From c42de3037ec406fa834c6c1756a6f0b70dcdd38f Mon Sep 17 00:00:00 2001 From: Karel Kočí Date: Wed, 23 Sep 2026 08:09:45 +0200 Subject: treewise: cleanup and general update --- pkgs/default.nix | 47 +- pkgs/dodo/default.nix | 6 +- pkgs/linux-openwrt-one-mediatek.patch | 1958 - pkgs/linux-openwrt-one.patch | 2508 - pkgs/linux_6_12-openwrt-one.patch | 222237 ------------------------------- 5 files changed, 26 insertions(+), 226730 deletions(-) delete mode 100644 pkgs/linux-openwrt-one-mediatek.patch delete mode 100644 pkgs/linux-openwrt-one.patch delete mode 100644 pkgs/linux_6_12-openwrt-one.patch (limited to 'pkgs') diff --git a/pkgs/default.nix b/pkgs/default.nix index 376a9d8..cb4f913 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix @@ -87,30 +87,29 @@ final: prev: { }; # NixPkgs patches - gnutls = - if prev.stdenv.hostPlatform != prev.stdenv.buildPlatform - then - prev.gnutls.overrideAttrs (oldAttrs: { - configureFlags = oldAttrs.configureFlags ++ ["--disable-doc"]; - outputs = builtins.filter (v: v != "man" && v != "devdoc") oldAttrs.outputs; - }) - else prev.gnutls; - git = - if prev.stdenv.hostPlatform != prev.stdenv.buildPlatform - then prev.git.override {rustSupport = false;} - else prev.git; - libcap = - if prev.stdenv.hostPlatform != prev.stdenv.buildPlatform - then - prev.libcap.overrideAttrs { - patches = [ - (final.fetchpatch { - url = "https://git.kernel.org/pub/scm/libs/libcap/libcap.git/patch/?id=d628b3bfe40338d4efff6b0ae50f250a0eb884c7"; - hash = "sha256-Eiv/BOJZkduL+hOEJd8K1LQd9wvOeCKchE2GaLcerVc="; - }) - ]; - } - else prev.libcap; + xdg-desktop-portal = prev.xdg-desktop-portal.overrideAttrs (oldAttrs: { + patches = + oldAttrs.patches + ++ [ + # https://github.com/NixOS/nixpkgs/pull/548762 + (final.fetchpatch { + url = "https://github.com/NixOS/nixpkgs/raw/4ba561388760a6fdfe376cbef28613b4366161ab/pkgs/by-name/xd/xdg-desktop-portal/allow-no-graphical-session-target.patch"; + hash = "sha256-55RFYk4Fzsj8xp6j0wg1AEz+9c05tqfNkPCP+z9czdI="; + }) + ]; + }); + #gnutls = + # if prev.stdenv.hostPlatform != prev.stdenv.buildPlatform + # then + # prev.gnutls.overrideAttrs (oldAttrs: { + # configureFlags = oldAttrs.configureFlags ++ ["--disable-doc"]; + # outputs = builtins.filter (v: v != "man" && v != "devdoc") oldAttrs.outputs; + # }) + # else prev.gnutls; + #git = + # if prev.stdenv.hostPlatform != prev.stdenv.buildPlatform + # then prev.git.override {rustSupport = false;} + # else prev.git; gvproxy = if prev.stdenv.hostPlatform.is32bit then diff --git a/pkgs/dodo/default.nix b/pkgs/dodo/default.nix index 627635e..07ee8b1 100644 --- a/pkgs/dodo/default.nix +++ b/pkgs/dodo/default.nix @@ -6,14 +6,14 @@ }: python3Packages.buildPythonApplication { pname = "dodo"; - version = "20250926"; + version = "20260730"; pyproject = true; src = fetchFromGitHub { owner = "akissinger"; repo = "dodo"; - rev = "a710d0a3fe78d5bf4b3d07ea087712d3581e5a85"; - hash = "sha256-IylZCG/7egGA7IBfSIMwmSbJVRv5cMWEtiIyds720Sw="; + rev = "2d1c91a625ac026f7624f80a36b29c2a4bdd0f4f"; + hash = "sha256-v4eXwzmS3DFYQ/v8sQWnnsyGjflf+OhVbVNqXLrYmZE="; }; build-system = with python3Packages; [ diff --git a/pkgs/linux-openwrt-one-mediatek.patch b/pkgs/linux-openwrt-one-mediatek.patch deleted file mode 100644 index 5c5a516..0000000 --- a/pkgs/linux-openwrt-one-mediatek.patch +++ /dev/null @@ -1,1958 +0,0 @@ -From patchwork Sat Nov 15 20:58:04 2025 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Sjoerd Simons -X-Patchwork-Id: 14315817 -Return-Path: - -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from bombadil.infradead.org (bombadil.infradead.org - [198.137.202.133]) - (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) - (No client certificate requested) - by smtp.lore.kernel.org (Postfix) with ESMTPS id 87133CEBF87 - for ; - Sat, 15 Nov 2025 20:58:48 +0000 (UTC) -DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; - d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help - :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References - :Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: - From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: - Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; - bh=YTHvtBL+VZnUTHjrz6ClSw7+XPBkv6t8SxYxsbAo8Ew=; b=DH1ulSz1P48SAm2zAuEzX6AiuW - i+Xb+boNBxdlgsK3sqlTIf6mn31nXf2NKTODWn5xR9F7OxwhS0V+8Iz/1bwePbus3Z/8RFUm26ehd - zSFSuzBO6tYAiPaB6AeAx97zb2+w+aT/0+bpDXE9gCmOBioPoFt6lXBGy1wojO8S/u+Jo4GaMCe0N - QySoWkbYLCnAE2wllpuVDlZKUWN39RVbthKIF5Q5XgEUj7x7W3x7KTLz+Uq9Gl4IszSclQiBfOvdo - YffKTNrPb/AfDtwo8UGk0iqaOZRClkJUbmWqw8yh31fxS8UffywXF9SdwytoAygFT4T4ZDoLCUD1L - 3BerwY2w==; -Received: from localhost ([::1] helo=bombadil.infradead.org) - by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) - id 1vKNM7-0000000E5Fz-3FnD; - Sat, 15 Nov 2025 20:58:47 +0000 -Received: from bali.collaboradmins.com ([2a01:4f8:201:9162::2]) - by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) - id 1vKNLw-0000000E56g-1nGv; - Sat, 15 Nov 2025 20:58:39 +0000 -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; - s=mail; t=1763240312; - bh=BNloXSmxfui+A+UD0vb6639VkVLh4h7qFS1iqqJUbUo=; - h=From:Date:Subject:References:In-Reply-To:To:Cc:From; - b=d6IFiUNqQD+93pkq4ov86+rPsBtqWuNo+o78OoQQeHDVPP6RnQvqLT0il8ol+tsgU - YMhKX0Dz+TVcC3EtyHF7Ck6JT2/94g3FzZeYYCK8zWmMpsh5DSSZjwm9ME60o3QjoV - aOlfgrFV808O7OmvfGCGPaouspC95qn7GlhLeK8hX25M45q2CTlbc8uP12FRDKPVwK - LBDVWjUfhgIZz3+HIzzg0OF6DEGWUKypIn05PzcPlXgp4iu/wxaIF0yTtyjJD/dJgg - u/IO3GbZ5fekm38/cTda66Kaxq1x5qkpojvKA3nkAb/chsHnprCZNbOK1OnknsJ9O0 - ypAexouToZ05Q== -Received: from beast.luon.net (simons.connected.by.freedominter.net - [45.83.240.172]) - (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) - key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest - SHA256) - (No client certificate requested) - (Authenticated sender: sjoerd) - by bali.collaboradmins.com (Postfix) with ESMTPSA id 6FCE517E00B0; - Sat, 15 Nov 2025 21:58:32 +0100 (CET) -Received: by beast.luon.net (Postfix, from userid 1000) - id 11F6A110527D9; Sat, 15 Nov 2025 21:58:32 +0100 (CET) -From: Sjoerd Simons -Date: Sat, 15 Nov 2025 21:58:04 +0100 -Subject: [PATCH v4 01/11] dt-bindings: mfd: syscon: Add mt7981-topmisc -MIME-Version: 1.0 -Message-Id: <20251115-openwrt-one-network-v4-1-48cbda2969ac@collabora.com> -References: <20251115-openwrt-one-network-v4-0-48cbda2969ac@collabora.com> -In-Reply-To: <20251115-openwrt-one-network-v4-0-48cbda2969ac@collabora.com> -To: Rob Herring , Krzysztof Kozlowski , - Conor Dooley , - Matthias Brugger , - AngeloGioacchino Del Regno , - Ryder Lee , - Jianjun Wang , - Bjorn Helgaas , - Lorenzo Pieralisi , =?utf-8?q?Krzysztof_Wilczy?= - =?utf-8?q?=C5=84ski?= , - Manivannan Sadhasivam , - Chunfeng Yun , Vinod Koul , - Kishon Vijay Abraham I , Lee Jones , - Andrew Lunn , - "David S. Miller" , Eric Dumazet , - Jakub Kicinski , Paolo Abeni , - Lorenzo Bianconi , Felix Fietkau -Cc: kernel@collabora.com, devicetree@vger.kernel.org, - linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, - linux-mediatek@lists.infradead.org, linux-pci@vger.kernel.org, - linux-phy@lists.infradead.org, netdev@vger.kernel.org, - Daniel Golle , Bryan Hinton , - Sjoerd Simons , - Conor Dooley -X-Mailer: b4 0.14.3 -X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 -X-CRM114-CacheID: sfid-20251115_125836_635252_F7CBC235 -X-CRM114-Status: UNSURE ( 8.47 ) -X-CRM114-Notice: Please train this message. -X-BeenThere: linux-mediatek@lists.infradead.org -X-Mailman-Version: 2.1.34 -Precedence: list -List-Id: -List-Unsubscribe: , - -List-Archive: -List-Post: -List-Help: -List-Subscribe: , - -Sender: "Linux-mediatek" -Errors-To: - linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org - -This hardware block amongst other things includes a multiplexer for a -high-speed Combo-Phy. This binding allows exposing the multiplexer - -Acked-by: Conor Dooley -Reviewed-by: AngeloGioacchino Del Regno -Signed-off-by: Sjoerd Simons ---- - Documentation/devicetree/bindings/mfd/syscon.yaml | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml -index 657c38175fba2..51511078c4c3b 100644 ---- a/Documentation/devicetree/bindings/mfd/syscon.yaml -+++ b/Documentation/devicetree/bindings/mfd/syscon.yaml -@@ -193,6 +193,7 @@ properties: - - mediatek,mt2701-pctl-a-syscfg - - mediatek,mt2712-pctl-a-syscfg - - mediatek,mt6397-pctl-pmic-syscfg -+ - mediatek,mt7981-topmisc - - mediatek,mt7988-topmisc - - mediatek,mt8135-pctl-a-syscfg - - mediatek,mt8135-pctl-b-syscfg - -From patchwork Sat Nov 15 20:58:05 2025 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Sjoerd Simons -X-Patchwork-Id: 14315818 -Return-Path: - -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from bombadil.infradead.org (bombadil.infradead.org - [198.137.202.133]) - (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) - (No client certificate requested) - by smtp.lore.kernel.org (Postfix) with ESMTPS id 51A19CEBF91 - for ; - Sat, 15 Nov 2025 20:58:49 +0000 (UTC) -DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; - d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help - :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References - :Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: - From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: - Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; - bh=j/r2anqRW+90VM9McPY+HL40VXbPRjGoaWqnMpIZ0Fs=; b=LzxtwLOLzukTwsjgNKokmUHiAP - E+MMsDIqRuSTrc0KP326+ESa+sxMAL++DfvflnutJuJJw+2LyT/tlhXLCT+4kDKd93fXJl3rbFA/8 - znNtJAAflN80Irlc2ZWgvABiLaGpnzV4ZcR0fBki1ENa9R9SXLZXeC0gnfc1bxD8fQ+d/M4dbBFwi - 7UPdXETna447WPghK5sr8wMRJAIqw/hl8JIrd9lSwOzJtMfVp9JvKjAzQ9axdqt5+LTWgP5lC9UYN - dyV5C0SH9dOizniOYHESFro5Osy9xbcIfB0uvIo7lx4b1SbnUOKDOtAAgLEGzY5ZOXAlEIr4vyZP4 - 4jEp3gVA==; -Received: from localhost ([::1] helo=bombadil.infradead.org) - by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) - id 1vKNM8-0000000E5Gd-1VH2; - Sat, 15 Nov 2025 20:58:48 +0000 -Received: from bali.collaboradmins.com ([148.251.105.195]) - by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) - id 1vKNLw-0000000E56f-2xAa; - Sat, 15 Nov 2025 20:58:39 +0000 -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; - s=mail; t=1763240312; - bh=JdKvpThqp3TDs4o0pkrFusvXBPtE9LtpoPmwO6qXgiM=; - h=From:Date:Subject:References:In-Reply-To:To:Cc:From; - b=SRtp7rTMzwbGSe7WBPL0JooFZ9MC1NaN0wdOyoTLxb7QDCJyG8qYLDo8LnLl6Jcmb - /OXnw8pz4g1m2BZnlPg4zGJ/arOYZUxhiH9GpqZWWaVngrMs1GSZR2elktYm7v3QHS - YjErx28KgjfJeTUV9fvRXSpTIeO6TwTPDSueAaH7FnHqPnBRFD+H3VBlfDM16Qto2Y - 1xtK8UKg8qJkN6usUZ5Amdb6P5hM8ZiJpvf8Phn8NDxhBbG7qFcWe99IgU+Ibvdni+ - gNqBYbv0Y5bFf1jLmW7mL5kl9LhhuI3ZqxTL74Mypm3V2ZlK7BZ1pgJn82afW2SXpo - z0iWQVf1AWNow== -Received: from beast.luon.net (unknown [IPv6:2a10:3781:2531::8]) - (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) - key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest - SHA256) - (No client certificate requested) - (Authenticated sender: sjoerd) - by bali.collaboradmins.com (Postfix) with ESMTPSA id 7138F17E0202; - Sat, 15 Nov 2025 21:58:32 +0100 (CET) -Received: by beast.luon.net (Postfix, from userid 1000) - id 175EF110527DB; Sat, 15 Nov 2025 21:58:32 +0100 (CET) -From: Sjoerd Simons -Date: Sat, 15 Nov 2025 21:58:05 +0100 -Subject: [PATCH v4 02/11] dt-bindings: PCI: mediatek-gen3: Add MT7981 PCIe - compatible -MIME-Version: 1.0 -Message-Id: <20251115-openwrt-one-network-v4-2-48cbda2969ac@collabora.com> -References: <20251115-openwrt-one-network-v4-0-48cbda2969ac@collabora.com> -In-Reply-To: <20251115-openwrt-one-network-v4-0-48cbda2969ac@collabora.com> -To: Rob Herring , Krzysztof Kozlowski , - Conor Dooley , - Matthias Brugger , - AngeloGioacchino Del Regno , - Ryder Lee , - Jianjun Wang , - Bjorn Helgaas , - Lorenzo Pieralisi , =?utf-8?q?Krzysztof_Wilczy?= - =?utf-8?q?=C5=84ski?= , - Manivannan Sadhasivam , - Chunfeng Yun , Vinod Koul , - Kishon Vijay Abraham I , Lee Jones , - Andrew Lunn , - "David S. Miller" , Eric Dumazet , - Jakub Kicinski , Paolo Abeni , - Lorenzo Bianconi , Felix Fietkau -Cc: kernel@collabora.com, devicetree@vger.kernel.org, - linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, - linux-mediatek@lists.infradead.org, linux-pci@vger.kernel.org, - linux-phy@lists.infradead.org, netdev@vger.kernel.org, - Daniel Golle , Bryan Hinton , - Sjoerd Simons , - Conor Dooley -X-Mailer: b4 0.14.3 -X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 -X-CRM114-CacheID: sfid-20251115_125836_895114_1999B926 -X-CRM114-Status: UNSURE ( 8.81 ) -X-CRM114-Notice: Please train this message. -X-BeenThere: linux-mediatek@lists.infradead.org -X-Mailman-Version: 2.1.34 -Precedence: list -List-Id: -List-Unsubscribe: , - -List-Archive: -List-Post: -List-Help: -List-Subscribe: , - -Sender: "Linux-mediatek" -Errors-To: - linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org - -Add compatible string for MediaTek MT7981 PCIe Gen3 controller. -The MT7981 PCIe controller is compatible with the MT8192 PCIe -controller. - -Acked-by: Conor Dooley -Reviewed-by: AngeloGioacchino Del Regno -Signed-off-by: Sjoerd Simons ---- -V1 -> V2: Improve commit subject ---- - Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml b/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml -index 0278845701ce8..4db700fc36ba7 100644 ---- a/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml -+++ b/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml -@@ -48,6 +48,7 @@ properties: - oneOf: - - items: - - enum: -+ - mediatek,mt7981-pcie - - mediatek,mt7986-pcie - - mediatek,mt8188-pcie - - mediatek,mt8195-pcie - -From patchwork Sat Nov 15 20:58:06 2025 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Sjoerd Simons -X-Patchwork-Id: 14315816 -Return-Path: - -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from bombadil.infradead.org (bombadil.infradead.org - [198.137.202.133]) - (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) - (No client certificate requested) - by smtp.lore.kernel.org (Postfix) with ESMTPS id 75078CEBF88 - for ; - Sat, 15 Nov 2025 20:58:47 +0000 (UTC) -DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; - d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help - :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References - :Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: - From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: - Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; - bh=ksghHQTQZO35rk2pD4ByHO3UcRzFD5f5eXAve+3bdKg=; b=3tGsceyjX6cXTdiASs8XE/DvFl - PWUXrsvY6QlEvPMj1Ezj9rAIv0bn+EEOrlvzcX1sI7+8PhfFxgpfZNnUfQT3Nk757MZrrHlG9IXgQ - WT9ukbjZ8mv/YwglhZpgFhWf4kD74SUAco0WbS6gexWVh9sSLBBw+FoHNgb/WOFnZJY7GoqUY/0wa - l0RBPxwb7pYWOtYzy4VBgo1Bu/HdbcL75f8nF1K6iyHGcDlW6Jp++Mw6XncwpPvHK1U+HmE7IWcg4 - OjAfy4qX9PsPfFDVCkFKX+usBeWG1YaQxD/75ZLckgUgFeYYfkzDRfsRL3Aw6YmXxGZeto3+W7w1N - 8Iy6mKvw==; -Received: from localhost ([::1] helo=bombadil.infradead.org) - by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) - id 1vKNM6-0000000E5E8-2k63; - Sat, 15 Nov 2025 20:58:46 +0000 -Received: from bali.collaboradmins.com ([148.251.105.195]) - by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) - id 1vKNLw-0000000E56j-0q7p; - Sat, 15 Nov 2025 20:58:38 +0000 -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; - s=mail; t=1763240312; - bh=0HQMjZYjWvOC8AwZB4R1t/Hz5V/fyYneHN+5PdUNP20=; - h=From:Date:Subject:References:In-Reply-To:To:Cc:From; - b=DKCS9RPUbiAUYzBlJzJKWw4qPry+26xTEWZ10gp5WbW8ypD0H/Vu1AQmgNIE8YFk+ - /VmTDj8RffLNvduOmHnqKehMFLVwQ4epLwgPD+eSKyFT315b+X0ST3DK1R1KkOxZst - FhtmPwMw2u29bhVO7KLGIP9cOq0WQezCx9gAOrKpraS65Mk4prB5LhmWaA4mD6PjZJ - 8hgy3qUbGWwTVKFM64vhRPQ9b2ogdKONE8r+JeWzHFu7QopxwBDyThZpSZqA+6Wk/M - FRvF81p9BTAO4rm4JDuiLdugk9lbrNs7i2swbRx/dE0BHXqmlZWJzslBO1WXWNf7tH - 8xZgyAWt0T2jQ== -Received: from beast.luon.net (simons.connected.by.freedominter.net - [45.83.240.172]) - (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) - key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest - SHA256) - (No client certificate requested) - (Authenticated sender: sjoerd) - by bali.collaboradmins.com (Postfix) with ESMTPSA id 74A1517E0610; - Sat, 15 Nov 2025 21:58:32 +0100 (CET) -Received: by beast.luon.net (Postfix, from userid 1000) - id 1AE68110527DD; Sat, 15 Nov 2025 21:58:32 +0100 (CET) -From: Sjoerd Simons -Date: Sat, 15 Nov 2025 21:58:06 +0100 -Subject: [PATCH v4 03/11] dt-bindings: phy: mediatek,tphy: Add support for - MT7981 -MIME-Version: 1.0 -Message-Id: <20251115-openwrt-one-network-v4-3-48cbda2969ac@collabora.com> -References: <20251115-openwrt-one-network-v4-0-48cbda2969ac@collabora.com> -In-Reply-To: <20251115-openwrt-one-network-v4-0-48cbda2969ac@collabora.com> -To: Rob Herring , Krzysztof Kozlowski , - Conor Dooley , - Matthias Brugger , - AngeloGioacchino Del Regno , - Ryder Lee , - Jianjun Wang , - Bjorn Helgaas , - Lorenzo Pieralisi , =?utf-8?q?Krzysztof_Wilczy?= - =?utf-8?q?=C5=84ski?= , - Manivannan Sadhasivam , - Chunfeng Yun , Vinod Koul , - Kishon Vijay Abraham I , Lee Jones , - Andrew Lunn , - "David S. Miller" , Eric Dumazet , - Jakub Kicinski , Paolo Abeni , - Lorenzo Bianconi , Felix Fietkau -Cc: kernel@collabora.com, devicetree@vger.kernel.org, - linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, - linux-mediatek@lists.infradead.org, linux-pci@vger.kernel.org, - linux-phy@lists.infradead.org, netdev@vger.kernel.org, - Daniel Golle , Bryan Hinton , - Sjoerd Simons , - Conor Dooley -X-Mailer: b4 0.14.3 -X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 -X-CRM114-CacheID: sfid-20251115_125836_406913_BA71748C -X-CRM114-Status: UNSURE ( 8.92 ) -X-CRM114-Notice: Please train this message. -X-BeenThere: linux-mediatek@lists.infradead.org -X-Mailman-Version: 2.1.34 -Precedence: list -List-Id: -List-Unsubscribe: , - -List-Archive: -List-Post: -List-Help: -List-Subscribe: , - -Sender: "Linux-mediatek" -Errors-To: - linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org - -Add a compatible string for Filogic 820, this chip integrates a MediaTek -generic T-PHY version 2 - -Acked-by: Conor Dooley -Reviewed-by: AngeloGioacchino Del Regno -Signed-off-by: Sjoerd Simons ---- - Documentation/devicetree/bindings/phy/mediatek,tphy.yaml | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml -index b2218c1519391..ff5c77ef11765 100644 ---- a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml -+++ b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml -@@ -80,6 +80,7 @@ properties: - - mediatek,mt2712-tphy - - mediatek,mt6893-tphy - - mediatek,mt7629-tphy -+ - mediatek,mt7981-tphy - - mediatek,mt7986-tphy - - mediatek,mt8183-tphy - - mediatek,mt8186-tphy - -From patchwork Sat Nov 15 20:58:07 2025 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Sjoerd Simons -X-Patchwork-Id: 14315815 -Return-Path: - -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from bombadil.infradead.org (bombadil.infradead.org - [198.137.202.133]) - (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) - (No client certificate requested) - by smtp.lore.kernel.org (Postfix) with ESMTPS id 197BFCEBF86 - for ; - Sat, 15 Nov 2025 20:58:45 +0000 (UTC) -DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; - d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help - :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References - :Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: - From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: - Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; - bh=OewVkhzvg4trcmQP7/dgtYYz1ryrPP/rqMADz2pCeIY=; b=EvyjEIEBQKhelqkgH3LIbqPY63 - cFIr5zcv018sfc+NcAG3NehHT6qpqmU0KSG0q+0BFq2yZn3//5IqU88heeYn3k7VS7w7Pe3cJr5Gr - 1RIwczzUzDW44SniH3h8E73lOsLILlL0y7sh493XAroJWrv0E6M+LsrRGdAq4kPJXoHvNaoJSoREh - Wsp+mzEpIpi57bC5uZKp0hA18drP2nK0z8VOpJ7k63D6sUmUWVL2ck+id1nKjqaQ9VjgwKKi91GE3 - FXAEinedGgwiEaT3FrDdCkYfVX/zjrBLLJnKf36DmMWnwXOENj65nCtMXfYHR76gy49/ECfOxrTf7 - 56/iq3IQ==; -Received: from localhost ([::1] helo=bombadil.infradead.org) - by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) - id 1vKNM0-0000000E59L-3Ntw; - Sat, 15 Nov 2025 20:58:40 +0000 -Received: from bali.collaboradmins.com ([2a01:4f8:201:9162::2]) - by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) - id 1vKNLw-0000000E56i-1H3s; - Sat, 15 Nov 2025 20:58:37 +0000 -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; - s=mail; t=1763240312; - bh=USBTzS5LeZooJ42tEMhi7N85ITpVvJxHo6le5MQpsP8=; - h=From:Date:Subject:References:In-Reply-To:To:Cc:From; - b=J/52ZUFHclPFqDSg6mnAkchEl1Asf4QNTWvVn9L4iss5+uSMlpHYvWIRMBd6OO+v+ - eotX3qF03b7wdTt0OPyHf3k98vzDyOifpXrPgXwIY50eWoaiBp5jIqvExz1z4F2ajz - AiP287jfiZgBsu5wWVAVcMmmfGz3qRKZNTMLvRZGWQKDBVhw0RzCkWyQvHS/zbU/nd - GENWs8LgN/0KxUvdB1I0O0RmKxfYJStgNcmG+nqUPIu5f235k5eB2O67B1ZsLd6X/E - ixhYPKate1Y9TLSCSYtyc69oML0nwgJESVB+G+MNCj/IRNqcTvS+5TmoSUTfvoH/eB - XZFhBNFdgJzIw== -Received: from beast.luon.net (simons.connected.by.freedominter.net - [45.83.240.172]) - (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) - key-exchange X25519 server-signature RSA-PSS (4096 bits)) - (No client certificate requested) - (Authenticated sender: sjoerd) - by bali.collaboradmins.com (Postfix) with ESMTPSA id 82B2F17E0B46; - Sat, 15 Nov 2025 21:58:32 +0100 (CET) -Received: by beast.luon.net (Postfix, from userid 1000) - id 239DA110527DF; Sat, 15 Nov 2025 21:58:32 +0100 (CET) -From: Sjoerd Simons -Date: Sat, 15 Nov 2025 21:58:07 +0100 -Subject: [PATCH v4 04/11] arm64: dts: mediatek: mt7981b: Add PCIe and USB - support -MIME-Version: 1.0 -Message-Id: <20251115-openwrt-one-network-v4-4-48cbda2969ac@collabora.com> -References: <20251115-openwrt-one-network-v4-0-48cbda2969ac@collabora.com> -In-Reply-To: <20251115-openwrt-one-network-v4-0-48cbda2969ac@collabora.com> -To: Rob Herring , Krzysztof Kozlowski , - Conor Dooley , - Matthias Brugger , - AngeloGioacchino Del Regno , - Ryder Lee , - Jianjun Wang , - Bjorn Helgaas , - Lorenzo Pieralisi , =?utf-8?q?Krzysztof_Wilczy?= - =?utf-8?q?=C5=84ski?= , - Manivannan Sadhasivam , - Chunfeng Yun , Vinod Koul , - Kishon Vijay Abraham I , Lee Jones , - Andrew Lunn , - "David S. Miller" , Eric Dumazet , - Jakub Kicinski , Paolo Abeni , - Lorenzo Bianconi , Felix Fietkau -Cc: kernel@collabora.com, devicetree@vger.kernel.org, - linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, - linux-mediatek@lists.infradead.org, linux-pci@vger.kernel.org, - linux-phy@lists.infradead.org, netdev@vger.kernel.org, - Daniel Golle , Bryan Hinton , - Sjoerd Simons -X-Mailer: b4 0.14.3 -X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 -X-CRM114-CacheID: sfid-20251115_125836_493398_5613042F -X-CRM114-Status: GOOD ( 12.77 ) -X-BeenThere: linux-mediatek@lists.infradead.org -X-Mailman-Version: 2.1.34 -Precedence: list -List-Id: -List-Unsubscribe: , - -List-Archive: -List-Post: -List-Help: -List-Subscribe: , - -Sender: "Linux-mediatek" -Errors-To: - linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org - -Add device tree nodes for PCIe controller and USB3 XHCI host -controller on MT7981B SoC. Both controllers share the USB3 PHY -which can be configured for either USB3 or PCIe operation. - -The USB3 XHCI controller supports USB 2.0 and USB 3.0 SuperSpeed -operation. The PCIe controller is compatible with PCIe Gen2 -specifications. - -Also add the topmisc syscon node required for USB/PCIe PHY -multiplexing. - -Reviewed-by: AngeloGioacchino Del Regno -Signed-off-by: Sjoerd Simons ---- -V1 -> V2: Keep xhci reg and phys properties in single lines ---- - arch/arm64/boot/dts/mediatek/mt7981b.dtsi | 80 +++++++++++++++++++++++++++++++ - 1 file changed, 80 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi -index 416096b80770c..d3f37413413e2 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi -@@ -2,6 +2,7 @@ - - #include - #include -+#include - #include - - / { -@@ -223,6 +224,55 @@ auxadc: adc@1100d000 { - status = "disabled"; - }; - -+ xhci: usb@11200000 { -+ compatible = "mediatek,mt7986-xhci", "mediatek,mtk-xhci"; -+ reg = <0 0x11200000 0 0x2e00>, <0 0x11203e00 0 0x0100>; -+ reg-names = "mac", "ippc"; -+ clocks = <&infracfg CLK_INFRA_IUSB_SYS_CK>, -+ <&infracfg CLK_INFRA_IUSB_CK>, -+ <&infracfg CLK_INFRA_IUSB_133_CK>, -+ <&infracfg CLK_INFRA_IUSB_66M_CK>, -+ <&topckgen CLK_TOP_U2U3_XHCI_SEL>; -+ clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck"; -+ interrupts = ; -+ phys = <&u2port0 PHY_TYPE_USB2>, <&u3port0 PHY_TYPE_USB3>; -+ status = "disabled"; -+ }; -+ -+ pcie: pcie@11280000 { -+ compatible = "mediatek,mt7981-pcie", -+ "mediatek,mt8192-pcie"; -+ reg = <0 0x11280000 0 0x4000>; -+ reg-names = "pcie-mac"; -+ ranges = <0x82000000 0 0x20000000 -+ 0x0 0x20000000 0 0x10000000>; -+ bus-range = <0x00 0xff>; -+ clocks = <&infracfg CLK_INFRA_IPCIE_CK>, -+ <&infracfg CLK_INFRA_IPCIE_PIPE_CK>, -+ <&infracfg CLK_INFRA_IPCIER_CK>, -+ <&infracfg CLK_INFRA_IPCIEB_CK>; -+ clock-names = "pl_250m", "tl_26m", "peri_26m", "top_133m"; -+ device_type = "pci"; -+ phys = <&u3port0 PHY_TYPE_PCIE>; -+ phy-names = "pcie-phy"; -+ interrupts = ; -+ interrupt-map-mask = <0 0 0 7>; -+ interrupt-map = <0 0 0 1 &pcie_intc 0>, -+ <0 0 0 2 &pcie_intc 1>, -+ <0 0 0 3 &pcie_intc 2>, -+ <0 0 0 4 &pcie_intc 3>; -+ #address-cells = <3>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ status = "disabled"; -+ -+ pcie_intc: interrupt-controller { -+ interrupt-controller; -+ #address-cells = <0>; -+ #interrupt-cells = <1>; -+ }; -+ }; -+ - pio: pinctrl@11d00000 { - compatible = "mediatek,mt7981-pinctrl"; - reg = <0 0x11d00000 0 0x1000>, -@@ -252,6 +302,36 @@ mux { - }; - }; - -+ topmisc: topmisc@11d10000 { -+ compatible = "mediatek,mt7981-topmisc", "syscon"; -+ reg = <0 0x11d10000 0 0x10000>; -+ #clock-cells = <1>; -+ }; -+ -+ usb_phy: t-phy@11e10000 { -+ compatible = "mediatek,mt7981-tphy", -+ "mediatek,generic-tphy-v2"; -+ ranges = <0 0 0x11e10000 0x1700>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ status = "disabled"; -+ -+ u2port0: usb-phy@0 { -+ reg = <0x0 0x700>; -+ clocks = <&topckgen CLK_TOP_USB_FRMCNT_SEL>; -+ clock-names = "ref"; -+ #phy-cells = <1>; -+ }; -+ -+ u3port0: usb-phy@700 { -+ reg = <0x700 0x900>; -+ clocks = <&topckgen CLK_TOP_USB3_PHY_SEL>; -+ clock-names = "ref"; -+ #phy-cells = <1>; -+ mediatek,syscon-type = <&topmisc 0x218 0>; -+ }; -+ }; -+ - efuse@11f20000 { - compatible = "mediatek,mt7981-efuse", "mediatek,efuse"; - reg = <0 0x11f20000 0 0x1000>; - -From patchwork Sat Nov 15 20:58:08 2025 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Sjoerd Simons -X-Patchwork-Id: 14315825 -Return-Path: - -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from bombadil.infradead.org (bombadil.infradead.org - [198.137.202.133]) - (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) - (No client certificate requested) - by smtp.lore.kernel.org (Postfix) with ESMTPS id 2AE33CEBF93 - for ; - Sat, 15 Nov 2025 20:59:00 +0000 (UTC) -DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; - d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help - :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References - :Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: - From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: - Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; - bh=5LeoqZv3J6t2Lu06YdrFLcmlUA455lKj3p+A2h/ypu8=; b=SQ3o2kxzmKUUqGCfhAK/EcvRA8 - CU4AR190oM9Rhyz5SGy7HNTZqcj1adzIrl1yi8SONGnUfRK2T+lGxH+YEFvfTCPVyGYBzvWUjbbFj - W/IFCKaN8ORcWYGZF61UBseu6lP9stKcMcm+37t7OKGwME9S1A6ECmG5Y/vLCBjXxjKWeQeOedj6p - TPuMUlR5fPu+uV13+I6oZt4SdckwQ8sjvKgug53e9pDteeASbz3FpbjgfP4gFsF3KpxF4V6p5nDke - qbn6ypgZLZ+FYZshT7WLMakkn2zPEwbNCt1AyzZZnX+BickNvgbFp8z5WSYKWBnsX2ivGpgPqkdyc - gExEcT2Q==; -Received: from localhost ([::1] helo=bombadil.infradead.org) - by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) - id 1vKNMI-0000000E5bD-3svU; - Sat, 15 Nov 2025 20:58:58 +0000 -Received: from bali.collaboradmins.com ([2a01:4f8:201:9162::2]) - by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) - id 1vKNM2-0000000E58z-1yGX; - Sat, 15 Nov 2025 20:58:45 +0000 -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; - s=mail; t=1763240313; - bh=qtE8TxX+bp4mVeKXXycM622mPKaw8qoe/nGz0YEjV0g=; - h=From:Date:Subject:References:In-Reply-To:To:Cc:From; - b=OMTrMedcu0AeQXazVdUg3cIgK7psG/6TTE91XDJScFPQcInb7moqAzzyqBzWMDPmz - NmMaHV1wu9Nz42zxajQAQ/OVT8yEz6+nRjUBVO0ryHzqc6UPNqfoRDKxlmdJRbZLcU - f0fP/rJJ0iF9d1BTMgPkvJIdlO6HtcKXqiaUQDCdE2NH5V72CUyGVwg7ypj0I+Z9GC - fFvUrGEWkzCZDiDsT+KmQcAyXF5jp7wnfitEFNwXJa7RSjYWUDWHDsdc3lxG0KbE37 - wzquvJyfv+Jf3MLJJYQ3W39I+pp3wpzIuUkR6xJ1gbJmGI8O67yR+rLPlahzQL2Tbk - Vp1ipOawKNEUA== -Received: from beast.luon.net (unknown [IPv6:2a10:3781:2531::8]) - (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) - key-exchange X25519 server-signature RSA-PSS (4096 bits)) - (No client certificate requested) - (Authenticated sender: sjoerd) - by bali.collaboradmins.com (Postfix) with ESMTPSA id 47C3217E1401; - Sat, 15 Nov 2025 21:58:33 +0100 (CET) -Received: by beast.luon.net (Postfix, from userid 1000) - id 29442110527E1; Sat, 15 Nov 2025 21:58:32 +0100 (CET) -From: Sjoerd Simons -Date: Sat, 15 Nov 2025 21:58:08 +0100 -Subject: [PATCH v4 05/11] arm64: dts: mediatek: mt7981b-openwrt-one: Enable - PCIe and USB -MIME-Version: 1.0 -Message-Id: <20251115-openwrt-one-network-v4-5-48cbda2969ac@collabora.com> -References: <20251115-openwrt-one-network-v4-0-48cbda2969ac@collabora.com> -In-Reply-To: <20251115-openwrt-one-network-v4-0-48cbda2969ac@collabora.com> -To: Rob Herring , Krzysztof Kozlowski , - Conor Dooley , - Matthias Brugger , - AngeloGioacchino Del Regno , - Ryder Lee , - Jianjun Wang , - Bjorn Helgaas , - Lorenzo Pieralisi , =?utf-8?q?Krzysztof_Wilczy?= - =?utf-8?q?=C5=84ski?= , - Manivannan Sadhasivam , - Chunfeng Yun , Vinod Koul , - Kishon Vijay Abraham I , Lee Jones , - Andrew Lunn , - "David S. Miller" , Eric Dumazet , - Jakub Kicinski , Paolo Abeni , - Lorenzo Bianconi , Felix Fietkau -Cc: kernel@collabora.com, devicetree@vger.kernel.org, - linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, - linux-mediatek@lists.infradead.org, linux-pci@vger.kernel.org, - linux-phy@lists.infradead.org, netdev@vger.kernel.org, - Daniel Golle , Bryan Hinton , - Sjoerd Simons -X-Mailer: b4 0.14.3 -X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 -X-CRM114-CacheID: sfid-20251115_125844_876976_31568B83 -X-CRM114-Status: GOOD ( 11.36 ) -X-BeenThere: linux-mediatek@lists.infradead.org -X-Mailman-Version: 2.1.34 -Precedence: list -List-Id: -List-Unsubscribe: , - -List-Archive: -List-Post: -List-Help: -List-Subscribe: , - -Sender: "Linux-mediatek" -Errors-To: - linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org - -Enable the PCIe controller and USB3 XHCI host on the OpenWrt One -board. The USB controller is configured for USB 2.0 only mode, as the -shared USB3/PCIe PHY is dedicated to PCIe functionality on this board. - -Signed-off-by: Sjoerd Simons ---- - .../boot/dts/mediatek/mt7981b-openwrt-one.dts | 43 ++++++++++++++++++++++ - 1 file changed, 43 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7981b-openwrt-one.dts b/arch/arm64/boot/dts/mediatek/mt7981b-openwrt-one.dts -index 2e39e72877301..7382599cfea29 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7981b-openwrt-one.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7981b-openwrt-one.dts -@@ -67,9 +67,40 @@ led-2 { - linux,default-trigger = "netdev"; - }; - }; -+ -+ reg_3p3v: regulator-3p3v { -+ compatible = "regulator-fixed"; -+ regulator-name = "fixed-3.3V"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ reg_5v: regulator-5v { -+ compatible = "regulator-fixed"; -+ regulator-name = "fixed-5V"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+}; -+ -+&pcie { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie_pins>; -+ status = "okay"; - }; - - &pio { -+ pcie_pins: pcie-pins { -+ mux { -+ function = "pcie"; -+ groups = "pcie_pereset"; -+ }; -+ }; -+ - pwm_pins: pwm-pins { - mux { - function = "pwm"; -@@ -163,3 +194,15 @@ partition@180000 { - &uart0 { - status = "okay"; - }; -+ -+&usb_phy { -+ status = "okay"; -+}; -+ -+&xhci { -+ phys = <&u2port0 PHY_TYPE_USB2>; -+ vusb33-supply = <®_3p3v>; -+ vbus-supply = <®_5v>; -+ mediatek,u3p-dis-msk = <0x01>; -+ status = "okay"; -+}; - -From patchwork Sat Nov 15 20:58:09 2025 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Sjoerd Simons -X-Patchwork-Id: 14315823 -Return-Path: - -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from bombadil.infradead.org (bombadil.infradead.org - [198.137.202.133]) - (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) - (No client certificate requested) - by smtp.lore.kernel.org (Postfix) with ESMTPS id 03A8BCEBF87 - for ; - Sat, 15 Nov 2025 20:58:56 +0000 (UTC) -DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; - d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help - :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References - :Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: - From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: - Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; - bh=C2bjGxQ6HoZ8TwnWzdhU4ymJp6VMNPaTXtRwAbzTLT0=; b=jgXpD9wclS0/S726cJ5b1Xedf0 - +w+meVYFpyZhECkfp/kMXtI2jXmEMmENlr1iiCZhE1Jw5m5dOvA4M+TVdJ6QDYRokVT3hX5UWqVxe - 1qOHCR+3RSjhP31JvQBtZ2yuzK56TbpKtFbsw8g91Iepmlfzzm9t2I5QVtEHw7kvR87II+xNu7I0F - EX1URTMIx718uoBqEVa9m17M2FrjzypdpwmQQa9LV++tF7KLKZEgWMiC/0qozBz/G+ONw0ksHxqdI - u73OHdnP4DHev+AvRWudxFHjXahgEsa5cHg31v52/5RD0SdNN+B1xqzldPB2/UhGqsO1GlkGXViEI - +k6sU7NQ==; -Received: from localhost ([::1] helo=bombadil.infradead.org) - by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) - id 1vKNMF-0000000E5UH-2fCE; - Sat, 15 Nov 2025 20:58:55 +0000 -Received: from bali.collaboradmins.com ([2a01:4f8:201:9162::2]) - by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) - id 1vKNM1-0000000E58I-1TWC; - Sat, 15 Nov 2025 20:58:45 +0000 -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; - s=mail; t=1763240313; - bh=hw3ZAW2zOtXRACUrBJfwNwFWR2lDq8YE4T88GaAFI9E=; - h=From:Date:Subject:References:In-Reply-To:To:Cc:From; - b=AJKfCLLDEVZ2vLVs5c4AQth3HKWTJxWUAschvzx7UK7egad+wwIbwyP1CfqB9qheJ - ZyhUpaxUENHwiP6RELESKammjVBDat8g/h6kbAfXTsVWZqZ5VhUrZ1zhBxcLNFeJZj - ZRdm6VO7LpKhwNJdRtFbDq17VQNNznRUEGwPNqWKM7q2GyD04oHQ1i4XNpFJ/SLrji - Q0U63jm2Ka7oGMw010OayNXjsMEFItBFD9F6TTooNmZOa1F9SleM+Pq/tXp3S9tmV+ - ps3pDTFG7xEOWoLvTkIAQnTXDaa5RItxdanzGh7Z8mDHqVJWDkxB3gtgN+6qSyjvyv - OmxOFYVPaqomw== -Received: from beast.luon.net (simons.connected.by.freedominter.net - [45.83.240.172]) - (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) - key-exchange X25519 server-signature RSA-PSS (4096 bits)) - (No client certificate requested) - (Authenticated sender: sjoerd) - by bali.collaboradmins.com (Postfix) with ESMTPSA id E8E6017E13D6; - Sat, 15 Nov 2025 21:58:32 +0100 (CET) -Received: by beast.luon.net (Postfix, from userid 1000) - id 2CCF8110527E3; Sat, 15 Nov 2025 21:58:32 +0100 (CET) -From: Sjoerd Simons -Date: Sat, 15 Nov 2025 21:58:09 +0100 -Subject: [PATCH v4 06/11] dt-bindings: net: mediatek,net: Correct bindings - for MT7981 -MIME-Version: 1.0 -Message-Id: <20251115-openwrt-one-network-v4-6-48cbda2969ac@collabora.com> -References: <20251115-openwrt-one-network-v4-0-48cbda2969ac@collabora.com> -In-Reply-To: <20251115-openwrt-one-network-v4-0-48cbda2969ac@collabora.com> -To: Rob Herring , Krzysztof Kozlowski , - Conor Dooley , - Matthias Brugger , - AngeloGioacchino Del Regno , - Ryder Lee , - Jianjun Wang , - Bjorn Helgaas , - Lorenzo Pieralisi , =?utf-8?q?Krzysztof_Wilczy?= - =?utf-8?q?=C5=84ski?= , - Manivannan Sadhasivam , - Chunfeng Yun , Vinod Koul , - Kishon Vijay Abraham I , Lee Jones , - Andrew Lunn , - "David S. Miller" , Eric Dumazet , - Jakub Kicinski , Paolo Abeni , - Lorenzo Bianconi , Felix Fietkau -Cc: kernel@collabora.com, devicetree@vger.kernel.org, - linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, - linux-mediatek@lists.infradead.org, linux-pci@vger.kernel.org, - linux-phy@lists.infradead.org, netdev@vger.kernel.org, - Daniel Golle , Bryan Hinton , - Sjoerd Simons -X-Mailer: b4 0.14.3 -X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 -X-CRM114-CacheID: sfid-20251115_125841_568173_8F06F4C0 -X-CRM114-Status: UNSURE ( 9.74 ) -X-CRM114-Notice: Please train this message. -X-BeenThere: linux-mediatek@lists.infradead.org -X-Mailman-Version: 2.1.34 -Precedence: list -List-Id: -List-Unsubscribe: , - -List-Archive: -List-Post: -List-Help: -List-Subscribe: , - -Sender: "Linux-mediatek" -Errors-To: - linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org - -Different SoCs have different numbers of Wireless Ethernet -Dispatch (WED) units: -- MT7981: Has 1 WED unit -- MT7986: Has 2 WED units -- MT7988: Has 2 WED units - -Update the binding to reflect these hardware differences. The MT7981 -also uses infracfg for PHY switching, so allow that property. - -Signed-off-by: Sjoerd Simons -Acked-by: Conor Dooley ---- -V4: - - Move back to V2 version (widening global constraint, constraining - per compatible) - - Ensure all compatibles are constraint in the amount of WEDs (2 for - everything apart from mt7981). Specifically adding constraints for - mediatek,mt7622-eth and ralink,rt5350-eth -V2 -> V3: Only update MT7981 constraints rather then defaults -V2: Only overwrite properties that are different from the default ---- - .../devicetree/bindings/net/mediatek,net.yaml | 26 +++++++++++++++++++--- - 1 file changed, 23 insertions(+), 3 deletions(-) - -diff --git a/Documentation/devicetree/bindings/net/mediatek,net.yaml b/Documentation/devicetree/bindings/net/mediatek,net.yaml -index b45f67f92e80d..cc346946291af 100644 ---- a/Documentation/devicetree/bindings/net/mediatek,net.yaml -+++ b/Documentation/devicetree/bindings/net/mediatek,net.yaml -@@ -112,7 +112,7 @@ properties: - - mediatek,wed: - $ref: /schemas/types.yaml#/definitions/phandle-array -- minItems: 2 -+ minItems: 1 - maxItems: 2 - items: - maxItems: 1 -@@ -249,6 +249,9 @@ allOf: - minItems: 1 - maxItems: 1 - -+ mediatek,wed: -+ minItems: 2 -+ - mediatek,wed-pcie: false - else: - properties: -@@ -338,12 +341,13 @@ allOf: - - const: netsys0 - - const: netsys1 - -- mediatek,infracfg: false -- - mediatek,sgmiisys: - minItems: 2 - maxItems: 2 - -+ mediatek,wed: -+ maxItems: 1 -+ - - if: - properties: - compatible: -@@ -385,6 +389,9 @@ allOf: - minItems: 2 - maxItems: 2 - -+ mediatek,wed: -+ minItems: 2 -+ - - if: - properties: - compatible: -@@ -429,6 +436,19 @@ allOf: - - const: xgp2 - - const: xgp3 - -+ mediatek,wed: -+ minItems: 2 -+ -+ - if: -+ properties: -+ compatible: -+ contains: -+ const: ralink,rt5350-eth -+ then: -+ properties: -+ mediatek,wed: -+ minItems: 2 -+ - patternProperties: - "^mac@[0-2]$": - type: object - -From patchwork Sat Nov 15 20:58:10 2025 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Sjoerd Simons -X-Patchwork-Id: 14315820 -Return-Path: - -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from bombadil.infradead.org (bombadil.infradead.org - [198.137.202.133]) - (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) - (No client certificate requested) - by smtp.lore.kernel.org (Postfix) with ESMTPS id 9FCECCEBF93 - for ; - Sat, 15 Nov 2025 20:58:53 +0000 (UTC) -DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; - d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help - :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References - :Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: - From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: - Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; - bh=ueCHoKYMg9K7QpsQLRQi0Sc30bMhBHa09ApzlEJfMVY=; b=f65hzIYkZWQxPQiFkbXL+XS5yZ - kHKrJv5XISb/3OZ7MrD5/y3j8VxdD9TFeAmEnHaWhFy8WWE/FfcOUvlbEMZXvVK+ZqtgMDjOz+Sms - gPmv1QmrxjH8K/FEqAayZQ/RV2C6pmhlzfyb1zfTNI5/0PvnqjAE0P4OyvKpFn2XRbae66EeuiA0q - Kg+ocXqU4f2vajquQSv7djiJksGmy5qPaU3AEkRoAob5et8ktMl5o1JaF9hMg3F8RUqzj2QmBFBND - bS6TPxR1QCLAIJowA4q4et2YAPPiNHem3Yvzt25SIbMKf4ANCZRWoibEMlgChbuu4bZJrNyqM63kD - k1hHYDww==; -Received: from localhost ([::1] helo=bombadil.infradead.org) - by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) - id 1vKNMC-0000000E5Ny-2dlS; - Sat, 15 Nov 2025 20:58:52 +0000 -Received: from bali.collaboradmins.com ([2a01:4f8:201:9162::2]) - by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) - id 1vKNM0-0000000E58G-2xVt; - Sat, 15 Nov 2025 20:58:42 +0000 -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; - s=mail; t=1763240312; - bh=BQ/4Q4O4iwtOMxBPtuM66Fi5zxdH24aH3c3Edh+F6Gw=; - h=From:Date:Subject:References:In-Reply-To:To:Cc:From; - b=DSjV0V1+pdTcThXzfMFVFxo3AXV/sO/vdOgnuumLXA/McJRmPAAXKSP1q7jizRTcD - d3EYyfDdqRvo5GEp8XZFCsJkQF7jrT7msKMHKMPHXzMx0GrBVxI7uRizgYtf5EOqrj - WSsM8brRdXl9o3g9hU+6oWsWVoQIry5k7OCd0HrYIcgfWzMTBQjedpytCbfrqT8UM2 - yScTd+eEA3Z/sJ/R+8t7hLirwdPAe5OS/1h+w6lmm2Ww99zTZJVraRVfX+X4054Kcs - 0Ig3cE5js9Xu+EF3ozrRoz4n6SWCm6OIcmF7/9Pwxtqo/zqcuBhSqHrYR4i2iKjtIF - vBA3IAlVcFsBw== -Received: from beast.luon.net (simons.connected.by.freedominter.net - [45.83.240.172]) - (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) - key-exchange X25519 server-signature RSA-PSS (4096 bits)) - (No client certificate requested) - (Authenticated sender: sjoerd) - by bali.collaboradmins.com (Postfix) with ESMTPSA id D99D217E129C; - Sat, 15 Nov 2025 21:58:32 +0100 (CET) -Received: by beast.luon.net (Postfix, from userid 1000) - id 3443C110527E5; Sat, 15 Nov 2025 21:58:32 +0100 (CET) -From: Sjoerd Simons -Date: Sat, 15 Nov 2025 21:58:10 +0100 -Subject: [PATCH v4 07/11] arm64: dts: mediatek: mt7981b: Add Ethernet and - WiFi offload support -MIME-Version: 1.0 -Message-Id: <20251115-openwrt-one-network-v4-7-48cbda2969ac@collabora.com> -References: <20251115-openwrt-one-network-v4-0-48cbda2969ac@collabora.com> -In-Reply-To: <20251115-openwrt-one-network-v4-0-48cbda2969ac@collabora.com> -To: Rob Herring , Krzysztof Kozlowski , - Conor Dooley , - Matthias Brugger , - AngeloGioacchino Del Regno , - Ryder Lee , - Jianjun Wang , - Bjorn Helgaas , - Lorenzo Pieralisi , =?utf-8?q?Krzysztof_Wilczy?= - =?utf-8?q?=C5=84ski?= , - Manivannan Sadhasivam , - Chunfeng Yun , Vinod Koul , - Kishon Vijay Abraham I , Lee Jones , - Andrew Lunn , - "David S. Miller" , Eric Dumazet , - Jakub Kicinski , Paolo Abeni , - Lorenzo Bianconi , Felix Fietkau -Cc: kernel@collabora.com, devicetree@vger.kernel.org, - linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, - linux-mediatek@lists.infradead.org, linux-pci@vger.kernel.org, - linux-phy@lists.infradead.org, netdev@vger.kernel.org, - Daniel Golle , Bryan Hinton , - Sjoerd Simons -X-Mailer: b4 0.14.3 -X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 -X-CRM114-CacheID: sfid-20251115_125840_935977_8532D838 -X-CRM114-Status: GOOD ( 12.89 ) -X-BeenThere: linux-mediatek@lists.infradead.org -X-Mailman-Version: 2.1.34 -Precedence: list -List-Id: -List-Unsubscribe: , - -List-Archive: -List-Post: -List-Help: -List-Subscribe: , - -Sender: "Linux-mediatek" -Errors-To: - linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org - -Add device tree nodes for the Ethernet subsystem on MT7981B SoC, -including: -- Ethernet MAC controller with dual GMAC support -- Wireless Ethernet Dispatch (WED) -- SGMII PHY controllers for high-speed Ethernet interfaces -- Reserved memory regions for WiFi offload processor - -Signed-off-by: Sjoerd Simons ---- -V1 -> V2: Don't add unneeded interrupt-parent ---- - arch/arm64/boot/dts/mediatek/mt7981b.dtsi | 133 +++++++++++++++++++++++++++++- - 1 file changed, 132 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi -index d3f37413413e2..6be588be3761a 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi -@@ -2,6 +2,7 @@ - - #include - #include -+#include - #include - #include - -@@ -47,11 +48,36 @@ reserved-memory { - #size-cells = <2>; - ranges; - -+ wo_boot: wo-boot@15194000 { -+ reg = <0 0x15194000 0 0x1000>; -+ no-map; -+ }; -+ -+ wo_ilm0: wo-ilm@151e0000 { -+ reg = <0 0x151e0000 0 0x8000>; -+ no-map; -+ }; -+ -+ wo_dlm0: wo-dlm@151e8000 { -+ reg = <0 0x151e8000 0 0x2000>; -+ no-map; -+ }; -+ - /* 192 KiB reserved for ARM Trusted Firmware (BL31) */ - secmon_reserved: secmon@43000000 { - reg = <0 0x43000000 0 0x30000>; - no-map; - }; -+ -+ wo_emi0: wo-emi@47d80000 { -+ reg = <0 0x47d80000 0 0x40000>; -+ no-map; -+ }; -+ -+ wo_data: wo-data@47dc0000 { -+ reg = <0 0x47dc0000 0 0x240000>; -+ no-map; -+ }; - }; - - soc { -@@ -107,6 +133,18 @@ pwm: pwm@10048000 { - #pwm-cells = <2>; - }; - -+ sgmiisys0: syscon@10060000 { -+ compatible = "mediatek,mt7981-sgmiisys_0", "syscon"; -+ reg = <0 0x10060000 0 0x1000>; -+ #clock-cells = <1>; -+ }; -+ -+ sgmiisys1: syscon@10070000 { -+ compatible = "mediatek,mt7981-sgmiisys_1", "syscon"; -+ reg = <0 0x10070000 0 0x1000>; -+ #clock-cells = <1>; -+ }; -+ - uart0: serial@11002000 { - compatible = "mediatek,mt7981-uart", "mediatek,mt6577-uart"; - reg = <0 0x11002000 0 0x100>; -@@ -345,15 +383,108 @@ soc-uuid@140 { - thermal_calibration: thermal-calib@274 { - reg = <0x274 0xc>; - }; -+ -+ phy_calibration: phy-calib@8dc { -+ reg = <0x8dc 0x10>; -+ }; - }; - -- clock-controller@15000000 { -+ ethsys: clock-controller@15000000 { - compatible = "mediatek,mt7981-ethsys", "syscon"; - reg = <0 0x15000000 0 0x1000>; - #clock-cells = <1>; - #reset-cells = <1>; - }; - -+ wed: wed@15010000 { -+ compatible = "mediatek,mt7981-wed", -+ "syscon"; -+ reg = <0 0x15010000 0 0x1000>; -+ interrupts = ; -+ memory-region = <&wo_emi0>, <&wo_ilm0>, <&wo_dlm0>, -+ <&wo_data>, <&wo_boot>; -+ memory-region-names = "wo-emi", "wo-ilm", "wo-dlm", -+ "wo-data", "wo-boot"; -+ mediatek,wo-ccif = <&wo_ccif0>; -+ }; -+ -+ eth: ethernet@15100000 { -+ compatible = "mediatek,mt7981-eth"; -+ reg = <0 0x15100000 0 0x40000>; -+ assigned-clocks = <&topckgen CLK_TOP_NETSYS_2X_SEL>, -+ <&topckgen CLK_TOP_SGM_325M_SEL>; -+ assigned-clock-parents = <&topckgen CLK_TOP_CB_NET2_800M>, -+ <&topckgen CLK_TOP_CB_SGM_325M>; -+ clocks = <ðsys CLK_ETH_FE_EN>, -+ <ðsys CLK_ETH_GP2_EN>, -+ <ðsys CLK_ETH_GP1_EN>, -+ <ðsys CLK_ETH_WOCPU0_EN>, -+ <&topckgen CLK_TOP_SGM_REG>, -+ <&sgmiisys0 CLK_SGM0_TX_EN>, -+ <&sgmiisys0 CLK_SGM0_RX_EN>, -+ <&sgmiisys0 CLK_SGM0_CK0_EN>, -+ <&sgmiisys0 CLK_SGM0_CDR_CK0_EN>, -+ <&sgmiisys1 CLK_SGM1_TX_EN>, -+ <&sgmiisys1 CLK_SGM1_RX_EN>, -+ <&sgmiisys1 CLK_SGM1_CK1_EN>, -+ <&sgmiisys1 CLK_SGM1_CDR_CK1_EN>, -+ <&topckgen CLK_TOP_NETSYS_SEL>, -+ <&topckgen CLK_TOP_NETSYS_500M_SEL>; -+ clock-names = "fe", "gp2", "gp1", "wocpu0", -+ "sgmii_ck", -+ "sgmii_tx250m", "sgmii_rx250m", -+ "sgmii_cdr_ref", "sgmii_cdr_fb", -+ "sgmii2_tx250m", "sgmii2_rx250m", -+ "sgmii2_cdr_ref", "sgmii2_cdr_fb", -+ "netsys0", "netsys1"; -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ interrupt-names = "fe0", "fe1", "fe2", "fe3", "pdma0", -+ "pdma1", "pdma2", "pdma3"; -+ sram = <ð_sram>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ mediatek,ethsys = <ðsys>; -+ mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>; -+ mediatek,infracfg = <&topmisc>; -+ mediatek,wed = <&wed>; -+ status = "disabled"; -+ -+ mdio_bus: mdio-bus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ int_gbe_phy: ethernet-phy@0 { -+ compatible = "ethernet-phy-ieee802.3-c22"; -+ reg = <0>; -+ phy-mode = "gmii"; -+ phy-is-integrated; -+ nvmem-cells = <&phy_calibration>; -+ nvmem-cell-names = "phy-cal-data"; -+ }; -+ }; -+ }; -+ -+ eth_sram: sram@15140000 { -+ compatible = "mmio-sram"; -+ reg = <0 0x15140000 0 0x40000>; -+ ranges = <0 0x15140000 0 0x40000>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ }; -+ -+ wo_ccif0: syscon@151a5000 { -+ compatible = "mediatek,mt7986-wo-ccif", "syscon"; -+ reg = <0 0x151a5000 0 0x1000>; -+ interrupts = ; -+ }; -+ - wifi@18000000 { - compatible = "mediatek,mt7981-wmac"; - reg = <0 0x18000000 0 0x1000000>, - -From patchwork Sat Nov 15 20:58:11 2025 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Sjoerd Simons -X-Patchwork-Id: 14315821 -Return-Path: - -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from bombadil.infradead.org (bombadil.infradead.org - [198.137.202.133]) - (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) - (No client certificate requested) - by smtp.lore.kernel.org (Postfix) with ESMTPS id B943ACEBF8E - for ; - Sat, 15 Nov 2025 20:58:54 +0000 (UTC) -DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; - d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help - :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References - :Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: - From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: - Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; - bh=VGCX3mgdLYE3ZtU21iczIBrppRvsmuNEB9MXEkOTjzE=; b=LUIcJFboEZjACmWWWdt0hcAX4l - WcRzv0N63RZgr44LTOf7TZYhkDpb78uM3+XEoaGCud4OfzKSpypUT97CxQG5/seVByl6wm5v5wV1n - rBNFM5FTN9aBGtbH2sXav2qjKsGVfsTEdFIw/gEiAkSrTA8vVenI1k2eJhDt582ngOsVxCoTtgk/O - XlnQMerfoIiikumRCpc1bxII0/j0sWC2P1NbyvdzrF7k7dd3KFmoZ1Pk+DH9ChlQUf2fyzZpd+x8+ - nxhUHPW8CHQGJ/TWZ27ThwFWcLeC408X+5yZan5QRwf33Hrr5wiBgZ6pHfapFIQazI2TWK5IMP7AG - IUIyhrzg==; -Received: from localhost ([::1] helo=bombadil.infradead.org) - by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) - id 1vKNMD-0000000E5QA-2g9l; - Sat, 15 Nov 2025 20:58:53 +0000 -Received: from bali.collaboradmins.com ([148.251.105.195]) - by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) - id 1vKNM0-0000000E58H-3gfI; - Sat, 15 Nov 2025 20:58:44 +0000 -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; - s=mail; t=1763240313; - bh=8iJNPpI85EcL2zA7omSQYgyHFc03BY1+Hwd6GqmpZ7c=; - h=From:Date:Subject:References:In-Reply-To:To:Cc:From; - b=bWdQNyPtiD6YGJ5U1tblDalUMjPSFWlLTCVs1FJNg3aM1LzTzH3lOqijc0PR27Mo1 - KP1MmZ0ABQCv2JiSVy45PlI72oyWvYp2oCHe+JKj55k9iN1/R875ODl9Wz+N1pUS9T - tyBqPNG7xr6FgkKbsvN9B8sEi+f0/0TR5e8S1KcoKlzrU8RNl3UHDVUXUsIVTOUlub - AY+RBAnqeyxJCZ95XnzdLRF04IJJtCbw23HDlPLkLOLj4KZ1Q/G+STRfg41qoeN6WW - +KdLLAvUTmF1m2+nvnk2JeBN5EaFsBZJaGfWmgPDFmH1iSJF2SImhGkwVXcI8dsdEM - tZxY2LYuM8Cnw== -Received: from beast.luon.net (simons.connected.by.freedominter.net - [45.83.240.172]) - (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) - key-exchange X25519 server-signature RSA-PSS (4096 bits)) - (No client certificate requested) - (Authenticated sender: sjoerd) - by bali.collaboradmins.com (Postfix) with ESMTPSA id E66F717E1340; - Sat, 15 Nov 2025 21:58:32 +0100 (CET) -Received: by beast.luon.net (Postfix, from userid 1000) - id 37FA8110527E7; Sat, 15 Nov 2025 21:58:32 +0100 (CET) -From: Sjoerd Simons -Date: Sat, 15 Nov 2025 21:58:11 +0100 -Subject: [PATCH v4 08/11] arm64: dts: mediatek: mt7981b-openwrt-one: Enable - Ethernet -MIME-Version: 1.0 -Message-Id: <20251115-openwrt-one-network-v4-8-48cbda2969ac@collabora.com> -References: <20251115-openwrt-one-network-v4-0-48cbda2969ac@collabora.com> -In-Reply-To: <20251115-openwrt-one-network-v4-0-48cbda2969ac@collabora.com> -To: Rob Herring , Krzysztof Kozlowski , - Conor Dooley , - Matthias Brugger , - AngeloGioacchino Del Regno , - Ryder Lee , - Jianjun Wang , - Bjorn Helgaas , - Lorenzo Pieralisi , =?utf-8?q?Krzysztof_Wilczy?= - =?utf-8?q?=C5=84ski?= , - Manivannan Sadhasivam , - Chunfeng Yun , Vinod Koul , - Kishon Vijay Abraham I , Lee Jones , - Andrew Lunn , - "David S. Miller" , Eric Dumazet , - Jakub Kicinski , Paolo Abeni , - Lorenzo Bianconi , Felix Fietkau -Cc: kernel@collabora.com, devicetree@vger.kernel.org, - linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, - linux-mediatek@lists.infradead.org, linux-pci@vger.kernel.org, - linux-phy@lists.infradead.org, netdev@vger.kernel.org, - Daniel Golle , Bryan Hinton , - Sjoerd Simons -X-Mailer: b4 0.14.3 -X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 -X-CRM114-CacheID: sfid-20251115_125841_092912_3F31D9ED -X-CRM114-Status: GOOD ( 11.48 ) -X-BeenThere: linux-mediatek@lists.infradead.org -X-Mailman-Version: 2.1.34 -Precedence: list -List-Id: -List-Unsubscribe: , - -List-Archive: -List-Post: -List-Help: -List-Subscribe: , - -Sender: "Linux-mediatek" -Errors-To: - linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org - -Enable the Ethernet subsystem on OpenWrt One board with dual-MAC -configuration: -- GMAC0: Connected to external Airoha EN8811H 2.5GbE PHY via SGMII - (2500base-x mode) for WAN connectivity with LED indicators -- GMAC1: Connected to internal MT7981 1GbE PHY (GMII mode) for LAN - -Ethernet aliases are defined to provide consistent network interface -naming (ethernet0 = LAN, ethernet1 = WAN). - -Signed-off-by: Sjoerd Simons ---- -V1 -> V2: - - Switch gmac0 phy irq to Level - - Update mac nvmem label name ---- - .../boot/dts/mediatek/mt7981b-openwrt-one.dts | 58 ++++++++++++++++++++++ - 1 file changed, 58 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7981b-openwrt-one.dts b/arch/arm64/boot/dts/mediatek/mt7981b-openwrt-one.dts -index 7382599cfea29..2aea899006453 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7981b-openwrt-one.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7981b-openwrt-one.dts -@@ -12,6 +12,8 @@ / { - model = "OpenWrt One"; - - aliases { -+ ethernet0 = &gmac1; -+ ethernet1 = &gmac0; - serial0 = &uart0; - }; - -@@ -87,6 +89,58 @@ reg_5v: regulator-5v { - }; - }; - -+ð { -+ status = "okay"; -+ -+ /* WAN interface */ -+ gmac0: mac@0 { -+ compatible = "mediatek,eth-mac"; -+ reg = <0>; -+ nvmem-cells = <&wan_factory_mac 0>; -+ nvmem-cell-names = "mac-address"; -+ phy-mode = "2500base-x"; -+ phy-handle = <&phy15>; -+ }; -+ -+ /* LAN interface */ -+ gmac1: mac@1 { -+ compatible = "mediatek,eth-mac"; -+ reg = <1>; -+ phy-mode = "gmii"; -+ phy-handle = <&int_gbe_phy>; -+ }; -+}; -+ -+&mdio_bus { -+ phy15: ethernet-phy@f { -+ compatible = "ethernet-phy-id03a2.a411"; -+ reg = <0xf>; -+ interrupt-parent = <&pio>; -+ interrupts = <38 IRQ_TYPE_LEVEL_LOW>; -+ reset-gpios = <&pio 39 GPIO_ACTIVE_LOW>; -+ reset-assert-us = <10000>; -+ reset-deassert-us = <20000>; -+ airoha,pnswap-rx; -+ -+ leds { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ led@0 { -+ reg = <0>; -+ function = LED_FUNCTION_WAN; -+ color = ; -+ }; -+ -+ led@1 { -+ reg = <1>; -+ function = LED_FUNCTION_WAN; -+ color = ; -+ }; -+ }; -+ }; -+}; -+ - &pcie { - pinctrl-names = "default"; - pinctrl-0 = <&pcie_pins>; -@@ -191,6 +245,10 @@ partition@180000 { - }; - }; - -+&sgmiisys0 { -+ mediatek,pnswap; -+}; -+ - &uart0 { - status = "okay"; - }; - -From patchwork Sat Nov 15 20:58:12 2025 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Sjoerd Simons -X-Patchwork-Id: 14315822 -Return-Path: - -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from bombadil.infradead.org (bombadil.infradead.org - [198.137.202.133]) - (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) - (No client certificate requested) - by smtp.lore.kernel.org (Postfix) with ESMTPS id 72EFDCEBF86 - for ; - Sat, 15 Nov 2025 20:58:56 +0000 (UTC) -DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; - d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help - :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References - :Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: - From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: - Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; - bh=dp/5wNhrbtwapW+ZRZXWBO5in38eZanyORlRgzGBhBc=; b=Fwbv89q7a4W83v5OexqaPCKxV1 - suRDN++YNV+tTGixYfuFsPY4NML93zstLE6//XEqUBSvOnQYz4/2n63iL6iSMyvVyWGASv4s3FYgP - MdRLr5Y40kAJ0dtXyw7Z4VHRlXP4IMJfSDGvGVfu79kXF8pdHwdBGQ1246khAcpw+FexTm2w/xq4g - gTnbTIacarL5c8UO7UcscNW62VAyDPj9jYG+QVKP8TwmhOoZkz9XHNDJRhg4mhbVFOX0dQJN1M1Jq - yo2XVnZGFCpsDLGyVeBfPRFkrI0xizA+alanbqnAGGp48910pyj+yZ1lSkCSUoekyIUD5+p1W9wAg - Qa25H4eg==; -Received: from localhost ([::1] helo=bombadil.infradead.org) - by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) - id 1vKNMF-0000000E5Tc-13xy; - Sat, 15 Nov 2025 20:58:55 +0000 -Received: from bali.collaboradmins.com ([2a01:4f8:201:9162::2]) - by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) - id 1vKNM1-0000000E58h-40C6; - Sat, 15 Nov 2025 20:58:45 +0000 -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; - s=mail; t=1763240314; - bh=haXHZnrCQw87Hh0XlwT4Nqlq0lDr5SGoeyDsPgAcJ6c=; - h=From:Date:Subject:References:In-Reply-To:To:Cc:From; - b=TOoV/J7cx5DpMaFvAYsYvaD9LPvgXxNp7YzX6WYjs3cvvv0YO0wkhBXGgOmqU/Ik7 - citiTlK3d5z1LTbYuHmb6MUtRogL7OxbF6U0iWhIn6Y4MvG2zgv3D7DL0apFPvVNzW - BPaVnpgrMw1xz2XZajY8//z15GGj207k1X6yywHUMOTQab6fKfaJi5WtX/PrgK4nC1 - /HZAdkTMK0OCovro7ffLfFUPelI1Dr3XCSA48/7lOpabn8tVXe3lA3tYWXZpkwiwmJ - qPKcMyPXAONT/3J0p/TPOe38lIR5eCa/W59LppUe1I2oE0djAJ6RZheKd5/xiQ/XHK - by8Tbx2CrPd5Q== -Received: from beast.luon.net (unknown [IPv6:2a10:3781:2531::8]) - (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) - key-exchange X25519 server-signature RSA-PSS (4096 bits)) - (No client certificate requested) - (Authenticated sender: sjoerd) - by bali.collaboradmins.com (Postfix) with ESMTPSA id D5C9D17E141E; - Sat, 15 Nov 2025 21:58:33 +0100 (CET) -Received: by beast.luon.net (Postfix, from userid 1000) - id 3FC51110527E9; Sat, 15 Nov 2025 21:58:32 +0100 (CET) -From: Sjoerd Simons -Date: Sat, 15 Nov 2025 21:58:12 +0100 -Subject: [PATCH v4 09/11] arm64: dts: mediatek: mt7981b: Disable wifi by - default -MIME-Version: 1.0 -Message-Id: <20251115-openwrt-one-network-v4-9-48cbda2969ac@collabora.com> -References: <20251115-openwrt-one-network-v4-0-48cbda2969ac@collabora.com> -In-Reply-To: <20251115-openwrt-one-network-v4-0-48cbda2969ac@collabora.com> -To: Rob Herring , Krzysztof Kozlowski , - Conor Dooley , - Matthias Brugger , - AngeloGioacchino Del Regno , - Ryder Lee , - Jianjun Wang , - Bjorn Helgaas , - Lorenzo Pieralisi , =?utf-8?q?Krzysztof_Wilczy?= - =?utf-8?q?=C5=84ski?= , - Manivannan Sadhasivam , - Chunfeng Yun , Vinod Koul , - Kishon Vijay Abraham I , Lee Jones , - Andrew Lunn , - "David S. Miller" , Eric Dumazet , - Jakub Kicinski , Paolo Abeni , - Lorenzo Bianconi , Felix Fietkau -Cc: kernel@collabora.com, devicetree@vger.kernel.org, - linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, - linux-mediatek@lists.infradead.org, linux-pci@vger.kernel.org, - linux-phy@lists.infradead.org, netdev@vger.kernel.org, - Daniel Golle , Bryan Hinton , - Sjoerd Simons -X-Mailer: b4 0.14.3 -X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 -X-CRM114-CacheID: sfid-20251115_125842_182365_C62C650B -X-CRM114-Status: UNSURE ( 9.83 ) -X-CRM114-Notice: Please train this message. -X-BeenThere: linux-mediatek@lists.infradead.org -X-Mailman-Version: 2.1.34 -Precedence: list -List-Id: -List-Unsubscribe: , - -List-Archive: -List-Post: -List-Help: -List-Subscribe: , - -Sender: "Linux-mediatek" -Errors-To: - linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org - -Disable the wifi block by default as it won't function properly without -at least pin muxing. - -This doesn't enable wifi on any of the existing mt7981b devices as a -required memory-region property is missing, causing the driver to fail -probing anyway. - -Signed-off-by: Sjoerd Simons ---- -V2: Newly introduced patch ---- - arch/arm64/boot/dts/mediatek/mt7981b.dtsi | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi -index 6be588be3761a..1f4c114354660 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi -@@ -499,6 +499,7 @@ wifi@18000000 { - clock-names = "mcu", "ap2conn"; - resets = <&watchdog MT7986_TOPRGU_CONSYS_SW_RST>; - reset-names = "consys"; -+ status = "disabled"; - }; - }; - - -From patchwork Sat Nov 15 20:58:13 2025 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Sjoerd Simons -X-Patchwork-Id: 14315819 -Return-Path: - -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from bombadil.infradead.org (bombadil.infradead.org - [198.137.202.133]) - (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) - (No client certificate requested) - by smtp.lore.kernel.org (Postfix) with ESMTPS id 61E1FCEBF86 - for ; - Sat, 15 Nov 2025 20:58:52 +0000 (UTC) -DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; - d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help - :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References - :Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: - From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: - Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; - bh=nah67Wz58HCqfn8dBCUyWhoscQpKpdn3omH+G+6PS0A=; b=o/TBpCi/Vf2cLUI+X8tmLxdQOC - ZHhNpJngzvb+EbsrBgccoFpN73IW6QBtYtuyK4nfkdxQLBm/k4J/CE636iHJXrJfXkrOvlPjmvVt4 - YYWoYQiX7pw34Ni+0o9yOBZquix7D95A48EeA1WSNPlTCEcjZSI7E2YwTqZTnM79hTpaqOqlmhqQx - 8JlCkv7urbesb/exgDI1CEwLt3gHzby1QrTedAO/xRluCQA6zTdcNGozZ7/pwlrfrRko6jQmAAjCs - 3xPnGa4uPouN73Y0Z0HAn+Z/Px0LtorkAQWVS75FKP7MJ5p3kQwhXWfHSNdH3TNdDNMYwRNo0mjVC - 8psPK2tA==; -Received: from localhost ([::1] helo=bombadil.infradead.org) - by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) - id 1vKNMB-0000000E5M4-2M9i; - Sat, 15 Nov 2025 20:58:51 +0000 -Received: from bali.collaboradmins.com ([148.251.105.195]) - by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) - id 1vKNM0-0000000E58F-1Zb8; - Sat, 15 Nov 2025 20:58:41 +0000 -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; - s=mail; t=1763240313; - bh=HT2YugA6R+JpQglGJhQu+r3GtnpE3Srg2faLNwIOQZE=; - h=From:Date:Subject:References:In-Reply-To:To:Cc:From; - b=bNbPPnOfeO7/8uyPLu4g53QRCgM9HEXjJe5m9jizWuMqv1bd66GC3wXes4BqEafC7 - Er3IiDDMHRHx5VXemgCT3XA2w8NpEBmtnkt+13Ce9C/dFfvVFjOzvB3JJ6atzrG5jf - 3RTcDVNis7UymlFmNM3uXkqEHaMopiO86GJigK9yLOZ15TPjHEqOh1FTQeWm9a1BKW - wkBjK02V9e+V26wU+4SwzCgZ6VNGNlIalOapK+rQTOwzWkMzK9e7A+3A7HPurJB7rq - En185h29EgsM4gR45oiOPHVh0HUTD2BTFrvDXMezknAOEHlhmZGYHTuEvLcxDFnlUf - Fa4myJOYCl5VQ== -Received: from beast.luon.net (simons.connected.by.freedominter.net - [45.83.240.172]) - (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) - key-exchange X25519 server-signature RSA-PSS (4096 bits)) - (No client certificate requested) - (Authenticated sender: sjoerd) - by bali.collaboradmins.com (Postfix) with ESMTPSA id E210917E12FB; - Sat, 15 Nov 2025 21:58:32 +0100 (CET) -Received: by beast.luon.net (Postfix, from userid 1000) - id 450EE110527EB; Sat, 15 Nov 2025 21:58:32 +0100 (CET) -From: Sjoerd Simons -Date: Sat, 15 Nov 2025 21:58:13 +0100 -Subject: [PATCH v4 10/11] arm64: dts: mediatek: mt7981b: Add wifi memory - region -MIME-Version: 1.0 -Message-Id: <20251115-openwrt-one-network-v4-10-48cbda2969ac@collabora.com> -References: <20251115-openwrt-one-network-v4-0-48cbda2969ac@collabora.com> -In-Reply-To: <20251115-openwrt-one-network-v4-0-48cbda2969ac@collabora.com> -To: Rob Herring , Krzysztof Kozlowski , - Conor Dooley , - Matthias Brugger , - AngeloGioacchino Del Regno , - Ryder Lee , - Jianjun Wang , - Bjorn Helgaas , - Lorenzo Pieralisi , =?utf-8?q?Krzysztof_Wilczy?= - =?utf-8?q?=C5=84ski?= , - Manivannan Sadhasivam , - Chunfeng Yun , Vinod Koul , - Kishon Vijay Abraham I , Lee Jones , - Andrew Lunn , - "David S. Miller" , Eric Dumazet , - Jakub Kicinski , Paolo Abeni , - Lorenzo Bianconi , Felix Fietkau -Cc: kernel@collabora.com, devicetree@vger.kernel.org, - linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, - linux-mediatek@lists.infradead.org, linux-pci@vger.kernel.org, - linux-phy@lists.infradead.org, netdev@vger.kernel.org, - Daniel Golle , Bryan Hinton , - Sjoerd Simons -X-Mailer: b4 0.14.3 -X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 -X-CRM114-CacheID: sfid-20251115_125840_614401_F45684EF -X-CRM114-Status: UNSURE ( 9.80 ) -X-CRM114-Notice: Please train this message. -X-BeenThere: linux-mediatek@lists.infradead.org -X-Mailman-Version: 2.1.34 -Precedence: list -List-Id: -List-Unsubscribe: , - -List-Archive: -List-Post: -List-Help: -List-Subscribe: , - -Sender: "Linux-mediatek" -Errors-To: - linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org - -Add required memory region for the builtin wifi block. - -Signed-off-by: Sjoerd Simons ---- -V1 -> V2: Don't set status to in this patch ---- - arch/arm64/boot/dts/mediatek/mt7981b.dtsi | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi -index 1f4c114354660..a7be3670e0059 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi -@@ -69,6 +69,11 @@ secmon_reserved: secmon@43000000 { - no-map; - }; - -+ wmcpu_emi: wmcpu-reserved@47c80000 { -+ reg = <0 0x47c80000 0 0x100000>; -+ no-map; -+ }; -+ - wo_emi0: wo-emi@47d80000 { - reg = <0 0x47d80000 0 0x40000>; - no-map; -@@ -497,6 +502,7 @@ wifi@18000000 { - clocks = <&topckgen CLK_TOP_NETSYS_MCU_SEL>, - <&topckgen CLK_TOP_AP2CNN_HOST_SEL>; - clock-names = "mcu", "ap2conn"; -+ memory-region = <&wmcpu_emi>; - resets = <&watchdog MT7986_TOPRGU_CONSYS_SW_RST>; - reset-names = "consys"; - status = "disabled"; - -From patchwork Sat Nov 15 20:58:14 2025 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Sjoerd Simons -X-Patchwork-Id: 14315824 -Return-Path: - -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from bombadil.infradead.org (bombadil.infradead.org - [198.137.202.133]) - (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) - (No client certificate requested) - by smtp.lore.kernel.org (Postfix) with ESMTPS id D42F4CEBF8E - for ; - Sat, 15 Nov 2025 20:58:58 +0000 (UTC) -DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; - d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help - :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References - :Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: - From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: - Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; - bh=AX63OyLy843bMJU2Vw7R714gkAf6ineUAbu3ZUG0cdE=; b=CFP7+dUXpRGexflyTMYspnXZ3n - sylQlHoSJrbFJM9D3Gr5O5VC/0qmC/HokKEtj0O2UxEYP4nyMyNmmd7Z1ngF5fOKBRv3AwE1W/qDE - HfBu/nlHGZo4C37qRUFaH1NyrJFwoBIXu8Og7whtaEZh2pMn5XGN88I7Ea8vBZNYtE5EJZvic+iLR - YycvmTl/DdfW9JnpVYazqERVD9mETdNc+KoE5HKPxvgXB4x52P4FQtXhLlwaP5QrKzk6Q5+I9xx8F - X74wY6M48if8l1csM70Avt4BNIX5HlMDdevb49MX4SkzYSdenPFrtuYJN4u2nfM0IGut41wHuuIJf - +zxqG4Gw==; -Received: from localhost ([::1] helo=bombadil.infradead.org) - by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) - id 1vKNMH-0000000E5YY-37mo; - Sat, 15 Nov 2025 20:58:57 +0000 -Received: from bali.collaboradmins.com ([148.251.105.195]) - by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) - id 1vKNM2-0000000E58i-0IDV; - Sat, 15 Nov 2025 20:58:45 +0000 -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; - s=mail; t=1763240313; - bh=l3tEWhRqP4lk80hQap0vJX2rjpGnZh5LT9KfShignVs=; - h=From:Date:Subject:References:In-Reply-To:To:Cc:From; - b=ilgjpPSUMlDtGSpNEMVv3z06Af98BhAOQ0MswiSL4weOeq+OEsNFpxJcr1BcQXAzV - jcGlkhNxeuslcmqHhWBUfjNOEvlBz9un+WqLaKJlwi39zf6uBQMQ1yFpa9N7y6/982 - LIfqQ8EPV9nOvXdJA6r5QbJhG6CBsDwcuqXRrZkkOk/9f/ex7ghOeTbpnc4Obp3Bhi - JVuwMqqvSDTvL/C1RG9KBgu54buk+6HnkGCioHGqjeXGlJooCbthCFrszSYtAffEDV - quXKbGwUj0NUYVSK0y71hnH7HkMOIq2b91zM5rL71rpqy+dnFy9I9VnIVKcEy3K8rk - b9SRJW/XnAFNA== -Received: from beast.luon.net (simons.connected.by.freedominter.net - [45.83.240.172]) - (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) - key-exchange X25519 server-signature RSA-PSS (4096 bits)) - (No client certificate requested) - (Authenticated sender: sjoerd) - by bali.collaboradmins.com (Postfix) with ESMTPSA id 16F1F17E13DE; - Sat, 15 Nov 2025 21:58:33 +0100 (CET) -Received: by beast.luon.net (Postfix, from userid 1000) - id 48258110527ED; Sat, 15 Nov 2025 21:58:32 +0100 (CET) -From: Sjoerd Simons -Date: Sat, 15 Nov 2025 21:58:14 +0100 -Subject: [PATCH v4 11/11] arm64: dts: mediatek: mt7981b-openwrt-one: Enable - wifi -MIME-Version: 1.0 -Message-Id: <20251115-openwrt-one-network-v4-11-48cbda2969ac@collabora.com> -References: <20251115-openwrt-one-network-v4-0-48cbda2969ac@collabora.com> -In-Reply-To: <20251115-openwrt-one-network-v4-0-48cbda2969ac@collabora.com> -To: Rob Herring , Krzysztof Kozlowski , - Conor Dooley , - Matthias Brugger , - AngeloGioacchino Del Regno , - Ryder Lee , - Jianjun Wang , - Bjorn Helgaas , - Lorenzo Pieralisi , =?utf-8?q?Krzysztof_Wilczy?= - =?utf-8?q?=C5=84ski?= , - Manivannan Sadhasivam , - Chunfeng Yun , Vinod Koul , - Kishon Vijay Abraham I , Lee Jones , - Andrew Lunn , - "David S. Miller" , Eric Dumazet , - Jakub Kicinski , Paolo Abeni , - Lorenzo Bianconi , Felix Fietkau -Cc: kernel@collabora.com, devicetree@vger.kernel.org, - linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, - linux-mediatek@lists.infradead.org, linux-pci@vger.kernel.org, - linux-phy@lists.infradead.org, netdev@vger.kernel.org, - Daniel Golle , Bryan Hinton , - Sjoerd Simons -X-Mailer: b4 0.14.3 -X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 -X-CRM114-CacheID: sfid-20251115_125842_340042_B6F8A55A -X-CRM114-Status: GOOD ( 11.54 ) -X-BeenThere: linux-mediatek@lists.infradead.org -X-Mailman-Version: 2.1.34 -Precedence: list -List-Id: -List-Unsubscribe: , - -List-Archive: -List-Post: -List-Help: -List-Subscribe: , - -Sender: "Linux-mediatek" -Errors-To: - linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org - -Enable Dual-band WiFI 6 functionality on the Openwrt One - -Signed-off-by: Sjoerd Simons ---- -V2 -> V3: replace MTK_DRIVE_4mA with direct value -V1 -> V2: Update eeprom node label ---- - .../boot/dts/mediatek/mt7981b-openwrt-one.dts | 24 ++++++++++++++++++++++ - arch/arm64/boot/dts/mediatek/mt7981b.dtsi | 2 +- - 2 files changed, 25 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7981b-openwrt-one.dts b/arch/arm64/boot/dts/mediatek/mt7981b-openwrt-one.dts -index 2aea899006453..3de368c73bc81 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7981b-openwrt-one.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7981b-openwrt-one.dts -@@ -180,6 +180,22 @@ conf-pd { - pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; - }; - }; -+ -+ wifi_dbdc_pins: wifi-dbdc-pins { -+ mux { -+ function = "eth"; -+ groups = "wf0_mode1"; -+ }; -+ -+ conf { -+ pins = "WF_HB1", "WF_HB2", "WF_HB3", "WF_HB4", -+ "WF_HB0", "WF_HB0_B", "WF_HB5", "WF_HB6", -+ "WF_HB7", "WF_HB8", "WF_HB9", "WF_HB10", -+ "WF_TOP_CLK", "WF_TOP_DATA", "WF_XO_REQ", -+ "WF_CBA_RESETB", "WF_DIG_RESETB"; -+ drive-strength = <4>; -+ }; -+ }; - }; - - &pwm { -@@ -257,6 +273,14 @@ &usb_phy { - status = "okay"; - }; - -+&wifi { -+ nvmem-cells = <&wifi_factory_calibration>; -+ nvmem-cell-names = "eeprom"; -+ pinctrl-names = "dbdc"; -+ pinctrl-0 = <&wifi_dbdc_pins>; -+ status = "okay"; -+}; -+ - &xhci { - phys = <&u2port0 PHY_TYPE_USB2>; - vusb33-supply = <®_3p3v>; -diff --git a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi -index a7be3670e0059..66d89495bac52 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi -@@ -490,7 +490,7 @@ wo_ccif0: syscon@151a5000 { - interrupts = ; - }; - -- wifi@18000000 { -+ wifi: wifi@18000000 { - compatible = "mediatek,mt7981-wmac"; - reg = <0 0x18000000 0 0x1000000>, - <0 0x10003000 0 0x1000>, diff --git a/pkgs/linux-openwrt-one.patch b/pkgs/linux-openwrt-one.patch deleted file mode 100644 index 62c20ad..0000000 --- a/pkgs/linux-openwrt-one.patch +++ /dev/null @@ -1,2508 +0,0 @@ -From 9c7cb0b21491ba7fd804f669b969418e33270142 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Wed, 28 Dec 2022 23:44:42 +0000 -Subject: [PATCH 01/12] complete mt7981 dts - -working: - * Ethernet (fully working incl. ppe) - * UART - * SPI-NAND flash - * thermal sensors (SoC and mxl-gpy) - * random number generator via SMC - * USB 1.1, 2.0 and 3.0 - * WiFi with MT7976C 2.4G+5G DBDC incl. WED offloading - * PWM ---- - arch/arm64/boot/dts/mediatek/mt7981b.dtsi | 566 +++++++++++++++++++++- - 1 file changed, 554 insertions(+), 12 deletions(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi -index 5cbea9cd411f..6a816e5c1f46 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi -@@ -1,7 +1,14 @@ - // SPDX-License-Identifier: GPL-2.0-only OR MIT - - #include -+#include -+#include - #include -+#include -+#include -+#include -+#include -+#include - #include - - / { -@@ -41,6 +48,57 @@ psci { - method = "smc"; - }; - -+ fan: pwm-fan { -+ compatible = "pwm-fan"; -+ /* cooling level (0, 1, 2, 3) : (0% duty, 50% duty, 75% duty, 100% duty) */ -+ cooling-levels = <0 128 192 255>; -+ #cooling-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ reg_3p3v: regulator-3p3v { -+ compatible = "regulator-fixed"; -+ regulator-name = "fixed-3.3V"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ reserved-memory { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ ranges; -+ -+ /* 64 KiB reserved for ramoops/pstore */ -+ ramoops@42ff0000 { -+ compatible = "ramoops"; -+ reg = <0 0x42ff0000 0 0x10000>; -+ record-size = <0x1000>; -+ }; -+ -+ /* 192 KiB reserved for ARM Trusted Firmware (BL31) */ -+ secmon_reserved: secmon@43000000 { -+ reg = <0 0x43000000 0 0x30000>; -+ no-map; -+ }; -+ -+ wmcpu_emi: wmcpu-reserved@47c80000 { -+ reg = <0 0x47c80000 0 0x100000>; -+ no-map; -+ }; -+ -+ wo_emi0: wo-emi@47d80000 { -+ reg = <0 0x47d80000 0 0x40000>; -+ no-map; -+ }; -+ -+ wo_data: wo-data@47dc0000 { -+ reg = <0 0x47dc0000 0 0x240000>; -+ no-map; -+ }; -+ }; -+ - soc { - compatible = "simple-bus"; - ranges; -@@ -76,13 +134,13 @@ watchdog: watchdog@1001c000 { - #reset-cells = <1>; - }; - -- clock-controller@1001e000 { -- compatible = "mediatek,mt7981-apmixedsys"; -+ apmixedsys: clock-controller@1001e000 { -+ compatible = "mediatek,mt7981-apmixedsys", "syscon"; - reg = <0 0x1001e000 0 0x1000>; - #clock-cells = <1>; - }; - -- pwm@10048000 { -+ pwm: pwm@10048000 { - compatible = "mediatek,mt7981-pwm"; - reg = <0 0x10048000 0 0x1000>; - clocks = <&infracfg CLK_INFRA_PWM_STA>, -@@ -94,7 +152,21 @@ pwm@10048000 { - #pwm-cells = <2>; - }; - -- serial@11002000 { -+ crypto: crypto@10320000 { -+ compatible = "inside-secure,safexcel-eip97"; -+ reg = <0 0x10320000 0 0x40000>; -+ interrupts = , -+ , -+ , -+ ; -+ interrupt-names = "ring0", "ring1", "ring2", "ring3"; -+ clocks = <&topckgen CLK_TOP_EIP97B>; -+ clock-names = "top_eip97_ck"; -+ assigned-clocks = <&topckgen CLK_TOP_EIP97B_SEL>; -+ assigned-clock-parents = <&topckgen CLK_TOP_CB_NET1_D5>; -+ }; -+ -+ uart0: serial@11002000 { - compatible = "mediatek,mt7981-uart", "mediatek,mt6577-uart"; - reg = <0 0x11002000 0 0x100>; - interrupts = ; -@@ -105,7 +177,7 @@ serial@11002000 { - status = "disabled"; - }; - -- serial@11003000 { -+ uart1: serial@11003000 { - compatible = "mediatek,mt7981-uart", "mediatek,mt6577-uart"; - reg = <0 0x11003000 0 0x100>; - interrupts = ; -@@ -116,7 +188,7 @@ serial@11003000 { - status = "disabled"; - }; - -- serial@11004000 { -+ uart2: serial@11004000 { - compatible = "mediatek,mt7981-uart", "mediatek,mt6577-uart"; - reg = <0 0x11004000 0 0x100>; - interrupts = ; -@@ -127,11 +199,12 @@ serial@11004000 { - status = "disabled"; - }; - -- i2c@11007000 { -+ i2c0: i2c@11007000 { - compatible = "mediatek,mt7981-i2c"; - reg = <0 0x11007000 0 0x1000>, - <0 0x10217080 0 0x80>; - interrupts = ; -+ clock-div = <1>; - clocks = <&infracfg CLK_INFRA_I2C0_CK>, - <&infracfg CLK_INFRA_AP_DMA_CK>, - <&infracfg CLK_INFRA_I2C_MCK_CK>, -@@ -142,7 +215,32 @@ i2c@11007000 { - status = "disabled"; - }; - -- spi@11009000 { -+ thermal: thermal@1100c800 { -+ #thermal-sensor-cells = <1>; -+ compatible = "mediatek,mt7981-thermal", "mediatek,mt7986-thermal"; -+ reg = <0 0x1100c800 0 0x800>; -+ interrupts = ; -+ clocks = <&infracfg CLK_INFRA_THERM_CK>, -+ <&infracfg CLK_INFRA_ADC_26M_CK>; -+ clock-names = "therm", "auxadc"; -+ mediatek,auxadc = <&auxadc>; -+ mediatek,apmixedsys = <&apmixedsys>; -+ nvmem-cells = <&thermal_calibration>; -+ nvmem-cell-names = "calibration-data"; -+ }; -+ -+ auxadc: adc@1100d000 { -+ compatible = "mediatek,mt7981-auxadc", -+ "mediatek,mt7986-auxadc", -+ "mediatek,mt7622-auxadc"; -+ reg = <0 0x1100d000 0 0x1000>; -+ clocks = <&infracfg CLK_INFRA_ADC_26M_CK>, -+ <&infracfg CLK_INFRA_ADC_FRC_CK>; -+ clock-names = "main", "32k"; -+ #io-channel-cells = <1>; -+ }; -+ -+ spi2: spi@11009000 { - compatible = "mediatek,mt7981-spi-ipm", "mediatek,spi-ipm"; - reg = <0 0x11009000 0 0x1000>; - interrupts = ; -@@ -156,7 +254,7 @@ spi@11009000 { - status = "disabled"; - }; - -- spi@1100a000 { -+ spi0: spi@1100a000 { - compatible = "mediatek,mt7981-spi-ipm", "mediatek,spi-ipm"; - reg = <0 0x1100a000 0 0x1000>; - interrupts = ; -@@ -170,7 +268,7 @@ spi@1100a000 { - status = "disabled"; - }; - -- spi@1100b000 { -+ spi1: spi@1100b000 { - compatible = "mediatek,mt7981-spi-ipm", "mediatek,spi-ipm"; - reg = <0 0x1100b000 0 0x1000>; - interrupts = ; -@@ -184,6 +282,41 @@ spi@1100b000 { - status = "disabled"; - }; - -+ pcie: pcie@11280000 { -+ compatible = "mediatek,mt7981-pcie", -+ "mediatek,mt8192-pcie"; -+ device_type = "pci"; -+ reg = <0 0x11280000 0 0x4000>; -+ reg-names = "pcie-mac"; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ interrupts = ; -+ bus-range = <0x00 0xff>; -+ ranges = <0x82000000 0 0x20000000 -+ 0x0 0x20000000 0 0x10000000>; -+ status = "disabled"; -+ -+ clocks = <&infracfg CLK_INFRA_IPCIE_CK>, -+ <&infracfg CLK_INFRA_IPCIE_PIPE_CK>, -+ <&infracfg CLK_INFRA_IPCIER_CK>, -+ <&infracfg CLK_INFRA_IPCIEB_CK>; -+ -+ phys = <&u3port0 PHY_TYPE_PCIE>; -+ phy-names = "pcie-phy"; -+ -+ #interrupt-cells = <1>; -+ interrupt-map-mask = <0 0 0 7>; -+ interrupt-map = <0 0 0 1 &pcie_intc 0>, -+ <0 0 0 2 &pcie_intc 1>, -+ <0 0 0 3 &pcie_intc 2>, -+ <0 0 0 4 &pcie_intc 3>; -+ pcie_intc: interrupt-controller { -+ interrupt-controller; -+ #address-cells = <0>; -+ #interrupt-cells = <1>; -+ }; -+ }; -+ - pio: pinctrl@11d00000 { - compatible = "mediatek,mt7981-pinctrl"; - reg = <0 0x11d00000 0 0x1000>, -@@ -204,6 +337,49 @@ pio: pinctrl@11d00000 { - gpio-controller; - #gpio-cells = <2>; - #interrupt-cells = <2>; -+ -+ mdio_pins: mdc-mdio-pins { -+ mux { -+ function = "eth"; -+ groups = "smi_mdc_mdio"; -+ }; -+ }; -+ -+ uart0_pins: uart0-pins { -+ mux { -+ function = "uart"; -+ groups = "uart0"; -+ }; -+ }; -+ -+ wifi_dbdc_pins: wifi-dbdc-pins { -+ mux { -+ function = "eth"; -+ groups = "wf0_mode1"; -+ }; -+ conf { -+ pins = "WF_HB1", "WF_HB2", "WF_HB3", "WF_HB4", -+ "WF_HB0", "WF_HB0_B", "WF_HB5", "WF_HB6", -+ "WF_HB7", "WF_HB8", "WF_HB9", "WF_HB10", -+ "WF_TOP_CLK", "WF_TOP_DATA", "WF_XO_REQ", -+ "WF_CBA_RESETB", "WF_DIG_RESETB"; -+ drive-strength = ; -+ }; -+ }; -+ -+ gbe_led0_pins: gbe-led0-pins { -+ mux { -+ function = "led"; -+ groups = "gbe_led0"; -+ }; -+ }; -+ -+ gbe_led1_pins: gbe-led1-pins { -+ mux { -+ function = "led"; -+ groups = "gbe_led1"; -+ }; -+ }; - }; - - efuse@11f20000 { -@@ -211,17 +387,318 @@ efuse@11f20000 { - reg = <0 0x11f20000 0 0x1000>; - #address-cells = <1>; - #size-cells = <1>; -+ -+ thermal_calibration: thermal-calib@274 { -+ reg = <0x274 0xc>; -+ }; -+ -+ phy_calibration: phy-calib@8dc { -+ reg = <0x8dc 0x10>; -+ }; -+ -+ comb_rx_imp_p0: usb3-rx-imp@8c8 { -+ reg = <0x8c8 1>; -+ bits = <0 5>; -+ }; -+ -+ comb_tx_imp_p0: usb3-tx-imp@8c8 { -+ reg = <0x8c8 2>; -+ bits = <5 5>; -+ }; -+ -+ comb_intr_p0: usb3-intr@8c9 { -+ reg = <0x8c9 1>; -+ bits = <2 6>; -+ }; - }; - -- clock-controller@15000000 { -+ ethsys: clock-controller@15000000 { - compatible = "mediatek,mt7981-ethsys", "syscon"; - reg = <0 0x15000000 0 0x1000>; - #clock-cells = <1>; - #reset-cells = <1>; - }; - -- wifi@18000000 { -+ wed: wed@15010000 { -+ compatible = "mediatek,mt7981-wed", -+ "mediatek,mt7986-wed", -+ "syscon"; -+ reg = <0 0x15010000 0 0x1000>; -+ interrupt-parent = <&gic>; -+ interrupts = ; -+ memory-region = <&wo_emi0>, <&wo_data>; -+ memory-region-names = "wo-emi", "wo-data"; -+ mediatek,wo-ccif = <&wo_ccif0>; -+ mediatek,wo-ilm = <&wo_ilm0>; -+ mediatek,wo-dlm = <&wo_dlm0>; -+ mediatek,wo-cpuboot = <&wo_cpuboot>; -+ }; -+ -+ eth: ethernet@15100000 { -+ compatible = "mediatek,mt7981-eth"; -+ reg = <0 0x15100000 0 0x80000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ interrupts = , -+ , -+ , -+ ; -+ clocks = <ðsys CLK_ETH_FE_EN>, -+ <ðsys CLK_ETH_GP2_EN>, -+ <ðsys CLK_ETH_GP1_EN>, -+ <ðsys CLK_ETH_WOCPU0_EN>, -+ <&sgmiisys0 CLK_SGM0_TX_EN>, -+ <&sgmiisys0 CLK_SGM0_RX_EN>, -+ <&sgmiisys0 CLK_SGM0_CK0_EN>, -+ <&sgmiisys0 CLK_SGM0_CDR_CK0_EN>, -+ <&sgmiisys1 CLK_SGM1_TX_EN>, -+ <&sgmiisys1 CLK_SGM1_RX_EN>, -+ <&sgmiisys1 CLK_SGM1_CK1_EN>, -+ <&sgmiisys1 CLK_SGM1_CDR_CK1_EN>, -+ <&topckgen CLK_TOP_SGM_REG>, -+ <&topckgen CLK_TOP_NETSYS_SEL>, -+ <&topckgen CLK_TOP_NETSYS_500M_SEL>; -+ clock-names = "fe", "gp2", "gp1", "wocpu0", -+ "sgmii_tx250m", "sgmii_rx250m", -+ "sgmii_cdr_ref", "sgmii_cdr_fb", -+ "sgmii2_tx250m", "sgmii2_rx250m", -+ "sgmii2_cdr_ref", "sgmii2_cdr_fb", -+ "sgmii_ck", "netsys0", "netsys1"; -+ assigned-clocks = <&topckgen CLK_TOP_NETSYS_2X_SEL>, -+ <&topckgen CLK_TOP_SGM_325M_SEL>; -+ assigned-clock-parents = <&topckgen CLK_TOP_CB_NET2_800M>, -+ <&topckgen CLK_TOP_CB_SGM_325M>; -+ mediatek,ethsys = <ðsys>; -+ mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>; -+ mediatek,infracfg = <&topmisc>; -+ mediatek,wed = <&wed>; -+ status = "disabled"; -+ -+ mdio_bus: mdio-bus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ int_gbe_phy: ethernet-phy@0 { -+ reg = <0>; -+ compatible = "ethernet-phy-ieee802.3-c22"; -+ phy-mode = "gmii"; -+ phy-is-integrated; -+ nvmem-cells = <&phy_calibration>; -+ nvmem-cell-names = "phy-cal-data"; -+ -+ leds { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ int_gbe_phy_led0: int-gbe-phy-led0@0 { -+ reg = <0>; -+ function = LED_FUNCTION_LAN; -+ pinctrl-0 = <&gbe_led0_pins>; -+ pinctrl-names = "default"; -+ status = "disabled"; -+ }; -+ -+ int_gbe_phy_led1: int-gbe-phy-led1@1 { -+ reg = <1>; -+ function = LED_FUNCTION_LAN; -+ pinctrl-0 = <&gbe_led1_pins>; -+ pinctrl-names = "default"; -+ status = "disabled"; -+ }; -+ }; -+ }; -+ }; -+ }; -+ -+ wdma: wdma@15104800 { -+ compatible = "mediatek,wed-wdma"; -+ reg = <0 0x15104800 0 0x400>, -+ <0 0x15104c00 0 0x400>; -+ }; -+ -+ ap2woccif: ap2woccif@151a5000 { -+ compatible = "mediatek,ap2woccif"; -+ reg = <0 0x151a5000 0 0x1000>, -+ <0 0x151ad000 0 0x1000>; -+ interrupt-parent = <&gic>; -+ interrupts = , -+ ; -+ }; -+ -+ wo_dlm0: syscon@151e8000 { -+ compatible = "mediatek,mt7986-wo-dlm", "syscon"; -+ reg = <0 0x151e8000 0 0x2000>; -+ }; -+ -+ wo_ilm0: syscon@151e0000 { -+ compatible = "mediatek,mt7986-wo-ilm", "syscon"; -+ reg = <0 0x151e0000 0 0x8000>; -+ }; -+ -+ wo_cpuboot: syscon@15194000 { -+ compatible = "mediatek,mt7986-wo-cpuboot", "syscon"; -+ reg = <0 0x15194000 0 0x1000>; -+ }; -+ -+ wo_ccif0: syscon@151a5000 { -+ compatible = "mediatek,mt7986-wo-ccif", "syscon"; -+ reg = <0 0x151a5000 0 0x1000>; -+ interrupt-parent = <&gic>; -+ interrupts = ; -+ }; -+ -+ sgmiisys0: syscon@10060000 { -+ compatible = "mediatek,mt7981-sgmiisys_0", "mediatek,mt7986-sgmiisys_0", "syscon"; -+ reg = <0 0x10060000 0 0x1000>; -+ mediatek,pnswap; -+ #clock-cells = <1>; -+ }; -+ -+ sgmiisys1: syscon@10070000 { -+ compatible = "mediatek,mt7981-sgmiisys_1", "mediatek,mt7986-sgmiisys_1", "syscon"; -+ reg = <0 0x10070000 0 0x1000>; -+ #clock-cells = <1>; -+ }; -+ -+ topmisc: topmisc@11d10000 { -+ compatible = "mediatek,mt7981-topmisc", "syscon"; -+ reg = <0 0x11d10000 0 0x10000>; -+ #clock-cells = <1>; -+ }; -+ -+ snand: snfi@11005000 { -+ compatible = "mediatek,mt7986-snand"; -+ reg = <0 0x11005000 0 0x1000>, <0 0x11006000 0 0x1000>; -+ reg-names = "nfi", "ecc"; -+ interrupts = ; -+ clocks = <&infracfg CLK_INFRA_SPINFI1_CK>, -+ <&infracfg CLK_INFRA_NFI1_CK>, -+ <&infracfg CLK_INFRA_NFI_HCK_CK>; -+ clock-names = "pad_clk", "nfi_clk", "nfi_hclk"; -+ assigned-clocks = <&topckgen CLK_TOP_SPINFI_SEL>, -+ <&topckgen CLK_TOP_NFI1X_SEL>; -+ assigned-clock-parents = <&topckgen CLK_TOP_CB_M_D8>, -+ <&topckgen CLK_TOP_CB_M_D8>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ mmc0: mmc@11230000 { -+ compatible = "mediatek,mt7986-mmc", -+ "mediatek,mt7981-mmc"; -+ reg = <0 0x11230000 0 0x1000>, <0 0x11c20000 0 0x1000>; -+ interrupts = ; -+ clocks = <&infracfg CLK_INFRA_MSDC_CK>, -+ <&infracfg CLK_INFRA_MSDC_HCK_CK>, -+ <&infracfg CLK_INFRA_MSDC_66M_CK>, -+ <&infracfg CLK_INFRA_MSDC_133M_CK>; -+ assigned-clocks = <&topckgen CLK_TOP_EMMC_208M_SEL>, -+ <&topckgen CLK_TOP_EMMC_400M_SEL>; -+ assigned-clock-parents = <&topckgen CLK_TOP_CB_M_D2>, -+ <&topckgen CLK_TOP_CB_NET2_D2>; -+ clock-names = "source", "hclk", "axi_cg", "ahb_cg"; -+ status = "disabled"; -+ }; -+ -+ wed_pcie: wed_pcie@10003000 { -+ compatible = "mediatek,wed_pcie"; -+ reg = <0 0x10003000 0 0x10>; -+ }; -+ -+ consys: consys@10000000 { -+ compatible = "mediatek,mt7981-consys"; -+ reg = <0 0x10000000 0 0x8600000>; -+ memory-region = <&wmcpu_emi>; -+ }; -+ -+ xhci: usb@11200000 { -+ compatible = "mediatek,mt7986-xhci", -+ "mediatek,mtk-xhci"; -+ reg = <0 0x11200000 0 0x2e00>, -+ <0 0x11203e00 0 0x0100>; -+ reg-names = "mac", "ippc"; -+ interrupts = ; -+ clocks = <&infracfg CLK_INFRA_IUSB_SYS_CK>, -+ <&infracfg CLK_INFRA_IUSB_CK>, -+ <&infracfg CLK_INFRA_IUSB_133_CK>, -+ <&infracfg CLK_INFRA_IUSB_66M_CK>, -+ <&topckgen CLK_TOP_U2U3_XHCI_SEL>; -+ clock-names = "sys_ck", -+ "ref_ck", -+ "mcu_ck", -+ "dma_ck", -+ "xhci_ck"; -+ phys = <&u2port0 PHY_TYPE_USB2>, -+ <&u3port0 PHY_TYPE_USB3>; -+ vusb33-supply = <®_3p3v>; -+ status = "disabled"; -+ }; -+ -+ usb_phy: usb-phy@11e10000 { -+ compatible = "mediatek,mt7981", -+ "mediatek,generic-tphy-v2"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0 0 0x11e10000 0x1700>; -+ status = "disabled"; -+ -+ u2port0: usb-phy@0 { -+ reg = <0x0 0x700>; -+ clocks = <&topckgen CLK_TOP_USB_FRMCNT_SEL>; -+ clock-names = "ref"; -+ #phy-cells = <1>; -+ }; -+ -+ u3port0: usb-phy@700 { -+ reg = <0x700 0x900>; -+ clocks = <&topckgen CLK_TOP_USB3_PHY_SEL>; -+ clock-names = "ref"; -+ #phy-cells = <1>; -+ mediatek,syscon-type = <&topmisc 0x218 0>; -+ status = "okay"; -+ }; -+ }; -+ -+ -+ afe: audio-controller@11210000 { -+ compatible = "mediatek,mt79xx-audio"; -+ reg = <0 0x11210000 0 0x9000>; -+ interrupts = ; -+ clocks = <&infracfg CLK_INFRA_AUD_BUS_CK>, -+ <&infracfg CLK_INFRA_AUD_26M_CK>, -+ <&infracfg CLK_INFRA_AUD_L_CK>, -+ <&infracfg CLK_INFRA_AUD_AUD_CK>, -+ <&infracfg CLK_INFRA_AUD_EG2_CK>, -+ <&topckgen CLK_TOP_AUD_SEL>; -+ clock-names = "aud_bus_ck", -+ "aud_26m_ck", -+ "aud_l_ck", -+ "aud_aud_ck", -+ "aud_eg2_ck", -+ "aud_sel"; -+ assigned-clocks = <&topckgen CLK_TOP_AUD_SEL>, -+ <&topckgen CLK_TOP_A1SYS_SEL>, -+ <&topckgen CLK_TOP_AUD_L_SEL>, -+ <&topckgen CLK_TOP_A_TUNER_SEL>; -+ assigned-clock-parents = <&topckgen CLK_TOP_CB_APLL2_196M>, -+ <&topckgen CLK_TOP_APLL2_D4>, -+ <&topckgen CLK_TOP_CB_APLL2_196M>, -+ <&topckgen CLK_TOP_APLL2_D4>; -+ status = "disabled"; -+ }; -+ -+ ice: ice_debug { -+ compatible = "mediatek,mt7981-ice_debug", -+ "mediatek,mt2701-ice_debug"; -+ clocks = <&infracfg CLK_INFRA_DBG_CK>; -+ clock-names = "ice_dbg"; -+ }; -+ -+ wifi: wifi@18000000 { - compatible = "mediatek,mt7981-wmac"; -+ pinctrl-0 = <&wifi_dbdc_pins>; -+ pinctrl-names = "dbdc"; - reg = <0 0x18000000 0 0x1000000>, - <0 0x10003000 0 0x1000>, - <0 0x11d10000 0 0x1000>; -@@ -234,6 +711,67 @@ wifi@18000000 { - clock-names = "mcu", "ap2conn"; - resets = <&watchdog MT7986_TOPRGU_CONSYS_SW_RST>; - reset-names = "consys"; -+ memory-region = <&wmcpu_emi>; -+ status = "disabled"; -+ }; -+ }; -+ -+ thermal-zones { -+ cpu_thermal: cpu-thermal { -+ polling-delay-passive = <1000>; -+ polling-delay = <1000>; -+ thermal-sensors = <&thermal 0>; -+ trips { -+ cpu_trip_crit: crit { -+ temperature = <125000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ -+ cpu_trip_hot: hot { -+ temperature = <120000>; -+ hysteresis = <2000>; -+ type = "hot"; -+ }; -+ -+ cpu_trip_active_high: active-high { -+ temperature = <115000>; -+ hysteresis = <2000>; -+ type = "active"; -+ }; -+ -+ cpu_trip_active_med: active-med { -+ temperature = <85000>; -+ hysteresis = <2000>; -+ type = "active"; -+ }; -+ -+ cpu_trip_active_low: active-low { -+ temperature = <60000>; -+ hysteresis = <2000>; -+ type = "active"; -+ }; -+ }; -+ -+ cooling-maps { -+ cpu-active-high { -+ /* active: set fan to cooling level 3 */ -+ cooling-device = <&fan 3 3>; -+ trip = <&cpu_trip_active_high>; -+ }; -+ -+ cpu-active-med { -+ /* active: set fan to cooling level 2 */ -+ cooling-device = <&fan 2 2>; -+ trip = <&cpu_trip_active_med>; -+ }; -+ -+ cpu-active-low { -+ /* passive: set fan to cooling level 1 */ -+ cooling-device = <&fan 1 1>; -+ trip = <&cpu_trip_active_low>; -+ }; -+ }; - }; - }; - -@@ -245,4 +783,8 @@ timer { - , - ; - }; -+ -+ trng { -+ compatible = "mediatek,mt7981-rng"; -+ }; - }; --- -2.51.0 - - -From c99275204c5709fa159c2cbbdc6dd25bad49f882 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Thu, 2 Oct 2025 11:54:23 +0200 -Subject: [PATCH 02/12] Pull OpenWrt One device tree from OpenWrt master - -The commit used: 915a57ccd9086db88ee74cfa531ff13f8652a447 ---- - .../boot/dts/mediatek/mt7981b-openwrt-one.dts | 460 +++++++++++++++++- - 1 file changed, 457 insertions(+), 3 deletions(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7981b-openwrt-one.dts b/arch/arm64/boot/dts/mediatek/mt7981b-openwrt-one.dts -index 4f6cbb491287..5f54506b2cba 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7981b-openwrt-one.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7981b-openwrt-one.dts -@@ -1,15 +1,469 @@ --// SPDX-License-Identifier: GPL-2.0-only OR MIT -+// SPDX-License-Identifier: (GPL-2.0 OR MIT) - - /dts-v1/; -- - #include "mt7981b.dtsi" - - / { -- compatible = "openwrt,one", "mediatek,mt7981b"; - model = "OpenWrt One"; -+ compatible = "openwrt,one", "mediatek,mt7981"; -+ -+ aliases { -+ ethernet0 = &gmac1; -+ label-mac-device = &gmac0; -+ led-boot = &led_status_white; -+ led-failsafe = &led_status_red; -+ led-running = &led_status_green; -+ led-upgrade = &led_status_green; -+ serial0 = &uart0; -+ }; -+ -+ chosen { -+ stdout-path = "serial0:115200n8"; -+ rootdisk = <&ubi_fit_volume>; -+ }; - - memory@40000000 { - reg = <0 0x40000000 0 0x40000000>; - device_type = "memory"; - }; -+ -+ reg_3p3v: regulator-3p3v { -+ compatible = "regulator-fixed"; -+ regulator-name = "fixed-3.3V"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ reg_5v: regulator-5v { -+ compatible = "regulator-fixed"; -+ regulator-name = "fixed-5V"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ gpio-keys { -+ compatible = "gpio-keys"; -+ -+ user { -+ label = "user"; -+ linux,code = ; -+ gpios = <&pio 0 GPIO_ACTIVE_LOW>; -+ }; -+ -+ reset { -+ label = "reset"; -+ linux,code = ; -+ gpios = <&pio 1 GPIO_ACTIVE_LOW>; -+ }; -+ }; -+ -+ pwm-leds { -+ compatible = "pwm-leds"; -+ -+ led_status_white: led-0 { -+ color = ; -+ function = LED_FUNCTION_STATUS; -+ pwms = <&pwm 0 10000>; -+ linux,default-trigger = "pattern"; -+ led-pattern = <0 500 25 500>; -+ }; -+ -+ led_status_green: led-1 { -+ color = ; -+ function = LED_FUNCTION_STATUS; -+ pwms = <&pwm 1 10000>; -+ }; -+ }; -+ -+ gpio-leds { -+ compatible = "gpio-leds"; -+ -+ led_status_red: led-0 { -+ color = ; -+ function = LED_FUNCTION_STATUS; -+ gpios = <&pio 9 GPIO_ACTIVE_HIGH>; -+ }; -+ -+ led-1 { -+ function = LED_FUNCTION_LAN; -+ color = ; -+ gpios = <&pio 34 GPIO_ACTIVE_LOW>; -+ }; -+ -+ led-2 { -+ function = LED_FUNCTION_LAN; -+ color = ; -+ gpios = <&pio 35 GPIO_ACTIVE_LOW>; -+ }; -+ }; -+ -+ gpio-export { -+ compatible = "gpio-export"; -+ -+ gpio-0 { -+ gpio-export,name = "mikrobus-reset"; -+ gpio-export,output = <1>; -+ gpios = <&pio 2 GPIO_ACTIVE_HIGH>; -+ }; -+ -+ gpio-1 { -+ gpio-export,name = "watchdog-enable"; -+ gpio-export,output = <1>; -+ gpios = <&pio 11 GPIO_ACTIVE_HIGH>; -+ }; -+ -+ gpio-2 { -+ gpio-export,name = "usb-enable"; -+ gpio-export,output = <1>; -+ gpios = <&pio 14 GPIO_ACTIVE_HIGH>; -+ }; -+ }; -+ -+ gpio-watchdog { -+ compatible = "linux,wdt-gpio"; -+ gpios = <&pio 8 GPIO_ACTIVE_LOW>; -+ hw_algo = "toggle"; -+ hw_margin_ms = <25000>; -+ always-running; -+ }; -+}; -+ -+ð { -+ status = "okay"; -+ -+ gmac0: mac@0 { -+ compatible = "mediatek,eth-mac"; -+ reg = <0>; -+ phy-handle = <&phy15>; -+ phy-mode = "2500base-x"; -+ nvmem-cell-names = "mac-address"; -+ nvmem-cells = <&macaddr_factory_24>; -+ }; -+ -+ gmac1: mac@1 { -+ compatible = "mediatek,eth-mac"; -+ reg = <1>; -+ phy-mode = "gmii"; -+ phy-handle = <&int_gbe_phy>; -+ }; -+}; -+ -+&mdio_bus { -+ phy15: phy@f { -+ reg = <0xf>; -+ -+ airoha,pnswap-rx; -+ -+ interrupt-parent = <&pio>; -+ interrupts = <38 IRQ_TYPE_EDGE_FALLING>; -+ reset-gpios = <&pio 39 GPIO_ACTIVE_LOW>; -+ reset-assert-us = <10000>; -+ reset-deassert-us = <20000>; -+ -+ phy-mode = "2500base-x"; -+ full-duplex; -+ pause; -+ -+ leds { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ led@0 { -+ reg = <0>; -+ function = LED_FUNCTION_WAN; -+ color = ; -+ }; -+ -+ led@1 { -+ reg = <1>; -+ function = LED_FUNCTION_WAN; -+ color = ; -+ }; -+ }; -+ }; -+}; -+ -+&crypto { -+ status = "okay"; -+}; -+ -+&pio { -+ spi0_flash_pins: spi0-pins { -+ mux { -+ function = "spi"; -+ groups = "spi0", "spi0_wp_hold"; -+ }; -+ -+ conf-pu { -+ pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP"; -+ drive-strength = ; -+ bias-pull-up = ; -+ }; -+ -+ conf-pd { -+ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO"; -+ drive-strength = ; -+ bias-pull-down = ; -+ }; -+ }; -+ -+ spi1_flash_pins: spi1-pins { -+ mux { -+ function = "spi"; -+ groups = "spi1_1"; -+ }; -+ -+ conf-pu { -+ pins = "SPI1_CS"; -+ drive-strength = ; -+ bias-pull-up = ; -+ }; -+ -+ conf-pd { -+ pins = "SPI1_CLK", "SPI1_MOSI", "SPI1_MISO"; -+ drive-strength = ; -+ bias-pull-down = ; -+ }; -+ }; -+ -+ spi2_flash_pins: spi2-pins { -+ mux { -+ function = "spi"; -+ groups = "spi2"; -+ }; -+ -+ conf-pu { -+ pins = "SPI2_CS", "SPI2_WP"; -+ drive-strength = ; -+ bias-pull-up = ; -+ }; -+ -+ conf-pd { -+ pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; -+ drive-strength = ; -+ bias-pull-down = ; -+ }; -+ }; -+ -+ i2c_pins: i2c-pins { -+ mux { -+ function = "i2c"; -+ groups = "i2c0_0"; -+ }; -+ }; -+ -+ uart2_pins: uart2-pins { -+ mux { -+ function = "uart"; -+ groups = "uart2_0_tx_rx"; -+ }; -+ }; -+ -+ pwm_pins: pwm-pins { -+ mux { -+ function = "pwm"; -+ groups = "pwm0_0", "pwm1_1"; -+ }; -+ }; -+ -+ pcie_pins: pcie-pins { -+ mux { -+ function = "pcie"; -+ groups = "pcie_pereset"; -+ }; -+ }; -+}; -+ -+&pwm { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pwm_pins>; -+ status = "okay"; -+}; -+ -+&i2c0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c_pins>; -+ status = "okay"; -+ -+ rtc@51 { -+ compatible = "nxp,pcf8563"; -+ reg = <0x51>; -+ }; -+}; -+ -+&spi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_flash_pins>; -+ cs-gpios = <0>, <0>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ flash@1 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "spi-nand"; -+ reg = <1>; -+ spi-max-frequency = <52000000>; -+ -+ spi-cal-enable; -+ spi-cal-mode = "read-data"; -+ spi-cal-datalen = <7>; -+ spi-cal-data = /bits/ 8 <0x53 0x50 0x49 0x4E 0x41 0x4E 0x44>; -+ spi-cal-addrlen = <5>; -+ spi-cal-addr = /bits/ 32 <0x0 0x0 0x0 0x0 0x0>; -+ -+ partitions { -+ compatible = "fixed-partitions"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ partition@0 { -+ label = "bl2"; -+ reg = <0x0 0x100000>; -+ read-only; -+ }; -+ -+ partition@580000 { -+ label = "ubi"; -+ reg = <0x100000 0xFF00000>; -+ compatible = "linux,ubi"; -+ -+ volumes { -+ ubi_fit_volume: ubi-volume-fit { -+ volname = "fit"; -+ }; -+ }; -+ }; -+ }; -+ }; -+}; -+ -+&spi1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi1_flash_pins>; -+ status = "okay"; -+}; -+ -+&spi2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi2_flash_pins>; -+ status = "okay"; -+ -+ flash@0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "jedec,spi-nor"; -+ reg = <0>; -+ -+ spi-max-frequency = <52000000>; -+ -+ partitions { -+ compatible = "fixed-partitions"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ partition@0 { -+ label = "bl2-nor"; -+ reg = <0x00000 0x40000>; -+ }; -+ -+ partition@40000 { -+ label = "factory"; -+ reg = <0x40000 0xc0000>; -+ read-only; -+ -+ nvmem-layout { -+ compatible = "fixed-layout"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ eeprom_factory_0: eeprom@0 { -+ reg = <0x0 0x1000>; -+ }; -+ -+ macaddr_factory_4: macaddr@4 { -+ reg = <0x4 0x6>; -+ compatible = "mac-base"; -+ #nvmem-cell-cells = <1>; -+ }; -+ -+ macaddr_factory_24: macaddr@24 { -+ reg = <0x24 0x6>; -+ compatible = "mac-base"; -+ }; -+ }; -+ }; -+ -+ partition@100000 { -+ label = "fip-nor"; -+ reg = <0x100000 0x80000>; -+ }; -+ -+ partition@180000 { -+ label = "recovery"; -+ reg = <0x180000 0xc80000>; -+ }; -+ }; -+ }; -+}; -+ -+&xhci { -+ phys = <&u2port0 PHY_TYPE_USB2>; -+ vusb33-supply = <®_3p3v>; -+ vbus-supply = <®_5v>; -+ mediatek,u3p-dis-msk = <0x01>; -+ status = "okay"; -+}; -+ -+&uart0 { -+ status = "okay"; -+}; -+ -+&uart2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart2_pins>; -+ status = "okay"; -+}; -+ -+&usb_phy { -+ status = "okay"; -+}; -+ -+&watchdog { -+ status = "okay"; -+}; -+ -+&wifi { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ nvmem-cells = <&eeprom_factory_0>; -+ nvmem-cell-names = "eeprom"; -+ status = "okay"; -+ -+ band@0 { -+ reg = <0>; -+ nvmem-cells = <&macaddr_factory_4 0>; -+ nvmem-cell-names = "mac-address"; -+ }; -+ -+ band@1 { -+ reg = <1>; -+ nvmem-cells = <&macaddr_factory_4 7>; -+ nvmem-cell-names = "mac-address"; -+ }; -+}; -+ -+&pcie { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie_pins>; -+ status = "okay"; -+}; -+ -+&sgmiisys0 { -+ /delete-node/ mediatek,pnswap; - }; --- -2.51.0 - - -From faeb104b5fbd6383664672f1324d74eef55507b5 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Thu, 27 Oct 2022 23:39:52 +0200 -Subject: [PATCH 03/12] net: ethernet: mtk_eth_soc: compile out netsys v2 code - on mt7621 - -Avoid some branches in the hot path on low-end devices with limited CPU power, -and reduce code size - -Signed-off-by: Felix Fietkau ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -index 0168e2fbc619..2f89a06471e3 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1383,6 +1383,22 @@ struct mtk_mac { - /* the struct describing the SoC. these are declared in the soc_xyz.c files */ - extern const struct of_device_id of_mtk_match[]; - -+#ifdef CONFIG_SOC_MT7621 -+static inline bool mtk_is_netsys_v1(struct mtk_eth *eth) -+{ -+ return true; -+} -+ -+static inline bool mtk_is_netsys_v2_or_greater(struct mtk_eth *eth) -+{ -+ return false; -+} -+ -+static inline bool mtk_is_netsys_v3_or_greater(struct mtk_eth *eth) -+{ -+ return false; -+} -+#else - static inline bool mtk_is_netsys_v1(struct mtk_eth *eth) - { - return eth->soc->version == 1; -@@ -1397,6 +1413,7 @@ static inline bool mtk_is_netsys_v3_or_greater(struct mtk_eth *eth) - { - return eth->soc->version > 2; - } -+#endif - - static inline struct mtk_foe_entry * - mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash) --- -2.51.0 - - -From 6e848e9de009eeafe0d970f0914c3d6441c843bb Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Thu, 3 Nov 2022 12:38:49 +0100 -Subject: [PATCH 04/12] net: ethernet: mtk_eth_soc: work around issue with - sending small fragments - -When lots of frames are sent with a number of very small fragments, an -internal FIFO can overflow, causing the DMA engine to lock up lock up and -transmit attempts time out. - -Fix this on MT7986 by increasing the reserved FIFO space. -Fix this on older chips by detecting the presence of small fragments and use -skb_gso_segment + skb_linearize to deal with them. - -Signed-off-by: Felix Fietkau ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 39 +++++++++++++++++++-- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 +- - 2 files changed, 38 insertions(+), 3 deletions(-) - -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -index e68997a29191..2931376785f2 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -1752,12 +1753,28 @@ static void mtk_wake_queue(struct mtk_eth *eth) - } - } - -+static bool mtk_skb_has_small_frag(struct sk_buff *skb) -+{ -+ int min_size = 16; -+ int i; -+ -+ if (skb_headlen(skb) < min_size) -+ return true; -+ -+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) -+ if (skb_frag_size(&skb_shinfo(skb)->frags[i]) < min_size) -+ return true; -+ -+ return false; -+} -+ - static netdev_tx_t mtk_start_xmit(struct sk_buff *skb, struct net_device *dev) - { - struct mtk_mac *mac = netdev_priv(dev); - struct mtk_eth *eth = mac->hw; - struct mtk_tx_ring *ring = ð->tx_ring; - struct net_device_stats *stats = &dev->stats; -+ struct sk_buff *segs, *next; - bool gso = false; - int tx_num; - -@@ -1786,6 +1803,18 @@ static netdev_tx_t mtk_start_xmit(struct sk_buff *skb, struct net_device *dev) - return NETDEV_TX_BUSY; - } - -+ if (mtk_is_netsys_v1(eth) && -+ skb_is_gso(skb) && mtk_skb_has_small_frag(skb)) { -+ segs = skb_gso_segment(skb, dev->features & ~NETIF_F_ALL_TSO); -+ if (IS_ERR(segs)) -+ goto drop; -+ -+ if (segs) { -+ consume_skb(skb); -+ skb = segs; -+ } -+ } -+ - /* TSO: fill MSS info in tcp checksum field */ - if (skb_is_gso(skb)) { - if (skb_cow_head(skb, 0)) { -@@ -1801,8 +1830,14 @@ static netdev_tx_t mtk_start_xmit(struct sk_buff *skb, struct net_device *dev) - } - } - -- if (mtk_tx_map(skb, dev, tx_num, ring, gso) < 0) -- goto drop; -+ skb_list_walk_safe(skb, skb, next) { -+ if ((mtk_is_netsys_v1(eth) && -+ mtk_skb_has_small_frag(skb) && skb_linearize(skb)) || -+ mtk_tx_map(skb, dev, tx_num, ring, gso) < 0) { -+ stats->tx_dropped++; -+ dev_kfree_skb_any(skb); -+ } -+ } - - if (unlikely(atomic_read(&ring->free_count) <= ring->thresh)) - netif_tx_stop_all_queues(dev); -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -index 2f89a06471e3..ee7bb3b7b93a 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -280,7 +280,7 @@ - #define MTK_CHK_DDONE_EN BIT(28) - #define MTK_DMAD_WR_WDONE BIT(26) - #define MTK_WCOMP_EN BIT(24) --#define MTK_RESV_BUF (0x40 << 16) -+#define MTK_RESV_BUF (0x80 << 16) - #define MTK_MUTLI_CNT (0x4 << 12) - #define MTK_LEAKY_BUCKET_EN BIT(11) - --- -2.51.0 - - -From 0cdfa5eb67e05aeb2b35960db1b797a945902091 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Mon, 14 Jul 2025 10:52:59 +0200 -Subject: [PATCH 05/12] net: ethernet: mtk_eth_soc: shrink struct mtk_tx_buf - -There is no need to track the difference between dma_map_page -and dma_map_single, since they're unmapped in exactly the same way. -Also reorder fields in order to avoid padding. - -Signed-off-by: Felix Fietkau ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 42 ++++++--------------- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 13 +------ - 2 files changed, 14 insertions(+), 41 deletions(-) - -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -index 2931376785f2..3b81ea22bbea 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1386,32 +1386,19 @@ static int txd_to_idx(struct mtk_tx_ring *ring, void *dma, u32 txd_size) - static void mtk_tx_unmap(struct mtk_eth *eth, struct mtk_tx_buf *tx_buf, - struct xdp_frame_bulk *bq, bool napi) - { -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) { -- if (tx_buf->flags & MTK_TX_FLAGS_SINGLE0) { -- dma_unmap_single(eth->dma_dev, -- dma_unmap_addr(tx_buf, dma_addr0), -- dma_unmap_len(tx_buf, dma_len0), -- DMA_TO_DEVICE); -- } else if (tx_buf->flags & MTK_TX_FLAGS_PAGE0) { -- dma_unmap_page(eth->dma_dev, -- dma_unmap_addr(tx_buf, dma_addr0), -- dma_unmap_len(tx_buf, dma_len0), -- DMA_TO_DEVICE); -- } -- } else { -- if (dma_unmap_len(tx_buf, dma_len0)) { -- dma_unmap_page(eth->dma_dev, -- dma_unmap_addr(tx_buf, dma_addr0), -- dma_unmap_len(tx_buf, dma_len0), -- DMA_TO_DEVICE); -- } -+ if (dma_unmap_len(tx_buf, dma_len0)) { -+ dma_unmap_page(eth->dma_dev, -+ dma_unmap_addr(tx_buf, dma_addr0), -+ dma_unmap_len(tx_buf, dma_len0), -+ DMA_TO_DEVICE); -+ } - -- if (dma_unmap_len(tx_buf, dma_len1)) { -- dma_unmap_page(eth->dma_dev, -- dma_unmap_addr(tx_buf, dma_addr1), -- dma_unmap_len(tx_buf, dma_len1), -- DMA_TO_DEVICE); -- } -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA) && -+ dma_unmap_len(tx_buf, dma_len1)) { -+ dma_unmap_page(eth->dma_dev, -+ dma_unmap_addr(tx_buf, dma_addr1), -+ dma_unmap_len(tx_buf, dma_len1), -+ DMA_TO_DEVICE); - } - - if (tx_buf->data && tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { -@@ -1433,7 +1420,6 @@ static void mtk_tx_unmap(struct mtk_eth *eth, struct mtk_tx_buf *tx_buf, - xdp_return_frame(xdpf); - } - } -- tx_buf->flags = 0; - tx_buf->data = NULL; - } - -@@ -1598,7 +1584,6 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, - - mtk_tx_set_dma_desc(dev, itxd, &txd_info); - -- itx_buf->flags |= MTK_TX_FLAGS_SINGLE0; - itx_buf->mac_id = mac->id; - setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size, - k++); -@@ -1646,7 +1631,6 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, - if (new_desc) - memset(tx_buf, 0, sizeof(*tx_buf)); - tx_buf->data = (void *)MTK_DMA_DUMMY_DESC; -- tx_buf->flags |= MTK_TX_FLAGS_PAGE0; - tx_buf->mac_id = mac->id; - - setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr, -@@ -1979,8 +1963,6 @@ static int mtk_xdp_frame_map(struct mtk_eth *eth, struct net_device *dev, - txd_info->size, DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(eth->dma_dev, txd_info->addr))) - return -ENOMEM; -- -- tx_buf->flags |= MTK_TX_FLAGS_SINGLE0; - } else { - struct page *page = virt_to_head_page(data); - -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -index ee7bb3b7b93a..19381abcdfc6 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -728,14 +728,6 @@ struct mtk_hw_stats { - struct u64_stats_sync syncp; - }; - --enum mtk_tx_flags { -- /* PDMA descriptor can point at 1-2 segments. This enum allows us to -- * track how memory was allocated so that it can be freed properly. -- */ -- MTK_TX_FLAGS_SINGLE0 = 0x01, -- MTK_TX_FLAGS_PAGE0 = 0x02, --}; -- - /* This enum allows us to identify how the clock is defined on the array of the - * clock in the order - */ -@@ -908,13 +900,12 @@ enum mtk_tx_buf_type { - */ - struct mtk_tx_buf { - enum mtk_tx_buf_type type; -+ u16 mac_id; - void *data; - -- u16 mac_id; -- u16 flags; - DEFINE_DMA_UNMAP_ADDR(dma_addr0); -- DEFINE_DMA_UNMAP_LEN(dma_len0); - DEFINE_DMA_UNMAP_ADDR(dma_addr1); -+ DEFINE_DMA_UNMAP_LEN(dma_len0); - DEFINE_DMA_UNMAP_LEN(dma_len1); - }; - --- -2.51.0 - - -From 498cd003f1c801ad2e11f51dddf9aa075f412477 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Thu, 22 Aug 2024 18:02:17 +0200 -Subject: [PATCH 06/12] net: bridge: fix switchdev host mdb entry updates - -When a mdb entry is removed, the bridge switchdev code can issue a -switchdev_port_obj_del call for a port that was not offloaded. - -This leads to an imbalance in switchdev_port_obj_add/del calls, since -br_switchdev_mdb_replay has not been called for the port before. - -This can lead to potential multicast forwarding issues and messages such as: -mt7915e 0000:01:00.0 wl1-ap0: Failed to del Host Multicast Database entry - (object id=3) with error: -ENOENT (-2). - -Fix this issue by checking the port offload status when iterating over -lower devs. - -Signed-off-by: Felix Fietkau ---- - net/bridge/br_switchdev.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c -index fe3f7bbe86ee..b898e1a4b5ff 100644 ---- a/net/bridge/br_switchdev.c -+++ b/net/bridge/br_switchdev.c -@@ -576,10 +576,18 @@ static void br_switchdev_host_mdb(struct net_device *dev, - struct net_bridge_mdb_entry *mp, int type) - { - struct net_device *lower_dev; -+ struct net_bridge_port *port; - struct list_head *iter; - -- netdev_for_each_lower_dev(dev, lower_dev, iter) -+ rcu_read_lock(); -+ netdev_for_each_lower_dev(dev, lower_dev, iter) { -+ port = br_port_get_rcu(lower_dev); -+ if (!port || !port->offload_count) -+ continue; -+ - br_switchdev_host_mdb_one(dev, lower_dev, mp, type); -+ } -+ rcu_read_unlock(); - } - - static int --- -2.51.0 - - -From 96b0666b743311a15d8e01016462d7cf57764f62 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Mon, 21 Mar 2022 20:39:59 +0100 -Subject: [PATCH 07/12] net: ethernet: mtk_eth_soc: enable threaded NAPI - -This can improve performance under load by ensuring that NAPI processing is -not pinned on CPU 0. - -Signed-off-by: Felix Fietkau ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -index 3b81ea22bbea..a5586bd06490 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -5306,6 +5306,8 @@ static int mtk_probe(struct platform_device *pdev) - dev_err(eth->dev, "failed to allocated dummy device\n"); - goto err_unreg_netdev; - } -+ eth->dummy_dev->threaded = 1; -+ strcpy(eth->dummy_dev->name, "mtk_eth"); - netif_napi_add(eth->dummy_dev, ð->tx_napi, mtk_napi_tx); - netif_napi_add(eth->dummy_dev, ð->rx_napi, mtk_napi_rx); - --- -2.51.0 - - -From 0666439429f6983cde79712125d76e21fea034f8 Mon Sep 17 00:00:00 2001 -From: Chad Monroe -Date: Mon, 16 Sep 2024 19:29:03 -0700 -Subject: [PATCH 08/12] net: ethernet: mediatek: increase QDMA RESV_BUF size - -Increase QDMA RESV_BUF from 2K to 3K for netsys v2 to match Mediatek SDK[1]. -This helps reduce the possibility of Ethernet transmit timeouts. - -[1]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/19d8456c3051e5f6dabf42fa770916a2126ea4bf - -Signed-off-by: Chad Monroe ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 6 ++++-- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 + - 2 files changed, 5 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -index a5586bd06490..9d6f395f73dc 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3487,12 +3487,14 @@ static int mtk_start_dma(struct mtk_eth *eth) - MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO | - MTK_RX_2B_OFFSET | MTK_TX_WB_DDONE; - -- if (mtk_is_netsys_v2_or_greater(eth)) -+ if (mtk_is_netsys_v2_or_greater(eth)) { -+ val &= ~MTK_RESV_BUF_MASK; - val |= MTK_MUTLI_CNT | MTK_RESV_BUF | - MTK_WCOMP_EN | MTK_DMAD_WR_WDONE | - MTK_CHK_DDONE_EN; -- else -+ } else { - val |= MTK_RX_BT_32DWORDS; -+ } - mtk_w32(eth, val, reg_map->qdma.glo_cfg); - - mtk_w32(eth, -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -index 19381abcdfc6..b9da762fcc70 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -282,6 +282,7 @@ - #define MTK_WCOMP_EN BIT(24) - #define MTK_RESV_BUF (0x80 << 16) - #define MTK_MUTLI_CNT (0x4 << 12) -+#define MTK_RESV_BUF_MASK (0xff << 16) - #define MTK_LEAKY_BUCKET_EN BIT(11) - - /* QDMA Flow Control Register */ --- -2.51.0 - - -From 80b5de03406650271a4a5fafb06d06dbe4fd8846 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Thu, 23 Mar 2023 10:24:11 +0100 -Subject: [PATCH 09/12] net: ethernet: mtk_eth_soc: improve keeping track of - offloaded flows - -Unify tracking of L2 and L3 flows. Use the generic list field in struct -mtk_foe_entry for tracking L2 subflows. Preparation for improving -flow accounting support. - -Signed-off-by: Felix Fietkau ---- - drivers/net/ethernet/mediatek/mtk_ppe.c | 162 ++++++++++++------------ - drivers/net/ethernet/mediatek/mtk_ppe.h | 15 +-- - 2 files changed, 86 insertions(+), 91 deletions(-) - -diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c -index ada852adc5f7..5b352ab64ef7 100644 ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -479,42 +479,43 @@ int mtk_foe_entry_set_queue(struct mtk_eth *eth, struct mtk_foe_entry *entry, - return 0; - } - -+static int -+mtk_flow_entry_match_len(struct mtk_eth *eth, struct mtk_foe_entry *entry) -+{ -+ int type = mtk_get_ib1_pkt_type(eth, entry->ib1); -+ -+ if (type > MTK_PPE_PKT_TYPE_IPV4_DSLITE) -+ return offsetof(struct mtk_foe_entry, ipv6._rsv); -+ else -+ return offsetof(struct mtk_foe_entry, ipv4.ib2); -+} -+ - static bool - mtk_flow_entry_match(struct mtk_eth *eth, struct mtk_flow_entry *entry, -- struct mtk_foe_entry *data) -+ struct mtk_foe_entry *data, int len) - { -- int type, len; -- - if ((data->ib1 ^ entry->data.ib1) & MTK_FOE_IB1_UDP) - return false; - -- type = mtk_get_ib1_pkt_type(eth, entry->data.ib1); -- if (type > MTK_PPE_PKT_TYPE_IPV4_DSLITE) -- len = offsetof(struct mtk_foe_entry, ipv6._rsv); -- else -- len = offsetof(struct mtk_foe_entry, ipv4.ib2); -- - return !memcmp(&entry->data.data, &data->data, len - 4); - } - - static void --__mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) -+__mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, -+ bool set_state) - { -- struct hlist_head *head; - struct hlist_node *tmp; - - if (entry->type == MTK_FLOW_TYPE_L2) { - rhashtable_remove_fast(&ppe->l2_flows, &entry->l2_node, - mtk_flow_l2_ht_params); - -- head = &entry->l2_flows; -- hlist_for_each_entry_safe(entry, tmp, head, l2_data.list) -- __mtk_foe_entry_clear(ppe, entry); -+ hlist_for_each_entry_safe(entry, tmp, &entry->l2_flows, l2_list) -+ __mtk_foe_entry_clear(ppe, entry, set_state); - return; - } - -- hlist_del_init(&entry->list); -- if (entry->hash != 0xffff) { -+ if (entry->hash != 0xffff && set_state) { - struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, entry->hash); - - hwe->ib1 &= ~MTK_FOE_IB1_STATE; -@@ -535,7 +536,8 @@ __mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - if (entry->type != MTK_FLOW_TYPE_L2_SUBFLOW) - return; - -- hlist_del_init(&entry->l2_data.list); -+ hlist_del_init(&entry->l2_list); -+ hlist_del_init(&entry->list); - kfree(entry); - } - -@@ -551,68 +553,57 @@ static int __mtk_foe_entry_idle_time(struct mtk_ppe *ppe, u32 ib1) - return now - timestamp; - } - -+static bool -+mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) -+{ -+ struct mtk_foe_entry foe = {}; -+ struct mtk_foe_entry *hwe; -+ u16 hash = entry->hash; -+ int len; -+ -+ if (hash == 0xffff) -+ return false; -+ -+ hwe = mtk_foe_get_entry(ppe, hash); -+ len = mtk_flow_entry_match_len(ppe->eth, &entry->data); -+ memcpy(&foe, hwe, len); -+ -+ if (!mtk_flow_entry_match(ppe->eth, entry, &foe, len) || -+ FIELD_GET(MTK_FOE_IB1_STATE, foe.ib1) != MTK_FOE_STATE_BIND) -+ return false; -+ -+ entry->data.ib1 = foe.ib1; -+ -+ return true; -+} -+ - static void - mtk_flow_entry_update_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { - u32 ib1_ts_mask = mtk_get_ib1_ts_mask(ppe->eth); - struct mtk_flow_entry *cur; -- struct mtk_foe_entry *hwe; - struct hlist_node *tmp; - int idle; - - idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1); -- hlist_for_each_entry_safe(cur, tmp, &entry->l2_flows, l2_data.list) { -+ hlist_for_each_entry_safe(cur, tmp, &entry->l2_flows, l2_list) { - int cur_idle; -- u32 ib1; -- -- hwe = mtk_foe_get_entry(ppe, cur->hash); -- ib1 = READ_ONCE(hwe->ib1); - -- if (FIELD_GET(MTK_FOE_IB1_STATE, ib1) != MTK_FOE_STATE_BIND) { -- cur->hash = 0xffff; -- __mtk_foe_entry_clear(ppe, cur); -+ if (!mtk_flow_entry_update(ppe, cur)) { -+ __mtk_foe_entry_clear(ppe, entry, false); - continue; - } - -- cur_idle = __mtk_foe_entry_idle_time(ppe, ib1); -+ cur_idle = __mtk_foe_entry_idle_time(ppe, cur->data.ib1); - if (cur_idle >= idle) - continue; - - idle = cur_idle; - entry->data.ib1 &= ~ib1_ts_mask; -- entry->data.ib1 |= ib1 & ib1_ts_mask; -+ entry->data.ib1 |= cur->data.ib1 & ib1_ts_mask; - } - } - --static void --mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) --{ -- struct mtk_foe_entry foe = {}; -- struct mtk_foe_entry *hwe; -- -- spin_lock_bh(&ppe_lock); -- -- if (entry->type == MTK_FLOW_TYPE_L2) { -- mtk_flow_entry_update_l2(ppe, entry); -- goto out; -- } -- -- if (entry->hash == 0xffff) -- goto out; -- -- hwe = mtk_foe_get_entry(ppe, entry->hash); -- memcpy(&foe, hwe, ppe->eth->soc->foe_entry_size); -- if (!mtk_flow_entry_match(ppe->eth, entry, &foe)) { -- entry->hash = 0xffff; -- goto out; -- } -- -- entry->data.ib1 = foe.ib1; -- --out: -- spin_unlock_bh(&ppe_lock); --} -- - static void - __mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry, - u16 hash) -@@ -653,7 +644,8 @@ __mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry, - void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { - spin_lock_bh(&ppe_lock); -- __mtk_foe_entry_clear(ppe, entry); -+ __mtk_foe_entry_clear(ppe, entry, true); -+ hlist_del_init(&entry->list); - spin_unlock_bh(&ppe_lock); - } - -@@ -700,8 +692,8 @@ mtk_foe_entry_commit_subflow(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, - { - const struct mtk_soc_data *soc = ppe->eth->soc; - struct mtk_flow_entry *flow_info; -- struct mtk_foe_entry foe = {}, *hwe; - struct mtk_foe_mac_info *l2; -+ struct mtk_foe_entry *hwe; - u32 ib1_mask = mtk_get_ib1_pkt_type_mask(ppe->eth) | MTK_FOE_IB1_UDP; - int type; - -@@ -709,30 +701,30 @@ mtk_foe_entry_commit_subflow(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, - if (!flow_info) - return; - -- flow_info->l2_data.base_flow = entry; - flow_info->type = MTK_FLOW_TYPE_L2_SUBFLOW; - flow_info->hash = hash; - hlist_add_head(&flow_info->list, - &ppe->foe_flow[hash / soc->hash_offset]); -- hlist_add_head(&flow_info->l2_data.list, &entry->l2_flows); -+ hlist_add_head(&flow_info->l2_list, &entry->l2_flows); - - hwe = mtk_foe_get_entry(ppe, hash); -- memcpy(&foe, hwe, soc->foe_entry_size); -- foe.ib1 &= ib1_mask; -- foe.ib1 |= entry->data.ib1 & ~ib1_mask; -+ memcpy(&flow_info->data, hwe, soc->foe_entry_size); -+ flow_info->data.ib1 &= ib1_mask; -+ flow_info->data.ib1 |= entry->data.ib1 & ~ib1_mask; - -- l2 = mtk_foe_entry_l2(ppe->eth, &foe); -+ l2 = mtk_foe_entry_l2(ppe->eth, &flow_info->data); - memcpy(l2, &entry->data.bridge.l2, sizeof(*l2)); - -- type = mtk_get_ib1_pkt_type(ppe->eth, foe.ib1); -+ type = mtk_get_ib1_pkt_type(ppe->eth, flow_info->data.ib1); - if (type == MTK_PPE_PKT_TYPE_IPV4_HNAPT) -- memcpy(&foe.ipv4.new, &foe.ipv4.orig, sizeof(foe.ipv4.new)); -+ memcpy(&flow_info->data.ipv4.new, &flow_info->data.ipv4.orig, -+ sizeof(flow_info->data.ipv4.new)); - else if (type >= MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T && l2->etype == ETH_P_IP) - l2->etype = ETH_P_IPV6; - -- *mtk_foe_entry_ib2(ppe->eth, &foe) = entry->data.bridge.ib2; -+ *mtk_foe_entry_ib2(ppe->eth, &flow_info->data) = entry->data.bridge.ib2; - -- __mtk_foe_entry_commit(ppe, &foe, hash); -+ __mtk_foe_entry_commit(ppe, &flow_info->data, hash); - } - - void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash) -@@ -742,9 +734,11 @@ void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash) - struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, hash); - struct mtk_flow_entry *entry; - struct mtk_foe_bridge key = {}; -+ struct mtk_foe_entry foe = {}; - struct hlist_node *n; - struct ethhdr *eh; - bool found = false; -+ int entry_len; - u8 *tag; - - spin_lock_bh(&ppe_lock); -@@ -752,20 +746,14 @@ void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash) - if (FIELD_GET(MTK_FOE_IB1_STATE, hwe->ib1) == MTK_FOE_STATE_BIND) - goto out; - -- hlist_for_each_entry_safe(entry, n, head, list) { -- if (entry->type == MTK_FLOW_TYPE_L2_SUBFLOW) { -- if (unlikely(FIELD_GET(MTK_FOE_IB1_STATE, hwe->ib1) == -- MTK_FOE_STATE_BIND)) -- continue; -- -- entry->hash = 0xffff; -- __mtk_foe_entry_clear(ppe, entry); -- continue; -- } -+ entry_len = mtk_flow_entry_match_len(ppe->eth, hwe); -+ memcpy(&foe, hwe, entry_len); - -- if (found || !mtk_flow_entry_match(ppe->eth, entry, hwe)) { -+ hlist_for_each_entry_safe(entry, n, head, list) { -+ if (found || -+ !mtk_flow_entry_match(ppe->eth, entry, &foe, entry_len)) { - if (entry->hash != 0xffff) -- entry->hash = 0xffff; -+ __mtk_foe_entry_clear(ppe, entry, false); - continue; - } - -@@ -816,9 +804,17 @@ void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash) - - int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { -- mtk_flow_entry_update(ppe, entry); -+ int idle; -+ -+ spin_lock_bh(&ppe_lock); -+ if (entry->type == MTK_FLOW_TYPE_L2) -+ mtk_flow_entry_update_l2(ppe, entry); -+ else -+ mtk_flow_entry_update(ppe, entry); -+ idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1); -+ spin_unlock_bh(&ppe_lock); - -- return __mtk_foe_entry_idle_time(ppe, entry->data.ib1); -+ return idle; - } - - int mtk_ppe_prepare_reset(struct mtk_ppe *ppe) -diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.h b/drivers/net/ethernet/mediatek/mtk_ppe.h -index 223f709e2704..aa0799c1ce95 100644 ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -286,7 +286,12 @@ enum { - - struct mtk_flow_entry { - union { -- struct hlist_node list; -+ /* regular flows + L2 subflows */ -+ struct { -+ struct hlist_node list; -+ struct hlist_node l2_list; -+ }; -+ /* L2 flows */ - struct { - struct rhash_head l2_node; - struct hlist_head l2_flows; -@@ -296,13 +301,7 @@ struct mtk_flow_entry { - s8 wed_index; - u8 ppe_index; - u16 hash; -- union { -- struct mtk_foe_entry data; -- struct { -- struct mtk_flow_entry *base_flow; -- struct hlist_node list; -- } l2_data; -- }; -+ struct mtk_foe_entry data; - struct rhash_head node; - unsigned long cookie; - }; --- -2.51.0 - - -From ecc4b72e231898cf8e61dd3dac99b8a36224cd41 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Thu, 23 Mar 2023 11:05:22 +0100 -Subject: [PATCH 10/12] net: ethernet: mediatek: fix ppe flow accounting for L2 - flows - -For L2 flows, the packet/byte counters should report the sum of the -counters of their subflows, both current and expired. -In order to make this work, change the way that accounting data is tracked. -Reset counters when a flow enters bind. Once it expires (or enters unbind), -store the last counter value in struct mtk_flow_entry. - -Signed-off-by: Felix Fietkau ---- - drivers/net/ethernet/mediatek/mtk_ppe.c | 140 ++++++++++-------- - drivers/net/ethernet/mediatek/mtk_ppe.h | 8 +- - .../net/ethernet/mediatek/mtk_ppe_debugfs.c | 2 +- - .../net/ethernet/mediatek/mtk_ppe_offload.c | 17 +-- - 4 files changed, 89 insertions(+), 78 deletions(-) - -diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c -index 5b352ab64ef7..96365a75b198 100644 ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -83,9 +83,9 @@ static int mtk_ppe_mib_wait_busy(struct mtk_ppe *ppe) - int ret; - u32 val; - -- ret = readl_poll_timeout(ppe->base + MTK_PPE_MIB_SER_CR, val, -- !(val & MTK_PPE_MIB_SER_CR_ST), -- 20, MTK_PPE_WAIT_TIMEOUT_US); -+ ret = readl_poll_timeout_atomic(ppe->base + MTK_PPE_MIB_SER_CR, val, -+ !(val & MTK_PPE_MIB_SER_CR_ST), -+ 20, MTK_PPE_WAIT_TIMEOUT_US); - - if (ret) - dev_err(ppe->dev, "MIB table busy"); -@@ -93,17 +93,31 @@ static int mtk_ppe_mib_wait_busy(struct mtk_ppe *ppe) - return ret; - } - --static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *packets) -+static inline struct mtk_foe_accounting * -+mtk_ppe_acct_data(struct mtk_ppe *ppe, u16 index) -+{ -+ if (!ppe->acct_table) -+ return NULL; -+ -+ return ppe->acct_table + index * sizeof(struct mtk_foe_accounting); -+} -+ -+struct mtk_foe_accounting *mtk_ppe_mib_entry_read(struct mtk_ppe *ppe, u16 index) - { - u32 val, cnt_r0, cnt_r1, cnt_r2; -+ struct mtk_foe_accounting *acct; - int ret; - - val = FIELD_PREP(MTK_PPE_MIB_SER_CR_ADDR, index) | MTK_PPE_MIB_SER_CR_ST; - ppe_w32(ppe, MTK_PPE_MIB_SER_CR, val); - -+ acct = mtk_ppe_acct_data(ppe, index); -+ if (!acct) -+ return NULL; -+ - ret = mtk_ppe_mib_wait_busy(ppe); - if (ret) -- return ret; -+ return acct; - - cnt_r0 = readl(ppe->base + MTK_PPE_MIB_SER_R0); - cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1); -@@ -112,19 +126,19 @@ static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *p - if (mtk_is_netsys_v3_or_greater(ppe->eth)) { - /* 64 bit for each counter */ - u32 cnt_r3 = readl(ppe->base + MTK_PPE_MIB_SER_R3); -- *bytes = ((u64)cnt_r1 << 32) | cnt_r0; -- *packets = ((u64)cnt_r3 << 32) | cnt_r2; -+ acct->bytes += ((u64)cnt_r1 << 32) | cnt_r0; -+ acct->packets += ((u64)cnt_r3 << 32) | cnt_r2; - } else { - /* 48 bit byte counter, 40 bit packet counter */ - u32 byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0); - u32 byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1); - u32 pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1); - u32 pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2); -- *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low; -- *packets = ((u64)pkt_cnt_high << 16) | pkt_cnt_low; -+ acct->bytes += ((u64)byte_cnt_high << 32) | byte_cnt_low; -+ acct->packets += ((u64)pkt_cnt_high << 16) | pkt_cnt_low; - } - -- return 0; -+ return acct; - } - - static void mtk_ppe_cache_clear(struct mtk_ppe *ppe) -@@ -522,14 +536,6 @@ __mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, - hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID); - dma_wmb(); - mtk_ppe_cache_clear(ppe); -- -- if (ppe->accounting) { -- struct mtk_foe_accounting *acct; -- -- acct = ppe->acct_table + entry->hash * sizeof(*acct); -- acct->packets = 0; -- acct->bytes = 0; -- } - } - entry->hash = 0xffff; - -@@ -554,11 +560,14 @@ static int __mtk_foe_entry_idle_time(struct mtk_ppe *ppe, u32 ib1) - } - - static bool --mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) -+mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, -+ u64 *packets, u64 *bytes) - { -+ struct mtk_foe_accounting *acct; - struct mtk_foe_entry foe = {}; - struct mtk_foe_entry *hwe; - u16 hash = entry->hash; -+ bool ret = false; - int len; - - if (hash == 0xffff) -@@ -569,18 +578,35 @@ mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - memcpy(&foe, hwe, len); - - if (!mtk_flow_entry_match(ppe->eth, entry, &foe, len) || -- FIELD_GET(MTK_FOE_IB1_STATE, foe.ib1) != MTK_FOE_STATE_BIND) -- return false; -+ FIELD_GET(MTK_FOE_IB1_STATE, foe.ib1) != MTK_FOE_STATE_BIND) { -+ acct = mtk_ppe_acct_data(ppe, hash); -+ if (acct) { -+ entry->prev_packets += acct->packets; -+ entry->prev_bytes += acct->bytes; -+ } -+ -+ goto out; -+ } - - entry->data.ib1 = foe.ib1; -+ acct = mtk_ppe_mib_entry_read(ppe, hash); -+ ret = true; -+ -+out: -+ if (acct) { -+ *packets += acct->packets; -+ *bytes += acct->bytes; -+ } - -- return true; -+ return ret; - } - - static void - mtk_flow_entry_update_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { - u32 ib1_ts_mask = mtk_get_ib1_ts_mask(ppe->eth); -+ u64 *packets = &entry->packets; -+ u64 *bytes = &entry->bytes; - struct mtk_flow_entry *cur; - struct hlist_node *tmp; - int idle; -@@ -589,7 +615,9 @@ mtk_flow_entry_update_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - hlist_for_each_entry_safe(cur, tmp, &entry->l2_flows, l2_list) { - int cur_idle; - -- if (!mtk_flow_entry_update(ppe, cur)) { -+ if (!mtk_flow_entry_update(ppe, cur, packets, bytes)) { -+ entry->prev_packets += cur->prev_packets; -+ entry->prev_bytes += cur->prev_bytes; - __mtk_foe_entry_clear(ppe, entry, false); - continue; - } -@@ -604,10 +632,29 @@ mtk_flow_entry_update_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - } - } - -+void mtk_foe_entry_get_stats(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, -+ int *idle) -+{ -+ entry->packets = entry->prev_packets; -+ entry->bytes = entry->prev_bytes; -+ -+ spin_lock_bh(&ppe_lock); -+ -+ if (entry->type == MTK_FLOW_TYPE_L2) -+ mtk_flow_entry_update_l2(ppe, entry); -+ else -+ mtk_flow_entry_update(ppe, entry, &entry->packets, &entry->bytes); -+ -+ *idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1); -+ -+ spin_unlock_bh(&ppe_lock); -+} -+ - static void - __mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry, - u16 hash) - { -+ struct mtk_foe_accounting *acct; - struct mtk_eth *eth = ppe->eth; - u16 timestamp = mtk_eth_timestamp(eth); - struct mtk_foe_entry *hwe; -@@ -638,6 +685,12 @@ __mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry, - - dma_wmb(); - -+ acct = mtk_ppe_mib_entry_read(ppe, hash); -+ if (acct) { -+ acct->packets = 0; -+ acct->bytes = 0; -+ } -+ - mtk_ppe_cache_clear(ppe); - } - -@@ -802,21 +855,6 @@ void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash) - spin_unlock_bh(&ppe_lock); - } - --int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) --{ -- int idle; -- -- spin_lock_bh(&ppe_lock); -- if (entry->type == MTK_FLOW_TYPE_L2) -- mtk_flow_entry_update_l2(ppe, entry); -- else -- mtk_flow_entry_update(ppe, entry); -- idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1); -- spin_unlock_bh(&ppe_lock); -- -- return idle; --} -- - int mtk_ppe_prepare_reset(struct mtk_ppe *ppe) - { - if (!ppe) -@@ -844,32 +882,6 @@ int mtk_ppe_prepare_reset(struct mtk_ppe *ppe) - return mtk_ppe_wait_busy(ppe); - } - --struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index, -- struct mtk_foe_accounting *diff) --{ -- struct mtk_foe_accounting *acct; -- int size = sizeof(struct mtk_foe_accounting); -- u64 bytes, packets; -- -- if (!ppe->accounting) -- return NULL; -- -- if (mtk_mib_entry_read(ppe, index, &bytes, &packets)) -- return NULL; -- -- acct = ppe->acct_table + index * size; -- -- acct->bytes += bytes; -- acct->packets += packets; -- -- if (diff) { -- diff->bytes = bytes; -- diff->packets = packets; -- } -- -- return acct; --} -- - struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index) - { - bool accounting = eth->soc->has_accounting; -diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.h b/drivers/net/ethernet/mediatek/mtk_ppe.h -index aa0799c1ce95..9a4990aa5fa5 100644 ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -304,6 +304,8 @@ struct mtk_flow_entry { - struct mtk_foe_entry data; - struct rhash_head node; - unsigned long cookie; -+ u64 prev_packets, prev_bytes; -+ u64 packets, bytes; - }; - - struct mtk_mib_entry { -@@ -348,6 +350,7 @@ void mtk_ppe_deinit(struct mtk_eth *eth); - void mtk_ppe_start(struct mtk_ppe *ppe); - int mtk_ppe_stop(struct mtk_ppe *ppe); - int mtk_ppe_prepare_reset(struct mtk_ppe *ppe); -+struct mtk_foe_accounting *mtk_ppe_mib_entry_read(struct mtk_ppe *ppe, u16 index); - - void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash); - -@@ -397,9 +400,8 @@ int mtk_foe_entry_set_queue(struct mtk_eth *eth, struct mtk_foe_entry *entry, - unsigned int queue); - int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); - void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); --int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); - int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index); --struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index, -- struct mtk_foe_accounting *diff); -+void mtk_foe_entry_get_stats(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, -+ int *idle); - - #endif -diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c -index 570ebf91f693..9259d0925b88 100644 ---- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c -@@ -97,7 +97,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file *m, void *private, bool bind) - if (bind && state != MTK_FOE_STATE_BIND) - continue; - -- acct = mtk_foe_entry_get_mib(ppe, i, NULL); -+ acct = mtk_ppe_mib_entry_read(ppe, i); - - type = mtk_get_ib1_pkt_type(ppe->eth, entry->ib1); - seq_printf(m, "%05x %s %7s", i, -diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -index e9bd32741983..af8e0107fb93 100644 ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -522,24 +522,21 @@ static int - mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f) - { - struct mtk_flow_entry *entry; -- struct mtk_foe_accounting diff; -- u32 idle; -+ u64 packets, bytes; -+ int idle; - - entry = rhashtable_lookup(ð->flow_table, &f->cookie, - mtk_flow_ht_params); - if (!entry) - return -ENOENT; - -- idle = mtk_foe_entry_idle_time(eth->ppe[entry->ppe_index], entry); -+ packets = entry->packets; -+ bytes = entry->bytes; -+ mtk_foe_entry_get_stats(eth->ppe[entry->ppe_index], entry, &idle); -+ f->stats.pkts += entry->packets - packets; -+ f->stats.bytes += entry->bytes - bytes; - f->stats.lastused = jiffies - idle * HZ; - -- if (entry->hash != 0xFFFF && -- mtk_foe_entry_get_mib(eth->ppe[entry->ppe_index], entry->hash, -- &diff)) { -- f->stats.pkts += diff.packets; -- f->stats.bytes += diff.bytes; -- } -- - return 0; - } - --- -2.51.0 - - -From 0d9be0a839c47582a77b1c63164b2e93a48973ac Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 12 Sep 2025 14:18:14 +0200 -Subject: [PATCH 11/12] net: ethernet: mtk_eth_soc: zero initialize PPE flow - table - -Avoid picking up flows from last boot or other invalid data - -Signed-off-by: Felix Fietkau ---- - drivers/net/ethernet/mediatek/mtk_ppe.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c -index 96365a75b198..cb08d132bad9 100644 ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -914,6 +914,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index) - if (!foe) - goto err_free_l2_flows; - -+ memset(foe, 0, MTK_PPE_ENTRIES * soc->foe_entry_size); - ppe->foe_table = foe; - - foe_flow_size = (MTK_PPE_ENTRIES / soc->hash_offset) * -@@ -928,6 +929,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index) - if (!mib) - return NULL; - -+ memset(mib, 0, MTK_PPE_ENTRIES * sizeof(*mib)); - ppe->mib_table = mib; - - acct = devm_kzalloc(dev, MTK_PPE_ENTRIES * sizeof(*acct), --- -2.51.0 - - -From 3b613fe4850f9bbb32417ef3c2c48c5f65f0111d Mon Sep 17 00:00:00 2001 -From: Bo-Cun Chen -Date: Wed, 27 Nov 2024 13:36:49 +0800 -Subject: [PATCH 12/12] net: ethernet: mtk_eth_soc: add hw dump for forced - reset - -Without this patch, the ETH driver is unable to dump the registers -before triggering a forced reset. - -Signed-off-by: Bo-Cun Chen ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 55 +++++++++++++++++++++ - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 + - 2 files changed, 56 insertions(+) - -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -index 9d6f395f73dc..110dac8248df 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -65,6 +65,7 @@ static const struct mtk_reg_map mtk_reg_map = { - .rx_ptr = 0x1900, - .rx_cnt_cfg = 0x1904, - .qcrx_ptr = 0x1908, -+ .page = 0x19f0, - .glo_cfg = 0x1a04, - .rst_idx = 0x1a08, - .delay_irq = 0x1a0c, -@@ -131,6 +132,7 @@ static const struct mtk_reg_map mt7986_reg_map = { - .rx_ptr = 0x4500, - .rx_cnt_cfg = 0x4504, - .qcrx_ptr = 0x4508, -+ .page = 0x45f0, - .glo_cfg = 0x4604, - .rst_idx = 0x4608, - .delay_irq = 0x460c, -@@ -182,6 +184,7 @@ static const struct mtk_reg_map mt7988_reg_map = { - .rx_ptr = 0x4500, - .rx_cnt_cfg = 0x4504, - .qcrx_ptr = 0x4508, -+ .page = 0x45f0, - .glo_cfg = 0x4604, - .rst_idx = 0x4608, - .delay_irq = 0x460c, -@@ -3913,6 +3916,56 @@ static void mtk_set_mcr_max_rx(struct mtk_mac *mac, u32 val) - mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id)); - } - -+static void mtk_hw_dump_reg(struct mtk_eth *eth, char *name, u32 offset, u32 range) -+{ -+ u32 cur = offset; -+ -+ pr_info("\n==================== %s ====================\n", name); -+ while (cur < offset + range) { -+ pr_info("0x%08x: %08x %08x %08x %08x\n", -+ cur, mtk_r32(eth, cur), mtk_r32(eth, cur + 0x4), -+ mtk_r32(eth, cur + 0x8), mtk_r32(eth, cur + 0xc)); -+ cur += 0x10; -+ } -+} -+ -+static void mtk_hw_dump(struct mtk_eth *eth) -+{ -+ const struct mtk_reg_map *reg_map = eth->soc->reg_map; -+ u32 id; -+ -+ mtk_hw_dump_reg(eth, "FE", 0x0, 0x600); -+ mtk_hw_dump_reg(eth, "FE", 0x1400, 0x300); -+ mtk_hw_dump_reg(eth, "ADMA", reg_map->pdma.rx_ptr, 0x300); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) { -+ for (id = 0; id < MTK_QDMA_NUM_QUEUES / 16; id++) { -+ mtk_w32(eth, id, reg_map->qdma.page); -+ pr_info("\nQDMA PAGE:%x ", mtk_r32(eth, reg_map->qdma.page)); -+ mtk_hw_dump_reg(eth, "QDMA", reg_map->qdma.qtx_cfg, 0x100); -+ mtk_w32(eth, 0, reg_map->qdma.page); -+ } -+ mtk_hw_dump_reg(eth, "QDMA", reg_map->qdma.rx_ptr, 0x300); -+ } -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) { -+ mtk_hw_dump_reg(eth, "WDMA0", reg_map->wdma_base[0], 0x400); -+ mtk_hw_dump_reg(eth, "WDMA1", reg_map->wdma_base[1], 0x400); -+ if (mtk_is_netsys_v3_or_greater(eth)) -+ mtk_hw_dump_reg(eth, "WDMA2", reg_map->wdma_base[2], 0x400); -+ } -+ mtk_hw_dump_reg(eth, "PPE0", reg_map->ppe_base + 0x200, 0x200); -+ if (!mtk_is_netsys_v1(eth)) -+ mtk_hw_dump_reg(eth, "PPE1", reg_map->ppe_base + 0x600, 0x200); -+ if (mtk_is_netsys_v3_or_greater(eth)) -+ mtk_hw_dump_reg(eth, "PPE2", reg_map->ppe_base + 0xE00, 0x200); -+ mtk_hw_dump_reg(eth, "GMAC", 0x10000, 0x300); -+ if (mtk_is_netsys_v3_or_greater(eth)) -+ mtk_hw_dump_reg(eth, "GMAC", 0x10300, 0x100); -+ if (mtk_is_netsys_v3_or_greater(eth)) { -+ mtk_hw_dump_reg(eth, "XGMAC0", 0x12000, 0x300); -+ mtk_hw_dump_reg(eth, "XGMAC1", 0x13000, 0x300); -+ } -+} -+ - static void mtk_hw_reset(struct mtk_eth *eth) - { - u32 val; -@@ -4392,6 +4445,8 @@ static void mtk_pending_work(struct work_struct *work) - rtnl_lock(); - set_bit(MTK_RESETTING, ð->state); - -+ mtk_hw_dump(eth); -+ - mtk_prepare_for_reset(eth); - mtk_wed_fe_reset(); - /* Run again reset preliminary configuration in order to avoid any -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -index b9da762fcc70..64b94b21b493 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1152,6 +1152,7 @@ struct mtk_reg_map { - u32 rx_ptr; /* rx base pointer */ - u32 rx_cnt_cfg; /* rx max count configuration */ - u32 qcrx_ptr; /* rx cpu pointer */ -+ u32 page; /* page configuration */ - u32 glo_cfg; /* global configuration */ - u32 rst_idx; /* reset index */ - u32 delay_irq; /* delay interrupt */ --- -2.51.0 - diff --git a/pkgs/linux_6_12-openwrt-one.patch b/pkgs/linux_6_12-openwrt-one.patch deleted file mode 100644 index 1e231cf..0000000 --- a/pkgs/linux_6_12-openwrt-one.patch +++ /dev/null @@ -1,222237 +0,0 @@ -From 1d094806fc13ed0e5ed368b9a7da338ac24457f9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:48:42 +0100 -Subject: [PATCH 001/517] OpenWrt files - ---- - .../mtd/partitions/openwrt,uimage.yaml | 91 + - Documentation/networking/adm6996.txt | 110 + - .../mt7981-rfb-mxl-2p5g-phy-eth1.dtso | 34 + - .../mt7981-rfb-mxl-2p5g-phy-swp5.dtso | 35 + - .../dts/mediatek/mt7981-rfb-spim-nand.dtso | 78 + - arch/arm64/boot/dts/mediatek/mt7981-rfb.dts | 189 + - .../dts/mediatek/mt7986a-rfb-spim-nand.dts | 52 + - .../dts/mediatek/mt7986a-rfb-spim-nor.dts | 51 + - arch/arm64/boot/dts/mediatek/mt7986a-rfb.dtsi | 391 + - arch/mips/fw/myloader/Makefile | 5 + - arch/mips/fw/myloader/myloader.c | 63 + - drivers/bcma/fallback-sprom.c | 534 + - drivers/bcma/fallback-sprom.h | 7 + - drivers/leds/leds-smartrg-system.c | 225 + - drivers/mfd/airoha-an8855.c | 278 + - drivers/mtd/mtdsplit/Kconfig | 117 + - drivers/mtd/mtdsplit/Makefile | 20 + - drivers/mtd/mtdsplit/mtdsplit.c | 130 + - drivers/mtd/mtdsplit/mtdsplit.h | 67 + - drivers/mtd/mtdsplit/mtdsplit_bcm63xx.c | 186 + - drivers/mtd/mtdsplit/mtdsplit_bcm_wfi.c | 535 + - drivers/mtd/mtdsplit/mtdsplit_brnimage.c | 104 + - drivers/mtd/mtdsplit/mtdsplit_cfe_bootfs.c | 90 + - drivers/mtd/mtdsplit/mtdsplit_elf.c | 287 + - drivers/mtd/mtdsplit/mtdsplit_eva.c | 103 + - drivers/mtd/mtdsplit/mtdsplit_fit.c | 365 + - drivers/mtd/mtdsplit/mtdsplit_h3c_vfs.c | 167 + - drivers/mtd/mtdsplit/mtdsplit_jimage.c | 284 + - drivers/mtd/mtdsplit/mtdsplit_lzma.c | 109 + - drivers/mtd/mtdsplit/mtdsplit_minor.c | 142 + - drivers/mtd/mtdsplit/mtdsplit_mstc_boot.c | 270 + - drivers/mtd/mtdsplit/mtdsplit_seama.c | 118 + - drivers/mtd/mtdsplit/mtdsplit_seil.c | 191 + - drivers/mtd/mtdsplit/mtdsplit_squashfs.c | 72 + - drivers/mtd/mtdsplit/mtdsplit_tplink.c | 176 + - drivers/mtd/mtdsplit/mtdsplit_trx.c | 155 + - drivers/mtd/mtdsplit/mtdsplit_uimage.c | 282 + - drivers/mtd/mtdsplit/mtdsplit_wrgg.c | 142 + - drivers/mtd/nand/mtk_bmt.c | 474 + - drivers/mtd/nand/mtk_bmt.h | 137 + - drivers/mtd/nand/mtk_bmt_bbt.c | 203 + - drivers/mtd/nand/mtk_bmt_nmbm.c | 2348 ++ - drivers/mtd/nand/mtk_bmt_v2.c | 506 + - drivers/mtd/parsers/routerbootpart.c | 365 + - drivers/net/dsa/an8855.c | 2308 ++ - drivers/net/dsa/an8855.h | 783 + - drivers/net/mdio/mdio-an8855.c | 113 + - drivers/net/phy/adm6996.c | 1241 + - drivers/net/phy/adm6996.h | 186 + - drivers/net/phy/air_an8855.c | 267 + - drivers/net/phy/ar8216.c | 2909 ++ - drivers/net/phy/ar8216.h | 725 + - drivers/net/phy/ar8327.c | 1589 ++ - drivers/net/phy/ar8327.h | 334 + - drivers/net/phy/b53/Kconfig | 37 + - drivers/net/phy/b53/Makefile | 10 + - drivers/net/phy/b53/b53_common.c | 1724 ++ - drivers/net/phy/b53/b53_mdio.c | 436 + - drivers/net/phy/b53/b53_mmap.c | 239 + - drivers/net/phy/b53/b53_phy_fixup.c | 55 + - drivers/net/phy/b53/b53_priv.h | 336 + - drivers/net/phy/b53/b53_regs.h | 348 + - drivers/net/phy/b53/b53_spi.c | 344 + - drivers/net/phy/b53/b53_srab.c | 376 + - drivers/net/phy/en8801sc.c | 1117 + - drivers/net/phy/en8801sc.h | 250 + - drivers/net/phy/ip17xx.c | 1370 + - drivers/net/phy/psb6970.c | 443 + - drivers/net/phy/rtk/Makefile | 66 + - drivers/net/phy/rtk/rtl8367c/acl.c | 2061 ++ - drivers/net/phy/rtk/rtl8367c/cpu.c | 537 + - drivers/net/phy/rtk/rtl8367c/dot1x.c | 843 + - drivers/net/phy/rtk/rtl8367c/eee.c | 162 + - drivers/net/phy/rtk/rtl8367c/i2c.c | 436 + - drivers/net/phy/rtk/rtl8367c/igmp.c | 1555 ++ - drivers/net/phy/rtk/rtl8367c/include/acl.h | 990 + - drivers/net/phy/rtk/rtl8367c/include/cpu.h | 327 + - drivers/net/phy/rtk/rtl8367c/include/dot1x.h | 470 + - drivers/net/phy/rtk/rtl8367c/include/eee.h | 82 + - drivers/net/phy/rtk/rtl8367c/include/i2c.h | 168 + - drivers/net/phy/rtk/rtl8367c/include/igmp.h | 769 + - .../net/phy/rtk/rtl8367c/include/interrupt.h | 254 + - drivers/net/phy/rtk/rtl8367c/include/l2.h | 1181 + - drivers/net/phy/rtk/rtl8367c/include/leaky.h | 371 + - drivers/net/phy/rtk/rtl8367c/include/led.h | 481 + - drivers/net/phy/rtk/rtl8367c/include/mirror.h | 272 + - drivers/net/phy/rtk/rtl8367c/include/oam.h | 188 + - drivers/net/phy/rtk/rtl8367c/include/port.h | 959 + - drivers/net/phy/rtk/rtl8367c/include/ptp.h | 511 + - drivers/net/phy/rtk/rtl8367c/include/qos.h | 781 + - drivers/net/phy/rtk/rtl8367c/include/rate.h | 305 + - drivers/net/phy/rtk/rtl8367c/include/rldp.h | 264 + - .../net/phy/rtk/rtl8367c/include/rtk_error.h | 229 + - .../net/phy/rtk/rtl8367c/include/rtk_hal.h | 44 + - .../net/phy/rtk/rtl8367c/include/rtk_switch.h | 741 + - .../net/phy/rtk/rtl8367c/include/rtk_types.h | 155 + - .../rtk/rtl8367c/include/rtl8367c_asicdrv.h | 129 + - .../rtl8367c/include/rtl8367c_asicdrv_acl.h | 231 + - .../include/rtl8367c_asicdrv_cputag.h | 49 + - .../rtl8367c/include/rtl8367c_asicdrv_dot1x.h | 52 + - .../rtl8367c/include/rtl8367c_asicdrv_eav.h | 109 + - .../rtl8367c/include/rtl8367c_asicdrv_eee.h | 31 + - .../rtl8367c/include/rtl8367c_asicdrv_fc.h | 99 + - .../rtl8367c/include/rtl8367c_asicdrv_green.h | 36 + - .../rtl8367c/include/rtl8367c_asicdrv_hsb.h | 43 + - .../rtl8367c/include/rtl8367c_asicdrv_i2c.h | 47 + - .../rtl8367c/include/rtl8367c_asicdrv_igmp.h | 169 + - .../include/rtl8367c_asicdrv_inbwctrl.h | 30 + - .../include/rtl8367c_asicdrv_interrupt.h | 66 + - .../rtl8367c/include/rtl8367c_asicdrv_led.h | 138 + - .../rtl8367c/include/rtl8367c_asicdrv_lut.h | 159 + - .../rtl8367c/include/rtl8367c_asicdrv_meter.h | 34 + - .../rtl8367c/include/rtl8367c_asicdrv_mib.h | 133 + - .../include/rtl8367c_asicdrv_mii_mgr.h | 26 + - .../include/rtl8367c_asicdrv_mirror.h | 49 + - .../rtl8367c/include/rtl8367c_asicdrv_misc.h | 34 + - .../rtl8367c/include/rtl8367c_asicdrv_oam.h | 47 + - .../rtl8367c/include/rtl8367c_asicdrv_phy.h | 43 + - .../rtl8367c/include/rtl8367c_asicdrv_port.h | 237 + - .../include/rtl8367c_asicdrv_portIsolation.h | 28 + - .../rtl8367c/include/rtl8367c_asicdrv_qos.h | 96 + - .../rtl8367c/include/rtl8367c_asicdrv_rldp.h | 60 + - .../rtl8367c/include/rtl8367c_asicdrv_rma.h | 57 + - .../include/rtl8367c_asicdrv_scheduling.h | 58 + - .../rtl8367c/include/rtl8367c_asicdrv_storm.h | 61 + - .../rtl8367c/include/rtl8367c_asicdrv_svlan.h | 132 + - .../include/rtl8367c_asicdrv_trunking.h | 48 + - .../rtl8367c_asicdrv_unknownMulticast.h | 59 + - .../rtl8367c/include/rtl8367c_asicdrv_vlan.h | 157 + - .../phy/rtk/rtl8367c/include/rtl8367c_base.h | 596 + - .../phy/rtk/rtl8367c/include/rtl8367c_reg.h | 22819 ++++++++++++++++ - drivers/net/phy/rtk/rtl8367c/include/smi.h | 54 + - drivers/net/phy/rtk/rtl8367c/include/stat.h | 433 + - drivers/net/phy/rtk/rtl8367c/include/storm.h | 422 + - drivers/net/phy/rtk/rtl8367c/include/svlan.h | 896 + - drivers/net/phy/rtk/rtl8367c/include/trap.h | 757 + - drivers/net/phy/rtk/rtl8367c/include/trunk.h | 328 + - drivers/net/phy/rtk/rtl8367c/include/vlan.h | 892 + - drivers/net/phy/rtk/rtl8367c/interrupt.c | 434 + - drivers/net/phy/rtk/rtl8367c/l2.c | 2911 ++ - drivers/net/phy/rtk/rtl8367c/leaky.c | 590 + - drivers/net/phy/rtk/rtl8367c/led.c | 792 + - drivers/net/phy/rtk/rtl8367c/mirror.c | 548 + - drivers/net/phy/rtk/rtl8367c/oam.c | 245 + - drivers/net/phy/rtk/rtl8367c/port.c | 2467 ++ - drivers/net/phy/rtk/rtl8367c/ptp.c | 759 + - drivers/net/phy/rtk/rtl8367c/qos.c | 1452 + - drivers/net/phy/rtk/rtl8367c/rate.c | 607 + - drivers/net/phy/rtk/rtl8367c/rldp.c | 468 + - drivers/net/phy/rtk/rtl8367c/rtk_hal.c | 839 + - drivers/net/phy/rtk/rtl8367c/rtk_switch.c | 1794 ++ - .../net/phy/rtk/rtl8367c/rtl8367c_asicdrv.c | 639 + - .../phy/rtk/rtl8367c/rtl8367c_asicdrv_acl.c | 1173 + - .../rtk/rtl8367c/rtl8367c_asicdrv_cputag.c | 369 + - .../phy/rtk/rtl8367c/rtl8367c_asicdrv_dot1x.c | 415 + - .../phy/rtk/rtl8367c/rtl8367c_asicdrv_eav.c | 877 + - .../phy/rtk/rtl8367c/rtl8367c_asicdrv_eee.c | 141 + - .../phy/rtk/rtl8367c/rtl8367c_asicdrv_fc.c | 1354 + - .../phy/rtk/rtl8367c/rtl8367c_asicdrv_green.c | 445 + - .../phy/rtk/rtl8367c/rtl8367c_asicdrv_hsb.c | 81 + - .../phy/rtk/rtl8367c/rtl8367c_asicdrv_i2c.c | 474 + - .../phy/rtk/rtl8367c/rtl8367c_asicdrv_igmp.c | 2109 ++ - .../rtk/rtl8367c/rtl8367c_asicdrv_inbwctrl.c | 164 + - .../rtk/rtl8367c/rtl8367c_asicdrv_interrupt.c | 205 + - .../phy/rtk/rtl8367c/rtl8367c_asicdrv_led.c | 727 + - .../phy/rtk/rtl8367c/rtl8367c_asicdrv_lut.c | 1549 ++ - .../phy/rtk/rtl8367c/rtl8367c_asicdrv_meter.c | 305 + - .../phy/rtk/rtl8367c/rtl8367c_asicdrv_mib.c | 570 + - .../rtk/rtl8367c/rtl8367c_asicdrv_mirror.c | 472 + - .../phy/rtk/rtl8367c/rtl8367c_asicdrv_misc.c | 268 + - .../phy/rtk/rtl8367c/rtl8367c_asicdrv_oam.c | 194 + - .../phy/rtk/rtl8367c/rtl8367c_asicdrv_phy.c | 394 + - .../phy/rtk/rtl8367c/rtl8367c_asicdrv_port.c | 5752 ++++ - .../rtl8367c/rtl8367c_asicdrv_portIsolation.c | 119 + - .../phy/rtk/rtl8367c/rtl8367c_asicdrv_qos.c | 778 + - .../phy/rtk/rtl8367c/rtl8367c_asicdrv_rldp.c | 674 + - .../phy/rtk/rtl8367c/rtl8367c_asicdrv_rma.c | 362 + - .../rtl8367c/rtl8367c_asicdrv_scheduling.c | 525 + - .../phy/rtk/rtl8367c/rtl8367c_asicdrv_storm.c | 851 + - .../phy/rtk/rtl8367c/rtl8367c_asicdrv_svlan.c | 1003 + - .../rtk/rtl8367c/rtl8367c_asicdrv_trunking.c | 356 + - .../rtl8367c_asicdrv_unknownMulticast.c | 238 + - .../phy/rtk/rtl8367c/rtl8367c_asicdrv_vlan.c | 1505 + - drivers/net/phy/rtk/rtl8367c/smi.c | 442 + - drivers/net/phy/rtk/rtl8367c/stat.c | 626 + - drivers/net/phy/rtk/rtl8367c/storm.c | 816 + - drivers/net/phy/rtk/rtl8367c/svlan.c | 2415 ++ - drivers/net/phy/rtk/rtl8367c/trap.c | 1229 + - drivers/net/phy/rtk/rtl8367c/trunk.c | 605 + - drivers/net/phy/rtk/rtl8367c/vlan.c | 2124 ++ - drivers/net/phy/rtk/rtl8367s.c | 580 + - drivers/net/phy/rtk/rtl8367s_dbg.c | 648 + - drivers/net/phy/rtk/rtl8367s_mdio.c | 301 + - drivers/net/phy/rtl8261n/Kconfig | 5 + - drivers/net/phy/rtl8261n/Makefile | 11 + - .../phy/rtl8261n/construct/conf_rtl8261n_c.c | 1465 + - .../phy/rtl8261n/construct/conf_rtl8264b.c | 2177 ++ - drivers/net/phy/rtl8261n/error.h | 165 + - drivers/net/phy/rtl8261n/phy_patch.c | 188 + - drivers/net/phy/rtl8261n/phy_patch.h | 174 + - drivers/net/phy/rtl8261n/phy_rtl826xb_patch.c | 1031 + - drivers/net/phy/rtl8261n/phy_rtl826xb_patch.h | 63 + - drivers/net/phy/rtl8261n/rtk_osal.c | 57 + - drivers/net/phy/rtl8261n/rtk_osal.h | 99 + - drivers/net/phy/rtl8261n/rtk_phy.c | 324 + - drivers/net/phy/rtl8261n/rtk_phylib.c | 108 + - drivers/net/phy/rtl8261n/rtk_phylib.h | 106 + - drivers/net/phy/rtl8261n/rtk_phylib_def.h | 166 + - .../net/phy/rtl8261n/rtk_phylib_rtl826xb.c | 57 + - .../net/phy/rtl8261n/rtk_phylib_rtl826xb.h | 19 + - drivers/net/phy/rtl8261n/type.h | 117 + - drivers/net/phy/rtl8306.c | 1063 + - drivers/net/phy/rtl8366_smi.c | 1625 ++ - drivers/net/phy/rtl8366_smi.h | 171 + - drivers/net/phy/rtl8366rb.c | 1529 ++ - drivers/net/phy/rtl8366s.c | 1317 + - drivers/net/phy/rtl8367.c | 1859 ++ - drivers/net/phy/rtl8367b.c | 1649 ++ - drivers/net/phy/swconfig.c | 1242 + - drivers/net/phy/swconfig_leds.c | 555 + - drivers/nvmem/an8855-efuse.c | 63 + - drivers/platform/mikrotik/Kconfig | 31 + - drivers/platform/mikrotik/Makefile | 6 + - drivers/platform/mikrotik/rb_hardconfig.c | 844 + - drivers/platform/mikrotik/rb_hardconfig.h | 32 + - drivers/platform/mikrotik/rb_lz77.c | 446 + - drivers/platform/mikrotik/rb_lz77.h | 35 + - drivers/platform/mikrotik/rb_nvmem.c | 230 + - drivers/platform/mikrotik/rb_softconfig.c | 795 + - drivers/platform/mikrotik/routerboot.c | 251 + - drivers/platform/mikrotik/routerboot.h | 38 + - drivers/ssb/fallback-sprom.c | 745 + - drivers/ssb/fallback-sprom.h | 7 + - include/dt-bindings/mtd/partitions/uimage.h | 198 + - include/linux/ar8216_platform.h | 134 + - include/linux/ath5k_platform.h | 30 + - include/linux/mfd/airoha-an8855-mfd.h | 41 + - include/linux/mtd/mtk_bmt.h | 18 + - include/linux/myloader.h | 121 + - include/linux/platform_data/adm6996-gpio.h | 29 + - include/linux/routerboot.h | 106 + - include/linux/rtl8366.h | 42 + - include/linux/rtl8367.h | 63 + - include/linux/switch.h | 179 + - include/uapi/linux/switch.h | 119 + - 245 files changed, 143699 insertions(+) - create mode 100644 Documentation/devicetree/bindings/mtd/partitions/openwrt,uimage.yaml - create mode 100644 Documentation/networking/adm6996.txt - create mode 100644 arch/arm64/boot/dts/mediatek/mt7981-rfb-mxl-2p5g-phy-eth1.dtso - create mode 100644 arch/arm64/boot/dts/mediatek/mt7981-rfb-mxl-2p5g-phy-swp5.dtso - create mode 100644 arch/arm64/boot/dts/mediatek/mt7981-rfb-spim-nand.dtso - create mode 100644 arch/arm64/boot/dts/mediatek/mt7981-rfb.dts - create mode 100644 arch/arm64/boot/dts/mediatek/mt7986a-rfb-spim-nand.dts - create mode 100644 arch/arm64/boot/dts/mediatek/mt7986a-rfb-spim-nor.dts - create mode 100644 arch/arm64/boot/dts/mediatek/mt7986a-rfb.dtsi - create mode 100644 arch/mips/fw/myloader/Makefile - create mode 100644 arch/mips/fw/myloader/myloader.c - create mode 100644 drivers/bcma/fallback-sprom.c - create mode 100644 drivers/bcma/fallback-sprom.h - create mode 100644 drivers/leds/leds-smartrg-system.c - create mode 100644 drivers/mfd/airoha-an8855.c - create mode 100644 drivers/mtd/mtdsplit/Kconfig - create mode 100644 drivers/mtd/mtdsplit/Makefile - create mode 100644 drivers/mtd/mtdsplit/mtdsplit.c - create mode 100644 drivers/mtd/mtdsplit/mtdsplit.h - create mode 100644 drivers/mtd/mtdsplit/mtdsplit_bcm63xx.c - create mode 100644 drivers/mtd/mtdsplit/mtdsplit_bcm_wfi.c - create mode 100644 drivers/mtd/mtdsplit/mtdsplit_brnimage.c - create mode 100644 drivers/mtd/mtdsplit/mtdsplit_cfe_bootfs.c - create mode 100644 drivers/mtd/mtdsplit/mtdsplit_elf.c - create mode 100644 drivers/mtd/mtdsplit/mtdsplit_eva.c - create mode 100644 drivers/mtd/mtdsplit/mtdsplit_fit.c - create mode 100644 drivers/mtd/mtdsplit/mtdsplit_h3c_vfs.c - create mode 100644 drivers/mtd/mtdsplit/mtdsplit_jimage.c - create mode 100644 drivers/mtd/mtdsplit/mtdsplit_lzma.c - create mode 100644 drivers/mtd/mtdsplit/mtdsplit_minor.c - create mode 100644 drivers/mtd/mtdsplit/mtdsplit_mstc_boot.c - create mode 100644 drivers/mtd/mtdsplit/mtdsplit_seama.c - create mode 100644 drivers/mtd/mtdsplit/mtdsplit_seil.c - create mode 100644 drivers/mtd/mtdsplit/mtdsplit_squashfs.c - create mode 100644 drivers/mtd/mtdsplit/mtdsplit_tplink.c - create mode 100644 drivers/mtd/mtdsplit/mtdsplit_trx.c - create mode 100644 drivers/mtd/mtdsplit/mtdsplit_uimage.c - create mode 100644 drivers/mtd/mtdsplit/mtdsplit_wrgg.c - create mode 100644 drivers/mtd/nand/mtk_bmt.c - create mode 100644 drivers/mtd/nand/mtk_bmt.h - create mode 100644 drivers/mtd/nand/mtk_bmt_bbt.c - create mode 100644 drivers/mtd/nand/mtk_bmt_nmbm.c - create mode 100644 drivers/mtd/nand/mtk_bmt_v2.c - create mode 100644 drivers/mtd/parsers/routerbootpart.c - create mode 100644 drivers/net/dsa/an8855.c - create mode 100644 drivers/net/dsa/an8855.h - create mode 100644 drivers/net/mdio/mdio-an8855.c - create mode 100644 drivers/net/phy/adm6996.c - create mode 100644 drivers/net/phy/adm6996.h - create mode 100644 drivers/net/phy/air_an8855.c - create mode 100644 drivers/net/phy/ar8216.c - create mode 100644 drivers/net/phy/ar8216.h - create mode 100644 drivers/net/phy/ar8327.c - create mode 100644 drivers/net/phy/ar8327.h - create mode 100644 drivers/net/phy/b53/Kconfig - create mode 100644 drivers/net/phy/b53/Makefile - create mode 100644 drivers/net/phy/b53/b53_common.c - create mode 100644 drivers/net/phy/b53/b53_mdio.c - create mode 100644 drivers/net/phy/b53/b53_mmap.c - create mode 100644 drivers/net/phy/b53/b53_phy_fixup.c - create mode 100644 drivers/net/phy/b53/b53_priv.h - create mode 100644 drivers/net/phy/b53/b53_regs.h - create mode 100644 drivers/net/phy/b53/b53_spi.c - create mode 100644 drivers/net/phy/b53/b53_srab.c - create mode 100644 drivers/net/phy/en8801sc.c - create mode 100644 drivers/net/phy/en8801sc.h - create mode 100644 drivers/net/phy/ip17xx.c - create mode 100644 drivers/net/phy/psb6970.c - create mode 100644 drivers/net/phy/rtk/Makefile - create mode 100644 drivers/net/phy/rtk/rtl8367c/acl.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/cpu.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/dot1x.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/eee.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/i2c.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/igmp.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/acl.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/cpu.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/dot1x.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/eee.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/i2c.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/igmp.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/interrupt.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/l2.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/leaky.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/led.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/mirror.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/oam.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/port.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/ptp.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/qos.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rate.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rldp.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtk_error.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtk_hal.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtk_switch.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtk_types.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_acl.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_cputag.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_dot1x.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eav.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eee.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_fc.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_green.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_hsb.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_i2c.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_igmp.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_inbwctrl.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_interrupt.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_led.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_lut.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_meter.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mib.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mii_mgr.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mirror.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_misc.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_oam.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_phy.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_port.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_portIsolation.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_qos.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rldp.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rma.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_scheduling.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_storm.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_svlan.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_trunking.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_unknownMulticast.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_vlan.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_base.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/rtl8367c_reg.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/smi.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/stat.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/storm.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/svlan.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/trap.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/trunk.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/include/vlan.h - create mode 100644 drivers/net/phy/rtk/rtl8367c/interrupt.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/l2.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/leaky.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/led.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/mirror.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/oam.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/port.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/ptp.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/qos.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rate.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rldp.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtk_hal.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtk_switch.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_acl.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_cputag.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_dot1x.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eav.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eee.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_fc.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_green.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_hsb.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_i2c.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_igmp.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_inbwctrl.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_interrupt.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_led.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_lut.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_meter.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_mib.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_mirror.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_misc.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_oam.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_phy.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_port.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_portIsolation.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_qos.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rldp.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rma.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_scheduling.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_storm.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_svlan.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_trunking.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_unknownMulticast.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_vlan.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/smi.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/stat.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/storm.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/svlan.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/trap.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/trunk.c - create mode 100644 drivers/net/phy/rtk/rtl8367c/vlan.c - create mode 100644 drivers/net/phy/rtk/rtl8367s.c - create mode 100644 drivers/net/phy/rtk/rtl8367s_dbg.c - create mode 100644 drivers/net/phy/rtk/rtl8367s_mdio.c - create mode 100644 drivers/net/phy/rtl8261n/Kconfig - create mode 100644 drivers/net/phy/rtl8261n/Makefile - create mode 100644 drivers/net/phy/rtl8261n/construct/conf_rtl8261n_c.c - create mode 100644 drivers/net/phy/rtl8261n/construct/conf_rtl8264b.c - create mode 100644 drivers/net/phy/rtl8261n/error.h - create mode 100644 drivers/net/phy/rtl8261n/phy_patch.c - create mode 100644 drivers/net/phy/rtl8261n/phy_patch.h - create mode 100644 drivers/net/phy/rtl8261n/phy_rtl826xb_patch.c - create mode 100644 drivers/net/phy/rtl8261n/phy_rtl826xb_patch.h - create mode 100644 drivers/net/phy/rtl8261n/rtk_osal.c - create mode 100644 drivers/net/phy/rtl8261n/rtk_osal.h - create mode 100644 drivers/net/phy/rtl8261n/rtk_phy.c - create mode 100644 drivers/net/phy/rtl8261n/rtk_phylib.c - create mode 100644 drivers/net/phy/rtl8261n/rtk_phylib.h - create mode 100644 drivers/net/phy/rtl8261n/rtk_phylib_def.h - create mode 100644 drivers/net/phy/rtl8261n/rtk_phylib_rtl826xb.c - create mode 100644 drivers/net/phy/rtl8261n/rtk_phylib_rtl826xb.h - create mode 100644 drivers/net/phy/rtl8261n/type.h - create mode 100644 drivers/net/phy/rtl8306.c - create mode 100644 drivers/net/phy/rtl8366_smi.c - create mode 100644 drivers/net/phy/rtl8366_smi.h - create mode 100644 drivers/net/phy/rtl8366rb.c - create mode 100644 drivers/net/phy/rtl8366s.c - create mode 100644 drivers/net/phy/rtl8367.c - create mode 100644 drivers/net/phy/rtl8367b.c - create mode 100644 drivers/net/phy/swconfig.c - create mode 100644 drivers/net/phy/swconfig_leds.c - create mode 100644 drivers/nvmem/an8855-efuse.c - create mode 100644 drivers/platform/mikrotik/Kconfig - create mode 100644 drivers/platform/mikrotik/Makefile - create mode 100644 drivers/platform/mikrotik/rb_hardconfig.c - create mode 100644 drivers/platform/mikrotik/rb_hardconfig.h - create mode 100644 drivers/platform/mikrotik/rb_lz77.c - create mode 100644 drivers/platform/mikrotik/rb_lz77.h - create mode 100644 drivers/platform/mikrotik/rb_nvmem.c - create mode 100644 drivers/platform/mikrotik/rb_softconfig.c - create mode 100644 drivers/platform/mikrotik/routerboot.c - create mode 100644 drivers/platform/mikrotik/routerboot.h - create mode 100644 drivers/ssb/fallback-sprom.c - create mode 100644 drivers/ssb/fallback-sprom.h - create mode 100644 include/dt-bindings/mtd/partitions/uimage.h - create mode 100644 include/linux/ar8216_platform.h - create mode 100644 include/linux/ath5k_platform.h - create mode 100644 include/linux/mfd/airoha-an8855-mfd.h - create mode 100644 include/linux/mtd/mtk_bmt.h - create mode 100644 include/linux/myloader.h - create mode 100644 include/linux/platform_data/adm6996-gpio.h - create mode 100644 include/linux/routerboot.h - create mode 100644 include/linux/rtl8366.h - create mode 100644 include/linux/rtl8367.h - create mode 100644 include/linux/switch.h - create mode 100644 include/uapi/linux/switch.h - -diff --git a/Documentation/devicetree/bindings/mtd/partitions/openwrt,uimage.yaml b/Documentation/devicetree/bindings/mtd/partitions/openwrt,uimage.yaml -new file mode 100644 -index 000000000000..d052ab1fc981 ---- /dev/null -+++ b/Documentation/devicetree/bindings/mtd/partitions/openwrt,uimage.yaml -@@ -0,0 +1,91 @@ -+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/mtd/partitions/openwrt,uimage.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: OpenWrt variations of U-Boot Image partitions -+ -+maintainers: -+ - Bjørn Mork -+ -+description: | -+ The image format defined by the boot loader "Das U-Boot" is often -+ modified or extended by device vendors. This defines a few optional -+ properties which can be used to describe such modifications. -+ -+# partition.txt defines common properties, but has not yet been -+# converted to YAML -+#allOf: -+# - $ref: ../partition.yaml# -+ -+properties: -+ compatible: -+ items: -+ - enum: -+ - openwrt,uimage -+ - const: denx,uimage -+ -+ openwrt,padding: -+ description: Number of padding bytes between header and data -+ $ref: /schemas/types.yaml#/definitions/uint32 -+ default: 0 -+ -+ openwrt,ih-magic: -+ description: U-Boot Image Header magic number. -+ $ref: /schemas/types.yaml#/definitions/uint32 -+ default: 0x27051956 # IH_MAGIC -+ -+ openwrt,ih-type: -+ description: U-Boot Image type -+ $ref: /schemas/types.yaml#/definitions/uint32 -+ default: 2 # IH_TYPE_KERNEL -+ -+ openwrt,offset: -+ description: -+ Offset between partition start and U-Boot Image in bytes -+ $ref: /schemas/types.yaml#/definitions/uint32 -+ default: 0 -+ -+ openwrt,partition-magic: -+ description: -+ Magic number found at the start of the partition. Will only be -+ validated if both this property and openwrt,offset is non-zero -+ $ref: /schemas/types.yaml#/definitions/uint32 -+ default: 0 -+ -+required: -+ - compatible -+ - reg -+ -+#unevaluatedProperties: false -+additionalProperties: false -+ -+examples: -+ - | -+ // device with non-default magic -+ partition@300000 { -+ compatible = "openwrt,uimage", "denx,uimage"; -+ reg = <0x00300000 0xe80000>; -+ label = "firmware"; -+ openwrt,ih-magic = <0x4e474520>; -+ }; -+ - | -+ // device with U-Boot Image at an offset, with a partition magic value -+ partition@70000 { -+ compatible = "openwrt,uimage", "denx,uimage"; -+ reg = <0x00070000 0x00790000>; -+ label = "firmware"; -+ openwrt,offset = <20>; -+ openwrt,partition-magic = <0x43535953>; -+ }; -+ - | -+ // device using a non-default image type -+ #include "dt-bindings/mtd/partitions/uimage.h" -+ partition@6c0000 { -+ compatible = "openwrt,uimage", "denx,uimage"; -+ reg = <0x6c0000 0x1900000>; -+ label = "firmware"; -+ openwrt,ih-magic = <0x33373033>; -+ openwrt,ih-type = ; -+ }; -diff --git a/Documentation/networking/adm6996.txt b/Documentation/networking/adm6996.txt -new file mode 100644 -index 000000000000..ab59f1df0337 ---- /dev/null -+++ b/Documentation/networking/adm6996.txt -@@ -0,0 +1,110 @@ -+------- -+ -+ADM6996FC / ADM6996M switch chip driver -+ -+ -+1. General information -+ -+ This driver supports the FC and M models only. The ADM6996F and L are -+ completely different chips. -+ -+ Support for the FC model is extremely limited at the moment. There is no VLAN -+ support as of yet. The driver will not offer an swconfig interface for the FC -+ chip. -+ -+1.1 VLAN IDs -+ -+ It is possible to define 16 different VLANs. Every VLAN has an identifier, its -+ VLAN ID. It is easiest if you use at most VLAN IDs 0-15. In that case, the -+ swconfig based configuration is very straightforward. To define two VLANs with -+ IDs 4 and 5, you can invoke, for example: -+ -+ # swconfig dev ethX vlan 4 set ports '0 1t 2 5t' -+ # swconfig dev ethX vlan 5 set ports '0t 1t 5t' -+ -+ The swconfig framework will automatically invoke 'port Y set pvid Z' for every -+ port that is an untagged member of VLAN Y, setting its Primary VLAN ID. In -+ this example, ports 0 and 2 would get "pvid 4". The Primary VLAN ID of a port -+ is the VLAN ID associated with untagged packets coming in on that port. -+ -+ But if you wish to use VLAN IDs outside the range 0-15, this automatic -+ behaviour of the swconfig framework becomes a problem. The 16 VLANs that -+ swconfig can configure on the ADM6996 also have a "vid" setting. By default, -+ this is the same as the number of the VLAN entry, to make the simple behaviour -+ above possible. To still support a VLAN with a VLAN ID higher than 15 -+ (presumably because you are in a network where such VLAN IDs are already in -+ use), you can change the "vid" setting of the VLAN to anything in the range -+ 0-1023. But suppose you did the following: -+ -+ # swconfig dev ethX vlan 0 set vid 998 -+ # swconfig dev ethX vlan 0 set ports '0 2 5t' -+ -+ Now the swconfig framework will issue 'port 0 set pvid 0' and 'port 2 set pvid -+ 0'. But the "pvid" should be set to 998, so you are responsible for manually -+ fixing this! -+ -+1.2 VLAN filtering -+ -+ The switch is configured to apply source port filtering. This means that -+ packets are only accepted when the port the packets came in on is a member of -+ the VLAN the packet should go to. -+ -+ Only membership of a VLAN is tested, it does not matter whether it is a tagged -+ or untagged membership. -+ -+ For untagged packets, the destination VLAN is the Primary VLAN ID of the -+ incoming port. So if the PVID of a port is 0, but that port is not a member of -+ the VLAN with ID 0, this means that untagged packets on that port are dropped. -+ This can be used as a roundabout way of dropping untagged packets from a port, -+ a mode often referred to as "Admit only tagged packets". -+ -+1.3 Reset -+ -+ The two supported chip models do not have a sofware-initiated reset. When the -+ driver is initialised, as well as when the 'reset' swconfig option is invoked, -+ the driver will set those registers it knows about and supports to the correct -+ default value. But there are a lot of registers in the chip that the driver -+ does not support. If something changed those registers, invoking 'reset' or -+ performing a warm reboot might still leave the chip in a "broken" state. Only -+ a hardware reset will bring it back in the default state. -+ -+2. Technical details on PHYs and the ADM6996 -+ -+ From the viewpoint of the Linux kernel, it is common that an Ethernet adapter -+ can be seen as a separate MAC entity and a separate PHY entity. The PHY entity -+ can be queried and set through registers accessible via an MDIO bus. A PHY -+ normally has a single address on that bus, in the range 0 through 31. -+ -+ The ADM6996 has special-purpose registers in the range of PHYs 0 through 10. -+ Even though all these registers control a single ADM6996 chip, the Linux -+ kernel treats this as 11 separate PHYs. The driver will bind to these -+ addresses to prevent a different PHY driver from binding and corrupting these -+ registers. -+ -+ What Linux sees as the PHY on address 0 is meant for the Ethernet MAC -+ connected to the CPU port of the ADM6996 switch chip (port 5). This is the -+ Ethernet MAC you will use to send and receive data through the switch. -+ -+ The PHYs at addresses 16 through 20 map to the PHYs on ports 0 through 4 of -+ the switch chip. These can be accessed with the Generic PHY driver, as the -+ registers have the common layout. -+ -+ If a second Ethernet MAC on your board is wired to the port 4 PHY, that MAC -+ needs to bind to PHY address 20 for the port to work correctly. -+ -+ The ADM6996 switch driver will reset the ports 0 through 3 on startup and when -+ 'reset' is invoked. This could clash with a different PHY driver if the kernel -+ binds a PHY driver to address 16 through 19. -+ -+ If Linux binds a PHY on addresses 1 through 10 to an Ethernet MAC, the ADM6996 -+ driver will simply always report a connected 100 Mbit/s full-duplex link for -+ that PHY, and provide no other functionality. This is most likely not what you -+ want. So if you see a message in your log -+ -+ ethX: PHY overlaps ADM6996, providing fixed PHY yy. -+ -+ This is most likely an indication that ethX will not work properly, and your -+ kernel needs to be configured to attach a different PHY to that Ethernet MAC. -+ -+ Controlling the mapping between MACs and PHYs is usually done in platform- or -+ board-specific fixup code. The ADM6996 driver has no influence over this. -diff --git a/arch/arm64/boot/dts/mediatek/mt7981-rfb-mxl-2p5g-phy-eth1.dtso b/arch/arm64/boot/dts/mediatek/mt7981-rfb-mxl-2p5g-phy-eth1.dtso -new file mode 100644 -index 000000000000..51d5dc661ad6 ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7981-rfb-mxl-2p5g-phy-eth1.dtso -@@ -0,0 +1,34 @@ -+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ -+/dts-v1/; -+/plugin/; -+ -+#include -+ -+/ { -+ compatible = "mediatek,mt7981-rfb", "mediatek,mt7981"; -+ -+ fragment@0 { -+ target = <&gmac1>; -+ __overlay__ { -+ phy-mode = "2500base-x"; -+ phy-handle = <&phy5>; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&mdio_bus>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reset-gpios = <&pio 14 GPIO_ACTIVE_LOW>; -+ reset-delay-us = <600>; -+ reset-post-delay-us = <20000>; -+ -+ phy5: ethernet-phy@5 { -+ reg = <5>; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ phy-mode = "2500base-x"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7981-rfb-mxl-2p5g-phy-swp5.dtso b/arch/arm64/boot/dts/mediatek/mt7981-rfb-mxl-2p5g-phy-swp5.dtso -new file mode 100644 -index 000000000000..4cc3cf1df6cf ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7981-rfb-mxl-2p5g-phy-swp5.dtso -@@ -0,0 +1,35 @@ -+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ -+/dts-v1/; -+/plugin/; -+ -+#include -+ -+/ { -+ compatible = "mediatek,mt7981-rfb", "mediatek,mt7981"; -+ -+ fragment@0 { -+ target = <&sw_p5>; -+ __overlay__ { -+ phy-mode = "2500base-x"; -+ phy-handle = <&phy5>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&mdio_bus>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reset-gpios = <&pio 14 GPIO_ACTIVE_LOW>; -+ reset-delay-us = <600>; -+ reset-post-delay-us = <20000>; -+ -+ phy5: ethernet-phy@5 { -+ reg = <5>; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ phy-mode = "2500base-x"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7981-rfb-spim-nand.dtso b/arch/arm64/boot/dts/mediatek/mt7981-rfb-spim-nand.dtso -new file mode 100644 -index 000000000000..af4845ec6cff ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7981-rfb-spim-nand.dtso -@@ -0,0 +1,78 @@ -+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "mediatek,mt7981-rfb", "mediatek,mt7981"; -+ -+ fragment@0 { -+ target = <&chosen>; -+ rootdisk-spim-nand = <&ubi_rootdisk>; -+ }; -+ -+ fragment@1 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ spi_nand: spi_nand@1 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "spi-nand"; -+ reg = <1>; -+ spi-max-frequency = <10000000>; -+ spi-tx-bus-width = <4>; -+ spi-rx-bus-width = <4>; -+ -+ partitions { -+ compatible = "fixed-partitions"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ partition@0 { -+ label = "BL2"; -+ reg = <0x00000 0x0100000>; -+ read-only; -+ }; -+ -+ partition@100000 { -+ label = "u-boot-env"; -+ reg = <0x0100000 0x0080000>; -+ }; -+ -+ factory: partition@180000 { -+ label = "Factory"; -+ reg = <0x180000 0x0200000>; -+ }; -+ -+ partition@380000 { -+ label = "FIP"; -+ reg = <0x380000 0x0200000>; -+ }; -+ -+ partition@580000 { -+ label = "ubi"; -+ reg = <0x580000 0x4000000>; -+ compatible = "linux,ubi"; -+ -+ volumes { -+ ubi_rootdisk: ubi-volume-fit { -+ volname = "fit"; -+ }; -+ }; -+ }; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&wifi>; -+ __overlay__ { -+ mediatek,mtd-eeprom = <&factory 0x0>; -+ status = "okay"; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7981-rfb.dts b/arch/arm64/boot/dts/mediatek/mt7981-rfb.dts -new file mode 100644 -index 000000000000..155157762479 ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7981-rfb.dts -@@ -0,0 +1,189 @@ -+// SPDX-License-Identifier: (GPL-2.0 OR MIT) -+/* -+ * Copyright (C) 2022 MediaTek Inc. -+ * Author: Sam.Shih -+ */ -+ -+/dts-v1/; -+#include "mt7981b.dtsi" -+ -+/ { -+ model = "MediaTek MT7981 RFB"; -+ compatible = "mediatek,mt7981-rfb", "mediatek,mt7981"; -+ -+ aliases { -+ serial0 = &uart0; -+ }; -+ -+ chosen: chosen { -+ stdout-path = "serial0:115200n8"; -+ bootargs-append = " root=/dev/fit0 rootwait"; -+ }; -+ -+ memory@40000000 { -+ reg = <0 0x40000000 0 0x20000000>; -+ device_type = "memory"; -+ }; -+ -+ reg_3p3v: regulator-3p3v { -+ compatible = "regulator-fixed"; -+ regulator-name = "fixed-3.3V"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ reg_5v: regulator-5v { -+ compatible = "regulator-fixed"; -+ regulator-name = "fixed-5V"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ gpio-keys { -+ compatible = "gpio-keys"; -+ reset { -+ label = "reset"; -+ linux,code = ; -+ gpios = <&pio 1 GPIO_ACTIVE_LOW>; -+ }; -+ wps { -+ label = "wps"; -+ linux,code = ; -+ gpios = <&pio 0 GPIO_ACTIVE_HIGH>; -+ }; -+ }; -+}; -+ -+ð { -+ status = "okay"; -+ -+ gmac0: mac@0 { -+ compatible = "mediatek,eth-mac"; -+ reg = <0>; -+ phy-mode = "2500base-x"; -+ -+ fixed-link { -+ speed = <2500>; -+ full-duplex; -+ pause; -+ }; -+ }; -+ -+ gmac1: mac@1 { -+ compatible = "mediatek,eth-mac"; -+ reg = <1>; -+ phy-mode = "gmii"; -+ phy-handle = <&int_gbe_phy>; -+ }; -+}; -+ -+&mdio_bus { -+ switch: switch@1f { -+ compatible = "mediatek,mt7531"; -+ reg = <31>; -+ interrupt-controller; -+ #interrupt-cells = <1>; -+ interrupt-parent = <&pio>; -+ interrupts = <38 IRQ_TYPE_LEVEL_HIGH>; -+ reset-gpios = <&pio 5 GPIO_ACTIVE_HIGH>; -+ }; -+}; -+ -+&crypto { -+ status = "okay"; -+}; -+ -+&pio { -+ spi0_flash_pins: spi0-pins { -+ mux { -+ function = "spi"; -+ groups = "spi0", "spi0_wp_hold"; -+ }; -+ conf-pu { -+ pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP"; -+ drive-strength = ; -+ bias-pull-up = ; -+ }; -+ conf-pd { -+ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO"; -+ drive-strength = ; -+ bias-pull-down = ; -+ }; -+ }; -+ -+}; -+ -+&spi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_flash_pins>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+}; -+ -+&switch { -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ port@0 { -+ reg = <0>; -+ label = "lan1"; -+ }; -+ -+ port@1 { -+ reg = <1>; -+ label = "lan2"; -+ }; -+ -+ port@2 { -+ reg = <2>; -+ label = "lan3"; -+ }; -+ -+ port@3 { -+ reg = <3>; -+ label = "lan4"; -+ }; -+ -+ sw_p5: port@5 { -+ reg = <5>; -+ label = "lan5"; -+ status = "disabled"; -+ }; -+ -+ port@6 { -+ reg = <6>; -+ ethernet = <&gmac0>; -+ phy-mode = "2500base-x"; -+ -+ fixed-link { -+ speed = <2500>; -+ full-duplex; -+ pause; -+ }; -+ }; -+ }; -+}; -+ -+&xhci { -+ vusb33-supply = <®_3p3v>; -+ vbus-supply = <®_5v>; -+ status = "okay"; -+}; -+ -+&uart0 { -+ status = "okay"; -+}; -+ -+&usb_phy { -+ status = "okay"; -+}; -+ -+&watchdog { -+ status = "okay"; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-rfb-spim-nand.dts b/arch/arm64/boot/dts/mediatek/mt7986a-rfb-spim-nand.dts -new file mode 100644 -index 000000000000..479a5ca2fc4d ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7986a-rfb-spim-nand.dts -@@ -0,0 +1,52 @@ -+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ -+ -+#include "mt7986a-rfb.dtsi" -+ -+/ { -+ compatible = "mediatek,mt7986a-rfb-snand"; -+}; -+ -+&spi0 { -+ status = "okay"; -+ -+ spi_nand: spi_nand@1 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "spi-nand"; -+ reg = <1>; -+ spi-max-frequency = <10000000>; -+ spi-tx-bus-width = <4>; -+ spi-rx-bus-width = <4>; -+ -+ partitions { -+ compatible = "fixed-partitions"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ partition@0 { -+ label = "BL2"; -+ reg = <0x00000 0x0100000>; -+ read-only; -+ }; -+ partition@100000 { -+ label = "u-boot-env"; -+ reg = <0x0100000 0x0080000>; -+ }; -+ factory: partition@180000 { -+ label = "Factory"; -+ reg = <0x180000 0x0200000>; -+ }; -+ partition@380000 { -+ label = "FIP"; -+ reg = <0x380000 0x0200000>; -+ }; -+ partition@580000 { -+ label = "ubi"; -+ reg = <0x580000 0x4000000>; -+ }; -+ }; -+ }; -+}; -+ -+&wifi { -+ mediatek,mtd-eeprom = <&factory 0>; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-rfb-spim-nor.dts b/arch/arm64/boot/dts/mediatek/mt7986a-rfb-spim-nor.dts -new file mode 100644 -index 000000000000..ea148315f055 ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7986a-rfb-spim-nor.dts -@@ -0,0 +1,51 @@ -+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ -+ -+#include "mt7986a-rfb.dtsi" -+ -+/ { -+ compatible = "mediatek,mt7986a-rfb-snor"; -+}; -+ -+&spi0 { -+ status = "okay"; -+ -+ spi_nor: spi_nor@0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "jedec,spi-nor"; -+ reg = <0>; -+ spi-max-frequency = <52000000>; -+ spi-tx-bus-width = <4>; -+ spi-rx-bus-width = <4>; -+ partitions { -+ compatible = "fixed-partitions"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ partition@00000 { -+ label = "BL2"; -+ reg = <0x00000 0x0040000>; -+ }; -+ partition@40000 { -+ label = "u-boot-env"; -+ reg = <0x40000 0x0010000>; -+ }; -+ factory: partition@50000 { -+ label = "Factory"; -+ reg = <0x50000 0x00B0000>; -+ }; -+ partition@100000 { -+ label = "FIP"; -+ reg = <0x100000 0x0080000>; -+ }; -+ partition@180000 { -+ label = "firmware"; -+ reg = <0x180000 0xE00000>; -+ }; -+ }; -+ }; -+}; -+ -+&wifi { -+ mediatek,mtd-eeprom = <&factory 0>; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dtsi -new file mode 100644 -index 000000000000..1dfb64d4565e ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dtsi -@@ -0,0 +1,391 @@ -+// SPDX-License-Identifier: (GPL-2.0 OR MIT) -+/* -+ * Copyright (C) 2021 MediaTek Inc. -+ * Author: Sam.Shih -+ */ -+ -+/dts-v1/; -+#include -+#include -+#include "mt7986a.dtsi" -+ -+/ { -+ model = "MediaTek MT7986a RFB"; -+ compatible = "mediatek,mt7986a-rfb"; -+ -+ aliases { -+ serial0 = &uart0; -+ }; -+ -+ chosen { -+ stdout-path = "serial0:115200n8"; -+ }; -+ -+ memory@40000000 { -+ reg = <0 0x40000000 0 0x40000000>; -+ device_type = "memory"; -+ }; -+ -+ reg_1p8v: regulator-1p8v { -+ compatible = "regulator-fixed"; -+ regulator-name = "fixed-1.8V"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ reg_3p3v: regulator-3p3v { -+ compatible = "regulator-fixed"; -+ regulator-name = "fixed-3.3V"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ reg_5v: regulator-5v { -+ compatible = "regulator-fixed"; -+ regulator-name = "fixed-5V"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+}; -+ -+ð { -+ status = "okay"; -+ -+ gmac0: mac@0 { -+ compatible = "mediatek,eth-mac"; -+ reg = <0>; -+ phy-mode = "2500base-x"; -+ -+ fixed-link { -+ speed = <2500>; -+ full-duplex; -+ pause; -+ }; -+ }; -+ -+ gmac1: mac@1 { -+ compatible = "mediatek,eth-mac"; -+ reg = <1>; -+ phy-mode = "2500base-x"; -+ }; -+ -+ mdio: mdio-bus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+}; -+ -+&wifi { -+ status = "okay"; -+ pinctrl-names = "default", "dbdc"; -+ pinctrl-0 = <&wf_2g_5g_pins>; -+ pinctrl-1 = <&wf_dbdc_pins>; -+}; -+ -+&mdio { -+ phy5: phy@5 { -+ compatible = "ethernet-phy-id67c9.de0a"; -+ reg = <5>; -+ -+ reset-gpios = <&pio 6 GPIO_ACTIVE_LOW>; -+ reset-deassert-us = <20000>; -+ }; -+ -+ phy6: phy@6 { -+ compatible = "ethernet-phy-id67c9.de0a"; -+ reg = <6>; -+ }; -+ -+ switch: switch@1f { -+ compatible = "mediatek,mt7531"; -+ reg = <31>; -+ reset-gpios = <&pio 5 GPIO_ACTIVE_HIGH>; -+ }; -+}; -+ -+&crypto { -+ status = "okay"; -+}; -+ -+&mmc0 { -+ pinctrl-names = "default", "state_uhs"; -+ pinctrl-0 = <&mmc0_pins_default>; -+ pinctrl-1 = <&mmc0_pins_uhs>; -+ bus-width = <8>; -+ max-frequency = <200000000>; -+ cap-mmc-highspeed; -+ mmc-hs200-1_8v; -+ mmc-hs400-1_8v; -+ hs400-ds-delay = <0x14014>; -+ vmmc-supply = <®_3p3v>; -+ vqmmc-supply = <®_1p8v>; -+ non-removable; -+ no-sd; -+ no-sdio; -+ status = "okay"; -+}; -+ -+&pcie { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie_pins>; -+ status = "okay"; -+}; -+ -+&pcie_phy { -+ status = "okay"; -+}; -+ -+&pio { -+ mmc0_pins_default: mmc0-pins { -+ mux { -+ function = "emmc"; -+ groups = "emmc_51"; -+ }; -+ conf-cmd-dat { -+ pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2", -+ "EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5", -+ "EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD"; -+ input-enable; -+ drive-strength = ; -+ bias-pull-up = ; /* pull-up 10K */ -+ }; -+ conf-clk { -+ pins = "EMMC_CK"; -+ drive-strength = ; -+ bias-pull-down = ; /* pull-down 50K */ -+ }; -+ conf-ds { -+ pins = "EMMC_DSL"; -+ bias-pull-down = ; /* pull-down 50K */ -+ }; -+ conf-rst { -+ pins = "EMMC_RSTB"; -+ drive-strength = ; -+ bias-pull-up = ; /* pull-up 10K */ -+ }; -+ }; -+ -+ mmc0_pins_uhs: mmc0-uhs-pins { -+ mux { -+ function = "emmc"; -+ groups = "emmc_51"; -+ }; -+ conf-cmd-dat { -+ pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2", -+ "EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5", -+ "EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD"; -+ input-enable; -+ drive-strength = ; -+ bias-pull-up = ; /* pull-up 10K */ -+ }; -+ conf-clk { -+ pins = "EMMC_CK"; -+ drive-strength = ; -+ bias-pull-down = ; /* pull-down 50K */ -+ }; -+ conf-ds { -+ pins = "EMMC_DSL"; -+ bias-pull-down = ; /* pull-down 50K */ -+ }; -+ conf-rst { -+ pins = "EMMC_RSTB"; -+ drive-strength = ; -+ bias-pull-up = ; /* pull-up 10K */ -+ }; -+ }; -+ -+ pcie_pins: pcie-pins { -+ mux { -+ function = "pcie"; -+ groups = "pcie_clk", "pcie_wake", "pcie_pereset"; -+ }; -+ }; -+ -+ spic_pins_g2: spic-pins-29-to-32 { -+ mux { -+ function = "spi"; -+ groups = "spi1_2"; -+ }; -+ }; -+ -+ spi_flash_pins: spi-flash-pins-33-to-38 { -+ mux { -+ function = "spi"; -+ groups = "spi0", "spi0_wp_hold"; -+ }; -+ conf-pu { -+ pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP"; -+ drive-strength = ; -+ bias-disable; /* bias-disable */ -+ }; -+ conf-pd { -+ pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; -+ drive-strength = ; -+ bias-disable; /* bias-disable */ -+ }; -+ }; -+ -+ uart1_pins: uart1-pins { -+ mux { -+ function = "uart"; -+ groups = "uart1"; -+ }; -+ }; -+ -+ uart2_pins: uart2-pins { -+ mux { -+ function = "uart"; -+ groups = "uart2"; -+ }; -+ }; -+ -+ wf_2g_5g_pins: wf_2g_5g-pins { -+ mux { -+ function = "wifi"; -+ groups = "wf_2g", "wf_5g"; -+ }; -+ conf { -+ pins = "WF0_HB1", "WF0_HB2", "WF0_HB3", "WF0_HB4", -+ "WF0_HB0", "WF0_HB0_B", "WF0_HB5", "WF0_HB6", -+ "WF0_HB7", "WF0_HB8", "WF0_HB9", "WF0_HB10", -+ "WF0_TOP_CLK", "WF0_TOP_DATA", "WF1_HB1", -+ "WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0", -+ "WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8", -+ "WF1_TOP_CLK", "WF1_TOP_DATA"; -+ drive-strength = ; -+ }; -+ }; -+ -+ wf_dbdc_pins: wf_dbdc-pins { -+ mux { -+ function = "wifi"; -+ groups = "wf_dbdc"; -+ }; -+ conf { -+ pins = "WF0_HB1", "WF0_HB2", "WF0_HB3", "WF0_HB4", -+ "WF0_HB0", "WF0_HB0_B", "WF0_HB5", "WF0_HB6", -+ "WF0_HB7", "WF0_HB8", "WF0_HB9", "WF0_HB10", -+ "WF0_TOP_CLK", "WF0_TOP_DATA", "WF1_HB1", -+ "WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0", -+ "WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8", -+ "WF1_TOP_CLK", "WF1_TOP_DATA"; -+ drive-strength = ; -+ }; -+ }; -+}; -+ -+&spi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi_flash_pins>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+}; -+ -+&spi1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spic_pins_g2>; -+ status = "okay"; -+ -+ proslic_spi: proslic_spi@0 { -+ compatible = "silabs,proslic_spi"; -+ reg = <0>; -+ spi-max-frequency = <10000000>; -+ spi-cpha = <1>; -+ spi-cpol = <1>; -+ channel_count = <1>; -+ debug_level = <4>; /* 1 = TRC, 2 = DBG, 4 = ERR */ -+ reset-gpios = <&pio 7 GPIO_ACTIVE_HIGH>; -+ ig,enable-spi = <1>; /* 1: Enable, 0: Disable */ -+ }; -+}; -+ -+&gmac1 { -+ phy-mode = "2500base-x"; -+ phy-connection-type = "2500base-x"; -+ phy-handle = <&phy6>; -+}; -+ -+&switch { -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ port@0 { -+ reg = <0>; -+ label = "lan1"; -+ }; -+ -+ port@1 { -+ reg = <1>; -+ label = "lan2"; -+ }; -+ -+ port@2 { -+ reg = <2>; -+ label = "lan3"; -+ }; -+ -+ port@3 { -+ reg = <3>; -+ label = "lan4"; -+ }; -+ -+ port@4 { -+ reg = <4>; -+ label = "wan"; -+ }; -+ -+ port@5 { -+ reg = <5>; -+ label = "lan6"; -+ -+ phy-mode = "2500base-x"; -+ phy-handle = <&phy5>; -+ }; -+ -+ port@6 { -+ reg = <6>; -+ ethernet = <&gmac0>; -+ phy-mode = "2500base-x"; -+ -+ fixed-link { -+ speed = <2500>; -+ full-duplex; -+ pause; -+ }; -+ }; -+ }; -+}; -+ -+&ssusb { -+ vusb33-supply = <®_3p3v>; -+ vbus-supply = <®_5v>; -+ status = "okay"; -+}; -+ -+&uart0 { -+ status = "okay"; -+}; -+ -+&uart1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart1_pins>; -+ status = "okay"; -+}; -+ -+&uart2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart2_pins>; -+ status = "okay"; -+}; -+ -+&usb_phy { -+ status = "okay"; -+}; -diff --git a/arch/mips/fw/myloader/Makefile b/arch/mips/fw/myloader/Makefile -new file mode 100644 -index 000000000000..34acfd01cc0a ---- /dev/null -+++ b/arch/mips/fw/myloader/Makefile -@@ -0,0 +1,5 @@ -+# -+# Makefile for the Compex's MyLoader support on MIPS architecture -+# -+ -+lib-y += myloader.o -diff --git a/arch/mips/fw/myloader/myloader.c b/arch/mips/fw/myloader/myloader.c -new file mode 100644 -index 000000000000..a26f9ad3fdbf ---- /dev/null -+++ b/arch/mips/fw/myloader/myloader.c -@@ -0,0 +1,63 @@ -+/* -+ * Compex's MyLoader specific prom routines -+ * -+ * Copyright (C) 2007-2008 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#define SYS_PARAMS_ADDR KSEG1ADDR(0x80000800) -+#define BOARD_PARAMS_ADDR KSEG1ADDR(0x80000A00) -+#define PART_TABLE_ADDR KSEG1ADDR(0x80000C00) -+#define BOOT_PARAMS_ADDR KSEG1ADDR(0x80000E00) -+ -+static struct myloader_info myloader_info __initdata; -+static int myloader_found __initdata; -+ -+struct myloader_info * __init myloader_get_info(void) -+{ -+ struct mylo_system_params *sysp; -+ struct mylo_board_params *boardp; -+ struct mylo_partition_table *parts; -+ -+ if (myloader_found) -+ return &myloader_info; -+ -+ sysp = (struct mylo_system_params *)(SYS_PARAMS_ADDR); -+ boardp = (struct mylo_board_params *)(BOARD_PARAMS_ADDR); -+ parts = (struct mylo_partition_table *)(PART_TABLE_ADDR); -+ -+ printk(KERN_DEBUG "MyLoader: sysp=%08x, boardp=%08x, parts=%08x\n", -+ sysp->magic, boardp->magic, parts->magic); -+ -+ /* Check for some magic numbers */ -+ if (sysp->magic != MYLO_MAGIC_SYS_PARAMS || -+ boardp->magic != MYLO_MAGIC_BOARD_PARAMS || -+ le32_to_cpu(parts->magic) != MYLO_MAGIC_PARTITIONS) -+ return NULL; -+ -+ printk(KERN_DEBUG "MyLoader: id=%04x:%04x, sub_id=%04x:%04x\n", -+ sysp->vid, sysp->did, sysp->svid, sysp->sdid); -+ -+ myloader_info.vid = sysp->vid; -+ myloader_info.did = sysp->did; -+ myloader_info.svid = sysp->svid; -+ myloader_info.sdid = sysp->sdid; -+ -+ memcpy(myloader_info.macs, boardp->addr, sizeof(myloader_info.macs)); -+ -+ myloader_found = 1; -+ -+ return &myloader_info; -+} -diff --git a/drivers/bcma/fallback-sprom.c b/drivers/bcma/fallback-sprom.c -new file mode 100644 -index 000000000000..6932c3c8f574 ---- /dev/null -+++ b/drivers/bcma/fallback-sprom.c -@@ -0,0 +1,534 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * BCMA Fallback SPROM Driver -+ * -+ * Copyright (C) 2020 Álvaro Fernández Rojas -+ * Copyright (C) 2014 Jonas Gorski -+ * Copyright (C) 2008 Maxime Bizon -+ * Copyright (C) 2008 Florian Fainelli -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "fallback-sprom.h" -+ -+#define BCMA_FBS_MAX_SIZE 468 -+ -+/* SPROM Extraction */ -+#define SPOFF(offset) ((offset) / sizeof(u16)) -+ -+#define SPEX(_outvar, _offset, _mask, _shift) \ -+ out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift)) -+ -+#define SPEX32(_outvar, _offset, _mask, _shift) \ -+ out->_outvar = ((((u32)in[SPOFF((_offset)+2)] << 16 | \ -+ in[SPOFF(_offset)]) & (_mask)) >> (_shift)) -+ -+#define SPEX_ARRAY8(_field, _offset, _mask, _shift) \ -+ do { \ -+ SPEX(_field[0], _offset + 0, _mask, _shift); \ -+ SPEX(_field[1], _offset + 2, _mask, _shift); \ -+ SPEX(_field[2], _offset + 4, _mask, _shift); \ -+ SPEX(_field[3], _offset + 6, _mask, _shift); \ -+ SPEX(_field[4], _offset + 8, _mask, _shift); \ -+ SPEX(_field[5], _offset + 10, _mask, _shift); \ -+ SPEX(_field[6], _offset + 12, _mask, _shift); \ -+ SPEX(_field[7], _offset + 14, _mask, _shift); \ -+ } while (0) -+ -+struct bcma_fbs { -+ struct device *dev; -+ struct list_head list; -+ struct ssb_sprom sprom; -+ u32 pci_bus; -+ u32 pci_dev; -+ bool devid_override; -+}; -+ -+static DEFINE_SPINLOCK(bcma_fbs_lock); -+static struct list_head bcma_fbs_list = LIST_HEAD_INIT(bcma_fbs_list); -+ -+int bcma_get_fallback_sprom(struct bcma_bus *bus, struct ssb_sprom *out) -+{ -+ struct bcma_fbs *pos; -+ u32 pci_bus, pci_dev; -+ -+ if (bus->hosttype != BCMA_HOSTTYPE_PCI) -+ return -ENOENT; -+ -+ pci_bus = bus->host_pci->bus->number; -+ pci_dev = PCI_SLOT(bus->host_pci->devfn); -+ -+ list_for_each_entry(pos, &bcma_fbs_list, list) { -+ if (pos->pci_bus != pci_bus || -+ pos->pci_dev != pci_dev) -+ continue; -+ -+ if (pos->devid_override) -+ bus->host_pci->device = pos->sprom.dev_id; -+ -+ memcpy(out, &pos->sprom, sizeof(struct ssb_sprom)); -+ dev_info(pos->dev, "requested by [%x:%x]", -+ pos->pci_bus, pos->pci_dev); -+ -+ return 0; -+ } -+ -+ pr_err("unable to fill SPROM for [%x:%x]\n", pci_bus, pci_dev); -+ -+ return -EINVAL; -+} -+ -+static s8 sprom_extract_antgain(const u16 *in, u16 offset, u16 mask, u16 shift) -+{ -+ u16 v; -+ u8 gain; -+ -+ v = in[SPOFF(offset)]; -+ gain = (v & mask) >> shift; -+ if (gain == 0xFF) { -+ gain = 8; /* If unset use 2dBm */ -+ } else { -+ /* Q5.2 Fractional part is stored in 0xC0 */ -+ gain = ((gain & 0xC0) >> 6) | ((gain & 0x3F) << 2); -+ } -+ -+ return (s8)gain; -+} -+ -+static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in) -+{ -+ static const u16 pwr_info_offset[] = { -+ SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1, -+ SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3 -+ }; -+ u16 o; -+ int i; -+ -+ BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) != -+ ARRAY_SIZE(out->core_pwr_info)); -+ -+ SPEX(board_rev, SSB_SPROM8_BOARDREV, ~0, 0); -+ SPEX(board_type, SSB_SPROM1_SPID, ~0, 0); -+ -+ SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G0, -+ SSB_SPROM4_TXPID2G0_SHIFT); -+ SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G1, -+ SSB_SPROM4_TXPID2G1_SHIFT); -+ SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G2, -+ SSB_SPROM4_TXPID2G2_SHIFT); -+ SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G3, -+ SSB_SPROM4_TXPID2G3_SHIFT); -+ -+ SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL0, -+ SSB_SPROM4_TXPID5GL0_SHIFT); -+ SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL1, -+ SSB_SPROM4_TXPID5GL1_SHIFT); -+ SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL2, -+ SSB_SPROM4_TXPID5GL2_SHIFT); -+ SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL3, -+ SSB_SPROM4_TXPID5GL3_SHIFT); -+ -+ SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G0, -+ SSB_SPROM4_TXPID5G0_SHIFT); -+ SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G1, -+ SSB_SPROM4_TXPID5G1_SHIFT); -+ SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G2, -+ SSB_SPROM4_TXPID5G2_SHIFT); -+ SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G3, -+ SSB_SPROM4_TXPID5G3_SHIFT); -+ -+ SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH0, -+ SSB_SPROM4_TXPID5GH0_SHIFT); -+ SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH1, -+ SSB_SPROM4_TXPID5GH1_SHIFT); -+ SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH2, -+ SSB_SPROM4_TXPID5GH2_SHIFT); -+ SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH3, -+ SSB_SPROM4_TXPID5GH3_SHIFT); -+ -+ SPEX(boardflags_lo, SSB_SPROM8_BFLLO, ~0, 0); -+ SPEX(boardflags_hi, SSB_SPROM8_BFLHI, ~0, 0); -+ SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, ~0, 0); -+ SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, ~0, 0); -+ -+ SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8); -+ SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0); -+ -+ /* Extract core's power info */ -+ for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) { -+ o = pwr_info_offset[i]; -+ SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI, -+ SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT); -+ SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI, -+ SSB_SPROM8_2G_MAXP, 0); -+ -+ SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0); -+ SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0); -+ SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0); -+ -+ SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI, -+ SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT); -+ SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI, -+ SSB_SPROM8_5G_MAXP, 0); -+ SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP, -+ SSB_SPROM8_5GH_MAXP, 0); -+ SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP, -+ SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT); -+ -+ SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0); -+ } -+ -+ SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TSSIPOS, -+ SSB_SROM8_FEM_TSSIPOS_SHIFT); -+ SPEX(fem.ghz2.extpa_gain, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_EXTPA_GAIN, -+ SSB_SROM8_FEM_EXTPA_GAIN_SHIFT); -+ SPEX(fem.ghz2.pdet_range, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_PDET_RANGE, -+ SSB_SROM8_FEM_PDET_RANGE_SHIFT); -+ SPEX(fem.ghz2.tr_iso, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TR_ISO, -+ SSB_SROM8_FEM_TR_ISO_SHIFT); -+ SPEX(fem.ghz2.antswlut, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_ANTSWLUT, -+ SSB_SROM8_FEM_ANTSWLUT_SHIFT); -+ -+ SPEX(fem.ghz5.tssipos, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TSSIPOS, -+ SSB_SROM8_FEM_TSSIPOS_SHIFT); -+ SPEX(fem.ghz5.extpa_gain, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_EXTPA_GAIN, -+ SSB_SROM8_FEM_EXTPA_GAIN_SHIFT); -+ SPEX(fem.ghz5.pdet_range, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_PDET_RANGE, -+ SSB_SROM8_FEM_PDET_RANGE_SHIFT); -+ SPEX(fem.ghz5.tr_iso, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TR_ISO, -+ SSB_SROM8_FEM_TR_ISO_SHIFT); -+ SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_ANTSWLUT, -+ SSB_SROM8_FEM_ANTSWLUT_SHIFT); -+ -+ SPEX(ant_available_a, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_A, -+ SSB_SPROM8_ANTAVAIL_A_SHIFT); -+ SPEX(ant_available_bg, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_BG, -+ SSB_SPROM8_ANTAVAIL_BG_SHIFT); -+ SPEX(maxpwr_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_MAXP_BG_MASK, 0); -+ SPEX(itssi_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_ITSSI_BG, -+ SSB_SPROM8_ITSSI_BG_SHIFT); -+ SPEX(maxpwr_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_MAXP_A_MASK, 0); -+ SPEX(itssi_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_ITSSI_A, -+ SSB_SPROM8_ITSSI_A_SHIFT); -+ SPEX(maxpwr_ah, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AH_MASK, 0); -+ SPEX(maxpwr_al, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AL_MASK, -+ SSB_SPROM8_MAXP_AL_SHIFT); -+ SPEX(gpio0, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P0, 0); -+ SPEX(gpio1, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P1, -+ SSB_SPROM8_GPIOA_P1_SHIFT); -+ SPEX(gpio2, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P2, 0); -+ SPEX(gpio3, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P3, -+ SSB_SPROM8_GPIOB_P3_SHIFT); -+ SPEX(tri2g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI2G, 0); -+ SPEX(tri5g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI5G, -+ SSB_SPROM8_TRI5G_SHIFT); -+ SPEX(tri5gl, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GL, 0); -+ SPEX(tri5gh, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GH, -+ SSB_SPROM8_TRI5GH_SHIFT); -+ SPEX(rxpo2g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO2G, -+ SSB_SPROM8_RXPO2G_SHIFT); -+ SPEX(rxpo5g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO5G, -+ SSB_SPROM8_RXPO5G_SHIFT); -+ SPEX(rssismf2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMF2G, 0); -+ SPEX(rssismc2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMC2G, -+ SSB_SPROM8_RSSISMC2G_SHIFT); -+ SPEX(rssisav2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISAV2G, -+ SSB_SPROM8_RSSISAV2G_SHIFT); -+ SPEX(bxa2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_BXA2G, -+ SSB_SPROM8_BXA2G_SHIFT); -+ SPEX(rssismf5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMF5G, 0); -+ SPEX(rssismc5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMC5G, -+ SSB_SPROM8_RSSISMC5G_SHIFT); -+ SPEX(rssisav5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISAV5G, -+ SSB_SPROM8_RSSISAV5G_SHIFT); -+ SPEX(bxa5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_BXA5G, -+ SSB_SPROM8_BXA5G_SHIFT); -+ -+ SPEX(pa0b0, SSB_SPROM8_PA0B0, ~0, 0); -+ SPEX(pa0b1, SSB_SPROM8_PA0B1, ~0, 0); -+ SPEX(pa0b2, SSB_SPROM8_PA0B2, ~0, 0); -+ SPEX(pa1b0, SSB_SPROM8_PA1B0, ~0, 0); -+ SPEX(pa1b1, SSB_SPROM8_PA1B1, ~0, 0); -+ SPEX(pa1b2, SSB_SPROM8_PA1B2, ~0, 0); -+ SPEX(pa1lob0, SSB_SPROM8_PA1LOB0, ~0, 0); -+ SPEX(pa1lob1, SSB_SPROM8_PA1LOB1, ~0, 0); -+ SPEX(pa1lob2, SSB_SPROM8_PA1LOB2, ~0, 0); -+ SPEX(pa1hib0, SSB_SPROM8_PA1HIB0, ~0, 0); -+ SPEX(pa1hib1, SSB_SPROM8_PA1HIB1, ~0, 0); -+ SPEX(pa1hib2, SSB_SPROM8_PA1HIB2, ~0, 0); -+ SPEX(cck2gpo, SSB_SPROM8_CCK2GPO, ~0, 0); -+ SPEX32(ofdm2gpo, SSB_SPROM8_OFDM2GPO, ~0, 0); -+ SPEX32(ofdm5glpo, SSB_SPROM8_OFDM5GLPO, ~0, 0); -+ SPEX32(ofdm5gpo, SSB_SPROM8_OFDM5GPO, ~0, 0); -+ SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, ~0, 0); -+ -+ /* Extract the antenna gain values. */ -+ out->antenna_gain.a0 = sprom_extract_antgain(in, -+ SSB_SPROM8_AGAIN01, -+ SSB_SPROM8_AGAIN0, -+ SSB_SPROM8_AGAIN0_SHIFT); -+ out->antenna_gain.a1 = sprom_extract_antgain(in, -+ SSB_SPROM8_AGAIN01, -+ SSB_SPROM8_AGAIN1, -+ SSB_SPROM8_AGAIN1_SHIFT); -+ out->antenna_gain.a2 = sprom_extract_antgain(in, -+ SSB_SPROM8_AGAIN23, -+ SSB_SPROM8_AGAIN2, -+ SSB_SPROM8_AGAIN2_SHIFT); -+ out->antenna_gain.a3 = sprom_extract_antgain(in, -+ SSB_SPROM8_AGAIN23, -+ SSB_SPROM8_AGAIN3, -+ SSB_SPROM8_AGAIN3_SHIFT); -+ -+ SPEX(leddc_on_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_ON, -+ SSB_SPROM8_LEDDC_ON_SHIFT); -+ SPEX(leddc_off_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_OFF, -+ SSB_SPROM8_LEDDC_OFF_SHIFT); -+ -+ SPEX(txchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_TXCHAIN, -+ SSB_SPROM8_TXRXC_TXCHAIN_SHIFT); -+ SPEX(rxchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_RXCHAIN, -+ SSB_SPROM8_TXRXC_RXCHAIN_SHIFT); -+ SPEX(antswitch, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_SWITCH, -+ SSB_SPROM8_TXRXC_SWITCH_SHIFT); -+ -+ SPEX(opo, SSB_SPROM8_OFDM2GPO, 0x00ff, 0); -+ -+ SPEX_ARRAY8(mcs2gpo, SSB_SPROM8_2G_MCSPO, ~0, 0); -+ SPEX_ARRAY8(mcs5gpo, SSB_SPROM8_5G_MCSPO, ~0, 0); -+ SPEX_ARRAY8(mcs5glpo, SSB_SPROM8_5GL_MCSPO, ~0, 0); -+ SPEX_ARRAY8(mcs5ghpo, SSB_SPROM8_5GH_MCSPO, ~0, 0); -+ -+ SPEX(rawtempsense, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_RAWTEMP, -+ SSB_SPROM8_RAWTS_RAWTEMP_SHIFT); -+ SPEX(measpower, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_MEASPOWER, -+ SSB_SPROM8_RAWTS_MEASPOWER_SHIFT); -+ SPEX(tempsense_slope, SSB_SPROM8_OPT_CORRX, -+ SSB_SPROM8_OPT_CORRX_TEMP_SLOPE, -+ SSB_SPROM8_OPT_CORRX_TEMP_SLOPE_SHIFT); -+ SPEX(tempcorrx, SSB_SPROM8_OPT_CORRX, SSB_SPROM8_OPT_CORRX_TEMPCORRX, -+ SSB_SPROM8_OPT_CORRX_TEMPCORRX_SHIFT); -+ SPEX(tempsense_option, SSB_SPROM8_OPT_CORRX, -+ SSB_SPROM8_OPT_CORRX_TEMP_OPTION, -+ SSB_SPROM8_OPT_CORRX_TEMP_OPTION_SHIFT); -+ SPEX(freqoffset_corr, SSB_SPROM8_HWIQ_IQSWP, -+ SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR, -+ SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR_SHIFT); -+ SPEX(iqcal_swp_dis, SSB_SPROM8_HWIQ_IQSWP, -+ SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP, -+ SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP_SHIFT); -+ SPEX(hw_iqcal_en, SSB_SPROM8_HWIQ_IQSWP, SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL, -+ SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL_SHIFT); -+ -+ SPEX(bw40po, SSB_SPROM8_BW40PO, ~0, 0); -+ SPEX(cddpo, SSB_SPROM8_CDDPO, ~0, 0); -+ SPEX(stbcpo, SSB_SPROM8_STBCPO, ~0, 0); -+ SPEX(bwduppo, SSB_SPROM8_BWDUPPO, ~0, 0); -+ -+ SPEX(tempthresh, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_TRESH, -+ SSB_SPROM8_THERMAL_TRESH_SHIFT); -+ SPEX(tempoffset, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_OFFSET, -+ SSB_SPROM8_THERMAL_OFFSET_SHIFT); -+ SPEX(phycal_tempdelta, SSB_SPROM8_TEMPDELTA, -+ SSB_SPROM8_TEMPDELTA_PHYCAL, -+ SSB_SPROM8_TEMPDELTA_PHYCAL_SHIFT); -+ SPEX(temps_period, SSB_SPROM8_TEMPDELTA, SSB_SPROM8_TEMPDELTA_PERIOD, -+ SSB_SPROM8_TEMPDELTA_PERIOD_SHIFT); -+ SPEX(temps_hysteresis, SSB_SPROM8_TEMPDELTA, -+ SSB_SPROM8_TEMPDELTA_HYSTERESIS, -+ SSB_SPROM8_TEMPDELTA_HYSTERESIS_SHIFT); -+} -+ -+static int sprom_extract(struct bcma_fbs *priv, const u16 *in, u16 size) -+{ -+ struct ssb_sprom *out = &priv->sprom; -+ -+ memset(out, 0, sizeof(*out)); -+ -+ out->revision = in[size - 1] & 0x00FF; -+ if (out->revision < 8 || out->revision > 11) { -+ dev_warn(priv->dev, -+ "Unsupported SPROM revision %d detected." -+ " Will extract v8\n", -+ out->revision); -+ out->revision = 8; -+ } -+ -+ sprom_extract_r8(out, in); -+ -+ return 0; -+} -+ -+static void bcma_fbs_fixup(struct bcma_fbs *priv, u16 *sprom) -+{ -+ struct device_node *node = priv->dev->of_node; -+ u32 fixups, off, val; -+ int i = 0; -+ -+ if (!of_get_property(node, "brcm,sprom-fixups", &fixups)) -+ return; -+ -+ fixups /= sizeof(u32); -+ -+ dev_info(priv->dev, "patching SPROM with %u fixups...\n", fixups >> 1); -+ -+ while (i < fixups) { -+ if (of_property_read_u32_index(node, "brcm,sprom-fixups", -+ i++, &off)) { -+ dev_err(priv->dev, "error reading fixup[%u] offset\n", -+ i - 1); -+ return; -+ } -+ -+ if (of_property_read_u32_index(node, "brcm,sprom-fixups", -+ i++, &val)) { -+ dev_err(priv->dev, "error reading fixup[%u] value\n", -+ i - 1); -+ return; -+ } -+ -+ dev_dbg(priv->dev, "fixup[%d]=0x%04x\n", off, val); -+ -+ sprom[off] = val; -+ } -+} -+ -+static bool sprom_override_devid(struct bcma_fbs *priv, struct ssb_sprom *out, -+ const u16 *in) -+{ -+ SPEX(dev_id, 0x0060, 0xFFFF, 0); -+ return !!out->dev_id; -+} -+ -+static void bcma_fbs_set(struct bcma_fbs *priv, struct device_node *node) -+{ -+ struct ssb_sprom *sprom = &priv->sprom; -+ const struct firmware *fw; -+ const char *sprom_name; -+ int err; -+ -+ if (of_property_read_string(node, "brcm,sprom", &sprom_name)) -+ sprom_name = NULL; -+ -+ if (sprom_name) { -+ err = request_firmware_direct(&fw, sprom_name, priv->dev); -+ if (err) -+ dev_err(priv->dev, "%s load error\n", sprom_name); -+ } else { -+ err = -ENOENT; -+ } -+ -+ if (err) { -+ sprom->revision = 0x02; -+ sprom->board_rev = 0x0017; -+ sprom->country_code = 0x00; -+ sprom->ant_available_bg = 0x03; -+ sprom->pa0b0 = 0x15ae; -+ sprom->pa0b1 = 0xfa85; -+ sprom->pa0b2 = 0xfe8d; -+ sprom->pa1b0 = 0xffff; -+ sprom->pa1b1 = 0xffff; -+ sprom->pa1b2 = 0xffff; -+ sprom->gpio0 = 0xff; -+ sprom->gpio1 = 0xff; -+ sprom->gpio2 = 0xff; -+ sprom->gpio3 = 0xff; -+ sprom->maxpwr_bg = 0x4c; -+ sprom->itssi_bg = 0x00; -+ sprom->boardflags_lo = 0x2848; -+ sprom->boardflags_hi = 0x0000; -+ priv->devid_override = false; -+ -+ dev_warn(priv->dev, "using basic SPROM\n"); -+ } else { -+ size_t size = min(fw->size, (size_t) BCMA_FBS_MAX_SIZE); -+ u16 tmp_sprom[BCMA_FBS_MAX_SIZE >> 1]; -+ u32 i, j; -+ -+ for (i = 0, j = 0; i < size; i += 2, j++) -+ tmp_sprom[j] = (fw->data[i] << 8) | fw->data[i + 1]; -+ -+ release_firmware(fw); -+ bcma_fbs_fixup(priv, tmp_sprom); -+ sprom_extract(priv, tmp_sprom, size >> 1); -+ -+ priv->devid_override = sprom_override_devid(priv, sprom, -+ tmp_sprom); -+ } -+} -+ -+static int bcma_fbs_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct device_node *node = dev->of_node; -+ struct bcma_fbs *priv; -+ unsigned long flags; -+ u8 mac[ETH_ALEN]; -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->dev = dev; -+ -+ bcma_fbs_set(priv, node); -+ -+ of_property_read_u32(node, "pci-bus", &priv->pci_bus); -+ of_property_read_u32(node, "pci-dev", &priv->pci_dev); -+ -+ of_get_mac_address(node, mac); -+ if (is_valid_ether_addr(mac)) { -+ dev_info(dev, "mtd mac %pM\n", mac); -+ } else { -+ eth_random_addr(mac); -+ dev_info(dev, "random mac %pM\n", mac); -+ } -+ -+ memcpy(priv->sprom.il0mac, mac, ETH_ALEN); -+ memcpy(priv->sprom.et0mac, mac, ETH_ALEN); -+ memcpy(priv->sprom.et1mac, mac, ETH_ALEN); -+ memcpy(priv->sprom.et2mac, mac, ETH_ALEN); -+ -+ spin_lock_irqsave(&bcma_fbs_lock, flags); -+ list_add(&priv->list, &bcma_fbs_list); -+ spin_unlock_irqrestore(&bcma_fbs_lock, flags); -+ -+ dev_info(dev, "registered SPROM for [%x:%x]\n", -+ priv->pci_bus, priv->pci_dev); -+ -+ return 0; -+} -+ -+static const struct of_device_id bcma_fbs_of_match[] = { -+ { .compatible = "brcm,bcma-sprom", }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, bcma_fbs_of_match); -+ -+static struct platform_driver bcma_fbs_driver = { -+ .probe = bcma_fbs_probe, -+ .driver = { -+ .name = "bcma-sprom", -+ .of_match_table = bcma_fbs_of_match, -+ }, -+}; -+ -+int __init bcma_fbs_register(void) -+{ -+ return platform_driver_register(&bcma_fbs_driver); -+} -diff --git a/drivers/bcma/fallback-sprom.h b/drivers/bcma/fallback-sprom.h -new file mode 100644 -index 000000000000..363663413dc4 ---- /dev/null -+++ b/drivers/bcma/fallback-sprom.h -@@ -0,0 +1,7 @@ -+#ifndef _FALLBACK_SPROM_H -+#define _FALLBACK_SPROM_H -+ -+int __init bcma_fbs_register(void); -+int bcma_get_fallback_sprom(struct bcma_bus *dev, struct ssb_sprom *out); -+ -+#endif /* _FALLBACK_SPROM_H */ -diff --git a/drivers/leds/leds-smartrg-system.c b/drivers/leds/leds-smartrg-system.c -new file mode 100644 -index 000000000000..c1770aa81b59 ---- /dev/null -+++ b/drivers/leds/leds-smartrg-system.c -@@ -0,0 +1,225 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/** -+ * Driver for SmartRG RGBW LED microcontroller. -+ * RGBW LED is connected to a Holtek HT45F0062 that is on the I2C bus. -+ * -+ */ -+ -+struct srg_led_ctrl; -+struct srg_led { -+ u8 index; -+ struct led_classdev led; -+ struct srg_led_ctrl *ctrl; -+}; -+ -+struct srg_led_ctrl { -+ struct mutex lock; -+ struct i2c_client *client; -+ struct srg_led channel[4]; -+ u8 control[5]; -+}; -+ -+static int -+srg_led_i2c_write(struct srg_led_ctrl *sysled_ctrl, u8 reg, u8 value) -+{ -+ return i2c_smbus_write_byte_data(sysled_ctrl->client, reg, value); -+} -+ -+/* -+ * MC LED Command: 0 = OFF, 1 = ON, 2 = Flash, 3 = Pulse, 4 = Blink -+ * */ -+static int -+srg_led_control_sync(struct srg_led_ctrl *sysled_ctrl) -+{ -+ int i, ret; -+ -+ for (i = 1; i < 5; i++) { -+ ret = srg_led_i2c_write(sysled_ctrl, i, sysled_ctrl->control[i]); -+ if (ret) -+ break; -+ } -+ return ret; -+} -+ -+/* -+ * This function overrides the led driver timer trigger to offload -+ * flashing to the micro-controller. The negative effect of this -+ * is the inability to configure the delay_on and delay_off periods. -+ * -+ * */ -+static int -+srg_led_set_pulse(struct led_classdev *led_cdev, -+ unsigned long *delay_on, -+ unsigned long *delay_off) -+{ -+ struct srg_led *sysled = container_of(led_cdev, struct srg_led, led); -+ struct srg_led_ctrl *sysled_ctrl = sysled->ctrl; -+ bool blinking = false, pulsing = false; -+ u8 cbyte; -+ int ret; -+ -+ if (delay_on && delay_off && (*delay_on > 100) && (*delay_on <= 500)) { -+ pulsing = true; -+ *delay_on = 500; -+ *delay_off = 500; -+ } else if (delay_on && delay_off && (*delay_on >= 50) && (*delay_on <= 100)) { -+ blinking = true; -+ *delay_on = 50; -+ *delay_off = 50; -+ } -+ -+ cbyte = pulsing ? 3 : blinking ? 2 : 0; -+ mutex_lock(&sysled_ctrl->lock); -+ ret = srg_led_i2c_write(sysled_ctrl, sysled->index + 4, -+ (blinking || pulsing) ? 255 : 0); -+ if (!ret) { -+ sysled_ctrl->control[sysled->index] = cbyte; -+ ret = srg_led_control_sync(sysled_ctrl); -+ } -+ mutex_unlock(&sysled_ctrl->lock); -+ -+ return !cbyte; -+} -+ -+static int -+srg_led_set_brightness(struct led_classdev *led_cdev, -+ enum led_brightness value) -+{ -+ struct srg_led *sysled = container_of(led_cdev, struct srg_led, led); -+ struct srg_led_ctrl *sysled_ctrl = sysled->ctrl; -+ int ret; -+ -+ mutex_lock(&sysled_ctrl->lock); -+ ret = srg_led_i2c_write(sysled_ctrl, sysled->index + 4, value); -+ if (!ret) { -+ sysled_ctrl->control[sysled->index] = !!value; -+ ret = srg_led_control_sync(sysled_ctrl); -+ } -+ mutex_unlock(&sysled_ctrl->lock); -+ return ret; -+} -+ -+static int -+srg_led_init_led(struct srg_led_ctrl *sysled_ctrl, struct device_node *np) -+{ -+ struct led_init_data init_data = {}; -+ struct led_classdev *led_cdev; -+ struct srg_led *sysled; -+ int index, ret; -+ -+ if (!np) -+ return -ENOENT; -+ -+ ret = of_property_read_u32(np, "reg", &index); -+ if (ret) { -+ dev_err(&sysled_ctrl->client->dev, -+ "srg_led_init_led: no reg defined in np!\n"); -+ return ret; -+ } -+ -+ if (index < 1 || index > 4) -+ return -EINVAL; -+ -+ sysled = &sysled_ctrl->channel[index - 1]; -+ led_cdev = &sysled->led; -+ -+ sysled->index = index; -+ sysled->ctrl = sysled_ctrl; -+ -+ init_data.fwnode = of_fwnode_handle(np); -+ -+ led_cdev->name = of_get_property(np, "label", NULL) ? : np->name; -+ led_cdev->brightness = LED_OFF; -+ led_cdev->max_brightness = LED_FULL; -+ led_cdev->brightness_set_blocking = srg_led_set_brightness; -+ led_cdev->blink_set = srg_led_set_pulse; -+ -+ srg_led_i2c_write(sysled_ctrl, index + 4, 0); -+ -+ ret = devm_led_classdev_register_ext(&sysled_ctrl->client->dev, -+ led_cdev, &init_data); -+ if (ret) { -+ dev_err(&sysled_ctrl->client->dev, -+ "srg_led_init_led: led register %s error ret %d!n", -+ led_cdev->name, ret); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int -+ -+srg_led_probe(struct i2c_client *client) -+{ -+ struct device_node *np = client->dev.of_node, *child; -+ struct srg_led_ctrl *sysled_ctrl; -+ int err; -+ -+ sysled_ctrl = devm_kzalloc(&client->dev, sizeof(*sysled_ctrl), GFP_KERNEL); -+ if (!sysled_ctrl) -+ return -ENOMEM; -+ -+ sysled_ctrl->client = client; -+ -+ err = devm_mutex_init(&client->dev, &sysled_ctrl->lock); -+ if (err) -+ return err; -+ -+ i2c_set_clientdata(client, sysled_ctrl); -+ -+ for_each_available_child_of_node(np, child) { -+ if (srg_led_init_led(sysled_ctrl, child)) -+ continue; -+ -+ msleep(5); -+ } -+ -+ return srg_led_control_sync(sysled_ctrl);; -+} -+ -+static void srg_led_disable(struct i2c_client *client) -+{ -+ struct srg_led_ctrl *sysled_ctrl = i2c_get_clientdata(client); -+ int i; -+ -+ for (i = 1; i < 10; i++) -+ srg_led_i2c_write(sysled_ctrl, i, 0); -+} -+ -+static const struct i2c_device_id srg_led_id[] = { -+ { "srg-sysled", 0 }, -+ { } -+}; -+MODULE_DEVICE_TABLE(i2c, srg_led_id); -+ -+static const struct of_device_id of_srg_led_match[] = { -+ { .compatible = "srg,sysled", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, of_srg_led_match); -+ -+static struct i2c_driver srg_sysled_driver = { -+ .driver = { -+ .name = "srg-sysled", -+ .of_match_table = of_srg_led_match, -+ }, -+ .probe = srg_led_probe, -+ .remove = srg_led_disable, -+ .id_table = srg_led_id, -+}; -+module_i2c_driver(srg_sysled_driver); -+ -+MODULE_DESCRIPTION("SmartRG system LED driver"); -+MODULE_AUTHOR("Shen Loh "); -+MODULE_AUTHOR("Daniel Golle "); -+MODULE_LICENSE("GPL v2"); -diff --git a/drivers/mfd/airoha-an8855.c b/drivers/mfd/airoha-an8855.c -new file mode 100644 -index 000000000000..eeaea348aa41 ---- /dev/null -+++ b/drivers/mfd/airoha-an8855.c -@@ -0,0 +1,278 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * MFD driver for Airoha AN8855 Switch -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static const struct mfd_cell an8855_mfd_devs[] = { -+ { -+ .name = "an8855-efuse", -+ .of_compatible = "airoha,an8855-efuse", -+ }, { -+ .name = "an8855-switch", -+ .of_compatible = "airoha,an8855-switch", -+ }, { -+ .name = "an8855-mdio", -+ .of_compatible = "airoha,an8855-mdio", -+ } -+}; -+ -+int an8855_mii_set_page(struct an8855_mfd_priv *priv, u8 phy_id, -+ u8 page) __must_hold(&priv->bus->mdio_lock) -+{ -+ struct mii_bus *bus = priv->bus; -+ int ret; -+ -+ ret = __mdiobus_write(bus, phy_id, AN8855_PHY_SELECT_PAGE, page); -+ if (ret < 0) -+ dev_err_ratelimited(&bus->dev, -+ "failed to set an8855 mii page\n"); -+ -+ /* Cache current page if next mii read/write is for switch */ -+ priv->current_page = page; -+ return ret < 0 ? ret : 0; -+} -+EXPORT_SYMBOL_GPL(an8855_mii_set_page); -+ -+static int an8855_mii_read32(struct mii_bus *bus, u8 phy_id, u32 reg, -+ u32 *val) __must_hold(&bus->mdio_lock) -+{ -+ int lo, hi, ret; -+ -+ ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_MODE, -+ AN8855_PBUS_MODE_ADDR_FIXED); -+ if (ret < 0) -+ goto err; -+ -+ ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_RD_ADDR_HIGH, -+ upper_16_bits(reg)); -+ if (ret < 0) -+ goto err; -+ ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_RD_ADDR_LOW, -+ lower_16_bits(reg)); -+ if (ret < 0) -+ goto err; -+ -+ hi = __mdiobus_read(bus, phy_id, AN8855_PBUS_RD_DATA_HIGH); -+ if (hi < 0) { -+ ret = hi; -+ goto err; -+ } -+ lo = __mdiobus_read(bus, phy_id, AN8855_PBUS_RD_DATA_LOW); -+ if (lo < 0) { -+ ret = lo; -+ goto err; -+ } -+ -+ *val = ((u16)hi << 16) | ((u16)lo & 0xffff); -+ -+ return 0; -+err: -+ dev_err_ratelimited(&bus->dev, -+ "failed to read an8855 register\n"); -+ return ret; -+} -+ -+static int an8855_regmap_read(void *ctx, uint32_t reg, uint32_t *val) -+{ -+ struct an8855_mfd_priv *priv = ctx; -+ struct mii_bus *bus = priv->bus; -+ u16 addr = priv->switch_addr; -+ int ret; -+ -+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ ret = an8855_mii_set_page(priv, addr, AN8855_PHY_PAGE_EXTENDED_4); -+ if (ret < 0) -+ goto exit; -+ -+ ret = an8855_mii_read32(bus, addr, reg, val); -+ -+exit: -+ mutex_unlock(&bus->mdio_lock); -+ -+ return ret < 0 ? ret : 0; -+} -+ -+static int an8855_mii_write32(struct mii_bus *bus, u8 phy_id, u32 reg, -+ u32 val) __must_hold(&bus->mdio_lock) -+{ -+ int ret; -+ -+ ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_MODE, -+ AN8855_PBUS_MODE_ADDR_FIXED); -+ if (ret < 0) -+ goto err; -+ -+ ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_WR_ADDR_HIGH, -+ upper_16_bits(reg)); -+ if (ret < 0) -+ goto err; -+ ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_WR_ADDR_LOW, -+ lower_16_bits(reg)); -+ if (ret < 0) -+ goto err; -+ -+ ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_WR_DATA_HIGH, -+ upper_16_bits(val)); -+ if (ret < 0) -+ goto err; -+ ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_WR_DATA_LOW, -+ lower_16_bits(val)); -+ if (ret < 0) -+ goto err; -+ -+ return 0; -+err: -+ dev_err_ratelimited(&bus->dev, -+ "failed to write an8855 register\n"); -+ return ret; -+} -+ -+static int -+an8855_regmap_write(void *ctx, uint32_t reg, uint32_t val) -+{ -+ struct an8855_mfd_priv *priv = ctx; -+ struct mii_bus *bus = priv->bus; -+ u16 addr = priv->switch_addr; -+ int ret; -+ -+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ ret = an8855_mii_set_page(priv, addr, AN8855_PHY_PAGE_EXTENDED_4); -+ if (ret < 0) -+ goto exit; -+ -+ ret = an8855_mii_write32(bus, addr, reg, val); -+ -+exit: -+ mutex_unlock(&bus->mdio_lock); -+ -+ return ret < 0 ? ret : 0; -+} -+ -+static int an8855_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, -+ uint32_t write_val) -+{ -+ struct an8855_mfd_priv *priv = ctx; -+ struct mii_bus *bus = priv->bus; -+ u16 addr = priv->switch_addr; -+ u32 val; -+ int ret; -+ -+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ ret = an8855_mii_set_page(priv, addr, AN8855_PHY_PAGE_EXTENDED_4); -+ if (ret < 0) -+ goto exit; -+ -+ ret = an8855_mii_read32(bus, addr, reg, &val); -+ if (ret < 0) -+ goto exit; -+ -+ val &= ~mask; -+ val |= write_val; -+ ret = an8855_mii_write32(bus, addr, reg, val); -+ -+exit: -+ mutex_unlock(&bus->mdio_lock); -+ -+ return ret < 0 ? ret : 0; -+} -+ -+static const struct regmap_range an8855_readable_ranges[] = { -+ regmap_reg_range(0x10000000, 0x10000fff), /* SCU */ -+ regmap_reg_range(0x10001000, 0x10001fff), /* RBUS */ -+ regmap_reg_range(0x10002000, 0x10002fff), /* MCU */ -+ regmap_reg_range(0x10005000, 0x10005fff), /* SYS SCU */ -+ regmap_reg_range(0x10007000, 0x10007fff), /* I2C Slave */ -+ regmap_reg_range(0x10008000, 0x10008fff), /* I2C Master */ -+ regmap_reg_range(0x10009000, 0x10009fff), /* PDMA */ -+ regmap_reg_range(0x1000a100, 0x1000a2ff), /* General Purpose Timer */ -+ regmap_reg_range(0x1000a200, 0x1000a2ff), /* GPU timer */ -+ regmap_reg_range(0x1000a300, 0x1000a3ff), /* GPIO */ -+ regmap_reg_range(0x1000a400, 0x1000a5ff), /* EFUSE */ -+ regmap_reg_range(0x1000c000, 0x1000cfff), /* GDMP CSR */ -+ regmap_reg_range(0x10010000, 0x1001ffff), /* GDMP SRAM */ -+ regmap_reg_range(0x10200000, 0x10203fff), /* Switch - ARL Global */ -+ regmap_reg_range(0x10204000, 0x10207fff), /* Switch - BMU */ -+ regmap_reg_range(0x10208000, 0x1020bfff), /* Switch - ARL Port */ -+ regmap_reg_range(0x1020c000, 0x1020cfff), /* Switch - SCH */ -+ regmap_reg_range(0x10210000, 0x10213fff), /* Switch - MAC */ -+ regmap_reg_range(0x10214000, 0x10217fff), /* Switch - MIB */ -+ regmap_reg_range(0x10218000, 0x1021bfff), /* Switch - Port Control */ -+ regmap_reg_range(0x1021c000, 0x1021ffff), /* Switch - TOP */ -+ regmap_reg_range(0x10220000, 0x1022ffff), /* SerDes */ -+ regmap_reg_range(0x10286000, 0x10286fff), /* RG Batcher */ -+ regmap_reg_range(0x1028c000, 0x1028ffff), /* ETHER_SYS */ -+ regmap_reg_range(0x30000000, 0x37ffffff), /* I2C EEPROM */ -+ regmap_reg_range(0x38000000, 0x3fffffff), /* BOOT_ROM */ -+ regmap_reg_range(0xa0000000, 0xbfffffff), /* GPHY */ -+}; -+ -+static const struct regmap_access_table an8855_readable_table = { -+ .yes_ranges = an8855_readable_ranges, -+ .n_yes_ranges = ARRAY_SIZE(an8855_readable_ranges), -+}; -+ -+static const struct regmap_config an8855_regmap_config = { -+ .reg_bits = 32, -+ .val_bits = 32, -+ .reg_stride = 4, -+ .max_register = 0xbfffffff, -+ .reg_read = an8855_regmap_read, -+ .reg_write = an8855_regmap_write, -+ .reg_update_bits = an8855_regmap_update_bits, -+ .disable_locking = true, -+ .rd_table = &an8855_readable_table, -+}; -+ -+static int an8855_mfd_probe(struct mdio_device *mdiodev) -+{ -+ struct an8855_mfd_priv *priv; -+ struct regmap *regmap; -+ -+ priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->bus = mdiodev->bus; -+ priv->dev = &mdiodev->dev; -+ priv->switch_addr = mdiodev->addr; -+ /* no DMA for mdiobus, mute warning for DMA mask not set */ -+ priv->dev->dma_mask = &priv->dev->coherent_dma_mask; -+ -+ regmap = devm_regmap_init(priv->dev, NULL, priv, -+ &an8855_regmap_config); -+ if (IS_ERR(regmap)) -+ dev_err_probe(priv->dev, PTR_ERR(priv->dev), -+ "regmap initialization failed\n"); -+ -+ dev_set_drvdata(&mdiodev->dev, priv); -+ -+ return devm_mfd_add_devices(priv->dev, PLATFORM_DEVID_AUTO, an8855_mfd_devs, -+ ARRAY_SIZE(an8855_mfd_devs), NULL, 0, -+ NULL); -+} -+ -+static const struct of_device_id an8855_mfd_of_match[] = { -+ { .compatible = "airoha,an8855-mfd" }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, an8855_mfd_of_match); -+ -+static struct mdio_driver an8855_mfd_driver = { -+ .probe = an8855_mfd_probe, -+ .mdiodrv.driver = { -+ .name = "an8855", -+ .of_match_table = an8855_mfd_of_match, -+ }, -+}; -+mdio_module_driver(an8855_mfd_driver); -+ -+MODULE_AUTHOR("Christian Marangi "); -+MODULE_DESCRIPTION("Driver for Airoha AN8855 MFD"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/mtd/mtdsplit/Kconfig b/drivers/mtd/mtdsplit/Kconfig -new file mode 100644 -index 000000000000..396becf160cf ---- /dev/null -+++ b/drivers/mtd/mtdsplit/Kconfig -@@ -0,0 +1,117 @@ -+config MTD_SPLIT -+ def_bool n -+ help -+ Generic MTD split support. -+ -+config MTD_SPLIT_SUPPORT -+ def_bool MTD = y -+ -+comment "Rootfs partition parsers" -+ -+config MTD_SPLIT_SQUASHFS_ROOT -+ bool "Squashfs based root partition parser" -+ depends on MTD_SPLIT_SUPPORT -+ select MTD_SPLIT -+ help -+ This provides a parsing function which allows to detect the -+ offset and size of the unused portion of a rootfs partition -+ containing a squashfs. -+ -+comment "Firmware partition parsers" -+ -+config MTD_SPLIT_BCM63XX_FW -+ bool "BCM63xx firmware parser" -+ depends on MTD_SPLIT_SUPPORT -+ select MTD_SPLIT -+ -+config MTD_SPLIT_BCM_WFI_FW -+ bool "Broadcom Whole Flash Image parser" -+ depends on MTD_SPLIT_SUPPORT -+ select MTD_SPLIT -+ -+config MTD_SPLIT_CFE_BOOTFS -+ bool "Parser finding rootfs appended to the CFE bootfs" -+ depends on MTD_SPLIT_SUPPORT && (ARCH_BCM4908 || ARCH_BCMBCA) -+ select MTD_SPLIT -+ help -+ cferom on BCM4908 (and bcm63xx) uses JFFS2 bootfs partition -+ for storing kernel, cferam and some device specific files. -+ There isn't any straight way of storing rootfs so it gets -+ appended to the JFFS2 bootfs partition. Kernel needs to find -+ it and run init from it. This parser is responsible for -+ finding appended rootfs. -+ -+config MTD_SPLIT_SEAMA_FW -+ bool "Seama firmware parser" -+ depends on MTD_SPLIT_SUPPORT -+ select MTD_SPLIT -+ -+config MTD_SPLIT_WRGG_FW -+ bool "WRGG firmware parser" -+ depends on MTD_SPLIT_SUPPORT -+ select MTD_SPLIT -+ -+config MTD_SPLIT_UIMAGE_FW -+ bool "uImage based firmware partition parser" -+ depends on MTD_SPLIT_SUPPORT -+ select MTD_SPLIT -+ -+config MTD_SPLIT_FIT_FW -+ bool "FIT based firmware partition parser" -+ depends on MTD_SPLIT_SUPPORT -+ select MTD_SPLIT -+ -+config MTD_SPLIT_LZMA_FW -+ bool "LZMA compressed kernel based firmware partition parser" -+ depends on MTD_SPLIT_SUPPORT -+ select MTD_SPLIT -+ -+config MTD_SPLIT_TPLINK_FW -+ bool "TP-Link firmware parser" -+ depends on MTD_SPLIT_SUPPORT -+ select MTD_SPLIT -+ -+config MTD_SPLIT_TRX_FW -+ bool "TRX image based firmware partition parser" -+ depends on MTD_SPLIT_SUPPORT -+ select MTD_SPLIT -+ -+config MTD_SPLIT_BRNIMAGE_FW -+ bool "brnImage (brnboot image) firmware parser" -+ depends on MTD_SPLIT_SUPPORT -+ select MTD_SPLIT -+ -+config MTD_SPLIT_EVA_FW -+ bool "EVA image based firmware partition parser" -+ depends on MTD_SPLIT_SUPPORT -+ select MTD_SPLIT -+ -+config MTD_SPLIT_MINOR_FW -+ bool "Mikrotik NOR image based firmware partition parser" -+ depends on MTD_SPLIT_SUPPORT -+ select MTD_SPLIT -+ -+config MTD_SPLIT_JIMAGE_FW -+ bool "JBOOT Image based firmware partition parser" -+ depends on MTD_SPLIT_SUPPORT -+ select MTD_SPLIT -+ -+config MTD_SPLIT_ELF_FW -+ bool "ELF loader firmware partition parser" -+ depends on MTD_SPLIT_SUPPORT -+ select MTD_SPLIT -+ -+config MTD_SPLIT_H3C_VFS -+ bool "Parser finding rootfs appended to H3C VFS" -+ depends on MTD_SPLIT_SUPPORT -+ select MTD_SPLIT -+ -+config MTD_SPLIT_SEIL_FW -+ bool "IIJ SEIL firmware parser" -+ depends on MTD_SPLIT_SUPPORT -+ select MTD_SPLIT -+ -+config MTD_SPLIT_MSTC_BOOT -+ bool "MSTC bootnum-based parser" -+ depends on MTD_SPLIT_SUPPORT -+ select MTD_SPLIT -diff --git a/drivers/mtd/mtdsplit/Makefile b/drivers/mtd/mtdsplit/Makefile -new file mode 100644 -index 000000000000..b85ce5d21f3b ---- /dev/null -+++ b/drivers/mtd/mtdsplit/Makefile -@@ -0,0 +1,20 @@ -+obj-$(CONFIG_MTD_SPLIT) += mtdsplit.o -+obj-$(CONFIG_MTD_SPLIT_BCM63XX_FW) += mtdsplit_bcm63xx.o -+obj-$(CONFIG_MTD_SPLIT_BCM_WFI_FW) += mtdsplit_bcm_wfi.o -+obj-$(CONFIG_MTD_SPLIT_CFE_BOOTFS) += mtdsplit_cfe_bootfs.o -+obj-$(CONFIG_MTD_SPLIT_SEAMA_FW) += mtdsplit_seama.o -+obj-$(CONFIG_MTD_SPLIT_SEIL_FW) += mtdsplit_seil.o -+obj-$(CONFIG_MTD_SPLIT_SQUASHFS_ROOT) += mtdsplit_squashfs.o -+obj-$(CONFIG_MTD_SPLIT_UIMAGE_FW) += mtdsplit_uimage.o -+obj-$(CONFIG_MTD_SPLIT_FIT_FW) += mtdsplit_fit.o -+obj-$(CONFIG_MTD_SPLIT_LZMA_FW) += mtdsplit_lzma.o -+obj-$(CONFIG_MTD_SPLIT_TPLINK_FW) += mtdsplit_tplink.o -+obj-$(CONFIG_MTD_SPLIT_TRX_FW) += mtdsplit_trx.o -+obj-$(CONFIG_MTD_SPLIT_BRNIMAGE_FW) += mtdsplit_brnimage.o -+obj-$(CONFIG_MTD_SPLIT_EVA_FW) += mtdsplit_eva.o -+obj-$(CONFIG_MTD_SPLIT_WRGG_FW) += mtdsplit_wrgg.o -+obj-$(CONFIG_MTD_SPLIT_MINOR_FW) += mtdsplit_minor.o -+obj-$(CONFIG_MTD_SPLIT_JIMAGE_FW) += mtdsplit_jimage.o -+obj-$(CONFIG_MTD_SPLIT_ELF_FW) += mtdsplit_elf.o -+obj-$(CONFIG_MTD_SPLIT_H3C_VFS) += mtdsplit_h3c_vfs.o -+obj-$(CONFIG_MTD_SPLIT_MSTC_BOOT) += mtdsplit_mstc_boot.o -diff --git a/drivers/mtd/mtdsplit/mtdsplit.c b/drivers/mtd/mtdsplit/mtdsplit.c -new file mode 100644 -index 000000000000..b2e51dcfc66b ---- /dev/null -+++ b/drivers/mtd/mtdsplit/mtdsplit.c -@@ -0,0 +1,130 @@ -+/* -+ * Copyright (C) 2009-2013 Felix Fietkau -+ * Copyright (C) 2009-2013 Gabor Juhos -+ * Copyright (C) 2012 Jonas Gorski -+ * Copyright (C) 2013 Hauke Mehrtens -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+ -+#define pr_fmt(fmt) "mtdsplit: " fmt -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mtdsplit.h" -+ -+#define UBI_EC_MAGIC 0x55424923 /* UBI# */ -+ -+struct squashfs_super_block { -+ __le32 s_magic; -+ __le32 pad0[9]; -+ __le64 bytes_used; -+}; -+ -+int mtd_get_squashfs_len(struct mtd_info *master, -+ size_t offset, -+ size_t *squashfs_len) -+{ -+ struct squashfs_super_block sb; -+ size_t retlen; -+ int err; -+ -+ err = mtd_read(master, offset, sizeof(sb), &retlen, (void *)&sb); -+ if (err || (retlen != sizeof(sb))) { -+ pr_alert("error occured while reading from \"%s\"\n", -+ master->name); -+ return -EIO; -+ } -+ -+ if (le32_to_cpu(sb.s_magic) != SQUASHFS_MAGIC) { -+ pr_alert("no squashfs found in \"%s\"\n", master->name); -+ return -EINVAL; -+ } -+ -+ retlen = le64_to_cpu(sb.bytes_used); -+ if (retlen <= 0) { -+ pr_alert("squashfs is empty in \"%s\"\n", master->name); -+ return -ENODEV; -+ } -+ -+ if (offset + retlen > master->size) { -+ pr_alert("squashfs has invalid size in \"%s\"\n", -+ master->name); -+ return -EINVAL; -+ } -+ -+ *squashfs_len = retlen; -+ return 0; -+} -+EXPORT_SYMBOL_GPL(mtd_get_squashfs_len); -+ -+static ssize_t mtd_next_eb(struct mtd_info *mtd, size_t offset) -+{ -+ return mtd_rounddown_to_eb(offset, mtd) + mtd->erasesize; -+} -+ -+int mtd_check_rootfs_magic(struct mtd_info *mtd, size_t offset, -+ enum mtdsplit_part_type *type) -+{ -+ u32 magic; -+ size_t retlen; -+ int ret; -+ -+ ret = mtd_read(mtd, offset, sizeof(magic), &retlen, -+ (unsigned char *) &magic); -+ if (ret) -+ return ret; -+ -+ if (retlen != sizeof(magic)) -+ return -EIO; -+ -+ if (le32_to_cpu(magic) == SQUASHFS_MAGIC) { -+ if (type) -+ *type = MTDSPLIT_PART_TYPE_SQUASHFS; -+ return 0; -+ } else if (magic == 0x19852003) { -+ if (type) -+ *type = MTDSPLIT_PART_TYPE_JFFS2; -+ return 0; -+ } else if (be32_to_cpu(magic) == UBI_EC_MAGIC) { -+ if (type) -+ *type = MTDSPLIT_PART_TYPE_UBI; -+ return 0; -+ } -+ -+ return -EINVAL; -+} -+EXPORT_SYMBOL_GPL(mtd_check_rootfs_magic); -+ -+int mtd_find_rootfs_from(struct mtd_info *mtd, -+ size_t from, -+ size_t limit, -+ size_t *ret_offset, -+ enum mtdsplit_part_type *type) -+{ -+ size_t offset; -+ int err; -+ -+ for (offset = from; offset < limit; -+ offset = mtd_next_eb(mtd, offset)) { -+ err = mtd_check_rootfs_magic(mtd, offset, type); -+ if (err) -+ continue; -+ -+ *ret_offset = offset; -+ return 0; -+ } -+ -+ return -ENODEV; -+} -+EXPORT_SYMBOL_GPL(mtd_find_rootfs_from); -+ -diff --git a/drivers/mtd/mtdsplit/mtdsplit.h b/drivers/mtd/mtdsplit/mtdsplit.h -new file mode 100644 -index 000000000000..71d62a8956b2 ---- /dev/null -+++ b/drivers/mtd/mtdsplit/mtdsplit.h -@@ -0,0 +1,67 @@ -+/* -+ * Copyright (C) 2009-2013 Felix Fietkau -+ * Copyright (C) 2009-2013 Gabor Juhos -+ * Copyright (C) 2012 Jonas Gorski -+ * Copyright (C) 2013 Hauke Mehrtens -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+ -+#ifndef _MTDSPLIT_H -+#define _MTDSPLIT_H -+ -+#define KERNEL_PART_NAME "kernel" -+#define ROOTFS_PART_NAME "rootfs" -+#define UBI_PART_NAME "ubi" -+ -+#define ROOTFS_SPLIT_NAME "rootfs_data" -+ -+enum mtdsplit_part_type { -+ MTDSPLIT_PART_TYPE_UNK = 0, -+ MTDSPLIT_PART_TYPE_SQUASHFS, -+ MTDSPLIT_PART_TYPE_JFFS2, -+ MTDSPLIT_PART_TYPE_UBI, -+}; -+ -+#ifdef CONFIG_MTD_SPLIT -+int mtd_get_squashfs_len(struct mtd_info *master, -+ size_t offset, -+ size_t *squashfs_len); -+ -+int mtd_check_rootfs_magic(struct mtd_info *mtd, size_t offset, -+ enum mtdsplit_part_type *type); -+ -+int mtd_find_rootfs_from(struct mtd_info *mtd, -+ size_t from, -+ size_t limit, -+ size_t *ret_offset, -+ enum mtdsplit_part_type *type); -+ -+#else -+static inline int mtd_get_squashfs_len(struct mtd_info *master, -+ size_t offset, -+ size_t *squashfs_len) -+{ -+ return -ENODEV; -+} -+ -+static inline int mtd_check_rootfs_magic(struct mtd_info *mtd, size_t offset, -+ enum mtdsplit_part_type *type) -+{ -+ return -EINVAL; -+} -+ -+static inline int mtd_find_rootfs_from(struct mtd_info *mtd, -+ size_t from, -+ size_t limit, -+ size_t *ret_offset, -+ enum mtdsplit_part_type *type) -+{ -+ return -ENODEV; -+} -+#endif /* CONFIG_MTD_SPLIT */ -+ -+#endif /* _MTDSPLIT_H */ -diff --git a/drivers/mtd/mtdsplit/mtdsplit_bcm63xx.c b/drivers/mtd/mtdsplit/mtdsplit_bcm63xx.c -new file mode 100644 -index 000000000000..3a4b8a754fde ---- /dev/null -+++ b/drivers/mtd/mtdsplit/mtdsplit_bcm63xx.c -@@ -0,0 +1,186 @@ -+/* -+ * Firmware MTD split for BCM63XX, based on bcm63xxpart.c -+ * -+ * Copyright (C) 2006-2008 Florian Fainelli -+ * Copyright (C) 2006-2008 Mike Albon -+ * Copyright (C) 2009-2010 Daniel Dickinson -+ * Copyright (C) 2011-2013 Jonas Gorski -+ * Copyright (C) 2015 Simon Arlott -+ * Copyright (C) 2017 Álvaro Fernández Rojas -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+ -+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mtdsplit.h" -+ -+/* Ensure strings read from flash structs are null terminated */ -+#define STR_NULL_TERMINATE(x) \ -+ do { char *_str = (x); _str[sizeof(x) - 1] = 0; } while (0) -+ -+#define BCM63XX_NR_PARTS 2 -+ -+static int bcm63xx_read_image_tag(struct mtd_info *master, loff_t offset, -+ struct bcm_tag *hdr) -+{ -+ int ret; -+ size_t retlen; -+ u32 computed_crc; -+ -+ ret = mtd_read(master, offset, sizeof(*hdr), &retlen, (void *) hdr); -+ if (ret) -+ return ret; -+ -+ if (retlen != sizeof(*hdr)) -+ return -EIO; -+ -+ computed_crc = crc32_le(IMAGETAG_CRC_START, (u8 *)hdr, -+ offsetof(struct bcm_tag, header_crc)); -+ if (computed_crc == hdr->header_crc) { -+ STR_NULL_TERMINATE(hdr->board_id); -+ STR_NULL_TERMINATE(hdr->tag_version); -+ -+ pr_info("CFE image tag found at 0x%llx with version %s, " -+ "board type %s\n", offset, hdr->tag_version, -+ hdr->board_id); -+ -+ return 0; -+ } else { -+ pr_err("CFE image tag at 0x%llx CRC invalid " -+ "(expected %08x, actual %08x)\n", -+ offset, hdr->header_crc, computed_crc); -+ -+ return 1; -+ } -+} -+ -+static int bcm63xx_parse_partitions(struct mtd_info *master, -+ const struct mtd_partition **pparts, -+ struct bcm_tag *hdr) -+{ -+ struct mtd_partition *parts; -+ unsigned int flash_image_start; -+ unsigned int kernel_address; -+ unsigned int kernel_length; -+ size_t kernel_offset = 0, kernel_size = 0; -+ size_t rootfs_offset = 0, rootfs_size = 0; -+ int kernel_part, rootfs_part; -+ -+ STR_NULL_TERMINATE(hdr->flash_image_start); -+ if (kstrtouint(hdr->flash_image_start, 10, &flash_image_start) || -+ flash_image_start < BCM963XX_EXTENDED_SIZE) { -+ pr_err("invalid rootfs address: %*ph\n", -+ (int) sizeof(hdr->flash_image_start), -+ hdr->flash_image_start); -+ return -EINVAL; -+ } -+ -+ STR_NULL_TERMINATE(hdr->kernel_address); -+ if (kstrtouint(hdr->kernel_address, 10, &kernel_address) || -+ kernel_address < BCM963XX_EXTENDED_SIZE) { -+ pr_err("invalid kernel address: %*ph\n", -+ (int) sizeof(hdr->kernel_address), hdr->kernel_address); -+ return -EINVAL; -+ } -+ -+ STR_NULL_TERMINATE(hdr->kernel_length); -+ if (kstrtouint(hdr->kernel_length, 10, &kernel_length) || -+ !kernel_length) { -+ pr_err("invalid kernel length: %*ph\n", -+ (int) sizeof(hdr->kernel_length), hdr->kernel_length); -+ return -EINVAL; -+ } -+ -+ kernel_offset = kernel_address - BCM963XX_EXTENDED_SIZE - -+ mtdpart_get_offset(master); -+ kernel_size = kernel_length; -+ -+ if (flash_image_start < kernel_address) { -+ /* rootfs first */ -+ rootfs_part = 0; -+ kernel_part = 1; -+ rootfs_offset = flash_image_start - BCM963XX_EXTENDED_SIZE - -+ mtdpart_get_offset(master); -+ rootfs_size = kernel_offset - rootfs_offset; -+ } else { -+ /* kernel first */ -+ kernel_part = 0; -+ rootfs_part = 1; -+ rootfs_offset = kernel_offset + kernel_size; -+ rootfs_size = master->size - rootfs_offset; -+ } -+ -+ if (mtd_check_rootfs_magic(master, rootfs_offset, NULL)) -+ pr_warn("rootfs magic not found\n"); -+ -+ parts = kzalloc(BCM63XX_NR_PARTS * sizeof(*parts), GFP_KERNEL); -+ if (!parts) -+ return -ENOMEM; -+ -+ parts[kernel_part].name = KERNEL_PART_NAME; -+ parts[kernel_part].offset = kernel_offset; -+ parts[kernel_part].size = kernel_size; -+ -+ parts[rootfs_part].name = ROOTFS_PART_NAME; -+ parts[rootfs_part].offset = rootfs_offset; -+ parts[rootfs_part].size = rootfs_size; -+ -+ *pparts = parts; -+ return BCM63XX_NR_PARTS; -+} -+ -+static int mtdsplit_parse_bcm63xx(struct mtd_info *master, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct bcm_tag hdr; -+ loff_t offset; -+ -+ if (mtd_type_is_nand(master)) -+ return -EINVAL; -+ -+ /* find bcm63xx_cfe image on erase block boundaries */ -+ for (offset = 0; offset < master->size; offset += master->erasesize) { -+ if (!bcm63xx_read_image_tag(master, offset, (void *) &hdr)) -+ return bcm63xx_parse_partitions(master, pparts, -+ (void *) &hdr); -+ } -+ -+ return -EINVAL; -+} -+ -+static const struct of_device_id mtdsplit_fit_of_match_table[] = { -+ { .compatible = "brcm,bcm963xx-imagetag" }, -+ { }, -+}; -+ -+static struct mtd_part_parser mtdsplit_bcm63xx_parser = { -+ .owner = THIS_MODULE, -+ .name = "bcm63xx-fw", -+ .of_match_table = mtdsplit_fit_of_match_table, -+ .parse_fn = mtdsplit_parse_bcm63xx, -+ .type = MTD_PARSER_TYPE_FIRMWARE, -+}; -+ -+static int __init mtdsplit_bcm63xx_init(void) -+{ -+ register_mtd_parser(&mtdsplit_bcm63xx_parser); -+ -+ return 0; -+} -+ -+module_init(mtdsplit_bcm63xx_init); -diff --git a/drivers/mtd/mtdsplit/mtdsplit_bcm_wfi.c b/drivers/mtd/mtdsplit/mtdsplit_bcm_wfi.c -new file mode 100644 -index 000000000000..1cafc91fded3 ---- /dev/null -+++ b/drivers/mtd/mtdsplit/mtdsplit_bcm_wfi.c -@@ -0,0 +1,535 @@ -+/* -+ * MTD split for Broadcom Whole Flash Image -+ * -+ * Copyright (C) 2020 Álvaro Fernández Rojas -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+ -+#define je16_to_cpu(x) ((x).v16) -+#define je32_to_cpu(x) ((x).v32) -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mtdsplit.h" -+ -+#define char_to_num(c) ((c >= '0' && c <= '9') ? (c - '0') : (0)) -+ -+#define BCM_WFI_PARTS 3 -+#define BCM_WFI_SPLIT_PARTS 2 -+ -+#define CFERAM_NAME "cferam" -+#define CFERAM_NAME_LEN (sizeof(CFERAM_NAME) - 1) -+#define CFERAM_NAME_MAX_LEN 32 -+#define KERNEL_NAME "vmlinux.lz" -+#define KERNEL_NAME_LEN (sizeof(KERNEL_NAME) - 1) -+#define OPENWRT_NAME "1-openwrt" -+#define OPENWRT_NAME_LEN (sizeof(OPENWRT_NAME) - 1) -+ -+#define UBI_MAGIC 0x55424923 -+ -+#define CFE_MAGIC_PFX "cferam." -+#define CFE_MAGIC_PFX_LEN (sizeof(CFE_MAGIC_PFX) - 1) -+#define CFE_MAGIC "cferam.000" -+#define CFE_MAGIC_LEN (sizeof(CFE_MAGIC) - 1) -+#define SERCOMM_MAGIC_PFX "eRcOmM." -+#define SERCOMM_MAGIC_PFX_LEN (sizeof(SERCOMM_MAGIC_PFX) - 1) -+#define SERCOMM_MAGIC "eRcOmM.000" -+#define SERCOMM_MAGIC_LEN (sizeof(SERCOMM_MAGIC) - 1) -+ -+#define PART_CFERAM "cferam" -+#define PART_FIRMWARE "firmware" -+#define PART_IMAGE_1 "img1" -+#define PART_IMAGE_2 "img2" -+ -+static u32 jffs2_dirent_crc(struct jffs2_raw_dirent *node) -+{ -+ return crc32(0, node, sizeof(struct jffs2_raw_dirent) - 8); -+} -+ -+static bool jffs2_dirent_valid(struct jffs2_raw_dirent *node) -+{ -+ return ((je16_to_cpu(node->magic) == JFFS2_MAGIC_BITMASK) && -+ (je16_to_cpu(node->nodetype) == JFFS2_NODETYPE_DIRENT) && -+ je32_to_cpu(node->ino) && -+ je32_to_cpu(node->node_crc) == jffs2_dirent_crc(node)); -+} -+ -+static int jffs2_find_file(struct mtd_info *mtd, uint8_t *buf, -+ const char *name, size_t name_len, -+ loff_t *offs, loff_t size, -+ char **out_name, size_t *out_name_len) -+{ -+ const loff_t end = *offs + size; -+ struct jffs2_raw_dirent *node; -+ bool valid = false; -+ size_t retlen; -+ uint16_t magic; -+ int rc; -+ -+ for (; *offs < end; *offs += mtd->erasesize) { -+ unsigned int block_offs = 0; -+ -+ /* Skip CFE erased blocks */ -+ rc = mtd_read(mtd, *offs, sizeof(magic), &retlen, -+ (void *) &magic); -+ if (rc || retlen != sizeof(magic)) { -+ continue; -+ } -+ -+ /* Skip blocks not starting with JFFS2 magic */ -+ if (magic != JFFS2_MAGIC_BITMASK) -+ continue; -+ -+ /* Read full block */ -+ rc = mtd_read(mtd, *offs, mtd->erasesize, &retlen, -+ (void *) buf); -+ if (rc) -+ return rc; -+ if (retlen != mtd->erasesize) -+ return -EINVAL; -+ -+ while (block_offs < mtd->erasesize) { -+ node = (struct jffs2_raw_dirent *) &buf[block_offs]; -+ -+ if (!jffs2_dirent_valid(node)) { -+ block_offs += 4; -+ continue; -+ } -+ -+ if (!memcmp(node->name, OPENWRT_NAME, -+ OPENWRT_NAME_LEN)) { -+ valid = true; -+ } else if (!memcmp(node->name, name, name_len)) { -+ if (!valid) -+ return -EINVAL; -+ -+ if (out_name) -+ *out_name = kstrndup(node->name, -+ node->nsize, -+ GFP_KERNEL); -+ -+ if (out_name_len) -+ *out_name_len = node->nsize; -+ -+ return 0; -+ } -+ -+ block_offs += je32_to_cpu(node->totlen); -+ block_offs = (block_offs + 0x3) & ~0x3; -+ } -+ } -+ -+ return -ENOENT; -+} -+ -+static int ubifs_find(struct mtd_info *mtd, loff_t *offs, loff_t size) -+{ -+ const loff_t end = *offs + size; -+ uint32_t magic; -+ size_t retlen; -+ int rc; -+ -+ for (; *offs < end; *offs += mtd->erasesize) { -+ rc = mtd_read(mtd, *offs, sizeof(magic), &retlen, -+ (unsigned char *) &magic); -+ if (rc || retlen != sizeof(magic)) -+ continue; -+ -+ if (be32_to_cpu(magic) == UBI_MAGIC) -+ return 0; -+ } -+ -+ return -ENOENT; -+} -+ -+static int parse_bcm_wfi(struct mtd_info *master, -+ const struct mtd_partition **pparts, -+ uint8_t *buf, loff_t off, loff_t size, bool cfe_part) -+{ -+ struct device_node *mtd_node; -+ struct mtd_partition *parts; -+ loff_t cfe_off, kernel_off, rootfs_off; -+ unsigned int num_parts = BCM_WFI_PARTS, cur_part = 0; -+ const char *cferam_name = CFERAM_NAME; -+ size_t cferam_name_len; -+ int ret; -+ -+ mtd_node = mtd_get_of_node(master); -+ if (mtd_node) -+ of_property_read_string(mtd_node, "brcm,cferam", &cferam_name); -+ -+ cferam_name_len = strnlen(cferam_name, CFERAM_NAME_MAX_LEN); -+ if (cferam_name_len > 0) -+ cferam_name_len--; -+ -+ if (cfe_part) { -+ num_parts++; -+ cfe_off = off; -+ -+ ret = jffs2_find_file(master, buf, cferam_name, -+ cferam_name_len, &cfe_off, -+ size - (cfe_off - off), NULL, NULL); -+ if (ret) -+ return ret; -+ -+ kernel_off = cfe_off + master->erasesize; -+ } else { -+ kernel_off = off; -+ } -+ -+ ret = jffs2_find_file(master, buf, KERNEL_NAME, KERNEL_NAME_LEN, -+ &kernel_off, size - (kernel_off - off), -+ NULL, NULL); -+ if (ret) -+ return ret; -+ -+ rootfs_off = kernel_off + master->erasesize; -+ ret = ubifs_find(master, &rootfs_off, size - (rootfs_off - off)); -+ if (ret) -+ return ret; -+ -+ parts = kzalloc(num_parts * sizeof(*parts), GFP_KERNEL); -+ if (!parts) -+ return -ENOMEM; -+ -+ if (cfe_part) { -+ parts[cur_part].name = PART_CFERAM; -+ parts[cur_part].mask_flags = MTD_WRITEABLE; -+ parts[cur_part].offset = cfe_off; -+ parts[cur_part].size = kernel_off - cfe_off; -+ cur_part++; -+ } -+ -+ parts[cur_part].name = PART_FIRMWARE; -+ parts[cur_part].offset = kernel_off; -+ parts[cur_part].size = size - (kernel_off - off); -+ cur_part++; -+ -+ parts[cur_part].name = KERNEL_PART_NAME; -+ parts[cur_part].offset = kernel_off; -+ parts[cur_part].size = rootfs_off - kernel_off; -+ cur_part++; -+ -+ parts[cur_part].name = UBI_PART_NAME; -+ parts[cur_part].offset = rootfs_off; -+ parts[cur_part].size = size - (rootfs_off - off); -+ cur_part++; -+ -+ *pparts = parts; -+ -+ return num_parts; -+} -+ -+static int mtdsplit_parse_bcm_wfi(struct mtd_info *master, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct device_node *mtd_node; -+ bool cfe_part = true; -+ uint8_t *buf; -+ int ret; -+ -+ mtd_node = mtd_get_of_node(master); -+ if (!mtd_node) -+ return -EINVAL; -+ -+ buf = kzalloc(master->erasesize, GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; -+ -+ if (of_property_read_bool(mtd_node, "brcm,no-cferam")) -+ cfe_part = false; -+ -+ ret = parse_bcm_wfi(master, pparts, buf, 0, master->size, cfe_part); -+ -+ kfree(buf); -+ -+ return ret; -+} -+ -+static const struct of_device_id mtdsplit_bcm_wfi_of_match[] = { -+ { .compatible = "brcm,wfi" }, -+ { }, -+}; -+ -+static struct mtd_part_parser mtdsplit_bcm_wfi_parser = { -+ .owner = THIS_MODULE, -+ .name = "bcm-wfi-fw", -+ .of_match_table = mtdsplit_bcm_wfi_of_match, -+ .parse_fn = mtdsplit_parse_bcm_wfi, -+ .type = MTD_PARSER_TYPE_FIRMWARE, -+}; -+ -+static int cferam_bootflag_value(const char *name, size_t name_len) -+{ -+ int rc = -ENOENT; -+ -+ if (name && -+ (name_len >= CFE_MAGIC_LEN) && -+ !memcmp(name, CFE_MAGIC_PFX, CFE_MAGIC_PFX_LEN)) { -+ rc = char_to_num(name[CFE_MAGIC_PFX_LEN + 0]) * 100; -+ rc += char_to_num(name[CFE_MAGIC_PFX_LEN + 1]) * 10; -+ rc += char_to_num(name[CFE_MAGIC_PFX_LEN + 2]) * 1; -+ } -+ -+ return rc; -+} -+ -+static int mtdsplit_parse_bcm_wfi_split(struct mtd_info *master, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct mtd_partition *parts; -+ loff_t cfe_off; -+ loff_t img1_off = 0; -+ loff_t img2_off = master->size / 2; -+ loff_t img1_size = (img2_off - img1_off); -+ loff_t img2_size = (master->size - img2_off); -+ loff_t active_off, inactive_off; -+ loff_t active_size, inactive_size; -+ const char *inactive_name; -+ uint8_t *buf; -+ char *cfe1_name = NULL, *cfe2_name = NULL; -+ size_t cfe1_size = 0, cfe2_size = 0; -+ int ret; -+ int bf1, bf2; -+ -+ buf = kzalloc(master->erasesize, GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; -+ -+ cfe_off = img1_off; -+ ret = jffs2_find_file(master, buf, CFERAM_NAME, CFERAM_NAME_LEN, -+ &cfe_off, img1_size, &cfe1_name, &cfe1_size); -+ -+ cfe_off = img2_off; -+ ret = jffs2_find_file(master, buf, CFERAM_NAME, CFERAM_NAME_LEN, -+ &cfe_off, img2_size, &cfe2_name, &cfe2_size); -+ -+ bf1 = cferam_bootflag_value(cfe1_name, cfe1_size); -+ if (bf1 >= 0) -+ printk("cferam: bootflag1=%d\n", bf1); -+ -+ bf2 = cferam_bootflag_value(cfe2_name, cfe2_size); -+ if (bf2 >= 0) -+ printk("cferam: bootflag2=%d\n", bf2); -+ -+ kfree(cfe1_name); -+ kfree(cfe2_name); -+ -+ if (bf1 >= bf2) { -+ active_off = img1_off; -+ active_size = img1_size; -+ inactive_off = img2_off; -+ inactive_size = img2_size; -+ inactive_name = PART_IMAGE_2; -+ } else { -+ active_off = img2_off; -+ active_size = img2_size; -+ inactive_off = img1_off; -+ inactive_size = img1_size; -+ inactive_name = PART_IMAGE_1; -+ } -+ -+ ret = parse_bcm_wfi(master, pparts, buf, active_off, active_size, true); -+ -+ kfree(buf); -+ -+ if (ret > 0) { -+ parts = kzalloc((ret + 1) * sizeof(*parts), GFP_KERNEL); -+ if (!parts) -+ return -ENOMEM; -+ -+ memcpy(parts, *pparts, ret * sizeof(*parts)); -+ kfree(*pparts); -+ -+ parts[ret].name = inactive_name; -+ parts[ret].offset = inactive_off; -+ parts[ret].size = inactive_size; -+ ret++; -+ -+ *pparts = parts; -+ } else { -+ parts = kzalloc(BCM_WFI_SPLIT_PARTS * sizeof(*parts), GFP_KERNEL); -+ -+ parts[0].name = PART_IMAGE_1; -+ parts[0].offset = img1_off; -+ parts[0].size = img1_size; -+ -+ parts[1].name = PART_IMAGE_2; -+ parts[1].offset = img2_off; -+ parts[1].size = img2_size; -+ -+ *pparts = parts; -+ } -+ -+ return ret; -+} -+ -+static const struct of_device_id mtdsplit_bcm_wfi_split_of_match[] = { -+ { .compatible = "brcm,wfi-split" }, -+ { }, -+}; -+ -+static struct mtd_part_parser mtdsplit_bcm_wfi_split_parser = { -+ .owner = THIS_MODULE, -+ .name = "bcm-wfi-split-fw", -+ .of_match_table = mtdsplit_bcm_wfi_split_of_match, -+ .parse_fn = mtdsplit_parse_bcm_wfi_split, -+ .type = MTD_PARSER_TYPE_FIRMWARE, -+}; -+ -+static int sercomm_bootflag_value(struct mtd_info *mtd, uint8_t *buf) -+{ -+ size_t retlen; -+ loff_t offs; -+ int rc; -+ -+ for (offs = 0; offs < mtd->size; offs += mtd->erasesize) { -+ rc = mtd_read(mtd, offs, SERCOMM_MAGIC_LEN, &retlen, buf); -+ if (rc || retlen != SERCOMM_MAGIC_LEN) -+ continue; -+ -+ if (memcmp(buf, SERCOMM_MAGIC_PFX, SERCOMM_MAGIC_PFX_LEN)) -+ continue; -+ -+ rc = char_to_num(buf[SERCOMM_MAGIC_PFX_LEN + 0]) * 100; -+ rc += char_to_num(buf[SERCOMM_MAGIC_PFX_LEN + 1]) * 10; -+ rc += char_to_num(buf[SERCOMM_MAGIC_PFX_LEN + 2]) * 1; -+ -+ return rc; -+ } -+ -+ return -ENOENT; -+} -+ -+static int mtdsplit_parse_ser_wfi(struct mtd_info *master, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct mtd_partition *parts; -+ struct mtd_info *mtd_bf1, *mtd_bf2; -+ loff_t img1_off = 0; -+ loff_t img2_off = master->size / 2; -+ loff_t img1_size = (img2_off - img1_off); -+ loff_t img2_size = (master->size - img2_off); -+ loff_t active_off, inactive_off; -+ loff_t active_size, inactive_size; -+ const char *inactive_name; -+ uint8_t *buf; -+ int bf1, bf2; -+ int ret; -+ -+ mtd_bf1 = get_mtd_device_nm("bootflag1"); -+ if (IS_ERR(mtd_bf1)) -+ return -ENOENT; -+ -+ mtd_bf2 = get_mtd_device_nm("bootflag2"); -+ if (IS_ERR(mtd_bf2)) -+ return -ENOENT; -+ -+ buf = kzalloc(master->erasesize, GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; -+ -+ bf1 = sercomm_bootflag_value(mtd_bf1, buf); -+ if (bf1 >= 0) -+ printk("sercomm: bootflag1=%d\n", bf1); -+ -+ bf2 = sercomm_bootflag_value(mtd_bf2, buf); -+ if (bf2 >= 0) -+ printk("sercomm: bootflag2=%d\n", bf2); -+ -+ if (bf1 == bf2 && bf2 >= 0) { -+ struct erase_info bf_erase; -+ -+ bf2 = -ENOENT; -+ bf_erase.addr = 0; -+ bf_erase.len = mtd_bf2->size; -+ mtd_erase(mtd_bf2, &bf_erase); -+ } -+ -+ if (bf1 >= bf2) { -+ active_off = img1_off; -+ active_size = img1_size; -+ inactive_off = img2_off; -+ inactive_size = img2_size; -+ inactive_name = PART_IMAGE_2; -+ } else { -+ active_off = img2_off; -+ active_size = img2_size; -+ inactive_off = img1_off; -+ inactive_size = img1_size; -+ inactive_name = PART_IMAGE_1; -+ } -+ -+ ret = parse_bcm_wfi(master, pparts, buf, active_off, active_size, false); -+ -+ kfree(buf); -+ -+ if (ret > 0) { -+ parts = kzalloc((ret + 1) * sizeof(*parts), GFP_KERNEL); -+ if (!parts) -+ return -ENOMEM; -+ -+ memcpy(parts, *pparts, ret * sizeof(*parts)); -+ kfree(*pparts); -+ -+ parts[ret].name = inactive_name; -+ parts[ret].offset = inactive_off; -+ parts[ret].size = inactive_size; -+ ret++; -+ -+ *pparts = parts; -+ } else { -+ parts = kzalloc(BCM_WFI_SPLIT_PARTS * sizeof(*parts), GFP_KERNEL); -+ -+ parts[0].name = PART_IMAGE_1; -+ parts[0].offset = img1_off; -+ parts[0].size = img1_size; -+ -+ parts[1].name = PART_IMAGE_2; -+ parts[1].offset = img2_off; -+ parts[1].size = img2_size; -+ -+ *pparts = parts; -+ } -+ -+ return ret; -+} -+ -+static const struct of_device_id mtdsplit_ser_wfi_of_match[] = { -+ { .compatible = "sercomm,wfi" }, -+ { }, -+}; -+ -+static struct mtd_part_parser mtdsplit_ser_wfi_parser = { -+ .owner = THIS_MODULE, -+ .name = "ser-wfi-fw", -+ .of_match_table = mtdsplit_ser_wfi_of_match, -+ .parse_fn = mtdsplit_parse_ser_wfi, -+ .type = MTD_PARSER_TYPE_FIRMWARE, -+}; -+ -+static int __init mtdsplit_bcm_wfi_init(void) -+{ -+ register_mtd_parser(&mtdsplit_bcm_wfi_parser); -+ register_mtd_parser(&mtdsplit_bcm_wfi_split_parser); -+ register_mtd_parser(&mtdsplit_ser_wfi_parser); -+ -+ return 0; -+} -+ -+module_init(mtdsplit_bcm_wfi_init); -diff --git a/drivers/mtd/mtdsplit/mtdsplit_brnimage.c b/drivers/mtd/mtdsplit/mtdsplit_brnimage.c -new file mode 100644 -index 000000000000..3f2d79601a14 ---- /dev/null -+++ b/drivers/mtd/mtdsplit/mtdsplit_brnimage.c -@@ -0,0 +1,104 @@ -+/* -+ * Copyright (C) 2012 John Crispin -+ * Copyright (C) 2015 Martin Blumenstingl -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mtdsplit.h" -+ -+#define BRNIMAGE_NR_PARTS 2 -+ -+#define BRNIMAGE_ALIGN_BYTES 0x400 -+#define BRNIMAGE_FOOTER_SIZE 12 -+ -+#define BRNIMAGE_MIN_OVERHEAD (BRNIMAGE_FOOTER_SIZE) -+#define BRNIMAGE_MAX_OVERHEAD (BRNIMAGE_ALIGN_BYTES + BRNIMAGE_FOOTER_SIZE) -+ -+static int mtdsplit_parse_brnimage(struct mtd_info *master, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct mtd_partition *parts; -+ uint32_t buf; -+ unsigned long rootfs_offset, rootfs_size, kernel_size; -+ size_t len; -+ int ret = 0; -+ -+ for (rootfs_offset = 0; rootfs_offset < master->size; -+ rootfs_offset += BRNIMAGE_ALIGN_BYTES) { -+ ret = mtd_check_rootfs_magic(master, rootfs_offset, NULL); -+ if (!ret) -+ break; -+ } -+ -+ if (ret) -+ return ret; -+ -+ if (rootfs_offset >= master->size) -+ return -EINVAL; -+ -+ ret = mtd_read(master, rootfs_offset - BRNIMAGE_FOOTER_SIZE, 4, &len, -+ (void *)&buf); -+ if (ret) -+ return ret; -+ -+ if (len != 4) -+ return -EIO; -+ -+ kernel_size = le32_to_cpu(buf); -+ -+ if (kernel_size > (rootfs_offset - BRNIMAGE_MIN_OVERHEAD)) -+ return -EINVAL; -+ -+ if (kernel_size < (rootfs_offset - BRNIMAGE_MAX_OVERHEAD)) -+ return -EINVAL; -+ -+ /* -+ * The footer must be untouched as it contains the checksum of the -+ * original brnImage (kernel + squashfs)! -+ */ -+ rootfs_size = master->size - rootfs_offset - BRNIMAGE_FOOTER_SIZE; -+ -+ parts = kzalloc(BRNIMAGE_NR_PARTS * sizeof(*parts), GFP_KERNEL); -+ if (!parts) -+ return -ENOMEM; -+ -+ parts[0].name = KERNEL_PART_NAME; -+ parts[0].offset = 0; -+ parts[0].size = kernel_size; -+ -+ parts[1].name = ROOTFS_PART_NAME; -+ parts[1].offset = rootfs_offset; -+ parts[1].size = rootfs_size; -+ -+ *pparts = parts; -+ return BRNIMAGE_NR_PARTS; -+} -+ -+static struct mtd_part_parser mtdsplit_brnimage_parser = { -+ .owner = THIS_MODULE, -+ .name = "brnimage-fw", -+ .parse_fn = mtdsplit_parse_brnimage, -+ .type = MTD_PARSER_TYPE_FIRMWARE, -+}; -+ -+static int __init mtdsplit_brnimage_init(void) -+{ -+ register_mtd_parser(&mtdsplit_brnimage_parser); -+ -+ return 0; -+} -+ -+subsys_initcall(mtdsplit_brnimage_init); -diff --git a/drivers/mtd/mtdsplit/mtdsplit_cfe_bootfs.c b/drivers/mtd/mtdsplit/mtdsplit_cfe_bootfs.c -new file mode 100644 -index 000000000000..a3474c9dc274 ---- /dev/null -+++ b/drivers/mtd/mtdsplit/mtdsplit_cfe_bootfs.c -@@ -0,0 +1,90 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (C) 2021 Rafał Miłecki -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mtdsplit.h" -+ -+#define je16_to_cpu(x) ((x).v16) -+#define je32_to_cpu(x) ((x).v32) -+ -+#define NR_PARTS 2 -+ -+static int mtdsplit_cfe_bootfs_parse(struct mtd_info *mtd, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct jffs2_raw_dirent node; -+ enum mtdsplit_part_type type; -+ struct mtd_partition *parts; -+ size_t rootfs_offset; -+ size_t retlen; -+ size_t offset; -+ int err; -+ -+ /* Don't parse backup partitions */ -+ if (strcmp(mtd->name, "firmware")) -+ return -EINVAL; -+ -+ /* Find the end of JFFS2 bootfs partition */ -+ offset = 0; -+ do { -+ err = mtd_read(mtd, offset, sizeof(node), &retlen, (void *)&node); -+ if (err || retlen != sizeof(node)) -+ break; -+ -+ if (je16_to_cpu(node.magic) != JFFS2_MAGIC_BITMASK) -+ break; -+ -+ offset += je32_to_cpu(node.totlen); -+ offset = (offset + 0x3) & ~0x3; -+ } while (offset < mtd->size); -+ -+ /* Find rootfs partition that follows the bootfs */ -+ err = mtd_find_rootfs_from(mtd, mtd->erasesize, mtd->size, &rootfs_offset, &type); -+ if (err) -+ return err; -+ -+ parts = kzalloc(NR_PARTS * sizeof(*parts), GFP_KERNEL); -+ if (!parts) -+ return -ENOMEM; -+ -+ parts[0].name = "bootfs"; -+ parts[0].offset = 0; -+ parts[0].size = rootfs_offset; -+ -+ if (type == MTDSPLIT_PART_TYPE_UBI) -+ parts[1].name = UBI_PART_NAME; -+ else -+ parts[1].name = ROOTFS_PART_NAME; -+ parts[1].offset = rootfs_offset; -+ parts[1].size = mtd->size - rootfs_offset; -+ -+ *pparts = parts; -+ -+ return NR_PARTS; -+} -+ -+static const struct of_device_id mtdsplit_cfe_bootfs_of_match_table[] = { -+ { .compatible = "brcm,bcm4908-firmware" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, mtdsplit_cfe_bootfs_of_match_table); -+ -+static struct mtd_part_parser mtdsplit_cfe_bootfs_parser = { -+ .owner = THIS_MODULE, -+ .name = "cfe-bootfs", -+ .of_match_table = mtdsplit_cfe_bootfs_of_match_table, -+ .parse_fn = mtdsplit_cfe_bootfs_parse, -+}; -+ -+module_mtd_part_parser(mtdsplit_cfe_bootfs_parser); -diff --git a/drivers/mtd/mtdsplit/mtdsplit_elf.c b/drivers/mtd/mtdsplit/mtdsplit_elf.c -new file mode 100644 -index 000000000000..47818416f61c ---- /dev/null -+++ b/drivers/mtd/mtdsplit/mtdsplit_elf.c -@@ -0,0 +1,287 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * MTD splitter for ELF loader firmware partitions -+ * -+ * Copyright (C) 2020 Sander Vanheule -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the Free -+ * Software Foundation; version 2. -+ * -+ * To parse the ELF kernel loader, a small ELF parser is used that can -+ * handle both ELF32 or ELF64 class loaders. The splitter assumes that the -+ * kernel is always located before the rootfs, whether it is embedded in the -+ * loader or not. -+ * -+ * The kernel image is preferably embedded inside the ELF loader, so the end -+ * of the loader equals the end of the kernel partition. This is due to the -+ * way mtd_find_rootfs_from searches for the the rootfs: -+ * - if the kernel image is embedded in the loader, the appended rootfs may -+ * follow the loader immediately, within the same erase block. -+ * - if the kernel image is not embedded in the loader, but placed at some -+ * offset behind the loader (OKLI-style loader), the rootfs must be -+ * aligned to an erase-block after the loader and kernel image. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mtdsplit.h" -+ -+#define ELF_NR_PARTS 2 -+ -+#define ELF_MAGIC 0x7f454c46 /* 0x7f E L F */ -+#define ELF_CLASS_32 1 -+#define ELF_CLASS_64 2 -+ -+struct elf_header_ident { -+ uint32_t magic; -+ uint8_t class; -+ uint8_t data; -+ uint8_t version; -+ uint8_t osabi; -+ uint8_t abiversion; -+ uint8_t pad[7]; -+}; -+ -+struct elf_header_32 { -+ uint16_t type; -+ uint16_t machine; -+ uint32_t version; -+ uint32_t entry; -+ uint32_t phoff; -+ uint32_t shoff; -+ uint32_t flags; -+ uint16_t ehsize; -+ uint16_t phentsize; -+ uint16_t phnum; -+ uint16_t shentsize; -+ uint16_t shnum; -+ uint16_t shstrndx; -+}; -+ -+struct elf_header_64 { -+ uint16_t type; -+ uint16_t machine; -+ uint32_t version; -+ uint64_t entry; -+ uint64_t phoff; -+ uint64_t shoff; -+ uint32_t flags; -+ uint16_t ehsize; -+ uint16_t phentsize; -+ uint16_t phnum; -+ uint16_t shentsize; -+ uint16_t shnum; -+ uint16_t shstrndx; -+}; -+ -+struct elf_header { -+ struct elf_header_ident ident; -+ union { -+ struct elf_header_32 elf32; -+ struct elf_header_64 elf64; -+ }; -+}; -+ -+struct elf_program_header_32 { -+ uint32_t type; -+ uint32_t offset; -+ uint32_t vaddr; -+ uint32_t paddr; -+ uint32_t filesize; -+ uint32_t memsize; -+ uint32_t flags; -+}; -+ -+struct elf_program_header_64 { -+ uint32_t type; -+ uint32_t flags; -+ uint64_t offset; -+ uint64_t vaddr; -+ uint64_t paddr; -+ uint64_t filesize; -+ uint64_t memsize; -+}; -+ -+ -+static int mtdsplit_elf_read_mtd(struct mtd_info *mtd, size_t offset, -+ uint8_t *dst, size_t len) -+{ -+ size_t retlen; -+ int ret; -+ -+ ret = mtd_read(mtd, offset, len, &retlen, dst); -+ if (ret) { -+ pr_debug("read error in \"%s\"\n", mtd->name); -+ return ret; -+ } -+ -+ if (retlen != len) { -+ pr_debug("short read in \"%s\"\n", mtd->name); -+ return -EIO; -+ } -+ -+ return 0; -+} -+ -+static int elf32_determine_size(struct mtd_info *mtd, struct elf_header *hdr, -+ size_t *size) -+{ -+ struct elf_header_32 *hdr32 = &(hdr->elf32); -+ int err; -+ size_t section_end, ph_table_end, ph_entry; -+ struct elf_program_header_32 ph; -+ -+ *size = 0; -+ -+ if (hdr32->shoff > 0) { -+ *size = hdr32->shoff + hdr32->shentsize * hdr32->shnum; -+ return 0; -+ } -+ -+ ph_entry = hdr32->phoff; -+ ph_table_end = hdr32->phoff + hdr32->phentsize * hdr32->phnum; -+ -+ while (ph_entry < ph_table_end) { -+ err = mtdsplit_elf_read_mtd(mtd, ph_entry, (uint8_t *)(&ph), -+ sizeof(ph)); -+ if (err) -+ return err; -+ -+ section_end = ph.offset + ph.filesize; -+ if (section_end > *size) -+ *size = section_end; -+ -+ ph_entry += hdr32->phentsize; -+ } -+ -+ return 0; -+} -+ -+static int elf64_determine_size(struct mtd_info *mtd, struct elf_header *hdr, -+ size_t *size) -+{ -+ struct elf_header_64 *hdr64 = &(hdr->elf64); -+ int err; -+ size_t section_end, ph_table_end, ph_entry; -+ struct elf_program_header_64 ph; -+ -+ *size = 0; -+ -+ if (hdr64->shoff > 0) { -+ *size = hdr64->shoff + hdr64->shentsize * hdr64->shnum; -+ return 0; -+ } -+ -+ ph_entry = hdr64->phoff; -+ ph_table_end = hdr64->phoff + hdr64->phentsize * hdr64->phnum; -+ -+ while (ph_entry < ph_table_end) { -+ err = mtdsplit_elf_read_mtd(mtd, ph_entry, (uint8_t *)(&ph), -+ sizeof(ph)); -+ if (err) -+ return err; -+ -+ section_end = ph.offset + ph.filesize; -+ if (section_end > *size) -+ *size = section_end; -+ -+ ph_entry += hdr64->phentsize; -+ } -+ -+ return 0; -+} -+ -+static int mtdsplit_parse_elf(struct mtd_info *mtd, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct elf_header hdr; -+ size_t loader_size, rootfs_offset; -+ enum mtdsplit_part_type type; -+ struct mtd_partition *parts; -+ int err; -+ -+ err = mtdsplit_elf_read_mtd(mtd, 0, (uint8_t *)&hdr, sizeof(hdr)); -+ if (err) -+ return err; -+ -+ if (be32_to_cpu(hdr.ident.magic) != ELF_MAGIC) { -+ pr_debug("invalid ELF magic %08x\n", -+ be32_to_cpu(hdr.ident.magic)); -+ return -EINVAL; -+ } -+ -+ switch (hdr.ident.class) { -+ case ELF_CLASS_32: -+ err = elf32_determine_size(mtd, &hdr, &loader_size); -+ break; -+ case ELF_CLASS_64: -+ err = elf64_determine_size(mtd, &hdr, &loader_size); -+ break; -+ default: -+ pr_debug("invalid ELF class %i\n", hdr.ident.class); -+ err = -EINVAL; -+ } -+ -+ if (err) -+ return err; -+ -+ err = mtd_find_rootfs_from(mtd, loader_size, mtd->size, -+ &rootfs_offset, &type); -+ if (err) -+ return err; -+ -+ if (rootfs_offset == mtd->size) { -+ pr_debug("no rootfs found in \"%s\"\n", mtd->name); -+ return -ENODEV; -+ } -+ -+ parts = kzalloc(ELF_NR_PARTS * sizeof(*parts), GFP_KERNEL); -+ if (!parts) -+ return -ENOMEM; -+ -+ parts[0].name = KERNEL_PART_NAME; -+ parts[0].offset = 0; -+ parts[0].size = rootfs_offset; -+ -+ if (type == MTDSPLIT_PART_TYPE_UBI) -+ parts[1].name = UBI_PART_NAME; -+ else -+ parts[1].name = ROOTFS_PART_NAME; -+ parts[1].offset = rootfs_offset; -+ parts[1].size = mtd->size - rootfs_offset; -+ -+ *pparts = parts; -+ return ELF_NR_PARTS; -+} -+ -+static const struct of_device_id mtdsplit_elf_of_match_table[] = { -+ { .compatible = "openwrt,elf" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, mtdsplit_elf_of_match_table); -+ -+static struct mtd_part_parser mtdsplit_elf_parser = { -+ .owner = THIS_MODULE, -+ .name = "elf-loader-fw", -+ .of_match_table = mtdsplit_elf_of_match_table, -+ .parse_fn = mtdsplit_parse_elf, -+ .type = MTD_PARSER_TYPE_FIRMWARE, -+}; -+ -+static int __init mtdsplit_elf_init(void) -+{ -+ register_mtd_parser(&mtdsplit_elf_parser); -+ -+ return 0; -+} -+ -+subsys_initcall(mtdsplit_elf_init); -diff --git a/drivers/mtd/mtdsplit/mtdsplit_eva.c b/drivers/mtd/mtdsplit/mtdsplit_eva.c -new file mode 100644 -index 000000000000..55004a6d36d7 ---- /dev/null -+++ b/drivers/mtd/mtdsplit/mtdsplit_eva.c -@@ -0,0 +1,103 @@ -+/* -+ * Copyright (C) 2012 John Crispin -+ * Copyright (C) 2015 Martin Blumenstingl -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mtdsplit.h" -+ -+#define EVA_NR_PARTS 2 -+#define EVA_MAGIC 0xfeed1281 -+#define EVA_FOOTER_SIZE 0x18 -+#define EVA_DUMMY_SQUASHFS_SIZE 0x100 -+ -+struct eva_image_header { -+ uint32_t magic; -+ uint32_t size; -+}; -+ -+static int mtdsplit_parse_eva(struct mtd_info *master, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct mtd_partition *parts; -+ struct eva_image_header hdr; -+ size_t retlen; -+ unsigned long kernel_size, rootfs_offset; -+ int err; -+ -+ err = mtd_read(master, 0, sizeof(hdr), &retlen, (void *) &hdr); -+ if (err) -+ return err; -+ -+ if (retlen != sizeof(hdr)) -+ return -EIO; -+ -+ if (le32_to_cpu(hdr.magic) != EVA_MAGIC) -+ return -EINVAL; -+ -+ kernel_size = le32_to_cpu(hdr.size) + EVA_FOOTER_SIZE; -+ -+ /* rootfs starts at the next 0x10000 boundary: */ -+ rootfs_offset = round_up(kernel_size, 0x10000); -+ -+ /* skip the dummy EVA squashfs partition (with wrong endianness): */ -+ rootfs_offset += EVA_DUMMY_SQUASHFS_SIZE; -+ -+ if (rootfs_offset >= master->size) -+ return -EINVAL; -+ -+ err = mtd_check_rootfs_magic(master, rootfs_offset, NULL); -+ if (err) -+ return err; -+ -+ parts = kzalloc(EVA_NR_PARTS * sizeof(*parts), GFP_KERNEL); -+ if (!parts) -+ return -ENOMEM; -+ -+ parts[0].name = KERNEL_PART_NAME; -+ parts[0].offset = 0; -+ parts[0].size = kernel_size; -+ -+ parts[1].name = ROOTFS_PART_NAME; -+ parts[1].offset = rootfs_offset; -+ parts[1].size = master->size - rootfs_offset; -+ -+ *pparts = parts; -+ return EVA_NR_PARTS; -+} -+ -+static const struct of_device_id mtdsplit_eva_of_match_table[] = { -+ { .compatible = "avm,eva-firmware" }, -+ {}, -+}; -+ -+static struct mtd_part_parser mtdsplit_eva_parser = { -+ .owner = THIS_MODULE, -+ .name = "eva-fw", -+ .of_match_table = mtdsplit_eva_of_match_table, -+ .parse_fn = mtdsplit_parse_eva, -+ .type = MTD_PARSER_TYPE_FIRMWARE, -+}; -+ -+static int __init mtdsplit_eva_init(void) -+{ -+ register_mtd_parser(&mtdsplit_eva_parser); -+ -+ return 0; -+} -+ -+subsys_initcall(mtdsplit_eva_init); -diff --git a/drivers/mtd/mtdsplit/mtdsplit_fit.c b/drivers/mtd/mtdsplit/mtdsplit_fit.c -new file mode 100644 -index 000000000000..a271a676e10e ---- /dev/null -+++ b/drivers/mtd/mtdsplit/mtdsplit_fit.c -@@ -0,0 +1,365 @@ -+/* -+ * Copyright (c) 2015 The Linux Foundation -+ * Copyright (C) 2014 Gabor Juhos -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mtdsplit.h" -+ -+// string macros from git://git.denx.de/u-boot.git/include/image.h -+ -+#define FIT_IMAGES_PATH "/images" -+#define FIT_DATA_PROP "data" -+#define FIT_DATA_POSITION_PROP "data-position" -+#define FIT_DATA_OFFSET_PROP "data-offset" -+#define FIT_DATA_SIZE_PROP "data-size" -+ -+// functions from git://git.denx.de/u-boot.git/common/image-fit.c -+ -+/** -+ * fit_image_get_data - get data property and its size for a given component image node -+ * @fit: pointer to the FIT format image header -+ * @noffset: component image node offset -+ * @data: double pointer to void, will hold data property's data address -+ * @size: pointer to size_t, will hold data property's data size -+ * -+ * fit_image_get_data() finds data property in a given component image node. -+ * If the property is found its data start address and size are returned to -+ * the caller. -+ * -+ * returns: -+ * 0, on success -+ * -1, on failure -+ */ -+static int fit_image_get_data(const void *fit, int noffset, -+ const void **data, size_t *size) -+{ -+ int len; -+ -+ *data = fdt_getprop(fit, noffset, FIT_DATA_PROP, &len); -+ if (*data == NULL) { -+ *size = 0; -+ return -1; -+ } -+ -+ *size = len; -+ return 0; -+} -+ -+ -+/** -+ * Get 'data-offset' property from a given image node. -+ * -+ * @fit: pointer to the FIT image header -+ * @noffset: component image node offset -+ * @data_offset: holds the data-offset property -+ * -+ * returns: -+ * 0, on success -+ * -ENOENT if the property could not be found -+ */ -+static int fit_image_get_data_offset(const void *fit, int noffset, int *data_offset) -+{ -+ const fdt32_t *val; -+ -+ val = fdt_getprop(fit, noffset, FIT_DATA_OFFSET_PROP, NULL); -+ if (!val) -+ return -ENOENT; -+ -+ *data_offset = fdt32_to_cpu(*val); -+ -+ return 0; -+} -+ -+/** -+ * Get 'data-position' property from a given image node. -+ * -+ * @fit: pointer to the FIT image header -+ * @noffset: component image node offset -+ * @data_position: holds the data-position property -+ * -+ * returns: -+ * 0, on success -+ * -ENOENT if the property could not be found -+ */ -+static int fit_image_get_data_position(const void *fit, int noffset, -+ int *data_position) -+{ -+ const fdt32_t *val; -+ -+ val = fdt_getprop(fit, noffset, FIT_DATA_POSITION_PROP, NULL); -+ if (!val) -+ return -ENOENT; -+ -+ *data_position = fdt32_to_cpu(*val); -+ -+ return 0; -+} -+ -+/** -+ * Get 'data-size' property from a given image node. -+ * -+ * @fit: pointer to the FIT image header -+ * @noffset: component image node offset -+ * @data_size: holds the data-size property -+ * -+ * returns: -+ * 0, on success -+ * -ENOENT if the property could not be found -+ */ -+static int fit_image_get_data_size(const void *fit, int noffset, int *data_size) -+{ -+ const fdt32_t *val; -+ -+ val = fdt_getprop(fit, noffset, FIT_DATA_SIZE_PROP, NULL); -+ if (!val) -+ return -ENOENT; -+ -+ *data_size = fdt32_to_cpu(*val); -+ -+ return 0; -+} -+ -+/** -+ * fit_image_get_data_and_size - get data and its size including -+ * both embedded and external data -+ * @fit: pointer to the FIT format image header -+ * @noffset: component image node offset -+ * @data: double pointer to void, will hold data property's data address -+ * @size: pointer to size_t, will hold data property's data size -+ * -+ * fit_image_get_data_and_size() finds data and its size including -+ * both embedded and external data. If the property is found -+ * its data start address and size are returned to the caller. -+ * -+ * returns: -+ * 0, on success -+ * otherwise, on failure -+ */ -+static int fit_image_get_data_and_size(const void *fit, int noffset, -+ const void **data, size_t *size) -+{ -+ bool external_data = false; -+ int offset; -+ int len; -+ int ret; -+ -+ if (!fit_image_get_data_position(fit, noffset, &offset)) { -+ external_data = true; -+ } else if (!fit_image_get_data_offset(fit, noffset, &offset)) { -+ external_data = true; -+ /* -+ * For FIT with external data, figure out where -+ * the external images start. This is the base -+ * for the data-offset properties in each image. -+ */ -+ offset += ((fdt_totalsize(fit) + 3) & ~3); -+ } -+ -+ if (external_data) { -+ ret = fit_image_get_data_size(fit, noffset, &len); -+ if (!ret) { -+ *data = fit + offset; -+ *size = len; -+ } -+ } else { -+ ret = fit_image_get_data(fit, noffset, data, size); -+ } -+ -+ return ret; -+} -+ -+static int -+mtdsplit_fit_parse(struct mtd_info *mtd, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct device_node *np = mtd_get_of_node(mtd); -+ const char *cmdline_match = NULL; -+ struct fdt_header hdr; -+ size_t hdr_len, retlen; -+ size_t offset; -+ u32 offset_start = 0; -+ size_t fit_offset, fit_size; -+ size_t rootfs_offset, rootfs_size; -+ size_t data_size, img_total, max_size = 0; -+ struct mtd_partition *parts; -+ int ret, ndepth, noffset, images_noffset; -+ const void *img_data; -+ void *fit; -+ -+ of_property_read_string(np, "openwrt,cmdline-match", &cmdline_match); -+ if (cmdline_match && !strstr(saved_command_line, cmdline_match)) -+ return -ENODEV; -+ -+ of_property_read_u32(np, "openwrt,fit-offset", &offset_start); -+ -+ hdr_len = sizeof(struct fdt_header); -+ -+ /* Parse the MTD device & search for the FIT image location */ -+ for(offset = 0; offset + hdr_len <= mtd->size; offset += mtd->erasesize) { -+ ret = mtd_read(mtd, offset + offset_start, hdr_len, &retlen, (void*) &hdr); -+ if (ret) { -+ pr_err("read error in \"%s\" at offset 0x%llx\n", -+ mtd->name, (unsigned long long) offset); -+ return ret; -+ } -+ -+ if (retlen != hdr_len) { -+ pr_err("short read in \"%s\"\n", mtd->name); -+ return -EIO; -+ } -+ -+ /* Check the magic - see if this is a FIT image */ -+ if (be32_to_cpu(hdr.magic) != OF_DT_HEADER) { -+ pr_debug("no valid FIT image found in \"%s\" at offset %llx\n", -+ mtd->name, (unsigned long long) offset); -+ continue; -+ } -+ -+ /* We found a FIT image. Let's keep going */ -+ break; -+ } -+ -+ fit_offset = offset; -+ fit_size = be32_to_cpu(hdr.totalsize); -+ -+ if (fit_size == 0) { -+ pr_err("FIT image in \"%s\" at offset %llx has null size\n", -+ mtd->name, (unsigned long long) fit_offset); -+ return -ENODEV; -+ } -+ -+ /* -+ * Classic uImage.FIT has all data embedded into the FDT -+ * data structure. Hence the total size of the image equals -+ * the total size of the FDT structure. -+ * Modern uImage.FIT may have only references to data in FDT, -+ * hence we need to parse FDT structure to find the end of the -+ * last external data refernced. -+ */ -+ if (fit_size > 0x1000) { -+ enum mtdsplit_part_type type; -+ -+ /* Search for the rootfs partition after the FIT image */ -+ ret = mtd_find_rootfs_from(mtd, fit_offset + fit_size + offset_start, mtd->size, -+ &rootfs_offset, &type); -+ if (ret) { -+ pr_info("no rootfs found after FIT image in \"%s\"\n", -+ mtd->name); -+ return ret; -+ } -+ -+ rootfs_size = mtd->size - rootfs_offset; -+ -+ parts = kzalloc(2 * sizeof(*parts), GFP_KERNEL); -+ if (!parts) -+ return -ENOMEM; -+ -+ parts[0].name = KERNEL_PART_NAME; -+ parts[0].offset = fit_offset; -+ parts[0].size = mtd_roundup_to_eb(fit_size + offset_start, mtd); -+ -+ if (type == MTDSPLIT_PART_TYPE_UBI) -+ parts[1].name = UBI_PART_NAME; -+ else -+ parts[1].name = ROOTFS_PART_NAME; -+ parts[1].offset = rootfs_offset; -+ parts[1].size = rootfs_size; -+ -+ *pparts = parts; -+ -+ return 2; -+ } else { -+ /* Search for rootfs_data after FIT external data */ -+ fit = kzalloc(fit_size, GFP_KERNEL); -+ ret = mtd_read(mtd, offset, fit_size + offset_start, &retlen, fit); -+ if (ret) { -+ pr_err("read error in \"%s\" at offset 0x%llx\n", -+ mtd->name, (unsigned long long) offset); -+ return ret; -+ } -+ -+ images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); -+ if (images_noffset < 0) { -+ pr_err("Can't find images parent node '%s' (%s)\n", -+ FIT_IMAGES_PATH, fdt_strerror(images_noffset)); -+ return -ENODEV; -+ } -+ -+ for (ndepth = 0, -+ noffset = fdt_next_node(fit, images_noffset, &ndepth); -+ (noffset >= 0) && (ndepth > 0); -+ noffset = fdt_next_node(fit, noffset, &ndepth)) { -+ if (ndepth == 1) { -+ ret = fit_image_get_data_and_size(fit, noffset, &img_data, &data_size); -+ if (ret) -+ return 0; -+ -+ img_total = data_size + (img_data - fit); -+ -+ max_size = (max_size > img_total) ? max_size : img_total; -+ } -+ } -+ -+ parts = kzalloc(sizeof(*parts), GFP_KERNEL); -+ if (!parts) -+ return -ENOMEM; -+ -+ parts[0].name = ROOTFS_SPLIT_NAME; -+ parts[0].offset = fit_offset + mtd_roundup_to_eb(max_size, mtd); -+ parts[0].size = mtd->size - parts[0].offset; -+ -+ *pparts = parts; -+ -+ kfree(fit); -+ -+ return 1; -+ } -+} -+ -+static const struct of_device_id mtdsplit_fit_of_match_table[] = { -+ { .compatible = "denx,fit" }, -+ {}, -+}; -+ -+static struct mtd_part_parser uimage_parser = { -+ .owner = THIS_MODULE, -+ .name = "fit-fw", -+ .of_match_table = mtdsplit_fit_of_match_table, -+ .parse_fn = mtdsplit_fit_parse, -+ .type = MTD_PARSER_TYPE_FIRMWARE, -+}; -+ -+/************************************************** -+ * Init -+ **************************************************/ -+ -+static int __init mtdsplit_fit_init(void) -+{ -+ register_mtd_parser(&uimage_parser); -+ -+ return 0; -+} -+ -+module_init(mtdsplit_fit_init); -diff --git a/drivers/mtd/mtdsplit/mtdsplit_h3c_vfs.c b/drivers/mtd/mtdsplit/mtdsplit_h3c_vfs.c -new file mode 100644 -index 000000000000..25993e762bf9 ---- /dev/null -+++ b/drivers/mtd/mtdsplit/mtdsplit_h3c_vfs.c -@@ -0,0 +1,167 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Some devices made by H3C use a "VFS" filesystem to store firmware images. -+ * This parses the start of the filesystem to read the length of the first -+ * file (the kernel image). It then searches for the rootfs after the end of -+ * the file data. This driver assumes that the filesystem was generated by -+ * mkh3cvfs, and only works if the filesystem matches the expected layout, -+ * which includes the file name of the kernel image. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mtdsplit.h" -+ -+#define VFS_ERASEBLOCK_SIZE 0x10000 -+#define VFS_BLOCK_SIZE 0x400 -+#define VFS_BLOCKS_PER_ERASEBLOCK (VFS_ERASEBLOCK_SIZE / VFS_BLOCK_SIZE) -+ -+#define FORMAT_FLAG_OFFSET 0x0 -+ -+#define FORMAT_FLAG (VFS_ERASEBLOCK_SIZE << 12 | VFS_BLOCK_SIZE) -+ -+#define FILE_ENTRY_OFFSET 0x800 -+ -+#define FILE_ENTRY_FLAGS 0x3f -+#define FILE_ENTRY_PARENT_BLOCK 0 -+#define FILE_ENTRY_PARENT_INDEX 0 -+#define FILE_ENTRY_DATA_BLOCK 2 -+#define FILE_ENTRY_NAME "openwrt-kernel.bin" -+ -+#define NR_PARTS 2 -+ -+struct file_entry { -+ uint8_t flags; -+ -+ uint8_t res0[5]; -+ -+ uint16_t year; -+ uint8_t month; -+ uint8_t day; -+ uint8_t hour; -+ uint8_t minute; -+ uint8_t second; -+ -+ uint8_t res1[3]; -+ -+ uint32_t length; -+ -+ uint32_t parent_block; -+ uint16_t parent_index; -+ -+ uint8_t res2[2]; -+ -+ uint32_t data_block; -+ -+ char name[96]; -+} __attribute__ ((packed)); -+ -+static inline size_t block_offset(int block) -+{ -+ return VFS_ERASEBLOCK_SIZE * (block / (VFS_BLOCKS_PER_ERASEBLOCK-1)) -+ + VFS_BLOCK_SIZE * (1 + (block % (VFS_BLOCKS_PER_ERASEBLOCK-1))); -+} -+ -+static inline int block_count(size_t size) -+{ -+ return (size + VFS_BLOCK_SIZE - 1) / VFS_BLOCK_SIZE; -+} -+ -+static int mtdsplit_h3c_vfs_parse(struct mtd_info *mtd, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct mtd_partition *parts; -+ uint32_t format_flag; -+ struct file_entry file_entry; -+ size_t retlen; -+ int err; -+ size_t kernel_size; -+ size_t expected_offset; -+ size_t rootfs_offset; -+ -+ if (mtd->erasesize != VFS_ERASEBLOCK_SIZE) -+ return -EINVAL; -+ -+ /* Check format flag */ -+ err = mtd_read(mtd, FORMAT_FLAG_OFFSET, sizeof(format_flag), &retlen, -+ (void *) &format_flag); -+ if (err) -+ return err; -+ -+ if (retlen != sizeof(format_flag)) -+ return -EIO; -+ -+ if (format_flag != FORMAT_FLAG) { -+ pr_info("mtdsplit_h3c_vfs: unexpected format flag %08x\n", -+ format_flag); -+ return 0; -+ } -+ -+ /* Check file entry */ -+ err = mtd_read(mtd, FILE_ENTRY_OFFSET, sizeof(file_entry), &retlen, -+ (void *) &file_entry); -+ if (err) -+ return err; -+ -+ if (retlen != sizeof(file_entry)) -+ return -EIO; -+ -+ if (file_entry.flags != FILE_ENTRY_FLAGS || -+ file_entry.parent_block != FILE_ENTRY_PARENT_BLOCK || -+ file_entry.parent_index != FILE_ENTRY_PARENT_INDEX || -+ file_entry.data_block != FILE_ENTRY_DATA_BLOCK || -+ strncmp(file_entry.name, FILE_ENTRY_NAME, sizeof(file_entry.name)) != 0) { -+ pr_info("mtdsplit_h3c_vfs: unexpected file entry - OpenWrt probably not installed\n"); -+ return 0; -+ } -+ -+ /* Find rootfs offset */ -+ kernel_size = block_offset(file_entry.data_block + -+ block_count(file_entry.length) - 1) + -+ VFS_BLOCK_SIZE; -+ -+ expected_offset = mtd_roundup_to_eb(kernel_size, mtd); -+ -+ err = mtd_find_rootfs_from(mtd, expected_offset, mtd->size, -+ &rootfs_offset, NULL); -+ if (err) -+ return err; -+ -+ parts = kzalloc(NR_PARTS * sizeof(*parts), GFP_KERNEL); -+ if (!parts) -+ return -ENOMEM; -+ -+ parts[0].name = KERNEL_PART_NAME; -+ parts[0].offset = 0; -+ parts[0].size = rootfs_offset; -+ -+ parts[1].name = ROOTFS_PART_NAME; -+ parts[1].offset = rootfs_offset; -+ parts[1].size = mtd->size - rootfs_offset; -+ -+ *pparts = parts; -+ return NR_PARTS; -+} -+ -+static const struct of_device_id mtdsplit_h3c_vfs_of_match_table[] = { -+ { .compatible = "h3c,vfs-firmware" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, mtdsplit_h3c_vfs_of_match_table); -+ -+static struct mtd_part_parser mtdsplit_h3c_vfs_parser = { -+ .owner = THIS_MODULE, -+ .name = "h3c-vfs", -+ .of_match_table = mtdsplit_h3c_vfs_of_match_table, -+ .parse_fn = mtdsplit_h3c_vfs_parse, -+ .type = MTD_PARSER_TYPE_FIRMWARE, -+}; -+ -+module_mtd_part_parser(mtdsplit_h3c_vfs_parser); -diff --git a/drivers/mtd/mtdsplit/mtdsplit_jimage.c b/drivers/mtd/mtdsplit/mtdsplit_jimage.c -new file mode 100644 -index 000000000000..1244bbdb06e5 ---- /dev/null -+++ b/drivers/mtd/mtdsplit/mtdsplit_jimage.c -@@ -0,0 +1,284 @@ -+/* -+ * Copyright (C) 2018 Paweł Dembicki -+ * -+ * Based on: mtdsplit_uimage.c -+ * Copyright (C) 2013 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+ -+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mtdsplit.h" -+ -+#define MAX_HEADER_LEN ( STAG_SIZE + SCH2_SIZE ) -+ -+#define STAG_SIZE 16 -+#define STAG_ID 0x04 -+#define STAG_MAGIC 0x2B24 -+ -+#define SCH2_SIZE 40 -+#define SCH2_MAGIC 0x2124 -+#define SCH2_VER 0x02 -+ -+/* -+ * Jboot image header, -+ * all data in little endian. -+ */ -+ -+struct jimage_header //stag + sch2 jboot joined headers -+{ -+ uint8_t stag_cmark; // in factory 0xFF , in sysupgrade must be the same as stag_id -+ uint8_t stag_id; // 0x04 -+ uint16_t stag_magic; //magic 0x2B24 -+ uint32_t stag_time_stamp; // timestamp calculated in jboot way -+ uint32_t stag_image_length; // lentgh of kernel + sch2 header -+ uint16_t stag_image_checksum; // negated jboot_checksum of sch2 + kernel -+ uint16_t stag_tag_checksum; // negated jboot_checksum of stag header data -+ uint16_t sch2_magic; // magic 0x2124 -+ uint8_t sch2_cp_type; // 0x00 for flat, 0x01 for jz, 0x02 for gzip, 0x03 for lzma -+ uint8_t sch2_version; // 0x02 for sch2 -+ uint32_t sch2_ram_addr; // ram entry address -+ uint32_t sch2_image_len; // kernel image length -+ uint32_t sch2_image_crc32; // kernel image crc -+ uint32_t sch2_start_addr; // ram start address -+ uint32_t sch2_rootfs_addr; // rootfs flash address -+ uint32_t sch2_rootfs_len; // rootfls length -+ uint32_t sch2_rootfs_crc32; // rootfs crc32 -+ uint32_t sch2_header_crc32; // sch2 header crc32, durring calculation this area is replaced by zero -+ uint16_t sch2_header_length; // sch2 header length: 0x28 -+ uint16_t sch2_cmd_line_length; // cmd line length, known zeros -+}; -+ -+static int -+read_jimage_header(struct mtd_info *mtd, size_t offset, u_char *buf, -+ size_t header_len) -+{ -+ size_t retlen; -+ int ret; -+ -+ ret = mtd_read(mtd, offset, header_len, &retlen, buf); -+ if (ret) { -+ pr_debug("read error in \"%s\"\n", mtd->name); -+ return ret; -+ } -+ -+ if (retlen != header_len) { -+ pr_debug("short read in \"%s\"\n", mtd->name); -+ return -EIO; -+ } -+ -+ return 0; -+} -+ -+/** -+ * __mtdsplit_parse_jimage - scan partition and create kernel + rootfs parts -+ * -+ * @find_header: function to call for a block of data that will return offset -+ * of a valid jImage header if found -+ */ -+static int __mtdsplit_parse_jimage(struct mtd_info *master, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data, -+ ssize_t (*find_header)(u_char *buf, size_t len)) -+{ -+ struct mtd_partition *parts; -+ u_char *buf; -+ int nr_parts; -+ size_t offset; -+ size_t jimage_offset; -+ size_t jimage_size = 0; -+ size_t rootfs_offset; -+ size_t rootfs_size = 0; -+ int jimage_part, rf_part; -+ int ret; -+ enum mtdsplit_part_type type; -+ -+ nr_parts = 2; -+ parts = kzalloc(nr_parts * sizeof(*parts), GFP_KERNEL); -+ if (!parts) -+ return -ENOMEM; -+ -+ buf = vmalloc(MAX_HEADER_LEN); -+ if (!buf) { -+ ret = -ENOMEM; -+ goto err_free_parts; -+ } -+ -+ /* find jImage on erase block boundaries */ -+ for (offset = 0; offset < master->size; offset += master->erasesize) { -+ struct jimage_header *header; -+ -+ jimage_size = 0; -+ -+ ret = read_jimage_header(master, offset, buf, MAX_HEADER_LEN); -+ if (ret) -+ continue; -+ -+ ret = find_header(buf, MAX_HEADER_LEN); -+ if (ret < 0) { -+ pr_debug("no valid jImage found in \"%s\" at offset %llx\n", -+ master->name, (unsigned long long) offset); -+ continue; -+ } -+ header = (struct jimage_header *)(buf + ret); -+ -+ jimage_size = sizeof(*header) + header->sch2_image_len + ret; -+ if ((offset + jimage_size) > master->size) { -+ pr_debug("jImage exceeds MTD device \"%s\"\n", -+ master->name); -+ continue; -+ } -+ break; -+ } -+ -+ if (jimage_size == 0) { -+ pr_debug("no jImage found in \"%s\"\n", master->name); -+ ret = -ENODEV; -+ goto err_free_buf; -+ } -+ -+ jimage_offset = offset; -+ -+ if (jimage_offset == 0) { -+ jimage_part = 0; -+ rf_part = 1; -+ -+ /* find the roots after the jImage */ -+ ret = mtd_find_rootfs_from(master, jimage_offset + jimage_size, -+ master->size, &rootfs_offset, &type); -+ if (ret) { -+ pr_debug("no rootfs after jImage in \"%s\"\n", -+ master->name); -+ goto err_free_buf; -+ } -+ -+ rootfs_size = master->size - rootfs_offset; -+ jimage_size = rootfs_offset - jimage_offset; -+ } else { -+ rf_part = 0; -+ jimage_part = 1; -+ -+ /* check rootfs presence at offset 0 */ -+ ret = mtd_check_rootfs_magic(master, 0, &type); -+ if (ret) { -+ pr_debug("no rootfs before jImage in \"%s\"\n", -+ master->name); -+ goto err_free_buf; -+ } -+ -+ rootfs_offset = 0; -+ rootfs_size = jimage_offset; -+ } -+ -+ if (rootfs_size == 0) { -+ pr_debug("no rootfs found in \"%s\"\n", master->name); -+ ret = -ENODEV; -+ goto err_free_buf; -+ } -+ -+ parts[jimage_part].name = KERNEL_PART_NAME; -+ parts[jimage_part].offset = jimage_offset; -+ parts[jimage_part].size = jimage_size; -+ -+ if (type == MTDSPLIT_PART_TYPE_UBI) -+ parts[rf_part].name = UBI_PART_NAME; -+ else -+ parts[rf_part].name = ROOTFS_PART_NAME; -+ parts[rf_part].offset = rootfs_offset; -+ parts[rf_part].size = rootfs_size; -+ -+ vfree(buf); -+ -+ *pparts = parts; -+ return nr_parts; -+ -+err_free_buf: -+ vfree(buf); -+ -+err_free_parts: -+ kfree(parts); -+ return ret; -+} -+ -+static ssize_t jimage_verify_default(u_char *buf, size_t len) -+{ -+ struct jimage_header *header = (struct jimage_header *)buf; -+ -+ /* default sanity checks */ -+ if (header->stag_magic != STAG_MAGIC) { -+ pr_debug("invalid jImage stag header magic: %04x\n", -+ header->stag_magic); -+ return -EINVAL; -+ } -+ if (header->sch2_magic != SCH2_MAGIC) { -+ pr_debug("invalid jImage sch2 header magic: %04x\n", -+ header->stag_magic); -+ return -EINVAL; -+ } -+ if (header->stag_cmark != header->stag_id) { -+ pr_debug("invalid jImage stag header cmark: %02x\n", -+ header->stag_magic); -+ return -EINVAL; -+ } -+ if (header->stag_id != STAG_ID) { -+ pr_debug("invalid jImage stag header id: %02x\n", -+ header->stag_magic); -+ return -EINVAL; -+ } -+ if (header->sch2_version != SCH2_VER) { -+ pr_debug("invalid jImage sch2 header version: %02x\n", -+ header->stag_magic); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int -+mtdsplit_jimage_parse_generic(struct mtd_info *master, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ return __mtdsplit_parse_jimage(master, pparts, data, -+ jimage_verify_default); -+} -+ -+static const struct of_device_id mtdsplit_jimage_of_match_table[] = { -+ { .compatible = "amit,jimage" }, -+ {}, -+}; -+ -+static struct mtd_part_parser jimage_generic_parser = { -+ .owner = THIS_MODULE, -+ .name = "jimage-fw", -+ .of_match_table = mtdsplit_jimage_of_match_table, -+ .parse_fn = mtdsplit_jimage_parse_generic, -+ .type = MTD_PARSER_TYPE_FIRMWARE, -+}; -+ -+/************************************************** -+ * Init -+ **************************************************/ -+ -+static int __init mtdsplit_jimage_init(void) -+{ -+ register_mtd_parser(&jimage_generic_parser); -+ -+ return 0; -+} -+ -+module_init(mtdsplit_jimage_init); -diff --git a/drivers/mtd/mtdsplit/mtdsplit_lzma.c b/drivers/mtd/mtdsplit/mtdsplit_lzma.c -new file mode 100644 -index 000000000000..6dcffd04203d ---- /dev/null -+++ b/drivers/mtd/mtdsplit/mtdsplit_lzma.c -@@ -0,0 +1,109 @@ -+/* -+ * Copyright (C) 2014 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(6,12,0) -+#include -+#else -+#include -+#endif -+ -+#include "mtdsplit.h" -+ -+#define LZMA_NR_PARTS 2 -+#define LZMA_PROPERTIES_SIZE 5 -+ -+struct lzma_header { -+ u8 props[LZMA_PROPERTIES_SIZE]; -+ u8 size_low[4]; -+ u8 size_high[4]; -+}; -+ -+static int mtdsplit_parse_lzma(struct mtd_info *master, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct lzma_header hdr; -+ size_t hdr_len, retlen; -+ size_t rootfs_offset; -+ u32 t; -+ struct mtd_partition *parts; -+ int err; -+ -+ hdr_len = sizeof(hdr); -+ err = mtd_read(master, 0, hdr_len, &retlen, (void *) &hdr); -+ if (err) -+ return err; -+ -+ if (retlen != hdr_len) -+ return -EIO; -+ -+ /* verify LZMA properties */ -+ if (hdr.props[0] >= (9 * 5 * 5)) -+ return -EINVAL; -+ -+ t = get_unaligned_le32(&hdr.props[1]); -+ if (!is_power_of_2(t)) -+ return -EINVAL; -+ -+ t = get_unaligned_le32(&hdr.size_high); -+ if (t) -+ return -EINVAL; -+ -+ err = mtd_find_rootfs_from(master, master->erasesize, master->size, -+ &rootfs_offset, NULL); -+ if (err) -+ return err; -+ -+ parts = kzalloc(LZMA_NR_PARTS * sizeof(*parts), GFP_KERNEL); -+ if (!parts) -+ return -ENOMEM; -+ -+ parts[0].name = KERNEL_PART_NAME; -+ parts[0].offset = 0; -+ parts[0].size = rootfs_offset; -+ -+ parts[1].name = ROOTFS_PART_NAME; -+ parts[1].offset = rootfs_offset; -+ parts[1].size = master->size - rootfs_offset; -+ -+ *pparts = parts; -+ return LZMA_NR_PARTS; -+} -+ -+static const struct of_device_id mtdsplit_lzma_of_match_table[] = { -+ { .compatible = "lzma" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, mtdsplit_lzma_of_match_table); -+ -+static struct mtd_part_parser mtdsplit_lzma_parser = { -+ .owner = THIS_MODULE, -+ .name = "lzma-fw", -+ .of_match_table = mtdsplit_lzma_of_match_table, -+ .parse_fn = mtdsplit_parse_lzma, -+ .type = MTD_PARSER_TYPE_FIRMWARE, -+}; -+ -+static int __init mtdsplit_lzma_init(void) -+{ -+ register_mtd_parser(&mtdsplit_lzma_parser); -+ -+ return 0; -+} -+ -+subsys_initcall(mtdsplit_lzma_init); -diff --git a/drivers/mtd/mtdsplit/mtdsplit_minor.c b/drivers/mtd/mtdsplit/mtdsplit_minor.c -new file mode 100644 -index 000000000000..053cba6272da ---- /dev/null -+++ b/drivers/mtd/mtdsplit/mtdsplit_minor.c -@@ -0,0 +1,142 @@ -+/* -+ * MTD splitter for MikroTik NOR devices -+ * -+ * Copyright (C) 2017 Thibaut VARENE -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ * The rootfs is expected at erase-block boundary due to the use of -+ * mtd_find_rootfs_from(). We use a trimmed down version of the yaffs header -+ * for two main reasons: -+ * - the original header uses weakly defined types (int, enum...) which can -+ * vary in length depending on build host (and the struct is not packed), -+ * and the name field can have a different total length depending on -+ * whether or not the yaffs code was _built_ with unicode support. -+ * - the only field that could be of real use here (file_size_low) contains -+ * invalid data in the header generated by kernel2minor, so we cannot use -+ * it to infer the exact position of the rootfs and do away with -+ * mtd_find_rootfs_from() (and thus have non-EB-aligned rootfs). -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mtdsplit.h" -+ -+#define YAFFS_OBJECT_TYPE_FILE 0x1 -+#define YAFFS_OBJECTID_ROOT 0x1 -+#define YAFFS_SUM_UNUSED 0xFFFF -+#define YAFFS_MAX_NAME_LENGTH 127 -+#define YAFFS_NAME_KERNEL "kernel" -+#define YAFFS_NAME_BOOTIMAGE "bootimage" -+ -+#define MINOR_NR_PARTS 2 -+ -+/* -+ * This structure is based on yaffs_obj_hdr from yaffs_guts.h -+ * The weak types match upstream. The fields have cpu-endianness -+ */ -+struct minor_header { -+ int yaffs_type; -+ int yaffs_obj_id; -+ u16 yaffs_sum_unused; -+ char yaffs_name[YAFFS_MAX_NAME_LENGTH]; -+}; -+ -+static int mtdsplit_parse_minor(struct mtd_info *master, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct minor_header hdr; -+ size_t hdr_len, retlen; -+ size_t rootfs_offset; -+ struct mtd_partition *parts; -+ int err; -+ -+ hdr_len = sizeof(hdr); -+ err = mtd_read(master, 0, hdr_len, &retlen, (void *) &hdr); -+ if (err) { -+ pr_err("MiNOR mtd_read error: %d\n", err); -+ return err; -+ } -+ -+ if (retlen != hdr_len) { -+ pr_err("MiNOR mtd_read too short\n"); -+ return -EIO; -+ } -+ -+ /* match header */ -+ if (hdr.yaffs_type != YAFFS_OBJECT_TYPE_FILE) { -+ pr_info("MiNOR YAFFS first type not matched\n"); -+ return 0; -+ } -+ -+ if (hdr.yaffs_obj_id != YAFFS_OBJECTID_ROOT) { -+ pr_info("MiNOR YAFFS first objectid not matched\n"); -+ return 0; -+ } -+ -+ if (hdr.yaffs_sum_unused != YAFFS_SUM_UNUSED) { -+ pr_info("MiNOR YAFFS first sum not matched\n"); -+ return 0; -+ } -+ -+ if ((memcmp(hdr.yaffs_name, YAFFS_NAME_KERNEL, sizeof(YAFFS_NAME_KERNEL))) && -+ (memcmp(hdr.yaffs_name, YAFFS_NAME_BOOTIMAGE, sizeof(YAFFS_NAME_BOOTIMAGE)))) { -+ pr_info("MiNOR YAFFS first name not matched\n"); -+ return 0; -+ } -+ -+ err = mtd_find_rootfs_from(master, master->erasesize, master->size, -+ &rootfs_offset, NULL); -+ if (err) { -+ pr_info("MiNOR mtd_find_rootfs_from error: %d\n", err); -+ return 0; -+ } -+ -+ parts = kzalloc(MINOR_NR_PARTS * sizeof(*parts), GFP_KERNEL); -+ if (!parts) -+ return -ENOMEM; -+ -+ parts[0].name = KERNEL_PART_NAME; -+ parts[0].offset = 0; -+ parts[0].size = rootfs_offset; -+ -+ parts[1].name = ROOTFS_PART_NAME; -+ parts[1].offset = rootfs_offset; -+ parts[1].size = master->size - rootfs_offset; -+ -+ *pparts = parts; -+ return MINOR_NR_PARTS; -+} -+ -+static const struct of_device_id mtdsplit_minor_of_match_table[] = { -+ { .compatible = "mikrotik,minor" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, mtdsplit_minor_of_match_table); -+ -+static struct mtd_part_parser mtdsplit_minor_parser = { -+ .owner = THIS_MODULE, -+ .name = "minor-fw", -+ .of_match_table = mtdsplit_minor_of_match_table, -+ .parse_fn = mtdsplit_parse_minor, -+ .type = MTD_PARSER_TYPE_FIRMWARE, -+}; -+ -+static int __init mtdsplit_minor_init(void) -+{ -+ register_mtd_parser(&mtdsplit_minor_parser); -+ -+ return 0; -+} -+ -+subsys_initcall(mtdsplit_minor_init); -diff --git a/drivers/mtd/mtdsplit/mtdsplit_mstc_boot.c b/drivers/mtd/mtdsplit/mtdsplit_mstc_boot.c -new file mode 100644 -index 000000000000..6d7980792aed ---- /dev/null -+++ b/drivers/mtd/mtdsplit/mtdsplit_mstc_boot.c -@@ -0,0 +1,270 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * a mtdsplit parser using "bootnum" value in the "persist" partition -+ * for the devices manufactured by MSTC (MitraStar Technology Corp.) -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mtdsplit.h" -+ -+#define PERSIST_BOOTNUM_OFFSET 0x4 -+#define NR_PARTS_MAX 2 -+ -+/* -+ * Legacy format image header, -+ * all data in network byte order (aka natural aka bigendian). -+ */ -+ struct uimage_header { -+ uint32_t ih_magic; /* Image Header Magic Number */ -+ uint32_t ih_hcrc; /* Image Header CRC Checksum */ -+ uint32_t ih_time; /* Image Creation Timestamp */ -+ uint32_t ih_size; /* Image Data Size */ -+ uint32_t ih_load; /* Data Load Address */ -+ uint32_t ih_ep; /* Entry Point Address */ -+ uint32_t ih_dcrc; /* Image Data CRC Checksum */ -+ uint8_t ih_os; /* Operating System */ -+ uint8_t ih_arch; /* CPU architecture */ -+ uint8_t ih_type; /* Image Type */ -+ uint8_t ih_comp; /* Compression Type */ -+ uint8_t ih_name[IH_NMLEN]; /* Image Name */ -+}; -+ -+/* check whether the current mtd device is active or not */ -+static int -+mstcboot_is_active(struct mtd_info *mtd, u32 *bootnum_dt) -+{ -+ struct device_node *np = mtd_get_of_node(mtd); -+ struct device_node *persist_np; -+ size_t retlen; -+ u32 persist_offset; -+ u_char bootnum; -+ int ret; -+ -+ ret = of_property_read_u32(np, "mstc,bootnum", bootnum_dt); -+ if (ret) -+ return ret; -+ -+ persist_np = of_parse_phandle(np, "mstc,persist", 0); -+ if (!persist_np) -+ return -ENODATA; -+ /* is "persist" under the same node? */ -+ if (persist_np->parent != np->parent) { -+ of_node_put(persist_np); -+ return -EINVAL; -+ } -+ -+ ret = of_property_read_u32(persist_np, "reg", &persist_offset); -+ of_node_put(persist_np); -+ if (ret) -+ return ret; -+ ret = mtd_read(mtd->parent, persist_offset + PERSIST_BOOTNUM_OFFSET, -+ 1, &retlen, &bootnum); -+ if (ret) -+ return ret; -+ if (retlen != 1) -+ return -EIO; -+ -+ return (bootnum == *bootnum_dt) ? 1 : 0; -+} -+ -+/* -+ * mainly for NOR devices that uses raw kernel and squashfs -+ * -+ * example: -+ * -+ * partition@5a0000 { -+ * compatible = "mstc,boot"; -+ * label = "firmware1"; -+ * reg = <0x5a0000 0x3200000>; -+ * mstc,bootnum = <1>; -+ * mstc,persist = <&mtd_persist>; -+ * }; -+ */ -+static int -+mstcboot_parse_image_parts(struct mtd_info *mtd, -+ const struct mtd_partition **pparts) -+{ -+ struct mtd_partition *parts; -+ size_t retlen, kern_len = 0; -+ size_t rootfs_offset; -+ enum mtdsplit_part_type type; -+ u_char buf[0x40]; -+ int ret, nr_parts = 1, index = 0; -+ -+ ret = mtd_read(mtd, 0, sizeof(struct uimage_header), &retlen, buf); -+ if (ret) -+ return ret; -+ if (retlen != sizeof(struct uimage_header)) -+ return -EIO; -+ -+ if (be32_to_cpu(*(u32 *)buf) == OF_DT_HEADER) { -+ /* Flattened Image Tree (FIT) */ -+ struct fdt_header *fdthdr = (void *)buf; -+ kern_len = be32_to_cpu(fdthdr->totalsize); -+ } else if (be32_to_cpu(*(u32 *)buf) == IH_MAGIC) { -+ /* Legacy uImage */ -+ struct uimage_header *uimghdr = (void *)buf; -+ kern_len = sizeof(*uimghdr) + be32_to_cpu(uimghdr->ih_size); -+ } -+ -+ ret = mtd_find_rootfs_from(mtd, kern_len, mtd->size, &rootfs_offset, &type); -+ if (ret) { -+ pr_debug("no rootfs in \"%s\"\n", mtd->name); -+ return ret; -+ } -+ -+ if (kern_len > 0) -+ nr_parts++; -+ -+ parts = kcalloc(nr_parts, sizeof(*parts), GFP_KERNEL); -+ if (!parts) -+ return -ENOMEM; -+ -+ if (kern_len) { -+ parts[index].name = KERNEL_PART_NAME; -+ parts[index].offset = 0; -+ parts[index++].size = rootfs_offset; -+ } -+ -+ parts[index].name = (type == MTDSPLIT_PART_TYPE_UBI) -+ ? UBI_PART_NAME : ROOTFS_PART_NAME; -+ parts[index].offset = rootfs_offset; -+ parts[index].size = mtd->size - rootfs_offset; -+ -+ *pparts = parts; -+ return nr_parts; -+} -+ -+/* -+ * mainly for NAND devices that uses raw-kernel and UBI and needs -+ * splitted kernel/ubi partitions when sysupgrade -+ * -+ * example: -+ * -+ * partition@3c0000 { -+ * compatible = "mstc,boot"; -+ * reg = <0x3c0000 0x3240000>; -+ * label = "firmware1"; -+ * mstc,bootnum = <1>; -+ * mstc,persist = <&mtd_persist>; -+ * #address-cells = <1>; -+ * #size-cells = <1>; -+ * -+ * partition@0 { -+ * reg = <0x0 0x800000>; -+ * label-base = "kernel"; -+ * }; -+ * -+ * partition@800000 { -+ * reg = <0x800000 0x2a40000>; -+ * label-base = "ubi"; -+ * }; -+}; -+ */ -+static int -+mstcboot_parse_fixed_parts(struct mtd_info *mtd, -+ const struct mtd_partition **pparts, -+ int active, u32 bootnum_dt) -+{ -+ struct device_node *np = mtd_get_of_node(mtd); -+ struct device_node *child; -+ struct mtd_partition *parts; -+ int ret, nr_parts, index = 0; -+ -+ nr_parts = of_get_child_count(np); -+ if (nr_parts > NR_PARTS_MAX) { -+ pr_err("too many partitions found!\n"); -+ return -EINVAL; -+ } -+ -+ parts = kcalloc(nr_parts, sizeof(*parts), GFP_KERNEL); -+ if (!parts) -+ return -ENOMEM; -+ -+ for_each_child_of_node(np, child) { -+ u32 reg[2]; -+ if (of_n_addr_cells(child) != 1 || -+ of_n_size_cells(child) != 1) -+ { -+ ret = -EINVAL; -+ break; -+ } -+ -+ ret = of_property_read_u32_array(child, "reg", reg, 2); -+ if (ret) -+ break; -+ ret = of_property_read_string(child, "label-base", -+ &parts[index].name); -+ if (ret) -+ break; -+ -+ if (!active) { -+ parts[index].name = devm_kasprintf(&mtd->dev, GFP_KERNEL, -+ "%s%u", -+ parts[index].name, bootnum_dt); -+ if (!parts[index].name) { -+ ret = -ENOMEM; -+ break; -+ } -+ } -+ parts[index].offset = reg[0]; -+ parts[index].size = reg[1]; -+ index++; -+ } -+ of_node_put(child); -+ -+ if (ret) -+ kfree(parts); -+ else -+ *pparts = parts; -+ return ret ? ret : nr_parts; -+} -+ -+static int -+mtdsplit_mstcboot_parse(struct mtd_info *mtd, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct device_node *np = mtd_get_of_node(mtd); -+ u32 bootnum_dt; -+ int ret; -+ -+ ret = mstcboot_is_active(mtd, &bootnum_dt); -+ if (ret < 0) -+ goto exit; -+ -+ if (of_get_child_count(np)) -+ ret = mstcboot_parse_fixed_parts(mtd, pparts, ret, bootnum_dt); -+ else if (ret != 0) -+ ret = mstcboot_parse_image_parts(mtd, pparts); -+ -+exit: -+ /* -+ * return 0 when ret=-ENODEV, to prevent deletion of -+ * parent mtd partitions on Linux 6.7 and later -+ */ -+ return ret == -ENODEV ? 0 : ret; -+} -+ -+static const struct of_device_id mtdsplit_mstcboot_of_match_table[] = { -+ { .compatible = "mstc,boot" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, mtdsplit_mstcboot_of_match_table); -+ -+static struct mtd_part_parser mtdsplit_mstcboot_parser = { -+ .owner = THIS_MODULE, -+ .name = "mstc-boot", -+ .of_match_table = mtdsplit_mstcboot_of_match_table, -+ .parse_fn = mtdsplit_mstcboot_parse, -+ .type = MTD_PARSER_TYPE_FIRMWARE, -+}; -+module_mtd_part_parser(mtdsplit_mstcboot_parser) -diff --git a/drivers/mtd/mtdsplit/mtdsplit_seama.c b/drivers/mtd/mtdsplit/mtdsplit_seama.c -new file mode 100644 -index 000000000000..5d49171b1f74 ---- /dev/null -+++ b/drivers/mtd/mtdsplit/mtdsplit_seama.c -@@ -0,0 +1,118 @@ -+/* -+ * Copyright (C) 2013 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mtdsplit.h" -+ -+#define SEAMA_MAGIC 0x5EA3A417 -+#define SEAMA_NR_PARTS 2 -+#define SEAMA_MIN_ROOTFS_OFFS 0x80000 /* 512KiB */ -+ -+struct seama_header { -+ __be32 magic; /* should always be SEAMA_MAGIC. */ -+ __be16 reserved; /* reserved for */ -+ __be16 metasize; /* size of the META data */ -+ __be32 size; /* size of the image */ -+ u8 md5[16]; /* digest */ -+}; -+ -+static int mtdsplit_parse_seama(struct mtd_info *master, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct seama_header hdr; -+ size_t hdr_len, retlen, kernel_ent_size; -+ size_t rootfs_offset; -+ struct mtd_partition *parts; -+ enum mtdsplit_part_type type; -+ int err; -+ -+ hdr_len = sizeof(hdr); -+ err = mtd_read(master, 0, hdr_len, &retlen, (void *) &hdr); -+ if (err) -+ return err; -+ -+ if (retlen != hdr_len) -+ return -EIO; -+ -+ /* sanity checks */ -+ if (be32_to_cpu(hdr.magic) != SEAMA_MAGIC) -+ return -EINVAL; -+ -+ kernel_ent_size = hdr_len + be32_to_cpu(hdr.size) + -+ be16_to_cpu(hdr.metasize); -+ if (kernel_ent_size > master->size) -+ return -EINVAL; -+ -+ /* Check for the rootfs right after Seama entity with a kernel. */ -+ err = mtd_check_rootfs_magic(master, kernel_ent_size, &type); -+ if (!err) { -+ rootfs_offset = kernel_ent_size; -+ } else { -+ /* -+ * On some devices firmware entity might contain both: kernel -+ * and rootfs. We can't determine kernel size so we just have to -+ * look for rootfs magic. -+ * Start the search from an arbitrary offset. -+ */ -+ err = mtd_find_rootfs_from(master, SEAMA_MIN_ROOTFS_OFFS, -+ master->size, &rootfs_offset, &type); -+ if (err) -+ return err; -+ } -+ -+ parts = kzalloc(SEAMA_NR_PARTS * sizeof(*parts), GFP_KERNEL); -+ if (!parts) -+ return -ENOMEM; -+ -+ parts[0].name = KERNEL_PART_NAME; -+ parts[0].offset = sizeof hdr + be16_to_cpu(hdr.metasize); -+ parts[0].size = rootfs_offset - parts[0].offset; -+ -+ if (type == MTDSPLIT_PART_TYPE_UBI) -+ parts[1].name = UBI_PART_NAME; -+ else -+ parts[1].name = ROOTFS_PART_NAME; -+ parts[1].offset = rootfs_offset; -+ parts[1].size = master->size - rootfs_offset; -+ -+ *pparts = parts; -+ return SEAMA_NR_PARTS; -+} -+ -+static const struct of_device_id mtdsplit_seama_of_match_table[] = { -+ { .compatible = "seama" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, mtdsplit_seama_of_match_table); -+ -+static struct mtd_part_parser mtdsplit_seama_parser = { -+ .owner = THIS_MODULE, -+ .name = "seama-fw", -+ .of_match_table = mtdsplit_seama_of_match_table, -+ .parse_fn = mtdsplit_parse_seama, -+ .type = MTD_PARSER_TYPE_FIRMWARE, -+}; -+ -+static int __init mtdsplit_seama_init(void) -+{ -+ register_mtd_parser(&mtdsplit_seama_parser); -+ -+ return 0; -+} -+ -+subsys_initcall(mtdsplit_seama_init); -diff --git a/drivers/mtd/mtdsplit/mtdsplit_seil.c b/drivers/mtd/mtdsplit/mtdsplit_seil.c -new file mode 100644 -index 000000000000..e58bb49b23fc ---- /dev/null -+++ b/drivers/mtd/mtdsplit/mtdsplit_seil.c -@@ -0,0 +1,191 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* a mtdsplit driver for IIJ SEIL devices */ -+ -+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mtdsplit.h" -+ -+#define NR_PARTS 2 -+#define SEIL_VFMT 1 -+#define LDR_ENV_PART_NAME "bootloader-env" -+#define LDR_ENV_KEY_BOOTDEV "BOOTDEV" -+ -+struct seil_header { -+ uint64_t id; /* Identifier */ -+ uint8_t copy[80]; /* Copyright */ -+ uint32_t dcrc; /* Data CRC Checksum */ -+ uint32_t vfmt; /* Image Version Format */ -+ uint32_t vmjr; /* Image Version Major */ -+ uint32_t vmnr; /* Image Version Minor */ -+ uint8_t vrel[32]; /* Image Version Release */ -+ uint32_t dxor; /* xor value for Data? */ -+ uint32_t dlen; /* Data Length */ -+}; -+ -+/* -+ * check whether the current mtd device is active or not -+ * -+ * example of BOOTDEV value (IIJ SA-W2): -+ * - "flash" : primary image on flash -+ * - "rescue" : secondary image on flash -+ * - "usb" : usb storage -+ * - "lan0/1" : network -+ */ -+static bool seil_bootdev_is_active(struct device_node *np) -+{ -+ struct mtd_info *env_mtd; -+ char *buf, *var, *value, *eq; -+ const char *devnm; -+ size_t rdlen; -+ int ret; -+ -+ /* -+ * read bootdev name of the partition -+ * if doesn't exist, return true and skip checking of active device -+ */ -+ ret = of_property_read_string(np, "iij,bootdev-name", &devnm); -+ if (ret == -EINVAL) -+ return true; -+ else if (ret < 0) -+ return false; -+ -+ env_mtd = get_mtd_device_nm(LDR_ENV_PART_NAME); -+ if (IS_ERR(env_mtd)) { -+ pr_err("failed to get mtd device \"%s\"", LDR_ENV_PART_NAME); -+ return false; -+ } -+ -+ buf = vmalloc(env_mtd->size); -+ if (!buf) -+ return false; -+ -+ ret = mtd_read(env_mtd, 0, env_mtd->size, &rdlen, buf); -+ if (ret || rdlen != env_mtd->size) { -+ pr_err("failed to read from mtd (%d)\n", ret); -+ ret = 0; -+ goto exit_vfree; -+ } -+ -+ for (var = buf, ret = false; -+ var < buf + env_mtd->size && *var; -+ var = value + strlen(value) + 1) { -+ eq = strchr(var, '='); -+ if (!eq) -+ break; -+ *eq = '\0'; -+ value = eq + 1; -+ -+ pr_debug("ENV: %s=%s\n", var, value); -+ if (!strcmp(var, LDR_ENV_KEY_BOOTDEV)) { -+ ret = !strcmp(devnm, value); -+ break; -+ } -+ } -+ -+exit_vfree: -+ vfree(buf); -+ -+ return ret; -+} -+ -+static int mtdsplit_parse_seil_fw(struct mtd_info *master, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct device_node *np = mtd_get_of_node(master); -+ struct mtd_partition *parts; -+ struct seil_header header; -+ size_t image_size = 0; -+ size_t rootfs_offset; -+ size_t hdrlen = sizeof(header); -+ size_t retlen; -+ int ret; -+ u64 id; -+ -+ if (!seil_bootdev_is_active(np)) -+ return -ENODEV; -+ -+ ret = of_property_read_u64(np, "iij,seil-id", &id); -+ if (ret) { -+ pr_err("failed to get iij,seil-id from dt\n"); -+ return ret; -+ } -+ pr_debug("got seil-id=0x%016llx from dt\n", id); -+ -+ parts = kcalloc(NR_PARTS, sizeof(*parts), GFP_KERNEL); -+ if (!parts) -+ return -ENOMEM; -+ -+ ret = mtd_read(master, 0, hdrlen, &retlen, (void *)&header); -+ if (ret) -+ goto err_free_parts; -+ -+ if (retlen != hdrlen) { -+ ret = -EIO; -+ goto err_free_parts; -+ } -+ -+ if (be64_to_cpu(header.id) != id || -+ be32_to_cpu(header.vfmt) != SEIL_VFMT) { -+ pr_debug("no valid seil image found in \"%s\"\n", master->name); -+ ret = -ENODEV; -+ goto err_free_parts; -+ } -+ -+ image_size = hdrlen + be32_to_cpu(header.dlen); -+ if (image_size > master->size) { -+ pr_err("seil image exceeds MTD device \"%s\"\n", master->name); -+ ret = -EINVAL; -+ goto err_free_parts; -+ } -+ -+ /* find the roots after the seil image */ -+ ret = mtd_find_rootfs_from(master, image_size, -+ master->size, &rootfs_offset, NULL); -+ if (ret || (master->size - rootfs_offset) == 0) { -+ pr_debug("no rootfs after seil image in \"%s\"\n", -+ master->name); -+ ret = -ENODEV; -+ goto err_free_parts; -+ } -+ -+ parts[0].name = KERNEL_PART_NAME; -+ parts[0].offset = 0; -+ parts[0].size = rootfs_offset; -+ -+ parts[1].name = ROOTFS_PART_NAME; -+ parts[1].offset = rootfs_offset; -+ parts[1].size = master->size - rootfs_offset; -+ -+ *pparts = parts; -+ return NR_PARTS; -+ -+err_free_parts: -+ kfree(parts); -+ return ret; -+} -+ -+static const struct of_device_id mtdsplit_seil_fw_of_match_table[] = { -+ { .compatible = "iij,seil-firmware" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, mtdsplit_seil_fw_of_match_table); -+ -+static struct mtd_part_parser mtdsplit_seil_fw_parser = { -+ .owner = THIS_MODULE, -+ .name = "seil-fw", -+ .of_match_table = mtdsplit_seil_fw_of_match_table, -+ .parse_fn = mtdsplit_parse_seil_fw, -+ .type = MTD_PARSER_TYPE_FIRMWARE, -+}; -+ -+module_mtd_part_parser(mtdsplit_seil_fw_parser); -diff --git a/drivers/mtd/mtdsplit/mtdsplit_squashfs.c b/drivers/mtd/mtdsplit/mtdsplit_squashfs.c -new file mode 100644 -index 000000000000..f6353da65b0e ---- /dev/null -+++ b/drivers/mtd/mtdsplit/mtdsplit_squashfs.c -@@ -0,0 +1,72 @@ -+/* -+ * Copyright (C) 2013 Felix Fietkau -+ * Copyright (C) 2013 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+ -+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mtdsplit.h" -+ -+static int -+mtdsplit_parse_squashfs(struct mtd_info *master, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct mtd_partition *part; -+ struct mtd_info *parent_mtd; -+ size_t part_offset; -+ size_t squashfs_len; -+ int err; -+ -+ err = mtd_get_squashfs_len(master, 0, &squashfs_len); -+ if (err) -+ return err; -+ -+ parent_mtd = mtd_get_master(master); -+ part_offset = mtdpart_get_offset(master); -+ -+ part = kzalloc(sizeof(*part), GFP_KERNEL); -+ if (!part) { -+ pr_alert("unable to allocate memory for \"%s\" partition\n", -+ ROOTFS_SPLIT_NAME); -+ return -ENOMEM; -+ } -+ -+ part->name = ROOTFS_SPLIT_NAME; -+ part->offset = mtd_roundup_to_eb(part_offset + squashfs_len, -+ parent_mtd) - part_offset; -+ part->size = mtd_rounddown_to_eb(master->size - part->offset, master); -+ -+ *pparts = part; -+ return 1; -+} -+ -+static struct mtd_part_parser mtdsplit_squashfs_parser = { -+ .owner = THIS_MODULE, -+ .name = "squashfs-split", -+ .parse_fn = mtdsplit_parse_squashfs, -+ .type = MTD_PARSER_TYPE_ROOTFS, -+}; -+ -+static int __init mtdsplit_squashfs_init(void) -+{ -+ register_mtd_parser(&mtdsplit_squashfs_parser); -+ -+ return 0; -+} -+ -+subsys_initcall(mtdsplit_squashfs_init); -diff --git a/drivers/mtd/mtdsplit/mtdsplit_tplink.c b/drivers/mtd/mtdsplit/mtdsplit_tplink.c -new file mode 100644 -index 000000000000..8909c107a094 ---- /dev/null -+++ b/drivers/mtd/mtdsplit/mtdsplit_tplink.c -@@ -0,0 +1,176 @@ -+/* -+ * Copyright (C) 2013 Gabor Juhos -+ * Copyright (C) 2014 Felix Fietkau -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mtdsplit.h" -+ -+#define TPLINK_NR_PARTS 2 -+#define TPLINK_MIN_ROOTFS_OFFS 0x80000 /* 512KiB */ -+ -+#define MD5SUM_LEN 16 -+ -+struct fw_v1 { -+ char vendor_name[24]; -+ char fw_version[36]; -+ uint32_t hw_id; /* hardware id */ -+ uint32_t hw_rev; /* hardware revision */ -+ uint32_t unk1; -+ uint8_t md5sum1[MD5SUM_LEN]; -+ uint32_t unk2; -+ uint8_t md5sum2[MD5SUM_LEN]; -+ uint32_t unk3; -+ uint32_t kernel_la; /* kernel load address */ -+ uint32_t kernel_ep; /* kernel entry point */ -+ uint32_t fw_length; /* total length of the firmware */ -+ uint32_t kernel_ofs; /* kernel data offset */ -+ uint32_t kernel_len; /* kernel data length */ -+ uint32_t rootfs_ofs; /* rootfs data offset */ -+ uint32_t rootfs_len; /* rootfs data length */ -+ uint32_t boot_ofs; /* bootloader data offset */ -+ uint32_t boot_len; /* bootloader data length */ -+ uint8_t pad[360]; -+} __attribute__ ((packed)); -+ -+struct fw_v2 { -+ char fw_version[48]; /* 0x04: fw version string */ -+ uint32_t hw_id; /* 0x34: hardware id */ -+ uint32_t hw_rev; /* 0x38: FIXME: hardware revision? */ -+ uint32_t unk1; /* 0x3c: 0x00000000 */ -+ uint8_t md5sum1[MD5SUM_LEN]; /* 0x40 */ -+ uint32_t unk2; /* 0x50: 0x00000000 */ -+ uint8_t md5sum2[MD5SUM_LEN]; /* 0x54 */ -+ uint32_t unk3; /* 0x64: 0xffffffff */ -+ -+ uint32_t kernel_la; /* 0x68: kernel load address */ -+ uint32_t kernel_ep; /* 0x6c: kernel entry point */ -+ uint32_t fw_length; /* 0x70: total length of the image */ -+ uint32_t kernel_ofs; /* 0x74: kernel data offset */ -+ uint32_t kernel_len; /* 0x78: kernel data length */ -+ uint32_t rootfs_ofs; /* 0x7c: rootfs data offset */ -+ uint32_t rootfs_len; /* 0x80: rootfs data length */ -+ uint32_t boot_ofs; /* 0x84: FIXME: seems to be unused */ -+ uint32_t boot_len; /* 0x88: FIXME: seems to be unused */ -+ uint16_t unk4; /* 0x8c: 0x55aa */ -+ uint8_t sver_hi; /* 0x8e */ -+ uint8_t sver_lo; /* 0x8f */ -+ uint8_t unk5; /* 0x90: magic: 0xa5 */ -+ uint8_t ver_hi; /* 0x91 */ -+ uint8_t ver_mid; /* 0x92 */ -+ uint8_t ver_lo; /* 0x93 */ -+ uint8_t pad[364]; -+} __attribute__ ((packed)); -+ -+struct tplink_fw_header { -+ uint32_t version; -+ union { -+ struct fw_v1 v1; -+ struct fw_v2 v2; -+ }; -+}; -+ -+static int mtdsplit_parse_tplink(struct mtd_info *master, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct tplink_fw_header hdr; -+ size_t hdr_len, retlen, kernel_size; -+ size_t rootfs_offset; -+ struct mtd_partition *parts; -+ int err; -+ -+ hdr_len = sizeof(hdr); -+ err = mtd_read(master, 0, hdr_len, &retlen, (void *) &hdr); -+ if (err) -+ return err; -+ -+ if (retlen != hdr_len) -+ return -EIO; -+ -+ switch (le32_to_cpu(hdr.version)) { -+ case 1: -+ if (be32_to_cpu(hdr.v1.kernel_ofs) != sizeof(hdr)) -+ return -EINVAL; -+ -+ kernel_size = sizeof(hdr) + be32_to_cpu(hdr.v1.kernel_len); -+ rootfs_offset = be32_to_cpu(hdr.v1.rootfs_ofs); -+ break; -+ case 2: -+ case 3: -+ if (be32_to_cpu(hdr.v2.kernel_ofs) != sizeof(hdr)) -+ return -EINVAL; -+ -+ kernel_size = sizeof(hdr) + be32_to_cpu(hdr.v2.kernel_len); -+ rootfs_offset = be32_to_cpu(hdr.v2.rootfs_ofs); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ if (kernel_size > master->size) -+ return -EINVAL; -+ -+ /* Find the rootfs */ -+ err = mtd_check_rootfs_magic(master, rootfs_offset, NULL); -+ if (err) { -+ /* -+ * The size in the header might cover the rootfs as well. -+ * Start the search from an arbitrary offset. -+ */ -+ err = mtd_find_rootfs_from(master, TPLINK_MIN_ROOTFS_OFFS, -+ master->size, &rootfs_offset, NULL); -+ if (err) -+ return err; -+ } -+ -+ parts = kzalloc(TPLINK_NR_PARTS * sizeof(*parts), GFP_KERNEL); -+ if (!parts) -+ return -ENOMEM; -+ -+ parts[0].name = KERNEL_PART_NAME; -+ parts[0].offset = 0; -+ parts[0].size = kernel_size; -+ -+ parts[1].name = ROOTFS_PART_NAME; -+ parts[1].offset = rootfs_offset; -+ parts[1].size = master->size - rootfs_offset; -+ -+ *pparts = parts; -+ return TPLINK_NR_PARTS; -+} -+ -+static const struct of_device_id mtdsplit_tplink_of_match_table[] = { -+ { .compatible = "tplink,firmware" }, -+ {}, -+}; -+ -+static struct mtd_part_parser mtdsplit_tplink_parser = { -+ .owner = THIS_MODULE, -+ .name = "tplink-fw", -+ .of_match_table = mtdsplit_tplink_of_match_table, -+ .parse_fn = mtdsplit_parse_tplink, -+ .type = MTD_PARSER_TYPE_FIRMWARE, -+}; -+ -+static int __init mtdsplit_tplink_init(void) -+{ -+ register_mtd_parser(&mtdsplit_tplink_parser); -+ -+ return 0; -+} -+ -+subsys_initcall(mtdsplit_tplink_init); -diff --git a/drivers/mtd/mtdsplit/mtdsplit_trx.c b/drivers/mtd/mtdsplit/mtdsplit_trx.c -new file mode 100644 -index 000000000000..b853ec9e5283 ---- /dev/null -+++ b/drivers/mtd/mtdsplit/mtdsplit_trx.c -@@ -0,0 +1,155 @@ -+/* -+ * Copyright (C) 2013 Gabor Juhos -+ * Copyright (C) 2014 Felix Fietkau -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+ -+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mtdsplit.h" -+ -+#define TRX_MAGIC 0x30524448 /* "HDR0" */ -+ -+struct trx_header { -+ __le32 magic; -+ __le32 len; -+ __le32 crc32; -+ __le32 flag_version; -+ __le32 offset[4]; -+}; -+ -+static int -+read_trx_header(struct mtd_info *mtd, size_t offset, -+ struct trx_header *header) -+{ -+ size_t header_len; -+ size_t retlen; -+ int ret; -+ -+ header_len = sizeof(*header); -+ ret = mtd_read(mtd, offset, header_len, &retlen, -+ (unsigned char *) header); -+ if (ret) { -+ pr_debug("read error in \"%s\"\n", mtd->name); -+ return ret; -+ } -+ -+ if (retlen != header_len) { -+ pr_debug("short read in \"%s\"\n", mtd->name); -+ return -EIO; -+ } -+ -+ return 0; -+} -+ -+static int -+mtdsplit_parse_trx(struct mtd_info *master, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct mtd_partition *parts; -+ struct trx_header hdr; -+ int nr_parts; -+ size_t offset; -+ size_t trx_offset; -+ size_t trx_size = 0; -+ size_t rootfs_offset; -+ size_t rootfs_size = 0; -+ int ret; -+ -+ nr_parts = 2; -+ parts = kzalloc(nr_parts * sizeof(*parts), GFP_KERNEL); -+ if (!parts) -+ return -ENOMEM; -+ -+ /* find trx image on erase block boundaries */ -+ for (offset = 0; offset < master->size; offset += master->erasesize) { -+ trx_size = 0; -+ -+ ret = read_trx_header(master, offset, &hdr); -+ if (ret) -+ continue; -+ -+ if (hdr.magic != cpu_to_le32(TRX_MAGIC)) { -+ pr_debug("no valid trx header found in \"%s\" at offset %llx\n", -+ master->name, (unsigned long long) offset); -+ continue; -+ } -+ -+ trx_size = le32_to_cpu(hdr.len); -+ if ((offset + trx_size) > master->size) { -+ pr_debug("trx image exceeds MTD device \"%s\"\n", -+ master->name); -+ continue; -+ } -+ break; -+ } -+ -+ if (trx_size == 0) { -+ pr_debug("no trx header found in \"%s\"\n", master->name); -+ ret = -ENODEV; -+ goto err; -+ } -+ -+ trx_offset = offset + hdr.offset[0]; -+ rootfs_offset = offset + hdr.offset[1]; -+ rootfs_size = master->size - rootfs_offset; -+ trx_size = rootfs_offset - trx_offset; -+ -+ if (rootfs_size == 0) { -+ pr_debug("no rootfs found in \"%s\"\n", master->name); -+ ret = -ENODEV; -+ goto err; -+ } -+ -+ parts[0].name = KERNEL_PART_NAME; -+ parts[0].offset = trx_offset; -+ parts[0].size = trx_size; -+ -+ parts[1].name = ROOTFS_PART_NAME; -+ parts[1].offset = rootfs_offset; -+ parts[1].size = rootfs_size; -+ -+ *pparts = parts; -+ return nr_parts; -+ -+err: -+ kfree(parts); -+ return ret; -+} -+ -+static const struct of_device_id trx_parser_of_match_table[] = { -+ { .compatible = "openwrt,trx" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, trx_parser_of_match_table); -+ -+static struct mtd_part_parser trx_parser = { -+ .owner = THIS_MODULE, -+ .name = "trx-fw", -+ .of_match_table = trx_parser_of_match_table, -+ .parse_fn = mtdsplit_parse_trx, -+ .type = MTD_PARSER_TYPE_FIRMWARE, -+}; -+ -+static int __init mtdsplit_trx_init(void) -+{ -+ register_mtd_parser(&trx_parser); -+ -+ return 0; -+} -+ -+module_init(mtdsplit_trx_init); -diff --git a/drivers/mtd/mtdsplit/mtdsplit_uimage.c b/drivers/mtd/mtdsplit/mtdsplit_uimage.c -new file mode 100644 -index 000000000000..0d9685490030 ---- /dev/null -+++ b/drivers/mtd/mtdsplit/mtdsplit_uimage.c -@@ -0,0 +1,282 @@ -+/* -+ * Copyright (C) 2013 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+ -+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mtdsplit.h" -+ -+/* -+ * Legacy format image header, -+ * all data in network byte order (aka natural aka bigendian). -+ */ -+struct uimage_header { -+ uint32_t ih_magic; /* Image Header Magic Number */ -+ uint32_t ih_hcrc; /* Image Header CRC Checksum */ -+ uint32_t ih_time; /* Image Creation Timestamp */ -+ uint32_t ih_size; /* Image Data Size */ -+ uint32_t ih_load; /* Data Load Address */ -+ uint32_t ih_ep; /* Entry Point Address */ -+ uint32_t ih_dcrc; /* Image Data CRC Checksum */ -+ uint8_t ih_os; /* Operating System */ -+ uint8_t ih_arch; /* CPU architecture */ -+ uint8_t ih_type; /* Image Type */ -+ uint8_t ih_comp; /* Compression Type */ -+ uint8_t ih_name[IH_NMLEN]; /* Image Name */ -+}; -+ -+static int -+read_uimage_header(struct mtd_info *mtd, size_t offset, u_char *buf, -+ size_t header_len) -+{ -+ size_t retlen; -+ int ret; -+ -+ ret = mtd_read(mtd, offset, header_len, &retlen, buf); -+ if (ret) { -+ pr_debug("read error in \"%s\"\n", mtd->name); -+ return ret; -+ } -+ -+ if (retlen != header_len) { -+ pr_debug("short read in \"%s\"\n", mtd->name); -+ return -EIO; -+ } -+ -+ return 0; -+} -+ -+static void uimage_parse_dt(struct mtd_info *master, int *extralen, -+ u32 *ih_magic, u32 *ih_type, -+ u32 *header_offset, u32 *part_magic) -+{ -+ struct device_node *np = mtd_get_of_node(master); -+ -+ if (!np || !of_device_is_compatible(np, "openwrt,uimage")) -+ return; -+ -+ if (!of_property_read_u32(np, "openwrt,padding", extralen)) -+ pr_debug("got openwrt,padding=%d from device-tree\n", *extralen); -+ if (!of_property_read_u32(np, "openwrt,ih-magic", ih_magic)) -+ pr_debug("got openwrt,ih-magic=%08x from device-tree\n", *ih_magic); -+ if (!of_property_read_u32(np, "openwrt,ih-type", ih_type)) -+ pr_debug("got openwrt,ih-type=%08x from device-tree\n", *ih_type); -+ if (!of_property_read_u32(np, "openwrt,offset", header_offset)) -+ pr_debug("got ih-start=%u from device-tree\n", *header_offset); -+ if (!of_property_read_u32(np, "openwrt,partition-magic", part_magic)) -+ pr_debug("got openwrt,partition-magic=%08x from device-tree\n", *part_magic); -+} -+ -+static ssize_t uimage_verify_default(u_char *buf, u32 ih_magic, u32 ih_type) -+{ -+ struct uimage_header *header = (struct uimage_header *)buf; -+ -+ /* default sanity checks */ -+ if (be32_to_cpu(header->ih_magic) != ih_magic) { -+ pr_debug("invalid uImage magic: %08x != %08x\n", -+ be32_to_cpu(header->ih_magic), ih_magic); -+ return -EINVAL; -+ } -+ -+ if (header->ih_os != IH_OS_LINUX) { -+ pr_debug("invalid uImage OS: %08x != %08x\n", -+ be32_to_cpu(header->ih_os), IH_OS_LINUX); -+ return -EINVAL; -+ } -+ -+ if (header->ih_type != ih_type) { -+ pr_debug("invalid uImage type: %08x != %08x\n", -+ be32_to_cpu(header->ih_type), ih_type); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+/** -+ * __mtdsplit_parse_uimage - scan partition and create kernel + rootfs parts -+ * -+ * @find_header: function to call for a block of data that will return offset -+ * and tail padding length of a valid uImage header if found -+ */ -+static int __mtdsplit_parse_uimage(struct mtd_info *master, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct mtd_partition *parts; -+ u_char *buf; -+ int nr_parts; -+ size_t offset; -+ size_t uimage_offset; -+ size_t uimage_size = 0; -+ size_t rootfs_offset; -+ size_t rootfs_size = 0; -+ size_t buflen; -+ int uimage_part, rf_part; -+ int ret; -+ int extralen = 0; -+ u32 ih_magic = IH_MAGIC; -+ u32 ih_type = IH_TYPE_KERNEL; -+ u32 header_offset = 0; -+ u32 part_magic = 0; -+ enum mtdsplit_part_type type; -+ -+ nr_parts = 2; -+ parts = kzalloc(nr_parts * sizeof(*parts), GFP_KERNEL); -+ if (!parts) -+ return -ENOMEM; -+ -+ uimage_parse_dt(master, &extralen, &ih_magic, &ih_type, &header_offset, &part_magic); -+ buflen = sizeof(struct uimage_header) + header_offset; -+ buf = vmalloc(buflen); -+ if (!buf) { -+ ret = -ENOMEM; -+ goto err_free_parts; -+ } -+ -+ /* find uImage on erase block boundaries */ -+ for (offset = 0; offset < master->size; offset += master->erasesize) { -+ struct uimage_header *header; -+ -+ uimage_size = 0; -+ -+ ret = read_uimage_header(master, offset, buf, buflen); -+ if (ret) -+ continue; -+ -+ /* verify optional partition magic before uimage header */ -+ if (header_offset && part_magic && (be32_to_cpu(*(u32 *)buf) != part_magic)) -+ continue; -+ -+ ret = uimage_verify_default(buf + header_offset, ih_magic, ih_type); -+ if (ret < 0) { -+ pr_debug("no valid uImage found in \"%s\" at offset %llx\n", -+ master->name, (unsigned long long) offset); -+ continue; -+ } -+ -+ header = (struct uimage_header *)(buf + header_offset); -+ -+ uimage_size = sizeof(*header) + -+ be32_to_cpu(header->ih_size) + header_offset + extralen; -+ -+ if ((offset + uimage_size) > master->size) { -+ pr_debug("uImage exceeds MTD device \"%s\"\n", -+ master->name); -+ continue; -+ } -+ break; -+ } -+ -+ if (uimage_size == 0) { -+ pr_info("no uImage found in \"%s\"\n", master->name); -+ ret = 0; -+ goto err_free_buf; -+ } -+ -+ uimage_offset = offset; -+ -+ if (uimage_offset == 0) { -+ uimage_part = 0; -+ rf_part = 1; -+ -+ /* find the roots after the uImage */ -+ ret = mtd_find_rootfs_from(master, uimage_offset + uimage_size, -+ master->size, &rootfs_offset, &type); -+ if (ret) { -+ pr_info("no rootfs after uImage in \"%s\"\n", master->name); -+ ret = 0; -+ goto err_free_buf; -+ } -+ -+ rootfs_size = master->size - rootfs_offset; -+ uimage_size = rootfs_offset - uimage_offset; -+ } else { -+ rf_part = 0; -+ uimage_part = 1; -+ -+ /* check rootfs presence at offset 0 */ -+ ret = mtd_check_rootfs_magic(master, 0, &type); -+ if (ret) { -+ pr_info("no rootfs before uImage in \"%s\"\n", master->name); -+ ret = 0; -+ goto err_free_buf; -+ } -+ -+ rootfs_offset = 0; -+ rootfs_size = uimage_offset; -+ } -+ -+ if (rootfs_size == 0) { -+ pr_debug("no rootfs found in \"%s\"\n", master->name); -+ ret = -ENODEV; -+ goto err_free_buf; -+ } -+ -+ parts[uimage_part].name = KERNEL_PART_NAME; -+ parts[uimage_part].offset = uimage_offset; -+ parts[uimage_part].size = uimage_size; -+ -+ if (type == MTDSPLIT_PART_TYPE_UBI) -+ parts[rf_part].name = UBI_PART_NAME; -+ else -+ parts[rf_part].name = ROOTFS_PART_NAME; -+ parts[rf_part].offset = rootfs_offset; -+ parts[rf_part].size = rootfs_size; -+ -+ vfree(buf); -+ -+ *pparts = parts; -+ return nr_parts; -+ -+err_free_buf: -+ vfree(buf); -+ -+err_free_parts: -+ kfree(parts); -+ return ret; -+} -+ -+static const struct of_device_id mtdsplit_uimage_of_match_table[] = { -+ { .compatible = "denx,uimage" }, -+ { .compatible = "openwrt,uimage" }, -+ {}, -+}; -+ -+static struct mtd_part_parser uimage_generic_parser = { -+ .owner = THIS_MODULE, -+ .name = "uimage-fw", -+ .of_match_table = mtdsplit_uimage_of_match_table, -+ .parse_fn = __mtdsplit_parse_uimage, -+ .type = MTD_PARSER_TYPE_FIRMWARE, -+}; -+ -+/************************************************** -+ * Init -+ **************************************************/ -+ -+static int __init mtdsplit_uimage_init(void) -+{ -+ register_mtd_parser(&uimage_generic_parser); -+ -+ return 0; -+} -+ -+module_init(mtdsplit_uimage_init); -diff --git a/drivers/mtd/mtdsplit/mtdsplit_wrgg.c b/drivers/mtd/mtdsplit/mtdsplit_wrgg.c -new file mode 100644 -index 000000000000..dfd6058ae7e4 ---- /dev/null -+++ b/drivers/mtd/mtdsplit/mtdsplit_wrgg.c -@@ -0,0 +1,142 @@ -+/* -+ * Copyright (C) 2013 Gabor Juhos -+ * Copyright (C) 2014 Felix Fietkau -+ * Copyright (C) 2016 Stijn Tintel -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mtdsplit.h" -+ -+#define WRGG_NR_PARTS 2 -+#define WRGG_MIN_ROOTFS_OFFS 0x80000 /* 512KiB */ -+#define WRGG03_MAGIC 0x20080321 -+#define WRG_MAGIC 0x20040220 -+ -+struct wrgg03_header { -+ char signature[32]; -+ uint32_t magic1; -+ uint32_t magic2; -+ char version[16]; -+ char model[16]; -+ uint32_t flag[2]; -+ uint32_t reserve[2]; -+ char buildno[16]; -+ uint32_t size; -+ uint32_t offset; -+ char devname[32]; -+ char digest[16]; -+} __attribute__ ((packed)); -+ -+struct wrg_header { -+ char signature[32]; -+ uint32_t magic1; -+ uint32_t magic2; -+ uint32_t size; -+ uint32_t offset; -+ char devname[32]; -+ char digest[16]; -+} __attribute__ ((packed)); -+ -+ -+static int mtdsplit_parse_wrgg(struct mtd_info *master, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct wrgg03_header hdr; -+ size_t hdr_len, retlen, kernel_ent_size; -+ size_t rootfs_offset; -+ struct mtd_partition *parts; -+ enum mtdsplit_part_type type; -+ int err; -+ -+ hdr_len = sizeof(hdr); -+ err = mtd_read(master, 0, hdr_len, &retlen, (void *) &hdr); -+ if (err) -+ return err; -+ -+ if (retlen != hdr_len) -+ return -EIO; -+ -+ /* sanity checks */ -+ if (le32_to_cpu(hdr.magic1) == WRGG03_MAGIC) { -+ kernel_ent_size = hdr_len + be32_to_cpu(hdr.size); -+ /* -+ * If this becomes silly big it's probably because the -+ * WRGG image is little-endian. -+ */ -+ if (kernel_ent_size > master->size) -+ kernel_ent_size = hdr_len + le32_to_cpu(hdr.size); -+ -+ /* Now what ?! It's neither */ -+ if (kernel_ent_size > master->size) -+ return -EINVAL; -+ } else if (le32_to_cpu(hdr.magic1) == WRG_MAGIC) { -+ kernel_ent_size = sizeof(struct wrg_header) + le32_to_cpu( -+ ((struct wrg_header*)&hdr)->size); -+ } else { -+ return -EINVAL; -+ } -+ -+ if (kernel_ent_size > master->size) -+ return -EINVAL; -+ -+ /* -+ * The size in the header covers the rootfs as well. -+ * Start the search from an arbitrary offset. -+ */ -+ err = mtd_find_rootfs_from(master, WRGG_MIN_ROOTFS_OFFS, -+ master->size, &rootfs_offset, &type); -+ if (err) -+ return err; -+ -+ parts = kzalloc(WRGG_NR_PARTS * sizeof(*parts), GFP_KERNEL); -+ if (!parts) -+ return -ENOMEM; -+ -+ parts[0].name = KERNEL_PART_NAME; -+ parts[0].offset = 0; -+ parts[0].size = rootfs_offset; -+ -+ parts[1].name = ROOTFS_PART_NAME; -+ parts[1].offset = rootfs_offset; -+ parts[1].size = master->size - rootfs_offset; -+ -+ *pparts = parts; -+ return WRGG_NR_PARTS; -+} -+ -+static const struct of_device_id mtdsplit_wrgg_of_match_table[] = { -+ { .compatible = "wrg" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, mtdsplit_wrgg_of_match_table); -+ -+static struct mtd_part_parser mtdsplit_wrgg_parser = { -+ .owner = THIS_MODULE, -+ .name = "wrgg-fw", -+ .of_match_table = mtdsplit_wrgg_of_match_table, -+ .parse_fn = mtdsplit_parse_wrgg, -+ .type = MTD_PARSER_TYPE_FIRMWARE, -+}; -+ -+static int __init mtdsplit_wrgg_init(void) -+{ -+ register_mtd_parser(&mtdsplit_wrgg_parser); -+ -+ return 0; -+} -+ -+subsys_initcall(mtdsplit_wrgg_init); -diff --git a/drivers/mtd/nand/mtk_bmt.c b/drivers/mtd/nand/mtk_bmt.c -new file mode 100644 -index 000000000000..063adb50fb60 ---- /dev/null -+++ b/drivers/mtd/nand/mtk_bmt.c -@@ -0,0 +1,474 @@ -+/* -+ * Copyright (c) 2017 MediaTek Inc. -+ * Author: Xiangsheng Hou -+ * Copyright (c) 2020-2022 Felix Fietkau -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include "mtk_bmt.h" -+ -+struct bmt_desc bmtd = {}; -+ -+/* -------- Nand operations wrapper -------- */ -+int bbt_nand_copy(u16 dest_blk, u16 src_blk, loff_t max_offset) -+{ -+ int pages = bmtd.blk_size >> bmtd.pg_shift; -+ loff_t src = (loff_t)src_blk << bmtd.blk_shift; -+ loff_t dest = (loff_t)dest_blk << bmtd.blk_shift; -+ loff_t offset = 0; -+ uint8_t oob[64]; -+ int i, ret; -+ -+ for (i = 0; i < pages; i++) { -+ struct mtd_oob_ops rd_ops = { -+ .mode = MTD_OPS_PLACE_OOB, -+ .oobbuf = oob, -+ .ooblen = min_t(int, bmtd.mtd->oobsize / pages, sizeof(oob)), -+ .datbuf = bmtd.data_buf, -+ .len = bmtd.pg_size, -+ }; -+ struct mtd_oob_ops wr_ops = { -+ .mode = MTD_OPS_PLACE_OOB, -+ .oobbuf = oob, -+ .datbuf = bmtd.data_buf, -+ .len = bmtd.pg_size, -+ }; -+ -+ if (offset >= max_offset) -+ break; -+ -+ ret = bmtd._read_oob(bmtd.mtd, src + offset, &rd_ops); -+ if (ret < 0 && !mtd_is_bitflip(ret)) -+ return ret; -+ -+ if (!rd_ops.retlen) -+ break; -+ -+ ret = bmtd._write_oob(bmtd.mtd, dest + offset, &wr_ops); -+ if (ret < 0) -+ return ret; -+ -+ wr_ops.ooblen = rd_ops.oobretlen; -+ offset += rd_ops.retlen; -+ } -+ -+ return 0; -+} -+ -+/* -------- Bad Blocks Management -------- */ -+bool mapping_block_in_range(int block, int *start, int *end) -+{ -+ const __be32 *cur = bmtd.remap_range; -+ u32 addr = block << bmtd.blk_shift; -+ int i; -+ -+ if (!cur || !bmtd.remap_range_len) { -+ *start = 0; -+ *end = bmtd.total_blks; -+ return true; -+ } -+ -+ for (i = 0; i < bmtd.remap_range_len; i++, cur += 2) { -+ if (addr < be32_to_cpu(cur[0]) || addr >= be32_to_cpu(cur[1])) -+ continue; -+ -+ *start = be32_to_cpu(cur[0]); -+ *end = be32_to_cpu(cur[1]); -+ return true; -+ } -+ -+ return false; -+} -+ -+static bool -+mtk_bmt_remap_block(u32 block, u32 mapped_block, int copy_len) -+{ -+ int start, end; -+ -+ if (!mapping_block_in_range(block, &start, &end)) -+ return false; -+ -+ return bmtd.ops->remap_block(block, mapped_block, copy_len); -+} -+ -+static int -+mtk_bmt_read(struct mtd_info *mtd, loff_t from, -+ struct mtd_oob_ops *ops) -+{ -+ struct mtd_oob_ops cur_ops = *ops; -+ int retry_count = 0; -+ loff_t cur_from; -+ int ret = 0; -+ int max_bitflips = 0; -+ -+ ops->retlen = 0; -+ ops->oobretlen = 0; -+ -+ while (ops->retlen < ops->len || ops->oobretlen < ops->ooblen) { -+ int cur_ret; -+ -+ u32 offset = from & (bmtd.blk_size - 1); -+ u32 block = from >> bmtd.blk_shift; -+ int cur_block; -+ -+ cur_block = bmtd.ops->get_mapping_block(block); -+ if (cur_block < 0) -+ return -EIO; -+ -+ cur_from = ((loff_t)cur_block << bmtd.blk_shift) + offset; -+ -+ cur_ops.oobretlen = 0; -+ cur_ops.retlen = 0; -+ cur_ops.len = min_t(u32, mtd->erasesize - offset, -+ ops->len - ops->retlen); -+ cur_ret = bmtd._read_oob(mtd, cur_from, &cur_ops); -+ if (cur_ret < 0) -+ ret = cur_ret; -+ else -+ max_bitflips = max_t(int, max_bitflips, cur_ret); -+ if (cur_ret < 0 && !mtd_is_bitflip(cur_ret)) { -+ if (mtk_bmt_remap_block(block, cur_block, mtd->erasesize) && -+ retry_count++ < 10) -+ continue; -+ -+ goto out; -+ } -+ -+ if (mtd->bitflip_threshold && cur_ret >= mtd->bitflip_threshold) -+ mtk_bmt_remap_block(block, cur_block, mtd->erasesize); -+ -+ ops->retlen += cur_ops.retlen; -+ ops->oobretlen += cur_ops.oobretlen; -+ -+ cur_ops.ooboffs = 0; -+ cur_ops.datbuf += cur_ops.retlen; -+ cur_ops.oobbuf += cur_ops.oobretlen; -+ cur_ops.ooblen -= cur_ops.oobretlen; -+ -+ if (!cur_ops.len) -+ cur_ops.len = mtd->erasesize - offset; -+ -+ from += cur_ops.len; -+ retry_count = 0; -+ } -+ -+out: -+ if (ret < 0) -+ return ret; -+ -+ return max_bitflips; -+} -+ -+static int -+mtk_bmt_write(struct mtd_info *mtd, loff_t to, -+ struct mtd_oob_ops *ops) -+{ -+ struct mtd_oob_ops cur_ops = *ops; -+ int retry_count = 0; -+ loff_t cur_to; -+ int ret; -+ -+ ops->retlen = 0; -+ ops->oobretlen = 0; -+ -+ while (ops->retlen < ops->len || ops->oobretlen < ops->ooblen) { -+ u32 offset = to & (bmtd.blk_size - 1); -+ u32 block = to >> bmtd.blk_shift; -+ int cur_block; -+ -+ cur_block = bmtd.ops->get_mapping_block(block); -+ if (cur_block < 0) -+ return -EIO; -+ -+ cur_to = ((loff_t)cur_block << bmtd.blk_shift) + offset; -+ -+ cur_ops.oobretlen = 0; -+ cur_ops.retlen = 0; -+ cur_ops.len = min_t(u32, bmtd.blk_size - offset, -+ ops->len - ops->retlen); -+ ret = bmtd._write_oob(mtd, cur_to, &cur_ops); -+ if (ret < 0) { -+ if (mtk_bmt_remap_block(block, cur_block, offset) && -+ retry_count++ < 10) -+ continue; -+ -+ return ret; -+ } -+ -+ ops->retlen += cur_ops.retlen; -+ ops->oobretlen += cur_ops.oobretlen; -+ -+ cur_ops.ooboffs = 0; -+ cur_ops.datbuf += cur_ops.retlen; -+ cur_ops.oobbuf += cur_ops.oobretlen; -+ cur_ops.ooblen -= cur_ops.oobretlen; -+ -+ if (!cur_ops.len) -+ cur_ops.len = mtd->erasesize - offset; -+ -+ to += cur_ops.len; -+ retry_count = 0; -+ } -+ -+ return 0; -+} -+ -+static int -+mtk_bmt_mtd_erase(struct mtd_info *mtd, struct erase_info *instr) -+{ -+ struct erase_info mapped_instr = { -+ .len = bmtd.blk_size, -+ }; -+ int retry_count = 0; -+ u64 start_addr, end_addr; -+ int ret; -+ u16 orig_block; -+ int block; -+ -+ start_addr = instr->addr & (~mtd->erasesize_mask); -+ end_addr = instr->addr + instr->len; -+ -+ while (start_addr < end_addr) { -+ orig_block = start_addr >> bmtd.blk_shift; -+ block = bmtd.ops->get_mapping_block(orig_block); -+ if (block < 0) -+ return -EIO; -+ mapped_instr.addr = (loff_t)block << bmtd.blk_shift; -+ ret = bmtd._erase(mtd, &mapped_instr); -+ if (ret) { -+ if (mtk_bmt_remap_block(orig_block, block, 0) && -+ retry_count++ < 10) -+ continue; -+ instr->fail_addr = start_addr; -+ break; -+ } -+ start_addr += mtd->erasesize; -+ retry_count = 0; -+ } -+ -+ return ret; -+} -+static int -+mtk_bmt_block_isbad(struct mtd_info *mtd, loff_t ofs) -+{ -+ int retry_count = 0; -+ u16 orig_block = ofs >> bmtd.blk_shift; -+ u16 block; -+ int ret; -+ -+retry: -+ block = bmtd.ops->get_mapping_block(orig_block); -+ ret = bmtd._block_isbad(mtd, (loff_t)block << bmtd.blk_shift); -+ if (ret) { -+ if (mtk_bmt_remap_block(orig_block, block, bmtd.blk_size) && -+ retry_count++ < 10) -+ goto retry; -+ } -+ return ret; -+} -+ -+static int -+mtk_bmt_block_markbad(struct mtd_info *mtd, loff_t ofs) -+{ -+ u16 orig_block = ofs >> bmtd.blk_shift; -+ int block; -+ -+ block = bmtd.ops->get_mapping_block(orig_block); -+ if (block < 0) -+ return -EIO; -+ -+ mtk_bmt_remap_block(orig_block, block, bmtd.blk_size); -+ -+ return bmtd._block_markbad(mtd, (loff_t)block << bmtd.blk_shift); -+} -+ -+static void -+mtk_bmt_replace_ops(struct mtd_info *mtd) -+{ -+ bmtd._read_oob = mtd->_read_oob; -+ bmtd._write_oob = mtd->_write_oob; -+ bmtd._erase = mtd->_erase; -+ bmtd._block_isbad = mtd->_block_isbad; -+ bmtd._block_markbad = mtd->_block_markbad; -+ -+ mtd->_read_oob = mtk_bmt_read; -+ mtd->_write_oob = mtk_bmt_write; -+ mtd->_erase = mtk_bmt_mtd_erase; -+ mtd->_block_isbad = mtk_bmt_block_isbad; -+ mtd->_block_markbad = mtk_bmt_block_markbad; -+} -+ -+static int mtk_bmt_debug_repair(void *data, u64 val) -+{ -+ int block = val >> bmtd.blk_shift; -+ int prev_block, new_block; -+ -+ prev_block = bmtd.ops->get_mapping_block(block); -+ if (prev_block < 0) -+ return -EIO; -+ -+ bmtd.ops->unmap_block(block); -+ new_block = bmtd.ops->get_mapping_block(block); -+ if (new_block < 0) -+ return -EIO; -+ -+ if (prev_block == new_block) -+ return 0; -+ -+ bbt_nand_erase(new_block); -+ bbt_nand_copy(new_block, prev_block, bmtd.blk_size); -+ -+ return 0; -+} -+ -+static int mtk_bmt_debug_mark_good(void *data, u64 val) -+{ -+ bmtd.ops->unmap_block(val >> bmtd.blk_shift); -+ -+ return 0; -+} -+ -+static int mtk_bmt_debug_mark_bad(void *data, u64 val) -+{ -+ u32 block = val >> bmtd.blk_shift; -+ int cur_block; -+ -+ cur_block = bmtd.ops->get_mapping_block(block); -+ if (cur_block < 0) -+ return -EIO; -+ -+ mtk_bmt_remap_block(block, cur_block, bmtd.blk_size); -+ -+ return 0; -+} -+ -+static int mtk_bmt_debug(void *data, u64 val) -+{ -+ return bmtd.ops->debug(data, val); -+} -+ -+ -+DEFINE_DEBUGFS_ATTRIBUTE(fops_repair, NULL, mtk_bmt_debug_repair, "%llu\n"); -+DEFINE_DEBUGFS_ATTRIBUTE(fops_mark_good, NULL, mtk_bmt_debug_mark_good, "%llu\n"); -+DEFINE_DEBUGFS_ATTRIBUTE(fops_mark_bad, NULL, mtk_bmt_debug_mark_bad, "%llu\n"); -+DEFINE_DEBUGFS_ATTRIBUTE(fops_debug, NULL, mtk_bmt_debug, "%llu\n"); -+ -+static void -+mtk_bmt_add_debugfs(void) -+{ -+ struct dentry *dir; -+ -+ dir = bmtd.debugfs_dir = debugfs_create_dir("mtk-bmt", NULL); -+ if (!dir) -+ return; -+ -+ debugfs_create_file_unsafe("repair", S_IWUSR, dir, NULL, &fops_repair); -+ debugfs_create_file_unsafe("mark_good", S_IWUSR, dir, NULL, &fops_mark_good); -+ debugfs_create_file_unsafe("mark_bad", S_IWUSR, dir, NULL, &fops_mark_bad); -+ debugfs_create_file_unsafe("debug", S_IWUSR, dir, NULL, &fops_debug); -+} -+ -+void mtk_bmt_detach(struct mtd_info *mtd) -+{ -+ if (bmtd.mtd != mtd) -+ return; -+ -+ if (bmtd.debugfs_dir) -+ debugfs_remove_recursive(bmtd.debugfs_dir); -+ bmtd.debugfs_dir = NULL; -+ -+ kfree(bmtd.bbt_buf); -+ kfree(bmtd.data_buf); -+ -+ mtd->_read_oob = bmtd._read_oob; -+ mtd->_write_oob = bmtd._write_oob; -+ mtd->_erase = bmtd._erase; -+ mtd->_block_isbad = bmtd._block_isbad; -+ mtd->_block_markbad = bmtd._block_markbad; -+ mtd->size = bmtd.total_blks << bmtd.blk_shift; -+ -+ memset(&bmtd, 0, sizeof(bmtd)); -+} -+ -+ -+int mtk_bmt_attach(struct mtd_info *mtd) -+{ -+ struct device_node *np; -+ int ret = 0; -+ u32 overridden_oobsize = 0; -+ -+ if (bmtd.mtd) -+ return -ENOSPC; -+ -+ np = mtd_get_of_node(mtd); -+ if (!np) -+ return 0; -+ -+ if (of_property_read_bool(np, "mediatek,bmt-v2")) -+ bmtd.ops = &mtk_bmt_v2_ops; -+ else if (of_property_read_bool(np, "mediatek,nmbm")) -+ bmtd.ops = &mtk_bmt_nmbm_ops; -+ else if (of_property_read_bool(np, "mediatek,bbt")) -+ bmtd.ops = &mtk_bmt_bbt_ops; -+ else -+ return 0; -+ -+ bmtd.remap_range = of_get_property(np, "mediatek,bmt-remap-range", -+ &bmtd.remap_range_len); -+ bmtd.remap_range_len /= 8; -+ -+ bmtd.mtd = mtd; -+ mtk_bmt_replace_ops(mtd); -+ -+ if (!of_property_read_u32(np, "mediatek,bmt-mtd-overridden-oobsize", -+ &overridden_oobsize)) -+ if (overridden_oobsize < bmtd.mtd->oobsize) { -+ bmtd.mtd->oobsize = overridden_oobsize; -+ pr_info("NMBM: mtd OOB size has been overridden to %luB\n", -+ (long unsigned int)bmtd.mtd->oobsize); -+ } -+ -+ bmtd.blk_size = mtd->erasesize; -+ bmtd.blk_shift = ffs(bmtd.blk_size) - 1; -+ bmtd.pg_size = mtd->writesize; -+ bmtd.pg_shift = ffs(bmtd.pg_size) - 1; -+ bmtd.total_blks = mtd->size >> bmtd.blk_shift; -+ -+ bmtd.data_buf = kzalloc(bmtd.pg_size + bmtd.mtd->oobsize, GFP_KERNEL); -+ if (!bmtd.data_buf) { -+ pr_info("nand: FATAL ERR: allocate buffer failed!\n"); -+ ret = -1; -+ goto error; -+ } -+ -+ memset(bmtd.data_buf, 0xff, bmtd.pg_size + bmtd.mtd->oobsize); -+ -+ ret = bmtd.ops->init(np); -+ if (ret) -+ goto error; -+ -+ mtk_bmt_add_debugfs(); -+ return 0; -+ -+error: -+ mtk_bmt_detach(mtd); -+ return ret; -+} -+ -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Xiangsheng Hou , Felix Fietkau "); -+MODULE_DESCRIPTION("Bad Block mapping management v2 for MediaTek NAND Flash Driver"); -+ -diff --git a/drivers/mtd/nand/mtk_bmt.h b/drivers/mtd/nand/mtk_bmt.h -new file mode 100644 -index 000000000000..517ff7414f34 ---- /dev/null -+++ b/drivers/mtd/nand/mtk_bmt.h -@@ -0,0 +1,137 @@ -+#ifndef __MTK_BMT_PRIV_H -+#define __MTK_BMT_PRIV_H -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MAIN_SIGNATURE_OFFSET 0 -+#define OOB_SIGNATURE_OFFSET 1 -+ -+#define BBT_LOG(fmt, ...) pr_debug("[BBT][%s|%d] "fmt"\n", __func__, __LINE__, ##__VA_ARGS__) -+ -+struct mtk_bmt_ops { -+ char *sig; -+ unsigned int sig_len; -+ int (*init)(struct device_node *np); -+ bool (*remap_block)(u16 block, u16 mapped_block, int copy_len); -+ void (*unmap_block)(u16 block); -+ int (*get_mapping_block)(int block); -+ int (*debug)(void *data, u64 val); -+}; -+ -+struct bbbt; -+struct nmbm_instance; -+ -+struct bmt_desc { -+ struct mtd_info *mtd; -+ unsigned char *bbt_buf; -+ unsigned char *data_buf; -+ -+ int (*_read_oob) (struct mtd_info *mtd, loff_t from, -+ struct mtd_oob_ops *ops); -+ int (*_write_oob) (struct mtd_info *mtd, loff_t to, -+ struct mtd_oob_ops *ops); -+ int (*_erase) (struct mtd_info *mtd, struct erase_info *instr); -+ int (*_block_isbad) (struct mtd_info *mtd, loff_t ofs); -+ int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs); -+ -+ const struct mtk_bmt_ops *ops; -+ -+ union { -+ struct bbbt *bbt; -+ struct nmbm_instance *ni; -+ }; -+ -+ struct dentry *debugfs_dir; -+ -+ u32 table_size; -+ u32 pg_size; -+ u32 blk_size; -+ u16 pg_shift; -+ u16 blk_shift; -+ /* bbt logical address */ -+ u16 pool_lba; -+ /* bbt physical address */ -+ u16 pool_pba; -+ /* Maximum count of bad blocks that the vendor guaranteed */ -+ u16 bb_max; -+ /* Total blocks of the Nand Chip */ -+ u16 total_blks; -+ /* The block(n) BMT is located at (bmt_tbl[n]) */ -+ u16 bmt_blk_idx; -+ /* How many pages needs to store 'struct bbbt' */ -+ u32 bmt_pgs; -+ -+ const __be32 *remap_range; -+ int remap_range_len; -+ -+ /* to compensate for driver level remapping */ -+ u8 oob_offset; -+}; -+ -+extern struct bmt_desc bmtd; -+extern const struct mtk_bmt_ops mtk_bmt_v2_ops; -+extern const struct mtk_bmt_ops mtk_bmt_bbt_ops; -+extern const struct mtk_bmt_ops mtk_bmt_nmbm_ops; -+ -+static inline u32 blk_pg(u16 block) -+{ -+ return (u32)(block << (bmtd.blk_shift - bmtd.pg_shift)); -+} -+ -+static inline int -+bbt_nand_read(u32 page, unsigned char *dat, int dat_len, -+ unsigned char *fdm, int fdm_len) -+{ -+ struct mtd_oob_ops ops = { -+ .mode = MTD_OPS_PLACE_OOB, -+ .ooboffs = bmtd.oob_offset, -+ .oobbuf = fdm, -+ .ooblen = fdm_len, -+ .datbuf = dat, -+ .len = dat_len, -+ }; -+ int ret; -+ -+ ret = bmtd._read_oob(bmtd.mtd, page << bmtd.pg_shift, &ops); -+ if (ret < 0) -+ return ret; -+ if (ret) -+ pr_info("%s: %d bitflips\n", __func__, ret); -+ return 0; -+} -+ -+static inline int bbt_nand_erase(u16 block) -+{ -+ struct mtd_info *mtd = bmtd.mtd; -+ struct erase_info instr = { -+ .addr = (loff_t)block << bmtd.blk_shift, -+ .len = bmtd.blk_size, -+ }; -+ -+ return bmtd._erase(mtd, &instr); -+} -+ -+static inline int write_bmt(u16 block, unsigned char *dat) -+{ -+ struct mtd_oob_ops ops = { -+ .mode = MTD_OPS_PLACE_OOB, -+ .ooboffs = OOB_SIGNATURE_OFFSET + bmtd.oob_offset, -+ .oobbuf = bmtd.ops->sig, -+ .ooblen = bmtd.ops->sig_len, -+ .datbuf = dat, -+ .len = bmtd.bmt_pgs << bmtd.pg_shift, -+ }; -+ loff_t addr = (loff_t)block << bmtd.blk_shift; -+ -+ return bmtd._write_oob(bmtd.mtd, addr, &ops); -+} -+ -+int bbt_nand_copy(u16 dest_blk, u16 src_blk, loff_t max_offset); -+bool mapping_block_in_range(int block, int *start, int *end); -+ -+#endif -diff --git a/drivers/mtd/nand/mtk_bmt_bbt.c b/drivers/mtd/nand/mtk_bmt_bbt.c -new file mode 100644 -index 000000000000..519e1ed70c7b ---- /dev/null -+++ b/drivers/mtd/nand/mtk_bmt_bbt.c -@@ -0,0 +1,203 @@ -+/* -+ * Copyright (c) 2017 MediaTek Inc. -+ * Author: Xiangsheng Hou -+ * Copyright (c) 2020-2022 Felix Fietkau -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+#include "mtk_bmt.h" -+ -+static bool -+bbt_block_is_bad(u16 block) -+{ -+ u8 cur = bmtd.bbt_buf[block / 4]; -+ -+ return cur & (3 << ((block % 4) * 2)); -+} -+ -+static void -+bbt_set_block_state(u16 block, bool bad) -+{ -+ u8 mask = (3 << ((block % 4) * 2)); -+ -+ if (bad) -+ bmtd.bbt_buf[block / 4] |= mask; -+ else -+ bmtd.bbt_buf[block / 4] &= ~mask; -+ -+ bbt_nand_erase(bmtd.bmt_blk_idx); -+ write_bmt(bmtd.bmt_blk_idx, bmtd.bbt_buf); -+} -+ -+static int -+get_mapping_block_index_bbt(int block) -+{ -+ int start, end, ofs; -+ int bad_blocks = 0; -+ int i; -+ -+ if (!mapping_block_in_range(block, &start, &end)) -+ return block; -+ -+ start >>= bmtd.blk_shift; -+ end >>= bmtd.blk_shift; -+ /* skip bad blocks within the mapping range */ -+ ofs = block - start; -+ for (i = start; i < end; i++) { -+ if (bbt_block_is_bad(i)) -+ bad_blocks++; -+ else if (ofs) -+ ofs--; -+ else -+ break; -+ } -+ -+ if (i < end) -+ return i; -+ -+ /* when overflowing, remap remaining blocks to bad ones */ -+ for (i = end - 1; bad_blocks > 0; i--) { -+ if (!bbt_block_is_bad(i)) -+ continue; -+ -+ bad_blocks--; -+ if (bad_blocks <= ofs) -+ return i; -+ } -+ -+ return block; -+} -+ -+static bool remap_block_bbt(u16 block, u16 mapped_blk, int copy_len) -+{ -+ int start, end; -+ u16 new_blk; -+ -+ if (!mapping_block_in_range(block, &start, &end)) -+ return false; -+ -+ bbt_set_block_state(mapped_blk, true); -+ -+ new_blk = get_mapping_block_index_bbt(block); -+ bbt_nand_erase(new_blk); -+ if (copy_len > 0) -+ bbt_nand_copy(new_blk, mapped_blk, copy_len); -+ -+ return true; -+} -+ -+static void -+unmap_block_bbt(u16 block) -+{ -+ bbt_set_block_state(block, false); -+} -+ -+static int -+mtk_bmt_read_bbt(void) -+{ -+ u8 oob_buf[8]; -+ int i; -+ -+ for (i = bmtd.total_blks - 1; i >= bmtd.total_blks - 5; i--) { -+ u32 page = i << (bmtd.blk_shift - bmtd.pg_shift); -+ -+ if (bbt_nand_read(page, bmtd.bbt_buf, bmtd.pg_size, -+ oob_buf, sizeof(oob_buf))) { -+ pr_info("read_bbt: could not read block %d\n", i); -+ continue; -+ } -+ -+ if (oob_buf[0] != 0xff) { -+ pr_info("read_bbt: bad block at %d\n", i); -+ continue; -+ } -+ -+ if (memcmp(&oob_buf[1], "mtknand", 7) != 0) { -+ pr_info("read_bbt: signature mismatch in block %d\n", i); -+ print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, oob_buf, 8, 1); -+ continue; -+ } -+ -+ pr_info("read_bbt: found bbt at block %d\n", i); -+ bmtd.bmt_blk_idx = i; -+ return 0; -+ } -+ -+ return -EIO; -+} -+ -+ -+static int -+mtk_bmt_init_bbt(struct device_node *np) -+{ -+ int buf_size = round_up(bmtd.total_blks >> 2, bmtd.blk_size); -+ int ret; -+ -+ bmtd.bbt_buf = kmalloc(buf_size, GFP_KERNEL); -+ if (!bmtd.bbt_buf) -+ return -ENOMEM; -+ -+ memset(bmtd.bbt_buf, 0xff, buf_size); -+ bmtd.mtd->size -= 4 * bmtd.mtd->erasesize; -+ -+ ret = mtk_bmt_read_bbt(); -+ if (ret) -+ return ret; -+ -+ bmtd.bmt_pgs = buf_size / bmtd.pg_size; -+ -+ return 0; -+} -+ -+static int mtk_bmt_debug_bbt(void *data, u64 val) -+{ -+ char buf[5]; -+ int i, k; -+ -+ switch (val) { -+ case 0: -+ for (i = 0; i < bmtd.total_blks; i += 4) { -+ u8 cur = bmtd.bbt_buf[i / 4]; -+ -+ for (k = 0; k < 4; k++, cur >>= 2) -+ buf[k] = (cur & 3) ? 'B' : '.'; -+ -+ buf[4] = 0; -+ printk("[%06x] %s\n", i * bmtd.blk_size, buf); -+ } -+ break; -+ case 100: -+#if 0 -+ for (i = bmtd.bmt_blk_idx; i < bmtd.total_blks - 1; i++) -+ bbt_nand_erase(bmtd.bmt_blk_idx); -+#endif -+ -+ bmtd.bmt_blk_idx = bmtd.total_blks - 1; -+ bbt_nand_erase(bmtd.bmt_blk_idx); -+ write_bmt(bmtd.bmt_blk_idx, bmtd.bbt_buf); -+ break; -+ default: -+ break; -+ } -+ return 0; -+} -+ -+const struct mtk_bmt_ops mtk_bmt_bbt_ops = { -+ .sig = "mtknand", -+ .sig_len = 7, -+ .init = mtk_bmt_init_bbt, -+ .remap_block = remap_block_bbt, -+ .unmap_block = unmap_block_bbt, -+ .get_mapping_block = get_mapping_block_index_bbt, -+ .debug = mtk_bmt_debug_bbt, -+}; -diff --git a/drivers/mtd/nand/mtk_bmt_nmbm.c b/drivers/mtd/nand/mtk_bmt_nmbm.c -new file mode 100644 -index 000000000000..a896e49ec047 ---- /dev/null -+++ b/drivers/mtd/nand/mtk_bmt_nmbm.c -@@ -0,0 +1,2348 @@ -+#include -+#include -+#include "mtk_bmt.h" -+ -+#define nlog_err(ni, ...) printk(KERN_ERR __VA_ARGS__) -+#define nlog_info(ni, ...) printk(KERN_INFO __VA_ARGS__) -+#define nlog_debug(ni, ...) printk(KERN_INFO __VA_ARGS__) -+#define nlog_warn(ni, ...) printk(KERN_WARNING __VA_ARGS__) -+ -+#define NMBM_MAGIC_SIGNATURE 0x304d4d4e /* NMM0 */ -+#define NMBM_MAGIC_INFO_TABLE 0x314d4d4e /* NMM1 */ -+ -+#define NMBM_VERSION_MAJOR_S 0 -+#define NMBM_VERSION_MAJOR_M 0xffff -+#define NMBM_VERSION_MINOR_S 16 -+#define NMBM_VERSION_MINOR_M 0xffff -+#define NMBM_VERSION_MAKE(major, minor) (((major) & NMBM_VERSION_MAJOR_M) | \ -+ (((minor) & NMBM_VERSION_MINOR_M) << \ -+ NMBM_VERSION_MINOR_S)) -+#define NMBM_VERSION_MAJOR_GET(ver) (((ver) >> NMBM_VERSION_MAJOR_S) & \ -+ NMBM_VERSION_MAJOR_M) -+#define NMBM_VERSION_MINOR_GET(ver) (((ver) >> NMBM_VERSION_MINOR_S) & \ -+ NMBM_VERSION_MINOR_M) -+ -+#define NMBM_BITMAP_UNIT_SIZE (sizeof(u32)) -+#define NMBM_BITMAP_BITS_PER_BLOCK 2 -+#define NMBM_BITMAP_BITS_PER_UNIT (8 * sizeof(u32)) -+#define NMBM_BITMAP_BLOCKS_PER_UNIT (NMBM_BITMAP_BITS_PER_UNIT / \ -+ NMBM_BITMAP_BITS_PER_BLOCK) -+ -+#define NMBM_SPARE_BLOCK_MULTI 1 -+#define NMBM_SPARE_BLOCK_DIV 2 -+#define NMBM_SPARE_BLOCK_MIN 2 -+ -+#define NMBM_MGMT_DIV 16 -+#define NMBM_MGMT_BLOCKS_MIN 32 -+ -+#define NMBM_TRY_COUNT 3 -+ -+#define BLOCK_ST_BAD 0 -+#define BLOCK_ST_NEED_REMAP 2 -+#define BLOCK_ST_GOOD 3 -+#define BLOCK_ST_MASK 3 -+ -+#define NMBM_VER_MAJOR 1 -+#define NMBM_VER_MINOR 0 -+#define NMBM_VER NMBM_VERSION_MAKE(NMBM_VER_MAJOR, \ -+ NMBM_VER_MINOR) -+ -+struct nmbm_header { -+ u32 magic; -+ u32 version; -+ u32 size; -+ u32 checksum; -+}; -+ -+struct nmbm_signature { -+ struct nmbm_header header; -+ uint64_t nand_size; -+ u32 block_size; -+ u32 page_size; -+ u32 spare_size; -+ u32 mgmt_start_pb; -+ u8 max_try_count; -+ u8 padding[3]; -+}; -+ -+struct nmbm_info_table_header { -+ struct nmbm_header header; -+ u32 write_count; -+ u32 state_table_off; -+ u32 mapping_table_off; -+ u32 padding; -+}; -+ -+struct nmbm_instance { -+ u32 rawpage_size; -+ u32 rawblock_size; -+ u32 rawchip_size; -+ -+ struct nmbm_signature signature; -+ -+ u8 *info_table_cache; -+ u32 info_table_size; -+ u32 info_table_spare_blocks; -+ struct nmbm_info_table_header info_table; -+ -+ u32 *block_state; -+ u32 block_state_changed; -+ u32 state_table_size; -+ -+ int32_t *block_mapping; -+ u32 block_mapping_changed; -+ u32 mapping_table_size; -+ -+ u8 *page_cache; -+ -+ int protected; -+ -+ u32 block_count; -+ u32 data_block_count; -+ -+ u32 mgmt_start_ba; -+ u32 main_table_ba; -+ u32 backup_table_ba; -+ u32 mapping_blocks_ba; -+ u32 mapping_blocks_top_ba; -+ u32 signature_ba; -+ -+ u32 max_ratio; -+ u32 max_reserved_blocks; -+ bool empty_page_ecc_ok; -+ bool force_create; -+}; -+ -+static inline u32 nmbm_crc32(u32 crcval, const void *buf, size_t size) -+{ -+ unsigned int chksz; -+ const unsigned char *p = buf; -+ -+ while (size) { -+ if (size > UINT_MAX) -+ chksz = UINT_MAX; -+ else -+ chksz = (uint)size; -+ -+ crcval = crc32_le(crcval, p, chksz); -+ size -= chksz; -+ p += chksz; -+ } -+ -+ return crcval; -+} -+/* -+ * nlog_table_creation - Print log of table creation event -+ * @ni: NMBM instance structure -+ * @main_table: whether the table is main info table -+ * @start_ba: start block address of the table -+ * @end_ba: block address after the end of the table -+ */ -+static void nlog_table_creation(struct nmbm_instance *ni, bool main_table, -+ uint32_t start_ba, uint32_t end_ba) -+{ -+ if (start_ba == end_ba - 1) -+ nlog_info(ni, "%s info table has been written to block %u\n", -+ main_table ? "Main" : "Backup", start_ba); -+ else -+ nlog_info(ni, "%s info table has been written to block %u-%u\n", -+ main_table ? "Main" : "Backup", start_ba, end_ba - 1); -+} -+ -+/* -+ * nlog_table_update - Print log of table update event -+ * @ni: NMBM instance structure -+ * @main_table: whether the table is main info table -+ * @start_ba: start block address of the table -+ * @end_ba: block address after the end of the table -+ */ -+static void nlog_table_update(struct nmbm_instance *ni, bool main_table, -+ uint32_t start_ba, uint32_t end_ba) -+{ -+ if (start_ba == end_ba - 1) -+ nlog_debug(ni, "%s info table has been updated in block %u\n", -+ main_table ? "Main" : "Backup", start_ba); -+ else -+ nlog_debug(ni, "%s info table has been updated in block %u-%u\n", -+ main_table ? "Main" : "Backup", start_ba, end_ba - 1); -+} -+ -+/* -+ * nlog_table_found - Print log of table found event -+ * @ni: NMBM instance structure -+ * @first_table: whether the table is first found info table -+ * @write_count: write count of the info table -+ * @start_ba: start block address of the table -+ * @end_ba: block address after the end of the table -+ */ -+static void nlog_table_found(struct nmbm_instance *ni, bool first_table, -+ uint32_t write_count, uint32_t start_ba, -+ uint32_t end_ba) -+{ -+ if (start_ba == end_ba - 1) -+ nlog_info(ni, "%s info table with writecount %u found in block %u\n", -+ first_table ? "First" : "Second", write_count, -+ start_ba); -+ else -+ nlog_info(ni, "%s info table with writecount %u found in block %u-%u\n", -+ first_table ? "First" : "Second", write_count, -+ start_ba, end_ba - 1); -+} -+ -+/*****************************************************************************/ -+/* Address conversion functions */ -+/*****************************************************************************/ -+ -+/* -+ * ba2addr - Convert a block address to linear address -+ * @ni: NMBM instance structure -+ * @ba: Block address -+ */ -+static uint64_t ba2addr(struct nmbm_instance *ni, uint32_t ba) -+{ -+ return (uint64_t)ba << bmtd.blk_shift; -+} -+/* -+ * size2blk - Get minimum required blocks for storing specific size of data -+ * @ni: NMBM instance structure -+ * @size: size for storing -+ */ -+static uint32_t size2blk(struct nmbm_instance *ni, uint64_t size) -+{ -+ return (size + bmtd.blk_size - 1) >> bmtd.blk_shift; -+} -+ -+/*****************************************************************************/ -+/* High level NAND chip APIs */ -+/*****************************************************************************/ -+ -+/* -+ * nmbm_read_phys_page - Read page with retry -+ * @ni: NMBM instance structure -+ * @addr: linear address where the data will be read from -+ * @data: the main data to be read -+ * @oob: the oob data to be read -+ * -+ * Read a page for at most NMBM_TRY_COUNT times. -+ * -+ * Return 0 for success, positive value for corrected bitflip count, -+ * -EBADMSG for ecc error, other negative values for other errors -+ */ -+static int nmbm_read_phys_page(struct nmbm_instance *ni, uint64_t addr, -+ void *data, void *oob) -+{ -+ int tries, ret; -+ -+ for (tries = 0; tries < NMBM_TRY_COUNT; tries++) { -+ struct mtd_oob_ops ops = { -+ .mode = MTD_OPS_PLACE_OOB, -+ .oobbuf = oob, -+ .datbuf = data, -+ }; -+ -+ if (data) -+ ops.len = bmtd.pg_size; -+ if (oob) -+ ops.ooblen = mtd_oobavail(bmtd.mtd, &ops); -+ -+ ret = bmtd._read_oob(bmtd.mtd, addr, &ops); -+ if (ret == -EUCLEAN) -+ return min_t(u32, bmtd.mtd->bitflip_threshold + 1, -+ bmtd.mtd->ecc_strength); -+ if (ret >= 0) -+ return 0; -+ } -+ -+ if (ret != -EBADMSG) -+ nlog_err(ni, "Page read failed at address 0x%08llx\n", addr); -+ -+ return ret; -+} -+ -+/* -+ * nmbm_write_phys_page - Write page with retry -+ * @ni: NMBM instance structure -+ * @addr: linear address where the data will be written to -+ * @data: the main data to be written -+ * @oob: the oob data to be written -+ * -+ * Write a page for at most NMBM_TRY_COUNT times. -+ */ -+static bool nmbm_write_phys_page(struct nmbm_instance *ni, uint64_t addr, -+ const void *data, const void *oob) -+{ -+ int tries, ret; -+ -+ for (tries = 0; tries < NMBM_TRY_COUNT; tries++) { -+ struct mtd_oob_ops ops = { -+ .mode = MTD_OPS_PLACE_OOB, -+ .oobbuf = (void *)oob, -+ .datbuf = (void *)data, -+ }; -+ -+ if (data) -+ ops.len = bmtd.pg_size; -+ if (oob) -+ ops.ooblen = mtd_oobavail(bmtd.mtd, &ops); -+ -+ ret = bmtd._write_oob(bmtd.mtd, addr, &ops); -+ if (!ret) -+ return true; -+ } -+ -+ nlog_err(ni, "Page write failed at address 0x%08llx\n", addr); -+ -+ return false; -+} -+ -+/* -+ * nmbm_erase_phys_block - Erase a block with retry -+ * @ni: NMBM instance structure -+ * @addr: Linear address -+ * -+ * Erase a block for at most NMBM_TRY_COUNT times. -+ */ -+static bool nmbm_erase_phys_block(struct nmbm_instance *ni, uint64_t addr) -+{ -+ int tries, ret; -+ -+ for (tries = 0; tries < NMBM_TRY_COUNT; tries++) { -+ struct erase_info ei = { -+ .addr = addr, -+ .len = bmtd.mtd->erasesize, -+ }; -+ -+ ret = bmtd._erase(bmtd.mtd, &ei); -+ if (!ret) -+ return true; -+ } -+ -+ nlog_err(ni, "Block erasure failed at address 0x%08llx\n", addr); -+ -+ return false; -+} -+ -+/* -+ * nmbm_check_bad_phys_block - Check whether a block is marked bad in OOB -+ * @ni: NMBM instance structure -+ * @ba: block address -+ */ -+static bool nmbm_check_bad_phys_block(struct nmbm_instance *ni, uint32_t ba) -+{ -+ uint64_t addr = ba2addr(ni, ba); -+ -+ return bmtd._block_isbad(bmtd.mtd, addr); -+} -+ -+/* -+ * nmbm_mark_phys_bad_block - Mark a block bad -+ * @ni: NMBM instance structure -+ * @addr: Linear address -+ */ -+static int nmbm_mark_phys_bad_block(struct nmbm_instance *ni, uint32_t ba) -+{ -+ uint64_t addr = ba2addr(ni, ba); -+ -+ nlog_info(ni, "Block %u [0x%08llx] will be marked bad\n", ba, addr); -+ -+ return bmtd._block_markbad(bmtd.mtd, addr); -+} -+ -+/*****************************************************************************/ -+/* NMBM related functions */ -+/*****************************************************************************/ -+ -+/* -+ * nmbm_check_header - Check whether a NMBM structure is valid -+ * @data: pointer to a NMBM structure with a NMBM header at beginning -+ * @size: Size of the buffer pointed by @header -+ * -+ * The size of the NMBM structure may be larger than NMBM header, -+ * e.g. block mapping table and block state table. -+ */ -+static bool nmbm_check_header(const void *data, uint32_t size) -+{ -+ const struct nmbm_header *header = data; -+ struct nmbm_header nhdr; -+ uint32_t new_checksum; -+ -+ /* -+ * Make sure expected structure size is equal or smaller than -+ * buffer size. -+ */ -+ if (header->size > size) -+ return false; -+ -+ memcpy(&nhdr, data, sizeof(nhdr)); -+ -+ nhdr.checksum = 0; -+ new_checksum = nmbm_crc32(0, &nhdr, sizeof(nhdr)); -+ if (header->size > sizeof(nhdr)) -+ new_checksum = nmbm_crc32(new_checksum, -+ (const uint8_t *)data + sizeof(nhdr), -+ header->size - sizeof(nhdr)); -+ -+ if (header->checksum != new_checksum) -+ return false; -+ -+ return true; -+} -+ -+/* -+ * nmbm_update_checksum - Update checksum of a NMBM structure -+ * @header: pointer to a NMBM structure with a NMBM header at beginning -+ * -+ * The size of the NMBM structure must be specified by @header->size -+ */ -+static void nmbm_update_checksum(struct nmbm_header *header) -+{ -+ header->checksum = 0; -+ header->checksum = nmbm_crc32(0, header, header->size); -+} -+ -+/* -+ * nmbm_get_spare_block_count - Calculate number of blocks should be reserved -+ * @block_count: number of blocks of data -+ * -+ * Calculate number of blocks should be reserved for data -+ */ -+static uint32_t nmbm_get_spare_block_count(uint32_t block_count) -+{ -+ uint32_t val; -+ -+ val = (block_count + NMBM_SPARE_BLOCK_DIV / 2) / NMBM_SPARE_BLOCK_DIV; -+ val *= NMBM_SPARE_BLOCK_MULTI; -+ -+ if (val < NMBM_SPARE_BLOCK_MIN) -+ val = NMBM_SPARE_BLOCK_MIN; -+ -+ return val; -+} -+ -+/* -+ * nmbm_get_block_state_raw - Get state of a block from raw block state table -+ * @block_state: pointer to raw block state table (bitmap) -+ * @ba: block address -+ */ -+static uint32_t nmbm_get_block_state_raw(u32 *block_state, -+ uint32_t ba) -+{ -+ uint32_t unit, shift; -+ -+ unit = ba / NMBM_BITMAP_BLOCKS_PER_UNIT; -+ shift = (ba % NMBM_BITMAP_BLOCKS_PER_UNIT) * NMBM_BITMAP_BITS_PER_BLOCK; -+ -+ return (block_state[unit] >> shift) & BLOCK_ST_MASK; -+} -+ -+/* -+ * nmbm_get_block_state - Get state of a block from block state table -+ * @ni: NMBM instance structure -+ * @ba: block address -+ */ -+static uint32_t nmbm_get_block_state(struct nmbm_instance *ni, uint32_t ba) -+{ -+ return nmbm_get_block_state_raw(ni->block_state, ba); -+} -+ -+/* -+ * nmbm_set_block_state - Set state of a block to block state table -+ * @ni: NMBM instance structure -+ * @ba: block address -+ * @state: block state -+ * -+ * Set state of a block. If the block state changed, ni->block_state_changed -+ * will be increased. -+ */ -+static bool nmbm_set_block_state(struct nmbm_instance *ni, uint32_t ba, -+ uint32_t state) -+{ -+ uint32_t unit, shift, orig; -+ u32 uv; -+ -+ unit = ba / NMBM_BITMAP_BLOCKS_PER_UNIT; -+ shift = (ba % NMBM_BITMAP_BLOCKS_PER_UNIT) * NMBM_BITMAP_BITS_PER_BLOCK; -+ -+ orig = (ni->block_state[unit] >> shift) & BLOCK_ST_MASK; -+ state &= BLOCK_ST_MASK; -+ -+ uv = ni->block_state[unit] & (~(BLOCK_ST_MASK << shift)); -+ uv |= state << shift; -+ ni->block_state[unit] = uv; -+ -+ if (orig != state) { -+ ni->block_state_changed++; -+ return true; -+ } -+ -+ return false; -+} -+ -+/* -+ * nmbm_block_walk_asc - Skip specified number of good blocks, ascending addr. -+ * @ni: NMBM instance structure -+ * @ba: start physical block address -+ * @nba: return physical block address after walk -+ * @count: number of good blocks to be skipped -+ * @limit: highest block address allowed for walking -+ * -+ * Start from @ba, skipping any bad blocks, counting @count good blocks, and -+ * return the next good block address. -+ * -+ * If no enough good blocks counted while @limit reached, false will be returned. -+ * -+ * If @count == 0, nearest good block address will be returned. -+ * @limit is not counted in walking. -+ */ -+static bool nmbm_block_walk_asc(struct nmbm_instance *ni, uint32_t ba, -+ uint32_t *nba, uint32_t count, -+ uint32_t limit) -+{ -+ int32_t nblock = count; -+ -+ if (limit >= ni->block_count) -+ limit = ni->block_count - 1; -+ -+ while (ba < limit) { -+ if (nmbm_get_block_state(ni, ba) == BLOCK_ST_GOOD) -+ nblock--; -+ -+ if (nblock < 0) { -+ *nba = ba; -+ return true; -+ } -+ -+ ba++; -+ } -+ -+ return false; -+} -+ -+/* -+ * nmbm_block_walk_desc - Skip specified number of good blocks, descending addr -+ * @ni: NMBM instance structure -+ * @ba: start physical block address -+ * @nba: return physical block address after walk -+ * @count: number of good blocks to be skipped -+ * @limit: lowest block address allowed for walking -+ * -+ * Start from @ba, skipping any bad blocks, counting @count good blocks, and -+ * return the next good block address. -+ * -+ * If no enough good blocks counted while @limit reached, false will be returned. -+ * -+ * If @count == 0, nearest good block address will be returned. -+ * @limit is not counted in walking. -+ */ -+static bool nmbm_block_walk_desc(struct nmbm_instance *ni, uint32_t ba, -+ uint32_t *nba, uint32_t count, uint32_t limit) -+{ -+ int32_t nblock = count; -+ -+ if (limit >= ni->block_count) -+ limit = ni->block_count - 1; -+ -+ while (ba > limit) { -+ if (nmbm_get_block_state(ni, ba) == BLOCK_ST_GOOD) -+ nblock--; -+ -+ if (nblock < 0) { -+ *nba = ba; -+ return true; -+ } -+ -+ ba--; -+ } -+ -+ return false; -+} -+ -+/* -+ * nmbm_block_walk - Skip specified number of good blocks from curr. block addr -+ * @ni: NMBM instance structure -+ * @ascending: whether to walk ascending -+ * @ba: start physical block address -+ * @nba: return physical block address after walk -+ * @count: number of good blocks to be skipped -+ * @limit: highest/lowest block address allowed for walking -+ * -+ * Start from @ba, skipping any bad blocks, counting @count good blocks, and -+ * return the next good block address. -+ * -+ * If no enough good blocks counted while @limit reached, false will be returned. -+ * -+ * If @count == 0, nearest good block address will be returned. -+ * @limit can be set to negative if no limit required. -+ * @limit is not counted in walking. -+ */ -+static bool nmbm_block_walk(struct nmbm_instance *ni, bool ascending, -+ uint32_t ba, uint32_t *nba, int32_t count, -+ int32_t limit) -+{ -+ if (ascending) -+ return nmbm_block_walk_asc(ni, ba, nba, count, limit); -+ -+ return nmbm_block_walk_desc(ni, ba, nba, count, limit); -+} -+ -+/* -+ * nmbm_scan_badblocks - Scan and record all bad blocks -+ * @ni: NMBM instance structure -+ * -+ * Scan the entire lower NAND chip and record all bad blocks in to block state -+ * table. -+ */ -+static void nmbm_scan_badblocks(struct nmbm_instance *ni) -+{ -+ uint32_t ba; -+ -+ for (ba = 0; ba < ni->block_count; ba++) { -+ if (nmbm_check_bad_phys_block(ni, ba)) { -+ nmbm_set_block_state(ni, ba, BLOCK_ST_BAD); -+ nlog_info(ni, "Bad block %u [0x%08llx]\n", ba, -+ ba2addr(ni, ba)); -+ } -+ } -+} -+ -+/* -+ * nmbm_build_mapping_table - Build initial block mapping table -+ * @ni: NMBM instance structure -+ * -+ * The initial mapping table will be compatible with the stratage of -+ * factory production. -+ */ -+static void nmbm_build_mapping_table(struct nmbm_instance *ni) -+{ -+ uint32_t pb, lb; -+ -+ for (pb = 0, lb = 0; pb < ni->mgmt_start_ba; pb++) { -+ if (nmbm_get_block_state(ni, pb) == BLOCK_ST_BAD) -+ continue; -+ -+ /* Always map to the next good block */ -+ ni->block_mapping[lb++] = pb; -+ } -+ -+ ni->data_block_count = lb; -+ -+ /* Unusable/Management blocks */ -+ for (pb = lb; pb < ni->block_count; pb++) -+ ni->block_mapping[pb] = -1; -+} -+ -+/* -+ * nmbm_erase_block_and_check - Erase a block and check its usability -+ * @ni: NMBM instance structure -+ * @ba: block address to be erased -+ * -+ * Erase a block anc check its usability -+ * -+ * Return true if the block is usable, false if erasure failure or the block -+ * has too many bitflips. -+ */ -+static bool nmbm_erase_block_and_check(struct nmbm_instance *ni, uint32_t ba) -+{ -+ uint64_t addr, off; -+ bool success; -+ int ret; -+ -+ success = nmbm_erase_phys_block(ni, ba2addr(ni, ba)); -+ if (!success) -+ return false; -+ -+ if (!ni->empty_page_ecc_ok) -+ return true; -+ -+ /* Check every page to make sure there aren't too many bitflips */ -+ -+ addr = ba2addr(ni, ba); -+ -+ for (off = 0; off < bmtd.blk_size; off += bmtd.pg_size) { -+ ret = nmbm_read_phys_page(ni, addr + off, ni->page_cache, NULL); -+ if (ret == -EBADMSG) { -+ /* -+ * empty_page_ecc_ok means the empty page is -+ * still protected by ECC. So reading pages with ECC -+ * enabled and -EBADMSG means there are too many -+ * bitflips that can't be recovered, and the block -+ * containing the page should be marked bad. -+ */ -+ nlog_err(ni, -+ "Too many bitflips in empty page at 0x%llx\n", -+ addr + off); -+ return false; -+ } -+ } -+ -+ return true; -+} -+ -+/* -+ * nmbm_erase_range - Erase a range of blocks -+ * @ni: NMBM instance structure -+ * @ba: block address where the erasure will start -+ * @limit: top block address allowed for erasure -+ * -+ * Erase blocks within the specific range. Newly-found bad blocks will be -+ * marked. -+ * -+ * @limit is not counted into the allowed erasure address. -+ */ -+static void nmbm_erase_range(struct nmbm_instance *ni, uint32_t ba, -+ uint32_t limit) -+{ -+ bool success; -+ -+ while (ba < limit) { -+ if (nmbm_get_block_state(ni, ba) != BLOCK_ST_GOOD) -+ goto next_block; -+ -+ /* Insurance to detect unexpected bad block marked by user */ -+ if (nmbm_check_bad_phys_block(ni, ba)) { -+ nmbm_set_block_state(ni, ba, BLOCK_ST_BAD); -+ goto next_block; -+ } -+ -+ success = nmbm_erase_block_and_check(ni, ba); -+ if (success) -+ goto next_block; -+ -+ nmbm_mark_phys_bad_block(ni, ba); -+ nmbm_set_block_state(ni, ba, BLOCK_ST_BAD); -+ -+ next_block: -+ ba++; -+ } -+} -+ -+/* -+ * nmbm_write_repeated_data - Write critical data to a block with retry -+ * @ni: NMBM instance structure -+ * @ba: block address where the data will be written to -+ * @data: the data to be written -+ * @size: size of the data -+ * -+ * Write data to every page of the block. Success only if all pages within -+ * this block have been successfully written. -+ * -+ * Make sure data size is not bigger than one page. -+ * -+ * This function will write and verify every page for at most -+ * NMBM_TRY_COUNT times. -+ */ -+static bool nmbm_write_repeated_data(struct nmbm_instance *ni, uint32_t ba, -+ const void *data, uint32_t size) -+{ -+ uint64_t addr, off; -+ bool success; -+ int ret; -+ -+ if (size > bmtd.pg_size) -+ return false; -+ -+ addr = ba2addr(ni, ba); -+ -+ for (off = 0; off < bmtd.blk_size; off += bmtd.pg_size) { -+ /* Prepare page data. fill 0xff to unused region */ -+ memcpy(ni->page_cache, data, size); -+ memset(ni->page_cache + size, 0xff, ni->rawpage_size - size); -+ -+ success = nmbm_write_phys_page(ni, addr + off, ni->page_cache, NULL); -+ if (!success) -+ return false; -+ -+ /* Verify the data just written. ECC error indicates failure */ -+ ret = nmbm_read_phys_page(ni, addr + off, ni->page_cache, NULL); -+ if (ret < 0) -+ return false; -+ -+ if (memcmp(ni->page_cache, data, size)) -+ return false; -+ } -+ -+ return true; -+} -+ -+/* -+ * nmbm_write_signature - Write signature to NAND chip -+ * @ni: NMBM instance structure -+ * @limit: top block address allowed for writing -+ * @signature: the signature to be written -+ * @signature_ba: the actual block address where signature is written to -+ * -+ * Write signature within a specific range, from chip bottom to limit. -+ * At most one block will be written. -+ * -+ * @limit is not counted into the allowed write address. -+ */ -+static bool nmbm_write_signature(struct nmbm_instance *ni, uint32_t limit, -+ const struct nmbm_signature *signature, -+ uint32_t *signature_ba) -+{ -+ uint32_t ba = ni->block_count - 1; -+ bool success; -+ -+ while (ba > limit) { -+ if (nmbm_get_block_state(ni, ba) != BLOCK_ST_GOOD) -+ goto next_block; -+ -+ /* Insurance to detect unexpected bad block marked by user */ -+ if (nmbm_check_bad_phys_block(ni, ba)) { -+ nmbm_set_block_state(ni, ba, BLOCK_ST_BAD); -+ goto next_block; -+ } -+ -+ success = nmbm_erase_block_and_check(ni, ba); -+ if (!success) -+ goto skip_bad_block; -+ -+ success = nmbm_write_repeated_data(ni, ba, signature, -+ sizeof(*signature)); -+ if (success) { -+ *signature_ba = ba; -+ return true; -+ } -+ -+ skip_bad_block: -+ nmbm_mark_phys_bad_block(ni, ba); -+ nmbm_set_block_state(ni, ba, BLOCK_ST_BAD); -+ -+ next_block: -+ ba--; -+ }; -+ -+ return false; -+} -+ -+/* -+ * nmbn_read_data - Read data -+ * @ni: NMBM instance structure -+ * @addr: linear address where the data will be read from -+ * @data: the data to be read -+ * @size: the size of data -+ * -+ * Read data range. -+ * Every page will be tried for at most NMBM_TRY_COUNT times. -+ * -+ * Return 0 for success, positive value for corrected bitflip count, -+ * -EBADMSG for ecc error, other negative values for other errors -+ */ -+static int nmbn_read_data(struct nmbm_instance *ni, uint64_t addr, void *data, -+ uint32_t size) -+{ -+ uint64_t off = addr; -+ uint8_t *ptr = data; -+ uint32_t sizeremain = size, chunksize, leading; -+ int ret; -+ -+ while (sizeremain) { -+ leading = off & (bmtd.pg_size - 1); -+ chunksize = bmtd.pg_size - leading; -+ if (chunksize > sizeremain) -+ chunksize = sizeremain; -+ -+ if (chunksize == bmtd.pg_size) { -+ ret = nmbm_read_phys_page(ni, off - leading, ptr, NULL); -+ if (ret < 0) -+ return ret; -+ } else { -+ ret = nmbm_read_phys_page(ni, off - leading, -+ ni->page_cache, NULL); -+ if (ret < 0) -+ return ret; -+ -+ memcpy(ptr, ni->page_cache + leading, chunksize); -+ } -+ -+ off += chunksize; -+ ptr += chunksize; -+ sizeremain -= chunksize; -+ } -+ -+ return 0; -+} -+ -+/* -+ * nmbn_write_verify_data - Write data with validation -+ * @ni: NMBM instance structure -+ * @addr: linear address where the data will be written to -+ * @data: the data to be written -+ * @size: the size of data -+ * -+ * Write data and verify. -+ * Every page will be tried for at most NMBM_TRY_COUNT times. -+ */ -+static bool nmbn_write_verify_data(struct nmbm_instance *ni, uint64_t addr, -+ const void *data, uint32_t size) -+{ -+ uint64_t off = addr; -+ const uint8_t *ptr = data; -+ uint32_t sizeremain = size, chunksize, leading; -+ bool success; -+ int ret; -+ -+ while (sizeremain) { -+ leading = off & (bmtd.pg_size - 1); -+ chunksize = bmtd.pg_size - leading; -+ if (chunksize > sizeremain) -+ chunksize = sizeremain; -+ -+ /* Prepare page data. fill 0xff to unused region */ -+ memset(ni->page_cache, 0xff, ni->rawpage_size); -+ memcpy(ni->page_cache + leading, ptr, chunksize); -+ -+ success = nmbm_write_phys_page(ni, off - leading, -+ ni->page_cache, NULL); -+ if (!success) -+ return false; -+ -+ /* Verify the data just written. ECC error indicates failure */ -+ ret = nmbm_read_phys_page(ni, off - leading, ni->page_cache, NULL); -+ if (ret < 0) -+ return false; -+ -+ if (memcmp(ni->page_cache + leading, ptr, chunksize)) -+ return false; -+ -+ off += chunksize; -+ ptr += chunksize; -+ sizeremain -= chunksize; -+ } -+ -+ return true; -+} -+ -+/* -+ * nmbm_write_mgmt_range - Write management data into NAND within a range -+ * @ni: NMBM instance structure -+ * @addr: preferred start block address for writing -+ * @limit: highest block address allowed for writing -+ * @data: the data to be written -+ * @size: the size of data -+ * @actual_start_ba: actual start block address of data -+ * @actual_end_ba: block address after the end of data -+ * -+ * @limit is not counted into the allowed write address. -+ */ -+static bool nmbm_write_mgmt_range(struct nmbm_instance *ni, uint32_t ba, -+ uint32_t limit, const void *data, -+ uint32_t size, uint32_t *actual_start_ba, -+ uint32_t *actual_end_ba) -+{ -+ const uint8_t *ptr = data; -+ uint32_t sizeremain = size, chunksize; -+ bool success; -+ -+ while (sizeremain && ba < limit) { -+ chunksize = sizeremain; -+ if (chunksize > bmtd.blk_size) -+ chunksize = bmtd.blk_size; -+ -+ if (nmbm_get_block_state(ni, ba) != BLOCK_ST_GOOD) -+ goto next_block; -+ -+ /* Insurance to detect unexpected bad block marked by user */ -+ if (nmbm_check_bad_phys_block(ni, ba)) { -+ nmbm_set_block_state(ni, ba, BLOCK_ST_BAD); -+ goto next_block; -+ } -+ -+ success = nmbm_erase_block_and_check(ni, ba); -+ if (!success) -+ goto skip_bad_block; -+ -+ success = nmbn_write_verify_data(ni, ba2addr(ni, ba), ptr, -+ chunksize); -+ if (!success) -+ goto skip_bad_block; -+ -+ if (sizeremain == size) -+ *actual_start_ba = ba; -+ -+ ptr += chunksize; -+ sizeremain -= chunksize; -+ -+ goto next_block; -+ -+ skip_bad_block: -+ nmbm_mark_phys_bad_block(ni, ba); -+ nmbm_set_block_state(ni, ba, BLOCK_ST_BAD); -+ -+ next_block: -+ ba++; -+ } -+ -+ if (sizeremain) -+ return false; -+ -+ *actual_end_ba = ba; -+ -+ return true; -+} -+ -+/* -+ * nmbm_generate_info_table_cache - Generate info table cache data -+ * @ni: NMBM instance structure -+ * -+ * Generate info table cache data to be written into flash. -+ */ -+static bool nmbm_generate_info_table_cache(struct nmbm_instance *ni) -+{ -+ bool changed = false; -+ -+ memset(ni->info_table_cache, 0xff, ni->info_table_size); -+ -+ memcpy(ni->info_table_cache + ni->info_table.state_table_off, -+ ni->block_state, ni->state_table_size); -+ -+ memcpy(ni->info_table_cache + ni->info_table.mapping_table_off, -+ ni->block_mapping, ni->mapping_table_size); -+ -+ ni->info_table.header.magic = NMBM_MAGIC_INFO_TABLE; -+ ni->info_table.header.version = NMBM_VER; -+ ni->info_table.header.size = ni->info_table_size; -+ -+ if (ni->block_state_changed || ni->block_mapping_changed) { -+ ni->info_table.write_count++; -+ changed = true; -+ } -+ -+ memcpy(ni->info_table_cache, &ni->info_table, sizeof(ni->info_table)); -+ -+ nmbm_update_checksum((struct nmbm_header *)ni->info_table_cache); -+ -+ return changed; -+} -+ -+/* -+ * nmbm_write_info_table - Write info table into NAND within a range -+ * @ni: NMBM instance structure -+ * @ba: preferred start block address for writing -+ * @limit: highest block address allowed for writing -+ * @actual_start_ba: actual start block address of info table -+ * @actual_end_ba: block address after the end of info table -+ * -+ * @limit is counted into the allowed write address. -+ */ -+static bool nmbm_write_info_table(struct nmbm_instance *ni, uint32_t ba, -+ uint32_t limit, uint32_t *actual_start_ba, -+ uint32_t *actual_end_ba) -+{ -+ return nmbm_write_mgmt_range(ni, ba, limit, ni->info_table_cache, -+ ni->info_table_size, actual_start_ba, -+ actual_end_ba); -+} -+ -+/* -+ * nmbm_mark_tables_clean - Mark info table `clean' -+ * @ni: NMBM instance structure -+ */ -+static void nmbm_mark_tables_clean(struct nmbm_instance *ni) -+{ -+ ni->block_state_changed = 0; -+ ni->block_mapping_changed = 0; -+} -+ -+/* -+ * nmbm_try_reserve_blocks - Reserve blocks with compromisation -+ * @ni: NMBM instance structure -+ * @ba: start physical block address -+ * @nba: return physical block address after reservation -+ * @count: number of good blocks to be skipped -+ * @min_count: minimum number of good blocks to be skipped -+ * @limit: highest/lowest block address allowed for walking -+ * -+ * Reserve specific blocks. If failed, try to reserve as many as possible. -+ */ -+static bool nmbm_try_reserve_blocks(struct nmbm_instance *ni, uint32_t ba, -+ uint32_t *nba, uint32_t count, -+ int32_t min_count, int32_t limit) -+{ -+ int32_t nblocks = count; -+ bool success; -+ -+ while (nblocks >= min_count) { -+ success = nmbm_block_walk(ni, true, ba, nba, nblocks, limit); -+ if (success) -+ return true; -+ -+ nblocks--; -+ } -+ -+ return false; -+} -+ -+/* -+ * nmbm_rebuild_info_table - Build main & backup info table from scratch -+ * @ni: NMBM instance structure -+ * @allow_no_gap: allow no spare blocks between two tables -+ */ -+static bool nmbm_rebuild_info_table(struct nmbm_instance *ni) -+{ -+ uint32_t table_start_ba, table_end_ba, next_start_ba; -+ uint32_t main_table_end_ba; -+ bool success; -+ -+ /* Set initial value */ -+ ni->main_table_ba = 0; -+ ni->backup_table_ba = 0; -+ ni->mapping_blocks_ba = ni->mapping_blocks_top_ba; -+ -+ /* Write main table */ -+ success = nmbm_write_info_table(ni, ni->mgmt_start_ba, -+ ni->mapping_blocks_top_ba, -+ &table_start_ba, &table_end_ba); -+ if (!success) { -+ /* Failed to write main table, data will be lost */ -+ nlog_err(ni, "Unable to write at least one info table!\n"); -+ nlog_err(ni, "Please save your data before power off!\n"); -+ ni->protected = 1; -+ return false; -+ } -+ -+ /* Main info table is successfully written, record its offset */ -+ ni->main_table_ba = table_start_ba; -+ main_table_end_ba = table_end_ba; -+ -+ /* Adjust mapping_blocks_ba */ -+ ni->mapping_blocks_ba = table_end_ba; -+ -+ nmbm_mark_tables_clean(ni); -+ -+ nlog_table_creation(ni, true, table_start_ba, table_end_ba); -+ -+ /* Reserve spare blocks for main info table. */ -+ success = nmbm_try_reserve_blocks(ni, table_end_ba, -+ &next_start_ba, -+ ni->info_table_spare_blocks, 0, -+ ni->mapping_blocks_top_ba - -+ size2blk(ni, ni->info_table_size)); -+ if (!success) { -+ /* There is no spare block. */ -+ nlog_debug(ni, "No room for backup info table\n"); -+ return true; -+ } -+ -+ /* Write backup info table. */ -+ success = nmbm_write_info_table(ni, next_start_ba, -+ ni->mapping_blocks_top_ba, -+ &table_start_ba, &table_end_ba); -+ if (!success) { -+ /* There is no enough blocks for backup table. */ -+ nlog_debug(ni, "No room for backup info table\n"); -+ return true; -+ } -+ -+ /* Backup table is successfully written, record its offset */ -+ ni->backup_table_ba = table_start_ba; -+ -+ /* Adjust mapping_blocks_off */ -+ ni->mapping_blocks_ba = table_end_ba; -+ -+ /* Erase spare blocks of main table to clean possible interference data */ -+ nmbm_erase_range(ni, main_table_end_ba, ni->backup_table_ba); -+ -+ nlog_table_creation(ni, false, table_start_ba, table_end_ba); -+ -+ return true; -+} -+ -+/* -+ * nmbm_rescue_single_info_table - Rescue when there is only one info table -+ * @ni: NMBM instance structure -+ * -+ * This function is called when there is only one info table exists. -+ * This function may fail if we can't write new info table -+ */ -+static bool nmbm_rescue_single_info_table(struct nmbm_instance *ni) -+{ -+ uint32_t table_start_ba, table_end_ba, write_ba; -+ bool success; -+ -+ /* Try to write new info table in front of existing table */ -+ success = nmbm_write_info_table(ni, ni->mgmt_start_ba, -+ ni->main_table_ba, -+ &table_start_ba, -+ &table_end_ba); -+ if (success) { -+ /* -+ * New table becomes the main table, existing table becomes -+ * the backup table. -+ */ -+ ni->backup_table_ba = ni->main_table_ba; -+ ni->main_table_ba = table_start_ba; -+ -+ nmbm_mark_tables_clean(ni); -+ -+ /* Erase spare blocks of main table to clean possible interference data */ -+ nmbm_erase_range(ni, table_end_ba, ni->backup_table_ba); -+ -+ nlog_table_creation(ni, true, table_start_ba, table_end_ba); -+ -+ return true; -+ } -+ -+ /* Try to reserve spare blocks for existing table */ -+ success = nmbm_try_reserve_blocks(ni, ni->mapping_blocks_ba, &write_ba, -+ ni->info_table_spare_blocks, 0, -+ ni->mapping_blocks_top_ba - -+ size2blk(ni, ni->info_table_size)); -+ if (!success) { -+ nlog_warn(ni, "Failed to rescue single info table\n"); -+ return false; -+ } -+ -+ /* Try to write new info table next to the existing table */ -+ while (write_ba >= ni->mapping_blocks_ba) { -+ success = nmbm_write_info_table(ni, write_ba, -+ ni->mapping_blocks_top_ba, -+ &table_start_ba, -+ &table_end_ba); -+ if (success) -+ break; -+ -+ write_ba--; -+ } -+ -+ if (success) { -+ /* Erase spare blocks of main table to clean possible interference data */ -+ nmbm_erase_range(ni, ni->mapping_blocks_ba, table_start_ba); -+ -+ /* New table becomes the backup table */ -+ ni->backup_table_ba = table_start_ba; -+ ni->mapping_blocks_ba = table_end_ba; -+ -+ nmbm_mark_tables_clean(ni); -+ -+ nlog_table_creation(ni, false, table_start_ba, table_end_ba); -+ -+ return true; -+ } -+ -+ nlog_warn(ni, "Failed to rescue single info table\n"); -+ return false; -+} -+ -+/* -+ * nmbm_update_single_info_table - Update specific one info table -+ * @ni: NMBM instance structure -+ */ -+static bool nmbm_update_single_info_table(struct nmbm_instance *ni, -+ bool update_main_table) -+{ -+ uint32_t write_start_ba, write_limit, table_start_ba, table_end_ba; -+ bool success; -+ -+ /* Determine the write range */ -+ if (update_main_table) { -+ write_start_ba = ni->main_table_ba; -+ write_limit = ni->backup_table_ba; -+ } else { -+ write_start_ba = ni->backup_table_ba; -+ write_limit = ni->mapping_blocks_top_ba; -+ } -+ -+ success = nmbm_write_info_table(ni, write_start_ba, write_limit, -+ &table_start_ba, &table_end_ba); -+ if (success) { -+ if (update_main_table) { -+ ni->main_table_ba = table_start_ba; -+ } else { -+ ni->backup_table_ba = table_start_ba; -+ ni->mapping_blocks_ba = table_end_ba; -+ } -+ -+ nmbm_mark_tables_clean(ni); -+ -+ nlog_table_update(ni, update_main_table, table_start_ba, -+ table_end_ba); -+ -+ return true; -+ } -+ -+ if (update_main_table) { -+ /* -+ * If failed to update main table, make backup table the new -+ * main table, and call nmbm_rescue_single_info_table() -+ */ -+ nlog_warn(ni, "Unable to update %s info table\n", -+ update_main_table ? "Main" : "Backup"); -+ -+ ni->main_table_ba = ni->backup_table_ba; -+ ni->backup_table_ba = 0; -+ return nmbm_rescue_single_info_table(ni); -+ } -+ -+ /* Only one table left */ -+ ni->mapping_blocks_ba = ni->backup_table_ba; -+ ni->backup_table_ba = 0; -+ -+ return false; -+} -+ -+/* -+ * nmbm_rescue_main_info_table - Rescue when failed to write main info table -+ * @ni: NMBM instance structure -+ * -+ * This function is called when main info table failed to be written, and -+ * backup info table exists. -+ */ -+static bool nmbm_rescue_main_info_table(struct nmbm_instance *ni) -+{ -+ uint32_t tmp_table_start_ba, tmp_table_end_ba, main_table_start_ba; -+ uint32_t main_table_end_ba, write_ba; -+ uint32_t info_table_erasesize = size2blk(ni, ni->info_table_size); -+ bool success; -+ -+ /* Try to reserve spare blocks for existing backup info table */ -+ success = nmbm_try_reserve_blocks(ni, ni->mapping_blocks_ba, &write_ba, -+ ni->info_table_spare_blocks, 0, -+ ni->mapping_blocks_top_ba - -+ info_table_erasesize); -+ if (!success) { -+ /* There is no spare block. Backup info table becomes the main table. */ -+ nlog_err(ni, "No room for temporary info table\n"); -+ ni->main_table_ba = ni->backup_table_ba; -+ ni->backup_table_ba = 0; -+ return true; -+ } -+ -+ /* Try to write temporary info table into spare unmapped blocks */ -+ while (write_ba >= ni->mapping_blocks_ba) { -+ success = nmbm_write_info_table(ni, write_ba, -+ ni->mapping_blocks_top_ba, -+ &tmp_table_start_ba, -+ &tmp_table_end_ba); -+ if (success) -+ break; -+ -+ write_ba--; -+ } -+ -+ if (!success) { -+ /* Backup info table becomes the main table */ -+ nlog_err(ni, "Failed to update main info table\n"); -+ ni->main_table_ba = ni->backup_table_ba; -+ ni->backup_table_ba = 0; -+ return true; -+ } -+ -+ /* Adjust mapping_blocks_off */ -+ ni->mapping_blocks_ba = tmp_table_end_ba; -+ -+ /* -+ * Now write main info table at the beginning of management area. -+ * This operation will generally destroy the original backup info -+ * table. -+ */ -+ success = nmbm_write_info_table(ni, ni->mgmt_start_ba, -+ tmp_table_start_ba, -+ &main_table_start_ba, -+ &main_table_end_ba); -+ if (!success) { -+ /* Temporary info table becomes the main table */ -+ ni->main_table_ba = tmp_table_start_ba; -+ ni->backup_table_ba = 0; -+ -+ nmbm_mark_tables_clean(ni); -+ -+ nlog_err(ni, "Failed to update main info table\n"); -+ -+ return true; -+ } -+ -+ /* Main info table has been successfully written, record its offset */ -+ ni->main_table_ba = main_table_start_ba; -+ -+ nmbm_mark_tables_clean(ni); -+ -+ nlog_table_creation(ni, true, main_table_start_ba, main_table_end_ba); -+ -+ /* -+ * Temporary info table becomes the new backup info table if it's -+ * not overwritten. -+ */ -+ if (main_table_end_ba <= tmp_table_start_ba) { -+ ni->backup_table_ba = tmp_table_start_ba; -+ -+ nlog_table_creation(ni, false, tmp_table_start_ba, -+ tmp_table_end_ba); -+ -+ return true; -+ } -+ -+ /* Adjust mapping_blocks_off */ -+ ni->mapping_blocks_ba = main_table_end_ba; -+ -+ /* Try to reserve spare blocks for new main info table */ -+ success = nmbm_try_reserve_blocks(ni, main_table_end_ba, &write_ba, -+ ni->info_table_spare_blocks, 0, -+ ni->mapping_blocks_top_ba - -+ info_table_erasesize); -+ if (!success) { -+ /* There is no spare block. Only main table exists. */ -+ nlog_err(ni, "No room for backup info table\n"); -+ ni->backup_table_ba = 0; -+ return true; -+ } -+ -+ /* Write new backup info table. */ -+ while (write_ba >= main_table_end_ba) { -+ success = nmbm_write_info_table(ni, write_ba, -+ ni->mapping_blocks_top_ba, -+ &tmp_table_start_ba, -+ &tmp_table_end_ba); -+ if (success) -+ break; -+ -+ write_ba--; -+ } -+ -+ if (!success) { -+ nlog_err(ni, "No room for backup info table\n"); -+ ni->backup_table_ba = 0; -+ return true; -+ } -+ -+ /* Backup info table has been successfully written, record its offset */ -+ ni->backup_table_ba = tmp_table_start_ba; -+ -+ /* Adjust mapping_blocks_off */ -+ ni->mapping_blocks_ba = tmp_table_end_ba; -+ -+ /* Erase spare blocks of main table to clean possible interference data */ -+ nmbm_erase_range(ni, main_table_end_ba, ni->backup_table_ba); -+ -+ nlog_table_creation(ni, false, tmp_table_start_ba, tmp_table_end_ba); -+ -+ return true; -+} -+ -+/* -+ * nmbm_update_info_table_once - Update info table once -+ * @ni: NMBM instance structure -+ * @force: force update -+ * -+ * Update both main and backup info table. Return true if at least one info -+ * table has been successfully written. -+ * This function only try to update info table once regard less of the result. -+ */ -+static bool nmbm_update_info_table_once(struct nmbm_instance *ni, bool force) -+{ -+ uint32_t table_start_ba, table_end_ba; -+ uint32_t main_table_limit; -+ bool success; -+ -+ /* Do nothing if there is no change */ -+ if (!nmbm_generate_info_table_cache(ni) && !force) -+ return true; -+ -+ /* Check whether both two tables exist */ -+ if (!ni->backup_table_ba) { -+ main_table_limit = ni->mapping_blocks_top_ba; -+ goto write_main_table; -+ } -+ -+ /* -+ * Write backup info table in its current range. -+ * Note that limit is set to mapping_blocks_top_off to provide as many -+ * spare blocks as possible for the backup table. If at last -+ * unmapped blocks are used by backup table, mapping_blocks_off will -+ * be adjusted. -+ */ -+ success = nmbm_write_info_table(ni, ni->backup_table_ba, -+ ni->mapping_blocks_top_ba, -+ &table_start_ba, &table_end_ba); -+ if (!success) { -+ /* -+ * There is nothing to do if failed to write backup table. -+ * Write the main table now. -+ */ -+ nlog_err(ni, "No room for backup table\n"); -+ ni->mapping_blocks_ba = ni->backup_table_ba; -+ ni->backup_table_ba = 0; -+ main_table_limit = ni->mapping_blocks_top_ba; -+ goto write_main_table; -+ } -+ -+ /* Backup table is successfully written, record its offset */ -+ ni->backup_table_ba = table_start_ba; -+ -+ /* Adjust mapping_blocks_off */ -+ ni->mapping_blocks_ba = table_end_ba; -+ -+ nmbm_mark_tables_clean(ni); -+ -+ /* The normal limit of main table */ -+ main_table_limit = ni->backup_table_ba; -+ -+ nlog_table_update(ni, false, table_start_ba, table_end_ba); -+ -+write_main_table: -+ if (!ni->main_table_ba) -+ goto rebuild_tables; -+ -+ /* Write main info table in its current range */ -+ success = nmbm_write_info_table(ni, ni->main_table_ba, -+ main_table_limit, &table_start_ba, -+ &table_end_ba); -+ if (!success) { -+ /* If failed to write main table, go rescue procedure */ -+ if (!ni->backup_table_ba) -+ goto rebuild_tables; -+ -+ return nmbm_rescue_main_info_table(ni); -+ } -+ -+ /* Main info table is successfully written, record its offset */ -+ ni->main_table_ba = table_start_ba; -+ -+ /* Adjust mapping_blocks_off */ -+ if (!ni->backup_table_ba) -+ ni->mapping_blocks_ba = table_end_ba; -+ -+ nmbm_mark_tables_clean(ni); -+ -+ nlog_table_update(ni, true, table_start_ba, table_end_ba); -+ -+ return true; -+ -+rebuild_tables: -+ return nmbm_rebuild_info_table(ni); -+} -+ -+/* -+ * nmbm_update_info_table - Update info table -+ * @ni: NMBM instance structure -+ * -+ * Update both main and backup info table. Return true if at least one table -+ * has been successfully written. -+ * This function will try to update info table repeatedly until no new bad -+ * block found during updating. -+ */ -+static bool nmbm_update_info_table(struct nmbm_instance *ni) -+{ -+ bool success; -+ -+ if (ni->protected) -+ return true; -+ -+ while (ni->block_state_changed || ni->block_mapping_changed) { -+ success = nmbm_update_info_table_once(ni, false); -+ if (!success) { -+ nlog_err(ni, "Failed to update info table\n"); -+ return false; -+ } -+ } -+ -+ return true; -+} -+ -+/* -+ * nmbm_map_block - Map a bad block to a unused spare block -+ * @ni: NMBM instance structure -+ * @lb: logic block addr to map -+ */ -+static bool nmbm_map_block(struct nmbm_instance *ni, uint32_t lb) -+{ -+ uint32_t pb; -+ bool success; -+ -+ if (ni->mapping_blocks_ba == ni->mapping_blocks_top_ba) { -+ nlog_warn(ni, "No spare unmapped blocks.\n"); -+ return false; -+ } -+ -+ success = nmbm_block_walk(ni, false, ni->mapping_blocks_top_ba, &pb, 0, -+ ni->mapping_blocks_ba); -+ if (!success) { -+ nlog_warn(ni, "No spare unmapped blocks.\n"); -+ nmbm_update_info_table(ni); -+ ni->mapping_blocks_top_ba = ni->mapping_blocks_ba; -+ return false; -+ } -+ -+ ni->block_mapping[lb] = pb; -+ ni->mapping_blocks_top_ba--; -+ ni->block_mapping_changed++; -+ -+ nlog_info(ni, "Logic block %u mapped to physical block %u\n", lb, pb); -+ -+ return true; -+} -+ -+/* -+ * nmbm_create_info_table - Create info table(s) -+ * @ni: NMBM instance structure -+ * -+ * This function assumes that the chip has no existing info table(s) -+ */ -+static bool nmbm_create_info_table(struct nmbm_instance *ni) -+{ -+ uint32_t lb; -+ bool success; -+ -+ /* Set initial mapping_blocks_top_off */ -+ success = nmbm_block_walk(ni, false, ni->signature_ba, -+ &ni->mapping_blocks_top_ba, 1, -+ ni->mgmt_start_ba); -+ if (!success) { -+ nlog_err(ni, "No room for spare blocks\n"); -+ return false; -+ } -+ -+ /* Generate info table cache */ -+ nmbm_generate_info_table_cache(ni); -+ -+ /* Write info table */ -+ success = nmbm_rebuild_info_table(ni); -+ if (!success) { -+ nlog_err(ni, "Failed to build info tables\n"); -+ return false; -+ } -+ -+ /* Remap bad block(s) at end of data area */ -+ for (lb = ni->data_block_count; lb < ni->mgmt_start_ba; lb++) { -+ success = nmbm_map_block(ni, lb); -+ if (!success) -+ break; -+ -+ ni->data_block_count++; -+ } -+ -+ /* If state table and/or mapping table changed, update info table. */ -+ success = nmbm_update_info_table(ni); -+ if (!success) -+ return false; -+ -+ return true; -+} -+ -+/* -+ * nmbm_create_new - Create NMBM on a new chip -+ * @ni: NMBM instance structure -+ */ -+static bool nmbm_create_new(struct nmbm_instance *ni) -+{ -+ bool success; -+ -+ /* Determine the boundary of management blocks */ -+ ni->mgmt_start_ba = ni->block_count * (NMBM_MGMT_DIV - ni->max_ratio) / NMBM_MGMT_DIV; -+ -+ if (ni->max_reserved_blocks && ni->block_count - ni->mgmt_start_ba > ni->max_reserved_blocks) -+ ni->mgmt_start_ba = ni->block_count - ni->max_reserved_blocks; -+ -+ nlog_info(ni, "NMBM management region starts at block %u [0x%08llx]\n", -+ ni->mgmt_start_ba, ba2addr(ni, ni->mgmt_start_ba)); -+ -+ /* Fill block state table & mapping table */ -+ nmbm_scan_badblocks(ni); -+ nmbm_build_mapping_table(ni); -+ -+ /* Write signature */ -+ ni->signature.header.magic = NMBM_MAGIC_SIGNATURE; -+ ni->signature.header.version = NMBM_VER; -+ ni->signature.header.size = sizeof(ni->signature); -+ ni->signature.nand_size = bmtd.total_blks << bmtd.blk_shift; -+ ni->signature.block_size = bmtd.blk_size; -+ ni->signature.page_size = bmtd.pg_size; -+ ni->signature.spare_size = bmtd.mtd->oobsize; -+ ni->signature.mgmt_start_pb = ni->mgmt_start_ba; -+ ni->signature.max_try_count = NMBM_TRY_COUNT; -+ nmbm_update_checksum(&ni->signature.header); -+ -+ success = nmbm_write_signature(ni, ni->mgmt_start_ba, -+ &ni->signature, &ni->signature_ba); -+ if (!success) { -+ nlog_err(ni, "Failed to write signature to a proper offset\n"); -+ return false; -+ } -+ -+ nlog_info(ni, "Signature has been written to block %u [0x%08llx]\n", -+ ni->signature_ba, ba2addr(ni, ni->signature_ba)); -+ -+ /* Write info table(s) */ -+ success = nmbm_create_info_table(ni); -+ if (success) { -+ nlog_info(ni, "NMBM has been successfully created\n"); -+ return true; -+ } -+ -+ return false; -+} -+ -+/* -+ * nmbm_check_info_table_header - Check if a info table header is valid -+ * @ni: NMBM instance structure -+ * @data: pointer to the info table header -+ */ -+static bool nmbm_check_info_table_header(struct nmbm_instance *ni, void *data) -+{ -+ struct nmbm_info_table_header *ifthdr = data; -+ -+ if (ifthdr->header.magic != NMBM_MAGIC_INFO_TABLE) -+ return false; -+ -+ if (ifthdr->header.size != ni->info_table_size) -+ return false; -+ -+ if (ifthdr->mapping_table_off - ifthdr->state_table_off < ni->state_table_size) -+ return false; -+ -+ if (ni->info_table_size - ifthdr->mapping_table_off < ni->mapping_table_size) -+ return false; -+ -+ return true; -+} -+ -+/* -+ * nmbm_check_info_table - Check if a whole info table is valid -+ * @ni: NMBM instance structure -+ * @start_ba: start block address of this table -+ * @end_ba: end block address of this table -+ * @data: pointer to the info table header -+ * @mapping_blocks_top_ba: return the block address of top remapped block -+ */ -+static bool nmbm_check_info_table(struct nmbm_instance *ni, uint32_t start_ba, -+ uint32_t end_ba, void *data, -+ uint32_t *mapping_blocks_top_ba) -+{ -+ struct nmbm_info_table_header *ifthdr = data; -+ int32_t *block_mapping = (int32_t *)((uintptr_t)data + ifthdr->mapping_table_off); -+ u32 *block_state = (u32 *)((uintptr_t)data + ifthdr->state_table_off); -+ uint32_t minimum_mapping_pb = ni->signature_ba; -+ uint32_t ba; -+ -+ for (ba = 0; ba < ni->data_block_count; ba++) { -+ if ((block_mapping[ba] >= ni->data_block_count && block_mapping[ba] < end_ba) || -+ block_mapping[ba] == ni->signature_ba) -+ return false; -+ -+ if (block_mapping[ba] >= end_ba && block_mapping[ba] < minimum_mapping_pb) -+ minimum_mapping_pb = block_mapping[ba]; -+ } -+ -+ for (ba = start_ba; ba < end_ba; ba++) { -+ if (nmbm_get_block_state(ni, ba) != BLOCK_ST_GOOD) -+ continue; -+ -+ if (nmbm_get_block_state_raw(block_state, ba) != BLOCK_ST_GOOD) -+ return false; -+ } -+ -+ *mapping_blocks_top_ba = minimum_mapping_pb - 1; -+ -+ return true; -+} -+ -+/* -+ * nmbm_try_load_info_table - Try to load info table from a address -+ * @ni: NMBM instance structure -+ * @ba: start block address of the info table -+ * @eba: return the block address after end of the table -+ * @write_count: return the write count of this table -+ * @mapping_blocks_top_ba: return the block address of top remapped block -+ * @table_loaded: used to record whether ni->info_table has valid data -+ */ -+static bool nmbm_try_load_info_table(struct nmbm_instance *ni, uint32_t ba, -+ uint32_t *eba, uint32_t *write_count, -+ uint32_t *mapping_blocks_top_ba, -+ bool table_loaded) -+{ -+ struct nmbm_info_table_header *ifthdr = (void *)ni->info_table_cache; -+ uint8_t *off = ni->info_table_cache; -+ uint32_t limit = ba + size2blk(ni, ni->info_table_size); -+ uint32_t start_ba = 0, chunksize, sizeremain = ni->info_table_size; -+ bool success, checkhdr = true; -+ int ret; -+ -+ while (sizeremain && ba < limit) { -+ if (nmbm_get_block_state(ni, ba) != BLOCK_ST_GOOD) -+ goto next_block; -+ -+ if (nmbm_check_bad_phys_block(ni, ba)) { -+ nmbm_set_block_state(ni, ba, BLOCK_ST_BAD); -+ goto next_block; -+ } -+ -+ chunksize = sizeremain; -+ if (chunksize > bmtd.blk_size) -+ chunksize = bmtd.blk_size; -+ -+ /* Assume block with ECC error has no info table data */ -+ ret = nmbn_read_data(ni, ba2addr(ni, ba), off, chunksize); -+ if (ret < 0) -+ goto skip_bad_block; -+ else if (ret > 0) -+ return false; -+ -+ if (checkhdr) { -+ success = nmbm_check_info_table_header(ni, off); -+ if (!success) -+ return false; -+ -+ start_ba = ba; -+ checkhdr = false; -+ } -+ -+ off += chunksize; -+ sizeremain -= chunksize; -+ -+ goto next_block; -+ -+ skip_bad_block: -+ /* Only mark bad in memory */ -+ nmbm_set_block_state(ni, ba, BLOCK_ST_BAD); -+ -+ next_block: -+ ba++; -+ } -+ -+ if (sizeremain) -+ return false; -+ -+ success = nmbm_check_header(ni->info_table_cache, ni->info_table_size); -+ if (!success) -+ return false; -+ -+ *eba = ba; -+ *write_count = ifthdr->write_count; -+ -+ success = nmbm_check_info_table(ni, start_ba, ba, ni->info_table_cache, -+ mapping_blocks_top_ba); -+ if (!success) -+ return false; -+ -+ if (!table_loaded || ifthdr->write_count > ni->info_table.write_count) { -+ memcpy(&ni->info_table, ifthdr, sizeof(ni->info_table)); -+ memcpy(ni->block_state, -+ (uint8_t *)ifthdr + ifthdr->state_table_off, -+ ni->state_table_size); -+ memcpy(ni->block_mapping, -+ (uint8_t *)ifthdr + ifthdr->mapping_table_off, -+ ni->mapping_table_size); -+ ni->info_table.write_count = ifthdr->write_count; -+ } -+ -+ return true; -+} -+ -+/* -+ * nmbm_search_info_table - Search info table from specific address -+ * @ni: NMBM instance structure -+ * @ba: start block address to search -+ * @limit: highest block address allowed for searching -+ * @table_start_ba: return the start block address of this table -+ * @table_end_ba: return the block address after end of this table -+ * @write_count: return the write count of this table -+ * @mapping_blocks_top_ba: return the block address of top remapped block -+ * @table_loaded: used to record whether ni->info_table has valid data -+ */ -+static bool nmbm_search_info_table(struct nmbm_instance *ni, uint32_t ba, -+ uint32_t limit, uint32_t *table_start_ba, -+ uint32_t *table_end_ba, -+ uint32_t *write_count, -+ uint32_t *mapping_blocks_top_ba, -+ bool table_loaded) -+{ -+ bool success; -+ -+ while (ba < limit - size2blk(ni, ni->info_table_size)) { -+ success = nmbm_try_load_info_table(ni, ba, table_end_ba, -+ write_count, -+ mapping_blocks_top_ba, -+ table_loaded); -+ if (success) { -+ *table_start_ba = ba; -+ return true; -+ } -+ -+ ba++; -+ } -+ -+ return false; -+} -+ -+/* -+ * nmbm_load_info_table - Load info table(s) from a chip -+ * @ni: NMBM instance structure -+ * @ba: start block address to search info table -+ * @limit: highest block address allowed for searching -+ */ -+static bool nmbm_load_info_table(struct nmbm_instance *ni, uint32_t ba, -+ uint32_t limit) -+{ -+ uint32_t main_table_end_ba, backup_table_end_ba, table_end_ba; -+ uint32_t main_mapping_blocks_top_ba, backup_mapping_blocks_top_ba; -+ uint32_t main_table_write_count, backup_table_write_count; -+ uint32_t i; -+ bool success; -+ -+ /* Set initial value */ -+ ni->main_table_ba = 0; -+ ni->backup_table_ba = 0; -+ ni->info_table.write_count = 0; -+ ni->mapping_blocks_top_ba = ni->signature_ba - 1; -+ ni->data_block_count = ni->signature.mgmt_start_pb; -+ -+ /* Find first info table */ -+ success = nmbm_search_info_table(ni, ba, limit, &ni->main_table_ba, -+ &main_table_end_ba, &main_table_write_count, -+ &main_mapping_blocks_top_ba, false); -+ if (!success) { -+ nlog_warn(ni, "No valid info table found\n"); -+ return false; -+ } -+ -+ table_end_ba = main_table_end_ba; -+ -+ nlog_table_found(ni, true, main_table_write_count, ni->main_table_ba, -+ main_table_end_ba); -+ -+ /* Find second info table */ -+ success = nmbm_search_info_table(ni, main_table_end_ba, limit, -+ &ni->backup_table_ba, &backup_table_end_ba, -+ &backup_table_write_count, &backup_mapping_blocks_top_ba, true); -+ if (!success) { -+ nlog_warn(ni, "Second info table not found\n"); -+ } else { -+ table_end_ba = backup_table_end_ba; -+ -+ nlog_table_found(ni, false, backup_table_write_count, -+ ni->backup_table_ba, backup_table_end_ba); -+ } -+ -+ /* Pick mapping_blocks_top_ba */ -+ if (!ni->backup_table_ba) { -+ ni->mapping_blocks_top_ba= main_mapping_blocks_top_ba; -+ } else { -+ if (main_table_write_count >= backup_table_write_count) -+ ni->mapping_blocks_top_ba = main_mapping_blocks_top_ba; -+ else -+ ni->mapping_blocks_top_ba = backup_mapping_blocks_top_ba; -+ } -+ -+ /* Set final mapping_blocks_ba */ -+ ni->mapping_blocks_ba = table_end_ba; -+ -+ /* Set final data_block_count */ -+ for (i = ni->signature.mgmt_start_pb; i > 0; i--) { -+ if (ni->block_mapping[i - 1] >= 0) { -+ ni->data_block_count = i; -+ break; -+ } -+ } -+ -+ /* Regenerate the info table cache from the final selected info table */ -+ nmbm_generate_info_table_cache(ni); -+ -+ /* -+ * If only one table exists, try to write another table. -+ * If two tables have different write count, try to update info table -+ */ -+ if (!ni->backup_table_ba) { -+ success = nmbm_rescue_single_info_table(ni); -+ } else if (main_table_write_count != backup_table_write_count) { -+ /* Mark state & mapping tables changed */ -+ ni->block_state_changed = 1; -+ ni->block_mapping_changed = 1; -+ -+ success = nmbm_update_single_info_table(ni, -+ main_table_write_count < backup_table_write_count); -+ } else { -+ success = true; -+ } -+ -+ /* -+ * If there is no spare unmapped blocks, or still only one table -+ * exists, set the chip to read-only -+ */ -+ if (ni->mapping_blocks_ba == ni->mapping_blocks_top_ba) { -+ nlog_warn(ni, "No spare unmapped blocks. Device is now read-only\n"); -+ ni->protected = 1; -+ } else if (!success) { -+ nlog_warn(ni, "Only one info table found. Device is now read-only\n"); -+ ni->protected = 1; -+ } -+ -+ return true; -+} -+ -+/* -+ * nmbm_load_existing - Load NMBM from a new chip -+ * @ni: NMBM instance structure -+ */ -+static bool nmbm_load_existing(struct nmbm_instance *ni) -+{ -+ bool success; -+ -+ /* Calculate the boundary of management blocks */ -+ ni->mgmt_start_ba = ni->signature.mgmt_start_pb; -+ -+ nlog_debug(ni, "NMBM management region starts at block %u [0x%08llx]\n", -+ ni->mgmt_start_ba, ba2addr(ni, ni->mgmt_start_ba)); -+ -+ /* Look for info table(s) */ -+ success = nmbm_load_info_table(ni, ni->mgmt_start_ba, -+ ni->signature_ba); -+ if (success) { -+ nlog_info(ni, "NMBM has been successfully attached\n"); -+ return true; -+ } -+ -+ if (!ni->force_create) { -+ printk("not creating NMBM table\n"); -+ return false; -+ } -+ -+ /* Fill block state table & mapping table */ -+ nmbm_scan_badblocks(ni); -+ nmbm_build_mapping_table(ni); -+ -+ /* Write info table(s) */ -+ success = nmbm_create_info_table(ni); -+ if (success) { -+ nlog_info(ni, "NMBM has been successfully created\n"); -+ return true; -+ } -+ -+ return false; -+} -+ -+/* -+ * nmbm_find_signature - Find signature in the lower NAND chip -+ * @ni: NMBM instance structure -+ * @signature_ba: used for storing block address of the signature -+ * @signature_ba: return the actual block address of signature block -+ * -+ * Find a valid signature from a specific range in the lower NAND chip, -+ * from bottom (highest address) to top (lowest address) -+ * -+ * Return true if found. -+ */ -+static bool nmbm_find_signature(struct nmbm_instance *ni, -+ struct nmbm_signature *signature, -+ uint32_t *signature_ba) -+{ -+ struct nmbm_signature sig; -+ uint64_t off, addr; -+ uint32_t block_count, ba, limit; -+ bool success; -+ int ret; -+ -+ /* Calculate top and bottom block address */ -+ block_count = bmtd.total_blks; -+ ba = block_count; -+ limit = (block_count / NMBM_MGMT_DIV) * (NMBM_MGMT_DIV - ni->max_ratio); -+ if (ni->max_reserved_blocks && block_count - limit > ni->max_reserved_blocks) -+ limit = block_count - ni->max_reserved_blocks; -+ -+ while (ba >= limit) { -+ ba--; -+ addr = ba2addr(ni, ba); -+ -+ if (nmbm_check_bad_phys_block(ni, ba)) -+ continue; -+ -+ /* Check every page. -+ * As long as at leaset one page contains valid signature, -+ * the block is treated as a valid signature block. -+ */ -+ for (off = 0; off < bmtd.blk_size; -+ off += bmtd.pg_size) { -+ ret = nmbn_read_data(ni, addr + off, &sig, -+ sizeof(sig)); -+ if (ret) -+ continue; -+ -+ /* Check for header size and checksum */ -+ success = nmbm_check_header(&sig, sizeof(sig)); -+ if (!success) -+ continue; -+ -+ /* Check for header magic */ -+ if (sig.header.magic == NMBM_MAGIC_SIGNATURE) { -+ /* Found it */ -+ memcpy(signature, &sig, sizeof(sig)); -+ *signature_ba = ba; -+ return true; -+ } -+ } -+ }; -+ -+ return false; -+} -+ -+/* -+ * nmbm_calc_structure_size - Calculate the instance structure size -+ * @nld: NMBM lower device structure -+ */ -+static size_t nmbm_calc_structure_size(void) -+{ -+ uint32_t state_table_size, mapping_table_size, info_table_size; -+ uint32_t block_count; -+ -+ block_count = bmtd.total_blks; -+ -+ /* Calculate info table size */ -+ state_table_size = ((block_count + NMBM_BITMAP_BLOCKS_PER_UNIT - 1) / -+ NMBM_BITMAP_BLOCKS_PER_UNIT) * NMBM_BITMAP_UNIT_SIZE; -+ mapping_table_size = block_count * sizeof(int32_t); -+ -+ info_table_size = ALIGN(sizeof(struct nmbm_info_table_header), -+ bmtd.pg_size); -+ info_table_size += ALIGN(state_table_size, bmtd.pg_size); -+ info_table_size += ALIGN(mapping_table_size, bmtd.pg_size); -+ -+ return info_table_size + state_table_size + mapping_table_size + -+ sizeof(struct nmbm_instance); -+} -+ -+/* -+ * nmbm_init_structure - Initialize members of instance structure -+ * @ni: NMBM instance structure -+ */ -+static void nmbm_init_structure(struct nmbm_instance *ni) -+{ -+ uint32_t pages_per_block, blocks_per_chip; -+ uintptr_t ptr; -+ -+ pages_per_block = bmtd.blk_size / bmtd.pg_size; -+ blocks_per_chip = bmtd.total_blks; -+ -+ ni->rawpage_size = bmtd.pg_size + bmtd.mtd->oobsize; -+ ni->rawblock_size = pages_per_block * ni->rawpage_size; -+ ni->rawchip_size = blocks_per_chip * ni->rawblock_size; -+ -+ /* Calculate number of block this chip */ -+ ni->block_count = blocks_per_chip; -+ -+ /* Calculate info table size */ -+ ni->state_table_size = ((ni->block_count + NMBM_BITMAP_BLOCKS_PER_UNIT - 1) / -+ NMBM_BITMAP_BLOCKS_PER_UNIT) * NMBM_BITMAP_UNIT_SIZE; -+ ni->mapping_table_size = ni->block_count * sizeof(*ni->block_mapping); -+ -+ ni->info_table_size = ALIGN(sizeof(ni->info_table), -+ bmtd.pg_size); -+ ni->info_table.state_table_off = ni->info_table_size; -+ -+ ni->info_table_size += ALIGN(ni->state_table_size, -+ bmtd.pg_size); -+ ni->info_table.mapping_table_off = ni->info_table_size; -+ -+ ni->info_table_size += ALIGN(ni->mapping_table_size, -+ bmtd.pg_size); -+ -+ ni->info_table_spare_blocks = nmbm_get_spare_block_count( -+ size2blk(ni, ni->info_table_size)); -+ -+ /* Assign memory to members */ -+ ptr = (uintptr_t)ni + sizeof(*ni); -+ -+ ni->info_table_cache = (void *)ptr; -+ ptr += ni->info_table_size; -+ -+ ni->block_state = (void *)ptr; -+ ptr += ni->state_table_size; -+ -+ ni->block_mapping = (void *)ptr; -+ ptr += ni->mapping_table_size; -+ -+ ni->page_cache = bmtd.data_buf; -+ -+ /* Initialize block state table */ -+ ni->block_state_changed = 0; -+ memset(ni->block_state, 0xff, ni->state_table_size); -+ -+ /* Initialize block mapping table */ -+ ni->block_mapping_changed = 0; -+} -+ -+/* -+ * nmbm_attach - Attach to a lower device -+ * @ni: NMBM instance structure -+ */ -+static int nmbm_attach(struct nmbm_instance *ni) -+{ -+ bool success; -+ -+ if (!ni) -+ return -EINVAL; -+ -+ /* Initialize NMBM instance */ -+ nmbm_init_structure(ni); -+ -+ success = nmbm_find_signature(ni, &ni->signature, &ni->signature_ba); -+ if (!success) { -+ if (!ni->force_create) { -+ nlog_err(ni, "Signature not found\n"); -+ return -ENODEV; -+ } -+ -+ success = nmbm_create_new(ni); -+ if (!success) -+ return -ENODEV; -+ -+ return 0; -+ } -+ -+ nlog_info(ni, "Signature found at block %u [0x%08llx]\n", -+ ni->signature_ba, ba2addr(ni, ni->signature_ba)); -+ -+ if (ni->signature.header.version != NMBM_VER) { -+ nlog_err(ni, "NMBM version %u.%u is not supported\n", -+ NMBM_VERSION_MAJOR_GET(ni->signature.header.version), -+ NMBM_VERSION_MINOR_GET(ni->signature.header.version)); -+ return -EINVAL; -+ } -+ -+ if (ni->signature.nand_size != bmtd.total_blks << bmtd.blk_shift || -+ ni->signature.block_size != bmtd.blk_size || -+ ni->signature.page_size != bmtd.pg_size || -+ ni->signature.spare_size != bmtd.mtd->oobsize) { -+ nlog_err(ni, "NMBM configuration mismatch\n"); -+ return -EINVAL; -+ } -+ -+ success = nmbm_load_existing(ni); -+ if (!success) -+ return -ENODEV; -+ -+ return 0; -+} -+ -+static bool remap_block_nmbm(u16 block, u16 mapped_block, int copy_len) -+{ -+ struct nmbm_instance *ni = bmtd.ni; -+ int new_block; -+ -+ if (block >= ni->data_block_count) -+ return false; -+ -+ nmbm_set_block_state(ni, mapped_block, BLOCK_ST_BAD); -+ if (!nmbm_map_block(ni, block)) -+ return false; -+ -+ new_block = ni->block_mapping[block]; -+ bbt_nand_erase(new_block); -+ if (copy_len > 0) -+ bbt_nand_copy(new_block, mapped_block, copy_len); -+ nmbm_update_info_table(ni); -+ -+ return true; -+} -+ -+static int get_mapping_block_index_nmbm(int block) -+{ -+ struct nmbm_instance *ni = bmtd.ni; -+ -+ if (block >= ni->data_block_count) -+ return -1; -+ -+ return ni->block_mapping[block]; -+} -+ -+static int mtk_bmt_init_nmbm(struct device_node *np) -+{ -+ struct nmbm_instance *ni; -+ int ret; -+ -+ ni = kzalloc(nmbm_calc_structure_size(), GFP_KERNEL); -+ if (!ni) -+ return -ENOMEM; -+ -+ bmtd.ni = ni; -+ -+ if (of_property_read_u32(np, "mediatek,bmt-max-ratio", &ni->max_ratio)) -+ ni->max_ratio = 1; -+ if (of_property_read_u32(np, "mediatek,bmt-max-reserved-blocks", -+ &ni->max_reserved_blocks)) -+ ni->max_reserved_blocks = 256; -+ if (of_property_read_bool(np, "mediatek,empty-page-ecc-protected")) -+ ni->empty_page_ecc_ok = true; -+ if (of_property_read_bool(np, "mediatek,bmt-force-create")) -+ ni->force_create = true; -+ -+ ret = nmbm_attach(ni); -+ if (ret) -+ goto out; -+ -+ bmtd.mtd->size = ni->data_block_count << bmtd.blk_shift; -+ -+ return 0; -+ -+out: -+ kfree(ni); -+ bmtd.ni = NULL; -+ -+ return ret; -+} -+ -+static int mtk_bmt_debug_nmbm(void *data, u64 val) -+{ -+ struct nmbm_instance *ni = bmtd.ni; -+ int i; -+ -+ switch (val) { -+ case 0: -+ for (i = 1; i < ni->data_block_count; i++) { -+ if (ni->block_mapping[i] < ni->mapping_blocks_ba) -+ continue; -+ -+ printk("remap [%x->%x]\n", i, ni->block_mapping[i]); -+ } -+ } -+ -+ return 0; -+} -+ -+static void unmap_block_nmbm(u16 block) -+{ -+ struct nmbm_instance *ni = bmtd.ni; -+ int start, offset; -+ int new_block; -+ -+ if (block >= ni->data_block_count) -+ return; -+ -+ start = block; -+ offset = 0; -+ while (ni->block_mapping[start] >= ni->mapping_blocks_ba) { -+ start--; -+ offset++; -+ if (start < 0) -+ return; -+ } -+ -+ if (!offset) -+ return; -+ -+ new_block = ni->block_mapping[start] + offset; -+ nmbm_set_block_state(ni, new_block, BLOCK_ST_GOOD); -+ ni->block_mapping[block] = new_block; -+ ni->block_mapping_changed++; -+ -+ new_block = ni->signature_ba - 1; -+ for (block = 0; block < ni->data_block_count; block++) { -+ int cur = ni->block_mapping[block]; -+ -+ if (cur < ni->mapping_blocks_ba) -+ continue; -+ -+ if (cur <= new_block) -+ new_block = cur - 1; -+ } -+ -+ ni->mapping_blocks_top_ba = new_block; -+ -+ nmbm_update_info_table(ni); -+} -+ -+const struct mtk_bmt_ops mtk_bmt_nmbm_ops = { -+ .init = mtk_bmt_init_nmbm, -+ .remap_block = remap_block_nmbm, -+ .unmap_block = unmap_block_nmbm, -+ .get_mapping_block = get_mapping_block_index_nmbm, -+ .debug = mtk_bmt_debug_nmbm, -+}; -diff --git a/drivers/mtd/nand/mtk_bmt_v2.c b/drivers/mtd/nand/mtk_bmt_v2.c -new file mode 100644 -index 000000000000..a17b7290260b ---- /dev/null -+++ b/drivers/mtd/nand/mtk_bmt_v2.c -@@ -0,0 +1,506 @@ -+/* -+ * Copyright (c) 2017 MediaTek Inc. -+ * Author: Xiangsheng Hou -+ * Copyright (c) 2020-2022 Felix Fietkau -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+#include "mtk_bmt.h" -+ -+struct bbbt { -+ char signature[3]; -+ /* This version is used to distinguish the legacy and new algorithm */ -+#define BBMT_VERSION 2 -+ unsigned char version; -+ /* Below 2 tables will be written in SLC */ -+ u16 bb_tbl[]; -+}; -+ -+struct bbmt { -+ u16 block; -+#define NO_MAPPED 0 -+#define NORMAL_MAPPED 1 -+#define BMT_MAPPED 2 -+ u16 mapped; -+}; -+ -+/* Maximum 8k blocks */ -+#define BBPOOL_RATIO 2 -+#define BB_TABLE_MAX bmtd.table_size -+#define BMT_TABLE_MAX (BB_TABLE_MAX * BBPOOL_RATIO / 100) -+#define BMT_TBL_DEF_VAL 0x0 -+ -+static inline struct bbmt *bmt_tbl(struct bbbt *bbbt) -+{ -+ return (struct bbmt *)&bbbt->bb_tbl[bmtd.table_size]; -+} -+ -+static u16 find_valid_block(u16 block) -+{ -+ u8 fdm[4]; -+ int ret; -+ int loop = 0; -+ -+retry: -+ if (block >= bmtd.total_blks) -+ return 0; -+ -+ ret = bbt_nand_read(blk_pg(block), bmtd.data_buf, bmtd.pg_size, -+ fdm, sizeof(fdm)); -+ /* Read the 1st byte of FDM to judge whether it's a bad -+ * or not -+ */ -+ if (ret || fdm[0] != 0xff) { -+ pr_info("nand: found bad block 0x%x\n", block); -+ if (loop >= bmtd.bb_max) { -+ pr_info("nand: FATAL ERR: too many bad blocks!!\n"); -+ return 0; -+ } -+ -+ loop++; -+ block++; -+ goto retry; -+ } -+ -+ return block; -+} -+ -+/* Find out all bad blocks, and fill in the mapping table */ -+static int scan_bad_blocks(struct bbbt *bbt) -+{ -+ int i; -+ u16 block = 0; -+ -+ /* First time download, the block0 MUST NOT be a bad block, -+ * this is guaranteed by vendor -+ */ -+ bbt->bb_tbl[0] = 0; -+ -+ /* -+ * Construct the mapping table of Normal data area(non-PMT/BMTPOOL) -+ * G - Good block; B - Bad block -+ * --------------------------- -+ * physical |G|G|B|G|B|B|G|G|G|G|B|G|B| -+ * --------------------------- -+ * What bb_tbl[i] looks like: -+ * physical block(i): -+ * 0 1 2 3 4 5 6 7 8 9 a b c -+ * mapped block(bb_tbl[i]): -+ * 0 1 3 6 7 8 9 b ...... -+ * ATTENTION: -+ * If new bad block ocurred(n), search bmt_tbl to find -+ * a available block(x), and fill in the bb_tbl[n] = x; -+ */ -+ for (i = 1; i < bmtd.pool_lba; i++) { -+ bbt->bb_tbl[i] = find_valid_block(bbt->bb_tbl[i - 1] + 1); -+ BBT_LOG("bb_tbl[0x%x] = 0x%x", i, bbt->bb_tbl[i]); -+ if (bbt->bb_tbl[i] == 0) -+ return -1; -+ } -+ -+ /* Physical Block start Address of BMT pool */ -+ bmtd.pool_pba = bbt->bb_tbl[i - 1] + 1; -+ if (bmtd.pool_pba >= bmtd.total_blks - 2) { -+ pr_info("nand: FATAL ERR: Too many bad blocks!!\n"); -+ return -1; -+ } -+ -+ BBT_LOG("pool_pba=0x%x", bmtd.pool_pba); -+ i = 0; -+ block = bmtd.pool_pba; -+ /* -+ * The bmt table is used for runtime bad block mapping -+ * G - Good block; B - Bad block -+ * --------------------------- -+ * physical |G|G|B|G|B|B|G|G|G|G|B|G|B| -+ * --------------------------- -+ * block: 0 1 2 3 4 5 6 7 8 9 a b c -+ * What bmt_tbl[i] looks like in initial state: -+ * i: -+ * 0 1 2 3 4 5 6 7 -+ * bmt_tbl[i].block: -+ * 0 1 3 6 7 8 9 b -+ * bmt_tbl[i].mapped: -+ * N N N N N N N B -+ * N - Not mapped(Available) -+ * M - Mapped -+ * B - BMT -+ * ATTENTION: -+ * BMT always in the last valid block in pool -+ */ -+ while ((block = find_valid_block(block)) != 0) { -+ bmt_tbl(bbt)[i].block = block; -+ bmt_tbl(bbt)[i].mapped = NO_MAPPED; -+ BBT_LOG("bmt_tbl[%d].block = 0x%x", i, block); -+ block++; -+ i++; -+ } -+ -+ /* i - How many available blocks in pool, which is the length of bmt_tbl[] -+ * bmtd.bmt_blk_idx - bmt_tbl[bmtd.bmt_blk_idx].block => the BMT block -+ */ -+ bmtd.bmt_blk_idx = i - 1; -+ bmt_tbl(bbt)[bmtd.bmt_blk_idx].mapped = BMT_MAPPED; -+ -+ if (i < 1) { -+ pr_info("nand: FATAL ERR: no space to store BMT!!\n"); -+ return -1; -+ } -+ -+ pr_info("[BBT] %d available blocks in BMT pool\n", i); -+ -+ return 0; -+} -+ -+static bool is_valid_bmt(unsigned char *buf, unsigned char *fdm) -+{ -+ struct bbbt *bbt = (struct bbbt *)buf; -+ u8 *sig = (u8*)bbt->signature + MAIN_SIGNATURE_OFFSET; -+ -+ -+ if (memcmp(bbt->signature + MAIN_SIGNATURE_OFFSET, "BMT", 3) == 0 && -+ memcmp(fdm + OOB_SIGNATURE_OFFSET, "bmt", 3) == 0) { -+ if (bbt->version == BBMT_VERSION) -+ return true; -+ } -+ BBT_LOG("[BBT] BMT Version not match,upgrage preloader and uboot please! sig=%02x%02x%02x, fdm=%02x%02x%02x", -+ sig[0], sig[1], sig[2], -+ fdm[1], fdm[2], fdm[3]); -+ return false; -+} -+ -+static u16 get_bmt_index(struct bbmt *bmt) -+{ -+ int i = 0; -+ -+ while (bmt[i].block != BMT_TBL_DEF_VAL) { -+ if (bmt[i].mapped == BMT_MAPPED) -+ return i; -+ i++; -+ } -+ return 0; -+} -+ -+/* Write the Burner Bad Block Table to Nand Flash -+ * n - write BMT to bmt_tbl[n] -+ */ -+static u16 upload_bmt(struct bbbt *bbt, int n) -+{ -+ u16 block; -+ -+retry: -+ if (n < 0 || bmt_tbl(bbt)[n].mapped == NORMAL_MAPPED) { -+ pr_info("nand: FATAL ERR: no space to store BMT!\n"); -+ return (u16)-1; -+ } -+ -+ block = bmt_tbl(bbt)[n].block; -+ BBT_LOG("n = 0x%x, block = 0x%x", n, block); -+ if (bbt_nand_erase(block)) { -+ bmt_tbl(bbt)[n].block = 0; -+ /* erase failed, try the previous block: bmt_tbl[n - 1].block */ -+ n--; -+ goto retry; -+ } -+ -+ /* The signature offset is fixed set to 0, -+ * oob signature offset is fixed set to 1 -+ */ -+ memcpy(bbt->signature + MAIN_SIGNATURE_OFFSET, "BMT", 3); -+ bbt->version = BBMT_VERSION; -+ -+ if (write_bmt(block, (unsigned char *)bbt)) { -+ bmt_tbl(bbt)[n].block = 0; -+ -+ /* write failed, try the previous block in bmt_tbl[n - 1] */ -+ n--; -+ goto retry; -+ } -+ -+ /* Return the current index(n) of BMT pool (bmt_tbl[n]) */ -+ return n; -+} -+ -+static u16 find_valid_block_in_pool(struct bbbt *bbt) -+{ -+ int i; -+ -+ if (bmtd.bmt_blk_idx == 0) -+ goto error; -+ -+ for (i = 0; i < bmtd.bmt_blk_idx; i++) { -+ if (bmt_tbl(bbt)[i].block != 0 && bmt_tbl(bbt)[i].mapped == NO_MAPPED) { -+ bmt_tbl(bbt)[i].mapped = NORMAL_MAPPED; -+ return bmt_tbl(bbt)[i].block; -+ } -+ } -+ -+error: -+ pr_info("nand: FATAL ERR: BMT pool is run out!\n"); -+ return 0; -+} -+ -+/* We met a bad block, mark it as bad and map it to a valid block in pool, -+ * if it's a write failure, we need to write the data to mapped block -+ */ -+static bool remap_block_v2(u16 block, u16 mapped_block, int copy_len) -+{ -+ u16 new_block; -+ struct bbbt *bbt; -+ -+ bbt = bmtd.bbt; -+ new_block = find_valid_block_in_pool(bbt); -+ if (new_block == 0) -+ return false; -+ -+ /* Map new bad block to available block in pool */ -+ bbt->bb_tbl[block] = new_block; -+ -+ /* Erase new block */ -+ bbt_nand_erase(new_block); -+ if (copy_len > 0) -+ bbt_nand_copy(new_block, mapped_block, copy_len); -+ -+ bmtd.bmt_blk_idx = upload_bmt(bbt, bmtd.bmt_blk_idx); -+ -+ return true; -+} -+ -+static int get_mapping_block_index_v2(int block) -+{ -+ int start, end; -+ -+ if (block >= bmtd.pool_lba) -+ return block; -+ -+ if (!mapping_block_in_range(block, &start, &end)) -+ return block; -+ -+ return bmtd.bbt->bb_tbl[block]; -+} -+ -+static void -+unmap_block_v2(u16 block) -+{ -+ bmtd.bbt->bb_tbl[block] = block; -+ bmtd.bmt_blk_idx = upload_bmt(bmtd.bbt, bmtd.bmt_blk_idx); -+} -+ -+static unsigned long * -+mtk_bmt_get_mapping_mask(void) -+{ -+ struct bbmt *bbmt = bmt_tbl(bmtd.bbt); -+ int main_blocks = bmtd.mtd->size >> bmtd.blk_shift; -+ unsigned long *used; -+ int i, k; -+ -+ used = kcalloc(BIT_WORD(bmtd.bmt_blk_idx) + 1, sizeof(unsigned long), GFP_KERNEL); -+ if (!used) -+ return NULL; -+ -+ for (i = 1; i < main_blocks; i++) { -+ if (bmtd.bbt->bb_tbl[i] == i) -+ continue; -+ -+ for (k = 0; k < bmtd.bmt_blk_idx; k++) { -+ if (bmtd.bbt->bb_tbl[i] != bbmt[k].block) -+ continue; -+ -+ set_bit(k, used); -+ break; -+ } -+ } -+ -+ return used; -+} -+ -+static int mtk_bmt_debug_v2(void *data, u64 val) -+{ -+ struct bbmt *bbmt = bmt_tbl(bmtd.bbt); -+ struct mtd_info *mtd = bmtd.mtd; -+ unsigned long *used; -+ int main_blocks = mtd->size >> bmtd.blk_shift; -+ int n_remap = 0; -+ int i; -+ -+ used = mtk_bmt_get_mapping_mask(); -+ if (!used) -+ return -ENOMEM; -+ -+ switch (val) { -+ case 0: -+ for (i = 1; i < main_blocks; i++) { -+ if (bmtd.bbt->bb_tbl[i] == i) -+ continue; -+ -+ printk("remap [%x->%x]\n", i, bmtd.bbt->bb_tbl[i]); -+ n_remap++; -+ } -+ for (i = 0; i <= bmtd.bmt_blk_idx; i++) { -+ char c; -+ -+ switch (bbmt[i].mapped) { -+ case NO_MAPPED: -+ continue; -+ case NORMAL_MAPPED: -+ c = 'm'; -+ if (test_bit(i, used)) -+ c = 'M'; -+ break; -+ case BMT_MAPPED: -+ c = 'B'; -+ break; -+ default: -+ c = 'X'; -+ break; -+ } -+ printk("[%x:%c] = 0x%x\n", i, c, bbmt[i].block); -+ } -+ break; -+ case 100: -+ for (i = 0; i <= bmtd.bmt_blk_idx; i++) { -+ if (bbmt[i].mapped != NORMAL_MAPPED) -+ continue; -+ -+ if (test_bit(i, used)) -+ continue; -+ -+ n_remap++; -+ bbmt[i].mapped = NO_MAPPED; -+ printk("free block [%d:%x]\n", i, bbmt[i].block); -+ } -+ if (n_remap) -+ bmtd.bmt_blk_idx = upload_bmt(bmtd.bbt, bmtd.bmt_blk_idx); -+ break; -+ } -+ -+ kfree(used); -+ -+ return 0; -+} -+ -+static int mtk_bmt_init_v2(struct device_node *np) -+{ -+ u32 bmt_pool_size, bmt_table_size; -+ u32 bufsz, block; -+ u16 pmt_block; -+ -+ if (of_property_read_u32(np, "mediatek,bmt-pool-size", -+ &bmt_pool_size) != 0) -+ bmt_pool_size = 80; -+ -+ if (of_property_read_u8(np, "mediatek,bmt-oob-offset", -+ &bmtd.oob_offset) != 0) -+ bmtd.oob_offset = 0; -+ -+ if (of_property_read_u32(np, "mediatek,bmt-table-size", -+ &bmt_table_size) != 0) -+ bmt_table_size = 0x2000U; -+ -+ bmtd.table_size = bmt_table_size; -+ -+ pmt_block = bmtd.total_blks - bmt_pool_size - 2; -+ -+ bmtd.mtd->size = pmt_block << bmtd.blk_shift; -+ -+ /* -+ * --------------------------------------- -+ * | PMT(2blks) | BMT POOL(totalblks * 2%) | -+ * --------------------------------------- -+ * ^ ^ -+ * | | -+ * pmt_block pmt_block + 2blocks(pool_lba) -+ * -+ * ATTETION!!!!!! -+ * The blocks ahead of the boundary block are stored in bb_tbl -+ * and blocks behind are stored in bmt_tbl -+ */ -+ -+ bmtd.pool_lba = (u16)(pmt_block + 2); -+ bmtd.bb_max = bmtd.total_blks * BBPOOL_RATIO / 100; -+ -+ bufsz = round_up(sizeof(struct bbbt) + -+ bmt_table_size * sizeof(struct bbmt), bmtd.pg_size); -+ bmtd.bmt_pgs = bufsz >> bmtd.pg_shift; -+ -+ bmtd.bbt_buf = kzalloc(bufsz, GFP_KERNEL); -+ if (!bmtd.bbt_buf) -+ return -ENOMEM; -+ -+ memset(bmtd.bbt_buf, 0xff, bufsz); -+ -+ /* Scanning start from the first page of the last block -+ * of whole flash -+ */ -+ bmtd.bbt = NULL; -+ for (u16 block = bmtd.total_blks - 1; !bmtd.bbt && block >= bmtd.pool_lba; block--) { -+ u8 fdm[4]; -+ -+ if (bbt_nand_read(blk_pg(block), bmtd.bbt_buf, bufsz, fdm, sizeof(fdm))) { -+ /* Read failed, try the previous block */ -+ continue; -+ } -+ -+ if (!is_valid_bmt(bmtd.bbt_buf, fdm)) { -+ /* No valid BMT found, try the previous block */ -+ continue; -+ } -+ -+ bmtd.bmt_blk_idx = get_bmt_index(bmt_tbl((struct bbbt *)bmtd.bbt_buf)); -+ if (bmtd.bmt_blk_idx == 0) { -+ pr_info("[BBT] FATAL ERR: bmt block index is wrong!\n"); -+ break; -+ } -+ -+ pr_info("[BBT] BMT.v2 is found at 0x%x\n", block); -+ bmtd.bbt = (struct bbbt *)bmtd.bbt_buf; -+ } -+ -+ if (!bmtd.bbt) { -+ /* BMT not found */ -+ if (bmtd.total_blks > BB_TABLE_MAX + BMT_TABLE_MAX) { -+ pr_info("nand: FATAL: Too many blocks, can not support!\n"); -+ return -1; -+ } -+ -+ bmtd.bbt = (struct bbbt *)bmtd.bbt_buf; -+ memset(bmt_tbl(bmtd.bbt), BMT_TBL_DEF_VAL, -+ bmtd.table_size * sizeof(struct bbmt)); -+ -+ if (scan_bad_blocks(bmtd.bbt)) -+ return -1; -+ -+ /* BMT always in the last valid block in pool */ -+ bmtd.bmt_blk_idx = upload_bmt(bmtd.bbt, bmtd.bmt_blk_idx); -+ block = bmt_tbl(bmtd.bbt)[bmtd.bmt_blk_idx].block; -+ pr_notice("[BBT] BMT.v2 is written into PBA:0x%x\n", block); -+ -+ if (bmtd.bmt_blk_idx == 0) -+ pr_info("nand: Warning: no available block in BMT pool!\n"); -+ else if (bmtd.bmt_blk_idx == (u16)-1) -+ return -1; -+ } -+ -+ return 0; -+} -+ -+ -+const struct mtk_bmt_ops mtk_bmt_v2_ops = { -+ .sig = "bmt", -+ .sig_len = 3, -+ .init = mtk_bmt_init_v2, -+ .remap_block = remap_block_v2, -+ .unmap_block = unmap_block_v2, -+ .get_mapping_block = get_mapping_block_index_v2, -+ .debug = mtk_bmt_debug_v2, -+}; -diff --git a/drivers/mtd/parsers/routerbootpart.c b/drivers/mtd/parsers/routerbootpart.c -new file mode 100644 -index 000000000000..aa786cd895e5 ---- /dev/null -+++ b/drivers/mtd/parsers/routerbootpart.c -@@ -0,0 +1,365 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Parser for MikroTik RouterBoot partitions. -+ * -+ * Copyright (C) 2020 Thibaut VARÈNE -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ * This parser builds from the "fixed-partitions" one (see ofpart.c), but it can -+ * handle dynamic partitions as found on routerboot devices. -+ * -+ * DTS nodes are defined as follows: -+ * For fixed partitions: -+ * node-name@unit-address { -+ * reg = ; -+ * label = ; -+ * read-only; -+ * lock; -+ * }; -+ * -+ * reg property is mandatory; other properties are optional. -+ * reg format is
. length can be 0 if the next partition is -+ * another fixed partition or a "well-known" partition as defined below: in that -+ * case the partition will extend up to the next one. -+ * -+ * For dynamic partitions: -+ * node-name { -+ * size = ; -+ * label = ; -+ * read-only; -+ * lock; -+ * }; -+ * -+ * size property is normally mandatory. It can only be omitted (or set to 0) if: -+ * - the partition is a "well-known" one (as defined below), in which case -+ * the partition size will be automatically adjusted; or -+ * - the next partition is a fixed one or a "well-known" one, in which case -+ * the current partition will extend up to the next one. -+ * Other properties are optional. -+ * size format is . -+ * By default dynamic partitions are appended after the preceding one, except -+ * for "well-known" ones which are automatically located on flash. -+ * -+ * Well-known partitions (matched via label or node-name): -+ * - "hard_config" -+ * - "soft_config" -+ * - "dtb_config" -+ * -+ * Note: this parser will happily register 0-sized partitions if misused. -+ * -+ * This parser requires the DTS to list partitions in ascending order as -+ * expected on the MTD device. -+ * -+ * Since only the "hard_config" and "soft_config" partitions are used in OpenWRT, -+ * a minimal working DTS could define only these two partitions dynamically (in -+ * the right order, usually hard_config then soft_config). -+ * -+ * Note: some mips RB devices encode the hard_config offset and length in two -+ * consecutive u32 located at offset 0x14 (for ramips) or 0x24 (for ath79) on -+ * the SPI NOR flash. Unfortunately this seems inconsistent across machines and -+ * does not apply to e.g. ipq-based ones, so we ignore that information. -+ * -+ * Note: To find well-known partitions, this parser will go through the entire -+ * top mtd partition parsed, _before_ the DTS nodes are processed. This works -+ * well in the current state of affairs, and is a simpler implementation than -+ * searching for known partitions in the "holes" left between fixed-partition, -+ * _after_ processing DTS nodes. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define RB_MAGIC_HARD (('H') | ('a' << 8) | ('r' << 16) | ('d' << 24)) -+#define RB_MAGIC_SOFT (('S') | ('o' << 8) | ('f' << 16) | ('t' << 24)) -+#define RB_BLOCK_SIZE 0x1000 -+ -+struct routerboot_dynpart { -+ const char * const name; -+ const u32 magic; -+ int (* const size_fixup)(struct mtd_info *, struct routerboot_dynpart *); -+ size_t offset; -+ size_t size; -+ bool found; -+}; -+ -+static int routerboot_dtbsfixup(struct mtd_info *, struct routerboot_dynpart *); -+ -+static struct routerboot_dynpart rb_dynparts[] = { -+ { -+ .name = "hard_config", -+ .magic = RB_MAGIC_HARD, // stored in CPU-endianness on flash -+ .size_fixup = NULL, -+ .offset = 0x0, -+ .size = RB_BLOCK_SIZE, -+ .found = false, -+ }, { -+ .name = "soft_config", -+ .magic = RB_MAGIC_SOFT, // stored in CPU-endianness on flash -+ .size_fixup = NULL, -+ .offset = 0x0, -+ .size = RB_BLOCK_SIZE, -+ .found = false, -+ }, { -+ .name = "dtb_config", -+ .magic = fdt32_to_cpu(OF_DT_HEADER), // stored BE on flash -+ .size_fixup = routerboot_dtbsfixup, -+ .offset = 0x0, -+ .size = 0x0, -+ .found = false, -+ } -+}; -+ -+static int routerboot_dtbsfixup(struct mtd_info *master, struct routerboot_dynpart *rbdpart) -+{ -+ int err; -+ size_t bytes_read, psize; -+ struct { -+ fdt32_t magic; -+ fdt32_t totalsize; -+ fdt32_t off_dt_struct; -+ fdt32_t off_dt_strings; -+ fdt32_t off_mem_rsvmap; -+ fdt32_t version; -+ fdt32_t last_comp_version; -+ fdt32_t boot_cpuid_phys; -+ fdt32_t size_dt_strings; -+ fdt32_t size_dt_struct; -+ } fdt_header; -+ -+ err = mtd_read(master, rbdpart->offset, sizeof(fdt_header), -+ &bytes_read, (u8 *)&fdt_header); -+ if (err) -+ return err; -+ -+ if (bytes_read != sizeof(fdt_header)) -+ return -EIO; -+ -+ psize = fdt32_to_cpu(fdt_header.totalsize); -+ if (!psize) -+ return -EINVAL; -+ -+ rbdpart->size = psize; -+ return 0; -+} -+ -+static void routerboot_find_dynparts(struct mtd_info *master) -+{ -+ size_t bytes_read, offset; -+ bool allfound; -+ int err, i; -+ u32 buf; -+ -+ /* -+ * Dynamic RouterBoot partitions offsets are aligned to RB_BLOCK_SIZE: -+ * read the whole partition at RB_BLOCK_SIZE intervals to find sigs. -+ * Skip partition content when possible. -+ */ -+ offset = 0; -+ while (offset < master->size) { -+ err = mtd_read(master, offset, sizeof(buf), &bytes_read, (u8 *)&buf); -+ if (err) { -+ pr_err("%s: mtd_read error while parsing (offset: 0x%zX): %d\n", -+ master->name, offset, err); -+ continue; -+ } -+ -+ allfound = true; -+ -+ for (i = 0; i < ARRAY_SIZE(rb_dynparts); i++) { -+ if (rb_dynparts[i].found) -+ continue; -+ -+ allfound = false; -+ -+ if (rb_dynparts[i].magic == buf) { -+ rb_dynparts[i].offset = offset; -+ -+ if (rb_dynparts[i].size_fixup) { -+ err = rb_dynparts[i].size_fixup(master, &rb_dynparts[i]); -+ if (err) { -+ pr_err("%s: size fixup error while parsing \"%s\": %d\n", -+ master->name, rb_dynparts[i].name, err); -+ continue; -+ } -+ } -+ -+ rb_dynparts[i].found = true; -+ -+ /* -+ * move offset to skip the whole partition on -+ * next iteration if size > RB_BLOCK_SIZE. -+ */ -+ if (rb_dynparts[i].size > RB_BLOCK_SIZE) -+ offset += ALIGN_DOWN((rb_dynparts[i].size - RB_BLOCK_SIZE), RB_BLOCK_SIZE); -+ -+ break; -+ } -+ } -+ -+ offset += RB_BLOCK_SIZE; -+ -+ if (allfound) -+ break; -+ } -+} -+ -+static int routerboot_partitions_parse(struct mtd_info *master, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct device_node *rbpart_node, *pp; -+ struct mtd_partition *parts; -+ const char *partname; -+ size_t master_ofs; -+ int np; -+ -+ /* Pull of_node from the master device node */ -+ rbpart_node = mtd_get_of_node(master); -+ if (!rbpart_node) -+ return 0; -+ -+ /* First count the subnodes */ -+ np = 0; -+ for_each_child_of_node(rbpart_node, pp) -+ np++; -+ -+ if (!np) -+ return 0; -+ -+ parts = kcalloc(np, sizeof(*parts), GFP_KERNEL); -+ if (!parts) -+ return -ENOMEM; -+ -+ /* Preemptively look for known parts in flash */ -+ routerboot_find_dynparts(master); -+ -+ np = 0; -+ master_ofs = 0; -+ for_each_child_of_node(rbpart_node, pp) { -+ const __be32 *reg, *sz; -+ size_t offset, size; -+ int i, len, a_cells, s_cells; -+ -+ partname = of_get_property(pp, "label", &len); -+ /* Allow deprecated use of "name" instead of "label" */ -+ if (!partname) -+ partname = of_get_property(pp, "name", &len); -+ /* Fallback to node name per spec if all else fails: partname is always set */ -+ if (!partname) -+ partname = pp->name; -+ parts[np].name = partname; -+ -+ reg = of_get_property(pp, "reg", &len); -+ if (reg) { -+ /* Fixed partition */ -+ a_cells = of_n_addr_cells(pp); -+ s_cells = of_n_size_cells(pp); -+ -+ if ((len / 4) != (a_cells + s_cells)) { -+ pr_debug("%s: routerboot partition %pOF (%pOF) error parsing reg property.\n", -+ master->name, pp, rbpart_node); -+ goto rbpart_fail; -+ } -+ -+ offset = of_read_number(reg, a_cells); -+ size = of_read_number(reg + a_cells, s_cells); -+ } else { -+ /* Dynamic partition */ -+ /* Default: part starts at current offset, 0 size */ -+ offset = master_ofs; -+ size = 0; -+ -+ /* Check if well-known partition */ -+ for (i = 0; i < ARRAY_SIZE(rb_dynparts); i++) { -+ if (!strcmp(partname, rb_dynparts[i].name) && rb_dynparts[i].found) { -+ offset = rb_dynparts[i].offset; -+ size = rb_dynparts[i].size; -+ break; -+ } -+ } -+ -+ /* Standalone 'size' property? Override size */ -+ sz = of_get_property(pp, "size", &len); -+ if (sz) { -+ s_cells = of_n_size_cells(pp); -+ if ((len / 4) != s_cells) { -+ pr_debug("%s: routerboot partition %pOF (%pOF) error parsing size property.\n", -+ master->name, pp, rbpart_node); -+ goto rbpart_fail; -+ } -+ -+ size = of_read_number(sz, s_cells); -+ } -+ } -+ -+ if (np > 0) { -+ /* Minor sanity check for overlaps */ -+ if (offset < (parts[np-1].offset + parts[np-1].size)) { -+ pr_err("%s: routerboot partition %pOF (%pOF) \"%s\" overlaps with previous partition \"%s\".\n", -+ master->name, pp, rbpart_node, -+ partname, parts[np-1].name); -+ goto rbpart_fail; -+ } -+ -+ /* Fixup end of previous partition if necessary */ -+ if (!parts[np-1].size) -+ parts[np-1].size = (offset - parts[np-1].offset); -+ } -+ -+ if ((offset + size) > master->size) { -+ pr_err("%s: routerboot partition %pOF (%pOF) \"%s\" extends past end of segment.\n", -+ master->name, pp, rbpart_node, partname); -+ goto rbpart_fail; -+ } -+ -+ parts[np].offset = offset; -+ parts[np].size = size; -+ parts[np].of_node = pp; -+ -+ if (of_get_property(pp, "read-only", &len)) -+ parts[np].mask_flags |= MTD_WRITEABLE; -+ -+ if (of_get_property(pp, "lock", &len)) -+ parts[np].mask_flags |= MTD_POWERUP_LOCK; -+ -+ /* Keep master offset aligned to RB_BLOCK_SIZE */ -+ master_ofs = ALIGN(offset + size, RB_BLOCK_SIZE); -+ np++; -+ } -+ -+ *pparts = parts; -+ return np; -+ -+rbpart_fail: -+ pr_err("%s: error parsing routerboot partition %pOF (%pOF)\n", -+ master->name, pp, rbpart_node); -+ of_node_put(pp); -+ kfree(parts); -+ return -EINVAL; -+} -+ -+static const struct of_device_id parse_routerbootpart_match_table[] = { -+ { .compatible = "mikrotik,routerboot-partitions" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, parse_routerbootpart_match_table); -+ -+static struct mtd_part_parser routerbootpart_parser = { -+ .parse_fn = routerboot_partitions_parse, -+ .name = "routerbootpart", -+ .of_match_table = parse_routerbootpart_match_table, -+}; -+module_mtd_part_parser(routerbootpart_parser); -+ -+MODULE_LICENSE("GPL v2"); -+MODULE_DESCRIPTION("MTD partitioning for RouterBoot"); -+MODULE_AUTHOR("Thibaut VARENE"); -diff --git a/drivers/net/dsa/an8855.c b/drivers/net/dsa/an8855.c -new file mode 100644 -index 000000000000..e6666d2011c9 ---- /dev/null -+++ b/drivers/net/dsa/an8855.c -@@ -0,0 +1,2308 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Airoha AN8855 DSA Switch driver -+ * Copyright (C) 2023 Min Yao -+ * Copyright (C) 2024 Christian Marangi -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "an8855.h" -+ -+static const struct an8855_mib_desc an8855_mib[] = { -+ MIB_DESC(1, AN8855_PORT_MIB_TX_DROP, "TxDrop"), -+ MIB_DESC(1, AN8855_PORT_MIB_TX_CRC_ERR, "TxCrcErr"), -+ MIB_DESC(1, AN8855_PORT_MIB_TX_COLLISION, "TxCollision"), -+ MIB_DESC(1, AN8855_PORT_MIB_TX_OVERSIZE_DROP, "TxOversizeDrop"), -+ MIB_DESC(2, AN8855_PORT_MIB_TX_BAD_PKT_BYTES, "TxBadPktBytes"), -+ MIB_DESC(1, AN8855_PORT_MIB_RX_DROP, "RxDrop"), -+ MIB_DESC(1, AN8855_PORT_MIB_RX_FILTERING, "RxFiltering"), -+ MIB_DESC(1, AN8855_PORT_MIB_RX_CRC_ERR, "RxCrcErr"), -+ MIB_DESC(1, AN8855_PORT_MIB_RX_CTRL_DROP, "RxCtrlDrop"), -+ MIB_DESC(1, AN8855_PORT_MIB_RX_INGRESS_DROP, "RxIngressDrop"), -+ MIB_DESC(1, AN8855_PORT_MIB_RX_ARL_DROP, "RxArlDrop"), -+ MIB_DESC(1, AN8855_PORT_MIB_FLOW_CONTROL_DROP, "FlowControlDrop"), -+ MIB_DESC(1, AN8855_PORT_MIB_WRED_DROP, "WredDrop"), -+ MIB_DESC(1, AN8855_PORT_MIB_MIRROR_DROP, "MirrorDrop"), -+ MIB_DESC(2, AN8855_PORT_MIB_RX_BAD_PKT_BYTES, "RxBadPktBytes"), -+ MIB_DESC(1, AN8855_PORT_MIB_RXS_FLOW_SAMPLING_PKT_DROP, "RxsFlowSamplingPktDrop"), -+ MIB_DESC(1, AN8855_PORT_MIB_RXS_FLOW_TOTAL_PKT_DROP, "RxsFlowTotalPktDrop"), -+ MIB_DESC(1, AN8855_PORT_MIB_PORT_CONTROL_DROP, "PortControlDrop"), -+}; -+ -+static int -+an8855_mib_init(struct an8855_priv *priv) -+{ -+ int ret; -+ -+ ret = regmap_write(priv->regmap, AN8855_MIB_CCR, -+ AN8855_CCR_MIB_ENABLE); -+ if (ret) -+ return ret; -+ -+ return regmap_write(priv->regmap, AN8855_MIB_CCR, -+ AN8855_CCR_MIB_ACTIVATE); -+} -+ -+static void an8855_fdb_write(struct an8855_priv *priv, u16 vid, -+ u8 port_mask, const u8 *mac, -+ bool add) __must_hold(&priv->reg_mutex) -+{ -+ u32 mac_reg[2] = { }; -+ u32 reg; -+ -+ mac_reg[0] |= FIELD_PREP(AN8855_ATA1_MAC0, mac[0]); -+ mac_reg[0] |= FIELD_PREP(AN8855_ATA1_MAC1, mac[1]); -+ mac_reg[0] |= FIELD_PREP(AN8855_ATA1_MAC2, mac[2]); -+ mac_reg[0] |= FIELD_PREP(AN8855_ATA1_MAC3, mac[3]); -+ mac_reg[1] |= FIELD_PREP(AN8855_ATA2_MAC4, mac[4]); -+ mac_reg[1] |= FIELD_PREP(AN8855_ATA2_MAC5, mac[5]); -+ -+ regmap_bulk_write(priv->regmap, AN8855_ATA1, mac_reg, -+ ARRAY_SIZE(mac_reg)); -+ -+ reg = AN8855_ATWD_IVL; -+ if (add) -+ reg |= AN8855_ATWD_VLD; -+ reg |= FIELD_PREP(AN8855_ATWD_VID, vid); -+ reg |= FIELD_PREP(AN8855_ATWD_FID, AN8855_FID_BRIDGED); -+ regmap_write(priv->regmap, AN8855_ATWD, reg); -+ regmap_write(priv->regmap, AN8855_ATWD2, -+ FIELD_PREP(AN8855_ATWD2_PORT, port_mask)); -+} -+ -+static void an8855_fdb_read(struct an8855_priv *priv, struct an8855_fdb *fdb) -+{ -+ u32 reg[4]; -+ -+ regmap_bulk_read(priv->regmap, AN8855_ATRD0, reg, -+ ARRAY_SIZE(reg)); -+ -+ fdb->live = FIELD_GET(AN8855_ATRD0_LIVE, reg[0]); -+ fdb->type = FIELD_GET(AN8855_ATRD0_TYPE, reg[0]); -+ fdb->ivl = FIELD_GET(AN8855_ATRD0_IVL, reg[0]); -+ fdb->vid = FIELD_GET(AN8855_ATRD0_VID, reg[0]); -+ fdb->fid = FIELD_GET(AN8855_ATRD0_FID, reg[0]); -+ fdb->aging = FIELD_GET(AN8855_ATRD1_AGING, reg[1]); -+ fdb->port_mask = FIELD_GET(AN8855_ATRD3_PORTMASK, reg[3]); -+ fdb->mac[0] = FIELD_GET(AN8855_ATRD2_MAC0, reg[2]); -+ fdb->mac[1] = FIELD_GET(AN8855_ATRD2_MAC1, reg[2]); -+ fdb->mac[2] = FIELD_GET(AN8855_ATRD2_MAC2, reg[2]); -+ fdb->mac[3] = FIELD_GET(AN8855_ATRD2_MAC3, reg[2]); -+ fdb->mac[4] = FIELD_GET(AN8855_ATRD1_MAC4, reg[1]); -+ fdb->mac[5] = FIELD_GET(AN8855_ATRD1_MAC5, reg[1]); -+ fdb->noarp = !!FIELD_GET(AN8855_ATRD0_ARP, reg[0]); -+} -+ -+static int an8855_fdb_cmd(struct an8855_priv *priv, u32 cmd, -+ u32 *rsp) __must_hold(&priv->reg_mutex) -+{ -+ u32 val; -+ int ret; -+ -+ /* Set the command operating upon the MAC address entries */ -+ val = AN8855_ATC_BUSY | cmd; -+ ret = regmap_write(priv->regmap, AN8855_ATC, val); -+ if (ret) -+ return ret; -+ -+ ret = regmap_read_poll_timeout(priv->regmap, AN8855_ATC, val, -+ !(val & AN8855_ATC_BUSY), 20, 200000); -+ if (ret) -+ return ret; -+ -+ if (rsp) -+ *rsp = val; -+ -+ return 0; -+} -+ -+static void -+an8855_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) -+{ -+ struct dsa_port *dp = dsa_to_port(ds, port); -+ struct an8855_priv *priv = ds->priv; -+ bool learning = false; -+ u32 stp_state; -+ -+ switch (state) { -+ case BR_STATE_DISABLED: -+ stp_state = AN8855_STP_DISABLED; -+ break; -+ case BR_STATE_BLOCKING: -+ stp_state = AN8855_STP_BLOCKING; -+ break; -+ case BR_STATE_LISTENING: -+ stp_state = AN8855_STP_LISTENING; -+ break; -+ case BR_STATE_LEARNING: -+ stp_state = AN8855_STP_LEARNING; -+ learning = dp->learning; -+ break; -+ case BR_STATE_FORWARDING: -+ learning = dp->learning; -+ fallthrough; -+ default: -+ stp_state = AN8855_STP_FORWARDING; -+ break; -+ } -+ -+ regmap_update_bits(priv->regmap, AN8855_SSP_P(port), -+ AN8855_FID_PST_MASK(AN8855_FID_BRIDGED), -+ AN8855_FID_PST_VAL(AN8855_FID_BRIDGED, stp_state)); -+ -+ regmap_update_bits(priv->regmap, AN8855_PSC_P(port), AN8855_SA_DIS, -+ learning ? 0 : AN8855_SA_DIS); -+} -+ -+static void an8855_port_fast_age(struct dsa_switch *ds, int port) -+{ -+ struct an8855_priv *priv = ds->priv; -+ int ret; -+ -+ /* Set to clean Dynamic entry */ -+ ret = regmap_write(priv->regmap, AN8855_ATA2, AN8855_ATA2_TYPE); -+ if (ret) -+ return; -+ -+ /* Set Port */ -+ ret = regmap_write(priv->regmap, AN8855_ATWD2, -+ FIELD_PREP(AN8855_ATWD2_PORT, BIT(port))); -+ if (ret) -+ return; -+ -+ /* Flush Dynamic entry at port */ -+ an8855_fdb_cmd(priv, AN8855_ATC_MAT(AND8855_FDB_MAT_MAC_TYPE_PORT) | -+ AN8855_FDB_FLUSH, NULL); -+} -+ -+static int an8855_update_port_member(struct dsa_switch *ds, int port, -+ const struct net_device *bridge_dev, -+ bool join) -+{ -+ struct an8855_priv *priv = ds->priv; -+ bool isolated, other_isolated; -+ struct dsa_port *dp; -+ u32 port_mask = 0; -+ int ret; -+ -+ isolated = !!(priv->port_isolated_map & BIT(port)); -+ -+ dsa_switch_for_each_user_port(dp, ds) { -+ if (dp->index == port) -+ continue; -+ -+ if (!dsa_port_offloads_bridge_dev(dp, bridge_dev)) -+ continue; -+ -+ other_isolated = !!(priv->port_isolated_map & BIT(dp->index)); -+ port_mask |= BIT(dp->index); -+ /* Add/remove this port to the portvlan mask of the other -+ * ports in the bridge -+ */ -+ if (join && !(isolated && other_isolated)) -+ ret = regmap_set_bits(priv->regmap, -+ AN8855_PORTMATRIX_P(dp->index), -+ FIELD_PREP(AN8855_USER_PORTMATRIX, -+ BIT(port))); -+ else -+ ret = regmap_clear_bits(priv->regmap, -+ AN8855_PORTMATRIX_P(dp->index), -+ FIELD_PREP(AN8855_USER_PORTMATRIX, -+ BIT(port))); -+ if (ret) -+ return ret; -+ } -+ -+ /* Add/remove all other ports to this port's portvlan mask */ -+ return regmap_update_bits(priv->regmap, AN8855_PORTMATRIX_P(port), -+ AN8855_USER_PORTMATRIX, -+ join ? port_mask : ~port_mask); -+} -+ -+static int an8855_port_pre_bridge_flags(struct dsa_switch *ds, int port, -+ struct switchdev_brport_flags flags, -+ struct netlink_ext_ack *extack) -+{ -+ if (flags.mask & ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | -+ BR_BCAST_FLOOD | BR_ISOLATED)) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static int an8855_port_bridge_flags(struct dsa_switch *ds, int port, -+ struct switchdev_brport_flags flags, -+ struct netlink_ext_ack *extack) -+{ -+ struct an8855_priv *priv = ds->priv; -+ int ret; -+ -+ if (flags.mask & BR_LEARNING) { -+ ret = regmap_update_bits(priv->regmap, AN8855_PSC_P(port), AN8855_SA_DIS, -+ flags.val & BR_LEARNING ? 0 : AN8855_SA_DIS); -+ if (ret) -+ return ret; -+ } -+ -+ if (flags.mask & BR_FLOOD) { -+ ret = regmap_update_bits(priv->regmap, AN8855_UNUF, BIT(port), -+ flags.val & BR_FLOOD ? BIT(port) : 0); -+ if (ret) -+ return ret; -+ } -+ -+ if (flags.mask & BR_MCAST_FLOOD) { -+ ret = regmap_update_bits(priv->regmap, AN8855_UNMF, BIT(port), -+ flags.val & BR_MCAST_FLOOD ? BIT(port) : 0); -+ if (ret) -+ return ret; -+ -+ ret = regmap_update_bits(priv->regmap, AN8855_UNIPMF, BIT(port), -+ flags.val & BR_MCAST_FLOOD ? BIT(port) : 0); -+ if (ret) -+ return ret; -+ } -+ -+ if (flags.mask & BR_BCAST_FLOOD) { -+ ret = regmap_update_bits(priv->regmap, AN8855_BCF, BIT(port), -+ flags.val & BR_BCAST_FLOOD ? BIT(port) : 0); -+ if (ret) -+ return ret; -+ } -+ -+ if (flags.mask & BR_ISOLATED) { -+ struct dsa_port *dp = dsa_to_port(ds, port); -+ struct net_device *bridge_dev = dsa_port_bridge_dev_get(dp); -+ -+ if (flags.val & BR_ISOLATED) -+ priv->port_isolated_map |= BIT(port); -+ else -+ priv->port_isolated_map &= ~BIT(port); -+ -+ ret = an8855_update_port_member(ds, port, bridge_dev, true); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int an8855_set_ageing_time(struct dsa_switch *ds, unsigned int msecs) -+{ -+ struct an8855_priv *priv = ds->priv; -+ u32 age_count, age_unit, val; -+ -+ /* Convert msec in AN8855_L2_AGING_MS_CONSTANT counter */ -+ val = msecs / AN8855_L2_AGING_MS_CONSTANT; -+ /* Derive the count unit */ -+ age_unit = val / FIELD_MAX(AN8855_AGE_UNIT); -+ /* Get the count in unit, age_unit is always incremented by 1 internally */ -+ age_count = val / (age_unit + 1); -+ -+ return regmap_update_bits(priv->regmap, AN8855_AAC, -+ AN8855_AGE_CNT | AN8855_AGE_UNIT, -+ FIELD_PREP(AN8855_AGE_CNT, age_count) | -+ FIELD_PREP(AN8855_AGE_UNIT, age_unit)); -+} -+ -+static int an8855_port_bridge_join(struct dsa_switch *ds, int port, -+ struct dsa_bridge bridge, -+ bool *tx_fwd_offload, -+ struct netlink_ext_ack *extack) -+{ -+ struct an8855_priv *priv = ds->priv; -+ int ret; -+ -+ ret = an8855_update_port_member(ds, port, bridge.dev, true); -+ if (ret) -+ return ret; -+ -+ /* Set to fallback mode for independent VLAN learning if in a bridge */ -+ return regmap_update_bits(priv->regmap, AN8855_PCR_P(port), -+ AN8855_PORT_VLAN, -+ FIELD_PREP(AN8855_PORT_VLAN, -+ AN8855_PORT_FALLBACK_MODE)); -+} -+ -+static void an8855_port_bridge_leave(struct dsa_switch *ds, int port, -+ struct dsa_bridge bridge) -+{ -+ struct an8855_priv *priv = ds->priv; -+ -+ an8855_update_port_member(ds, port, bridge.dev, false); -+ -+ /* When a port is removed from the bridge, the port would be set up -+ * back to the default as is at initial boot which is a VLAN-unaware -+ * port. -+ */ -+ regmap_update_bits(priv->regmap, AN8855_PCR_P(port), -+ AN8855_PORT_VLAN, -+ FIELD_PREP(AN8855_PORT_VLAN, -+ AN8855_PORT_MATRIX_MODE)); -+} -+ -+static int an8855_port_fdb_add(struct dsa_switch *ds, int port, -+ const unsigned char *addr, u16 vid, -+ struct dsa_db db) -+{ -+ struct an8855_priv *priv = ds->priv; -+ u8 port_mask = BIT(port); -+ int ret; -+ -+ /* Set the vid to the port vlan id if no vid is set */ -+ if (!vid) -+ vid = AN8855_PORT_VID_DEFAULT; -+ -+ mutex_lock(&priv->reg_mutex); -+ an8855_fdb_write(priv, vid, port_mask, addr, true); -+ ret = an8855_fdb_cmd(priv, AN8855_FDB_WRITE, NULL); -+ mutex_unlock(&priv->reg_mutex); -+ -+ return ret; -+} -+ -+static int an8855_port_fdb_del(struct dsa_switch *ds, int port, -+ const unsigned char *addr, u16 vid, -+ struct dsa_db db) -+{ -+ struct an8855_priv *priv = ds->priv; -+ u8 port_mask = BIT(port); -+ int ret; -+ -+ /* Set the vid to the port vlan id if no vid is set */ -+ if (!vid) -+ vid = AN8855_PORT_VID_DEFAULT; -+ -+ mutex_lock(&priv->reg_mutex); -+ an8855_fdb_write(priv, vid, port_mask, addr, false); -+ ret = an8855_fdb_cmd(priv, AN8855_FDB_WRITE, NULL); -+ mutex_unlock(&priv->reg_mutex); -+ -+ return ret; -+} -+ -+static int an8855_port_fdb_dump(struct dsa_switch *ds, int port, -+ dsa_fdb_dump_cb_t *cb, void *data) -+{ -+ struct an8855_priv *priv = ds->priv; -+ int banks, count = 0; -+ u32 rsp; -+ int ret; -+ int i; -+ -+ mutex_lock(&priv->reg_mutex); -+ -+ /* Load search port */ -+ ret = regmap_write(priv->regmap, AN8855_ATWD2, -+ FIELD_PREP(AN8855_ATWD2_PORT, BIT(port))); -+ if (ret) -+ goto exit; -+ ret = an8855_fdb_cmd(priv, AN8855_ATC_MAT(AND8855_FDB_MAT_MAC_PORT) | -+ AN8855_FDB_START, &rsp); -+ if (ret < 0) -+ goto exit; -+ -+ do { -+ /* From response get the number of banks to read, exit if 0 */ -+ banks = FIELD_GET(AN8855_ATC_HIT, rsp); -+ if (!banks) -+ break; -+ -+ /* Each banks have 4 entry */ -+ for (i = 0; i < 4; i++) { -+ struct an8855_fdb _fdb = { }; -+ -+ count++; -+ -+ /* Check if bank is present */ -+ if (!(banks & BIT(i))) -+ continue; -+ -+ /* Select bank entry index */ -+ ret = regmap_write(priv->regmap, AN8855_ATRDS, -+ FIELD_PREP(AN8855_ATRD_SEL, i)); -+ if (ret) -+ break; -+ /* wait 1ms for the bank entry to be filled */ -+ usleep_range(1000, 1500); -+ an8855_fdb_read(priv, &_fdb); -+ -+ if (!_fdb.live) -+ continue; -+ ret = cb(_fdb.mac, _fdb.vid, _fdb.noarp, data); -+ if (ret < 0) -+ break; -+ } -+ -+ /* Stop if reached max FDB number */ -+ if (count >= AN8855_NUM_FDB_RECORDS) -+ break; -+ -+ /* Read next bank */ -+ ret = an8855_fdb_cmd(priv, AN8855_ATC_MAT(AND8855_FDB_MAT_MAC_PORT) | -+ AN8855_FDB_NEXT, &rsp); -+ if (ret < 0) -+ break; -+ } while (true); -+ -+exit: -+ mutex_unlock(&priv->reg_mutex); -+ return ret; -+} -+ -+static int an8855_vlan_cmd(struct an8855_priv *priv, enum an8855_vlan_cmd cmd, -+ u16 vid) __must_hold(&priv->reg_mutex) -+{ -+ u32 val; -+ int ret; -+ -+ val = AN8855_VTCR_BUSY | FIELD_PREP(AN8855_VTCR_FUNC, cmd) | -+ FIELD_PREP(AN8855_VTCR_VID, vid); -+ ret = regmap_write(priv->regmap, AN8855_VTCR, val); -+ if (ret) -+ return ret; -+ -+ return regmap_read_poll_timeout(priv->regmap, AN8855_VTCR, val, -+ !(val & AN8855_VTCR_BUSY), 20, 200000); -+} -+ -+static int an8855_vlan_add(struct an8855_priv *priv, u8 port, u16 vid, -+ bool untagged) __must_hold(&priv->reg_mutex) -+{ -+ u32 port_mask; -+ u32 val; -+ int ret; -+ -+ /* Fetch entry */ -+ ret = an8855_vlan_cmd(priv, AN8855_VTCR_RD_VID, vid); -+ if (ret) -+ return ret; -+ -+ ret = regmap_read(priv->regmap, AN8855_VARD0, &val); -+ if (ret) -+ return ret; -+ port_mask = FIELD_GET(AN8855_VA0_PORT, val) | BIT(port); -+ -+ /* Validate the entry with independent learning, create egress tag per -+ * VLAN and joining the port as one of the port members. -+ */ -+ val = (val & AN8855_VA0_ETAG) | AN8855_VA0_IVL_MAC | -+ AN8855_VA0_VTAG_EN | AN8855_VA0_VLAN_VALID | -+ FIELD_PREP(AN8855_VA0_PORT, port_mask) | -+ FIELD_PREP(AN8855_VA0_FID, AN8855_FID_BRIDGED); -+ ret = regmap_write(priv->regmap, AN8855_VAWD0, val); -+ if (ret) -+ return ret; -+ ret = regmap_write(priv->regmap, AN8855_VAWD1, 0); -+ if (ret) -+ return ret; -+ -+ /* CPU port is always taken as a tagged port for serving more than one -+ * VLANs across and also being applied with egress type stack mode for -+ * that VLAN tags would be appended after hardware special tag used as -+ * DSA tag. -+ */ -+ if (port == AN8855_CPU_PORT) -+ val = AN8855_VLAN_EGRESS_STACK; -+ /* Decide whether adding tag or not for those outgoing packets from the -+ * port inside the VLAN. -+ */ -+ else -+ val = untagged ? AN8855_VLAN_EGRESS_UNTAG : AN8855_VLAN_EGRESS_TAG; -+ ret = regmap_update_bits(priv->regmap, AN8855_VAWD0, -+ AN8855_VA0_ETAG_PORT_MASK(port), -+ AN8855_VA0_ETAG_PORT_VAL(port, val)); -+ if (ret) -+ return ret; -+ -+ /* Flush result to hardware */ -+ return an8855_vlan_cmd(priv, AN8855_VTCR_WR_VID, vid); -+} -+ -+static int an8855_vlan_del(struct an8855_priv *priv, u8 port, -+ u16 vid) __must_hold(&priv->reg_mutex) -+{ -+ u32 port_mask; -+ u32 val; -+ int ret; -+ -+ /* Fetch entry */ -+ ret = an8855_vlan_cmd(priv, AN8855_VTCR_RD_VID, vid); -+ if (ret) -+ return ret; -+ -+ ret = regmap_read(priv->regmap, AN8855_VARD0, &val); -+ if (ret) -+ return ret; -+ port_mask = FIELD_GET(AN8855_VA0_PORT, val) & ~BIT(port); -+ -+ if (!(val & AN8855_VA0_VLAN_VALID)) { -+ dev_err(priv->dev, "Cannot be deleted due to invalid entry\n"); -+ return -EINVAL; -+ } -+ -+ if (port_mask) { -+ val = (val & AN8855_VA0_ETAG) | AN8855_VA0_IVL_MAC | -+ AN8855_VA0_VTAG_EN | AN8855_VA0_VLAN_VALID | -+ FIELD_PREP(AN8855_VA0_PORT, port_mask); -+ ret = regmap_write(priv->regmap, AN8855_VAWD0, val); -+ if (ret) -+ return ret; -+ } else { -+ ret = regmap_write(priv->regmap, AN8855_VAWD0, 0); -+ if (ret) -+ return ret; -+ } -+ ret = regmap_write(priv->regmap, AN8855_VAWD1, 0); -+ if (ret) -+ return ret; -+ -+ /* Flush result to hardware */ -+ return an8855_vlan_cmd(priv, AN8855_VTCR_WR_VID, vid); -+} -+ -+static int an8855_port_set_vlan_mode(struct an8855_priv *priv, int port, -+ enum an8855_port_mode port_mode, -+ enum an8855_vlan_port_eg_tag eg_tag, -+ enum an8855_vlan_port_attr vlan_attr, -+ enum an8855_vlan_port_acc_frm acc_frm) -+{ -+ int ret; -+ -+ ret = regmap_update_bits(priv->regmap, AN8855_PCR_P(port), -+ AN8855_PORT_VLAN, -+ FIELD_PREP(AN8855_PORT_VLAN, port_mode)); -+ if (ret) -+ return ret; -+ -+ return regmap_update_bits(priv->regmap, AN8855_PVC_P(port), -+ AN8855_PVC_EG_TAG | AN8855_VLAN_ATTR | AN8855_ACC_FRM, -+ FIELD_PREP(AN8855_PVC_EG_TAG, eg_tag) | -+ FIELD_PREP(AN8855_VLAN_ATTR, vlan_attr) | -+ FIELD_PREP(AN8855_ACC_FRM, acc_frm)); -+} -+ -+static int an8855_port_set_pid(struct an8855_priv *priv, int port, -+ u16 pid) -+{ -+ int ret; -+ -+ ret = regmap_update_bits(priv->regmap, AN8855_PPBV1_P(port), -+ AN8855_PPBV_G0_PORT_VID, -+ FIELD_PREP(AN8855_PPBV_G0_PORT_VID, pid)); -+ if (ret) -+ return ret; -+ -+ return regmap_update_bits(priv->regmap, AN8855_PVID_P(port), -+ AN8855_G0_PORT_VID, -+ FIELD_PREP(AN8855_G0_PORT_VID, pid)); -+} -+ -+static int an8855_port_vlan_filtering(struct dsa_switch *ds, int port, -+ bool vlan_filtering, -+ struct netlink_ext_ack *extack) -+{ -+ struct an8855_priv *priv = ds->priv; -+ u32 val; -+ int ret; -+ -+ /* The port is being kept as VLAN-unaware port when bridge is -+ * set up with vlan_filtering not being set, Otherwise, the -+ * port and the corresponding CPU port is required the setup -+ * for becoming a VLAN-aware port. -+ */ -+ if (vlan_filtering) { -+ u32 acc_frm; -+ /* CPU port is set to fallback mode to let untagged -+ * frames pass through. -+ */ -+ ret = an8855_port_set_vlan_mode(priv, AN8855_CPU_PORT, -+ AN8855_PORT_FALLBACK_MODE, -+ AN8855_VLAN_EG_CONSISTENT, -+ AN8855_VLAN_USER, -+ AN8855_VLAN_ACC_ALL); -+ if (ret) -+ return ret; -+ -+ ret = regmap_read(priv->regmap, AN8855_PVID_P(port), &val); -+ if (ret) -+ return ret; -+ -+ /* Only accept tagged frames if PVID is not set */ -+ if (FIELD_GET(AN8855_G0_PORT_VID, val) != AN8855_PORT_VID_DEFAULT) -+ acc_frm = AN8855_VLAN_ACC_TAGGED; -+ else -+ acc_frm = AN8855_VLAN_ACC_ALL; -+ -+ /* Trapped into security mode allows packet forwarding through VLAN -+ * table lookup. -+ * Set the port as a user port which is to be able to recognize VID -+ * from incoming packets before fetching entry within the VLAN table. -+ */ -+ ret = an8855_port_set_vlan_mode(priv, port, -+ AN8855_PORT_SECURITY_MODE, -+ AN8855_VLAN_EG_DISABLED, -+ AN8855_VLAN_USER, -+ acc_frm); -+ if (ret) -+ return ret; -+ } else { -+ bool disable_cpu_vlan = true; -+ struct dsa_port *dp; -+ u32 port_mode; -+ -+ /* This is called after .port_bridge_leave when leaving a VLAN-aware -+ * bridge. Don't set standalone ports to fallback mode. -+ */ -+ if (dsa_port_bridge_dev_get(dsa_to_port(ds, port))) -+ port_mode = AN8855_PORT_FALLBACK_MODE; -+ else -+ port_mode = AN8855_PORT_MATRIX_MODE; -+ -+ /* When a port is removed from the bridge, the port would be set up -+ * back to the default as is at initial boot which is a VLAN-unaware -+ * port. -+ */ -+ ret = an8855_port_set_vlan_mode(priv, port, port_mode, -+ AN8855_VLAN_EG_CONSISTENT, -+ AN8855_VLAN_TRANSPARENT, -+ AN8855_VLAN_ACC_ALL); -+ if (ret) -+ return ret; -+ -+ /* Restore default PVID */ -+ ret = an8855_port_set_pid(priv, port, AN8855_PORT_VID_DEFAULT); -+ if (ret) -+ return ret; -+ -+ dsa_switch_for_each_user_port(dp, ds) { -+ if (dsa_port_is_vlan_filtering(dp)) { -+ disable_cpu_vlan = false; -+ break; -+ } -+ } -+ -+ if (disable_cpu_vlan) { -+ ret = an8855_port_set_vlan_mode(priv, AN8855_CPU_PORT, -+ AN8855_PORT_MATRIX_MODE, -+ AN8855_VLAN_EG_CONSISTENT, -+ AN8855_VLAN_USER, -+ AN8855_VLAN_ACC_ALL); -+ if (ret) -+ return ret; -+ } -+ } -+ -+ return 0; -+} -+ -+static int an8855_port_vlan_add(struct dsa_switch *ds, int port, -+ const struct switchdev_obj_port_vlan *vlan, -+ struct netlink_ext_ack *extack) -+{ -+ bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; -+ bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; -+ struct an8855_priv *priv = ds->priv; -+ u32 val; -+ int ret; -+ -+ mutex_lock(&priv->reg_mutex); -+ ret = an8855_vlan_add(priv, port, vlan->vid, untagged); -+ mutex_unlock(&priv->reg_mutex); -+ if (ret) -+ return ret; -+ -+ if (pvid) { -+ /* Accept all frames if PVID is set */ -+ regmap_update_bits(priv->regmap, AN8855_PVC_P(port), AN8855_ACC_FRM, -+ FIELD_PREP(AN8855_ACC_FRM, AN8855_VLAN_ACC_ALL)); -+ -+ /* Only configure PVID if VLAN filtering is enabled */ -+ if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port))) { -+ ret = an8855_port_set_pid(priv, port, vlan->vid); -+ if (ret) -+ return ret; -+ } -+ } else if (vlan->vid) { -+ ret = regmap_read(priv->regmap, AN8855_PVID_P(port), &val); -+ if (ret) -+ return ret; -+ -+ if (FIELD_GET(AN8855_G0_PORT_VID, val) != vlan->vid) -+ return 0; -+ -+ /* This VLAN is overwritten without PVID, so unset it */ -+ if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port))) { -+ ret = regmap_update_bits(priv->regmap, AN8855_PVC_P(port), -+ AN8855_ACC_FRM, -+ FIELD_PREP(AN8855_ACC_FRM, -+ AN8855_VLAN_ACC_TAGGED)); -+ if (ret) -+ return ret; -+ } -+ -+ ret = an8855_port_set_pid(priv, port, AN8855_PORT_VID_DEFAULT); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int an8855_port_vlan_del(struct dsa_switch *ds, int port, -+ const struct switchdev_obj_port_vlan *vlan) -+{ -+ struct an8855_priv *priv = ds->priv; -+ u32 val; -+ int ret; -+ -+ mutex_lock(&priv->reg_mutex); -+ ret = an8855_vlan_del(priv, port, vlan->vid); -+ mutex_unlock(&priv->reg_mutex); -+ if (ret) -+ return ret; -+ -+ ret = regmap_read(priv->regmap, AN8855_PVID_P(port), &val); -+ if (ret) -+ return ret; -+ -+ /* PVID is being restored to the default whenever the PVID port -+ * is being removed from the VLAN. -+ */ -+ if (FIELD_GET(AN8855_G0_PORT_VID, val) == vlan->vid) { -+ /* Only accept tagged frames if the port is VLAN-aware */ -+ if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port))) { -+ ret = regmap_update_bits(priv->regmap, AN8855_PVC_P(port), -+ AN8855_ACC_FRM, -+ FIELD_PREP(AN8855_ACC_FRM, -+ AN8855_VLAN_ACC_TAGGED)); -+ if (ret) -+ return ret; -+ } -+ -+ ret = an8855_port_set_pid(priv, port, AN8855_PORT_VID_DEFAULT); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int -+an8855_port_mdb_add(struct dsa_switch *ds, int port, -+ const struct switchdev_obj_port_mdb *mdb, -+ struct dsa_db db) -+{ -+ struct an8855_priv *priv = ds->priv; -+ const u8 *addr = mdb->addr; -+ u16 vid = mdb->vid; -+ u8 port_mask = 0; -+ u32 val; -+ int ret; -+ -+ /* Set the vid to the port vlan id if no vid is set */ -+ if (!vid) -+ vid = AN8855_PORT_VID_DEFAULT; -+ -+ mutex_lock(&priv->reg_mutex); -+ -+ an8855_fdb_write(priv, vid, 0, addr, false); -+ if (!an8855_fdb_cmd(priv, AN8855_FDB_READ, NULL)) { -+ ret = regmap_read(priv->regmap, AN8855_ATRD3, &val); -+ if (ret) -+ goto exit; -+ -+ port_mask = FIELD_GET(AN8855_ATRD3_PORTMASK, val); -+ } -+ -+ port_mask |= BIT(port); -+ an8855_fdb_write(priv, vid, port_mask, addr, true); -+ ret = an8855_fdb_cmd(priv, AN8855_FDB_WRITE, NULL); -+ -+exit: -+ mutex_unlock(&priv->reg_mutex); -+ -+ return ret; -+} -+ -+static int -+an8855_port_mdb_del(struct dsa_switch *ds, int port, -+ const struct switchdev_obj_port_mdb *mdb, -+ struct dsa_db db) -+{ -+ struct an8855_priv *priv = ds->priv; -+ const u8 *addr = mdb->addr; -+ u16 vid = mdb->vid; -+ u8 port_mask = 0; -+ u32 val; -+ int ret; -+ -+ /* Set the vid to the port vlan id if no vid is set */ -+ if (!vid) -+ vid = AN8855_PORT_VID_DEFAULT; -+ -+ mutex_lock(&priv->reg_mutex); -+ -+ an8855_fdb_write(priv, vid, 0, addr, 0); -+ if (!an8855_fdb_cmd(priv, AN8855_FDB_READ, NULL)) { -+ ret = regmap_read(priv->regmap, AN8855_ATRD3, &val); -+ if (ret) -+ goto exit; -+ -+ port_mask = FIELD_GET(AN8855_ATRD3_PORTMASK, val); -+ } -+ -+ port_mask &= ~BIT(port); -+ an8855_fdb_write(priv, vid, port_mask, addr, port_mask ? true : false); -+ ret = an8855_fdb_cmd(priv, AN8855_FDB_WRITE, NULL); -+ -+exit: -+ mutex_unlock(&priv->reg_mutex); -+ -+ return ret; -+} -+ -+static int -+an8855_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) -+{ -+ struct an8855_priv *priv = ds->priv; -+ int length; -+ u32 val; -+ -+ /* When a new MTU is set, DSA always set the CPU port's MTU to the -+ * largest MTU of the slave ports. Because the switch only has a global -+ * RX length register, only allowing CPU port here is enough. -+ */ -+ if (!dsa_is_cpu_port(ds, port)) -+ return 0; -+ -+ /* RX length also includes Ethernet header, MTK tag, and FCS length */ -+ length = new_mtu + ETH_HLEN + MTK_TAG_LEN + ETH_FCS_LEN; -+ if (length <= 1522) -+ val = AN8855_MAX_RX_PKT_1518_1522; -+ else if (length <= 1536) -+ val = AN8855_MAX_RX_PKT_1536; -+ else if (length <= 1552) -+ val = AN8855_MAX_RX_PKT_1552; -+ else if (length <= 3072) -+ val = AN8855_MAX_RX_JUMBO_3K; -+ else if (length <= 4096) -+ val = AN8855_MAX_RX_JUMBO_4K; -+ else if (length <= 5120) -+ val = AN8855_MAX_RX_JUMBO_5K; -+ else if (length <= 6144) -+ val = AN8855_MAX_RX_JUMBO_6K; -+ else if (length <= 7168) -+ val = AN8855_MAX_RX_JUMBO_7K; -+ else if (length <= 8192) -+ val = AN8855_MAX_RX_JUMBO_8K; -+ else if (length <= 9216) -+ val = AN8855_MAX_RX_JUMBO_9K; -+ else if (length <= 12288) -+ val = AN8855_MAX_RX_JUMBO_12K; -+ else if (length <= 15360) -+ val = AN8855_MAX_RX_JUMBO_15K; -+ else -+ val = AN8855_MAX_RX_JUMBO_16K; -+ -+ /* Enable JUMBO packet */ -+ if (length > 1552) -+ val |= AN8855_MAX_RX_PKT_JUMBO; -+ -+ return regmap_update_bits(priv->regmap, AN8855_GMACCR, -+ AN8855_MAX_RX_JUMBO | AN8855_MAX_RX_PKT_LEN, -+ val); -+} -+ -+static int -+an8855_port_max_mtu(struct dsa_switch *ds, int port) -+{ -+ return AN8855_MAX_MTU; -+} -+ -+static void -+an8855_get_strings(struct dsa_switch *ds, int port, u32 stringset, -+ uint8_t *data) -+{ -+ int i; -+ -+ if (stringset != ETH_SS_STATS) -+ return; -+ -+ for (i = 0; i < ARRAY_SIZE(an8855_mib); i++) -+ ethtool_puts(&data, an8855_mib[i].name); -+} -+ -+static void -+an8855_read_port_stats(struct an8855_priv *priv, int port, u32 offset, u8 size, -+ uint64_t *data) -+{ -+ u32 val, reg = AN8855_PORT_MIB_COUNTER(port) + offset; -+ -+ regmap_read(priv->regmap, reg, &val); -+ *data = val; -+ -+ if (size == 2) { -+ regmap_read(priv->regmap, reg + 4, &val); -+ *data |= (u64)val << 32; -+ } -+} -+ -+static void -+an8855_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data) -+{ -+ struct an8855_priv *priv = ds->priv; -+ const struct an8855_mib_desc *mib; -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(an8855_mib); i++) { -+ mib = &an8855_mib[i]; -+ -+ an8855_read_port_stats(priv, port, mib->offset, mib->size, -+ data + i); -+ } -+} -+ -+static int -+an8855_get_sset_count(struct dsa_switch *ds, int port, int sset) -+{ -+ if (sset != ETH_SS_STATS) -+ return 0; -+ -+ return ARRAY_SIZE(an8855_mib); -+} -+ -+static void -+an8855_get_eth_mac_stats(struct dsa_switch *ds, int port, -+ struct ethtool_eth_mac_stats *mac_stats) -+{ -+ struct an8855_priv *priv = ds->priv; -+ -+ /* MIB counter doesn't provide a FramesTransmittedOK but instead -+ * provide stats for Unicast, Broadcast and Multicast frames separately. -+ * To simulate a global frame counter, read Unicast and addition Multicast -+ * and Broadcast later -+ */ -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_UNICAST, 1, -+ &mac_stats->FramesTransmittedOK); -+ -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_SINGLE_COLLISION, 1, -+ &mac_stats->SingleCollisionFrames); -+ -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_MULTIPLE_COLLISION, 1, -+ &mac_stats->MultipleCollisionFrames); -+ -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_UNICAST, 1, -+ &mac_stats->FramesReceivedOK); -+ -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_BYTES, 2, -+ &mac_stats->OctetsTransmittedOK); -+ -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_ALIGN_ERR, 1, -+ &mac_stats->AlignmentErrors); -+ -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_DEFERRED, 1, -+ &mac_stats->FramesWithDeferredXmissions); -+ -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_LATE_COLLISION, 1, -+ &mac_stats->LateCollisions); -+ -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_EXCESSIVE_COLLISION, 1, -+ &mac_stats->FramesAbortedDueToXSColls); -+ -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_BYTES, 2, -+ &mac_stats->OctetsReceivedOK); -+ -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_MULTICAST, 1, -+ &mac_stats->MulticastFramesXmittedOK); -+ mac_stats->FramesTransmittedOK += mac_stats->MulticastFramesXmittedOK; -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_BROADCAST, 1, -+ &mac_stats->BroadcastFramesXmittedOK); -+ mac_stats->FramesTransmittedOK += mac_stats->BroadcastFramesXmittedOK; -+ -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_MULTICAST, 1, -+ &mac_stats->MulticastFramesReceivedOK); -+ mac_stats->FramesReceivedOK += mac_stats->MulticastFramesReceivedOK; -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_BROADCAST, 1, -+ &mac_stats->BroadcastFramesReceivedOK); -+ mac_stats->FramesReceivedOK += mac_stats->BroadcastFramesReceivedOK; -+} -+ -+static const struct ethtool_rmon_hist_range an8855_rmon_ranges[] = { -+ { 0, 64 }, -+ { 65, 127 }, -+ { 128, 255 }, -+ { 256, 511 }, -+ { 512, 1023 }, -+ { 1024, 1518 }, -+ { 1519, AN8855_MAX_MTU }, -+ {} -+}; -+ -+static void an8855_get_rmon_stats(struct dsa_switch *ds, int port, -+ struct ethtool_rmon_stats *rmon_stats, -+ const struct ethtool_rmon_hist_range **ranges) -+{ -+ struct an8855_priv *priv = ds->priv; -+ -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_UNDER_SIZE_ERR, 1, -+ &rmon_stats->undersize_pkts); -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_OVER_SZ_ERR, 1, -+ &rmon_stats->oversize_pkts); -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_FRAG_ERR, 1, -+ &rmon_stats->fragments); -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_JABBER_ERR, 1, -+ &rmon_stats->jabbers); -+ -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PKT_SZ_64, 1, -+ &rmon_stats->hist[0]); -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PKT_SZ_65_TO_127, 1, -+ &rmon_stats->hist[1]); -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PKT_SZ_128_TO_255, 1, -+ &rmon_stats->hist[2]); -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PKT_SZ_256_TO_511, 1, -+ &rmon_stats->hist[3]); -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PKT_SZ_512_TO_1023, 1, -+ &rmon_stats->hist[4]); -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PKT_SZ_1024_TO_1518, 1, -+ &rmon_stats->hist[5]); -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PKT_SZ_1519_TO_MAX, 1, -+ &rmon_stats->hist[6]); -+ -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PKT_SZ_64, 1, -+ &rmon_stats->hist_tx[0]); -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PKT_SZ_65_TO_127, 1, -+ &rmon_stats->hist_tx[1]); -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PKT_SZ_128_TO_255, 1, -+ &rmon_stats->hist_tx[2]); -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PKT_SZ_256_TO_511, 1, -+ &rmon_stats->hist_tx[3]); -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PKT_SZ_512_TO_1023, 1, -+ &rmon_stats->hist_tx[4]); -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PKT_SZ_1024_TO_1518, 1, -+ &rmon_stats->hist_tx[5]); -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PKT_SZ_1519_TO_MAX, 1, -+ &rmon_stats->hist_tx[6]); -+ -+ *ranges = an8855_rmon_ranges; -+} -+ -+static void an8855_get_eth_ctrl_stats(struct dsa_switch *ds, int port, -+ struct ethtool_eth_ctrl_stats *ctrl_stats) -+{ -+ struct an8855_priv *priv = ds->priv; -+ -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PAUSE, 1, -+ &ctrl_stats->MACControlFramesTransmitted); -+ -+ an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PAUSE, 1, -+ &ctrl_stats->MACControlFramesReceived); -+} -+ -+static int an8855_port_mirror_add(struct dsa_switch *ds, int port, -+ struct dsa_mall_mirror_tc_entry *mirror, -+ bool ingress, -+ struct netlink_ext_ack *extack) -+{ -+ struct an8855_priv *priv = ds->priv; -+ int monitor_port; -+ u32 val; -+ int ret; -+ -+ /* Check for existent entry */ -+ if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port)) -+ return -EEXIST; -+ -+ ret = regmap_read(priv->regmap, AN8855_MIR, &val); -+ if (ret) -+ return ret; -+ -+ /* AN8855 supports 4 monitor port, but only use first group */ -+ monitor_port = FIELD_GET(AN8855_MIRROR_PORT, val); -+ if (val & AN8855_MIRROR_EN && monitor_port != mirror->to_local_port) -+ return -EEXIST; -+ -+ val = AN8855_MIRROR_EN; -+ val |= FIELD_PREP(AN8855_MIRROR_PORT, mirror->to_local_port); -+ ret = regmap_update_bits(priv->regmap, AN8855_MIR, -+ AN8855_MIRROR_EN | AN8855_MIRROR_PORT, -+ val); -+ if (ret) -+ return ret; -+ -+ ret = regmap_set_bits(priv->regmap, AN8855_PCR_P(port), -+ ingress ? AN8855_PORT_RX_MIR : AN8855_PORT_TX_MIR); -+ if (ret) -+ return ret; -+ -+ if (ingress) -+ priv->mirror_rx |= BIT(port); -+ else -+ priv->mirror_tx |= BIT(port); -+ -+ return 0; -+} -+ -+static void an8855_port_mirror_del(struct dsa_switch *ds, int port, -+ struct dsa_mall_mirror_tc_entry *mirror) -+{ -+ struct an8855_priv *priv = ds->priv; -+ -+ if (mirror->ingress) -+ priv->mirror_rx &= ~BIT(port); -+ else -+ priv->mirror_tx &= ~BIT(port); -+ -+ regmap_clear_bits(priv->regmap, AN8855_PCR_P(port), -+ mirror->ingress ? AN8855_PORT_RX_MIR : -+ AN8855_PORT_TX_MIR); -+ -+ if (!priv->mirror_rx && !priv->mirror_tx) -+ regmap_clear_bits(priv->regmap, AN8855_MIR, AN8855_MIRROR_EN); -+} -+ -+static int an8855_port_set_status(struct an8855_priv *priv, int port, -+ bool enable) -+{ -+ if (enable) -+ return regmap_set_bits(priv->regmap, AN8855_PMCR_P(port), -+ AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN); -+ else -+ return regmap_clear_bits(priv->regmap, AN8855_PMCR_P(port), -+ AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN); -+} -+ -+static int an8855_port_enable(struct dsa_switch *ds, int port, -+ struct phy_device *phy) -+{ -+ return an8855_port_set_status(ds->priv, port, true); -+} -+ -+static void an8855_port_disable(struct dsa_switch *ds, int port) -+{ -+ an8855_port_set_status(ds->priv, port, false); -+} -+ -+static u32 en8855_get_phy_flags(struct dsa_switch *ds, int port) -+{ -+ struct an8855_priv *priv = ds->priv; -+ -+ /* PHY doesn't need calibration */ -+ if (!priv->phy_require_calib) -+ return 0; -+ -+ /* Use AN8855_PHY_FLAGS_EN_CALIBRATION to signal -+ * calibration needed. -+ */ -+ return AN8855_PHY_FLAGS_EN_CALIBRATION; -+} -+ -+static enum dsa_tag_protocol -+an8855_get_tag_protocol(struct dsa_switch *ds, int port, -+ enum dsa_tag_protocol mp) -+{ -+ return DSA_TAG_PROTO_MTK; -+} -+ -+/* Similar to MT7530 also trap link local frame and special frame to CPU */ -+static int an8855_trap_special_frames(struct an8855_priv *priv) -+{ -+ int ret; -+ -+ /* Trap BPDUs to the CPU port(s) and egress them -+ * VLAN-untagged. -+ */ -+ ret = regmap_update_bits(priv->regmap, AN8855_BPC, -+ AN8855_BPDU_BPDU_FR | AN8855_BPDU_EG_TAG | -+ AN8855_BPDU_PORT_FW, -+ AN8855_BPDU_BPDU_FR | -+ FIELD_PREP(AN8855_BPDU_EG_TAG, AN8855_VLAN_EG_UNTAGGED) | -+ FIELD_PREP(AN8855_BPDU_PORT_FW, AN8855_BPDU_CPU_ONLY)); -+ if (ret) -+ return ret; -+ -+ /* Trap 802.1X PAE frames to the CPU port(s) and egress them -+ * VLAN-untagged. -+ */ -+ ret = regmap_update_bits(priv->regmap, AN8855_PAC, -+ AN8855_PAE_BPDU_FR | AN8855_PAE_EG_TAG | -+ AN8855_PAE_PORT_FW, -+ AN8855_PAE_BPDU_FR | -+ FIELD_PREP(AN8855_PAE_EG_TAG, AN8855_VLAN_EG_UNTAGGED) | -+ FIELD_PREP(AN8855_PAE_PORT_FW, AN8855_BPDU_CPU_ONLY)); -+ if (ret) -+ return ret; -+ -+ /* Trap frames with :01 MAC DAs to the CPU port(s) and egress -+ * them VLAN-untagged. -+ */ -+ ret = regmap_update_bits(priv->regmap, AN8855_RGAC1, -+ AN8855_R01_BPDU_FR | AN8855_R01_EG_TAG | -+ AN8855_R01_PORT_FW, -+ AN8855_R01_BPDU_FR | -+ FIELD_PREP(AN8855_R01_EG_TAG, AN8855_VLAN_EG_UNTAGGED) | -+ FIELD_PREP(AN8855_R01_PORT_FW, AN8855_BPDU_CPU_ONLY)); -+ if (ret) -+ return ret; -+ -+ /* Trap frames with :02 MAC DAs to the CPU port(s) and egress -+ * them VLAN-untagged. -+ */ -+ ret = regmap_update_bits(priv->regmap, AN8855_RGAC1, -+ AN8855_R02_BPDU_FR | AN8855_R02_EG_TAG | -+ AN8855_R02_PORT_FW, -+ AN8855_R02_BPDU_FR | -+ FIELD_PREP(AN8855_R02_EG_TAG, AN8855_VLAN_EG_UNTAGGED) | -+ FIELD_PREP(AN8855_R02_PORT_FW, AN8855_BPDU_CPU_ONLY)); -+ if (ret) -+ return ret; -+ -+ /* Trap frames with :03 MAC DAs to the CPU port(s) and egress -+ * them VLAN-untagged. -+ */ -+ ret = regmap_update_bits(priv->regmap, AN8855_RGAC1, -+ AN8855_R03_BPDU_FR | AN8855_R03_EG_TAG | -+ AN8855_R03_PORT_FW, -+ AN8855_R03_BPDU_FR | -+ FIELD_PREP(AN8855_R03_EG_TAG, AN8855_VLAN_EG_UNTAGGED) | -+ FIELD_PREP(AN8855_R03_PORT_FW, AN8855_BPDU_CPU_ONLY)); -+ if (ret) -+ return ret; -+ -+ /* Trap frames with :0E MAC DAs to the CPU port(s) and egress -+ * them VLAN-untagged. -+ */ -+ return regmap_update_bits(priv->regmap, AN8855_RGAC1, -+ AN8855_R0E_BPDU_FR | AN8855_R0E_EG_TAG | -+ AN8855_R0E_PORT_FW, -+ AN8855_R0E_BPDU_FR | -+ FIELD_PREP(AN8855_R0E_EG_TAG, AN8855_VLAN_EG_UNTAGGED) | -+ FIELD_PREP(AN8855_R0E_PORT_FW, AN8855_BPDU_CPU_ONLY)); -+} -+ -+static int -+an8855_setup_pvid_vlan(struct an8855_priv *priv) -+{ -+ u32 val; -+ int ret; -+ -+ /* Validate the entry with independent learning, keep the original -+ * ingress tag attribute. -+ */ -+ val = AN8855_VA0_IVL_MAC | AN8855_VA0_EG_CON | -+ FIELD_PREP(AN8855_VA0_FID, AN8855_FID_BRIDGED) | -+ AN8855_VA0_PORT | AN8855_VA0_VLAN_VALID; -+ ret = regmap_write(priv->regmap, AN8855_VAWD0, val); -+ if (ret) -+ return ret; -+ -+ return an8855_vlan_cmd(priv, AN8855_VTCR_WR_VID, -+ AN8855_PORT_VID_DEFAULT); -+} -+ -+static int an8855_setup(struct dsa_switch *ds) -+{ -+ struct an8855_priv *priv = ds->priv; -+ struct dsa_port *dp; -+ int ret; -+ -+ /* Enable and reset MIB counters */ -+ ret = an8855_mib_init(priv); -+ if (ret) -+ return ret; -+ -+ dsa_switch_for_each_user_port(dp, ds) { -+ /* Disable MAC by default on all user ports */ -+ ret = an8855_port_set_status(priv, dp->index, false); -+ if (ret) -+ return ret; -+ -+ /* Individual user ports get connected to CPU port only */ -+ ret = regmap_write(priv->regmap, AN8855_PORTMATRIX_P(dp->index), -+ FIELD_PREP(AN8855_PORTMATRIX, BIT(AN8855_CPU_PORT))); -+ if (ret) -+ return ret; -+ -+ /* Disable Broadcast Forward on user ports */ -+ ret = regmap_clear_bits(priv->regmap, AN8855_BCF, BIT(dp->index)); -+ if (ret) -+ return ret; -+ -+ /* Disable Unknown Unicast Forward on user ports */ -+ ret = regmap_clear_bits(priv->regmap, AN8855_UNUF, BIT(dp->index)); -+ if (ret) -+ return ret; -+ -+ /* Disable Unknown Multicast Forward on user ports */ -+ ret = regmap_clear_bits(priv->regmap, AN8855_UNMF, BIT(dp->index)); -+ if (ret) -+ return ret; -+ -+ ret = regmap_clear_bits(priv->regmap, AN8855_UNIPMF, BIT(dp->index)); -+ if (ret) -+ return ret; -+ -+ /* Set default PVID to on all user ports */ -+ ret = an8855_port_set_pid(priv, dp->index, AN8855_PORT_VID_DEFAULT); -+ if (ret) -+ return ret; -+ } -+ -+ /* Enable Airoha header mode on the cpu port */ -+ ret = regmap_write(priv->regmap, AN8855_PVC_P(AN8855_CPU_PORT), -+ AN8855_PORT_SPEC_REPLACE_MODE | AN8855_PORT_SPEC_TAG); -+ if (ret) -+ return ret; -+ -+ /* Unknown multicast frame forwarding to the cpu port */ -+ ret = regmap_write(priv->regmap, AN8855_UNMF, BIT(AN8855_CPU_PORT)); -+ if (ret) -+ return ret; -+ -+ /* Set CPU port number */ -+ ret = regmap_update_bits(priv->regmap, AN8855_MFC, -+ AN8855_CPU_EN | AN8855_CPU_PORT_IDX, -+ AN8855_CPU_EN | -+ FIELD_PREP(AN8855_CPU_PORT_IDX, AN8855_CPU_PORT)); -+ if (ret) -+ return ret; -+ -+ /* CPU port gets connected to all user ports of -+ * the switch. -+ */ -+ ret = regmap_write(priv->regmap, AN8855_PORTMATRIX_P(AN8855_CPU_PORT), -+ FIELD_PREP(AN8855_PORTMATRIX, dsa_user_ports(ds))); -+ if (ret) -+ return ret; -+ -+ /* CPU port is set to fallback mode to let untagged -+ * frames pass through. -+ */ -+ ret = regmap_update_bits(priv->regmap, AN8855_PCR_P(AN8855_CPU_PORT), -+ AN8855_PORT_VLAN, -+ FIELD_PREP(AN8855_PORT_VLAN, AN8855_PORT_FALLBACK_MODE)); -+ if (ret) -+ return ret; -+ -+ /* Enable Broadcast Forward on CPU port */ -+ ret = regmap_set_bits(priv->regmap, AN8855_BCF, BIT(AN8855_CPU_PORT)); -+ if (ret) -+ return ret; -+ -+ /* Enable Unknown Unicast Forward on CPU port */ -+ ret = regmap_set_bits(priv->regmap, AN8855_UNUF, BIT(AN8855_CPU_PORT)); -+ if (ret) -+ return ret; -+ -+ /* Enable Unknown Multicast Forward on CPU port */ -+ ret = regmap_set_bits(priv->regmap, AN8855_UNMF, BIT(AN8855_CPU_PORT)); -+ if (ret) -+ return ret; -+ -+ ret = regmap_set_bits(priv->regmap, AN8855_UNIPMF, BIT(AN8855_CPU_PORT)); -+ if (ret) -+ return ret; -+ -+ /* Setup Trap special frame to CPU rules */ -+ ret = an8855_trap_special_frames(priv); -+ if (ret) -+ return ret; -+ -+ dsa_switch_for_each_port(dp, ds) { -+ /* Disable Learning on all ports. -+ * Learning on CPU is disabled for fdb isolation and handled by -+ * assisted_learning_on_cpu_port. -+ */ -+ ret = regmap_set_bits(priv->regmap, AN8855_PSC_P(dp->index), -+ AN8855_SA_DIS); -+ if (ret) -+ return ret; -+ -+ /* Enable consistent egress tag (for VLAN unware VLAN-passtrough) */ -+ ret = regmap_update_bits(priv->regmap, AN8855_PVC_P(dp->index), -+ AN8855_PVC_EG_TAG, -+ FIELD_PREP(AN8855_PVC_EG_TAG, AN8855_VLAN_EG_CONSISTENT)); -+ if (ret) -+ return ret; -+ } -+ -+ /* Setup VLAN for Default PVID */ -+ ret = an8855_setup_pvid_vlan(priv); -+ if (ret) -+ return ret; -+ -+ ret = regmap_clear_bits(priv->regmap, AN8855_CKGCR, -+ AN8855_CKG_LNKDN_GLB_STOP | AN8855_CKG_LNKDN_PORT_STOP); -+ if (ret) -+ return ret; -+ -+ /* Release global PHY power down */ -+ ret = regmap_write(priv->regmap, AN8855_RG_GPHY_AFE_PWD, 0x0); -+ if (ret) -+ return ret; -+ -+ ds->configure_vlan_while_not_filtering = true; -+ -+ /* Flush the FDB table */ -+ ret = an8855_fdb_cmd(priv, AN8855_FDB_FLUSH, NULL); -+ if (ret < 0) -+ return ret; -+ -+ /* Set min a max ageing value supported */ -+ ds->ageing_time_min = AN8855_L2_AGING_MS_CONSTANT; -+ ds->ageing_time_max = FIELD_MAX(AN8855_AGE_CNT) * -+ FIELD_MAX(AN8855_AGE_UNIT) * -+ AN8855_L2_AGING_MS_CONSTANT; -+ -+ /* Enable assisted learning for fdb isolation */ -+ ds->assisted_learning_on_cpu_port = true; -+ -+ return 0; -+} -+ -+static struct phylink_pcs *an8855_phylink_mac_select_pcs(struct phylink_config *config, -+ phy_interface_t interface) -+{ -+ struct dsa_port *dp = dsa_phylink_to_port(config); -+ struct an8855_priv *priv = dp->ds->priv; -+ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_2500BASEX: -+ return &priv->pcs; -+ default: -+ return NULL; -+ } -+} -+ -+static void an8855_phylink_mac_config(struct phylink_config *config, -+ unsigned int mode, -+ const struct phylink_link_state *state) -+{ -+ struct dsa_port *dp = dsa_phylink_to_port(config); -+ struct dsa_switch *ds = dp->ds; -+ struct an8855_priv *priv; -+ int port = dp->index; -+ -+ priv = ds->priv; -+ -+ /* Nothing to configure for internal ports */ -+ if (port != 5) -+ return; -+ -+ regmap_update_bits(priv->regmap, AN8855_PMCR_P(port), -+ AN8855_PMCR_IFG_XMIT | AN8855_PMCR_MAC_MODE | -+ AN8855_PMCR_BACKOFF_EN | AN8855_PMCR_BACKPR_EN, -+ FIELD_PREP(AN8855_PMCR_IFG_XMIT, 0x1) | -+ AN8855_PMCR_MAC_MODE | AN8855_PMCR_BACKOFF_EN | -+ AN8855_PMCR_BACKPR_EN); -+} -+ -+static void an8855_phylink_get_caps(struct dsa_switch *ds, int port, -+ struct phylink_config *config) -+{ -+ switch (port) { -+ case 0: -+ case 1: -+ case 2: -+ case 3: -+ case 4: -+ __set_bit(PHY_INTERFACE_MODE_GMII, -+ config->supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_INTERNAL, -+ config->supported_interfaces); -+ break; -+ case 5: -+ phy_interface_set_rgmii(config->supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_SGMII, -+ config->supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_2500BASEX, -+ config->supported_interfaces); -+ break; -+ } -+ -+ config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | -+ MAC_10 | MAC_100 | MAC_1000FD | MAC_2500FD; -+} -+ -+static void an8855_phylink_mac_link_down(struct phylink_config *config, -+ unsigned int mode, -+ phy_interface_t interface) -+{ -+ struct dsa_port *dp = dsa_phylink_to_port(config); -+ struct an8855_priv *priv = dp->ds->priv; -+ -+ /* With autoneg just disable TX/RX else also force link down */ -+ if (phylink_autoneg_inband(mode)) { -+ regmap_clear_bits(priv->regmap, AN8855_PMCR_P(dp->index), -+ AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN); -+ } else { -+ regmap_update_bits(priv->regmap, AN8855_PMCR_P(dp->index), -+ AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN | -+ AN8855_PMCR_FORCE_MODE | AN8855_PMCR_FORCE_LNK, -+ AN8855_PMCR_FORCE_MODE); -+ } -+} -+ -+static void an8855_phylink_mac_link_up(struct phylink_config *config, -+ struct phy_device *phydev, unsigned int mode, -+ phy_interface_t interface, int speed, -+ int duplex, bool tx_pause, bool rx_pause) -+{ -+ struct dsa_port *dp = dsa_phylink_to_port(config); -+ struct an8855_priv *priv = dp->ds->priv; -+ int port = dp->index; -+ u32 reg; -+ -+ reg = regmap_read(priv->regmap, AN8855_PMCR_P(port), ®); -+ if (phylink_autoneg_inband(mode)) { -+ reg &= ~AN8855_PMCR_FORCE_MODE; -+ } else { -+ reg |= AN8855_PMCR_FORCE_MODE | AN8855_PMCR_FORCE_LNK; -+ -+ reg &= ~AN8855_PMCR_FORCE_SPEED; -+ switch (speed) { -+ case SPEED_10: -+ reg |= AN8855_PMCR_FORCE_SPEED_10; -+ break; -+ case SPEED_100: -+ reg |= AN8855_PMCR_FORCE_SPEED_100; -+ break; -+ case SPEED_1000: -+ reg |= AN8855_PMCR_FORCE_SPEED_1000; -+ break; -+ case SPEED_2500: -+ reg |= AN8855_PMCR_FORCE_SPEED_2500; -+ break; -+ case SPEED_5000: -+ dev_err(priv->dev, "Missing support for 5G speed. Aborting...\n"); -+ return; -+ } -+ -+ reg &= ~AN8855_PMCR_FORCE_FDX; -+ if (duplex == DUPLEX_FULL) -+ reg |= AN8855_PMCR_FORCE_FDX; -+ -+ reg &= ~AN8855_PMCR_RX_FC_EN; -+ if (rx_pause || dsa_port_is_cpu(dp)) -+ reg |= AN8855_PMCR_RX_FC_EN; -+ -+ reg &= ~AN8855_PMCR_TX_FC_EN; -+ if (rx_pause || dsa_port_is_cpu(dp)) -+ reg |= AN8855_PMCR_TX_FC_EN; -+ -+ /* Disable any EEE options */ -+ reg &= ~(AN8855_PMCR_FORCE_EEE5G | AN8855_PMCR_FORCE_EEE2P5G | -+ AN8855_PMCR_FORCE_EEE1G | AN8855_PMCR_FORCE_EEE100); -+ } -+ -+ reg |= AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN; -+ -+ regmap_write(priv->regmap, AN8855_PMCR_P(port), reg); -+} -+ -+static unsigned int an8855_pcs_inband_caps(struct phylink_pcs *pcs, -+ phy_interface_t interface) -+{ -+ /* SGMII can be configured to use inband with AN result */ -+ if (interface == PHY_INTERFACE_MODE_SGMII) -+ return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE; -+ -+ /* inband is not supported in 2500-baseX and must be disabled */ -+ return LINK_INBAND_DISABLE; -+} -+ -+static void an8855_pcs_get_state(struct phylink_pcs *pcs, -+ struct phylink_link_state *state) -+{ -+ struct an8855_priv *priv = container_of(pcs, struct an8855_priv, pcs); -+ u32 val; -+ int ret; -+ -+ ret = regmap_read(priv->regmap, AN8855_PMSR_P(AN8855_CPU_PORT), &val); -+ if (ret < 0) { -+ state->link = false; -+ return; -+ } -+ -+ state->link = !!(val & AN8855_PMSR_LNK); -+ state->an_complete = state->link; -+ state->duplex = (val & AN8855_PMSR_DPX) ? DUPLEX_FULL : -+ DUPLEX_HALF; -+ -+ switch (val & AN8855_PMSR_SPEED) { -+ case AN8855_PMSR_SPEED_10: -+ state->speed = SPEED_10; -+ break; -+ case AN8855_PMSR_SPEED_100: -+ state->speed = SPEED_100; -+ break; -+ case AN8855_PMSR_SPEED_1000: -+ state->speed = SPEED_1000; -+ break; -+ case AN8855_PMSR_SPEED_2500: -+ state->speed = SPEED_2500; -+ break; -+ case AN8855_PMSR_SPEED_5000: -+ dev_err(priv->dev, "Missing support for 5G speed. Setting Unknown.\n"); -+ fallthrough; -+ default: -+ state->speed = SPEED_UNKNOWN; -+ break; -+ } -+ -+ if (val & AN8855_PMSR_RX_FC) -+ state->pause |= MLO_PAUSE_RX; -+ if (val & AN8855_PMSR_TX_FC) -+ state->pause |= MLO_PAUSE_TX; -+} -+ -+static int an8855_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode, -+ phy_interface_t interface, -+ const unsigned long *advertising, -+ bool permit_pause_to_mac) -+{ -+ struct an8855_priv *priv = container_of(pcs, struct an8855_priv, pcs); -+ u32 val; -+ int ret; -+ -+ /* !!! WELCOME TO HELL !!! */ -+ -+ /* TX FIR - improve TX EYE */ -+ ret = regmap_update_bits(priv->regmap, AN8855_INTF_CTRL_10, -+ AN8855_RG_DA_QP_TX_FIR_C2_SEL | -+ AN8855_RG_DA_QP_TX_FIR_C2_FORCE | -+ AN8855_RG_DA_QP_TX_FIR_C1_SEL | -+ AN8855_RG_DA_QP_TX_FIR_C1_FORCE, -+ AN8855_RG_DA_QP_TX_FIR_C2_SEL | -+ FIELD_PREP(AN8855_RG_DA_QP_TX_FIR_C2_FORCE, 0x4) | -+ AN8855_RG_DA_QP_TX_FIR_C1_SEL | -+ FIELD_PREP(AN8855_RG_DA_QP_TX_FIR_C1_FORCE, 0x0)); -+ if (ret) -+ return ret; -+ -+ if (interface == PHY_INTERFACE_MODE_2500BASEX) -+ val = 0x0; -+ else -+ val = 0xd; -+ ret = regmap_update_bits(priv->regmap, AN8855_INTF_CTRL_11, -+ AN8855_RG_DA_QP_TX_FIR_C0B_SEL | -+ AN8855_RG_DA_QP_TX_FIR_C0B_FORCE, -+ AN8855_RG_DA_QP_TX_FIR_C0B_SEL | -+ FIELD_PREP(AN8855_RG_DA_QP_TX_FIR_C0B_FORCE, val)); -+ if (ret) -+ return ret; -+ -+ /* RX CDR - improve RX Jitter Tolerance */ -+ if (interface == PHY_INTERFACE_MODE_2500BASEX) -+ val = 0x5; -+ else -+ val = 0x6; -+ ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_LPF_BOT_LIM, -+ AN8855_RG_QP_CDR_LPF_KP_GAIN | -+ AN8855_RG_QP_CDR_LPF_KI_GAIN, -+ FIELD_PREP(AN8855_RG_QP_CDR_LPF_KP_GAIN, val) | -+ FIELD_PREP(AN8855_RG_QP_CDR_LPF_KI_GAIN, val)); -+ if (ret) -+ return ret; -+ -+ /* PLL */ -+ if (interface == PHY_INTERFACE_MODE_2500BASEX) -+ val = 0x1; -+ else -+ val = 0x0; -+ ret = regmap_update_bits(priv->regmap, AN8855_QP_DIG_MODE_CTRL_1, -+ AN8855_RG_TPHY_SPEED, -+ FIELD_PREP(AN8855_RG_TPHY_SPEED, val)); -+ if (ret) -+ return ret; -+ -+ /* PLL - LPF */ -+ ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2, -+ AN8855_RG_DA_QP_PLL_RICO_SEL_INTF | -+ AN8855_RG_DA_QP_PLL_FBKSEL_INTF | -+ AN8855_RG_DA_QP_PLL_BR_INTF | -+ AN8855_RG_DA_QP_PLL_BPD_INTF | -+ AN8855_RG_DA_QP_PLL_BPA_INTF | -+ AN8855_RG_DA_QP_PLL_BC_INTF, -+ AN8855_RG_DA_QP_PLL_RICO_SEL_INTF | -+ FIELD_PREP(AN8855_RG_DA_QP_PLL_FBKSEL_INTF, 0x0) | -+ FIELD_PREP(AN8855_RG_DA_QP_PLL_BR_INTF, 0x3) | -+ FIELD_PREP(AN8855_RG_DA_QP_PLL_BPD_INTF, 0x0) | -+ FIELD_PREP(AN8855_RG_DA_QP_PLL_BPA_INTF, 0x5) | -+ FIELD_PREP(AN8855_RG_DA_QP_PLL_BC_INTF, 0x1)); -+ if (ret) -+ return ret; -+ -+ /* PLL - ICO */ -+ ret = regmap_set_bits(priv->regmap, AN8855_PLL_CTRL_4, -+ AN8855_RG_DA_QP_PLL_ICOLP_EN_INTF); -+ if (ret) -+ return ret; -+ ret = regmap_clear_bits(priv->regmap, AN8855_PLL_CTRL_2, -+ AN8855_RG_DA_QP_PLL_ICOIQ_EN_INTF); -+ if (ret) -+ return ret; -+ -+ /* PLL - CHP */ -+ if (interface == PHY_INTERFACE_MODE_2500BASEX) -+ val = 0x6; -+ else -+ val = 0x4; -+ ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2, -+ AN8855_RG_DA_QP_PLL_IR_INTF, -+ FIELD_PREP(AN8855_RG_DA_QP_PLL_IR_INTF, val)); -+ if (ret) -+ return ret; -+ -+ /* PLL - PFD */ -+ ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2, -+ AN8855_RG_DA_QP_PLL_PFD_OFFSET_EN_INTRF | -+ AN8855_RG_DA_QP_PLL_PFD_OFFSET_INTF | -+ AN8855_RG_DA_QP_PLL_KBAND_PREDIV_INTF, -+ FIELD_PREP(AN8855_RG_DA_QP_PLL_PFD_OFFSET_INTF, 0x1) | -+ FIELD_PREP(AN8855_RG_DA_QP_PLL_KBAND_PREDIV_INTF, 0x1)); -+ if (ret) -+ return ret; -+ -+ /* PLL - POSTDIV */ -+ ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2, -+ AN8855_RG_DA_QP_PLL_POSTDIV_EN_INTF | -+ AN8855_RG_DA_QP_PLL_PHY_CK_EN_INTF | -+ AN8855_RG_DA_QP_PLL_PCK_SEL_INTF, -+ AN8855_RG_DA_QP_PLL_PCK_SEL_INTF); -+ if (ret) -+ return ret; -+ -+ /* PLL - SDM */ -+ ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2, -+ AN8855_RG_DA_QP_PLL_SDM_HREN_INTF, -+ FIELD_PREP(AN8855_RG_DA_QP_PLL_SDM_HREN_INTF, 0x0)); -+ if (ret) -+ return ret; -+ ret = regmap_clear_bits(priv->regmap, AN8855_PLL_CTRL_2, -+ AN8855_RG_DA_QP_PLL_SDM_IFM_INTF); -+ if (ret) -+ return ret; -+ -+ ret = regmap_update_bits(priv->regmap, AN8855_SS_LCPLL_PWCTL_SETTING_2, -+ AN8855_RG_NCPO_ANA_MSB, -+ FIELD_PREP(AN8855_RG_NCPO_ANA_MSB, 0x1)); -+ if (ret) -+ return ret; -+ -+ if (interface == PHY_INTERFACE_MODE_2500BASEX) -+ val = 0x7a000000; -+ else -+ val = 0x48000000; -+ ret = regmap_write(priv->regmap, AN8855_SS_LCPLL_TDC_FLT_2, -+ FIELD_PREP(AN8855_RG_LCPLL_NCPO_VALUE, val)); -+ if (ret) -+ return ret; -+ ret = regmap_write(priv->regmap, AN8855_SS_LCPLL_TDC_PCW_1, -+ FIELD_PREP(AN8855_RG_LCPLL_PON_HRDDS_PCW_NCPO_GPON, val)); -+ if (ret) -+ return ret; -+ -+ ret = regmap_clear_bits(priv->regmap, AN8855_SS_LCPLL_TDC_FLT_5, -+ AN8855_RG_LCPLL_NCPO_CHG); -+ if (ret) -+ return ret; -+ ret = regmap_clear_bits(priv->regmap, AN8855_PLL_CK_CTRL_0, -+ AN8855_RG_DA_QP_PLL_SDM_DI_EN_INTF); -+ if (ret) -+ return ret; -+ -+ /* PLL - SS */ -+ ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_3, -+ AN8855_RG_DA_QP_PLL_SSC_DELTA_INTF, -+ FIELD_PREP(AN8855_RG_DA_QP_PLL_SSC_DELTA_INTF, 0x0)); -+ if (ret) -+ return ret; -+ ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_4, -+ AN8855_RG_DA_QP_PLL_SSC_DIR_DLY_INTF, -+ FIELD_PREP(AN8855_RG_DA_QP_PLL_SSC_DIR_DLY_INTF, 0x0)); -+ if (ret) -+ return ret; -+ ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_3, -+ AN8855_RG_DA_QP_PLL_SSC_PERIOD_INTF, -+ FIELD_PREP(AN8855_RG_DA_QP_PLL_SSC_PERIOD_INTF, 0x0)); -+ if (ret) -+ return ret; -+ -+ /* PLL - TDC */ -+ ret = regmap_clear_bits(priv->regmap, AN8855_PLL_CK_CTRL_0, -+ AN8855_RG_DA_QP_PLL_TDC_TXCK_SEL_INTF); -+ if (ret) -+ return ret; -+ -+ ret = regmap_set_bits(priv->regmap, AN8855_RG_QP_PLL_SDM_ORD, -+ AN8855_RG_QP_PLL_SSC_TRI_EN); -+ if (ret) -+ return ret; -+ ret = regmap_set_bits(priv->regmap, AN8855_RG_QP_PLL_SDM_ORD, -+ AN8855_RG_QP_PLL_SSC_PHASE_INI); -+ if (ret) -+ return ret; -+ -+ ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_RX_DAC_EN, -+ AN8855_RG_QP_SIGDET_HF, -+ FIELD_PREP(AN8855_RG_QP_SIGDET_HF, 0x2)); -+ if (ret) -+ return ret; -+ -+ /* TCL Disable (only for Co-SIM) */ -+ ret = regmap_clear_bits(priv->regmap, AN8855_PON_RXFEDIG_CTRL_0, -+ AN8855_RG_QP_EQ_RX500M_CK_SEL); -+ if (ret) -+ return ret; -+ -+ /* TX Init */ -+ if (interface == PHY_INTERFACE_MODE_2500BASEX) -+ val = 0x4; -+ else -+ val = 0x0; -+ ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_TX_MODE, -+ AN8855_RG_QP_TX_RESERVE | -+ AN8855_RG_QP_TX_MODE_16B_EN, -+ FIELD_PREP(AN8855_RG_QP_TX_RESERVE, val)); -+ if (ret) -+ return ret; -+ -+ /* RX Control/Init */ -+ ret = regmap_set_bits(priv->regmap, AN8855_RG_QP_RXAFE_RESERVE, -+ AN8855_RG_QP_CDR_PD_10B_EN); -+ if (ret) -+ return ret; -+ -+ if (interface == PHY_INTERFACE_MODE_2500BASEX) -+ val = 0x1; -+ else -+ val = 0x2; -+ ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_LPF_MJV_LIM, -+ AN8855_RG_QP_CDR_LPF_RATIO, -+ FIELD_PREP(AN8855_RG_QP_CDR_LPF_RATIO, val)); -+ if (ret) -+ return ret; -+ -+ ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_LPF_SETVALUE, -+ AN8855_RG_QP_CDR_PR_BUF_IN_SR | -+ AN8855_RG_QP_CDR_PR_BETA_SEL, -+ FIELD_PREP(AN8855_RG_QP_CDR_PR_BUF_IN_SR, 0x6) | -+ FIELD_PREP(AN8855_RG_QP_CDR_PR_BETA_SEL, 0x1)); -+ if (ret) -+ return ret; -+ -+ if (interface == PHY_INTERFACE_MODE_2500BASEX) -+ val = 0xf; -+ else -+ val = 0xc; -+ ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_PR_CKREF_DIV1, -+ AN8855_RG_QP_CDR_PR_DAC_BAND, -+ FIELD_PREP(AN8855_RG_QP_CDR_PR_DAC_BAND, val)); -+ if (ret) -+ return ret; -+ -+ ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE, -+ AN8855_RG_QP_CDR_PR_KBAND_PCIE_MODE | -+ AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE_MASK, -+ FIELD_PREP(AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE_MASK, 0x19)); -+ if (ret) -+ return ret; -+ -+ ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_FORCE_IBANDLPF_R_OFF, -+ AN8855_RG_QP_CDR_PHYCK_SEL | -+ AN8855_RG_QP_CDR_PHYCK_RSTB | -+ AN8855_RG_QP_CDR_PHYCK_DIV, -+ FIELD_PREP(AN8855_RG_QP_CDR_PHYCK_SEL, 0x2) | -+ FIELD_PREP(AN8855_RG_QP_CDR_PHYCK_DIV, 0x21)); -+ if (ret) -+ return ret; -+ -+ ret = regmap_clear_bits(priv->regmap, AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE, -+ AN8855_RG_QP_CDR_PR_XFICK_EN); -+ if (ret) -+ return ret; -+ -+ ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_PR_CKREF_DIV1, -+ AN8855_RG_QP_CDR_PR_KBAND_DIV, -+ FIELD_PREP(AN8855_RG_QP_CDR_PR_KBAND_DIV, 0x4)); -+ if (ret) -+ return ret; -+ -+ ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_26, -+ AN8855_RG_QP_EQ_RETRAIN_ONLY_EN | -+ AN8855_RG_LINK_NE_EN | -+ AN8855_RG_LINK_ERRO_EN, -+ AN8855_RG_QP_EQ_RETRAIN_ONLY_EN | -+ AN8855_RG_LINK_ERRO_EN); -+ if (ret) -+ return ret; -+ -+ ret = regmap_update_bits(priv->regmap, AN8855_RX_DLY_0, -+ AN8855_RG_QP_RX_SAOSC_EN_H_DLY | -+ AN8855_RG_QP_RX_PI_CAL_EN_H_DLY, -+ FIELD_PREP(AN8855_RG_QP_RX_SAOSC_EN_H_DLY, 0x3f) | -+ FIELD_PREP(AN8855_RG_QP_RX_PI_CAL_EN_H_DLY, 0x6f)); -+ if (ret) -+ return ret; -+ -+ ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_42, -+ AN8855_RG_QP_EQ_EN_DLY, -+ FIELD_PREP(AN8855_RG_QP_EQ_EN_DLY, 0x150)); -+ if (ret) -+ return ret; -+ -+ ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_2, -+ AN8855_RG_QP_RX_EQ_EN_H_DLY, -+ FIELD_PREP(AN8855_RG_QP_RX_EQ_EN_H_DLY, 0x150)); -+ if (ret) -+ return ret; -+ -+ ret = regmap_update_bits(priv->regmap, AN8855_PON_RXFEDIG_CTRL_9, -+ AN8855_RG_QP_EQ_LEQOSC_DLYCNT, -+ FIELD_PREP(AN8855_RG_QP_EQ_LEQOSC_DLYCNT, 0x1)); -+ if (ret) -+ return ret; -+ -+ ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_8, -+ AN8855_RG_DA_QP_SAOSC_DONE_TIME | -+ AN8855_RG_DA_QP_LEQOS_EN_TIME, -+ FIELD_PREP(AN8855_RG_DA_QP_SAOSC_DONE_TIME, 0x200) | -+ FIELD_PREP(AN8855_RG_DA_QP_LEQOS_EN_TIME, 0xfff)); -+ if (ret) -+ return ret; -+ -+ /* Frequency meter */ -+ if (interface == PHY_INTERFACE_MODE_2500BASEX) -+ val = 0x10; -+ else -+ val = 0x28; -+ ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_5, -+ AN8855_RG_FREDET_CHK_CYCLE, -+ FIELD_PREP(AN8855_RG_FREDET_CHK_CYCLE, val)); -+ if (ret) -+ return ret; -+ -+ ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_6, -+ AN8855_RG_FREDET_GOLDEN_CYCLE, -+ FIELD_PREP(AN8855_RG_FREDET_GOLDEN_CYCLE, 0x64)); -+ if (ret) -+ return ret; -+ -+ ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_7, -+ AN8855_RG_FREDET_TOLERATE_CYCLE, -+ FIELD_PREP(AN8855_RG_FREDET_TOLERATE_CYCLE, 0x2710)); -+ if (ret) -+ return ret; -+ -+ ret = regmap_set_bits(priv->regmap, AN8855_PLL_CTRL_0, -+ AN8855_RG_PHYA_AUTO_INIT); -+ if (ret) -+ return ret; -+ -+ /* PCS Init */ -+ if (interface == PHY_INTERFACE_MODE_SGMII && -+ neg_mode == PHYLINK_PCS_NEG_INBAND_DISABLED) { -+ ret = regmap_clear_bits(priv->regmap, AN8855_QP_DIG_MODE_CTRL_0, -+ AN8855_RG_SGMII_MODE | AN8855_RG_SGMII_AN_EN); -+ if (ret) -+ return ret; -+ } -+ -+ ret = regmap_clear_bits(priv->regmap, AN8855_RG_HSGMII_PCS_CTROL_1, -+ AN8855_RG_TBI_10B_MODE); -+ if (ret) -+ return ret; -+ -+ if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) { -+ /* Set AN Ability - Interrupt */ -+ ret = regmap_set_bits(priv->regmap, AN8855_SGMII_REG_AN_FORCE_CL37, -+ AN8855_RG_FORCE_AN_DONE); -+ if (ret) -+ return ret; -+ -+ ret = regmap_update_bits(priv->regmap, AN8855_SGMII_REG_AN_13, -+ AN8855_SGMII_REMOTE_FAULT_DIS | -+ AN8855_SGMII_IF_MODE, -+ AN8855_SGMII_REMOTE_FAULT_DIS | -+ FIELD_PREP(AN8855_SGMII_IF_MODE, 0xb)); -+ if (ret) -+ return ret; -+ } -+ -+ /* Rate Adaption - GMII path config. */ -+ if (interface == PHY_INTERFACE_MODE_2500BASEX) { -+ ret = regmap_clear_bits(priv->regmap, AN8855_RATE_ADP_P0_CTRL_0, -+ AN8855_RG_P0_DIS_MII_MODE); -+ if (ret) -+ return ret; -+ } else { -+ if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) { -+ ret = regmap_set_bits(priv->regmap, AN8855_MII_RA_AN_ENABLE, -+ AN8855_RG_P0_RA_AN_EN); -+ if (ret) -+ return ret; -+ } else { -+ ret = regmap_update_bits(priv->regmap, AN8855_RG_AN_SGMII_MODE_FORCE, -+ AN8855_RG_FORCE_CUR_SGMII_MODE | -+ AN8855_RG_FORCE_CUR_SGMII_SEL, -+ AN8855_RG_FORCE_CUR_SGMII_SEL); -+ if (ret) -+ return ret; -+ -+ ret = regmap_clear_bits(priv->regmap, AN8855_RATE_ADP_P0_CTRL_0, -+ AN8855_RG_P0_MII_RA_RX_EN | -+ AN8855_RG_P0_MII_RA_TX_EN | -+ AN8855_RG_P0_MII_RA_RX_MODE | -+ AN8855_RG_P0_MII_RA_TX_MODE); -+ if (ret) -+ return ret; -+ } -+ -+ ret = regmap_set_bits(priv->regmap, AN8855_RATE_ADP_P0_CTRL_0, -+ AN8855_RG_P0_MII_MODE); -+ if (ret) -+ return ret; -+ } -+ -+ ret = regmap_set_bits(priv->regmap, AN8855_RG_RATE_ADAPT_CTRL_0, -+ AN8855_RG_RATE_ADAPT_RX_BYPASS | -+ AN8855_RG_RATE_ADAPT_TX_BYPASS | -+ AN8855_RG_RATE_ADAPT_RX_EN | -+ AN8855_RG_RATE_ADAPT_TX_EN); -+ if (ret) -+ return ret; -+ -+ /* Disable AN if not in autoneg */ -+ ret = regmap_update_bits(priv->regmap, AN8855_SGMII_REG_AN0, BMCR_ANENABLE, -+ neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED ? BMCR_ANENABLE : -+ 0); -+ if (ret) -+ return ret; -+ -+ if (interface == PHY_INTERFACE_MODE_SGMII) { -+ /* Follow SDK init flow with restarting AN after AN enable */ -+ if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) { -+ ret = regmap_set_bits(priv->regmap, AN8855_SGMII_REG_AN0, -+ BMCR_ANRESTART); -+ if (ret) -+ return ret; -+ } else { -+ ret = regmap_set_bits(priv->regmap, AN8855_PHY_RX_FORCE_CTRL_0, -+ AN8855_RG_FORCE_TXC_SEL); -+ if (ret) -+ return ret; -+ } -+ } -+ -+ /* Force Speed with fixed-link or 2500base-x as doesn't support aneg */ -+ if (interface == PHY_INTERFACE_MODE_2500BASEX || -+ neg_mode != PHYLINK_PCS_NEG_INBAND_ENABLED) { -+ if (interface == PHY_INTERFACE_MODE_2500BASEX) -+ val = AN8855_RG_LINK_MODE_P0_SPEED_2500; -+ else -+ val = AN8855_RG_LINK_MODE_P0_SPEED_1000; -+ ret = regmap_update_bits(priv->regmap, AN8855_SGMII_STS_CTRL_0, -+ AN8855_RG_LINK_MODE_P0 | -+ AN8855_RG_FORCE_SPD_MODE_P0, -+ val | AN8855_RG_FORCE_SPD_MODE_P0); -+ if (ret) -+ return ret; -+ } -+ -+ /* bypass flow control to MAC */ -+ ret = regmap_write(priv->regmap, AN8855_MSG_RX_LIK_STS_0, -+ AN8855_RG_DPX_STS_P3 | AN8855_RG_DPX_STS_P2 | -+ AN8855_RG_DPX_STS_P1 | AN8855_RG_TXFC_STS_P0 | -+ AN8855_RG_RXFC_STS_P0 | AN8855_RG_DPX_STS_P0); -+ if (ret) -+ return ret; -+ ret = regmap_write(priv->regmap, AN8855_MSG_RX_LIK_STS_2, -+ AN8855_RG_RXFC_AN_BYPASS_P3 | -+ AN8855_RG_RXFC_AN_BYPASS_P2 | -+ AN8855_RG_RXFC_AN_BYPASS_P1 | -+ AN8855_RG_TXFC_AN_BYPASS_P3 | -+ AN8855_RG_TXFC_AN_BYPASS_P2 | -+ AN8855_RG_TXFC_AN_BYPASS_P1 | -+ AN8855_RG_DPX_AN_BYPASS_P3 | -+ AN8855_RG_DPX_AN_BYPASS_P2 | -+ AN8855_RG_DPX_AN_BYPASS_P1 | -+ AN8855_RG_DPX_AN_BYPASS_P0); -+ if (ret) -+ return ret; -+ -+ return 0; -+} -+ -+static void an8855_pcs_an_restart(struct phylink_pcs *pcs) -+{ -+ return; -+} -+ -+static const struct phylink_pcs_ops an8855_pcs_ops = { -+ .pcs_inband_caps = an8855_pcs_inband_caps, -+ .pcs_get_state = an8855_pcs_get_state, -+ .pcs_config = an8855_pcs_config, -+ .pcs_an_restart = an8855_pcs_an_restart, -+}; -+ -+static const struct phylink_mac_ops an8855_phylink_mac_ops = { -+ .mac_select_pcs = an8855_phylink_mac_select_pcs, -+ .mac_config = an8855_phylink_mac_config, -+ .mac_link_down = an8855_phylink_mac_link_down, -+ .mac_link_up = an8855_phylink_mac_link_up, -+}; -+ -+static const struct dsa_switch_ops an8855_switch_ops = { -+ .get_tag_protocol = an8855_get_tag_protocol, -+ .setup = an8855_setup, -+ .get_phy_flags = en8855_get_phy_flags, -+ .phylink_get_caps = an8855_phylink_get_caps, -+ .get_strings = an8855_get_strings, -+ .get_ethtool_stats = an8855_get_ethtool_stats, -+ .get_sset_count = an8855_get_sset_count, -+ .get_eth_mac_stats = an8855_get_eth_mac_stats, -+ .get_eth_ctrl_stats = an8855_get_eth_ctrl_stats, -+ .get_rmon_stats = an8855_get_rmon_stats, -+ .port_enable = an8855_port_enable, -+ .port_disable = an8855_port_disable, -+ .set_ageing_time = an8855_set_ageing_time, -+ .port_bridge_join = an8855_port_bridge_join, -+ .port_bridge_leave = an8855_port_bridge_leave, -+ .port_fast_age = an8855_port_fast_age, -+ .port_stp_state_set = an8855_port_stp_state_set, -+ .port_pre_bridge_flags = an8855_port_pre_bridge_flags, -+ .port_bridge_flags = an8855_port_bridge_flags, -+ .port_vlan_filtering = an8855_port_vlan_filtering, -+ .port_vlan_add = an8855_port_vlan_add, -+ .port_vlan_del = an8855_port_vlan_del, -+ .port_fdb_add = an8855_port_fdb_add, -+ .port_fdb_del = an8855_port_fdb_del, -+ .port_fdb_dump = an8855_port_fdb_dump, -+ .port_mdb_add = an8855_port_mdb_add, -+ .port_mdb_del = an8855_port_mdb_del, -+ .port_change_mtu = an8855_port_change_mtu, -+ .port_max_mtu = an8855_port_max_mtu, -+ .port_mirror_add = an8855_port_mirror_add, -+ .port_mirror_del = an8855_port_mirror_del, -+}; -+ -+static int an8855_read_switch_id(struct an8855_priv *priv) -+{ -+ u32 id; -+ int ret; -+ -+ ret = regmap_read(priv->regmap, AN8855_CREV, &id); -+ if (ret) -+ return ret; -+ -+ if (id != AN8855_ID) { -+ dev_err(priv->dev, -+ "Switch id detected %x but expected %x\n", -+ id, AN8855_ID); -+ return -ENODEV; -+ } -+ -+ return 0; -+} -+ -+static int an8855_switch_probe(struct platform_device *pdev) -+{ -+ struct an8855_priv *priv; -+ u32 val; -+ int ret; -+ -+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->dev = &pdev->dev; -+ priv->phy_require_calib = of_property_read_bool(priv->dev->of_node, -+ "airoha,ext-surge"); -+ -+ priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset", -+ GPIOD_OUT_LOW); -+ if (IS_ERR(priv->reset_gpio)) -+ return PTR_ERR(priv->reset_gpio); -+ -+ /* Get regmap from MFD */ -+ priv->regmap = dev_get_regmap(priv->dev->parent, NULL); -+ -+ if (priv->reset_gpio) { -+ usleep_range(100000, 150000); -+ gpiod_set_value_cansleep(priv->reset_gpio, 0); -+ usleep_range(100000, 150000); -+ gpiod_set_value_cansleep(priv->reset_gpio, 1); -+ -+ /* Poll HWTRAP reg to wait for Switch to fully Init */ -+ ret = regmap_read_poll_timeout(priv->regmap, AN8855_HWTRAP, val, -+ val, 20, 200000); -+ if (ret) -+ return ret; -+ } -+ -+ ret = an8855_read_switch_id(priv); -+ if (ret) -+ return ret; -+ -+ priv->ds = devm_kzalloc(priv->dev, sizeof(*priv->ds), GFP_KERNEL); -+ if (!priv->ds) -+ return -ENOMEM; -+ -+ priv->ds->dev = priv->dev; -+ priv->ds->num_ports = AN8855_NUM_PORTS; -+ priv->ds->priv = priv; -+ priv->ds->ops = &an8855_switch_ops; -+ devm_mutex_init(priv->dev, &priv->reg_mutex); -+ priv->ds->phylink_mac_ops = &an8855_phylink_mac_ops; -+ -+ priv->pcs.ops = &an8855_pcs_ops; -+ priv->pcs.neg_mode = true; -+ priv->pcs.poll = true; -+ -+ dev_set_drvdata(priv->dev, priv); -+ -+ return dsa_register_switch(priv->ds); -+} -+ -+static void an8855_switch_remove(struct platform_device *pdev) -+{ -+ struct an8855_priv *priv = dev_get_drvdata(&pdev->dev); -+ -+ if (priv) -+ dsa_unregister_switch(priv->ds); -+} -+ -+static const struct of_device_id an8855_switch_of_match[] = { -+ { .compatible = "airoha,an8855-switch" }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, an8855_switch_of_match); -+ -+static struct platform_driver an8855_switch_driver = { -+ .probe = an8855_switch_probe, -+ .remove_new = an8855_switch_remove, -+ .driver = { -+ .name = "an8855-switch", -+ .of_match_table = an8855_switch_of_match, -+ }, -+}; -+module_platform_driver(an8855_switch_driver); -+ -+MODULE_AUTHOR("Min Yao "); -+MODULE_AUTHOR("Christian Marangi "); -+MODULE_DESCRIPTION("Driver for Airoha AN8855 Switch"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/net/dsa/an8855.h b/drivers/net/dsa/an8855.h -new file mode 100644 -index 000000000000..2462b9d33752 ---- /dev/null -+++ b/drivers/net/dsa/an8855.h -@@ -0,0 +1,783 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (C) 2023 Min Yao -+ * Copyright (C) 2024 Christian Marangi -+ */ -+ -+#ifndef __AN8855_H -+#define __AN8855_H -+ -+#include -+ -+#define AN8855_NUM_PORTS 6 -+#define AN8855_CPU_PORT 5 -+#define AN8855_NUM_FDB_RECORDS 2048 -+#define AN8855_GPHY_SMI_ADDR_DEFAULT 1 -+#define AN8855_PORT_VID_DEFAULT 0 -+ -+#define MTK_TAG_LEN 4 -+#define AN8855_MAX_MTU (15360 - ETH_HLEN - ETH_FCS_LEN - MTK_TAG_LEN) -+ -+#define AN8855_L2_AGING_MS_CONSTANT 1024 -+ -+#define AN8855_PHY_FLAGS_EN_CALIBRATION BIT(0) -+ -+/* AN8855_SCU 0x10000000 */ -+#define AN8855_RG_GPIO_LED_MODE 0x10000054 -+#define AN8855_RG_GPIO_LED_SEL(i) (0x10000000 + (0x0058 + ((i) * 4))) -+#define AN8855_RG_INTB_MODE 0x10000080 -+#define AN8855_RG_RGMII_TXCK_C 0x100001d0 -+ -+#define AN8855_PKG_SEL 0x10000094 -+#define AN8855_PAG_SEL_AN8855H 0x2 -+ -+/* Register for hw trap status */ -+#define AN8855_HWTRAP 0x1000009c -+ -+#define AN8855_RG_GPIO_L_INV 0x10000010 -+#define AN8855_RG_GPIO_CTRL 0x1000a300 -+#define AN8855_RG_GPIO_DATA 0x1000a304 -+#define AN8855_RG_GPIO_OE 0x1000a314 -+ -+#define AN8855_CREV 0x10005000 -+#define AN8855_ID 0x8855 -+ -+/* Register for system reset */ -+#define AN8855_RST_CTRL 0x100050c0 -+#define AN8855_SYS_CTRL_SYS_RST BIT(31) -+ -+#define AN8855_INT_MASK 0x100050f0 -+#define AN8855_INT_SYS BIT(15) -+ -+#define AN8855_RG_CLK_CPU_ICG 0x10005034 -+#define AN8855_MCU_ENABLE BIT(3) -+ -+#define AN8855_RG_TIMER_CTL 0x1000a100 -+#define AN8855_WDOG_ENABLE BIT(25) -+ -+#define AN8855_RG_GDMP_RAM 0x10010000 -+ -+/* Registers to mac forward control for unknown frames */ -+#define AN8855_MFC 0x10200010 -+#define AN8855_CPU_EN BIT(15) -+#define AN8855_CPU_PORT_IDX GENMASK(12, 8) -+ -+#define AN8855_PAC 0x10200024 -+#define AN8855_TAG_PAE_MANG_FR BIT(30) -+#define AN8855_TAG_PAE_BPDU_FR BIT(28) -+#define AN8855_TAG_PAE_EG_TAG GENMASK(27, 25) -+#define AN8855_TAG_PAE_LKY_VLAN BIT(24) -+#define AN8855_TAG_PAE_PRI_HIGH BIT(23) -+#define AN8855_TAG_PAE_MIR GENMASK(20, 19) -+#define AN8855_TAG_PAE_PORT_FW GENMASK(18, 16) -+#define AN8855_PAE_MANG_FR BIT(14) -+#define AN8855_PAE_BPDU_FR BIT(12) -+#define AN8855_PAE_EG_TAG GENMASK(11, 9) -+#define AN8855_PAE_LKY_VLAN BIT(8) -+#define AN8855_PAE_PRI_HIGH BIT(7) -+#define AN8855_PAE_MIR GENMASK(4, 3) -+#define AN8855_PAE_PORT_FW GENMASK(2, 0) -+ -+#define AN8855_RGAC1 0x10200028 -+#define AN8855_R02_MANG_FR BIT(30) -+#define AN8855_R02_BPDU_FR BIT(28) -+#define AN8855_R02_EG_TAG GENMASK(27, 25) -+#define AN8855_R02_LKY_VLAN BIT(24) -+#define AN8855_R02_PRI_HIGH BIT(23) -+#define AN8855_R02_MIR GENMASK(20, 19) -+#define AN8855_R02_PORT_FW GENMASK(18, 16) -+#define AN8855_R01_MANG_FR BIT(14) -+#define AN8855_R01_BPDU_FR BIT(12) -+#define AN8855_R01_EG_TAG GENMASK(11, 9) -+#define AN8855_R01_LKY_VLAN BIT(8) -+#define AN8855_R01_PRI_HIGH BIT(7) -+#define AN8855_R01_MIR GENMASK(4, 3) -+#define AN8855_R01_PORT_FW GENMASK(2, 0) -+ -+#define AN8855_RGAC2 0x1020002c -+#define AN8855_R0E_MANG_FR BIT(30) -+#define AN8855_R0E_BPDU_FR BIT(28) -+#define AN8855_R0E_EG_TAG GENMASK(27, 25) -+#define AN8855_R0E_LKY_VLAN BIT(24) -+#define AN8855_R0E_PRI_HIGH BIT(23) -+#define AN8855_R0E_MIR GENMASK(20, 19) -+#define AN8855_R0E_PORT_FW GENMASK(18, 16) -+#define AN8855_R03_MANG_FR BIT(14) -+#define AN8855_R03_BPDU_FR BIT(12) -+#define AN8855_R03_EG_TAG GENMASK(11, 9) -+#define AN8855_R03_LKY_VLAN BIT(8) -+#define AN8855_R03_PRI_HIGH BIT(7) -+#define AN8855_R03_MIR GENMASK(4, 3) -+#define AN8855_R03_PORT_FW GENMASK(2, 0) -+ -+#define AN8855_AAC 0x102000a0 -+#define AN8855_MAC_AUTO_FLUSH BIT(28) -+/* Control Address Table Age time. -+ * (AN8855_AGE_CNT + 1) * ( AN8855_AGE_UNIT + 1 ) * AN8855_L2_AGING_MS_CONSTANT -+ */ -+#define AN8855_AGE_CNT GENMASK(20, 12) -+/* Value in seconds. Value is always incremented of 1 */ -+#define AN8855_AGE_UNIT GENMASK(10, 0) -+ -+/* Registers for ARL Unknown Unicast Forward control */ -+#define AN8855_UNUF 0x102000b4 -+ -+/* Registers for ARL Unknown Multicast Forward control */ -+#define AN8855_UNMF 0x102000b8 -+ -+/* Registers for ARL Broadcast forward control */ -+#define AN8855_BCF 0x102000bc -+ -+/* Registers for port address age disable */ -+#define AN8855_AGDIS 0x102000c0 -+ -+/* Registers for mirror port control */ -+#define AN8855_MIR 0x102000cc -+#define AN8855_MIRROR_EN BIT(7) -+#define AN8855_MIRROR_PORT GENMASK(4, 0) -+ -+/* Registers for BPDU and PAE frame control*/ -+#define AN8855_BPC 0x102000d0 -+#define AN8855_BPDU_MANG_FR BIT(14) -+#define AN8855_BPDU_BPDU_FR BIT(12) -+#define AN8855_BPDU_EG_TAG GENMASK(11, 9) -+#define AN8855_BPDU_LKY_VLAN BIT(8) -+#define AN8855_BPDU_PRI_HIGH BIT(7) -+#define AN8855_BPDU_MIR GENMASK(4, 3) -+#define AN8855_BPDU_PORT_FW GENMASK(2, 0) -+ -+/* Registers for IP Unknown Multicast Forward control */ -+#define AN8855_UNIPMF 0x102000dc -+ -+enum an8855_bpdu_port_fw { -+ AN8855_BPDU_FOLLOW_MFC = 0, -+ AN8855_BPDU_CPU_EXCLUDE = 4, -+ AN8855_BPDU_CPU_INCLUDE = 5, -+ AN8855_BPDU_CPU_ONLY = 6, -+ AN8855_BPDU_DROP = 7, -+}; -+ -+/* Register for address table control */ -+#define AN8855_ATC 0x10200300 -+#define AN8855_ATC_BUSY BIT(31) -+#define AN8855_ATC_HASH GENMASK(24, 16) -+#define AN8855_ATC_HIT GENMASK(15, 12) -+#define AN8855_ATC_MAT_MASK GENMASK(11, 7) -+#define AN8855_ATC_MAT(x) FIELD_PREP(AN8855_ATC_MAT_MASK, x) -+#define AN8855_ATC_SAT GENMASK(5, 4) -+#define AN8855_ATC_CMD GENMASK(2, 0) -+ -+enum an8855_fdb_mat_cmds { -+ AND8855_FDB_MAT_ALL = 0, -+ AND8855_FDB_MAT_MAC, /* All MAC address */ -+ AND8855_FDB_MAT_DYNAMIC_MAC, /* All Dynamic MAC address */ -+ AND8855_FDB_MAT_STATIC_MAC, /* All Static Mac Address */ -+ AND8855_FDB_MAT_DIP, /* All DIP/GA address */ -+ AND8855_FDB_MAT_DIP_IPV4, /* All DIP/GA IPv4 address */ -+ AND8855_FDB_MAT_DIP_IPV6, /* All DIP/GA IPv6 address */ -+ AND8855_FDB_MAT_DIP_SIP, /* All DIP_SIP address */ -+ AND8855_FDB_MAT_DIP_SIP_IPV4, /* All DIP_SIP IPv4 address */ -+ AND8855_FDB_MAT_DIP_SIP_IPV6, /* All DIP_SIP IPv6 address */ -+ AND8855_FDB_MAT_MAC_CVID, /* All MAC address with CVID */ -+ AND8855_FDB_MAT_MAC_FID, /* All MAC address with Filter ID */ -+ AND8855_FDB_MAT_MAC_PORT, /* All MAC address with port */ -+ AND8855_FDB_MAT_DIP_SIP_DIP_IPV4, /* All DIP_SIP address with DIP_IPV4 */ -+ AND8855_FDB_MAT_DIP_SIP_SIP_IPV4, /* All DIP_SIP address with SIP_IPV4 */ -+ AND8855_FDB_MAT_DIP_SIP_DIP_IPV6, /* All DIP_SIP address with DIP_IPV6 */ -+ AND8855_FDB_MAT_DIP_SIP_SIP_IPV6, /* All DIP_SIP address with SIP_IPV6 */ -+ /* All MAC address with MAC type (dynamic or static) with CVID */ -+ AND8855_FDB_MAT_MAC_TYPE_CVID, -+ /* All MAC address with MAC type (dynamic or static) with Filter ID */ -+ AND8855_FDB_MAT_MAC_TYPE_FID, -+ /* All MAC address with MAC type (dynamic or static) with port */ -+ AND8855_FDB_MAT_MAC_TYPE_PORT, -+}; -+ -+enum an8855_fdb_cmds { -+ AN8855_FDB_READ = 0, -+ AN8855_FDB_WRITE = 1, -+ AN8855_FDB_FLUSH = 2, -+ AN8855_FDB_START = 4, -+ AN8855_FDB_NEXT = 5, -+}; -+ -+/* Registers for address table access */ -+#define AN8855_ATA1 0x10200304 -+#define AN8855_ATA1_MAC0 GENMASK(31, 24) -+#define AN8855_ATA1_MAC1 GENMASK(23, 16) -+#define AN8855_ATA1_MAC2 GENMASK(15, 8) -+#define AN8855_ATA1_MAC3 GENMASK(7, 0) -+#define AN8855_ATA2 0x10200308 -+#define AN8855_ATA2_MAC4 GENMASK(31, 24) -+#define AN8855_ATA2_MAC5 GENMASK(23, 16) -+#define AN8855_ATA2_UNAUTH BIT(10) -+#define AN8855_ATA2_TYPE BIT(9) /* 1: dynamic, 0: static */ -+#define AN8855_ATA2_AGE GENMASK(8, 0) -+ -+/* Register for address table write data */ -+#define AN8855_ATWD 0x10200324 -+#define AN8855_ATWD_FID GENMASK(31, 28) -+#define AN8855_ATWD_VID GENMASK(27, 16) -+#define AN8855_ATWD_IVL BIT(15) -+#define AN8855_ATWD_EG_TAG GENMASK(14, 12) -+#define AN8855_ATWD_SA_MIR GENMASK(9, 8) -+#define AN8855_ATWD_SA_FWD GENMASK(7, 5) -+#define AN8855_ATWD_UPRI GENMASK(4, 2) -+#define AN8855_ATWD_LEAKY BIT(1) -+#define AN8855_ATWD_VLD BIT(0) /* vid LOAD */ -+#define AN8855_ATWD2 0x10200328 -+#define AN8855_ATWD2_PORT GENMASK(7, 0) -+ -+/* Registers for table search read address */ -+#define AN8855_ATRDS 0x10200330 -+#define AN8855_ATRD_SEL GENMASK(1, 0) -+#define AN8855_ATRD0 0x10200334 -+#define AN8855_ATRD0_FID GENMASK(28, 25) -+#define AN8855_ATRD0_VID GENMASK(21, 10) -+#define AN8855_ATRD0_IVL BIT(9) -+#define AN8855_ATRD0_TYPE GENMASK(4, 3) -+#define AN8855_ATRD0_ARP GENMASK(2, 1) -+#define AN8855_ATRD0_LIVE BIT(0) -+#define AN8855_ATRD1 0x10200338 -+#define AN8855_ATRD1_MAC4 GENMASK(31, 24) -+#define AN8855_ATRD1_MAC5 GENMASK(23, 16) -+#define AN8855_ATRD1_AGING GENMASK(11, 3) -+#define AN8855_ATRD2 0x1020033c -+#define AN8855_ATRD2_MAC0 GENMASK(31, 24) -+#define AN8855_ATRD2_MAC1 GENMASK(23, 16) -+#define AN8855_ATRD2_MAC2 GENMASK(15, 8) -+#define AN8855_ATRD2_MAC3 GENMASK(7, 0) -+#define AN8855_ATRD3 0x10200340 -+#define AN8855_ATRD3_PORTMASK GENMASK(7, 0) -+ -+enum an8855_fdb_type { -+ AN8855_MAC_TB_TY_MAC = 0, -+ AN8855_MAC_TB_TY_DIP = 1, -+ AN8855_MAC_TB_TY_DIP_SIP = 2, -+}; -+ -+/* Register for vlan table control */ -+#define AN8855_VTCR 0x10200600 -+#define AN8855_VTCR_BUSY BIT(31) -+#define AN8855_VTCR_FUNC GENMASK(15, 12) -+#define AN8855_VTCR_VID GENMASK(11, 0) -+ -+enum an8855_vlan_cmd { -+ /* Read/Write the specified VID entry from VAWD register based -+ * on VID. -+ */ -+ AN8855_VTCR_RD_VID = 0, -+ AN8855_VTCR_WR_VID = 1, -+}; -+ -+/* Register for setup vlan write data */ -+#define AN8855_VAWD0 0x10200604 -+/* VLAN Member Control */ -+#define AN8855_VA0_PORT GENMASK(31, 26) -+/* Egress Tag Control */ -+#define AN8855_VA0_ETAG GENMASK(23, 12) -+#define AN8855_VA0_ETAG_PORT GENMASK(13, 12) -+#define AN8855_VA0_ETAG_PORT_SHIFT(port) ((port) * 2) -+#define AN8855_VA0_ETAG_PORT_MASK(port) (AN8855_VA0_ETAG_PORT << \ -+ AN8855_VA0_ETAG_PORT_SHIFT(port)) -+#define AN8855_VA0_ETAG_PORT_VAL(port, val) (FIELD_PREP(AN8855_VA0_ETAG_PORT, (val)) << \ -+ AN8855_VA0_ETAG_PORT_SHIFT(port)) -+#define AN8855_VA0_EG_CON BIT(11) -+#define AN8855_VA0_VTAG_EN BIT(10) /* Per VLAN Egress Tag Control */ -+#define AN8855_VA0_IVL_MAC BIT(5) /* Independent VLAN Learning */ -+#define AN8855_VA0_FID GENMASK(4, 1) -+#define AN8855_VA0_VLAN_VALID BIT(0) /* VLAN Entry Valid */ -+#define AN8855_VAWD1 0x10200608 -+#define AN8855_VA1_PORT_STAG BIT(1) -+ -+enum an8855_fid { -+ AN8855_FID_STANDALONE = 0, -+ AN8855_FID_BRIDGED = 1, -+}; -+ -+/* Same register field of VAWD0 */ -+#define AN8855_VARD0 0x10200618 -+ -+enum an8855_vlan_egress_attr { -+ AN8855_VLAN_EGRESS_UNTAG = 0, -+ AN8855_VLAN_EGRESS_TAG = 2, -+ AN8855_VLAN_EGRESS_STACK = 3, -+}; -+ -+/* Register for port STP state control */ -+#define AN8855_SSP_P(x) (0x10208000 + ((x) * 0x200)) -+/* Up to 16 FID supported, each with the same mask */ -+#define AN8855_FID_PST GENMASK(1, 0) -+#define AN8855_FID_PST_SHIFT(fid) (2 * (fid)) -+#define AN8855_FID_PST_MASK(fid) (AN8855_FID_PST << \ -+ AN8855_FID_PST_SHIFT(fid)) -+#define AN8855_FID_PST_VAL(fid, val) (FIELD_PREP(AN8855_FID_PST, (val)) << \ -+ AN8855_FID_PST_SHIFT(fid)) -+ -+enum an8855_stp_state { -+ AN8855_STP_DISABLED = 0, -+ AN8855_STP_BLOCKING = 1, -+ AN8855_STP_LISTENING = AN8855_STP_BLOCKING, -+ AN8855_STP_LEARNING = 2, -+ AN8855_STP_FORWARDING = 3 -+}; -+ -+/* Register for port control */ -+#define AN8855_PCR_P(x) (0x10208004 + ((x) * 0x200)) -+#define AN8855_EG_TAG GENMASK(29, 28) -+#define AN8855_PORT_PRI GENMASK(26, 24) -+#define AN8855_PORT_TX_MIR BIT(20) -+#define AN8855_PORT_RX_MIR BIT(16) -+#define AN8855_PORT_VLAN GENMASK(1, 0) -+ -+enum an8855_port_mode { -+ /* Port Matrix Mode: Frames are forwarded by the PCR_MATRIX members. */ -+ AN8855_PORT_MATRIX_MODE = 0, -+ -+ /* Fallback Mode: Forward received frames with ingress ports that do -+ * not belong to the VLAN member. Frames whose VID is not listed on -+ * the VLAN table are forwarded by the PCR_MATRIX members. -+ */ -+ AN8855_PORT_FALLBACK_MODE = 1, -+ -+ /* Check Mode: Forward received frames whose ingress do not -+ * belong to the VLAN member. Discard frames if VID ismiddes on the -+ * VLAN table. -+ */ -+ AN8855_PORT_CHECK_MODE = 2, -+ -+ /* Security Mode: Discard any frame due to ingress membership -+ * violation or VID missed on the VLAN table. -+ */ -+ AN8855_PORT_SECURITY_MODE = 3, -+}; -+ -+/* Register for port security control */ -+#define AN8855_PSC_P(x) (0x1020800c + ((x) * 0x200)) -+#define AN8855_SA_DIS BIT(4) -+ -+/* Register for port vlan control */ -+#define AN8855_PVC_P(x) (0x10208010 + ((x) * 0x200)) -+#define AN8855_PORT_SPEC_REPLACE_MODE BIT(11) -+#define AN8855_PVC_EG_TAG GENMASK(10, 8) -+#define AN8855_VLAN_ATTR GENMASK(7, 6) -+#define AN8855_PORT_SPEC_TAG BIT(5) -+#define AN8855_ACC_FRM GENMASK(1, 0) -+ -+enum an8855_vlan_port_eg_tag { -+ AN8855_VLAN_EG_DISABLED = 0, -+ AN8855_VLAN_EG_CONSISTENT = 1, -+ AN8855_VLAN_EG_UNTAGGED = 4, -+ AN8855_VLAN_EG_SWAP = 5, -+ AN8855_VLAN_EG_TAGGED = 6, -+ AN8855_VLAN_EG_STACK = 7, -+}; -+ -+enum an8855_vlan_port_attr { -+ AN8855_VLAN_USER = 0, -+ AN8855_VLAN_STACK = 1, -+ AN8855_VLAN_TRANSPARENT = 3, -+}; -+ -+enum an8855_vlan_port_acc_frm { -+ AN8855_VLAN_ACC_ALL = 0, -+ AN8855_VLAN_ACC_TAGGED = 1, -+ AN8855_VLAN_ACC_UNTAGGED = 2, -+}; -+ -+#define AN8855_PPBV1_P(x) (0x10208014 + ((x) * 0x200)) -+#define AN8855_PPBV_G0_PORT_VID GENMASK(11, 0) -+ -+#define AN8855_PORTMATRIX_P(x) (0x10208044 + ((x) * 0x200)) -+#define AN8855_PORTMATRIX GENMASK(5, 0) -+/* Port matrix without the CPU port that should never be removed */ -+#define AN8855_USER_PORTMATRIX GENMASK(4, 0) -+ -+/* Register for port PVID */ -+#define AN8855_PVID_P(x) (0x10208048 + ((x) * 0x200)) -+#define AN8855_G0_PORT_VID GENMASK(11, 0) -+ -+/* Register for port MAC control register */ -+#define AN8855_PMCR_P(x) (0x10210000 + ((x) * 0x200)) -+#define AN8855_PMCR_FORCE_MODE BIT(31) -+#define AN8855_PMCR_FORCE_SPEED GENMASK(30, 28) -+#define AN8855_PMCR_FORCE_SPEED_5000 FIELD_PREP_CONST(AN8855_PMCR_FORCE_SPEED, 0x4) -+#define AN8855_PMCR_FORCE_SPEED_2500 FIELD_PREP_CONST(AN8855_PMCR_FORCE_SPEED, 0x3) -+#define AN8855_PMCR_FORCE_SPEED_1000 FIELD_PREP_CONST(AN8855_PMCR_FORCE_SPEED, 0x2) -+#define AN8855_PMCR_FORCE_SPEED_100 FIELD_PREP_CONST(AN8855_PMCR_FORCE_SPEED, 0x1) -+#define AN8855_PMCR_FORCE_SPEED_10 FIELD_PREP_CONST(AN8855_PMCR_FORCE_SPEED, 0x1) -+#define AN8855_PMCR_FORCE_FDX BIT(25) -+#define AN8855_PMCR_FORCE_LNK BIT(24) -+#define AN8855_PMCR_IFG_XMIT GENMASK(21, 20) -+#define AN8855_PMCR_EXT_PHY BIT(19) -+#define AN8855_PMCR_MAC_MODE BIT(18) -+#define AN8855_PMCR_TX_EN BIT(16) -+#define AN8855_PMCR_RX_EN BIT(15) -+#define AN8855_PMCR_BACKOFF_EN BIT(12) -+#define AN8855_PMCR_BACKPR_EN BIT(11) -+#define AN8855_PMCR_FORCE_EEE5G BIT(9) -+#define AN8855_PMCR_FORCE_EEE2P5G BIT(8) -+#define AN8855_PMCR_FORCE_EEE1G BIT(7) -+#define AN8855_PMCR_FORCE_EEE100 BIT(6) -+#define AN8855_PMCR_TX_FC_EN BIT(5) -+#define AN8855_PMCR_RX_FC_EN BIT(4) -+ -+#define AN8855_PMSR_P(x) (0x10210010 + (x) * 0x200) -+#define AN8855_PMSR_SPEED GENMASK(30, 28) -+#define AN8855_PMSR_SPEED_5000 FIELD_PREP_CONST(AN8855_PMSR_SPEED, 0x4) -+#define AN8855_PMSR_SPEED_2500 FIELD_PREP_CONST(AN8855_PMSR_SPEED, 0x3) -+#define AN8855_PMSR_SPEED_1000 FIELD_PREP_CONST(AN8855_PMSR_SPEED, 0x2) -+#define AN8855_PMSR_SPEED_100 FIELD_PREP_CONST(AN8855_PMSR_SPEED, 0x1) -+#define AN8855_PMSR_SPEED_10 FIELD_PREP_CONST(AN8855_PMSR_SPEED, 0x0) -+#define AN8855_PMSR_DPX BIT(25) -+#define AN8855_PMSR_LNK BIT(24) -+#define AN8855_PMSR_EEE1G BIT(7) -+#define AN8855_PMSR_EEE100M BIT(6) -+#define AN8855_PMSR_RX_FC BIT(5) -+#define AN8855_PMSR_TX_FC BIT(4) -+ -+#define AN8855_PMEEECR_P(x) (0x10210004 + (x) * 0x200) -+#define AN8855_LPI_MODE_EN BIT(31) -+#define AN8855_WAKEUP_TIME_2500 GENMASK(23, 16) -+#define AN8855_WAKEUP_TIME_1000 GENMASK(15, 8) -+#define AN8855_WAKEUP_TIME_100 GENMASK(7, 0) -+#define AN8855_PMEEECR2_P(x) (0x10210008 + (x) * 0x200) -+#define AN8855_WAKEUP_TIME_5000 GENMASK(7, 0) -+ -+#define AN8855_GMACCR 0x10213e00 -+#define AN8855_MAX_RX_JUMBO GENMASK(7, 4) -+/* 2K for 0x0, 0x1, 0x2 */ -+#define AN8855_MAX_RX_JUMBO_2K FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x0) -+#define AN8855_MAX_RX_JUMBO_3K FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x3) -+#define AN8855_MAX_RX_JUMBO_4K FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x4) -+#define AN8855_MAX_RX_JUMBO_5K FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x5) -+#define AN8855_MAX_RX_JUMBO_6K FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x6) -+#define AN8855_MAX_RX_JUMBO_7K FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x7) -+#define AN8855_MAX_RX_JUMBO_8K FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x8) -+#define AN8855_MAX_RX_JUMBO_9K FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x9) -+#define AN8855_MAX_RX_JUMBO_12K FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0xa) -+#define AN8855_MAX_RX_JUMBO_15K FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0xb) -+#define AN8855_MAX_RX_JUMBO_16K FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0xc) -+#define AN8855_MAX_RX_PKT_LEN GENMASK(1, 0) -+#define AN8855_MAX_RX_PKT_1518_1522 FIELD_PREP_CONST(AN8855_MAX_RX_PKT_LEN, 0x0) -+#define AN8855_MAX_RX_PKT_1536 FIELD_PREP_CONST(AN8855_MAX_RX_PKT_LEN, 0x1) -+#define AN8855_MAX_RX_PKT_1552 FIELD_PREP_CONST(AN8855_MAX_RX_PKT_LEN, 0x2) -+#define AN8855_MAX_RX_PKT_JUMBO FIELD_PREP_CONST(AN8855_MAX_RX_PKT_LEN, 0x3) -+ -+#define AN8855_CKGCR 0x10213e1c -+#define AN8855_LPI_TXIDLE_THD_MASK GENMASK(31, 14) -+#define AN8855_CKG_LNKDN_PORT_STOP BIT(1) -+#define AN8855_CKG_LNKDN_GLB_STOP BIT(0) -+ -+/* Register for MIB */ -+#define AN8855_PORT_MIB_COUNTER(x) (0x10214000 + (x) * 0x200) -+/* Each define is an offset of AN8855_PORT_MIB_COUNTER */ -+#define AN8855_PORT_MIB_TX_DROP 0x00 -+#define AN8855_PORT_MIB_TX_CRC_ERR 0x04 -+#define AN8855_PORT_MIB_TX_UNICAST 0x08 -+#define AN8855_PORT_MIB_TX_MULTICAST 0x0c -+#define AN8855_PORT_MIB_TX_BROADCAST 0x10 -+#define AN8855_PORT_MIB_TX_COLLISION 0x14 -+#define AN8855_PORT_MIB_TX_SINGLE_COLLISION 0x18 -+#define AN8855_PORT_MIB_TX_MULTIPLE_COLLISION 0x1c -+#define AN8855_PORT_MIB_TX_DEFERRED 0x20 -+#define AN8855_PORT_MIB_TX_LATE_COLLISION 0x24 -+#define AN8855_PORT_MIB_TX_EXCESSIVE_COLLISION 0x28 -+#define AN8855_PORT_MIB_TX_PAUSE 0x2c -+#define AN8855_PORT_MIB_TX_PKT_SZ_64 0x30 -+#define AN8855_PORT_MIB_TX_PKT_SZ_65_TO_127 0x34 -+#define AN8855_PORT_MIB_TX_PKT_SZ_128_TO_255 0x38 -+#define AN8855_PORT_MIB_TX_PKT_SZ_256_TO_511 0x3 -+#define AN8855_PORT_MIB_TX_PKT_SZ_512_TO_1023 0x40 -+#define AN8855_PORT_MIB_TX_PKT_SZ_1024_TO_1518 0x44 -+#define AN8855_PORT_MIB_TX_PKT_SZ_1519_TO_MAX 0x48 -+#define AN8855_PORT_MIB_TX_BYTES 0x4c /* 64 bytes */ -+#define AN8855_PORT_MIB_TX_OVERSIZE_DROP 0x54 -+#define AN8855_PORT_MIB_TX_BAD_PKT_BYTES 0x58 /* 64 bytes */ -+#define AN8855_PORT_MIB_RX_DROP 0x80 -+#define AN8855_PORT_MIB_RX_FILTERING 0x84 -+#define AN8855_PORT_MIB_RX_UNICAST 0x88 -+#define AN8855_PORT_MIB_RX_MULTICAST 0x8c -+#define AN8855_PORT_MIB_RX_BROADCAST 0x90 -+#define AN8855_PORT_MIB_RX_ALIGN_ERR 0x94 -+#define AN8855_PORT_MIB_RX_CRC_ERR 0x98 -+#define AN8855_PORT_MIB_RX_UNDER_SIZE_ERR 0x9c -+#define AN8855_PORT_MIB_RX_FRAG_ERR 0xa0 -+#define AN8855_PORT_MIB_RX_OVER_SZ_ERR 0xa4 -+#define AN8855_PORT_MIB_RX_JABBER_ERR 0xa8 -+#define AN8855_PORT_MIB_RX_PAUSE 0xac -+#define AN8855_PORT_MIB_RX_PKT_SZ_64 0xb0 -+#define AN8855_PORT_MIB_RX_PKT_SZ_65_TO_127 0xb4 -+#define AN8855_PORT_MIB_RX_PKT_SZ_128_TO_255 0xb8 -+#define AN8855_PORT_MIB_RX_PKT_SZ_256_TO_511 0xbc -+#define AN8855_PORT_MIB_RX_PKT_SZ_512_TO_1023 0xc0 -+#define AN8855_PORT_MIB_RX_PKT_SZ_1024_TO_1518 0xc4 -+#define AN8855_PORT_MIB_RX_PKT_SZ_1519_TO_MAX 0xc8 -+#define AN8855_PORT_MIB_RX_BYTES 0xcc /* 64 bytes */ -+#define AN8855_PORT_MIB_RX_CTRL_DROP 0xd4 -+#define AN8855_PORT_MIB_RX_INGRESS_DROP 0xd8 -+#define AN8855_PORT_MIB_RX_ARL_DROP 0xdc -+#define AN8855_PORT_MIB_FLOW_CONTROL_DROP 0xe0 -+#define AN8855_PORT_MIB_WRED_DROP 0xe4 -+#define AN8855_PORT_MIB_MIRROR_DROP 0xe8 -+#define AN8855_PORT_MIB_RX_BAD_PKT_BYTES 0xec /* 64 bytes */ -+#define AN8855_PORT_MIB_RXS_FLOW_SAMPLING_PKT_DROP 0xf4 -+#define AN8855_PORT_MIB_RXS_FLOW_TOTAL_PKT_DROP 0xf8 -+#define AN8855_PORT_MIB_PORT_CONTROL_DROP 0xfc -+#define AN8855_MIB_CCR 0x10213e30 -+#define AN8855_CCR_MIB_ENABLE BIT(31) -+#define AN8855_CCR_RX_OCT_CNT_GOOD BIT(7) -+#define AN8855_CCR_RX_OCT_CNT_BAD BIT(6) -+#define AN8855_CCR_TX_OCT_CNT_GOOD BIT(5) -+#define AN8855_CCR_TX_OCT_CNT_BAD BIT(4) -+#define AN8855_CCR_RX_OCT_CNT_GOOD_2 BIT(3) -+#define AN8855_CCR_RX_OCT_CNT_BAD_2 BIT(2) -+#define AN8855_CCR_TX_OCT_CNT_GOOD_2 BIT(1) -+#define AN8855_CCR_TX_OCT_CNT_BAD_2 BIT(0) -+#define AN8855_CCR_MIB_ACTIVATE (AN8855_CCR_MIB_ENABLE | \ -+ AN8855_CCR_RX_OCT_CNT_GOOD | \ -+ AN8855_CCR_RX_OCT_CNT_BAD | \ -+ AN8855_CCR_TX_OCT_CNT_GOOD | \ -+ AN8855_CCR_TX_OCT_CNT_BAD | \ -+ AN8855_CCR_RX_OCT_CNT_BAD_2 | \ -+ AN8855_CCR_TX_OCT_CNT_BAD_2) -+#define AN8855_MIB_CLR 0x10213e34 -+#define AN8855_MIB_PORT6_CLR BIT(6) -+#define AN8855_MIB_PORT5_CLR BIT(5) -+#define AN8855_MIB_PORT4_CLR BIT(4) -+#define AN8855_MIB_PORT3_CLR BIT(3) -+#define AN8855_MIB_PORT2_CLR BIT(2) -+#define AN8855_MIB_PORT1_CLR BIT(1) -+#define AN8855_MIB_PORT0_CLR BIT(0) -+ -+/* HSGMII/SGMII Configuration register */ -+/* AN8855_HSGMII_AN_CSR_BASE 0x10220000 */ -+#define AN8855_SGMII_REG_AN0 0x10220000 -+/* AN8855_SGMII_AN_ENABLE BMCR_ANENABLE */ -+/* AN8855_SGMII_AN_RESTART BMCR_ANRESTART */ -+#define AN8855_SGMII_REG_AN_13 0x10220034 -+#define AN8855_SGMII_REMOTE_FAULT_DIS BIT(8) -+#define AN8855_SGMII_IF_MODE GENMASK(5, 0) -+#define AN8855_SGMII_REG_AN_FORCE_CL37 0x10220060 -+#define AN8855_RG_FORCE_AN_DONE BIT(0) -+ -+/* AN8855_HSGMII_CSR_PCS_BASE 0x10220000 */ -+#define AN8855_RG_HSGMII_PCS_CTROL_1 0x10220a00 -+#define AN8855_RG_TBI_10B_MODE BIT(30) -+#define AN8855_RG_AN_SGMII_MODE_FORCE 0x10220a24 -+#define AN8855_RG_FORCE_CUR_SGMII_MODE GENMASK(5, 4) -+#define AN8855_RG_FORCE_CUR_SGMII_SEL BIT(0) -+ -+/* AN8855_MULTI_SGMII_CSR_BASE 0x10224000 */ -+#define AN8855_SGMII_STS_CTRL_0 0x10224018 -+#define AN8855_RG_LINK_MODE_P0 GENMASK(5, 4) -+#define AN8855_RG_LINK_MODE_P0_SPEED_2500 FIELD_PREP_CONST(AN8855_RG_LINK_MODE_P0, 0x3) -+#define AN8855_RG_LINK_MODE_P0_SPEED_1000 FIELD_PREP_CONST(AN8855_RG_LINK_MODE_P0, 0x2) -+#define AN8855_RG_LINK_MODE_P0_SPEED_100 FIELD_PREP_CONST(AN8855_RG_LINK_MODE_P0, 0x1) -+#define AN8855_RG_LINK_MODE_P0_SPEED_10 FIELD_PREP_CONST(AN8855_RG_LINK_MODE_P0, 0x0) -+#define AN8855_RG_FORCE_SPD_MODE_P0 BIT(2) -+#define AN8855_MSG_RX_CTRL_0 0x10224100 -+#define AN8855_MSG_RX_LIK_STS_0 0x10224514 -+#define AN8855_RG_DPX_STS_P3 BIT(24) -+#define AN8855_RG_DPX_STS_P2 BIT(16) -+#define AN8855_RG_EEE1G_STS_P1 BIT(12) -+#define AN8855_RG_DPX_STS_P1 BIT(8) -+#define AN8855_RG_TXFC_STS_P0 BIT(2) -+#define AN8855_RG_RXFC_STS_P0 BIT(1) -+#define AN8855_RG_DPX_STS_P0 BIT(0) -+#define AN8855_MSG_RX_LIK_STS_2 0x1022451c -+#define AN8855_RG_RXFC_AN_BYPASS_P3 BIT(11) -+#define AN8855_RG_RXFC_AN_BYPASS_P2 BIT(10) -+#define AN8855_RG_RXFC_AN_BYPASS_P1 BIT(9) -+#define AN8855_RG_TXFC_AN_BYPASS_P3 BIT(7) -+#define AN8855_RG_TXFC_AN_BYPASS_P2 BIT(6) -+#define AN8855_RG_TXFC_AN_BYPASS_P1 BIT(5) -+#define AN8855_RG_DPX_AN_BYPASS_P3 BIT(3) -+#define AN8855_RG_DPX_AN_BYPASS_P2 BIT(2) -+#define AN8855_RG_DPX_AN_BYPASS_P1 BIT(1) -+#define AN8855_RG_DPX_AN_BYPASS_P0 BIT(0) -+#define AN8855_PHY_RX_FORCE_CTRL_0 0x10224520 -+#define AN8855_RG_FORCE_TXC_SEL BIT(4) -+ -+/* AN8855_XFI_CSR_PCS_BASE 0x10225000 */ -+#define AN8855_RG_USXGMII_AN_CONTROL_0 0x10225bf8 -+ -+/* AN8855_MULTI_PHY_RA_CSR_BASE 0x10226000 */ -+#define AN8855_RG_RATE_ADAPT_CTRL_0 0x10226000 -+#define AN8855_RG_RATE_ADAPT_RX_BYPASS BIT(27) -+#define AN8855_RG_RATE_ADAPT_TX_BYPASS BIT(26) -+#define AN8855_RG_RATE_ADAPT_RX_EN BIT(4) -+#define AN8855_RG_RATE_ADAPT_TX_EN BIT(0) -+#define AN8855_RATE_ADP_P0_CTRL_0 0x10226100 -+#define AN8855_RG_P0_DIS_MII_MODE BIT(31) -+#define AN8855_RG_P0_MII_MODE BIT(28) -+#define AN8855_RG_P0_MII_RA_RX_EN BIT(3) -+#define AN8855_RG_P0_MII_RA_TX_EN BIT(2) -+#define AN8855_RG_P0_MII_RA_RX_MODE BIT(1) -+#define AN8855_RG_P0_MII_RA_TX_MODE BIT(0) -+#define AN8855_MII_RA_AN_ENABLE 0x10226300 -+#define AN8855_RG_P0_RA_AN_EN BIT(0) -+ -+/* AN8855_QP_DIG_CSR_BASE 0x1022a000 */ -+#define AN8855_QP_CK_RST_CTRL_4 0x1022a310 -+#define AN8855_QP_DIG_MODE_CTRL_0 0x1022a324 -+#define AN8855_RG_SGMII_MODE GENMASK(5, 4) -+#define AN8855_RG_SGMII_AN_EN BIT(0) -+#define AN8855_QP_DIG_MODE_CTRL_1 0x1022a330 -+#define AN8855_RG_TPHY_SPEED GENMASK(3, 2) -+ -+/* AN8855_SERDES_WRAPPER_BASE 0x1022c000 */ -+#define AN8855_USGMII_CTRL_0 0x1022c000 -+ -+/* AN8855_QP_PMA_TOP_BASE 0x1022e000 */ -+#define AN8855_PON_RXFEDIG_CTRL_0 0x1022e100 -+#define AN8855_RG_QP_EQ_RX500M_CK_SEL BIT(12) -+#define AN8855_PON_RXFEDIG_CTRL_9 0x1022e124 -+#define AN8855_RG_QP_EQ_LEQOSC_DLYCNT GENMASK(2, 0) -+ -+#define AN8855_SS_LCPLL_PWCTL_SETTING_2 0x1022e208 -+#define AN8855_RG_NCPO_ANA_MSB GENMASK(17, 16) -+#define AN8855_SS_LCPLL_TDC_FLT_2 0x1022e230 -+#define AN8855_RG_LCPLL_NCPO_VALUE GENMASK(30, 0) -+#define AN8855_SS_LCPLL_TDC_FLT_5 0x1022e23c -+#define AN8855_RG_LCPLL_NCPO_CHG BIT(24) -+#define AN8855_SS_LCPLL_TDC_PCW_1 0x1022e248 -+#define AN8855_RG_LCPLL_PON_HRDDS_PCW_NCPO_GPON GENMASK(30, 0) -+#define AN8855_INTF_CTRL_8 0x1022e320 -+#define AN8855_INTF_CTRL_9 0x1022e324 -+#define AN8855_INTF_CTRL_10 0x1022e328 -+#define AN8855_RG_DA_QP_TX_FIR_C2_SEL BIT(29) -+#define AN8855_RG_DA_QP_TX_FIR_C2_FORCE GENMASK(28, 24) -+#define AN8855_RG_DA_QP_TX_FIR_C1_SEL BIT(21) -+#define AN8855_RG_DA_QP_TX_FIR_C1_FORCE GENMASK(20, 16) -+#define AN8855_INTF_CTRL_11 0x1022e32c -+#define AN8855_RG_DA_QP_TX_FIR_C0B_SEL BIT(6) -+#define AN8855_RG_DA_QP_TX_FIR_C0B_FORCE GENMASK(5, 0) -+#define AN8855_PLL_CTRL_0 0x1022e400 -+#define AN8855_RG_PHYA_AUTO_INIT BIT(0) -+#define AN8855_PLL_CTRL_2 0x1022e408 -+#define AN8855_RG_DA_QP_PLL_SDM_IFM_INTF BIT(30) -+#define AN8855_RG_DA_QP_PLL_RICO_SEL_INTF BIT(29) -+#define AN8855_RG_DA_QP_PLL_POSTDIV_EN_INTF BIT(28) -+#define AN8855_RG_DA_QP_PLL_PHY_CK_EN_INTF BIT(27) -+#define AN8855_RG_DA_QP_PLL_PFD_OFFSET_EN_INTRF BIT(26) -+#define AN8855_RG_DA_QP_PLL_PFD_OFFSET_INTF GENMASK(25, 24) -+#define AN8855_RG_DA_QP_PLL_PCK_SEL_INTF BIT(22) -+#define AN8855_RG_DA_QP_PLL_KBAND_PREDIV_INTF GENMASK(21, 20) -+#define AN8855_RG_DA_QP_PLL_IR_INTF GENMASK(19, 16) -+#define AN8855_RG_DA_QP_PLL_ICOIQ_EN_INTF BIT(14) -+#define AN8855_RG_DA_QP_PLL_FBKSEL_INTF GENMASK(13, 12) -+#define AN8855_RG_DA_QP_PLL_BR_INTF GENMASK(10, 8) -+#define AN8855_RG_DA_QP_PLL_BPD_INTF GENMASK(7, 6) -+#define AN8855_RG_DA_QP_PLL_BPA_INTF GENMASK(4, 2) -+#define AN8855_RG_DA_QP_PLL_BC_INTF GENMASK(1, 0) -+#define AN8855_PLL_CTRL_3 0x1022e40c -+#define AN8855_RG_DA_QP_PLL_SSC_PERIOD_INTF GENMASK(31, 16) -+#define AN8855_RG_DA_QP_PLL_SSC_DELTA_INTF GENMASK(15, 0) -+#define AN8855_PLL_CTRL_4 0x1022e410 -+#define AN8855_RG_DA_QP_PLL_SDM_HREN_INTF GENMASK(4, 3) -+#define AN8855_RG_DA_QP_PLL_ICOLP_EN_INTF BIT(2) -+#define AN8855_RG_DA_QP_PLL_SSC_DIR_DLY_INTF GENMASK(1, 0) -+#define AN8855_PLL_CK_CTRL_0 0x1022e414 -+#define AN8855_RG_DA_QP_PLL_TDC_TXCK_SEL_INTF BIT(9) -+#define AN8855_RG_DA_QP_PLL_SDM_DI_EN_INTF BIT(8) -+#define AN8855_RX_DLY_0 0x1022e614 -+#define AN8855_RG_QP_RX_SAOSC_EN_H_DLY GENMASK(13, 8) -+#define AN8855_RG_QP_RX_PI_CAL_EN_H_DLY GENMASK(7, 0) -+#define AN8855_RX_CTRL_2 0x1022e630 -+#define AN8855_RG_QP_RX_EQ_EN_H_DLY GENMASK(28, 16) -+#define AN8855_RX_CTRL_5 0x1022e63c -+#define AN8855_RG_FREDET_CHK_CYCLE GENMASK(29, 10) -+#define AN8855_RX_CTRL_6 0x1022e640 -+#define AN8855_RG_FREDET_GOLDEN_CYCLE GENMASK(19, 0) -+#define AN8855_RX_CTRL_7 0x1022e644 -+#define AN8855_RG_FREDET_TOLERATE_CYCLE GENMASK(19, 0) -+#define AN8855_RX_CTRL_8 0x1022e648 -+#define AN8855_RG_DA_QP_SAOSC_DONE_TIME GENMASK(27, 16) -+#define AN8855_RG_DA_QP_LEQOS_EN_TIME GENMASK(14, 0) -+#define AN8855_RX_CTRL_26 0x1022e690 -+#define AN8855_RG_QP_EQ_RETRAIN_ONLY_EN BIT(26) -+#define AN8855_RG_LINK_NE_EN BIT(24) -+#define AN8855_RG_LINK_ERRO_EN BIT(23) -+#define AN8855_RX_CTRL_42 0x1022e6d0 -+#define AN8855_RG_QP_EQ_EN_DLY GENMASK(12, 0) -+ -+/* AN8855_QP_ANA_CSR_BASE 0x1022f000 */ -+#define AN8855_RG_QP_RX_DAC_EN 0x1022f000 -+#define AN8855_RG_QP_SIGDET_HF GENMASK(17, 16) -+#define AN8855_RG_QP_RXAFE_RESERVE 0x1022f004 -+#define AN8855_RG_QP_CDR_PD_10B_EN BIT(11) -+#define AN8855_RG_QP_CDR_LPF_BOT_LIM 0x1022f008 -+#define AN8855_RG_QP_CDR_LPF_KP_GAIN GENMASK(26, 24) -+#define AN8855_RG_QP_CDR_LPF_KI_GAIN GENMASK(22, 20) -+#define AN8855_RG_QP_CDR_LPF_MJV_LIM 0x1022f00c -+#define AN8855_RG_QP_CDR_LPF_RATIO GENMASK(5, 4) -+#define AN8855_RG_QP_CDR_LPF_SETVALUE 0x1022f014 -+#define AN8855_RG_QP_CDR_PR_BUF_IN_SR GENMASK(31, 29) -+#define AN8855_RG_QP_CDR_PR_BETA_SEL GENMASK(28, 25) -+#define AN8855_RG_QP_CDR_PR_CKREF_DIV1 0x1022f018 -+#define AN8855_RG_QP_CDR_PR_KBAND_DIV GENMASK(26, 24) -+#define AN8855_RG_QP_CDR_PR_DAC_BAND GENMASK(12, 8) -+#define AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE 0x1022f01c -+#define AN8855_RG_QP_CDR_PR_XFICK_EN BIT(30) -+#define AN8855_RG_QP_CDR_PR_KBAND_PCIE_MODE BIT(6) -+#define AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE_MASK GENMASK(5, 0) -+#define AN8855_RG_QP_CDR_FORCE_IBANDLPF_R_OFF 0x1022f020 -+#define AN8855_RG_QP_CDR_PHYCK_SEL GENMASK(17, 16) -+#define AN8855_RG_QP_CDR_PHYCK_RSTB BIT(13) -+#define AN8855_RG_QP_CDR_PHYCK_DIV GENMASK(12, 6) -+#define AN8855_RG_QP_TX_MODE 0x1022f028 -+#define AN8855_RG_QP_TX_RESERVE GENMASK(31, 16) -+#define AN8855_RG_QP_TX_MODE_16B_EN BIT(0) -+#define AN8855_RG_QP_PLL_IPLL_DIG_PWR_SEL 0x1022f03c -+#define AN8855_RG_QP_PLL_SDM_ORD 0x1022f040 -+#define AN8855_RG_QP_PLL_SSC_PHASE_INI BIT(4) -+#define AN8855_RG_QP_PLL_SSC_TRI_EN BIT(3) -+ -+/* AN8855_ETHER_SYS_BASE 0x1028c800 */ -+#define AN8855_RG_GPHY_AFE_PWD 0x1028c840 -+#define AN8855_RG_GPHY_SMI_ADDR 0x1028c848 -+ -+#define MIB_DESC(_s, _o, _n) \ -+ { \ -+ .size = (_s), \ -+ .offset = (_o), \ -+ .name = (_n), \ -+ } -+ -+struct an8855_mib_desc { -+ unsigned int size; -+ unsigned int offset; -+ const char *name; -+}; -+ -+struct an8855_fdb { -+ u16 vid; -+ u8 port_mask; -+ u16 aging; -+ u8 mac[6]; -+ bool noarp; -+ u8 live; -+ u8 type; -+ u8 fid; -+ u8 ivl; -+}; -+ -+struct an8855_priv { -+ struct device *dev; -+ struct dsa_switch *ds; -+ struct regmap *regmap; -+ struct gpio_desc *reset_gpio; -+ /* Protect ATU or VLAN table access */ -+ struct mutex reg_mutex; -+ -+ struct phylink_pcs pcs; -+ -+ u8 mirror_rx; -+ u8 mirror_tx; -+ u8 port_isolated_map; -+ -+ bool phy_require_calib; -+}; -+ -+#endif /* __AN8855_H */ -diff --git a/drivers/net/mdio/mdio-an8855.c b/drivers/net/mdio/mdio-an8855.c -new file mode 100644 -index 000000000000..5feba72c021b ---- /dev/null -+++ b/drivers/net/mdio/mdio-an8855.c -@@ -0,0 +1,113 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * MDIO passthrough driver for Airoha AN8855 Switch -+ */ -+ -+#include -+#include -+#include -+#include -+ -+static int an855_phy_restore_page(struct an8855_mfd_priv *priv, -+ int phy) __must_hold(&priv->bus->mdio_lock) -+{ -+ /* Check PHY page only for addr shared with switch */ -+ if (phy != priv->switch_addr) -+ return 0; -+ -+ /* Don't restore page if it's not set to switch page */ -+ if (priv->current_page != FIELD_GET(AN8855_PHY_PAGE, -+ AN8855_PHY_PAGE_EXTENDED_4)) -+ return 0; -+ -+ /* Restore page to 0, PHY might change page right after but that -+ * will be ignored as it won't be a switch page. -+ */ -+ return an8855_mii_set_page(priv, phy, AN8855_PHY_PAGE_STANDARD); -+} -+ -+static int an8855_phy_read(struct mii_bus *bus, int phy, int regnum) -+{ -+ struct an8855_mfd_priv *priv = bus->priv; -+ struct mii_bus *real_bus = priv->bus; -+ int ret; -+ -+ mutex_lock_nested(&real_bus->mdio_lock, MDIO_MUTEX_NESTED); -+ -+ ret = an855_phy_restore_page(priv, phy); -+ if (ret) -+ goto exit; -+ -+ ret = __mdiobus_read(real_bus, phy, regnum); -+exit: -+ mutex_unlock(&real_bus->mdio_lock); -+ -+ return ret; -+} -+ -+static int an8855_phy_write(struct mii_bus *bus, int phy, int regnum, u16 val) -+{ -+ struct an8855_mfd_priv *priv = bus->priv; -+ struct mii_bus *real_bus = priv->bus; -+ int ret; -+ -+ mutex_lock_nested(&real_bus->mdio_lock, MDIO_MUTEX_NESTED); -+ -+ ret = an855_phy_restore_page(priv, phy); -+ if (ret) -+ goto exit; -+ -+ ret = __mdiobus_write(real_bus, phy, regnum, val); -+exit: -+ mutex_unlock(&real_bus->mdio_lock); -+ -+ return ret; -+} -+ -+static int an8855_mdio_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct an8855_mfd_priv *priv; -+ struct mii_bus *bus; -+ int ret; -+ -+ /* Get priv of MFD */ -+ priv = dev_get_drvdata(dev->parent); -+ -+ bus = devm_mdiobus_alloc(dev); -+ if (!bus) -+ return -ENOMEM; -+ -+ bus->priv = priv; -+ bus->name = KBUILD_MODNAME "-mii"; -+ snprintf(bus->id, MII_BUS_ID_SIZE, KBUILD_MODNAME "-%d", -+ priv->switch_addr); -+ bus->parent = dev; -+ bus->read = an8855_phy_read; -+ bus->write = an8855_phy_write; -+ -+ ret = devm_of_mdiobus_register(dev, bus, dev->of_node); -+ if (ret) -+ return dev_err_probe(dev, ret, "failed to register MDIO bus\n"); -+ -+ return ret; -+} -+ -+static const struct of_device_id an8855_mdio_of_match[] = { -+ { .compatible = "airoha,an8855-mdio", }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, an8855_mdio_of_match); -+ -+static struct platform_driver an8855_mdio_driver = { -+ .probe = an8855_mdio_probe, -+ .driver = { -+ .name = "an8855-mdio", -+ .of_match_table = an8855_mdio_of_match, -+ }, -+}; -+module_platform_driver(an8855_mdio_driver); -+ -+MODULE_AUTHOR("Christian Marangi "); -+MODULE_DESCRIPTION("Driver for AN8855 MDIO passthrough"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/net/phy/adm6996.c b/drivers/net/phy/adm6996.c -new file mode 100644 -index 000000000000..d917427419ad ---- /dev/null -+++ b/drivers/net/phy/adm6996.c -@@ -0,0 +1,1241 @@ -+/* -+ * ADM6996 switch driver -+ * -+ * swconfig interface based on ar8216.c -+ * -+ * Copyright (c) 2008 Felix Fietkau -+ * VLAN support Copyright (c) 2010, 2011 Peter Lebbing -+ * Copyright (c) 2013 Hauke Mehrtens -+ * Copyright (c) 2014 Matti Laakso -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License v2 as published by the -+ * Free Software Foundation -+ */ -+ -+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -+ -+/*#define DEBUG 1*/ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include "adm6996.h" -+ -+MODULE_DESCRIPTION("Infineon ADM6996 Switch"); -+MODULE_AUTHOR("Felix Fietkau, Peter Lebbing "); -+MODULE_LICENSE("GPL"); -+ -+static const char * const adm6996_model_name[] = -+{ -+ NULL, -+ "ADM6996FC", -+ "ADM6996M", -+ "ADM6996L" -+}; -+ -+struct adm6996_mib_desc { -+ unsigned int offset; -+ const char *name; -+}; -+ -+struct adm6996_priv { -+ struct switch_dev dev; -+ void *priv; -+ -+ u8 eecs; -+ u8 eesk; -+ u8 eedi; -+ -+ enum adm6996_model model; -+ -+ bool enable_vlan; -+ bool vlan_enabled; /* Current hardware state */ -+ -+#ifdef DEBUG -+ u16 addr; /* Debugging: register address to operate on */ -+#endif -+ -+ u16 pvid[ADM_NUM_PORTS]; /* Primary VLAN ID */ -+ u8 tagged_ports; -+ -+ u16 vlan_id[ADM_NUM_VLANS]; -+ u8 vlan_table[ADM_NUM_VLANS]; /* bitmap, 1 = port is member */ -+ u8 vlan_tagged[ADM_NUM_VLANS]; /* bitmap, 1 = tagged member */ -+ -+ struct mutex mib_lock; -+ char buf[2048]; -+ -+ struct mutex reg_mutex; -+ -+ /* use abstraction for regops, we want to add gpio support in the future */ -+ u16 (*read)(struct adm6996_priv *priv, enum admreg reg); -+ void (*write)(struct adm6996_priv *priv, enum admreg reg, u16 val); -+}; -+ -+#define to_adm(_dev) container_of(_dev, struct adm6996_priv, dev) -+#define phy_to_adm(_phy) ((struct adm6996_priv *) (_phy)->priv) -+ -+#define MIB_DESC(_o, _n) \ -+ { \ -+ .offset = (_o), \ -+ .name = (_n), \ -+ } -+ -+static const struct adm6996_mib_desc adm6996_mibs[] = { -+ MIB_DESC(ADM_CL0, "RxPacket"), -+ MIB_DESC(ADM_CL6, "RxByte"), -+ MIB_DESC(ADM_CL12, "TxPacket"), -+ MIB_DESC(ADM_CL18, "TxByte"), -+ MIB_DESC(ADM_CL24, "Collision"), -+ MIB_DESC(ADM_CL30, "Error"), -+}; -+ -+#define ADM6996_MIB_RXB_ID 1 -+#define ADM6996_MIB_TXB_ID 3 -+ -+static inline u16 -+r16(struct adm6996_priv *priv, enum admreg reg) -+{ -+ return priv->read(priv, reg); -+} -+ -+static inline void -+w16(struct adm6996_priv *priv, enum admreg reg, u16 val) -+{ -+ priv->write(priv, reg, val); -+} -+ -+/* Minimum timing constants */ -+#define EECK_EDGE_TIME 3 /* 3us - max(adm 2.5us, 93c 1us) */ -+#define EEDI_SETUP_TIME 1 /* 1us - max(adm 10ns, 93c 400ns) */ -+#define EECS_SETUP_TIME 1 /* 1us - max(adm no, 93c 200ns) */ -+ -+static void adm6996_gpio_write(struct adm6996_priv *priv, int cs, char *buf, unsigned int bits) -+{ -+ int i, len = (bits + 7) / 8; -+ u8 mask; -+ -+ gpio_set_value(priv->eecs, cs); -+ udelay(EECK_EDGE_TIME); -+ -+ /* Byte assemble from MSB to LSB */ -+ for (i = 0; i < len; i++) { -+ /* Bit bang from MSB to LSB */ -+ for (mask = 0x80; mask && bits > 0; mask >>= 1, bits --) { -+ /* Clock low */ -+ gpio_set_value(priv->eesk, 0); -+ udelay(EECK_EDGE_TIME); -+ -+ /* Output on rising edge */ -+ gpio_set_value(priv->eedi, (mask & buf[i])); -+ udelay(EEDI_SETUP_TIME); -+ -+ /* Clock high */ -+ gpio_set_value(priv->eesk, 1); -+ udelay(EECK_EDGE_TIME); -+ } -+ } -+ -+ /* Clock low */ -+ gpio_set_value(priv->eesk, 0); -+ udelay(EECK_EDGE_TIME); -+ -+ if (cs) -+ gpio_set_value(priv->eecs, 0); -+} -+ -+static void adm6996_gpio_read(struct adm6996_priv *priv, int cs, char *buf, unsigned int bits) -+{ -+ int i, len = (bits + 7) / 8; -+ u8 mask; -+ -+ gpio_set_value(priv->eecs, cs); -+ udelay(EECK_EDGE_TIME); -+ -+ /* Byte assemble from MSB to LSB */ -+ for (i = 0; i < len; i++) { -+ u8 byte; -+ -+ /* Bit bang from MSB to LSB */ -+ for (mask = 0x80, byte = 0; mask && bits > 0; mask >>= 1, bits --) { -+ u8 gp; -+ -+ /* Clock low */ -+ gpio_set_value(priv->eesk, 0); -+ udelay(EECK_EDGE_TIME); -+ -+ /* Input on rising edge */ -+ gp = gpio_get_value(priv->eedi); -+ if (gp) -+ byte |= mask; -+ -+ /* Clock high */ -+ gpio_set_value(priv->eesk, 1); -+ udelay(EECK_EDGE_TIME); -+ } -+ -+ *buf++ = byte; -+ } -+ -+ /* Clock low */ -+ gpio_set_value(priv->eesk, 0); -+ udelay(EECK_EDGE_TIME); -+ -+ if (cs) -+ gpio_set_value(priv->eecs, 0); -+} -+ -+/* Advance clock(s) */ -+static void adm6996_gpio_adclk(struct adm6996_priv *priv, int clocks) -+{ -+ int i; -+ for (i = 0; i < clocks; i++) { -+ /* Clock high */ -+ gpio_set_value(priv->eesk, 1); -+ udelay(EECK_EDGE_TIME); -+ -+ /* Clock low */ -+ gpio_set_value(priv->eesk, 0); -+ udelay(EECK_EDGE_TIME); -+ } -+} -+ -+static u16 -+adm6996_read_gpio_reg(struct adm6996_priv *priv, enum admreg reg) -+{ -+ /* cmd: 01 10 T DD R RRRRRR */ -+ u8 bits[6] = { -+ 0xFF, 0xFF, 0xFF, 0xFF, -+ (0x06 << 4) | ((0 & 0x01) << 3 | (reg&64)>>6), -+ ((reg&63)<<2) -+ }; -+ -+ u8 rbits[4]; -+ -+ /* Enable GPIO outputs with all pins to 0 */ -+ gpio_direction_output(priv->eecs, 0); -+ gpio_direction_output(priv->eesk, 0); -+ gpio_direction_output(priv->eedi, 0); -+ -+ adm6996_gpio_write(priv, 0, bits, 46); -+ gpio_direction_input(priv->eedi); -+ adm6996_gpio_adclk(priv, 2); -+ adm6996_gpio_read(priv, 0, rbits, 32); -+ -+ /* Extra clock(s) required per datasheet */ -+ adm6996_gpio_adclk(priv, 2); -+ -+ /* Disable GPIO outputs */ -+ gpio_direction_input(priv->eecs); -+ gpio_direction_input(priv->eesk); -+ -+ /* EEPROM has 16-bit registers, but pumps out two registers in one request */ -+ return (reg & 0x01 ? (rbits[0]<<8) | rbits[1] : (rbits[2]<<8) | (rbits[3])); -+} -+ -+/* Write chip configuration register */ -+/* Follow 93c66 timing and chip's min EEPROM timing requirement */ -+static void -+adm6996_write_gpio_reg(struct adm6996_priv *priv, enum admreg reg, u16 val) -+{ -+ /* cmd(27bits): sb(1) + opc(01) + addr(bbbbbbbb) + data(bbbbbbbbbbbbbbbb) */ -+ u8 bits[4] = { -+ (0x05 << 5) | (reg >> 3), -+ (reg << 5) | (u8)(val >> 11), -+ (u8)(val >> 3), -+ (u8)(val << 5) -+ }; -+ -+ /* Enable GPIO outputs with all pins to 0 */ -+ gpio_direction_output(priv->eecs, 0); -+ gpio_direction_output(priv->eesk, 0); -+ gpio_direction_output(priv->eedi, 0); -+ -+ /* Write cmd. Total 27 bits */ -+ adm6996_gpio_write(priv, 1, bits, 27); -+ -+ /* Extra clock(s) required per datasheet */ -+ adm6996_gpio_adclk(priv, 2); -+ -+ /* Disable GPIO outputs */ -+ gpio_direction_input(priv->eecs); -+ gpio_direction_input(priv->eesk); -+ gpio_direction_input(priv->eedi); -+} -+ -+static u16 -+adm6996_read_mii_reg(struct adm6996_priv *priv, enum admreg reg) -+{ -+ struct phy_device *phydev = priv->priv; -+ struct mii_bus *bus = phydev->mdio.bus; -+ -+ return bus->read(bus, PHYADDR(reg)); -+} -+ -+static void -+adm6996_write_mii_reg(struct adm6996_priv *priv, enum admreg reg, u16 val) -+{ -+ struct phy_device *phydev = priv->priv; -+ struct mii_bus *bus = phydev->mdio.bus; -+ -+ bus->write(bus, PHYADDR(reg), val); -+} -+ -+static int -+adm6996_set_enable_vlan(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct adm6996_priv *priv = to_adm(dev); -+ -+ if (val->value.i > 1) -+ return -EINVAL; -+ -+ priv->enable_vlan = val->value.i; -+ -+ return 0; -+}; -+ -+static int -+adm6996_get_enable_vlan(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct adm6996_priv *priv = to_adm(dev); -+ -+ val->value.i = priv->enable_vlan; -+ -+ return 0; -+}; -+ -+#ifdef DEBUG -+ -+static int -+adm6996_set_addr(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct adm6996_priv *priv = to_adm(dev); -+ -+ if (val->value.i > 1023) -+ return -EINVAL; -+ -+ priv->addr = val->value.i; -+ -+ return 0; -+}; -+ -+static int -+adm6996_get_addr(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct adm6996_priv *priv = to_adm(dev); -+ -+ val->value.i = priv->addr; -+ -+ return 0; -+}; -+ -+static int -+adm6996_set_data(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct adm6996_priv *priv = to_adm(dev); -+ -+ if (val->value.i > 65535) -+ return -EINVAL; -+ -+ w16(priv, priv->addr, val->value.i); -+ -+ return 0; -+}; -+ -+static int -+adm6996_get_data(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct adm6996_priv *priv = to_adm(dev); -+ -+ val->value.i = r16(priv, priv->addr); -+ -+ return 0; -+}; -+ -+#endif /* def DEBUG */ -+ -+static int -+adm6996_set_pvid(struct switch_dev *dev, int port, int vlan) -+{ -+ struct adm6996_priv *priv = to_adm(dev); -+ -+ pr_devel("set_pvid port %d vlan %d\n", port, vlan); -+ -+ if (vlan > ADM_VLAN_MAX_ID) -+ return -EINVAL; -+ -+ priv->pvid[port] = vlan; -+ -+ return 0; -+} -+ -+static int -+adm6996_get_pvid(struct switch_dev *dev, int port, int *vlan) -+{ -+ struct adm6996_priv *priv = to_adm(dev); -+ -+ pr_devel("get_pvid port %d\n", port); -+ *vlan = priv->pvid[port]; -+ -+ return 0; -+} -+ -+static int -+adm6996_set_vid(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct adm6996_priv *priv = to_adm(dev); -+ -+ pr_devel("set_vid port %d vid %d\n", val->port_vlan, val->value.i); -+ -+ if (val->value.i > ADM_VLAN_MAX_ID) -+ return -EINVAL; -+ -+ priv->vlan_id[val->port_vlan] = val->value.i; -+ -+ return 0; -+}; -+ -+static int -+adm6996_get_vid(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct adm6996_priv *priv = to_adm(dev); -+ -+ pr_devel("get_vid port %d\n", val->port_vlan); -+ -+ val->value.i = priv->vlan_id[val->port_vlan]; -+ -+ return 0; -+}; -+ -+static int -+adm6996_get_ports(struct switch_dev *dev, struct switch_val *val) -+{ -+ struct adm6996_priv *priv = to_adm(dev); -+ u8 ports = priv->vlan_table[val->port_vlan]; -+ u8 tagged = priv->vlan_tagged[val->port_vlan]; -+ int i; -+ -+ pr_devel("get_ports port_vlan %d\n", val->port_vlan); -+ -+ val->len = 0; -+ -+ for (i = 0; i < ADM_NUM_PORTS; i++) { -+ struct switch_port *p; -+ -+ if (!(ports & (1 << i))) -+ continue; -+ -+ p = &val->value.ports[val->len++]; -+ p->id = i; -+ if (tagged & (1 << i)) -+ p->flags = (1 << SWITCH_PORT_FLAG_TAGGED); -+ else -+ p->flags = 0; -+ } -+ -+ return 0; -+}; -+ -+static int -+adm6996_set_ports(struct switch_dev *dev, struct switch_val *val) -+{ -+ struct adm6996_priv *priv = to_adm(dev); -+ u8 *ports = &priv->vlan_table[val->port_vlan]; -+ u8 *tagged = &priv->vlan_tagged[val->port_vlan]; -+ int i; -+ -+ pr_devel("set_ports port_vlan %d ports", val->port_vlan); -+ -+ *ports = 0; -+ *tagged = 0; -+ -+ for (i = 0; i < val->len; i++) { -+ struct switch_port *p = &val->value.ports[i]; -+ -+#ifdef DEBUG -+ pr_cont(" %d%s", p->id, -+ ((p->flags & (1 << SWITCH_PORT_FLAG_TAGGED)) ? "T" : -+ "")); -+#endif -+ -+ if (p->flags & (1 << SWITCH_PORT_FLAG_TAGGED)) { -+ *tagged |= (1 << p->id); -+ priv->tagged_ports |= (1 << p->id); -+ } -+ -+ *ports |= (1 << p->id); -+ } -+ -+#ifdef DEBUG -+ pr_cont("\n"); -+#endif -+ -+ return 0; -+}; -+ -+/* -+ * Precondition: reg_mutex must be held -+ */ -+static void -+adm6996_enable_vlan(struct adm6996_priv *priv) -+{ -+ u16 reg; -+ -+ reg = r16(priv, ADM_OTBE_P2_PVID); -+ reg &= ~(ADM_OTBE_MASK); -+ w16(priv, ADM_OTBE_P2_PVID, reg); -+ reg = r16(priv, ADM_IFNTE); -+ reg &= ~(ADM_IFNTE_MASK); -+ w16(priv, ADM_IFNTE, reg); -+ reg = r16(priv, ADM_VID_CHECK); -+ reg |= ADM_VID_CHECK_MASK; -+ w16(priv, ADM_VID_CHECK, reg); -+ reg = r16(priv, ADM_SYSC0); -+ reg |= ADM_NTTE; -+ reg &= ~(ADM_RVID1); -+ w16(priv, ADM_SYSC0, reg); -+ reg = r16(priv, ADM_SYSC3); -+ reg |= ADM_TBV; -+ w16(priv, ADM_SYSC3, reg); -+} -+ -+static void -+adm6996_enable_vlan_6996l(struct adm6996_priv *priv) -+{ -+ u16 reg; -+ -+ reg = r16(priv, ADM_SYSC3); -+ reg |= ADM_TBV; -+ reg |= ADM_MAC_CLONE; -+ w16(priv, ADM_SYSC3, reg); -+} -+ -+/* -+ * Disable VLANs -+ * -+ * Sets VLAN mapping for port-based VLAN with all ports connected to -+ * eachother (this is also the power-on default). -+ * -+ * Precondition: reg_mutex must be held -+ */ -+static void -+adm6996_disable_vlan(struct adm6996_priv *priv) -+{ -+ u16 reg; -+ int i; -+ -+ for (i = 0; i < ADM_NUM_VLANS; i++) { -+ reg = ADM_VLAN_FILT_MEMBER_MASK; -+ w16(priv, ADM_VLAN_FILT_L(i), reg); -+ reg = ADM_VLAN_FILT_VALID | ADM_VLAN_FILT_VID(1); -+ w16(priv, ADM_VLAN_FILT_H(i), reg); -+ } -+ -+ reg = r16(priv, ADM_OTBE_P2_PVID); -+ reg |= ADM_OTBE_MASK; -+ w16(priv, ADM_OTBE_P2_PVID, reg); -+ reg = r16(priv, ADM_IFNTE); -+ reg |= ADM_IFNTE_MASK; -+ w16(priv, ADM_IFNTE, reg); -+ reg = r16(priv, ADM_VID_CHECK); -+ reg &= ~(ADM_VID_CHECK_MASK); -+ w16(priv, ADM_VID_CHECK, reg); -+ reg = r16(priv, ADM_SYSC0); -+ reg &= ~(ADM_NTTE); -+ reg |= ADM_RVID1; -+ w16(priv, ADM_SYSC0, reg); -+ reg = r16(priv, ADM_SYSC3); -+ reg &= ~(ADM_TBV); -+ w16(priv, ADM_SYSC3, reg); -+} -+ -+/* -+ * Disable VLANs -+ * -+ * Sets VLAN mapping for port-based VLAN with all ports connected to -+ * eachother (this is also the power-on default). -+ * -+ * Precondition: reg_mutex must be held -+ */ -+static void -+adm6996_disable_vlan_6996l(struct adm6996_priv *priv) -+{ -+ u16 reg; -+ int i; -+ -+ for (i = 0; i < ADM_NUM_VLANS; i++) { -+ w16(priv, ADM_VLAN_MAP(i), 0); -+ } -+ -+ reg = r16(priv, ADM_SYSC3); -+ reg &= ~(ADM_TBV); -+ reg &= ~(ADM_MAC_CLONE); -+ w16(priv, ADM_SYSC3, reg); -+} -+ -+/* -+ * Precondition: reg_mutex must be held -+ */ -+static void -+adm6996_apply_port_pvids(struct adm6996_priv *priv) -+{ -+ u16 reg; -+ int i; -+ -+ for (i = 0; i < ADM_NUM_PORTS; i++) { -+ reg = r16(priv, adm_portcfg[i]); -+ reg &= ~(ADM_PORTCFG_PVID_MASK); -+ reg |= ADM_PORTCFG_PVID(priv->pvid[i]); -+ if (priv->model == ADM6996L) { -+ if (priv->tagged_ports & (1 << i)) -+ reg |= (1 << 4); -+ else -+ reg &= ~(1 << 4); -+ } -+ w16(priv, adm_portcfg[i], reg); -+ } -+ -+ w16(priv, ADM_P0_PVID, ADM_P0_PVID_VAL(priv->pvid[0])); -+ w16(priv, ADM_P1_PVID, ADM_P1_PVID_VAL(priv->pvid[1])); -+ reg = r16(priv, ADM_OTBE_P2_PVID); -+ reg &= ~(ADM_P2_PVID_MASK); -+ reg |= ADM_P2_PVID_VAL(priv->pvid[2]); -+ w16(priv, ADM_OTBE_P2_PVID, reg); -+ reg = ADM_P3_PVID_VAL(priv->pvid[3]); -+ reg |= ADM_P4_PVID_VAL(priv->pvid[4]); -+ w16(priv, ADM_P3_P4_PVID, reg); -+ reg = r16(priv, ADM_P5_PVID); -+ reg &= ~(ADM_P2_PVID_MASK); -+ reg |= ADM_P5_PVID_VAL(priv->pvid[5]); -+ w16(priv, ADM_P5_PVID, reg); -+} -+ -+/* -+ * Precondition: reg_mutex must be held -+ */ -+static void -+adm6996_apply_vlan_filters(struct adm6996_priv *priv) -+{ -+ u8 ports, tagged; -+ u16 vid, reg; -+ int i; -+ -+ for (i = 0; i < ADM_NUM_VLANS; i++) { -+ vid = priv->vlan_id[i]; -+ ports = priv->vlan_table[i]; -+ tagged = priv->vlan_tagged[i]; -+ -+ if (ports == 0) { -+ /* Disable VLAN entry */ -+ w16(priv, ADM_VLAN_FILT_H(i), 0); -+ w16(priv, ADM_VLAN_FILT_L(i), 0); -+ continue; -+ } -+ -+ reg = ADM_VLAN_FILT_MEMBER(ports); -+ reg |= ADM_VLAN_FILT_TAGGED(tagged); -+ w16(priv, ADM_VLAN_FILT_L(i), reg); -+ reg = ADM_VLAN_FILT_VALID | ADM_VLAN_FILT_VID(vid); -+ w16(priv, ADM_VLAN_FILT_H(i), reg); -+ } -+} -+ -+static void -+adm6996_apply_vlan_filters_6996l(struct adm6996_priv *priv) -+{ -+ u8 ports; -+ u16 reg; -+ int i; -+ -+ for (i = 0; i < ADM_NUM_VLANS; i++) { -+ ports = priv->vlan_table[i]; -+ -+ if (ports == 0) { -+ /* Disable VLAN entry */ -+ w16(priv, ADM_VLAN_MAP(i), 0); -+ continue; -+ } else { -+ reg = ADM_VLAN_FILT(ports); -+ w16(priv, ADM_VLAN_MAP(i), reg); -+ } -+ } -+} -+ -+static int -+adm6996_hw_apply(struct switch_dev *dev) -+{ -+ struct adm6996_priv *priv = to_adm(dev); -+ -+ pr_devel("hw_apply\n"); -+ -+ mutex_lock(&priv->reg_mutex); -+ -+ if (!priv->enable_vlan) { -+ if (priv->vlan_enabled) { -+ if (priv->model == ADM6996L) -+ adm6996_disable_vlan_6996l(priv); -+ else -+ adm6996_disable_vlan(priv); -+ priv->vlan_enabled = 0; -+ } -+ goto out; -+ } -+ -+ if (!priv->vlan_enabled) { -+ if (priv->model == ADM6996L) -+ adm6996_enable_vlan_6996l(priv); -+ else -+ adm6996_enable_vlan(priv); -+ priv->vlan_enabled = 1; -+ } -+ -+ adm6996_apply_port_pvids(priv); -+ if (priv->model == ADM6996L) -+ adm6996_apply_vlan_filters_6996l(priv); -+ else -+ adm6996_apply_vlan_filters(priv); -+ -+out: -+ mutex_unlock(&priv->reg_mutex); -+ -+ return 0; -+} -+ -+/* -+ * Reset the switch -+ * -+ * The ADM6996 can't do a software-initiated reset, so we just initialise the -+ * registers we support in this driver. -+ * -+ * Precondition: reg_mutex must be held -+ */ -+static void -+adm6996_perform_reset (struct adm6996_priv *priv) -+{ -+ int i; -+ -+ /* initialize port and vlan settings */ -+ for (i = 0; i < ADM_NUM_PORTS - 1; i++) { -+ w16(priv, adm_portcfg[i], ADM_PORTCFG_INIT | -+ ADM_PORTCFG_PVID(0)); -+ } -+ w16(priv, adm_portcfg[5], ADM_PORTCFG_CPU); -+ -+ if (priv->model == ADM6996M || priv->model == ADM6996FC) { -+ /* reset all PHY ports */ -+ for (i = 0; i < ADM_PHY_PORTS; i++) { -+ w16(priv, ADM_PHY_PORT(i), ADM_PHYCFG_INIT); -+ } -+ } -+ -+ priv->enable_vlan = 0; -+ priv->vlan_enabled = 0; -+ -+ for (i = 0; i < ADM_NUM_PORTS; i++) { -+ priv->pvid[i] = 0; -+ } -+ -+ for (i = 0; i < ADM_NUM_VLANS; i++) { -+ priv->vlan_id[i] = i; -+ priv->vlan_table[i] = 0; -+ priv->vlan_tagged[i] = 0; -+ } -+ -+ if (priv->model == ADM6996M) { -+ /* Clear VLAN priority map so prio's are unused */ -+ w16 (priv, ADM_VLAN_PRIOMAP, 0); -+ -+ adm6996_disable_vlan(priv); -+ adm6996_apply_port_pvids(priv); -+ } else if (priv->model == ADM6996L) { -+ /* Clear VLAN priority map so prio's are unused */ -+ w16 (priv, ADM_VLAN_PRIOMAP, 0); -+ -+ adm6996_disable_vlan_6996l(priv); -+ adm6996_apply_port_pvids(priv); -+ } -+} -+ -+static int -+adm6996_reset_switch(struct switch_dev *dev) -+{ -+ struct adm6996_priv *priv = to_adm(dev); -+ -+ pr_devel("reset\n"); -+ -+ mutex_lock(&priv->reg_mutex); -+ adm6996_perform_reset (priv); -+ mutex_unlock(&priv->reg_mutex); -+ return 0; -+} -+ -+static int -+adm6996_get_port_link(struct switch_dev *dev, int port, -+ struct switch_port_link *link) -+{ -+ struct adm6996_priv *priv = to_adm(dev); -+ -+ u16 reg = 0; -+ -+ if (port >= ADM_NUM_PORTS) -+ return -EINVAL; -+ -+ switch (port) { -+ case 0: -+ reg = r16(priv, ADM_PS0); -+ break; -+ case 1: -+ reg = r16(priv, ADM_PS0); -+ reg = reg >> 8; -+ break; -+ case 2: -+ reg = r16(priv, ADM_PS1); -+ break; -+ case 3: -+ reg = r16(priv, ADM_PS1); -+ reg = reg >> 8; -+ break; -+ case 4: -+ reg = r16(priv, ADM_PS1); -+ reg = reg >> 12; -+ break; -+ case 5: -+ reg = r16(priv, ADM_PS2); -+ /* Bits 0, 1, 3 and 4. */ -+ reg = (reg & 3) | ((reg & 24) >> 1); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ link->link = reg & ADM_PS_LS; -+ if (!link->link) -+ return 0; -+ link->aneg = true; -+ link->duplex = reg & ADM_PS_DS; -+ link->tx_flow = reg & ADM_PS_FCS; -+ link->rx_flow = reg & ADM_PS_FCS; -+ if (reg & ADM_PS_SS) -+ link->speed = SWITCH_PORT_SPEED_100; -+ else -+ link->speed = SWITCH_PORT_SPEED_10; -+ -+ return 0; -+} -+ -+static int -+adm6996_sw_get_port_mib(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct adm6996_priv *priv = to_adm(dev); -+ int port; -+ char *buf = priv->buf; -+ int i, len = 0; -+ u32 reg = 0; -+ -+ port = val->port_vlan; -+ if (port >= ADM_NUM_PORTS) -+ return -EINVAL; -+ -+ mutex_lock(&priv->mib_lock); -+ -+ len += snprintf(buf + len, sizeof(priv->buf) - len, -+ "Port %d MIB counters\n", -+ port); -+ -+ for (i = 0; i < ARRAY_SIZE(adm6996_mibs); i++) { -+ reg = r16(priv, adm6996_mibs[i].offset + ADM_OFFSET_PORT(port)); -+ reg += r16(priv, adm6996_mibs[i].offset + ADM_OFFSET_PORT(port) + 1) << 16; -+ len += snprintf(buf + len, sizeof(priv->buf) - len, -+ "%-12s: %u\n", -+ adm6996_mibs[i].name, -+ reg); -+ } -+ -+ mutex_unlock(&priv->mib_lock); -+ -+ val->value.s = buf; -+ val->len = len; -+ -+ return 0; -+} -+ -+static int -+adm6996_get_port_stats(struct switch_dev *dev, int port, -+ struct switch_port_stats *stats) -+{ -+ struct adm6996_priv *priv = to_adm(dev); -+ int id; -+ u32 reg = 0; -+ -+ if (port >= ADM_NUM_PORTS) -+ return -EINVAL; -+ -+ mutex_lock(&priv->mib_lock); -+ -+ id = ADM6996_MIB_TXB_ID; -+ reg = r16(priv, adm6996_mibs[id].offset + ADM_OFFSET_PORT(port)); -+ reg += r16(priv, adm6996_mibs[id].offset + ADM_OFFSET_PORT(port) + 1) << 16; -+ stats->tx_bytes = reg; -+ -+ id = ADM6996_MIB_RXB_ID; -+ reg = r16(priv, adm6996_mibs[id].offset + ADM_OFFSET_PORT(port)); -+ reg += r16(priv, adm6996_mibs[id].offset + ADM_OFFSET_PORT(port) + 1) << 16; -+ stats->rx_bytes = reg; -+ -+ mutex_unlock(&priv->mib_lock); -+ -+ return 0; -+} -+ -+static struct switch_attr adm6996_globals[] = { -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_vlan", -+ .description = "Enable VLANs", -+ .set = adm6996_set_enable_vlan, -+ .get = adm6996_get_enable_vlan, -+ }, -+#ifdef DEBUG -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "addr", -+ .description = -+ "Direct register access: set register address (0 - 1023)", -+ .set = adm6996_set_addr, -+ .get = adm6996_get_addr, -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "data", -+ .description = -+ "Direct register access: read/write to register (0 - 65535)", -+ .set = adm6996_set_data, -+ .get = adm6996_get_data, -+ }, -+#endif /* def DEBUG */ -+}; -+ -+static struct switch_attr adm6996_port[] = { -+ { -+ .type = SWITCH_TYPE_STRING, -+ .name = "mib", -+ .description = "Get port's MIB counters", -+ .set = NULL, -+ .get = adm6996_sw_get_port_mib, -+ }, -+}; -+ -+static struct switch_attr adm6996_vlan[] = { -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "vid", -+ .description = "VLAN ID", -+ .set = adm6996_set_vid, -+ .get = adm6996_get_vid, -+ }, -+}; -+ -+static struct switch_dev_ops adm6996_ops = { -+ .attr_global = { -+ .attr = adm6996_globals, -+ .n_attr = ARRAY_SIZE(adm6996_globals), -+ }, -+ .attr_port = { -+ .attr = adm6996_port, -+ .n_attr = ARRAY_SIZE(adm6996_port), -+ }, -+ .attr_vlan = { -+ .attr = adm6996_vlan, -+ .n_attr = ARRAY_SIZE(adm6996_vlan), -+ }, -+ .get_port_pvid = adm6996_get_pvid, -+ .set_port_pvid = adm6996_set_pvid, -+ .get_vlan_ports = adm6996_get_ports, -+ .set_vlan_ports = adm6996_set_ports, -+ .apply_config = adm6996_hw_apply, -+ .reset_switch = adm6996_reset_switch, -+ .get_port_link = adm6996_get_port_link, -+ .get_port_stats = adm6996_get_port_stats, -+}; -+ -+static int adm6996_switch_init(struct adm6996_priv *priv, const char *alias, struct net_device *netdev) -+{ -+ struct switch_dev *swdev; -+ u16 test, old; -+ -+ if (!priv->model) { -+ /* Detect type of chip */ -+ old = r16(priv, ADM_VID_CHECK); -+ test = old ^ (1 << 12); -+ w16(priv, ADM_VID_CHECK, test); -+ test ^= r16(priv, ADM_VID_CHECK); -+ if (test & (1 << 12)) { -+ /* -+ * Bit 12 of this register is read-only. -+ * This is the FC model. -+ */ -+ priv->model = ADM6996FC; -+ } else { -+ /* Bit 12 is read-write. This is the M model. */ -+ priv->model = ADM6996M; -+ w16(priv, ADM_VID_CHECK, old); -+ } -+ } -+ -+ swdev = &priv->dev; -+ swdev->name = (adm6996_model_name[priv->model]); -+ swdev->cpu_port = ADM_CPU_PORT; -+ swdev->ports = ADM_NUM_PORTS; -+ swdev->vlans = ADM_NUM_VLANS; -+ swdev->ops = &adm6996_ops; -+ swdev->alias = alias; -+ -+ /* The ADM6996L connected through GPIOs does not support any switch -+ status calls */ -+ if (priv->model == ADM6996L) { -+ adm6996_ops.attr_port.n_attr = 0; -+ adm6996_ops.get_port_link = NULL; -+ } -+ -+ pr_info ("%s: %s model PHY found.\n", alias, swdev->name); -+ -+ mutex_lock(&priv->reg_mutex); -+ adm6996_perform_reset (priv); -+ mutex_unlock(&priv->reg_mutex); -+ -+ if (priv->model == ADM6996M || priv->model == ADM6996L) { -+ return register_switch(swdev, netdev); -+ } -+ -+ return -ENODEV; -+} -+ -+static int adm6996_config_init(struct phy_device *pdev) -+{ -+ struct adm6996_priv *priv; -+ int ret; -+ -+ linkmode_zero(pdev->supported); -+ linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, pdev->supported); -+ linkmode_copy(pdev->advertising, pdev->supported); -+ -+ if (pdev->mdio.addr != 0) { -+ pr_info ("%s: PHY overlaps ADM6996, providing fixed PHY 0x%x.\n" -+ , pdev->attached_dev->name, pdev->mdio.addr); -+ return 0; -+ } -+ -+ priv = devm_kzalloc(&pdev->mdio.dev, sizeof(struct adm6996_priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ mutex_init(&priv->reg_mutex); -+ mutex_init(&priv->mib_lock); -+ priv->priv = pdev; -+ priv->read = adm6996_read_mii_reg; -+ priv->write = adm6996_write_mii_reg; -+ -+ ret = adm6996_switch_init(priv, pdev->attached_dev->name, pdev->attached_dev); -+ if (ret < 0) -+ return ret; -+ -+ pdev->priv = priv; -+ -+ return 0; -+} -+ -+/* -+ * Warning: phydev->priv is NULL if phydev->mdio.addr != 0 -+ */ -+static int adm6996_read_status(struct phy_device *phydev) -+{ -+ phydev->speed = SPEED_100; -+ phydev->duplex = DUPLEX_FULL; -+ phydev->link = 1; -+ -+ phydev->state = PHY_RUNNING; -+ netif_carrier_on(phydev->attached_dev); -+ phydev->adjust_link(phydev->attached_dev); -+ -+ return 0; -+} -+ -+/* -+ * Warning: phydev->priv is NULL if phydev->mdio.addr != 0 -+ */ -+static int adm6996_config_aneg(struct phy_device *phydev) -+{ -+ return 0; -+} -+ -+static int adm6996_fixup(struct phy_device *dev) -+{ -+ struct mii_bus *bus = dev->mdio.bus; -+ u16 reg; -+ -+ /* Our custom registers are at PHY addresses 0-10. Claim those. */ -+ if (dev->mdio.addr > 10) -+ return 0; -+ -+ /* look for the switch on the bus */ -+ reg = bus->read(bus, PHYADDR(ADM_SIG0)) & ADM_SIG0_MASK; -+ if (reg != ADM_SIG0_VAL) -+ return 0; -+ -+ reg = bus->read(bus, PHYADDR(ADM_SIG1)) & ADM_SIG1_MASK; -+ if (reg != ADM_SIG1_VAL) -+ return 0; -+ -+ dev->phy_id = (ADM_SIG0_VAL << 16) | ADM_SIG1_VAL; -+ -+ return 0; -+} -+ -+static int adm6996_probe(struct phy_device *pdev) -+{ -+ return 0; -+} -+ -+static void adm6996_remove(struct phy_device *pdev) -+{ -+ struct adm6996_priv *priv = phy_to_adm(pdev); -+ -+ if (priv && (priv->model == ADM6996M || priv->model == ADM6996L)) -+ unregister_switch(&priv->dev); -+} -+ -+static int adm6996_soft_reset(struct phy_device *phydev) -+{ -+ /* we don't need an extra reset */ -+ return 0; -+} -+ -+static struct phy_driver adm6996_phy_driver = { -+ .name = "Infineon ADM6996", -+ .phy_id = (ADM_SIG0_VAL << 16) | ADM_SIG1_VAL, -+ .phy_id_mask = 0xffffffff, -+ .features = PHY_BASIC_FEATURES, -+ .probe = adm6996_probe, -+ .remove = adm6996_remove, -+ .config_init = &adm6996_config_init, -+ .config_aneg = &adm6996_config_aneg, -+ .read_status = &adm6996_read_status, -+ .soft_reset = adm6996_soft_reset, -+}; -+ -+static int adm6996_gpio_probe(struct platform_device *pdev) -+{ -+ struct adm6996_gpio_platform_data *pdata = pdev->dev.platform_data; -+ struct adm6996_priv *priv; -+ int ret; -+ -+ if (!pdata) -+ return -EINVAL; -+ -+ priv = devm_kzalloc(&pdev->dev, sizeof(struct adm6996_priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ mutex_init(&priv->reg_mutex); -+ mutex_init(&priv->mib_lock); -+ -+ priv->eecs = pdata->eecs; -+ priv->eedi = pdata->eedi; -+ priv->eesk = pdata->eesk; -+ -+ priv->model = pdata->model; -+ priv->read = adm6996_read_gpio_reg; -+ priv->write = adm6996_write_gpio_reg; -+ -+ ret = devm_gpio_request(&pdev->dev, priv->eecs, "adm_eecs"); -+ if (ret) -+ return ret; -+ ret = devm_gpio_request(&pdev->dev, priv->eedi, "adm_eedi"); -+ if (ret) -+ return ret; -+ ret = devm_gpio_request(&pdev->dev, priv->eesk, "adm_eesk"); -+ if (ret) -+ return ret; -+ -+ ret = adm6996_switch_init(priv, dev_name(&pdev->dev), NULL); -+ if (ret < 0) -+ return ret; -+ -+ platform_set_drvdata(pdev, priv); -+ -+ return 0; -+} -+ -+static void adm6996_gpio_remove(struct platform_device *pdev) -+{ -+ struct adm6996_priv *priv = platform_get_drvdata(pdev); -+ -+ if (priv && (priv->model == ADM6996M || priv->model == ADM6996L)) -+ unregister_switch(&priv->dev); -+} -+ -+static struct platform_driver adm6996_gpio_driver = { -+ .probe = adm6996_gpio_probe, -+ .remove_new = adm6996_gpio_remove, -+ .driver = { -+ .name = "adm6996_gpio", -+ }, -+}; -+ -+static int __init adm6996_init(void) -+{ -+ int err; -+ -+ phy_register_fixup_for_id(PHY_ANY_ID, adm6996_fixup); -+ err = phy_driver_register(&adm6996_phy_driver, THIS_MODULE); -+ if (err) -+ return err; -+ -+ err = platform_driver_register(&adm6996_gpio_driver); -+ if (err) -+ phy_driver_unregister(&adm6996_phy_driver); -+ -+ return err; -+} -+ -+static void __exit adm6996_exit(void) -+{ -+ platform_driver_unregister(&adm6996_gpio_driver); -+ phy_driver_unregister(&adm6996_phy_driver); -+} -+ -+module_init(adm6996_init); -+module_exit(adm6996_exit); -diff --git a/drivers/net/phy/adm6996.h b/drivers/net/phy/adm6996.h -new file mode 100644 -index 000000000000..6fd460a46594 ---- /dev/null -+++ b/drivers/net/phy/adm6996.h -@@ -0,0 +1,186 @@ -+/* -+ * ADM6996 switch driver -+ * -+ * Copyright (c) 2008 Felix Fietkau -+ * Copyright (c) 2010,2011 Peter Lebbing -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License v2 as published by the -+ * Free Software Foundation -+ */ -+#ifndef __ADM6996_H -+#define __ADM6996_H -+ -+/* -+ * ADM_PHY_PORTS: Number of ports with a PHY. -+ * We only control ports 0 to 3, because if 4 is connected, it is most likely -+ * not connected to the switch but to a separate MII and MAC for the WAN port. -+ */ -+#define ADM_PHY_PORTS 4 -+#define ADM_NUM_PORTS 6 -+#define ADM_CPU_PORT 5 -+ -+#define ADM_NUM_VLANS 16 -+#define ADM_VLAN_MAX_ID 4094 -+ -+enum admreg { -+ ADM_EEPROM_BASE = 0x0, -+ ADM_P0_CFG = ADM_EEPROM_BASE + 1, -+ ADM_P1_CFG = ADM_EEPROM_BASE + 3, -+ ADM_P2_CFG = ADM_EEPROM_BASE + 5, -+ ADM_P3_CFG = ADM_EEPROM_BASE + 7, -+ ADM_P4_CFG = ADM_EEPROM_BASE + 8, -+ ADM_P5_CFG = ADM_EEPROM_BASE + 9, -+ ADM_SYSC0 = ADM_EEPROM_BASE + 0xa, -+ ADM_VLAN_PRIOMAP = ADM_EEPROM_BASE + 0xe, -+ ADM_SYSC3 = ADM_EEPROM_BASE + 0x11, -+ /* Input Force No Tag Enable */ -+ ADM_IFNTE = ADM_EEPROM_BASE + 0x20, -+ ADM_VID_CHECK = ADM_EEPROM_BASE + 0x26, -+ ADM_P0_PVID = ADM_EEPROM_BASE + 0x28, -+ ADM_P1_PVID = ADM_EEPROM_BASE + 0x29, -+ /* Output Tag Bypass Enable and P2 PVID */ -+ ADM_OTBE_P2_PVID = ADM_EEPROM_BASE + 0x2a, -+ ADM_P3_P4_PVID = ADM_EEPROM_BASE + 0x2b, -+ ADM_P5_PVID = ADM_EEPROM_BASE + 0x2c, -+ ADM_EEPROM_EXT_BASE = 0x40, -+#define ADM_VLAN_FILT_L(n) (ADM_EEPROM_EXT_BASE + 2 * (n)) -+#define ADM_VLAN_FILT_H(n) (ADM_EEPROM_EXT_BASE + 1 + 2 * (n)) -+#define ADM_VLAN_MAP(n) (ADM_EEPROM_BASE + 0x13 + n) -+ ADM_COUNTER_BASE = 0xa0, -+ ADM_SIG0 = ADM_COUNTER_BASE + 0, -+ ADM_SIG1 = ADM_COUNTER_BASE + 1, -+ ADM_PS0 = ADM_COUNTER_BASE + 2, -+ ADM_PS1 = ADM_COUNTER_BASE + 3, -+ ADM_PS2 = ADM_COUNTER_BASE + 4, -+ ADM_CL0 = ADM_COUNTER_BASE + 8, /* RxPacket */ -+ ADM_CL6 = ADM_COUNTER_BASE + 0x1a, /* RxByte */ -+ ADM_CL12 = ADM_COUNTER_BASE + 0x2c, /* TxPacket */ -+ ADM_CL18 = ADM_COUNTER_BASE + 0x3e, /* TxByte */ -+ ADM_CL24 = ADM_COUNTER_BASE + 0x50, /* Coll */ -+ ADM_CL30 = ADM_COUNTER_BASE + 0x62, /* Err */ -+#define ADM_OFFSET_PORT(n) ((n * 4) - (n / 4) * 2 - (n / 5) * 2) -+ ADM_PHY_BASE = 0x200, -+#define ADM_PHY_PORT(n) (ADM_PHY_BASE + (0x20 * n)) -+}; -+ -+/* Chip identification patterns */ -+#define ADM_SIG0_MASK 0xffff -+#define ADM_SIG0_VAL 0x1023 -+#define ADM_SIG1_MASK 0xffff -+#define ADM_SIG1_VAL 0x0007 -+ -+enum { -+ ADM_PHYCFG_COLTST = (1 << 7), /* Enable collision test */ -+ ADM_PHYCFG_DPLX = (1 << 8), /* Enable full duplex */ -+ ADM_PHYCFG_ANEN_RST = (1 << 9), /* Restart auto negotiation (self clear) */ -+ ADM_PHYCFG_ISO = (1 << 10), /* Isolate PHY */ -+ ADM_PHYCFG_PDN = (1 << 11), /* Power down PHY */ -+ ADM_PHYCFG_ANEN = (1 << 12), /* Enable auto negotiation */ -+ ADM_PHYCFG_SPEED_100 = (1 << 13), /* Enable 100 Mbit/s */ -+ ADM_PHYCFG_LPBK = (1 << 14), /* Enable loopback operation */ -+ ADM_PHYCFG_RST = (1 << 15), /* Reset the port (self clear) */ -+ ADM_PHYCFG_INIT = ( -+ ADM_PHYCFG_RST | -+ ADM_PHYCFG_SPEED_100 | -+ ADM_PHYCFG_ANEN | -+ ADM_PHYCFG_ANEN_RST -+ ) -+}; -+ -+enum { -+ ADM_PORTCFG_FC = (1 << 0), /* Enable 802.x flow control */ -+ ADM_PORTCFG_AN = (1 << 1), /* Enable auto-negotiation */ -+ ADM_PORTCFG_SPEED_100 = (1 << 2), /* Enable 100 Mbit/s */ -+ ADM_PORTCFG_DPLX = (1 << 3), /* Enable full duplex */ -+ ADM_PORTCFG_OT = (1 << 4), /* Output tagged packets */ -+ ADM_PORTCFG_PD = (1 << 5), /* Port disable */ -+ ADM_PORTCFG_TV_PRIO = (1 << 6), /* 0 = VLAN based priority -+ * 1 = TOS based priority */ -+ ADM_PORTCFG_PPE = (1 << 7), /* Port based priority enable */ -+ ADM_PORTCFG_PP_S = (1 << 8), /* Port based priority, 2 bits */ -+ ADM_PORTCFG_PVID_BASE = (1 << 10), /* Primary VLAN id, 4 bits */ -+ ADM_PORTCFG_FSE = (1 << 14), /* Fx select enable */ -+ ADM_PORTCFG_CAM = (1 << 15), /* Crossover Auto MDIX */ -+ -+ ADM_PORTCFG_INIT = ( -+ ADM_PORTCFG_FC | -+ ADM_PORTCFG_AN | -+ ADM_PORTCFG_SPEED_100 | -+ ADM_PORTCFG_DPLX | -+ ADM_PORTCFG_CAM -+ ), -+ ADM_PORTCFG_CPU = ( -+ ADM_PORTCFG_FC | -+ ADM_PORTCFG_SPEED_100 | -+ ADM_PORTCFG_OT | -+ ADM_PORTCFG_DPLX -+ ), -+}; -+ -+#define ADM_PORTCFG_PPID(n) ((n & 0x3) << 8) -+#define ADM_PORTCFG_PVID(n) ((n & 0xf) << 10) -+#define ADM_PORTCFG_PVID_MASK (0xf << 10) -+ -+#define ADM_IFNTE_MASK (0x3f << 9) -+#define ADM_VID_CHECK_MASK (0x3f << 6) -+ -+#define ADM_P0_PVID_VAL(n) ((((n) & 0xff0) >> 4) << 0) -+#define ADM_P1_PVID_VAL(n) ((((n) & 0xff0) >> 4) << 0) -+#define ADM_P2_PVID_VAL(n) ((((n) & 0xff0) >> 4) << 0) -+#define ADM_P3_PVID_VAL(n) ((((n) & 0xff0) >> 4) << 0) -+#define ADM_P4_PVID_VAL(n) ((((n) & 0xff0) >> 4) << 8) -+#define ADM_P5_PVID_VAL(n) ((((n) & 0xff0) >> 4) << 0) -+#define ADM_P2_PVID_MASK 0xff -+ -+#define ADM_OTBE(n) (((n) & 0x3f) << 8) -+#define ADM_OTBE_MASK (0x3f << 8) -+ -+/* ADM_SYSC0 */ -+enum { -+ ADM_NTTE = (1 << 2), /* New Tag Transmit Enable */ -+ ADM_RVID1 = (1 << 8) /* Replace VLAN ID 1 */ -+}; -+ -+/* Tag Based VLAN in ADM_SYSC3 */ -+#define ADM_MAC_CLONE BIT(4) -+#define ADM_TBV BIT(5) -+ -+static const u8 adm_portcfg[] = { -+ [0] = ADM_P0_CFG, -+ [1] = ADM_P1_CFG, -+ [2] = ADM_P2_CFG, -+ [3] = ADM_P3_CFG, -+ [4] = ADM_P4_CFG, -+ [5] = ADM_P5_CFG, -+}; -+ -+/* Fields in ADM_VLAN_FILT_L(x) */ -+#define ADM_VLAN_FILT_FID(n) (((n) & 0xf) << 12) -+#define ADM_VLAN_FILT_TAGGED(n) (((n) & 0x3f) << 6) -+#define ADM_VLAN_FILT_MEMBER(n) (((n) & 0x3f) << 0) -+#define ADM_VLAN_FILT_MEMBER_MASK 0x3f -+/* Fields in ADM_VLAN_FILT_H(x) */ -+#define ADM_VLAN_FILT_VALID (1 << 15) -+#define ADM_VLAN_FILT_VID(n) (((n) & 0xfff) << 0) -+ -+/* Convert ports to a form for ADM6996L VLAN map */ -+#define ADM_VLAN_FILT(ports) ((ports & 0x01) | ((ports & 0x02) << 1) | \ -+ ((ports & 0x04) << 2) | ((ports & 0x08) << 3) | \ -+ ((ports & 0x10) << 3) | ((ports & 0x20) << 3)) -+ -+/* Port status register */ -+enum { -+ ADM_PS_LS = (1 << 0), /* Link status */ -+ ADM_PS_SS = (1 << 1), /* Speed status */ -+ ADM_PS_DS = (1 << 2), /* Duplex status */ -+ ADM_PS_FCS = (1 << 3) /* Flow control status */ -+}; -+ -+/* -+ * Split the register address in phy id and register -+ * it will get combined again by the mdio bus op -+ */ -+#define PHYADDR(_reg) ((_reg >> 5) & 0xff), (_reg & 0x1f) -+ -+#endif -diff --git a/drivers/net/phy/air_an8855.c b/drivers/net/phy/air_an8855.c -new file mode 100644 -index 000000000000..7fab0854ef78 ---- /dev/null -+++ b/drivers/net/phy/air_an8855.c -@@ -0,0 +1,267 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Copyright (C) 2024 Christian Marangi -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#define AN8855_PHY_SELECT_PAGE 0x1f -+#define AN8855_PHY_PAGE GENMASK(2, 0) -+#define AN8855_PHY_PAGE_STANDARD FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x0) -+#define AN8855_PHY_PAGE_EXTENDED_1 FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x1) -+ -+/* MII Registers Page 1 */ -+#define AN8855_PHY_EXT_REG_14 0x14 -+#define AN8855_PHY_EN_DOWN_SHIFT BIT(4) -+ -+/* R50 Calibration regs in MDIO_MMD_VEND1 */ -+#define AN8855_PHY_R500HM_RSEL_TX_AB 0x174 -+#define AN8855_PHY_R50OHM_RSEL_TX_A_EN BIT(15) -+#define AN8855_PHY_R50OHM_RSEL_TX_A GENMASK(14, 8) -+#define AN8855_PHY_R50OHM_RSEL_TX_B_EN BIT(7) -+#define AN8855_PHY_R50OHM_RSEL_TX_B GENMASK(6, 0) -+#define AN8855_PHY_R500HM_RSEL_TX_CD 0x175 -+#define AN8855_PHY_R50OHM_RSEL_TX_C_EN BIT(15) -+#define AN8855_PHY_R50OHM_RSEL_TX_C GENMASK(14, 8) -+#define AN8855_PHY_R50OHM_RSEL_TX_D_EN BIT(7) -+#define AN8855_PHY_R50OHM_RSEL_TX_D GENMASK(6, 0) -+ -+#define AN8855_SWITCH_EFUSE_R50O GENMASK(30, 24) -+ -+/* PHY TX PAIR DELAY SELECT Register */ -+#define AN8855_PHY_TX_PAIR_DLY_SEL_GBE 0x013 -+#define AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_A_GBE GENMASK(14, 12) -+#define AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_B_GBE GENMASK(10, 8) -+#define AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_C_GBE GENMASK(6, 4) -+#define AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_D_GBE GENMASK(2, 0) -+/* PHY ADC Register */ -+#define AN8855_PHY_RXADC_CTRL 0x0d8 -+#define AN8855_PHY_RG_AD_SAMNPLE_PHSEL_A BIT(12) -+#define AN8855_PHY_RG_AD_SAMNPLE_PHSEL_B BIT(8) -+#define AN8855_PHY_RG_AD_SAMNPLE_PHSEL_C BIT(4) -+#define AN8855_PHY_RG_AD_SAMNPLE_PHSEL_D BIT(0) -+#define AN8855_PHY_RXADC_REV_0 0x0d9 -+#define AN8855_PHY_RG_AD_RESERVE0_A GENMASK(15, 8) -+#define AN8855_PHY_RG_AD_RESERVE0_B GENMASK(7, 0) -+#define AN8855_PHY_RXADC_REV_1 0x0da -+#define AN8855_PHY_RG_AD_RESERVE0_C GENMASK(15, 8) -+#define AN8855_PHY_RG_AD_RESERVE0_D GENMASK(7, 0) -+ -+#define AN8855_PHY_ID 0xc0ff0410 -+ -+#define AN8855_PHY_FLAGS_EN_CALIBRATION BIT(0) -+ -+struct air_an8855_priv { -+ u8 calibration_data[4]; -+}; -+ -+static const u8 dsa_r50ohm_table[] = { -+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, -+ 127, 127, 127, 127, 127, 127, 127, 126, 122, 117, -+ 112, 109, 104, 101, 97, 94, 90, 88, 84, 80, -+ 78, 74, 72, 68, 66, 64, 61, 58, 56, 53, -+ 51, 48, 47, 44, 42, 40, 38, 36, 34, 32, -+ 31, 28, 27, 24, 24, 22, 20, 18, 16, 16, -+ 14, 12, 11, 9 -+}; -+ -+static int en8855_get_r50ohm_val(struct device *dev, const char *calib_name, -+ u8 *dest) -+{ -+ u32 shift_sel, val; -+ int ret; -+ int i; -+ -+ ret = nvmem_cell_read_u32(dev, calib_name, &val); -+ if (ret) -+ return ret; -+ -+ shift_sel = FIELD_GET(AN8855_SWITCH_EFUSE_R50O, val); -+ for (i = 0; i < ARRAY_SIZE(dsa_r50ohm_table); i++) -+ if (dsa_r50ohm_table[i] == shift_sel) -+ break; -+ -+ if (i < 8 || i >= ARRAY_SIZE(dsa_r50ohm_table)) -+ *dest = dsa_r50ohm_table[25]; -+ else -+ *dest = dsa_r50ohm_table[i - 8]; -+ -+ return 0; -+} -+ -+static int an8855_probe(struct phy_device *phydev) -+{ -+ struct device *dev = &phydev->mdio.dev; -+ struct device_node *node = dev->of_node; -+ struct air_an8855_priv *priv; -+ -+ /* If we don't have a node, skip calib */ -+ if (!node) -+ return 0; -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ phydev->priv = priv; -+ -+ return 0; -+} -+ -+static int an8855_get_downshift(struct phy_device *phydev, u8 *data) -+{ -+ int val; -+ -+ val = phy_read_paged(phydev, AN8855_PHY_PAGE_EXTENDED_1, AN8855_PHY_EXT_REG_14); -+ if (val < 0) -+ return val; -+ -+ *data = val & AN8855_PHY_EN_DOWN_SHIFT ? DOWNSHIFT_DEV_DEFAULT_COUNT : -+ DOWNSHIFT_DEV_DISABLE; -+ -+ return 0; -+} -+ -+static int an8855_set_downshift(struct phy_device *phydev, u8 cnt) -+{ -+ u16 ds = cnt != DOWNSHIFT_DEV_DISABLE ? AN8855_PHY_EN_DOWN_SHIFT : 0; -+ -+ return phy_modify_paged(phydev, AN8855_PHY_PAGE_EXTENDED_1, -+ AN8855_PHY_EXT_REG_14, AN8855_PHY_EN_DOWN_SHIFT, -+ ds); -+} -+ -+static int an8855_config_init(struct phy_device *phydev) -+{ -+ struct air_an8855_priv *priv = phydev->priv; -+ struct device *dev = &phydev->mdio.dev; -+ int ret; -+ -+ /* Enable HW auto downshift */ -+ ret = an8855_set_downshift(phydev, DOWNSHIFT_DEV_DEFAULT_COUNT); -+ if (ret) -+ return ret; -+ -+ /* Apply calibration values, if needed. -+ * AN8855_PHY_FLAGS_EN_CALIBRATION signal this. -+ */ -+ if (priv && phydev->dev_flags & AN8855_PHY_FLAGS_EN_CALIBRATION) { -+ u8 *calibration_data = priv->calibration_data; -+ -+ ret = en8855_get_r50ohm_val(dev, "tx_a", &calibration_data[0]); -+ if (ret) -+ return ret; -+ -+ ret = en8855_get_r50ohm_val(dev, "tx_b", &calibration_data[1]); -+ if (ret) -+ return ret; -+ -+ ret = en8855_get_r50ohm_val(dev, "tx_c", &calibration_data[2]); -+ if (ret) -+ return ret; -+ -+ ret = en8855_get_r50ohm_val(dev, "tx_d", &calibration_data[3]); -+ if (ret) -+ return ret; -+ -+ ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_R500HM_RSEL_TX_AB, -+ AN8855_PHY_R50OHM_RSEL_TX_A | AN8855_PHY_R50OHM_RSEL_TX_B, -+ FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_A, calibration_data[0]) | -+ FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_B, calibration_data[1])); -+ if (ret) -+ return ret; -+ ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_R500HM_RSEL_TX_CD, -+ AN8855_PHY_R50OHM_RSEL_TX_C | AN8855_PHY_R50OHM_RSEL_TX_D, -+ FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_C, calibration_data[2]) | -+ FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_D, calibration_data[3])); -+ if (ret) -+ return ret; -+ } -+ -+ /* Apply values to reduce signal noise */ -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_TX_PAIR_DLY_SEL_GBE, -+ FIELD_PREP(AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_A_GBE, 0x4) | -+ FIELD_PREP(AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_C_GBE, 0x4)); -+ if (ret) -+ return ret; -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_RXADC_CTRL, -+ AN8855_PHY_RG_AD_SAMNPLE_PHSEL_A | -+ AN8855_PHY_RG_AD_SAMNPLE_PHSEL_C); -+ if (ret) -+ return ret; -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_RXADC_REV_0, -+ FIELD_PREP(AN8855_PHY_RG_AD_RESERVE0_A, 0x1)); -+ if (ret) -+ return ret; -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_RXADC_REV_1, -+ FIELD_PREP(AN8855_PHY_RG_AD_RESERVE0_C, 0x1)); -+ if (ret) -+ return ret; -+ -+ return 0; -+} -+ -+static int an8855_get_tunable(struct phy_device *phydev, -+ struct ethtool_tunable *tuna, void *data) -+{ -+ switch (tuna->id) { -+ case ETHTOOL_PHY_DOWNSHIFT: -+ return an8855_get_downshift(phydev, data); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+static int an8855_set_tunable(struct phy_device *phydev, -+ struct ethtool_tunable *tuna, const void *data) -+{ -+ switch (tuna->id) { -+ case ETHTOOL_PHY_DOWNSHIFT: -+ return an8855_set_downshift(phydev, *(const u8 *)data); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+static int an8855_read_page(struct phy_device *phydev) -+{ -+ return __phy_read(phydev, AN8855_PHY_SELECT_PAGE); -+} -+ -+static int an8855_write_page(struct phy_device *phydev, int page) -+{ -+ return __phy_write(phydev, AN8855_PHY_SELECT_PAGE, page); -+} -+ -+static struct phy_driver an8855_driver[] = { -+{ -+ PHY_ID_MATCH_EXACT(AN8855_PHY_ID), -+ .name = "Airoha AN8855 internal PHY", -+ /* PHY_GBIT_FEATURES */ -+ .flags = PHY_IS_INTERNAL, -+ .probe = an8855_probe, -+ .config_init = an8855_config_init, -+ .soft_reset = genphy_soft_reset, -+ .get_tunable = an8855_get_tunable, -+ .set_tunable = an8855_set_tunable, -+ .suspend = genphy_suspend, -+ .resume = genphy_resume, -+ .read_page = an8855_read_page, -+ .write_page = an8855_write_page, -+}, }; -+ -+module_phy_driver(an8855_driver); -+ -+static struct mdio_device_id __maybe_unused an8855_tbl[] = { -+ { PHY_ID_MATCH_EXACT(AN8855_PHY_ID) }, -+ { } -+}; -+ -+MODULE_DEVICE_TABLE(mdio, an8855_tbl); -+ -+MODULE_DESCRIPTION("Airoha AN8855 PHY driver"); -+MODULE_AUTHOR("Christian Marangi "); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/net/phy/ar8216.c b/drivers/net/phy/ar8216.c -new file mode 100644 -index 000000000000..84b923ffc125 ---- /dev/null -+++ b/drivers/net/phy/ar8216.c -@@ -0,0 +1,2909 @@ -+/* -+ * ar8216.c: AR8216 switch driver -+ * -+ * Copyright (C) 2009 Felix Fietkau -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "ar8216.h" -+ -+extern const struct ar8xxx_chip ar8327_chip; -+extern const struct ar8xxx_chip ar8337_chip; -+ -+#define MIB_DESC_BASIC(_s , _o, _n) \ -+ { \ -+ .size = (_s), \ -+ .offset = (_o), \ -+ .name = (_n), \ -+ .type = AR8XXX_MIB_BASIC, \ -+ } -+ -+#define MIB_DESC_EXT(_s , _o, _n) \ -+ { \ -+ .size = (_s), \ -+ .offset = (_o), \ -+ .name = (_n), \ -+ .type = AR8XXX_MIB_EXTENDED, \ -+ } -+ -+static const struct ar8xxx_mib_desc ar8216_mibs[] = { -+ MIB_DESC_EXT(1, AR8216_STATS_RXBROAD, "RxBroad"), -+ MIB_DESC_EXT(1, AR8216_STATS_RXPAUSE, "RxPause"), -+ MIB_DESC_EXT(1, AR8216_STATS_RXMULTI, "RxMulti"), -+ MIB_DESC_EXT(1, AR8216_STATS_RXFCSERR, "RxFcsErr"), -+ MIB_DESC_EXT(1, AR8216_STATS_RXALIGNERR, "RxAlignErr"), -+ MIB_DESC_EXT(1, AR8216_STATS_RXRUNT, "RxRunt"), -+ MIB_DESC_EXT(1, AR8216_STATS_RXFRAGMENT, "RxFragment"), -+ MIB_DESC_EXT(1, AR8216_STATS_RX64BYTE, "Rx64Byte"), -+ MIB_DESC_EXT(1, AR8216_STATS_RX128BYTE, "Rx128Byte"), -+ MIB_DESC_EXT(1, AR8216_STATS_RX256BYTE, "Rx256Byte"), -+ MIB_DESC_EXT(1, AR8216_STATS_RX512BYTE, "Rx512Byte"), -+ MIB_DESC_EXT(1, AR8216_STATS_RX1024BYTE, "Rx1024Byte"), -+ MIB_DESC_EXT(1, AR8216_STATS_RXMAXBYTE, "RxMaxByte"), -+ MIB_DESC_EXT(1, AR8216_STATS_RXTOOLONG, "RxTooLong"), -+ MIB_DESC_BASIC(2, AR8216_STATS_RXGOODBYTE, "RxGoodByte"), -+ MIB_DESC_EXT(2, AR8216_STATS_RXBADBYTE, "RxBadByte"), -+ MIB_DESC_EXT(1, AR8216_STATS_RXOVERFLOW, "RxOverFlow"), -+ MIB_DESC_EXT(1, AR8216_STATS_FILTERED, "Filtered"), -+ MIB_DESC_EXT(1, AR8216_STATS_TXBROAD, "TxBroad"), -+ MIB_DESC_EXT(1, AR8216_STATS_TXPAUSE, "TxPause"), -+ MIB_DESC_EXT(1, AR8216_STATS_TXMULTI, "TxMulti"), -+ MIB_DESC_EXT(1, AR8216_STATS_TXUNDERRUN, "TxUnderRun"), -+ MIB_DESC_EXT(1, AR8216_STATS_TX64BYTE, "Tx64Byte"), -+ MIB_DESC_EXT(1, AR8216_STATS_TX128BYTE, "Tx128Byte"), -+ MIB_DESC_EXT(1, AR8216_STATS_TX256BYTE, "Tx256Byte"), -+ MIB_DESC_EXT(1, AR8216_STATS_TX512BYTE, "Tx512Byte"), -+ MIB_DESC_EXT(1, AR8216_STATS_TX1024BYTE, "Tx1024Byte"), -+ MIB_DESC_EXT(1, AR8216_STATS_TXMAXBYTE, "TxMaxByte"), -+ MIB_DESC_EXT(1, AR8216_STATS_TXOVERSIZE, "TxOverSize"), -+ MIB_DESC_BASIC(2, AR8216_STATS_TXBYTE, "TxByte"), -+ MIB_DESC_EXT(1, AR8216_STATS_TXCOLLISION, "TxCollision"), -+ MIB_DESC_EXT(1, AR8216_STATS_TXABORTCOL, "TxAbortCol"), -+ MIB_DESC_EXT(1, AR8216_STATS_TXMULTICOL, "TxMultiCol"), -+ MIB_DESC_EXT(1, AR8216_STATS_TXSINGLECOL, "TxSingleCol"), -+ MIB_DESC_EXT(1, AR8216_STATS_TXEXCDEFER, "TxExcDefer"), -+ MIB_DESC_EXT(1, AR8216_STATS_TXDEFER, "TxDefer"), -+ MIB_DESC_EXT(1, AR8216_STATS_TXLATECOL, "TxLateCol"), -+}; -+ -+const struct ar8xxx_mib_desc ar8236_mibs[39] = { -+ MIB_DESC_EXT(1, AR8236_STATS_RXBROAD, "RxBroad"), -+ MIB_DESC_EXT(1, AR8236_STATS_RXPAUSE, "RxPause"), -+ MIB_DESC_EXT(1, AR8236_STATS_RXMULTI, "RxMulti"), -+ MIB_DESC_EXT(1, AR8236_STATS_RXFCSERR, "RxFcsErr"), -+ MIB_DESC_EXT(1, AR8236_STATS_RXALIGNERR, "RxAlignErr"), -+ MIB_DESC_EXT(1, AR8236_STATS_RXRUNT, "RxRunt"), -+ MIB_DESC_EXT(1, AR8236_STATS_RXFRAGMENT, "RxFragment"), -+ MIB_DESC_EXT(1, AR8236_STATS_RX64BYTE, "Rx64Byte"), -+ MIB_DESC_EXT(1, AR8236_STATS_RX128BYTE, "Rx128Byte"), -+ MIB_DESC_EXT(1, AR8236_STATS_RX256BYTE, "Rx256Byte"), -+ MIB_DESC_EXT(1, AR8236_STATS_RX512BYTE, "Rx512Byte"), -+ MIB_DESC_EXT(1, AR8236_STATS_RX1024BYTE, "Rx1024Byte"), -+ MIB_DESC_EXT(1, AR8236_STATS_RX1518BYTE, "Rx1518Byte"), -+ MIB_DESC_EXT(1, AR8236_STATS_RXMAXBYTE, "RxMaxByte"), -+ MIB_DESC_EXT(1, AR8236_STATS_RXTOOLONG, "RxTooLong"), -+ MIB_DESC_BASIC(2, AR8236_STATS_RXGOODBYTE, "RxGoodByte"), -+ MIB_DESC_EXT(2, AR8236_STATS_RXBADBYTE, "RxBadByte"), -+ MIB_DESC_EXT(1, AR8236_STATS_RXOVERFLOW, "RxOverFlow"), -+ MIB_DESC_EXT(1, AR8236_STATS_FILTERED, "Filtered"), -+ MIB_DESC_EXT(1, AR8236_STATS_TXBROAD, "TxBroad"), -+ MIB_DESC_EXT(1, AR8236_STATS_TXPAUSE, "TxPause"), -+ MIB_DESC_EXT(1, AR8236_STATS_TXMULTI, "TxMulti"), -+ MIB_DESC_EXT(1, AR8236_STATS_TXUNDERRUN, "TxUnderRun"), -+ MIB_DESC_EXT(1, AR8236_STATS_TX64BYTE, "Tx64Byte"), -+ MIB_DESC_EXT(1, AR8236_STATS_TX128BYTE, "Tx128Byte"), -+ MIB_DESC_EXT(1, AR8236_STATS_TX256BYTE, "Tx256Byte"), -+ MIB_DESC_EXT(1, AR8236_STATS_TX512BYTE, "Tx512Byte"), -+ MIB_DESC_EXT(1, AR8236_STATS_TX1024BYTE, "Tx1024Byte"), -+ MIB_DESC_EXT(1, AR8236_STATS_TX1518BYTE, "Tx1518Byte"), -+ MIB_DESC_EXT(1, AR8236_STATS_TXMAXBYTE, "TxMaxByte"), -+ MIB_DESC_EXT(1, AR8236_STATS_TXOVERSIZE, "TxOverSize"), -+ MIB_DESC_BASIC(2, AR8236_STATS_TXBYTE, "TxByte"), -+ MIB_DESC_EXT(1, AR8236_STATS_TXCOLLISION, "TxCollision"), -+ MIB_DESC_EXT(1, AR8236_STATS_TXABORTCOL, "TxAbortCol"), -+ MIB_DESC_EXT(1, AR8236_STATS_TXMULTICOL, "TxMultiCol"), -+ MIB_DESC_EXT(1, AR8236_STATS_TXSINGLECOL, "TxSingleCol"), -+ MIB_DESC_EXT(1, AR8236_STATS_TXEXCDEFER, "TxExcDefer"), -+ MIB_DESC_EXT(1, AR8236_STATS_TXDEFER, "TxDefer"), -+ MIB_DESC_EXT(1, AR8236_STATS_TXLATECOL, "TxLateCol"), -+}; -+ -+static DEFINE_MUTEX(ar8xxx_dev_list_lock); -+static LIST_HEAD(ar8xxx_dev_list); -+ -+static void -+ar8xxx_mib_start(struct ar8xxx_priv *priv); -+static void -+ar8xxx_mib_stop(struct ar8xxx_priv *priv); -+ -+/* inspired by phy_poll_reset in drivers/net/phy/phy_device.c */ -+static int -+ar8xxx_phy_poll_reset(struct mii_bus *bus) -+{ -+ unsigned int sleep_msecs = 20; -+ int ret, elapsed, i; -+ -+ for (elapsed = sleep_msecs; elapsed <= 600; -+ elapsed += sleep_msecs) { -+ msleep(sleep_msecs); -+ for (i = 0; i < AR8XXX_NUM_PHYS; i++) { -+ ret = mdiobus_read(bus, i, MII_BMCR); -+ if (ret < 0) -+ return ret; -+ if (ret & BMCR_RESET) -+ break; -+ if (i == AR8XXX_NUM_PHYS - 1) { -+ usleep_range(1000, 2000); -+ return 0; -+ } -+ } -+ } -+ return -ETIMEDOUT; -+} -+ -+static int -+ar8xxx_phy_check_aneg(struct phy_device *phydev) -+{ -+ int ret; -+ -+ if (phydev->autoneg != AUTONEG_ENABLE) -+ return 0; -+ /* -+ * BMCR_ANENABLE might have been cleared -+ * by phy_init_hw in certain kernel versions -+ * therefore check for it -+ */ -+ ret = phy_read(phydev, MII_BMCR); -+ if (ret < 0) -+ return ret; -+ if (ret & BMCR_ANENABLE) -+ return 0; -+ -+ dev_info(&phydev->mdio.dev, "ANEG disabled, re-enabling ...\n"); -+ ret |= BMCR_ANENABLE | BMCR_ANRESTART; -+ return phy_write(phydev, MII_BMCR, ret); -+} -+ -+void -+ar8xxx_phy_init(struct ar8xxx_priv *priv) -+{ -+ int i; -+ struct mii_bus *bus; -+ -+ bus = priv->sw_mii_bus ?: priv->mii_bus; -+ for (i = 0; i < AR8XXX_NUM_PHYS; i++) { -+ if (priv->chip->phy_fixup) -+ priv->chip->phy_fixup(priv, i); -+ -+ /* initialize the port itself */ -+ mdiobus_write(bus, i, MII_ADVERTISE, -+ ADVERTISE_ALL | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); -+ if (ar8xxx_has_gige(priv)) -+ mdiobus_write(bus, i, MII_CTRL1000, ADVERTISE_1000FULL); -+ mdiobus_write(bus, i, MII_BMCR, BMCR_RESET | BMCR_ANENABLE); -+ } -+ -+ ar8xxx_phy_poll_reset(bus); -+} -+ -+u32 -+ar8xxx_mii_read32(struct ar8xxx_priv *priv, int phy_id, int regnum) -+{ -+ struct mii_bus *bus = priv->mii_bus; -+ u16 lo, hi; -+ -+ lo = bus->read(bus, phy_id, regnum); -+ hi = bus->read(bus, phy_id, regnum + 1); -+ -+ return (hi << 16) | lo; -+} -+ -+void -+ar8xxx_mii_write32(struct ar8xxx_priv *priv, int phy_id, int regnum, u32 val) -+{ -+ struct mii_bus *bus = priv->mii_bus; -+ u16 lo, hi; -+ -+ lo = val & 0xffff; -+ hi = (u16) (val >> 16); -+ -+ if (priv->chip->mii_lo_first) -+ { -+ bus->write(bus, phy_id, regnum, lo); -+ bus->write(bus, phy_id, regnum + 1, hi); -+ } else { -+ bus->write(bus, phy_id, regnum + 1, hi); -+ bus->write(bus, phy_id, regnum, lo); -+ } -+} -+ -+u32 -+ar8xxx_read(struct ar8xxx_priv *priv, int reg) -+{ -+ struct mii_bus *bus = priv->mii_bus; -+ u16 r1, r2, page; -+ u32 val; -+ -+ split_addr((u32) reg, &r1, &r2, &page); -+ -+ mutex_lock(&bus->mdio_lock); -+ -+ bus->write(bus, 0x18, 0, page); -+ wait_for_page_switch(); -+ val = ar8xxx_mii_read32(priv, 0x10 | r2, r1); -+ -+ mutex_unlock(&bus->mdio_lock); -+ -+ return val; -+} -+ -+void -+ar8xxx_write(struct ar8xxx_priv *priv, int reg, u32 val) -+{ -+ struct mii_bus *bus = priv->mii_bus; -+ u16 r1, r2, page; -+ -+ split_addr((u32) reg, &r1, &r2, &page); -+ -+ mutex_lock(&bus->mdio_lock); -+ -+ bus->write(bus, 0x18, 0, page); -+ wait_for_page_switch(); -+ ar8xxx_mii_write32(priv, 0x10 | r2, r1, val); -+ -+ mutex_unlock(&bus->mdio_lock); -+} -+ -+u32 -+ar8xxx_rmw(struct ar8xxx_priv *priv, int reg, u32 mask, u32 val) -+{ -+ struct mii_bus *bus = priv->mii_bus; -+ u16 r1, r2, page; -+ u32 ret; -+ -+ split_addr((u32) reg, &r1, &r2, &page); -+ -+ mutex_lock(&bus->mdio_lock); -+ -+ bus->write(bus, 0x18, 0, page); -+ wait_for_page_switch(); -+ -+ ret = ar8xxx_mii_read32(priv, 0x10 | r2, r1); -+ ret &= ~mask; -+ ret |= val; -+ ar8xxx_mii_write32(priv, 0x10 | r2, r1, ret); -+ -+ mutex_unlock(&bus->mdio_lock); -+ -+ return ret; -+} -+void -+ar8xxx_phy_dbg_read(struct ar8xxx_priv *priv, int phy_addr, -+ u16 dbg_addr, u16 *dbg_data) -+{ -+ struct mii_bus *bus = priv->mii_bus; -+ -+ mutex_lock(&bus->mdio_lock); -+ bus->write(bus, phy_addr, MII_ATH_DBG_ADDR, dbg_addr); -+ *dbg_data = bus->read(bus, phy_addr, MII_ATH_DBG_DATA); -+ mutex_unlock(&bus->mdio_lock); -+} -+ -+void -+ar8xxx_phy_dbg_write(struct ar8xxx_priv *priv, int phy_addr, -+ u16 dbg_addr, u16 dbg_data) -+{ -+ struct mii_bus *bus = priv->mii_bus; -+ -+ mutex_lock(&bus->mdio_lock); -+ bus->write(bus, phy_addr, MII_ATH_DBG_ADDR, dbg_addr); -+ bus->write(bus, phy_addr, MII_ATH_DBG_DATA, dbg_data); -+ mutex_unlock(&bus->mdio_lock); -+} -+ -+static inline void -+ar8xxx_phy_mmd_prep(struct mii_bus *bus, int phy_addr, u16 addr, u16 reg) -+{ -+ bus->write(bus, phy_addr, MII_ATH_MMD_ADDR, addr); -+ bus->write(bus, phy_addr, MII_ATH_MMD_DATA, reg); -+ bus->write(bus, phy_addr, MII_ATH_MMD_ADDR, addr | 0x4000); -+} -+ -+void -+ar8xxx_phy_mmd_write(struct ar8xxx_priv *priv, int phy_addr, u16 addr, u16 reg, u16 data) -+{ -+ struct mii_bus *bus = priv->mii_bus; -+ -+ mutex_lock(&bus->mdio_lock); -+ ar8xxx_phy_mmd_prep(bus, phy_addr, addr, reg); -+ bus->write(bus, phy_addr, MII_ATH_MMD_DATA, data); -+ mutex_unlock(&bus->mdio_lock); -+} -+ -+u16 -+ar8xxx_phy_mmd_read(struct ar8xxx_priv *priv, int phy_addr, u16 addr, u16 reg) -+{ -+ struct mii_bus *bus = priv->mii_bus; -+ u16 data; -+ -+ mutex_lock(&bus->mdio_lock); -+ ar8xxx_phy_mmd_prep(bus, phy_addr, addr, reg); -+ data = bus->read(bus, phy_addr, MII_ATH_MMD_DATA); -+ mutex_unlock(&bus->mdio_lock); -+ -+ return data; -+} -+ -+static int -+ar8xxx_reg_wait(struct ar8xxx_priv *priv, u32 reg, u32 mask, u32 val, -+ unsigned timeout) -+{ -+ int i; -+ -+ for (i = 0; i < timeout; i++) { -+ u32 t; -+ -+ t = ar8xxx_read(priv, reg); -+ if ((t & mask) == val) -+ return 0; -+ -+ usleep_range(1000, 2000); -+ cond_resched(); -+ } -+ -+ return -ETIMEDOUT; -+} -+ -+static int -+ar8xxx_mib_op(struct ar8xxx_priv *priv, u32 op) -+{ -+ unsigned mib_func = priv->chip->mib_func; -+ int ret; -+ -+ lockdep_assert_held(&priv->mib_lock); -+ -+ /* Capture the hardware statistics for all ports */ -+ ar8xxx_rmw(priv, mib_func, AR8216_MIB_FUNC, (op << AR8216_MIB_FUNC_S)); -+ -+ /* Wait for the capturing to complete. */ -+ ret = ar8xxx_reg_wait(priv, mib_func, AR8216_MIB_BUSY, 0, 10); -+ if (ret) -+ goto out; -+ -+ ret = 0; -+ -+out: -+ return ret; -+} -+ -+static int -+ar8xxx_mib_capture(struct ar8xxx_priv *priv) -+{ -+ return ar8xxx_mib_op(priv, AR8216_MIB_FUNC_CAPTURE); -+} -+ -+static int -+ar8xxx_mib_flush(struct ar8xxx_priv *priv) -+{ -+ return ar8xxx_mib_op(priv, AR8216_MIB_FUNC_FLUSH); -+} -+ -+static void -+ar8xxx_mib_fetch_port_stat(struct ar8xxx_priv *priv, int port, bool flush) -+{ -+ unsigned int base; -+ u64 *mib_stats; -+ int i; -+ -+ WARN_ON(port >= priv->dev.ports); -+ -+ lockdep_assert_held(&priv->mib_lock); -+ -+ base = priv->chip->reg_port_stats_start + -+ priv->chip->reg_port_stats_length * port; -+ -+ mib_stats = &priv->mib_stats[port * priv->chip->num_mibs]; -+ for (i = 0; i < priv->chip->num_mibs; i++) { -+ const struct ar8xxx_mib_desc *mib; -+ u64 t; -+ -+ mib = &priv->chip->mib_decs[i]; -+ if (mib->type > priv->mib_type) -+ continue; -+ t = ar8xxx_read(priv, base + mib->offset); -+ if (mib->size == 2) { -+ u64 hi; -+ -+ hi = ar8xxx_read(priv, base + mib->offset + 4); -+ t |= hi << 32; -+ } -+ -+ if (flush) -+ mib_stats[i] = 0; -+ else -+ mib_stats[i] += t; -+ cond_resched(); -+ } -+} -+ -+static void -+ar8216_read_port_link(struct ar8xxx_priv *priv, int port, -+ struct switch_port_link *link) -+{ -+ u32 status; -+ u32 speed; -+ -+ memset(link, '\0', sizeof(*link)); -+ -+ status = priv->chip->read_port_status(priv, port); -+ -+ link->aneg = !!(status & AR8216_PORT_STATUS_LINK_AUTO); -+ if (link->aneg) { -+ link->link = !!(status & AR8216_PORT_STATUS_LINK_UP); -+ } else { -+ link->link = true; -+ -+ if (priv->get_port_link) { -+ int err; -+ -+ err = priv->get_port_link(port); -+ if (err >= 0) -+ link->link = !!err; -+ } -+ } -+ -+ if (!link->link) -+ return; -+ -+ link->duplex = !!(status & AR8216_PORT_STATUS_DUPLEX); -+ link->tx_flow = !!(status & AR8216_PORT_STATUS_TXFLOW); -+ link->rx_flow = !!(status & AR8216_PORT_STATUS_RXFLOW); -+ -+ if (link->aneg && link->duplex && priv->chip->read_port_eee_status) -+ link->eee = priv->chip->read_port_eee_status(priv, port); -+ -+ speed = (status & AR8216_PORT_STATUS_SPEED) >> -+ AR8216_PORT_STATUS_SPEED_S; -+ -+ switch (speed) { -+ case AR8216_PORT_SPEED_10M: -+ link->speed = SWITCH_PORT_SPEED_10; -+ break; -+ case AR8216_PORT_SPEED_100M: -+ link->speed = SWITCH_PORT_SPEED_100; -+ break; -+ case AR8216_PORT_SPEED_1000M: -+ link->speed = SWITCH_PORT_SPEED_1000; -+ break; -+ default: -+ link->speed = SWITCH_PORT_SPEED_UNKNOWN; -+ break; -+ } -+} -+ -+#ifdef CONFIG_ETHERNET_PACKET_MANGLE -+ -+static struct sk_buff * -+ar8216_mangle_tx(struct net_device *dev, struct sk_buff *skb) -+{ -+ struct ar8xxx_priv *priv = dev->phy_ptr; -+ unsigned char *buf; -+ -+ if (unlikely(!priv)) -+ goto error; -+ -+ if (!priv->vlan) -+ goto send; -+ -+ if (unlikely(skb_headroom(skb) < 2)) { -+ if (pskb_expand_head(skb, 2, 0, GFP_ATOMIC) < 0) -+ goto error; -+ } -+ -+ buf = skb_push(skb, 2); -+ buf[0] = 0x10; -+ buf[1] = 0x80; -+ -+send: -+ return skb; -+ -+error: -+ dev_kfree_skb_any(skb); -+ return NULL; -+} -+ -+static void -+ar8216_mangle_rx(struct net_device *dev, struct sk_buff *skb) -+{ -+ struct ar8xxx_priv *priv; -+ unsigned char *buf; -+ int port, vlan; -+ -+ priv = dev->phy_ptr; -+ if (!priv) -+ return; -+ -+ /* don't strip the header if vlan mode is disabled */ -+ if (!priv->vlan) -+ return; -+ -+ /* strip header, get vlan id */ -+ buf = skb->data; -+ skb_pull(skb, 2); -+ -+ /* check for vlan header presence */ -+ if ((buf[12 + 2] != 0x81) || (buf[13 + 2] != 0x00)) -+ return; -+ -+ port = buf[0] & 0x7; -+ -+ /* no need to fix up packets coming from a tagged source */ -+ if (priv->vlan_tagged & (1 << port)) -+ return; -+ -+ /* lookup port vid from local table, the switch passes an invalid vlan id */ -+ vlan = priv->vlan_id[priv->pvid[port]]; -+ -+ buf[14 + 2] &= 0xf0; -+ buf[14 + 2] |= vlan >> 8; -+ buf[15 + 2] = vlan & 0xff; -+} -+ -+#endif -+ -+int -+ar8216_wait_bit(struct ar8xxx_priv *priv, int reg, u32 mask, u32 val) -+{ -+ int timeout = 20; -+ u32 t = 0; -+ -+ while (1) { -+ t = ar8xxx_read(priv, reg); -+ if ((t & mask) == val) -+ return 0; -+ -+ if (timeout-- <= 0) -+ break; -+ -+ udelay(10); -+ cond_resched(); -+ } -+ -+ pr_err("ar8216: timeout on reg %08x: %08x & %08x != %08x\n", -+ (unsigned int) reg, t, mask, val); -+ return -ETIMEDOUT; -+} -+ -+static void -+ar8216_vtu_op(struct ar8xxx_priv *priv, u32 op, u32 val) -+{ -+ if (ar8216_wait_bit(priv, AR8216_REG_VTU, AR8216_VTU_ACTIVE, 0)) -+ return; -+ if ((op & AR8216_VTU_OP) == AR8216_VTU_OP_LOAD) { -+ val &= AR8216_VTUDATA_MEMBER; -+ val |= AR8216_VTUDATA_VALID; -+ ar8xxx_write(priv, AR8216_REG_VTU_DATA, val); -+ } -+ op |= AR8216_VTU_ACTIVE; -+ ar8xxx_write(priv, AR8216_REG_VTU, op); -+} -+ -+static void -+ar8216_vtu_flush(struct ar8xxx_priv *priv) -+{ -+ ar8216_vtu_op(priv, AR8216_VTU_OP_FLUSH, 0); -+} -+ -+static void -+ar8216_vtu_load_vlan(struct ar8xxx_priv *priv, u32 vid, u32 port_mask) -+{ -+ u32 op; -+ -+ op = AR8216_VTU_OP_LOAD | (vid << AR8216_VTU_VID_S); -+ ar8216_vtu_op(priv, op, port_mask); -+} -+ -+static int -+ar8216_atu_flush(struct ar8xxx_priv *priv) -+{ -+ int ret; -+ -+ ret = ar8216_wait_bit(priv, AR8216_REG_ATU_FUNC0, AR8216_ATU_ACTIVE, 0); -+ if (!ret) -+ ar8xxx_write(priv, AR8216_REG_ATU_FUNC0, AR8216_ATU_OP_FLUSH | -+ AR8216_ATU_ACTIVE); -+ -+ return ret; -+} -+ -+static int -+ar8216_atu_flush_port(struct ar8xxx_priv *priv, int port) -+{ -+ u32 t; -+ int ret; -+ -+ ret = ar8216_wait_bit(priv, AR8216_REG_ATU_FUNC0, AR8216_ATU_ACTIVE, 0); -+ if (!ret) { -+ t = (port << AR8216_ATU_PORT_NUM_S) | AR8216_ATU_OP_FLUSH_PORT; -+ t |= AR8216_ATU_ACTIVE; -+ ar8xxx_write(priv, AR8216_REG_ATU_FUNC0, t); -+ } -+ -+ return ret; -+} -+ -+static u32 -+ar8216_read_port_status(struct ar8xxx_priv *priv, int port) -+{ -+ return ar8xxx_read(priv, AR8216_REG_PORT_STATUS(port)); -+} -+ -+static void -+__ar8216_setup_port(struct ar8xxx_priv *priv, int port, u32 members, -+ bool ath_hdr_en) -+{ -+ u32 header; -+ u32 egress, ingress; -+ u32 pvid; -+ -+ if (priv->vlan) { -+ pvid = priv->vlan_id[priv->pvid[port]]; -+ if (priv->vlan_tagged & (1 << port)) -+ egress = AR8216_OUT_ADD_VLAN; -+ else -+ egress = AR8216_OUT_STRIP_VLAN; -+ ingress = AR8216_IN_SECURE; -+ } else { -+ pvid = port; -+ egress = AR8216_OUT_KEEP; -+ ingress = AR8216_IN_PORT_ONLY; -+ } -+ -+ header = ath_hdr_en ? AR8216_PORT_CTRL_HEADER : 0; -+ -+ ar8xxx_rmw(priv, AR8216_REG_PORT_CTRL(port), -+ AR8216_PORT_CTRL_LEARN | AR8216_PORT_CTRL_VLAN_MODE | -+ AR8216_PORT_CTRL_SINGLE_VLAN | AR8216_PORT_CTRL_STATE | -+ AR8216_PORT_CTRL_HEADER | AR8216_PORT_CTRL_LEARN_LOCK, -+ AR8216_PORT_CTRL_LEARN | header | -+ (egress << AR8216_PORT_CTRL_VLAN_MODE_S) | -+ (AR8216_PORT_STATE_FORWARD << AR8216_PORT_CTRL_STATE_S)); -+ -+ ar8xxx_rmw(priv, AR8216_REG_PORT_VLAN(port), -+ AR8216_PORT_VLAN_DEST_PORTS | AR8216_PORT_VLAN_MODE | -+ AR8216_PORT_VLAN_DEFAULT_ID, -+ (members << AR8216_PORT_VLAN_DEST_PORTS_S) | -+ (ingress << AR8216_PORT_VLAN_MODE_S) | -+ (pvid << AR8216_PORT_VLAN_DEFAULT_ID_S)); -+} -+ -+static void -+ar8216_setup_port(struct ar8xxx_priv *priv, int port, u32 members) -+{ -+ return __ar8216_setup_port(priv, port, members, -+ chip_is_ar8216(priv) && priv->vlan && -+ port == AR8216_PORT_CPU); -+} -+ -+static int -+ar8216_hw_init(struct ar8xxx_priv *priv) -+{ -+ if (priv->initialized) -+ return 0; -+ -+ ar8xxx_write(priv, AR8216_REG_CTRL, AR8216_CTRL_RESET); -+ ar8xxx_reg_wait(priv, AR8216_REG_CTRL, AR8216_CTRL_RESET, 0, 1000); -+ -+ ar8xxx_phy_init(priv); -+ -+ priv->initialized = true; -+ return 0; -+} -+ -+static void -+ar8216_init_globals(struct ar8xxx_priv *priv) -+{ -+ /* standard atheros magic */ -+ ar8xxx_write(priv, 0x38, 0xc000050e); -+ -+ ar8xxx_rmw(priv, AR8216_REG_GLOBAL_CTRL, -+ AR8216_GCTRL_MTU, 1518 + 8 + 2); -+} -+ -+static void -+__ar8216_init_port(struct ar8xxx_priv *priv, int port, -+ bool cpu_ge, bool flow_en) -+{ -+ /* Enable port learning and tx */ -+ ar8xxx_write(priv, AR8216_REG_PORT_CTRL(port), -+ AR8216_PORT_CTRL_LEARN | -+ (4 << AR8216_PORT_CTRL_STATE_S)); -+ -+ ar8xxx_write(priv, AR8216_REG_PORT_VLAN(port), 0); -+ -+ if (port == AR8216_PORT_CPU) { -+ ar8xxx_write(priv, AR8216_REG_PORT_STATUS(port), -+ AR8216_PORT_STATUS_LINK_UP | -+ (cpu_ge ? AR8216_PORT_SPEED_1000M : AR8216_PORT_SPEED_100M) | -+ AR8216_PORT_STATUS_TXMAC | -+ AR8216_PORT_STATUS_RXMAC | -+ (flow_en ? AR8216_PORT_STATUS_RXFLOW : 0) | -+ (flow_en ? AR8216_PORT_STATUS_TXFLOW : 0) | -+ AR8216_PORT_STATUS_DUPLEX); -+ } else { -+ ar8xxx_write(priv, AR8216_REG_PORT_STATUS(port), -+ AR8216_PORT_STATUS_LINK_AUTO); -+ } -+} -+ -+static void -+ar8216_init_port(struct ar8xxx_priv *priv, int port) -+{ -+ __ar8216_init_port(priv, port, ar8xxx_has_gige(priv), -+ chip_is_ar8316(priv)); -+} -+ -+static void -+ar8216_wait_atu_ready(struct ar8xxx_priv *priv, u16 r2, u16 r1) -+{ -+ int timeout = 20; -+ -+ while (ar8xxx_mii_read32(priv, r2, r1) & AR8216_ATU_ACTIVE && --timeout) { -+ udelay(10); -+ cond_resched(); -+ } -+ -+ if (!timeout) -+ pr_err("ar8216: timeout waiting for atu to become ready\n"); -+} -+ -+static void ar8216_get_arl_entry(struct ar8xxx_priv *priv, -+ struct arl_entry *a, u32 *status, enum arl_op op) -+{ -+ struct mii_bus *bus = priv->mii_bus; -+ u16 r2, page; -+ u16 r1_func0, r1_func1, r1_func2; -+ u32 t, val0, val1, val2; -+ -+ split_addr(AR8216_REG_ATU_FUNC0, &r1_func0, &r2, &page); -+ r2 |= 0x10; -+ -+ r1_func1 = (AR8216_REG_ATU_FUNC1 >> 1) & 0x1e; -+ r1_func2 = (AR8216_REG_ATU_FUNC2 >> 1) & 0x1e; -+ -+ switch (op) { -+ case AR8XXX_ARL_INITIALIZE: -+ /* all ATU registers are on the same page -+ * therefore set page only once -+ */ -+ bus->write(bus, 0x18, 0, page); -+ wait_for_page_switch(); -+ -+ ar8216_wait_atu_ready(priv, r2, r1_func0); -+ -+ ar8xxx_mii_write32(priv, r2, r1_func0, AR8216_ATU_OP_GET_NEXT); -+ ar8xxx_mii_write32(priv, r2, r1_func1, 0); -+ ar8xxx_mii_write32(priv, r2, r1_func2, 0); -+ break; -+ case AR8XXX_ARL_GET_NEXT: -+ t = ar8xxx_mii_read32(priv, r2, r1_func0); -+ t |= AR8216_ATU_ACTIVE; -+ ar8xxx_mii_write32(priv, r2, r1_func0, t); -+ ar8216_wait_atu_ready(priv, r2, r1_func0); -+ -+ val0 = ar8xxx_mii_read32(priv, r2, r1_func0); -+ val1 = ar8xxx_mii_read32(priv, r2, r1_func1); -+ val2 = ar8xxx_mii_read32(priv, r2, r1_func2); -+ -+ *status = (val2 & AR8216_ATU_STATUS) >> AR8216_ATU_STATUS_S; -+ if (!*status) -+ break; -+ -+ a->portmap = (val2 & AR8216_ATU_PORTS) >> AR8216_ATU_PORTS_S; -+ a->mac[0] = (val0 & AR8216_ATU_ADDR5) >> AR8216_ATU_ADDR5_S; -+ a->mac[1] = (val0 & AR8216_ATU_ADDR4) >> AR8216_ATU_ADDR4_S; -+ a->mac[2] = (val1 & AR8216_ATU_ADDR3) >> AR8216_ATU_ADDR3_S; -+ a->mac[3] = (val1 & AR8216_ATU_ADDR2) >> AR8216_ATU_ADDR2_S; -+ a->mac[4] = (val1 & AR8216_ATU_ADDR1) >> AR8216_ATU_ADDR1_S; -+ a->mac[5] = (val1 & AR8216_ATU_ADDR0) >> AR8216_ATU_ADDR0_S; -+ break; -+ } -+} -+ -+static int -+ar8216_phy_read(struct ar8xxx_priv *priv, int addr, int regnum) -+{ -+ u32 t, val = 0xffff; -+ int err; -+ -+ if (addr >= AR8216_NUM_PORTS) -+ return 0xffff; -+ t = (regnum << AR8216_MDIO_CTRL_REG_ADDR_S) | -+ (addr << AR8216_MDIO_CTRL_PHY_ADDR_S) | -+ AR8216_MDIO_CTRL_MASTER_EN | -+ AR8216_MDIO_CTRL_BUSY | -+ AR8216_MDIO_CTRL_CMD_READ; -+ -+ ar8xxx_write(priv, AR8216_REG_MDIO_CTRL, t); -+ err = ar8xxx_reg_wait(priv, AR8216_REG_MDIO_CTRL, -+ AR8216_MDIO_CTRL_BUSY, 0, 5); -+ if (!err) -+ val = ar8xxx_read(priv, AR8216_REG_MDIO_CTRL); -+ -+ return val & AR8216_MDIO_CTRL_DATA_M; -+} -+ -+static int -+ar8216_phy_write(struct ar8xxx_priv *priv, int addr, int regnum, u16 val) -+{ -+ u32 t; -+ int ret; -+ -+ if (addr >= AR8216_NUM_PORTS) -+ return -EINVAL; -+ -+ t = (addr << AR8216_MDIO_CTRL_PHY_ADDR_S) | -+ (regnum << AR8216_MDIO_CTRL_REG_ADDR_S) | -+ AR8216_MDIO_CTRL_MASTER_EN | -+ AR8216_MDIO_CTRL_BUSY | -+ AR8216_MDIO_CTRL_CMD_WRITE | -+ val; -+ -+ ar8xxx_write(priv, AR8216_REG_MDIO_CTRL, t); -+ ret = ar8xxx_reg_wait(priv, AR8216_REG_MDIO_CTRL, -+ AR8216_MDIO_CTRL_BUSY, 0, 5); -+ -+ return ret; -+} -+ -+static int -+ar8229_hw_init(struct ar8xxx_priv *priv) -+{ -+ phy_interface_t phy_if_mode; -+ -+ if (priv->initialized) -+ return 0; -+ -+ ar8xxx_write(priv, AR8216_REG_CTRL, AR8216_CTRL_RESET); -+ ar8xxx_reg_wait(priv, AR8216_REG_CTRL, AR8216_CTRL_RESET, 0, 1000); -+ -+ of_get_phy_mode(priv->pdev->of_node, &phy_if_mode); -+ -+ if (phy_if_mode == PHY_INTERFACE_MODE_GMII) { -+ ar8xxx_write(priv, AR8229_REG_OPER_MODE0, -+ AR8229_OPER_MODE0_MAC_GMII_EN); -+ } else if (phy_if_mode == PHY_INTERFACE_MODE_MII) { -+ ar8xxx_write(priv, AR8229_REG_OPER_MODE0, -+ AR8229_OPER_MODE0_PHY_MII_EN); -+ } else { -+ pr_err("ar8229: unsupported mii mode\n"); -+ return -EINVAL; -+ } -+ -+ if (priv->port4_phy) { -+ ar8xxx_write(priv, AR8229_REG_OPER_MODE1, -+ AR8229_REG_OPER_MODE1_PHY4_MII_EN); -+ /* disable port5 to prevent mii conflict */ -+ ar8xxx_write(priv, AR8216_REG_PORT_STATUS(5), 0); -+ } -+ -+ ar8xxx_phy_init(priv); -+ -+ priv->initialized = true; -+ return 0; -+} -+ -+static void -+ar8229_init_globals(struct ar8xxx_priv *priv) -+{ -+ -+ /* Enable CPU port, and disable mirror port */ -+ ar8xxx_write(priv, AR8216_REG_GLOBAL_CPUPORT, -+ AR8216_GLOBAL_CPUPORT_EN | -+ (15 << AR8216_GLOBAL_CPUPORT_MIRROR_PORT_S)); -+ -+ /* Setup TAG priority mapping */ -+ ar8xxx_write(priv, AR8216_REG_TAG_PRIORITY, 0xfa50); -+ -+ /* Enable aging, MAC replacing */ -+ ar8xxx_write(priv, AR8216_REG_ATU_CTRL, -+ 0x2b /* 5 min age time */ | -+ AR8216_ATU_CTRL_AGE_EN | -+ AR8216_ATU_CTRL_LEARN_CHANGE); -+ -+ /* Enable ARP frame acknowledge */ -+ ar8xxx_reg_set(priv, AR8229_REG_QM_CTRL, -+ AR8229_QM_CTRL_ARP_EN); -+ -+ /* -+ * Enable Broadcast/unknown multicast and unicast frames -+ * transmitted to the CPU port. -+ */ -+ ar8xxx_reg_set(priv, AR8216_REG_FLOOD_MASK, -+ AR8229_FLOOD_MASK_BC_DP(0) | -+ AR8229_FLOOD_MASK_MC_DP(0) | -+ AR8229_FLOOD_MASK_UC_DP(0)); -+ -+ /* setup MTU */ -+ ar8xxx_rmw(priv, AR8216_REG_GLOBAL_CTRL, -+ AR8236_GCTRL_MTU, AR8236_GCTRL_MTU); -+ -+ /* Enable MIB counters */ -+ ar8xxx_reg_set(priv, AR8216_REG_MIB_FUNC, -+ AR8236_MIB_EN); -+ -+ /* setup Service TAG */ -+ ar8xxx_rmw(priv, AR8216_REG_SERVICE_TAG, AR8216_SERVICE_TAG_M, 0); -+} -+ -+static void -+ar8229_init_port(struct ar8xxx_priv *priv, int port) -+{ -+ __ar8216_init_port(priv, port, true, true); -+} -+ -+ -+static int -+ar7240sw_hw_init(struct ar8xxx_priv *priv) -+{ -+ if (priv->initialized) -+ return 0; -+ -+ ar8xxx_write(priv, AR8216_REG_CTRL, AR8216_CTRL_RESET); -+ ar8xxx_reg_wait(priv, AR8216_REG_CTRL, AR8216_CTRL_RESET, 0, 1000); -+ -+ priv->port4_phy = 1; -+ /* disable port5 to prevent mii conflict */ -+ ar8xxx_write(priv, AR8216_REG_PORT_STATUS(5), 0); -+ -+ ar8xxx_phy_init(priv); -+ -+ priv->initialized = true; -+ return 0; -+} -+ -+static void -+ar7240sw_init_globals(struct ar8xxx_priv *priv) -+{ -+ -+ /* Enable CPU port, and disable mirror port */ -+ ar8xxx_write(priv, AR8216_REG_GLOBAL_CPUPORT, -+ AR8216_GLOBAL_CPUPORT_EN | -+ (15 << AR8216_GLOBAL_CPUPORT_MIRROR_PORT_S)); -+ -+ /* Setup TAG priority mapping */ -+ ar8xxx_write(priv, AR8216_REG_TAG_PRIORITY, 0xfa50); -+ -+ /* Enable ARP frame acknowledge, aging, MAC replacing */ -+ ar8xxx_write(priv, AR8216_REG_ATU_CTRL, -+ AR8216_ATU_CTRL_RESERVED | -+ 0x2b /* 5 min age time */ | -+ AR8216_ATU_CTRL_AGE_EN | -+ AR8216_ATU_CTRL_ARP_EN | -+ AR8216_ATU_CTRL_LEARN_CHANGE); -+ -+ /* Enable Broadcast frames transmitted to the CPU */ -+ ar8xxx_reg_set(priv, AR8216_REG_FLOOD_MASK, -+ AR8216_FM_CPU_BROADCAST_EN); -+ -+ /* setup MTU */ -+ ar8xxx_rmw(priv, AR8216_REG_GLOBAL_CTRL, -+ AR8216_GCTRL_MTU, -+ AR8216_GCTRL_MTU); -+ -+ /* setup Service TAG */ -+ ar8xxx_rmw(priv, AR8216_REG_SERVICE_TAG, AR8216_SERVICE_TAG_M, 0); -+} -+ -+static void -+ar7240sw_setup_port(struct ar8xxx_priv *priv, int port, u32 members) -+{ -+ return __ar8216_setup_port(priv, port, members, false); -+} -+ -+static void -+ar8236_setup_port(struct ar8xxx_priv *priv, int port, u32 members) -+{ -+ u32 egress, ingress; -+ u32 pvid; -+ -+ if (priv->vlan) { -+ pvid = priv->vlan_id[priv->pvid[port]]; -+ if (priv->vlan_tagged & (1 << port)) -+ egress = AR8216_OUT_ADD_VLAN; -+ else -+ egress = AR8216_OUT_STRIP_VLAN; -+ ingress = AR8216_IN_SECURE; -+ } else { -+ pvid = port; -+ egress = AR8216_OUT_KEEP; -+ ingress = AR8216_IN_PORT_ONLY; -+ } -+ -+ ar8xxx_rmw(priv, AR8216_REG_PORT_CTRL(port), -+ AR8216_PORT_CTRL_LEARN | AR8216_PORT_CTRL_VLAN_MODE | -+ AR8216_PORT_CTRL_SINGLE_VLAN | AR8216_PORT_CTRL_STATE | -+ AR8216_PORT_CTRL_HEADER | AR8216_PORT_CTRL_LEARN_LOCK, -+ AR8216_PORT_CTRL_LEARN | -+ (egress << AR8216_PORT_CTRL_VLAN_MODE_S) | -+ (AR8216_PORT_STATE_FORWARD << AR8216_PORT_CTRL_STATE_S)); -+ -+ ar8xxx_rmw(priv, AR8236_REG_PORT_VLAN(port), -+ AR8236_PORT_VLAN_DEFAULT_ID, -+ (pvid << AR8236_PORT_VLAN_DEFAULT_ID_S)); -+ -+ ar8xxx_rmw(priv, AR8236_REG_PORT_VLAN2(port), -+ AR8236_PORT_VLAN2_VLAN_MODE | -+ AR8236_PORT_VLAN2_MEMBER, -+ (ingress << AR8236_PORT_VLAN2_VLAN_MODE_S) | -+ (members << AR8236_PORT_VLAN2_MEMBER_S)); -+} -+ -+static void -+ar8236_init_globals(struct ar8xxx_priv *priv) -+{ -+ /* enable jumbo frames */ -+ ar8xxx_rmw(priv, AR8216_REG_GLOBAL_CTRL, -+ AR8316_GCTRL_MTU, 9018 + 8 + 2); -+ -+ /* enable cpu port to receive arp frames */ -+ ar8xxx_reg_set(priv, AR8216_REG_ATU_CTRL, -+ AR8236_ATU_CTRL_RES); -+ -+ /* -+ * Enable Broadcast/unknown multicast and unicast frames -+ * transmitted to the CPU port. -+ */ -+ ar8xxx_reg_set(priv, AR8216_REG_FLOOD_MASK, -+ AR8229_FLOOD_MASK_BC_DP(0) | -+ AR8229_FLOOD_MASK_MC_DP(0) | -+ AR8229_FLOOD_MASK_UC_DP(0)); -+ -+ /* Enable MIB counters */ -+ ar8xxx_rmw(priv, AR8216_REG_MIB_FUNC, AR8216_MIB_FUNC | AR8236_MIB_EN, -+ (AR8216_MIB_FUNC_NO_OP << AR8216_MIB_FUNC_S) | -+ AR8236_MIB_EN); -+} -+ -+static int -+ar8316_hw_init(struct ar8xxx_priv *priv) -+{ -+ u32 val, newval; -+ -+ val = ar8xxx_read(priv, AR8316_REG_POSTRIP); -+ -+ if (priv->phy->interface == PHY_INTERFACE_MODE_RGMII) { -+ if (priv->port4_phy) { -+ /* value taken from Ubiquiti RouterStation Pro */ -+ newval = 0x81461bea; -+ pr_info("ar8316: Using port 4 as PHY\n"); -+ } else { -+ newval = 0x01261be2; -+ pr_info("ar8316: Using port 4 as switch port\n"); -+ } -+ } else if (priv->phy->interface == PHY_INTERFACE_MODE_GMII) { -+ /* value taken from AVM Fritz!Box 7390 sources */ -+ newval = 0x010e5b71; -+ } else { -+ /* no known value for phy interface */ -+ pr_err("ar8316: unsupported mii mode: %d.\n", -+ priv->phy->interface); -+ return -EINVAL; -+ } -+ -+ if (val == newval) -+ goto out; -+ -+ ar8xxx_write(priv, AR8316_REG_POSTRIP, newval); -+ -+ if (priv->port4_phy && -+ priv->phy->interface == PHY_INTERFACE_MODE_RGMII) { -+ /* work around for phy4 rgmii mode */ -+ ar8xxx_phy_dbg_write(priv, 4, 0x12, 0x480c); -+ /* rx delay */ -+ ar8xxx_phy_dbg_write(priv, 4, 0x0, 0x824e); -+ /* tx delay */ -+ ar8xxx_phy_dbg_write(priv, 4, 0x5, 0x3d47); -+ msleep(1000); -+ } -+ -+ ar8xxx_phy_init(priv); -+ -+out: -+ priv->initialized = true; -+ return 0; -+} -+ -+static void -+ar8316_init_globals(struct ar8xxx_priv *priv) -+{ -+ /* standard atheros magic */ -+ ar8xxx_write(priv, 0x38, 0xc000050e); -+ -+ /* enable cpu port to receive multicast and broadcast frames */ -+ ar8xxx_write(priv, AR8216_REG_FLOOD_MASK, 0x003f003f); -+ -+ /* enable jumbo frames */ -+ ar8xxx_rmw(priv, AR8216_REG_GLOBAL_CTRL, -+ AR8316_GCTRL_MTU, 9018 + 8 + 2); -+ -+ /* Enable MIB counters */ -+ ar8xxx_rmw(priv, AR8216_REG_MIB_FUNC, AR8216_MIB_FUNC | AR8236_MIB_EN, -+ (AR8216_MIB_FUNC_NO_OP << AR8216_MIB_FUNC_S) | -+ AR8236_MIB_EN); -+} -+ -+int -+ar8xxx_sw_set_vlan(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ priv->vlan = !!val->value.i; -+ return 0; -+} -+ -+int -+ar8xxx_sw_get_vlan(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ val->value.i = priv->vlan; -+ return 0; -+} -+ -+ -+int -+ar8xxx_sw_set_pvid(struct switch_dev *dev, int port, int vlan) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ -+ /* make sure no invalid PVIDs get set */ -+ -+ if (vlan < 0 || vlan >= dev->vlans || -+ port < 0 || port >= AR8X16_MAX_PORTS) -+ return -EINVAL; -+ -+ priv->pvid[port] = vlan; -+ return 0; -+} -+ -+int -+ar8xxx_sw_get_pvid(struct switch_dev *dev, int port, int *vlan) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ -+ if (port < 0 || port >= AR8X16_MAX_PORTS) -+ return -EINVAL; -+ -+ *vlan = priv->pvid[port]; -+ return 0; -+} -+ -+static int -+ar8xxx_sw_set_vid(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ -+ if (val->port_vlan >= dev->vlans) -+ return -EINVAL; -+ -+ priv->vlan_id[val->port_vlan] = val->value.i; -+ return 0; -+} -+ -+static int -+ar8xxx_sw_get_vid(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ val->value.i = priv->vlan_id[val->port_vlan]; -+ return 0; -+} -+ -+int -+ar8xxx_sw_get_port_link(struct switch_dev *dev, int port, -+ struct switch_port_link *link) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ -+ ar8216_read_port_link(priv, port, link); -+ return 0; -+} -+ -+static int -+ar8xxx_sw_get_ports(struct switch_dev *dev, struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ u8 ports; -+ int i; -+ -+ if (val->port_vlan >= dev->vlans) -+ return -EINVAL; -+ -+ ports = priv->vlan_table[val->port_vlan]; -+ val->len = 0; -+ for (i = 0; i < dev->ports; i++) { -+ struct switch_port *p; -+ -+ if (!(ports & (1 << i))) -+ continue; -+ -+ p = &val->value.ports[val->len++]; -+ p->id = i; -+ if (priv->vlan_tagged & (1 << i)) -+ p->flags = (1 << SWITCH_PORT_FLAG_TAGGED); -+ else -+ p->flags = 0; -+ } -+ return 0; -+} -+ -+static int -+ar8xxx_sw_set_ports(struct switch_dev *dev, struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ u8 *vt = &priv->vlan_table[val->port_vlan]; -+ int i, j; -+ -+ *vt = 0; -+ for (i = 0; i < val->len; i++) { -+ struct switch_port *p = &val->value.ports[i]; -+ -+ if (p->flags & (1 << SWITCH_PORT_FLAG_TAGGED)) { -+ priv->vlan_tagged |= (1 << p->id); -+ } else { -+ priv->vlan_tagged &= ~(1 << p->id); -+ priv->pvid[p->id] = val->port_vlan; -+ -+ /* make sure that an untagged port does not -+ * appear in other vlans */ -+ for (j = 0; j < dev->vlans; j++) { -+ if (j == val->port_vlan) -+ continue; -+ priv->vlan_table[j] &= ~(1 << p->id); -+ } -+ } -+ -+ *vt |= 1 << p->id; -+ } -+ return 0; -+} -+ -+static void -+ar8216_set_mirror_regs(struct ar8xxx_priv *priv) -+{ -+ int port; -+ -+ /* reset all mirror registers */ -+ ar8xxx_rmw(priv, AR8216_REG_GLOBAL_CPUPORT, -+ AR8216_GLOBAL_CPUPORT_MIRROR_PORT, -+ (0xF << AR8216_GLOBAL_CPUPORT_MIRROR_PORT_S)); -+ for (port = 0; port < AR8216_NUM_PORTS; port++) { -+ ar8xxx_reg_clear(priv, AR8216_REG_PORT_CTRL(port), -+ AR8216_PORT_CTRL_MIRROR_RX); -+ -+ ar8xxx_reg_clear(priv, AR8216_REG_PORT_CTRL(port), -+ AR8216_PORT_CTRL_MIRROR_TX); -+ } -+ -+ /* now enable mirroring if necessary */ -+ if (priv->source_port >= AR8216_NUM_PORTS || -+ priv->monitor_port >= AR8216_NUM_PORTS || -+ priv->source_port == priv->monitor_port) { -+ return; -+ } -+ -+ ar8xxx_rmw(priv, AR8216_REG_GLOBAL_CPUPORT, -+ AR8216_GLOBAL_CPUPORT_MIRROR_PORT, -+ (priv->monitor_port << AR8216_GLOBAL_CPUPORT_MIRROR_PORT_S)); -+ -+ if (priv->mirror_rx) -+ ar8xxx_reg_set(priv, AR8216_REG_PORT_CTRL(priv->source_port), -+ AR8216_PORT_CTRL_MIRROR_RX); -+ -+ if (priv->mirror_tx) -+ ar8xxx_reg_set(priv, AR8216_REG_PORT_CTRL(priv->source_port), -+ AR8216_PORT_CTRL_MIRROR_TX); -+} -+ -+static inline u32 -+ar8xxx_age_time_val(int age_time) -+{ -+ return (age_time + AR8XXX_REG_ARL_CTRL_AGE_TIME_SECS / 2) / -+ AR8XXX_REG_ARL_CTRL_AGE_TIME_SECS; -+} -+ -+static inline void -+ar8xxx_set_age_time(struct ar8xxx_priv *priv, int reg) -+{ -+ u32 age_time = ar8xxx_age_time_val(priv->arl_age_time); -+ ar8xxx_rmw(priv, reg, AR8216_ATU_CTRL_AGE_TIME, age_time << AR8216_ATU_CTRL_AGE_TIME_S); -+} -+ -+int -+ar8xxx_sw_hw_apply(struct switch_dev *dev) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ const struct ar8xxx_chip *chip = priv->chip; -+ u8 portmask[AR8X16_MAX_PORTS]; -+ int i, j; -+ -+ mutex_lock(&priv->reg_mutex); -+ /* flush all vlan translation unit entries */ -+ priv->chip->vtu_flush(priv); -+ -+ memset(portmask, 0, sizeof(portmask)); -+ if (!priv->init) { -+ /* calculate the port destination masks and load vlans -+ * into the vlan translation unit */ -+ for (j = 0; j < dev->vlans; j++) { -+ u8 vp = priv->vlan_table[j]; -+ -+ if (!vp) -+ continue; -+ -+ for (i = 0; i < dev->ports; i++) { -+ u8 mask = (1 << i); -+ if (vp & mask) -+ portmask[i] |= vp & ~mask; -+ } -+ -+ chip->vtu_load_vlan(priv, priv->vlan_id[j], -+ priv->vlan_table[j]); -+ } -+ } else { -+ /* vlan disabled: -+ * isolate all ports, but connect them to the cpu port */ -+ for (i = 0; i < dev->ports; i++) { -+ if (i == AR8216_PORT_CPU) -+ continue; -+ -+ portmask[i] = 1 << AR8216_PORT_CPU; -+ portmask[AR8216_PORT_CPU] |= (1 << i); -+ } -+ } -+ -+ /* update the port destination mask registers and tag settings */ -+ for (i = 0; i < dev->ports; i++) { -+ chip->setup_port(priv, i, portmask[i]); -+ } -+ -+ chip->set_mirror_regs(priv); -+ -+ /* set age time */ -+ if (chip->reg_arl_ctrl) -+ ar8xxx_set_age_time(priv, chip->reg_arl_ctrl); -+ -+ mutex_unlock(&priv->reg_mutex); -+ return 0; -+} -+ -+int -+ar8xxx_sw_reset_switch(struct switch_dev *dev) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ const struct ar8xxx_chip *chip = priv->chip; -+ int i; -+ -+ mutex_lock(&priv->reg_mutex); -+ memset(&priv->ar8xxx_priv_volatile, 0, sizeof(priv->ar8xxx_priv_volatile)); -+ -+ for (i = 0; i < dev->vlans; i++) -+ priv->vlan_id[i] = i; -+ -+ /* Configure all ports */ -+ for (i = 0; i < dev->ports; i++) -+ chip->init_port(priv, i); -+ -+ priv->mirror_rx = false; -+ priv->mirror_tx = false; -+ priv->source_port = 0; -+ priv->monitor_port = 0; -+ priv->arl_age_time = AR8XXX_DEFAULT_ARL_AGE_TIME; -+ -+ chip->init_globals(priv); -+ chip->atu_flush(priv); -+ -+ mutex_unlock(&priv->reg_mutex); -+ -+ return chip->sw_hw_apply(dev); -+} -+ -+int -+ar8xxx_sw_set_reset_mibs(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ unsigned int len; -+ int ret; -+ -+ if (!ar8xxx_has_mib_counters(priv)) -+ return -EOPNOTSUPP; -+ -+ mutex_lock(&priv->mib_lock); -+ -+ len = priv->dev.ports * priv->chip->num_mibs * -+ sizeof(*priv->mib_stats); -+ memset(priv->mib_stats, '\0', len); -+ ret = ar8xxx_mib_flush(priv); -+ if (ret) -+ goto unlock; -+ -+ ret = 0; -+ -+unlock: -+ mutex_unlock(&priv->mib_lock); -+ return ret; -+} -+ -+int -+ar8xxx_sw_set_mib_poll_interval(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ -+ if (!ar8xxx_has_mib_counters(priv)) -+ return -EOPNOTSUPP; -+ -+ ar8xxx_mib_stop(priv); -+ priv->mib_poll_interval = val->value.i; -+ ar8xxx_mib_start(priv); -+ -+ return 0; -+} -+ -+int -+ar8xxx_sw_get_mib_poll_interval(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ -+ if (!ar8xxx_has_mib_counters(priv)) -+ return -EOPNOTSUPP; -+ val->value.i = priv->mib_poll_interval; -+ return 0; -+} -+ -+int -+ar8xxx_sw_set_mib_type(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ -+ if (!ar8xxx_has_mib_counters(priv)) -+ return -EOPNOTSUPP; -+ priv->mib_type = val->value.i; -+ return 0; -+} -+ -+int -+ar8xxx_sw_get_mib_type(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ -+ if (!ar8xxx_has_mib_counters(priv)) -+ return -EOPNOTSUPP; -+ val->value.i = priv->mib_type; -+ return 0; -+} -+ -+int -+ar8xxx_sw_set_mirror_rx_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ -+ mutex_lock(&priv->reg_mutex); -+ priv->mirror_rx = !!val->value.i; -+ priv->chip->set_mirror_regs(priv); -+ mutex_unlock(&priv->reg_mutex); -+ -+ return 0; -+} -+ -+int -+ar8xxx_sw_get_mirror_rx_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ val->value.i = priv->mirror_rx; -+ return 0; -+} -+ -+int -+ar8xxx_sw_set_mirror_tx_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ -+ mutex_lock(&priv->reg_mutex); -+ priv->mirror_tx = !!val->value.i; -+ priv->chip->set_mirror_regs(priv); -+ mutex_unlock(&priv->reg_mutex); -+ -+ return 0; -+} -+ -+int -+ar8xxx_sw_get_mirror_tx_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ val->value.i = priv->mirror_tx; -+ return 0; -+} -+ -+int -+ar8xxx_sw_set_mirror_monitor_port(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ -+ mutex_lock(&priv->reg_mutex); -+ priv->monitor_port = val->value.i; -+ priv->chip->set_mirror_regs(priv); -+ mutex_unlock(&priv->reg_mutex); -+ -+ return 0; -+} -+ -+int -+ar8xxx_sw_get_mirror_monitor_port(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ val->value.i = priv->monitor_port; -+ return 0; -+} -+ -+int -+ar8xxx_sw_set_mirror_source_port(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ -+ mutex_lock(&priv->reg_mutex); -+ priv->source_port = val->value.i; -+ priv->chip->set_mirror_regs(priv); -+ mutex_unlock(&priv->reg_mutex); -+ -+ return 0; -+} -+ -+int -+ar8xxx_sw_get_mirror_source_port(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ val->value.i = priv->source_port; -+ return 0; -+} -+ -+int -+ar8xxx_sw_set_port_reset_mib(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ int port; -+ int ret; -+ -+ if (!ar8xxx_has_mib_counters(priv)) -+ return -EOPNOTSUPP; -+ -+ port = val->port_vlan; -+ if (port >= dev->ports) -+ return -EINVAL; -+ -+ mutex_lock(&priv->mib_lock); -+ ret = ar8xxx_mib_capture(priv); -+ if (ret) -+ goto unlock; -+ -+ ar8xxx_mib_fetch_port_stat(priv, port, true); -+ -+ ret = 0; -+ -+unlock: -+ mutex_unlock(&priv->mib_lock); -+ return ret; -+} -+ -+static void -+ar8xxx_byte_to_str(char *buf, int len, u64 byte) -+{ -+ unsigned long b; -+ const char *unit; -+ -+ if (byte >= 0x40000000) { /* 1 GiB */ -+ b = byte * 10 / 0x40000000; -+ unit = "GiB"; -+ } else if (byte >= 0x100000) { /* 1 MiB */ -+ b = byte * 10 / 0x100000; -+ unit = "MiB"; -+ } else if (byte >= 0x400) { /* 1 KiB */ -+ b = byte * 10 / 0x400; -+ unit = "KiB"; -+ } else { -+ b = byte; -+ unit = "Byte"; -+ } -+ if (strcmp(unit, "Byte")) -+ snprintf(buf, len, "%lu.%lu %s", b / 10, b % 10, unit); -+ else -+ snprintf(buf, len, "%lu %s", b, unit); -+} -+ -+int -+ar8xxx_sw_get_port_mib(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ const struct ar8xxx_chip *chip = priv->chip; -+ u64 *mib_stats, mib_data; -+ unsigned int port; -+ int ret; -+ char *buf = priv->buf; -+ char buf1[64]; -+ const char *mib_name; -+ int i, len = 0; -+ bool mib_stats_empty = true; -+ -+ if (!ar8xxx_has_mib_counters(priv) || !priv->mib_poll_interval) -+ return -EOPNOTSUPP; -+ -+ port = val->port_vlan; -+ if (port >= dev->ports) -+ return -EINVAL; -+ -+ mutex_lock(&priv->mib_lock); -+ ret = ar8xxx_mib_capture(priv); -+ if (ret) -+ goto unlock; -+ -+ ar8xxx_mib_fetch_port_stat(priv, port, false); -+ -+ len += snprintf(buf + len, sizeof(priv->buf) - len, -+ "MIB counters\n"); -+ -+ mib_stats = &priv->mib_stats[port * chip->num_mibs]; -+ for (i = 0; i < chip->num_mibs; i++) { -+ if (chip->mib_decs[i].type > priv->mib_type) -+ continue; -+ mib_name = chip->mib_decs[i].name; -+ mib_data = mib_stats[i]; -+ len += snprintf(buf + len, sizeof(priv->buf) - len, -+ "%-12s: %llu\n", mib_name, mib_data); -+ if ((!strcmp(mib_name, "TxByte") || -+ !strcmp(mib_name, "RxGoodByte")) && -+ mib_data >= 1024) { -+ ar8xxx_byte_to_str(buf1, sizeof(buf1), mib_data); -+ --len; /* discard newline at the end of buf */ -+ len += snprintf(buf + len, sizeof(priv->buf) - len, -+ " (%s)\n", buf1); -+ } -+ if (mib_stats_empty && mib_data) -+ mib_stats_empty = false; -+ } -+ -+ if (mib_stats_empty) -+ len = snprintf(buf, sizeof(priv->buf), "No MIB data"); -+ -+ val->value.s = buf; -+ val->len = len; -+ -+ ret = 0; -+ -+unlock: -+ mutex_unlock(&priv->mib_lock); -+ return ret; -+} -+ -+int -+ar8xxx_sw_set_arl_age_time(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ int age_time = val->value.i; -+ u32 age_time_val; -+ -+ if (age_time < 0) -+ return -EINVAL; -+ -+ age_time_val = ar8xxx_age_time_val(age_time); -+ if (age_time_val == 0 || age_time_val > 0xffff) -+ return -EINVAL; -+ -+ priv->arl_age_time = age_time; -+ return 0; -+} -+ -+int -+ar8xxx_sw_get_arl_age_time(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ val->value.i = priv->arl_age_time; -+ return 0; -+} -+ -+int -+ar8xxx_sw_get_arl_table(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ struct mii_bus *bus = priv->mii_bus; -+ const struct ar8xxx_chip *chip = priv->chip; -+ char *buf = priv->arl_buf; -+ int i, j, k, len = 0; -+ struct arl_entry *a, *a1; -+ u32 status; -+ -+ if (!chip->get_arl_entry) -+ return -EOPNOTSUPP; -+ -+ mutex_lock(&priv->reg_mutex); -+ mutex_lock(&bus->mdio_lock); -+ -+ chip->get_arl_entry(priv, NULL, NULL, AR8XXX_ARL_INITIALIZE); -+ -+ for(i = 0; i < AR8XXX_NUM_ARL_RECORDS; ++i) { -+ a = &priv->arl_table[i]; -+ duplicate: -+ chip->get_arl_entry(priv, a, &status, AR8XXX_ARL_GET_NEXT); -+ -+ if (!status) -+ break; -+ -+ /* avoid duplicates -+ * ARL table can include multiple valid entries -+ * per MAC, just with differing status codes -+ */ -+ for (j = 0; j < i; ++j) { -+ a1 = &priv->arl_table[j]; -+ if (!memcmp(a->mac, a1->mac, sizeof(a->mac))) { -+ /* ignore ports already seen in former entry */ -+ a->portmap &= ~a1->portmap; -+ if (!a->portmap) -+ goto duplicate; -+ } -+ } -+ } -+ -+ mutex_unlock(&bus->mdio_lock); -+ -+ len += snprintf(buf + len, sizeof(priv->arl_buf) - len, -+ "address resolution table\n"); -+ -+ if (i == AR8XXX_NUM_ARL_RECORDS) -+ len += snprintf(buf + len, sizeof(priv->arl_buf) - len, -+ "Too many entries found, displaying the first %d only!\n", -+ AR8XXX_NUM_ARL_RECORDS); -+ -+ for (j = 0; j < priv->dev.ports; ++j) { -+ for (k = 0; k < i; ++k) { -+ a = &priv->arl_table[k]; -+ if (!(a->portmap & BIT(j))) -+ continue; -+ len += snprintf(buf + len, sizeof(priv->arl_buf) - len, -+ "Port %d: MAC %02x:%02x:%02x:%02x:%02x:%02x\n", -+ j, -+ a->mac[5], a->mac[4], a->mac[3], -+ a->mac[2], a->mac[1], a->mac[0]); -+ } -+ } -+ -+ val->value.s = buf; -+ val->len = len; -+ -+ mutex_unlock(&priv->reg_mutex); -+ -+ return 0; -+} -+ -+int -+ar8xxx_sw_set_flush_arl_table(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ int ret; -+ -+ mutex_lock(&priv->reg_mutex); -+ ret = priv->chip->atu_flush(priv); -+ mutex_unlock(&priv->reg_mutex); -+ -+ return ret; -+} -+ -+int -+ar8xxx_sw_set_flush_port_arl_table(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ int port, ret; -+ -+ port = val->port_vlan; -+ if (port >= dev->ports) -+ return -EINVAL; -+ -+ mutex_lock(&priv->reg_mutex); -+ ret = priv->chip->atu_flush_port(priv, port); -+ mutex_unlock(&priv->reg_mutex); -+ -+ return ret; -+} -+ -+int -+ar8xxx_sw_get_port_stats(struct switch_dev *dev, int port, -+ struct switch_port_stats *stats) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ u64 *mib_stats; -+ -+ if (!ar8xxx_has_mib_counters(priv) || !priv->mib_poll_interval) -+ return -EOPNOTSUPP; -+ -+ if (!(priv->chip->mib_rxb_id || priv->chip->mib_txb_id)) -+ return -EOPNOTSUPP; -+ -+ if (port >= dev->ports) -+ return -EINVAL; -+ -+ mutex_lock(&priv->mib_lock); -+ -+ mib_stats = &priv->mib_stats[port * priv->chip->num_mibs]; -+ -+ stats->tx_bytes = mib_stats[priv->chip->mib_txb_id]; -+ stats->rx_bytes = mib_stats[priv->chip->mib_rxb_id]; -+ -+ mutex_unlock(&priv->mib_lock); -+ return 0; -+} -+ -+static int -+ar8xxx_phy_read(struct mii_bus *bus, int phy_addr, int reg_addr) -+{ -+ struct ar8xxx_priv *priv = bus->priv; -+ return priv->chip->phy_read(priv, phy_addr, reg_addr); -+} -+ -+static int -+ar8xxx_phy_write(struct mii_bus *bus, int phy_addr, int reg_addr, -+ u16 reg_val) -+{ -+ struct ar8xxx_priv *priv = bus->priv; -+ return priv->chip->phy_write(priv, phy_addr, reg_addr, reg_val); -+} -+ -+static const struct switch_attr ar8xxx_sw_attr_globals[] = { -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_vlan", -+ .description = "Enable VLAN mode", -+ .set = ar8xxx_sw_set_vlan, -+ .get = ar8xxx_sw_get_vlan, -+ .max = 1 -+ }, -+ { -+ .type = SWITCH_TYPE_NOVAL, -+ .name = "reset_mibs", -+ .description = "Reset all MIB counters", -+ .set = ar8xxx_sw_set_reset_mibs, -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "ar8xxx_mib_poll_interval", -+ .description = "MIB polling interval in msecs (0 to disable)", -+ .set = ar8xxx_sw_set_mib_poll_interval, -+ .get = ar8xxx_sw_get_mib_poll_interval -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "ar8xxx_mib_type", -+ .description = "MIB type (0=basic 1=extended)", -+ .set = ar8xxx_sw_set_mib_type, -+ .get = ar8xxx_sw_get_mib_type -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_mirror_rx", -+ .description = "Enable mirroring of RX packets", -+ .set = ar8xxx_sw_set_mirror_rx_enable, -+ .get = ar8xxx_sw_get_mirror_rx_enable, -+ .max = 1 -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_mirror_tx", -+ .description = "Enable mirroring of TX packets", -+ .set = ar8xxx_sw_set_mirror_tx_enable, -+ .get = ar8xxx_sw_get_mirror_tx_enable, -+ .max = 1 -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "mirror_monitor_port", -+ .description = "Mirror monitor port", -+ .set = ar8xxx_sw_set_mirror_monitor_port, -+ .get = ar8xxx_sw_get_mirror_monitor_port, -+ .max = AR8216_NUM_PORTS - 1 -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "mirror_source_port", -+ .description = "Mirror source port", -+ .set = ar8xxx_sw_set_mirror_source_port, -+ .get = ar8xxx_sw_get_mirror_source_port, -+ .max = AR8216_NUM_PORTS - 1 -+ }, -+ { -+ .type = SWITCH_TYPE_STRING, -+ .name = "arl_table", -+ .description = "Get ARL table", -+ .set = NULL, -+ .get = ar8xxx_sw_get_arl_table, -+ }, -+ { -+ .type = SWITCH_TYPE_NOVAL, -+ .name = "flush_arl_table", -+ .description = "Flush ARL table", -+ .set = ar8xxx_sw_set_flush_arl_table, -+ }, -+}; -+ -+const struct switch_attr ar8xxx_sw_attr_port[] = { -+ { -+ .type = SWITCH_TYPE_NOVAL, -+ .name = "reset_mib", -+ .description = "Reset single port MIB counters", -+ .set = ar8xxx_sw_set_port_reset_mib, -+ }, -+ { -+ .type = SWITCH_TYPE_STRING, -+ .name = "mib", -+ .description = "Get port's MIB counters", -+ .set = NULL, -+ .get = ar8xxx_sw_get_port_mib, -+ }, -+ { -+ .type = SWITCH_TYPE_NOVAL, -+ .name = "flush_arl_table", -+ .description = "Flush port's ARL table entries", -+ .set = ar8xxx_sw_set_flush_port_arl_table, -+ }, -+}; -+ -+const struct switch_attr ar8xxx_sw_attr_vlan[1] = { -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "vid", -+ .description = "VLAN ID (0-4094)", -+ .set = ar8xxx_sw_set_vid, -+ .get = ar8xxx_sw_get_vid, -+ .max = 4094, -+ }, -+}; -+ -+static const struct switch_dev_ops ar8xxx_sw_ops = { -+ .attr_global = { -+ .attr = ar8xxx_sw_attr_globals, -+ .n_attr = ARRAY_SIZE(ar8xxx_sw_attr_globals), -+ }, -+ .attr_port = { -+ .attr = ar8xxx_sw_attr_port, -+ .n_attr = ARRAY_SIZE(ar8xxx_sw_attr_port), -+ }, -+ .attr_vlan = { -+ .attr = ar8xxx_sw_attr_vlan, -+ .n_attr = ARRAY_SIZE(ar8xxx_sw_attr_vlan), -+ }, -+ .get_port_pvid = ar8xxx_sw_get_pvid, -+ .set_port_pvid = ar8xxx_sw_set_pvid, -+ .get_vlan_ports = ar8xxx_sw_get_ports, -+ .set_vlan_ports = ar8xxx_sw_set_ports, -+ .apply_config = ar8xxx_sw_hw_apply, -+ .reset_switch = ar8xxx_sw_reset_switch, -+ .get_port_link = ar8xxx_sw_get_port_link, -+ .get_port_stats = ar8xxx_sw_get_port_stats, -+}; -+ -+static const struct ar8xxx_chip ar7240sw_chip = { -+ .caps = AR8XXX_CAP_MIB_COUNTERS, -+ -+ .reg_port_stats_start = 0x20000, -+ .reg_port_stats_length = 0x100, -+ .reg_arl_ctrl = AR8216_REG_ATU_CTRL, -+ -+ .name = "Atheros AR724X/AR933X built-in", -+ .ports = AR7240SW_NUM_PORTS, -+ .vlans = AR8216_NUM_VLANS, -+ .swops = &ar8xxx_sw_ops, -+ -+ .hw_init = ar7240sw_hw_init, -+ .init_globals = ar7240sw_init_globals, -+ .init_port = ar8229_init_port, -+ .phy_read = ar8216_phy_read, -+ .phy_write = ar8216_phy_write, -+ .setup_port = ar7240sw_setup_port, -+ .read_port_status = ar8216_read_port_status, -+ .atu_flush = ar8216_atu_flush, -+ .atu_flush_port = ar8216_atu_flush_port, -+ .vtu_flush = ar8216_vtu_flush, -+ .vtu_load_vlan = ar8216_vtu_load_vlan, -+ .set_mirror_regs = ar8216_set_mirror_regs, -+ .get_arl_entry = ar8216_get_arl_entry, -+ .sw_hw_apply = ar8xxx_sw_hw_apply, -+ -+ .num_mibs = ARRAY_SIZE(ar8236_mibs), -+ .mib_decs = ar8236_mibs, -+ .mib_func = AR8216_REG_MIB_FUNC, -+ .mib_rxb_id = AR8236_MIB_RXB_ID, -+ .mib_txb_id = AR8236_MIB_TXB_ID, -+}; -+ -+static const struct ar8xxx_chip ar8216_chip = { -+ .caps = AR8XXX_CAP_MIB_COUNTERS, -+ -+ .reg_port_stats_start = 0x19000, -+ .reg_port_stats_length = 0xa0, -+ .reg_arl_ctrl = AR8216_REG_ATU_CTRL, -+ -+ .name = "Atheros AR8216", -+ .ports = AR8216_NUM_PORTS, -+ .vlans = AR8216_NUM_VLANS, -+ .swops = &ar8xxx_sw_ops, -+ -+ .hw_init = ar8216_hw_init, -+ .init_globals = ar8216_init_globals, -+ .init_port = ar8216_init_port, -+ .setup_port = ar8216_setup_port, -+ .read_port_status = ar8216_read_port_status, -+ .atu_flush = ar8216_atu_flush, -+ .atu_flush_port = ar8216_atu_flush_port, -+ .vtu_flush = ar8216_vtu_flush, -+ .vtu_load_vlan = ar8216_vtu_load_vlan, -+ .set_mirror_regs = ar8216_set_mirror_regs, -+ .get_arl_entry = ar8216_get_arl_entry, -+ .sw_hw_apply = ar8xxx_sw_hw_apply, -+ -+ .num_mibs = ARRAY_SIZE(ar8216_mibs), -+ .mib_decs = ar8216_mibs, -+ .mib_func = AR8216_REG_MIB_FUNC, -+ .mib_rxb_id = AR8216_MIB_RXB_ID, -+ .mib_txb_id = AR8216_MIB_TXB_ID, -+}; -+ -+static const struct ar8xxx_chip ar8229_chip = { -+ .caps = AR8XXX_CAP_MIB_COUNTERS, -+ -+ .reg_port_stats_start = 0x20000, -+ .reg_port_stats_length = 0x100, -+ .reg_arl_ctrl = AR8216_REG_ATU_CTRL, -+ -+ .name = "Atheros AR8229", -+ .ports = AR8216_NUM_PORTS, -+ .vlans = AR8216_NUM_VLANS, -+ .swops = &ar8xxx_sw_ops, -+ -+ .hw_init = ar8229_hw_init, -+ .init_globals = ar8229_init_globals, -+ .init_port = ar8229_init_port, -+ .phy_read = ar8216_phy_read, -+ .phy_write = ar8216_phy_write, -+ .setup_port = ar8236_setup_port, -+ .read_port_status = ar8216_read_port_status, -+ .atu_flush = ar8216_atu_flush, -+ .atu_flush_port = ar8216_atu_flush_port, -+ .vtu_flush = ar8216_vtu_flush, -+ .vtu_load_vlan = ar8216_vtu_load_vlan, -+ .set_mirror_regs = ar8216_set_mirror_regs, -+ .get_arl_entry = ar8216_get_arl_entry, -+ .sw_hw_apply = ar8xxx_sw_hw_apply, -+ -+ .num_mibs = ARRAY_SIZE(ar8236_mibs), -+ .mib_decs = ar8236_mibs, -+ .mib_func = AR8216_REG_MIB_FUNC, -+ .mib_rxb_id = AR8236_MIB_RXB_ID, -+ .mib_txb_id = AR8236_MIB_TXB_ID, -+}; -+ -+static const struct ar8xxx_chip ar8236_chip = { -+ .caps = AR8XXX_CAP_MIB_COUNTERS, -+ -+ .reg_port_stats_start = 0x20000, -+ .reg_port_stats_length = 0x100, -+ .reg_arl_ctrl = AR8216_REG_ATU_CTRL, -+ -+ .name = "Atheros AR8236", -+ .ports = AR8216_NUM_PORTS, -+ .vlans = AR8216_NUM_VLANS, -+ .swops = &ar8xxx_sw_ops, -+ -+ .hw_init = ar8216_hw_init, -+ .init_globals = ar8236_init_globals, -+ .init_port = ar8216_init_port, -+ .setup_port = ar8236_setup_port, -+ .read_port_status = ar8216_read_port_status, -+ .atu_flush = ar8216_atu_flush, -+ .atu_flush_port = ar8216_atu_flush_port, -+ .vtu_flush = ar8216_vtu_flush, -+ .vtu_load_vlan = ar8216_vtu_load_vlan, -+ .set_mirror_regs = ar8216_set_mirror_regs, -+ .get_arl_entry = ar8216_get_arl_entry, -+ .sw_hw_apply = ar8xxx_sw_hw_apply, -+ -+ .num_mibs = ARRAY_SIZE(ar8236_mibs), -+ .mib_decs = ar8236_mibs, -+ .mib_func = AR8216_REG_MIB_FUNC, -+ .mib_rxb_id = AR8236_MIB_RXB_ID, -+ .mib_txb_id = AR8236_MIB_TXB_ID, -+}; -+ -+static const struct ar8xxx_chip ar8316_chip = { -+ .caps = AR8XXX_CAP_GIGE | AR8XXX_CAP_MIB_COUNTERS, -+ -+ .reg_port_stats_start = 0x20000, -+ .reg_port_stats_length = 0x100, -+ .reg_arl_ctrl = AR8216_REG_ATU_CTRL, -+ -+ .name = "Atheros AR8316", -+ .ports = AR8216_NUM_PORTS, -+ .vlans = AR8X16_MAX_VLANS, -+ .swops = &ar8xxx_sw_ops, -+ -+ .hw_init = ar8316_hw_init, -+ .init_globals = ar8316_init_globals, -+ .init_port = ar8216_init_port, -+ .setup_port = ar8216_setup_port, -+ .read_port_status = ar8216_read_port_status, -+ .atu_flush = ar8216_atu_flush, -+ .atu_flush_port = ar8216_atu_flush_port, -+ .vtu_flush = ar8216_vtu_flush, -+ .vtu_load_vlan = ar8216_vtu_load_vlan, -+ .set_mirror_regs = ar8216_set_mirror_regs, -+ .get_arl_entry = ar8216_get_arl_entry, -+ .sw_hw_apply = ar8xxx_sw_hw_apply, -+ -+ .num_mibs = ARRAY_SIZE(ar8236_mibs), -+ .mib_decs = ar8236_mibs, -+ .mib_func = AR8216_REG_MIB_FUNC, -+ .mib_rxb_id = AR8236_MIB_RXB_ID, -+ .mib_txb_id = AR8236_MIB_TXB_ID, -+}; -+ -+static int -+ar8xxx_read_id(struct ar8xxx_priv *priv) -+{ -+ u32 val; -+ u16 id; -+ int i; -+ -+ val = ar8xxx_read(priv, AR8216_REG_CTRL); -+ if (val == ~0) -+ return -ENODEV; -+ -+ id = val & (AR8216_CTRL_REVISION | AR8216_CTRL_VERSION); -+ for (i = 0; i < AR8X16_PROBE_RETRIES; i++) { -+ u16 t; -+ -+ val = ar8xxx_read(priv, AR8216_REG_CTRL); -+ if (val == ~0) -+ return -ENODEV; -+ -+ t = val & (AR8216_CTRL_REVISION | AR8216_CTRL_VERSION); -+ if (t != id) -+ return -ENODEV; -+ } -+ -+ priv->chip_ver = (id & AR8216_CTRL_VERSION) >> AR8216_CTRL_VERSION_S; -+ priv->chip_rev = (id & AR8216_CTRL_REVISION); -+ return 0; -+} -+ -+static int -+ar8xxx_id_chip(struct ar8xxx_priv *priv) -+{ -+ int ret; -+ -+ ret = ar8xxx_read_id(priv); -+ if(ret) -+ return ret; -+ -+ switch (priv->chip_ver) { -+ case AR8XXX_VER_AR8216: -+ priv->chip = &ar8216_chip; -+ break; -+ case AR8XXX_VER_AR8236: -+ priv->chip = &ar8236_chip; -+ break; -+ case AR8XXX_VER_AR8316: -+ priv->chip = &ar8316_chip; -+ break; -+ case AR8XXX_VER_AR8327: -+ priv->chip = &ar8327_chip; -+ break; -+ case AR8XXX_VER_AR8337: -+ priv->chip = &ar8337_chip; -+ break; -+ default: -+ pr_err("ar8216: Unknown Atheros device [ver=%d, rev=%d]\n", -+ priv->chip_ver, priv->chip_rev); -+ -+ return -ENODEV; -+ } -+ -+ return 0; -+} -+ -+static void -+ar8xxx_mib_work_func(struct work_struct *work) -+{ -+ struct ar8xxx_priv *priv; -+ int err, i; -+ -+ priv = container_of(work, struct ar8xxx_priv, mib_work.work); -+ -+ mutex_lock(&priv->mib_lock); -+ -+ err = ar8xxx_mib_capture(priv); -+ if (err) -+ goto next_attempt; -+ -+ for (i = 0; i < priv->dev.ports; i++) -+ ar8xxx_mib_fetch_port_stat(priv, i, false); -+ -+next_attempt: -+ mutex_unlock(&priv->mib_lock); -+ schedule_delayed_work(&priv->mib_work, -+ msecs_to_jiffies(priv->mib_poll_interval)); -+} -+ -+static int -+ar8xxx_mib_init(struct ar8xxx_priv *priv) -+{ -+ unsigned int len; -+ -+ if (!ar8xxx_has_mib_counters(priv)) -+ return 0; -+ -+ BUG_ON(!priv->chip->mib_decs || !priv->chip->num_mibs); -+ -+ len = priv->dev.ports * priv->chip->num_mibs * -+ sizeof(*priv->mib_stats); -+ priv->mib_stats = kzalloc(len, GFP_KERNEL); -+ -+ if (!priv->mib_stats) -+ return -ENOMEM; -+ -+ return 0; -+} -+ -+static void -+ar8xxx_mib_start(struct ar8xxx_priv *priv) -+{ -+ if (!ar8xxx_has_mib_counters(priv) || !priv->mib_poll_interval) -+ return; -+ -+ schedule_delayed_work(&priv->mib_work, -+ msecs_to_jiffies(priv->mib_poll_interval)); -+} -+ -+static void -+ar8xxx_mib_stop(struct ar8xxx_priv *priv) -+{ -+ if (!ar8xxx_has_mib_counters(priv) || !priv->mib_poll_interval) -+ return; -+ -+ cancel_delayed_work_sync(&priv->mib_work); -+} -+ -+static struct ar8xxx_priv * -+ar8xxx_create(void) -+{ -+ struct ar8xxx_priv *priv; -+ -+ priv = kzalloc(sizeof(struct ar8xxx_priv), GFP_KERNEL); -+ if (priv == NULL) -+ return NULL; -+ -+ mutex_init(&priv->reg_mutex); -+ mutex_init(&priv->mib_lock); -+ INIT_DELAYED_WORK(&priv->mib_work, ar8xxx_mib_work_func); -+ -+ return priv; -+} -+ -+static void -+ar8xxx_free(struct ar8xxx_priv *priv) -+{ -+ if (priv->chip && priv->chip->cleanup) -+ priv->chip->cleanup(priv); -+ -+ kfree(priv->chip_data); -+ kfree(priv->mib_stats); -+ kfree(priv); -+} -+ -+static int -+ar8xxx_probe_switch(struct ar8xxx_priv *priv) -+{ -+ const struct ar8xxx_chip *chip; -+ struct switch_dev *swdev; -+ int ret; -+ -+ chip = priv->chip; -+ -+ swdev = &priv->dev; -+ swdev->cpu_port = AR8216_PORT_CPU; -+ swdev->name = chip->name; -+ swdev->vlans = chip->vlans; -+ swdev->ports = chip->ports; -+ swdev->ops = chip->swops; -+ -+ ret = ar8xxx_mib_init(priv); -+ if (ret) -+ return ret; -+ -+ return 0; -+} -+ -+static int -+ar8xxx_start(struct ar8xxx_priv *priv) -+{ -+ int ret; -+ -+ priv->init = true; -+ -+ ret = priv->chip->hw_init(priv); -+ if (ret) -+ return ret; -+ -+ ret = ar8xxx_sw_reset_switch(&priv->dev); -+ if (ret) -+ return ret; -+ -+ priv->init = false; -+ -+ ar8xxx_mib_start(priv); -+ -+ return 0; -+} -+ -+static int -+ar8xxx_phy_config_init(struct phy_device *phydev) -+{ -+ struct ar8xxx_priv *priv = phydev->priv; -+#ifdef CONFIG_ETHERNET_PACKET_MANGLE -+ struct net_device *dev = phydev->attached_dev; -+#endif -+ int ret; -+ -+ if (WARN_ON(!priv)) -+ return -ENODEV; -+ -+ if (priv->chip->config_at_probe) -+ return ar8xxx_phy_check_aneg(phydev); -+ -+ priv->phy = phydev; -+ -+ if (phydev->mdio.addr != 0) { -+ if (chip_is_ar8316(priv)) { -+ /* switch device has been initialized, reinit */ -+ priv->dev.ports = (AR8216_NUM_PORTS - 1); -+ priv->initialized = false; -+ priv->port4_phy = true; -+ ar8316_hw_init(priv); -+ return 0; -+ } -+ -+ return 0; -+ } -+ -+ ret = ar8xxx_start(priv); -+ if (ret) -+ return ret; -+ -+#ifdef CONFIG_ETHERNET_PACKET_MANGLE -+ /* VID fixup only needed on ar8216 */ -+ if (chip_is_ar8216(priv)) { -+ dev->phy_ptr = priv; -+ dev->priv_flags |= IFF_NO_IP_ALIGN; -+ dev->eth_mangle_rx = ar8216_mangle_rx; -+ dev->eth_mangle_tx = ar8216_mangle_tx; -+ } -+#endif -+ -+ return 0; -+} -+ -+static bool -+ar8xxx_check_link_states(struct ar8xxx_priv *priv) -+{ -+ bool link_new, changed = false; -+ u32 status; -+ int i; -+ -+ mutex_lock(&priv->reg_mutex); -+ -+ for (i = 0; i < priv->dev.ports; i++) { -+ status = priv->chip->read_port_status(priv, i); -+ link_new = !!(status & AR8216_PORT_STATUS_LINK_UP); -+ if (link_new == priv->link_up[i]) -+ continue; -+ -+ priv->link_up[i] = link_new; -+ changed = true; -+ /* flush ARL entries for this port if it went down*/ -+ if (!link_new) -+ priv->chip->atu_flush_port(priv, i); -+ dev_info(&priv->phy->mdio.dev, "Port %d is %s\n", -+ i, link_new ? "up" : "down"); -+ } -+ -+ mutex_unlock(&priv->reg_mutex); -+ -+ return changed; -+} -+ -+static int -+ar8xxx_phy_read_status(struct phy_device *phydev) -+{ -+ struct ar8xxx_priv *priv = phydev->priv; -+ struct switch_port_link link; -+ -+ /* check for switch port link changes */ -+ ar8xxx_check_link_states(priv); -+ -+ if (phydev->mdio.addr != 0) -+ return genphy_read_status(phydev); -+ -+ ar8216_read_port_link(priv, phydev->mdio.addr, &link); -+ phydev->link = !!link.link; -+ if (!phydev->link) -+ return 0; -+ -+ switch (link.speed) { -+ case SWITCH_PORT_SPEED_10: -+ phydev->speed = SPEED_10; -+ break; -+ case SWITCH_PORT_SPEED_100: -+ phydev->speed = SPEED_100; -+ break; -+ case SWITCH_PORT_SPEED_1000: -+ phydev->speed = SPEED_1000; -+ break; -+ default: -+ phydev->speed = 0; -+ } -+ phydev->duplex = link.duplex ? DUPLEX_FULL : DUPLEX_HALF; -+ -+ phydev->state = PHY_RUNNING; -+ netif_carrier_on(phydev->attached_dev); -+ if (phydev->adjust_link) -+ phydev->adjust_link(phydev->attached_dev); -+ -+ return 0; -+} -+ -+static int -+ar8xxx_phy_config_aneg(struct phy_device *phydev) -+{ -+ if (phydev->mdio.addr == 0) -+ return 0; -+ -+ return genphy_config_aneg(phydev); -+} -+ -+static int -+ar8xxx_get_features(struct phy_device *phydev) -+{ -+ struct ar8xxx_priv *priv = phydev->priv; -+ -+ linkmode_copy(phydev->supported, PHY_BASIC_FEATURES); -+ if (ar8xxx_has_gige(priv)) -+ linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, phydev->supported); -+ -+ return 0; -+} -+ -+static const u32 ar8xxx_phy_ids[] = { -+ 0x004dd033, -+ 0x004dd034, /* AR8327 */ -+ 0x004dd036, /* AR8337 */ -+ 0x004dd041, -+ 0x004dd042, -+ 0x004dd043, /* AR8236 */ -+}; -+ -+static bool -+ar8xxx_phy_match(u32 phy_id) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(ar8xxx_phy_ids); i++) -+ if (phy_id == ar8xxx_phy_ids[i]) -+ return true; -+ -+ return false; -+} -+ -+static bool -+ar8xxx_is_possible(struct mii_bus *bus) -+{ -+ unsigned int i, found_phys = 0; -+ -+ for (i = 0; i < 5; i++) { -+ u32 phy_id; -+ -+ phy_id = mdiobus_read(bus, i, MII_PHYSID1) << 16; -+ phy_id |= mdiobus_read(bus, i, MII_PHYSID2); -+ if (ar8xxx_phy_match(phy_id)) { -+ found_phys++; -+ } else if (phy_id) { -+ pr_debug("ar8xxx: unknown PHY at %s:%02x id:%08x\n", -+ dev_name(&bus->dev), i, phy_id); -+ } -+ } -+ return !!found_phys; -+} -+ -+static int -+ar8xxx_phy_probe(struct phy_device *phydev) -+{ -+ struct ar8xxx_priv *priv; -+ struct switch_dev *swdev; -+ int ret; -+ -+ /* skip PHYs at unused adresses */ -+ if (phydev->mdio.addr != 0 && phydev->mdio.addr != 3 && phydev->mdio.addr != 4) -+ return -ENODEV; -+ -+ if (!ar8xxx_is_possible(phydev->mdio.bus)) -+ return -ENODEV; -+ -+ mutex_lock(&ar8xxx_dev_list_lock); -+ list_for_each_entry(priv, &ar8xxx_dev_list, list) -+ if (priv->mii_bus == phydev->mdio.bus) -+ goto found; -+ -+ priv = ar8xxx_create(); -+ if (priv == NULL) { -+ ret = -ENOMEM; -+ goto unlock; -+ } -+ -+ priv->mii_bus = phydev->mdio.bus; -+ priv->pdev = &phydev->mdio.dev; -+ -+ ret = of_property_read_u32(priv->pdev->of_node, "qca,mib-poll-interval", -+ &priv->mib_poll_interval); -+ if (ret) -+ priv->mib_poll_interval = 0; -+ -+ ret = ar8xxx_id_chip(priv); -+ if (ret) -+ goto free_priv; -+ -+ ret = ar8xxx_probe_switch(priv); -+ if (ret) -+ goto free_priv; -+ -+ swdev = &priv->dev; -+ swdev->alias = dev_name(&priv->mii_bus->dev); -+ ret = register_switch(swdev, NULL); -+ if (ret) -+ goto free_priv; -+ -+ pr_info("%s: %s rev. %u switch registered on %s\n", -+ swdev->devname, swdev->name, priv->chip_rev, -+ dev_name(&priv->mii_bus->dev)); -+ -+ list_add(&priv->list, &ar8xxx_dev_list); -+ -+found: -+ priv->use_count++; -+ -+ if (phydev->mdio.addr == 0 && priv->chip->config_at_probe) { -+ priv->phy = phydev; -+ -+ ret = ar8xxx_start(priv); -+ if (ret) -+ goto err_unregister_switch; -+ } else if (priv->chip->phy_rgmii_set) { -+ priv->chip->phy_rgmii_set(priv, phydev); -+ } -+ -+ phydev->priv = priv; -+ -+ mutex_unlock(&ar8xxx_dev_list_lock); -+ -+ return 0; -+ -+err_unregister_switch: -+ if (--priv->use_count) -+ goto unlock; -+ -+ unregister_switch(&priv->dev); -+ -+free_priv: -+ ar8xxx_free(priv); -+unlock: -+ mutex_unlock(&ar8xxx_dev_list_lock); -+ return ret; -+} -+ -+static void -+ar8xxx_phy_detach(struct phy_device *phydev) -+{ -+ struct net_device *dev = phydev->attached_dev; -+ -+ if (!dev) -+ return; -+ -+#ifdef CONFIG_ETHERNET_PACKET_MANGLE -+ dev->phy_ptr = NULL; -+ dev->priv_flags &= ~IFF_NO_IP_ALIGN; -+ dev->eth_mangle_rx = NULL; -+ dev->eth_mangle_tx = NULL; -+#endif -+} -+ -+static void -+ar8xxx_phy_remove(struct phy_device *phydev) -+{ -+ struct ar8xxx_priv *priv = phydev->priv; -+ -+ if (WARN_ON(!priv)) -+ return; -+ -+ phydev->priv = NULL; -+ -+ mutex_lock(&ar8xxx_dev_list_lock); -+ -+ if (--priv->use_count > 0) { -+ mutex_unlock(&ar8xxx_dev_list_lock); -+ return; -+ } -+ -+ list_del(&priv->list); -+ mutex_unlock(&ar8xxx_dev_list_lock); -+ -+ unregister_switch(&priv->dev); -+ ar8xxx_mib_stop(priv); -+ ar8xxx_free(priv); -+} -+ -+static struct phy_driver ar8xxx_phy_driver[] = { -+ { -+ .phy_id = 0x004d0000, -+ .name = "Atheros AR8216/AR8236/AR8316", -+ .phy_id_mask = 0xffff0000, -+ .probe = ar8xxx_phy_probe, -+ .remove = ar8xxx_phy_remove, -+ .detach = ar8xxx_phy_detach, -+ .config_init = ar8xxx_phy_config_init, -+ .config_aneg = ar8xxx_phy_config_aneg, -+ .read_status = ar8xxx_phy_read_status, -+ .get_features = ar8xxx_get_features, -+ } -+}; -+ -+static const struct of_device_id ar8xxx_mdiodev_of_match[] = { -+ { -+ .compatible = "qca,ar7240sw", -+ .data = &ar7240sw_chip, -+ }, { -+ .compatible = "qca,ar8229", -+ .data = &ar8229_chip, -+ }, { -+ .compatible = "qca,ar8236", -+ .data = &ar8236_chip, -+ }, { -+ .compatible = "qca,ar8327", -+ .data = &ar8327_chip, -+ }, -+ { /* sentinel */ }, -+}; -+ -+static int -+ar8xxx_mdiodev_probe(struct mdio_device *mdiodev) -+{ -+ const struct of_device_id *match; -+ struct ar8xxx_priv *priv; -+ struct switch_dev *swdev; -+ struct device_node *mdio_node; -+ int ret; -+ -+ match = of_match_device(ar8xxx_mdiodev_of_match, &mdiodev->dev); -+ if (!match) -+ return -EINVAL; -+ -+ priv = ar8xxx_create(); -+ if (priv == NULL) -+ return -ENOMEM; -+ -+ priv->mii_bus = mdiodev->bus; -+ priv->pdev = &mdiodev->dev; -+ priv->chip = (const struct ar8xxx_chip *) match->data; -+ -+ ret = of_property_read_u32(priv->pdev->of_node, "qca,mib-poll-interval", -+ &priv->mib_poll_interval); -+ if (ret) -+ priv->mib_poll_interval = 0; -+ -+ ret = ar8xxx_read_id(priv); -+ if (ret) -+ goto free_priv; -+ -+ ret = ar8xxx_probe_switch(priv); -+ if (ret) -+ goto free_priv; -+ -+ if (priv->chip->phy_read && priv->chip->phy_write) { -+ priv->sw_mii_bus = devm_mdiobus_alloc(&mdiodev->dev); -+ priv->sw_mii_bus->name = "ar8xxx-mdio"; -+ priv->sw_mii_bus->read = ar8xxx_phy_read; -+ priv->sw_mii_bus->write = ar8xxx_phy_write; -+ priv->sw_mii_bus->priv = priv; -+ priv->sw_mii_bus->parent = &mdiodev->dev; -+ snprintf(priv->sw_mii_bus->id, MII_BUS_ID_SIZE, "%s", -+ dev_name(&mdiodev->dev)); -+ mdio_node = of_get_child_by_name(priv->pdev->of_node, "mdio-bus"); -+ ret = of_mdiobus_register(priv->sw_mii_bus, mdio_node); -+ if (ret) -+ goto free_priv; -+ } -+ -+ swdev = &priv->dev; -+ swdev->alias = dev_name(&mdiodev->dev); -+ -+ if (of_property_read_bool(priv->pdev->of_node, "qca,phy4-mii-enable")) { -+ priv->port4_phy = true; -+ swdev->ports--; -+ } -+ -+ ret = register_switch(swdev, NULL); -+ if (ret) -+ goto free_priv; -+ -+ pr_info("%s: %s rev. %u switch registered on %s\n", -+ swdev->devname, swdev->name, priv->chip_rev, -+ dev_name(&priv->mii_bus->dev)); -+ -+ mutex_lock(&ar8xxx_dev_list_lock); -+ list_add(&priv->list, &ar8xxx_dev_list); -+ mutex_unlock(&ar8xxx_dev_list_lock); -+ -+ priv->use_count++; -+ -+ ret = ar8xxx_start(priv); -+ if (ret) -+ goto err_unregister_switch; -+ -+ dev_set_drvdata(&mdiodev->dev, priv); -+ -+ return 0; -+ -+err_unregister_switch: -+ if (--priv->use_count) -+ return ret; -+ -+ unregister_switch(&priv->dev); -+ -+free_priv: -+ ar8xxx_free(priv); -+ return ret; -+} -+ -+static void -+ar8xxx_mdiodev_remove(struct mdio_device *mdiodev) -+{ -+ struct ar8xxx_priv *priv = dev_get_drvdata(&mdiodev->dev); -+ -+ if (WARN_ON(!priv)) -+ return; -+ -+ mutex_lock(&ar8xxx_dev_list_lock); -+ -+ if (--priv->use_count > 0) { -+ mutex_unlock(&ar8xxx_dev_list_lock); -+ return; -+ } -+ -+ list_del(&priv->list); -+ mutex_unlock(&ar8xxx_dev_list_lock); -+ -+ unregister_switch(&priv->dev); -+ ar8xxx_mib_stop(priv); -+ if(priv->sw_mii_bus) -+ mdiobus_unregister(priv->sw_mii_bus); -+ ar8xxx_free(priv); -+} -+ -+static struct mdio_driver ar8xxx_mdio_driver = { -+ .probe = ar8xxx_mdiodev_probe, -+ .remove = ar8xxx_mdiodev_remove, -+ .mdiodrv.driver = { -+ .name = "ar8xxx-switch", -+ .of_match_table = ar8xxx_mdiodev_of_match, -+ }, -+}; -+ -+static int __init ar8216_init(void) -+{ -+ int ret; -+ -+ ret = phy_drivers_register(ar8xxx_phy_driver, -+ ARRAY_SIZE(ar8xxx_phy_driver), -+ THIS_MODULE); -+ if (ret) -+ return ret; -+ -+ ret = mdio_driver_register(&ar8xxx_mdio_driver); -+ if (ret) -+ phy_drivers_unregister(ar8xxx_phy_driver, -+ ARRAY_SIZE(ar8xxx_phy_driver)); -+ -+ return ret; -+} -+module_init(ar8216_init); -+ -+static void __exit ar8216_exit(void) -+{ -+ mdio_driver_unregister(&ar8xxx_mdio_driver); -+ phy_drivers_unregister(ar8xxx_phy_driver, -+ ARRAY_SIZE(ar8xxx_phy_driver)); -+} -+module_exit(ar8216_exit); -+ -+MODULE_LICENSE("GPL"); -diff --git a/drivers/net/phy/ar8216.h b/drivers/net/phy/ar8216.h -new file mode 100644 -index 000000000000..f046b35f43fb ---- /dev/null -+++ b/drivers/net/phy/ar8216.h -@@ -0,0 +1,725 @@ -+/* -+ * ar8216.h: AR8216 switch driver -+ * -+ * Copyright (C) 2009 Felix Fietkau -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __AR8216_H -+#define __AR8216_H -+ -+#define BITS(_s, _n) (((1UL << (_n)) - 1) << _s) -+ -+#define AR8XXX_CAP_GIGE BIT(0) -+#define AR8XXX_CAP_MIB_COUNTERS BIT(1) -+ -+#define AR8XXX_NUM_PHYS 5 -+#define AR8216_PORT_CPU 0 -+#define AR8216_NUM_PORTS 6 -+#define AR8216_NUM_VLANS 16 -+#define AR7240SW_NUM_PORTS 5 -+#define AR8316_NUM_VLANS 4096 -+ -+/* size of the vlan table */ -+#define AR8X16_MAX_VLANS 128 -+#define AR83X7_MAX_VLANS 4096 -+#define AR8XXX_MAX_VLANS AR83X7_MAX_VLANS -+ -+#define AR8X16_PROBE_RETRIES 10 -+#define AR8X16_MAX_PORTS 8 -+ -+#define AR8XXX_REG_ARL_CTRL_AGE_TIME_SECS 7 -+#define AR8XXX_DEFAULT_ARL_AGE_TIME 300 -+ -+/* Atheros specific MII registers */ -+#define MII_ATH_MMD_ADDR 0x0d -+#define MII_ATH_MMD_DATA 0x0e -+#define MII_ATH_DBG_ADDR 0x1d -+#define MII_ATH_DBG_DATA 0x1e -+ -+#define AR8216_REG_CTRL 0x0000 -+#define AR8216_CTRL_REVISION BITS(0, 8) -+#define AR8216_CTRL_REVISION_S 0 -+#define AR8216_CTRL_VERSION BITS(8, 8) -+#define AR8216_CTRL_VERSION_S 8 -+#define AR8216_CTRL_RESET BIT(31) -+ -+#define AR8216_REG_FLOOD_MASK 0x002C -+#define AR8216_FM_UNI_DEST_PORTS BITS(0, 6) -+#define AR8216_FM_MULTI_DEST_PORTS BITS(16, 6) -+#define AR8216_FM_CPU_BROADCAST_EN BIT(26) -+#define AR8229_FLOOD_MASK_UC_DP(_p) BIT(_p) -+#define AR8229_FLOOD_MASK_MC_DP(_p) BIT(16 + (_p)) -+#define AR8229_FLOOD_MASK_BC_DP(_p) BIT(25 + (_p)) -+ -+#define AR8216_REG_GLOBAL_CTRL 0x0030 -+#define AR8216_GCTRL_MTU BITS(0, 11) -+#define AR8236_GCTRL_MTU BITS(0, 14) -+#define AR8316_GCTRL_MTU BITS(0, 14) -+ -+#define AR8216_REG_VTU 0x0040 -+#define AR8216_VTU_OP BITS(0, 3) -+#define AR8216_VTU_OP_NOOP 0x0 -+#define AR8216_VTU_OP_FLUSH 0x1 -+#define AR8216_VTU_OP_LOAD 0x2 -+#define AR8216_VTU_OP_PURGE 0x3 -+#define AR8216_VTU_OP_REMOVE_PORT 0x4 -+#define AR8216_VTU_ACTIVE BIT(3) -+#define AR8216_VTU_FULL BIT(4) -+#define AR8216_VTU_PORT BITS(8, 4) -+#define AR8216_VTU_PORT_S 8 -+#define AR8216_VTU_VID BITS(16, 12) -+#define AR8216_VTU_VID_S 16 -+#define AR8216_VTU_PRIO BITS(28, 3) -+#define AR8216_VTU_PRIO_S 28 -+#define AR8216_VTU_PRIO_EN BIT(31) -+ -+#define AR8216_REG_VTU_DATA 0x0044 -+#define AR8216_VTUDATA_MEMBER BITS(0, 10) -+#define AR8236_VTUDATA_MEMBER BITS(0, 7) -+#define AR8216_VTUDATA_VALID BIT(11) -+ -+#define AR8216_REG_ATU_FUNC0 0x0050 -+#define AR8216_ATU_OP BITS(0, 3) -+#define AR8216_ATU_OP_NOOP 0x0 -+#define AR8216_ATU_OP_FLUSH 0x1 -+#define AR8216_ATU_OP_LOAD 0x2 -+#define AR8216_ATU_OP_PURGE 0x3 -+#define AR8216_ATU_OP_FLUSH_UNLOCKED 0x4 -+#define AR8216_ATU_OP_FLUSH_PORT 0x5 -+#define AR8216_ATU_OP_GET_NEXT 0x6 -+#define AR8216_ATU_ACTIVE BIT(3) -+#define AR8216_ATU_PORT_NUM BITS(8, 4) -+#define AR8216_ATU_PORT_NUM_S 8 -+#define AR8216_ATU_FULL_VIO BIT(12) -+#define AR8216_ATU_ADDR5 BITS(16, 8) -+#define AR8216_ATU_ADDR5_S 16 -+#define AR8216_ATU_ADDR4 BITS(24, 8) -+#define AR8216_ATU_ADDR4_S 24 -+ -+#define AR8216_REG_ATU_FUNC1 0x0054 -+#define AR8216_ATU_ADDR3 BITS(0, 8) -+#define AR8216_ATU_ADDR3_S 0 -+#define AR8216_ATU_ADDR2 BITS(8, 8) -+#define AR8216_ATU_ADDR2_S 8 -+#define AR8216_ATU_ADDR1 BITS(16, 8) -+#define AR8216_ATU_ADDR1_S 16 -+#define AR8216_ATU_ADDR0 BITS(24, 8) -+#define AR8216_ATU_ADDR0_S 24 -+ -+#define AR8216_REG_ATU_FUNC2 0x0058 -+#define AR8216_ATU_PORTS BITS(0, 6) -+#define AR8216_ATU_PORTS_S 0 -+#define AR8216_ATU_PORT0 BIT(0) -+#define AR8216_ATU_PORT1 BIT(1) -+#define AR8216_ATU_PORT2 BIT(2) -+#define AR8216_ATU_PORT3 BIT(3) -+#define AR8216_ATU_PORT4 BIT(4) -+#define AR8216_ATU_PORT5 BIT(5) -+#define AR8216_ATU_STATUS BITS(16, 4) -+#define AR8216_ATU_STATUS_S 16 -+ -+#define AR8216_REG_ATU_CTRL 0x005C -+#define AR8216_ATU_CTRL_AGE_EN BIT(17) -+#define AR8216_ATU_CTRL_AGE_TIME BITS(0, 16) -+#define AR8216_ATU_CTRL_AGE_TIME_S 0 -+#define AR8236_ATU_CTRL_RES BIT(20) -+#define AR8216_ATU_CTRL_LEARN_CHANGE BIT(18) -+#define AR8216_ATU_CTRL_RESERVED BIT(19) -+#define AR8216_ATU_CTRL_ARP_EN BIT(20) -+ -+#define AR8216_REG_TAG_PRIORITY 0x0070 -+ -+#define AR8216_REG_SERVICE_TAG 0x0074 -+#define AR8216_SERVICE_TAG_M BITS(0, 16) -+ -+#define AR8216_REG_MIB_FUNC 0x0080 -+#define AR8216_MIB_TIMER BITS(0, 16) -+#define AR8216_MIB_AT_HALF_EN BIT(16) -+#define AR8216_MIB_BUSY BIT(17) -+#define AR8216_MIB_FUNC BITS(24, 3) -+#define AR8216_MIB_FUNC_S 24 -+#define AR8216_MIB_FUNC_NO_OP 0x0 -+#define AR8216_MIB_FUNC_FLUSH 0x1 -+#define AR8216_MIB_FUNC_CAPTURE 0x3 -+#define AR8236_MIB_EN BIT(30) -+ -+#define AR8216_REG_GLOBAL_CPUPORT 0x0078 -+#define AR8216_GLOBAL_CPUPORT_MIRROR_PORT BITS(4, 4) -+#define AR8216_GLOBAL_CPUPORT_MIRROR_PORT_S 4 -+#define AR8216_GLOBAL_CPUPORT_EN BIT(8) -+ -+#define AR8216_REG_MDIO_CTRL 0x98 -+#define AR8216_MDIO_CTRL_DATA_M BITS(0, 16) -+#define AR8216_MDIO_CTRL_REG_ADDR_S 16 -+#define AR8216_MDIO_CTRL_PHY_ADDR_S 21 -+#define AR8216_MDIO_CTRL_CMD_WRITE 0 -+#define AR8216_MDIO_CTRL_CMD_READ BIT(27) -+#define AR8216_MDIO_CTRL_MASTER_EN BIT(30) -+#define AR8216_MDIO_CTRL_BUSY BIT(31) -+ -+#define AR8216_PORT_OFFSET(_i) (0x0100 * (_i + 1)) -+#define AR8216_REG_PORT_STATUS(_i) (AR8216_PORT_OFFSET(_i) + 0x0000) -+#define AR8216_PORT_STATUS_SPEED BITS(0,2) -+#define AR8216_PORT_STATUS_SPEED_S 0 -+#define AR8216_PORT_STATUS_TXMAC BIT(2) -+#define AR8216_PORT_STATUS_RXMAC BIT(3) -+#define AR8216_PORT_STATUS_TXFLOW BIT(4) -+#define AR8216_PORT_STATUS_RXFLOW BIT(5) -+#define AR8216_PORT_STATUS_DUPLEX BIT(6) -+#define AR8216_PORT_STATUS_LINK_UP BIT(8) -+#define AR8216_PORT_STATUS_LINK_AUTO BIT(9) -+#define AR8216_PORT_STATUS_LINK_PAUSE BIT(10) -+#define AR8216_PORT_STATUS_FLOW_CONTROL BIT(12) -+ -+#define AR8216_REG_PORT_CTRL(_i) (AR8216_PORT_OFFSET(_i) + 0x0004) -+ -+/* port forwarding state */ -+#define AR8216_PORT_CTRL_STATE BITS(0, 3) -+#define AR8216_PORT_CTRL_STATE_S 0 -+ -+#define AR8216_PORT_CTRL_LEARN_LOCK BIT(7) -+ -+/* egress 802.1q mode */ -+#define AR8216_PORT_CTRL_VLAN_MODE BITS(8, 2) -+#define AR8216_PORT_CTRL_VLAN_MODE_S 8 -+ -+#define AR8216_PORT_CTRL_IGMP_SNOOP BIT(10) -+#define AR8216_PORT_CTRL_HEADER BIT(11) -+#define AR8216_PORT_CTRL_MAC_LOOP BIT(12) -+#define AR8216_PORT_CTRL_SINGLE_VLAN BIT(13) -+#define AR8216_PORT_CTRL_LEARN BIT(14) -+#define AR8216_PORT_CTRL_MIRROR_TX BIT(16) -+#define AR8216_PORT_CTRL_MIRROR_RX BIT(17) -+ -+#define AR8216_REG_PORT_VLAN(_i) (AR8216_PORT_OFFSET(_i) + 0x0008) -+ -+#define AR8216_PORT_VLAN_DEFAULT_ID BITS(0, 12) -+#define AR8216_PORT_VLAN_DEFAULT_ID_S 0 -+ -+#define AR8216_PORT_VLAN_DEST_PORTS BITS(16, 9) -+#define AR8216_PORT_VLAN_DEST_PORTS_S 16 -+ -+/* bit0 added to the priority field of egress frames */ -+#define AR8216_PORT_VLAN_TX_PRIO BIT(27) -+ -+/* port default priority */ -+#define AR8216_PORT_VLAN_PRIORITY BITS(28, 2) -+#define AR8216_PORT_VLAN_PRIORITY_S 28 -+ -+/* ingress 802.1q mode */ -+#define AR8216_PORT_VLAN_MODE BITS(30, 2) -+#define AR8216_PORT_VLAN_MODE_S 30 -+ -+#define AR8216_REG_PORT_RATE(_i) (AR8216_PORT_OFFSET(_i) + 0x000c) -+#define AR8216_REG_PORT_PRIO(_i) (AR8216_PORT_OFFSET(_i) + 0x0010) -+ -+#define AR8216_STATS_RXBROAD 0x00 -+#define AR8216_STATS_RXPAUSE 0x04 -+#define AR8216_STATS_RXMULTI 0x08 -+#define AR8216_STATS_RXFCSERR 0x0c -+#define AR8216_STATS_RXALIGNERR 0x10 -+#define AR8216_STATS_RXRUNT 0x14 -+#define AR8216_STATS_RXFRAGMENT 0x18 -+#define AR8216_STATS_RX64BYTE 0x1c -+#define AR8216_STATS_RX128BYTE 0x20 -+#define AR8216_STATS_RX256BYTE 0x24 -+#define AR8216_STATS_RX512BYTE 0x28 -+#define AR8216_STATS_RX1024BYTE 0x2c -+#define AR8216_STATS_RXMAXBYTE 0x30 -+#define AR8216_STATS_RXTOOLONG 0x34 -+#define AR8216_STATS_RXGOODBYTE 0x38 -+#define AR8216_STATS_RXBADBYTE 0x40 -+#define AR8216_STATS_RXOVERFLOW 0x48 -+#define AR8216_STATS_FILTERED 0x4c -+#define AR8216_STATS_TXBROAD 0x50 -+#define AR8216_STATS_TXPAUSE 0x54 -+#define AR8216_STATS_TXMULTI 0x58 -+#define AR8216_STATS_TXUNDERRUN 0x5c -+#define AR8216_STATS_TX64BYTE 0x60 -+#define AR8216_STATS_TX128BYTE 0x64 -+#define AR8216_STATS_TX256BYTE 0x68 -+#define AR8216_STATS_TX512BYTE 0x6c -+#define AR8216_STATS_TX1024BYTE 0x70 -+#define AR8216_STATS_TXMAXBYTE 0x74 -+#define AR8216_STATS_TXOVERSIZE 0x78 -+#define AR8216_STATS_TXBYTE 0x7c -+#define AR8216_STATS_TXCOLLISION 0x84 -+#define AR8216_STATS_TXABORTCOL 0x88 -+#define AR8216_STATS_TXMULTICOL 0x8c -+#define AR8216_STATS_TXSINGLECOL 0x90 -+#define AR8216_STATS_TXEXCDEFER 0x94 -+#define AR8216_STATS_TXDEFER 0x98 -+#define AR8216_STATS_TXLATECOL 0x9c -+ -+#define AR8216_MIB_RXB_ID 14 /* RxGoodByte */ -+#define AR8216_MIB_TXB_ID 29 /* TxByte */ -+ -+#define AR8229_REG_OPER_MODE0 0x04 -+#define AR8229_OPER_MODE0_MAC_GMII_EN BIT(6) -+#define AR8229_OPER_MODE0_PHY_MII_EN BIT(10) -+ -+#define AR8229_REG_OPER_MODE1 0x08 -+#define AR8229_REG_OPER_MODE1_PHY4_MII_EN BIT(28) -+ -+#define AR8229_REG_QM_CTRL 0x3c -+#define AR8229_QM_CTRL_ARP_EN BIT(15) -+ -+#define AR8236_REG_PORT_VLAN(_i) (AR8216_PORT_OFFSET((_i)) + 0x0008) -+#define AR8236_PORT_VLAN_DEFAULT_ID BITS(16, 12) -+#define AR8236_PORT_VLAN_DEFAULT_ID_S 16 -+#define AR8236_PORT_VLAN_PRIORITY BITS(29, 3) -+#define AR8236_PORT_VLAN_PRIORITY_S 28 -+ -+#define AR8236_REG_PORT_VLAN2(_i) (AR8216_PORT_OFFSET((_i)) + 0x000c) -+#define AR8236_PORT_VLAN2_MEMBER BITS(16, 7) -+#define AR8236_PORT_VLAN2_MEMBER_S 16 -+#define AR8236_PORT_VLAN2_TX_PRIO BIT(23) -+#define AR8236_PORT_VLAN2_VLAN_MODE BITS(30, 2) -+#define AR8236_PORT_VLAN2_VLAN_MODE_S 30 -+ -+#define AR8236_STATS_RXBROAD 0x00 -+#define AR8236_STATS_RXPAUSE 0x04 -+#define AR8236_STATS_RXMULTI 0x08 -+#define AR8236_STATS_RXFCSERR 0x0c -+#define AR8236_STATS_RXALIGNERR 0x10 -+#define AR8236_STATS_RXRUNT 0x14 -+#define AR8236_STATS_RXFRAGMENT 0x18 -+#define AR8236_STATS_RX64BYTE 0x1c -+#define AR8236_STATS_RX128BYTE 0x20 -+#define AR8236_STATS_RX256BYTE 0x24 -+#define AR8236_STATS_RX512BYTE 0x28 -+#define AR8236_STATS_RX1024BYTE 0x2c -+#define AR8236_STATS_RX1518BYTE 0x30 -+#define AR8236_STATS_RXMAXBYTE 0x34 -+#define AR8236_STATS_RXTOOLONG 0x38 -+#define AR8236_STATS_RXGOODBYTE 0x3c -+#define AR8236_STATS_RXBADBYTE 0x44 -+#define AR8236_STATS_RXOVERFLOW 0x4c -+#define AR8236_STATS_FILTERED 0x50 -+#define AR8236_STATS_TXBROAD 0x54 -+#define AR8236_STATS_TXPAUSE 0x58 -+#define AR8236_STATS_TXMULTI 0x5c -+#define AR8236_STATS_TXUNDERRUN 0x60 -+#define AR8236_STATS_TX64BYTE 0x64 -+#define AR8236_STATS_TX128BYTE 0x68 -+#define AR8236_STATS_TX256BYTE 0x6c -+#define AR8236_STATS_TX512BYTE 0x70 -+#define AR8236_STATS_TX1024BYTE 0x74 -+#define AR8236_STATS_TX1518BYTE 0x78 -+#define AR8236_STATS_TXMAXBYTE 0x7c -+#define AR8236_STATS_TXOVERSIZE 0x80 -+#define AR8236_STATS_TXBYTE 0x84 -+#define AR8236_STATS_TXCOLLISION 0x8c -+#define AR8236_STATS_TXABORTCOL 0x90 -+#define AR8236_STATS_TXMULTICOL 0x94 -+#define AR8236_STATS_TXSINGLECOL 0x98 -+#define AR8236_STATS_TXEXCDEFER 0x9c -+#define AR8236_STATS_TXDEFER 0xa0 -+#define AR8236_STATS_TXLATECOL 0xa4 -+ -+#define AR8236_MIB_RXB_ID 15 /* RxGoodByte */ -+#define AR8236_MIB_TXB_ID 31 /* TxByte */ -+ -+#define AR8316_REG_POSTRIP 0x0008 -+#define AR8316_POSTRIP_MAC0_GMII_EN BIT(0) -+#define AR8316_POSTRIP_MAC0_RGMII_EN BIT(1) -+#define AR8316_POSTRIP_PHY4_GMII_EN BIT(2) -+#define AR8316_POSTRIP_PHY4_RGMII_EN BIT(3) -+#define AR8316_POSTRIP_MAC0_MAC_MODE BIT(4) -+#define AR8316_POSTRIP_RTL_MODE BIT(5) -+#define AR8316_POSTRIP_RGMII_RXCLK_DELAY_EN BIT(6) -+#define AR8316_POSTRIP_RGMII_TXCLK_DELAY_EN BIT(7) -+#define AR8316_POSTRIP_SERDES_EN BIT(8) -+#define AR8316_POSTRIP_SEL_ANA_RST BIT(9) -+#define AR8316_POSTRIP_GATE_25M_EN BIT(10) -+#define AR8316_POSTRIP_SEL_CLK25M BIT(11) -+#define AR8316_POSTRIP_HIB_PULSE_HW BIT(12) -+#define AR8316_POSTRIP_DBG_MODE_I BIT(13) -+#define AR8316_POSTRIP_MAC5_MAC_MODE BIT(14) -+#define AR8316_POSTRIP_MAC5_PHY_MODE BIT(15) -+#define AR8316_POSTRIP_POWER_DOWN_HW BIT(16) -+#define AR8316_POSTRIP_LPW_STATE_EN BIT(17) -+#define AR8316_POSTRIP_MAN_EN BIT(18) -+#define AR8316_POSTRIP_PHY_PLL_ON BIT(19) -+#define AR8316_POSTRIP_LPW_EXIT BIT(20) -+#define AR8316_POSTRIP_TXDELAY_S0 BIT(21) -+#define AR8316_POSTRIP_TXDELAY_S1 BIT(22) -+#define AR8316_POSTRIP_RXDELAY_S0 BIT(23) -+#define AR8316_POSTRIP_LED_OPEN_EN BIT(24) -+#define AR8316_POSTRIP_SPI_EN BIT(25) -+#define AR8316_POSTRIP_RXDELAY_S1 BIT(26) -+#define AR8316_POSTRIP_POWER_ON_SEL BIT(31) -+ -+/* port speed */ -+enum { -+ AR8216_PORT_SPEED_10M = 0, -+ AR8216_PORT_SPEED_100M = 1, -+ AR8216_PORT_SPEED_1000M = 2, -+ AR8216_PORT_SPEED_ERR = 3, -+}; -+ -+/* ingress 802.1q mode */ -+enum { -+ AR8216_IN_PORT_ONLY = 0, -+ AR8216_IN_PORT_FALLBACK = 1, -+ AR8216_IN_VLAN_ONLY = 2, -+ AR8216_IN_SECURE = 3 -+}; -+ -+/* egress 802.1q mode */ -+enum { -+ AR8216_OUT_KEEP = 0, -+ AR8216_OUT_STRIP_VLAN = 1, -+ AR8216_OUT_ADD_VLAN = 2 -+}; -+ -+/* port forwarding state */ -+enum { -+ AR8216_PORT_STATE_DISABLED = 0, -+ AR8216_PORT_STATE_BLOCK = 1, -+ AR8216_PORT_STATE_LISTEN = 2, -+ AR8216_PORT_STATE_LEARN = 3, -+ AR8216_PORT_STATE_FORWARD = 4 -+}; -+ -+/* mib counter type */ -+enum { -+ AR8XXX_MIB_BASIC = 0, -+ AR8XXX_MIB_EXTENDED = 1 -+}; -+ -+enum { -+ AR8XXX_VER_AR8216 = 0x01, -+ AR8XXX_VER_AR8236 = 0x03, -+ AR8XXX_VER_AR8316 = 0x10, -+ AR8XXX_VER_AR8327 = 0x12, -+ AR8XXX_VER_AR8337 = 0x13, -+}; -+ -+#define AR8XXX_NUM_ARL_RECORDS 100 -+ -+enum arl_op { -+ AR8XXX_ARL_INITIALIZE, -+ AR8XXX_ARL_GET_NEXT -+}; -+ -+struct arl_entry { -+ u16 portmap; -+ u8 mac[6]; -+}; -+ -+struct ar8xxx_priv; -+ -+struct ar8xxx_mib_desc { -+ unsigned int size; -+ unsigned int offset; -+ const char *name; -+ u8 type; -+}; -+ -+struct ar8xxx_chip { -+ unsigned long caps; -+ bool config_at_probe; -+ bool mii_lo_first; -+ -+ /* parameters to calculate REG_PORT_STATS_BASE */ -+ unsigned reg_port_stats_start; -+ unsigned reg_port_stats_length; -+ -+ unsigned reg_arl_ctrl; -+ -+ int (*hw_init)(struct ar8xxx_priv *priv); -+ void (*cleanup)(struct ar8xxx_priv *priv); -+ -+ const char *name; -+ int vlans; -+ int ports; -+ const struct switch_dev_ops *swops; -+ -+ void (*init_globals)(struct ar8xxx_priv *priv); -+ void (*init_port)(struct ar8xxx_priv *priv, int port); -+ void (*setup_port)(struct ar8xxx_priv *priv, int port, u32 members); -+ u32 (*read_port_status)(struct ar8xxx_priv *priv, int port); -+ u32 (*read_port_eee_status)(struct ar8xxx_priv *priv, int port); -+ int (*atu_flush)(struct ar8xxx_priv *priv); -+ int (*atu_flush_port)(struct ar8xxx_priv *priv, int port); -+ void (*vtu_flush)(struct ar8xxx_priv *priv); -+ void (*vtu_load_vlan)(struct ar8xxx_priv *priv, u32 vid, u32 port_mask); -+ void (*phy_fixup)(struct ar8xxx_priv *priv, int phy); -+ void (*set_mirror_regs)(struct ar8xxx_priv *priv); -+ void (*get_arl_entry)(struct ar8xxx_priv *priv, struct arl_entry *a, -+ u32 *status, enum arl_op op); -+ int (*sw_hw_apply)(struct switch_dev *dev); -+ void (*phy_rgmii_set)(struct ar8xxx_priv *priv, struct phy_device *phydev); -+ int (*phy_read)(struct ar8xxx_priv *priv, int addr, int regnum); -+ int (*phy_write)(struct ar8xxx_priv *priv, int addr, int regnum, u16 val); -+ -+ const struct ar8xxx_mib_desc *mib_decs; -+ unsigned num_mibs; -+ unsigned mib_func; -+ int mib_rxb_id; -+ int mib_txb_id; -+}; -+ -+struct ar8xxx_priv { -+ struct switch_dev dev; -+ struct mii_bus *mii_bus; -+ struct mii_bus *sw_mii_bus; -+ struct phy_device *phy; -+ struct device *pdev; -+ -+ int (*get_port_link)(unsigned port); -+ -+ const struct net_device_ops *ndo_old; -+ struct net_device_ops ndo; -+ struct mutex reg_mutex; -+ u8 chip_ver; -+ u8 chip_rev; -+ const struct ar8xxx_chip *chip; -+ void *chip_data; -+ bool initialized; -+ bool port4_phy; -+ char buf[2048]; -+ struct arl_entry arl_table[AR8XXX_NUM_ARL_RECORDS]; -+ char arl_buf[AR8XXX_NUM_ARL_RECORDS * 32 + 256]; -+ bool link_up[AR8X16_MAX_PORTS]; -+ -+ bool init; -+ -+ struct mutex mib_lock; -+ struct delayed_work mib_work; -+ u64 *mib_stats; -+ u32 mib_poll_interval; -+ u8 mib_type; -+ -+ struct list_head list; -+ unsigned int use_count; -+ -+ /* all fields below are cleared on reset */ -+ struct_group(ar8xxx_priv_volatile, -+ bool vlan; -+ -+ u16 vlan_id[AR8XXX_MAX_VLANS]; -+ u8 vlan_table[AR8XXX_MAX_VLANS]; -+ u8 vlan_tagged; -+ u16 pvid[AR8X16_MAX_PORTS]; -+ int arl_age_time; -+ -+ /* mirroring */ -+ bool mirror_rx; -+ bool mirror_tx; -+ int source_port; -+ int monitor_port; -+ u8 port_vlan_prio[AR8X16_MAX_PORTS]; -+ ); -+}; -+ -+u32 -+ar8xxx_mii_read32(struct ar8xxx_priv *priv, int phy_id, int regnum); -+void -+ar8xxx_mii_write32(struct ar8xxx_priv *priv, int phy_id, int regnum, u32 val); -+u32 -+ar8xxx_read(struct ar8xxx_priv *priv, int reg); -+void -+ar8xxx_write(struct ar8xxx_priv *priv, int reg, u32 val); -+u32 -+ar8xxx_rmw(struct ar8xxx_priv *priv, int reg, u32 mask, u32 val); -+ -+void -+ar8xxx_phy_dbg_read(struct ar8xxx_priv *priv, int phy_addr, -+ u16 dbg_addr, u16 *dbg_data); -+void -+ar8xxx_phy_dbg_write(struct ar8xxx_priv *priv, int phy_addr, -+ u16 dbg_addr, u16 dbg_data); -+void -+ar8xxx_phy_mmd_write(struct ar8xxx_priv *priv, int phy_addr, u16 addr, u16 reg, u16 data); -+u16 -+ar8xxx_phy_mmd_read(struct ar8xxx_priv *priv, int phy_addr, u16 addr, u16 reg); -+void -+ar8xxx_phy_init(struct ar8xxx_priv *priv); -+int -+ar8xxx_sw_set_vlan(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val); -+int -+ar8xxx_sw_get_vlan(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val); -+int -+ar8xxx_sw_set_reset_mibs(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val); -+int -+ar8xxx_sw_set_mib_poll_interval(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val); -+int -+ar8xxx_sw_get_mib_poll_interval(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val); -+int -+ar8xxx_sw_set_mib_type(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val); -+int -+ar8xxx_sw_get_mib_type(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val); -+int -+ar8xxx_sw_set_mirror_rx_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val); -+int -+ar8xxx_sw_get_mirror_rx_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val); -+int -+ar8xxx_sw_set_mirror_tx_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val); -+int -+ar8xxx_sw_get_mirror_tx_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val); -+int -+ar8xxx_sw_set_mirror_monitor_port(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val); -+int -+ar8xxx_sw_get_mirror_monitor_port(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val); -+int -+ar8xxx_sw_set_mirror_source_port(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val); -+int -+ar8xxx_sw_get_mirror_source_port(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val); -+int -+ar8xxx_sw_set_pvid(struct switch_dev *dev, int port, int vlan); -+int -+ar8xxx_sw_get_pvid(struct switch_dev *dev, int port, int *vlan); -+int -+ar8xxx_sw_hw_apply(struct switch_dev *dev); -+int -+ar8xxx_sw_reset_switch(struct switch_dev *dev); -+int -+ar8xxx_sw_get_port_link(struct switch_dev *dev, int port, -+ struct switch_port_link *link); -+int -+ar8xxx_sw_set_port_reset_mib(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val); -+int -+ar8xxx_sw_get_port_mib(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val); -+int -+ar8xxx_sw_get_arl_age_time(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val); -+int -+ar8xxx_sw_set_arl_age_time(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val); -+int -+ar8xxx_sw_get_arl_table(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val); -+int -+ar8xxx_sw_set_flush_arl_table(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val); -+int -+ar8xxx_sw_set_flush_port_arl_table(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val); -+int -+ar8xxx_sw_get_port_stats(struct switch_dev *dev, int port, -+ struct switch_port_stats *stats); -+int -+ar8216_wait_bit(struct ar8xxx_priv *priv, int reg, u32 mask, u32 val); -+ -+static inline struct ar8xxx_priv * -+swdev_to_ar8xxx(struct switch_dev *swdev) -+{ -+ return container_of(swdev, struct ar8xxx_priv, dev); -+} -+ -+static inline bool ar8xxx_has_gige(struct ar8xxx_priv *priv) -+{ -+ return priv->chip->caps & AR8XXX_CAP_GIGE; -+} -+ -+static inline bool ar8xxx_has_mib_counters(struct ar8xxx_priv *priv) -+{ -+ return priv->chip->caps & AR8XXX_CAP_MIB_COUNTERS; -+} -+ -+static inline bool chip_is_ar8216(struct ar8xxx_priv *priv) -+{ -+ return priv->chip_ver == AR8XXX_VER_AR8216; -+} -+ -+static inline bool chip_is_ar8236(struct ar8xxx_priv *priv) -+{ -+ return priv->chip_ver == AR8XXX_VER_AR8236; -+} -+ -+static inline bool chip_is_ar8316(struct ar8xxx_priv *priv) -+{ -+ return priv->chip_ver == AR8XXX_VER_AR8316; -+} -+ -+static inline bool chip_is_ar8327(struct ar8xxx_priv *priv) -+{ -+ return priv->chip_ver == AR8XXX_VER_AR8327; -+} -+ -+static inline bool chip_is_ar8337(struct ar8xxx_priv *priv) -+{ -+ return priv->chip_ver == AR8XXX_VER_AR8337; -+} -+ -+static inline void -+ar8xxx_reg_set(struct ar8xxx_priv *priv, int reg, u32 val) -+{ -+ ar8xxx_rmw(priv, reg, 0, val); -+} -+ -+static inline void -+ar8xxx_reg_clear(struct ar8xxx_priv *priv, int reg, u32 val) -+{ -+ ar8xxx_rmw(priv, reg, val, 0); -+} -+ -+static inline void -+split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page) -+{ -+ regaddr >>= 1; -+ *r1 = regaddr & 0x1e; -+ -+ regaddr >>= 5; -+ *r2 = regaddr & 0x7; -+ -+ regaddr >>= 3; -+ *page = regaddr & 0x1ff; -+} -+ -+static inline void -+wait_for_page_switch(void) -+{ -+ udelay(5); -+} -+ -+#endif -diff --git a/drivers/net/phy/ar8327.c b/drivers/net/phy/ar8327.c -new file mode 100644 -index 000000000000..d6749ad70ed2 ---- /dev/null -+++ b/drivers/net/phy/ar8327.c -@@ -0,0 +1,1589 @@ -+/* -+ * ar8327.c: AR8216 switch driver -+ * -+ * Copyright (C) 2009 Felix Fietkau -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "ar8216.h" -+#include "ar8327.h" -+ -+extern const struct ar8xxx_mib_desc ar8236_mibs[39]; -+extern const struct switch_attr ar8xxx_sw_attr_vlan[1]; -+ -+static u32 -+ar8327_get_pad_cfg(struct ar8327_pad_cfg *cfg) -+{ -+ u32 t; -+ -+ if (!cfg) -+ return 0; -+ -+ t = 0; -+ switch (cfg->mode) { -+ case AR8327_PAD_NC: -+ break; -+ -+ case AR8327_PAD_MAC2MAC_MII: -+ t = AR8327_PAD_MAC_MII_EN; -+ if (cfg->rxclk_sel) -+ t |= AR8327_PAD_MAC_MII_RXCLK_SEL; -+ if (cfg->txclk_sel) -+ t |= AR8327_PAD_MAC_MII_TXCLK_SEL; -+ break; -+ -+ case AR8327_PAD_MAC2MAC_GMII: -+ t = AR8327_PAD_MAC_GMII_EN; -+ if (cfg->rxclk_sel) -+ t |= AR8327_PAD_MAC_GMII_RXCLK_SEL; -+ if (cfg->txclk_sel) -+ t |= AR8327_PAD_MAC_GMII_TXCLK_SEL; -+ break; -+ -+ case AR8327_PAD_MAC_SGMII: -+ t = AR8327_PAD_SGMII_EN; -+ -+ /* -+ * WAR for the QUalcomm Atheros AP136 board. -+ * It seems that RGMII TX/RX delay settings needs to be -+ * applied for SGMII mode as well, The ethernet is not -+ * reliable without this. -+ */ -+ t |= cfg->txclk_delay_sel << AR8327_PAD_RGMII_TXCLK_DELAY_SEL_S; -+ t |= cfg->rxclk_delay_sel << AR8327_PAD_RGMII_RXCLK_DELAY_SEL_S; -+ if (cfg->rxclk_delay_en) -+ t |= AR8327_PAD_RGMII_RXCLK_DELAY_EN; -+ if (cfg->txclk_delay_en) -+ t |= AR8327_PAD_RGMII_TXCLK_DELAY_EN; -+ -+ if (cfg->sgmii_delay_en) -+ t |= AR8327_PAD_SGMII_DELAY_EN; -+ -+ break; -+ -+ case AR8327_PAD_MAC2PHY_MII: -+ t = AR8327_PAD_PHY_MII_EN; -+ if (cfg->rxclk_sel) -+ t |= AR8327_PAD_PHY_MII_RXCLK_SEL; -+ if (cfg->txclk_sel) -+ t |= AR8327_PAD_PHY_MII_TXCLK_SEL; -+ break; -+ -+ case AR8327_PAD_MAC2PHY_GMII: -+ t = AR8327_PAD_PHY_GMII_EN; -+ if (cfg->pipe_rxclk_sel) -+ t |= AR8327_PAD_PHY_GMII_PIPE_RXCLK_SEL; -+ if (cfg->rxclk_sel) -+ t |= AR8327_PAD_PHY_GMII_RXCLK_SEL; -+ if (cfg->txclk_sel) -+ t |= AR8327_PAD_PHY_GMII_TXCLK_SEL; -+ break; -+ -+ case AR8327_PAD_MAC_RGMII: -+ t = AR8327_PAD_RGMII_EN; -+ t |= cfg->txclk_delay_sel << AR8327_PAD_RGMII_TXCLK_DELAY_SEL_S; -+ t |= cfg->rxclk_delay_sel << AR8327_PAD_RGMII_RXCLK_DELAY_SEL_S; -+ if (cfg->rxclk_delay_en) -+ t |= AR8327_PAD_RGMII_RXCLK_DELAY_EN; -+ if (cfg->txclk_delay_en) -+ t |= AR8327_PAD_RGMII_TXCLK_DELAY_EN; -+ break; -+ -+ case AR8327_PAD_PHY_GMII: -+ t = AR8327_PAD_PHYX_GMII_EN; -+ break; -+ -+ case AR8327_PAD_PHY_RGMII: -+ t = AR8327_PAD_PHYX_RGMII_EN; -+ break; -+ -+ case AR8327_PAD_PHY_MII: -+ t = AR8327_PAD_PHYX_MII_EN; -+ break; -+ } -+ -+ return t; -+} -+ -+static void -+ar8327_phy_rgmii_set(struct ar8xxx_priv *priv, struct phy_device *phydev) -+{ -+ u16 phy_val = 0; -+ int phyaddr = phydev->mdio.addr; -+ struct device_node *np = phydev->mdio.dev.of_node; -+ -+ if (!np) -+ return; -+ -+ if (!of_property_read_bool(np, "qca,phy-rgmii-en")) { -+ pr_err("ar8327: qca,phy-rgmii-en is not specified\n"); -+ return; -+ } -+ ar8xxx_phy_dbg_read(priv, phyaddr, -+ AR8327_PHY_MODE_SEL, &phy_val); -+ phy_val |= AR8327_PHY_MODE_SEL_RGMII; -+ ar8xxx_phy_dbg_write(priv, phyaddr, -+ AR8327_PHY_MODE_SEL, phy_val); -+ -+ /* set rgmii tx clock delay if needed */ -+ if (!of_property_read_bool(np, "qca,txclk-delay-en")) { -+ pr_err("ar8327: qca,txclk-delay-en is not specified\n"); -+ return; -+ } -+ ar8xxx_phy_dbg_read(priv, phyaddr, -+ AR8327_PHY_SYS_CTRL, &phy_val); -+ phy_val |= AR8327_PHY_SYS_CTRL_RGMII_TX_DELAY; -+ ar8xxx_phy_dbg_write(priv, phyaddr, -+ AR8327_PHY_SYS_CTRL, phy_val); -+ -+ /* set rgmii rx clock delay if needed */ -+ if (!of_property_read_bool(np, "qca,rxclk-delay-en")) { -+ pr_err("ar8327: qca,rxclk-delay-en is not specified\n"); -+ return; -+ } -+ ar8xxx_phy_dbg_read(priv, phyaddr, -+ AR8327_PHY_TEST_CTRL, &phy_val); -+ phy_val |= AR8327_PHY_TEST_CTRL_RGMII_RX_DELAY; -+ ar8xxx_phy_dbg_write(priv, phyaddr, -+ AR8327_PHY_TEST_CTRL, phy_val); -+} -+ -+static void -+ar8327_phy_fixup(struct ar8xxx_priv *priv, int phy) -+{ -+ switch (priv->chip_rev) { -+ case 1: -+ /* For 100M waveform */ -+ ar8xxx_phy_dbg_write(priv, phy, 0, 0x02ea); -+ /* Turn on Gigabit clock */ -+ ar8xxx_phy_dbg_write(priv, phy, 0x3d, 0x68a0); -+ break; -+ -+ case 2: -+ ar8xxx_phy_mmd_write(priv, phy, 0x7, 0x3c, 0x0); -+ fallthrough; -+ case 4: -+ ar8xxx_phy_mmd_write(priv, phy, 0x3, 0x800d, 0x803f); -+ ar8xxx_phy_dbg_write(priv, phy, 0x3d, 0x6860); -+ ar8xxx_phy_dbg_write(priv, phy, 0x5, 0x2c46); -+ ar8xxx_phy_dbg_write(priv, phy, 0x3c, 0x6000); -+ break; -+ } -+} -+ -+static u32 -+ar8327_get_port_init_status(struct ar8327_port_cfg *cfg) -+{ -+ u32 t; -+ -+ if (!cfg->force_link) -+ return AR8216_PORT_STATUS_LINK_AUTO; -+ -+ t = AR8216_PORT_STATUS_TXMAC | AR8216_PORT_STATUS_RXMAC; -+ t |= cfg->duplex ? AR8216_PORT_STATUS_DUPLEX : 0; -+ t |= cfg->rxpause ? AR8216_PORT_STATUS_RXFLOW : 0; -+ t |= cfg->txpause ? AR8216_PORT_STATUS_TXFLOW : 0; -+ -+ switch (cfg->speed) { -+ case AR8327_PORT_SPEED_10: -+ t |= AR8216_PORT_SPEED_10M; -+ break; -+ case AR8327_PORT_SPEED_100: -+ t |= AR8216_PORT_SPEED_100M; -+ break; -+ case AR8327_PORT_SPEED_1000: -+ t |= AR8216_PORT_SPEED_1000M; -+ break; -+ } -+ -+ return t; -+} -+ -+#define AR8327_LED_ENTRY(_num, _reg, _shift) \ -+ [_num] = { .reg = (_reg), .shift = (_shift) } -+ -+static const struct ar8327_led_entry -+ar8327_led_map[AR8327_NUM_LEDS] = { -+ AR8327_LED_ENTRY(AR8327_LED_PHY0_0, 0, 14), -+ AR8327_LED_ENTRY(AR8327_LED_PHY0_1, 1, 14), -+ AR8327_LED_ENTRY(AR8327_LED_PHY0_2, 2, 14), -+ -+ AR8327_LED_ENTRY(AR8327_LED_PHY1_0, 3, 8), -+ AR8327_LED_ENTRY(AR8327_LED_PHY1_1, 3, 10), -+ AR8327_LED_ENTRY(AR8327_LED_PHY1_2, 3, 12), -+ -+ AR8327_LED_ENTRY(AR8327_LED_PHY2_0, 3, 14), -+ AR8327_LED_ENTRY(AR8327_LED_PHY2_1, 3, 16), -+ AR8327_LED_ENTRY(AR8327_LED_PHY2_2, 3, 18), -+ -+ AR8327_LED_ENTRY(AR8327_LED_PHY3_0, 3, 20), -+ AR8327_LED_ENTRY(AR8327_LED_PHY3_1, 3, 22), -+ AR8327_LED_ENTRY(AR8327_LED_PHY3_2, 3, 24), -+ -+ AR8327_LED_ENTRY(AR8327_LED_PHY4_0, 0, 30), -+ AR8327_LED_ENTRY(AR8327_LED_PHY4_1, 1, 30), -+ AR8327_LED_ENTRY(AR8327_LED_PHY4_2, 2, 30), -+}; -+ -+static void -+ar8327_set_led_pattern(struct ar8xxx_priv *priv, unsigned int led_num, -+ enum ar8327_led_pattern pattern) -+{ -+ const struct ar8327_led_entry *entry; -+ -+ entry = &ar8327_led_map[led_num]; -+ ar8xxx_rmw(priv, AR8327_REG_LED_CTRL(entry->reg), -+ (3 << entry->shift), pattern << entry->shift); -+} -+ -+static void -+ar8327_led_work_func(struct work_struct *work) -+{ -+ struct ar8327_led *aled; -+ u8 pattern; -+ -+ aled = container_of(work, struct ar8327_led, led_work); -+ -+ pattern = aled->pattern; -+ -+ ar8327_set_led_pattern(aled->sw_priv, aled->led_num, -+ pattern); -+} -+ -+static void -+ar8327_led_schedule_change(struct ar8327_led *aled, u8 pattern) -+{ -+ if (aled->pattern == pattern) -+ return; -+ -+ aled->pattern = pattern; -+ schedule_work(&aled->led_work); -+} -+ -+static inline struct ar8327_led * -+led_cdev_to_ar8327_led(struct led_classdev *led_cdev) -+{ -+ return container_of(led_cdev, struct ar8327_led, cdev); -+} -+ -+static int -+ar8327_led_blink_set(struct led_classdev *led_cdev, -+ unsigned long *delay_on, -+ unsigned long *delay_off) -+{ -+ struct ar8327_led *aled = led_cdev_to_ar8327_led(led_cdev); -+ -+ if (*delay_on == 0 && *delay_off == 0) { -+ *delay_on = 125; -+ *delay_off = 125; -+ } -+ -+ if (*delay_on != 125 || *delay_off != 125) { -+ /* -+ * The hardware only supports blinking at 4Hz. Fall back -+ * to software implementation in other cases. -+ */ -+ return -EINVAL; -+ } -+ -+ spin_lock(&aled->lock); -+ -+ aled->enable_hw_mode = false; -+ ar8327_led_schedule_change(aled, AR8327_LED_PATTERN_BLINK); -+ -+ spin_unlock(&aled->lock); -+ -+ return 0; -+} -+ -+static void -+ar8327_led_set_brightness(struct led_classdev *led_cdev, -+ enum led_brightness brightness) -+{ -+ struct ar8327_led *aled = led_cdev_to_ar8327_led(led_cdev); -+ u8 pattern; -+ bool active; -+ -+ active = (brightness != LED_OFF) != aled->active_low; -+ -+ pattern = (active) ? AR8327_LED_PATTERN_ON : -+ AR8327_LED_PATTERN_OFF; -+ -+ spin_lock(&aled->lock); -+ -+ aled->enable_hw_mode = false; -+ ar8327_led_schedule_change(aled, pattern); -+ -+ spin_unlock(&aled->lock); -+} -+ -+static ssize_t -+ar8327_led_enable_hw_mode_show(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct led_classdev *led_cdev = dev_get_drvdata(dev); -+ struct ar8327_led *aled = led_cdev_to_ar8327_led(led_cdev); -+ ssize_t ret = 0; -+ -+ ret += scnprintf(buf, PAGE_SIZE, "%d\n", aled->enable_hw_mode); -+ -+ return ret; -+} -+ -+static ssize_t -+ar8327_led_enable_hw_mode_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, -+ size_t size) -+{ -+ struct led_classdev *led_cdev = dev_get_drvdata(dev); -+ struct ar8327_led *aled = led_cdev_to_ar8327_led(led_cdev); -+ u8 pattern; -+ u8 value; -+ int ret; -+ -+ ret = kstrtou8(buf, 10, &value); -+ if (ret < 0) -+ return -EINVAL; -+ -+ spin_lock(&aled->lock); -+ -+ aled->enable_hw_mode = !!value; -+ if (aled->enable_hw_mode) -+ pattern = AR8327_LED_PATTERN_RULE; -+ else -+ pattern = AR8327_LED_PATTERN_OFF; -+ -+ ar8327_led_schedule_change(aled, pattern); -+ -+ spin_unlock(&aled->lock); -+ -+ return size; -+} -+ -+static DEVICE_ATTR(enable_hw_mode, S_IRUGO | S_IWUSR, -+ ar8327_led_enable_hw_mode_show, -+ ar8327_led_enable_hw_mode_store); -+ -+static int -+ar8327_led_register(struct ar8327_led *aled) -+{ -+ int ret; -+ struct led_init_data init_data = { -+ .fwnode = aled->fwnode -+ }; -+ -+ ret = led_classdev_register_ext(NULL, &aled->cdev, &init_data); -+ if (ret < 0) -+ return ret; -+ -+ if (aled->mode == AR8327_LED_MODE_HW) { -+ ret = device_create_file(aled->cdev.dev, -+ &dev_attr_enable_hw_mode); -+ if (ret) -+ goto err_unregister; -+ } -+ -+ return 0; -+ -+err_unregister: -+ led_classdev_unregister(&aled->cdev); -+ return ret; -+} -+ -+static void -+ar8327_led_unregister(struct ar8327_led *aled) -+{ -+ if (aled->mode == AR8327_LED_MODE_HW) -+ device_remove_file(aled->cdev.dev, &dev_attr_enable_hw_mode); -+ -+ led_classdev_unregister(&aled->cdev); -+ cancel_work_sync(&aled->led_work); -+} -+ -+static int -+ar8327_led_create(struct ar8xxx_priv *priv, -+ const struct ar8327_led_info *led_info) -+{ -+ struct ar8327_data *data = priv->chip_data; -+ struct ar8327_led *aled; -+ int ret; -+ -+ if (!IS_ENABLED(CONFIG_AR8216_PHY_LEDS)) -+ return 0; -+ -+ if (!led_info->name) -+ return -EINVAL; -+ -+ if (led_info->led_num >= AR8327_NUM_LEDS) -+ return -EINVAL; -+ -+ aled = kzalloc(sizeof(*aled) + strlen(led_info->name) + 1, -+ GFP_KERNEL); -+ if (!aled) -+ return -ENOMEM; -+ -+ aled->sw_priv = priv; -+ aled->led_num = led_info->led_num; -+ aled->active_low = led_info->active_low; -+ aled->mode = led_info->mode; -+ aled->fwnode = led_info->fwnode; -+ -+ if (aled->mode == AR8327_LED_MODE_HW) -+ aled->enable_hw_mode = true; -+ -+ aled->name = (char *)(aled + 1); -+ strcpy(aled->name, led_info->name); -+ -+ aled->cdev.name = aled->name; -+ aled->cdev.brightness_set = ar8327_led_set_brightness; -+ aled->cdev.blink_set = ar8327_led_blink_set; -+ aled->cdev.default_trigger = led_info->default_trigger; -+ -+ spin_lock_init(&aled->lock); -+ mutex_init(&aled->mutex); -+ INIT_WORK(&aled->led_work, ar8327_led_work_func); -+ -+ ret = ar8327_led_register(aled); -+ if (ret) -+ goto err_free; -+ -+ data->leds[data->num_leds++] = aled; -+ -+ return 0; -+ -+err_free: -+ kfree(aled); -+ return ret; -+} -+ -+static void -+ar8327_led_destroy(struct ar8327_led *aled) -+{ -+ ar8327_led_unregister(aled); -+ kfree(aled); -+} -+ -+static void -+ar8327_leds_init(struct ar8xxx_priv *priv) -+{ -+ struct ar8327_data *data = priv->chip_data; -+ unsigned i; -+ -+ if (!IS_ENABLED(CONFIG_AR8216_PHY_LEDS)) -+ return; -+ -+ for (i = 0; i < data->num_leds; i++) { -+ struct ar8327_led *aled; -+ -+ aled = data->leds[i]; -+ -+ if (aled->enable_hw_mode) -+ aled->pattern = AR8327_LED_PATTERN_RULE; -+ else -+ aled->pattern = aled->active_low ? -+ AR8327_LED_PATTERN_ON : AR8327_LED_PATTERN_OFF; -+ -+ ar8327_set_led_pattern(priv, aled->led_num, aled->pattern); -+ } -+} -+ -+static void -+ar8327_leds_cleanup(struct ar8xxx_priv *priv) -+{ -+ struct ar8327_data *data = priv->chip_data; -+ unsigned i; -+ -+ if (!IS_ENABLED(CONFIG_AR8216_PHY_LEDS)) -+ return; -+ -+ for (i = 0; i < data->num_leds; i++) { -+ struct ar8327_led *aled; -+ -+ aled = data->leds[i]; -+ ar8327_led_destroy(aled); -+ } -+ -+ kfree(data->leds); -+} -+ -+static int -+ar8327_hw_config_pdata(struct ar8xxx_priv *priv, -+ struct ar8327_platform_data *pdata) -+{ -+ struct ar8327_led_cfg *led_cfg; -+ struct ar8327_data *data = priv->chip_data; -+ u32 pos, new_pos; -+ u32 t; -+ -+ if (!pdata) -+ return -EINVAL; -+ -+ priv->get_port_link = pdata->get_port_link; -+ -+ data->port0_status = ar8327_get_port_init_status(&pdata->port0_cfg); -+ data->port6_status = ar8327_get_port_init_status(&pdata->port6_cfg); -+ -+ t = ar8327_get_pad_cfg(pdata->pad0_cfg); -+ if (chip_is_ar8337(priv) && !pdata->pad0_cfg->mac06_exchange_dis) -+ t |= AR8337_PAD_MAC06_EXCHANGE_EN; -+ ar8xxx_write(priv, AR8327_REG_PAD0_MODE, t); -+ -+ t = ar8327_get_pad_cfg(pdata->pad5_cfg); -+ ar8xxx_write(priv, AR8327_REG_PAD5_MODE, t); -+ t = ar8327_get_pad_cfg(pdata->pad6_cfg); -+ ar8xxx_write(priv, AR8327_REG_PAD6_MODE, t); -+ -+ pos = ar8xxx_read(priv, AR8327_REG_POWER_ON_STRAP); -+ new_pos = pos; -+ -+ led_cfg = pdata->led_cfg; -+ if (led_cfg) { -+ if (led_cfg->open_drain) -+ new_pos |= AR8327_POWER_ON_STRAP_LED_OPEN_EN; -+ else -+ new_pos &= ~AR8327_POWER_ON_STRAP_LED_OPEN_EN; -+ -+ ar8xxx_write(priv, AR8327_REG_LED_CTRL0, led_cfg->led_ctrl0); -+ ar8xxx_write(priv, AR8327_REG_LED_CTRL1, led_cfg->led_ctrl1); -+ ar8xxx_write(priv, AR8327_REG_LED_CTRL2, led_cfg->led_ctrl2); -+ ar8xxx_write(priv, AR8327_REG_LED_CTRL3, led_cfg->led_ctrl3); -+ -+ if (new_pos != pos) -+ new_pos |= AR8327_POWER_ON_STRAP_POWER_ON_SEL; -+ } -+ -+ if (pdata->sgmii_cfg) { -+ t = pdata->sgmii_cfg->sgmii_ctrl; -+ if (priv->chip_rev == 1) -+ t |= AR8327_SGMII_CTRL_EN_PLL | -+ AR8327_SGMII_CTRL_EN_RX | -+ AR8327_SGMII_CTRL_EN_TX; -+ else -+ t &= ~(AR8327_SGMII_CTRL_EN_PLL | -+ AR8327_SGMII_CTRL_EN_RX | -+ AR8327_SGMII_CTRL_EN_TX); -+ -+ ar8xxx_write(priv, AR8327_REG_SGMII_CTRL, t); -+ -+ if (pdata->sgmii_cfg->serdes_aen) -+ new_pos &= ~AR8327_POWER_ON_STRAP_SERDES_AEN; -+ else -+ new_pos |= AR8327_POWER_ON_STRAP_SERDES_AEN; -+ } -+ -+ ar8xxx_write(priv, AR8327_REG_POWER_ON_STRAP, new_pos); -+ -+ if (pdata->leds && pdata->num_leds) { -+ int i; -+ -+ data->leds = kzalloc(pdata->num_leds * sizeof(void *), -+ GFP_KERNEL); -+ if (!data->leds) -+ return -ENOMEM; -+ -+ for (i = 0; i < pdata->num_leds; i++) -+ ar8327_led_create(priv, &pdata->leds[i]); -+ } -+ -+ return 0; -+} -+ -+#ifdef CONFIG_OF -+static int -+ar8327_hw_config_of(struct ar8xxx_priv *priv, struct device_node *np) -+{ -+ struct ar8327_data *data = priv->chip_data; -+ const __be32 *paddr; -+ int len; -+ int i; -+ struct device_node *leds, *child; -+ -+ paddr = of_get_property(np, "qca,ar8327-initvals", &len); -+ if (!paddr || len < (2 * sizeof(*paddr))) -+ return -EINVAL; -+ -+ len /= sizeof(*paddr); -+ -+ for (i = 0; i < len - 1; i += 2) { -+ u32 reg; -+ u32 val; -+ -+ reg = be32_to_cpup(paddr + i); -+ val = be32_to_cpup(paddr + i + 1); -+ -+ switch (reg) { -+ case AR8327_REG_PORT_STATUS(0): -+ data->port0_status = val; -+ break; -+ case AR8327_REG_PORT_STATUS(6): -+ data->port6_status = val; -+ break; -+ default: -+ ar8xxx_write(priv, reg, val); -+ break; -+ } -+ } -+ -+ leds = of_get_child_by_name(np, "leds"); -+ if (!leds) -+ return 0; -+ -+ data->leds = kvcalloc(of_get_child_count(leds), sizeof(void *), -+ GFP_KERNEL); -+ if (!data->leds) -+ return -ENOMEM; -+ -+ for_each_available_child_of_node(leds, child) { -+ u32 reg = 0, mode = 0; -+ struct ar8327_led_info info; -+ int ret; -+ -+ ret = of_property_read_u32(child, "reg", ®); -+ if (ret) { -+ pr_err("ar8327: LED %s is missing reg node\n", child->name); -+ continue; -+ } -+ -+ of_property_read_u32(child, "qca,led-mode", &mode); -+ -+ info = (struct ar8327_led_info) { -+ .name = of_get_property(child, "label", NULL) ? : child->name, -+ .fwnode = of_fwnode_handle(child), -+ .active_low = of_property_read_bool(child, "active-low"), -+ .led_num = (enum ar8327_led_num) reg, -+ .mode = (enum ar8327_led_mode) mode -+ }; -+ ar8327_led_create(priv, &info); -+ } -+ -+ of_node_put(leds); -+ return 0; -+} -+#else -+static inline int -+ar8327_hw_config_of(struct ar8xxx_priv *priv, struct device_node *np) -+{ -+ return -EINVAL; -+} -+#endif -+ -+static int -+ar8327_hw_init(struct ar8xxx_priv *priv) -+{ -+ int ret; -+ -+ priv->chip_data = kzalloc(sizeof(struct ar8327_data), GFP_KERNEL); -+ if (!priv->chip_data) -+ return -ENOMEM; -+ -+ if (priv->pdev->of_node) -+ ret = ar8327_hw_config_of(priv, priv->pdev->of_node); -+ else -+ ret = ar8327_hw_config_pdata(priv, -+ priv->phy->mdio.dev.platform_data); -+ -+ if (ret) -+ return ret; -+ -+ ar8327_leds_init(priv); -+ -+ ar8xxx_phy_init(priv); -+ -+ return 0; -+} -+ -+static void -+ar8327_cleanup(struct ar8xxx_priv *priv) -+{ -+ ar8327_leds_cleanup(priv); -+} -+ -+static void -+ar8327_init_globals(struct ar8xxx_priv *priv) -+{ -+ struct ar8327_data *data = priv->chip_data; -+ u32 t; -+ int i; -+ -+ /* enable CPU port and disable mirror port */ -+ t = AR8327_FWD_CTRL0_CPU_PORT_EN | -+ AR8327_FWD_CTRL0_MIRROR_PORT; -+ ar8xxx_write(priv, AR8327_REG_FWD_CTRL0, t); -+ -+ /* forward multicast and broadcast frames to CPU */ -+ t = (AR8327_PORTS_ALL << AR8327_FWD_CTRL1_UC_FLOOD_S) | -+ (AR8327_PORTS_ALL << AR8327_FWD_CTRL1_MC_FLOOD_S) | -+ (AR8327_PORTS_ALL << AR8327_FWD_CTRL1_BC_FLOOD_S); -+ ar8xxx_write(priv, AR8327_REG_FWD_CTRL1, t); -+ -+ /* enable jumbo frames */ -+ ar8xxx_rmw(priv, AR8327_REG_MAX_FRAME_SIZE, -+ AR8327_MAX_FRAME_SIZE_MTU, 9018 + 8 + 2); -+ -+ /* Enable MIB counters */ -+ ar8xxx_reg_set(priv, AR8327_REG_MODULE_EN, -+ AR8327_MODULE_EN_MIB); -+ -+ /* Disable EEE on all phy's due to stability issues */ -+ for (i = 0; i < AR8XXX_NUM_PHYS; i++) -+ data->eee[i] = false; -+} -+ -+static void -+ar8327_init_port(struct ar8xxx_priv *priv, int port) -+{ -+ struct ar8327_data *data = priv->chip_data; -+ u32 t; -+ -+ if (port == AR8216_PORT_CPU) -+ t = data->port0_status; -+ else if (port == 6) -+ t = data->port6_status; -+ else -+ t = AR8216_PORT_STATUS_LINK_AUTO; -+ -+ if (port != AR8216_PORT_CPU && port != 6) { -+ /*hw limitation:if configure mac when there is traffic, -+ port MAC may work abnormal. Need disable lan&wan mac at fisrt*/ -+ ar8xxx_write(priv, AR8327_REG_PORT_STATUS(port), 0); -+ msleep(100); -+ t |= AR8216_PORT_STATUS_FLOW_CONTROL; -+ ar8xxx_write(priv, AR8327_REG_PORT_STATUS(port), t); -+ } else { -+ ar8xxx_write(priv, AR8327_REG_PORT_STATUS(port), t); -+ } -+ -+ ar8xxx_write(priv, AR8327_REG_PORT_HEADER(port), 0); -+ -+ ar8xxx_write(priv, AR8327_REG_PORT_VLAN0(port), 0); -+ -+ t = AR8327_PORT_VLAN1_OUT_MODE_UNTOUCH << AR8327_PORT_VLAN1_OUT_MODE_S; -+ ar8xxx_write(priv, AR8327_REG_PORT_VLAN1(port), t); -+ -+ t = AR8327_PORT_LOOKUP_LEARN; -+ t |= AR8216_PORT_STATE_FORWARD << AR8327_PORT_LOOKUP_STATE_S; -+ ar8xxx_write(priv, AR8327_REG_PORT_LOOKUP(port), t); -+} -+ -+static u32 -+ar8327_read_port_status(struct ar8xxx_priv *priv, int port) -+{ -+ u32 t; -+ -+ t = ar8xxx_read(priv, AR8327_REG_PORT_STATUS(port)); -+ /* map the flow control autoneg result bits to the flow control bits -+ * used in forced mode to allow ar8216_read_port_link detect -+ * flow control properly if autoneg is used -+ */ -+ if (t & AR8216_PORT_STATUS_LINK_UP && -+ t & AR8216_PORT_STATUS_LINK_AUTO) { -+ t &= ~(AR8216_PORT_STATUS_TXFLOW | AR8216_PORT_STATUS_RXFLOW); -+ if (t & AR8327_PORT_STATUS_TXFLOW_AUTO) -+ t |= AR8216_PORT_STATUS_TXFLOW; -+ if (t & AR8327_PORT_STATUS_RXFLOW_AUTO) -+ t |= AR8216_PORT_STATUS_RXFLOW; -+ } -+ -+ return t; -+} -+ -+static u32 -+ar8327_read_port_eee_status(struct ar8xxx_priv *priv, int port) -+{ -+ int phy; -+ u16 t; -+ -+ if (port >= priv->dev.ports) -+ return 0; -+ -+ if (port == 0 || port == 6) -+ return 0; -+ -+ phy = port - 1; -+ -+ /* EEE Ability Auto-negotiation Result */ -+ t = ar8xxx_phy_mmd_read(priv, phy, 0x7, 0x8000); -+ -+ return mmd_eee_adv_to_ethtool_adv_t(t); -+} -+ -+static int -+ar8327_atu_flush(struct ar8xxx_priv *priv) -+{ -+ int ret; -+ -+ ret = ar8216_wait_bit(priv, AR8327_REG_ATU_FUNC, -+ AR8327_ATU_FUNC_BUSY, 0); -+ if (!ret) -+ ar8xxx_write(priv, AR8327_REG_ATU_FUNC, -+ AR8327_ATU_FUNC_OP_FLUSH | -+ AR8327_ATU_FUNC_BUSY); -+ -+ return ret; -+} -+ -+static int -+ar8327_atu_flush_port(struct ar8xxx_priv *priv, int port) -+{ -+ u32 t; -+ int ret; -+ -+ ret = ar8216_wait_bit(priv, AR8327_REG_ATU_FUNC, -+ AR8327_ATU_FUNC_BUSY, 0); -+ if (!ret) { -+ t = (port << AR8327_ATU_PORT_NUM_S); -+ t |= AR8327_ATU_FUNC_OP_FLUSH_PORT; -+ t |= AR8327_ATU_FUNC_BUSY; -+ ar8xxx_write(priv, AR8327_REG_ATU_FUNC, t); -+ } -+ -+ return ret; -+} -+ -+static int -+ar8327_get_port_igmp(struct ar8xxx_priv *priv, int port) -+{ -+ u32 fwd_ctrl, frame_ack; -+ -+ fwd_ctrl = (BIT(port) << AR8327_FWD_CTRL1_IGMP_S); -+ frame_ack = ((AR8327_FRAME_ACK_CTRL_IGMP_MLD | -+ AR8327_FRAME_ACK_CTRL_IGMP_JOIN | -+ AR8327_FRAME_ACK_CTRL_IGMP_LEAVE) << -+ AR8327_FRAME_ACK_CTRL_S(port)); -+ -+ return (ar8xxx_read(priv, AR8327_REG_FWD_CTRL1) & -+ fwd_ctrl) == fwd_ctrl && -+ (ar8xxx_read(priv, AR8327_REG_FRAME_ACK_CTRL(port)) & -+ frame_ack) == frame_ack; -+} -+ -+static void -+ar8327_set_port_igmp(struct ar8xxx_priv *priv, int port, int enable) -+{ -+ int reg_frame_ack = AR8327_REG_FRAME_ACK_CTRL(port); -+ u32 val_frame_ack = (AR8327_FRAME_ACK_CTRL_IGMP_MLD | -+ AR8327_FRAME_ACK_CTRL_IGMP_JOIN | -+ AR8327_FRAME_ACK_CTRL_IGMP_LEAVE) << -+ AR8327_FRAME_ACK_CTRL_S(port); -+ -+ if (enable) { -+ ar8xxx_rmw(priv, AR8327_REG_FWD_CTRL1, -+ BIT(port) << AR8327_FWD_CTRL1_MC_FLOOD_S, -+ BIT(port) << AR8327_FWD_CTRL1_IGMP_S); -+ ar8xxx_reg_set(priv, reg_frame_ack, val_frame_ack); -+ } else { -+ ar8xxx_rmw(priv, AR8327_REG_FWD_CTRL1, -+ BIT(port) << AR8327_FWD_CTRL1_IGMP_S, -+ BIT(port) << AR8327_FWD_CTRL1_MC_FLOOD_S); -+ ar8xxx_reg_clear(priv, reg_frame_ack, val_frame_ack); -+ } -+} -+ -+static void -+ar8327_vtu_op(struct ar8xxx_priv *priv, u32 op, u32 val) -+{ -+ if (ar8216_wait_bit(priv, AR8327_REG_VTU_FUNC1, -+ AR8327_VTU_FUNC1_BUSY, 0)) -+ return; -+ -+ if ((op & AR8327_VTU_FUNC1_OP) == AR8327_VTU_FUNC1_OP_LOAD) -+ ar8xxx_write(priv, AR8327_REG_VTU_FUNC0, val); -+ -+ op |= AR8327_VTU_FUNC1_BUSY; -+ ar8xxx_write(priv, AR8327_REG_VTU_FUNC1, op); -+} -+ -+static void -+ar8327_vtu_flush(struct ar8xxx_priv *priv) -+{ -+ ar8327_vtu_op(priv, AR8327_VTU_FUNC1_OP_FLUSH, 0); -+} -+ -+static void -+ar8327_vtu_load_vlan(struct ar8xxx_priv *priv, u32 vid, u32 port_mask) -+{ -+ u32 op; -+ u32 val; -+ int i; -+ -+ op = AR8327_VTU_FUNC1_OP_LOAD | (vid << AR8327_VTU_FUNC1_VID_S); -+ val = AR8327_VTU_FUNC0_VALID | AR8327_VTU_FUNC0_IVL; -+ for (i = 0; i < AR8327_NUM_PORTS; i++) { -+ u32 mode; -+ -+ if ((port_mask & BIT(i)) == 0) -+ mode = AR8327_VTU_FUNC0_EG_MODE_NOT; -+ else if (priv->vlan == 0) -+ mode = AR8327_VTU_FUNC0_EG_MODE_KEEP; -+ else if ((priv->vlan_tagged & BIT(i)) || (priv->vlan_id[priv->pvid[i]] != vid)) -+ mode = AR8327_VTU_FUNC0_EG_MODE_TAG; -+ else -+ mode = AR8327_VTU_FUNC0_EG_MODE_UNTAG; -+ -+ val |= mode << AR8327_VTU_FUNC0_EG_MODE_S(i); -+ } -+ ar8327_vtu_op(priv, op, val); -+} -+ -+static void -+ar8327_setup_port(struct ar8xxx_priv *priv, int port, u32 members) -+{ -+ u32 t; -+ u32 egress, ingress; -+ u32 pvid = priv->vlan_id[priv->pvid[port]]; -+ -+ if (priv->vlan) { -+ egress = AR8327_PORT_VLAN1_OUT_MODE_UNMOD; -+ ingress = AR8216_IN_SECURE; -+ } else { -+ egress = AR8327_PORT_VLAN1_OUT_MODE_UNTOUCH; -+ ingress = AR8216_IN_PORT_ONLY; -+ } -+ -+ t = pvid << AR8327_PORT_VLAN0_DEF_SVID_S; -+ t |= pvid << AR8327_PORT_VLAN0_DEF_CVID_S; -+ if (priv->vlan && priv->port_vlan_prio[port]) { -+ u32 prio = priv->port_vlan_prio[port]; -+ -+ t |= prio << AR8327_PORT_VLAN0_DEF_SPRI_S; -+ t |= prio << AR8327_PORT_VLAN0_DEF_CPRI_S; -+ } -+ ar8xxx_write(priv, AR8327_REG_PORT_VLAN0(port), t); -+ -+ t = AR8327_PORT_VLAN1_PORT_VLAN_PROP; -+ t |= egress << AR8327_PORT_VLAN1_OUT_MODE_S; -+ if (priv->vlan && priv->port_vlan_prio[port]) -+ t |= AR8327_PORT_VLAN1_VLAN_PRI_PROP; -+ -+ ar8xxx_write(priv, AR8327_REG_PORT_VLAN1(port), t); -+ -+ t = members; -+ t |= AR8327_PORT_LOOKUP_LEARN; -+ t |= ingress << AR8327_PORT_LOOKUP_IN_MODE_S; -+ t |= AR8216_PORT_STATE_FORWARD << AR8327_PORT_LOOKUP_STATE_S; -+ ar8xxx_write(priv, AR8327_REG_PORT_LOOKUP(port), t); -+} -+ -+static int -+ar8327_sw_get_ports(struct switch_dev *dev, struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ u8 ports = priv->vlan_table[val->port_vlan]; -+ int i; -+ -+ val->len = 0; -+ for (i = 0; i < dev->ports; i++) { -+ struct switch_port *p; -+ -+ if (!(ports & (1 << i))) -+ continue; -+ -+ p = &val->value.ports[val->len++]; -+ p->id = i; -+ if ((priv->vlan_tagged & (1 << i)) || (priv->pvid[i] != val->port_vlan)) -+ p->flags = (1 << SWITCH_PORT_FLAG_TAGGED); -+ else -+ p->flags = 0; -+ } -+ return 0; -+} -+ -+static int -+ar8327_sw_set_ports(struct switch_dev *dev, struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ u8 *vt = &priv->vlan_table[val->port_vlan]; -+ int i; -+ -+ *vt = 0; -+ for (i = 0; i < val->len; i++) { -+ struct switch_port *p = &val->value.ports[i]; -+ -+ if (p->flags & (1 << SWITCH_PORT_FLAG_TAGGED)) { -+ if (val->port_vlan == priv->pvid[p->id]) { -+ priv->vlan_tagged |= (1 << p->id); -+ } -+ } else { -+ priv->vlan_tagged &= ~(1 << p->id); -+ priv->pvid[p->id] = val->port_vlan; -+ } -+ -+ *vt |= 1 << p->id; -+ } -+ return 0; -+} -+ -+static void -+ar8327_set_mirror_regs(struct ar8xxx_priv *priv) -+{ -+ int port; -+ -+ /* reset all mirror registers */ -+ ar8xxx_rmw(priv, AR8327_REG_FWD_CTRL0, -+ AR8327_FWD_CTRL0_MIRROR_PORT, -+ (0xF << AR8327_FWD_CTRL0_MIRROR_PORT_S)); -+ for (port = 0; port < AR8327_NUM_PORTS; port++) { -+ ar8xxx_reg_clear(priv, AR8327_REG_PORT_LOOKUP(port), -+ AR8327_PORT_LOOKUP_ING_MIRROR_EN); -+ -+ ar8xxx_reg_clear(priv, AR8327_REG_PORT_HOL_CTRL1(port), -+ AR8327_PORT_HOL_CTRL1_EG_MIRROR_EN); -+ } -+ -+ /* now enable mirroring if necessary */ -+ if (priv->source_port >= AR8327_NUM_PORTS || -+ priv->monitor_port >= AR8327_NUM_PORTS || -+ priv->source_port == priv->monitor_port) { -+ return; -+ } -+ -+ ar8xxx_rmw(priv, AR8327_REG_FWD_CTRL0, -+ AR8327_FWD_CTRL0_MIRROR_PORT, -+ (priv->monitor_port << AR8327_FWD_CTRL0_MIRROR_PORT_S)); -+ -+ if (priv->mirror_rx) -+ ar8xxx_reg_set(priv, AR8327_REG_PORT_LOOKUP(priv->source_port), -+ AR8327_PORT_LOOKUP_ING_MIRROR_EN); -+ -+ if (priv->mirror_tx) -+ ar8xxx_reg_set(priv, AR8327_REG_PORT_HOL_CTRL1(priv->source_port), -+ AR8327_PORT_HOL_CTRL1_EG_MIRROR_EN); -+} -+ -+static int -+ar8327_sw_set_eee(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ struct ar8327_data *data = priv->chip_data; -+ int port = val->port_vlan; -+ int phy; -+ -+ if (port >= dev->ports) -+ return -EINVAL; -+ if (port == 0 || port == 6) -+ return -EOPNOTSUPP; -+ -+ phy = port - 1; -+ -+ data->eee[phy] = !!(val->value.i); -+ -+ return 0; -+} -+ -+static int -+ar8327_sw_get_eee(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ const struct ar8327_data *data = priv->chip_data; -+ int port = val->port_vlan; -+ int phy; -+ -+ if (port >= dev->ports) -+ return -EINVAL; -+ if (port == 0 || port == 6) -+ return -EOPNOTSUPP; -+ -+ phy = port - 1; -+ -+ val->value.i = data->eee[phy]; -+ -+ return 0; -+} -+ -+static void -+ar8327_wait_atu_ready(struct ar8xxx_priv *priv, u16 r2, u16 r1) -+{ -+ int timeout = 20; -+ -+ while (ar8xxx_mii_read32(priv, r2, r1) & AR8327_ATU_FUNC_BUSY && --timeout) { -+ udelay(10); -+ cond_resched(); -+ } -+ -+ if (!timeout) -+ pr_err("ar8327: timeout waiting for atu to become ready\n"); -+} -+ -+static void ar8327_get_arl_entry(struct ar8xxx_priv *priv, -+ struct arl_entry *a, u32 *status, enum arl_op op) -+{ -+ struct mii_bus *bus = priv->mii_bus; -+ u16 r2, page; -+ u16 r1_data0, r1_data1, r1_data2, r1_func; -+ u32 val0, val1, val2; -+ -+ split_addr(AR8327_REG_ATU_DATA0, &r1_data0, &r2, &page); -+ r2 |= 0x10; -+ -+ r1_data1 = (AR8327_REG_ATU_DATA1 >> 1) & 0x1e; -+ r1_data2 = (AR8327_REG_ATU_DATA2 >> 1) & 0x1e; -+ r1_func = (AR8327_REG_ATU_FUNC >> 1) & 0x1e; -+ -+ switch (op) { -+ case AR8XXX_ARL_INITIALIZE: -+ /* all ATU registers are on the same page -+ * therefore set page only once -+ */ -+ bus->write(bus, 0x18, 0, page); -+ wait_for_page_switch(); -+ -+ ar8327_wait_atu_ready(priv, r2, r1_func); -+ -+ ar8xxx_mii_write32(priv, r2, r1_data0, 0); -+ ar8xxx_mii_write32(priv, r2, r1_data1, 0); -+ ar8xxx_mii_write32(priv, r2, r1_data2, 0); -+ break; -+ case AR8XXX_ARL_GET_NEXT: -+ ar8xxx_mii_write32(priv, r2, r1_func, -+ AR8327_ATU_FUNC_OP_GET_NEXT | -+ AR8327_ATU_FUNC_BUSY); -+ ar8327_wait_atu_ready(priv, r2, r1_func); -+ -+ val0 = ar8xxx_mii_read32(priv, r2, r1_data0); -+ val1 = ar8xxx_mii_read32(priv, r2, r1_data1); -+ val2 = ar8xxx_mii_read32(priv, r2, r1_data2); -+ -+ *status = val2 & AR8327_ATU_STATUS; -+ if (!*status) -+ break; -+ -+ a->portmap = (val1 & AR8327_ATU_PORTS) >> AR8327_ATU_PORTS_S; -+ a->mac[0] = (val0 & AR8327_ATU_ADDR0) >> AR8327_ATU_ADDR0_S; -+ a->mac[1] = (val0 & AR8327_ATU_ADDR1) >> AR8327_ATU_ADDR1_S; -+ a->mac[2] = (val0 & AR8327_ATU_ADDR2) >> AR8327_ATU_ADDR2_S; -+ a->mac[3] = (val0 & AR8327_ATU_ADDR3) >> AR8327_ATU_ADDR3_S; -+ a->mac[4] = (val1 & AR8327_ATU_ADDR4) >> AR8327_ATU_ADDR4_S; -+ a->mac[5] = (val1 & AR8327_ATU_ADDR5) >> AR8327_ATU_ADDR5_S; -+ break; -+ } -+} -+ -+static int -+ar8327_sw_hw_apply(struct switch_dev *dev) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ const struct ar8327_data *data = priv->chip_data; -+ int ret, i; -+ -+ ret = ar8xxx_sw_hw_apply(dev); -+ if (ret) -+ return ret; -+ -+ for (i=0; i < AR8XXX_NUM_PHYS; i++) { -+ if (data->eee[i]) -+ ar8xxx_reg_clear(priv, AR8327_REG_EEE_CTRL, -+ AR8327_EEE_CTRL_DISABLE_PHY(i)); -+ else -+ ar8xxx_reg_set(priv, AR8327_REG_EEE_CTRL, -+ AR8327_EEE_CTRL_DISABLE_PHY(i)); -+ } -+ -+ return 0; -+} -+ -+static int -+ar8327_sw_get_port_igmp_snooping(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ int port = val->port_vlan; -+ -+ if (port >= dev->ports) -+ return -EINVAL; -+ -+ mutex_lock(&priv->reg_mutex); -+ val->value.i = ar8327_get_port_igmp(priv, port); -+ mutex_unlock(&priv->reg_mutex); -+ -+ return 0; -+} -+ -+static int -+ar8327_sw_set_port_igmp_snooping(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ int port = val->port_vlan; -+ -+ if (port >= dev->ports) -+ return -EINVAL; -+ -+ mutex_lock(&priv->reg_mutex); -+ ar8327_set_port_igmp(priv, port, val->value.i); -+ mutex_unlock(&priv->reg_mutex); -+ -+ return 0; -+} -+ -+static int -+ar8327_sw_get_igmp_snooping(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ int port; -+ -+ for (port = 0; port < dev->ports; port++) { -+ val->port_vlan = port; -+ if (ar8327_sw_get_port_igmp_snooping(dev, attr, val) || -+ !val->value.i) -+ break; -+ } -+ -+ return 0; -+} -+ -+static int -+ar8327_sw_set_igmp_snooping(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ int port; -+ -+ for (port = 0; port < dev->ports; port++) { -+ val->port_vlan = port; -+ if (ar8327_sw_set_port_igmp_snooping(dev, attr, val)) -+ break; -+ } -+ -+ return 0; -+} -+ -+static int -+ar8327_sw_get_igmp_v3(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ u32 val_reg; -+ -+ mutex_lock(&priv->reg_mutex); -+ val_reg = ar8xxx_read(priv, AR8327_REG_FRAME_ACK_CTRL1); -+ val->value.i = ((val_reg & AR8327_FRAME_ACK_CTRL_IGMP_V3_EN) != 0); -+ mutex_unlock(&priv->reg_mutex); -+ -+ return 0; -+} -+ -+static int -+ar8327_sw_set_igmp_v3(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ -+ mutex_lock(&priv->reg_mutex); -+ if (val->value.i) -+ ar8xxx_reg_set(priv, AR8327_REG_FRAME_ACK_CTRL1, -+ AR8327_FRAME_ACK_CTRL_IGMP_V3_EN); -+ else -+ ar8xxx_reg_clear(priv, AR8327_REG_FRAME_ACK_CTRL1, -+ AR8327_FRAME_ACK_CTRL_IGMP_V3_EN); -+ mutex_unlock(&priv->reg_mutex); -+ -+ return 0; -+} -+ -+static int -+ar8327_sw_set_port_vlan_prio(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ int port = val->port_vlan; -+ -+ if (port >= dev->ports) -+ return -EINVAL; -+ if (port == 0 || port == 6) -+ return -EOPNOTSUPP; -+ if (val->value.i < 0 || val->value.i > 7) -+ return -EINVAL; -+ -+ priv->port_vlan_prio[port] = val->value.i; -+ -+ return 0; -+} -+ -+static int -+ar8327_sw_get_port_vlan_prio(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); -+ int port = val->port_vlan; -+ -+ val->value.i = priv->port_vlan_prio[port]; -+ -+ return 0; -+} -+ -+static const struct switch_attr ar8327_sw_attr_globals[] = { -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_vlan", -+ .description = "Enable VLAN mode", -+ .set = ar8xxx_sw_set_vlan, -+ .get = ar8xxx_sw_get_vlan, -+ .max = 1 -+ }, -+ { -+ .type = SWITCH_TYPE_NOVAL, -+ .name = "reset_mibs", -+ .description = "Reset all MIB counters", -+ .set = ar8xxx_sw_set_reset_mibs, -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "ar8xxx_mib_poll_interval", -+ .description = "MIB polling interval in msecs (0 to disable)", -+ .set = ar8xxx_sw_set_mib_poll_interval, -+ .get = ar8xxx_sw_get_mib_poll_interval -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "ar8xxx_mib_type", -+ .description = "MIB type (0=basic 1=extended)", -+ .set = ar8xxx_sw_set_mib_type, -+ .get = ar8xxx_sw_get_mib_type -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_mirror_rx", -+ .description = "Enable mirroring of RX packets", -+ .set = ar8xxx_sw_set_mirror_rx_enable, -+ .get = ar8xxx_sw_get_mirror_rx_enable, -+ .max = 1 -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_mirror_tx", -+ .description = "Enable mirroring of TX packets", -+ .set = ar8xxx_sw_set_mirror_tx_enable, -+ .get = ar8xxx_sw_get_mirror_tx_enable, -+ .max = 1 -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "mirror_monitor_port", -+ .description = "Mirror monitor port", -+ .set = ar8xxx_sw_set_mirror_monitor_port, -+ .get = ar8xxx_sw_get_mirror_monitor_port, -+ .max = AR8327_NUM_PORTS - 1 -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "mirror_source_port", -+ .description = "Mirror source port", -+ .set = ar8xxx_sw_set_mirror_source_port, -+ .get = ar8xxx_sw_get_mirror_source_port, -+ .max = AR8327_NUM_PORTS - 1 -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "arl_age_time", -+ .description = "ARL age time (secs)", -+ .set = ar8xxx_sw_set_arl_age_time, -+ .get = ar8xxx_sw_get_arl_age_time, -+ }, -+ { -+ .type = SWITCH_TYPE_STRING, -+ .name = "arl_table", -+ .description = "Get ARL table", -+ .set = NULL, -+ .get = ar8xxx_sw_get_arl_table, -+ }, -+ { -+ .type = SWITCH_TYPE_NOVAL, -+ .name = "flush_arl_table", -+ .description = "Flush ARL table", -+ .set = ar8xxx_sw_set_flush_arl_table, -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "igmp_snooping", -+ .description = "Enable IGMP Snooping", -+ .set = ar8327_sw_set_igmp_snooping, -+ .get = ar8327_sw_get_igmp_snooping, -+ .max = 1 -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "igmp_v3", -+ .description = "Enable IGMPv3 support", -+ .set = ar8327_sw_set_igmp_v3, -+ .get = ar8327_sw_get_igmp_v3, -+ .max = 1 -+ }, -+}; -+ -+static const struct switch_attr ar8327_sw_attr_port[] = { -+ { -+ .type = SWITCH_TYPE_NOVAL, -+ .name = "reset_mib", -+ .description = "Reset single port MIB counters", -+ .set = ar8xxx_sw_set_port_reset_mib, -+ }, -+ { -+ .type = SWITCH_TYPE_STRING, -+ .name = "mib", -+ .description = "Get port's MIB counters", -+ .set = NULL, -+ .get = ar8xxx_sw_get_port_mib, -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_eee", -+ .description = "Enable EEE PHY sleep mode", -+ .set = ar8327_sw_set_eee, -+ .get = ar8327_sw_get_eee, -+ .max = 1, -+ }, -+ { -+ .type = SWITCH_TYPE_NOVAL, -+ .name = "flush_arl_table", -+ .description = "Flush port's ARL table entries", -+ .set = ar8xxx_sw_set_flush_port_arl_table, -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "igmp_snooping", -+ .description = "Enable port's IGMP Snooping", -+ .set = ar8327_sw_set_port_igmp_snooping, -+ .get = ar8327_sw_get_port_igmp_snooping, -+ .max = 1 -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "vlan_prio", -+ .description = "Port VLAN default priority (VLAN PCP) (0-7)", -+ .set = ar8327_sw_set_port_vlan_prio, -+ .get = ar8327_sw_get_port_vlan_prio, -+ .max = 7, -+ }, -+}; -+ -+static const struct switch_dev_ops ar8327_sw_ops = { -+ .attr_global = { -+ .attr = ar8327_sw_attr_globals, -+ .n_attr = ARRAY_SIZE(ar8327_sw_attr_globals), -+ }, -+ .attr_port = { -+ .attr = ar8327_sw_attr_port, -+ .n_attr = ARRAY_SIZE(ar8327_sw_attr_port), -+ }, -+ .attr_vlan = { -+ .attr = ar8xxx_sw_attr_vlan, -+ .n_attr = ARRAY_SIZE(ar8xxx_sw_attr_vlan), -+ }, -+ .get_port_pvid = ar8xxx_sw_get_pvid, -+ .set_port_pvid = ar8xxx_sw_set_pvid, -+ .get_vlan_ports = ar8327_sw_get_ports, -+ .set_vlan_ports = ar8327_sw_set_ports, -+ .apply_config = ar8327_sw_hw_apply, -+ .reset_switch = ar8xxx_sw_reset_switch, -+ .get_port_link = ar8xxx_sw_get_port_link, -+ .get_port_stats = ar8xxx_sw_get_port_stats, -+}; -+ -+const struct ar8xxx_chip ar8327_chip = { -+ .caps = AR8XXX_CAP_GIGE | AR8XXX_CAP_MIB_COUNTERS, -+ .config_at_probe = true, -+ .mii_lo_first = true, -+ -+ .name = "Atheros AR8327", -+ .ports = AR8327_NUM_PORTS, -+ .vlans = AR83X7_MAX_VLANS, -+ .swops = &ar8327_sw_ops, -+ -+ .reg_port_stats_start = 0x1000, -+ .reg_port_stats_length = 0x100, -+ .reg_arl_ctrl = AR8327_REG_ARL_CTRL, -+ -+ .hw_init = ar8327_hw_init, -+ .cleanup = ar8327_cleanup, -+ .init_globals = ar8327_init_globals, -+ .init_port = ar8327_init_port, -+ .setup_port = ar8327_setup_port, -+ .read_port_status = ar8327_read_port_status, -+ .read_port_eee_status = ar8327_read_port_eee_status, -+ .atu_flush = ar8327_atu_flush, -+ .atu_flush_port = ar8327_atu_flush_port, -+ .vtu_flush = ar8327_vtu_flush, -+ .vtu_load_vlan = ar8327_vtu_load_vlan, -+ .phy_fixup = ar8327_phy_fixup, -+ .set_mirror_regs = ar8327_set_mirror_regs, -+ .get_arl_entry = ar8327_get_arl_entry, -+ .sw_hw_apply = ar8327_sw_hw_apply, -+ -+ .num_mibs = ARRAY_SIZE(ar8236_mibs), -+ .mib_decs = ar8236_mibs, -+ .mib_func = AR8327_REG_MIB_FUNC, -+ .mib_rxb_id = AR8236_MIB_RXB_ID, -+ .mib_txb_id = AR8236_MIB_TXB_ID, -+}; -+ -+const struct ar8xxx_chip ar8337_chip = { -+ .caps = AR8XXX_CAP_GIGE | AR8XXX_CAP_MIB_COUNTERS, -+ .config_at_probe = true, -+ .mii_lo_first = true, -+ -+ .name = "Atheros AR8337", -+ .ports = AR8327_NUM_PORTS, -+ .vlans = AR83X7_MAX_VLANS, -+ .swops = &ar8327_sw_ops, -+ -+ .reg_port_stats_start = 0x1000, -+ .reg_port_stats_length = 0x100, -+ .reg_arl_ctrl = AR8327_REG_ARL_CTRL, -+ -+ .hw_init = ar8327_hw_init, -+ .cleanup = ar8327_cleanup, -+ .init_globals = ar8327_init_globals, -+ .init_port = ar8327_init_port, -+ .setup_port = ar8327_setup_port, -+ .read_port_status = ar8327_read_port_status, -+ .read_port_eee_status = ar8327_read_port_eee_status, -+ .atu_flush = ar8327_atu_flush, -+ .atu_flush_port = ar8327_atu_flush_port, -+ .vtu_flush = ar8327_vtu_flush, -+ .vtu_load_vlan = ar8327_vtu_load_vlan, -+ .phy_fixup = ar8327_phy_fixup, -+ .set_mirror_regs = ar8327_set_mirror_regs, -+ .get_arl_entry = ar8327_get_arl_entry, -+ .sw_hw_apply = ar8327_sw_hw_apply, -+ .phy_rgmii_set = ar8327_phy_rgmii_set, -+ -+ .num_mibs = ARRAY_SIZE(ar8236_mibs), -+ .mib_decs = ar8236_mibs, -+ .mib_func = AR8327_REG_MIB_FUNC, -+ .mib_rxb_id = AR8236_MIB_RXB_ID, -+ .mib_txb_id = AR8236_MIB_TXB_ID, -+}; -diff --git a/drivers/net/phy/ar8327.h b/drivers/net/phy/ar8327.h -new file mode 100644 -index 000000000000..53a82d1f76a3 ---- /dev/null -+++ b/drivers/net/phy/ar8327.h -@@ -0,0 +1,334 @@ -+/* -+ * ar8327.h: AR8216 switch driver -+ * -+ * Copyright (C) 2009 Felix Fietkau -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __AR8327_H -+#define __AR8327_H -+ -+#define AR8327_NUM_PORTS 7 -+#define AR8327_NUM_LEDS 15 -+#define AR8327_PORTS_ALL 0x7f -+#define AR8327_NUM_LED_CTRL_REGS 4 -+ -+#define AR8327_REG_MASK 0x000 -+ -+#define AR8327_REG_PAD0_MODE 0x004 -+#define AR8327_REG_PAD5_MODE 0x008 -+#define AR8327_REG_PAD6_MODE 0x00c -+#define AR8327_PAD_MAC_MII_RXCLK_SEL BIT(0) -+#define AR8327_PAD_MAC_MII_TXCLK_SEL BIT(1) -+#define AR8327_PAD_MAC_MII_EN BIT(2) -+#define AR8327_PAD_MAC_GMII_RXCLK_SEL BIT(4) -+#define AR8327_PAD_MAC_GMII_TXCLK_SEL BIT(5) -+#define AR8327_PAD_MAC_GMII_EN BIT(6) -+#define AR8327_PAD_SGMII_EN BIT(7) -+#define AR8327_PAD_PHY_MII_RXCLK_SEL BIT(8) -+#define AR8327_PAD_PHY_MII_TXCLK_SEL BIT(9) -+#define AR8327_PAD_PHY_MII_EN BIT(10) -+#define AR8327_PAD_PHY_GMII_PIPE_RXCLK_SEL BIT(11) -+#define AR8327_PAD_PHY_GMII_RXCLK_SEL BIT(12) -+#define AR8327_PAD_PHY_GMII_TXCLK_SEL BIT(13) -+#define AR8327_PAD_PHY_GMII_EN BIT(14) -+#define AR8327_PAD_PHYX_GMII_EN BIT(16) -+#define AR8327_PAD_PHYX_RGMII_EN BIT(17) -+#define AR8327_PAD_PHYX_MII_EN BIT(18) -+#define AR8327_PAD_SGMII_DELAY_EN BIT(19) -+#define AR8327_PAD_RGMII_RXCLK_DELAY_SEL BITS(20, 2) -+#define AR8327_PAD_RGMII_RXCLK_DELAY_SEL_S 20 -+#define AR8327_PAD_RGMII_TXCLK_DELAY_SEL BITS(22, 2) -+#define AR8327_PAD_RGMII_TXCLK_DELAY_SEL_S 22 -+#define AR8327_PAD_RGMII_RXCLK_DELAY_EN BIT(24) -+#define AR8327_PAD_RGMII_TXCLK_DELAY_EN BIT(25) -+#define AR8327_PAD_RGMII_EN BIT(26) -+ -+#define AR8327_REG_POWER_ON_STRAP 0x010 -+#define AR8327_POWER_ON_STRAP_POWER_ON_SEL BIT(31) -+#define AR8327_POWER_ON_STRAP_LED_OPEN_EN BIT(24) -+#define AR8327_POWER_ON_STRAP_SERDES_AEN BIT(7) -+ -+#define AR8327_REG_INT_STATUS0 0x020 -+#define AR8327_INT0_VT_DONE BIT(20) -+ -+#define AR8327_REG_INT_STATUS1 0x024 -+#define AR8327_REG_INT_MASK0 0x028 -+#define AR8327_REG_INT_MASK1 0x02c -+ -+#define AR8327_REG_MODULE_EN 0x030 -+#define AR8327_MODULE_EN_MIB BIT(0) -+ -+#define AR8327_REG_MIB_FUNC 0x034 -+#define AR8327_MIB_CPU_KEEP BIT(20) -+ -+#define AR8327_REG_SERVICE_TAG 0x048 -+#define AR8327_REG_LED_CTRL(_i) (0x050 + (_i) * 4) -+#define AR8327_REG_LED_CTRL0 0x050 -+#define AR8327_REG_LED_CTRL1 0x054 -+#define AR8327_REG_LED_CTRL2 0x058 -+#define AR8327_REG_LED_CTRL3 0x05c -+#define AR8327_REG_MAC_ADDR0 0x060 -+#define AR8327_REG_MAC_ADDR1 0x064 -+ -+#define AR8327_REG_MAX_FRAME_SIZE 0x078 -+#define AR8327_MAX_FRAME_SIZE_MTU BITS(0, 14) -+ -+#define AR8327_REG_PORT_STATUS(_i) (0x07c + (_i) * 4) -+#define AR8327_PORT_STATUS_TXFLOW_AUTO BIT(10) -+#define AR8327_PORT_STATUS_RXFLOW_AUTO BIT(11) -+ -+#define AR8327_REG_HEADER_CTRL 0x098 -+#define AR8327_REG_PORT_HEADER(_i) (0x09c + (_i) * 4) -+ -+#define AR8327_REG_SGMII_CTRL 0x0e0 -+#define AR8327_SGMII_CTRL_EN_PLL BIT(1) -+#define AR8327_SGMII_CTRL_EN_RX BIT(2) -+#define AR8327_SGMII_CTRL_EN_TX BIT(3) -+ -+#define AR8327_REG_EEE_CTRL 0x100 -+#define AR8327_EEE_CTRL_DISABLE_PHY(_i) BIT(4 + (_i) * 2) -+ -+#define AR8327_REG_FRAME_ACK_CTRL0 0x210 -+#define AR8327_FRAME_ACK_CTRL_IGMP_MLD_EN0 BIT(0) -+#define AR8327_FRAME_ACK_CTRL_IGMP_JOIN_EN0 BIT(1) -+#define AR8327_FRAME_ACK_CTRL_IGMP_LEAVE_EN0 BIT(2) -+#define AR8327_FRAME_ACK_CTRL_EAPOL_EN0 BIT(3) -+#define AR8327_FRAME_ACK_CTRL_DHCP_EN0 BIT(4) -+#define AR8327_FRAME_ACK_CTRL_ARP_ACK_EN0 BIT(5) -+#define AR8327_FRAME_ACK_CTRL_ARP_REQ_EN0 BIT(6) -+#define AR8327_FRAME_ACK_CTRL_IGMP_MLD_EN1 BIT(8) -+#define AR8327_FRAME_ACK_CTRL_IGMP_JOIN_EN1 BIT(9) -+#define AR8327_FRAME_ACK_CTRL_IGMP_LEAVE_EN1 BIT(10) -+#define AR8327_FRAME_ACK_CTRL_EAPOL_EN1 BIT(11) -+#define AR8327_FRAME_ACK_CTRL_DHCP_EN1 BIT(12) -+#define AR8327_FRAME_ACK_CTRL_ARP_ACK_EN1 BIT(13) -+#define AR8327_FRAME_ACK_CTRL_ARP_REQ_EN1 BIT(14) -+#define AR8327_FRAME_ACK_CTRL_IGMP_MLD_EN2 BIT(16) -+#define AR8327_FRAME_ACK_CTRL_IGMP_JOIN_EN2 BIT(17) -+#define AR8327_FRAME_ACK_CTRL_IGMP_LEAVE_EN2 BIT(18) -+#define AR8327_FRAME_ACK_CTRL_EAPOL_EN2 BIT(19) -+#define AR8327_FRAME_ACK_CTRL_DHCP_EN2 BIT(20) -+#define AR8327_FRAME_ACK_CTRL_ARP_ACK_EN2 BIT(21) -+#define AR8327_FRAME_ACK_CTRL_ARP_REQ_EN2 BIT(22) -+#define AR8327_FRAME_ACK_CTRL_IGMP_MLD_EN3 BIT(24) -+#define AR8327_FRAME_ACK_CTRL_IGMP_JOIN_EN3 BIT(25) -+#define AR8327_FRAME_ACK_CTRL_IGMP_LEAVE_EN3 BIT(26) -+#define AR8327_FRAME_ACK_CTRL_EAPOL_EN3 BIT(27) -+#define AR8327_FRAME_ACK_CTRL_DHCP_EN3 BIT(28) -+#define AR8327_FRAME_ACK_CTRL_ARP_ACK_EN3 BIT(29) -+#define AR8327_FRAME_ACK_CTRL_ARP_REQ_EN3 BIT(30) -+ -+#define AR8327_REG_FRAME_ACK_CTRL1 0x214 -+#define AR8327_FRAME_ACK_CTRL_IGMP_MLD_EN4 BIT(0) -+#define AR8327_FRAME_ACK_CTRL_IGMP_JOIN_EN4 BIT(1) -+#define AR8327_FRAME_ACK_CTRL_IGMP_LEAVE_EN4 BIT(2) -+#define AR8327_FRAME_ACK_CTRL_EAPOL_EN4 BIT(3) -+#define AR8327_FRAME_ACK_CTRL_DHCP_EN4 BIT(4) -+#define AR8327_FRAME_ACK_CTRL_ARP_ACK_EN4 BIT(5) -+#define AR8327_FRAME_ACK_CTRL_ARP_REQ_EN4 BIT(6) -+#define AR8327_FRAME_ACK_CTRL_IGMP_MLD_EN5 BIT(8) -+#define AR8327_FRAME_ACK_CTRL_IGMP_JOIN_EN5 BIT(9) -+#define AR8327_FRAME_ACK_CTRL_IGMP_LEAVE_EN5 BIT(10) -+#define AR8327_FRAME_ACK_CTRL_EAPOL_EN5 BIT(11) -+#define AR8327_FRAME_ACK_CTRL_DHCP_EN5 BIT(12) -+#define AR8327_FRAME_ACK_CTRL_ARP_ACK_EN5 BIT(13) -+#define AR8327_FRAME_ACK_CTRL_ARP_REQ_EN5 BIT(14) -+#define AR8327_FRAME_ACK_CTRL_IGMP_MLD_EN6 BIT(16) -+#define AR8327_FRAME_ACK_CTRL_IGMP_JOIN_EN6 BIT(17) -+#define AR8327_FRAME_ACK_CTRL_IGMP_LEAVE_EN6 BIT(18) -+#define AR8327_FRAME_ACK_CTRL_EAPOL_EN6 BIT(19) -+#define AR8327_FRAME_ACK_CTRL_DHCP_EN6 BIT(20) -+#define AR8327_FRAME_ACK_CTRL_ARP_ACK_EN6 BIT(21) -+#define AR8327_FRAME_ACK_CTRL_ARP_REQ_EN6 BIT(22) -+#define AR8327_FRAME_ACK_CTRL_IGMP_V3_EN BIT(24) -+#define AR8327_FRAME_ACK_CTRL_PPPOE_EN BIT(25) -+ -+#define AR8327_REG_FRAME_ACK_CTRL(_i) (0x210 + ((_i) / 4) * 0x4) -+#define AR8327_FRAME_ACK_CTRL_IGMP_MLD BIT(0) -+#define AR8327_FRAME_ACK_CTRL_IGMP_JOIN BIT(1) -+#define AR8327_FRAME_ACK_CTRL_IGMP_LEAVE BIT(2) -+#define AR8327_FRAME_ACK_CTRL_EAPOL BIT(3) -+#define AR8327_FRAME_ACK_CTRL_DHCP BIT(4) -+#define AR8327_FRAME_ACK_CTRL_ARP_ACK BIT(5) -+#define AR8327_FRAME_ACK_CTRL_ARP_REQ BIT(6) -+#define AR8327_FRAME_ACK_CTRL_S(_i) (((_i) % 4) * 8) -+ -+#define AR8327_REG_PORT_VLAN0(_i) (0x420 + (_i) * 0x8) -+#define AR8327_PORT_VLAN0_DEF_PRI_MASK BITS(0, 3) -+#define AR8327_PORT_VLAN0_DEF_SVID BITS(0, 12) -+#define AR8327_PORT_VLAN0_DEF_SVID_S 0 -+#define AR8327_PORT_VLAN0_DEF_SPRI BITS(13, 3) -+#define AR8327_PORT_VLAN0_DEF_SPRI_S 13 -+#define AR8327_PORT_VLAN0_DEF_CVID BITS(16, 12) -+#define AR8327_PORT_VLAN0_DEF_CVID_S 16 -+#define AR8327_PORT_VLAN0_DEF_CPRI BITS(29, 3) -+#define AR8327_PORT_VLAN0_DEF_CPRI_S 29 -+ -+#define AR8327_REG_PORT_VLAN1(_i) (0x424 + (_i) * 0x8) -+#define AR8327_PORT_VLAN1_VLAN_PRI_PROP BIT(4) -+#define AR8327_PORT_VLAN1_PORT_VLAN_PROP BIT(6) -+#define AR8327_PORT_VLAN1_OUT_MODE BITS(12, 2) -+#define AR8327_PORT_VLAN1_OUT_MODE_S 12 -+#define AR8327_PORT_VLAN1_OUT_MODE_UNMOD 0 -+#define AR8327_PORT_VLAN1_OUT_MODE_UNTAG 1 -+#define AR8327_PORT_VLAN1_OUT_MODE_TAG 2 -+#define AR8327_PORT_VLAN1_OUT_MODE_UNTOUCH 3 -+ -+#define AR8327_REG_ATU_DATA0 0x600 -+#define AR8327_ATU_ADDR0 BITS(0, 8) -+#define AR8327_ATU_ADDR0_S 0 -+#define AR8327_ATU_ADDR1 BITS(8, 8) -+#define AR8327_ATU_ADDR1_S 8 -+#define AR8327_ATU_ADDR2 BITS(16, 8) -+#define AR8327_ATU_ADDR2_S 16 -+#define AR8327_ATU_ADDR3 BITS(24, 8) -+#define AR8327_ATU_ADDR3_S 24 -+#define AR8327_REG_ATU_DATA1 0x604 -+#define AR8327_ATU_ADDR4 BITS(0, 8) -+#define AR8327_ATU_ADDR4_S 0 -+#define AR8327_ATU_ADDR5 BITS(8, 8) -+#define AR8327_ATU_ADDR5_S 8 -+#define AR8327_ATU_PORTS BITS(16, 7) -+#define AR8327_ATU_PORTS_S 16 -+#define AR8327_ATU_PORT0 BIT(16) -+#define AR8327_ATU_PORT1 BIT(17) -+#define AR8327_ATU_PORT2 BIT(18) -+#define AR8327_ATU_PORT3 BIT(19) -+#define AR8327_ATU_PORT4 BIT(20) -+#define AR8327_ATU_PORT5 BIT(21) -+#define AR8327_ATU_PORT6 BIT(22) -+#define AR8327_REG_ATU_DATA2 0x608 -+#define AR8327_ATU_STATUS BITS(0, 4) -+ -+#define AR8327_REG_ATU_FUNC 0x60c -+#define AR8327_ATU_FUNC_OP BITS(0, 4) -+#define AR8327_ATU_FUNC_OP_NOOP 0x0 -+#define AR8327_ATU_FUNC_OP_FLUSH 0x1 -+#define AR8327_ATU_FUNC_OP_LOAD 0x2 -+#define AR8327_ATU_FUNC_OP_PURGE 0x3 -+#define AR8327_ATU_FUNC_OP_FLUSH_UNLOCKED 0x4 -+#define AR8327_ATU_FUNC_OP_FLUSH_PORT 0x5 -+#define AR8327_ATU_FUNC_OP_GET_NEXT 0x6 -+#define AR8327_ATU_FUNC_OP_SEARCH_MAC 0x7 -+#define AR8327_ATU_FUNC_OP_CHANGE_TRUNK 0x8 -+#define AR8327_ATU_PORT_NUM BITS(8, 4) -+#define AR8327_ATU_PORT_NUM_S 8 -+#define AR8327_ATU_FUNC_BUSY BIT(31) -+ -+#define AR8327_REG_VTU_FUNC0 0x0610 -+#define AR8327_VTU_FUNC0_EG_MODE BITS(4, 14) -+#define AR8327_VTU_FUNC0_EG_MODE_S(_i) (4 + (_i) * 2) -+#define AR8327_VTU_FUNC0_EG_MODE_KEEP 0 -+#define AR8327_VTU_FUNC0_EG_MODE_UNTAG 1 -+#define AR8327_VTU_FUNC0_EG_MODE_TAG 2 -+#define AR8327_VTU_FUNC0_EG_MODE_NOT 3 -+#define AR8327_VTU_FUNC0_IVL BIT(19) -+#define AR8327_VTU_FUNC0_VALID BIT(20) -+ -+#define AR8327_REG_VTU_FUNC1 0x0614 -+#define AR8327_VTU_FUNC1_OP BITS(0, 3) -+#define AR8327_VTU_FUNC1_OP_NOOP 0 -+#define AR8327_VTU_FUNC1_OP_FLUSH 1 -+#define AR8327_VTU_FUNC1_OP_LOAD 2 -+#define AR8327_VTU_FUNC1_OP_PURGE 3 -+#define AR8327_VTU_FUNC1_OP_REMOVE_PORT 4 -+#define AR8327_VTU_FUNC1_OP_GET_NEXT 5 -+#define AR8327_VTU_FUNC1_OP_GET_ONE 6 -+#define AR8327_VTU_FUNC1_FULL BIT(4) -+#define AR8327_VTU_FUNC1_PORT BIT(8, 4) -+#define AR8327_VTU_FUNC1_PORT_S 8 -+#define AR8327_VTU_FUNC1_VID BIT(16, 12) -+#define AR8327_VTU_FUNC1_VID_S 16 -+#define AR8327_VTU_FUNC1_BUSY BIT(31) -+ -+#define AR8327_REG_ARL_CTRL 0x0618 -+ -+#define AR8327_REG_FWD_CTRL0 0x620 -+#define AR8327_FWD_CTRL0_CPU_PORT_EN BIT(10) -+#define AR8327_FWD_CTRL0_MIRROR_PORT BITS(4, 4) -+#define AR8327_FWD_CTRL0_MIRROR_PORT_S 4 -+ -+#define AR8327_REG_FWD_CTRL1 0x624 -+#define AR8327_FWD_CTRL1_UC_FLOOD BITS(0, 7) -+#define AR8327_FWD_CTRL1_UC_FLOOD_S 0 -+#define AR8327_FWD_CTRL1_MC_FLOOD BITS(8, 7) -+#define AR8327_FWD_CTRL1_MC_FLOOD_S 8 -+#define AR8327_FWD_CTRL1_BC_FLOOD BITS(16, 7) -+#define AR8327_FWD_CTRL1_BC_FLOOD_S 16 -+#define AR8327_FWD_CTRL1_IGMP BITS(24, 7) -+#define AR8327_FWD_CTRL1_IGMP_S 24 -+ -+#define AR8327_REG_PORT_LOOKUP(_i) (0x660 + (_i) * 0xc) -+#define AR8327_PORT_LOOKUP_MEMBER BITS(0, 7) -+#define AR8327_PORT_LOOKUP_IN_MODE BITS(8, 2) -+#define AR8327_PORT_LOOKUP_IN_MODE_S 8 -+#define AR8327_PORT_LOOKUP_STATE BITS(16, 3) -+#define AR8327_PORT_LOOKUP_STATE_S 16 -+#define AR8327_PORT_LOOKUP_LEARN BIT(20) -+#define AR8327_PORT_LOOKUP_ING_MIRROR_EN BIT(25) -+ -+#define AR8327_REG_PORT_PRIO(_i) (0x664 + (_i) * 0xc) -+ -+#define AR8327_REG_PORT_HOL_CTRL1(_i) (0x974 + (_i) * 0x8) -+#define AR8327_PORT_HOL_CTRL1_EG_MIRROR_EN BIT(16) -+ -+#define AR8337_PAD_MAC06_EXCHANGE_EN BIT(31) -+ -+#define AR8327_PHY_MODE_SEL 0x12 -+#define AR8327_PHY_MODE_SEL_RGMII BIT(3) -+#define AR8327_PHY_TEST_CTRL 0x0 -+#define AR8327_PHY_TEST_CTRL_RGMII_RX_DELAY BIT(15) -+#define AR8327_PHY_SYS_CTRL 0x5 -+#define AR8327_PHY_SYS_CTRL_RGMII_TX_DELAY BIT(8) -+ -+enum ar8327_led_pattern { -+ AR8327_LED_PATTERN_OFF = 0, -+ AR8327_LED_PATTERN_BLINK, -+ AR8327_LED_PATTERN_ON, -+ AR8327_LED_PATTERN_RULE, -+}; -+ -+struct ar8327_led_entry { -+ unsigned reg; -+ unsigned shift; -+}; -+ -+struct ar8327_led { -+ struct led_classdev cdev; -+ struct ar8xxx_priv *sw_priv; -+ -+ char *name; -+ bool active_low; -+ u8 led_num; -+ enum ar8327_led_mode mode; -+ -+ struct mutex mutex; -+ spinlock_t lock; -+ struct work_struct led_work; -+ bool enable_hw_mode; -+ enum ar8327_led_pattern pattern; -+ struct fwnode_handle *fwnode; -+}; -+ -+struct ar8327_data { -+ u32 port0_status; -+ u32 port6_status; -+ -+ struct ar8327_led **leds; -+ unsigned int num_leds; -+ -+ /* all fields below are cleared on reset */ -+ bool eee[AR8XXX_NUM_PHYS]; -+}; -+ -+#endif -diff --git a/drivers/net/phy/b53/Kconfig b/drivers/net/phy/b53/Kconfig -new file mode 100644 -index 000000000000..08287e7adf79 ---- /dev/null -+++ b/drivers/net/phy/b53/Kconfig -@@ -0,0 +1,37 @@ -+menuconfig SWCONFIG_B53 -+ tristate "Broadcom bcm53xx managed switch support" -+ depends on SWCONFIG -+ help -+ This driver adds support for Broadcom managed switch chips. It supports -+ BCM5325E, BCM5365, BCM539x, BCM53115 and BCM53125 as well as BCM63XX -+ integrated switches. -+ -+config SWCONFIG_B53_SPI_DRIVER -+ tristate "B53 SPI connected switch driver" -+ depends on SWCONFIG_B53 && SPI -+ help -+ Select to enable support for registering switches configured through SPI. -+ -+config SWCONFIG_B53_PHY_DRIVER -+ tristate "B53 MDIO connected switch driver" -+ depends on SWCONFIG_B53 -+ select SWCONFIG_B53_PHY_FIXUP -+ help -+ Select to enable support for registering switches configured through MDIO. -+ -+config SWCONFIG_B53_MMAP_DRIVER -+ tristate "B53 MMAP connected switch driver" -+ depends on SWCONFIG_B53 -+ help -+ Select to enable support for memory-mapped switches like the BCM63XX -+ integrated switches. -+ -+config SWCONFIG_B53_SRAB_DRIVER -+ tristate "B53 SRAB connected switch driver" -+ depends on SWCONFIG_B53 -+ help -+ Select to enable support for memory-mapped Switch Register Access -+ Bridge Registers (SRAB) like it is found on the BCM53010 -+ -+config SWCONFIG_B53_PHY_FIXUP -+ bool -diff --git a/drivers/net/phy/b53/Makefile b/drivers/net/phy/b53/Makefile -new file mode 100644 -index 000000000000..13ff366448df ---- /dev/null -+++ b/drivers/net/phy/b53/Makefile -@@ -0,0 +1,10 @@ -+obj-$(CONFIG_SWCONFIG_B53) += b53_common.o -+ -+obj-$(CONFIG_SWCONFIG_B53_PHY_FIXUP) += b53_phy_fixup.o -+ -+obj-$(CONFIG_SWCONFIG_B53_MMAP_DRIVER) += b53_mmap.o -+obj-$(CONFIG_SWCONFIG_B53_SRAB_DRIVER) += b53_srab.o -+obj-$(CONFIG_SWCONFIG_B53_PHY_DRIVER) += b53_mdio.o -+obj-$(CONFIG_SWCONFIG_B53_SPI_DRIVER) += b53_spi.o -+ -+ccflags-y += -Werror -diff --git a/drivers/net/phy/b53/b53_common.c b/drivers/net/phy/b53/b53_common.c -new file mode 100644 -index 000000000000..d5f9bfc2f043 ---- /dev/null -+++ b/drivers/net/phy/b53/b53_common.c -@@ -0,0 +1,1724 @@ -+/* -+ * B53 switch driver main logic -+ * -+ * Copyright (C) 2011-2013 Jonas Gorski -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "b53_regs.h" -+#include "b53_priv.h" -+ -+/* buffer size needed for displaying all MIBs with max'd values */ -+#define B53_BUF_SIZE 1188 -+ -+struct b53_mib_desc { -+ u8 size; -+ u8 offset; -+ const char *name; -+}; -+ -+/* BCM5365 MIB counters */ -+static const struct b53_mib_desc b53_mibs_65[] = { -+ { 8, 0x00, "TxOctets" }, -+ { 4, 0x08, "TxDropPkts" }, -+ { 4, 0x10, "TxBroadcastPkts" }, -+ { 4, 0x14, "TxMulticastPkts" }, -+ { 4, 0x18, "TxUnicastPkts" }, -+ { 4, 0x1c, "TxCollisions" }, -+ { 4, 0x20, "TxSingleCollision" }, -+ { 4, 0x24, "TxMultipleCollision" }, -+ { 4, 0x28, "TxDeferredTransmit" }, -+ { 4, 0x2c, "TxLateCollision" }, -+ { 4, 0x30, "TxExcessiveCollision" }, -+ { 4, 0x38, "TxPausePkts" }, -+ { 8, 0x44, "RxOctets" }, -+ { 4, 0x4c, "RxUndersizePkts" }, -+ { 4, 0x50, "RxPausePkts" }, -+ { 4, 0x54, "Pkts64Octets" }, -+ { 4, 0x58, "Pkts65to127Octets" }, -+ { 4, 0x5c, "Pkts128to255Octets" }, -+ { 4, 0x60, "Pkts256to511Octets" }, -+ { 4, 0x64, "Pkts512to1023Octets" }, -+ { 4, 0x68, "Pkts1024to1522Octets" }, -+ { 4, 0x6c, "RxOversizePkts" }, -+ { 4, 0x70, "RxJabbers" }, -+ { 4, 0x74, "RxAlignmentErrors" }, -+ { 4, 0x78, "RxFCSErrors" }, -+ { 8, 0x7c, "RxGoodOctets" }, -+ { 4, 0x84, "RxDropPkts" }, -+ { 4, 0x88, "RxUnicastPkts" }, -+ { 4, 0x8c, "RxMulticastPkts" }, -+ { 4, 0x90, "RxBroadcastPkts" }, -+ { 4, 0x94, "RxSAChanges" }, -+ { 4, 0x98, "RxFragments" }, -+ { }, -+}; -+ -+#define B63XX_MIB_TXB_ID 0 /* TxOctets */ -+#define B63XX_MIB_RXB_ID 14 /* RxOctets */ -+ -+/* BCM63xx MIB counters */ -+static const struct b53_mib_desc b53_mibs_63xx[] = { -+ { 8, 0x00, "TxOctets" }, -+ { 4, 0x08, "TxDropPkts" }, -+ { 4, 0x0c, "TxQoSPkts" }, -+ { 4, 0x10, "TxBroadcastPkts" }, -+ { 4, 0x14, "TxMulticastPkts" }, -+ { 4, 0x18, "TxUnicastPkts" }, -+ { 4, 0x1c, "TxCollisions" }, -+ { 4, 0x20, "TxSingleCollision" }, -+ { 4, 0x24, "TxMultipleCollision" }, -+ { 4, 0x28, "TxDeferredTransmit" }, -+ { 4, 0x2c, "TxLateCollision" }, -+ { 4, 0x30, "TxExcessiveCollision" }, -+ { 4, 0x38, "TxPausePkts" }, -+ { 8, 0x3c, "TxQoSOctets" }, -+ { 8, 0x44, "RxOctets" }, -+ { 4, 0x4c, "RxUndersizePkts" }, -+ { 4, 0x50, "RxPausePkts" }, -+ { 4, 0x54, "Pkts64Octets" }, -+ { 4, 0x58, "Pkts65to127Octets" }, -+ { 4, 0x5c, "Pkts128to255Octets" }, -+ { 4, 0x60, "Pkts256to511Octets" }, -+ { 4, 0x64, "Pkts512to1023Octets" }, -+ { 4, 0x68, "Pkts1024to1522Octets" }, -+ { 4, 0x6c, "RxOversizePkts" }, -+ { 4, 0x70, "RxJabbers" }, -+ { 4, 0x74, "RxAlignmentErrors" }, -+ { 4, 0x78, "RxFCSErrors" }, -+ { 8, 0x7c, "RxGoodOctets" }, -+ { 4, 0x84, "RxDropPkts" }, -+ { 4, 0x88, "RxUnicastPkts" }, -+ { 4, 0x8c, "RxMulticastPkts" }, -+ { 4, 0x90, "RxBroadcastPkts" }, -+ { 4, 0x94, "RxSAChanges" }, -+ { 4, 0x98, "RxFragments" }, -+ { 4, 0xa0, "RxSymbolErrors" }, -+ { 4, 0xa4, "RxQoSPkts" }, -+ { 8, 0xa8, "RxQoSOctets" }, -+ { 4, 0xb0, "Pkts1523to2047Octets" }, -+ { 4, 0xb4, "Pkts2048to4095Octets" }, -+ { 4, 0xb8, "Pkts4096to8191Octets" }, -+ { 4, 0xbc, "Pkts8192to9728Octets" }, -+ { 4, 0xc0, "RxDiscarded" }, -+ { } -+}; -+ -+#define B53XX_MIB_TXB_ID 0 /* TxOctets */ -+#define B53XX_MIB_RXB_ID 12 /* RxOctets */ -+ -+/* MIB counters */ -+static const struct b53_mib_desc b53_mibs[] = { -+ { 8, 0x00, "TxOctets" }, -+ { 4, 0x08, "TxDropPkts" }, -+ { 4, 0x10, "TxBroadcastPkts" }, -+ { 4, 0x14, "TxMulticastPkts" }, -+ { 4, 0x18, "TxUnicastPkts" }, -+ { 4, 0x1c, "TxCollisions" }, -+ { 4, 0x20, "TxSingleCollision" }, -+ { 4, 0x24, "TxMultipleCollision" }, -+ { 4, 0x28, "TxDeferredTransmit" }, -+ { 4, 0x2c, "TxLateCollision" }, -+ { 4, 0x30, "TxExcessiveCollision" }, -+ { 4, 0x38, "TxPausePkts" }, -+ { 8, 0x50, "RxOctets" }, -+ { 4, 0x58, "RxUndersizePkts" }, -+ { 4, 0x5c, "RxPausePkts" }, -+ { 4, 0x60, "Pkts64Octets" }, -+ { 4, 0x64, "Pkts65to127Octets" }, -+ { 4, 0x68, "Pkts128to255Octets" }, -+ { 4, 0x6c, "Pkts256to511Octets" }, -+ { 4, 0x70, "Pkts512to1023Octets" }, -+ { 4, 0x74, "Pkts1024to1522Octets" }, -+ { 4, 0x78, "RxOversizePkts" }, -+ { 4, 0x7c, "RxJabbers" }, -+ { 4, 0x80, "RxAlignmentErrors" }, -+ { 4, 0x84, "RxFCSErrors" }, -+ { 8, 0x88, "RxGoodOctets" }, -+ { 4, 0x90, "RxDropPkts" }, -+ { 4, 0x94, "RxUnicastPkts" }, -+ { 4, 0x98, "RxMulticastPkts" }, -+ { 4, 0x9c, "RxBroadcastPkts" }, -+ { 4, 0xa0, "RxSAChanges" }, -+ { 4, 0xa4, "RxFragments" }, -+ { 4, 0xa8, "RxJumboPkts" }, -+ { 4, 0xac, "RxSymbolErrors" }, -+ { 4, 0xc0, "RxDiscarded" }, -+ { } -+}; -+ -+static int b53_do_vlan_op(struct b53_device *dev, u8 op) -+{ -+ unsigned int i; -+ -+ b53_write8(dev, B53_ARLIO_PAGE, dev->vta_regs[0], VTA_START_CMD | op); -+ -+ for (i = 0; i < 10; i++) { -+ u8 vta; -+ -+ b53_read8(dev, B53_ARLIO_PAGE, dev->vta_regs[0], &vta); -+ if (!(vta & VTA_START_CMD)) -+ return 0; -+ -+ usleep_range(100, 200); -+ } -+ -+ return -EIO; -+} -+ -+static void b53_set_vlan_entry(struct b53_device *dev, u16 vid, u16 members, -+ u16 untag) -+{ -+ if (is5325(dev)) { -+ u32 entry = 0; -+ -+ if (members) { -+ entry = ((untag & VA_UNTAG_MASK_25) << VA_UNTAG_S_25) | -+ members; -+ if (dev->core_rev >= 3) -+ entry |= VA_VALID_25_R4 | vid << VA_VID_HIGH_S; -+ else -+ entry |= VA_VALID_25; -+ } -+ -+ b53_write32(dev, B53_VLAN_PAGE, B53_VLAN_WRITE_25, entry); -+ b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_25, vid | -+ VTA_RW_STATE_WR | VTA_RW_OP_EN); -+ } else if (is5365(dev)) { -+ u16 entry = 0; -+ -+ if (members) -+ entry = ((untag & VA_UNTAG_MASK_65) << VA_UNTAG_S_65) | -+ members | VA_VALID_65; -+ -+ b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_WRITE_65, entry); -+ b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_65, vid | -+ VTA_RW_STATE_WR | VTA_RW_OP_EN); -+ } else { -+ b53_write16(dev, B53_ARLIO_PAGE, dev->vta_regs[1], vid); -+ b53_write32(dev, B53_ARLIO_PAGE, dev->vta_regs[2], -+ (untag << VTE_UNTAG_S) | members); -+ -+ b53_do_vlan_op(dev, VTA_CMD_WRITE); -+ } -+} -+ -+void b53_set_forwarding(struct b53_device *dev, int enable) -+{ -+ u8 mgmt; -+ -+ b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt); -+ -+ if (enable) -+ mgmt |= SM_SW_FWD_EN; -+ else -+ mgmt &= ~SM_SW_FWD_EN; -+ -+ b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, mgmt); -+} -+ -+static void b53_enable_vlan(struct b53_device *dev, int enable) -+{ -+ u8 mgmt, vc0, vc1, vc4 = 0, vc5; -+ -+ b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt); -+ b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL0, &vc0); -+ b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL1, &vc1); -+ -+ if (is5325(dev) || is5365(dev)) { -+ b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_25, &vc4); -+ b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5_25, &vc5); -+ } else if (is63xx(dev)) { -+ b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_63XX, &vc4); -+ b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5_63XX, &vc5); -+ } else { -+ b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4, &vc4); -+ b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5, &vc5); -+ } -+ -+ mgmt &= ~SM_SW_FWD_MODE; -+ -+ if (enable) { -+ vc0 |= VC0_VLAN_EN | VC0_VID_CHK_EN | VC0_VID_HASH_VID; -+ vc1 |= VC1_RX_MCST_UNTAG_EN | VC1_RX_MCST_FWD_EN; -+ vc4 &= ~VC4_ING_VID_CHECK_MASK; -+ vc4 |= VC4_ING_VID_VIO_DROP << VC4_ING_VID_CHECK_S; -+ vc5 |= VC5_DROP_VTABLE_MISS; -+ -+ if (is5325(dev)) -+ vc0 &= ~VC0_RESERVED_1; -+ -+ if (is5325(dev) || is5365(dev)) -+ vc1 |= VC1_RX_MCST_TAG_EN; -+ -+ if (!is5325(dev) && !is5365(dev)) { -+ if (dev->allow_vid_4095) -+ vc5 |= VC5_VID_FFF_EN; -+ else -+ vc5 &= ~VC5_VID_FFF_EN; -+ } -+ } else { -+ vc0 &= ~(VC0_VLAN_EN | VC0_VID_CHK_EN | VC0_VID_HASH_VID); -+ vc1 &= ~(VC1_RX_MCST_UNTAG_EN | VC1_RX_MCST_FWD_EN); -+ vc4 &= ~VC4_ING_VID_CHECK_MASK; -+ vc5 &= ~VC5_DROP_VTABLE_MISS; -+ -+ if (is5325(dev) || is5365(dev)) -+ vc4 |= VC4_ING_VID_VIO_FWD << VC4_ING_VID_CHECK_S; -+ else -+ vc4 |= VC4_ING_VID_VIO_TO_IMP << VC4_ING_VID_CHECK_S; -+ -+ if (is5325(dev) || is5365(dev)) -+ vc1 &= ~VC1_RX_MCST_TAG_EN; -+ -+ if (!is5325(dev) && !is5365(dev)) -+ vc5 &= ~VC5_VID_FFF_EN; -+ } -+ -+ b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL0, vc0); -+ b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL1, vc1); -+ -+ if (is5325(dev) || is5365(dev)) { -+ /* enable the high 8 bit vid check on 5325 */ -+ if (is5325(dev) && enable) -+ b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL3, -+ VC3_HIGH_8BIT_EN); -+ else -+ b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL3, 0); -+ -+ b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_25, vc4); -+ b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5_25, vc5); -+ } else if (is63xx(dev)) { -+ b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_CTRL3_63XX, 0); -+ b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_63XX, vc4); -+ b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5_63XX, vc5); -+ } else { -+ b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_CTRL3, 0); -+ b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4, vc4); -+ b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5, vc5); -+ } -+ -+ b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, mgmt); -+} -+ -+static int b53_set_jumbo(struct b53_device *dev, int enable, int allow_10_100) -+{ -+ u32 port_mask = 0; -+ u16 max_size = JMS_MIN_SIZE; -+ -+ if (is5325(dev) || is5365(dev)) -+ return -EINVAL; -+ -+ if (enable) { -+ port_mask = dev->enabled_ports; -+ max_size = JMS_MAX_SIZE; -+ if (allow_10_100) -+ port_mask |= JPM_10_100_JUMBO_EN; -+ } -+ -+ b53_write32(dev, B53_JUMBO_PAGE, dev->jumbo_pm_reg, port_mask); -+ return b53_write16(dev, B53_JUMBO_PAGE, dev->jumbo_size_reg, max_size); -+} -+ -+static int b53_flush_arl(struct b53_device *dev) -+{ -+ unsigned int i; -+ -+ b53_write8(dev, B53_CTRL_PAGE, B53_FAST_AGE_CTRL, -+ FAST_AGE_DONE | FAST_AGE_DYNAMIC | FAST_AGE_STATIC); -+ -+ for (i = 0; i < 10; i++) { -+ u8 fast_age_ctrl; -+ -+ b53_read8(dev, B53_CTRL_PAGE, B53_FAST_AGE_CTRL, -+ &fast_age_ctrl); -+ -+ if (!(fast_age_ctrl & FAST_AGE_DONE)) -+ return 0; -+ -+ mdelay(1); -+ } -+ -+ pr_warn("time out while flushing ARL\n"); -+ -+ return -EINVAL; -+} -+ -+static void b53_enable_ports(struct b53_device *dev) -+{ -+ unsigned i; -+ -+ b53_for_each_port(dev, i) { -+ u8 port_ctrl; -+ u16 pvlan_mask; -+ -+ /* -+ * prevent leaking packets between wan and lan in unmanaged -+ * mode through port vlans. -+ */ -+ if (dev->enable_vlan || is_cpu_port(dev, i)) -+ pvlan_mask = 0x1ff; -+ else if (is531x5(dev) || is5301x(dev)) -+ /* BCM53115 may use a different port as cpu port */ -+ pvlan_mask = BIT(dev->sw_dev.cpu_port); -+ else -+ pvlan_mask = BIT(B53_CPU_PORT); -+ -+ /* BCM5325 CPU port is at 8 */ -+ if ((is5325(dev) || is5365(dev)) && i == B53_CPU_PORT_25) -+ i = B53_CPU_PORT; -+ -+ if (dev->chip_id == BCM5398_DEVICE_ID && (i == 6 || i == 7)) -+ /* disable unused ports 6 & 7 */ -+ port_ctrl = PORT_CTRL_RX_DISABLE | PORT_CTRL_TX_DISABLE; -+ else if (i == B53_CPU_PORT) -+ port_ctrl = PORT_CTRL_RX_BCST_EN | -+ PORT_CTRL_RX_MCST_EN | -+ PORT_CTRL_RX_UCST_EN; -+ else -+ port_ctrl = 0; -+ -+ b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), -+ pvlan_mask); -+ -+ /* port state is handled by bcm63xx_enet driver */ -+ if (!is63xx(dev) && !(is5301x(dev) && i == 6)) -+ b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(i), -+ port_ctrl); -+ } -+} -+ -+static void b53_enable_mib(struct b53_device *dev) -+{ -+ u8 gc; -+ -+ b53_read8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, &gc); -+ -+ gc &= ~(GC_RESET_MIB | GC_MIB_AC_EN); -+ -+ b53_write8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, gc); -+} -+ -+static int b53_apply(struct b53_device *dev) -+{ -+ int i; -+ -+ /* clear all vlan entries */ -+ if (is5325(dev) || is5365(dev)) { -+ for (i = 1; i < dev->sw_dev.vlans; i++) -+ b53_set_vlan_entry(dev, i, 0, 0); -+ } else { -+ b53_do_vlan_op(dev, VTA_CMD_CLEAR); -+ } -+ -+ b53_enable_vlan(dev, dev->enable_vlan); -+ -+ /* fill VLAN table */ -+ if (dev->enable_vlan) { -+ for (i = 0; i < dev->sw_dev.vlans; i++) { -+ struct b53_vlan *vlan = &dev->vlans[i]; -+ -+ if (!vlan->members) -+ continue; -+ -+ b53_set_vlan_entry(dev, i, vlan->members, vlan->untag); -+ } -+ -+ b53_for_each_port(dev, i) -+ b53_write16(dev, B53_VLAN_PAGE, -+ B53_VLAN_PORT_DEF_TAG(i), -+ dev->ports[i].pvid); -+ } else { -+ b53_for_each_port(dev, i) -+ b53_write16(dev, B53_VLAN_PAGE, -+ B53_VLAN_PORT_DEF_TAG(i), 1); -+ -+ } -+ -+ b53_enable_ports(dev); -+ -+ if (!is5325(dev) && !is5365(dev)) -+ b53_set_jumbo(dev, dev->enable_jumbo, 1); -+ -+ return 0; -+} -+ -+static void b53_switch_reset_gpio(struct b53_device *dev) -+{ -+ int gpio = dev->reset_gpio; -+ -+ if (gpio < 0) -+ return; -+ -+ /* -+ * Reset sequence: RESET low(50ms)->high(20ms) -+ */ -+ gpio_set_value(gpio, 0); -+ mdelay(50); -+ -+ gpio_set_value(gpio, 1); -+ mdelay(20); -+ -+ dev->current_page = 0xff; -+} -+ -+static int b53_configure_ports_of(struct b53_device *dev) -+{ -+ struct device_node *dn, *pn; -+ u32 port_num; -+ -+ dn = of_get_child_by_name(dev_of_node(dev->dev), "ports"); -+ -+ for_each_available_child_of_node(dn, pn) { -+ struct device_node *fixed_link; -+ -+ if (of_property_read_u32(pn, "reg", &port_num)) -+ continue; -+ -+ if (port_num > B53_CPU_PORT) -+ continue; -+ -+ fixed_link = of_get_child_by_name(pn, "fixed-link"); -+ if (fixed_link) { -+ u32 spd; -+ u8 po = GMII_PO_LINK; -+ phy_interface_t mode; -+ -+ of_get_phy_mode(pn, &mode); -+ -+ if (!of_property_read_u32(fixed_link, "speed", &spd)) { -+ switch (spd) { -+ case 10: -+ po |= GMII_PO_SPEED_10M; -+ break; -+ case 100: -+ po |= GMII_PO_SPEED_100M; -+ break; -+ case 2000: -+ if (is_imp_port(dev, port_num)) -+ po |= PORT_OVERRIDE_SPEED_2000M; -+ else -+ po |= GMII_PO_SPEED_2000M; -+ fallthrough; -+ case 1000: -+ po |= GMII_PO_SPEED_1000M; -+ break; -+ } -+ } -+ -+ if (of_property_read_bool(fixed_link, "full-duplex")) -+ po |= PORT_OVERRIDE_FULL_DUPLEX; -+ if (of_property_read_bool(fixed_link, "pause")) -+ po |= GMII_PO_RX_FLOW; -+ if (of_property_read_bool(fixed_link, "asym-pause")) -+ po |= GMII_PO_TX_FLOW; -+ -+ if (is_imp_port(dev, port_num)) { -+ po |= PORT_OVERRIDE_EN; -+ -+ if (is5325(dev) && -+ mode == PHY_INTERFACE_MODE_REVMII) -+ po |= PORT_OVERRIDE_RV_MII_25; -+ -+ b53_write8(dev, B53_CTRL_PAGE, -+ B53_PORT_OVERRIDE_CTRL, po); -+ -+ if (is5325(dev) && -+ mode == PHY_INTERFACE_MODE_REVMII) { -+ b53_read8(dev, B53_CTRL_PAGE, -+ B53_PORT_OVERRIDE_CTRL, &po); -+ if (!(po & PORT_OVERRIDE_RV_MII_25)) -+ pr_err("Failed to enable reverse MII mode\n"); -+ return -EINVAL; -+ } -+ } else { -+ po |= GMII_PO_EN; -+ b53_write8(dev, B53_CTRL_PAGE, -+ B53_GMII_PORT_OVERRIDE_CTRL(port_num), -+ po); -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+static int b53_configure_ports(struct b53_device *dev) -+{ -+ u8 cpu_port = dev->sw_dev.cpu_port; -+ -+ /* configure MII port if necessary */ -+ if (is5325(dev)) { -+ u8 mii_port_override; -+ -+ b53_read8(dev, B53_CTRL_PAGE, B53_PORT_OVERRIDE_CTRL, -+ &mii_port_override); -+ /* reverse mii needs to be enabled */ -+ if (!(mii_port_override & PORT_OVERRIDE_RV_MII_25)) { -+ b53_write8(dev, B53_CTRL_PAGE, B53_PORT_OVERRIDE_CTRL, -+ mii_port_override | PORT_OVERRIDE_RV_MII_25); -+ b53_read8(dev, B53_CTRL_PAGE, B53_PORT_OVERRIDE_CTRL, -+ &mii_port_override); -+ -+ if (!(mii_port_override & PORT_OVERRIDE_RV_MII_25)) { -+ pr_err("Failed to enable reverse MII mode\n"); -+ return -EINVAL; -+ } -+ } -+ } else if (is531x5(dev) && cpu_port == B53_CPU_PORT) { -+ u8 mii_port_override; -+ -+ b53_read8(dev, B53_CTRL_PAGE, B53_PORT_OVERRIDE_CTRL, -+ &mii_port_override); -+ b53_write8(dev, B53_CTRL_PAGE, B53_PORT_OVERRIDE_CTRL, -+ mii_port_override | PORT_OVERRIDE_EN | -+ PORT_OVERRIDE_LINK); -+ -+ /* BCM47189 has another interface connected to the port 5 */ -+ if (dev->enabled_ports & BIT(5)) { -+ u8 po_reg = B53_GMII_PORT_OVERRIDE_CTRL(5); -+ u8 gmii_po; -+ -+ b53_read8(dev, B53_CTRL_PAGE, po_reg, &gmii_po); -+ gmii_po |= GMII_PO_LINK | -+ GMII_PO_RX_FLOW | -+ GMII_PO_TX_FLOW | -+ GMII_PO_EN; -+ b53_write8(dev, B53_CTRL_PAGE, po_reg, gmii_po); -+ } -+ } else if (is5301x(dev)) { -+ if (cpu_port == 8) { -+ u8 mii_port_override; -+ -+ b53_read8(dev, B53_CTRL_PAGE, B53_PORT_OVERRIDE_CTRL, -+ &mii_port_override); -+ mii_port_override |= PORT_OVERRIDE_LINK | -+ PORT_OVERRIDE_RX_FLOW | -+ PORT_OVERRIDE_TX_FLOW | -+ PORT_OVERRIDE_SPEED_2000M | -+ PORT_OVERRIDE_EN; -+ b53_write8(dev, B53_CTRL_PAGE, B53_PORT_OVERRIDE_CTRL, -+ mii_port_override); -+ -+ /* TODO: Ports 5 & 7 require some extra handling */ -+ } else { -+ u8 po_reg = B53_GMII_PORT_OVERRIDE_CTRL(cpu_port); -+ u8 gmii_po; -+ -+ b53_read8(dev, B53_CTRL_PAGE, po_reg, &gmii_po); -+ gmii_po |= GMII_PO_LINK | -+ GMII_PO_RX_FLOW | -+ GMII_PO_TX_FLOW | -+ GMII_PO_EN | -+ GMII_PO_SPEED_2000M; -+ b53_write8(dev, B53_CTRL_PAGE, po_reg, gmii_po); -+ } -+ } -+ -+ return 0; -+} -+ -+static int b53_switch_reset(struct b53_device *dev) -+{ -+ int ret = 0; -+ u8 mgmt; -+ -+ b53_switch_reset_gpio(dev); -+ -+ if (is539x(dev)) { -+ b53_write8(dev, B53_CTRL_PAGE, B53_SOFTRESET, 0x83); -+ b53_write8(dev, B53_CTRL_PAGE, B53_SOFTRESET, 0x00); -+ } -+ -+ b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt); -+ -+ if (!(mgmt & SM_SW_FWD_EN)) { -+ mgmt &= ~SM_SW_FWD_MODE; -+ mgmt |= SM_SW_FWD_EN; -+ -+ b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, mgmt); -+ b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt); -+ -+ if (!(mgmt & SM_SW_FWD_EN)) { -+ pr_err("Failed to enable switch!\n"); -+ return -EINVAL; -+ } -+ } -+ -+ /* enable all ports */ -+ b53_enable_ports(dev); -+ -+ if (dev->dev->of_node) -+ ret = b53_configure_ports_of(dev); -+ else -+ ret = b53_configure_ports(dev); -+ -+ if (ret) -+ return ret; -+ -+ b53_enable_mib(dev); -+ -+ return b53_flush_arl(dev); -+} -+ -+/* -+ * Swconfig glue functions -+ */ -+ -+static int b53_global_get_vlan_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct b53_device *priv = sw_to_b53(dev); -+ -+ val->value.i = priv->enable_vlan; -+ -+ return 0; -+} -+ -+static int b53_global_set_vlan_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct b53_device *priv = sw_to_b53(dev); -+ -+ priv->enable_vlan = val->value.i; -+ -+ return 0; -+} -+ -+static int b53_global_get_jumbo_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct b53_device *priv = sw_to_b53(dev); -+ -+ val->value.i = priv->enable_jumbo; -+ -+ return 0; -+} -+ -+static int b53_global_set_jumbo_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct b53_device *priv = sw_to_b53(dev); -+ -+ priv->enable_jumbo = val->value.i; -+ -+ return 0; -+} -+ -+static int b53_global_get_4095_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct b53_device *priv = sw_to_b53(dev); -+ -+ val->value.i = priv->allow_vid_4095; -+ -+ return 0; -+} -+ -+static int b53_global_set_4095_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct b53_device *priv = sw_to_b53(dev); -+ -+ priv->allow_vid_4095 = val->value.i; -+ -+ return 0; -+} -+ -+static int b53_global_get_ports(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct b53_device *priv = sw_to_b53(dev); -+ -+ val->len = snprintf(priv->buf, B53_BUF_SIZE, "0x%04x", -+ priv->enabled_ports); -+ val->value.s = priv->buf; -+ -+ return 0; -+} -+ -+static int b53_port_get_pvid(struct switch_dev *dev, int port, int *val) -+{ -+ struct b53_device *priv = sw_to_b53(dev); -+ -+ *val = priv->ports[port].pvid; -+ -+ return 0; -+} -+ -+static int b53_port_set_pvid(struct switch_dev *dev, int port, int val) -+{ -+ struct b53_device *priv = sw_to_b53(dev); -+ -+ if (val > 15 && is5325(priv)) -+ return -EINVAL; -+ if (val == 4095 && !priv->allow_vid_4095) -+ return -EINVAL; -+ -+ priv->ports[port].pvid = val; -+ -+ return 0; -+} -+ -+static int b53_vlan_get_ports(struct switch_dev *dev, struct switch_val *val) -+{ -+ struct b53_device *priv = sw_to_b53(dev); -+ struct switch_port *port = &val->value.ports[0]; -+ struct b53_vlan *vlan = &priv->vlans[val->port_vlan]; -+ int i; -+ -+ val->len = 0; -+ -+ if (!vlan->members) -+ return 0; -+ -+ for (i = 0; i < dev->ports; i++) { -+ if (!(vlan->members & BIT(i))) -+ continue; -+ -+ -+ if (!(vlan->untag & BIT(i))) -+ port->flags = BIT(SWITCH_PORT_FLAG_TAGGED); -+ else -+ port->flags = 0; -+ -+ port->id = i; -+ val->len++; -+ port++; -+ } -+ -+ return 0; -+} -+ -+static int b53_vlan_set_ports(struct switch_dev *dev, struct switch_val *val) -+{ -+ struct b53_device *priv = sw_to_b53(dev); -+ struct switch_port *port; -+ struct b53_vlan *vlan = &priv->vlans[val->port_vlan]; -+ int i; -+ -+ /* only BCM5325 and BCM5365 supports VID 0 */ -+ if (val->port_vlan == 0 && !is5325(priv) && !is5365(priv)) -+ return -EINVAL; -+ -+ /* VLAN 4095 needs special handling */ -+ if (val->port_vlan == 4095 && !priv->allow_vid_4095) -+ return -EINVAL; -+ -+ port = &val->value.ports[0]; -+ vlan->members = 0; -+ vlan->untag = 0; -+ for (i = 0; i < val->len; i++, port++) { -+ vlan->members |= BIT(port->id); -+ -+ if (!(port->flags & BIT(SWITCH_PORT_FLAG_TAGGED))) { -+ vlan->untag |= BIT(port->id); -+ priv->ports[port->id].pvid = val->port_vlan; -+ }; -+ } -+ -+ /* ignore disabled ports */ -+ vlan->members &= priv->enabled_ports; -+ vlan->untag &= priv->enabled_ports; -+ -+ return 0; -+} -+ -+static int b53_port_get_link(struct switch_dev *dev, int port, -+ struct switch_port_link *link) -+{ -+ struct b53_device *priv = sw_to_b53(dev); -+ -+ if (is_cpu_port(priv, port)) { -+ link->link = 1; -+ link->duplex = 1; -+ link->speed = is5325(priv) || is5365(priv) ? -+ SWITCH_PORT_SPEED_100 : SWITCH_PORT_SPEED_1000; -+ link->aneg = 0; -+ } else if (priv->enabled_ports & BIT(port)) { -+ u32 speed; -+ u16 lnk, duplex; -+ -+ b53_read16(priv, B53_STAT_PAGE, B53_LINK_STAT, &lnk); -+ b53_read16(priv, B53_STAT_PAGE, priv->duplex_reg, &duplex); -+ -+ lnk = (lnk >> port) & 1; -+ duplex = (duplex >> port) & 1; -+ -+ if (is5325(priv) || is5365(priv)) { -+ u16 tmp; -+ -+ b53_read16(priv, B53_STAT_PAGE, B53_SPEED_STAT, &tmp); -+ speed = SPEED_PORT_FE(tmp, port); -+ } else { -+ b53_read32(priv, B53_STAT_PAGE, B53_SPEED_STAT, &speed); -+ speed = SPEED_PORT_GE(speed, port); -+ } -+ -+ link->link = lnk; -+ if (lnk) { -+ link->duplex = duplex; -+ switch (speed) { -+ case SPEED_STAT_10M: -+ link->speed = SWITCH_PORT_SPEED_10; -+ break; -+ case SPEED_STAT_100M: -+ link->speed = SWITCH_PORT_SPEED_100; -+ break; -+ case SPEED_STAT_1000M: -+ link->speed = SWITCH_PORT_SPEED_1000; -+ break; -+ } -+ } -+ -+ link->aneg = 1; -+ } else { -+ link->link = 0; -+ } -+ -+ return 0; -+ -+} -+ -+static int b53_port_set_link(struct switch_dev *sw_dev, int port, -+ struct switch_port_link *link) -+{ -+ struct b53_device *dev = sw_to_b53(sw_dev); -+ -+ /* -+ * TODO: BCM63XX requires special handling as it can have external phys -+ * and ports might be GE or only FE -+ */ -+ if (is63xx(dev)) -+ return -ENOTSUPP; -+ -+ if (port == sw_dev->cpu_port) -+ return -EINVAL; -+ -+ if (!(BIT(port) & dev->enabled_ports)) -+ return -EINVAL; -+ -+ if (link->speed == SWITCH_PORT_SPEED_1000 && -+ (is5325(dev) || is5365(dev))) -+ return -EINVAL; -+ -+ if (link->speed == SWITCH_PORT_SPEED_1000 && !link->duplex) -+ return -EINVAL; -+ -+ return switch_generic_set_link(sw_dev, port, link); -+} -+ -+static int b53_phy_read16(struct switch_dev *dev, int addr, u8 reg, u16 *value) -+{ -+ struct b53_device *priv = sw_to_b53(dev); -+ -+ if (priv->ops->phy_read16) -+ return priv->ops->phy_read16(priv, addr, reg, value); -+ -+ return b53_read16(priv, B53_PORT_MII_PAGE(addr), reg, value); -+} -+ -+static int b53_phy_write16(struct switch_dev *dev, int addr, u8 reg, u16 value) -+{ -+ struct b53_device *priv = sw_to_b53(dev); -+ -+ if (priv->ops->phy_write16) -+ return priv->ops->phy_write16(priv, addr, reg, value); -+ -+ return b53_write16(priv, B53_PORT_MII_PAGE(addr), reg, value); -+} -+ -+static int b53_global_reset_switch(struct switch_dev *dev) -+{ -+ struct b53_device *priv = sw_to_b53(dev); -+ -+ /* reset vlans */ -+ priv->enable_vlan = 0; -+ priv->enable_jumbo = 0; -+ priv->allow_vid_4095 = 0; -+ -+ memset(priv->vlans, 0, sizeof(*priv->vlans) * dev->vlans); -+ memset(priv->ports, 0, sizeof(*priv->ports) * dev->ports); -+ -+ return b53_switch_reset(priv); -+} -+ -+static int b53_global_apply_config(struct switch_dev *dev) -+{ -+ struct b53_device *priv = sw_to_b53(dev); -+ -+ /* disable switching */ -+ b53_set_forwarding(priv, 0); -+ -+ b53_apply(priv); -+ -+ /* enable switching */ -+ b53_set_forwarding(priv, 1); -+ -+ return 0; -+} -+ -+ -+static int b53_global_reset_mib(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct b53_device *priv = sw_to_b53(dev); -+ u8 gc; -+ -+ b53_read8(priv, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, &gc); -+ -+ b53_write8(priv, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, gc | GC_RESET_MIB); -+ mdelay(1); -+ b53_write8(priv, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, gc & ~GC_RESET_MIB); -+ mdelay(1); -+ -+ return 0; -+} -+ -+static int b53_port_get_mib(struct switch_dev *sw_dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct b53_device *dev = sw_to_b53(sw_dev); -+ const struct b53_mib_desc *mibs; -+ int port = val->port_vlan; -+ int len = 0; -+ -+ if (!(BIT(port) & dev->enabled_ports)) -+ return -1; -+ -+ if (is5365(dev)) { -+ if (port == 5) -+ port = 8; -+ -+ mibs = b53_mibs_65; -+ } else if (is63xx(dev)) { -+ mibs = b53_mibs_63xx; -+ } else { -+ mibs = b53_mibs; -+ } -+ -+ dev->buf[0] = 0; -+ -+ for (; mibs->size > 0; mibs++) { -+ u64 val; -+ -+ if (mibs->size == 8) { -+ b53_read64(dev, B53_MIB_PAGE(port), mibs->offset, &val); -+ } else { -+ u32 val32; -+ -+ b53_read32(dev, B53_MIB_PAGE(port), mibs->offset, -+ &val32); -+ val = val32; -+ } -+ -+ len += snprintf(dev->buf + len, B53_BUF_SIZE - len, -+ "%-20s: %llu\n", mibs->name, val); -+ } -+ -+ val->len = len; -+ val->value.s = dev->buf; -+ -+ return 0; -+} -+ -+static int b53_port_get_stats(struct switch_dev *sw_dev, int port, -+ struct switch_port_stats *stats) -+{ -+ struct b53_device *dev = sw_to_b53(sw_dev); -+ const struct b53_mib_desc *mibs; -+ int txb_id, rxb_id; -+ u64 rxb, txb; -+ -+ if (!(BIT(port) & dev->enabled_ports)) -+ return -EINVAL; -+ -+ txb_id = B53XX_MIB_TXB_ID; -+ rxb_id = B53XX_MIB_RXB_ID; -+ -+ if (is5365(dev)) { -+ if (port == 5) -+ port = 8; -+ -+ mibs = b53_mibs_65; -+ } else if (is63xx(dev)) { -+ mibs = b53_mibs_63xx; -+ txb_id = B63XX_MIB_TXB_ID; -+ rxb_id = B63XX_MIB_RXB_ID; -+ } else { -+ mibs = b53_mibs; -+ } -+ -+ dev->buf[0] = 0; -+ -+ if (mibs->size == 8) { -+ b53_read64(dev, B53_MIB_PAGE(port), mibs[txb_id].offset, &txb); -+ b53_read64(dev, B53_MIB_PAGE(port), mibs[rxb_id].offset, &rxb); -+ } else { -+ u32 val32; -+ -+ b53_read32(dev, B53_MIB_PAGE(port), mibs[txb_id].offset, &val32); -+ txb = val32; -+ -+ b53_read32(dev, B53_MIB_PAGE(port), mibs[rxb_id].offset, &val32); -+ rxb = val32; -+ } -+ -+ stats->tx_bytes = txb; -+ stats->rx_bytes = rxb; -+ -+ return 0; -+} -+ -+static struct switch_attr b53_global_ops_25[] = { -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_vlan", -+ .description = "Enable VLAN mode", -+ .set = b53_global_set_vlan_enable, -+ .get = b53_global_get_vlan_enable, -+ .max = 1, -+ }, -+ { -+ .type = SWITCH_TYPE_STRING, -+ .name = "ports", -+ .description = "Available ports (as bitmask)", -+ .get = b53_global_get_ports, -+ }, -+}; -+ -+static struct switch_attr b53_global_ops_65[] = { -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_vlan", -+ .description = "Enable VLAN mode", -+ .set = b53_global_set_vlan_enable, -+ .get = b53_global_get_vlan_enable, -+ .max = 1, -+ }, -+ { -+ .type = SWITCH_TYPE_STRING, -+ .name = "ports", -+ .description = "Available ports (as bitmask)", -+ .get = b53_global_get_ports, -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "reset_mib", -+ .description = "Reset MIB counters", -+ .set = b53_global_reset_mib, -+ }, -+}; -+ -+static struct switch_attr b53_global_ops[] = { -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_vlan", -+ .description = "Enable VLAN mode", -+ .set = b53_global_set_vlan_enable, -+ .get = b53_global_get_vlan_enable, -+ .max = 1, -+ }, -+ { -+ .type = SWITCH_TYPE_STRING, -+ .name = "ports", -+ .description = "Available Ports (as bitmask)", -+ .get = b53_global_get_ports, -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "reset_mib", -+ .description = "Reset MIB counters", -+ .set = b53_global_reset_mib, -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_jumbo", -+ .description = "Enable Jumbo Frames", -+ .set = b53_global_set_jumbo_enable, -+ .get = b53_global_get_jumbo_enable, -+ .max = 1, -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "allow_vid_4095", -+ .description = "Allow VID 4095", -+ .set = b53_global_set_4095_enable, -+ .get = b53_global_get_4095_enable, -+ .max = 1, -+ }, -+}; -+ -+static struct switch_attr b53_port_ops[] = { -+ { -+ .type = SWITCH_TYPE_STRING, -+ .name = "mib", -+ .description = "Get port's MIB counters", -+ .get = b53_port_get_mib, -+ }, -+}; -+ -+static struct switch_attr b53_no_ops[] = { -+}; -+ -+static const struct switch_dev_ops b53_switch_ops_25 = { -+ .attr_global = { -+ .attr = b53_global_ops_25, -+ .n_attr = ARRAY_SIZE(b53_global_ops_25), -+ }, -+ .attr_port = { -+ .attr = b53_no_ops, -+ .n_attr = ARRAY_SIZE(b53_no_ops), -+ }, -+ .attr_vlan = { -+ .attr = b53_no_ops, -+ .n_attr = ARRAY_SIZE(b53_no_ops), -+ }, -+ -+ .get_vlan_ports = b53_vlan_get_ports, -+ .set_vlan_ports = b53_vlan_set_ports, -+ .get_port_pvid = b53_port_get_pvid, -+ .set_port_pvid = b53_port_set_pvid, -+ .apply_config = b53_global_apply_config, -+ .reset_switch = b53_global_reset_switch, -+ .get_port_link = b53_port_get_link, -+ .set_port_link = b53_port_set_link, -+ .get_port_stats = b53_port_get_stats, -+ .phy_read16 = b53_phy_read16, -+ .phy_write16 = b53_phy_write16, -+}; -+ -+static const struct switch_dev_ops b53_switch_ops_65 = { -+ .attr_global = { -+ .attr = b53_global_ops_65, -+ .n_attr = ARRAY_SIZE(b53_global_ops_65), -+ }, -+ .attr_port = { -+ .attr = b53_port_ops, -+ .n_attr = ARRAY_SIZE(b53_port_ops), -+ }, -+ .attr_vlan = { -+ .attr = b53_no_ops, -+ .n_attr = ARRAY_SIZE(b53_no_ops), -+ }, -+ -+ .get_vlan_ports = b53_vlan_get_ports, -+ .set_vlan_ports = b53_vlan_set_ports, -+ .get_port_pvid = b53_port_get_pvid, -+ .set_port_pvid = b53_port_set_pvid, -+ .apply_config = b53_global_apply_config, -+ .reset_switch = b53_global_reset_switch, -+ .get_port_link = b53_port_get_link, -+ .set_port_link = b53_port_set_link, -+ .get_port_stats = b53_port_get_stats, -+ .phy_read16 = b53_phy_read16, -+ .phy_write16 = b53_phy_write16, -+}; -+ -+static const struct switch_dev_ops b53_switch_ops = { -+ .attr_global = { -+ .attr = b53_global_ops, -+ .n_attr = ARRAY_SIZE(b53_global_ops), -+ }, -+ .attr_port = { -+ .attr = b53_port_ops, -+ .n_attr = ARRAY_SIZE(b53_port_ops), -+ }, -+ .attr_vlan = { -+ .attr = b53_no_ops, -+ .n_attr = ARRAY_SIZE(b53_no_ops), -+ }, -+ -+ .get_vlan_ports = b53_vlan_get_ports, -+ .set_vlan_ports = b53_vlan_set_ports, -+ .get_port_pvid = b53_port_get_pvid, -+ .set_port_pvid = b53_port_set_pvid, -+ .apply_config = b53_global_apply_config, -+ .reset_switch = b53_global_reset_switch, -+ .get_port_link = b53_port_get_link, -+ .set_port_link = b53_port_set_link, -+ .get_port_stats = b53_port_get_stats, -+ .phy_read16 = b53_phy_read16, -+ .phy_write16 = b53_phy_write16, -+}; -+ -+struct b53_chip_data { -+ u32 chip_id; -+ const char *dev_name; -+ const char *alias; -+ u16 vlans; -+ u16 enabled_ports; -+ u8 cpu_port; -+ u8 vta_regs[3]; -+ u8 duplex_reg; -+ u8 jumbo_pm_reg; -+ u8 jumbo_size_reg; -+ const struct switch_dev_ops *sw_ops; -+}; -+ -+#define B53_VTA_REGS \ -+ { B53_VT_ACCESS, B53_VT_INDEX, B53_VT_ENTRY } -+#define B53_VTA_REGS_9798 \ -+ { B53_VT_ACCESS_9798, B53_VT_INDEX_9798, B53_VT_ENTRY_9798 } -+#define B53_VTA_REGS_63XX \ -+ { B53_VT_ACCESS_63XX, B53_VT_INDEX_63XX, B53_VT_ENTRY_63XX } -+ -+static const struct b53_chip_data b53_switch_chips[] = { -+ { -+ .chip_id = BCM5325_DEVICE_ID, -+ .dev_name = "BCM5325", -+ .alias = "bcm5325", -+ .vlans = 16, -+ .enabled_ports = 0x1f, -+ .cpu_port = B53_CPU_PORT_25, -+ .duplex_reg = B53_DUPLEX_STAT_FE, -+ .sw_ops = &b53_switch_ops_25, -+ }, -+ { -+ .chip_id = BCM5365_DEVICE_ID, -+ .dev_name = "BCM5365", -+ .alias = "bcm5365", -+ .vlans = 256, -+ .enabled_ports = 0x1f, -+ .cpu_port = B53_CPU_PORT_25, -+ .duplex_reg = B53_DUPLEX_STAT_FE, -+ .sw_ops = &b53_switch_ops_65, -+ }, -+ { -+ .chip_id = BCM5395_DEVICE_ID, -+ .dev_name = "BCM5395", -+ .alias = "bcm5395", -+ .vlans = 4096, -+ .enabled_ports = 0x1f, -+ .cpu_port = B53_CPU_PORT, -+ .vta_regs = B53_VTA_REGS, -+ .duplex_reg = B53_DUPLEX_STAT_GE, -+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE, -+ .sw_ops = &b53_switch_ops, -+ }, -+ { -+ .chip_id = BCM5397_DEVICE_ID, -+ .dev_name = "BCM5397", -+ .alias = "bcm5397", -+ .vlans = 4096, -+ .enabled_ports = 0x1f, -+ .cpu_port = B53_CPU_PORT, -+ .vta_regs = B53_VTA_REGS_9798, -+ .duplex_reg = B53_DUPLEX_STAT_GE, -+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE, -+ .sw_ops = &b53_switch_ops, -+ }, -+ { -+ .chip_id = BCM5398_DEVICE_ID, -+ .dev_name = "BCM5398", -+ .alias = "bcm5398", -+ .vlans = 4096, -+ .enabled_ports = 0x7f, -+ .cpu_port = B53_CPU_PORT, -+ .vta_regs = B53_VTA_REGS_9798, -+ .duplex_reg = B53_DUPLEX_STAT_GE, -+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE, -+ .sw_ops = &b53_switch_ops, -+ }, -+ { -+ .chip_id = BCM53115_DEVICE_ID, -+ .dev_name = "BCM53115", -+ .alias = "bcm53115", -+ .vlans = 4096, -+ .enabled_ports = 0x1f, -+ .vta_regs = B53_VTA_REGS, -+ .cpu_port = B53_CPU_PORT, -+ .duplex_reg = B53_DUPLEX_STAT_GE, -+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE, -+ .sw_ops = &b53_switch_ops, -+ }, -+ { -+ .chip_id = BCM53125_DEVICE_ID, -+ .dev_name = "BCM53125", -+ .alias = "bcm53125", -+ .vlans = 4096, -+ .enabled_ports = 0x1f, -+ .cpu_port = B53_CPU_PORT, -+ .vta_regs = B53_VTA_REGS, -+ .duplex_reg = B53_DUPLEX_STAT_GE, -+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE, -+ .sw_ops = &b53_switch_ops, -+ }, -+ { -+ .chip_id = BCM53128_DEVICE_ID, -+ .dev_name = "BCM53128", -+ .alias = "bcm53128", -+ .vlans = 4096, -+ .enabled_ports = 0x1ff, -+ .cpu_port = B53_CPU_PORT, -+ .vta_regs = B53_VTA_REGS, -+ .duplex_reg = B53_DUPLEX_STAT_GE, -+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE, -+ .sw_ops = &b53_switch_ops, -+ }, -+ { -+ .chip_id = BCM63XX_DEVICE_ID, -+ .dev_name = "BCM63xx", -+ .alias = "bcm63xx", -+ .vlans = 4096, -+ .enabled_ports = 0, /* pdata must provide them */ -+ .cpu_port = B53_CPU_PORT, -+ .vta_regs = B53_VTA_REGS_63XX, -+ .duplex_reg = B53_DUPLEX_STAT_63XX, -+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK_63XX, -+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE_63XX, -+ .sw_ops = &b53_switch_ops, -+ }, -+ { -+ .chip_id = BCM53010_DEVICE_ID, -+ .dev_name = "BCM53010", -+ .alias = "bcm53011", -+ .vlans = 4096, -+ .enabled_ports = 0x1f, -+ .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */ -+ .vta_regs = B53_VTA_REGS, -+ .duplex_reg = B53_DUPLEX_STAT_GE, -+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE, -+ .sw_ops = &b53_switch_ops, -+ }, -+ { -+ .chip_id = BCM53011_DEVICE_ID, -+ .dev_name = "BCM53011", -+ .alias = "bcm53011", -+ .vlans = 4096, -+ .enabled_ports = 0x1bf, -+ .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */ -+ .vta_regs = B53_VTA_REGS, -+ .duplex_reg = B53_DUPLEX_STAT_GE, -+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE, -+ .sw_ops = &b53_switch_ops, -+ }, -+ { -+ .chip_id = BCM53012_DEVICE_ID, -+ .dev_name = "BCM53012", -+ .alias = "bcm53011", -+ .vlans = 4096, -+ .enabled_ports = 0x1bf, -+ .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */ -+ .vta_regs = B53_VTA_REGS, -+ .duplex_reg = B53_DUPLEX_STAT_GE, -+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE, -+ .sw_ops = &b53_switch_ops, -+ }, -+ { -+ .chip_id = BCM53018_DEVICE_ID, -+ .dev_name = "BCM53018", -+ .alias = "bcm53018", -+ .vlans = 4096, -+ .enabled_ports = 0x1f, -+ .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */ -+ .vta_regs = B53_VTA_REGS, -+ .duplex_reg = B53_DUPLEX_STAT_GE, -+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE, -+ .sw_ops = &b53_switch_ops, -+ }, -+ { -+ .chip_id = BCM53019_DEVICE_ID, -+ .dev_name = "BCM53019", -+ .alias = "bcm53019", -+ .vlans = 4096, -+ .enabled_ports = 0x1f, -+ .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */ -+ .vta_regs = B53_VTA_REGS, -+ .duplex_reg = B53_DUPLEX_STAT_GE, -+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE, -+ .sw_ops = &b53_switch_ops, -+ }, -+}; -+ -+static int b53_switch_init_of(struct b53_device *dev) -+{ -+ struct device_node *dn, *pn; -+ const char *alias; -+ u32 port_num; -+ u16 ports = 0; -+ -+ dn = of_get_child_by_name(dev_of_node(dev->dev), "ports"); -+ if (!dn) -+ return -EINVAL; -+ -+ for_each_available_child_of_node(dn, pn) { -+ const char *label; -+ int len; -+ -+ if (of_property_read_u32(pn, "reg", &port_num)) -+ continue; -+ -+ if (port_num > B53_CPU_PORT) -+ continue; -+ -+ ports |= BIT(port_num); -+ -+ label = of_get_property(pn, "label", &len); -+ if (label && !strcmp(label, "cpu")) -+ dev->sw_dev.cpu_port = port_num; -+ } -+ -+ dev->enabled_ports = ports; -+ -+ if (!of_property_read_string(dev_of_node(dev->dev), "lede,alias", -+ &alias)) -+ dev->sw_dev.alias = devm_kstrdup(dev->dev, alias, GFP_KERNEL); -+ -+ return 0; -+} -+ -+static int b53_switch_init(struct b53_device *dev) -+{ -+ struct switch_dev *sw_dev = &dev->sw_dev; -+ unsigned i; -+ int ret; -+ -+ for (i = 0; i < ARRAY_SIZE(b53_switch_chips); i++) { -+ const struct b53_chip_data *chip = &b53_switch_chips[i]; -+ -+ if (chip->chip_id == dev->chip_id) { -+ sw_dev->name = chip->dev_name; -+ if (!sw_dev->alias) -+ sw_dev->alias = chip->alias; -+ if (!dev->enabled_ports) -+ dev->enabled_ports = chip->enabled_ports; -+ dev->duplex_reg = chip->duplex_reg; -+ dev->vta_regs[0] = chip->vta_regs[0]; -+ dev->vta_regs[1] = chip->vta_regs[1]; -+ dev->vta_regs[2] = chip->vta_regs[2]; -+ dev->jumbo_pm_reg = chip->jumbo_pm_reg; -+ sw_dev->ops = chip->sw_ops; -+ sw_dev->cpu_port = chip->cpu_port; -+ sw_dev->vlans = chip->vlans; -+ break; -+ } -+ } -+ -+ if (!sw_dev->name) -+ return -EINVAL; -+ -+ /* check which BCM5325x version we have */ -+ if (is5325(dev)) { -+ u8 vc4; -+ -+ b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_25, &vc4); -+ -+ /* check reserved bits */ -+ switch (vc4 & 3) { -+ case 1: -+ /* BCM5325E */ -+ break; -+ case 3: -+ /* BCM5325F - do not use port 4 */ -+ dev->enabled_ports &= ~BIT(4); -+ break; -+ default: -+/* On the BCM47XX SoCs this is the supported internal switch.*/ -+#ifndef CONFIG_BCM47XX -+ /* BCM5325M */ -+ return -EINVAL; -+#else -+ break; -+#endif -+ } -+ } else if (dev->chip_id == BCM53115_DEVICE_ID) { -+ u64 strap_value; -+ -+ b53_read48(dev, B53_STAT_PAGE, B53_STRAP_VALUE, &strap_value); -+ /* use second IMP port if GMII is enabled */ -+ if (strap_value & SV_GMII_CTRL_115) -+ sw_dev->cpu_port = 5; -+ } -+ -+ if (dev_of_node(dev->dev)) { -+ ret = b53_switch_init_of(dev); -+ if (ret) -+ return ret; -+ } -+ -+ dev->enabled_ports |= BIT(sw_dev->cpu_port); -+ sw_dev->ports = fls(dev->enabled_ports); -+ -+ dev->ports = devm_kzalloc(dev->dev, -+ sizeof(struct b53_port) * sw_dev->ports, -+ GFP_KERNEL); -+ if (!dev->ports) -+ return -ENOMEM; -+ -+ dev->vlans = devm_kzalloc(dev->dev, -+ sizeof(struct b53_vlan) * sw_dev->vlans, -+ GFP_KERNEL); -+ if (!dev->vlans) -+ return -ENOMEM; -+ -+ dev->buf = devm_kzalloc(dev->dev, B53_BUF_SIZE, GFP_KERNEL); -+ if (!dev->buf) -+ return -ENOMEM; -+ -+ dev->reset_gpio = b53_switch_get_reset_gpio(dev); -+ if (dev->reset_gpio >= 0) { -+ ret = devm_gpio_request_one(dev->dev, dev->reset_gpio, -+ GPIOF_OUT_INIT_HIGH, "robo_reset"); -+ if (ret) -+ return ret; -+ } -+ -+ return b53_switch_reset(dev); -+} -+ -+struct b53_device *b53_swconfig_switch_alloc(struct device *base, struct b53_io_ops *ops, -+ void *priv) -+{ -+ struct b53_device *dev; -+ -+ dev = devm_kzalloc(base, sizeof(*dev), GFP_KERNEL); -+ if (!dev) -+ return NULL; -+ -+ dev->dev = base; -+ dev->ops = ops; -+ dev->priv = priv; -+ mutex_init(&dev->reg_mutex); -+ -+ return dev; -+} -+EXPORT_SYMBOL(b53_swconfig_switch_alloc); -+ -+int b53_swconfig_switch_detect(struct b53_device *dev) -+{ -+ u32 id32; -+ u16 tmp; -+ u8 id8; -+ int ret; -+ -+ ret = b53_read8(dev, B53_MGMT_PAGE, B53_DEVICE_ID, &id8); -+ if (ret) -+ return ret; -+ -+ switch (id8) { -+ case 0: -+ /* -+ * BCM5325 and BCM5365 do not have this register so reads -+ * return 0. But the read operation did succeed, so assume -+ * this is one of them. -+ * -+ * Next check if we can write to the 5325's VTA register; for -+ * 5365 it is read only. -+ */ -+ -+ b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_25, 0xf); -+ b53_read16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_25, &tmp); -+ -+ if (tmp == 0xf) -+ dev->chip_id = BCM5325_DEVICE_ID; -+ else -+ dev->chip_id = BCM5365_DEVICE_ID; -+ break; -+ case BCM5395_DEVICE_ID: -+ case BCM5397_DEVICE_ID: -+ case BCM5398_DEVICE_ID: -+ dev->chip_id = id8; -+ break; -+ default: -+ ret = b53_read32(dev, B53_MGMT_PAGE, B53_DEVICE_ID, &id32); -+ if (ret) -+ return ret; -+ -+ switch (id32) { -+ case BCM53115_DEVICE_ID: -+ case BCM53125_DEVICE_ID: -+ case BCM53128_DEVICE_ID: -+ case BCM53010_DEVICE_ID: -+ case BCM53011_DEVICE_ID: -+ case BCM53012_DEVICE_ID: -+ case BCM53018_DEVICE_ID: -+ case BCM53019_DEVICE_ID: -+ dev->chip_id = id32; -+ break; -+ default: -+ pr_err("unsupported switch detected (BCM53%02x/BCM%x)\n", -+ id8, id32); -+ return -ENODEV; -+ } -+ } -+ -+ if (dev->chip_id == BCM5325_DEVICE_ID) -+ return b53_read8(dev, B53_STAT_PAGE, B53_REV_ID_25, -+ &dev->core_rev); -+ else -+ return b53_read8(dev, B53_MGMT_PAGE, B53_REV_ID, -+ &dev->core_rev); -+} -+EXPORT_SYMBOL(b53_swconfig_switch_detect); -+ -+int b53_swconfig_switch_register(struct b53_device *dev) -+{ -+ int ret; -+ -+ if (dev->pdata) { -+ dev->chip_id = dev->pdata->chip_id; -+ dev->enabled_ports = dev->pdata->enabled_ports; -+ dev->sw_dev.alias = dev->pdata->alias; -+ } -+ -+ if (!dev->chip_id && b53_swconfig_switch_detect(dev)) -+ return -EINVAL; -+ -+ ret = b53_switch_init(dev); -+ if (ret) -+ return ret; -+ -+ pr_info("found switch: %s, rev %i\n", dev->sw_dev.name, dev->core_rev); -+ -+ return register_switch(&dev->sw_dev, NULL); -+} -+EXPORT_SYMBOL(b53_swconfig_switch_register); -+ -+MODULE_AUTHOR("Jonas Gorski "); -+MODULE_DESCRIPTION("B53 switch library"); -+MODULE_LICENSE("Dual BSD/GPL"); -diff --git a/drivers/net/phy/b53/b53_mdio.c b/drivers/net/phy/b53/b53_mdio.c -new file mode 100644 -index 000000000000..c85df1f30558 ---- /dev/null -+++ b/drivers/net/phy/b53/b53_mdio.c -@@ -0,0 +1,436 @@ -+/* -+ * B53 register access through MII registers -+ * -+ * Copyright (C) 2011-2013 Jonas Gorski -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#include -+#include -+#include -+ -+#include "b53_priv.h" -+ -+#define B53_PSEUDO_PHY 0x1e /* Register Access Pseudo PHY */ -+ -+/* MII registers */ -+#define REG_MII_PAGE 0x10 /* MII Page register */ -+#define REG_MII_ADDR 0x11 /* MII Address register */ -+#define REG_MII_DATA0 0x18 /* MII Data register 0 */ -+#define REG_MII_DATA1 0x19 /* MII Data register 1 */ -+#define REG_MII_DATA2 0x1a /* MII Data register 2 */ -+#define REG_MII_DATA3 0x1b /* MII Data register 3 */ -+ -+#define REG_MII_PAGE_ENABLE BIT(0) -+#define REG_MII_ADDR_WRITE BIT(0) -+#define REG_MII_ADDR_READ BIT(1) -+ -+static int b53_mdio_op(struct b53_device *dev, u8 page, u8 reg, u16 op) -+{ -+ int i; -+ u16 v; -+ int ret; -+ struct mii_bus *bus = dev->priv; -+ -+ if (dev->current_page != page) { -+ /* set page number */ -+ v = (page << 8) | REG_MII_PAGE_ENABLE; -+ ret = mdiobus_write(bus, B53_PSEUDO_PHY, REG_MII_PAGE, v); -+ if (ret) -+ return ret; -+ dev->current_page = page; -+ } -+ -+ /* set register address */ -+ v = (reg << 8) | op; -+ ret = mdiobus_write(bus, B53_PSEUDO_PHY, REG_MII_ADDR, v); -+ if (ret) -+ return ret; -+ -+ /* check if operation completed */ -+ for (i = 0; i < 5; ++i) { -+ v = mdiobus_read(bus, B53_PSEUDO_PHY, REG_MII_ADDR); -+ if (!(v & (REG_MII_ADDR_WRITE | REG_MII_ADDR_READ))) -+ break; -+ usleep_range(10, 100); -+ } -+ -+ if (WARN_ON(i == 5)) -+ return -EIO; -+ -+ return 0; -+} -+ -+static int b53_mdio_read8(struct b53_device *dev, u8 page, u8 reg, u8 *val) -+{ -+ struct mii_bus *bus = dev->priv; -+ int ret; -+ -+ ret = b53_mdio_op(dev, page, reg, REG_MII_ADDR_READ); -+ if (ret) -+ return ret; -+ -+ *val = mdiobus_read(bus, B53_PSEUDO_PHY, REG_MII_DATA0) & 0xff; -+ -+ return 0; -+} -+ -+static int b53_mdio_read16(struct b53_device *dev, u8 page, u8 reg, u16 *val) -+{ -+ struct mii_bus *bus = dev->priv; -+ int ret; -+ -+ ret = b53_mdio_op(dev, page, reg, REG_MII_ADDR_READ); -+ if (ret) -+ return ret; -+ -+ *val = mdiobus_read(bus, B53_PSEUDO_PHY, REG_MII_DATA0); -+ -+ return 0; -+} -+ -+static int b53_mdio_read32(struct b53_device *dev, u8 page, u8 reg, u32 *val) -+{ -+ struct mii_bus *bus = dev->priv; -+ int ret; -+ -+ ret = b53_mdio_op(dev, page, reg, REG_MII_ADDR_READ); -+ if (ret) -+ return ret; -+ -+ *val = mdiobus_read(bus, B53_PSEUDO_PHY, REG_MII_DATA0); -+ *val |= mdiobus_read(bus, B53_PSEUDO_PHY, REG_MII_DATA1) << 16; -+ -+ return 0; -+} -+ -+static int b53_mdio_read48(struct b53_device *dev, u8 page, u8 reg, u64 *val) -+{ -+ struct mii_bus *bus = dev->priv; -+ u64 temp = 0; -+ int i; -+ int ret; -+ -+ ret = b53_mdio_op(dev, page, reg, REG_MII_ADDR_READ); -+ if (ret) -+ return ret; -+ -+ for (i = 2; i >= 0; i--) { -+ temp <<= 16; -+ temp |= mdiobus_read(bus, B53_PSEUDO_PHY, REG_MII_DATA0 + i); -+ } -+ -+ *val = temp; -+ -+ return 0; -+} -+ -+static int b53_mdio_read64(struct b53_device *dev, u8 page, u8 reg, u64 *val) -+{ -+ struct mii_bus *bus = dev->priv; -+ u64 temp = 0; -+ int i; -+ int ret; -+ -+ ret = b53_mdio_op(dev, page, reg, REG_MII_ADDR_READ); -+ if (ret) -+ return ret; -+ -+ for (i = 3; i >= 0; i--) { -+ temp <<= 16; -+ temp |= mdiobus_read(bus, B53_PSEUDO_PHY, REG_MII_DATA0 + i); -+ } -+ -+ *val = temp; -+ -+ return 0; -+} -+ -+static int b53_mdio_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) -+{ -+ struct mii_bus *bus = dev->priv; -+ int ret; -+ -+ ret = mdiobus_write(bus, B53_PSEUDO_PHY, REG_MII_DATA0, value); -+ if (ret) -+ return ret; -+ -+ return b53_mdio_op(dev, page, reg, REG_MII_ADDR_WRITE); -+} -+ -+static int b53_mdio_write16(struct b53_device *dev, u8 page, u8 reg, -+ u16 value) -+{ -+ struct mii_bus *bus = dev->priv; -+ int ret; -+ -+ ret = mdiobus_write(bus, B53_PSEUDO_PHY, REG_MII_DATA0, value); -+ if (ret) -+ return ret; -+ -+ return b53_mdio_op(dev, page, reg, REG_MII_ADDR_WRITE); -+} -+ -+static int b53_mdio_write32(struct b53_device *dev, u8 page, u8 reg, -+ u32 value) -+{ -+ struct mii_bus *bus = dev->priv; -+ unsigned int i; -+ u32 temp = value; -+ -+ for (i = 0; i < 2; i++) { -+ int ret = mdiobus_write(bus, B53_PSEUDO_PHY, REG_MII_DATA0 + i, -+ temp & 0xffff); -+ if (ret) -+ return ret; -+ temp >>= 16; -+ } -+ -+ return b53_mdio_op(dev, page, reg, REG_MII_ADDR_WRITE); -+ -+} -+ -+static int b53_mdio_write48(struct b53_device *dev, u8 page, u8 reg, -+ u64 value) -+{ -+ struct mii_bus *bus = dev->priv; -+ unsigned i; -+ u64 temp = value; -+ -+ for (i = 0; i < 3; i++) { -+ int ret = mdiobus_write(bus, B53_PSEUDO_PHY, REG_MII_DATA0 + i, -+ temp & 0xffff); -+ if (ret) -+ return ret; -+ temp >>= 16; -+ } -+ -+ return b53_mdio_op(dev, page, reg, REG_MII_ADDR_WRITE); -+ -+} -+ -+static int b53_mdio_write64(struct b53_device *dev, u8 page, u8 reg, -+ u64 value) -+{ -+ struct mii_bus *bus = dev->priv; -+ unsigned i; -+ u64 temp = value; -+ -+ for (i = 0; i < 4; i++) { -+ int ret = mdiobus_write(bus, B53_PSEUDO_PHY, REG_MII_DATA0 + i, -+ temp & 0xffff); -+ if (ret) -+ return ret; -+ temp >>= 16; -+ } -+ -+ return b53_mdio_op(dev, page, reg, REG_MII_ADDR_WRITE); -+} -+ -+static int b53_mdio_phy_read16(struct b53_device *dev, int addr, u8 reg, -+ u16 *value) -+{ -+ struct mii_bus *bus = dev->priv; -+ -+ *value = mdiobus_read(bus, addr, reg); -+ -+ return 0; -+} -+ -+static int b53_mdio_phy_write16(struct b53_device *dev, int addr, u8 reg, -+ u16 value) -+{ -+ struct mii_bus *bus = dev->priv; -+ -+ return mdiobus_write(bus, addr, reg, value); -+} -+ -+static struct b53_io_ops b53_mdio_ops = { -+ .read8 = b53_mdio_read8, -+ .read16 = b53_mdio_read16, -+ .read32 = b53_mdio_read32, -+ .read48 = b53_mdio_read48, -+ .read64 = b53_mdio_read64, -+ .write8 = b53_mdio_write8, -+ .write16 = b53_mdio_write16, -+ .write32 = b53_mdio_write32, -+ .write48 = b53_mdio_write48, -+ .write64 = b53_mdio_write64, -+ .phy_read16 = b53_mdio_phy_read16, -+ .phy_write16 = b53_mdio_phy_write16, -+}; -+ -+static int b53_phy_probe(struct phy_device *phydev) -+{ -+ struct b53_device *dev; -+ int ret; -+ -+ /* allow the generic phy driver to take over */ -+ if (phydev->mdio.addr != B53_PSEUDO_PHY && phydev->mdio.addr != 0) -+ return -ENODEV; -+ -+ dev = b53_swconfig_switch_alloc(&phydev->mdio.dev, &b53_mdio_ops, phydev->mdio.bus); -+ if (!dev) -+ return -ENOMEM; -+ -+ dev->current_page = 0xff; -+ dev->priv = phydev->mdio.bus; -+ dev->ops = &b53_mdio_ops; -+ dev->pdata = NULL; -+ mutex_init(&dev->reg_mutex); -+ -+ ret = b53_swconfig_switch_detect(dev); -+ if (ret) -+ return ret; -+ -+ linkmode_zero(phydev->supported); -+ if (is5325(dev) || is5365(dev)) -+ linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, phydev->supported); -+ else -+ linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, phydev->supported); -+ -+ linkmode_copy(phydev->advertising, phydev->supported); -+ -+ ret = b53_swconfig_switch_register(dev); -+ if (ret) { -+ dev_err(dev->dev, "failed to register switch: %i\n", ret); -+ return ret; -+ } -+ -+ phydev->priv = dev; -+ -+ return 0; -+} -+ -+static int b53_phy_config_init(struct phy_device *phydev) -+{ -+ struct b53_device *dev = phydev->priv; -+ -+ /* we don't use page 0xff, so force a page set */ -+ dev->current_page = 0xff; -+ /* force the ethX as alias */ -+ dev->sw_dev.alias = phydev->attached_dev->name; -+ -+ return 0; -+} -+ -+static void b53_phy_remove(struct phy_device *phydev) -+{ -+ struct b53_device *priv = phydev->priv; -+ -+ if (!priv) -+ return; -+ -+ b53_switch_remove(priv); -+ -+ phydev->priv = NULL; -+} -+ -+static int b53_phy_config_aneg(struct phy_device *phydev) -+{ -+ return 0; -+} -+ -+static int b53_phy_read_status(struct phy_device *phydev) -+{ -+ struct b53_device *priv = phydev->priv; -+ -+ if (is5325(priv) || is5365(priv)) -+ phydev->speed = 100; -+ else -+ phydev->speed = 1000; -+ -+ phydev->duplex = DUPLEX_FULL; -+ phydev->link = 1; -+ phydev->state = PHY_RUNNING; -+ -+ netif_carrier_on(phydev->attached_dev); -+ phydev->adjust_link(phydev->attached_dev); -+ -+ return 0; -+} -+ -+/* BCM5325, BCM539x */ -+static struct phy_driver b53_phy_driver_id1 = { -+ .phy_id = 0x0143bc00, -+ .name = "Broadcom B53 (1)", -+ .phy_id_mask = 0x1ffffc00, -+ .features = 0, -+ .probe = b53_phy_probe, -+ .remove = b53_phy_remove, -+ .config_aneg = b53_phy_config_aneg, -+ .config_init = b53_phy_config_init, -+ .read_status = b53_phy_read_status, -+}; -+ -+/* BCM53125, BCM53128 */ -+static struct phy_driver b53_phy_driver_id2 = { -+ .phy_id = 0x03625c00, -+ .name = "Broadcom B53 (2)", -+ .phy_id_mask = 0x1ffffc00, -+ .features = 0, -+ .probe = b53_phy_probe, -+ .remove = b53_phy_remove, -+ .config_aneg = b53_phy_config_aneg, -+ .config_init = b53_phy_config_init, -+ .read_status = b53_phy_read_status, -+}; -+ -+/* BCM5365 */ -+static struct phy_driver b53_phy_driver_id3 = { -+ .phy_id = 0x00406300, -+ .name = "Broadcom B53 (3)", -+ .phy_id_mask = 0x1fffff00, -+ .features = 0, -+ .probe = b53_phy_probe, -+ .remove = b53_phy_remove, -+ .config_aneg = b53_phy_config_aneg, -+ .config_init = b53_phy_config_init, -+ .read_status = b53_phy_read_status, -+}; -+ -+int __init b53_phy_driver_register(void) -+{ -+ int ret; -+ -+ ret = phy_driver_register(&b53_phy_driver_id1, THIS_MODULE); -+ if (ret) -+ return ret; -+ -+ ret = phy_driver_register(&b53_phy_driver_id2, THIS_MODULE); -+ if (ret) -+ goto err1; -+ -+ ret = phy_driver_register(&b53_phy_driver_id3, THIS_MODULE); -+ if (!ret) -+ return 0; -+ -+ phy_driver_unregister(&b53_phy_driver_id2); -+err1: -+ phy_driver_unregister(&b53_phy_driver_id1); -+ return ret; -+} -+ -+void __exit b53_phy_driver_unregister(void) -+{ -+ phy_driver_unregister(&b53_phy_driver_id3); -+ phy_driver_unregister(&b53_phy_driver_id2); -+ phy_driver_unregister(&b53_phy_driver_id1); -+} -+ -+module_init(b53_phy_driver_register); -+module_exit(b53_phy_driver_unregister); -+ -+MODULE_DESCRIPTION("B53 MDIO access driver"); -+MODULE_LICENSE("Dual BSD/GPL"); -diff --git a/drivers/net/phy/b53/b53_mmap.c b/drivers/net/phy/b53/b53_mmap.c -new file mode 100644 -index 000000000000..62dfe1c24282 ---- /dev/null -+++ b/drivers/net/phy/b53/b53_mmap.c -@@ -0,0 +1,239 @@ -+/* -+ * B53 register access through memory mapped registers -+ * -+ * Copyright (C) 2012-2013 Jonas Gorski -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "b53_priv.h" -+ -+static int b53_mmap_read8(struct b53_device *dev, u8 page, u8 reg, u8 *val) -+{ -+ u8 __iomem *regs = dev->priv; -+ -+ *val = readb(regs + (page << 8) + reg); -+ -+ return 0; -+} -+ -+static int b53_mmap_read16(struct b53_device *dev, u8 page, u8 reg, u16 *val) -+{ -+ u8 __iomem *regs = dev->priv; -+ -+ if (WARN_ON(reg % 2)) -+ return -EINVAL; -+ -+ if (dev->pdata && dev->pdata->big_endian) -+ *val = readw_be(regs + (page << 8) + reg); -+ else -+ *val = readw(regs + (page << 8) + reg); -+ -+ return 0; -+} -+ -+static int b53_mmap_read32(struct b53_device *dev, u8 page, u8 reg, u32 *val) -+{ -+ u8 __iomem *regs = dev->priv; -+ -+ if (WARN_ON(reg % 4)) -+ return -EINVAL; -+ -+ if (dev->pdata && dev->pdata->big_endian) -+ *val = readl_be(regs + (page << 8) + reg); -+ else -+ *val = readl(regs + (page << 8) + reg); -+ -+ return 0; -+} -+ -+static int b53_mmap_read48(struct b53_device *dev, u8 page, u8 reg, u64 *val) -+{ -+ if (WARN_ON(reg % 2)) -+ return -EINVAL; -+ -+ if (reg % 4) { -+ u16 lo; -+ u32 hi; -+ -+ b53_mmap_read16(dev, page, reg, &lo); -+ b53_mmap_read32(dev, page, reg + 2, &hi); -+ -+ *val = ((u64)hi << 16) | lo; -+ } else { -+ u32 lo; -+ u16 hi; -+ -+ b53_mmap_read32(dev, page, reg, &lo); -+ b53_mmap_read16(dev, page, reg + 4, &hi); -+ -+ *val = ((u64)hi << 32) | lo; -+ } -+ -+ return 0; -+} -+ -+static int b53_mmap_read64(struct b53_device *dev, u8 page, u8 reg, u64 *val) -+{ -+ u32 hi, lo; -+ -+ if (WARN_ON(reg % 4)) -+ return -EINVAL; -+ -+ b53_mmap_read32(dev, page, reg, &lo); -+ b53_mmap_read32(dev, page, reg + 4, &hi); -+ -+ *val = ((u64)hi << 32) | lo; -+ -+ return 0; -+} -+ -+static int b53_mmap_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) -+{ -+ u8 __iomem *regs = dev->priv; -+ -+ writeb(value, regs + (page << 8) + reg); -+ -+ return 0; -+} -+ -+static int b53_mmap_write16(struct b53_device *dev, u8 page, u8 reg, -+ u16 value) -+{ -+ u8 __iomem *regs = dev->priv; -+ -+ if (WARN_ON(reg % 2)) -+ return -EINVAL; -+ -+ if (dev->pdata && dev->pdata->big_endian) -+ writew_be(value, regs + (page << 8) + reg); -+ else -+ writew(value, regs + (page << 8) + reg); -+ -+ return 0; -+} -+ -+static int b53_mmap_write32(struct b53_device *dev, u8 page, u8 reg, -+ u32 value) -+{ -+ u8 __iomem *regs = dev->priv; -+ -+ if (WARN_ON(reg % 4)) -+ return -EINVAL; -+ -+ if (dev->pdata && dev->pdata->big_endian) -+ writel_be(value, regs + (page << 8) + reg); -+ else -+ writel(value, regs + (page << 8) + reg); -+ -+ return 0; -+} -+ -+static int b53_mmap_write48(struct b53_device *dev, u8 page, u8 reg, -+ u64 value) -+{ -+ if (WARN_ON(reg % 2)) -+ return -EINVAL; -+ -+ if (reg % 4) { -+ u32 hi = (u32)(value >> 16); -+ u16 lo = (u16)value; -+ -+ b53_mmap_write16(dev, page, reg, lo); -+ b53_mmap_write32(dev, page, reg + 2, hi); -+ } else { -+ u16 hi = (u16)(value >> 32); -+ u32 lo = (u32)value; -+ -+ b53_mmap_write32(dev, page, reg, lo); -+ b53_mmap_write16(dev, page, reg + 4, hi); -+ } -+ -+ return 0; -+} -+ -+static int b53_mmap_write64(struct b53_device *dev, u8 page, u8 reg, -+ u64 value) -+{ -+ u32 hi, lo; -+ -+ hi = (u32)(value >> 32); -+ lo = (u32)value; -+ -+ if (WARN_ON(reg % 4)) -+ return -EINVAL; -+ -+ b53_mmap_write32(dev, page, reg, lo); -+ b53_mmap_write32(dev, page, reg + 4, hi); -+ -+ return 0; -+} -+ -+static struct b53_io_ops b53_mmap_ops = { -+ .read8 = b53_mmap_read8, -+ .read16 = b53_mmap_read16, -+ .read32 = b53_mmap_read32, -+ .read48 = b53_mmap_read48, -+ .read64 = b53_mmap_read64, -+ .write8 = b53_mmap_write8, -+ .write16 = b53_mmap_write16, -+ .write32 = b53_mmap_write32, -+ .write48 = b53_mmap_write48, -+ .write64 = b53_mmap_write64, -+}; -+ -+static int b53_mmap_probe(struct platform_device *pdev) -+{ -+ struct b53_platform_data *pdata = pdev->dev.platform_data; -+ struct b53_device *dev; -+ -+ if (!pdata) -+ return -EINVAL; -+ -+ dev = b53_swconfig_switch_alloc(&pdev->dev, &b53_mmap_ops, pdata->regs); -+ if (!dev) -+ return -ENOMEM; -+ -+ if (pdata) -+ dev->pdata = pdata; -+ -+ platform_set_drvdata(pdev, dev); -+ -+ return b53_swconfig_switch_register(dev); -+} -+ -+static void b53_mmap_remove(struct platform_device *pdev) -+{ -+ struct b53_device *dev = platform_get_drvdata(pdev); -+ -+ if (dev) -+ b53_switch_remove(dev); -+} -+ -+static struct platform_driver b53_mmap_driver = { -+ .probe = b53_mmap_probe, -+ .remove_new = b53_mmap_remove, -+ .driver = { -+ .name = "b53-switch", -+ }, -+}; -+ -+module_platform_driver(b53_mmap_driver); -+MODULE_AUTHOR("Jonas Gorski "); -+MODULE_DESCRIPTION("B53 MMAP access driver"); -+MODULE_LICENSE("Dual BSD/GPL"); -diff --git a/drivers/net/phy/b53/b53_phy_fixup.c b/drivers/net/phy/b53/b53_phy_fixup.c -new file mode 100644 -index 000000000000..a19eccefd14c ---- /dev/null -+++ b/drivers/net/phy/b53/b53_phy_fixup.c -@@ -0,0 +1,55 @@ -+/* -+ * B53 PHY Fixup call -+ * -+ * Copyright (C) 2013 Jonas Gorski -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#include -+#include -+#include -+ -+#define B53_PSEUDO_PHY 0x1e /* Register Access Pseudo PHY */ -+ -+#define B53_BRCM_OUI_1 0x0143bc00 -+#define B53_BRCM_OUI_2 0x03625c00 -+#define B53_BRCM_OUI_3 0x00406300 -+ -+static int b53_phy_fixup(struct phy_device *dev) -+{ -+ struct mii_bus *bus = dev->mdio.bus; -+ u32 phy_id; -+ -+ if (dev->mdio.addr != B53_PSEUDO_PHY) -+ return 0; -+ -+ /* read the first port's id */ -+ phy_id = mdiobus_read(bus, 0, 2) << 16; -+ phy_id |= mdiobus_read(bus, 0, 3); -+ -+ if ((phy_id & 0xfffffc00) == B53_BRCM_OUI_1 || -+ (phy_id & 0xfffffc00) == B53_BRCM_OUI_2 || -+ (phy_id & 0xffffff00) == B53_BRCM_OUI_3) { -+ dev->phy_id = phy_id; -+ } -+ -+ return 0; -+} -+ -+int __init b53_phy_fixup_register(void) -+{ -+ return phy_register_fixup_for_id(PHY_ANY_ID, b53_phy_fixup); -+} -+ -+subsys_initcall(b53_phy_fixup_register); -diff --git a/drivers/net/phy/b53/b53_priv.h b/drivers/net/phy/b53/b53_priv.h -new file mode 100644 -index 000000000000..e455c755bf22 ---- /dev/null -+++ b/drivers/net/phy/b53/b53_priv.h -@@ -0,0 +1,336 @@ -+/* -+ * B53 common definitions -+ * -+ * Copyright (C) 2011-2013 Jonas Gorski -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#ifndef __B53_PRIV_H -+#define __B53_PRIV_H -+ -+#include -+#include -+#include -+ -+struct b53_device; -+ -+struct b53_io_ops { -+ int (*read8)(struct b53_device *dev, u8 page, u8 reg, u8 *value); -+ int (*read16)(struct b53_device *dev, u8 page, u8 reg, u16 *value); -+ int (*read32)(struct b53_device *dev, u8 page, u8 reg, u32 *value); -+ int (*read48)(struct b53_device *dev, u8 page, u8 reg, u64 *value); -+ int (*read64)(struct b53_device *dev, u8 page, u8 reg, u64 *value); -+ int (*write8)(struct b53_device *dev, u8 page, u8 reg, u8 value); -+ int (*write16)(struct b53_device *dev, u8 page, u8 reg, u16 value); -+ int (*write32)(struct b53_device *dev, u8 page, u8 reg, u32 value); -+ int (*write48)(struct b53_device *dev, u8 page, u8 reg, u64 value); -+ int (*write64)(struct b53_device *dev, u8 page, u8 reg, u64 value); -+ int (*phy_read16)(struct b53_device *dev, int addr, u8 reg, u16 *value); -+ int (*phy_write16)(struct b53_device *dev, int addr, u8 reg, u16 value); -+}; -+ -+enum { -+ BCM5325_DEVICE_ID = 0x25, -+ BCM5365_DEVICE_ID = 0x65, -+ BCM5395_DEVICE_ID = 0x95, -+ BCM5397_DEVICE_ID = 0x97, -+ BCM5398_DEVICE_ID = 0x98, -+ BCM53115_DEVICE_ID = 0x53115, -+ BCM53125_DEVICE_ID = 0x53125, -+ BCM53128_DEVICE_ID = 0x53128, -+ BCM63XX_DEVICE_ID = 0x6300, -+ BCM53010_DEVICE_ID = 0x53010, -+ BCM53011_DEVICE_ID = 0x53011, -+ BCM53012_DEVICE_ID = 0x53012, -+ BCM53018_DEVICE_ID = 0x53018, -+ BCM53019_DEVICE_ID = 0x53019, -+}; -+ -+#define B53_N_PORTS 9 -+#define B53_N_PORTS_25 6 -+ -+struct b53_vlan { -+ unsigned int members:B53_N_PORTS; -+ unsigned int untag:B53_N_PORTS; -+}; -+ -+struct b53_port { -+ unsigned int pvid:12; -+}; -+ -+struct b53_device { -+ struct switch_dev sw_dev; -+ struct b53_platform_data *pdata; -+ -+ struct mutex reg_mutex; -+ const struct b53_io_ops *ops; -+ -+ /* chip specific data */ -+ u32 chip_id; -+ u8 core_rev; -+ u8 vta_regs[3]; -+ u8 duplex_reg; -+ u8 jumbo_pm_reg; -+ u8 jumbo_size_reg; -+ int reset_gpio; -+ -+ /* used ports mask */ -+ u16 enabled_ports; -+ -+ /* connect specific data */ -+ u8 current_page; -+ struct device *dev; -+ void *priv; -+ -+ /* run time configuration */ -+ unsigned enable_vlan:1; -+ unsigned enable_jumbo:1; -+ unsigned allow_vid_4095:1; -+ -+ struct b53_port *ports; -+ struct b53_vlan *vlans; -+ -+ char *buf; -+}; -+ -+#define b53_for_each_port(dev, i) \ -+ for (i = 0; i < B53_N_PORTS; i++) \ -+ if (dev->enabled_ports & BIT(i)) -+ -+ -+ -+static inline int is5325(struct b53_device *dev) -+{ -+ return dev->chip_id == BCM5325_DEVICE_ID; -+} -+ -+static inline int is5365(struct b53_device *dev) -+{ -+#ifdef CONFIG_BCM47XX -+ return dev->chip_id == BCM5365_DEVICE_ID; -+#else -+ return 0; -+#endif -+} -+ -+static inline int is5397_98(struct b53_device *dev) -+{ -+ return dev->chip_id == BCM5397_DEVICE_ID || -+ dev->chip_id == BCM5398_DEVICE_ID; -+} -+ -+static inline int is539x(struct b53_device *dev) -+{ -+ return dev->chip_id == BCM5395_DEVICE_ID || -+ dev->chip_id == BCM5397_DEVICE_ID || -+ dev->chip_id == BCM5398_DEVICE_ID; -+} -+ -+static inline int is531x5(struct b53_device *dev) -+{ -+ return dev->chip_id == BCM53115_DEVICE_ID || -+ dev->chip_id == BCM53125_DEVICE_ID || -+ dev->chip_id == BCM53128_DEVICE_ID; -+} -+ -+static inline int is63xx(struct b53_device *dev) -+{ -+#ifdef CONFIG_BCM63XX -+ return dev->chip_id == BCM63XX_DEVICE_ID; -+#else -+ return 0; -+#endif -+} -+ -+static inline int is5301x(struct b53_device *dev) -+{ -+ return dev->chip_id == BCM53010_DEVICE_ID || -+ dev->chip_id == BCM53011_DEVICE_ID || -+ dev->chip_id == BCM53012_DEVICE_ID || -+ dev->chip_id == BCM53018_DEVICE_ID || -+ dev->chip_id == BCM53019_DEVICE_ID; -+} -+ -+#define B53_CPU_PORT_25 5 -+#define B53_CPU_PORT 8 -+ -+static inline int is_cpu_port(struct b53_device *dev, int port) -+{ -+ return dev->sw_dev.cpu_port == port; -+} -+ -+static inline int is_imp_port(struct b53_device *dev, int port) -+{ -+ if (is5325(dev) || is5365(dev)) -+ return port == B53_CPU_PORT_25; -+ else -+ return port == B53_CPU_PORT; -+} -+ -+static inline struct b53_device *sw_to_b53(struct switch_dev *sw) -+{ -+ return container_of(sw, struct b53_device, sw_dev); -+} -+ -+struct b53_device *b53_swconfig_switch_alloc(struct device *base, struct b53_io_ops *ops, -+ void *priv); -+ -+int b53_swconfig_switch_detect(struct b53_device *dev); -+ -+int b53_swconfig_switch_register(struct b53_device *dev); -+ -+static inline void b53_switch_remove(struct b53_device *dev) -+{ -+ unregister_switch(&dev->sw_dev); -+} -+ -+static inline int b53_read8(struct b53_device *dev, u8 page, u8 reg, u8 *val) -+{ -+ int ret; -+ -+ mutex_lock(&dev->reg_mutex); -+ ret = dev->ops->read8(dev, page, reg, val); -+ mutex_unlock(&dev->reg_mutex); -+ -+ return ret; -+} -+ -+static inline int b53_read16(struct b53_device *dev, u8 page, u8 reg, u16 *val) -+{ -+ int ret; -+ -+ mutex_lock(&dev->reg_mutex); -+ ret = dev->ops->read16(dev, page, reg, val); -+ mutex_unlock(&dev->reg_mutex); -+ -+ return ret; -+} -+ -+static inline int b53_read32(struct b53_device *dev, u8 page, u8 reg, u32 *val) -+{ -+ int ret; -+ -+ mutex_lock(&dev->reg_mutex); -+ ret = dev->ops->read32(dev, page, reg, val); -+ mutex_unlock(&dev->reg_mutex); -+ -+ return ret; -+} -+ -+static inline int b53_read48(struct b53_device *dev, u8 page, u8 reg, u64 *val) -+{ -+ int ret; -+ -+ mutex_lock(&dev->reg_mutex); -+ ret = dev->ops->read48(dev, page, reg, val); -+ mutex_unlock(&dev->reg_mutex); -+ -+ return ret; -+} -+ -+static inline int b53_read64(struct b53_device *dev, u8 page, u8 reg, u64 *val) -+{ -+ int ret; -+ -+ mutex_lock(&dev->reg_mutex); -+ ret = dev->ops->read64(dev, page, reg, val); -+ mutex_unlock(&dev->reg_mutex); -+ -+ return ret; -+} -+ -+static inline int b53_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) -+{ -+ int ret; -+ -+ mutex_lock(&dev->reg_mutex); -+ ret = dev->ops->write8(dev, page, reg, value); -+ mutex_unlock(&dev->reg_mutex); -+ -+ return ret; -+} -+ -+static inline int b53_write16(struct b53_device *dev, u8 page, u8 reg, -+ u16 value) -+{ -+ int ret; -+ -+ mutex_lock(&dev->reg_mutex); -+ ret = dev->ops->write16(dev, page, reg, value); -+ mutex_unlock(&dev->reg_mutex); -+ -+ return ret; -+} -+ -+static inline int b53_write32(struct b53_device *dev, u8 page, u8 reg, -+ u32 value) -+{ -+ int ret; -+ -+ mutex_lock(&dev->reg_mutex); -+ ret = dev->ops->write32(dev, page, reg, value); -+ mutex_unlock(&dev->reg_mutex); -+ -+ return ret; -+} -+ -+static inline int b53_write48(struct b53_device *dev, u8 page, u8 reg, -+ u64 value) -+{ -+ int ret; -+ -+ mutex_lock(&dev->reg_mutex); -+ ret = dev->ops->write48(dev, page, reg, value); -+ mutex_unlock(&dev->reg_mutex); -+ -+ return ret; -+} -+ -+static inline int b53_write64(struct b53_device *dev, u8 page, u8 reg, -+ u64 value) -+{ -+ int ret; -+ -+ mutex_lock(&dev->reg_mutex); -+ ret = dev->ops->write64(dev, page, reg, value); -+ mutex_unlock(&dev->reg_mutex); -+ -+ return ret; -+} -+ -+#ifdef CONFIG_BCM47XX -+#include -+#endif -+ -+#include -+#include -+ -+static inline int b53_switch_get_reset_gpio(struct b53_device *dev) -+{ -+#ifdef CONFIG_BCM47XX -+ enum bcm47xx_board board = bcm47xx_board_get(); -+ -+ switch (board) { -+ case BCM47XX_BOARD_LINKSYS_WRT300NV11: -+ case BCM47XX_BOARD_LINKSYS_WRT310NV1: -+ return 8; -+ default: -+ break; -+ } -+#endif -+ -+ return bcm47xx_nvram_gpio_pin("robo_reset"); -+} -+ -+#endif -diff --git a/drivers/net/phy/b53/b53_regs.h b/drivers/net/phy/b53/b53_regs.h -new file mode 100644 -index 000000000000..f0bf6744a75c ---- /dev/null -+++ b/drivers/net/phy/b53/b53_regs.h -@@ -0,0 +1,348 @@ -+/* -+ * B53 register definitions -+ * -+ * Copyright (C) 2004 Broadcom Corporation -+ * Copyright (C) 2011-2013 Jonas Gorski -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#ifndef __B53_REGS_H -+#define __B53_REGS_H -+ -+/* Management Port (SMP) Page offsets */ -+#define B53_CTRL_PAGE 0x00 /* Control */ -+#define B53_STAT_PAGE 0x01 /* Status */ -+#define B53_MGMT_PAGE 0x02 /* Management Mode */ -+#define B53_MIB_AC_PAGE 0x03 /* MIB Autocast */ -+#define B53_ARLCTRL_PAGE 0x04 /* ARL Control */ -+#define B53_ARLIO_PAGE 0x05 /* ARL Access */ -+#define B53_FRAMEBUF_PAGE 0x06 /* Management frame access */ -+#define B53_MEM_ACCESS_PAGE 0x08 /* Memory access */ -+ -+/* PHY Registers */ -+#define B53_PORT_MII_PAGE(i) (0x10 + (i)) /* Port i MII Registers */ -+#define B53_IM_PORT_PAGE 0x18 /* Inverse MII Port (to EMAC) */ -+#define B53_ALL_PORT_PAGE 0x19 /* All ports MII (broadcast) */ -+ -+/* MIB registers */ -+#define B53_MIB_PAGE(i) (0x20 + (i)) -+ -+/* Quality of Service (QoS) Registers */ -+#define B53_QOS_PAGE 0x30 -+ -+/* Port VLAN Page */ -+#define B53_PVLAN_PAGE 0x31 -+ -+/* VLAN Registers */ -+#define B53_VLAN_PAGE 0x34 -+ -+/* Jumbo Frame Registers */ -+#define B53_JUMBO_PAGE 0x40 -+ -+/* CFP Configuration Registers Page */ -+#define B53_CFP_PAGE 0xa1 -+ -+/************************************************************************* -+ * Control Page registers -+ *************************************************************************/ -+ -+/* Port Control Register (8 bit) */ -+#define B53_PORT_CTRL(i) (0x00 + (i)) -+#define PORT_CTRL_RX_DISABLE BIT(0) -+#define PORT_CTRL_TX_DISABLE BIT(1) -+#define PORT_CTRL_RX_BCST_EN BIT(2) /* Broadcast RX (P8 only) */ -+#define PORT_CTRL_RX_MCST_EN BIT(3) /* Multicast RX (P8 only) */ -+#define PORT_CTRL_RX_UCST_EN BIT(4) /* Unicast RX (P8 only) */ -+#define PORT_CTRL_STP_STATE_S 5 -+#define PORT_CTRL_STP_STATE_MASK (0x7 << PORT_CTRL_STP_STATE_S) -+ -+/* SMP Control Register (8 bit) */ -+#define B53_SMP_CTRL 0x0a -+ -+/* Switch Mode Control Register (8 bit) */ -+#define B53_SWITCH_MODE 0x0b -+#define SM_SW_FWD_MODE BIT(0) /* 1 = Managed Mode */ -+#define SM_SW_FWD_EN BIT(1) /* Forwarding Enable */ -+ -+/* IMP Port state override register (8 bit) */ -+#define B53_PORT_OVERRIDE_CTRL 0x0e -+#define PORT_OVERRIDE_LINK BIT(0) -+#define PORT_OVERRIDE_FULL_DUPLEX BIT(1) /* 0 = Half Duplex */ -+#define PORT_OVERRIDE_SPEED_S 2 -+#define PORT_OVERRIDE_SPEED_10M (0 << PORT_OVERRIDE_SPEED_S) -+#define PORT_OVERRIDE_SPEED_100M (1 << PORT_OVERRIDE_SPEED_S) -+#define PORT_OVERRIDE_SPEED_1000M (2 << PORT_OVERRIDE_SPEED_S) -+#define PORT_OVERRIDE_RV_MII_25 BIT(4) /* BCM5325 only */ -+#define PORT_OVERRIDE_RX_FLOW BIT(4) -+#define PORT_OVERRIDE_TX_FLOW BIT(5) -+#define PORT_OVERRIDE_SPEED_2000M BIT(6) /* BCM5301X only, requires setting 1000M */ -+#define PORT_OVERRIDE_EN BIT(7) /* Use the register contents */ -+ -+/* Power-down mode control */ -+#define B53_PD_MODE_CTRL_25 0x0f -+ -+/* IP Multicast control (8 bit) */ -+#define B53_IP_MULTICAST_CTRL 0x21 -+#define B53_IPMC_FWD_EN BIT(1) -+#define B53_UC_FWD_EN BIT(6) -+#define B53_MC_FWD_EN BIT(7) -+ -+/* (16 bit) */ -+#define B53_UC_FLOOD_MASK 0x32 -+#define B53_MC_FLOOD_MASK 0x34 -+#define B53_IPMC_FLOOD_MASK 0x36 -+ -+/* -+ * Override Ports 0-7 State on devices with xMII interfaces (8 bit) -+ * -+ * For port 8 still use B53_PORT_OVERRIDE_CTRL -+ * Please note that not all ports are available on every hardware, e.g. BCM5301X -+ * don't include overriding port 6, BCM63xx also have some limitations. -+ */ -+#define B53_GMII_PORT_OVERRIDE_CTRL(i) (0x58 + (i)) -+#define GMII_PO_LINK BIT(0) -+#define GMII_PO_FULL_DUPLEX BIT(1) /* 0 = Half Duplex */ -+#define GMII_PO_SPEED_S 2 -+#define GMII_PO_SPEED_10M (0 << GMII_PO_SPEED_S) -+#define GMII_PO_SPEED_100M (1 << GMII_PO_SPEED_S) -+#define GMII_PO_SPEED_1000M (2 << GMII_PO_SPEED_S) -+#define GMII_PO_RX_FLOW BIT(4) -+#define GMII_PO_TX_FLOW BIT(5) -+#define GMII_PO_EN BIT(6) /* Use the register contents */ -+#define GMII_PO_SPEED_2000M BIT(7) /* BCM5301X only, requires setting 1000M */ -+ -+/* Software reset register (8 bit) */ -+#define B53_SOFTRESET 0x79 -+ -+/* Fast Aging Control register (8 bit) */ -+#define B53_FAST_AGE_CTRL 0x88 -+#define FAST_AGE_STATIC BIT(0) -+#define FAST_AGE_DYNAMIC BIT(1) -+#define FAST_AGE_PORT BIT(2) -+#define FAST_AGE_VLAN BIT(3) -+#define FAST_AGE_STP BIT(4) -+#define FAST_AGE_MC BIT(5) -+#define FAST_AGE_DONE BIT(7) -+ -+/************************************************************************* -+ * Status Page registers -+ *************************************************************************/ -+ -+/* Link Status Summary Register (16bit) */ -+#define B53_LINK_STAT 0x00 -+ -+/* Link Status Change Register (16 bit) */ -+#define B53_LINK_STAT_CHANGE 0x02 -+ -+/* Port Speed Summary Register (16 bit for FE, 32 bit for GE) */ -+#define B53_SPEED_STAT 0x04 -+#define SPEED_PORT_FE(reg, port) (((reg) >> (port)) & 1) -+#define SPEED_PORT_GE(reg, port) (((reg) >> 2 * (port)) & 3) -+#define SPEED_STAT_10M 0 -+#define SPEED_STAT_100M 1 -+#define SPEED_STAT_1000M 2 -+ -+/* Duplex Status Summary (16 bit) */ -+#define B53_DUPLEX_STAT_FE 0x06 -+#define B53_DUPLEX_STAT_GE 0x08 -+#define B53_DUPLEX_STAT_63XX 0x0c -+ -+/* Revision ID register for BCM5325 */ -+#define B53_REV_ID_25 0x50 -+ -+/* Strap Value (48 bit) */ -+#define B53_STRAP_VALUE 0x70 -+#define SV_GMII_CTRL_115 BIT(27) -+ -+/************************************************************************* -+ * Management Mode Page Registers -+ *************************************************************************/ -+ -+/* Global Management Config Register (8 bit) */ -+#define B53_GLOBAL_CONFIG 0x00 -+#define GC_RESET_MIB 0x01 -+#define GC_RX_BPDU_EN 0x02 -+#define GC_MIB_AC_HDR_EN 0x10 -+#define GC_MIB_AC_EN 0x20 -+#define GC_FRM_MGMT_PORT_M 0xC0 -+#define GC_FRM_MGMT_PORT_04 0x00 -+#define GC_FRM_MGMT_PORT_MII 0x80 -+ -+/* Broadcom Header control register (8 bit) */ -+#define B53_BRCM_HDR 0x03 -+#define BRCM_HDR_P8_EN BIT(0) /* Enable tagging on port 8 */ -+#define BRCM_HDR_P5_EN BIT(1) /* Enable tagging on port 5 */ -+ -+/* Device ID register (8 or 32 bit) */ -+#define B53_DEVICE_ID 0x30 -+ -+/* Revision ID register (8 bit) */ -+#define B53_REV_ID 0x40 -+ -+/************************************************************************* -+ * ARL Access Page Registers -+ *************************************************************************/ -+ -+/* VLAN Table Access Register (8 bit) */ -+#define B53_VT_ACCESS 0x80 -+#define B53_VT_ACCESS_9798 0x60 /* for BCM5397/BCM5398 */ -+#define B53_VT_ACCESS_63XX 0x60 /* for BCM6328/62/68 */ -+#define VTA_CMD_WRITE 0 -+#define VTA_CMD_READ 1 -+#define VTA_CMD_CLEAR 2 -+#define VTA_START_CMD BIT(7) -+ -+/* VLAN Table Index Register (16 bit) */ -+#define B53_VT_INDEX 0x81 -+#define B53_VT_INDEX_9798 0x61 -+#define B53_VT_INDEX_63XX 0x62 -+ -+/* VLAN Table Entry Register (32 bit) */ -+#define B53_VT_ENTRY 0x83 -+#define B53_VT_ENTRY_9798 0x63 -+#define B53_VT_ENTRY_63XX 0x64 -+#define VTE_MEMBERS 0x1ff -+#define VTE_UNTAG_S 9 -+#define VTE_UNTAG (0x1ff << 9) -+ -+/************************************************************************* -+ * Port VLAN Registers -+ *************************************************************************/ -+ -+/* Port VLAN mask (16 bit) IMP port is always 8, also on 5325 & co */ -+#define B53_PVLAN_PORT_MASK(i) ((i) * 2) -+ -+/************************************************************************* -+ * 802.1Q Page Registers -+ *************************************************************************/ -+ -+/* Global QoS Control (8 bit) */ -+#define B53_QOS_GLOBAL_CTL 0x00 -+ -+/* Enable 802.1Q for individual Ports (16 bit) */ -+#define B53_802_1P_EN 0x04 -+ -+/************************************************************************* -+ * VLAN Page Registers -+ *************************************************************************/ -+ -+/* VLAN Control 0 (8 bit) */ -+#define B53_VLAN_CTRL0 0x00 -+#define VC0_8021PF_CTRL_MASK 0x3 -+#define VC0_8021PF_CTRL_NONE 0x0 -+#define VC0_8021PF_CTRL_CHANGE_PRI 0x1 -+#define VC0_8021PF_CTRL_CHANGE_VID 0x2 -+#define VC0_8021PF_CTRL_CHANGE_BOTH 0x3 -+#define VC0_8021QF_CTRL_MASK 0xc -+#define VC0_8021QF_CTRL_CHANGE_PRI 0x1 -+#define VC0_8021QF_CTRL_CHANGE_VID 0x2 -+#define VC0_8021QF_CTRL_CHANGE_BOTH 0x3 -+#define VC0_RESERVED_1 BIT(1) -+#define VC0_DROP_VID_MISS BIT(4) -+#define VC0_VID_HASH_VID BIT(5) -+#define VC0_VID_CHK_EN BIT(6) /* Use VID,DA or VID,SA */ -+#define VC0_VLAN_EN BIT(7) /* 802.1Q VLAN Enabled */ -+ -+/* VLAN Control 1 (8 bit) */ -+#define B53_VLAN_CTRL1 0x01 -+#define VC1_RX_MCST_TAG_EN BIT(1) -+#define VC1_RX_MCST_FWD_EN BIT(2) -+#define VC1_RX_MCST_UNTAG_EN BIT(3) -+ -+/* VLAN Control 2 (8 bit) */ -+#define B53_VLAN_CTRL2 0x02 -+ -+/* VLAN Control 3 (8 bit when BCM5325, 16 bit else) */ -+#define B53_VLAN_CTRL3 0x03 -+#define B53_VLAN_CTRL3_63XX 0x04 -+#define VC3_MAXSIZE_1532 BIT(6) /* 5325 only */ -+#define VC3_HIGH_8BIT_EN BIT(7) /* 5325 only */ -+ -+/* VLAN Control 4 (8 bit) */ -+#define B53_VLAN_CTRL4 0x05 -+#define B53_VLAN_CTRL4_25 0x04 -+#define B53_VLAN_CTRL4_63XX 0x06 -+#define VC4_ING_VID_CHECK_S 6 -+#define VC4_ING_VID_CHECK_MASK (0x3 << VC4_ING_VID_CHECK_S) -+#define VC4_ING_VID_VIO_FWD 0 /* forward, but do not learn */ -+#define VC4_ING_VID_VIO_DROP 1 /* drop VID violations */ -+#define VC4_NO_ING_VID_CHK 2 /* do not check */ -+#define VC4_ING_VID_VIO_TO_IMP 3 /* redirect to MII port */ -+ -+/* VLAN Control 5 (8 bit) */ -+#define B53_VLAN_CTRL5 0x06 -+#define B53_VLAN_CTRL5_25 0x05 -+#define B53_VLAN_CTRL5_63XX 0x07 -+#define VC5_VID_FFF_EN BIT(2) -+#define VC5_DROP_VTABLE_MISS BIT(3) -+ -+/* VLAN Control 6 (8 bit) */ -+#define B53_VLAN_CTRL6 0x07 -+#define B53_VLAN_CTRL6_63XX 0x08 -+ -+/* VLAN Table Access Register (16 bit) */ -+#define B53_VLAN_TABLE_ACCESS_25 0x06 /* BCM5325E/5350 */ -+#define B53_VLAN_TABLE_ACCESS_65 0x08 /* BCM5365 */ -+#define VTA_VID_LOW_MASK_25 0xf -+#define VTA_VID_LOW_MASK_65 0xff -+#define VTA_VID_HIGH_S_25 4 -+#define VTA_VID_HIGH_S_65 8 -+#define VTA_VID_HIGH_MASK_25 (0xff << VTA_VID_HIGH_S_25E) -+#define VTA_VID_HIGH_MASK_65 (0xf << VTA_VID_HIGH_S_65) -+#define VTA_RW_STATE BIT(12) -+#define VTA_RW_STATE_RD 0 -+#define VTA_RW_STATE_WR BIT(12) -+#define VTA_RW_OP_EN BIT(13) -+ -+/* VLAN Read/Write Registers for (16/32 bit) */ -+#define B53_VLAN_WRITE_25 0x08 -+#define B53_VLAN_WRITE_65 0x0a -+#define B53_VLAN_READ 0x0c -+#define VA_MEMBER_MASK 0x3f -+#define VA_UNTAG_S_25 6 -+#define VA_UNTAG_MASK_25 0x3f -+#define VA_UNTAG_S_65 7 -+#define VA_UNTAG_MASK_65 0x1f -+#define VA_VID_HIGH_S 12 -+#define VA_VID_HIGH_MASK (0xffff << VA_VID_HIGH_S) -+#define VA_VALID_25 BIT(20) -+#define VA_VALID_25_R4 BIT(24) -+#define VA_VALID_65 BIT(14) -+ -+/* VLAN Port Default Tag (16 bit) */ -+#define B53_VLAN_PORT_DEF_TAG(i) (0x10 + 2 * (i)) -+ -+/************************************************************************* -+ * Jumbo Frame Page Registers -+ *************************************************************************/ -+ -+/* Jumbo Enable Port Mask (bit i == port i enabled) (32 bit) */ -+#define B53_JUMBO_PORT_MASK 0x01 -+#define B53_JUMBO_PORT_MASK_63XX 0x04 -+#define JPM_10_100_JUMBO_EN BIT(24) /* GigE always enabled */ -+ -+/* Good Frame Max Size without 802.1Q TAG (16 bit) */ -+#define B53_JUMBO_MAX_SIZE 0x05 -+#define B53_JUMBO_MAX_SIZE_63XX 0x08 -+#define JMS_MIN_SIZE 1518 -+#define JMS_MAX_SIZE 9724 -+ -+/************************************************************************* -+ * CFP Configuration Page Registers -+ *************************************************************************/ -+ -+/* CFP Control Register with ports map (8 bit) */ -+#define B53_CFP_CTRL 0x00 -+ -+#endif /* !__B53_REGS_H */ -diff --git a/drivers/net/phy/b53/b53_spi.c b/drivers/net/phy/b53/b53_spi.c -new file mode 100644 -index 000000000000..400454df18c1 ---- /dev/null -+++ b/drivers/net/phy/b53/b53_spi.c -@@ -0,0 +1,344 @@ -+/* -+ * B53 register access through SPI -+ * -+ * Copyright (C) 2011-2013 Jonas Gorski -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "b53_priv.h" -+ -+#define B53_SPI_DATA 0xf0 -+ -+#define B53_SPI_STATUS 0xfe -+#define B53_SPI_CMD_SPIF BIT(7) -+#define B53_SPI_CMD_RACK BIT(5) -+ -+#define B53_SPI_CMD_READ 0x00 -+#define B53_SPI_CMD_WRITE 0x01 -+#define B53_SPI_CMD_NORMAL 0x60 -+#define B53_SPI_CMD_FAST 0x10 -+ -+#define B53_SPI_PAGE_SELECT 0xff -+ -+static inline int b53_spi_read_reg(struct spi_device *spi, u8 reg, u8 *val, -+ unsigned len) -+{ -+ u8 txbuf[2]; -+ -+ txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_READ; -+ txbuf[1] = reg; -+ -+ return spi_write_then_read(spi, txbuf, 2, val, len); -+} -+ -+static inline int b53_spi_clear_status(struct spi_device *spi) -+{ -+ unsigned int i; -+ u8 rxbuf; -+ int ret; -+ -+ for (i = 0; i < 10; i++) { -+ ret = b53_spi_read_reg(spi, B53_SPI_STATUS, &rxbuf, 1); -+ if (ret) -+ return ret; -+ -+ if (!(rxbuf & B53_SPI_CMD_SPIF)) -+ break; -+ -+ mdelay(1); -+ } -+ -+ if (i == 10) -+ return -EIO; -+ -+ return 0; -+} -+ -+static inline int b53_spi_set_page(struct spi_device *spi, u8 page) -+{ -+ u8 txbuf[3]; -+ -+ txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE; -+ txbuf[1] = B53_SPI_PAGE_SELECT; -+ txbuf[2] = page; -+ -+ return spi_write(spi, txbuf, sizeof(txbuf)); -+} -+ -+static inline int b53_prepare_reg_access(struct spi_device *spi, u8 page) -+{ -+ int ret = b53_spi_clear_status(spi); -+ -+ if (ret) -+ return ret; -+ -+ return b53_spi_set_page(spi, page); -+} -+ -+static int b53_spi_prepare_reg_read(struct spi_device *spi, u8 reg) -+{ -+ u8 rxbuf; -+ int retry_count; -+ int ret; -+ -+ ret = b53_spi_read_reg(spi, reg, &rxbuf, 1); -+ if (ret) -+ return ret; -+ -+ for (retry_count = 0; retry_count < 10; retry_count++) { -+ ret = b53_spi_read_reg(spi, B53_SPI_STATUS, &rxbuf, 1); -+ if (ret) -+ return ret; -+ -+ if (rxbuf & B53_SPI_CMD_RACK) -+ break; -+ -+ mdelay(1); -+ } -+ -+ if (retry_count == 10) -+ return -EIO; -+ -+ return 0; -+} -+ -+static int b53_spi_read(struct b53_device *dev, u8 page, u8 reg, u8 *data, -+ unsigned len) -+{ -+ struct spi_device *spi = dev->priv; -+ int ret; -+ -+ ret = b53_prepare_reg_access(spi, page); -+ if (ret) -+ return ret; -+ -+ ret = b53_spi_prepare_reg_read(spi, reg); -+ if (ret) -+ return ret; -+ -+ return b53_spi_read_reg(spi, B53_SPI_DATA, data, len); -+} -+ -+static int b53_spi_read8(struct b53_device *dev, u8 page, u8 reg, u8 *val) -+{ -+ return b53_spi_read(dev, page, reg, val, 1); -+} -+ -+static int b53_spi_read16(struct b53_device *dev, u8 page, u8 reg, u16 *val) -+{ -+ int ret = b53_spi_read(dev, page, reg, (u8 *)val, 2); -+ -+ if (!ret) -+ *val = le16_to_cpu(*val); -+ -+ return ret; -+} -+ -+static int b53_spi_read32(struct b53_device *dev, u8 page, u8 reg, u32 *val) -+{ -+ int ret = b53_spi_read(dev, page, reg, (u8 *)val, 4); -+ -+ if (!ret) -+ *val = le32_to_cpu(*val); -+ -+ return ret; -+} -+ -+static int b53_spi_read48(struct b53_device *dev, u8 page, u8 reg, u64 *val) -+{ -+ int ret; -+ -+ *val = 0; -+ ret = b53_spi_read(dev, page, reg, (u8 *)val, 6); -+ if (!ret) -+ *val = le64_to_cpu(*val); -+ -+ return ret; -+} -+ -+static int b53_spi_read64(struct b53_device *dev, u8 page, u8 reg, u64 *val) -+{ -+ int ret = b53_spi_read(dev, page, reg, (u8 *)val, 8); -+ -+ if (!ret) -+ *val = le64_to_cpu(*val); -+ -+ return ret; -+} -+ -+static int b53_spi_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) -+{ -+ struct spi_device *spi = dev->priv; -+ int ret; -+ u8 txbuf[3]; -+ -+ ret = b53_prepare_reg_access(spi, page); -+ if (ret) -+ return ret; -+ -+ txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE; -+ txbuf[1] = reg; -+ txbuf[2] = value; -+ -+ return spi_write(spi, txbuf, sizeof(txbuf)); -+} -+ -+static int b53_spi_write16(struct b53_device *dev, u8 page, u8 reg, u16 value) -+{ -+ struct spi_device *spi = dev->priv; -+ int ret; -+ u8 txbuf[4]; -+ -+ ret = b53_prepare_reg_access(spi, page); -+ if (ret) -+ return ret; -+ -+ txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE; -+ txbuf[1] = reg; -+ put_unaligned_le16(value, &txbuf[2]); -+ -+ return spi_write(spi, txbuf, sizeof(txbuf)); -+} -+ -+static int b53_spi_write32(struct b53_device *dev, u8 page, u8 reg, u32 value) -+{ -+ struct spi_device *spi = dev->priv; -+ int ret; -+ u8 txbuf[6]; -+ -+ ret = b53_prepare_reg_access(spi, page); -+ if (ret) -+ return ret; -+ -+ txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE; -+ txbuf[1] = reg; -+ put_unaligned_le32(value, &txbuf[2]); -+ -+ return spi_write(spi, txbuf, sizeof(txbuf)); -+} -+ -+static int b53_spi_write48(struct b53_device *dev, u8 page, u8 reg, u64 value) -+{ -+ struct spi_device *spi = dev->priv; -+ int ret; -+ u8 txbuf[10]; -+ -+ ret = b53_prepare_reg_access(spi, page); -+ if (ret) -+ return ret; -+ -+ txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE; -+ txbuf[1] = reg; -+ put_unaligned_le64(value, &txbuf[2]); -+ -+ return spi_write(spi, txbuf, sizeof(txbuf) - 2); -+} -+ -+static int b53_spi_write64(struct b53_device *dev, u8 page, u8 reg, u64 value) -+{ -+ struct spi_device *spi = dev->priv; -+ int ret; -+ u8 txbuf[10]; -+ -+ ret = b53_prepare_reg_access(spi, page); -+ if (ret) -+ return ret; -+ -+ txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE; -+ txbuf[1] = reg; -+ put_unaligned_le64(value, &txbuf[2]); -+ -+ return spi_write(spi, txbuf, sizeof(txbuf)); -+} -+ -+static struct b53_io_ops b53_spi_ops = { -+ .read8 = b53_spi_read8, -+ .read16 = b53_spi_read16, -+ .read32 = b53_spi_read32, -+ .read48 = b53_spi_read48, -+ .read64 = b53_spi_read64, -+ .write8 = b53_spi_write8, -+ .write16 = b53_spi_write16, -+ .write32 = b53_spi_write32, -+ .write48 = b53_spi_write48, -+ .write64 = b53_spi_write64, -+}; -+ -+static int b53_spi_probe(struct spi_device *spi) -+{ -+ struct b53_device *dev; -+ int ret; -+ -+ dev = b53_swconfig_switch_alloc(&spi->dev, &b53_spi_ops, spi); -+ if (!dev) -+ return -ENOMEM; -+ -+ if (spi->dev.platform_data) -+ dev->pdata = spi->dev.platform_data; -+ -+ ret = b53_swconfig_switch_register(dev); -+ if (ret) -+ return ret; -+ -+ spi_set_drvdata(spi, dev); -+ -+ return 0; -+} -+ -+static int b53_spi_remove(struct spi_device *spi) -+{ -+ struct b53_device *dev = spi_get_drvdata(spi); -+ -+ if (dev) -+ b53_switch_remove(dev); -+ -+ return 0; -+} -+ -+static const struct of_device_id b53_of_match[] = { -+ { .compatible = "brcm,bcm5325" }, -+ { .compatible = "brcm,bcm53115" }, -+ { .compatible = "brcm,bcm53125" }, -+ { .compatible = "brcm,bcm53128" }, -+ { .compatible = "brcm,bcm5365" }, -+ { .compatible = "brcm,bcm5395" }, -+ { .compatible = "brcm,bcm5397" }, -+ { .compatible = "brcm,bcm5398" }, -+ { /* sentinel */ }, -+}; -+ -+static struct spi_driver b53_spi_driver = { -+ .driver = { -+ .name = "b53-switch", -+ .bus = &spi_bus_type, -+ .owner = THIS_MODULE, -+ .of_match_table = b53_of_match, -+ }, -+ .probe = b53_spi_probe, -+ .remove = b53_spi_remove, -+}; -+ -+module_spi_driver(b53_spi_driver); -+ -+MODULE_AUTHOR("Jonas Gorski "); -+MODULE_DESCRIPTION("B53 SPI access driver"); -+MODULE_LICENSE("Dual BSD/GPL"); -diff --git a/drivers/net/phy/b53/b53_srab.c b/drivers/net/phy/b53/b53_srab.c -new file mode 100644 -index 000000000000..f8cb99383ff1 ---- /dev/null -+++ b/drivers/net/phy/b53/b53_srab.c -@@ -0,0 +1,376 @@ -+/* -+ * B53 register access through Switch Register Access Bridge Registers -+ * -+ * Copyright (C) 2013 Hauke Mehrtens -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "b53_priv.h" -+ -+/* command and status register of the SRAB */ -+#define B53_SRAB_CMDSTAT 0x2c -+#define B53_SRAB_CMDSTAT_RST BIT(2) -+#define B53_SRAB_CMDSTAT_WRITE BIT(1) -+#define B53_SRAB_CMDSTAT_GORDYN BIT(0) -+#define B53_SRAB_CMDSTAT_PAGE 24 -+#define B53_SRAB_CMDSTAT_REG 16 -+ -+/* high order word of write data to switch registe */ -+#define B53_SRAB_WD_H 0x30 -+ -+/* low order word of write data to switch registe */ -+#define B53_SRAB_WD_L 0x34 -+ -+/* high order word of read data from switch register */ -+#define B53_SRAB_RD_H 0x38 -+ -+/* low order word of read data from switch register */ -+#define B53_SRAB_RD_L 0x3c -+ -+/* command and status register of the SRAB */ -+#define B53_SRAB_CTRLS 0x40 -+#define B53_SRAB_CTRLS_RCAREQ BIT(3) -+#define B53_SRAB_CTRLS_RCAGNT BIT(4) -+#define B53_SRAB_CTRLS_SW_INIT_DONE BIT(6) -+ -+/* the register captures interrupt pulses from the switch */ -+#define B53_SRAB_INTR 0x44 -+ -+static int b53_srab_request_grant(struct b53_device *dev) -+{ -+ u8 __iomem *regs = dev->priv; -+ u32 ctrls; -+ int i; -+ -+ ctrls = readl(regs + B53_SRAB_CTRLS); -+ ctrls |= B53_SRAB_CTRLS_RCAREQ; -+ writel(ctrls, regs + B53_SRAB_CTRLS); -+ -+ for (i = 0; i < 20; i++) { -+ ctrls = readl(regs + B53_SRAB_CTRLS); -+ if (ctrls & B53_SRAB_CTRLS_RCAGNT) -+ break; -+ usleep_range(10, 100); -+ } -+ if (WARN_ON(i == 5)) -+ return -EIO; -+ -+ return 0; -+} -+ -+static void b53_srab_release_grant(struct b53_device *dev) -+{ -+ u8 __iomem *regs = dev->priv; -+ u32 ctrls; -+ -+ ctrls = readl(regs + B53_SRAB_CTRLS); -+ ctrls &= ~B53_SRAB_CTRLS_RCAREQ; -+ writel(ctrls, regs + B53_SRAB_CTRLS); -+} -+ -+static int b53_srab_op(struct b53_device *dev, u8 page, u8 reg, u32 op) -+{ -+ int i; -+ u32 cmdstat; -+ u8 __iomem *regs = dev->priv; -+ -+ /* set register address */ -+ cmdstat = (page << B53_SRAB_CMDSTAT_PAGE) | -+ (reg << B53_SRAB_CMDSTAT_REG) | -+ B53_SRAB_CMDSTAT_GORDYN | -+ op; -+ writel(cmdstat, regs + B53_SRAB_CMDSTAT); -+ -+ /* check if operation completed */ -+ for (i = 0; i < 5; ++i) { -+ cmdstat = readl(regs + B53_SRAB_CMDSTAT); -+ if (!(cmdstat & B53_SRAB_CMDSTAT_GORDYN)) -+ break; -+ usleep_range(10, 100); -+ } -+ -+ if (WARN_ON(i == 5)) -+ return -EIO; -+ -+ return 0; -+} -+ -+static int b53_srab_read8(struct b53_device *dev, u8 page, u8 reg, u8 *val) -+{ -+ u8 __iomem *regs = dev->priv; -+ int ret = 0; -+ -+ ret = b53_srab_request_grant(dev); -+ if (ret) -+ goto err; -+ -+ ret = b53_srab_op(dev, page, reg, 0); -+ if (ret) -+ goto err; -+ -+ *val = readl(regs + B53_SRAB_RD_L) & 0xff; -+ -+err: -+ b53_srab_release_grant(dev); -+ -+ return ret; -+} -+ -+static int b53_srab_read16(struct b53_device *dev, u8 page, u8 reg, u16 *val) -+{ -+ u8 __iomem *regs = dev->priv; -+ int ret = 0; -+ -+ ret = b53_srab_request_grant(dev); -+ if (ret) -+ goto err; -+ -+ ret = b53_srab_op(dev, page, reg, 0); -+ if (ret) -+ goto err; -+ -+ *val = readl(regs + B53_SRAB_RD_L) & 0xffff; -+ -+err: -+ b53_srab_release_grant(dev); -+ -+ return ret; -+} -+ -+static int b53_srab_read32(struct b53_device *dev, u8 page, u8 reg, u32 *val) -+{ -+ u8 __iomem *regs = dev->priv; -+ int ret = 0; -+ -+ ret = b53_srab_request_grant(dev); -+ if (ret) -+ goto err; -+ -+ ret = b53_srab_op(dev, page, reg, 0); -+ if (ret) -+ goto err; -+ -+ *val = readl(regs + B53_SRAB_RD_L); -+ -+err: -+ b53_srab_release_grant(dev); -+ -+ return ret; -+} -+ -+static int b53_srab_read48(struct b53_device *dev, u8 page, u8 reg, u64 *val) -+{ -+ u8 __iomem *regs = dev->priv; -+ int ret = 0; -+ -+ ret = b53_srab_request_grant(dev); -+ if (ret) -+ goto err; -+ -+ ret = b53_srab_op(dev, page, reg, 0); -+ if (ret) -+ goto err; -+ -+ *val = readl(regs + B53_SRAB_RD_L); -+ *val += ((u64)readl(regs + B53_SRAB_RD_H) & 0xffff) << 32; -+ -+err: -+ b53_srab_release_grant(dev); -+ -+ return ret; -+} -+ -+static int b53_srab_read64(struct b53_device *dev, u8 page, u8 reg, u64 *val) -+{ -+ u8 __iomem *regs = dev->priv; -+ int ret = 0; -+ -+ ret = b53_srab_request_grant(dev); -+ if (ret) -+ goto err; -+ -+ ret = b53_srab_op(dev, page, reg, 0); -+ if (ret) -+ goto err; -+ -+ *val = readl(regs + B53_SRAB_RD_L); -+ *val += (u64)readl(regs + B53_SRAB_RD_H) << 32; -+ -+err: -+ b53_srab_release_grant(dev); -+ -+ return ret; -+} -+ -+static int b53_srab_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) -+{ -+ u8 __iomem *regs = dev->priv; -+ int ret = 0; -+ -+ ret = b53_srab_request_grant(dev); -+ if (ret) -+ goto err; -+ -+ writel(value, regs + B53_SRAB_WD_L); -+ -+ ret = b53_srab_op(dev, page, reg, B53_SRAB_CMDSTAT_WRITE); -+ -+err: -+ b53_srab_release_grant(dev); -+ -+ return ret; -+} -+ -+static int b53_srab_write16(struct b53_device *dev, u8 page, u8 reg, -+ u16 value) -+{ -+ u8 __iomem *regs = dev->priv; -+ int ret = 0; -+ -+ ret = b53_srab_request_grant(dev); -+ if (ret) -+ goto err; -+ -+ writel(value, regs + B53_SRAB_WD_L); -+ -+ ret = b53_srab_op(dev, page, reg, B53_SRAB_CMDSTAT_WRITE); -+ -+err: -+ b53_srab_release_grant(dev); -+ -+ return ret; -+} -+ -+static int b53_srab_write32(struct b53_device *dev, u8 page, u8 reg, -+ u32 value) -+{ -+ u8 __iomem *regs = dev->priv; -+ int ret = 0; -+ -+ ret = b53_srab_request_grant(dev); -+ if (ret) -+ goto err; -+ -+ writel(value, regs + B53_SRAB_WD_L); -+ -+ ret = b53_srab_op(dev, page, reg, B53_SRAB_CMDSTAT_WRITE); -+ -+err: -+ b53_srab_release_grant(dev); -+ -+ return ret; -+ -+} -+ -+static int b53_srab_write48(struct b53_device *dev, u8 page, u8 reg, -+ u64 value) -+{ -+ u8 __iomem *regs = dev->priv; -+ int ret = 0; -+ -+ ret = b53_srab_request_grant(dev); -+ if (ret) -+ goto err; -+ -+ writel((u32)value, regs + B53_SRAB_WD_L); -+ writel((u16)(value >> 32), regs + B53_SRAB_WD_H); -+ -+ ret = b53_srab_op(dev, page, reg, B53_SRAB_CMDSTAT_WRITE); -+ -+err: -+ b53_srab_release_grant(dev); -+ -+ return ret; -+ -+} -+ -+static int b53_srab_write64(struct b53_device *dev, u8 page, u8 reg, -+ u64 value) -+{ -+ u8 __iomem *regs = dev->priv; -+ int ret = 0; -+ -+ ret = b53_srab_request_grant(dev); -+ if (ret) -+ goto err; -+ -+ writel((u32)value, regs + B53_SRAB_WD_L); -+ writel((u32)(value >> 32), regs + B53_SRAB_WD_H); -+ -+ ret = b53_srab_op(dev, page, reg, B53_SRAB_CMDSTAT_WRITE); -+ -+err: -+ b53_srab_release_grant(dev); -+ -+ return ret; -+} -+ -+static struct b53_io_ops b53_srab_ops = { -+ .read8 = b53_srab_read8, -+ .read16 = b53_srab_read16, -+ .read32 = b53_srab_read32, -+ .read48 = b53_srab_read48, -+ .read64 = b53_srab_read64, -+ .write8 = b53_srab_write8, -+ .write16 = b53_srab_write16, -+ .write32 = b53_srab_write32, -+ .write48 = b53_srab_write48, -+ .write64 = b53_srab_write64, -+}; -+ -+static int b53_srab_probe(struct platform_device *pdev) -+{ -+ struct b53_platform_data *pdata = pdev->dev.platform_data; -+ struct b53_device *dev; -+ -+ if (!pdata) -+ return -EINVAL; -+ -+ dev = b53_swconfig_switch_alloc(&pdev->dev, &b53_srab_ops, pdata->regs); -+ if (!dev) -+ return -ENOMEM; -+ -+ if (pdata) -+ dev->pdata = pdata; -+ -+ platform_set_drvdata(pdev, dev); -+ -+ return b53_swconfig_switch_register(dev); -+} -+ -+static void b53_srab_remove(struct platform_device *pdev) -+{ -+ struct b53_device *dev = platform_get_drvdata(pdev); -+ -+ if (dev) -+ b53_switch_remove(dev); -+} -+ -+static struct platform_driver b53_srab_driver = { -+ .probe = b53_srab_probe, -+ .remove_new = b53_srab_remove, -+ .driver = { -+ .name = "b53-srab-switch", -+ }, -+}; -+ -+module_platform_driver(b53_srab_driver); -+MODULE_AUTHOR("Hauke Mehrtens "); -+MODULE_DESCRIPTION("B53 Switch Register Access Bridge Registers (SRAB) access driver"); -+MODULE_LICENSE("Dual BSD/GPL"); -diff --git a/drivers/net/phy/en8801sc.c b/drivers/net/phy/en8801sc.c -new file mode 100644 -index 000000000000..08774e3b8889 ---- /dev/null -+++ b/drivers/net/phy/en8801sc.c -@@ -0,0 +1,1117 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* FILE NAME: en8801sc.c -+ * PURPOSE: -+ * EN8801SC phy driver for Linux -+ * NOTES: -+ * -+ */ -+ -+/* INCLUDE FILE DECLARATIONS -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "en8801sc.h" -+ -+MODULE_DESCRIPTION("Airoha EN8801S PHY drivers for MediaTek SoC"); -+MODULE_AUTHOR("Airoha"); -+MODULE_LICENSE("GPL"); -+ -+#define airoha_mdio_lock(bus) mutex_lock(&((bus)->mdio_lock)) -+#define airoha_mdio_unlock(bus) mutex_unlock(&((bus)->mdio_lock)) -+ -+#define phydev_mdio_bus(_dev) (_dev->mdio.bus) -+#define phydev_phy_addr(_dev) (_dev->mdio.addr) -+#define phydev_dev(_dev) (&_dev->mdio.dev) -+#define phydev_pbus_addr(dev) ((dev)->mdio.addr + 1) -+ -+enum { -+ PHY_STATE_DONE = 0, -+ PHY_STATE_INIT = 1, -+ PHY_STATE_PROCESS = 2, -+ PHY_STATE_FAIL = 3, -+}; -+ -+struct en8801s_priv { -+ bool first_init; -+ u16 count; -+ u16 pro_version; -+}; -+ -+/* -+The following led_cfg example is for reference only. -+LED5 1000M/LINK/ACT (GPIO5) <-> BASE_T_LED0, -+LED6 10/100M/LINK/ACT (GPIO9) <-> BASE_T_LED1, -+LED4 100M/LINK/ACT (GPIO8) <-> BASE_T_LED2, -+*/ -+/* User-defined.B */ -+#define AIR_LED_SUPPORT -+#ifdef AIR_LED_SUPPORT -+static const struct AIR_BASE_T_LED_CFG_S led_cfg[4] = { -+/* -+* {LED Enable, GPIO, LED Polarity, LED ON, LED Blink} -+*/ -+ /* BASE-T LED0 */ -+ {LED_ENABLE, 5, AIR_ACTIVE_LOW, -+ BASE_T_LED0_ON_CFG, BASE_T_LED0_BLK_CFG}, -+ /* BASE-T LED1 */ -+ {LED_ENABLE, 9, AIR_ACTIVE_LOW, -+ BASE_T_LED1_ON_CFG, BASE_T_LED1_BLK_CFG}, -+ /* BASE-T LED2 */ -+ {LED_ENABLE, 8, AIR_ACTIVE_LOW, -+ BASE_T_LED2_ON_CFG, BASE_T_LED2_BLK_CFG}, -+ /* BASE-T LED3 */ -+ {LED_DISABLE, 1, AIR_ACTIVE_LOW, -+ BASE_T_LED3_ON_CFG, BASE_T_LED3_BLK_CFG}, -+}; -+static const u16 led_dur = UNIT_LED_BLINK_DURATION << AIR_LED_BLK_DUR_64M; -+#endif -+ -+/* User-defined.E */ -+ -+/************************************************************************ -+* F U N C T I O N S -+************************************************************************/ -+static int en8801s_phase2_init(struct phy_device *phydev); -+ -+static int __airoha_cl45_write(struct mii_bus *bus, int port, -+ u32 devad, u32 reg, u16 val) -+{ -+ int ret = 0; -+ struct device *dev = &bus->dev; -+ -+ ret = __mdiobus_write(bus, port, MII_MMD_ACC_CTL_REG, devad); -+ if (ret < 0) { -+ dev_err(dev, "%s fail. (ret=%d)\n", __func__, ret); -+ return ret; -+ } -+ ret = __mdiobus_write(bus, port, MII_MMD_ADDR_DATA_REG, reg); -+ if (ret < 0) { -+ dev_err(dev, "%s fail. (ret=%d)\n", __func__, ret); -+ return ret; -+ } -+ ret = __mdiobus_write(bus, port, MII_MMD_ACC_CTL_REG, -+ MMD_OP_MODE_DATA | devad); -+ if (ret < 0) { -+ dev_err(dev, "%s fail. (ret=%d)\n", __func__, ret); -+ return ret; -+ } -+ ret = __mdiobus_write(bus, port, MII_MMD_ADDR_DATA_REG, val); -+ if (ret < 0) { -+ dev_err(dev, "%s fail. (ret=%d)\n", __func__, ret); -+ return ret; -+ } -+ -+ return ret; -+} -+ -+static int __airoha_cl45_read(struct mii_bus *bus, int port, -+ u32 devad, u32 reg, u16 *read_data) -+{ -+ int ret = 0; -+ struct device *dev = &bus->dev; -+ -+ ret = __mdiobus_write(bus, port, MII_MMD_ACC_CTL_REG, devad); -+ if (ret < 0) { -+ dev_err(dev, "%s fail. (ret=%d)\n", __func__, ret); -+ return ret; -+ } -+ ret = __mdiobus_write(bus, port, MII_MMD_ADDR_DATA_REG, reg); -+ if (ret < 0) { -+ dev_err(dev, "%s fail. (ret=%d)\n", __func__, ret); -+ return ret; -+ } -+ ret = __mdiobus_write(bus, port, MII_MMD_ACC_CTL_REG, -+ MMD_OP_MODE_DATA | devad); -+ if (ret < 0) { -+ dev_err(dev, "%s fail. (ret=%d)\n", __func__, ret); -+ return ret; -+ } -+ *read_data = __mdiobus_read(bus, port, MII_MMD_ADDR_DATA_REG); -+ -+ return ret; -+} -+ -+static int airoha_cl45_write(struct mii_bus *bus, int port, -+ u32 devad, u32 reg, u16 val) -+{ -+ int ret = 0; -+ -+ airoha_mdio_lock(bus); -+ ret = __airoha_cl45_write(bus, port, devad, reg, val); -+ airoha_mdio_unlock(bus); -+ -+ return ret; -+} -+ -+static int airoha_cl45_read(struct mii_bus *bus, int port, -+ u32 devad, u32 reg, u16 *read_data) -+{ -+ int ret = 0; -+ -+ airoha_mdio_lock(bus); -+ ret = __airoha_cl45_read(bus, port, devad, reg, read_data); -+ airoha_mdio_unlock(bus); -+ -+ return ret; -+} -+ -+static int __airoha_pbus_write(struct mii_bus *ebus, int pbus_id, -+ unsigned long pbus_address, unsigned long pbus_data) -+{ -+ int ret = 0; -+ -+ ret = __mdiobus_write(ebus, pbus_id, 0x1F, -+ (unsigned int)(pbus_address >> 6)); -+ if (ret < 0) -+ return ret; -+ ret = __mdiobus_write(ebus, pbus_id, -+ (unsigned int)((pbus_address >> 2) & 0xf), -+ (unsigned int)(pbus_data & 0xFFFF)); -+ if (ret < 0) -+ return ret; -+ ret = __mdiobus_write(ebus, pbus_id, 0x10, -+ (unsigned int)(pbus_data >> 16)); -+ if (ret < 0) -+ return ret; -+ return ret; -+} -+ -+static unsigned long __airoha_pbus_read(struct mii_bus *ebus, int pbus_id, -+ unsigned long pbus_address) -+{ -+ unsigned long pbus_data; -+ unsigned int pbus_data_low, pbus_data_high; -+ int ret = 0; -+ struct device *dev = &ebus->dev; -+ -+ ret = __mdiobus_write(ebus, pbus_id, 0x1F, -+ (unsigned int)(pbus_address >> 6)); -+ if (ret < 0) { -+ dev_err(dev, "%s fail. (ret=%d)\n", __func__, ret); -+ return INVALID_DATA; -+ } -+ pbus_data_low = __mdiobus_read(ebus, pbus_id, -+ (unsigned int)((pbus_address >> 2) & 0xf)); -+ pbus_data_high = __mdiobus_read(ebus, pbus_id, 0x10); -+ pbus_data = (pbus_data_high << 16) + pbus_data_low; -+ return pbus_data; -+} -+ -+static int airoha_pbus_write(struct mii_bus *ebus, int pbus_id, -+ unsigned long pbus_address, unsigned long pbus_data) -+{ -+ int ret = 0; -+ -+ airoha_mdio_lock(ebus); -+ ret = __airoha_pbus_write(ebus, pbus_id, pbus_address, pbus_data); -+ airoha_mdio_unlock(ebus); -+ -+ return ret; -+} -+ -+static unsigned long airoha_pbus_read(struct mii_bus *ebus, int pbus_id, -+ unsigned long pbus_address) -+{ -+ unsigned long pbus_data; -+ -+ airoha_mdio_lock(ebus); -+ pbus_data = __airoha_pbus_read(ebus, pbus_id, pbus_address); -+ airoha_mdio_unlock(ebus); -+ -+ return pbus_data; -+} -+ -+/* Airoha Token Ring Write function */ -+static int airoha_tr_reg_write(struct phy_device *phydev, -+ unsigned long tr_address, unsigned long tr_data) -+{ -+ int ret = 0; -+ int phy_addr = phydev_phy_addr(phydev); -+ struct mii_bus *ebus = phydev_mdio_bus(phydev); -+ -+ airoha_mdio_lock(ebus); -+ ret = __mdiobus_write(ebus, phy_addr, 0x1F, 0x52b5); /* page select */ -+ ret = __mdiobus_write(ebus, phy_addr, 0x11, -+ (unsigned int)(tr_data & 0xffff)); -+ ret = __mdiobus_write(ebus, phy_addr, 0x12, -+ (unsigned int)(tr_data >> 16)); -+ ret = __mdiobus_write(ebus, phy_addr, 0x10, -+ (unsigned int)(tr_address | TrReg_WR)); -+ ret = __mdiobus_write(ebus, phy_addr, 0x1F, 0x0); /* page resetore */ -+ airoha_mdio_unlock(ebus); -+ -+ return ret; -+} -+ -+#ifdef AIR_LED_SUPPORT -+static int airoha_led_set_usr_def(struct phy_device *phydev, u8 entity, -+ int polar, u16 on_evt, u16 blk_evt) -+{ -+ int ret = 0; -+ int phy_addr = phydev_phy_addr(phydev); -+ struct mii_bus *mbus = phydev_mdio_bus(phydev); -+ -+ if (polar == AIR_ACTIVE_HIGH) -+ on_evt |= LED_ON_POL; -+ else -+ on_evt &= ~LED_ON_POL; -+ -+ ret = airoha_cl45_write(mbus, phy_addr, 0x1f, -+ LED_ON_CTRL(entity), on_evt | LED_ON_EN); -+ if (ret < 0) -+ return ret; -+ -+ ret = airoha_cl45_write(mbus, phy_addr, 0x1f, -+ LED_BLK_CTRL(entity), blk_evt); -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+static int airoha_led_set_mode(struct phy_device *phydev, u8 mode) -+{ -+ u16 cl45_data; -+ int err = 0; -+ int phy_addr = phydev_phy_addr(phydev); -+ struct mii_bus *mbus = phydev_mdio_bus(phydev); -+ -+ err = airoha_cl45_read(mbus, phy_addr, 0x1f, LED_BCR, &cl45_data); -+ if (err < 0) -+ return err; -+ -+ switch (mode) { -+ case AIR_LED_MODE_DISABLE: -+ cl45_data &= ~LED_BCR_EXT_CTRL; -+ cl45_data &= ~LED_BCR_MODE_MASK; -+ cl45_data |= LED_BCR_MODE_DISABLE; -+ break; -+ case AIR_LED_MODE_USER_DEFINE: -+ cl45_data |= LED_BCR_EXT_CTRL; -+ cl45_data |= LED_BCR_CLK_EN; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ err = airoha_cl45_write(mbus, phy_addr, 0x1f, LED_BCR, cl45_data); -+ if (err < 0) -+ return err; -+ return 0; -+} -+ -+static int airoha_led_set_state(struct phy_device *phydev, u8 entity, u8 state) -+{ -+ u16 cl45_data; -+ int err; -+ int phy_addr = phydev_phy_addr(phydev); -+ struct mii_bus *mbus = phydev_mdio_bus(phydev); -+ -+ err = airoha_cl45_read(mbus, phy_addr, 0x1f, -+ LED_ON_CTRL(entity), &cl45_data); -+ if (err < 0) -+ return err; -+ if (state == LED_ENABLE) -+ cl45_data |= LED_ON_EN; -+ else -+ cl45_data &= ~LED_ON_EN; -+ -+ err = airoha_cl45_write(mbus, phy_addr, 0x1f, -+ LED_ON_CTRL(entity), cl45_data); -+ if (err < 0) -+ return err; -+ return 0; -+} -+ -+static int en8801s_led_init(struct phy_device *phydev) -+{ -+ -+ unsigned long led_gpio = 0, reg_value = 0; -+ int ret = 0, led_id; -+ struct mii_bus *mbus = phydev_mdio_bus(phydev); -+ int gpio_led_rg[3] = {0x1870, 0x1874, 0x1878}; -+ u16 cl45_data = led_dur; -+ struct device *dev = phydev_dev(phydev); -+ int phy_addr = phydev_phy_addr(phydev); -+ int pbus_addr = phydev_pbus_addr(phydev); -+ -+ ret = airoha_cl45_write(mbus, phy_addr, 0x1f, LED_BLK_DUR, cl45_data); -+ if (ret < 0) -+ return ret; -+ cl45_data >>= 1; -+ ret = airoha_cl45_write(mbus, phy_addr, 0x1f, LED_ON_DUR, cl45_data); -+ if (ret < 0) -+ return ret; -+ ret = airoha_led_set_mode(phydev, AIR_LED_MODE_USER_DEFINE); -+ if (ret != 0) { -+ dev_err(dev, "LED fail to set mode, ret %d !\n", ret); -+ return ret; -+ } -+ for (led_id = 0; led_id < EN8801S_LED_COUNT; led_id++) { -+ reg_value = 0; -+ ret = airoha_led_set_state(phydev, led_id, led_cfg[led_id].en); -+ if (ret != 0) { -+ dev_err(dev, "LED fail to set state, ret %d !\n", ret); -+ return ret; -+ } -+ if (led_cfg[led_id].en == LED_ENABLE) { -+ if ((led_cfg[led_id].gpio < 0) -+ || led_cfg[led_id].gpio > 9) { -+ dev_err(dev, "GPIO%d is out of range!! GPIO number is 0~9.\n", -+ led_cfg[led_id].gpio); -+ return -EIO; -+ } -+ led_gpio |= BIT(led_cfg[led_id].gpio); -+ reg_value = airoha_pbus_read(mbus, pbus_addr, -+ gpio_led_rg[led_cfg[led_id].gpio / 4]); -+ LED_SET_GPIO_SEL(led_cfg[led_id].gpio, -+ led_id, reg_value); -+ dev_dbg(dev, "[Airoha] gpio%d, reg_value 0x%lx\n", -+ led_cfg[led_id].gpio, reg_value); -+ ret = airoha_pbus_write(mbus, pbus_addr, -+ gpio_led_rg[led_cfg[led_id].gpio / 4], -+ reg_value); -+ if (ret < 0) -+ return ret; -+ ret = airoha_led_set_usr_def(phydev, led_id, -+ led_cfg[led_id].pol, -+ led_cfg[led_id].on_cfg, -+ led_cfg[led_id].blk_cfg); -+ if (ret != 0) { -+ dev_err(dev, "LED fail to set usr def, ret %d !\n", -+ ret); -+ return ret; -+ } -+ } -+ } -+ reg_value = (airoha_pbus_read(mbus, pbus_addr, 0x1880) & ~led_gpio); -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x1880, reg_value); -+ if (ret < 0) -+ return ret; -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x186c, led_gpio); -+ if (ret < 0) -+ return ret; -+ dev_info(dev, "LED initialize OK !\n"); -+ return 0; -+} -+#endif -+static int en8801s_phy_process(struct phy_device *phydev) -+{ -+ struct mii_bus *mbus = phydev_mdio_bus(phydev); -+ unsigned long reg_value = 0; -+ int ret = 0; -+ int pbus_addr = phydev_pbus_addr(phydev); -+ -+ reg_value = airoha_pbus_read(mbus, pbus_addr, 0x19e0); -+ reg_value |= BIT(0); -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x19e0, reg_value); -+ if (ret < 0) -+ return ret; -+ reg_value = airoha_pbus_read(mbus, pbus_addr, 0x19e0); -+ reg_value &= ~BIT(0); -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x19e0, reg_value); -+ if (ret < 0) -+ return ret; -+ return ret; -+} -+ -+static int en8801s_phase1_init(struct phy_device *phydev) -+{ -+ unsigned long pbus_data; -+ int pbus_addr = EN8801S_PBUS_DEFAULT_ADDR; -+ u16 reg_value; -+ int retry, ret = 0; -+ struct mii_bus *mbus = phydev_mdio_bus(phydev); -+ struct device *dev = phydev_dev(phydev); -+ struct en8801s_priv *priv = phydev->priv; -+ -+ priv->count = 1; -+ msleep(1000); -+ -+ retry = MAX_OUI_CHECK; -+ while (1) { -+ pbus_data = airoha_pbus_read(mbus, pbus_addr, -+ EN8801S_RG_ETHER_PHY_OUI); /* PHY OUI */ -+ if (pbus_data == EN8801S_PBUS_OUI) { -+ dev_info(dev, "PBUS addr 0x%x: Start initialized.\n", -+ pbus_addr); -+ break; -+ } -+ pbus_addr = phydev_pbus_addr(phydev); -+ if (0 == --retry) { -+ dev_err(dev, "Probe fail !\n"); -+ return 0; -+ } -+ } -+ -+ ret = airoha_pbus_write(mbus, pbus_addr, EN8801S_RG_BUCK_CTL, 0x03); -+ if (ret < 0) -+ return ret; -+ pbus_data = airoha_pbus_read(mbus, pbus_addr, EN8801S_RG_PROD_VER); -+ priv->pro_version = pbus_data & 0xf; -+ dev_info(dev, "EN8801S Procduct Version :E%d\n", priv->pro_version); -+ mdelay(10); -+ pbus_data = (airoha_pbus_read(mbus, pbus_addr, EN8801S_RG_LTR_CTL) -+ & 0xfffffffc) | BIT(2); -+ ret = airoha_pbus_write(mbus, pbus_addr, -+ EN8801S_RG_LTR_CTL, pbus_data); -+ if (ret < 0) -+ return ret; -+ mdelay(500); -+ pbus_data = (pbus_data & ~BIT(2)) | -+ EN8801S_RX_POLARITY_NORMAL | -+ EN8801S_TX_POLARITY_NORMAL; -+ ret = airoha_pbus_write(mbus, pbus_addr, -+ EN8801S_RG_LTR_CTL, pbus_data); -+ if (ret < 0) -+ return ret; -+ mdelay(500); -+ if (priv->pro_version == 4) { -+ pbus_data = airoha_pbus_read(mbus, pbus_addr, 0x1900); -+ dev_dbg(dev, "Before 0x1900 0x%lx\n", pbus_data); -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x1900, 0x101009f); -+ if (ret < 0) -+ return ret; -+ pbus_data = airoha_pbus_read(mbus, pbus_addr, 0x1900); -+ dev_dbg(dev, "After 0x1900 0x%lx\n", pbus_data); -+ pbus_data = airoha_pbus_read(mbus, pbus_addr, 0x19a8); -+ dev_dbg(dev, "Before 19a8 0x%lx\n", pbus_data); -+ ret = airoha_pbus_write(mbus, pbus_addr, -+ 0x19a8, pbus_data & ~BIT(16)); -+ if (ret < 0) -+ return ret; -+ pbus_data = airoha_pbus_read(mbus, pbus_addr, 0x19a8); -+ dev_dbg(dev, "After 19a8 0x%lx\n", pbus_data); -+ } -+ pbus_data = airoha_pbus_read(mbus, pbus_addr, -+ EN8801S_RG_SMI_ADDR); /* SMI ADDR */ -+ pbus_data = (pbus_data & 0xffff0000) | -+ (unsigned long)(phydev_pbus_addr(phydev) << 8) | -+ (unsigned long)(phydev_phy_addr(phydev)); -+ dev_info(phydev_dev(phydev), "SMI_ADDR=%lx (renew)\n", pbus_data); -+ ret = airoha_pbus_write(mbus, pbus_addr, -+ EN8801S_RG_SMI_ADDR, pbus_data); -+ mdelay(10); -+ -+ retry = MAX_RETRY; -+ while (1) { -+ mdelay(10); -+ reg_value = phy_read(phydev, MII_PHYSID2); -+ if (reg_value == EN8801S_PHY_ID2) -+ break; /* wait GPHY ready */ -+ -+ retry--; -+ if (retry == 0) { -+ dev_err(dev, "Initialize fail !\n"); -+ return 0; -+ } -+ } -+ /* Software Reset PHY */ -+ reg_value = phy_read(phydev, MII_BMCR); -+ reg_value |= BMCR_RESET; -+ ret = phy_write(phydev, MII_BMCR, reg_value); -+ if (ret < 0) -+ return ret; -+ retry = MAX_RETRY; -+ do { -+ mdelay(10); -+ reg_value = phy_read(phydev, MII_BMCR); -+ retry--; -+ if (retry == 0) { -+ dev_err(dev, "Reset fail !\n"); -+ return 0; -+ } -+ } while (reg_value & BMCR_RESET); -+ -+ phydev->dev_flags = PHY_STATE_INIT; -+ -+ dev_info(dev, "Phase1 initialize OK ! (%s)\n", EN8801S_DRIVER_VERSION); -+ if (priv->pro_version == 4) { -+ ret = en8801s_phase2_init(phydev); -+ if (ret != 0) { -+ dev_info(dev, "en8801_phase2_init failed\n"); -+ phydev->dev_flags = PHY_STATE_FAIL; -+ return 0; -+ } -+ phydev->dev_flags = PHY_STATE_PROCESS; -+ } -+ -+ return 0; -+} -+ -+static int en8801s_phase2_init(struct phy_device *phydev) -+{ -+ union gephy_all_REG_LpiReg1Ch GPHY_RG_LPI_1C; -+ union gephy_all_REG_dev1Eh_reg324h GPHY_RG_1E_324; -+ union gephy_all_REG_dev1Eh_reg012h GPHY_RG_1E_012; -+ union gephy_all_REG_dev1Eh_reg017h GPHY_RG_1E_017; -+ unsigned long pbus_data; -+ int phy_addr = phydev_phy_addr(phydev); -+ int pbus_addr = phydev_pbus_addr(phydev); -+ u16 cl45_value; -+ int retry, ret = 0; -+ struct mii_bus *mbus = phydev_mdio_bus(phydev); -+ struct device *dev = phydev_dev(phydev); -+ struct en8801s_priv *priv = phydev->priv; -+ -+ pbus_data = airoha_pbus_read(mbus, pbus_addr, 0x1690); -+ pbus_data |= BIT(31); -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x1690, pbus_data); -+ if (ret < 0) -+ return ret; -+ -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x0600, 0x0c000c00); -+ if (ret < 0) -+ return ret; -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x10, 0xD801); -+ if (ret < 0) -+ return ret; -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x0, 0x9140); -+ if (ret < 0) -+ return ret; -+ -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x0A14, 0x0003); -+ if (ret < 0) -+ return ret; -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x0600, 0x0c000c00); -+ if (ret < 0) -+ return ret; -+ /* Set FCM control */ -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x1404, 0x004b); -+ if (ret < 0) -+ return ret; -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x140c, 0x0007); -+ if (ret < 0) -+ return ret; -+ -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x142c, 0x05050505); -+ if (ret < 0) -+ return ret; -+ pbus_data = airoha_pbus_read(mbus, pbus_addr, 0x1440); -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x1440, pbus_data & ~BIT(11)); -+ if (ret < 0) -+ return ret; -+ -+ pbus_data = airoha_pbus_read(mbus, pbus_addr, 0x1408); -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x1408, pbus_data | BIT(5)); -+ if (ret < 0) -+ return ret; -+ -+ /* Set GPHY Perfomance*/ -+ /* Token Ring */ -+ ret = airoha_tr_reg_write(phydev, RgAddr_R1000DEC_15h, 0x0055A0); -+ if (ret < 0) -+ return ret; -+ ret = airoha_tr_reg_write(phydev, RgAddr_R1000DEC_17h, 0x07FF3F); -+ if (ret < 0) -+ return ret; -+ ret = airoha_tr_reg_write(phydev, RgAddr_PMA_00h, 0x00001E); -+ if (ret < 0) -+ return ret; -+ ret = airoha_tr_reg_write(phydev, RgAddr_PMA_01h, 0x6FB90A); -+ if (ret < 0) -+ return ret; -+ ret = airoha_tr_reg_write(phydev, RgAddr_PMA_17h, 0x060671); -+ if (ret < 0) -+ return ret; -+ ret = airoha_tr_reg_write(phydev, RgAddr_PMA_18h, 0x0E2F00); -+ if (ret < 0) -+ return ret; -+ ret = airoha_tr_reg_write(phydev, RgAddr_TR_26h, 0x444444); -+ if (ret < 0) -+ return ret; -+ ret = airoha_tr_reg_write(phydev, RgAddr_DSPF_03h, 0x000000); -+ if (ret < 0) -+ return ret; -+ ret = airoha_tr_reg_write(phydev, RgAddr_DSPF_06h, 0x2EBAEF); -+ if (ret < 0) -+ return ret; -+ ret = airoha_tr_reg_write(phydev, RgAddr_DSPF_08h, 0x00000B); -+ if (ret < 0) -+ return ret; -+ ret = airoha_tr_reg_write(phydev, RgAddr_DSPF_0Ch, 0x00504D); -+ if (ret < 0) -+ return ret; -+ ret = airoha_tr_reg_write(phydev, RgAddr_DSPF_0Dh, 0x02314F); -+ if (ret < 0) -+ return ret; -+ ret = airoha_tr_reg_write(phydev, RgAddr_DSPF_0Fh, 0x003028); -+ if (ret < 0) -+ return ret; -+ ret = airoha_tr_reg_write(phydev, RgAddr_DSPF_10h, 0x005010); -+ if (ret < 0) -+ return ret; -+ ret = airoha_tr_reg_write(phydev, RgAddr_DSPF_11h, 0x040001); -+ if (ret < 0) -+ return ret; -+ ret = airoha_tr_reg_write(phydev, RgAddr_DSPF_13h, 0x018670); -+ if (ret < 0) -+ return ret; -+ ret = airoha_tr_reg_write(phydev, RgAddr_DSPF_14h, 0x00024A); -+ if (ret < 0) -+ return ret; -+ ret = airoha_tr_reg_write(phydev, RgAddr_DSPF_1Bh, 0x000072); -+ if (ret < 0) -+ return ret; -+ ret = airoha_tr_reg_write(phydev, RgAddr_DSPF_1Ch, 0x003210); -+ if (ret < 0) -+ return ret; -+ -+ /* CL22 & CL45 */ -+ ret = phy_write(phydev, 0x1f, 0x03); -+ if (ret < 0) -+ return ret; -+ GPHY_RG_LPI_1C.DATA = phy_read(phydev, RgAddr_LPI_1Ch); -+ GPHY_RG_LPI_1C.DataBitField.smi_deton_th = 0x0C; -+ ret = phy_write(phydev, RgAddr_LPI_1Ch, GPHY_RG_LPI_1C.DATA); -+ if (ret < 0) -+ return ret; -+ ret = phy_write(phydev, RgAddr_LPI_1Ch, 0xC92); -+ if (ret < 0) -+ return ret; -+ ret = phy_write(phydev, RgAddr_AUXILIARY_1Dh, 0x1); -+ if (ret < 0) -+ return ret; -+ ret = phy_write(phydev, 0x1f, 0x0); -+ if (ret < 0) -+ return ret; -+ ret = airoha_cl45_write(mbus, phy_addr, 0x1E, 0x120, 0x8014); -+ if (ret < 0) -+ return ret; -+ ret = airoha_cl45_write(mbus, phy_addr, 0x1E, 0x122, 0xffff); -+ if (ret < 0) -+ return ret; -+ ret = airoha_cl45_write(mbus, phy_addr, 0x1E, 0x123, 0xffff); -+ if (ret < 0) -+ return ret; -+ ret = airoha_cl45_write(mbus, phy_addr, 0x1E, 0x144, 0x0200); -+ if (ret < 0) -+ return ret; -+ ret = airoha_cl45_write(mbus, phy_addr, 0x1E, 0x14A, 0xEE20); -+ if (ret < 0) -+ return ret; -+ ret = airoha_cl45_write(mbus, phy_addr, 0x1E, 0x189, 0x0110); -+ if (ret < 0) -+ return ret; -+ ret = airoha_cl45_write(mbus, phy_addr, 0x1E, 0x19B, 0x0111); -+ if (ret < 0) -+ return ret; -+ ret = airoha_cl45_write(mbus, phy_addr, 0x1E, 0x234, 0x0181); -+ if (ret < 0) -+ return ret; -+ ret = airoha_cl45_write(mbus, phy_addr, 0x1E, 0x238, 0x0120); -+ if (ret < 0) -+ return ret; -+ ret = airoha_cl45_write(mbus, phy_addr, 0x1E, 0x239, 0x0117); -+ if (ret < 0) -+ return ret; -+ ret = airoha_cl45_write(mbus, phy_addr, 0x1E, 0x268, 0x07F4); -+ if (ret < 0) -+ return ret; -+ ret = airoha_cl45_write(mbus, phy_addr, 0x1E, 0x2D1, 0x0733); -+ if (ret < 0) -+ return ret; -+ ret = airoha_cl45_write(mbus, phy_addr, 0x1E, 0x323, 0x0011); -+ if (ret < 0) -+ return ret; -+ ret = airoha_cl45_write(mbus, phy_addr, 0x1E, 0x324, 0x013F); -+ if (ret < 0) -+ return ret; -+ ret = airoha_cl45_write(mbus, phy_addr, 0x1E, 0x326, 0x0037); -+ if (ret < 0) -+ return ret; -+ -+ ret = airoha_cl45_read(mbus, phy_addr, 0x1E, 0x324, &cl45_value); -+ if (ret < 0) -+ return ret; -+ GPHY_RG_1E_324.DATA = cl45_value; -+ GPHY_RG_1E_324.DataBitField.smi_det_deglitch_off = 0; -+ ret = airoha_cl45_write(mbus, phy_addr, 0x1E, 0x324, -+ GPHY_RG_1E_324.DATA); -+ if (ret < 0) -+ return ret; -+ ret = airoha_cl45_write(mbus, phy_addr, 0x1E, 0x19E, 0xC2); -+ if (ret < 0) -+ return ret; -+ ret = airoha_cl45_write(mbus, phy_addr, 0x1E, 0x013, 0x0); -+ if (ret < 0) -+ return ret; -+ -+ /* EFUSE */ -+ airoha_pbus_write(mbus, pbus_addr, 0x1C08, 0x40000040); -+ retry = MAX_RETRY; -+ while (retry != 0) { -+ mdelay(1); -+ pbus_data = airoha_pbus_read(mbus, pbus_addr, 0x1C08); -+ if ((pbus_data & BIT(30)) == 0) -+ break; -+ -+ retry--; -+ } -+ pbus_data = airoha_pbus_read(mbus, pbus_addr, 0x1C38); /* RAW#2 */ -+ ret = airoha_cl45_read(mbus, phy_addr, 0x1E, 0x12, &cl45_value); -+ if (ret < 0) -+ return ret; -+ GPHY_RG_1E_012.DATA = cl45_value; -+ GPHY_RG_1E_012.DataBitField.da_tx_i2mpb_a_tbt = -+ (u16)(pbus_data & 0x03f); -+ ret = airoha_cl45_write(mbus, phy_addr, 0x1E, 0x12, -+ GPHY_RG_1E_012.DATA); -+ if (ret < 0) -+ return ret; -+ ret = airoha_cl45_read(mbus, phy_addr, 0x1E, 0x17, &cl45_value); -+ if (ret < 0) -+ return ret; -+ GPHY_RG_1E_017.DATA = cl45_value; -+ GPHY_RG_1E_017.DataBitField.da_tx_i2mpb_b_tbt = -+ (u16)((pbus_data >> 8) & 0x03f); -+ ret = airoha_cl45_write(mbus, phy_addr, 0x1E, 0x17, -+ GPHY_RG_1E_017.DATA); -+ if (ret < 0) -+ return ret; -+ -+ airoha_pbus_write(mbus, pbus_addr, 0x1C08, 0x40400040); -+ retry = MAX_RETRY; -+ while (retry != 0) { -+ mdelay(1); -+ pbus_data = airoha_pbus_read(mbus, pbus_addr, 0x1C08); -+ if ((pbus_data & BIT(30)) == 0) -+ break; -+ -+ retry--; -+ } -+ pbus_data = airoha_pbus_read(mbus, pbus_addr, 0x1C30); /* RAW#16 */ -+ GPHY_RG_1E_324.DataBitField.smi_det_deglitch_off = -+ (u16)((pbus_data >> 12) & 0x01); -+ ret = airoha_cl45_write(mbus, phy_addr, 0x1E, 0x324, -+ GPHY_RG_1E_324.DATA); -+ if (ret < 0) -+ return ret; -+#ifdef AIR_LED_SUPPORT -+ ret = en8801s_led_init(phydev); -+ if (ret != 0) -+ dev_err(dev, "en8801s_led_init fail (ret:%d) !\n", ret); -+#endif -+ -+ ret = airoha_cl45_read(mbus, phy_addr, MDIO_MMD_AN, -+ MDIO_AN_EEE_ADV, &cl45_value); -+ if (ret < 0) -+ return ret; -+ if (cl45_value == 0) { -+ pbus_data = airoha_pbus_read(mbus, pbus_addr, 0x1960); -+ if (0xA == ((pbus_data & 0x07c00000) >> 22)) { -+ pbus_data = (pbus_data & 0xf83fffff) | (0xC << 22); -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x1960, -+ pbus_data); -+ if (ret < 0) -+ return ret; -+ mdelay(10); -+ pbus_data = (pbus_data & 0xf83fffff) | (0xE << 22); -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x1960, -+ pbus_data); -+ if (ret < 0) -+ return ret; -+ mdelay(10); -+ } -+ } else { -+ pbus_data = airoha_pbus_read(mbus, pbus_addr, 0x1960); -+ if (0xE == ((pbus_data & 0x07c00000) >> 22)) { -+ pbus_data = (pbus_data & 0xf83fffff) | (0xC << 22); -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x1960, -+ pbus_data); -+ if (ret < 0) -+ return ret; -+ mdelay(10); -+ pbus_data = (pbus_data & 0xf83fffff) | (0xA << 22); -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x1960, -+ pbus_data); -+ if (ret < 0) -+ return ret; -+ mdelay(10); -+ } -+ } -+ -+ priv->first_init = false; -+ dev_info(phydev_dev(phydev), "Phase2 initialize OK !\n"); -+ return 0; -+} -+ -+static int en8801s_read_status(struct phy_device *phydev) -+{ -+ int ret = 0, preSpeed = phydev->speed; -+ struct mii_bus *mbus = phydev_mdio_bus(phydev); -+ u32 reg_value; -+ struct device *dev = phydev_dev(phydev); -+ int pbus_addr = phydev_pbus_addr(phydev); -+ struct en8801s_priv *priv = phydev->priv; -+ -+ ret = genphy_read_status(phydev); -+ if (phydev->link == LINK_DOWN) -+ preSpeed = phydev->speed = 0; -+ -+ if (phydev->dev_flags == PHY_STATE_PROCESS) { -+ en8801s_phy_process(phydev); -+ phydev->dev_flags = PHY_STATE_DONE; -+ } -+ -+ if (phydev->dev_flags == PHY_STATE_INIT) { -+ dev_dbg(dev, "phydev->link %d, count %d\n", -+ phydev->link, priv->count); -+ if ((phydev->link) || (priv->count == 5)) { -+ if (priv->pro_version != 4) { -+ ret = en8801s_phase2_init(phydev); -+ if (ret != 0) { -+ dev_info(dev, "en8801_phase2_init failed\n"); -+ phydev->dev_flags = PHY_STATE_FAIL; -+ return 0; -+ } -+ phydev->dev_flags = PHY_STATE_PROCESS; -+ } -+ } -+ priv->count++; -+ } -+ -+ if ((preSpeed != phydev->speed) && (phydev->link == LINK_UP)) { -+ preSpeed = phydev->speed; -+ -+ if (preSpeed == SPEED_10) { -+ reg_value = airoha_pbus_read(mbus, pbus_addr, 0x1694); -+ reg_value |= BIT(31); -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x1694, -+ reg_value); -+ if (ret < 0) -+ return ret; -+ phydev->dev_flags = PHY_STATE_PROCESS; -+ } else { -+ reg_value = airoha_pbus_read(mbus, pbus_addr, 0x1694); -+ reg_value &= ~BIT(31); -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x1694, -+ reg_value); -+ if (ret < 0) -+ return ret; -+ phydev->dev_flags = PHY_STATE_PROCESS; -+ } -+ -+ airoha_pbus_write(mbus, pbus_addr, 0x0600, -+ 0x0c000c00); -+ if (preSpeed == SPEED_1000) { -+ dev_dbg(dev, "SPEED_1000\n"); -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x10, -+ 0xD801); -+ if (ret < 0) -+ return ret; -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x0, -+ 0x9140); -+ if (ret < 0) -+ return ret; -+ -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x0A14, -+ 0x0003); -+ if (ret < 0) -+ return ret; -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x0600, -+ 0x0c000c00); -+ if (ret < 0) -+ return ret; -+ mdelay(2); /* delay 2 ms */ -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x1404, -+ 0x004b); -+ if (ret < 0) -+ return ret; -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x140c, -+ 0x0007); -+ if (ret < 0) -+ return ret; -+ } else if (preSpeed == SPEED_100) { -+ dev_dbg(dev, "SPEED_100\n"); -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x10, -+ 0xD401); -+ if (ret < 0) -+ return ret; -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x0, -+ 0x9140); -+ if (ret < 0) -+ return ret; -+ -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x0A14, -+ 0x0007); -+ if (ret < 0) -+ return ret; -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x0600, -+ 0x0c11); -+ if (ret < 0) -+ return ret; -+ mdelay(2); /* delay 2 ms */ -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x1404, -+ 0x0027); -+ if (ret < 0) -+ return ret; -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x140c, -+ 0x0007); -+ if (ret < 0) -+ return ret; -+ } else if (preSpeed == SPEED_10) { -+ dev_dbg(dev, "SPEED_10\n"); -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x10, -+ 0xD001); -+ if (ret < 0) -+ return ret; -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x0, -+ 0x9140); -+ if (ret < 0) -+ return ret; -+ -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x0A14, -+ 0x000b); -+ if (ret < 0) -+ return ret; -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x0600, -+ 0x0c11); -+ if (ret < 0) -+ return ret; -+ mdelay(2); /* delay 2 ms */ -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x1404, -+ 0x0027); -+ if (ret < 0) -+ return ret; -+ ret = airoha_pbus_write(mbus, pbus_addr, 0x140c, -+ 0x0007); -+ if (ret < 0) -+ return ret; -+ } -+ } -+ return ret; -+} -+ -+static int en8801s_probe(struct phy_device *phydev) -+{ -+ struct en8801s_priv *priv; -+ unsigned long phy_addr = phydev_phy_addr(phydev); -+ struct mdio_device *mdiodev = &phydev->mdio; -+ -+ priv = kzalloc(sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->count = 0; -+ priv->first_init = true; -+ -+ if (mdiodev->reset_gpio) { -+ dev_dbg(phydev_dev(phydev), -+ "Assert PHY %lx HWRST until phy_init_hw\n", -+ phy_addr); -+ phy_device_reset(phydev, 1); -+ } -+ -+ phydev->priv = priv; -+ -+ return 0; -+} -+ -+static int airoha_mmd_read(struct phy_device *phydev, -+ int devad, u16 reg) -+{ -+ struct mii_bus *mbus = phydev_mdio_bus(phydev); -+ int phy_addr = phydev_phy_addr(phydev); -+ int ret = 0; -+ u16 cl45_value; -+ -+ ret = __airoha_cl45_read(mbus, phy_addr, devad, reg, &cl45_value); -+ if (ret < 0) -+ return ret; -+ -+ return cl45_value; -+} -+ -+static int airoha_mmd_write(struct phy_device *phydev, -+ int devad, u16 reg, u16 val) -+{ -+ struct mii_bus *mbus = phydev_mdio_bus(phydev); -+ int phy_addr = phydev_phy_addr(phydev); -+ int pbus_addr = phydev_pbus_addr(phydev); -+ unsigned long pbus_data; -+ int ret = 0; -+ -+ if (MDIO_MMD_AN == devad && MDIO_AN_EEE_ADV == reg) { -+ if (val == 0) { -+ pbus_data = __airoha_pbus_read(mbus, pbus_addr, 0x1960); -+ if (0xA == ((pbus_data & 0x07c00000) >> 22)) { -+ pbus_data = (pbus_data & 0xf83fffff) | -+ (0xC << 22); -+ __airoha_pbus_write(mbus, pbus_addr, 0x1960, -+ pbus_data); -+ mdelay(10); -+ pbus_data = (pbus_data & 0xf83fffff) | -+ (0xE << 22); -+ __airoha_pbus_write(mbus, pbus_addr, 0x1960, -+ pbus_data); -+ mdelay(10); -+ } -+ } else { -+ pbus_data = __airoha_pbus_read(mbus, pbus_addr, 0x1960); -+ if (0xE == ((pbus_data & 0x07c00000) >> 22)) { -+ pbus_data = (pbus_data & 0xf83fffff) | -+ (0xC << 22); -+ __airoha_pbus_write(mbus, pbus_addr, 0x1960, -+ pbus_data); -+ mdelay(10); -+ pbus_data = (pbus_data & 0xf83fffff) | -+ (0xA << 22); -+ __airoha_pbus_write(mbus, pbus_addr, 0x1960, -+ pbus_data); -+ mdelay(10); -+ } -+ } -+ } -+ ret = __airoha_cl45_write(mbus, phy_addr, devad, reg, val); -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+static struct phy_driver Airoha_driver[] = { -+ { -+ .phy_id = EN8801SC_PHY_ID, -+ .name = "Airoha EN8801SC", -+ .phy_id_mask = 0x0ffffff0, -+ .features = PHY_GBIT_FEATURES, -+ .probe = en8801s_probe, -+ .config_init = en8801s_phase1_init, -+ .config_aneg = genphy_config_aneg, -+ .read_status = en8801s_read_status, -+ .suspend = genphy_suspend, -+ .resume = genphy_resume, -+ .read_mmd = airoha_mmd_read, -+ .write_mmd = airoha_mmd_write, -+ } -+}; -+ -+module_phy_driver(Airoha_driver); -+ -+static struct mdio_device_id __maybe_unused Airoha_tbl[] = { -+ { EN8801SC_PHY_ID, 0x0ffffff0 }, -+ { } -+}; -+ -+MODULE_DEVICE_TABLE(mdio, Airoha_tbl); -diff --git a/drivers/net/phy/en8801sc.h b/drivers/net/phy/en8801sc.h -new file mode 100644 -index 000000000000..d1e268c9aa3a ---- /dev/null -+++ b/drivers/net/phy/en8801sc.h -@@ -0,0 +1,250 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* FILE NAME: en8801sc.h -+ * PURPOSE: -+ * Define EN8801SC driver function -+ * -+ * NOTES: -+ * -+ */ -+ -+#ifndef __EN8801SC_H -+#define __EN8801SC_H -+ -+/* NAMING DECLARATIONS -+ */ -+#define EN8801S_DRIVER_VERSION "1.1.8_Generic" -+#define EN8801S_PBUS_DEFAULT_ADDR 0x1e -+#define EN8801S_PHY_DEFAULT_ADDR 0x1d -+#define EN8801S_RG_ETHER_PHY_OUI 0x19a4 -+#define EN8801S_RG_SMI_ADDR 0x19a8 -+#define EN8801S_RG_BUCK_CTL 0x1a20 -+#define EN8801S_RG_LTR_CTL 0x0cf8 -+#define EN8801S_RG_PROD_VER 0x18e0 -+ -+#define EN8801S_PBUS_OUI 0x17a5 -+#define EN8801S_PHY_ID1 0x03a2 -+#define EN8801S_PHY_ID2 0x9461 -+#define EN8801SC_PHY_ID 0x03a29471 -+ -+#define LED_ON_CTRL(i) (0x024 + ((i)*2)) -+#define LED_ON_EN (1 << 15) -+#define LED_ON_POL (1 << 14) -+#define LED_ON_EVT_MASK (0x7f) -+/* LED ON Event Option.B */ -+#define LED_ON_EVT_FORCE (1 << 6) -+#define LED_ON_EVT_LINK_DOWN (1 << 3) -+#define LED_ON_EVT_LINK_10M (1 << 2) -+#define LED_ON_EVT_LINK_100M (1 << 1) -+#define LED_ON_EVT_LINK_1000M (1 << 0) -+/* LED ON Event Option.E */ -+ -+#define LED_BLK_CTRL(i) (0x025 + ((i)*2)) -+#define LED_BLK_EVT_MASK (0x3ff) -+/* LED Blinking Event Option.B*/ -+#define LED_BLK_EVT_FORCE (1 << 9) -+#define LED_BLK_EVT_10M_RX_ACT (1 << 5) -+#define LED_BLK_EVT_10M_TX_ACT (1 << 4) -+#define LED_BLK_EVT_100M_RX_ACT (1 << 3) -+#define LED_BLK_EVT_100M_TX_ACT (1 << 2) -+#define LED_BLK_EVT_1000M_RX_ACT (1 << 1) -+#define LED_BLK_EVT_1000M_TX_ACT (1 << 0) -+/* LED Blinking Event Option.E*/ -+#define LED_ENABLE 1 -+#define LED_DISABLE 0 -+ -+#define LINK_UP 1 -+#define LINK_DOWN 0 -+ -+/* -+SFP Sample for verification -+Tx Reverse, Rx Reverse -+*/ -+#define EN8801S_TX_POLARITY_NORMAL 0x0 -+#define EN8801S_TX_POLARITY_REVERSE 0x1 -+ -+#define EN8801S_RX_POLARITY_NORMAL (0x1 << 1) -+#define EN8801S_RX_POLARITY_REVERSE (0x0 << 1) -+ -+/* -+The following led_cfg example is for reference only. -+LED5 1000M/LINK/ACT (GPIO5) <-> BASE_T_LED0, -+LED6 10/100M/LINK/ACT(GPIO9) <-> BASE_T_LED1, -+LED4 100M/LINK/ACT (GPIO8) <-> BASE_T_LED2, -+*/ -+/* User-defined.B */ -+#define BASE_T_LED0_ON_CFG (LED_ON_EVT_LINK_1000M) -+#define BASE_T_LED0_BLK_CFG \ -+ (LED_BLK_EVT_1000M_TX_ACT | \ -+ LED_BLK_EVT_1000M_RX_ACT) -+#define BASE_T_LED1_ON_CFG \ -+ (LED_ON_EVT_LINK_100M | \ -+ LED_ON_EVT_LINK_10M) -+#define BASE_T_LED1_BLK_CFG \ -+ (LED_BLK_EVT_100M_TX_ACT | \ -+ LED_BLK_EVT_100M_RX_ACT | \ -+ LED_BLK_EVT_10M_TX_ACT | \ -+ LED_BLK_EVT_10M_RX_ACT) -+#define BASE_T_LED2_ON_CFG \ -+ (LED_ON_EVT_LINK_100M) -+#define BASE_T_LED2_BLK_CFG \ -+ (LED_BLK_EVT_100M_TX_ACT | \ -+ LED_BLK_EVT_100M_RX_ACT) -+#define BASE_T_LED3_ON_CFG (0x0) -+#define BASE_T_LED3_BLK_CFG (0x0) -+/* User-defined.E */ -+ -+#define EN8801S_LED_COUNT 4 -+ -+#define MAX_RETRY 5 -+#define MAX_OUI_CHECK 2 -+/* CL45 MDIO control */ -+#define MII_MMD_ACC_CTL_REG 0x0d -+#define MII_MMD_ADDR_DATA_REG 0x0e -+#define MMD_OP_MODE_DATA BIT(14) -+ -+#define MAX_TRG_COUNTER 5 -+ -+/* CL22 Reg Support Page Select */ -+#define RgAddr_Reg1Fh 0x1f -+#define CL22_Page_Reg 0x0000 -+#define CL22_Page_ExtReg 0x0001 -+#define CL22_Page_MiscReg 0x0002 -+#define CL22_Page_LpiReg 0x0003 -+#define CL22_Page_tReg 0x02A3 -+#define CL22_Page_TrReg 0x52B5 -+ -+/* CL45 Reg Support DEVID */ -+#define DEVID_03 0x03 -+#define DEVID_07 0x07 -+#define DEVID_1E 0x1E -+#define DEVID_1F 0x1F -+ -+/* TokenRing Reg Access */ -+#define TrReg_PKT_XMT_STA 0x8000 -+#define TrReg_WR 0x8000 -+#define TrReg_RD 0xA000 -+ -+#define RgAddr_LPI_1Ch 0x1c -+#define RgAddr_AUXILIARY_1Dh 0x1d -+#define RgAddr_PMA_00h 0x0f80 -+#define RgAddr_PMA_01h 0x0f82 -+#define RgAddr_PMA_17h 0x0fae -+#define RgAddr_PMA_18h 0x0fb0 -+#define RgAddr_DSPF_03h 0x1686 -+#define RgAddr_DSPF_06h 0x168c -+#define RgAddr_DSPF_08h 0x1690 -+#define RgAddr_DSPF_0Ch 0x1698 -+#define RgAddr_DSPF_0Dh 0x169a -+#define RgAddr_DSPF_0Fh 0x169e -+#define RgAddr_DSPF_10h 0x16a0 -+#define RgAddr_DSPF_11h 0x16a2 -+#define RgAddr_DSPF_13h 0x16a6 -+#define RgAddr_DSPF_14h 0x16a8 -+#define RgAddr_DSPF_1Bh 0x16b6 -+#define RgAddr_DSPF_1Ch 0x16b8 -+#define RgAddr_TR_26h 0x0ecc -+#define RgAddr_R1000DEC_15h 0x03aa -+#define RgAddr_R1000DEC_17h 0x03ae -+ -+#define LED_BCR (0x021) -+#define LED_BCR_EXT_CTRL (1 << 15) -+#define LED_BCR_CLK_EN (1 << 3) -+#define LED_BCR_TIME_TEST (1 << 2) -+#define LED_BCR_MODE_MASK (3) -+#define LED_BCR_MODE_DISABLE (0) -+ -+#define LED_ON_DUR (0x022) -+#define LED_ON_DUR_MASK (0xffff) -+ -+#define LED_BLK_DUR (0x023) -+#define LED_BLK_DUR_MASK (0xffff) -+ -+#define LED_GPIO_SEL_MASK 0x7FFFFFF -+ -+#define UNIT_LED_BLINK_DURATION 1024 -+ -+/* Invalid data */ -+#define INVALID_DATA 0xffffffff -+ -+#define LED_SET_GPIO_SEL(gpio, led, val) \ -+ (val |= (led << (8 * (gpio % 4)))) \ -+ -+#define GET_BIT(val, bit) ((val & BIT(bit)) >> bit) -+/* DATA TYPE DECLARATIONS -+ */ -+struct AIR_BASE_T_LED_CFG_S { -+ u16 en; -+ u16 gpio; -+ u16 pol; -+ u16 on_cfg; -+ u16 blk_cfg; -+}; -+ -+union gephy_all_REG_LpiReg1Ch { -+ struct { -+ /* b[15:00] */ -+ u16 smi_deton_wt : 3; -+ u16 smi_det_mdi_inv : 1; -+ u16 smi_detoff_wt : 3; -+ u16 smi_sigdet_debouncing_en : 1; -+ u16 smi_deton_th : 6; -+ u16 rsv_14 : 2; -+ } DataBitField; -+ u16 DATA; -+}; -+ -+union gephy_all_REG_dev1Eh_reg324h { -+ struct { -+ /* b[15:00] */ -+ u16 rg_smi_detcnt_max : 6; -+ u16 rsv_6 : 2; -+ u16 rg_smi_det_max_en : 1; -+ u16 smi_det_deglitch_off : 1; -+ u16 rsv_10 : 6; -+ } DataBitField; -+ u16 DATA; -+}; -+ -+union gephy_all_REG_dev1Eh_reg012h { -+ struct { -+ /* b[15:00] */ -+ u16 da_tx_i2mpb_a_tbt : 6; -+ u16 rsv_6 : 4; -+ u16 da_tx_i2mpb_a_gbe : 6; -+ } DataBitField; -+ u16 DATA; -+}; -+ -+union gephy_all_REG_dev1Eh_reg017h { -+ struct { -+ /* b[15:00] */ -+ u16 da_tx_i2mpb_b_tbt : 6; -+ u16 rsv_6 : 2; -+ u16 da_tx_i2mpb_b_gbe : 6; -+ u16 rsv_14 : 2; -+ } DataBitField; -+ u16 DATA; -+}; -+ -+enum { -+ AIR_LED_BLK_DUR_32M, -+ AIR_LED_BLK_DUR_64M, -+ AIR_LED_BLK_DUR_128M, -+ AIR_LED_BLK_DUR_256M, -+ AIR_LED_BLK_DUR_512M, -+ AIR_LED_BLK_DUR_1024M, -+ AIR_LED_BLK_DUR_LAST -+}; -+ -+enum { -+ AIR_ACTIVE_LOW, -+ AIR_ACTIVE_HIGH, -+}; -+ -+enum { -+ AIR_LED_MODE_DISABLE, -+ AIR_LED_MODE_USER_DEFINE, -+ AIR_LED_MODE_LAST -+}; -+ -+#endif /* End of __EN8801SC_H */ -diff --git a/drivers/net/phy/ip17xx.c b/drivers/net/phy/ip17xx.c -new file mode 100644 -index 000000000000..c36980339578 ---- /dev/null -+++ b/drivers/net/phy/ip17xx.c -@@ -0,0 +1,1370 @@ -+/* -+ * ip17xx.c: Swconfig configuration for IC+ IP17xx switch family -+ * -+ * Copyright (C) 2008 Patrick Horn -+ * Copyright (C) 2008, 2010 Martin Mares -+ * Copyright (C) 2009 Felix Fietkau -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MAX_VLANS 16 -+#define MAX_PORTS 9 -+#undef DUMP_MII_IO -+ -+typedef struct ip17xx_reg { -+ u16 p; // phy -+ u16 m; // mii -+} reg; -+typedef char bitnum; -+ -+#define NOTSUPPORTED {-1,-1} -+ -+#define REG_SUPP(x) (((x).m != ((u16)-1)) && ((x).p != (u16)-1)) -+ -+struct ip17xx_state; -+ -+/*********** CONSTANTS ***********/ -+struct register_mappings { -+ char *NAME; -+ u16 MODEL_NO; // Compare to bits 4-9 of MII register 0,3. -+ bitnum NUM_PORTS; -+ bitnum CPU_PORT; -+ -+/* The default VLAN for each port. -+ Default: 0x0001 for Ports 0,1,2,3 -+ 0x0002 for Ports 4,5 */ -+ reg VLAN_DEFAULT_TAG_REG[MAX_PORTS]; -+ -+/* These ports are tagged. -+ Default: 0x00 */ -+ reg ADD_TAG_REG; -+ reg REMOVE_TAG_REG; -+ bitnum ADD_TAG_BIT[MAX_PORTS]; -+/* These ports are untagged. -+ Default: 0x00 (i.e. do not alter any VLAN tags...) -+ Maybe set to 0 if user disables VLANs. */ -+ bitnum REMOVE_TAG_BIT[MAX_PORTS]; -+ -+/* Port M and Port N are on the same VLAN. -+ Default: All ports on all VLANs. */ -+// Use register {29, 19+N/2} -+ reg VLAN_LOOKUP_REG; -+// Port 5 uses register {30, 18} but same as odd bits. -+ reg VLAN_LOOKUP_REG_5; // in a different register on IP175C. -+ bitnum VLAN_LOOKUP_EVEN_BIT[MAX_PORTS]; -+ bitnum VLAN_LOOKUP_ODD_BIT[MAX_PORTS]; -+ -+/* This VLAN corresponds to which ports. -+ Default: 0x2f,0x30,0x3f,0x3f... */ -+ reg TAG_VLAN_MASK_REG; -+ bitnum TAG_VLAN_MASK_EVEN_BIT[MAX_PORTS]; -+ bitnum TAG_VLAN_MASK_ODD_BIT[MAX_PORTS]; -+ -+ int RESET_VAL; -+ reg RESET_REG; -+ -+ reg MODE_REG; -+ int MODE_VAL; -+ -+/* General flags */ -+ reg ROUTER_CONTROL_REG; -+ reg VLAN_CONTROL_REG; -+ bitnum TAG_VLAN_BIT; -+ bitnum ROUTER_EN_BIT; -+ bitnum NUMLAN_GROUPS_MAX; -+ bitnum NUMLAN_GROUPS_BIT; -+ -+ reg MII_REGISTER_EN; -+ bitnum MII_REGISTER_EN_BIT; -+ -+ // set to 1 for 178C, 0 for 175C. -+ bitnum SIMPLE_VLAN_REGISTERS; // 175C has two vlans per register but 178C has only one. -+ -+ // Pointers to functions which manipulate hardware state -+ int (*update_state)(struct ip17xx_state *state); -+ int (*set_vlan_mode)(struct ip17xx_state *state); -+ int (*reset)(struct ip17xx_state *state); -+}; -+ -+static int ip175c_update_state(struct ip17xx_state *state); -+static int ip175c_set_vlan_mode(struct ip17xx_state *state); -+static int ip175c_reset(struct ip17xx_state *state); -+ -+static const struct register_mappings IP178C = { -+ .NAME = "IP178C", -+ .MODEL_NO = 0x18, -+ .VLAN_DEFAULT_TAG_REG = { -+ {30,3},{30,4},{30,5},{30,6},{30,7},{30,8}, -+ {30,9},{30,10},{30,11}, -+ }, -+ -+ .ADD_TAG_REG = {30,12}, -+ .ADD_TAG_BIT = {0,1,2,3,4,5,6,7,8}, -+ .REMOVE_TAG_REG = {30,13}, -+ .REMOVE_TAG_BIT = {4,5,6,7,8,9,10,11,12}, -+ -+ .SIMPLE_VLAN_REGISTERS = 1, -+ -+ .VLAN_LOOKUP_REG = {31,0},// +N -+ .VLAN_LOOKUP_REG_5 = NOTSUPPORTED, // not used with SIMPLE_VLAN_REGISTERS -+ .VLAN_LOOKUP_EVEN_BIT = {0,1,2,3,4,5,6,7,8}, -+ .VLAN_LOOKUP_ODD_BIT = {0,1,2,3,4,5,6,7,8}, -+ -+ .TAG_VLAN_MASK_REG = {30,14}, // +N -+ .TAG_VLAN_MASK_EVEN_BIT = {0,1,2,3,4,5,6,7,8}, -+ .TAG_VLAN_MASK_ODD_BIT = {0,1,2,3,4,5,6,7,8}, -+ -+ .RESET_VAL = 0x55AA, -+ .RESET_REG = {30,0}, -+ .MODE_VAL = 0, -+ .MODE_REG = NOTSUPPORTED, -+ -+ .ROUTER_CONTROL_REG = {30,30}, -+ .ROUTER_EN_BIT = 11, -+ .NUMLAN_GROUPS_MAX = 8, -+ .NUMLAN_GROUPS_BIT = 8, // {0-2} -+ -+ .VLAN_CONTROL_REG = {30,13}, -+ .TAG_VLAN_BIT = 3, -+ -+ .CPU_PORT = 8, -+ .NUM_PORTS = 9, -+ -+ .MII_REGISTER_EN = NOTSUPPORTED, -+ -+ .update_state = ip175c_update_state, -+ .set_vlan_mode = ip175c_set_vlan_mode, -+ .reset = ip175c_reset, -+}; -+ -+static const struct register_mappings IP175C = { -+ .NAME = "IP175C", -+ .MODEL_NO = 0x18, -+ .VLAN_DEFAULT_TAG_REG = { -+ {29,24},{29,25},{29,26},{29,27},{29,28},{29,30}, -+ NOTSUPPORTED,NOTSUPPORTED,NOTSUPPORTED -+ }, -+ -+ .ADD_TAG_REG = {29,23}, -+ .REMOVE_TAG_REG = {29,23}, -+ .ADD_TAG_BIT = {11,12,13,14,15,1,-1,-1,-1}, -+ .REMOVE_TAG_BIT = {6,7,8,9,10,0,-1,-1,-1}, -+ -+ .SIMPLE_VLAN_REGISTERS = 0, -+ -+ .VLAN_LOOKUP_REG = {29,19},// +N/2 -+ .VLAN_LOOKUP_REG_5 = {30,18}, -+ .VLAN_LOOKUP_EVEN_BIT = {8,9,10,11,12,15,-1,-1,-1}, -+ .VLAN_LOOKUP_ODD_BIT = {0,1,2,3,4,7,-1,-1,-1}, -+ -+ .TAG_VLAN_MASK_REG = {30,1}, // +N/2 -+ .TAG_VLAN_MASK_EVEN_BIT = {0,1,2,3,4,5,-1,-1,-1}, -+ .TAG_VLAN_MASK_ODD_BIT = {8,9,10,11,12,13,-1,-1,-1}, -+ -+ .RESET_VAL = 0x175C, -+ .RESET_REG = {30,0}, -+ .MODE_VAL = 0x175C, -+ .MODE_REG = {29,31}, -+ -+ .ROUTER_CONTROL_REG = {30,9}, -+ .ROUTER_EN_BIT = 3, -+ .NUMLAN_GROUPS_MAX = 8, -+ .NUMLAN_GROUPS_BIT = 0, // {0-2} -+ -+ .VLAN_CONTROL_REG = {30,9}, -+ .TAG_VLAN_BIT = 7, -+ -+ .NUM_PORTS = 6, -+ .CPU_PORT = 5, -+ -+ .MII_REGISTER_EN = NOTSUPPORTED, -+ -+ .update_state = ip175c_update_state, -+ .set_vlan_mode = ip175c_set_vlan_mode, -+ .reset = ip175c_reset, -+}; -+ -+static const struct register_mappings IP175A = { -+ .NAME = "IP175A", -+ .MODEL_NO = 0x05, -+ .VLAN_DEFAULT_TAG_REG = { -+ {0,24},{0,25},{0,26},{0,27},{0,28},NOTSUPPORTED, -+ NOTSUPPORTED,NOTSUPPORTED,NOTSUPPORTED -+ }, -+ -+ .ADD_TAG_REG = {0,23}, -+ .REMOVE_TAG_REG = {0,23}, -+ .ADD_TAG_BIT = {11,12,13,14,15,-1,-1,-1,-1}, -+ .REMOVE_TAG_BIT = {6,7,8,9,10,-1,-1,-1,-1}, -+ -+ .SIMPLE_VLAN_REGISTERS = 0, -+ -+ // Only programmable via EEPROM -+ .VLAN_LOOKUP_REG = NOTSUPPORTED,// +N/2 -+ .VLAN_LOOKUP_REG_5 = NOTSUPPORTED, -+ .VLAN_LOOKUP_EVEN_BIT = {8,9,10,11,12,-1,-1,-1,-1}, -+ .VLAN_LOOKUP_ODD_BIT = {0,1,2,3,4,-1,-1,-1,-1}, -+ -+ .TAG_VLAN_MASK_REG = NOTSUPPORTED, // +N/2, -+ .TAG_VLAN_MASK_EVEN_BIT = {-1,-1,-1,-1,-1,-1,-1,-1,-1}, -+ .TAG_VLAN_MASK_ODD_BIT = {-1,-1,-1,-1,-1,-1,-1,-1,-1}, -+ -+ .RESET_VAL = -1, -+ .RESET_REG = NOTSUPPORTED, -+ .MODE_VAL = 0, -+ .MODE_REG = NOTSUPPORTED, -+ -+ .ROUTER_CONTROL_REG = NOTSUPPORTED, -+ .VLAN_CONTROL_REG = NOTSUPPORTED, -+ .TAG_VLAN_BIT = -1, -+ .ROUTER_EN_BIT = -1, -+ .NUMLAN_GROUPS_MAX = -1, -+ .NUMLAN_GROUPS_BIT = -1, // {0-2} -+ -+ .NUM_PORTS = 5, -+ .CPU_PORT = 4, -+ -+ .MII_REGISTER_EN = {0, 18}, -+ .MII_REGISTER_EN_BIT = 7, -+ -+ .update_state = ip175c_update_state, -+ .set_vlan_mode = ip175c_set_vlan_mode, -+ .reset = ip175c_reset, -+}; -+ -+ -+static int ip175d_update_state(struct ip17xx_state *state); -+static int ip175d_set_vlan_mode(struct ip17xx_state *state); -+static int ip175d_reset(struct ip17xx_state *state); -+ -+static const struct register_mappings IP175D = { -+ .NAME = "IP175D", -+ .MODEL_NO = 0x18, -+ -+ // The IP175D has a completely different interface, so we leave most -+ // of the registers undefined and switch to different code paths. -+ -+ .VLAN_DEFAULT_TAG_REG = { -+ NOTSUPPORTED,NOTSUPPORTED,NOTSUPPORTED,NOTSUPPORTED, -+ NOTSUPPORTED,NOTSUPPORTED,NOTSUPPORTED,NOTSUPPORTED, -+ }, -+ -+ .ADD_TAG_REG = NOTSUPPORTED, -+ .REMOVE_TAG_REG = NOTSUPPORTED, -+ -+ .SIMPLE_VLAN_REGISTERS = 0, -+ -+ .VLAN_LOOKUP_REG = NOTSUPPORTED, -+ .VLAN_LOOKUP_REG_5 = NOTSUPPORTED, -+ .TAG_VLAN_MASK_REG = NOTSUPPORTED, -+ -+ .RESET_VAL = 0x175D, -+ .RESET_REG = {20,2}, -+ .MODE_REG = NOTSUPPORTED, -+ -+ .ROUTER_CONTROL_REG = NOTSUPPORTED, -+ .ROUTER_EN_BIT = -1, -+ .NUMLAN_GROUPS_BIT = -1, -+ -+ .VLAN_CONTROL_REG = NOTSUPPORTED, -+ .TAG_VLAN_BIT = -1, -+ -+ .NUM_PORTS = 6, -+ .CPU_PORT = 5, -+ -+ .MII_REGISTER_EN = NOTSUPPORTED, -+ -+ .update_state = ip175d_update_state, -+ .set_vlan_mode = ip175d_set_vlan_mode, -+ .reset = ip175d_reset, -+}; -+ -+struct ip17xx_state { -+ struct switch_dev dev; -+ struct mii_bus *mii_bus; -+ bool registered; -+ -+ int router_mode; // ROUTER_EN -+ int vlan_enabled; // TAG_VLAN_EN -+ struct port_state { -+ u16 pvid; -+ unsigned int shareports; -+ } ports[MAX_PORTS]; -+ unsigned int add_tag; -+ unsigned int remove_tag; -+ int num_vlans; -+ struct vlan_state { -+ unsigned int ports; -+ unsigned int tag; // VLAN tag (IP175D only) -+ } vlans[MAX_VLANS]; -+ const struct register_mappings *regs; -+ reg proc_mii; // phy/reg for the low level register access via swconfig -+ -+ char buf[80]; -+}; -+ -+#define get_state(_dev) container_of((_dev), struct ip17xx_state, dev) -+ -+static int ip_phy_read(struct ip17xx_state *state, int port, int reg) -+{ -+ int val = mdiobus_read(state->mii_bus, port, reg); -+ if (val < 0) -+ pr_warn("IP17xx: Unable to get MII register %d,%d: error %d\n", port, reg, -val); -+#ifdef DUMP_MII_IO -+ else -+ pr_debug("IP17xx: Read MII(%d,%d) -> %04x\n", port, reg, val); -+#endif -+ return val; -+} -+ -+static int ip_phy_write(struct ip17xx_state *state, int port, int reg, u16 val) -+{ -+ int err; -+ -+#ifdef DUMP_MII_IO -+ pr_debug("IP17xx: Write MII(%d,%d) <- %04x\n", port, reg, val); -+#endif -+ err = mdiobus_write(state->mii_bus, port, reg, val); -+ if (err < 0) -+ pr_warn("IP17xx: Unable to write MII register %d,%d: error %d\n", port, reg, -err); -+ return err; -+} -+ -+static int ip_phy_write_masked(struct ip17xx_state *state, int port, int reg, unsigned int mask, unsigned int data) -+{ -+ int val = ip_phy_read(state, port, reg); -+ if (val < 0) -+ return 0; -+ return ip_phy_write(state, port, reg, (val & ~mask) | data); -+} -+ -+static int getPhy(struct ip17xx_state *state, reg mii) -+{ -+ if (!REG_SUPP(mii)) -+ return -EFAULT; -+ return ip_phy_read(state, mii.p, mii.m); -+} -+ -+static int setPhy(struct ip17xx_state *state, reg mii, u16 value) -+{ -+ int err; -+ -+ if (!REG_SUPP(mii)) -+ return -EFAULT; -+ err = ip_phy_write(state, mii.p, mii.m, value); -+ if (err < 0) -+ return err; -+ mdelay(2); -+ getPhy(state, mii); -+ return 0; -+} -+ -+ -+/** -+ * These two macros are to simplify the mapping of logical bits to the bits in hardware. -+ * NOTE: these macros will return if there is an error! -+ */ -+ -+#define GET_PORT_BITS(state, bits, addr, bit_lookup) \ -+ do { \ -+ int i, val = getPhy((state), (addr)); \ -+ if (val < 0) \ -+ return val; \ -+ (bits) = 0; \ -+ for (i = 0; i < MAX_PORTS; i++) { \ -+ if ((bit_lookup)[i] == -1) continue; \ -+ if (val & (1<<(bit_lookup)[i])) \ -+ (bits) |= (1<>i)<<(bit_lookup)[i]); \ -+ } \ -+ val = setPhy((state), (addr), val); \ -+ if (val < 0) \ -+ return val; \ -+ } while (0) -+ -+ -+static int get_model(struct ip17xx_state *state) -+{ -+ int id1, id2; -+ int oui_id, model_no, rev_no, chip_no; -+ -+ id1 = ip_phy_read(state, 0, 2); -+ id2 = ip_phy_read(state, 0, 3); -+ oui_id = (id1 << 6) | ((id2 >> 10) & 0x3f); -+ model_no = (id2 >> 4) & 0x3f; -+ rev_no = id2 & 0xf; -+ pr_debug("IP17xx: Identified oui=%06x model=%02x rev=%X\n", oui_id, model_no, rev_no); -+ -+ if (oui_id != 0x0090c3) // No other oui_id should have reached us anyway -+ return -ENODEV; -+ -+ if (model_no == IP175A.MODEL_NO) { -+ state->regs = &IP175A; -+ } else if (model_no == IP175C.MODEL_NO) { -+ /* -+ * Several models share the same model_no: -+ * 178C has more PHYs, so we try whether the device responds to a read from PHY5 -+ * 175D has a new chip ID register -+ * 175C has neither -+ */ -+ if (ip_phy_read(state, 5, 2) == 0x0243) { -+ state->regs = &IP178C; -+ } else { -+ chip_no = ip_phy_read(state, 20, 0); -+ pr_debug("IP17xx: Chip ID register reads %04x\n", chip_no); -+ if (chip_no == 0x175d) { -+ state->regs = &IP175D; -+ } else { -+ state->regs = &IP175C; -+ } -+ } -+ } else { -+ pr_warn("IP17xx: Found an unknown IC+ switch with model number %02x, revision %X.\n", model_no, rev_no); -+ return -EPERM; -+ } -+ return 0; -+} -+ -+/*** Low-level functions for the older models ***/ -+ -+/** Only set vlan and router flags in the switch **/ -+static int ip175c_set_flags(struct ip17xx_state *state) -+{ -+ int val; -+ -+ if (!REG_SUPP(state->regs->ROUTER_CONTROL_REG)) { -+ return 0; -+ } -+ -+ val = getPhy(state, state->regs->ROUTER_CONTROL_REG); -+ if (val < 0) { -+ return val; -+ } -+ if (state->regs->ROUTER_EN_BIT >= 0) { -+ if (state->router_mode) { -+ val |= (1<regs->ROUTER_EN_BIT); -+ } else { -+ val &= (~(1<regs->ROUTER_EN_BIT)); -+ } -+ } -+ if (state->regs->TAG_VLAN_BIT >= 0) { -+ if (state->vlan_enabled) { -+ val |= (1<regs->TAG_VLAN_BIT); -+ } else { -+ val &= (~(1<regs->TAG_VLAN_BIT)); -+ } -+ } -+ if (state->regs->NUMLAN_GROUPS_BIT >= 0) { -+ val &= (~((state->regs->NUMLAN_GROUPS_MAX-1)<regs->NUMLAN_GROUPS_BIT)); -+ if (state->num_vlans > state->regs->NUMLAN_GROUPS_MAX) { -+ val |= state->regs->NUMLAN_GROUPS_MAX << state->regs->NUMLAN_GROUPS_BIT; -+ } else if (state->num_vlans >= 1) { -+ val |= (state->num_vlans-1) << state->regs->NUMLAN_GROUPS_BIT; -+ } -+ } -+ return setPhy(state, state->regs->ROUTER_CONTROL_REG, val); -+} -+ -+/** Set all VLAN and port state. Usually you should call "correct_vlan_state" first. **/ -+static int ip175c_set_state(struct ip17xx_state *state) -+{ -+ int j; -+ int i; -+ SET_PORT_BITS(state, state->add_tag, -+ state->regs->ADD_TAG_REG, state->regs->ADD_TAG_BIT); -+ SET_PORT_BITS(state, state->remove_tag, -+ state->regs->REMOVE_TAG_REG, state->regs->REMOVE_TAG_BIT); -+ -+ if (REG_SUPP(state->regs->VLAN_LOOKUP_REG)) { -+ for (j=0; jregs->NUM_PORTS; j++) { -+ reg addr; -+ const bitnum *bit_lookup = (j%2==0)? -+ state->regs->VLAN_LOOKUP_EVEN_BIT: -+ state->regs->VLAN_LOOKUP_ODD_BIT; -+ -+ addr = state->regs->VLAN_LOOKUP_REG; -+ if (state->regs->SIMPLE_VLAN_REGISTERS) { -+ addr.m += j; -+ } else { -+ switch (j) { -+ case 0: -+ case 1: -+ break; -+ case 2: -+ case 3: -+ addr.m+=1; -+ break; -+ case 4: -+ addr.m+=2; -+ break; -+ case 5: -+ addr = state->regs->VLAN_LOOKUP_REG_5; -+ break; -+ default: -+ addr.m = -1; // shouldn't get here, but... -+ break; -+ } -+ } -+ //printf("shareports for %d is %02X\n",j,state->ports[j].shareports); -+ if (REG_SUPP(addr)) { -+ SET_PORT_BITS(state, state->ports[j].shareports, addr, bit_lookup); -+ } -+ } -+ } -+ if (REG_SUPP(state->regs->TAG_VLAN_MASK_REG)) { -+ for (j=0; jregs->TAG_VLAN_MASK_REG; -+ const bitnum *bit_lookup = (j%2==0)? -+ state->regs->TAG_VLAN_MASK_EVEN_BIT: -+ state->regs->TAG_VLAN_MASK_ODD_BIT; -+ unsigned int vlan_mask; -+ if (state->regs->SIMPLE_VLAN_REGISTERS) { -+ addr.m += j; -+ } else { -+ addr.m += j/2; -+ } -+ vlan_mask = state->vlans[j].ports; -+ SET_PORT_BITS(state, vlan_mask, addr, bit_lookup); -+ } -+ } -+ -+ for (i=0; iregs->VLAN_DEFAULT_TAG_REG[i])) { -+ int err = setPhy(state, state->regs->VLAN_DEFAULT_TAG_REG[i], -+ state->ports[i].pvid); -+ if (err < 0) { -+ return err; -+ } -+ } -+ } -+ -+ return ip175c_set_flags(state); -+} -+ -+/** -+ * Uses only the VLAN port mask and the add tag mask to generate the other fields: -+ * which ports are part of the same VLAN, removing vlan tags, and VLAN tag ids. -+ */ -+static void ip175c_correct_vlan_state(struct ip17xx_state *state) -+{ -+ int i, j; -+ state->num_vlans = 0; -+ for (i=0; ivlans[i].ports != 0) { -+ state->num_vlans = i+1; // Hack -- we need to store the "set" vlans somewhere... -+ } -+ } -+ -+ for (i=0; iregs->NUM_PORTS; i++) { -+ unsigned int portmask = (1<vlan_enabled) { -+ // Share with everybody! -+ state->ports[i].shareports = (1<regs->NUM_PORTS)-1; -+ continue; -+ } -+ state->ports[i].shareports = portmask; -+ for (j=0; jvlans[j].ports & portmask) -+ state->ports[i].shareports |= state->vlans[j].ports; -+ } -+ } -+} -+ -+static int ip175c_update_state(struct ip17xx_state *state) -+{ -+ ip175c_correct_vlan_state(state); -+ return ip175c_set_state(state); -+} -+ -+static int ip175c_set_vlan_mode(struct ip17xx_state *state) -+{ -+ return ip175c_update_state(state); -+} -+ -+static int ip175c_reset(struct ip17xx_state *state) -+{ -+ int err; -+ -+ if (REG_SUPP(state->regs->MODE_REG)) { -+ err = setPhy(state, state->regs->MODE_REG, state->regs->MODE_VAL); -+ if (err < 0) -+ return err; -+ err = getPhy(state, state->regs->MODE_REG); -+ if (err < 0) -+ return err; -+ } -+ -+ return ip175c_update_state(state); -+} -+ -+/*** Low-level functions for IP175D ***/ -+ -+static int ip175d_update_state(struct ip17xx_state *state) -+{ -+ unsigned int filter_mask = 0; -+ unsigned int ports[16], add[16], rem[16]; -+ int i, j; -+ int err = 0; -+ -+ for (i = 0; i < 16; i++) { -+ ports[i] = 0; -+ add[i] = 0; -+ rem[i] = 0; -+ if (!state->vlan_enabled) { -+ err |= ip_phy_write(state, 22, 14+i, i+1); // default tags -+ ports[i] = 0x3f; -+ continue; -+ } -+ if (!state->vlans[i].tag) { -+ // Reset the filter -+ err |= ip_phy_write(state, 22, 14+i, 0); // tag -+ continue; -+ } -+ filter_mask |= 1 << i; -+ err |= ip_phy_write(state, 22, 14+i, state->vlans[i].tag); -+ ports[i] = state->vlans[i].ports; -+ for (j = 0; j < 6; j++) { -+ if (ports[i] & (1 << j)) { -+ if (state->add_tag & (1 << j)) -+ add[i] |= 1 << j; -+ if (state->remove_tag & (1 << j)) -+ rem[i] |= 1 << j; -+ } -+ } -+ } -+ -+ // Port masks, tag adds and removals -+ for (i = 0; i < 8; i++) { -+ err |= ip_phy_write(state, 23, i, ports[2*i] | (ports[2*i+1] << 8)); -+ err |= ip_phy_write(state, 23, 8+i, add[2*i] | (add[2*i+1] << 8)); -+ err |= ip_phy_write(state, 23, 16+i, rem[2*i] | (rem[2*i+1] << 8)); -+ } -+ err |= ip_phy_write(state, 22, 10, filter_mask); -+ -+ // Default VLAN tag for each port -+ for (i = 0; i < 6; i++) -+ err |= ip_phy_write(state, 22, 4+i, state->vlans[state->ports[i].pvid].tag); -+ -+ return (err ? -EIO : 0); -+} -+ -+static int ip175d_set_vlan_mode(struct ip17xx_state *state) -+{ -+ int i; -+ int err = 0; -+ -+ if (state->vlan_enabled) { -+ // VLAN classification rules: tag-based VLANs, use VID to classify, -+ // drop packets that cannot be classified. -+ err |= ip_phy_write_masked(state, 22, 0, 0x3fff, 0x003f); -+ -+ // Ingress rules: CFI=1 dropped, null VID is untagged, VID=1 passed, -+ // VID=0xfff discarded, admin both tagged and untagged, ingress -+ // filters enabled. -+ err |= ip_phy_write_masked(state, 22, 1, 0x0fff, 0x0c3f); -+ -+ // Egress rules: IGMP processing off, keep VLAN header off -+ err |= ip_phy_write_masked(state, 22, 2, 0x0fff, 0x0000); -+ } else { -+ // VLAN classification rules: everything off & clear table -+ err |= ip_phy_write_masked(state, 22, 0, 0xbfff, 0x8000); -+ -+ // Ingress and egress rules: set to defaults -+ err |= ip_phy_write_masked(state, 22, 1, 0x0fff, 0x0c3f); -+ err |= ip_phy_write_masked(state, 22, 2, 0x0fff, 0x0000); -+ } -+ -+ // Reset default VLAN for each port to 0 -+ for (i = 0; i < 6; i++) -+ state->ports[i].pvid = 0; -+ -+ err |= ip175d_update_state(state); -+ -+ return (err ? -EIO : 0); -+} -+ -+static int ip175d_reset(struct ip17xx_state *state) -+{ -+ int err = 0; -+ -+ // Disable the special tagging mode -+ err |= ip_phy_write_masked(state, 21, 22, 0x0003, 0x0000); -+ -+ // Set 802.1q protocol type -+ err |= ip_phy_write(state, 22, 3, 0x8100); -+ -+ state->vlan_enabled = 0; -+ err |= ip175d_set_vlan_mode(state); -+ -+ return (err ? -EIO : 0); -+} -+ -+/*** High-level functions ***/ -+ -+static int ip17xx_get_enable_vlan(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ struct ip17xx_state *state = get_state(dev); -+ -+ val->value.i = state->vlan_enabled; -+ return 0; -+} -+ -+static void ip17xx_reset_vlan_config(struct ip17xx_state *state) -+{ -+ int i; -+ -+ state->remove_tag = (state->vlan_enabled ? ((1<regs->NUM_PORTS)-1) : 0x0000); -+ state->add_tag = 0x0000; -+ for (i = 0; i < MAX_VLANS; i++) { -+ state->vlans[i].ports = 0x0000; -+ state->vlans[i].tag = (i ? i : 16); -+ } -+ for (i = 0; i < MAX_PORTS; i++) -+ state->ports[i].pvid = 0; -+} -+ -+static int ip17xx_set_enable_vlan(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ struct ip17xx_state *state = get_state(dev); -+ int enable; -+ -+ enable = val->value.i; -+ if (state->vlan_enabled == enable) { -+ // Do not change any state. -+ return 0; -+ } -+ state->vlan_enabled = enable; -+ -+ // Otherwise, if we are switching state, set fields to a known default. -+ ip17xx_reset_vlan_config(state); -+ -+ return state->regs->set_vlan_mode(state); -+} -+ -+static int ip17xx_get_ports(struct switch_dev *dev, struct switch_val *val) -+{ -+ struct ip17xx_state *state = get_state(dev); -+ int b; -+ int ind; -+ unsigned int ports; -+ -+ if (val->port_vlan >= dev->vlans || val->port_vlan < 0) -+ return -EINVAL; -+ -+ ports = state->vlans[val->port_vlan].ports; -+ b = 0; -+ ind = 0; -+ while (b < MAX_PORTS) { -+ if (ports&1) { -+ int istagged = ((state->add_tag >> b) & 1); -+ val->value.ports[ind].id = b; -+ val->value.ports[ind].flags = (istagged << SWITCH_PORT_FLAG_TAGGED); -+ ind++; -+ } -+ b++; -+ ports >>= 1; -+ } -+ val->len = ind; -+ -+ return 0; -+} -+ -+static int ip17xx_set_ports(struct switch_dev *dev, struct switch_val *val) -+{ -+ struct ip17xx_state *state = get_state(dev); -+ int i; -+ -+ if (val->port_vlan >= dev->vlans || val->port_vlan < 0) -+ return -EINVAL; -+ -+ state->vlans[val->port_vlan].ports = 0; -+ for (i = 0; i < val->len; i++) { -+ unsigned int bitmask = (1<value.ports[i].id); -+ state->vlans[val->port_vlan].ports |= bitmask; -+ if (val->value.ports[i].flags & (1<add_tag |= bitmask; -+ state->remove_tag &= (~bitmask); -+ } else { -+ state->add_tag &= (~bitmask); -+ state->remove_tag |= bitmask; -+ } -+ } -+ -+ return state->regs->update_state(state); -+} -+ -+static int ip17xx_apply(struct switch_dev *dev) -+{ -+ struct ip17xx_state *state = get_state(dev); -+ -+ if (REG_SUPP(state->regs->MII_REGISTER_EN)) { -+ int val = getPhy(state, state->regs->MII_REGISTER_EN); -+ if (val < 0) { -+ return val; -+ } -+ val |= (1<regs->MII_REGISTER_EN_BIT); -+ return setPhy(state, state->regs->MII_REGISTER_EN, val); -+ } -+ return 0; -+} -+ -+static int ip17xx_reset(struct switch_dev *dev) -+{ -+ struct ip17xx_state *state = get_state(dev); -+ int i, err; -+ -+ if (REG_SUPP(state->regs->RESET_REG)) { -+ err = setPhy(state, state->regs->RESET_REG, state->regs->RESET_VAL); -+ if (err < 0) -+ return err; -+ err = getPhy(state, state->regs->RESET_REG); -+ -+ /* -+ * Data sheet specifies reset period to be 2 msec. -+ * (I don't see any mention of the 2ms delay in the IP178C spec, only -+ * in IP175C, but it can't hurt.) -+ */ -+ mdelay(2); -+ } -+ -+ /* reset switch ports */ -+ for (i = 0; i < state->regs->NUM_PORTS-1; i++) { -+ err = ip_phy_write(state, i, MII_BMCR, BMCR_RESET); -+ if (err < 0) -+ return err; -+ } -+ -+ state->router_mode = 0; -+ state->vlan_enabled = 0; -+ ip17xx_reset_vlan_config(state); -+ -+ return state->regs->reset(state); -+} -+ -+static int ip17xx_get_tagged(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ struct ip17xx_state *state = get_state(dev); -+ -+ if (state->add_tag & (1<port_vlan)) { -+ if (state->remove_tag & (1<port_vlan)) -+ val->value.i = 3; // shouldn't ever happen. -+ else -+ val->value.i = 1; -+ } else { -+ if (state->remove_tag & (1<port_vlan)) -+ val->value.i = 0; -+ else -+ val->value.i = 2; -+ } -+ return 0; -+} -+ -+static int ip17xx_set_tagged(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ struct ip17xx_state *state = get_state(dev); -+ -+ state->add_tag &= ~(1<port_vlan); -+ state->remove_tag &= ~(1<port_vlan); -+ -+ if (val->value.i == 0) -+ state->remove_tag |= (1<port_vlan); -+ if (val->value.i == 1) -+ state->add_tag |= (1<port_vlan); -+ -+ return state->regs->update_state(state); -+} -+ -+/** Get the current phy address */ -+static int ip17xx_get_phy(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ struct ip17xx_state *state = get_state(dev); -+ -+ val->value.i = state->proc_mii.p; -+ return 0; -+} -+ -+/** Set a new phy address for low level access to registers */ -+static int ip17xx_set_phy(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ struct ip17xx_state *state = get_state(dev); -+ int new_reg = val->value.i; -+ -+ if (new_reg < 0 || new_reg > 31) -+ state->proc_mii.p = (u16)-1; -+ else -+ state->proc_mii.p = (u16)new_reg; -+ return 0; -+} -+ -+/** Get the current register number */ -+static int ip17xx_get_reg(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ struct ip17xx_state *state = get_state(dev); -+ -+ val->value.i = state->proc_mii.m; -+ return 0; -+} -+ -+/** Set a new register address for low level access to registers */ -+static int ip17xx_set_reg(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ struct ip17xx_state *state = get_state(dev); -+ int new_reg = val->value.i; -+ -+ if (new_reg < 0 || new_reg > 31) -+ state->proc_mii.m = (u16)-1; -+ else -+ state->proc_mii.m = (u16)new_reg; -+ return 0; -+} -+ -+/** Get the register content of state->proc_mii */ -+static int ip17xx_get_val(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ struct ip17xx_state *state = get_state(dev); -+ int retval = -EINVAL; -+ if (REG_SUPP(state->proc_mii)) -+ retval = getPhy(state, state->proc_mii); -+ -+ if (retval < 0) { -+ return retval; -+ } else { -+ val->value.i = retval; -+ return 0; -+ } -+} -+ -+/** Write a value to the register defined by phy/reg above */ -+static int ip17xx_set_val(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ struct ip17xx_state *state = get_state(dev); -+ int myval, err = -EINVAL; -+ -+ myval = val->value.i; -+ if (myval <= 0xffff && myval >= 0 && REG_SUPP(state->proc_mii)) { -+ err = setPhy(state, state->proc_mii, (u16)myval); -+ } -+ return err; -+} -+ -+static int ip17xx_read_name(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ struct ip17xx_state *state = get_state(dev); -+ val->value.s = state->regs->NAME; // Just a const pointer, won't be freed by swconfig. -+ return 0; -+} -+ -+static int ip17xx_get_tag(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ struct ip17xx_state *state = get_state(dev); -+ int vlan = val->port_vlan; -+ -+ if (vlan < 0 || vlan >= MAX_VLANS) -+ return -EINVAL; -+ -+ val->value.i = state->vlans[vlan].tag; -+ return 0; -+} -+ -+static int ip17xx_set_tag(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ struct ip17xx_state *state = get_state(dev); -+ int vlan = val->port_vlan; -+ int tag = val->value.i; -+ -+ if (vlan < 0 || vlan >= MAX_VLANS) -+ return -EINVAL; -+ -+ if (tag < 0 || tag > 4095) -+ return -EINVAL; -+ -+ state->vlans[vlan].tag = tag; -+ return state->regs->update_state(state); -+} -+ -+static int ip17xx_set_port_speed(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ struct ip17xx_state *state = get_state(dev); -+ int nr = val->port_vlan; -+ int ctrl; -+ int autoneg; -+ int speed; -+ if (val->value.i == 100) { -+ speed = 1; -+ autoneg = 0; -+ } else if (val->value.i == 10) { -+ speed = 0; -+ autoneg = 0; -+ } else { -+ autoneg = 1; -+ speed = 1; -+ } -+ -+ /* Can't set speed for cpu port */ -+ if (nr == state->regs->CPU_PORT) -+ return -EINVAL; -+ -+ if (nr >= dev->ports || nr < 0) -+ return -EINVAL; -+ -+ ctrl = ip_phy_read(state, nr, 0); -+ if (ctrl < 0) -+ return -EIO; -+ -+ ctrl &= (~(1<<12)); -+ ctrl &= (~(1<<13)); -+ ctrl |= (autoneg<<12); -+ ctrl |= (speed<<13); -+ -+ return ip_phy_write(state, nr, 0, ctrl); -+} -+ -+static int ip17xx_get_port_speed(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ struct ip17xx_state *state = get_state(dev); -+ int nr = val->port_vlan; -+ int speed, status; -+ -+ if (nr == state->regs->CPU_PORT) { -+ val->value.i = 100; -+ return 0; -+ } -+ -+ if (nr >= dev->ports || nr < 0) -+ return -EINVAL; -+ -+ status = ip_phy_read(state, nr, 1); -+ speed = ip_phy_read(state, nr, 18); -+ if (status < 0 || speed < 0) -+ return -EIO; -+ -+ if (status & 4) -+ val->value.i = ((speed & (1<<11)) ? 100 : 10); -+ else -+ val->value.i = 0; -+ -+ return 0; -+} -+ -+static int ip17xx_get_port_status(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ struct ip17xx_state *state = get_state(dev); -+ int ctrl, speed, status; -+ int nr = val->port_vlan; -+ int len; -+ char *buf = state->buf; // fixed-length at 80. -+ -+ if (nr == state->regs->CPU_PORT) { -+ sprintf(buf, "up, 100 Mbps, cpu port"); -+ val->value.s = buf; -+ return 0; -+ } -+ -+ if (nr >= dev->ports || nr < 0) -+ return -EINVAL; -+ -+ ctrl = ip_phy_read(state, nr, 0); -+ status = ip_phy_read(state, nr, 1); -+ speed = ip_phy_read(state, nr, 18); -+ if (ctrl < 0 || status < 0 || speed < 0) -+ return -EIO; -+ -+ if (status & 4) -+ len = sprintf(buf, "up, %d Mbps, %s duplex", -+ ((speed & (1<<11)) ? 100 : 10), -+ ((speed & (1<<10)) ? "full" : "half")); -+ else -+ len = sprintf(buf, "down"); -+ -+ if (ctrl & (1<<12)) { -+ len += sprintf(buf+len, ", auto-negotiate"); -+ if (!(status & (1<<5))) -+ len += sprintf(buf+len, " (in progress)"); -+ } else { -+ len += sprintf(buf+len, ", fixed speed (%d)", -+ ((ctrl & (1<<13)) ? 100 : 10)); -+ } -+ -+ buf[len] = '\0'; -+ val->value.s = buf; -+ return 0; -+} -+ -+static int ip17xx_get_pvid(struct switch_dev *dev, int port, int *val) -+{ -+ struct ip17xx_state *state = get_state(dev); -+ -+ *val = state->ports[port].pvid; -+ return 0; -+} -+ -+static int ip17xx_set_pvid(struct switch_dev *dev, int port, int val) -+{ -+ struct ip17xx_state *state = get_state(dev); -+ -+ if (val < 0 || val >= MAX_VLANS) -+ return -EINVAL; -+ -+ state->ports[port].pvid = val; -+ return state->regs->update_state(state); -+} -+ -+ -+enum Ports { -+ IP17XX_PORT_STATUS, -+ IP17XX_PORT_LINK, -+ IP17XX_PORT_TAGGED, -+ IP17XX_PORT_PVID, -+}; -+ -+enum Globals { -+ IP17XX_ENABLE_VLAN, -+ IP17XX_GET_NAME, -+ IP17XX_REGISTER_PHY, -+ IP17XX_REGISTER_MII, -+ IP17XX_REGISTER_VALUE, -+ IP17XX_REGISTER_ERRNO, -+}; -+ -+enum Vlans { -+ IP17XX_VLAN_TAG, -+}; -+ -+static const struct switch_attr ip17xx_global[] = { -+ [IP17XX_ENABLE_VLAN] = { -+ .id = IP17XX_ENABLE_VLAN, -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_vlan", -+ .description = "Flag to enable or disable VLANs and tagging", -+ .get = ip17xx_get_enable_vlan, -+ .set = ip17xx_set_enable_vlan, -+ }, -+ [IP17XX_GET_NAME] = { -+ .id = IP17XX_GET_NAME, -+ .type = SWITCH_TYPE_STRING, -+ .description = "Returns the type of IC+ chip.", -+ .name = "name", -+ .get = ip17xx_read_name, -+ .set = NULL, -+ }, -+ /* jal: added for low level debugging etc. */ -+ [IP17XX_REGISTER_PHY] = { -+ .id = IP17XX_REGISTER_PHY, -+ .type = SWITCH_TYPE_INT, -+ .description = "Direct register access: set PHY (0-4, or 29,30,31)", -+ .name = "phy", -+ .get = ip17xx_get_phy, -+ .set = ip17xx_set_phy, -+ }, -+ [IP17XX_REGISTER_MII] = { -+ .id = IP17XX_REGISTER_MII, -+ .type = SWITCH_TYPE_INT, -+ .description = "Direct register access: set MII register number (0-31)", -+ .name = "reg", -+ .get = ip17xx_get_reg, -+ .set = ip17xx_set_reg, -+ }, -+ [IP17XX_REGISTER_VALUE] = { -+ .id = IP17XX_REGISTER_VALUE, -+ .type = SWITCH_TYPE_INT, -+ .description = "Direct register access: read/write to register (0-65535)", -+ .name = "val", -+ .get = ip17xx_get_val, -+ .set = ip17xx_set_val, -+ }, -+}; -+ -+static const struct switch_attr ip17xx_vlan[] = { -+ [IP17XX_VLAN_TAG] = { -+ .id = IP17XX_VLAN_TAG, -+ .type = SWITCH_TYPE_INT, -+ .description = "VLAN ID (0-4095) [IP175D only]", -+ .name = "vid", -+ .get = ip17xx_get_tag, -+ .set = ip17xx_set_tag, -+ } -+}; -+ -+static const struct switch_attr ip17xx_port[] = { -+ [IP17XX_PORT_STATUS] = { -+ .id = IP17XX_PORT_STATUS, -+ .type = SWITCH_TYPE_STRING, -+ .description = "Returns Detailed port status", -+ .name = "status", -+ .get = ip17xx_get_port_status, -+ .set = NULL, -+ }, -+ [IP17XX_PORT_LINK] = { -+ .id = IP17XX_PORT_LINK, -+ .type = SWITCH_TYPE_INT, -+ .description = "Link speed. Can write 0 for auto-negotiate, or 10 or 100", -+ .name = "link", -+ .get = ip17xx_get_port_speed, -+ .set = ip17xx_set_port_speed, -+ }, -+ [IP17XX_PORT_TAGGED] = { -+ .id = IP17XX_PORT_LINK, -+ .type = SWITCH_TYPE_INT, -+ .description = "0 = untag, 1 = add tags, 2 = do not alter (This value is reset if vlans are altered)", -+ .name = "tagged", -+ .get = ip17xx_get_tagged, -+ .set = ip17xx_set_tagged, -+ }, -+}; -+ -+static const struct switch_dev_ops ip17xx_ops = { -+ .attr_global = { -+ .attr = ip17xx_global, -+ .n_attr = ARRAY_SIZE(ip17xx_global), -+ }, -+ .attr_port = { -+ .attr = ip17xx_port, -+ .n_attr = ARRAY_SIZE(ip17xx_port), -+ }, -+ .attr_vlan = { -+ .attr = ip17xx_vlan, -+ .n_attr = ARRAY_SIZE(ip17xx_vlan), -+ }, -+ -+ .get_port_pvid = ip17xx_get_pvid, -+ .set_port_pvid = ip17xx_set_pvid, -+ .get_vlan_ports = ip17xx_get_ports, -+ .set_vlan_ports = ip17xx_set_ports, -+ .apply_config = ip17xx_apply, -+ .reset_switch = ip17xx_reset, -+}; -+ -+static int ip17xx_probe(struct phy_device *pdev) -+{ -+ struct ip17xx_state *state; -+ struct switch_dev *dev; -+ int err; -+ -+ /* We only attach to PHY 0, but use all available PHYs */ -+ if (pdev->mdio.addr != 0) -+ return -ENODEV; -+ -+ state = kzalloc(sizeof(*state), GFP_KERNEL); -+ if (!state) -+ return -ENOMEM; -+ -+ dev = &state->dev; -+ -+ pdev->priv = state; -+ state->mii_bus = pdev->mdio.bus; -+ -+ err = get_model(state); -+ if (err < 0) -+ goto error; -+ -+ dev->vlans = MAX_VLANS; -+ dev->cpu_port = state->regs->CPU_PORT; -+ dev->ports = state->regs->NUM_PORTS; -+ dev->name = state->regs->NAME; -+ dev->ops = &ip17xx_ops; -+ -+ pr_info("IP17xx: Found %s at %s\n", dev->name, dev_name(&pdev->mdio.dev)); -+ return 0; -+ -+error: -+ kfree(state); -+ return err; -+} -+ -+static int ip17xx_config_init(struct phy_device *pdev) -+{ -+ struct ip17xx_state *state = pdev->priv; -+ struct net_device *dev = pdev->attached_dev; -+ int err; -+ -+ err = register_switch(&state->dev, dev); -+ if (err < 0) -+ return err; -+ -+ state->registered = true; -+ ip17xx_reset(&state->dev); -+ return 0; -+} -+ -+static void ip17xx_remove(struct phy_device *pdev) -+{ -+ struct ip17xx_state *state = pdev->priv; -+ -+ if (state->registered) -+ unregister_switch(&state->dev); -+ kfree(state); -+} -+ -+static int ip17xx_config_aneg(struct phy_device *pdev) -+{ -+ return 0; -+} -+ -+static int ip17xx_aneg_done(struct phy_device *pdev) -+{ -+ return 1; /* Return any positive value */ -+} -+ -+static int ip17xx_read_status(struct phy_device *pdev) -+{ -+ pdev->speed = SPEED_100; -+ pdev->duplex = DUPLEX_FULL; -+ pdev->pause = pdev->asym_pause = 0; -+ pdev->link = 1; -+ -+ return 0; -+} -+ -+static struct phy_driver ip17xx_driver[] = { -+ { -+ .name = "IC+ IP17xx", -+ .phy_id = 0x02430c00, -+ .phy_id_mask = 0x0ffffc00, -+ .features = PHY_BASIC_FEATURES, -+ .probe = ip17xx_probe, -+ .remove = ip17xx_remove, -+ .config_init = ip17xx_config_init, -+ .config_aneg = ip17xx_config_aneg, -+ .aneg_done = ip17xx_aneg_done, -+ .read_status = ip17xx_read_status, -+ } -+}; -+ -+module_phy_driver(ip17xx_driver); -+ -+MODULE_AUTHOR("Patrick Horn "); -+MODULE_AUTHOR("Felix Fietkau "); -+MODULE_AUTHOR("Martin Mares "); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/net/phy/psb6970.c b/drivers/net/phy/psb6970.c -new file mode 100644 -index 000000000000..e8b1b06f6365 ---- /dev/null -+++ b/drivers/net/phy/psb6970.c -@@ -0,0 +1,443 @@ -+/* -+ * Lantiq PSB6970 (Tantos) Switch driver -+ * -+ * Copyright (c) 2009,2010 Team Embedded. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License v2 as published by the -+ * Free Software Foundation. -+ * -+ * The switch programming done in this driver follows the -+ * "Ethernet Traffic Separation using VLAN" Application Note as -+ * published by Lantiq. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define PSB6970_MAX_VLANS 16 -+#define PSB6970_NUM_PORTS 7 -+#define PSB6970_DEFAULT_PORT_CPU 6 -+#define PSB6970_IS_CPU_PORT(x) ((x) > 4) -+ -+#define PHYADDR(_reg) ((_reg >> 5) & 0xff), (_reg & 0x1f) -+ -+/* --- Identification --- */ -+#define PSB6970_CI0 0x0100 -+#define PSB6970_CI0_MASK 0x000f -+#define PSB6970_CI1 0x0101 -+#define PSB6970_CI1_VAL 0x2599 -+#define PSB6970_CI1_MASK 0xffff -+ -+/* --- VLAN filter table --- */ -+#define PSB6970_VFxL(i) ((i)*2+0x10) /* VLAN Filter Low */ -+#define PSB6970_VFxL_VV (1 << 15) /* VLAN_Valid */ -+ -+#define PSB6970_VFxH(i) ((i)*2+0x11) /* VLAN Filter High */ -+#define PSB6970_VFxH_TM_SHIFT 7 /* Tagged Member */ -+ -+/* --- Port registers --- */ -+#define PSB6970_EC(p) ((p)*0x20+2) /* Extended Control */ -+#define PSB6970_EC_IFNTE (1 << 1) /* Input Force No Tag Enable */ -+ -+#define PSB6970_PBVM(p) ((p)*0x20+3) /* Port Base VLAN Map */ -+#define PSB6970_PBVM_VMCE (1 << 8) -+#define PSB6970_PBVM_AOVTP (1 << 9) -+#define PSB6970_PBVM_VSD (1 << 10) -+#define PSB6970_PBVM_VC (1 << 11) /* VID Check with VID table */ -+#define PSB6970_PBVM_TBVE (1 << 13) /* Tag-Based VLAN enable */ -+ -+#define PSB6970_DVID(p) ((p)*0x20+4) /* Default VLAN ID & Priority */ -+ -+struct psb6970_priv { -+ struct switch_dev dev; -+ struct phy_device *phy; -+ u16 (*read) (struct phy_device* phydev, int reg); -+ void (*write) (struct phy_device* phydev, int reg, u16 val); -+ struct mutex reg_mutex; -+ -+ /* all fields below are cleared on reset */ -+ struct_group(psb6970_priv_volatile, -+ bool vlan; -+ u16 vlan_id[PSB6970_MAX_VLANS]; -+ u8 vlan_table[PSB6970_MAX_VLANS]; -+ u8 vlan_tagged; -+ u16 pvid[PSB6970_NUM_PORTS]; -+ ); -+}; -+ -+#define to_psb6970(_dev) container_of(_dev, struct psb6970_priv, dev) -+ -+static u16 psb6970_mii_read(struct phy_device *phydev, int reg) -+{ -+ struct mii_bus *bus = phydev->mdio.bus; -+ -+ return bus->read(bus, PHYADDR(reg)); -+} -+ -+static void psb6970_mii_write(struct phy_device *phydev, int reg, u16 val) -+{ -+ struct mii_bus *bus = phydev->mdio.bus; -+ -+ bus->write(bus, PHYADDR(reg), val); -+} -+ -+static int -+psb6970_set_vlan(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct psb6970_priv *priv = to_psb6970(dev); -+ priv->vlan = !!val->value.i; -+ return 0; -+} -+ -+static int -+psb6970_get_vlan(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct psb6970_priv *priv = to_psb6970(dev); -+ val->value.i = priv->vlan; -+ return 0; -+} -+ -+static int psb6970_set_pvid(struct switch_dev *dev, int port, int vlan) -+{ -+ struct psb6970_priv *priv = to_psb6970(dev); -+ -+ /* make sure no invalid PVIDs get set */ -+ if (vlan >= dev->vlans) -+ return -EINVAL; -+ -+ priv->pvid[port] = vlan; -+ return 0; -+} -+ -+static int psb6970_get_pvid(struct switch_dev *dev, int port, int *vlan) -+{ -+ struct psb6970_priv *priv = to_psb6970(dev); -+ *vlan = priv->pvid[port]; -+ return 0; -+} -+ -+static int -+psb6970_set_vid(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct psb6970_priv *priv = to_psb6970(dev); -+ priv->vlan_id[val->port_vlan] = val->value.i; -+ return 0; -+} -+ -+static int -+psb6970_get_vid(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct psb6970_priv *priv = to_psb6970(dev); -+ val->value.i = priv->vlan_id[val->port_vlan]; -+ return 0; -+} -+ -+static struct switch_attr psb6970_globals[] = { -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_vlan", -+ .description = "Enable VLAN mode", -+ .set = psb6970_set_vlan, -+ .get = psb6970_get_vlan, -+ .max = 1}, -+}; -+ -+static struct switch_attr psb6970_port[] = { -+}; -+ -+static struct switch_attr psb6970_vlan[] = { -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "vid", -+ .description = "VLAN ID (0-4094)", -+ .set = psb6970_set_vid, -+ .get = psb6970_get_vid, -+ .max = 4094, -+ }, -+}; -+ -+static int psb6970_get_ports(struct switch_dev *dev, struct switch_val *val) -+{ -+ struct psb6970_priv *priv = to_psb6970(dev); -+ u8 ports = priv->vlan_table[val->port_vlan]; -+ int i; -+ -+ val->len = 0; -+ for (i = 0; i < PSB6970_NUM_PORTS; i++) { -+ struct switch_port *p; -+ -+ if (!(ports & (1 << i))) -+ continue; -+ -+ p = &val->value.ports[val->len++]; -+ p->id = i; -+ if (priv->vlan_tagged & (1 << i)) -+ p->flags = (1 << SWITCH_PORT_FLAG_TAGGED); -+ else -+ p->flags = 0; -+ } -+ return 0; -+} -+ -+static int psb6970_set_ports(struct switch_dev *dev, struct switch_val *val) -+{ -+ struct psb6970_priv *priv = to_psb6970(dev); -+ u8 *vt = &priv->vlan_table[val->port_vlan]; -+ int i, j; -+ -+ *vt = 0; -+ for (i = 0; i < val->len; i++) { -+ struct switch_port *p = &val->value.ports[i]; -+ -+ if (p->flags & (1 << SWITCH_PORT_FLAG_TAGGED)) -+ priv->vlan_tagged |= (1 << p->id); -+ else { -+ priv->vlan_tagged &= ~(1 << p->id); -+ priv->pvid[p->id] = val->port_vlan; -+ -+ /* make sure that an untagged port does not -+ * appear in other vlans */ -+ for (j = 0; j < PSB6970_MAX_VLANS; j++) { -+ if (j == val->port_vlan) -+ continue; -+ priv->vlan_table[j] &= ~(1 << p->id); -+ } -+ } -+ -+ *vt |= 1 << p->id; -+ } -+ return 0; -+} -+ -+static int psb6970_hw_apply(struct switch_dev *dev) -+{ -+ struct psb6970_priv *priv = to_psb6970(dev); -+ int i, j; -+ -+ mutex_lock(&priv->reg_mutex); -+ -+ if (priv->vlan) { -+ /* into the vlan translation unit */ -+ for (j = 0; j < PSB6970_MAX_VLANS; j++) { -+ u8 vp = priv->vlan_table[j]; -+ -+ if (vp) { -+ priv->write(priv->phy, PSB6970_VFxL(j), -+ PSB6970_VFxL_VV | priv->vlan_id[j]); -+ priv->write(priv->phy, PSB6970_VFxH(j), -+ ((vp & priv-> -+ vlan_tagged) << -+ PSB6970_VFxH_TM_SHIFT) | vp); -+ } else /* clear VLAN Valid flag for unused vlans */ -+ priv->write(priv->phy, PSB6970_VFxL(j), 0); -+ -+ } -+ } -+ -+ /* update the port destination mask registers and tag settings */ -+ for (i = 0; i < PSB6970_NUM_PORTS; i++) { -+ int dvid = 1, pbvm = 0x7f | PSB6970_PBVM_VSD, ec = 0; -+ -+ if (priv->vlan) { -+ ec = PSB6970_EC_IFNTE; -+ dvid = priv->vlan_id[priv->pvid[i]]; -+ pbvm |= PSB6970_PBVM_TBVE | PSB6970_PBVM_VMCE; -+ -+ if ((i << 1) & priv->vlan_tagged) -+ pbvm |= PSB6970_PBVM_AOVTP | PSB6970_PBVM_VC; -+ } -+ -+ priv->write(priv->phy, PSB6970_PBVM(i), pbvm); -+ -+ if (!PSB6970_IS_CPU_PORT(i)) { -+ priv->write(priv->phy, PSB6970_EC(i), ec); -+ priv->write(priv->phy, PSB6970_DVID(i), dvid); -+ } -+ } -+ -+ mutex_unlock(&priv->reg_mutex); -+ return 0; -+} -+ -+static int psb6970_reset_switch(struct switch_dev *dev) -+{ -+ struct psb6970_priv *priv = to_psb6970(dev); -+ int i; -+ -+ mutex_lock(&priv->reg_mutex); -+ -+ memset(&priv->psb6970_priv_volatile, 0, -+ sizeof(priv->psb6970_priv_volatile)); -+ -+ for (i = 0; i < PSB6970_MAX_VLANS; i++) -+ priv->vlan_id[i] = i; -+ -+ mutex_unlock(&priv->reg_mutex); -+ -+ return psb6970_hw_apply(dev); -+} -+ -+static const struct switch_dev_ops psb6970_ops = { -+ .attr_global = { -+ .attr = psb6970_globals, -+ .n_attr = ARRAY_SIZE(psb6970_globals), -+ }, -+ .attr_port = { -+ .attr = psb6970_port, -+ .n_attr = ARRAY_SIZE(psb6970_port), -+ }, -+ .attr_vlan = { -+ .attr = psb6970_vlan, -+ .n_attr = ARRAY_SIZE(psb6970_vlan), -+ }, -+ .get_port_pvid = psb6970_get_pvid, -+ .set_port_pvid = psb6970_set_pvid, -+ .get_vlan_ports = psb6970_get_ports, -+ .set_vlan_ports = psb6970_set_ports, -+ .apply_config = psb6970_hw_apply, -+ .reset_switch = psb6970_reset_switch, -+}; -+ -+static int psb6970_config_init(struct phy_device *pdev) -+{ -+ struct psb6970_priv *priv; -+ struct switch_dev *swdev; -+ int ret; -+ -+ priv = kzalloc(sizeof(struct psb6970_priv), GFP_KERNEL); -+ if (priv == NULL) -+ return -ENOMEM; -+ -+ priv->phy = pdev; -+ -+ if (pdev->mdio.addr == 0) -+ printk(KERN_INFO "%s: psb6970 switch driver attached.\n", -+ pdev->attached_dev->name); -+ -+ if (pdev->mdio.addr != 0) { -+ kfree(priv); -+ return 0; -+ } -+ -+ linkmode_zero(pdev->supported); -+ linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, pdev->supported); -+ linkmode_copy(pdev->advertising, pdev->supported); -+ -+ mutex_init(&priv->reg_mutex); -+ priv->read = psb6970_mii_read; -+ priv->write = psb6970_mii_write; -+ -+ pdev->priv = priv; -+ -+ swdev = &priv->dev; -+ swdev->cpu_port = PSB6970_DEFAULT_PORT_CPU; -+ swdev->ops = &psb6970_ops; -+ -+ swdev->name = "Lantiq PSB6970"; -+ swdev->vlans = PSB6970_MAX_VLANS; -+ swdev->ports = PSB6970_NUM_PORTS; -+ -+ if ((ret = register_switch(&priv->dev, pdev->attached_dev)) < 0) { -+ kfree(priv); -+ goto done; -+ } -+ -+ ret = psb6970_reset_switch(&priv->dev); -+ if (ret) { -+ kfree(priv); -+ goto done; -+ } -+ -+done: -+ return ret; -+} -+ -+static int psb6970_read_status(struct phy_device *phydev) -+{ -+ phydev->speed = SPEED_100; -+ phydev->duplex = DUPLEX_FULL; -+ phydev->link = 1; -+ -+ phydev->state = PHY_RUNNING; -+ netif_carrier_on(phydev->attached_dev); -+ phydev->adjust_link(phydev->attached_dev); -+ -+ return 0; -+} -+ -+static int psb6970_config_aneg(struct phy_device *phydev) -+{ -+ return 0; -+} -+ -+static int psb6970_probe(struct phy_device *pdev) -+{ -+ return 0; -+} -+ -+static void psb6970_remove(struct phy_device *pdev) -+{ -+ struct psb6970_priv *priv = pdev->priv; -+ -+ if (!priv) -+ return; -+ -+ if (pdev->mdio.addr == 0) -+ unregister_switch(&priv->dev); -+ kfree(priv); -+} -+ -+static int psb6970_fixup(struct phy_device *dev) -+{ -+ struct mii_bus *bus = dev->mdio.bus; -+ u16 reg; -+ -+ /* look for the switch on the bus */ -+ reg = bus->read(bus, PHYADDR(PSB6970_CI1)) & PSB6970_CI1_MASK; -+ if (reg != PSB6970_CI1_VAL) -+ return 0; -+ -+ dev->phy_id = (reg << 16); -+ dev->phy_id |= bus->read(bus, PHYADDR(PSB6970_CI0)) & PSB6970_CI0_MASK; -+ -+ return 0; -+} -+ -+static struct phy_driver psb6970_driver = { -+ .name = "Lantiq PSB6970", -+ .phy_id = PSB6970_CI1_VAL << 16, -+ .phy_id_mask = 0xffff0000, -+ .features = PHY_BASIC_FEATURES, -+ .probe = psb6970_probe, -+ .remove = psb6970_remove, -+ .config_init = &psb6970_config_init, -+ .config_aneg = &psb6970_config_aneg, -+ .read_status = &psb6970_read_status, -+}; -+ -+static int __init psb6970_init(void) -+{ -+ phy_register_fixup_for_id(PHY_ANY_ID, psb6970_fixup); -+ return phy_driver_register(&psb6970_driver, THIS_MODULE); -+} -+ -+module_init(psb6970_init); -+ -+static void __exit psb6970_exit(void) -+{ -+ phy_driver_unregister(&psb6970_driver); -+} -+ -+module_exit(psb6970_exit); -+ -+MODULE_DESCRIPTION("Lantiq PSB6970 Switch"); -+MODULE_AUTHOR("Ithamar R. Adema "); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/net/phy/rtk/Makefile b/drivers/net/phy/rtk/Makefile -new file mode 100644 -index 000000000000..0f2891ead419 ---- /dev/null -+++ b/drivers/net/phy/rtk/Makefile -@@ -0,0 +1,66 @@ -+obj-$(CONFIG_RTL8367S_GSW) += rtl8367s_gsw.o -+rtl8367s_gsw-objs := rtl8367s_mdio.o rtl8367s_dbg.o -+ifeq ($(CONFIG_SWCONFIG),y) -+rtl8367s_gsw-objs += rtl8367s.o -+endif -+rtl8367s_gsw-objs += rtl8367c/acl.o -+rtl8367s_gsw-objs += rtl8367c/cpu.o -+rtl8367s_gsw-objs += rtl8367c/dot1x.o -+rtl8367s_gsw-objs += rtl8367c/eee.o -+rtl8367s_gsw-objs += rtl8367c/igmp.o -+rtl8367s_gsw-objs += rtl8367c/interrupt.o -+rtl8367s_gsw-objs += rtl8367c/l2.o -+rtl8367s_gsw-objs += rtl8367c/leaky.o -+rtl8367s_gsw-objs += rtl8367c/led.o -+rtl8367s_gsw-objs += rtl8367c/mirror.o -+rtl8367s_gsw-objs += rtl8367c/oam.o -+rtl8367s_gsw-objs += rtl8367c/port.o -+rtl8367s_gsw-objs += rtl8367c/ptp.o -+rtl8367s_gsw-objs += rtl8367c/qos.o -+rtl8367s_gsw-objs += rtl8367c/rate.o -+rtl8367s_gsw-objs += rtl8367c/rldp.o -+rtl8367s_gsw-objs += rtl8367c/rtk_switch.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_acl.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_cputag.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_dot1x.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_eav.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_eee.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_fc.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_green.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_hsb.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_igmp.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_inbwctrl.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_interrupt.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_led.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_lut.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_meter.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_mib.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_mirror.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_misc.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_oam.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_phy.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_port.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_portIsolation.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_qos.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_rldp.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_rma.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_scheduling.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_storm.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_svlan.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_trunking.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_unknownMulticast.o -+rtl8367s_gsw-objs += rtl8367c/rtl8367c_asicdrv_vlan.o -+rtl8367s_gsw-objs += rtl8367c/smi.o -+rtl8367s_gsw-objs += rtl8367c/stat.o -+rtl8367s_gsw-objs += rtl8367c/storm.o -+rtl8367s_gsw-objs += rtl8367c/svlan.o -+rtl8367s_gsw-objs += rtl8367c/trap.o -+rtl8367s_gsw-objs += rtl8367c/trunk.o -+rtl8367s_gsw-objs += rtl8367c/vlan.o -+ -+ccflags-y += -Werror -D_LITTLE_ENDIAN -DMDC_MDIO_OPERATION -+ -+ccflags-y += -Idrivers/net/phy/rtk/rtl8367c/include -+ccflags-y += -Iinclude/linux/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/acl.c b/drivers/net/phy/rtk/rtl8367c/acl.c -new file mode 100644 -index 000000000000..85c12b000ff8 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/acl.c -@@ -0,0 +1,2061 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTK switch high-level API for RTL8367/RTL8367C -+ * Feature : Here is a list of all functions and variables in ACL module. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+CONST_T rtk_uint8 filter_templateField[RTL8367C_ACLTEMPLATENO][RTL8367C_ACLRULEFIELDNO] = { -+ {ACL_DMAC0, ACL_DMAC1, ACL_DMAC2, ACL_SMAC0, ACL_SMAC1, ACL_SMAC2, ACL_ETHERTYPE, ACL_FIELD_SELECT15}, -+ {ACL_IP4SIP0, ACL_IP4SIP1, ACL_IP4DIP0, ACL_IP4DIP1, ACL_FIELD_SELECT13, ACL_FIELD_SELECT14, ACL_FIELD_SELECT02, ACL_FIELD_SELECT15}, -+ {ACL_IP6SIP0WITHIPV4, ACL_IP6SIP1WITHIPV4,ACL_FIELD_SELECT03, ACL_FIELD_SELECT04, ACL_FIELD_SELECT05, ACL_FIELD_SELECT06, ACL_FIELD_SELECT07, ACL_FIELD_SELECT08}, -+ {ACL_IP6DIP0WITHIPV4, ACL_IP6DIP1WITHIPV4,ACL_FIELD_SELECT09, ACL_FIELD_SELECT10, ACL_FIELD_SELECT11, ACL_FIELD_SELECT12, ACL_FIELD_SELECT13, ACL_FIELD_SELECT14}, -+ {ACL_VIDRANGE, ACL_IPRANGE, ACL_PORTRANGE, ACL_CTAG, ACL_STAG, ACL_FIELD_SELECT13, ACL_FIELD_SELECT14, ACL_FIELD_SELECT15} -+}; -+ -+CONST_T rtk_uint8 filter_advanceCaretagField[RTL8367C_ACLTEMPLATENO][2] = { -+ {TRUE, 7}, -+ {TRUE, 7}, -+ {FALSE, 0}, -+ {FALSE, 0}, -+ {TRUE, 7}, -+}; -+ -+ -+CONST_T rtk_uint8 filter_fieldTemplateIndex[FILTER_FIELD_END][RTK_FILTER_FIELD_USED_MAX] = { -+ {0x00, 0x01,0x02}, -+ {0x03, 0x04,0x05}, -+ {0x06}, -+ {0x43}, -+ {0x44}, -+ {0x10, 0x11}, -+ {0x12, 0x13}, -+ {0x24}, -+ {0x25}, -+ {0x35}, -+ {0x35}, -+ {0x20, 0x21,0x22,0x23}, -+ {0x30, 0x31,0x32,0x33}, -+ {0x26}, -+ {0x27}, -+ {0x14}, -+ {0x15}, -+ {0x16}, -+ {0x14}, -+ {0x15}, -+ {0x14}, -+ {0x14}, -+ {0x14}, -+ -+ {0x40}, -+ {0x41}, -+ {0x42}, -+ -+ {0x14}, -+ {0x15}, -+ {0x16}, -+ {0x22}, -+ {0x23}, -+ {0x24}, -+ {0x25}, -+ {0x26}, -+ {0x27}, -+ {0x32}, -+ {0x33}, -+ {0x34}, -+ {0x35}, -+ {0x36}, -+ {0x37}, -+ {0x47}, -+ -+ {0xFF} /* Pattern Match */ -+}; -+ -+CONST_T rtk_uint8 filter_fieldSize[FILTER_FIELD_END] = { -+ 3, 3, 1, 1, 1, -+ 2, 2, 1, 1, 1, 1, 4, 4, 1, 1, -+ 1, 1, 1, 1, 1, 1, 1, 1, -+ 1, 1, 1, -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -+ 8 -+}; -+ -+CONST_T rtk_uint16 field_selector[RTL8367C_FIELDSEL_FORMAT_NUMBER][2] = -+{ -+ {FIELDSEL_FORMAT_DEFAULT, 0}, /* Field Selector 0 */ -+ {FIELDSEL_FORMAT_DEFAULT, 0}, /* Field Selector 1 */ -+ {FIELDSEL_FORMAT_IPPAYLOAD, 12}, /* Field Selector 2 */ -+ {FIELDSEL_FORMAT_IPV6, 10}, /* Field Selector 3 */ -+ {FIELDSEL_FORMAT_IPV6, 8}, /* Field Selector 4 */ -+ {FIELDSEL_FORMAT_IPV4, 0}, /* Field Selector 5 */ -+ {FIELDSEL_FORMAT_IPV4, 8}, /* Field Selector 6 */ -+ {FIELDSEL_FORMAT_IPV6, 0}, /* Field Selector 7 */ -+ {FIELDSEL_FORMAT_IPV6, 6}, /* Field Selector 8 */ -+ {FIELDSEL_FORMAT_IPV6, 26}, /* Field Selector 9 */ -+ {FIELDSEL_FORMAT_IPV6, 24}, /* Field Selector 10 */ -+ {FIELDSEL_FORMAT_DEFAULT, 0}, /* Field Selector 11 */ -+ {FIELDSEL_FORMAT_IPV4, 6}, /* Field Selector 12 */ -+ {FIELDSEL_FORMAT_IPPAYLOAD, 0}, /* Field Selector 13 */ -+ {FIELDSEL_FORMAT_IPPAYLOAD, 2}, /* Field Selector 14 */ -+ {FIELDSEL_FORMAT_DEFAULT, 0} /* Field Selector 15 */ -+}; -+ -+ -+static rtk_api_ret_t _rtk_filter_igrAcl_writeDataField(rtl8367c_aclrule *aclRule, rtk_filter_field_t *fieldPtr); -+ -+ -+/* Function Name: -+ * rtk_filter_igrAcl_init -+ * Description: -+ * ACL initialization function -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL. -+ * Note: -+ * This function enable and initialize ACL function -+ */ -+rtk_api_ret_t rtk_filter_igrAcl_init(void) -+{ -+ rtl8367c_acltemplate_t aclTemp; -+ rtk_uint32 i, j; -+ rtk_api_ret_t ret; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if ((ret = rtk_filter_igrAcl_cfg_delAll()) != RT_ERR_OK) -+ return ret; -+ -+ for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++) -+ { -+ for(j = 0; j < RTL8367C_ACLRULEFIELDNO;j++) -+ aclTemp.field[j] = filter_templateField[i][j]; -+ -+ if ((ret = rtl8367c_setAsicAclTemplate(i, &aclTemp)) != RT_ERR_OK) -+ return ret; -+ } -+ -+ for(i = 0; i < RTL8367C_FIELDSEL_FORMAT_NUMBER; i++) -+ { -+ if ((ret = rtl8367c_setAsicFieldSelector(i, field_selector[i][0], field_selector[i][1])) != RT_ERR_OK) -+ return ret; -+ } -+ -+ RTK_SCAN_ALL_PHY_PORTMASK(i) -+ { -+ if ((ret = rtl8367c_setAsicAcl(i, TRUE)) != RT_ERR_OK) -+ return ret; -+ -+ if ((ret = rtl8367c_setAsicAclUnmatchedPermit(i, TRUE)) != RT_ERR_OK) -+ return ret; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_filter_igrAcl_field_add -+ * Description: -+ * Add comparison rule to an ACL configuration -+ * Input: -+ * pFilter_cfg - The ACL configuration that this function will add comparison rule -+ * pFilter_field - The comparison rule that will be added. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This function add a comparison rule (*pFilter_field) to an ACL configuration (*pFilter_cfg). -+ * Pointer pFilter_cfg points to an ACL configuration structure, this structure keeps multiple ACL -+ * comparison rules by means of linked list. Pointer pFilter_field will be added to linked -+ * list kept by structure that pFilter_cfg points to. -+ */ -+rtk_api_ret_t rtk_filter_igrAcl_field_add(rtk_filter_cfg_t* pFilter_cfg, rtk_filter_field_t* pFilter_field) -+{ -+ rtk_uint32 i; -+ rtk_filter_field_t *tailPtr; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pFilter_cfg || NULL == pFilter_field) -+ return RT_ERR_NULL_POINTER; -+ -+ if(pFilter_field->fieldType >= FILTER_FIELD_END) -+ return RT_ERR_ENTRY_INDEX; -+ -+ -+ if(0 == pFilter_field->fieldTemplateNo) -+ { -+ pFilter_field->fieldTemplateNo = filter_fieldSize[pFilter_field->fieldType]; -+ -+ for(i = 0; i < pFilter_field->fieldTemplateNo; i++) -+ { -+ pFilter_field->fieldTemplateIdx[i] = filter_fieldTemplateIndex[pFilter_field->fieldType][i]; -+ } -+ } -+ -+ if(NULL == pFilter_cfg->fieldHead) -+ { -+ pFilter_cfg->fieldHead = pFilter_field; -+ } -+ else -+ { -+ if (pFilter_cfg->fieldHead->next == NULL) -+ { -+ pFilter_cfg->fieldHead->next = pFilter_field; -+ } -+ else -+ { -+ tailPtr = pFilter_cfg->fieldHead->next; -+ while( tailPtr->next != NULL) -+ { -+ tailPtr = tailPtr->next; -+ } -+ tailPtr->next = pFilter_field; -+ } -+ } -+ -+ return RT_ERR_OK; -+} -+ -+static rtk_api_ret_t _rtk_filter_igrAcl_writeDataField(rtl8367c_aclrule *aclRule, rtk_filter_field_t *fieldPtr) -+{ -+ rtk_uint32 i, tempIdx,fieldIdx, ipValue, ipMask; -+ rtk_uint32 ip6addr[RTK_IPV6_ADDR_WORD_LENGTH]; -+ rtk_uint32 ip6mask[RTK_IPV6_ADDR_WORD_LENGTH]; -+ -+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) -+ { -+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; -+ -+ aclRule[tempIdx].valid = TRUE; -+ } -+ -+ switch (fieldPtr->fieldType) -+ { -+ /* use DMAC structure as representative for mac structure */ -+ case FILTER_FIELD_DMAC: -+ case FILTER_FIELD_SMAC: -+ -+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) -+ { -+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; -+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; -+ -+ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.mac.value.octet[5 - i*2] | (fieldPtr->filter_pattern_union.mac.value.octet[5 - (i*2 + 1)] << 8); -+ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.mac.mask.octet[5 - i*2] | (fieldPtr->filter_pattern_union.mac.mask.octet[5 - (i*2 + 1)] << 8); -+ } -+ break; -+ case FILTER_FIELD_ETHERTYPE: -+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) -+ { -+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; -+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; -+ -+ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.etherType.value; -+ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.etherType.mask; -+ } -+ break; -+ case FILTER_FIELD_IPV4_SIP: -+ case FILTER_FIELD_IPV4_DIP: -+ -+ ipValue = fieldPtr->filter_pattern_union.sip.value; -+ ipMask = fieldPtr->filter_pattern_union.sip.mask; -+ -+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) -+ { -+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; -+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; -+ -+ aclRule[tempIdx].data_bits.field[fieldIdx] = (0xFFFF & (ipValue >> (i*16))); -+ aclRule[tempIdx].care_bits.field[fieldIdx] = (0xFFFF & (ipMask >> (i*16))); -+ } -+ break; -+ case FILTER_FIELD_IPV4_TOS: -+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) -+ { -+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; -+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; -+ -+ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.ipTos.value & 0xFF; -+ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.ipTos.mask & 0xFF; -+ } -+ break; -+ case FILTER_FIELD_IPV4_PROTOCOL: -+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) -+ { -+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; -+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; -+ -+ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.protocol.value & 0xFF; -+ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.protocol.mask & 0xFF; -+ } -+ break; -+ case FILTER_FIELD_IPV6_SIPV6: -+ case FILTER_FIELD_IPV6_DIPV6: -+ for(i = 0; i < RTK_IPV6_ADDR_WORD_LENGTH; i++) -+ { -+ ip6addr[i] = fieldPtr->filter_pattern_union.sipv6.value.addr[i]; -+ ip6mask[i] = fieldPtr->filter_pattern_union.sipv6.mask.addr[i]; -+ } -+ -+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) -+ { -+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; -+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; -+ -+ if(i < 2) -+ { -+ aclRule[tempIdx].data_bits.field[fieldIdx] = ((ip6addr[0] & (0xFFFF << (i * 16))) >> (i * 16)); -+ aclRule[tempIdx].care_bits.field[fieldIdx] = ((ip6mask[0] & (0xFFFF << (i * 16))) >> (i * 16)); -+ } -+ else -+ { -+ /*default ACL template for ipv6 address supports MSB 32-bits and LSB 32-bits only*/ -+ aclRule[tempIdx].data_bits.field[fieldIdx] = ((ip6addr[3] & (0xFFFF << ((i&1) * 16))) >> ((i&1) * 16)); -+ aclRule[tempIdx].care_bits.field[fieldIdx] = ((ip6mask[3] & (0xFFFF << ((i&1) * 16))) >> ((i&1) * 16)); -+ } -+ } -+ -+ break; -+ case FILTER_FIELD_CTAG: -+ case FILTER_FIELD_STAG: -+ -+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) -+ { -+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; -+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; -+ -+ aclRule[tempIdx].data_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.l2tag.pri.value << 13) | (fieldPtr->filter_pattern_union.l2tag.cfi.value << 12) | fieldPtr->filter_pattern_union.l2tag.vid.value; -+ aclRule[tempIdx].care_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.l2tag.pri.mask << 13) | (fieldPtr->filter_pattern_union.l2tag.cfi.mask << 12) | fieldPtr->filter_pattern_union.l2tag.vid.mask; -+ } -+ break; -+ case FILTER_FIELD_IPV4_FLAG: -+ -+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) -+ { -+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; -+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; -+ -+ aclRule[tempIdx].data_bits.field[fieldIdx] &= 0x1FFF; -+ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.xf.value << 15); -+ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.df.value << 14); -+ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.mf.value << 13); -+ -+ aclRule[tempIdx].care_bits.field[fieldIdx] &= 0x1FFF; -+ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.xf.mask << 15); -+ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.df.mask << 14); -+ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.mf.mask << 13); -+ } -+ -+ break; -+ case FILTER_FIELD_IPV4_OFFSET: -+ -+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) -+ { -+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; -+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; -+ -+ aclRule[tempIdx].data_bits.field[fieldIdx] &= 0xE000; -+ aclRule[tempIdx].data_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.inData.value; -+ -+ aclRule[tempIdx].care_bits.field[fieldIdx] &= 0xE000; -+ aclRule[tempIdx].care_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.inData.mask; -+ } -+ -+ break; -+ -+ case FILTER_FIELD_IPV6_TRAFFIC_CLASS: -+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) -+ { -+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; -+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; -+ -+ -+ aclRule[tempIdx].data_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.inData.value << 4)&0x0FF0; -+ aclRule[tempIdx].care_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.inData.mask << 4)&0x0FF0; -+ } -+ break; -+ case FILTER_FIELD_IPV6_NEXT_HEADER: -+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) -+ { -+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; -+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; -+ -+ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.inData.value << 8; -+ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.inData.mask << 8; -+ } -+ break; -+ case FILTER_FIELD_TCP_SPORT: -+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) -+ { -+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; -+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; -+ -+ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.tcpSrcPort.value; -+ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.tcpSrcPort.mask; -+ } -+ break; -+ case FILTER_FIELD_TCP_DPORT: -+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) -+ { -+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; -+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; -+ -+ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.tcpDstPort.value; -+ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.tcpDstPort.mask; -+ } -+ break; -+ case FILTER_FIELD_TCP_FLAG: -+ -+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) -+ { -+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; -+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; -+ -+ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.cwr.value << 7); -+ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.ece.value << 6); -+ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.urg.value << 5); -+ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.ack.value << 4); -+ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.psh.value << 3); -+ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.rst.value << 2); -+ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.syn.value << 1); -+ aclRule[tempIdx].data_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.tcpFlag.fin.value; -+ -+ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.cwr.mask << 7); -+ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.ece.mask << 6); -+ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.urg.mask << 5); -+ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.ack.mask << 4); -+ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.psh.mask << 3); -+ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.rst.mask << 2); -+ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.syn.mask << 1); -+ aclRule[tempIdx].care_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.tcpFlag.fin.mask; -+ } -+ break; -+ case FILTER_FIELD_UDP_SPORT: -+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) -+ { -+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; -+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; -+ -+ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.udpSrcPort.value; -+ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.udpSrcPort.mask; -+ } -+ break; -+ case FILTER_FIELD_UDP_DPORT: -+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) -+ { -+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; -+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; -+ -+ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.udpDstPort.value; -+ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.udpDstPort.mask; -+ } -+ break; -+ case FILTER_FIELD_ICMP_CODE: -+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) -+ { -+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; -+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; -+ -+ aclRule[tempIdx].data_bits.field[fieldIdx] &= 0xFF00; -+ aclRule[tempIdx].data_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.icmpCode.value; -+ aclRule[tempIdx].care_bits.field[fieldIdx] &= 0xFF00; -+ aclRule[tempIdx].care_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.icmpCode.mask; -+ } -+ break; -+ case FILTER_FIELD_ICMP_TYPE: -+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) -+ { -+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; -+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; -+ -+ aclRule[tempIdx].data_bits.field[fieldIdx] &= 0x00FF; -+ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.icmpType.value << 8); -+ aclRule[tempIdx].care_bits.field[fieldIdx] &= 0x00FF; -+ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.icmpType.mask << 8); -+ } -+ break; -+ case FILTER_FIELD_IGMP_TYPE: -+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) -+ { -+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; -+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; -+ -+ aclRule[tempIdx].data_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.igmpType.value << 8); -+ aclRule[tempIdx].care_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.igmpType.mask << 8); -+ } -+ break; -+ case FILTER_FIELD_PATTERN_MATCH: -+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) -+ { -+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; -+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; -+ -+ aclRule[tempIdx].data_bits.field[fieldIdx] = ((fieldPtr->filter_pattern_union.pattern.value[i/2] >> (16 * (i%2))) & 0x0000FFFF ); -+ aclRule[tempIdx].care_bits.field[fieldIdx] = ((fieldPtr->filter_pattern_union.pattern.mask[i/2] >> (16 * (i%2))) & 0x0000FFFF ); -+ } -+ break; -+ case FILTER_FIELD_VID_RANGE: -+ case FILTER_FIELD_IP_RANGE: -+ case FILTER_FIELD_PORT_RANGE: -+ default: -+ tempIdx = (fieldPtr->fieldTemplateIdx[0] & 0xF0) >> 4; -+ fieldIdx = fieldPtr->fieldTemplateIdx[0] & 0x0F; -+ -+ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.inData.value; -+ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.inData.mask; -+ break; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_filter_igrAcl_cfg_add -+ * Description: -+ * Add an ACL configuration to ASIC -+ * Input: -+ * filter_id - Start index of ACL configuration. -+ * pFilter_cfg - The ACL configuration that this function will add comparison rule -+ * pFilter_action - Action(s) of ACL configuration. -+ * Output: -+ * ruleNum - number of rules written in ACL table -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_ENTRY_INDEX - Invalid filter_id . -+ * RT_ERR_NULL_POINTER - Pointer pFilter_action or pFilter_cfg point to NULL. -+ * RT_ERR_FILTER_INACL_ACT_NOT_SUPPORT - Action is not supported in this chip. -+ * RT_ERR_FILTER_INACL_RULE_NOT_SUPPORT - Rule is not supported. -+ * Note: -+ * This function store pFilter_cfg, pFilter_action into ASIC. The starting -+ * index(es) is filter_id. -+ */ -+rtk_api_ret_t rtk_filter_igrAcl_cfg_add(rtk_filter_id_t filter_id, rtk_filter_cfg_t* pFilter_cfg, rtk_filter_action_t* pFilter_action, rtk_filter_number_t *ruleNum) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 careTagData, careTagMask; -+ rtk_uint32 i,vidx, svidx, actType, ruleId; -+ rtk_uint32 aclActCtrl; -+ rtk_uint32 cpuPort; -+ rtk_filter_field_t* fieldPtr; -+ rtl8367c_aclrule aclRule[RTL8367C_ACLTEMPLATENO]; -+ rtl8367c_aclrule tempRule; -+ rtl8367c_acl_act_t aclAct; -+ rtk_uint32 noRulesAdd; -+ rtk_uint32 portmask; -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(filter_id > RTL8367C_ACLRULEMAX ) -+ return RT_ERR_ENTRY_INDEX; -+ -+ if((NULL == pFilter_cfg) || (NULL == pFilter_action) || (NULL == ruleNum)) -+ return RT_ERR_NULL_POINTER; -+ -+ fieldPtr = pFilter_cfg->fieldHead; -+ -+ /* init RULE */ -+ for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++) -+ { -+ memset(&aclRule[i], 0, sizeof(rtl8367c_aclrule)); -+ -+ aclRule[i].data_bits.type= i; -+ aclRule[i].care_bits.type= 0x7; -+ } -+ -+ while(NULL != fieldPtr) -+ { -+ _rtk_filter_igrAcl_writeDataField(aclRule, fieldPtr); -+ -+ fieldPtr = fieldPtr->next; -+ } -+ -+ /*set care tag mask in User Defined Field 15*/ -+ /*Follow care tag should not be used while ACL template and User defined fields are fully control by system designer*/ -+ /*those advanced packet type care tag is used in default template design structure only*/ -+ careTagData = 0; -+ careTagMask = 0; -+ -+ for(i = CARE_TAG_TCP; i < CARE_TAG_END; i++) -+ { -+ if(pFilter_cfg->careTag.tagType[i].mask) -+ careTagMask = careTagMask | (1 << (i-CARE_TAG_TCP)); -+ -+ if(pFilter_cfg->careTag.tagType[i].value) -+ careTagData = careTagData | (1 << (i-CARE_TAG_TCP)); -+ } -+ -+ if(careTagData || careTagMask) -+ { -+ i = 0; -+ while(i < RTL8367C_ACLTEMPLATENO) -+ { -+ if(aclRule[i].valid == 1 && filter_advanceCaretagField[i][0] == TRUE) -+ { -+ -+ aclRule[i].data_bits.field[filter_advanceCaretagField[i][1]] = careTagData & 0xFFFF; -+ aclRule[i].care_bits.field[filter_advanceCaretagField[i][1]] = careTagMask & 0xFFFF; -+ break; -+ } -+ i++; -+ } -+ /*none of previous used template containing field 15*/ -+ if(i == RTL8367C_ACLTEMPLATENO) -+ { -+ i = 0; -+ while(i < RTL8367C_ACLTEMPLATENO) -+ { -+ if(filter_advanceCaretagField[i][0] == TRUE) -+ { -+ aclRule[i].data_bits.field[filter_advanceCaretagField[i][1]] = careTagData & 0xFFFF; -+ aclRule[i].care_bits.field[filter_advanceCaretagField[i][1]] = careTagMask & 0xFFFF; -+ aclRule[i].valid = 1; -+ break; -+ } -+ i++; -+ } -+ } -+ } -+ -+ /*Check rule number*/ -+ noRulesAdd = 0; -+ for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++) -+ { -+ if(1 == aclRule[i].valid) -+ { -+ noRulesAdd ++; -+ } -+ } -+ -+ *ruleNum = noRulesAdd; -+ -+ if((filter_id + noRulesAdd - 1) > RTL8367C_ACLRULEMAX) -+ { -+ return RT_ERR_ENTRY_INDEX; -+ } -+ -+ /*set care tag mask in TAG Indicator*/ -+ careTagData = 0; -+ careTagMask = 0; -+ -+ for(i = 0; i <= CARE_TAG_IPV6;i++) -+ { -+ if(0 == pFilter_cfg->careTag.tagType[i].mask ) -+ { -+ careTagMask &= ~(1 << i); -+ } -+ else -+ { -+ careTagMask |= (1 << i); -+ if(0 == pFilter_cfg->careTag.tagType[i].value ) -+ careTagData &= ~(1 << i); -+ else -+ careTagData |= (1 << i); -+ } -+ } -+ -+ for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++) -+ { -+ aclRule[i].data_bits.tag_exist = (careTagData) & ACL_RULE_CARETAG_MASK; -+ aclRule[i].care_bits.tag_exist = (careTagMask) & ACL_RULE_CARETAG_MASK; -+ } -+ -+ RTK_CHK_PORTMASK_VALID(&pFilter_cfg->activeport.value); -+ RTK_CHK_PORTMASK_VALID(&pFilter_cfg->activeport.mask); -+ -+ for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++) -+ { -+ if(TRUE == aclRule[i].valid) -+ { -+ if(rtk_switch_portmask_L2P_get(&pFilter_cfg->activeport.value, &portmask) != RT_ERR_OK) -+ return RT_ERR_PORT_MASK; -+ -+ aclRule[i].data_bits.active_portmsk = portmask; -+ -+ if(rtk_switch_portmask_L2P_get(&pFilter_cfg->activeport.mask, &portmask) != RT_ERR_OK) -+ return RT_ERR_PORT_MASK; -+ -+ aclRule[i].care_bits.active_portmsk = portmask; -+ } -+ } -+ -+ if(pFilter_cfg->invert >= FILTER_INVERT_END ) -+ return RT_ERR_INPUT; -+ -+ -+ /*Last action gets high priority if actions are the same*/ -+ memset(&aclAct, 0, sizeof(rtl8367c_acl_act_t)); -+ aclActCtrl = 0; -+ for(actType = 0; actType < FILTER_ENACT_END; actType ++) -+ { -+ if(pFilter_action->actEnable[actType]) -+ { -+ switch (actType) -+ { -+ case FILTER_ENACT_CVLAN_INGRESS: -+ if(pFilter_action->filterCvlanVid > RTL8367C_EVIDMAX) -+ return RT_ERR_INPUT; -+ -+ if((retVal = rtk_vlan_checkAndCreateMbr(pFilter_action->filterCvlanVid, &vidx)) != RT_ERR_OK) -+ { -+ return retVal; -+ } -+ aclAct.cact = FILTER_ENACT_CVLAN_TYPE(actType); -+ aclAct.cvidx_cact = vidx; -+ -+ if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) -+ { -+ if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_TAGONLY) -+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; -+ } -+ else -+ { -+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_VLANONLY; -+ } -+ -+ aclActCtrl |= FILTER_ENACT_CVLAN_MASK; -+ break; -+ case FILTER_ENACT_CVLAN_EGRESS: -+ if(pFilter_action->filterCvlanVid > RTL8367C_EVIDMAX) -+ return RT_ERR_INPUT; -+ -+ if((retVal = rtk_vlan_checkAndCreateMbr(pFilter_action->filterCvlanVid, &vidx)) != RT_ERR_OK) -+ return retVal; -+ -+ aclAct.cact = FILTER_ENACT_CVLAN_TYPE(actType); -+ aclAct.cvidx_cact = vidx; -+ -+ if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) -+ { -+ if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_TAGONLY) -+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; -+ } -+ else -+ { -+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_VLANONLY; -+ } -+ -+ aclActCtrl |= FILTER_ENACT_CVLAN_MASK; -+ break; -+ case FILTER_ENACT_CVLAN_SVID: -+ -+ aclAct.cact = FILTER_ENACT_CVLAN_TYPE(actType); -+ -+ if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) -+ { -+ if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_TAGONLY) -+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; -+ } -+ else -+ { -+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_VLANONLY; -+ } -+ -+ aclActCtrl |= FILTER_ENACT_CVLAN_MASK; -+ break; -+ case FILTER_ENACT_POLICING_1: -+ if(pFilter_action->filterPolicingIdx[1] >= (RTK_METER_NUM + RTL8367C_MAX_LOG_CNT_NUM)) -+ return RT_ERR_INPUT; -+ -+ aclAct.cact = FILTER_ENACT_CVLAN_TYPE(actType); -+ aclAct.cvidx_cact = pFilter_action->filterPolicingIdx[1]; -+ -+ if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) -+ { -+ if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_TAGONLY) -+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; -+ } -+ else -+ { -+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_VLANONLY; -+ } -+ -+ aclActCtrl |= FILTER_ENACT_CVLAN_MASK; -+ break; -+ -+ case FILTER_ENACT_SVLAN_INGRESS: -+ case FILTER_ENACT_SVLAN_EGRESS: -+ -+ if((retVal = rtk_svlan_checkAndCreateMbr(pFilter_action->filterSvlanVid, &svidx)) != RT_ERR_OK) -+ return retVal; -+ -+ aclAct.sact = FILTER_ENACT_SVLAN_TYPE(actType); -+ aclAct.svidx_sact = svidx; -+ aclActCtrl |= FILTER_ENACT_SVLAN_MASK; -+ break; -+ case FILTER_ENACT_SVLAN_CVID: -+ -+ aclAct.sact = FILTER_ENACT_SVLAN_TYPE(actType); -+ aclActCtrl |= FILTER_ENACT_SVLAN_MASK; -+ break; -+ case FILTER_ENACT_POLICING_2: -+ if(pFilter_action->filterPolicingIdx[2] >= (RTK_METER_NUM + RTL8367C_MAX_LOG_CNT_NUM)) -+ return RT_ERR_INPUT; -+ -+ aclAct.sact = FILTER_ENACT_SVLAN_TYPE(actType); -+ aclAct.svidx_sact = pFilter_action->filterPolicingIdx[2]; -+ aclActCtrl |= FILTER_ENACT_SVLAN_MASK; -+ break; -+ case FILTER_ENACT_POLICING_0: -+ if(pFilter_action->filterPolicingIdx[0] >= (RTK_METER_NUM + RTL8367C_MAX_LOG_CNT_NUM)) -+ return RT_ERR_INPUT; -+ -+ aclAct.aclmeteridx = pFilter_action->filterPolicingIdx[0]; -+ aclActCtrl |= FILTER_ENACT_POLICING_MASK; -+ break; -+ case FILTER_ENACT_PRIORITY: -+ case FILTER_ENACT_1P_REMARK: -+ if(pFilter_action->filterPriority > RTL8367C_PRIMAX) -+ return RT_ERR_INPUT; -+ -+ aclAct.priact = FILTER_ENACT_PRI_TYPE(actType); -+ aclAct.pridx = pFilter_action->filterPriority; -+ aclActCtrl |= FILTER_ENACT_PRIORITY_MASK; -+ break; -+ case FILTER_ENACT_DSCP_REMARK: -+ if(pFilter_action->filterPriority > RTL8367C_DSCPMAX) -+ return RT_ERR_INPUT; -+ -+ aclAct.priact = FILTER_ENACT_PRI_TYPE(actType); -+ aclAct.pridx = pFilter_action->filterPriority; -+ aclActCtrl |= FILTER_ENACT_PRIORITY_MASK; -+ break; -+ case FILTER_ENACT_POLICING_3: -+ if(pFilter_action->filterPriority >= (RTK_METER_NUM + RTL8367C_MAX_LOG_CNT_NUM)) -+ return RT_ERR_INPUT; -+ -+ aclAct.priact = FILTER_ENACT_PRI_TYPE(actType); -+ aclAct.pridx = pFilter_action->filterPolicingIdx[3]; -+ aclActCtrl |= FILTER_ENACT_PRIORITY_MASK; -+ break; -+ case FILTER_ENACT_DROP: -+ -+ aclAct.fwdact = FILTER_ENACT_FWD_TYPE(FILTER_ENACT_REDIRECT); -+ aclAct.fwdact_ext = FALSE; -+ -+ aclAct.fwdpmask = 0; -+ aclActCtrl |= FILTER_ENACT_FWD_MASK; -+ break; -+ case FILTER_ENACT_REDIRECT: -+ RTK_CHK_PORTMASK_VALID(&pFilter_action->filterPortmask); -+ -+ aclAct.fwdact = FILTER_ENACT_FWD_TYPE(actType); -+ aclAct.fwdact_ext = FALSE; -+ -+ if(rtk_switch_portmask_L2P_get(&pFilter_action->filterPortmask, &portmask) != RT_ERR_OK) -+ return RT_ERR_PORT_MASK; -+ aclAct.fwdpmask = portmask; -+ -+ aclActCtrl |= FILTER_ENACT_FWD_MASK; -+ break; -+ -+ case FILTER_ENACT_ADD_DSTPORT: -+ RTK_CHK_PORTMASK_VALID(&pFilter_action->filterPortmask); -+ -+ aclAct.fwdact = FILTER_ENACT_FWD_TYPE(actType); -+ aclAct.fwdact_ext = FALSE; -+ -+ if(rtk_switch_portmask_L2P_get(&pFilter_action->filterPortmask, &portmask) != RT_ERR_OK) -+ return RT_ERR_PORT_MASK; -+ aclAct.fwdpmask = portmask; -+ -+ aclActCtrl |= FILTER_ENACT_FWD_MASK; -+ break; -+ case FILTER_ENACT_MIRROR: -+ RTK_CHK_PORTMASK_VALID(&pFilter_action->filterPortmask); -+ -+ aclAct.fwdact = FILTER_ENACT_FWD_TYPE(actType); -+ aclAct.cact_ext = FALSE; -+ -+ if(rtk_switch_portmask_L2P_get(&pFilter_action->filterPortmask, &portmask) != RT_ERR_OK) -+ return RT_ERR_PORT_MASK; -+ aclAct.fwdpmask = portmask; -+ -+ aclActCtrl |= FILTER_ENACT_FWD_MASK; -+ break; -+ case FILTER_ENACT_TRAP_CPU: -+ -+ aclAct.fwdact = FILTER_ENACT_FWD_TYPE(actType); -+ aclAct.fwdact_ext = FALSE; -+ -+ aclActCtrl |= FILTER_ENACT_FWD_MASK; -+ break; -+ case FILTER_ENACT_COPY_CPU: -+ if((retVal = rtl8367c_getAsicCputagTrapPort(&cpuPort)) != RT_ERR_OK) -+ return retVal; -+ -+ aclAct.fwdact = FILTER_ENACT_FWD_TYPE(FILTER_ENACT_MIRROR); -+ aclAct.fwdact_ext = FALSE; -+ -+ aclAct.fwdpmask = 1 << cpuPort; -+ aclActCtrl |= FILTER_ENACT_FWD_MASK; -+ break; -+ case FILTER_ENACT_ISOLATION: -+ RTK_CHK_PORTMASK_VALID(&pFilter_action->filterPortmask); -+ -+ aclAct.fwdact_ext = TRUE; -+ -+ if(rtk_switch_portmask_L2P_get(&pFilter_action->filterPortmask, &portmask) != RT_ERR_OK) -+ return RT_ERR_PORT_MASK; -+ aclAct.fwdpmask = portmask; -+ -+ aclActCtrl |= FILTER_ENACT_FWD_MASK; -+ break; -+ -+ case FILTER_ENACT_INTERRUPT: -+ -+ aclAct.aclint = TRUE; -+ aclActCtrl |= FILTER_ENACT_INTGPIO_MASK; -+ break; -+ case FILTER_ENACT_GPO: -+ -+ aclAct.gpio_en = TRUE; -+ aclAct.gpio_pin = pFilter_action->filterPin; -+ aclActCtrl |= FILTER_ENACT_INTGPIO_MASK; -+ break; -+ case FILTER_ENACT_EGRESSCTAG_TAG: -+ -+ if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) -+ { -+ if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_VLANONLY) -+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; -+ } -+ else -+ { -+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_TAGONLY; -+ } -+ aclAct.tag_fmt = FILTER_CTAGFMT_TAG; -+ aclActCtrl |= FILTER_ENACT_CVLAN_MASK; -+ break; -+ case FILTER_ENACT_EGRESSCTAG_UNTAG: -+ -+ if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) -+ { -+ if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_VLANONLY) -+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; -+ } -+ else -+ { -+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_TAGONLY; -+ } -+ aclAct.tag_fmt = FILTER_CTAGFMT_UNTAG; -+ aclActCtrl |= FILTER_ENACT_CVLAN_MASK; -+ break; -+ case FILTER_ENACT_EGRESSCTAG_KEEP: -+ -+ if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) -+ { -+ if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_VLANONLY) -+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; -+ } -+ else -+ { -+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_TAGONLY; -+ } -+ aclAct.tag_fmt = FILTER_CTAGFMT_KEEP; -+ aclActCtrl |= FILTER_ENACT_CVLAN_MASK; -+ break; -+ case FILTER_ENACT_EGRESSCTAG_KEEPAND1PRMK: -+ -+ if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) -+ { -+ if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_VLANONLY) -+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; -+ } -+ else -+ { -+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_TAGONLY; -+ } -+ aclAct.tag_fmt = FILTER_CTAGFMT_KEEP1PRMK; -+ aclActCtrl |= FILTER_ENACT_CVLAN_MASK; -+ break; -+ default: -+ return RT_ERR_FILTER_INACL_ACT_NOT_SUPPORT; -+ } -+ } -+ } -+ -+ -+ /*check if free ACL rules are enough*/ -+ for(i = filter_id; i < (filter_id + noRulesAdd); i++) -+ { -+ if((retVal = rtl8367c_getAsicAclRule(i, &tempRule)) != RT_ERR_OK ) -+ return retVal; -+ -+ if(tempRule.valid == TRUE) -+ { -+ return RT_ERR_TBL_FULL; -+ } -+ } -+ -+ ruleId = 0; -+ for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++) -+ { -+ if(aclRule[i].valid == TRUE) -+ { -+ /* write ACL action control */ -+ if((retVal = rtl8367c_setAsicAclActCtrl(filter_id + ruleId, aclActCtrl)) != RT_ERR_OK ) -+ return retVal; -+ /* write ACL action */ -+ if((retVal = rtl8367c_setAsicAclAct(filter_id + ruleId, &aclAct)) != RT_ERR_OK ) -+ return retVal; -+ -+ /* write ACL not */ -+ if((retVal = rtl8367c_setAsicAclNot(filter_id + ruleId, pFilter_cfg->invert)) != RT_ERR_OK ) -+ return retVal; -+ /* write ACL rule */ -+ if((retVal = rtl8367c_setAsicAclRule(filter_id + ruleId, &aclRule[i])) != RT_ERR_OK ) -+ return retVal; -+ -+ /* only the first rule will be written with input action control, aclActCtrl of other rules will be zero */ -+ aclActCtrl = 0; -+ memset(&aclAct, 0, sizeof(rtl8367c_acl_act_t)); -+ -+ ruleId ++; -+ } -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_filter_igrAcl_cfg_del -+ * Description: -+ * Delete an ACL configuration from ASIC -+ * Input: -+ * filter_id - Start index of ACL configuration. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_FILTER_ENTRYIDX - Invalid filter_id. -+ * Note: -+ * This function delete a group of ACL rules starting from filter_id. -+ */ -+rtk_api_ret_t rtk_filter_igrAcl_cfg_del(rtk_filter_id_t filter_id) -+{ -+ rtl8367c_aclrule initRule; -+ rtl8367c_acl_act_t initAct; -+ rtk_api_ret_t ret; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(filter_id > RTL8367C_ACLRULEMAX ) -+ return RT_ERR_FILTER_ENTRYIDX; -+ -+ memset(&initRule, 0, sizeof(rtl8367c_aclrule)); -+ memset(&initAct, 0, sizeof(rtl8367c_acl_act_t)); -+ -+ if((ret = rtl8367c_setAsicAclRule(filter_id, &initRule)) != RT_ERR_OK) -+ return ret; -+ if((ret = rtl8367c_setAsicAclActCtrl(filter_id, FILTER_ENACT_INIT_MASK))!= RT_ERR_OK) -+ return ret; -+ if((ret = rtl8367c_setAsicAclAct(filter_id, &initAct)) != RT_ERR_OK) -+ return ret; -+ if((ret = rtl8367c_setAsicAclNot(filter_id, DISABLED)) != RT_ERR_OK ) -+ return ret; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_filter_igrAcl_cfg_delAll -+ * Description: -+ * Delete all ACL entries from ASIC -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * This function delete all ACL configuration from ASIC. -+ */ -+rtk_api_ret_t rtk_filter_igrAcl_cfg_delAll(void) -+{ -+ rtk_uint32 i; -+ rtk_api_ret_t ret; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ for(i = 0; i < RTL8367C_ACLRULENO; i++) -+ { -+ if((ret = rtl8367c_setAsicAclActCtrl(i, FILTER_ENACT_INIT_MASK))!= RT_ERR_OK) -+ return ret; -+ if((ret = rtl8367c_setAsicAclNot(i, DISABLED)) != RT_ERR_OK ) -+ return ret; -+ } -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_ACL_RESET_CFG, RTL8367C_ACL_RESET_CFG_OFFSET, TRUE);; -+} -+ -+/* Function Name: -+ * rtk_filter_igrAcl_cfg_get -+ * Description: -+ * Get one ingress ACL configuration from ASIC. -+ * Input: -+ * filter_id - Start index of ACL configuration. -+ * Output: -+ * pFilter_cfg - buffer pointer of ingress ACL data -+ * pFilter_action - buffer pointer of ingress ACL action -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Pointer pFilter_action or pFilter_cfg point to NULL. -+ * RT_ERR_FILTER_ENTRYIDX - Invalid entry index. -+ * Note: -+ * This function get configuration from ASIC. -+ */ -+rtk_api_ret_t rtk_filter_igrAcl_cfg_get(rtk_filter_id_t filter_id, rtk_filter_cfg_raw_t *pFilter_cfg, rtk_filter_action_t *pAction) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 i, tmp; -+ rtl8367c_aclrule aclRule; -+ rtl8367c_acl_act_t aclAct; -+ rtk_uint32 cpuPort; -+ rtl8367c_acltemplate_t type; -+ rtl8367c_svlan_memconf_t svlan_cfg; -+ rtl8367c_vlanconfiguser vlanMC; -+ rtk_uint32 phyPmask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pFilter_cfg || NULL == pAction) -+ return RT_ERR_NULL_POINTER; -+ -+ if(filter_id > RTL8367C_ACLRULEMAX) -+ return RT_ERR_ENTRY_INDEX; -+ -+ if ((retVal = rtl8367c_getAsicAclRule(filter_id, &aclRule)) != RT_ERR_OK) -+ return retVal; -+ -+ /* Check valid */ -+ if(aclRule.valid == 0) -+ { -+ pFilter_cfg->valid = DISABLED; -+ return RT_ERR_OK; -+ } -+ -+ phyPmask = aclRule.data_bits.active_portmsk; -+ if(rtk_switch_portmask_P2L_get(phyPmask,&(pFilter_cfg->activeport.value)) != RT_ERR_OK) -+ return RT_ERR_FAILED; -+ -+ phyPmask = aclRule.care_bits.active_portmsk; -+ if(rtk_switch_portmask_P2L_get(phyPmask,&(pFilter_cfg->activeport.mask)) != RT_ERR_OK) -+ return RT_ERR_FAILED; -+ -+ for(i = 0; i <= CARE_TAG_IPV6; i++) -+ { -+ if(aclRule.data_bits.tag_exist & (1 << i)) -+ pFilter_cfg->careTag.tagType[i].value = 1; -+ else -+ pFilter_cfg->careTag.tagType[i].value = 0; -+ -+ if (aclRule.care_bits.tag_exist & (1 << i)) -+ pFilter_cfg->careTag.tagType[i].mask = 1; -+ else -+ pFilter_cfg->careTag.tagType[i].mask = 0; -+ } -+ -+ if(filter_advanceCaretagField[aclRule.data_bits.type][0] == TRUE) -+ { -+ /* Advanced Care tag setting */ -+ for(i = CARE_TAG_TCP; i < CARE_TAG_END; i++) -+ { -+ if(aclRule.data_bits.field[filter_advanceCaretagField[aclRule.data_bits.type][1]] & (0x0001 << (i-CARE_TAG_TCP)) ) -+ pFilter_cfg->careTag.tagType[i].value = 1; -+ else -+ pFilter_cfg->careTag.tagType[i].value = 0; -+ -+ if(aclRule.care_bits.field[filter_advanceCaretagField[aclRule.care_bits.type][1]] & (0x0001 << (i-CARE_TAG_TCP)) ) -+ pFilter_cfg->careTag.tagType[i].mask = 1; -+ else -+ pFilter_cfg->careTag.tagType[i].mask = 0; -+ } -+ } -+ -+ for(i = 0; i < RTL8367C_ACLRULEFIELDNO; i++) -+ { -+ pFilter_cfg->careFieldRaw[i] = aclRule.care_bits.field[i]; -+ pFilter_cfg->dataFieldRaw[i] = aclRule.data_bits.field[i]; -+ } -+ -+ if ((retVal = rtl8367c_getAsicAclNot(filter_id, &tmp))!= RT_ERR_OK) -+ return retVal; -+ -+ pFilter_cfg->invert = tmp; -+ -+ pFilter_cfg->valid = aclRule.valid; -+ -+ memset(pAction, 0, sizeof(rtk_filter_action_t)); -+ -+ if ((retVal = rtl8367c_getAsicAclActCtrl(filter_id, &tmp))!= RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicAclAct(filter_id, &aclAct)) != RT_ERR_OK) -+ return retVal; -+ -+ if(tmp & FILTER_ENACT_FWD_MASK) -+ { -+ if(TRUE == aclAct.fwdact_ext) -+ { -+ pAction->actEnable[FILTER_ENACT_ISOLATION] = TRUE; -+ -+ phyPmask = aclAct.fwdpmask; -+ if(rtk_switch_portmask_P2L_get(phyPmask,&(pAction->filterPortmask)) != RT_ERR_OK) -+ return RT_ERR_FAILED; -+ } -+ else if(aclAct.fwdact == RTL8367C_ACL_FWD_TRAP) -+ { -+ pAction->actEnable[FILTER_ENACT_TRAP_CPU] = TRUE; -+ } -+ else if (aclAct.fwdact == RTL8367C_ACL_FWD_MIRRORFUNTION ) -+ { -+ pAction->actEnable[FILTER_ENACT_MIRROR] = TRUE; -+ -+ phyPmask = aclAct.fwdpmask; -+ if(rtk_switch_portmask_P2L_get(phyPmask,&(pAction->filterPortmask)) != RT_ERR_OK) -+ return RT_ERR_FAILED; -+ } -+ else if (aclAct.fwdact == RTL8367C_ACL_FWD_REDIRECT) -+ { -+ if(aclAct.fwdpmask == 0 ) -+ pAction->actEnable[FILTER_ENACT_DROP] = TRUE; -+ else -+ { -+ pAction->actEnable[FILTER_ENACT_REDIRECT] = TRUE; -+ -+ phyPmask = aclAct.fwdpmask; -+ if(rtk_switch_portmask_P2L_get(phyPmask,&(pAction->filterPortmask)) != RT_ERR_OK) -+ return RT_ERR_FAILED; -+ } -+ } -+ else if (aclAct.fwdact == RTL8367C_ACL_FWD_MIRROR) -+ { -+ if((retVal = rtl8367c_getAsicCputagTrapPort(&cpuPort)) != RT_ERR_OK) -+ return retVal; -+ if (aclAct.fwdpmask == (1 << cpuPort)) -+ { -+ pAction->actEnable[FILTER_ENACT_COPY_CPU] = TRUE; -+ } -+ else -+ { -+ pAction->actEnable[FILTER_ENACT_ADD_DSTPORT] = TRUE; -+ -+ phyPmask = aclAct.fwdpmask; -+ if(rtk_switch_portmask_P2L_get(phyPmask,&(pAction->filterPortmask)) != RT_ERR_OK) -+ return RT_ERR_FAILED; -+ } -+ } -+ else -+ { -+ return RT_ERR_FAILED; -+ } -+ } -+ -+ if(tmp & FILTER_ENACT_POLICING_MASK) -+ { -+ pAction->actEnable[FILTER_ENACT_POLICING_0] = TRUE; -+ pAction->filterPolicingIdx[0] = aclAct.aclmeteridx; -+ } -+ -+ if(tmp & FILTER_ENACT_PRIORITY_MASK) -+ { -+ if(aclAct.priact == FILTER_ENACT_PRI_TYPE(FILTER_ENACT_PRIORITY)) -+ { -+ pAction->actEnable[FILTER_ENACT_PRIORITY] = TRUE; -+ pAction->filterPriority = aclAct.pridx; -+ } -+ else if(aclAct.priact == FILTER_ENACT_PRI_TYPE(FILTER_ENACT_1P_REMARK)) -+ { -+ pAction->actEnable[FILTER_ENACT_1P_REMARK] = TRUE; -+ pAction->filterPriority = aclAct.pridx; -+ } -+ else if(aclAct.priact == FILTER_ENACT_PRI_TYPE(FILTER_ENACT_DSCP_REMARK)) -+ { -+ pAction->actEnable[FILTER_ENACT_DSCP_REMARK] = TRUE; -+ pAction->filterPriority = aclAct.pridx; -+ } -+ else if(aclAct.priact == FILTER_ENACT_PRI_TYPE(FILTER_ENACT_POLICING_3)) -+ { -+ pAction->actEnable[FILTER_ENACT_POLICING_3] = TRUE; -+ pAction->filterPolicingIdx[3] = aclAct.pridx; -+ } -+ } -+ -+ if(tmp & FILTER_ENACT_SVLAN_MASK) -+ { -+ if(aclAct.sact == FILTER_ENACT_SVLAN_TYPE(FILTER_ENACT_SVLAN_INGRESS)) -+ { -+ if((retVal = rtl8367c_getAsicSvlanMemberConfiguration(aclAct.svidx_sact, &svlan_cfg)) != RT_ERR_OK) -+ return retVal; -+ -+ pAction->actEnable[FILTER_ENACT_SVLAN_INGRESS] = TRUE; -+ pAction->filterSvlanIdx = aclAct.svidx_sact; -+ pAction->filterSvlanVid = svlan_cfg.vs_svid; -+ } -+ else if(aclAct.sact == FILTER_ENACT_SVLAN_TYPE(FILTER_ENACT_SVLAN_EGRESS)) -+ { -+ if((retVal = rtl8367c_getAsicSvlanMemberConfiguration(aclAct.svidx_sact, &svlan_cfg)) != RT_ERR_OK) -+ return retVal; -+ -+ pAction->actEnable[FILTER_ENACT_SVLAN_EGRESS] = TRUE; -+ pAction->filterSvlanIdx = aclAct.svidx_sact; -+ pAction->filterSvlanVid = svlan_cfg.vs_svid; -+ } -+ else if(aclAct.sact == FILTER_ENACT_SVLAN_TYPE(FILTER_ENACT_SVLAN_CVID)) -+ pAction->actEnable[FILTER_ENACT_SVLAN_CVID] = TRUE; -+ else if(aclAct.sact == FILTER_ENACT_SVLAN_TYPE(FILTER_ENACT_POLICING_2)) -+ { -+ pAction->actEnable[FILTER_ENACT_POLICING_2] = TRUE; -+ pAction->filterPolicingIdx[2] = aclAct.svidx_sact; -+ } -+ } -+ -+ -+ if(tmp & FILTER_ENACT_CVLAN_MASK) -+ { -+ if(FILTER_ENACT_CACTEXT_TAGONLY == aclAct.cact_ext || -+ FILTER_ENACT_CACTEXT_BOTHVLANTAG == aclAct.cact_ext ) -+ { -+ if(FILTER_CTAGFMT_UNTAG == aclAct.tag_fmt) -+ { -+ pAction->actEnable[FILTER_ENACT_EGRESSCTAG_UNTAG] = TRUE; -+ } -+ else if(FILTER_CTAGFMT_TAG == aclAct.tag_fmt) -+ { -+ pAction->actEnable[FILTER_ENACT_EGRESSCTAG_TAG] = TRUE; -+ } -+ else if(FILTER_CTAGFMT_KEEP == aclAct.tag_fmt) -+ { -+ pAction->actEnable[FILTER_ENACT_EGRESSCTAG_KEEP] = TRUE; -+ } -+ else if(FILTER_CTAGFMT_KEEP1PRMK== aclAct.tag_fmt) -+ { -+ pAction->actEnable[FILTER_ENACT_EGRESSCTAG_KEEPAND1PRMK] = TRUE; -+ } -+ -+ } -+ -+ if(FILTER_ENACT_CACTEXT_VLANONLY == aclAct.cact_ext || -+ FILTER_ENACT_CACTEXT_BOTHVLANTAG == aclAct.cact_ext ) -+ { -+ if(aclAct.cact == FILTER_ENACT_CVLAN_TYPE(FILTER_ENACT_CVLAN_INGRESS)) -+ { -+ if((retVal = rtl8367c_getAsicVlanMemberConfig(aclAct.cvidx_cact, &vlanMC)) != RT_ERR_OK) -+ return retVal; -+ -+ pAction->actEnable[FILTER_ENACT_CVLAN_INGRESS] = TRUE; -+ pAction->filterCvlanIdx = aclAct.cvidx_cact; -+ pAction->filterCvlanVid = vlanMC.evid; -+ } -+ else if(aclAct.cact == FILTER_ENACT_CVLAN_TYPE(FILTER_ENACT_CVLAN_EGRESS)) -+ { -+ if((retVal = rtl8367c_getAsicVlanMemberConfig(aclAct.cvidx_cact, &vlanMC)) != RT_ERR_OK) -+ return retVal; -+ -+ pAction->actEnable[FILTER_ENACT_CVLAN_EGRESS] = TRUE; -+ pAction->filterCvlanIdx = aclAct.cvidx_cact; -+ pAction->filterCvlanVid = vlanMC.evid; -+ } -+ else if(aclAct.cact == FILTER_ENACT_CVLAN_TYPE(FILTER_ENACT_CVLAN_SVID)) -+ { -+ pAction->actEnable[FILTER_ENACT_CVLAN_SVID] = TRUE; -+ } -+ else if(aclAct.cact == FILTER_ENACT_CVLAN_TYPE(FILTER_ENACT_POLICING_1)) -+ { -+ pAction->actEnable[FILTER_ENACT_POLICING_1] = TRUE; -+ pAction->filterPolicingIdx[1] = aclAct.cvidx_cact; -+ } -+ } -+ } -+ -+ if(tmp & FILTER_ENACT_INTGPIO_MASK) -+ { -+ if(TRUE == aclAct.aclint) -+ { -+ pAction->actEnable[FILTER_ENACT_INTERRUPT] = TRUE; -+ } -+ -+ if(TRUE == aclAct.gpio_en) -+ { -+ pAction->actEnable[FILTER_ENACT_GPO] = TRUE; -+ pAction->filterPin = aclAct.gpio_pin; -+ } -+ } -+ -+ /* Get field type of RAW data */ -+ if ((retVal = rtl8367c_getAsicAclTemplate(aclRule.data_bits.type, &type))!= RT_ERR_OK) -+ return retVal; -+ -+ for(i = 0; i < RTL8367C_ACLRULEFIELDNO; i++) -+ { -+ pFilter_cfg->fieldRawType[i] = type.field[i]; -+ }/* end of for(i...) */ -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_filter_igrAcl_unmatchAction_set -+ * Description: -+ * Set action to packets when no ACL configuration match -+ * Input: -+ * port - Port id. -+ * action - Action. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port id. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This function sets action of packets when no ACL configuration matches. -+ */ -+rtk_api_ret_t rtk_filter_igrAcl_unmatchAction_set(rtk_port_t port, rtk_filter_unmatch_action_t action) -+{ -+ rtk_api_ret_t ret; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check port valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(action >= FILTER_UNMATCH_END) -+ return RT_ERR_INPUT; -+ -+ if((ret = rtl8367c_setAsicAclUnmatchedPermit(rtk_switch_port_L2P_get(port), action)) != RT_ERR_OK) -+ return ret; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_filter_igrAcl_unmatchAction_get -+ * Description: -+ * Get action to packets when no ACL configuration match -+ * Input: -+ * port - Port id. -+ * Output: -+ * pAction - Action. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port id. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This function gets action of packets when no ACL configruation matches. -+ */ -+rtk_api_ret_t rtk_filter_igrAcl_unmatchAction_get(rtk_port_t port, rtk_filter_unmatch_action_t* pAction) -+{ -+ rtk_api_ret_t ret; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pAction) -+ return RT_ERR_NULL_POINTER; -+ -+ /* Check port valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if((ret = rtl8367c_getAsicAclUnmatchedPermit(rtk_switch_port_L2P_get(port), pAction)) != RT_ERR_OK) -+ return ret; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_filter_igrAcl_state_set -+ * Description: -+ * Set state of ingress ACL. -+ * Input: -+ * port - Port id. -+ * state - Ingress ACL state. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port id. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This function gets action of packets when no ACL configuration matches. -+ */ -+rtk_api_ret_t rtk_filter_igrAcl_state_set(rtk_port_t port, rtk_filter_state_t state) -+{ -+ rtk_api_ret_t ret; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check port valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(state >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if((ret = rtl8367c_setAsicAcl(rtk_switch_port_L2P_get(port), state)) != RT_ERR_OK) -+ return ret; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_filter_igrAcl_state_get -+ * Description: -+ * Get state of ingress ACL. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pState - Ingress ACL state. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port id. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This function gets action of packets when no ACL configuration matches. -+ */ -+rtk_api_ret_t rtk_filter_igrAcl_state_get(rtk_port_t port, rtk_filter_state_t* pState) -+{ -+ rtk_api_ret_t ret; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pState) -+ return RT_ERR_NULL_POINTER; -+ -+ /* Check port valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if((ret = rtl8367c_getAsicAcl(rtk_switch_port_L2P_get(port), pState)) != RT_ERR_OK) -+ return ret; -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtk_filter_igrAcl_template_set -+ * Description: -+ * Set template of ingress ACL. -+ * Input: -+ * template - Ingress ACL template -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This function set ACL template. -+ */ -+rtk_api_ret_t rtk_filter_igrAcl_template_set(rtk_filter_template_t *aclTemplate) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 idxField; -+ rtl8367c_acltemplate_t aclType; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(aclTemplate->index >= RTK_MAX_NUM_OF_FILTER_TYPE) -+ return RT_ERR_INPUT; -+ -+ for(idxField = 0; idxField < RTK_MAX_NUM_OF_FILTER_FIELD; idxField++) -+ { -+ if(aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_DMAC_15_0 || -+ (aclTemplate->fieldType[idxField] > FILTER_FIELD_RAW_CTAG && aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_IPV4_SIP_15_0 ) || -+ (aclTemplate->fieldType[idxField] > FILTER_FIELD_RAW_IPV4_DIP_31_16 && aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_IPV6_SIP_15_0 ) || -+ (aclTemplate->fieldType[idxField] > FILTER_FIELD_RAW_IPV6_DIP_31_16 && aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_VIDRANGE ) || -+ (aclTemplate->fieldType[idxField] > FILTER_FIELD_RAW_FIELD_VALID && aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_FIELD_SELECT00 ) || -+ aclTemplate->fieldType[idxField] >= FILTER_FIELD_RAW_END) -+ { -+ return RT_ERR_INPUT; -+ } -+ } -+ -+ for(idxField = 0; idxField < RTK_MAX_NUM_OF_FILTER_FIELD; idxField++) -+ { -+ aclType.field[idxField] = aclTemplate->fieldType[idxField]; -+ } -+ -+ if((retVal = rtl8367c_setAsicAclTemplate(aclTemplate->index, &aclType)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_filter_igrAcl_template_get -+ * Description: -+ * Get template of ingress ACL. -+ * Input: -+ * template - Ingress ACL template -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * This function gets template of ACL. -+ */ -+rtk_api_ret_t rtk_filter_igrAcl_template_get(rtk_filter_template_t *aclTemplate) -+{ -+ rtk_api_ret_t ret; -+ rtk_uint32 idxField; -+ rtl8367c_acltemplate_t aclType; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == aclTemplate) -+ return RT_ERR_NULL_POINTER; -+ -+ if(aclTemplate->index >= RTK_MAX_NUM_OF_FILTER_TYPE) -+ return RT_ERR_INPUT; -+ -+ if((ret = rtl8367c_getAsicAclTemplate(aclTemplate->index, &aclType)) != RT_ERR_OK) -+ return ret; -+ -+ for(idxField = 0; idxField < RTK_MAX_NUM_OF_FILTER_FIELD; idxField ++) -+ { -+ aclTemplate->fieldType[idxField] = aclType.field[idxField]; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_filter_igrAcl_field_sel_set -+ * Description: -+ * Set user defined field selectors in HSB -+ * Input: -+ * index - index of field selector 0-15 -+ * format - Format of field selector -+ * offset - Retrieving data offset -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * System support 16 user defined field selectors. -+ * Each selector can be enabled or disable. -+ * User can defined retrieving 16-bits in many predefiend -+ * standard l2/l3/l4 payload. -+ */ -+rtk_api_ret_t rtk_filter_igrAcl_field_sel_set(rtk_uint32 index, rtk_field_sel_t format, rtk_uint32 offset) -+{ -+ rtk_api_ret_t ret; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(index >= RTL8367C_FIELDSEL_FORMAT_NUMBER) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(format >= FORMAT_END) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(offset > RTL8367C_FIELDSEL_MAX_OFFSET) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if((ret = rtl8367c_setAsicFieldSelector(index, (rtk_uint32)format, offset)) != RT_ERR_OK) -+ return ret; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_filter_igrAcl_field_sel_get -+ * Description: -+ * Get user defined field selectors in HSB -+ * Input: -+ * index - index of field selector 0-15 -+ * Output: -+ * pFormat - Format of field selector -+ * pOffset - Retrieving data offset -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None. -+ */ -+rtk_api_ret_t rtk_filter_igrAcl_field_sel_get(rtk_uint32 index, rtk_field_sel_t *pFormat, rtk_uint32 *pOffset) -+{ -+ rtk_api_ret_t ret; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pFormat || NULL == pOffset) -+ return RT_ERR_NULL_POINTER; -+ -+ if(index >= RTL8367C_FIELDSEL_FORMAT_NUMBER) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if((ret = rtl8367c_getAsicFieldSelector(index, pFormat, pOffset)) != RT_ERR_OK) -+ return ret; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_filter_iprange_set -+ * Description: -+ * Set IP Range check -+ * Input: -+ * index - index of IP Range 0-15 -+ * type - IP Range check type, 0:Delete a entry, 1: IPv4_SIP, 2: IPv4_DIP, 3:IPv6_SIP, 4:IPv6_DIP -+ * upperIp - The upper bound of IP range -+ * lowerIp - The lower Bound of IP range -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - The parameter is out of range -+ * RT_ERR_INPUT - Input error -+ * Note: -+ * upperIp must be larger or equal than lowerIp. -+ */ -+rtk_api_ret_t rtk_filter_iprange_set(rtk_uint32 index, rtk_filter_iprange_t type, ipaddr_t upperIp, ipaddr_t lowerIp) -+{ -+ rtk_api_ret_t ret; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(index > RTL8367C_ACLRANGEMAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(type >= IPRANGE_END) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(lowerIp > upperIp) -+ return RT_ERR_INPUT; -+ -+ if((ret = rtl8367c_setAsicAclIpRange(index, type, upperIp, lowerIp)) != RT_ERR_OK) -+ return ret; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_filter_iprange_get -+ * Description: -+ * Set IP Range check -+ * Input: -+ * index - index of IP Range 0-15 -+ * Output: -+ * pType - IP Range check type, 0:Delete a entry, 1: IPv4_SIP, 2: IPv4_DIP, 3:IPv6_SIP, 4:IPv6_DIP -+ * pUpperIp - The upper bound of IP range -+ * pLowerIp - The lower Bound of IP range -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - The parameter is out of range -+ * Note: -+ * None. -+ */ -+rtk_api_ret_t rtk_filter_iprange_get(rtk_uint32 index, rtk_filter_iprange_t *pType, ipaddr_t *pUpperIp, ipaddr_t *pLowerIp) -+{ -+ rtk_api_ret_t ret; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if((NULL == pType) || (NULL == pUpperIp) || (NULL == pLowerIp)) -+ return RT_ERR_NULL_POINTER; -+ -+ if(index > RTL8367C_ACLRANGEMAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if((ret = rtl8367c_getAsicAclIpRange(index, pType, pUpperIp, pLowerIp)) != RT_ERR_OK) -+ return ret; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_filter_vidrange_set -+ * Description: -+ * Set VID Range check -+ * Input: -+ * index - index of VID Range 0-15 -+ * type - IP Range check type, 0:Delete a entry, 1: CVID, 2: SVID -+ * upperVid - The upper bound of VID range -+ * lowerVid - The lower Bound of VID range -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - The parameter is out of range -+ * RT_ERR_INPUT - Input error -+ * Note: -+ * upperVid must be larger or equal than lowerVid. -+ */ -+rtk_api_ret_t rtk_filter_vidrange_set(rtk_uint32 index, rtk_filter_vidrange_t type, rtk_uint32 upperVid, rtk_uint32 lowerVid) -+{ -+ rtk_api_ret_t ret; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(index > RTL8367C_ACLRANGEMAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(type >= VIDRANGE_END) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(lowerVid > upperVid) -+ return RT_ERR_INPUT; -+ -+ if( (upperVid > RTL8367C_VIDMAX) || (lowerVid > RTL8367C_VIDMAX)) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if((ret = rtl8367c_setAsicAclVidRange(index, type, upperVid, lowerVid)) != RT_ERR_OK) -+ return ret; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_filter_vidrange_get -+ * Description: -+ * Get VID Range check -+ * Input: -+ * index - index of VID Range 0-15 -+ * Output: -+ * pType - IP Range check type, 0:Unused, 1: CVID, 2: SVID -+ * pUpperVid - The upper bound of VID range -+ * pLowerVid - The lower Bound of VID range -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - The parameter is out of range -+ * Note: -+ * None. -+ */ -+rtk_api_ret_t rtk_filter_vidrange_get(rtk_uint32 index, rtk_filter_vidrange_t *pType, rtk_uint32 *pUpperVid, rtk_uint32 *pLowerVid) -+{ -+ rtk_api_ret_t ret; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if((NULL == pType) || (NULL == pUpperVid) || (NULL == pLowerVid)) -+ return RT_ERR_NULL_POINTER; -+ -+ if(index > RTL8367C_ACLRANGEMAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if((ret = rtl8367c_getAsicAclVidRange(index, pType, pUpperVid, pLowerVid)) != RT_ERR_OK) -+ return ret; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_filter_portrange_set -+ * Description: -+ * Set Port Range check -+ * Input: -+ * index - index of Port Range 0-15 -+ * type - IP Range check type, 0:Delete a entry, 1: Source Port, 2: Destination Port -+ * upperPort - The upper bound of Port range -+ * lowerPort - The lower Bound of Port range -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - The parameter is out of range -+ * RT_ERR_INPUT - Input error -+ * Note: -+ * upperPort must be larger or equal than lowerPort. -+ */ -+rtk_api_ret_t rtk_filter_portrange_set(rtk_uint32 index, rtk_filter_portrange_t type, rtk_uint32 upperPort, rtk_uint32 lowerPort) -+{ -+ rtk_api_ret_t ret; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(index > RTL8367C_ACLRANGEMAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(type >= PORTRANGE_END) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(lowerPort > upperPort) -+ return RT_ERR_INPUT; -+ -+ if(upperPort > RTL8367C_ACL_PORTRANGEMAX) -+ return RT_ERR_INPUT; -+ -+ if(lowerPort > RTL8367C_ACL_PORTRANGEMAX) -+ return RT_ERR_INPUT; -+ -+ if((ret = rtl8367c_setAsicAclPortRange(index, type, upperPort, lowerPort)) != RT_ERR_OK) -+ return ret; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_filter_portrange_get -+ * Description: -+ * Set Port Range check -+ * Input: -+ * index - index of Port Range 0-15 -+ * Output: -+ * pType - IP Range check type, 0:Delete a entry, 1: Source Port, 2: Destination Port -+ * pUpperPort - The upper bound of Port range -+ * pLowerPort - The lower Bound of Port range -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - The parameter is out of range -+ * RT_ERR_INPUT - Input error -+ * Note: -+ * None. -+ */ -+rtk_api_ret_t rtk_filter_portrange_get(rtk_uint32 index, rtk_filter_portrange_t *pType, rtk_uint32 *pUpperPort, rtk_uint32 *pLowerPort) -+{ -+ rtk_api_ret_t ret; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if((NULL == pType) || (NULL == pUpperPort) || (NULL == pLowerPort)) -+ return RT_ERR_NULL_POINTER; -+ -+ if(index > RTL8367C_ACLRANGEMAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if((ret = rtl8367c_getAsicAclPortRange(index, pType, pUpperPort, pLowerPort)) != RT_ERR_OK) -+ return ret; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_filter_igrAclPolarity_set -+ * Description: -+ * Set ACL Goip control polarity -+ * Input: -+ * polarity - 1: High, 0: Low -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * none -+ */ -+rtk_api_ret_t rtk_filter_igrAclPolarity_set(rtk_uint32 polarity) -+{ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(polarity > 1) -+ return RT_ERR_OUT_OF_RANGE; -+ return rtl8367c_setAsicAclGpioPolarity(polarity); -+} -+/* Function Name: -+ * rtk_filter_igrAclPolarity_get -+ * Description: -+ * Get ACL Goip control polarity -+ * Input: -+ * pPolarity - 1: High, 0: Low -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * none -+ */ -+rtk_api_ret_t rtk_filter_igrAclPolarity_get(rtk_uint32* pPolarity) -+{ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pPolarity) -+ return RT_ERR_NULL_POINTER; -+ -+ return rtl8367c_getAsicAclGpioPolarity(pPolarity); -+} -+ -+ -+ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/cpu.c b/drivers/net/phy/rtk/rtl8367c/cpu.c -new file mode 100644 -index 000000000000..b031cbe920eb ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/cpu.c -@@ -0,0 +1,537 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTK switch high-level API for RTL8367/RTL8367C -+ * Feature : Here is a list of all functions and variables in CPU module. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+/* Function Name: -+ * rtk_cpu_enable_set -+ * Description: -+ * Set CPU port function enable/disable. -+ * Input: -+ * enable - CPU port function enable -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can set CPU port function enable/disable. -+ */ -+rtk_api_ret_t rtk_cpu_enable_set(rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (enable >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ if ((retVal = rtl8367c_setAsicCputagEnable(enable)) != RT_ERR_OK) -+ return retVal; -+ -+ if (DISABLED == enable) -+ { -+ if ((retVal = rtl8367c_setAsicCputagPortmask(0)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_cpu_enable_get -+ * Description: -+ * Get CPU port and its setting. -+ * Input: -+ * None -+ * Output: -+ * pEnable - CPU port function enable -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_L2_NO_CPU_PORT - CPU port is not exist -+ * Note: -+ * The API can get CPU port function enable/disable. -+ */ -+rtk_api_ret_t rtk_cpu_enable_get(rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pEnable) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicCputagEnable(pEnable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_cpu_tagPort_set -+ * Description: -+ * Set CPU port and CPU tag insert mode. -+ * Input: -+ * port - Port id. -+ * mode - CPU tag insert for packets egress from CPU port. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can set CPU port and inserting proprietary CPU tag mode (Length/Type 0x8899) -+ * to the frame that transmitting to CPU port. -+ * The insert CPU tag mode is as following: -+ * - CPU_INSERT_TO_ALL -+ * - CPU_INSERT_TO_TRAPPING -+ * - CPU_INSERT_TO_NONE -+ */ -+rtk_api_ret_t rtk_cpu_tagPort_set(rtk_port_t port, rtk_cpu_insert_t mode) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (mode >= CPU_INSERT_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicCputagPortmask(1<= CPU_POS_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicCputagPosition(position)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_cpu_tagPosition_get -+ * Description: -+ * Get CPU tag position. -+ * Input: -+ * None -+ * Output: -+ * pPosition - CPU tag position. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input. -+ * Note: -+ * The API can get CPU tag position. -+ */ -+rtk_api_ret_t rtk_cpu_tagPosition_get(rtk_cpu_position_t *pPosition) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pPosition) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicCputagPosition(pPosition)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_cpu_tagLength_set -+ * Description: -+ * Set CPU tag length. -+ * Input: -+ * length - CPU tag length. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input. -+ * Note: -+ * The API can set CPU tag length. -+ */ -+rtk_api_ret_t rtk_cpu_tagLength_set(rtk_cpu_tag_length_t length) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (length >= CPU_LEN_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicCputagMode(length)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_cpu_tagLength_get -+ * Description: -+ * Get CPU tag length. -+ * Input: -+ * None -+ * Output: -+ * pLength - CPU tag length. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input. -+ * Note: -+ * The API can get CPU tag length. -+ */ -+rtk_api_ret_t rtk_cpu_tagLength_get(rtk_cpu_tag_length_t *pLength) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pLength) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicCputagMode(pLength)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_cpu_priRemap_set -+ * Description: -+ * Configure CPU priorities mapping to internal absolute priority. -+ * Input: -+ * int_pri - internal priority value. -+ * new_pri - new internal priority value. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_VLAN_PRIORITY - Invalid 1p priority. -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority. -+ * Note: -+ * Priority of CPU tag assignment for internal asic priority, and it is used for queue usage and packet scheduling. -+ */ -+rtk_api_ret_t rtk_cpu_priRemap_set(rtk_pri_t int_pri, rtk_pri_t new_pri) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (new_pri > RTL8367C_PRIMAX || int_pri > RTL8367C_PRIMAX) -+ return RT_ERR_VLAN_PRIORITY; -+ -+ if ((retVal = rtl8367c_setAsicCputagPriorityRemapping(int_pri, new_pri)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_cpu_priRemap_get -+ * Description: -+ * Configure CPU priorities mapping to internal absolute priority. -+ * Input: -+ * int_pri - internal priority value. -+ * Output: -+ * pNew_pri - new internal priority value. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_VLAN_PRIORITY - Invalid 1p priority. -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority. -+ * Note: -+ * Priority of CPU tag assignment for internal asic priority, and it is used for queue usage and packet scheduling. -+ */ -+rtk_api_ret_t rtk_cpu_priRemap_get(rtk_pri_t int_pri, rtk_pri_t *pNew_pri) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pNew_pri) -+ return RT_ERR_NULL_POINTER; -+ -+ if (int_pri > RTL8367C_PRIMAX) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ if ((retVal = rtl8367c_getAsicCputagPriorityRemapping(int_pri, pNew_pri)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_cpu_acceptLength_set -+ * Description: -+ * Set CPU accept length. -+ * Input: -+ * length - CPU tag length. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input. -+ * Note: -+ * The API can set CPU accept length. -+ */ -+rtk_api_ret_t rtk_cpu_acceptLength_set(rtk_cpu_rx_length_t length) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (length >= CPU_RX_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicCputagRxMinLength(length)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_cpu_acceptLength_get -+ * Description: -+ * Get CPU accept length. -+ * Input: -+ * None -+ * Output: -+ * pLength - CPU tag length. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input. -+ * Note: -+ * The API can get CPU accept length. -+ */ -+rtk_api_ret_t rtk_cpu_acceptLength_get(rtk_cpu_rx_length_t *pLength) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pLength) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicCputagRxMinLength(pLength)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/dot1x.c b/drivers/net/phy/rtk/rtl8367c/dot1x.c -new file mode 100644 -index 000000000000..c9b146a6d887 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/dot1x.c -@@ -0,0 +1,843 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 75783 $ -+ * $Date: 2017-02-13 14:54:53 +0800 (週一, 13 二月 2017) $ -+ * -+ * Purpose : RTK switch high-level API for RTL8367/RTL8367C -+ * Feature : Here is a list of all functions and variables in 1X module. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Function Name: -+ * rtk_dot1x_unauthPacketOper_set -+ * Description: -+ * Set 802.1x unauth action configuration. -+ * Input: -+ * port - Port id. -+ * unauth_action - 802.1X unauth action. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_INPUT - Invalid input parameter. -+ * Note: -+ * This API can set 802.1x unauth action configuration. -+ * The unauth action is as following: -+ * - DOT1X_ACTION_DROP -+ * - DOT1X_ACTION_TRAP2CPU -+ * - DOT1X_ACTION_GUESTVLAN -+ */ -+rtk_api_ret_t rtk_dot1x_unauthPacketOper_set(rtk_port_t port, rtk_dot1x_unauth_action_t unauth_action) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (unauth_action >= DOT1X_ACTION_END) -+ return RT_ERR_DOT1X_PROC; -+ -+ if ((retVal = rtl8367c_setAsic1xProcConfig(rtk_switch_port_L2P_get(port), unauth_action)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_dot1x_unauthPacketOper_get -+ * Description: -+ * Get 802.1x unauth action configuration. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pUnauth_action - 802.1X unauth action. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * This API can get 802.1x unauth action configuration. -+ * The unauth action is as following: -+ * - DOT1X_ACTION_DROP -+ * - DOT1X_ACTION_TRAP2CPU -+ * - DOT1X_ACTION_GUESTVLAN -+ */ -+rtk_api_ret_t rtk_dot1x_unauthPacketOper_get(rtk_port_t port, rtk_dot1x_unauth_action_t *pUnauth_action) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(NULL == pUnauth_action) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsic1xProcConfig(rtk_switch_port_L2P_get(port), pUnauth_action)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_dot1x_eapolFrame2CpuEnable_set -+ * Description: -+ * Set 802.1x EAPOL packet trap to CPU configuration -+ * Input: -+ * enable - The status of 802.1x EAPOL packet. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_ENABLE - Invalid enable input. -+ * Note: -+ * To support 802.1x authentication functionality, EAPOL frame (ether type = 0x888E) has to -+ * be trapped to CPU. -+ * The status of EAPOL frame trap to CPU is as following: -+ * - DISABLED -+ * - ENABLED -+ */ -+rtk_api_ret_t rtk_dot1x_eapolFrame2CpuEnable_set(rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_rma_t rmacfg; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (enable >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ if ((retVal = rtl8367c_getAsicRma(3, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ if (ENABLED == enable) -+ rmacfg.operation = RMAOP_TRAP_TO_CPU; -+ else if (DISABLED == enable) -+ rmacfg.operation = RMAOP_FORWARD; -+ -+ if ((retVal = rtl8367c_setAsicRma(3, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_dot1x_eapolFrame2CpuEnable_get -+ * Description: -+ * Get 802.1x EAPOL packet trap to CPU configuration -+ * Input: -+ * None -+ * Output: -+ * pEnable - The status of 802.1x EAPOL packet. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * To support 802.1x authentication functionality, EAPOL frame (ether type = 0x888E) has to -+ * be trapped to CPU. -+ * The status of EAPOL frame trap to CPU is as following: -+ * - DISABLED -+ * - ENABLED -+ */ -+rtk_api_ret_t rtk_dot1x_eapolFrame2CpuEnable_get(rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_rma_t rmacfg; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pEnable) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicRma(3, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ if (RMAOP_TRAP_TO_CPU == rmacfg.operation) -+ *pEnable = ENABLED; -+ else -+ *pEnable = DISABLED; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_dot1x_portBasedEnable_set -+ * Description: -+ * Set 802.1x port-based enable configuration -+ * Input: -+ * port - Port id. -+ * enable - The status of 802.1x port. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_ENABLE - Invalid enable input. -+ * RT_ERR_DOT1X_PORTBASEDPNEN - 802.1X port-based enable error -+ * Note: -+ * The API can update the port-based port enable register content. If a port is 802.1x -+ * port based network access control "enabled", it should be authenticated so packets -+ * from that port won't be dropped or trapped to CPU. -+ * The status of 802.1x port-based network access control is as following: -+ * - DISABLED -+ * - ENABLED -+ */ -+rtk_api_ret_t rtk_dot1x_portBasedEnable_set(rtk_port_t port, rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (enable >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ if ((retVal = rtl8367c_setAsic1xPBEnConfig(rtk_switch_port_L2P_get(port),enable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_dot1x_portBasedEnable_get -+ * Description: -+ * Get 802.1x port-based enable configuration -+ * Input: -+ * port - Port id. -+ * Output: -+ * pEnable - The status of 802.1x port. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get the 802.1x port-based port status. -+ */ -+rtk_api_ret_t rtk_dot1x_portBasedEnable_get(rtk_port_t port, rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(NULL == pEnable) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsic1xPBEnConfig(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_dot1x_portBasedAuthStatus_set -+ * Description: -+ * Set 802.1x port-based auth. port configuration -+ * Input: -+ * port - Port id. -+ * port_auth - The status of 802.1x port. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_DOT1X_PORTBASEDAUTH - 802.1X port-based auth error -+ * Note: -+ * The authenticated status of 802.1x port-based network access control is as following: -+ * - UNAUTH -+ * - AUTH -+ */ -+rtk_api_ret_t rtk_dot1x_portBasedAuthStatus_set(rtk_port_t port, rtk_dot1x_auth_status_t port_auth) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (port_auth >= AUTH_STATUS_END) -+ return RT_ERR_DOT1X_PORTBASEDAUTH; -+ -+ if ((retVal = rtl8367c_setAsic1xPBAuthConfig(rtk_switch_port_L2P_get(port), port_auth)) != RT_ERR_OK) -+ return retVal; -+ -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_dot1x_portBasedAuthStatus_get -+ * Description: -+ * Get 802.1x port-based auth. port configuration -+ * Input: -+ * port - Port id. -+ * Output: -+ * pPort_auth - The status of 802.1x port. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get 802.1x port-based port auth.information. -+ */ -+rtk_api_ret_t rtk_dot1x_portBasedAuthStatus_get(rtk_port_t port, rtk_dot1x_auth_status_t *pPort_auth) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pPort_auth) -+ return RT_ERR_NULL_POINTER; -+ -+ /* Check port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if ((retVal = rtl8367c_getAsic1xPBAuthConfig(rtk_switch_port_L2P_get(port), pPort_auth)) != RT_ERR_OK) -+ return retVal; -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_dot1x_portBasedDirection_set -+ * Description: -+ * Set 802.1x port-based operational direction configuration -+ * Input: -+ * port - Port id. -+ * port_direction - Operation direction -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_DOT1X_PORTBASEDOPDIR - 802.1X port-based operation direction error -+ * Note: -+ * The operate controlled direction of 802.1x port-based network access control is as following: -+ * - BOTH -+ * - IN -+ */ -+rtk_api_ret_t rtk_dot1x_portBasedDirection_set(rtk_port_t port, rtk_dot1x_direction_t port_direction) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (port_direction >= DIRECTION_END) -+ return RT_ERR_DOT1X_PORTBASEDOPDIR; -+ -+ if ((retVal = rtl8367c_setAsic1xPBOpdirConfig(rtk_switch_port_L2P_get(port), port_direction)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_dot1x_portBasedDirection_get -+ * Description: -+ * Get 802.1X port-based operational direction configuration -+ * Input: -+ * port - Port id. -+ * Output: -+ * pPort_direction - Operation direction -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get 802.1x port-based operational direction information. -+ */ -+rtk_api_ret_t rtk_dot1x_portBasedDirection_get(rtk_port_t port, rtk_dot1x_direction_t *pPort_direction) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pPort_direction) -+ return RT_ERR_NULL_POINTER; -+ -+ /* Check port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if ((retVal = rtl8367c_getAsic1xPBOpdirConfig(rtk_switch_port_L2P_get(port), pPort_direction)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_dot1x_macBasedEnable_set -+ * Description: -+ * Set 802.1x mac-based port enable configuration -+ * Input: -+ * port - Port id. -+ * enable - The status of 802.1x port. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_ENABLE - Invalid enable input. -+ * RT_ERR_DOT1X_MACBASEDPNEN - 802.1X mac-based enable error -+ * Note: -+ * If a port is 802.1x MAC based network access control "enabled", the incoming packets should -+ * be authenticated so packets from that port won't be dropped or trapped to CPU. -+ * The status of 802.1x MAC-based network access control is as following: -+ * - DISABLED -+ * - ENABLED -+ */ -+rtk_api_ret_t rtk_dot1x_macBasedEnable_set(rtk_port_t port, rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (enable >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ if ((retVal = rtl8367c_setAsic1xMBEnConfig(rtk_switch_port_L2P_get(port),enable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_dot1x_macBasedEnable_get -+ * Description: -+ * Get 802.1x mac-based port enable configuration -+ * Input: -+ * port - Port id. -+ * Output: -+ * pEnable - The status of 802.1x port. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * If a port is 802.1x MAC based network access control "enabled", the incoming packets should -+ * be authenticated so packets from that port wont be dropped or trapped to CPU. -+ * The status of 802.1x MAC-based network access control is as following: -+ * - DISABLED -+ * - ENABLED -+ */ -+rtk_api_ret_t rtk_dot1x_macBasedEnable_get(rtk_port_t port, rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pEnable) -+ return RT_ERR_NULL_POINTER; -+ -+ /* Check port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if ((retVal = rtl8367c_getAsic1xMBEnConfig(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_dot1x_macBasedAuthMac_add -+ * Description: -+ * Add an authenticated MAC to ASIC -+ * Input: -+ * port - Port id. -+ * pAuth_mac - The authenticated MAC. -+ * fid - filtering database. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_ENABLE - Invalid enable input. -+ * RT_ERR_DOT1X_MACBASEDPNEN - 802.1X mac-based enable error -+ * Note: -+ * The API can add a 802.1x authenticated MAC address to port. If the MAC does not exist in LUT, -+ * user can't add this MAC to auth status. -+ */ -+rtk_api_ret_t rtk_dot1x_macBasedAuthMac_add(rtk_port_t port, rtk_mac_t *pAuth_mac, rtk_fid_t fid) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 method; -+ rtl8367c_luttb l2Table; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* must be unicast address */ -+ if ((pAuth_mac == NULL) || (pAuth_mac->octet[0] & 0x1)) -+ return RT_ERR_MAC; -+ -+ /* Check port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (fid > RTL8367C_FIDMAX) -+ return RT_ERR_L2_FID; -+ -+ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); -+ -+ /* fill key (MAC,FID) to get L2 entry */ -+ memcpy(l2Table.mac.octet, pAuth_mac->octet, ETHER_ADDR_LEN); -+ l2Table.fid = fid; -+ method = LUTREADMETHOD_MAC; -+ retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); -+ if ( RT_ERR_OK == retVal) -+ { -+ if (l2Table.spa != rtk_switch_port_L2P_get(port)) -+ return RT_ERR_DOT1X_MAC_PORT_MISMATCH; -+ -+ memcpy(l2Table.mac.octet, pAuth_mac->octet, ETHER_ADDR_LEN); -+ l2Table.fid = fid; -+ l2Table.efid = 0; -+ l2Table.auth = 1; -+ retVal = rtl8367c_setAsicL2LookupTb(&l2Table); -+ return retVal; -+ } -+ else -+ return retVal; -+ -+} -+ -+/* Function Name: -+ * rtk_dot1x_macBasedAuthMac_del -+ * Description: -+ * Delete an authenticated MAC to ASIC -+ * Input: -+ * port - Port id. -+ * pAuth_mac - The authenticated MAC. -+ * fid - filtering database. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_MAC - Invalid MAC address. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can delete a 802.1x authenticated MAC address to port. It only change the auth status of -+ * the MAC and won't delete it from LUT. -+ */ -+rtk_api_ret_t rtk_dot1x_macBasedAuthMac_del(rtk_port_t port, rtk_mac_t *pAuth_mac, rtk_fid_t fid) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 method; -+ rtl8367c_luttb l2Table; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* must be unicast address */ -+ if ((pAuth_mac == NULL) || (pAuth_mac->octet[0] & 0x1)) -+ return RT_ERR_MAC; -+ -+ /* Check port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (fid > RTL8367C_FIDMAX) -+ return RT_ERR_L2_FID; -+ -+ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); -+ -+ /* fill key (MAC,FID) to get L2 entry */ -+ memcpy(l2Table.mac.octet, pAuth_mac->octet, ETHER_ADDR_LEN); -+ l2Table.fid = fid; -+ method = LUTREADMETHOD_MAC; -+ retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); -+ if (RT_ERR_OK == retVal) -+ { -+ if (l2Table.spa != rtk_switch_port_L2P_get(port)) -+ return RT_ERR_DOT1X_MAC_PORT_MISMATCH; -+ -+ memcpy(l2Table.mac.octet, pAuth_mac->octet, ETHER_ADDR_LEN); -+ l2Table.fid = fid; -+ l2Table.auth = 0; -+ retVal = rtl8367c_setAsicL2LookupTb(&l2Table); -+ return retVal; -+ } -+ else -+ return retVal; -+ -+} -+ -+/* Function Name: -+ * rtk_dot1x_macBasedDirection_set -+ * Description: -+ * Set 802.1x mac-based operational direction configuration -+ * Input: -+ * mac_direction - Operation direction -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter. -+ * RT_ERR_DOT1X_MACBASEDOPDIR - 802.1X mac-based operation direction error -+ * Note: -+ * The operate controlled direction of 802.1x mac-based network access control is as following: -+ * - BOTH -+ * - IN -+ */ -+rtk_api_ret_t rtk_dot1x_macBasedDirection_set(rtk_dot1x_direction_t mac_direction) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (mac_direction >= DIRECTION_END) -+ return RT_ERR_DOT1X_MACBASEDOPDIR; -+ -+ if ((retVal = rtl8367c_setAsic1xMBOpdirConfig(mac_direction)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_dot1x_macBasedDirection_get -+ * Description: -+ * Get 802.1x mac-based operational direction configuration -+ * Input: -+ * port - Port id. -+ * Output: -+ * pMac_direction - Operation direction -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can get 802.1x mac-based operational direction information. -+ */ -+rtk_api_ret_t rtk_dot1x_macBasedDirection_get(rtk_dot1x_direction_t *pMac_direction) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pMac_direction) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsic1xMBOpdirConfig(pMac_direction)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * Set 802.1x guest VLAN configuration -+ * Description: -+ * Set 802.1x mac-based operational direction configuration -+ * Input: -+ * vid - 802.1x guest VLAN ID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter. -+ * Note: -+ * The operate controlled 802.1x guest VLAN -+ */ -+rtk_api_ret_t rtk_dot1x_guestVlan_set(rtk_vlan_t vid) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 index; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* vid must be 0~4095 */ -+ if (vid > RTL8367C_VIDMAX) -+ return RT_ERR_VLAN_VID; -+ -+ if((retVal = rtk_vlan_checkAndCreateMbr(vid, &index)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsic1xGuestVidx(index)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_dot1x_guestVlan_get -+ * Description: -+ * Get 802.1x guest VLAN configuration -+ * Input: -+ * None -+ * Output: -+ * pVid - 802.1x guest VLAN ID -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can get 802.1x guest VLAN information. -+ */ -+rtk_api_ret_t rtk_dot1x_guestVlan_get(rtk_vlan_t *pVid) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 gvidx; -+ rtl8367c_vlanconfiguser vlanMC; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pVid) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsic1xGuestVidx(&gvidx)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicVlanMemberConfig(gvidx, &vlanMC)) != RT_ERR_OK) -+ return retVal; -+ -+ *pVid = vlanMC.evid; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_dot1x_guestVlan2Auth_set -+ * Description: -+ * Set 802.1x guest VLAN to auth host configuration -+ * Input: -+ * enable - The status of guest VLAN to auth host. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter. -+ * Note: -+ * The operational direction of 802.1x guest VLAN to auth host control is as following: -+ * - ENABLED -+ * - DISABLED -+ */ -+rtk_api_ret_t rtk_dot1x_guestVlan2Auth_set(rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (enable >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ if ((retVal = rtl8367c_setAsic1xGVOpdir(enable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_dot1x_guestVlan2Auth_get -+ * Description: -+ * Get 802.1x guest VLAN to auth host configuration -+ * Input: -+ * None -+ * Output: -+ * pEnable - The status of guest VLAN to auth host. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can get 802.1x guest VLAN to auth host information. -+ */ -+rtk_api_ret_t rtk_dot1x_guestVlan2Auth_get(rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pEnable) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsic1xGVOpdir(pEnable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/eee.c b/drivers/net/phy/rtk/rtl8367c/eee.c -new file mode 100644 -index 000000000000..cd14c2ce1325 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/eee.c -@@ -0,0 +1,162 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 48156 $ -+ * $Date: 2014-05-29 16:39:06 +0800 (週四, 29 五月 2014) $ -+ * -+ * Purpose : RTK switch high-level API for RTL8367/RTL8367C -+ * Feature : Here is a list of all functions and variables in EEE module. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+/* Function Name: -+ * rtk_eee_init -+ * Description: -+ * EEE function initialization. -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * This API is used to initialize EEE status. -+ */ -+rtk_api_ret_t rtk_eee_init(void) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x0018, 10, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x0018, 11, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_eee_portEnable_set -+ * Description: -+ * Set enable status of EEE function. -+ * Input: -+ * port - port id. -+ * enable - enable EEE status. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_ENABLE - Invalid enable input. -+ * Note: -+ * This API can set EEE function to the specific port. -+ * The configuration of the port is as following: -+ * - DISABLE -+ * - ENABLE -+ */ -+rtk_api_ret_t rtk_eee_portEnable_set(rtk_port_t port, rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 regData; -+ rtk_uint32 phy_port; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check port is UTP port */ -+ RTK_CHK_PORT_IS_UTP(port); -+ -+ if (enable>=RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ phy_port = rtk_switch_port_L2P_get(port); -+ -+ if ((retVal = rtl8367c_setAsicEee100M(phy_port,enable))!=RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicEeeGiga(phy_port,enable))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicPHYReg(phy_port, RTL8367C_PHY_PAGE_ADDRESS, 0))!=RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_getAsicPHYReg(phy_port, 0, ®Data))!=RT_ERR_OK) -+ return retVal; -+ regData |= 0x0200; -+ if ((retVal = rtl8367c_setAsicPHYReg(phy_port, 0, regData))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_eee_portEnable_get -+ * Description: -+ * Get enable status of EEE function -+ * Input: -+ * port - Port id. -+ * Output: -+ * pEnable - Back pressure status. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * This API can get EEE function to the specific port. -+ * The configuration of the port is as following: -+ * - DISABLE -+ * - ENABLE -+ */ -+ -+rtk_api_ret_t rtk_eee_portEnable_get(rtk_port_t port, rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 regData1, regData2; -+ rtk_uint32 phy_port; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check port is UTP port */ -+ RTK_CHK_PORT_IS_UTP(port); -+ -+ if(NULL == pEnable) -+ return RT_ERR_NULL_POINTER; -+ -+ phy_port = rtk_switch_port_L2P_get(port); -+ -+ if ((retVal = rtl8367c_getAsicEee100M(phy_port,®Data1))!=RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_getAsicEeeGiga(phy_port,®Data2))!=RT_ERR_OK) -+ return retVal; -+ -+ if (regData1==1&®Data2==1) -+ *pEnable = ENABLED; -+ else -+ *pEnable = DISABLED; -+ -+ return RT_ERR_OK; -+} -+ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/i2c.c b/drivers/net/phy/rtk/rtl8367c/i2c.c -new file mode 100644 -index 000000000000..17a5f3785bd4 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/i2c.c -@@ -0,0 +1,436 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 63932 $ -+ * $Date: 2015-12-08 14:06:29 +0800 (周二, 08 十二月 2015) $ -+ * -+ * Purpose : RTK switch high-level API for RTL8367/RTL8367C -+ * Feature : Here is a list of all functions and variables in i2c module. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+ -+static rtk_I2C_16bit_mode_t rtk_i2c_mode = I2C_LSB_16BIT_MODE; -+ -+ -+/* Function Name: -+ * rtk_i2c_init -+ * Description: -+ * I2C smart function initialization. -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * Note: -+ * This API is used to initialize EEE status. -+ * need used GPIO pins -+ * OpenDrain and clock -+ */ -+rtk_api_ret_t rtk_i2c_init(void) -+{ -+ rtk_uint32 retVal; -+ switch_chip_t ChipID; -+ /* probe switch */ -+ if((retVal = rtk_switch_probe(&ChipID)) != RT_ERR_OK) -+ return retVal; -+ -+ if( ChipID == CHIP_RTL8370B ) -+ { -+ /*set GPIO8, GPIO9, OpenDrain as I2C, clock = 252KHZ */ -+ if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_SYS_CTL, 0x5c3f)) != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ return RT_ERR_FAILED; -+ return RT_ERR_OK; -+} -+ -+ -+/* Function Name: -+ * rtk_i2c_mode_set -+ * Description: -+ * Set I2C data byte-order. -+ * Input: -+ * i2cmode - byte-order mode -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_INPUT - Invalid input parameter. -+ * Note: -+ * This API can set I2c traffic's byte-order . -+ */ -+rtk_api_ret_t rtk_i2c_mode_set( rtk_I2C_16bit_mode_t i2cmode ) -+{ -+ if(i2cmode >= I2C_Mode_END) -+ { -+ return RT_ERR_INPUT; -+ } -+ else if(i2cmode == I2C_70B_LSB_16BIT_MODE) -+ { -+ rtk_i2c_mode = I2C_70B_LSB_16BIT_MODE; -+ -+ return RT_ERR_OK; -+ } -+ else if( i2cmode == I2C_LSB_16BIT_MODE) -+ { -+ rtk_i2c_mode = I2C_LSB_16BIT_MODE; -+ return RT_ERR_OK; -+ } -+ else -+ return RT_ERR_FAILED; -+ -+ return RT_ERR_OK; -+} -+ -+ -+/* Function Name: -+ * rtk_i2c_mode_get -+ * Description: -+ * Get i2c traffic byte-order setting. -+ * Input: -+ * None -+ * Output: -+ * pI2cMode - i2c byte-order -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_NULL_POINTER - input parameter is null pointer -+ * Note: -+ * The API can get i2c traffic byte-order setting. -+ */ -+rtk_api_ret_t rtk_i2c_mode_get( rtk_I2C_16bit_mode_t * pI2cMode) -+{ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ if(NULL == pI2cMode) -+ return RT_ERR_NULL_POINTER; -+ if(rtk_i2c_mode == I2C_70B_LSB_16BIT_MODE) -+ *pI2cMode = 1; -+ else if ((rtk_i2c_mode == I2C_LSB_16BIT_MODE)) -+ *pI2cMode = 0; -+ else -+ return RT_ERR_FAILED; -+ return RT_ERR_OK; -+} -+ -+ -+/* Function Name: -+ * rtk_i2c_gpioPinGroup_set -+ * Description: -+ * Set i2c SDA & SCL used GPIO pins group. -+ * Input: -+ * pins_group - GPIO pins group -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_INPUT - Invalid input parameter. -+ * Note: -+ * The API can set i2c used gpio pins group. -+ * There are three group pins could be used -+ */ -+rtk_api_ret_t rtk_i2c_gpioPinGroup_set( rtk_I2C_gpio_pin_t pins_group ) -+{ -+ rtk_uint32 retVal; -+ -+ -+ if( ( pins_group > I2C_GPIO_PIN_END )|| ( pins_group < I2C_GPIO_PIN_8_9) ) -+ return RT_ERR_INPUT; -+ -+ if( (retVal = rtl8367c_setAsicI2CGpioPinGroup(pins_group) ) != RT_ERR_OK ) -+ return retVal ; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_i2c_gpioPinGroup_get -+ * Description: -+ * Get i2c SDA & SCL used GPIO pins group. -+ * Input: -+ * None -+ * Output: -+ * pPins_group - GPIO pins group -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_NULL_POINTER - input parameter is null pointer -+ * Note: -+ * The API can get i2c used gpio pins group. -+ * There are three group pins could be used -+ */ -+rtk_api_ret_t rtk_i2c_gpioPinGroup_get( rtk_I2C_gpio_pin_t * pPins_group ) -+{ -+ rtk_uint32 retVal; -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pPins_group) -+ return RT_ERR_NULL_POINTER; -+ if( (retVal = rtl8367c_getAsicI2CGpioPinGroup(pPins_group) ) != RT_ERR_OK ) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_i2c_data_read -+ * Description: -+ * read i2c slave device register. -+ * Input: -+ * deviceAddr - access Slave device address -+ * slaveRegAddr - access Slave register address -+ * Output: -+ * pRegData - read data -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_NULL_POINTER - input parameter is null pointer -+ * Note: -+ * The API can access i2c slave and read i2c slave device register. -+ */ -+rtk_api_ret_t rtk_i2c_data_read(rtk_uint8 deviceAddr, rtk_uint32 slaveRegAddr, rtk_uint32 *pRegData) -+{ -+ rtk_uint32 retVal, counter=0; -+ rtk_uint8 controlByte_W, controlByte_R; -+ rtk_uint8 slaveRegAddr_L, slaveRegAddr_H = 0x0, temp; -+ rtk_uint8 regData_L, regData_H; -+ -+ /* control byte :deviceAddress + W, deviceAddress + R */ -+ controlByte_W = (rtk_uint8)(deviceAddr << 1) ; -+ controlByte_R = (rtk_uint8)(controlByte_W | 0x1); -+ -+ slaveRegAddr_L = (rtk_uint8) (slaveRegAddr & 0x00FF) ; -+ slaveRegAddr_H = (rtk_uint8) (slaveRegAddr >>8) ; -+ -+ if( rtk_i2c_mode == I2C_70B_LSB_16BIT_MODE) -+ { -+ temp = slaveRegAddr_L ; -+ slaveRegAddr_L = slaveRegAddr_H; -+ slaveRegAddr_H = temp; -+ } -+ -+ -+ /*check bus state: idle*/ -+ for(counter = 3000; counter>0; counter--) -+ { -+ if ( (retVal = rtl8367c_setAsicI2C_checkBusIdle() ) == RT_ERR_OK) -+ break; -+ } -+ if( counter ==0 ) -+ return retVal; /*i2c is busy*/ -+ -+ /*tx Start cmd*/ -+ if( (retVal = rtl8367c_setAsicI2CStartCmd() ) != RT_ERR_OK ) -+ return retVal ; -+ -+ -+ /*tx control _W*/ -+ if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(controlByte_W))!= RT_ERR_OK ) -+ return retVal ; -+ -+ -+ /*check if RX ack from slave*/ -+ if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK ) -+ return retVal; -+ -+ /* tx slave buffer address low 8 bits */ -+ if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(slaveRegAddr_L))!= RT_ERR_OK ) -+ return retVal ; -+ -+ /*check if RX ack from slave*/ -+ if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK ) -+ return retVal; -+ -+ -+ -+ /* tx slave buffer address high 8 bits */ -+ if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(slaveRegAddr_H))!= RT_ERR_OK ) -+ return retVal ; -+ -+ -+ /*check if RX ack from slave*/ -+ if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK ) -+ return retVal; -+ -+ -+ /*tx Start cmd*/ -+ if( (retVal = rtl8367c_setAsicI2CStartCmd() ) != RT_ERR_OK ) -+ return retVal ; -+ -+ /*tx control _R*/ -+ if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(controlByte_R))!= RT_ERR_OK ) -+ return retVal ; -+ -+ -+ /*check if RX ack from slave*/ -+ if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK ) -+ return retVal; -+ -+ -+ /* rx low 8bit data*/ -+ if( ( retVal = rtl8367c_setAsicI2CRxOneCharCmd( ®Data_L) ) != RT_ERR_OK ) -+ return retVal; -+ -+ -+ -+ /* tx ack to slave, keep receive */ -+ if( (retVal = rtl8367c_setAsicI2CTxAckCmd()) != RT_ERR_OK ) -+ return retVal; -+ -+ /* rx high 8bit data*/ -+ if( ( retVal = rtl8367c_setAsicI2CRxOneCharCmd( ®Data_H) ) != RT_ERR_OK ) -+ return retVal; -+ -+ -+ -+ /* tx Noack to slave, Stop receive */ -+ if( (retVal = rtl8367c_setAsicI2CTxNoAckCmd()) != RT_ERR_OK ) -+ return retVal; -+ -+ -+ /*tx Stop cmd */ -+ if( (retVal = rtl8367c_setAsicI2CStopCmd()) != RT_ERR_OK ) -+ return retVal; -+ -+ *pRegData = (regData_H << 8) | regData_L; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_i2c_data_write -+ * Description: -+ * write data to i2c slave device register -+ * Input: -+ * deviceAddr - access Slave device address -+ * slaveRegAddr - access Slave register address -+ * regData - data to set -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * Note: -+ * The API can access i2c slave and setting i2c slave device register. -+ */ -+rtk_api_ret_t rtk_i2c_data_write(rtk_uint8 deviceAddr, rtk_uint32 slaveRegAddr, rtk_uint32 regData) -+{ -+ rtk_uint32 retVal,counter; -+ rtk_uint8 controlByte_W; -+ rtk_uint8 slaveRegAddr_L, slaveRegAddr_H = 0x0, temp; -+ rtk_uint8 regData_L, regData_H; -+ -+ /* control byte :deviceAddress + W */ -+ controlByte_W = (rtk_uint8)(deviceAddr<< 1) ; -+ -+ slaveRegAddr_L = (rtk_uint8) (slaveRegAddr & 0x00FF) ; -+ slaveRegAddr_H = (rtk_uint8) (slaveRegAddr >>8) ; -+ -+ regData_H = (rtk_uint8) (regData>> 8); -+ regData_L = (rtk_uint8) (regData & 0x00FF); -+ -+ if( rtk_i2c_mode == I2C_70B_LSB_16BIT_MODE) -+ { -+ temp = slaveRegAddr_L ; -+ slaveRegAddr_L = slaveRegAddr_H; -+ slaveRegAddr_H = temp; -+ } -+ -+ -+ /*check bus state: idle*/ -+ for(counter = 3000; counter>0; counter--) -+ { -+ if ( (retVal = rtl8367c_setAsicI2C_checkBusIdle() ) == RT_ERR_OK) -+ break; -+ } -+ -+ if( counter ==0 ) -+ return retVal; /*i2c is busy*/ -+ -+ -+ /*tx Start cmd*/ -+ if( (retVal = rtl8367c_setAsicI2CStartCmd() ) != RT_ERR_OK ) -+ return retVal ; -+ -+ -+ /*tx control _W*/ -+ if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(controlByte_W))!= RT_ERR_OK ) -+ return retVal ; -+ -+ -+ /*check if RX ack from slave*/ -+ if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK ) -+ return retVal; -+ -+ -+ /* tx slave buffer address low 8 bits */ -+ if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(slaveRegAddr_L))!= RT_ERR_OK ) -+ return retVal; -+ -+ -+ /*check if RX ack from slave*/ -+ if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK ) -+ return retVal; -+ -+ -+ /* tx slave buffer address high 8 bits */ -+ if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(slaveRegAddr_H))!= RT_ERR_OK ) -+ return retVal; -+ -+ -+ /*check if RX ack from slave*/ -+ if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK ) -+ return retVal; -+ -+ -+ /*tx Datavlue LSB*/ -+ if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(regData_L))!= RT_ERR_OK ) -+ return retVal; -+ -+ -+ /*check if RX ack from slave*/ -+ if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK ) -+ return retVal; -+ -+ -+ /*tx Datavlue MSB*/ -+ if( (retVal = rtl8367c_setAsicI2CTxOneCharCmd(regData_H))!= RT_ERR_OK ) -+ return retVal; -+ -+ -+ /*check if RX ack from slave*/ -+ if( (retVal = rtl8367c_setAsicI2CcheckRxAck()) != RT_ERR_OK ) -+ return retVal; -+ -+ -+ /*tx Stop cmd */ -+ if( (retVal = rtl8367c_setAsicI2CStopCmd()) != RT_ERR_OK ) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/igmp.c b/drivers/net/phy/rtk/rtl8367c/igmp.c -new file mode 100644 -index 000000000000..18e145a21c8c ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/igmp.c -@@ -0,0 +1,1555 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTK switch high-level API for RTL8367/RTL8367C -+ * Feature : Here is a list of all functions and variables in IGMP module. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+ -+/* Function Name: -+ * rtk_igmp_init -+ * Description: -+ * This API enables H/W IGMP and set a default initial configuration. -+ * Input: -+ * None. -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * This API enables H/W IGMP and set a default initial configuration. -+ */ -+rtk_api_ret_t rtk_igmp_init(void) -+{ -+ rtk_api_ret_t retVal; -+ rtk_port_t port; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if ((retVal = rtl8367c_setAsicLutIpMulticastLookup(ENABLED))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicLutIpLookupMethod(1))!=RT_ERR_OK) -+ return retVal; -+ -+ RTK_SCAN_ALL_PHY_PORTMASK(port) -+ { -+ if ((retVal = rtl8367c_setAsicIGMPv1Opeartion(port, PROTOCOL_OP_ASIC))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicIGMPv2Opeartion(port, PROTOCOL_OP_ASIC))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicIGMPv3Opeartion(port, PROTOCOL_OP_FLOOD))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicMLDv1Opeartion(port, PROTOCOL_OP_ASIC))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicMLDv2Opeartion(port, PROTOCOL_OP_FLOOD))!=RT_ERR_OK) -+ return retVal; -+ } -+ -+ if ((retVal = rtl8367c_setAsicIGMPAllowDynamicRouterPort(rtk_switch_phyPortMask_get()))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicIGMPFastLeaveEn(ENABLED))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicIGMPReportLeaveFlood(1))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicIgmp(ENABLED))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_state_set -+ * Description: -+ * This API set H/W IGMP state. -+ * Input: -+ * enabled - H/W IGMP state -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error parameter -+ * Note: -+ * This API set H/W IGMP state. -+ */ -+rtk_api_ret_t rtk_igmp_state_set(rtk_enable_t enabled) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (enabled >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicIgmp(enabled))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_state_get -+ * Description: -+ * This API get H/W IGMP state. -+ * Input: -+ * None. -+ * Output: -+ * pEnabled - H/W IGMP state -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error parameter -+ * Note: -+ * This API set current H/W IGMP state. -+ */ -+rtk_api_ret_t rtk_igmp_state_get(rtk_enable_t *pEnabled) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(pEnabled == NULL) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicIgmp(pEnabled))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_static_router_port_set -+ * Description: -+ * Configure static router port -+ * Input: -+ * pPortmask - Static Port mask -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Error parameter -+ * Note: -+ * This API set static router port -+ */ -+rtk_api_ret_t rtk_igmp_static_router_port_set(rtk_portmask_t *pPortmask) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pmask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Valid port mask */ -+ if(pPortmask == NULL) -+ return RT_ERR_NULL_POINTER; -+ -+ RTK_CHK_PORTMASK_VALID(pPortmask); -+ -+ if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicIGMPStaticRouterPort(pmask))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_static_router_port_get -+ * Description: -+ * Get static router port -+ * Input: -+ * None. -+ * Output: -+ * pPortmask - Static port mask -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Error parameter -+ * Note: -+ * This API get static router port -+ */ -+rtk_api_ret_t rtk_igmp_static_router_port_get(rtk_portmask_t *pPortmask) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pmask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(pPortmask == NULL) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicIGMPStaticRouterPort(&pmask))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_protocol_set -+ * Description: -+ * set IGMP/MLD protocol action -+ * Input: -+ * port - Port ID -+ * protocol - IGMP/MLD protocol -+ * action - Per-port and per-protocol IGMP action setting -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Error parameter -+ * Note: -+ * This API set IGMP/MLD protocol action -+ */ -+rtk_api_ret_t rtk_igmp_protocol_set(rtk_port_t port, rtk_igmp_protocol_t protocol, rtk_igmp_action_t action) -+{ -+ rtk_uint32 operation; -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check port valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(protocol >= PROTOCOL_END) -+ return RT_ERR_INPUT; -+ -+ if(action >= IGMP_ACTION_END) -+ return RT_ERR_INPUT; -+ -+ switch(action) -+ { -+ case IGMP_ACTION_FORWARD: -+ operation = PROTOCOL_OP_FLOOD; -+ break; -+ case IGMP_ACTION_TRAP2CPU: -+ operation = PROTOCOL_OP_TRAP; -+ break; -+ case IGMP_ACTION_DROP: -+ operation = PROTOCOL_OP_DROP; -+ break; -+ case IGMP_ACTION_ASIC: -+ operation = PROTOCOL_OP_ASIC; -+ break; -+ default: -+ return RT_ERR_INPUT; -+ } -+ -+ switch(protocol) -+ { -+ case PROTOCOL_IGMPv1: -+ if ((retVal = rtl8367c_setAsicIGMPv1Opeartion(rtk_switch_port_L2P_get(port), operation))!=RT_ERR_OK) -+ return retVal; -+ -+ break; -+ case PROTOCOL_IGMPv2: -+ if ((retVal = rtl8367c_setAsicIGMPv2Opeartion(rtk_switch_port_L2P_get(port), operation))!=RT_ERR_OK) -+ return retVal; -+ -+ break; -+ case PROTOCOL_IGMPv3: -+ if ((retVal = rtl8367c_setAsicIGMPv3Opeartion(rtk_switch_port_L2P_get(port), operation))!=RT_ERR_OK) -+ return retVal; -+ -+ break; -+ case PROTOCOL_MLDv1: -+ if ((retVal = rtl8367c_setAsicMLDv1Opeartion(rtk_switch_port_L2P_get(port), operation))!=RT_ERR_OK) -+ return retVal; -+ -+ break; -+ case PROTOCOL_MLDv2: -+ if ((retVal = rtl8367c_setAsicMLDv2Opeartion(rtk_switch_port_L2P_get(port), operation))!=RT_ERR_OK) -+ return retVal; -+ -+ break; -+ default: -+ return RT_ERR_INPUT; -+ -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_protocol_get -+ * Description: -+ * set IGMP/MLD protocol action -+ * Input: -+ * port - Port ID -+ * protocol - IGMP/MLD protocol -+ * action - Per-port and per-protocol IGMP action setting -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Error parameter -+ * Note: -+ * This API set IGMP/MLD protocol action -+ */ -+rtk_api_ret_t rtk_igmp_protocol_get(rtk_port_t port, rtk_igmp_protocol_t protocol, rtk_igmp_action_t *pAction) -+{ -+ rtk_uint32 operation; -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check port valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(protocol >= PROTOCOL_END) -+ return RT_ERR_INPUT; -+ -+ if(pAction == NULL) -+ return RT_ERR_NULL_POINTER; -+ -+ switch(protocol) -+ { -+ case PROTOCOL_IGMPv1: -+ if ((retVal = rtl8367c_getAsicIGMPv1Opeartion(rtk_switch_port_L2P_get(port), &operation))!=RT_ERR_OK) -+ return retVal; -+ -+ break; -+ case PROTOCOL_IGMPv2: -+ if ((retVal = rtl8367c_getAsicIGMPv2Opeartion(rtk_switch_port_L2P_get(port), &operation))!=RT_ERR_OK) -+ return retVal; -+ -+ break; -+ case PROTOCOL_IGMPv3: -+ if ((retVal = rtl8367c_getAsicIGMPv3Opeartion(rtk_switch_port_L2P_get(port), &operation))!=RT_ERR_OK) -+ return retVal; -+ -+ break; -+ case PROTOCOL_MLDv1: -+ if ((retVal = rtl8367c_getAsicMLDv1Opeartion(rtk_switch_port_L2P_get(port), &operation))!=RT_ERR_OK) -+ return retVal; -+ -+ break; -+ case PROTOCOL_MLDv2: -+ if ((retVal = rtl8367c_getAsicMLDv2Opeartion(rtk_switch_port_L2P_get(port), &operation))!=RT_ERR_OK) -+ return retVal; -+ -+ break; -+ default: -+ return RT_ERR_INPUT; -+ -+ } -+ -+ switch(operation) -+ { -+ case PROTOCOL_OP_FLOOD: -+ *pAction = IGMP_ACTION_FORWARD; -+ break; -+ case PROTOCOL_OP_TRAP: -+ *pAction = IGMP_ACTION_TRAP2CPU; -+ break; -+ case PROTOCOL_OP_DROP: -+ *pAction = IGMP_ACTION_DROP; -+ break; -+ case PROTOCOL_OP_ASIC: -+ *pAction = IGMP_ACTION_ASIC; -+ break; -+ default: -+ return RT_ERR_FAILED; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_fastLeave_set -+ * Description: -+ * set IGMP/MLD FastLeave state -+ * Input: -+ * state - ENABLED: Enable FastLeave, DISABLED: disable FastLeave -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_INPUT - Error Input -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * This API set IGMP/MLD FastLeave state -+ */ -+rtk_api_ret_t rtk_igmp_fastLeave_set(rtk_enable_t state) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(state >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicIGMPFastLeaveEn((rtk_uint32)state))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_fastLeave_get -+ * Description: -+ * get IGMP/MLD FastLeave state -+ * Input: -+ * None -+ * Output: -+ * pState - ENABLED: Enable FastLeave, DISABLED: disable FastLeave -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_NULL_POINTER - NULL pointer -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * This API get IGMP/MLD FastLeave state -+ */ -+rtk_api_ret_t rtk_igmp_fastLeave_get(rtk_enable_t *pState) -+{ -+ rtk_uint32 fast_leave; -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(pState == NULL) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicIGMPFastLeaveEn(&fast_leave))!=RT_ERR_OK) -+ return retVal; -+ -+ *pState = ((fast_leave == 1) ? ENABLED : DISABLED); -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_maxGroup_set -+ * Description: -+ * Set per port multicast group learning limit. -+ * Input: -+ * port - Port ID -+ * group - The number of multicast group learning limit. -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_PORT_ID - Error Port ID -+ * RT_ERR_OUT_OF_RANGE - parameter out of range -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * This API set per port multicast group learning limit. -+ */ -+rtk_api_ret_t rtk_igmp_maxGroup_set(rtk_port_t port, rtk_uint32 group) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check port valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(group > RTL8367C_IGMP_MAX_GOUP) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if ((retVal = rtl8367c_setAsicIGMPPortMAXGroup(rtk_switch_port_L2P_get(port), group))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_maxGroup_get -+ * Description: -+ * Get per port multicast group learning limit. -+ * Input: -+ * port - Port ID -+ * Output: -+ * pGroup - The number of multicast group learning limit. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_PORT_ID - Error Port ID -+ * RT_ERR_NULL_POINTER - Null pointer -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * This API get per port multicast group learning limit. -+ */ -+rtk_api_ret_t rtk_igmp_maxGroup_get(rtk_port_t port, rtk_uint32 *pGroup) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check port valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(pGroup == NULL) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicIGMPPortMAXGroup(rtk_switch_port_L2P_get(port), pGroup))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_currentGroup_get -+ * Description: -+ * Get per port multicast group learning count. -+ * Input: -+ * port - Port ID -+ * Output: -+ * pGroup - The number of multicast group learning count. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_PORT_ID - Error Port ID -+ * RT_ERR_NULL_POINTER - Null pointer -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * This API get per port multicast group learning count. -+ */ -+rtk_api_ret_t rtk_igmp_currentGroup_get(rtk_port_t port, rtk_uint32 *pGroup) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check port valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(pGroup == NULL) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicIGMPPortCurrentGroup(rtk_switch_port_L2P_get(port), pGroup))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_tableFullAction_set -+ * Description: -+ * set IGMP/MLD Table Full Action -+ * Input: -+ * action - Table Full Action -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_INPUT - Error Input -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ */ -+rtk_api_ret_t rtk_igmp_tableFullAction_set(rtk_igmp_tableFullAction_t action) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(action >= IGMP_TABLE_FULL_OP_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicIGMPTableFullOP((rtk_uint32)action))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_tableFullAction_get -+ * Description: -+ * get IGMP/MLD Table Full Action -+ * Input: -+ * None -+ * Output: -+ * pAction - Table Full Action -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_NULL_POINTER - Null pointer -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ */ -+rtk_api_ret_t rtk_igmp_tableFullAction_get(rtk_igmp_tableFullAction_t *pAction) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pAction) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicIGMPTableFullOP((rtk_uint32 *)pAction))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_checksumErrorAction_set -+ * Description: -+ * set IGMP/MLD Checksum Error Action -+ * Input: -+ * action - Checksum error Action -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_INPUT - Error Input -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ */ -+rtk_api_ret_t rtk_igmp_checksumErrorAction_set(rtk_igmp_checksumErrorAction_t action) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(action >= IGMP_CRC_ERR_OP_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicIGMPCRCErrOP((rtk_uint32)action))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+ -+/* Function Name: -+ * rtk_igmp_checksumErrorAction_get -+ * Description: -+ * get IGMP/MLD Checksum Error Action -+ * Input: -+ * None -+ * Output: -+ * pAction - Checksum error Action -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_NULL_POINTER - Null pointer -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ */ -+rtk_api_ret_t rtk_igmp_checksumErrorAction_get(rtk_igmp_checksumErrorAction_t *pAction) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pAction) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicIGMPCRCErrOP((rtk_uint32 *)pAction))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_leaveTimer_set -+ * Description: -+ * set IGMP/MLD Leave timer -+ * Input: -+ * timer - Leave timer -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_INPUT - Error Input -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ */ -+rtk_api_ret_t rtk_igmp_leaveTimer_set(rtk_uint32 timer) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(timer > RTL8367C_MAX_LEAVE_TIMER) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicIGMPLeaveTimer(timer))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_leaveTimer_get -+ * Description: -+ * get IGMP/MLD Leave timer -+ * Input: -+ * None -+ * Output: -+ * pTimer - Leave Timer. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_NULL_POINTER - Null pointer -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ */ -+rtk_api_ret_t rtk_igmp_leaveTimer_get(rtk_uint32 *pTimer) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pTimer) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicIGMPLeaveTimer(pTimer))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_queryInterval_set -+ * Description: -+ * set IGMP/MLD Query Interval -+ * Input: -+ * interval - Query Interval -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_INPUT - Error Input -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ */ -+rtk_api_ret_t rtk_igmp_queryInterval_set(rtk_uint32 interval) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(interval > RTL8367C_MAX_QUERY_INT) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicIGMPQueryInterval(interval))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_queryInterval_get -+ * Description: -+ * get IGMP/MLD Query Interval -+ * Input: -+ * None. -+ * Output: -+ * pInterval - Query Interval -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_NULL_POINTER - Null pointer -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ */ -+rtk_api_ret_t rtk_igmp_queryInterval_get(rtk_uint32 *pInterval) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pInterval) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicIGMPQueryInterval(pInterval))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_robustness_set -+ * Description: -+ * set IGMP/MLD Robustness value -+ * Input: -+ * robustness - Robustness value -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_INPUT - Error Input -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ */ -+rtk_api_ret_t rtk_igmp_robustness_set(rtk_uint32 robustness) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(robustness > RTL8367C_MAX_ROB_VAR) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicIGMPRobVar(robustness))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_robustness_get -+ * Description: -+ * get IGMP/MLD Robustness value -+ * Input: -+ * None -+ * Output: -+ * pRobustness - Robustness value. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_NULL_POINTER - Null pointer -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ */ -+rtk_api_ret_t rtk_igmp_robustness_get(rtk_uint32 *pRobustness) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pRobustness) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicIGMPRobVar(pRobustness))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_dynamicRouterRortAllow_set -+ * Description: -+ * Configure dynamic router port allow option -+ * Input: -+ * pPortmask - Dynamic Port allow mask -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Error parameter -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_igmp_dynamicRouterPortAllow_set(rtk_portmask_t *pPortmask) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pmask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pPortmask) -+ return RT_ERR_NULL_POINTER; -+ -+ RTK_CHK_PORTMASK_VALID(pPortmask); -+ -+ if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicIGMPAllowDynamicRouterPort(pmask))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_dynamicRouterRortAllow_get -+ * Description: -+ * Get dynamic router port allow option -+ * Input: -+ * None. -+ * Output: -+ * pPortmask - Dynamic Port allow mask -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_NULL_POINTER - Null pointer -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Error parameter -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_igmp_dynamicRouterPortAllow_get(rtk_portmask_t *pPortmask) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pmask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pPortmask) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicIGMPAllowDynamicRouterPort(&pmask))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_dynamicRouterPort_get -+ * Description: -+ * Get dynamic router port -+ * Input: -+ * None. -+ * Output: -+ * pDynamicRouterPort - Dynamic Router Port -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_NULL_POINTER - Null pointer -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Error parameter -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_igmp_dynamicRouterPort_get(rtk_igmp_dynamicRouterPort_t *pDynamicRouterPort) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 port; -+ rtk_uint32 timer; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pDynamicRouterPort) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicIGMPdynamicRouterPort1(&port, &timer))!= RT_ERR_OK) -+ return retVal; -+ -+ if (port == RTL8367C_ROUTER_PORT_INVALID) -+ { -+ pDynamicRouterPort->dynamicRouterPort0Valid = DISABLED; -+ pDynamicRouterPort->dynamicRouterPort0 = 0; -+ pDynamicRouterPort->dynamicRouterPort0Timer = 0; -+ } -+ else -+ { -+ pDynamicRouterPort->dynamicRouterPort0Valid = ENABLED; -+ pDynamicRouterPort->dynamicRouterPort0 = rtk_switch_port_P2L_get(port); -+ pDynamicRouterPort->dynamicRouterPort0Timer = timer; -+ } -+ -+ if ((retVal = rtl8367c_getAsicIGMPdynamicRouterPort2(&port, &timer))!= RT_ERR_OK) -+ return retVal; -+ -+ if (port == RTL8367C_ROUTER_PORT_INVALID) -+ { -+ pDynamicRouterPort->dynamicRouterPort1Valid = DISABLED; -+ pDynamicRouterPort->dynamicRouterPort1 = 0; -+ pDynamicRouterPort->dynamicRouterPort1Timer = 0; -+ } -+ else -+ { -+ pDynamicRouterPort->dynamicRouterPort1Valid = ENABLED; -+ pDynamicRouterPort->dynamicRouterPort1 = rtk_switch_port_P2L_get(port); -+ pDynamicRouterPort->dynamicRouterPort1Timer = timer; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_suppressionEnable_set -+ * Description: -+ * Configure IGMPv1/v2 & MLDv1 Report/Leave/Done suppression -+ * Input: -+ * reportSuppression - Report suppression -+ * leaveSuppression - Leave suppression -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_igmp_suppressionEnable_set(rtk_enable_t reportSuppression, rtk_enable_t leaveSuppression) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(reportSuppression >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if(leaveSuppression >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicIGMPSuppression((rtk_uint32)reportSuppression, (rtk_uint32)leaveSuppression))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_suppressionEnable_get -+ * Description: -+ * Get IGMPv1/v2 & MLDv1 Report/Leave/Done suppression -+ * Input: -+ * None -+ * Output: -+ * pReportSuppression - Report suppression -+ * pLeaveSuppression - Leave suppression -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_igmp_suppressionEnable_get(rtk_enable_t *pReportSuppression, rtk_enable_t *pLeaveSuppression) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pReportSuppression) -+ return RT_ERR_NULL_POINTER; -+ -+ if(NULL == pLeaveSuppression) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicIGMPSuppression((rtk_uint32 *)pReportSuppression, (rtk_uint32 *)pLeaveSuppression))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_portRxPktEnable_set -+ * Description: -+ * Configure IGMP/MLD RX Packet configuration -+ * Input: -+ * port - Port ID -+ * pRxCfg - RX Packet Configuration -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_igmp_portRxPktEnable_set(rtk_port_t port, rtk_igmp_rxPktEnable_t *pRxCfg) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check port valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(NULL == pRxCfg) -+ return RT_ERR_NULL_POINTER; -+ -+ if(pRxCfg->rxQuery >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if(pRxCfg->rxReport >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if(pRxCfg->rxLeave >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if(pRxCfg->rxMRP >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if(pRxCfg->rxMcast >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicIGMPQueryRX(rtk_switch_port_L2P_get(port), (rtk_uint32)pRxCfg->rxQuery))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicIGMPReportRX(rtk_switch_port_L2P_get(port), (rtk_uint32)pRxCfg->rxReport))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicIGMPLeaveRX(rtk_switch_port_L2P_get(port), (rtk_uint32)pRxCfg->rxLeave))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicIGMPMRPRX(rtk_switch_port_L2P_get(port), (rtk_uint32)pRxCfg->rxMRP))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicIGMPMcDataRX(rtk_switch_port_L2P_get(port), (rtk_uint32)pRxCfg->rxMcast))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_portRxPktEnable_get -+ * Description: -+ * Get IGMP/MLD RX Packet configuration -+ * Input: -+ * port - Port ID -+ * pRxCfg - RX Packet Configuration -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_igmp_portRxPktEnable_get(rtk_port_t port, rtk_igmp_rxPktEnable_t *pRxCfg) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check port valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(NULL == pRxCfg) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicIGMPQueryRX(rtk_switch_port_L2P_get(port), (rtk_uint32 *)&(pRxCfg->rxQuery)))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicIGMPReportRX(rtk_switch_port_L2P_get(port), (rtk_uint32 *)&(pRxCfg->rxReport)))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicIGMPLeaveRX(rtk_switch_port_L2P_get(port), (rtk_uint32 *)&(pRxCfg->rxLeave)))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicIGMPMRPRX(rtk_switch_port_L2P_get(port), (rtk_uint32 *)&(pRxCfg->rxMRP)))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicIGMPMcDataRX(rtk_switch_port_L2P_get(port), (rtk_uint32 *)&(pRxCfg->rxMcast)))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_groupInfo_get -+ * Description: -+ * Get IGMP/MLD Group database -+ * Input: -+ * index - Index (0~255) -+ * Output: -+ * pGroup - Group database information. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_igmp_groupInfo_get(rtk_uint32 index, rtk_igmp_groupInfo_t *pGroup) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 valid; -+ rtl8367c_igmpgroup grp; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check index */ -+ if(index > RTL8367C_IGMP_MAX_GOUP) -+ return RT_ERR_INPUT; -+ -+ if(NULL == pGroup) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicIGMPGroup(index, &valid, &grp))!=RT_ERR_OK) -+ return retVal; -+ -+ memset(pGroup, 0x00, sizeof(rtk_igmp_groupInfo_t)); -+ pGroup->valid = valid; -+ pGroup->reportSuppFlag = grp.report_supp_flag; -+ -+ if(grp.p0_timer != 0) -+ { -+ RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(0)); -+ pGroup->timer[rtk_switch_port_P2L_get(0)] = grp.p0_timer; -+ } -+ -+ if(grp.p1_timer != 0) -+ { -+ RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(1)); -+ pGroup->timer[rtk_switch_port_P2L_get(1)] = grp.p1_timer; -+ } -+ -+ if(grp.p2_timer != 0) -+ { -+ RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(2)); -+ pGroup->timer[rtk_switch_port_P2L_get(2)] = grp.p2_timer; -+ } -+ -+ if(grp.p3_timer != 0) -+ { -+ RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(3)); -+ pGroup->timer[rtk_switch_port_P2L_get(3)] = grp.p3_timer; -+ } -+ -+ if(grp.p4_timer != 0) -+ { -+ RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(4)); -+ pGroup->timer[rtk_switch_port_P2L_get(4)] = grp.p4_timer; -+ } -+ -+ if(grp.p5_timer != 0) -+ { -+ RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(5)); -+ pGroup->timer[rtk_switch_port_P2L_get(5)] = grp.p5_timer; -+ } -+ -+ if(grp.p6_timer != 0) -+ { -+ RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(6)); -+ pGroup->timer[rtk_switch_port_P2L_get(6)] = grp.p6_timer; -+ } -+ -+ if(grp.p7_timer != 0) -+ { -+ RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(7)); -+ pGroup->timer[rtk_switch_port_P2L_get(7)] = grp.p7_timer; -+ } -+ -+ if(grp.p8_timer != 0) -+ { -+ RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(8)); -+ pGroup->timer[rtk_switch_port_P2L_get(8)] = grp.p8_timer; -+ } -+ -+ if(grp.p9_timer != 0) -+ { -+ RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(9)); -+ pGroup->timer[rtk_switch_port_P2L_get(9)] = grp.p9_timer; -+ } -+ -+ if(grp.p10_timer != 0) -+ { -+ RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(10)); -+ pGroup->timer[rtk_switch_port_P2L_get(10)] = grp.p10_timer; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_ReportLeaveFwdAction_set -+ * Description: -+ * Set Report Leave packet forwarding action -+ * Input: -+ * action - Action -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_igmp_ReportLeaveFwdAction_set(rtk_igmp_ReportLeaveFwdAct_t action) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 regData; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ switch(action) -+ { -+ case IGMP_REPORT_LEAVE_TO_ROUTER: -+ regData = 1; -+ break; -+ case IGMP_REPORT_LEAVE_TO_ALLPORT: -+ regData = 2; -+ break; -+ case IGMP_REPORT_LEAVE_TO_ROUTER_PORT_ADV: -+ regData = 3; -+ break; -+ default: -+ return RT_ERR_INPUT; -+ } -+ -+ if ((retVal = rtl8367c_setAsicIGMPReportLeaveFlood(regData))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_ReportLeaveFwdAction_get -+ * Description: -+ * Get Report Leave packet forwarding action -+ * Input: -+ * action - Action -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * RT_ERR_NULL_POINTER - Null Pointer -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_igmp_ReportLeaveFwdAction_get(rtk_igmp_ReportLeaveFwdAct_t *pAction) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 regData; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pAction) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicIGMPReportLeaveFlood(®Data))!=RT_ERR_OK) -+ return retVal; -+ -+ switch(regData) -+ { -+ case 1: -+ *pAction = IGMP_REPORT_LEAVE_TO_ROUTER; -+ break; -+ case 2: -+ *pAction = IGMP_REPORT_LEAVE_TO_ALLPORT; -+ break; -+ case 3: -+ *pAction = IGMP_REPORT_LEAVE_TO_ROUTER_PORT_ADV; -+ break; -+ default: -+ return RT_ERR_FAILED; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_dropLeaveZeroEnable_set -+ * Description: -+ * Set the function of dropping Leave packet with group IP = 0.0.0.0 -+ * Input: -+ * enabled - Action 1: drop, 0:pass -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_igmp_dropLeaveZeroEnable_set(rtk_enable_t enabled) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(enabled >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicIGMPDropLeaveZero(enabled))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+ -+} -+ -+/* Function Name: -+ * rtk_igmp_dropLeaveZeroEnable_get -+ * Description: -+ * Get the function of dropping Leave packet with group IP = 0.0.0.0 -+ * Input: -+ * None -+ * Output: -+ * pEnabled. - Action 1: drop, 0:pass -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * RT_ERR_NULL_POINTER - Null Pointer -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_igmp_dropLeaveZeroEnable_get(rtk_enable_t *pEnabled) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pEnabled) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicIGMPDropLeaveZero((rtk_uint32 *)pEnabled))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+ -+} -+ -+/* Function Name: -+ * rtk_igmp_bypassGroupRange_set -+ * Description: -+ * Set Bypass group -+ * Input: -+ * group - bypassed group -+ * enabled - enabled 1: Bypassed, 0: not bypass -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_igmp_bypassGroupRange_set(rtk_igmp_bypassGroup_t group, rtk_enable_t enabled) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(group >= IGMP_BYPASS_GROUP_END) -+ return RT_ERR_INPUT; -+ -+ if(enabled >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicIGMPBypassGroup(group, enabled))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_igmp_bypassGroupRange_get -+ * Description: -+ * get Bypass group -+ * Input: -+ * group - bypassed group -+ * Output: -+ * pEnable - enabled 1: Bypassed, 0: not bypass -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * RT_ERR_NULL_POINTER - Null Pointer -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_igmp_bypassGroupRange_get(rtk_igmp_bypassGroup_t group, rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(group >= IGMP_BYPASS_GROUP_END) -+ return RT_ERR_INPUT; -+ -+ if(NULL == pEnable) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicIGMPBypassGroup(group, pEnable))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -diff --git a/drivers/net/phy/rtk/rtl8367c/include/acl.h b/drivers/net/phy/rtk/rtl8367c/include/acl.h -new file mode 100644 -index 000000000000..634e7325d696 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/acl.h -@@ -0,0 +1,990 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * Purpose : RTL8367/RTL8367C switch high-level API -+ * -+ * Feature : The file includes ACL module high-layer API definition -+ * -+ */ -+ -+#ifndef __RTK_API_ACL_H__ -+#define __RTK_API_ACL_H__ -+ -+/* -+ * Data Type Declaration -+ */ -+#define RTK_FILTER_RAW_FIELD_NUMBER 8 -+ -+#define ACL_DEFAULT_ABILITY 0 -+#define ACL_DEFAULT_UNMATCH_PERMIT 1 -+ -+#define ACL_RULE_FREE 0 -+#define ACL_RULE_INAVAILABLE 1 -+#define ACL_RULE_CARETAG_MASK 0x1F -+#define FILTER_POLICING_MAX 4 -+#define FILTER_LOGGING_MAX 8 -+#define FILTER_PATTERN_MAX 4 -+ -+#define FILTER_ENACT_CVLAN_MASK 0x01 -+#define FILTER_ENACT_SVLAN_MASK 0x02 -+#define FILTER_ENACT_PRIORITY_MASK 0x04 -+#define FILTER_ENACT_POLICING_MASK 0x08 -+#define FILTER_ENACT_FWD_MASK 0x10 -+#define FILTER_ENACT_INTGPIO_MASK 0x20 -+#define FILTER_ENACT_INIT_MASK 0x3F -+ -+typedef enum rtk_filter_act_cactext_e -+{ -+ FILTER_ENACT_CACTEXT_VLANONLY=0, -+ FILTER_ENACT_CACTEXT_BOTHVLANTAG, -+ FILTER_ENACT_CACTEXT_TAGONLY, -+ FILTER_ENACT_CACTEXT_END, -+ -+ -+}rtk_filter_act_cactext_t; -+ -+typedef enum rtk_filter_act_ctagfmt_e -+{ -+ FILTER_CTAGFMT_UNTAG=0, -+ FILTER_CTAGFMT_TAG, -+ FILTER_CTAGFMT_KEEP, -+ FILTER_CTAGFMT_KEEP1PRMK, -+ -+ -+}rtk_filter_act_ctag_t; -+ -+ -+ -+ -+ -+#define RTK_MAX_NUM_OF_FILTER_TYPE 5 -+#define RTK_MAX_NUM_OF_FILTER_FIELD 8 -+ -+#define RTK_DOT_1AS_TIMESTAMP_UNIT_IN_WORD_LENGTH 3UL -+#define RTK_IPV6_ADDR_WORD_LENGTH 4UL -+ -+#define FILTER_ENACT_CVLAN_TYPE(type) (type - FILTER_ENACT_CVLAN_INGRESS) -+#define FILTER_ENACT_SVLAN_TYPE(type) (type - FILTER_ENACT_SVLAN_INGRESS) -+#define FILTER_ENACT_FWD_TYPE(type) (type - FILTER_ENACT_ADD_DSTPORT) -+#define FILTER_ENACT_PRI_TYPE(type) (type - FILTER_ENACT_PRIORITY) -+ -+#define RTK_FILTER_FIELD_USED_MAX 8 -+#define RTK_FILTER_FIELD_INDEX(template, index) ((template << 4) + index) -+ -+ -+typedef enum rtk_filter_act_enable_e -+{ -+ /* CVLAN */ -+ FILTER_ENACT_CVLAN_INGRESS = 0, -+ FILTER_ENACT_CVLAN_EGRESS, -+ FILTER_ENACT_CVLAN_SVID, -+ FILTER_ENACT_POLICING_1, -+ -+ /* SVLAN */ -+ FILTER_ENACT_SVLAN_INGRESS, -+ FILTER_ENACT_SVLAN_EGRESS, -+ FILTER_ENACT_SVLAN_CVID, -+ FILTER_ENACT_POLICING_2, -+ -+ /* Policing and Logging */ -+ FILTER_ENACT_POLICING_0, -+ -+ /* Forward */ -+ FILTER_ENACT_COPY_CPU, -+ FILTER_ENACT_DROP, -+ FILTER_ENACT_ADD_DSTPORT, -+ FILTER_ENACT_REDIRECT, -+ FILTER_ENACT_MIRROR, -+ FILTER_ENACT_TRAP_CPU, -+ FILTER_ENACT_ISOLATION, -+ -+ /* QoS */ -+ FILTER_ENACT_PRIORITY, -+ FILTER_ENACT_DSCP_REMARK, -+ FILTER_ENACT_1P_REMARK, -+ FILTER_ENACT_POLICING_3, -+ -+ /* Interrutp and GPO */ -+ FILTER_ENACT_INTERRUPT, -+ FILTER_ENACT_GPO, -+ -+ /*VLAN tag*/ -+ FILTER_ENACT_EGRESSCTAG_UNTAG, -+ FILTER_ENACT_EGRESSCTAG_TAG, -+ FILTER_ENACT_EGRESSCTAG_KEEP, -+ FILTER_ENACT_EGRESSCTAG_KEEPAND1PRMK, -+ -+ FILTER_ENACT_END, -+} rtk_filter_act_enable_t; -+ -+ -+typedef struct -+{ -+ rtk_filter_act_enable_t actEnable[FILTER_ENACT_END]; -+ -+ /* CVLAN acton */ -+ rtk_uint32 filterCvlanVid; -+ rtk_uint32 filterCvlanIdx; -+ /* SVLAN action */ -+ rtk_uint32 filterSvlanVid; -+ rtk_uint32 filterSvlanIdx; -+ -+ /* Policing action */ -+ rtk_uint32 filterPolicingIdx[FILTER_POLICING_MAX]; -+ -+ /* Forwarding action */ -+ rtk_portmask_t filterPortmask; -+ -+ /* QOS action */ -+ rtk_uint32 filterPriority; -+ -+ /*GPO*/ -+ rtk_uint32 filterPin; -+ -+} rtk_filter_action_t; -+ -+typedef struct rtk_filter_flag_s -+{ -+ rtk_uint32 value; -+ rtk_uint32 mask; -+} rtk_filter_flag_t; -+ -+typedef enum rtk_filter_care_tag_index_e -+{ -+ CARE_TAG_CTAG = 0, -+ CARE_TAG_STAG, -+ CARE_TAG_PPPOE, -+ CARE_TAG_IPV4, -+ CARE_TAG_IPV6, -+ CARE_TAG_TCP, -+ CARE_TAG_UDP, -+ CARE_TAG_ARP, -+ CARE_TAG_RSV1, -+ CARE_TAG_RSV2, -+ CARE_TAG_ICMP, -+ CARE_TAG_IGMP, -+ CARE_TAG_LLC, -+ CARE_TAG_RSV3, -+ CARE_TAG_HTTP, -+ CARE_TAG_RSV4, -+ CARE_TAG_RSV5, -+ CARE_TAG_DHCP, -+ CARE_TAG_DHCPV6, -+ CARE_TAG_SNMP, -+ CARE_TAG_OAM, -+ CARE_TAG_END, -+} rtk_filter_care_tag_index_t; -+ -+typedef struct rtk_filter_care_tag_s -+{ -+ rtk_filter_flag_t tagType[CARE_TAG_END]; -+} rtk_filter_care_tag_t; -+ -+typedef struct rtk_filter_field rtk_filter_field_t; -+ -+typedef struct -+{ -+ rtk_uint32 value[RTK_DOT_1AS_TIMESTAMP_UNIT_IN_WORD_LENGTH]; -+} rtk_filter_dot1as_timestamp_t; -+ -+typedef enum rtk_filter_field_data_type_e -+{ -+ FILTER_FIELD_DATA_MASK = 0, -+ FILTER_FIELD_DATA_RANGE, -+ FILTER_FIELD_DATA_END , -+} rtk_filter_field_data_type_t; -+ -+typedef struct rtk_filter_ip_s -+{ -+ rtk_uint32 dataType; -+ rtk_uint32 rangeStart; -+ rtk_uint32 rangeEnd; -+ rtk_uint32 value; -+ rtk_uint32 mask; -+} rtk_filter_ip_t; -+ -+typedef struct rtk_filter_mac_s -+{ -+ rtk_uint32 dataType; -+ rtk_mac_t value; -+ rtk_mac_t mask; -+ rtk_mac_t rangeStart; -+ rtk_mac_t rangeEnd; -+} rtk_filter_mac_t; -+ -+typedef rtk_uint32 rtk_filter_op_t; -+ -+typedef struct rtk_filter_value_s -+{ -+ rtk_uint32 dataType; -+ rtk_uint32 value; -+ rtk_uint32 mask; -+ rtk_uint32 rangeStart; -+ rtk_uint32 rangeEnd; -+ -+} rtk_filter_value_t; -+ -+typedef struct rtk_filter_activeport_s -+{ -+ rtk_portmask_t value; -+ rtk_portmask_t mask; -+ -+} rtk_filter_activeport_t; -+ -+ -+ -+typedef struct rtk_filter_tag_s -+{ -+ rtk_filter_value_t pri; -+ rtk_filter_flag_t cfi; -+ rtk_filter_value_t vid; -+} rtk_filter_tag_t; -+ -+typedef struct rtk_filter_ipFlag_s -+{ -+ rtk_filter_flag_t xf; -+ rtk_filter_flag_t mf; -+ rtk_filter_flag_t df; -+} rtk_filter_ipFlag_t; -+ -+typedef struct -+{ -+ rtk_uint32 addr[RTK_IPV6_ADDR_WORD_LENGTH]; -+} rtk_filter_ip6_addr_t; -+ -+typedef struct -+{ -+ rtk_uint32 dataType; -+ rtk_filter_ip6_addr_t value; -+ rtk_filter_ip6_addr_t mask; -+ rtk_filter_ip6_addr_t rangeStart; -+ rtk_filter_ip6_addr_t rangeEnd; -+} rtk_filter_ip6_t; -+ -+typedef rtk_uint32 rtk_filter_number_t; -+ -+typedef struct rtk_filter_pattern_s -+{ -+ rtk_uint32 value[FILTER_PATTERN_MAX]; -+ rtk_uint32 mask[FILTER_PATTERN_MAX]; -+} rtk_filter_pattern_t; -+ -+typedef struct rtk_filter_tcpFlag_s -+{ -+ rtk_filter_flag_t urg; -+ rtk_filter_flag_t ack; -+ rtk_filter_flag_t psh; -+ rtk_filter_flag_t rst; -+ rtk_filter_flag_t syn; -+ rtk_filter_flag_t fin; -+ rtk_filter_flag_t ns; -+ rtk_filter_flag_t cwr; -+ rtk_filter_flag_t ece; -+} rtk_filter_tcpFlag_t; -+ -+typedef rtk_uint32 rtk_filter_field_raw_t; -+ -+typedef enum rtk_filter_field_temple_input_e -+{ -+ FILTER_FIELD_TEMPLE_INPUT_TYPE = 0, -+ FILTER_FIELD_TEMPLE_INPUT_INDEX, -+ FILTER_FIELD_TEMPLE_INPUT_MAX , -+} rtk_filter_field_temple_input_t; -+ -+struct rtk_filter_field -+{ -+ rtk_uint32 fieldType; -+ -+ union -+ { -+ /* L2 struct */ -+ rtk_filter_mac_t dmac; -+ rtk_filter_mac_t smac; -+ rtk_filter_value_t etherType; -+ rtk_filter_tag_t ctag; -+ rtk_filter_tag_t relayCtag; -+ rtk_filter_tag_t stag; -+ rtk_filter_tag_t l2tag; -+ rtk_filter_dot1as_timestamp_t dot1asTimeStamp; -+ rtk_filter_mac_t mac; -+ -+ /* L3 struct */ -+ rtk_filter_ip_t sip; -+ rtk_filter_ip_t dip; -+ rtk_filter_ip_t ip; -+ rtk_filter_value_t protocol; -+ rtk_filter_value_t ipTos; -+ rtk_filter_ipFlag_t ipFlag; -+ rtk_filter_value_t ipOffset; -+ rtk_filter_ip6_t sipv6; -+ rtk_filter_ip6_t dipv6; -+ rtk_filter_ip6_t ipv6; -+ rtk_filter_value_t ipv6TrafficClass; -+ rtk_filter_value_t ipv6NextHeader; -+ rtk_filter_value_t flowLabel; -+ -+ /* L4 struct */ -+ rtk_filter_value_t tcpSrcPort; -+ rtk_filter_value_t tcpDstPort; -+ rtk_filter_tcpFlag_t tcpFlag; -+ rtk_filter_value_t tcpSeqNumber; -+ rtk_filter_value_t tcpAckNumber; -+ rtk_filter_value_t udpSrcPort; -+ rtk_filter_value_t udpDstPort; -+ rtk_filter_value_t icmpCode; -+ rtk_filter_value_t icmpType; -+ rtk_filter_value_t igmpType; -+ -+ /* pattern match */ -+ rtk_filter_pattern_t pattern; -+ -+ rtk_filter_value_t inData; -+ -+ } filter_pattern_union; -+ -+ rtk_uint32 fieldTemplateNo; -+ rtk_uint32 fieldTemplateIdx[RTK_FILTER_FIELD_USED_MAX]; -+ -+ struct rtk_filter_field *next; -+}; -+ -+typedef enum rtk_filter_field_type_e -+{ -+ FILTER_FIELD_DMAC = 0, -+ FILTER_FIELD_SMAC, -+ FILTER_FIELD_ETHERTYPE, -+ FILTER_FIELD_CTAG, -+ FILTER_FIELD_STAG, -+ -+ FILTER_FIELD_IPV4_SIP, -+ FILTER_FIELD_IPV4_DIP, -+ FILTER_FIELD_IPV4_TOS, -+ FILTER_FIELD_IPV4_PROTOCOL, -+ FILTER_FIELD_IPV4_FLAG, -+ FILTER_FIELD_IPV4_OFFSET, -+ FILTER_FIELD_IPV6_SIPV6, -+ FILTER_FIELD_IPV6_DIPV6, -+ FILTER_FIELD_IPV6_TRAFFIC_CLASS, -+ FILTER_FIELD_IPV6_NEXT_HEADER, -+ -+ FILTER_FIELD_TCP_SPORT, -+ FILTER_FIELD_TCP_DPORT, -+ FILTER_FIELD_TCP_FLAG, -+ FILTER_FIELD_UDP_SPORT, -+ FILTER_FIELD_UDP_DPORT, -+ FILTER_FIELD_ICMP_CODE, -+ FILTER_FIELD_ICMP_TYPE, -+ FILTER_FIELD_IGMP_TYPE, -+ -+ FILTER_FIELD_VID_RANGE, -+ FILTER_FIELD_IP_RANGE, -+ FILTER_FIELD_PORT_RANGE, -+ -+ FILTER_FIELD_USER_DEFINED00, -+ FILTER_FIELD_USER_DEFINED01, -+ FILTER_FIELD_USER_DEFINED02, -+ FILTER_FIELD_USER_DEFINED03, -+ FILTER_FIELD_USER_DEFINED04, -+ FILTER_FIELD_USER_DEFINED05, -+ FILTER_FIELD_USER_DEFINED06, -+ FILTER_FIELD_USER_DEFINED07, -+ FILTER_FIELD_USER_DEFINED08, -+ FILTER_FIELD_USER_DEFINED09, -+ FILTER_FIELD_USER_DEFINED10, -+ FILTER_FIELD_USER_DEFINED11, -+ FILTER_FIELD_USER_DEFINED12, -+ FILTER_FIELD_USER_DEFINED13, -+ FILTER_FIELD_USER_DEFINED14, -+ FILTER_FIELD_USER_DEFINED15, -+ -+ FILTER_FIELD_PATTERN_MATCH, -+ -+ FILTER_FIELD_END, -+} rtk_filter_field_type_t; -+ -+ -+typedef enum rtk_filter_field_type_raw_e -+{ -+ FILTER_FIELD_RAW_UNUSED = 0, -+ FILTER_FIELD_RAW_DMAC_15_0, -+ FILTER_FIELD_RAW_DMAC_31_16, -+ FILTER_FIELD_RAW_DMAC_47_32, -+ FILTER_FIELD_RAW_SMAC_15_0, -+ FILTER_FIELD_RAW_SMAC_31_16, -+ FILTER_FIELD_RAW_SMAC_47_32, -+ FILTER_FIELD_RAW_ETHERTYPE, -+ FILTER_FIELD_RAW_STAG, -+ FILTER_FIELD_RAW_CTAG, -+ -+ FILTER_FIELD_RAW_IPV4_SIP_15_0 = 0x10, -+ FILTER_FIELD_RAW_IPV4_SIP_31_16, -+ FILTER_FIELD_RAW_IPV4_DIP_15_0, -+ FILTER_FIELD_RAW_IPV4_DIP_31_16, -+ -+ -+ FILTER_FIELD_RAW_IPV6_SIP_15_0 = 0x20, -+ FILTER_FIELD_RAW_IPV6_SIP_31_16, -+ FILTER_FIELD_RAW_IPV6_DIP_15_0 = 0x28, -+ FILTER_FIELD_RAW_IPV6_DIP_31_16, -+ -+ FILTER_FIELD_RAW_VIDRANGE = 0x30, -+ FILTER_FIELD_RAW_IPRANGE, -+ FILTER_FIELD_RAW_PORTRANGE, -+ FILTER_FIELD_RAW_FIELD_VALID, -+ -+ FILTER_FIELD_RAW_FIELD_SELECT00 = 0x40, -+ FILTER_FIELD_RAW_FIELD_SELECT01, -+ FILTER_FIELD_RAW_FIELD_SELECT02, -+ FILTER_FIELD_RAW_FIELD_SELECT03, -+ FILTER_FIELD_RAW_FIELD_SELECT04, -+ FILTER_FIELD_RAW_FIELD_SELECT05, -+ FILTER_FIELD_RAW_FIELD_SELECT06, -+ FILTER_FIELD_RAW_FIELD_SELECT07, -+ FILTER_FIELD_RAW_FIELD_SELECT08, -+ FILTER_FIELD_RAW_FIELD_SELECT09, -+ FILTER_FIELD_RAW_FIELD_SELECT10, -+ FILTER_FIELD_RAW_FIELD_SELECT11, -+ FILTER_FIELD_RAW_FIELD_SELECT12, -+ FILTER_FIELD_RAW_FIELD_SELECT13, -+ FILTER_FIELD_RAW_FIELD_SELECT14, -+ FILTER_FIELD_RAW_FIELD_SELECT15, -+ -+ FILTER_FIELD_RAW_END, -+} rtk_filter_field_type_raw_t; -+ -+typedef enum rtk_filter_flag_care_type_e -+{ -+ FILTER_FLAG_CARE_DONT_CARE = 0, -+ FILTER_FLAG_CARE_1, -+ FILTER_FLAG_CARE_0, -+ FILTER_FLAG_END -+} rtk_filter_flag_care_type_t; -+ -+typedef rtk_uint32 rtk_filter_id_t; /* filter id type */ -+ -+typedef enum rtk_filter_invert_e -+{ -+ FILTER_INVERT_DISABLE = 0, -+ FILTER_INVERT_ENABLE, -+ FILTER_INVERT_END, -+} rtk_filter_invert_t; -+ -+typedef rtk_uint32 rtk_filter_state_t; -+ -+typedef rtk_uint32 rtk_filter_unmatch_action_t; -+ -+typedef enum rtk_filter_unmatch_action_e -+{ -+ FILTER_UNMATCH_DROP = 0, -+ FILTER_UNMATCH_PERMIT, -+ FILTER_UNMATCH_END, -+} rtk_filter_unmatch_action_type_t; -+ -+typedef struct -+{ -+ rtk_filter_field_t *fieldHead; -+ rtk_filter_care_tag_t careTag; -+ rtk_filter_activeport_t activeport; -+ -+ rtk_filter_invert_t invert; -+} rtk_filter_cfg_t; -+ -+typedef struct -+{ -+ rtk_filter_field_raw_t dataFieldRaw[RTK_FILTER_RAW_FIELD_NUMBER]; -+ rtk_filter_field_raw_t careFieldRaw[RTK_FILTER_RAW_FIELD_NUMBER]; -+ rtk_filter_field_type_raw_t fieldRawType[RTK_FILTER_RAW_FIELD_NUMBER]; -+ rtk_filter_care_tag_t careTag; -+ rtk_filter_activeport_t activeport; -+ -+ rtk_filter_invert_t invert; -+ rtk_enable_t valid; -+} rtk_filter_cfg_raw_t; -+ -+typedef struct -+{ -+ rtk_uint32 index; -+ rtk_filter_field_type_raw_t fieldType[RTK_FILTER_RAW_FIELD_NUMBER]; -+} rtk_filter_template_t; -+ -+typedef enum rtk_field_sel_e -+{ -+ FORMAT_DEFAULT = 0, -+ FORMAT_RAW, -+ FORMAT_LLC, -+ FORMAT_IPV4, -+ FORMAT_ARP, -+ FORMAT_IPV6, -+ FORMAT_IPPAYLOAD, -+ FORMAT_L4PAYLOAD, -+ FORMAT_END -+}rtk_field_sel_t; -+ -+typedef enum rtk_filter_iprange_e -+{ -+ IPRANGE_UNUSED = 0, -+ IPRANGE_IPV4_SIP, -+ IPRANGE_IPV4_DIP, -+ IPRANGE_IPV6_SIP, -+ IPRANGE_IPV6_DIP, -+ IPRANGE_END -+}rtk_filter_iprange_t; -+ -+typedef enum rtk_filter_vidrange_e -+{ -+ VIDRANGE_UNUSED = 0, -+ VIDRANGE_CVID, -+ VIDRANGE_SVID, -+ VIDRANGE_END -+}rtk_filter_vidrange_t; -+ -+typedef enum rtk_filter_portrange_e -+{ -+ PORTRANGE_UNUSED = 0, -+ PORTRANGE_SPORT, -+ PORTRANGE_DPORT, -+ PORTRANGE_END -+}rtk_filter_portrange_t; -+ -+/* Function Name: -+ * rtk_filter_igrAcl_init -+ * Description: -+ * ACL initialization function -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL. -+ * Note: -+ * This function enable and initialize ACL function -+ */ -+extern rtk_api_ret_t rtk_filter_igrAcl_init(void); -+ -+/* Function Name: -+ * rtk_filter_igrAcl_field_add -+ * Description: -+ * Add comparison rule to an ACL configuration -+ * Input: -+ * pFilter_cfg - The ACL configuration that this function will add comparison rule -+ * pFilter_field - The comparison rule that will be added. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This function add a comparison rule (*pFilter_field) to an ACL configuration (*pFilter_cfg). -+ * Pointer pFilter_cfg points to an ACL configuration structure, this structure keeps multiple ACL -+ * comparison rules by means of linked list. Pointer pFilter_field will be added to linked -+ * list kept by structure that pFilter_cfg points to. -+ */ -+extern rtk_api_ret_t rtk_filter_igrAcl_field_add(rtk_filter_cfg_t *pFilter_cfg, rtk_filter_field_t *pFilter_field); -+ -+/* Function Name: -+ * rtk_filter_igrAcl_cfg_add -+ * Description: -+ * Add an ACL configuration to ASIC -+ * Input: -+ * filter_id - Start index of ACL configuration. -+ * pFilter_cfg - The ACL configuration that this function will add comparison rule -+ * pFilter_action - Action(s) of ACL configuration. -+ * Output: -+ * ruleNum - number of rules written in ACL table -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_ENTRY_INDEX - Invalid filter_id . -+ * RT_ERR_NULL_POINTER - Pointer pFilter_action or pFilter_cfg point to NULL. -+ * RT_ERR_FILTER_INACL_ACT_NOT_SUPPORT - Action is not supported in this chip. -+ * RT_ERR_FILTER_INACL_RULE_NOT_SUPPORT - Rule is not supported. -+ * Note: -+ * This function store pFilter_cfg, pFilter_action into ASIC. The starting -+ * index(es) is filter_id. -+ */ -+extern rtk_api_ret_t rtk_filter_igrAcl_cfg_add(rtk_filter_id_t filter_id, rtk_filter_cfg_t *pFilter_cfg, rtk_filter_action_t *pAction, rtk_filter_number_t *ruleNum); -+ -+/* Function Name: -+ * rtk_filter_igrAcl_cfg_del -+ * Description: -+ * Delete an ACL configuration from ASIC -+ * Input: -+ * filter_id - Start index of ACL configuration. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_FILTER_ENTRYIDX - Invalid filter_id. -+ * Note: -+ * This function delete a group of ACL rules starting from filter_id. -+ */ -+extern rtk_api_ret_t rtk_filter_igrAcl_cfg_del(rtk_filter_id_t filter_id); -+ -+/* Function Name: -+ * rtk_filter_igrAcl_cfg_delAll -+ * Description: -+ * Delete all ACL entries from ASIC -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * This function delete all ACL configuration from ASIC. -+ */ -+extern rtk_api_ret_t rtk_filter_igrAcl_cfg_delAll(void); -+ -+/* Function Name: -+ * rtk_filter_igrAcl_cfg_get -+ * Description: -+ * Get one ingress ACL configuration from ASIC. -+ * Input: -+ * filter_id - Start index of ACL configuration. -+ * Output: -+ * pFilter_cfg - buffer pointer of ingress ACL data -+ * pFilter_action - buffer pointer of ingress ACL action -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Pointer pFilter_action or pFilter_cfg point to NULL. -+ * RT_ERR_FILTER_ENTRYIDX - Invalid entry index. -+ * Note: -+ * This function delete all ACL configuration from ASIC. -+ */ -+extern rtk_api_ret_t rtk_filter_igrAcl_cfg_get(rtk_filter_id_t filter_id, rtk_filter_cfg_raw_t *pFilter_cfg, rtk_filter_action_t *pAction); -+ -+/* Function Name: -+ * rtk_filter_igrAcl_unmatchAction_set -+ * Description: -+ * Set action to packets when no ACL configuration match -+ * Input: -+ * port - Port id. -+ * action - Action. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port id. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This function sets action of packets when no ACL configuration matches. -+ */ -+extern rtk_api_ret_t rtk_filter_igrAcl_unmatchAction_set(rtk_port_t port, rtk_filter_unmatch_action_t action); -+ -+/* Function Name: -+ * rtk_filter_igrAcl_unmatchAction_get -+ * Description: -+ * Get action to packets when no ACL configuration match -+ * Input: -+ * port - Port id. -+ * Output: -+ * pAction - Action. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port id. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This function gets action of packets when no ACL configuration matches. -+ */ -+extern rtk_api_ret_t rtk_filter_igrAcl_unmatchAction_get(rtk_port_t port, rtk_filter_unmatch_action_t* action); -+ -+/* Function Name: -+ * rtk_filter_igrAcl_state_set -+ * Description: -+ * Set state of ingress ACL. -+ * Input: -+ * port - Port id. -+ * state - Ingress ACL state. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port id. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This function gets action of packets when no ACL configuration matches. -+ */ -+extern rtk_api_ret_t rtk_filter_igrAcl_state_set(rtk_port_t port, rtk_filter_state_t state); -+ -+/* Function Name: -+ * rtk_filter_igrAcl_state_get -+ * Description: -+ * Get state of ingress ACL. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pState - Ingress ACL state. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port id. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This function gets action of packets when no ACL configuration matches. -+ */ -+extern rtk_api_ret_t rtk_filter_igrAcl_state_get(rtk_port_t port, rtk_filter_state_t* state); -+ -+/* Function Name: -+ * rtk_filter_igrAcl_template_set -+ * Description: -+ * Set template of ingress ACL. -+ * Input: -+ * template - Ingress ACL template -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This function set ACL template. -+ */ -+extern rtk_api_ret_t rtk_filter_igrAcl_template_set(rtk_filter_template_t *aclTemplate); -+ -+/* Function Name: -+ * rtk_filter_igrAcl_template_get -+ * Description: -+ * Get template of ingress ACL. -+ * Input: -+ * template - Ingress ACL template -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * This function gets template of ACL. -+ */ -+extern rtk_api_ret_t rtk_filter_igrAcl_template_get(rtk_filter_template_t *aclTemplate); -+ -+/* Function Name: -+ * rtk_filter_igrAcl_field_sel_set -+ * Description: -+ * Set user defined field selectors in HSB -+ * Input: -+ * index - index of field selector 0-15 -+ * format - Format of field selector -+ * offset - Retrieving data offset -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * System support 16 user defined field selectors. -+ * Each selector can be enabled or disable. -+ * User can defined retrieving 16-bits in many predefiend -+ * standard l2/l3/l4 payload. -+ */ -+extern rtk_api_ret_t rtk_filter_igrAcl_field_sel_set(rtk_uint32 index, rtk_field_sel_t format, rtk_uint32 offset); -+ -+/* Function Name: -+ * rtk_filter_igrAcl_field_sel_get -+ * Description: -+ * Get user defined field selectors in HSB -+ * Input: -+ * index - index of field selector 0-15 -+ * Output: -+ * pFormat - Format of field selector -+ * pOffset - Retrieving data offset -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None. -+ */ -+extern rtk_api_ret_t rtk_filter_igrAcl_field_sel_get(rtk_uint32 index, rtk_field_sel_t *pFormat, rtk_uint32 *pOffset); -+ -+/* Function Name: -+ * rtk_filter_iprange_set -+ * Description: -+ * Set IP Range check -+ * Input: -+ * index - index of IP Range 0-15 -+ * type - IP Range check type, 0:Delete a entry, 1: IPv4_SIP, 2: IPv4_DIP, 3:IPv6_SIP, 4:IPv6_DIP -+ * upperIp - The upper bound of IP range -+ * lowerIp - The lower Bound of IP range -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - The parameter is out of range -+ * RT_ERR_INPUT - Input error -+ * Note: -+ * upperIp must be larger or equal than lowerIp. -+ */ -+extern rtk_api_ret_t rtk_filter_iprange_set(rtk_uint32 index, rtk_filter_iprange_t type, ipaddr_t upperIp, ipaddr_t lowerIp); -+ -+/* Function Name: -+ * rtk_filter_iprange_get -+ * Description: -+ * Set IP Range check -+ * Input: -+ * index - index of IP Range 0-15 -+ * Output: -+ * pType - IP Range check type, 0:Delete a entry, 1: IPv4_SIP, 2: IPv4_DIP, 3:IPv6_SIP, 4:IPv6_DIP -+ * pUpperIp - The upper bound of IP range -+ * pLowerIp - The lower Bound of IP range -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - The parameter is out of range -+ * Note: -+ * upperIp must be larger or equal than lowerIp. -+ */ -+extern rtk_api_ret_t rtk_filter_iprange_get(rtk_uint32 index, rtk_filter_iprange_t *pType, ipaddr_t *pUpperIp, ipaddr_t *pLowerIp); -+ -+/* Function Name: -+ * rtk_filter_vidrange_set -+ * Description: -+ * Set VID Range check -+ * Input: -+ * index - index of VID Range 0-15 -+ * type - IP Range check type, 0:Delete a entry, 1: CVID, 2: SVID -+ * upperVid - The upper bound of VID range -+ * lowerVid - The lower Bound of VID range -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - The parameter is out of range -+ * RT_ERR_INPUT - Input error -+ * Note: -+ * upperVid must be larger or equal than lowerVid. -+ */ -+extern rtk_api_ret_t rtk_filter_vidrange_set(rtk_uint32 index, rtk_filter_vidrange_t type, rtk_uint32 upperVid, rtk_uint32 lowerVid); -+ -+/* Function Name: -+ * rtk_filter_vidrange_get -+ * Description: -+ * Get VID Range check -+ * Input: -+ * index - index of VID Range 0-15 -+ * Output: -+ * pType - IP Range check type, 0:Unused, 1: CVID, 2: SVID -+ * pUpperVid - The upper bound of VID range -+ * pLowerVid - The lower Bound of VID range -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - The parameter is out of range -+ * Note: -+ * None. -+ */ -+extern rtk_api_ret_t rtk_filter_vidrange_get(rtk_uint32 index, rtk_filter_vidrange_t *pType, rtk_uint32 *pUpperVid, rtk_uint32 *pLowerVid); -+ -+/* Function Name: -+ * rtk_filter_portrange_set -+ * Description: -+ * Set Port Range check -+ * Input: -+ * index - index of Port Range 0-15 -+ * type - IP Range check type, 0:Delete a entry, 1: Source Port, 2: Destination Port -+ * upperPort - The upper bound of Port range -+ * lowerPort - The lower Bound of Port range -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - The parameter is out of range -+ * RT_ERR_INPUT - Input error -+ * Note: -+ * upperPort must be larger or equal than lowerPort. -+ */ -+extern rtk_api_ret_t rtk_filter_portrange_set(rtk_uint32 index, rtk_filter_portrange_t type, rtk_uint32 upperPort, rtk_uint32 lowerPort); -+ -+/* Function Name: -+ * rtk_filter_portrange_get -+ * Description: -+ * Set Port Range check -+ * Input: -+ * index - index of Port Range 0-15 -+ * Output: -+ * pType - IP Range check type, 0:Delete a entry, 1: Source Port, 2: Destination Port -+ * pUpperPort - The upper bound of Port range -+ * pLowerPort - The lower Bound of Port range -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - The parameter is out of range -+ * RT_ERR_INPUT - Input error -+ * Note: -+ * None. -+ */ -+extern rtk_api_ret_t rtk_filter_portrange_get(rtk_uint32 index, rtk_filter_portrange_t *pType, rtk_uint32 *pUpperPort, rtk_uint32 *pLowerPort); -+ -+/* Function Name: -+ * rtk_filter_igrAclPolarity_set -+ * Description: -+ * Set ACL Goip control polarity -+ * Input: -+ * polarity - 1: High, 0: Low -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * none -+ */ -+extern rtk_api_ret_t rtk_filter_igrAclPolarity_set(rtk_uint32 polarity); -+ -+/* Function Name: -+ * rtk_filter_igrAclPolarity_get -+ * Description: -+ * Get ACL Goip control polarity -+ * Input: -+ * pPolarity - 1: High, 0: Low -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * none -+ */ -+extern rtk_api_ret_t rtk_filter_igrAclPolarity_get(rtk_uint32* pPolarity); -+ -+ -+#endif /* __RTK_API_ACL_H__ */ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/cpu.h b/drivers/net/phy/rtk/rtl8367c/include/cpu.h -new file mode 100644 -index 000000000000..67aa1e3d88ea ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/cpu.h -@@ -0,0 +1,327 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * Purpose : RTL8367/RTL8367C switch high-level API -+ * -+ * Feature : The file includes CPU module high-layer API definition -+ * -+ */ -+ -+#ifndef __RTK_API_CPU_H__ -+#define __RTK_API_CPU_H__ -+ -+ -+/* -+ * Data Type Declaration -+ */ -+typedef enum rtk_cpu_insert_e -+{ -+ CPU_INSERT_TO_ALL = 0, -+ CPU_INSERT_TO_TRAPPING, -+ CPU_INSERT_TO_NONE, -+ CPU_INSERT_END -+}rtk_cpu_insert_t; -+ -+typedef enum rtk_cpu_position_e -+{ -+ CPU_POS_AFTER_SA = 0, -+ CPU_POS_BEFORE_CRC, -+ CPU_POS_END -+}rtk_cpu_position_t; -+ -+typedef enum rtk_cpu_tag_length_e -+{ -+ CPU_LEN_8BYTES = 0, -+ CPU_LEN_4BYTES, -+ CPU_LEN_END -+}rtk_cpu_tag_length_t; -+ -+ -+typedef enum rtk_cpu_rx_length_e -+{ -+ CPU_RX_72BYTES = 0, -+ CPU_RX_64BYTES, -+ CPU_RX_END -+}rtk_cpu_rx_length_t; -+ -+ -+/* Function Name: -+ * rtk_cpu_enable_set -+ * Description: -+ * Set CPU port function enable/disable. -+ * Input: -+ * enable - CPU port function enable -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can set CPU port function enable/disable. -+ */ -+extern rtk_api_ret_t rtk_cpu_enable_set(rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_cpu_enable_get -+ * Description: -+ * Get CPU port and its setting. -+ * Input: -+ * None -+ * Output: -+ * pEnable - CPU port function enable -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_L2_NO_CPU_PORT - CPU port is not exist -+ * Note: -+ * The API can get CPU port function enable/disable. -+ */ -+extern rtk_api_ret_t rtk_cpu_enable_get(rtk_enable_t *pEnable); -+ -+/* Function Name: -+ * rtk_cpu_tagPort_set -+ * Description: -+ * Set CPU port and CPU tag insert mode. -+ * Input: -+ * port - Port id. -+ * mode - CPU tag insert for packets egress from CPU port. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can set CPU port and inserting proprietary CPU tag mode (Length/Type 0x8899) -+ * to the frame that transmitting to CPU port. -+ * The insert CPU tag mode is as following: -+ * - CPU_INSERT_TO_ALL -+ * - CPU_INSERT_TO_TRAPPING -+ * - CPU_INSERT_TO_NONE -+ */ -+extern rtk_api_ret_t rtk_cpu_tagPort_set(rtk_port_t port, rtk_cpu_insert_t mode); -+ -+/* Function Name: -+ * rtk_cpu_tagPort_get -+ * Description: -+ * Get CPU port and CPU tag insert mode. -+ * Input: -+ * None -+ * Output: -+ * pPort - Port id. -+ * pMode - CPU tag insert for packets egress from CPU port, 0:all insert 1:Only for trapped packets 2:no insert. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_L2_NO_CPU_PORT - CPU port is not exist -+ * Note: -+ * The API can get configured CPU port and its setting. -+ * The insert CPU tag mode is as following: -+ * - CPU_INSERT_TO_ALL -+ * - CPU_INSERT_TO_TRAPPING -+ * - CPU_INSERT_TO_NONE -+ */ -+extern rtk_api_ret_t rtk_cpu_tagPort_get(rtk_port_t *pPort, rtk_cpu_insert_t *pMode); -+ -+/* Function Name: -+ * rtk_cpu_awarePort_set -+ * Description: -+ * Set CPU aware port mask. -+ * Input: -+ * portmask - Port mask. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Invalid port mask. -+ * Note: -+ * The API can set configured CPU aware port mask. -+ */ -+extern rtk_api_ret_t rtk_cpu_awarePort_set(rtk_portmask_t *pPortmask); -+ -+ -+/* Function Name: -+ * rtk_cpu_awarePort_get -+ * Description: -+ * Get CPU aware port mask. -+ * Input: -+ * None -+ * Output: -+ * pPortmask - Port mask. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * The API can get configured CPU aware port mask. -+ */ -+extern rtk_api_ret_t rtk_cpu_awarePort_get(rtk_portmask_t *pPortmask); -+ -+/* Function Name: -+ * rtk_cpu_tagPosition_set -+ * Description: -+ * Set CPU tag position. -+ * Input: -+ * position - CPU tag position. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input. -+ * Note: -+ * The API can set CPU tag position. -+ */ -+extern rtk_api_ret_t rtk_cpu_tagPosition_set(rtk_cpu_position_t position); -+ -+/* Function Name: -+ * rtk_cpu_tagPosition_get -+ * Description: -+ * Get CPU tag position. -+ * Input: -+ * None -+ * Output: -+ * pPosition - CPU tag position. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input. -+ * Note: -+ * The API can get CPU tag position. -+ */ -+extern rtk_api_ret_t rtk_cpu_tagPosition_get(rtk_cpu_position_t *pPosition); -+ -+/* Function Name: -+ * rtk_cpu_tagLength_set -+ * Description: -+ * Set CPU tag length. -+ * Input: -+ * length - CPU tag length. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input. -+ * Note: -+ * The API can set CPU tag length. -+ */ -+extern rtk_api_ret_t rtk_cpu_tagLength_set(rtk_cpu_tag_length_t length); -+ -+/* Function Name: -+ * rtk_cpu_tagLength_get -+ * Description: -+ * Get CPU tag length. -+ * Input: -+ * None -+ * Output: -+ * pLength - CPU tag length. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input. -+ * Note: -+ * The API can get CPU tag length. -+ */ -+extern rtk_api_ret_t rtk_cpu_tagLength_get(rtk_cpu_tag_length_t *pLength); -+ -+/* Function Name: -+ * rtk_cpu_acceptLength_set -+ * Description: -+ * Set CPU accept length. -+ * Input: -+ * length - CPU tag length. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input. -+ * Note: -+ * The API can set CPU accept length. -+ */ -+extern rtk_api_ret_t rtk_cpu_acceptLength_set(rtk_cpu_rx_length_t length); -+ -+/* Function Name: -+ * rtk_cpu_acceptLength_get -+ * Description: -+ * Get CPU accept length. -+ * Input: -+ * None -+ * Output: -+ * pLength - CPU tag length. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input. -+ * Note: -+ * The API can get CPU accept length. -+ */ -+extern rtk_api_ret_t rtk_cpu_acceptLength_get(rtk_cpu_rx_length_t *pLength); -+ -+/* Function Name: -+ * rtk_cpu_priRemap_set -+ * Description: -+ * Configure CPU priorities mapping to internal absolute priority. -+ * Input: -+ * int_pri - internal priority value. -+ * new_pri - new internal priority value. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_VLAN_PRIORITY - Invalid 1p priority. -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority. -+ * Note: -+ * Priority of CPU tag assignment for internal asic priority, and it is used for queue usage and packet scheduling. -+ */ -+extern rtk_api_ret_t rtk_cpu_priRemap_set(rtk_pri_t int_pri, rtk_pri_t new_pri); -+ -+/* Function Name: -+ * rtk_cpu_priRemap_get -+ * Description: -+ * Configure CPU priorities mapping to internal absolute priority. -+ * Input: -+ * int_pri - internal priority value. -+ * Output: -+ * pNew_pri - new internal priority value. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_VLAN_PRIORITY - Invalid 1p priority. -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority. -+ * Note: -+ * Priority of CPU tag assignment for internal asic priority, and it is used for queue usage and packet scheduling. -+ */ -+extern rtk_api_ret_t rtk_cpu_priRemap_get(rtk_pri_t int_pri, rtk_pri_t *pNew_pri); -+ -+ -+#endif /* __RTK_API_CPU_H__ */ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/dot1x.h b/drivers/net/phy/rtk/rtl8367c/include/dot1x.h -new file mode 100644 -index 000000000000..082ee2569e2a ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/dot1x.h -@@ -0,0 +1,470 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * Purpose : RTL8367/RTL8367C switch high-level API -+ * -+ * Feature : The file includes 1X module high-layer API definition -+ * -+ */ -+ -+#ifndef __RTK_API_DOT1X_H__ -+#define __RTK_API_DOT1X_H__ -+ -+ -+/* Type of port-based dot1x auth/unauth*/ -+typedef enum rtk_dot1x_auth_status_e -+{ -+ UNAUTH = 0, -+ AUTH, -+ AUTH_STATUS_END -+} rtk_dot1x_auth_status_t; -+ -+typedef enum rtk_dot1x_direction_e -+{ -+ DIR_BOTH = 0, -+ DIR_IN, -+ DIRECTION_END -+} rtk_dot1x_direction_t; -+ -+/* unauth pkt action */ -+typedef enum rtk_dot1x_unauth_action_e -+{ -+ DOT1X_ACTION_DROP = 0, -+ DOT1X_ACTION_TRAP2CPU, -+ DOT1X_ACTION_GUESTVLAN, -+ DOT1X_ACTION_END -+} rtk_dot1x_unauth_action_t; -+ -+/* Function Name: -+ * rtk_dot1x_unauthPacketOper_set -+ * Description: -+ * Set 802.1x unauth action configuration. -+ * Input: -+ * port - Port id. -+ * unauth_action - 802.1X unauth action. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_INPUT - Invalid input parameter. -+ * Note: -+ * This API can set 802.1x unauth action configuration. -+ * The unauth action is as following: -+ * - DOT1X_ACTION_DROP -+ * - DOT1X_ACTION_TRAP2CPU -+ * - DOT1X_ACTION_GUESTVLAN -+ */ -+extern rtk_api_ret_t rtk_dot1x_unauthPacketOper_set(rtk_port_t port, rtk_dot1x_unauth_action_t unauth_action); -+ -+/* Function Name: -+ * rtk_dot1x_unauthPacketOper_get -+ * Description: -+ * Get 802.1x unauth action configuration. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pUnauth_action - 802.1X unauth action. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * This API can get 802.1x unauth action configuration. -+ * The unauth action is as following: -+ * - DOT1X_ACTION_DROP -+ * - DOT1X_ACTION_TRAP2CPU -+ * - DOT1X_ACTION_GUESTVLAN -+ */ -+extern rtk_api_ret_t rtk_dot1x_unauthPacketOper_get(rtk_port_t port, rtk_dot1x_unauth_action_t *pUnauth_action); -+ -+/* Function Name: -+ * rtk_dot1x_eapolFrame2CpuEnable_set -+ * Description: -+ * Set 802.1x EAPOL packet trap to CPU configuration -+ * Input: -+ * enable - The status of 802.1x EAPOL packet. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_ENABLE - Invalid enable input. -+ * Note: -+ * To support 802.1x authentication functionality, EAPOL frame (ether type = 0x888E) has to -+ * be trapped to CPU. -+ * The status of EAPOL frame trap to CPU is as following: -+ * - DISABLED -+ * - ENABLED -+ */ -+extern rtk_api_ret_t rtk_dot1x_eapolFrame2CpuEnable_set(rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_dot1x_eapolFrame2CpuEnable_get -+ * Description: -+ * Get 802.1x EAPOL packet trap to CPU configuration -+ * Input: -+ * None -+ * Output: -+ * pEnable - The status of 802.1x EAPOL packet. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * To support 802.1x authentication functionality, EAPOL frame (ether type = 0x888E) has to -+ * be trapped to CPU. -+ * The status of EAPOL frame trap to CPU is as following: -+ * - DISABLED -+ * - ENABLED -+ */ -+extern rtk_api_ret_t rtk_dot1x_eapolFrame2CpuEnable_get(rtk_enable_t *pEnable); -+ -+/* Function Name: -+ * rtk_dot1x_portBasedEnable_set -+ * Description: -+ * Set 802.1x port-based enable configuration -+ * Input: -+ * port - Port id. -+ * enable - The status of 802.1x port. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_ENABLE - Invalid enable input. -+ * RT_ERR_DOT1X_PORTBASEDPNEN - 802.1X port-based enable error -+ * Note: -+ * The API can update the port-based port enable register content. If a port is 802.1x -+ * port based network access control "enabled", it should be authenticated so packets -+ * from that port won't be dropped or trapped to CPU. -+ * The status of 802.1x port-based network access control is as following: -+ * - DISABLED -+ * - ENABLED -+ */ -+extern rtk_api_ret_t rtk_dot1x_portBasedEnable_set(rtk_port_t port, rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_dot1x_portBasedEnable_get -+ * Description: -+ * Get 802.1x port-based enable configuration -+ * Input: -+ * port - Port id. -+ * Output: -+ * pEnable - The status of 802.1x port. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get the 802.1x port-based port status. -+ */ -+extern rtk_api_ret_t rtk_dot1x_portBasedEnable_get(rtk_port_t port, rtk_enable_t *pEnable); -+ -+/* Function Name: -+ * rtk_dot1x_portBasedAuthStatus_set -+ * Description: -+ * Set 802.1x port-based auth. port configuration -+ * Input: -+ * port - Port id. -+ * port_auth - The status of 802.1x port. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_DOT1X_PORTBASEDAUTH - 802.1X port-based auth error -+ * Note: -+ * The authenticated status of 802.1x port-based network access control is as following: -+ * - UNAUTH -+ * - AUTH -+ */ -+extern rtk_api_ret_t rtk_dot1x_portBasedAuthStatus_set(rtk_port_t port, rtk_dot1x_auth_status_t port_auth); -+ -+/* Function Name: -+ * rtk_dot1x_portBasedAuthStatus_get -+ * Description: -+ * Get 802.1x port-based auth. port configuration -+ * Input: -+ * port - Port id. -+ * Output: -+ * pPort_auth - The status of 802.1x port. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get 802.1x port-based port auth.information. -+ */ -+extern rtk_api_ret_t rtk_dot1x_portBasedAuthStatus_get(rtk_port_t port, rtk_dot1x_auth_status_t *pPort_auth); -+ -+/* Function Name: -+ * rtk_dot1x_portBasedDirection_set -+ * Description: -+ * Set 802.1x port-based operational direction configuration -+ * Input: -+ * port - Port id. -+ * port_direction - Operation direction -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_DOT1X_PORTBASEDOPDIR - 802.1X port-based operation direction error -+ * Note: -+ * The operate controlled direction of 802.1x port-based network access control is as following: -+ * - BOTH -+ * - IN -+ */ -+extern rtk_api_ret_t rtk_dot1x_portBasedDirection_set(rtk_port_t port, rtk_dot1x_direction_t port_direction); -+ -+/* Function Name: -+ * rtk_dot1x_portBasedDirection_get -+ * Description: -+ * Get 802.1X port-based operational direction configuration -+ * Input: -+ * port - Port id. -+ * Output: -+ * pPort_direction - Operation direction -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get 802.1x port-based operational direction information. -+ */ -+extern rtk_api_ret_t rtk_dot1x_portBasedDirection_get(rtk_port_t port, rtk_dot1x_direction_t *pPort_direction); -+ -+/* Function Name: -+ * rtk_dot1x_macBasedEnable_set -+ * Description: -+ * Set 802.1x mac-based port enable configuration -+ * Input: -+ * port - Port id. -+ * enable - The status of 802.1x port. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_ENABLE - Invalid enable input. -+ * RT_ERR_DOT1X_MACBASEDPNEN - 802.1X mac-based enable error -+ * Note: -+ * If a port is 802.1x MAC based network access control "enabled", the incoming packets should -+ * be authenticated so packets from that port won't be dropped or trapped to CPU. -+ * The status of 802.1x MAC-based network access control is as following: -+ * - DISABLED -+ * - ENABLED -+ */ -+extern rtk_api_ret_t rtk_dot1x_macBasedEnable_set(rtk_port_t port, rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_dot1x_macBasedEnable_get -+ * Description: -+ * Get 802.1x mac-based port enable configuration -+ * Input: -+ * port - Port id. -+ * Output: -+ * pEnable - The status of 802.1x port. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * If a port is 802.1x MAC based network access control "enabled", the incoming packets should -+ * be authenticated so packets from that port wont be dropped or trapped to CPU. -+ * The status of 802.1x MAC-based network access control is as following: -+ * - DISABLED -+ * - ENABLED -+ */ -+extern rtk_api_ret_t rtk_dot1x_macBasedEnable_get(rtk_port_t port, rtk_enable_t *pEnable); -+ -+/* Function Name: -+ * rtk_dot1x_macBasedAuthMac_add -+ * Description: -+ * Add an authenticated MAC to ASIC -+ * Input: -+ * port - Port id. -+ * pAuth_mac - The authenticated MAC. -+ * fid - filtering database. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_ENABLE - Invalid enable input. -+ * RT_ERR_DOT1X_MACBASEDPNEN - 802.1X mac-based enable error -+ * Note: -+ * The API can add a 802.1x authenticated MAC address to port. If the MAC does not exist in LUT, -+ * user can't add this MAC to auth status. -+ */ -+extern rtk_api_ret_t rtk_dot1x_macBasedAuthMac_add(rtk_port_t port, rtk_mac_t *pAuth_mac, rtk_fid_t fid); -+ -+/* Function Name: -+ * rtk_dot1x_macBasedAuthMac_del -+ * Description: -+ * Delete an authenticated MAC to ASIC -+ * Input: -+ * port - Port id. -+ * pAuth_mac - The authenticated MAC. -+ * fid - filtering database. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_MAC - Invalid MAC address. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can delete a 802.1x authenticated MAC address to port. It only change the auth status of -+ * the MAC and won't delete it from LUT. -+ */ -+extern rtk_api_ret_t rtk_dot1x_macBasedAuthMac_del(rtk_port_t port, rtk_mac_t *pAuth_mac, rtk_fid_t fid); -+ -+/* Function Name: -+ * rtk_dot1x_macBasedDirection_set -+ * Description: -+ * Set 802.1x mac-based operational direction configuration -+ * Input: -+ * mac_direction - Operation direction -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter. -+ * RT_ERR_DOT1X_MACBASEDOPDIR - 802.1X mac-based operation direction error -+ * Note: -+ * The operate controlled direction of 802.1x mac-based network access control is as following: -+ * - BOTH -+ * - IN -+ */ -+extern rtk_api_ret_t rtk_dot1x_macBasedDirection_set(rtk_dot1x_direction_t mac_direction); -+ -+/* Function Name: -+ * rtk_dot1x_macBasedDirection_get -+ * Description: -+ * Get 802.1x mac-based operational direction configuration -+ * Input: -+ * port - Port id. -+ * Output: -+ * pMac_direction - Operation direction -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can get 802.1x mac-based operational direction information. -+ */ -+extern rtk_api_ret_t rtk_dot1x_macBasedDirection_get(rtk_dot1x_direction_t *pMac_direction); -+ -+/* Function Name: -+ * Set 802.1x guest VLAN configuration -+ * Description: -+ * Set 802.1x mac-based operational direction configuration -+ * Input: -+ * vid - 802.1x guest VLAN ID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter. -+ * Note: -+ * The operate controlled 802.1x guest VLAN -+ */ -+extern rtk_api_ret_t rtk_dot1x_guestVlan_set(rtk_vlan_t vid); -+ -+/* Function Name: -+ * rtk_dot1x_guestVlan_get -+ * Description: -+ * Get 802.1x guest VLAN configuration -+ * Input: -+ * None -+ * Output: -+ * pVid - 802.1x guest VLAN ID -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can get 802.1x guest VLAN information. -+ */ -+extern rtk_api_ret_t rtk_dot1x_guestVlan_get(rtk_vlan_t *pVid); -+ -+/* Function Name: -+ * rtk_dot1x_guestVlan2Auth_set -+ * Description: -+ * Set 802.1x guest VLAN to auth host configuration -+ * Input: -+ * enable - The status of guest VLAN to auth host. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter. -+ * Note: -+ * The operational direction of 802.1x guest VLAN to auth host control is as following: -+ * - ENABLED -+ * - DISABLED -+ */ -+extern rtk_api_ret_t rtk_dot1x_guestVlan2Auth_set(rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_dot1x_guestVlan2Auth_get -+ * Description: -+ * Get 802.1x guest VLAN to auth host configuration -+ * Input: -+ * None -+ * Output: -+ * pEnable - The status of guest VLAN to auth host. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can get 802.1x guest VLAN to auth host information. -+ */ -+extern rtk_api_ret_t rtk_dot1x_guestVlan2Auth_get(rtk_enable_t *pEnable); -+ -+ -+#endif /* __RTK_API_DOT1X_H__ */ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/eee.h b/drivers/net/phy/rtk/rtl8367c/include/eee.h -new file mode 100644 -index 000000000000..e3920363d15c ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/eee.h -@@ -0,0 +1,82 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * Purpose : RTL8367/RTL8367C switch high-level API -+ * -+ * Feature : The file includes EEE module high-layer API definition -+ * -+ */ -+ -+#ifndef __RTK_API_EEE_H__ -+#define __RTK_API_EEE_H__ -+ -+/* Function Name: -+ * rtk_eee_init -+ * Description: -+ * EEE function initialization. -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * This API is used to initialize EEE status. -+ */ -+extern rtk_api_ret_t rtk_eee_init(void); -+ -+/* Function Name: -+ * rtk_eee_portEnable_set -+ * Description: -+ * Set enable status of EEE function. -+ * Input: -+ * port - port id. -+ * enable - enable EEE status. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_ENABLE - Invalid enable input. -+ * Note: -+ * This API can set EEE function to the specific port. -+ * The configuration of the port is as following: -+ * - DISABLE -+ * - ENABLE -+ */ -+extern rtk_api_ret_t rtk_eee_portEnable_set(rtk_port_t port, rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_eee_portEnable_get -+ * Description: -+ * Get port admin configuration of the specific port. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pEnable - Back pressure status. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * This API can set EEE function to the specific port. -+ * The configuration of the port is as following: -+ * - DISABLE -+ * - ENABLE -+ */ -+extern rtk_api_ret_t rtk_eee_portEnable_get(rtk_port_t port, rtk_enable_t *pEnable); -+ -+ -+#endif /* __RTK_API_EEE_H__ */ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/i2c.h b/drivers/net/phy/rtk/rtl8367c/include/i2c.h -new file mode 100644 -index 000000000000..110f41e818ee ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/i2c.h -@@ -0,0 +1,168 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * Purpose : RTL8367/RTL8367C switch high-level API -+ * -+ * Feature : The file includes I2C module high-layer API definition -+ * -+ */ -+ -+ -+#ifndef __RTK_API_I2C_H__ -+#define __RTK_API_I2C_H__ -+#include -+ -+#define I2C_GPIO_MAX_GROUP (3) -+ -+typedef enum rtk_I2C_16bit_mode_e{ -+ I2C_LSB_16BIT_MODE = 0, -+ I2C_70B_LSB_16BIT_MODE, -+ I2C_Mode_END -+}rtk_I2C_16bit_mode_t; -+ -+ -+typedef enum rtk_I2C_gpio_pin_e{ -+ I2C_GPIO_PIN_8_9 = 0, -+ I2C_GPIO_PIN_15_16 , -+ I2C_GPIO_PIN_35_36 , -+ I2C_GPIO_PIN_END -+}rtk_I2C_gpio_pin_t; -+ -+ -+/* Function Name: -+ * rtk_i2c_data_read -+ * Description: -+ * read i2c slave device register. -+ * Input: -+ * deviceAddr - access Slave device address -+ * slaveRegAddr - access Slave register address -+ * Output: -+ * pRegData - read data -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_NULL_POINTER - input parameter is null pointer -+ * Note: -+ * The API can access i2c slave and read i2c slave device register. -+ */ -+extern rtk_api_ret_t rtk_i2c_data_read(rtk_uint8 deviceAddr, rtk_uint32 slaveRegAddr, rtk_uint32 *pRegData); -+ -+/* Function Name: -+ * rtk_i2c_data_write -+ * Description: -+ * write data to i2c slave device register -+ * Input: -+ * deviceAddr - access Slave device address -+ * slaveRegAddr - access Slave register address -+ * regData - data to set -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * Note: -+ * The API can access i2c slave and setting i2c slave device register. -+ */ -+extern rtk_api_ret_t rtk_i2c_data_write(rtk_uint8 deviceAddr, rtk_uint32 slaveRegAddr, rtk_uint32 regData); -+ -+ -+/* Function Name: -+ * rtk_i2c_init -+ * Description: -+ * I2C smart function initialization. -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * Note: -+ * This API is used to initialize EEE status. -+ * need used GPIO pins -+ * OpenDrain and clock -+ */ -+extern rtk_api_ret_t rtk_i2c_init(void); -+ -+/* Function Name: -+ * rtk_i2c_mode_set -+ * Description: -+ * Set I2C data byte-order. -+ * Input: -+ * i2cmode - byte-order mode -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_INPUT - Invalid input parameter. -+ * Note: -+ * This API can set I2c traffic's byte-order . -+ */ -+extern rtk_api_ret_t rtk_i2c_mode_set( rtk_I2C_16bit_mode_t i2cmode); -+ -+/* Function Name: -+ * rtk_i2c_mode_get -+ * Description: -+ * Get i2c traffic byte-order setting. -+ * Input: -+ * None -+ * Output: -+ * pI2cMode - i2c byte-order -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_NULL_POINTER - input parameter is null pointer -+ * Note: -+ * The API can get i2c traffic byte-order setting. -+ */ -+extern rtk_api_ret_t rtk_i2c_mode_get( rtk_I2C_16bit_mode_t * pI2cMode); -+ -+ -+/* Function Name: -+ * rtk_i2c_gpioPinGroup_set -+ * Description: -+ * Set i2c SDA & SCL used GPIO pins group. -+ * Input: -+ * pins_group - GPIO pins group -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_INPUT - Invalid input parameter. -+ * Note: -+ * The API can set i2c used gpio pins group. -+ * There are three group pins could be used -+ */ -+extern rtk_api_ret_t rtk_i2c_gpioPinGroup_set( rtk_I2C_gpio_pin_t pins_group); -+ -+/* Function Name: -+ * rtk_i2c_gpioPinGroup_get -+ * Description: -+ * Get i2c SDA & SCL used GPIO pins group. -+ * Input: -+ * None -+ * Output: -+ * pPins_group - GPIO pins group -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_NULL_POINTER - input parameter is null pointer -+ * Note: -+ * The API can get i2c used gpio pins group. -+ * There are three group pins could be used -+ */ -+extern rtk_api_ret_t rtk_i2c_gpioPinGroup_get(rtk_I2C_gpio_pin_t * pPins_group); -+ -+ -+ -+ -+ -+ -+ -+#endif -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/igmp.h b/drivers/net/phy/rtk/rtl8367c/include/igmp.h -new file mode 100644 -index 000000000000..b36db43d830c ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/igmp.h -@@ -0,0 +1,769 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * Purpose : RTL8367/RTL8367C switch high-level API -+ * -+ * Feature : The file includes IGMP module high-layer API definition -+ * -+ */ -+ -+#ifndef __RTK_API_IGMP_H__ -+#define __RTK_API_IGMP_H__ -+ -+/* -+ * Data Type Declaration -+ */ -+typedef enum rtk_igmp_type_e -+{ -+ IGMP_IPV4 = 0, -+ IGMP_PPPOE_IPV4, -+ IGMP_MLD, -+ IGMP_PPPOE_MLD, -+ IGMP_TYPE_END -+} rtk_igmp_type_t; -+ -+typedef enum rtk_trap_igmp_action_e -+{ -+ IGMP_ACTION_FORWARD = 0, -+ IGMP_ACTION_TRAP2CPU, -+ IGMP_ACTION_DROP, -+ IGMP_ACTION_ASIC, -+ IGMP_ACTION_END -+} rtk_igmp_action_t; -+ -+typedef enum rtk_igmp_protocol_e -+{ -+ PROTOCOL_IGMPv1 = 0, -+ PROTOCOL_IGMPv2, -+ PROTOCOL_IGMPv3, -+ PROTOCOL_MLDv1, -+ PROTOCOL_MLDv2, -+ PROTOCOL_END -+} rtk_igmp_protocol_t; -+ -+typedef enum rtk_igmp_tableFullAction_e -+{ -+ IGMP_TABLE_FULL_FORWARD = 0, -+ IGMP_TABLE_FULL_DROP, -+ IGMP_TABLE_FULL_TRAP, -+ IGMP_TABLE_FULL_OP_END -+}rtk_igmp_tableFullAction_t; -+ -+typedef enum rtk_igmp_checksumErrorAction_e -+{ -+ IGMP_CRC_ERR_DROP = 0, -+ IGMP_CRC_ERR_TRAP, -+ IGMP_CRC_ERR_FORWARD, -+ IGMP_CRC_ERR_OP_END -+}rtk_igmp_checksumErrorAction_t; -+ -+typedef enum rtk_igmp_bypassGroup_e -+{ -+ IGMP_BYPASS_224_0_0_X = 0, -+ IGMP_BYPASS_224_0_1_X, -+ IGMP_BYPASS_239_255_255_X, -+ IGMP_BYPASS_IPV6_00XX, -+ IGMP_BYPASS_GROUP_END -+}rtk_igmp_bypassGroup_t; -+ -+ -+typedef struct rtk_igmp_dynamicRouterPort_s -+{ -+ rtk_enable_t dynamicRouterPort0Valid; -+ rtk_port_t dynamicRouterPort0; -+ rtk_uint32 dynamicRouterPort0Timer; -+ rtk_enable_t dynamicRouterPort1Valid; -+ rtk_port_t dynamicRouterPort1; -+ rtk_uint32 dynamicRouterPort1Timer; -+ -+}rtk_igmp_dynamicRouterPort_t; -+ -+typedef struct rtk_igmp_rxPktEnable_s -+{ -+ rtk_enable_t rxQuery; -+ rtk_enable_t rxReport; -+ rtk_enable_t rxLeave; -+ rtk_enable_t rxMRP; -+ rtk_enable_t rxMcast; -+}rtk_igmp_rxPktEnable_t; -+ -+typedef struct rtk_igmp_groupInfo_s -+{ -+ rtk_enable_t valid; -+ rtk_portmask_t member; -+ rtk_uint32 timer[RTK_PORT_MAX]; -+ rtk_uint32 reportSuppFlag; -+}rtk_igmp_groupInfo_t; -+ -+typedef enum rtk_igmp_ReportLeaveFwdAct_e -+{ -+ IGMP_REPORT_LEAVE_TO_ROUTER = 0, -+ IGMP_REPORT_LEAVE_TO_ALLPORT, -+ IGMP_REPORT_LEAVE_TO_ROUTER_PORT_ADV, -+ IGMP_REPORT_LEAVE_ACT_END -+}rtk_igmp_ReportLeaveFwdAct_t; -+ -+/* Function Name: -+ * rtk_igmp_init -+ * Description: -+ * This API enables H/W IGMP and set a default initial configuration. -+ * Input: -+ * None. -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * This API enables H/W IGMP and set a default initial configuration. -+ */ -+extern rtk_api_ret_t rtk_igmp_init(void); -+ -+/* Function Name: -+ * rtk_igmp_state_set -+ * Description: -+ * This API set H/W IGMP state. -+ * Input: -+ * enabled - H/W IGMP state -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error parameter -+ * Note: -+ * This API set H/W IGMP state. -+ */ -+extern rtk_api_ret_t rtk_igmp_state_set(rtk_enable_t enabled); -+ -+/* Function Name: -+ * rtk_igmp_state_get -+ * Description: -+ * This API get H/W IGMP state. -+ * Input: -+ * None. -+ * Output: -+ * pEnabled - H/W IGMP state -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error parameter -+ * Note: -+ * This API set current H/W IGMP state. -+ */ -+extern rtk_api_ret_t rtk_igmp_state_get(rtk_enable_t *pEnabled); -+ -+/* Function Name: -+ * rtk_igmp_static_router_port_set -+ * Description: -+ * Configure static router port -+ * Input: -+ * pPortmask - Static Port mask -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Error parameter -+ * Note: -+ * This API set static router port -+ */ -+extern rtk_api_ret_t rtk_igmp_static_router_port_set(rtk_portmask_t *pPortmask); -+ -+/* Function Name: -+ * rtk_igmp_static_router_port_get -+ * Description: -+ * Get static router port -+ * Input: -+ * None. -+ * Output: -+ * pPortmask - Static port mask -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Error parameter -+ * Note: -+ * This API get static router port -+ */ -+extern rtk_api_ret_t rtk_igmp_static_router_port_get(rtk_portmask_t *pPortmask); -+ -+/* Function Name: -+ * rtk_igmp_protocol_set -+ * Description: -+ * set IGMP/MLD protocol action -+ * Input: -+ * port - Port ID -+ * protocol - IGMP/MLD protocol -+ * action - Per-port and per-protocol IGMP action setting -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Error parameter -+ * Note: -+ * This API set IGMP/MLD protocol action -+ */ -+extern rtk_api_ret_t rtk_igmp_protocol_set(rtk_port_t port, rtk_igmp_protocol_t protocol, rtk_igmp_action_t action); -+ -+/* Function Name: -+ * rtk_igmp_protocol_get -+ * Description: -+ * set IGMP/MLD protocol action -+ * Input: -+ * port - Port ID -+ * protocol - IGMP/MLD protocol -+ * action - Per-port and per-protocol IGMP action setting -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Error parameter -+ * Note: -+ * This API set IGMP/MLD protocol action -+ */ -+extern rtk_api_ret_t rtk_igmp_protocol_get(rtk_port_t port, rtk_igmp_protocol_t protocol, rtk_igmp_action_t *pAction); -+ -+/* Function Name: -+ * rtk_igmp_fastLeave_set -+ * Description: -+ * set IGMP/MLD FastLeave state -+ * Input: -+ * state - ENABLED: Enable FastLeave, DISABLED: disable FastLeave -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_INPUT - Error Input -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * This API set IGMP/MLD FastLeave state -+ */ -+extern rtk_api_ret_t rtk_igmp_fastLeave_set(rtk_enable_t state); -+ -+/* Function Name: -+ * rtk_igmp_fastLeave_get -+ * Description: -+ * get IGMP/MLD FastLeave state -+ * Input: -+ * None -+ * Output: -+ * pState - ENABLED: Enable FastLeave, DISABLED: disable FastLeave -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_NULL_POINTER - NULL pointer -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * This API get IGMP/MLD FastLeave state -+ */ -+extern rtk_api_ret_t rtk_igmp_fastLeave_get(rtk_enable_t *pState); -+ -+/* Function Name: -+ * rtk_igmp_maxGroup_set -+ * Description: -+ * Set per port multicast group learning limit. -+ * Input: -+ * port - Port ID -+ * group - The number of multicast group learning limit. -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_PORT_ID - Error Port ID -+ * RT_ERR_OUT_OF_RANGE - parameter out of range -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * This API set per port multicast group learning limit. -+ */ -+extern rtk_api_ret_t rtk_igmp_maxGroup_set(rtk_port_t port, rtk_uint32 group); -+ -+/* Function Name: -+ * rtk_igmp_maxGroup_get -+ * Description: -+ * Get per port multicast group learning limit. -+ * Input: -+ * port - Port ID -+ * Output: -+ * pGroup - The number of multicast group learning limit. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_PORT_ID - Error Port ID -+ * RT_ERR_NULL_POINTER - Null pointer -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * This API get per port multicast group learning limit. -+ */ -+extern rtk_api_ret_t rtk_igmp_maxGroup_get(rtk_port_t port, rtk_uint32 *pGroup); -+ -+/* Function Name: -+ * rtk_igmp_currentGroup_get -+ * Description: -+ * Get per port multicast group learning count. -+ * Input: -+ * port - Port ID -+ * Output: -+ * pGroup - The number of multicast group learning count. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_PORT_ID - Error Port ID -+ * RT_ERR_NULL_POINTER - Null pointer -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * This API get per port multicast group learning count. -+ */ -+extern rtk_api_ret_t rtk_igmp_currentGroup_get(rtk_port_t port, rtk_uint32 *pGroup); -+ -+/* Function Name: -+ * rtk_igmp_tableFullAction_set -+ * Description: -+ * set IGMP/MLD Table Full Action -+ * Input: -+ * action - Table Full Action -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_INPUT - Error Input -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ */ -+extern rtk_api_ret_t rtk_igmp_tableFullAction_set(rtk_igmp_tableFullAction_t action); -+ -+/* Function Name: -+ * rtk_igmp_tableFullAction_get -+ * Description: -+ * get IGMP/MLD Table Full Action -+ * Input: -+ * None -+ * Output: -+ * pAction - Table Full Action -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_NULL_POINTER - Null pointer -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ */ -+extern rtk_api_ret_t rtk_igmp_tableFullAction_get(rtk_igmp_tableFullAction_t *pAction); -+ -+/* Function Name: -+ * rtk_igmp_checksumErrorAction_set -+ * Description: -+ * set IGMP/MLD Checksum Error Action -+ * Input: -+ * action - Checksum error Action -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_INPUT - Error Input -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ */ -+extern rtk_api_ret_t rtk_igmp_checksumErrorAction_set(rtk_igmp_checksumErrorAction_t action); -+ -+/* Function Name: -+ * rtk_igmp_checksumErrorAction_get -+ * Description: -+ * get IGMP/MLD Checksum Error Action -+ * Input: -+ * None -+ * Output: -+ * pAction - Checksum error Action -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_NULL_POINTER - Null pointer -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ */ -+extern rtk_api_ret_t rtk_igmp_checksumErrorAction_get(rtk_igmp_checksumErrorAction_t *pAction); -+ -+/* Function Name: -+ * rtk_igmp_leaveTimer_set -+ * Description: -+ * set IGMP/MLD Leave timer -+ * Input: -+ * timer - Leave timer -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_INPUT - Error Input -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ */ -+extern rtk_api_ret_t rtk_igmp_leaveTimer_set(rtk_uint32 timer); -+ -+/* Function Name: -+ * rtk_igmp_leaveTimer_get -+ * Description: -+ * get IGMP/MLD Leave timer -+ * Input: -+ * None -+ * Output: -+ * pTimer - Leave Timer. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_NULL_POINTER - Null pointer -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ */ -+extern rtk_api_ret_t rtk_igmp_leaveTimer_get(rtk_uint32 *pTimer); -+ -+/* Function Name: -+ * rtk_igmp_queryInterval_set -+ * Description: -+ * set IGMP/MLD Query Interval -+ * Input: -+ * interval - Query Interval -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_INPUT - Error Input -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ */ -+extern rtk_api_ret_t rtk_igmp_queryInterval_set(rtk_uint32 interval); -+ -+/* Function Name: -+ * rtk_igmp_queryInterval_get -+ * Description: -+ * get IGMP/MLD Query Interval -+ * Input: -+ * None. -+ * Output: -+ * pInterval - Query Interval -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_NULL_POINTER - Null pointer -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ */ -+extern rtk_api_ret_t rtk_igmp_queryInterval_get(rtk_uint32 *pInterval); -+ -+/* Function Name: -+ * rtk_igmp_robustness_set -+ * Description: -+ * set IGMP/MLD Robustness value -+ * Input: -+ * robustness - Robustness value -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_INPUT - Error Input -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ */ -+extern rtk_api_ret_t rtk_igmp_robustness_set(rtk_uint32 robustness); -+ -+/* Function Name: -+ * rtk_igmp_robustness_get -+ * Description: -+ * get IGMP/MLD Robustness value -+ * Input: -+ * None -+ * Output: -+ * pRobustness - Robustness value. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_NULL_POINTER - Null pointer -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ */ -+extern rtk_api_ret_t rtk_igmp_robustness_get(rtk_uint32 *pRobustness); -+ -+/* Function Name: -+ * rtk_igmp_dynamicRouterRortAllow_set -+ * Description: -+ * Configure dynamic router port allow option -+ * Input: -+ * pPortmask - Dynamic Port allow mask -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Error parameter -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_igmp_dynamicRouterPortAllow_set(rtk_portmask_t *pPortmask); -+ -+/* Function Name: -+ * rtk_igmp_dynamicRouterRortAllow_get -+ * Description: -+ * Get dynamic router port allow option -+ * Input: -+ * None. -+ * Output: -+ * pPortmask - Dynamic Port allow mask -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Error parameter -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_igmp_dynamicRouterPortAllow_get(rtk_portmask_t *pPortmask); -+ -+/* Function Name: -+ * rtk_igmp_dynamicRouterPort_get -+ * Description: -+ * Get dynamic router port -+ * Input: -+ * None. -+ * Output: -+ * pDynamicRouterPort - Dynamic Router Port -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_NULL_POINTER - Null pointer -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Error parameter -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_igmp_dynamicRouterPort_get(rtk_igmp_dynamicRouterPort_t *pDynamicRouterPort); -+ -+/* Function Name: -+ * rtk_igmp_suppressionEnable_set -+ * Description: -+ * Configure IGMPv1/v2 & MLDv1 Report/Leave/Done suppression -+ * Input: -+ * reportSuppression - Report suppression -+ * leaveSuppression - Leave suppression -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_igmp_suppressionEnable_set(rtk_enable_t reportSuppression, rtk_enable_t leaveSuppression); -+ -+/* Function Name: -+ * rtk_igmp_suppressionEnable_get -+ * Description: -+ * Get IGMPv1/v2 & MLDv1 Report/Leave/Done suppression -+ * Input: -+ * None -+ * Output: -+ * pReportSuppression - Report suppression -+ * pLeaveSuppression - Leave suppression -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_igmp_suppressionEnable_get(rtk_enable_t *pReportSuppression, rtk_enable_t *pLeaveSuppression); -+ -+/* Function Name: -+ * rtk_igmp_portRxPktEnable_set -+ * Description: -+ * Configure IGMP/MLD RX Packet configuration -+ * Input: -+ * port - Port ID -+ * pRxCfg - RX Packet Configuration -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_igmp_portRxPktEnable_set(rtk_port_t port, rtk_igmp_rxPktEnable_t *pRxCfg); -+ -+/* Function Name: -+ * rtk_igmp_portRxPktEnable_get -+ * Description: -+ * Get IGMP/MLD RX Packet configuration -+ * Input: -+ * port - Port ID -+ * pRxCfg - RX Packet Configuration -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_igmp_portRxPktEnable_get(rtk_port_t port, rtk_igmp_rxPktEnable_t *pRxCfg); -+ -+/* Function Name: -+ * rtk_igmp_groupInfo_get -+ * Description: -+ * Get IGMP/MLD Group database -+ * Input: -+ * index - Index (0~255) -+ * Output: -+ * pGroup - Group database information. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_igmp_groupInfo_get(rtk_uint32 index, rtk_igmp_groupInfo_t *pGroup); -+ -+/* Function Name: -+ * rtk_igmp_ReportLeaveFwdAction_set -+ * Description: -+ * Set Report Leave packet forwarding action -+ * Input: -+ * action - Action -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_igmp_ReportLeaveFwdAction_set(rtk_igmp_ReportLeaveFwdAct_t action); -+ -+/* Function Name: -+ * rtk_igmp_ReportLeaveFwdAction_get -+ * Description: -+ * Get Report Leave packet forwarding action -+ * Input: -+ * action - Action -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * RT_ERR_NULL_POINTER - Null Pointer -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_igmp_ReportLeaveFwdAction_get(rtk_igmp_ReportLeaveFwdAct_t *pAction); -+ -+/* Function Name: -+ * rtk_igmp_dropLeaveZeroEnable_set -+ * Description: -+ * Set the function of dropping Leave packet with group IP = 0.0.0.0 -+ * Input: -+ * enabled - Action 1: drop, 0:pass -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_igmp_dropLeaveZeroEnable_set(rtk_enable_t enabled); -+ -+/* Function Name: -+ * rtk_igmp_dropLeaveZeroEnable_get -+ * Description: -+ * Get the function of dropping Leave packet with group IP = 0.0.0.0 -+ * Input: -+ * None -+ * Output: -+ * pEnabled. - Action 1: drop, 0:pass -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * RT_ERR_NULL_POINTER - Null Pointer -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_igmp_dropLeaveZeroEnable_get(rtk_enable_t *pEnabled); -+ -+/* Function Name: -+ * rtk_igmp_bypassGroupRange_set -+ * Description: -+ * Set Bypass group -+ * Input: -+ * group - bypassed group -+ * enabled - enabled 1: Bypassed, 0: not bypass -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_igmp_bypassGroupRange_set(rtk_igmp_bypassGroup_t group, rtk_enable_t enabled); -+ -+/* Function Name: -+ * rtk_igmp_bypassGroupRange_get -+ * Description: -+ * get Bypass group -+ * Input: -+ * group - bypassed group -+ * Output: -+ * pEnable - enabled 1: Bypassed, 0: not bypass -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * RT_ERR_NULL_POINTER - Null Pointer -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_igmp_bypassGroupRange_get(rtk_igmp_bypassGroup_t group, rtk_enable_t *pEnable); -+ -+#endif /* __RTK_API_IGMP_H__ */ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/interrupt.h b/drivers/net/phy/rtk/rtl8367c/include/interrupt.h -new file mode 100644 -index 000000000000..20625fff52c2 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/interrupt.h -@@ -0,0 +1,254 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * Purpose : RTL8367/RTL8367C switch high-level API -+ * -+ * Feature : The file includes Interrupt module high-layer API definition -+ * -+ */ -+ -+#ifndef __RTK_API_INTERRUPT_H__ -+#define __RTK_API_INTERRUPT_H__ -+ -+ -+/* -+ * Data Type Declaration -+ */ -+#define RTK_MAX_NUM_OF_INTERRUPT_TYPE 1 -+ -+ -+typedef struct rtk_int_status_s -+{ -+ rtk_uint16 value[RTK_MAX_NUM_OF_INTERRUPT_TYPE]; -+} rtk_int_status_t; -+ -+typedef struct rtk_int_info_s -+{ -+ rtk_portmask_t portMask; -+ rtk_uint32 meterMask; -+ rtk_uint32 systemLearnOver; -+}rtk_int_info_t; -+ -+typedef enum rtk_int_type_e -+{ -+ INT_TYPE_LINK_STATUS = 0, -+ INT_TYPE_METER_EXCEED, -+ INT_TYPE_LEARN_LIMIT, -+ INT_TYPE_LINK_SPEED, -+ INT_TYPE_CONGEST, -+ INT_TYPE_GREEN_FEATURE, -+ INT_TYPE_LOOP_DETECT, -+ INT_TYPE_8051, -+ INT_TYPE_CABLE_DIAG, -+ INT_TYPE_ACL, -+ INT_TYPE_RESERVED, /* Unused */ -+ INT_TYPE_SLIENT, -+ INT_TYPE_END -+}rtk_int_type_t; -+ -+typedef enum rtk_int_advType_e -+{ -+ ADV_L2_LEARN_PORT_MASK = 0, -+ ADV_SPEED_CHANGE_PORT_MASK, -+ ADV_SPECIAL_CONGESTION_PORT_MASK, -+ ADV_PORT_LINKDOWN_PORT_MASK, -+ ADV_PORT_LINKUP_PORT_MASK, -+ ADV_METER_EXCEED_MASK, -+ ADV_RLDP_LOOPED, -+ ADV_RLDP_RELEASED, -+ ADV_END, -+} rtk_int_advType_t; -+ -+typedef enum rtk_int_polarity_e -+{ -+ INT_POLAR_HIGH = 0, -+ INT_POLAR_LOW, -+ INT_POLAR_END -+} rtk_int_polarity_t; -+ -+/* Function Name: -+ * rtk_int_polarity_set -+ * Description: -+ * Set interrupt polarity configuration. -+ * Input: -+ * type - Interruptpolarity type. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can set interrupt polarity configuration. -+ */ -+extern rtk_api_ret_t rtk_int_polarity_set(rtk_int_polarity_t type); -+ -+/* Function Name: -+ * rtk_int_polarity_get -+ * Description: -+ * Get interrupt polarity configuration. -+ * Input: -+ * None -+ * Output: -+ * pType - Interruptpolarity type. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * The API can get interrupt polarity configuration. -+ */ -+extern rtk_api_ret_t rtk_int_polarity_get(rtk_int_polarity_t *pType); -+ -+/* Function Name: -+ * rtk_int_control_set -+ * Description: -+ * Set interrupt trigger status configuration. -+ * Input: -+ * type - Interrupt type. -+ * enable - Interrupt status. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_ENABLE - Invalid enable input. -+ * Note: -+ * The API can set interrupt status configuration. -+ * The interrupt trigger status is shown in the following: -+ * - INT_TYPE_LINK_STATUS -+ * - INT_TYPE_METER_EXCEED -+ * - INT_TYPE_LEARN_LIMIT -+ * - INT_TYPE_LINK_SPEED -+ * - INT_TYPE_CONGEST -+ * - INT_TYPE_GREEN_FEATURE -+ * - INT_TYPE_LOOP_DETECT -+ * - INT_TYPE_8051, -+ * - INT_TYPE_CABLE_DIAG, -+ * - INT_TYPE_ACL, -+ * - INT_TYPE_SLIENT -+ */ -+extern rtk_api_ret_t rtk_int_control_set(rtk_int_type_t type, rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_int_control_get -+ * Description: -+ * Get interrupt trigger status configuration. -+ * Input: -+ * type - Interrupt type. -+ * Output: -+ * pEnable - Interrupt status. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can get interrupt status configuration. -+ * The interrupt trigger status is shown in the following: -+ * - INT_TYPE_LINK_STATUS -+ * - INT_TYPE_METER_EXCEED -+ * - INT_TYPE_LEARN_LIMIT -+ * - INT_TYPE_LINK_SPEED -+ * - INT_TYPE_CONGEST -+ * - INT_TYPE_GREEN_FEATURE -+ * - INT_TYPE_LOOP_DETECT -+ * - INT_TYPE_8051, -+ * - INT_TYPE_CABLE_DIAG, -+ * - INT_TYPE_ACL, -+ * - INT_TYPE_SLIENT -+ */ -+extern rtk_api_ret_t rtk_int_control_get(rtk_int_type_t type, rtk_enable_t* pEnable); -+ -+/* Function Name: -+ * rtk_int_status_set -+ * Description: -+ * Set interrupt trigger status to clean. -+ * Input: -+ * None -+ * Output: -+ * pStatusMask - Interrupt status bit mask. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can clean interrupt trigger status when interrupt happened. -+ * The interrupt trigger status is shown in the following: -+ * - INT_TYPE_LINK_STATUS (value[0] (Bit0)) -+ * - INT_TYPE_METER_EXCEED (value[0] (Bit1)) -+ * - INT_TYPE_LEARN_LIMIT (value[0] (Bit2)) -+ * - INT_TYPE_LINK_SPEED (value[0] (Bit3)) -+ * - INT_TYPE_CONGEST (value[0] (Bit4)) -+ * - INT_TYPE_GREEN_FEATURE (value[0] (Bit5)) -+ * - INT_TYPE_LOOP_DETECT (value[0] (Bit6)) -+ * - INT_TYPE_8051 (value[0] (Bit7)) -+ * - INT_TYPE_CABLE_DIAG (value[0] (Bit8)) -+ * - INT_TYPE_ACL (value[0] (Bit9)) -+ * - INT_TYPE_SLIENT (value[0] (Bit11)) -+ * The status will be cleared after execute this API. -+ */ -+extern rtk_api_ret_t rtk_int_status_set(rtk_int_status_t *pStatusMask); -+ -+/* Function Name: -+ * rtk_int_status_get -+ * Description: -+ * Get interrupt trigger status. -+ * Input: -+ * None -+ * Output: -+ * pStatusMask - Interrupt status bit mask. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can get interrupt trigger status when interrupt happened. -+ * The interrupt trigger status is shown in the following: -+ * - INT_TYPE_LINK_STATUS (value[0] (Bit0)) -+ * - INT_TYPE_METER_EXCEED (value[0] (Bit1)) -+ * - INT_TYPE_LEARN_LIMIT (value[0] (Bit2)) -+ * - INT_TYPE_LINK_SPEED (value[0] (Bit3)) -+ * - INT_TYPE_CONGEST (value[0] (Bit4)) -+ * - INT_TYPE_GREEN_FEATURE (value[0] (Bit5)) -+ * - INT_TYPE_LOOP_DETECT (value[0] (Bit6)) -+ * - INT_TYPE_8051 (value[0] (Bit7)) -+ * - INT_TYPE_CABLE_DIAG (value[0] (Bit8)) -+ * - INT_TYPE_ACL (value[0] (Bit9)) -+ * - INT_TYPE_SLIENT (value[0] (Bit11)) -+ * -+ */ -+extern rtk_api_ret_t rtk_int_status_get(rtk_int_status_t* pStatusMask); -+ -+/* Function Name: -+ * rtk_int_advanceInfo_get -+ * Description: -+ * Get interrupt advanced information. -+ * Input: -+ * adv_type - Advanced interrupt type. -+ * Output: -+ * info - Information per type. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can get advanced information when interrupt happened. -+ * The status will be cleared after execute this API. -+ */ -+extern rtk_api_ret_t rtk_int_advanceInfo_get(rtk_int_advType_t adv_type, rtk_int_info_t* info); -+ -+ -+#endif /* __RTK_API_INTERRUPT_H__ */ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/l2.h b/drivers/net/phy/rtk/rtl8367c/include/l2.h -new file mode 100644 -index 000000000000..ec5aad2e30b9 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/l2.h -@@ -0,0 +1,1181 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * Purpose : RTL8367/RTL8367C switch high-level API -+ * -+ * Feature : The file includes L2 module high-layer API definition -+ * -+ */ -+ -+#ifndef __RTK_API_L2_H__ -+#define __RTK_API_L2_H__ -+ -+ -+/* -+ * Data Type Declaration -+ */ -+#define RTK_MAX_NUM_OF_LEARN_LIMIT (rtk_switch_maxLutAddrNumber_get()) -+ -+#define RTK_MAC_ADDR_LEN 6 -+#define RTK_MAX_LUT_ADDRESS (RTK_MAX_NUM_OF_LEARN_LIMIT) -+#define RTK_MAX_LUT_ADDR_ID (RTK_MAX_LUT_ADDRESS - 1) -+ -+typedef rtk_uint32 rtk_l2_age_time_t; -+ -+typedef enum rtk_l2_flood_type_e -+{ -+ FLOOD_UNKNOWNDA = 0, -+ FLOOD_UNKNOWNMC, -+ FLOOD_BC, -+ FLOOD_END -+} rtk_l2_flood_type_t; -+ -+typedef rtk_uint32 rtk_l2_flushItem_t; -+ -+typedef enum rtk_l2_flushType_e -+{ -+ FLUSH_TYPE_BY_PORT = 0, /* physical port */ -+ FLUSH_TYPE_BY_PORT_VID, /* physical port + VID */ -+ FLUSH_TYPE_BY_PORT_FID, /* physical port + FID */ -+ FLUSH_TYPE_END -+} rtk_l2_flushType_t; -+ -+typedef struct rtk_l2_flushCfg_s -+{ -+ rtk_enable_t flushByVid; -+ rtk_vlan_t vid; -+ rtk_enable_t flushByFid; -+ rtk_uint32 fid; -+ rtk_enable_t flushByPort; -+ rtk_port_t port; -+ rtk_enable_t flushByMac; -+ rtk_mac_t ucastAddr; -+ rtk_enable_t flushStaticAddr; -+ rtk_enable_t flushAddrOnAllPorts; /* this is used when flushByVid */ -+} rtk_l2_flushCfg_t; -+ -+typedef enum rtk_l2_read_method_e{ -+ -+ READMETHOD_MAC = 0, -+ READMETHOD_ADDRESS, -+ READMETHOD_NEXT_ADDRESS, -+ READMETHOD_NEXT_L2UC, -+ READMETHOD_NEXT_L2MC, -+ READMETHOD_NEXT_L3MC, -+ READMETHOD_NEXT_L2L3MC, -+ READMETHOD_NEXT_L2UCSPA, -+ READMETHOD_END -+}rtk_l2_read_method_t; -+ -+/* l2 limit learning count action */ -+typedef enum rtk_l2_limitLearnCntAction_e -+{ -+ LIMIT_LEARN_CNT_ACTION_DROP = 0, -+ LIMIT_LEARN_CNT_ACTION_FORWARD, -+ LIMIT_LEARN_CNT_ACTION_TO_CPU, -+ LIMIT_LEARN_CNT_ACTION_END -+} rtk_l2_limitLearnCntAction_t; -+ -+typedef enum rtk_l2_ipmc_lookup_type_e -+{ -+ LOOKUP_MAC = 0, -+ LOOKUP_IP, -+ LOOKUP_IP_VID, -+ LOOKUP_END -+} rtk_l2_ipmc_lookup_type_t; -+ -+/* l2 address table - unicast data structure */ -+typedef struct rtk_l2_ucastAddr_s -+{ -+ rtk_mac_t mac; -+ rtk_uint32 ivl; -+ rtk_uint32 cvid; -+ rtk_uint32 fid; -+ rtk_uint32 efid; -+ rtk_uint32 port; -+ rtk_uint32 sa_block; -+ rtk_uint32 da_block; -+ rtk_uint32 auth; -+ rtk_uint32 is_static; -+ rtk_uint32 priority; -+ rtk_uint32 sa_pri_en; -+ rtk_uint32 fwd_pri_en; -+ rtk_uint32 address; -+}rtk_l2_ucastAddr_t; -+ -+/* l2 address table - multicast data structure */ -+typedef struct rtk_l2_mcastAddr_s -+{ -+ rtk_uint32 vid; -+ rtk_mac_t mac; -+ rtk_uint32 fid; -+ rtk_portmask_t portmask; -+ rtk_uint32 ivl; -+ rtk_uint32 priority; -+ rtk_uint32 fwd_pri_en; -+ rtk_uint32 igmp_asic; -+ rtk_uint32 igmp_index; -+ rtk_uint32 address; -+}rtk_l2_mcastAddr_t; -+ -+/* l2 address table - ip multicast data structure */ -+typedef struct rtk_l2_ipMcastAddr_s -+{ -+ ipaddr_t dip; -+ ipaddr_t sip; -+ rtk_portmask_t portmask; -+ rtk_uint32 priority; -+ rtk_uint32 fwd_pri_en; -+ rtk_uint32 igmp_asic; -+ rtk_uint32 igmp_index; -+ rtk_uint32 address; -+}rtk_l2_ipMcastAddr_t; -+ -+/* l2 address table - ip VID multicast data structure */ -+typedef struct rtk_l2_ipVidMcastAddr_s -+{ -+ ipaddr_t dip; -+ ipaddr_t sip; -+ rtk_uint32 vid; -+ rtk_portmask_t portmask; -+ rtk_uint32 address; -+}rtk_l2_ipVidMcastAddr_t; -+ -+typedef struct rtk_l2_addr_table_s -+{ -+ rtk_uint32 index; -+ ipaddr_t sip; -+ ipaddr_t dip; -+ rtk_mac_t mac; -+ rtk_uint32 sa_block; -+ rtk_uint32 auth; -+ rtk_portmask_t portmask; -+ rtk_uint32 age; -+ rtk_uint32 ivl; -+ rtk_uint32 cvid; -+ rtk_uint32 fid; -+ rtk_uint32 is_ipmul; -+ rtk_uint32 is_static; -+ rtk_uint32 is_ipvidmul; -+ rtk_uint32 l3_vid; -+}rtk_l2_addr_table_t; -+ -+typedef enum rtk_l2_clearStatus_e -+{ -+ L2_CLEAR_STATE_FINISH = 0, -+ L2_CLEAR_STATE_BUSY, -+ L2_CLEAR_STATE_END -+}rtk_l2_clearStatus_t; -+ -+/* Function Name: -+ * rtk_l2_init -+ * Description: -+ * Initialize l2 module of the specified device. -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * Initialize l2 module before calling any l2 APIs. -+ */ -+extern rtk_api_ret_t rtk_l2_init(void); -+ -+/* Function Name: -+ * rtk_l2_addr_add -+ * Description: -+ * Add LUT unicast entry. -+ * Input: -+ * pMac - 6 bytes unicast(I/G bit is 0) mac address to be written into LUT. -+ * pL2_data - Unicast entry parameter -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_MAC - Invalid MAC address. -+ * RT_ERR_L2_FID - Invalid FID . -+ * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * If the unicast mac address already existed in LUT, it will update the status of the entry. -+ * Otherwise, it will find an empty or asic auto learned entry to write. If all the entries -+ * with the same hash value can't be replaced, ASIC will return a RT_ERR_L2_INDEXTBL_FULL error. -+ */ -+extern rtk_api_ret_t rtk_l2_addr_add(rtk_mac_t *pMac, rtk_l2_ucastAddr_t *pL2_data); -+ -+/* Function Name: -+ * rtk_l2_addr_get -+ * Description: -+ * Get LUT unicast entry. -+ * Input: -+ * pMac - 6 bytes unicast(I/G bit is 0) mac address to be written into LUT. -+ * Output: -+ * pL2_data - Unicast entry parameter -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_MAC - Invalid MAC address. -+ * RT_ERR_L2_FID - Invalid FID . -+ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * If the unicast mac address existed in LUT, it will return the port and fid where -+ * the mac is learned. Otherwise, it will return a RT_ERR_L2_ENTRY_NOTFOUND error. -+ */ -+extern rtk_api_ret_t rtk_l2_addr_get(rtk_mac_t *pMac, rtk_l2_ucastAddr_t *pL2_data); -+ -+/* Function Name: -+ * rtk_l2_addr_next_get -+ * Description: -+ * Get Next LUT unicast entry. -+ * Input: -+ * read_method - The reading method. -+ * port - The port number if the read_metohd is READMETHOD_NEXT_L2UCSPA -+ * pAddress - The Address ID -+ * Output: -+ * pL2_data - Unicast entry parameter -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_MAC - Invalid MAC address. -+ * RT_ERR_L2_FID - Invalid FID . -+ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * Get the next unicast entry after the current entry pointed by pAddress. -+ * The address of next entry is returned by pAddress. User can use (address + 1) -+ * as pAddress to call this API again for dumping all entries is LUT. -+ */ -+extern rtk_api_ret_t rtk_l2_addr_next_get(rtk_l2_read_method_t read_method, rtk_port_t port, rtk_uint32 *pAddress, rtk_l2_ucastAddr_t *pL2_data); -+ -+/* Function Name: -+ * rtk_l2_addr_del -+ * Description: -+ * Delete LUT unicast entry. -+ * Input: -+ * pMac - 6 bytes unicast(I/G bit is 0) mac address to be written into LUT. -+ * fid - Filtering database -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_MAC - Invalid MAC address. -+ * RT_ERR_L2_FID - Invalid FID . -+ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * If the mac has existed in the LUT, it will be deleted. Otherwise, it will return RT_ERR_L2_ENTRY_NOTFOUND. -+ */ -+extern rtk_api_ret_t rtk_l2_addr_del(rtk_mac_t *pMac, rtk_l2_ucastAddr_t *pL2_data); -+ -+/* Function Name: -+ * rtk_l2_mcastAddr_add -+ * Description: -+ * Add LUT multicast entry. -+ * Input: -+ * pMcastAddr - L2 multicast entry structure -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_MAC - Invalid MAC address. -+ * RT_ERR_L2_FID - Invalid FID . -+ * RT_ERR_L2_VID - Invalid VID . -+ * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. -+ * RT_ERR_PORT_MASK - Invalid portmask. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * If the multicast mac address already existed in the LUT, it will update the -+ * port mask of the entry. Otherwise, it will find an empty or asic auto learned -+ * entry to write. If all the entries with the same hash value can't be replaced, -+ * ASIC will return a RT_ERR_L2_INDEXTBL_FULL error. -+ */ -+extern rtk_api_ret_t rtk_l2_mcastAddr_add(rtk_l2_mcastAddr_t *pMcastAddr); -+ -+/* Function Name: -+ * rtk_l2_mcastAddr_get -+ * Description: -+ * Get LUT multicast entry. -+ * Input: -+ * pMcastAddr - L2 multicast entry structure -+ * Output: -+ * pMcastAddr - L2 multicast entry structure -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_MAC - Invalid MAC address. -+ * RT_ERR_L2_FID - Invalid FID . -+ * RT_ERR_L2_VID - Invalid VID . -+ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * If the multicast mac address existed in the LUT, it will return the port where -+ * the mac is learned. Otherwise, it will return a RT_ERR_L2_ENTRY_NOTFOUND error. -+ */ -+extern rtk_api_ret_t rtk_l2_mcastAddr_get(rtk_l2_mcastAddr_t *pMcastAddr); -+ -+/* Function Name: -+ * rtk_l2_mcastAddr_next_get -+ * Description: -+ * Get Next L2 Multicast entry. -+ * Input: -+ * pAddress - The Address ID -+ * Output: -+ * pMcastAddr - L2 multicast entry structure -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * Get the next L2 multicast entry after the current entry pointed by pAddress. -+ * The address of next entry is returned by pAddress. User can use (address + 1) -+ * as pAddress to call this API again for dumping all multicast entries is LUT. -+ */ -+extern rtk_api_ret_t rtk_l2_mcastAddr_next_get(rtk_uint32 *pAddress, rtk_l2_mcastAddr_t *pMcastAddr); -+ -+/* Function Name: -+ * rtk_l2_mcastAddr_del -+ * Description: -+ * Delete LUT multicast entry. -+ * Input: -+ * pMcastAddr - L2 multicast entry structure -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_MAC - Invalid MAC address. -+ * RT_ERR_L2_FID - Invalid FID . -+ * RT_ERR_L2_VID - Invalid VID . -+ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * If the mac has existed in the LUT, it will be deleted. Otherwise, it will return RT_ERR_L2_ENTRY_NOTFOUND. -+ */ -+extern rtk_api_ret_t rtk_l2_mcastAddr_del(rtk_l2_mcastAddr_t *pMcastAddr); -+ -+/* Function Name: -+ * rtk_l2_ipMcastAddr_add -+ * Description: -+ * Add LUT IP multicast entry -+ * Input: -+ * pIpMcastAddr - IP Multicast entry -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. -+ * RT_ERR_PORT_MASK - Invalid portmask. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * System supports L2 entry with IP multicast DIP/SIP to forward IP multicasting frame as user -+ * desired. If this function is enabled, then system will be looked up L2 IP multicast entry to -+ * forward IP multicast frame directly without flooding. -+ */ -+extern rtk_api_ret_t rtk_l2_ipMcastAddr_add(rtk_l2_ipMcastAddr_t *pIpMcastAddr); -+ -+/* Function Name: -+ * rtk_l2_ipMcastAddr_get -+ * Description: -+ * Get LUT IP multicast entry. -+ * Input: -+ * pIpMcastAddr - IP Multicast entry -+ * Output: -+ * pIpMcastAddr - IP Multicast entry -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can get LUT table of IP multicast entry. -+ */ -+extern rtk_api_ret_t rtk_l2_ipMcastAddr_get(rtk_l2_ipMcastAddr_t *pIpMcastAddr); -+ -+/* Function Name: -+ * rtk_l2_ipMcastAddr_next_get -+ * Description: -+ * Get Next IP Multicast entry. -+ * Input: -+ * pAddress - The Address ID -+ * Output: -+ * pIpMcastAddr - IP Multicast entry -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * Get the next IP multicast entry after the current entry pointed by pAddress. -+ * The address of next entry is returned by pAddress. User can use (address + 1) -+ * as pAddress to call this API again for dumping all IP multicast entries is LUT. -+ */ -+extern rtk_api_ret_t rtk_l2_ipMcastAddr_next_get(rtk_uint32 *pAddress, rtk_l2_ipMcastAddr_t *pIpMcastAddr); -+ -+/* Function Name: -+ * rtk_l2_ipMcastAddr_del -+ * Description: -+ * Delete a ip multicast address entry from the specified device. -+ * Input: -+ * pIpMcastAddr - IP Multicast entry -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can delete a IP multicast address entry from the specified device. -+ */ -+extern rtk_api_ret_t rtk_l2_ipMcastAddr_del(rtk_l2_ipMcastAddr_t *pIpMcastAddr); -+ -+/* Function Name: -+ * rtk_l2_ipVidMcastAddr_add -+ * Description: -+ * Add LUT IP multicast+VID entry -+ * Input: -+ * pIpVidMcastAddr - IP & VID multicast Entry -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. -+ * RT_ERR_PORT_MASK - Invalid portmask. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_l2_ipVidMcastAddr_add(rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr); -+ -+/* Function Name: -+ * rtk_l2_ipVidMcastAddr_get -+ * Description: -+ * Get LUT IP multicast+VID entry. -+ * Input: -+ * pIpVidMcastAddr - IP & VID multicast Entry -+ * Output: -+ * pIpVidMcastAddr - IP & VID multicast Entry -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_l2_ipVidMcastAddr_get(rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr); -+ -+/* Function Name: -+ * rtk_l2_ipVidMcastAddr_next_get -+ * Description: -+ * Get Next IP Multicast+VID entry. -+ * Input: -+ * pAddress - The Address ID -+ * Output: -+ * pIpVidMcastAddr - IP & VID multicast Entry -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * Get the next IP multicast entry after the current entry pointed by pAddress. -+ * The address of next entry is returned by pAddress. User can use (address + 1) -+ * as pAddress to call this API again for dumping all IP multicast entries is LUT. -+ */ -+extern rtk_api_ret_t rtk_l2_ipVidMcastAddr_next_get(rtk_uint32 *pAddress, rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr); -+ -+/* Function Name: -+ * rtk_l2_ipVidMcastAddr_del -+ * Description: -+ * Delete a ip multicast+VID address entry from the specified device. -+ * Input: -+ * pIpVidMcastAddr - IP & VID multicast Entry -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_l2_ipVidMcastAddr_del(rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr); -+ -+/* Function Name: -+ * rtk_l2_ucastAddr_flush -+ * Description: -+ * Flush L2 mac address by type in the specified device (both dynamic and static). -+ * Input: -+ * pConfig - flush configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_VLAN_VID - Invalid VID parameter. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * flushByVid - 1: Flush by VID, 0: Don't flush by VID -+ * vid - VID (0 ~ 4095) -+ * flushByFid - 1: Flush by FID, 0: Don't flush by FID -+ * fid - FID (0 ~ 15) -+ * flushByPort - 1: Flush by Port, 0: Don't flush by Port -+ * port - Port ID -+ * flushByMac - Not Supported -+ * ucastAddr - Not Supported -+ * flushStaticAddr - 1: Flush both Static and Dynamic entries, 0: Flush only Dynamic entries -+ * flushAddrOnAllPorts - 1: Flush VID-matched entries at all ports, 0: Flush VID-matched entries per port. -+ */ -+extern rtk_api_ret_t rtk_l2_ucastAddr_flush(rtk_l2_flushCfg_t *pConfig); -+ -+/* Function Name: -+ * rtk_l2_table_clear -+ * Description: -+ * Flush all static & dynamic entries in LUT. -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_l2_table_clear(void); -+ -+/* Function Name: -+ * rtk_l2_table_clearStatus_get -+ * Description: -+ * Get table clear status -+ * Input: -+ * None -+ * Output: -+ * pStatus - Clear status, 1:Busy, 0:finish -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_l2_table_clearStatus_get(rtk_l2_clearStatus_t *pStatus); -+ -+/* Function Name: -+ * rtk_l2_flushLinkDownPortAddrEnable_set -+ * Description: -+ * Set HW flush linkdown port mac configuration of the specified device. -+ * Input: -+ * port - Port id. -+ * enable - link down flush status -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_ENABLE - Invalid enable input. -+ * Note: -+ * The status of flush linkdown port address is as following: -+ * - DISABLED -+ * - ENABLED -+ */ -+extern rtk_api_ret_t rtk_l2_flushLinkDownPortAddrEnable_set(rtk_port_t port, rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_l2_flushLinkDownPortAddrEnable_get -+ * Description: -+ * Get HW flush linkdown port mac configuration of the specified device. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pEnable - link down flush status -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The status of flush linkdown port address is as following: -+ * - DISABLED -+ * - ENABLED -+ */ -+extern rtk_api_ret_t rtk_l2_flushLinkDownPortAddrEnable_get(rtk_port_t port, rtk_enable_t *pEnable); -+ -+/* Function Name: -+ * rtk_l2_agingEnable_set -+ * Description: -+ * Set L2 LUT aging status per port setting. -+ * Input: -+ * port - Port id. -+ * enable - Aging status -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_ENABLE - Invalid enable input. -+ * Note: -+ * This API can be used to set L2 LUT aging status per port. -+ */ -+extern rtk_api_ret_t rtk_l2_agingEnable_set(rtk_port_t port, rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_l2_agingEnable_get -+ * Description: -+ * Get L2 LUT aging status per port setting. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pEnable - Aging status -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * This API can be used to get L2 LUT aging function per port. -+ */ -+extern rtk_api_ret_t rtk_l2_agingEnable_get(rtk_port_t port, rtk_enable_t *pEnable); -+ -+/* Function Name: -+ * rtk_l2_limitLearningCnt_set -+ * Description: -+ * Set per-Port auto learning limit number -+ * Input: -+ * port - Port id. -+ * mac_cnt - Auto learning entries limit number -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_LIMITED_L2ENTRY_NUM - Invalid auto learning limit number -+ * Note: -+ * The API can set per-port ASIC auto learning limit number from 0(disable learning) -+ * to 8k. -+ */ -+extern rtk_api_ret_t rtk_l2_limitLearningCnt_set(rtk_port_t port, rtk_mac_cnt_t mac_cnt); -+ -+/* Function Name: -+ * rtk_l2_limitLearningCnt_get -+ * Description: -+ * Get per-Port auto learning limit number -+ * Input: -+ * port - Port id. -+ * Output: -+ * pMac_cnt - Auto learning entries limit number -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get per-port ASIC auto learning limit number. -+ */ -+extern rtk_api_ret_t rtk_l2_limitLearningCnt_get(rtk_port_t port, rtk_mac_cnt_t *pMac_cnt); -+ -+/* Function Name: -+ * rtk_l2_limitSystemLearningCnt_set -+ * Description: -+ * Set System auto learning limit number -+ * Input: -+ * mac_cnt - Auto learning entries limit number -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_LIMITED_L2ENTRY_NUM - Invalid auto learning limit number -+ * Note: -+ * The API can set system ASIC auto learning limit number from 0(disable learning) -+ * to 2112. -+ */ -+extern rtk_api_ret_t rtk_l2_limitSystemLearningCnt_set(rtk_mac_cnt_t mac_cnt); -+ -+/* Function Name: -+ * rtk_l2_limitSystemLearningCnt_get -+ * Description: -+ * Get System auto learning limit number -+ * Input: -+ * None -+ * Output: -+ * pMac_cnt - Auto learning entries limit number -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get system ASIC auto learning limit number. -+ */ -+extern rtk_api_ret_t rtk_l2_limitSystemLearningCnt_get(rtk_mac_cnt_t *pMac_cnt); -+ -+/* Function Name: -+ * rtk_l2_limitLearningCntAction_set -+ * Description: -+ * Configure auto learn over limit number action. -+ * Input: -+ * port - Port id. -+ * action - Auto learning entries limit number -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_NOT_ALLOWED - Invalid learn over action -+ * Note: -+ * The API can set SA unknown packet action while auto learn limit number is over -+ * The action symbol as following: -+ * - LIMIT_LEARN_CNT_ACTION_DROP, -+ * - LIMIT_LEARN_CNT_ACTION_FORWARD, -+ * - LIMIT_LEARN_CNT_ACTION_TO_CPU, -+ */ -+extern rtk_api_ret_t rtk_l2_limitLearningCntAction_set(rtk_port_t port, rtk_l2_limitLearnCntAction_t action); -+ -+/* Function Name: -+ * rtk_l2_limitLearningCntAction_get -+ * Description: -+ * Get auto learn over limit number action. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pAction - Learn over action -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get SA unknown packet action while auto learn limit number is over -+ * The action symbol as following: -+ * - LIMIT_LEARN_CNT_ACTION_DROP, -+ * - LIMIT_LEARN_CNT_ACTION_FORWARD, -+ * - LIMIT_LEARN_CNT_ACTION_TO_CPU, -+ */ -+extern rtk_api_ret_t rtk_l2_limitLearningCntAction_get(rtk_port_t port, rtk_l2_limitLearnCntAction_t *pAction); -+ -+/* Function Name: -+ * rtk_l2_limitSystemLearningCntAction_set -+ * Description: -+ * Configure system auto learn over limit number action. -+ * Input: -+ * port - Port id. -+ * action - Auto learning entries limit number -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_NOT_ALLOWED - Invalid learn over action -+ * Note: -+ * The API can set SA unknown packet action while auto learn limit number is over -+ * The action symbol as following: -+ * - LIMIT_LEARN_CNT_ACTION_DROP, -+ * - LIMIT_LEARN_CNT_ACTION_FORWARD, -+ * - LIMIT_LEARN_CNT_ACTION_TO_CPU, -+ */ -+extern rtk_api_ret_t rtk_l2_limitSystemLearningCntAction_set(rtk_l2_limitLearnCntAction_t action); -+ -+/* Function Name: -+ * rtk_l2_limitSystemLearningCntAction_get -+ * Description: -+ * Get system auto learn over limit number action. -+ * Input: -+ * None. -+ * Output: -+ * pAction - Learn over action -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get SA unknown packet action while auto learn limit number is over -+ * The action symbol as following: -+ * - LIMIT_LEARN_CNT_ACTION_DROP, -+ * - LIMIT_LEARN_CNT_ACTION_FORWARD, -+ * - LIMIT_LEARN_CNT_ACTION_TO_CPU, -+ */ -+extern rtk_api_ret_t rtk_l2_limitSystemLearningCntAction_get(rtk_l2_limitLearnCntAction_t *pAction); -+ -+/* Function Name: -+ * rtk_l2_limitSystemLearningCntPortMask_set -+ * Description: -+ * Configure system auto learn portmask -+ * Input: -+ * pPortmask - Port Mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Invalid port mask. -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_l2_limitSystemLearningCntPortMask_set(rtk_portmask_t *pPortmask); -+ -+/* Function Name: -+ * rtk_l2_limitSystemLearningCntPortMask_get -+ * Description: -+ * get system auto learn portmask -+ * Input: -+ * None -+ * Output: -+ * pPortmask - Port Mask -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Null pointer. -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_l2_limitSystemLearningCntPortMask_get(rtk_portmask_t *pPortmask); -+ -+/* Function Name: -+ * rtk_l2_learningCnt_get -+ * Description: -+ * Get per-Port current auto learning number -+ * Input: -+ * port - Port id. -+ * Output: -+ * pMac_cnt - ASIC auto learning entries number -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get per-port ASIC auto learning number -+ */ -+extern rtk_api_ret_t rtk_l2_learningCnt_get(rtk_port_t port, rtk_mac_cnt_t *pMac_cnt); -+ -+/* Function Name: -+ * rtk_l2_floodPortMask_set -+ * Description: -+ * Set flooding portmask -+ * Input: -+ * type - flooding type. -+ * pFlood_portmask - flooding portmask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Invalid portmask. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can set the flooding mask. -+ * The flooding type is as following: -+ * - FLOOD_UNKNOWNDA -+ * - FLOOD_UNKNOWNMC -+ * - FLOOD_BC -+ */ -+extern rtk_api_ret_t rtk_l2_floodPortMask_set(rtk_l2_flood_type_t floood_type, rtk_portmask_t *pFlood_portmask); -+ -+/* Function Name: -+ * rtk_l2_floodPortMask_get -+ * Description: -+ * Get flooding portmask -+ * Input: -+ * type - flooding type. -+ * Output: -+ * pFlood_portmask - flooding portmask -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * This API can get the flooding mask. -+ * The flooding type is as following: -+ * - FLOOD_UNKNOWNDA -+ * - FLOOD_UNKNOWNMC -+ * - FLOOD_BC -+ */ -+extern rtk_api_ret_t rtk_l2_floodPortMask_get(rtk_l2_flood_type_t floood_type, rtk_portmask_t *pFlood_portmask); -+ -+/* Function Name: -+ * rtk_l2_localPktPermit_set -+ * Description: -+ * Set permission of frames if source port and destination port are the same. -+ * Input: -+ * port - Port id. -+ * permit - permission status -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_ENABLE - Invalid permit value. -+ * Note: -+ * This API is set to permit frame if its source port is equal to destination port. -+ */ -+extern rtk_api_ret_t rtk_l2_localPktPermit_set(rtk_port_t port, rtk_enable_t permit); -+ -+/* Function Name: -+ * rtk_l2_localPktPermit_get -+ * Description: -+ * Get permission of frames if source port and destination port are the same. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pPermit - permission status -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * This API is to get permission status for frames if its source port is equal to destination port. -+ */ -+extern rtk_api_ret_t rtk_l2_localPktPermit_get(rtk_port_t port, rtk_enable_t *pPermit); -+ -+/* Function Name: -+ * rtk_l2_aging_set -+ * Description: -+ * Set LUT ageing out speed -+ * Input: -+ * aging_time - Ageing out time. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * Note: -+ * The API can set LUT ageing out period for each entry and the range is from 14s to 800s. -+ */ -+extern rtk_api_ret_t rtk_l2_aging_set(rtk_l2_age_time_t aging_time); -+ -+/* Function Name: -+ * rtk_l2_aging_get -+ * Description: -+ * Get LUT ageing out time -+ * Input: -+ * None -+ * Output: -+ * pEnable - Aging status -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get LUT ageing out period for each entry. -+ */ -+extern rtk_api_ret_t rtk_l2_aging_get(rtk_l2_age_time_t *pAging_time); -+ -+/* Function Name: -+ * rtk_l2_ipMcastAddrLookup_set -+ * Description: -+ * Set LUT IP multicast lookup function -+ * Input: -+ * type - Lookup type for IPMC packet. -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * This API can work with rtk_l2_ipMcastAddrLookupException_add. -+ * If users set the lookup type to DIP, the group in exception table -+ * will be lookup by DIP+SIP -+ * If users set the lookup type to DIP+SIP, the group in exception table -+ * will be lookup by only DIP -+ */ -+extern rtk_api_ret_t rtk_l2_ipMcastAddrLookup_set(rtk_l2_ipmc_lookup_type_t type); -+ -+/* Function Name: -+ * rtk_l2_ipMcastAddrLookup_get -+ * Description: -+ * Get LUT IP multicast lookup function -+ * Input: -+ * None. -+ * Output: -+ * pType - Lookup type for IPMC packet. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None. -+ */ -+extern rtk_api_ret_t rtk_l2_ipMcastAddrLookup_get(rtk_l2_ipmc_lookup_type_t *pType); -+ -+/* Function Name: -+ * rtk_l2_ipMcastForwardRouterPort_set -+ * Description: -+ * Set IPMC packet forward to router port also or not -+ * Input: -+ * enabled - 1: Include router port, 0, exclude router port -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_l2_ipMcastForwardRouterPort_set(rtk_enable_t enabled); -+ -+/* Function Name: -+ * rtk_l2_ipMcastForwardRouterPort_get -+ * Description: -+ * Get IPMC packet forward to router port also or not -+ * Input: -+ * None. -+ * Output: -+ * pEnabled - 1: Include router port, 0, exclude router port -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_l2_ipMcastForwardRouterPort_get(rtk_enable_t *pEnabled); -+ -+/* Function Name: -+ * rtk_l2_ipMcastGroupEntry_add -+ * Description: -+ * Add an IP Multicast entry to group table -+ * Input: -+ * ip_addr - IP address -+ * vid - VLAN ID -+ * pPortmask - portmask -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_TBL_FULL - Table Full -+ * Note: -+ * Add an entry to IP Multicast Group table. -+ */ -+extern rtk_api_ret_t rtk_l2_ipMcastGroupEntry_add(ipaddr_t ip_addr, rtk_uint32 vid, rtk_portmask_t *pPortmask); -+ -+/* Function Name: -+ * rtk_l2_ipMcastGroupEntry_del -+ * Description: -+ * Delete an entry from IP Multicast group table -+ * Input: -+ * ip_addr - IP address -+ * vid - VLAN ID -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_TBL_FULL - Table Full -+ * Note: -+ * Delete an entry from IP Multicast group table. -+ */ -+extern rtk_api_ret_t rtk_l2_ipMcastGroupEntry_del(ipaddr_t ip_addr, rtk_uint32 vid); -+ -+/* Function Name: -+ * rtk_l2_ipMcastGroupEntry_get -+ * Description: -+ * get an entry from IP Multicast group table -+ * Input: -+ * ip_addr - IP address -+ * vid - VLAN ID -+ * Output: -+ * pPortmask - member port mask -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_TBL_FULL - Table Full -+ * Note: -+ * Delete an entry from IP Multicast group table. -+ */ -+extern rtk_api_ret_t rtk_l2_ipMcastGroupEntry_get(ipaddr_t ip_addr, rtk_uint32 vid, rtk_portmask_t *pPortmask); -+ -+/* Function Name: -+ * rtk_l2_entry_get -+ * Description: -+ * Get LUT unicast entry. -+ * Input: -+ * pL2_entry - Index field in the structure. -+ * Output: -+ * pL2_entry - other fields such as MAC, port, age... -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_L2_EMPTY_ENTRY - Empty LUT entry. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API is used to get address by index from 0~2111. -+ */ -+extern rtk_api_ret_t rtk_l2_entry_get(rtk_l2_addr_table_t *pL2_entry); -+ -+ -+#endif /* __RTK_API_L2_H__ */ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/leaky.h b/drivers/net/phy/rtk/rtl8367c/include/leaky.h -new file mode 100644 -index 000000000000..e5b22e2878b4 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/leaky.h -@@ -0,0 +1,371 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * Purpose : RTL8367/RTL8367C switch high-level API -+ * -+ * Feature : The file includes Leaky module high-layer API definition -+ * -+ */ -+ -+#ifndef __RTK_API_LEAKY_H__ -+#define __RTK_API_LEAKY_H__ -+ -+ -+typedef enum rtk_leaky_type_e -+{ -+ LEAKY_BRG_GROUP = 0, -+ LEAKY_FD_PAUSE, -+ LEAKY_SP_MCAST, -+ LEAKY_1X_PAE, -+ LEAKY_UNDEF_BRG_04, -+ LEAKY_UNDEF_BRG_05, -+ LEAKY_UNDEF_BRG_06, -+ LEAKY_UNDEF_BRG_07, -+ LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS, -+ LEAKY_UNDEF_BRG_09, -+ LEAKY_UNDEF_BRG_0A, -+ LEAKY_UNDEF_BRG_0B, -+ LEAKY_UNDEF_BRG_0C, -+ LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS, -+ LEAKY_8021AB, -+ LEAKY_UNDEF_BRG_0F, -+ LEAKY_BRG_MNGEMENT, -+ LEAKY_UNDEFINED_11, -+ LEAKY_UNDEFINED_12, -+ LEAKY_UNDEFINED_13, -+ LEAKY_UNDEFINED_14, -+ LEAKY_UNDEFINED_15, -+ LEAKY_UNDEFINED_16, -+ LEAKY_UNDEFINED_17, -+ LEAKY_UNDEFINED_18, -+ LEAKY_UNDEFINED_19, -+ LEAKY_UNDEFINED_1A, -+ LEAKY_UNDEFINED_1B, -+ LEAKY_UNDEFINED_1C, -+ LEAKY_UNDEFINED_1D, -+ LEAKY_UNDEFINED_1E, -+ LEAKY_UNDEFINED_1F, -+ LEAKY_GMRP, -+ LEAKY_GVRP, -+ LEAKY_UNDEF_GARP_22, -+ LEAKY_UNDEF_GARP_23, -+ LEAKY_UNDEF_GARP_24, -+ LEAKY_UNDEF_GARP_25, -+ LEAKY_UNDEF_GARP_26, -+ LEAKY_UNDEF_GARP_27, -+ LEAKY_UNDEF_GARP_28, -+ LEAKY_UNDEF_GARP_29, -+ LEAKY_UNDEF_GARP_2A, -+ LEAKY_UNDEF_GARP_2B, -+ LEAKY_UNDEF_GARP_2C, -+ LEAKY_UNDEF_GARP_2D, -+ LEAKY_UNDEF_GARP_2E, -+ LEAKY_UNDEF_GARP_2F, -+ LEAKY_IGMP, -+ LEAKY_IPMULTICAST, -+ LEAKY_CDP, -+ LEAKY_CSSTP, -+ LEAKY_LLDP, -+ LEAKY_END, -+}rtk_leaky_type_t; -+ -+/* Function Name: -+ * rtk_leaky_vlan_set -+ * Description: -+ * Set VLAN leaky. -+ * Input: -+ * type - Packet type for VLAN leaky. -+ * enable - Leaky status. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_ENABLE - Invalid enable input -+ * Note: -+ * This API can set VLAN leaky for RMA ,IGMP/MLD, CDP, CSSTP, and LLDP packets. -+ * The leaky frame types are as following: -+ * - LEAKY_BRG_GROUP, -+ * - LEAKY_FD_PAUSE, -+ * - LEAKY_SP_MCAST, -+ * - LEAKY_1X_PAE, -+ * - LEAKY_UNDEF_BRG_04, -+ * - LEAKY_UNDEF_BRG_05, -+ * - LEAKY_UNDEF_BRG_06, -+ * - LEAKY_UNDEF_BRG_07, -+ * - LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS, -+ * - LEAKY_UNDEF_BRG_09, -+ * - LEAKY_UNDEF_BRG_0A, -+ * - LEAKY_UNDEF_BRG_0B, -+ * - LEAKY_UNDEF_BRG_0C, -+ * - LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS, -+ * - LEAKY_8021AB, -+ * - LEAKY_UNDEF_BRG_0F, -+ * - LEAKY_BRG_MNGEMENT, -+ * - LEAKY_UNDEFINED_11, -+ * - LEAKY_UNDEFINED_12, -+ * - LEAKY_UNDEFINED_13, -+ * - LEAKY_UNDEFINED_14, -+ * - LEAKY_UNDEFINED_15, -+ * - LEAKY_UNDEFINED_16, -+ * - LEAKY_UNDEFINED_17, -+ * - LEAKY_UNDEFINED_18, -+ * - LEAKY_UNDEFINED_19, -+ * - LEAKY_UNDEFINED_1A, -+ * - LEAKY_UNDEFINED_1B, -+ * - LEAKY_UNDEFINED_1C, -+ * - LEAKY_UNDEFINED_1D, -+ * - LEAKY_UNDEFINED_1E, -+ * - LEAKY_UNDEFINED_1F, -+ * - LEAKY_GMRP, -+ * - LEAKY_GVRP, -+ * - LEAKY_UNDEF_GARP_22, -+ * - LEAKY_UNDEF_GARP_23, -+ * - LEAKY_UNDEF_GARP_24, -+ * - LEAKY_UNDEF_GARP_25, -+ * - LEAKY_UNDEF_GARP_26, -+ * - LEAKY_UNDEF_GARP_27, -+ * - LEAKY_UNDEF_GARP_28, -+ * - LEAKY_UNDEF_GARP_29, -+ * - LEAKY_UNDEF_GARP_2A, -+ * - LEAKY_UNDEF_GARP_2B, -+ * - LEAKY_UNDEF_GARP_2C, -+ * - LEAKY_UNDEF_GARP_2D, -+ * - LEAKY_UNDEF_GARP_2E, -+ * - LEAKY_UNDEF_GARP_2F, -+ * - LEAKY_IGMP, -+ * - LEAKY_IPMULTICAST. -+ * - LEAKY_CDP, -+ * - LEAKY_CSSTP, -+ * - LEAKY_LLDP. -+ */ -+extern rtk_api_ret_t rtk_leaky_vlan_set(rtk_leaky_type_t type, rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_leaky_vlan_get -+ * Description: -+ * Get VLAN leaky. -+ * Input: -+ * type - Packet type for VLAN leaky. -+ * Output: -+ * pEnable - Leaky status. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can get VLAN leaky status for RMA ,IGMP/MLD, CDP, CSSTP, and LLDP packets. -+ * The leaky frame types are as following: -+ * - LEAKY_BRG_GROUP, -+ * - LEAKY_FD_PAUSE, -+ * - LEAKY_SP_MCAST, -+ * - LEAKY_1X_PAE, -+ * - LEAKY_UNDEF_BRG_04, -+ * - LEAKY_UNDEF_BRG_05, -+ * - LEAKY_UNDEF_BRG_06, -+ * - LEAKY_UNDEF_BRG_07, -+ * - LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS, -+ * - LEAKY_UNDEF_BRG_09, -+ * - LEAKY_UNDEF_BRG_0A, -+ * - LEAKY_UNDEF_BRG_0B, -+ * - LEAKY_UNDEF_BRG_0C, -+ * - LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS, -+ * - LEAKY_8021AB, -+ * - LEAKY_UNDEF_BRG_0F, -+ * - LEAKY_BRG_MNGEMENT, -+ * - LEAKY_UNDEFINED_11, -+ * - LEAKY_UNDEFINED_12, -+ * - LEAKY_UNDEFINED_13, -+ * - LEAKY_UNDEFINED_14, -+ * - LEAKY_UNDEFINED_15, -+ * - LEAKY_UNDEFINED_16, -+ * - LEAKY_UNDEFINED_17, -+ * - LEAKY_UNDEFINED_18, -+ * - LEAKY_UNDEFINED_19, -+ * - LEAKY_UNDEFINED_1A, -+ * - LEAKY_UNDEFINED_1B, -+ * - LEAKY_UNDEFINED_1C, -+ * - LEAKY_UNDEFINED_1D, -+ * - LEAKY_UNDEFINED_1E, -+ * - LEAKY_UNDEFINED_1F, -+ * - LEAKY_GMRP, -+ * - LEAKY_GVRP, -+ * - LEAKY_UNDEF_GARP_22, -+ * - LEAKY_UNDEF_GARP_23, -+ * - LEAKY_UNDEF_GARP_24, -+ * - LEAKY_UNDEF_GARP_25, -+ * - LEAKY_UNDEF_GARP_26, -+ * - LEAKY_UNDEF_GARP_27, -+ * - LEAKY_UNDEF_GARP_28, -+ * - LEAKY_UNDEF_GARP_29, -+ * - LEAKY_UNDEF_GARP_2A, -+ * - LEAKY_UNDEF_GARP_2B, -+ * - LEAKY_UNDEF_GARP_2C, -+ * - LEAKY_UNDEF_GARP_2D, -+ * - LEAKY_UNDEF_GARP_2E, -+ * - LEAKY_UNDEF_GARP_2F, -+ * - LEAKY_IGMP, -+ * - LEAKY_IPMULTICAST. -+ * - LEAKY_CDP, -+ * - LEAKY_CSSTP, -+ * - LEAKY_LLDP. -+ */ -+extern rtk_api_ret_t rtk_leaky_vlan_get(rtk_leaky_type_t type, rtk_enable_t *pEnable); -+ -+/* Function Name: -+ * rtk_leaky_portIsolation_set -+ * Description: -+ * Set port isolation leaky. -+ * Input: -+ * type - Packet type for port isolation leaky. -+ * enable - Leaky status. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_ENABLE - Invalid enable input -+ * Note: -+ * This API can set port isolation leaky for RMA ,IGMP/MLD, CDP, CSSTP, and LLDP packets. -+ * The leaky frame types are as following: -+ * - LEAKY_BRG_GROUP, -+ * - LEAKY_FD_PAUSE, -+ * - LEAKY_SP_MCAST, -+ * - LEAKY_1X_PAE, -+ * - LEAKY_UNDEF_BRG_04, -+ * - LEAKY_UNDEF_BRG_05, -+ * - LEAKY_UNDEF_BRG_06, -+ * - LEAKY_UNDEF_BRG_07, -+ * - LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS, -+ * - LEAKY_UNDEF_BRG_09, -+ * - LEAKY_UNDEF_BRG_0A, -+ * - LEAKY_UNDEF_BRG_0B, -+ * - LEAKY_UNDEF_BRG_0C, -+ * - LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS, -+ * - LEAKY_8021AB, -+ * - LEAKY_UNDEF_BRG_0F, -+ * - LEAKY_BRG_MNGEMENT, -+ * - LEAKY_UNDEFINED_11, -+ * - LEAKY_UNDEFINED_12, -+ * - LEAKY_UNDEFINED_13, -+ * - LEAKY_UNDEFINED_14, -+ * - LEAKY_UNDEFINED_15, -+ * - LEAKY_UNDEFINED_16, -+ * - LEAKY_UNDEFINED_17, -+ * - LEAKY_UNDEFINED_18, -+ * - LEAKY_UNDEFINED_19, -+ * - LEAKY_UNDEFINED_1A, -+ * - LEAKY_UNDEFINED_1B, -+ * - LEAKY_UNDEFINED_1C, -+ * - LEAKY_UNDEFINED_1D, -+ * - LEAKY_UNDEFINED_1E, -+ * - LEAKY_UNDEFINED_1F, -+ * - LEAKY_GMRP, -+ * - LEAKY_GVRP, -+ * - LEAKY_UNDEF_GARP_22, -+ * - LEAKY_UNDEF_GARP_23, -+ * - LEAKY_UNDEF_GARP_24, -+ * - LEAKY_UNDEF_GARP_25, -+ * - LEAKY_UNDEF_GARP_26, -+ * - LEAKY_UNDEF_GARP_27, -+ * - LEAKY_UNDEF_GARP_28, -+ * - LEAKY_UNDEF_GARP_29, -+ * - LEAKY_UNDEF_GARP_2A, -+ * - LEAKY_UNDEF_GARP_2B, -+ * - LEAKY_UNDEF_GARP_2C, -+ * - LEAKY_UNDEF_GARP_2D, -+ * - LEAKY_UNDEF_GARP_2E, -+ * - LEAKY_UNDEF_GARP_2F, -+ * - LEAKY_IGMP, -+ * - LEAKY_IPMULTICAST. -+ * - LEAKY_CDP, -+ * - LEAKY_CSSTP, -+ * - LEAKY_LLDP. -+ */ -+extern rtk_api_ret_t rtk_leaky_portIsolation_set(rtk_leaky_type_t type, rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_leaky_portIsolation_get -+ * Description: -+ * Get port isolation leaky. -+ * Input: -+ * type - Packet type for port isolation leaky. -+ * Output: -+ * pEnable - Leaky status. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can get port isolation leaky status for RMA ,IGMP/MLD, CDP, CSSTP, and LLDP packets. -+ * The leaky frame types are as following: -+ * - LEAKY_BRG_GROUP, -+ * - LEAKY_FD_PAUSE, -+ * - LEAKY_SP_MCAST, -+ * - LEAKY_1X_PAE, -+ * - LEAKY_UNDEF_BRG_04, -+ * - LEAKY_UNDEF_BRG_05, -+ * - LEAKY_UNDEF_BRG_06, -+ * - LEAKY_UNDEF_BRG_07, -+ * - LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS, -+ * - LEAKY_UNDEF_BRG_09, -+ * - LEAKY_UNDEF_BRG_0A, -+ * - LEAKY_UNDEF_BRG_0B, -+ * - LEAKY_UNDEF_BRG_0C, -+ * - LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS, -+ * - LEAKY_8021AB, -+ * - LEAKY_UNDEF_BRG_0F, -+ * - LEAKY_BRG_MNGEMENT, -+ * - LEAKY_UNDEFINED_11, -+ * - LEAKY_UNDEFINED_12, -+ * - LEAKY_UNDEFINED_13, -+ * - LEAKY_UNDEFINED_14, -+ * - LEAKY_UNDEFINED_15, -+ * - LEAKY_UNDEFINED_16, -+ * - LEAKY_UNDEFINED_17, -+ * - LEAKY_UNDEFINED_18, -+ * - LEAKY_UNDEFINED_19, -+ * - LEAKY_UNDEFINED_1A, -+ * - LEAKY_UNDEFINED_1B, -+ * - LEAKY_UNDEFINED_1C, -+ * - LEAKY_UNDEFINED_1D, -+ * - LEAKY_UNDEFINED_1E, -+ * - LEAKY_UNDEFINED_1F, -+ * - LEAKY_GMRP, -+ * - LEAKY_GVRP, -+ * - LEAKY_UNDEF_GARP_22, -+ * - LEAKY_UNDEF_GARP_23, -+ * - LEAKY_UNDEF_GARP_24, -+ * - LEAKY_UNDEF_GARP_25, -+ * - LEAKY_UNDEF_GARP_26, -+ * - LEAKY_UNDEF_GARP_27, -+ * - LEAKY_UNDEF_GARP_28, -+ * - LEAKY_UNDEF_GARP_29, -+ * - LEAKY_UNDEF_GARP_2A, -+ * - LEAKY_UNDEF_GARP_2B, -+ * - LEAKY_UNDEF_GARP_2C, -+ * - LEAKY_UNDEF_GARP_2D, -+ * - LEAKY_UNDEF_GARP_2E, -+ * - LEAKY_UNDEF_GARP_2F, -+ * - LEAKY_IGMP, -+ * - LEAKY_IPMULTICAST. -+ * - LEAKY_CDP, -+ * - LEAKY_CSSTP, -+ * - LEAKY_LLDP. -+ */ -+extern rtk_api_ret_t rtk_leaky_portIsolation_get(rtk_leaky_type_t type, rtk_enable_t *pEnable); -+ -+#endif /* __RTK_API_LEAKY_H__ */ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/led.h b/drivers/net/phy/rtk/rtl8367c/include/led.h -new file mode 100644 -index 000000000000..7706107ef40e ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/led.h -@@ -0,0 +1,481 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * Purpose : RTL8367/RTL8367C switch high-level API -+ * -+ * Feature : The file includes LED module high-layer API definition -+ * -+ */ -+ -+#ifndef __RTK_API_LED_H__ -+#define __RTK_API_LED_H__ -+ -+typedef enum rtk_led_operation_e -+{ -+ LED_OP_SCAN=0, -+ LED_OP_PARALLEL, -+ LED_OP_SERIAL, -+ LED_OP_END, -+}rtk_led_operation_t; -+ -+ -+typedef enum rtk_led_active_e -+{ -+ LED_ACTIVE_HIGH=0, -+ LED_ACTIVE_LOW, -+ LED_ACTIVE_END, -+}rtk_led_active_t; -+ -+typedef enum rtk_led_config_e -+{ -+ LED_CONFIG_LEDOFF=0, -+ LED_CONFIG_DUPCOL, -+ LED_CONFIG_LINK_ACT, -+ LED_CONFIG_SPD1000, -+ LED_CONFIG_SPD100, -+ LED_CONFIG_SPD10, -+ LED_CONFIG_SPD1000ACT, -+ LED_CONFIG_SPD100ACT, -+ LED_CONFIG_SPD10ACT, -+ LED_CONFIG_SPD10010ACT, -+ LED_CONFIG_LOOPDETECT, -+ LED_CONFIG_EEE, -+ LED_CONFIG_LINKRX, -+ LED_CONFIG_LINKTX, -+ LED_CONFIG_MASTER, -+ LED_CONFIG_ACT, -+ LED_CONFIG_END, -+}rtk_led_congig_t; -+ -+typedef struct rtk_led_ability_s -+{ -+ rtk_enable_t link_10m; -+ rtk_enable_t link_100m; -+ rtk_enable_t link_500m; -+ rtk_enable_t link_1000m; -+ rtk_enable_t act_rx; -+ rtk_enable_t act_tx; -+}rtk_led_ability_t; -+ -+typedef enum rtk_led_blink_rate_e -+{ -+ LED_BLINKRATE_32MS=0, -+ LED_BLINKRATE_64MS, -+ LED_BLINKRATE_128MS, -+ LED_BLINKRATE_256MS, -+ LED_BLINKRATE_512MS, -+ LED_BLINKRATE_1024MS, -+ LED_BLINKRATE_48MS, -+ LED_BLINKRATE_96MS, -+ LED_BLINKRATE_END, -+}rtk_led_blink_rate_t; -+ -+typedef enum rtk_led_group_e -+{ -+ LED_GROUP_0 = 0, -+ LED_GROUP_1, -+ LED_GROUP_2, -+ LED_GROUP_END -+}rtk_led_group_t; -+ -+ -+typedef enum rtk_led_force_mode_e -+{ -+ LED_FORCE_NORMAL=0, -+ LED_FORCE_BLINK, -+ LED_FORCE_OFF, -+ LED_FORCE_ON, -+ LED_FORCE_END -+}rtk_led_force_mode_t; -+ -+typedef enum rtk_led_serialOutput_e -+{ -+ SERIAL_LED_NONE = 0, -+ SERIAL_LED_0, -+ SERIAL_LED_0_1, -+ SERIAL_LED_0_2, -+ SERIAL_LED_END, -+}rtk_led_serialOutput_t; -+ -+ -+/* Function Name: -+ * rtk_led_enable_set -+ * Description: -+ * Set Led enable configuration -+ * Input: -+ * group - LED group id. -+ * pPortmask - LED enable port mask. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can be used to enable LED per port per group. -+ */ -+extern rtk_api_ret_t rtk_led_enable_set(rtk_led_group_t group, rtk_portmask_t *pPortmask); -+ -+/* Function Name: -+ * rtk_led_enable_get -+ * Description: -+ * Get Led enable configuration -+ * Input: -+ * group - LED group id. -+ * Output: -+ * pPortmask - LED enable port mask. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can be used to get LED enable status. -+ */ -+extern rtk_api_ret_t rtk_led_enable_get(rtk_led_group_t group, rtk_portmask_t *pPortmask); -+ -+/* Function Name: -+ * rtk_led_operation_set -+ * Description: -+ * Set Led operation mode -+ * Input: -+ * mode - LED operation mode. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can set Led operation mode. -+ * The modes that can be set are as following: -+ * - LED_OP_SCAN, -+ * - LED_OP_PARALLEL, -+ * - LED_OP_SERIAL, -+ */ -+extern rtk_api_ret_t rtk_led_operation_set(rtk_led_operation_t mode); -+ -+/* Function Name: -+ * rtk_led_operation_get -+ * Description: -+ * Get Led operation mode -+ * Input: -+ * None -+ * Output: -+ * pMode - Support LED operation mode. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can get Led operation mode. -+ * The modes that can be set are as following: -+ * - LED_OP_SCAN, -+ * - LED_OP_PARALLEL, -+ * - LED_OP_SERIAL, -+ */ -+extern rtk_api_ret_t rtk_led_operation_get(rtk_led_operation_t *pMode); -+ -+/* Function Name: -+ * rtk_led_modeForce_set -+ * Description: -+ * Set Led group to configuration force mode -+ * Input: -+ * port - port ID -+ * group - Support LED group id. -+ * mode - Support LED force mode. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Error Port ID -+ * Note: -+ * The API can force to one force mode. -+ * The force modes that can be set are as following: -+ * - LED_FORCE_NORMAL, -+ * - LED_FORCE_BLINK, -+ * - LED_FORCE_OFF, -+ * - LED_FORCE_ON. -+ */ -+extern rtk_api_ret_t rtk_led_modeForce_set(rtk_port_t port, rtk_led_group_t group, rtk_led_force_mode_t mode); -+ -+/* Function Name: -+ * rtk_led_modeForce_get -+ * Description: -+ * Get Led group to configuration force mode -+ * Input: -+ * port - port ID -+ * group - Support LED group id. -+ * pMode - Support LED force mode. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Error Port ID -+ * Note: -+ * The API can get forced Led group mode. -+ * The force modes that can be set are as following: -+ * - LED_FORCE_NORMAL, -+ * - LED_FORCE_BLINK, -+ * - LED_FORCE_OFF, -+ * - LED_FORCE_ON. -+ */ -+extern rtk_api_ret_t rtk_led_modeForce_get(rtk_port_t port, rtk_led_group_t group, rtk_led_force_mode_t *pMode); -+ -+/* Function Name: -+ * rtk_led_blinkRate_set -+ * Description: -+ * Set LED blinking rate -+ * Input: -+ * blinkRate - blinking rate. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * ASIC support 6 types of LED blinking rates at 43ms, 84ms, 120ms, 170ms, 340ms and 670ms. -+ */ -+extern rtk_api_ret_t rtk_led_blinkRate_set(rtk_led_blink_rate_t blinkRate); -+ -+/* Function Name: -+ * rtk_led_blinkRate_get -+ * Description: -+ * Get LED blinking rate at mode 0 to mode 3 -+ * Input: -+ * None -+ * Output: -+ * pBlinkRate - blinking rate. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * There are 6 types of LED blinking rates at 43ms, 84ms, 120ms, 170ms, 340ms and 670ms. -+ */ -+extern rtk_api_ret_t rtk_led_blinkRate_get(rtk_led_blink_rate_t *pBlinkRate); -+ -+/* Function Name: -+ * rtk_led_groupConfig_set -+ * Description: -+ * Set per group Led to configuration mode -+ * Input: -+ * group - LED group. -+ * config - LED configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can set LED indicated information configuration for each LED group with 1 to 1 led mapping to each port. -+ * - Definition LED Statuses Description -+ * - 0000 LED_Off LED pin Tri-State. -+ * - 0001 Dup/Col Collision, Full duplex Indicator. -+ * - 0010 Link/Act Link, Activity Indicator. -+ * - 0011 Spd1000 1000Mb/s Speed Indicator. -+ * - 0100 Spd100 100Mb/s Speed Indicator. -+ * - 0101 Spd10 10Mb/s Speed Indicator. -+ * - 0110 Spd1000/Act 1000Mb/s Speed/Activity Indicator. -+ * - 0111 Spd100/Act 100Mb/s Speed/Activity Indicator. -+ * - 1000 Spd10/Act 10Mb/s Speed/Activity Indicator. -+ * - 1001 Spd100 (10)/Act 10/100Mb/s Speed/Activity Indicator. -+ * - 1010 LoopDetect LoopDetect Indicator. -+ * - 1011 EEE EEE Indicator. -+ * - 1100 Link/Rx Link, Activity Indicator. -+ * - 1101 Link/Tx Link, Activity Indicator. -+ * - 1110 Master Link on Master Indicator. -+ * - 1111 Act Activity Indicator. Low for link established. -+ */ -+extern rtk_api_ret_t rtk_led_groupConfig_set(rtk_led_group_t group, rtk_led_congig_t config); -+ -+/* Function Name: -+ * rtk_led_groupConfig_get -+ * Description: -+ * Get Led group configuration mode -+ * Input: -+ * group - LED group. -+ * Output: -+ * pConfig - LED configuration. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can get LED indicated information configuration for each LED group. -+ */ -+extern rtk_api_ret_t rtk_led_groupConfig_get(rtk_led_group_t group, rtk_led_congig_t *pConfig); -+ -+/* Function Name: -+ * rtk_led_groupAbility_set -+ * Description: -+ * Configure per group Led ability -+ * Input: -+ * group - LED group. -+ * pAbility - LED ability -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * None. -+ */ -+ -+extern rtk_api_ret_t rtk_led_groupAbility_set(rtk_led_group_t group, rtk_led_ability_t *pAbility); -+ -+/* Function Name: -+ * rtk_led_groupAbility_get -+ * Description: -+ * Get per group Led ability -+ * Input: -+ * group - LED group. -+ * pAbility - LED ability -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * None. -+ */ -+ -+extern rtk_api_ret_t rtk_led_groupAbility_get(rtk_led_group_t group, rtk_led_ability_t *pAbility); -+ -+/* Function Name: -+ * rtk_led_serialMode_set -+ * Description: -+ * Set Led serial mode active configuration -+ * Input: -+ * active - LED group. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can set LED serial mode active configuration. -+ */ -+extern rtk_api_ret_t rtk_led_serialMode_set(rtk_led_active_t active); -+ -+/* Function Name: -+ * rtk_led_serialMode_get -+ * Description: -+ * Get Led group configuration mode -+ * Input: -+ * group - LED group. -+ * Output: -+ * pConfig - LED configuration. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can get LED serial mode active configuration. -+ */ -+extern rtk_api_ret_t rtk_led_serialMode_get(rtk_led_active_t *pActive); -+ -+/* Function Name: -+ * rtk_led_OutputEnable_set -+ * Description: -+ * This API set LED I/O state. -+ * Input: -+ * enabled - LED I/O state -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error parameter -+ * Note: -+ * This API set LED I/O state. -+ */ -+extern rtk_api_ret_t rtk_led_OutputEnable_set(rtk_enable_t state); -+ -+ -+/* Function Name: -+ * rtk_led_OutputEnable_get -+ * Description: -+ * This API get LED I/O state. -+ * Input: -+ * None. -+ * Output: -+ * pEnabled - LED I/O state -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error parameter -+ * Note: -+ * This API set current LED I/O state. -+ */ -+extern rtk_api_ret_t rtk_led_OutputEnable_get(rtk_enable_t *pState); -+ -+/* Function Name: -+ * rtk_led_serialModePortmask_set -+ * Description: -+ * This API configure Serial LED output Group and portmask -+ * Input: -+ * output - output group -+ * pPortmask - output portmask -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error parameter -+ * Note: -+ * None. -+ */ -+extern rtk_api_ret_t rtk_led_serialModePortmask_set(rtk_led_serialOutput_t output, rtk_portmask_t *pPortmask); -+ -+/* Function Name: -+ * rtk_led_serialModePortmask_get -+ * Description: -+ * This API get Serial LED output Group and portmask -+ * Input: -+ * None. -+ * Output: -+ * pOutput - output group -+ * pPortmask - output portmask -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error parameter -+ * Note: -+ * None. -+ */ -+extern rtk_api_ret_t rtk_led_serialModePortmask_get(rtk_led_serialOutput_t *pOutput, rtk_portmask_t *pPortmask); -+ -+#endif /* __RTK_API_LED_H__ */ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/mirror.h b/drivers/net/phy/rtk/rtl8367c/include/mirror.h -new file mode 100644 -index 000000000000..8d179ce2df48 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/mirror.h -@@ -0,0 +1,272 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * Purpose : RTL8367/RTL8367C switch high-level API -+ * -+ * Feature : The file includes Mirror module high-layer API definition -+ * -+ */ -+ -+#ifndef __RTK_API_MIRROR_H__ -+#define __RTK_API_MIRROR_H__ -+ -+typedef enum rtk_mirror_keep_e -+{ -+ MIRROR_FOLLOW_VLAN = 0, -+ MIRROR_KEEP_ORIGINAL, -+ MIRROR_KEEP_END -+}rtk_mirror_keep_t; -+ -+ -+/* Function Name: -+ * rtk_mirror_portBased_set -+ * Description: -+ * Set port mirror function. -+ * Input: -+ * mirroring_port - Monitor port. -+ * pMirrored_rx_portmask - Rx mirror port mask. -+ * pMirrored_tx_portmask - Tx mirror port mask. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_PORT_MASK - Invalid portmask. -+ * Note: -+ * The API is to set mirror function of source port and mirror port. -+ * The mirror port can only be set to one port and the TX and RX mirror ports -+ * should be identical. -+ */ -+extern rtk_api_ret_t rtk_mirror_portBased_set(rtk_port_t mirroring_port, rtk_portmask_t *pMirrored_rx_portmask, rtk_portmask_t *pMirrored_tx_portmask); -+ -+/* Function Name: -+ * rtk_mirror_portBased_get -+ * Description: -+ * Get port mirror function. -+ * Input: -+ * None -+ * Output: -+ * pMirroring_port - Monitor port. -+ * pMirrored_rx_portmask - Rx mirror port mask. -+ * pMirrored_tx_portmask - Tx mirror port mask. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API is to get mirror function of source port and mirror port. -+ */ -+extern rtk_api_ret_t rtk_mirror_portBased_get(rtk_port_t* pMirroring_port, rtk_portmask_t *pMirrored_rx_portmask, rtk_portmask_t *pMirrored_tx_portmask); -+ -+/* Function Name: -+ * rtk_mirror_portIso_set -+ * Description: -+ * Set mirror port isolation. -+ * Input: -+ * enable |Mirror isolation status. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_ENABLE - Invalid enable input -+ * Note: -+ * The API is to set mirror isolation function that prevent normal forwarding packets to mirror port. -+ */ -+extern rtk_api_ret_t rtk_mirror_portIso_set(rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_mirror_portIso_get -+ * Description: -+ * Get mirror port isolation. -+ * Input: -+ * None -+ * Output: -+ * pEnable |Mirror isolation status. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API is to get mirror isolation status. -+ */ -+extern rtk_api_ret_t rtk_mirror_portIso_get(rtk_enable_t *pEnable); -+ -+/* Function Name: -+ * rtk_mirror_vlanLeaky_set -+ * Description: -+ * Set mirror VLAN leaky. -+ * Input: -+ * txenable -TX leaky enable. -+ * rxenable - RX leaky enable. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_ENABLE - Invalid enable input -+ * Note: -+ * The API is to set mirror VLAN leaky function forwarding packets to mirror port. -+ */ -+extern rtk_api_ret_t rtk_mirror_vlanLeaky_set(rtk_enable_t txenable, rtk_enable_t rxenable); -+ -+ -+/* Function Name: -+ * rtk_mirror_vlanLeaky_get -+ * Description: -+ * Get mirror VLAN leaky. -+ * Input: -+ * None -+ * Output: -+ * pTxenable - TX leaky enable. -+ * pRxenable - RX leaky enable. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API is to get mirror VLAN leaky status. -+ */ -+extern rtk_api_ret_t rtk_mirror_vlanLeaky_get(rtk_enable_t *pTxenable, rtk_enable_t *pRxenable); -+ -+/* Function Name: -+ * rtk_mirror_isolationLeaky_set -+ * Description: -+ * Set mirror Isolation leaky. -+ * Input: -+ * txenable -TX leaky enable. -+ * rxenable - RX leaky enable. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_ENABLE - Invalid enable input -+ * Note: -+ * The API is to set mirror VLAN leaky function forwarding packets to mirror port. -+ */ -+extern rtk_api_ret_t rtk_mirror_isolationLeaky_set(rtk_enable_t txenable, rtk_enable_t rxenable); -+ -+/* Function Name: -+ * rtk_mirror_isolationLeaky_get -+ * Description: -+ * Get mirror isolation leaky. -+ * Input: -+ * None -+ * Output: -+ * pTxenable - TX leaky enable. -+ * pRxenable - RX leaky enable. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API is to get mirror isolation leaky status. -+ */ -+extern rtk_api_ret_t rtk_mirror_isolationLeaky_get(rtk_enable_t *pTxenable, rtk_enable_t *pRxenable); -+ -+/* Function Name: -+ * rtk_mirror_keep_set -+ * Description: -+ * Set mirror packet format keep. -+ * Input: -+ * mode - -mirror keep mode. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_ENABLE - Invalid enable input -+ * Note: -+ * The API is to set -mirror keep mode. -+ * The mirror keep mode is as following: -+ * - MIRROR_FOLLOW_VLAN -+ * - MIRROR_KEEP_ORIGINAL -+ * - MIRROR_KEEP_END -+ */ -+extern rtk_api_ret_t rtk_mirror_keep_set(rtk_mirror_keep_t mode); -+ -+ -+/* Function Name: -+ * rtk_mirror_keep_get -+ * Description: -+ * Get mirror packet format keep. -+ * Input: -+ * None -+ * Output: -+ * pMode -mirror keep mode. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API is to get mirror keep mode. -+ * The mirror keep mode is as following: -+ * - MIRROR_FOLLOW_VLAN -+ * - MIRROR_KEEP_ORIGINAL -+ * - MIRROR_KEEP_END -+ */ -+extern rtk_api_ret_t rtk_mirror_keep_get(rtk_mirror_keep_t *pMode); -+ -+/* Function Name: -+ * rtk_mirror_override_set -+ * Description: -+ * Set port mirror override function. -+ * Input: -+ * rxMirror - 1: output mirrored packet, 0: output normal forward packet -+ * txMirror - 1: output mirrored packet, 0: output normal forward packet -+ * aclMirror - 1: output mirrored packet, 0: output normal forward packet -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * The API is to set mirror override function. -+ * This function control the output format when a port output -+ * normal forward & mirrored packet at the same time. -+ */ -+extern rtk_api_ret_t rtk_mirror_override_set(rtk_enable_t rxMirror, rtk_enable_t txMirror, rtk_enable_t aclMirror); -+ -+/* Function Name: -+ * rtk_mirror_override_get -+ * Description: -+ * Get port mirror override function. -+ * Input: -+ * None -+ * Output: -+ * pRxMirror - 1: output mirrored packet, 0: output normal forward packet -+ * pTxMirror - 1: output mirrored packet, 0: output normal forward packet -+ * pAclMirror - 1: output mirrored packet, 0: output normal forward packet -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Null Pointer -+ * Note: -+ * The API is to Get mirror override function. -+ * This function control the output format when a port output -+ * normal forward & mirrored packet at the same time. -+ */ -+extern rtk_api_ret_t rtk_mirror_override_get(rtk_enable_t *pRxMirror, rtk_enable_t *pTxMirror, rtk_enable_t *pAclMirror); -+ -+#endif /* __RTK_API_MIRROR_H__ */ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/oam.h b/drivers/net/phy/rtk/rtl8367c/include/oam.h -new file mode 100644 -index 000000000000..1fc14bd62fec ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/oam.h -@@ -0,0 +1,188 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTL8367/RTL8367C switch high-level API -+ * -+ * Feature : The file includes the following modules and sub-modules -+ * (1) OAM (802.3ah) configuration -+ * -+ */ -+ -+#ifndef __RTK_OAM_H__ -+#define __RTK_OAM_H__ -+ -+/* -+ * Symbol Definition -+ */ -+ -+ -+/* -+ * Data Declaration -+ */ -+ -+ -+/* -+ * Macro Declaration -+ */ -+ -+typedef enum rtk_oam_parser_act_e -+{ -+ OAM_PARSER_ACTION_FORWARD = 0, -+ OAM_PARSER_ACTION_LOOPBACK, -+ OAM_PARSER_ACTION_DISCARD, -+ OAM_PARSER_ACTION_END, -+ -+} rtk_oam_parser_act_t; -+ -+typedef enum rtk_oam_multiplexer_act_e -+{ -+ OAM_MULTIPLEXER_ACTION_FORWARD = 0, -+ OAM_MULTIPLEXER_ACTION_DISCARD, -+ OAM_MULTIPLEXER_ACTION_CPUONLY, -+ OAM_MULTIPLEXER_ACTION_END, -+ -+} rtk_oam_multiplexer_act_t; -+ -+ -+/* -+ * Function Declaration -+ */ -+ -+/* Function Name: -+ * rtk_oam_init -+ * Description: -+ * Initialize oam module. -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * Note: -+ * Must initialize oam module before calling any oam APIs. -+ */ -+extern rtk_api_ret_t rtk_oam_init(void); -+ -+/* Function Name: -+ * rtk_oam_state_set -+ * Description: -+ * This API set OAM state. -+ * Input: -+ * enabled -OAMstate -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error parameter -+ * Note: -+ * This API set OAM state. -+ */ -+extern rtk_api_ret_t rtk_oam_state_set(rtk_enable_t enabled); -+ -+/* Function Name: -+ * rtk_oam_state_get -+ * Description: -+ * This API get OAM state. -+ * Input: -+ * None. -+ * Output: -+ * pEnabled - H/W IGMP state -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error parameter -+ * Note: -+ * This API set current OAM state. -+ */ -+extern rtk_api_ret_t rtk_oam_state_get(rtk_enable_t *pEnabled); -+ -+ -+/* Module Name : OAM */ -+ -+/* Function Name: -+ * rtk_oam_parserAction_set -+ * Description: -+ * Set OAM parser action -+ * Input: -+ * port - port id -+ * action - parser action -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_PORT_ID - invalid port id -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_oam_parserAction_set(rtk_port_t port, rtk_oam_parser_act_t action); -+ -+/* Function Name: -+ * rtk_oam_parserAction_set -+ * Description: -+ * Get OAM parser action -+ * Input: -+ * port - port id -+ * Output: -+ * pAction - parser action -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_PORT_ID - invalid port id -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_oam_parserAction_get(rtk_port_t port, rtk_oam_parser_act_t *pAction); -+ -+ -+/* Function Name: -+ * rtk_oam_multiplexerAction_set -+ * Description: -+ * Set OAM multiplexer action -+ * Input: -+ * port - port id -+ * action - parser action -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_PORT_ID - invalid port id -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_oam_multiplexerAction_set(rtk_port_t port, rtk_oam_multiplexer_act_t action); -+ -+/* Function Name: -+ * rtk_oam_multiplexerAction_set -+ * Description: -+ * Get OAM multiplexer action -+ * Input: -+ * port - port id -+ * Output: -+ * pAction - parser action -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_PORT_ID - invalid port id -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_oam_multiplexerAction_get(rtk_port_t port, rtk_oam_multiplexer_act_t *pAction); -+ -+ -+#endif /* __RTK_OAM_H__ */ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/port.h b/drivers/net/phy/rtk/rtl8367c/include/port.h -new file mode 100644 -index 000000000000..458f16bf6d97 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/port.h -@@ -0,0 +1,959 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * Purpose : RTL8367/RTL8367C switch high-level API -+ * -+ * Feature : The file includes port module high-layer API definition -+ * -+ */ -+ -+#ifndef __RTK_API_PORT_H__ -+#define __RTK_API_PORT_H__ -+ -+/* -+ * Data Type Declaration -+ */ -+ -+#define PHY_CONTROL_REG 0 -+#define PHY_STATUS_REG 1 -+#define PHY_AN_ADVERTISEMENT_REG 4 -+#define PHY_AN_LINKPARTNER_REG 5 -+#define PHY_1000_BASET_CONTROL_REG 9 -+#define PHY_1000_BASET_STATUS_REG 10 -+#define PHY_RESOLVED_REG 26 -+ -+#define RTK_EFID_MAX 0x7 -+ -+#define RTK_FIBER_FORCE_1000M 3 -+#define RTK_FIBER_FORCE_100M 5 -+#define RTK_FIBER_FORCE_100M1000M 7 -+ -+#define RTK_INDRECT_ACCESS_CRTL 0x1f00 -+#define RTK_INDRECT_ACCESS_STATUS 0x1f01 -+#define RTK_INDRECT_ACCESS_ADDRESS 0x1f02 -+#define RTK_INDRECT_ACCESS_WRITE_DATA 0x1f03 -+#define RTK_INDRECT_ACCESS_READ_DATA 0x1f04 -+#define RTK_INDRECT_ACCESS_DELAY 0x1f80 -+#define RTK_INDRECT_ACCESS_BURST 0x1f81 -+#define RTK_RW_MASK 0x2 -+#define RTK_CMD_MASK 0x1 -+#define RTK_PHY_BUSY_OFFSET 2 -+ -+ -+typedef enum rtk_mode_ext_e -+{ -+ MODE_EXT_DISABLE = 0, -+ MODE_EXT_RGMII, -+ MODE_EXT_MII_MAC, -+ MODE_EXT_MII_PHY, -+ MODE_EXT_TMII_MAC, -+ MODE_EXT_TMII_PHY, -+ MODE_EXT_GMII, -+ MODE_EXT_RMII_MAC, -+ MODE_EXT_RMII_PHY, -+ MODE_EXT_SGMII, -+ MODE_EXT_HSGMII, -+ MODE_EXT_1000X_100FX, -+ MODE_EXT_1000X, -+ MODE_EXT_100FX, -+ MODE_EXT_RGMII_2, -+ MODE_EXT_MII_MAC_2, -+ MODE_EXT_MII_PHY_2, -+ MODE_EXT_TMII_MAC_2, -+ MODE_EXT_TMII_PHY_2, -+ MODE_EXT_RMII_MAC_2, -+ MODE_EXT_RMII_PHY_2, -+ MODE_EXT_END -+} rtk_mode_ext_t; -+ -+typedef enum rtk_port_duplex_e -+{ -+ PORT_HALF_DUPLEX = 0, -+ PORT_FULL_DUPLEX, -+ PORT_DUPLEX_END -+} rtk_port_duplex_t; -+ -+typedef enum rtk_port_linkStatus_e -+{ -+ PORT_LINKDOWN = 0, -+ PORT_LINKUP, -+ PORT_LINKSTATUS_END -+} rtk_port_linkStatus_t; -+ -+typedef struct rtk_port_mac_ability_s -+{ -+ rtk_uint32 forcemode; -+ rtk_uint32 speed; -+ rtk_uint32 duplex; -+ rtk_uint32 link; -+ rtk_uint32 nway; -+ rtk_uint32 txpause; -+ rtk_uint32 rxpause; -+}rtk_port_mac_ability_t; -+ -+typedef struct rtk_port_phy_ability_s -+{ -+ rtk_uint32 AutoNegotiation; /*PHY register 0.12 setting for auto-negotiation process*/ -+ rtk_uint32 Half_10; /*PHY register 4.5 setting for 10BASE-TX half duplex capable*/ -+ rtk_uint32 Full_10; /*PHY register 4.6 setting for 10BASE-TX full duplex capable*/ -+ rtk_uint32 Half_100; /*PHY register 4.7 setting for 100BASE-TX half duplex capable*/ -+ rtk_uint32 Full_100; /*PHY register 4.8 setting for 100BASE-TX full duplex capable*/ -+ rtk_uint32 Full_1000; /*PHY register 9.9 setting for 1000BASE-T full duplex capable*/ -+ rtk_uint32 FC; /*PHY register 4.10 setting for flow control capability*/ -+ rtk_uint32 AsyFC; /*PHY register 4.11 setting for asymmetric flow control capability*/ -+} rtk_port_phy_ability_t; -+ -+typedef rtk_uint32 rtk_port_phy_data_t; /* phy page */ -+ -+typedef enum rtk_port_phy_mdix_mode_e -+{ -+ PHY_AUTO_CROSSOVER_MODE= 0, -+ PHY_FORCE_MDI_MODE, -+ PHY_FORCE_MDIX_MODE, -+ PHY_FORCE_MODE_END -+} rtk_port_phy_mdix_mode_t; -+ -+typedef enum rtk_port_phy_mdix_status_e -+{ -+ PHY_STATUS_AUTO_MDI_MODE= 0, -+ PHY_STATUS_AUTO_MDIX_MODE, -+ PHY_STATUS_FORCE_MDI_MODE, -+ PHY_STATUS_FORCE_MDIX_MODE, -+ PHY_STATUS_FORCE_MODE_END -+} rtk_port_phy_mdix_status_t; -+ -+typedef rtk_uint32 rtk_port_phy_page_t; /* phy page */ -+ -+typedef enum rtk_port_phy_reg_e -+{ -+ PHY_REG_CONTROL = 0, -+ PHY_REG_STATUS, -+ PHY_REG_IDENTIFIER_1, -+ PHY_REG_IDENTIFIER_2, -+ PHY_REG_AN_ADVERTISEMENT, -+ PHY_REG_AN_LINKPARTNER, -+ PHY_REG_1000_BASET_CONTROL = 9, -+ PHY_REG_1000_BASET_STATUS, -+ PHY_REG_END = 32 -+} rtk_port_phy_reg_t; -+ -+typedef enum rtk_port_phy_test_mode_e -+{ -+ PHY_TEST_MODE_NORMAL= 0, -+ PHY_TEST_MODE_1, -+ PHY_TEST_MODE_2, -+ PHY_TEST_MODE_3, -+ PHY_TEST_MODE_4, -+ PHY_TEST_MODE_END -+} rtk_port_phy_test_mode_t; -+ -+typedef enum rtk_port_speed_e -+{ -+ PORT_SPEED_10M = 0, -+ PORT_SPEED_100M, -+ PORT_SPEED_1000M, -+ PORT_SPEED_500M, -+ PORT_SPEED_2500M, -+ PORT_SPEED_END -+} rtk_port_speed_t; -+ -+typedef enum rtk_port_media_e -+{ -+ PORT_MEDIA_COPPER = 0, -+ PORT_MEDIA_FIBER, -+ PORT_MEDIA_END -+}rtk_port_media_t; -+ -+typedef struct rtk_rtctResult_s -+{ -+ rtk_port_speed_t linkType; -+ union -+ { -+ struct fe_result_s -+ { -+ rtk_uint32 isRxShort; -+ rtk_uint32 isTxShort; -+ rtk_uint32 isRxOpen; -+ rtk_uint32 isTxOpen; -+ rtk_uint32 isRxMismatch; -+ rtk_uint32 isTxMismatch; -+ rtk_uint32 isRxLinedriver; -+ rtk_uint32 isTxLinedriver; -+ rtk_uint32 rxLen; -+ rtk_uint32 txLen; -+ } fe_result; -+ -+ struct ge_result_s -+ { -+ rtk_uint32 channelAShort; -+ rtk_uint32 channelBShort; -+ rtk_uint32 channelCShort; -+ rtk_uint32 channelDShort; -+ -+ rtk_uint32 channelAOpen; -+ rtk_uint32 channelBOpen; -+ rtk_uint32 channelCOpen; -+ rtk_uint32 channelDOpen; -+ -+ rtk_uint32 channelAMismatch; -+ rtk_uint32 channelBMismatch; -+ rtk_uint32 channelCMismatch; -+ rtk_uint32 channelDMismatch; -+ -+ rtk_uint32 channelALinedriver; -+ rtk_uint32 channelBLinedriver; -+ rtk_uint32 channelCLinedriver; -+ rtk_uint32 channelDLinedriver; -+ -+ rtk_uint32 channelALen; -+ rtk_uint32 channelBLen; -+ rtk_uint32 channelCLen; -+ rtk_uint32 channelDLen; -+ } ge_result; -+ }result; -+} rtk_rtctResult_t; -+ -+/* Function Name: -+ * rtk_port_phyAutoNegoAbility_set -+ * Description: -+ * Set Ethernet PHY auto-negotiation desired ability. -+ * Input: -+ * port - port id. -+ * pAbility - Ability structure -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_PHY_REG_ID - Invalid PHY address -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy -+ * Note: -+ * If Full_1000 bit is set to 1, the AutoNegotiation will be automatic set to 1. While both AutoNegotiation and Full_1000 are set to 0, the PHY speed and duplex selection will -+ * be set as following 100F > 100H > 10F > 10H priority sequence. -+ */ -+extern rtk_api_ret_t rtk_port_phyAutoNegoAbility_set(rtk_port_t port, rtk_port_phy_ability_t *pAbility); -+ -+/* Function Name: -+ * rtk_port_phyAutoNegoAbility_get -+ * Description: -+ * Get PHY ability through PHY registers. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pAbility - Ability structure -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_PHY_REG_ID - Invalid PHY address -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy -+ * Note: -+ * Get the capability of specified PHY. -+ */ -+extern rtk_api_ret_t rtk_port_phyAutoNegoAbility_get(rtk_port_t port, rtk_port_phy_ability_t *pAbility); -+ -+/* Function Name: -+ * rtk_port_phyForceModeAbility_set -+ * Description: -+ * Set the port speed/duplex mode/pause/asy_pause in the PHY force mode. -+ * Input: -+ * port - port id. -+ * pAbility - Ability structure -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_PHY_REG_ID - Invalid PHY address -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy -+ * Note: -+ * While both AutoNegotiation and Full_1000 are set to 0, the PHY speed and duplex selection will -+ * be set as following 100F > 100H > 10F > 10H priority sequence. -+ */ -+extern rtk_api_ret_t rtk_port_phyForceModeAbility_set(rtk_port_t port, rtk_port_phy_ability_t *pAbility); -+ -+/* Function Name: -+ * rtk_port_phyForceModeAbility_get -+ * Description: -+ * Get PHY ability through PHY registers. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pAbility - Ability structure -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_PHY_REG_ID - Invalid PHY address -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy -+ * Note: -+ * Get the capability of specified PHY. -+ */ -+extern rtk_api_ret_t rtk_port_phyForceModeAbility_get(rtk_port_t port, rtk_port_phy_ability_t *pAbility); -+ -+/* Function Name: -+ * rtk_port_phyStatus_get -+ * Description: -+ * Get Ethernet PHY linking status -+ * Input: -+ * port - Port id. -+ * Output: -+ * linkStatus - PHY link status -+ * speed - PHY link speed -+ * duplex - PHY duplex mode -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_PHY_REG_ID - Invalid PHY address -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy -+ * Note: -+ * API will return auto negotiation status of phy. -+ */ -+extern rtk_api_ret_t rtk_port_phyStatus_get(rtk_port_t port, rtk_port_linkStatus_t *pLinkStatus, rtk_port_speed_t *pSpeed, rtk_port_duplex_t *pDuplex); -+ -+/* Function Name: -+ * rtk_port_macForceLink_set -+ * Description: -+ * Set port force linking configuration. -+ * Input: -+ * port - port id. -+ * pPortability - port ability configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * This API can set Port/MAC force mode properties. -+ */ -+extern rtk_api_ret_t rtk_port_macForceLink_set(rtk_port_t port, rtk_port_mac_ability_t *pPortability); -+ -+/* Function Name: -+ * rtk_port_macForceLink_get -+ * Description: -+ * Get port force linking configuration. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pPortability - port ability configuration -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can get Port/MAC force mode properties. -+ */ -+extern rtk_api_ret_t rtk_port_macForceLink_get(rtk_port_t port, rtk_port_mac_ability_t *pPortability); -+ -+/* Function Name: -+ * rtk_port_macForceLinkExt_set -+ * Description: -+ * Set external interface force linking configuration. -+ * Input: -+ * port - external port ID -+ * mode - external interface mode -+ * pPortability - port ability configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can set external interface force mode properties. -+ * The external interface can be set to: -+ * - MODE_EXT_DISABLE, -+ * - MODE_EXT_RGMII, -+ * - MODE_EXT_MII_MAC, -+ * - MODE_EXT_MII_PHY, -+ * - MODE_EXT_TMII_MAC, -+ * - MODE_EXT_TMII_PHY, -+ * - MODE_EXT_GMII, -+ * - MODE_EXT_RMII_MAC, -+ * - MODE_EXT_RMII_PHY, -+ * - MODE_EXT_SGMII, -+ * - MODE_EXT_HSGMII, -+ * - MODE_EXT_1000X_100FX, -+ * - MODE_EXT_1000X, -+ * - MODE_EXT_100FX, -+ */ -+extern rtk_api_ret_t rtk_port_macForceLinkExt_set(rtk_port_t port, rtk_mode_ext_t mode, rtk_port_mac_ability_t *pPortability); -+ -+/* Function Name: -+ * rtk_port_macForceLinkExt_get -+ * Description: -+ * Set external interface force linking configuration. -+ * Input: -+ * port - external port ID -+ * Output: -+ * pMode - external interface mode -+ * pPortability - port ability configuration -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can get external interface force mode properties. -+ */ -+extern rtk_api_ret_t rtk_port_macForceLinkExt_get(rtk_port_t port, rtk_mode_ext_t *pMode, rtk_port_mac_ability_t *pPortability); -+ -+/* Function Name: -+ * rtk_port_macStatus_get -+ * Description: -+ * Get port link status. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pPortstatus - port ability configuration -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * This API can get Port/PHY properties. -+ */ -+extern rtk_api_ret_t rtk_port_macStatus_get(rtk_port_t port, rtk_port_mac_ability_t *pPortstatus); -+ -+/* Function Name: -+ * rtk_port_macLocalLoopbackEnable_set -+ * Description: -+ * Set Port Local Loopback. (Redirect TX to RX.) -+ * Input: -+ * port - Port id. -+ * enable - Loopback state, 0:disable, 1:enable -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * This API can enable/disable Local loopback in MAC. -+ * For UTP port, This API will also enable the digital -+ * loopback bit in PHY register for sync of speed between -+ * PHY and MAC. For EXT port, users need to force the -+ * link state by themselves. -+ */ -+extern rtk_api_ret_t rtk_port_macLocalLoopbackEnable_set(rtk_port_t port, rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_port_macLocalLoopbackEnable_get -+ * Description: -+ * Get Port Local Loopback. (Redirect TX to RX.) -+ * Input: -+ * port - Port id. -+ * Output: -+ * pEnable - Loopback state, 0:disable, 1:enable -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * None. -+ */ -+extern rtk_api_ret_t rtk_port_macLocalLoopbackEnable_get(rtk_port_t port, rtk_enable_t *pEnable); -+ -+/* Function Name: -+ * rtk_port_phyReg_set -+ * Description: -+ * Set PHY register data of the specific port. -+ * Input: -+ * port - port id. -+ * reg - Register id -+ * regData - Register data -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_PHY_REG_ID - Invalid PHY address -+ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy -+ * Note: -+ * This API can set PHY register data of the specific port. -+ */ -+extern rtk_api_ret_t rtk_port_phyReg_set(rtk_port_t port, rtk_port_phy_reg_t reg, rtk_port_phy_data_t value); -+ -+/* Function Name: -+ * rtk_port_phyReg_get -+ * Description: -+ * Get PHY register data of the specific port. -+ * Input: -+ * port - Port id. -+ * reg - Register id -+ * Output: -+ * pData - Register data -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_PHY_REG_ID - Invalid PHY address -+ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy -+ * Note: -+ * This API can get PHY register data of the specific port. -+ */ -+extern rtk_api_ret_t rtk_port_phyReg_get(rtk_port_t port, rtk_port_phy_reg_t reg, rtk_port_phy_data_t *pData); -+ -+/* Function Name: -+ * rtk_port_backpressureEnable_set -+ * Description: -+ * Set the half duplex back-pressure enable status of the specific port. -+ * Input: -+ * port - port id. -+ * enable - Back pressure status. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_ENABLE - Invalid enable input. -+ * Note: -+ * This API can set the half duplex back-pressure enable status of the specific port. -+ * The half duplex back-pressure enable status of the port is as following: -+ * - DISABLE -+ * - ENABLE -+ */ -+extern rtk_api_ret_t rtk_port_backpressureEnable_set(rtk_port_t port, rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_port_backpressureEnable_get -+ * Description: -+ * Get the half duplex back-pressure enable status of the specific port. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pEnable - Back pressure status. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * This API can get the half duplex back-pressure enable status of the specific port. -+ * The half duplex back-pressure enable status of the port is as following: -+ * - DISABLE -+ * - ENABLE -+ */ -+extern rtk_api_ret_t rtk_port_backpressureEnable_get(rtk_port_t port, rtk_enable_t *pEnable); -+ -+/* Function Name: -+ * rtk_port_adminEnable_set -+ * Description: -+ * Set port admin configuration of the specific port. -+ * Input: -+ * port - port id. -+ * enable - Back pressure status. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_ENABLE - Invalid enable input. -+ * Note: -+ * This API can set port admin configuration of the specific port. -+ * The port admin configuration of the port is as following: -+ * - DISABLE -+ * - ENABLE -+ */ -+extern rtk_api_ret_t rtk_port_adminEnable_set(rtk_port_t port, rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_port_adminEnable_get -+ * Description: -+ * Get port admin configuration of the specific port. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pEnable - Back pressure status. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * This API can get port admin configuration of the specific port. -+ * The port admin configuration of the port is as following: -+ * - DISABLE -+ * - ENABLE -+ */ -+extern rtk_api_ret_t rtk_port_adminEnable_get(rtk_port_t port, rtk_enable_t *pEnable); -+ -+/* Function Name: -+ * rtk_port_isolation_set -+ * Description: -+ * Set permitted port isolation portmask -+ * Input: -+ * port - port id. -+ * pPortmask - Permit port mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_PORT_MASK - Invalid portmask. -+ * Note: -+ * This API set the port mask that a port can transmit packet to of each port -+ * A port can only transmit packet to ports included in permitted portmask -+ */ -+extern rtk_api_ret_t rtk_port_isolation_set(rtk_port_t port, rtk_portmask_t *pPortmask); -+ -+/* Function Name: -+ * rtk_port_isolation_get -+ * Description: -+ * Get permitted port isolation portmask -+ * Input: -+ * port - Port id. -+ * Output: -+ * pPortmask - Permit port mask -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * This API get the port mask that a port can transmit packet to of each port -+ * A port can only transmit packet to ports included in permitted portmask -+ */ -+extern rtk_api_ret_t rtk_port_isolation_get(rtk_port_t port, rtk_portmask_t *pPortmask); -+ -+/* Function Name: -+ * rtk_port_rgmiiDelayExt_set -+ * Description: -+ * Set RGMII interface delay value for TX and RX. -+ * Input: -+ * txDelay - TX delay value, 1 for delay 2ns and 0 for no-delay -+ * rxDelay - RX delay value, 0~7 for delay setup. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can set external interface 2 RGMII delay. -+ * In TX delay, there are 2 selection: no-delay and 2ns delay. -+ * In RX delay, there are 8 steps for delay tuning. 0 for no-delay, and 7 for maximum delay. -+ */ -+extern rtk_api_ret_t rtk_port_rgmiiDelayExt_set(rtk_port_t port, rtk_data_t txDelay, rtk_data_t rxDelay); -+ -+/* Function Name: -+ * rtk_port_rgmiiDelayExt_get -+ * Description: -+ * Get RGMII interface delay value for TX and RX. -+ * Input: -+ * None -+ * Output: -+ * pTxDelay - TX delay value -+ * pRxDelay - RX delay value -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can set external interface 2 RGMII delay. -+ * In TX delay, there are 2 selection: no-delay and 2ns delay. -+ * In RX delay, there are 8 steps for delay tuning. 0 for n0-delay, and 7 for maximum delay. -+ */ -+extern rtk_api_ret_t rtk_port_rgmiiDelayExt_get(rtk_port_t port, rtk_data_t *pTxDelay, rtk_data_t *pRxDelay); -+ -+/* Function Name: -+ * rtk_port_phyEnableAll_set -+ * Description: -+ * Set all PHY enable status. -+ * Input: -+ * enable - PHY Enable State. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_ENABLE - Invalid enable input. -+ * Note: -+ * This API can set all PHY status. -+ * The configuration of all PHY is as following: -+ * - DISABLE -+ * - ENABLE -+ */ -+extern rtk_api_ret_t rtk_port_phyEnableAll_set(rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_port_phyEnableAll_get -+ * Description: -+ * Get all PHY enable status. -+ * Input: -+ * None -+ * Output: -+ * pEnable - PHY Enable State. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * This API can set all PHY status. -+ * The configuration of all PHY is as following: -+ * - DISABLE -+ * - ENABLE -+ */ -+extern rtk_api_ret_t rtk_port_phyEnableAll_get(rtk_enable_t *pEnable); -+ -+/* Function Name: -+ * rtk_port_efid_set -+ * Description: -+ * Set port-based enhanced filtering database -+ * Input: -+ * port - Port id. -+ * efid - Specified enhanced filtering database. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_L2_FID - Invalid fid. -+ * RT_ERR_INPUT - Invalid input parameter. -+ * RT_ERR_PORT_ID - Invalid port ID. -+ * Note: -+ * The API can set port-based enhanced filtering database. -+ */ -+extern rtk_api_ret_t rtk_port_efid_set(rtk_port_t port, rtk_data_t efid); -+ -+/* Function Name: -+ * rtk_port_efid_get -+ * Description: -+ * Get port-based enhanced filtering database -+ * Input: -+ * port - Port id. -+ * Output: -+ * pEfid - Specified enhanced filtering database. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port ID. -+ * Note: -+ * The API can get port-based enhanced filtering database status. -+ */ -+extern rtk_api_ret_t rtk_port_efid_get(rtk_port_t port, rtk_data_t *pEfid); -+ -+/* Function Name: -+ * rtk_port_phyComboPortMedia_set -+ * Description: -+ * Set Combo port media type -+ * Input: -+ * port - Port id. (Should be Port 4) -+ * media - Media (COPPER or FIBER) -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port ID. -+ * Note: -+ * The API can Set Combo port media type. -+ */ -+extern rtk_api_ret_t rtk_port_phyComboPortMedia_set(rtk_port_t port, rtk_port_media_t media); -+ -+/* Function Name: -+ * rtk_port_phyComboPortMedia_get -+ * Description: -+ * Get Combo port media type -+ * Input: -+ * port - Port id. (Should be Port 4) -+ * Output: -+ * pMedia - Media (COPPER or FIBER) -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port ID. -+ * Note: -+ * The API can Set Combo port media type. -+ */ -+extern rtk_api_ret_t rtk_port_phyComboPortMedia_get(rtk_port_t port, rtk_port_media_t *pMedia); -+ -+/* Function Name: -+ * rtk_port_rtctEnable_set -+ * Description: -+ * Enable RTCT test -+ * Input: -+ * pPortmask - Port mask of RTCT enabled port -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Invalid port mask. -+ * Note: -+ * The API can enable RTCT Test -+ */ -+extern rtk_api_ret_t rtk_port_rtctEnable_set(rtk_portmask_t *pPortmask); -+ -+/* Function Name: -+ * rtk_port_rtctDisable_set -+ * Description: -+ * Disable RTCT test -+ * Input: -+ * pPortmask - Port mask of RTCT disabled port -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Invalid port mask. -+ * Note: -+ * The API can disable RTCT Test -+ */ -+rtk_api_ret_t rtk_port_rtctDisable_set(rtk_portmask_t *pPortmask); -+ -+ -+/* Function Name: -+ * rtk_port_rtctResult_get -+ * Description: -+ * Get the result of RTCT test -+ * Input: -+ * port - Port ID -+ * Output: -+ * pRtctResult - The result of RTCT result -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port ID. -+ * RT_ERR_PHY_RTCT_NOT_FINISH - Testing does not finish. -+ * Note: -+ * The API can get RTCT test result. -+ * RTCT test may takes 4.8 seconds to finish its test at most. -+ * Thus, if this API return RT_ERR_PHY_RTCT_NOT_FINISH or -+ * other error code, the result can not be referenced and -+ * user should call this API again until this API returns -+ * a RT_ERR_OK. -+ * The result is stored at pRtctResult->ge_result -+ * pRtctResult->linkType is unused. -+ * The unit of channel length is 2.5cm. Ex. 300 means 300 * 2.5 = 750cm = 7.5M -+ */ -+extern rtk_api_ret_t rtk_port_rtctResult_get(rtk_port_t port, rtk_rtctResult_t *pRtctResult); -+ -+/* Function Name: -+ * rtk_port_sds_reset -+ * Description: -+ * Reset Serdes -+ * Input: -+ * port - Port ID -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port ID. -+ * Note: -+ * The API can reset Serdes -+ */ -+extern rtk_api_ret_t rtk_port_sds_reset(rtk_port_t port); -+ -+/* Function Name: -+ * rtk_port_sgmiiLinkStatus_get -+ * Description: -+ * Get SGMII status -+ * Input: -+ * port - Port ID -+ * Output: -+ * pSignalDetect - Signal detect -+ * pSync - Sync -+ * pLink - Link -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port ID. -+ * Note: -+ * The API can reset Serdes -+ */ -+extern rtk_api_ret_t rtk_port_sgmiiLinkStatus_get(rtk_port_t port, rtk_data_t *pSignalDetect, rtk_data_t *pSync, rtk_port_linkStatus_t *pLink); -+ -+/* Function Name: -+ * rtk_port_sgmiiNway_set -+ * Description: -+ * Configure SGMII/HSGMII port Nway state -+ * Input: -+ * port - Port ID -+ * state - Nway state -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port ID. -+ * Note: -+ * The API configure SGMII/HSGMII port Nway state -+ */ -+extern rtk_api_ret_t rtk_port_sgmiiNway_set(rtk_port_t port, rtk_enable_t state); -+ -+/* Function Name: -+ * rtk_port_sgmiiNway_get -+ * Description: -+ * Get SGMII/HSGMII port Nway state -+ * Input: -+ * port - Port ID -+ * Output: -+ * pState - Nway state -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port ID. -+ * Note: -+ * The API can get SGMII/HSGMII port Nway state -+ */ -+extern rtk_api_ret_t rtk_port_sgmiiNway_get(rtk_port_t port, rtk_enable_t *pState); -+ -+#endif /* __RTK_API_PORT_H__ */ -+ -+ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/ptp.h b/drivers/net/phy/rtk/rtl8367c/include/ptp.h -new file mode 100644 -index 000000000000..d18c4a01ed43 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/ptp.h -@@ -0,0 +1,511 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * Purpose : RTL8367/RTL8367C switch high-level API -+ * -+ * Feature : The file includes time module high-layer API definition -+ * -+ */ -+ -+#ifndef __RTK_API_PTP_H__ -+#define __RTK_API_PTP_H__ -+ -+/* -+ * Symbol Definition -+ */ -+#define RTK_MAX_NUM_OF_NANO_SECOND 0x3B9AC9FF -+#define RTK_PTP_INTR_MASK 0xFF -+#define RTK_MAX_NUM_OF_TPID 0xFFFF -+ -+/* Message Type */ -+typedef enum rtk_ptp_msgType_e -+{ -+ PTP_MSG_TYPE_TX_SYNC = 0, -+ PTP_MSG_TYPE_TX_DELAY_REQ, -+ PTP_MSG_TYPE_TX_PDELAY_REQ, -+ PTP_MSG_TYPE_TX_PDELAY_RESP, -+ PTP_MSG_TYPE_RX_SYNC, -+ PTP_MSG_TYPE_RX_DELAY_REQ, -+ PTP_MSG_TYPE_RX_PDELAY_REQ, -+ PTP_MSG_TYPE_RX_PDELAY_RESP, -+ PTP_MSG_TYPE_END -+} rtk_ptp_msgType_t; -+ -+typedef enum rtk_ptp_intType_e -+{ -+ PTP_INT_TYPE_TX_SYNC = 0, -+ PTP_INT_TYPE_TX_DELAY_REQ, -+ PTP_INT_TYPE_TX_PDELAY_REQ, -+ PTP_INT_TYPE_TX_PDELAY_RESP, -+ PTP_INT_TYPE_RX_SYNC, -+ PTP_INT_TYPE_RX_DELAY_REQ, -+ PTP_INT_TYPE_RX_PDELAY_REQ, -+ PTP_INT_TYPE_RX_PDELAY_RESP, -+ PTP_INT_TYPE_ALL, -+ PTP_INT_TYPE_END -+}rtk_ptp_intType_t; -+ -+typedef enum rtk_ptp_sys_adjust_e -+{ -+ SYS_ADJUST_PLUS = 0, -+ SYS_ADJUST_MINUS, -+ SYS_ADJUST_END -+} rtk_ptp_sys_adjust_t; -+ -+ -+/* Reference Time */ -+typedef struct rtk_ptp_timeStamp_s -+{ -+ rtk_uint32 sec; -+ rtk_uint32 nsec; -+} rtk_ptp_timeStamp_t; -+ -+typedef struct rtk_ptp_info_s -+{ -+ rtk_uint32 sequenceId; -+ rtk_ptp_timeStamp_t timeStamp; -+} rtk_ptp_info_t; -+ -+typedef rtk_uint32 rtk_ptp_tpid_t; -+ -+typedef rtk_uint32 rtk_ptp_intStatus_t; /* interrupt status mask */ -+ -+/* -+ * Data Declaration -+ */ -+ -+/* -+ * Function Declaration -+ */ -+/* Function Name: -+ * rtk_time_init -+ * Description: -+ * PTP function initialization. -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * This API is used to initialize EEE status. -+ */ -+extern rtk_api_ret_t rtk_ptp_init(void); -+ -+/* Function Name: -+ * rtk_ptp_mac_set -+ * Description: -+ * Configure PTP mac address. -+ * Input: -+ * mac - mac address to parser PTP packets. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter. -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_ptp_mac_set(rtk_mac_t mac); -+ -+/* Function Name: -+ * rtk_ptp_mac_get -+ * Description: -+ * Get PTP mac address. -+ * Input: -+ * None -+ * Output: -+ * pMac - mac address to parser PTP packets. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter. -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_ptp_mac_get(rtk_mac_t *pMac); -+ -+/* Function Name: -+ * rtk_ptp_tpid_set -+ * Description: -+ * Configure PTP accepted outer & inner tag TPID. -+ * Input: -+ * outerId - Ether type of S-tag frame parsing in PTP ports. -+ * innerId - Ether type of C-tag frame parsing in PTP ports. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter. -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_ptp_tpid_set(rtk_ptp_tpid_t outerId, rtk_ptp_tpid_t innerId); -+ -+/* Function Name: -+ * rtk_ptp_tpid_get -+ * Description: -+ * Get PTP accepted outer & inner tag TPID. -+ * Input: -+ * None -+ * Output: -+ * pOuterId - Ether type of S-tag frame parsing in PTP ports. -+ * pInnerId - Ether type of C-tag frame parsing in PTP ports. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_ptp_tpid_get(rtk_ptp_tpid_t *pOuterId, rtk_ptp_tpid_t *pInnerId); -+ -+/* Function Name: -+ * rtk_ptp_refTime_set -+ * Description: -+ * Set the reference time of the specified device. -+ * Input: -+ * timeStamp - reference timestamp value -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_INPUT - invalid input parameter -+ * Applicable: -+ * 8390, 8380 -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_ptp_refTime_set(rtk_ptp_timeStamp_t timeStamp); -+ -+/* Function Name: -+ * rtk_ptp_refTime_get -+ * Description: -+ * Get the reference time of the specified device. -+ * Input: -+ * Output: -+ * pTimeStamp - pointer buffer of the reference time -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_UNIT_ID - invalid unit id -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ * Applicable: -+ * 8390, 8380 -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_ptp_refTime_get(rtk_ptp_timeStamp_t *pTimeStamp); -+ -+/* Function Name: -+ * rtk_ptp_refTimeAdjust_set -+ * Description: -+ * Adjust the reference time. -+ * Input: -+ * unit - unit id -+ * sign - significant -+ * timeStamp - reference timestamp value -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_UNIT_ID - invalid unit id -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_INPUT - invalid input parameter -+ * Note: -+ * sign=0 for positive adjustment, sign=1 for negative adjustment. -+ */ -+extern rtk_api_ret_t rtk_ptp_refTimeAdjust_set(rtk_ptp_sys_adjust_t sign, rtk_ptp_timeStamp_t timeStamp); -+ -+/* Function Name: -+ * rtk_ptp_refTimeEnable_set -+ * Description: -+ * Set the enable state of reference time of the specified device. -+ * Input: -+ * enable - status -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_INPUT - invalid input parameter -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_ptp_refTimeEnable_set(rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_ptp_refTimeEnable_get -+ * Description: -+ * Get the enable state of reference time of the specified device. -+ * Input: -+ * Output: -+ * pEnable - status -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_UNIT_ID - invalid unit id -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ * Applicable: -+ * 8390, 8380 -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_ptp_refTimeEnable_get(rtk_enable_t *pEnable); -+ -+/* Function Name: -+ * rtk_ptp_portEnable_set -+ * Description: -+ * Set PTP status of the specified port. -+ * Input: -+ * port - port id -+ * enable - status -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_PORT - invalid port id -+ * RT_ERR_INPUT - invalid input parameter -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_ptp_portEnable_set(rtk_port_t port, rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_ptp_portEnable_get -+ * Description: -+ * Get PTP status of the specified port. -+ * Input: -+ * port - port id -+ * Output: -+ * pEnable - status -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_PORT - invalid port id -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_ptp_portEnable_get(rtk_port_t port, rtk_enable_t *pEnable); -+ -+/* Function Name: -+ * rtk_ptp_portTimestamp_get -+ * Description: -+ * Get PTP timestamp according to the PTP identifier on the dedicated port from the specified device. -+ * Input: -+ * unit - unit id -+ * port - port id -+ * type - PTP message type -+ * Output: -+ * pInfo - pointer buffer of sequence ID and timestamp -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_PORT_ID - invalid port id -+ * RT_ERR_INPUT - invalid input parameter -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ * Applicable: -+ * 8390, 8380 -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_ptp_portTimestamp_get( rtk_port_t port, rtk_ptp_msgType_t type, rtk_ptp_info_t *pInfo); -+ -+/* Function Name: -+ * rtk_ptp_intControl_set -+ * Description: -+ * Set PTP interrupt trigger status configuration. -+ * Input: -+ * type - Interrupt type. -+ * enable - Interrupt status. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_ENABLE - Invalid enable input. -+ * Note: -+ * The API can set PTP interrupt status configuration. -+ * The interrupt trigger status is shown in the following: -+ * PTP_INT_TYPE_TX_SYNC = 0, -+ * PTP_INT_TYPE_TX_DELAY_REQ, -+ * PTP_INT_TYPE_TX_PDELAY_REQ, -+ * PTP_INT_TYPE_TX_PDELAY_RESP, -+ * PTP_INT_TYPE_RX_SYNC, -+ * PTP_INT_TYPE_RX_DELAY_REQ, -+ * PTP_INT_TYPE_RX_PDELAY_REQ, -+ * PTP_INT_TYPE_RX_PDELAY_RESP, -+ * PTP_INT_TYPE_ALL, -+ */ -+extern rtk_api_ret_t rtk_ptp_intControl_set(rtk_ptp_intType_t type, rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_ptp_intControl_get -+ * Description: -+ * Get PTP interrupt trigger status configuration. -+ * Input: -+ * type - Interrupt type. -+ * Output: -+ * pEnable - Interrupt status. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can get interrupt status configuration. -+ * The interrupt trigger status is shown in the following: -+ * PTP_INT_TYPE_TX_SYNC = 0, -+ * PTP_INT_TYPE_TX_DELAY_REQ, -+ * PTP_INT_TYPE_TX_PDELAY_REQ, -+ * PTP_INT_TYPE_TX_PDELAY_RESP, -+ * PTP_INT_TYPE_RX_SYNC, -+ * PTP_INT_TYPE_RX_DELAY_REQ, -+ * PTP_INT_TYPE_RX_PDELAY_REQ, -+ * PTP_INT_TYPE_RX_PDELAY_RESP, -+ */ -+extern rtk_api_ret_t rtk_ptp_intControl_get(rtk_ptp_intType_t type, rtk_enable_t *pEnable); -+ -+ -+/* Function Name: -+ * rtk_ptp_intStatus_get -+ * Description: -+ * Get PTP port interrupt trigger status. -+ * Input: -+ * port - physical port -+ * Output: -+ * pStatusMask - Interrupt status bit mask. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can get interrupt trigger status when interrupt happened. -+ * The interrupt trigger status is shown in the following: -+ * - PORT 0 INT (value[0] (Bit0)) -+ * - PORT 1 INT (value[0] (Bit1)) -+ * - PORT 2 INT (value[0] (Bit2)) -+ * - PORT 3 INT (value[0] (Bit3)) -+ * - PORT 4 INT (value[0] (Bit4)) -+ -+ * -+ */ -+extern rtk_api_ret_t rtk_ptp_intStatus_get(rtk_ptp_intStatus_t *pStatusMask); -+ -+/* Function Name: -+ * rtk_ptp_portIntStatus_set -+ * Description: -+ * Set PTP port interrupt trigger status to clean. -+ * Input: -+ * port - physical port -+ * statusMask - Interrupt status bit mask. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can clean interrupt trigger status when interrupt happened. -+ * The interrupt trigger status is shown in the following: -+ * - PTP_INT_TYPE_TX_SYNC (value[0] (Bit0)) -+ * - PTP_INT_TYPE_TX_DELAY_REQ (value[0] (Bit1)) -+ * - PTP_INT_TYPE_TX_PDELAY_REQ (value[0] (Bit2)) -+ * - PTP_INT_TYPE_TX_PDELAY_RESP (value[0] (Bit3)) -+ * - PTP_INT_TYPE_RX_SYNC (value[0] (Bit4)) -+ * - PTP_INT_TYPE_RX_DELAY_REQ (value[0] (Bit5)) -+ * - PTP_INT_TYPE_RX_PDELAY_REQ (value[0] (Bit6)) -+ * - PTP_INT_TYPE_RX_PDELAY_RESP (value[0] (Bit7)) -+ * The status will be cleared after execute this API. -+ */ -+extern rtk_api_ret_t rtk_ptp_portIntStatus_set(rtk_port_t port, rtk_ptp_intStatus_t statusMask); -+ -+/* Function Name: -+ * rtk_ptp_portIntStatus_get -+ * Description: -+ * Get PTP port interrupt trigger status. -+ * Input: -+ * port - physical port -+ * Output: -+ * pStatusMask - Interrupt status bit mask. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can get interrupt trigger status when interrupt happened. -+ * The interrupt trigger status is shown in the following: -+ * - PTP_INT_TYPE_TX_SYNC (value[0] (Bit0)) -+ * - PTP_INT_TYPE_TX_DELAY_REQ (value[0] (Bit1)) -+ * - PTP_INT_TYPE_TX_PDELAY_REQ (value[0] (Bit2)) -+ * - PTP_INT_TYPE_TX_PDELAY_RESP (value[0] (Bit3)) -+ * - PTP_INT_TYPE_RX_SYNC (value[0] (Bit4)) -+ * - PTP_INT_TYPE_RX_DELAY_REQ (value[0] (Bit5)) -+ * - PTP_INT_TYPE_RX_PDELAY_REQ (value[0] (Bit6)) -+ * - PTP_INT_TYPE_RX_PDELAY_RESP (value[0] (Bit7)) -+ * -+ */ -+extern rtk_api_ret_t rtk_ptp_portIntStatus_get(rtk_port_t port, rtk_ptp_intStatus_t *pStatusMask); -+ -+/* Function Name: -+ * rtk_ptp_portPtpTrap_set -+ * Description: -+ * Set PTP packet trap of the specified port. -+ * Input: -+ * port - port id -+ * enable - status -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_PORT - invalid port id -+ * RT_ERR_INPUT - invalid input parameter -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_ptp_portTrap_set(rtk_port_t port, rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_ptp_portPtpEnable_get -+ * Description: -+ * Get PTP packet trap of the specified port. -+ * Input: -+ * port - port id -+ * Output: -+ * pEnable - status -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_PORT - invalid port id -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_ptp_portTrap_get(rtk_port_t port, rtk_enable_t *pEnable); -+ -+#endif /* __RTK_API_PTP_H__ */ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/qos.h b/drivers/net/phy/rtk/rtl8367c/include/qos.h -new file mode 100644 -index 000000000000..d2d8fac24a23 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/qos.h -@@ -0,0 +1,781 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * Purpose : RTL8367/RTL8367C switch high-level API -+ * -+ * Feature : The file includes QoS module high-layer API definition -+ * -+ */ -+ -+#ifndef __RTK_API_QOS_H__ -+#define __RTK_API_QOS_H__ -+ -+/* -+ * Data Type Declaration -+ */ -+#define QOS_DEFAULT_TICK_PERIOD (19-1) -+#define QOS_DEFAULT_BYTE_PER_TOKEN 34 -+#define QOS_DEFAULT_LK_THRESHOLD (34*3) /* Why use 0x400? */ -+ -+ -+#define QOS_DEFAULT_INGRESS_BANDWIDTH 0x3FFF /* 0x3FFF => unlimit */ -+#define QOS_DEFAULT_EGRESS_BANDWIDTH 0x3D08 /*( 0x3D08 + 1) * 64Kbps => 1Gbps*/ -+#define QOS_DEFAULT_PREIFP 1 -+#define QOS_DEFAULT_PACKET_USED_PAGES_FC 0x60 -+#define QOS_DEFAULT_PACKET_USED_FC_EN 0 -+#define QOS_DEFAULT_QUEUE_BASED_FC_EN 1 -+ -+#define QOS_DEFAULT_PRIORITY_SELECT_PORT 8 -+#define QOS_DEFAULT_PRIORITY_SELECT_1Q 0 -+#define QOS_DEFAULT_PRIORITY_SELECT_ACL 0 -+#define QOS_DEFAULT_PRIORITY_SELECT_DSCP 0 -+ -+#define QOS_DEFAULT_DSCP_MAPPING_PRIORITY 0 -+ -+#define QOS_DEFAULT_1Q_REMARKING_ABILITY 0 -+#define QOS_DEFAULT_DSCP_REMARKING_ABILITY 0 -+#define QOS_DEFAULT_QUEUE_GAP 20 -+#define QOS_DEFAULT_QUEUE_NO_MAX 6 -+#define QOS_DEFAULT_AVERAGE_PACKET_RATE 0x3FFF -+#define QOS_DEFAULT_BURST_SIZE_IN_APR 0x3F -+#define QOS_DEFAULT_PEAK_PACKET_RATE 2 -+#define QOS_DEFAULT_SCHEDULER_ABILITY_APR 1 /*disable*/ -+#define QOS_DEFAULT_SCHEDULER_ABILITY_PPR 1 /*disable*/ -+#define QOS_DEFAULT_SCHEDULER_ABILITY_WFQ 1 /*disable*/ -+ -+#define QOS_WEIGHT_MAX 127 -+ -+#define RTK_MAX_NUM_OF_PRIORITY 8 -+#define RTK_MAX_NUM_OF_QUEUE 8 -+ -+#define RTK_PRIMAX 7 -+#define RTK_QIDMAX 7 -+#define RTK_DSCPMAX 63 -+ -+ -+/* enum Priority Selection Index */ -+typedef enum rtk_qos_priDecTbl_e -+{ -+ PRIDECTBL_IDX0 = 0, -+ PRIDECTBL_IDX1, -+ PRIDECTBL_END, -+}rtk_qos_priDecTbl_t; -+ -+ -+/* Types of 802.1p remarking source */ -+typedef enum rtk_qos_1pRmkSrc_e -+{ -+ DOT1P_RMK_SRC_USER_PRI, -+ DOT1P_RMK_SRC_TAG_PRI, -+ DOT1P_RMK_SRC_END -+} rtk_qos_1pRmkSrc_t; -+ -+ -+/* Types of DSCP remarking source */ -+typedef enum rtk_qos_dscpRmkSrc_e -+{ -+ DSCP_RMK_SRC_INT_PRI, -+ DSCP_RMK_SRC_DSCP, -+ DSCP_RMK_SRC_USER_PRI, -+ DSCP_RMK_SRC_END -+} rtk_qos_dscpRmkSrc_t; -+ -+ -+ -+ -+typedef struct rtk_priority_select_s -+{ -+ rtk_uint32 port_pri; -+ rtk_uint32 dot1q_pri; -+ rtk_uint32 acl_pri; -+ rtk_uint32 dscp_pri; -+ rtk_uint32 cvlan_pri; -+ rtk_uint32 svlan_pri; -+ rtk_uint32 dmac_pri; -+ rtk_uint32 smac_pri; -+} rtk_priority_select_t; -+ -+typedef struct rtk_qos_pri2queue_s -+{ -+ rtk_uint32 pri2queue[RTK_MAX_NUM_OF_PRIORITY]; -+} rtk_qos_pri2queue_t; -+ -+typedef struct rtk_qos_queue_weights_s -+{ -+ rtk_uint32 weights[RTK_MAX_NUM_OF_QUEUE]; -+} rtk_qos_queue_weights_t; -+ -+typedef enum rtk_qos_scheduling_type_e -+{ -+ WFQ = 0, /* Weighted-Fair-Queue */ -+ WRR, /* Weighted-Round-Robin */ -+ SCHEDULING_TYPE_END -+} rtk_qos_scheduling_type_t; -+ -+typedef rtk_uint32 rtk_queue_num_t; /* queue number*/ -+ -+/* Function Name: -+ * rtk_qos_init -+ * Description: -+ * Configure QoS default settings with queue number assignment to each port. -+ * Input: -+ * queueNum - Queue number of each port. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QUEUE_NUM - Invalid queue number. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API will initialize related QoS setting with queue number assignment. -+ * The queue number is from 1 to 8. -+ */ -+extern rtk_api_ret_t rtk_qos_init(rtk_queue_num_t queueNum); -+ -+/* Function Name: -+ * rtk_qos_priSel_set -+ * Description: -+ * Configure the priority order among different priority mechanism. -+ * Input: -+ * index - Priority decision table index (0~1) -+ * pPriDec - Priority assign for port, dscp, 802.1p, cvlan, svlan, acl based priority decision. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_SEL_PRI_SOURCE - Invalid priority decision source parameter. -+ * Note: -+ * ASIC will follow user priority setting of mechanisms to select mapped queue priority for receiving frame. -+ * If two priority mechanisms are the same, the ASIC will chose the highest priority from mechanisms to -+ * assign queue priority to receiving frame. -+ * The priority sources are: -+ * - PRIDEC_PORT -+ * - PRIDEC_ACL -+ * - PRIDEC_DSCP -+ * - PRIDEC_1Q -+ * - PRIDEC_1AD -+ * - PRIDEC_CVLAN -+ * - PRIDEC_DA -+ * - PRIDEC_SA -+ */ -+extern rtk_api_ret_t rtk_qos_priSel_set(rtk_qos_priDecTbl_t index, rtk_priority_select_t *pPriDec); -+ -+ -+/* Function Name: -+ * rtk_qos_priSel_get -+ * Description: -+ * Get the priority order configuration among different priority mechanism. -+ * Input: -+ * index - Priority decision table index (0~1) -+ * Output: -+ * pPriDec - Priority assign for port, dscp, 802.1p, cvlan, svlan, acl based priority decision . -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * ASIC will follow user priority setting of mechanisms to select mapped queue priority for receiving frame. -+ * If two priority mechanisms are the same, the ASIC will chose the highest priority from mechanisms to -+ * assign queue priority to receiving frame. -+ * The priority sources are: -+ * - PRIDEC_PORT, -+ * - PRIDEC_ACL, -+ * - PRIDEC_DSCP, -+ * - PRIDEC_1Q, -+ * - PRIDEC_1AD, -+ * - PRIDEC_CVLAN, -+ * - PRIDEC_DA, -+ * - PRIDEC_SA, -+ */ -+extern rtk_api_ret_t rtk_qos_priSel_get(rtk_qos_priDecTbl_t index, rtk_priority_select_t *pPriDec); -+ -+/* Function Name: -+ * rtk_qos_1pPriRemap_set -+ * Description: -+ * Configure 1Q priorities mapping to internal absolute priority. -+ * Input: -+ * dot1p_pri - 802.1p priority value. -+ * int_pri - internal priority value. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_VLAN_PRIORITY - Invalid 1p priority. -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority. -+ * Note: -+ * Priority of 802.1Q assignment for internal asic priority, and it is used for queue usage and packet scheduling. -+ */ -+extern rtk_api_ret_t rtk_qos_1pPriRemap_set(rtk_pri_t dot1p_pri, rtk_pri_t int_pri); -+ -+/* Function Name: -+ * rtk_qos_1pPriRemap_get -+ * Description: -+ * Get 1Q priorities mapping to internal absolute priority. -+ * Input: -+ * dot1p_pri - 802.1p priority value . -+ * Output: -+ * pInt_pri - internal priority value. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_VLAN_PRIORITY - Invalid priority. -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority. -+ * Note: -+ * Priority of 802.1Q assignment for internal asic priority, and it is used for queue usage and packet scheduling. -+ */ -+extern rtk_api_ret_t rtk_qos_1pPriRemap_get(rtk_pri_t dot1p_pri, rtk_pri_t *pInt_pri); -+ -+ -+/* Function Name: -+ * rtk_qos_1pRemarkSrcSel_set -+ * Description: -+ * Set remarking source of 802.1p remarking. -+ * Input: -+ * type - remarking source -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_PORT_ID - invalid port id -+ * RT_ERR_INPUT - invalid input parameter -+ -+ * Note: -+ * The API can configure 802.1p remark functionality to map original 802.1p value or internal -+ * priority to TX DSCP value. -+ */ -+extern rtk_api_ret_t rtk_qos_1pRemarkSrcSel_set(rtk_qos_1pRmkSrc_t type); -+ -+/* Function Name: -+ * rtk_qos_1pRemarkSrcSel_get -+ * Description: -+ * Get remarking source of 802.1p remarking. -+ * Input: -+ * none -+ * Output: -+ * pType - remarking source -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_PORT_ID - invalid port id -+ * RT_ERR_INPUT - invalid input parameter -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_qos_1pRemarkSrcSel_get(rtk_qos_1pRmkSrc_t *pType); -+ -+/* Function Name: -+ * rtk_qos_dscpPriRemap_set -+ * Description: -+ * Map dscp value to internal priority. -+ * Input: -+ * dscp - Dscp value of receiving frame -+ * int_pri - internal priority value . -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value. -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority. -+ * Note: -+ * The Differentiated Service Code Point is a selector for router's per-hop behaviors. As a selector, there is no implication that a numerically -+ * greater DSCP implies a better network service. As can be seen, the DSCP totally overlaps the old precedence field of TOS. So if values of -+ * DSCP are carefully chosen then backward compatibility can be achieved. -+ */ -+extern rtk_api_ret_t rtk_qos_dscpPriRemap_set(rtk_dscp_t dscp, rtk_pri_t int_pri); -+ -+/* Function Name: -+ * rtk_qos_dscpPriRemap_get -+ * Description: -+ * Get dscp value to internal priority. -+ * Input: -+ * dscp - Dscp value of receiving frame -+ * Output: -+ * pInt_pri - internal priority value. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value. -+ * Note: -+ * The Differentiated Service Code Point is a selector for router's per-hop behaviors. As a selector, there is no implication that a numerically -+ * greater DSCP implies a better network service. As can be seen, the DSCP totally overlaps the old precedence field of TOS. So if values of -+ * DSCP are carefully chosen then backward compatibility can be achieved. -+ */ -+extern rtk_api_ret_t rtk_qos_dscpPriRemap_get(rtk_dscp_t dscp, rtk_pri_t *pInt_pri); -+ -+/* Function Name: -+ * rtk_qos_portPri_set -+ * Description: -+ * Configure priority usage to each port. -+ * Input: -+ * port - Port id. -+ * int_pri - internal priority value. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_QOS_SEL_PORT_PRI - Invalid port priority. -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority. -+ * Note: -+ * The API can set priority of port assignments for queue usage and packet scheduling. -+ */ -+extern rtk_api_ret_t rtk_qos_portPri_set(rtk_port_t port, rtk_pri_t int_pri) ; -+ -+/* Function Name: -+ * rtk_qos_portPri_get -+ * Description: -+ * Get priority usage to each port. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pInt_pri - internal priority value. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can get priority of port assignments for queue usage and packet scheduling. -+ */ -+extern rtk_api_ret_t rtk_qos_portPri_get(rtk_port_t port, rtk_pri_t *pInt_pri) ; -+ -+/* Function Name: -+ * rtk_qos_queueNum_set -+ * Description: -+ * Set output queue number for each port. -+ * Input: -+ * port - Port id. -+ * index - Mapping queue number (1~8) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_QUEUE_NUM - Invalid queue number. -+ * Note: -+ * The API can set the output queue number of the specified port. The queue number is from 1 to 8. -+ */ -+extern rtk_api_ret_t rtk_qos_queueNum_set(rtk_port_t port, rtk_queue_num_t queue_num); -+ -+/* Function Name: -+ * rtk_qos_queueNum_get -+ * Description: -+ * Get output queue number. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pQueue_num - Mapping queue number -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API will return the output queue number of the specified port. The queue number is from 1 to 8. -+ */ -+extern rtk_api_ret_t rtk_qos_queueNum_get(rtk_port_t port, rtk_queue_num_t *pQueue_num); -+ -+/* Function Name: -+ * rtk_qos_priMap_set -+ * Description: -+ * Set output queue number for each port. -+ * Input: -+ * queue_num - Queue number usage. -+ * pPri2qid - Priority mapping to queue ID. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_QUEUE_NUM - Invalid queue number. -+ * RT_ERR_QUEUE_ID - Invalid queue id. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority. -+ * Note: -+ * ASIC supports priority mapping to queue with different queue number from 1 to 8. -+ * For different queue numbers usage, ASIC supports different internal available queue IDs. -+ */ -+extern rtk_api_ret_t rtk_qos_priMap_set(rtk_queue_num_t queue_num, rtk_qos_pri2queue_t *pPri2qid); -+ -+ -+/* Function Name: -+ * rtk_qos_priMap_get -+ * Description: -+ * Get priority to queue ID mapping table parameters. -+ * Input: -+ * queue_num - Queue number usage. -+ * Output: -+ * pPri2qid - Priority mapping to queue ID. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_QUEUE_NUM - Invalid queue number. -+ * Note: -+ * The API can return the mapping queue id of the specified priority and queue number. -+ * The queue number is from 1 to 8. -+ */ -+extern rtk_api_ret_t rtk_qos_priMap_get(rtk_queue_num_t queue_num, rtk_qos_pri2queue_t *pPri2qid); -+ -+/* Function Name: -+ * rtk_qos_schedulingQueue_set -+ * Description: -+ * Set weight and type of queues in dedicated port. -+ * Input: -+ * port - Port id. -+ * pQweights - The array of weights for WRR/WFQ queue (0 for STRICT_PRIORITY queue). -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_QOS_QUEUE_WEIGHT - Invalid queue weight. -+ * Note: -+ * The API can set weight and type, strict priority or weight fair queue (WFQ) for -+ * dedicated port for using queues. If queue id is not included in queue usage, -+ * then its type and weight setting in dummy for setting. There are priorities -+ * as queue id in strict queues. It means strict queue id 5 carrying higher priority -+ * than strict queue id 4. The WFQ queue weight is from 1 to 128, and weight 0 is -+ * for strict priority queue type. -+ */ -+extern rtk_api_ret_t rtk_qos_schedulingQueue_set(rtk_port_t port, rtk_qos_queue_weights_t *pQweights); -+ -+/* Function Name: -+ * rtk_qos_schedulingQueue_get -+ * Description: -+ * Get weight and type of queues in dedicated port. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pQweights - The array of weights for WRR/WFQ queue (0 for STRICT_PRIORITY queue). -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get weight and type, strict priority or weight fair queue (WFQ) for dedicated port for using queues. -+ * The WFQ queue weight is from 1 to 128, and weight 0 is for strict priority queue type. -+ */ -+extern rtk_api_ret_t rtk_qos_schedulingQueue_get(rtk_port_t port, rtk_qos_queue_weights_t *pQweights); -+ -+/* Function Name: -+ * rtk_qos_1pRemarkEnable_set -+ * Description: -+ * Set 1p Remarking state -+ * Input: -+ * port - Port id. -+ * enable - State of per-port 1p Remarking -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_ENABLE - Invalid enable parameter. -+ * Note: -+ * The API can enable or disable 802.1p remarking ability for whole system. -+ * The status of 802.1p remark: -+ * - DISABLED -+ * - ENABLED -+ */ -+extern rtk_api_ret_t rtk_qos_1pRemarkEnable_set(rtk_port_t port, rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_qos_1pRemarkEnable_get -+ * Description: -+ * Get 802.1p remarking ability. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pEnable - Status of 802.1p remark. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get 802.1p remarking ability. -+ * The status of 802.1p remark: -+ * - DISABLED -+ * - ENABLED -+ */ -+extern rtk_api_ret_t rtk_qos_1pRemarkEnable_get(rtk_port_t port, rtk_enable_t *pEnable); -+ -+/* Function Name: -+ * rtk_qos_1pRemark_set -+ * Description: -+ * Set 802.1p remarking parameter. -+ * Input: -+ * int_pri - Internal priority value. -+ * dot1p_pri - 802.1p priority value. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_VLAN_PRIORITY - Invalid 1p priority. -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority. -+ * Note: -+ * The API can set 802.1p parameters source priority and new priority. -+ */ -+extern rtk_api_ret_t rtk_qos_1pRemark_set(rtk_pri_t int_pri, rtk_pri_t dot1p_pri); -+ -+/* Function Name: -+ * rtk_qos_1pRemark_get -+ * Description: -+ * Get 802.1p remarking parameter. -+ * Input: -+ * int_pri - Internal priority value. -+ * Output: -+ * pDot1p_pri - 802.1p priority value. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority. -+ * Note: -+ * The API can get 802.1p remarking parameters. It would return new priority of ingress priority. -+ */ -+extern rtk_api_ret_t rtk_qos_1pRemark_get(rtk_pri_t int_pri, rtk_pri_t *pDot1p_pri); -+ -+/* Function Name: -+ * rtk_qos_dscpRemarkEnable_set -+ * Description: -+ * Set DSCP remarking ability. -+ * Input: -+ * port - Port id. -+ * enable - status of DSCP remark. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority. -+ * RT_ERR_ENABLE - Invalid enable parameter. -+ * Note: -+ * The API can enable or disable DSCP remarking ability for whole system. -+ * The status of DSCP remark: -+ * - DISABLED -+ * - ENABLED -+ */ -+extern rtk_api_ret_t rtk_qos_dscpRemarkEnable_set(rtk_port_t port, rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_qos_dscpRemarkEnable_get -+ * Description: -+ * Get DSCP remarking ability. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pEnable - status of DSCP remarking. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get DSCP remarking ability. -+ * The status of DSCP remark: -+ * - DISABLED -+ * - ENABLED -+ */ -+extern rtk_api_ret_t rtk_qos_dscpRemarkEnable_get(rtk_port_t port, rtk_enable_t *pEnable); -+ -+/* Function Name: -+ * rtk_qos_dscpRemark_set -+ * Description: -+ * Set DSCP remarking parameter. -+ * Input: -+ * int_pri - Internal priority value. -+ * dscp - DSCP value. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority. -+ * RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value. -+ * Note: -+ * The API can set DSCP value and mapping priority. -+ */ -+extern rtk_api_ret_t rtk_qos_dscpRemark_set(rtk_pri_t int_pri, rtk_dscp_t dscp); -+ -+/* Function Name: -+ * rtk_qos_dscpRemark_get -+ * Description: -+ * Get DSCP remarking parameter. -+ * Input: -+ * int_pri - Internal priority value. -+ * Output: -+ * Dscp - DSCP value. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority. -+ * Note: -+ * The API can get DSCP parameters. It would return DSCP value for mapping priority. -+ */ -+extern rtk_api_ret_t rtk_qos_dscpRemark_get(rtk_pri_t int_pri, rtk_dscp_t *pDscp); -+ -+/* Function Name: -+ * rtk_qos_dscpRemarkSrcSel_set -+ * Description: -+ * Set remarking source of DSCP remarking. -+ * Input: -+ * type - remarking source -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_PORT_ID - invalid port id -+ * RT_ERR_INPUT - invalid input parameter -+ -+ * Note: -+ * The API can configure DSCP remark functionality to map original DSCP value or internal -+ * priority to TX DSCP value. -+ */ -+extern rtk_api_ret_t rtk_qos_dscpRemarkSrcSel_set(rtk_qos_dscpRmkSrc_t type); -+ -+ -+/* Function Name: -+ * rtk_qos_dcpRemarkSrcSel_get -+ * Description: -+ * Get remarking source of DSCP remarking. -+ * Input: -+ * none -+ * Output: -+ * pType - remarking source -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_PORT_ID - invalid port id -+ * RT_ERR_INPUT - invalid input parameter -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_qos_dscpRemarkSrcSel_get(rtk_qos_dscpRmkSrc_t *pType); -+ -+ -+/* Function Name: -+ * rtk_qos_dscpRemark2Dscp_set -+ * Description: -+ * Set DSCP to remarked DSCP mapping. -+ * Input: -+ * dscp - DSCP value -+ * rmkDscp - remarked DSCP value -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_QOS_DSCP_VALUE - Invalid dscp value -+ * Note: -+ * dscp parameter can be DSCP value or internal priority according to configuration of API -+ * dal_apollomp_qos_dscpRemarkSrcSel_set(), because DSCP remark functionality can map original DSCP -+ * value or internal priority to TX DSCP value. -+ */ -+extern rtk_api_ret_t rtk_qos_dscpRemark2Dscp_set(rtk_dscp_t dscp, rtk_dscp_t rmkDscp); -+ -+/* Function Name: -+ * rtk_qos_dscpRemark2Dscp_get -+ * Description: -+ * Get DSCP to remarked DSCP mapping. -+ * Input: -+ * dscp - DSCP value -+ * Output: -+ * pDscp - remarked DSCP value -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_QOS_DSCP_VALUE - Invalid dscp value -+ * RT_ERR_NULL_POINTER - NULL pointer -+ * Note: -+ * None. -+ */ -+extern rtk_api_ret_t rtk_qos_dscpRemark2Dscp_get(rtk_dscp_t dscp, rtk_dscp_t *pDscp); -+ -+/* Function Name: -+ * rtk_qos_portPriSelIndex_set -+ * Description: -+ * Configure priority decision index to each port. -+ * Input: -+ * port - Port id. -+ * index - priority decision index. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_ENTRY_INDEX - Invalid entry index. -+ * Note: -+ * The API can set priority of port assignments for queue usage and packet scheduling. -+ */ -+extern rtk_api_ret_t rtk_qos_portPriSelIndex_set(rtk_port_t port, rtk_qos_priDecTbl_t index); -+ -+/* Function Name: -+ * rtk_qos_portPriSelIndex_get -+ * Description: -+ * Get priority decision index from each port. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pIndex - priority decision index. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get priority of port assignments for queue usage and packet scheduling. -+ */ -+extern rtk_api_ret_t rtk_qos_portPriSelIndex_get(rtk_port_t port, rtk_qos_priDecTbl_t *pIndex); -+ -+#endif /* __RTK_API_QOS_H__ */ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rate.h b/drivers/net/phy/rtk/rtl8367c/include/rate.h -new file mode 100644 -index 000000000000..b3cdf432f747 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rate.h -@@ -0,0 +1,305 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * Purpose : RTL8367/RTL8367C switch high-level API -+ * -+ * Feature : The file includes rate module high-layer API definition -+ * -+ */ -+ -+#ifndef __RTK_API_RATE_H__ -+#define __RTK_API_RATE_H__ -+ -+/* -+ * Include Files -+ */ -+//#include -+ -+/* -+ * Data Type Declaration -+ */ -+#define RTK_MAX_METER_ID (rtk_switch_maxMeterId_get()) -+#define RTK_METER_NUM (RTK_MAX_METER_ID + 1) -+ -+typedef enum rtk_meter_type_e{ -+ METER_TYPE_KBPS = 0, /* Kbps */ -+ METER_TYPE_PPS, /* Packet per second */ -+ METER_TYPE_END -+}rtk_meter_type_t; -+ -+ -+/* -+ * Function Declaration -+ */ -+ -+ /* Rate */ -+/* Function Name: -+ * rtk_rate_shareMeter_set -+ * Description: -+ * Set meter configuration -+ * Input: -+ * index - shared meter index -+ * type - shared meter type -+ * rate - rate of share meter -+ * ifg_include - include IFG or not, ENABLE:include DISABLE:exclude -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_FILTER_METER_ID - Invalid meter -+ * RT_ERR_RATE - Invalid rate -+ * RT_ERR_INPUT - Invalid input parameters -+ * Note: -+ * The API can set shared meter rate and ifg include for each meter. -+ * The rate unit is 1 kbps and the range is from 8k to 1048568k if type is METER_TYPE_KBPS and -+ * the granularity of rate is 8 kbps. -+ * The rate unit is packets per second and the range is 1 ~ 0x1FFF if type is METER_TYPE_PPS. -+ * The ifg_include parameter is used -+ * for rate calculation with/without inter-frame-gap and preamble. -+ */ -+rtk_api_ret_t rtk_rate_shareMeter_set(rtk_meter_id_t index, rtk_meter_type_t type, rtk_rate_t rate, rtk_enable_t ifg_include); -+ -+/* Function Name: -+ * rtk_rate_shareMeter_get -+ * Description: -+ * Get meter configuration -+ * Input: -+ * index - shared meter index -+ * Output: -+ * pType - Meter Type -+ * pRate - pointer of rate of share meter -+ * pIfg_include - include IFG or not, ENABLE:include DISABLE:exclude -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_FILTER_METER_ID - Invalid meter -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_rate_shareMeter_get(rtk_meter_id_t index, rtk_meter_type_t *pType, rtk_rate_t *pRate, rtk_enable_t *pIfg_include); -+ -+/* Function Name: -+ * rtk_rate_shareMeterBucket_set -+ * Description: -+ * Set meter Bucket Size -+ * Input: -+ * index - shared meter index -+ * bucket_size - Bucket Size -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_INPUT - Error Input -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_FILTER_METER_ID - Invalid meter -+ * Note: -+ * The API can set shared meter bucket size. -+ */ -+extern rtk_api_ret_t rtk_rate_shareMeterBucket_set(rtk_meter_id_t index, rtk_uint32 bucket_size); -+ -+/* Function Name: -+ * rtk_rate_shareMeterBucket_get -+ * Description: -+ * Get meter Bucket Size -+ * Input: -+ * index - shared meter index -+ * Output: -+ * pBucket_size - Bucket Size -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_FILTER_METER_ID - Invalid meter -+ * Note: -+ * The API can get shared meter bucket size. -+ */ -+extern rtk_api_ret_t rtk_rate_shareMeterBucket_get(rtk_meter_id_t index, rtk_uint32 *pBucket_size); -+ -+/* Function Name: -+ * rtk_rate_igrBandwidthCtrlRate_set -+ * Description: -+ * Set port ingress bandwidth control -+ * Input: -+ * port - Port id -+ * rate - Rate of share meter -+ * ifg_include - include IFG or not, ENABLE:include DISABLE:exclude -+ * fc_enable - enable flow control or not, ENABLE:use flow control DISABLE:drop -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_ENABLE - Invalid IFG parameter. -+ * RT_ERR_INBW_RATE - Invalid ingress rate parameter. -+ * Note: -+ * The rate unit is 1 kbps and the range is from 8k to 1048568k. The granularity of rate is 8 kbps. -+ * The ifg_include parameter is used for rate calculation with/without inter-frame-gap and preamble. -+ */ -+extern rtk_api_ret_t rtk_rate_igrBandwidthCtrlRate_set( rtk_port_t port, rtk_rate_t rate, rtk_enable_t ifg_include, rtk_enable_t fc_enable); -+ -+/* Function Name: -+ * rtk_rate_igrBandwidthCtrlRate_get -+ * Description: -+ * Get port ingress bandwidth control -+ * Input: -+ * port - Port id -+ * Output: -+ * pRate - Rate of share meter -+ * pIfg_include - Rate's calculation including IFG, ENABLE:include DISABLE:exclude -+ * pFc_enable - enable flow control or not, ENABLE:use flow control DISABLE:drop -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The rate unit is 1 kbps and the range is from 8k to 1048568k. The granularity of rate is 8 kbps. -+ * The ifg_include parameter is used for rate calculation with/without inter-frame-gap and preamble. -+ */ -+extern rtk_api_ret_t rtk_rate_igrBandwidthCtrlRate_get(rtk_port_t port, rtk_rate_t *pRate, rtk_enable_t *pIfg_include, rtk_enable_t *pFc_enable); -+ -+/* Function Name: -+ * rtk_rate_egrBandwidthCtrlRate_set -+ * Description: -+ * Set port egress bandwidth control -+ * Input: -+ * port - Port id -+ * rate - Rate of egress bandwidth -+ * ifg_include - include IFG or not, ENABLE:include DISABLE:exclude -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_QOS_EBW_RATE - Invalid egress bandwidth/rate -+ * Note: -+ * The rate unit is 1 kbps and the range is from 8k to 1048568k. The granularity of rate is 8 kbps. -+ * The ifg_include parameter is used for rate calculation with/without inter-frame-gap and preamble. -+ */ -+extern rtk_api_ret_t rtk_rate_egrBandwidthCtrlRate_set(rtk_port_t port, rtk_rate_t rate, rtk_enable_t ifg_includ); -+ -+/* Function Name: -+ * rtk_rate_egrBandwidthCtrlRate_get -+ * Description: -+ * Get port egress bandwidth control -+ * Input: -+ * port - Port id -+ * Output: -+ * pRate - Rate of egress bandwidth -+ * pIfg_include - Rate's calculation including IFG, ENABLE:include DISABLE:exclude -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The rate unit is 1 kbps and the range is from 8k to 1048568k. The granularity of rate is 8 kbps. -+ * The ifg_include parameter is used for rate calculation with/without inter-frame-gap and preamble. -+ */ -+extern rtk_api_ret_t rtk_rate_egrBandwidthCtrlRate_get(rtk_port_t port, rtk_rate_t *pRate, rtk_enable_t *pIfg_include); -+ -+/* Function Name: -+ * rtk_rate_egrQueueBwCtrlEnable_set -+ * Description: -+ * Set enable status of egress bandwidth control on specified queue. -+ * Input: -+ * port - port id -+ * queue - queue id -+ * enable - enable status of egress queue bandwidth control -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_PORT_ID - invalid port id -+ * RT_ERR_QUEUE_ID - invalid queue id -+ * RT_ERR_INPUT - invalid input parameter -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_rate_egrQueueBwCtrlEnable_set(rtk_port_t port, rtk_qid_t queue, rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_rate_egrQueueBwCtrlRate_get -+ * Description: -+ * Get rate of egress bandwidth control on specified queue. -+ * Input: -+ * port - port id -+ * queue - queue id -+ * pIndex - shared meter index -+ * Output: -+ * pRate - pointer to rate of egress queue bandwidth control -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_PORT_ID - invalid port id -+ * RT_ERR_QUEUE_ID - invalid queue id -+ * RT_ERR_FILTER_METER_ID - Invalid meter id -+ * Note: -+ * None. -+ */ -+extern rtk_api_ret_t rtk_rate_egrQueueBwCtrlEnable_get(rtk_port_t port, rtk_qid_t queue, rtk_enable_t *pEnable); -+ -+/* Function Name: -+ * rtk_rate_egrQueueBwCtrlRate_set -+ * Description: -+ * Set rate of egress bandwidth control on specified queue. -+ * Input: -+ * port - port id -+ * queue - queue id -+ * index - shared meter index -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_PORT_ID - invalid port id -+ * RT_ERR_QUEUE_ID - invalid queue id -+ * RT_ERR_FILTER_METER_ID - Invalid meter id -+ * Note: -+ * The actual rate control is set in shared meters. -+ * The unit of granularity is 8Kbps. -+ */ -+extern rtk_api_ret_t rtk_rate_egrQueueBwCtrlRate_set(rtk_port_t port, rtk_qid_t queue, rtk_meter_id_t index); -+ -+/* Function Name: -+ * rtk_rate_egrQueueBwCtrlRate_get -+ * Description: -+ * Get rate of egress bandwidth control on specified queue. -+ * Input: -+ * port - port id -+ * queue - queue id -+ * pIndex - shared meter index -+ * Output: -+ * pRate - pointer to rate of egress queue bandwidth control -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_PORT_ID - invalid port id -+ * RT_ERR_QUEUE_ID - invalid queue id -+ * RT_ERR_FILTER_METER_ID - Invalid meter id -+ * Note: -+ * The actual rate control is set in shared meters. -+ * The unit of granularity is 8Kbps. -+ */ -+extern rtk_api_ret_t rtk_rate_egrQueueBwCtrlRate_get(rtk_port_t port, rtk_qid_t queue, rtk_meter_id_t *pIndex); -+ -+#endif /* __RTK_API_RATE_H__ */ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rldp.h b/drivers/net/phy/rtk/rtl8367c/include/rldp.h -new file mode 100644 -index 000000000000..111de0c09377 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rldp.h -@@ -0,0 +1,264 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ -+ * -+ * Purpose : Declaration of RLDP and RLPP API -+ * -+ * Feature : The file have include the following module and sub-modules -+ * 1) RLDP and RLPP configuration and status -+ * -+ */ -+ -+ -+#ifndef __RTK_RLDP_H__ -+#define __RTK_RLDP_H__ -+ -+ -+/* -+ * Include Files -+ */ -+ -+ -+/* -+ * Symbol Definition -+ */ -+typedef enum rtk_rldp_trigger_e -+{ -+ RTK_RLDP_TRIGGER_SAMOVING = 0, -+ RTK_RLDP_TRIGGER_PERIOD, -+ RTK_RLDP_TRIGGER_END -+} rtk_rldp_trigger_t; -+ -+typedef enum rtk_rldp_cmpType_e -+{ -+ RTK_RLDP_CMPTYPE_MAGIC = 0, /* Compare the RLDP with magic only */ -+ RTK_RLDP_CMPTYPE_MAGIC_ID, /* Compare the RLDP with both magic + ID */ -+ RTK_RLDP_CMPTYPE_END -+} rtk_rldp_cmpType_t; -+ -+typedef enum rtk_rldp_loopStatus_e -+{ -+ RTK_RLDP_LOOPSTS_NONE = 0, -+ RTK_RLDP_LOOPSTS_LOOPING, -+ RTK_RLDP_LOOPSTS_END -+} rtk_rldp_loopStatus_t; -+ -+typedef enum rtk_rlpp_trapType_e -+{ -+ RTK_RLPP_TRAPTYPE_NONE = 0, -+ RTK_RLPP_TRAPTYPE_CPU, -+ RTK_RLPP_TRAPTYPE_END -+} rtk_rlpp_trapType_t; -+ -+typedef struct rtk_rldp_config_s -+{ -+ rtk_enable_t rldp_enable; -+ rtk_rldp_trigger_t trigger_mode; -+ rtk_mac_t magic; -+ rtk_rldp_cmpType_t compare_type; -+ rtk_uint32 interval_check; /* Checking interval for check state */ -+ rtk_uint32 num_check; /* Checking number for check state */ -+ rtk_uint32 interval_loop; /* Checking interval for loop state */ -+ rtk_uint32 num_loop; /* Checking number for loop state */ -+} rtk_rldp_config_t; -+ -+typedef struct rtk_rldp_portConfig_s -+{ -+ rtk_enable_t tx_enable; -+} rtk_rldp_portConfig_t; -+ -+typedef struct rtk_rldp_status_s -+{ -+ rtk_mac_t id; -+} rtk_rldp_status_t; -+ -+typedef struct rtk_rldp_portStatus_s -+{ -+ rtk_rldp_loopStatus_t loop_status; -+ rtk_rldp_loopStatus_t loop_enter; -+ rtk_rldp_loopStatus_t loop_leave; -+} rtk_rldp_portStatus_t; -+ -+/* -+ * Data Declaration -+ */ -+ -+ -+/* -+ * Macro Declaration -+ */ -+ -+#define RTK_RLDP_INTERVAL_MAX 0xffff -+#define RTK_RLDP_NUM_MAX 0xff -+ -+ -+/* -+ * Function Declaration -+ */ -+ -+/* Module Name : RLDP */ -+ -+ -+/* Function Name: -+ * rtk_rldp_config_set -+ * Description: -+ * Set RLDP module configuration -+ * Input: -+ * pConfig - configuration structure of RLDP -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_INPUT -+ * RT_ERR_NULL_POINTER -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_rldp_config_set(rtk_rldp_config_t *pConfig); -+ -+ -+/* Function Name: -+ * rtk_rldp_config_get -+ * Description: -+ * Get RLDP module configuration -+ * Input: -+ * None -+ * Output: -+ * pConfig - configuration structure of RLDP -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_INPUT -+ * RT_ERR_NULL_POINTER -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_rldp_config_get(rtk_rldp_config_t *pConfig); -+ -+ -+/* Function Name: -+ * rtk_rldp_portConfig_set -+ * Description: -+ * Set per port RLDP module configuration -+ * Input: -+ * port - port number to be configured -+ * pPortConfig - per port configuration structure of RLDP -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_INPUT -+ * RT_ERR_NULL_POINTER -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_rldp_portConfig_set(rtk_port_t port, rtk_rldp_portConfig_t *pPortConfig); -+ -+ -+/* Function Name: -+ * rtk_rldp_portConfig_get -+ * Description: -+ * Get per port RLDP module configuration -+ * Input: -+ * port - port number to be get -+ * Output: -+ * pPortConfig - per port configuration structure of RLDP -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_INPUT -+ * RT_ERR_NULL_POINTER -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_rldp_portConfig_get(rtk_port_t port, rtk_rldp_portConfig_t *pPortConfig); -+ -+ -+/* Function Name: -+ * rtk_rldp_status_get -+ * Description: -+ * Get RLDP module status -+ * Input: -+ * None -+ * Output: -+ * pStatus - status structure of RLDP -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NULL_POINTER -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_rldp_status_get(rtk_rldp_status_t *pStatus); -+ -+ -+/* Function Name: -+ * rtk_rldp_portStatus_get -+ * Description: -+ * Get RLDP module status -+ * Input: -+ * port - port number to be get -+ * Output: -+ * pPortStatus - per port status structure of RLDP -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_INPUT -+ * RT_ERR_NULL_POINTER -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_rldp_portStatus_get(rtk_port_t port, rtk_rldp_portStatus_t *pPortStatus); -+ -+ -+/* Function Name: -+ * rtk_rldp_portStatus_clear -+ * Description: -+ * Clear RLDP module status -+ * Input: -+ * port - port number to be clear -+ * pPortStatus - per port status structure of RLDP -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_INPUT -+ * RT_ERR_NULL_POINTER -+ * Note: -+ * Clear operation effect loop_enter and loop_leave only, other field in -+ * the structure are don't care -+ */ -+extern rtk_api_ret_t rtk_rldp_portStatus_set(rtk_port_t port, rtk_rldp_portStatus_t *pPortStatus); -+ -+ -+/* Function Name: -+ * rtk_rldp_portLoopPair_get -+ * Description: -+ * Get RLDP port loop pairs -+ * Input: -+ * port - port number to be get -+ * Output: -+ * pPortmask - per port related loop ports -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_INPUT -+ * RT_ERR_NULL_POINTER -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_rldp_portLoopPair_get(rtk_port_t port, rtk_portmask_t *pPortmask); -+ -+#endif /* __RTK_RLDP_H__ */ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtk_error.h b/drivers/net/phy/rtk/rtl8367c/include/rtk_error.h -new file mode 100644 -index 000000000000..54d1a13f3bee ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtk_error.h -@@ -0,0 +1,229 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : Definition the error number in the SDK. -+ * Feature : error definition -+ * -+ */ -+ -+#ifndef __COMMON_RT_ERROR_H__ -+#define __COMMON_RT_ERROR_H__ -+ -+/* -+ * Include Files -+ */ -+ -+/* -+ * Data Type Declaration -+ */ -+typedef enum rt_error_code_e -+{ -+ RT_ERR_FAILED = -1, /* General Error */ -+ -+ /* 0x0000xxxx for common error code */ -+ RT_ERR_OK = 0, /* 0x00000000, OK */ -+ RT_ERR_INPUT, /* 0x00000001, invalid input parameter */ -+ RT_ERR_UNIT_ID, /* 0x00000002, invalid unit id */ -+ RT_ERR_PORT_ID, /* 0x00000003, invalid port id */ -+ RT_ERR_PORT_MASK, /* 0x00000004, invalid port mask */ -+ RT_ERR_PORT_LINKDOWN, /* 0x00000005, link down port status */ -+ RT_ERR_ENTRY_INDEX, /* 0x00000006, invalid entry index */ -+ RT_ERR_NULL_POINTER, /* 0x00000007, input parameter is null pointer */ -+ RT_ERR_QUEUE_ID, /* 0x00000008, invalid queue id */ -+ RT_ERR_QUEUE_NUM, /* 0x00000009, invalid queue number */ -+ RT_ERR_BUSYWAIT_TIMEOUT, /* 0x0000000a, busy waiting time out */ -+ RT_ERR_MAC, /* 0x0000000b, invalid mac address */ -+ RT_ERR_OUT_OF_RANGE, /* 0x0000000c, input parameter out of range */ -+ RT_ERR_CHIP_NOT_SUPPORTED, /* 0x0000000d, functions not supported by this chip model */ -+ RT_ERR_SMI, /* 0x0000000e, SMI error */ -+ RT_ERR_NOT_INIT, /* 0x0000000f, The module is not initial */ -+ RT_ERR_CHIP_NOT_FOUND, /* 0x00000010, The chip can not found */ -+ RT_ERR_NOT_ALLOWED, /* 0x00000011, actions not allowed by the function */ -+ RT_ERR_DRIVER_NOT_FOUND, /* 0x00000012, The driver can not found */ -+ RT_ERR_SEM_LOCK_FAILED, /* 0x00000013, Failed to lock semaphore */ -+ RT_ERR_SEM_UNLOCK_FAILED, /* 0x00000014, Failed to unlock semaphore */ -+ RT_ERR_ENABLE, /* 0x00000015, invalid enable parameter */ -+ RT_ERR_TBL_FULL, /* 0x00000016, input table full */ -+ -+ /* 0x0001xxxx for vlan */ -+ RT_ERR_VLAN_VID = 0x00010000, /* 0x00010000, invalid vid */ -+ RT_ERR_VLAN_PRIORITY, /* 0x00010001, invalid 1p priority */ -+ RT_ERR_VLAN_EMPTY_ENTRY, /* 0x00010002, empty entry of vlan table */ -+ RT_ERR_VLAN_ACCEPT_FRAME_TYPE, /* 0x00010003, invalid accept frame type */ -+ RT_ERR_VLAN_EXIST, /* 0x00010004, vlan is exist */ -+ RT_ERR_VLAN_ENTRY_NOT_FOUND, /* 0x00010005, specified vlan entry not found */ -+ RT_ERR_VLAN_PORT_MBR_EXIST, /* 0x00010006, member port exist in the specified vlan */ -+ RT_ERR_VLAN_PROTO_AND_PORT, /* 0x00010008, invalid protocol and port based vlan */ -+ -+ /* 0x0002xxxx for svlan */ -+ RT_ERR_SVLAN_ENTRY_INDEX = 0x00020000, /* 0x00020000, invalid svid entry no */ -+ RT_ERR_SVLAN_ETHER_TYPE, /* 0x00020001, invalid SVLAN ether type */ -+ RT_ERR_SVLAN_TABLE_FULL, /* 0x00020002, no empty entry in SVLAN table */ -+ RT_ERR_SVLAN_ENTRY_NOT_FOUND, /* 0x00020003, specified svlan entry not found */ -+ RT_ERR_SVLAN_EXIST, /* 0x00020004, SVLAN entry is exist */ -+ RT_ERR_SVLAN_VID, /* 0x00020005, invalid svid */ -+ -+ /* 0x0003xxxx for MSTP */ -+ RT_ERR_MSTI = 0x00030000, /* 0x00030000, invalid msti */ -+ RT_ERR_MSTP_STATE, /* 0x00030001, invalid spanning tree status */ -+ RT_ERR_MSTI_EXIST, /* 0x00030002, MSTI exist */ -+ RT_ERR_MSTI_NOT_EXIST, /* 0x00030003, MSTI not exist */ -+ -+ /* 0x0004xxxx for BUCKET */ -+ RT_ERR_TIMESLOT = 0x00040000, /* 0x00040000, invalid time slot */ -+ RT_ERR_TOKEN, /* 0x00040001, invalid token amount */ -+ RT_ERR_RATE, /* 0x00040002, invalid rate */ -+ RT_ERR_TICK, /* 0x00040003, invalid tick */ -+ -+ /* 0x0005xxxx for RMA */ -+ RT_ERR_RMA_ADDR = 0x00050000, /* 0x00050000, invalid rma mac address */ -+ RT_ERR_RMA_ACTION, /* 0x00050001, invalid rma action */ -+ -+ /* 0x0006xxxx for L2 */ -+ RT_ERR_L2_HASH_KEY = 0x00060000, /* 0x00060000, invalid L2 Hash key */ -+ RT_ERR_L2_HASH_INDEX, /* 0x00060001, invalid L2 Hash index */ -+ RT_ERR_L2_CAM_INDEX, /* 0x00060002, invalid L2 CAM index */ -+ RT_ERR_L2_ENRTYSEL, /* 0x00060003, invalid EntrySel */ -+ RT_ERR_L2_INDEXTABLE_INDEX, /* 0x00060004, invalid L2 index table(=portMask table) index */ -+ RT_ERR_LIMITED_L2ENTRY_NUM, /* 0x00060005, invalid limited L2 entry number */ -+ RT_ERR_L2_AGGREG_PORT, /* 0x00060006, this aggregated port is not the lowest physical -+ port of its aggregation group */ -+ RT_ERR_L2_FID, /* 0x00060007, invalid fid */ -+ RT_ERR_L2_VID, /* 0x00060008, invalid cvid */ -+ RT_ERR_L2_NO_EMPTY_ENTRY, /* 0x00060009, no empty entry in L2 table */ -+ RT_ERR_L2_ENTRY_NOTFOUND, /* 0x0006000a, specified entry not found */ -+ RT_ERR_L2_INDEXTBL_FULL, /* 0x0006000b, the L2 index table is full */ -+ RT_ERR_L2_INVALID_FLOWTYPE, /* 0x0006000c, invalid L2 flow type */ -+ RT_ERR_L2_L2UNI_PARAM, /* 0x0006000d, invalid L2 unicast parameter */ -+ RT_ERR_L2_L2MULTI_PARAM, /* 0x0006000e, invalid L2 multicast parameter */ -+ RT_ERR_L2_IPMULTI_PARAM, /* 0x0006000f, invalid L2 ip multicast parameter */ -+ RT_ERR_L2_PARTIAL_HASH_KEY, /* 0x00060010, invalid L2 partial Hash key */ -+ RT_ERR_L2_EMPTY_ENTRY, /* 0x00060011, the entry is empty(invalid) */ -+ RT_ERR_L2_FLUSH_TYPE, /* 0x00060012, the flush type is invalid */ -+ RT_ERR_L2_NO_CPU_PORT, /* 0x00060013, CPU port not exist */ -+ -+ /* 0x0007xxxx for FILTER (PIE) */ -+ RT_ERR_FILTER_BLOCKNUM = 0x00070000, /* 0x00070000, invalid block number */ -+ RT_ERR_FILTER_ENTRYIDX, /* 0x00070001, invalid entry index */ -+ RT_ERR_FILTER_CUTLINE, /* 0x00070002, invalid cutline value */ -+ RT_ERR_FILTER_FLOWTBLBLOCK, /* 0x00070003, block belongs to flow table */ -+ RT_ERR_FILTER_INACLBLOCK, /* 0x00070004, block belongs to ingress ACL */ -+ RT_ERR_FILTER_ACTION, /* 0x00070005, action doesn't consist to entry type */ -+ RT_ERR_FILTER_INACL_RULENUM, /* 0x00070006, invalid ACL rulenum */ -+ RT_ERR_FILTER_INACL_TYPE, /* 0x00070007, entry type isn't an ingress ACL rule */ -+ RT_ERR_FILTER_INACL_EXIST, /* 0x00070008, ACL entry is already exit */ -+ RT_ERR_FILTER_INACL_EMPTY, /* 0x00070009, ACL entry is empty */ -+ RT_ERR_FILTER_FLOWTBL_TYPE, /* 0x0007000a, entry type isn't an flow table rule */ -+ RT_ERR_FILTER_FLOWTBL_RULENUM, /* 0x0007000b, invalid flow table rulenum */ -+ RT_ERR_FILTER_FLOWTBL_EMPTY, /* 0x0007000c, flow table entry is empty */ -+ RT_ERR_FILTER_FLOWTBL_EXIST, /* 0x0007000d, flow table entry is already exist */ -+ RT_ERR_FILTER_METER_ID, /* 0x0007000e, invalid metering id */ -+ RT_ERR_FILTER_LOG_ID, /* 0x0007000f, invalid log id */ -+ RT_ERR_FILTER_INACL_NONE_BEGIN_IDX, /* 0x00070010, entry index is not starting index of a group of rules */ -+ RT_ERR_FILTER_INACL_ACT_NOT_SUPPORT, /* 0x00070011, action not support */ -+ RT_ERR_FILTER_INACL_RULE_NOT_SUPPORT, /* 0x00070012, rule not support */ -+ -+ /* 0x0008xxxx for ACL Rate Limit */ -+ RT_ERR_ACLRL_HTHR = 0x00080000, /* 0x00080000, invalid high threshold */ -+ RT_ERR_ACLRL_TIMESLOT, /* 0x00080001, invalid time slot */ -+ RT_ERR_ACLRL_TOKEN, /* 0x00080002, invalid token amount */ -+ RT_ERR_ACLRL_RATE, /* 0x00080003, invalid rate */ -+ -+ /* 0x0009xxxx for Link aggregation */ -+ RT_ERR_LA_CPUPORT = 0x00090000, /* 0x00090000, CPU port can not be aggregated port */ -+ RT_ERR_LA_TRUNK_ID, /* 0x00090001, invalid trunk id */ -+ RT_ERR_LA_PORTMASK, /* 0x00090002, invalid port mask */ -+ RT_ERR_LA_HASHMASK, /* 0x00090003, invalid hash mask */ -+ RT_ERR_LA_DUMB, /* 0x00090004, this API should be used in 802.1ad dumb mode */ -+ RT_ERR_LA_PORTNUM_DUMB, /* 0x00090005, it can only aggregate at most four ports when 802.1ad dumb mode */ -+ RT_ERR_LA_PORTNUM_NORMAL, /* 0x00090006, it can only aggregate at most eight ports when 802.1ad normal mode */ -+ RT_ERR_LA_MEMBER_OVERLAP, /* 0x00090007, the specified port mask is overlapped with other group */ -+ RT_ERR_LA_NOT_MEMBER_PORT, /* 0x00090008, the port is not a member port of the trunk */ -+ RT_ERR_LA_TRUNK_NOT_EXIST, /* 0x00090009, the trunk doesn't exist */ -+ -+ -+ /* 0x000axxxx for storm filter */ -+ RT_ERR_SFC_TICK_PERIOD = 0x000a0000, /* 0x000a0000, invalid SFC tick period */ -+ RT_ERR_SFC_UNKNOWN_GROUP, /* 0x000a0001, Unknown Storm filter group */ -+ -+ /* 0x000bxxxx for pattern match */ -+ RT_ERR_PM_MASK = 0x000b0000, /* 0x000b0000, invalid pattern length. Pattern length should be 8 */ -+ RT_ERR_PM_LENGTH, /* 0x000b0001, invalid pattern match mask, first byte must care */ -+ RT_ERR_PM_MODE, /* 0x000b0002, invalid pattern match mode */ -+ -+ /* 0x000cxxxx for input bandwidth control */ -+ RT_ERR_INBW_TICK_PERIOD = 0x000c0000, /* 0x000c0000, invalid tick period for input bandwidth control */ -+ RT_ERR_INBW_TOKEN_AMOUNT, /* 0x000c0001, invalid amount of token for input bandwidth control */ -+ RT_ERR_INBW_FCON_VALUE, /* 0x000c0002, invalid flow control ON threshold value for input bandwidth control */ -+ RT_ERR_INBW_FCOFF_VALUE, /* 0x000c0003, invalid flow control OFF threshold value for input bandwidth control */ -+ RT_ERR_INBW_FC_ALLOWANCE, /* 0x000c0004, invalid allowance of incoming packet for input bandwidth control */ -+ RT_ERR_INBW_RATE, /* 0x000c0005, invalid input bandwidth */ -+ -+ /* 0x000dxxxx for QoS */ -+ RT_ERR_QOS_1P_PRIORITY = 0x000d0000, /* 0x000d0000, invalid 802.1P priority */ -+ RT_ERR_QOS_DSCP_VALUE, /* 0x000d0001, invalid DSCP value */ -+ RT_ERR_QOS_INT_PRIORITY, /* 0x000d0002, invalid internal priority */ -+ RT_ERR_QOS_SEL_DSCP_PRI, /* 0x000d0003, invalid DSCP selection priority */ -+ RT_ERR_QOS_SEL_PORT_PRI, /* 0x000d0004, invalid port selection priority */ -+ RT_ERR_QOS_SEL_IN_ACL_PRI, /* 0x000d0005, invalid ingress ACL selection priority */ -+ RT_ERR_QOS_SEL_CLASS_PRI, /* 0x000d0006, invalid classifier selection priority */ -+ RT_ERR_QOS_EBW_RATE, /* 0x000d0007, invalid egress bandwidth rate */ -+ RT_ERR_QOS_SCHE_TYPE, /* 0x000d0008, invalid QoS scheduling type */ -+ RT_ERR_QOS_QUEUE_WEIGHT, /* 0x000d0009, invalid Queue weight */ -+ RT_ERR_QOS_SEL_PRI_SOURCE, /* 0x000d000a, invalid selection of priority source */ -+ -+ /* 0x000exxxx for port ability */ -+ RT_ERR_PHY_PAGE_ID = 0x000e0000, /* 0x000e0000, invalid PHY page id */ -+ RT_ERR_PHY_REG_ID, /* 0x000e0001, invalid PHY reg id */ -+ RT_ERR_PHY_DATAMASK, /* 0x000e0002, invalid PHY data mask */ -+ RT_ERR_PHY_AUTO_NEGO_MODE, /* 0x000e0003, invalid PHY auto-negotiation mode*/ -+ RT_ERR_PHY_SPEED, /* 0x000e0004, invalid PHY speed setting */ -+ RT_ERR_PHY_DUPLEX, /* 0x000e0005, invalid PHY duplex setting */ -+ RT_ERR_PHY_FORCE_ABILITY, /* 0x000e0006, invalid PHY force mode ability parameter */ -+ RT_ERR_PHY_FORCE_1000, /* 0x000e0007, invalid PHY force mode 1G speed setting */ -+ RT_ERR_PHY_TXRX, /* 0x000e0008, invalid PHY tx/rx */ -+ RT_ERR_PHY_ID, /* 0x000e0009, invalid PHY id */ -+ RT_ERR_PHY_RTCT_NOT_FINISH, /* 0x000e000a, PHY RTCT in progress */ -+ -+ /* 0x000fxxxx for mirror */ -+ RT_ERR_MIRROR_DIRECTION = 0x000f0000, /* 0x000f0000, invalid error mirror direction */ -+ RT_ERR_MIRROR_SESSION_FULL, /* 0x000f0001, mirroring session is full */ -+ RT_ERR_MIRROR_SESSION_NOEXIST, /* 0x000f0002, mirroring session not exist */ -+ RT_ERR_MIRROR_PORT_EXIST, /* 0x000f0003, mirroring port already exists */ -+ RT_ERR_MIRROR_PORT_NOT_EXIST, /* 0x000f0004, mirroring port does not exists */ -+ RT_ERR_MIRROR_PORT_FULL, /* 0x000f0005, Exceeds maximum number of supported mirroring port */ -+ -+ /* 0x0010xxxx for stat */ -+ RT_ERR_STAT_INVALID_GLOBAL_CNTR = 0x00100000, /* 0x00100000, Invalid Global Counter */ -+ RT_ERR_STAT_INVALID_PORT_CNTR, /* 0x00100001, Invalid Port Counter */ -+ RT_ERR_STAT_GLOBAL_CNTR_FAIL, /* 0x00100002, Could not retrieve/reset Global Counter */ -+ RT_ERR_STAT_PORT_CNTR_FAIL, /* 0x00100003, Could not retrieve/reset Port Counter */ -+ RT_ERR_STAT_INVALID_CNTR, /* 0x00100004, Invalid Counter */ -+ RT_ERR_STAT_CNTR_FAIL, /* 0x00100005, Could not retrieve/reset Counter */ -+ -+ /* 0x0011xxxx for dot1x */ -+ RT_ERR_DOT1X_INVALID_DIRECTION = 0x00110000, /* 0x00110000, Invalid Authentication Direction */ -+ RT_ERR_DOT1X_PORTBASEDPNEN, /* 0x00110001, Port-based enable port error */ -+ RT_ERR_DOT1X_PORTBASEDAUTH, /* 0x00110002, Port-based auth port error */ -+ RT_ERR_DOT1X_PORTBASEDOPDIR, /* 0x00110003, Port-based opdir error */ -+ RT_ERR_DOT1X_MACBASEDPNEN, /* 0x00110004, MAC-based enable port error */ -+ RT_ERR_DOT1X_MACBASEDOPDIR, /* 0x00110005, MAC-based opdir error */ -+ RT_ERR_DOT1X_PROC, /* 0x00110006, unauthorized behavior error */ -+ RT_ERR_DOT1X_GVLANIDX, /* 0x00110007, guest vlan index error */ -+ RT_ERR_DOT1X_GVLANTALK, /* 0x00110008, guest vlan OPDIR error */ -+ RT_ERR_DOT1X_MAC_PORT_MISMATCH, /* 0x00110009, Auth MAC and port mismatch error */ -+ -+ RT_ERR_END /* The symbol is the latest symbol */ -+} rt_error_code_t; -+ -+ -+#endif /* __COMMON_RT_ERROR_H__ */ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtk_hal.h b/drivers/net/phy/rtk/rtl8367c/include/rtk_hal.h -new file mode 100644 -index 000000000000..6ddb23f2ede7 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtk_hal.h -@@ -0,0 +1,44 @@ -+#ifndef __RTK_HAL_H__ -+#define __RTK_HAL_H__ -+#include "ra_ioctl.h" -+ -+#define RTK_SW_VID_RANGE 16 -+void rtk_hal_switch_init(void); -+void rtk_hal_dump_mib(void); -+void rtk_hal_dump_full_mib(void); -+int rtk_hal_dump_vlan(void); -+void rtk_hal_clear_vlan(void); -+int rtk_hal_set_vlan(struct ra_switch_ioctl_data *data); -+int rtk_hal_set_ingress_rate(struct ra_switch_ioctl_data *data); -+int rtk_hal_set_egress_rate(struct ra_switch_ioctl_data *data); -+void rtk_hal_dump_table(void); -+void rtk_hal_clear_table(void); -+void rtk_hal_get_phy_status(struct ra_switch_ioctl_data *data); -+void rtk_hal_set_port_mirror(struct ra_switch_ioctl_data *data); -+void rtk_hal_read_reg(struct ra_switch_ioctl_data *data); -+void rtk_hal_write_reg(struct ra_switch_ioctl_data *data); -+void rtk_hal_qos_en(struct ra_switch_ioctl_data *data); -+void rtk_hal_qos_set_table2type(struct ra_switch_ioctl_data *data); -+void rtk_hal_qos_get_table2type(struct ra_switch_ioctl_data *data); -+void rtk_hal_qos_set_port2table(struct ra_switch_ioctl_data *data); -+void rtk_hal_qos_get_port2table(struct ra_switch_ioctl_data *data); -+void rtk_hal_qos_set_port2pri(struct ra_switch_ioctl_data *data); -+void rtk_hal_qos_get_port2pri(struct ra_switch_ioctl_data *data); -+void rtk_hal_qos_set_dscp2pri(struct ra_switch_ioctl_data *data); -+void rtk_hal_qos_get_dscp2pri(struct ra_switch_ioctl_data *data); -+void rtk_hal_qos_set_pri2queue(struct ra_switch_ioctl_data *data); -+void rtk_hal_qos_get_pri2queue(struct ra_switch_ioctl_data *data); -+void rtk_hal_qos_set_queue_weight(struct ra_switch_ioctl_data *data); -+void rtk_hal_qos_get_queue_weight(struct ra_switch_ioctl_data *data); -+void rtk_hal_enable_igmpsnoop(struct ra_switch_ioctl_data *data); -+void rtk_hal_disable_igmpsnoop(void); -+void rtk_hal_set_phy_test_mode(struct ra_switch_ioctl_data *data); -+void rtk_hal_get_phy_reg(struct ra_switch_ioctl_data *data); -+void rtk_hal_set_phy_reg(struct ra_switch_ioctl_data *data); -+void rtk_hal_vlan_tag(struct ra_switch_ioctl_data *data); -+void rtk_hal_vlan_portpvid_set(rtk_port_t port, rtk_vlan_t pvid, rtk_pri_t priority); -+void rtk_hal_add_table(struct ra_switch_ioctl_data *data); -+void rtk_hal_del_table(struct ra_switch_ioctl_data *data); -+void rtk_hal_vlan_mode(struct ra_switch_ioctl_data *data); -+void rtk_hal_set_port_trunk(struct ra_switch_ioctl_data *data); -+#endif -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtk_switch.h b/drivers/net/phy/rtk/rtl8367c/include/rtk_switch.h -new file mode 100644 -index 000000000000..1c92188d6b19 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtk_switch.h -@@ -0,0 +1,741 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76336 $ -+ * $Date: 2017-03-09 10:41:21 +0800 (週四, 09 三月 2017) $ -+ * -+ * Purpose : RTK switch high-level API -+ * Feature : Here is a list of all functions and variables in this module. -+ * -+ */ -+ -+#ifndef __RTK_SWITCH_H__ -+#define __RTK_SWITCH_H__ -+ -+#include -+ -+#define UNDEFINE_PHY_PORT (0xFF) -+#define RTK_SWITCH_PORT_NUM (32) -+ -+#define MAXPKTLEN_CFG_ID_MAX (1) -+ -+#define RTK_SWITCH_MAX_PKTLEN (0x3FFF) -+ -+typedef enum init_state_e -+{ -+ INIT_NOT_COMPLETED = 0, -+ INIT_COMPLETED, -+ INIT_STATE_END -+} init_state_t; -+ -+typedef enum switch_chip_e -+{ -+ CHIP_RTL8367C = 0, -+ CHIP_RTL8370B, -+ CHIP_RTL8364B, -+ CHIP_RTL8363SC_VB, -+ CHIP_END -+}switch_chip_t; -+ -+typedef enum port_type_e -+{ -+ UTP_PORT = 0, -+ EXT_PORT, -+ UNKNOWN_PORT = 0xFF, -+ PORT_TYPE_END -+}port_type_t; -+ -+typedef struct rtk_switch_halCtrl_s -+{ -+ switch_chip_t switch_type; -+ rtk_uint32 l2p_port[RTK_SWITCH_PORT_NUM]; -+ rtk_uint32 p2l_port[RTK_SWITCH_PORT_NUM]; -+ port_type_t log_port_type[RTK_SWITCH_PORT_NUM]; -+ rtk_uint32 ptp_port[RTK_SWITCH_PORT_NUM]; -+ rtk_uint32 valid_portmask; -+ rtk_uint32 valid_utp_portmask; -+ rtk_uint32 valid_ext_portmask; -+ rtk_uint32 valid_cpu_portmask; -+ rtk_uint32 min_phy_port; -+ rtk_uint32 max_phy_port; -+ rtk_uint32 phy_portmask; -+ rtk_uint32 combo_logical_port; -+ rtk_uint32 hsg_logical_port; -+ rtk_uint32 sg_logical_portmask; -+ rtk_uint32 max_meter_id; -+ rtk_uint32 max_lut_addr_num; -+ rtk_uint32 trunk_group_mask; -+ -+}rtk_switch_halCtrl_t; -+ -+typedef enum rtk_switch_maxPktLen_linkSpeed_e { -+ MAXPKTLEN_LINK_SPEED_FE = 0, -+ MAXPKTLEN_LINK_SPEED_GE, -+ MAXPKTLEN_LINK_SPEED_END, -+} rtk_switch_maxPktLen_linkSpeed_t; -+ -+ -+/* UTIL MACRO */ -+#define RTK_CHK_INIT_STATE() \ -+ do \ -+ { \ -+ if(rtk_switch_initialState_get() != INIT_COMPLETED) \ -+ { \ -+ return RT_ERR_NOT_INIT; \ -+ } \ -+ }while(0) -+ -+#define RTK_CHK_PORT_VALID(__port__) \ -+ do \ -+ { \ -+ if(rtk_switch_logicalPortCheck(__port__) != RT_ERR_OK) \ -+ { \ -+ return RT_ERR_PORT_ID; \ -+ } \ -+ }while(0) -+ -+#define RTK_CHK_PORT_IS_UTP(__port__) \ -+ do \ -+ { \ -+ if(rtk_switch_isUtpPort(__port__) != RT_ERR_OK) \ -+ { \ -+ return RT_ERR_PORT_ID; \ -+ } \ -+ }while(0) -+ -+#define RTK_CHK_PORT_IS_EXT(__port__) \ -+ do \ -+ { \ -+ if(rtk_switch_isExtPort(__port__) != RT_ERR_OK) \ -+ { \ -+ return RT_ERR_PORT_ID; \ -+ } \ -+ }while(0) -+ -+#define RTK_CHK_PORT_IS_COMBO(__port__) \ -+ do \ -+ { \ -+ if(rtk_switch_isComboPort(__port__) != RT_ERR_OK) \ -+ { \ -+ return RT_ERR_PORT_ID; \ -+ } \ -+ }while(0) -+ -+#define RTK_CHK_PORT_IS_PTP(__port__) \ -+ do \ -+ { \ -+ if(rtk_switch_isPtpPort(__port__) != RT_ERR_OK) \ -+ { \ -+ return RT_ERR_PORT_ID; \ -+ } \ -+ }while(0) -+ -+#define RTK_CHK_PORTMASK_VALID(__portmask__) \ -+ do \ -+ { \ -+ if(rtk_switch_isPortMaskValid(__portmask__) != RT_ERR_OK) \ -+ { \ -+ return RT_ERR_PORT_MASK; \ -+ } \ -+ }while(0) -+ -+#define RTK_CHK_PORTMASK_VALID_ONLY_UTP(__portmask__) \ -+ do \ -+ { \ -+ if(rtk_switch_isPortMaskUtp(__portmask__) != RT_ERR_OK) \ -+ { \ -+ return RT_ERR_PORT_MASK; \ -+ } \ -+ }while(0) -+ -+#define RTK_CHK_PORTMASK_VALID_ONLY_EXT(__portmask__) \ -+ do \ -+ { \ -+ if(rtk_switch_isPortMaskExt(__portmask__) != RT_ERR_OK) \ -+ { \ -+ return RT_ERR_PORT_MASK; \ -+ } \ -+ }while(0) -+ -+#define RTK_CHK_TRUNK_GROUP_VALID(__grpId__) \ -+ do \ -+ { \ -+ if(rtk_switch_isValidTrunkGrpId(__grpId__) != RT_ERR_OK) \ -+ { \ -+ return RT_ERR_LA_TRUNK_ID; \ -+ } \ -+ }while(0) -+ -+#define RTK_PORTMASK_IS_PORT_SET(__portmask__, __port__) (((__portmask__).bits[0] & (0x00000001 << __port__)) ? 1 : 0) -+#define RTK_PORTMASK_IS_EMPTY(__portmask__) (((__portmask__).bits[0] == 0) ? 1 : 0) -+#define RTK_PORTMASK_CLEAR(__portmask__) ((__portmask__).bits[0] = 0) -+#define RTK_PORTMASK_PORT_SET(__portmask__, __port__) ((__portmask__).bits[0] |= (0x00000001 << __port__)) -+#define RTK_PORTMASK_PORT_CLEAR(__portmask__, __port__) ((__portmask__).bits[0] &= ~(0x00000001 << __port__)) -+#define RTK_PORTMASK_ALLPORT_SET(__portmask__) (rtk_switch_logPortMask_get(&__portmask__)) -+#define RTK_PORTMASK_SCAN(__portmask__, __port__) for(__port__ = 0; __port__ < RTK_SWITCH_PORT_NUM; __port__++) if(RTK_PORTMASK_IS_PORT_SET(__portmask__, __port__)) -+#define RTK_PORTMASK_COMPARE(__portmask_A__, __portmask_B__) ((__portmask_A__).bits[0] - (__portmask_B__).bits[0]) -+ -+#define RTK_SCAN_ALL_PHY_PORTMASK(__port__) for(__port__ = 0; __port__ < RTK_SWITCH_PORT_NUM; __port__++) if( (rtk_switch_phyPortMask_get() & (0x00000001 << __port__))) -+#define RTK_SCAN_ALL_LOG_PORT(__port__) for(__port__ = 0; __port__ < RTK_SWITCH_PORT_NUM; __port__++) if( rtk_switch_logicalPortCheck(__port__) == RT_ERR_OK) -+#define RTK_SCAN_ALL_LOG_PORTMASK(__portmask__) for((__portmask__).bits[0] = 0; (__portmask__).bits[0] < 0x7FFFF; (__portmask__).bits[0]++) if( rtk_switch_isPortMaskValid(&__portmask__) == RT_ERR_OK) -+ -+/* Port mask definition */ -+#define RTK_PHY_PORTMASK_ALL (rtk_switch_phyPortMask_get()) -+ -+/* Port definition*/ -+#define RTK_MAX_LOGICAL_PORT_ID (rtk_switch_maxLogicalPort_get()) -+ -+/* Function Name: -+ * rtk_switch_probe -+ * Description: -+ * Probe switch -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Switch probed -+ * RT_ERR_FAILED - Switch Unprobed. -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_switch_probe(switch_chip_t *pSwitchChip); -+ -+/* Function Name: -+ * rtk_switch_initialState_set -+ * Description: -+ * Set initial status -+ * Input: -+ * state - Initial state; -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Initialized -+ * RT_ERR_FAILED - Uninitialized -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_switch_initialState_set(init_state_t state); -+ -+/* Function Name: -+ * rtk_switch_initialState_get -+ * Description: -+ * Get initial status -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * INIT_COMPLETED - Initialized -+ * INIT_NOT_COMPLETED - Uninitialized -+ * Note: -+ * -+ */ -+extern init_state_t rtk_switch_initialState_get(void); -+ -+/* Function Name: -+ * rtk_switch_logicalPortCheck -+ * Description: -+ * Check logical port ID. -+ * Input: -+ * logicalPort - logical port ID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Port ID is correct -+ * RT_ERR_FAILED - Port ID is not correct -+ * RT_ERR_NOT_INIT - Not Initialize -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_switch_logicalPortCheck(rtk_port_t logicalPort); -+ -+/* Function Name: -+ * rtk_switch_isUtpPort -+ * Description: -+ * Check is logical port a UTP port -+ * Input: -+ * logicalPort - logical port ID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Port ID is a UTP port -+ * RT_ERR_FAILED - Port ID is not a UTP port -+ * RT_ERR_NOT_INIT - Not Initialize -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_switch_isUtpPort(rtk_port_t logicalPort); -+ -+/* Function Name: -+ * rtk_switch_isExtPort -+ * Description: -+ * Check is logical port a Extension port -+ * Input: -+ * logicalPort - logical port ID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Port ID is a EXT port -+ * RT_ERR_FAILED - Port ID is not a EXT port -+ * RT_ERR_NOT_INIT - Not Initialize -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_switch_isExtPort(rtk_port_t logicalPort); -+ -+/* Function Name: -+ * rtk_switch_isHsgPort -+ * Description: -+ * Check is logical port a HSG port -+ * Input: -+ * logicalPort - logical port ID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Port ID is a HSG port -+ * RT_ERR_FAILED - Port ID is not a HSG port -+ * RT_ERR_NOT_INIT - Not Initialize -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_switch_isHsgPort(rtk_port_t logicalPort); -+ -+/* Function Name: -+ * rtk_switch_isSgmiiPort -+ * Description: -+ * Check is logical port a SGMII port -+ * Input: -+ * logicalPort - logical port ID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Port ID is a SGMII port -+ * RT_ERR_FAILED - Port ID is not a SGMII port -+ * RT_ERR_NOT_INIT - Not Initialize -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_switch_isSgmiiPort(rtk_port_t logicalPort); -+ -+/* Function Name: -+ * rtk_switch_isCPUPort -+ * Description: -+ * Check is logical port a CPU port -+ * Input: -+ * logicalPort - logical port ID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Port ID is a CPU port -+ * RT_ERR_FAILED - Port ID is not a CPU port -+ * RT_ERR_NOT_INIT - Not Initialize -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_switch_isCPUPort(rtk_port_t logicalPort); -+ -+/* Function Name: -+ * rtk_switch_isComboPort -+ * Description: -+ * Check is logical port a Combo port -+ * Input: -+ * logicalPort - logical port ID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Port ID is a combo port -+ * RT_ERR_FAILED - Port ID is not a combo port -+ * RT_ERR_NOT_INIT - Not Initialize -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_switch_isComboPort(rtk_port_t logicalPort); -+ -+/* Function Name: -+ * rtk_switch_ComboPort_get -+ * Description: -+ * Get Combo port ID -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * Port ID of combo port -+ * Note: -+ * -+ */ -+extern rtk_uint32 rtk_switch_ComboPort_get(void); -+ -+/* Function Name: -+ * rtk_switch_isPtpPort -+ * Description: -+ * Check is logical port a PTP port -+ * Input: -+ * logicalPort - logical port ID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Port ID is a PTP port -+ * RT_ERR_FAILED - Port ID is not a PTP port -+ * RT_ERR_NOT_INIT - Not Initialize -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_switch_isPtpPort(rtk_port_t logicalPort); -+ -+/* Function Name: -+ * rtk_switch_port_L2P_get -+ * Description: -+ * Get physical port ID -+ * Input: -+ * logicalPort - logical port ID -+ * Output: -+ * None -+ * Return: -+ * Physical port ID -+ * Note: -+ * -+ */ -+extern rtk_uint32 rtk_switch_port_L2P_get(rtk_port_t logicalPort); -+ -+/* Function Name: -+ * rtk_switch_port_P2L_get -+ * Description: -+ * Get logical port ID -+ * Input: -+ * physicalPort - physical port ID -+ * Output: -+ * None -+ * Return: -+ * logical port ID -+ * Note: -+ * -+ */ -+extern rtk_port_t rtk_switch_port_P2L_get(rtk_uint32 physicalPort); -+ -+/* Function Name: -+ * rtk_switch_isPortMaskValid -+ * Description: -+ * Check portmask is valid or not -+ * Input: -+ * pPmask - logical port mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - port mask is valid -+ * RT_ERR_FAILED - port mask is not valid -+ * RT_ERR_NOT_INIT - Not Initialize -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_switch_isPortMaskValid(rtk_portmask_t *pPmask); -+ -+/* Function Name: -+ * rtk_switch_isPortMaskUtp -+ * Description: -+ * Check all ports in portmask are only UTP port -+ * Input: -+ * pPmask - logical port mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Only UTP port in port mask -+ * RT_ERR_FAILED - Not only UTP port in port mask -+ * RT_ERR_NOT_INIT - Not Initialize -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_switch_isPortMaskUtp(rtk_portmask_t *pPmask); -+ -+/* Function Name: -+ * rtk_switch_isPortMaskExt -+ * Description: -+ * Check all ports in portmask are only EXT port -+ * Input: -+ * pPmask - logical port mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Only EXT port in port mask -+ * RT_ERR_FAILED - Not only EXT port in port mask -+ * RT_ERR_NOT_INIT - Not Initialize -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_switch_isPortMaskExt(rtk_portmask_t *pPmask); -+ -+/* Function Name: -+ * rtk_switch_portmask_L2P_get -+ * Description: -+ * Get physical portmask from logical portmask -+ * Input: -+ * pLogicalPmask - logical port mask -+ * Output: -+ * pPhysicalPortmask - physical port mask -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_NOT_INIT - Not Initialize -+ * RT_ERR_NULL_POINTER - Null pointer -+ * RT_ERR_PORT_MASK - Error port mask -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_switch_portmask_L2P_get(rtk_portmask_t *pLogicalPmask, rtk_uint32 *pPhysicalPortmask); -+ -+/* Function Name: -+ * rtk_switch_portmask_P2L_get -+ * Description: -+ * Get logical portmask from physical portmask -+ * Input: -+ * physicalPortmask - physical port mask -+ * Output: -+ * pLogicalPmask - logical port mask -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_NOT_INIT - Not Initialize -+ * RT_ERR_NULL_POINTER - Null pointer -+ * RT_ERR_PORT_MASK - Error port mask -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_switch_portmask_P2L_get(rtk_uint32 physicalPortmask, rtk_portmask_t *pLogicalPmask); -+ -+/* Function Name: -+ * rtk_switch_phyPortMask_get -+ * Description: -+ * Get physical portmask -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * 0x00 - Not Initialize -+ * Other value - Physical port mask -+ * Note: -+ * -+ */ -+rtk_uint32 rtk_switch_phyPortMask_get(void); -+ -+/* Function Name: -+ * rtk_switch_logPortMask_get -+ * Description: -+ * Get Logical portmask -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_NOT_INIT - Not Initialize -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_switch_logPortMask_get(rtk_portmask_t *pPortmask); -+ -+/* Function Name: -+ * rtk_switch_init -+ * Description: -+ * Set chip to default configuration environment -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * The API can set chip registers to default configuration for different release chip model. -+ */ -+extern rtk_api_ret_t rtk_switch_init(void); -+ -+/* Function Name: -+ * rtk_switch_portMaxPktLen_set -+ * Description: -+ * Set Max packet length -+ * Input: -+ * port - Port ID -+ * speed - Speed -+ * cfgId - Configuration ID -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * Note: -+ */ -+extern rtk_api_ret_t rtk_switch_portMaxPktLen_set(rtk_port_t port, rtk_switch_maxPktLen_linkSpeed_t speed, rtk_uint32 cfgId); -+ -+/* Function Name: -+ * rtk_switch_portMaxPktLen_get -+ * Description: -+ * Get Max packet length -+ * Input: -+ * port - Port ID -+ * speed - Speed -+ * Output: -+ * pCfgId - Configuration ID -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * Note: -+ */ -+extern rtk_api_ret_t rtk_switch_portMaxPktLen_get(rtk_port_t port, rtk_switch_maxPktLen_linkSpeed_t speed, rtk_uint32 *pCfgId); -+ -+/* Function Name: -+ * rtk_switch_maxPktLenCfg_set -+ * Description: -+ * Set Max packet length configuration -+ * Input: -+ * cfgId - Configuration ID -+ * pktLen - Max packet length -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * Note: -+ */ -+extern rtk_api_ret_t rtk_switch_maxPktLenCfg_set(rtk_uint32 cfgId, rtk_uint32 pktLen); -+ -+/* Function Name: -+ * rtk_switch_maxPktLenCfg_get -+ * Description: -+ * Get Max packet length configuration -+ * Input: -+ * cfgId - Configuration ID -+ * pPktLen - Max packet length -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * Note: -+ */ -+extern rtk_api_ret_t rtk_switch_maxPktLenCfg_get(rtk_uint32 cfgId, rtk_uint32 *pPktLen); -+ -+/* Function Name: -+ * rtk_switch_greenEthernet_set -+ * Description: -+ * Set all Ports Green Ethernet state. -+ * Input: -+ * enable - Green Ethernet state. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_ENABLE - Invalid enable input. -+ * Note: -+ * This API can set all Ports Green Ethernet state. -+ * The configuration is as following: -+ * - DISABLE -+ * - ENABLE -+ */ -+extern rtk_api_ret_t rtk_switch_greenEthernet_set(rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_switch_greenEthernet_get -+ * Description: -+ * Get all Ports Green Ethernet state. -+ * Input: -+ * None -+ * Output: -+ * pEnable - Green Ethernet state. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * This API can get Green Ethernet state. -+ */ -+extern rtk_api_ret_t rtk_switch_greenEthernet_get(rtk_enable_t *pEnable); -+ -+/* Function Name: -+ * rtk_switch_maxLogicalPort_get -+ * Description: -+ * Get Max logical port ID -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * Max logical port -+ * Note: -+ * This API can get max logical port -+ */ -+extern rtk_port_t rtk_switch_maxLogicalPort_get(void); -+ -+/* Function Name: -+ * rtk_switch_maxMeterId_get -+ * Description: -+ * Get Max Meter ID -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * 0x00 - Not Initialize -+ * Other value - Max Meter ID -+ * Note: -+ * -+ */ -+extern rtk_uint32 rtk_switch_maxMeterId_get(void); -+ -+/* Function Name: -+ * rtk_switch_maxLutAddrNumber_get -+ * Description: -+ * Get Max LUT Address number -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * 0x00 - Not Initialize -+ * Other value - Max LUT Address number -+ * Note: -+ * -+ */ -+extern rtk_uint32 rtk_switch_maxLutAddrNumber_get(void); -+ -+/* Function Name: -+ * rtk_switch_isValidTrunkGrpId -+ * Description: -+ * Check if trunk group is valid or not -+ * Input: -+ * grpId - Group ID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Trunk Group ID is valid -+ * RT_ERR_LA_TRUNK_ID - Trunk Group ID is not valid -+ * Note: -+ * -+ */ -+rtk_uint32 rtk_switch_isValidTrunkGrpId(rtk_uint32 grpId); -+ -+int gsw_debug_proc_init(void); -+void gsw_debug_proc_exit(void); -+int rtl8367s_swconfig_init(void (*reset_func)(void)); -+ -+#endif -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtk_types.h b/drivers/net/phy/rtk/rtl8367c/include/rtk_types.h -new file mode 100644 -index 000000000000..cafc7ff9da36 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtk_types.h -@@ -0,0 +1,155 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level type enum definition. -+ * Feature : -+ * -+ */ -+ -+#ifndef _RTL8367C_TYPES_H_ -+#define _RTL8367C_TYPES_H_ -+ -+//#include -+ -+typedef unsigned long long rtk_uint64; -+typedef long long rtk_int64; -+typedef unsigned int rtk_uint32; -+typedef int rtk_int32; -+typedef unsigned short rtk_uint16; -+typedef short rtk_int16; -+typedef unsigned char rtk_uint8; -+typedef char rtk_int8; -+ -+#define CONST_T const -+ -+#define RTK_TOTAL_NUM_OF_WORD_FOR_1BIT_PORT_LIST 1 -+ -+#define RTK_MAX_NUM_OF_PORT 8 -+#define RTK_PORT_ID_MAX (RTK_MAX_NUM_OF_PORT-1) -+#define RTK_PHY_ID_MAX (RTK_MAX_NUM_OF_PORT-4) -+#define RTK_MAX_PORT_MASK 0xFF -+ -+#define RTK_WHOLE_SYSTEM 0xFF -+ -+typedef struct rtk_portmask_s -+{ -+ rtk_uint32 bits[RTK_TOTAL_NUM_OF_WORD_FOR_1BIT_PORT_LIST]; -+} rtk_portmask_t; -+ -+typedef enum rtk_enable_e -+{ -+ DISABLED = 0, -+ ENABLED, -+ RTK_ENABLE_END -+} rtk_enable_t; -+ -+#ifndef ETHER_ADDR_LEN -+#define ETHER_ADDR_LEN 6 -+#endif -+ -+/* Ethernet address type */ -+typedef struct rtk_mac_s -+{ -+ rtk_uint8 octet[ETHER_ADDR_LEN]; -+} rtk_mac_t; -+ -+typedef rtk_uint32 rtk_pri_t; /* priority value */ -+typedef rtk_uint32 rtk_qid_t; /* queue id type */ -+typedef rtk_uint32 rtk_data_t; -+typedef rtk_uint32 rtk_dscp_t; /* dscp vlaue */ -+typedef rtk_uint32 rtk_fid_t; /* filter id type */ -+typedef rtk_uint32 rtk_vlan_t; /* vlan id type */ -+typedef rtk_uint32 rtk_mac_cnt_t; /* MAC count type */ -+typedef rtk_uint32 rtk_meter_id_t; /* meter id type */ -+typedef rtk_uint32 rtk_rate_t; /* rate type */ -+ -+typedef enum rtk_port_e -+{ -+ UTP_PORT0 = 0, -+ UTP_PORT1, -+ UTP_PORT2, -+ UTP_PORT3, -+ UTP_PORT4, -+ UTP_PORT5, -+ UTP_PORT6, -+ UTP_PORT7, -+ -+ EXT_PORT0 = 16, -+ EXT_PORT1, -+ EXT_PORT2, -+ -+ UNDEFINE_PORT = 30, -+ RTK_PORT_MAX = 31 -+} rtk_port_t; -+ -+ -+#ifndef _RTL_TYPES_H -+ -+#if 0 -+typedef unsigned long long uint64; -+typedef long long int64; -+typedef unsigned int uint32; -+typedef int int32; -+typedef unsigned short uint16; -+typedef short int16; -+typedef unsigned char uint8; -+typedef char int8; -+#endif -+ -+typedef rtk_uint32 ipaddr_t; -+typedef rtk_uint32 memaddr; -+ -+#ifndef ETHER_ADDR_LEN -+#define ETHER_ADDR_LEN 6 -+#endif -+ -+typedef struct ether_addr_s { -+ rtk_uint8 octet[ETHER_ADDR_LEN]; -+} ether_addr_t; -+ -+#ifdef __KERNEL__ -+#define rtlglue_printf printk -+#else -+#define rtlglue_printf printf -+#endif -+#define PRINT rtlglue_printf -+#endif /*_RTL_TYPES_H*/ -+ -+/* type abstraction */ -+#ifdef EMBEDDED_SUPPORT -+ -+typedef rtk_int16 rtk_api_ret_t; -+typedef rtk_int16 ret_t; -+typedef rtk_uint32 rtk_u_long; -+ -+#else -+ -+typedef rtk_int32 rtk_api_ret_t; -+typedef rtk_int32 ret_t; -+typedef rtk_uint64 rtk_u_long_t; -+ -+#endif -+ -+#ifndef NULL -+#define NULL 0 -+#endif -+ -+#ifndef TRUE -+#define TRUE 1 -+#endif -+ -+#ifndef FALSE -+#define FALSE 0 -+#endif -+ -+#define CONST const -+#endif /* _RTL8367C_TYPES_H_ */ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv.h -new file mode 100644 -index 000000000000..55cb41b06728 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv.h -@@ -0,0 +1,129 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : -+ * -+ */ -+ -+ -+#ifndef _RTL8367C_ASICDRV_H_ -+#define _RTL8367C_ASICDRV_H_ -+ -+#include -+#include -+#include -+#include -+ -+#define RTL8367C_REGBITLENGTH 16 -+#define RTL8367C_REGDATAMAX 0xFFFF -+ -+#define RTL8367C_VIDMAX 0xFFF -+#define RTL8367C_EVIDMAX 0x1FFF -+#define RTL8367C_CVIDXNO 32 -+#define RTL8367C_CVIDXMAX (RTL8367C_CVIDXNO-1) -+ -+#define RTL8367C_PRIMAX 7 -+#define RTL8367C_DSCPMAX 63 -+ -+#define RTL8367C_PORTNO 11 -+#define RTL8367C_PORTIDMAX (RTL8367C_PORTNO-1) -+#define RTL8367C_PMSKMAX ((1<<(RTL8367C_PORTNO))-1) -+#define RTL8367C_PORTMASK 0x7FF -+ -+#define RTL8367C_PHYNO 5 -+#define RTL8367C_PHYIDMAX (RTL8367C_PHYNO-1) -+ -+#define RTL8367C_SVIDXNO 64 -+#define RTL8367C_SVIDXMAX (RTL8367C_SVIDXNO-1) -+#define RTL8367C_MSTIMAX 15 -+ -+#define RTL8367C_METERNO 64 -+#define RTL8367C_METERMAX (RTL8367C_METERNO-1) -+#define RTL8367C_METERBUCKETSIZEMAX 0xFFFF -+ -+#define RTL8367C_QUEUENO 8 -+#define RTL8367C_QIDMAX (RTL8367C_QUEUENO-1) -+ -+#define RTL8367C_PHY_BUSY_CHECK_COUNTER 1000 -+ -+#define RTL8367C_QOS_GRANULARTY_MAX 0x7FFFF -+#define RTL8367C_QOS_GRANULARTY_LSB_MASK 0xFFFF -+#define RTL8367C_QOS_GRANULARTY_LSB_OFFSET 0 -+#define RTL8367C_QOS_GRANULARTY_MSB_MASK 0x70000 -+#define RTL8367C_QOS_GRANULARTY_MSB_OFFSET 16 -+ -+#define RTL8367C_QOS_GRANULARTY_UNIT_KBPS 8 -+ -+#define RTL8367C_QOS_RATE_INPUT_MAX (0x1FFFF * 8) -+#define RTL8367C_QOS_RATE_INPUT_MAX_HSG (0x7FFFF * 8) -+#define RTL8367C_QOS_RATE_INPUT_MIN 8 -+#define RTL8367C_QOS_PPS_INPUT_MAX (0x7FFFF) -+#define RTL8367C_QOS_PPS_INPUT_MIN 1 -+ -+#define RTL8367C_QUEUE_MASK 0xFF -+ -+#define RTL8367C_EFIDMAX 0x7 -+#define RTL8367C_FIDMAX 0xF -+ -+#define RTL8367C_EAV_SECONDMAX 0xFFFFFFFF -+#define RTL8367C_EAV_NANOSECONDMAX 0x3B9AC9FF -+ -+ -+/* the above macro is generated by genDotH */ -+#define RTL8367C_VALID_REG_NO 3869 -+ -+/*======================================================================= -+ * Enum -+ *========================================================================*/ -+enum RTL8367C_TABLE_ACCESS_OP -+{ -+ TB_OP_READ = 0, -+ TB_OP_WRITE -+}; -+ -+enum RTL8367C_TABLE_ACCESS_TARGET -+{ -+ TB_TARGET_ACLRULE = 1, -+ TB_TARGET_ACLACT, -+ TB_TARGET_CVLAN, -+ TB_TARGET_L2, -+ TB_TARGET_IGMP_GROUP -+}; -+ -+#define RTL8367C_TABLE_ACCESS_REG_DATA(op, target) ((op << 3) | target) -+ -+/*======================================================================= -+ * Structures -+ *========================================================================*/ -+ -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+extern ret_t rtl8367c_setAsicRegBit(rtk_uint32 reg, rtk_uint32 bit, rtk_uint32 value); -+extern ret_t rtl8367c_getAsicRegBit(rtk_uint32 reg, rtk_uint32 bit, rtk_uint32 *pValue); -+ -+extern ret_t rtl8367c_setAsicRegBits(rtk_uint32 reg, rtk_uint32 bits, rtk_uint32 value); -+extern ret_t rtl8367c_getAsicRegBits(rtk_uint32 reg, rtk_uint32 bits, rtk_uint32 *pValue); -+ -+extern ret_t rtl8367c_setAsicReg(rtk_uint32 reg, rtk_uint32 value); -+extern ret_t rtl8367c_getAsicReg(rtk_uint32 reg, rtk_uint32 *pValue); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+ -+ -+#endif /*#ifndef _RTL8367C_ASICDRV_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_acl.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_acl.h -new file mode 100644 -index 000000000000..8ae69ac332c2 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_acl.h -@@ -0,0 +1,231 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : ACL related function drivers -+ * -+ */ -+ -+#ifndef _RTL8367C_ASICDRV_ACL_H_ -+#define _RTL8367C_ASICDRV_ACL_H_ -+ -+#include -+ -+#define RTL8367C_ACLRULENO 96 -+ -+#define RTL8367C_ACLRULEMAX (RTL8367C_ACLRULENO-1) -+#define RTL8367C_ACLRULEFIELDNO 8 -+#define RTL8367C_ACLTEMPLATENO 5 -+#define RTL8367C_ACLTYPEMAX (RTL8367C_ACLTEMPLATENO-1) -+ -+#define RTL8367C_ACLRULETBLEN 9 -+#define RTL8367C_ACLACTTBLEN 4 -+#define RTL8367C_ACLRULETBADDR(type, rule) ((type << 6) | rule) -+#define RTL8367C_ACLRULETBADDR2(type, rule) ((type << 5) | (rule + 64)) -+ -+#define ACL_ACT_CVLAN_ENABLE_MASK 0x1 -+#define ACL_ACT_SVLAN_ENABLE_MASK 0x2 -+#define ACL_ACT_PRIORITY_ENABLE_MASK 0x4 -+#define ACL_ACT_POLICING_ENABLE_MASK 0x8 -+#define ACL_ACT_FWD_ENABLE_MASK 0x10 -+#define ACL_ACT_INTGPIO_ENABLE_MASK 0x20 -+ -+#define RTL8367C_ACLRULETAGBITS 5 -+ -+#define RTL8367C_ACLRANGENO 16 -+ -+#define RTL8367C_ACLRANGEMAX (RTL8367C_ACLRANGENO-1) -+ -+#define RTL8367C_ACL_PORTRANGEMAX (0xFFFF) -+#define RTL8367C_ACL_ACT_TABLE_LEN (4) -+ -+enum ACLTCAMTYPES -+{ -+ CAREBITS= 0, -+ DATABITS -+}; -+ -+typedef enum aclFwdAct -+{ -+ RTL8367C_ACL_FWD_MIRROR = 0, -+ RTL8367C_ACL_FWD_REDIRECT, -+ RTL8367C_ACL_FWD_MIRRORFUNTION, -+ RTL8367C_ACL_FWD_TRAP, -+} rtl8367c_aclFwd_t; -+ -+enum ACLFIELDTYPES -+{ -+ ACL_UNUSED, -+ ACL_DMAC0, -+ ACL_DMAC1, -+ ACL_DMAC2, -+ ACL_SMAC0, -+ ACL_SMAC1, -+ ACL_SMAC2, -+ ACL_ETHERTYPE, -+ ACL_STAG, -+ ACL_CTAG, -+ ACL_IP4SIP0 = 0x10, -+ ACL_IP4SIP1, -+ ACL_IP4DIP0, -+ ACL_IP4DIP1, -+ ACL_IP6SIP0WITHIPV4 = 0x20, -+ ACL_IP6SIP1WITHIPV4, -+ ACL_IP6DIP0WITHIPV4 = 0x28, -+ ACL_IP6DIP1WITHIPV4, -+ ACL_VIDRANGE = 0x30, -+ ACL_IPRANGE, -+ ACL_PORTRANGE, -+ ACL_FIELD_VALID, -+ ACL_FIELD_SELECT00 = 0x40, -+ ACL_FIELD_SELECT01, -+ ACL_FIELD_SELECT02, -+ ACL_FIELD_SELECT03, -+ ACL_FIELD_SELECT04, -+ ACL_FIELD_SELECT05, -+ ACL_FIELD_SELECT06, -+ ACL_FIELD_SELECT07, -+ ACL_FIELD_SELECT08, -+ ACL_FIELD_SELECT09, -+ ACL_FIELD_SELECT10, -+ ACL_FIELD_SELECT11, -+ ACL_FIELD_SELECT12, -+ ACL_FIELD_SELECT13, -+ ACL_FIELD_SELECT14, -+ ACL_FIELD_SELECT15, -+ ACL_TCPSPORT = 0x80, -+ ACL_TCPDPORT, -+ ACL_TCPFLAG, -+ ACL_UDPSPORT, -+ ACL_UDPDPORT, -+ ACL_ICMPCODETYPE, -+ ACL_IGMPTYPE, -+ ACL_SPORT, -+ ACL_DPORT, -+ ACL_IP4TOSPROTO, -+ ACL_IP4FLAGOFF, -+ ACL_TCNH, -+ ACL_CPUTAG, -+ ACL_L2PAYLOAD, -+ ACL_IP6SIP0, -+ ACL_IP6SIP1, -+ ACL_IP6SIP2, -+ ACL_IP6SIP3, -+ ACL_IP6SIP4, -+ ACL_IP6SIP5, -+ ACL_IP6SIP6, -+ ACL_IP6SIP7, -+ ACL_IP6DIP0, -+ ACL_IP6DIP1, -+ ACL_IP6DIP2, -+ ACL_IP6DIP3, -+ ACL_IP6DIP4, -+ ACL_IP6DIP5, -+ ACL_IP6DIP6, -+ ACL_IP6DIP7, -+ ACL_TYPE_END -+}; -+ -+struct acl_rule_smi_st{ -+ rtk_uint16 rule_info; -+ rtk_uint16 field[RTL8367C_ACLRULEFIELDNO]; -+}; -+ -+struct acl_rule_smi_ext_st{ -+ rtk_uint16 rule_info; -+}; -+ -+typedef struct ACLRULESMI{ -+ struct acl_rule_smi_st care_bits; -+ rtk_uint16 valid:1; -+ struct acl_rule_smi_st data_bits; -+ -+ struct acl_rule_smi_ext_st care_bits_ext; -+ struct acl_rule_smi_ext_st data_bits_ext; -+}rtl8367c_aclrulesmi; -+ -+struct acl_rule_st{ -+ rtk_uint16 active_portmsk:11; -+ rtk_uint16 type:3; -+ rtk_uint16 tag_exist:5; -+ rtk_uint16 field[RTL8367C_ACLRULEFIELDNO]; -+}; -+ -+typedef struct ACLRULE{ -+ struct acl_rule_st data_bits; -+ rtk_uint16 valid:1; -+ struct acl_rule_st care_bits; -+}rtl8367c_aclrule; -+ -+ -+typedef struct rtl8367c_acltemplate_s{ -+ rtk_uint8 field[8]; -+}rtl8367c_acltemplate_t; -+ -+ -+typedef struct acl_act_s{ -+ rtk_uint16 cvidx_cact:7; -+ rtk_uint16 cact:2; -+ rtk_uint16 svidx_sact:7; -+ rtk_uint16 sact:2; -+ -+ -+ rtk_uint16 aclmeteridx:7; -+ rtk_uint16 fwdpmask:11; -+ rtk_uint16 fwdact:2; -+ -+ rtk_uint16 pridx:7; -+ rtk_uint16 priact:2; -+ rtk_uint16 gpio_pin:4; -+ rtk_uint16 gpio_en:1; -+ rtk_uint16 aclint:1; -+ -+ rtk_uint16 cact_ext:2; -+ rtk_uint16 fwdact_ext:1; -+ rtk_uint16 tag_fmt:2; -+}rtl8367c_acl_act_t; -+ -+typedef struct acl_rule_union_s -+{ -+ rtl8367c_aclrule aclRule; -+ rtl8367c_acl_act_t aclAct; -+ rtk_uint32 aclActCtrl; -+ rtk_uint32 aclNot; -+}rtl8367c_acl_rule_union_t; -+ -+ -+extern ret_t rtl8367c_setAsicAcl(rtk_uint32 port, rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicAcl(rtk_uint32 port, rtk_uint32* pEnabled); -+extern ret_t rtl8367c_setAsicAclUnmatchedPermit(rtk_uint32 port, rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicAclUnmatchedPermit(rtk_uint32 port, rtk_uint32* pEnabled); -+extern ret_t rtl8367c_setAsicAclRule(rtk_uint32 index, rtl8367c_aclrule *pAclRule); -+extern ret_t rtl8367c_getAsicAclRule(rtk_uint32 index, rtl8367c_aclrule *pAclRule); -+extern ret_t rtl8367c_setAsicAclNot(rtk_uint32 index, rtk_uint32 not); -+extern ret_t rtl8367c_getAsicAclNot(rtk_uint32 index, rtk_uint32* pNot); -+extern ret_t rtl8367c_setAsicAclTemplate(rtk_uint32 index, rtl8367c_acltemplate_t* pAclType); -+extern ret_t rtl8367c_getAsicAclTemplate(rtk_uint32 index, rtl8367c_acltemplate_t *pAclType); -+extern ret_t rtl8367c_setAsicAclAct(rtk_uint32 index, rtl8367c_acl_act_t* pAclAct); -+extern ret_t rtl8367c_getAsicAclAct(rtk_uint32 index, rtl8367c_acl_act_t *pAclAct); -+extern ret_t rtl8367c_setAsicAclActCtrl(rtk_uint32 index, rtk_uint32 aclActCtrl); -+extern ret_t rtl8367c_getAsicAclActCtrl(rtk_uint32 index, rtk_uint32 *aclActCtrl); -+extern ret_t rtl8367c_setAsicAclPortRange(rtk_uint32 index, rtk_uint32 type, rtk_uint32 upperPort, rtk_uint32 lowerPort); -+extern ret_t rtl8367c_getAsicAclPortRange(rtk_uint32 index, rtk_uint32* pType, rtk_uint32* pUpperPort, rtk_uint32* pLowerPort); -+extern ret_t rtl8367c_setAsicAclVidRange(rtk_uint32 index, rtk_uint32 type, rtk_uint32 upperVid, rtk_uint32 lowerVid); -+extern ret_t rtl8367c_getAsicAclVidRange(rtk_uint32 index, rtk_uint32* pType, rtk_uint32* pUpperVid, rtk_uint32* pLowerVid); -+extern ret_t rtl8367c_setAsicAclIpRange(rtk_uint32 index, rtk_uint32 type, ipaddr_t upperIp, ipaddr_t lowerIp); -+extern ret_t rtl8367c_getAsicAclIpRange(rtk_uint32 index, rtk_uint32* pType, ipaddr_t* pUpperIp, ipaddr_t* pLowerIp); -+extern ret_t rtl8367c_setAsicAclGpioPolarity(rtk_uint32 polarity); -+extern ret_t rtl8367c_getAsicAclGpioPolarity(rtk_uint32* pPolarity); -+ -+#endif /*_RTL8367C_ASICDRV_ACL_H_*/ -+ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_cputag.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_cputag.h -new file mode 100644 -index 000000000000..982e2c4bfcdb ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_cputag.h -@@ -0,0 +1,49 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Proprietary CPU-tag related function drivers -+ * -+ */ -+ -+#ifndef _RTL8367C_ASICDRV_CPUTAG_H_ -+#define _RTL8367C_ASICDRV_CPUTAG_H_ -+ -+#include -+ -+enum CPUTAG_INSERT_MODE -+{ -+ CPUTAG_INSERT_TO_ALL = 0, -+ CPUTAG_INSERT_TO_TRAPPING, -+ CPUTAG_INSERT_TO_NO, -+ CPUTAG_INSERT_END -+}; -+ -+extern ret_t rtl8367c_setAsicCputagEnable(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicCputagEnable(rtk_uint32 *pEnabled); -+extern ret_t rtl8367c_setAsicCputagTrapPort(rtk_uint32 port); -+extern ret_t rtl8367c_getAsicCputagTrapPort(rtk_uint32 *pPort); -+extern ret_t rtl8367c_setAsicCputagPortmask(rtk_uint32 portmask); -+extern ret_t rtl8367c_getAsicCputagPortmask(rtk_uint32 *pPmsk); -+extern ret_t rtl8367c_setAsicCputagInsertMode(rtk_uint32 mode); -+extern ret_t rtl8367c_getAsicCputagInsertMode(rtk_uint32 *pMode); -+extern ret_t rtl8367c_setAsicCputagPriorityRemapping(rtk_uint32 srcPri, rtk_uint32 newPri); -+extern ret_t rtl8367c_getAsicCputagPriorityRemapping(rtk_uint32 srcPri, rtk_uint32 *pNewPri); -+extern ret_t rtl8367c_setAsicCputagPosition(rtk_uint32 position); -+extern ret_t rtl8367c_getAsicCputagPosition(rtk_uint32* pPostion); -+extern ret_t rtl8367c_setAsicCputagMode(rtk_uint32 mode); -+extern ret_t rtl8367c_getAsicCputagMode(rtk_uint32 *pMode); -+extern ret_t rtl8367c_setAsicCputagRxMinLength(rtk_uint32 mode); -+extern ret_t rtl8367c_getAsicCputagRxMinLength(rtk_uint32 *pMode); -+ -+#endif /*#ifndef _RTL8367C_ASICDRV_CPUTAG_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_dot1x.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_dot1x.h -new file mode 100644 -index 000000000000..7639ae782b5c ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_dot1x.h -@@ -0,0 +1,52 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : 802.1X related functions -+ * -+ */ -+ -+#ifndef _RTL8367C_ASICDRV_DOT1X_H_ -+#define _RTL8367C_ASICDRV_DOT1X_H_ -+ -+#include -+ -+enum DOT1X_UNAUTH_BEHAV -+{ -+ DOT1X_UNAUTH_DROP = 0, -+ DOT1X_UNAUTH_TRAP, -+ DOT1X_UNAUTH_GVLAN, -+ DOT1X_UNAUTH_END -+}; -+ -+extern ret_t rtl8367c_setAsic1xPBEnConfig(rtk_uint32 port, rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsic1xPBEnConfig(rtk_uint32 port, rtk_uint32 *pEnabled); -+extern ret_t rtl8367c_setAsic1xPBAuthConfig(rtk_uint32 port, rtk_uint32 auth); -+extern ret_t rtl8367c_getAsic1xPBAuthConfig(rtk_uint32 port, rtk_uint32 *pAuth); -+extern ret_t rtl8367c_setAsic1xPBOpdirConfig(rtk_uint32 port, rtk_uint32 opdir); -+extern ret_t rtl8367c_getAsic1xPBOpdirConfig(rtk_uint32 port, rtk_uint32 *pOpdir); -+extern ret_t rtl8367c_setAsic1xMBEnConfig(rtk_uint32 port, rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsic1xMBEnConfig(rtk_uint32 port, rtk_uint32 *pEnabled); -+extern ret_t rtl8367c_setAsic1xMBOpdirConfig(rtk_uint32 opdir); -+extern ret_t rtl8367c_getAsic1xMBOpdirConfig(rtk_uint32 *pOpdir); -+extern ret_t rtl8367c_setAsic1xProcConfig(rtk_uint32 port, rtk_uint32 proc); -+extern ret_t rtl8367c_getAsic1xProcConfig(rtk_uint32 port, rtk_uint32 *pProc); -+extern ret_t rtl8367c_setAsic1xGuestVidx(rtk_uint32 index); -+extern ret_t rtl8367c_getAsic1xGuestVidx(rtk_uint32 *pIndex); -+extern ret_t rtl8367c_setAsic1xGVOpdir(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsic1xGVOpdir(rtk_uint32 *pEnabled); -+extern ret_t rtl8367c_setAsic1xTrapPriority(rtk_uint32 priority); -+extern ret_t rtl8367c_getAsic1xTrapPriority(rtk_uint32 *pPriority); -+ -+ -+#endif /*_RTL8367C_ASICDRV_DOT1X_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eav.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eav.h -new file mode 100644 -index 000000000000..b633f66fb0c0 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eav.h -@@ -0,0 +1,109 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Ethernet AV related functions -+ * -+ */ -+ -+#ifndef _RTL8367C_ASICDRV_EAV_H_ -+#define _RTL8367C_ASICDRV_EAV_H_ -+ -+#include -+ -+typedef enum RTL8367C_PTP_TIME_CMD_E -+{ -+ PTP_TIME_READ = 0, -+ PTP_TIME_WRITE, -+ PTP_TIME_INC, -+ PTP_TIME_DEC, -+ PTP_TIME_CMD_END -+}RTL8367C_PTP_TIME_CMD; -+ -+typedef enum RTL8367C_PTP_TIME_ADJ_E -+{ -+ PTP_TIME_ADJ_INC = 0, -+ PTP_TIME_ADJ_DEC, -+ PTP_TIME_ADJ_END -+}RTL8367C_PTP_TIME_ADJ; -+ -+typedef enum RTL8367C_PTP_TIME_CTRL_E -+{ -+ PTP_TIME_CTRL_STOP = 0, -+ PTP_TIME_CTRL_START, -+ PTP_TIME_CTRL_END -+}RTL8367C_PTP_TIME_CTRL; -+ -+typedef enum RTL8367C_PTP_INTR_IMRS_E -+{ -+ PTP_IMRS_TX_SYNC, -+ PTP_IMRS_TX_DELAY_REQ, -+ PTP_IMRS_TX_PDELAY_REQ, -+ PTP_IMRS_TX_PDELAY_RESP, -+ PTP_IMRS_RX_SYNC, -+ PTP_IMRS_RX_DELAY_REQ, -+ PTP_IMRS_RX_PDELAY_REQ, -+ PTP_IMRS_RX_PDELAY_RESP, -+ PTP_IMRS_END, -+}RTL8367C_PTP_INTR_IMRS; -+ -+ -+typedef enum RTL8367C_PTP_PKT_TYPE_E -+{ -+ PTP_PKT_TYPE_TX_SYNC, -+ PTP_PKT_TYPE_TX_DELAY_REQ, -+ PTP_PKT_TYPE_TX_PDELAY_REQ, -+ PTP_PKT_TYPE_TX_PDELAY_RESP, -+ PTP_PKT_TYPE_RX_SYNC, -+ PTP_PKT_TYPE_RX_DELAY_REQ, -+ PTP_PKT_TYPE_RX_PDELAY_REQ, -+ PTP_PKT_TYPE_RX_PDELAY_RESP, -+ PTP_PKT_TYPE_END, -+}RTL8367C_PTP_PKT_TYPE; -+ -+typedef struct rtl8367c_ptp_time_stamp_s{ -+ rtk_uint32 sequence_id; -+ rtk_uint32 second; -+ rtk_uint32 nano_second; -+}rtl8367c_ptp_time_stamp_t; -+ -+#define RTL8367C_PTP_INTR_MASK 0xFF -+ -+#define RTL8367C_PTP_PORT_MASK 0x3FF -+ -+extern ret_t rtl8367c_setAsicEavMacAddress(ether_addr_t mac); -+extern ret_t rtl8367c_getAsicEavMacAddress(ether_addr_t *pMac); -+extern ret_t rtl8367c_setAsicEavTpid(rtk_uint32 outerTag, rtk_uint32 innerTag); -+extern ret_t rtl8367c_getAsicEavTpid(rtk_uint32* pOuterTag, rtk_uint32* pInnerTag); -+extern ret_t rtl8367c_setAsicEavSysTime(rtk_uint32 second, rtk_uint32 nanoSecond); -+extern ret_t rtl8367c_getAsicEavSysTime(rtk_uint32* pSecond, rtk_uint32* pNanoSecond); -+extern ret_t rtl8367c_setAsicEavSysTimeAdjust(rtk_uint32 type, rtk_uint32 second, rtk_uint32 nanoSecond); -+extern ret_t rtl8367c_setAsicEavSysTimeCtrl(rtk_uint32 control); -+extern ret_t rtl8367c_getAsicEavSysTimeCtrl(rtk_uint32* pControl); -+extern ret_t rtl8367c_setAsicEavInterruptMask(rtk_uint32 imr); -+extern ret_t rtl8367c_getAsicEavInterruptMask(rtk_uint32* pImr); -+extern ret_t rtl8367c_getAsicEavInterruptStatus(rtk_uint32* pIms); -+extern ret_t rtl8367c_setAsicEavPortInterruptStatus(rtk_uint32 port, rtk_uint32 ims); -+extern ret_t rtl8367c_getAsicEavPortInterruptStatus(rtk_uint32 port, rtk_uint32* pIms); -+extern ret_t rtl8367c_setAsicEavPortEnable(rtk_uint32 port, rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicEavPortEnable(rtk_uint32 port, rtk_uint32 *pEnabled); -+extern ret_t rtl8367c_getAsicEavPortTimeStamp(rtk_uint32 port, rtk_uint32 type, rtl8367c_ptp_time_stamp_t* timeStamp); -+ -+extern ret_t rtl8367c_setAsicEavTrap(rtk_uint32 port, rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicEavTrap(rtk_uint32 port, rtk_uint32 *pEnabled); -+extern ret_t rtl8367c_setAsicEavEnable(rtk_uint32 port, rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicEavEnable(rtk_uint32 port, rtk_uint32 *pEnabled); -+extern ret_t rtl8367c_setAsicEavPriRemapping(rtk_uint32 srcpriority, rtk_uint32 priority); -+extern ret_t rtl8367c_getAsicEavPriRemapping(rtk_uint32 srcpriority, rtk_uint32 *pPriority); -+ -+#endif /*#ifndef _RTL8367C_ASICDRV_EAV_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eee.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eee.h -new file mode 100644 -index 000000000000..6bedce62b0ad ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eee.h -@@ -0,0 +1,31 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 48989 $ -+ * $Date: 2014-07-01 15:45:24 +0800 (¶g¤G, 01 ¤C¤ë 2014) $ -+ * -+ * Purpose : RTL8370 switch high-level API for RTL8367C -+ * Feature : -+ * -+ */ -+ -+#ifndef _RTL8367C_ASICDRV_EEE_H_ -+#define _RTL8367C_ASICDRV_EEE_H_ -+ -+#include -+ -+#define EEE_OCP_PHY_ADDR (0xA5D0) -+ -+extern ret_t rtl8367c_setAsicEee100M(rtk_uint32 port, rtk_uint32 enable); -+extern ret_t rtl8367c_getAsicEee100M(rtk_uint32 port, rtk_uint32 *enable); -+extern ret_t rtl8367c_setAsicEeeGiga(rtk_uint32 port, rtk_uint32 enable); -+extern ret_t rtl8367c_getAsicEeeGiga(rtk_uint32 port, rtk_uint32 *enable); -+ -+ -+#endif /*_RTL8367C_ASICDRV_EEE_H_*/ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_fc.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_fc.h -new file mode 100644 -index 000000000000..ce67cdebacad ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_fc.h -@@ -0,0 +1,99 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Flow control related functions -+ * -+ */ -+ -+#ifndef _RTL8367C_ASICDRV_FC_H_ -+#define _RTL8367C_ASICDRV_FC_H_ -+ -+#include -+ -+#define RTL8367C_PAGE_NUMBER 0x600 -+ -+ -+enum FLOW_CONTROL_TYPE -+{ -+ FC_EGRESS = 0, -+ FC_INGRESS, -+}; -+ -+enum FC_JUMBO_SIZE -+{ -+ FC_JUMBO_SIZE_3K = 0, -+ FC_JUMBO_SIZE_4K, -+ FC_JUMBO_SIZE_6K, -+ FC_JUMBO_SIZE_9K, -+ FC_JUMBO_SIZE_END, -+ -+}; -+ -+ -+extern ret_t rtl8367c_setAsicFlowControlSelect(rtk_uint32 select); -+extern ret_t rtl8367c_getAsicFlowControlSelect(rtk_uint32 *pSelect); -+extern ret_t rtl8367c_setAsicFlowControlJumboMode(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicFlowControlJumboMode(rtk_uint32* pEnabled); -+extern ret_t rtl8367c_setAsicFlowControlJumboModeSize(rtk_uint32 size); -+extern ret_t rtl8367c_getAsicFlowControlJumboModeSize(rtk_uint32* pSize); -+extern ret_t rtl8367c_setAsicFlowControlQueueEgressEnable(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicFlowControlQueueEgressEnable(rtk_uint32 port, rtk_uint32 qid, rtk_uint32* pEnabled); -+extern ret_t rtl8367c_setAsicFlowControlDropAll(rtk_uint32 dropall); -+extern ret_t rtl8367c_getAsicFlowControlDropAll(rtk_uint32* pDropall); -+extern ret_t rtl8367c_setAsicFlowControlPauseAllThreshold(rtk_uint32 threshold); -+extern ret_t rtl8367c_getAsicFlowControlPauseAllThreshold(rtk_uint32 *pThreshold); -+extern ret_t rtl8367c_setAsicFlowControlSystemThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); -+extern ret_t rtl8367c_getAsicFlowControlSystemThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); -+extern ret_t rtl8367c_setAsicFlowControlSharedThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); -+extern ret_t rtl8367c_getAsicFlowControlSharedThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); -+extern ret_t rtl8367c_setAsicFlowControlPortThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); -+extern ret_t rtl8367c_getAsicFlowControlPortThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); -+extern ret_t rtl8367c_setAsicFlowControlPortPrivateThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); -+extern ret_t rtl8367c_getAsicFlowControlPortPrivateThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); -+extern ret_t rtl8367c_setAsicFlowControlSystemDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); -+extern ret_t rtl8367c_getAsicFlowControlSystemDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); -+extern ret_t rtl8367c_setAsicFlowControlSharedDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); -+extern ret_t rtl8367c_getAsicFlowControlSharedDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); -+extern ret_t rtl8367c_setAsicFlowControlPortDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); -+extern ret_t rtl8367c_getAsicFlowControlPortDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); -+extern ret_t rtl8367c_setAsicFlowControlPortPrivateDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); -+extern ret_t rtl8367c_getAsicFlowControlPortPrivateDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); -+extern ret_t rtl8367c_setAsicFlowControlSystemJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); -+extern ret_t rtl8367c_getAsicFlowControlSystemJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); -+extern ret_t rtl8367c_setAsicFlowControlSharedJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); -+extern ret_t rtl8367c_getAsicFlowControlSharedJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); -+extern ret_t rtl8367c_setAsicFlowControlPortJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); -+extern ret_t rtl8367c_getAsicFlowControlPortJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); -+extern ret_t rtl8367c_setAsicFlowControlPortPrivateJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold); -+extern ret_t rtl8367c_getAsicFlowControlPortPrivateJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold); -+ -+extern ret_t rtl8367c_setAsicEgressFlowControlPortDropGap(rtk_uint32 gap); -+extern ret_t rtl8367c_getAsicEgressFlowControlPortDropGap(rtk_uint32 *pGap); -+extern ret_t rtl8367c_setAsicEgressFlowControlQueueDropGap(rtk_uint32 gap); -+extern ret_t rtl8367c_getAsicEgressFlowControlQueueDropGap(rtk_uint32 *pGap); -+extern ret_t rtl8367c_setAsicEgressFlowControlPortDropThreshold(rtk_uint32 port, rtk_uint32 threshold); -+extern ret_t rtl8367c_getAsicEgressFlowControlPortDropThreshold(rtk_uint32 port, rtk_uint32 *pThreshold); -+extern ret_t rtl8367c_setAsicEgressFlowControlQueueDropThreshold(rtk_uint32 qid, rtk_uint32 threshold); -+extern ret_t rtl8367c_getAsicEgressFlowControlQueueDropThreshold(rtk_uint32 qid, rtk_uint32 *pThreshold); -+extern ret_t rtl8367c_getAsicEgressQueueEmptyPortMask(rtk_uint32 *pPortmask); -+extern ret_t rtl8367c_getAsicTotalPage(rtk_uint32 *pPageCount); -+extern ret_t rtl8367c_getAsicPulbicPage(rtk_uint32 *pPageCount); -+extern ret_t rtl8367c_getAsicMaxTotalPage(rtk_uint32 *pPageCount); -+extern ret_t rtl8367c_getAsicMaxPulbicPage(rtk_uint32 *pPageCount); -+extern ret_t rtl8367c_getAsicPortPage(rtk_uint32 port, rtk_uint32 *pPageCount); -+extern ret_t rtl8367c_getAsicPortPageMax(rtk_uint32 port, rtk_uint32 *pPageCount); -+extern ret_t rtl8367c_setAsicFlowControlEgressPortIndep(rtk_uint32 port, rtk_uint32 enable); -+extern ret_t rtl8367c_getAsicFlowControlEgressPortIndep(rtk_uint32 port, rtk_uint32 *pEnable); -+ -+#endif /*_RTL8367C_ASICDRV_FC_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_green.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_green.h -new file mode 100644 -index 000000000000..95c1b20bd49f ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_green.h -@@ -0,0 +1,36 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Green Ethernet related functions -+ * -+ */ -+ -+#ifndef _RTL8367C_ASICDRV_GREEN_H_ -+#define _RTL8367C_ASICDRV_GREEN_H_ -+ -+#include -+#include -+ -+#define PHY_POWERSAVING_REG 24 -+ -+extern ret_t rtl8367c_setAsicGreenTrafficType(rtk_uint32 priority, rtk_uint32 traffictype); -+extern ret_t rtl8367c_getAsicGreenTrafficType(rtk_uint32 priority, rtk_uint32* pTraffictype); -+extern ret_t rtl8367c_getAsicGreenPortPage(rtk_uint32 port, rtk_uint32* pPage); -+extern ret_t rtl8367c_getAsicGreenHighPriorityTraffic(rtk_uint32 port, rtk_uint32* pIndicator); -+extern ret_t rtl8367c_setAsicGreenHighPriorityTraffic(rtk_uint32 port); -+extern ret_t rtl8367c_setAsicGreenEthernet(rtk_uint32 port, rtk_uint32 green); -+extern ret_t rtl8367c_getAsicGreenEthernet(rtk_uint32 port, rtk_uint32* green); -+extern ret_t rtl8367c_setAsicPowerSaving(rtk_uint32 phy, rtk_uint32 enable); -+extern ret_t rtl8367c_getAsicPowerSaving(rtk_uint32 phy, rtk_uint32* enable); -+#endif /*#ifndef _RTL8367C_ASICDRV_GREEN_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_hsb.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_hsb.h -new file mode 100644 -index 000000000000..f4f9bb377b9f ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_hsb.h -@@ -0,0 +1,43 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Field selector related functions -+ * -+ */ -+ -+#ifndef _RTL8367C_ASICDRV__HSB_H_ -+#define _RTL8367C_ASICDRV__HSB_H_ -+ -+#include -+ -+#define RTL8367C_FIELDSEL_FORMAT_NUMBER (16) -+#define RTL8367C_FIELDSEL_MAX_OFFSET (255) -+ -+enum FIELDSEL_FORMAT_FORMAT -+{ -+ FIELDSEL_FORMAT_DEFAULT = 0, -+ FIELDSEL_FORMAT_RAW, -+ FIELDSEL_FORMAT_LLC, -+ FIELDSEL_FORMAT_IPV4, -+ FIELDSEL_FORMAT_ARP, -+ FIELDSEL_FORMAT_IPV6, -+ FIELDSEL_FORMAT_IPPAYLOAD, -+ FIELDSEL_FORMAT_L4PAYLOAD, -+ FIELDSEL_FORMAT_END -+}; -+ -+extern ret_t rtl8367c_setAsicFieldSelector(rtk_uint32 index, rtk_uint32 format, rtk_uint32 offset); -+extern ret_t rtl8367c_getAsicFieldSelector(rtk_uint32 index, rtk_uint32* pFormat, rtk_uint32* pOffset); -+ -+#endif /*_RTL8367C_ASICDRV__HSB_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_i2c.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_i2c.h -new file mode 100644 -index 000000000000..d5b095a0e5c6 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_i2c.h -@@ -0,0 +1,47 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 38651 $ -+ * $Date: 2016-02-27 14:32:56 +0800 (©P¤T, 17 ¥|¤ë 2016) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : I2C related functions -+ * -+ */ -+ -+ -+#ifndef _RTL8367C_ASICDRV_I2C_H_ -+#define _RTL8367C_ASICDRV_I2C_H_ -+#include -+#include -+ -+ -+#define TIMEROUT_FOR_MICROSEMI (0x400) -+ -+#define GPIO_INPUT 1 -+#define GPIO_OUTPUT 2 -+ -+extern ret_t rtl8367c_setAsicI2C_checkBusIdle(void); -+extern ret_t rtl8367c_setAsicI2CStartCmd(void); -+extern ret_t rtl8367c_setAsicI2CStopCmd(void); -+extern ret_t rtl8367c_setAsicI2CTxOneCharCmd(rtk_uint8 oneChar); -+extern ret_t rtl8367c_setAsicI2CcheckRxAck(void); -+extern ret_t rtl8367c_setAsicI2CRxOneCharCmd(rtk_uint8 *pValue); -+extern ret_t rtl8367c_setAsicI2CTxAckCmd(void); -+extern ret_t rtl8367c_setAsicI2CTxNoAckCmd(void); -+extern ret_t rtl8367c_setAsicI2CSoftRSTseqCmd(void); -+extern ret_t rtl8367c_setAsicI2CGpioPinGroup(rtk_uint32 pinGroup_ID); -+extern ret_t rtl8367c_getAsicI2CGpioPinGroup(rtk_uint32 * pPinGroup_ID); -+ -+ -+ -+ -+ -+#endif /*#ifndef _RTL8367C_ASICDRV_I2C_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_igmp.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_igmp.h -new file mode 100644 -index 000000000000..b879b6b520e4 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_igmp.h -@@ -0,0 +1,169 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : IGMP related functions -+ * -+ */ -+ -+#ifndef _RTL8367C_ASICDRV_IGMP_H_ -+#define _RTL8367C_ASICDRV_IGMP_H_ -+ -+/****************************************************************/ -+/* Header File inclusion */ -+/****************************************************************/ -+#include -+ -+#define RTL8367C_MAX_LEAVE_TIMER (7) -+#define RTL8367C_MAX_QUERY_INT (0xFFFF) -+#define RTL8367C_MAX_ROB_VAR (7) -+ -+#define RTL8367C_IGMP_GOUP_NO (256) -+#define RTL8367C_IGMP_MAX_GOUP (0xFF) -+#define RTL8367C_IGMP_GRP_BLEN (3) -+#define RTL8367C_ROUTER_PORT_INVALID (0xF) -+ -+enum RTL8367C_IGMPTABLE_FULL_OP -+{ -+ TABLE_FULL_FORWARD = 0, -+ TABLE_FULL_DROP, -+ TABLE_FULL_TRAP, -+ TABLE_FULL_OP_END -+}; -+ -+enum RTL8367C_CRC_ERR_OP -+{ -+ CRC_ERR_DROP = 0, -+ CRC_ERR_TRAP, -+ CRC_ERR_FORWARD, -+ CRC_ERR_OP_END -+}; -+ -+enum RTL8367C_IGMP_MLD_PROTOCOL_OP -+{ -+ PROTOCOL_OP_ASIC = 0, -+ PROTOCOL_OP_FLOOD, -+ PROTOCOL_OP_TRAP, -+ PROTOCOL_OP_DROP, -+ PROTOCOL_OP_END -+}; -+ -+enum RTL8367C_IGMP_MLD_BYPASS_GROUP -+{ -+ BYPASS_224_0_0_X = 0, -+ BYPASS_224_0_1_X, -+ BYPASS_239_255_255_X, -+ BYPASS_IPV6_00XX, -+ BYPASS_GROUP_END -+}; -+ -+typedef struct -+{ -+ rtk_uint32 p0_timer; -+ rtk_uint32 p1_timer; -+ rtk_uint32 p2_timer; -+ rtk_uint32 p3_timer; -+ rtk_uint32 p4_timer; -+ rtk_uint32 p5_timer; -+ rtk_uint32 p6_timer; -+ rtk_uint32 p7_timer; -+ rtk_uint32 p8_timer; -+ rtk_uint32 p9_timer; -+ rtk_uint32 p10_timer; -+ rtk_uint32 report_supp_flag; -+ -+}rtl8367c_igmpgroup; -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * This program is the proprietary software of Realtek Semiconductor -+ * Corporation and/or its licensors, and only be used, duplicated, -+ * modified or distributed under the authorized license from Realtek. -+ * -+ * ANY USE OF THE SOFTWARE OTHER THAN AS AUTHORIZED UNDER -+ * THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : IGMP related functions -+ * -+ */ -+#include -+ -+ret_t rtl8367c_setAsicIgmp(rtk_uint32 enabled); -+ret_t rtl8367c_getAsicIgmp(rtk_uint32 *pEnabled); -+ret_t rtl8367c_setAsicIpMulticastVlanLeaky(rtk_uint32 port, rtk_uint32 enabled ); -+ret_t rtl8367c_getAsicIpMulticastVlanLeaky(rtk_uint32 port, rtk_uint32 *pEnabled ); -+ret_t rtl8367c_setAsicIGMPTableFullOP(rtk_uint32 operation); -+ret_t rtl8367c_getAsicIGMPTableFullOP(rtk_uint32 *pOperation); -+ret_t rtl8367c_setAsicIGMPCRCErrOP(rtk_uint32 operation); -+ret_t rtl8367c_getAsicIGMPCRCErrOP(rtk_uint32 *pOperation); -+ret_t rtl8367c_setAsicIGMPFastLeaveEn(rtk_uint32 enabled); -+ret_t rtl8367c_getAsicIGMPFastLeaveEn(rtk_uint32 *pEnabled); -+ret_t rtl8367c_setAsicIGMPLeaveTimer(rtk_uint32 leave_timer); -+ret_t rtl8367c_getAsicIGMPLeaveTimer(rtk_uint32 *pLeave_timer); -+ret_t rtl8367c_setAsicIGMPQueryInterval(rtk_uint32 interval); -+ret_t rtl8367c_getAsicIGMPQueryInterval(rtk_uint32 *pInterval); -+ret_t rtl8367c_setAsicIGMPRobVar(rtk_uint32 rob_var); -+ret_t rtl8367c_getAsicIGMPRobVar(rtk_uint32 *pRob_var); -+ret_t rtl8367c_setAsicIGMPStaticRouterPort(rtk_uint32 pmsk); -+ret_t rtl8367c_getAsicIGMPStaticRouterPort(rtk_uint32 *pMsk); -+ret_t rtl8367c_setAsicIGMPAllowDynamicRouterPort(rtk_uint32 pmsk); -+ret_t rtl8367c_getAsicIGMPAllowDynamicRouterPort(rtk_uint32 *pPmsk); -+ret_t rtl8367c_getAsicIGMPdynamicRouterPort1(rtk_uint32 *pPort, rtk_uint32 *pTimer); -+ret_t rtl8367c_getAsicIGMPdynamicRouterPort2(rtk_uint32 *pPort, rtk_uint32 *pTimer); -+ret_t rtl8367c_setAsicIGMPSuppression(rtk_uint32 report_supp_enabled, rtk_uint32 leave_supp_enabled); -+ret_t rtl8367c_getAsicIGMPSuppression(rtk_uint32 *pReport_supp_enabled, rtk_uint32 *pLeave_supp_enabled); -+ret_t rtl8367c_setAsicIGMPQueryRX(rtk_uint32 port, rtk_uint32 allow_query); -+ret_t rtl8367c_getAsicIGMPQueryRX(rtk_uint32 port, rtk_uint32 *pAllow_query); -+ret_t rtl8367c_setAsicIGMPReportRX(rtk_uint32 port, rtk_uint32 allow_report); -+ret_t rtl8367c_getAsicIGMPReportRX(rtk_uint32 port, rtk_uint32 *pAllow_report); -+ret_t rtl8367c_setAsicIGMPLeaveRX(rtk_uint32 port, rtk_uint32 allow_leave); -+ret_t rtl8367c_getAsicIGMPLeaveRX(rtk_uint32 port, rtk_uint32 *pAllow_leave); -+ret_t rtl8367c_setAsicIGMPMRPRX(rtk_uint32 port, rtk_uint32 allow_mrp); -+ret_t rtl8367c_getAsicIGMPMRPRX(rtk_uint32 port, rtk_uint32 *pAllow_mrp); -+ret_t rtl8367c_setAsicIGMPMcDataRX(rtk_uint32 port, rtk_uint32 allow_mcdata); -+ret_t rtl8367c_getAsicIGMPMcDataRX(rtk_uint32 port, rtk_uint32 *pAllow_mcdata); -+ret_t rtl8367c_setAsicIGMPv1Opeartion(rtk_uint32 port, rtk_uint32 igmpv1_op); -+ret_t rtl8367c_getAsicIGMPv1Opeartion(rtk_uint32 port, rtk_uint32 *pIgmpv1_op); -+ret_t rtl8367c_setAsicIGMPv2Opeartion(rtk_uint32 port, rtk_uint32 igmpv2_op); -+ret_t rtl8367c_getAsicIGMPv2Opeartion(rtk_uint32 port, rtk_uint32 *pIgmpv2_op); -+ret_t rtl8367c_setAsicIGMPv3Opeartion(rtk_uint32 port, rtk_uint32 igmpv3_op); -+ret_t rtl8367c_getAsicIGMPv3Opeartion(rtk_uint32 port, rtk_uint32 *pIgmpv3_op); -+ret_t rtl8367c_setAsicMLDv1Opeartion(rtk_uint32 port, rtk_uint32 mldv1_op); -+ret_t rtl8367c_getAsicMLDv1Opeartion(rtk_uint32 port, rtk_uint32 *pMldv1_op); -+ret_t rtl8367c_setAsicMLDv2Opeartion(rtk_uint32 port, rtk_uint32 mldv2_op); -+ret_t rtl8367c_getAsicMLDv2Opeartion(rtk_uint32 port, rtk_uint32 *pMldv2_op); -+ret_t rtl8367c_setAsicIGMPPortMAXGroup(rtk_uint32 port, rtk_uint32 max_group); -+ret_t rtl8367c_getAsicIGMPPortMAXGroup(rtk_uint32 port, rtk_uint32 *pMax_group); -+ret_t rtl8367c_getAsicIGMPPortCurrentGroup(rtk_uint32 port, rtk_uint32 *pCurrent_group); -+ret_t rtl8367c_getAsicIGMPGroup(rtk_uint32 idx, rtk_uint32 *pValid, rtl8367c_igmpgroup *pGrp); -+ret_t rtl8367c_setAsicIpMulticastPortIsoLeaky(rtk_uint32 port, rtk_uint32 enabled); -+ret_t rtl8367c_getAsicIpMulticastPortIsoLeaky(rtk_uint32 port, rtk_uint32 *pEnabled); -+ret_t rtl8367c_setAsicIGMPReportLeaveFlood(rtk_uint32 flood); -+ret_t rtl8367c_getAsicIGMPReportLeaveFlood(rtk_uint32 *pFlood); -+ret_t rtl8367c_setAsicIGMPDropLeaveZero(rtk_uint32 drop); -+ret_t rtl8367c_getAsicIGMPDropLeaveZero(rtk_uint32 *pDrop); -+ret_t rtl8367c_setAsicIGMPBypassStormCTRL(rtk_uint32 bypass); -+ret_t rtl8367c_getAsicIGMPBypassStormCTRL(rtk_uint32 *pBypass); -+ret_t rtl8367c_setAsicIGMPIsoLeaky(rtk_uint32 leaky); -+ret_t rtl8367c_getAsicIGMPIsoLeaky(rtk_uint32 *pLeaky); -+ret_t rtl8367c_setAsicIGMPVLANLeaky(rtk_uint32 leaky); -+ret_t rtl8367c_getAsicIGMPVLANLeaky(rtk_uint32 *pLeaky); -+ret_t rtl8367c_setAsicIGMPBypassGroup(rtk_uint32 bypassType, rtk_uint32 enabled); -+ret_t rtl8367c_getAsicIGMPBypassGroup(rtk_uint32 bypassType, rtk_uint32 *pEnabled); -+ -+#endif /*#ifndef _RTL8367C_ASICDRV_IGMP_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_inbwctrl.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_inbwctrl.h -new file mode 100644 -index 000000000000..10f3545322c9 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_inbwctrl.h -@@ -0,0 +1,30 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Ingress bandwidth control related functions -+ * -+ */ -+ -+#ifndef _RTL8367C_ASICDRV_INBWCTRL_H_ -+#define _RTL8367C_ASICDRV_INBWCTRL_H_ -+ -+#include -+ -+extern ret_t rtl8367c_setAsicPortIngressBandwidth(rtk_uint32 port, rtk_uint32 bandwidth, rtk_uint32 preifg, rtk_uint32 enableFC); -+extern ret_t rtl8367c_getAsicPortIngressBandwidth(rtk_uint32 port, rtk_uint32* pBandwidth, rtk_uint32* pPreifg, rtk_uint32* pEnableFC ); -+extern ret_t rtl8367c_setAsicPortIngressBandwidthBypass(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicPortIngressBandwidthBypass(rtk_uint32* pEnabled); -+ -+ -+#endif /*_RTL8367C_ASICDRV_INBWCTRL_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_interrupt.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_interrupt.h -new file mode 100644 -index 000000000000..8b78014ab01b ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_interrupt.h -@@ -0,0 +1,66 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Interrupt related functions -+ * -+ */ -+ -+#ifndef _RTL8367C_ASICDRV_INTERRUPT_H_ -+#define _RTL8367C_ASICDRV_INTERRUPT_H_ -+ -+#include -+ -+typedef enum RTL8367C_INTR_IMRS_E -+{ -+ IMRS_LINK_CHANGE, -+ IMRS_METER_EXCEED, -+ IMRS_L2_LEARN, -+ IMRS_SPEED_CHANGE, -+ IMRS_SPECIAL_CONGESTION, -+ IMRS_GREEN_FEATURE, -+ IMRS_LOOP_DETECTION, -+ IMRS_8051, -+ IMRS_CABLE_DIAG, -+ IMRS_ACL, -+ IMRS_RESERVED, /* Unused */ -+ IMRS_SLIENT, -+ IMRS_END, -+}RTL8367C_INTR_IMRS; -+ -+typedef enum RTL8367C_INTR_INDICATOR_E -+{ -+ INTRST_L2_LEARN = 0, -+ INTRST_SPEED_CHANGE, -+ INTRST_SPECIAL_CONGESTION, -+ INTRST_PORT_LINKDOWN, -+ INTRST_PORT_LINKUP, -+ INTRST_METER0_15, -+ INTRST_METER16_31, -+ INTRST_RLDP_LOOPED, -+ INTRST_RLDP_RELEASED, -+ INTRST_SYS_LEARN, -+ INTRST_END, -+}RTL8367C_INTR_INDICATOR; -+ -+extern ret_t rtl8367c_setAsicInterruptPolarity(rtk_uint32 polarity); -+extern ret_t rtl8367c_getAsicInterruptPolarity(rtk_uint32* pPolarity); -+extern ret_t rtl8367c_setAsicInterruptMask(rtk_uint32 imr); -+extern ret_t rtl8367c_getAsicInterruptMask(rtk_uint32* pImr); -+extern ret_t rtl8367c_setAsicInterruptStatus(rtk_uint32 ims); -+extern ret_t rtl8367c_getAsicInterruptStatus(rtk_uint32* pIms); -+extern ret_t rtl8367c_setAsicInterruptRelatedStatus(rtk_uint32 type, rtk_uint32 status); -+extern ret_t rtl8367c_getAsicInterruptRelatedStatus(rtk_uint32 type, rtk_uint32* pStatus); -+ -+ -+#endif /*#ifndef _RTL8367C_ASICDRV_INTERRUPT_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_led.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_led.h -new file mode 100644 -index 000000000000..a7f8e2064320 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_led.h -@@ -0,0 +1,138 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : LED related functions -+ * -+ */ -+ -+#ifndef _RTL8367C_ASICDRV_LED_H_ -+#define _RTL8367C_ASICDRV_LED_H_ -+ -+#include -+ -+#define RTL8367C_LEDGROUPNO 3 -+#define RTL8367C_LEDGROUPMASK 0x7 -+#define RTL8367C_LED_FORCE_MODE_BASE RTL8367C_REG_CPU_FORCE_LED0_CFG0 -+#define RTL8367C_LED_FORCE_CTRL RTL8367C_REG_CPU_FORCE_LED_CFG -+ -+enum RTL8367C_LEDOP{ -+ -+ LEDOP_SCAN0=0, -+ LEDOP_SCAN1, -+ LEDOP_PARALLEL, -+ LEDOP_SERIAL, -+ LEDOP_END, -+}; -+ -+enum RTL8367C_LEDSERACT{ -+ -+ LEDSERACT_HIGH=0, -+ LEDSERACT_LOW, -+ LEDSERACT_MAX, -+}; -+ -+enum RTL8367C_LEDSER{ -+ -+ LEDSER_16G=0, -+ LEDSER_8G, -+ LEDSER_MAX, -+}; -+ -+enum RTL8367C_LEDCONF{ -+ -+ LEDCONF_LEDOFF=0, -+ LEDCONF_DUPCOL, -+ LEDCONF_LINK_ACT, -+ LEDCONF_SPD1000, -+ LEDCONF_SPD100, -+ LEDCONF_SPD10, -+ LEDCONF_SPD1000ACT, -+ LEDCONF_SPD100ACT, -+ LEDCONF_SPD10ACT, -+ LEDCONF_SPD10010ACT, -+ LEDCONF_LOOPDETECT, -+ LEDCONF_EEE, -+ LEDCONF_LINKRX, -+ LEDCONF_LINKTX, -+ LEDCONF_MASTER, -+ LEDCONF_ACT, -+ LEDCONF_END -+}; -+ -+enum RTL8367C_LEDBLINKRATE{ -+ -+ LEDBLINKRATE_32MS=0, -+ LEDBLINKRATE_64MS, -+ LEDBLINKRATE_128MS, -+ LEDBLINKRATE_256MS, -+ LEDBLINKRATE_512MS, -+ LEDBLINKRATE_1024MS, -+ LEDBLINKRATE_48MS, -+ LEDBLINKRATE_96MS, -+ LEDBLINKRATE_END, -+}; -+ -+enum RTL8367C_LEDFORCEMODE{ -+ -+ LEDFORCEMODE_NORMAL=0, -+ LEDFORCEMODE_BLINK, -+ LEDFORCEMODE_OFF, -+ LEDFORCEMODE_ON, -+ LEDFORCEMODE_END, -+}; -+ -+enum RTL8367C_LEDFORCERATE{ -+ -+ LEDFORCERATE_512MS=0, -+ LEDFORCERATE_1024MS, -+ LEDFORCERATE_2048MS, -+ LEDFORCERATE_NORMAL, -+ LEDFORCERATE_END, -+ -+}; -+ -+enum RTL8367C_LEDMODE -+{ -+ RTL8367C_LED_MODE_0 = 0, -+ RTL8367C_LED_MODE_1, -+ RTL8367C_LED_MODE_2, -+ RTL8367C_LED_MODE_3, -+ RTL8367C_LED_MODE_END -+}; -+ -+extern ret_t rtl8367c_setAsicLedIndicateInfoConfig(rtk_uint32 ledno, rtk_uint32 config); -+extern ret_t rtl8367c_getAsicLedIndicateInfoConfig(rtk_uint32 ledno, rtk_uint32* pConfig); -+extern ret_t rtl8367c_setAsicForceLed(rtk_uint32 port, rtk_uint32 group, rtk_uint32 mode); -+extern ret_t rtl8367c_getAsicForceLed(rtk_uint32 port, rtk_uint32 group, rtk_uint32* pMode); -+extern ret_t rtl8367c_setAsicForceGroupLed(rtk_uint32 groupmask, rtk_uint32 mode); -+extern ret_t rtl8367c_getAsicForceGroupLed(rtk_uint32* groupmask, rtk_uint32* pMode); -+extern ret_t rtl8367c_setAsicLedBlinkRate(rtk_uint32 blinkRate); -+extern ret_t rtl8367c_getAsicLedBlinkRate(rtk_uint32* pBlinkRate); -+extern ret_t rtl8367c_setAsicLedForceBlinkRate(rtk_uint32 blinkRate); -+extern ret_t rtl8367c_getAsicLedForceBlinkRate(rtk_uint32* pBlinkRate); -+extern ret_t rtl8367c_setAsicLedGroupMode(rtk_uint32 mode); -+extern ret_t rtl8367c_getAsicLedGroupMode(rtk_uint32* pMode); -+extern ret_t rtl8367c_setAsicLedGroupEnable(rtk_uint32 group, rtk_uint32 portmask); -+extern ret_t rtl8367c_getAsicLedGroupEnable(rtk_uint32 group, rtk_uint32 *portmask); -+extern ret_t rtl8367c_setAsicLedOperationMode(rtk_uint32 mode); -+extern ret_t rtl8367c_getAsicLedOperationMode(rtk_uint32 *mode); -+extern ret_t rtl8367c_setAsicLedSerialModeConfig(rtk_uint32 active, rtk_uint32 serimode); -+extern ret_t rtl8367c_getAsicLedSerialModeConfig(rtk_uint32 *active, rtk_uint32 *serimode); -+extern ret_t rtl8367c_setAsicLedOutputEnable(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicLedOutputEnable(rtk_uint32 *ptr_enabled); -+extern ret_t rtl8367c_setAsicLedSerialOutput(rtk_uint32 output, rtk_uint32 pmask); -+extern ret_t rtl8367c_getAsicLedSerialOutput(rtk_uint32 *pOutput, rtk_uint32 *pPmask); -+ -+ -+#endif /*#ifndef _RTL8367C_ASICDRV_LED_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_lut.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_lut.h -new file mode 100644 -index 000000000000..c94ea0760193 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_lut.h -@@ -0,0 +1,159 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : LUT related functions -+ * -+ */ -+ -+ -+#ifndef _RTL8367C_ASICDRV_LUT_H_ -+#define _RTL8367C_ASICDRV_LUT_H_ -+ -+#include -+ -+#define RTL8367C_LUT_AGETIMERMAX (7) -+#define RTL8367C_LUT_AGESPEEDMAX (3) -+#define RTL8367C_LUT_LEARNLIMITMAX (0x1040) -+#define RTL8367C_LUT_ADDRMAX (0x103F) -+#define RTL8367C_LUT_IPMCGRP_TABLE_MAX (0x3F) -+#define RTL8367C_LUT_ENTRY_SIZE (6) -+#define RTL8367C_LUT_BUSY_CHECK_NO (10) -+ -+#define RTL8367C_LUT_TABLE_SIZE (6) -+ -+enum RTL8367C_LUTHASHMETHOD{ -+ -+ LUTHASHMETHOD_SVL=0, -+ LUTHASHMETHOD_IVL, -+ LUTHASHMETHOD_END, -+}; -+ -+ -+enum RTL8367C_LRNOVERACT{ -+ -+ LRNOVERACT_FORWARD=0, -+ LRNOVERACT_DROP, -+ LRNOVERACT_TRAP, -+ LRNOVERACT_END, -+}; -+ -+enum RTL8367C_LUTREADMETHOD{ -+ -+ LUTREADMETHOD_MAC =0, -+ LUTREADMETHOD_ADDRESS, -+ LUTREADMETHOD_NEXT_ADDRESS, -+ LUTREADMETHOD_NEXT_L2UC, -+ LUTREADMETHOD_NEXT_L2MC, -+ LUTREADMETHOD_NEXT_L3MC, -+ LUTREADMETHOD_NEXT_L2L3MC, -+ LUTREADMETHOD_NEXT_L2UCSPA, -+}; -+ -+enum RTL8367C_FLUSHMODE -+{ -+ FLUSHMDOE_PORT = 0, -+ FLUSHMDOE_VID, -+ FLUSHMDOE_FID, -+ FLUSHMDOE_END, -+}; -+ -+enum RTL8367C_FLUSHTYPE -+{ -+ FLUSHTYPE_DYNAMIC = 0, -+ FLUSHTYPE_BOTH, -+ FLUSHTYPE_END, -+}; -+ -+ -+typedef struct LUTTABLE{ -+ -+ ipaddr_t sip; -+ ipaddr_t dip; -+ ether_addr_t mac; -+ rtk_uint16 ivl_svl:1; -+ rtk_uint16 cvid_fid:12; -+ rtk_uint16 fid:4; -+ rtk_uint16 efid:3; -+ -+ rtk_uint16 nosalearn:1; -+ rtk_uint16 da_block:1; -+ rtk_uint16 sa_block:1; -+ rtk_uint16 auth:1; -+ rtk_uint16 lut_pri:3; -+ rtk_uint16 sa_en:1; -+ rtk_uint16 fwd_en:1; -+ rtk_uint16 mbr:11; -+ rtk_uint16 spa:4; -+ rtk_uint16 age:3; -+ rtk_uint16 l3lookup:1; -+ rtk_uint16 igmp_asic:1; -+ rtk_uint16 igmpidx:8; -+ -+ rtk_uint16 lookup_hit:1; -+ rtk_uint16 lookup_busy:1; -+ rtk_uint16 address:13; -+ -+ rtk_uint16 l3vidlookup:1; -+ rtk_uint16 l3_vid:12; -+ -+ rtk_uint16 wait_time; -+ -+}rtl8367c_luttb; -+ -+extern ret_t rtl8367c_setAsicLutIpMulticastLookup(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicLutIpMulticastLookup(rtk_uint32* pEnabled); -+extern ret_t rtl8367c_setAsicLutIpMulticastVidLookup(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicLutIpMulticastVidLookup(rtk_uint32* pEnabled); -+extern ret_t rtl8367c_setAsicLutAgeTimerSpeed(rtk_uint32 timer, rtk_uint32 speed); -+extern ret_t rtl8367c_getAsicLutAgeTimerSpeed(rtk_uint32* pTimer, rtk_uint32* pSpeed); -+extern ret_t rtl8367c_setAsicLutCamTbUsage(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicLutCamTbUsage(rtk_uint32* pEnabled); -+extern ret_t rtl8367c_getAsicLutCamType(rtk_uint32* pType); -+extern ret_t rtl8367c_setAsicLutLearnLimitNo(rtk_uint32 port, rtk_uint32 number); -+extern ret_t rtl8367c_getAsicLutLearnLimitNo(rtk_uint32 port, rtk_uint32* pNumber); -+extern ret_t rtl8367c_setAsicSystemLutLearnLimitNo(rtk_uint32 number); -+extern ret_t rtl8367c_getAsicSystemLutLearnLimitNo(rtk_uint32 *pNumber); -+extern ret_t rtl8367c_setAsicLutLearnOverAct(rtk_uint32 action); -+extern ret_t rtl8367c_getAsicLutLearnOverAct(rtk_uint32* pAction); -+extern ret_t rtl8367c_setAsicSystemLutLearnOverAct(rtk_uint32 action); -+extern ret_t rtl8367c_getAsicSystemLutLearnOverAct(rtk_uint32 *pAction); -+extern ret_t rtl8367c_setAsicSystemLutLearnPortMask(rtk_uint32 portmask); -+extern ret_t rtl8367c_getAsicSystemLutLearnPortMask(rtk_uint32 *pPortmask); -+extern ret_t rtl8367c_setAsicL2LookupTb(rtl8367c_luttb *pL2Table); -+extern ret_t rtl8367c_getAsicL2LookupTb(rtk_uint32 method, rtl8367c_luttb *pL2Table); -+extern ret_t rtl8367c_getAsicLutLearnNo(rtk_uint32 port, rtk_uint32* pNumber); -+extern ret_t rtl8367c_setAsicLutIpLookupMethod(rtk_uint32 type); -+extern ret_t rtl8367c_getAsicLutIpLookupMethod(rtk_uint32* pType); -+extern ret_t rtl8367c_setAsicLutForceFlush(rtk_uint32 portmask); -+extern ret_t rtl8367c_getAsicLutForceFlushStatus(rtk_uint32 *pPortmask); -+extern ret_t rtl8367c_setAsicLutFlushMode(rtk_uint32 mode); -+extern ret_t rtl8367c_getAsicLutFlushMode(rtk_uint32* pMode); -+extern ret_t rtl8367c_setAsicLutFlushType(rtk_uint32 type); -+extern ret_t rtl8367c_getAsicLutFlushType(rtk_uint32* pType); -+extern ret_t rtl8367c_setAsicLutFlushVid(rtk_uint32 vid); -+extern ret_t rtl8367c_getAsicLutFlushVid(rtk_uint32* pVid); -+extern ret_t rtl8367c_setAsicLutFlushFid(rtk_uint32 fid); -+extern ret_t rtl8367c_getAsicLutFlushFid(rtk_uint32* pFid); -+extern ret_t rtl8367c_setAsicLutDisableAging(rtk_uint32 port, rtk_uint32 disabled); -+extern ret_t rtl8367c_getAsicLutDisableAging(rtk_uint32 port, rtk_uint32 *pDisabled); -+extern ret_t rtl8367c_setAsicLutIPMCGroup(rtk_uint32 index, ipaddr_t group_addr, rtk_uint32 vid, rtk_uint32 pmask, rtk_uint32 valid); -+extern ret_t rtl8367c_getAsicLutIPMCGroup(rtk_uint32 index, ipaddr_t *pGroup_addr, rtk_uint32 *pVid, rtk_uint32 *pPmask, rtk_uint32 *pValid); -+extern ret_t rtl8367c_setAsicLutLinkDownForceAging(rtk_uint32 enable); -+extern ret_t rtl8367c_getAsicLutLinkDownForceAging(rtk_uint32 *pEnable); -+extern ret_t rtl8367c_setAsicLutFlushAll(void); -+extern ret_t rtl8367c_getAsicLutFlushAllStatus(rtk_uint32 *pBusyStatus); -+extern ret_t rtl8367c_setAsicLutIpmcFwdRouterPort(rtk_uint32 enable); -+extern ret_t rtl8367c_getAsicLutIpmcFwdRouterPort(rtk_uint32 *pEnable); -+ -+#endif /*_RTL8367C_ASICDRV_LUT_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_meter.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_meter.h -new file mode 100644 -index 000000000000..ba761a94f8da ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_meter.h -@@ -0,0 +1,34 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Shared meter related functions -+ * -+ */ -+ -+#ifndef _RTL8367C_ASICDRV_METER_H_ -+#define _RTL8367C_ASICDRV_METER_H_ -+ -+#include -+ -+ -+extern ret_t rtl8367c_setAsicShareMeter(rtk_uint32 index, rtk_uint32 rate, rtk_uint32 ifg); -+extern ret_t rtl8367c_getAsicShareMeter(rtk_uint32 index, rtk_uint32 *pRate, rtk_uint32 *pIfg); -+extern ret_t rtl8367c_setAsicShareMeterBucketSize(rtk_uint32 index, rtk_uint32 lbThreshold); -+extern ret_t rtl8367c_getAsicShareMeterBucketSize(rtk_uint32 index, rtk_uint32 *pLbThreshold); -+extern ret_t rtl8367c_setAsicShareMeterType(rtk_uint32 index, rtk_uint32 type); -+extern ret_t rtl8367c_getAsicShareMeterType(rtk_uint32 index, rtk_uint32 *pType); -+extern ret_t rtl8367c_setAsicMeterExceedStatus(rtk_uint32 index); -+extern ret_t rtl8367c_getAsicMeterExceedStatus(rtk_uint32 index, rtk_uint32* pStatus); -+ -+#endif /*_RTL8367C_ASICDRV_FC_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mib.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mib.h -new file mode 100644 -index 000000000000..ca46e0f4706c ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mib.h -@@ -0,0 +1,133 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : MIB related functions -+ * -+ */ -+ -+#ifndef _RTL8367C_ASICDRV_MIB_H_ -+#define _RTL8367C_ASICDRV_MIB_H_ -+ -+#include -+ -+#define RTL8367C_MIB_PORT_OFFSET (0x7C) -+#define RTL8367C_MIB_LEARNENTRYDISCARD_OFFSET (0x420) -+ -+#define RTL8367C_MAX_LOG_CNT_NUM (32) -+#define RTL8367C_MIB_MAX_LOG_CNT_IDX (RTL8367C_MAX_LOG_CNT_NUM - 1) -+#define RTL8367C_MIB_LOG_CNT_OFFSET (0x3E0) -+#define RTL8367C_MIB_MAX_LOG_MODE_IDX (16-1) -+ -+typedef enum RTL8367C_MIBCOUNTER_E{ -+ -+ /* RX */ -+ ifInOctets = 0, -+ -+ dot3StatsFCSErrors, -+ dot3StatsSymbolErrors, -+ dot3InPauseFrames, -+ dot3ControlInUnknownOpcodes, -+ -+ etherStatsFragments, -+ etherStatsJabbers, -+ ifInUcastPkts, -+ etherStatsDropEvents, -+ -+ ifInMulticastPkts, -+ ifInBroadcastPkts, -+ inMldChecksumError, -+ inIgmpChecksumError, -+ inMldSpecificQuery, -+ inMldGeneralQuery, -+ inIgmpSpecificQuery, -+ inIgmpGeneralQuery, -+ inMldLeaves, -+ inIgmpLeaves, -+ -+ /* TX/RX */ -+ etherStatsOctets, -+ -+ etherStatsUnderSizePkts, -+ etherOversizeStats, -+ etherStatsPkts64Octets, -+ etherStatsPkts65to127Octets, -+ etherStatsPkts128to255Octets, -+ etherStatsPkts256to511Octets, -+ etherStatsPkts512to1023Octets, -+ etherStatsPkts1024to1518Octets, -+ -+ /* TX */ -+ ifOutOctets, -+ -+ dot3StatsSingleCollisionFrames, -+ dot3StatMultipleCollisionFrames, -+ dot3sDeferredTransmissions, -+ dot3StatsLateCollisions, -+ etherStatsCollisions, -+ dot3StatsExcessiveCollisions, -+ dot3OutPauseFrames, -+ ifOutDiscards, -+ -+ /* ALE */ -+ dot1dTpPortInDiscards, -+ ifOutUcastPkts, -+ ifOutMulticastPkts, -+ ifOutBroadcastPkts, -+ outOampduPkts, -+ inOampduPkts, -+ -+ inIgmpJoinsSuccess, -+ inIgmpJoinsFail, -+ inMldJoinsSuccess, -+ inMldJoinsFail, -+ inReportSuppressionDrop, -+ inLeaveSuppressionDrop, -+ outIgmpReports, -+ outIgmpLeaves, -+ outIgmpGeneralQuery, -+ outIgmpSpecificQuery, -+ outMldReports, -+ outMldLeaves, -+ outMldGeneralQuery, -+ outMldSpecificQuery, -+ inKnownMulticastPkts, -+ -+ /*Device only */ -+ dot1dTpLearnedEntryDiscards, -+ RTL8367C_MIBS_NUMBER, -+ -+}RTL8367C_MIBCOUNTER; -+ -+ -+extern ret_t rtl8367c_setAsicMIBsCounterReset(rtk_uint32 greset, rtk_uint32 qmreset, rtk_uint32 pmask); -+extern ret_t rtl8367c_getAsicMIBsCounter(rtk_uint32 port,RTL8367C_MIBCOUNTER mibIdx, rtk_uint64* pCounter); -+extern ret_t rtl8367c_getAsicMIBsLogCounter(rtk_uint32 index, rtk_uint32 *pCounter); -+extern ret_t rtl8367c_getAsicMIBsControl(rtk_uint32* pMask); -+ -+extern ret_t rtl8367c_setAsicMIBsResetValue(rtk_uint32 value); -+extern ret_t rtl8367c_getAsicMIBsResetValue(rtk_uint32* value); -+ -+extern ret_t rtl8367c_setAsicMIBsUsageMode(rtk_uint32 mode); -+extern ret_t rtl8367c_getAsicMIBsUsageMode(rtk_uint32* pMode); -+extern ret_t rtl8367c_setAsicMIBsTimer(rtk_uint32 timer); -+extern ret_t rtl8367c_getAsicMIBsTimer(rtk_uint32* pTimer); -+extern ret_t rtl8367c_setAsicMIBsLoggingMode(rtk_uint32 index, rtk_uint32 mode); -+extern ret_t rtl8367c_getAsicMIBsLoggingMode(rtk_uint32 index, rtk_uint32* pMode); -+extern ret_t rtl8367c_setAsicMIBsLoggingType(rtk_uint32 index, rtk_uint32 type); -+extern ret_t rtl8367c_getAsicMIBsLoggingType(rtk_uint32 index, rtk_uint32* pType); -+extern ret_t rtl8367c_setAsicMIBsResetLoggingCounter(rtk_uint32 index); -+extern ret_t rtl8367c_setAsicMIBsLength(rtk_uint32 txLengthMode, rtk_uint32 rxLengthMode); -+extern ret_t rtl8367c_getAsicMIBsLength(rtk_uint32 *pTxLengthMode, rtk_uint32 *pRxLengthMode); -+ -+#endif /*#ifndef _RTL8367C_ASICDRV_MIB_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mii_mgr.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mii_mgr.h -new file mode 100644 -index 000000000000..816763fae1e8 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mii_mgr.h -@@ -0,0 +1,26 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76333 $ -+ * $Date: 2017-03-09 09:33:15 +0800 (¶g¥|, 09 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch MII access -+ * Feature : MII access functions -+ * -+ */ -+ -+#ifndef _RTL8367C_ASICDRV_MII_MGR_H_ -+#define _RTL8367C_ASICDRV_MII_MGR_H_ -+ -+#define u32 unsigned int -+extern u32 mii_mgr_read(u32 phy_addr, u32 phy_register, u32 *read_data); -+extern u32 mii_mgr_write(u32 phy_addr, u32 phy_register, u32 write_data); -+ -+#endif /*_RTL8367C_ASICDRV_MII_MGR_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mirror.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mirror.h -new file mode 100644 -index 000000000000..23b788d7a629 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mirror.h -@@ -0,0 +1,49 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Port mirror related functions -+ * -+ */ -+ -+#ifndef _RTL8367C_ASICDRV_MIRROR_H_ -+#define _RTL8367C_ASICDRV_MIRROR_H_ -+ -+#include -+ -+extern ret_t rtl8367c_setAsicPortMirror(rtk_uint32 source, rtk_uint32 monitor); -+extern ret_t rtl8367c_getAsicPortMirror(rtk_uint32 *pSource, rtk_uint32 *pMonitor); -+extern ret_t rtl8367c_setAsicPortMirrorRxFunction(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicPortMirrorRxFunction(rtk_uint32* pEnabled); -+extern ret_t rtl8367c_setAsicPortMirrorTxFunction(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicPortMirrorTxFunction(rtk_uint32* pEnabled); -+extern ret_t rtl8367c_setAsicPortMirrorIsolation(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicPortMirrorIsolation(rtk_uint32* pEnabled); -+extern ret_t rtl8367c_setAsicPortMirrorPriority(rtk_uint32 priority); -+extern ret_t rtl8367c_getAsicPortMirrorPriority(rtk_uint32* pPriority); -+extern ret_t rtl8367c_setAsicPortMirrorMask(rtk_uint32 SourcePortmask); -+extern ret_t rtl8367c_getAsicPortMirrorMask(rtk_uint32 *pSourcePortmask); -+extern ret_t rtl8367c_setAsicPortMirrorVlanRxLeaky(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicPortMirrorVlanRxLeaky(rtk_uint32* pEnabled); -+extern ret_t rtl8367c_setAsicPortMirrorVlanTxLeaky(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicPortMirrorVlanTxLeaky(rtk_uint32* pEnabled); -+extern ret_t rtl8367c_setAsicPortMirrorIsolationRxLeaky(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicPortMirrorIsolationRxLeaky(rtk_uint32* pEnabled); -+extern ret_t rtl8367c_setAsicPortMirrorIsolationTxLeaky(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicPortMirrorIsolationTxLeaky(rtk_uint32* pEnabled); -+extern ret_t rtl8367c_setAsicPortMirrorRealKeep(rtk_uint32 mode); -+extern ret_t rtl8367c_getAsicPortMirrorRealKeep(rtk_uint32* pMode); -+extern ret_t rtl8367c_setAsicPortMirrorOverride(rtk_uint32 rxMirror, rtk_uint32 txMirror, rtk_uint32 aclMirror); -+extern ret_t rtl8367c_getAsicPortMirrorOverride(rtk_uint32 *pRxMirror, rtk_uint32 *pTxMirror, rtk_uint32 *pAclMirror); -+ -+#endif /*#ifndef _RTL8367C_ASICDRV_MIRROR_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_misc.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_misc.h -new file mode 100644 -index 000000000000..c666a7b58bd5 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_misc.h -@@ -0,0 +1,34 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Miscellaneous functions -+ * -+ */ -+ -+#ifndef _RTL8367C_ASICDRV_MISC_H_ -+#define _RTL8367C_ASICDRV_MISC_H_ -+ -+#include -+ -+extern ret_t rtl8367c_setAsicMacAddress(ether_addr_t mac); -+extern ret_t rtl8367c_getAsicMacAddress(ether_addr_t *pMac); -+extern ret_t rtl8367c_getAsicDebugInfo(rtk_uint32 port, rtk_uint32 *pDebugifo); -+extern ret_t rtl8367c_setAsicPortJamMode(rtk_uint32 mode); -+extern ret_t rtl8367c_getAsicPortJamMode(rtk_uint32* pMode); -+extern ret_t rtl8367c_setAsicMaxLengthCfg(rtk_uint32 cfgId, rtk_uint32 maxLength); -+extern ret_t rtl8367c_getAsicMaxLengthCfg(rtk_uint32 cfgId, rtk_uint32 *pMaxLength); -+extern ret_t rtl8367c_setAsicMaxLength(rtk_uint32 port, rtk_uint32 type, rtk_uint32 cfgId); -+extern ret_t rtl8367c_getAsicMaxLength(rtk_uint32 port, rtk_uint32 type, rtk_uint32 *pCfgId); -+ -+#endif /*_RTL8367C_ASICDRV_MISC_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_oam.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_oam.h -new file mode 100644 -index 000000000000..c09dc7698868 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_oam.h -@@ -0,0 +1,47 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 42321 $ -+ * $Date: 2013-08-26 13:51:29 +0800 (¶g¤@, 26 ¤K¤ë 2013) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : OAM related functions -+ * -+ */ -+ -+#ifndef _RTL8367C_ASICDRV_OAM_H_ -+#define _RTL8367C_ASICDRV_OAM_H_ -+ -+#include -+ -+enum OAMPARACT -+{ -+ OAM_PARFWD = 0, -+ OAM_PARLB, -+ OAM_PARDISCARD, -+ OAM_PARFWDCPU -+}; -+ -+enum OAMMULACT -+{ -+ OAM_MULFWD = 0, -+ OAM_MULDISCARD, -+ OAM_MULCPU -+}; -+ -+extern ret_t rtl8367c_setAsicOamParser(rtk_uint32 port, rtk_uint32 parser); -+extern ret_t rtl8367c_getAsicOamParser(rtk_uint32 port, rtk_uint32* pParser); -+extern ret_t rtl8367c_setAsicOamMultiplexer(rtk_uint32 port, rtk_uint32 multiplexer); -+extern ret_t rtl8367c_getAsicOamMultiplexer(rtk_uint32 port, rtk_uint32* pMultiplexer); -+extern ret_t rtl8367c_setAsicOamCpuPri(rtk_uint32 priority); -+extern ret_t rtl8367c_getAsicOamCpuPri(rtk_uint32 *pPriority); -+extern ret_t rtl8367c_setAsicOamEnable(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicOamEnable(rtk_uint32 *pEnabled); -+#endif /*_RTL8367C_ASICDRV_OAM_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_phy.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_phy.h -new file mode 100644 -index 000000000000..e993d6edf73c ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_phy.h -@@ -0,0 +1,43 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : PHY related functions -+ * -+ */ -+ -+#ifndef _RTL8367C_ASICDRV_PHY_H_ -+#define _RTL8367C_ASICDRV_PHY_H_ -+ -+#include -+ -+#define RTL8367C_PHY_REGNOMAX 0x1F -+#define RTL8367C_PHY_EXTERNALMAX 0x7 -+ -+#define RTL8367C_PHY_BASE 0x2000 -+#define RTL8367C_PHY_EXT_BASE 0xA000 -+ -+#define RTL8367C_PHY_OFFSET 5 -+#define RTL8367C_PHY_EXT_OFFSET 9 -+ -+#define RTL8367C_PHY_PAGE_ADDRESS 31 -+ -+ -+extern ret_t rtl8367c_setAsicPHYReg(rtk_uint32 phyNo, rtk_uint32 phyAddr, rtk_uint32 regData ); -+extern ret_t rtl8367c_getAsicPHYReg(rtk_uint32 phyNo, rtk_uint32 phyAddr, rtk_uint32* pRegData ); -+extern ret_t rtl8367c_setAsicPHYOCPReg(rtk_uint32 phyNo, rtk_uint32 ocpAddr, rtk_uint32 ocpData ); -+extern ret_t rtl8367c_getAsicPHYOCPReg(rtk_uint32 phyNo, rtk_uint32 ocpAddr, rtk_uint32 *pRegData ); -+extern ret_t rtl8367c_setAsicSdsReg(rtk_uint32 sdsId, rtk_uint32 sdsReg, rtk_uint32 sdsPage, rtk_uint32 value); -+extern ret_t rtl8367c_getAsicSdsReg(rtk_uint32 sdsId, rtk_uint32 sdsReg, rtk_uint32 sdsPage, rtk_uint32 *value); -+ -+#endif /*#ifndef _RTL8367C_ASICDRV_PHY_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_port.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_port.h -new file mode 100644 -index 000000000000..ad99d8560b7e ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_port.h -@@ -0,0 +1,237 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76333 $ -+ * $Date: 2017-03-09 09:33:15 +0800 (¶g¥|, 09 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Port security related functions -+ * -+ */ -+ -+#ifndef _RTL8367C_ASICDRV_PORTSECURITY_H_ -+#define _RTL8367C_ASICDRV_PORTSECURITY_H_ -+ -+#include -+#include -+#include -+ -+/****************************************************************/ -+/* Type Definition */ -+/****************************************************************/ -+ -+#define RTL8367C_MAC7 7 -+#define RTL8367C_EXTNO 3 -+ -+#define RTL8367C_RTCT_PAGE (11) -+#define RTL8367C_RTCT_RESULT_A_REG (27) -+#define RTL8367C_RTCT_RESULT_B_REG (28) -+#define RTL8367C_RTCT_RESULT_C_REG (29) -+#define RTL8367C_RTCT_RESULT_D_REG (30) -+#define RTL8367C_RTCT_STATUS_REG (26) -+ -+enum L2_SECURITY_BEHAVE -+{ -+ L2_BEHAVE_FLOODING = 0, -+ L2_BEHAVE_DROP, -+ L2_BEHAVE_TRAP, -+ L2_BEHAVE_END -+}; -+ -+enum L2_UNDA_BEHAVE -+{ -+ L2_UNDA_BEHAVE_FLOODING_PMASK = 0, -+ L2_UNDA_BEHAVE_DROP, -+ L2_UNDA_BEHAVE_TRAP, -+ L2_UNDA_BEHAVE_FLOODING, -+ L2_UNDA_BEHAVE_END -+}; -+ -+enum L2_SECURITY_SA_BEHAVE -+{ -+ L2_BEHAVE_SA_FLOODING = 0, -+ L2_BEHAVE_SA_DROP, -+ L2_BEHAVE_SA_TRAP, -+ L2_BEHAVE_SA_COPY28051, -+ L2_BEHAVE_SA_END -+}; -+ -+/* enum for port current link speed */ -+enum SPEEDMODE -+{ -+ SPD_10M = 0, -+ SPD_100M, -+ SPD_1000M, -+ SPD_2500M -+}; -+ -+/* enum for mac link mode */ -+enum LINKMODE -+{ -+ MAC_NORMAL = 0, -+ MAC_FORCE, -+}; -+ -+/* enum for port current link duplex mode */ -+enum DUPLEXMODE -+{ -+ HALF_DUPLEX = 0, -+ FULL_DUPLEX -+}; -+ -+/* enum for port current MST mode */ -+enum MSTMODE -+{ -+ SLAVE_MODE= 0, -+ MASTER_MODE -+}; -+ -+ -+enum EXTMODE -+{ -+ EXT_DISABLE = 0, -+ EXT_RGMII, -+ EXT_MII_MAC, -+ EXT_MII_PHY, -+ EXT_TMII_MAC, -+ EXT_TMII_PHY, -+ EXT_GMII, -+ EXT_RMII_MAC, -+ EXT_RMII_PHY, -+ EXT_SGMII, -+ EXT_HSGMII, -+ EXT_1000X_100FX, -+ EXT_1000X, -+ EXT_100FX, -+ EXT_RGMII_2, -+ EXT_MII_MAC_2, -+ EXT_MII_PHY_2, -+ EXT_TMII_MAC_2, -+ EXT_TMII_PHY_2, -+ EXT_RMII_MAC_2, -+ EXT_RMII_PHY_2, -+ EXT_END -+}; -+ -+enum DOSTYPE -+{ -+ DOS_DAEQSA = 0, -+ DOS_LANDATTACKS, -+ DOS_BLATATTACKS, -+ DOS_SYNFINSCAN, -+ DOS_XMASCAN, -+ DOS_NULLSCAN, -+ DOS_SYN1024, -+ DOS_TCPSHORTHDR, -+ DOS_TCPFRAGERROR, -+ DOS_ICMPFRAGMENT, -+ DOS_END, -+ -+}; -+ -+typedef struct rtl8367c_port_ability_s{ -+ rtk_uint16 forcemode; -+ rtk_uint16 mstfault; -+ rtk_uint16 mstmode; -+ rtk_uint16 nway; -+ rtk_uint16 txpause; -+ rtk_uint16 rxpause; -+ rtk_uint16 link; -+ rtk_uint16 duplex; -+ rtk_uint16 speed; -+}rtl8367c_port_ability_t; -+ -+typedef struct rtl8367c_port_status_s{ -+ -+ rtk_uint16 lpi1000; -+ rtk_uint16 lpi100; -+ rtk_uint16 mstfault; -+ rtk_uint16 mstmode; -+ rtk_uint16 nway; -+ rtk_uint16 txpause; -+ rtk_uint16 rxpause; -+ rtk_uint16 link; -+ rtk_uint16 duplex; -+ rtk_uint16 speed; -+ -+}rtl8367c_port_status_t; -+ -+typedef struct rtct_result_s -+{ -+ rtk_uint32 channelAShort; -+ rtk_uint32 channelBShort; -+ rtk_uint32 channelCShort; -+ rtk_uint32 channelDShort; -+ -+ rtk_uint32 channelAOpen; -+ rtk_uint32 channelBOpen; -+ rtk_uint32 channelCOpen; -+ rtk_uint32 channelDOpen; -+ -+ rtk_uint32 channelAMismatch; -+ rtk_uint32 channelBMismatch; -+ rtk_uint32 channelCMismatch; -+ rtk_uint32 channelDMismatch; -+ -+ rtk_uint32 channelALinedriver; -+ rtk_uint32 channelBLinedriver; -+ rtk_uint32 channelCLinedriver; -+ rtk_uint32 channelDLinedriver; -+ -+ rtk_uint32 channelALen; -+ rtk_uint32 channelBLen; -+ rtk_uint32 channelCLen; -+ rtk_uint32 channelDLen; -+} rtl8367c_port_rtct_result_t; -+ -+ -+/****************************************************************/ -+/* Driver Proto Type Definition */ -+/****************************************************************/ -+extern ret_t rtl8367c_setAsicPortUnknownDaBehavior(rtk_uint32 port, rtk_uint32 behavior); -+extern ret_t rtl8367c_getAsicPortUnknownDaBehavior(rtk_uint32 port, rtk_uint32 *pBehavior); -+extern ret_t rtl8367c_setAsicPortUnknownSaBehavior(rtk_uint32 behavior); -+extern ret_t rtl8367c_getAsicPortUnknownSaBehavior(rtk_uint32 *pBehavior); -+extern ret_t rtl8367c_setAsicPortUnmatchedSaBehavior(rtk_uint32 behavior); -+extern ret_t rtl8367c_getAsicPortUnmatchedSaBehavior(rtk_uint32 *pBehavior); -+extern ret_t rtl8367c_setAsicPortUnmatchedSaMoving(rtk_uint32 port, rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicPortUnmatchedSaMoving(rtk_uint32 port, rtk_uint32 *pEnabled); -+extern ret_t rtl8367c_setAsicPortUnknownDaFloodingPortmask(rtk_uint32 portmask); -+extern ret_t rtl8367c_getAsicPortUnknownDaFloodingPortmask(rtk_uint32 *pPortmask); -+extern ret_t rtl8367c_setAsicPortUnknownMulticastFloodingPortmask(rtk_uint32 portmask); -+extern ret_t rtl8367c_getAsicPortUnknownMulticastFloodingPortmask(rtk_uint32 *pPortmask); -+extern ret_t rtl8367c_setAsicPortBcastFloodingPortmask(rtk_uint32 portmask); -+extern ret_t rtl8367c_getAsicPortBcastFloodingPortmask(rtk_uint32 *pPortmask); -+extern ret_t rtl8367c_setAsicPortBlockSpa(rtk_uint32 port, rtk_uint32 block); -+extern ret_t rtl8367c_getAsicPortBlockSpa(rtk_uint32 port, rtk_uint32 *pBlock); -+extern ret_t rtl8367c_setAsicPortForceLink(rtk_uint32 port, rtl8367c_port_ability_t *pPortAbility); -+extern ret_t rtl8367c_getAsicPortForceLink(rtk_uint32 port, rtl8367c_port_ability_t *pPortAbility); -+extern ret_t rtl8367c_getAsicPortStatus(rtk_uint32 port, rtl8367c_port_status_t *pPortStatus); -+extern ret_t rtl8367c_setAsicPortForceLinkExt(rtk_uint32 id, rtl8367c_port_ability_t *pPortAbility); -+extern ret_t rtl8367c_getAsicPortForceLinkExt(rtk_uint32 id, rtl8367c_port_ability_t *pPortAbility); -+extern ret_t rtl8367c_setAsicPortExtMode(rtk_uint32 id, rtk_uint32 mode); -+extern ret_t rtl8367c_getAsicPortExtMode(rtk_uint32 id, rtk_uint32 *pMode); -+extern ret_t rtl8367c_setAsicPortDos(rtk_uint32 type, rtk_uint32 drop); -+extern ret_t rtl8367c_getAsicPortDos(rtk_uint32 type, rtk_uint32* pDrop); -+extern ret_t rtl8367c_setAsicPortEnableAll(rtk_uint32 enable); -+extern ret_t rtl8367c_getAsicPortEnableAll(rtk_uint32 *pEnable); -+extern ret_t rtl8367c_setAsicPortSmallIpg(rtk_uint32 port, rtk_uint32 enable); -+extern ret_t rtl8367c_getAsicPortSmallIpg(rtk_uint32 port, rtk_uint32* pEnable); -+extern ret_t rtl8367c_setAsicPortLoopback(rtk_uint32 port, rtk_uint32 enable); -+extern ret_t rtl8367c_getAsicPortLoopback(rtk_uint32 port, rtk_uint32 *pEnable); -+extern ret_t rtl8367c_setAsicPortRTCTEnable(rtk_uint32 portmask); -+extern ret_t rtl8367c_setAsicPortRTCTDisable(rtk_uint32 portmask); -+extern ret_t rtl8367c_getAsicPortRTCTResult(rtk_uint32 port, rtl8367c_port_rtct_result_t *pResult); -+extern ret_t rtl8367c_sdsReset(rtk_uint32 id); -+extern ret_t rtl8367c_getSdsLinkStatus(rtk_uint32 ext_id, rtk_uint32 *pSignalDetect, rtk_uint32 *pSync, rtk_uint32 *pLink); -+extern ret_t rtl8367c_setSgmiiNway(rtk_uint32 ext_id, rtk_uint32 state); -+extern ret_t rtl8367c_getSgmiiNway(rtk_uint32 ext_id, rtk_uint32 *pState); -+ -+#endif /*_RTL8367C_ASICDRV_PORTSECURITY_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_portIsolation.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_portIsolation.h -new file mode 100644 -index 000000000000..e23d88e81f60 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_portIsolation.h -@@ -0,0 +1,28 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Port isolation related functions -+ * -+ */ -+ -+#ifndef _RTL8367C_ASICDRV_PORTISOLATION_H_ -+#define _RTL8367C_ASICDRV_PORTISOLATION_H_ -+ -+#include -+ -+extern ret_t rtl8367c_setAsicPortIsolationPermittedPortmask(rtk_uint32 port, rtk_uint32 permitPortmask); -+extern ret_t rtl8367c_getAsicPortIsolationPermittedPortmask(rtk_uint32 port, rtk_uint32 *pPermitPortmask); -+extern ret_t rtl8367c_setAsicPortIsolationEfid(rtk_uint32 port, rtk_uint32 efid); -+extern ret_t rtl8367c_getAsicPortIsolationEfid(rtk_uint32 port, rtk_uint32 *pEfid); -+ -+#endif /*_RTL8367C_ASICDRV_PORTISOLATION_H_*/ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_qos.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_qos.h -new file mode 100644 -index 000000000000..d0a8995879c3 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_qos.h -@@ -0,0 +1,96 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : QoS related functions -+ * -+ */ -+ -+#ifndef _RTL8367C_ASICDRV_QOS_H_ -+#define _RTL8367C_ASICDRV_QOS_H_ -+ -+#include -+ -+#define RTL8367C_DECISIONPRIMAX 0xFF -+ -+/* enum Priority Selection Types */ -+enum PRIDECISION -+{ -+ PRIDEC_PORT = 0, -+ PRIDEC_ACL, -+ PRIDEC_DSCP, -+ PRIDEC_1Q, -+ PRIDEC_1AD, -+ PRIDEC_CVLAN, -+ PRIDEC_DA, -+ PRIDEC_SA, -+ PRIDEC_END, -+}; -+ -+/* enum Priority Selection Index */ -+enum RTL8367C_PRIDEC_TABLE -+{ -+ PRIDEC_IDX0 = 0, -+ PRIDEC_IDX1, -+ PRIDEC_IDX_END, -+}; -+ -+enum RTL8367C_DOT1P_PRISEL -+{ -+ DOT1P_PRISEL_USER = 0, -+ DOT1P_PRISEL_TAG, -+ DOT1P_PRISEL_END -+}; -+ -+enum RTL8367C_DSCP_PRISEL -+{ -+ DSCP_PRISEL_INTERNAL = 0, -+ DSCP_PRISEL_DSCP, -+ DSCP_PRISEL_USER , -+ DSCP_PRISEL_END -+}; -+ -+ -+extern ret_t rtl8367c_setAsicRemarkingDot1pAbility(rtk_uint32 port, rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicRemarkingDot1pAbility(rtk_uint32 port, rtk_uint32* pEnabled); -+extern ret_t rtl8367c_setAsicRemarkingDot1pParameter(rtk_uint32 priority, rtk_uint32 newPriority ); -+extern ret_t rtl8367c_getAsicRemarkingDot1pParameter(rtk_uint32 priority, rtk_uint32 *pNewPriority ); -+extern ret_t rtl8367c_setAsicRemarkingDot1pSrc(rtk_uint32 type); -+extern ret_t rtl8367c_getAsicRemarkingDot1pSrc(rtk_uint32 *pType); -+extern ret_t rtl8367c_setAsicRemarkingDscpAbility(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicRemarkingDscpAbility(rtk_uint32* pEnabled); -+extern ret_t rtl8367c_setAsicRemarkingDscpParameter(rtk_uint32 priority, rtk_uint32 newDscp ); -+extern ret_t rtl8367c_getAsicRemarkingDscpParameter(rtk_uint32 priority, rtk_uint32* pNewDscp ); -+ -+extern ret_t rtl8367c_setAsicPriorityDot1qRemapping(rtk_uint32 srcpriority, rtk_uint32 priority ); -+extern ret_t rtl8367c_getAsicPriorityDot1qRemapping(rtk_uint32 srcpriority, rtk_uint32 *pPriority ); -+extern ret_t rtl8367c_setAsicPriorityDscpBased(rtk_uint32 dscp, rtk_uint32 priority ); -+extern ret_t rtl8367c_getAsicPriorityDscpBased(rtk_uint32 dscp, rtk_uint32 *pPriority ); -+extern ret_t rtl8367c_setAsicPriorityPortBased(rtk_uint32 port, rtk_uint32 priority ); -+extern ret_t rtl8367c_getAsicPriorityPortBased(rtk_uint32 port, rtk_uint32 *pPriority ); -+extern ret_t rtl8367c_setAsicPriorityDecision(rtk_uint32 index, rtk_uint32 prisrc, rtk_uint32 decisionPri); -+extern ret_t rtl8367c_getAsicPriorityDecision(rtk_uint32 index, rtk_uint32 prisrc, rtk_uint32* pDecisionPri); -+extern ret_t rtl8367c_setAsicPriorityToQIDMappingTable(rtk_uint32 qnum, rtk_uint32 priority, rtk_uint32 qid ); -+extern ret_t rtl8367c_getAsicPriorityToQIDMappingTable(rtk_uint32 qnum, rtk_uint32 priority, rtk_uint32* pQid); -+extern ret_t rtl8367c_setAsicOutputQueueMappingIndex(rtk_uint32 port, rtk_uint32 qnum ); -+extern ret_t rtl8367c_getAsicOutputQueueMappingIndex(rtk_uint32 port, rtk_uint32 *pQnum ); -+ -+extern ret_t rtl8367c_setAsicRemarkingDscpSrc(rtk_uint32 type); -+extern ret_t rtl8367c_getAsicRemarkingDscpSrc(rtk_uint32 *pType); -+extern ret_t rtl8367c_setAsicRemarkingDscp2Dscp(rtk_uint32 dscp, rtk_uint32 rmkDscp); -+extern ret_t rtl8367c_getAsicRemarkingDscp2Dscp(rtk_uint32 dscp, rtk_uint32 *pRmkDscp); -+ -+extern ret_t rtl8367c_setAsicPortPriorityDecisionIndex(rtk_uint32 port, rtk_uint32 index ); -+extern ret_t rtl8367c_getAsicPortPriorityDecisionIndex(rtk_uint32 port, rtk_uint32 *pIndex ); -+ -+#endif /*#ifndef _RTL8367C_ASICDRV_QOS_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rldp.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rldp.h -new file mode 100644 -index 000000000000..cde970b638b3 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rldp.h -@@ -0,0 +1,60 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 42321 $ -+ * $Date: 2013-08-26 13:51:29 +0800 (¶g¤@, 26 ¤K¤ë 2013) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : RLDP related functions -+ * -+ */ -+ -+#ifndef _RTL8367C_ASICDRV_RLDP_H_ -+#define _RTL8367C_ASICDRV_RLDP_H_ -+ -+#include -+#include -+ -+extern ret_t rtl8367c_setAsicRldp(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicRldp(rtk_uint32 *pEnabled); -+extern ret_t rtl8367c_setAsicRldpEnable8051(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicRldpEnable8051(rtk_uint32 *pEnabled); -+extern ret_t rtl8367c_setAsicRldpCompareRandomNumber(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicRldpCompareRandomNumber(rtk_uint32 *pEnabled); -+extern ret_t rtl8367c_setAsicRldpIndicatorSource(rtk_uint32 src); -+extern ret_t rtl8367c_getAsicRldpIndicatorSource(rtk_uint32 *pSrc); -+extern ret_t rtl8367c_setAsicRldpCheckingStatePara(rtk_uint32 retryCount, rtk_uint32 retryPeriod); -+extern ret_t rtl8367c_getAsicRldpCheckingStatePara(rtk_uint32 *pRetryCount, rtk_uint32 *pRetryPeriod); -+extern ret_t rtl8367c_setAsicRldpLoopStatePara(rtk_uint32 retryCount, rtk_uint32 retryPeriod); -+extern ret_t rtl8367c_getAsicRldpLoopStatePara(rtk_uint32 *pRetryCount, rtk_uint32 *pRetryPeriod); -+extern ret_t rtl8367c_setAsicRldpTxPortmask(rtk_uint32 portmask); -+extern ret_t rtl8367c_getAsicRldpTxPortmask(rtk_uint32 *pPortmask); -+extern ret_t rtl8367c_setAsicRldpMagicNum(ether_addr_t seed); -+extern ret_t rtl8367c_getAsicRldpMagicNum(ether_addr_t *pSeed); -+extern ret_t rtl8367c_getAsicRldpLoopedPortmask(rtk_uint32 *pPortmask); -+extern ret_t rtl8367c_setAsicRldp8051Portmask(rtk_uint32 portmask); -+extern ret_t rtl8367c_getAsicRldp8051Portmask(rtk_uint32 *pPortmask); -+ -+ -+extern ret_t rtl8367c_getAsicRldpRandomNumber(ether_addr_t *pRandNumber); -+extern ret_t rtl8367c_getAsicRldpLoopedPortPair(rtk_uint32 port, rtk_uint32 *pLoopedPair); -+extern ret_t rtl8367c_setAsicRlppTrap8051(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicRlppTrap8051(rtk_uint32 *pEnabled); -+ -+extern ret_t rtl8367c_setAsicRldpLeaveLoopedPortmask(rtk_uint32 portmask); -+extern ret_t rtl8367c_getAsicRldpLeaveLoopedPortmask(rtk_uint32 *pPortmask); -+ -+extern ret_t rtl8367c_setAsicRldpEnterLoopedPortmask(rtk_uint32 portmask); -+extern ret_t rtl8367c_getAsicRldpEnterLoopedPortmask(rtk_uint32 *pPortmask); -+ -+extern ret_t rtl8367c_setAsicRldpTriggerMode(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicRldpTriggerMode(rtk_uint32 *pEnabled); -+ -+#endif /*_RTL8367C_ASICDRV_RLDP_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rma.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rma.h -new file mode 100644 -index 000000000000..10c707544f93 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rma.h -@@ -0,0 +1,57 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 64716 $ -+ * $Date: 2015-12-31 16:31:55 +0800 (¶g¥|, 31 ¤Q¤G¤ë 2015) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : RMA related functions -+ * -+ */ -+ -+#ifndef _RTL8367C_ASICDRV_RMA_H_ -+#define _RTL8367C_ASICDRV_RMA_H_ -+ -+#include -+ -+#define RTL8367C_RMAMAX 0x2F -+ -+enum RTL8367C_RMAOP -+{ -+ RMAOP_FORWARD = 0, -+ RMAOP_TRAP_TO_CPU, -+ RMAOP_DROP, -+ RMAOP_FORWARD_EXCLUDE_CPU, -+ RMAOP_END -+}; -+ -+ -+typedef struct rtl8367c_rma_s{ -+ -+ rtk_uint16 operation; -+ rtk_uint16 discard_storm_filter; -+ rtk_uint16 trap_priority; -+ rtk_uint16 keep_format; -+ rtk_uint16 vlan_leaky; -+ rtk_uint16 portiso_leaky; -+ -+}rtl8367c_rma_t; -+ -+ -+extern ret_t rtl8367c_setAsicRma(rtk_uint32 index, rtl8367c_rma_t* pRmacfg); -+extern ret_t rtl8367c_getAsicRma(rtk_uint32 index, rtl8367c_rma_t* pRmacfg); -+extern ret_t rtl8367c_setAsicRmaCdp(rtl8367c_rma_t* pRmacfg); -+extern ret_t rtl8367c_getAsicRmaCdp(rtl8367c_rma_t* pRmacfg); -+extern ret_t rtl8367c_setAsicRmaCsstp(rtl8367c_rma_t* pRmacfg); -+extern ret_t rtl8367c_getAsicRmaCsstp(rtl8367c_rma_t* pRmacfg); -+extern ret_t rtl8367c_setAsicRmaLldp(rtk_uint32 enabled, rtl8367c_rma_t* pRmacfg); -+extern ret_t rtl8367c_getAsicRmaLldp(rtk_uint32 *pEnabled, rtl8367c_rma_t* pRmacfg); -+ -+#endif /*#ifndef _RTL8367C_ASICDRV_RMA_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_scheduling.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_scheduling.h -new file mode 100644 -index 000000000000..919a4ca69262 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_scheduling.h -@@ -0,0 +1,58 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Packet Scheduling related functions -+ * -+ */ -+ -+#ifndef _RTL8367C_ASICDRV_SCHEDULING_H_ -+#define _RTL8367C_ASICDRV_SCHEDULING_H_ -+ -+#include -+ -+#define RTL8367C_QWEIGHTMAX 0x7F -+#define RTL8367C_PORT_QUEUE_METER_INDEX_MAX 7 -+ -+/* enum for queue type */ -+enum QUEUETYPE -+{ -+ QTYPE_STRICT = 0, -+ QTYPE_WFQ, -+}; -+extern ret_t rtl8367c_setAsicLeakyBucketParameter(rtk_uint32 tick, rtk_uint32 token); -+extern ret_t rtl8367c_getAsicLeakyBucketParameter(rtk_uint32 *tick, rtk_uint32 *token); -+extern ret_t rtl8367c_setAsicAprMeter(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 apridx); -+extern ret_t rtl8367c_getAsicAprMeter(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 *apridx); -+extern ret_t rtl8367c_setAsicPprMeter(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 ppridx); -+extern ret_t rtl8367c_getAsicPprMeter(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 *ppridx); -+extern ret_t rtl8367c_setAsicAprEnable(rtk_uint32 port, rtk_uint32 aprEnable); -+extern ret_t rtl8367c_getAsicAprEnable(rtk_uint32 port, rtk_uint32 *aprEnable); -+extern ret_t rtl8367c_setAsicPprEnable(rtk_uint32 port, rtk_uint32 pprEnable); -+extern ret_t rtl8367c_getAsicPprEnable(rtk_uint32 port, rtk_uint32 *pprEnable); -+ -+extern ret_t rtl8367c_setAsicWFQWeight(rtk_uint32, rtk_uint32 queueid, rtk_uint32 weight ); -+extern ret_t rtl8367c_getAsicWFQWeight(rtk_uint32, rtk_uint32 queueid, rtk_uint32 *weight ); -+extern ret_t rtl8367c_setAsicWFQBurstSize(rtk_uint32 burstsize); -+extern ret_t rtl8367c_getAsicWFQBurstSize(rtk_uint32 *burstsize); -+ -+extern ret_t rtl8367c_setAsicQueueType(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 queueType); -+extern ret_t rtl8367c_getAsicQueueType(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 *queueType); -+extern ret_t rtl8367c_setAsicQueueRate(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 ppridx, rtk_uint32 apridx ); -+extern ret_t rtl8367c_getAsicQueueRate(rtk_uint32 port, rtk_uint32 qid, rtk_uint32* ppridx, rtk_uint32* apridx ); -+extern ret_t rtl8367c_setAsicPortEgressRate(rtk_uint32 port, rtk_uint32 rate); -+extern ret_t rtl8367c_getAsicPortEgressRate(rtk_uint32 port, rtk_uint32 *rate); -+extern ret_t rtl8367c_setAsicPortEgressRateIfg(rtk_uint32 ifg); -+extern ret_t rtl8367c_getAsicPortEgressRateIfg(rtk_uint32 *ifg); -+ -+#endif /*_RTL8367C_ASICDRV_SCHEDULING_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_storm.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_storm.h -new file mode 100644 -index 000000000000..3865b5225a81 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_storm.h -@@ -0,0 +1,61 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Storm control filtering related functions -+ * -+ */ -+ -+#ifndef _RTL8367C_ASICDRV_STORM_H_ -+#define _RTL8367C_ASICDRV_STORM_H_ -+ -+#include -+ -+extern ret_t rtl8367c_setAsicStormFilterBroadcastEnable(rtk_uint32 port, rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicStormFilterBroadcastEnable(rtk_uint32 port, rtk_uint32 *pEnabled); -+extern ret_t rtl8367c_setAsicStormFilterBroadcastMeter(rtk_uint32 port, rtk_uint32 meter); -+extern ret_t rtl8367c_getAsicStormFilterBroadcastMeter(rtk_uint32 port, rtk_uint32 *pMeter); -+extern ret_t rtl8367c_setAsicStormFilterMulticastEnable(rtk_uint32 port, rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicStormFilterMulticastEnable(rtk_uint32 port, rtk_uint32 *pEnabled); -+extern ret_t rtl8367c_setAsicStormFilterMulticastMeter(rtk_uint32 port, rtk_uint32 meter); -+extern ret_t rtl8367c_getAsicStormFilterMulticastMeter(rtk_uint32 port, rtk_uint32 *pMeter); -+extern ret_t rtl8367c_setAsicStormFilterUnknownMulticastEnable(rtk_uint32 port, rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicStormFilterUnknownMulticastEnable(rtk_uint32 port, rtk_uint32 *pEnabled); -+extern ret_t rtl8367c_setAsicStormFilterUnknownMulticastMeter(rtk_uint32 port, rtk_uint32 meter); -+extern ret_t rtl8367c_getAsicStormFilterUnknownMulticastMeter(rtk_uint32 port, rtk_uint32 *pMeter); -+extern ret_t rtl8367c_setAsicStormFilterUnknownUnicastEnable(rtk_uint32 port, rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicStormFilterUnknownUnicastEnable(rtk_uint32 port, rtk_uint32 *pEnabled); -+extern ret_t rtl8367c_setAsicStormFilterUnknownUnicastMeter(rtk_uint32 port, rtk_uint32 meter); -+extern ret_t rtl8367c_getAsicStormFilterUnknownUnicastMeter(rtk_uint32 port, rtk_uint32 *pMeter); -+extern ret_t rtl8367c_setAsicStormFilterExtBroadcastMeter(rtk_uint32 meter); -+extern ret_t rtl8367c_getAsicStormFilterExtBroadcastMeter(rtk_uint32 *pMeter); -+extern ret_t rtl8367c_setAsicStormFilterExtMulticastMeter(rtk_uint32 meter); -+extern ret_t rtl8367c_getAsicStormFilterExtMulticastMeter(rtk_uint32 *pMeter); -+extern ret_t rtl8367c_setAsicStormFilterExtUnknownMulticastMeter(rtk_uint32 meter); -+extern ret_t rtl8367c_getAsicStormFilterExtUnknownMulticastMeter(rtk_uint32 *pMeter); -+extern ret_t rtl8367c_setAsicStormFilterExtUnknownUnicastMeter(rtk_uint32 meter); -+extern ret_t rtl8367c_getAsicStormFilterExtUnknownUnicastMeter(rtk_uint32 *pMeter); -+extern ret_t rtl8367c_setAsicStormFilterExtBroadcastEnable(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicStormFilterExtBroadcastEnable(rtk_uint32 *pEnabled); -+extern ret_t rtl8367c_setAsicStormFilterExtMulticastEnable(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicStormFilterExtMulticastEnable(rtk_uint32 *pEnabled); -+extern ret_t rtl8367c_setAsicStormFilterExtUnknownMulticastEnable(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicStormFilterExtUnknownMulticastEnable(rtk_uint32 *pEnabled); -+extern ret_t rtl8367c_setAsicStormFilterExtUnknownUnicastEnable(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicStormFilterExtUnknownUnicastEnable(rtk_uint32 *pEnabled); -+extern ret_t rtl8367c_setAsicStormFilterExtEnablePortMask(rtk_uint32 portmask); -+extern ret_t rtl8367c_getAsicStormFilterExtEnablePortMask(rtk_uint32 *pPortmask); -+ -+ -+#endif /*_RTL8367C_ASICDRV_STORM_H_*/ -+ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_svlan.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_svlan.h -new file mode 100644 -index 000000000000..5a6a4a83290a ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_svlan.h -@@ -0,0 +1,132 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : SVLAN related functions -+ * -+ */ -+ -+#ifndef _RTL8367C_ASICDRV_SVLAN_H_ -+#define _RTL8367C_ASICDRV_SVLAN_H_ -+ -+#include -+ -+#define RTL8367C_C2SIDXNO 128 -+#define RTL8367C_C2SIDXMAX (RTL8367C_C2SIDXNO-1) -+#define RTL8367C_MC2SIDXNO 32 -+#define RTL8367C_MC2SIDXMAX (RTL8367C_MC2SIDXNO-1) -+#define RTL8367C_SP2CIDXNO 128 -+#define RTL8367C_SP2CMAX (RTL8367C_SP2CIDXNO-1) -+ -+#define RTL8367C_SVLAN_MEMCONF_LEN 4 -+#define RTL8367C_SVLAN_MC2S_LEN 5 -+#define RTL8367C_SVLAN_SP2C_LEN 2 -+ -+enum RTL8367C_SPRISEL -+{ -+ SPRISEL_INTERNALPRI = 0, -+ SPRISEL_CTAGPRI, -+ SPRISEL_VSPRI, -+ SPRISEL_PBPRI, -+ SPRISEL_END -+}; -+ -+enum RTL8367C_SUNACCEPT -+{ -+ SUNACCEPT_DROP = 0, -+ SUNACCEPT_TRAP, -+ SUNACCEPT_SVLAN, -+ SUNACCEPT_END -+}; -+ -+enum RTL8367C_SVLAN_MC2S_MODE -+{ -+ SVLAN_MC2S_MODE_MAC = 0, -+ SVLAN_MC2S_MODE_IP, -+ SVLAN_MC2S_MODE_END -+}; -+ -+ -+typedef struct rtl8367c_svlan_memconf_s{ -+ -+ rtk_uint16 vs_member:11; -+ rtk_uint16 vs_untag:11; -+ -+ rtk_uint16 vs_fid_msti:4; -+ rtk_uint16 vs_priority:3; -+ rtk_uint16 vs_force_fid:1; -+ rtk_uint16 reserved:8; -+ -+ rtk_uint16 vs_svid:12; -+ rtk_uint16 vs_efiden:1; -+ rtk_uint16 vs_efid:3; -+ -+ -+}rtl8367c_svlan_memconf_t; -+ -+ -+typedef struct rtl8367c_svlan_mc2s_s{ -+ -+ rtk_uint16 valid:1; -+ rtk_uint16 format:1; -+ rtk_uint16 svidx:6; -+ rtk_uint32 sdata; -+ rtk_uint32 smask; -+}rtl8367c_svlan_mc2s_t; -+ -+ -+typedef struct rtl8367c_svlan_s2c_s{ -+ -+ rtk_uint16 valid:1; -+ rtk_uint16 svidx:6; -+ rtk_uint16 dstport:4; -+ rtk_uint32 vid:12; -+}rtl8367c_svlan_s2c_t; -+ -+extern ret_t rtl8367c_setAsicSvlanIngressUntag(rtk_uint32 mode); -+extern ret_t rtl8367c_getAsicSvlanIngressUntag(rtk_uint32* pMode); -+extern ret_t rtl8367c_setAsicSvlanIngressUnmatch(rtk_uint32 mode); -+extern ret_t rtl8367c_getAsicSvlanIngressUnmatch(rtk_uint32* pMode); -+extern ret_t rtl8367c_setAsicSvlanTrapPriority(rtk_uint32 priority); -+extern ret_t rtl8367c_getAsicSvlanTrapPriority(rtk_uint32* pPriority); -+extern ret_t rtl8367c_setAsicSvlanDefaultVlan(rtk_uint32 port, rtk_uint32 index); -+extern ret_t rtl8367c_getAsicSvlanDefaultVlan(rtk_uint32 port, rtk_uint32* pIndex); -+ -+extern ret_t rtl8367c_setAsicSvlanMemberConfiguration(rtk_uint32 index,rtl8367c_svlan_memconf_t* pSvlanMemCfg); -+extern ret_t rtl8367c_getAsicSvlanMemberConfiguration(rtk_uint32 index,rtl8367c_svlan_memconf_t* pSvlanMemCfg); -+ -+extern ret_t rtl8367c_setAsicSvlanPrioritySel(rtk_uint32 priSel); -+extern ret_t rtl8367c_getAsicSvlanPrioritySel(rtk_uint32* pPriSel); -+extern ret_t rtl8367c_setAsicSvlanTpid(rtk_uint32 protocolType); -+extern ret_t rtl8367c_getAsicSvlanTpid(rtk_uint32* pProtocolType); -+extern ret_t rtl8367c_setAsicSvlanUplinkPortMask(rtk_uint32 portMask); -+extern ret_t rtl8367c_getAsicSvlanUplinkPortMask(rtk_uint32* pPortmask); -+extern ret_t rtl8367c_setAsicSvlanEgressUnassign(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicSvlanEgressUnassign(rtk_uint32* pEnabled); -+extern ret_t rtl8367c_setAsicSvlanC2SConf(rtk_uint32 index, rtk_uint32 evid, rtk_uint32 portmask, rtk_uint32 svidx); -+extern ret_t rtl8367c_getAsicSvlanC2SConf(rtk_uint32 index, rtk_uint32* pEvid, rtk_uint32* pPortmask, rtk_uint32* pSvidx); -+extern ret_t rtl8367c_setAsicSvlanMC2SConf(rtk_uint32 index,rtl8367c_svlan_mc2s_t* pSvlanMc2sCfg); -+extern ret_t rtl8367c_getAsicSvlanMC2SConf(rtk_uint32 index,rtl8367c_svlan_mc2s_t* pSvlanMc2sCfg); -+extern ret_t rtl8367c_setAsicSvlanSP2CConf(rtk_uint32 index,rtl8367c_svlan_s2c_t* pSvlanSp2cCfg); -+extern ret_t rtl8367c_getAsicSvlanSP2CConf(rtk_uint32 index,rtl8367c_svlan_s2c_t* pSvlanSp2cCfg); -+extern ret_t rtl8367c_setAsicSvlanDmacCvidSel(rtk_uint32 port, rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicSvlanDmacCvidSel(rtk_uint32 port, rtk_uint32* pEnabled); -+extern ret_t rtl8367c_setAsicSvlanUntagVlan(rtk_uint32 index); -+extern ret_t rtl8367c_getAsicSvlanUntagVlan(rtk_uint32* pIndex); -+extern ret_t rtl8367c_setAsicSvlanUnmatchVlan(rtk_uint32 index); -+extern ret_t rtl8367c_getAsicSvlanUnmatchVlan(rtk_uint32* pIndex); -+extern ret_t rtl8367c_setAsicSvlanLookupType(rtk_uint32 type); -+extern ret_t rtl8367c_getAsicSvlanLookupType(rtk_uint32* pType); -+ -+ -+#endif /*#ifndef _RTL8367C_ASICDRV_SVLAN_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_trunking.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_trunking.h -new file mode 100644 -index 000000000000..2e3a682819db ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_trunking.h -@@ -0,0 +1,48 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Port trunking related functions -+ * -+ */ -+ -+ -+#ifndef _RTL8367C_ASICDRV_TRUNKING_H_ -+#define _RTL8367C_ASICDRV_TRUNKING_H_ -+ -+#include -+ -+#define RTL8367C_MAX_TRUNK_GID (2) -+#define RTL8367C_TRUNKING_PORTNO (4) -+#define RTL8367C_TRUNKING1_PORTN0 (2) -+#define RTL8367C_TRUNKING_HASHVALUE_MAX (15) -+ -+extern ret_t rtl8367c_setAsicTrunkingGroup(rtk_uint32 group, rtk_uint32 portmask); -+extern ret_t rtl8367c_getAsicTrunkingGroup(rtk_uint32 group, rtk_uint32* pPortmask); -+extern ret_t rtl8367c_setAsicTrunkingFlood(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicTrunkingFlood(rtk_uint32* pEnabled); -+extern ret_t rtl8367c_setAsicTrunkingHashSelect(rtk_uint32 hashsel); -+extern ret_t rtl8367c_getAsicTrunkingHashSelect(rtk_uint32* pHashsel); -+ -+extern ret_t rtl8367c_getAsicQeueuEmptyStatus(rtk_uint32* pPortmask); -+ -+extern ret_t rtl8367c_setAsicTrunkingMode(rtk_uint32 mode); -+extern ret_t rtl8367c_getAsicTrunkingMode(rtk_uint32* pMode); -+extern ret_t rtl8367c_setAsicTrunkingFc(rtk_uint32 group, rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicTrunkingFc(rtk_uint32 group, rtk_uint32* pEnabled); -+extern ret_t rtl8367c_setAsicTrunkingHashTable(rtk_uint32 hashval, rtk_uint32 portId); -+extern ret_t rtl8367c_getAsicTrunkingHashTable(rtk_uint32 hashval, rtk_uint32* pPortId); -+extern ret_t rtl8367c_setAsicTrunkingHashTable1(rtk_uint32 hashval, rtk_uint32 portId); -+extern ret_t rtl8367c_getAsicTrunkingHashTable1(rtk_uint32 hashval, rtk_uint32* pPortId); -+ -+#endif /*_RTL8367C_ASICDRV_TRUNKING_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_unknownMulticast.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_unknownMulticast.h -new file mode 100644 -index 000000000000..e492e715b39b ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_unknownMulticast.h -@@ -0,0 +1,59 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Unknown multicast related functions -+ * -+ */ -+ -+#ifndef _RTL8367C_ASICDRV_UNKNOWNMULTICAST_H_ -+#define _RTL8367C_ASICDRV_UNKNOWNMULTICAST_H_ -+ -+#include -+ -+enum L2_UNKOWN_MULTICAST_BEHAVE -+{ -+ L2_UNKOWN_MULTICAST_FLOODING = 0, -+ L2_UNKOWN_MULTICAST_DROP, -+ L2_UNKOWN_MULTICAST_TRAP, -+ L2_UNKOWN_MULTICAST_DROP_EXCLUDE_RMA, -+ L2_UNKOWN_MULTICAST_END -+}; -+ -+enum L3_UNKOWN_MULTICAST_BEHAVE -+{ -+ L3_UNKOWN_MULTICAST_FLOODING = 0, -+ L3_UNKOWN_MULTICAST_DROP, -+ L3_UNKOWN_MULTICAST_TRAP, -+ L3_UNKOWN_MULTICAST_ROUTER, -+ L3_UNKOWN_MULTICAST_END -+}; -+ -+enum MULTICASTTYPE{ -+ MULTICAST_TYPE_IPV4 = 0, -+ MULTICAST_TYPE_IPV6, -+ MULTICAST_TYPE_L2, -+ MULTICAST_TYPE_END -+}; -+ -+extern ret_t rtl8367c_setAsicUnknownL2MulticastBehavior(rtk_uint32 port, rtk_uint32 behave); -+extern ret_t rtl8367c_getAsicUnknownL2MulticastBehavior(rtk_uint32 port, rtk_uint32 *pBehave); -+extern ret_t rtl8367c_setAsicUnknownIPv4MulticastBehavior(rtk_uint32 port, rtk_uint32 behave); -+extern ret_t rtl8367c_getAsicUnknownIPv4MulticastBehavior(rtk_uint32 port, rtk_uint32 *pBehave); -+extern ret_t rtl8367c_setAsicUnknownIPv6MulticastBehavior(rtk_uint32 port, rtk_uint32 behave); -+extern ret_t rtl8367c_getAsicUnknownIPv6MulticastBehavior(rtk_uint32 port, rtk_uint32 *pBehave); -+extern ret_t rtl8367c_setAsicUnknownMulticastTrapPriority(rtk_uint32 priority); -+extern ret_t rtl8367c_getAsicUnknownMulticastTrapPriority(rtk_uint32 *pPriority); -+ -+#endif /*_RTL8367C_ASICDRV_UNKNOWNMULTICAST_H_*/ -+ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_vlan.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_vlan.h -new file mode 100644 -index 000000000000..61848650b579 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_vlan.h -@@ -0,0 +1,157 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : VLAN related functions -+ * -+ */ -+ -+ -+#ifndef _RTL8367C_ASICDRV_VLAN_H_ -+#define _RTL8367C_ASICDRV_VLAN_H_ -+ -+/****************************************************************/ -+/* Header File inclusion */ -+/****************************************************************/ -+#include -+ -+/****************************************************************/ -+/* Constant Definition */ -+/****************************************************************/ -+#define RTL8367C_PROTOVLAN_GIDX_MAX 3 -+#define RTL8367C_PROTOVLAN_GROUPNO 4 -+ -+#define RTL8367C_VLAN_BUSY_CHECK_NO (10) -+ -+#define RTL8367C_VLAN_MBRCFG_LEN (4) -+#define RTL8367C_VLAN_4KTABLE_LEN (3) -+ -+/****************************************************************/ -+/* Type Definition */ -+/****************************************************************/ -+typedef struct VLANCONFIGUSER -+{ -+ rtk_uint16 evid; -+ rtk_uint16 mbr; -+ rtk_uint16 fid_msti; -+ rtk_uint16 envlanpol; -+ rtk_uint16 meteridx; -+ rtk_uint16 vbpen; -+ rtk_uint16 vbpri; -+}rtl8367c_vlanconfiguser; -+ -+typedef struct USER_VLANTABLE{ -+ -+ rtk_uint16 vid; -+ rtk_uint16 mbr; -+ rtk_uint16 untag; -+ rtk_uint16 fid_msti; -+ rtk_uint16 envlanpol; -+ rtk_uint16 meteridx; -+ rtk_uint16 vbpen; -+ rtk_uint16 vbpri; -+ rtk_uint16 ivl_svl; -+ -+}rtl8367c_user_vlan4kentry; -+ -+typedef enum -+{ -+ FRAME_TYPE_BOTH = 0, -+ FRAME_TYPE_TAGGED_ONLY, -+ FRAME_TYPE_UNTAGGED_ONLY, -+ FRAME_TYPE_MAX_BOUND -+} rtl8367c_accframetype; -+ -+typedef enum -+{ -+ EG_TAG_MODE_ORI = 0, -+ EG_TAG_MODE_KEEP, -+ EG_TAG_MODE_PRI_TAG, -+ EG_TAG_MODE_REAL_KEEP, -+ EG_TAG_MODE_END -+} rtl8367c_egtagmode; -+ -+typedef enum -+{ -+ PPVLAN_FRAME_TYPE_ETHERNET = 0, -+ PPVLAN_FRAME_TYPE_LLC, -+ PPVLAN_FRAME_TYPE_RFC1042, -+ PPVLAN_FRAME_TYPE_END -+} rtl8367c_provlan_frametype; -+ -+enum RTL8367C_STPST -+{ -+ STPST_DISABLED = 0, -+ STPST_BLOCKING, -+ STPST_LEARNING, -+ STPST_FORWARDING -+}; -+ -+enum RTL8367C_RESVIDACT -+{ -+ RES_VID_ACT_UNTAG = 0, -+ RES_VID_ACT_TAG, -+ RES_VID_ACT_END -+}; -+ -+typedef struct -+{ -+ rtl8367c_provlan_frametype frameType; -+ rtk_uint32 etherType; -+} rtl8367c_protocolgdatacfg; -+ -+typedef struct -+{ -+ rtk_uint32 valid; -+ rtk_uint32 vlan_idx; -+ rtk_uint32 priority; -+} rtl8367c_protocolvlancfg; -+ -+extern ret_t rtl8367c_setAsicVlanMemberConfig(rtk_uint32 index, rtl8367c_vlanconfiguser *pVlanCg); -+extern ret_t rtl8367c_getAsicVlanMemberConfig(rtk_uint32 index, rtl8367c_vlanconfiguser *pVlanCg); -+extern ret_t rtl8367c_setAsicVlan4kEntry(rtl8367c_user_vlan4kentry *pVlan4kEntry ); -+extern ret_t rtl8367c_getAsicVlan4kEntry(rtl8367c_user_vlan4kentry *pVlan4kEntry ); -+extern ret_t rtl8367c_setAsicVlanAccpetFrameType(rtk_uint32 port, rtl8367c_accframetype frameType); -+extern ret_t rtl8367c_getAsicVlanAccpetFrameType(rtk_uint32 port, rtl8367c_accframetype *pFrameType); -+extern ret_t rtl8367c_setAsicVlanIngressFilter(rtk_uint32 port, rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicVlanIngressFilter(rtk_uint32 port, rtk_uint32 *pEnable); -+extern ret_t rtl8367c_setAsicVlanEgressTagMode(rtk_uint32 port, rtl8367c_egtagmode tagMode); -+extern ret_t rtl8367c_getAsicVlanEgressTagMode(rtk_uint32 port, rtl8367c_egtagmode *pTagMode); -+extern ret_t rtl8367c_setAsicVlanPortBasedVID(rtk_uint32 port, rtk_uint32 index, rtk_uint32 pri); -+extern ret_t rtl8367c_getAsicVlanPortBasedVID(rtk_uint32 port, rtk_uint32 *pIndex, rtk_uint32 *pPri); -+extern ret_t rtl8367c_setAsicVlanProtocolBasedGroupData(rtk_uint32 index, rtl8367c_protocolgdatacfg *pPbCfg); -+extern ret_t rtl8367c_getAsicVlanProtocolBasedGroupData(rtk_uint32 index, rtl8367c_protocolgdatacfg *pPbCfg); -+extern ret_t rtl8367c_setAsicVlanPortAndProtocolBased(rtk_uint32 port, rtk_uint32 index, rtl8367c_protocolvlancfg *pPpbCfg); -+extern ret_t rtl8367c_getAsicVlanPortAndProtocolBased(rtk_uint32 port, rtk_uint32 index, rtl8367c_protocolvlancfg *pPpbCfg); -+extern ret_t rtl8367c_setAsicVlanFilter(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicVlanFilter(rtk_uint32* pEnabled); -+ -+extern ret_t rtl8367c_setAsicPortBasedFid(rtk_uint32 port, rtk_uint32 fid); -+extern ret_t rtl8367c_getAsicPortBasedFid(rtk_uint32 port, rtk_uint32* pFid); -+extern ret_t rtl8367c_setAsicPortBasedFidEn(rtk_uint32 port, rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicPortBasedFidEn(rtk_uint32 port, rtk_uint32* pEnabled); -+extern ret_t rtl8367c_setAsicSpanningTreeStatus(rtk_uint32 port, rtk_uint32 msti, rtk_uint32 state); -+extern ret_t rtl8367c_getAsicSpanningTreeStatus(rtk_uint32 port, rtk_uint32 msti, rtk_uint32* pState); -+extern ret_t rtl8367c_setAsicVlanUntagDscpPriorityEn(rtk_uint32 enabled); -+extern ret_t rtl8367c_getAsicVlanUntagDscpPriorityEn(rtk_uint32* enabled); -+extern ret_t rtl8367c_setAsicVlanTransparent(rtk_uint32 port, rtk_uint32 portmask); -+extern ret_t rtl8367c_getAsicVlanTransparent(rtk_uint32 port, rtk_uint32 *pPortmask); -+extern ret_t rtl8367c_setAsicVlanEgressKeep(rtk_uint32 port, rtk_uint32 portmask); -+extern ret_t rtl8367c_getAsicVlanEgressKeep(rtk_uint32 port, rtk_uint32* pPortmask); -+extern ret_t rtl8367c_setReservedVidAction(rtk_uint32 vid0Action, rtk_uint32 vid4095Action); -+extern ret_t rtl8367c_getReservedVidAction(rtk_uint32 *pVid0Action, rtk_uint32 *pVid4095Action); -+extern ret_t rtl8367c_setRealKeepRemarkEn(rtk_uint32 enabled); -+extern ret_t rtl8367c_getRealKeepRemarkEn(rtk_uint32 *pEnabled); -+extern ret_t rtl8367c_resetVlan(void); -+ -+#endif /*#ifndef _RTL8367C_ASICDRV_VLAN_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_base.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_base.h -new file mode 100644 -index 000000000000..7a70e158fa6f ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_base.h -@@ -0,0 +1,596 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (¶g¤T, 08 ¤T¤ë 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Register MACRO related definition -+ * -+ */ -+ -+#ifndef _RTL8367C_BASE_H_ -+#define _RTL8367C_BASE_H_ -+ -+#include -+ -+/* (16'h0000) port_reg */ -+ -+#define RTL8367C_PORT_SPECIAL_CONGEST_MODE_TIMER_BASE RTL8367C_REG_PKTGEN_PORT0_TIMER -+#define RTL8367C_PORT_SPECIAL_CONGEST_MODE_TIMER_REG(port) (RTL8367C_PORT_SPECIAL_CONGEST_MODE_TIMER_BASE + (port << 5)) -+ -+#define RTL8367C_PORT_MISC_CFG_BASE RTL8367C_REG_PORT0_MISC_CFG -+#define RTL8367C_PORT_MISC_CFG_REG(port) (RTL8367C_PORT_MISC_CFG_BASE + (port << 5)) -+#define RTL8367C_1QREMARK_ENABLE_OFFSET RTL8367C_PORT0_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET -+#define RTL8367C_1QREMARK_ENABLE_MASK RTL8367C_PORT0_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK -+ -+#define RTL8367C_INGRESSBW_PORT_IFG_MASK RTL8367C_PORT0_MISC_CFG_INGRESSBW_IFG_MASK -+#define RTL8367C_VLAN_EGRESS_MDOE_MASK RTL8367C_PORT0_MISC_CFG_VLAN_EGRESS_MODE_MASK -+#define RTL8367C_SPECIALCONGEST_SUSTAIN_TIMER_MASK RTL8367C_PORT0_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK -+ -+#define RTL8367C_INGRESSBW_PORT_RATE_LSB_BASE RTL8367C_REG_INGRESSBW_PORT0_RATE_CTRL0 -+#define RTL8367C_INGRESSBW_PORT_RATE_LSB_REG(port) (RTL8367C_INGRESSBW_PORT_RATE_LSB_BASE + (port << 5)) -+ -+#define RTL8367C_PORT_SMALL_IPG_REG(port) (RTL8367C_REG_PORT0_MISC_CFG + (port*0x20)) -+ -+#define RTL8367C_PORT_EEE_CFG_BASE RTL8367C_REG_PORT0_EEECFG -+#define RTL8367C_PORT_EEE_CFG_REG(port) (RTL8367C_REG_PORT0_EEECFG + (port << 5)) -+#define RTL8367C_PORT_EEE_100M_OFFSET RTL8367C_PORT0_EEECFG_EEE_100M_OFFSET -+#define RTL8367C_PORT_EEE_100M_MASK RTL8367C_PORT0_EEECFG_EEE_100M_MASK -+#define RTL8367C_PORT_EEE_GIGA_OFFSET RTL8367C_PORT0_EEECFG_EEE_GIGA_500M_OFFSET -+#define RTL8367C_PORT_EEE_GIGA_MASK RTL8367C_PORT0_EEECFG_EEE_GIGA_500M_MASK -+ -+ -+/* (16'h0200) outq_reg */ -+ -+#define RTL8367C_FLOWCTRL_QUEUE_DROP_ON_BASE RTL8367C_REG_FLOWCTRL_QUEUE0_DROP_ON -+#define RTL8367C_FLOWCTRL_QUEUE_DROP_ON_REG(queue) (RTL8367C_FLOWCTRL_QUEUE_DROP_ON_BASE + queue) -+#define RTL8367C_FLOWCTRL_QUEUE_DROP_ON_MASK RTL8367C_FLOWCTRL_QUEUE0_DROP_ON_MASK -+ -+#define RTL8367C_FLOWCTRL_PORT_DROP_ON_BASE RTL8367C_REG_FLOWCTRL_PORT0_DROP_ON -+#define RTL8367C_FLOWCTRL_PORT_DROP_ON_REG(PORT) (RTL8367C_FLOWCTRL_PORT_DROP_ON_BASE + PORT) -+#define RTL8367C_FLOWCTRL_PORT_DROP_ON_MASK RTL8367C_FLOWCTRL_PORT0_DROP_ON_MASK -+ -+#define RTL8367C_FLOWCTRL_PORT_GAP_REG RTL8367C_REG_FLOWCTRL_PORT_GAP -+#define RTL8367C_FLOWCTRL_QUEUE_GAP_REG RTL8367C_REG_FLOWCTRL_QUEUE_GAP -+#define RTL8367C_FLOWCTRL_PORT_QEMPTY_REG RTL8367C_REG_PORT_QEMPTY -+ -+/* (16'h0300) sch_reg */ -+ -+#define RTL8367C_SCHEDULE_WFQ_BURST_SIZE_REG RTL8367C_REG_SCHEDULE_WFQ_BURST_SIZE -+ -+#define RTL8367C_SCHEDULE_QUEUE_TYPE_BASE RTL8367C_REG_SCHEDULE_QUEUE_TYPE_CTRL0 -+#define RTL8367C_SCHEDULE_QUEUE_TYPE_REG(port) (RTL8367C_SCHEDULE_QUEUE_TYPE_BASE + (port >> 1)) -+#define RTL8367C_SCHEDULE_QUEUE_TYPE_OFFSET(port, queue) (((port & 0x1) << 3) + queue) -+#define RTL8367C_SCHEDULE_QUEUE_TYPE_MASK(port, queue) RTL8367C_SCHEDULE_QUEUE_TYPE_OFFSET(port, queue) -+ -+#define RTL8367C_SCHEDULE_PORT_QUEUE_WFQ_WEIGHT_BASE RTL8367C_REG_SCHEDULE_PORT0_QUEUE0_WFQ_WEIGHT -+#define RTL8367C_SCHEDULE_PORT_QUEUE_WFQ_WEIGHT_REG(port, queue) (RTL8367C_SCHEDULE_PORT_QUEUE_WFQ_WEIGHT_BASE + (port << 3) + queue) -+ -+#define RTL8367C_SCHEDULE_APR_CTRL_REG RTL8367C_REG_SCHEDULE_APR_CTRL0 -+#define RTL8367C_SCHEDULE_APR_CTRL_OFFSET(port) (port) -+#define RTL8367C_SCHEDULE_APR_CTRL_MASK(port) (1 << RTL8367C_SCHEDULE_APR_CTRL_OFFSET(port)) -+ -+#define RTL8367C_SCHEDULE_PORT_APR_METER_BASE RTL8367C_REG_SCHEDULE_PORT0_APR_METER_CTRL0 -+#define RTL8367C_SCHEDULE_PORT_APR_METER_REG(port, queue) (RTL8367C_SCHEDULE_PORT_APR_METER_BASE + (port << 2) + (queue / 5)) -+#define RTL8367C_SCHEDULE_PORT_APR_METER_OFFSET(queue) (3 * (queue % 5)) -+#define RTL8367C_SCHEDULE_PORT_APR_METER_MASK(queue) (RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE0_APR_METER_MASK << RTL8367C_SCHEDULE_PORT_APR_METER_OFFSET(queue)) -+ -+#define RTL8367C_PORT_EGRESSBW_LSB_BASE RTL8367C_REG_PORT0_EGRESSBW_CTRL0 -+#define RTL8367C_PORT_EGRESSBW_LSB_REG(port) (RTL8367C_PORT_EGRESSBW_LSB_BASE + (port << 1)) -+ -+#define RTL8367C_PORT_EGRESSBW_MSB_BASE RTL8367C_REG_PORT0_EGRESSBW_CTRL1 -+#define RTL8367C_PORT_EGRESSBW_MSB_REG(port) (RTL8367C_PORT_EGRESSBW_MSB_BASE + (port << 1)) -+ -+/* (16'h0500) table_reg */ -+ -+#define RTL8367C_TABLE_ACCESS_CTRL_REG RTL8367C_REG_TABLE_ACCESS_CTRL -+ -+#define RTL8367C_TABLE_ACCESS_ADDR_REG RTL8367C_REG_TABLE_ACCESS_ADDR -+ -+#define RTL8367C_TABLE_ACCESS_STATUS_REG RTL8367C_REG_TABLE_LUT_ADDR -+ -+#define RTL8367C_TABLE_ACCESS_WRDATA_BASE RTL8367C_REG_TABLE_WRITE_DATA0 -+#define RTL8367C_TABLE_ACCESS_WRDATA_REG(index) (RTL8367C_TABLE_ACCESS_WRDATA_BASE + index) -+ -+#define RTL8367C_TABLE_ACCESS_RDDATA_BASE RTL8367C_REG_TABLE_READ_DATA0 -+#define RTL8367C_TABLE_ACCESS_RDDATA_REG(index) (RTL8367C_TABLE_ACCESS_RDDATA_BASE + index) -+ -+ -+ -+/* (16'h0600) acl_reg */ -+ -+#define RTL8367C_ACL_RULE_TEMPLATE_CTRL_BASE RTL8367C_REG_ACL_RULE_TEMPLATE0_CTRL0 -+#define RTL8367C_ACL_RULE_TEMPLATE_CTRL_REG(template) (RTL8367C_ACL_RULE_TEMPLATE_CTRL_BASE + template * 0x4) -+#define RTL8367C_ACL_TEMPLATE_FIELD_OFFSET(field) ((field & 0x01) <<3) -+#define RTL8367C_ACL_TEMPLATE_FIELD_MASK(field) (0x3F << RTL8367C_ACL_TEMPLATE_FIELD_OFFSET(field)) -+ -+#define RTL8367C_ACL_ACTION_CTRL_BASE RTL8367C_REG_ACL_ACTION_CTRL0 -+#define RTL8367C_ACL_ACTION_CTRL_REG(rule) (RTL8367C_ACL_ACTION_CTRL_BASE + (rule >> 1)) -+#define RTL8367C_ACL_ACTION_CTRL2_BASE RTL8367C_REG_ACL_ACTION_CTRL32 -+#define RTL8367C_ACL_ACTION_CTRL2_REG(rule) (RTL8367C_ACL_ACTION_CTRL2_BASE + ((rule-64) >> 1)) -+ -+#define RTL8367C_ACL_OP_NOT_OFFSET(rule) (6 + ((rule & 0x1) << 3)) -+#define RTL8367C_ACL_OP_NOT_MASK(rule) (1 << RTL8367C_ACL_OP_NOT_OFFSET(rule)) -+#define RTL8367C_ACL_OP_ACTION_OFFSET(rule) ((rule & 0x1) << 3) -+#define RTL8367C_ACL_OP_ACTION_MASK(rule) (0x3F << RTL8367C_ACL_OP_ACTION_OFFSET(rule)) -+ -+#define RTL8367C_ACL_ENABLE_REG RTL8367C_REG_ACL_ENABLE -+#define RTL8367C_ACL_UNMATCH_PERMIT_REG RTL8367C_REG_ACL_UNMATCH_PERMIT -+ -+/* (16'h0700) cvlan_reg */ -+ -+#define RTL8367C_VLAN_PVID_CTRL_BASE RTL8367C_REG_VLAN_PVID_CTRL0 -+#define RTL8367C_VLAN_PVID_CTRL_REG(port) (RTL8367C_VLAN_PVID_CTRL_BASE + (port >> 1)) -+#define RTL8367C_PORT_VIDX_OFFSET(port) ((port &1)<<3) -+#define RTL8367C_PORT_VIDX_MASK(port) (RTL8367C_PORT0_VIDX_MASK << RTL8367C_PORT_VIDX_OFFSET(port)) -+ -+#define RTL8367C_VLAN_PPB_VALID_BASE RTL8367C_REG_VLAN_PPB0_VALID -+#define RTL8367C_VLAN_PPB_VALID_REG(item) (RTL8367C_VLAN_PPB_VALID_BASE + (item << 3)) -+ -+#define RTL8367C_VLAN_PPB_CTRL_BASE RTL8367C_REG_VLAN_PPB0_CTRL0 -+#define RTL8367C_VLAN_PPB_CTRL_REG(item, port) (RTL8367C_VLAN_PPB_CTRL_BASE + (item << 3) + (port / 3) ) -+#define RTL8367C_VLAN_PPB_CTRL_OFFSET(port) ((port % 3) * 5) -+#define RTL8367C_VLAN_PPB_CTRL_MASK(port) (RTL8367C_VLAN_PPB0_CTRL0_PORT0_INDEX_MASK << RTL8367C_VLAN_PPB_CTRL_OFFSET(port)) -+ -+#define RTL8367C_VLAN_PPB_FRAMETYPE_BASE RTL8367C_REG_VLAN_PPB0_CTRL2 -+#define RTL8367C_VLAN_PPB_FRAMETYPE_REG(item) (RTL8367C_VLAN_PPB_FRAMETYPE_BASE + (item << 3)) -+#define RTL8367C_VLAN_PPB_FRAMETYPE_MASK RTL8367C_VLAN_PPB0_CTRL2_FRAME_TYPE_MASK -+ -+#define RTL8367C_VLAN_PPB_ETHERTYPR_BASE RTL8367C_REG_VLAN_PPB0_CTRL3 -+#define RTL8367C_VLAN_PPB_ETHERTYPR_REG(item) (RTL8367C_VLAN_PPB_ETHERTYPR_BASE + (item << 3)) -+ -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION_BASE RTL8367C_REG_VLAN_MEMBER_CONFIGURATION0_CTRL0 -+ -+ -+#define RTL8367C_VLAN_CTRL_REG RTL8367C_REG_VLAN_CTRL -+ -+#define RTL8367C_VLAN_INGRESS_REG RTL8367C_REG_VLAN_INGRESS -+ -+#define RTL8367C_VLAN_ACCEPT_FRAME_TYPE_BASE RTL8367C_REG_VLAN_ACCEPT_FRAME_TYPE_CTRL0 -+#define RTL8367C_VLAN_ACCEPT_FRAME_TYPE_REG(port) (RTL8367C_VLAN_ACCEPT_FRAME_TYPE_BASE + (port >> 3)) -+#define RTL8367C_VLAN_ACCEPT_FRAME_TYPE_MASK(port) (RTL8367C_PORT0_FRAME_TYPE_MASK << ((port & 0x7) << 1)) -+ -+#define RTL8367C_PORT_EFID_BASE RTL8367C_REG_PORT_EFID_CTRL0 -+#define RTL8367C_PORT_EFID_REG(port) (RTL8367C_PORT_EFID_BASE + (port >> 2)) -+#define RTL8367C_PORT_EFID_OFFSET(port) ((port & 0x3) << 2) -+#define RTL8367C_PORT_EFID_MASK(port) (RTL8367C_PORT0_EFID_MASK << RTL8367C_PORT_EFID_OFFSET(port)) -+ -+#define RTL8367C_PORT_PBFIDEN_REG RTL8367C_REG_PORT_PBFIDEN -+ -+#define RTL8367C_PORT_PBFID_BASE RTL8367C_REG_PORT0_PBFID -+#define RTL8367C_PORT_PBFID_REG(port) (RTL8367C_PORT_PBFID_BASE + port) -+ -+/* (16'h0800) dpm_reg */ -+ -+#define RTL8367C_RMA_CTRL_BASE RTL8367C_REG_RMA_CTRL00 -+ -+ -+#define RTL8367C_VLAN_PORTBASED_PRIORITY_BASE RTL8367C_REG_VLAN_PORTBASED_PRIORITY_CTRL0 -+#define RTL8367C_VLAN_PORTBASED_PRIORITY_REG(port) (RTL8367C_VLAN_PORTBASED_PRIORITY_BASE + (port >> 2)) -+#define RTL8367C_VLAN_PORTBASED_PRIORITY_OFFSET(port) ((port & 0x3) << 2) -+#define RTL8367C_VLAN_PORTBASED_PRIORITY_MASK(port) (0x7 << RTL8367C_VLAN_PORTBASED_PRIORITY_OFFSET(port)) -+ -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM_BASE RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM0_CTRL0 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM_REG(port, item) (RTL8367C_VLAN_PPB_PRIORITY_ITEM_BASE + (item << 2)+ (port>>2)) -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM_OFFSET(port) ((port & 0x3) <<2) -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM_MASK(port) (RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT0_PRIORITY_MASK << RTL8367C_VLAN_PPB_PRIORITY_ITEM_OFFSET(port)) -+ -+#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_BASE RTL8367C_REG_QOS_1Q_PRIORITY_REMAPPING_CTRL0 -+#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_REG(pri) (RTL8367C_QOS_1Q_PRIORITY_REMAPPING_BASE + (pri >> 2)) -+#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_OFFSET(pri) ((pri & 0x3) << 2) -+#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_MASK(pri) (0x7 << RTL8367C_QOS_1Q_PRIORITY_REMAPPING_OFFSET(pri)) -+ -+#define RTL8367C_QOS_DSCP_TO_PRIORITY_BASE RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL0 -+#define RTL8367C_QOS_DSCP_TO_PRIORITY_REG(dscp) (RTL8367C_QOS_DSCP_TO_PRIORITY_BASE + (dscp >> 2)) -+#define RTL8367C_QOS_DSCP_TO_PRIORITY_OFFSET(dscp) ((dscp & 0x3) << 2) -+#define RTL8367C_QOS_DSCP_TO_PRIORITY_MASK(dscp) (0x7 << RTL8367C_QOS_DSCP_TO_PRIORITY_OFFSET(dscp)) -+ -+#define RTL8367C_QOS_PORTBASED_PRIORITY_BASE RTL8367C_REG_QOS_PORTBASED_PRIORITY_CTRL0 -+#define RTL8367C_QOS_PORTBASED_PRIORITY_REG(port) (RTL8367C_QOS_PORTBASED_PRIORITY_BASE + (port >> 2)) -+#define RTL8367C_QOS_PORTBASED_PRIORITY_OFFSET(port) ((port & 0x3) << 2) -+#define RTL8367C_QOS_PORTBASED_PRIORITY_MASK(port) (0x7 << RTL8367C_QOS_PORTBASED_PRIORITY_OFFSET(port)) -+ -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_BASE RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION_CTRL0 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_REG(src) (RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_BASE + (src >> 1)) -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_OFFSET(src) ((src & 1) << 3) -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_MASK(src) (RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL0_QOS_PORT_WEIGHT_MASK << RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_OFFSET(src)) -+ -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_BASE RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION2_CTRL0 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_REG(src) (RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_BASE + (src >> 1)) -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_OFFSET(src) ((src & 1) << 3) -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_MASK(src) (RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL0_QOS_PORT_WEIGHT_MASK << RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_OFFSET(src)) -+ -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_IDX_CTRL RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION_IDX -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_IDX(port) (1 << port) -+ -+#define RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_BASE RTL8367C_REG_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0 -+#define RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_REG(pri) (RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_BASE + (pri >> 2)) -+#define RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_OFFSET(pri) ((pri & 0x3) << 2) -+#define RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_MASK(pri) (RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY0_MASK << RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_OFFSET(pri)) -+ -+#define RTL8367C_QOS_TRAP_PRIORITY_CTRL0_REG RTL8367C_REG_QOS_TRAP_PRIORITY0 -+ -+#define RTL8367C_QOS_TRAP_PRIORITY_CTRL1_REG RTL8367C_REG_QOS_TRAP_PRIORITY1 -+ -+#define RTL8367C_QOS_DSCP_TO_DSCP_BASE RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL0 -+#define RTL8367C_QOS_DSCP_TO_DSCP_REG(dscp) (RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL0 + (dscp >> 1)) -+#define RTL8367C_QOS_DSCP_TO_DSCP_OFFSET(dscp) ((dscp & 0x1) << 8) -+#define RTL8367C_QOS_DSCP_TO_DSCP_MASK(dscp) (0x3F << RTL8367C_QOS_DSCP_TO_DSCP_OFFSET(dscp)) -+ -+#define RTL8367C_UNUCAST_FLOADING_PMSK_REG RTL8367C_REG_UNDA_FLOODING_PMSK -+ -+#define RTL8367C_UNMCAST_FLOADING_PMSK_REG RTL8367C_REG_UNMCAST_FLOADING_PMSK -+ -+#define RTL8367C_BCAST_FLOADING_PMSK_REG RTL8367C_REG_BCAST_FLOADING_PMSK -+ -+#define RTL8367C_PORT_ISOLATION_PORT_MASK_BASE RTL8367C_REG_PORT_ISOLATION_PORT0_MASK -+#define RTL8367C_PORT_ISOLATION_PORT_MASK_REG(port) (RTL8367C_PORT_ISOLATION_PORT_MASK_BASE + port) -+ -+#define RTL8367C_FORCE_CTRL_REG RTL8367C_REG_FORCE_CTRL -+ -+#define RTL8367C_SOURCE_PORT_BLOCK_REG RTL8367C_REG_SOURCE_PORT_PERMIT -+ -+#define RTL8367C_IPMCAST_VLAN_LEAKY_REG RTL8367C_REG_IPMCAST_VLAN_LEAKY -+ -+#define RTL8367C_IPMCAST_PORTISO_LEAKY_REG RTL8367C_REG_IPMCAST_PORTISO_LEAKY -+ -+#define RTL8367C_PORT_SECURIT_CTRL_REG RTL8367C_REG_PORT_SECURITY_CTRL -+ -+#define RTL8367C_UNKNOWN_IPV4_MULTICAST_BASE RTL8367C_REG_UNKNOWN_IPV4_MULTICAST_CTRL0 -+#define RTL8367C_UNKNOWN_IPV4_MULTICAST_REG(port) (RTL8367C_UNKNOWN_IPV4_MULTICAST_BASE + (port >> 3)) -+#define RTL8367C_UNKNOWN_IPV4_MULTICAST_OFFSET(port) ((port & 0x7) << 1) -+#define RTL8367C_UNKNOWN_IPV4_MULTICAST_MASK(port) (RTL8367C_PORT0_UNKNOWN_IP4_MCAST_MASK << RTL8367C_UNKNOWN_IPV4_MULTICAST_OFFSET(port)) -+ -+#define RTL8367C_UNKNOWN_IPV6_MULTICAST_BASE RTL8367C_REG_UNKNOWN_IPV6_MULTICAST_CTRL0 -+#define RTL8367C_UNKNOWN_IPV6_MULTICAST_REG(port) (RTL8367C_UNKNOWN_IPV6_MULTICAST_BASE + (port >> 3)) -+#define RTL8367C_UNKNOWN_IPV6_MULTICAST_OFFSET(port) ((port & 0x7) << 1) -+#define RTL8367C_UNKNOWN_IPV6_MULTICAST_MASK(port) (RTL8367C_PORT0_UNKNOWN_IP4_MCAST_MASK << RTL8367C_UNKNOWN_IPV6_MULTICAST_OFFSET(port)) -+ -+#define RTL8367C_UNKNOWN_L2_MULTICAST_BASE RTL8367C_REG_UNKNOWN_L2_MULTICAST_CTRL0 -+#define RTL8367C_UNKNOWN_L2_MULTICAST_REG(port) (RTL8367C_UNKNOWN_L2_MULTICAST_BASE + (port >> 3)) -+#define RTL8367C_UNKNOWN_L2_MULTICAST_OFFSET(port) ((port & 0x7) << 1) -+#define RTL8367C_UNKNOWN_L2_MULTICAST_MASK(port) (RTL8367C_PORT0_UNKNOWN_L2_MCAST_MASK << RTL8367C_UNKNOWN_L2_MULTICAST_OFFSET(port)) -+ -+#define RTL8367C_PORT_TRUNK_CTRL_REG RTL8367C_REG_PORT_TRUNK_CTRL -+#define RTL8367C_PORT_TRUNK_HASH_MASK 0x007F -+ -+#define RTL8367C_PORT_TRUNK_GROUP_MASK_REG RTL8367C_REG_PORT_TRUNK_GROUP_MASK -+#define RTL8367C_PORT_TRUNK_GROUP_MASK_OFFSET(group) (group << 2) -+#define RTL8367C_PORT_TRUNK_GROUP_MASK_MASK(group) (RTL8367C_PORT_TRUNK_GROUP0_MASK_MASK << RTL8367C_PORT_TRUNK_GROUP_MASK_OFFSET(group)) -+ -+#define RTL8367C_PORT_TRUNK_FLOWCTRL_REG RTL8367C_REG_PORT_TRUNK_FLOWCTRL -+ -+#define RTL8367C_QOS_PORT_QUEUE_NUMBER_BASE RTL8367C_REG_QOS_PORT_QUEUE_NUMBER_CTRL0 -+#define RTL8367C_QOS_PORT_QUEUE_NUMBER_REG(port) (RTL8367C_QOS_PORT_QUEUE_NUMBER_BASE + (port >> 2)) -+#define RTL8367C_QOS_PORT_QUEUE_NUMBER_OFFSET(port) ((port & 0x3) << 2) -+#define RTL8367C_QOS_PORT_QUEUE_NUMBER_MASK(port) (0x7 << RTL8367C_QOS_PORT_QUEUE_NUMBER_OFFSET(port)) -+ -+#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_BASE RTL8367C_REG_QOS_1Q_PRIORITY_TO_QID_CTRL0 -+#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_REG(index, pri) (RTL8367C_QOS_1Q_PRIORITY_TO_QID_BASE + (index << 1) + (pri >> 2)) -+#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_OFFSET(pri) ((pri & 0x3) << 2) -+#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_MASK(pri) (RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK << RTL8367C_QOS_1Q_PRIORITY_TO_QID_OFFSET(pri)) -+ -+#define RTL8367C_DEBUG_INFO_BASE RTL8367C_REG_PORT_DEBUG_INFO_CTRL0 -+#define RTL8367C_DEBUG_INFO_REG(port) (RTL8367C_DEBUG_INFO_BASE + (port >>1)) -+#define RTL8367C_DEBUG_INFO_OFFSET(port) ((port&1)<<3) -+#define RTL8367C_DEBUG_INFO_MASK(port) (RTL8367C_PORT0_DEBUG_INFO_MASK << RTL8367C_DEBUG_INFO_OFFSET(port)) -+ -+/* (16'h0a00) l2_reg */ -+ -+#define RTL8367C_VLAN_MSTI_BASE RTL8367C_REG_VLAN_MSTI0_CTRL0 -+#define RTL8367C_VLAN_MSTI_REG(tree, port) (RTL8367C_VLAN_MSTI_BASE + (tree << 1) + (port >> 3)) -+#define RTL8367C_VLAN_MSTI_OFFSET(port) ((port & 0x7) << 1) -+#define RTL8367C_VLAN_MSTI_MASK(port) (RTL8367C_VLAN_MSTI0_CTRL0_PORT0_STATE_MASK << RTL8367C_VLAN_MSTI_OFFSET(port)) -+ -+#define RTL8367C_LUT_PORT_LEARN_LIMITNO_BASE RTL8367C_REG_LUT_PORT0_LEARN_LIMITNO -+#define RTL8367C_LUT_PORT_LEARN_LIMITNO_REG(port) (RTL8367C_LUT_PORT_LEARN_LIMITNO_BASE + port) -+ -+#define RTL8367C_LUT_CFG_REG RTL8367C_REG_LUT_CFG -+ -+#define RTL8367C_LUT_AGEOUT_CTRL_REG RTL8367C_REG_LUT_AGEOUT_CTRL -+ -+#define RTL8367C_FORCE_FLUSH_REG RTL8367C_REG_FORCE_FLUSH -+ -+#define RTL8367C_STORM_BCAST_REG RTL8367C_REG_STORM_BCAST -+ -+#define RTL8367C_STORM_MCAST_REG RTL8367C_REG_STORM_MCAST -+ -+#define RTL8367C_STORM_UNKNOWN_UCAST_REG RTL8367C_REG_STORM_UNKOWN_UCAST -+ -+#define RTL8367C_STORM_UNKNOWN_MCAST_REG RTL8367C_REG_STORM_UNKOWN_MCAST -+ -+#define RTL8367C_STORM_BCAST_METER_CTRL_BASE RTL8367C_REG_STORM_BCAST_METER_CTRL0 -+#define RTL8367C_STORM_BCAST_METER_CTRL_REG(port) (RTL8367C_STORM_BCAST_METER_CTRL_BASE + (port >> 1)) -+#define RTL8367C_STORM_BCAST_METER_CTRL_OFFSET(port) ((port & 0x1) << 3) -+#define RTL8367C_STORM_BCAST_METER_CTRL_MASK(port) (0xFF << RTL8367C_STORM_BCAST_METER_CTRL_OFFSET(port)) -+ -+#define RTL8367C_STORM_MCAST_METER_CTRL_BASE RTL8367C_REG_STORM_MCAST_METER_CTRL0 -+#define RTL8367C_STORM_MCAST_METER_CTRL_REG(port) (RTL8367C_STORM_MCAST_METER_CTRL_BASE + (port >> 1)) -+#define RTL8367C_STORM_MCAST_METER_CTRL_OFFSET(port) ((port & 0x1) << 3) -+#define RTL8367C_STORM_MCAST_METER_CTRL_MASK(port) (0xFF << RTL8367C_STORM_MCAST_METER_CTRL_OFFSET(port)) -+ -+#define RTL8367C_STORM_UNDA_METER_CTRL_BASE RTL8367C_REG_STORM_UNDA_METER_CTRL0 -+#define RTL8367C_STORM_UNDA_METER_CTRL_REG(port) (RTL8367C_STORM_UNDA_METER_CTRL_BASE + (port >> 1)) -+#define RTL8367C_STORM_UNDA_METER_CTRL_OFFSET(port) ((port & 0x1) << 3) -+#define RTL8367C_STORM_UNDA_METER_CTRL_MASK(port) (0xFF << RTL8367C_STORM_UNDA_METER_CTRL_OFFSET(port)) -+ -+#define RTL8367C_STORM_UNMC_METER_CTRL_BASE RTL8367C_REG_STORM_UNMC_METER_CTRL0 -+#define RTL8367C_STORM_UNMC_METER_CTRL_REG(port) (RTL8367C_STORM_UNMC_METER_CTRL_BASE + (port >> 1)) -+#define RTL8367C_STORM_UNMC_METER_CTRL_OFFSET(port) ((port & 0x1) << 3) -+#define RTL8367C_STORM_UNMC_METER_CTRL_MASK(port) (0xFF << RTL8367C_STORM_UNMC_METER_CTRL_OFFSET(port)) -+ -+#define RTL8367C_OAM_PARSER_OFFSET(port) (port*2) -+#define RTL8367C_OAM_PARSER_MASK(port) (RTL8367C_PORT0_PARACT_MASK << RTL8367C_OAM_PARSER_OFFSET(port)) -+ -+#define RTL8367C_OAM_MULTIPLEXER_OFFSET(port) (port*2) -+#define RTL8367C_OAM_MULTIPLEXER_MASK(port) (RTL8367C_PORT0_PARACT_MASK << RTL8367C_OAM_MULTIPLEXER_OFFSET(port)) -+ -+#define RTL8367C_OAM_CTRL_REG RTL8367C_REG_OAM_CTRL -+ -+#define RTL8367C_DOT1X_PORT_ENABLE_REG RTL8367C_REG_DOT1X_PORT_ENABLE -+ -+#define RTL8367C_DOT1X_MAC_ENABLE_REG RTL8367C_REG_DOT1X_MAC_ENABLE -+ -+#define RTL8367C_DOT1X_PORT_AUTH_REG RTL8367C_REG_DOT1X_PORT_AUTH -+ -+#define RTL8367C_DOT1X_PORT_OPDIR_REG RTL8367C_REG_DOT1X_PORT_OPDIR -+ -+#define RTL8367C_DOT1X_UNAUTH_ACT_BASE RTL8367C_REG_DOT1X_UNAUTH_ACT_W0 -+#define RTL8367C_DOT1X_UNAUTH_ACT_OFFSET(port) ((port & 0x7) << 1) -+#define RTL8367C_DOT1X_UNAUTH_ACT_MASK(port) (RTL8367C_DOT1X_PORT0_UNAUTHBH_MASK << RTL8367C_DOT1X_UNAUTH_ACT_OFFSET(port)) -+ -+#define RTL8367C_DOT1X_CFG_REG RTL8367C_REG_DOT1X_CFG -+ -+#define RTL8367C_REG_L2_LRN_CNT_BASE RTL8367C_REG_L2_LRN_CNT_CTRL0 -+#define RTL8367C_REG_L2_LRN_CNT_REG(port) (RTL8367C_REG_L2_LRN_CNT_BASE + port) -+ -+/* (16'h0b00) mltvlan_reg */ -+ -+#define RTL8367C_SVLAN_MCAST2S_ENTRY_BASE_REG(index) (RTL8367C_REG_SVLAN_MCAST2S_ENTRY0_CTRL0 + index*5) -+ -+/* (16'h0c00) svlan_reg */ -+ -+#define RTL8367C_SVLAN_MEMBERCFG_BASE_REG(index) (RTL8367C_REG_SVLAN_MEMBERCFG0_CTRL1 + index*3) -+#define RTL8367C_SVLAN_C2SCFG_BASE_REG(index) (RTL8367C_REG_SVLAN_C2SCFG0_CTRL0+ index*3) -+#define RTL8367C_SVLAN_CFG_REG RTL8367C_REG_SVLAN_CFG -+ -+/* (16'h0f00) hsactrl_reg */ -+ -+#define RTL8367C_SVLAN_S2C_ENTRY_BASE_REG(index) (RTL8367C_REG_SVLAN_SP2C_ENTRY0_CTRL0 + index*2) -+ -+/* (16'h1000) mib_reg */ -+ -+#define RTL8367C_MIB_COUNTER_BASE_REG RTL8367C_REG_MIB_COUNTER0 -+ -+#define RTL8367C_MIB_ADDRESS_REG RTL8367C_REG_MIB_ADDRESS -+ -+#define RTL8367C_MIB_CTRL_REG RTL8367C_REG_MIB_CTRL0 -+#define RTL8367C_MIB_PORT07_MASK (0xFF<> 4)) -+#define RTL8367C_REG_METER_EXCEED_INDICATOR_OFFSET(meter) (meter & 0xF) -+ -+/* (16'h1200) swcore_reg */ -+ -+#define RTL8367C_VS_TPID_REG RTL8367C_REG_VS_TPID -+ -+#define RTL8367C_SWITCH_MAC_BASE RTL8367C_REG_SWITCH_MAC0 -+ -+#define RTL8367C_REMARKING_CTRL_REG RTL8367C_REG_SWITCH_CTRL0 -+ -+#define RTL8367C_QOS_DSCP_REMARK_BASE RTL8367C_REG_QOS_DSCP_REMARK_CTRL0 -+#define RTL8367C_QOS_DSCP_REMARK_REG(pri) (RTL8367C_QOS_DSCP_REMARK_BASE + (pri >> 1)) -+#define RTL8367C_QOS_DSCP_REMARK_OFFSET(pri) (((pri) & 0x1) << 3) -+#define RTL8367C_QOS_DSCP_REMARK_MASK(pri) (0x3F << RTL8367C_QOS_DSCP_REMARK_OFFSET(pri)) -+ -+#define RTL8367C_QOS_1Q_REMARK_BASE RTL8367C_REG_QOS_1Q_REMARK_CTRL0 -+#define RTL8367C_QOS_1Q_REMARK_REG(pri) (RTL8367C_QOS_1Q_REMARK_BASE + (pri >> 2)) -+#define RTL8367C_QOS_1Q_REMARK_OFFSET(pri) ((pri & 0x3) << 2) -+#define RTL8367C_QOS_1Q_REMARK_MASK(pri) (0x7 << RTL8367C_QOS_1Q_REMARK_OFFSET(pri)) -+ -+#define RTL8367C_PTKGEN_PAYLOAD_CTRL0_REG RTL8367C_REG_PTKGEN_PAYLOAD_CTRL0 -+ -+#define RTL8367C_PTKGEN_PAYLOAD_CTRL1_REG RTL8367C_REG_PTKGEN_PAYLOAD_CTRL1 -+ -+#define RTL8367C_SVLAN_UPLINK_PORTMASK_REG RTL8367C_REG_SVLAN_UPLINK_PORTMASK -+ -+#define RTL8367C_CPU_PORT_MASK_REG RTL8367C_REG_CPU_PORT_MASK -+ -+#define RTL8367C_CPU_CTRL_REG RTL8367C_REG_CPU_CTRL -+ -+#define RTL8367C_MIRROR_CTRL_REG RTL8367C_REG_MIRROR_CTRL -+ -+ -+#define RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_BASE RTL8367C_REG_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL0 -+#define RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG(port) (RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_BASE + (port >> 1)) -+#define RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG_OFFSET(port) ((port & 0x1) << 3) -+#define RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG_MASK(port) (RTL8367C_PORT0_QUEUE_MASK_MASK << RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG_OFFSET(port)) -+ -+ -+#define RTL8367C_FLOWCTRL_PORT_PAGE_COUNTER_BASE RTL8367C_REG_FLOWCTRL_PORT0_PAGE_COUNTER -+#define RTL8367C_FLOWCTRL_PORT_PAGE_COUNTER_REG(port) (RTL8367C_FLOWCTRL_PORT_PAGE_COUNTER_BASE + port) -+#define RTL8367C_FLOWCTRL_PORT_PAGE_COUNTER_MASK RTL8367C_FLOWCTRL_PORT0_PAGE_COUNTER_MASK -+ -+#define RTL8367C_FLOWCTRL_PORT_PAGE_MAX_BASE RTL8367C_REG_FLOWCTRL_PORT0_PAGE_MAX -+#define RTL8367C_FLOWCTRL_PORT_PAGE_MAX_REG(port) (RTL8367C_FLOWCTRL_PORT_PAGE_MAX_BASE + port) -+#define RTL8367C_FLOWCTRL_PORT_PAGE_MAX_MASK RTL8367C_FLOWCTRL_PORT0_PAGE_MAX_MASK -+ -+#define RTL8367C_FIELD_SELECTOR_REG(index) (RTL8367C_REG_FIELD_SELECTOR0 + index) -+#define RTL8367C_FIELD_SELECTOR_ENABLE_OFFSET RTL8367C_FIELD_SELECTOR0_ENABLE_OFFSET -+#define RTL8367C_FIELD_SELECTOR_ENABLE_MASK RTL8367C_FIELD_SELECTOR0_ENABLE_MASK -+#define RTL8367C_FIELD_SELECTOR_FORMAT_OFFSET RTL8367C_FIELD_SELECTOR0_FORMAT_OFFSET -+#define RTL8367C_FIELD_SELECTOR_FORMAT_MASK RTL8367C_FIELD_SELECTOR0_FORMAT_MASK -+#define RTL8367C_FIELD_SELECTOR_OFFSET_OFFSET RTL8367C_FIELD_SELECTOR0_OFFSET_OFFSET -+#define RTL8367C_FIELD_SELECTOR_OFFSET_MASK RTL8367C_FIELD_SELECTOR0_OFFSET_MASK -+ -+/* (16'h1300) chip_reg*/ -+ -+/* (16'h1400) mtrpool_reg */ -+#define RTL8367C_METER_RATE_BASE RTL8367C_REG_METER0_RATE_CTRL0 -+#define RTL8367C_METER_RATE_REG(meter) ((meter << 1) + RTL8367C_METER_RATE_BASE) -+ -+#define RTL8367C_METER_BUCKET_SIZE_BASE RTL8367C_REG_METER0_BUCKET_SIZE -+#define RTL8367C_METER_BUCKET_SIZE_REG(meter) (RTL8367C_METER_BUCKET_SIZE_BASE + meter) -+ -+#define RTL8367C_LEAKY_BUCKET_TICK_REG RTL8367C_REG_METER_CTRL0 -+#define RTL8367C_LEAKY_BUCKET_TICK_OFFSET RTL8367C_METER_TICK_OFFSET -+#define RTL8367C_LEAKY_BUCKET_TICK_MASK RTL8367C_METER_TICK_MASK -+ -+#define RTL8367C_LEAKY_BUCKET_TOKEN_REG RTL8367C_REG_METER_CTRL1 -+#define RTL8367C_LEAKY_BUCKET_TOKEN_OFFSET RTL8367C_METER_CTRL1_OFFSET -+#define RTL8367C_LEAKY_BUCKET_TOKEN_MASK RTL8367C_METER_CTRL1_MASK -+ -+#define RTL8367C_METER_OVERRATE_INDICATOR_BASE RTL8367C_REG_METER_OVERRATE_INDICATOR0 -+#define RTL8367C_METER_OVERRATE_INDICATOR_REG(meter) (RTL8367C_METER_OVERRATE_INDICATOR_BASE + (meter >> 4)) -+#define RTL8367C_METER_EXCEED_OFFSET(meter) (meter & 0xF) -+#define RTL8367C_METER_EXCEED_MASK(meter) (1 << RTL8367C_METER_EXCEED_OFFSET(meter)) -+ -+#define RTL8367C_METER_IFG_CTRL_BASE RTL8367C_REG_METER_IFG_CTRL0 -+#define RTL8367C_METER_IFG_CTRL_REG(meter) (RTL8367C_METER_IFG_CTRL_BASE + (meter >> 4)) -+#define RTL8367C_METER_IFG_OFFSET(meter) (meter & 0xF) -+#define RTL8367C_METER_IFG_MASK(meter) (1 << RTL8367C_METER_IFG_OFFSET(meter)) -+ -+#define RTL8367C_FLOWCTRL_CTRL_REG RTL8367C_REG_FLOWCTRL_CTRL0 -+ -+/* (16'h1800)8051_RLDP_EEE_reg */ -+#define RTL8367C_EEELLDP_CTRL0_REG RTL8367C_REG_EEELLDP_CTRL0 -+ -+#define RTL8367C_EEELLDP_CTRL1_REG RTL8367C_REG_EEELLDP_CTRL1 -+ -+#define RTL8367C_EEELLDP_PMSK_REG RTL8367C_REG_EEELLDP_PMSK -+ -+#define RTL8367C_EEELLDP_TX_FRAMEU_REG_BASE RTL8367C_REG_EEELLDP_FRAMEU00 -+ -+#define RTL8367C_EEELLDP_TX_CAP_FRAMEL_REG_BASE RTL8367C_REG_EEELLDP_CAP_FRAMEL00 -+ -+#define RTL8367C_EEELLDP_RX_VALUE_PORT_BASE RTL8367C_REG_EEELLDP_RX_VALUE_P00_00 -+#define RTL8367C_EEELLDP_RX_VALUE_PORT_REG(port) (RTL8367C_EEELLDP_RX_VALUE_PORT_BASE + (port * 9)) -+ -+#define RTL8367C_RLDP_CTRL0_REG RTL8367C_REG_RLDP_CTRL0 -+#define RTL8367C_RLDP_MODE_OFFSET 14 -+ -+#define RTL8367C_RLDP_RETRY_COUNT_REG RTL8367C_REG_RLDP_CTRL1 -+ -+#define RTL8367C_RLDP_RETRY_PERIOD_LOOPSTATE_REG RTL8367C_REG_RLDP_CTRL2 -+ -+#define RTL8367C_RLDP_RETRY_PERIOD_CHKSTATE_REG RTL8367C_REG_RLDP_CTRL3 -+ -+#define RTL8367C_RLDP_TX_PMSK_REG RTL8367C_REG_RLDP_CTRL4 -+ -+#define RTL8367C_RLDP_RAND_NUM_REG_BASE RTL8367C_REG_RLDP_RAND_NUM0 -+ -+#define RTL8367C_RLDP_MAGIC_NUM_REG_BASE RTL8367C_REG_RLDP_MAGIC_NUM0 -+ -+#define RTL8367C_RLDP_LOOP_PMSK_REG RTL8367C_REG_RLDP_LOOPSTATUS_INDICATOR -+ -+#define RTL8367C_RLDP_LOOP_PORT_BASE RTL8367C_REG_RLDP_LOOP_PORT_REG0 -+#define RTL8367C_RLDP_LOOP_PORT_REG(port) (RTL8367C_RLDP_LOOP_PORT_BASE + (port >> 1)) -+#define RTL8367C_RLDP_LOOP_PORT_OFFSET(port) ((port & 0x1) << 3) -+#define RTL8367C_RLDP_LOOP_PORT_MASK(port) (RTL8367C_RLDP_LOOP_PORT_00_MASK << RTL8367C_RLDP_LOOP_PORT_OFFSET(port)) -+ -+#define RTL8367C_PAGEMETER_PORT_BASE RTL8367C_REG_PAGEMETER_PORT0_CTRL0 -+#define RTL8367C_PAGEMETER_PORT_REG(port) (RTL8367C_PAGEMETER_PORT_BASE + 0x20*port) -+ -+#define RTL8367C_HIGHPRI_INDICATOR_REG RTL8367C_REG_HIGHPRI_INDICATOR -+#define RTL8367C_PORT_INDICATOR_OFFSET(port) (port) -+#define RTL8367C_PORT_INDICATOR_MASK(port) (RTL8367C_PORT0_INDICATOR_MASK << RTL8367C_PORT_INDICATOR_OFFSET(port)) -+ -+#define RTL8367C_HIGHPRI_CFG_REG RTL8367C_REG_HIGHPRI_CFG -+ -+#define RTL8367C_EAV_PRIORITY_REMAPPING_BASE RTL8367C_REG_EAV_CTRL1 -+#define RTL8367C_EAV_PRIORITY_REMAPPING_REG(pri) (RTL8367C_EAV_PRIORITY_REMAPPING_BASE + (pri >> 2)) -+#define RTL8367C_EAV_PRIORITY_REMAPPING_OFFSET(pri) ((pri & 0x3) * RTL8367C_REMAP_EAV_PRI1_REGEN_OFFSET) -+#define RTL8367C_EAV_PRIORITY_REMAPPING_MASK(pri) (RTL8367C_REMAP_EAV_PRI0_REGEN_MASK << RTL8367C_EAV_PRIORITY_REMAPPING_OFFSET(pri)) -+ -+#define RTL8367C_EEEP_CFG_BASE RTL8367C_REG_PORT0_EEECFG -+#define RTL8367C_EEEP_CFG_REG(port) (RTL8367C_EEEP_CFG_BASE + (port*0x20)) -+ -+#define RTL8367C_PKG_CFG_BASE RTL8367C_REG_PKTGEN_PORT0_CTRL -+#define RTL8367C_PKG_CFG_REG(port) (RTL8367C_PKG_CFG_BASE + (port*0x20)) -+ -+#define RTL8367C_PKG_DA_BASE RTL8367C_REG_PKTGEN_PORT0_DA0 -+#define RTL8367C_PKG_DA_REG(port) (RTL8367C_PKG_DA_BASE + (port*0x20)) -+ -+#define RTL8367C_PKG_SA_BASE RTL8367C_REG_PKTGEN_PORT0_SA0 -+#define RTL8367C_PKG_SA_REG(port) (RTL8367C_PKG_SA_BASE + (port*0x20)) -+ -+#define RTL8367C_PKG_NUM_BASE RTL8367C_REG_PKTGEN_PORT0_COUNTER0 -+#define RTL8367C_PKG_NUM_REG(port) (RTL8367C_PKG_NUM_BASE + (port*0x20)) -+ -+#define RTL8367C_PKG_LENGTH_BASE RTL8367C_REG_PKTGEN_PORT0_TX_LENGTH -+#define RTL8367C_PKG_LENGTH_REG(port) (RTL8367C_PKG_LENGTH_BASE + (port*0x20)) -+ -+/* (16'h1c00)IGMP_MLD_reg */ -+#define RTL8367C_IGMP_GROUP_USAGE_BASE RTL8367C_REG_IGMP_GROUP_USAGE_LIST0 -+#define RTL8367C_IGMP_GROUP_USAGE_REG(idx) (RTL8367C_IGMP_GROUP_USAGE_BASE + (idx / 16)) -+ -+#define RTL8367C_FALLBACK_BASE RTL8367C_REG_FALLBACK_PORT0_CFG0 -+#define RTL8367C_FALLBACK_PORT_CFG_REG(port) (RTL8367C_FALLBACK_BASE + (port * 4)) -+#define RTL8367C_FALLBACK_PORT_MON_CNT_REG(port) (RTL8367C_FALLBACK_BASE + 1 + (port * 4)) -+#define RTL8367C_FALLBACK_PORT_ERR_CNT_REG(port) (RTL8367C_FALLBACK_BASE + 3 + (port * 4)) -+ -+ -+/* (16'h6400)timer_1588 */ -+#define RTL8367C_EAV_CFG_BASE RTL8367C_REG_P0_EAV_CFG -+#define RTL8367C_EAV_PORT_CFG_REG(port) (RTL8367C_EAV_CFG_BASE + (port *0x10)) -+#define RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET RTL8367C_P0_EAV_CFG_PTP_PHY_EN_EN_OFFSET -+#define RTL8367C_EAV_CFG_RX_PDELAY_RESP_OFFSET RTL8367C_P0_EAV_CFG_RX_PDELAY_RESP_OFFSET -+#define RTL8367C_EAV_CFG_RX_PDELAY_REQ_OFFSET RTL8367C_P0_EAV_CFG_RX_PDELAY_REQ_OFFSET -+#define RTL8367C_EAV_CFG_RX_DELAY_REQ_OFFSET RTL8367C_P0_EAV_CFG_RX_DELAY_REQ_OFFSET -+#define RTL8367C_EAV_CFG_RX_SYNC_OFFSET RTL8367C_P0_EAV_CFG_RX_SYNC_OFFSET -+#define RTL8367C_EAV_CFG_TX_PDELAY_RESP_OFFSET RTL8367C_P0_EAV_CFG_TX_PDELAY_RESP_OFFSET -+#define RTL8367C_EAV_CFG_TX_PDELAY_REQ_OFFSET RTL8367C_P0_EAV_CFG_TX_PDELAY_REQ_OFFSET -+#define RTL8367C_EAV_CFG_TX_DELAY_REQ_OFFSET RTL8367C_P0_EAV_CFG_TX_DELAY_REQ_OFFSET -+#define RTL8367C_EAV_CFG_TX_SYNC_OFFSET RTL8367C_P0_EAV_CFG_TX_SYNC_OFFSET -+ -+#define RTL8367C_REG_TX_SYNC_SEQ_ID_BASE RTL8367C_REG_P0_TX_SYNC_SEQ_ID -+#define RTL8367C_REG_TX_SYNC_SEQ_ID(port) (RTL8367C_REG_TX_SYNC_SEQ_ID_BASE + (port *0x10)) -+#define RTL8367C_REG_SEQ_ID(port, type) (RTL8367C_REG_TX_SYNC_SEQ_ID_BASE + type + (port *0x10)) -+ -+#define RTL8367C_REG_TX_DELAY_REQ_SEQ_ID_BASE RTL8367C_REG_P0_TX_DELAY_REQ_SEQ_ID -+#define RTL8367C_REG_TX_PDELAY_REQ_SEQ_ID_BASE RTL8367C_REG_P0_TX_PDELAY_REQ_SEQ_ID -+#define RTL8367C_REG_TX_PDELAY_RESP_SEQ_ID_BASE RTL8367C_REG_P0_TX_PDELAY_RESP_SEQ_ID -+#define RTL8367C_REG_RX_SYNC_SEQ_ID_BASE RTL8367C_REG_P0_RX_SYNC_SEQ_ID -+#define RTL8367C_REG_RX_DELAY_REQ_SEQ_ID_BASE RTL8367C_REG_P0_RX_DELAY_REQ_SEQ_ID -+#define RTL8367C_REG_RX_PDELAY_REQ_SEQ_ID_BASE RTL8367C_REG_P0_RX_PDELAY_REQ_SEQ_ID -+#define RTL8367C_REG_RX_PDELAY_RESP_SEQ_ID_BASE RTL8367C_REG_P0_RX_PDELAY_RESP_SEQ_ID -+ -+#define RTL8367C_REG_PORT_NSEC_L_BASE RTL8367C_REG_P0_PORT_NSEC_15_0 -+#define RTL8367C_REG_PORT_NSEC_L(port) (RTL8367C_REG_PORT_NSEC_L_BASE + (port *0x10)) -+#define RTL8367C_REG_PORT_NSEC_H_BASE RTL8367C_REG_P0_PORT_NSEC_26_16 -+#define RTL8367C_REG_PORT_NSEC_H(port) (RTL8367C_REG_PORT_NSEC_H_BASE + (port *0x10)) -+#define RTL8367C_PORT_NSEC_H_OFFSET RTL8367C_P0_PORT_NSEC_26_16_OFFSET -+#define RTL8367C_PORT_NSEC_H_MASK RTL8367C_P0_PORT_NSEC_26_16_MASK -+ -+#define RTL8367C_REG_PORT_SEC_L_BASE RTL8367C_REG_P0_PORT_SEC_15_0 -+#define RTL8367C_REG_PORT_SEC_L(port) (RTL8367C_REG_PORT_SEC_L_BASE + (port *0x10)) -+#define RTL8367C_REG_PORT_SEC_H_BASE RTL8367C_REG_P0_PORT_SEC_31_16 -+#define RTL8367C_REG_PORT_SEC_H(port) (RTL8367C_REG_PORT_SEC_H_BASE + (port *0x10)) -+ -+#endif /*#ifndef _RTL8367C_BASE_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_reg.h b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_reg.h -new file mode 100644 -index 000000000000..f973c7bcb62d ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_reg.h -@@ -0,0 +1,22819 @@ -+#ifndef _RTL8367C_REG_H_ -+#define _RTL8367C_REG_H_ -+ -+/************************************************************ -+auto-generated register address and field data -+*************************************************************/ -+ -+/* (16'h0000)port_reg */ -+ -+#define RTL8367C_REG_PORT0_CGST_HALF_CFG 0x0000 -+#define RTL8367C_PORT0_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 -+#define RTL8367C_PORT0_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 -+#define RTL8367C_PORT0_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 -+#define RTL8367C_PORT0_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF -+ -+#define RTL8367C_REG_PKTGEN_PORT0_CTRL 0x0001 -+#define RTL8367C_PKTGEN_PORT0_CTRL_STATUS_OFFSET 15 -+#define RTL8367C_PKTGEN_PORT0_CTRL_STATUS_MASK 0x8000 -+#define RTL8367C_PKTGEN_PORT0_CTRL_PKTGEN_STS_OFFSET 13 -+#define RTL8367C_PKTGEN_PORT0_CTRL_PKTGEN_STS_MASK 0x2000 -+#define RTL8367C_PKTGEN_PORT0_CTRL_CRC_NO_ERROR_OFFSET 4 -+#define RTL8367C_PKTGEN_PORT0_CTRL_CRC_NO_ERROR_MASK 0x10 -+#define RTL8367C_PKTGEN_PORT0_CTRL_CMD_START_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT0_CTRL_CMD_START_MASK 0x1 -+ -+#define RTL8367C_REG_TX_ERR_CNT_PORT0 0x0002 -+#define RTL8367C_TX_ERR_CNT_PORT0_OFFSET 0 -+#define RTL8367C_TX_ERR_CNT_PORT0_MASK 0x7 -+ -+#define RTL8367C_REG_PKTGEN_PORT0_DA0 0x0003 -+ -+#define RTL8367C_REG_PKTGEN_PORT0_DA1 0x0004 -+ -+#define RTL8367C_REG_PKTGEN_PORT0_DA2 0x0005 -+ -+#define RTL8367C_REG_PKTGEN_PORT0_SA0 0x0006 -+ -+#define RTL8367C_REG_PKTGEN_PORT0_SA1 0x0007 -+ -+#define RTL8367C_REG_PKTGEN_PORT0_SA2 0x0008 -+ -+#define RTL8367C_REG_PKTGEN_PORT0_COUNTER0 0x0009 -+ -+#define RTL8367C_REG_PKTGEN_PORT0_COUNTER1 0x000a -+#define RTL8367C_PKTGEN_PORT0_COUNTER1_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT0_COUNTER1_MASK 0xFF -+ -+#define RTL8367C_REG_PKTGEN_PORT0_TX_LENGTH 0x000b -+#define RTL8367C_PKTGEN_PORT0_TX_LENGTH_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT0_TX_LENGTH_MASK 0x3FFF -+ -+#define RTL8367C_REG_PKTGEN_PORT0_TIMER 0x000d -+#define RTL8367C_PKTGEN_PORT0_TIMER_TIMER_OFFSET 4 -+#define RTL8367C_PKTGEN_PORT0_TIMER_TIMER_MASK 0xF0 -+#define RTL8367C_PKTGEN_PORT0_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 -+#define RTL8367C_PKTGEN_PORT0_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 -+ -+#define RTL8367C_REG_PORT0_MISC_CFG 0x000e -+#define RTL8367C_PORT0_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 -+#define RTL8367C_PORT0_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 -+#define RTL8367C_PORT0_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 -+#define RTL8367C_PORT0_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 -+#define RTL8367C_PORT0_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 -+#define RTL8367C_PORT0_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 -+#define RTL8367C_PORT0_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 -+#define RTL8367C_PORT0_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 -+#define RTL8367C_PORT0_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 -+#define RTL8367C_PORT0_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 -+#define RTL8367C_PORT0_MISC_CFG_INGRESSBW_IFG_OFFSET 10 -+#define RTL8367C_PORT0_MISC_CFG_INGRESSBW_IFG_MASK 0x400 -+#define RTL8367C_PORT0_MISC_CFG_RX_SPC_OFFSET 9 -+#define RTL8367C_PORT0_MISC_CFG_RX_SPC_MASK 0x200 -+#define RTL8367C_PORT0_MISC_CFG_CRC_SKIP_OFFSET 8 -+#define RTL8367C_PORT0_MISC_CFG_CRC_SKIP_MASK 0x100 -+#define RTL8367C_PORT0_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 -+#define RTL8367C_PORT0_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 -+#define RTL8367C_PORT0_MISC_CFG_MAC_LOOPBACK_OFFSET 6 -+#define RTL8367C_PORT0_MISC_CFG_MAC_LOOPBACK_MASK 0x40 -+#define RTL8367C_PORT0_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 -+#define RTL8367C_PORT0_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 -+#define RTL8367C_PORT0_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 -+#define RTL8367C_PORT0_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF -+ -+#define RTL8367C_REG_INGRESSBW_PORT0_RATE_CTRL0 0x000f -+ -+#define RTL8367C_REG_INGRESSBW_PORT0_RATE_CTRL1 0x0010 -+#define RTL8367C_INGRESSBW_PORT0_RATE_CTRL1_DUMMY_OFFSET 3 -+#define RTL8367C_INGRESSBW_PORT0_RATE_CTRL1_DUMMY_MASK 0xFFF8 -+#define RTL8367C_INGRESSBW_PORT0_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 -+#define RTL8367C_INGRESSBW_PORT0_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 -+ -+#define RTL8367C_REG_PORT0_FORCE_RATE0 0x0011 -+ -+#define RTL8367C_REG_PORT0_FORCE_RATE1 0x0012 -+ -+#define RTL8367C_REG_PORT0_CURENT_RATE0 0x0013 -+ -+#define RTL8367C_REG_PORT0_CURENT_RATE1 0x0014 -+ -+#define RTL8367C_REG_PORT0_PAGE_COUNTER 0x0015 -+#define RTL8367C_PORT0_PAGE_COUNTER_OFFSET 0 -+#define RTL8367C_PORT0_PAGE_COUNTER_MASK 0x7F -+ -+#define RTL8367C_REG_PAGEMETER_PORT0_CTRL0 0x0016 -+ -+#define RTL8367C_REG_PAGEMETER_PORT0_CTRL1 0x0017 -+ -+#define RTL8367C_REG_PORT0_EEECFG 0x0018 -+#define RTL8367C_PORT0_EEECFG_EEEP_ENABLE_TX_OFFSET 14 -+#define RTL8367C_PORT0_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 -+#define RTL8367C_PORT0_EEECFG_EEEP_ENABLE_RX_OFFSET 13 -+#define RTL8367C_PORT0_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 -+#define RTL8367C_PORT0_EEECFG_EEE_FORCE_OFFSET 12 -+#define RTL8367C_PORT0_EEECFG_EEE_FORCE_MASK 0x1000 -+#define RTL8367C_PORT0_EEECFG_EEE_100M_OFFSET 11 -+#define RTL8367C_PORT0_EEECFG_EEE_100M_MASK 0x800 -+#define RTL8367C_PORT0_EEECFG_EEE_GIGA_500M_OFFSET 10 -+#define RTL8367C_PORT0_EEECFG_EEE_GIGA_500M_MASK 0x400 -+#define RTL8367C_PORT0_EEECFG_EEE_TX_OFFSET 9 -+#define RTL8367C_PORT0_EEECFG_EEE_TX_MASK 0x200 -+#define RTL8367C_PORT0_EEECFG_EEE_RX_OFFSET 8 -+#define RTL8367C_PORT0_EEECFG_EEE_RX_MASK 0x100 -+#define RTL8367C_PORT0_EEECFG_EEE_DSP_RX_OFFSET 6 -+#define RTL8367C_PORT0_EEECFG_EEE_DSP_RX_MASK 0x40 -+#define RTL8367C_PORT0_EEECFG_EEE_LPI_OFFSET 5 -+#define RTL8367C_PORT0_EEECFG_EEE_LPI_MASK 0x20 -+#define RTL8367C_PORT0_EEECFG_EEE_TX_LPI_OFFSET 4 -+#define RTL8367C_PORT0_EEECFG_EEE_TX_LPI_MASK 0x10 -+#define RTL8367C_PORT0_EEECFG_EEE_RX_LPI_OFFSET 3 -+#define RTL8367C_PORT0_EEECFG_EEE_RX_LPI_MASK 0x8 -+#define RTL8367C_PORT0_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 -+#define RTL8367C_PORT0_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 -+#define RTL8367C_PORT0_EEECFG_EEE_WAKE_REQ_OFFSET 1 -+#define RTL8367C_PORT0_EEECFG_EEE_WAKE_REQ_MASK 0x2 -+#define RTL8367C_PORT0_EEECFG_EEE_SLEEP_REQ_OFFSET 0 -+#define RTL8367C_PORT0_EEECFG_EEE_SLEEP_REQ_MASK 0x1 -+ -+#define RTL8367C_REG_PORT0_EEETXMTR 0x0019 -+ -+#define RTL8367C_REG_PORT0_EEERXMTR 0x001a -+ -+#define RTL8367C_REG_PORT0_EEEPTXMTR 0x001b -+ -+#define RTL8367C_REG_PORT0_EEEPRXMTR 0x001c -+ -+#define RTL8367C_REG_PTP_PORT0_CFG1 0x001e -+#define RTL8367C_PTP_PORT0_CFG1_OFFSET 7 -+#define RTL8367C_PTP_PORT0_CFG1_MASK 0xFF -+ -+#define RTL8367C_REG_P0_MSIC1 0x001f -+#define RTL8367C_P0_MSIC1_OFFSET 0 -+#define RTL8367C_P0_MSIC1_MASK 0x1 -+ -+#define RTL8367C_REG_PORT1_CGST_HALF_CFG 0x0020 -+#define RTL8367C_PORT1_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 -+#define RTL8367C_PORT1_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 -+#define RTL8367C_PORT1_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 -+#define RTL8367C_PORT1_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF -+ -+#define RTL8367C_REG_PKTGEN_PORT1_CTRL 0x0021 -+#define RTL8367C_PKTGEN_PORT1_CTRL_STATUS_OFFSET 15 -+#define RTL8367C_PKTGEN_PORT1_CTRL_STATUS_MASK 0x8000 -+#define RTL8367C_PKTGEN_PORT1_CTRL_PKTGEN_STS_OFFSET 13 -+#define RTL8367C_PKTGEN_PORT1_CTRL_PKTGEN_STS_MASK 0x2000 -+#define RTL8367C_PKTGEN_PORT1_CTRL_CRC_NO_ERROR_OFFSET 4 -+#define RTL8367C_PKTGEN_PORT1_CTRL_CRC_NO_ERROR_MASK 0x10 -+#define RTL8367C_PKTGEN_PORT1_CTRL_CMD_START_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT1_CTRL_CMD_START_MASK 0x1 -+ -+#define RTL8367C_REG_TX_ERR_CNT_PORT1 0x0022 -+#define RTL8367C_TX_ERR_CNT_PORT1_OFFSET 0 -+#define RTL8367C_TX_ERR_CNT_PORT1_MASK 0x7 -+ -+#define RTL8367C_REG_PKTGEN_PORT1_DA0 0x0023 -+ -+#define RTL8367C_REG_PKTGEN_PORT1_DA1 0x0024 -+ -+#define RTL8367C_REG_PKTGEN_PORT1_DA2 0x0025 -+ -+#define RTL8367C_REG_PKTGEN_PORT1_SA0 0x0026 -+ -+#define RTL8367C_REG_PKTGEN_PORT1_SA1 0x0027 -+ -+#define RTL8367C_REG_PKTGEN_PORT1_SA2 0x0028 -+ -+#define RTL8367C_REG_PKTGEN_PORT1_COUNTER0 0x0029 -+ -+#define RTL8367C_REG_PKTGEN_PORT1_COUNTER1 0x002a -+#define RTL8367C_PKTGEN_PORT1_COUNTER1_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT1_COUNTER1_MASK 0xFF -+ -+#define RTL8367C_REG_PKTGEN_PORT1_TX_LENGTH 0x002b -+#define RTL8367C_PKTGEN_PORT1_TX_LENGTH_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT1_TX_LENGTH_MASK 0x3FFF -+ -+#define RTL8367C_REG_PKTGEN_PORT1_TIMER 0x002d -+#define RTL8367C_PKTGEN_PORT1_TIMER_TIMER_OFFSET 4 -+#define RTL8367C_PKTGEN_PORT1_TIMER_TIMER_MASK 0xF0 -+#define RTL8367C_PKTGEN_PORT1_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 -+#define RTL8367C_PKTGEN_PORT1_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 -+ -+#define RTL8367C_REG_PORT1_MISC_CFG 0x002e -+#define RTL8367C_PORT1_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 -+#define RTL8367C_PORT1_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 -+#define RTL8367C_PORT1_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 -+#define RTL8367C_PORT1_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 -+#define RTL8367C_PORT1_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 -+#define RTL8367C_PORT1_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 -+#define RTL8367C_PORT1_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 -+#define RTL8367C_PORT1_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 -+#define RTL8367C_PORT1_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 -+#define RTL8367C_PORT1_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 -+#define RTL8367C_PORT1_MISC_CFG_INGRESSBW_IFG_OFFSET 10 -+#define RTL8367C_PORT1_MISC_CFG_INGRESSBW_IFG_MASK 0x400 -+#define RTL8367C_PORT1_MISC_CFG_RX_SPC_OFFSET 9 -+#define RTL8367C_PORT1_MISC_CFG_RX_SPC_MASK 0x200 -+#define RTL8367C_PORT1_MISC_CFG_CRC_SKIP_OFFSET 8 -+#define RTL8367C_PORT1_MISC_CFG_CRC_SKIP_MASK 0x100 -+#define RTL8367C_PORT1_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 -+#define RTL8367C_PORT1_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 -+#define RTL8367C_PORT1_MISC_CFG_MAC_LOOPBACK_OFFSET 6 -+#define RTL8367C_PORT1_MISC_CFG_MAC_LOOPBACK_MASK 0x40 -+#define RTL8367C_PORT1_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 -+#define RTL8367C_PORT1_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 -+#define RTL8367C_PORT1_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 -+#define RTL8367C_PORT1_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF -+ -+#define RTL8367C_REG_INGRESSBW_PORT1_RATE_CTRL0 0x002f -+ -+#define RTL8367C_REG_INGRESSBW_PORT1_RATE_CTRL1 0x0030 -+#define RTL8367C_INGRESSBW_PORT1_RATE_CTRL1_DUMMY_OFFSET 3 -+#define RTL8367C_INGRESSBW_PORT1_RATE_CTRL1_DUMMY_MASK 0xFFF8 -+#define RTL8367C_INGRESSBW_PORT1_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 -+#define RTL8367C_INGRESSBW_PORT1_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 -+ -+#define RTL8367C_REG_PORT1_FORCE_RATE0 0x0031 -+ -+#define RTL8367C_REG_PORT1_FORCE_RATE1 0x0032 -+ -+#define RTL8367C_REG_PORT1_CURENT_RATE0 0x0033 -+ -+#define RTL8367C_REG_PORT1_CURENT_RATE1 0x0034 -+ -+#define RTL8367C_REG_PORT1_PAGE_COUNTER 0x0035 -+#define RTL8367C_PORT1_PAGE_COUNTER_OFFSET 0 -+#define RTL8367C_PORT1_PAGE_COUNTER_MASK 0x7F -+ -+#define RTL8367C_REG_PAGEMETER_PORT1_CTRL0 0x0036 -+ -+#define RTL8367C_REG_PAGEMETER_PORT1_CTRL1 0x0037 -+ -+#define RTL8367C_REG_PORT1_EEECFG 0x0038 -+#define RTL8367C_PORT1_EEECFG_EEEP_ENABLE_TX_OFFSET 14 -+#define RTL8367C_PORT1_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 -+#define RTL8367C_PORT1_EEECFG_EEEP_ENABLE_RX_OFFSET 13 -+#define RTL8367C_PORT1_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 -+#define RTL8367C_PORT1_EEECFG_EEE_FORCE_OFFSET 12 -+#define RTL8367C_PORT1_EEECFG_EEE_FORCE_MASK 0x1000 -+#define RTL8367C_PORT1_EEECFG_EEE_100M_OFFSET 11 -+#define RTL8367C_PORT1_EEECFG_EEE_100M_MASK 0x800 -+#define RTL8367C_PORT1_EEECFG_EEE_GIGA_500M_OFFSET 10 -+#define RTL8367C_PORT1_EEECFG_EEE_GIGA_500M_MASK 0x400 -+#define RTL8367C_PORT1_EEECFG_EEE_TX_OFFSET 9 -+#define RTL8367C_PORT1_EEECFG_EEE_TX_MASK 0x200 -+#define RTL8367C_PORT1_EEECFG_EEE_RX_OFFSET 8 -+#define RTL8367C_PORT1_EEECFG_EEE_RX_MASK 0x100 -+#define RTL8367C_PORT1_EEECFG_EEE_DSP_RX_OFFSET 6 -+#define RTL8367C_PORT1_EEECFG_EEE_DSP_RX_MASK 0x40 -+#define RTL8367C_PORT1_EEECFG_EEE_LPI_OFFSET 5 -+#define RTL8367C_PORT1_EEECFG_EEE_LPI_MASK 0x20 -+#define RTL8367C_PORT1_EEECFG_EEE_TX_LPI_OFFSET 4 -+#define RTL8367C_PORT1_EEECFG_EEE_TX_LPI_MASK 0x10 -+#define RTL8367C_PORT1_EEECFG_EEE_RX_LPI_OFFSET 3 -+#define RTL8367C_PORT1_EEECFG_EEE_RX_LPI_MASK 0x8 -+#define RTL8367C_PORT1_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 -+#define RTL8367C_PORT1_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 -+#define RTL8367C_PORT1_EEECFG_EEE_WAKE_REQ_OFFSET 1 -+#define RTL8367C_PORT1_EEECFG_EEE_WAKE_REQ_MASK 0x2 -+#define RTL8367C_PORT1_EEECFG_EEE_SLEEP_REQ_OFFSET 0 -+#define RTL8367C_PORT1_EEECFG_EEE_SLEEP_REQ_MASK 0x1 -+ -+#define RTL8367C_REG_PORT1_EEETXMTR 0x0039 -+ -+#define RTL8367C_REG_PORT1_EEERXMTR 0x003a -+ -+#define RTL8367C_REG_PORT1_EEEPTXMTR 0x003b -+ -+#define RTL8367C_REG_PORT1_EEEPRXMTR 0x003c -+ -+#define RTL8367C_REG_PTP_PORT1_CFG1 0x003e -+#define RTL8367C_PTP_PORT1_CFG1_OFFSET 7 -+#define RTL8367C_PTP_PORT1_CFG1_MASK 0xFF -+ -+#define RTL8367C_REG_P1_MSIC1 0x003f -+#define RTL8367C_P1_MSIC1_OFFSET 0 -+#define RTL8367C_P1_MSIC1_MASK 0x1 -+ -+#define RTL8367C_REG_PORT2_CGST_HALF_CFG 0x0040 -+#define RTL8367C_PORT2_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 -+#define RTL8367C_PORT2_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 -+#define RTL8367C_PORT2_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 -+#define RTL8367C_PORT2_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF -+ -+#define RTL8367C_REG_PKTGEN_PORT2_CTRL 0x0041 -+#define RTL8367C_PKTGEN_PORT2_CTRL_STATUS_OFFSET 15 -+#define RTL8367C_PKTGEN_PORT2_CTRL_STATUS_MASK 0x8000 -+#define RTL8367C_PKTGEN_PORT2_CTRL_PKTGEN_STS_OFFSET 13 -+#define RTL8367C_PKTGEN_PORT2_CTRL_PKTGEN_STS_MASK 0x2000 -+#define RTL8367C_PKTGEN_PORT2_CTRL_CRC_NO_ERROR_OFFSET 4 -+#define RTL8367C_PKTGEN_PORT2_CTRL_CRC_NO_ERROR_MASK 0x10 -+#define RTL8367C_PKTGEN_PORT2_CTRL_CMD_START_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT2_CTRL_CMD_START_MASK 0x1 -+ -+#define RTL8367C_REG_TX_ERR_CNT_PORT2 0x0042 -+#define RTL8367C_TX_ERR_CNT_PORT2_OFFSET 0 -+#define RTL8367C_TX_ERR_CNT_PORT2_MASK 0x7 -+ -+#define RTL8367C_REG_PKTGEN_PORT2_DA0 0x0043 -+ -+#define RTL8367C_REG_PKTGEN_PORT2_DA1 0x0044 -+ -+#define RTL8367C_REG_PKTGEN_PORT2_DA2 0x0045 -+ -+#define RTL8367C_REG_PKTGEN_PORT2_SA0 0x0046 -+ -+#define RTL8367C_REG_PKTGEN_PORT2_SA1 0x0047 -+ -+#define RTL8367C_REG_PKTGEN_PORT2_SA2 0x0048 -+ -+#define RTL8367C_REG_PKTGEN_PORT2_COUNTER0 0x0049 -+ -+#define RTL8367C_REG_PKTGEN_PORT2_COUNTER1 0x004a -+#define RTL8367C_PKTGEN_PORT2_COUNTER1_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT2_COUNTER1_MASK 0xFF -+ -+#define RTL8367C_REG_PKTGEN_PORT2_TX_LENGTH 0x004b -+#define RTL8367C_PKTGEN_PORT2_TX_LENGTH_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT2_TX_LENGTH_MASK 0x3FFF -+ -+#define RTL8367C_REG_PKTGEN_PORT2_TIMER 0x004d -+#define RTL8367C_PKTGEN_PORT2_TIMER_TIMER_OFFSET 4 -+#define RTL8367C_PKTGEN_PORT2_TIMER_TIMER_MASK 0xF0 -+#define RTL8367C_PKTGEN_PORT2_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 -+#define RTL8367C_PKTGEN_PORT2_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 -+ -+#define RTL8367C_REG_PORT2_MISC_CFG 0x004e -+#define RTL8367C_PORT2_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 -+#define RTL8367C_PORT2_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 -+#define RTL8367C_PORT2_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 -+#define RTL8367C_PORT2_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 -+#define RTL8367C_PORT2_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 -+#define RTL8367C_PORT2_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 -+#define RTL8367C_PORT2_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 -+#define RTL8367C_PORT2_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 -+#define RTL8367C_PORT2_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 -+#define RTL8367C_PORT2_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 -+#define RTL8367C_PORT2_MISC_CFG_INGRESSBW_IFG_OFFSET 10 -+#define RTL8367C_PORT2_MISC_CFG_INGRESSBW_IFG_MASK 0x400 -+#define RTL8367C_PORT2_MISC_CFG_RX_SPC_OFFSET 9 -+#define RTL8367C_PORT2_MISC_CFG_RX_SPC_MASK 0x200 -+#define RTL8367C_PORT2_MISC_CFG_CRC_SKIP_OFFSET 8 -+#define RTL8367C_PORT2_MISC_CFG_CRC_SKIP_MASK 0x100 -+#define RTL8367C_PORT2_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 -+#define RTL8367C_PORT2_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 -+#define RTL8367C_PORT2_MISC_CFG_MAC_LOOPBACK_OFFSET 6 -+#define RTL8367C_PORT2_MISC_CFG_MAC_LOOPBACK_MASK 0x40 -+#define RTL8367C_PORT2_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 -+#define RTL8367C_PORT2_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 -+#define RTL8367C_PORT2_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 -+#define RTL8367C_PORT2_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF -+ -+#define RTL8367C_REG_INGRESSBW_PORT2_RATE_CTRL0 0x004f -+ -+#define RTL8367C_REG_INGRESSBW_PORT2_RATE_CTRL1 0x0050 -+#define RTL8367C_INGRESSBW_PORT2_RATE_CTRL1_DUMMY_OFFSET 3 -+#define RTL8367C_INGRESSBW_PORT2_RATE_CTRL1_DUMMY_MASK 0xFFF8 -+#define RTL8367C_INGRESSBW_PORT2_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 -+#define RTL8367C_INGRESSBW_PORT2_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 -+ -+#define RTL8367C_REG_PORT2_FORCE_RATE0 0x0051 -+ -+#define RTL8367C_REG_PORT2_FORCE_RATE1 0x0052 -+ -+#define RTL8367C_REG_PORT2_CURENT_RATE0 0x0053 -+ -+#define RTL8367C_REG_PORT2_CURENT_RATE1 0x0054 -+ -+#define RTL8367C_REG_PORT2_PAGE_COUNTER 0x0055 -+#define RTL8367C_PORT2_PAGE_COUNTER_OFFSET 0 -+#define RTL8367C_PORT2_PAGE_COUNTER_MASK 0x7F -+ -+#define RTL8367C_REG_PAGEMETER_PORT2_CTRL0 0x0056 -+ -+#define RTL8367C_REG_PAGEMETER_PORT2_CTRL1 0x0057 -+ -+#define RTL8367C_REG_PORT2_EEECFG 0x0058 -+#define RTL8367C_PORT2_EEECFG_EEEP_ENABLE_TX_OFFSET 14 -+#define RTL8367C_PORT2_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 -+#define RTL8367C_PORT2_EEECFG_EEEP_ENABLE_RX_OFFSET 13 -+#define RTL8367C_PORT2_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 -+#define RTL8367C_PORT2_EEECFG_EEE_FORCE_OFFSET 12 -+#define RTL8367C_PORT2_EEECFG_EEE_FORCE_MASK 0x1000 -+#define RTL8367C_PORT2_EEECFG_EEE_100M_OFFSET 11 -+#define RTL8367C_PORT2_EEECFG_EEE_100M_MASK 0x800 -+#define RTL8367C_PORT2_EEECFG_EEE_GIGA_500M_OFFSET 10 -+#define RTL8367C_PORT2_EEECFG_EEE_GIGA_500M_MASK 0x400 -+#define RTL8367C_PORT2_EEECFG_EEE_TX_OFFSET 9 -+#define RTL8367C_PORT2_EEECFG_EEE_TX_MASK 0x200 -+#define RTL8367C_PORT2_EEECFG_EEE_RX_OFFSET 8 -+#define RTL8367C_PORT2_EEECFG_EEE_RX_MASK 0x100 -+#define RTL8367C_PORT2_EEECFG_EEE_DSP_RX_OFFSET 6 -+#define RTL8367C_PORT2_EEECFG_EEE_DSP_RX_MASK 0x40 -+#define RTL8367C_PORT2_EEECFG_EEE_LPI_OFFSET 5 -+#define RTL8367C_PORT2_EEECFG_EEE_LPI_MASK 0x20 -+#define RTL8367C_PORT2_EEECFG_EEE_TX_LPI_OFFSET 4 -+#define RTL8367C_PORT2_EEECFG_EEE_TX_LPI_MASK 0x10 -+#define RTL8367C_PORT2_EEECFG_EEE_RX_LPI_OFFSET 3 -+#define RTL8367C_PORT2_EEECFG_EEE_RX_LPI_MASK 0x8 -+#define RTL8367C_PORT2_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 -+#define RTL8367C_PORT2_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 -+#define RTL8367C_PORT2_EEECFG_EEE_WAKE_REQ_OFFSET 1 -+#define RTL8367C_PORT2_EEECFG_EEE_WAKE_REQ_MASK 0x2 -+#define RTL8367C_PORT2_EEECFG_EEE_SLEEP_REQ_OFFSET 0 -+#define RTL8367C_PORT2_EEECFG_EEE_SLEEP_REQ_MASK 0x1 -+ -+#define RTL8367C_REG_PORT2_EEETXMTR 0x0059 -+ -+#define RTL8367C_REG_PORT2_EEERXMTR 0x005a -+ -+#define RTL8367C_REG_PORT2_EEEPTXMTR 0x005b -+ -+#define RTL8367C_REG_PORT2_EEEPRXMTR 0x005c -+ -+#define RTL8367C_REG_PTP_PORT2_CFG1 0x005e -+#define RTL8367C_PTP_PORT2_CFG1_OFFSET 7 -+#define RTL8367C_PTP_PORT2_CFG1_MASK 0xFF -+ -+#define RTL8367C_REG_P2_MSIC1 0x005f -+#define RTL8367C_P2_MSIC1_OFFSET 0 -+#define RTL8367C_P2_MSIC1_MASK 0x1 -+ -+#define RTL8367C_REG_PORT3_CGST_HALF_CFG 0x0060 -+#define RTL8367C_PORT3_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 -+#define RTL8367C_PORT3_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 -+#define RTL8367C_PORT3_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 -+#define RTL8367C_PORT3_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF -+ -+#define RTL8367C_REG_PKTGEN_PORT3_CTRL 0x0061 -+#define RTL8367C_PKTGEN_PORT3_CTRL_STATUS_OFFSET 15 -+#define RTL8367C_PKTGEN_PORT3_CTRL_STATUS_MASK 0x8000 -+#define RTL8367C_PKTGEN_PORT3_CTRL_PKTGEN_STS_OFFSET 13 -+#define RTL8367C_PKTGEN_PORT3_CTRL_PKTGEN_STS_MASK 0x2000 -+#define RTL8367C_PKTGEN_PORT3_CTRL_CRC_NO_ERROR_OFFSET 4 -+#define RTL8367C_PKTGEN_PORT3_CTRL_CRC_NO_ERROR_MASK 0x10 -+#define RTL8367C_PKTGEN_PORT3_CTRL_CMD_START_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT3_CTRL_CMD_START_MASK 0x1 -+ -+#define RTL8367C_REG_TX_ERR_CNT_PORT3 0x0062 -+#define RTL8367C_TX_ERR_CNT_PORT3_OFFSET 0 -+#define RTL8367C_TX_ERR_CNT_PORT3_MASK 0x7 -+ -+#define RTL8367C_REG_PKTGEN_PORT3_DA0 0x0063 -+ -+#define RTL8367C_REG_PKTGEN_PORT3_DA1 0x0064 -+ -+#define RTL8367C_REG_PKTGEN_PORT3_DA2 0x0065 -+ -+#define RTL8367C_REG_PKTGEN_PORT3_SA0 0x0066 -+ -+#define RTL8367C_REG_PKTGEN_PORT3_SA1 0x0067 -+ -+#define RTL8367C_REG_PKTGEN_PORT3_SA2 0x0068 -+ -+#define RTL8367C_REG_PKTGEN_PORT3_COUNTER0 0x0069 -+ -+#define RTL8367C_REG_PKTGEN_PORT3_COUNTER1 0x006a -+#define RTL8367C_PKTGEN_PORT3_COUNTER1_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT3_COUNTER1_MASK 0xFF -+ -+#define RTL8367C_REG_PKTGEN_PORT3_TX_LENGTH 0x006b -+#define RTL8367C_PKTGEN_PORT3_TX_LENGTH_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT3_TX_LENGTH_MASK 0x3FFF -+ -+#define RTL8367C_REG_PKTGEN_PORT3_TIMER 0x006d -+#define RTL8367C_PKTGEN_PORT3_TIMER_TIMER_OFFSET 4 -+#define RTL8367C_PKTGEN_PORT3_TIMER_TIMER_MASK 0xF0 -+#define RTL8367C_PKTGEN_PORT3_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 -+#define RTL8367C_PKTGEN_PORT3_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 -+ -+#define RTL8367C_REG_PORT3_MISC_CFG 0x006e -+#define RTL8367C_PORT3_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 -+#define RTL8367C_PORT3_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 -+#define RTL8367C_PORT3_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 -+#define RTL8367C_PORT3_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 -+#define RTL8367C_PORT3_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 -+#define RTL8367C_PORT3_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 -+#define RTL8367C_PORT3_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 -+#define RTL8367C_PORT3_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 -+#define RTL8367C_PORT3_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 -+#define RTL8367C_PORT3_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 -+#define RTL8367C_PORT3_MISC_CFG_INGRESSBW_IFG_OFFSET 10 -+#define RTL8367C_PORT3_MISC_CFG_INGRESSBW_IFG_MASK 0x400 -+#define RTL8367C_PORT3_MISC_CFG_RX_SPC_OFFSET 9 -+#define RTL8367C_PORT3_MISC_CFG_RX_SPC_MASK 0x200 -+#define RTL8367C_PORT3_MISC_CFG_CRC_SKIP_OFFSET 8 -+#define RTL8367C_PORT3_MISC_CFG_CRC_SKIP_MASK 0x100 -+#define RTL8367C_PORT3_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 -+#define RTL8367C_PORT3_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 -+#define RTL8367C_PORT3_MISC_CFG_MAC_LOOPBACK_OFFSET 6 -+#define RTL8367C_PORT3_MISC_CFG_MAC_LOOPBACK_MASK 0x40 -+#define RTL8367C_PORT3_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 -+#define RTL8367C_PORT3_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 -+#define RTL8367C_PORT3_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 -+#define RTL8367C_PORT3_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF -+ -+#define RTL8367C_REG_INGRESSBW_PORT3_RATE_CTRL0 0x006f -+ -+#define RTL8367C_REG_INGRESSBW_PORT3_RATE_CTRL1 0x0070 -+#define RTL8367C_INGRESSBW_PORT3_RATE_CTRL1_DUMMY_OFFSET 3 -+#define RTL8367C_INGRESSBW_PORT3_RATE_CTRL1_DUMMY_MASK 0xFFF8 -+#define RTL8367C_INGRESSBW_PORT3_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 -+#define RTL8367C_INGRESSBW_PORT3_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 -+ -+#define RTL8367C_REG_PORT3_FORCE_RATE0 0x0071 -+ -+#define RTL8367C_REG_PORT3_FORCE_RATE1 0x0072 -+ -+#define RTL8367C_REG_PORT3_CURENT_RATE0 0x0073 -+ -+#define RTL8367C_REG_PORT3_CURENT_RATE1 0x0074 -+ -+#define RTL8367C_REG_PORT3_PAGE_COUNTER 0x0075 -+#define RTL8367C_PORT3_PAGE_COUNTER_OFFSET 0 -+#define RTL8367C_PORT3_PAGE_COUNTER_MASK 0x7F -+ -+#define RTL8367C_REG_PAGEMETER_PORT3_CTRL0 0x0076 -+ -+#define RTL8367C_REG_PAGEMETER_PORT3_CTRL1 0x0077 -+ -+#define RTL8367C_REG_PORT3_EEECFG 0x0078 -+#define RTL8367C_PORT3_EEECFG_EEEP_ENABLE_TX_OFFSET 14 -+#define RTL8367C_PORT3_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 -+#define RTL8367C_PORT3_EEECFG_EEEP_ENABLE_RX_OFFSET 13 -+#define RTL8367C_PORT3_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 -+#define RTL8367C_PORT3_EEECFG_EEE_FORCE_OFFSET 12 -+#define RTL8367C_PORT3_EEECFG_EEE_FORCE_MASK 0x1000 -+#define RTL8367C_PORT3_EEECFG_EEE_100M_OFFSET 11 -+#define RTL8367C_PORT3_EEECFG_EEE_100M_MASK 0x800 -+#define RTL8367C_PORT3_EEECFG_EEE_GIGA_500M_OFFSET 10 -+#define RTL8367C_PORT3_EEECFG_EEE_GIGA_500M_MASK 0x400 -+#define RTL8367C_PORT3_EEECFG_EEE_TX_OFFSET 9 -+#define RTL8367C_PORT3_EEECFG_EEE_TX_MASK 0x200 -+#define RTL8367C_PORT3_EEECFG_EEE_RX_OFFSET 8 -+#define RTL8367C_PORT3_EEECFG_EEE_RX_MASK 0x100 -+#define RTL8367C_PORT3_EEECFG_EEE_DSP_RX_OFFSET 6 -+#define RTL8367C_PORT3_EEECFG_EEE_DSP_RX_MASK 0x40 -+#define RTL8367C_PORT3_EEECFG_EEE_LPI_OFFSET 5 -+#define RTL8367C_PORT3_EEECFG_EEE_LPI_MASK 0x20 -+#define RTL8367C_PORT3_EEECFG_EEE_TX_LPI_OFFSET 4 -+#define RTL8367C_PORT3_EEECFG_EEE_TX_LPI_MASK 0x10 -+#define RTL8367C_PORT3_EEECFG_EEE_RX_LPI_OFFSET 3 -+#define RTL8367C_PORT3_EEECFG_EEE_RX_LPI_MASK 0x8 -+#define RTL8367C_PORT3_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 -+#define RTL8367C_PORT3_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 -+#define RTL8367C_PORT3_EEECFG_EEE_WAKE_REQ_OFFSET 1 -+#define RTL8367C_PORT3_EEECFG_EEE_WAKE_REQ_MASK 0x2 -+#define RTL8367C_PORT3_EEECFG_EEE_SLEEP_REQ_OFFSET 0 -+#define RTL8367C_PORT3_EEECFG_EEE_SLEEP_REQ_MASK 0x1 -+ -+#define RTL8367C_REG_PORT3_EEETXMTR 0x0079 -+ -+#define RTL8367C_REG_PORT3_EEERXMTR 0x007a -+ -+#define RTL8367C_REG_PORT3_EEEPTXMTR 0x007b -+ -+#define RTL8367C_REG_PORT3_EEEPRXMTR 0x007c -+ -+#define RTL8367C_REG_PTP_PORT3_CFG1 0x007e -+#define RTL8367C_PTP_PORT3_CFG1_OFFSET 7 -+#define RTL8367C_PTP_PORT3_CFG1_MASK 0xFF -+ -+#define RTL8367C_REG_P3_MSIC1 0x007f -+#define RTL8367C_P3_MSIC1_OFFSET 0 -+#define RTL8367C_P3_MSIC1_MASK 0x1 -+ -+#define RTL8367C_REG_PORT4_CGST_HALF_CFG 0x0080 -+#define RTL8367C_PORT4_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 -+#define RTL8367C_PORT4_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 -+#define RTL8367C_PORT4_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 -+#define RTL8367C_PORT4_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF -+ -+#define RTL8367C_REG_PKTGEN_PORT4_CTRL 0x0081 -+#define RTL8367C_PKTGEN_PORT4_CTRL_STATUS_OFFSET 15 -+#define RTL8367C_PKTGEN_PORT4_CTRL_STATUS_MASK 0x8000 -+#define RTL8367C_PKTGEN_PORT4_CTRL_PKTGEN_STS_OFFSET 13 -+#define RTL8367C_PKTGEN_PORT4_CTRL_PKTGEN_STS_MASK 0x2000 -+#define RTL8367C_PKTGEN_PORT4_CTRL_CRC_NO_ERROR_OFFSET 4 -+#define RTL8367C_PKTGEN_PORT4_CTRL_CRC_NO_ERROR_MASK 0x10 -+#define RTL8367C_PKTGEN_PORT4_CTRL_CMD_START_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT4_CTRL_CMD_START_MASK 0x1 -+ -+#define RTL8367C_REG_TX_ERR_CNT_PORT4 0x0082 -+#define RTL8367C_TX_ERR_CNT_PORT4_OFFSET 0 -+#define RTL8367C_TX_ERR_CNT_PORT4_MASK 0x7 -+ -+#define RTL8367C_REG_PKTGEN_PORT4_DA0 0x0083 -+ -+#define RTL8367C_REG_PKTGEN_PORT4_DA1 0x0084 -+ -+#define RTL8367C_REG_PKTGEN_PORT4_DA2 0x0085 -+ -+#define RTL8367C_REG_PKTGEN_PORT4_SA0 0x0086 -+ -+#define RTL8367C_REG_PKTGEN_PORT4_SA1 0x0087 -+ -+#define RTL8367C_REG_PKTGEN_PORT4_SA2 0x0088 -+ -+#define RTL8367C_REG_PKTGEN_PORT4_COUNTER0 0x0089 -+ -+#define RTL8367C_REG_PKTGEN_PORT4_COUNTER1 0x008a -+#define RTL8367C_PKTGEN_PORT4_COUNTER1_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT4_COUNTER1_MASK 0xFF -+ -+#define RTL8367C_REG_PKTGEN_PORT4_TX_LENGTH 0x008b -+#define RTL8367C_PKTGEN_PORT4_TX_LENGTH_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT4_TX_LENGTH_MASK 0x3FFF -+ -+#define RTL8367C_REG_PKTGEN_PORT4_TIMER 0x008d -+#define RTL8367C_PKTGEN_PORT4_TIMER_TIMER_OFFSET 4 -+#define RTL8367C_PKTGEN_PORT4_TIMER_TIMER_MASK 0xF0 -+#define RTL8367C_PKTGEN_PORT4_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 -+#define RTL8367C_PKTGEN_PORT4_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 -+ -+#define RTL8367C_REG_PORT4_MISC_CFG 0x008e -+#define RTL8367C_PORT4_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 -+#define RTL8367C_PORT4_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 -+#define RTL8367C_PORT4_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 -+#define RTL8367C_PORT4_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 -+#define RTL8367C_PORT4_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 -+#define RTL8367C_PORT4_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 -+#define RTL8367C_PORT4_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 -+#define RTL8367C_PORT4_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 -+#define RTL8367C_PORT4_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 -+#define RTL8367C_PORT4_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 -+#define RTL8367C_PORT4_MISC_CFG_INGRESSBW_IFG_OFFSET 10 -+#define RTL8367C_PORT4_MISC_CFG_INGRESSBW_IFG_MASK 0x400 -+#define RTL8367C_PORT4_MISC_CFG_RX_SPC_OFFSET 9 -+#define RTL8367C_PORT4_MISC_CFG_RX_SPC_MASK 0x200 -+#define RTL8367C_PORT4_MISC_CFG_CRC_SKIP_OFFSET 8 -+#define RTL8367C_PORT4_MISC_CFG_CRC_SKIP_MASK 0x100 -+#define RTL8367C_PORT4_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 -+#define RTL8367C_PORT4_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 -+#define RTL8367C_PORT4_MISC_CFG_MAC_LOOPBACK_OFFSET 6 -+#define RTL8367C_PORT4_MISC_CFG_MAC_LOOPBACK_MASK 0x40 -+#define RTL8367C_PORT4_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 -+#define RTL8367C_PORT4_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 -+#define RTL8367C_PORT4_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 -+#define RTL8367C_PORT4_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF -+ -+#define RTL8367C_REG_INGRESSBW_PORT4_RATE_CTRL0 0x008f -+ -+#define RTL8367C_REG_INGRESSBW_PORT4_RATE_CTRL1 0x0090 -+#define RTL8367C_INGRESSBW_PORT4_RATE_CTRL1_DUMMY_OFFSET 3 -+#define RTL8367C_INGRESSBW_PORT4_RATE_CTRL1_DUMMY_MASK 0xFFF8 -+#define RTL8367C_INGRESSBW_PORT4_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 -+#define RTL8367C_INGRESSBW_PORT4_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 -+ -+#define RTL8367C_REG_PORT4_FORCE_RATE0 0x0091 -+ -+#define RTL8367C_REG_PORT4_FORCE_RATE1 0x0092 -+ -+#define RTL8367C_REG_PORT4_CURENT_RATE0 0x0093 -+ -+#define RTL8367C_REG_PORT4_CURENT_RATE1 0x0094 -+ -+#define RTL8367C_REG_PORT4_PAGE_COUNTER 0x0095 -+#define RTL8367C_PORT4_PAGE_COUNTER_OFFSET 0 -+#define RTL8367C_PORT4_PAGE_COUNTER_MASK 0x7F -+ -+#define RTL8367C_REG_PAGEMETER_PORT4_CTRL0 0x0096 -+ -+#define RTL8367C_REG_PAGEMETER_PORT4_CTRL1 0x0097 -+ -+#define RTL8367C_REG_PORT4_EEECFG 0x0098 -+#define RTL8367C_PORT4_EEECFG_EEEP_ENABLE_TX_OFFSET 14 -+#define RTL8367C_PORT4_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 -+#define RTL8367C_PORT4_EEECFG_EEEP_ENABLE_RX_OFFSET 13 -+#define RTL8367C_PORT4_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 -+#define RTL8367C_PORT4_EEECFG_EEE_FORCE_OFFSET 12 -+#define RTL8367C_PORT4_EEECFG_EEE_FORCE_MASK 0x1000 -+#define RTL8367C_PORT4_EEECFG_EEE_100M_OFFSET 11 -+#define RTL8367C_PORT4_EEECFG_EEE_100M_MASK 0x800 -+#define RTL8367C_PORT4_EEECFG_EEE_GIGA_500M_OFFSET 10 -+#define RTL8367C_PORT4_EEECFG_EEE_GIGA_500M_MASK 0x400 -+#define RTL8367C_PORT4_EEECFG_EEE_TX_OFFSET 9 -+#define RTL8367C_PORT4_EEECFG_EEE_TX_MASK 0x200 -+#define RTL8367C_PORT4_EEECFG_EEE_RX_OFFSET 8 -+#define RTL8367C_PORT4_EEECFG_EEE_RX_MASK 0x100 -+#define RTL8367C_PORT4_EEECFG_EEE_DSP_RX_OFFSET 6 -+#define RTL8367C_PORT4_EEECFG_EEE_DSP_RX_MASK 0x40 -+#define RTL8367C_PORT4_EEECFG_EEE_LPI_OFFSET 5 -+#define RTL8367C_PORT4_EEECFG_EEE_LPI_MASK 0x20 -+#define RTL8367C_PORT4_EEECFG_EEE_TX_LPI_OFFSET 4 -+#define RTL8367C_PORT4_EEECFG_EEE_TX_LPI_MASK 0x10 -+#define RTL8367C_PORT4_EEECFG_EEE_RX_LPI_OFFSET 3 -+#define RTL8367C_PORT4_EEECFG_EEE_RX_LPI_MASK 0x8 -+#define RTL8367C_PORT4_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 -+#define RTL8367C_PORT4_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 -+#define RTL8367C_PORT4_EEECFG_EEE_WAKE_REQ_OFFSET 1 -+#define RTL8367C_PORT4_EEECFG_EEE_WAKE_REQ_MASK 0x2 -+#define RTL8367C_PORT4_EEECFG_EEE_SLEEP_REQ_OFFSET 0 -+#define RTL8367C_PORT4_EEECFG_EEE_SLEEP_REQ_MASK 0x1 -+ -+#define RTL8367C_REG_PORT4_EEETXMTR 0x0099 -+ -+#define RTL8367C_REG_PORT4_EEERXMTR 0x009a -+ -+#define RTL8367C_REG_PORT4_EEEPTXMTR 0x009b -+ -+#define RTL8367C_REG_PORT4_EEEPRXMTR 0x009c -+ -+#define RTL8367C_REG_PTP_PORT4_CFG1 0x009e -+#define RTL8367C_PTP_PORT4_CFG1_OFFSET 7 -+#define RTL8367C_PTP_PORT4_CFG1_MASK 0xFF -+ -+#define RTL8367C_REG_P4_MSIC1 0x009f -+#define RTL8367C_P4_MSIC1_OFFSET 0 -+#define RTL8367C_P4_MSIC1_MASK 0x1 -+ -+#define RTL8367C_REG_PORT5_CGST_HALF_CFG 0x00a0 -+#define RTL8367C_PORT5_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 -+#define RTL8367C_PORT5_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 -+#define RTL8367C_PORT5_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 -+#define RTL8367C_PORT5_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF -+ -+#define RTL8367C_REG_PKTGEN_PORT5_CTRL 0x00a1 -+#define RTL8367C_PKTGEN_PORT5_CTRL_STATUS_OFFSET 15 -+#define RTL8367C_PKTGEN_PORT5_CTRL_STATUS_MASK 0x8000 -+#define RTL8367C_PKTGEN_PORT5_CTRL_PKTGEN_STS_OFFSET 13 -+#define RTL8367C_PKTGEN_PORT5_CTRL_PKTGEN_STS_MASK 0x2000 -+#define RTL8367C_PKTGEN_PORT5_CTRL_CRC_NO_ERROR_OFFSET 4 -+#define RTL8367C_PKTGEN_PORT5_CTRL_CRC_NO_ERROR_MASK 0x10 -+#define RTL8367C_PKTGEN_PORT5_CTRL_CMD_START_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT5_CTRL_CMD_START_MASK 0x1 -+ -+#define RTL8367C_REG_TX_ERR_CNT_PORT5 0x00a2 -+#define RTL8367C_TX_ERR_CNT_PORT5_OFFSET 0 -+#define RTL8367C_TX_ERR_CNT_PORT5_MASK 0x7 -+ -+#define RTL8367C_REG_PKTGEN_PORT5_DA0 0x00a3 -+ -+#define RTL8367C_REG_PKTGEN_PORT5_DA1 0x00a4 -+ -+#define RTL8367C_REG_PKTGEN_PORT5_DA2 0x00a5 -+ -+#define RTL8367C_REG_PKTGEN_PORT5_SA0 0x00a6 -+ -+#define RTL8367C_REG_PKTGEN_PORT5_SA1 0x00a7 -+ -+#define RTL8367C_REG_PKTGEN_PORT5_SA2 0x00a8 -+ -+#define RTL8367C_REG_PKTGEN_PORT5_COUNTER0 0x00a9 -+ -+#define RTL8367C_REG_PKTGEN_PORT5_COUNTER1 0x00aa -+#define RTL8367C_PKTGEN_PORT5_COUNTER1_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT5_COUNTER1_MASK 0xFF -+ -+#define RTL8367C_REG_PKTGEN_PORT5_TX_LENGTH 0x00ab -+#define RTL8367C_PKTGEN_PORT5_TX_LENGTH_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT5_TX_LENGTH_MASK 0x3FFF -+ -+#define RTL8367C_REG_PKTGEN_PORT5_TIMER 0x00ad -+#define RTL8367C_PKTGEN_PORT5_TIMER_TIMER_OFFSET 4 -+#define RTL8367C_PKTGEN_PORT5_TIMER_TIMER_MASK 0xF0 -+#define RTL8367C_PKTGEN_PORT5_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 -+#define RTL8367C_PKTGEN_PORT5_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 -+ -+#define RTL8367C_REG_PORT5_MISC_CFG 0x00ae -+#define RTL8367C_PORT5_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 -+#define RTL8367C_PORT5_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 -+#define RTL8367C_PORT5_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 -+#define RTL8367C_PORT5_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 -+#define RTL8367C_PORT5_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 -+#define RTL8367C_PORT5_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 -+#define RTL8367C_PORT5_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 -+#define RTL8367C_PORT5_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 -+#define RTL8367C_PORT5_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 -+#define RTL8367C_PORT5_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 -+#define RTL8367C_PORT5_MISC_CFG_INGRESSBW_IFG_OFFSET 10 -+#define RTL8367C_PORT5_MISC_CFG_INGRESSBW_IFG_MASK 0x400 -+#define RTL8367C_PORT5_MISC_CFG_RX_SPC_OFFSET 9 -+#define RTL8367C_PORT5_MISC_CFG_RX_SPC_MASK 0x200 -+#define RTL8367C_PORT5_MISC_CFG_CRC_SKIP_OFFSET 8 -+#define RTL8367C_PORT5_MISC_CFG_CRC_SKIP_MASK 0x100 -+#define RTL8367C_PORT5_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 -+#define RTL8367C_PORT5_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 -+#define RTL8367C_PORT5_MISC_CFG_MAC_LOOPBACK_OFFSET 6 -+#define RTL8367C_PORT5_MISC_CFG_MAC_LOOPBACK_MASK 0x40 -+#define RTL8367C_PORT5_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 -+#define RTL8367C_PORT5_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 -+#define RTL8367C_PORT5_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 -+#define RTL8367C_PORT5_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF -+ -+#define RTL8367C_REG_INGRESSBW_PORT5_RATE_CTRL0 0x00af -+ -+#define RTL8367C_REG_INGRESSBW_PORT5_RATE_CTRL1 0x00b0 -+#define RTL8367C_INGRESSBW_PORT5_RATE_CTRL1_DUMMY_OFFSET 3 -+#define RTL8367C_INGRESSBW_PORT5_RATE_CTRL1_DUMMY_MASK 0xFFF8 -+#define RTL8367C_INGRESSBW_PORT5_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 -+#define RTL8367C_INGRESSBW_PORT5_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 -+ -+#define RTL8367C_REG_PORT5_FORCE_RATE0 0x00b1 -+ -+#define RTL8367C_REG_PORT5_FORCE_RATE1 0x00b2 -+ -+#define RTL8367C_REG_PORT5_CURENT_RATE0 0x00b3 -+ -+#define RTL8367C_REG_PORT5_CURENT_RATE1 0x00b4 -+ -+#define RTL8367C_REG_PORT5_PAGE_COUNTER 0x00b5 -+#define RTL8367C_PORT5_PAGE_COUNTER_OFFSET 0 -+#define RTL8367C_PORT5_PAGE_COUNTER_MASK 0x7F -+ -+#define RTL8367C_REG_PAGEMETER_PORT5_CTRL0 0x00b6 -+ -+#define RTL8367C_REG_PAGEMETER_PORT5_CTRL1 0x00b7 -+ -+#define RTL8367C_REG_PORT5_EEECFG 0x00b8 -+#define RTL8367C_PORT5_EEECFG_EEEP_ENABLE_TX_OFFSET 14 -+#define RTL8367C_PORT5_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 -+#define RTL8367C_PORT5_EEECFG_EEEP_ENABLE_RX_OFFSET 13 -+#define RTL8367C_PORT5_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 -+#define RTL8367C_PORT5_EEECFG_EEE_FORCE_OFFSET 12 -+#define RTL8367C_PORT5_EEECFG_EEE_FORCE_MASK 0x1000 -+#define RTL8367C_PORT5_EEECFG_EEE_100M_OFFSET 11 -+#define RTL8367C_PORT5_EEECFG_EEE_100M_MASK 0x800 -+#define RTL8367C_PORT5_EEECFG_EEE_GIGA_500M_OFFSET 10 -+#define RTL8367C_PORT5_EEECFG_EEE_GIGA_500M_MASK 0x400 -+#define RTL8367C_PORT5_EEECFG_EEE_TX_OFFSET 9 -+#define RTL8367C_PORT5_EEECFG_EEE_TX_MASK 0x200 -+#define RTL8367C_PORT5_EEECFG_EEE_RX_OFFSET 8 -+#define RTL8367C_PORT5_EEECFG_EEE_RX_MASK 0x100 -+#define RTL8367C_PORT5_EEECFG_EEE_DSP_RX_OFFSET 6 -+#define RTL8367C_PORT5_EEECFG_EEE_DSP_RX_MASK 0x40 -+#define RTL8367C_PORT5_EEECFG_EEE_LPI_OFFSET 5 -+#define RTL8367C_PORT5_EEECFG_EEE_LPI_MASK 0x20 -+#define RTL8367C_PORT5_EEECFG_EEE_TX_LPI_OFFSET 4 -+#define RTL8367C_PORT5_EEECFG_EEE_TX_LPI_MASK 0x10 -+#define RTL8367C_PORT5_EEECFG_EEE_RX_LPI_OFFSET 3 -+#define RTL8367C_PORT5_EEECFG_EEE_RX_LPI_MASK 0x8 -+#define RTL8367C_PORT5_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 -+#define RTL8367C_PORT5_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 -+#define RTL8367C_PORT5_EEECFG_EEE_WAKE_REQ_OFFSET 1 -+#define RTL8367C_PORT5_EEECFG_EEE_WAKE_REQ_MASK 0x2 -+#define RTL8367C_PORT5_EEECFG_EEE_SLEEP_REQ_OFFSET 0 -+#define RTL8367C_PORT5_EEECFG_EEE_SLEEP_REQ_MASK 0x1 -+ -+#define RTL8367C_REG_PORT5_EEETXMTR 0x00b9 -+ -+#define RTL8367C_REG_PORT5_EEERXMTR 0x00ba -+ -+#define RTL8367C_REG_PORT5_EEEPTXMTR 0x00bb -+ -+#define RTL8367C_REG_PORT5_EEEPRXMTR 0x00bc -+ -+#define RTL8367C_REG_PTP_PORT5_CFG1 0x00be -+#define RTL8367C_PTP_PORT5_CFG1_OFFSET 7 -+#define RTL8367C_PTP_PORT5_CFG1_MASK 0xFF -+ -+#define RTL8367C_REG_P5_MSIC1 0x00bf -+#define RTL8367C_P5_MSIC1_OFFSET 0 -+#define RTL8367C_P5_MSIC1_MASK 0x1 -+ -+#define RTL8367C_REG_PORT6_CGST_HALF_CFG 0x00c0 -+#define RTL8367C_PORT6_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 -+#define RTL8367C_PORT6_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 -+#define RTL8367C_PORT6_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 -+#define RTL8367C_PORT6_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF -+ -+#define RTL8367C_REG_PKTGEN_PORT6_CTRL 0x00c1 -+#define RTL8367C_PKTGEN_PORT6_CTRL_STATUS_OFFSET 15 -+#define RTL8367C_PKTGEN_PORT6_CTRL_STATUS_MASK 0x8000 -+#define RTL8367C_PKTGEN_PORT6_CTRL_PKTGEN_STS_OFFSET 13 -+#define RTL8367C_PKTGEN_PORT6_CTRL_PKTGEN_STS_MASK 0x2000 -+#define RTL8367C_PKTGEN_PORT6_CTRL_CRC_NO_ERROR_OFFSET 4 -+#define RTL8367C_PKTGEN_PORT6_CTRL_CRC_NO_ERROR_MASK 0x10 -+#define RTL8367C_PKTGEN_PORT6_CTRL_CMD_START_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT6_CTRL_CMD_START_MASK 0x1 -+ -+#define RTL8367C_REG_TX_ERR_CNT_PORT6 0x00c2 -+#define RTL8367C_TX_ERR_CNT_PORT6_OFFSET 0 -+#define RTL8367C_TX_ERR_CNT_PORT6_MASK 0x7 -+ -+#define RTL8367C_REG_PKTGEN_PORT6_DA0 0x00c3 -+ -+#define RTL8367C_REG_PKTGEN_PORT6_DA1 0x00c4 -+ -+#define RTL8367C_REG_PKTGEN_PORT6_DA2 0x00c5 -+ -+#define RTL8367C_REG_PKTGEN_PORT6_SA0 0x00c6 -+ -+#define RTL8367C_REG_PKTGEN_PORT6_SA1 0x00c7 -+ -+#define RTL8367C_REG_PKTGEN_PORT6_SA2 0x00c8 -+ -+#define RTL8367C_REG_PKTGEN_PORT6_COUNTER0 0x00c9 -+ -+#define RTL8367C_REG_PKTGEN_PORT6_COUNTER1 0x00ca -+#define RTL8367C_PKTGEN_PORT6_COUNTER1_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT6_COUNTER1_MASK 0xFF -+ -+#define RTL8367C_REG_PKTGEN_PORT6_TX_LENGTH 0x00cb -+#define RTL8367C_PKTGEN_PORT6_TX_LENGTH_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT6_TX_LENGTH_MASK 0x3FFF -+ -+#define RTL8367C_REG_PKTGEN_PORT6_TIMER 0x00cd -+#define RTL8367C_PKTGEN_PORT6_TIMER_TIMER_OFFSET 4 -+#define RTL8367C_PKTGEN_PORT6_TIMER_TIMER_MASK 0xF0 -+#define RTL8367C_PKTGEN_PORT6_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 -+#define RTL8367C_PKTGEN_PORT6_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 -+ -+#define RTL8367C_REG_PORT6_MISC_CFG 0x00ce -+#define RTL8367C_PORT6_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 -+#define RTL8367C_PORT6_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 -+#define RTL8367C_PORT6_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 -+#define RTL8367C_PORT6_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 -+#define RTL8367C_PORT6_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 -+#define RTL8367C_PORT6_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 -+#define RTL8367C_PORT6_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 -+#define RTL8367C_PORT6_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 -+#define RTL8367C_PORT6_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 -+#define RTL8367C_PORT6_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 -+#define RTL8367C_PORT6_MISC_CFG_INGRESSBW_IFG_OFFSET 10 -+#define RTL8367C_PORT6_MISC_CFG_INGRESSBW_IFG_MASK 0x400 -+#define RTL8367C_PORT6_MISC_CFG_RX_SPC_OFFSET 9 -+#define RTL8367C_PORT6_MISC_CFG_RX_SPC_MASK 0x200 -+#define RTL8367C_PORT6_MISC_CFG_CRC_SKIP_OFFSET 8 -+#define RTL8367C_PORT6_MISC_CFG_CRC_SKIP_MASK 0x100 -+#define RTL8367C_PORT6_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 -+#define RTL8367C_PORT6_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 -+#define RTL8367C_PORT6_MISC_CFG_MAC_LOOPBACK_OFFSET 6 -+#define RTL8367C_PORT6_MISC_CFG_MAC_LOOPBACK_MASK 0x40 -+#define RTL8367C_PORT6_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 -+#define RTL8367C_PORT6_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 -+#define RTL8367C_PORT6_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 -+#define RTL8367C_PORT6_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF -+ -+#define RTL8367C_REG_INGRESSBW_PORT6_RATE_CTRL0 0x00cf -+ -+#define RTL8367C_REG_INGRESSBW_PORT6_RATE_CTRL1 0x00d0 -+#define RTL8367C_INGRESSBW_PORT6_RATE_CTRL1_DUMMY_OFFSET 3 -+#define RTL8367C_INGRESSBW_PORT6_RATE_CTRL1_DUMMY_MASK 0xFFF8 -+#define RTL8367C_INGRESSBW_PORT6_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 -+#define RTL8367C_INGRESSBW_PORT6_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 -+ -+#define RTL8367C_REG_PORT6_FORCE_RATE0 0x00d1 -+ -+#define RTL8367C_REG_PORT6_FORCE_RATE1 0x00d2 -+ -+#define RTL8367C_REG_PORT6_CURENT_RATE0 0x00d3 -+ -+#define RTL8367C_REG_PORT6_CURENT_RATE1 0x00d4 -+ -+#define RTL8367C_REG_PORT6_PAGE_COUNTER 0x00d5 -+#define RTL8367C_PORT6_PAGE_COUNTER_OFFSET 0 -+#define RTL8367C_PORT6_PAGE_COUNTER_MASK 0x7F -+ -+#define RTL8367C_REG_PAGEMETER_PORT6_CTRL0 0x00d6 -+ -+#define RTL8367C_REG_PAGEMETER_PORT6_CTRL1 0x00d7 -+ -+#define RTL8367C_REG_PORT6_EEECFG 0x00d8 -+#define RTL8367C_PORT6_EEECFG_EEEP_ENABLE_TX_OFFSET 14 -+#define RTL8367C_PORT6_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 -+#define RTL8367C_PORT6_EEECFG_EEEP_ENABLE_RX_OFFSET 13 -+#define RTL8367C_PORT6_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 -+#define RTL8367C_PORT6_EEECFG_EEE_FORCE_OFFSET 12 -+#define RTL8367C_PORT6_EEECFG_EEE_FORCE_MASK 0x1000 -+#define RTL8367C_PORT6_EEECFG_EEE_100M_OFFSET 11 -+#define RTL8367C_PORT6_EEECFG_EEE_100M_MASK 0x800 -+#define RTL8367C_PORT6_EEECFG_EEE_GIGA_500M_OFFSET 10 -+#define RTL8367C_PORT6_EEECFG_EEE_GIGA_500M_MASK 0x400 -+#define RTL8367C_PORT6_EEECFG_EEE_TX_OFFSET 9 -+#define RTL8367C_PORT6_EEECFG_EEE_TX_MASK 0x200 -+#define RTL8367C_PORT6_EEECFG_EEE_RX_OFFSET 8 -+#define RTL8367C_PORT6_EEECFG_EEE_RX_MASK 0x100 -+#define RTL8367C_PORT6_EEECFG_EEE_DSP_RX_OFFSET 6 -+#define RTL8367C_PORT6_EEECFG_EEE_DSP_RX_MASK 0x40 -+#define RTL8367C_PORT6_EEECFG_EEE_LPI_OFFSET 5 -+#define RTL8367C_PORT6_EEECFG_EEE_LPI_MASK 0x20 -+#define RTL8367C_PORT6_EEECFG_EEE_TX_LPI_OFFSET 4 -+#define RTL8367C_PORT6_EEECFG_EEE_TX_LPI_MASK 0x10 -+#define RTL8367C_PORT6_EEECFG_EEE_RX_LPI_OFFSET 3 -+#define RTL8367C_PORT6_EEECFG_EEE_RX_LPI_MASK 0x8 -+#define RTL8367C_PORT6_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 -+#define RTL8367C_PORT6_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 -+#define RTL8367C_PORT6_EEECFG_EEE_WAKE_REQ_OFFSET 1 -+#define RTL8367C_PORT6_EEECFG_EEE_WAKE_REQ_MASK 0x2 -+#define RTL8367C_PORT6_EEECFG_EEE_SLEEP_REQ_OFFSET 0 -+#define RTL8367C_PORT6_EEECFG_EEE_SLEEP_REQ_MASK 0x1 -+ -+#define RTL8367C_REG_PORT6_EEETXMTR 0x00d9 -+ -+#define RTL8367C_REG_PORT6_EEERXMTR 0x00da -+ -+#define RTL8367C_REG_PORT6_EEEPTXMTR 0x00db -+ -+#define RTL8367C_REG_PORT6_EEEPRXMTR 0x00dc -+ -+#define RTL8367C_REG_PTP_PORT6_CFG1 0x00de -+#define RTL8367C_PTP_PORT6_CFG1_OFFSET 7 -+#define RTL8367C_PTP_PORT6_CFG1_MASK 0xFF -+ -+#define RTL8367C_REG_P6_MSIC1 0x00df -+#define RTL8367C_P6_MSIC1_OFFSET 0 -+#define RTL8367C_P6_MSIC1_MASK 0x1 -+ -+#define RTL8367C_REG_PORT7_CGST_HALF_CFG 0x00e0 -+#define RTL8367C_PORT7_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 -+#define RTL8367C_PORT7_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 -+#define RTL8367C_PORT7_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 -+#define RTL8367C_PORT7_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF -+ -+#define RTL8367C_REG_PKTGEN_PORT7_CTRL 0x00e1 -+#define RTL8367C_PKTGEN_PORT7_CTRL_STATUS_OFFSET 15 -+#define RTL8367C_PKTGEN_PORT7_CTRL_STATUS_MASK 0x8000 -+#define RTL8367C_PKTGEN_PORT7_CTRL_PKTGEN_STS_OFFSET 13 -+#define RTL8367C_PKTGEN_PORT7_CTRL_PKTGEN_STS_MASK 0x2000 -+#define RTL8367C_PKTGEN_PORT7_CTRL_CRC_NO_ERROR_OFFSET 4 -+#define RTL8367C_PKTGEN_PORT7_CTRL_CRC_NO_ERROR_MASK 0x10 -+#define RTL8367C_PKTGEN_PORT7_CTRL_CMD_START_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT7_CTRL_CMD_START_MASK 0x1 -+ -+#define RTL8367C_REG_TX_ERR_CNT_PORT7 0x00e2 -+#define RTL8367C_TX_ERR_CNT_PORT7_OFFSET 0 -+#define RTL8367C_TX_ERR_CNT_PORT7_MASK 0x7 -+ -+#define RTL8367C_REG_PKTGEN_PORT7_DA0 0x00e3 -+ -+#define RTL8367C_REG_PKTGEN_PORT7_DA1 0x00e4 -+ -+#define RTL8367C_REG_PKTGEN_PORT7_DA2 0x00e5 -+ -+#define RTL8367C_REG_PKTGEN_PORT7_SA0 0x00e6 -+ -+#define RTL8367C_REG_PKTGEN_PORT7_SA1 0x00e7 -+ -+#define RTL8367C_REG_PKTGEN_PORT7_SA2 0x00e8 -+ -+#define RTL8367C_REG_PKTGEN_PORT7_COUNTER0 0x00e9 -+ -+#define RTL8367C_REG_PKTGEN_PORT7_COUNTER1 0x00ea -+#define RTL8367C_PKTGEN_PORT7_COUNTER1_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT7_COUNTER1_MASK 0xFF -+ -+#define RTL8367C_REG_PKTGEN_PORT7_TX_LENGTH 0x00eb -+#define RTL8367C_PKTGEN_PORT7_TX_LENGTH_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT7_TX_LENGTH_MASK 0x3FFF -+ -+#define RTL8367C_REG_PKTGEN_PORT7_TIMER 0x00ed -+#define RTL8367C_PKTGEN_PORT7_TIMER_TIMER_OFFSET 4 -+#define RTL8367C_PKTGEN_PORT7_TIMER_TIMER_MASK 0xF0 -+#define RTL8367C_PKTGEN_PORT7_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 -+#define RTL8367C_PKTGEN_PORT7_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 -+ -+#define RTL8367C_REG_PORT7_MISC_CFG 0x00ee -+#define RTL8367C_PORT7_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 -+#define RTL8367C_PORT7_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 -+#define RTL8367C_PORT7_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 -+#define RTL8367C_PORT7_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 -+#define RTL8367C_PORT7_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 -+#define RTL8367C_PORT7_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 -+#define RTL8367C_PORT7_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 -+#define RTL8367C_PORT7_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 -+#define RTL8367C_PORT7_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 -+#define RTL8367C_PORT7_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 -+#define RTL8367C_PORT7_MISC_CFG_INGRESSBW_IFG_OFFSET 10 -+#define RTL8367C_PORT7_MISC_CFG_INGRESSBW_IFG_MASK 0x400 -+#define RTL8367C_PORT7_MISC_CFG_RX_SPC_OFFSET 9 -+#define RTL8367C_PORT7_MISC_CFG_RX_SPC_MASK 0x200 -+#define RTL8367C_PORT7_MISC_CFG_CRC_SKIP_OFFSET 8 -+#define RTL8367C_PORT7_MISC_CFG_CRC_SKIP_MASK 0x100 -+#define RTL8367C_PORT7_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 -+#define RTL8367C_PORT7_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 -+#define RTL8367C_PORT7_MISC_CFG_MAC_LOOPBACK_OFFSET 6 -+#define RTL8367C_PORT7_MISC_CFG_MAC_LOOPBACK_MASK 0x40 -+#define RTL8367C_PORT7_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 -+#define RTL8367C_PORT7_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 -+#define RTL8367C_PORT7_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 -+#define RTL8367C_PORT7_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF -+ -+#define RTL8367C_REG_INGRESSBW_PORT7_RATE_CTRL0 0x00ef -+ -+#define RTL8367C_REG_INGRESSBW_PORT7_RATE_CTRL1 0x00f0 -+#define RTL8367C_INGRESSBW_PORT7_RATE_CTRL1_DUMMY_OFFSET 3 -+#define RTL8367C_INGRESSBW_PORT7_RATE_CTRL1_DUMMY_MASK 0xFFF8 -+#define RTL8367C_INGRESSBW_PORT7_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 -+#define RTL8367C_INGRESSBW_PORT7_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 -+ -+#define RTL8367C_REG_PORT7_FORCE_RATE0 0x00f1 -+ -+#define RTL8367C_REG_PORT7_FORCE_RATE1 0x00f2 -+ -+#define RTL8367C_REG_PORT7_CURENT_RATE0 0x00f3 -+ -+#define RTL8367C_REG_PORT7_CURENT_RATE1 0x00f4 -+ -+#define RTL8367C_REG_PORT7_PAGE_COUNTER 0x00f5 -+#define RTL8367C_PORT7_PAGE_COUNTER_OFFSET 0 -+#define RTL8367C_PORT7_PAGE_COUNTER_MASK 0x7F -+ -+#define RTL8367C_REG_PAGEMETER_PORT7_CTRL0 0x00f6 -+ -+#define RTL8367C_REG_PAGEMETER_PORT7_CTRL1 0x00f7 -+ -+#define RTL8367C_REG_PORT7_EEECFG 0x00f8 -+#define RTL8367C_PORT7_EEECFG_EEEP_ENABLE_TX_OFFSET 14 -+#define RTL8367C_PORT7_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 -+#define RTL8367C_PORT7_EEECFG_EEEP_ENABLE_RX_OFFSET 13 -+#define RTL8367C_PORT7_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 -+#define RTL8367C_PORT7_EEECFG_EEE_FORCE_OFFSET 12 -+#define RTL8367C_PORT7_EEECFG_EEE_FORCE_MASK 0x1000 -+#define RTL8367C_PORT7_EEECFG_EEE_100M_OFFSET 11 -+#define RTL8367C_PORT7_EEECFG_EEE_100M_MASK 0x800 -+#define RTL8367C_PORT7_EEECFG_EEE_GIGA_500M_OFFSET 10 -+#define RTL8367C_PORT7_EEECFG_EEE_GIGA_500M_MASK 0x400 -+#define RTL8367C_PORT7_EEECFG_EEE_TX_OFFSET 9 -+#define RTL8367C_PORT7_EEECFG_EEE_TX_MASK 0x200 -+#define RTL8367C_PORT7_EEECFG_EEE_RX_OFFSET 8 -+#define RTL8367C_PORT7_EEECFG_EEE_RX_MASK 0x100 -+#define RTL8367C_PORT7_EEECFG_EEE_DSP_RX_OFFSET 6 -+#define RTL8367C_PORT7_EEECFG_EEE_DSP_RX_MASK 0x40 -+#define RTL8367C_PORT7_EEECFG_EEE_LPI_OFFSET 5 -+#define RTL8367C_PORT7_EEECFG_EEE_LPI_MASK 0x20 -+#define RTL8367C_PORT7_EEECFG_EEE_TX_LPI_OFFSET 4 -+#define RTL8367C_PORT7_EEECFG_EEE_TX_LPI_MASK 0x10 -+#define RTL8367C_PORT7_EEECFG_EEE_RX_LPI_OFFSET 3 -+#define RTL8367C_PORT7_EEECFG_EEE_RX_LPI_MASK 0x8 -+#define RTL8367C_PORT7_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 -+#define RTL8367C_PORT7_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 -+#define RTL8367C_PORT7_EEECFG_EEE_WAKE_REQ_OFFSET 1 -+#define RTL8367C_PORT7_EEECFG_EEE_WAKE_REQ_MASK 0x2 -+#define RTL8367C_PORT7_EEECFG_EEE_SLEEP_REQ_OFFSET 0 -+#define RTL8367C_PORT7_EEECFG_EEE_SLEEP_REQ_MASK 0x1 -+ -+#define RTL8367C_REG_PORT7_EEETXMTR 0x00f9 -+ -+#define RTL8367C_REG_PORT7_EEERXMTR 0x00fa -+ -+#define RTL8367C_REG_PORT7_EEEPTXMTR 0x00fb -+ -+#define RTL8367C_REG_PORT7_EEEPRXMTR 0x00fc -+ -+#define RTL8367C_REG_PTP_PORT7_CFG1 0x00fe -+#define RTL8367C_PTP_PORT7_CFG1_OFFSET 7 -+#define RTL8367C_PTP_PORT7_CFG1_MASK 0xFF -+ -+#define RTL8367C_REG_P7_MSIC1 0x00ff -+#define RTL8367C_P7_MSIC1_OFFSET 0 -+#define RTL8367C_P7_MSIC1_MASK 0x1 -+ -+#define RTL8367C_REG_PORT8_CGST_HALF_CFG 0x0100 -+#define RTL8367C_PORT8_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 -+#define RTL8367C_PORT8_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 -+#define RTL8367C_PORT8_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 -+#define RTL8367C_PORT8_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF -+ -+#define RTL8367C_REG_PKTGEN_PORT8_CTRL 0x0101 -+#define RTL8367C_PKTGEN_PORT8_CTRL_STATUS_OFFSET 15 -+#define RTL8367C_PKTGEN_PORT8_CTRL_STATUS_MASK 0x8000 -+#define RTL8367C_PKTGEN_PORT8_CTRL_PKTGEN_STS_OFFSET 13 -+#define RTL8367C_PKTGEN_PORT8_CTRL_PKTGEN_STS_MASK 0x2000 -+#define RTL8367C_PKTGEN_PORT8_CTRL_CRC_NO_ERROR_OFFSET 4 -+#define RTL8367C_PKTGEN_PORT8_CTRL_CRC_NO_ERROR_MASK 0x10 -+#define RTL8367C_PKTGEN_PORT8_CTRL_CMD_START_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT8_CTRL_CMD_START_MASK 0x1 -+ -+#define RTL8367C_REG_TX_ERR_CNT_PORT8 0x0102 -+#define RTL8367C_TX_ERR_CNT_PORT8_OFFSET 0 -+#define RTL8367C_TX_ERR_CNT_PORT8_MASK 0x7 -+ -+#define RTL8367C_REG_PKTGEN_PORT8_DA0 0x0103 -+ -+#define RTL8367C_REG_PKTGEN_PORT8_DA1 0x0104 -+ -+#define RTL8367C_REG_PKTGEN_PORT8_DA2 0x0105 -+ -+#define RTL8367C_REG_PKTGEN_PORT8_SA0 0x0106 -+ -+#define RTL8367C_REG_PKTGEN_PORT8_SA1 0x0107 -+ -+#define RTL8367C_REG_PKTGEN_PORT8_SA2 0x0108 -+ -+#define RTL8367C_REG_PKTGEN_PORT8_COUNTER0 0x0109 -+ -+#define RTL8367C_REG_PKTGEN_PORT8_COUNTER1 0x010a -+#define RTL8367C_PKTGEN_PORT8_COUNTER1_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT8_COUNTER1_MASK 0xFF -+ -+#define RTL8367C_REG_PKTGEN_PORT8_TX_LENGTH 0x010b -+#define RTL8367C_PKTGEN_PORT8_TX_LENGTH_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT8_TX_LENGTH_MASK 0x3FFF -+ -+#define RTL8367C_REG_PKTGEN_PORT8_TIMER 0x010d -+#define RTL8367C_PKTGEN_PORT8_TIMER_TIMER_OFFSET 4 -+#define RTL8367C_PKTGEN_PORT8_TIMER_TIMER_MASK 0xF0 -+#define RTL8367C_PKTGEN_PORT8_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 -+#define RTL8367C_PKTGEN_PORT8_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 -+ -+#define RTL8367C_REG_PORT8_MISC_CFG 0x010e -+#define RTL8367C_PORT8_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 -+#define RTL8367C_PORT8_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 -+#define RTL8367C_PORT8_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 -+#define RTL8367C_PORT8_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 -+#define RTL8367C_PORT8_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 -+#define RTL8367C_PORT8_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 -+#define RTL8367C_PORT8_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 -+#define RTL8367C_PORT8_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 -+#define RTL8367C_PORT8_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 -+#define RTL8367C_PORT8_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 -+#define RTL8367C_PORT8_MISC_CFG_INGRESSBW_IFG_OFFSET 10 -+#define RTL8367C_PORT8_MISC_CFG_INGRESSBW_IFG_MASK 0x400 -+#define RTL8367C_PORT8_MISC_CFG_RX_SPC_OFFSET 9 -+#define RTL8367C_PORT8_MISC_CFG_RX_SPC_MASK 0x200 -+#define RTL8367C_PORT8_MISC_CFG_CRC_SKIP_OFFSET 8 -+#define RTL8367C_PORT8_MISC_CFG_CRC_SKIP_MASK 0x100 -+#define RTL8367C_PORT8_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 -+#define RTL8367C_PORT8_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 -+#define RTL8367C_PORT8_MISC_CFG_MAC_LOOPBACK_OFFSET 6 -+#define RTL8367C_PORT8_MISC_CFG_MAC_LOOPBACK_MASK 0x40 -+#define RTL8367C_PORT8_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 -+#define RTL8367C_PORT8_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 -+#define RTL8367C_PORT8_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 -+#define RTL8367C_PORT8_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF -+ -+#define RTL8367C_REG_INGRESSBW_PORT8_RATE_CTRL0 0x010f -+ -+#define RTL8367C_REG_INGRESSBW_PORT8_RATE_CTRL1 0x0110 -+#define RTL8367C_INGRESSBW_PORT8_RATE_CTRL1_DUMMY_OFFSET 3 -+#define RTL8367C_INGRESSBW_PORT8_RATE_CTRL1_DUMMY_MASK 0xFFF8 -+#define RTL8367C_INGRESSBW_PORT8_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 -+#define RTL8367C_INGRESSBW_PORT8_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 -+ -+#define RTL8367C_REG_PORT8_FORCE_RATE0 0x0111 -+ -+#define RTL8367C_REG_PORT8_FORCE_RATE1 0x0112 -+ -+#define RTL8367C_REG_PORT8_CURENT_RATE0 0x0113 -+ -+#define RTL8367C_REG_PORT8_CURENT_RATE1 0x0114 -+ -+#define RTL8367C_REG_PORT8_PAGE_COUNTER 0x0115 -+#define RTL8367C_PORT8_PAGE_COUNTER_OFFSET 0 -+#define RTL8367C_PORT8_PAGE_COUNTER_MASK 0x7F -+ -+#define RTL8367C_REG_PAGEMETER_PORT8_CTRL0 0x0116 -+ -+#define RTL8367C_REG_PAGEMETER_PORT8_CTRL1 0x0117 -+ -+#define RTL8367C_REG_PORT8_EEECFG 0x0118 -+#define RTL8367C_PORT8_EEECFG_EEEP_ENABLE_TX_OFFSET 14 -+#define RTL8367C_PORT8_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 -+#define RTL8367C_PORT8_EEECFG_EEEP_ENABLE_RX_OFFSET 13 -+#define RTL8367C_PORT8_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 -+#define RTL8367C_PORT8_EEECFG_EEE_FORCE_OFFSET 12 -+#define RTL8367C_PORT8_EEECFG_EEE_FORCE_MASK 0x1000 -+#define RTL8367C_PORT8_EEECFG_EEE_100M_OFFSET 11 -+#define RTL8367C_PORT8_EEECFG_EEE_100M_MASK 0x800 -+#define RTL8367C_PORT8_EEECFG_EEE_GIGA_500M_OFFSET 10 -+#define RTL8367C_PORT8_EEECFG_EEE_GIGA_500M_MASK 0x400 -+#define RTL8367C_PORT8_EEECFG_EEE_TX_OFFSET 9 -+#define RTL8367C_PORT8_EEECFG_EEE_TX_MASK 0x200 -+#define RTL8367C_PORT8_EEECFG_EEE_RX_OFFSET 8 -+#define RTL8367C_PORT8_EEECFG_EEE_RX_MASK 0x100 -+#define RTL8367C_PORT8_EEECFG_EEE_DSP_RX_OFFSET 6 -+#define RTL8367C_PORT8_EEECFG_EEE_DSP_RX_MASK 0x40 -+#define RTL8367C_PORT8_EEECFG_EEE_LPI_OFFSET 5 -+#define RTL8367C_PORT8_EEECFG_EEE_LPI_MASK 0x20 -+#define RTL8367C_PORT8_EEECFG_EEE_TX_LPI_OFFSET 4 -+#define RTL8367C_PORT8_EEECFG_EEE_TX_LPI_MASK 0x10 -+#define RTL8367C_PORT8_EEECFG_EEE_RX_LPI_OFFSET 3 -+#define RTL8367C_PORT8_EEECFG_EEE_RX_LPI_MASK 0x8 -+#define RTL8367C_PORT8_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 -+#define RTL8367C_PORT8_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 -+#define RTL8367C_PORT8_EEECFG_EEE_WAKE_REQ_OFFSET 1 -+#define RTL8367C_PORT8_EEECFG_EEE_WAKE_REQ_MASK 0x2 -+#define RTL8367C_PORT8_EEECFG_EEE_SLEEP_REQ_OFFSET 0 -+#define RTL8367C_PORT8_EEECFG_EEE_SLEEP_REQ_MASK 0x1 -+ -+#define RTL8367C_REG_PORT8_EEETXMTR 0x0119 -+ -+#define RTL8367C_REG_PORT8_EEERXMTR 0x011a -+ -+#define RTL8367C_REG_PORT8_EEEPTXMTR 0x011b -+ -+#define RTL8367C_REG_PORT8_EEEPRXMTR 0x011c -+ -+#define RTL8367C_REG_PTP_PORT8_CFG1 0x011e -+#define RTL8367C_PTP_PORT8_CFG1_OFFSET 7 -+#define RTL8367C_PTP_PORT8_CFG1_MASK 0xFF -+ -+#define RTL8367C_REG_P8_MSIC1 0x011f -+#define RTL8367C_P8_MSIC1_OFFSET 0 -+#define RTL8367C_P8_MSIC1_MASK 0x1 -+ -+#define RTL8367C_REG_PORT9_CGST_HALF_CFG 0x0120 -+#define RTL8367C_PORT9_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 -+#define RTL8367C_PORT9_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 -+#define RTL8367C_PORT9_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 -+#define RTL8367C_PORT9_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF -+ -+#define RTL8367C_REG_PKTGEN_PORT9_CTRL 0x0121 -+#define RTL8367C_PKTGEN_PORT9_CTRL_STATUS_OFFSET 15 -+#define RTL8367C_PKTGEN_PORT9_CTRL_STATUS_MASK 0x8000 -+#define RTL8367C_PKTGEN_PORT9_CTRL_PKTGEN_STS_OFFSET 13 -+#define RTL8367C_PKTGEN_PORT9_CTRL_PKTGEN_STS_MASK 0x2000 -+#define RTL8367C_PKTGEN_PORT9_CTRL_CRC_NO_ERROR_OFFSET 4 -+#define RTL8367C_PKTGEN_PORT9_CTRL_CRC_NO_ERROR_MASK 0x10 -+#define RTL8367C_PKTGEN_PORT9_CTRL_CMD_START_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT9_CTRL_CMD_START_MASK 0x1 -+ -+#define RTL8367C_REG_TX_ERR_CNT_PORT9 0x0122 -+#define RTL8367C_TX_ERR_CNT_PORT9_OFFSET 0 -+#define RTL8367C_TX_ERR_CNT_PORT9_MASK 0x7 -+ -+#define RTL8367C_REG_PKTGEN_PORT9_DA0 0x0123 -+ -+#define RTL8367C_REG_PKTGEN_PORT9_DA1 0x0124 -+ -+#define RTL8367C_REG_PKTGEN_PORT9_DA2 0x0125 -+ -+#define RTL8367C_REG_PKTGEN_PORT9_SA0 0x0126 -+ -+#define RTL8367C_REG_PKTGEN_PORT9_SA1 0x0127 -+ -+#define RTL8367C_REG_PKTGEN_PORT9_SA2 0x0128 -+ -+#define RTL8367C_REG_PKTGEN_PORT9_COUNTER0 0x0129 -+ -+#define RTL8367C_REG_PKTGEN_PORT9_COUNTER1 0x012a -+#define RTL8367C_PKTGEN_PORT9_COUNTER1_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT9_COUNTER1_MASK 0xFF -+ -+#define RTL8367C_REG_PKTGEN_PORT9_TX_LENGTH 0x012b -+#define RTL8367C_PKTGEN_PORT9_TX_LENGTH_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT9_TX_LENGTH_MASK 0x3FFF -+ -+#define RTL8367C_REG_PKTGEN_PORT9_TIMER 0x012d -+#define RTL8367C_PKTGEN_PORT9_TIMER_TIMER_OFFSET 4 -+#define RTL8367C_PKTGEN_PORT9_TIMER_TIMER_MASK 0xF0 -+#define RTL8367C_PKTGEN_PORT9_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 -+#define RTL8367C_PKTGEN_PORT9_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 -+ -+#define RTL8367C_REG_PORT9_MISC_CFG 0x012e -+#define RTL8367C_PORT9_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 -+#define RTL8367C_PORT9_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 -+#define RTL8367C_PORT9_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 -+#define RTL8367C_PORT9_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 -+#define RTL8367C_PORT9_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 -+#define RTL8367C_PORT9_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 -+#define RTL8367C_PORT9_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 -+#define RTL8367C_PORT9_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 -+#define RTL8367C_PORT9_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 -+#define RTL8367C_PORT9_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 -+#define RTL8367C_PORT9_MISC_CFG_INGRESSBW_IFG_OFFSET 10 -+#define RTL8367C_PORT9_MISC_CFG_INGRESSBW_IFG_MASK 0x400 -+#define RTL8367C_PORT9_MISC_CFG_RX_SPC_OFFSET 9 -+#define RTL8367C_PORT9_MISC_CFG_RX_SPC_MASK 0x200 -+#define RTL8367C_PORT9_MISC_CFG_CRC_SKIP_OFFSET 8 -+#define RTL8367C_PORT9_MISC_CFG_CRC_SKIP_MASK 0x100 -+#define RTL8367C_PORT9_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 -+#define RTL8367C_PORT9_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 -+#define RTL8367C_PORT9_MISC_CFG_MAC_LOOPBACK_OFFSET 6 -+#define RTL8367C_PORT9_MISC_CFG_MAC_LOOPBACK_MASK 0x40 -+#define RTL8367C_PORT9_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 -+#define RTL8367C_PORT9_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 -+#define RTL8367C_PORT9_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 -+#define RTL8367C_PORT9_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF -+ -+#define RTL8367C_REG_INGRESSBW_PORT9_RATE_CTRL0 0x012f -+ -+#define RTL8367C_REG_INGRESSBW_PORT9_RATE_CTRL1 0x0130 -+#define RTL8367C_INGRESSBW_PORT9_RATE_CTRL1_DUMMY_OFFSET 3 -+#define RTL8367C_INGRESSBW_PORT9_RATE_CTRL1_DUMMY_MASK 0xFFF8 -+#define RTL8367C_INGRESSBW_PORT9_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 -+#define RTL8367C_INGRESSBW_PORT9_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 -+ -+#define RTL8367C_REG_PORT9_FORCE_RATE0 0x0131 -+ -+#define RTL8367C_REG_PORT9_FORCE_RATE1 0x0132 -+ -+#define RTL8367C_REG_PORT9_CURENT_RATE0 0x0133 -+ -+#define RTL8367C_REG_PORT9_CURENT_RATE1 0x0134 -+ -+#define RTL8367C_REG_PORT9_PAGE_COUNTER 0x0135 -+#define RTL8367C_PORT9_PAGE_COUNTER_OFFSET 0 -+#define RTL8367C_PORT9_PAGE_COUNTER_MASK 0x7F -+ -+#define RTL8367C_REG_PAGEMETER_PORT9_CTRL0 0x0136 -+ -+#define RTL8367C_REG_PAGEMETER_PORT9_CTRL1 0x0137 -+ -+#define RTL8367C_REG_PORT9_EEECFG 0x0138 -+#define RTL8367C_PORT9_EEECFG_EEEP_ENABLE_TX_OFFSET 14 -+#define RTL8367C_PORT9_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 -+#define RTL8367C_PORT9_EEECFG_EEEP_ENABLE_RX_OFFSET 13 -+#define RTL8367C_PORT9_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 -+#define RTL8367C_PORT9_EEECFG_EEE_FORCE_OFFSET 12 -+#define RTL8367C_PORT9_EEECFG_EEE_FORCE_MASK 0x1000 -+#define RTL8367C_PORT9_EEECFG_EEE_100M_OFFSET 11 -+#define RTL8367C_PORT9_EEECFG_EEE_100M_MASK 0x800 -+#define RTL8367C_PORT9_EEECFG_EEE_GIGA_500M_OFFSET 10 -+#define RTL8367C_PORT9_EEECFG_EEE_GIGA_500M_MASK 0x400 -+#define RTL8367C_PORT9_EEECFG_EEE_TX_OFFSET 9 -+#define RTL8367C_PORT9_EEECFG_EEE_TX_MASK 0x200 -+#define RTL8367C_PORT9_EEECFG_EEE_RX_OFFSET 8 -+#define RTL8367C_PORT9_EEECFG_EEE_RX_MASK 0x100 -+#define RTL8367C_PORT9_EEECFG_EEE_DSP_RX_OFFSET 6 -+#define RTL8367C_PORT9_EEECFG_EEE_DSP_RX_MASK 0x40 -+#define RTL8367C_PORT9_EEECFG_EEE_LPI_OFFSET 5 -+#define RTL8367C_PORT9_EEECFG_EEE_LPI_MASK 0x20 -+#define RTL8367C_PORT9_EEECFG_EEE_TX_LPI_OFFSET 4 -+#define RTL8367C_PORT9_EEECFG_EEE_TX_LPI_MASK 0x10 -+#define RTL8367C_PORT9_EEECFG_EEE_RX_LPI_OFFSET 3 -+#define RTL8367C_PORT9_EEECFG_EEE_RX_LPI_MASK 0x8 -+#define RTL8367C_PORT9_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 -+#define RTL8367C_PORT9_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 -+#define RTL8367C_PORT9_EEECFG_EEE_WAKE_REQ_OFFSET 1 -+#define RTL8367C_PORT9_EEECFG_EEE_WAKE_REQ_MASK 0x2 -+#define RTL8367C_PORT9_EEECFG_EEE_SLEEP_REQ_OFFSET 0 -+#define RTL8367C_PORT9_EEECFG_EEE_SLEEP_REQ_MASK 0x1 -+ -+#define RTL8367C_REG_PORT9_EEETXMTR 0x0139 -+ -+#define RTL8367C_REG_PORT9_EEERXMTR 0x013a -+ -+#define RTL8367C_REG_PORT9_EEEPTXMTR 0x013b -+ -+#define RTL8367C_REG_PORT9_EEEPRXMTR 0x013c -+ -+#define RTL8367C_REG_PTP_PORT9_CFG1 0x013e -+#define RTL8367C_PTP_PORT9_CFG1_OFFSET 7 -+#define RTL8367C_PTP_PORT9_CFG1_MASK 0xFF -+ -+#define RTL8367C_REG_P9_MSIC1 0x013f -+#define RTL8367C_P9_MSIC1_OFFSET 0 -+#define RTL8367C_P9_MSIC1_MASK 0x1 -+ -+#define RTL8367C_REG_PORT10_CGST_HALF_CFG 0x0140 -+#define RTL8367C_PORT10_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 -+#define RTL8367C_PORT10_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 -+#define RTL8367C_PORT10_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 -+#define RTL8367C_PORT10_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF -+ -+#define RTL8367C_REG_PKTGEN_PORT10_CTRL 0x0141 -+#define RTL8367C_PKTGEN_PORT10_CTRL_STATUS_OFFSET 15 -+#define RTL8367C_PKTGEN_PORT10_CTRL_STATUS_MASK 0x8000 -+#define RTL8367C_PKTGEN_PORT10_CTRL_PKTGEN_STS_OFFSET 13 -+#define RTL8367C_PKTGEN_PORT10_CTRL_PKTGEN_STS_MASK 0x2000 -+#define RTL8367C_PKTGEN_PORT10_CTRL_CRC_NO_ERROR_OFFSET 4 -+#define RTL8367C_PKTGEN_PORT10_CTRL_CRC_NO_ERROR_MASK 0x10 -+#define RTL8367C_PKTGEN_PORT10_CTRL_CMD_START_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT10_CTRL_CMD_START_MASK 0x1 -+ -+#define RTL8367C_REG_TX_ERR_CNT_PORT10 0x0142 -+#define RTL8367C_TX_ERR_CNT_PORT10_OFFSET 0 -+#define RTL8367C_TX_ERR_CNT_PORT10_MASK 0x7 -+ -+#define RTL8367C_REG_PKTGEN_PORT10_DA0 0x0143 -+ -+#define RTL8367C_REG_PKTGEN_PORT10_DA1 0x0144 -+ -+#define RTL8367C_REG_PKTGEN_PORT10_DA2 0x0145 -+ -+#define RTL8367C_REG_PKTGEN_PORT10_SA0 0x0146 -+ -+#define RTL8367C_REG_PKTGEN_PORT10_SA1 0x0147 -+ -+#define RTL8367C_REG_PKTGEN_PORT10_SA2 0x0148 -+ -+#define RTL8367C_REG_PKTGEN_PORT10_COUNTER0 0x0149 -+ -+#define RTL8367C_REG_PKTGEN_PORT10_COUNTER1 0x014a -+#define RTL8367C_PKTGEN_PORT10_COUNTER1_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT10_COUNTER1_MASK 0xFF -+ -+#define RTL8367C_REG_PKTGEN_PORT10_TX_LENGTH 0x014b -+#define RTL8367C_PKTGEN_PORT10_TX_LENGTH_OFFSET 0 -+#define RTL8367C_PKTGEN_PORT10_TX_LENGTH_MASK 0x3FFF -+ -+#define RTL8367C_REG_PKTGEN_PORT10_TIMER 0x014d -+#define RTL8367C_PKTGEN_PORT10_TIMER_TIMER_OFFSET 4 -+#define RTL8367C_PKTGEN_PORT10_TIMER_TIMER_MASK 0xF0 -+#define RTL8367C_PKTGEN_PORT10_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 -+#define RTL8367C_PKTGEN_PORT10_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 -+ -+#define RTL8367C_REG_PORT10_MISC_CFG 0x014e -+#define RTL8367C_PORT10_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 -+#define RTL8367C_PORT10_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 -+#define RTL8367C_PORT10_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 -+#define RTL8367C_PORT10_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 -+#define RTL8367C_PORT10_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 -+#define RTL8367C_PORT10_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 -+#define RTL8367C_PORT10_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 -+#define RTL8367C_PORT10_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 -+#define RTL8367C_PORT10_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 -+#define RTL8367C_PORT10_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 -+#define RTL8367C_PORT10_MISC_CFG_INGRESSBW_IFG_OFFSET 10 -+#define RTL8367C_PORT10_MISC_CFG_INGRESSBW_IFG_MASK 0x400 -+#define RTL8367C_PORT10_MISC_CFG_RX_SPC_OFFSET 9 -+#define RTL8367C_PORT10_MISC_CFG_RX_SPC_MASK 0x200 -+#define RTL8367C_PORT10_MISC_CFG_CRC_SKIP_OFFSET 8 -+#define RTL8367C_PORT10_MISC_CFG_CRC_SKIP_MASK 0x100 -+#define RTL8367C_PORT10_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 -+#define RTL8367C_PORT10_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 -+#define RTL8367C_PORT10_MISC_CFG_MAC_LOOPBACK_OFFSET 6 -+#define RTL8367C_PORT10_MISC_CFG_MAC_LOOPBACK_MASK 0x40 -+#define RTL8367C_PORT10_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 -+#define RTL8367C_PORT10_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 -+#define RTL8367C_PORT10_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 -+#define RTL8367C_PORT10_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF -+ -+#define RTL8367C_REG_INGRESSBW_PORT10_RATE_CTRL0 0x014f -+ -+#define RTL8367C_REG_INGRESSBW_PORT10_RATE_CTRL1 0x0150 -+#define RTL8367C_INGRESSBW_PORT10_RATE_CTRL1_DUMMY_OFFSET 3 -+#define RTL8367C_INGRESSBW_PORT10_RATE_CTRL1_DUMMY_MASK 0xFFF8 -+#define RTL8367C_INGRESSBW_PORT10_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 -+#define RTL8367C_INGRESSBW_PORT10_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 -+ -+#define RTL8367C_REG_PORT10_FORCE_RATE0 0x0151 -+ -+#define RTL8367C_REG_PORT10_FORCE_RATE1 0x0152 -+ -+#define RTL8367C_REG_PORT10_CURENT_RATE0 0x0153 -+ -+#define RTL8367C_REG_PORT10_CURENT_RATE1 0x0154 -+ -+#define RTL8367C_REG_PORT10_PAGE_COUNTER 0x0155 -+#define RTL8367C_PORT10_PAGE_COUNTER_OFFSET 0 -+#define RTL8367C_PORT10_PAGE_COUNTER_MASK 0x7F -+ -+#define RTL8367C_REG_PAGEMETER_PORT10_CTRL0 0x0156 -+ -+#define RTL8367C_REG_PAGEMETER_PORT10_CTRL1 0x0157 -+ -+#define RTL8367C_REG_PORT10_EEECFG 0x0158 -+#define RTL8367C_PORT10_EEECFG_EEEP_ENABLE_TX_OFFSET 14 -+#define RTL8367C_PORT10_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 -+#define RTL8367C_PORT10_EEECFG_EEEP_ENABLE_RX_OFFSET 13 -+#define RTL8367C_PORT10_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 -+#define RTL8367C_PORT10_EEECFG_EEE_FORCE_OFFSET 12 -+#define RTL8367C_PORT10_EEECFG_EEE_FORCE_MASK 0x1000 -+#define RTL8367C_PORT10_EEECFG_EEE_100M_OFFSET 11 -+#define RTL8367C_PORT10_EEECFG_EEE_100M_MASK 0x800 -+#define RTL8367C_PORT10_EEECFG_EEE_GIGA_500M_OFFSET 10 -+#define RTL8367C_PORT10_EEECFG_EEE_GIGA_500M_MASK 0x400 -+#define RTL8367C_PORT10_EEECFG_EEE_TX_OFFSET 9 -+#define RTL8367C_PORT10_EEECFG_EEE_TX_MASK 0x200 -+#define RTL8367C_PORT10_EEECFG_EEE_RX_OFFSET 8 -+#define RTL8367C_PORT10_EEECFG_EEE_RX_MASK 0x100 -+#define RTL8367C_PORT10_EEECFG_EEE_DSP_RX_OFFSET 6 -+#define RTL8367C_PORT10_EEECFG_EEE_DSP_RX_MASK 0x40 -+#define RTL8367C_PORT10_EEECFG_EEE_LPI_OFFSET 5 -+#define RTL8367C_PORT10_EEECFG_EEE_LPI_MASK 0x20 -+#define RTL8367C_PORT10_EEECFG_EEE_TX_LPI_OFFSET 4 -+#define RTL8367C_PORT10_EEECFG_EEE_TX_LPI_MASK 0x10 -+#define RTL8367C_PORT10_EEECFG_EEE_RX_LPI_OFFSET 3 -+#define RTL8367C_PORT10_EEECFG_EEE_RX_LPI_MASK 0x8 -+#define RTL8367C_PORT10_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 -+#define RTL8367C_PORT10_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 -+#define RTL8367C_PORT10_EEECFG_EEE_WAKE_REQ_OFFSET 1 -+#define RTL8367C_PORT10_EEECFG_EEE_WAKE_REQ_MASK 0x2 -+#define RTL8367C_PORT10_EEECFG_EEE_SLEEP_REQ_OFFSET 0 -+#define RTL8367C_PORT10_EEECFG_EEE_SLEEP_REQ_MASK 0x1 -+ -+#define RTL8367C_REG_PORT10_EEETXMTR 0x0159 -+ -+#define RTL8367C_REG_PORT10_EEERXMTR 0x015a -+ -+#define RTL8367C_REG_PORT10_EEEPTXMTR 0x015b -+ -+#define RTL8367C_REG_PORT10_EEEPRXMTR 0x015c -+ -+#define RTL8367C_REG_PTP_PORT10_CFG1 0x015e -+#define RTL8367C_PTP_PORT10_CFG1_OFFSET 7 -+#define RTL8367C_PTP_PORT10_CFG1_MASK 0xFF -+ -+#define RTL8367C_REG_P10_MSIC1 0x015f -+#define RTL8367C_P10_MSIC1_OFFSET 0 -+#define RTL8367C_P10_MSIC1_MASK 0x1 -+ -+/* (16'h0200)outq_reg */ -+ -+#define RTL8367C_REG_FLOWCTRL_QUEUE0_DROP_ON 0x0200 -+#define RTL8367C_FLOWCTRL_QUEUE0_DROP_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_QUEUE0_DROP_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_QUEUE1_DROP_ON 0x0201 -+#define RTL8367C_FLOWCTRL_QUEUE1_DROP_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_QUEUE1_DROP_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_QUEUE2_DROP_ON 0x0202 -+#define RTL8367C_FLOWCTRL_QUEUE2_DROP_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_QUEUE2_DROP_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_QUEUE3_DROP_ON 0x0203 -+#define RTL8367C_FLOWCTRL_QUEUE3_DROP_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_QUEUE3_DROP_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_QUEUE4_DROP_ON 0x0204 -+#define RTL8367C_FLOWCTRL_QUEUE4_DROP_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_QUEUE4_DROP_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_QUEUE5_DROP_ON 0x0205 -+#define RTL8367C_FLOWCTRL_QUEUE5_DROP_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_QUEUE5_DROP_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_QUEUE6_DROP_ON 0x0206 -+#define RTL8367C_FLOWCTRL_QUEUE6_DROP_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_QUEUE6_DROP_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_QUEUE7_DROP_ON 0x0207 -+#define RTL8367C_FLOWCTRL_QUEUE7_DROP_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_QUEUE7_DROP_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT0_DROP_ON 0x0208 -+#define RTL8367C_FLOWCTRL_PORT0_DROP_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT0_DROP_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT1_DROP_ON 0x0209 -+#define RTL8367C_FLOWCTRL_PORT1_DROP_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT1_DROP_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT2_DROP_ON 0x020a -+#define RTL8367C_FLOWCTRL_PORT2_DROP_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT2_DROP_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT3_DROP_ON 0x020b -+#define RTL8367C_FLOWCTRL_PORT3_DROP_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT3_DROP_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT4_DROP_ON 0x020c -+#define RTL8367C_FLOWCTRL_PORT4_DROP_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT4_DROP_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT5_DROP_ON 0x020d -+#define RTL8367C_FLOWCTRL_PORT5_DROP_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT5_DROP_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT6_DROP_ON 0x020e -+#define RTL8367C_FLOWCTRL_PORT6_DROP_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT6_DROP_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT7_DROP_ON 0x020f -+#define RTL8367C_FLOWCTRL_PORT7_DROP_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT7_DROP_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT8_DROP_ON 0x0210 -+#define RTL8367C_FLOWCTRL_PORT8_DROP_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT8_DROP_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT9_DROP_ON 0x0211 -+#define RTL8367C_FLOWCTRL_PORT9_DROP_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT9_DROP_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT10_DROP_ON 0x0212 -+#define RTL8367C_FLOWCTRL_PORT10_DROP_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT10_DROP_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT_GAP 0x0218 -+#define RTL8367C_FLOWCTRL_PORT_GAP_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT_GAP_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_QUEUE_GAP 0x0219 -+#define RTL8367C_FLOWCTRL_QUEUE_GAP_OFFSET 0 -+#define RTL8367C_FLOWCTRL_QUEUE_GAP_MASK 0x7FF -+ -+#define RTL8367C_REG_PORT_QEMPTY 0x022d -+#define RTL8367C_PORT_QEMPTY_OFFSET 0 -+#define RTL8367C_PORT_QEMPTY_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_DEBUG_CTRL0 0x022e -+#define RTL8367C_FLOWCTRL_DEBUG_CTRL0_OFFSET 0 -+#define RTL8367C_FLOWCTRL_DEBUG_CTRL0_MASK 0xF -+ -+#define RTL8367C_REG_FLOWCTRL_DEBUG_CTRL1 0x022f -+#define RTL8367C_TOTAL_OFFSET 9 -+#define RTL8367C_TOTAL_MASK 0x200 -+#define RTL8367C_PORT_MAX_OFFSET 8 -+#define RTL8367C_PORT_MAX_MASK 0x100 -+#define RTL8367C_QMAX_MASK_OFFSET 0 -+#define RTL8367C_QMAX_MASK_MASK 0xFF -+ -+#define RTL8367C_REG_FLOWCTRL_QUEUE0_PAGE_COUNT 0x0230 -+#define RTL8367C_FLOWCTRL_QUEUE0_PAGE_COUNT_OFFSET 0 -+#define RTL8367C_FLOWCTRL_QUEUE0_PAGE_COUNT_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_QUEUE1_PAGE_COUNT 0x0231 -+#define RTL8367C_FLOWCTRL_QUEUE1_PAGE_COUNT_OFFSET 0 -+#define RTL8367C_FLOWCTRL_QUEUE1_PAGE_COUNT_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_QUEUE2_PAGE_COUNT 0x0232 -+#define RTL8367C_FLOWCTRL_QUEUE2_PAGE_COUNT_OFFSET 0 -+#define RTL8367C_FLOWCTRL_QUEUE2_PAGE_COUNT_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_QUEUE3_PAGE_COUNT 0x0233 -+#define RTL8367C_FLOWCTRL_QUEUE3_PAGE_COUNT_OFFSET 0 -+#define RTL8367C_FLOWCTRL_QUEUE3_PAGE_COUNT_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_QUEUE4_PAGE_COUNT 0x0234 -+#define RTL8367C_FLOWCTRL_QUEUE4_PAGE_COUNT_OFFSET 0 -+#define RTL8367C_FLOWCTRL_QUEUE4_PAGE_COUNT_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_QUEUE5_PAGE_COUNT 0x0235 -+#define RTL8367C_FLOWCTRL_QUEUE5_PAGE_COUNT_OFFSET 0 -+#define RTL8367C_FLOWCTRL_QUEUE5_PAGE_COUNT_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_QUEUE6_PAGE_COUNT 0x0236 -+#define RTL8367C_FLOWCTRL_QUEUE6_PAGE_COUNT_OFFSET 0 -+#define RTL8367C_FLOWCTRL_QUEUE6_PAGE_COUNT_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_QUEUE7_PAGE_COUNT 0x0237 -+#define RTL8367C_FLOWCTRL_QUEUE7_PAGE_COUNT_OFFSET 0 -+#define RTL8367C_FLOWCTRL_QUEUE7_PAGE_COUNT_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT_PAGE_COUNT 0x0238 -+#define RTL8367C_FLOWCTRL_PORT_PAGE_COUNT_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT_PAGE_COUNT_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_QUEUE0_MAX_PAGE_COUNT 0x0239 -+#define RTL8367C_FLOWCTRL_QUEUE0_MAX_PAGE_COUNT_OFFSET 0 -+#define RTL8367C_FLOWCTRL_QUEUE0_MAX_PAGE_COUNT_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_QUEUE1_MAX_PAGE_COUNT 0x023a -+#define RTL8367C_FLOWCTRL_QUEUE1_MAX_PAGE_COUNT_OFFSET 0 -+#define RTL8367C_FLOWCTRL_QUEUE1_MAX_PAGE_COUNT_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_QUEUE2_MAX_PAGE_COUNT 0x023b -+#define RTL8367C_FLOWCTRL_QUEUE2_MAX_PAGE_COUNT_OFFSET 0 -+#define RTL8367C_FLOWCTRL_QUEUE2_MAX_PAGE_COUNT_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_QUEUE3_MAX_PAGE_COUNT 0x023c -+#define RTL8367C_FLOWCTRL_QUEUE3_MAX_PAGE_COUNT_OFFSET 0 -+#define RTL8367C_FLOWCTRL_QUEUE3_MAX_PAGE_COUNT_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_QUEUE4_MAX_PAGE_COUNT 0x023d -+#define RTL8367C_FLOWCTRL_QUEUE4_MAX_PAGE_COUNT_OFFSET 0 -+#define RTL8367C_FLOWCTRL_QUEUE4_MAX_PAGE_COUNT_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_QUEUE5_MAX_PAGE_COUNT 0x023e -+#define RTL8367C_FLOWCTRL_QUEUE5_MAX_PAGE_COUNT_OFFSET 0 -+#define RTL8367C_FLOWCTRL_QUEUE5_MAX_PAGE_COUNT_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_QUEUE6_MAX_PAGE_COUNT 0x023f -+#define RTL8367C_FLOWCTRL_QUEUE6_MAX_PAGE_COUNT_OFFSET 0 -+#define RTL8367C_FLOWCTRL_QUEUE6_MAX_PAGE_COUNT_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_QUEUE7_MAX_PAGE_COUNT 0x0240 -+#define RTL8367C_FLOWCTRL_QUEUE7_MAX_PAGE_COUNT_OFFSET 0 -+#define RTL8367C_FLOWCTRL_QUEUE7_MAX_PAGE_COUNT_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT_MAX_PAGE_COUNT 0x0241 -+#define RTL8367C_FLOWCTRL_PORT_MAX_PAGE_COUNT_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT_MAX_PAGE_COUNT_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_TOTAL_PACKET_COUNT 0x0243 -+ -+#define RTL8367C_REG_HIGH_QUEUE_MASK0 0x0244 -+#define RTL8367C_PORT1_HIGH_QUEUE_MASK_OFFSET 8 -+#define RTL8367C_PORT1_HIGH_QUEUE_MASK_MASK 0xFF00 -+#define RTL8367C_PORT0_HIGH_QUEUE_MASK_OFFSET 0 -+#define RTL8367C_PORT0_HIGH_QUEUE_MASK_MASK 0xFF -+ -+#define RTL8367C_REG_HIGH_QUEUE_MASK1 0x0245 -+#define RTL8367C_PORT3_HIGH_QUEUE_MASK_OFFSET 8 -+#define RTL8367C_PORT3_HIGH_QUEUE_MASK_MASK 0xFF00 -+#define RTL8367C_PORT2_HIGH_QUEUE_MASK_OFFSET 0 -+#define RTL8367C_PORT2_HIGH_QUEUE_MASK_MASK 0xFF -+ -+#define RTL8367C_REG_HIGH_QUEUE_MASK2 0x0246 -+#define RTL8367C_PORT5_HIGH_QUEUE_MASK_OFFSET 8 -+#define RTL8367C_PORT5_HIGH_QUEUE_MASK_MASK 0xFF00 -+#define RTL8367C_PORT4_HIGH_QUEUE_MASK_OFFSET 0 -+#define RTL8367C_PORT4_HIGH_QUEUE_MASK_MASK 0xFF -+ -+#define RTL8367C_REG_HIGH_QUEUE_MASK3 0x0247 -+#define RTL8367C_PORT7_HIGH_QUEUE_MASK_OFFSET 8 -+#define RTL8367C_PORT7_HIGH_QUEUE_MASK_MASK 0xFF00 -+#define RTL8367C_PORT6_HIGH_QUEUE_MASK_OFFSET 0 -+#define RTL8367C_PORT6_HIGH_QUEUE_MASK_MASK 0xFF -+ -+#define RTL8367C_REG_HIGH_QUEUE_MASK4 0x0248 -+#define RTL8367C_PORT9_HIGH_QUEUE_MASK_OFFSET 8 -+#define RTL8367C_PORT9_HIGH_QUEUE_MASK_MASK 0xFF00 -+#define RTL8367C_PORT8_HIGH_QUEUE_MASK_OFFSET 0 -+#define RTL8367C_PORT8_HIGH_QUEUE_MASK_MASK 0xFF -+ -+#define RTL8367C_REG_HIGH_QUEUE_MASK5 0x0249 -+#define RTL8367C_HIGH_QUEUE_MASK5_OFFSET 0 -+#define RTL8367C_HIGH_QUEUE_MASK5_MASK 0xFF -+ -+#define RTL8367C_REG_LOW_QUEUE_TH 0x024c -+#define RTL8367C_LOW_QUEUE_TH_OFFSET 0 -+#define RTL8367C_LOW_QUEUE_TH_MASK 0x7FF -+ -+#define RTL8367C_REG_TH_TX_PREFET 0x0250 -+#define RTL8367C_TH_TX_PREFET_OFFSET 0 -+#define RTL8367C_TH_TX_PREFET_MASK 0xFF -+ -+#define RTL8367C_REG_DUMMY_0251 0x0251 -+ -+#define RTL8367C_REG_DUMMY_0252 0x0252 -+ -+#define RTL8367C_REG_DUMMY_0253 0x0253 -+ -+#define RTL8367C_REG_DUMMY_0254 0x0254 -+ -+#define RTL8367C_REG_DUMMY_0255 0x0255 -+ -+#define RTL8367C_REG_DUMMY_0256 0x0256 -+ -+#define RTL8367C_REG_DUMMY_0257 0x0257 -+ -+#define RTL8367C_REG_DUMMY_0258 0x0258 -+ -+#define RTL8367C_REG_DUMMY_0259 0x0259 -+ -+#define RTL8367C_REG_DUMMY_025A 0x025A -+ -+#define RTL8367C_REG_DUMMY_025B 0x025B -+ -+#define RTL8367C_REG_DUMMY_025C 0x025C -+ -+#define RTL8367C_REG_Q_TXPKT_CNT_CTL 0x025d -+#define RTL8367C_QUEUE_PKT_CNT_CLR_OFFSET 4 -+#define RTL8367C_QUEUE_PKT_CNT_CLR_MASK 0x10 -+#define RTL8367C_PORT_ID_QUEUE_PKT_CNT_OFFSET 0 -+#define RTL8367C_PORT_ID_QUEUE_PKT_CNT_MASK 0xF -+ -+#define RTL8367C_REG_Q0_TXPKT_CNT_L 0x025e -+ -+#define RTL8367C_REG_Q0_TXPKT_CNT_H 0x025f -+ -+#define RTL8367C_REG_Q1_TXPKT_CNT_L 0x0260 -+ -+#define RTL8367C_REG_Q1_TXPKT_CNT_H 0x0261 -+ -+#define RTL8367C_REG_Q2_TXPKT_CNT_L 0x0262 -+ -+#define RTL8367C_REG_Q2_TXPKT_CNT_H 0x0263 -+ -+#define RTL8367C_REG_Q3_TXPKT_CNT_L 0x0264 -+ -+#define RTL8367C_REG_Q3_TXPKT_CNT_H 0x0265 -+ -+#define RTL8367C_REG_Q4_TXPKT_CNT_L 0x0266 -+ -+#define RTL8367C_REG_Q4_TXPKT_CNT_H 0x0267 -+ -+#define RTL8367C_REG_Q5_TXPKT_CNT_L 0x0268 -+ -+#define RTL8367C_REG_Q5_TXPKT_CNT_H 0x0269 -+ -+#define RTL8367C_REG_Q6_TXPKT_CNT_L 0x026a -+ -+#define RTL8367C_REG_Q6_TXPKT_CNT_H 0x026b -+ -+#define RTL8367C_REG_Q7_TXPKT_CNT_L 0x026c -+ -+#define RTL8367C_REG_Q7_TXPKT_CNT_H 0x026d -+ -+/* (16'h0300)sch_reg */ -+ -+#define RTL8367C_REG_SCHEDULE_WFQ_CTRL 0x0300 -+#define RTL8367C_SCHEDULE_WFQ_CTRL_OFFSET 0 -+#define RTL8367C_SCHEDULE_WFQ_CTRL_MASK 0x1 -+ -+#define RTL8367C_REG_SCHEDULE_WFQ_BURST_SIZE 0x0301 -+ -+#define RTL8367C_REG_SCHEDULE_QUEUE_TYPE_CTRL0 0x0302 -+#define RTL8367C_PORT1_QUEUE7_TYPE_OFFSET 15 -+#define RTL8367C_PORT1_QUEUE7_TYPE_MASK 0x8000 -+#define RTL8367C_PORT1_QUEUE6_TYPE_OFFSET 14 -+#define RTL8367C_PORT1_QUEUE6_TYPE_MASK 0x4000 -+#define RTL8367C_PORT1_QUEUE5_TYPE_OFFSET 13 -+#define RTL8367C_PORT1_QUEUE5_TYPE_MASK 0x2000 -+#define RTL8367C_PORT1_QUEUE4_TYPE_OFFSET 12 -+#define RTL8367C_PORT1_QUEUE4_TYPE_MASK 0x1000 -+#define RTL8367C_PORT1_QUEUE3_TYPE_OFFSET 11 -+#define RTL8367C_PORT1_QUEUE3_TYPE_MASK 0x800 -+#define RTL8367C_PORT1_QUEUE2_TYPE_OFFSET 10 -+#define RTL8367C_PORT1_QUEUE2_TYPE_MASK 0x400 -+#define RTL8367C_PORT1_QUEUE1_TYPE_OFFSET 9 -+#define RTL8367C_PORT1_QUEUE1_TYPE_MASK 0x200 -+#define RTL8367C_PORT1_QUEUE0_TYPE_OFFSET 8 -+#define RTL8367C_PORT1_QUEUE0_TYPE_MASK 0x100 -+#define RTL8367C_PORT0_QUEUE7_TYPE_OFFSET 7 -+#define RTL8367C_PORT0_QUEUE7_TYPE_MASK 0x80 -+#define RTL8367C_PORT0_QUEUE6_TYPE_OFFSET 6 -+#define RTL8367C_PORT0_QUEUE6_TYPE_MASK 0x40 -+#define RTL8367C_PORT0_QUEUE5_TYPE_OFFSET 5 -+#define RTL8367C_PORT0_QUEUE5_TYPE_MASK 0x20 -+#define RTL8367C_PORT0_QUEUE4_TYPE_OFFSET 4 -+#define RTL8367C_PORT0_QUEUE4_TYPE_MASK 0x10 -+#define RTL8367C_PORT0_QUEUE3_TYPE_OFFSET 3 -+#define RTL8367C_PORT0_QUEUE3_TYPE_MASK 0x8 -+#define RTL8367C_PORT0_QUEUE2_TYPE_OFFSET 2 -+#define RTL8367C_PORT0_QUEUE2_TYPE_MASK 0x4 -+#define RTL8367C_PORT0_QUEUE1_TYPE_OFFSET 1 -+#define RTL8367C_PORT0_QUEUE1_TYPE_MASK 0x2 -+#define RTL8367C_PORT0_QUEUE0_TYPE_OFFSET 0 -+#define RTL8367C_PORT0_QUEUE0_TYPE_MASK 0x1 -+ -+#define RTL8367C_REG_SCHEDULE_QUEUE_TYPE_CTRL1 0x0303 -+#define RTL8367C_PORT3_QUEUE7_TYPE_OFFSET 15 -+#define RTL8367C_PORT3_QUEUE7_TYPE_MASK 0x8000 -+#define RTL8367C_PORT3_QUEUE6_TYPE_OFFSET 14 -+#define RTL8367C_PORT3_QUEUE6_TYPE_MASK 0x4000 -+#define RTL8367C_PORT3_QUEUE5_TYPE_OFFSET 13 -+#define RTL8367C_PORT3_QUEUE5_TYPE_MASK 0x2000 -+#define RTL8367C_PORT3_QUEUE4_TYPE_OFFSET 12 -+#define RTL8367C_PORT3_QUEUE4_TYPE_MASK 0x1000 -+#define RTL8367C_PORT3_QUEUE3_TYPE_OFFSET 11 -+#define RTL8367C_PORT3_QUEUE3_TYPE_MASK 0x800 -+#define RTL8367C_PORT3_QUEUE2_TYPE_OFFSET 10 -+#define RTL8367C_PORT3_QUEUE2_TYPE_MASK 0x400 -+#define RTL8367C_PORT3_QUEUE1_TYPE_OFFSET 9 -+#define RTL8367C_PORT3_QUEUE1_TYPE_MASK 0x200 -+#define RTL8367C_PORT3_QUEUE0_TYPE_OFFSET 8 -+#define RTL8367C_PORT3_QUEUE0_TYPE_MASK 0x100 -+#define RTL8367C_PORT2_QUEUE7_TYPE_OFFSET 7 -+#define RTL8367C_PORT2_QUEUE7_TYPE_MASK 0x80 -+#define RTL8367C_PORT2_QUEUE6_TYPE_OFFSET 6 -+#define RTL8367C_PORT2_QUEUE6_TYPE_MASK 0x40 -+#define RTL8367C_PORT2_QUEUE5_TYPE_OFFSET 5 -+#define RTL8367C_PORT2_QUEUE5_TYPE_MASK 0x20 -+#define RTL8367C_PORT2_QUEUE4_TYPE_OFFSET 4 -+#define RTL8367C_PORT2_QUEUE4_TYPE_MASK 0x10 -+#define RTL8367C_PORT2_QUEUE3_TYPE_OFFSET 3 -+#define RTL8367C_PORT2_QUEUE3_TYPE_MASK 0x8 -+#define RTL8367C_PORT2_QUEUE2_TYPE_OFFSET 2 -+#define RTL8367C_PORT2_QUEUE2_TYPE_MASK 0x4 -+#define RTL8367C_PORT2_QUEUE1_TYPE_OFFSET 1 -+#define RTL8367C_PORT2_QUEUE1_TYPE_MASK 0x2 -+#define RTL8367C_PORT2_QUEUE0_TYPE_OFFSET 0 -+#define RTL8367C_PORT2_QUEUE0_TYPE_MASK 0x1 -+ -+#define RTL8367C_REG_SCHEDULE_QUEUE_TYPE_CTRL2 0x0304 -+#define RTL8367C_PORT5_QUEUE7_TYPE_OFFSET 15 -+#define RTL8367C_PORT5_QUEUE7_TYPE_MASK 0x8000 -+#define RTL8367C_PORT5_QUEUE6_TYPE_OFFSET 14 -+#define RTL8367C_PORT5_QUEUE6_TYPE_MASK 0x4000 -+#define RTL8367C_PORT5_QUEUE5_TYPE_OFFSET 13 -+#define RTL8367C_PORT5_QUEUE5_TYPE_MASK 0x2000 -+#define RTL8367C_PORT5_QUEUE4_TYPE_OFFSET 12 -+#define RTL8367C_PORT5_QUEUE4_TYPE_MASK 0x1000 -+#define RTL8367C_PORT5_QUEUE3_TYPE_OFFSET 11 -+#define RTL8367C_PORT5_QUEUE3_TYPE_MASK 0x800 -+#define RTL8367C_PORT5_QUEUE2_TYPE_OFFSET 10 -+#define RTL8367C_PORT5_QUEUE2_TYPE_MASK 0x400 -+#define RTL8367C_PORT5_QUEUE1_TYPE_OFFSET 9 -+#define RTL8367C_PORT5_QUEUE1_TYPE_MASK 0x200 -+#define RTL8367C_PORT5_QUEUE0_TYPE_OFFSET 8 -+#define RTL8367C_PORT5_QUEUE0_TYPE_MASK 0x100 -+#define RTL8367C_PORT4_QUEUE7_TYPE_OFFSET 7 -+#define RTL8367C_PORT4_QUEUE7_TYPE_MASK 0x80 -+#define RTL8367C_PORT4_QUEUE6_TYPE_OFFSET 6 -+#define RTL8367C_PORT4_QUEUE6_TYPE_MASK 0x40 -+#define RTL8367C_PORT4_QUEUE5_TYPE_OFFSET 5 -+#define RTL8367C_PORT4_QUEUE5_TYPE_MASK 0x20 -+#define RTL8367C_PORT4_QUEUE4_TYPE_OFFSET 4 -+#define RTL8367C_PORT4_QUEUE4_TYPE_MASK 0x10 -+#define RTL8367C_PORT4_QUEUE3_TYPE_OFFSET 3 -+#define RTL8367C_PORT4_QUEUE3_TYPE_MASK 0x8 -+#define RTL8367C_PORT4_QUEUE2_TYPE_OFFSET 2 -+#define RTL8367C_PORT4_QUEUE2_TYPE_MASK 0x4 -+#define RTL8367C_PORT4_QUEUE1_TYPE_OFFSET 1 -+#define RTL8367C_PORT4_QUEUE1_TYPE_MASK 0x2 -+#define RTL8367C_PORT4_QUEUE0_TYPE_OFFSET 0 -+#define RTL8367C_PORT4_QUEUE0_TYPE_MASK 0x1 -+ -+#define RTL8367C_REG_SCHEDULE_QUEUE_TYPE_CTRL3 0x0305 -+#define RTL8367C_PORT7_QUEUE7_TYPE_OFFSET 15 -+#define RTL8367C_PORT7_QUEUE7_TYPE_MASK 0x8000 -+#define RTL8367C_PORT7_QUEUE6_TYPE_OFFSET 14 -+#define RTL8367C_PORT7_QUEUE6_TYPE_MASK 0x4000 -+#define RTL8367C_PORT7_QUEUE5_TYPE_OFFSET 13 -+#define RTL8367C_PORT7_QUEUE5_TYPE_MASK 0x2000 -+#define RTL8367C_PORT7_QUEUE4_TYPE_OFFSET 12 -+#define RTL8367C_PORT7_QUEUE4_TYPE_MASK 0x1000 -+#define RTL8367C_PORT7_QUEUE3_TYPE_OFFSET 11 -+#define RTL8367C_PORT7_QUEUE3_TYPE_MASK 0x800 -+#define RTL8367C_PORT7_QUEUE2_TYPE_OFFSET 10 -+#define RTL8367C_PORT7_QUEUE2_TYPE_MASK 0x400 -+#define RTL8367C_PORT7_QUEUE1_TYPE_OFFSET 9 -+#define RTL8367C_PORT7_QUEUE1_TYPE_MASK 0x200 -+#define RTL8367C_PORT7_QUEUE0_TYPE_OFFSET 8 -+#define RTL8367C_PORT7_QUEUE0_TYPE_MASK 0x100 -+#define RTL8367C_PORT6_QUEUE7_TYPE_OFFSET 7 -+#define RTL8367C_PORT6_QUEUE7_TYPE_MASK 0x80 -+#define RTL8367C_PORT6_QUEUE6_TYPE_OFFSET 6 -+#define RTL8367C_PORT6_QUEUE6_TYPE_MASK 0x40 -+#define RTL8367C_PORT6_QUEUE5_TYPE_OFFSET 5 -+#define RTL8367C_PORT6_QUEUE5_TYPE_MASK 0x20 -+#define RTL8367C_PORT6_QUEUE4_TYPE_OFFSET 4 -+#define RTL8367C_PORT6_QUEUE4_TYPE_MASK 0x10 -+#define RTL8367C_PORT6_QUEUE3_TYPE_OFFSET 3 -+#define RTL8367C_PORT6_QUEUE3_TYPE_MASK 0x8 -+#define RTL8367C_PORT6_QUEUE2_TYPE_OFFSET 2 -+#define RTL8367C_PORT6_QUEUE2_TYPE_MASK 0x4 -+#define RTL8367C_PORT6_QUEUE1_TYPE_OFFSET 1 -+#define RTL8367C_PORT6_QUEUE1_TYPE_MASK 0x2 -+#define RTL8367C_SCHEDULE_QUEUE_TYPE_CTRL3_PORT6_QUEUE0_TYPE_OFFSET 0 -+#define RTL8367C_SCHEDULE_QUEUE_TYPE_CTRL3_PORT6_QUEUE0_TYPE_MASK 0x1 -+ -+#define RTL8367C_REG_SCHEDULE_QUEUE_TYPE_CTRL4 0x0306 -+#define RTL8367C_PORT9_QUEUE7_TYPE_OFFSET 15 -+#define RTL8367C_PORT9_QUEUE7_TYPE_MASK 0x8000 -+#define RTL8367C_PORT9_QUEUE6_TYPE_OFFSET 14 -+#define RTL8367C_PORT9_QUEUE6_TYPE_MASK 0x4000 -+#define RTL8367C_PORT9_QUEUE5_TYPE_OFFSET 13 -+#define RTL8367C_PORT9_QUEUE5_TYPE_MASK 0x2000 -+#define RTL8367C_PORT9_QUEUE4_TYPE_OFFSET 12 -+#define RTL8367C_PORT9_QUEUE4_TYPE_MASK 0x1000 -+#define RTL8367C_PORT9_QUEUE3_TYPE_OFFSET 11 -+#define RTL8367C_PORT9_QUEUE3_TYPE_MASK 0x800 -+#define RTL8367C_PORT9_QUEUE2_TYPE_OFFSET 10 -+#define RTL8367C_PORT9_QUEUE2_TYPE_MASK 0x400 -+#define RTL8367C_PORT9_QUEUE1_TYPE_OFFSET 9 -+#define RTL8367C_PORT9_QUEUE1_TYPE_MASK 0x200 -+#define RTL8367C_PORT9_QUEUE0_TYPE_OFFSET 8 -+#define RTL8367C_PORT9_QUEUE0_TYPE_MASK 0x100 -+#define RTL8367C_PORT8_QUEUE7_TYPE_OFFSET 7 -+#define RTL8367C_PORT8_QUEUE7_TYPE_MASK 0x80 -+#define RTL8367C_PORT8_QUEUE6_TYPE_OFFSET 6 -+#define RTL8367C_PORT8_QUEUE6_TYPE_MASK 0x40 -+#define RTL8367C_PORT8_QUEUE5_TYPE_OFFSET 5 -+#define RTL8367C_PORT8_QUEUE5_TYPE_MASK 0x20 -+#define RTL8367C_PORT8_QUEUE4_TYPE_OFFSET 4 -+#define RTL8367C_PORT8_QUEUE4_TYPE_MASK 0x10 -+#define RTL8367C_PORT8_QUEUE3_TYPE_OFFSET 3 -+#define RTL8367C_PORT8_QUEUE3_TYPE_MASK 0x8 -+#define RTL8367C_PORT8_QUEUE2_TYPE_OFFSET 2 -+#define RTL8367C_PORT8_QUEUE2_TYPE_MASK 0x4 -+#define RTL8367C_PORT8_QUEUE1_TYPE_OFFSET 1 -+#define RTL8367C_PORT8_QUEUE1_TYPE_MASK 0x2 -+#define RTL8367C_SCHEDULE_QUEUE_TYPE_CTRL4_PORT6_QUEUE0_TYPE_OFFSET 0 -+#define RTL8367C_SCHEDULE_QUEUE_TYPE_CTRL4_PORT6_QUEUE0_TYPE_MASK 0x1 -+ -+#define RTL8367C_REG_SCHEDULE_QUEUE_TYPE_CTRL5 0x0307 -+#define RTL8367C_PORT10_QUEUE7_TYPE_OFFSET 7 -+#define RTL8367C_PORT10_QUEUE7_TYPE_MASK 0x80 -+#define RTL8367C_PORT10_QUEUE6_TYPE_OFFSET 6 -+#define RTL8367C_PORT10_QUEUE6_TYPE_MASK 0x40 -+#define RTL8367C_PORT10_QUEUE5_TYPE_OFFSET 5 -+#define RTL8367C_PORT10_QUEUE5_TYPE_MASK 0x20 -+#define RTL8367C_PORT10_QUEUE4_TYPE_OFFSET 4 -+#define RTL8367C_PORT10_QUEUE4_TYPE_MASK 0x10 -+#define RTL8367C_PORT10_QUEUE3_TYPE_OFFSET 3 -+#define RTL8367C_PORT10_QUEUE3_TYPE_MASK 0x8 -+#define RTL8367C_PORT10_QUEUE2_TYPE_OFFSET 2 -+#define RTL8367C_PORT10_QUEUE2_TYPE_MASK 0x4 -+#define RTL8367C_PORT10_QUEUE1_TYPE_OFFSET 1 -+#define RTL8367C_PORT10_QUEUE1_TYPE_MASK 0x2 -+#define RTL8367C_PORT10_QUEUE0_TYPE_OFFSET 0 -+#define RTL8367C_PORT10_QUEUE0_TYPE_MASK 0x1 -+ -+#define RTL8367C_REG_SCHEDULE_APR_CTRL0 0x030a -+#define RTL8367C_PORT10_APR_ENABLE_OFFSET 10 -+#define RTL8367C_PORT10_APR_ENABLE_MASK 0x400 -+#define RTL8367C_PORT9_APR_ENABLE_OFFSET 9 -+#define RTL8367C_PORT9_APR_ENABLE_MASK 0x200 -+#define RTL8367C_PORT8_APR_ENABLE_OFFSET 8 -+#define RTL8367C_PORT8_APR_ENABLE_MASK 0x100 -+#define RTL8367C_PORT7_APR_ENABLE_OFFSET 7 -+#define RTL8367C_PORT7_APR_ENABLE_MASK 0x80 -+#define RTL8367C_PORT6_APR_ENABLE_OFFSET 6 -+#define RTL8367C_PORT6_APR_ENABLE_MASK 0x40 -+#define RTL8367C_PORT5_APR_ENABLE_OFFSET 5 -+#define RTL8367C_PORT5_APR_ENABLE_MASK 0x20 -+#define RTL8367C_PORT4_APR_ENABLE_OFFSET 4 -+#define RTL8367C_PORT4_APR_ENABLE_MASK 0x10 -+#define RTL8367C_PORT3_APR_ENABLE_OFFSET 3 -+#define RTL8367C_PORT3_APR_ENABLE_MASK 0x8 -+#define RTL8367C_PORT2_APR_ENABLE_OFFSET 2 -+#define RTL8367C_PORT2_APR_ENABLE_MASK 0x4 -+#define RTL8367C_PORT1_APR_ENABLE_OFFSET 1 -+#define RTL8367C_PORT1_APR_ENABLE_MASK 0x2 -+#define RTL8367C_PORT0_APR_ENABLE_OFFSET 0 -+#define RTL8367C_PORT0_APR_ENABLE_MASK 0x1 -+ -+#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE0_WFQ_WEIGHT 0x030c -+ -+#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE1_WFQ_WEIGHT 0x030d -+#define RTL8367C_SCHEDULE_PORT0_QUEUE1_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT0_QUEUE1_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE2_WFQ_WEIGHT 0x030e -+#define RTL8367C_SCHEDULE_PORT0_QUEUE2_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT0_QUEUE2_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE3_WFQ_WEIGHT 0x030f -+#define RTL8367C_SCHEDULE_PORT0_QUEUE3_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT0_QUEUE3_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE4_WFQ_WEIGHT 0x0310 -+#define RTL8367C_SCHEDULE_PORT0_QUEUE4_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT0_QUEUE4_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE5_WFQ_WEIGHT 0x0311 -+#define RTL8367C_SCHEDULE_PORT0_QUEUE5_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT0_QUEUE5_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE6_WFQ_WEIGHT 0x0312 -+#define RTL8367C_SCHEDULE_PORT0_QUEUE6_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT0_QUEUE6_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE7_WFQ_WEIGHT 0x0313 -+#define RTL8367C_SCHEDULE_PORT0_QUEUE7_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT0_QUEUE7_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE0_WFQ_WEIGHT 0x0314 -+ -+#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE1_WFQ_WEIGHT 0x0315 -+#define RTL8367C_SCHEDULE_PORT1_QUEUE1_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT1_QUEUE1_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE2_WFQ_WEIGHT 0x0316 -+#define RTL8367C_SCHEDULE_PORT1_QUEUE2_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT1_QUEUE2_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE3_WFQ_WEIGHT 0x0317 -+#define RTL8367C_SCHEDULE_PORT1_QUEUE3_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT1_QUEUE3_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE4_WFQ_WEIGHT 0x0318 -+#define RTL8367C_SCHEDULE_PORT1_QUEUE4_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT1_QUEUE4_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE5_WFQ_WEIGHT 0x0319 -+#define RTL8367C_SCHEDULE_PORT1_QUEUE5_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT1_QUEUE5_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE6_WFQ_WEIGHT 0x031a -+#define RTL8367C_SCHEDULE_PORT1_QUEUE6_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT1_QUEUE6_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE7_WFQ_WEIGHT 0x031b -+#define RTL8367C_SCHEDULE_PORT1_QUEUE7_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT1_QUEUE7_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE0_WFQ_WEIGHT 0x031c -+ -+#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE1_WFQ_WEIGHT 0x031d -+#define RTL8367C_SCHEDULE_PORT2_QUEUE1_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT2_QUEUE1_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE2_WFQ_WEIGHT 0x031e -+#define RTL8367C_SCHEDULE_PORT2_QUEUE2_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT2_QUEUE2_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE3_WFQ_WEIGHT 0x031f -+#define RTL8367C_SCHEDULE_PORT2_QUEUE3_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT2_QUEUE3_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE4_WFQ_WEIGHT 0x0320 -+#define RTL8367C_SCHEDULE_PORT2_QUEUE4_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT2_QUEUE4_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE5_WFQ_WEIGHT 0x0321 -+#define RTL8367C_SCHEDULE_PORT2_QUEUE5_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT2_QUEUE5_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE6_WFQ_WEIGHT 0x0322 -+#define RTL8367C_SCHEDULE_PORT2_QUEUE6_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT2_QUEUE6_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE7_WFQ_WEIGHT 0x0323 -+#define RTL8367C_SCHEDULE_PORT2_QUEUE7_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT2_QUEUE7_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE0_WFQ_WEIGHT 0x0324 -+ -+#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE1_WFQ_WEIGHT 0x0325 -+#define RTL8367C_SCHEDULE_PORT3_QUEUE1_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT3_QUEUE1_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE2_WFQ_WEIGHT 0x0326 -+#define RTL8367C_SCHEDULE_PORT3_QUEUE2_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT3_QUEUE2_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE3_WFQ_WEIGHT 0x0327 -+#define RTL8367C_SCHEDULE_PORT3_QUEUE3_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT3_QUEUE3_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE4_WFQ_WEIGHT 0x0328 -+#define RTL8367C_SCHEDULE_PORT3_QUEUE4_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT3_QUEUE4_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE5_WFQ_WEIGHT 0x0329 -+#define RTL8367C_SCHEDULE_PORT3_QUEUE5_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT3_QUEUE5_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE6_WFQ_WEIGHT 0x032a -+#define RTL8367C_SCHEDULE_PORT3_QUEUE6_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT3_QUEUE6_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE7_WFQ_WEIGHT 0x032b -+#define RTL8367C_SCHEDULE_PORT3_QUEUE7_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT3_QUEUE7_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE0_WFQ_WEIGHT 0x032c -+ -+#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE1_WFQ_WEIGHT 0x032d -+#define RTL8367C_SCHEDULE_PORT4_QUEUE1_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT4_QUEUE1_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE2_WFQ_WEIGHT 0x032e -+#define RTL8367C_SCHEDULE_PORT4_QUEUE2_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT4_QUEUE2_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE3_WFQ_WEIGHT 0x032f -+#define RTL8367C_SCHEDULE_PORT4_QUEUE3_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT4_QUEUE3_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE4_WFQ_WEIGHT 0x0330 -+#define RTL8367C_SCHEDULE_PORT4_QUEUE4_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT4_QUEUE4_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE5_WFQ_WEIGHT 0x0331 -+#define RTL8367C_SCHEDULE_PORT4_QUEUE5_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT4_QUEUE5_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE6_WFQ_WEIGHT 0x0332 -+#define RTL8367C_SCHEDULE_PORT4_QUEUE6_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT4_QUEUE6_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE7_WFQ_WEIGHT 0x0333 -+#define RTL8367C_SCHEDULE_PORT4_QUEUE7_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT4_QUEUE7_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE0_WFQ_WEIGHT 0x0334 -+ -+#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE1_WFQ_WEIGHT 0x0335 -+#define RTL8367C_SCHEDULE_PORT5_QUEUE1_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT5_QUEUE1_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE2_WFQ_WEIGHT 0x0336 -+#define RTL8367C_SCHEDULE_PORT5_QUEUE2_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT5_QUEUE2_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE3_WFQ_WEIGHT 0x0337 -+#define RTL8367C_SCHEDULE_PORT5_QUEUE3_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT5_QUEUE3_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE4_WFQ_WEIGHT 0x0338 -+#define RTL8367C_SCHEDULE_PORT5_QUEUE4_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT5_QUEUE4_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE5_WFQ_WEIGHT 0x0339 -+#define RTL8367C_SCHEDULE_PORT5_QUEUE5_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT5_QUEUE5_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE6_WFQ_WEIGHT 0x033a -+#define RTL8367C_SCHEDULE_PORT5_QUEUE6_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT5_QUEUE6_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE7_WFQ_WEIGHT 0x033b -+#define RTL8367C_SCHEDULE_PORT5_QUEUE7_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT5_QUEUE7_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE0_WFQ_WEIGHT 0x033c -+ -+#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE1_WFQ_WEIGHT 0x033d -+#define RTL8367C_SCHEDULE_PORT6_QUEUE1_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT6_QUEUE1_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE2_WFQ_WEIGHT 0x033e -+#define RTL8367C_SCHEDULE_PORT6_QUEUE2_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT6_QUEUE2_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE3_WFQ_WEIGHT 0x033f -+#define RTL8367C_SCHEDULE_PORT6_QUEUE3_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT6_QUEUE3_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE4_WFQ_WEIGHT 0x0340 -+#define RTL8367C_SCHEDULE_PORT6_QUEUE4_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT6_QUEUE4_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE5_WFQ_WEIGHT 0x0341 -+#define RTL8367C_SCHEDULE_PORT6_QUEUE5_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT6_QUEUE5_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE6_WFQ_WEIGHT 0x0342 -+#define RTL8367C_SCHEDULE_PORT6_QUEUE6_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT6_QUEUE6_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE7_WFQ_WEIGHT 0x0343 -+#define RTL8367C_SCHEDULE_PORT6_QUEUE7_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT6_QUEUE7_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE0_WFQ_WEIGHT 0x0344 -+ -+#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE1_WFQ_WEIGHT 0x0345 -+#define RTL8367C_SCHEDULE_PORT7_QUEUE1_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT7_QUEUE1_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE2_WFQ_WEIGHT 0x0346 -+#define RTL8367C_SCHEDULE_PORT7_QUEUE2_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT7_QUEUE2_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE3_WFQ_WEIGHT 0x0347 -+#define RTL8367C_SCHEDULE_PORT7_QUEUE3_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT7_QUEUE3_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE4_WFQ_WEIGHT 0x0348 -+#define RTL8367C_SCHEDULE_PORT7_QUEUE4_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT7_QUEUE4_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE5_WFQ_WEIGHT 0x0349 -+#define RTL8367C_SCHEDULE_PORT7_QUEUE5_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT7_QUEUE5_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE6_WFQ_WEIGHT 0x034a -+#define RTL8367C_SCHEDULE_PORT7_QUEUE6_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT7_QUEUE6_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE7_WFQ_WEIGHT 0x034b -+#define RTL8367C_SCHEDULE_PORT7_QUEUE7_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT7_QUEUE7_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE0_WFQ_WEIGHT 0x034c -+ -+#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE1_WFQ_WEIGHT 0x034d -+#define RTL8367C_SCHEDULE_PORT8_QUEUE1_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT8_QUEUE1_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE2_WFQ_WEIGHT 0x034e -+#define RTL8367C_SCHEDULE_PORT8_QUEUE2_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT8_QUEUE2_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE3_WFQ_WEIGHT 0x034f -+#define RTL8367C_SCHEDULE_PORT8_QUEUE3_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT8_QUEUE3_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE4_WFQ_WEIGHT 0x0350 -+#define RTL8367C_SCHEDULE_PORT8_QUEUE4_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT8_QUEUE4_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE5_WFQ_WEIGHT 0x0351 -+#define RTL8367C_SCHEDULE_PORT8_QUEUE5_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT8_QUEUE5_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE6_WFQ_WEIGHT 0x0352 -+#define RTL8367C_SCHEDULE_PORT8_QUEUE6_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT8_QUEUE6_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE7_WFQ_WEIGHT 0x0353 -+#define RTL8367C_SCHEDULE_PORT8_QUEUE7_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT8_QUEUE7_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE0_WFQ_WEIGHT 0x0354 -+ -+#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE1_WFQ_WEIGHT 0x0355 -+#define RTL8367C_SCHEDULE_PORT9_QUEUE1_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT9_QUEUE1_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE2_WFQ_WEIGHT 0x0356 -+#define RTL8367C_SCHEDULE_PORT9_QUEUE2_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT9_QUEUE2_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE3_WFQ_WEIGHT 0x0357 -+#define RTL8367C_SCHEDULE_PORT9_QUEUE3_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT9_QUEUE3_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE4_WFQ_WEIGHT 0x0358 -+#define RTL8367C_SCHEDULE_PORT9_QUEUE4_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT9_QUEUE4_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE5_WFQ_WEIGHT 0x0359 -+#define RTL8367C_SCHEDULE_PORT9_QUEUE5_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT9_QUEUE5_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE6_WFQ_WEIGHT 0x035a -+#define RTL8367C_SCHEDULE_PORT9_QUEUE6_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT9_QUEUE6_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE7_WFQ_WEIGHT 0x035b -+#define RTL8367C_SCHEDULE_PORT9_QUEUE7_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT9_QUEUE7_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE0_WFQ_WEIGHT 0x035c -+ -+#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE1_WFQ_WEIGHT 0x035d -+#define RTL8367C_SCHEDULE_PORT10_QUEUE1_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT10_QUEUE1_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE2_WFQ_WEIGHT 0x035e -+#define RTL8367C_SCHEDULE_PORT10_QUEUE2_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT10_QUEUE2_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE3_WFQ_WEIGHT 0x035f -+#define RTL8367C_SCHEDULE_PORT10_QUEUE3_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT10_QUEUE3_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE4_WFQ_WEIGHT 0x0360 -+#define RTL8367C_SCHEDULE_PORT10_QUEUE4_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT10_QUEUE4_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE5_WFQ_WEIGHT 0x0361 -+#define RTL8367C_SCHEDULE_PORT10_QUEUE5_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT10_QUEUE5_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE6_WFQ_WEIGHT 0x0362 -+#define RTL8367C_SCHEDULE_PORT10_QUEUE6_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT10_QUEUE6_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE7_WFQ_WEIGHT 0x0363 -+#define RTL8367C_SCHEDULE_PORT10_QUEUE7_WFQ_WEIGHT_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT10_QUEUE7_WFQ_WEIGHT_MASK 0x7F -+ -+#define RTL8367C_REG_PORT0_EGRESSBW_CTRL0 0x038c -+ -+#define RTL8367C_REG_PORT0_EGRESSBW_CTRL1 0x038d -+#define RTL8367C_PORT0_EGRESSBW_CTRL1_OFFSET 0 -+#define RTL8367C_PORT0_EGRESSBW_CTRL1_MASK 0x1 -+ -+#define RTL8367C_REG_PORT1_EGRESSBW_CTRL0 0x038e -+ -+#define RTL8367C_REG_PORT1_EGRESSBW_CTRL1 0x038f -+#define RTL8367C_PORT1_EGRESSBW_CTRL1_OFFSET 0 -+#define RTL8367C_PORT1_EGRESSBW_CTRL1_MASK 0x1 -+ -+#define RTL8367C_REG_PORT2_EGRESSBW_CTRL0 0x0390 -+ -+#define RTL8367C_REG_PORT2_EGRESSBW_CTRL1 0x0391 -+#define RTL8367C_PORT2_EGRESSBW_CTRL1_OFFSET 0 -+#define RTL8367C_PORT2_EGRESSBW_CTRL1_MASK 0x1 -+ -+#define RTL8367C_REG_PORT3_EGRESSBW_CTRL0 0x0392 -+ -+#define RTL8367C_REG_PORT3_EGRESSBW_CTRL1 0x0393 -+#define RTL8367C_PORT3_EGRESSBW_CTRL1_OFFSET 0 -+#define RTL8367C_PORT3_EGRESSBW_CTRL1_MASK 0x1 -+ -+#define RTL8367C_REG_PORT4_EGRESSBW_CTRL0 0x0394 -+ -+#define RTL8367C_REG_PORT4_EGRESSBW_CTRL1 0x0395 -+#define RTL8367C_PORT4_EGRESSBW_CTRL1_OFFSET 0 -+#define RTL8367C_PORT4_EGRESSBW_CTRL1_MASK 0x1 -+ -+#define RTL8367C_REG_PORT5_EGRESSBW_CTRL0 0x0396 -+ -+#define RTL8367C_REG_PORT5_EGRESSBW_CTRL1 0x0397 -+#define RTL8367C_PORT5_EGRESSBW_CTRL1_OFFSET 0 -+#define RTL8367C_PORT5_EGRESSBW_CTRL1_MASK 0x1 -+ -+#define RTL8367C_REG_PORT6_EGRESSBW_CTRL0 0x0398 -+ -+#define RTL8367C_REG_PORT6_EGRESSBW_CTRL1 0x0399 -+#define RTL8367C_PORT6_EGRESSBW_CTRL1_OFFSET 0 -+#define RTL8367C_PORT6_EGRESSBW_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_PORT7_EGRESSBW_CTRL0 0x039a -+ -+#define RTL8367C_REG_PORT7_EGRESSBW_CTRL1 0x039b -+#define RTL8367C_PORT7_EGRESSBW_CTRL1_OFFSET 0 -+#define RTL8367C_PORT7_EGRESSBW_CTRL1_MASK 0x1 -+ -+#define RTL8367C_REG_PORT8_EGRESSBW_CTRL0 0x039c -+ -+#define RTL8367C_REG_PORT8_EGRESSBW_CTRL1 0x039d -+#define RTL8367C_PORT8_EGRESSBW_CTRL1_OFFSET 0 -+#define RTL8367C_PORT8_EGRESSBW_CTRL1_MASK 0x1 -+ -+#define RTL8367C_REG_PORT9_EGRESSBW_CTRL0 0x039e -+ -+#define RTL8367C_REG_PORT9_EGRESSBW_CTRL1 0x039f -+#define RTL8367C_PORT9_EGRESSBW_CTRL1_OFFSET 0 -+#define RTL8367C_PORT9_EGRESSBW_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_PORT10_EGRESSBW_CTRL0 0x03a0 -+ -+#define RTL8367C_REG_PORT10_EGRESSBW_CTRL1 0x03a1 -+#define RTL8367C_PORT10_EGRESSBW_CTRL1_OFFSET 0 -+#define RTL8367C_PORT10_EGRESSBW_CTRL1_MASK 0x1 -+ -+#define RTL8367C_REG_SCHEDULE_PORT0_APR_METER_CTRL0 0x03ac -+#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 -+#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 -+#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 -+#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 -+#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 -+#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 -+#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 -+#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 -+#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 -+ -+#define RTL8367C_REG_SCHEDULE_PORT0_APR_METER_CTRL1 0x03ad -+#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 -+#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 -+#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 -+#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 -+#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 -+ -+#define RTL8367C_REG_SCHEDULE_PORT1_APR_METER_CTRL0 0x03b0 -+#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 -+#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 -+#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 -+#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 -+#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 -+#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 -+#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 -+#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 -+#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 -+ -+#define RTL8367C_REG_SCHEDULE_PORT1_APR_METER_CTRL1 0x03b1 -+#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 -+#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 -+#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 -+#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 -+#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 -+ -+#define RTL8367C_REG_SCHEDULE_PORT2_APR_METER_CTRL0 0x03b4 -+#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 -+#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 -+#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 -+#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 -+#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 -+#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 -+#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 -+#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 -+#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 -+ -+#define RTL8367C_REG_SCHEDULE_PORT2_APR_METER_CTRL1 0x03b5 -+#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 -+#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 -+#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 -+#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 -+#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 -+ -+#define RTL8367C_REG_SCHEDULE_PORT3_APR_METER_CTRL0 0x03b8 -+#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 -+#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 -+#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 -+#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 -+#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 -+#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 -+#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 -+#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 -+#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 -+ -+#define RTL8367C_REG_SCHEDULE_PORT3_APR_METER_CTRL1 0x03b9 -+#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 -+#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 -+#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 -+#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 -+#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 -+ -+#define RTL8367C_REG_SCHEDULE_PORT4_APR_METER_CTRL0 0x03bc -+#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 -+#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 -+#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 -+#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 -+#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 -+#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 -+#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 -+#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 -+#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 -+ -+#define RTL8367C_REG_SCHEDULE_PORT4_APR_METER_CTRL1 0x03bd -+#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 -+#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 -+#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 -+#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 -+#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 -+ -+#define RTL8367C_REG_SCHEDULE_PORT5_APR_METER_CTRL0 0x03c0 -+#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 -+#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 -+#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 -+#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 -+#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 -+#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 -+#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 -+#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 -+#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 -+ -+#define RTL8367C_REG_SCHEDULE_PORT5_APR_METER_CTRL1 0x03c1 -+#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 -+#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 -+#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 -+#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 -+#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 -+ -+#define RTL8367C_REG_SCHEDULE_PORT6_APR_METER_CTRL0 0x03c4 -+#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 -+#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 -+#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 -+#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 -+#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 -+#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 -+#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 -+#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 -+#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 -+ -+#define RTL8367C_REG_SCHEDULE_PORT6_APR_METER_CTRL1 0x03c5 -+#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 -+#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 -+#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 -+#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 -+#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 -+ -+#define RTL8367C_REG_SCHEDULE_PORT7_APR_METER_CTRL0 0x03c8 -+#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 -+#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 -+#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 -+#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 -+#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 -+#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 -+#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 -+#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 -+#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 -+ -+#define RTL8367C_REG_SCHEDULE_PORT7_APR_METER_CTRL1 0x03c9 -+#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 -+#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 -+#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 -+#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 -+#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 -+ -+#define RTL8367C_REG_SCHEDULE_PORT8_APR_METER_CTRL0 0x03ca -+#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 -+#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 -+#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 -+#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 -+#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 -+#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 -+#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 -+#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 -+#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 -+ -+#define RTL8367C_REG_SCHEDULE_PORT8_APR_METER_CTRL1 0x03cb -+#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 -+#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 -+#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 -+#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 -+#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 -+ -+#define RTL8367C_REG_SCHEDULE_PORT9_APR_METER_CTRL0 0x03cc -+#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 -+#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 -+#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 -+#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 -+#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 -+#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 -+#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 -+#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 -+#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 -+ -+#define RTL8367C_REG_SCHEDULE_PORT9_APR_METER_CTRL1 0x03cd -+#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 -+#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 -+#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 -+#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 -+#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 -+ -+#define RTL8367C_REG_SCHEDULE_PORT10_APR_METER_CTRL0 0x03ce -+#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 -+#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 -+#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 -+#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 -+#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 -+#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 -+#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 -+#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 -+#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 -+ -+#define RTL8367C_REG_SCHEDULE_PORT10_APR_METER_CTRL1 0x03cf -+#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 -+#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 -+#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 -+#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 -+#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 -+#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 -+ -+#define RTL8367C_REG_LINE_RATE_1G_L 0x03ec -+ -+#define RTL8367C_REG_LINE_RATE_1G_H 0x03ed -+#define RTL8367C_LINE_RATE_1G_H_OFFSET 0 -+#define RTL8367C_LINE_RATE_1G_H_MASK 0x1 -+ -+#define RTL8367C_REG_LINE_RATE_100_L 0x03ee -+ -+#define RTL8367C_REG_LINE_RATE_100_H 0x03ef -+#define RTL8367C_LINE_RATE_100_H_OFFSET 0 -+#define RTL8367C_LINE_RATE_100_H_MASK 0x1 -+ -+#define RTL8367C_REG_LINE_RATE_10_L 0x03f0 -+ -+#define RTL8367C_REG_LINE_RATE_10_H 0x03f1 -+#define RTL8367C_LINE_RATE_10_H_OFFSET 0 -+#define RTL8367C_LINE_RATE_10_H_MASK 0x1 -+ -+#define RTL8367C_REG_DUMMY_03f2 0x03f2 -+ -+#define RTL8367C_REG_DUMMY_03f3 0x03f3 -+ -+#define RTL8367C_REG_DUMMY_03f4 0x03f4 -+ -+#define RTL8367C_REG_DUMMY_03f5 0x03f5 -+ -+#define RTL8367C_REG_DUMMY_03f6 0x03f6 -+ -+#define RTL8367C_REG_BYPASS_LINE_RATE 0x03f7 -+#define RTL8367C_BYPASS_PORT10_CONSTRAINT_OFFSET 5 -+#define RTL8367C_BYPASS_PORT10_CONSTRAINT_MASK 0x20 -+#define RTL8367C_BYPASS_PORT9_CONSTRAINT_OFFSET 4 -+#define RTL8367C_BYPASS_PORT9_CONSTRAINT_MASK 0x10 -+#define RTL8367C_BYPASS_PORT8_CONSTRAINT_OFFSET 3 -+#define RTL8367C_BYPASS_PORT8_CONSTRAINT_MASK 0x8 -+#define RTL8367C_BYPASS_PORT7_CONSTRAINT_OFFSET 2 -+#define RTL8367C_BYPASS_PORT7_CONSTRAINT_MASK 0x4 -+#define RTL8367C_BYPASS_PORT6_CONSTRAINT_OFFSET 1 -+#define RTL8367C_BYPASS_PORT6_CONSTRAINT_MASK 0x2 -+#define RTL8367C_BYPASS_PORT5_CONSTRAINT_OFFSET 0 -+#define RTL8367C_BYPASS_PORT5_CONSTRAINT_MASK 0x1 -+ -+#define RTL8367C_REG_LINE_RATE_500_H 0x03f8 -+#define RTL8367C_LINE_RATE_500_H_OFFSET 0 -+#define RTL8367C_LINE_RATE_500_H_MASK 0x7 -+ -+#define RTL8367C_REG_LINE_RATE_500_L 0x03f9 -+ -+#define RTL8367C_REG_LINE_RATE_HSG_H 0x03fa -+#define RTL8367C_LINE_RATE_HSG_H_OFFSET 0 -+#define RTL8367C_LINE_RATE_HSG_H_MASK 0x7 -+ -+#define RTL8367C_REG_LINE_RATE_HSG_L 0x03fb -+ -+/* (16'h0500)table_reg */ -+ -+#define RTL8367C_REG_TABLE_ACCESS_CTRL 0x0500 -+#define RTL8367C_TABLE_ACCESS_CTRL_SPA_OFFSET 8 -+#define RTL8367C_TABLE_ACCESS_CTRL_SPA_MASK 0xF00 -+#define RTL8367C_ACCESS_METHOD_OFFSET 4 -+#define RTL8367C_ACCESS_METHOD_MASK 0x70 -+#define RTL8367C_COMMAND_TYPE_OFFSET 3 -+#define RTL8367C_COMMAND_TYPE_MASK 0x8 -+#define RTL8367C_TABLE_TYPE_OFFSET 0 -+#define RTL8367C_TABLE_TYPE_MASK 0x7 -+ -+#define RTL8367C_REG_TABLE_ACCESS_ADDR 0x0501 -+#define RTL8367C_TABLE_ACCESS_ADDR_OFFSET 0 -+#define RTL8367C_TABLE_ACCESS_ADDR_MASK 0x1FFF -+ -+#define RTL8367C_REG_TABLE_LUT_ADDR 0x0502 -+#define RTL8367C_ADDRESS2_OFFSET 14 -+#define RTL8367C_ADDRESS2_MASK 0x4000 -+#define RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_OFFSET 13 -+#define RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_MASK 0x2000 -+#define RTL8367C_HIT_STATUS_OFFSET 12 -+#define RTL8367C_HIT_STATUS_MASK 0x1000 -+#define RTL8367C_TABLE_LUT_ADDR_TYPE_OFFSET 11 -+#define RTL8367C_TABLE_LUT_ADDR_TYPE_MASK 0x800 -+#define RTL8367C_TABLE_LUT_ADDR_ADDRESS_OFFSET 0 -+#define RTL8367C_TABLE_LUT_ADDR_ADDRESS_MASK 0x7FF -+ -+#define RTL8367C_REG_HSA_HSB_LATCH 0x0503 -+#define RTL8367C_LATCH_ALWAYS_OFFSET 15 -+#define RTL8367C_LATCH_ALWAYS_MASK 0x8000 -+#define RTL8367C_LATCH_FIRST_OFFSET 14 -+#define RTL8367C_LATCH_FIRST_MASK 0x4000 -+#define RTL8367C_SPA_EN_OFFSET 13 -+#define RTL8367C_SPA_EN_MASK 0x2000 -+#define RTL8367C_FORWARD_EN_OFFSET 12 -+#define RTL8367C_FORWARD_EN_MASK 0x1000 -+#define RTL8367C_REASON_EN_OFFSET 11 -+#define RTL8367C_REASON_EN_MASK 0x800 -+#define RTL8367C_HSA_HSB_LATCH_SPA_OFFSET 8 -+#define RTL8367C_HSA_HSB_LATCH_SPA_MASK 0x700 -+#define RTL8367C_FORWARD_OFFSET 6 -+#define RTL8367C_FORWARD_MASK 0xC0 -+#define RTL8367C_REASON_OFFSET 0 -+#define RTL8367C_REASON_MASK 0x3F -+ -+#define RTL8367C_REG_HSA_HSB_LATCH2 0x0504 -+#define RTL8367C_HSA_HSB_LATCH2_Reserved_OFFSET 1 -+#define RTL8367C_HSA_HSB_LATCH2_Reserved_MASK 0xFFFE -+#define RTL8367C_SPA2_OFFSET 0 -+#define RTL8367C_SPA2_MASK 0x1 -+ -+#define RTL8367C_REG_TABLE_WRITE_DATA0 0x0510 -+ -+#define RTL8367C_REG_TABLE_WRITE_DATA1 0x0511 -+ -+#define RTL8367C_REG_TABLE_WRITE_DATA2 0x0512 -+ -+#define RTL8367C_REG_TABLE_WRITE_DATA3 0x0513 -+ -+#define RTL8367C_REG_TABLE_WRITE_DATA4 0x0514 -+ -+#define RTL8367C_REG_TABLE_WRITE_DATA5 0x0515 -+ -+#define RTL8367C_REG_TABLE_WRITE_DATA6 0x0516 -+ -+#define RTL8367C_REG_TABLE_WRITE_DATA7 0x0517 -+ -+#define RTL8367C_REG_TABLE_WRITE_DATA8 0x0518 -+ -+#define RTL8367C_REG_TABLE_WRITE_DATA9 0x0519 -+#define RTL8367C_TABLE_WRITE_DATA9_OFFSET 0 -+#define RTL8367C_TABLE_WRITE_DATA9_MASK 0xF -+ -+#define RTL8367C_REG_TABLE_READ_DATA0 0x0520 -+ -+#define RTL8367C_REG_TABLE_READ_DATA1 0x0521 -+ -+#define RTL8367C_REG_TABLE_READ_DATA2 0x0522 -+ -+#define RTL8367C_REG_TABLE_READ_DATA3 0x0523 -+ -+#define RTL8367C_REG_TABLE_READ_DATA4 0x0524 -+ -+#define RTL8367C_REG_TABLE_READ_DATA5 0x0525 -+ -+#define RTL8367C_REG_TABLE_READ_DATA6 0x0526 -+ -+#define RTL8367C_REG_TABLE_READ_DATA7 0x0527 -+ -+#define RTL8367C_REG_TABLE_READ_DATA8 0x0528 -+ -+#define RTL8367C_REG_TABLE_READ_DATA9 0x0529 -+#define RTL8367C_TABLE_READ_DATA9_OFFSET 0 -+#define RTL8367C_TABLE_READ_DATA9_MASK 0xF -+ -+#define RTL8367C_REG_TBL_DUMMY00 0x0550 -+ -+#define RTL8367C_REG_TBL_DUMMY01 0x0551 -+ -+/* (16'h0600)acl_reg */ -+ -+#define RTL8367C_REG_ACL_RULE_TEMPLATE0_CTRL0 0x0600 -+#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL0_FIELD1_OFFSET 8 -+#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL0_FIELD1_MASK 0x7F00 -+#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL0_FIELD0_OFFSET 0 -+#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL0_FIELD0_MASK 0x7F -+ -+#define RTL8367C_REG_ACL_RULE_TEMPLATE0_CTRL1 0x0601 -+#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL1_FIELD3_OFFSET 8 -+#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL1_FIELD3_MASK 0x7F00 -+#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL1_FIELD2_OFFSET 0 -+#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL1_FIELD2_MASK 0x7F -+ -+#define RTL8367C_REG_ACL_RULE_TEMPLATE0_CTRL2 0x0602 -+#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL2_FIELD5_OFFSET 8 -+#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL2_FIELD5_MASK 0x7F00 -+#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL2_FIELD4_OFFSET 0 -+#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL2_FIELD4_MASK 0x7F -+ -+#define RTL8367C_REG_ACL_RULE_TEMPLATE0_CTRL3 0x0603 -+#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL3_FIELD7_OFFSET 8 -+#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL3_FIELD7_MASK 0x7F00 -+#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL3_FIELD6_OFFSET 0 -+#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL3_FIELD6_MASK 0x7F -+ -+#define RTL8367C_REG_ACL_RULE_TEMPLATE1_CTRL0 0x0604 -+#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL0_FIELD1_OFFSET 8 -+#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL0_FIELD1_MASK 0x7F00 -+#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL0_FIELD0_OFFSET 0 -+#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL0_FIELD0_MASK 0x7F -+ -+#define RTL8367C_REG_ACL_RULE_TEMPLATE1_CTRL1 0x0605 -+#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL1_FIELD3_OFFSET 8 -+#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL1_FIELD3_MASK 0x7F00 -+#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL1_FIELD2_OFFSET 0 -+#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL1_FIELD2_MASK 0x7F -+ -+#define RTL8367C_REG_ACL_RULE_TEMPLATE1_CTRL2 0x0606 -+#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL2_FIELD5_OFFSET 8 -+#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL2_FIELD5_MASK 0x7F00 -+#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL2_FIELD4_OFFSET 0 -+#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL2_FIELD4_MASK 0x7F -+ -+#define RTL8367C_REG_ACL_RULE_TEMPLATE1_CTRL3 0x0607 -+#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL3_FIELD7_OFFSET 8 -+#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL3_FIELD7_MASK 0x7F00 -+#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL3_FIELD6_OFFSET 0 -+#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL3_FIELD6_MASK 0x7F -+ -+#define RTL8367C_REG_ACL_RULE_TEMPLATE2_CTRL0 0x0608 -+#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL0_FIELD1_OFFSET 8 -+#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL0_FIELD1_MASK 0x7F00 -+#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL0_FIELD0_OFFSET 0 -+#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL0_FIELD0_MASK 0x7F -+ -+#define RTL8367C_REG_ACL_RULE_TEMPLATE2_CTRL1 0x0609 -+#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL1_FIELD3_OFFSET 8 -+#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL1_FIELD3_MASK 0x7F00 -+#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL1_FIELD2_OFFSET 0 -+#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL1_FIELD2_MASK 0x7F -+ -+#define RTL8367C_REG_ACL_RULE_TEMPLATE2_CTRL2 0x060a -+#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL2_FIELD5_OFFSET 8 -+#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL2_FIELD5_MASK 0x7F00 -+#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL2_FIELD4_OFFSET 0 -+#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL2_FIELD4_MASK 0x7F -+ -+#define RTL8367C_REG_ACL_RULE_TEMPLATE2_CTRL3 0x060b -+#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL3_FIELD7_OFFSET 8 -+#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL3_FIELD7_MASK 0x7F00 -+#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL3_FIELD6_OFFSET 0 -+#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL3_FIELD6_MASK 0x7F -+ -+#define RTL8367C_REG_ACL_RULE_TEMPLATE3_CTRL0 0x060c -+#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL0_FIELD1_OFFSET 8 -+#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL0_FIELD1_MASK 0x7F00 -+#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL0_FIELD0_OFFSET 0 -+#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL0_FIELD0_MASK 0x7F -+ -+#define RTL8367C_REG_ACL_RULE_TEMPLATE3_CTRL1 0x060d -+#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL1_FIELD3_OFFSET 8 -+#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL1_FIELD3_MASK 0x7F00 -+#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL1_FIELD2_OFFSET 0 -+#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL1_FIELD2_MASK 0x7F -+ -+#define RTL8367C_REG_ACL_RULE_TEMPLATE3_CTRL2 0x060e -+#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL2_FIELD5_OFFSET 8 -+#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL2_FIELD5_MASK 0x7F00 -+#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL2_FIELD4_OFFSET 0 -+#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL2_FIELD4_MASK 0x7F -+ -+#define RTL8367C_REG_ACL_RULE_TEMPLATE3_CTRL3 0x060f -+#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL3_FIELD7_OFFSET 8 -+#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL3_FIELD7_MASK 0x7F00 -+#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL3_FIELD6_OFFSET 0 -+#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL3_FIELD6_MASK 0x7F -+ -+#define RTL8367C_REG_ACL_RULE_TEMPLATE4_CTRL0 0x0610 -+#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL0_FIELD1_OFFSET 8 -+#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL0_FIELD1_MASK 0x7F00 -+#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL0_FIELD0_OFFSET 0 -+#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL0_FIELD0_MASK 0x7F -+ -+#define RTL8367C_REG_ACL_RULE_TEMPLATE4_CTRL1 0x0611 -+#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL1_FIELD3_OFFSET 8 -+#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL1_FIELD3_MASK 0x7F00 -+#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL1_FIELD2_OFFSET 0 -+#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL1_FIELD2_MASK 0x7F -+ -+#define RTL8367C_REG_ACL_RULE_TEMPLATE4_CTRL2 0x0612 -+#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL2_FIELD5_OFFSET 8 -+#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL2_FIELD5_MASK 0x7F00 -+#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL2_FIELD4_OFFSET 0 -+#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL2_FIELD4_MASK 0x7F -+ -+#define RTL8367C_REG_ACL_RULE_TEMPLATE4_CTRL3 0x0613 -+#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL3_FIELD7_OFFSET 8 -+#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL3_FIELD7_MASK 0x7F00 -+#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL3_FIELD6_OFFSET 0 -+#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL3_FIELD6_MASK 0x7F -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL0 0x0614 -+#define RTL8367C_OP1_NOT_OFFSET 14 -+#define RTL8367C_OP1_NOT_MASK 0x4000 -+#define RTL8367C_ACT1_GPIO_OFFSET 13 -+#define RTL8367C_ACT1_GPIO_MASK 0x2000 -+#define RTL8367C_ACT1_FORWARD_OFFSET 12 -+#define RTL8367C_ACT1_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT1_POLICING_OFFSET 11 -+#define RTL8367C_ACT1_POLICING_MASK 0x800 -+#define RTL8367C_ACT1_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT1_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT1_SVID_OFFSET 9 -+#define RTL8367C_ACT1_SVID_MASK 0x200 -+#define RTL8367C_ACT1_CVID_OFFSET 8 -+#define RTL8367C_ACT1_CVID_MASK 0x100 -+#define RTL8367C_OP0_NOT_OFFSET 6 -+#define RTL8367C_OP0_NOT_MASK 0x40 -+#define RTL8367C_ACT0_GPIO_OFFSET 5 -+#define RTL8367C_ACT0_GPIO_MASK 0x20 -+#define RTL8367C_ACT0_FORWARD_OFFSET 4 -+#define RTL8367C_ACT0_FORWARD_MASK 0x10 -+#define RTL8367C_ACT0_POLICING_OFFSET 3 -+#define RTL8367C_ACT0_POLICING_MASK 0x8 -+#define RTL8367C_ACT0_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT0_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT0_SVID_OFFSET 1 -+#define RTL8367C_ACT0_SVID_MASK 0x2 -+#define RTL8367C_ACT0_CVID_OFFSET 0 -+#define RTL8367C_ACT0_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL1 0x0615 -+#define RTL8367C_OP3_NOT_OFFSET 14 -+#define RTL8367C_OP3_NOT_MASK 0x4000 -+#define RTL8367C_ACT3_GPIO_OFFSET 13 -+#define RTL8367C_ACT3_GPIO_MASK 0x2000 -+#define RTL8367C_ACT3_FORWARD_OFFSET 12 -+#define RTL8367C_ACT3_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT3_POLICING_OFFSET 11 -+#define RTL8367C_ACT3_POLICING_MASK 0x800 -+#define RTL8367C_ACT3_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT3_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT3_SVID_OFFSET 9 -+#define RTL8367C_ACT3_SVID_MASK 0x200 -+#define RTL8367C_ACT3_CVID_OFFSET 8 -+#define RTL8367C_ACT3_CVID_MASK 0x100 -+#define RTL8367C_OP2_NOT_OFFSET 6 -+#define RTL8367C_OP2_NOT_MASK 0x40 -+#define RTL8367C_ACT2_GPIO_OFFSET 5 -+#define RTL8367C_ACT2_GPIO_MASK 0x20 -+#define RTL8367C_ACT2_FORWARD_OFFSET 4 -+#define RTL8367C_ACT2_FORWARD_MASK 0x10 -+#define RTL8367C_ACT2_POLICING_OFFSET 3 -+#define RTL8367C_ACT2_POLICING_MASK 0x8 -+#define RTL8367C_ACT2_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT2_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT2_SVID_OFFSET 1 -+#define RTL8367C_ACT2_SVID_MASK 0x2 -+#define RTL8367C_ACT2_CVID_OFFSET 0 -+#define RTL8367C_ACT2_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL2 0x0616 -+#define RTL8367C_OP5_NOT_OFFSET 14 -+#define RTL8367C_OP5_NOT_MASK 0x4000 -+#define RTL8367C_ACT5_GPIO_OFFSET 13 -+#define RTL8367C_ACT5_GPIO_MASK 0x2000 -+#define RTL8367C_ACT5_FORWARD_OFFSET 12 -+#define RTL8367C_ACT5_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT5_POLICING_OFFSET 11 -+#define RTL8367C_ACT5_POLICING_MASK 0x800 -+#define RTL8367C_ACT5_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT5_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT5_SVID_OFFSET 9 -+#define RTL8367C_ACT5_SVID_MASK 0x200 -+#define RTL8367C_ACT5_CVID_OFFSET 8 -+#define RTL8367C_ACT5_CVID_MASK 0x100 -+#define RTL8367C_OP4_NOT_OFFSET 6 -+#define RTL8367C_OP4_NOT_MASK 0x40 -+#define RTL8367C_ACT4_GPIO_OFFSET 5 -+#define RTL8367C_ACT4_GPIO_MASK 0x20 -+#define RTL8367C_ACT4_FORWARD_OFFSET 4 -+#define RTL8367C_ACT4_FORWARD_MASK 0x10 -+#define RTL8367C_ACT4_POLICING_OFFSET 3 -+#define RTL8367C_ACT4_POLICING_MASK 0x8 -+#define RTL8367C_ACT4_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT4_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT4_SVID_OFFSET 1 -+#define RTL8367C_ACT4_SVID_MASK 0x2 -+#define RTL8367C_ACT4_CVID_OFFSET 0 -+#define RTL8367C_ACT4_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL3 0x0617 -+#define RTL8367C_OP7_NOT_OFFSET 14 -+#define RTL8367C_OP7_NOT_MASK 0x4000 -+#define RTL8367C_ACT7_GPIO_OFFSET 13 -+#define RTL8367C_ACT7_GPIO_MASK 0x2000 -+#define RTL8367C_ACT7_FORWARD_OFFSET 12 -+#define RTL8367C_ACT7_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT7_POLICING_OFFSET 11 -+#define RTL8367C_ACT7_POLICING_MASK 0x800 -+#define RTL8367C_ACT7_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT7_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT7_SVID_OFFSET 9 -+#define RTL8367C_ACT7_SVID_MASK 0x200 -+#define RTL8367C_ACT7_CVID_OFFSET 8 -+#define RTL8367C_ACT7_CVID_MASK 0x100 -+#define RTL8367C_OP6_NOT_OFFSET 6 -+#define RTL8367C_OP6_NOT_MASK 0x40 -+#define RTL8367C_ACT6_GPIO_OFFSET 5 -+#define RTL8367C_ACT6_GPIO_MASK 0x20 -+#define RTL8367C_ACT6_FORWARD_OFFSET 4 -+#define RTL8367C_ACT6_FORWARD_MASK 0x10 -+#define RTL8367C_ACT6_POLICING_OFFSET 3 -+#define RTL8367C_ACT6_POLICING_MASK 0x8 -+#define RTL8367C_ACT6_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT6_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT6_SVID_OFFSET 1 -+#define RTL8367C_ACT6_SVID_MASK 0x2 -+#define RTL8367C_ACT6_CVID_OFFSET 0 -+#define RTL8367C_ACT6_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL4 0x0618 -+#define RTL8367C_OP9_NOT_OFFSET 14 -+#define RTL8367C_OP9_NOT_MASK 0x4000 -+#define RTL8367C_ACT9_GPIO_OFFSET 13 -+#define RTL8367C_ACT9_GPIO_MASK 0x2000 -+#define RTL8367C_ACT9_FORWARD_OFFSET 12 -+#define RTL8367C_ACT9_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT9_POLICING_OFFSET 11 -+#define RTL8367C_ACT9_POLICING_MASK 0x800 -+#define RTL8367C_ACT9_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT9_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT9_SVID_OFFSET 9 -+#define RTL8367C_ACT9_SVID_MASK 0x200 -+#define RTL8367C_ACT9_CVID_OFFSET 8 -+#define RTL8367C_ACT9_CVID_MASK 0x100 -+#define RTL8367C_OP8_NOT_OFFSET 6 -+#define RTL8367C_OP8_NOT_MASK 0x40 -+#define RTL8367C_ACT8_GPIO_OFFSET 5 -+#define RTL8367C_ACT8_GPIO_MASK 0x20 -+#define RTL8367C_ACT8_FORWARD_OFFSET 4 -+#define RTL8367C_ACT8_FORWARD_MASK 0x10 -+#define RTL8367C_ACT8_POLICING_OFFSET 3 -+#define RTL8367C_ACT8_POLICING_MASK 0x8 -+#define RTL8367C_ACT8_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT8_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT8_SVID_OFFSET 1 -+#define RTL8367C_ACT8_SVID_MASK 0x2 -+#define RTL8367C_ACT8_CVID_OFFSET 0 -+#define RTL8367C_ACT8_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL5 0x0619 -+#define RTL8367C_OP11_NOT_OFFSET 14 -+#define RTL8367C_OP11_NOT_MASK 0x4000 -+#define RTL8367C_ACT11_GPIO_OFFSET 13 -+#define RTL8367C_ACT11_GPIO_MASK 0x2000 -+#define RTL8367C_ACT11_FORWARD_OFFSET 12 -+#define RTL8367C_ACT11_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT11_POLICING_OFFSET 11 -+#define RTL8367C_ACT11_POLICING_MASK 0x800 -+#define RTL8367C_ACT11_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT11_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT11_SVID_OFFSET 9 -+#define RTL8367C_ACT11_SVID_MASK 0x200 -+#define RTL8367C_ACT11_CVID_OFFSET 8 -+#define RTL8367C_ACT11_CVID_MASK 0x100 -+#define RTL8367C_OP10_NOT_OFFSET 6 -+#define RTL8367C_OP10_NOT_MASK 0x40 -+#define RTL8367C_ACT10_GPIO_OFFSET 5 -+#define RTL8367C_ACT10_GPIO_MASK 0x20 -+#define RTL8367C_ACT10_FORWARD_OFFSET 4 -+#define RTL8367C_ACT10_FORWARD_MASK 0x10 -+#define RTL8367C_ACT10_POLICING_OFFSET 3 -+#define RTL8367C_ACT10_POLICING_MASK 0x8 -+#define RTL8367C_ACT10_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT10_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT10_SVID_OFFSET 1 -+#define RTL8367C_ACT10_SVID_MASK 0x2 -+#define RTL8367C_ACT10_CVID_OFFSET 0 -+#define RTL8367C_ACT10_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL6 0x061a -+#define RTL8367C_OP13_NOT_OFFSET 14 -+#define RTL8367C_OP13_NOT_MASK 0x4000 -+#define RTL8367C_ACT13_GPIO_OFFSET 13 -+#define RTL8367C_ACT13_GPIO_MASK 0x2000 -+#define RTL8367C_ACT13_FORWARD_OFFSET 12 -+#define RTL8367C_ACT13_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT13_POLICING_OFFSET 11 -+#define RTL8367C_ACT13_POLICING_MASK 0x800 -+#define RTL8367C_ACT13_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT13_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT13_SVID_OFFSET 9 -+#define RTL8367C_ACT13_SVID_MASK 0x200 -+#define RTL8367C_ACT13_CVID_OFFSET 8 -+#define RTL8367C_ACT13_CVID_MASK 0x100 -+#define RTL8367C_OP12_NOT_OFFSET 6 -+#define RTL8367C_OP12_NOT_MASK 0x40 -+#define RTL8367C_ACT12_GPIO_OFFSET 5 -+#define RTL8367C_ACT12_GPIO_MASK 0x20 -+#define RTL8367C_ACT12_FORWARD_OFFSET 4 -+#define RTL8367C_ACT12_FORWARD_MASK 0x10 -+#define RTL8367C_ACT12_POLICING_OFFSET 3 -+#define RTL8367C_ACT12_POLICING_MASK 0x8 -+#define RTL8367C_ACT12_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT12_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT12_SVID_OFFSET 1 -+#define RTL8367C_ACT12_SVID_MASK 0x2 -+#define RTL8367C_ACT12_CVID_OFFSET 0 -+#define RTL8367C_ACT12_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL7 0x061b -+#define RTL8367C_OP15_NOT_OFFSET 14 -+#define RTL8367C_OP15_NOT_MASK 0x4000 -+#define RTL8367C_ACT15_GPIO_OFFSET 13 -+#define RTL8367C_ACT15_GPIO_MASK 0x2000 -+#define RTL8367C_ACT15_FORWARD_OFFSET 12 -+#define RTL8367C_ACT15_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT15_POLICING_OFFSET 11 -+#define RTL8367C_ACT15_POLICING_MASK 0x800 -+#define RTL8367C_ACT15_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT15_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT15_SVID_OFFSET 9 -+#define RTL8367C_ACT15_SVID_MASK 0x200 -+#define RTL8367C_ACT15_CVID_OFFSET 8 -+#define RTL8367C_ACT15_CVID_MASK 0x100 -+#define RTL8367C_OP14_NOT_OFFSET 6 -+#define RTL8367C_OP14_NOT_MASK 0x40 -+#define RTL8367C_ACT14_GPIO_OFFSET 5 -+#define RTL8367C_ACT14_GPIO_MASK 0x20 -+#define RTL8367C_ACT14_FORWARD_OFFSET 4 -+#define RTL8367C_ACT14_FORWARD_MASK 0x10 -+#define RTL8367C_ACT14_POLICING_OFFSET 3 -+#define RTL8367C_ACT14_POLICING_MASK 0x8 -+#define RTL8367C_ACT14_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT14_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT14_SVID_OFFSET 1 -+#define RTL8367C_ACT14_SVID_MASK 0x2 -+#define RTL8367C_ACT14_CVID_OFFSET 0 -+#define RTL8367C_ACT14_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL8 0x061c -+#define RTL8367C_OP17_NOT_OFFSET 14 -+#define RTL8367C_OP17_NOT_MASK 0x4000 -+#define RTL8367C_ACT17_GPIO_OFFSET 13 -+#define RTL8367C_ACT17_GPIO_MASK 0x2000 -+#define RTL8367C_ACT17_FORWARD_OFFSET 12 -+#define RTL8367C_ACT17_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT17_POLICING_OFFSET 11 -+#define RTL8367C_ACT17_POLICING_MASK 0x800 -+#define RTL8367C_ACT17_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT17_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT17_SVID_OFFSET 9 -+#define RTL8367C_ACT17_SVID_MASK 0x200 -+#define RTL8367C_ACT17_CVID_OFFSET 8 -+#define RTL8367C_ACT17_CVID_MASK 0x100 -+#define RTL8367C_OP16_NOT_OFFSET 6 -+#define RTL8367C_OP16_NOT_MASK 0x40 -+#define RTL8367C_ACT16_GPIO_OFFSET 5 -+#define RTL8367C_ACT16_GPIO_MASK 0x20 -+#define RTL8367C_ACT16_FORWARD_OFFSET 4 -+#define RTL8367C_ACT16_FORWARD_MASK 0x10 -+#define RTL8367C_ACT16_POLICING_OFFSET 3 -+#define RTL8367C_ACT16_POLICING_MASK 0x8 -+#define RTL8367C_ACT16_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT16_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT16_SVID_OFFSET 1 -+#define RTL8367C_ACT16_SVID_MASK 0x2 -+#define RTL8367C_ACT16_CVID_OFFSET 0 -+#define RTL8367C_ACT16_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL9 0x061d -+#define RTL8367C_OP19_NOT_OFFSET 14 -+#define RTL8367C_OP19_NOT_MASK 0x4000 -+#define RTL8367C_ACT19_GPIO_OFFSET 13 -+#define RTL8367C_ACT19_GPIO_MASK 0x2000 -+#define RTL8367C_ACT19_FORWARD_OFFSET 12 -+#define RTL8367C_ACT19_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT19_POLICING_OFFSET 11 -+#define RTL8367C_ACT19_POLICING_MASK 0x800 -+#define RTL8367C_ACT19_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT19_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT19_SVID_OFFSET 9 -+#define RTL8367C_ACT19_SVID_MASK 0x200 -+#define RTL8367C_ACT19_CVID_OFFSET 8 -+#define RTL8367C_ACT19_CVID_MASK 0x100 -+#define RTL8367C_OP18_NOT_OFFSET 6 -+#define RTL8367C_OP18_NOT_MASK 0x40 -+#define RTL8367C_ACT18_GPIO_OFFSET 5 -+#define RTL8367C_ACT18_GPIO_MASK 0x20 -+#define RTL8367C_ACT18_FORWARD_OFFSET 4 -+#define RTL8367C_ACT18_FORWARD_MASK 0x10 -+#define RTL8367C_ACT18_POLICING_OFFSET 3 -+#define RTL8367C_ACT18_POLICING_MASK 0x8 -+#define RTL8367C_ACT18_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT18_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT18_SVID_OFFSET 1 -+#define RTL8367C_ACT18_SVID_MASK 0x2 -+#define RTL8367C_ACT18_CVID_OFFSET 0 -+#define RTL8367C_ACT18_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL10 0x061e -+#define RTL8367C_OP21_NOT_OFFSET 14 -+#define RTL8367C_OP21_NOT_MASK 0x4000 -+#define RTL8367C_ACT21_GPIO_OFFSET 13 -+#define RTL8367C_ACT21_GPIO_MASK 0x2000 -+#define RTL8367C_ACT21_FORWARD_OFFSET 12 -+#define RTL8367C_ACT21_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT21_POLICING_OFFSET 11 -+#define RTL8367C_ACT21_POLICING_MASK 0x800 -+#define RTL8367C_ACT21_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT21_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT21_SVID_OFFSET 9 -+#define RTL8367C_ACT21_SVID_MASK 0x200 -+#define RTL8367C_ACT21_CVID_OFFSET 8 -+#define RTL8367C_ACT21_CVID_MASK 0x100 -+#define RTL8367C_OP20_NOT_OFFSET 6 -+#define RTL8367C_OP20_NOT_MASK 0x40 -+#define RTL8367C_ACT20_GPIO_OFFSET 5 -+#define RTL8367C_ACT20_GPIO_MASK 0x20 -+#define RTL8367C_ACT20_FORWARD_OFFSET 4 -+#define RTL8367C_ACT20_FORWARD_MASK 0x10 -+#define RTL8367C_ACT20_POLICING_OFFSET 3 -+#define RTL8367C_ACT20_POLICING_MASK 0x8 -+#define RTL8367C_ACT20_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT20_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT20_SVID_OFFSET 1 -+#define RTL8367C_ACT20_SVID_MASK 0x2 -+#define RTL8367C_ACT20_CVID_OFFSET 0 -+#define RTL8367C_ACT20_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL11 0x061f -+#define RTL8367C_OP23_NOT_OFFSET 14 -+#define RTL8367C_OP23_NOT_MASK 0x4000 -+#define RTL8367C_ACT23_GPIO_OFFSET 13 -+#define RTL8367C_ACT23_GPIO_MASK 0x2000 -+#define RTL8367C_ACT23_FORWARD_OFFSET 12 -+#define RTL8367C_ACT23_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT23_POLICING_OFFSET 11 -+#define RTL8367C_ACT23_POLICING_MASK 0x800 -+#define RTL8367C_ACT23_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT23_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT23_SVID_OFFSET 9 -+#define RTL8367C_ACT23_SVID_MASK 0x200 -+#define RTL8367C_ACT23_CVID_OFFSET 8 -+#define RTL8367C_ACT23_CVID_MASK 0x100 -+#define RTL8367C_OP22_NOT_OFFSET 6 -+#define RTL8367C_OP22_NOT_MASK 0x40 -+#define RTL8367C_ACT22_GPIO_OFFSET 5 -+#define RTL8367C_ACT22_GPIO_MASK 0x20 -+#define RTL8367C_ACT22_FORWARD_OFFSET 4 -+#define RTL8367C_ACT22_FORWARD_MASK 0x10 -+#define RTL8367C_ACT22_POLICING_OFFSET 3 -+#define RTL8367C_ACT22_POLICING_MASK 0x8 -+#define RTL8367C_ACT22_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT22_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT22_SVID_OFFSET 1 -+#define RTL8367C_ACT22_SVID_MASK 0x2 -+#define RTL8367C_ACT22_CVID_OFFSET 0 -+#define RTL8367C_ACT22_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL12 0x0620 -+#define RTL8367C_OP25_NOT_OFFSET 14 -+#define RTL8367C_OP25_NOT_MASK 0x4000 -+#define RTL8367C_ACT25_GPIO_OFFSET 13 -+#define RTL8367C_ACT25_GPIO_MASK 0x2000 -+#define RTL8367C_ACT25_FORWARD_OFFSET 12 -+#define RTL8367C_ACT25_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT25_POLICING_OFFSET 11 -+#define RTL8367C_ACT25_POLICING_MASK 0x800 -+#define RTL8367C_ACT25_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT25_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT25_SVID_OFFSET 9 -+#define RTL8367C_ACT25_SVID_MASK 0x200 -+#define RTL8367C_ACT25_CVID_OFFSET 8 -+#define RTL8367C_ACT25_CVID_MASK 0x100 -+#define RTL8367C_OP24_NOT_OFFSET 6 -+#define RTL8367C_OP24_NOT_MASK 0x40 -+#define RTL8367C_ACT24_GPIO_OFFSET 5 -+#define RTL8367C_ACT24_GPIO_MASK 0x20 -+#define RTL8367C_ACT24_FORWARD_OFFSET 4 -+#define RTL8367C_ACT24_FORWARD_MASK 0x10 -+#define RTL8367C_ACT24_POLICING_OFFSET 3 -+#define RTL8367C_ACT24_POLICING_MASK 0x8 -+#define RTL8367C_ACT24_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT24_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT24_SVID_OFFSET 1 -+#define RTL8367C_ACT24_SVID_MASK 0x2 -+#define RTL8367C_ACT24_CVID_OFFSET 0 -+#define RTL8367C_ACT24_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL13 0x0621 -+#define RTL8367C_OP27_NOT_OFFSET 14 -+#define RTL8367C_OP27_NOT_MASK 0x4000 -+#define RTL8367C_ACT27_GPIO_OFFSET 13 -+#define RTL8367C_ACT27_GPIO_MASK 0x2000 -+#define RTL8367C_ACT27_FORWARD_OFFSET 12 -+#define RTL8367C_ACT27_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT27_POLICING_OFFSET 11 -+#define RTL8367C_ACT27_POLICING_MASK 0x800 -+#define RTL8367C_ACT27_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT27_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT27_SVID_OFFSET 9 -+#define RTL8367C_ACT27_SVID_MASK 0x200 -+#define RTL8367C_ACT27_CVID_OFFSET 8 -+#define RTL8367C_ACT27_CVID_MASK 0x100 -+#define RTL8367C_OP26_NOT_OFFSET 6 -+#define RTL8367C_OP26_NOT_MASK 0x40 -+#define RTL8367C_ACT26_GPIO_OFFSET 5 -+#define RTL8367C_ACT26_GPIO_MASK 0x20 -+#define RTL8367C_ACT26_FORWARD_OFFSET 4 -+#define RTL8367C_ACT26_FORWARD_MASK 0x10 -+#define RTL8367C_ACT26_POLICING_OFFSET 3 -+#define RTL8367C_ACT26_POLICING_MASK 0x8 -+#define RTL8367C_ACT26_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT26_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT26_SVID_OFFSET 1 -+#define RTL8367C_ACT26_SVID_MASK 0x2 -+#define RTL8367C_ACT26_CVID_OFFSET 0 -+#define RTL8367C_ACT26_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL14 0x0622 -+#define RTL8367C_OP29_NOT_OFFSET 14 -+#define RTL8367C_OP29_NOT_MASK 0x4000 -+#define RTL8367C_ACT29_GPIO_OFFSET 13 -+#define RTL8367C_ACT29_GPIO_MASK 0x2000 -+#define RTL8367C_ACT29_FORWARD_OFFSET 12 -+#define RTL8367C_ACT29_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT29_POLICING_OFFSET 11 -+#define RTL8367C_ACT29_POLICING_MASK 0x800 -+#define RTL8367C_ACT29_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT29_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT29_SVID_OFFSET 9 -+#define RTL8367C_ACT29_SVID_MASK 0x200 -+#define RTL8367C_ACT29_CVID_OFFSET 8 -+#define RTL8367C_ACT29_CVID_MASK 0x100 -+#define RTL8367C_OP28_NOT_OFFSET 6 -+#define RTL8367C_OP28_NOT_MASK 0x40 -+#define RTL8367C_ACT28_GPIO_OFFSET 5 -+#define RTL8367C_ACT28_GPIO_MASK 0x20 -+#define RTL8367C_ACT28_FORWARD_OFFSET 4 -+#define RTL8367C_ACT28_FORWARD_MASK 0x10 -+#define RTL8367C_ACT28_POLICING_OFFSET 3 -+#define RTL8367C_ACT28_POLICING_MASK 0x8 -+#define RTL8367C_ACT28_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT28_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT28_SVID_OFFSET 1 -+#define RTL8367C_ACT28_SVID_MASK 0x2 -+#define RTL8367C_ACT28_CVID_OFFSET 0 -+#define RTL8367C_ACT28_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL15 0x0623 -+#define RTL8367C_OP31_NOT_OFFSET 14 -+#define RTL8367C_OP31_NOT_MASK 0x4000 -+#define RTL8367C_ACT31_GPIO_OFFSET 13 -+#define RTL8367C_ACT31_GPIO_MASK 0x2000 -+#define RTL8367C_ACT31_FORWARD_OFFSET 12 -+#define RTL8367C_ACT31_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT31_POLICING_OFFSET 11 -+#define RTL8367C_ACT31_POLICING_MASK 0x800 -+#define RTL8367C_ACT31_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT31_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT31_SVID_OFFSET 9 -+#define RTL8367C_ACT31_SVID_MASK 0x200 -+#define RTL8367C_ACT31_CVID_OFFSET 8 -+#define RTL8367C_ACT31_CVID_MASK 0x100 -+#define RTL8367C_OP30_NOT_OFFSET 6 -+#define RTL8367C_OP30_NOT_MASK 0x40 -+#define RTL8367C_ACT30_GPIO_OFFSET 5 -+#define RTL8367C_ACT30_GPIO_MASK 0x20 -+#define RTL8367C_ACT30_FORWARD_OFFSET 4 -+#define RTL8367C_ACT30_FORWARD_MASK 0x10 -+#define RTL8367C_ACT30_POLICING_OFFSET 3 -+#define RTL8367C_ACT30_POLICING_MASK 0x8 -+#define RTL8367C_ACT30_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT30_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT30_SVID_OFFSET 1 -+#define RTL8367C_ACT30_SVID_MASK 0x2 -+#define RTL8367C_ACT30_CVID_OFFSET 0 -+#define RTL8367C_ACT30_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL16 0x0624 -+#define RTL8367C_OP33_NOT_OFFSET 14 -+#define RTL8367C_OP33_NOT_MASK 0x4000 -+#define RTL8367C_ACT33_GPIO_OFFSET 13 -+#define RTL8367C_ACT33_GPIO_MASK 0x2000 -+#define RTL8367C_ACT33_FORWARD_OFFSET 12 -+#define RTL8367C_ACT33_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT33_POLICING_OFFSET 11 -+#define RTL8367C_ACT33_POLICING_MASK 0x800 -+#define RTL8367C_ACT33_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT33_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT33_SVID_OFFSET 9 -+#define RTL8367C_ACT33_SVID_MASK 0x200 -+#define RTL8367C_ACT33_CVID_OFFSET 8 -+#define RTL8367C_ACT33_CVID_MASK 0x100 -+#define RTL8367C_OP32_NOT_OFFSET 6 -+#define RTL8367C_OP32_NOT_MASK 0x40 -+#define RTL8367C_ACT32_GPIO_OFFSET 5 -+#define RTL8367C_ACT32_GPIO_MASK 0x20 -+#define RTL8367C_ACT32_FORWARD_OFFSET 4 -+#define RTL8367C_ACT32_FORWARD_MASK 0x10 -+#define RTL8367C_ACT32_POLICING_OFFSET 3 -+#define RTL8367C_ACT32_POLICING_MASK 0x8 -+#define RTL8367C_ACT32_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT32_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT32_SVID_OFFSET 1 -+#define RTL8367C_ACT32_SVID_MASK 0x2 -+#define RTL8367C_ACT32_CVID_OFFSET 0 -+#define RTL8367C_ACT32_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL17 0x0625 -+#define RTL8367C_OP35_NOT_OFFSET 14 -+#define RTL8367C_OP35_NOT_MASK 0x4000 -+#define RTL8367C_ACT35_GPIO_OFFSET 13 -+#define RTL8367C_ACT35_GPIO_MASK 0x2000 -+#define RTL8367C_ACT35_FORWARD_OFFSET 12 -+#define RTL8367C_ACT35_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT35_POLICING_OFFSET 11 -+#define RTL8367C_ACT35_POLICING_MASK 0x800 -+#define RTL8367C_ACT35_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT35_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT35_SVID_OFFSET 9 -+#define RTL8367C_ACT35_SVID_MASK 0x200 -+#define RTL8367C_ACT35_CVID_OFFSET 8 -+#define RTL8367C_ACT35_CVID_MASK 0x100 -+#define RTL8367C_OP34_NOT_OFFSET 6 -+#define RTL8367C_OP34_NOT_MASK 0x40 -+#define RTL8367C_ACT34_GPIO_OFFSET 5 -+#define RTL8367C_ACT34_GPIO_MASK 0x20 -+#define RTL8367C_ACT34_FORWARD_OFFSET 4 -+#define RTL8367C_ACT34_FORWARD_MASK 0x10 -+#define RTL8367C_ACT34_POLICING_OFFSET 3 -+#define RTL8367C_ACT34_POLICING_MASK 0x8 -+#define RTL8367C_ACT34_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT34_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT34_SVID_OFFSET 1 -+#define RTL8367C_ACT34_SVID_MASK 0x2 -+#define RTL8367C_ACT34_CVID_OFFSET 0 -+#define RTL8367C_ACT34_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL18 0x0626 -+#define RTL8367C_OP37_NOT_OFFSET 14 -+#define RTL8367C_OP37_NOT_MASK 0x4000 -+#define RTL8367C_ACT37_GPIO_OFFSET 13 -+#define RTL8367C_ACT37_GPIO_MASK 0x2000 -+#define RTL8367C_ACT37_FORWARD_OFFSET 12 -+#define RTL8367C_ACT37_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT37_POLICING_OFFSET 11 -+#define RTL8367C_ACT37_POLICING_MASK 0x800 -+#define RTL8367C_ACT37_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT37_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT37_SVID_OFFSET 9 -+#define RTL8367C_ACT37_SVID_MASK 0x200 -+#define RTL8367C_ACT37_CVID_OFFSET 8 -+#define RTL8367C_ACT37_CVID_MASK 0x100 -+#define RTL8367C_OP36_NOT_OFFSET 6 -+#define RTL8367C_OP36_NOT_MASK 0x40 -+#define RTL8367C_ACT36_GPIO_OFFSET 5 -+#define RTL8367C_ACT36_GPIO_MASK 0x20 -+#define RTL8367C_ACT36_FORWARD_OFFSET 4 -+#define RTL8367C_ACT36_FORWARD_MASK 0x10 -+#define RTL8367C_ACT36_POLICING_OFFSET 3 -+#define RTL8367C_ACT36_POLICING_MASK 0x8 -+#define RTL8367C_ACT36_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT36_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT36_SVID_OFFSET 1 -+#define RTL8367C_ACT36_SVID_MASK 0x2 -+#define RTL8367C_ACT36_CVID_OFFSET 0 -+#define RTL8367C_ACT36_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL19 0x0627 -+#define RTL8367C_OP39_NOT_OFFSET 14 -+#define RTL8367C_OP39_NOT_MASK 0x4000 -+#define RTL8367C_ACT39_GPIO_OFFSET 13 -+#define RTL8367C_ACT39_GPIO_MASK 0x2000 -+#define RTL8367C_ACT39_FORWARD_OFFSET 12 -+#define RTL8367C_ACT39_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT39_POLICING_OFFSET 11 -+#define RTL8367C_ACT39_POLICING_MASK 0x800 -+#define RTL8367C_ACT39_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT39_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT39_SVID_OFFSET 9 -+#define RTL8367C_ACT39_SVID_MASK 0x200 -+#define RTL8367C_ACT39_CVID_OFFSET 8 -+#define RTL8367C_ACT39_CVID_MASK 0x100 -+#define RTL8367C_OP38_NOT_OFFSET 6 -+#define RTL8367C_OP38_NOT_MASK 0x40 -+#define RTL8367C_ACT38_GPIO_OFFSET 5 -+#define RTL8367C_ACT38_GPIO_MASK 0x20 -+#define RTL8367C_ACT38_FORWARD_OFFSET 4 -+#define RTL8367C_ACT38_FORWARD_MASK 0x10 -+#define RTL8367C_ACT38_POLICING_OFFSET 3 -+#define RTL8367C_ACT38_POLICING_MASK 0x8 -+#define RTL8367C_ACT38_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT38_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT38_SVID_OFFSET 1 -+#define RTL8367C_ACT38_SVID_MASK 0x2 -+#define RTL8367C_ACT38_CVID_OFFSET 0 -+#define RTL8367C_ACT38_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL20 0x0628 -+#define RTL8367C_OP41_NOT_OFFSET 14 -+#define RTL8367C_OP41_NOT_MASK 0x4000 -+#define RTL8367C_ACT41_GPIO_OFFSET 13 -+#define RTL8367C_ACT41_GPIO_MASK 0x2000 -+#define RTL8367C_ACT41_FORWARD_OFFSET 12 -+#define RTL8367C_ACT41_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT41_POLICING_OFFSET 11 -+#define RTL8367C_ACT41_POLICING_MASK 0x800 -+#define RTL8367C_ACT41_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT41_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT41_SVID_OFFSET 9 -+#define RTL8367C_ACT41_SVID_MASK 0x200 -+#define RTL8367C_ACT41_CVID_OFFSET 8 -+#define RTL8367C_ACT41_CVID_MASK 0x100 -+#define RTL8367C_OP40_NOT_OFFSET 6 -+#define RTL8367C_OP40_NOT_MASK 0x40 -+#define RTL8367C_ACT40_GPIO_OFFSET 5 -+#define RTL8367C_ACT40_GPIO_MASK 0x20 -+#define RTL8367C_ACT40_FORWARD_OFFSET 4 -+#define RTL8367C_ACT40_FORWARD_MASK 0x10 -+#define RTL8367C_ACT40_POLICING_OFFSET 3 -+#define RTL8367C_ACT40_POLICING_MASK 0x8 -+#define RTL8367C_ACT40_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT40_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT40_SVID_OFFSET 1 -+#define RTL8367C_ACT40_SVID_MASK 0x2 -+#define RTL8367C_ACT40_CVID_OFFSET 0 -+#define RTL8367C_ACT40_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL21 0x0629 -+#define RTL8367C_OP43_NOT_OFFSET 14 -+#define RTL8367C_OP43_NOT_MASK 0x4000 -+#define RTL8367C_ACT43_GPIO_OFFSET 13 -+#define RTL8367C_ACT43_GPIO_MASK 0x2000 -+#define RTL8367C_ACT43_FORWARD_OFFSET 12 -+#define RTL8367C_ACT43_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT43_POLICING_OFFSET 11 -+#define RTL8367C_ACT43_POLICING_MASK 0x800 -+#define RTL8367C_ACT43_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT43_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT43_SVID_OFFSET 9 -+#define RTL8367C_ACT43_SVID_MASK 0x200 -+#define RTL8367C_ACT43_CVID_OFFSET 8 -+#define RTL8367C_ACT43_CVID_MASK 0x100 -+#define RTL8367C_OP42_NOT_OFFSET 6 -+#define RTL8367C_OP42_NOT_MASK 0x40 -+#define RTL8367C_ACT42_GPIO_OFFSET 5 -+#define RTL8367C_ACT42_GPIO_MASK 0x20 -+#define RTL8367C_ACT42_FORWARD_OFFSET 4 -+#define RTL8367C_ACT42_FORWARD_MASK 0x10 -+#define RTL8367C_ACT42_POLICING_OFFSET 3 -+#define RTL8367C_ACT42_POLICING_MASK 0x8 -+#define RTL8367C_ACT42_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT42_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT42_SVID_OFFSET 1 -+#define RTL8367C_ACT42_SVID_MASK 0x2 -+#define RTL8367C_ACT42_CVID_OFFSET 0 -+#define RTL8367C_ACT42_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL22 0x062a -+#define RTL8367C_OP45_NOT_OFFSET 14 -+#define RTL8367C_OP45_NOT_MASK 0x4000 -+#define RTL8367C_ACT45_GPIO_OFFSET 13 -+#define RTL8367C_ACT45_GPIO_MASK 0x2000 -+#define RTL8367C_ACT45_FORWARD_OFFSET 12 -+#define RTL8367C_ACT45_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT45_POLICING_OFFSET 11 -+#define RTL8367C_ACT45_POLICING_MASK 0x800 -+#define RTL8367C_ACT45_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT45_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT45_SVID_OFFSET 9 -+#define RTL8367C_ACT45_SVID_MASK 0x200 -+#define RTL8367C_ACT45_CVID_OFFSET 8 -+#define RTL8367C_ACT45_CVID_MASK 0x100 -+#define RTL8367C_OP44_NOT_OFFSET 6 -+#define RTL8367C_OP44_NOT_MASK 0x40 -+#define RTL8367C_ACT44_GPIO_OFFSET 5 -+#define RTL8367C_ACT44_GPIO_MASK 0x20 -+#define RTL8367C_ACT44_FORWARD_OFFSET 4 -+#define RTL8367C_ACT44_FORWARD_MASK 0x10 -+#define RTL8367C_ACT44_POLICING_OFFSET 3 -+#define RTL8367C_ACT44_POLICING_MASK 0x8 -+#define RTL8367C_ACT44_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT44_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT44_SVID_OFFSET 1 -+#define RTL8367C_ACT44_SVID_MASK 0x2 -+#define RTL8367C_ACT44_CVID_OFFSET 0 -+#define RTL8367C_ACT44_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL23 0x062b -+#define RTL8367C_OP47_NOT_OFFSET 14 -+#define RTL8367C_OP47_NOT_MASK 0x4000 -+#define RTL8367C_ACT47_GPIO_OFFSET 13 -+#define RTL8367C_ACT47_GPIO_MASK 0x2000 -+#define RTL8367C_ACT47_FORWARD_OFFSET 12 -+#define RTL8367C_ACT47_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT47_POLICING_OFFSET 11 -+#define RTL8367C_ACT47_POLICING_MASK 0x800 -+#define RTL8367C_ACT47_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT47_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT47_SVID_OFFSET 9 -+#define RTL8367C_ACT47_SVID_MASK 0x200 -+#define RTL8367C_ACT47_CVID_OFFSET 8 -+#define RTL8367C_ACT47_CVID_MASK 0x100 -+#define RTL8367C_OP46_NOT_OFFSET 6 -+#define RTL8367C_OP46_NOT_MASK 0x40 -+#define RTL8367C_ACT46_GPIO_OFFSET 5 -+#define RTL8367C_ACT46_GPIO_MASK 0x20 -+#define RTL8367C_ACT46_FORWARD_OFFSET 4 -+#define RTL8367C_ACT46_FORWARD_MASK 0x10 -+#define RTL8367C_ACT46_POLICING_OFFSET 3 -+#define RTL8367C_ACT46_POLICING_MASK 0x8 -+#define RTL8367C_ACT46_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT46_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT46_SVID_OFFSET 1 -+#define RTL8367C_ACT46_SVID_MASK 0x2 -+#define RTL8367C_ACT46_CVID_OFFSET 0 -+#define RTL8367C_ACT46_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL24 0x062c -+#define RTL8367C_OP49_NOT_OFFSET 14 -+#define RTL8367C_OP49_NOT_MASK 0x4000 -+#define RTL8367C_ACT49_GPIO_OFFSET 13 -+#define RTL8367C_ACT49_GPIO_MASK 0x2000 -+#define RTL8367C_ACT49_FORWARD_OFFSET 12 -+#define RTL8367C_ACT49_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT49_POLICING_OFFSET 11 -+#define RTL8367C_ACT49_POLICING_MASK 0x800 -+#define RTL8367C_ACT49_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT49_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT49_SVID_OFFSET 9 -+#define RTL8367C_ACT49_SVID_MASK 0x200 -+#define RTL8367C_ACT49_CVID_OFFSET 8 -+#define RTL8367C_ACT49_CVID_MASK 0x100 -+#define RTL8367C_OP48_NOT_OFFSET 6 -+#define RTL8367C_OP48_NOT_MASK 0x40 -+#define RTL8367C_ACT48_GPIO_OFFSET 5 -+#define RTL8367C_ACT48_GPIO_MASK 0x20 -+#define RTL8367C_ACT48_FORWARD_OFFSET 4 -+#define RTL8367C_ACT48_FORWARD_MASK 0x10 -+#define RTL8367C_ACT48_POLICING_OFFSET 3 -+#define RTL8367C_ACT48_POLICING_MASK 0x8 -+#define RTL8367C_ACT48_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT48_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT48_SVID_OFFSET 1 -+#define RTL8367C_ACT48_SVID_MASK 0x2 -+#define RTL8367C_ACT48_CVID_OFFSET 0 -+#define RTL8367C_ACT48_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL25 0x062d -+#define RTL8367C_OP51_NOT_OFFSET 14 -+#define RTL8367C_OP51_NOT_MASK 0x4000 -+#define RTL8367C_ACT51_GPIO_OFFSET 13 -+#define RTL8367C_ACT51_GPIO_MASK 0x2000 -+#define RTL8367C_ACT51_FORWARD_OFFSET 12 -+#define RTL8367C_ACT51_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT51_POLICING_OFFSET 11 -+#define RTL8367C_ACT51_POLICING_MASK 0x800 -+#define RTL8367C_ACT51_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT51_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT51_SVID_OFFSET 9 -+#define RTL8367C_ACT51_SVID_MASK 0x200 -+#define RTL8367C_ACT51_CVID_OFFSET 8 -+#define RTL8367C_ACT51_CVID_MASK 0x100 -+#define RTL8367C_OP50_NOT_OFFSET 6 -+#define RTL8367C_OP50_NOT_MASK 0x40 -+#define RTL8367C_ACT50_GPIO_OFFSET 5 -+#define RTL8367C_ACT50_GPIO_MASK 0x20 -+#define RTL8367C_ACT50_FORWARD_OFFSET 4 -+#define RTL8367C_ACT50_FORWARD_MASK 0x10 -+#define RTL8367C_ACT50_POLICING_OFFSET 3 -+#define RTL8367C_ACT50_POLICING_MASK 0x8 -+#define RTL8367C_ACT50_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT50_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT50_SVID_OFFSET 1 -+#define RTL8367C_ACT50_SVID_MASK 0x2 -+#define RTL8367C_ACT50_CVID_OFFSET 0 -+#define RTL8367C_ACT50_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL26 0x062e -+#define RTL8367C_OP53_NOT_OFFSET 14 -+#define RTL8367C_OP53_NOT_MASK 0x4000 -+#define RTL8367C_ACT53_GPIO_OFFSET 13 -+#define RTL8367C_ACT53_GPIO_MASK 0x2000 -+#define RTL8367C_ACT53_FORWARD_OFFSET 12 -+#define RTL8367C_ACT53_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT53_POLICING_OFFSET 11 -+#define RTL8367C_ACT53_POLICING_MASK 0x800 -+#define RTL8367C_ACT53_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT53_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT53_SVID_OFFSET 9 -+#define RTL8367C_ACT53_SVID_MASK 0x200 -+#define RTL8367C_ACT53_CVID_OFFSET 8 -+#define RTL8367C_ACT53_CVID_MASK 0x100 -+#define RTL8367C_OP52_NOT_OFFSET 6 -+#define RTL8367C_OP52_NOT_MASK 0x40 -+#define RTL8367C_ACT52_GPIO_OFFSET 5 -+#define RTL8367C_ACT52_GPIO_MASK 0x20 -+#define RTL8367C_ACT52_FORWARD_OFFSET 4 -+#define RTL8367C_ACT52_FORWARD_MASK 0x10 -+#define RTL8367C_ACT52_POLICING_OFFSET 3 -+#define RTL8367C_ACT52_POLICING_MASK 0x8 -+#define RTL8367C_ACT52_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT52_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT52_SVID_OFFSET 1 -+#define RTL8367C_ACT52_SVID_MASK 0x2 -+#define RTL8367C_ACT52_CVID_OFFSET 0 -+#define RTL8367C_ACT52_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL27 0x062f -+#define RTL8367C_OP55_NOT_OFFSET 14 -+#define RTL8367C_OP55_NOT_MASK 0x4000 -+#define RTL8367C_ACT55_GPIO_OFFSET 13 -+#define RTL8367C_ACT55_GPIO_MASK 0x2000 -+#define RTL8367C_ACT55_FORWARD_OFFSET 12 -+#define RTL8367C_ACT55_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT55_POLICING_OFFSET 11 -+#define RTL8367C_ACT55_POLICING_MASK 0x800 -+#define RTL8367C_ACT55_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT55_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT55_SVID_OFFSET 9 -+#define RTL8367C_ACT55_SVID_MASK 0x200 -+#define RTL8367C_ACT55_CVID_OFFSET 8 -+#define RTL8367C_ACT55_CVID_MASK 0x100 -+#define RTL8367C_OP54_NOT_OFFSET 6 -+#define RTL8367C_OP54_NOT_MASK 0x40 -+#define RTL8367C_ACT54_GPIO_OFFSET 5 -+#define RTL8367C_ACT54_GPIO_MASK 0x20 -+#define RTL8367C_ACT54_FORWARD_OFFSET 4 -+#define RTL8367C_ACT54_FORWARD_MASK 0x10 -+#define RTL8367C_ACT54_POLICING_OFFSET 3 -+#define RTL8367C_ACT54_POLICING_MASK 0x8 -+#define RTL8367C_ACT54_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT54_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT54_SVID_OFFSET 1 -+#define RTL8367C_ACT54_SVID_MASK 0x2 -+#define RTL8367C_ACT54_CVID_OFFSET 0 -+#define RTL8367C_ACT54_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL28 0x0630 -+#define RTL8367C_OP57_NOT_OFFSET 14 -+#define RTL8367C_OP57_NOT_MASK 0x4000 -+#define RTL8367C_ACT57_GPIO_OFFSET 13 -+#define RTL8367C_ACT57_GPIO_MASK 0x2000 -+#define RTL8367C_ACT57_FORWARD_OFFSET 12 -+#define RTL8367C_ACT57_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT57_POLICING_OFFSET 11 -+#define RTL8367C_ACT57_POLICING_MASK 0x800 -+#define RTL8367C_ACT57_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT57_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT57_SVID_OFFSET 9 -+#define RTL8367C_ACT57_SVID_MASK 0x200 -+#define RTL8367C_ACT57_CVID_OFFSET 8 -+#define RTL8367C_ACT57_CVID_MASK 0x100 -+#define RTL8367C_OP56_NOT_OFFSET 6 -+#define RTL8367C_OP56_NOT_MASK 0x40 -+#define RTL8367C_ACT56_GPIO_OFFSET 5 -+#define RTL8367C_ACT56_GPIO_MASK 0x20 -+#define RTL8367C_ACT56_FORWARD_OFFSET 4 -+#define RTL8367C_ACT56_FORWARD_MASK 0x10 -+#define RTL8367C_ACT56_POLICING_OFFSET 3 -+#define RTL8367C_ACT56_POLICING_MASK 0x8 -+#define RTL8367C_ACT56_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT56_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT56_SVID_OFFSET 1 -+#define RTL8367C_ACT56_SVID_MASK 0x2 -+#define RTL8367C_ACT56_CVID_OFFSET 0 -+#define RTL8367C_ACT56_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL29 0x0631 -+#define RTL8367C_OP59_NOT_OFFSET 14 -+#define RTL8367C_OP59_NOT_MASK 0x4000 -+#define RTL8367C_ACT59_GPIO_OFFSET 13 -+#define RTL8367C_ACT59_GPIO_MASK 0x2000 -+#define RTL8367C_ACT59_FORWARD_OFFSET 12 -+#define RTL8367C_ACT59_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT59_POLICING_OFFSET 11 -+#define RTL8367C_ACT59_POLICING_MASK 0x800 -+#define RTL8367C_ACT59_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT59_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT59_SVID_OFFSET 9 -+#define RTL8367C_ACT59_SVID_MASK 0x200 -+#define RTL8367C_ACT59_CVID_OFFSET 8 -+#define RTL8367C_ACT59_CVID_MASK 0x100 -+#define RTL8367C_OP58_NOT_OFFSET 6 -+#define RTL8367C_OP58_NOT_MASK 0x40 -+#define RTL8367C_ACT58_GPIO_OFFSET 5 -+#define RTL8367C_ACT58_GPIO_MASK 0x20 -+#define RTL8367C_ACT58_FORWARD_OFFSET 4 -+#define RTL8367C_ACT58_FORWARD_MASK 0x10 -+#define RTL8367C_ACT58_POLICING_OFFSET 3 -+#define RTL8367C_ACT58_POLICING_MASK 0x8 -+#define RTL8367C_ACT58_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT58_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT58_SVID_OFFSET 1 -+#define RTL8367C_ACT58_SVID_MASK 0x2 -+#define RTL8367C_ACT58_CVID_OFFSET 0 -+#define RTL8367C_ACT58_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL30 0x0632 -+#define RTL8367C_OP61_NOT_OFFSET 14 -+#define RTL8367C_OP61_NOT_MASK 0x4000 -+#define RTL8367C_ACT61_GPIO_OFFSET 13 -+#define RTL8367C_ACT61_GPIO_MASK 0x2000 -+#define RTL8367C_ACT61_FORWARD_OFFSET 12 -+#define RTL8367C_ACT61_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT61_POLICING_OFFSET 11 -+#define RTL8367C_ACT61_POLICING_MASK 0x800 -+#define RTL8367C_ACT61_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT61_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT61_SVID_OFFSET 9 -+#define RTL8367C_ACT61_SVID_MASK 0x200 -+#define RTL8367C_ACT61_CVID_OFFSET 8 -+#define RTL8367C_ACT61_CVID_MASK 0x100 -+#define RTL8367C_OP60_NOT_OFFSET 6 -+#define RTL8367C_OP60_NOT_MASK 0x40 -+#define RTL8367C_ACT60_GPIO_OFFSET 5 -+#define RTL8367C_ACT60_GPIO_MASK 0x20 -+#define RTL8367C_ACT60_FORWARD_OFFSET 4 -+#define RTL8367C_ACT60_FORWARD_MASK 0x10 -+#define RTL8367C_ACT60_POLICING_OFFSET 3 -+#define RTL8367C_ACT60_POLICING_MASK 0x8 -+#define RTL8367C_ACT60_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT60_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT60_SVID_OFFSET 1 -+#define RTL8367C_ACT60_SVID_MASK 0x2 -+#define RTL8367C_ACT60_CVID_OFFSET 0 -+#define RTL8367C_ACT60_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL31 0x0633 -+#define RTL8367C_OP63_NOT_OFFSET 14 -+#define RTL8367C_OP63_NOT_MASK 0x4000 -+#define RTL8367C_ACT63_GPIO_OFFSET 13 -+#define RTL8367C_ACT63_GPIO_MASK 0x2000 -+#define RTL8367C_ACT63_FORWARD_OFFSET 12 -+#define RTL8367C_ACT63_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT63_POLICING_OFFSET 11 -+#define RTL8367C_ACT63_POLICING_MASK 0x800 -+#define RTL8367C_ACT63_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT63_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT63_SVID_OFFSET 9 -+#define RTL8367C_ACT63_SVID_MASK 0x200 -+#define RTL8367C_ACT63_CVID_OFFSET 8 -+#define RTL8367C_ACT63_CVID_MASK 0x100 -+#define RTL8367C_OP62_NOT_OFFSET 6 -+#define RTL8367C_OP62_NOT_MASK 0x40 -+#define RTL8367C_ACT62_GPIO_OFFSET 5 -+#define RTL8367C_ACT62_GPIO_MASK 0x20 -+#define RTL8367C_ACT62_FORWARD_OFFSET 4 -+#define RTL8367C_ACT62_FORWARD_MASK 0x10 -+#define RTL8367C_ACT62_POLICING_OFFSET 3 -+#define RTL8367C_ACT62_POLICING_MASK 0x8 -+#define RTL8367C_ACT62_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT62_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT62_SVID_OFFSET 1 -+#define RTL8367C_ACT62_SVID_MASK 0x2 -+#define RTL8367C_ACT62_CVID_OFFSET 0 -+#define RTL8367C_ACT62_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL0 0x0635 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL1 0x0636 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL2 0x0637 -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY0_CTRL2_OFFSET 0 -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY0_CTRL2_MASK 0x3 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY1_CTRL0 0x0638 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY1_CTRL1 0x0639 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY1_CTRL2 0x063a -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY1_CTRL2_OFFSET 0 -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY1_CTRL2_MASK 0x3 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY2_CTRL0 0x063b -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY2_CTRL1 0x063c -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY2_CTRL2 0x063d -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY2_CTRL2_OFFSET 0 -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY2_CTRL2_MASK 0x3 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY3_CTRL0 0x063e -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY3_CTRL1 0x063f -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY3_CTRL2 0x0640 -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY3_CTRL2_OFFSET 0 -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY3_CTRL2_MASK 0x3 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY4_CTRL0 0x0641 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY4_CTRL1 0x0642 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY4_CTRL2 0x0643 -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY4_CTRL2_OFFSET 0 -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY4_CTRL2_MASK 0x3 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY5_CTRL0 0x0644 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY5_CTRL1 0x0645 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY5_CTRL2 0x0646 -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY5_CTRL2_OFFSET 0 -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY5_CTRL2_MASK 0x3 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY6_CTRL0 0x0647 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY6_CTRL1 0x0648 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY6_CTRL2 0x0649 -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY6_CTRL2_OFFSET 0 -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY6_CTRL2_MASK 0x3 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY7_CTRL0 0x064a -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY7_CTRL1 0x064b -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY7_CTRL2 0x064c -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY7_CTRL2_OFFSET 0 -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY7_CTRL2_MASK 0x3 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY8_CTRL0 0x064d -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY8_CTRL1 0x064e -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY8_CTRL2 0x064f -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY8_CTRL2_OFFSET 0 -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY8_CTRL2_MASK 0x3 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY9_CTRL0 0x0650 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY9_CTRL1 0x0651 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY9_CTRL2 0x0652 -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY9_CTRL2_OFFSET 0 -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY9_CTRL2_MASK 0x3 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY10_CTRL0 0x0653 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY10_CTRL1 0x0654 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY10_CTRL2 0x0655 -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY10_CTRL2_OFFSET 0 -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY10_CTRL2_MASK 0x3 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY11_CTRL0 0x0656 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY11_CTRL1 0x0657 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY11_CTRL2 0x0658 -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY11_CTRL2_OFFSET 0 -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY11_CTRL2_MASK 0x3 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY12_CTRL0 0x0659 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY12_CTRL1 0x065a -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY12_CTRL2 0x065b -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY12_CTRL2_OFFSET 0 -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY12_CTRL2_MASK 0x3 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY13_CTRL0 0x065c -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY13_CTRL1 0x065d -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY13_CTRL2 0x065e -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY13_CTRL2_OFFSET 0 -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY13_CTRL2_MASK 0x3 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY14_CTRL0 0x065f -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY14_CTRL1 0x0660 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY14_CTRL2 0x0661 -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY14_CTRL2_OFFSET 0 -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY14_CTRL2_MASK 0x3 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY15_CTRL0 0x0662 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY15_CTRL1 0x0663 -+ -+#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY15_CTRL2 0x0664 -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY15_CTRL2_OFFSET 0 -+#define RTL8367C_ACL_SDPORT_RANGE_ENTRY15_CTRL2_MASK 0x3 -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY0_CTRL0 0x0665 -+#define RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL0_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL0_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY0_CTRL1 0x0666 -+#define RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_TYPE_OFFSET 12 -+#define RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_TYPE_MASK 0x3000 -+#define RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_HIGH_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_HIGH_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY1_CTRL0 0x0667 -+#define RTL8367C_ACL_VID_RANGE_ENTRY1_CTRL0_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY1_CTRL0_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY1_CTRL1 0x0668 -+#define RTL8367C_ACL_VID_RANGE_ENTRY1_CTRL1_CHECK1_TYPE_OFFSET 12 -+#define RTL8367C_ACL_VID_RANGE_ENTRY1_CTRL1_CHECK1_TYPE_MASK 0x3000 -+#define RTL8367C_ACL_VID_RANGE_ENTRY1_CTRL1_CHECK1_HIGH_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY1_CTRL1_CHECK1_HIGH_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY2_CTRL0 0x0669 -+#define RTL8367C_ACL_VID_RANGE_ENTRY2_CTRL0_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY2_CTRL0_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY2_CTRL1 0x066a -+#define RTL8367C_ACL_VID_RANGE_ENTRY2_CTRL1_CHECK2_TYPE_OFFSET 12 -+#define RTL8367C_ACL_VID_RANGE_ENTRY2_CTRL1_CHECK2_TYPE_MASK 0x3000 -+#define RTL8367C_ACL_VID_RANGE_ENTRY2_CTRL1_CHECK2_HIGH_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY2_CTRL1_CHECK2_HIGH_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY3_CTRL0 0x066b -+#define RTL8367C_ACL_VID_RANGE_ENTRY3_CTRL0_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY3_CTRL0_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY3_CTRL1 0x066c -+#define RTL8367C_ACL_VID_RANGE_ENTRY3_CTRL1_CHECK3_TYPE_OFFSET 12 -+#define RTL8367C_ACL_VID_RANGE_ENTRY3_CTRL1_CHECK3_TYPE_MASK 0x3000 -+#define RTL8367C_ACL_VID_RANGE_ENTRY3_CTRL1_CHECK3_HIGH_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY3_CTRL1_CHECK3_HIGH_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY4_CTRL0 0x066d -+#define RTL8367C_ACL_VID_RANGE_ENTRY4_CTRL0_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY4_CTRL0_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY4_CTRL1 0x066e -+#define RTL8367C_ACL_VID_RANGE_ENTRY4_CTRL1_CHECK4_TYPE_OFFSET 12 -+#define RTL8367C_ACL_VID_RANGE_ENTRY4_CTRL1_CHECK4_TYPE_MASK 0x3000 -+#define RTL8367C_ACL_VID_RANGE_ENTRY4_CTRL1_CHECK4_HIGH_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY4_CTRL1_CHECK4_HIGH_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY5_CTRL0 0x066f -+#define RTL8367C_ACL_VID_RANGE_ENTRY5_CTRL0_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY5_CTRL0_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY5_CTRL1 0x0670 -+#define RTL8367C_ACL_VID_RANGE_ENTRY5_CTRL1_CHECK5_TYPE_OFFSET 12 -+#define RTL8367C_ACL_VID_RANGE_ENTRY5_CTRL1_CHECK5_TYPE_MASK 0x3000 -+#define RTL8367C_ACL_VID_RANGE_ENTRY5_CTRL1_CHECK5_HIGH_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY5_CTRL1_CHECK5_HIGH_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY6_CTRL0 0x0671 -+#define RTL8367C_ACL_VID_RANGE_ENTRY6_CTRL0_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY6_CTRL0_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY6_CTRL1 0x0672 -+#define RTL8367C_ACL_VID_RANGE_ENTRY6_CTRL1_CHECK6_TYPE_OFFSET 12 -+#define RTL8367C_ACL_VID_RANGE_ENTRY6_CTRL1_CHECK6_TYPE_MASK 0x3000 -+#define RTL8367C_ACL_VID_RANGE_ENTRY6_CTRL1_CHECK6_HIGH_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY6_CTRL1_CHECK6_HIGH_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY7_CTRL0 0x0673 -+#define RTL8367C_ACL_VID_RANGE_ENTRY7_CTRL0_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY7_CTRL0_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY7_CTRL1 0x0674 -+#define RTL8367C_ACL_VID_RANGE_ENTRY7_CTRL1_CHECK7_TYPE_OFFSET 12 -+#define RTL8367C_ACL_VID_RANGE_ENTRY7_CTRL1_CHECK7_TYPE_MASK 0x3000 -+#define RTL8367C_ACL_VID_RANGE_ENTRY7_CTRL1_CHECK7_HIGH_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY7_CTRL1_CHECK7_HIGH_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY8_CTRL0 0x0675 -+#define RTL8367C_ACL_VID_RANGE_ENTRY8_CTRL0_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY8_CTRL0_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY8_CTRL1 0x0676 -+#define RTL8367C_ACL_VID_RANGE_ENTRY8_CTRL1_CHECK8_TYPE_OFFSET 12 -+#define RTL8367C_ACL_VID_RANGE_ENTRY8_CTRL1_CHECK8_TYPE_MASK 0x3000 -+#define RTL8367C_ACL_VID_RANGE_ENTRY8_CTRL1_CHECK8_HIGH_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY8_CTRL1_CHECK8_HIGH_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY9_CTRL0 0x0677 -+#define RTL8367C_ACL_VID_RANGE_ENTRY9_CTRL0_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY9_CTRL0_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY9_CTRL1 0x0678 -+#define RTL8367C_ACL_VID_RANGE_ENTRY9_CTRL1_CHECK9_TYPE_OFFSET 12 -+#define RTL8367C_ACL_VID_RANGE_ENTRY9_CTRL1_CHECK9_TYPE_MASK 0x3000 -+#define RTL8367C_ACL_VID_RANGE_ENTRY9_CTRL1_CHECK9_HIGH_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY9_CTRL1_CHECK9_HIGH_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY10_CTRL0 0x0679 -+#define RTL8367C_ACL_VID_RANGE_ENTRY10_CTRL0_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY10_CTRL0_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY10_CTRL1 0x067a -+#define RTL8367C_ACL_VID_RANGE_ENTRY10_CTRL1_CHECK10_TYPE_OFFSET 12 -+#define RTL8367C_ACL_VID_RANGE_ENTRY10_CTRL1_CHECK10_TYPE_MASK 0x3000 -+#define RTL8367C_ACL_VID_RANGE_ENTRY10_CTRL1_CHECK10_HIGH_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY10_CTRL1_CHECK10_HIGH_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY11_CTRL0 0x067b -+#define RTL8367C_ACL_VID_RANGE_ENTRY11_CTRL0_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY11_CTRL0_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY11_CTRL1 0x067c -+#define RTL8367C_ACL_VID_RANGE_ENTRY11_CTRL1_CHECK11_TYPE_OFFSET 12 -+#define RTL8367C_ACL_VID_RANGE_ENTRY11_CTRL1_CHECK11_TYPE_MASK 0x3000 -+#define RTL8367C_ACL_VID_RANGE_ENTRY11_CTRL1_CHECK11_HIGH_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY11_CTRL1_CHECK11_HIGH_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY12_CTRL0 0x067d -+#define RTL8367C_ACL_VID_RANGE_ENTRY12_CTRL0_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY12_CTRL0_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY12_CTRL1 0x067e -+#define RTL8367C_ACL_VID_RANGE_ENTRY12_CTRL1_CHECK12_TYPE_OFFSET 12 -+#define RTL8367C_ACL_VID_RANGE_ENTRY12_CTRL1_CHECK12_TYPE_MASK 0x3000 -+#define RTL8367C_ACL_VID_RANGE_ENTRY12_CTRL1_CHECK12_HIGH_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY12_CTRL1_CHECK12_HIGH_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY13_CTRL0 0x067f -+#define RTL8367C_ACL_VID_RANGE_ENTRY13_CTRL0_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY13_CTRL0_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY13_CTRL1 0x0680 -+#define RTL8367C_ACL_VID_RANGE_ENTRY13_CTRL1_CHECK13_TYPE_OFFSET 12 -+#define RTL8367C_ACL_VID_RANGE_ENTRY13_CTRL1_CHECK13_TYPE_MASK 0x3000 -+#define RTL8367C_ACL_VID_RANGE_ENTRY13_CTRL1_CHECK13_HIGH_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY13_CTRL1_CHECK13_HIGH_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY14_CTRL0 0x0681 -+#define RTL8367C_ACL_VID_RANGE_ENTRY14_CTRL0_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY14_CTRL0_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY14_CTRL1 0x0682 -+#define RTL8367C_ACL_VID_RANGE_ENTRY14_CTRL1_CHECK14_TYPE_OFFSET 12 -+#define RTL8367C_ACL_VID_RANGE_ENTRY14_CTRL1_CHECK14_TYPE_MASK 0x3000 -+#define RTL8367C_ACL_VID_RANGE_ENTRY14_CTRL1_CHECK14_HIGH_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY14_CTRL1_CHECK14_HIGH_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY15_CTRL0 0x0683 -+#define RTL8367C_ACL_VID_RANGE_ENTRY15_CTRL0_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY15_CTRL0_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_VID_RANGE_ENTRY15_CTRL1 0x0684 -+#define RTL8367C_ACL_VID_RANGE_ENTRY15_CTRL1_CHECK15_TYPE_OFFSET 12 -+#define RTL8367C_ACL_VID_RANGE_ENTRY15_CTRL1_CHECK15_TYPE_MASK 0x3000 -+#define RTL8367C_ACL_VID_RANGE_ENTRY15_CTRL1_CHECK15_HIGH_OFFSET 0 -+#define RTL8367C_ACL_VID_RANGE_ENTRY15_CTRL1_CHECK15_HIGH_MASK 0xFFF -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL0 0x0685 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL1 0x0686 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL2 0x0687 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL3 0x0688 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL4 0x0689 -+#define RTL8367C_ACL_IP_RANGE_ENTRY0_CTRL4_OFFSET 0 -+#define RTL8367C_ACL_IP_RANGE_ENTRY0_CTRL4_MASK 0x7 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY1_CTRL0 0x068a -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY1_CTRL1 0x068b -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY1_CTRL2 0x068c -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY1_CTRL3 0x068d -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY1_CTRL4 0x068e -+#define RTL8367C_ACL_IP_RANGE_ENTRY1_CTRL4_OFFSET 0 -+#define RTL8367C_ACL_IP_RANGE_ENTRY1_CTRL4_MASK 0x7 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY2_CTRL0 0x068f -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY2_CTRL1 0x0690 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY2_CTRL2 0x0691 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY2_CTRL3 0x0692 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY2_CTRL4 0x0693 -+#define RTL8367C_ACL_IP_RANGE_ENTRY2_CTRL4_OFFSET 0 -+#define RTL8367C_ACL_IP_RANGE_ENTRY2_CTRL4_MASK 0x7 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY3_CTRL0 0x0694 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY3_CTRL1 0x0695 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY3_CTRL2 0x0696 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY3_CTRL3 0x0697 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY3_CTRL4 0x0698 -+#define RTL8367C_ACL_IP_RANGE_ENTRY3_CTRL4_OFFSET 0 -+#define RTL8367C_ACL_IP_RANGE_ENTRY3_CTRL4_MASK 0x7 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY4_CTRL0 0x0699 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY4_CTRL1 0x069a -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY4_CTRL2 0x069b -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY4_CTRL3 0x069c -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY4_CTRL4 0x069d -+#define RTL8367C_ACL_IP_RANGE_ENTRY4_CTRL4_OFFSET 0 -+#define RTL8367C_ACL_IP_RANGE_ENTRY4_CTRL4_MASK 0x7 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY5_CTRL0 0x069e -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY5_CTRL1 0x069f -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY5_CTRL2 0x06a0 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY5_CTRL3 0x06a1 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY5_CTRL4 0x06a2 -+#define RTL8367C_ACL_IP_RANGE_ENTRY5_CTRL4_OFFSET 0 -+#define RTL8367C_ACL_IP_RANGE_ENTRY5_CTRL4_MASK 0x7 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY6_CTRL0 0x06a3 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY6_CTRL1 0x06a4 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY6_CTRL2 0x06a5 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY6_CTRL3 0x06a6 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY6_CTRL4 0x06a7 -+#define RTL8367C_ACL_IP_RANGE_ENTRY6_CTRL4_OFFSET 0 -+#define RTL8367C_ACL_IP_RANGE_ENTRY6_CTRL4_MASK 0x7 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY7_CTRL0 0x06a8 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY7_CTRL1 0x06a9 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY7_CTRL2 0x06aa -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY7_CTRL3 0x06ab -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY7_CTRL4 0x06ac -+#define RTL8367C_ACL_IP_RANGE_ENTRY7_CTRL4_OFFSET 0 -+#define RTL8367C_ACL_IP_RANGE_ENTRY7_CTRL4_MASK 0x7 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY8_CTRL0 0x06ad -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY8_CTRL1 0x06ae -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY8_CTRL2 0x06af -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY8_CTRL3 0x06b0 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY8_CTRL4 0x06b1 -+#define RTL8367C_ACL_IP_RANGE_ENTRY8_CTRL4_OFFSET 0 -+#define RTL8367C_ACL_IP_RANGE_ENTRY8_CTRL4_MASK 0x7 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY9_CTRL0 0x06b2 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY9_CTRL1 0x06b3 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY9_CTRL2 0x06b4 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY9_CTRL3 0x06b5 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY9_CTRL4 0x06b6 -+#define RTL8367C_ACL_IP_RANGE_ENTRY9_CTRL4_OFFSET 0 -+#define RTL8367C_ACL_IP_RANGE_ENTRY9_CTRL4_MASK 0x7 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY10_CTRL0 0x06b7 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY10_CTRL1 0x06b8 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY10_CTRL2 0x06b9 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY10_CTRL3 0x06ba -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY10_CTRL4 0x06bb -+#define RTL8367C_ACL_IP_RANGE_ENTRY10_CTRL4_OFFSET 0 -+#define RTL8367C_ACL_IP_RANGE_ENTRY10_CTRL4_MASK 0x7 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY11_CTRL0 0x06bc -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY11_CTRL1 0x06bd -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY11_CTRL2 0x06be -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY11_CTRL3 0x06bf -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY11_CTRL4 0x06c0 -+#define RTL8367C_ACL_IP_RANGE_ENTRY11_CTRL4_OFFSET 0 -+#define RTL8367C_ACL_IP_RANGE_ENTRY11_CTRL4_MASK 0x7 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY12_CTRL0 0x06c1 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY12_CTRL1 0x06c2 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY12_CTRL2 0x06c3 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY12_CTRL3 0x06c4 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY12_CTRL4 0x06c5 -+#define RTL8367C_ACL_IP_RANGE_ENTRY12_CTRL4_OFFSET 0 -+#define RTL8367C_ACL_IP_RANGE_ENTRY12_CTRL4_MASK 0x7 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY13_CTRL0 0x06c6 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY13_CTRL1 0x06c7 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY13_CTRL2 0x06c8 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY13_CTRL3 0x06c9 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY13_CTRL4 0x06ca -+#define RTL8367C_ACL_IP_RANGE_ENTRY13_CTRL4_OFFSET 0 -+#define RTL8367C_ACL_IP_RANGE_ENTRY13_CTRL4_MASK 0x7 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY14_CTRL0 0x06cb -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY14_CTRL1 0x06cc -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY14_CTRL2 0x06cd -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY14_CTRL3 0x06ce -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY14_CTRL4 0x06cf -+#define RTL8367C_ACL_IP_RANGE_ENTRY14_CTRL4_OFFSET 0 -+#define RTL8367C_ACL_IP_RANGE_ENTRY14_CTRL4_MASK 0x7 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY15_CTRL0 0x06d0 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY15_CTRL1 0x06d1 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY15_CTRL2 0x06d2 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY15_CTRL3 0x06d3 -+ -+#define RTL8367C_REG_ACL_IP_RANGE_ENTRY15_CTRL4 0x06d4 -+#define RTL8367C_ACL_IP_RANGE_ENTRY15_CTRL4_OFFSET 0 -+#define RTL8367C_ACL_IP_RANGE_ENTRY15_CTRL4_MASK 0x7 -+ -+#define RTL8367C_REG_ACL_ENABLE 0x06d5 -+#define RTL8367C_PORT10_ENABLE_OFFSET 10 -+#define RTL8367C_PORT10_ENABLE_MASK 0x400 -+#define RTL8367C_PORT9_ENABLE_OFFSET 9 -+#define RTL8367C_PORT9_ENABLE_MASK 0x200 -+#define RTL8367C_PORT8_ENABLE_OFFSET 8 -+#define RTL8367C_PORT8_ENABLE_MASK 0x100 -+#define RTL8367C_PORT7_ENABLE_OFFSET 7 -+#define RTL8367C_PORT7_ENABLE_MASK 0x80 -+#define RTL8367C_PORT6_ENABLE_OFFSET 6 -+#define RTL8367C_PORT6_ENABLE_MASK 0x40 -+#define RTL8367C_PORT5_ENABLE_OFFSET 5 -+#define RTL8367C_PORT5_ENABLE_MASK 0x20 -+#define RTL8367C_PORT4_ENABLE_OFFSET 4 -+#define RTL8367C_PORT4_ENABLE_MASK 0x10 -+#define RTL8367C_PORT3_ENABLE_OFFSET 3 -+#define RTL8367C_PORT3_ENABLE_MASK 0x8 -+#define RTL8367C_PORT2_ENABLE_OFFSET 2 -+#define RTL8367C_PORT2_ENABLE_MASK 0x4 -+#define RTL8367C_PORT1_ENABLE_OFFSET 1 -+#define RTL8367C_PORT1_ENABLE_MASK 0x2 -+#define RTL8367C_PORT0_ENABLE_OFFSET 0 -+#define RTL8367C_PORT0_ENABLE_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_UNMATCH_PERMIT 0x06d6 -+#define RTL8367C_PORT10_PERMIT_OFFSET 10 -+#define RTL8367C_PORT10_PERMIT_MASK 0x400 -+#define RTL8367C_PORT9_PERMIT_OFFSET 9 -+#define RTL8367C_PORT9_PERMIT_MASK 0x200 -+#define RTL8367C_PORT8_PERMIT_OFFSET 8 -+#define RTL8367C_PORT8_PERMIT_MASK 0x100 -+#define RTL8367C_PORT7_PERMIT_OFFSET 7 -+#define RTL8367C_PORT7_PERMIT_MASK 0x80 -+#define RTL8367C_PORT6_PERMIT_OFFSET 6 -+#define RTL8367C_PORT6_PERMIT_MASK 0x40 -+#define RTL8367C_PORT5_PERMIT_OFFSET 5 -+#define RTL8367C_PORT5_PERMIT_MASK 0x20 -+#define RTL8367C_PORT4_PERMIT_OFFSET 4 -+#define RTL8367C_PORT4_PERMIT_MASK 0x10 -+#define RTL8367C_PORT3_PERMIT_OFFSET 3 -+#define RTL8367C_PORT3_PERMIT_MASK 0x8 -+#define RTL8367C_PORT2_PERMIT_OFFSET 2 -+#define RTL8367C_PORT2_PERMIT_MASK 0x4 -+#define RTL8367C_PORT1_PERMIT_OFFSET 1 -+#define RTL8367C_PORT1_PERMIT_MASK 0x2 -+#define RTL8367C_PORT0_PERMIT_OFFSET 0 -+#define RTL8367C_PORT0_PERMIT_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_GPIO_POLARITY 0x06d7 -+#define RTL8367C_ACL_GPIO_POLARITY_OFFSET 0 -+#define RTL8367C_ACL_GPIO_POLARITY_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_LOG_CNT_TYPE 0x06d8 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER15_TYPE_OFFSET 15 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER15_TYPE_MASK 0x8000 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER14_TYPE_OFFSET 14 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER14_TYPE_MASK 0x4000 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER13_TYPE_OFFSET 13 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER13_TYPE_MASK 0x2000 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER12_TYPE_OFFSET 12 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER12_TYPE_MASK 0x1000 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER11_TYPE_OFFSET 11 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER11_TYPE_MASK 0x800 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER10_TYPE_OFFSET 10 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER10_TYPE_MASK 0x400 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER9_TYPE_OFFSET 9 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER9_TYPE_MASK 0x200 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER8_TYPE_OFFSET 8 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER8_TYPE_MASK 0x100 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER7_TYPE_OFFSET 7 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER7_TYPE_MASK 0x80 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER6_TYPE_OFFSET 6 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER6_TYPE_MASK 0x40 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER5_TYPE_OFFSET 5 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER5_TYPE_MASK 0x20 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER4_TYPE_OFFSET 4 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER4_TYPE_MASK 0x10 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER3_TYPE_OFFSET 3 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER3_TYPE_MASK 0x8 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER2_TYPE_OFFSET 2 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER2_TYPE_MASK 0x4 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER1_TYPE_OFFSET 1 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER1_TYPE_MASK 0x2 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER0_TYPE_OFFSET 0 -+#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER0_TYPE_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_RESET_CFG 0x06d9 -+#define RTL8367C_ACL_RESET_CFG_OFFSET 0 -+#define RTL8367C_ACL_RESET_CFG_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_DUMMY00 0x06E0 -+ -+#define RTL8367C_REG_ACL_DUMMY01 0x06E1 -+ -+#define RTL8367C_REG_ACL_DUMMY02 0x06E2 -+ -+#define RTL8367C_REG_ACL_DUMMY03 0x06E3 -+ -+#define RTL8367C_REG_ACL_DUMMY04 0x06E4 -+ -+#define RTL8367C_REG_ACL_DUMMY05 0x06E5 -+ -+#define RTL8367C_REG_ACL_DUMMY06 0x06E6 -+ -+#define RTL8367C_REG_ACL_DUMMY07 0x06E7 -+ -+#define RTL8367C_REG_ACL_REASON_01 0x06E8 -+#define RTL8367C_ACL_ACT_1_OFFSET 8 -+#define RTL8367C_ACL_ACT_1_MASK 0xFF00 -+#define RTL8367C_ACL_ACT_0_OFFSET 0 -+#define RTL8367C_ACL_ACT_0_MASK 0xFF -+ -+#define RTL8367C_REG_ACL_REASON_23 0x06E9 -+#define RTL8367C_ACL_ACT_3_OFFSET 8 -+#define RTL8367C_ACL_ACT_3_MASK 0xFF00 -+#define RTL8367C_ACL_ACT_2_OFFSET 0 -+#define RTL8367C_ACL_ACT_2_MASK 0xFF -+ -+#define RTL8367C_REG_ACL_REASON_45 0x06EA -+#define RTL8367C_ACL_ACT_5_OFFSET 8 -+#define RTL8367C_ACL_ACT_5_MASK 0xFF00 -+#define RTL8367C_ACL_ACT_4_OFFSET 0 -+#define RTL8367C_ACL_ACT_4_MASK 0xFF -+ -+#define RTL8367C_REG_ACL_ACCESS_MODE 0x06EB -+#define RTL8367C_ACL_ACCESS_MODE_OFFSET 0 -+#define RTL8367C_ACL_ACCESS_MODE_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL32 0x06F0 -+#define RTL8367C_OP65_NOT_OFFSET 14 -+#define RTL8367C_OP65_NOT_MASK 0x4000 -+#define RTL8367C_ACT65_GPIO_OFFSET 13 -+#define RTL8367C_ACT65_GPIO_MASK 0x2000 -+#define RTL8367C_ACT65_FORWARD_OFFSET 12 -+#define RTL8367C_ACT65_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT65_POLICING_OFFSET 11 -+#define RTL8367C_ACT65_POLICING_MASK 0x800 -+#define RTL8367C_ACT65_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT65_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT65_SVID_OFFSET 9 -+#define RTL8367C_ACT65_SVID_MASK 0x200 -+#define RTL8367C_ACT65_CVID_OFFSET 8 -+#define RTL8367C_ACT65_CVID_MASK 0x100 -+#define RTL8367C_OP64_NOT_OFFSET 6 -+#define RTL8367C_OP64_NOT_MASK 0x40 -+#define RTL8367C_ACT64_GPIO_OFFSET 5 -+#define RTL8367C_ACT64_GPIO_MASK 0x20 -+#define RTL8367C_ACT64_FORWARD_OFFSET 4 -+#define RTL8367C_ACT64_FORWARD_MASK 0x10 -+#define RTL8367C_ACT64_POLICING_OFFSET 3 -+#define RTL8367C_ACT64_POLICING_MASK 0x8 -+#define RTL8367C_ACT64_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT64_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT64_SVID_OFFSET 1 -+#define RTL8367C_ACT64_SVID_MASK 0x2 -+#define RTL8367C_ACT64_CVID_OFFSET 0 -+#define RTL8367C_ACT64_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL33 0x06F1 -+#define RTL8367C_OP67_NOT_OFFSET 14 -+#define RTL8367C_OP67_NOT_MASK 0x4000 -+#define RTL8367C_ACT67_GPIO_OFFSET 13 -+#define RTL8367C_ACT67_GPIO_MASK 0x2000 -+#define RTL8367C_ACT67_FORWARD_OFFSET 12 -+#define RTL8367C_ACT67_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT67_POLICING_OFFSET 11 -+#define RTL8367C_ACT67_POLICING_MASK 0x800 -+#define RTL8367C_ACT67_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT67_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT67_SVID_OFFSET 9 -+#define RTL8367C_ACT67_SVID_MASK 0x200 -+#define RTL8367C_ACT67_CVID_OFFSET 8 -+#define RTL8367C_ACT67_CVID_MASK 0x100 -+#define RTL8367C_OP66_NOT_OFFSET 6 -+#define RTL8367C_OP66_NOT_MASK 0x40 -+#define RTL8367C_ACT66_GPIO_OFFSET 5 -+#define RTL8367C_ACT66_GPIO_MASK 0x20 -+#define RTL8367C_ACT66_FORWARD_OFFSET 4 -+#define RTL8367C_ACT66_FORWARD_MASK 0x10 -+#define RTL8367C_ACT66_POLICING_OFFSET 3 -+#define RTL8367C_ACT66_POLICING_MASK 0x8 -+#define RTL8367C_ACT66_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT66_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT66_SVID_OFFSET 1 -+#define RTL8367C_ACT66_SVID_MASK 0x2 -+#define RTL8367C_ACT66_CVID_OFFSET 0 -+#define RTL8367C_ACT66_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL34 0x06F2 -+#define RTL8367C_OP69_NOT_OFFSET 14 -+#define RTL8367C_OP69_NOT_MASK 0x4000 -+#define RTL8367C_ACT69_GPIO_OFFSET 13 -+#define RTL8367C_ACT69_GPIO_MASK 0x2000 -+#define RTL8367C_ACT69_FORWARD_OFFSET 12 -+#define RTL8367C_ACT69_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT69_POLICING_OFFSET 11 -+#define RTL8367C_ACT69_POLICING_MASK 0x800 -+#define RTL8367C_ACT69_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT69_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT69_SVID_OFFSET 9 -+#define RTL8367C_ACT69_SVID_MASK 0x200 -+#define RTL8367C_ACT69_CVID_OFFSET 8 -+#define RTL8367C_ACT69_CVID_MASK 0x100 -+#define RTL8367C_OP68_NOT_OFFSET 6 -+#define RTL8367C_OP68_NOT_MASK 0x40 -+#define RTL8367C_ACT68_GPIO_OFFSET 5 -+#define RTL8367C_ACT68_GPIO_MASK 0x20 -+#define RTL8367C_ACT68_FORWARD_OFFSET 4 -+#define RTL8367C_ACT68_FORWARD_MASK 0x10 -+#define RTL8367C_ACT68_POLICING_OFFSET 3 -+#define RTL8367C_ACT68_POLICING_MASK 0x8 -+#define RTL8367C_ACT68_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT68_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT68_SVID_OFFSET 1 -+#define RTL8367C_ACT68_SVID_MASK 0x2 -+#define RTL8367C_ACT68_CVID_OFFSET 0 -+#define RTL8367C_ACT68_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL35 0x06F3 -+#define RTL8367C_OP71_NOT_OFFSET 14 -+#define RTL8367C_OP71_NOT_MASK 0x4000 -+#define RTL8367C_ACT71_GPIO_OFFSET 13 -+#define RTL8367C_ACT71_GPIO_MASK 0x2000 -+#define RTL8367C_ACT71_FORWARD_OFFSET 12 -+#define RTL8367C_ACT71_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT71_POLICING_OFFSET 11 -+#define RTL8367C_ACT71_POLICING_MASK 0x800 -+#define RTL8367C_ACT71_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT71_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT71_SVID_OFFSET 9 -+#define RTL8367C_ACT71_SVID_MASK 0x200 -+#define RTL8367C_ACT71_CVID_OFFSET 8 -+#define RTL8367C_ACT71_CVID_MASK 0x100 -+#define RTL8367C_OP70_NOT_OFFSET 6 -+#define RTL8367C_OP70_NOT_MASK 0x40 -+#define RTL8367C_ACT70_GPIO_OFFSET 5 -+#define RTL8367C_ACT70_GPIO_MASK 0x20 -+#define RTL8367C_ACT70_FORWARD_OFFSET 4 -+#define RTL8367C_ACT70_FORWARD_MASK 0x10 -+#define RTL8367C_ACT70_POLICING_OFFSET 3 -+#define RTL8367C_ACT70_POLICING_MASK 0x8 -+#define RTL8367C_ACT70_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT70_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT70_SVID_OFFSET 1 -+#define RTL8367C_ACT70_SVID_MASK 0x2 -+#define RTL8367C_ACT70_CVID_OFFSET 0 -+#define RTL8367C_ACT70_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL36 0x06F4 -+#define RTL8367C_OP73_NOT_OFFSET 14 -+#define RTL8367C_OP73_NOT_MASK 0x4000 -+#define RTL8367C_ACT73_GPIO_OFFSET 13 -+#define RTL8367C_ACT73_GPIO_MASK 0x2000 -+#define RTL8367C_ACT73_FORWARD_OFFSET 12 -+#define RTL8367C_ACT73_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT73_POLICING_OFFSET 11 -+#define RTL8367C_ACT73_POLICING_MASK 0x800 -+#define RTL8367C_ACT73_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT73_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT73_SVID_OFFSET 9 -+#define RTL8367C_ACT73_SVID_MASK 0x200 -+#define RTL8367C_ACT73_CVID_OFFSET 8 -+#define RTL8367C_ACT73_CVID_MASK 0x100 -+#define RTL8367C_OP72_NOT_OFFSET 6 -+#define RTL8367C_OP72_NOT_MASK 0x40 -+#define RTL8367C_ACT72_GPIO_OFFSET 5 -+#define RTL8367C_ACT72_GPIO_MASK 0x20 -+#define RTL8367C_ACT72_FORWARD_OFFSET 4 -+#define RTL8367C_ACT72_FORWARD_MASK 0x10 -+#define RTL8367C_ACT72_POLICING_OFFSET 3 -+#define RTL8367C_ACT72_POLICING_MASK 0x8 -+#define RTL8367C_ACT72_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT72_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT72_SVID_OFFSET 1 -+#define RTL8367C_ACT72_SVID_MASK 0x2 -+#define RTL8367C_ACT72_CVID_OFFSET 0 -+#define RTL8367C_ACT72_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL37 0x06F5 -+#define RTL8367C_OP75_NOT_OFFSET 14 -+#define RTL8367C_OP75_NOT_MASK 0x4000 -+#define RTL8367C_ACT75_GPIO_OFFSET 13 -+#define RTL8367C_ACT75_GPIO_MASK 0x2000 -+#define RTL8367C_ACT75_FORWARD_OFFSET 12 -+#define RTL8367C_ACT75_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT75_POLICING_OFFSET 11 -+#define RTL8367C_ACT75_POLICING_MASK 0x800 -+#define RTL8367C_ACT75_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT75_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT75_SVID_OFFSET 9 -+#define RTL8367C_ACT75_SVID_MASK 0x200 -+#define RTL8367C_ACT75_CVID_OFFSET 8 -+#define RTL8367C_ACT75_CVID_MASK 0x100 -+#define RTL8367C_OP74_NOT_OFFSET 6 -+#define RTL8367C_OP74_NOT_MASK 0x40 -+#define RTL8367C_ACT74_GPIO_OFFSET 5 -+#define RTL8367C_ACT74_GPIO_MASK 0x20 -+#define RTL8367C_ACT74_FORWARD_OFFSET 4 -+#define RTL8367C_ACT74_FORWARD_MASK 0x10 -+#define RTL8367C_ACT74_POLICING_OFFSET 3 -+#define RTL8367C_ACT74_POLICING_MASK 0x8 -+#define RTL8367C_ACT74_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT74_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT74_SVID_OFFSET 1 -+#define RTL8367C_ACT74_SVID_MASK 0x2 -+#define RTL8367C_ACT74_CVID_OFFSET 0 -+#define RTL8367C_ACT74_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL38 0x06F6 -+#define RTL8367C_OP77_NOT_OFFSET 14 -+#define RTL8367C_OP77_NOT_MASK 0x4000 -+#define RTL8367C_ACT77_GPIO_OFFSET 13 -+#define RTL8367C_ACT77_GPIO_MASK 0x2000 -+#define RTL8367C_ACT77_FORWARD_OFFSET 12 -+#define RTL8367C_ACT77_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT77_POLICING_OFFSET 11 -+#define RTL8367C_ACT77_POLICING_MASK 0x800 -+#define RTL8367C_ACT77_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT77_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT77_SVID_OFFSET 9 -+#define RTL8367C_ACT77_SVID_MASK 0x200 -+#define RTL8367C_ACT77_CVID_OFFSET 8 -+#define RTL8367C_ACT77_CVID_MASK 0x100 -+#define RTL8367C_OP76_NOT_OFFSET 6 -+#define RTL8367C_OP76_NOT_MASK 0x40 -+#define RTL8367C_ACT76_GPIO_OFFSET 5 -+#define RTL8367C_ACT76_GPIO_MASK 0x20 -+#define RTL8367C_ACT76_FORWARD_OFFSET 4 -+#define RTL8367C_ACT76_FORWARD_MASK 0x10 -+#define RTL8367C_ACT76_POLICING_OFFSET 3 -+#define RTL8367C_ACT76_POLICING_MASK 0x8 -+#define RTL8367C_ACT76_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT76_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT76_SVID_OFFSET 1 -+#define RTL8367C_ACT76_SVID_MASK 0x2 -+#define RTL8367C_ACT76_CVID_OFFSET 0 -+#define RTL8367C_ACT76_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL39 0x06F7 -+#define RTL8367C_OP79_NOT_OFFSET 14 -+#define RTL8367C_OP79_NOT_MASK 0x4000 -+#define RTL8367C_ACT79_GPIO_OFFSET 13 -+#define RTL8367C_ACT79_GPIO_MASK 0x2000 -+#define RTL8367C_ACT79_FORWARD_OFFSET 12 -+#define RTL8367C_ACT79_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT79_POLICING_OFFSET 11 -+#define RTL8367C_ACT79_POLICING_MASK 0x800 -+#define RTL8367C_ACT79_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT79_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT79_SVID_OFFSET 9 -+#define RTL8367C_ACT79_SVID_MASK 0x200 -+#define RTL8367C_ACT79_CVID_OFFSET 8 -+#define RTL8367C_ACT79_CVID_MASK 0x100 -+#define RTL8367C_OP78_NOT_OFFSET 6 -+#define RTL8367C_OP78_NOT_MASK 0x40 -+#define RTL8367C_ACT78_GPIO_OFFSET 5 -+#define RTL8367C_ACT78_GPIO_MASK 0x20 -+#define RTL8367C_ACT78_FORWARD_OFFSET 4 -+#define RTL8367C_ACT78_FORWARD_MASK 0x10 -+#define RTL8367C_ACT78_POLICING_OFFSET 3 -+#define RTL8367C_ACT78_POLICING_MASK 0x8 -+#define RTL8367C_ACT78_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT78_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT78_SVID_OFFSET 1 -+#define RTL8367C_ACT78_SVID_MASK 0x2 -+#define RTL8367C_ACT78_CVID_OFFSET 0 -+#define RTL8367C_ACT78_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL40 0x06F8 -+#define RTL8367C_OP81_NOT_OFFSET 14 -+#define RTL8367C_OP81_NOT_MASK 0x4000 -+#define RTL8367C_ACT81_GPIO_OFFSET 13 -+#define RTL8367C_ACT81_GPIO_MASK 0x2000 -+#define RTL8367C_ACT81_FORWARD_OFFSET 12 -+#define RTL8367C_ACT81_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT81_POLICING_OFFSET 11 -+#define RTL8367C_ACT81_POLICING_MASK 0x800 -+#define RTL8367C_ACT81_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT81_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT81_SVID_OFFSET 9 -+#define RTL8367C_ACT81_SVID_MASK 0x200 -+#define RTL8367C_ACT81_CVID_OFFSET 8 -+#define RTL8367C_ACT81_CVID_MASK 0x100 -+#define RTL8367C_OP80_NOT_OFFSET 6 -+#define RTL8367C_OP80_NOT_MASK 0x40 -+#define RTL8367C_ACT80_GPIO_OFFSET 5 -+#define RTL8367C_ACT80_GPIO_MASK 0x20 -+#define RTL8367C_ACT80_FORWARD_OFFSET 4 -+#define RTL8367C_ACT80_FORWARD_MASK 0x10 -+#define RTL8367C_ACT80_POLICING_OFFSET 3 -+#define RTL8367C_ACT80_POLICING_MASK 0x8 -+#define RTL8367C_ACT80_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT80_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT80_SVID_OFFSET 1 -+#define RTL8367C_ACT80_SVID_MASK 0x2 -+#define RTL8367C_ACT80_CVID_OFFSET 0 -+#define RTL8367C_ACT80_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL41 0x06F9 -+#define RTL8367C_OP83_NOT_OFFSET 14 -+#define RTL8367C_OP83_NOT_MASK 0x4000 -+#define RTL8367C_ACT83_GPIO_OFFSET 13 -+#define RTL8367C_ACT83_GPIO_MASK 0x2000 -+#define RTL8367C_ACT83_FORWARD_OFFSET 12 -+#define RTL8367C_ACT83_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT83_POLICING_OFFSET 11 -+#define RTL8367C_ACT83_POLICING_MASK 0x800 -+#define RTL8367C_ACT83_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT83_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT83_SVID_OFFSET 9 -+#define RTL8367C_ACT83_SVID_MASK 0x200 -+#define RTL8367C_ACT83_CVID_OFFSET 8 -+#define RTL8367C_ACT83_CVID_MASK 0x100 -+#define RTL8367C_OP82_NOT_OFFSET 6 -+#define RTL8367C_OP82_NOT_MASK 0x40 -+#define RTL8367C_ACT82_GPIO_OFFSET 5 -+#define RTL8367C_ACT82_GPIO_MASK 0x20 -+#define RTL8367C_ACT82_FORWARD_OFFSET 4 -+#define RTL8367C_ACT82_FORWARD_MASK 0x10 -+#define RTL8367C_ACT82_POLICING_OFFSET 3 -+#define RTL8367C_ACT82_POLICING_MASK 0x8 -+#define RTL8367C_ACT82_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT82_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT82_SVID_OFFSET 1 -+#define RTL8367C_ACT82_SVID_MASK 0x2 -+#define RTL8367C_ACT82_CVID_OFFSET 0 -+#define RTL8367C_ACT82_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL42 0x06FA -+#define RTL8367C_OP85_NOT_OFFSET 14 -+#define RTL8367C_OP85_NOT_MASK 0x4000 -+#define RTL8367C_ACT85_GPIO_OFFSET 13 -+#define RTL8367C_ACT85_GPIO_MASK 0x2000 -+#define RTL8367C_ACT85_FORWARD_OFFSET 12 -+#define RTL8367C_ACT85_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT85_POLICING_OFFSET 11 -+#define RTL8367C_ACT85_POLICING_MASK 0x800 -+#define RTL8367C_ACT85_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT85_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT85_SVID_OFFSET 9 -+#define RTL8367C_ACT85_SVID_MASK 0x200 -+#define RTL8367C_ACT85_CVID_OFFSET 8 -+#define RTL8367C_ACT85_CVID_MASK 0x100 -+#define RTL8367C_OP84_NOT_OFFSET 6 -+#define RTL8367C_OP84_NOT_MASK 0x40 -+#define RTL8367C_ACT84_GPIO_OFFSET 5 -+#define RTL8367C_ACT84_GPIO_MASK 0x20 -+#define RTL8367C_ACT84_FORWARD_OFFSET 4 -+#define RTL8367C_ACT84_FORWARD_MASK 0x10 -+#define RTL8367C_ACT84_POLICING_OFFSET 3 -+#define RTL8367C_ACT84_POLICING_MASK 0x8 -+#define RTL8367C_ACT84_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT84_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT84_SVID_OFFSET 1 -+#define RTL8367C_ACT84_SVID_MASK 0x2 -+#define RTL8367C_ACT84_CVID_OFFSET 0 -+#define RTL8367C_ACT84_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL43 0x06FB -+#define RTL8367C_OP87_NOT_OFFSET 14 -+#define RTL8367C_OP87_NOT_MASK 0x4000 -+#define RTL8367C_ACT87_GPIO_OFFSET 13 -+#define RTL8367C_ACT87_GPIO_MASK 0x2000 -+#define RTL8367C_ACT87_FORWARD_OFFSET 12 -+#define RTL8367C_ACT87_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT87_POLICING_OFFSET 11 -+#define RTL8367C_ACT87_POLICING_MASK 0x800 -+#define RTL8367C_ACT87_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT87_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT87_SVID_OFFSET 9 -+#define RTL8367C_ACT87_SVID_MASK 0x200 -+#define RTL8367C_ACT87_CVID_OFFSET 8 -+#define RTL8367C_ACT87_CVID_MASK 0x100 -+#define RTL8367C_OP86_NOT_OFFSET 6 -+#define RTL8367C_OP86_NOT_MASK 0x40 -+#define RTL8367C_ACT86_GPIO_OFFSET 5 -+#define RTL8367C_ACT86_GPIO_MASK 0x20 -+#define RTL8367C_ACT86_FORWARD_OFFSET 4 -+#define RTL8367C_ACT86_FORWARD_MASK 0x10 -+#define RTL8367C_ACT86_POLICING_OFFSET 3 -+#define RTL8367C_ACT86_POLICING_MASK 0x8 -+#define RTL8367C_ACT86_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT86_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT86_SVID_OFFSET 1 -+#define RTL8367C_ACT86_SVID_MASK 0x2 -+#define RTL8367C_ACT86_CVID_OFFSET 0 -+#define RTL8367C_ACT86_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL44 0x06FC -+#define RTL8367C_OP89_NOT_OFFSET 14 -+#define RTL8367C_OP89_NOT_MASK 0x4000 -+#define RTL8367C_ACT89_GPIO_OFFSET 13 -+#define RTL8367C_ACT89_GPIO_MASK 0x2000 -+#define RTL8367C_ACT89_FORWARD_OFFSET 12 -+#define RTL8367C_ACT89_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT89_POLICING_OFFSET 11 -+#define RTL8367C_ACT89_POLICING_MASK 0x800 -+#define RTL8367C_ACT89_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT89_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT89_SVID_OFFSET 9 -+#define RTL8367C_ACT89_SVID_MASK 0x200 -+#define RTL8367C_ACT89_CVID_OFFSET 8 -+#define RTL8367C_ACT89_CVID_MASK 0x100 -+#define RTL8367C_OP88_NOT_OFFSET 6 -+#define RTL8367C_OP88_NOT_MASK 0x40 -+#define RTL8367C_ACT88_GPIO_OFFSET 5 -+#define RTL8367C_ACT88_GPIO_MASK 0x20 -+#define RTL8367C_ACT88_FORWARD_OFFSET 4 -+#define RTL8367C_ACT88_FORWARD_MASK 0x10 -+#define RTL8367C_ACT88_POLICING_OFFSET 3 -+#define RTL8367C_ACT88_POLICING_MASK 0x8 -+#define RTL8367C_ACT88_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT88_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT88_SVID_OFFSET 1 -+#define RTL8367C_ACT88_SVID_MASK 0x2 -+#define RTL8367C_ACT88_CVID_OFFSET 0 -+#define RTL8367C_ACT88_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL45 0x06FD -+#define RTL8367C_OP91_NOT_OFFSET 14 -+#define RTL8367C_OP91_NOT_MASK 0x4000 -+#define RTL8367C_ACT91_GPIO_OFFSET 13 -+#define RTL8367C_ACT91_GPIO_MASK 0x2000 -+#define RTL8367C_ACT91_FORWARD_OFFSET 12 -+#define RTL8367C_ACT91_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT91_POLICING_OFFSET 11 -+#define RTL8367C_ACT91_POLICING_MASK 0x800 -+#define RTL8367C_ACT91_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT91_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT91_SVID_OFFSET 9 -+#define RTL8367C_ACT91_SVID_MASK 0x200 -+#define RTL8367C_ACT91_CVID_OFFSET 8 -+#define RTL8367C_ACT91_CVID_MASK 0x100 -+#define RTL8367C_OP90_NOT_OFFSET 6 -+#define RTL8367C_OP90_NOT_MASK 0x40 -+#define RTL8367C_ACT90_GPIO_OFFSET 5 -+#define RTL8367C_ACT90_GPIO_MASK 0x20 -+#define RTL8367C_ACT90_FORWARD_OFFSET 4 -+#define RTL8367C_ACT90_FORWARD_MASK 0x10 -+#define RTL8367C_ACT90_POLICING_OFFSET 3 -+#define RTL8367C_ACT90_POLICING_MASK 0x8 -+#define RTL8367C_ACT90_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT90_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT90_SVID_OFFSET 1 -+#define RTL8367C_ACT90_SVID_MASK 0x2 -+#define RTL8367C_ACT90_CVID_OFFSET 0 -+#define RTL8367C_ACT90_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL46 0x06FE -+#define RTL8367C_OP93_NOT_OFFSET 14 -+#define RTL8367C_OP93_NOT_MASK 0x4000 -+#define RTL8367C_ACT93_GPIO_OFFSET 13 -+#define RTL8367C_ACT93_GPIO_MASK 0x2000 -+#define RTL8367C_ACT93_FORWARD_OFFSET 12 -+#define RTL8367C_ACT93_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT93_POLICING_OFFSET 11 -+#define RTL8367C_ACT93_POLICING_MASK 0x800 -+#define RTL8367C_ACT93_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT93_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT93_SVID_OFFSET 9 -+#define RTL8367C_ACT93_SVID_MASK 0x200 -+#define RTL8367C_ACT93_CVID_OFFSET 8 -+#define RTL8367C_ACT93_CVID_MASK 0x100 -+#define RTL8367C_OP92_NOT_OFFSET 6 -+#define RTL8367C_OP92_NOT_MASK 0x40 -+#define RTL8367C_ACT92_GPIO_OFFSET 5 -+#define RTL8367C_ACT92_GPIO_MASK 0x20 -+#define RTL8367C_ACT92_FORWARD_OFFSET 4 -+#define RTL8367C_ACT92_FORWARD_MASK 0x10 -+#define RTL8367C_ACT92_POLICING_OFFSET 3 -+#define RTL8367C_ACT92_POLICING_MASK 0x8 -+#define RTL8367C_ACT92_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT92_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT92_SVID_OFFSET 1 -+#define RTL8367C_ACT92_SVID_MASK 0x2 -+#define RTL8367C_ACT92_CVID_OFFSET 0 -+#define RTL8367C_ACT92_CVID_MASK 0x1 -+ -+#define RTL8367C_REG_ACL_ACTION_CTRL47 0x06FF -+#define RTL8367C_OP95_NOT_OFFSET 14 -+#define RTL8367C_OP95_NOT_MASK 0x4000 -+#define RTL8367C_ACT95_GPIO_OFFSET 13 -+#define RTL8367C_ACT95_GPIO_MASK 0x2000 -+#define RTL8367C_ACT95_FORWARD_OFFSET 12 -+#define RTL8367C_ACT95_FORWARD_MASK 0x1000 -+#define RTL8367C_ACT95_POLICING_OFFSET 11 -+#define RTL8367C_ACT95_POLICING_MASK 0x800 -+#define RTL8367C_ACT95_PRIORITY_OFFSET 10 -+#define RTL8367C_ACT95_PRIORITY_MASK 0x400 -+#define RTL8367C_ACT95_SVID_OFFSET 9 -+#define RTL8367C_ACT95_SVID_MASK 0x200 -+#define RTL8367C_ACT95_CVID_OFFSET 8 -+#define RTL8367C_ACT95_CVID_MASK 0x100 -+#define RTL8367C_OP94_NOT_OFFSET 6 -+#define RTL8367C_OP94_NOT_MASK 0x40 -+#define RTL8367C_ACT94_GPIO_OFFSET 5 -+#define RTL8367C_ACT94_GPIO_MASK 0x20 -+#define RTL8367C_ACT94_FORWARD_OFFSET 4 -+#define RTL8367C_ACT94_FORWARD_MASK 0x10 -+#define RTL8367C_ACT94_POLICING_OFFSET 3 -+#define RTL8367C_ACT94_POLICING_MASK 0x8 -+#define RTL8367C_ACT94_PRIORITY_OFFSET 2 -+#define RTL8367C_ACT94_PRIORITY_MASK 0x4 -+#define RTL8367C_ACT94_SVID_OFFSET 1 -+#define RTL8367C_ACT94_SVID_MASK 0x2 -+#define RTL8367C_ACT94_CVID_OFFSET 0 -+#define RTL8367C_ACT94_CVID_MASK 0x1 -+ -+/* (16'h0700)cvlan_reg */ -+ -+#define RTL8367C_REG_VLAN_PVID_CTRL0 0x0700 -+#define RTL8367C_PORT1_VIDX_OFFSET 8 -+#define RTL8367C_PORT1_VIDX_MASK 0x1F00 -+#define RTL8367C_PORT0_VIDX_OFFSET 0 -+#define RTL8367C_PORT0_VIDX_MASK 0x1F -+ -+#define RTL8367C_REG_VLAN_PVID_CTRL1 0x0701 -+#define RTL8367C_PORT3_VIDX_OFFSET 8 -+#define RTL8367C_PORT3_VIDX_MASK 0x1F00 -+#define RTL8367C_PORT2_VIDX_OFFSET 0 -+#define RTL8367C_PORT2_VIDX_MASK 0x1F -+ -+#define RTL8367C_REG_VLAN_PVID_CTRL2 0x0702 -+#define RTL8367C_PORT5_VIDX_OFFSET 8 -+#define RTL8367C_PORT5_VIDX_MASK 0x1F00 -+#define RTL8367C_PORT4_VIDX_OFFSET 0 -+#define RTL8367C_PORT4_VIDX_MASK 0x1F -+ -+#define RTL8367C_REG_VLAN_PVID_CTRL3 0x0703 -+#define RTL8367C_PORT7_VIDX_OFFSET 8 -+#define RTL8367C_PORT7_VIDX_MASK 0x1F00 -+#define RTL8367C_PORT6_VIDX_OFFSET 0 -+#define RTL8367C_PORT6_VIDX_MASK 0x1F -+ -+#define RTL8367C_REG_VLAN_PVID_CTRL4 0x0704 -+#define RTL8367C_PORT9_VIDX_OFFSET 8 -+#define RTL8367C_PORT9_VIDX_MASK 0x1F00 -+#define RTL8367C_PORT8_VIDX_OFFSET 0 -+#define RTL8367C_PORT8_VIDX_MASK 0x1F -+ -+#define RTL8367C_REG_VLAN_PVID_CTRL5 0x0705 -+#define RTL8367C_VLAN_PVID_CTRL5_OFFSET 0 -+#define RTL8367C_VLAN_PVID_CTRL5_MASK 0x1F -+ -+#define RTL8367C_REG_VLAN_PPB0_VALID 0x0708 -+#define RTL8367C_VLAN_PPB0_VALID_VALID_EXT_OFFSET 8 -+#define RTL8367C_VLAN_PPB0_VALID_VALID_EXT_MASK 0x700 -+#define RTL8367C_VLAN_PPB0_VALID_VALID_OFFSET 0 -+#define RTL8367C_VLAN_PPB0_VALID_VALID_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_PPB0_CTRL0 0x0709 -+#define RTL8367C_VLAN_PPB0_CTRL0_PORT2_INDEX_OFFSET 10 -+#define RTL8367C_VLAN_PPB0_CTRL0_PORT2_INDEX_MASK 0x7C00 -+#define RTL8367C_VLAN_PPB0_CTRL0_PORT1_INDEX_OFFSET 5 -+#define RTL8367C_VLAN_PPB0_CTRL0_PORT1_INDEX_MASK 0x3E0 -+#define RTL8367C_VLAN_PPB0_CTRL0_PORT0_INDEX_OFFSET 0 -+#define RTL8367C_VLAN_PPB0_CTRL0_PORT0_INDEX_MASK 0x1F -+ -+#define RTL8367C_REG_VLAN_PPB0_CTRL1 0x070a -+#define RTL8367C_VLAN_PPB0_CTRL1_PORT5_INDEX_OFFSET 10 -+#define RTL8367C_VLAN_PPB0_CTRL1_PORT5_INDEX_MASK 0x7C00 -+#define RTL8367C_VLAN_PPB0_CTRL1_PORT4_INDEX_OFFSET 5 -+#define RTL8367C_VLAN_PPB0_CTRL1_PORT4_INDEX_MASK 0x3E0 -+#define RTL8367C_VLAN_PPB0_CTRL1_PORT3_INDEX_OFFSET 0 -+#define RTL8367C_VLAN_PPB0_CTRL1_PORT3_INDEX_MASK 0x1F -+ -+#define RTL8367C_REG_VLAN_PPB0_CTRL2 0x070b -+#define RTL8367C_VLAN_PPB0_CTRL2_FRAME_TYPE_OFFSET 10 -+#define RTL8367C_VLAN_PPB0_CTRL2_FRAME_TYPE_MASK 0xC00 -+#define RTL8367C_VLAN_PPB0_CTRL2_PORT7_INDEX_OFFSET 5 -+#define RTL8367C_VLAN_PPB0_CTRL2_PORT7_INDEX_MASK 0x3E0 -+#define RTL8367C_VLAN_PPB0_CTRL2_PORT6_INDEX_OFFSET 0 -+#define RTL8367C_VLAN_PPB0_CTRL2_PORT6_INDEX_MASK 0x1F -+ -+#define RTL8367C_REG_VLAN_PPB0_CTRL4 0x070c -+#define RTL8367C_VLAN_PPB0_CTRL4_PORT10_INDEX_OFFSET 10 -+#define RTL8367C_VLAN_PPB0_CTRL4_PORT10_INDEX_MASK 0x7C00 -+#define RTL8367C_VLAN_PPB0_CTRL4_PORT9_INDEX_OFFSET 5 -+#define RTL8367C_VLAN_PPB0_CTRL4_PORT9_INDEX_MASK 0x3E0 -+#define RTL8367C_VLAN_PPB0_CTRL4_PORT8_INDEX_OFFSET 0 -+#define RTL8367C_VLAN_PPB0_CTRL4_PORT8_INDEX_MASK 0x1F -+ -+#define RTL8367C_REG_VLAN_PPB0_CTRL3 0x070f -+ -+#define RTL8367C_REG_VLAN_PPB1_VALID 0x0710 -+#define RTL8367C_VLAN_PPB1_VALID_VALID_EXT_OFFSET 8 -+#define RTL8367C_VLAN_PPB1_VALID_VALID_EXT_MASK 0x700 -+#define RTL8367C_VLAN_PPB1_VALID_VALID_OFFSET 0 -+#define RTL8367C_VLAN_PPB1_VALID_VALID_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_PPB1_CTRL0 0x0711 -+#define RTL8367C_VLAN_PPB1_CTRL0_PORT2_INDEX_OFFSET 10 -+#define RTL8367C_VLAN_PPB1_CTRL0_PORT2_INDEX_MASK 0x7C00 -+#define RTL8367C_VLAN_PPB1_CTRL0_PORT1_INDEX_OFFSET 5 -+#define RTL8367C_VLAN_PPB1_CTRL0_PORT1_INDEX_MASK 0x3E0 -+#define RTL8367C_VLAN_PPB1_CTRL0_PORT0_INDEX_OFFSET 0 -+#define RTL8367C_VLAN_PPB1_CTRL0_PORT0_INDEX_MASK 0x1F -+ -+#define RTL8367C_REG_VLAN_PPB1_CTRL1 0x0712 -+#define RTL8367C_VLAN_PPB1_CTRL1_PORT5_INDEX_OFFSET 10 -+#define RTL8367C_VLAN_PPB1_CTRL1_PORT5_INDEX_MASK 0x7C00 -+#define RTL8367C_VLAN_PPB1_CTRL1_PORT4_INDEX_OFFSET 5 -+#define RTL8367C_VLAN_PPB1_CTRL1_PORT4_INDEX_MASK 0x3E0 -+#define RTL8367C_VLAN_PPB1_CTRL1_PORT3_INDEX_OFFSET 0 -+#define RTL8367C_VLAN_PPB1_CTRL1_PORT3_INDEX_MASK 0x1F -+ -+#define RTL8367C_REG_VLAN_PPB1_CTRL2 0x0713 -+#define RTL8367C_VLAN_PPB1_CTRL2_FRAME_TYPE_OFFSET 10 -+#define RTL8367C_VLAN_PPB1_CTRL2_FRAME_TYPE_MASK 0xC00 -+#define RTL8367C_VLAN_PPB1_CTRL2_PORT7_INDEX_OFFSET 5 -+#define RTL8367C_VLAN_PPB1_CTRL2_PORT7_INDEX_MASK 0x3E0 -+#define RTL8367C_VLAN_PPB1_CTRL2_PORT6_INDEX_OFFSET 0 -+#define RTL8367C_VLAN_PPB1_CTRL2_PORT6_INDEX_MASK 0x1F -+ -+#define RTL8367C_REG_VLAN_PPB1_CTRL4 0x0714 -+#define RTL8367C_VLAN_PPB1_CTRL4_PORT10_INDEX_OFFSET 10 -+#define RTL8367C_VLAN_PPB1_CTRL4_PORT10_INDEX_MASK 0x7C00 -+#define RTL8367C_VLAN_PPB1_CTRL4_PORT9_INDEX_OFFSET 5 -+#define RTL8367C_VLAN_PPB1_CTRL4_PORT9_INDEX_MASK 0x3E0 -+#define RTL8367C_VLAN_PPB1_CTRL4_PORT8_INDEX_OFFSET 0 -+#define RTL8367C_VLAN_PPB1_CTRL4_PORT8_INDEX_MASK 0x1F -+ -+#define RTL8367C_REG_VLAN_PPB1_CTRL3 0x0717 -+ -+#define RTL8367C_REG_VLAN_PPB2_VALID 0x0718 -+#define RTL8367C_VLAN_PPB2_VALID_VALID_EXT_OFFSET 8 -+#define RTL8367C_VLAN_PPB2_VALID_VALID_EXT_MASK 0x700 -+#define RTL8367C_VLAN_PPB2_VALID_VALID_OFFSET 0 -+#define RTL8367C_VLAN_PPB2_VALID_VALID_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_PPB2_CTRL0 0x0719 -+#define RTL8367C_VLAN_PPB2_CTRL0_PORT2_INDEX_OFFSET 10 -+#define RTL8367C_VLAN_PPB2_CTRL0_PORT2_INDEX_MASK 0x7C00 -+#define RTL8367C_VLAN_PPB2_CTRL0_PORT1_INDEX_OFFSET 5 -+#define RTL8367C_VLAN_PPB2_CTRL0_PORT1_INDEX_MASK 0x3E0 -+#define RTL8367C_VLAN_PPB2_CTRL0_PORT0_INDEX_OFFSET 0 -+#define RTL8367C_VLAN_PPB2_CTRL0_PORT0_INDEX_MASK 0x1F -+ -+#define RTL8367C_REG_VLAN_PPB2_CTRL1 0x071a -+#define RTL8367C_VLAN_PPB2_CTRL1_PORT5_INDEX_OFFSET 10 -+#define RTL8367C_VLAN_PPB2_CTRL1_PORT5_INDEX_MASK 0x7C00 -+#define RTL8367C_VLAN_PPB2_CTRL1_PORT4_INDEX_OFFSET 5 -+#define RTL8367C_VLAN_PPB2_CTRL1_PORT4_INDEX_MASK 0x3E0 -+#define RTL8367C_VLAN_PPB2_CTRL1_PORT3_INDEX_OFFSET 0 -+#define RTL8367C_VLAN_PPB2_CTRL1_PORT3_INDEX_MASK 0x1F -+ -+#define RTL8367C_REG_VLAN_PPB2_CTRL2 0x071b -+#define RTL8367C_VLAN_PPB2_CTRL2_FRAME_TYPE_OFFSET 10 -+#define RTL8367C_VLAN_PPB2_CTRL2_FRAME_TYPE_MASK 0xC00 -+#define RTL8367C_VLAN_PPB2_CTRL2_PORT7_INDEX_OFFSET 5 -+#define RTL8367C_VLAN_PPB2_CTRL2_PORT7_INDEX_MASK 0x3E0 -+#define RTL8367C_VLAN_PPB2_CTRL2_PORT6_INDEX_OFFSET 0 -+#define RTL8367C_VLAN_PPB2_CTRL2_PORT6_INDEX_MASK 0x1F -+ -+#define RTL8367C_REG_VLAN_PPB2_CTRL4 0x071c -+#define RTL8367C_VLAN_PPB2_CTRL4_PORT10_INDEX_OFFSET 10 -+#define RTL8367C_VLAN_PPB2_CTRL4_PORT10_INDEX_MASK 0x7C00 -+#define RTL8367C_VLAN_PPB2_CTRL4_PORT9_INDEX_OFFSET 5 -+#define RTL8367C_VLAN_PPB2_CTRL4_PORT9_INDEX_MASK 0x3E0 -+#define RTL8367C_VLAN_PPB2_CTRL4_PORT8_INDEX_OFFSET 0 -+#define RTL8367C_VLAN_PPB2_CTRL4_PORT8_INDEX_MASK 0x1F -+ -+#define RTL8367C_REG_VLAN_PPB2_CTRL3 0x071f -+ -+#define RTL8367C_REG_VLAN_PPB3_VALID 0x0720 -+#define RTL8367C_VLAN_PPB3_VALID_VALID_EXT_OFFSET 8 -+#define RTL8367C_VLAN_PPB3_VALID_VALID_EXT_MASK 0x700 -+#define RTL8367C_VLAN_PPB3_VALID_VALID_OFFSET 0 -+#define RTL8367C_VLAN_PPB3_VALID_VALID_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_PPB3_CTRL0 0x0721 -+#define RTL8367C_VLAN_PPB3_CTRL0_PORT2_INDEX_OFFSET 10 -+#define RTL8367C_VLAN_PPB3_CTRL0_PORT2_INDEX_MASK 0x7C00 -+#define RTL8367C_VLAN_PPB3_CTRL0_PORT1_INDEX_OFFSET 5 -+#define RTL8367C_VLAN_PPB3_CTRL0_PORT1_INDEX_MASK 0x3E0 -+#define RTL8367C_VLAN_PPB3_CTRL0_PORT0_INDEX_OFFSET 0 -+#define RTL8367C_VLAN_PPB3_CTRL0_PORT0_INDEX_MASK 0x1F -+ -+#define RTL8367C_REG_VLAN_PPB3_CTRL1 0x0722 -+#define RTL8367C_VLAN_PPB3_CTRL1_PORT5_INDEX_OFFSET 10 -+#define RTL8367C_VLAN_PPB3_CTRL1_PORT5_INDEX_MASK 0x7C00 -+#define RTL8367C_VLAN_PPB3_CTRL1_PORT4_INDEX_OFFSET 5 -+#define RTL8367C_VLAN_PPB3_CTRL1_PORT4_INDEX_MASK 0x3E0 -+#define RTL8367C_VLAN_PPB3_CTRL1_PORT3_INDEX_OFFSET 0 -+#define RTL8367C_VLAN_PPB3_CTRL1_PORT3_INDEX_MASK 0x1F -+ -+#define RTL8367C_REG_VLAN_PPB3_CTRL2 0x0723 -+#define RTL8367C_VLAN_PPB3_CTRL2_FRAME_TYPE_OFFSET 10 -+#define RTL8367C_VLAN_PPB3_CTRL2_FRAME_TYPE_MASK 0xC00 -+#define RTL8367C_VLAN_PPB3_CTRL2_PORT7_INDEX_OFFSET 5 -+#define RTL8367C_VLAN_PPB3_CTRL2_PORT7_INDEX_MASK 0x3E0 -+#define RTL8367C_VLAN_PPB3_CTRL2_PORT6_INDEX_OFFSET 0 -+#define RTL8367C_VLAN_PPB3_CTRL2_PORT6_INDEX_MASK 0x1F -+ -+#define RTL8367C_REG_VLAN_PPB3_CTRL4 0x0724 -+#define RTL8367C_VLAN_PPB3_CTRL4_PORT10_INDEX_OFFSET 10 -+#define RTL8367C_VLAN_PPB3_CTRL4_PORT10_INDEX_MASK 0x7C00 -+#define RTL8367C_VLAN_PPB3_CTRL4_PORT9_INDEX_OFFSET 5 -+#define RTL8367C_VLAN_PPB3_CTRL4_PORT9_INDEX_MASK 0x3E0 -+#define RTL8367C_VLAN_PPB3_CTRL4_PORT8_INDEX_OFFSET 0 -+#define RTL8367C_VLAN_PPB3_CTRL4_PORT8_INDEX_MASK 0x1F -+ -+#define RTL8367C_REG_VLAN_PPB3_CTRL3 0x0727 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION0_CTRL0 0x0728 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION0_CTRL1 0x0729 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION0_CTRL2 0x072a -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION0_CTRL3 0x072b -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION1_CTRL0 0x072c -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION1_CTRL1 0x072d -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION1_CTRL2 0x072e -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION1_CTRL3 0x072f -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION2_CTRL0 0x0730 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION2_CTRL1 0x0731 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION2_CTRL2 0x0732 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION2_CTRL3 0x0733 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION3_CTRL0 0x0734 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION3_CTRL1 0x0735 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION3_CTRL2 0x0736 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION3_CTRL3 0x0737 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION4_CTRL0 0x0738 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION4_CTRL1 0x0739 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION4_CTRL2 0x073a -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION4_CTRL3 0x073b -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION5_CTRL0 0x073c -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION5_CTRL1 0x073d -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION5_CTRL2 0x073e -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION5_CTRL3 0x073f -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION6_CTRL0 0x0740 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION6_CTRL1 0x0741 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION6_CTRL2 0x0742 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION6_CTRL3 0x0743 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION7_CTRL0 0x0744 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION7_CTRL1 0x0745 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION7_CTRL2 0x0746 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION7_CTRL3 0x0747 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION8_CTRL0 0x0748 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION8_CTRL1 0x0749 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION8_CTRL2 0x074a -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION8_CTRL3 0x074b -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION9_CTRL0 0x074c -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION9_CTRL1 0x074d -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION9_CTRL2 0x074e -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION9_CTRL3 0x074f -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION10_CTRL0 0x0750 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION10_CTRL1 0x0751 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION10_CTRL2 0x0752 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION10_CTRL3 0x0753 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION11_CTRL0 0x0754 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION11_CTRL1 0x0755 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION11_CTRL2 0x0756 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION11_CTRL3 0x0757 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION12_CTRL0 0x0758 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION12_CTRL1 0x0759 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION12_CTRL2 0x075a -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION12_CTRL3 0x075b -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION13_CTRL0 0x075c -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION13_CTRL1 0x075d -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION13_CTRL2 0x075e -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION13_CTRL3 0x075f -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION14_CTRL0 0x0760 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION14_CTRL1 0x0761 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION14_CTRL2 0x0762 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION14_CTRL3 0x0763 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION15_CTRL0 0x0764 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION15_CTRL1 0x0765 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION15_CTRL2 0x0766 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION15_CTRL3 0x0767 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION16_CTRL0 0x0768 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION16_CTRL1 0x0769 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION16_CTRL2 0x076a -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION16_CTRL3 0x076b -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION17_CTRL0 0x076c -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION17_CTRL1 0x076d -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION17_CTRL2 0x076e -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION17_CTRL3 0x076f -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION18_CTRL0 0x0770 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION18_CTRL1 0x0771 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION18_CTRL2 0x0772 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION18_CTRL3 0x0773 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION19_CTRL0 0x0774 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION19_CTRL1 0x0775 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION19_CTRL2 0x0776 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION19_CTRL3 0x0777 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION20_CTRL0 0x0778 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION20_CTRL1 0x0779 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION20_CTRL2 0x077a -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION20_CTRL3 0x077b -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION21_CTRL0 0x077c -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION21_CTRL1 0x077d -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION21_CTRL2 0x077e -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION21_CTRL3 0x077f -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION22_CTRL0 0x0780 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION22_CTRL1 0x0781 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION22_CTRL2 0x0782 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION22_CTRL3 0x0783 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION23_CTRL0 0x0784 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION23_CTRL1 0x0785 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION23_CTRL2 0x0786 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION23_CTRL3 0x0787 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION24_CTRL0 0x0788 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION24_CTRL1 0x0789 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION24_CTRL2 0x078a -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION24_CTRL3 0x078b -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION25_CTRL0 0x078c -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION25_CTRL1 0x078d -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION25_CTRL2 0x078e -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION25_CTRL3 0x078f -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION26_CTRL0 0x0790 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION26_CTRL1 0x0791 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION26_CTRL2 0x0792 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION26_CTRL3 0x0793 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION27_CTRL0 0x0794 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION27_CTRL1 0x0795 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION27_CTRL2 0x0796 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION27_CTRL3 0x0797 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION28_CTRL0 0x0798 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION28_CTRL1 0x0799 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION28_CTRL2 0x079a -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION28_CTRL3 0x079b -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION29_CTRL0 0x079c -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION29_CTRL1 0x079d -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION29_CTRL2 0x079e -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION29_CTRL3 0x079f -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION30_CTRL0 0x07a0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION30_CTRL1 0x07a1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION30_CTRL2 0x07a2 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION30_CTRL3 0x07a3 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION31_CTRL0 0x07a4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL0_MBR_EXT_OFFSET 8 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL0_MBR_EXT_MASK 0x700 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL0_MBR_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL0_MBR_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION31_CTRL1 0x07a5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL1_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION31_CTRL2 0x07a6 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_METERIDX_EXT_OFFSET 10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_METERIDX_EXT_MASK 0x400 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_METERIDX_OFFSET 5 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_METERIDX_MASK 0x3E0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_ENVLANPOL_OFFSET 4 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_ENVLANPOL_MASK 0x10 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_VBPRI_OFFSET 1 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_VBPRI_MASK 0xE -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_VBPEN_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_VBPEN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION31_CTRL3 0x07a7 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_VLAN_CTRL 0x07a8 -+#define RTL8367C_VLAN_CTRL_OFFSET 0 -+#define RTL8367C_VLAN_CTRL_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_INGRESS 0x07a9 -+#define RTL8367C_VLAN_INGRESS_OFFSET 0 -+#define RTL8367C_VLAN_INGRESS_MASK 0x7FF -+ -+#define RTL8367C_REG_VLAN_ACCEPT_FRAME_TYPE_CTRL0 0x07aa -+#define RTL8367C_PORT7_FRAME_TYPE_OFFSET 14 -+#define RTL8367C_PORT7_FRAME_TYPE_MASK 0xC000 -+#define RTL8367C_PORT6_FRAME_TYPE_OFFSET 12 -+#define RTL8367C_PORT6_FRAME_TYPE_MASK 0x3000 -+#define RTL8367C_PORT5_FRAME_TYPE_OFFSET 10 -+#define RTL8367C_PORT5_FRAME_TYPE_MASK 0xC00 -+#define RTL8367C_PORT4_FRAME_TYPE_OFFSET 8 -+#define RTL8367C_PORT4_FRAME_TYPE_MASK 0x300 -+#define RTL8367C_PORT3_FRAME_TYPE_OFFSET 6 -+#define RTL8367C_PORT3_FRAME_TYPE_MASK 0xC0 -+#define RTL8367C_PORT2_FRAME_TYPE_OFFSET 4 -+#define RTL8367C_PORT2_FRAME_TYPE_MASK 0x30 -+#define RTL8367C_PORT1_FRAME_TYPE_OFFSET 2 -+#define RTL8367C_PORT1_FRAME_TYPE_MASK 0xC -+#define RTL8367C_PORT0_FRAME_TYPE_OFFSET 0 -+#define RTL8367C_PORT0_FRAME_TYPE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_ACCEPT_FRAME_TYPE_CTRL1 0x07ab -+#define RTL8367C_PORT10_FRAME_TYPE_OFFSET 4 -+#define RTL8367C_PORT10_FRAME_TYPE_MASK 0x30 -+#define RTL8367C_PORT9_FRAME_TYPE_OFFSET 2 -+#define RTL8367C_PORT9_FRAME_TYPE_MASK 0xC -+#define RTL8367C_PORT8_FRAME_TYPE_OFFSET 0 -+#define RTL8367C_PORT8_FRAME_TYPE_MASK 0x3 -+ -+#define RTL8367C_REG_PORT_PBFIDEN 0x07ac -+#define RTL8367C_PORT_PBFIDEN_OFFSET 0 -+#define RTL8367C_PORT_PBFIDEN_MASK 0x7FF -+ -+#define RTL8367C_REG_PORT0_PBFID 0x07ad -+#define RTL8367C_PORT0_PBFID_OFFSET 0 -+#define RTL8367C_PORT0_PBFID_MASK 0xF -+ -+#define RTL8367C_REG_PORT1_PBFID 0x07ae -+#define RTL8367C_PORT1_PBFID_OFFSET 0 -+#define RTL8367C_PORT1_PBFID_MASK 0xF -+ -+#define RTL8367C_REG_PORT2_PBFID 0x07af -+#define RTL8367C_PORT2_PBFID_OFFSET 0 -+#define RTL8367C_PORT2_PBFID_MASK 0xF -+ -+#define RTL8367C_REG_PORT3_PBFID 0x07b0 -+#define RTL8367C_PORT3_PBFID_OFFSET 0 -+#define RTL8367C_PORT3_PBFID_MASK 0xF -+ -+#define RTL8367C_REG_PORT4_PBFID 0x07b1 -+#define RTL8367C_PORT4_PBFID_OFFSET 0 -+#define RTL8367C_PORT4_PBFID_MASK 0xF -+ -+#define RTL8367C_REG_PORT5_PBFID 0x07b2 -+#define RTL8367C_PORT5_PBFID_OFFSET 0 -+#define RTL8367C_PORT5_PBFID_MASK 0xF -+ -+#define RTL8367C_REG_PORT6_PBFID 0x07b3 -+#define RTL8367C_PORT6_PBFID_OFFSET 0 -+#define RTL8367C_PORT6_PBFID_MASK 0xF -+ -+#define RTL8367C_REG_PORT7_PBFID 0x07b4 -+#define RTL8367C_PORT7_PBFID_OFFSET 0 -+#define RTL8367C_PORT7_PBFID_MASK 0xF -+ -+#define RTL8367C_REG_VLAN_EXT_CTRL 0x07b5 -+#define RTL8367C_VLAN_1P_REMARK_BYPASS_REALKEEP_OFFSET 2 -+#define RTL8367C_VLAN_1P_REMARK_BYPASS_REALKEEP_MASK 0x4 -+#define RTL8367C_VLAN_VID4095_TYPE_OFFSET 1 -+#define RTL8367C_VLAN_VID4095_TYPE_MASK 0x2 -+#define RTL8367C_VLAN_VID0_TYPE_OFFSET 0 -+#define RTL8367C_VLAN_VID0_TYPE_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_EXT_CTRL2 0x07b6 -+#define RTL8367C_VLAN_EXT_CTRL2_OFFSET 0 -+#define RTL8367C_VLAN_EXT_CTRL2_MASK 0x1 -+ -+#define RTL8367C_REG_PORT8_PBFID 0x07b7 -+#define RTL8367C_PORT8_PBFID_OFFSET 0 -+#define RTL8367C_PORT8_PBFID_MASK 0xF -+ -+#define RTL8367C_REG_PORT9_PBFID 0x07b8 -+#define RTL8367C_PORT9_PBFID_OFFSET 0 -+#define RTL8367C_PORT9_PBFID_MASK 0xF -+ -+#define RTL8367C_REG_PORT10_PBFID 0x07b9 -+#define RTL8367C_PORT10_PBFID_OFFSET 0 -+#define RTL8367C_PORT10_PBFID_MASK 0xF -+ -+#define RTL8367C_REG_CVLAN_DUMMY00 0x07E0 -+ -+#define RTL8367C_REG_CVLAN_DUMMY01 0x07E1 -+ -+#define RTL8367C_REG_CVLAN_DUMMY02 0x07E2 -+ -+#define RTL8367C_REG_CVLAN_DUMMY03 0x07E3 -+ -+#define RTL8367C_REG_CVLAN_DUMMY04 0x07E4 -+ -+#define RTL8367C_REG_CVLAN_DUMMY05 0x07E5 -+ -+#define RTL8367C_REG_CVLAN_DUMMY06 0x07E6 -+ -+#define RTL8367C_REG_CVLAN_DUMMY07 0x07E7 -+ -+#define RTL8367C_REG_CVLAN_DUMMY08 0x07E8 -+ -+#define RTL8367C_REG_CVLAN_DUMMY09 0x07E9 -+ -+#define RTL8367C_REG_CVLAN_DUMMY10 0x07EA -+ -+#define RTL8367C_REG_CVLAN_DUMMY11 0x07EB -+ -+#define RTL8367C_REG_CVLAN_DUMMY12 0x07EC -+ -+#define RTL8367C_REG_CVLAN_DUMMY13 0x07ED -+ -+#define RTL8367C_REG_CVLAN_DUMMY14 0x07EE -+ -+#define RTL8367C_REG_CVLAN_DUMMY15 0x07EF -+ -+/* (16'h0800)dpm_reg */ -+ -+#define RTL8367C_REG_RMA_CTRL00 0x0800 -+#define RTL8367C_RMA_CTRL00_OPERATION_OFFSET 7 -+#define RTL8367C_RMA_CTRL00_OPERATION_MASK 0x180 -+#define RTL8367C_RMA_CTRL00_DISCARD_STORM_FILTER_OFFSET 6 -+#define RTL8367C_RMA_CTRL00_DISCARD_STORM_FILTER_MASK 0x40 -+#define RTL8367C_TRAP_PRIORITY_OFFSET 3 -+#define RTL8367C_TRAP_PRIORITY_MASK 0x38 -+#define RTL8367C_RMA_CTRL00_KEEP_FORMAT_OFFSET 2 -+#define RTL8367C_RMA_CTRL00_KEEP_FORMAT_MASK 0x4 -+#define RTL8367C_RMA_CTRL00_VLAN_LEAKY_OFFSET 1 -+#define RTL8367C_RMA_CTRL00_VLAN_LEAKY_MASK 0x2 -+#define RTL8367C_RMA_CTRL00_PORTISO_LEAKY_OFFSET 0 -+#define RTL8367C_RMA_CTRL00_PORTISO_LEAKY_MASK 0x1 -+ -+#define RTL8367C_REG_RMA_CTRL01 0x0801 -+#define RTL8367C_RMA_CTRL01_OPERATION_OFFSET 7 -+#define RTL8367C_RMA_CTRL01_OPERATION_MASK 0x180 -+#define RTL8367C_RMA_CTRL01_DISCARD_STORM_FILTER_OFFSET 6 -+#define RTL8367C_RMA_CTRL01_DISCARD_STORM_FILTER_MASK 0x40 -+#define RTL8367C_RMA_CTRL01_KEEP_FORMAT_OFFSET 2 -+#define RTL8367C_RMA_CTRL01_KEEP_FORMAT_MASK 0x4 -+#define RTL8367C_RMA_CTRL01_VLAN_LEAKY_OFFSET 1 -+#define RTL8367C_RMA_CTRL01_VLAN_LEAKY_MASK 0x2 -+#define RTL8367C_RMA_CTRL01_PORTISO_LEAKY_OFFSET 0 -+#define RTL8367C_RMA_CTRL01_PORTISO_LEAKY_MASK 0x1 -+ -+#define RTL8367C_REG_RMA_CTRL02 0x0802 -+#define RTL8367C_RMA_CTRL02_OPERATION_OFFSET 7 -+#define RTL8367C_RMA_CTRL02_OPERATION_MASK 0x180 -+#define RTL8367C_RMA_CTRL02_DISCARD_STORM_FILTER_OFFSET 6 -+#define RTL8367C_RMA_CTRL02_DISCARD_STORM_FILTER_MASK 0x40 -+#define RTL8367C_RMA_CTRL02_KEEP_FORMAT_OFFSET 2 -+#define RTL8367C_RMA_CTRL02_KEEP_FORMAT_MASK 0x4 -+#define RTL8367C_RMA_CTRL02_VLAN_LEAKY_OFFSET 1 -+#define RTL8367C_RMA_CTRL02_VLAN_LEAKY_MASK 0x2 -+#define RTL8367C_RMA_CTRL02_PORTISO_LEAKY_OFFSET 0 -+#define RTL8367C_RMA_CTRL02_PORTISO_LEAKY_MASK 0x1 -+ -+#define RTL8367C_REG_RMA_CTRL03 0x0803 -+#define RTL8367C_RMA_CTRL03_OPERATION_OFFSET 7 -+#define RTL8367C_RMA_CTRL03_OPERATION_MASK 0x180 -+#define RTL8367C_RMA_CTRL03_DISCARD_STORM_FILTER_OFFSET 6 -+#define RTL8367C_RMA_CTRL03_DISCARD_STORM_FILTER_MASK 0x40 -+#define RTL8367C_RMA_CTRL03_KEEP_FORMAT_OFFSET 2 -+#define RTL8367C_RMA_CTRL03_KEEP_FORMAT_MASK 0x4 -+#define RTL8367C_RMA_CTRL03_VLAN_LEAKY_OFFSET 1 -+#define RTL8367C_RMA_CTRL03_VLAN_LEAKY_MASK 0x2 -+#define RTL8367C_RMA_CTRL03_PORTISO_LEAKY_OFFSET 0 -+#define RTL8367C_RMA_CTRL03_PORTISO_LEAKY_MASK 0x1 -+ -+#define RTL8367C_REG_RMA_CTRL04 0x0804 -+#define RTL8367C_RMA_CTRL04_OPERATION_OFFSET 7 -+#define RTL8367C_RMA_CTRL04_OPERATION_MASK 0x180 -+#define RTL8367C_RMA_CTRL04_DISCARD_STORM_FILTER_OFFSET 6 -+#define RTL8367C_RMA_CTRL04_DISCARD_STORM_FILTER_MASK 0x40 -+#define RTL8367C_RMA_CTRL04_KEEP_FORMAT_OFFSET 2 -+#define RTL8367C_RMA_CTRL04_KEEP_FORMAT_MASK 0x4 -+#define RTL8367C_RMA_CTRL04_VLAN_LEAKY_OFFSET 1 -+#define RTL8367C_RMA_CTRL04_VLAN_LEAKY_MASK 0x2 -+#define RTL8367C_RMA_CTRL04_PORTISO_LEAKY_OFFSET 0 -+#define RTL8367C_RMA_CTRL04_PORTISO_LEAKY_MASK 0x1 -+ -+#define RTL8367C_REG_RMA_CTRL08 0x0808 -+#define RTL8367C_RMA_CTRL08_OPERATION_OFFSET 7 -+#define RTL8367C_RMA_CTRL08_OPERATION_MASK 0x180 -+#define RTL8367C_RMA_CTRL08_DISCARD_STORM_FILTER_OFFSET 6 -+#define RTL8367C_RMA_CTRL08_DISCARD_STORM_FILTER_MASK 0x40 -+#define RTL8367C_RMA_CTRL08_KEEP_FORMAT_OFFSET 2 -+#define RTL8367C_RMA_CTRL08_KEEP_FORMAT_MASK 0x4 -+#define RTL8367C_RMA_CTRL08_VLAN_LEAKY_OFFSET 1 -+#define RTL8367C_RMA_CTRL08_VLAN_LEAKY_MASK 0x2 -+#define RTL8367C_RMA_CTRL08_PORTISO_LEAKY_OFFSET 0 -+#define RTL8367C_RMA_CTRL08_PORTISO_LEAKY_MASK 0x1 -+ -+#define RTL8367C_REG_RMA_CTRL0D 0x080d -+#define RTL8367C_RMA_CTRL0D_OPERATION_OFFSET 7 -+#define RTL8367C_RMA_CTRL0D_OPERATION_MASK 0x180 -+#define RTL8367C_RMA_CTRL0D_DISCARD_STORM_FILTER_OFFSET 6 -+#define RTL8367C_RMA_CTRL0D_DISCARD_STORM_FILTER_MASK 0x40 -+#define RTL8367C_RMA_CTRL0D_KEEP_FORMAT_OFFSET 2 -+#define RTL8367C_RMA_CTRL0D_KEEP_FORMAT_MASK 0x4 -+#define RTL8367C_RMA_CTRL0D_VLAN_LEAKY_OFFSET 1 -+#define RTL8367C_RMA_CTRL0D_VLAN_LEAKY_MASK 0x2 -+#define RTL8367C_RMA_CTRL0D_PORTISO_LEAKY_OFFSET 0 -+#define RTL8367C_RMA_CTRL0D_PORTISO_LEAKY_MASK 0x1 -+ -+#define RTL8367C_REG_RMA_CTRL0E 0x080e -+#define RTL8367C_RMA_CTRL0E_OPERATION_OFFSET 7 -+#define RTL8367C_RMA_CTRL0E_OPERATION_MASK 0x180 -+#define RTL8367C_RMA_CTRL0E_DISCARD_STORM_FILTER_OFFSET 6 -+#define RTL8367C_RMA_CTRL0E_DISCARD_STORM_FILTER_MASK 0x40 -+#define RTL8367C_RMA_CTRL0E_KEEP_FORMAT_OFFSET 2 -+#define RTL8367C_RMA_CTRL0E_KEEP_FORMAT_MASK 0x4 -+#define RTL8367C_RMA_CTRL0E_VLAN_LEAKY_OFFSET 1 -+#define RTL8367C_RMA_CTRL0E_VLAN_LEAKY_MASK 0x2 -+#define RTL8367C_RMA_CTRL0E_PORTISO_LEAKY_OFFSET 0 -+#define RTL8367C_RMA_CTRL0E_PORTISO_LEAKY_MASK 0x1 -+ -+#define RTL8367C_REG_RMA_CTRL10 0x0810 -+#define RTL8367C_RMA_CTRL10_OPERATION_OFFSET 7 -+#define RTL8367C_RMA_CTRL10_OPERATION_MASK 0x180 -+#define RTL8367C_RMA_CTRL10_DISCARD_STORM_FILTER_OFFSET 6 -+#define RTL8367C_RMA_CTRL10_DISCARD_STORM_FILTER_MASK 0x40 -+#define RTL8367C_RMA_CTRL10_KEEP_FORMAT_OFFSET 2 -+#define RTL8367C_RMA_CTRL10_KEEP_FORMAT_MASK 0x4 -+#define RTL8367C_RMA_CTRL10_VLAN_LEAKY_OFFSET 1 -+#define RTL8367C_RMA_CTRL10_VLAN_LEAKY_MASK 0x2 -+#define RTL8367C_RMA_CTRL10_PORTISO_LEAKY_OFFSET 0 -+#define RTL8367C_RMA_CTRL10_PORTISO_LEAKY_MASK 0x1 -+ -+#define RTL8367C_REG_RMA_CTRL11 0x0811 -+#define RTL8367C_RMA_CTRL11_OPERATION_OFFSET 7 -+#define RTL8367C_RMA_CTRL11_OPERATION_MASK 0x180 -+#define RTL8367C_RMA_CTRL11_DISCARD_STORM_FILTER_OFFSET 6 -+#define RTL8367C_RMA_CTRL11_DISCARD_STORM_FILTER_MASK 0x40 -+#define RTL8367C_RMA_CTRL11_KEEP_FORMAT_OFFSET 2 -+#define RTL8367C_RMA_CTRL11_KEEP_FORMAT_MASK 0x4 -+#define RTL8367C_RMA_CTRL11_VLAN_LEAKY_OFFSET 1 -+#define RTL8367C_RMA_CTRL11_VLAN_LEAKY_MASK 0x2 -+#define RTL8367C_RMA_CTRL11_PORTISO_LEAKY_OFFSET 0 -+#define RTL8367C_RMA_CTRL11_PORTISO_LEAKY_MASK 0x1 -+ -+#define RTL8367C_REG_RMA_CTRL12 0x0812 -+#define RTL8367C_RMA_CTRL12_OPERATION_OFFSET 7 -+#define RTL8367C_RMA_CTRL12_OPERATION_MASK 0x180 -+#define RTL8367C_RMA_CTRL12_DISCARD_STORM_FILTER_OFFSET 6 -+#define RTL8367C_RMA_CTRL12_DISCARD_STORM_FILTER_MASK 0x40 -+#define RTL8367C_RMA_CTRL12_KEEP_FORMAT_OFFSET 2 -+#define RTL8367C_RMA_CTRL12_KEEP_FORMAT_MASK 0x4 -+#define RTL8367C_RMA_CTRL12_VLAN_LEAKY_OFFSET 1 -+#define RTL8367C_RMA_CTRL12_VLAN_LEAKY_MASK 0x2 -+#define RTL8367C_RMA_CTRL12_PORTISO_LEAKY_OFFSET 0 -+#define RTL8367C_RMA_CTRL12_PORTISO_LEAKY_MASK 0x1 -+ -+#define RTL8367C_REG_RMA_CTRL13 0x0813 -+#define RTL8367C_RMA_CTRL13_OPERATION_OFFSET 7 -+#define RTL8367C_RMA_CTRL13_OPERATION_MASK 0x180 -+#define RTL8367C_RMA_CTRL13_DISCARD_STORM_FILTER_OFFSET 6 -+#define RTL8367C_RMA_CTRL13_DISCARD_STORM_FILTER_MASK 0x40 -+#define RTL8367C_RMA_CTRL13_KEEP_FORMAT_OFFSET 2 -+#define RTL8367C_RMA_CTRL13_KEEP_FORMAT_MASK 0x4 -+#define RTL8367C_RMA_CTRL13_VLAN_LEAKY_OFFSET 1 -+#define RTL8367C_RMA_CTRL13_VLAN_LEAKY_MASK 0x2 -+#define RTL8367C_RMA_CTRL13_PORTISO_LEAKY_OFFSET 0 -+#define RTL8367C_RMA_CTRL13_PORTISO_LEAKY_MASK 0x1 -+ -+#define RTL8367C_REG_RMA_CTRL18 0x0818 -+#define RTL8367C_RMA_CTRL18_OPERATION_OFFSET 7 -+#define RTL8367C_RMA_CTRL18_OPERATION_MASK 0x180 -+#define RTL8367C_RMA_CTRL18_DISCARD_STORM_FILTER_OFFSET 6 -+#define RTL8367C_RMA_CTRL18_DISCARD_STORM_FILTER_MASK 0x40 -+#define RTL8367C_RMA_CTRL18_KEEP_FORMAT_OFFSET 2 -+#define RTL8367C_RMA_CTRL18_KEEP_FORMAT_MASK 0x4 -+#define RTL8367C_RMA_CTRL18_VLAN_LEAKY_OFFSET 1 -+#define RTL8367C_RMA_CTRL18_VLAN_LEAKY_MASK 0x2 -+#define RTL8367C_RMA_CTRL18_PORTISO_LEAKY_OFFSET 0 -+#define RTL8367C_RMA_CTRL18_PORTISO_LEAKY_MASK 0x1 -+ -+#define RTL8367C_REG_RMA_CTRL1A 0x081a -+#define RTL8367C_RMA_CTRL1A_OPERATION_OFFSET 7 -+#define RTL8367C_RMA_CTRL1A_OPERATION_MASK 0x180 -+#define RTL8367C_RMA_CTRL1A_DISCARD_STORM_FILTER_OFFSET 6 -+#define RTL8367C_RMA_CTRL1A_DISCARD_STORM_FILTER_MASK 0x40 -+#define RTL8367C_RMA_CTRL1A_KEEP_FORMAT_OFFSET 2 -+#define RTL8367C_RMA_CTRL1A_KEEP_FORMAT_MASK 0x4 -+#define RTL8367C_RMA_CTRL1A_VLAN_LEAKY_OFFSET 1 -+#define RTL8367C_RMA_CTRL1A_VLAN_LEAKY_MASK 0x2 -+#define RTL8367C_RMA_CTRL1A_PORTISO_LEAKY_OFFSET 0 -+#define RTL8367C_RMA_CTRL1A_PORTISO_LEAKY_MASK 0x1 -+ -+#define RTL8367C_REG_RMA_CTRL20 0x0820 -+#define RTL8367C_RMA_CTRL20_OPERATION_OFFSET 7 -+#define RTL8367C_RMA_CTRL20_OPERATION_MASK 0x180 -+#define RTL8367C_RMA_CTRL20_DISCARD_STORM_FILTER_OFFSET 6 -+#define RTL8367C_RMA_CTRL20_DISCARD_STORM_FILTER_MASK 0x40 -+#define RTL8367C_RMA_CTRL20_KEEP_FORMAT_OFFSET 2 -+#define RTL8367C_RMA_CTRL20_KEEP_FORMAT_MASK 0x4 -+#define RTL8367C_RMA_CTRL20_VLAN_LEAKY_OFFSET 1 -+#define RTL8367C_RMA_CTRL20_VLAN_LEAKY_MASK 0x2 -+#define RTL8367C_RMA_CTRL20_PORTISO_LEAKY_OFFSET 0 -+#define RTL8367C_RMA_CTRL20_PORTISO_LEAKY_MASK 0x1 -+ -+#define RTL8367C_REG_RMA_CTRL21 0x0821 -+#define RTL8367C_RMA_CTRL21_OPERATION_OFFSET 7 -+#define RTL8367C_RMA_CTRL21_OPERATION_MASK 0x180 -+#define RTL8367C_RMA_CTRL21_DISCARD_STORM_FILTER_OFFSET 6 -+#define RTL8367C_RMA_CTRL21_DISCARD_STORM_FILTER_MASK 0x40 -+#define RTL8367C_RMA_CTRL21_KEEP_FORMAT_OFFSET 2 -+#define RTL8367C_RMA_CTRL21_KEEP_FORMAT_MASK 0x4 -+#define RTL8367C_RMA_CTRL21_VLAN_LEAKY_OFFSET 1 -+#define RTL8367C_RMA_CTRL21_VLAN_LEAKY_MASK 0x2 -+#define RTL8367C_RMA_CTRL21_PORTISO_LEAKY_OFFSET 0 -+#define RTL8367C_RMA_CTRL21_PORTISO_LEAKY_MASK 0x1 -+ -+#define RTL8367C_REG_RMA_CTRL22 0x0822 -+#define RTL8367C_RMA_CTRL22_OPERATION_OFFSET 7 -+#define RTL8367C_RMA_CTRL22_OPERATION_MASK 0x180 -+#define RTL8367C_RMA_CTRL22_DISCARD_STORM_FILTER_OFFSET 6 -+#define RTL8367C_RMA_CTRL22_DISCARD_STORM_FILTER_MASK 0x40 -+#define RTL8367C_RMA_CTRL22_KEEP_FORMAT_OFFSET 2 -+#define RTL8367C_RMA_CTRL22_KEEP_FORMAT_MASK 0x4 -+#define RTL8367C_RMA_CTRL22_VLAN_LEAKY_OFFSET 1 -+#define RTL8367C_RMA_CTRL22_VLAN_LEAKY_MASK 0x2 -+#define RTL8367C_RMA_CTRL22_PORTISO_LEAKY_OFFSET 0 -+#define RTL8367C_RMA_CTRL22_PORTISO_LEAKY_MASK 0x1 -+ -+#define RTL8367C_REG_RMA_CTRL_CDP 0x0830 -+#define RTL8367C_RMA_CTRL_CDP_OPERATION_OFFSET 7 -+#define RTL8367C_RMA_CTRL_CDP_OPERATION_MASK 0x180 -+#define RTL8367C_RMA_CTRL_CDP_DISCARD_STORM_FILTER_OFFSET 6 -+#define RTL8367C_RMA_CTRL_CDP_DISCARD_STORM_FILTER_MASK 0x40 -+#define RTL8367C_RMA_CTRL_CDP_KEEP_FORMAT_OFFSET 2 -+#define RTL8367C_RMA_CTRL_CDP_KEEP_FORMAT_MASK 0x4 -+#define RTL8367C_RMA_CTRL_CDP_VLAN_LEAKY_OFFSET 1 -+#define RTL8367C_RMA_CTRL_CDP_VLAN_LEAKY_MASK 0x2 -+#define RTL8367C_RMA_CTRL_CDP_PORTISO_LEAKY_OFFSET 0 -+#define RTL8367C_RMA_CTRL_CDP_PORTISO_LEAKY_MASK 0x1 -+ -+#define RTL8367C_REG_RMA_CTRL_CSSTP 0x0831 -+#define RTL8367C_RMA_CTRL_CSSTP_OPERATION_OFFSET 7 -+#define RTL8367C_RMA_CTRL_CSSTP_OPERATION_MASK 0x180 -+#define RTL8367C_RMA_CTRL_CSSTP_DISCARD_STORM_FILTER_OFFSET 6 -+#define RTL8367C_RMA_CTRL_CSSTP_DISCARD_STORM_FILTER_MASK 0x40 -+#define RTL8367C_RMA_CTRL_CSSTP_KEEP_FORMAT_OFFSET 2 -+#define RTL8367C_RMA_CTRL_CSSTP_KEEP_FORMAT_MASK 0x4 -+#define RTL8367C_RMA_CTRL_CSSTP_VLAN_LEAKY_OFFSET 1 -+#define RTL8367C_RMA_CTRL_CSSTP_VLAN_LEAKY_MASK 0x2 -+#define RTL8367C_RMA_CTRL_CSSTP_PORTISO_LEAKY_OFFSET 0 -+#define RTL8367C_RMA_CTRL_CSSTP_PORTISO_LEAKY_MASK 0x1 -+ -+#define RTL8367C_REG_RMA_CTRL_LLDP 0x0832 -+#define RTL8367C_RMA_CTRL_LLDP_OPERATION_OFFSET 7 -+#define RTL8367C_RMA_CTRL_LLDP_OPERATION_MASK 0x180 -+#define RTL8367C_RMA_CTRL_LLDP_DISCARD_STORM_FILTER_OFFSET 6 -+#define RTL8367C_RMA_CTRL_LLDP_DISCARD_STORM_FILTER_MASK 0x40 -+#define RTL8367C_RMA_CTRL_LLDP_KEEP_FORMAT_OFFSET 2 -+#define RTL8367C_RMA_CTRL_LLDP_KEEP_FORMAT_MASK 0x4 -+#define RTL8367C_RMA_CTRL_LLDP_VLAN_LEAKY_OFFSET 1 -+#define RTL8367C_RMA_CTRL_LLDP_VLAN_LEAKY_MASK 0x2 -+#define RTL8367C_RMA_CTRL_LLDP_PORTISO_LEAKY_OFFSET 0 -+#define RTL8367C_RMA_CTRL_LLDP_PORTISO_LEAKY_MASK 0x1 -+ -+#define RTL8367C_REG_RMA_LLDP_EN 0x0833 -+#define RTL8367C_RMA_LLDP_EN_OFFSET 0 -+#define RTL8367C_RMA_LLDP_EN_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_PORTBASED_PRIORITY_CTRL0 0x0851 -+#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT3_PRIORITY_OFFSET 12 -+#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT3_PRIORITY_MASK 0x7000 -+#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT2_PRIORITY_OFFSET 8 -+#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT2_PRIORITY_MASK 0x700 -+#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT1_PRIORITY_OFFSET 4 -+#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT1_PRIORITY_MASK 0x70 -+#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT0_PRIORITY_OFFSET 0 -+#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT0_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_VLAN_PORTBASED_PRIORITY_CTRL1 0x0852 -+#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT7_PRIORITY_OFFSET 12 -+#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT7_PRIORITY_MASK 0x7000 -+#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT6_PRIORITY_OFFSET 8 -+#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT6_PRIORITY_MASK 0x700 -+#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT5_PRIORITY_OFFSET 4 -+#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT5_PRIORITY_MASK 0x70 -+#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT4_PRIORITY_OFFSET 0 -+#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT4_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_VLAN_PORTBASED_PRIORITY_CTRL2 0x0853 -+#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL2_PORT10_PRIORITY_OFFSET 8 -+#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL2_PORT10_PRIORITY_MASK 0x700 -+#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL2_PORT9_PRIORITY_OFFSET 4 -+#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL2_PORT9_PRIORITY_MASK 0x70 -+#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL2_PORT8_PRIORITY_OFFSET 0 -+#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL2_PORT8_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM0_CTRL0 0x0855 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT3_PRIORITY_OFFSET 12 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT3_PRIORITY_MASK 0x7000 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT2_PRIORITY_OFFSET 8 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT2_PRIORITY_MASK 0x700 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT1_PRIORITY_OFFSET 4 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT1_PRIORITY_MASK 0x70 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT0_PRIORITY_OFFSET 0 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT0_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM0_CTRL1 0x0856 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT7_PRIORITY_OFFSET 12 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT7_PRIORITY_MASK 0x7000 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT6_PRIORITY_OFFSET 8 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT6_PRIORITY_MASK 0x700 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT5_PRIORITY_OFFSET 4 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT5_PRIORITY_MASK 0x70 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT4_PRIORITY_OFFSET 0 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT4_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM0_CTRL2 0x0857 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL2_PORT10_PRIORITY_OFFSET 8 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL2_PORT10_PRIORITY_MASK 0x700 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL2_PORT9_PRIORITY_OFFSET 4 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL2_PORT9_PRIORITY_MASK 0x70 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL2_PORT8_PRIORITY_OFFSET 0 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL2_PORT8_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM1_CTRL0 0x0859 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT3_PRIORITY_OFFSET 12 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT3_PRIORITY_MASK 0x7000 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT2_PRIORITY_OFFSET 8 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT2_PRIORITY_MASK 0x700 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT1_PRIORITY_OFFSET 4 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT1_PRIORITY_MASK 0x70 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT0_PRIORITY_OFFSET 0 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT0_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM1_CTRL1 0x085a -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT7_PRIORITY_OFFSET 12 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT7_PRIORITY_MASK 0x7000 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT6_PRIORITY_OFFSET 8 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT6_PRIORITY_MASK 0x700 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT5_PRIORITY_OFFSET 4 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT5_PRIORITY_MASK 0x70 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT4_PRIORITY_OFFSET 0 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT4_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM1_CTRL2 0x085b -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL2_PORT10_PRIORITY_OFFSET 8 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL2_PORT10_PRIORITY_MASK 0x700 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL2_PORT9_PRIORITY_OFFSET 4 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL2_PORT9_PRIORITY_MASK 0x70 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL2_PORT8_PRIORITY_OFFSET 0 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL2_PORT8_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM2_CTRL0 0x085d -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT3_PRIORITY_OFFSET 12 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT3_PRIORITY_MASK 0x7000 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT2_PRIORITY_OFFSET 8 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT2_PRIORITY_MASK 0x700 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT1_PRIORITY_OFFSET 4 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT1_PRIORITY_MASK 0x70 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT0_PRIORITY_OFFSET 0 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT0_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM2_CTRL1 0x085e -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT7_PRIORITY_OFFSET 12 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT7_PRIORITY_MASK 0x7000 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT6_PRIORITY_OFFSET 8 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT6_PRIORITY_MASK 0x700 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT5_PRIORITY_OFFSET 4 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT5_PRIORITY_MASK 0x70 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT4_PRIORITY_OFFSET 0 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT4_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM2_CTRL2 0x085f -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL2_PORT10_PRIORITY_OFFSET 8 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL2_PORT10_PRIORITY_MASK 0x700 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL2_PORT9_PRIORITY_OFFSET 4 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL2_PORT9_PRIORITY_MASK 0x70 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL2_PORT8_PRIORITY_OFFSET 0 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL2_PORT8_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM3_CTRL0 0x0861 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT3_PRIORITY_OFFSET 12 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT3_PRIORITY_MASK 0x7000 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT2_PRIORITY_OFFSET 8 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT2_PRIORITY_MASK 0x700 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT1_PRIORITY_OFFSET 4 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT1_PRIORITY_MASK 0x70 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT0_PRIORITY_OFFSET 0 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT0_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM3_CTRL1 0x0862 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT7_PRIORITY_OFFSET 12 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT7_PRIORITY_MASK 0x7000 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT6_PRIORITY_OFFSET 8 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT6_PRIORITY_MASK 0x700 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT5_PRIORITY_OFFSET 4 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT5_PRIORITY_MASK 0x70 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT4_PRIORITY_OFFSET 0 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT4_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM3_CTRL2 0x0863 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL2_PORT10_PRIORITY_OFFSET 8 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL2_PORT10_PRIORITY_MASK 0x700 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL2_PORT9_PRIORITY_OFFSET 4 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL2_PORT9_PRIORITY_MASK 0x70 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL2_PORT8_PRIORITY_OFFSET 0 -+#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL2_PORT8_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_1Q_PRIORITY_REMAPPING_CTRL0 0x0865 -+#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY3_OFFSET 12 -+#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY3_MASK 0x7000 -+#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY2_OFFSET 8 -+#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY2_MASK 0x700 -+#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY1_OFFSET 4 -+#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY1_MASK 0x70 -+#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY0_OFFSET 0 -+#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY0_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_1Q_PRIORITY_REMAPPING_CTRL1 0x0866 -+#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY7_OFFSET 12 -+#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY7_MASK 0x7000 -+#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY6_OFFSET 8 -+#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY6_MASK 0x700 -+#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY5_OFFSET 4 -+#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY5_MASK 0x70 -+#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY4_OFFSET 0 -+#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY4_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL0 0x0867 -+#define RTL8367C_DSCP3_PRIORITY_OFFSET 12 -+#define RTL8367C_DSCP3_PRIORITY_MASK 0x7000 -+#define RTL8367C_DSCP2_PRIORITY_OFFSET 8 -+#define RTL8367C_DSCP2_PRIORITY_MASK 0x700 -+#define RTL8367C_DSCP1_PRIORITY_OFFSET 4 -+#define RTL8367C_DSCP1_PRIORITY_MASK 0x70 -+#define RTL8367C_DSCP0_PRIORITY_OFFSET 0 -+#define RTL8367C_DSCP0_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL1 0x0868 -+#define RTL8367C_DSCP7_PRIORITY_OFFSET 12 -+#define RTL8367C_DSCP7_PRIORITY_MASK 0x7000 -+#define RTL8367C_DSCP6_PRIORITY_OFFSET 8 -+#define RTL8367C_DSCP6_PRIORITY_MASK 0x700 -+#define RTL8367C_DSCP5_PRIORITY_OFFSET 4 -+#define RTL8367C_DSCP5_PRIORITY_MASK 0x70 -+#define RTL8367C_DSCP4_PRIORITY_OFFSET 0 -+#define RTL8367C_DSCP4_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL2 0x0869 -+#define RTL8367C_DSCP11_PRIORITY_OFFSET 12 -+#define RTL8367C_DSCP11_PRIORITY_MASK 0x7000 -+#define RTL8367C_DSCP10_PRIORITY_OFFSET 8 -+#define RTL8367C_DSCP10_PRIORITY_MASK 0x700 -+#define RTL8367C_DSCP9_PRIORITY_OFFSET 4 -+#define RTL8367C_DSCP9_PRIORITY_MASK 0x70 -+#define RTL8367C_DSCP8_PRIORITY_OFFSET 0 -+#define RTL8367C_DSCP8_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL3 0x086a -+#define RTL8367C_DSCP15_PRIORITY_OFFSET 12 -+#define RTL8367C_DSCP15_PRIORITY_MASK 0x7000 -+#define RTL8367C_DSCP14_PRIORITY_OFFSET 8 -+#define RTL8367C_DSCP14_PRIORITY_MASK 0x700 -+#define RTL8367C_DSCP13_PRIORITY_OFFSET 4 -+#define RTL8367C_DSCP13_PRIORITY_MASK 0x70 -+#define RTL8367C_DSCP12_PRIORITY_OFFSET 0 -+#define RTL8367C_DSCP12_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL4 0x086b -+#define RTL8367C_DSCP19_PRIORITY_OFFSET 12 -+#define RTL8367C_DSCP19_PRIORITY_MASK 0x7000 -+#define RTL8367C_DSCP18_PRIORITY_OFFSET 8 -+#define RTL8367C_DSCP18_PRIORITY_MASK 0x700 -+#define RTL8367C_DSCP17_PRIORITY_OFFSET 4 -+#define RTL8367C_DSCP17_PRIORITY_MASK 0x70 -+#define RTL8367C_DSCP16_PRIORITY_OFFSET 0 -+#define RTL8367C_DSCP16_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL5 0x086c -+#define RTL8367C_DSCP23_PRIORITY_OFFSET 12 -+#define RTL8367C_DSCP23_PRIORITY_MASK 0x7000 -+#define RTL8367C_DSCP22_PRIORITY_OFFSET 8 -+#define RTL8367C_DSCP22_PRIORITY_MASK 0x700 -+#define RTL8367C_DSCP21_PRIORITY_OFFSET 4 -+#define RTL8367C_DSCP21_PRIORITY_MASK 0x70 -+#define RTL8367C_DSCP20_PRIORITY_OFFSET 0 -+#define RTL8367C_DSCP20_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL6 0x086d -+#define RTL8367C_DSCP27_PRIORITY_OFFSET 12 -+#define RTL8367C_DSCP27_PRIORITY_MASK 0x7000 -+#define RTL8367C_DSCP26_PRIORITY_OFFSET 8 -+#define RTL8367C_DSCP26_PRIORITY_MASK 0x700 -+#define RTL8367C_DSCP25_PRIORITY_OFFSET 4 -+#define RTL8367C_DSCP25_PRIORITY_MASK 0x70 -+#define RTL8367C_DSCP24_PRIORITY_OFFSET 0 -+#define RTL8367C_DSCP24_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL7 0x086e -+#define RTL8367C_DSCP31_PRIORITY_OFFSET 12 -+#define RTL8367C_DSCP31_PRIORITY_MASK 0x7000 -+#define RTL8367C_DSCP30_PRIORITY_OFFSET 8 -+#define RTL8367C_DSCP30_PRIORITY_MASK 0x700 -+#define RTL8367C_DSCP29_PRIORITY_OFFSET 4 -+#define RTL8367C_DSCP29_PRIORITY_MASK 0x70 -+#define RTL8367C_DSCP28_PRIORITY_OFFSET 0 -+#define RTL8367C_DSCP28_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL8 0x086f -+#define RTL8367C_DSCP35_PRIORITY_OFFSET 12 -+#define RTL8367C_DSCP35_PRIORITY_MASK 0x7000 -+#define RTL8367C_DSCP34_PRIORITY_OFFSET 8 -+#define RTL8367C_DSCP34_PRIORITY_MASK 0x700 -+#define RTL8367C_DSCP33_PRIORITY_OFFSET 4 -+#define RTL8367C_DSCP33_PRIORITY_MASK 0x70 -+#define RTL8367C_DSCP32_PRIORITY_OFFSET 0 -+#define RTL8367C_DSCP32_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL9 0x0870 -+#define RTL8367C_DSCP39_PRIORITY_OFFSET 12 -+#define RTL8367C_DSCP39_PRIORITY_MASK 0x7000 -+#define RTL8367C_DSCP38_PRIORITY_OFFSET 8 -+#define RTL8367C_DSCP38_PRIORITY_MASK 0x700 -+#define RTL8367C_DSCP37_PRIORITY_OFFSET 4 -+#define RTL8367C_DSCP37_PRIORITY_MASK 0x70 -+#define RTL8367C_DSCP36_PRIORITY_OFFSET 0 -+#define RTL8367C_DSCP36_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL10 0x0871 -+#define RTL8367C_DSCP43_PRIORITY_OFFSET 12 -+#define RTL8367C_DSCP43_PRIORITY_MASK 0x7000 -+#define RTL8367C_DSCP42_PRIORITY_OFFSET 8 -+#define RTL8367C_DSCP42_PRIORITY_MASK 0x700 -+#define RTL8367C_DSCP41_PRIORITY_OFFSET 4 -+#define RTL8367C_DSCP41_PRIORITY_MASK 0x70 -+#define RTL8367C_DSCP40_PRIORITY_OFFSET 0 -+#define RTL8367C_DSCP40_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL11 0x0872 -+#define RTL8367C_DSCP47_PRIORITY_OFFSET 12 -+#define RTL8367C_DSCP47_PRIORITY_MASK 0x7000 -+#define RTL8367C_DSCP46_PRIORITY_OFFSET 8 -+#define RTL8367C_DSCP46_PRIORITY_MASK 0x700 -+#define RTL8367C_DSCP45_PRIORITY_OFFSET 4 -+#define RTL8367C_DSCP45_PRIORITY_MASK 0x70 -+#define RTL8367C_DSCP44_PRIORITY_OFFSET 0 -+#define RTL8367C_DSCP44_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL12 0x0873 -+#define RTL8367C_DSCP51_PRIORITY_OFFSET 12 -+#define RTL8367C_DSCP51_PRIORITY_MASK 0x7000 -+#define RTL8367C_DSCP50_PRIORITY_OFFSET 8 -+#define RTL8367C_DSCP50_PRIORITY_MASK 0x700 -+#define RTL8367C_DSCP49_PRIORITY_OFFSET 4 -+#define RTL8367C_DSCP49_PRIORITY_MASK 0x70 -+#define RTL8367C_DSCP48_PRIORITY_OFFSET 0 -+#define RTL8367C_DSCP48_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL13 0x0874 -+#define RTL8367C_DSCP55_PRIORITY_OFFSET 12 -+#define RTL8367C_DSCP55_PRIORITY_MASK 0x7000 -+#define RTL8367C_DSCP54_PRIORITY_OFFSET 8 -+#define RTL8367C_DSCP54_PRIORITY_MASK 0x700 -+#define RTL8367C_DSCP53_PRIORITY_OFFSET 4 -+#define RTL8367C_DSCP53_PRIORITY_MASK 0x70 -+#define RTL8367C_DSCP52_PRIORITY_OFFSET 0 -+#define RTL8367C_DSCP52_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL14 0x0875 -+#define RTL8367C_DSCP59_PRIORITY_OFFSET 12 -+#define RTL8367C_DSCP59_PRIORITY_MASK 0x7000 -+#define RTL8367C_DSCP58_PRIORITY_OFFSET 8 -+#define RTL8367C_DSCP58_PRIORITY_MASK 0x700 -+#define RTL8367C_DSCP57_PRIORITY_OFFSET 4 -+#define RTL8367C_DSCP57_PRIORITY_MASK 0x70 -+#define RTL8367C_DSCP56_PRIORITY_OFFSET 0 -+#define RTL8367C_DSCP56_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL15 0x0876 -+#define RTL8367C_DSCP63_PRIORITY_OFFSET 12 -+#define RTL8367C_DSCP63_PRIORITY_MASK 0x7000 -+#define RTL8367C_DSCP62_PRIORITY_OFFSET 8 -+#define RTL8367C_DSCP62_PRIORITY_MASK 0x700 -+#define RTL8367C_DSCP61_PRIORITY_OFFSET 4 -+#define RTL8367C_DSCP61_PRIORITY_MASK 0x70 -+#define RTL8367C_DSCP60_PRIORITY_OFFSET 0 -+#define RTL8367C_DSCP60_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_PORTBASED_PRIORITY_CTRL0 0x0877 -+#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT3_PRIORITY_OFFSET 12 -+#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT3_PRIORITY_MASK 0x7000 -+#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT2_PRIORITY_OFFSET 8 -+#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT2_PRIORITY_MASK 0x700 -+#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT1_PRIORITY_OFFSET 4 -+#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT1_PRIORITY_MASK 0x70 -+#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT0_PRIORITY_OFFSET 0 -+#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT0_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_PORTBASED_PRIORITY_CTRL1 0x0878 -+#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT7_PRIORITY_OFFSET 12 -+#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT7_PRIORITY_MASK 0x7000 -+#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT6_PRIORITY_OFFSET 8 -+#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT6_PRIORITY_MASK 0x700 -+#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT5_PRIORITY_OFFSET 4 -+#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT5_PRIORITY_MASK 0x70 -+#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT4_PRIORITY_OFFSET 0 -+#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT4_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_DUMMY0879 0x0879 -+#define RTL8367C_DUMMY0879_OFFSET 0 -+#define RTL8367C_DUMMY0879_MASK 0x1 -+ -+#define RTL8367C_REG_QOS_PORTBASED_PRIORITY_CTRL2 0x087a -+#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL2_PORT10_PRIORITY_OFFSET 8 -+#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL2_PORT10_PRIORITY_MASK 0x700 -+#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL2_PORT9_PRIORITY_OFFSET 4 -+#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL2_PORT9_PRIORITY_MASK 0x70 -+#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL2_PORT8_PRIORITY_OFFSET 0 -+#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL2_PORT8_PRIORITY_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION_CTRL0 0x087b -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL0_QOS_ACL_WEIGHT_OFFSET 8 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL0_QOS_ACL_WEIGHT_MASK 0xFF00 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL0_QOS_PORT_WEIGHT_OFFSET 0 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL0_QOS_PORT_WEIGHT_MASK 0xFF -+ -+#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION_CTRL1 0x087c -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL1_QOS_DOT1Q_WEIGHT_OFFSET 8 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL1_QOS_DOT1Q_WEIGHT_MASK 0xFF00 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL1_QOS_DSCP_WEIGHT_OFFSET 0 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL1_QOS_DSCP_WEIGHT_MASK 0xFF -+ -+#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION_CTRL2 0x087d -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL2_QOS_CVLAN_WEIGHT_OFFSET 8 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL2_QOS_CVLAN_WEIGHT_MASK 0xFF00 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL2_QOS_SVLAN_WEIGHT_OFFSET 0 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL2_QOS_SVLAN_WEIGHT_MASK 0xFF -+ -+#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION_CTRL3 0x087e -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL3_QOS_SA_WEIGHT_OFFSET 8 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL3_QOS_SA_WEIGHT_MASK 0xFF00 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL3_QOS_LUTFWD_WEIGHT_OFFSET 0 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL3_QOS_LUTFWD_WEIGHT_MASK 0xFF -+ -+#define RTL8367C_REG_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0 0x087f -+#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY3_OFFSET 12 -+#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY3_MASK 0x7000 -+#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY2_OFFSET 8 -+#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY2_MASK 0x700 -+#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY1_OFFSET 4 -+#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY1_MASK 0x70 -+#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY0_OFFSET 0 -+#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY0_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1 0x0880 -+#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY7_OFFSET 12 -+#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY7_MASK 0x7000 -+#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY6_OFFSET 8 -+#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY6_MASK 0x700 -+#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY5_OFFSET 4 -+#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY5_MASK 0x70 -+#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY4_OFFSET 0 -+#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY4_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_TRAP_PRIORITY0 0x0881 -+#define RTL8367C_UNKNOWN_MC_PRIORTY_OFFSET 12 -+#define RTL8367C_UNKNOWN_MC_PRIORTY_MASK 0x7000 -+#define RTL8367C_SVLAN_PRIOIRTY_OFFSET 8 -+#define RTL8367C_SVLAN_PRIOIRTY_MASK 0x700 -+#define RTL8367C_OAM_PRIOIRTY_OFFSET 4 -+#define RTL8367C_OAM_PRIOIRTY_MASK 0x70 -+#define RTL8367C_DOT1X_PRIORTY_OFFSET 0 -+#define RTL8367C_DOT1X_PRIORTY_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_TRAP_PRIORITY1 0x0882 -+#define RTL8367C_DW8051_TRAP_PRI_OFFSET 4 -+#define RTL8367C_DW8051_TRAP_PRI_MASK 0x70 -+#define RTL8367C_EEELLDP_TRAP_PRI_OFFSET 0 -+#define RTL8367C_EEELLDP_TRAP_PRI_MASK 0x7 -+ -+#define RTL8367C_REG_MAX_LENGTH_CFG 0x0883 -+#define RTL8367C_MAX_LENGTH_GIGA_OFFSET 8 -+#define RTL8367C_MAX_LENGTH_GIGA_MASK 0xFF00 -+#define RTL8367C_MAX_LENGTH_10_100M_OFFSET 0 -+#define RTL8367C_MAX_LENGTH_10_100M_MASK 0xFF -+ -+#define RTL8367C_REG_MAX_LEN_RX_TX 0x0884 -+#define RTL8367C_MAX_LEN_RX_TX_OFFSET 0 -+#define RTL8367C_MAX_LEN_RX_TX_MASK 0x3 -+ -+#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION2_CTRL0 0x0885 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL0_QOS_ACL_WEIGHT_OFFSET 8 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL0_QOS_ACL_WEIGHT_MASK 0xFF00 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL0_QOS_PORT_WEIGHT_OFFSET 0 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL0_QOS_PORT_WEIGHT_MASK 0xFF -+ -+#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION2_CTRL1 0x0886 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL1_QOS_DOT1Q_WEIGHT_OFFSET 8 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL1_QOS_DOT1Q_WEIGHT_MASK 0xFF00 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL1_QOS_DSCP_WEIGHT_OFFSET 0 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL1_QOS_DSCP_WEIGHT_MASK 0xFF -+ -+#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION2_CTRL2 0x0887 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL2_QOS_CVLAN_WEIGHT_OFFSET 8 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL2_QOS_CVLAN_WEIGHT_MASK 0xFF00 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL2_QOS_SVLAN_WEIGHT_OFFSET 0 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL2_QOS_SVLAN_WEIGHT_MASK 0xFF -+ -+#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION2_CTRL3 0x0888 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL3_QOS_SA_WEIGHT_OFFSET 8 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL3_QOS_SA_WEIGHT_MASK 0xFF00 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL3_QOS_LUTFWD_WEIGHT_OFFSET 0 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL3_QOS_LUTFWD_WEIGHT_MASK 0xFF -+ -+#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION_IDX 0x0889 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_IDX_OFFSET 0 -+#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_IDX_MASK 0x7FF -+ -+#define RTL8367C_REG_MAX_LENGTH_CFG_EXT 0x088a -+#define RTL8367C_MAX_LENGTH_GIGA_EXT_OFFSET 3 -+#define RTL8367C_MAX_LENGTH_GIGA_EXT_MASK 0x38 -+#define RTL8367C_MAX_LENGTH_10_100M_EXT_OFFSET 0 -+#define RTL8367C_MAX_LENGTH_10_100M_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_MAX_LEN_RX_TX_CFG0 0x088c -+#define RTL8367C_MAX_LEN_RX_TX_CFG0_OFFSET 0 -+#define RTL8367C_MAX_LEN_RX_TX_CFG0_MASK 0x3FFF -+ -+#define RTL8367C_REG_MAX_LEN_RX_TX_CFG1 0x088d -+#define RTL8367C_MAX_LEN_RX_TX_CFG1_OFFSET 0 -+#define RTL8367C_MAX_LEN_RX_TX_CFG1_MASK 0x3FFF -+ -+#define RTL8367C_REG_UNDA_FLOODING_PMSK 0x0890 -+#define RTL8367C_UNDA_FLOODING_PMSK_OFFSET 0 -+#define RTL8367C_UNDA_FLOODING_PMSK_MASK 0x7FF -+ -+#define RTL8367C_REG_UNMCAST_FLOADING_PMSK 0x0891 -+#define RTL8367C_UNMCAST_FLOADING_PMSK_OFFSET 0 -+#define RTL8367C_UNMCAST_FLOADING_PMSK_MASK 0x7FF -+ -+#define RTL8367C_REG_BCAST_FLOADING_PMSK 0x0892 -+#define RTL8367C_BCAST_FLOADING_PMSK_OFFSET 0 -+#define RTL8367C_BCAST_FLOADING_PMSK_MASK 0x7FF -+ -+#define RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL2 0x08a0 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH7_OFFSET 14 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH7_MASK 0xC000 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH6_OFFSET 12 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH6_MASK 0x3000 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH5_OFFSET 10 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH5_MASK 0xC00 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH4_OFFSET 8 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH4_MASK 0x300 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH3_OFFSET 6 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH3_MASK 0xC0 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH2_OFFSET 4 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH2_MASK 0x30 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH1_OFFSET 2 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH1_MASK 0xC -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH0_OFFSET 0 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH0_MASK 0x3 -+ -+#define RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL3 0x08a1 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH15_OFFSET 14 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH15_MASK 0xC000 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH14_OFFSET 12 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH14_MASK 0x3000 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH13_OFFSET 10 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH13_MASK 0xC00 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH12_OFFSET 8 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH12_MASK 0x300 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH11_OFFSET 6 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH11_MASK 0xC0 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH10_OFFSET 4 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH10_MASK 0x30 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH9_OFFSET 2 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH9_MASK 0xC -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH8_OFFSET 0 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH8_MASK 0x3 -+ -+#define RTL8367C_REG_PORT_ISOLATION_PORT0_MASK 0x08a2 -+#define RTL8367C_PORT_ISOLATION_PORT0_MASK_OFFSET 0 -+#define RTL8367C_PORT_ISOLATION_PORT0_MASK_MASK 0x7FF -+ -+#define RTL8367C_REG_PORT_ISOLATION_PORT1_MASK 0x08a3 -+#define RTL8367C_PORT_ISOLATION_PORT1_MASK_OFFSET 0 -+#define RTL8367C_PORT_ISOLATION_PORT1_MASK_MASK 0x7FF -+ -+#define RTL8367C_REG_PORT_ISOLATION_PORT2_MASK 0x08a4 -+#define RTL8367C_PORT_ISOLATION_PORT2_MASK_OFFSET 0 -+#define RTL8367C_PORT_ISOLATION_PORT2_MASK_MASK 0x7FF -+ -+#define RTL8367C_REG_PORT_ISOLATION_PORT3_MASK 0x08a5 -+#define RTL8367C_PORT_ISOLATION_PORT3_MASK_OFFSET 0 -+#define RTL8367C_PORT_ISOLATION_PORT3_MASK_MASK 0x7FF -+ -+#define RTL8367C_REG_PORT_ISOLATION_PORT4_MASK 0x08a6 -+#define RTL8367C_PORT_ISOLATION_PORT4_MASK_OFFSET 0 -+#define RTL8367C_PORT_ISOLATION_PORT4_MASK_MASK 0x7FF -+ -+#define RTL8367C_REG_PORT_ISOLATION_PORT5_MASK 0x08a7 -+#define RTL8367C_PORT_ISOLATION_PORT5_MASK_OFFSET 0 -+#define RTL8367C_PORT_ISOLATION_PORT5_MASK_MASK 0x7FF -+ -+#define RTL8367C_REG_PORT_ISOLATION_PORT6_MASK 0x08a8 -+#define RTL8367C_PORT_ISOLATION_PORT6_MASK_OFFSET 0 -+#define RTL8367C_PORT_ISOLATION_PORT6_MASK_MASK 0x7FF -+ -+#define RTL8367C_REG_PORT_ISOLATION_PORT7_MASK 0x08a9 -+#define RTL8367C_PORT_ISOLATION_PORT7_MASK_OFFSET 0 -+#define RTL8367C_PORT_ISOLATION_PORT7_MASK_MASK 0x7FF -+ -+#define RTL8367C_REG_PORT_ISOLATION_PORT8_MASK 0x08aa -+#define RTL8367C_PORT_ISOLATION_PORT8_MASK_OFFSET 0 -+#define RTL8367C_PORT_ISOLATION_PORT8_MASK_MASK 0x7FF -+ -+#define RTL8367C_REG_PORT_ISOLATION_PORT9_MASK 0x08ab -+#define RTL8367C_PORT_ISOLATION_PORT9_MASK_OFFSET 0 -+#define RTL8367C_PORT_ISOLATION_PORT9_MASK_MASK 0x7FF -+ -+#define RTL8367C_REG_PORT_ISOLATION_PORT10_MASK 0x08ac -+#define RTL8367C_PORT_ISOLATION_PORT10_MASK_OFFSET 0 -+#define RTL8367C_PORT_ISOLATION_PORT10_MASK_MASK 0x7FF -+ -+#define RTL8367C_REG_FORCE_CTRL 0x08b4 -+#define RTL8367C_FORCE_CTRL_OFFSET 0 -+#define RTL8367C_FORCE_CTRL_MASK 0x7FF -+ -+#define RTL8367C_REG_FORCE_PORT0_MASK 0x08b5 -+#define RTL8367C_FORCE_PORT0_MASK_OFFSET 0 -+#define RTL8367C_FORCE_PORT0_MASK_MASK 0x7FF -+ -+#define RTL8367C_REG_FORCE_PORT1_MASK 0x08b6 -+#define RTL8367C_FORCE_PORT1_MASK_OFFSET 0 -+#define RTL8367C_FORCE_PORT1_MASK_MASK 0x7FF -+ -+#define RTL8367C_REG_FORCE_PORT2_MASK 0x08b7 -+#define RTL8367C_FORCE_PORT2_MASK_OFFSET 0 -+#define RTL8367C_FORCE_PORT2_MASK_MASK 0x7FF -+ -+#define RTL8367C_REG_FORCE_PORT3_MASK 0x08b8 -+#define RTL8367C_FORCE_PORT3_MASK_OFFSET 0 -+#define RTL8367C_FORCE_PORT3_MASK_MASK 0x7FF -+ -+#define RTL8367C_REG_FORCE_PORT4_MASK 0x08b9 -+#define RTL8367C_FORCE_PORT4_MASK_OFFSET 0 -+#define RTL8367C_FORCE_PORT4_MASK_MASK 0x7FF -+ -+#define RTL8367C_REG_FORCE_PORT5_MASK 0x08ba -+#define RTL8367C_FORCE_PORT5_MASK_OFFSET 0 -+#define RTL8367C_FORCE_PORT5_MASK_MASK 0x7FF -+ -+#define RTL8367C_REG_FORCE_PORT6_MASK 0x08bb -+#define RTL8367C_FORCE_PORT6_MASK_OFFSET 0 -+#define RTL8367C_FORCE_PORT6_MASK_MASK 0x7FF -+ -+#define RTL8367C_REG_FORCE_PORT7_MASK 0x08bc -+#define RTL8367C_FORCE_PORT7_MASK_OFFSET 0 -+#define RTL8367C_FORCE_PORT7_MASK_MASK 0x7FF -+ -+#define RTL8367C_REG_FORCE_PORT8_MASK 0x08bd -+#define RTL8367C_FORCE_PORT8_MASK_OFFSET 0 -+#define RTL8367C_FORCE_PORT8_MASK_MASK 0x7FF -+ -+#define RTL8367C_REG_FORCE_PORT9_MASK 0x08be -+#define RTL8367C_FORCE_PORT9_MASK_OFFSET 0 -+#define RTL8367C_FORCE_PORT9_MASK_MASK 0x7FF -+ -+#define RTL8367C_REG_FORCE_PORT10_MASK 0x08bf -+#define RTL8367C_FORCE_PORT10_MASK_OFFSET 0 -+#define RTL8367C_FORCE_PORT10_MASK_MASK 0x7FF -+ -+#define RTL8367C_REG_SOURCE_PORT_PERMIT 0x08c5 -+#define RTL8367C_SOURCE_PORT_PERMIT_OFFSET 0 -+#define RTL8367C_SOURCE_PORT_PERMIT_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMCAST_VLAN_LEAKY 0x08c6 -+#define RTL8367C_IPMCAST_VLAN_LEAKY_OFFSET 0 -+#define RTL8367C_IPMCAST_VLAN_LEAKY_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMCAST_PORTISO_LEAKY 0x08c7 -+#define RTL8367C_IPMCAST_PORTISO_LEAKY_OFFSET 0 -+#define RTL8367C_IPMCAST_PORTISO_LEAKY_MASK 0x7FF -+ -+#define RTL8367C_REG_PORT_SECURITY_CTRL 0x08c8 -+#define RTL8367C_UNKNOWN_UNICAST_DA_BEHAVE_OFFSET 6 -+#define RTL8367C_UNKNOWN_UNICAST_DA_BEHAVE_MASK 0xC0 -+#define RTL8367C_LUT_LEARN_OVER_ACT_OFFSET 4 -+#define RTL8367C_LUT_LEARN_OVER_ACT_MASK 0x30 -+#define RTL8367C_UNMATCHED_SA_BEHAVE_OFFSET 2 -+#define RTL8367C_UNMATCHED_SA_BEHAVE_MASK 0xC -+#define RTL8367C_UNKNOWN_SA_BEHAVE_OFFSET 0 -+#define RTL8367C_UNKNOWN_SA_BEHAVE_MASK 0x3 -+ -+#define RTL8367C_REG_UNKNOWN_IPV4_MULTICAST_CTRL0 0x08c9 -+#define RTL8367C_PORT7_UNKNOWN_IP4_MCAST_OFFSET 14 -+#define RTL8367C_PORT7_UNKNOWN_IP4_MCAST_MASK 0xC000 -+#define RTL8367C_PORT6_UNKNOWN_IP4_MCAST_OFFSET 12 -+#define RTL8367C_PORT6_UNKNOWN_IP4_MCAST_MASK 0x3000 -+#define RTL8367C_PORT5_UNKNOWN_IP4_MCAST_OFFSET 10 -+#define RTL8367C_PORT5_UNKNOWN_IP4_MCAST_MASK 0xC00 -+#define RTL8367C_PORT4_UNKNOWN_IP4_MCAST_OFFSET 8 -+#define RTL8367C_PORT4_UNKNOWN_IP4_MCAST_MASK 0x300 -+#define RTL8367C_PORT3_UNKNOWN_IP4_MCAST_OFFSET 6 -+#define RTL8367C_PORT3_UNKNOWN_IP4_MCAST_MASK 0xC0 -+#define RTL8367C_PORT2_UNKNOWN_IP4_MCAST_OFFSET 4 -+#define RTL8367C_PORT2_UNKNOWN_IP4_MCAST_MASK 0x30 -+#define RTL8367C_PORT1_UNKNOWN_IP4_MCAST_OFFSET 2 -+#define RTL8367C_PORT1_UNKNOWN_IP4_MCAST_MASK 0xC -+#define RTL8367C_PORT0_UNKNOWN_IP4_MCAST_OFFSET 0 -+#define RTL8367C_PORT0_UNKNOWN_IP4_MCAST_MASK 0x3 -+ -+#define RTL8367C_REG_UNKNOWN_IPV4_MULTICAST_CTRL1 0x08ca -+#define RTL8367C_PORT10_UNKNOWN_IP4_MCAST_OFFSET 4 -+#define RTL8367C_PORT10_UNKNOWN_IP4_MCAST_MASK 0x30 -+#define RTL8367C_PORT9_UNKNOWN_IP4_MCAST_OFFSET 2 -+#define RTL8367C_PORT9_UNKNOWN_IP4_MCAST_MASK 0xC -+#define RTL8367C_PORT8_UNKNOWN_IP4_MCAST_OFFSET 0 -+#define RTL8367C_PORT8_UNKNOWN_IP4_MCAST_MASK 0x3 -+ -+#define RTL8367C_REG_UNKNOWN_IPV6_MULTICAST_CTRL0 0x08cb -+#define RTL8367C_PORT7_UNKNOWN_IP6_MCAST_OFFSET 14 -+#define RTL8367C_PORT7_UNKNOWN_IP6_MCAST_MASK 0xC000 -+#define RTL8367C_PORT6_UNKNOWN_IP6_MCAST_OFFSET 12 -+#define RTL8367C_PORT6_UNKNOWN_IP6_MCAST_MASK 0x3000 -+#define RTL8367C_PORT5_UNKNOWN_IP6_MCAST_OFFSET 10 -+#define RTL8367C_PORT5_UNKNOWN_IP6_MCAST_MASK 0xC00 -+#define RTL8367C_PORT4_UNKNOWN_IP6_MCAST_OFFSET 8 -+#define RTL8367C_PORT4_UNKNOWN_IP6_MCAST_MASK 0x300 -+#define RTL8367C_PORT3_UNKNOWN_IP6_MCAST_OFFSET 6 -+#define RTL8367C_PORT3_UNKNOWN_IP6_MCAST_MASK 0xC0 -+#define RTL8367C_PORT2_UNKNOWN_IP6_MCAST_OFFSET 4 -+#define RTL8367C_PORT2_UNKNOWN_IP6_MCAST_MASK 0x30 -+#define RTL8367C_PORT1_UNKNOWN_IP6_MCAST_OFFSET 2 -+#define RTL8367C_PORT1_UNKNOWN_IP6_MCAST_MASK 0xC -+#define RTL8367C_PORT0_UNKNOWN_IP6_MCAST_OFFSET 0 -+#define RTL8367C_PORT0_UNKNOWN_IP6_MCAST_MASK 0x3 -+ -+#define RTL8367C_REG_UNKNOWN_IPV6_MULTICAST_CTRL1 0x08cc -+#define RTL8367C_PORT10_UNKNOWN_IP6_MCAST_OFFSET 4 -+#define RTL8367C_PORT10_UNKNOWN_IP6_MCAST_MASK 0x30 -+#define RTL8367C_PORT9_UNKNOWN_IP6_MCAST_OFFSET 2 -+#define RTL8367C_PORT9_UNKNOWN_IP6_MCAST_MASK 0xC -+#define RTL8367C_PORT8_UNKNOWN_IP6_MCAST_OFFSET 0 -+#define RTL8367C_PORT8_UNKNOWN_IP6_MCAST_MASK 0x3 -+ -+#define RTL8367C_REG_UNKNOWN_L2_MULTICAST_CTRL0 0x08cd -+#define RTL8367C_PORT7_UNKNOWN_L2_MCAST_OFFSET 14 -+#define RTL8367C_PORT7_UNKNOWN_L2_MCAST_MASK 0xC000 -+#define RTL8367C_PORT6_UNKNOWN_L2_MCAST_OFFSET 12 -+#define RTL8367C_PORT6_UNKNOWN_L2_MCAST_MASK 0x3000 -+#define RTL8367C_PORT5_UNKNOWN_L2_MCAST_OFFSET 10 -+#define RTL8367C_PORT5_UNKNOWN_L2_MCAST_MASK 0xC00 -+#define RTL8367C_PORT4_UNKNOWN_L2_MCAST_OFFSET 8 -+#define RTL8367C_PORT4_UNKNOWN_L2_MCAST_MASK 0x300 -+#define RTL8367C_PORT3_UNKNOWN_L2_MCAST_OFFSET 6 -+#define RTL8367C_PORT3_UNKNOWN_L2_MCAST_MASK 0xC0 -+#define RTL8367C_PORT2_UNKNOWN_L2_MCAST_OFFSET 4 -+#define RTL8367C_PORT2_UNKNOWN_L2_MCAST_MASK 0x30 -+#define RTL8367C_PORT1_UNKNOWN_L2_MCAST_OFFSET 2 -+#define RTL8367C_PORT1_UNKNOWN_L2_MCAST_MASK 0xC -+#define RTL8367C_PORT0_UNKNOWN_L2_MCAST_OFFSET 0 -+#define RTL8367C_PORT0_UNKNOWN_L2_MCAST_MASK 0x3 -+ -+#define RTL8367C_REG_PORT_TRUNK_DROP_CTRL 0x08ce -+#define RTL8367C_PORT_TRUNK_DROP_CTRL_OFFSET 0 -+#define RTL8367C_PORT_TRUNK_DROP_CTRL_MASK 0x1 -+ -+#define RTL8367C_REG_PORT_TRUNK_CTRL 0x08cf -+#define RTL8367C_PORT_TRUNK_DUMB_OFFSET 8 -+#define RTL8367C_PORT_TRUNK_DUMB_MASK 0x100 -+#define RTL8367C_PORT_TRUNK_FLOOD_OFFSET 7 -+#define RTL8367C_PORT_TRUNK_FLOOD_MASK 0x80 -+#define RTL8367C_DPORT_HASH_OFFSET 6 -+#define RTL8367C_DPORT_HASH_MASK 0x40 -+#define RTL8367C_SPORT_HASH_OFFSET 5 -+#define RTL8367C_SPORT_HASH_MASK 0x20 -+#define RTL8367C_DIP_HASH_OFFSET 4 -+#define RTL8367C_DIP_HASH_MASK 0x10 -+#define RTL8367C_SIP_HASH_OFFSET 3 -+#define RTL8367C_SIP_HASH_MASK 0x8 -+#define RTL8367C_DMAC_HASH_OFFSET 2 -+#define RTL8367C_DMAC_HASH_MASK 0x4 -+#define RTL8367C_SMAC_HASH_OFFSET 1 -+#define RTL8367C_SMAC_HASH_MASK 0x2 -+#define RTL8367C_SPA_HASH_OFFSET 0 -+#define RTL8367C_SPA_HASH_MASK 0x1 -+ -+#define RTL8367C_REG_PORT_TRUNK_GROUP_MASK 0x08d0 -+#define RTL8367C_PORT_TRUNK_GROUP2_MASK_OFFSET 8 -+#define RTL8367C_PORT_TRUNK_GROUP2_MASK_MASK 0x300 -+#define RTL8367C_PORT_TRUNK_GROUP1_MASK_OFFSET 4 -+#define RTL8367C_PORT_TRUNK_GROUP1_MASK_MASK 0xF0 -+#define RTL8367C_PORT_TRUNK_GROUP0_MASK_OFFSET 0 -+#define RTL8367C_PORT_TRUNK_GROUP0_MASK_MASK 0xF -+ -+#define RTL8367C_REG_PORT_TRUNK_FLOWCTRL 0x08d1 -+#define RTL8367C_EN_FLOWCTRL_TG2_OFFSET 2 -+#define RTL8367C_EN_FLOWCTRL_TG2_MASK 0x4 -+#define RTL8367C_EN_FLOWCTRL_TG1_OFFSET 1 -+#define RTL8367C_EN_FLOWCTRL_TG1_MASK 0x2 -+#define RTL8367C_EN_FLOWCTRL_TG0_OFFSET 0 -+#define RTL8367C_EN_FLOWCTRL_TG0_MASK 0x1 -+ -+#define RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL0 0x08d2 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH7_OFFSET 14 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH7_MASK 0xC000 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH6_OFFSET 12 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH6_MASK 0x3000 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH5_OFFSET 10 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH5_MASK 0xC00 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH4_OFFSET 8 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH4_MASK 0x300 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH3_OFFSET 6 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH3_MASK 0xC0 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH2_OFFSET 4 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH2_MASK 0x30 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH1_OFFSET 2 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH1_MASK 0xC -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH0_OFFSET 0 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH0_MASK 0x3 -+ -+#define RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL1 0x08d3 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH15_OFFSET 14 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH15_MASK 0xC000 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH14_OFFSET 12 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH14_MASK 0x3000 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH13_OFFSET 10 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH13_MASK 0xC00 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH12_OFFSET 8 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH12_MASK 0x300 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH11_OFFSET 6 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH11_MASK 0xC0 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH10_OFFSET 4 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH10_MASK 0x30 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH9_OFFSET 2 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH9_MASK 0xC -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH8_OFFSET 0 -+#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH8_MASK 0x3 -+ -+#define RTL8367C_REG_DOS_CFG 0x08d4 -+#define RTL8367C_DROP_ICMPFRAGMENT_OFFSET 9 -+#define RTL8367C_DROP_ICMPFRAGMENT_MASK 0x200 -+#define RTL8367C_DROP_TCPFRAGERROR_OFFSET 8 -+#define RTL8367C_DROP_TCPFRAGERROR_MASK 0x100 -+#define RTL8367C_DROP_TCPSHORTHDR_OFFSET 7 -+#define RTL8367C_DROP_TCPSHORTHDR_MASK 0x80 -+#define RTL8367C_DROP_SYN1024_OFFSET 6 -+#define RTL8367C_DROP_SYN1024_MASK 0x40 -+#define RTL8367C_DROP_NULLSCAN_OFFSET 5 -+#define RTL8367C_DROP_NULLSCAN_MASK 0x20 -+#define RTL8367C_DROP_XMASCAN_OFFSET 4 -+#define RTL8367C_DROP_XMASCAN_MASK 0x10 -+#define RTL8367C_DROP_SYNFINSCAN_OFFSET 3 -+#define RTL8367C_DROP_SYNFINSCAN_MASK 0x8 -+#define RTL8367C_DROP_BLATATTACKS_OFFSET 2 -+#define RTL8367C_DROP_BLATATTACKS_MASK 0x4 -+#define RTL8367C_DROP_LANDATTACKS_OFFSET 1 -+#define RTL8367C_DROP_LANDATTACKS_MASK 0x2 -+#define RTL8367C_DROP_DAEQSA_OFFSET 0 -+#define RTL8367C_DROP_DAEQSA_MASK 0x1 -+ -+#define RTL8367C_REG_UNKNOWN_L2_MULTICAST_CTRL1 0x08d5 -+#define RTL8367C_PORT10_UNKNOWN_L2_MCAST_OFFSET 4 -+#define RTL8367C_PORT10_UNKNOWN_L2_MCAST_MASK 0x30 -+#define RTL8367C_PORT9_UNKNOWN_L2_MCAST_OFFSET 2 -+#define RTL8367C_PORT9_UNKNOWN_L2_MCAST_MASK 0xC -+#define RTL8367C_PORT8_UNKNOWN_L2_MCAST_OFFSET 0 -+#define RTL8367C_PORT8_UNKNOWN_L2_MCAST_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4 0x08d6 -+#define RTL8367C_PORT9_VLAN_KEEP_MASK_OFFSET 8 -+#define RTL8367C_PORT9_VLAN_KEEP_MASK_MASK 0xFF00 -+#define RTL8367C_PORT8_VLAN_KEEP_MASK_OFFSET 0 -+#define RTL8367C_PORT8_VLAN_KEEP_MASK_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL5 0x08d7 -+#define RTL8367C_VLAN_EGRESS_KEEP_CTRL5_OFFSET 0 -+#define RTL8367C_VLAN_EGRESS_KEEP_CTRL5_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL0_EXT 0x08d8 -+#define RTL8367C_PORT1_VLAN_KEEP_MASK_EXT_OFFSET 3 -+#define RTL8367C_PORT1_VLAN_KEEP_MASK_EXT_MASK 0x38 -+#define RTL8367C_PORT0_VLAN_KEEP_MASK_EXT_OFFSET 0 -+#define RTL8367C_PORT0_VLAN_KEEP_MASK_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL1_EXT 0x08d9 -+#define RTL8367C_PORT3_VLAN_KEEP_MASK_EXT_OFFSET 3 -+#define RTL8367C_PORT3_VLAN_KEEP_MASK_EXT_MASK 0x38 -+#define RTL8367C_PORT2_VLAN_KEEP_MASK_EXT_OFFSET 0 -+#define RTL8367C_PORT2_VLAN_KEEP_MASK_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL2_EXT 0x08da -+#define RTL8367C_PORT5_VLAN_KEEP_MASK_EXT_OFFSET 3 -+#define RTL8367C_PORT5_VLAN_KEEP_MASK_EXT_MASK 0x38 -+#define RTL8367C_PORT4_VLAN_KEEP_MASK_EXT_OFFSET 0 -+#define RTL8367C_PORT4_VLAN_KEEP_MASK_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL3_EXT 0x08db -+#define RTL8367C_PORT7_VLAN_KEEP_MASK_EXT_OFFSET 3 -+#define RTL8367C_PORT7_VLAN_KEEP_MASK_EXT_MASK 0x38 -+#define RTL8367C_PORT6_VLAN_KEEP_MASK_EXT_OFFSET 0 -+#define RTL8367C_PORT6_VLAN_KEEP_MASK_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4_EXT 0x08dc -+#define RTL8367C_PORT9_VLAN_KEEP_MASK_EXT_OFFSET 3 -+#define RTL8367C_PORT9_VLAN_KEEP_MASK_EXT_MASK 0x38 -+#define RTL8367C_PORT8_VLAN_KEEP_MASK_EXT_OFFSET 0 -+#define RTL8367C_PORT8_VLAN_KEEP_MASK_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL5_EXT 0x08dd -+#define RTL8367C_VLAN_EGRESS_KEEP_CTRL5_EXT_OFFSET 0 -+#define RTL8367C_VLAN_EGRESS_KEEP_CTRL5_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL10 0x08de -+#define RTL8367C_VLAN_EGRESS_TRANS_CTRL10_OFFSET 0 -+#define RTL8367C_VLAN_EGRESS_TRANS_CTRL10_MASK 0x7FF -+ -+#define RTL8367C_REG_FPGA_VER_CEN 0x08e0 -+ -+#define RTL8367C_REG_FPGA_TIME_CEN 0x08e1 -+ -+#define RTL8367C_REG_FPGA_DATE_CEN 0x08e2 -+ -+#define RTL8367C_REG_QOS_PORT_QUEUE_NUMBER_CTRL0 0x0900 -+#define RTL8367C_PORT3_NUMBER_OFFSET 12 -+#define RTL8367C_PORT3_NUMBER_MASK 0x7000 -+#define RTL8367C_PORT2_NUMBER_OFFSET 8 -+#define RTL8367C_PORT2_NUMBER_MASK 0x700 -+#define RTL8367C_PORT1_NUMBER_OFFSET 4 -+#define RTL8367C_PORT1_NUMBER_MASK 0x70 -+#define RTL8367C_PORT0_NUMBER_OFFSET 0 -+#define RTL8367C_PORT0_NUMBER_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_PORT_QUEUE_NUMBER_CTRL1 0x0901 -+#define RTL8367C_PORT7_NUMBER_OFFSET 12 -+#define RTL8367C_PORT7_NUMBER_MASK 0x7000 -+#define RTL8367C_PORT6_NUMBER_OFFSET 8 -+#define RTL8367C_PORT6_NUMBER_MASK 0x700 -+#define RTL8367C_PORT5_NUMBER_OFFSET 4 -+#define RTL8367C_PORT5_NUMBER_MASK 0x70 -+#define RTL8367C_PORT4_NUMBER_OFFSET 0 -+#define RTL8367C_PORT4_NUMBER_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_PORT_QUEUE_NUMBER_CTRL2 0x0902 -+#define RTL8367C_PORT10_NUMBER_OFFSET 8 -+#define RTL8367C_PORT10_NUMBER_MASK 0x700 -+#define RTL8367C_PORT9_NUMBER_OFFSET 4 -+#define RTL8367C_PORT9_NUMBER_MASK 0x70 -+#define RTL8367C_PORT8_NUMBER_OFFSET 0 -+#define RTL8367C_PORT8_NUMBER_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_1Q_PRIORITY_TO_QID_CTRL0 0x0904 -+#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 -+#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 -+#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 -+#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 -+#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 -+#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 -+#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 -+#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_1Q_PRIORITY_TO_QID_CTRL1 0x0905 -+#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 -+#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 -+#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 -+#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 -+#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 -+#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 -+#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 -+#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_2Q_PRIORITY_TO_QID_CTRL0 0x0906 -+#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 -+#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 -+#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 -+#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 -+#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 -+#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 -+#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 -+#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_2Q_PRIORITY_TO_QID_CTRL1 0x0907 -+#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 -+#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 -+#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 -+#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 -+#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 -+#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 -+#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 -+#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_3Q_PRIORITY_TO_QID_CTRL0 0x0908 -+#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 -+#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 -+#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 -+#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 -+#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 -+#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 -+#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 -+#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_3Q_PRIORITY_TO_QID_CTRL1 0x0909 -+#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 -+#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 -+#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 -+#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 -+#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 -+#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 -+#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 -+#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_4Q_PRIORITY_TO_QID_CTRL0 0x090a -+#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 -+#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 -+#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 -+#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 -+#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 -+#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 -+#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 -+#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_4Q_PRIORITY_TO_QID_CTRL1 0x090b -+#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 -+#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 -+#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 -+#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 -+#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 -+#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 -+#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 -+#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_5Q_PRIORITY_TO_QID_CTRL0 0x090c -+#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 -+#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 -+#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 -+#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 -+#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 -+#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 -+#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 -+#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_5Q_PRIORITY_TO_QID_CTRL1 0x090d -+#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 -+#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 -+#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 -+#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 -+#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 -+#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 -+#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 -+#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_6Q_PRIORITY_TO_QID_CTRL0 0x090e -+#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 -+#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 -+#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 -+#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 -+#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 -+#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 -+#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 -+#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_6Q_PRIORITY_TO_QID_CTRL1 0x090f -+#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 -+#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 -+#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 -+#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 -+#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 -+#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 -+#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 -+#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_7Q_PRIORITY_TO_QID_CTRL0 0x0910 -+#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 -+#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 -+#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 -+#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 -+#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 -+#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 -+#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 -+#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_7Q_PRIORITY_TO_QID_CTRL1 0x0911 -+#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 -+#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 -+#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 -+#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 -+#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 -+#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 -+#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 -+#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_8Q_PRIORITY_TO_QID_CTRL0 0x0912 -+#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 -+#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 -+#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 -+#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 -+#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 -+#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 -+#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 -+#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_8Q_PRIORITY_TO_QID_CTRL1 0x0913 -+#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 -+#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 -+#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 -+#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 -+#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 -+#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 -+#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 -+#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 -+ -+#define RTL8367C_REG_HIGHPRI_INDICATOR 0x0915 -+#define RTL8367C_PORT10_INDICATOR_OFFSET 10 -+#define RTL8367C_PORT10_INDICATOR_MASK 0x400 -+#define RTL8367C_PORT9_INDICATOR_OFFSET 9 -+#define RTL8367C_PORT9_INDICATOR_MASK 0x200 -+#define RTL8367C_PORT8_INDICATOR_OFFSET 8 -+#define RTL8367C_PORT8_INDICATOR_MASK 0x100 -+#define RTL8367C_PORT7_INDICATOR_OFFSET 7 -+#define RTL8367C_PORT7_INDICATOR_MASK 0x80 -+#define RTL8367C_PORT6_INDICATOR_OFFSET 6 -+#define RTL8367C_PORT6_INDICATOR_MASK 0x40 -+#define RTL8367C_PORT5_INDICATOR_OFFSET 5 -+#define RTL8367C_PORT5_INDICATOR_MASK 0x20 -+#define RTL8367C_PORT4_INDICATOR_OFFSET 4 -+#define RTL8367C_PORT4_INDICATOR_MASK 0x10 -+#define RTL8367C_PORT3_INDICATOR_OFFSET 3 -+#define RTL8367C_PORT3_INDICATOR_MASK 0x8 -+#define RTL8367C_PORT2_INDICATOR_OFFSET 2 -+#define RTL8367C_PORT2_INDICATOR_MASK 0x4 -+#define RTL8367C_PORT1_INDICATOR_OFFSET 1 -+#define RTL8367C_PORT1_INDICATOR_MASK 0x2 -+#define RTL8367C_PORT0_INDICATOR_OFFSET 0 -+#define RTL8367C_PORT0_INDICATOR_MASK 0x1 -+ -+#define RTL8367C_REG_HIGHPRI_CFG 0x0916 -+#define RTL8367C_HIGHPRI_CFG_OFFSET 0 -+#define RTL8367C_HIGHPRI_CFG_MASK 0xFF -+ -+#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL0 0x0917 -+#define RTL8367C_PORT1_DEBUG_INFO_OFFSET 8 -+#define RTL8367C_PORT1_DEBUG_INFO_MASK 0xFF00 -+#define RTL8367C_PORT0_DEBUG_INFO_OFFSET 0 -+#define RTL8367C_PORT0_DEBUG_INFO_MASK 0xFF -+ -+#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL1 0x0918 -+#define RTL8367C_PORT3_DEBUG_INFO_OFFSET 8 -+#define RTL8367C_PORT3_DEBUG_INFO_MASK 0xFF00 -+#define RTL8367C_PORT2_DEBUG_INFO_OFFSET 0 -+#define RTL8367C_PORT2_DEBUG_INFO_MASK 0xFF -+ -+#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL2 0x0919 -+#define RTL8367C_PORT5_DEBUG_INFO_OFFSET 8 -+#define RTL8367C_PORT5_DEBUG_INFO_MASK 0xFF00 -+#define RTL8367C_PORT4_DEBUG_INFO_OFFSET 0 -+#define RTL8367C_PORT4_DEBUG_INFO_MASK 0xFF -+ -+#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL3 0x091a -+#define RTL8367C_PORT7_DEBUG_INFO_OFFSET 8 -+#define RTL8367C_PORT7_DEBUG_INFO_MASK 0xFF00 -+#define RTL8367C_PORT6_DEBUG_INFO_OFFSET 0 -+#define RTL8367C_PORT6_DEBUG_INFO_MASK 0xFF -+ -+#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL4 0x091b -+#define RTL8367C_PORT9_DEBUG_INFO_OFFSET 8 -+#define RTL8367C_PORT9_DEBUG_INFO_MASK 0xFF00 -+#define RTL8367C_PORT8_DEBUG_INFO_OFFSET 0 -+#define RTL8367C_PORT8_DEBUG_INFO_MASK 0xFF -+ -+#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL5 0x091c -+#define RTL8367C_PORT10_DEBUG_INFO_OFFSET 0 -+#define RTL8367C_PORT10_DEBUG_INFO_MASK 0xFF -+ -+#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL6 0x091d -+#define RTL8367C_PORT7_DEBUG_INDICATOR_OFFSET 14 -+#define RTL8367C_PORT7_DEBUG_INDICATOR_MASK 0xC000 -+#define RTL8367C_PORT6_DEBUG_INDICATOR_OFFSET 12 -+#define RTL8367C_PORT6_DEBUG_INDICATOR_MASK 0x3000 -+#define RTL8367C_PORT5_DEBUG_INDICATOR_OFFSET 10 -+#define RTL8367C_PORT5_DEBUG_INDICATOR_MASK 0xC00 -+#define RTL8367C_PORT4_DEBUG_INDICATOR_OFFSET 8 -+#define RTL8367C_PORT4_DEBUG_INDICATOR_MASK 0x300 -+#define RTL8367C_PORT3_DEBUG_INDICATOR_OFFSET 6 -+#define RTL8367C_PORT3_DEBUG_INDICATOR_MASK 0xC0 -+#define RTL8367C_PORT2_DEBUG_INDICATOR_OFFSET 4 -+#define RTL8367C_PORT2_DEBUG_INDICATOR_MASK 0x30 -+#define RTL8367C_PORT1_DEBUG_INDICATOR_OFFSET 2 -+#define RTL8367C_PORT1_DEBUG_INDICATOR_MASK 0xC -+#define RTL8367C_PORT0_DEBUG_INDICATOR_OFFSET 0 -+#define RTL8367C_PORT0_DEBUG_INDICATOR_MASK 0x3 -+ -+#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL7 0x091e -+#define RTL8367C_PORT10_DEBUG_INDICATOR_OFFSET 4 -+#define RTL8367C_PORT10_DEBUG_INDICATOR_MASK 0x30 -+#define RTL8367C_PORT9_DEBUG_INDICATOR_OFFSET 2 -+#define RTL8367C_PORT9_DEBUG_INDICATOR_MASK 0xC -+#define RTL8367C_PORT8_DEBUG_INDICATOR_OFFSET 0 -+#define RTL8367C_PORT8_DEBUG_INDICATOR_MASK 0x3 -+ -+#define RTL8367C_REG_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL0 0x0930 -+#define RTL8367C_PORT1_QUEUE_MASK_OFFSET 8 -+#define RTL8367C_PORT1_QUEUE_MASK_MASK 0xFF00 -+#define RTL8367C_PORT0_QUEUE_MASK_OFFSET 0 -+#define RTL8367C_PORT0_QUEUE_MASK_MASK 0xFF -+ -+#define RTL8367C_REG_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL1 0x0931 -+#define RTL8367C_PORT3_QUEUE_MASK_OFFSET 8 -+#define RTL8367C_PORT3_QUEUE_MASK_MASK 0xFF00 -+#define RTL8367C_PORT2_QUEUE_MASK_OFFSET 0 -+#define RTL8367C_PORT2_QUEUE_MASK_MASK 0xFF -+ -+#define RTL8367C_REG_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL2 0x0932 -+#define RTL8367C_PORT5_QUEUE_MASK_OFFSET 8 -+#define RTL8367C_PORT5_QUEUE_MASK_MASK 0xFF00 -+#define RTL8367C_PORT4_QUEUE_MASK_OFFSET 0 -+#define RTL8367C_PORT4_QUEUE_MASK_MASK 0xFF -+ -+#define RTL8367C_REG_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL3 0x0933 -+#define RTL8367C_PORT7_QUEUE_MASK_OFFSET 8 -+#define RTL8367C_PORT7_QUEUE_MASK_MASK 0xFF00 -+#define RTL8367C_PORT6_QUEUE_MASK_OFFSET 0 -+#define RTL8367C_PORT6_QUEUE_MASK_MASK 0xFF -+ -+#define RTL8367C_REG_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL4 0x0934 -+#define RTL8367C_PORT9_QUEUE_MASK_OFFSET 8 -+#define RTL8367C_PORT9_QUEUE_MASK_MASK 0xFF00 -+#define RTL8367C_PORT8_QUEUE_MASK_OFFSET 0 -+#define RTL8367C_PORT8_QUEUE_MASK_MASK 0xFF -+ -+#define RTL8367C_REG_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL5 0x0935 -+#define RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL5_OFFSET 0 -+#define RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL5_MASK 0xFF -+ -+#define RTL8367C_REG_FLOWCRTL_EGRESS_PORT_ENABLE 0x0938 -+#define RTL8367C_FLOWCRTL_EGRESS_PORT_ENABLE_OFFSET 0 -+#define RTL8367C_FLOWCRTL_EGRESS_PORT_ENABLE_MASK 0xFF -+ -+#define RTL8367C_REG_EAV_CTRL 0x0939 -+#define RTL8367C_EAV_TRAP_CPU_OFFSET 1 -+#define RTL8367C_EAV_TRAP_CPU_MASK 0x2 -+#define RTL8367C_EAV_TRAP_8051_OFFSET 0 -+#define RTL8367C_EAV_TRAP_8051_MASK 0x1 -+ -+#define RTL8367C_REG_UNTAG_DSCP_PRI_CFG 0x093a -+#define RTL8367C_UNTAG_DSCP_PRI_CFG_OFFSET 0 -+#define RTL8367C_UNTAG_DSCP_PRI_CFG_MASK 0x1 -+ -+#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL0 0x093b -+#define RTL8367C_PORT1_VLAN_KEEP_MASK_OFFSET 8 -+#define RTL8367C_PORT1_VLAN_KEEP_MASK_MASK 0xFF00 -+#define RTL8367C_PORT0_VLAN_KEEP_MASK_OFFSET 0 -+#define RTL8367C_PORT0_VLAN_KEEP_MASK_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL1 0x093c -+#define RTL8367C_PORT3_VLAN_KEEP_MASK_OFFSET 8 -+#define RTL8367C_PORT3_VLAN_KEEP_MASK_MASK 0xFF00 -+#define RTL8367C_PORT2_VLAN_KEEP_MASK_OFFSET 0 -+#define RTL8367C_PORT2_VLAN_KEEP_MASK_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL2 0x093d -+#define RTL8367C_PORT5_VLAN_KEEP_MASK_OFFSET 8 -+#define RTL8367C_PORT5_VLAN_KEEP_MASK_MASK 0xFF00 -+#define RTL8367C_PORT4_VLAN_KEEP_MASK_OFFSET 0 -+#define RTL8367C_PORT4_VLAN_KEEP_MASK_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL3 0x093e -+#define RTL8367C_PORT7_VLAN_KEEP_MASK_OFFSET 8 -+#define RTL8367C_PORT7_VLAN_KEEP_MASK_MASK 0xFF00 -+#define RTL8367C_PORT6_VLAN_KEEP_MASK_OFFSET 0 -+#define RTL8367C_PORT6_VLAN_KEEP_MASK_MASK 0xFF -+ -+#define RTL8367C_REG_VLAN_TRANSPARENT_EN_CFG 0x093f -+#define RTL8367C_VLAN_TRANSPARENT_EN_CFG_OFFSET 0 -+#define RTL8367C_VLAN_TRANSPARENT_EN_CFG_MASK 0x1 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY0_H 0x0940 -+#define RTL8367C_IPMC_GROUP_ENTRY0_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY0_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY0_L 0x0941 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY1_H 0x0942 -+#define RTL8367C_IPMC_GROUP_ENTRY1_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY1_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY1_L 0x0943 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY2_H 0x0944 -+#define RTL8367C_IPMC_GROUP_ENTRY2_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY2_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY2_L 0x0945 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY3_H 0x0946 -+#define RTL8367C_IPMC_GROUP_ENTRY3_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY3_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY3_L 0x0947 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY4_H 0x0948 -+#define RTL8367C_IPMC_GROUP_ENTRY4_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY4_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY4_L 0x0949 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY5_H 0x094a -+#define RTL8367C_IPMC_GROUP_ENTRY5_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY5_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY5_L 0x094b -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY6_H 0x094c -+#define RTL8367C_IPMC_GROUP_ENTRY6_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY6_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY6_L 0x094d -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY7_H 0x094e -+#define RTL8367C_IPMC_GROUP_ENTRY7_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY7_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY7_L 0x094f -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY8_H 0x0950 -+#define RTL8367C_IPMC_GROUP_ENTRY8_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY8_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY8_L 0x0951 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY9_H 0x0952 -+#define RTL8367C_IPMC_GROUP_ENTRY9_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY9_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY9_L 0x0953 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY10_H 0x0954 -+#define RTL8367C_IPMC_GROUP_ENTRY10_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY10_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY10_L 0x0955 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY11_H 0x0956 -+#define RTL8367C_IPMC_GROUP_ENTRY11_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY11_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY11_L 0x0957 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY12_H 0x0958 -+#define RTL8367C_IPMC_GROUP_ENTRY12_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY12_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY12_L 0x0959 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY13_H 0x095a -+#define RTL8367C_IPMC_GROUP_ENTRY13_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY13_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY13_L 0x095b -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY14_H 0x095c -+#define RTL8367C_IPMC_GROUP_ENTRY14_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY14_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY14_L 0x095d -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY15_H 0x095e -+#define RTL8367C_IPMC_GROUP_ENTRY15_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY15_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY15_L 0x095f -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY16_H 0x0960 -+#define RTL8367C_IPMC_GROUP_ENTRY16_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY16_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY16_L 0x0961 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY17_H 0x0962 -+#define RTL8367C_IPMC_GROUP_ENTRY17_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY17_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY17_L 0x0963 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY18_H 0x0964 -+#define RTL8367C_IPMC_GROUP_ENTRY18_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY18_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY18_L 0x0965 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY19_H 0x0966 -+#define RTL8367C_IPMC_GROUP_ENTRY19_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY19_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY19_L 0x0967 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY20_H 0x0968 -+#define RTL8367C_IPMC_GROUP_ENTRY20_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY20_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY20_L 0x0969 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY21_H 0x096a -+#define RTL8367C_IPMC_GROUP_ENTRY21_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY21_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY21_L 0x096b -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY22_H 0x096c -+#define RTL8367C_IPMC_GROUP_ENTRY22_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY22_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY22_L 0x096d -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY23_H 0x096e -+#define RTL8367C_IPMC_GROUP_ENTRY23_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY23_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY23_L 0x096f -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY24_H 0x0970 -+#define RTL8367C_IPMC_GROUP_ENTRY24_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY24_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY24_L 0x0971 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY25_H 0x0972 -+#define RTL8367C_IPMC_GROUP_ENTRY25_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY25_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY25_L 0x0973 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY26_H 0x0974 -+#define RTL8367C_IPMC_GROUP_ENTRY26_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY26_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY26_L 0x0975 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY27_H 0x0976 -+#define RTL8367C_IPMC_GROUP_ENTRY27_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY27_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY27_L 0x0977 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY28_H 0x0978 -+#define RTL8367C_IPMC_GROUP_ENTRY28_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY28_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY28_L 0x0979 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY29_H 0x097a -+#define RTL8367C_IPMC_GROUP_ENTRY29_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY29_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY29_L 0x097b -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY30_H 0x097c -+#define RTL8367C_IPMC_GROUP_ENTRY30_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY30_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY30_L 0x097d -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY31_H 0x097e -+#define RTL8367C_IPMC_GROUP_ENTRY31_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY31_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY31_L 0x097f -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY32_H 0x0980 -+#define RTL8367C_IPMC_GROUP_ENTRY32_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY32_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY32_L 0x0981 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY33_H 0x0982 -+#define RTL8367C_IPMC_GROUP_ENTRY33_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY33_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY33_L 0x0983 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY34_H 0x0984 -+#define RTL8367C_IPMC_GROUP_ENTRY34_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY34_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY34_L 0x0985 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY35_H 0x0986 -+#define RTL8367C_IPMC_GROUP_ENTRY35_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY35_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY35_L 0x0987 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY36_H 0x0988 -+#define RTL8367C_IPMC_GROUP_ENTRY36_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY36_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY36_L 0x0989 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY37_H 0x098a -+#define RTL8367C_IPMC_GROUP_ENTRY37_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY37_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY37_L 0x098b -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY38_H 0x098c -+#define RTL8367C_IPMC_GROUP_ENTRY38_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY38_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY38_L 0x098d -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY39_H 0x098e -+#define RTL8367C_IPMC_GROUP_ENTRY39_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY39_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY39_L 0x098f -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY40_H 0x0990 -+#define RTL8367C_IPMC_GROUP_ENTRY40_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY40_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY40_L 0x0991 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY41_H 0x0992 -+#define RTL8367C_IPMC_GROUP_ENTRY41_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY41_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY41_L 0x0993 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY42_H 0x0994 -+#define RTL8367C_IPMC_GROUP_ENTRY42_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY42_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY42_L 0x0995 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY43_H 0x0996 -+#define RTL8367C_IPMC_GROUP_ENTRY43_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY43_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY43_L 0x0997 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY44_H 0x0998 -+#define RTL8367C_IPMC_GROUP_ENTRY44_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY44_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY44_L 0x0999 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY45_H 0x099a -+#define RTL8367C_IPMC_GROUP_ENTRY45_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY45_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY45_L 0x099b -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY46_H 0x099c -+#define RTL8367C_IPMC_GROUP_ENTRY46_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY46_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY46_L 0x099d -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY47_H 0x099e -+#define RTL8367C_IPMC_GROUP_ENTRY47_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY47_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY47_L 0x099f -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY48_H 0x09a0 -+#define RTL8367C_IPMC_GROUP_ENTRY48_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY48_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY48_L 0x09a1 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY49_H 0x09a2 -+#define RTL8367C_IPMC_GROUP_ENTRY49_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY49_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY49_L 0x09a3 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY50_H 0x09a4 -+#define RTL8367C_IPMC_GROUP_ENTRY50_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY50_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY50_L 0x09a5 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY51_H 0x09a6 -+#define RTL8367C_IPMC_GROUP_ENTRY51_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY51_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY51_L 0x09a7 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY52_H 0x09a8 -+#define RTL8367C_IPMC_GROUP_ENTRY52_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY52_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY52_L 0x09a9 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY53_H 0x09aa -+#define RTL8367C_IPMC_GROUP_ENTRY53_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY53_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY53_L 0x09ab -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY54_H 0x09ac -+#define RTL8367C_IPMC_GROUP_ENTRY54_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY54_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY54_L 0x09ad -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY55_H 0x09ae -+#define RTL8367C_IPMC_GROUP_ENTRY55_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY55_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY55_L 0x09af -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY56_H 0x09b0 -+#define RTL8367C_IPMC_GROUP_ENTRY56_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY56_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY56_L 0x09b1 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY57_H 0x09b2 -+#define RTL8367C_IPMC_GROUP_ENTRY57_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY57_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY57_L 0x09b3 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY58_H 0x09b4 -+#define RTL8367C_IPMC_GROUP_ENTRY58_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY58_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY58_L 0x09b5 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY59_H 0x09b6 -+#define RTL8367C_IPMC_GROUP_ENTRY59_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY59_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY59_L 0x09b7 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY60_H 0x09b8 -+#define RTL8367C_IPMC_GROUP_ENTRY60_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY60_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY60_L 0x09b9 -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY61_H 0x09ba -+#define RTL8367C_IPMC_GROUP_ENTRY61_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY61_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY61_L 0x09bb -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY62_H 0x09bc -+#define RTL8367C_IPMC_GROUP_ENTRY62_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY62_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY62_L 0x09bd -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY63_H 0x09be -+#define RTL8367C_IPMC_GROUP_ENTRY63_H_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_ENTRY63_H_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_ENTRY63_L 0x09bf -+ -+#define RTL8367C_REG_UNKNOWN_UNICAST_DA_PORT_BEHAVE 0x09C0 -+#define RTL8367C_Port7_ACTION_OFFSET 14 -+#define RTL8367C_Port7_ACTION_MASK 0xC000 -+#define RTL8367C_Port6_ACTION_OFFSET 12 -+#define RTL8367C_Port6_ACTION_MASK 0x3000 -+#define RTL8367C_Port5_ACTION_OFFSET 10 -+#define RTL8367C_Port5_ACTION_MASK 0xC00 -+#define RTL8367C_Port4_ACTION_OFFSET 8 -+#define RTL8367C_Port4_ACTION_MASK 0x300 -+#define RTL8367C_Port3_ACTION_OFFSET 6 -+#define RTL8367C_Port3_ACTION_MASK 0xC0 -+#define RTL8367C_Port2_ACTION_OFFSET 4 -+#define RTL8367C_Port2_ACTION_MASK 0x30 -+#define RTL8367C_Port1_ACTION_OFFSET 2 -+#define RTL8367C_Port1_ACTION_MASK 0xC -+#define RTL8367C_Port0_ACTION_OFFSET 0 -+#define RTL8367C_Port0_ACTION_MASK 0x3 -+ -+#define RTL8367C_REG_MIRROR_CTRL3 0x09C1 -+#define RTL8367C_MIRROR_ACL_OVERRIDE_EN_OFFSET 2 -+#define RTL8367C_MIRROR_ACL_OVERRIDE_EN_MASK 0x4 -+#define RTL8367C_MIRROR_TX_OVERRIDE_EN_OFFSET 1 -+#define RTL8367C_MIRROR_TX_OVERRIDE_EN_MASK 0x2 -+#define RTL8367C_MIRROR_RX_OVERRIDE_EN_OFFSET 0 -+#define RTL8367C_MIRROR_RX_OVERRIDE_EN_MASK 0x1 -+ -+#define RTL8367C_REG_DPM_DUMMY02 0x09C2 -+ -+#define RTL8367C_REG_DPM_DUMMY03 0x09C3 -+ -+#define RTL8367C_REG_DPM_DUMMY04 0x09C4 -+ -+#define RTL8367C_REG_DPM_DUMMY05 0x09C5 -+ -+#define RTL8367C_REG_DPM_DUMMY06 0x09C6 -+ -+#define RTL8367C_REG_DPM_DUMMY07 0x09C7 -+ -+#define RTL8367C_REG_DPM_DUMMY08 0x09C8 -+ -+#define RTL8367C_REG_DPM_DUMMY09 0x09C9 -+ -+#define RTL8367C_REG_DPM_DUMMY10 0x09CA -+ -+#define RTL8367C_REG_DPM_DUMMY11 0x09CB -+ -+#define RTL8367C_REG_DPM_DUMMY12 0x09CC -+ -+#define RTL8367C_REG_DPM_DUMMY13 0x09CD -+ -+#define RTL8367C_REG_DPM_DUMMY14 0x09CE -+ -+#define RTL8367C_REG_DPM_DUMMY15 0x09CF -+ -+#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL0 0x09D0 -+#define RTL8367C_VLAN_EGRESS_TRANS_CTRL0_OFFSET 0 -+#define RTL8367C_VLAN_EGRESS_TRANS_CTRL0_MASK 0x7FF -+ -+#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL1 0x09D1 -+#define RTL8367C_VLAN_EGRESS_TRANS_CTRL1_OFFSET 0 -+#define RTL8367C_VLAN_EGRESS_TRANS_CTRL1_MASK 0x7FF -+ -+#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL2 0x09D2 -+#define RTL8367C_VLAN_EGRESS_TRANS_CTRL2_OFFSET 0 -+#define RTL8367C_VLAN_EGRESS_TRANS_CTRL2_MASK 0x7FF -+ -+#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL3 0x09D3 -+#define RTL8367C_VLAN_EGRESS_TRANS_CTRL3_OFFSET 0 -+#define RTL8367C_VLAN_EGRESS_TRANS_CTRL3_MASK 0x7FF -+ -+#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL4 0x09D4 -+#define RTL8367C_VLAN_EGRESS_TRANS_CTRL4_OFFSET 0 -+#define RTL8367C_VLAN_EGRESS_TRANS_CTRL4_MASK 0x7FF -+ -+#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL5 0x09D5 -+#define RTL8367C_VLAN_EGRESS_TRANS_CTRL5_OFFSET 0 -+#define RTL8367C_VLAN_EGRESS_TRANS_CTRL5_MASK 0x7FF -+ -+#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL6 0x09D6 -+#define RTL8367C_VLAN_EGRESS_TRANS_CTRL6_OFFSET 0 -+#define RTL8367C_VLAN_EGRESS_TRANS_CTRL6_MASK 0x7FF -+ -+#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL7 0x09D7 -+#define RTL8367C_VLAN_EGRESS_TRANS_CTRL7_OFFSET 0 -+#define RTL8367C_VLAN_EGRESS_TRANS_CTRL7_MASK 0x7FF -+ -+#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL8 0x09D8 -+#define RTL8367C_VLAN_EGRESS_TRANS_CTRL8_OFFSET 0 -+#define RTL8367C_VLAN_EGRESS_TRANS_CTRL8_MASK 0x7FF -+ -+#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL9 0x09D9 -+#define RTL8367C_VLAN_EGRESS_TRANS_CTRL9_OFFSET 0 -+#define RTL8367C_VLAN_EGRESS_TRANS_CTRL9_MASK 0x7FF -+ -+#define RTL8367C_REG_MIRROR_CTRL2 0x09DA -+#define RTL8367C_MIRROR_REALKEEP_EN_OFFSET 4 -+#define RTL8367C_MIRROR_REALKEEP_EN_MASK 0x10 -+#define RTL8367C_MIRROR_RX_ISOLATION_LEAKY_OFFSET 3 -+#define RTL8367C_MIRROR_RX_ISOLATION_LEAKY_MASK 0x8 -+#define RTL8367C_MIRROR_TX_ISOLATION_LEAKY_OFFSET 2 -+#define RTL8367C_MIRROR_TX_ISOLATION_LEAKY_MASK 0x4 -+#define RTL8367C_MIRROR_RX_VLAN_LEAKY_OFFSET 1 -+#define RTL8367C_MIRROR_RX_VLAN_LEAKY_MASK 0x2 -+#define RTL8367C_MIRROR_TX_VLAN_LEAKY_OFFSET 0 -+#define RTL8367C_MIRROR_TX_VLAN_LEAKY_MASK 0x1 -+ -+#define RTL8367C_REG_OUTPUT_DROP_CFG 0x09DB -+#define RTL8367C_ENABLE_PMASK_EXT_OFFSET 13 -+#define RTL8367C_ENABLE_PMASK_EXT_MASK 0xE000 -+#define RTL8367C_ENABLE_BC_OFFSET 12 -+#define RTL8367C_ENABLE_BC_MASK 0x1000 -+#define RTL8367C_ENABLE_MC_OFFSET 11 -+#define RTL8367C_ENABLE_MC_MASK 0x800 -+#define RTL8367C_ENABLE_UC_OFFSET 10 -+#define RTL8367C_ENABLE_UC_MASK 0x400 -+#define RTL8367C_ENABLE_PMASK_OFFSET 0 -+#define RTL8367C_ENABLE_PMASK_MASK 0xFF -+ -+#define RTL8367C_REG_UNKNOWN_UNICAST_DA_PORT_BEHAVE_EXT 0x09DC -+#define RTL8367C_PORT10_ACTION_OFFSET 4 -+#define RTL8367C_PORT10_ACTION_MASK 0x30 -+#define RTL8367C_PORT9_ACTION_OFFSET 2 -+#define RTL8367C_PORT9_ACTION_MASK 0xC -+#define RTL8367C_PORT8_ACTION_OFFSET 0 -+#define RTL8367C_PORT8_ACTION_MASK 0x3 -+ -+#define RTL8367C_REG_RMK_CFG_SEL_CTRL 0x09DF -+#define RTL8367C_RMK_1Q_CFG_SEL_OFFSET 2 -+#define RTL8367C_RMK_1Q_CFG_SEL_MASK 0x4 -+#define RTL8367C_RMK_DSCP_CFG_SEL_OFFSET 0 -+#define RTL8367C_RMK_DSCP_CFG_SEL_MASK 0x3 -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL0 0x09E0 -+#define RTL8367C_DSCP1_DSCP_OFFSET 8 -+#define RTL8367C_DSCP1_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP0_DSCP_OFFSET 0 -+#define RTL8367C_DSCP0_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL1 0x09E1 -+#define RTL8367C_DSCP3_DSCP_OFFSET 8 -+#define RTL8367C_DSCP3_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP2_DSCP_OFFSET 0 -+#define RTL8367C_DSCP2_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL2 0x09E2 -+#define RTL8367C_DSCP5_DSCP_OFFSET 8 -+#define RTL8367C_DSCP5_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP4_DSCP_OFFSET 0 -+#define RTL8367C_DSCP4_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL3 0x09E3 -+#define RTL8367C_DSCP7_DSCP_OFFSET 8 -+#define RTL8367C_DSCP7_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP6_DSCP_OFFSET 0 -+#define RTL8367C_DSCP6_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL4 0x09E4 -+#define RTL8367C_DSCP9_DSCP_OFFSET 8 -+#define RTL8367C_DSCP9_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP8_DSCP_OFFSET 0 -+#define RTL8367C_DSCP8_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL5 0x09E5 -+#define RTL8367C_DSCP11_DSCP_OFFSET 8 -+#define RTL8367C_DSCP11_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP10_DSCP_OFFSET 0 -+#define RTL8367C_DSCP10_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL6 0x09E6 -+#define RTL8367C_DSCP13_DSCP_OFFSET 8 -+#define RTL8367C_DSCP13_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP12_DSCP_OFFSET 0 -+#define RTL8367C_DSCP12_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL7 0x09E7 -+#define RTL8367C_DSCP15_DSCP_OFFSET 8 -+#define RTL8367C_DSCP15_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP14_DSCP_OFFSET 0 -+#define RTL8367C_DSCP14_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL8 0x09E8 -+#define RTL8367C_DSCP17_DSCP_OFFSET 8 -+#define RTL8367C_DSCP17_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP16_DSCP_OFFSET 0 -+#define RTL8367C_DSCP16_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL9 0x09E9 -+#define RTL8367C_DSCP19_DSCP_OFFSET 8 -+#define RTL8367C_DSCP19_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP18_DSCP_OFFSET 0 -+#define RTL8367C_DSCP18_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL10 0x09EA -+#define RTL8367C_DSCP21_DSCP_OFFSET 8 -+#define RTL8367C_DSCP21_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP20_DSCP_OFFSET 0 -+#define RTL8367C_DSCP20_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL11 0x09EB -+#define RTL8367C_DSCP23_DSCP_OFFSET 8 -+#define RTL8367C_DSCP23_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP22_DSCP_OFFSET 0 -+#define RTL8367C_DSCP22_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL12 0x09EC -+#define RTL8367C_DSCP25_DSCP_OFFSET 8 -+#define RTL8367C_DSCP25_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP24_DSCP_OFFSET 0 -+#define RTL8367C_DSCP24_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL13 0x09ED -+#define RTL8367C_DSCP27_DSCP_OFFSET 8 -+#define RTL8367C_DSCP27_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP26_DSCP_OFFSET 0 -+#define RTL8367C_DSCP26_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL14 0x09EE -+#define RTL8367C_DSCP29_DSCP_OFFSET 8 -+#define RTL8367C_DSCP29_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP28_DSCP_OFFSET 0 -+#define RTL8367C_DSCP28_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL15 0x09EF -+#define RTL8367C_DSCP31_DSCP_OFFSET 8 -+#define RTL8367C_DSCP31_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP30_DSCP_OFFSET 0 -+#define RTL8367C_DSCP30_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL16 0x09F0 -+#define RTL8367C_DSCP33_DSCP_OFFSET 8 -+#define RTL8367C_DSCP33_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP32_DSCP_OFFSET 0 -+#define RTL8367C_DSCP32_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL17 0x09F1 -+#define RTL8367C_DSCP35_DSCP_OFFSET 8 -+#define RTL8367C_DSCP35_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP34_DSCP_OFFSET 0 -+#define RTL8367C_DSCP34_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL18 0x09F2 -+#define RTL8367C_DSCP37_DSCP_OFFSET 8 -+#define RTL8367C_DSCP37_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP36_DSCP_OFFSET 0 -+#define RTL8367C_DSCP36_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL19 0x09F3 -+#define RTL8367C_DSCP39_DSCP_OFFSET 8 -+#define RTL8367C_DSCP39_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP38_DSCP_OFFSET 0 -+#define RTL8367C_DSCP38_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL20 0x09F4 -+#define RTL8367C_DSCP41_DSCP_OFFSET 8 -+#define RTL8367C_DSCP41_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP40_DSCP_OFFSET 0 -+#define RTL8367C_DSCP40_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL21 0x09F5 -+#define RTL8367C_DSCP43_DSCP_OFFSET 8 -+#define RTL8367C_DSCP43_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP42_DSCP_OFFSET 0 -+#define RTL8367C_DSCP42_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL22 0x09F6 -+#define RTL8367C_DSCP45_DSCP_OFFSET 8 -+#define RTL8367C_DSCP45_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP44_DSCP_OFFSET 0 -+#define RTL8367C_DSCP44_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL23 0x09F7 -+#define RTL8367C_DSCP47_DSCP_OFFSET 8 -+#define RTL8367C_DSCP47_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP46_DSCP_OFFSET 0 -+#define RTL8367C_DSCP46_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL24 0x09F8 -+#define RTL8367C_DSCP49_DSCP_OFFSET 8 -+#define RTL8367C_DSCP49_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP48_DSCP_OFFSET 0 -+#define RTL8367C_DSCP48_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL25 0x09F9 -+#define RTL8367C_DSCP51_DSCP_OFFSET 8 -+#define RTL8367C_DSCP51_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP50_DSCP_OFFSET 0 -+#define RTL8367C_DSCP50_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL26 0x09FA -+#define RTL8367C_DSCP53_DSCP_OFFSET 8 -+#define RTL8367C_DSCP53_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP52_DSCP_OFFSET 0 -+#define RTL8367C_DSCP52_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL27 0x09FB -+#define RTL8367C_DSCP55_DSCP_OFFSET 8 -+#define RTL8367C_DSCP55_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP54_DSCP_OFFSET 0 -+#define RTL8367C_DSCP54_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL28 0x09FC -+#define RTL8367C_DSCP57_DSCP_OFFSET 8 -+#define RTL8367C_DSCP57_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP56_DSCP_OFFSET 0 -+#define RTL8367C_DSCP56_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL29 0x09FD -+#define RTL8367C_DSCP59_DSCP_OFFSET 8 -+#define RTL8367C_DSCP59_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP58_DSCP_OFFSET 0 -+#define RTL8367C_DSCP58_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL30 0x09FE -+#define RTL8367C_DSCP61_DSCP_OFFSET 8 -+#define RTL8367C_DSCP61_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP60_DSCP_OFFSET 0 -+#define RTL8367C_DSCP60_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL31 0x09FF -+#define RTL8367C_DSCP63_DSCP_OFFSET 8 -+#define RTL8367C_DSCP63_DSCP_MASK 0x3F00 -+#define RTL8367C_DSCP62_DSCP_OFFSET 0 -+#define RTL8367C_DSCP62_DSCP_MASK 0x3F -+ -+/* (16'h0a00)l2_reg */ -+ -+#define RTL8367C_REG_VLAN_MSTI0_CTRL0 0x0a00 -+#define RTL8367C_VLAN_MSTI0_CTRL0_PORT7_STATE_OFFSET 14 -+#define RTL8367C_VLAN_MSTI0_CTRL0_PORT7_STATE_MASK 0xC000 -+#define RTL8367C_VLAN_MSTI0_CTRL0_PORT6_STATE_OFFSET 12 -+#define RTL8367C_VLAN_MSTI0_CTRL0_PORT6_STATE_MASK 0x3000 -+#define RTL8367C_VLAN_MSTI0_CTRL0_PORT5_STATE_OFFSET 10 -+#define RTL8367C_VLAN_MSTI0_CTRL0_PORT5_STATE_MASK 0xC00 -+#define RTL8367C_VLAN_MSTI0_CTRL0_PORT4_STATE_OFFSET 8 -+#define RTL8367C_VLAN_MSTI0_CTRL0_PORT4_STATE_MASK 0x300 -+#define RTL8367C_VLAN_MSTI0_CTRL0_PORT3_STATE_OFFSET 6 -+#define RTL8367C_VLAN_MSTI0_CTRL0_PORT3_STATE_MASK 0xC0 -+#define RTL8367C_VLAN_MSTI0_CTRL0_PORT2_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI0_CTRL0_PORT2_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI0_CTRL0_PORT1_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI0_CTRL0_PORT1_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI0_CTRL0_PORT0_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI0_CTRL0_PORT0_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI0_CTRL1 0x0a01 -+#define RTL8367C_VLAN_MSTI0_CTRL1_PORT10_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI0_CTRL1_PORT10_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI0_CTRL1_PORT9_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI0_CTRL1_PORT9_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI0_CTRL1_PORT8_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI0_CTRL1_PORT8_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI1_CTRL0 0x0a02 -+#define RTL8367C_VLAN_MSTI1_CTRL0_PORT7_STATE_OFFSET 14 -+#define RTL8367C_VLAN_MSTI1_CTRL0_PORT7_STATE_MASK 0xC000 -+#define RTL8367C_VLAN_MSTI1_CTRL0_PORT6_STATE_OFFSET 12 -+#define RTL8367C_VLAN_MSTI1_CTRL0_PORT6_STATE_MASK 0x3000 -+#define RTL8367C_VLAN_MSTI1_CTRL0_PORT5_STATE_OFFSET 10 -+#define RTL8367C_VLAN_MSTI1_CTRL0_PORT5_STATE_MASK 0xC00 -+#define RTL8367C_VLAN_MSTI1_CTRL0_PORT4_STATE_OFFSET 8 -+#define RTL8367C_VLAN_MSTI1_CTRL0_PORT4_STATE_MASK 0x300 -+#define RTL8367C_VLAN_MSTI1_CTRL0_PORT3_STATE_OFFSET 6 -+#define RTL8367C_VLAN_MSTI1_CTRL0_PORT3_STATE_MASK 0xC0 -+#define RTL8367C_VLAN_MSTI1_CTRL0_PORT2_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI1_CTRL0_PORT2_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI1_CTRL0_PORT1_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI1_CTRL0_PORT1_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI1_CTRL0_PORT0_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI1_CTRL0_PORT0_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI1_CTRL1 0x0a03 -+#define RTL8367C_VLAN_MSTI1_CTRL1_PORT10_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI1_CTRL1_PORT10_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI1_CTRL1_PORT9_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI1_CTRL1_PORT9_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI1_CTRL1_PORT8_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI1_CTRL1_PORT8_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI2_CTRL0 0x0a04 -+#define RTL8367C_VLAN_MSTI2_CTRL0_PORT7_STATE_OFFSET 14 -+#define RTL8367C_VLAN_MSTI2_CTRL0_PORT7_STATE_MASK 0xC000 -+#define RTL8367C_VLAN_MSTI2_CTRL0_PORT6_STATE_OFFSET 12 -+#define RTL8367C_VLAN_MSTI2_CTRL0_PORT6_STATE_MASK 0x3000 -+#define RTL8367C_VLAN_MSTI2_CTRL0_PORT5_STATE_OFFSET 10 -+#define RTL8367C_VLAN_MSTI2_CTRL0_PORT5_STATE_MASK 0xC00 -+#define RTL8367C_VLAN_MSTI2_CTRL0_PORT4_STATE_OFFSET 8 -+#define RTL8367C_VLAN_MSTI2_CTRL0_PORT4_STATE_MASK 0x300 -+#define RTL8367C_VLAN_MSTI2_CTRL0_PORT3_STATE_OFFSET 6 -+#define RTL8367C_VLAN_MSTI2_CTRL0_PORT3_STATE_MASK 0xC0 -+#define RTL8367C_VLAN_MSTI2_CTRL0_PORT2_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI2_CTRL0_PORT2_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI2_CTRL0_PORT1_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI2_CTRL0_PORT1_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI2_CTRL0_PORT0_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI2_CTRL0_PORT0_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI2_CTRL1 0x0a05 -+#define RTL8367C_VLAN_MSTI2_CTRL1_PORT10_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI2_CTRL1_PORT10_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI2_CTRL1_PORT9_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI2_CTRL1_PORT9_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI2_CTRL1_PORT8_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI2_CTRL1_PORT8_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI3_CTRL0 0x0a06 -+#define RTL8367C_VLAN_MSTI3_CTRL0_PORT7_STATE_OFFSET 14 -+#define RTL8367C_VLAN_MSTI3_CTRL0_PORT7_STATE_MASK 0xC000 -+#define RTL8367C_VLAN_MSTI3_CTRL0_PORT6_STATE_OFFSET 12 -+#define RTL8367C_VLAN_MSTI3_CTRL0_PORT6_STATE_MASK 0x3000 -+#define RTL8367C_VLAN_MSTI3_CTRL0_PORT5_STATE_OFFSET 10 -+#define RTL8367C_VLAN_MSTI3_CTRL0_PORT5_STATE_MASK 0xC00 -+#define RTL8367C_VLAN_MSTI3_CTRL0_PORT4_STATE_OFFSET 8 -+#define RTL8367C_VLAN_MSTI3_CTRL0_PORT4_STATE_MASK 0x300 -+#define RTL8367C_VLAN_MSTI3_CTRL0_PORT3_STATE_OFFSET 6 -+#define RTL8367C_VLAN_MSTI3_CTRL0_PORT3_STATE_MASK 0xC0 -+#define RTL8367C_VLAN_MSTI3_CTRL0_PORT2_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI3_CTRL0_PORT2_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI3_CTRL0_PORT1_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI3_CTRL0_PORT1_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI3_CTRL0_PORT0_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI3_CTRL0_PORT0_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI3_CTRL1 0x0a07 -+#define RTL8367C_VLAN_MSTI3_CTRL1_PORT10_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI3_CTRL1_PORT10_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI3_CTRL1_PORT9_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI3_CTRL1_PORT9_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI3_CTRL1_PORT8_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI3_CTRL1_PORT8_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI4_CTRL0 0x0a08 -+#define RTL8367C_VLAN_MSTI4_CTRL0_PORT7_STATE_OFFSET 14 -+#define RTL8367C_VLAN_MSTI4_CTRL0_PORT7_STATE_MASK 0xC000 -+#define RTL8367C_VLAN_MSTI4_CTRL0_PORT6_STATE_OFFSET 12 -+#define RTL8367C_VLAN_MSTI4_CTRL0_PORT6_STATE_MASK 0x3000 -+#define RTL8367C_VLAN_MSTI4_CTRL0_PORT5_STATE_OFFSET 10 -+#define RTL8367C_VLAN_MSTI4_CTRL0_PORT5_STATE_MASK 0xC00 -+#define RTL8367C_VLAN_MSTI4_CTRL0_PORT4_STATE_OFFSET 8 -+#define RTL8367C_VLAN_MSTI4_CTRL0_PORT4_STATE_MASK 0x300 -+#define RTL8367C_VLAN_MSTI4_CTRL0_PORT3_STATE_OFFSET 6 -+#define RTL8367C_VLAN_MSTI4_CTRL0_PORT3_STATE_MASK 0xC0 -+#define RTL8367C_VLAN_MSTI4_CTRL0_PORT2_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI4_CTRL0_PORT2_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI4_CTRL0_PORT1_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI4_CTRL0_PORT1_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI4_CTRL0_PORT0_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI4_CTRL0_PORT0_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI4_CTRL1 0x0a09 -+#define RTL8367C_VLAN_MSTI4_CTRL1_PORT10_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI4_CTRL1_PORT10_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI4_CTRL1_PORT9_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI4_CTRL1_PORT9_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI4_CTRL1_PORT8_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI4_CTRL1_PORT8_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI5_CTRL0 0x0a0a -+#define RTL8367C_VLAN_MSTI5_CTRL0_PORT7_STATE_OFFSET 14 -+#define RTL8367C_VLAN_MSTI5_CTRL0_PORT7_STATE_MASK 0xC000 -+#define RTL8367C_VLAN_MSTI5_CTRL0_PORT6_STATE_OFFSET 12 -+#define RTL8367C_VLAN_MSTI5_CTRL0_PORT6_STATE_MASK 0x3000 -+#define RTL8367C_VLAN_MSTI5_CTRL0_PORT5_STATE_OFFSET 10 -+#define RTL8367C_VLAN_MSTI5_CTRL0_PORT5_STATE_MASK 0xC00 -+#define RTL8367C_VLAN_MSTI5_CTRL0_PORT4_STATE_OFFSET 8 -+#define RTL8367C_VLAN_MSTI5_CTRL0_PORT4_STATE_MASK 0x300 -+#define RTL8367C_VLAN_MSTI5_CTRL0_PORT3_STATE_OFFSET 6 -+#define RTL8367C_VLAN_MSTI5_CTRL0_PORT3_STATE_MASK 0xC0 -+#define RTL8367C_VLAN_MSTI5_CTRL0_PORT2_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI5_CTRL0_PORT2_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI5_CTRL0_PORT1_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI5_CTRL0_PORT1_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI5_CTRL0_PORT0_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI5_CTRL0_PORT0_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI5_CTRL1 0x0a0b -+#define RTL8367C_VLAN_MSTI5_CTRL1_PORT10_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI5_CTRL1_PORT10_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI5_CTRL1_PORT9_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI5_CTRL1_PORT9_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI5_CTRL1_PORT8_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI5_CTRL1_PORT8_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI6_CTRL0 0x0a0c -+#define RTL8367C_VLAN_MSTI6_CTRL0_PORT7_STATE_OFFSET 14 -+#define RTL8367C_VLAN_MSTI6_CTRL0_PORT7_STATE_MASK 0xC000 -+#define RTL8367C_VLAN_MSTI6_CTRL0_PORT6_STATE_OFFSET 12 -+#define RTL8367C_VLAN_MSTI6_CTRL0_PORT6_STATE_MASK 0x3000 -+#define RTL8367C_VLAN_MSTI6_CTRL0_PORT5_STATE_OFFSET 10 -+#define RTL8367C_VLAN_MSTI6_CTRL0_PORT5_STATE_MASK 0xC00 -+#define RTL8367C_VLAN_MSTI6_CTRL0_PORT4_STATE_OFFSET 8 -+#define RTL8367C_VLAN_MSTI6_CTRL0_PORT4_STATE_MASK 0x300 -+#define RTL8367C_VLAN_MSTI6_CTRL0_PORT3_STATE_OFFSET 6 -+#define RTL8367C_VLAN_MSTI6_CTRL0_PORT3_STATE_MASK 0xC0 -+#define RTL8367C_VLAN_MSTI6_CTRL0_PORT2_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI6_CTRL0_PORT2_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI6_CTRL0_PORT1_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI6_CTRL0_PORT1_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI6_CTRL0_PORT0_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI6_CTRL0_PORT0_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI6_CTRL1 0x0a0d -+#define RTL8367C_VLAN_MSTI6_CTRL1_PORT10_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI6_CTRL1_PORT10_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI6_CTRL1_PORT9_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI6_CTRL1_PORT9_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI6_CTRL1_PORT8_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI6_CTRL1_PORT8_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI7_CTRL0 0x0a0e -+#define RTL8367C_VLAN_MSTI7_CTRL0_PORT7_STATE_OFFSET 14 -+#define RTL8367C_VLAN_MSTI7_CTRL0_PORT7_STATE_MASK 0xC000 -+#define RTL8367C_VLAN_MSTI7_CTRL0_PORT6_STATE_OFFSET 12 -+#define RTL8367C_VLAN_MSTI7_CTRL0_PORT6_STATE_MASK 0x3000 -+#define RTL8367C_VLAN_MSTI7_CTRL0_PORT5_STATE_OFFSET 10 -+#define RTL8367C_VLAN_MSTI7_CTRL0_PORT5_STATE_MASK 0xC00 -+#define RTL8367C_VLAN_MSTI7_CTRL0_PORT4_STATE_OFFSET 8 -+#define RTL8367C_VLAN_MSTI7_CTRL0_PORT4_STATE_MASK 0x300 -+#define RTL8367C_VLAN_MSTI7_CTRL0_PORT3_STATE_OFFSET 6 -+#define RTL8367C_VLAN_MSTI7_CTRL0_PORT3_STATE_MASK 0xC0 -+#define RTL8367C_VLAN_MSTI7_CTRL0_PORT2_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI7_CTRL0_PORT2_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI7_CTRL0_PORT1_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI7_CTRL0_PORT1_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI7_CTRL0_PORT0_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI7_CTRL0_PORT0_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI7_CTRL1 0x0a0f -+#define RTL8367C_VLAN_MSTI7_CTRL1_PORT10_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI7_CTRL1_PORT10_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI7_CTRL1_PORT9_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI7_CTRL1_PORT9_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI7_CTRL1_PORT8_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI7_CTRL1_PORT8_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI8_CTRL0 0x0a10 -+#define RTL8367C_VLAN_MSTI8_CTRL0_PORT7_STATE_OFFSET 14 -+#define RTL8367C_VLAN_MSTI8_CTRL0_PORT7_STATE_MASK 0xC000 -+#define RTL8367C_VLAN_MSTI8_CTRL0_PORT6_STATE_OFFSET 12 -+#define RTL8367C_VLAN_MSTI8_CTRL0_PORT6_STATE_MASK 0x3000 -+#define RTL8367C_VLAN_MSTI8_CTRL0_PORT5_STATE_OFFSET 10 -+#define RTL8367C_VLAN_MSTI8_CTRL0_PORT5_STATE_MASK 0xC00 -+#define RTL8367C_VLAN_MSTI8_CTRL0_PORT4_STATE_OFFSET 8 -+#define RTL8367C_VLAN_MSTI8_CTRL0_PORT4_STATE_MASK 0x300 -+#define RTL8367C_VLAN_MSTI8_CTRL0_PORT3_STATE_OFFSET 6 -+#define RTL8367C_VLAN_MSTI8_CTRL0_PORT3_STATE_MASK 0xC0 -+#define RTL8367C_VLAN_MSTI8_CTRL0_PORT2_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI8_CTRL0_PORT2_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI8_CTRL0_PORT1_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI8_CTRL0_PORT1_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI8_CTRL0_PORT0_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI8_CTRL0_PORT0_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI8_CTRL1 0x0a11 -+#define RTL8367C_VLAN_MSTI8_CTRL1_PORT10_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI8_CTRL1_PORT10_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI8_CTRL1_PORT9_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI8_CTRL1_PORT9_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI8_CTRL1_PORT8_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI8_CTRL1_PORT8_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI9_CTRL0 0x0a12 -+#define RTL8367C_VLAN_MSTI9_CTRL0_PORT7_STATE_OFFSET 14 -+#define RTL8367C_VLAN_MSTI9_CTRL0_PORT7_STATE_MASK 0xC000 -+#define RTL8367C_VLAN_MSTI9_CTRL0_PORT6_STATE_OFFSET 12 -+#define RTL8367C_VLAN_MSTI9_CTRL0_PORT6_STATE_MASK 0x3000 -+#define RTL8367C_VLAN_MSTI9_CTRL0_PORT5_STATE_OFFSET 10 -+#define RTL8367C_VLAN_MSTI9_CTRL0_PORT5_STATE_MASK 0xC00 -+#define RTL8367C_VLAN_MSTI9_CTRL0_PORT4_STATE_OFFSET 8 -+#define RTL8367C_VLAN_MSTI9_CTRL0_PORT4_STATE_MASK 0x300 -+#define RTL8367C_VLAN_MSTI9_CTRL0_PORT3_STATE_OFFSET 6 -+#define RTL8367C_VLAN_MSTI9_CTRL0_PORT3_STATE_MASK 0xC0 -+#define RTL8367C_VLAN_MSTI9_CTRL0_PORT2_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI9_CTRL0_PORT2_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI9_CTRL0_PORT1_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI9_CTRL0_PORT1_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI9_CTRL0_PORT0_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI9_CTRL0_PORT0_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI9_CTRL1 0x0a13 -+#define RTL8367C_VLAN_MSTI9_CTRL1_PORT10_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI9_CTRL1_PORT10_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI9_CTRL1_PORT9_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI9_CTRL1_PORT9_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI9_CTRL1_PORT8_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI9_CTRL1_PORT8_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI10_CTRL0 0x0a14 -+#define RTL8367C_VLAN_MSTI10_CTRL0_PORT7_STATE_OFFSET 14 -+#define RTL8367C_VLAN_MSTI10_CTRL0_PORT7_STATE_MASK 0xC000 -+#define RTL8367C_VLAN_MSTI10_CTRL0_PORT6_STATE_OFFSET 12 -+#define RTL8367C_VLAN_MSTI10_CTRL0_PORT6_STATE_MASK 0x3000 -+#define RTL8367C_VLAN_MSTI10_CTRL0_PORT5_STATE_OFFSET 10 -+#define RTL8367C_VLAN_MSTI10_CTRL0_PORT5_STATE_MASK 0xC00 -+#define RTL8367C_VLAN_MSTI10_CTRL0_PORT4_STATE_OFFSET 8 -+#define RTL8367C_VLAN_MSTI10_CTRL0_PORT4_STATE_MASK 0x300 -+#define RTL8367C_VLAN_MSTI10_CTRL0_PORT3_STATE_OFFSET 6 -+#define RTL8367C_VLAN_MSTI10_CTRL0_PORT3_STATE_MASK 0xC0 -+#define RTL8367C_VLAN_MSTI10_CTRL0_PORT2_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI10_CTRL0_PORT2_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI10_CTRL0_PORT1_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI10_CTRL0_PORT1_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI10_CTRL0_PORT0_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI10_CTRL0_PORT0_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI10_CTRL1 0x0a15 -+#define RTL8367C_VLAN_MSTI10_CTRL1_PORT10_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI10_CTRL1_PORT10_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI10_CTRL1_PORT9_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI10_CTRL1_PORT9_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI10_CTRL1_PORT8_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI10_CTRL1_PORT8_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI11_CTRL0 0x0a16 -+#define RTL8367C_VLAN_MSTI11_CTRL0_PORT7_STATE_OFFSET 14 -+#define RTL8367C_VLAN_MSTI11_CTRL0_PORT7_STATE_MASK 0xC000 -+#define RTL8367C_VLAN_MSTI11_CTRL0_PORT6_STATE_OFFSET 12 -+#define RTL8367C_VLAN_MSTI11_CTRL0_PORT6_STATE_MASK 0x3000 -+#define RTL8367C_VLAN_MSTI11_CTRL0_PORT5_STATE_OFFSET 10 -+#define RTL8367C_VLAN_MSTI11_CTRL0_PORT5_STATE_MASK 0xC00 -+#define RTL8367C_VLAN_MSTI11_CTRL0_PORT4_STATE_OFFSET 8 -+#define RTL8367C_VLAN_MSTI11_CTRL0_PORT4_STATE_MASK 0x300 -+#define RTL8367C_VLAN_MSTI11_CTRL0_PORT3_STATE_OFFSET 6 -+#define RTL8367C_VLAN_MSTI11_CTRL0_PORT3_STATE_MASK 0xC0 -+#define RTL8367C_VLAN_MSTI11_CTRL0_PORT2_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI11_CTRL0_PORT2_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI11_CTRL0_PORT1_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI11_CTRL0_PORT1_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI11_CTRL0_PORT0_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI11_CTRL0_PORT0_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI11_CTRL1 0x0a17 -+#define RTL8367C_VLAN_MSTI11_CTRL1_PORT10_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI11_CTRL1_PORT10_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI11_CTRL1_PORT9_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI11_CTRL1_PORT9_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI11_CTRL1_PORT8_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI11_CTRL1_PORT8_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI12_CTRL0 0x0a18 -+#define RTL8367C_VLAN_MSTI12_CTRL0_PORT7_STATE_OFFSET 14 -+#define RTL8367C_VLAN_MSTI12_CTRL0_PORT7_STATE_MASK 0xC000 -+#define RTL8367C_VLAN_MSTI12_CTRL0_PORT6_STATE_OFFSET 12 -+#define RTL8367C_VLAN_MSTI12_CTRL0_PORT6_STATE_MASK 0x3000 -+#define RTL8367C_VLAN_MSTI12_CTRL0_PORT5_STATE_OFFSET 10 -+#define RTL8367C_VLAN_MSTI12_CTRL0_PORT5_STATE_MASK 0xC00 -+#define RTL8367C_VLAN_MSTI12_CTRL0_PORT4_STATE_OFFSET 8 -+#define RTL8367C_VLAN_MSTI12_CTRL0_PORT4_STATE_MASK 0x300 -+#define RTL8367C_VLAN_MSTI12_CTRL0_PORT3_STATE_OFFSET 6 -+#define RTL8367C_VLAN_MSTI12_CTRL0_PORT3_STATE_MASK 0xC0 -+#define RTL8367C_VLAN_MSTI12_CTRL0_PORT2_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI12_CTRL0_PORT2_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI12_CTRL0_PORT1_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI12_CTRL0_PORT1_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI12_CTRL0_PORT0_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI12_CTRL0_PORT0_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI12_CTRL1 0x0a19 -+#define RTL8367C_VLAN_MSTI12_CTRL1_PORT10_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI12_CTRL1_PORT10_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI12_CTRL1_PORT9_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI12_CTRL1_PORT9_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI12_CTRL1_PORT8_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI12_CTRL1_PORT8_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI13_CTRL0 0x0a1a -+#define RTL8367C_VLAN_MSTI13_CTRL0_PORT7_STATE_OFFSET 14 -+#define RTL8367C_VLAN_MSTI13_CTRL0_PORT7_STATE_MASK 0xC000 -+#define RTL8367C_VLAN_MSTI13_CTRL0_PORT6_STATE_OFFSET 12 -+#define RTL8367C_VLAN_MSTI13_CTRL0_PORT6_STATE_MASK 0x3000 -+#define RTL8367C_VLAN_MSTI13_CTRL0_PORT5_STATE_OFFSET 10 -+#define RTL8367C_VLAN_MSTI13_CTRL0_PORT5_STATE_MASK 0xC00 -+#define RTL8367C_VLAN_MSTI13_CTRL0_PORT4_STATE_OFFSET 8 -+#define RTL8367C_VLAN_MSTI13_CTRL0_PORT4_STATE_MASK 0x300 -+#define RTL8367C_VLAN_MSTI13_CTRL0_PORT3_STATE_OFFSET 6 -+#define RTL8367C_VLAN_MSTI13_CTRL0_PORT3_STATE_MASK 0xC0 -+#define RTL8367C_VLAN_MSTI13_CTRL0_PORT2_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI13_CTRL0_PORT2_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI13_CTRL0_PORT1_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI13_CTRL0_PORT1_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI13_CTRL0_PORT0_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI13_CTRL0_PORT0_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI13_CTRL1 0x0a1b -+#define RTL8367C_VLAN_MSTI13_CTRL1_PORT10_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI13_CTRL1_PORT10_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI13_CTRL1_PORT9_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI13_CTRL1_PORT9_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI13_CTRL1_PORT8_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI13_CTRL1_PORT8_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI14_CTRL0 0x0a1c -+#define RTL8367C_VLAN_MSTI14_CTRL0_PORT7_STATE_OFFSET 14 -+#define RTL8367C_VLAN_MSTI14_CTRL0_PORT7_STATE_MASK 0xC000 -+#define RTL8367C_VLAN_MSTI14_CTRL0_PORT6_STATE_OFFSET 12 -+#define RTL8367C_VLAN_MSTI14_CTRL0_PORT6_STATE_MASK 0x3000 -+#define RTL8367C_VLAN_MSTI14_CTRL0_PORT5_STATE_OFFSET 10 -+#define RTL8367C_VLAN_MSTI14_CTRL0_PORT5_STATE_MASK 0xC00 -+#define RTL8367C_VLAN_MSTI14_CTRL0_PORT4_STATE_OFFSET 8 -+#define RTL8367C_VLAN_MSTI14_CTRL0_PORT4_STATE_MASK 0x300 -+#define RTL8367C_VLAN_MSTI14_CTRL0_PORT3_STATE_OFFSET 6 -+#define RTL8367C_VLAN_MSTI14_CTRL0_PORT3_STATE_MASK 0xC0 -+#define RTL8367C_VLAN_MSTI14_CTRL0_PORT2_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI14_CTRL0_PORT2_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI14_CTRL0_PORT1_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI14_CTRL0_PORT1_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI14_CTRL0_PORT0_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI14_CTRL0_PORT0_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI14_CTRL1 0x0a1d -+#define RTL8367C_VLAN_MSTI14_CTRL1_PORT10_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI14_CTRL1_PORT10_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI14_CTRL1_PORT9_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI14_CTRL1_PORT9_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI14_CTRL1_PORT8_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI14_CTRL1_PORT8_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI15_CTRL0 0x0a1e -+#define RTL8367C_VLAN_MSTI15_CTRL0_PORT7_STATE_OFFSET 14 -+#define RTL8367C_VLAN_MSTI15_CTRL0_PORT7_STATE_MASK 0xC000 -+#define RTL8367C_VLAN_MSTI15_CTRL0_PORT6_STATE_OFFSET 12 -+#define RTL8367C_VLAN_MSTI15_CTRL0_PORT6_STATE_MASK 0x3000 -+#define RTL8367C_VLAN_MSTI15_CTRL0_PORT5_STATE_OFFSET 10 -+#define RTL8367C_VLAN_MSTI15_CTRL0_PORT5_STATE_MASK 0xC00 -+#define RTL8367C_VLAN_MSTI15_CTRL0_PORT4_STATE_OFFSET 8 -+#define RTL8367C_VLAN_MSTI15_CTRL0_PORT4_STATE_MASK 0x300 -+#define RTL8367C_VLAN_MSTI15_CTRL0_PORT3_STATE_OFFSET 6 -+#define RTL8367C_VLAN_MSTI15_CTRL0_PORT3_STATE_MASK 0xC0 -+#define RTL8367C_VLAN_MSTI15_CTRL0_PORT2_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI15_CTRL0_PORT2_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI15_CTRL0_PORT1_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI15_CTRL0_PORT1_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI15_CTRL0_PORT0_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI15_CTRL0_PORT0_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_VLAN_MSTI15_CTRL1 0x0a1f -+#define RTL8367C_VLAN_MSTI15_CTRL1_PORT10_STATE_OFFSET 4 -+#define RTL8367C_VLAN_MSTI15_CTRL1_PORT10_STATE_MASK 0x30 -+#define RTL8367C_VLAN_MSTI15_CTRL1_PORT9_STATE_OFFSET 2 -+#define RTL8367C_VLAN_MSTI15_CTRL1_PORT9_STATE_MASK 0xC -+#define RTL8367C_VLAN_MSTI15_CTRL1_PORT8_STATE_OFFSET 0 -+#define RTL8367C_VLAN_MSTI15_CTRL1_PORT8_STATE_MASK 0x3 -+ -+#define RTL8367C_REG_LUT_PORT0_LEARN_LIMITNO 0x0a20 -+#define RTL8367C_LUT_PORT0_LEARN_LIMITNO_OFFSET 0 -+#define RTL8367C_LUT_PORT0_LEARN_LIMITNO_MASK 0x1FFF -+ -+#define RTL8367C_REG_LUT_PORT1_LEARN_LIMITNO 0x0a21 -+#define RTL8367C_LUT_PORT1_LEARN_LIMITNO_OFFSET 0 -+#define RTL8367C_LUT_PORT1_LEARN_LIMITNO_MASK 0x1FFF -+ -+#define RTL8367C_REG_LUT_PORT2_LEARN_LIMITNO 0x0a22 -+#define RTL8367C_LUT_PORT2_LEARN_LIMITNO_OFFSET 0 -+#define RTL8367C_LUT_PORT2_LEARN_LIMITNO_MASK 0x1FFF -+ -+#define RTL8367C_REG_LUT_PORT3_LEARN_LIMITNO 0x0a23 -+#define RTL8367C_LUT_PORT3_LEARN_LIMITNO_OFFSET 0 -+#define RTL8367C_LUT_PORT3_LEARN_LIMITNO_MASK 0x1FFF -+ -+#define RTL8367C_REG_LUT_PORT4_LEARN_LIMITNO 0x0a24 -+#define RTL8367C_LUT_PORT4_LEARN_LIMITNO_OFFSET 0 -+#define RTL8367C_LUT_PORT4_LEARN_LIMITNO_MASK 0x1FFF -+ -+#define RTL8367C_REG_LUT_PORT5_LEARN_LIMITNO 0x0a25 -+#define RTL8367C_LUT_PORT5_LEARN_LIMITNO_OFFSET 0 -+#define RTL8367C_LUT_PORT5_LEARN_LIMITNO_MASK 0x1FFF -+ -+#define RTL8367C_REG_LUT_PORT6_LEARN_LIMITNO 0x0a26 -+#define RTL8367C_LUT_PORT6_LEARN_LIMITNO_OFFSET 0 -+#define RTL8367C_LUT_PORT6_LEARN_LIMITNO_MASK 0x1FFF -+ -+#define RTL8367C_REG_LUT_PORT7_LEARN_LIMITNO 0x0a27 -+#define RTL8367C_LUT_PORT7_LEARN_LIMITNO_OFFSET 0 -+#define RTL8367C_LUT_PORT7_LEARN_LIMITNO_MASK 0x1FFF -+ -+#define RTL8367C_REG_LUT_SYS_LEARN_LIMITNO 0x0a28 -+#define RTL8367C_LUT_SYS_LEARN_LIMITNO_OFFSET 0 -+#define RTL8367C_LUT_SYS_LEARN_LIMITNO_MASK 0x1FFF -+ -+#define RTL8367C_REG_LUT_LRN_SYS_LMT_CTRL 0x0a29 -+#define RTL8367C_LUT_SYSTEM_LEARN_PMASK1_OFFSET 12 -+#define RTL8367C_LUT_SYSTEM_LEARN_PMASK1_MASK 0x7000 -+#define RTL8367C_LUT_SYSTEM_LEARN_OVER_ACT_OFFSET 10 -+#define RTL8367C_LUT_SYSTEM_LEARN_OVER_ACT_MASK 0xC00 -+#define RTL8367C_LUT_SYSTEM_LEARN_PMASK_OFFSET 0 -+#define RTL8367C_LUT_SYSTEM_LEARN_PMASK_MASK 0xFF -+ -+#define RTL8367C_REG_LUT_PORT8_LEARN_LIMITNO 0x0a2a -+#define RTL8367C_LUT_PORT8_LEARN_LIMITNO_OFFSET 0 -+#define RTL8367C_LUT_PORT8_LEARN_LIMITNO_MASK 0x1FFF -+ -+#define RTL8367C_REG_LUT_PORT9_LEARN_LIMITNO 0x0a2b -+#define RTL8367C_LUT_PORT9_LEARN_LIMITNO_OFFSET 0 -+#define RTL8367C_LUT_PORT9_LEARN_LIMITNO_MASK 0x1FFF -+ -+#define RTL8367C_REG_LUT_PORT10_LEARN_LIMITNO 0x0a2c -+#define RTL8367C_LUT_PORT10_LEARN_LIMITNO_OFFSET 0 -+#define RTL8367C_LUT_PORT10_LEARN_LIMITNO_MASK 0x1FFF -+ -+#define RTL8367C_REG_LUT_CFG 0x0a30 -+#define RTL8367C_AGE_SPEED_OFFSET 8 -+#define RTL8367C_AGE_SPEED_MASK 0x300 -+#define RTL8367C_BCAM_DISABLE_OFFSET 6 -+#define RTL8367C_BCAM_DISABLE_MASK 0x40 -+#define RTL8367C_LINKDOWN_AGEOUT_OFFSET 5 -+#define RTL8367C_LINKDOWN_AGEOUT_MASK 0x20 -+#define RTL8367C_LUT_IPMC_HASH_OFFSET 4 -+#define RTL8367C_LUT_IPMC_HASH_MASK 0x10 -+#define RTL8367C_LUT_IPMC_LOOKUP_OP_OFFSET 3 -+#define RTL8367C_LUT_IPMC_LOOKUP_OP_MASK 0x8 -+#define RTL8367C_AGE_TIMER_OFFSET 0 -+#define RTL8367C_AGE_TIMER_MASK 0x7 -+ -+#define RTL8367C_REG_LUT_AGEOUT_CTRL 0x0a31 -+#define RTL8367C_LUT_AGEOUT_CTRL_OFFSET 0 -+#define RTL8367C_LUT_AGEOUT_CTRL_MASK 0x7FF -+ -+#define RTL8367C_REG_PORT_EFID_CTRL0 0x0a32 -+#define RTL8367C_PORT3_EFID_OFFSET 12 -+#define RTL8367C_PORT3_EFID_MASK 0x7000 -+#define RTL8367C_PORT2_EFID_OFFSET 8 -+#define RTL8367C_PORT2_EFID_MASK 0x700 -+#define RTL8367C_PORT1_EFID_OFFSET 4 -+#define RTL8367C_PORT1_EFID_MASK 0x70 -+#define RTL8367C_PORT0_EFID_OFFSET 0 -+#define RTL8367C_PORT0_EFID_MASK 0x7 -+ -+#define RTL8367C_REG_PORT_EFID_CTRL1 0x0a33 -+#define RTL8367C_PORT7_EFID_OFFSET 12 -+#define RTL8367C_PORT7_EFID_MASK 0x7000 -+#define RTL8367C_PORT6_EFID_OFFSET 8 -+#define RTL8367C_PORT6_EFID_MASK 0x700 -+#define RTL8367C_PORT5_EFID_OFFSET 4 -+#define RTL8367C_PORT5_EFID_MASK 0x70 -+#define RTL8367C_PORT4_EFID_OFFSET 0 -+#define RTL8367C_PORT4_EFID_MASK 0x7 -+ -+#define RTL8367C_REG_PORT_EFID_CTRL2 0x0a34 -+#define RTL8367C_PORT10_EFID_OFFSET 8 -+#define RTL8367C_PORT10_EFID_MASK 0x700 -+#define RTL8367C_PORT9_EFID_OFFSET 4 -+#define RTL8367C_PORT9_EFID_MASK 0x70 -+#define RTL8367C_PORT8_EFID_OFFSET 0 -+#define RTL8367C_PORT8_EFID_MASK 0x7 -+ -+#define RTL8367C_REG_FORCE_FLUSH1 0x0a35 -+#define RTL8367C_BUSY_STATUS1_OFFSET 3 -+#define RTL8367C_BUSY_STATUS1_MASK 0x38 -+#define RTL8367C_PORTMASK1_OFFSET 0 -+#define RTL8367C_PORTMASK1_MASK 0x7 -+ -+#define RTL8367C_REG_FORCE_FLUSH 0x0a36 -+#define RTL8367C_BUSY_STATUS_OFFSET 8 -+#define RTL8367C_BUSY_STATUS_MASK 0xFF00 -+#define RTL8367C_FORCE_FLUSH_PORTMASK_OFFSET 0 -+#define RTL8367C_FORCE_FLUSH_PORTMASK_MASK 0xFF -+ -+#define RTL8367C_REG_L2_FLUSH_CTRL1 0x0a37 -+#define RTL8367C_LUT_FLUSH_FID_OFFSET 12 -+#define RTL8367C_LUT_FLUSH_FID_MASK 0xF000 -+#define RTL8367C_LUT_FLUSH_VID_OFFSET 0 -+#define RTL8367C_LUT_FLUSH_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_L2_FLUSH_CTRL2 0x0a38 -+#define RTL8367C_LUT_FLUSH_TYPE_OFFSET 2 -+#define RTL8367C_LUT_FLUSH_TYPE_MASK 0x4 -+#define RTL8367C_LUT_FLUSH_MODE_OFFSET 0 -+#define RTL8367C_LUT_FLUSH_MODE_MASK 0x3 -+ -+#define RTL8367C_REG_L2_FLUSH_CTRL3 0x0a39 -+#define RTL8367C_L2_FLUSH_CTRL3_OFFSET 0 -+#define RTL8367C_L2_FLUSH_CTRL3_MASK 0x1 -+ -+#define RTL8367C_REG_LUT_CFG2 0x0a3a -+#define RTL8367C_LUT_IPMC_FWD_RPORT_OFFSET 1 -+#define RTL8367C_LUT_IPMC_FWD_RPORT_MASK 0x2 -+#define RTL8367C_LUT_IPMC_VID_HASH_OFFSET 0 -+#define RTL8367C_LUT_IPMC_VID_HASH_MASK 0x1 -+ -+#define RTL8367C_REG_FLUSH_STATUS 0x0a3f -+#define RTL8367C_FLUSH_STATUS_OFFSET 0 -+#define RTL8367C_FLUSH_STATUS_MASK 0x1 -+ -+#define RTL8367C_REG_STORM_BCAST 0x0a40 -+#define RTL8367C_STORM_BCAST_OFFSET 0 -+#define RTL8367C_STORM_BCAST_MASK 0x7FF -+ -+#define RTL8367C_REG_STORM_MCAST 0x0a41 -+#define RTL8367C_STORM_MCAST_OFFSET 0 -+#define RTL8367C_STORM_MCAST_MASK 0x7FF -+ -+#define RTL8367C_REG_STORM_UNKOWN_UCAST 0x0a42 -+#define RTL8367C_STORM_UNKOWN_UCAST_OFFSET 0 -+#define RTL8367C_STORM_UNKOWN_UCAST_MASK 0x7FF -+ -+#define RTL8367C_REG_STORM_UNKOWN_MCAST 0x0a43 -+#define RTL8367C_STORM_UNKOWN_MCAST_OFFSET 0 -+#define RTL8367C_STORM_UNKOWN_MCAST_MASK 0x7FF -+ -+#define RTL8367C_REG_STORM_BCAST_METER_CTRL0 0x0a44 -+#define RTL8367C_STORM_BCAST_METER_CTRL0_PORT1_METERIDX_OFFSET 8 -+#define RTL8367C_STORM_BCAST_METER_CTRL0_PORT1_METERIDX_MASK 0x3F00 -+#define RTL8367C_STORM_BCAST_METER_CTRL0_PORT0_METERIDX_OFFSET 0 -+#define RTL8367C_STORM_BCAST_METER_CTRL0_PORT0_METERIDX_MASK 0x3F -+ -+#define RTL8367C_REG_STORM_BCAST_METER_CTRL1 0x0a45 -+#define RTL8367C_STORM_BCAST_METER_CTRL1_PORT3_METERIDX_OFFSET 8 -+#define RTL8367C_STORM_BCAST_METER_CTRL1_PORT3_METERIDX_MASK 0x3F00 -+#define RTL8367C_STORM_BCAST_METER_CTRL1_PORT2_METERIDX_OFFSET 0 -+#define RTL8367C_STORM_BCAST_METER_CTRL1_PORT2_METERIDX_MASK 0x3F -+ -+#define RTL8367C_REG_STORM_BCAST_METER_CTRL2 0x0a46 -+#define RTL8367C_STORM_BCAST_METER_CTRL2_PORT5_METERIDX_OFFSET 8 -+#define RTL8367C_STORM_BCAST_METER_CTRL2_PORT5_METERIDX_MASK 0x3F00 -+#define RTL8367C_STORM_BCAST_METER_CTRL2_PORT4_METERIDX_OFFSET 0 -+#define RTL8367C_STORM_BCAST_METER_CTRL2_PORT4_METERIDX_MASK 0x3F -+ -+#define RTL8367C_REG_STORM_BCAST_METER_CTRL3 0x0a47 -+#define RTL8367C_STORM_BCAST_METER_CTRL3_PORT7_METERIDX_OFFSET 8 -+#define RTL8367C_STORM_BCAST_METER_CTRL3_PORT7_METERIDX_MASK 0x3F00 -+#define RTL8367C_STORM_BCAST_METER_CTRL3_PORT6_METERIDX_OFFSET 0 -+#define RTL8367C_STORM_BCAST_METER_CTRL3_PORT6_METERIDX_MASK 0x3F -+ -+#define RTL8367C_REG_STORM_BCAST_METER_CTRL4 0x0a48 -+#define RTL8367C_STORM_BCAST_METER_CTRL4_PORT9_METERIDX_OFFSET 8 -+#define RTL8367C_STORM_BCAST_METER_CTRL4_PORT9_METERIDX_MASK 0x3F00 -+#define RTL8367C_STORM_BCAST_METER_CTRL4_PORT8_METERIDX_OFFSET 0 -+#define RTL8367C_STORM_BCAST_METER_CTRL4_PORT8_METERIDX_MASK 0x3F -+ -+#define RTL8367C_REG_STORM_BCAST_METER_CTRL5 0x0a49 -+#define RTL8367C_STORM_BCAST_METER_CTRL5_OFFSET 0 -+#define RTL8367C_STORM_BCAST_METER_CTRL5_MASK 0x3F -+ -+#define RTL8367C_REG_STORM_MCAST_METER_CTRL0 0x0a4c -+#define RTL8367C_STORM_MCAST_METER_CTRL0_PORT1_METERIDX_OFFSET 8 -+#define RTL8367C_STORM_MCAST_METER_CTRL0_PORT1_METERIDX_MASK 0x3F00 -+#define RTL8367C_STORM_MCAST_METER_CTRL0_PORT0_METERIDX_OFFSET 0 -+#define RTL8367C_STORM_MCAST_METER_CTRL0_PORT0_METERIDX_MASK 0x3F -+ -+#define RTL8367C_REG_STORM_MCAST_METER_CTRL1 0x0a4d -+#define RTL8367C_STORM_MCAST_METER_CTRL1_PORT3_METERIDX_OFFSET 8 -+#define RTL8367C_STORM_MCAST_METER_CTRL1_PORT3_METERIDX_MASK 0x3F00 -+#define RTL8367C_STORM_MCAST_METER_CTRL1_PORT2_METERIDX_OFFSET 0 -+#define RTL8367C_STORM_MCAST_METER_CTRL1_PORT2_METERIDX_MASK 0x3F -+ -+#define RTL8367C_REG_STORM_MCAST_METER_CTRL2 0x0a4e -+#define RTL8367C_STORM_MCAST_METER_CTRL2_PORT5_METERIDX_OFFSET 8 -+#define RTL8367C_STORM_MCAST_METER_CTRL2_PORT5_METERIDX_MASK 0x3F00 -+#define RTL8367C_STORM_MCAST_METER_CTRL2_PORT4_METERIDX_OFFSET 0 -+#define RTL8367C_STORM_MCAST_METER_CTRL2_PORT4_METERIDX_MASK 0x3F -+ -+#define RTL8367C_REG_STORM_MCAST_METER_CTRL3 0x0a4f -+#define RTL8367C_STORM_MCAST_METER_CTRL3_PORT7_METERIDX_OFFSET 8 -+#define RTL8367C_STORM_MCAST_METER_CTRL3_PORT7_METERIDX_MASK 0x3F00 -+#define RTL8367C_STORM_MCAST_METER_CTRL3_PORT6_METERIDX_OFFSET 0 -+#define RTL8367C_STORM_MCAST_METER_CTRL3_PORT6_METERIDX_MASK 0x3F -+ -+#define RTL8367C_REG_STORM_MCAST_METER_CTRL4 0x0a50 -+#define RTL8367C_STORM_MCAST_METER_CTRL4_PORT9_METERIDX_OFFSET 8 -+#define RTL8367C_STORM_MCAST_METER_CTRL4_PORT9_METERIDX_MASK 0x3F00 -+#define RTL8367C_STORM_MCAST_METER_CTRL4_PORT8_METERIDX_OFFSET 0 -+#define RTL8367C_STORM_MCAST_METER_CTRL4_PORT8_METERIDX_MASK 0x3F -+ -+#define RTL8367C_REG_STORM_MCAST_METER_CTRL5 0x0a51 -+#define RTL8367C_STORM_MCAST_METER_CTRL5_OFFSET 0 -+#define RTL8367C_STORM_MCAST_METER_CTRL5_MASK 0x3F -+ -+#define RTL8367C_REG_STORM_UNDA_METER_CTRL0 0x0a54 -+#define RTL8367C_STORM_UNDA_METER_CTRL0_PORT1_METERIDX_OFFSET 8 -+#define RTL8367C_STORM_UNDA_METER_CTRL0_PORT1_METERIDX_MASK 0x3F00 -+#define RTL8367C_STORM_UNDA_METER_CTRL0_PORT0_METERIDX_OFFSET 0 -+#define RTL8367C_STORM_UNDA_METER_CTRL0_PORT0_METERIDX_MASK 0x3F -+ -+#define RTL8367C_REG_STORM_UNDA_METER_CTRL1 0x0a55 -+#define RTL8367C_STORM_UNDA_METER_CTRL1_PORT3_METERIDX_OFFSET 8 -+#define RTL8367C_STORM_UNDA_METER_CTRL1_PORT3_METERIDX_MASK 0x3F00 -+#define RTL8367C_STORM_UNDA_METER_CTRL1_PORT2_METERIDX_OFFSET 0 -+#define RTL8367C_STORM_UNDA_METER_CTRL1_PORT2_METERIDX_MASK 0x3F -+ -+#define RTL8367C_REG_STORM_UNDA_METER_CTRL2 0x0a56 -+#define RTL8367C_STORM_UNDA_METER_CTRL2_PORT5_METERIDX_OFFSET 8 -+#define RTL8367C_STORM_UNDA_METER_CTRL2_PORT5_METERIDX_MASK 0x3F00 -+#define RTL8367C_STORM_UNDA_METER_CTRL2_PORT4_METERIDX_OFFSET 0 -+#define RTL8367C_STORM_UNDA_METER_CTRL2_PORT4_METERIDX_MASK 0x3F -+ -+#define RTL8367C_REG_STORM_UNDA_METER_CTRL3 0x0a57 -+#define RTL8367C_STORM_UNDA_METER_CTRL3_PORT7_METERIDX_OFFSET 8 -+#define RTL8367C_STORM_UNDA_METER_CTRL3_PORT7_METERIDX_MASK 0x3F00 -+#define RTL8367C_STORM_UNDA_METER_CTRL3_PORT6_METERIDX_OFFSET 0 -+#define RTL8367C_STORM_UNDA_METER_CTRL3_PORT6_METERIDX_MASK 0x3F -+ -+#define RTL8367C_REG_STORM_UNDA_METER_CTRL4 0x0a58 -+#define RTL8367C_STORM_UNDA_METER_CTRL4_PORT9_METERIDX_OFFSET 8 -+#define RTL8367C_STORM_UNDA_METER_CTRL4_PORT9_METERIDX_MASK 0x3F00 -+#define RTL8367C_STORM_UNDA_METER_CTRL4_PORT8_METERIDX_OFFSET 0 -+#define RTL8367C_STORM_UNDA_METER_CTRL4_PORT8_METERIDX_MASK 0x3F -+ -+#define RTL8367C_REG_STORM_UNDA_METER_CTRL5 0x0a59 -+#define RTL8367C_STORM_UNDA_METER_CTRL5_OFFSET 0 -+#define RTL8367C_STORM_UNDA_METER_CTRL5_MASK 0x3F -+ -+#define RTL8367C_REG_STORM_UNMC_METER_CTRL0 0x0a5c -+#define RTL8367C_STORM_UNMC_METER_CTRL0_PORT1_METERIDX_OFFSET 8 -+#define RTL8367C_STORM_UNMC_METER_CTRL0_PORT1_METERIDX_MASK 0x3F00 -+#define RTL8367C_STORM_UNMC_METER_CTRL0_PORT0_METERIDX_OFFSET 0 -+#define RTL8367C_STORM_UNMC_METER_CTRL0_PORT0_METERIDX_MASK 0x3F -+ -+#define RTL8367C_REG_STORM_UNMC_METER_CTRL1 0x0a5d -+#define RTL8367C_STORM_UNMC_METER_CTRL1_PORT3_METERIDX_OFFSET 8 -+#define RTL8367C_STORM_UNMC_METER_CTRL1_PORT3_METERIDX_MASK 0x3F00 -+#define RTL8367C_STORM_UNMC_METER_CTRL1_PORT2_METERIDX_OFFSET 0 -+#define RTL8367C_STORM_UNMC_METER_CTRL1_PORT2_METERIDX_MASK 0x3F -+ -+#define RTL8367C_REG_STORM_UNMC_METER_CTRL2 0x0a5e -+#define RTL8367C_STORM_UNMC_METER_CTRL2_PORT5_METERIDX_OFFSET 8 -+#define RTL8367C_STORM_UNMC_METER_CTRL2_PORT5_METERIDX_MASK 0x3F00 -+#define RTL8367C_STORM_UNMC_METER_CTRL2_PORT4_METERIDX_OFFSET 0 -+#define RTL8367C_STORM_UNMC_METER_CTRL2_PORT4_METERIDX_MASK 0x3F -+ -+#define RTL8367C_REG_STORM_UNMC_METER_CTRL3 0x0a5f -+#define RTL8367C_STORM_UNMC_METER_CTRL3_PORT7_METERIDX_OFFSET 8 -+#define RTL8367C_STORM_UNMC_METER_CTRL3_PORT7_METERIDX_MASK 0x3F00 -+#define RTL8367C_STORM_UNMC_METER_CTRL3_PORT6_METERIDX_OFFSET 0 -+#define RTL8367C_STORM_UNMC_METER_CTRL3_PORT6_METERIDX_MASK 0x3F -+ -+#define RTL8367C_REG_STORM_EXT_CFG 0x0a60 -+#define RTL8367C_STORM_EXT_EN_PORTMASK_EXT_OFFSET 14 -+#define RTL8367C_STORM_EXT_EN_PORTMASK_EXT_MASK 0x4000 -+#define RTL8367C_STORM_UNKNOWN_MCAST_EXT_EN_OFFSET 13 -+#define RTL8367C_STORM_UNKNOWN_MCAST_EXT_EN_MASK 0x2000 -+#define RTL8367C_STORM_UNKNOWN_UCAST_EXT_EN_OFFSET 12 -+#define RTL8367C_STORM_UNKNOWN_UCAST_EXT_EN_MASK 0x1000 -+#define RTL8367C_STORM_MCAST_EXT_EN_OFFSET 11 -+#define RTL8367C_STORM_MCAST_EXT_EN_MASK 0x800 -+#define RTL8367C_STORM_BCAST_EXT_EN_OFFSET 10 -+#define RTL8367C_STORM_BCAST_EXT_EN_MASK 0x400 -+#define RTL8367C_STORM_EXT_EN_PORTMASK_OFFSET 0 -+#define RTL8367C_STORM_EXT_EN_PORTMASK_MASK 0x3FF -+ -+#define RTL8367C_REG_STORM_EXT_MTRIDX_CFG0 0x0a61 -+#define RTL8367C_MC_STORM_EXT_METERIDX_OFFSET 8 -+#define RTL8367C_MC_STORM_EXT_METERIDX_MASK 0x3F00 -+#define RTL8367C_BC_STORM_EXT_METERIDX_OFFSET 0 -+#define RTL8367C_BC_STORM_EXT_METERIDX_MASK 0x3F -+ -+#define RTL8367C_REG_STORM_EXT_MTRIDX_CFG1 0x0a62 -+#define RTL8367C_UNMC_STORM_EXT_METERIDX_OFFSET 8 -+#define RTL8367C_UNMC_STORM_EXT_METERIDX_MASK 0x3F00 -+#define RTL8367C_UNUC_STORM_EXT_METERIDX_OFFSET 0 -+#define RTL8367C_UNUC_STORM_EXT_METERIDX_MASK 0x3F -+ -+#define RTL8367C_REG_STORM_UNMC_METER_CTRL4 0x0a63 -+#define RTL8367C_STORM_UNMC_METER_CTRL4_PORT9_METERIDX_OFFSET 8 -+#define RTL8367C_STORM_UNMC_METER_CTRL4_PORT9_METERIDX_MASK 0x3F00 -+#define RTL8367C_STORM_UNMC_METER_CTRL4_PORT8_METERIDX_OFFSET 0 -+#define RTL8367C_STORM_UNMC_METER_CTRL4_PORT8_METERIDX_MASK 0x3F -+ -+#define RTL8367C_REG_STORM_UNMC_METER_CTRL5 0x0a64 -+#define RTL8367C_STORM_UNMC_METER_CTRL5_OFFSET 0 -+#define RTL8367C_STORM_UNMC_METER_CTRL5_MASK 0x3F -+ -+#define RTL8367C_REG_OAM_PARSER_CTRL0 0x0a70 -+#define RTL8367C_PORT7_PARACT_OFFSET 14 -+#define RTL8367C_PORT7_PARACT_MASK 0xC000 -+#define RTL8367C_PORT6_PARACT_OFFSET 12 -+#define RTL8367C_PORT6_PARACT_MASK 0x3000 -+#define RTL8367C_PORT5_PARACT_OFFSET 10 -+#define RTL8367C_PORT5_PARACT_MASK 0xC00 -+#define RTL8367C_PORT4_PARACT_OFFSET 8 -+#define RTL8367C_PORT4_PARACT_MASK 0x300 -+#define RTL8367C_PORT3_PARACT_OFFSET 6 -+#define RTL8367C_PORT3_PARACT_MASK 0xC0 -+#define RTL8367C_PORT2_PARACT_OFFSET 4 -+#define RTL8367C_PORT2_PARACT_MASK 0x30 -+#define RTL8367C_PORT1_PARACT_OFFSET 2 -+#define RTL8367C_PORT1_PARACT_MASK 0xC -+#define RTL8367C_PORT0_PARACT_OFFSET 0 -+#define RTL8367C_PORT0_PARACT_MASK 0x3 -+ -+#define RTL8367C_REG_OAM_PARSER_CTRL1 0x0a71 -+#define RTL8367C_PORT10_PARACT_OFFSET 4 -+#define RTL8367C_PORT10_PARACT_MASK 0x30 -+#define RTL8367C_PORT9_PARACT_OFFSET 2 -+#define RTL8367C_PORT9_PARACT_MASK 0xC -+#define RTL8367C_PORT8_PARACT_OFFSET 0 -+#define RTL8367C_PORT8_PARACT_MASK 0x3 -+ -+#define RTL8367C_REG_OAM_MULTIPLEXER_CTRL0 0x0a72 -+#define RTL8367C_PORT7_MULACT_OFFSET 14 -+#define RTL8367C_PORT7_MULACT_MASK 0xC000 -+#define RTL8367C_PORT6_MULACT_OFFSET 12 -+#define RTL8367C_PORT6_MULACT_MASK 0x3000 -+#define RTL8367C_PORT5_MULACT_OFFSET 10 -+#define RTL8367C_PORT5_MULACT_MASK 0xC00 -+#define RTL8367C_PORT4_MULACT_OFFSET 8 -+#define RTL8367C_PORT4_MULACT_MASK 0x300 -+#define RTL8367C_PORT3_MULACT_OFFSET 6 -+#define RTL8367C_PORT3_MULACT_MASK 0xC0 -+#define RTL8367C_PORT2_MULACT_OFFSET 4 -+#define RTL8367C_PORT2_MULACT_MASK 0x30 -+#define RTL8367C_PORT1_MULACT_OFFSET 2 -+#define RTL8367C_PORT1_MULACT_MASK 0xC -+#define RTL8367C_PORT0_MULACT_OFFSET 0 -+#define RTL8367C_PORT0_MULACT_MASK 0x3 -+ -+#define RTL8367C_REG_OAM_MULTIPLEXER_CTRL1 0x0a73 -+#define RTL8367C_PORT10_MULACT_OFFSET 4 -+#define RTL8367C_PORT10_MULACT_MASK 0x30 -+#define RTL8367C_PORT9_MULACT_OFFSET 2 -+#define RTL8367C_PORT9_MULACT_MASK 0xC -+#define RTL8367C_PORT8_MULACT_OFFSET 0 -+#define RTL8367C_PORT8_MULACT_MASK 0x3 -+ -+#define RTL8367C_REG_OAM_CTRL 0x0a74 -+#define RTL8367C_OAM_CTRL_OFFSET 0 -+#define RTL8367C_OAM_CTRL_MASK 0x1 -+ -+#define RTL8367C_REG_DOT1X_PORT_ENABLE 0x0a80 -+#define RTL8367C_DOT1X_PORT_ENABLE_OFFSET 0 -+#define RTL8367C_DOT1X_PORT_ENABLE_MASK 0x7FF -+ -+#define RTL8367C_REG_DOT1X_MAC_ENABLE 0x0a81 -+#define RTL8367C_DOT1X_MAC_ENABLE_OFFSET 0 -+#define RTL8367C_DOT1X_MAC_ENABLE_MASK 0x7FF -+ -+#define RTL8367C_REG_DOT1X_PORT_AUTH 0x0a82 -+#define RTL8367C_DOT1X_PORT_AUTH_OFFSET 0 -+#define RTL8367C_DOT1X_PORT_AUTH_MASK 0x7FF -+ -+#define RTL8367C_REG_DOT1X_PORT_OPDIR 0x0a83 -+#define RTL8367C_DOT1X_PORT_OPDIR_OFFSET 0 -+#define RTL8367C_DOT1X_PORT_OPDIR_MASK 0x7FF -+ -+#define RTL8367C_REG_DOT1X_UNAUTH_ACT_W0 0x0a84 -+#define RTL8367C_DOT1X_PORT7_UNAUTHBH_OFFSET 14 -+#define RTL8367C_DOT1X_PORT7_UNAUTHBH_MASK 0xC000 -+#define RTL8367C_DOT1X_PORT6_UNAUTHBH_OFFSET 12 -+#define RTL8367C_DOT1X_PORT6_UNAUTHBH_MASK 0x3000 -+#define RTL8367C_DOT1X_PORT5_UNAUTHBH_OFFSET 10 -+#define RTL8367C_DOT1X_PORT5_UNAUTHBH_MASK 0xC00 -+#define RTL8367C_DOT1X_PORT4_UNAUTHBH_OFFSET 8 -+#define RTL8367C_DOT1X_PORT4_UNAUTHBH_MASK 0x300 -+#define RTL8367C_DOT1X_PORT3_UNAUTHBH_OFFSET 6 -+#define RTL8367C_DOT1X_PORT3_UNAUTHBH_MASK 0xC0 -+#define RTL8367C_DOT1X_PORT2_UNAUTHBH_OFFSET 4 -+#define RTL8367C_DOT1X_PORT2_UNAUTHBH_MASK 0x30 -+#define RTL8367C_DOT1X_PORT1_UNAUTHBH_OFFSET 2 -+#define RTL8367C_DOT1X_PORT1_UNAUTHBH_MASK 0xC -+#define RTL8367C_DOT1X_PORT0_UNAUTHBH_OFFSET 0 -+#define RTL8367C_DOT1X_PORT0_UNAUTHBH_MASK 0x3 -+ -+#define RTL8367C_REG_DOT1X_UNAUTH_ACT_W1 0x0a85 -+#define RTL8367C_DOT1X_PORT10_UNAUTHBH_OFFSET 4 -+#define RTL8367C_DOT1X_PORT10_UNAUTHBH_MASK 0x30 -+#define RTL8367C_DOT1X_PORT9_UNAUTHBH_OFFSET 2 -+#define RTL8367C_DOT1X_PORT9_UNAUTHBH_MASK 0xC -+#define RTL8367C_DOT1X_PORT8_UNAUTHBH_OFFSET 0 -+#define RTL8367C_DOT1X_PORT8_UNAUTHBH_MASK 0x3 -+ -+#define RTL8367C_REG_DOT1X_CFG 0x0a86 -+#define RTL8367C_DOT1X_GVOPDIR_OFFSET 6 -+#define RTL8367C_DOT1X_GVOPDIR_MASK 0x40 -+#define RTL8367C_DOT1X_MAC_OPDIR_OFFSET 5 -+#define RTL8367C_DOT1X_MAC_OPDIR_MASK 0x20 -+#define RTL8367C_DOT1X_GVIDX_OFFSET 0 -+#define RTL8367C_DOT1X_GVIDX_MASK 0x1F -+ -+#define RTL8367C_REG_L2_LRN_CNT_CTRL0 0x0a87 -+#define RTL8367C_L2_LRN_CNT_CTRL0_OFFSET 0 -+#define RTL8367C_L2_LRN_CNT_CTRL0_MASK 0x1FFF -+ -+#define RTL8367C_REG_L2_LRN_CNT_CTRL1 0x0a88 -+#define RTL8367C_L2_LRN_CNT_CTRL1_OFFSET 0 -+#define RTL8367C_L2_LRN_CNT_CTRL1_MASK 0x1FFF -+ -+#define RTL8367C_REG_L2_LRN_CNT_CTRL2 0x0a89 -+#define RTL8367C_L2_LRN_CNT_CTRL2_OFFSET 0 -+#define RTL8367C_L2_LRN_CNT_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_L2_LRN_CNT_CTRL3 0x0a8a -+#define RTL8367C_L2_LRN_CNT_CTRL3_OFFSET 0 -+#define RTL8367C_L2_LRN_CNT_CTRL3_MASK 0x1FFF -+ -+#define RTL8367C_REG_L2_LRN_CNT_CTRL4 0x0a8b -+#define RTL8367C_L2_LRN_CNT_CTRL4_OFFSET 0 -+#define RTL8367C_L2_LRN_CNT_CTRL4_MASK 0x1FFF -+ -+#define RTL8367C_REG_L2_LRN_CNT_CTRL5 0x0a8c -+#define RTL8367C_L2_LRN_CNT_CTRL5_OFFSET 0 -+#define RTL8367C_L2_LRN_CNT_CTRL5_MASK 0x1FFF -+ -+#define RTL8367C_REG_L2_LRN_CNT_CTRL6 0x0a8d -+#define RTL8367C_L2_LRN_CNT_CTRL6_OFFSET 0 -+#define RTL8367C_L2_LRN_CNT_CTRL6_MASK 0x1FFF -+ -+#define RTL8367C_REG_L2_LRN_CNT_CTRL7 0x0a8e -+#define RTL8367C_L2_LRN_CNT_CTRL7_OFFSET 0 -+#define RTL8367C_L2_LRN_CNT_CTRL7_MASK 0x1FFF -+ -+#define RTL8367C_REG_L2_LRN_CNT_CTRL8 0x0a8f -+#define RTL8367C_L2_LRN_CNT_CTRL8_OFFSET 0 -+#define RTL8367C_L2_LRN_CNT_CTRL8_MASK 0x1FFF -+ -+#define RTL8367C_REG_L2_LRN_CNT_CTRL9 0x0a90 -+#define RTL8367C_L2_LRN_CNT_CTRL9_OFFSET 0 -+#define RTL8367C_L2_LRN_CNT_CTRL9_MASK 0x1FFF -+ -+#define RTL8367C_REG_L2_LRN_CNT_CTRL10 0x0a92 -+#define RTL8367C_L2_LRN_CNT_CTRL10_OFFSET 0 -+#define RTL8367C_L2_LRN_CNT_CTRL10_MASK 0x1FFF -+ -+#define RTL8367C_REG_LUT_LRN_UNDER_STATUS 0x0a91 -+#define RTL8367C_LUT_LRN_UNDER_STATUS_OFFSET 0 -+#define RTL8367C_LUT_LRN_UNDER_STATUS_MASK 0x7FF -+ -+#define RTL8367C_REG_L2_SA_MOVING_FORBID 0x0aa0 -+#define RTL8367C_L2_SA_MOVING_FORBID_OFFSET 0 -+#define RTL8367C_L2_SA_MOVING_FORBID_MASK 0x7FF -+ -+#define RTL8367C_REG_DRPORT_LEARN_CTRL 0x0aa1 -+#define RTL8367C_FORBID1_OFFSET 1 -+#define RTL8367C_FORBID1_MASK 0x2 -+#define RTL8367C_FORBID0_OFFSET 0 -+#define RTL8367C_FORBID0_MASK 0x1 -+ -+#define RTL8367C_REG_L2_DUMMY02 0x0aa2 -+ -+#define RTL8367C_REG_L2_DUMMY03 0x0aa3 -+ -+#define RTL8367C_REG_L2_DUMMY04 0x0aa4 -+ -+#define RTL8367C_REG_L2_DUMMY05 0x0aa5 -+ -+#define RTL8367C_REG_L2_DUMMY06 0x0aa6 -+ -+#define RTL8367C_REG_L2_DUMMY07 0x0aa7 -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_00 0x0AC0 -+#define RTL8367C_IPMC_GROUP_PMSK_00_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_00_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_01 0x0AC1 -+#define RTL8367C_IPMC_GROUP_PMSK_01_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_01_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_02 0x0AC2 -+#define RTL8367C_IPMC_GROUP_PMSK_02_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_02_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_03 0x0AC3 -+#define RTL8367C_IPMC_GROUP_PMSK_03_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_03_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_04 0x0AC4 -+#define RTL8367C_IPMC_GROUP_PMSK_04_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_04_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_05 0x0AC5 -+#define RTL8367C_IPMC_GROUP_PMSK_05_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_05_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_06 0x0AC6 -+#define RTL8367C_IPMC_GROUP_PMSK_06_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_06_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_07 0x0AC7 -+#define RTL8367C_IPMC_GROUP_PMSK_07_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_07_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_08 0x0AC8 -+#define RTL8367C_IPMC_GROUP_PMSK_08_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_08_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_09 0x0AC9 -+#define RTL8367C_IPMC_GROUP_PMSK_09_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_09_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_10 0x0ACA -+#define RTL8367C_IPMC_GROUP_PMSK_10_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_10_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_11 0x0ACB -+#define RTL8367C_IPMC_GROUP_PMSK_11_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_11_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_12 0x0ACC -+#define RTL8367C_IPMC_GROUP_PMSK_12_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_12_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_13 0x0ACD -+#define RTL8367C_IPMC_GROUP_PMSK_13_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_13_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_14 0x0ACE -+#define RTL8367C_IPMC_GROUP_PMSK_14_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_14_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_15 0x0ACF -+#define RTL8367C_IPMC_GROUP_PMSK_15_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_15_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_16 0x0AD0 -+#define RTL8367C_IPMC_GROUP_PMSK_16_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_16_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_17 0x0AD1 -+#define RTL8367C_IPMC_GROUP_PMSK_17_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_17_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_18 0x0AD2 -+#define RTL8367C_IPMC_GROUP_PMSK_18_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_18_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_19 0x0AD3 -+#define RTL8367C_IPMC_GROUP_PMSK_19_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_19_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_20 0x0AD4 -+#define RTL8367C_IPMC_GROUP_PMSK_20_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_20_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_21 0x0AD5 -+#define RTL8367C_IPMC_GROUP_PMSK_21_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_21_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_22 0x0AD6 -+#define RTL8367C_IPMC_GROUP_PMSK_22_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_22_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_23 0x0AD7 -+#define RTL8367C_IPMC_GROUP_PMSK_23_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_23_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_24 0x0AD8 -+#define RTL8367C_IPMC_GROUP_PMSK_24_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_24_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_25 0x0AD9 -+#define RTL8367C_IPMC_GROUP_PMSK_25_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_25_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_26 0x0ADA -+#define RTL8367C_IPMC_GROUP_PMSK_26_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_26_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_27 0x0ADB -+#define RTL8367C_IPMC_GROUP_PMSK_27_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_27_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_28 0x0ADC -+#define RTL8367C_IPMC_GROUP_PMSK_28_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_28_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_29 0x0ADD -+#define RTL8367C_IPMC_GROUP_PMSK_29_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_29_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_30 0x0ADE -+#define RTL8367C_IPMC_GROUP_PMSK_30_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_30_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_31 0x0ADF -+#define RTL8367C_IPMC_GROUP_PMSK_31_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_31_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_32 0x0AE0 -+#define RTL8367C_IPMC_GROUP_PMSK_32_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_32_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_33 0x0AE1 -+#define RTL8367C_IPMC_GROUP_PMSK_33_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_33_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_34 0x0AE2 -+#define RTL8367C_IPMC_GROUP_PMSK_34_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_34_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_35 0x0AE3 -+#define RTL8367C_IPMC_GROUP_PMSK_35_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_35_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_36 0x0AE4 -+#define RTL8367C_IPMC_GROUP_PMSK_36_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_36_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_37 0x0AE5 -+#define RTL8367C_IPMC_GROUP_PMSK_37_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_37_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_38 0x0AE6 -+#define RTL8367C_IPMC_GROUP_PMSK_38_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_38_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_39 0x0AE7 -+#define RTL8367C_IPMC_GROUP_PMSK_39_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_39_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_40 0x0AE8 -+#define RTL8367C_IPMC_GROUP_PMSK_40_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_40_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_41 0x0AE9 -+#define RTL8367C_IPMC_GROUP_PMSK_41_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_41_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_42 0x0AEA -+#define RTL8367C_IPMC_GROUP_PMSK_42_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_42_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_43 0x0AEB -+#define RTL8367C_IPMC_GROUP_PMSK_43_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_43_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_44 0x0AEC -+#define RTL8367C_IPMC_GROUP_PMSK_44_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_44_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_45 0x0AED -+#define RTL8367C_IPMC_GROUP_PMSK_45_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_45_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_46 0x0AEE -+#define RTL8367C_IPMC_GROUP_PMSK_46_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_46_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_47 0x0AEF -+#define RTL8367C_IPMC_GROUP_PMSK_47_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_47_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_48 0x0AF0 -+#define RTL8367C_IPMC_GROUP_PMSK_48_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_48_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_49 0x0AF1 -+#define RTL8367C_IPMC_GROUP_PMSK_49_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_49_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_50 0x0AF2 -+#define RTL8367C_IPMC_GROUP_PMSK_50_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_50_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_51 0x0AF3 -+#define RTL8367C_IPMC_GROUP_PMSK_51_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_51_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_52 0x0AF4 -+#define RTL8367C_IPMC_GROUP_PMSK_52_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_52_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_53 0x0AF5 -+#define RTL8367C_IPMC_GROUP_PMSK_53_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_53_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_54 0x0AF6 -+#define RTL8367C_IPMC_GROUP_PMSK_54_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_54_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_55 0x0AF7 -+#define RTL8367C_IPMC_GROUP_PMSK_55_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_55_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_56 0x0AF8 -+#define RTL8367C_IPMC_GROUP_PMSK_56_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_56_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_57 0x0AF9 -+#define RTL8367C_IPMC_GROUP_PMSK_57_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_57_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_58 0x0AFA -+#define RTL8367C_IPMC_GROUP_PMSK_58_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_58_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_59 0x0AFB -+#define RTL8367C_IPMC_GROUP_PMSK_59_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_59_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_60 0x0AFC -+#define RTL8367C_IPMC_GROUP_PMSK_60_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_60_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_61 0x0AFD -+#define RTL8367C_IPMC_GROUP_PMSK_61_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_61_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_62 0x0AFE -+#define RTL8367C_IPMC_GROUP_PMSK_62_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_62_MASK 0x7FF -+ -+#define RTL8367C_REG_IPMC_GROUP_PMSK_63 0x0AFF -+#define RTL8367C_IPMC_GROUP_PMSK_63_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_PMSK_63_MASK 0x7FF -+ -+/* (16'h0b00)mltvlan_reg */ -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY0_CTRL0 0x0b00 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY0_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY0_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY0_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY0_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY0_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY0_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY0_CTRL1 0x0b01 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY0_CTRL2 0x0b02 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY0_CTRL3 0x0b03 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY0_CTRL4 0x0b04 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY1_CTRL0 0x0b05 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY1_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY1_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY1_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY1_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY1_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY1_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY1_CTRL1 0x0b06 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY1_CTRL2 0x0b07 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY1_CTRL3 0x0b08 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY1_CTRL4 0x0b09 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY2_CTRL0 0x0b0a -+#define RTL8367C_SVLAN_MCAST2S_ENTRY2_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY2_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY2_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY2_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY2_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY2_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY2_CTRL1 0x0b0b -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY2_CTRL2 0x0b0c -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY2_CTRL3 0x0b0d -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY2_CTRL4 0x0b0e -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY3_CTRL0 0x0b0f -+#define RTL8367C_SVLAN_MCAST2S_ENTRY3_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY3_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY3_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY3_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY3_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY3_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY3_CTRL1 0x0b10 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY3_CTRL2 0x0b11 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY3_CTRL3 0x0b12 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY3_CTRL4 0x0b13 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY4_CTRL0 0x0b14 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY4_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY4_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY4_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY4_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY4_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY4_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY4_CTRL1 0x0b15 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY4_CTRL2 0x0b16 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY4_CTRL3 0x0b17 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY4_CTRL4 0x0b18 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY5_CTRL0 0x0b19 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY5_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY5_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY5_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY5_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY5_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY5_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY5_CTRL1 0x0b1a -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY5_CTRL2 0x0b1b -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY5_CTRL3 0x0b1c -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY5_CTRL4 0x0b1d -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY6_CTRL0 0x0b1e -+#define RTL8367C_SVLAN_MCAST2S_ENTRY6_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY6_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY6_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY6_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY6_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY6_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY6_CTRL1 0x0b1f -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY6_CTRL2 0x0b20 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY6_CTRL3 0x0b21 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY6_CTRL4 0x0b22 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY7_CTRL0 0x0b23 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY7_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY7_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY7_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY7_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY7_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY7_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY7_CTRL1 0x0b24 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY7_CTRL2 0x0b25 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY7_CTRL3 0x0b26 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY7_CTRL4 0x0b27 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY8_CTRL0 0x0b28 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY8_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY8_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY8_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY8_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY8_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY8_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY8_CTRL1 0x0b29 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY8_CTRL2 0x0b2a -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY8_CTRL3 0x0b2b -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY8_CTRL4 0x0b2c -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY9_CTRL0 0x0b2d -+#define RTL8367C_SVLAN_MCAST2S_ENTRY9_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY9_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY9_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY9_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY9_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY9_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY9_CTRL1 0x0b2e -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY9_CTRL2 0x0b2f -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY9_CTRL3 0x0b30 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY9_CTRL4 0x0b31 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY10_CTRL0 0x0b32 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY10_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY10_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY10_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY10_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY10_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY10_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY10_CTRL1 0x0b33 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY10_CTRL2 0x0b34 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY10_CTRL3 0x0b35 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY10_CTRL4 0x0b36 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY11_CTRL0 0x0b37 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY11_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY11_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY11_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY11_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY11_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY11_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY11_CTRL1 0x0b38 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY11_CTRL2 0x0b39 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY11_CTRL3 0x0b3a -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY11_CTRL4 0x0b3b -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY12_CTRL0 0x0b3c -+#define RTL8367C_SVLAN_MCAST2S_ENTRY12_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY12_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY12_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY12_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY12_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY12_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY12_CTRL1 0x0b3d -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY12_CTRL2 0x0b3e -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY12_CTRL3 0x0b3f -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY12_CTRL4 0x0b40 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY13_CTRL0 0x0b41 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY13_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY13_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY13_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY13_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY13_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY13_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY13_CTRL1 0x0b42 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY13_CTRL2 0x0b43 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY13_CTRL3 0x0b44 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY13_CTRL4 0x0b45 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY14_CTRL0 0x0b46 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY14_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY14_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY14_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY14_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY14_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY14_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY14_CTRL1 0x0b47 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY14_CTRL2 0x0b48 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY14_CTRL3 0x0b49 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY14_CTRL4 0x0b4a -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY15_CTRL0 0x0b4b -+#define RTL8367C_SVLAN_MCAST2S_ENTRY15_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY15_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY15_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY15_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY15_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY15_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY15_CTRL1 0x0b4c -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY15_CTRL2 0x0b4d -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY15_CTRL3 0x0b4e -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY15_CTRL4 0x0b4f -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY16_CTRL0 0x0b50 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY16_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY16_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY16_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY16_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY16_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY16_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY16_CTRL1 0x0b51 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY16_CTRL2 0x0b52 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY16_CTRL3 0x0b53 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY16_CTRL4 0x0b54 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY17_CTRL0 0x0b55 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY17_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY17_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY17_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY17_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY17_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY17_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY17_CTRL1 0x0b56 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY17_CTRL2 0x0b57 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY17_CTRL3 0x0b58 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY17_CTRL4 0x0b59 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY18_CTRL0 0x0b5a -+#define RTL8367C_SVLAN_MCAST2S_ENTRY18_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY18_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY18_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY18_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY18_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY18_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY18_CTRL1 0x0b5b -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY18_CTRL2 0x0b5c -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY18_CTRL3 0x0b5d -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY18_CTRL4 0x0b5e -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY19_CTRL0 0x0b5f -+#define RTL8367C_SVLAN_MCAST2S_ENTRY19_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY19_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY19_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY19_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY19_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY19_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY19_CTRL1 0x0b60 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY19_CTRL2 0x0b61 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY19_CTRL3 0x0b62 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY19_CTRL4 0x0b63 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY20_CTRL0 0x0b64 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY20_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY20_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY20_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY20_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY20_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY20_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY20_CTRL1 0x0b65 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY20_CTRL2 0x0b66 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY20_CTRL3 0x0b67 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY20_CTRL4 0x0b68 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY21_CTRL0 0x0b69 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY21_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY21_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY21_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY21_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY21_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY21_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY21_CTRL1 0x0b6a -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY21_CTRL2 0x0b6b -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY21_CTRL3 0x0b6c -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY21_CTRL4 0x0b6d -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY22_CTRL0 0x0b6e -+#define RTL8367C_SVLAN_MCAST2S_ENTRY22_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY22_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY22_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY22_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY22_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY22_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY22_CTRL1 0x0b6f -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY22_CTRL2 0x0b70 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY22_CTRL3 0x0b71 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY22_CTRL4 0x0b72 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY23_CTRL0 0x0b73 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY23_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY23_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY23_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY23_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY23_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY23_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY23_CTRL1 0x0b74 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY23_CTRL2 0x0b75 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY23_CTRL3 0x0b76 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY23_CTRL4 0x0b77 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY24_CTRL0 0x0b78 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY24_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY24_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY24_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY24_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY24_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY24_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY24_CTRL1 0x0b79 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY24_CTRL2 0x0b7a -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY24_CTRL3 0x0b7b -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY24_CTRL4 0x0b7c -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY25_CTRL0 0x0b7d -+#define RTL8367C_SVLAN_MCAST2S_ENTRY25_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY25_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY25_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY25_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY25_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY25_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY25_CTRL1 0x0b7e -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY25_CTRL2 0x0b7f -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY25_CTRL3 0x0b80 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY25_CTRL4 0x0b81 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY26_CTRL0 0x0b82 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY26_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY26_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY26_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY26_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY26_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY26_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY26_CTRL1 0x0b83 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY26_CTRL2 0x0b84 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY26_CTRL3 0x0b85 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY26_CTRL4 0x0b86 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY27_CTRL0 0x0b87 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY27_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY27_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY27_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY27_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY27_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY27_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY27_CTRL1 0x0b88 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY27_CTRL2 0x0b89 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY27_CTRL3 0x0b8a -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY27_CTRL4 0x0b8b -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY28_CTRL0 0x0b8c -+#define RTL8367C_SVLAN_MCAST2S_ENTRY28_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY28_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY28_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY28_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY28_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY28_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY28_CTRL1 0x0b8d -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY28_CTRL2 0x0b8e -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY28_CTRL3 0x0b8f -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY28_CTRL4 0x0b90 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY29_CTRL0 0x0b91 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY29_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY29_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY29_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY29_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY29_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY29_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY29_CTRL1 0x0b92 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY29_CTRL2 0x0b93 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY29_CTRL3 0x0b94 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY29_CTRL4 0x0b95 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY30_CTRL0 0x0b96 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY30_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY30_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY30_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY30_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY30_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY30_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY30_CTRL1 0x0b97 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY30_CTRL2 0x0b98 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY30_CTRL3 0x0b99 -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY30_CTRL4 0x0b9a -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY31_CTRL0 0x0b9b -+#define RTL8367C_SVLAN_MCAST2S_ENTRY31_CTRL0_VALID_OFFSET 7 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY31_CTRL0_VALID_MASK 0x80 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY31_CTRL0_FORMAT_OFFSET 6 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY31_CTRL0_FORMAT_MASK 0x40 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY31_CTRL0_SVIDX_OFFSET 0 -+#define RTL8367C_SVLAN_MCAST2S_ENTRY31_CTRL0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY31_CTRL1 0x0b9c -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY31_CTRL2 0x0b9d -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY31_CTRL3 0x0b9e -+ -+#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY31_CTRL4 0x0b9f -+ -+#define RTL8367C_REG_MLTVLAN_DUMMY_0 0x0ba0 -+ -+#define RTL8367C_REG_MLTVLAN_DUMMY_1 0x0ba1 -+ -+#define RTL8367C_REG_MLTVLAN_DUMMY_2 0x0ba2 -+ -+#define RTL8367C_REG_MLTVLAN_DUMMY_3 0x0ba3 -+ -+#define RTL8367C_REG_MLTVLAN_DUMMY_4 0x0ba4 -+ -+#define RTL8367C_REG_MLTVLAN_DUMMY_5 0x0ba5 -+ -+#define RTL8367C_REG_MLTVLAN_DUMMY_6 0x0ba6 -+ -+#define RTL8367C_REG_MLTVLAN_DUMMY_7 0x0ba7 -+ -+/* (16'h0c00)svlan_reg */ -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG0_CTRL1 0x0c01 -+#define RTL8367C_SVLAN_MEMBERCFG0_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG0_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG0_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG0_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG0_CTRL2 0x0c02 -+#define RTL8367C_SVLAN_MEMBERCFG0_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG0_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG0_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG0_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG0_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG0_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG0_CTRL3 0x0c03 -+#define RTL8367C_SVLAN_MEMBERCFG0_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG0_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG0_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG0_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG0_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG0_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG1_CTRL1 0x0c04 -+#define RTL8367C_SVLAN_MEMBERCFG1_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG1_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG1_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG1_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG1_CTRL2 0x0c05 -+#define RTL8367C_SVLAN_MEMBERCFG1_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG1_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG1_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG1_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG1_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG1_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG1_CTRL3 0x0c06 -+#define RTL8367C_SVLAN_MEMBERCFG1_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG1_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG1_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG1_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG1_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG1_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG2_CTRL1 0x0c07 -+#define RTL8367C_SVLAN_MEMBERCFG2_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG2_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG2_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG2_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG2_CTRL2 0x0c08 -+#define RTL8367C_SVLAN_MEMBERCFG2_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG2_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG2_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG2_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG2_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG2_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG2_CTRL3 0x0c09 -+#define RTL8367C_SVLAN_MEMBERCFG2_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG2_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG2_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG2_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG2_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG2_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG3_CTRL1 0x0c0a -+#define RTL8367C_SVLAN_MEMBERCFG3_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG3_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG3_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG3_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG3_CTRL2 0x0c0b -+#define RTL8367C_SVLAN_MEMBERCFG3_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG3_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG3_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG3_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG3_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG3_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG3_CTRL3 0x0c0c -+#define RTL8367C_SVLAN_MEMBERCFG3_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG3_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG3_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG3_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG3_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG3_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG4_CTRL1 0x0c0d -+#define RTL8367C_SVLAN_MEMBERCFG4_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG4_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG4_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG4_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG4_CTRL2 0x0c0e -+#define RTL8367C_SVLAN_MEMBERCFG4_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG4_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG4_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG4_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG4_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG4_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG4_CTRL3 0x0c0f -+#define RTL8367C_SVLAN_MEMBERCFG4_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG4_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG4_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG4_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG4_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG4_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG5_CTRL1 0x0c10 -+#define RTL8367C_SVLAN_MEMBERCFG5_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG5_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG5_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG5_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG5_CTRL2 0x0c11 -+#define RTL8367C_SVLAN_MEMBERCFG5_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG5_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG5_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG5_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG5_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG5_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG5_CTRL3 0x0c12 -+#define RTL8367C_SVLAN_MEMBERCFG5_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG5_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG5_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG5_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG5_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG5_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG6_CTRL1 0x0c13 -+#define RTL8367C_SVLAN_MEMBERCFG6_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG6_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG6_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG6_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG6_CTRL2 0x0c14 -+#define RTL8367C_SVLAN_MEMBERCFG6_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG6_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG6_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG6_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG6_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG6_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG6_CTRL3 0x0c15 -+#define RTL8367C_SVLAN_MEMBERCFG6_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG6_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG6_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG6_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG6_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG6_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG7_CTRL1 0x0c16 -+#define RTL8367C_SVLAN_MEMBERCFG7_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG7_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG7_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG7_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG7_CTRL2 0x0c17 -+#define RTL8367C_SVLAN_MEMBERCFG7_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG7_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG7_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG7_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG7_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG7_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG7_CTRL3 0x0c18 -+#define RTL8367C_SVLAN_MEMBERCFG7_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG7_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG7_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG7_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG7_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG7_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG8_CTRL1 0x0c19 -+#define RTL8367C_SVLAN_MEMBERCFG8_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG8_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG8_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG8_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG8_CTRL2 0x0c1a -+#define RTL8367C_SVLAN_MEMBERCFG8_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG8_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG8_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG8_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG8_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG8_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG8_CTRL3 0x0c1b -+#define RTL8367C_SVLAN_MEMBERCFG8_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG8_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG8_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG8_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG8_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG8_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG9_CTRL1 0x0c1c -+#define RTL8367C_SVLAN_MEMBERCFG9_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG9_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG9_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG9_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG9_CTRL2 0x0c1d -+#define RTL8367C_SVLAN_MEMBERCFG9_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG9_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG9_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG9_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG9_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG9_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG9_CTRL3 0x0c1e -+#define RTL8367C_SVLAN_MEMBERCFG9_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG9_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG9_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG9_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG9_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG9_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG10_CTRL1 0x0c1f -+#define RTL8367C_SVLAN_MEMBERCFG10_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG10_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG10_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG10_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG10_CTRL2 0x0c20 -+#define RTL8367C_SVLAN_MEMBERCFG10_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG10_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG10_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG10_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG10_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG10_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG10_CTRL3 0x0c21 -+#define RTL8367C_SVLAN_MEMBERCFG10_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG10_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG10_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG10_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG10_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG10_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG11_CTRL1 0x0c22 -+#define RTL8367C_SVLAN_MEMBERCFG11_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG11_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG11_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG11_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG11_CTRL2 0x0c23 -+#define RTL8367C_SVLAN_MEMBERCFG11_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG11_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG11_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG11_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG11_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG11_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG11_CTRL3 0x0c24 -+#define RTL8367C_SVLAN_MEMBERCFG11_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG11_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG11_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG11_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG11_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG11_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG12_CTRL1 0x0c25 -+#define RTL8367C_SVLAN_MEMBERCFG12_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG12_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG12_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG12_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG12_CTRL2 0x0c26 -+#define RTL8367C_SVLAN_MEMBERCFG12_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG12_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG12_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG12_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG12_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG12_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG12_CTRL3 0x0c27 -+#define RTL8367C_SVLAN_MEMBERCFG12_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG12_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG12_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG12_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG12_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG12_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG13_CTRL1 0x0c28 -+#define RTL8367C_SVLAN_MEMBERCFG13_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG13_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG13_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG13_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG13_CTRL2 0x0c29 -+#define RTL8367C_SVLAN_MEMBERCFG13_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG13_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG13_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG13_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG13_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG13_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG13_CTRL3 0x0c2a -+#define RTL8367C_SVLAN_MEMBERCFG13_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG13_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG13_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG13_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG13_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG13_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG14_CTRL1 0x0c2b -+#define RTL8367C_SVLAN_MEMBERCFG14_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG14_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG14_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG14_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG14_CTRL2 0x0c2c -+#define RTL8367C_SVLAN_MEMBERCFG14_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG14_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG14_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG14_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG14_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG14_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG14_CTRL3 0x0c2d -+#define RTL8367C_SVLAN_MEMBERCFG14_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG14_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG14_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG14_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG14_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG14_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG15_CTRL1 0x0c2e -+#define RTL8367C_SVLAN_MEMBERCFG15_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG15_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG15_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG15_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG15_CTRL2 0x0c2f -+#define RTL8367C_SVLAN_MEMBERCFG15_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG15_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG15_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG15_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG15_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG15_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG15_CTRL3 0x0c30 -+#define RTL8367C_SVLAN_MEMBERCFG15_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG15_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG15_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG15_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG15_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG15_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG16_CTRL1 0x0c31 -+#define RTL8367C_SVLAN_MEMBERCFG16_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG16_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG16_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG16_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG16_CTRL2 0x0c32 -+#define RTL8367C_SVLAN_MEMBERCFG16_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG16_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG16_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG16_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG16_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG16_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG16_CTRL3 0x0c33 -+#define RTL8367C_SVLAN_MEMBERCFG16_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG16_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG16_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG16_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG16_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG16_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG17_CTRL1 0x0c34 -+#define RTL8367C_SVLAN_MEMBERCFG17_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG17_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG17_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG17_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG17_CTRL2 0x0c35 -+#define RTL8367C_SVLAN_MEMBERCFG17_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG17_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG17_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG17_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG17_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG17_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG17_CTRL3 0x0c36 -+#define RTL8367C_SVLAN_MEMBERCFG17_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG17_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG17_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG17_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG17_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG17_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG18_CTRL1 0x0c37 -+#define RTL8367C_SVLAN_MEMBERCFG18_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG18_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG18_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG18_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG18_CTRL2 0x0c38 -+#define RTL8367C_SVLAN_MEMBERCFG18_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG18_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG18_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG18_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG18_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG18_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG18_CTRL3 0x0c39 -+#define RTL8367C_SVLAN_MEMBERCFG18_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG18_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG18_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG18_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG18_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG18_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG19_CTRL1 0x0c3a -+#define RTL8367C_SVLAN_MEMBERCFG19_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG19_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG19_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG19_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG19_CTRL2 0x0c3b -+#define RTL8367C_SVLAN_MEMBERCFG19_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG19_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG19_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG19_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG19_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG19_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG19_CTRL3 0x0c3c -+#define RTL8367C_SVLAN_MEMBERCFG19_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG19_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG19_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG19_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG19_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG19_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG20_CTRL1 0x0c3d -+#define RTL8367C_SVLAN_MEMBERCFG20_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG20_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG20_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG20_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG20_CTRL2 0x0c3e -+#define RTL8367C_SVLAN_MEMBERCFG20_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG20_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG20_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG20_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG20_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG20_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG20_CTRL3 0x0c3f -+#define RTL8367C_SVLAN_MEMBERCFG20_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG20_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG20_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG20_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG20_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG20_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG21_CTRL1 0x0c40 -+#define RTL8367C_SVLAN_MEMBERCFG21_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG21_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG21_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG21_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG21_CTRL2 0x0c41 -+#define RTL8367C_SVLAN_MEMBERCFG21_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG21_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG21_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG21_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG21_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG21_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG21_CTRL3 0x0c42 -+#define RTL8367C_SVLAN_MEMBERCFG21_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG21_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG21_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG21_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG21_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG21_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG22_CTRL1 0x0c43 -+#define RTL8367C_SVLAN_MEMBERCFG22_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG22_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG22_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG22_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG22_CTRL2 0x0c44 -+#define RTL8367C_SVLAN_MEMBERCFG22_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG22_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG22_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG22_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG22_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG22_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG22_CTRL3 0x0c45 -+#define RTL8367C_SVLAN_MEMBERCFG22_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG22_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG22_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG22_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG22_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG22_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG23_CTRL1 0x0c46 -+#define RTL8367C_SVLAN_MEMBERCFG23_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG23_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG23_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG23_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG23_CTRL2 0x0c47 -+#define RTL8367C_SVLAN_MEMBERCFG23_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG23_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG23_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG23_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG23_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG23_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG23_CTRL3 0x0c48 -+#define RTL8367C_SVLAN_MEMBERCFG23_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG23_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG23_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG23_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG23_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG23_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG24_CTRL1 0x0c49 -+#define RTL8367C_SVLAN_MEMBERCFG24_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG24_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG24_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG24_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG24_CTRL2 0x0c4a -+#define RTL8367C_SVLAN_MEMBERCFG24_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG24_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG24_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG24_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG24_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG24_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG24_CTRL3 0x0c4b -+#define RTL8367C_SVLAN_MEMBERCFG24_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG24_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG24_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG24_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG24_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG24_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG25_CTRL1 0x0c4c -+#define RTL8367C_SVLAN_MEMBERCFG25_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG25_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG25_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG25_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG25_CTRL2 0x0c4d -+#define RTL8367C_SVLAN_MEMBERCFG25_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG25_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG25_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG25_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG25_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG25_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG25_CTRL3 0x0c4e -+#define RTL8367C_SVLAN_MEMBERCFG25_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG25_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG25_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG25_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG25_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG25_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG26_CTRL1 0x0c4f -+#define RTL8367C_SVLAN_MEMBERCFG26_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG26_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG26_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG26_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG26_CTRL2 0x0c50 -+#define RTL8367C_SVLAN_MEMBERCFG26_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG26_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG26_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG26_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG26_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG26_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG26_CTRL3 0x0c51 -+#define RTL8367C_SVLAN_MEMBERCFG26_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG26_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG26_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG26_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG26_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG26_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG27_CTRL1 0x0c52 -+#define RTL8367C_SVLAN_MEMBERCFG27_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG27_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG27_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG27_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG27_CTRL2 0x0c53 -+#define RTL8367C_SVLAN_MEMBERCFG27_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG27_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG27_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG27_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG27_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG27_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG27_CTRL3 0x0c54 -+#define RTL8367C_SVLAN_MEMBERCFG27_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG27_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG27_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG27_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG27_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG27_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG28_CTRL1 0x0c55 -+#define RTL8367C_SVLAN_MEMBERCFG28_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG28_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG28_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG28_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG28_CTRL2 0x0c56 -+#define RTL8367C_SVLAN_MEMBERCFG28_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG28_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG28_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG28_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG28_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG28_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG28_CTRL3 0x0c57 -+#define RTL8367C_SVLAN_MEMBERCFG28_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG28_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG28_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG28_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG28_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG28_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG29_CTRL1 0x0c58 -+#define RTL8367C_SVLAN_MEMBERCFG29_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG29_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG29_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG29_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG29_CTRL2 0x0c59 -+#define RTL8367C_SVLAN_MEMBERCFG29_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG29_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG29_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG29_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG29_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG29_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG29_CTRL3 0x0c5a -+#define RTL8367C_SVLAN_MEMBERCFG29_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG29_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG29_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG29_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG29_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG29_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG30_CTRL1 0x0c5b -+#define RTL8367C_SVLAN_MEMBERCFG30_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG30_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG30_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG30_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG30_CTRL2 0x0c5c -+#define RTL8367C_SVLAN_MEMBERCFG30_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG30_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG30_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG30_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG30_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG30_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG30_CTRL3 0x0c5d -+#define RTL8367C_SVLAN_MEMBERCFG30_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG30_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG30_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG30_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG30_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG30_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG31_CTRL1 0x0c5e -+#define RTL8367C_SVLAN_MEMBERCFG31_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG31_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG31_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG31_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG31_CTRL2 0x0c5f -+#define RTL8367C_SVLAN_MEMBERCFG31_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG31_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG31_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG31_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG31_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG31_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG31_CTRL3 0x0c60 -+#define RTL8367C_SVLAN_MEMBERCFG31_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG31_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG31_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG31_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG31_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG31_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG32_CTRL1 0x0c61 -+#define RTL8367C_SVLAN_MEMBERCFG32_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG32_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG32_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG32_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG32_CTRL2 0x0c62 -+#define RTL8367C_SVLAN_MEMBERCFG32_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG32_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG32_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG32_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG32_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG32_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG32_CTRL3 0x0c63 -+#define RTL8367C_SVLAN_MEMBERCFG32_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG32_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG32_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG32_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG32_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG32_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG33_CTRL1 0x0c64 -+#define RTL8367C_SVLAN_MEMBERCFG33_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG33_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG33_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG33_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG33_CTRL2 0x0c65 -+#define RTL8367C_SVLAN_MEMBERCFG33_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG33_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG33_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG33_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG33_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG33_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG33_CTRL3 0x0c66 -+#define RTL8367C_SVLAN_MEMBERCFG33_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG33_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG33_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG33_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG33_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG33_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG34_CTRL1 0x0c67 -+#define RTL8367C_SVLAN_MEMBERCFG34_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG34_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG34_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG34_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG34_CTRL2 0x0c68 -+#define RTL8367C_SVLAN_MEMBERCFG34_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG34_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG34_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG34_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG34_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG34_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG34_CTRL3 0x0c69 -+#define RTL8367C_SVLAN_MEMBERCFG34_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG34_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG34_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG34_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG34_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG34_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG35_CTRL1 0x0c6a -+#define RTL8367C_SVLAN_MEMBERCFG35_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG35_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG35_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG35_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG35_CTRL2 0x0c6b -+#define RTL8367C_SVLAN_MEMBERCFG35_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG35_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG35_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG35_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG35_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG35_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG35_CTRL3 0x0c6c -+#define RTL8367C_SVLAN_MEMBERCFG35_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG35_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG35_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG35_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG35_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG35_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG36_CTRL1 0x0c6d -+#define RTL8367C_SVLAN_MEMBERCFG36_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG36_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG36_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG36_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG36_CTRL2 0x0c6e -+#define RTL8367C_SVLAN_MEMBERCFG36_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG36_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG36_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG36_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG36_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG36_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG36_CTRL3 0x0c6f -+#define RTL8367C_SVLAN_MEMBERCFG36_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG36_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG36_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG36_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG36_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG36_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG37_CTRL1 0x0c70 -+#define RTL8367C_SVLAN_MEMBERCFG37_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG37_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG37_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG37_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG37_CTRL2 0x0c71 -+#define RTL8367C_SVLAN_MEMBERCFG37_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG37_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG37_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG37_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG37_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG37_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG37_CTRL3 0x0c72 -+#define RTL8367C_SVLAN_MEMBERCFG37_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG37_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG37_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG37_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG37_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG37_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG38_CTRL1 0x0c73 -+#define RTL8367C_SVLAN_MEMBERCFG38_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG38_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG38_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG38_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG38_CTRL2 0x0c74 -+#define RTL8367C_SVLAN_MEMBERCFG38_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG38_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG38_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG38_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG38_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG38_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG38_CTRL3 0x0c75 -+#define RTL8367C_SVLAN_MEMBERCFG38_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG38_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG38_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG38_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG38_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG38_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG39_CTRL1 0x0c76 -+#define RTL8367C_SVLAN_MEMBERCFG39_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG39_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG39_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG39_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG39_CTRL2 0x0c77 -+#define RTL8367C_SVLAN_MEMBERCFG39_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG39_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG39_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG39_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG39_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG39_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG39_CTRL3 0x0c78 -+#define RTL8367C_SVLAN_MEMBERCFG39_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG39_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG39_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG39_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG39_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG39_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG40_CTRL1 0x0c79 -+#define RTL8367C_SVLAN_MEMBERCFG40_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG40_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG40_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG40_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG40_CTRL2 0x0c7a -+#define RTL8367C_SVLAN_MEMBERCFG40_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG40_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG40_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG40_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG40_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG40_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG40_CTRL3 0x0c7b -+#define RTL8367C_SVLAN_MEMBERCFG40_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG40_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG40_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG40_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG40_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG40_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG41_CTRL1 0x0c7c -+#define RTL8367C_SVLAN_MEMBERCFG41_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG41_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG41_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG41_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG41_CTRL2 0x0c7d -+#define RTL8367C_SVLAN_MEMBERCFG41_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG41_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG41_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG41_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG41_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG41_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG41_CTRL3 0x0c7e -+#define RTL8367C_SVLAN_MEMBERCFG41_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG41_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG41_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG41_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG41_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG41_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG42_CTRL1 0x0c7f -+#define RTL8367C_SVLAN_MEMBERCFG42_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG42_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG42_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG42_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG42_CTRL2 0x0c80 -+#define RTL8367C_SVLAN_MEMBERCFG42_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG42_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG42_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG42_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG42_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG42_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG42_CTRL3 0x0c81 -+#define RTL8367C_SVLAN_MEMBERCFG42_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG42_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG42_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG42_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG42_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG42_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG43_CTRL1 0x0c82 -+#define RTL8367C_SVLAN_MEMBERCFG43_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG43_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG43_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG43_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG43_CTRL2 0x0c83 -+#define RTL8367C_SVLAN_MEMBERCFG43_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG43_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG43_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG43_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG43_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG43_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG43_CTRL3 0x0c84 -+#define RTL8367C_SVLAN_MEMBERCFG43_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG43_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG43_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG43_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG43_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG43_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG44_CTRL1 0x0c85 -+#define RTL8367C_SVLAN_MEMBERCFG44_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG44_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG44_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG44_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG44_CTRL2 0x0c86 -+#define RTL8367C_SVLAN_MEMBERCFG44_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG44_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG44_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG44_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG44_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG44_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG44_CTRL3 0x0c87 -+#define RTL8367C_SVLAN_MEMBERCFG44_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG44_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG44_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG44_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG44_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG44_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG45_CTRL1 0x0c88 -+#define RTL8367C_SVLAN_MEMBERCFG45_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG45_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG45_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG45_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG45_CTRL2 0x0c89 -+#define RTL8367C_SVLAN_MEMBERCFG45_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG45_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG45_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG45_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG45_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG45_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG45_CTRL3 0x0c8a -+#define RTL8367C_SVLAN_MEMBERCFG45_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG45_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG45_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG45_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG45_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG45_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG46_CTRL1 0x0c8b -+#define RTL8367C_SVLAN_MEMBERCFG46_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG46_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG46_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG46_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG46_CTRL2 0x0c8c -+#define RTL8367C_SVLAN_MEMBERCFG46_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG46_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG46_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG46_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG46_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG46_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG46_CTRL3 0x0c8d -+#define RTL8367C_SVLAN_MEMBERCFG46_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG46_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG46_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG46_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG46_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG46_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG47_CTRL1 0x0c8e -+#define RTL8367C_SVLAN_MEMBERCFG47_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG47_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG47_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG47_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG47_CTRL2 0x0c8f -+#define RTL8367C_SVLAN_MEMBERCFG47_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG47_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG47_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG47_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG47_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG47_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG47_CTRL3 0x0c90 -+#define RTL8367C_SVLAN_MEMBERCFG47_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG47_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG47_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG47_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG47_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG47_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG48_CTRL1 0x0c91 -+#define RTL8367C_SVLAN_MEMBERCFG48_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG48_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG48_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG48_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG48_CTRL2 0x0c92 -+#define RTL8367C_SVLAN_MEMBERCFG48_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG48_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG48_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG48_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG48_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG48_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG48_CTRL3 0x0c93 -+#define RTL8367C_SVLAN_MEMBERCFG48_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG48_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG48_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG48_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG48_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG48_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG49_CTRL1 0x0c94 -+#define RTL8367C_SVLAN_MEMBERCFG49_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG49_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG49_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG49_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG49_CTRL2 0x0c95 -+#define RTL8367C_SVLAN_MEMBERCFG49_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG49_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG49_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG49_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG49_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG49_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG49_CTRL3 0x0c96 -+#define RTL8367C_SVLAN_MEMBERCFG49_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG49_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG49_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG49_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG49_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG49_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG50_CTRL1 0x0c97 -+#define RTL8367C_SVLAN_MEMBERCFG50_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG50_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG50_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG50_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG50_CTRL2 0x0c98 -+#define RTL8367C_SVLAN_MEMBERCFG50_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG50_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG50_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG50_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG50_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG50_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG50_CTRL3 0x0c99 -+#define RTL8367C_SVLAN_MEMBERCFG50_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG50_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG50_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG50_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG50_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG50_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG51_CTRL1 0x0c9a -+#define RTL8367C_SVLAN_MEMBERCFG51_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG51_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG51_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG51_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG51_CTRL2 0x0c9b -+#define RTL8367C_SVLAN_MEMBERCFG51_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG51_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG51_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG51_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG51_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG51_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG51_CTRL3 0x0c9c -+#define RTL8367C_SVLAN_MEMBERCFG51_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG51_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG51_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG51_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG51_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG51_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG52_CTRL1 0x0c9d -+#define RTL8367C_SVLAN_MEMBERCFG52_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG52_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG52_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG52_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG52_CTRL2 0x0c9e -+#define RTL8367C_SVLAN_MEMBERCFG52_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG52_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG52_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG52_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG52_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG52_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG52_CTRL3 0x0c9f -+#define RTL8367C_SVLAN_MEMBERCFG52_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG52_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG52_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG52_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG52_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG52_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG53_CTRL1 0x0ca0 -+#define RTL8367C_SVLAN_MEMBERCFG53_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG53_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG53_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG53_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG53_CTRL2 0x0ca1 -+#define RTL8367C_SVLAN_MEMBERCFG53_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG53_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG53_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG53_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG53_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG53_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG53_CTRL3 0x0ca2 -+#define RTL8367C_SVLAN_MEMBERCFG53_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG53_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG53_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG53_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG53_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG53_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG54_CTRL1 0x0ca3 -+#define RTL8367C_SVLAN_MEMBERCFG54_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG54_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG54_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG54_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG54_CTRL2 0x0ca4 -+#define RTL8367C_SVLAN_MEMBERCFG54_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG54_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG54_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG54_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG54_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG54_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG54_CTRL3 0x0ca5 -+#define RTL8367C_SVLAN_MEMBERCFG54_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG54_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG54_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG54_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG54_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG54_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG55_CTRL1 0x0ca6 -+#define RTL8367C_SVLAN_MEMBERCFG55_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG55_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG55_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG55_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG55_CTRL2 0x0ca7 -+#define RTL8367C_SVLAN_MEMBERCFG55_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG55_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG55_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG55_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG55_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG55_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG55_CTRL3 0x0ca8 -+#define RTL8367C_SVLAN_MEMBERCFG55_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG55_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG55_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG55_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG55_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG55_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG56_CTRL1 0x0ca9 -+#define RTL8367C_SVLAN_MEMBERCFG56_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG56_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG56_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG56_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG56_CTRL2 0x0caa -+#define RTL8367C_SVLAN_MEMBERCFG56_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG56_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG56_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG56_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG56_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG56_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG56_CTRL3 0x0cab -+#define RTL8367C_SVLAN_MEMBERCFG56_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG56_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG56_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG56_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG56_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG56_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG57_CTRL1 0x0cac -+#define RTL8367C_SVLAN_MEMBERCFG57_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG57_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG57_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG57_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG57_CTRL2 0x0cad -+#define RTL8367C_SVLAN_MEMBERCFG57_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG57_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG57_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG57_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG57_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG57_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG57_CTRL3 0x0cae -+#define RTL8367C_SVLAN_MEMBERCFG57_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG57_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG57_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG57_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG57_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG57_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG58_CTRL1 0x0caf -+#define RTL8367C_SVLAN_MEMBERCFG58_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG58_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG58_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG58_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG58_CTRL2 0x0cb0 -+#define RTL8367C_SVLAN_MEMBERCFG58_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG58_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG58_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG58_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG58_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG58_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG58_CTRL3 0x0cb1 -+#define RTL8367C_SVLAN_MEMBERCFG58_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG58_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG58_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG58_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG58_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG58_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG59_CTRL1 0x0cb2 -+#define RTL8367C_SVLAN_MEMBERCFG59_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG59_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG59_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG59_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG59_CTRL2 0x0cb3 -+#define RTL8367C_SVLAN_MEMBERCFG59_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG59_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG59_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG59_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG59_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG59_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG59_CTRL3 0x0cb4 -+#define RTL8367C_SVLAN_MEMBERCFG59_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG59_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG59_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG59_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG59_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG59_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG60_CTRL1 0x0cb5 -+#define RTL8367C_SVLAN_MEMBERCFG60_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG60_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG60_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG60_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG60_CTRL2 0x0cb6 -+#define RTL8367C_SVLAN_MEMBERCFG60_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG60_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG60_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG60_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG60_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG60_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG60_CTRL3 0x0cb7 -+#define RTL8367C_SVLAN_MEMBERCFG60_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG60_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG60_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG60_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG60_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG60_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG61_CTRL1 0x0cb8 -+#define RTL8367C_SVLAN_MEMBERCFG61_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG61_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG61_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG61_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG61_CTRL2 0x0cb9 -+#define RTL8367C_SVLAN_MEMBERCFG61_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG61_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG61_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG61_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG61_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG61_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG61_CTRL3 0x0cba -+#define RTL8367C_SVLAN_MEMBERCFG61_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG61_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG61_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG61_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG61_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG61_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG62_CTRL1 0x0cbb -+#define RTL8367C_SVLAN_MEMBERCFG62_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG62_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG62_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG62_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG62_CTRL2 0x0cbc -+#define RTL8367C_SVLAN_MEMBERCFG62_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG62_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG62_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG62_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG62_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG62_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG62_CTRL3 0x0cbd -+#define RTL8367C_SVLAN_MEMBERCFG62_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG62_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG62_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG62_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG62_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG62_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG63_CTRL1 0x0cbe -+#define RTL8367C_SVLAN_MEMBERCFG63_CTRL1_VS_UNTAGSET_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG63_CTRL1_VS_UNTAGSET_MASK 0xFF00 -+#define RTL8367C_SVLAN_MEMBERCFG63_CTRL1_VS_SMBR_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG63_CTRL1_VS_SMBR_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG63_CTRL2 0x0cbf -+#define RTL8367C_SVLAN_MEMBERCFG63_CTRL2_VS_FIDEN_OFFSET 7 -+#define RTL8367C_SVLAN_MEMBERCFG63_CTRL2_VS_FIDEN_MASK 0x80 -+#define RTL8367C_SVLAN_MEMBERCFG63_CTRL2_VS_SPRI_OFFSET 4 -+#define RTL8367C_SVLAN_MEMBERCFG63_CTRL2_VS_SPRI_MASK 0x70 -+#define RTL8367C_SVLAN_MEMBERCFG63_CTRL2_VS_FID_MSTI_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG63_CTRL2_VS_FID_MSTI_MASK 0xF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG63_CTRL3 0x0cc0 -+#define RTL8367C_SVLAN_MEMBERCFG63_CTRL3_VS_EFID_OFFSET 13 -+#define RTL8367C_SVLAN_MEMBERCFG63_CTRL3_VS_EFID_MASK 0xE000 -+#define RTL8367C_SVLAN_MEMBERCFG63_CTRL3_VS_EFIDEN_OFFSET 12 -+#define RTL8367C_SVLAN_MEMBERCFG63_CTRL3_VS_EFIDEN_MASK 0x1000 -+#define RTL8367C_SVLAN_MEMBERCFG63_CTRL3_VS_SVID_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG63_CTRL3_VS_SVID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG0_CTRL4 0x0cc1 -+#define RTL8367C_SVLAN_MEMBERCFG0_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG0_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG0_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG0_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG1_CTRL4 0x0cc2 -+#define RTL8367C_SVLAN_MEMBERCFG1_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG1_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG1_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG1_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG2_CTRL4 0x0cc3 -+#define RTL8367C_SVLAN_MEMBERCFG2_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG2_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG2_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG2_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG3_CTRL4 0x0cc4 -+#define RTL8367C_SVLAN_MEMBERCFG3_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG3_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG3_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG3_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG4_CTRL4 0x0cc5 -+#define RTL8367C_SVLAN_MEMBERCFG4_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG4_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG4_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG4_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG5_CTRL4 0x0cc6 -+#define RTL8367C_SVLAN_MEMBERCFG5_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG5_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG5_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG5_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG6_CTRL4 0x0cc7 -+#define RTL8367C_SVLAN_MEMBERCFG6_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG6_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG6_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG6_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG7_CTRL4 0x0cc8 -+#define RTL8367C_SVLAN_MEMBERCFG7_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG7_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG7_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG7_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG8_CTRL4 0x0cc9 -+#define RTL8367C_SVLAN_MEMBERCFG8_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG8_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG8_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG8_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG9_CTRL4 0x0cca -+#define RTL8367C_SVLAN_MEMBERCFG9_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG9_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG9_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG9_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG10_CTRL4 0x0ccb -+#define RTL8367C_SVLAN_MEMBERCFG10_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG10_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG10_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG10_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG11_CTRL4 0x0ccc -+#define RTL8367C_SVLAN_MEMBERCFG11_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG11_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG11_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG11_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG12_CTRL4 0x0ccd -+#define RTL8367C_SVLAN_MEMBERCFG12_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG12_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG12_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG12_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG13_CTRL4 0x0cce -+#define RTL8367C_SVLAN_MEMBERCFG13_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG13_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG13_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG13_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG14_CTRL4 0x0ccf -+#define RTL8367C_SVLAN_MEMBERCFG14_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG14_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG14_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG14_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG15_CTRL4 0x0cd0 -+#define RTL8367C_SVLAN_MEMBERCFG15_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG15_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG15_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG15_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG16_CTRL4 0x0cd1 -+#define RTL8367C_SVLAN_MEMBERCFG16_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG16_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG16_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG16_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG17_CTRL4 0x0cd2 -+#define RTL8367C_SVLAN_MEMBERCFG17_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG17_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG17_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG17_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG18_CTRL4 0x0cd3 -+#define RTL8367C_SVLAN_MEMBERCFG18_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG18_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG18_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG18_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG19_CTRL4 0x0cd4 -+#define RTL8367C_SVLAN_MEMBERCFG19_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG19_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG19_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG19_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG20_CTRL4 0x0cd5 -+#define RTL8367C_SVLAN_MEMBERCFG20_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG20_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG20_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG20_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG21_CTRL4 0x0cd6 -+#define RTL8367C_SVLAN_MEMBERCFG21_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG21_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG21_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG21_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG22_CTRL4 0x0cd7 -+#define RTL8367C_SVLAN_MEMBERCFG22_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG22_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG22_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG22_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG23_CTRL4 0x0cd8 -+#define RTL8367C_SVLAN_MEMBERCFG23_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG23_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG23_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG23_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG24_CTRL4 0x0cd9 -+#define RTL8367C_SVLAN_MEMBERCFG24_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG24_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG24_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG24_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG25_CTRL4 0x0cda -+#define RTL8367C_SVLAN_MEMBERCFG25_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG25_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG25_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG25_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG26_CTRL4 0x0cdb -+#define RTL8367C_SVLAN_MEMBERCFG26_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG26_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG26_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG26_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG27_CTRL4 0x0cdc -+#define RTL8367C_SVLAN_MEMBERCFG27_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG27_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG27_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG27_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG28_CTRL4 0x0cdd -+#define RTL8367C_SVLAN_MEMBERCFG28_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG28_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG28_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG28_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG29_CTRL4 0x0cde -+#define RTL8367C_SVLAN_MEMBERCFG29_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG29_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG29_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG29_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG30_CTRL4 0x0cdf -+#define RTL8367C_SVLAN_MEMBERCFG30_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG30_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG30_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG30_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG31_CTRL4 0x0ce0 -+#define RTL8367C_SVLAN_MEMBERCFG31_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG31_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG31_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG31_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG32_CTRL4 0x0ce1 -+#define RTL8367C_SVLAN_MEMBERCFG32_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG32_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG32_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG32_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG33_CTRL4 0x0ce2 -+#define RTL8367C_SVLAN_MEMBERCFG33_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG33_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG33_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG33_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG34_CTRL4 0x0ce3 -+#define RTL8367C_SVLAN_MEMBERCFG34_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG34_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG34_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG34_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG35_CTRL4 0x0ce4 -+#define RTL8367C_SVLAN_MEMBERCFG35_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG35_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG35_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG35_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG36_CTRL4 0x0ce5 -+#define RTL8367C_SVLAN_MEMBERCFG36_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG36_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG36_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG36_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG37_CTRL4 0x0ce6 -+#define RTL8367C_SVLAN_MEMBERCFG37_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG37_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG37_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG37_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG38_CTRL4 0x0ce7 -+#define RTL8367C_SVLAN_MEMBERCFG38_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG38_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG38_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG38_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG39_CTRL4 0x0ce8 -+#define RTL8367C_SVLAN_MEMBERCFG39_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG39_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG39_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG39_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG40_CTRL4 0x0ce9 -+#define RTL8367C_SVLAN_MEMBERCFG40_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG40_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG40_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG40_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG41_CTRL4 0x0cea -+#define RTL8367C_SVLAN_MEMBERCFG41_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG41_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG41_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG41_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG42_CTRL4 0x0ceb -+#define RTL8367C_SVLAN_MEMBERCFG42_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG42_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG42_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG42_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG43_CTRL4 0x0cec -+#define RTL8367C_SVLAN_MEMBERCFG43_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG43_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG43_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG43_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG44_CTRL4 0x0ced -+#define RTL8367C_SVLAN_MEMBERCFG44_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG44_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG44_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG44_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG45_CTRL4 0x0cee -+#define RTL8367C_SVLAN_MEMBERCFG45_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG45_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG45_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG45_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG46_CTRL4 0x0cef -+#define RTL8367C_SVLAN_MEMBERCFG46_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG46_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG46_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG46_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG47_CTRL4 0x0cf0 -+#define RTL8367C_SVLAN_MEMBERCFG47_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG47_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG47_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG47_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG48_CTRL4 0x0cf1 -+#define RTL8367C_SVLAN_MEMBERCFG48_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG48_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG48_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG48_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG49_CTRL4 0x0cf2 -+#define RTL8367C_SVLAN_MEMBERCFG49_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG49_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG49_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG49_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG50_CTRL4 0x0cf3 -+#define RTL8367C_SVLAN_MEMBERCFG50_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG50_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG50_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG50_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG51_CTRL4 0x0cf4 -+#define RTL8367C_SVLAN_MEMBERCFG51_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG51_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG51_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG51_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG52_CTRL4 0x0cf5 -+#define RTL8367C_SVLAN_MEMBERCFG52_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG52_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG52_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG52_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG53_CTRL4 0x0cf6 -+#define RTL8367C_SVLAN_MEMBERCFG53_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG53_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG53_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG53_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG54_CTRL4 0x0cf7 -+#define RTL8367C_SVLAN_MEMBERCFG54_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG54_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG54_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG54_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG55_CTRL4 0x0cf8 -+#define RTL8367C_SVLAN_MEMBERCFG55_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG55_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG55_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG55_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG56_CTRL4 0x0cf9 -+#define RTL8367C_SVLAN_MEMBERCFG56_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG56_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG56_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG56_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG57_CTRL4 0x0cfa -+#define RTL8367C_SVLAN_MEMBERCFG57_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG57_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG57_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG57_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG58_CTRL4 0x0cfb -+#define RTL8367C_SVLAN_MEMBERCFG58_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG58_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG58_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG58_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG59_CTRL4 0x0cfc -+#define RTL8367C_SVLAN_MEMBERCFG59_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG59_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG59_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG59_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG60_CTRL4 0x0cfd -+#define RTL8367C_SVLAN_MEMBERCFG60_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG60_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG60_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG60_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG61_CTRL4 0x0cfe -+#define RTL8367C_SVLAN_MEMBERCFG61_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG61_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG61_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG61_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG62_CTRL4 0x0cff -+#define RTL8367C_SVLAN_MEMBERCFG62_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG62_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG62_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG62_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_C2SCFG0_CTRL0 0x0d00 -+#define RTL8367C_SVLAN_C2SCFG0_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG0_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG0_CTRL1 0x0d01 -+#define RTL8367C_SVLAN_C2SCFG0_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG0_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG0_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG0_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG0_CTRL2 0x0d02 -+#define RTL8367C_SVLAN_C2SCFG0_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG0_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG1_CTRL0 0x0d03 -+#define RTL8367C_SVLAN_C2SCFG1_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG1_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG1_CTRL1 0x0d04 -+#define RTL8367C_SVLAN_C2SCFG1_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG1_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG1_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG1_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG1_CTRL2 0x0d05 -+#define RTL8367C_SVLAN_C2SCFG1_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG1_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG2_CTRL0 0x0d06 -+#define RTL8367C_SVLAN_C2SCFG2_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG2_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG2_CTRL1 0x0d07 -+#define RTL8367C_SVLAN_C2SCFG2_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG2_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG2_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG2_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG2_CTRL2 0x0d08 -+#define RTL8367C_SVLAN_C2SCFG2_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG2_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG3_CTRL0 0x0d09 -+#define RTL8367C_SVLAN_C2SCFG3_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG3_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG3_CTRL1 0x0d0a -+#define RTL8367C_SVLAN_C2SCFG3_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG3_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG3_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG3_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG3_CTRL2 0x0d0b -+#define RTL8367C_SVLAN_C2SCFG3_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG3_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG4_CTRL0 0x0d0c -+#define RTL8367C_SVLAN_C2SCFG4_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG4_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG4_CTRL1 0x0d0d -+#define RTL8367C_SVLAN_C2SCFG4_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG4_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG4_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG4_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG4_CTRL2 0x0d0e -+#define RTL8367C_SVLAN_C2SCFG4_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG4_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG5_CTRL0 0x0d0f -+#define RTL8367C_SVLAN_C2SCFG5_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG5_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG5_CTRL1 0x0d10 -+#define RTL8367C_SVLAN_C2SCFG5_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG5_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG5_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG5_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG5_CTRL2 0x0d11 -+#define RTL8367C_SVLAN_C2SCFG5_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG5_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG6_CTRL0 0x0d12 -+#define RTL8367C_SVLAN_C2SCFG6_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG6_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG6_CTRL1 0x0d13 -+#define RTL8367C_SVLAN_C2SCFG6_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG6_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG6_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG6_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG6_CTRL2 0x0d14 -+#define RTL8367C_SVLAN_C2SCFG6_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG6_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG7_CTRL0 0x0d15 -+#define RTL8367C_SVLAN_C2SCFG7_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG7_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG7_CTRL1 0x0d16 -+#define RTL8367C_SVLAN_C2SCFG7_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG7_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG7_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG7_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG7_CTRL2 0x0d17 -+#define RTL8367C_SVLAN_C2SCFG7_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG7_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG8_CTRL0 0x0d18 -+#define RTL8367C_SVLAN_C2SCFG8_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG8_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG8_CTRL1 0x0d19 -+#define RTL8367C_SVLAN_C2SCFG8_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG8_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG8_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG8_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG8_CTRL2 0x0d1a -+#define RTL8367C_SVLAN_C2SCFG8_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG8_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG9_CTRL0 0x0d1b -+#define RTL8367C_SVLAN_C2SCFG9_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG9_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG9_CTRL1 0x0d1c -+#define RTL8367C_SVLAN_C2SCFG9_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG9_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG9_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG9_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG9_CTRL2 0x0d1d -+#define RTL8367C_SVLAN_C2SCFG9_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG9_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG10_CTRL0 0x0d1e -+#define RTL8367C_SVLAN_C2SCFG10_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG10_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG10_CTRL1 0x0d1f -+#define RTL8367C_SVLAN_C2SCFG10_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG10_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG10_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG10_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG10_CTRL2 0x0d20 -+#define RTL8367C_SVLAN_C2SCFG10_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG10_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG11_CTRL0 0x0d21 -+#define RTL8367C_SVLAN_C2SCFG11_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG11_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG11_CTRL1 0x0d22 -+#define RTL8367C_SVLAN_C2SCFG11_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG11_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG11_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG11_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG11_CTRL2 0x0d23 -+#define RTL8367C_SVLAN_C2SCFG11_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG11_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG12_CTRL0 0x0d24 -+#define RTL8367C_SVLAN_C2SCFG12_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG12_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG12_CTRL1 0x0d25 -+#define RTL8367C_SVLAN_C2SCFG12_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG12_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG12_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG12_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG12_CTRL2 0x0d26 -+#define RTL8367C_SVLAN_C2SCFG12_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG12_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG13_CTRL0 0x0d27 -+#define RTL8367C_SVLAN_C2SCFG13_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG13_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG13_CTRL1 0x0d28 -+#define RTL8367C_SVLAN_C2SCFG13_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG13_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG13_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG13_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG13_CTRL2 0x0d29 -+#define RTL8367C_SVLAN_C2SCFG13_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG13_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG14_CTRL0 0x0d2a -+#define RTL8367C_SVLAN_C2SCFG14_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG14_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG14_CTRL1 0x0d2b -+#define RTL8367C_SVLAN_C2SCFG14_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG14_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG14_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG14_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG14_CTRL2 0x0d2c -+#define RTL8367C_SVLAN_C2SCFG14_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG14_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG15_CTRL0 0x0d2d -+#define RTL8367C_SVLAN_C2SCFG15_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG15_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG15_CTRL1 0x0d2e -+#define RTL8367C_SVLAN_C2SCFG15_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG15_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG15_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG15_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG15_CTRL2 0x0d2f -+#define RTL8367C_SVLAN_C2SCFG15_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG15_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG16_CTRL0 0x0d30 -+#define RTL8367C_SVLAN_C2SCFG16_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG16_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG16_CTRL1 0x0d31 -+#define RTL8367C_SVLAN_C2SCFG16_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG16_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG16_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG16_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG16_CTRL2 0x0d32 -+#define RTL8367C_SVLAN_C2SCFG16_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG16_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG17_CTRL0 0x0d33 -+#define RTL8367C_SVLAN_C2SCFG17_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG17_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG17_CTRL1 0x0d34 -+#define RTL8367C_SVLAN_C2SCFG17_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG17_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG17_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG17_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG17_CTRL2 0x0d35 -+#define RTL8367C_SVLAN_C2SCFG17_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG17_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG18_CTRL0 0x0d36 -+#define RTL8367C_SVLAN_C2SCFG18_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG18_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG18_CTRL1 0x0d37 -+#define RTL8367C_SVLAN_C2SCFG18_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG18_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG18_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG18_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG18_CTRL2 0x0d38 -+#define RTL8367C_SVLAN_C2SCFG18_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG18_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG19_CTRL0 0x0d39 -+#define RTL8367C_SVLAN_C2SCFG19_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG19_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG19_CTRL1 0x0d3a -+#define RTL8367C_SVLAN_C2SCFG19_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG19_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG19_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG19_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG19_CTRL2 0x0d3b -+#define RTL8367C_SVLAN_C2SCFG19_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG19_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG20_CTRL0 0x0d3c -+#define RTL8367C_SVLAN_C2SCFG20_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG20_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG20_CTRL1 0x0d3d -+#define RTL8367C_SVLAN_C2SCFG20_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG20_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG20_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG20_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG20_CTRL2 0x0d3e -+#define RTL8367C_SVLAN_C2SCFG20_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG20_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG21_CTRL0 0x0d3f -+#define RTL8367C_SVLAN_C2SCFG21_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG21_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG21_CTRL1 0x0d40 -+#define RTL8367C_SVLAN_C2SCFG21_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG21_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG21_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG21_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG21_CTRL2 0x0d41 -+#define RTL8367C_SVLAN_C2SCFG21_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG21_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG22_CTRL0 0x0d42 -+#define RTL8367C_SVLAN_C2SCFG22_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG22_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG22_CTRL1 0x0d43 -+#define RTL8367C_SVLAN_C2SCFG22_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG22_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG22_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG22_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG22_CTRL2 0x0d44 -+#define RTL8367C_SVLAN_C2SCFG22_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG22_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG23_CTRL0 0x0d45 -+#define RTL8367C_SVLAN_C2SCFG23_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG23_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG23_CTRL1 0x0d46 -+#define RTL8367C_SVLAN_C2SCFG23_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG23_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG23_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG23_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG23_CTRL2 0x0d47 -+#define RTL8367C_SVLAN_C2SCFG23_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG23_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG24_CTRL0 0x0d48 -+#define RTL8367C_SVLAN_C2SCFG24_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG24_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG24_CTRL1 0x0d49 -+#define RTL8367C_SVLAN_C2SCFG24_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG24_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG24_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG24_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG24_CTRL2 0x0d4a -+#define RTL8367C_SVLAN_C2SCFG24_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG24_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG25_CTRL0 0x0d4b -+#define RTL8367C_SVLAN_C2SCFG25_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG25_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG25_CTRL1 0x0d4c -+#define RTL8367C_SVLAN_C2SCFG25_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG25_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG25_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG25_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG25_CTRL2 0x0d4d -+#define RTL8367C_SVLAN_C2SCFG25_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG25_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG26_CTRL0 0x0d4e -+#define RTL8367C_SVLAN_C2SCFG26_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG26_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG26_CTRL1 0x0d4f -+#define RTL8367C_SVLAN_C2SCFG26_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG26_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG26_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG26_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG26_CTRL2 0x0d50 -+#define RTL8367C_SVLAN_C2SCFG26_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG26_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG27_CTRL0 0x0d51 -+#define RTL8367C_SVLAN_C2SCFG27_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG27_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG27_CTRL1 0x0d52 -+#define RTL8367C_SVLAN_C2SCFG27_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG27_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG27_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG27_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG27_CTRL2 0x0d53 -+#define RTL8367C_SVLAN_C2SCFG27_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG27_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG28_CTRL0 0x0d54 -+#define RTL8367C_SVLAN_C2SCFG28_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG28_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG28_CTRL1 0x0d55 -+#define RTL8367C_SVLAN_C2SCFG28_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG28_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG28_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG28_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG28_CTRL2 0x0d56 -+#define RTL8367C_SVLAN_C2SCFG28_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG28_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG29_CTRL0 0x0d57 -+#define RTL8367C_SVLAN_C2SCFG29_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG29_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG29_CTRL1 0x0d58 -+#define RTL8367C_SVLAN_C2SCFG29_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG29_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG29_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG29_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG29_CTRL2 0x0d59 -+#define RTL8367C_SVLAN_C2SCFG29_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG29_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG30_CTRL0 0x0d5a -+#define RTL8367C_SVLAN_C2SCFG30_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG30_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG30_CTRL1 0x0d5b -+#define RTL8367C_SVLAN_C2SCFG30_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG30_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG30_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG30_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG30_CTRL2 0x0d5c -+#define RTL8367C_SVLAN_C2SCFG30_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG30_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG31_CTRL0 0x0d5d -+#define RTL8367C_SVLAN_C2SCFG31_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG31_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG31_CTRL1 0x0d5e -+#define RTL8367C_SVLAN_C2SCFG31_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG31_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG31_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG31_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG31_CTRL2 0x0d5f -+#define RTL8367C_SVLAN_C2SCFG31_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG31_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG32_CTRL0 0x0d60 -+#define RTL8367C_SVLAN_C2SCFG32_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG32_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG32_CTRL1 0x0d61 -+#define RTL8367C_SVLAN_C2SCFG32_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG32_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG32_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG32_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG32_CTRL2 0x0d62 -+#define RTL8367C_SVLAN_C2SCFG32_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG32_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG33_CTRL0 0x0d63 -+#define RTL8367C_SVLAN_C2SCFG33_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG33_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG33_CTRL1 0x0d64 -+#define RTL8367C_SVLAN_C2SCFG33_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG33_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG33_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG33_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG33_CTRL2 0x0d65 -+#define RTL8367C_SVLAN_C2SCFG33_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG33_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG34_CTRL0 0x0d66 -+#define RTL8367C_SVLAN_C2SCFG34_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG34_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG34_CTRL1 0x0d67 -+#define RTL8367C_SVLAN_C2SCFG34_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG34_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG34_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG34_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG34_CTRL2 0x0d68 -+#define RTL8367C_SVLAN_C2SCFG34_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG34_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG35_CTRL0 0x0d69 -+#define RTL8367C_SVLAN_C2SCFG35_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG35_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG35_CTRL1 0x0d6a -+#define RTL8367C_SVLAN_C2SCFG35_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG35_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG35_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG35_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG35_CTRL2 0x0d6b -+#define RTL8367C_SVLAN_C2SCFG35_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG35_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG36_CTRL0 0x0d6c -+#define RTL8367C_SVLAN_C2SCFG36_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG36_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG36_CTRL1 0x0d6d -+#define RTL8367C_SVLAN_C2SCFG36_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG36_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG36_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG36_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG36_CTRL2 0x0d6e -+#define RTL8367C_SVLAN_C2SCFG36_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG36_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG37_CTRL0 0x0d6f -+#define RTL8367C_SVLAN_C2SCFG37_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG37_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG37_CTRL1 0x0d70 -+#define RTL8367C_SVLAN_C2SCFG37_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG37_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG37_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG37_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG37_CTRL2 0x0d71 -+#define RTL8367C_SVLAN_C2SCFG37_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG37_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG38_CTRL0 0x0d72 -+#define RTL8367C_SVLAN_C2SCFG38_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG38_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG38_CTRL1 0x0d73 -+#define RTL8367C_SVLAN_C2SCFG38_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG38_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG38_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG38_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG38_CTRL2 0x0d74 -+#define RTL8367C_SVLAN_C2SCFG38_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG38_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG39_CTRL0 0x0d75 -+#define RTL8367C_SVLAN_C2SCFG39_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG39_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG39_CTRL1 0x0d76 -+#define RTL8367C_SVLAN_C2SCFG39_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG39_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG39_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG39_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG39_CTRL2 0x0d77 -+#define RTL8367C_SVLAN_C2SCFG39_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG39_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG40_CTRL0 0x0d78 -+#define RTL8367C_SVLAN_C2SCFG40_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG40_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG40_CTRL1 0x0d79 -+#define RTL8367C_SVLAN_C2SCFG40_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG40_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG40_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG40_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG40_CTRL2 0x0d7a -+#define RTL8367C_SVLAN_C2SCFG40_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG40_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG41_CTRL0 0x0d7b -+#define RTL8367C_SVLAN_C2SCFG41_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG41_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG41_CTRL1 0x0d7c -+#define RTL8367C_SVLAN_C2SCFG41_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG41_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG41_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG41_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG41_CTRL2 0x0d7d -+#define RTL8367C_SVLAN_C2SCFG41_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG41_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG42_CTRL0 0x0d7e -+#define RTL8367C_SVLAN_C2SCFG42_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG42_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG42_CTRL1 0x0d7f -+#define RTL8367C_SVLAN_C2SCFG42_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG42_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG42_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG42_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG42_CTRL2 0x0d80 -+#define RTL8367C_SVLAN_C2SCFG42_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG42_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG43_CTRL0 0x0d81 -+#define RTL8367C_SVLAN_C2SCFG43_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG43_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG43_CTRL1 0x0d82 -+#define RTL8367C_SVLAN_C2SCFG43_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG43_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG43_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG43_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG43_CTRL2 0x0d83 -+#define RTL8367C_SVLAN_C2SCFG43_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG43_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG44_CTRL0 0x0d84 -+#define RTL8367C_SVLAN_C2SCFG44_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG44_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG44_CTRL1 0x0d85 -+#define RTL8367C_SVLAN_C2SCFG44_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG44_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG44_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG44_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG44_CTRL2 0x0d86 -+#define RTL8367C_SVLAN_C2SCFG44_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG44_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG45_CTRL0 0x0d87 -+#define RTL8367C_SVLAN_C2SCFG45_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG45_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG45_CTRL1 0x0d88 -+#define RTL8367C_SVLAN_C2SCFG45_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG45_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG45_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG45_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG45_CTRL2 0x0d89 -+#define RTL8367C_SVLAN_C2SCFG45_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG45_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG46_CTRL0 0x0d8a -+#define RTL8367C_SVLAN_C2SCFG46_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG46_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG46_CTRL1 0x0d8b -+#define RTL8367C_SVLAN_C2SCFG46_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG46_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG46_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG46_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG46_CTRL2 0x0d8c -+#define RTL8367C_SVLAN_C2SCFG46_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG46_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG47_CTRL0 0x0d8d -+#define RTL8367C_SVLAN_C2SCFG47_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG47_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG47_CTRL1 0x0d8e -+#define RTL8367C_SVLAN_C2SCFG47_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG47_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG47_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG47_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG47_CTRL2 0x0d8f -+#define RTL8367C_SVLAN_C2SCFG47_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG47_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG48_CTRL0 0x0d90 -+#define RTL8367C_SVLAN_C2SCFG48_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG48_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG48_CTRL1 0x0d91 -+#define RTL8367C_SVLAN_C2SCFG48_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG48_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG48_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG48_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG48_CTRL2 0x0d92 -+#define RTL8367C_SVLAN_C2SCFG48_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG48_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG49_CTRL0 0x0d93 -+#define RTL8367C_SVLAN_C2SCFG49_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG49_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG49_CTRL1 0x0d94 -+#define RTL8367C_SVLAN_C2SCFG49_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG49_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG49_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG49_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG49_CTRL2 0x0d95 -+#define RTL8367C_SVLAN_C2SCFG49_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG49_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG50_CTRL0 0x0d96 -+#define RTL8367C_SVLAN_C2SCFG50_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG50_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG50_CTRL1 0x0d97 -+#define RTL8367C_SVLAN_C2SCFG50_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG50_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG50_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG50_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG50_CTRL2 0x0d98 -+#define RTL8367C_SVLAN_C2SCFG50_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG50_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG51_CTRL0 0x0d99 -+#define RTL8367C_SVLAN_C2SCFG51_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG51_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG51_CTRL1 0x0d9a -+#define RTL8367C_SVLAN_C2SCFG51_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG51_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG51_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG51_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG51_CTRL2 0x0d9b -+#define RTL8367C_SVLAN_C2SCFG51_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG51_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG52_CTRL0 0x0d9c -+#define RTL8367C_SVLAN_C2SCFG52_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG52_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG52_CTRL1 0x0d9d -+#define RTL8367C_SVLAN_C2SCFG52_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG52_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG52_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG52_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG52_CTRL2 0x0d9e -+#define RTL8367C_SVLAN_C2SCFG52_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG52_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG53_CTRL0 0x0d9f -+#define RTL8367C_SVLAN_C2SCFG53_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG53_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG53_CTRL1 0x0da0 -+#define RTL8367C_SVLAN_C2SCFG53_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG53_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG53_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG53_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG53_CTRL2 0x0da1 -+#define RTL8367C_SVLAN_C2SCFG53_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG53_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG54_CTRL0 0x0da2 -+#define RTL8367C_SVLAN_C2SCFG54_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG54_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG54_CTRL1 0x0da3 -+#define RTL8367C_SVLAN_C2SCFG54_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG54_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG54_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG54_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG54_CTRL2 0x0da4 -+#define RTL8367C_SVLAN_C2SCFG54_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG54_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG55_CTRL0 0x0da5 -+#define RTL8367C_SVLAN_C2SCFG55_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG55_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG55_CTRL1 0x0da6 -+#define RTL8367C_SVLAN_C2SCFG55_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG55_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG55_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG55_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG55_CTRL2 0x0da7 -+#define RTL8367C_SVLAN_C2SCFG55_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG55_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG56_CTRL0 0x0da8 -+#define RTL8367C_SVLAN_C2SCFG56_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG56_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG56_CTRL1 0x0da9 -+#define RTL8367C_SVLAN_C2SCFG56_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG56_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG56_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG56_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG56_CTRL2 0x0daa -+#define RTL8367C_SVLAN_C2SCFG56_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG56_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG57_CTRL0 0x0dab -+#define RTL8367C_SVLAN_C2SCFG57_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG57_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG57_CTRL1 0x0dac -+#define RTL8367C_SVLAN_C2SCFG57_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG57_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG57_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG57_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG57_CTRL2 0x0dad -+#define RTL8367C_SVLAN_C2SCFG57_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG57_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG58_CTRL0 0x0dae -+#define RTL8367C_SVLAN_C2SCFG58_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG58_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG58_CTRL1 0x0daf -+#define RTL8367C_SVLAN_C2SCFG58_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG58_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG58_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG58_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG58_CTRL2 0x0db0 -+#define RTL8367C_SVLAN_C2SCFG58_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG58_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG59_CTRL0 0x0db1 -+#define RTL8367C_SVLAN_C2SCFG59_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG59_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG59_CTRL1 0x0db2 -+#define RTL8367C_SVLAN_C2SCFG59_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG59_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG59_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG59_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG59_CTRL2 0x0db3 -+#define RTL8367C_SVLAN_C2SCFG59_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG59_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG60_CTRL0 0x0db4 -+#define RTL8367C_SVLAN_C2SCFG60_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG60_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG60_CTRL1 0x0db5 -+#define RTL8367C_SVLAN_C2SCFG60_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG60_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG60_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG60_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG60_CTRL2 0x0db6 -+#define RTL8367C_SVLAN_C2SCFG60_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG60_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG61_CTRL0 0x0db7 -+#define RTL8367C_SVLAN_C2SCFG61_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG61_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG61_CTRL1 0x0db8 -+#define RTL8367C_SVLAN_C2SCFG61_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG61_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG61_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG61_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG61_CTRL2 0x0db9 -+#define RTL8367C_SVLAN_C2SCFG61_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG61_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG62_CTRL0 0x0dba -+#define RTL8367C_SVLAN_C2SCFG62_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG62_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG62_CTRL1 0x0dbb -+#define RTL8367C_SVLAN_C2SCFG62_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG62_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG62_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG62_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG62_CTRL2 0x0dbc -+#define RTL8367C_SVLAN_C2SCFG62_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG62_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG63_CTRL0 0x0dbd -+#define RTL8367C_SVLAN_C2SCFG63_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG63_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG63_CTRL1 0x0dbe -+#define RTL8367C_SVLAN_C2SCFG63_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG63_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG63_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG63_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG63_CTRL2 0x0dbf -+#define RTL8367C_SVLAN_C2SCFG63_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG63_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG64_CTRL0 0x0dc0 -+#define RTL8367C_SVLAN_C2SCFG64_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG64_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG64_CTRL1 0x0dc1 -+#define RTL8367C_SVLAN_C2SCFG64_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG64_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG64_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG64_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG64_CTRL2 0x0dc2 -+#define RTL8367C_SVLAN_C2SCFG64_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG64_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG65_CTRL0 0x0dc3 -+#define RTL8367C_SVLAN_C2SCFG65_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG65_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG65_CTRL1 0x0dc4 -+#define RTL8367C_SVLAN_C2SCFG65_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG65_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG65_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG65_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG65_CTRL2 0x0dc5 -+#define RTL8367C_SVLAN_C2SCFG65_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG65_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG66_CTRL0 0x0dc6 -+#define RTL8367C_SVLAN_C2SCFG66_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG66_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG66_CTRL1 0x0dc7 -+#define RTL8367C_SVLAN_C2SCFG66_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG66_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG66_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG66_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG66_CTRL2 0x0dc8 -+#define RTL8367C_SVLAN_C2SCFG66_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG66_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG67_CTRL0 0x0dc9 -+#define RTL8367C_SVLAN_C2SCFG67_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG67_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG67_CTRL1 0x0dca -+#define RTL8367C_SVLAN_C2SCFG67_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG67_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG67_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG67_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG67_CTRL2 0x0dcb -+#define RTL8367C_SVLAN_C2SCFG67_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG67_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG68_CTRL0 0x0dcc -+#define RTL8367C_SVLAN_C2SCFG68_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG68_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG68_CTRL1 0x0dcd -+#define RTL8367C_SVLAN_C2SCFG68_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG68_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG68_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG68_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG68_CTRL2 0x0dce -+#define RTL8367C_SVLAN_C2SCFG68_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG68_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG69_CTRL0 0x0dcf -+#define RTL8367C_SVLAN_C2SCFG69_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG69_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG69_CTRL1 0x0dd0 -+#define RTL8367C_SVLAN_C2SCFG69_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG69_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG69_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG69_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG69_CTRL2 0x0dd1 -+#define RTL8367C_SVLAN_C2SCFG69_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG69_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG70_CTRL0 0x0dd2 -+#define RTL8367C_SVLAN_C2SCFG70_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG70_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG70_CTRL1 0x0dd3 -+#define RTL8367C_SVLAN_C2SCFG70_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG70_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG70_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG70_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG70_CTRL2 0x0dd4 -+#define RTL8367C_SVLAN_C2SCFG70_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG70_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG71_CTRL0 0x0dd5 -+#define RTL8367C_SVLAN_C2SCFG71_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG71_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG71_CTRL1 0x0dd6 -+#define RTL8367C_SVLAN_C2SCFG71_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG71_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG71_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG71_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG71_CTRL2 0x0dd7 -+#define RTL8367C_SVLAN_C2SCFG71_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG71_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG72_CTRL0 0x0dd8 -+#define RTL8367C_SVLAN_C2SCFG72_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG72_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG72_CTRL1 0x0dd9 -+#define RTL8367C_SVLAN_C2SCFG72_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG72_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG72_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG72_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG72_CTRL2 0x0dda -+#define RTL8367C_SVLAN_C2SCFG72_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG72_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG73_CTRL0 0x0ddb -+#define RTL8367C_SVLAN_C2SCFG73_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG73_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG73_CTRL1 0x0ddc -+#define RTL8367C_SVLAN_C2SCFG73_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG73_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG73_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG73_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG73_CTRL2 0x0ddd -+#define RTL8367C_SVLAN_C2SCFG73_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG73_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG74_CTRL0 0x0dde -+#define RTL8367C_SVLAN_C2SCFG74_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG74_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG74_CTRL1 0x0ddf -+#define RTL8367C_SVLAN_C2SCFG74_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG74_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG74_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG74_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG74_CTRL2 0x0de0 -+#define RTL8367C_SVLAN_C2SCFG74_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG74_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG75_CTRL0 0x0de1 -+#define RTL8367C_SVLAN_C2SCFG75_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG75_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG75_CTRL1 0x0de2 -+#define RTL8367C_SVLAN_C2SCFG75_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG75_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG75_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG75_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG75_CTRL2 0x0de3 -+#define RTL8367C_SVLAN_C2SCFG75_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG75_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG76_CTRL0 0x0de4 -+#define RTL8367C_SVLAN_C2SCFG76_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG76_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG76_CTRL1 0x0de5 -+#define RTL8367C_SVLAN_C2SCFG76_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG76_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG76_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG76_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG76_CTRL2 0x0de6 -+#define RTL8367C_SVLAN_C2SCFG76_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG76_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG77_CTRL0 0x0de7 -+#define RTL8367C_SVLAN_C2SCFG77_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG77_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG77_CTRL1 0x0de8 -+#define RTL8367C_SVLAN_C2SCFG77_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG77_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG77_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG77_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG77_CTRL2 0x0de9 -+#define RTL8367C_SVLAN_C2SCFG77_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG77_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG78_CTRL0 0x0dea -+#define RTL8367C_SVLAN_C2SCFG78_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG78_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG78_CTRL1 0x0deb -+#define RTL8367C_SVLAN_C2SCFG78_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG78_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG78_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG78_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG78_CTRL2 0x0dec -+#define RTL8367C_SVLAN_C2SCFG78_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG78_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG79_CTRL0 0x0ded -+#define RTL8367C_SVLAN_C2SCFG79_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG79_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG79_CTRL1 0x0dee -+#define RTL8367C_SVLAN_C2SCFG79_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG79_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG79_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG79_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG79_CTRL2 0x0def -+#define RTL8367C_SVLAN_C2SCFG79_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG79_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG80_CTRL0 0x0df0 -+#define RTL8367C_SVLAN_C2SCFG80_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG80_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG80_CTRL1 0x0df1 -+#define RTL8367C_SVLAN_C2SCFG80_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG80_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG80_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG80_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG80_CTRL2 0x0df2 -+#define RTL8367C_SVLAN_C2SCFG80_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG80_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG81_CTRL0 0x0df3 -+#define RTL8367C_SVLAN_C2SCFG81_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG81_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG81_CTRL1 0x0df4 -+#define RTL8367C_SVLAN_C2SCFG81_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG81_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG81_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG81_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG81_CTRL2 0x0df5 -+#define RTL8367C_SVLAN_C2SCFG81_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG81_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG82_CTRL0 0x0df6 -+#define RTL8367C_SVLAN_C2SCFG82_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG82_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG82_CTRL1 0x0df7 -+#define RTL8367C_SVLAN_C2SCFG82_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG82_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG82_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG82_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG82_CTRL2 0x0df8 -+#define RTL8367C_SVLAN_C2SCFG82_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG82_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG83_CTRL0 0x0df9 -+#define RTL8367C_SVLAN_C2SCFG83_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG83_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG83_CTRL1 0x0dfa -+#define RTL8367C_SVLAN_C2SCFG83_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG83_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG83_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG83_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG83_CTRL2 0x0dfb -+#define RTL8367C_SVLAN_C2SCFG83_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG83_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG84_CTRL0 0x0dfc -+#define RTL8367C_SVLAN_C2SCFG84_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG84_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG84_CTRL1 0x0dfd -+#define RTL8367C_SVLAN_C2SCFG84_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG84_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG84_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG84_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG84_CTRL2 0x0dfe -+#define RTL8367C_SVLAN_C2SCFG84_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG84_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG85_CTRL0 0x0dff -+#define RTL8367C_SVLAN_C2SCFG85_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG85_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG85_CTRL1 0x0e00 -+#define RTL8367C_SVLAN_C2SCFG85_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG85_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG85_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG85_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG85_CTRL2 0x0e01 -+#define RTL8367C_SVLAN_C2SCFG85_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG85_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG86_CTRL0 0x0e02 -+#define RTL8367C_SVLAN_C2SCFG86_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG86_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG86_CTRL1 0x0e03 -+#define RTL8367C_SVLAN_C2SCFG86_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG86_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG86_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG86_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG86_CTRL2 0x0e04 -+#define RTL8367C_SVLAN_C2SCFG86_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG86_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG87_CTRL0 0x0e05 -+#define RTL8367C_SVLAN_C2SCFG87_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG87_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG87_CTRL1 0x0e06 -+#define RTL8367C_SVLAN_C2SCFG87_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG87_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG87_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG87_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG87_CTRL2 0x0e07 -+#define RTL8367C_SVLAN_C2SCFG87_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG87_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG88_CTRL0 0x0e08 -+#define RTL8367C_SVLAN_C2SCFG88_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG88_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG88_CTRL1 0x0e09 -+#define RTL8367C_SVLAN_C2SCFG88_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG88_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG88_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG88_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG88_CTRL2 0x0e0a -+#define RTL8367C_SVLAN_C2SCFG88_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG88_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG89_CTRL0 0x0e0b -+#define RTL8367C_SVLAN_C2SCFG89_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG89_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG89_CTRL1 0x0e0c -+#define RTL8367C_SVLAN_C2SCFG89_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG89_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG89_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG89_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG89_CTRL2 0x0e0d -+#define RTL8367C_SVLAN_C2SCFG89_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG89_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG90_CTRL0 0x0e0e -+#define RTL8367C_SVLAN_C2SCFG90_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG90_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG90_CTRL1 0x0e0f -+#define RTL8367C_SVLAN_C2SCFG90_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG90_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG90_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG90_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG90_CTRL2 0x0e10 -+#define RTL8367C_SVLAN_C2SCFG90_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG90_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG91_CTRL0 0x0e11 -+#define RTL8367C_SVLAN_C2SCFG91_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG91_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG91_CTRL1 0x0e12 -+#define RTL8367C_SVLAN_C2SCFG91_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG91_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG91_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG91_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG91_CTRL2 0x0e13 -+#define RTL8367C_SVLAN_C2SCFG91_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG91_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG92_CTRL0 0x0e14 -+#define RTL8367C_SVLAN_C2SCFG92_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG92_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG92_CTRL1 0x0e15 -+#define RTL8367C_SVLAN_C2SCFG92_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG92_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG92_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG92_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG92_CTRL2 0x0e16 -+#define RTL8367C_SVLAN_C2SCFG92_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG92_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG93_CTRL0 0x0e17 -+#define RTL8367C_SVLAN_C2SCFG93_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG93_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG93_CTRL1 0x0e18 -+#define RTL8367C_SVLAN_C2SCFG93_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG93_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG93_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG93_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG93_CTRL2 0x0e19 -+#define RTL8367C_SVLAN_C2SCFG93_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG93_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG94_CTRL0 0x0e1a -+#define RTL8367C_SVLAN_C2SCFG94_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG94_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG94_CTRL1 0x0e1b -+#define RTL8367C_SVLAN_C2SCFG94_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG94_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG94_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG94_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG94_CTRL2 0x0e1c -+#define RTL8367C_SVLAN_C2SCFG94_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG94_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG95_CTRL0 0x0e1d -+#define RTL8367C_SVLAN_C2SCFG95_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG95_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG95_CTRL1 0x0e1e -+#define RTL8367C_SVLAN_C2SCFG95_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG95_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG95_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG95_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG95_CTRL2 0x0e1f -+#define RTL8367C_SVLAN_C2SCFG95_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG95_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG96_CTRL0 0x0e20 -+#define RTL8367C_SVLAN_C2SCFG96_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG96_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG96_CTRL1 0x0e21 -+#define RTL8367C_SVLAN_C2SCFG96_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG96_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG96_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG96_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG96_CTRL2 0x0e22 -+#define RTL8367C_SVLAN_C2SCFG96_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG96_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG97_CTRL0 0x0e23 -+#define RTL8367C_SVLAN_C2SCFG97_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG97_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG97_CTRL1 0x0e24 -+#define RTL8367C_SVLAN_C2SCFG97_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG97_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG97_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG97_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG97_CTRL2 0x0e25 -+#define RTL8367C_SVLAN_C2SCFG97_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG97_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG98_CTRL0 0x0e26 -+#define RTL8367C_SVLAN_C2SCFG98_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG98_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG98_CTRL1 0x0e27 -+#define RTL8367C_SVLAN_C2SCFG98_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG98_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG98_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG98_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG98_CTRL2 0x0e28 -+#define RTL8367C_SVLAN_C2SCFG98_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG98_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG99_CTRL0 0x0e29 -+#define RTL8367C_SVLAN_C2SCFG99_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG99_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG99_CTRL1 0x0e2a -+#define RTL8367C_SVLAN_C2SCFG99_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG99_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG99_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG99_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG99_CTRL2 0x0e2b -+#define RTL8367C_SVLAN_C2SCFG99_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG99_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG100_CTRL0 0x0e2c -+#define RTL8367C_SVLAN_C2SCFG100_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG100_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG100_CTRL1 0x0e2d -+#define RTL8367C_SVLAN_C2SCFG100_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG100_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG100_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG100_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG100_CTRL2 0x0e2e -+#define RTL8367C_SVLAN_C2SCFG100_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG100_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG101_CTRL0 0x0e2f -+#define RTL8367C_SVLAN_C2SCFG101_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG101_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG101_CTRL1 0x0e30 -+#define RTL8367C_SVLAN_C2SCFG101_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG101_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG101_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG101_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG101_CTRL2 0x0e31 -+#define RTL8367C_SVLAN_C2SCFG101_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG101_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG102_CTRL0 0x0e32 -+#define RTL8367C_SVLAN_C2SCFG102_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG102_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG102_CTRL1 0x0e33 -+#define RTL8367C_SVLAN_C2SCFG102_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG102_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG102_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG102_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG102_CTRL2 0x0e34 -+#define RTL8367C_SVLAN_C2SCFG102_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG102_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG103_CTRL0 0x0e35 -+#define RTL8367C_SVLAN_C2SCFG103_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG103_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG103_CTRL1 0x0e36 -+#define RTL8367C_SVLAN_C2SCFG103_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG103_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG103_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG103_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG103_CTRL2 0x0e37 -+#define RTL8367C_SVLAN_C2SCFG103_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG103_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG104_CTRL0 0x0e38 -+#define RTL8367C_SVLAN_C2SCFG104_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG104_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG104_CTRL1 0x0e39 -+#define RTL8367C_SVLAN_C2SCFG104_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG104_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG104_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG104_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG104_CTRL2 0x0e3a -+#define RTL8367C_SVLAN_C2SCFG104_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG104_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG105_CTRL0 0x0e3b -+#define RTL8367C_SVLAN_C2SCFG105_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG105_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG105_CTRL1 0x0e3c -+#define RTL8367C_SVLAN_C2SCFG105_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG105_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG105_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG105_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG105_CTRL2 0x0e3d -+#define RTL8367C_SVLAN_C2SCFG105_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG105_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG106_CTRL0 0x0e3e -+#define RTL8367C_SVLAN_C2SCFG106_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG106_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG106_CTRL1 0x0e3f -+#define RTL8367C_SVLAN_C2SCFG106_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG106_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG106_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG106_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG106_CTRL2 0x0e40 -+#define RTL8367C_SVLAN_C2SCFG106_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG106_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG107_CTRL0 0x0e41 -+#define RTL8367C_SVLAN_C2SCFG107_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG107_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG107_CTRL1 0x0e42 -+#define RTL8367C_SVLAN_C2SCFG107_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG107_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG107_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG107_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG107_CTRL2 0x0e43 -+#define RTL8367C_SVLAN_C2SCFG107_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG107_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG108_CTRL0 0x0e44 -+#define RTL8367C_SVLAN_C2SCFG108_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG108_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG108_CTRL1 0x0e45 -+#define RTL8367C_SVLAN_C2SCFG108_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG108_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG108_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG108_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG108_CTRL2 0x0e46 -+#define RTL8367C_SVLAN_C2SCFG108_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG108_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG109_CTRL0 0x0e47 -+#define RTL8367C_SVLAN_C2SCFG109_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG109_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG109_CTRL1 0x0e48 -+#define RTL8367C_SVLAN_C2SCFG109_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG109_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG109_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG109_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG109_CTRL2 0x0e49 -+#define RTL8367C_SVLAN_C2SCFG109_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG109_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG110_CTRL0 0x0e4a -+#define RTL8367C_SVLAN_C2SCFG110_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG110_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG110_CTRL1 0x0e4b -+#define RTL8367C_SVLAN_C2SCFG110_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG110_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG110_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG110_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG110_CTRL2 0x0e4c -+#define RTL8367C_SVLAN_C2SCFG110_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG110_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG111_CTRL0 0x0e4d -+#define RTL8367C_SVLAN_C2SCFG111_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG111_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG111_CTRL1 0x0e4e -+#define RTL8367C_SVLAN_C2SCFG111_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG111_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG111_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG111_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG111_CTRL2 0x0e4f -+#define RTL8367C_SVLAN_C2SCFG111_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG111_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG112_CTRL0 0x0e50 -+#define RTL8367C_SVLAN_C2SCFG112_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG112_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG112_CTRL1 0x0e51 -+#define RTL8367C_SVLAN_C2SCFG112_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG112_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG112_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG112_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG112_CTRL2 0x0e52 -+#define RTL8367C_SVLAN_C2SCFG112_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG112_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG113_CTRL0 0x0e53 -+#define RTL8367C_SVLAN_C2SCFG113_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG113_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG113_CTRL1 0x0e54 -+#define RTL8367C_SVLAN_C2SCFG113_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG113_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG113_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG113_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG113_CTRL2 0x0e55 -+#define RTL8367C_SVLAN_C2SCFG113_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG113_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG114_CTRL0 0x0e56 -+#define RTL8367C_SVLAN_C2SCFG114_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG114_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG114_CTRL1 0x0e57 -+#define RTL8367C_SVLAN_C2SCFG114_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG114_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG114_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG114_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG114_CTRL2 0x0e58 -+#define RTL8367C_SVLAN_C2SCFG114_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG114_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG115_CTRL0 0x0e59 -+#define RTL8367C_SVLAN_C2SCFG115_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG115_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG115_CTRL1 0x0e5a -+#define RTL8367C_SVLAN_C2SCFG115_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG115_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG115_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG115_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG115_CTRL2 0x0e5b -+#define RTL8367C_SVLAN_C2SCFG115_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG115_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG116_CTRL0 0x0e5c -+#define RTL8367C_SVLAN_C2SCFG116_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG116_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG116_CTRL1 0x0e5d -+#define RTL8367C_SVLAN_C2SCFG116_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG116_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG116_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG116_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG116_CTRL2 0x0e5e -+#define RTL8367C_SVLAN_C2SCFG116_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG116_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG117_CTRL0 0x0e5f -+#define RTL8367C_SVLAN_C2SCFG117_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG117_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG117_CTRL1 0x0e60 -+#define RTL8367C_SVLAN_C2SCFG117_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG117_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG117_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG117_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG117_CTRL2 0x0e61 -+#define RTL8367C_SVLAN_C2SCFG117_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG117_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG118_CTRL0 0x0e62 -+#define RTL8367C_SVLAN_C2SCFG118_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG118_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG118_CTRL1 0x0e63 -+#define RTL8367C_SVLAN_C2SCFG118_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG118_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG118_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG118_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG118_CTRL2 0x0e64 -+#define RTL8367C_SVLAN_C2SCFG118_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG118_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG119_CTRL0 0x0e65 -+#define RTL8367C_SVLAN_C2SCFG119_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG119_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG119_CTRL1 0x0e66 -+#define RTL8367C_SVLAN_C2SCFG119_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG119_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG119_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG119_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG119_CTRL2 0x0e67 -+#define RTL8367C_SVLAN_C2SCFG119_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG119_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG120_CTRL0 0x0e68 -+#define RTL8367C_SVLAN_C2SCFG120_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG120_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG120_CTRL1 0x0e69 -+#define RTL8367C_SVLAN_C2SCFG120_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG120_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG120_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG120_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG120_CTRL2 0x0e6a -+#define RTL8367C_SVLAN_C2SCFG120_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG120_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG121_CTRL0 0x0e6b -+#define RTL8367C_SVLAN_C2SCFG121_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG121_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG121_CTRL1 0x0e6c -+#define RTL8367C_SVLAN_C2SCFG121_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG121_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG121_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG121_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG121_CTRL2 0x0e6d -+#define RTL8367C_SVLAN_C2SCFG121_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG121_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG122_CTRL0 0x0e6e -+#define RTL8367C_SVLAN_C2SCFG122_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG122_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG122_CTRL1 0x0e6f -+#define RTL8367C_SVLAN_C2SCFG122_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG122_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG122_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG122_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG122_CTRL2 0x0e70 -+#define RTL8367C_SVLAN_C2SCFG122_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG122_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG123_CTRL0 0x0e71 -+#define RTL8367C_SVLAN_C2SCFG123_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG123_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG123_CTRL1 0x0e72 -+#define RTL8367C_SVLAN_C2SCFG123_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG123_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG123_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG123_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG123_CTRL2 0x0e73 -+#define RTL8367C_SVLAN_C2SCFG123_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG123_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG124_CTRL0 0x0e74 -+#define RTL8367C_SVLAN_C2SCFG124_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG124_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG124_CTRL1 0x0e75 -+#define RTL8367C_SVLAN_C2SCFG124_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG124_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG124_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG124_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG124_CTRL2 0x0e76 -+#define RTL8367C_SVLAN_C2SCFG124_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG124_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG125_CTRL0 0x0e77 -+#define RTL8367C_SVLAN_C2SCFG125_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG125_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG125_CTRL1 0x0e78 -+#define RTL8367C_SVLAN_C2SCFG125_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG125_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG125_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG125_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG125_CTRL2 0x0e79 -+#define RTL8367C_SVLAN_C2SCFG125_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG125_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG126_CTRL0 0x0e7a -+#define RTL8367C_SVLAN_C2SCFG126_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG126_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG126_CTRL1 0x0e7b -+#define RTL8367C_SVLAN_C2SCFG126_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG126_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG126_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG126_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG126_CTRL2 0x0e7c -+#define RTL8367C_SVLAN_C2SCFG126_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG126_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG127_CTRL0 0x0e7d -+#define RTL8367C_SVLAN_C2SCFG127_CTRL0_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG127_CTRL0_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_C2SCFG127_CTRL1 0x0e7e -+#define RTL8367C_SVLAN_C2SCFG127_CTRL1_C2SENPMSK_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_C2SCFG127_CTRL1_C2SENPMSK_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_C2SCFG127_CTRL1_C2SENPMSK_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG127_CTRL1_C2SENPMSK_MASK 0xFF -+ -+#define RTL8367C_REG_SVLAN_C2SCFG127_CTRL2 0x0e7f -+#define RTL8367C_SVLAN_C2SCFG127_CTRL2_OFFSET 0 -+#define RTL8367C_SVLAN_C2SCFG127_CTRL2_MASK 0x1FFF -+ -+#define RTL8367C_REG_SVLAN_CFG 0x0e80 -+#define RTL8367C_VS_PORT7_DMACVIDSEL_OFFSET 14 -+#define RTL8367C_VS_PORT7_DMACVIDSEL_MASK 0x4000 -+#define RTL8367C_VS_PORT6_DMACVIDSEL_OFFSET 13 -+#define RTL8367C_VS_PORT6_DMACVIDSEL_MASK 0x2000 -+#define RTL8367C_VS_PORT5_DMACVIDSEL_OFFSET 12 -+#define RTL8367C_VS_PORT5_DMACVIDSEL_MASK 0x1000 -+#define RTL8367C_VS_PORT4_DMACVIDSEL_OFFSET 11 -+#define RTL8367C_VS_PORT4_DMACVIDSEL_MASK 0x800 -+#define RTL8367C_VS_PORT3_DMACVIDSEL_OFFSET 10 -+#define RTL8367C_VS_PORT3_DMACVIDSEL_MASK 0x400 -+#define RTL8367C_VS_PORT2_DMACVIDSEL_OFFSET 9 -+#define RTL8367C_VS_PORT2_DMACVIDSEL_MASK 0x200 -+#define RTL8367C_VS_PORT1_DMACVIDSEL_OFFSET 8 -+#define RTL8367C_VS_PORT1_DMACVIDSEL_MASK 0x100 -+#define RTL8367C_VS_PORT0_DMACVIDSEL_OFFSET 7 -+#define RTL8367C_VS_PORT0_DMACVIDSEL_MASK 0x80 -+#define RTL8367C_VS_UIFSEG_OFFSET 6 -+#define RTL8367C_VS_UIFSEG_MASK 0x40 -+#define RTL8367C_VS_UNMAT_OFFSET 4 -+#define RTL8367C_VS_UNMAT_MASK 0x30 -+#define RTL8367C_VS_UNTAG_OFFSET 2 -+#define RTL8367C_VS_UNTAG_MASK 0xC -+#define RTL8367C_VS_SPRISEL_OFFSET 0 -+#define RTL8367C_VS_SPRISEL_MASK 0x3 -+ -+#define RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL0 0x0e81 -+#define RTL8367C_VS_PORT1_SVIDX_OFFSET 8 -+#define RTL8367C_VS_PORT1_SVIDX_MASK 0x3F00 -+#define RTL8367C_VS_PORT0_SVIDX_OFFSET 0 -+#define RTL8367C_VS_PORT0_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL1 0x0e82 -+#define RTL8367C_VS_PORT3_SVIDX_OFFSET 8 -+#define RTL8367C_VS_PORT3_SVIDX_MASK 0x3F00 -+#define RTL8367C_VS_PORT2_SVIDX_OFFSET 0 -+#define RTL8367C_VS_PORT2_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL2 0x0e83 -+#define RTL8367C_VS_PORT5_SVIDX_OFFSET 8 -+#define RTL8367C_VS_PORT5_SVIDX_MASK 0x3F00 -+#define RTL8367C_VS_PORT4_SVIDX_OFFSET 0 -+#define RTL8367C_VS_PORT4_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL3 0x0e84 -+#define RTL8367C_VS_PORT7_SVIDX_OFFSET 8 -+#define RTL8367C_VS_PORT7_SVIDX_MASK 0x3F00 -+#define RTL8367C_VS_PORT6_SVIDX_OFFSET 0 -+#define RTL8367C_VS_PORT6_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_UNTAG_UNMAT_CFG 0x0e85 -+#define RTL8367C_VS_UNTAG_SVIDX_OFFSET 8 -+#define RTL8367C_VS_UNTAG_SVIDX_MASK 0x3F00 -+#define RTL8367C_VS_UNMAT_SVIDX_OFFSET 0 -+#define RTL8367C_VS_UNMAT_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_LOOKUP_TYPE 0x0e86 -+#define RTL8367C_SVLAN_LOOKUP_TYPE_OFFSET 0 -+#define RTL8367C_SVLAN_LOOKUP_TYPE_MASK 0x1 -+ -+#define RTL8367C_REG_IPMC_GROUP_VALID_15_0 0x0e87 -+ -+#define RTL8367C_REG_IPMC_GROUP_VALID_31_16 0x0e88 -+ -+#define RTL8367C_REG_IPMC_GROUP_VALID_47_32 0x0e89 -+ -+#define RTL8367C_REG_IPMC_GROUP_VALID_63_48 0x0e8a -+ -+#define RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL4 0x0e8b -+#define RTL8367C_VS_PORT9_SVIDX_OFFSET 8 -+#define RTL8367C_VS_PORT9_SVIDX_MASK 0x3F00 -+#define RTL8367C_VS_PORT8_SVIDX_OFFSET 0 -+#define RTL8367C_VS_PORT8_SVIDX_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL5 0x0e8c -+#define RTL8367C_SVLAN_PORTBASED_SVIDX_CTRL5_OFFSET 0 -+#define RTL8367C_SVLAN_PORTBASED_SVIDX_CTRL5_MASK 0x3F -+ -+#define RTL8367C_REG_SVLAN_CFG_EXT 0x0e8d -+#define RTL8367C_VS_PORT10_DMACVIDSEL_OFFSET 2 -+#define RTL8367C_VS_PORT10_DMACVIDSEL_MASK 0x4 -+#define RTL8367C_VS_PORT9_DMACVIDSEL_OFFSET 1 -+#define RTL8367C_VS_PORT9_DMACVIDSEL_MASK 0x2 -+#define RTL8367C_VS_PORT8_DMACVIDSEL_OFFSET 0 -+#define RTL8367C_VS_PORT8_DMACVIDSEL_MASK 0x1 -+ -+#define RTL8367C_REG_SVLAN_MEMBERCFG63_CTRL4 0x0e8e -+#define RTL8367C_SVLAN_MEMBERCFG63_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 -+#define RTL8367C_SVLAN_MEMBERCFG63_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 -+#define RTL8367C_SVLAN_MEMBERCFG63_CTRL4_VS_SMBR_EXT_OFFSET 0 -+#define RTL8367C_SVLAN_MEMBERCFG63_CTRL4_VS_SMBR_EXT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_DUMMY_0 0x0e90 -+ -+#define RTL8367C_REG_SVLAN_DUMMY_1 0x0e91 -+ -+#define RTL8367C_REG_SVLAN_DUMMY_2 0x0e92 -+ -+#define RTL8367C_REG_SVLAN_DUMMY_3 0x0e93 -+ -+#define RTL8367C_REG_SVLAN_DUMMY_4 0x0e94 -+ -+#define RTL8367C_REG_SVLAN_DUMMY_5 0x0e95 -+ -+#define RTL8367C_REG_SVLAN_DUMMY_6 0x0e96 -+ -+#define RTL8367C_REG_SVLAN_DUMMY_7 0x0e97 -+ -+#define RTL8367C_REG_SVLAN_DUMMY_8 0x0e98 -+ -+#define RTL8367C_REG_SVLAN_DUMMY_9 0x0e99 -+ -+#define RTL8367C_REG_SVLAN_DUMMY_10 0x0e9a -+ -+#define RTL8367C_REG_SVLAN_DUMMY_11 0x0e9b -+ -+#define RTL8367C_REG_SVLAN_DUMMY_12 0x0e9c -+ -+#define RTL8367C_REG_SVLAN_DUMMY_13 0x0e9d -+ -+#define RTL8367C_REG_SVLAN_DUMMY_14 0x0e9e -+ -+#define RTL8367C_REG_SVLAN_DUMMY_15 0x0e9f -+ -+#define RTL8367C_REG_SVLAN_DUMMY_16 0x0ea0 -+ -+#define RTL8367C_REG_SVLAN_DUMMY_17 0x0ea1 -+ -+#define RTL8367C_REG_SVLAN_DUMMY_18 0x0ea2 -+ -+#define RTL8367C_REG_SVLAN_DUMMY_19 0x0ea3 -+ -+#define RTL8367C_REG_SVLAN_DUMMY_20 0x0ea4 -+ -+#define RTL8367C_REG_SVLAN_DUMMY_21 0x0ea5 -+ -+#define RTL8367C_REG_SVLAN_DUMMY_22 0x0ea6 -+ -+#define RTL8367C_REG_SVLAN_DUMMY_23 0x0ea7 -+ -+#define RTL8367C_REG_SVLAN_DUMMY_24 0x0ea8 -+ -+#define RTL8367C_REG_SVLAN_DUMMY_25 0x0ea9 -+ -+#define RTL8367C_REG_SVLAN_DUMMY_26 0x0eaa -+ -+#define RTL8367C_REG_SVLAN_DUMMY_27 0x0eab -+ -+#define RTL8367C_REG_SVLAN_DUMMY_28 0x0eac -+ -+#define RTL8367C_REG_SVLAN_DUMMY_29 0x0ead -+ -+#define RTL8367C_REG_SVLAN_DUMMY_30 0x0eae -+ -+#define RTL8367C_REG_SVLAN_DUMMY_31 0x0eaf -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_00 0x0eb0 -+#define RTL8367C_IPMC_GROUP_VID_00_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_00_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_01 0x0eb1 -+#define RTL8367C_IPMC_GROUP_VID_01_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_01_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_02 0x0eb2 -+#define RTL8367C_IPMC_GROUP_VID_02_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_02_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_03 0x0eb3 -+#define RTL8367C_IPMC_GROUP_VID_03_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_03_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_04 0x0eb4 -+#define RTL8367C_IPMC_GROUP_VID_04_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_04_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_05 0x0eb5 -+#define RTL8367C_IPMC_GROUP_VID_05_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_05_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_06 0x0eb6 -+#define RTL8367C_IPMC_GROUP_VID_06_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_06_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_07 0x0eb7 -+#define RTL8367C_IPMC_GROUP_VID_07_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_07_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_08 0x0eb8 -+#define RTL8367C_IPMC_GROUP_VID_08_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_08_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_09 0x0eb9 -+#define RTL8367C_IPMC_GROUP_VID_09_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_09_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_10 0x0eba -+#define RTL8367C_IPMC_GROUP_VID_10_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_10_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_11 0x0ebb -+#define RTL8367C_IPMC_GROUP_VID_11_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_11_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_12 0x0ebc -+#define RTL8367C_IPMC_GROUP_VID_12_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_12_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_13 0x0ebd -+#define RTL8367C_IPMC_GROUP_VID_13_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_13_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_14 0x0ebe -+#define RTL8367C_IPMC_GROUP_VID_14_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_14_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_15 0x0ebf -+#define RTL8367C_IPMC_GROUP_VID_15_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_15_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_16 0x0ec0 -+#define RTL8367C_IPMC_GROUP_VID_16_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_16_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_17 0x0ec1 -+#define RTL8367C_IPMC_GROUP_VID_17_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_17_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_18 0x0ec2 -+#define RTL8367C_IPMC_GROUP_VID_18_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_18_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_19 0x0ec3 -+#define RTL8367C_IPMC_GROUP_VID_19_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_19_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_20 0x0ec4 -+#define RTL8367C_IPMC_GROUP_VID_20_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_20_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_21 0x0ec5 -+#define RTL8367C_IPMC_GROUP_VID_21_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_21_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_22 0x0ec6 -+#define RTL8367C_IPMC_GROUP_VID_22_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_22_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_23 0x0ec7 -+#define RTL8367C_IPMC_GROUP_VID_23_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_23_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_24 0x0ec8 -+#define RTL8367C_IPMC_GROUP_VID_24_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_24_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_25 0x0ec9 -+#define RTL8367C_IPMC_GROUP_VID_25_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_25_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_26 0x0eca -+#define RTL8367C_IPMC_GROUP_VID_26_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_26_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_27 0x0ecb -+#define RTL8367C_IPMC_GROUP_VID_27_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_27_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_28 0x0ecc -+#define RTL8367C_IPMC_GROUP_VID_28_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_28_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_29 0x0ecd -+#define RTL8367C_IPMC_GROUP_VID_29_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_29_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_30 0x0ece -+#define RTL8367C_IPMC_GROUP_VID_30_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_30_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_31 0x0ecf -+#define RTL8367C_IPMC_GROUP_VID_31_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_31_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_32 0x0ed0 -+#define RTL8367C_IPMC_GROUP_VID_32_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_32_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_33 0x0ed1 -+#define RTL8367C_IPMC_GROUP_VID_33_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_33_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_34 0x0ed2 -+#define RTL8367C_IPMC_GROUP_VID_34_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_34_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_35 0x0ed3 -+#define RTL8367C_IPMC_GROUP_VID_35_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_35_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_36 0x0ed4 -+#define RTL8367C_IPMC_GROUP_VID_36_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_36_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_37 0x0ed5 -+#define RTL8367C_IPMC_GROUP_VID_37_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_37_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_38 0x0ed6 -+#define RTL8367C_IPMC_GROUP_VID_38_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_38_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_39 0x0ed7 -+#define RTL8367C_IPMC_GROUP_VID_39_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_39_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_40 0x0ed8 -+#define RTL8367C_IPMC_GROUP_VID_40_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_40_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_41 0x0ed9 -+#define RTL8367C_IPMC_GROUP_VID_41_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_41_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_42 0x0eda -+#define RTL8367C_IPMC_GROUP_VID_42_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_42_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_43 0x0edb -+#define RTL8367C_IPMC_GROUP_VID_43_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_43_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_44 0x0edc -+#define RTL8367C_IPMC_GROUP_VID_44_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_44_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_45 0x0edd -+#define RTL8367C_IPMC_GROUP_VID_45_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_45_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_46 0x0ede -+#define RTL8367C_IPMC_GROUP_VID_46_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_46_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_47 0x0edf -+#define RTL8367C_IPMC_GROUP_VID_47_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_47_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_48 0x0ef0 -+#define RTL8367C_IPMC_GROUP_VID_48_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_48_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_49 0x0ef1 -+#define RTL8367C_IPMC_GROUP_VID_49_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_49_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_50 0x0ef2 -+#define RTL8367C_IPMC_GROUP_VID_50_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_50_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_51 0x0ef3 -+#define RTL8367C_IPMC_GROUP_VID_51_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_51_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_52 0x0ef4 -+#define RTL8367C_IPMC_GROUP_VID_52_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_52_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_53 0x0ef5 -+#define RTL8367C_IPMC_GROUP_VID_53_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_53_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_54 0x0ef6 -+#define RTL8367C_IPMC_GROUP_VID_54_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_54_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_55 0x0ef7 -+#define RTL8367C_IPMC_GROUP_VID_55_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_55_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_56 0x0ef8 -+#define RTL8367C_IPMC_GROUP_VID_56_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_56_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_57 0x0ef9 -+#define RTL8367C_IPMC_GROUP_VID_57_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_57_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_58 0x0efa -+#define RTL8367C_IPMC_GROUP_VID_58_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_58_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_59 0x0efb -+#define RTL8367C_IPMC_GROUP_VID_59_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_59_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_60 0x0efc -+#define RTL8367C_IPMC_GROUP_VID_60_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_60_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_61 0x0efd -+#define RTL8367C_IPMC_GROUP_VID_61_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_61_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_62 0x0efe -+#define RTL8367C_IPMC_GROUP_VID_62_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_62_MASK 0xFFF -+ -+#define RTL8367C_REG_IPMC_GROUP_VID_63 0x0eff -+#define RTL8367C_IPMC_GROUP_VID_63_OFFSET 0 -+#define RTL8367C_IPMC_GROUP_VID_63_MASK 0xFFF -+ -+/* (16'h0f00)hsactrl_reg */ -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY0_CTRL0 0x0f00 -+#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY0_CTRL1 0x0f01 -+#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY1_CTRL0 0x0f02 -+#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY1_CTRL1 0x0f03 -+#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY2_CTRL0 0x0f04 -+#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY2_CTRL1 0x0f05 -+#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY3_CTRL0 0x0f06 -+#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY3_CTRL1 0x0f07 -+#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY4_CTRL0 0x0f08 -+#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY4_CTRL1 0x0f09 -+#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY5_CTRL0 0x0f0a -+#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY5_CTRL1 0x0f0b -+#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY6_CTRL0 0x0f0c -+#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY6_CTRL1 0x0f0d -+#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY7_CTRL0 0x0f0e -+#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY7_CTRL1 0x0f0f -+#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY8_CTRL0 0x0f10 -+#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY8_CTRL1 0x0f11 -+#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY9_CTRL0 0x0f12 -+#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY9_CTRL1 0x0f13 -+#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY10_CTRL0 0x0f14 -+#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY10_CTRL1 0x0f15 -+#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY11_CTRL0 0x0f16 -+#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY11_CTRL1 0x0f17 -+#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY12_CTRL0 0x0f18 -+#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY12_CTRL1 0x0f19 -+#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY13_CTRL0 0x0f1a -+#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY13_CTRL1 0x0f1b -+#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY14_CTRL0 0x0f1c -+#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY14_CTRL1 0x0f1d -+#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY15_CTRL0 0x0f1e -+#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY15_CTRL1 0x0f1f -+#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY16_CTRL0 0x0f20 -+#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY16_CTRL1 0x0f21 -+#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY17_CTRL0 0x0f22 -+#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY17_CTRL1 0x0f23 -+#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY18_CTRL0 0x0f24 -+#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY18_CTRL1 0x0f25 -+#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY19_CTRL0 0x0f26 -+#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY19_CTRL1 0x0f27 -+#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY20_CTRL0 0x0f28 -+#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY20_CTRL1 0x0f29 -+#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY21_CTRL0 0x0f2a -+#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY21_CTRL1 0x0f2b -+#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY22_CTRL0 0x0f2c -+#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY22_CTRL1 0x0f2d -+#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY23_CTRL0 0x0f2e -+#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY23_CTRL1 0x0f2f -+#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY24_CTRL0 0x0f30 -+#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY24_CTRL1 0x0f31 -+#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY25_CTRL0 0x0f32 -+#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY25_CTRL1 0x0f33 -+#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY26_CTRL0 0x0f34 -+#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY26_CTRL1 0x0f35 -+#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY27_CTRL0 0x0f36 -+#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY27_CTRL1 0x0f37 -+#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY28_CTRL0 0x0f38 -+#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY28_CTRL1 0x0f39 -+#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY29_CTRL0 0x0f3a -+#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY29_CTRL1 0x0f3b -+#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY30_CTRL0 0x0f3c -+#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY30_CTRL1 0x0f3d -+#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY31_CTRL0 0x0f3e -+#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY31_CTRL1 0x0f3f -+#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY32_CTRL0 0x0f40 -+#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY32_CTRL1 0x0f41 -+#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY33_CTRL0 0x0f42 -+#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY33_CTRL1 0x0f43 -+#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY34_CTRL0 0x0f44 -+#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY34_CTRL1 0x0f45 -+#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY35_CTRL0 0x0f46 -+#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY35_CTRL1 0x0f47 -+#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY36_CTRL0 0x0f48 -+#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY36_CTRL1 0x0f49 -+#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY37_CTRL0 0x0f4a -+#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY37_CTRL1 0x0f4b -+#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY38_CTRL0 0x0f4c -+#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY38_CTRL1 0x0f4d -+#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY39_CTRL0 0x0f4e -+#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY39_CTRL1 0x0f4f -+#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY40_CTRL0 0x0f50 -+#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY40_CTRL1 0x0f51 -+#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY41_CTRL0 0x0f52 -+#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY41_CTRL1 0x0f53 -+#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY42_CTRL0 0x0f54 -+#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY42_CTRL1 0x0f55 -+#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY43_CTRL0 0x0f56 -+#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY43_CTRL1 0x0f57 -+#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY44_CTRL0 0x0f58 -+#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY44_CTRL1 0x0f59 -+#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY45_CTRL0 0x0f5a -+#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY45_CTRL1 0x0f5b -+#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY46_CTRL0 0x0f5c -+#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY46_CTRL1 0x0f5d -+#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY47_CTRL0 0x0f5e -+#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY47_CTRL1 0x0f5f -+#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY48_CTRL0 0x0f60 -+#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY48_CTRL1 0x0f61 -+#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY49_CTRL0 0x0f62 -+#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY49_CTRL1 0x0f63 -+#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY50_CTRL0 0x0f64 -+#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY50_CTRL1 0x0f65 -+#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY51_CTRL0 0x0f66 -+#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY51_CTRL1 0x0f67 -+#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY52_CTRL0 0x0f68 -+#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY52_CTRL1 0x0f69 -+#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY53_CTRL0 0x0f6a -+#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY53_CTRL1 0x0f6b -+#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY54_CTRL0 0x0f6c -+#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY54_CTRL1 0x0f6d -+#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY55_CTRL0 0x0f6e -+#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY55_CTRL1 0x0f6f -+#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY56_CTRL0 0x0f70 -+#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY56_CTRL1 0x0f71 -+#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY57_CTRL0 0x0f72 -+#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY57_CTRL1 0x0f73 -+#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY58_CTRL0 0x0f74 -+#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY58_CTRL1 0x0f75 -+#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY59_CTRL0 0x0f76 -+#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY59_CTRL1 0x0f77 -+#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY60_CTRL0 0x0f78 -+#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY60_CTRL1 0x0f79 -+#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY61_CTRL0 0x0f7a -+#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY61_CTRL1 0x0f7b -+#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY62_CTRL0 0x0f7c -+#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY62_CTRL1 0x0f7d -+#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY63_CTRL0 0x0f7e -+#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY63_CTRL1 0x0f7f -+#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY64_CTRL0 0x0f80 -+#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY64_CTRL1 0x0f81 -+#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY65_CTRL0 0x0f82 -+#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY65_CTRL1 0x0f83 -+#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY66_CTRL0 0x0f84 -+#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY66_CTRL1 0x0f85 -+#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY67_CTRL0 0x0f86 -+#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY67_CTRL1 0x0f87 -+#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY68_CTRL0 0x0f88 -+#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY68_CTRL1 0x0f89 -+#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY69_CTRL0 0x0f8a -+#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY69_CTRL1 0x0f8b -+#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY70_CTRL0 0x0f8c -+#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY70_CTRL1 0x0f8d -+#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY71_CTRL0 0x0f8e -+#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY71_CTRL1 0x0f8f -+#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY72_CTRL0 0x0f90 -+#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY72_CTRL1 0x0f91 -+#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY73_CTRL0 0x0f92 -+#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY73_CTRL1 0x0f93 -+#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY74_CTRL0 0x0f94 -+#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY74_CTRL1 0x0f95 -+#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY75_CTRL0 0x0f96 -+#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY75_CTRL1 0x0f97 -+#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY76_CTRL0 0x0f98 -+#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY76_CTRL1 0x0f99 -+#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY77_CTRL0 0x0f9a -+#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY77_CTRL1 0x0f9b -+#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY78_CTRL0 0x0f9c -+#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY78_CTRL1 0x0f9d -+#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY79_CTRL0 0x0f9e -+#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY79_CTRL1 0x0f9f -+#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY80_CTRL0 0x0fa0 -+#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY80_CTRL1 0x0fa1 -+#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY81_CTRL0 0x0fa2 -+#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY81_CTRL1 0x0fa3 -+#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY82_CTRL0 0x0fa4 -+#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY82_CTRL1 0x0fa5 -+#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY83_CTRL0 0x0fa6 -+#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY83_CTRL1 0x0fa7 -+#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY84_CTRL0 0x0fa8 -+#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY84_CTRL1 0x0fa9 -+#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY85_CTRL0 0x0faa -+#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY85_CTRL1 0x0fab -+#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY86_CTRL0 0x0fac -+#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY86_CTRL1 0x0fad -+#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY87_CTRL0 0x0fae -+#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY87_CTRL1 0x0faf -+#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY88_CTRL0 0x0fb0 -+#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY88_CTRL1 0x0fb1 -+#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY89_CTRL0 0x0fb2 -+#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY89_CTRL1 0x0fb3 -+#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY90_CTRL0 0x0fb4 -+#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY90_CTRL1 0x0fb5 -+#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY91_CTRL0 0x0fb6 -+#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY91_CTRL1 0x0fb7 -+#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY92_CTRL0 0x0fb8 -+#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY92_CTRL1 0x0fb9 -+#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY93_CTRL0 0x0fba -+#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY93_CTRL1 0x0fbb -+#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY94_CTRL0 0x0fbc -+#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY94_CTRL1 0x0fbd -+#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY95_CTRL0 0x0fbe -+#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY95_CTRL1 0x0fbf -+#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY96_CTRL0 0x0fc0 -+#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY96_CTRL1 0x0fc1 -+#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY97_CTRL0 0x0fc2 -+#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY97_CTRL1 0x0fc3 -+#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY98_CTRL0 0x0fc4 -+#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY98_CTRL1 0x0fc5 -+#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY99_CTRL0 0x0fc6 -+#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY99_CTRL1 0x0fc7 -+#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY100_CTRL0 0x0fc8 -+#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY100_CTRL1 0x0fc9 -+#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY101_CTRL0 0x0fca -+#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY101_CTRL1 0x0fcb -+#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY102_CTRL0 0x0fcc -+#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY102_CTRL1 0x0fcd -+#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY103_CTRL0 0x0fce -+#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY103_CTRL1 0x0fcf -+#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY104_CTRL0 0x0fd0 -+#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY104_CTRL1 0x0fd1 -+#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY105_CTRL0 0x0fd2 -+#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY105_CTRL1 0x0fd3 -+#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY106_CTRL0 0x0fd4 -+#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY106_CTRL1 0x0fd5 -+#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY107_CTRL0 0x0fd6 -+#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY107_CTRL1 0x0fd7 -+#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY108_CTRL0 0x0fd8 -+#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY108_CTRL1 0x0fd9 -+#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY109_CTRL0 0x0fda -+#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY109_CTRL1 0x0fdb -+#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY110_CTRL0 0x0fdc -+#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY110_CTRL1 0x0fdd -+#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY111_CTRL0 0x0fde -+#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY111_CTRL1 0x0fdf -+#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY112_CTRL0 0x0fe0 -+#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY112_CTRL1 0x0fe1 -+#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY113_CTRL0 0x0fe2 -+#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY113_CTRL1 0x0fe3 -+#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY114_CTRL0 0x0fe4 -+#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY114_CTRL1 0x0fe5 -+#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY115_CTRL0 0x0fe6 -+#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY115_CTRL1 0x0fe7 -+#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY116_CTRL0 0x0fe8 -+#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY116_CTRL1 0x0fe9 -+#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY117_CTRL0 0x0fea -+#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY117_CTRL1 0x0feb -+#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY118_CTRL0 0x0fec -+#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY118_CTRL1 0x0fed -+#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY119_CTRL0 0x0fee -+#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY119_CTRL1 0x0fef -+#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY120_CTRL0 0x0ff0 -+#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY120_CTRL1 0x0ff1 -+#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY121_CTRL0 0x0ff2 -+#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY121_CTRL1 0x0ff3 -+#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY122_CTRL0 0x0ff4 -+#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY122_CTRL1 0x0ff5 -+#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY123_CTRL0 0x0ff6 -+#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY123_CTRL1 0x0ff7 -+#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY124_CTRL0 0x0ff8 -+#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY124_CTRL1 0x0ff9 -+#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY125_CTRL0 0x0ffa -+#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY125_CTRL1 0x0ffb -+#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY126_CTRL0 0x0ffc -+#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY126_CTRL1 0x0ffd -+#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL1_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY127_CTRL0 0x0ffe -+#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL0_DST_PORT1_OFFSET 9 -+#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL0_DST_PORT1_MASK 0x200 -+#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL0_SVIDX_OFFSET 3 -+#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL0_SVIDX_MASK 0x1F8 -+#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL0_DST_PORT_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL0_DST_PORT_MASK 0x7 -+ -+#define RTL8367C_REG_SVLAN_SP2C_ENTRY127_CTRL1 0x0fff -+#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL1_VALID_OFFSET 12 -+#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL1_VALID_MASK 0x1000 -+#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL1_VID_OFFSET 0 -+#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL1_VID_MASK 0xFFF -+ -+/* (16'h1000)mib_reg */ -+ -+#define RTL8367C_REG_MIB_COUNTER0 0x1000 -+ -+#define RTL8367C_REG_MIB_COUNTER1 0x1001 -+ -+#define RTL8367C_REG_MIB_COUNTER2 0x1002 -+ -+#define RTL8367C_REG_MIB_COUNTER3 0x1003 -+ -+#define RTL8367C_REG_MIB_ADDRESS 0x1004 -+#define RTL8367C_MIB_ADDRESS_OFFSET 0 -+#define RTL8367C_MIB_ADDRESS_MASK 0x1FF -+ -+#define RTL8367C_REG_MIB_CTRL0 0x1005 -+#define RTL8367C_PORT10_RESET_OFFSET 15 -+#define RTL8367C_PORT10_RESET_MASK 0x8000 -+#define RTL8367C_PORT9_RESET_OFFSET 14 -+#define RTL8367C_PORT9_RESET_MASK 0x4000 -+#define RTL8367C_PORT8_RESET_OFFSET 13 -+#define RTL8367C_PORT8_RESET_MASK 0x2000 -+#define RTL8367C_RESET_VALUE_OFFSET 12 -+#define RTL8367C_RESET_VALUE_MASK 0x1000 -+#define RTL8367C_GLOBAL_RESET_OFFSET 11 -+#define RTL8367C_GLOBAL_RESET_MASK 0x800 -+#define RTL8367C_QM_RESET_OFFSET 10 -+#define RTL8367C_QM_RESET_MASK 0x400 -+#define RTL8367C_PORT7_RESET_OFFSET 9 -+#define RTL8367C_PORT7_RESET_MASK 0x200 -+#define RTL8367C_PORT6_RESET_OFFSET 8 -+#define RTL8367C_PORT6_RESET_MASK 0x100 -+#define RTL8367C_PORT5_RESET_OFFSET 7 -+#define RTL8367C_PORT5_RESET_MASK 0x80 -+#define RTL8367C_PORT4_RESET_OFFSET 6 -+#define RTL8367C_PORT4_RESET_MASK 0x40 -+#define RTL8367C_PORT3_RESET_OFFSET 5 -+#define RTL8367C_PORT3_RESET_MASK 0x20 -+#define RTL8367C_PORT2_RESET_OFFSET 4 -+#define RTL8367C_PORT2_RESET_MASK 0x10 -+#define RTL8367C_PORT1_RESET_OFFSET 3 -+#define RTL8367C_PORT1_RESET_MASK 0x8 -+#define RTL8367C_PORT0_RESET_OFFSET 2 -+#define RTL8367C_PORT0_RESET_MASK 0x4 -+#define RTL8367C_RESET_FLAG_OFFSET 1 -+#define RTL8367C_RESET_FLAG_MASK 0x2 -+#define RTL8367C_MIB_CTRL0_BUSY_FLAG_OFFSET 0 -+#define RTL8367C_MIB_CTRL0_BUSY_FLAG_MASK 0x1 -+ -+#define RTL8367C_REG_MIB_CTRL1 0x1007 -+#define RTL8367C_COUNTER15_RESET_OFFSET 15 -+#define RTL8367C_COUNTER15_RESET_MASK 0x8000 -+#define RTL8367C_COUNTER14_RESET_OFFSET 14 -+#define RTL8367C_COUNTER14_RESET_MASK 0x4000 -+#define RTL8367C_COUNTER13_RESET_OFFSET 13 -+#define RTL8367C_COUNTER13_RESET_MASK 0x2000 -+#define RTL8367C_COUNTER12_RESET_OFFSET 12 -+#define RTL8367C_COUNTER12_RESET_MASK 0x1000 -+#define RTL8367C_COUNTER11_RESET_OFFSET 11 -+#define RTL8367C_COUNTER11_RESET_MASK 0x800 -+#define RTL8367C_COUNTER10_RESET_OFFSET 10 -+#define RTL8367C_COUNTER10_RESET_MASK 0x400 -+#define RTL8367C_COUNTER9_RESET_OFFSET 9 -+#define RTL8367C_COUNTER9_RESET_MASK 0x200 -+#define RTL8367C_COUNTER8_RESET_OFFSET 8 -+#define RTL8367C_COUNTER8_RESET_MASK 0x100 -+#define RTL8367C_COUNTER7_RESET_OFFSET 7 -+#define RTL8367C_COUNTER7_RESET_MASK 0x80 -+#define RTL8367C_COUNTER6_RESET_OFFSET 6 -+#define RTL8367C_COUNTER6_RESET_MASK 0x40 -+#define RTL8367C_COUNTER5_RESET_OFFSET 5 -+#define RTL8367C_COUNTER5_RESET_MASK 0x20 -+#define RTL8367C_COUNTER4_RESET_OFFSET 4 -+#define RTL8367C_COUNTER4_RESET_MASK 0x10 -+#define RTL8367C_COUNTER3_RESET_OFFSET 3 -+#define RTL8367C_COUNTER3_RESET_MASK 0x8 -+#define RTL8367C_COUNTER2_RESET_OFFSET 2 -+#define RTL8367C_COUNTER2_RESET_MASK 0x4 -+#define RTL8367C_COUNTER1_RESET_OFFSET 1 -+#define RTL8367C_COUNTER1_RESET_MASK 0x2 -+#define RTL8367C_COUNTER0_RESET_OFFSET 0 -+#define RTL8367C_COUNTER0_RESET_MASK 0x1 -+ -+#define RTL8367C_REG_MIB_CTRL2 0x1008 -+#define RTL8367C_COUNTER31_RESET_OFFSET 15 -+#define RTL8367C_COUNTER31_RESET_MASK 0x8000 -+#define RTL8367C_COUNTER30_RESET_OFFSET 14 -+#define RTL8367C_COUNTER30_RESET_MASK 0x4000 -+#define RTL8367C_COUNTER29_RESET_OFFSET 13 -+#define RTL8367C_COUNTER29_RESET_MASK 0x2000 -+#define RTL8367C_COUNTER28_RESET_OFFSET 12 -+#define RTL8367C_COUNTER28_RESET_MASK 0x1000 -+#define RTL8367C_COUNTER27_RESET_OFFSET 11 -+#define RTL8367C_COUNTER27_RESET_MASK 0x800 -+#define RTL8367C_COUNTER26_RESET_OFFSET 10 -+#define RTL8367C_COUNTER26_RESET_MASK 0x400 -+#define RTL8367C_COUNTER25_RESET_OFFSET 9 -+#define RTL8367C_COUNTER25_RESET_MASK 0x200 -+#define RTL8367C_COUNTER24_RESET_OFFSET 8 -+#define RTL8367C_COUNTER24_RESET_MASK 0x100 -+#define RTL8367C_COUNTER23_RESET_OFFSET 7 -+#define RTL8367C_COUNTER23_RESET_MASK 0x80 -+#define RTL8367C_COUNTER22_RESET_OFFSET 6 -+#define RTL8367C_COUNTER22_RESET_MASK 0x40 -+#define RTL8367C_COUNTER21_RESET_OFFSET 5 -+#define RTL8367C_COUNTER21_RESET_MASK 0x20 -+#define RTL8367C_COUNTER20_RESET_OFFSET 4 -+#define RTL8367C_COUNTER20_RESET_MASK 0x10 -+#define RTL8367C_COUNTER19_RESET_OFFSET 3 -+#define RTL8367C_COUNTER19_RESET_MASK 0x8 -+#define RTL8367C_COUNTER18_RESET_OFFSET 2 -+#define RTL8367C_COUNTER18_RESET_MASK 0x4 -+#define RTL8367C_COUNTER17_RESET_OFFSET 1 -+#define RTL8367C_COUNTER17_RESET_MASK 0x2 -+#define RTL8367C_COUNTER16_RESET_OFFSET 0 -+#define RTL8367C_COUNTER16_RESET_MASK 0x1 -+ -+#define RTL8367C_REG_MIB_CTRL3 0x1009 -+#define RTL8367C_COUNTER15_MODE_OFFSET 15 -+#define RTL8367C_COUNTER15_MODE_MASK 0x8000 -+#define RTL8367C_COUNTER14_MODE_OFFSET 14 -+#define RTL8367C_COUNTER14_MODE_MASK 0x4000 -+#define RTL8367C_COUNTER13_MODE_OFFSET 13 -+#define RTL8367C_COUNTER13_MODE_MASK 0x2000 -+#define RTL8367C_COUNTER12_MODE_OFFSET 12 -+#define RTL8367C_COUNTER12_MODE_MASK 0x1000 -+#define RTL8367C_COUNTER11_MODE_OFFSET 11 -+#define RTL8367C_COUNTER11_MODE_MASK 0x800 -+#define RTL8367C_COUNTER10_MODE_OFFSET 10 -+#define RTL8367C_COUNTER10_MODE_MASK 0x400 -+#define RTL8367C_COUNTER9_MODE_OFFSET 9 -+#define RTL8367C_COUNTER9_MODE_MASK 0x200 -+#define RTL8367C_COUNTER8_MODE_OFFSET 8 -+#define RTL8367C_COUNTER8_MODE_MASK 0x100 -+#define RTL8367C_COUNTER7_MODE_OFFSET 7 -+#define RTL8367C_COUNTER7_MODE_MASK 0x80 -+#define RTL8367C_COUNTER6_MODE_OFFSET 6 -+#define RTL8367C_COUNTER6_MODE_MASK 0x40 -+#define RTL8367C_COUNTER5_MODE_OFFSET 5 -+#define RTL8367C_COUNTER5_MODE_MASK 0x20 -+#define RTL8367C_COUNTER4_MODE_OFFSET 4 -+#define RTL8367C_COUNTER4_MODE_MASK 0x10 -+#define RTL8367C_COUNTER3_MODE_OFFSET 3 -+#define RTL8367C_COUNTER3_MODE_MASK 0x8 -+#define RTL8367C_COUNTER2_MODE_OFFSET 2 -+#define RTL8367C_COUNTER2_MODE_MASK 0x4 -+#define RTL8367C_COUNTER1_MODE_OFFSET 1 -+#define RTL8367C_COUNTER1_MODE_MASK 0x2 -+#define RTL8367C_COUNTER0_MODE_OFFSET 0 -+#define RTL8367C_COUNTER0_MODE_MASK 0x1 -+ -+#define RTL8367C_REG_MIB_CTRL4 0x100a -+#define RTL8367C_MIB_USAGE_MODE_OFFSET 8 -+#define RTL8367C_MIB_USAGE_MODE_MASK 0x100 -+#define RTL8367C_MIB_TIMER_OFFSET 0 -+#define RTL8367C_MIB_TIMER_MASK 0xFF -+ -+#define RTL8367C_REG_MIB_CTRL5 0x100b -+#define RTL8367C_MIB_CTRL5_COUNTER15_TYPE_OFFSET 15 -+#define RTL8367C_MIB_CTRL5_COUNTER15_TYPE_MASK 0x8000 -+#define RTL8367C_MIB_CTRL5_COUNTER14_TYPE_OFFSET 14 -+#define RTL8367C_MIB_CTRL5_COUNTER14_TYPE_MASK 0x4000 -+#define RTL8367C_MIB_CTRL5_COUNTER13_TYPE_OFFSET 13 -+#define RTL8367C_MIB_CTRL5_COUNTER13_TYPE_MASK 0x2000 -+#define RTL8367C_MIB_CTRL5_COUNTER12_TYPE_OFFSET 12 -+#define RTL8367C_MIB_CTRL5_COUNTER12_TYPE_MASK 0x1000 -+#define RTL8367C_MIB_CTRL5_COUNTER11_TYPE_OFFSET 11 -+#define RTL8367C_MIB_CTRL5_COUNTER11_TYPE_MASK 0x800 -+#define RTL8367C_MIB_CTRL5_COUNTER10_TYPE_OFFSET 10 -+#define RTL8367C_MIB_CTRL5_COUNTER10_TYPE_MASK 0x400 -+#define RTL8367C_MIB_CTRL5_COUNTER9_TYPE_OFFSET 9 -+#define RTL8367C_MIB_CTRL5_COUNTER9_TYPE_MASK 0x200 -+#define RTL8367C_MIB_CTRL5_COUNTER8_TYPE_OFFSET 8 -+#define RTL8367C_MIB_CTRL5_COUNTER8_TYPE_MASK 0x100 -+#define RTL8367C_MIB_CTRL5_COUNTER7_TYPE_OFFSET 7 -+#define RTL8367C_MIB_CTRL5_COUNTER7_TYPE_MASK 0x80 -+#define RTL8367C_MIB_CTRL5_COUNTER6_TYPE_OFFSET 6 -+#define RTL8367C_MIB_CTRL5_COUNTER6_TYPE_MASK 0x40 -+#define RTL8367C_MIB_CTRL5_COUNTER5_TYPE_OFFSET 5 -+#define RTL8367C_MIB_CTRL5_COUNTER5_TYPE_MASK 0x20 -+#define RTL8367C_MIB_CTRL5_COUNTER4_TYPE_OFFSET 4 -+#define RTL8367C_MIB_CTRL5_COUNTER4_TYPE_MASK 0x10 -+#define RTL8367C_MIB_CTRL5_COUNTER3_TYPE_OFFSET 3 -+#define RTL8367C_MIB_CTRL5_COUNTER3_TYPE_MASK 0x8 -+#define RTL8367C_MIB_CTRL5_COUNTER2_TYPE_OFFSET 2 -+#define RTL8367C_MIB_CTRL5_COUNTER2_TYPE_MASK 0x4 -+#define RTL8367C_MIB_CTRL5_COUNTER1_TYPE_OFFSET 1 -+#define RTL8367C_MIB_CTRL5_COUNTER1_TYPE_MASK 0x2 -+#define RTL8367C_MIB_CTRL5_COUNTER0_TYPE_OFFSET 0 -+#define RTL8367C_MIB_CTRL5_COUNTER0_TYPE_MASK 0x1 -+ -+/* (16'h1100)intrpt_reg */ -+ -+#define RTL8367C_REG_INTR_CTRL 0x1100 -+#define RTL8367C_INTR_CTRL_OFFSET 0 -+#define RTL8367C_INTR_CTRL_MASK 0x1 -+ -+#define RTL8367C_REG_INTR_IMR 0x1101 -+#define RTL8367C_INTR_IMR_SLIENT_START_2_OFFSET 12 -+#define RTL8367C_INTR_IMR_SLIENT_START_2_MASK 0x1000 -+#define RTL8367C_INTR_IMR_SLIENT_START_OFFSET 11 -+#define RTL8367C_INTR_IMR_SLIENT_START_MASK 0x800 -+#define RTL8367C_INTR_IMR_ACL_ACTION_OFFSET 9 -+#define RTL8367C_INTR_IMR_ACL_ACTION_MASK 0x200 -+#define RTL8367C_INTR_IMR_CABLE_DIAG_FIN_OFFSET 8 -+#define RTL8367C_INTR_IMR_CABLE_DIAG_FIN_MASK 0x100 -+#define RTL8367C_INTR_IMR_INTERRUPT_8051_OFFSET 7 -+#define RTL8367C_INTR_IMR_INTERRUPT_8051_MASK 0x80 -+#define RTL8367C_INTR_IMR_LOOP_DETECTION_OFFSET 6 -+#define RTL8367C_INTR_IMR_LOOP_DETECTION_MASK 0x40 -+#define RTL8367C_INTR_IMR_GREEN_TIMER_OFFSET 5 -+#define RTL8367C_INTR_IMR_GREEN_TIMER_MASK 0x20 -+#define RTL8367C_INTR_IMR_SPECIAL_CONGEST_OFFSET 4 -+#define RTL8367C_INTR_IMR_SPECIAL_CONGEST_MASK 0x10 -+#define RTL8367C_INTR_IMR_SPEED_CHANGE_OFFSET 3 -+#define RTL8367C_INTR_IMR_SPEED_CHANGE_MASK 0x8 -+#define RTL8367C_INTR_IMR_LEARN_OVER_OFFSET 2 -+#define RTL8367C_INTR_IMR_LEARN_OVER_MASK 0x4 -+#define RTL8367C_INTR_IMR_METER_EXCEEDED_OFFSET 1 -+#define RTL8367C_INTR_IMR_METER_EXCEEDED_MASK 0x2 -+#define RTL8367C_INTR_IMR_LINK_CHANGE_OFFSET 0 -+#define RTL8367C_INTR_IMR_LINK_CHANGE_MASK 0x1 -+ -+#define RTL8367C_REG_INTR_IMS 0x1102 -+#define RTL8367C_INTR_IMS_SLIENT_START_2_OFFSET 12 -+#define RTL8367C_INTR_IMS_SLIENT_START_2_MASK 0x1000 -+#define RTL8367C_INTR_IMS_SLIENT_START_OFFSET 11 -+#define RTL8367C_INTR_IMS_SLIENT_START_MASK 0x800 -+#define RTL8367C_INTR_IMS_ACL_ACTION_OFFSET 9 -+#define RTL8367C_INTR_IMS_ACL_ACTION_MASK 0x200 -+#define RTL8367C_INTR_IMS_CABLE_DIAG_FIN_OFFSET 8 -+#define RTL8367C_INTR_IMS_CABLE_DIAG_FIN_MASK 0x100 -+#define RTL8367C_INTR_IMS_INTERRUPT_8051_OFFSET 7 -+#define RTL8367C_INTR_IMS_INTERRUPT_8051_MASK 0x80 -+#define RTL8367C_INTR_IMS_LOOP_DETECTION_OFFSET 6 -+#define RTL8367C_INTR_IMS_LOOP_DETECTION_MASK 0x40 -+#define RTL8367C_INTR_IMS_GREEN_TIMER_OFFSET 5 -+#define RTL8367C_INTR_IMS_GREEN_TIMER_MASK 0x20 -+#define RTL8367C_INTR_IMS_SPECIAL_CONGEST_OFFSET 4 -+#define RTL8367C_INTR_IMS_SPECIAL_CONGEST_MASK 0x10 -+#define RTL8367C_INTR_IMS_SPEED_CHANGE_OFFSET 3 -+#define RTL8367C_INTR_IMS_SPEED_CHANGE_MASK 0x8 -+#define RTL8367C_INTR_IMS_LEARN_OVER_OFFSET 2 -+#define RTL8367C_INTR_IMS_LEARN_OVER_MASK 0x4 -+#define RTL8367C_INTR_IMS_METER_EXCEEDED_OFFSET 1 -+#define RTL8367C_INTR_IMS_METER_EXCEEDED_MASK 0x2 -+#define RTL8367C_INTR_IMS_LINK_CHANGE_OFFSET 0 -+#define RTL8367C_INTR_IMS_LINK_CHANGE_MASK 0x1 -+ -+#define RTL8367C_REG_LEARN_OVER_INDICATOR 0x1103 -+#define RTL8367C_LEARN_OVER_INDICATOR_OFFSET 0 -+#define RTL8367C_LEARN_OVER_INDICATOR_MASK 0x7FF -+ -+#define RTL8367C_REG_SPEED_CHANGE_INDICATOR 0x1104 -+#define RTL8367C_SPEED_CHANGE_INDICATOR_OFFSET 0 -+#define RTL8367C_SPEED_CHANGE_INDICATOR_MASK 0x7FF -+ -+#define RTL8367C_REG_SPECIAL_CONGEST_INDICATOR 0x1105 -+#define RTL8367C_SPECIAL_CONGEST_INDICATOR_OFFSET 0 -+#define RTL8367C_SPECIAL_CONGEST_INDICATOR_MASK 0x7FF -+ -+#define RTL8367C_REG_PORT_LINKDOWN_INDICATOR 0x1106 -+#define RTL8367C_PORT_LINKDOWN_INDICATOR_OFFSET 0 -+#define RTL8367C_PORT_LINKDOWN_INDICATOR_MASK 0x7FF -+ -+#define RTL8367C_REG_PORT_LINKUP_INDICATOR 0x1107 -+#define RTL8367C_PORT_LINKUP_INDICATOR_OFFSET 0 -+#define RTL8367C_PORT_LINKUP_INDICATOR_MASK 0x7FF -+ -+#define RTL8367C_REG_SYSTEM_LEARN_OVER_INDICATOR 0x1108 -+#define RTL8367C_SYSTEM_LEARN_OVER_INDICATOR_OFFSET 0 -+#define RTL8367C_SYSTEM_LEARN_OVER_INDICATOR_MASK 0x1 -+ -+#define RTL8367C_REG_INTR_IMR_8051 0x1118 -+#define RTL8367C_INTR_IMR_8051_SLIENT_START_2_OFFSET 13 -+#define RTL8367C_INTR_IMR_8051_SLIENT_START_2_MASK 0x2000 -+#define RTL8367C_INTR_IMR_8051_SLIENT_START_OFFSET 12 -+#define RTL8367C_INTR_IMR_8051_SLIENT_START_MASK 0x1000 -+#define RTL8367C_INTR_IMR_8051_ACL_ACTION_OFFSET 10 -+#define RTL8367C_INTR_IMR_8051_ACL_ACTION_MASK 0x400 -+#define RTL8367C_INTR_IMR_8051_SAMOVING_8051_OFFSET 9 -+#define RTL8367C_INTR_IMR_8051_SAMOVING_8051_MASK 0x200 -+#define RTL8367C_INTR_IMR_8051_CABLE_DIAG_FIN_8051_OFFSET 8 -+#define RTL8367C_INTR_IMR_8051_CABLE_DIAG_FIN_8051_MASK 0x100 -+#define RTL8367C_INTR_IMR_8051_EEELLDP_8051_OFFSET 7 -+#define RTL8367C_INTR_IMR_8051_EEELLDP_8051_MASK 0x80 -+#define RTL8367C_INTR_IMR_8051_LOOP_DETECTION_8051_OFFSET 6 -+#define RTL8367C_INTR_IMR_8051_LOOP_DETECTION_8051_MASK 0x40 -+#define RTL8367C_INTR_IMR_8051_GREEN_TIMER_8051_OFFSET 5 -+#define RTL8367C_INTR_IMR_8051_GREEN_TIMER_8051_MASK 0x20 -+#define RTL8367C_INTR_IMR_8051_SPECIAL_CONGEST_8051_OFFSET 4 -+#define RTL8367C_INTR_IMR_8051_SPECIAL_CONGEST_8051_MASK 0x10 -+#define RTL8367C_INTR_IMR_8051_SPEED_CHANGE_8051_OFFSET 3 -+#define RTL8367C_INTR_IMR_8051_SPEED_CHANGE_8051_MASK 0x8 -+#define RTL8367C_INTR_IMR_8051_LEARN_OVER_8051_OFFSET 2 -+#define RTL8367C_INTR_IMR_8051_LEARN_OVER_8051_MASK 0x4 -+#define RTL8367C_INTR_IMR_8051_METER_EXCEEDED_8051_OFFSET 1 -+#define RTL8367C_INTR_IMR_8051_METER_EXCEEDED_8051_MASK 0x2 -+#define RTL8367C_INTR_IMR_8051_LINK_CHANGE_8051_OFFSET 0 -+#define RTL8367C_INTR_IMR_8051_LINK_CHANGE_8051_MASK 0x1 -+ -+#define RTL8367C_REG_INTR_IMS_8051 0x1119 -+#define RTL8367C_INTR_IMS_8051_SLIENT_START_2_OFFSET 13 -+#define RTL8367C_INTR_IMS_8051_SLIENT_START_2_MASK 0x2000 -+#define RTL8367C_INTR_IMS_8051_SLIENT_START_OFFSET 12 -+#define RTL8367C_INTR_IMS_8051_SLIENT_START_MASK 0x1000 -+#define RTL8367C_INTR_IMS_8051_ACL_ACTION_OFFSET 10 -+#define RTL8367C_INTR_IMS_8051_ACL_ACTION_MASK 0x400 -+#define RTL8367C_INTR_IMS_8051_SAMOVING_8051_OFFSET 9 -+#define RTL8367C_INTR_IMS_8051_SAMOVING_8051_MASK 0x200 -+#define RTL8367C_INTR_IMS_8051_CABLE_DIAG_FIN_8051_OFFSET 8 -+#define RTL8367C_INTR_IMS_8051_CABLE_DIAG_FIN_8051_MASK 0x100 -+#define RTL8367C_INTR_IMS_8051_EEELLDP_8051_OFFSET 7 -+#define RTL8367C_INTR_IMS_8051_EEELLDP_8051_MASK 0x80 -+#define RTL8367C_INTR_IMS_8051_LOOP_DETECTION_8051_OFFSET 6 -+#define RTL8367C_INTR_IMS_8051_LOOP_DETECTION_8051_MASK 0x40 -+#define RTL8367C_INTR_IMS_8051_GREEN_TIMER_8051_OFFSET 5 -+#define RTL8367C_INTR_IMS_8051_GREEN_TIMER_8051_MASK 0x20 -+#define RTL8367C_INTR_IMS_8051_SPECIAL_CONGEST_8051_OFFSET 4 -+#define RTL8367C_INTR_IMS_8051_SPECIAL_CONGEST_8051_MASK 0x10 -+#define RTL8367C_INTR_IMS_8051_SPEED_CHANGE_8051_OFFSET 3 -+#define RTL8367C_INTR_IMS_8051_SPEED_CHANGE_8051_MASK 0x8 -+#define RTL8367C_INTR_IMS_8051_LEARN_OVER_8051_OFFSET 2 -+#define RTL8367C_INTR_IMS_8051_LEARN_OVER_8051_MASK 0x4 -+#define RTL8367C_INTR_IMS_8051_METER_EXCEEDED_8051_OFFSET 1 -+#define RTL8367C_INTR_IMS_8051_METER_EXCEEDED_8051_MASK 0x2 -+#define RTL8367C_INTR_IMS_8051_LINK_CHANGE_8051_OFFSET 0 -+#define RTL8367C_INTR_IMS_8051_LINK_CHANGE_8051_MASK 0x1 -+ -+#define RTL8367C_REG_DW8051_INT_CPU 0x111a -+#define RTL8367C_DW8051_INT_CPU_OFFSET 0 -+#define RTL8367C_DW8051_INT_CPU_MASK 0x1 -+ -+#define RTL8367C_REG_LEARN_OVER_INDICATOR_8051 0x1120 -+#define RTL8367C_LEARN_OVER_INDICATOR_8051_OFFSET 0 -+#define RTL8367C_LEARN_OVER_INDICATOR_8051_MASK 0x7FF -+ -+#define RTL8367C_REG_SPEED_CHANGE_INDICATOR_8051 0x1121 -+#define RTL8367C_SPEED_CHANGE_INDICATOR_8051_OFFSET 0 -+#define RTL8367C_SPEED_CHANGE_INDICATOR_8051_MASK 0x7FF -+ -+#define RTL8367C_REG_SPECIAL_CONGEST_INDICATOR_8051 0x1122 -+#define RTL8367C_SPECIAL_CONGEST_INDICATOR_8051_OFFSET 0 -+#define RTL8367C_SPECIAL_CONGEST_INDICATOR_8051_MASK 0x7FF -+ -+#define RTL8367C_REG_PORT_LINKDOWN_INDICATOR_8051 0x1123 -+#define RTL8367C_PORT_LINKDOWN_INDICATOR_8051_OFFSET 0 -+#define RTL8367C_PORT_LINKDOWN_INDICATOR_8051_MASK 0x7FF -+ -+#define RTL8367C_REG_PORT_LINKUP_INDICATOR_8051 0x1124 -+#define RTL8367C_PORT_LINKUP_INDICATOR_8051_OFFSET 0 -+#define RTL8367C_PORT_LINKUP_INDICATOR_8051_MASK 0x7FF -+ -+#define RTL8367C_REG_DUMMY_1125 0x1125 -+ -+#define RTL8367C_REG_DUMMY_1126 0x1126 -+ -+#define RTL8367C_REG_DUMMY_1127 0x1127 -+ -+#define RTL8367C_REG_DUMMY_1128 0x1128 -+ -+#define RTL8367C_REG_DUMMY_1129 0x1129 -+ -+#define RTL8367C_REG_INTR_IMS_BUFFER_RESET 0x112a -+#define RTL8367C_INTR_IMS_BUFFER_RESET_IMR_BUFF_RESET_OFFSET 1 -+#define RTL8367C_INTR_IMS_BUFFER_RESET_IMR_BUFF_RESET_MASK 0x2 -+#define RTL8367C_INTR_IMS_BUFFER_RESET_BUFFER_RESET_OFFSET 0 -+#define RTL8367C_INTR_IMS_BUFFER_RESET_BUFFER_RESET_MASK 0x1 -+ -+#define RTL8367C_REG_INTR_IMS_8051_BUFFER_RESET 0x112b -+#define RTL8367C_INTR_IMS_8051_BUFFER_RESET_IMR_BUFF_RESET_OFFSET 1 -+#define RTL8367C_INTR_IMS_8051_BUFFER_RESET_IMR_BUFF_RESET_MASK 0x2 -+#define RTL8367C_INTR_IMS_8051_BUFFER_RESET_BUFFER_RESET_OFFSET 0 -+#define RTL8367C_INTR_IMS_8051_BUFFER_RESET_BUFFER_RESET_MASK 0x1 -+ -+#define RTL8367C_REG_GPHY_INTRPT_8051 0x112c -+#define RTL8367C_IMS_GPHY_8051_H_OFFSET 13 -+#define RTL8367C_IMS_GPHY_8051_H_MASK 0xE000 -+#define RTL8367C_IMR_GPHY_8051_H_OFFSET 10 -+#define RTL8367C_IMR_GPHY_8051_H_MASK 0x1C00 -+#define RTL8367C_IMS_GPHY_8051_OFFSET 5 -+#define RTL8367C_IMS_GPHY_8051_MASK 0x3E0 -+#define RTL8367C_IMR_GPHY_8051_OFFSET 0 -+#define RTL8367C_IMR_GPHY_8051_MASK 0x1F -+ -+#define RTL8367C_REG_GPHY_INTRPT 0x112d -+#define RTL8367C_IMS_GPHY_H_OFFSET 13 -+#define RTL8367C_IMS_GPHY_H_MASK 0xE000 -+#define RTL8367C_IMR_GPHY_H_OFFSET 10 -+#define RTL8367C_IMR_GPHY_H_MASK 0x1C00 -+#define RTL8367C_IMS_GPHY_OFFSET 5 -+#define RTL8367C_IMS_GPHY_MASK 0x3E0 -+#define RTL8367C_IMR_GPHY_OFFSET 0 -+#define RTL8367C_IMR_GPHY_MASK 0x1F -+ -+#define RTL8367C_REG_THERMAL_INTRPT 0x112e -+#define RTL8367C_IMS_TM_HIGH_OFFSET 3 -+#define RTL8367C_IMS_TM_HIGH_MASK 0x8 -+#define RTL8367C_IMR_TM_HIGH_OFFSET 2 -+#define RTL8367C_IMR_TM_HIGH_MASK 0x4 -+#define RTL8367C_IMS_TM_LOW_OFFSET 1 -+#define RTL8367C_IMS_TM_LOW_MASK 0x2 -+#define RTL8367C_IMR_TM_LOW_OFFSET 0 -+#define RTL8367C_IMR_TM_LOW_MASK 0x1 -+ -+#define RTL8367C_REG_THERMAL_INTRPT_8051 0x112f -+#define RTL8367C_IMS_TM_HIGH_8051_OFFSET 3 -+#define RTL8367C_IMS_TM_HIGH_8051_MASK 0x8 -+#define RTL8367C_IMR_TM_HIGH_8051_OFFSET 2 -+#define RTL8367C_IMR_TM_HIGH_8051_MASK 0x4 -+#define RTL8367C_IMS_TM_LOW_8051_OFFSET 1 -+#define RTL8367C_IMS_TM_LOW_8051_MASK 0x2 -+#define RTL8367C_IMR_TM_LOW_8051_OFFSET 0 -+#define RTL8367C_IMR_TM_LOW_8051_MASK 0x1 -+ -+#define RTL8367C_REG_SDS_LINK_CHG_INT 0x1130 -+#define RTL8367C_IMS_SDS_LINK_STS_C7_OFFSET 15 -+#define RTL8367C_IMS_SDS_LINK_STS_C7_MASK 0x8000 -+#define RTL8367C_IMS_SDS_LINK_STS_C6_OFFSET 14 -+#define RTL8367C_IMS_SDS_LINK_STS_C6_MASK 0x4000 -+#define RTL8367C_IMS_SDS_LINK_STS_C5_OFFSET 13 -+#define RTL8367C_IMS_SDS_LINK_STS_C5_MASK 0x2000 -+#define RTL8367C_IMS_SDS_LINK_STS_C4_OFFSET 12 -+#define RTL8367C_IMS_SDS_LINK_STS_C4_MASK 0x1000 -+#define RTL8367C_IMS_SDS_LINK_STS_C3_OFFSET 11 -+#define RTL8367C_IMS_SDS_LINK_STS_C3_MASK 0x800 -+#define RTL8367C_IMS_SDS_LINK_STS_C2_OFFSET 10 -+#define RTL8367C_IMS_SDS_LINK_STS_C2_MASK 0x400 -+#define RTL8367C_IMS_SDS_LINK_STS_C1_OFFSET 9 -+#define RTL8367C_IMS_SDS_LINK_STS_C1_MASK 0x200 -+#define RTL8367C_IMS_SDS_LINK_STS_C0_OFFSET 8 -+#define RTL8367C_IMS_SDS_LINK_STS_C0_MASK 0x100 -+#define RTL8367C_IMR_SDS_LINK_STS_C7_OFFSET 7 -+#define RTL8367C_IMR_SDS_LINK_STS_C7_MASK 0x80 -+#define RTL8367C_IMR_SDS_LINK_STS_C6_OFFSET 6 -+#define RTL8367C_IMR_SDS_LINK_STS_C6_MASK 0x40 -+#define RTL8367C_IMR_SDS_LINK_STS_C5_OFFSET 5 -+#define RTL8367C_IMR_SDS_LINK_STS_C5_MASK 0x20 -+#define RTL8367C_IMR_SDS_LINK_STS_C4_OFFSET 4 -+#define RTL8367C_IMR_SDS_LINK_STS_C4_MASK 0x10 -+#define RTL8367C_IMR_SDS_LINK_STS_C3_OFFSET 3 -+#define RTL8367C_IMR_SDS_LINK_STS_C3_MASK 0x8 -+#define RTL8367C_IMR_SDS_LINK_STS_C2_OFFSET 2 -+#define RTL8367C_IMR_SDS_LINK_STS_C2_MASK 0x4 -+#define RTL8367C_IMR_SDS_LINK_STS_C1_OFFSET 1 -+#define RTL8367C_IMR_SDS_LINK_STS_C1_MASK 0x2 -+#define RTL8367C_IMR_SDS_LINK_STS_C0_OFFSET 0 -+#define RTL8367C_IMR_SDS_LINK_STS_C0_MASK 0x1 -+ -+#define RTL8367C_REG_SDS_LINK_CHG_INT_8051 0x1131 -+#define RTL8367C_IMS_SDS_LINK_STS_C7_8051_OFFSET 15 -+#define RTL8367C_IMS_SDS_LINK_STS_C7_8051_MASK 0x8000 -+#define RTL8367C_IMS_SDS_LINK_STS_C6_8051_OFFSET 14 -+#define RTL8367C_IMS_SDS_LINK_STS_C6_8051_MASK 0x4000 -+#define RTL8367C_IMS_SDS_LINK_STS_C5_8051_OFFSET 13 -+#define RTL8367C_IMS_SDS_LINK_STS_C5_8051_MASK 0x2000 -+#define RTL8367C_IMS_SDS_LINK_STS_C4_8051_OFFSET 12 -+#define RTL8367C_IMS_SDS_LINK_STS_C4_8051_MASK 0x1000 -+#define RTL8367C_IMS_SDS_LINK_STS_C3_8051_OFFSET 11 -+#define RTL8367C_IMS_SDS_LINK_STS_C3_8051_MASK 0x800 -+#define RTL8367C_IMS_SDS_LINK_STS_C2_8051_OFFSET 10 -+#define RTL8367C_IMS_SDS_LINK_STS_C2_8051_MASK 0x400 -+#define RTL8367C_IMS_SDS_LINK_STS_C1_8051_OFFSET 9 -+#define RTL8367C_IMS_SDS_LINK_STS_C1_8051_MASK 0x200 -+#define RTL8367C_IMS_SDS_LINK_STS_C0_8051_OFFSET 8 -+#define RTL8367C_IMS_SDS_LINK_STS_C0_8051_MASK 0x100 -+#define RTL8367C_IMR_SDS_LINK_STS_C7_8051_OFFSET 7 -+#define RTL8367C_IMR_SDS_LINK_STS_C7_8051_MASK 0x80 -+#define RTL8367C_IMR_SDS_LINK_STS_C6_8051_OFFSET 6 -+#define RTL8367C_IMR_SDS_LINK_STS_C6_8051_MASK 0x40 -+#define RTL8367C_IMR_SDS_LINK_STS_C5_8051_OFFSET 5 -+#define RTL8367C_IMR_SDS_LINK_STS_C5_8051_MASK 0x20 -+#define RTL8367C_IMR_SDS_LINK_STS_C4_8051_OFFSET 4 -+#define RTL8367C_IMR_SDS_LINK_STS_C4_8051_MASK 0x10 -+#define RTL8367C_IMR_SDS_LINK_STS_C3_8051_OFFSET 3 -+#define RTL8367C_IMR_SDS_LINK_STS_C3_8051_MASK 0x8 -+#define RTL8367C_IMR_SDS_LINK_STS_C2_8051_OFFSET 2 -+#define RTL8367C_IMR_SDS_LINK_STS_C2_8051_MASK 0x4 -+#define RTL8367C_IMR_SDS_LINK_STS_C1_8051_OFFSET 1 -+#define RTL8367C_IMR_SDS_LINK_STS_C1_8051_MASK 0x2 -+#define RTL8367C_IMR_SDS_LINK_STS_C0_8051_OFFSET 0 -+#define RTL8367C_IMR_SDS_LINK_STS_C0_8051_MASK 0x1 -+ -+/* (16'h1200)swcore_reg */ -+ -+#define RTL8367C_REG_MAX_LENGTH_LIMINT_IPG 0x1200 -+#define RTL8367C_MAX_LENTH_CTRL_OFFSET 13 -+#define RTL8367C_MAX_LENTH_CTRL_MASK 0x6000 -+#define RTL8367C_PAGES_BEFORE_FCDROP_OFFSET 6 -+#define RTL8367C_PAGES_BEFORE_FCDROP_MASK 0x1FC0 -+#define RTL8367C_CHECK_MIN_IPG_RXDV_OFFSET 5 -+#define RTL8367C_CHECK_MIN_IPG_RXDV_MASK 0x20 -+#define RTL8367C_LIMIT_IPG_CFG_OFFSET 0 -+#define RTL8367C_LIMIT_IPG_CFG_MASK 0x1F -+ -+#define RTL8367C_REG_IOL_RXDROP_CFG 0x1201 -+#define RTL8367C_RX_IOL_MAX_LENGTH_CFG_OFFSET 13 -+#define RTL8367C_RX_IOL_MAX_LENGTH_CFG_MASK 0x2000 -+#define RTL8367C_RX_IOL_ERROR_LENGTH_CFG_OFFSET 12 -+#define RTL8367C_RX_IOL_ERROR_LENGTH_CFG_MASK 0x1000 -+#define RTL8367C_RX_NODROP_PAUSE_CFG_OFFSET 8 -+#define RTL8367C_RX_NODROP_PAUSE_CFG_MASK 0x100 -+#define RTL8367C_RX_DV_CNT_CFG_OFFSET 0 -+#define RTL8367C_RX_DV_CNT_CFG_MASK 0x3F -+ -+#define RTL8367C_REG_VS_TPID 0x1202 -+ -+#define RTL8367C_REG_INBW_BOUND 0x1203 -+#define RTL8367C_LBOUND_OFFSET 4 -+#define RTL8367C_LBOUND_MASK 0xF0 -+#define RTL8367C_HBOUND_OFFSET 0 -+#define RTL8367C_HBOUND_MASK 0xF -+ -+#define RTL8367C_REG_CFG_TX_ITFSP_OP 0x1204 -+#define RTL8367C_MASK_OFFSET 1 -+#define RTL8367C_MASK_MASK 0x2 -+#define RTL8367C_OP_OFFSET 0 -+#define RTL8367C_OP_MASK 0x1 -+ -+#define RTL8367C_REG_INBW_BOUND2 0x1205 -+#define RTL8367C_LBOUND2_H_OFFSET 9 -+#define RTL8367C_LBOUND2_H_MASK 0x200 -+#define RTL8367C_HBOUND2_H_OFFSET 8 -+#define RTL8367C_HBOUND2_H_MASK 0x100 -+#define RTL8367C_LBOUND2_OFFSET 4 -+#define RTL8367C_LBOUND2_MASK 0xF0 -+#define RTL8367C_HBOUND2_OFFSET 0 -+#define RTL8367C_HBOUND2_MASK 0xF -+ -+#define RTL8367C_REG_CFG_48PASS1_DROP 0x1206 -+#define RTL8367C_CFG_48PASS1_DROP_OFFSET 0 -+#define RTL8367C_CFG_48PASS1_DROP_MASK 0x1 -+ -+#define RTL8367C_REG_CFG_BACKPRESSURE 0x1207 -+#define RTL8367C_LONGTXE_OFFSET 12 -+#define RTL8367C_LONGTXE_MASK 0x1000 -+#define RTL8367C_EN_BYPASS_ERROR_OFFSET 8 -+#define RTL8367C_EN_BYPASS_ERROR_MASK 0x100 -+#define RTL8367C_EN_BACKPRESSURE_OFFSET 4 -+#define RTL8367C_EN_BACKPRESSURE_MASK 0x10 -+#define RTL8367C_EN_48_PASS_1_OFFSET 0 -+#define RTL8367C_EN_48_PASS_1_MASK 0x1 -+ -+#define RTL8367C_REG_CFG_UNHIOL 0x1208 -+#define RTL8367C_IOL_BACKOFF_OFFSET 12 -+#define RTL8367C_IOL_BACKOFF_MASK 0x1000 -+#define RTL8367C_BACKOFF_RANDOM_TIME_OFFSET 8 -+#define RTL8367C_BACKOFF_RANDOM_TIME_MASK 0x100 -+#define RTL8367C_DISABLE_BACK_OFF_OFFSET 4 -+#define RTL8367C_DISABLE_BACK_OFF_MASK 0x10 -+#define RTL8367C_IPG_COMPENSATION_OFFSET 0 -+#define RTL8367C_IPG_COMPENSATION_MASK 0x1 -+ -+#define RTL8367C_REG_SWITCH_MAC0 0x1209 -+ -+#define RTL8367C_REG_SWITCH_MAC1 0x120a -+ -+#define RTL8367C_REG_SWITCH_MAC2 0x120b -+ -+#define RTL8367C_REG_SWITCH_CTRL0 0x120c -+#define RTL8367C_REMARKING_DSCP_ENABLE_OFFSET 8 -+#define RTL8367C_REMARKING_DSCP_ENABLE_MASK 0x100 -+#define RTL8367C_SHORT_IPG_OFFSET 4 -+#define RTL8367C_SHORT_IPG_MASK 0x10 -+#define RTL8367C_PAUSE_MAX128_OFFSET 0 -+#define RTL8367C_PAUSE_MAX128_MASK 0x1 -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_CTRL0 0x120d -+#define RTL8367C_INTPRI1_DSCP_OFFSET 8 -+#define RTL8367C_INTPRI1_DSCP_MASK 0x3F00 -+#define RTL8367C_INTPRI0_DSCP_OFFSET 0 -+#define RTL8367C_INTPRI0_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_CTRL1 0x120e -+#define RTL8367C_INTPRI3_DSCP_OFFSET 8 -+#define RTL8367C_INTPRI3_DSCP_MASK 0x3F00 -+#define RTL8367C_INTPRI2_DSCP_OFFSET 0 -+#define RTL8367C_INTPRI2_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_CTRL2 0x120f -+#define RTL8367C_INTPRI5_DSCP_OFFSET 8 -+#define RTL8367C_INTPRI5_DSCP_MASK 0x3F00 -+#define RTL8367C_INTPRI4_DSCP_OFFSET 0 -+#define RTL8367C_INTPRI4_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_DSCP_REMARK_CTRL3 0x1210 -+#define RTL8367C_INTPRI7_DSCP_OFFSET 8 -+#define RTL8367C_INTPRI7_DSCP_MASK 0x3F00 -+#define RTL8367C_INTPRI6_DSCP_OFFSET 0 -+#define RTL8367C_INTPRI6_DSCP_MASK 0x3F -+ -+#define RTL8367C_REG_QOS_1Q_REMARK_CTRL0 0x1211 -+#define RTL8367C_INTPRI3_PRI_OFFSET 12 -+#define RTL8367C_INTPRI3_PRI_MASK 0x7000 -+#define RTL8367C_INTPRI2_PRI_OFFSET 8 -+#define RTL8367C_INTPRI2_PRI_MASK 0x700 -+#define RTL8367C_INTPRI1_PRI_OFFSET 4 -+#define RTL8367C_INTPRI1_PRI_MASK 0x70 -+#define RTL8367C_INTPRI0_PRI_OFFSET 0 -+#define RTL8367C_INTPRI0_PRI_MASK 0x7 -+ -+#define RTL8367C_REG_QOS_1Q_REMARK_CTRL1 0x1212 -+#define RTL8367C_INTPRI7_PRI_OFFSET 12 -+#define RTL8367C_INTPRI7_PRI_MASK 0x7000 -+#define RTL8367C_INTPRI6_PRI_OFFSET 8 -+#define RTL8367C_INTPRI6_PRI_MASK 0x700 -+#define RTL8367C_INTPRI5_PRI_OFFSET 4 -+#define RTL8367C_INTPRI5_PRI_MASK 0x70 -+#define RTL8367C_INTPRI4_PRI_OFFSET 0 -+#define RTL8367C_INTPRI4_PRI_MASK 0x7 -+ -+#define RTL8367C_REG_PKTGEN_COMMAND 0x1213 -+#define RTL8367C_PKTGEN_STOP_OFFSET 8 -+#define RTL8367C_PKTGEN_STOP_MASK 0x100 -+#define RTL8367C_PKTGEN_START_OFFSET 4 -+#define RTL8367C_PKTGEN_START_MASK 0x10 -+#define RTL8367C_PKTGEN_BYPASS_FLOWCONTROL_OFFSET 0 -+#define RTL8367C_PKTGEN_BYPASS_FLOWCONTROL_MASK 0x1 -+ -+#define RTL8367C_REG_SW_DUMMY0 0x1214 -+#define RTL8367C_SW_DUMMY0_DUMMY_OFFSET 4 -+#define RTL8367C_SW_DUMMY0_DUMMY_MASK 0xFFF0 -+#define RTL8367C_EEE_DEFER_TXLPI_OFFSET 3 -+#define RTL8367C_EEE_DEFER_TXLPI_MASK 0x8 -+#define RTL8367C_INGRESSBW_BYPASS_EN_OFFSET 2 -+#define RTL8367C_INGRESSBW_BYPASS_EN_MASK 0x4 -+#define RTL8367C_CFG_RX_MIN_OFFSET 0 -+#define RTL8367C_CFG_RX_MIN_MASK 0x3 -+ -+#define RTL8367C_REG_SW_DUMMY1 0x1215 -+ -+#define RTL8367C_REG_PKTGEN_PAUSE_TIME 0x1216 -+ -+#define RTL8367C_REG_SVLAN_UPLINK_PORTMASK 0x1218 -+#define RTL8367C_SVLAN_UPLINK_PORTMASK_OFFSET 0 -+#define RTL8367C_SVLAN_UPLINK_PORTMASK_MASK 0x7FF -+ -+#define RTL8367C_REG_CPU_PORT_MASK 0x1219 -+#define RTL8367C_CPU_PORT_MASK_OFFSET 0 -+#define RTL8367C_CPU_PORT_MASK_MASK 0x7FF -+ -+#define RTL8367C_REG_CPU_CTRL 0x121a -+#define RTL8367C_CPU_TRAP_PORT_EXT_OFFSET 10 -+#define RTL8367C_CPU_TRAP_PORT_EXT_MASK 0x400 -+#define RTL8367C_CPU_TAG_FORMAT_OFFSET 9 -+#define RTL8367C_CPU_TAG_FORMAT_MASK 0x200 -+#define RTL8367C_IOL_16DROP_OFFSET 8 -+#define RTL8367C_IOL_16DROP_MASK 0x100 -+#define RTL8367C_CPU_TAG_RXBYTECOUNT_OFFSET 7 -+#define RTL8367C_CPU_TAG_RXBYTECOUNT_MASK 0x80 -+#define RTL8367C_CPU_TAG_POSITION_OFFSET 6 -+#define RTL8367C_CPU_TAG_POSITION_MASK 0x40 -+#define RTL8367C_CPU_TRAP_PORT_OFFSET 3 -+#define RTL8367C_CPU_TRAP_PORT_MASK 0x38 -+#define RTL8367C_CPU_INSERTMODE_OFFSET 1 -+#define RTL8367C_CPU_INSERTMODE_MASK 0x6 -+#define RTL8367C_CPU_EN_OFFSET 0 -+#define RTL8367C_CPU_EN_MASK 0x1 -+ -+#define RTL8367C_REG_MIRROR_CTRL 0x121c -+#define RTL8367C_MIRROR_CTRL_DUMMY_OFFSET 12 -+#define RTL8367C_MIRROR_CTRL_DUMMY_MASK 0xF000 -+#define RTL8367C_MIRROR_ISO_OFFSET 11 -+#define RTL8367C_MIRROR_ISO_MASK 0x800 -+#define RTL8367C_MIRROR_TX_OFFSET 10 -+#define RTL8367C_MIRROR_TX_MASK 0x400 -+#define RTL8367C_MIRROR_RX_OFFSET 9 -+#define RTL8367C_MIRROR_RX_MASK 0x200 -+#define RTL8367C_MIRROR_MONITOR_PORT_OFFSET 4 -+#define RTL8367C_MIRROR_MONITOR_PORT_MASK 0xF0 -+#define RTL8367C_MIRROR_SOURCE_PORT_OFFSET 0 -+#define RTL8367C_MIRROR_SOURCE_PORT_MASK 0xF -+ -+#define RTL8367C_REG_FLOWCTRL_CTRL0 0x121d -+#define RTL8367C_FLOWCTRL_TYPE_OFFSET 15 -+#define RTL8367C_FLOWCTRL_TYPE_MASK 0x8000 -+#define RTL8367C_DROP_ALL_THRESHOLD_OFFSET 5 -+#define RTL8367C_DROP_ALL_THRESHOLD_MASK 0x7FE0 -+#define RTL8367C_DROP_ALL_THRESHOLD_MSB_OFFSET 4 -+#define RTL8367C_DROP_ALL_THRESHOLD_MSB_MASK 0x10 -+#define RTL8367C_ITFSP_REG_OFFSET 0 -+#define RTL8367C_ITFSP_REG_MASK 0x7 -+ -+#define RTL8367C_REG_FLOWCTRL_ALL_ON 0x121e -+#define RTL8367C_CFG_RLDPACT_OFFSET 12 -+#define RTL8367C_CFG_RLDPACT_MASK 0x1000 -+#define RTL8367C_FLOWCTRL_ALL_ON_THRESHOLD_OFFSET 0 -+#define RTL8367C_FLOWCTRL_ALL_ON_THRESHOLD_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_SYS_ON 0x121f -+#define RTL8367C_FLOWCTRL_SYS_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_SYS_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_SYS_OFF 0x1220 -+#define RTL8367C_FLOWCTRL_SYS_OFF_OFFSET 0 -+#define RTL8367C_FLOWCTRL_SYS_OFF_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_SHARE_ON 0x1221 -+#define RTL8367C_FLOWCTRL_SHARE_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_SHARE_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_SHARE_OFF 0x1222 -+#define RTL8367C_FLOWCTRL_SHARE_OFF_OFFSET 0 -+#define RTL8367C_FLOWCTRL_SHARE_OFF_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_FCOFF_SYS_ON 0x1223 -+#define RTL8367C_FLOWCTRL_FCOFF_SYS_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_FCOFF_SYS_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_FCOFF_SYS_OFF 0x1224 -+#define RTL8367C_FLOWCTRL_FCOFF_SYS_OFF_OFFSET 0 -+#define RTL8367C_FLOWCTRL_FCOFF_SYS_OFF_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_FCOFF_SHARE_ON 0x1225 -+#define RTL8367C_FLOWCTRL_FCOFF_SHARE_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_FCOFF_SHARE_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_FCOFF_SHARE_OFF 0x1226 -+#define RTL8367C_FLOWCTRL_FCOFF_SHARE_OFF_OFFSET 0 -+#define RTL8367C_FLOWCTRL_FCOFF_SHARE_OFF_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT_ON 0x1227 -+#define RTL8367C_FLOWCTRL_PORT_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT_OFF 0x1228 -+#define RTL8367C_FLOWCTRL_PORT_OFF_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT_OFF_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT_PRIVATE_ON 0x1229 -+#define RTL8367C_FLOWCTRL_PORT_PRIVATE_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT_PRIVATE_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT_PRIVATE_OFF 0x122a -+#define RTL8367C_FLOWCTRL_PORT_PRIVATE_OFF_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT_PRIVATE_OFF_MASK 0x7FF -+ -+#define RTL8367C_REG_RRCP_CTRL0 0x122b -+#define RTL8367C_COL_SEL_OFFSET 14 -+#define RTL8367C_COL_SEL_MASK 0x4000 -+#define RTL8367C_CRS_SEL_OFFSET 13 -+#define RTL8367C_CRS_SEL_MASK 0x2000 -+#define RTL8367C_RRCP_PBVLAN_EN_OFFSET 11 -+#define RTL8367C_RRCP_PBVLAN_EN_MASK 0x800 -+#define RTL8367C_RRCPV3_SECURITY_CRC_OFFSET 10 -+#define RTL8367C_RRCPV3_SECURITY_CRC_MASK 0x400 -+#define RTL8367C_RRCPV3_HANDLE_OFFSET 8 -+#define RTL8367C_RRCPV3_HANDLE_MASK 0x300 -+#define RTL8367C_RRCPV1_MALFORMED_ACT_OFFSET 5 -+#define RTL8367C_RRCPV1_MALFORMED_ACT_MASK 0x60 -+#define RTL8367C_RRCP_VLANLEAKY_OFFSET 4 -+#define RTL8367C_RRCP_VLANLEAKY_MASK 0x10 -+#define RTL8367C_RRCPV1_SECURITY_CRC_GET_OFFSET 3 -+#define RTL8367C_RRCPV1_SECURITY_CRC_GET_MASK 0x8 -+#define RTL8367C_RRCPV1_SECURITY_CRC_SET_OFFSET 2 -+#define RTL8367C_RRCPV1_SECURITY_CRC_SET_MASK 0x4 -+#define RTL8367C_RRCPV1_HANDLE_OFFSET 1 -+#define RTL8367C_RRCPV1_HANDLE_MASK 0x2 -+#define RTL8367C_RRCP_ENABLE_OFFSET 0 -+#define RTL8367C_RRCP_ENABLE_MASK 0x1 -+ -+#define RTL8367C_REG_RRCP_CTRL1 0x122c -+#define RTL8367C_RRCP_ADMIN_PMSK_OFFSET 8 -+#define RTL8367C_RRCP_ADMIN_PMSK_MASK 0xFF00 -+#define RTL8367C_RRCP_AUTH_PMSK_OFFSET 0 -+#define RTL8367C_RRCP_AUTH_PMSK_MASK 0xFF -+ -+#define RTL8367C_REG_RRCP_CTRL2 0x122d -+#define RTL8367C_RRCPV1_HELLOFWD_TAG_OFFSET 9 -+#define RTL8367C_RRCPV1_HELLOFWD_TAG_MASK 0x600 -+#define RTL8367C_RRCP_FWD_TAG_OFFSET 7 -+#define RTL8367C_RRCP_FWD_TAG_MASK 0x180 -+#define RTL8367C_RRCPV1_REPLY_TAG_OFFSET 6 -+#define RTL8367C_RRCPV1_REPLY_TAG_MASK 0x40 -+#define RTL8367C_RRCPV1_HELLO_COUNT_OFFSET 3 -+#define RTL8367C_RRCPV1_HELLO_COUNT_MASK 0x38 -+#define RTL8367C_RRCPV1_HELLO_PEDIOD_OFFSET 0 -+#define RTL8367C_RRCPV1_HELLO_PEDIOD_MASK 0x3 -+ -+#define RTL8367C_REG_RRCP_CTRL3 0x122e -+#define RTL8367C_RRCP_TAG_PRIORITY_OFFSET 13 -+#define RTL8367C_RRCP_TAG_PRIORITY_MASK 0xE000 -+#define RTL8367C_RRCP_TAG_VID_OFFSET 0 -+#define RTL8367C_RRCP_TAG_VID_MASK 0xFFF -+ -+#define RTL8367C_REG_FLOWCTRL_FCOFF_PORT_ON 0x122f -+#define RTL8367C_FLOWCTRL_FCOFF_PORT_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_FCOFF_PORT_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_FCOFF_PORT_OFF 0x1230 -+#define RTL8367C_FLOWCTRL_FCOFF_PORT_OFF_OFFSET 0 -+#define RTL8367C_FLOWCTRL_FCOFF_PORT_OFF_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_FCOFF_PORT_PRIVATE_ON 0x1231 -+#define RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_FCOFF_PORT_PRIVATE_OFF 0x1232 -+#define RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_OFF_OFFSET 0 -+#define RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_OFF_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_JUMBO_SYS_ON 0x1233 -+#define RTL8367C_FLOWCTRL_JUMBO_SYS_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_JUMBO_SYS_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_JUMBO_SYS_OFF 0x1234 -+#define RTL8367C_FLOWCTRL_JUMBO_SYS_OFF_OFFSET 0 -+#define RTL8367C_FLOWCTRL_JUMBO_SYS_OFF_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_JUMBO_SHARE_ON 0x1235 -+#define RTL8367C_FLOWCTRL_JUMBO_SHARE_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_JUMBO_SHARE_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_JUMBO_SHARE_OFF 0x1236 -+#define RTL8367C_FLOWCTRL_JUMBO_SHARE_OFF_OFFSET 0 -+#define RTL8367C_FLOWCTRL_JUMBO_SHARE_OFF_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_JUMBO_PORT_ON 0x1237 -+#define RTL8367C_FLOWCTRL_JUMBO_PORT_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_JUMBO_PORT_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_JUMBO_PORT_OFF 0x1238 -+#define RTL8367C_FLOWCTRL_JUMBO_PORT_OFF_OFFSET 0 -+#define RTL8367C_FLOWCTRL_JUMBO_PORT_OFF_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_JUMBO_PORT_PRIVATE_ON 0x1239 -+#define RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_ON_OFFSET 0 -+#define RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_ON_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_JUMBO_PORT_PRIVATE_OFF 0x123a -+#define RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_OFF_OFFSET 0 -+#define RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_OFF_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_JUMBO_SIZE 0x123b -+#define RTL8367C_JUMBO_MODE_OFFSET 2 -+#define RTL8367C_JUMBO_MODE_MASK 0x4 -+#define RTL8367C_JUMBO_SIZE_OFFSET 0 -+#define RTL8367C_JUMBO_SIZE_MASK 0x3 -+ -+#define RTL8367C_REG_FLOWCTRL_TOTAL_PAGE_COUNTER 0x124c -+#define RTL8367C_FLOWCTRL_TOTAL_PAGE_COUNTER_OFFSET 0 -+#define RTL8367C_FLOWCTRL_TOTAL_PAGE_COUNTER_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PUBLIC_PAGE_COUNTER 0x124d -+#define RTL8367C_FLOWCTRL_PUBLIC_PAGE_COUNTER_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PUBLIC_PAGE_COUNTER_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_TOTAL_PAGE_MAX 0x124e -+#define RTL8367C_FLOWCTRL_TOTAL_PAGE_MAX_OFFSET 0 -+#define RTL8367C_FLOWCTRL_TOTAL_PAGE_MAX_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PUBLIC_PAGE_MAX 0x124f -+#define RTL8367C_FLOWCTRL_PUBLIC_PAGE_MAX_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PUBLIC_PAGE_MAX_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT0_PAGE_COUNTER 0x1250 -+#define RTL8367C_FLOWCTRL_PORT0_PAGE_COUNTER_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT0_PAGE_COUNTER_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT1_PAGE_COUNTER 0x1251 -+#define RTL8367C_FLOWCTRL_PORT1_PAGE_COUNTER_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT1_PAGE_COUNTER_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT2_PAGE_COUNTER 0x1252 -+#define RTL8367C_FLOWCTRL_PORT2_PAGE_COUNTER_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT2_PAGE_COUNTER_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT3_PAGE_COUNTER 0x1253 -+#define RTL8367C_FLOWCTRL_PORT3_PAGE_COUNTER_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT3_PAGE_COUNTER_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT4_PAGE_COUNTER 0x1254 -+#define RTL8367C_FLOWCTRL_PORT4_PAGE_COUNTER_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT4_PAGE_COUNTER_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT5_PAGE_COUNTER 0x1255 -+#define RTL8367C_FLOWCTRL_PORT5_PAGE_COUNTER_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT5_PAGE_COUNTER_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT6_PAGE_COUNTER 0x1256 -+#define RTL8367C_FLOWCTRL_PORT6_PAGE_COUNTER_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT6_PAGE_COUNTER_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT7_PAGE_COUNTER 0x1257 -+#define RTL8367C_FLOWCTRL_PORT7_PAGE_COUNTER_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT7_PAGE_COUNTER_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PUBLIC_FCOFF_PAGE_COUNTER 0x1258 -+#define RTL8367C_FLOWCTRL_PUBLIC_FCOFF_PAGE_COUNTER_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PUBLIC_FCOFF_PAGE_COUNTER_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PUBLIC_JUMBO_PAGE_COUNTER 0x1259 -+#define RTL8367C_FLOWCTRL_PUBLIC_JUMBO_PAGE_COUNTER_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PUBLIC_JUMBO_PAGE_COUNTER_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_MAX_PUBLIC_FCOFF_PAGE_COUNTER 0x125a -+#define RTL8367C_FLOWCTRL_MAX_PUBLIC_FCOFF_PAGE_COUNTER_OFFSET 0 -+#define RTL8367C_FLOWCTRL_MAX_PUBLIC_FCOFF_PAGE_COUNTER_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_MAX_PUBLIC_JUMBO_PAGE_COUNTER 0x125b -+#define RTL8367C_FLOWCTRL_MAX_PUBLIC_JUMBO_PAGE_COUNTER_OFFSET 0 -+#define RTL8367C_FLOWCTRL_MAX_PUBLIC_JUMBO_PAGE_COUNTER_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT0_PAGE_MAX 0x1260 -+#define RTL8367C_FLOWCTRL_PORT0_PAGE_MAX_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT0_PAGE_MAX_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT1_PAGE_MAX 0x1261 -+#define RTL8367C_FLOWCTRL_PORT1_PAGE_MAX_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT1_PAGE_MAX_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT2_PAGE_MAX 0x1262 -+#define RTL8367C_FLOWCTRL_PORT2_PAGE_MAX_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT2_PAGE_MAX_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT3_PAGE_MAX 0x1263 -+#define RTL8367C_FLOWCTRL_PORT3_PAGE_MAX_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT3_PAGE_MAX_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT4_PAGE_MAX 0x1264 -+#define RTL8367C_FLOWCTRL_PORT4_PAGE_MAX_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT4_PAGE_MAX_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT5_PAGE_MAX 0x1265 -+#define RTL8367C_FLOWCTRL_PORT5_PAGE_MAX_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT5_PAGE_MAX_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT6_PAGE_MAX 0x1266 -+#define RTL8367C_FLOWCTRL_PORT6_PAGE_MAX_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT6_PAGE_MAX_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT7_PAGE_MAX 0x1267 -+#define RTL8367C_FLOWCTRL_PORT7_PAGE_MAX_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT7_PAGE_MAX_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PAGE_COUNT_CLEAR 0x1268 -+#define RTL8367C_DIS_SKIP_FP_OFFSET 1 -+#define RTL8367C_DIS_SKIP_FP_MASK 0x2 -+#define RTL8367C_PAGE_COUNT_CLEAR_OFFSET 0 -+#define RTL8367C_PAGE_COUNT_CLEAR_MASK 0x1 -+ -+#define RTL8367C_REG_FLOWCTRL_PORT8_PAGE_MAX 0x1269 -+#define RTL8367C_FLOWCTRL_PORT8_PAGE_MAX_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT8_PAGE_MAX_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT9_PAGE_MAX 0x126a -+#define RTL8367C_FLOWCTRL_PORT9_PAGE_MAX_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT9_PAGE_MAX_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT10_PAGE_MAX 0x126b -+#define RTL8367C_FLOWCTRL_PORT10_PAGE_MAX_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT10_PAGE_MAX_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT8_PAGE_COUNTER 0x126c -+#define RTL8367C_FLOWCTRL_PORT8_PAGE_COUNTER_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT8_PAGE_COUNTER_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT9_PAGE_COUNTER 0x126d -+#define RTL8367C_FLOWCTRL_PORT9_PAGE_COUNTER_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT9_PAGE_COUNTER_MASK 0x7FF -+ -+#define RTL8367C_REG_FLOWCTRL_PORT10_PAGE_COUNTER 0x126e -+#define RTL8367C_FLOWCTRL_PORT10_PAGE_COUNTER_OFFSET 0 -+#define RTL8367C_FLOWCTRL_PORT10_PAGE_COUNTER_MASK 0x7FF -+ -+#define RTL8367C_REG_RRCP_CTRL1_H 0x126f -+#define RTL8367C_RRCP_ADMIN_PMSK_P10_8_OFFSET 3 -+#define RTL8367C_RRCP_ADMIN_PMSK_P10_8_MASK 0x38 -+#define RTL8367C_RRCP_AUTH_PMSK_P10_8_OFFSET 0 -+#define RTL8367C_RRCP_AUTH_PMSK_P10_8_MASK 0x7 -+ -+#define RTL8367C_REG_EMA_CTRL0 0x1270 -+#define RTL8367C_CFG_DVSE_VIAROM_OFFSET 13 -+#define RTL8367C_CFG_DVSE_VIAROM_MASK 0x2000 -+#define RTL8367C_CFG_DVSE_MIBRAM_OFFSET 12 -+#define RTL8367C_CFG_DVSE_MIBRAM_MASK 0x1000 -+#define RTL8367C_CFG_DVSE_IROM_OFFSET 11 -+#define RTL8367C_CFG_DVSE_IROM_MASK 0x800 -+#define RTL8367C_CFG_DVSE_ERAM_OFFSET 10 -+#define RTL8367C_CFG_DVSE_ERAM_MASK 0x400 -+#define RTL8367C_CFG_DVSE_IRAM_OFFSET 9 -+#define RTL8367C_CFG_DVSE_IRAM_MASK 0x200 -+#define RTL8367C_CFG_DVSE_NICRAM_OFFSET 8 -+#define RTL8367C_CFG_DVSE_NICRAM_MASK 0x100 -+#define RTL8367C_CFG_DVSE_CVLANRAM_OFFSET 7 -+#define RTL8367C_CFG_DVSE_CVLANRAM_MASK 0x80 -+#define RTL8367C_CFG_DVSE_ACTRAM_OFFSET 6 -+#define RTL8367C_CFG_DVSE_ACTRAM_MASK 0x40 -+#define RTL8367C_CFG_DVSE_INQRAM_OFFSET 5 -+#define RTL8367C_CFG_DVSE_INQRAM_MASK 0x20 -+#define RTL8367C_CFG_DVSE_HSARAM_OFFSET 4 -+#define RTL8367C_CFG_DVSE_HSARAM_MASK 0x10 -+#define RTL8367C_CFG_DVSE_OUTQRAM_OFFSET 3 -+#define RTL8367C_CFG_DVSE_OUTQRAM_MASK 0x8 -+#define RTL8367C_CFG_DVSE_HTRAM_OFFSET 2 -+#define RTL8367C_CFG_DVSE_HTRAM_MASK 0x4 -+#define RTL8367C_CFG_DVSE_PBRAM_OFFSET 1 -+#define RTL8367C_CFG_DVSE_PBRAM_MASK 0x2 -+#define RTL8367C_CFG_DVSE_L2RAM_OFFSET 0 -+#define RTL8367C_CFG_DVSE_L2RAM_MASK 0x1 -+ -+#define RTL8367C_REG_EMA_CTRL1 0x1271 -+#define RTL8367C_CFG_DVS_OUTQRAM_OFFSET 12 -+#define RTL8367C_CFG_DVS_OUTQRAM_MASK 0xF000 -+#define RTL8367C_CFG_DVS_HTRAM_OFFSET 8 -+#define RTL8367C_CFG_DVS_HTRAM_MASK 0x700 -+#define RTL8367C_CFG_DVS_PBRAM_OFFSET 4 -+#define RTL8367C_CFG_DVS_PBRAM_MASK 0xF0 -+#define RTL8367C_CFG_DVS_L2RAM_OFFSET 0 -+#define RTL8367C_CFG_DVS_L2RAM_MASK 0xF -+ -+#define RTL8367C_REG_EMA_CTRL2 0x1272 -+#define RTL8367C_CFG_DVS_CVLANRAM_OFFSET 12 -+#define RTL8367C_CFG_DVS_CVLANRAM_MASK 0xF000 -+#define RTL8367C_CFG_DVS_ACTRAM_OFFSET 8 -+#define RTL8367C_CFG_DVS_ACTRAM_MASK 0xF00 -+#define RTL8367C_CFG_DVS_INQRAM_OFFSET 4 -+#define RTL8367C_CFG_DVS_INQRAM_MASK 0xF0 -+#define RTL8367C_CFG_DVS_HSARAM_OFFSET 0 -+#define RTL8367C_CFG_DVS_HSARAM_MASK 0xF -+ -+#define RTL8367C_REG_EMA_CTRL3 0x1273 -+#define RTL8367C_CFG_DVS_IROM_OFFSET 12 -+#define RTL8367C_CFG_DVS_IROM_MASK 0xF000 -+#define RTL8367C_CFG_DVS_ERAM_OFFSET 8 -+#define RTL8367C_CFG_DVS_ERAM_MASK 0xF00 -+#define RTL8367C_CFG_DVS_IRAM_OFFSET 4 -+#define RTL8367C_CFG_DVS_IRAM_MASK 0xF0 -+#define RTL8367C_CFG_DVS_NICRAM_OFFSET 0 -+#define RTL8367C_CFG_DVS_NICRAM_MASK 0xF -+ -+#define RTL8367C_REG_EMA_CTRL4 0x1274 -+#define RTL8367C_CFG_DVS_VIAROM_OFFSET 4 -+#define RTL8367C_CFG_DVS_VIAROM_MASK 0xF0 -+#define RTL8367C_CFG_DVS_MIBRAM_OFFSET 0 -+#define RTL8367C_CFG_DVS_MIBRAM_MASK 0xF -+ -+#define RTL8367C_REG_DIAG_MODE 0x1275 -+#define RTL8367C_DIAG_MODE_OFFSET 0 -+#define RTL8367C_DIAG_MODE_MASK 0x1F -+ -+#define RTL8367C_REG_BIST_MODE 0x1276 -+ -+#define RTL8367C_REG_STS_BIST_DONE 0x1277 -+ -+#define RTL8367C_REG_STS_BIST_RLT0 0x1278 -+#define RTL8367C_STS_BIST_RLT0_OFFSET 0 -+#define RTL8367C_STS_BIST_RLT0_MASK 0x1 -+ -+#define RTL8367C_REG_STS_BIST_RLT1 0x1279 -+ -+#define RTL8367C_REG_STS_BIST_RLT2 0x127a -+ -+#define RTL8367C_REG_STS_BIST_RLT3 0x127b -+#define RTL8367C_STS_BIST_RLT3_OFFSET 0 -+#define RTL8367C_STS_BIST_RLT3_MASK 0x3FF -+ -+#define RTL8367C_REG_STS_BIST_RLT4 0x127c -+#define RTL8367C_STS_BIST_RLT4_OFFSET 0 -+#define RTL8367C_STS_BIST_RLT4_MASK 0x7 -+ -+#define RTL8367C_REG_VIAROM_MISR 0x127d -+ -+#define RTL8367C_REG_DRF_BIST_MODE 0x1280 -+#define RTL8367C_DRF_TCAMDEL_OFFSET 15 -+#define RTL8367C_DRF_TCAMDEL_MASK 0x8000 -+#define RTL8367C_CFG_DRF_BIST_MODE_OFFSET 0 -+#define RTL8367C_CFG_DRF_BIST_MODE_MASK 0x7FFF -+ -+#define RTL8367C_REG_STS_DRF_BIST 0x1281 -+#define RTL8367C_STS_DRF_BIST_OFFSET 0 -+#define RTL8367C_STS_DRF_BIST_MASK 0x7FFF -+ -+#define RTL8367C_REG_STS_DRF_BIST_RLT0 0x1282 -+#define RTL8367C_STS_DRF_BIST_RLT0_OFFSET 0 -+#define RTL8367C_STS_DRF_BIST_RLT0_MASK 0x1 -+ -+#define RTL8367C_REG_STS_DRF_BIST_RLT1 0x1283 -+ -+#define RTL8367C_REG_STS_DRF_BIST_RLT2 0x1284 -+ -+#define RTL8367C_REG_STS_DRF_BIST_RLT3 0x1285 -+#define RTL8367C_STS_DRF_BIST_RLT3_OFFSET 0 -+#define RTL8367C_STS_DRF_BIST_RLT3_MASK 0x3FF -+ -+#define RTL8367C_REG_STS_DRF_BIST_RLT4 0x1286 -+#define RTL8367C_STS_DRF_BIST_RLT4_OFFSET 0 -+#define RTL8367C_STS_DRF_BIST_RLT4_MASK 0x7FFF -+ -+#define RTL8367C_REG_RAM_DRF_CTRL 0x1289 -+#define RTL8367C_RAM_DRF_CTRL_OFFSET 0 -+#define RTL8367C_RAM_DRF_CTRL_MASK 0x1 -+ -+#define RTL8367C_REG_MIB_RMON_LEN_CTRL 0x128a -+#define RTL8367C_RX_LENGTH_CTRL_OFFSET 1 -+#define RTL8367C_RX_LENGTH_CTRL_MASK 0x2 -+#define RTL8367C_TX_LENGTH_CTRL_OFFSET 0 -+#define RTL8367C_TX_LENGTH_CTRL_MASK 0x1 -+ -+#define RTL8367C_REG_COND0_BISR_OUT0 0x1290 -+ -+#define RTL8367C_REG_COND0_BISR_OUT1 0x1291 -+ -+#define RTL8367C_REG_COND0_BISR_OUT2 0x1292 -+ -+#define RTL8367C_REG_COND0_BISR_OUT3 0x1293 -+ -+#define RTL8367C_REG_COND0_BISR_OUT4 0x1294 -+#define RTL8367C_COND0_BISR_OUT4_OFFSET 0 -+#define RTL8367C_COND0_BISR_OUT4_MASK 0x3F -+ -+#define RTL8367C_REG_COND0_BISR_OUT5 0x1295 -+#define RTL8367C_COND0_BISR_OUT5_OFFSET 0 -+#define RTL8367C_COND0_BISR_OUT5_MASK 0x7 -+ -+#define RTL8367C_REG_CHG_DUPLEX_CFG 0x1296 -+#define RTL8367C_CHG_COL_CNT_PORT_OFFSET 13 -+#define RTL8367C_CHG_COL_CNT_PORT_MASK 0xE000 -+#define RTL8367C_CHG_COL_CNT_OFFSET 8 -+#define RTL8367C_CHG_COL_CNT_MASK 0x1F00 -+#define RTL8367C_CFG_CHG_DUP_EN_OFFSET 7 -+#define RTL8367C_CFG_CHG_DUP_EN_MASK 0x80 -+#define RTL8367C_CFG_CHG_DUP_THR_OFFSET 2 -+#define RTL8367C_CFG_CHG_DUP_THR_MASK 0x7C -+#define RTL8367C_CFG_CHG_DUP_CONGEST_OFFSET 1 -+#define RTL8367C_CFG_CHG_DUP_CONGEST_MASK 0x2 -+#define RTL8367C_CFG_CHG_DUP_REF_OFFSET 0 -+#define RTL8367C_CFG_CHG_DUP_REF_MASK 0x1 -+ -+#define RTL8367C_REG_COND0_BIST_PASS 0x1297 -+#define RTL8367C_COND0_DRF_BIST_NOFAIL_OFFSET 1 -+#define RTL8367C_COND0_DRF_BIST_NOFAIL_MASK 0x2 -+#define RTL8367C_COND0_BIST_NOFAIL_OFFSET 0 -+#define RTL8367C_COND0_BIST_NOFAIL_MASK 0x1 -+ -+#define RTL8367C_REG_COND1_BISR_OUT0 0x1298 -+ -+#define RTL8367C_REG_COND1_BISR_OUT1 0x1299 -+ -+#define RTL8367C_REG_COND1_BISR_OUT2 0x129a -+ -+#define RTL8367C_REG_COND1_BISR_OUT3 0x129b -+ -+#define RTL8367C_REG_COND1_BISR_OUT4 0x129c -+#define RTL8367C_COND1_BISR_OUT4_OFFSET 0 -+#define RTL8367C_COND1_BISR_OUT4_MASK 0x3F -+ -+#define RTL8367C_REG_COND1_BISR_OUT5 0x129d -+#define RTL8367C_COND1_BISR_OUT5_OFFSET 0 -+#define RTL8367C_COND1_BISR_OUT5_MASK 0x7 -+ -+#define RTL8367C_REG_COND1_BIST_PASS 0x129f -+#define RTL8367C_COND1_DRF_BIST_NOFAIL_OFFSET 1 -+#define RTL8367C_COND1_DRF_BIST_NOFAIL_MASK 0x2 -+#define RTL8367C_COND1_BIST_NOFAIL_OFFSET 0 -+#define RTL8367C_COND1_BIST_NOFAIL_MASK 0x1 -+ -+#define RTL8367C_REG_EEE_TX_THR_Giga_500M 0x12a0 -+ -+#define RTL8367C_REG_EEE_TX_THR_FE 0x12a1 -+ -+#define RTL8367C_REG_EEE_MISC 0x12a3 -+#define RTL8367C_EEE_REQ_SET1_OFFSET 13 -+#define RTL8367C_EEE_REQ_SET1_MASK 0x2000 -+#define RTL8367C_EEE_REQ_SET0_OFFSET 12 -+#define RTL8367C_EEE_REQ_SET0_MASK 0x1000 -+#define RTL8367C_EEE_WAKE_SET1_OFFSET 9 -+#define RTL8367C_EEE_WAKE_SET1_MASK 0x200 -+#define RTL8367C_EEE_Wake_SET0_OFFSET 8 -+#define RTL8367C_EEE_Wake_SET0_MASK 0x100 -+#define RTL8367C_EEE_TU_GIGA_500M_OFFSET 4 -+#define RTL8367C_EEE_TU_GIGA_500M_MASK 0x30 -+#define RTL8367C_EEE_TU_100M_OFFSET 2 -+#define RTL8367C_EEE_TU_100M_MASK 0xC -+ -+#define RTL8367C_REG_EEE_GIGA_CTRL0 0x12a4 -+#define RTL8367C_EEE_TW_GIGA_OFFSET 8 -+#define RTL8367C_EEE_TW_GIGA_MASK 0xFF00 -+#define RTL8367C_EEE_TR_GIGA_500M_OFFSET 0 -+#define RTL8367C_EEE_TR_GIGA_500M_MASK 0xFF -+ -+#define RTL8367C_REG_EEE_GIGA_CTRL1 0x12a5 -+#define RTL8367C_EEE_TD_GIGA_500M_OFFSET 8 -+#define RTL8367C_EEE_TD_GIGA_500M_MASK 0xFF00 -+#define RTL8367C_EEE_TP_GIGA_OFFSET 0 -+#define RTL8367C_EEE_TP_GIGA_MASK 0xFF -+ -+#define RTL8367C_REG_EEE_100M_CTRL0 0x12a6 -+#define RTL8367C_EEE_TW_100M_OFFSET 8 -+#define RTL8367C_EEE_TW_100M_MASK 0xFF00 -+#define RTL8367C_EEE_TR_100M_OFFSET 0 -+#define RTL8367C_EEE_TR_100M_MASK 0xFF -+ -+#define RTL8367C_REG_EEE_100M_CTRL1 0x12a7 -+#define RTL8367C_EEE_TD_100M_OFFSET 8 -+#define RTL8367C_EEE_TD_100M_MASK 0xFF00 -+#define RTL8367C_EEE_TP_100M_OFFSET 0 -+#define RTL8367C_EEE_TP_100M_MASK 0xFF -+ -+#define RTL8367C_REG_RX_FC_REG 0x12aa -+#define RTL8367C_EN_EEE_HALF_DUP_OFFSET 8 -+#define RTL8367C_EN_EEE_HALF_DUP_MASK 0x100 -+#define RTL8367C_RX_PGCNT_OFFSET 0 -+#define RTL8367C_RX_PGCNT_MASK 0xFF -+ -+#define RTL8367C_REG_MAX_FIFO_SIZE 0x12af -+#define RTL8367C_MAX_FIFO_SIZE_OFFSET 0 -+#define RTL8367C_MAX_FIFO_SIZE_MASK 0xF -+ -+#define RTL8367C_REG_EEEP_RX_RATE_GIGA 0x12b0 -+ -+#define RTL8367C_REG_EEEP_RX_RATE_100M 0x12b1 -+ -+#define RTL8367C_REG_DUMMY_REG_12_2 0x12b2 -+ -+#define RTL8367C_REG_EEEP_TX_RATE_GIGA 0x12b3 -+ -+#define RTL8367C_REG_EEEP_TX_RATE_100M 0x12b4 -+ -+#define RTL8367C_REG_DUMMY_REG_12_3 0x12b5 -+ -+#define RTL8367C_REG_EEEP_GIGA_CTRL0 0x12b6 -+#define RTL8367C_EEEP_TR_GIGA_OFFSET 8 -+#define RTL8367C_EEEP_TR_GIGA_MASK 0xFF00 -+#define RTL8367C_EEEP_RW_GIGA_MST_OFFSET 0 -+#define RTL8367C_EEEP_RW_GIGA_MST_MASK 0xFF -+ -+#define RTL8367C_REG_EEEP_GIGA_CTRL1 0x12b7 -+#define RTL8367C_EEEP_TW_GIGA_OFFSET 8 -+#define RTL8367C_EEEP_TW_GIGA_MASK 0xFF00 -+#define RTL8367C_EEEP_TP_GIGA_OFFSET 0 -+#define RTL8367C_EEEP_TP_GIGA_MASK 0xFF -+ -+#define RTL8367C_REG_EEEP_GIGA_CTRL2 0x12b8 -+#define RTL8367C_EEEP_TXEN_GIGA_OFFSET 12 -+#define RTL8367C_EEEP_TXEN_GIGA_MASK 0x1000 -+#define RTL8367C_EEEP_TU_GIGA_OFFSET 8 -+#define RTL8367C_EEEP_TU_GIGA_MASK 0x300 -+#define RTL8367C_EEEP_TS_GIGA_OFFSET 0 -+#define RTL8367C_EEEP_TS_GIGA_MASK 0xFF -+ -+#define RTL8367C_REG_EEEP_100M_CTRL0 0x12b9 -+#define RTL8367C_EEEP_TR_100M_OFFSET 8 -+#define RTL8367C_EEEP_TR_100M_MASK 0xFF00 -+#define RTL8367C_EEEP_RW_100M_OFFSET 0 -+#define RTL8367C_EEEP_RW_100M_MASK 0xFF -+ -+#define RTL8367C_REG_EEEP_100M_CTRL1 0x12ba -+#define RTL8367C_EEEP_TW_100M_OFFSET 8 -+#define RTL8367C_EEEP_TW_100M_MASK 0xFF00 -+#define RTL8367C_EEEP_TP_100M_OFFSET 0 -+#define RTL8367C_EEEP_TP_100M_MASK 0xFF -+ -+#define RTL8367C_REG_EEEP_100M_CTRL2 0x12bb -+#define RTL8367C_EEEP_TXEN_100M_OFFSET 12 -+#define RTL8367C_EEEP_TXEN_100M_MASK 0x1000 -+#define RTL8367C_EEEP_TU_100M_OFFSET 8 -+#define RTL8367C_EEEP_TU_100M_MASK 0x300 -+#define RTL8367C_EEEP_TS_100M_OFFSET 0 -+#define RTL8367C_EEEP_TS_100M_MASK 0xFF -+ -+#define RTL8367C_REG_EEEP_CTRL0 0x12bc -+#define RTL8367C_EEEP_CTRL0_DUMMY_OFFSET 8 -+#define RTL8367C_EEEP_CTRL0_DUMMY_MASK 0xFF00 -+#define RTL8367C_EEEP_SLEEP_STEP_OFFSET 0 -+#define RTL8367C_EEEP_SLEEP_STEP_MASK 0xFF -+ -+#define RTL8367C_REG_EEEP_CTRL1 0x12bd -+#define RTL8367C_EEEP_TXR_GIGA_OFFSET 8 -+#define RTL8367C_EEEP_TXR_GIGA_MASK 0xFF00 -+#define RTL8367C_EEEP_TXR_100M_OFFSET 0 -+#define RTL8367C_EEEP_TXR_100M_MASK 0xFF -+ -+#define RTL8367C_REG_BACK_PRESSURE_IPG 0x12be -+#define RTL8367C_BACK_PRESSURE_IPG_OFFSET 0 -+#define RTL8367C_BACK_PRESSURE_IPG_MASK 0x3 -+ -+#define RTL8367C_REG_TX_ESD_LEVEL 0x12bf -+#define RTL8367C_TX_ESD_LEVEL_MODE_OFFSET 8 -+#define RTL8367C_TX_ESD_LEVEL_MODE_MASK 0x100 -+#define RTL8367C_LEVEL_OFFSET 0 -+#define RTL8367C_LEVEL_MASK 0xFF -+ -+#define RTL8367C_REG_RRCP_CTRL4 0x12e0 -+ -+#define RTL8367C_REG_RRCP_CTRL5 0x12e1 -+ -+#define RTL8367C_REG_RRCP_CTRL6 0x12e2 -+ -+#define RTL8367C_REG_RRCP_CTRL7 0x12e3 -+ -+#define RTL8367C_REG_RRCP_CTRL8 0x12e4 -+ -+#define RTL8367C_REG_RRCP_CTRL9 0x12e5 -+ -+#define RTL8367C_REG_RRCP_CTRL10 0x12e6 -+ -+#define RTL8367C_REG_FIELD_SELECTOR0 0x12e7 -+#define RTL8367C_FIELD_SELECTOR0_FORMAT_OFFSET 8 -+#define RTL8367C_FIELD_SELECTOR0_FORMAT_MASK 0x700 -+#define RTL8367C_FIELD_SELECTOR0_OFFSET_OFFSET 0 -+#define RTL8367C_FIELD_SELECTOR0_OFFSET_MASK 0xFF -+ -+#define RTL8367C_REG_FIELD_SELECTOR1 0x12e8 -+#define RTL8367C_FIELD_SELECTOR1_FORMAT_OFFSET 8 -+#define RTL8367C_FIELD_SELECTOR1_FORMAT_MASK 0x700 -+#define RTL8367C_FIELD_SELECTOR1_OFFSET_OFFSET 0 -+#define RTL8367C_FIELD_SELECTOR1_OFFSET_MASK 0xFF -+ -+#define RTL8367C_REG_FIELD_SELECTOR2 0x12e9 -+#define RTL8367C_FIELD_SELECTOR2_FORMAT_OFFSET 8 -+#define RTL8367C_FIELD_SELECTOR2_FORMAT_MASK 0x700 -+#define RTL8367C_FIELD_SELECTOR2_OFFSET_OFFSET 0 -+#define RTL8367C_FIELD_SELECTOR2_OFFSET_MASK 0xFF -+ -+#define RTL8367C_REG_FIELD_SELECTOR3 0x12ea -+#define RTL8367C_FIELD_SELECTOR3_FORMAT_OFFSET 8 -+#define RTL8367C_FIELD_SELECTOR3_FORMAT_MASK 0x700 -+#define RTL8367C_FIELD_SELECTOR3_OFFSET_OFFSET 0 -+#define RTL8367C_FIELD_SELECTOR3_OFFSET_MASK 0xFF -+ -+#define RTL8367C_REG_FIELD_SELECTOR4 0x12eb -+#define RTL8367C_FIELD_SELECTOR4_FORMAT_OFFSET 8 -+#define RTL8367C_FIELD_SELECTOR4_FORMAT_MASK 0x700 -+#define RTL8367C_FIELD_SELECTOR4_OFFSET_OFFSET 0 -+#define RTL8367C_FIELD_SELECTOR4_OFFSET_MASK 0xFF -+ -+#define RTL8367C_REG_FIELD_SELECTOR5 0x12ec -+#define RTL8367C_FIELD_SELECTOR5_FORMAT_OFFSET 8 -+#define RTL8367C_FIELD_SELECTOR5_FORMAT_MASK 0x700 -+#define RTL8367C_FIELD_SELECTOR5_OFFSET_OFFSET 0 -+#define RTL8367C_FIELD_SELECTOR5_OFFSET_MASK 0xFF -+ -+#define RTL8367C_REG_FIELD_SELECTOR6 0x12ed -+#define RTL8367C_FIELD_SELECTOR6_FORMAT_OFFSET 8 -+#define RTL8367C_FIELD_SELECTOR6_FORMAT_MASK 0x700 -+#define RTL8367C_FIELD_SELECTOR6_OFFSET_OFFSET 0 -+#define RTL8367C_FIELD_SELECTOR6_OFFSET_MASK 0xFF -+ -+#define RTL8367C_REG_FIELD_SELECTOR7 0x12ee -+#define RTL8367C_FIELD_SELECTOR7_FORMAT_OFFSET 8 -+#define RTL8367C_FIELD_SELECTOR7_FORMAT_MASK 0x700 -+#define RTL8367C_FIELD_SELECTOR7_OFFSET_OFFSET 0 -+#define RTL8367C_FIELD_SELECTOR7_OFFSET_MASK 0xFF -+ -+#define RTL8367C_REG_FIELD_SELECTOR8 0x12ef -+#define RTL8367C_FIELD_SELECTOR8_FORMAT_OFFSET 8 -+#define RTL8367C_FIELD_SELECTOR8_FORMAT_MASK 0x700 -+#define RTL8367C_FIELD_SELECTOR8_OFFSET_OFFSET 0 -+#define RTL8367C_FIELD_SELECTOR8_OFFSET_MASK 0xFF -+ -+#define RTL8367C_REG_FIELD_SELECTOR9 0x12f0 -+#define RTL8367C_FIELD_SELECTOR9_FORMAT_OFFSET 8 -+#define RTL8367C_FIELD_SELECTOR9_FORMAT_MASK 0x700 -+#define RTL8367C_FIELD_SELECTOR9_OFFSET_OFFSET 0 -+#define RTL8367C_FIELD_SELECTOR9_OFFSET_MASK 0xFF -+ -+#define RTL8367C_REG_FIELD_SELECTOR10 0x12f1 -+#define RTL8367C_FIELD_SELECTOR10_FORMAT_OFFSET 8 -+#define RTL8367C_FIELD_SELECTOR10_FORMAT_MASK 0x700 -+#define RTL8367C_FIELD_SELECTOR10_OFFSET_OFFSET 0 -+#define RTL8367C_FIELD_SELECTOR10_OFFSET_MASK 0xFF -+ -+#define RTL8367C_REG_FIELD_SELECTOR11 0x12f2 -+#define RTL8367C_FIELD_SELECTOR11_FORMAT_OFFSET 8 -+#define RTL8367C_FIELD_SELECTOR11_FORMAT_MASK 0x700 -+#define RTL8367C_FIELD_SELECTOR11_OFFSET_OFFSET 0 -+#define RTL8367C_FIELD_SELECTOR11_OFFSET_MASK 0xFF -+ -+#define RTL8367C_REG_FIELD_SELECTOR12 0x12f3 -+#define RTL8367C_FIELD_SELECTOR12_FORMAT_OFFSET 8 -+#define RTL8367C_FIELD_SELECTOR12_FORMAT_MASK 0x700 -+#define RTL8367C_FIELD_SELECTOR12_OFFSET_OFFSET 0 -+#define RTL8367C_FIELD_SELECTOR12_OFFSET_MASK 0xFF -+ -+#define RTL8367C_REG_FIELD_SELECTOR13 0x12f4 -+#define RTL8367C_FIELD_SELECTOR13_FORMAT_OFFSET 8 -+#define RTL8367C_FIELD_SELECTOR13_FORMAT_MASK 0x700 -+#define RTL8367C_FIELD_SELECTOR13_OFFSET_OFFSET 0 -+#define RTL8367C_FIELD_SELECTOR13_OFFSET_MASK 0xFF -+ -+#define RTL8367C_REG_FIELD_SELECTOR14 0x12f5 -+#define RTL8367C_FIELD_SELECTOR14_FORMAT_OFFSET 8 -+#define RTL8367C_FIELD_SELECTOR14_FORMAT_MASK 0x700 -+#define RTL8367C_FIELD_SELECTOR14_OFFSET_OFFSET 0 -+#define RTL8367C_FIELD_SELECTOR14_OFFSET_MASK 0xFF -+ -+#define RTL8367C_REG_FIELD_SELECTOR15 0x12f6 -+#define RTL8367C_FIELD_SELECTOR15_FORMAT_OFFSET 8 -+#define RTL8367C_FIELD_SELECTOR15_FORMAT_MASK 0x700 -+#define RTL8367C_FIELD_SELECTOR15_OFFSET_OFFSET 0 -+#define RTL8367C_FIELD_SELECTOR15_OFFSET_MASK 0xFF -+ -+#define RTL8367C_REG_HWPKT_GEN_MISC_H 0x12f7 -+#define RTL8367C_PKT_GEN_SUSPEND_P10_8_OFFSET 3 -+#define RTL8367C_PKT_GEN_SUSPEND_P10_8_MASK 0x38 -+#define RTL8367C_PKT_GEN_STATUS_P10_8_OFFSET 0 -+#define RTL8367C_PKT_GEN_STATUS_P10_8_MASK 0x7 -+ -+#define RTL8367C_REG_MIRROR_SRC_PMSK 0x12fb -+#define RTL8367C_MIRROR_SRC_PMSK_OFFSET 0 -+#define RTL8367C_MIRROR_SRC_PMSK_MASK 0x7FF -+ -+#define RTL8367C_REG_EEE_BURSTSIZE 0x12fc -+ -+#define RTL8367C_REG_EEE_IFG_CFG 0x12fd -+#define RTL8367C_EEE_IFG_CFG_OFFSET 0 -+#define RTL8367C_EEE_IFG_CFG_MASK 0x1 -+ -+#define RTL8367C_REG_FPGA_VER_MAC 0x12fe -+ -+#define RTL8367C_REG_HWPKT_GEN_MISC 0x12ff -+#define RTL8367C_PKT_GEN_SUSPEND_OFFSET 8 -+#define RTL8367C_PKT_GEN_SUSPEND_MASK 0xFF00 -+#define RTL8367C_PKT_GEN_STATUS_OFFSET 0 -+#define RTL8367C_PKT_GEN_STATUS_MASK 0xFF -+ -+/* (16'h1300)chip_reg */ -+ -+#define RTL8367C_REG_CHIP_NUMBER 0x1300 -+ -+#define RTL8367C_REG_CHIP_VER 0x1301 -+#define RTL8367C_VERID_OFFSET 12 -+#define RTL8367C_VERID_MASK 0xF000 -+#define RTL8367C_MCID_OFFSET 8 -+#define RTL8367C_MCID_MASK 0xF00 -+#define RTL8367C_MODEL_ID_OFFSET 4 -+#define RTL8367C_MODEL_ID_MASK 0xF0 -+#define RTL8367C_AFE_VERSION_OFFSET 0 -+#define RTL8367C_AFE_VERSION_MASK 0x1 -+ -+#define RTL8367C_REG_CHIP_DEBUG0 0x1303 -+#define RTL8367C_SEL33_EXT2_OFFSET 10 -+#define RTL8367C_SEL33_EXT2_MASK 0x400 -+#define RTL8367C_SEL33_EXT1_OFFSET 9 -+#define RTL8367C_SEL33_EXT1_MASK 0x200 -+#define RTL8367C_SEL33_EXT0_OFFSET 8 -+#define RTL8367C_SEL33_EXT0_MASK 0x100 -+#define RTL8367C_DRI_OTHER_OFFSET 7 -+#define RTL8367C_DRI_OTHER_MASK 0x80 -+#define RTL8367C_DRI_EXT1_RG_OFFSET 6 -+#define RTL8367C_DRI_EXT1_RG_MASK 0x40 -+#define RTL8367C_DRI_EXT0_RG_OFFSET 5 -+#define RTL8367C_DRI_EXT0_RG_MASK 0x20 -+#define RTL8367C_DRI_EXT1_OFFSET 4 -+#define RTL8367C_DRI_EXT1_MASK 0x10 -+#define RTL8367C_DRI_EXT0_OFFSET 3 -+#define RTL8367C_DRI_EXT0_MASK 0x8 -+#define RTL8367C_SLR_OTHER_OFFSET 2 -+#define RTL8367C_SLR_OTHER_MASK 0x4 -+#define RTL8367C_SLR_EXT1_OFFSET 1 -+#define RTL8367C_SLR_EXT1_MASK 0x2 -+#define RTL8367C_SLR_EXT0_OFFSET 0 -+#define RTL8367C_SLR_EXT0_MASK 0x1 -+ -+#define RTL8367C_REG_CHIP_DEBUG1 0x1304 -+#define RTL8367C_RG1_DN_OFFSET 12 -+#define RTL8367C_RG1_DN_MASK 0x7000 -+#define RTL8367C_RG1_DP_OFFSET 8 -+#define RTL8367C_RG1_DP_MASK 0x700 -+#define RTL8367C_RG0_DN_OFFSET 4 -+#define RTL8367C_RG0_DN_MASK 0x70 -+#define RTL8367C_RG0_DP_OFFSET 0 -+#define RTL8367C_RG0_DP_MASK 0x7 -+ -+#define RTL8367C_REG_DIGITAL_INTERFACE_SELECT 0x1305 -+#define RTL8367C_ORG_COL_OFFSET 15 -+#define RTL8367C_ORG_COL_MASK 0x8000 -+#define RTL8367C_ORG_CRS_OFFSET 14 -+#define RTL8367C_ORG_CRS_MASK 0x4000 -+#define RTL8367C_SKIP_MII_1_RXER_OFFSET 13 -+#define RTL8367C_SKIP_MII_1_RXER_MASK 0x2000 -+#define RTL8367C_SKIP_MII_0_RXER_OFFSET 12 -+#define RTL8367C_SKIP_MII_0_RXER_MASK 0x1000 -+#define RTL8367C_SELECT_GMII_1_OFFSET 4 -+#define RTL8367C_SELECT_GMII_1_MASK 0xF0 -+#define RTL8367C_SELECT_GMII_0_OFFSET 0 -+#define RTL8367C_SELECT_GMII_0_MASK 0xF -+ -+#define RTL8367C_REG_EXT0_RGMXF 0x1306 -+#define RTL8367C_EXT0_RGTX_INV_OFFSET 6 -+#define RTL8367C_EXT0_RGTX_INV_MASK 0x40 -+#define RTL8367C_EXT0_RGRX_INV_OFFSET 5 -+#define RTL8367C_EXT0_RGRX_INV_MASK 0x20 -+#define RTL8367C_EXT0_RGMXF_OFFSET 0 -+#define RTL8367C_EXT0_RGMXF_MASK 0x1F -+ -+#define RTL8367C_REG_EXT1_RGMXF 0x1307 -+#define RTL8367C_EXT1_RGTX_INV_OFFSET 6 -+#define RTL8367C_EXT1_RGTX_INV_MASK 0x40 -+#define RTL8367C_EXT1_RGRX_INV_OFFSET 5 -+#define RTL8367C_EXT1_RGRX_INV_MASK 0x20 -+#define RTL8367C_EXT1_RGMXF_OFFSET 0 -+#define RTL8367C_EXT1_RGMXF_MASK 0x1F -+ -+#define RTL8367C_REG_BISR_CTRL 0x1308 -+#define RTL8367C_BISR_CTRL_OFFSET 0 -+#define RTL8367C_BISR_CTRL_MASK 0x7 -+ -+#define RTL8367C_REG_SLF_IF 0x1309 -+#define RTL8367C_LINK_DOWN_CLR_FIFO_OFFSET 7 -+#define RTL8367C_LINK_DOWN_CLR_FIFO_MASK 0x80 -+#define RTL8367C_LOOPBACK_OFFSET 6 -+#define RTL8367C_LOOPBACK_MASK 0x40 -+#define RTL8367C_WATER_LEVEL_OFFSET 4 -+#define RTL8367C_WATER_LEVEL_MASK 0x30 -+#define RTL8367C_SLF_IF_OFFSET 0 -+#define RTL8367C_SLF_IF_MASK 0x3 -+ -+#define RTL8367C_REG_I2C_CLOCK_DIV 0x130a -+#define RTL8367C_I2C_CLOCK_DIV_OFFSET 0 -+#define RTL8367C_I2C_CLOCK_DIV_MASK 0x3FF -+ -+#define RTL8367C_REG_MDX_MDC_DIV 0x130b -+#define RTL8367C_MDX_MDC_DIV_OFFSET 0 -+#define RTL8367C_MDX_MDC_DIV_MASK 0x3FF -+ -+#define RTL8367C_REG_MISCELLANEOUS_CONFIGURE0 0x130c -+#define RTL8367C_ADCCKI_FROM_PAD_OFFSET 14 -+#define RTL8367C_ADCCKI_FROM_PAD_MASK 0x4000 -+#define RTL8367C_ADCCKI_EN_OFFSET 13 -+#define RTL8367C_ADCCKI_EN_MASK 0x2000 -+#define RTL8367C_FLASH_ENABLE_OFFSET 12 -+#define RTL8367C_FLASH_ENABLE_MASK 0x1000 -+#define RTL8367C_EEE_ENABLE_OFFSET 11 -+#define RTL8367C_EEE_ENABLE_MASK 0x800 -+#define RTL8367C_NIC_ENABLE_OFFSET 10 -+#define RTL8367C_NIC_ENABLE_MASK 0x400 -+#define RTL8367C_FT_ENABLE_OFFSET 9 -+#define RTL8367C_FT_ENABLE_MASK 0x200 -+#define RTL8367C_OLT_ENABLE_OFFSET 8 -+#define RTL8367C_OLT_ENABLE_MASK 0x100 -+#define RTL8367C_RTCT_EN_OFFSET 7 -+#define RTL8367C_RTCT_EN_MASK 0x80 -+#define RTL8367C_PON_LIGHT_EN_OFFSET 6 -+#define RTL8367C_PON_LIGHT_EN_MASK 0x40 -+#define RTL8367C_DW8051_EN_OFFSET 5 -+#define RTL8367C_DW8051_EN_MASK 0x20 -+#define RTL8367C_AUTOLOAD_EN_OFFSET 4 -+#define RTL8367C_AUTOLOAD_EN_MASK 0x10 -+#define RTL8367C_NRESTORE_EN_OFFSET 3 -+#define RTL8367C_NRESTORE_EN_MASK 0x8 -+#define RTL8367C_DIS_PON_TABLE_INIT_OFFSET 2 -+#define RTL8367C_DIS_PON_TABLE_INIT_MASK 0x4 -+#define RTL8367C_DIS_PON_BIST_OFFSET 1 -+#define RTL8367C_DIS_PON_BIST_MASK 0x2 -+#define RTL8367C_EFUSE_EN_OFFSET 0 -+#define RTL8367C_EFUSE_EN_MASK 0x1 -+ -+#define RTL8367C_REG_MISCELLANEOUS_CONFIGURE1 0x130d -+#define RTL8367C_EEPROM_DEV_ADR_OFFSET 8 -+#define RTL8367C_EEPROM_DEV_ADR_MASK 0x7F00 -+#define RTL8367C_EEPROM_MSB_OFFSET 7 -+#define RTL8367C_EEPROM_MSB_MASK 0x80 -+#define RTL8367C_EEPROM_ADDRESS_16B_OFFSET 6 -+#define RTL8367C_EEPROM_ADDRESS_16B_MASK 0x40 -+#define RTL8367C_EEPROM_DWONLOAD_COMPLETE_OFFSET 3 -+#define RTL8367C_EEPROM_DWONLOAD_COMPLETE_MASK 0x8 -+#define RTL8367C_SPI_SLAVE_EN_OFFSET 2 -+#define RTL8367C_SPI_SLAVE_EN_MASK 0x4 -+#define RTL8367C_SMI_SEL_OFFSET 0 -+#define RTL8367C_SMI_SEL_MASK 0x3 -+ -+#define RTL8367C_REG_PHY_AD 0x130f -+#define RTL8367C_EN_PHY_MAX_POWER_OFFSET 14 -+#define RTL8367C_EN_PHY_MAX_POWER_MASK 0x4000 -+#define RTL8367C_EN_PHY_SEL_DEG_OFFSET 13 -+#define RTL8367C_EN_PHY_SEL_DEG_MASK 0x2000 -+#define RTL8367C_EXTPHY_AD_OFFSET 8 -+#define RTL8367C_EXTPHY_AD_MASK 0x1F00 -+#define RTL8367C_EN_PHY_LOW_POWER_MODE_OFFSET 7 -+#define RTL8367C_EN_PHY_LOW_POWER_MODE_MASK 0x80 -+#define RTL8367C_EN_PHY_GREEN_OFFSET 6 -+#define RTL8367C_EN_PHY_GREEN_MASK 0x40 -+#define RTL8367C_PDNPHY_OFFSET 5 -+#define RTL8367C_PDNPHY_MASK 0x20 -+#define RTL8367C_INTPHY_AD_OFFSET 0 -+#define RTL8367C_INTPHY_AD_MASK 0x1F -+ -+#define RTL8367C_REG_DIGITAL_INTERFACE0_FORCE 0x1310 -+#define RTL8367C_GMII_0_FORCE_OFFSET 12 -+#define RTL8367C_GMII_0_FORCE_MASK 0x1000 -+#define RTL8367C_RGMII_0_FORCE_OFFSET 0 -+#define RTL8367C_RGMII_0_FORCE_MASK 0xFFF -+ -+#define RTL8367C_REG_DIGITAL_INTERFACE1_FORCE 0x1311 -+#define RTL8367C_GMII_1_FORCE_OFFSET 12 -+#define RTL8367C_GMII_1_FORCE_MASK 0x1000 -+#define RTL8367C_RGMII_1_FORCE_OFFSET 0 -+#define RTL8367C_RGMII_1_FORCE_MASK 0xFFF -+ -+#define RTL8367C_REG_MAC0_FORCE_SELECT 0x1312 -+#define RTL8367C_EN_MAC0_FORCE_OFFSET 12 -+#define RTL8367C_EN_MAC0_FORCE_MASK 0x1000 -+#define RTL8367C_MAC0_FORCE_ABLTY_OFFSET 0 -+#define RTL8367C_MAC0_FORCE_ABLTY_MASK 0xFFF -+ -+#define RTL8367C_REG_MAC1_FORCE_SELECT 0x1313 -+#define RTL8367C_EN_MAC1_FORCE_OFFSET 12 -+#define RTL8367C_EN_MAC1_FORCE_MASK 0x1000 -+#define RTL8367C_MAC1_FORCE_ABLTY_OFFSET 0 -+#define RTL8367C_MAC1_FORCE_ABLTY_MASK 0xFFF -+ -+#define RTL8367C_REG_MAC2_FORCE_SELECT 0x1314 -+#define RTL8367C_EN_MAC2_FORCE_OFFSET 12 -+#define RTL8367C_EN_MAC2_FORCE_MASK 0x1000 -+#define RTL8367C_MAC2_FORCE_ABLTY_OFFSET 0 -+#define RTL8367C_MAC2_FORCE_ABLTY_MASK 0xFFF -+ -+#define RTL8367C_REG_MAC3_FORCE_SELECT 0x1315 -+#define RTL8367C_EN_MAC3_FORCE_OFFSET 12 -+#define RTL8367C_EN_MAC3_FORCE_MASK 0x1000 -+#define RTL8367C_MAC3_FORCE_ABLTY_OFFSET 0 -+#define RTL8367C_MAC3_FORCE_ABLTY_MASK 0xFFF -+ -+#define RTL8367C_REG_MAC4_FORCE_SELECT 0x1316 -+#define RTL8367C_EN_MAC4_FORCE_OFFSET 12 -+#define RTL8367C_EN_MAC4_FORCE_MASK 0x1000 -+#define RTL8367C_MAC4_FORCE_ABLTY_OFFSET 0 -+#define RTL8367C_MAC4_FORCE_ABLTY_MASK 0xFFF -+ -+#define RTL8367C_REG_MAC5_FORCE_SELECT 0x1317 -+#define RTL8367C_EN_MAC5_FORCE_OFFSET 12 -+#define RTL8367C_EN_MAC5_FORCE_MASK 0x1000 -+#define RTL8367C_MAC5_FORCE_ABLTY_OFFSET 0 -+#define RTL8367C_MAC5_FORCE_ABLTY_MASK 0xFFF -+ -+#define RTL8367C_REG_MAC6_FORCE_SELECT 0x1318 -+#define RTL8367C_EN_MAC6_FORCE_OFFSET 12 -+#define RTL8367C_EN_MAC6_FORCE_MASK 0x1000 -+#define RTL8367C_MAC6_FORCE_ABLTY_OFFSET 0 -+#define RTL8367C_MAC6_FORCE_ABLTY_MASK 0xFFF -+ -+#define RTL8367C_REG_MAC7_FORCE_SELECT 0x1319 -+#define RTL8367C_EN_MAC7_FORCE_OFFSET 12 -+#define RTL8367C_EN_MAC7_FORCE_MASK 0x1000 -+#define RTL8367C_MAC7_FORCE_ABLTY_OFFSET 0 -+#define RTL8367C_MAC7_FORCE_ABLTY_MASK 0xFFF -+ -+#define RTL8367C_REG_M10_FORCE_SELECT 0x131c -+#define RTL8367C_EN_M10_FORCE_OFFSET 12 -+#define RTL8367C_EN_M10_FORCE_MASK 0x1000 -+#define RTL8367C_M10_FORCE_ABLTY_OFFSET 0 -+#define RTL8367C_M10_FORCE_ABLTY_MASK 0xFFF -+ -+#define RTL8367C_REG_CHIP_RESET 0x1322 -+#define RTL8367C_GPHY_RESET_OFFSET 6 -+#define RTL8367C_GPHY_RESET_MASK 0x40 -+#define RTL8367C_NIC_RST_OFFSET 5 -+#define RTL8367C_NIC_RST_MASK 0x20 -+#define RTL8367C_DW8051_RST_OFFSET 4 -+#define RTL8367C_DW8051_RST_MASK 0x10 -+#define RTL8367C_SDS_RST_OFFSET 3 -+#define RTL8367C_SDS_RST_MASK 0x8 -+#define RTL8367C_CONFIG_RST_OFFSET 2 -+#define RTL8367C_CONFIG_RST_MASK 0x4 -+#define RTL8367C_SW_RST_OFFSET 1 -+#define RTL8367C_SW_RST_MASK 0x2 -+#define RTL8367C_CHIP_RST_OFFSET 0 -+#define RTL8367C_CHIP_RST_MASK 0x1 -+ -+#define RTL8367C_REG_DIGITAL_DEBUG_0 0x1323 -+ -+#define RTL8367C_REG_DIGITAL_DEBUG_1 0x1324 -+ -+#define RTL8367C_REG_INTERNAL_PHY_MDC_DRIVER 0x1325 -+#define RTL8367C_INTERNAL_PHY_MDC_DRIVER_OFFSET 0 -+#define RTL8367C_INTERNAL_PHY_MDC_DRIVER_MASK 0x3FF -+ -+#define RTL8367C_REG_LINKDOWN_TIME_CTRL 0x1326 -+#define RTL8367C_LINKDOWN_TIME_CFG_OFFSET 9 -+#define RTL8367C_LINKDOWN_TIME_CFG_MASK 0x7E00 -+#define RTL8367C_LINKDOWN_TIME_ENABLE_OFFSET 8 -+#define RTL8367C_LINKDOWN_TIME_ENABLE_MASK 0x100 -+#define RTL8367C_LINKDOWN_TIME_OFFSET 0 -+#define RTL8367C_LINKDOWN_TIME_MASK 0xFF -+ -+#define RTL8367C_REG_PHYACK_TIMEOUT 0x1331 -+ -+#define RTL8367C_REG_MDXACK_TIMEOUT 0x1333 -+ -+#define RTL8367C_REG_DW8051_RDY 0x1336 -+#define RTL8367C_VIAROM_WRITE_EN_OFFSET 9 -+#define RTL8367C_VIAROM_WRITE_EN_MASK 0x200 -+#define RTL8367C_SPIF_CK2_OFFSET 8 -+#define RTL8367C_SPIF_CK2_MASK 0x100 -+#define RTL8367C_RRCP_MDOE_OFFSET 7 -+#define RTL8367C_RRCP_MDOE_MASK 0x80 -+#define RTL8367C_DW8051_RATE_OFFSET 4 -+#define RTL8367C_DW8051_RATE_MASK 0x70 -+#define RTL8367C_IROM_MSB_OFFSET 2 -+#define RTL8367C_IROM_MSB_MASK 0xC -+#define RTL8367C_ACS_IROM_ENABLE_OFFSET 1 -+#define RTL8367C_ACS_IROM_ENABLE_MASK 0x2 -+#define RTL8367C_DW8051_READY_OFFSET 0 -+#define RTL8367C_DW8051_READY_MASK 0x1 -+ -+#define RTL8367C_REG_BIST_CTRL 0x133c -+#define RTL8367C_DRF_BIST_DONE_ALL_OFFSET 5 -+#define RTL8367C_DRF_BIST_DONE_ALL_MASK 0x20 -+#define RTL8367C_DRF_BIST_PAUSE_ALL_OFFSET 4 -+#define RTL8367C_DRF_BIST_PAUSE_ALL_MASK 0x10 -+#define RTL8367C_BIST_DOAN_ALL_OFFSET 3 -+#define RTL8367C_BIST_DOAN_ALL_MASK 0x8 -+#define RTL8367C_BIST_PASS_OFFSET 0 -+#define RTL8367C_BIST_PASS_MASK 0x7 -+ -+#define RTL8367C_REG_DIAG_MODE2 0x133d -+#define RTL8367C_DIAG_MODE2_ACTRAM_OFFSET 1 -+#define RTL8367C_DIAG_MODE2_ACTRAM_MASK 0x2 -+#define RTL8367C_DIAG_MODE2_BCAM_ACTION_OFFSET 0 -+#define RTL8367C_DIAG_MODE2_BCAM_ACTION_MASK 0x1 -+ -+#define RTL8367C_REG_MDX_PHY_REG0 0x133e -+#define RTL8367C_PHY_BRD_MASK_OFFSET 4 -+#define RTL8367C_PHY_BRD_MASK_MASK 0x1F0 -+#define RTL8367C_MDX_INDACC_PAGE_OFFSET 0 -+#define RTL8367C_MDX_INDACC_PAGE_MASK 0xF -+ -+#define RTL8367C_REG_MDX_PHY_REG1 0x133f -+#define RTL8367C_PHY_BRD_MODE_OFFSET 5 -+#define RTL8367C_PHY_BRD_MODE_MASK 0x20 -+#define RTL8367C_BRD_PHYAD_OFFSET 0 -+#define RTL8367C_BRD_PHYAD_MASK 0x1F -+ -+#define RTL8367C_REG_DEBUG_SIGNAL_SELECT_SW 0x1340 -+ -+#define RTL8367C_REG_DEBUG_SIGNAL_SELECT_B 0x1341 -+#define RTL8367C_DEBUG_MX_OFFSET 9 -+#define RTL8367C_DEBUG_MX_MASK 0xE00 -+#define RTL8367C_DEBUG_SHIFT_MISC_OFFSET 6 -+#define RTL8367C_DEBUG_SHIFT_MISC_MASK 0x1C0 -+#define RTL8367C_DEBUG_SHIFT_SW_OFFSET 3 -+#define RTL8367C_DEBUG_SHIFT_SW_MASK 0x38 -+#define RTL8367C_DEBUG_SHIFT_GPHY_OFFSET 0 -+#define RTL8367C_DEBUG_SHIFT_GPHY_MASK 0x7 -+ -+#define RTL8367C_REG_DEBUG_SIGNAL_I 0x1343 -+ -+#define RTL8367C_REG_DEBUG_SIGNAL_H 0x1344 -+ -+#define RTL8367C_REG_DBGO_SEL_GPHY 0x1345 -+ -+#define RTL8367C_REG_DBGO_SEL_MISC 0x1346 -+ -+#define RTL8367C_REG_BYPASS_ABLTY_LOCK 0x1349 -+#define RTL8367C_BYPASS_ABLTY_LOCK_OFFSET 0 -+#define RTL8367C_BYPASS_ABLTY_LOCK_MASK 0xFF -+ -+#define RTL8367C_REG_BYPASS_ABLTY_LOCK_EXT 0x134a -+#define RTL8367C_BYPASS_P10_ABILIITY_LOCK_OFFSET 3 -+#define RTL8367C_BYPASS_P10_ABILIITY_LOCK_MASK 0x8 -+#define RTL8367C_BYPASS_EXT_ABILITY_LOCK_OFFSET 0 -+#define RTL8367C_BYPASS_EXT_ABILITY_LOCK_MASK 0x7 -+ -+#define RTL8367C_REG_ACL_GPIO 0x134f -+#define RTL8367C_ACL_GPIO_13_OFFSET 13 -+#define RTL8367C_ACL_GPIO_13_MASK 0x2000 -+#define RTL8367C_ACL_GPIO_12_OFFSET 12 -+#define RTL8367C_ACL_GPIO_12_MASK 0x1000 -+#define RTL8367C_ACL_GPIO_11_OFFSET 11 -+#define RTL8367C_ACL_GPIO_11_MASK 0x800 -+#define RTL8367C_ACL_GPIO_10_OFFSET 10 -+#define RTL8367C_ACL_GPIO_10_MASK 0x400 -+#define RTL8367C_ACL_GPIO_9_OFFSET 9 -+#define RTL8367C_ACL_GPIO_9_MASK 0x200 -+#define RTL8367C_ACL_GPIO_8_OFFSET 8 -+#define RTL8367C_ACL_GPIO_8_MASK 0x100 -+#define RTL8367C_ACL_GPIO_7_OFFSET 7 -+#define RTL8367C_ACL_GPIO_7_MASK 0x80 -+#define RTL8367C_ACL_GPIO_6_OFFSET 6 -+#define RTL8367C_ACL_GPIO_6_MASK 0x40 -+#define RTL8367C_ACL_GPIO_5_OFFSET 5 -+#define RTL8367C_ACL_GPIO_5_MASK 0x20 -+#define RTL8367C_ACL_GPIO_4_OFFSET 4 -+#define RTL8367C_ACL_GPIO_4_MASK 0x10 -+#define RTL8367C_ACL_GPIO_3_OFFSET 3 -+#define RTL8367C_ACL_GPIO_3_MASK 0x8 -+#define RTL8367C_ACL_GPIO_2_OFFSET 2 -+#define RTL8367C_ACL_GPIO_2_MASK 0x4 -+#define RTL8367C_ACL_GPIO_1_OFFSET 1 -+#define RTL8367C_ACL_GPIO_1_MASK 0x2 -+#define RTL8367C_ACL_GPIO_0_OFFSET 0 -+#define RTL8367C_ACL_GPIO_0_MASK 0x1 -+ -+#define RTL8367C_REG_EN_GPIO 0x1350 -+#define RTL8367C_EN_GPIO_13_OFFSET 13 -+#define RTL8367C_EN_GPIO_13_MASK 0x2000 -+#define RTL8367C_EN_GPIO_12_OFFSET 12 -+#define RTL8367C_EN_GPIO_12_MASK 0x1000 -+#define RTL8367C_EN_GPIO_11_OFFSET 11 -+#define RTL8367C_EN_GPIO_11_MASK 0x800 -+#define RTL8367C_EN_GPIO_10_OFFSET 10 -+#define RTL8367C_EN_GPIO_10_MASK 0x400 -+#define RTL8367C_EN_GPIO_9_OFFSET 9 -+#define RTL8367C_EN_GPIO_9_MASK 0x200 -+#define RTL8367C_EN_GPIO_8_OFFSET 8 -+#define RTL8367C_EN_GPIO_8_MASK 0x100 -+#define RTL8367C_EN_GPIO_7_OFFSET 7 -+#define RTL8367C_EN_GPIO_7_MASK 0x80 -+#define RTL8367C_EN_GPIO_6_OFFSET 6 -+#define RTL8367C_EN_GPIO_6_MASK 0x40 -+#define RTL8367C_EN_GPIO_5_OFFSET 5 -+#define RTL8367C_EN_GPIO_5_MASK 0x20 -+#define RTL8367C_EN_GPIO_4_OFFSET 4 -+#define RTL8367C_EN_GPIO_4_MASK 0x10 -+#define RTL8367C_EN_GPIO_3_OFFSET 3 -+#define RTL8367C_EN_GPIO_3_MASK 0x8 -+#define RTL8367C_EN_GPIO_2_OFFSET 2 -+#define RTL8367C_EN_GPIO_2_MASK 0x4 -+#define RTL8367C_EN_GPIO_1_OFFSET 1 -+#define RTL8367C_EN_GPIO_1_MASK 0x2 -+#define RTL8367C_EN_GPIO_0_OFFSET 0 -+#define RTL8367C_EN_GPIO_0_MASK 0x1 -+ -+#define RTL8367C_REG_CFG_MULTI_PIN 0x1351 -+#define RTL8367C_CFG_MULTI_PIN_OFFSET 0 -+#define RTL8367C_CFG_MULTI_PIN_MASK 0x3 -+ -+#define RTL8367C_REG_PORT0_STATUS 0x1352 -+#define RTL8367C_PORT0_STATUS_EN_1000_LPI_OFFSET 11 -+#define RTL8367C_PORT0_STATUS_EN_1000_LPI_MASK 0x800 -+#define RTL8367C_PORT0_STATUS_EN_100_LPI_OFFSET 10 -+#define RTL8367C_PORT0_STATUS_EN_100_LPI_MASK 0x400 -+#define RTL8367C_PORT0_STATUS_NWAY_FAULT_OFFSET 9 -+#define RTL8367C_PORT0_STATUS_NWAY_FAULT_MASK 0x200 -+#define RTL8367C_PORT0_STATUS_LINK_ON_MASTER_OFFSET 8 -+#define RTL8367C_PORT0_STATUS_LINK_ON_MASTER_MASK 0x100 -+#define RTL8367C_PORT0_STATUS_NWAY_CAP_OFFSET 7 -+#define RTL8367C_PORT0_STATUS_NWAY_CAP_MASK 0x80 -+#define RTL8367C_PORT0_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 -+#define RTL8367C_PORT0_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 -+#define RTL8367C_PORT0_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 -+#define RTL8367C_PORT0_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 -+#define RTL8367C_PORT0_STATUS_LINK_STATE_OFFSET 4 -+#define RTL8367C_PORT0_STATUS_LINK_STATE_MASK 0x10 -+#define RTL8367C_PORT0_STATUS_FULL_DUPLUX_CAP_OFFSET 2 -+#define RTL8367C_PORT0_STATUS_FULL_DUPLUX_CAP_MASK 0x4 -+#define RTL8367C_PORT0_STATUS_LINK_SPEED_OFFSET 0 -+#define RTL8367C_PORT0_STATUS_LINK_SPEED_MASK 0x3 -+ -+#define RTL8367C_REG_PORT1_STATUS 0x1353 -+#define RTL8367C_PORT1_STATUS_EN_1000_LPI_OFFSET 11 -+#define RTL8367C_PORT1_STATUS_EN_1000_LPI_MASK 0x800 -+#define RTL8367C_PORT1_STATUS_EN_100_LPI_OFFSET 10 -+#define RTL8367C_PORT1_STATUS_EN_100_LPI_MASK 0x400 -+#define RTL8367C_PORT1_STATUS_NWAY_FAULT_OFFSET 9 -+#define RTL8367C_PORT1_STATUS_NWAY_FAULT_MASK 0x200 -+#define RTL8367C_PORT1_STATUS_LINK_ON_MASTER_OFFSET 8 -+#define RTL8367C_PORT1_STATUS_LINK_ON_MASTER_MASK 0x100 -+#define RTL8367C_PORT1_STATUS_NWAY_CAP_OFFSET 7 -+#define RTL8367C_PORT1_STATUS_NWAY_CAP_MASK 0x80 -+#define RTL8367C_PORT1_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 -+#define RTL8367C_PORT1_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 -+#define RTL8367C_PORT1_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 -+#define RTL8367C_PORT1_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 -+#define RTL8367C_PORT1_STATUS_LINK_STATE_OFFSET 4 -+#define RTL8367C_PORT1_STATUS_LINK_STATE_MASK 0x10 -+#define RTL8367C_PORT1_STATUS_FULL_DUPLUX_CAP_OFFSET 2 -+#define RTL8367C_PORT1_STATUS_FULL_DUPLUX_CAP_MASK 0x4 -+#define RTL8367C_PORT1_STATUS_LINK_SPEED_OFFSET 0 -+#define RTL8367C_PORT1_STATUS_LINK_SPEED_MASK 0x3 -+ -+#define RTL8367C_REG_PORT2_STATUS 0x1354 -+#define RTL8367C_PORT2_STATUS_EN_1000_LPI_OFFSET 11 -+#define RTL8367C_PORT2_STATUS_EN_1000_LPI_MASK 0x800 -+#define RTL8367C_PORT2_STATUS_EN_100_LPI_OFFSET 10 -+#define RTL8367C_PORT2_STATUS_EN_100_LPI_MASK 0x400 -+#define RTL8367C_PORT2_STATUS_NWAY_FAULT_OFFSET 9 -+#define RTL8367C_PORT2_STATUS_NWAY_FAULT_MASK 0x200 -+#define RTL8367C_PORT2_STATUS_LINK_ON_MASTER_OFFSET 8 -+#define RTL8367C_PORT2_STATUS_LINK_ON_MASTER_MASK 0x100 -+#define RTL8367C_PORT2_STATUS_NWAY_CAP_OFFSET 7 -+#define RTL8367C_PORT2_STATUS_NWAY_CAP_MASK 0x80 -+#define RTL8367C_PORT2_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 -+#define RTL8367C_PORT2_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 -+#define RTL8367C_PORT2_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 -+#define RTL8367C_PORT2_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 -+#define RTL8367C_PORT2_STATUS_LINK_STATE_OFFSET 4 -+#define RTL8367C_PORT2_STATUS_LINK_STATE_MASK 0x10 -+#define RTL8367C_PORT2_STATUS_FULL_DUPLUX_CAP_OFFSET 2 -+#define RTL8367C_PORT2_STATUS_FULL_DUPLUX_CAP_MASK 0x4 -+#define RTL8367C_PORT2_STATUS_LINK_SPEED_OFFSET 0 -+#define RTL8367C_PORT2_STATUS_LINK_SPEED_MASK 0x3 -+ -+#define RTL8367C_REG_PORT3_STATUS 0x1355 -+#define RTL8367C_PORT3_STATUS_EN_1000_LPI_OFFSET 11 -+#define RTL8367C_PORT3_STATUS_EN_1000_LPI_MASK 0x800 -+#define RTL8367C_PORT3_STATUS_EN_100_LPI_OFFSET 10 -+#define RTL8367C_PORT3_STATUS_EN_100_LPI_MASK 0x400 -+#define RTL8367C_PORT3_STATUS_NWAY_FAULT_OFFSET 9 -+#define RTL8367C_PORT3_STATUS_NWAY_FAULT_MASK 0x200 -+#define RTL8367C_PORT3_STATUS_LINK_ON_MASTER_OFFSET 8 -+#define RTL8367C_PORT3_STATUS_LINK_ON_MASTER_MASK 0x100 -+#define RTL8367C_PORT3_STATUS_NWAY_CAP_OFFSET 7 -+#define RTL8367C_PORT3_STATUS_NWAY_CAP_MASK 0x80 -+#define RTL8367C_PORT3_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 -+#define RTL8367C_PORT3_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 -+#define RTL8367C_PORT3_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 -+#define RTL8367C_PORT3_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 -+#define RTL8367C_PORT3_STATUS_LINK_STATE_OFFSET 4 -+#define RTL8367C_PORT3_STATUS_LINK_STATE_MASK 0x10 -+#define RTL8367C_PORT3_STATUS_FULL_DUPLUX_CAP_OFFSET 2 -+#define RTL8367C_PORT3_STATUS_FULL_DUPLUX_CAP_MASK 0x4 -+#define RTL8367C_PORT3_STATUS_LINK_SPEED_OFFSET 0 -+#define RTL8367C_PORT3_STATUS_LINK_SPEED_MASK 0x3 -+ -+#define RTL8367C_REG_PORT4_STATUS 0x1356 -+#define RTL8367C_PORT4_STATUS_EN_1000_LPI_OFFSET 11 -+#define RTL8367C_PORT4_STATUS_EN_1000_LPI_MASK 0x800 -+#define RTL8367C_PORT4_STATUS_EN_100_LPI_OFFSET 10 -+#define RTL8367C_PORT4_STATUS_EN_100_LPI_MASK 0x400 -+#define RTL8367C_PORT4_STATUS_NWAY_FAULT_OFFSET 9 -+#define RTL8367C_PORT4_STATUS_NWAY_FAULT_MASK 0x200 -+#define RTL8367C_PORT4_STATUS_LINK_ON_MASTER_OFFSET 8 -+#define RTL8367C_PORT4_STATUS_LINK_ON_MASTER_MASK 0x100 -+#define RTL8367C_PORT4_STATUS_NWAY_CAP_OFFSET 7 -+#define RTL8367C_PORT4_STATUS_NWAY_CAP_MASK 0x80 -+#define RTL8367C_PORT4_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 -+#define RTL8367C_PORT4_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 -+#define RTL8367C_PORT4_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 -+#define RTL8367C_PORT4_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 -+#define RTL8367C_PORT4_STATUS_LINK_STATE_OFFSET 4 -+#define RTL8367C_PORT4_STATUS_LINK_STATE_MASK 0x10 -+#define RTL8367C_PORT4_STATUS_FULL_DUPLUX_CAP_OFFSET 2 -+#define RTL8367C_PORT4_STATUS_FULL_DUPLUX_CAP_MASK 0x4 -+#define RTL8367C_PORT4_STATUS_LINK_SPEED_OFFSET 0 -+#define RTL8367C_PORT4_STATUS_LINK_SPEED_MASK 0x3 -+ -+#define RTL8367C_REG_PORT5_STATUS 0x1357 -+#define RTL8367C_PORT5_STATUS_EN_1000_LPI_OFFSET 11 -+#define RTL8367C_PORT5_STATUS_EN_1000_LPI_MASK 0x800 -+#define RTL8367C_PORT5_STATUS_EN_100_LPI_OFFSET 10 -+#define RTL8367C_PORT5_STATUS_EN_100_LPI_MASK 0x400 -+#define RTL8367C_PORT5_STATUS_NWAY_FAULT_OFFSET 9 -+#define RTL8367C_PORT5_STATUS_NWAY_FAULT_MASK 0x200 -+#define RTL8367C_PORT5_STATUS_LINK_ON_MASTER_OFFSET 8 -+#define RTL8367C_PORT5_STATUS_LINK_ON_MASTER_MASK 0x100 -+#define RTL8367C_PORT5_STATUS_NWAY_CAP_OFFSET 7 -+#define RTL8367C_PORT5_STATUS_NWAY_CAP_MASK 0x80 -+#define RTL8367C_PORT5_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 -+#define RTL8367C_PORT5_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 -+#define RTL8367C_PORT5_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 -+#define RTL8367C_PORT5_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 -+#define RTL8367C_PORT5_STATUS_LINK_STATE_OFFSET 4 -+#define RTL8367C_PORT5_STATUS_LINK_STATE_MASK 0x10 -+#define RTL8367C_PORT5_STATUS_FULL_DUPLUX_CAP_OFFSET 2 -+#define RTL8367C_PORT5_STATUS_FULL_DUPLUX_CAP_MASK 0x4 -+#define RTL8367C_PORT5_STATUS_LINK_SPEED_OFFSET 0 -+#define RTL8367C_PORT5_STATUS_LINK_SPEED_MASK 0x3 -+ -+#define RTL8367C_REG_PORT6_STATUS 0x1358 -+#define RTL8367C_PORT6_STATUS_EN_1000_LPI_OFFSET 11 -+#define RTL8367C_PORT6_STATUS_EN_1000_LPI_MASK 0x800 -+#define RTL8367C_PORT6_STATUS_EN_100_LPI_OFFSET 10 -+#define RTL8367C_PORT6_STATUS_EN_100_LPI_MASK 0x400 -+#define RTL8367C_PORT6_STATUS_NWAY_FAULT_OFFSET 9 -+#define RTL8367C_PORT6_STATUS_NWAY_FAULT_MASK 0x200 -+#define RTL8367C_PORT6_STATUS_LINK_ON_MASTER_OFFSET 8 -+#define RTL8367C_PORT6_STATUS_LINK_ON_MASTER_MASK 0x100 -+#define RTL8367C_PORT6_STATUS_NWAY_CAP_OFFSET 7 -+#define RTL8367C_PORT6_STATUS_NWAY_CAP_MASK 0x80 -+#define RTL8367C_PORT6_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 -+#define RTL8367C_PORT6_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 -+#define RTL8367C_PORT6_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 -+#define RTL8367C_PORT6_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 -+#define RTL8367C_PORT6_STATUS_LINK_STATE_OFFSET 4 -+#define RTL8367C_PORT6_STATUS_LINK_STATE_MASK 0x10 -+#define RTL8367C_PORT6_STATUS_FULL_DUPLUX_CAP_OFFSET 2 -+#define RTL8367C_PORT6_STATUS_FULL_DUPLUX_CAP_MASK 0x4 -+#define RTL8367C_PORT6_STATUS_LINK_SPEED_OFFSET 0 -+#define RTL8367C_PORT6_STATUS_LINK_SPEED_MASK 0x3 -+ -+#define RTL8367C_REG_PORT7_STATUS 0x1359 -+#define RTL8367C_PORT7_STATUS_EN_1000_LPI_OFFSET 11 -+#define RTL8367C_PORT7_STATUS_EN_1000_LPI_MASK 0x800 -+#define RTL8367C_PORT7_STATUS_EN_100_LPI_OFFSET 10 -+#define RTL8367C_PORT7_STATUS_EN_100_LPI_MASK 0x400 -+#define RTL8367C_PORT7_STATUS_NWAY_FAULT_OFFSET 9 -+#define RTL8367C_PORT7_STATUS_NWAY_FAULT_MASK 0x200 -+#define RTL8367C_PORT7_STATUS_LINK_ON_MASTER_OFFSET 8 -+#define RTL8367C_PORT7_STATUS_LINK_ON_MASTER_MASK 0x100 -+#define RTL8367C_PORT7_STATUS_NWAY_CAP_OFFSET 7 -+#define RTL8367C_PORT7_STATUS_NWAY_CAP_MASK 0x80 -+#define RTL8367C_PORT7_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 -+#define RTL8367C_PORT7_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 -+#define RTL8367C_PORT7_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 -+#define RTL8367C_PORT7_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 -+#define RTL8367C_PORT7_STATUS_LINK_STATE_OFFSET 4 -+#define RTL8367C_PORT7_STATUS_LINK_STATE_MASK 0x10 -+#define RTL8367C_PORT7_STATUS_FULL_DUPLUX_CAP_OFFSET 2 -+#define RTL8367C_PORT7_STATUS_FULL_DUPLUX_CAP_MASK 0x4 -+#define RTL8367C_PORT7_STATUS_LINK_SPEED_OFFSET 0 -+#define RTL8367C_PORT7_STATUS_LINK_SPEED_MASK 0x3 -+ -+#define RTL8367C_REG_PORT8_STATUS 0x135a -+#define RTL8367C_PORT8_STATUS_EN_1000_LPI_OFFSET 11 -+#define RTL8367C_PORT8_STATUS_EN_1000_LPI_MASK 0x800 -+#define RTL8367C_PORT8_STATUS_EN_100_LPI_OFFSET 10 -+#define RTL8367C_PORT8_STATUS_EN_100_LPI_MASK 0x400 -+#define RTL8367C_PORT8_STATUS_NWAY_FAULT_OFFSET 9 -+#define RTL8367C_PORT8_STATUS_NWAY_FAULT_MASK 0x200 -+#define RTL8367C_PORT8_STATUS_LINK_ON_MASTER_OFFSET 8 -+#define RTL8367C_PORT8_STATUS_LINK_ON_MASTER_MASK 0x100 -+#define RTL8367C_PORT8_STATUS_NWAY_CAP_OFFSET 7 -+#define RTL8367C_PORT8_STATUS_NWAY_CAP_MASK 0x80 -+#define RTL8367C_PORT8_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 -+#define RTL8367C_PORT8_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 -+#define RTL8367C_PORT8_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 -+#define RTL8367C_PORT8_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 -+#define RTL8367C_PORT8_STATUS_LINK_STATE_OFFSET 4 -+#define RTL8367C_PORT8_STATUS_LINK_STATE_MASK 0x10 -+#define RTL8367C_PORT8_STATUS_FULL_DUPLUX_CAP_OFFSET 2 -+#define RTL8367C_PORT8_STATUS_FULL_DUPLUX_CAP_MASK 0x4 -+#define RTL8367C_PORT8_STATUS_LINK_SPEED_OFFSET 0 -+#define RTL8367C_PORT8_STATUS_LINK_SPEED_MASK 0x3 -+ -+#define RTL8367C_REG_PORT9_STATUS 0x135b -+#define RTL8367C_PORT9_STATUS_EN_1000_LPI_OFFSET 11 -+#define RTL8367C_PORT9_STATUS_EN_1000_LPI_MASK 0x800 -+#define RTL8367C_PORT9_STATUS_EN_100_LPI_OFFSET 10 -+#define RTL8367C_PORT9_STATUS_EN_100_LPI_MASK 0x400 -+#define RTL8367C_PORT9_STATUS_NWAY_FAULT_OFFSET 9 -+#define RTL8367C_PORT9_STATUS_NWAY_FAULT_MASK 0x200 -+#define RTL8367C_PORT9_STATUS_LINK_ON_MASTER_OFFSET 8 -+#define RTL8367C_PORT9_STATUS_LINK_ON_MASTER_MASK 0x100 -+#define RTL8367C_PORT9_STATUS_NWAY_CAP_OFFSET 7 -+#define RTL8367C_PORT9_STATUS_NWAY_CAP_MASK 0x80 -+#define RTL8367C_PORT9_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 -+#define RTL8367C_PORT9_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 -+#define RTL8367C_PORT9_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 -+#define RTL8367C_PORT9_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 -+#define RTL8367C_PORT9_STATUS_LINK_STATE_OFFSET 4 -+#define RTL8367C_PORT9_STATUS_LINK_STATE_MASK 0x10 -+#define RTL8367C_PORT9_STATUS_FULL_DUPLUX_CAP_OFFSET 2 -+#define RTL8367C_PORT9_STATUS_FULL_DUPLUX_CAP_MASK 0x4 -+#define RTL8367C_PORT9_STATUS_LINK_SPEED_OFFSET 0 -+#define RTL8367C_PORT9_STATUS_LINK_SPEED_MASK 0x3 -+ -+#define RTL8367C_REG_PORT10_STATUS 0x135c -+#define RTL8367C_PORT10_STATUS_EN_1000_LPI_OFFSET 11 -+#define RTL8367C_PORT10_STATUS_EN_1000_LPI_MASK 0x800 -+#define RTL8367C_PORT10_STATUS_EN_100_LPI_OFFSET 10 -+#define RTL8367C_PORT10_STATUS_EN_100_LPI_MASK 0x400 -+#define RTL8367C_PORT10_STATUS_NWAY_FAULT_OFFSET 9 -+#define RTL8367C_PORT10_STATUS_NWAY_FAULT_MASK 0x200 -+#define RTL8367C_PORT10_STATUS_LINK_ON_MASTER_OFFSET 8 -+#define RTL8367C_PORT10_STATUS_LINK_ON_MASTER_MASK 0x100 -+#define RTL8367C_PORT10_STATUS_NWAY_CAP_OFFSET 7 -+#define RTL8367C_PORT10_STATUS_NWAY_CAP_MASK 0x80 -+#define RTL8367C_PORT10_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 -+#define RTL8367C_PORT10_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 -+#define RTL8367C_PORT10_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 -+#define RTL8367C_PORT10_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 -+#define RTL8367C_PORT10_STATUS_LINK_STATE_OFFSET 4 -+#define RTL8367C_PORT10_STATUS_LINK_STATE_MASK 0x10 -+#define RTL8367C_PORT10_STATUS_FULL_DUPLUX_CAP_OFFSET 2 -+#define RTL8367C_PORT10_STATUS_FULL_DUPLUX_CAP_MASK 0x4 -+#define RTL8367C_PORT10_STATUS_LINK_SPEED_OFFSET 0 -+#define RTL8367C_PORT10_STATUS_LINK_SPEED_MASK 0x3 -+ -+#define RTL8367C_REG_UPS_CTRL0 0x1362 -+#define RTL8367C_P3_REF_SD_BIT0_OFFSET 8 -+#define RTL8367C_P3_REF_SD_BIT0_MASK 0xFF00 -+#define RTL8367C_P2_REF_SD_OFFSET 0 -+#define RTL8367C_P2_REF_SD_MASK 0xFF -+ -+#define RTL8367C_REG_UPS_CTRL1 0x1363 -+#define RTL8367C_UPS_OUT_OFFSET 8 -+#define RTL8367C_UPS_OUT_MASK 0xFF00 -+#define RTL8367C_UPS_WRITE_PULSE_OFFSET 1 -+#define RTL8367C_UPS_WRITE_PULSE_MASK 0x2 -+#define RTL8367C_UPS_EN_OFFSET 0 -+#define RTL8367C_UPS_EN_MASK 0x1 -+ -+#define RTL8367C_REG_UPS_CTRL2 0x1364 -+#define RTL8367C_IGNOE_MAC8_LINK_OFFSET 15 -+#define RTL8367C_IGNOE_MAC8_LINK_MASK 0x8000 -+#define RTL8367C_AGREE_SLEEP_OFFSET 14 -+#define RTL8367C_AGREE_SLEEP_MASK 0x4000 -+#define RTL8367C_WAIT_FOR_AGREEMENT_OFFSET 13 -+#define RTL8367C_WAIT_FOR_AGREEMENT_MASK 0x2000 -+#define RTL8367C_WAKE_UP_BY_LINK_OFFSET 12 -+#define RTL8367C_WAKE_UP_BY_LINK_MASK 0x1000 -+#define RTL8367C_WAKE_UP_BY_PHY_OFFSET 11 -+#define RTL8367C_WAKE_UP_BY_PHY_MASK 0x800 -+#define RTL8367C_SLOW_CLK_TGL_RATE_OFFSET 7 -+#define RTL8367C_SLOW_CLK_TGL_RATE_MASK 0x780 -+#define RTL8367C_PLL_G1_CTRL_EN_OFFSET 6 -+#define RTL8367C_PLL_G1_CTRL_EN_MASK 0x40 -+#define RTL8367C_PLL_G0_CTRL_EN_OFFSET 5 -+#define RTL8367C_PLL_G0_CTRL_EN_MASK 0x20 -+#define RTL8367C_SLOW_DOWN_PLL_EN_OFFSET 4 -+#define RTL8367C_SLOW_DOWN_PLL_EN_MASK 0x10 -+#define RTL8367C_SLOW_DOWN_CLK_EN_OFFSET 3 -+#define RTL8367C_SLOW_DOWN_CLK_EN_MASK 0x8 -+#define RTL8367C_GATING_CLK_SDS_EN_OFFSET 2 -+#define RTL8367C_GATING_CLK_SDS_EN_MASK 0x4 -+#define RTL8367C_GATING_CLK_CHIP_EN_OFFSET 1 -+#define RTL8367C_GATING_CLK_CHIP_EN_MASK 0x2 -+#define RTL8367C_GATING_SW_EN_OFFSET 0 -+#define RTL8367C_GATING_SW_EN_MASK 0x1 -+ -+#define RTL8367C_REG_GATING_CLK_1 0x1365 -+#define RTL8367C_ALDPS_MODE_4_OFFSET 15 -+#define RTL8367C_ALDPS_MODE_4_MASK 0x8000 -+#define RTL8367C_ALDPS_MODE_3_OFFSET 14 -+#define RTL8367C_ALDPS_MODE_3_MASK 0x4000 -+#define RTL8367C_ALDPS_MODE_2_OFFSET 13 -+#define RTL8367C_ALDPS_MODE_2_MASK 0x2000 -+#define RTL8367C_ALDPS_MODE_1_OFFSET 12 -+#define RTL8367C_ALDPS_MODE_1_MASK 0x1000 -+#define RTL8367C_ALDPS_MODE_0_OFFSET 11 -+#define RTL8367C_ALDPS_MODE_0_MASK 0x800 -+#define RTL8367C_UPS_DBGO_OFFSET 10 -+#define RTL8367C_UPS_DBGO_MASK 0x400 -+#define RTL8367C_IFMX_AFF_NOT_FF_OUT_OFFSET 9 -+#define RTL8367C_IFMX_AFF_NOT_FF_OUT_MASK 0x200 -+#define RTL8367C_WATER_LEVEL_FD_OFFSET 6 -+#define RTL8367C_WATER_LEVEL_FD_MASK 0x1C0 -+#define RTL8367C_WATER_LEVEL_Y2X_OFFSET 3 -+#define RTL8367C_WATER_LEVEL_Y2X_MASK 0x38 -+#define RTL8367C_WATER_LEVEL_X2Y_2_OFFSET 2 -+#define RTL8367C_WATER_LEVEL_X2Y_2_MASK 0x4 -+#define RTL8367C_IGNOE_MAC10_LINK_OFFSET 1 -+#define RTL8367C_IGNOE_MAC10_LINK_MASK 0x2 -+#define RTL8367C_IGNOE_MAC9_LINK_OFFSET 0 -+#define RTL8367C_IGNOE_MAC9_LINK_MASK 0x1 -+ -+#define RTL8367C_REG_UPS_CTRL4 0x1366 -+#define RTL8367C_PROB_EN_OFFSET 6 -+#define RTL8367C_PROB_EN_MASK 0x40 -+#define RTL8367C_PLL_DOWN_OFFSET 1 -+#define RTL8367C_PLL_DOWN_MASK 0x2 -+#define RTL8367C_XTAL_DOWN_OFFSET 0 -+#define RTL8367C_XTAL_DOWN_MASK 0x1 -+ -+#define RTL8367C_REG_UPS_CTRL5 0x1367 -+#define RTL8367C_FRC_CPU_ACPT_OFFSET 3 -+#define RTL8367C_FRC_CPU_ACPT_MASK 0x8 -+#define RTL8367C_UPS_CPU_ACPT_OFFSET 2 -+#define RTL8367C_UPS_CPU_ACPT_MASK 0x4 -+#define RTL8367C_UPS_DBG_4_OFFSET 0 -+#define RTL8367C_UPS_DBG_4_MASK 0x3 -+ -+#define RTL8367C_REG_UPS_CTRL6 0x1368 -+#define RTL8367C_UPS_CTRL6_OFFSET 0 -+#define RTL8367C_UPS_CTRL6_MASK 0xF -+ -+#define RTL8367C_REG_EFUSE_CMD_70B 0x1369 -+ -+#define RTL8367C_REG_EFUSE_CMD 0x1370 -+#define RTL8367C_EFUSE_TIME_OUT_FLAG_OFFSET 3 -+#define RTL8367C_EFUSE_TIME_OUT_FLAG_MASK 0x8 -+#define RTL8367C_EFUSE_ACCESS_BUSY_OFFSET 2 -+#define RTL8367C_EFUSE_ACCESS_BUSY_MASK 0x4 -+#define RTL8367C_EFUSE_COMMAND_EN_OFFSET 1 -+#define RTL8367C_EFUSE_COMMAND_EN_MASK 0x2 -+#define RTL8367C_EFUSE_WR_OFFSET 0 -+#define RTL8367C_EFUSE_WR_MASK 0x1 -+ -+#define RTL8367C_REG_EFUSE_ADR 0x1371 -+#define RTL8367C_DUMMY_15_10_OFFSET 8 -+#define RTL8367C_DUMMY_15_10_MASK 0xFF00 -+#define RTL8367C_EFUSE_ADDRESS_OFFSET 0 -+#define RTL8367C_EFUSE_ADDRESS_MASK 0xFF -+ -+#define RTL8367C_REG_EFUSE_WDAT 0x1372 -+ -+#define RTL8367C_REG_EFUSE_RDAT 0x1373 -+ -+#define RTL8367C_REG_I2C_CTRL 0x1374 -+#define RTL8367C_MDX_MST_FAIL_LAT_OFFSET 1 -+#define RTL8367C_MDX_MST_FAIL_LAT_MASK 0x2 -+#define RTL8367C_MDX_MST_FAIL_CLRPS_OFFSET 0 -+#define RTL8367C_MDX_MST_FAIL_CLRPS_MASK 0x1 -+ -+#define RTL8367C_REG_EEE_CFG 0x1375 -+#define RTL8367C_CFG_BYPASS_GATELPTD_OFFSET 11 -+#define RTL8367C_CFG_BYPASS_GATELPTD_MASK 0x800 -+#define RTL8367C_EEE_ABT_ADDR2_OFFSET 6 -+#define RTL8367C_EEE_ABT_ADDR2_MASK 0x7C0 -+#define RTL8367C_EEE_ABT_ADDR1_OFFSET 1 -+#define RTL8367C_EEE_ABT_ADDR1_MASK 0x3E -+#define RTL8367C_EEE_POLL_EN_OFFSET 0 -+#define RTL8367C_EEE_POLL_EN_MASK 0x1 -+ -+#define RTL8367C_REG_EEE_PAGE 0x1376 -+ -+#define RTL8367C_REG_EEE_EXT_PAGE 0x1377 -+ -+#define RTL8367C_REG_EEE_EN_SPD1000 0x1378 -+ -+#define RTL8367C_REG_EEE_EN_SPD100 0x1379 -+ -+#define RTL8367C_REG_EEE_LP_SPD1000 0x137a -+ -+#define RTL8367C_REG_EEE_LP_SPD100 0x137b -+ -+#define RTL8367C_REG_DW8051_PRO_REG0 0x13a0 -+ -+#define RTL8367C_REG_DW8051_PRO_REG1 0x13a1 -+ -+#define RTL8367C_REG_DW8051_PRO_REG2 0x13a2 -+ -+#define RTL8367C_REG_DW8051_PRO_REG3 0x13a3 -+ -+#define RTL8367C_REG_DW8051_PRO_REG4 0x13a4 -+ -+#define RTL8367C_REG_DW8051_PRO_REG5 0x13a5 -+ -+#define RTL8367C_REG_DW8051_PRO_REG6 0x13a6 -+ -+#define RTL8367C_REG_DW8051_PRO_REG7 0x13a7 -+ -+#define RTL8367C_REG_PROTECT_ID 0x13c0 -+ -+#define RTL8367C_REG_CHIP_VER_INTL 0x13c1 -+#define RTL8367C_CHIP_VER_INTL_OFFSET 0 -+#define RTL8367C_CHIP_VER_INTL_MASK 0xF -+ -+#define RTL8367C_REG_MAGIC_ID 0x13c2 -+ -+#define RTL8367C_REG_DIGITAL_INTERFACE_SELECT_1 0x13c3 -+#define RTL8367C_SKIP_MII_2_RXER_OFFSET 4 -+#define RTL8367C_SKIP_MII_2_RXER_MASK 0x10 -+#define RTL8367C_SELECT_GMII_2_OFFSET 0 -+#define RTL8367C_SELECT_GMII_2_MASK 0xF -+ -+#define RTL8367C_REG_DIGITAL_INTERFACE2_FORCE 0x13c4 -+#define RTL8367C_GMII_2_FORCE_OFFSET 12 -+#define RTL8367C_GMII_2_FORCE_MASK 0x1000 -+#define RTL8367C_RGMII_2_FORCE_OFFSET 0 -+#define RTL8367C_RGMII_2_FORCE_MASK 0xFFF -+ -+#define RTL8367C_REG_EXT2_RGMXF 0x13c5 -+#define RTL8367C_EXT2_RGTX_INV_OFFSET 6 -+#define RTL8367C_EXT2_RGTX_INV_MASK 0x40 -+#define RTL8367C_EXT2_RGRX_INV_OFFSET 5 -+#define RTL8367C_EXT2_RGRX_INV_MASK 0x20 -+#define RTL8367C_EXT2_RGMXF_OFFSET 0 -+#define RTL8367C_EXT2_RGMXF_MASK 0x1F -+ -+#define RTL8367C_REG_ROUTER_UPS_CFG 0x13c6 -+#define RTL8367C_UPS_Status_OFFSET 1 -+#define RTL8367C_UPS_Status_MASK 0x2 -+#define RTL8367C_SoftStart_OFFSET 0 -+#define RTL8367C_SoftStart_MASK 0x1 -+ -+#define RTL8367C_REG_CTRL_GPIO 0x13c7 -+#define RTL8367C_CTRL_GPIO_13_OFFSET 13 -+#define RTL8367C_CTRL_GPIO_13_MASK 0x2000 -+#define RTL8367C_CTRL_GPIO_12_OFFSET 12 -+#define RTL8367C_CTRL_GPIO_12_MASK 0x1000 -+#define RTL8367C_CTRL_GPIO_11_OFFSET 11 -+#define RTL8367C_CTRL_GPIO_11_MASK 0x800 -+#define RTL8367C_CTRL_GPIO_10_OFFSET 10 -+#define RTL8367C_CTRL_GPIO_10_MASK 0x400 -+#define RTL8367C_CTRL_GPIO_9_OFFSET 9 -+#define RTL8367C_CTRL_GPIO_9_MASK 0x200 -+#define RTL8367C_CTRL_GPIO_8_OFFSET 8 -+#define RTL8367C_CTRL_GPIO_8_MASK 0x100 -+#define RTL8367C_CTRL_GPIO_7_OFFSET 7 -+#define RTL8367C_CTRL_GPIO_7_MASK 0x80 -+#define RTL8367C_CTRL_GPIO_6_OFFSET 6 -+#define RTL8367C_CTRL_GPIO_6_MASK 0x40 -+#define RTL8367C_CTRL_GPIO_5_OFFSET 5 -+#define RTL8367C_CTRL_GPIO_5_MASK 0x20 -+#define RTL8367C_CTRL_GPIO_4_OFFSET 4 -+#define RTL8367C_CTRL_GPIO_4_MASK 0x10 -+#define RTL8367C_CTRL_GPIO_3_OFFSET 3 -+#define RTL8367C_CTRL_GPIO_3_MASK 0x8 -+#define RTL8367C_CTRL_GPIO_2_OFFSET 2 -+#define RTL8367C_CTRL_GPIO_2_MASK 0x4 -+#define RTL8367C_CTRL_GPIO_1_OFFSET 1 -+#define RTL8367C_CTRL_GPIO_1_MASK 0x2 -+#define RTL8367C_CTRL_GPIO_0_OFFSET 0 -+#define RTL8367C_CTRL_GPIO_0_MASK 0x1 -+ -+#define RTL8367C_REG_SEL_GPIO 0x13c8 -+#define RTL8367C_SEL_GPIO_13_OFFSET 13 -+#define RTL8367C_SEL_GPIO_13_MASK 0x2000 -+#define RTL8367C_SEL_GPIO_12_OFFSET 12 -+#define RTL8367C_SEL_GPIO_12_MASK 0x1000 -+#define RTL8367C_SEL_GPIO_11_OFFSET 11 -+#define RTL8367C_SEL_GPIO_11_MASK 0x800 -+#define RTL8367C_SEL_GPIO_10_OFFSET 10 -+#define RTL8367C_SEL_GPIO_10_MASK 0x400 -+#define RTL8367C_SEL_GPIO_9_OFFSET 9 -+#define RTL8367C_SEL_GPIO_9_MASK 0x200 -+#define RTL8367C_SEL_GPIO_8_OFFSET 8 -+#define RTL8367C_SEL_GPIO_8_MASK 0x100 -+#define RTL8367C_SEL_GPIO_7_OFFSET 7 -+#define RTL8367C_SEL_GPIO_7_MASK 0x80 -+#define RTL8367C_SEL_GPIO_6_OFFSET 6 -+#define RTL8367C_SEL_GPIO_6_MASK 0x40 -+#define RTL8367C_SEL_GPIO_5_OFFSET 5 -+#define RTL8367C_SEL_GPIO_5_MASK 0x20 -+#define RTL8367C_SEL_GPIO_4_OFFSET 4 -+#define RTL8367C_SEL_GPIO_4_MASK 0x10 -+#define RTL8367C_SEL_GPIO_3_OFFSET 3 -+#define RTL8367C_SEL_GPIO_3_MASK 0x8 -+#define RTL8367C_SEL_GPIO_2_OFFSET 2 -+#define RTL8367C_SEL_GPIO_2_MASK 0x4 -+#define RTL8367C_SEL_GPIO_1_OFFSET 1 -+#define RTL8367C_SEL_GPIO_1_MASK 0x2 -+#define RTL8367C_SEL_GPIO_0_OFFSET 0 -+#define RTL8367C_SEL_GPIO_0_MASK 0x1 -+ -+#define RTL8367C_REG_STATUS_GPIO 0x13c9 -+#define RTL8367C_STATUS_GPIO_OFFSET 0 -+#define RTL8367C_STATUS_GPIO_MASK 0x3FFF -+ -+#define RTL8367C_REG_SYNC_ETH_CFG 0x13e0 -+#define RTL8367C_DUMMY2_OFFSET 9 -+#define RTL8367C_DUMMY2_MASK 0xFE00 -+#define RTL8367C_RFC2819_TYPE_OFFSET 8 -+#define RTL8367C_RFC2819_TYPE_MASK 0x100 -+#define RTL8367C_DUMMY1_OFFSET 7 -+#define RTL8367C_DUMMY1_MASK 0x80 -+#define RTL8367C_FIBER_SYNCE125_L_SEL_OFFSET 6 -+#define RTL8367C_FIBER_SYNCE125_L_SEL_MASK 0x40 -+#define RTL8367C_SYNC_ETH_EN_RTT2_OFFSET 5 -+#define RTL8367C_SYNC_ETH_EN_RTT2_MASK 0x20 -+#define RTL8367C_SYNC_ETH_EN_RTT1_OFFSET 4 -+#define RTL8367C_SYNC_ETH_EN_RTT1_MASK 0x10 -+#define RTL8367C_SYNC_ETH_SEL_DPLL_OFFSET 3 -+#define RTL8367C_SYNC_ETH_SEL_DPLL_MASK 0x8 -+#define RTL8367C_SYNC_ETH_SEL_PHYREF_OFFSET 2 -+#define RTL8367C_SYNC_ETH_SEL_PHYREF_MASK 0x4 -+#define RTL8367C_SYNC_ETH_SEL_XTAL_OFFSET 1 -+#define RTL8367C_SYNC_ETH_SEL_XTAL_MASK 0x2 -+#define RTL8367C_DUMMY0_OFFSET 0 -+#define RTL8367C_DUMMY0_MASK 0x1 -+ -+#define RTL8367C_REG_LED_DRI_CFG 0x13e1 -+#define RTL8367C_LED_DRI_CFG_DUMMY_OFFSET 1 -+#define RTL8367C_LED_DRI_CFG_DUMMY_MASK 0xFFFE -+#define RTL8367C_LED_DRIVING_OFFSET 0 -+#define RTL8367C_LED_DRIVING_MASK 0x1 -+ -+#define RTL8367C_REG_CHIP_DEBUG2 0x13e2 -+#define RTL8367C_RG2_DN_OFFSET 6 -+#define RTL8367C_RG2_DN_MASK 0x1C0 -+#define RTL8367C_RG2_DP_OFFSET 3 -+#define RTL8367C_RG2_DP_MASK 0x38 -+#define RTL8367C_DRI_EXT2_RG_OFFSET 2 -+#define RTL8367C_DRI_EXT2_RG_MASK 0x4 -+#define RTL8367C_DRI_EXT2_OFFSET 1 -+#define RTL8367C_DRI_EXT2_MASK 0x2 -+#define RTL8367C_SLR_EXT2_OFFSET 0 -+#define RTL8367C_SLR_EXT2_MASK 0x1 -+ -+#define RTL8367C_REG_DIGITAL_DEBUG_2 0x13e3 -+ -+#define RTL8367C_REG_FIBER_RTL_OUI_CFG0 0x13e4 -+#define RTL8367C_FIBER_RTL_OUI_CFG0_OFFSET 0 -+#define RTL8367C_FIBER_RTL_OUI_CFG0_MASK 0xFF -+ -+#define RTL8367C_REG_FIBER_RTL_OUI_CFG1 0x13e5 -+ -+#define RTL8367C_REG_FIBER_CFG_0 0x13e6 -+#define RTL8367C_REV_NUM_OFFSET 8 -+#define RTL8367C_REV_NUM_MASK 0xF00 -+#define RTL8367C_MODEL_NUM_OFFSET 0 -+#define RTL8367C_MODEL_NUM_MASK 0x3F -+ -+#define RTL8367C_REG_FIBER_CFG_1 0x13e7 -+#define RTL8367C_SDS_FRC_REG4_OFFSET 12 -+#define RTL8367C_SDS_FRC_REG4_MASK 0x1000 -+#define RTL8367C_SDS_FRC_REG4_FIB100_OFFSET 11 -+#define RTL8367C_SDS_FRC_REG4_FIB100_MASK 0x800 -+#define RTL8367C_SEL_MASK_ONL_OFFSET 5 -+#define RTL8367C_SEL_MASK_ONL_MASK 0x20 -+#define RTL8367C_DIS_QUALITY_IN_MASK_OFFSET 4 -+#define RTL8367C_DIS_QUALITY_IN_MASK_MASK 0x10 -+#define RTL8367C_SDS_FRC_MODE_OFFSET 3 -+#define RTL8367C_SDS_FRC_MODE_MASK 0x8 -+#define RTL8367C_SDS_MODE_OFFSET 0 -+#define RTL8367C_SDS_MODE_MASK 0x7 -+ -+#define RTL8367C_REG_FIBER_CFG_2 0x13e8 -+#define RTL8367C_SEL_SDET_PS_OFFSET 12 -+#define RTL8367C_SEL_SDET_PS_MASK 0xF000 -+#define RTL8367C_UTP_DIS_RX_OFFSET 10 -+#define RTL8367C_UTP_DIS_RX_MASK 0xC00 -+#define RTL8367C_UTP_FRC_LD_OFFSET 8 -+#define RTL8367C_UTP_FRC_LD_MASK 0x300 -+#define RTL8367C_SDS_RX_DISABLE_OFFSET 6 -+#define RTL8367C_SDS_RX_DISABLE_MASK 0xC0 -+#define RTL8367C_SDS_TX_DISABLE_OFFSET 4 -+#define RTL8367C_SDS_TX_DISABLE_MASK 0x30 -+#define RTL8367C_FIBER_CFG_2_SDS_PWR_ISO_OFFSET 2 -+#define RTL8367C_FIBER_CFG_2_SDS_PWR_ISO_MASK 0xC -+#define RTL8367C_SDS_FRC_LD_OFFSET 0 -+#define RTL8367C_SDS_FRC_LD_MASK 0x3 -+ -+#define RTL8367C_REG_FIBER_CFG_3 0x13e9 -+#define RTL8367C_FIBER_CFG_3_OFFSET 0 -+#define RTL8367C_FIBER_CFG_3_MASK 0xFFF -+ -+#define RTL8367C_REG_FIBER_CFG_4 0x13ea -+ -+#define RTL8367C_REG_UTP_FIB_DET 0x13eb -+#define RTL8367C_FORCE_SEL_FIBER_OFFSET 14 -+#define RTL8367C_FORCE_SEL_FIBER_MASK 0xC000 -+#define RTL8367C_FIB_FINAL_TIMER_OFFSET 12 -+#define RTL8367C_FIB_FINAL_TIMER_MASK 0x3000 -+#define RTL8367C_FIB_LINK_TIMER_OFFSET 10 -+#define RTL8367C_FIB_LINK_TIMER_MASK 0xC00 -+#define RTL8367C_FIB_SDET_TIMER_OFFSET 8 -+#define RTL8367C_FIB_SDET_TIMER_MASK 0x300 -+#define RTL8367C_UTP_LINK_TIMER_OFFSET 6 -+#define RTL8367C_UTP_LINK_TIMER_MASK 0xC0 -+#define RTL8367C_UTP_SDET_TIMER_OFFSET 4 -+#define RTL8367C_UTP_SDET_TIMER_MASK 0x30 -+#define RTL8367C_FORCE_AUTODET_OFFSET 3 -+#define RTL8367C_FORCE_AUTODET_MASK 0x8 -+#define RTL8367C_AUTODET_FSM_CLR_OFFSET 2 -+#define RTL8367C_AUTODET_FSM_CLR_MASK 0x4 -+#define RTL8367C_UTP_FIRST_OFFSET 1 -+#define RTL8367C_UTP_FIRST_MASK 0x2 -+#define RTL8367C_UTP_FIB_DISAUTODET_OFFSET 0 -+#define RTL8367C_UTP_FIB_DISAUTODET_MASK 0x1 -+ -+#define RTL8367C_REG_NRESTORE_MAGIC_NUM 0x13ec -+#define RTL8367C_NRESTORE_MAGIC_NUM_MASK 0xFFFF -+#define RTL8367C_EEPROM_PROGRAM_CYCLE_OFFSET 0 -+#define RTL8367C_EEPROM_PROGRAM_CYCLE_MASK 0x3 -+ -+#define RTL8367C_REG_MAC_ACTIVE 0x13ee -+#define RTL8367C_MAC_ACTIVE_H_OFFSET 9 -+#define RTL8367C_MAC_ACTIVE_H_MASK 0xE00 -+#define RTL8367C_FORCE_MAC_ACTIVE_OFFSET 8 -+#define RTL8367C_FORCE_MAC_ACTIVE_MASK 0x100 -+#define RTL8367C_MAC_ACTIVE_OFFSET 0 -+#define RTL8367C_MAC_ACTIVE_MASK 0xFF -+ -+#define RTL8367C_REG_SERDES_RESULT 0x13ef -+#define RTL8367C_FIB100_DET_1_OFFSET 12 -+#define RTL8367C_FIB100_DET_1_MASK 0x1000 -+#define RTL8367C_FIB_ISO_1_OFFSET 11 -+#define RTL8367C_FIB_ISO_1_MASK 0x800 -+#define RTL8367C_SDS_ANFAULT_1_OFFSET 10 -+#define RTL8367C_SDS_ANFAULT_1_MASK 0x400 -+#define RTL8367C_SDS_INTB_1_OFFSET 9 -+#define RTL8367C_SDS_INTB_1_MASK 0x200 -+#define RTL8367C_SDS_LINK_OK_1_OFFSET 8 -+#define RTL8367C_SDS_LINK_OK_1_MASK 0x100 -+#define RTL8367C_FIB100_DET_OFFSET 4 -+#define RTL8367C_FIB100_DET_MASK 0x10 -+#define RTL8367C_FIB_ISO_OFFSET 3 -+#define RTL8367C_FIB_ISO_MASK 0x8 -+#define RTL8367C_SDS_ANFAULT_OFFSET 2 -+#define RTL8367C_SDS_ANFAULT_MASK 0x4 -+#define RTL8367C_SDS_INTB_OFFSET 1 -+#define RTL8367C_SDS_INTB_MASK 0x2 -+#define RTL8367C_SDS_LINK_OK_OFFSET 0 -+#define RTL8367C_SDS_LINK_OK_MASK 0x1 -+ -+#define RTL8367C_REG_CHIP_ECO 0x13f0 -+#define RTL8367C_CFG_CHIP_ECO_OFFSET 1 -+#define RTL8367C_CFG_CHIP_ECO_MASK 0xFFFE -+#define RTL8367C_CFG_CKOUTEN_OFFSET 0 -+#define RTL8367C_CFG_CKOUTEN_MASK 0x1 -+ -+#define RTL8367C_REG_WAKELPI_SLOT_PRD 0x13f1 -+#define RTL8367C_WAKELPI_SLOT_PRD_OFFSET 0 -+#define RTL8367C_WAKELPI_SLOT_PRD_MASK 0x1F -+ -+#define RTL8367C_REG_WAKELPI_SLOT_PG0 0x13f2 -+#define RTL8367C_WAKELPI_SLOT_P1_OFFSET 8 -+#define RTL8367C_WAKELPI_SLOT_P1_MASK 0x1F00 -+#define RTL8367C_WAKELPI_SLOT_P0_OFFSET 0 -+#define RTL8367C_WAKELPI_SLOT_P0_MASK 0x1F -+ -+#define RTL8367C_REG_WAKELPI_SLOT_PG1 0x13f3 -+#define RTL8367C_WAKELPI_SLOT_P3_OFFSET 8 -+#define RTL8367C_WAKELPI_SLOT_P3_MASK 0x1F00 -+#define RTL8367C_WAKELPI_SLOT_P2_OFFSET 0 -+#define RTL8367C_WAKELPI_SLOT_P2_MASK 0x1F -+ -+#define RTL8367C_REG_WAKELPI_SLOT_PG2 0x13f4 -+#define RTL8367C_WAKELPI_SLOT_P5_OFFSET 8 -+#define RTL8367C_WAKELPI_SLOT_P5_MASK 0x1F00 -+#define RTL8367C_WAKELPI_SLOT_P4_OFFSET 0 -+#define RTL8367C_WAKELPI_SLOT_P4_MASK 0x1F -+ -+#define RTL8367C_REG_WAKELPI_SLOT_PG3 0x13f5 -+#define RTL8367C_WAKELPI_SLOT_P7_OFFSET 8 -+#define RTL8367C_WAKELPI_SLOT_P7_MASK 0x1F00 -+#define RTL8367C_WAKELPI_SLOT_P6_OFFSET 0 -+#define RTL8367C_WAKELPI_SLOT_P6_MASK 0x1F -+ -+#define RTL8367C_REG_SYNC_FIFO_0 0x13f6 -+#define RTL8367C_SYNC_FIFO_TX_OFFSET 8 -+#define RTL8367C_SYNC_FIFO_TX_MASK 0x700 -+#define RTL8367C_SYNC_FIFO_RX_OFFSET 0 -+#define RTL8367C_SYNC_FIFO_RX_MASK 0xFF -+ -+#define RTL8367C_REG_SYNC_FIFO_1 0x13f7 -+#define RTL8367C_SYNC_FIFO_RX_ERR_P10_8_OFFSET 11 -+#define RTL8367C_SYNC_FIFO_RX_ERR_P10_8_MASK 0x3800 -+#define RTL8367C_SYNC_FIFO_TX_ERR_OFFSET 8 -+#define RTL8367C_SYNC_FIFO_TX_ERR_MASK 0x700 -+#define RTL8367C_SYNC_FIFO_RX_ERR_OFFSET 0 -+#define RTL8367C_SYNC_FIFO_RX_ERR_MASK 0xFF -+ -+#define RTL8367C_REG_RGM_EEE 0x13f8 -+#define RTL8367C_EXT2_PAD_STOP_EN_OFFSET 14 -+#define RTL8367C_EXT2_PAD_STOP_EN_MASK 0x4000 -+#define RTL8367C_EXT1_PAD_STOP_EN_OFFSET 13 -+#define RTL8367C_EXT1_PAD_STOP_EN_MASK 0x2000 -+#define RTL8367C_EXT0_PAD_STOP_EN_OFFSET 12 -+#define RTL8367C_EXT0_PAD_STOP_EN_MASK 0x1000 -+#define RTL8367C_EXT2_CYCLE_PAD_OFFSET 8 -+#define RTL8367C_EXT2_CYCLE_PAD_MASK 0xF00 -+#define RTL8367C_EXT1_CYCLE_PAD_OFFSET 4 -+#define RTL8367C_EXT1_CYCLE_PAD_MASK 0xF0 -+#define RTL8367C_EXT0_CYCLE_PAD_OFFSET 0 -+#define RTL8367C_EXT0_CYCLE_PAD_MASK 0xF -+ -+#define RTL8367C_REG_EXT_TXC_DLY 0x13f9 -+#define RTL8367C_EXT1_GMII_TX_DELAY_OFFSET 12 -+#define RTL8367C_EXT1_GMII_TX_DELAY_MASK 0x7000 -+#define RTL8367C_EXT0_GMII_TX_DELAY_OFFSET 9 -+#define RTL8367C_EXT0_GMII_TX_DELAY_MASK 0xE00 -+#define RTL8367C_EXT2_RGMII_TX_DELAY_OFFSET 6 -+#define RTL8367C_EXT2_RGMII_TX_DELAY_MASK 0x1C0 -+#define RTL8367C_EXT1_RGMII_TX_DELAY_OFFSET 3 -+#define RTL8367C_EXT1_RGMII_TX_DELAY_MASK 0x38 -+#define RTL8367C_EXT0_RGMII_TX_DELAY_OFFSET 0 -+#define RTL8367C_EXT0_RGMII_TX_DELAY_MASK 0x7 -+ -+#define RTL8367C_REG_IO_MISC_CTRL 0x13fa -+#define RTL8367C_IO_BUZZER_EN_OFFSET 3 -+#define RTL8367C_IO_BUZZER_EN_MASK 0x8 -+#define RTL8367C_IO_INTRPT_EN_OFFSET 2 -+#define RTL8367C_IO_INTRPT_EN_MASK 0x4 -+#define RTL8367C_IO_NRESTORE_EN_OFFSET 1 -+#define RTL8367C_IO_NRESTORE_EN_MASK 0x2 -+#define RTL8367C_IO_UART_EN_OFFSET 0 -+#define RTL8367C_IO_UART_EN_MASK 0x1 -+ -+#define RTL8367C_REG_CHIP_DUMMY_NO 0x13fb -+#define RTL8367C_CHIP_DUMMY_NO_OFFSET 0 -+#define RTL8367C_CHIP_DUMMY_NO_MASK 0xF -+ -+#define RTL8367C_REG_RC_CALIB_CFG 0x13fc -+#define RTL8367C_TRIG_BURN_EFUSE_OFFSET 9 -+#define RTL8367C_TRIG_BURN_EFUSE_MASK 0x200 -+#define RTL8367C_AMP_CALIB_FAIL_OFFSET 8 -+#define RTL8367C_AMP_CALIB_FAIL_MASK 0x100 -+#define RTL8367C_R_CALIB_FAIL_OFFSET 7 -+#define RTL8367C_R_CALIB_FAIL_MASK 0x80 -+#define RTL8367C_CFG_CALIB_MODE_OFFSET 6 -+#define RTL8367C_CFG_CALIB_MODE_MASK 0x40 -+#define RTL8367C_CENTER_PORT_SEL_OFFSET 3 -+#define RTL8367C_CENTER_PORT_SEL_MASK 0x38 -+#define RTL8367C_CALIB_FINISH_OFFSET 2 -+#define RTL8367C_CALIB_FINISH_MASK 0x4 -+#define RTL8367C_CFG_CALIB_OPTION_OFFSET 1 -+#define RTL8367C_CFG_CALIB_OPTION_MASK 0x2 -+#define RTL8367C_CFG_CALIB_EN_OFFSET 0 -+#define RTL8367C_CFG_CALIB_EN_MASK 0x1 -+ -+#define RTL8367C_REG_WAKELPI_SLOT_PG4 0x13fd -+#define RTL8367C_WAKELPI_SLOT_P9_OFFSET 8 -+#define RTL8367C_WAKELPI_SLOT_P9_MASK 0x1F00 -+#define RTL8367C_WAKELPI_SLOT_P8_OFFSET 0 -+#define RTL8367C_WAKELPI_SLOT_P8_MASK 0x1F -+ -+#define RTL8367C_REG_WAKELPI_SLOT_PG5 0x13fe -+#define RTL8367C_WAKELPI_SLOT_PG5_OFFSET 0 -+#define RTL8367C_WAKELPI_SLOT_PG5_MASK 0x1F -+ -+/* (16'h1400)mtrpool_reg */ -+ -+#define RTL8367C_REG_METER0_RATE_CTRL0 0x1400 -+ -+#define RTL8367C_REG_METER0_RATE_CTRL1 0x1401 -+#define RTL8367C_METER0_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER0_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER1_RATE_CTRL0 0x1402 -+ -+#define RTL8367C_REG_METER1_RATE_CTRL1 0x1403 -+#define RTL8367C_METER1_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER1_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER2_RATE_CTRL0 0x1404 -+ -+#define RTL8367C_REG_METER2_RATE_CTRL1 0x1405 -+#define RTL8367C_METER2_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER2_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER3_RATE_CTRL0 0x1406 -+ -+#define RTL8367C_REG_METER3_RATE_CTRL1 0x1407 -+#define RTL8367C_METER3_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER3_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER4_RATE_CTRL0 0x1408 -+ -+#define RTL8367C_REG_METER4_RATE_CTRL1 0x1409 -+#define RTL8367C_METER4_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER4_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER5_RATE_CTRL0 0x140a -+ -+#define RTL8367C_REG_METER5_RATE_CTRL1 0x140b -+#define RTL8367C_METER5_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER5_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER6_RATE_CTRL0 0x140c -+ -+#define RTL8367C_REG_METER6_RATE_CTRL1 0x140d -+#define RTL8367C_METER6_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER6_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER7_RATE_CTRL0 0x140e -+ -+#define RTL8367C_REG_METER7_RATE_CTRL1 0x140f -+#define RTL8367C_METER7_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER7_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER8_RATE_CTRL0 0x1410 -+ -+#define RTL8367C_REG_METER8_RATE_CTRL1 0x1411 -+#define RTL8367C_METER8_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER8_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER9_RATE_CTRL0 0x1412 -+ -+#define RTL8367C_REG_METER9_RATE_CTRL1 0x1413 -+#define RTL8367C_METER9_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER9_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER10_RATE_CTRL0 0x1414 -+ -+#define RTL8367C_REG_METER10_RATE_CTRL1 0x1415 -+#define RTL8367C_METER10_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER10_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER11_RATE_CTRL0 0x1416 -+ -+#define RTL8367C_REG_METER11_RATE_CTRL1 0x1417 -+#define RTL8367C_METER11_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER11_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER12_RATE_CTRL0 0x1418 -+ -+#define RTL8367C_REG_METER12_RATE_CTRL1 0x1419 -+#define RTL8367C_METER12_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER12_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER13_RATE_CTRL0 0x141a -+ -+#define RTL8367C_REG_METER13_RATE_CTRL1 0x141b -+#define RTL8367C_METER13_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER13_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER14_RATE_CTRL0 0x141c -+ -+#define RTL8367C_REG_METER14_RATE_CTRL1 0x141d -+#define RTL8367C_METER14_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER14_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER15_RATE_CTRL0 0x141e -+ -+#define RTL8367C_REG_METER15_RATE_CTRL1 0x141f -+#define RTL8367C_METER15_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER15_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER16_RATE_CTRL0 0x1420 -+ -+#define RTL8367C_REG_METER16_RATE_CTRL1 0x1421 -+#define RTL8367C_METER16_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER16_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER17_RATE_CTRL0 0x1422 -+ -+#define RTL8367C_REG_METER17_RATE_CTRL1 0x1423 -+#define RTL8367C_METER17_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER17_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER18_RATE_CTRL0 0x1424 -+ -+#define RTL8367C_REG_METER18_RATE_CTRL1 0x1425 -+#define RTL8367C_METER18_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER18_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER19_RATE_CTRL0 0x1426 -+ -+#define RTL8367C_REG_METER19_RATE_CTRL1 0x1427 -+#define RTL8367C_METER19_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER19_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER20_RATE_CTRL0 0x1428 -+ -+#define RTL8367C_REG_METER20_RATE_CTRL1 0x1429 -+#define RTL8367C_METER20_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER20_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER21_RATE_CTRL0 0x142a -+ -+#define RTL8367C_REG_METER21_RATE_CTRL1 0x142b -+#define RTL8367C_METER21_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER21_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER22_RATE_CTRL0 0x142c -+ -+#define RTL8367C_REG_METER22_RATE_CTRL1 0x142d -+#define RTL8367C_METER22_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER22_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER23_RATE_CTRL0 0x142e -+ -+#define RTL8367C_REG_METER23_RATE_CTRL1 0x142f -+#define RTL8367C_METER23_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER23_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER24_RATE_CTRL0 0x1430 -+ -+#define RTL8367C_REG_METER24_RATE_CTRL1 0x1431 -+#define RTL8367C_METER24_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER24_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER25_RATE_CTRL0 0x1432 -+ -+#define RTL8367C_REG_METER25_RATE_CTRL1 0x1433 -+#define RTL8367C_METER25_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER25_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER26_RATE_CTRL0 0x1434 -+ -+#define RTL8367C_REG_METER26_RATE_CTRL1 0x1435 -+#define RTL8367C_METER26_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER26_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER27_RATE_CTRL0 0x1436 -+ -+#define RTL8367C_REG_METER27_RATE_CTRL1 0x1437 -+#define RTL8367C_METER27_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER27_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER28_RATE_CTRL0 0x1438 -+ -+#define RTL8367C_REG_METER28_RATE_CTRL1 0x1439 -+#define RTL8367C_METER28_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER28_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER29_RATE_CTRL0 0x143a -+ -+#define RTL8367C_REG_METER29_RATE_CTRL1 0x143b -+#define RTL8367C_METER29_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER29_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER30_RATE_CTRL0 0x143c -+ -+#define RTL8367C_REG_METER30_RATE_CTRL1 0x143d -+#define RTL8367C_METER30_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER30_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER31_RATE_CTRL0 0x143e -+ -+#define RTL8367C_REG_METER31_RATE_CTRL1 0x143f -+#define RTL8367C_METER31_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER31_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER_MODE_SETTING0 0x1440 -+ -+#define RTL8367C_REG_METER_MODE_SETTING1 0x1441 -+ -+#define RTL8367C_REG_METER_MODE_TOKEN_CFG 0x1442 -+#define RTL8367C_METER_MODE_TOKEN_CFG_OFFSET 0 -+#define RTL8367C_METER_MODE_TOKEN_CFG_MASK 0x7FF -+ -+#define RTL8367C_REG_METER0_BUCKET_SIZE 0x1600 -+ -+#define RTL8367C_REG_METER1_BUCKET_SIZE 0x1601 -+ -+#define RTL8367C_REG_METER2_BUCKET_SIZE 0x1602 -+ -+#define RTL8367C_REG_METER3_BUCKET_SIZE 0x1603 -+ -+#define RTL8367C_REG_METER4_BUCKET_SIZE 0x1604 -+ -+#define RTL8367C_REG_METER5_BUCKET_SIZE 0x1605 -+ -+#define RTL8367C_REG_METER6_BUCKET_SIZE 0x1606 -+ -+#define RTL8367C_REG_METER7_BUCKET_SIZE 0x1607 -+ -+#define RTL8367C_REG_METER8_BUCKET_SIZE 0x1608 -+ -+#define RTL8367C_REG_METER9_BUCKET_SIZE 0x1609 -+ -+#define RTL8367C_REG_METER10_BUCKET_SIZE 0x160a -+ -+#define RTL8367C_REG_METER11_BUCKET_SIZE 0x160b -+ -+#define RTL8367C_REG_METER12_BUCKET_SIZE 0x160c -+ -+#define RTL8367C_REG_METER13_BUCKET_SIZE 0x160d -+ -+#define RTL8367C_REG_METER14_BUCKET_SIZE 0x160e -+ -+#define RTL8367C_REG_METER15_BUCKET_SIZE 0x160f -+ -+#define RTL8367C_REG_METER16_BUCKET_SIZE 0x1610 -+ -+#define RTL8367C_REG_METER17_BUCKET_SIZE 0x1611 -+ -+#define RTL8367C_REG_METER18_BUCKET_SIZE 0x1612 -+ -+#define RTL8367C_REG_METER19_BUCKET_SIZE 0x1613 -+ -+#define RTL8367C_REG_METER20_BUCKET_SIZE 0x1614 -+ -+#define RTL8367C_REG_METER21_BUCKET_SIZE 0x1615 -+ -+#define RTL8367C_REG_METER22_BUCKET_SIZE 0x1616 -+ -+#define RTL8367C_REG_METER23_BUCKET_SIZE 0x1617 -+ -+#define RTL8367C_REG_METER24_BUCKET_SIZE 0x1618 -+ -+#define RTL8367C_REG_METER25_BUCKET_SIZE 0x1619 -+ -+#define RTL8367C_REG_METER26_BUCKET_SIZE 0x161a -+ -+#define RTL8367C_REG_METER27_BUCKET_SIZE 0x161b -+ -+#define RTL8367C_REG_METER28_BUCKET_SIZE 0x161c -+ -+#define RTL8367C_REG_METER29_BUCKET_SIZE 0x161d -+ -+#define RTL8367C_REG_METER30_BUCKET_SIZE 0x161e -+ -+#define RTL8367C_REG_METER31_BUCKET_SIZE 0x161f -+ -+#define RTL8367C_REG_METER_CTRL0 0x1700 -+#define RTL8367C_METER_OP_OFFSET 8 -+#define RTL8367C_METER_OP_MASK 0x100 -+#define RTL8367C_METER_TICK_OFFSET 0 -+#define RTL8367C_METER_TICK_MASK 0xFF -+ -+#define RTL8367C_REG_METER_CTRL1 0x1701 -+#define RTL8367C_METER_CTRL1_OFFSET 0 -+#define RTL8367C_METER_CTRL1_MASK 0xFF -+ -+#define RTL8367C_REG_METER_OVERRATE_INDICATOR0 0x1702 -+ -+#define RTL8367C_REG_METER_OVERRATE_INDICATOR1 0x1703 -+ -+#define RTL8367C_REG_METER_OVERRATE_INDICATOR0_8051 0x1704 -+ -+#define RTL8367C_REG_METER_OVERRATE_INDICATOR1_8051 0x1705 -+ -+#define RTL8367C_REG_METER_IFG_CTRL0 0x1712 -+#define RTL8367C_METER15_IFG_OFFSET 15 -+#define RTL8367C_METER15_IFG_MASK 0x8000 -+#define RTL8367C_METER14_IFG_OFFSET 14 -+#define RTL8367C_METER14_IFG_MASK 0x4000 -+#define RTL8367C_METER13_IFG_OFFSET 13 -+#define RTL8367C_METER13_IFG_MASK 0x2000 -+#define RTL8367C_METER12_IFG_OFFSET 12 -+#define RTL8367C_METER12_IFG_MASK 0x1000 -+#define RTL8367C_METER11_IFG_OFFSET 11 -+#define RTL8367C_METER11_IFG_MASK 0x800 -+#define RTL8367C_METER10_IFG_OFFSET 10 -+#define RTL8367C_METER10_IFG_MASK 0x400 -+#define RTL8367C_METER9_IFG_OFFSET 9 -+#define RTL8367C_METER9_IFG_MASK 0x200 -+#define RTL8367C_METER8_IFG_OFFSET 8 -+#define RTL8367C_METER8_IFG_MASK 0x100 -+#define RTL8367C_METER7_IFG_OFFSET 7 -+#define RTL8367C_METER7_IFG_MASK 0x80 -+#define RTL8367C_METER6_IFG_OFFSET 6 -+#define RTL8367C_METER6_IFG_MASK 0x40 -+#define RTL8367C_METER5_IFG_OFFSET 5 -+#define RTL8367C_METER5_IFG_MASK 0x20 -+#define RTL8367C_METER4_IFG_OFFSET 4 -+#define RTL8367C_METER4_IFG_MASK 0x10 -+#define RTL8367C_METER3_IFG_OFFSET 3 -+#define RTL8367C_METER3_IFG_MASK 0x8 -+#define RTL8367C_METER2_IFG_OFFSET 2 -+#define RTL8367C_METER2_IFG_MASK 0x4 -+#define RTL8367C_METER1_IFG_OFFSET 1 -+#define RTL8367C_METER1_IFG_MASK 0x2 -+#define RTL8367C_METER0_IFG_OFFSET 0 -+#define RTL8367C_METER0_IFG_MASK 0x1 -+ -+#define RTL8367C_REG_METER_IFG_CTRL1 0x1713 -+#define RTL8367C_METER31_IFG_OFFSET 15 -+#define RTL8367C_METER31_IFG_MASK 0x8000 -+#define RTL8367C_METER30_IFG_OFFSET 14 -+#define RTL8367C_METER30_IFG_MASK 0x4000 -+#define RTL8367C_METER29_IFG_OFFSET 13 -+#define RTL8367C_METER29_IFG_MASK 0x2000 -+#define RTL8367C_METER28_IFG_OFFSET 12 -+#define RTL8367C_METER28_IFG_MASK 0x1000 -+#define RTL8367C_METER27_IFG_OFFSET 11 -+#define RTL8367C_METER27_IFG_MASK 0x800 -+#define RTL8367C_METER26_IFG_OFFSET 10 -+#define RTL8367C_METER26_IFG_MASK 0x400 -+#define RTL8367C_METER25_IFG_OFFSET 9 -+#define RTL8367C_METER25_IFG_MASK 0x200 -+#define RTL8367C_METER24_IFG_OFFSET 8 -+#define RTL8367C_METER24_IFG_MASK 0x100 -+#define RTL8367C_METER23_IFG_OFFSET 7 -+#define RTL8367C_METER23_IFG_MASK 0x80 -+#define RTL8367C_METER22_IFG_OFFSET 6 -+#define RTL8367C_METER22_IFG_MASK 0x40 -+#define RTL8367C_METER21_IFG_OFFSET 5 -+#define RTL8367C_METER21_IFG_MASK 0x20 -+#define RTL8367C_METER20_IFG_OFFSET 4 -+#define RTL8367C_METER20_IFG_MASK 0x10 -+#define RTL8367C_METER19_IFG_OFFSET 3 -+#define RTL8367C_METER19_IFG_MASK 0x8 -+#define RTL8367C_METER18_IFG_OFFSET 2 -+#define RTL8367C_METER18_IFG_MASK 0x4 -+#define RTL8367C_METER17_IFG_OFFSET 1 -+#define RTL8367C_METER17_IFG_MASK 0x2 -+#define RTL8367C_METER16_IFG_OFFSET 0 -+#define RTL8367C_METER16_IFG_MASK 0x1 -+ -+#define RTL8367C_REG_METER_CTRL2 0x1722 -+#define RTL8367C_cfg_mtr_tick_8g_OFFSET 8 -+#define RTL8367C_cfg_mtr_tick_8g_MASK 0xFF00 -+#define RTL8367C_cfg_mtr_dec_cnt_8g_OFFSET 0 -+#define RTL8367C_cfg_mtr_dec_cnt_8g_MASK 0xFF -+ -+#define RTL8367C_REG_DUMMY_1723 0x1723 -+ -+#define RTL8367C_REG_DUMMY_1724 0x1724 -+ -+#define RTL8367C_REG_DUMMY_1725 0x1725 -+ -+#define RTL8367C_REG_DUMMY_1726 0x1726 -+ -+#define RTL8367C_REG_DUMMY_1727 0x1727 -+ -+#define RTL8367C_REG_DUMMY_1728 0x1728 -+ -+#define RTL8367C_REG_DUMMY_1729 0x1729 -+ -+#define RTL8367C_REG_DUMMY_172A 0x172a -+ -+#define RTL8367C_REG_DUMMY_172B 0x172b -+ -+#define RTL8367C_REG_DUMMY_172C 0x172c -+ -+#define RTL8367C_REG_DUMMY_172D 0x172d -+ -+#define RTL8367C_REG_DUMMY_172E 0x172e -+ -+#define RTL8367C_REG_DUMMY_172F 0x172f -+ -+#define RTL8367C_REG_DUMMY_1730 0x1730 -+ -+#define RTL8367C_REG_DUMMY_1731 0x1731 -+ -+#define RTL8367C_REG_METER32_RATE_CTRL0 0x1740 -+ -+#define RTL8367C_REG_METER32_RATE_CTRL1 0x1741 -+#define RTL8367C_METER32_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER32_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER33_RATE_CTRL0 0x1742 -+ -+#define RTL8367C_REG_METER33_RATE_CTRL1 0x1743 -+#define RTL8367C_METER33_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER33_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER34_RATE_CTRL0 0x1744 -+ -+#define RTL8367C_REG_METER34_RATE_CTRL1 0x1745 -+#define RTL8367C_METER34_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER34_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER35_RATE_CTRL0 0x1746 -+ -+#define RTL8367C_REG_METER35_RATE_CTRL1 0x1747 -+#define RTL8367C_METER35_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER35_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER36_RATE_CTRL0 0x1748 -+ -+#define RTL8367C_REG_METER36_RATE_CTRL1 0x1749 -+#define RTL8367C_METER36_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER36_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER37_RATE_CTRL0 0x174a -+ -+#define RTL8367C_REG_METER37_RATE_CTRL1 0x174b -+#define RTL8367C_METER37_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER37_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER38_RATE_CTRL0 0x174c -+ -+#define RTL8367C_REG_METER38_RATE_CTRL1 0x174d -+#define RTL8367C_METER38_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER38_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER39_RATE_CTRL0 0x174e -+ -+#define RTL8367C_REG_METER39_RATE_CTRL1 0x174f -+#define RTL8367C_METER39_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER39_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER40_RATE_CTRL0 0x1750 -+ -+#define RTL8367C_REG_METER40_RATE_CTRL1 0x1751 -+#define RTL8367C_METER40_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER40_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER41_RATE_CTRL0 0x1752 -+ -+#define RTL8367C_REG_METER41_RATE_CTRL1 0x1753 -+#define RTL8367C_METER41_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER41_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER42_RATE_CTRL0 0x1754 -+ -+#define RTL8367C_REG_METER42_RATE_CTRL1 0x1755 -+#define RTL8367C_METER42_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER42_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER43_RATE_CTRL0 0x1756 -+ -+#define RTL8367C_REG_METER43_RATE_CTRL1 0x1757 -+#define RTL8367C_METER43_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER43_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER44_RATE_CTRL0 0x1758 -+ -+#define RTL8367C_REG_METER44_RATE_CTRL1 0x1759 -+#define RTL8367C_METER44_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER44_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER45_RATE_CTRL0 0x175a -+ -+#define RTL8367C_REG_METER45_RATE_CTRL1 0x175b -+#define RTL8367C_METER45_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER45_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER46_RATE_CTRL0 0x175c -+ -+#define RTL8367C_REG_METER46_RATE_CTRL1 0x175d -+#define RTL8367C_METER46_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER46_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER47_RATE_CTRL0 0x175e -+ -+#define RTL8367C_REG_METER47_RATE_CTRL1 0x175f -+#define RTL8367C_METER47_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER47_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER48_RATE_CTRL0 0x1760 -+ -+#define RTL8367C_REG_METER48_RATE_CTRL1 0x1761 -+#define RTL8367C_METER48_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER48_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER49_RATE_CTRL0 0x1762 -+ -+#define RTL8367C_REG_METER49_RATE_CTRL1 0x1763 -+#define RTL8367C_METER49_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER49_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER50_RATE_CTRL0 0x1764 -+ -+#define RTL8367C_REG_METER50_RATE_CTRL1 0x1765 -+#define RTL8367C_METER50_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER50_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER51_RATE_CTRL0 0x1766 -+ -+#define RTL8367C_REG_METER51_RATE_CTRL1 0x1767 -+#define RTL8367C_METER51_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER51_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER52_RATE_CTRL0 0x1768 -+ -+#define RTL8367C_REG_METER52_RATE_CTRL1 0x1769 -+#define RTL8367C_METER52_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER52_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER53_RATE_CTRL0 0x176a -+ -+#define RTL8367C_REG_METER53_RATE_CTRL1 0x176b -+#define RTL8367C_METER53_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER53_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER54_RATE_CTRL0 0x176c -+ -+#define RTL8367C_REG_METER54_RATE_CTRL1 0x176d -+#define RTL8367C_METER54_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER54_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER55_RATE_CTRL0 0x176e -+ -+#define RTL8367C_REG_METER55_RATE_CTRL1 0x176f -+#define RTL8367C_METER55_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER55_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER56_RATE_CTRL0 0x1770 -+ -+#define RTL8367C_REG_METER56_RATE_CTRL1 0x1771 -+#define RTL8367C_METER56_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER56_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER57_RATE_CTRL0 0x1772 -+ -+#define RTL8367C_REG_METER57_RATE_CTRL1 0x1773 -+#define RTL8367C_METER57_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER57_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER58_RATE_CTRL0 0x1774 -+ -+#define RTL8367C_REG_METER58_RATE_CTRL1 0x1775 -+#define RTL8367C_METER58_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER58_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER59_RATE_CTRL0 0x1776 -+ -+#define RTL8367C_REG_METER59_RATE_CTRL1 0x1777 -+#define RTL8367C_METER59_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER59_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER60_RATE_CTRL0 0x1778 -+ -+#define RTL8367C_REG_METER60_RATE_CTRL1 0x1779 -+#define RTL8367C_METER60_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER60_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER61_RATE_CTRL0 0x177a -+ -+#define RTL8367C_REG_METER61_RATE_CTRL1 0x177b -+#define RTL8367C_METER61_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER61_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER62_RATE_CTRL0 0x177c -+ -+#define RTL8367C_REG_METER62_RATE_CTRL1 0x177d -+#define RTL8367C_METER62_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER62_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER63_RATE_CTRL0 0x177e -+ -+#define RTL8367C_REG_METER63_RATE_CTRL1 0x177f -+#define RTL8367C_METER63_RATE_CTRL1_OFFSET 0 -+#define RTL8367C_METER63_RATE_CTRL1_MASK 0x7 -+ -+#define RTL8367C_REG_METER_MODE_SETTING2 0x1780 -+ -+#define RTL8367C_REG_METER_MODE_SETTING3 0x1781 -+ -+#define RTL8367C_REG_METER32_BUCKET_SIZE 0x1790 -+ -+#define RTL8367C_REG_METER33_BUCKET_SIZE 0x1791 -+ -+#define RTL8367C_REG_METER34_BUCKET_SIZE 0x1792 -+ -+#define RTL8367C_REG_METER35_BUCKET_SIZE 0x1793 -+ -+#define RTL8367C_REG_METER36_BUCKET_SIZE 0x1794 -+ -+#define RTL8367C_REG_METER37_BUCKET_SIZE 0x1795 -+ -+#define RTL8367C_REG_METER38_BUCKET_SIZE 0x1796 -+ -+#define RTL8367C_REG_METER39_BUCKET_SIZE 0x1797 -+ -+#define RTL8367C_REG_METER40_BUCKET_SIZE 0x1798 -+ -+#define RTL8367C_REG_METER41_BUCKET_SIZE 0x1799 -+ -+#define RTL8367C_REG_METER42_BUCKET_SIZE 0x179a -+ -+#define RTL8367C_REG_METER43_BUCKET_SIZE 0x179b -+ -+#define RTL8367C_REG_METER44_BUCKET_SIZE 0x179c -+ -+#define RTL8367C_REG_METER45_BUCKET_SIZE 0x179d -+ -+#define RTL8367C_REG_METER46_BUCKET_SIZE 0x179e -+ -+#define RTL8367C_REG_METER47_BUCKET_SIZE 0x179f -+ -+#define RTL8367C_REG_METER48_BUCKET_SIZE 0x17a0 -+ -+#define RTL8367C_REG_METER49_BUCKET_SIZE 0x17a1 -+ -+#define RTL8367C_REG_METER50_BUCKET_SIZE 0x17a2 -+ -+#define RTL8367C_REG_METER51_BUCKET_SIZE 0x17a3 -+ -+#define RTL8367C_REG_METER52_BUCKET_SIZE 0x17a4 -+ -+#define RTL8367C_REG_METER53_BUCKET_SIZE 0x17a5 -+ -+#define RTL8367C_REG_METER54_BUCKET_SIZE 0x17a6 -+ -+#define RTL8367C_REG_METER55_BUCKET_SIZE 0x17a7 -+ -+#define RTL8367C_REG_METER56_BUCKET_SIZE 0x17a8 -+ -+#define RTL8367C_REG_METER57_BUCKET_SIZE 0x17a9 -+ -+#define RTL8367C_REG_METER58_BUCKET_SIZE 0x17aa -+ -+#define RTL8367C_REG_METER59_BUCKET_SIZE 0x17ab -+ -+#define RTL8367C_REG_METER60_BUCKET_SIZE 0x17ac -+ -+#define RTL8367C_REG_METER61_BUCKET_SIZE 0x17ad -+ -+#define RTL8367C_REG_METER62_BUCKET_SIZE 0x17ae -+ -+#define RTL8367C_REG_METER63_BUCKET_SIZE 0x17af -+ -+#define RTL8367C_REG_METER_OVERRATE_INDICATOR2 0x17b0 -+ -+#define RTL8367C_REG_METER_OVERRATE_INDICATOR3 0x17b1 -+ -+#define RTL8367C_REG_METER_OVERRATE_INDICATOR2_8051 0x17b2 -+ -+#define RTL8367C_REG_METER_OVERRATE_INDICATOR3_8051 0x17b3 -+ -+#define RTL8367C_REG_METER_IFG_CTRL2 0x17b4 -+#define RTL8367C_METER47_IFG_OFFSET 15 -+#define RTL8367C_METER47_IFG_MASK 0x8000 -+#define RTL8367C_METER46_IFG_OFFSET 14 -+#define RTL8367C_METER46_IFG_MASK 0x4000 -+#define RTL8367C_METER45_IFG_OFFSET 13 -+#define RTL8367C_METER45_IFG_MASK 0x2000 -+#define RTL8367C_METER44_IFG_OFFSET 12 -+#define RTL8367C_METER44_IFG_MASK 0x1000 -+#define RTL8367C_METER43_IFG_OFFSET 11 -+#define RTL8367C_METER43_IFG_MASK 0x800 -+#define RTL8367C_METER42_IFG_OFFSET 10 -+#define RTL8367C_METER42_IFG_MASK 0x400 -+#define RTL8367C_METER41_IFG_OFFSET 9 -+#define RTL8367C_METER41_IFG_MASK 0x200 -+#define RTL8367C_METER40_IFG_OFFSET 8 -+#define RTL8367C_METER40_IFG_MASK 0x100 -+#define RTL8367C_METER39_IFG_OFFSET 7 -+#define RTL8367C_METER39_IFG_MASK 0x80 -+#define RTL8367C_METER38_IFG_OFFSET 6 -+#define RTL8367C_METER38_IFG_MASK 0x40 -+#define RTL8367C_METER37_IFG_OFFSET 5 -+#define RTL8367C_METER37_IFG_MASK 0x20 -+#define RTL8367C_METER36_IFG_OFFSET 4 -+#define RTL8367C_METER36_IFG_MASK 0x10 -+#define RTL8367C_METER35_IFG_OFFSET 3 -+#define RTL8367C_METER35_IFG_MASK 0x8 -+#define RTL8367C_METER34_IFG_OFFSET 2 -+#define RTL8367C_METER34_IFG_MASK 0x4 -+#define RTL8367C_METER33_IFG_OFFSET 1 -+#define RTL8367C_METER33_IFG_MASK 0x2 -+#define RTL8367C_METER32_IFG_OFFSET 0 -+#define RTL8367C_METER32_IFG_MASK 0x1 -+ -+#define RTL8367C_REG_METER_IFG_CTRL3 0x17b5 -+#define RTL8367C_METER63_IFG_OFFSET 15 -+#define RTL8367C_METER63_IFG_MASK 0x8000 -+#define RTL8367C_METER62_IFG_OFFSET 14 -+#define RTL8367C_METER62_IFG_MASK 0x4000 -+#define RTL8367C_METER61_IFG_OFFSET 13 -+#define RTL8367C_METER61_IFG_MASK 0x2000 -+#define RTL8367C_METER60_IFG_OFFSET 12 -+#define RTL8367C_METER60_IFG_MASK 0x1000 -+#define RTL8367C_METER59_IFG_OFFSET 11 -+#define RTL8367C_METER59_IFG_MASK 0x800 -+#define RTL8367C_METER58_IFG_OFFSET 10 -+#define RTL8367C_METER58_IFG_MASK 0x400 -+#define RTL8367C_METER57_IFG_OFFSET 9 -+#define RTL8367C_METER57_IFG_MASK 0x200 -+#define RTL8367C_METER56_IFG_OFFSET 8 -+#define RTL8367C_METER56_IFG_MASK 0x100 -+#define RTL8367C_METER55_IFG_OFFSET 7 -+#define RTL8367C_METER55_IFG_MASK 0x80 -+#define RTL8367C_METER54_IFG_OFFSET 6 -+#define RTL8367C_METER54_IFG_MASK 0x40 -+#define RTL8367C_METER53_IFG_OFFSET 5 -+#define RTL8367C_METER53_IFG_MASK 0x20 -+#define RTL8367C_METER52_IFG_OFFSET 4 -+#define RTL8367C_METER52_IFG_MASK 0x10 -+#define RTL8367C_METER51_IFG_OFFSET 3 -+#define RTL8367C_METER51_IFG_MASK 0x8 -+#define RTL8367C_METER50_IFG_OFFSET 2 -+#define RTL8367C_METER50_IFG_MASK 0x4 -+#define RTL8367C_METER49_IFG_OFFSET 1 -+#define RTL8367C_METER49_IFG_MASK 0x2 -+#define RTL8367C_METER48_IFG_OFFSET 0 -+#define RTL8367C_METER48_IFG_MASK 0x1 -+ -+#define RTL8367C_REG_METER_MISC 0x17b6 -+#define RTL8367C_METER_MISC_OFFSET 0 -+#define RTL8367C_METER_MISC_MASK 0x1 -+ -+/* (16'h1800)8051_RLDP_EEE_reg */ -+ -+#define RTL8367C_REG_EEELLDP_CTRL0 0x1820 -+#define RTL8367C_EEELLDP_SUBTYPE_OFFSET 6 -+#define RTL8367C_EEELLDP_SUBTYPE_MASK 0x3FC0 -+#define RTL8367C_EEELLDP_TRAP_8051_OFFSET 2 -+#define RTL8367C_EEELLDP_TRAP_8051_MASK 0x4 -+#define RTL8367C_EEELLDP_TRAP_CPU_OFFSET 1 -+#define RTL8367C_EEELLDP_TRAP_CPU_MASK 0x2 -+#define RTL8367C_EEELLDP_ENABLE_OFFSET 0 -+#define RTL8367C_EEELLDP_ENABLE_MASK 0x1 -+ -+#define RTL8367C_REG_EEELLDP_PMSK 0x1822 -+#define RTL8367C_EEELLDP_PMSK_OFFSET 0 -+#define RTL8367C_EEELLDP_PMSK_MASK 0x7FF -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_08 0x1843 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_07 0x1844 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_06 0x1845 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_05 0x1846 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_04 0x1847 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_03 0x1848 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_02 0x1849 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_01 0x184a -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_00 0x184b -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_08 0x184c -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_07 0x184d -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_06 0x184e -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_05 0x184f -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_04 0x1850 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_03 0x1851 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_02 0x1852 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_01 0x1853 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_00 0x1854 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_08 0x1855 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_07 0x1856 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_06 0x1857 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_05 0x1858 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_04 0x1859 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_03 0x185a -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_02 0x185b -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_01 0x185c -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_00 0x185d -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_08 0x185e -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_07 0x185f -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_06 0x1860 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_05 0x1861 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_04 0x1862 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_03 0x1863 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_02 0x1864 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_01 0x1865 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_00 0x1866 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_08 0x1867 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_07 0x1868 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_06 0x1869 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_05 0x186a -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_04 0x186b -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_03 0x186c -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_02 0x186d -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_01 0x186e -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_00 0x186f -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_08 0x1870 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_07 0x1871 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_06 0x1872 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_05 0x1873 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_04 0x1874 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_03 0x1875 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_02 0x1876 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_01 0x1877 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_00 0x1878 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_08 0x1879 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_07 0x187a -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_06 0x187b -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_05 0x187c -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_04 0x187d -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_03 0x187e -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_02 0x187f -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_01 0x1880 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_00 0x1881 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_08 0x1882 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_07 0x1883 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_06 0x1884 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_05 0x1885 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_04 0x1886 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_03 0x1887 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_02 0x1888 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_01 0x1889 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_00 0x188a -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_08 0x188b -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_07 0x188c -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_06 0x188d -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_05 0x188e -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_04 0x188f -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_03 0x1890 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_02 0x1891 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_01 0x1892 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_00 0x1893 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_08 0x1894 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_07 0x1895 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_06 0x1896 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_05 0x1897 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_04 0x1898 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_03 0x1899 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_02 0x189a -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_01 0x189b -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_00 0x189c -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_08 0x189d -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_07 0x189e -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_06 0x189f -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_05 0x18a0 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_04 0x18a1 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_03 0x18a2 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_02 0x18a3 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_01 0x18a4 -+ -+#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_00 0x18a5 -+ -+#define RTL8367C_REG_RLDP_CTRL0 0x18e0 -+#define RTL8367C_RLDP_TRIGGER_MODE_OFFSET 14 -+#define RTL8367C_RLDP_TRIGGER_MODE_MASK 0x4000 -+#define RTL8367C_RLDP_8051_LOOP_PORTMSK_OFFSET 6 -+#define RTL8367C_RLDP_8051_LOOP_PORTMSK_MASK 0x3FC0 -+#define RTL8367C_RLPP_8051_TRAP_OFFSET 5 -+#define RTL8367C_RLPP_8051_TRAP_MASK 0x20 -+#define RTL8367C_RLDP_INDICATOR_SOURCE_OFFSET 4 -+#define RTL8367C_RLDP_INDICATOR_SOURCE_MASK 0x10 -+#define RTL8367C_RLDP_GEN_RANDOM_OFFSET 3 -+#define RTL8367C_RLDP_GEN_RANDOM_MASK 0x8 -+#define RTL8367C_RLDP_COMP_ID_OFFSET 2 -+#define RTL8367C_RLDP_COMP_ID_MASK 0x4 -+#define RTL8367C_RLDP_8051_ENABLE_OFFSET 1 -+#define RTL8367C_RLDP_8051_ENABLE_MASK 0x2 -+#define RTL8367C_RLDP_ENABLE_OFFSET 0 -+#define RTL8367C_RLDP_ENABLE_MASK 0x1 -+ -+#define RTL8367C_REG_RLDP_CTRL1 0x18e1 -+#define RTL8367C_RLDP_RETRY_COUNT_LOOPSTATE_OFFSET 8 -+#define RTL8367C_RLDP_RETRY_COUNT_LOOPSTATE_MASK 0xFF00 -+#define RTL8367C_RLDP_RETRY_COUNT_CHKSTATE_OFFSET 0 -+#define RTL8367C_RLDP_RETRY_COUNT_CHKSTATE_MASK 0xFF -+ -+#define RTL8367C_REG_RLDP_CTRL2 0x18e2 -+ -+#define RTL8367C_REG_RLDP_CTRL3 0x18e3 -+ -+#define RTL8367C_REG_RLDP_CTRL4 0x18e4 -+#define RTL8367C_RLDP_CTRL4_OFFSET 0 -+#define RTL8367C_RLDP_CTRL4_MASK 0x7FF -+ -+#define RTL8367C_REG_RLDP_RAND_NUM0 0x18e5 -+ -+#define RTL8367C_REG_RLDP_RAND_NUM1 0x18e6 -+ -+#define RTL8367C_REG_RLDP_RAND_NUM2 0x18e7 -+ -+#define RTL8367C_REG_RLDP_MAGIC_NUM0 0x18e8 -+ -+#define RTL8367C_REG_RLDP_MAGIC_NUM1 0x18e9 -+ -+#define RTL8367C_REG_RLDP_MAGIC_NUM2 0x18ea -+ -+#define RTL8367C_REG_RLDP_LOOPED_INDICATOR 0x18eb -+#define RTL8367C_RLDP_LOOPED_INDICATOR_OFFSET 0 -+#define RTL8367C_RLDP_LOOPED_INDICATOR_MASK 0x7FF -+ -+#define RTL8367C_REG_RLDP_LOOP_PORT_REG0 0x18ec -+#define RTL8367C_RLDP_LOOP_PORT_01_OFFSET 8 -+#define RTL8367C_RLDP_LOOP_PORT_01_MASK 0xF00 -+#define RTL8367C_RLDP_LOOP_PORT_00_OFFSET 0 -+#define RTL8367C_RLDP_LOOP_PORT_00_MASK 0xF -+ -+#define RTL8367C_REG_RLDP_LOOP_PORT_REG1 0x18ed -+#define RTL8367C_RLDP_LOOP_PORT_03_OFFSET 8 -+#define RTL8367C_RLDP_LOOP_PORT_03_MASK 0xF00 -+#define RTL8367C_RLDP_LOOP_PORT_02_OFFSET 0 -+#define RTL8367C_RLDP_LOOP_PORT_02_MASK 0xF -+ -+#define RTL8367C_REG_RLDP_LOOP_PORT_REG2 0x18ee -+#define RTL8367C_RLDP_LOOP_PORT_05_OFFSET 8 -+#define RTL8367C_RLDP_LOOP_PORT_05_MASK 0xF00 -+#define RTL8367C_RLDP_LOOP_PORT_04_OFFSET 0 -+#define RTL8367C_RLDP_LOOP_PORT_04_MASK 0xF -+ -+#define RTL8367C_REG_RLDP_LOOP_PORT_REG3 0x18ef -+#define RTL8367C_RLDP_LOOP_PORT_07_OFFSET 8 -+#define RTL8367C_RLDP_LOOP_PORT_07_MASK 0xF00 -+#define RTL8367C_RLDP_LOOP_PORT_06_OFFSET 0 -+#define RTL8367C_RLDP_LOOP_PORT_06_MASK 0xF -+ -+#define RTL8367C_REG_RLDP_RELEASED_INDICATOR 0x18f0 -+#define RTL8367C_RLDP_RELEASED_INDICATOR_OFFSET 0 -+#define RTL8367C_RLDP_RELEASED_INDICATOR_MASK 0x7FF -+ -+#define RTL8367C_REG_RLDP_LOOPSTATUS_INDICATOR 0x18f1 -+#define RTL8367C_RLDP_LOOPSTATUS_INDICATOR_OFFSET 0 -+#define RTL8367C_RLDP_LOOPSTATUS_INDICATOR_MASK 0x7FF -+ -+#define RTL8367C_REG_RLDP_LOOP_PORT_REG4 0x18f2 -+#define RTL8367C_RLDP_LOOP_PORT_9_OFFSET 8 -+#define RTL8367C_RLDP_LOOP_PORT_9_MASK 0xF00 -+#define RTL8367C_RLDP_LOOP_PORT_8_OFFSET 0 -+#define RTL8367C_RLDP_LOOP_PORT_8_MASK 0xF -+ -+#define RTL8367C_REG_RLDP_LOOP_PORT_REG5 0x18f3 -+#define RTL8367C_RLDP_LOOP_PORT_REG5_OFFSET 0 -+#define RTL8367C_RLDP_LOOP_PORT_REG5_MASK 0xF -+ -+#define RTL8367C_REG_RLDP_CTRL5 0x18f4 -+#define RTL8367C_RLDP_CTRL5_OFFSET 0 -+#define RTL8367C_RLDP_CTRL5_MASK 0x7 -+ -+/* (16'h1900)EEE_EEEP_reg */ -+ -+#define RTL8367C_REG_EEE_500M_CTRL0 0x1900 -+#define RTL8367C_EEE_500M_CTRL0_OFFSET 0 -+#define RTL8367C_EEE_500M_CTRL0_MASK 0xFF -+ -+#define RTL8367C_REG_EEE_RXIDLE_GIGA_CTRL 0x1901 -+#define RTL8367C_EEE_RXIDLE_GIGA_EN_OFFSET 8 -+#define RTL8367C_EEE_RXIDLE_GIGA_EN_MASK 0x100 -+#define RTL8367C_EEE_RXIDLE_GIGA_OFFSET 0 -+#define RTL8367C_EEE_RXIDLE_GIGA_MASK 0xFF -+ -+#define RTL8367C_REG_EEE_RXIDLE_500M_CTRL 0x1902 -+#define RTL8367C_EEE_RXIDLE_500M_EN_OFFSET 8 -+#define RTL8367C_EEE_RXIDLE_500M_EN_MASK 0x100 -+#define RTL8367C_EEE_RXIDLE_500M_OFFSET 0 -+#define RTL8367C_EEE_RXIDLE_500M_MASK 0xFF -+ -+#define RTL8367C_REG_EEE_DECISION_GIGA_500M 0x1903 -+#define RTL8367C_EEE_DECISION_GIGA_OFFSET 8 -+#define RTL8367C_EEE_DECISION_GIGA_MASK 0xFF00 -+#define RTL8367C_EEE_DECISION_500M_OFFSET 0 -+#define RTL8367C_EEE_DECISION_500M_MASK 0xFF -+ -+#define RTL8367C_REG_EEE_DECISION_100M 0x1904 -+#define RTL8367C_EEE_DECISION_100M_OFFSET 0 -+#define RTL8367C_EEE_DECISION_100M_MASK 0xFF -+ -+#define RTL8367C_REG_EEEP_DEFER_TXLPI 0x1905 -+#define RTL8367C_EEEP_DEFER_TXLPI_OFFSET 0 -+#define RTL8367C_EEEP_DEFER_TXLPI_MASK 0x1 -+ -+#define RTL8367C_REG_EEEP_EN 0x1906 -+#define RTL8367C_EEEP_SLAVE_EN_OFFSET 3 -+#define RTL8367C_EEEP_SLAVE_EN_MASK 0x8 -+#define RTL8367C_EEEP_100M_OFFSET 2 -+#define RTL8367C_EEEP_100M_MASK 0x4 -+#define RTL8367C_EEEP_500M_OFFSET 1 -+#define RTL8367C_EEEP_500M_MASK 0x2 -+#define RTL8367C_EEEP_GIGA_OFFSET 0 -+#define RTL8367C_EEEP_GIGA_MASK 0x1 -+ -+#define RTL8367C_REG_EEEP_TI_GIGA_500M 0x1907 -+#define RTL8367C_EEEP_TI_GIGA_OFFSET 8 -+#define RTL8367C_EEEP_TI_GIGA_MASK 0xFF00 -+#define RTL8367C_EEEP_TI_500M_OFFSET 0 -+#define RTL8367C_EEEP_TI_500M_MASK 0xFF -+ -+#define RTL8367C_REG_EEEP_TI_100M 0x1908 -+#define RTL8367C_EEEP_TI_100M_OFFSET 0 -+#define RTL8367C_EEEP_TI_100M_MASK 0xFF -+ -+#define RTL8367C_REG_EEEP_CTRL2 0x1909 -+#define RTL8367C_EEEP_CTRL2_OFFSET 0 -+#define RTL8367C_EEEP_CTRL2_MASK 0xFF -+ -+#define RTL8367C_REG_EEEP_RX_RATE_500M 0x190b -+ -+#define RTL8367C_REG_EEEP_RW_GIGA_SLV 0x190c -+#define RTL8367C_EEEP_RW_GIGA_SLV_OFFSET 0 -+#define RTL8367C_EEEP_RW_GIGA_SLV_MASK 0xFF -+ -+#define RTL8367C_REG_EEEP_TMR_GIGA 0x190d -+#define RTL8367C_RX_IDLE_EEEP_GIGA_OFFSET 8 -+#define RTL8367C_RX_IDLE_EEEP_GIGA_MASK 0xFF00 -+#define RTL8367C_RX_MIN_SLP_TMR_GIGA_OFFSET 0 -+#define RTL8367C_RX_MIN_SLP_TMR_GIGA_MASK 0xFF -+ -+#define RTL8367C_REG_EEEP_TMR_500M 0x190e -+#define RTL8367C_RX_IDLE_EEEP_500M_OFFSET 8 -+#define RTL8367C_RX_IDLE_EEEP_500M_MASK 0xFF00 -+#define RTL8367C_RX_MIN_SLP_TMR_500M_OFFSET 0 -+#define RTL8367C_RX_MIN_SLP_TMR_500M_MASK 0xFF -+ -+#define RTL8367C_REG_EEEP_TMR_100M 0x190f -+#define RTL8367C_RX_IDLE_EEEP_100M_OFFSET 8 -+#define RTL8367C_RX_IDLE_EEEP_100M_MASK 0xFF00 -+#define RTL8367C_RX_MIN_SLP_TMR_100M_OFFSET 0 -+#define RTL8367C_RX_MIN_SLP_TMR_100M_MASK 0xFF -+ -+#define RTL8367C_REG_EEEP_RW_500M_MST_SLV 0x1910 -+#define RTL8367C_EEEP_RW_500M_MST_OFFSET 8 -+#define RTL8367C_EEEP_RW_500M_MST_MASK 0xFF00 -+#define RTL8367C_EEEP_RW_500M_SLV_OFFSET 0 -+#define RTL8367C_EEEP_RW_500M_SLV_MASK 0xFF -+ -+#define RTL8367C_REG_EEEP_500M_CTRL0 0x1911 -+#define RTL8367C_EEEP_500M_CTRL0_OFFSET 0 -+#define RTL8367C_EEEP_500M_CTRL0_MASK 0xFF -+ -+#define RTL8367C_REG_EEEP_500M_CTRL1 0x1912 -+#define RTL8367C_EEEP_TW_500M_OFFSET 8 -+#define RTL8367C_EEEP_TW_500M_MASK 0xFF00 -+#define RTL8367C_EEEP_TP_500M_OFFSET 0 -+#define RTL8367C_EEEP_TP_500M_MASK 0xFF -+ -+#define RTL8367C_REG_EEEP_500M_CTRL2 0x1913 -+#define RTL8367C_EEEP_TXEN_500M_OFFSET 12 -+#define RTL8367C_EEEP_TXEN_500M_MASK 0x1000 -+#define RTL8367C_EEEP_TU_500M_OFFSET 8 -+#define RTL8367C_EEEP_TU_500M_MASK 0x300 -+#define RTL8367C_EEEP_TS_500M_OFFSET 0 -+#define RTL8367C_EEEP_TS_500M_MASK 0xFF -+ -+#define RTL8367C_REG_EEE_NEW_CTRL0 0x1914 -+#define RTL8367C_LINK_UP_DELAY_OFFSET 3 -+#define RTL8367C_LINK_UP_DELAY_MASK 0x18 -+#define RTL8367C_EEE_TXLPI_ORI_OFFSET 2 -+#define RTL8367C_EEE_TXLPI_ORI_MASK 0x4 -+#define RTL8367C_REALTX_SEL_OFFSET 1 -+#define RTL8367C_REALTX_SEL_MASK 0x2 -+#define RTL8367C_EN_FC_EFCT_OFFSET 0 -+#define RTL8367C_EN_FC_EFCT_MASK 0x1 -+ -+#define RTL8367C_REG_EEE_LONGIDLE_100M 0x1915 -+#define RTL8367C_EEE_LONGIDLE_100M_OFFSET 0 -+#define RTL8367C_EEE_LONGIDLE_100M_MASK 0x3FF -+ -+#define RTL8367C_REG_EEE_LONGIDLE_500M 0x1916 -+#define RTL8367C_EEE_LONGIDLE_500M_OFFSET 0 -+#define RTL8367C_EEE_LONGIDLE_500M_MASK 0x3FF -+ -+#define RTL8367C_REG_EEE_LONGIDLE_GIGA 0x1917 -+#define RTL8367C_EEE_LONGIDLE_GIGA_OFFSET 0 -+#define RTL8367C_EEE_LONGIDLE_GIGA_MASK 0x3FF -+ -+#define RTL8367C_REG_EEE_MINIPG_100M 0x1918 -+ -+#define RTL8367C_REG_EEE_MINIPG_500M 0x1919 -+ -+#define RTL8367C_REG_EEE_MINIPG_GIGA 0x191A -+ -+#define RTL8367C_REG_EEE_LONGIDLE_CTRL0 0x191B -+#define RTL8367C_TX_IDLEN_REQ_100M_OFFSET 10 -+#define RTL8367C_TX_IDLEN_REQ_100M_MASK 0x400 -+#define RTL8367C_TX_IDLEN_REQ_500M_OFFSET 9 -+#define RTL8367C_TX_IDLEN_REQ_500M_MASK 0x200 -+#define RTL8367C_TX_IDLEN_REQ_GIGA_OFFSET 8 -+#define RTL8367C_TX_IDLEN_REQ_GIGA_MASK 0x100 -+#define RTL8367C_EEE_LONGIDLE_CTRL0_TX_LPI_MINIPG_100M_OFFSET 0 -+#define RTL8367C_EEE_LONGIDLE_CTRL0_TX_LPI_MINIPG_100M_MASK 0xFF -+ -+#define RTL8367C_REG_EEE_LONGIDLE_CTRL1 0x191C -+#define RTL8367C_EEE_LONGIDLE_CTRL1_TX_LPI_MINIPG_GELITE_OFFSET 8 -+#define RTL8367C_EEE_LONGIDLE_CTRL1_TX_LPI_MINIPG_GELITE_MASK 0xFF00 -+#define RTL8367C_EEE_LONGIDLE_CTRL1_TX_LPI_MINIPG_GIGA_OFFSET 0 -+#define RTL8367C_EEE_LONGIDLE_CTRL1_TX_LPI_MINIPG_GIGA_MASK 0xFF -+ -+#define RTL8367C_REG_EEE_TD_CTRL_H 0x191d -+#define RTL8367C_REF_RXLPI_OFFSET 8 -+#define RTL8367C_REF_RXLPI_MASK 0x100 -+#define RTL8367C_LOW_Q_TX_DELAY_GE_500M_H_OFFSET 4 -+#define RTL8367C_LOW_Q_TX_DELAY_GE_500M_H_MASK 0xF0 -+#define RTL8367C_LOW_Q_TX_DELAY_FE_H_OFFSET 0 -+#define RTL8367C_LOW_Q_TX_DELAY_FE_H_MASK 0xF -+ -+/* (16'h1a00)nic_reg */ -+ -+#define RTL8367C_REG_NIC_RXRDRL 0x1a04 -+#define RTL8367C_NIC_RXRDRL_OFFSET 0 -+#define RTL8367C_NIC_RXRDRL_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_RXRDRH 0x1a05 -+#define RTL8367C_NIC_RXRDRH_OFFSET 0 -+#define RTL8367C_NIC_RXRDRH_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_TXASRL 0x1a08 -+#define RTL8367C_NIC_TXASRL_OFFSET 0 -+#define RTL8367C_NIC_TXASRL_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_TXASRH 0x1a09 -+#define RTL8367C_NIC_TXASRH_OFFSET 0 -+#define RTL8367C_NIC_TXASRH_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_RXCMDR 0x1a0c -+#define RTL8367C_NIC_RXCMDR_OFFSET 0 -+#define RTL8367C_NIC_RXCMDR_MASK 0x1 -+ -+#define RTL8367C_REG_NIC_TXCMDR 0x1a0d -+#define RTL8367C_NIC_TXCMDR_OFFSET 0 -+#define RTL8367C_NIC_TXCMDR_MASK 0x1 -+ -+#define RTL8367C_REG_NIC_IMS 0x1a0e -+#define RTL8367C_NIC_RXIS_OFFSET 7 -+#define RTL8367C_NIC_RXIS_MASK 0x80 -+#define RTL8367C_NIC_TXIS_OFFSET 6 -+#define RTL8367C_NIC_TXIS_MASK 0x40 -+#define RTL8367C_NIC_TXES_OFFSET 5 -+#define RTL8367C_NIC_TXES_MASK 0x20 -+#define RTL8367C_NIC_IMS_DMY_OFFSET 4 -+#define RTL8367C_NIC_IMS_DMY_MASK 0x10 -+#define RTL8367C_NIC_RXBUS_OFFSET 3 -+#define RTL8367C_NIC_RXBUS_MASK 0x8 -+#define RTL8367C_NIC_TXBOS_OFFSET 2 -+#define RTL8367C_NIC_TXBOS_MASK 0x4 -+#define RTL8367C_NIC_RXMIS_OFFSET 1 -+#define RTL8367C_NIC_RXMIS_MASK 0x2 -+#define RTL8367C_NIC_TXNLS_OFFSET 0 -+#define RTL8367C_NIC_TXNLS_MASK 0x1 -+ -+#define RTL8367C_REG_NIC_IMR 0x1a0f -+#define RTL8367C_NIC_RXIE_OFFSET 7 -+#define RTL8367C_NIC_RXIE_MASK 0x80 -+#define RTL8367C_NIC_TXIE_OFFSET 6 -+#define RTL8367C_NIC_TXIE_MASK 0x40 -+#define RTL8367C_NIC_TXEE_OFFSET 5 -+#define RTL8367C_NIC_TXEE_MASK 0x20 -+#define RTL8367C_NIC_IMR_DMY_OFFSET 4 -+#define RTL8367C_NIC_IMR_DMY_MASK 0x10 -+#define RTL8367C_NIC_RXBUE_OFFSET 3 -+#define RTL8367C_NIC_RXBUE_MASK 0x8 -+#define RTL8367C_NIC_TXBOE_OFFSET 2 -+#define RTL8367C_NIC_TXBOE_MASK 0x4 -+#define RTL8367C_NIC_RXMIE_OFFSET 1 -+#define RTL8367C_NIC_RXMIE_MASK 0x2 -+#define RTL8367C_NIC_TXNLE_OFFSET 0 -+#define RTL8367C_NIC_TXNLE_MASK 0x1 -+ -+#define RTL8367C_REG_NIC_RXCR0 0x1a14 -+#define RTL8367C_NIC_HFPPE_OFFSET 7 -+#define RTL8367C_NIC_HFPPE_MASK 0x80 -+#define RTL8367C_NIC_HFMPE_OFFSET 6 -+#define RTL8367C_NIC_HFMPE_MASK 0x40 -+#define RTL8367C_NIC_RXBPE_OFFSET 5 -+#define RTL8367C_NIC_RXBPE_MASK 0x20 -+#define RTL8367C_NIC_RXMPE_OFFSET 4 -+#define RTL8367C_NIC_RXMPE_MASK 0x10 -+#define RTL8367C_NIC_RXPPS_OFFSET 2 -+#define RTL8367C_NIC_RXPPS_MASK 0xC -+#define RTL8367C_NIC_RXAPE_OFFSET 1 -+#define RTL8367C_NIC_RXAPE_MASK 0x2 -+#define RTL8367C_NIC_ARPPE_OFFSET 0 -+#define RTL8367C_NIC_ARPPE_MASK 0x1 -+ -+#define RTL8367C_REG_NIC_RXCR1 0x1a15 -+#define RTL8367C_NIC_RL4CEPE_OFFSET 4 -+#define RTL8367C_NIC_RL4CEPE_MASK 0x10 -+#define RTL8367C_NIC_RL3CEPE_OFFSET 3 -+#define RTL8367C_NIC_RL3CEPE_MASK 0x8 -+#define RTL8367C_NIC_RCRCEPE_OFFSET 2 -+#define RTL8367C_NIC_RCRCEPE_MASK 0x4 -+#define RTL8367C_NIC_RMCRC_OFFSET 1 -+#define RTL8367C_NIC_RMCRC_MASK 0x2 -+#define RTL8367C_NIC_RXENABLE_OFFSET 0 -+#define RTL8367C_NIC_RXENABLE_MASK 0x1 -+ -+#define RTL8367C_REG_NIC_TXCR 0x1a16 -+#define RTL8367C_NIC_LBE_OFFSET 2 -+#define RTL8367C_NIC_LBE_MASK 0x4 -+#define RTL8367C_NIC_TXMFM_OFFSET 1 -+#define RTL8367C_NIC_TXMFM_MASK 0x2 -+#define RTL8367C_NIC_TXENABLE_OFFSET 0 -+#define RTL8367C_NIC_TXENABLE_MASK 0x1 -+ -+#define RTL8367C_REG_NIC_GCR 0x1a17 -+#define RTL8367C_DUMMY_7_6_OFFSET 6 -+#define RTL8367C_DUMMY_7_6_MASK 0xC0 -+#define RTL8367C_NIC_RXMTU_OFFSET 4 -+#define RTL8367C_NIC_RXMTU_MASK 0x30 -+#define RTL8367C_NIC_GCR_DUMMY_0_OFFSET 0 -+#define RTL8367C_NIC_GCR_DUMMY_0_MASK 0x1 -+ -+#define RTL8367C_REG_NIC_MHR0 0x1a24 -+#define RTL8367C_NIC_MHR0_OFFSET 0 -+#define RTL8367C_NIC_MHR0_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_MHR1 0x1a25 -+#define RTL8367C_NIC_MHR1_OFFSET 0 -+#define RTL8367C_NIC_MHR1_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_MHR2 0x1a26 -+#define RTL8367C_NIC_MHR2_OFFSET 0 -+#define RTL8367C_NIC_MHR2_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_MHR3 0x1a27 -+#define RTL8367C_NIC_MHR3_OFFSET 0 -+#define RTL8367C_NIC_MHR3_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_MHR4 0x1a28 -+#define RTL8367C_NIC_MHR4_OFFSET 0 -+#define RTL8367C_NIC_MHR4_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_MHR5 0x1a29 -+#define RTL8367C_NIC_MHR5_OFFSET 0 -+#define RTL8367C_NIC_MHR5_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_MHR6 0x1a2a -+#define RTL8367C_NIC_MHR6_OFFSET 0 -+#define RTL8367C_NIC_MHR6_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_MHR7 0x1a2b -+#define RTL8367C_NIC_MHR7_OFFSET 0 -+#define RTL8367C_NIC_MHR7_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_PAHR0 0x1a2c -+#define RTL8367C_NIC_PAHR0_OFFSET 0 -+#define RTL8367C_NIC_PAHR0_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_PAHR1 0x1a2d -+#define RTL8367C_NIC_PAHR1_OFFSET 0 -+#define RTL8367C_NIC_PAHR1_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_PAHR2 0x1a2e -+#define RTL8367C_NIC_PAHR2_OFFSET 0 -+#define RTL8367C_NIC_PAHR2_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_PAHR3 0x1a2f -+#define RTL8367C_NIC_PAHR3_OFFSET 0 -+#define RTL8367C_NIC_PAHR3_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_PAHR4 0x1a30 -+#define RTL8367C_NIC_PAHR4_OFFSET 0 -+#define RTL8367C_NIC_PAHR4_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_PAHR5 0x1a31 -+#define RTL8367C_NIC_PAHR5_OFFSET 0 -+#define RTL8367C_NIC_PAHR5_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_PAHR6 0x1a32 -+#define RTL8367C_NIC_PAHR6_OFFSET 0 -+#define RTL8367C_NIC_PAHR6_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_PAHR7 0x1a33 -+#define RTL8367C_NIC_PAHR7_OFFSET 0 -+#define RTL8367C_NIC_PAHR7_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_TXSTOPRL 0x1a44 -+#define RTL8367C_NIC_TXSTOPRL_OFFSET 0 -+#define RTL8367C_NIC_TXSTOPRL_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_TXSTOPRH 0x1a45 -+#define RTL8367C_NIC_TXSTOPRH_OFFSET 0 -+#define RTL8367C_NIC_TXSTOPRH_MASK 0x3 -+ -+#define RTL8367C_REG_NIC_RXSTOPRL 0x1a46 -+#define RTL8367C_NIC_RXSTOPRL_OFFSET 0 -+#define RTL8367C_NIC_RXSTOPRL_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_RXSTOPRH 0x1a47 -+#define RTL8367C_NIC_RXSTOPRH_OFFSET 0 -+#define RTL8367C_NIC_RXSTOPRH_MASK 0x3 -+ -+#define RTL8367C_REG_NIC_RXFSTR 0x1a48 -+#define RTL8367C_NIC_RXFSTR_OFFSET 0 -+#define RTL8367C_NIC_RXFSTR_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_RXMBTRL 0x1a4c -+#define RTL8367C_NIC_RXMBTRL_OFFSET 0 -+#define RTL8367C_NIC_RXMBTRL_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_RXMBTRH 0x1a4d -+#define RTL8367C_NIC_RXMBTRH_OFFSET 0 -+#define RTL8367C_NIC_RXMBTRH_MASK 0x7F -+ -+#define RTL8367C_REG_NIC_RXMPTR 0x1a4e -+#define RTL8367C_NIC_RXMPTR_OFFSET 0 -+#define RTL8367C_NIC_RXMPTR_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_T0TR 0x1a4f -+#define RTL8367C_NIC_T0TR_OFFSET 0 -+#define RTL8367C_NIC_T0TR_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_CRXCPRL 0x1a50 -+#define RTL8367C_NIC_CRXCPRL_OFFSET 0 -+#define RTL8367C_NIC_CRXCPRL_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_CRXCPRH 0x1a51 -+#define RTL8367C_NIC_CRXCPRH_OFFSET 0 -+#define RTL8367C_NIC_CRXCPRH_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_CTXCPRL 0x1a52 -+#define RTL8367C_NIC_CTXCPRL_OFFSET 0 -+#define RTL8367C_NIC_CTXCPRL_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_CTXPCRH 0x1a53 -+#define RTL8367C_NIC_CTXPCRH_OFFSET 0 -+#define RTL8367C_NIC_CTXPCRH_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_SRXCURPKTRL 0x1a54 -+#define RTL8367C_NIC_SRXCURPKTRL_OFFSET 0 -+#define RTL8367C_NIC_SRXCURPKTRL_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_SRXCURPKTRH 0x1a55 -+#define RTL8367C_NIC_SRXCURPKTRH_OFFSET 0 -+#define RTL8367C_NIC_SRXCURPKTRH_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_STXCURPKTRL 0x1a56 -+#define RTL8367C_NIC_STXCURPKTRL_OFFSET 0 -+#define RTL8367C_NIC_STXCURPKTRL_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_STXCURPKTRH 0x1a57 -+#define RTL8367C_NIC_STXCURPKTRH_OFFSET 0 -+#define RTL8367C_NIC_STXCURPKTRH_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_STXPKTLENRL 0x1a58 -+#define RTL8367C_NIC_STXPKTLENRL_OFFSET 0 -+#define RTL8367C_NIC_STXPKTLENRL_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_STXPKTLENRH 0x1a59 -+#define RTL8367C_NIC_STXPKTLENRH_OFFSET 0 -+#define RTL8367C_NIC_STXPKTLENRH_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_STXCURUNITRL 0x1a5a -+#define RTL8367C_NIC_STXCURUNITRL_OFFSET 0 -+#define RTL8367C_NIC_STXCURUNITRL_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_STXCURUNITRH 0x1a5b -+#define RTL8367C_NIC_STXCURUNITRH_OFFSET 0 -+#define RTL8367C_NIC_STXCURUNITRH_MASK 0xFF -+ -+#define RTL8367C_REG_NIC_DROP_MODE 0x1a5c -+#define RTL8367C_NIC_RXDV_MODE_OFFSET 1 -+#define RTL8367C_NIC_RXDV_MODE_MASK 0x2 -+#define RTL8367C_NIC_DROP_MODE_OFFSET 0 -+#define RTL8367C_NIC_DROP_MODE_MASK 0x1 -+ -+/* (16'h1b00)LED */ -+ -+#define RTL8367C_REG_LED_SYS_CONFIG 0x1b00 -+#define RTL8367C_LED_SYS_CONFIG_DUMMY_15_OFFSET 15 -+#define RTL8367C_LED_SYS_CONFIG_DUMMY_15_MASK 0x8000 -+#define RTL8367C_LED_SERIAL_OUT_MODE_OFFSET 14 -+#define RTL8367C_LED_SERIAL_OUT_MODE_MASK 0x4000 -+#define RTL8367C_LED_EEE_LPI_MODE_OFFSET 13 -+#define RTL8367C_LED_EEE_LPI_MODE_MASK 0x2000 -+#define RTL8367C_LED_EEE_LPI_EN_OFFSET 12 -+#define RTL8367C_LED_EEE_LPI_EN_MASK 0x1000 -+#define RTL8367C_LED_EEE_LPI_10_OFFSET 11 -+#define RTL8367C_LED_EEE_LPI_10_MASK 0x800 -+#define RTL8367C_LED_EEE_CAP_10_OFFSET 10 -+#define RTL8367C_LED_EEE_CAP_10_MASK 0x400 -+#define RTL8367C_LED_LPI_SEL_OFFSET 8 -+#define RTL8367C_LED_LPI_SEL_MASK 0x300 -+#define RTL8367C_SERI_LED_ACT_LOW_OFFSET 7 -+#define RTL8367C_SERI_LED_ACT_LOW_MASK 0x80 -+#define RTL8367C_LED_POWERON_2_OFFSET 6 -+#define RTL8367C_LED_POWERON_2_MASK 0x40 -+#define RTL8367C_LED_POWERON_1_OFFSET 5 -+#define RTL8367C_LED_POWERON_1_MASK 0x20 -+#define RTL8367C_LED_POWERON_0_OFFSET 4 -+#define RTL8367C_LED_POWERON_0_MASK 0x10 -+#define RTL8367C_LED_IO_DISABLE_OFFSET 3 -+#define RTL8367C_LED_IO_DISABLE_MASK 0x8 -+#define RTL8367C_DUMMY_2_2_OFFSET 2 -+#define RTL8367C_DUMMY_2_2_MASK 0x4 -+#define RTL8367C_LED_SELECT_OFFSET 0 -+#define RTL8367C_LED_SELECT_MASK 0x3 -+ -+#define RTL8367C_REG_LED_SYS_CONFIG2 0x1b01 -+#define RTL8367C_LED_SYS_CONFIG2_DUMMY_OFFSET 2 -+#define RTL8367C_LED_SYS_CONFIG2_DUMMY_MASK 0xFFFC -+#define RTL8367C_GATE_LPTD_BYPASS_OFFSET 1 -+#define RTL8367C_GATE_LPTD_BYPASS_MASK 0x2 -+#define RTL8367C_LED_SPD_MODE_OFFSET 0 -+#define RTL8367C_LED_SPD_MODE_MASK 0x1 -+ -+#define RTL8367C_REG_LED_MODE 0x1b02 -+#define RTL8367C_DLINK_TIME_OFFSET 15 -+#define RTL8367C_DLINK_TIME_MASK 0x8000 -+#define RTL8367C_LED_BUZZ_DUTY_OFFSET 14 -+#define RTL8367C_LED_BUZZ_DUTY_MASK 0x4000 -+#define RTL8367C_BUZZER_RATE_OFFSET 12 -+#define RTL8367C_BUZZER_RATE_MASK 0x3000 -+#define RTL8367C_LOOP_DETECT_MODE_OFFSET 11 -+#define RTL8367C_LOOP_DETECT_MODE_MASK 0x800 -+#define RTL8367C_SEL_PWRON_TIME_OFFSET 9 -+#define RTL8367C_SEL_PWRON_TIME_MASK 0x600 -+#define RTL8367C_EN_DLINK_LED_OFFSET 8 -+#define RTL8367C_EN_DLINK_LED_MASK 0x100 -+#define RTL8367C_LOOP_DETECT_RATE_OFFSET 6 -+#define RTL8367C_LOOP_DETECT_RATE_MASK 0xC0 -+#define RTL8367C_FORCE_RATE_OFFSET 4 -+#define RTL8367C_FORCE_RATE_MASK 0x30 -+#define RTL8367C_SEL_LEDRATE_OFFSET 1 -+#define RTL8367C_SEL_LEDRATE_MASK 0xE -+#define RTL8367C_SPEED_UP_OFFSET 0 -+#define RTL8367C_SPEED_UP_MASK 0x1 -+ -+#define RTL8367C_REG_LED_CONFIGURATION 0x1b03 -+#define RTL8367C_LED_CONFIGURATION_DUMMY_OFFSET 15 -+#define RTL8367C_LED_CONFIGURATION_DUMMY_MASK 0x8000 -+#define RTL8367C_LED_CONFIG_SEL_OFFSET 14 -+#define RTL8367C_LED_CONFIG_SEL_MASK 0x4000 -+#define RTL8367C_DATA_LED_OFFSET 12 -+#define RTL8367C_DATA_LED_MASK 0x3000 -+#define RTL8367C_LED2_CFG_OFFSET 8 -+#define RTL8367C_LED2_CFG_MASK 0xF00 -+#define RTL8367C_LED1_CFG_OFFSET 4 -+#define RTL8367C_LED1_CFG_MASK 0xF0 -+#define RTL8367C_LED0_CFG_OFFSET 0 -+#define RTL8367C_LED0_CFG_MASK 0xF -+ -+#define RTL8367C_REG_RTCT_RESULTS_CFG 0x1b04 -+#define RTL8367C_RTCT_2PAIR_FTT_OFFSET 15 -+#define RTL8367C_RTCT_2PAIR_FTT_MASK 0x8000 -+#define RTL8367C_RTCT_2PAIR_MODE_OFFSET 14 -+#define RTL8367C_RTCT_2PAIR_MODE_MASK 0x4000 -+#define RTL8367C_BLINK_EN_OFFSET 13 -+#define RTL8367C_BLINK_EN_MASK 0x2000 -+#define RTL8367C_TIMEOUT_OFFSET 12 -+#define RTL8367C_TIMEOUT_MASK 0x1000 -+#define RTL8367C_EN_CD_SAME_SHORT_OFFSET 11 -+#define RTL8367C_EN_CD_SAME_SHORT_MASK 0x800 -+#define RTL8367C_EN_CD_SAME_OPEN_OFFSET 10 -+#define RTL8367C_EN_CD_SAME_OPEN_MASK 0x400 -+#define RTL8367C_EN_CD_SAME_LINEDRIVER_OFFSET 9 -+#define RTL8367C_EN_CD_SAME_LINEDRIVER_MASK 0x200 -+#define RTL8367C_EN_CD_SAME_MISMATCH_OFFSET 8 -+#define RTL8367C_EN_CD_SAME_MISMATCH_MASK 0x100 -+#define RTL8367C_EN_CD_SHORT_OFFSET 7 -+#define RTL8367C_EN_CD_SHORT_MASK 0x80 -+#define RTL8367C_EN_AB_SHORT_OFFSET 6 -+#define RTL8367C_EN_AB_SHORT_MASK 0x40 -+#define RTL8367C_EN_CD_OPEN_OFFSET 5 -+#define RTL8367C_EN_CD_OPEN_MASK 0x20 -+#define RTL8367C_EN_AB_OPEN_OFFSET 4 -+#define RTL8367C_EN_AB_OPEN_MASK 0x10 -+#define RTL8367C_EN_CD_MISMATCH_OFFSET 3 -+#define RTL8367C_EN_CD_MISMATCH_MASK 0x8 -+#define RTL8367C_EN_AB_MISMATCH_OFFSET 2 -+#define RTL8367C_EN_AB_MISMATCH_MASK 0x4 -+#define RTL8367C_EN_CD_LINEDRIVER_OFFSET 1 -+#define RTL8367C_EN_CD_LINEDRIVER_MASK 0x2 -+#define RTL8367C_EN_AB_LINEDRIVER_OFFSET 0 -+#define RTL8367C_EN_AB_LINEDRIVER_MASK 0x1 -+ -+#define RTL8367C_REG_RTCT_LED 0x1b05 -+#define RTL8367C_DUMMY_1b05a_OFFSET 12 -+#define RTL8367C_DUMMY_1b05a_MASK 0xF000 -+#define RTL8367C_RTCT_LED2_OFFSET 8 -+#define RTL8367C_RTCT_LED2_MASK 0xF00 -+#define RTL8367C_RTCT_LED1_OFFSET 4 -+#define RTL8367C_RTCT_LED1_MASK 0xF0 -+#define RTL8367C_RTCT_LED0_OFFSET 0 -+#define RTL8367C_RTCT_LED0_MASK 0xF -+ -+#define RTL8367C_REG_CPU_FORCE_LED_CFG 0x1b07 -+#define RTL8367C_DUMMY_1b07a_OFFSET 8 -+#define RTL8367C_DUMMY_1b07a_MASK 0xFF00 -+#define RTL8367C_LED_FORCE_MODE_OFFSET 2 -+#define RTL8367C_LED_FORCE_MODE_MASK 0xFC -+#define RTL8367C_FORCE_MODE_OFFSET 0 -+#define RTL8367C_FORCE_MODE_MASK 0x3 -+ -+#define RTL8367C_REG_CPU_FORCE_LED0_CFG0 0x1b08 -+#define RTL8367C_PORT7_LED0_MODE_OFFSET 14 -+#define RTL8367C_PORT7_LED0_MODE_MASK 0xC000 -+#define RTL8367C_PORT6_LED0_MODE_OFFSET 12 -+#define RTL8367C_PORT6_LED0_MODE_MASK 0x3000 -+#define RTL8367C_PORT5_LED0_MODE_OFFSET 10 -+#define RTL8367C_PORT5_LED0_MODE_MASK 0xC00 -+#define RTL8367C_PORT4_LED0_MODE_OFFSET 8 -+#define RTL8367C_PORT4_LED0_MODE_MASK 0x300 -+#define RTL8367C_PORT3_LED0_MODE_OFFSET 6 -+#define RTL8367C_PORT3_LED0_MODE_MASK 0xC0 -+#define RTL8367C_PORT2_LED0_MODE_OFFSET 4 -+#define RTL8367C_PORT2_LED0_MODE_MASK 0x30 -+#define RTL8367C_PORT1_LED0_MODE_OFFSET 2 -+#define RTL8367C_PORT1_LED0_MODE_MASK 0xC -+#define RTL8367C_PORT0_LED0_MODE_OFFSET 0 -+#define RTL8367C_PORT0_LED0_MODE_MASK 0x3 -+ -+#define RTL8367C_REG_CPU_FORCE_LED0_CFG1 0x1b09 -+#define RTL8367C_DUMMY_1b09a_OFFSET 4 -+#define RTL8367C_DUMMY_1b09a_MASK 0xFFF0 -+#define RTL8367C_PORT9_LED0_MODE_OFFSET 2 -+#define RTL8367C_PORT9_LED0_MODE_MASK 0xC -+#define RTL8367C_PORT8_LED0_MODE_OFFSET 0 -+#define RTL8367C_PORT8_LED0_MODE_MASK 0x3 -+ -+#define RTL8367C_REG_CPU_FORCE_LED1_CFG0 0x1b0a -+#define RTL8367C_PORT7_LED1_MODE_OFFSET 14 -+#define RTL8367C_PORT7_LED1_MODE_MASK 0xC000 -+#define RTL8367C_PORT6_LED1_MODE_OFFSET 12 -+#define RTL8367C_PORT6_LED1_MODE_MASK 0x3000 -+#define RTL8367C_PORT5_LED1_MODE_OFFSET 10 -+#define RTL8367C_PORT5_LED1_MODE_MASK 0xC00 -+#define RTL8367C_PORT4_LED1_MODE_OFFSET 8 -+#define RTL8367C_PORT4_LED1_MODE_MASK 0x300 -+#define RTL8367C_PORT3_LED1_MODE_OFFSET 6 -+#define RTL8367C_PORT3_LED1_MODE_MASK 0xC0 -+#define RTL8367C_PORT2_LED1_MODE_OFFSET 4 -+#define RTL8367C_PORT2_LED1_MODE_MASK 0x30 -+#define RTL8367C_PORT1_LED1_MODE_OFFSET 2 -+#define RTL8367C_PORT1_LED1_MODE_MASK 0xC -+#define RTL8367C_PORT0_LED1_MODE_OFFSET 0 -+#define RTL8367C_PORT0_LED1_MODE_MASK 0x3 -+ -+#define RTL8367C_REG_CPU_FORCE_LED1_CFG1 0x1b0b -+#define RTL8367C_DUMMY_1b0ba_OFFSET 4 -+#define RTL8367C_DUMMY_1b0ba_MASK 0xFFF0 -+#define RTL8367C_PORT9_LED1_MODE_OFFSET 2 -+#define RTL8367C_PORT9_LED1_MODE_MASK 0xC -+#define RTL8367C_PORT8_LED1_MODE_OFFSET 0 -+#define RTL8367C_PORT8_LED1_MODE_MASK 0x3 -+ -+#define RTL8367C_REG_CPU_FORCE_LED2_CFG0 0x1b0c -+#define RTL8367C_PORT7_LED2_MODE_OFFSET 14 -+#define RTL8367C_PORT7_LED2_MODE_MASK 0xC000 -+#define RTL8367C_PORT6_LED2_MODE_OFFSET 12 -+#define RTL8367C_PORT6_LED2_MODE_MASK 0x3000 -+#define RTL8367C_PORT5_LED2_MODE_OFFSET 10 -+#define RTL8367C_PORT5_LED2_MODE_MASK 0xC00 -+#define RTL8367C_PORT4_LED2_MODE_OFFSET 8 -+#define RTL8367C_PORT4_LED2_MODE_MASK 0x300 -+#define RTL8367C_PORT3_LED2_MODE_OFFSET 6 -+#define RTL8367C_PORT3_LED2_MODE_MASK 0xC0 -+#define RTL8367C_PORT2_LED2_MODE_OFFSET 4 -+#define RTL8367C_PORT2_LED2_MODE_MASK 0x30 -+#define RTL8367C_PORT1_LED2_MODE_OFFSET 2 -+#define RTL8367C_PORT1_LED2_MODE_MASK 0xC -+#define RTL8367C_PORT0_LED2_MODE_OFFSET 0 -+#define RTL8367C_PORT0_LED2_MODE_MASK 0x3 -+ -+#define RTL8367C_REG_CPU_FORCE_LED2_CFG1 0x1b0d -+#define RTL8367C_DUMMY_1b0da_OFFSET 4 -+#define RTL8367C_DUMMY_1b0da_MASK 0xFFF0 -+#define RTL8367C_PORT9_LED2_MODE_OFFSET 2 -+#define RTL8367C_PORT9_LED2_MODE_MASK 0xC -+#define RTL8367C_PORT8_LED2_MODE_OFFSET 0 -+#define RTL8367C_PORT8_LED2_MODE_MASK 0x3 -+ -+#define RTL8367C_REG_LED_ACTIVE_LOW_CFG0 0x1b0e -+#define RTL8367C_LED_ACTIVE_LOW_CFG0_DUMMY_15_OFFSET 15 -+#define RTL8367C_LED_ACTIVE_LOW_CFG0_DUMMY_15_MASK 0x8000 -+#define RTL8367C_PORT3_LED_ACTIVE_LOW_OFFSET 12 -+#define RTL8367C_PORT3_LED_ACTIVE_LOW_MASK 0x7000 -+#define RTL8367C_LED_ACTIVE_LOW_CFG0_DUMMY_11_OFFSET 11 -+#define RTL8367C_LED_ACTIVE_LOW_CFG0_DUMMY_11_MASK 0x800 -+#define RTL8367C_PORT2_LED_ACTIVE_LOW_OFFSET 8 -+#define RTL8367C_PORT2_LED_ACTIVE_LOW_MASK 0x700 -+#define RTL8367C_DUMMY_7_OFFSET 7 -+#define RTL8367C_DUMMY_7_MASK 0x80 -+#define RTL8367C_PORT1_LED_ACTIVE_LOW_OFFSET 4 -+#define RTL8367C_PORT1_LED_ACTIVE_LOW_MASK 0x70 -+#define RTL8367C_DUMMY_3_OFFSET 3 -+#define RTL8367C_DUMMY_3_MASK 0x8 -+#define RTL8367C_PORT0_LED_ACTIVE_LOW_OFFSET 0 -+#define RTL8367C_PORT0_LED_ACTIVE_LOW_MASK 0x7 -+ -+#define RTL8367C_REG_LED_ACTIVE_LOW_CFG1 0x1b0f -+#define RTL8367C_LED_ACTIVE_LOW_CFG1_DUMMY_15_OFFSET 15 -+#define RTL8367C_LED_ACTIVE_LOW_CFG1_DUMMY_15_MASK 0x8000 -+#define RTL8367C_PORT7_LED_ACTIVE_LOW_OFFSET 12 -+#define RTL8367C_PORT7_LED_ACTIVE_LOW_MASK 0x7000 -+#define RTL8367C_LED_ACTIVE_LOW_CFG1_DUMMY_11_OFFSET 11 -+#define RTL8367C_LED_ACTIVE_LOW_CFG1_DUMMY_11_MASK 0x800 -+#define RTL8367C_PORT6_LED_ACTIVE_LOW_OFFSET 8 -+#define RTL8367C_PORT6_LED_ACTIVE_LOW_MASK 0x700 -+#define RTL8367C_DUMMY_1b0f_b_OFFSET 7 -+#define RTL8367C_DUMMY_1b0f_b_MASK 0x80 -+#define RTL8367C_PORT5_LED_ACTIVE_LOW_OFFSET 4 -+#define RTL8367C_PORT5_LED_ACTIVE_LOW_MASK 0x70 -+#define RTL8367C_DUMMY_1b0f_a_OFFSET 3 -+#define RTL8367C_DUMMY_1b0f_a_MASK 0x8 -+#define RTL8367C_PORT4_LED_ACTIVE_LOW_OFFSET 0 -+#define RTL8367C_PORT4_LED_ACTIVE_LOW_MASK 0x7 -+ -+#define RTL8367C_REG_LED_ACTIVE_LOW_CFG2 0x1b10 -+#define RTL8367C_DUMMY_1b10_b_OFFSET 7 -+#define RTL8367C_DUMMY_1b10_b_MASK 0xFF80 -+#define RTL8367C_PORT9_LED_ACTIVE_LOW_OFFSET 4 -+#define RTL8367C_PORT9_LED_ACTIVE_LOW_MASK 0x70 -+#define RTL8367C_DUMMY_1b10_a_OFFSET 3 -+#define RTL8367C_DUMMY_1b10_a_MASK 0x8 -+#define RTL8367C_PORT8_LED_ACTIVE_LOW_OFFSET 0 -+#define RTL8367C_PORT8_LED_ACTIVE_LOW_MASK 0x7 -+ -+#define RTL8367C_REG_SEL_RTCT_PARA 0x1b21 -+#define RTL8367C_DO_RTCT_COMMAND_OFFSET 15 -+#define RTL8367C_DO_RTCT_COMMAND_MASK 0x8000 -+#define RTL8367C_SEL_RTCT_PARA_DUMMY_OFFSET 12 -+#define RTL8367C_SEL_RTCT_PARA_DUMMY_MASK 0x7000 -+#define RTL8367C_SEL_RTCT_RLSTLED_TIME_OFFSET 10 -+#define RTL8367C_SEL_RTCT_RLSTLED_TIME_MASK 0xC00 -+#define RTL8367C_SEL_RTCT_TEST_LED_TIME_OFFSET 8 -+#define RTL8367C_SEL_RTCT_TEST_LED_TIME_MASK 0x300 -+#define RTL8367C_EN_SCAN_RTCT_OFFSET 7 -+#define RTL8367C_EN_SCAN_RTCT_MASK 0x80 -+#define RTL8367C_EN_RTCT_TIMOUT_OFFSET 6 -+#define RTL8367C_EN_RTCT_TIMOUT_MASK 0x40 -+#define RTL8367C_EN_ALL_RTCT_OFFSET 5 -+#define RTL8367C_EN_ALL_RTCT_MASK 0x20 -+#define RTL8367C_SEL_RTCT_PLE_WID_OFFSET 0 -+#define RTL8367C_SEL_RTCT_PLE_WID_MASK 0x1F -+ -+#define RTL8367C_REG_RTCT_ENABLE 0x1b22 -+#define RTL8367C_RTCT_ENABLE_DUMMY_OFFSET 8 -+#define RTL8367C_RTCT_ENABLE_DUMMY_MASK 0xFF00 -+#define RTL8367C_RTCT_ENABLE_PORT_MASK_OFFSET 0 -+#define RTL8367C_RTCT_ENABLE_PORT_MASK_MASK 0xFF -+ -+#define RTL8367C_REG_RTCT_TIMEOUT 0x1b23 -+ -+#define RTL8367C_REG_PARA_LED_IO_EN1 0x1b24 -+#define RTL8367C_LED1_PARA_P07_00_OFFSET 8 -+#define RTL8367C_LED1_PARA_P07_00_MASK 0xFF00 -+#define RTL8367C_LED0_PARA_P07_00_OFFSET 0 -+#define RTL8367C_LED0_PARA_P07_00_MASK 0xFF -+ -+#define RTL8367C_REG_PARA_LED_IO_EN2 0x1b25 -+#define RTL8367C_DUMMY_15_8_OFFSET 8 -+#define RTL8367C_DUMMY_15_8_MASK 0xFF00 -+#define RTL8367C_LED2_PARA_P07_00_OFFSET 0 -+#define RTL8367C_LED2_PARA_P07_00_MASK 0xFF -+ -+#define RTL8367C_REG_SCAN0_LED_IO_EN1 0x1b26 -+#define RTL8367C_SCAN0_LED_IO_EN1_DUMMY_OFFSET 3 -+#define RTL8367C_SCAN0_LED_IO_EN1_DUMMY_MASK 0xFFF8 -+#define RTL8367C_LED_LOOP_DET_BUZZER_EN_OFFSET 2 -+#define RTL8367C_LED_LOOP_DET_BUZZER_EN_MASK 0x4 -+#define RTL8367C_LED_SERI_DATA_EN_OFFSET 1 -+#define RTL8367C_LED_SERI_DATA_EN_MASK 0x2 -+#define RTL8367C_LED_SERI_CLK_EN_OFFSET 0 -+#define RTL8367C_LED_SERI_CLK_EN_MASK 0x1 -+ -+#define RTL8367C_REG_SCAN1_LED_IO_EN2 0x1b27 -+#define RTL8367C_LED_SCAN1_BI_PORT_EN_OFFSET 8 -+#define RTL8367C_LED_SCAN1_BI_PORT_EN_MASK 0xFF00 -+#define RTL8367C_LED_SCAN1_BI_STA_EN_OFFSET 7 -+#define RTL8367C_LED_SCAN1_BI_STA_EN_MASK 0x80 -+#define RTL8367C_SCAN1_LED_IO_EN2_DUMMY_0_OFFSET 6 -+#define RTL8367C_SCAN1_LED_IO_EN2_DUMMY_0_MASK 0x40 -+#define RTL8367C_LED_SCAN1_SI_PORT_EN_OFFSET 2 -+#define RTL8367C_LED_SCAN1_SI_PORT_EN_MASK 0x3C -+#define RTL8367C_LED_SCAN1_SI_STA_EN_OFFSET 0 -+#define RTL8367C_LED_SCAN1_SI_STA_EN_MASK 0x3 -+ -+#define RTL8367C_REG_LPI_LED_OPT1 0x1b28 -+#define RTL8367C_LPI_TAG4_OFFSET 12 -+#define RTL8367C_LPI_TAG4_MASK 0xF000 -+#define RTL8367C_LPI_TAG3_OFFSET 8 -+#define RTL8367C_LPI_TAG3_MASK 0xF00 -+#define RTL8367C_LPI_TAG2_OFFSET 4 -+#define RTL8367C_LPI_TAG2_MASK 0xF0 -+#define RTL8367C_LPI_TAG1_OFFSET 0 -+#define RTL8367C_LPI_TAG1_MASK 0xF -+ -+#define RTL8367C_REG_LPI_LED_OPT2 0x1b29 -+#define RTL8367C_LPI_LED_OPT2_DUMMY_OFFSET 15 -+#define RTL8367C_LPI_LED_OPT2_DUMMY_MASK 0x8000 -+#define RTL8367C_LPI_LED2_WEAK_OFFSET 14 -+#define RTL8367C_LPI_LED2_WEAK_MASK 0x4000 -+#define RTL8367C_LPI_LED1_WEAK_OFFSET 13 -+#define RTL8367C_LPI_LED1_WEAK_MASK 0x2000 -+#define RTL8367C_LPI_LED0_WEAK_OFFSET 12 -+#define RTL8367C_LPI_LED0_WEAK_MASK 0x1000 -+#define RTL8367C_LPI_LED2_OFFSET 11 -+#define RTL8367C_LPI_LED2_MASK 0x800 -+#define RTL8367C_LPI_LED1_OFFSET 10 -+#define RTL8367C_LPI_LED1_MASK 0x400 -+#define RTL8367C_LPI_LED0_OFFSET 9 -+#define RTL8367C_LPI_LED0_MASK 0x200 -+#define RTL8367C_LPI_TAG8_OFFSET 8 -+#define RTL8367C_LPI_TAG8_MASK 0x100 -+#define RTL8367C_LPI_TAG7_OFFSET 6 -+#define RTL8367C_LPI_TAG7_MASK 0xC0 -+#define RTL8367C_LPI_TAG6_OFFSET 4 -+#define RTL8367C_LPI_TAG6_MASK 0x30 -+#define RTL8367C_LPI_TAG5_OFFSET 0 -+#define RTL8367C_LPI_TAG5_MASK 0xF -+ -+#define RTL8367C_REG_LPI_LED_OPT3 0x1b2a -+#define RTL8367C_LPI_LED_OPT3_DUMMY_OFFSET 3 -+#define RTL8367C_LPI_LED_OPT3_DUMMY_MASK 0xFFF8 -+#define RTL8367C_RESTORE_LED_RATE_SEL_OFFSET 1 -+#define RTL8367C_RESTORE_LED_RATE_SEL_MASK 0x6 -+#define RTL8367C_RESTORE_LED_SEL_OFFSET 0 -+#define RTL8367C_RESTORE_LED_SEL_MASK 0x1 -+ -+#define RTL8367C_REG_P0_LED_MUX 0x1b2b -+#define RTL8367C_CFG_P0_LED2_MUX_OFFSET 10 -+#define RTL8367C_CFG_P0_LED2_MUX_MASK 0x7C00 -+#define RTL8367C_CFG_P0_LED1_MUX_OFFSET 5 -+#define RTL8367C_CFG_P0_LED1_MUX_MASK 0x3E0 -+#define RTL8367C_CFG_P0_LED0_MUX_OFFSET 0 -+#define RTL8367C_CFG_P0_LED0_MUX_MASK 0x1F -+ -+#define RTL8367C_REG_P1_LED_MUX 0x1b2c -+#define RTL8367C_CFG_P1_LED2_MUX_OFFSET 10 -+#define RTL8367C_CFG_P1_LED2_MUX_MASK 0x7C00 -+#define RTL8367C_CFG_P1_LED1_MUX_OFFSET 5 -+#define RTL8367C_CFG_P1_LED1_MUX_MASK 0x3E0 -+#define RTL8367C_CFG_P1_LED0_MUX_OFFSET 0 -+#define RTL8367C_CFG_P1_LED0_MUX_MASK 0x1F -+ -+#define RTL8367C_REG_P2_LED_MUX 0x1b2d -+#define RTL8367C_CFG_P2_LED2_MUX_OFFSET 10 -+#define RTL8367C_CFG_P2_LED2_MUX_MASK 0x7C00 -+#define RTL8367C_CFG_P2_LED1_MUX_OFFSET 5 -+#define RTL8367C_CFG_P2_LED1_MUX_MASK 0x3E0 -+#define RTL8367C_CFG_P2_LED0_MUX_OFFSET 0 -+#define RTL8367C_CFG_P2_LED0_MUX_MASK 0x1F -+ -+#define RTL8367C_REG_P3_LED_MUX 0x1b2e -+#define RTL8367C_CFG_P3_LED2_MUX_OFFSET 10 -+#define RTL8367C_CFG_P3_LED2_MUX_MASK 0x7C00 -+#define RTL8367C_CFG_P3_LED1_MUX_OFFSET 5 -+#define RTL8367C_CFG_P3_LED1_MUX_MASK 0x3E0 -+#define RTL8367C_CFG_P3_LED0_MUX_OFFSET 0 -+#define RTL8367C_CFG_P3_LED0_MUX_MASK 0x1F -+ -+#define RTL8367C_REG_P4_LED_MUX 0x1b2f -+#define RTL8367C_CFG_P4_LED2_MUX_OFFSET 10 -+#define RTL8367C_CFG_P4_LED2_MUX_MASK 0x7C00 -+#define RTL8367C_CFG_P4_LED1_MUX_OFFSET 5 -+#define RTL8367C_CFG_P4_LED1_MUX_MASK 0x3E0 -+#define RTL8367C_CFG_P4_LED0_MUX_OFFSET 0 -+#define RTL8367C_CFG_P4_LED0_MUX_MASK 0x1F -+ -+#define RTL8367C_REG_LED0_DATA_CTRL 0x1b30 -+#define RTL8367C_CFG_DATA_LED0_SEL_OFFSET 6 -+#define RTL8367C_CFG_DATA_LED0_SEL_MASK 0x40 -+#define RTL8367C_CFG_DATA_LED0_ACT_OFFSET 4 -+#define RTL8367C_CFG_DATA_LED0_ACT_MASK 0x30 -+#define RTL8367C_CFG_DATA_LED0_SPD_OFFSET 0 -+#define RTL8367C_CFG_DATA_LED0_SPD_MASK 0xF -+ -+#define RTL8367C_REG_LED1_DATA_CTRL 0x1b31 -+#define RTL8367C_CFG_DATA_LED1_SEL_OFFSET 6 -+#define RTL8367C_CFG_DATA_LED1_SEL_MASK 0x40 -+#define RTL8367C_CFG_DATA_LED1_ACT_OFFSET 4 -+#define RTL8367C_CFG_DATA_LED1_ACT_MASK 0x30 -+#define RTL8367C_CFG_DATA_LED1_SPD_OFFSET 0 -+#define RTL8367C_CFG_DATA_LED1_SPD_MASK 0xF -+ -+#define RTL8367C_REG_LED2_DATA_CTRL 0x1b32 -+#define RTL8367C_CFG_DATA_LED2_SEL_OFFSET 6 -+#define RTL8367C_CFG_DATA_LED2_SEL_MASK 0x40 -+#define RTL8367C_CFG_DATA_LED2_ACT_OFFSET 4 -+#define RTL8367C_CFG_DATA_LED2_ACT_MASK 0x30 -+#define RTL8367C_CFG_DATA_LED2_SPD_OFFSET 0 -+#define RTL8367C_CFG_DATA_LED2_SPD_MASK 0xF -+ -+#define RTL8367C_REG_PARA_LED_IO_EN3 0x1b33 -+#define RTL8367C_dummy_1b33a_OFFSET 6 -+#define RTL8367C_dummy_1b33a_MASK 0xFFC0 -+#define RTL8367C_LED2_PARA_P09_08_OFFSET 4 -+#define RTL8367C_LED2_PARA_P09_08_MASK 0x30 -+#define RTL8367C_LED1_PARA_P09_08_OFFSET 2 -+#define RTL8367C_LED1_PARA_P09_08_MASK 0xC -+#define RTL8367C_LED0_PARA_P09_08_OFFSET 0 -+#define RTL8367C_LED0_PARA_P09_08_MASK 0x3 -+ -+#define RTL8367C_REG_SCAN1_LED_IO_EN3 0x1b34 -+#define RTL8367C_dummy_1b34a_OFFSET 3 -+#define RTL8367C_dummy_1b34a_MASK 0xFFF8 -+#define RTL8367C_LED_SCAN1_BI_PORT9_8_EN_OFFSET 1 -+#define RTL8367C_LED_SCAN1_BI_PORT9_8_EN_MASK 0x6 -+#define RTL8367C_LED_SCAN1_SI_PORT9_8_EN_OFFSET 0 -+#define RTL8367C_LED_SCAN1_SI_PORT9_8_EN_MASK 0x1 -+ -+#define RTL8367C_REG_P5_LED_MUX 0x1b35 -+#define RTL8367C_CFG_P5_LED2_MUX_OFFSET 10 -+#define RTL8367C_CFG_P5_LED2_MUX_MASK 0x7C00 -+#define RTL8367C_CFG_P5_LED1_MUX_OFFSET 5 -+#define RTL8367C_CFG_P5_LED1_MUX_MASK 0x3E0 -+#define RTL8367C_CFG_P5_LED0_MUX_OFFSET 0 -+#define RTL8367C_CFG_P5_LED0_MUX_MASK 0x1F -+ -+#define RTL8367C_REG_P6_LED_MUX 0x1b36 -+#define RTL8367C_CFG_P6_LED2_MUX_OFFSET 10 -+#define RTL8367C_CFG_P6_LED2_MUX_MASK 0x7C00 -+#define RTL8367C_CFG_P6_LED1_MUX_OFFSET 5 -+#define RTL8367C_CFG_P6_LED1_MUX_MASK 0x3E0 -+#define RTL8367C_CFG_P6_LED0_MUX_OFFSET 0 -+#define RTL8367C_CFG_P6_LED0_MUX_MASK 0x1F -+ -+#define RTL8367C_REG_P7_LED_MUX 0x1b37 -+#define RTL8367C_CFG_P7_LED2_MUX_OFFSET 10 -+#define RTL8367C_CFG_P7_LED2_MUX_MASK 0x7C00 -+#define RTL8367C_CFG_P7_LED1_MUX_OFFSET 5 -+#define RTL8367C_CFG_P7_LED1_MUX_MASK 0x3E0 -+#define RTL8367C_CFG_P7_LED0_MUX_OFFSET 0 -+#define RTL8367C_CFG_P7_LED0_MUX_MASK 0x1F -+ -+#define RTL8367C_REG_P8_LED_MUX 0x1b38 -+#define RTL8367C_CFG_P8_LED2_MUX_OFFSET 10 -+#define RTL8367C_CFG_P8_LED2_MUX_MASK 0x7C00 -+#define RTL8367C_CFG_P8_LED1_MUX_OFFSET 5 -+#define RTL8367C_CFG_P8_LED1_MUX_MASK 0x3E0 -+#define RTL8367C_CFG_P8_LED0_MUX_OFFSET 0 -+#define RTL8367C_CFG_P8_LED0_MUX_MASK 0x1F -+ -+#define RTL8367C_REG_P9_LED_MUX 0x1b39 -+#define RTL8367C_CFG_P9_LED2_MUX_OFFSET 10 -+#define RTL8367C_CFG_P9_LED2_MUX_MASK 0x7C00 -+#define RTL8367C_CFG_P9_LED1_MUX_OFFSET 5 -+#define RTL8367C_CFG_P9_LED1_MUX_MASK 0x3E0 -+#define RTL8367C_CFG_P9_LED0_MUX_OFFSET 0 -+#define RTL8367C_CFG_P9_LED0_MUX_MASK 0x1F -+ -+#define RTL8367C_REG_SERIAL_LED_CTRL 0x1b3a -+#define RTL8367C_SERIAL_LED_SHIFT_SEQUENCE_OFFSET 13 -+#define RTL8367C_SERIAL_LED_SHIFT_SEQUENCE_MASK 0x6000 -+#define RTL8367C_SERIAL_LED_SHIFT_SEQUENCE_EN_OFFSET 12 -+#define RTL8367C_SERIAL_LED_SHIFT_SEQUENCE_EN_MASK 0x1000 -+#define RTL8367C_SERIAL_LED_GROUP_NUM_OFFSET 10 -+#define RTL8367C_SERIAL_LED_GROUP_NUM_MASK 0xC00 -+#define RTL8367C_SERIAL_LED_PORT_EN_OFFSET 0 -+#define RTL8367C_SERIAL_LED_PORT_EN_MASK 0x3FF -+ -+/* (16'h1c00)IGMP_EAV */ -+ -+#define RTL8367C_REG_IGMP_MLD_CFG0 0x1c00 -+#define RTL8367C_IGMP_MLD_PORTISO_LEAKY_OFFSET 15 -+#define RTL8367C_IGMP_MLD_PORTISO_LEAKY_MASK 0x8000 -+#define RTL8367C_IGMP_MLD_VLAN_LEAKY_OFFSET 14 -+#define RTL8367C_IGMP_MLD_VLAN_LEAKY_MASK 0x4000 -+#define RTL8367C_IGMP_MLD_DISCARD_STORM_FILTER_OFFSET 13 -+#define RTL8367C_IGMP_MLD_DISCARD_STORM_FILTER_MASK 0x2000 -+#define RTL8367C_REPORT_FORWARD_OFFSET 12 -+#define RTL8367C_REPORT_FORWARD_MASK 0x1000 -+#define RTL8367C_ROBUSTNESS_VAR_OFFSET 9 -+#define RTL8367C_ROBUSTNESS_VAR_MASK 0xE00 -+#define RTL8367C_LEAVE_SUPPRESSION_OFFSET 8 -+#define RTL8367C_LEAVE_SUPPRESSION_MASK 0x100 -+#define RTL8367C_REPORT_SUPPRESSION_OFFSET 7 -+#define RTL8367C_REPORT_SUPPRESSION_MASK 0x80 -+#define RTL8367C_LEAVE_TIMER_OFFSET 4 -+#define RTL8367C_LEAVE_TIMER_MASK 0x70 -+#define RTL8367C_FAST_LEAVE_EN_OFFSET 3 -+#define RTL8367C_FAST_LEAVE_EN_MASK 0x8 -+#define RTL8367C_CKS_ERR_OP_OFFSET 1 -+#define RTL8367C_CKS_ERR_OP_MASK 0x6 -+#define RTL8367C_IGMP_MLD_EN_OFFSET 0 -+#define RTL8367C_IGMP_MLD_EN_MASK 0x1 -+ -+#define RTL8367C_REG_IGMP_MLD_CFG1 0x1c01 -+#define RTL8367C_DROP_LEAVE_ZERO_OFFSET 2 -+#define RTL8367C_DROP_LEAVE_ZERO_MASK 0x4 -+#define RTL8367C_TABLE_FULL_OP_OFFSET 0 -+#define RTL8367C_TABLE_FULL_OP_MASK 0x3 -+ -+#define RTL8367C_REG_IGMP_MLD_CFG2 0x1c02 -+ -+#define RTL8367C_REG_IGMP_DYNAMIC_ROUTER_PORT 0x1c03 -+#define RTL8367C_D_ROUTER_PORT_2_OFFSET 11 -+#define RTL8367C_D_ROUTER_PORT_2_MASK 0x7800 -+#define RTL8367C_D_ROUTER_PORT_TMR_2_OFFSET 8 -+#define RTL8367C_D_ROUTER_PORT_TMR_2_MASK 0x700 -+#define RTL8367C_D_ROUTER_PORT_1_OFFSET 3 -+#define RTL8367C_D_ROUTER_PORT_1_MASK 0x78 -+#define RTL8367C_D_ROUTER_PORT_TMR_1_OFFSET 0 -+#define RTL8367C_D_ROUTER_PORT_TMR_1_MASK 0x7 -+ -+#define RTL8367C_REG_IGMP_STATIC_ROUTER_PORT 0x1c04 -+#define RTL8367C_IGMP_STATIC_ROUTER_PORT_OFFSET 0 -+#define RTL8367C_IGMP_STATIC_ROUTER_PORT_MASK 0x7FF -+ -+#define RTL8367C_REG_IGMP_PORT0_CONTROL 0x1c05 -+#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_QUERY_OFFSET 14 -+#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_QUERY_MASK 0x4000 -+#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_REPORT_OFFSET 13 -+#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_REPORT_MASK 0x2000 -+#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_LEAVE_OFFSET 12 -+#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_LEAVE_MASK 0x1000 -+#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MRP_OFFSET 11 -+#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MRP_MASK 0x800 -+#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MC_DATA_OFFSET 10 -+#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MC_DATA_MASK 0x400 -+#define RTL8367C_IGMP_PORT0_CONTROL_MLDv2_OP_OFFSET 8 -+#define RTL8367C_IGMP_PORT0_CONTROL_MLDv2_OP_MASK 0x300 -+#define RTL8367C_IGMP_PORT0_CONTROL_MLDv1_OP_OFFSET 6 -+#define RTL8367C_IGMP_PORT0_CONTROL_MLDv1_OP_MASK 0xC0 -+#define RTL8367C_IGMP_PORT0_CONTROL_IGMPV3_OP_OFFSET 4 -+#define RTL8367C_IGMP_PORT0_CONTROL_IGMPV3_OP_MASK 0x30 -+#define RTL8367C_IGMP_PORT0_CONTROL_IGMPV2_OP_OFFSET 2 -+#define RTL8367C_IGMP_PORT0_CONTROL_IGMPV2_OP_MASK 0xC -+#define RTL8367C_IGMP_PORT0_CONTROL_IGMPV1_OP_OFFSET 0 -+#define RTL8367C_IGMP_PORT0_CONTROL_IGMPV1_OP_MASK 0x3 -+ -+#define RTL8367C_REG_IGMP_PORT1_CONTROL 0x1c06 -+#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_QUERY_OFFSET 14 -+#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_QUERY_MASK 0x4000 -+#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_REPORT_OFFSET 13 -+#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_REPORT_MASK 0x2000 -+#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_LEAVE_OFFSET 12 -+#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_LEAVE_MASK 0x1000 -+#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_MRP_OFFSET 11 -+#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_MRP_MASK 0x800 -+#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_MC_DATA_OFFSET 10 -+#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_MC_DATA_MASK 0x400 -+#define RTL8367C_IGMP_PORT1_CONTROL_MLDv2_OP_OFFSET 8 -+#define RTL8367C_IGMP_PORT1_CONTROL_MLDv2_OP_MASK 0x300 -+#define RTL8367C_IGMP_PORT1_CONTROL_MLDv1_OP_OFFSET 6 -+#define RTL8367C_IGMP_PORT1_CONTROL_MLDv1_OP_MASK 0xC0 -+#define RTL8367C_IGMP_PORT1_CONTROL_IGMPV3_OP_OFFSET 4 -+#define RTL8367C_IGMP_PORT1_CONTROL_IGMPV3_OP_MASK 0x30 -+#define RTL8367C_IGMP_PORT1_CONTROL_IGMPV2_OP_OFFSET 2 -+#define RTL8367C_IGMP_PORT1_CONTROL_IGMPV2_OP_MASK 0xC -+#define RTL8367C_IGMP_PORT1_CONTROL_IGMPV1_OP_OFFSET 0 -+#define RTL8367C_IGMP_PORT1_CONTROL_IGMPV1_OP_MASK 0x3 -+ -+#define RTL8367C_REG_IGMP_PORT2_CONTROL 0x1c07 -+#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_QUERY_OFFSET 14 -+#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_QUERY_MASK 0x4000 -+#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_REPORT_OFFSET 13 -+#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_REPORT_MASK 0x2000 -+#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_LEAVE_OFFSET 12 -+#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_LEAVE_MASK 0x1000 -+#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_MRP_OFFSET 11 -+#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_MRP_MASK 0x800 -+#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_MC_DATA_OFFSET 10 -+#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_MC_DATA_MASK 0x400 -+#define RTL8367C_IGMP_PORT2_CONTROL_MLDv2_OP_OFFSET 8 -+#define RTL8367C_IGMP_PORT2_CONTROL_MLDv2_OP_MASK 0x300 -+#define RTL8367C_IGMP_PORT2_CONTROL_MLDv1_OP_OFFSET 6 -+#define RTL8367C_IGMP_PORT2_CONTROL_MLDv1_OP_MASK 0xC0 -+#define RTL8367C_IGMP_PORT2_CONTROL_IGMPV3_OP_OFFSET 4 -+#define RTL8367C_IGMP_PORT2_CONTROL_IGMPV3_OP_MASK 0x30 -+#define RTL8367C_IGMP_PORT2_CONTROL_IGMPV2_OP_OFFSET 2 -+#define RTL8367C_IGMP_PORT2_CONTROL_IGMPV2_OP_MASK 0xC -+#define RTL8367C_IGMP_PORT2_CONTROL_IGMPV1_OP_OFFSET 0 -+#define RTL8367C_IGMP_PORT2_CONTROL_IGMPV1_OP_MASK 0x3 -+ -+#define RTL8367C_REG_IGMP_PORT3_CONTROL 0x1c08 -+#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_QUERY_OFFSET 14 -+#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_QUERY_MASK 0x4000 -+#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_REPORT_OFFSET 13 -+#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_REPORT_MASK 0x2000 -+#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_LEAVE_OFFSET 12 -+#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_LEAVE_MASK 0x1000 -+#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_MRP_OFFSET 11 -+#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_MRP_MASK 0x800 -+#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_MC_DATA_OFFSET 10 -+#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_MC_DATA_MASK 0x400 -+#define RTL8367C_IGMP_PORT3_CONTROL_MLDv2_OP_OFFSET 8 -+#define RTL8367C_IGMP_PORT3_CONTROL_MLDv2_OP_MASK 0x300 -+#define RTL8367C_IGMP_PORT3_CONTROL_MLDv1_OP_OFFSET 6 -+#define RTL8367C_IGMP_PORT3_CONTROL_MLDv1_OP_MASK 0xC0 -+#define RTL8367C_IGMP_PORT3_CONTROL_IGMPV3_OP_OFFSET 4 -+#define RTL8367C_IGMP_PORT3_CONTROL_IGMPV3_OP_MASK 0x30 -+#define RTL8367C_IGMP_PORT3_CONTROL_IGMPV2_OP_OFFSET 2 -+#define RTL8367C_IGMP_PORT3_CONTROL_IGMPV2_OP_MASK 0xC -+#define RTL8367C_IGMP_PORT3_CONTROL_IGMPV1_OP_OFFSET 0 -+#define RTL8367C_IGMP_PORT3_CONTROL_IGMPV1_OP_MASK 0x3 -+ -+#define RTL8367C_REG_IGMP_PORT4_CONTROL 0x1c09 -+#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_QUERY_OFFSET 14 -+#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_QUERY_MASK 0x4000 -+#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_REPORT_OFFSET 13 -+#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_REPORT_MASK 0x2000 -+#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_LEAVE_OFFSET 12 -+#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_LEAVE_MASK 0x1000 -+#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_MRP_OFFSET 11 -+#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_MRP_MASK 0x800 -+#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_MC_DATA_OFFSET 10 -+#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_MC_DATA_MASK 0x400 -+#define RTL8367C_IGMP_PORT4_CONTROL_MLDv2_OP_OFFSET 8 -+#define RTL8367C_IGMP_PORT4_CONTROL_MLDv2_OP_MASK 0x300 -+#define RTL8367C_IGMP_PORT4_CONTROL_MLDv1_OP_OFFSET 6 -+#define RTL8367C_IGMP_PORT4_CONTROL_MLDv1_OP_MASK 0xC0 -+#define RTL8367C_IGMP_PORT4_CONTROL_IGMPV3_OP_OFFSET 4 -+#define RTL8367C_IGMP_PORT4_CONTROL_IGMPV3_OP_MASK 0x30 -+#define RTL8367C_IGMP_PORT4_CONTROL_IGMPV2_OP_OFFSET 2 -+#define RTL8367C_IGMP_PORT4_CONTROL_IGMPV2_OP_MASK 0xC -+#define RTL8367C_IGMP_PORT4_CONTROL_IGMPV1_OP_OFFSET 0 -+#define RTL8367C_IGMP_PORT4_CONTROL_IGMPV1_OP_MASK 0x3 -+ -+#define RTL8367C_REG_IGMP_PORT5_CONTROL 0x1c0a -+#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_QUERY_OFFSET 14 -+#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_QUERY_MASK 0x4000 -+#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_REPORT_OFFSET 13 -+#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_REPORT_MASK 0x2000 -+#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_LEAVE_OFFSET 12 -+#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_LEAVE_MASK 0x1000 -+#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_MRP_OFFSET 11 -+#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_MRP_MASK 0x800 -+#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_MC_DATA_OFFSET 10 -+#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_MC_DATA_MASK 0x400 -+#define RTL8367C_IGMP_PORT5_CONTROL_MLDv2_OP_OFFSET 8 -+#define RTL8367C_IGMP_PORT5_CONTROL_MLDv2_OP_MASK 0x300 -+#define RTL8367C_IGMP_PORT5_CONTROL_MLDv1_OP_OFFSET 6 -+#define RTL8367C_IGMP_PORT5_CONTROL_MLDv1_OP_MASK 0xC0 -+#define RTL8367C_IGMP_PORT5_CONTROL_IGMPV3_OP_OFFSET 4 -+#define RTL8367C_IGMP_PORT5_CONTROL_IGMPV3_OP_MASK 0x30 -+#define RTL8367C_IGMP_PORT5_CONTROL_IGMPV2_OP_OFFSET 2 -+#define RTL8367C_IGMP_PORT5_CONTROL_IGMPV2_OP_MASK 0xC -+#define RTL8367C_IGMP_PORT5_CONTROL_IGMPV1_OP_OFFSET 0 -+#define RTL8367C_IGMP_PORT5_CONTROL_IGMPV1_OP_MASK 0x3 -+ -+#define RTL8367C_REG_IGMP_PORT6_CONTROL 0x1c0b -+#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_QUERY_OFFSET 14 -+#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_QUERY_MASK 0x4000 -+#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_REPORT_OFFSET 13 -+#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_REPORT_MASK 0x2000 -+#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_LEAVE_OFFSET 12 -+#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_LEAVE_MASK 0x1000 -+#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_MRP_OFFSET 11 -+#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_MRP_MASK 0x800 -+#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_MC_DATA_OFFSET 10 -+#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_MC_DATA_MASK 0x400 -+#define RTL8367C_IGMP_PORT6_CONTROL_MLDv2_OP_OFFSET 8 -+#define RTL8367C_IGMP_PORT6_CONTROL_MLDv2_OP_MASK 0x300 -+#define RTL8367C_IGMP_PORT6_CONTROL_MLDv1_OP_OFFSET 6 -+#define RTL8367C_IGMP_PORT6_CONTROL_MLDv1_OP_MASK 0xC0 -+#define RTL8367C_IGMP_PORT6_CONTROL_IGMPV3_OP_OFFSET 4 -+#define RTL8367C_IGMP_PORT6_CONTROL_IGMPV3_OP_MASK 0x30 -+#define RTL8367C_IGMP_PORT6_CONTROL_IGMPV2_OP_OFFSET 2 -+#define RTL8367C_IGMP_PORT6_CONTROL_IGMPV2_OP_MASK 0xC -+#define RTL8367C_IGMP_PORT6_CONTROL_IGMPV1_OP_OFFSET 0 -+#define RTL8367C_IGMP_PORT6_CONTROL_IGMPV1_OP_MASK 0x3 -+ -+#define RTL8367C_REG_IGMP_PORT7_CONTROL 0x1c0c -+#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_QUERY_OFFSET 14 -+#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_QUERY_MASK 0x4000 -+#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_REPORT_OFFSET 13 -+#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_REPORT_MASK 0x2000 -+#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_LEAVE_OFFSET 12 -+#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_LEAVE_MASK 0x1000 -+#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_MRP_OFFSET 11 -+#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_MRP_MASK 0x800 -+#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_MC_DATA_OFFSET 10 -+#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_MC_DATA_MASK 0x400 -+#define RTL8367C_IGMP_PORT7_CONTROL_MLDv2_OP_OFFSET 8 -+#define RTL8367C_IGMP_PORT7_CONTROL_MLDv2_OP_MASK 0x300 -+#define RTL8367C_IGMP_PORT7_CONTROL_MLDv1_OP_OFFSET 6 -+#define RTL8367C_IGMP_PORT7_CONTROL_MLDv1_OP_MASK 0xC0 -+#define RTL8367C_IGMP_PORT7_CONTROL_IGMPV3_OP_OFFSET 4 -+#define RTL8367C_IGMP_PORT7_CONTROL_IGMPV3_OP_MASK 0x30 -+#define RTL8367C_IGMP_PORT7_CONTROL_IGMPV2_OP_OFFSET 2 -+#define RTL8367C_IGMP_PORT7_CONTROL_IGMPV2_OP_MASK 0xC -+#define RTL8367C_IGMP_PORT7_CONTROL_IGMPV1_OP_OFFSET 0 -+#define RTL8367C_IGMP_PORT7_CONTROL_IGMPV1_OP_MASK 0x3 -+ -+#define RTL8367C_REG_IGMP_PORT01_MAX_GROUP 0x1c0d -+#define RTL8367C_PORT1_MAX_GROUP_OFFSET 8 -+#define RTL8367C_PORT1_MAX_GROUP_MASK 0xFF00 -+#define RTL8367C_PORT0_MAX_GROUP_OFFSET 0 -+#define RTL8367C_PORT0_MAX_GROUP_MASK 0xFF -+ -+#define RTL8367C_REG_IGMP_PORT23_MAX_GROUP 0x1c0e -+#define RTL8367C_PORT3_MAX_GROUP_OFFSET 8 -+#define RTL8367C_PORT3_MAX_GROUP_MASK 0xFF00 -+#define RTL8367C_PORT2_MAX_GROUP_OFFSET 0 -+#define RTL8367C_PORT2_MAX_GROUP_MASK 0xFF -+ -+#define RTL8367C_REG_IGMP_PORT45_MAX_GROUP 0x1c0f -+#define RTL8367C_PORT5_MAX_GROUP_OFFSET 8 -+#define RTL8367C_PORT5_MAX_GROUP_MASK 0xFF00 -+#define RTL8367C_PORT4_MAX_GROUP_OFFSET 0 -+#define RTL8367C_PORT4_MAX_GROUP_MASK 0xFF -+ -+#define RTL8367C_REG_IGMP_PORT67_MAX_GROUP 0x1c10 -+#define RTL8367C_PORT7_MAX_GROUP_OFFSET 8 -+#define RTL8367C_PORT7_MAX_GROUP_MASK 0xFF00 -+#define RTL8367C_PORT6_MAX_GROUP_OFFSET 0 -+#define RTL8367C_PORT6_MAX_GROUP_MASK 0xFF -+ -+#define RTL8367C_REG_IGMP_PORT01_CURRENT_GROUP 0x1c11 -+#define RTL8367C_PORT1_CURRENT_GROUP_OFFSET 8 -+#define RTL8367C_PORT1_CURRENT_GROUP_MASK 0xFF00 -+#define RTL8367C_PORT0_CURRENT_GROUP_OFFSET 0 -+#define RTL8367C_PORT0_CURRENT_GROUP_MASK 0xFF -+ -+#define RTL8367C_REG_IGMP_PORT23_CURRENT_GROUP 0x1c12 -+#define RTL8367C_PORT3_CURRENT_GROUP_OFFSET 8 -+#define RTL8367C_PORT3_CURRENT_GROUP_MASK 0xFF00 -+#define RTL8367C_PORT2_CURRENT_GROUP_OFFSET 0 -+#define RTL8367C_PORT2_CURRENT_GROUP_MASK 0xFF -+ -+#define RTL8367C_REG_IGMP_PORT45_CURRENT_GROUP 0x1c13 -+#define RTL8367C_PORT5_CURRENT_GROUP_OFFSET 8 -+#define RTL8367C_PORT5_CURRENT_GROUP_MASK 0xFF00 -+#define RTL8367C_PORT4_CURRENT_GROUP_OFFSET 0 -+#define RTL8367C_PORT4_CURRENT_GROUP_MASK 0xFF -+ -+#define RTL8367C_REG_IGMP_PORT67_CURRENT_GROUP 0x1c14 -+#define RTL8367C_PORT7_CURRENT_GROUP_OFFSET 8 -+#define RTL8367C_PORT7_CURRENT_GROUP_MASK 0xFF00 -+#define RTL8367C_PORT6_CURRENT_GROUP_OFFSET 0 -+#define RTL8367C_PORT6_CURRENT_GROUP_MASK 0xFF -+ -+#define RTL8367C_REG_IGMP_MLD_CFG3 0x1c15 -+#define RTL8367C_IGMP_MLD_IP6_BYPASS_OFFSET 5 -+#define RTL8367C_IGMP_MLD_IP6_BYPASS_MASK 0x20 -+#define RTL8367C_IGMP_MLD_IP4_BYPASS_239_255_255_OFFSET 4 -+#define RTL8367C_IGMP_MLD_IP4_BYPASS_239_255_255_MASK 0x10 -+#define RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_1_OFFSET 3 -+#define RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_1_MASK 0x8 -+#define RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_0_OFFSET 2 -+#define RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_0_MASK 0x4 -+#define RTL8367C_REPORT_LEAVE_FORWARD_OFFSET 0 -+#define RTL8367C_REPORT_LEAVE_FORWARD_MASK 0x3 -+ -+#define RTL8367C_REG_IGMP_MLD_CFG4 0x1c16 -+#define RTL8367C_IGMP_MLD_CFG4_OFFSET 0 -+#define RTL8367C_IGMP_MLD_CFG4_MASK 0x7FF -+ -+#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST0 0x1c20 -+ -+#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST1 0x1c21 -+ -+#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST2 0x1c22 -+ -+#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST3 0x1c23 -+ -+#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST4 0x1c24 -+ -+#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST5 0x1c25 -+ -+#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST6 0x1c26 -+ -+#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST7 0x1c27 -+ -+#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST8 0x1c28 -+ -+#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST9 0x1c29 -+ -+#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST10 0x1c2a -+ -+#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST11 0x1c2b -+ -+#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST12 0x1c2c -+ -+#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST13 0x1c2d -+ -+#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST14 0x1c2e -+ -+#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST15 0x1c2f -+ -+#define RTL8367C_REG_EAV_CTRL0 0x1c30 -+#define RTL8367C_EAV_CTRL0_OFFSET 0 -+#define RTL8367C_EAV_CTRL0_MASK 0xFF -+ -+#define RTL8367C_REG_EAV_CTRL1 0x1c31 -+#define RTL8367C_REMAP_EAV_PRI3_REGEN_OFFSET 9 -+#define RTL8367C_REMAP_EAV_PRI3_REGEN_MASK 0xE00 -+#define RTL8367C_REMAP_EAV_PRI2_REGEN_OFFSET 6 -+#define RTL8367C_REMAP_EAV_PRI2_REGEN_MASK 0x1C0 -+#define RTL8367C_REMAP_EAV_PRI1_REGEN_OFFSET 3 -+#define RTL8367C_REMAP_EAV_PRI1_REGEN_MASK 0x38 -+#define RTL8367C_REMAP_EAV_PRI0_REGEN_OFFSET 0 -+#define RTL8367C_REMAP_EAV_PRI0_REGEN_MASK 0x7 -+ -+#define RTL8367C_REG_EAV_CTRL2 0x1c32 -+#define RTL8367C_REMAP_EAV_PRI7_REGEN_OFFSET 9 -+#define RTL8367C_REMAP_EAV_PRI7_REGEN_MASK 0xE00 -+#define RTL8367C_REMAP_EAV_PRI6_REGEN_OFFSET 6 -+#define RTL8367C_REMAP_EAV_PRI6_REGEN_MASK 0x1C0 -+#define RTL8367C_REMAP_EAV_PRI5_REGEN_OFFSET 3 -+#define RTL8367C_REMAP_EAV_PRI5_REGEN_MASK 0x38 -+#define RTL8367C_REMAP_EAV_PRI4_REGEN_OFFSET 0 -+#define RTL8367C_REMAP_EAV_PRI4_REGEN_MASK 0x7 -+ -+#define RTL8367C_REG_SYS_TIME_FREQ 0x1c43 -+ -+#define RTL8367C_REG_SYS_TIME_OFFSET_L 0x1c44 -+ -+#define RTL8367C_REG_SYS_TIME_OFFSET_H 0x1c45 -+ -+#define RTL8367C_REG_SYS_TIME_OFFSET_512NS_L 0x1c46 -+ -+#define RTL8367C_REG_SYS_TIME_OFFSET_512NS_H 0x1c47 -+#define RTL8367C_SYS_TIME_OFFSET_TUNE_OFFSET 5 -+#define RTL8367C_SYS_TIME_OFFSET_TUNE_MASK 0x20 -+#define RTL8367C_SYS_TIME_OFFSET_512NS_H_SYS_TIME_OFFSET_512NS_OFFSET 0 -+#define RTL8367C_SYS_TIME_OFFSET_512NS_H_SYS_TIME_OFFSET_512NS_MASK 0x1F -+ -+#define RTL8367C_REG_SYS_TIME_SEC_TRANSIT 0x1c48 -+#define RTL8367C_SYS_TIME_SEC_TRANSIT_OFFSET 0 -+#define RTL8367C_SYS_TIME_SEC_TRANSIT_MASK 0x1 -+ -+#define RTL8367C_REG_SYS_TIME_SEC_HIGH_L 0x1c49 -+ -+#define RTL8367C_REG_SYS_TIME_SEC_HIGH_H 0x1c4a -+ -+#define RTL8367C_REG_SYS_TIME_512NS_L 0x1c4b -+ -+#define RTL8367C_REG_SYS_TIME_512NS_H 0x1c4c -+#define RTL8367C_SYS_TIME_512NS_H_OFFSET 0 -+#define RTL8367C_SYS_TIME_512NS_H_MASK 0x1F -+ -+#define RTL8367C_REG_FALLBACK_CTRL 0x1c70 -+#define RTL8367C_FALLBACK_PL_DEC_EN_OFFSET 15 -+#define RTL8367C_FALLBACK_PL_DEC_EN_MASK 0x8000 -+#define RTL8367C_FALLBACK_MONITOR_TIMEOUT_IGNORE_OFFSET 14 -+#define RTL8367C_FALLBACK_MONITOR_TIMEOUT_IGNORE_MASK 0x4000 -+#define RTL8367C_FALLBACK_ERROR_RATIO_THRESHOLD_OFFSET 11 -+#define RTL8367C_FALLBACK_ERROR_RATIO_THRESHOLD_MASK 0x3800 -+#define RTL8367C_FALLBACK_MONITORMAX_OFFSET 8 -+#define RTL8367C_FALLBACK_MONITORMAX_MASK 0x700 -+#define RTL8367C_FALLBACK_MONITOR_TIMEOUT_OFFSET 0 -+#define RTL8367C_FALLBACK_MONITOR_TIMEOUT_MASK 0xFF -+ -+#define RTL8367C_REG_FALLBACK_PORT0_CFG0 0x1c71 -+#define RTL8367C_FALLBACK_PORT0_CFG0_RESET_POWER_LEVEL_OFFSET 15 -+#define RTL8367C_FALLBACK_PORT0_CFG0_RESET_POWER_LEVEL_MASK 0x8000 -+#define RTL8367C_FALLBACK_PORT0_CFG0_ENABLE_OFFSET 14 -+#define RTL8367C_FALLBACK_PORT0_CFG0_ENABLE_MASK 0x4000 -+ -+#define RTL8367C_REG_FALLBACK_PORT0_CFG1 0x1c72 -+ -+#define RTL8367C_REG_FALLBACK_PORT0_CFG2 0x1c73 -+#define RTL8367C_FALLBACK_PORT0_CFG2_OFFSET 0 -+#define RTL8367C_FALLBACK_PORT0_CFG2_MASK 0xFFF -+ -+#define RTL8367C_REG_FALLBACK_PORT0_CFG3 0x1c74 -+#define RTL8367C_FALLBACK_PORT0_CFG3_OFFSET 0 -+#define RTL8367C_FALLBACK_PORT0_CFG3_MASK 0xFF -+ -+#define RTL8367C_REG_FALLBACK_PORT1_CFG0 0x1c75 -+#define RTL8367C_FALLBACK_PORT1_CFG0_RESET_POWER_LEVEL_OFFSET 15 -+#define RTL8367C_FALLBACK_PORT1_CFG0_RESET_POWER_LEVEL_MASK 0x8000 -+#define RTL8367C_FALLBACK_PORT1_CFG0_ENABLE_OFFSET 14 -+#define RTL8367C_FALLBACK_PORT1_CFG0_ENABLE_MASK 0x4000 -+ -+#define RTL8367C_REG_FALLBACK_PORT1_CFG1 0x1c76 -+ -+#define RTL8367C_REG_FALLBACK_PORT1_CFG2 0x1c77 -+#define RTL8367C_FALLBACK_PORT1_CFG2_OFFSET 0 -+#define RTL8367C_FALLBACK_PORT1_CFG2_MASK 0xFFF -+ -+#define RTL8367C_REG_FALLBACK_PORT1_CFG3 0x1c78 -+#define RTL8367C_FALLBACK_PORT1_CFG3_OFFSET 0 -+#define RTL8367C_FALLBACK_PORT1_CFG3_MASK 0xFF -+ -+#define RTL8367C_REG_FALLBACK_PORT2_CFG0 0x1c79 -+#define RTL8367C_FALLBACK_PORT2_CFG0_RESET_POWER_LEVEL_OFFSET 15 -+#define RTL8367C_FALLBACK_PORT2_CFG0_RESET_POWER_LEVEL_MASK 0x8000 -+#define RTL8367C_FALLBACK_PORT2_CFG0_ENABLE_OFFSET 14 -+#define RTL8367C_FALLBACK_PORT2_CFG0_ENABLE_MASK 0x4000 -+ -+#define RTL8367C_REG_FALLBACK_PORT2_CFG1 0x1c7a -+ -+#define RTL8367C_REG_FALLBACK_PORT2_CFG2 0x1c7b -+#define RTL8367C_FALLBACK_PORT2_CFG2_OFFSET 0 -+#define RTL8367C_FALLBACK_PORT2_CFG2_MASK 0xFFF -+ -+#define RTL8367C_REG_FALLBACK_PORT2_CFG3 0x1c7c -+#define RTL8367C_FALLBACK_PORT2_CFG3_OFFSET 0 -+#define RTL8367C_FALLBACK_PORT2_CFG3_MASK 0xFF -+ -+#define RTL8367C_REG_FALLBACK_PORT3_CFG0 0x1c7d -+#define RTL8367C_FALLBACK_PORT3_CFG0_RESET_POWER_LEVEL_OFFSET 15 -+#define RTL8367C_FALLBACK_PORT3_CFG0_RESET_POWER_LEVEL_MASK 0x8000 -+#define RTL8367C_FALLBACK_PORT3_CFG0_ENABLE_OFFSET 14 -+#define RTL8367C_FALLBACK_PORT3_CFG0_ENABLE_MASK 0x4000 -+ -+#define RTL8367C_REG_FALLBACK_PORT3_CFG1 0x1c7e -+ -+#define RTL8367C_REG_FALLBACK_PORT3_CFG2 0x1c7f -+#define RTL8367C_FALLBACK_PORT3_CFG2_OFFSET 0 -+#define RTL8367C_FALLBACK_PORT3_CFG2_MASK 0xFFF -+ -+#define RTL8367C_REG_FALLBACK_PORT3_CFG3 0x1c80 -+#define RTL8367C_FALLBACK_PORT3_CFG3_OFFSET 0 -+#define RTL8367C_FALLBACK_PORT3_CFG3_MASK 0xFF -+ -+#define RTL8367C_REG_FALLBACK_PORT4_CFG0 0x1c81 -+#define RTL8367C_FALLBACK_PORT4_CFG0_RESET_POWER_LEVEL_OFFSET 15 -+#define RTL8367C_FALLBACK_PORT4_CFG0_RESET_POWER_LEVEL_MASK 0x8000 -+#define RTL8367C_FALLBACK_PORT4_CFG0_ENABLE_OFFSET 14 -+#define RTL8367C_FALLBACK_PORT4_CFG0_ENABLE_MASK 0x4000 -+ -+#define RTL8367C_REG_FALLBACK_PORT4_CFG1 0x1c82 -+ -+#define RTL8367C_REG_FALLBACK_PORT4_CFG2 0x1c83 -+#define RTL8367C_FALLBACK_PORT4_CFG2_OFFSET 0 -+#define RTL8367C_FALLBACK_PORT4_CFG2_MASK 0xFFF -+ -+#define RTL8367C_REG_FALLBACK_PORT4_CFG3 0x1c84 -+#define RTL8367C_FALLBACK_PORT4_CFG3_OFFSET 0 -+#define RTL8367C_FALLBACK_PORT4_CFG3_MASK 0xFF -+ -+#define RTL8367C_REG_FALLBACK_CTRL1 0x1c85 -+#define RTL8367C_FALLBACK_VALIDFLOW_OFFSET 8 -+#define RTL8367C_FALLBACK_VALIDFLOW_MASK 0xFF00 -+#define RTL8367C_FALLBACK_STOP_TMR_OFFSET 0 -+#define RTL8367C_FALLBACK_STOP_TMR_MASK 0x1 -+ -+#define RTL8367C_REG_FALLBACK_CPL 0x1c86 -+#define RTL8367C_PORT4_CPL_OFFSET 4 -+#define RTL8367C_PORT4_CPL_MASK 0x10 -+#define RTL8367C_PORT3_CPL_OFFSET 3 -+#define RTL8367C_PORT3_CPL_MASK 0x8 -+#define RTL8367C_PORT2_CPL_OFFSET 2 -+#define RTL8367C_PORT2_CPL_MASK 0x4 -+#define RTL8367C_PORT1_CPL_OFFSET 1 -+#define RTL8367C_PORT1_CPL_MASK 0x2 -+#define RTL8367C_PORT0_CPL_OFFSET 0 -+#define RTL8367C_PORT0_CPL_MASK 0x1 -+ -+#define RTL8367C_REG_FALLBACK_PHY_PAGE 0x1c87 -+#define RTL8367C_FALLBACK_PHY_PAGE_OFFSET 0 -+#define RTL8367C_FALLBACK_PHY_PAGE_MASK 0xFFF -+ -+#define RTL8367C_REG_FALLBACK_PHY_REG 0x1c88 -+#define RTL8367C_FALLBACK_PHY_REG_OFFSET 0 -+#define RTL8367C_FALLBACK_PHY_REG_MASK 0x1F -+ -+#define RTL8367C_REG_AFBK_INFO_X0 0x1c89 -+ -+#define RTL8367C_REG_AFBK_INFO_X1 0x1c8a -+ -+#define RTL8367C_REG_AFBK_INFO_X2 0x1c8b -+ -+#define RTL8367C_REG_AFBK_INFO_X3 0x1c8c -+ -+#define RTL8367C_REG_AFBK_INFO_X4 0x1c8d -+ -+#define RTL8367C_REG_AFBK_INFO_X5 0x1c8e -+ -+#define RTL8367C_REG_AFBK_INFO_X6 0x1c8f -+ -+#define RTL8367C_REG_AFBK_INFO_X7 0x1c90 -+ -+#define RTL8367C_REG_AFBK_INFO_X8 0x1c91 -+ -+#define RTL8367C_REG_AFBK_INFO_X9 0x1c92 -+ -+#define RTL8367C_REG_AFBK_INFO_X10 0x1c93 -+ -+#define RTL8367C_REG_AFBK_INFO_X11 0x1c94 -+ -+#define RTL8367C_REG_FALLBACK_PORT5_CFG0 0x1ca0 -+#define RTL8367C_FALLBACK_PORT5_CFG0_RESET_POWER_LEVEL_OFFSET 15 -+#define RTL8367C_FALLBACK_PORT5_CFG0_RESET_POWER_LEVEL_MASK 0x8000 -+#define RTL8367C_FALLBACK_PORT5_CFG0_ENABLE_OFFSET 14 -+#define RTL8367C_FALLBACK_PORT5_CFG0_ENABLE_MASK 0x4000 -+ -+#define RTL8367C_REG_FALLBACK_PORT5_CFG1 0x1ca1 -+ -+#define RTL8367C_REG_FALLBACK_PORT5_CFG2 0x1ca2 -+#define RTL8367C_FALLBACK_PORT5_CFG2_OFFSET 0 -+#define RTL8367C_FALLBACK_PORT5_CFG2_MASK 0xFFF -+ -+#define RTL8367C_REG_FALLBACK_PORT5_CFG3 0x1ca3 -+#define RTL8367C_FALLBACK_PORT5_CFG3_OFFSET 0 -+#define RTL8367C_FALLBACK_PORT5_CFG3_MASK 0xFF -+ -+#define RTL8367C_REG_FALLBACK_PORT6_CFG0 0x1ca4 -+#define RTL8367C_FALLBACK_PORT6_CFG0_RESET_POWER_LEVEL_OFFSET 15 -+#define RTL8367C_FALLBACK_PORT6_CFG0_RESET_POWER_LEVEL_MASK 0x8000 -+#define RTL8367C_FALLBACK_PORT6_CFG0_ENABLE_OFFSET 14 -+#define RTL8367C_FALLBACK_PORT6_CFG0_ENABLE_MASK 0x4000 -+ -+#define RTL8367C_REG_FALLBACK_PORT6_CFG1 0x1ca5 -+ -+#define RTL8367C_REG_FALLBACK_PORT6_CFG2 0x1ca6 -+#define RTL8367C_FALLBACK_PORT6_CFG2_OFFSET 0 -+#define RTL8367C_FALLBACK_PORT6_CFG2_MASK 0xFFF -+ -+#define RTL8367C_REG_FALLBACK_PORT6_CFG3 0x1ca7 -+#define RTL8367C_FALLBACK_PORT6_CFG3_OFFSET 0 -+#define RTL8367C_FALLBACK_PORT6_CFG3_MASK 0xFF -+ -+#define RTL8367C_REG_FALLBACK_PORT7_CFG0 0x1ca8 -+#define RTL8367C_FALLBACK_PORT7_CFG0_RESET_POWER_LEVEL_OFFSET 15 -+#define RTL8367C_FALLBACK_PORT7_CFG0_RESET_POWER_LEVEL_MASK 0x8000 -+#define RTL8367C_FALLBACK_PORT7_CFG0_ENABLE_OFFSET 14 -+#define RTL8367C_FALLBACK_PORT7_CFG0_ENABLE_MASK 0x4000 -+ -+#define RTL8367C_REG_FALLBACK_PORT7_CFG1 0x1ca9 -+ -+#define RTL8367C_REG_FALLBACK_PORT7_CFG2 0x1caa -+#define RTL8367C_FALLBACK_PORT7_CFG2_OFFSET 0 -+#define RTL8367C_FALLBACK_PORT7_CFG2_MASK 0xFFF -+ -+#define RTL8367C_REG_FALLBACK_PORT7_CFG3 0x1cab -+#define RTL8367C_FALLBACK_PORT7_CFG3_OFFSET 0 -+#define RTL8367C_FALLBACK_PORT7_CFG3_MASK 0xFF -+ -+#define RTL8367C_REG_IGMP_PORT8_CONTROL 0x1cb0 -+#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_QUERY_OFFSET 14 -+#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_QUERY_MASK 0x4000 -+#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_REPORT_OFFSET 13 -+#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_REPORT_MASK 0x2000 -+#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_LEAVE_OFFSET 12 -+#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_LEAVE_MASK 0x1000 -+#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_MRP_OFFSET 11 -+#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_MRP_MASK 0x800 -+#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_MC_DATA_OFFSET 10 -+#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_MC_DATA_MASK 0x400 -+#define RTL8367C_IGMP_PORT8_CONTROL_MLDv2_OP_OFFSET 8 -+#define RTL8367C_IGMP_PORT8_CONTROL_MLDv2_OP_MASK 0x300 -+#define RTL8367C_IGMP_PORT8_CONTROL_MLDv1_OP_OFFSET 6 -+#define RTL8367C_IGMP_PORT8_CONTROL_MLDv1_OP_MASK 0xC0 -+#define RTL8367C_IGMP_PORT8_CONTROL_IGMPV3_OP_OFFSET 4 -+#define RTL8367C_IGMP_PORT8_CONTROL_IGMPV3_OP_MASK 0x30 -+#define RTL8367C_IGMP_PORT8_CONTROL_IGMPV2_OP_OFFSET 2 -+#define RTL8367C_IGMP_PORT8_CONTROL_IGMPV2_OP_MASK 0xC -+#define RTL8367C_IGMP_PORT8_CONTROL_IGMPV1_OP_OFFSET 0 -+#define RTL8367C_IGMP_PORT8_CONTROL_IGMPV1_OP_MASK 0x3 -+ -+#define RTL8367C_REG_IGMP_PORT9_CONTROL 0x1cb1 -+#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_QUERY_OFFSET 14 -+#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_QUERY_MASK 0x4000 -+#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_REPORT_OFFSET 13 -+#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_REPORT_MASK 0x2000 -+#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_LEAVE_OFFSET 12 -+#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_LEAVE_MASK 0x1000 -+#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_MRP_OFFSET 11 -+#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_MRP_MASK 0x800 -+#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_MC_DATA_OFFSET 10 -+#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_MC_DATA_MASK 0x400 -+#define RTL8367C_IGMP_PORT9_CONTROL_MLDv2_OP_OFFSET 8 -+#define RTL8367C_IGMP_PORT9_CONTROL_MLDv2_OP_MASK 0x300 -+#define RTL8367C_IGMP_PORT9_CONTROL_MLDv1_OP_OFFSET 6 -+#define RTL8367C_IGMP_PORT9_CONTROL_MLDv1_OP_MASK 0xC0 -+#define RTL8367C_IGMP_PORT9_CONTROL_IGMPV3_OP_OFFSET 4 -+#define RTL8367C_IGMP_PORT9_CONTROL_IGMPV3_OP_MASK 0x30 -+#define RTL8367C_IGMP_PORT9_CONTROL_IGMPV2_OP_OFFSET 2 -+#define RTL8367C_IGMP_PORT9_CONTROL_IGMPV2_OP_MASK 0xC -+#define RTL8367C_IGMP_PORT9_CONTROL_IGMPV1_OP_OFFSET 0 -+#define RTL8367C_IGMP_PORT9_CONTROL_IGMPV1_OP_MASK 0x3 -+ -+#define RTL8367C_REG_IGMP_PORT10_CONTROL 0x1cb2 -+#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_QUERY_OFFSET 14 -+#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_QUERY_MASK 0x4000 -+#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_REPORT_OFFSET 13 -+#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_REPORT_MASK 0x2000 -+#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_LEAVE_OFFSET 12 -+#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_LEAVE_MASK 0x1000 -+#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_MRP_OFFSET 11 -+#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_MRP_MASK 0x800 -+#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_MC_DATA_OFFSET 10 -+#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_MC_DATA_MASK 0x400 -+#define RTL8367C_IGMP_PORT10_CONTROL_MLDv2_OP_OFFSET 8 -+#define RTL8367C_IGMP_PORT10_CONTROL_MLDv2_OP_MASK 0x300 -+#define RTL8367C_IGMP_PORT10_CONTROL_MLDv1_OP_OFFSET 6 -+#define RTL8367C_IGMP_PORT10_CONTROL_MLDv1_OP_MASK 0xC0 -+#define RTL8367C_IGMP_PORT10_CONTROL_IGMPV3_OP_OFFSET 4 -+#define RTL8367C_IGMP_PORT10_CONTROL_IGMPV3_OP_MASK 0x30 -+#define RTL8367C_IGMP_PORT10_CONTROL_IGMPV2_OP_OFFSET 2 -+#define RTL8367C_IGMP_PORT10_CONTROL_IGMPV2_OP_MASK 0xC -+#define RTL8367C_IGMP_PORT10_CONTROL_IGMPV1_OP_OFFSET 0 -+#define RTL8367C_IGMP_PORT10_CONTROL_IGMPV1_OP_MASK 0x3 -+ -+#define RTL8367C_REG_IGMP_PORT89_MAX_GROUP 0x1cb3 -+#define RTL8367C_PORT9_MAX_GROUP_OFFSET 8 -+#define RTL8367C_PORT9_MAX_GROUP_MASK 0xFF00 -+#define RTL8367C_PORT8_MAX_GROUP_OFFSET 0 -+#define RTL8367C_PORT8_MAX_GROUP_MASK 0xFF -+ -+#define RTL8367C_REG_IGMP_PORT10_MAX_GROUP 0x1cb4 -+#define RTL8367C_IGMP_PORT10_MAX_GROUP_OFFSET 0 -+#define RTL8367C_IGMP_PORT10_MAX_GROUP_MASK 0xFF -+ -+#define RTL8367C_REG_IGMP_PORT89_CURRENT_GROUP 0x1cb5 -+#define RTL8367C_PORT9_CURRENT_GROUP_OFFSET 8 -+#define RTL8367C_PORT9_CURRENT_GROUP_MASK 0xFF00 -+#define RTL8367C_PORT8_CURRENT_GROUP_OFFSET 0 -+#define RTL8367C_PORT8_CURRENT_GROUP_MASK 0xFF -+ -+#define RTL8367C_REG_IGMP_PORT10_CURRENT_GROUP 0x1cb6 -+#define RTL8367C_IGMP_PORT10_CURRENT_GROUP_OFFSET 0 -+#define RTL8367C_IGMP_PORT10_CURRENT_GROUP_MASK 0xFF -+ -+#define RTL8367C_REG_IGMP_L3_CHECKSUM_CHECK 0x1cb7 -+#define RTL8367C_IGMP_L3_CHECKSUM_CHECK_OFFSET 0 -+#define RTL8367C_IGMP_L3_CHECKSUM_CHECK_MASK 0x1 -+ -+/* (16'h1d00)chip_70b_reg */ -+ -+#define RTL8367C_REG_PCSXF_CFG 0x1d00 -+#define RTL8367C_PCSXF_CFG_Reserved_OFFSET 15 -+#define RTL8367C_PCSXF_CFG_Reserved_MASK 0x8000 -+#define RTL8367C_CFG_RST_RXFIFO_P7_5_OFFSET 12 -+#define RTL8367C_CFG_RST_RXFIFO_P7_5_MASK 0x7000 -+#define RTL8367C_CFG_PCSXF_OFFSET 8 -+#define RTL8367C_CFG_PCSXF_MASK 0xF00 -+#define RTL8367C_CFG_RST_RXFIFO_OFFSET 3 -+#define RTL8367C_CFG_RST_RXFIFO_MASK 0xF8 -+#define RTL8367C_CFG_COL2RXDV_OFFSET 2 -+#define RTL8367C_CFG_COL2RXDV_MASK 0x4 -+#define RTL8367C_CFG_PHY_SDET_OFFSET 0 -+#define RTL8367C_CFG_PHY_SDET_MASK 0x3 -+ -+#define RTL8367C_REG_PHYID_CFG0 0x1d01 -+#define RTL8367C_CFG_PHY_BRD_MODE_P7_5_OFFSET 11 -+#define RTL8367C_CFG_PHY_BRD_MODE_P7_5_MASK 0x3800 -+#define RTL8367C_CFG_PHYAD_14C_OFFSET 10 -+#define RTL8367C_CFG_PHYAD_14C_MASK 0x400 -+#define RTL8367C_CFG_PHY_BRD_MODE_OFFSET 5 -+#define RTL8367C_CFG_PHY_BRD_MODE_MASK 0x3E0 -+#define RTL8367C_CFG_BRD_PHYAD_OFFSET 0 -+#define RTL8367C_CFG_BRD_PHYAD_MASK 0x1F -+ -+#define RTL8367C_REG_PHYID_CFG1 0x1d02 -+#define RTL8367C_CFG_MSK_MDI_OFFSET 5 -+#define RTL8367C_CFG_MSK_MDI_MASK 0x1FE0 -+#define RTL8367C_CFG_BASE_PHYAD_OFFSET 0 -+#define RTL8367C_CFG_BASE_PHYAD_MASK 0x1F -+ -+#define RTL8367C_REG_PHY_POLL_CFG0 0x1d03 -+#define RTL8367C_CFG_HOTCMD_PRD_EN_OFFSET 15 -+#define RTL8367C_CFG_HOTCMD_PRD_EN_MASK 0x8000 -+#define RTL8367C_CFG_HOTCMD_EN_OFFSET 12 -+#define RTL8367C_CFG_HOTCMD_EN_MASK 0x7000 -+#define RTL8367C_CFG_POLL_PERIOD_OFFSET 8 -+#define RTL8367C_CFG_POLL_PERIOD_MASK 0xF00 -+#define RTL8367C_CFG_PERI_CMDS_RD_OFFSET 4 -+#define RTL8367C_CFG_PERI_CMDS_RD_MASK 0xF0 -+#define RTL8367C_CFG_PERI_CMDS_WR_OFFSET 0 -+#define RTL8367C_CFG_PERI_CMDS_WR_MASK 0xF -+ -+#define RTL8367C_REG_PHY_POLL_CFG1 0x1d04 -+ -+#define RTL8367C_REG_PHY_POLL_CFG2 0x1d05 -+ -+#define RTL8367C_REG_PHY_POLL_CFG3 0x1d06 -+ -+#define RTL8367C_REG_PHY_POLL_CFG4 0x1d07 -+ -+#define RTL8367C_REG_PHY_POLL_CFG5 0x1d08 -+ -+#define RTL8367C_REG_PHY_POLL_CFG6 0x1d09 -+ -+#define RTL8367C_REG_PHY_POLL_CFG7 0x1d0a -+ -+#define RTL8367C_REG_PHY_POLL_CFG8 0x1d0b -+ -+#define RTL8367C_REG_PHY_POLL_CFG9 0x1d0c -+ -+#define RTL8367C_REG_PHY_POLL_CFG10 0x1d0d -+ -+#define RTL8367C_REG_PHY_POLL_CFG11 0x1d0e -+ -+#define RTL8367C_REG_PHY_POLL_CFG12 0x1d0f -+ -+#define RTL8367C_REG_EFUSE_MISC 0x1d10 -+#define RTL8367C_CFG_SA_SEL_OFFSET 5 -+#define RTL8367C_CFG_SA_SEL_MASK 0x20 -+#define RTL8367C_CFG_PHYAD00_OFFSET 0 -+#define RTL8367C_CFG_PHYAD00_MASK 0x1F -+ -+#define RTL8367C_REG_SDS_MISC 0x1d11 -+#define RTL8367C_CFG_SGMII_RXFC_OFFSET 14 -+#define RTL8367C_CFG_SGMII_RXFC_MASK 0x4000 -+#define RTL8367C_CFG_SGMII_TXFC_OFFSET 13 -+#define RTL8367C_CFG_SGMII_TXFC_MASK 0x2000 -+#define RTL8367C_INB_ARB_OFFSET 12 -+#define RTL8367C_INB_ARB_MASK 0x1000 -+#define RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET 11 -+#define RTL8367C_CFG_MAC8_SEL_HSGMII_MASK 0x800 -+#define RTL8367C_CFG_SGMII_FDUP_OFFSET 10 -+#define RTL8367C_CFG_SGMII_FDUP_MASK 0x400 -+#define RTL8367C_CFG_SGMII_LINK_OFFSET 9 -+#define RTL8367C_CFG_SGMII_LINK_MASK 0x200 -+#define RTL8367C_CFG_SGMII_SPD_OFFSET 7 -+#define RTL8367C_CFG_SGMII_SPD_MASK 0x180 -+#define RTL8367C_CFG_MAC8_SEL_SGMII_OFFSET 6 -+#define RTL8367C_CFG_MAC8_SEL_SGMII_MASK 0x40 -+#define RTL8367C_CFG_INB_SEL_OFFSET 3 -+#define RTL8367C_CFG_INB_SEL_MASK 0x38 -+#define RTL8367C_CFG_SDS_MODE_18C_OFFSET 0 -+#define RTL8367C_CFG_SDS_MODE_18C_MASK 0x7 -+ -+#define RTL8367C_REG_FIFO_CTRL 0x1d12 -+#define RTL8367C_CFG_LINK_DOWN_CLR_FIFO_OFFSET 11 -+#define RTL8367C_CFG_LINK_DOWN_CLR_FIFO_MASK 0x800 -+#define RTL8367C_CFG_LPBK_OFFSET 10 -+#define RTL8367C_CFG_LPBK_MASK 0x400 -+#define RTL8367C_CFG_NOT_FF_OUT_OFFSET 9 -+#define RTL8367C_CFG_NOT_FF_OUT_MASK 0x200 -+#define RTL8367C_CFG_WATER_LEVEL_FD_OFFSET 6 -+#define RTL8367C_CFG_WATER_LEVEL_FD_MASK 0x1C0 -+#define RTL8367C_CFG_WATER_LEVEL_Y2X_OFFSET 3 -+#define RTL8367C_CFG_WATER_LEVEL_Y2X_MASK 0x38 -+#define RTL8367C_CFG_WATER_LEVEL_X2Y_OFFSET 0 -+#define RTL8367C_CFG_WATER_LEVEL_X2Y_MASK 0x7 -+ -+#define RTL8367C_REG_BCAM_SETTING 0x1d13 -+#define RTL8367C_CFG_BCAM_MDS_OFFSET 3 -+#define RTL8367C_CFG_BCAM_MDS_MASK 0x18 -+#define RTL8367C_CFG_BCAM_RDS_OFFSET 0 -+#define RTL8367C_CFG_BCAM_RDS_MASK 0x7 -+ -+#define RTL8367C_REG_GPHY_ACS_MISC 0x1d14 -+#define RTL8367C_CFG_SEL_GPHY_SMI_OFFSET 3 -+#define RTL8367C_CFG_SEL_GPHY_SMI_MASK 0x8 -+#define RTL8367C_CFG_BRD_PHYIDX_OFFSET 0 -+#define RTL8367C_CFG_BRD_PHYIDX_MASK 0x7 -+ -+#define RTL8367C_REG_GPHY_OCP_MSB_0 0x1d15 -+#define RTL8367C_CFG_CPU_OCPADR_MSB_OFFSET 6 -+#define RTL8367C_CFG_CPU_OCPADR_MSB_MASK 0xFC0 -+#define RTL8367C_CFG_DW8051_OCPADR_MSB_OFFSET 0 -+#define RTL8367C_CFG_DW8051_OCPADR_MSB_MASK 0x3F -+ -+#define RTL8367C_REG_GPHY_OCP_MSB_1 0x1d16 -+#define RTL8367C_CFG_PATCH_OCPADR_MSB_OFFSET 6 -+#define RTL8367C_CFG_PATCH_OCPADR_MSB_MASK 0xFC0 -+#define RTL8367C_CFG_PHYSTS_OCPADR_MSB_OFFSET 0 -+#define RTL8367C_CFG_PHYSTS_OCPADR_MSB_MASK 0x3F -+ -+#define RTL8367C_REG_GPHY_OCP_MSB_2 0x1d17 -+#define RTL8367C_CFG_RRCP_OCPADR_MSB_OFFSET 6 -+#define RTL8367C_CFG_RRCP_OCPADR_MSB_MASK 0xFC0 -+#define RTL8367C_CFG_RTCT_OCPADR_MSB_OFFSET 0 -+#define RTL8367C_CFG_RTCT_OCPADR_MSB_MASK 0x3F -+ -+#define RTL8367C_REG_GPHY_OCP_MSB_3 0x1d18 -+#define RTL8367C_GPHY_OCP_MSB_3_OFFSET 0 -+#define RTL8367C_GPHY_OCP_MSB_3_MASK 0x3F -+ -+#define RTL8367C_REG_GPIO_67C_I_X0 0x1d19 -+ -+#define RTL8367C_REG_GPIO_67C_I_X1 0x1d1a -+ -+#define RTL8367C_REG_GPIO_67C_I_X2 0x1d1b -+ -+#define RTL8367C_REG_GPIO_67C_I_X3 0x1d1c -+#define RTL8367C_GPIO_67C_I_X3_OFFSET 0 -+#define RTL8367C_GPIO_67C_I_X3_MASK 0x3FFF -+ -+#define RTL8367C_REG_GPIO_67C_O_X0 0x1d1d -+ -+#define RTL8367C_REG_GPIO_67C_O_X1 0x1d1e -+ -+#define RTL8367C_REG_GPIO_67C_O_X2 0x1d1f -+ -+#define RTL8367C_REG_GPIO_67C_O_X3 0x1d20 -+#define RTL8367C_GPIO_67C_O_X3_OFFSET 0 -+#define RTL8367C_GPIO_67C_O_X3_MASK 0x3FFF -+ -+#define RTL8367C_REG_GPIO_67C_OE_X0 0x1d21 -+ -+#define RTL8367C_REG_GPIO_67C_OE_X1 0x1d22 -+ -+#define RTL8367C_REG_GPIO_67C_OE_X2 0x1d23 -+ -+#define RTL8367C_REG_GPIO_67C_OE_X3 0x1d24 -+#define RTL8367C_GPIO_67C_OE_X3_OFFSET 0 -+#define RTL8367C_GPIO_67C_OE_X3_MASK 0x3FFF -+ -+#define RTL8367C_REG_GPIO_MODE_67C_X0 0x1d25 -+ -+#define RTL8367C_REG_GPIO_MODE_67C_X1 0x1d26 -+ -+#define RTL8367C_REG_GPIO_MODE_67C_X2 0x1d27 -+ -+#define RTL8367C_REG_GPIO_MODE_67C_X3 0x1d28 -+#define RTL8367C_GPIO_MODE_67C_X3_OFFSET 0 -+#define RTL8367C_GPIO_MODE_67C_X3_MASK 0x3FFF -+ -+#define RTL8367C_REG_WGPHY_MISC_0 0x1d29 -+#define RTL8367C_CFG_INIPHY_DISGIGA_P7_5_OFFSET 13 -+#define RTL8367C_CFG_INIPHY_DISGIGA_P7_5_MASK 0xE000 -+#define RTL8367C_CFG_INIPHY_PWRUP_OFFSET 5 -+#define RTL8367C_CFG_INIPHY_PWRUP_MASK 0x1FE0 -+#define RTL8367C_CFG_INIPHY_DISGIGA_OFFSET 0 -+#define RTL8367C_CFG_INIPHY_DISGIGA_MASK 0x1F -+ -+#define RTL8367C_REG_WGPHY_MISC_1 0x1d2a -+#define RTL8367C_WGPHY_MISC_1_OFFSET 0 -+#define RTL8367C_WGPHY_MISC_1_MASK 0xFF -+ -+#define RTL8367C_REG_WGPHY_MISC_2 0x1d2b -+#define RTL8367C_WGPHY_MISC_2_OFFSET 0 -+#define RTL8367C_WGPHY_MISC_2_MASK 0x3FF -+ -+#define RTL8367C_REG_CFG_AFBK_GPHY_0 0x1d2c -+#define RTL8367C_CFG_AFBK_GPHY_0_OFFSET 0 -+#define RTL8367C_CFG_AFBK_GPHY_0_MASK 0x1F -+ -+#define RTL8367C_REG_CFG_AFBK_GPHY_1 0x1d2d -+#define RTL8367C_CFG_AFBK_GPHY_1_OFFSET 0 -+#define RTL8367C_CFG_AFBK_GPHY_1_MASK 0xFFF -+ -+#define RTL8367C_REG_EF_SLV_CTRL_0 0x1d2e -+#define RTL8367C_EF_SLV_BUSY_OFFSET 11 -+#define RTL8367C_EF_SLV_BUSY_MASK 0x800 -+#define RTL8367C_EF_SLV_ACK_OFFSET 10 -+#define RTL8367C_EF_SLV_ACK_MASK 0x400 -+#define RTL8367C_EF_SLV_A_OFFSET 2 -+#define RTL8367C_EF_SLV_A_MASK 0x3FC -+#define RTL8367C_EF_SLV_WE_OFFSET 1 -+#define RTL8367C_EF_SLV_WE_MASK 0x2 -+#define RTL8367C_EF_SLV_CE_OFFSET 0 -+#define RTL8367C_EF_SLV_CE_MASK 0x1 -+ -+#define RTL8367C_REG_EF_SLV_CTRL_1 0x1d2f -+ -+#define RTL8367C_REG_EF_SLV_CTRL_2 0x1d30 -+ -+#define RTL8367C_REG_EFUSE_MISC_1 0x1d31 -+#define RTL8367C_EF_EN_EFUSE_OFFSET 10 -+#define RTL8367C_EF_EN_EFUSE_MASK 0x400 -+#define RTL8367C_EF_MODEL_ID_OFFSET 6 -+#define RTL8367C_EF_MODEL_ID_MASK 0x3C0 -+#define RTL8367C_EF_RSVD_OFFSET 2 -+#define RTL8367C_EF_RSVD_MASK 0x3C -+#define RTL8367C_EF_SYS_CLK_OFFSET 0 -+#define RTL8367C_EF_SYS_CLK_MASK 0x3 -+ -+#define RTL8367C_REG_IO_MISC_FUNC 0x1d32 -+#define RTL8367C_TST_MODE_OFFSET 3 -+#define RTL8367C_TST_MODE_MASK 0x8 -+#define RTL8367C_UART_EN_OFFSET 2 -+#define RTL8367C_UART_EN_MASK 0x4 -+#define RTL8367C_INT_EN_OFFSET 1 -+#define RTL8367C_INT_EN_MASK 0x2 -+#define RTL8367C_BUZ_EN_OFFSET 0 -+#define RTL8367C_BUZ_EN_MASK 0x1 -+ -+#define RTL8367C_REG_HTRAM_DVS 0x1d33 -+#define RTL8367C_HTRAM_DVS_OFFSET 0 -+#define RTL8367C_HTRAM_DVS_MASK 0x1 -+ -+#define RTL8367C_REG_EF_SLV_CTRL_3 0x1d34 -+#define RTL8367C_EF_SLV_CTRL_3_OFFSET 0 -+#define RTL8367C_EF_SLV_CTRL_3_MASK 0x1 -+ -+#define RTL8367C_REG_INBAND_EN14C 0x1d35 -+#define RTL8367C_INBAND_EN14C_OFFSET 0 -+#define RTL8367C_INBAND_EN14C_MASK 0x1 -+ -+#define RTL8367C_REG_CFG_SWR_L 0x1d36 -+#define RTL8367C_ANARG_RDY_SWR_L_OFFSET 14 -+#define RTL8367C_ANARG_RDY_SWR_L_MASK 0x4000 -+#define RTL8367C_ANARG_VALID_SWR_L_OFFSET 13 -+#define RTL8367C_ANARG_VALID_SWR_L_MASK 0x2000 -+#define RTL8367C_SAW_SWR_L_OFFSET 9 -+#define RTL8367C_SAW_SWR_L_MASK 0x1E00 -+#define RTL8367C_SAW_VALID_SWR_L_OFFSET 8 -+#define RTL8367C_SAW_VALID_SWR_L_MASK 0x100 -+#define RTL8367C_UPS_DBGO_L_OFFSET 0 -+#define RTL8367C_UPS_DBGO_L_MASK 0xFF -+ -+#define RTL8367C_REG_BTCAM_CTRL 0x1d37 -+#define RTL8367C_TCAM_RDS_OFFSET 2 -+#define RTL8367C_TCAM_RDS_MASK 0x1C -+#define RTL8367C_TCAM_MDS_OFFSET 0 -+#define RTL8367C_TCAM_MDS_MASK 0x3 -+ -+#define RTL8367C_REG_PBRAM_BISR_CTRL 0x1d38 -+#define RTL8367C_HAS_HLDRMP_MD_OFFSET 9 -+#define RTL8367C_HAS_HLDRMP_MD_MASK 0x200 -+#define RTL8367C_PB_HLDRMP_MD_OFFSET 8 -+#define RTL8367C_PB_HLDRMP_MD_MASK 0x100 -+#define RTL8367C_HAS_BISR_BIRSTN_OFFSET 7 -+#define RTL8367C_HAS_BISR_BIRSTN_MASK 0x80 -+#define RTL8367C_SEC_RUN_HSA_OFFSET 6 -+#define RTL8367C_SEC_RUN_HSA_MASK 0x40 -+#define RTL8367C_HAS_HLDRMP_VAL_OFFSET 5 -+#define RTL8367C_HAS_HLDRMP_VAL_MASK 0x20 -+#define RTL8367C_HAS_BISR_PWRSTN_OFFSET 4 -+#define RTL8367C_HAS_BISR_PWRSTN_MASK 0x10 -+#define RTL8367C_SEC_RUN_PB_OFFSET 3 -+#define RTL8367C_SEC_RUN_PB_MASK 0x8 -+#define RTL8367C_PB_HLDRMP_VAL_OFFSET 2 -+#define RTL8367C_PB_HLDRMP_VAL_MASK 0x4 -+#define RTL8367C_PB_BISR_BIRSTN_OFFSET 1 -+#define RTL8367C_PB_BISR_BIRSTN_MASK 0x2 -+#define RTL8367C_PB_BISR_PWRSTN_OFFSET 0 -+#define RTL8367C_PB_BISR_PWRSTN_MASK 0x1 -+ -+#define RTL8367C_REG_CVLANRAM_BISR_CTRL 0x1d39 -+#define RTL8367C_SEC_RUN_CVLAN_OFFSET 4 -+#define RTL8367C_SEC_RUN_CVLAN_MASK 0x10 -+#define RTL8367C_CVALN_HLDRMP_MD_OFFSET 3 -+#define RTL8367C_CVALN_HLDRMP_MD_MASK 0x8 -+#define RTL8367C_CVALN_HLDRMP_VAL_OFFSET 2 -+#define RTL8367C_CVALN_HLDRMP_VAL_MASK 0x4 -+#define RTL8367C_CVLAN_BISR_BIRSTN_OFFSET 1 -+#define RTL8367C_CVLAN_BISR_BIRSTN_MASK 0x2 -+#define RTL8367C_CVLAN_BISR_PWRSTN_OFFSET 0 -+#define RTL8367C_CVLAN_BISR_PWRSTN_MASK 0x1 -+ -+#define RTL8367C_REG_CFG_1588_TIMER_EN_GPI 0x1d3a -+#define RTL8367C_CFG_1588_TIMER_EN_GPI_OFFSET 0 -+#define RTL8367C_CFG_1588_TIMER_EN_GPI_MASK 0x1 -+ -+#define RTL8367C_REG_MDIO_PRMB_SUPP 0x1d3b -+#define RTL8367C_FIB_HIPRI_OFFSET 14 -+#define RTL8367C_FIB_HIPRI_MASK 0x4000 -+#define RTL8367C_SMT_EN_OFFSET 13 -+#define RTL8367C_SMT_EN_MASK 0x2000 -+#define RTL8367C_P4_FB_CPL_OFFSET 12 -+#define RTL8367C_P4_FB_CPL_MASK 0x1000 -+#define RTL8367C_P3_FB_CPL_OFFSET 11 -+#define RTL8367C_P3_FB_CPL_MASK 0x800 -+#define RTL8367C_P2_FB_CPL_OFFSET 10 -+#define RTL8367C_P2_FB_CPL_MASK 0x400 -+#define RTL8367C_P1_FB_CPL_OFFSET 9 -+#define RTL8367C_P1_FB_CPL_MASK 0x200 -+#define RTL8367C_P0_FB_CPL_OFFSET 8 -+#define RTL8367C_P0_FB_CPL_MASK 0x100 -+#define RTL8367C_DBG_PKG_8367N_OFFSET 7 -+#define RTL8367C_DBG_PKG_8367N_MASK 0x80 -+#define RTL8367C_DBG_PKG_8367VB_OFFSET 6 -+#define RTL8367C_DBG_PKG_8367VB_MASK 0x40 -+#define RTL8367C_CFG_DEBUG_EN_OFFSET 5 -+#define RTL8367C_CFG_DEBUG_EN_MASK 0x20 -+#define RTL8367C_CFG_TMR_ACK_OFFSET 1 -+#define RTL8367C_CFG_TMR_ACK_MASK 0x1E -+#define RTL8367C_CFG_PRMB_SUPP_OFFSET 0 -+#define RTL8367C_CFG_PRMB_SUPP_MASK 0x1 -+ -+#define RTL8367C_REG_BOND4READ 0x1d3c -+#define RTL8367C_BOND_BOID0_OFFSET 8 -+#define RTL8367C_BOND_BOID0_MASK 0x100 -+#define RTL8367C_BOND_SYSCLK_OFFSET 7 -+#define RTL8367C_BOND_SYSCLK_MASK 0x80 -+#define RTL8367C_BOND_PHYMODE_OFFSET 6 -+#define RTL8367C_BOND_PHYMODE_MASK 0x40 -+#define RTL8367C_BOND_DIS_PON_BIST_OFFSET 5 -+#define RTL8367C_BOND_DIS_PON_BIST_MASK 0x20 -+#define RTL8367C_BOND_DIS_TABLE_INIT_OFFSET 4 -+#define RTL8367C_BOND_DIS_TABLE_INIT_MASK 0x10 -+#define RTL8367C_BOND_BYP_AFE_PLL_OFFSET 3 -+#define RTL8367C_BOND_BYP_AFE_PLL_MASK 0x8 -+#define RTL8367C_BOND_BYP_AFE_POR_OFFSET 2 -+#define RTL8367C_BOND_BYP_AFE_POR_MASK 0x4 -+#define RTL8367C_BOND_BISR_COND_OFFSET 1 -+#define RTL8367C_BOND_BISR_COND_MASK 0x2 -+#define RTL8367C_BOND_EF_EN_OFFSET 0 -+#define RTL8367C_BOND_EF_EN_MASK 0x1 -+ -+#define RTL8367C_REG_REG_TO_ECO0 0x1d3d -+ -+#define RTL8367C_REG_REG_TO_ECO1 0x1d3e -+ -+#define RTL8367C_REG_REG_TO_ECO2 0x1d3f -+ -+#define RTL8367C_REG_REG_TO_ECO3 0x1d40 -+ -+#define RTL8367C_REG_REG_TO_ECO4 0x1d41 -+ -+#define RTL8367C_REG_PHYSTS_CTRL0 0x1d42 -+#define RTL8367C_MACRX_DUPDET_EN_OFFSET 5 -+#define RTL8367C_MACRX_DUPDET_EN_MASK 0x20 -+#define RTL8367C_LNKUP_DLY_EN_OFFSET 4 -+#define RTL8367C_LNKUP_DLY_EN_MASK 0x10 -+#define RTL8367C_GE_100M_LNKUP_DLY_OFFSET 2 -+#define RTL8367C_GE_100M_LNKUP_DLY_MASK 0xC -+#define RTL8367C_PHYSTS_10M_LNKUP_DLY_OFFSET 0 -+#define RTL8367C_PHYSTS_10M_LNKUP_DLY_MASK 0x3 -+ -+#define RTL8367C_REG_SSC_CTRL0_0 0x1d44 -+#define RTL8367C_SSC_CTRL0_0_SSC_TYPE_OFFSET 13 -+#define RTL8367C_SSC_CTRL0_0_SSC_TYPE_MASK 0x2000 -+#define RTL8367C_SSC_CTRL0_0_PHASE_LIM_SEL_OFFSET 5 -+#define RTL8367C_SSC_CTRL0_0_PHASE_LIM_SEL_MASK 0x1FE0 -+#define RTL8367C_SSC_CTRL0_0_PHASE_LIM_EN_OFFSET 4 -+#define RTL8367C_SSC_CTRL0_0_PHASE_LIM_EN_MASK 0x10 -+#define RTL8367C_SSC_CTRL0_0_DLL_MODE_OFFSET 2 -+#define RTL8367C_SSC_CTRL0_0_DLL_MODE_MASK 0xC -+#define RTL8367C_SSC_CTRL0_0_SSC_EN_OFFSET 1 -+#define RTL8367C_SSC_CTRL0_0_SSC_EN_MASK 0x2 -+#define RTL8367C_SSC_CTRL0_0_SSC_MODE_OFFSET 0 -+#define RTL8367C_SSC_CTRL0_0_SSC_MODE_MASK 0x1 -+ -+#define RTL8367C_REG_SSC_RDM_SEED 0x1d45 -+ -+#define RTL8367C_REG_SSC_PN_POLY_SEL 0x1d46 -+ -+#define RTL8367C_REG_SSC_CTRL0_3 0x1d47 -+#define RTL8367C_SSC_CTRL0_3_PHSFT_CNT_OFFSET 8 -+#define RTL8367C_SSC_CTRL0_3_PHSFT_CNT_MASK 0x7F00 -+#define RTL8367C_SSC_CTRL0_3_PHSFT_A_OFFSET 7 -+#define RTL8367C_SSC_CTRL0_3_PHSFT_A_MASK 0x80 -+#define RTL8367C_SSC_CTRL0_3_PHSFT_B_OFFSET 6 -+#define RTL8367C_SSC_CTRL0_3_PHSFT_B_MASK 0x40 -+#define RTL8367C_SSC_CTRL0_3_PHSFT_UPDN_OFFSET 5 -+#define RTL8367C_SSC_CTRL0_3_PHSFT_UPDN_MASK 0x20 -+#define RTL8367C_SSC_CTRL0_3_PHSFT_PRD_OFFSET 4 -+#define RTL8367C_SSC_CTRL0_3_PHSFT_PRD_MASK 0x10 -+#define RTL8367C_SSC_CTRL0_3_PN_POLY_DEG_OFFSET 0 -+#define RTL8367C_SSC_CTRL0_3_PN_POLY_DEG_MASK 0xF -+ -+#define RTL8367C_REG_SSC_CTRL0_4 0x1d48 -+#define RTL8367C_SSC_CTRL0_4_SSC_UP1DN0_OFFSET 15 -+#define RTL8367C_SSC_CTRL0_4_SSC_UP1DN0_MASK 0x8000 -+#define RTL8367C_SSC_CTRL0_4_SSC_PERIOD_OFFSET 8 -+#define RTL8367C_SSC_CTRL0_4_SSC_PERIOD_MASK 0x7F00 -+#define RTL8367C_SSC_CTRL0_4_SSC_OFFSET_OFFSET 0 -+#define RTL8367C_SSC_CTRL0_4_SSC_OFFSET_MASK 0xFF -+ -+#define RTL8367C_REG_SSC_CTRL0_5 0x1d49 -+#define RTL8367C_SSC_CTRL0_5_PH_OFS_TOG_OFFSET 15 -+#define RTL8367C_SSC_CTRL0_5_PH_OFS_TOG_MASK 0x8000 -+#define RTL8367C_SSC_CTRL0_5_PH_OFS_OFFSET 10 -+#define RTL8367C_SSC_CTRL0_5_PH_OFS_MASK 0x7C00 -+#define RTL8367C_SSC_CTRL0_5_SSC_STEP_OFFSET 4 -+#define RTL8367C_SSC_CTRL0_5_SSC_STEP_MASK 0x3F0 -+#define RTL8367C_SSC_CTRL0_5_SSC_TEST_MODE_OFFSET 2 -+#define RTL8367C_SSC_CTRL0_5_SSC_TEST_MODE_MASK 0xC -+#define RTL8367C_SSC_CTRL0_5_SSC_PH_CFG_OFFSET 0 -+#define RTL8367C_SSC_CTRL0_5_SSC_PH_CFG_MASK 0x3 -+ -+#define RTL8367C_REG_SSC_STS0 0x1d4a -+#define RTL8367C_SSC_STS0_OFS_BUSY_OFFSET 13 -+#define RTL8367C_SSC_STS0_OFS_BUSY_MASK 0x2000 -+#define RTL8367C_SSC_STS0_OFS_TOTAL_R_OFFSET 8 -+#define RTL8367C_SSC_STS0_OFS_TOTAL_R_MASK 0x1F00 -+#define RTL8367C_SSC_STS0_CNT_GRY0_OFFSET 4 -+#define RTL8367C_SSC_STS0_CNT_GRY0_MASK 0xF0 -+#define RTL8367C_SSC_STS0_OFS_GRY0_OFFSET 0 -+#define RTL8367C_SSC_STS0_OFS_GRY0_MASK 0xF -+ -+#define RTL8367C_REG_SSC_CTRL1_0 0x1d4b -+#define RTL8367C_SSC_CTRL1_0_SSC_TYPE_OFFSET 13 -+#define RTL8367C_SSC_CTRL1_0_SSC_TYPE_MASK 0x2000 -+#define RTL8367C_SSC_CTRL1_0_PHASE_LIM_SEL_OFFSET 5 -+#define RTL8367C_SSC_CTRL1_0_PHASE_LIM_SEL_MASK 0x1FE0 -+#define RTL8367C_SSC_CTRL1_0_PHASE_LIM_EN_OFFSET 4 -+#define RTL8367C_SSC_CTRL1_0_PHASE_LIM_EN_MASK 0x10 -+#define RTL8367C_SSC_CTRL1_0_DLL_MODE_OFFSET 2 -+#define RTL8367C_SSC_CTRL1_0_DLL_MODE_MASK 0xC -+#define RTL8367C_SSC_CTRL1_0_SSC_EN_OFFSET 1 -+#define RTL8367C_SSC_CTRL1_0_SSC_EN_MASK 0x2 -+#define RTL8367C_SSC_CTRL1_0_SSC_MODE_OFFSET 0 -+#define RTL8367C_SSC_CTRL1_0_SSC_MODE_MASK 0x1 -+ -+#define RTL8367C_REG_SSC_RDM_SEED1 0x1d4c -+ -+#define RTL8367C_REG_SSC_PN_POLY_SEL1 0x1d4d -+ -+#define RTL8367C_REG_SSC_CTRL1_3 0x1d4e -+#define RTL8367C_SSC_CTRL1_3_PHSFT_CNT_OFFSET 8 -+#define RTL8367C_SSC_CTRL1_3_PHSFT_CNT_MASK 0x7F00 -+#define RTL8367C_SSC_CTRL1_3_PHSFT_A_OFFSET 7 -+#define RTL8367C_SSC_CTRL1_3_PHSFT_A_MASK 0x80 -+#define RTL8367C_SSC_CTRL1_3_PHSFT_B_OFFSET 6 -+#define RTL8367C_SSC_CTRL1_3_PHSFT_B_MASK 0x40 -+#define RTL8367C_SSC_CTRL1_3_PHSFT_UPDN_OFFSET 5 -+#define RTL8367C_SSC_CTRL1_3_PHSFT_UPDN_MASK 0x20 -+#define RTL8367C_SSC_CTRL1_3_PHSFT_PRD_OFFSET 4 -+#define RTL8367C_SSC_CTRL1_3_PHSFT_PRD_MASK 0x10 -+#define RTL8367C_SSC_CTRL1_3_PN_POLY_DEG_OFFSET 0 -+#define RTL8367C_SSC_CTRL1_3_PN_POLY_DEG_MASK 0xF -+ -+#define RTL8367C_REG_SSC_CTRL1_4 0x1d4f -+#define RTL8367C_SSC_CTRL1_4_SSC_UP1DN0_OFFSET 15 -+#define RTL8367C_SSC_CTRL1_4_SSC_UP1DN0_MASK 0x8000 -+#define RTL8367C_SSC_CTRL1_4_SSC_PERIOD_OFFSET 8 -+#define RTL8367C_SSC_CTRL1_4_SSC_PERIOD_MASK 0x7F00 -+#define RTL8367C_SSC_CTRL1_4_SSC_OFFSET_OFFSET 0 -+#define RTL8367C_SSC_CTRL1_4_SSC_OFFSET_MASK 0xFF -+ -+#define RTL8367C_REG_SSC_CTRL1_5 0x1d50 -+#define RTL8367C_SSC_CTRL1_5_PH_OFS_TOG_OFFSET 15 -+#define RTL8367C_SSC_CTRL1_5_PH_OFS_TOG_MASK 0x8000 -+#define RTL8367C_SSC_CTRL1_5_PH_OFS_OFFSET 10 -+#define RTL8367C_SSC_CTRL1_5_PH_OFS_MASK 0x7C00 -+#define RTL8367C_SSC_CTRL1_5_SSC_STEP_OFFSET 4 -+#define RTL8367C_SSC_CTRL1_5_SSC_STEP_MASK 0x3F0 -+#define RTL8367C_SSC_CTRL1_5_SSC_TEST_MODE_OFFSET 2 -+#define RTL8367C_SSC_CTRL1_5_SSC_TEST_MODE_MASK 0xC -+#define RTL8367C_SSC_CTRL1_5_SSC_PH_CFG_OFFSET 0 -+#define RTL8367C_SSC_CTRL1_5_SSC_PH_CFG_MASK 0x3 -+ -+#define RTL8367C_REG_SSC_STS1 0x1d51 -+#define RTL8367C_SSC_STS1_OFS_BUSY_OFFSET 13 -+#define RTL8367C_SSC_STS1_OFS_BUSY_MASK 0x2000 -+#define RTL8367C_SSC_STS1_OFS_TOTAL_R_OFFSET 8 -+#define RTL8367C_SSC_STS1_OFS_TOTAL_R_MASK 0x1F00 -+#define RTL8367C_SSC_STS1_CNT_GRY0_OFFSET 4 -+#define RTL8367C_SSC_STS1_CNT_GRY0_MASK 0xF0 -+#define RTL8367C_SSC_STS1_OFS_GRY0_OFFSET 0 -+#define RTL8367C_SSC_STS1_OFS_GRY0_MASK 0xF -+ -+#define RTL8367C_REG_SSC_CTRL2_0 0x1d52 -+#define RTL8367C_SSC_CTRL2_0_SSC_TYPE_OFFSET 13 -+#define RTL8367C_SSC_CTRL2_0_SSC_TYPE_MASK 0x2000 -+#define RTL8367C_SSC_CTRL2_0_PHASE_LIM_SEL_OFFSET 5 -+#define RTL8367C_SSC_CTRL2_0_PHASE_LIM_SEL_MASK 0x1FE0 -+#define RTL8367C_SSC_CTRL2_0_PHASE_LIM_EN_OFFSET 4 -+#define RTL8367C_SSC_CTRL2_0_PHASE_LIM_EN_MASK 0x10 -+#define RTL8367C_SSC_CTRL2_0_DLL_MODE_OFFSET 2 -+#define RTL8367C_SSC_CTRL2_0_DLL_MODE_MASK 0xC -+#define RTL8367C_SSC_CTRL2_0_SSC_EN_OFFSET 1 -+#define RTL8367C_SSC_CTRL2_0_SSC_EN_MASK 0x2 -+#define RTL8367C_SSC_CTRL2_0_SSC_MODE_OFFSET 0 -+#define RTL8367C_SSC_CTRL2_0_SSC_MODE_MASK 0x1 -+ -+#define RTL8367C_REG_SSC_RDM_SEED2 0x1d53 -+ -+#define RTL8367C_REG_SSC_PN_POLY_SEL2 0x1d54 -+ -+#define RTL8367C_REG_SSC_CTRL2_3 0x1d55 -+#define RTL8367C_SSC_CTRL2_3_PHSFT_CNT_OFFSET 8 -+#define RTL8367C_SSC_CTRL2_3_PHSFT_CNT_MASK 0x7F00 -+#define RTL8367C_SSC_CTRL2_3_PHSFT_A_OFFSET 7 -+#define RTL8367C_SSC_CTRL2_3_PHSFT_A_MASK 0x80 -+#define RTL8367C_SSC_CTRL2_3_PHSFT_B_OFFSET 6 -+#define RTL8367C_SSC_CTRL2_3_PHSFT_B_MASK 0x40 -+#define RTL8367C_SSC_CTRL2_3_PHSFT_UPDN_OFFSET 5 -+#define RTL8367C_SSC_CTRL2_3_PHSFT_UPDN_MASK 0x20 -+#define RTL8367C_SSC_CTRL2_3_PHSFT_PRD_OFFSET 4 -+#define RTL8367C_SSC_CTRL2_3_PHSFT_PRD_MASK 0x10 -+#define RTL8367C_SSC_CTRL2_3_PN_POLY_DEG_OFFSET 0 -+#define RTL8367C_SSC_CTRL2_3_PN_POLY_DEG_MASK 0xF -+ -+#define RTL8367C_REG_SSC_CTRL2_4 0x1d56 -+#define RTL8367C_SSC_CTRL2_4_SSC_UP1DN0_OFFSET 15 -+#define RTL8367C_SSC_CTRL2_4_SSC_UP1DN0_MASK 0x8000 -+#define RTL8367C_SSC_CTRL2_4_SSC_PERIOD_OFFSET 8 -+#define RTL8367C_SSC_CTRL2_4_SSC_PERIOD_MASK 0x7F00 -+#define RTL8367C_SSC_CTRL2_4_SSC_OFFSET_OFFSET 0 -+#define RTL8367C_SSC_CTRL2_4_SSC_OFFSET_MASK 0xFF -+ -+#define RTL8367C_REG_SSC_CTRL2_5 0x1d57 -+#define RTL8367C_SSC_CTRL2_5_PH_OFS_TOG_OFFSET 15 -+#define RTL8367C_SSC_CTRL2_5_PH_OFS_TOG_MASK 0x8000 -+#define RTL8367C_SSC_CTRL2_5_PH_OFS_OFFSET 10 -+#define RTL8367C_SSC_CTRL2_5_PH_OFS_MASK 0x7C00 -+#define RTL8367C_SSC_CTRL2_5_SSC_STEP_OFFSET 4 -+#define RTL8367C_SSC_CTRL2_5_SSC_STEP_MASK 0x3F0 -+#define RTL8367C_SSC_CTRL2_5_SSC_TEST_MODE_OFFSET 2 -+#define RTL8367C_SSC_CTRL2_5_SSC_TEST_MODE_MASK 0xC -+#define RTL8367C_SSC_CTRL2_5_SSC_PH_CFG_OFFSET 0 -+#define RTL8367C_SSC_CTRL2_5_SSC_PH_CFG_MASK 0x3 -+ -+#define RTL8367C_REG_SSC_STS2 0x1d58 -+#define RTL8367C_SSC_STS2_OFS_BUSY_OFFSET 13 -+#define RTL8367C_SSC_STS2_OFS_BUSY_MASK 0x2000 -+#define RTL8367C_SSC_STS2_OFS_TOTAL_R_OFFSET 8 -+#define RTL8367C_SSC_STS2_OFS_TOTAL_R_MASK 0x1F00 -+#define RTL8367C_SSC_STS2_CNT_GRY0_OFFSET 4 -+#define RTL8367C_SSC_STS2_CNT_GRY0_MASK 0xF0 -+#define RTL8367C_SSC_STS2_OFS_GRY0_OFFSET 0 -+#define RTL8367C_SSC_STS2_OFS_GRY0_MASK 0xF -+ -+#define RTL8367C_REG_SSC_CTRL3_0 0x1d59 -+#define RTL8367C_SSC_CTRL3_0_SSC_TYPE_OFFSET 13 -+#define RTL8367C_SSC_CTRL3_0_SSC_TYPE_MASK 0x2000 -+#define RTL8367C_SSC_CTRL3_0_PHASE_LIM_SEL_OFFSET 5 -+#define RTL8367C_SSC_CTRL3_0_PHASE_LIM_SEL_MASK 0x1FE0 -+#define RTL8367C_SSC_CTRL3_0_PHASE_LIM_EN_OFFSET 4 -+#define RTL8367C_SSC_CTRL3_0_PHASE_LIM_EN_MASK 0x10 -+#define RTL8367C_SSC_CTRL3_0_DLL_MODE_OFFSET 2 -+#define RTL8367C_SSC_CTRL3_0_DLL_MODE_MASK 0xC -+#define RTL8367C_SSC_CTRL3_0_SSC_EN_OFFSET 1 -+#define RTL8367C_SSC_CTRL3_0_SSC_EN_MASK 0x2 -+#define RTL8367C_SSC_CTRL3_0_SSC_MODE_OFFSET 0 -+#define RTL8367C_SSC_CTRL3_0_SSC_MODE_MASK 0x1 -+ -+#define RTL8367C_REG_SSC_RDM_SEED3 0x1d5a -+ -+#define RTL8367C_REG_SSC_PN_POLY_SEL3 0x1d5b -+ -+#define RTL8367C_REG_SSC_CTRL3_3 0x1d5c -+#define RTL8367C_SSC_CTRL3_3_PHSFT_CNT_OFFSET 8 -+#define RTL8367C_SSC_CTRL3_3_PHSFT_CNT_MASK 0x7F00 -+#define RTL8367C_SSC_CTRL3_3_PHSFT_A_OFFSET 7 -+#define RTL8367C_SSC_CTRL3_3_PHSFT_A_MASK 0x80 -+#define RTL8367C_SSC_CTRL3_3_PHSFT_B_OFFSET 6 -+#define RTL8367C_SSC_CTRL3_3_PHSFT_B_MASK 0x40 -+#define RTL8367C_SSC_CTRL3_3_PHSFT_UPDN_OFFSET 5 -+#define RTL8367C_SSC_CTRL3_3_PHSFT_UPDN_MASK 0x20 -+#define RTL8367C_SSC_CTRL3_3_PHSFT_PRD_OFFSET 4 -+#define RTL8367C_SSC_CTRL3_3_PHSFT_PRD_MASK 0x10 -+#define RTL8367C_SSC_CTRL3_3_PN_POLY_DEG_OFFSET 0 -+#define RTL8367C_SSC_CTRL3_3_PN_POLY_DEG_MASK 0xF -+ -+#define RTL8367C_REG_SSC_CTRL3_4 0x1d5d -+#define RTL8367C_SSC_CTRL3_4_SSC_UP1DN0_OFFSET 15 -+#define RTL8367C_SSC_CTRL3_4_SSC_UP1DN0_MASK 0x8000 -+#define RTL8367C_SSC_CTRL3_4_SSC_PERIOD_OFFSET 8 -+#define RTL8367C_SSC_CTRL3_4_SSC_PERIOD_MASK 0x7F00 -+#define RTL8367C_SSC_CTRL3_4_SSC_OFFSET_OFFSET 0 -+#define RTL8367C_SSC_CTRL3_4_SSC_OFFSET_MASK 0xFF -+ -+#define RTL8367C_REG_SSC_CTRL3_5 0x1d5e -+#define RTL8367C_SSC_CTRL3_5_PH_OFS_TOG_OFFSET 15 -+#define RTL8367C_SSC_CTRL3_5_PH_OFS_TOG_MASK 0x8000 -+#define RTL8367C_SSC_CTRL3_5_PH_OFS_OFFSET 10 -+#define RTL8367C_SSC_CTRL3_5_PH_OFS_MASK 0x7C00 -+#define RTL8367C_SSC_CTRL3_5_SSC_STEP_OFFSET 4 -+#define RTL8367C_SSC_CTRL3_5_SSC_STEP_MASK 0x3F0 -+#define RTL8367C_SSC_CTRL3_5_SSC_TEST_MODE_OFFSET 2 -+#define RTL8367C_SSC_CTRL3_5_SSC_TEST_MODE_MASK 0xC -+#define RTL8367C_SSC_CTRL3_5_SSC_PH_CFG_OFFSET 0 -+#define RTL8367C_SSC_CTRL3_5_SSC_PH_CFG_MASK 0x3 -+ -+#define RTL8367C_REG_SSC_STS3 0x1d5f -+#define RTL8367C_SSC_STS3_OFS_BUSY_OFFSET 13 -+#define RTL8367C_SSC_STS3_OFS_BUSY_MASK 0x2000 -+#define RTL8367C_SSC_STS3_OFS_TOTAL_R_OFFSET 8 -+#define RTL8367C_SSC_STS3_OFS_TOTAL_R_MASK 0x1F00 -+#define RTL8367C_SSC_STS3_CNT_GRY0_OFFSET 4 -+#define RTL8367C_SSC_STS3_CNT_GRY0_MASK 0xF0 -+#define RTL8367C_SSC_STS3_OFS_GRY0_OFFSET 0 -+#define RTL8367C_SSC_STS3_OFS_GRY0_MASK 0xF -+ -+#define RTL8367C_REG_PHY_POLL_CFG13 0x1d60 -+ -+#define RTL8367C_REG_PHY_POLL_CFG14 0x1d61 -+ -+#define RTL8367C_REG_FRC_SYS_CLK 0x1d62 -+#define RTL8367C_SYSCLK_FRC_MD_OFFSET 1 -+#define RTL8367C_SYSCLK_FRC_MD_MASK 0x2 -+#define RTL8367C_SYSCLK_FRC_VAL_OFFSET 0 -+#define RTL8367C_SYSCLK_FRC_VAL_MASK 0x1 -+ -+#define RTL8367C_REG_AFE_SSC_CTRL 0x1d63 -+#define RTL8367C_PH_RSTB_TXD1_OFFSET 9 -+#define RTL8367C_PH_RSTB_TXD1_MASK 0x200 -+#define RTL8367C_PH_RSTB_TXC1_OFFSET 8 -+#define RTL8367C_PH_RSTB_TXC1_MASK 0x100 -+#define RTL8367C_PH_RSTB_TXD0_OFFSET 7 -+#define RTL8367C_PH_RSTB_TXD0_MASK 0x80 -+#define RTL8367C_PH_RSTB_TXC0_OFFSET 6 -+#define RTL8367C_PH_RSTB_TXC0_MASK 0x40 -+#define RTL8367C_PH_RSTBSYS_OFFSET 5 -+#define RTL8367C_PH_RSTBSYS_MASK 0x20 -+#define RTL8367C_PH_RSTB8051_OFFSET 4 -+#define RTL8367C_PH_RSTB8051_MASK 0x10 -+#define RTL8367C_OREG_SSC_OFFSET 0 -+#define RTL8367C_OREG_SSC_MASK 0xF -+ -+#define RTL8367C_REG_BUFF_RST_CTRL0 0x1d64 -+#define RTL8367C_BUFFRST_TXESD_EN_OFFSET 13 -+#define RTL8367C_BUFFRST_TXESD_EN_MASK 0x2000 -+#define RTL8367C_BUFF_RST_TIME_LONG_OFFSET 8 -+#define RTL8367C_BUFF_RST_TIME_LONG_MASK 0x1F00 -+#define RTL8367C_BUFF_RST_TIME_SHORT_OFFSET 3 -+#define RTL8367C_BUFF_RST_TIME_SHORT_MASK 0xF8 -+#define RTL8367C_SW_BUFF_RST_OFFSET 2 -+#define RTL8367C_SW_BUFF_RST_MASK 0x4 -+#define RTL8367C_IMS_BUFF_RST_OFFSET 1 -+#define RTL8367C_IMS_BUFF_RST_MASK 0x2 -+#define RTL8367C_IMR_BUFF_RST_OFFSET 0 -+#define RTL8367C_IMR_BUFF_RST_MASK 0x1 -+ -+#define RTL8367C_REG_BUFF_RST_CTRL1 0x1d65 -+#define RTL8367C_BUFFRST_SYSOVER_EN_OFFSET 10 -+#define RTL8367C_BUFFRST_SYSOVER_EN_MASK 0x400 -+#define RTL8367C_BUFFRST_SYSOVER_THR_OFFSET 0 -+#define RTL8367C_BUFFRST_SYSOVER_THR_MASK 0x3FF -+ -+#define RTL8367C_REG_BUFF_RST_CTRL2 0x1d66 -+#define RTL8367C_BUFFRST_QOVER_EN_OFFSET 10 -+#define RTL8367C_BUFFRST_QOVER_EN_MASK 0x400 -+#define RTL8367C_BUFFRST_QOVER_THR_OFFSET 0 -+#define RTL8367C_BUFFRST_QOVER_THR_MASK 0x3FF -+ -+#define RTL8367C_REG_BUFF_RST_CTRL3 0x1d67 -+#define RTL8367C_DSC_TIMER_OFFSET 11 -+#define RTL8367C_DSC_TIMER_MASK 0x7800 -+#define RTL8367C_BUFFRST_DSCOVER_THR_OFFSET 1 -+#define RTL8367C_BUFFRST_DSCOVER_THR_MASK 0x7FE -+#define RTL8367C_BUFFRST_DSCOVER_EN_OFFSET 0 -+#define RTL8367C_BUFFRST_DSCOVER_EN_MASK 0x1 -+ -+#define RTL8367C_REG_BUFF_RST_CTRL4 0x1d68 -+#define RTL8367C_INDSC_TIMER_OFFSET 11 -+#define RTL8367C_INDSC_TIMER_MASK 0x7800 -+#define RTL8367C_BUFFRST_INDSCOVER_THR_OFFSET 1 -+#define RTL8367C_BUFFRST_INDSCOVER_THR_MASK 0x7FE -+#define RTL8367C_BUFFRST_INDSCOVER_EN_OFFSET 0 -+#define RTL8367C_BUFFRST_INDSCOVER_EN_MASK 0x1 -+ -+#define RTL8367C_REG_BUFF_RST_CTRL5 0x1d69 -+#define RTL8367C_TX_ESD_MODE_OFFSET 8 -+#define RTL8367C_TX_ESD_MODE_MASK 0x100 -+#define RTL8367C_TX_ESD_LVL_OFFSET 0 -+#define RTL8367C_TX_ESD_LVL_MASK 0xFF -+ -+#define RTL8367C_REG_TOP_CON0 0x1d70 -+#define RTL8367C_TOP_CON0_SDS_PWR_ISO_1_OFFSET 15 -+#define RTL8367C_TOP_CON0_SDS_PWR_ISO_1_MASK 0x8000 -+#define RTL8367C_OCP_TIMEOUT_P7_5_OFFSET 12 -+#define RTL8367C_OCP_TIMEOUT_P7_5_MASK 0x7000 -+#define RTL8367C_FIB_EEE_AB_OFFSET 11 -+#define RTL8367C_FIB_EEE_AB_MASK 0x800 -+#define RTL8367C_ADCCKIEN_OFFSET 10 -+#define RTL8367C_ADCCKIEN_MASK 0x400 -+#define RTL8367C_OCP_TIMEOUT_OFFSET 5 -+#define RTL8367C_OCP_TIMEOUT_MASK 0x3E0 -+#define RTL8367C_TOP_CON0_SDS_PWR_ISO_OFFSET 4 -+#define RTL8367C_TOP_CON0_SDS_PWR_ISO_MASK 0x10 -+#define RTL8367C_RG2_TXC_SEL_OFFSET 3 -+#define RTL8367C_RG2_TXC_SEL_MASK 0x8 -+#define RTL8367C_RG1TXC_SEL_OFFSET 2 -+#define RTL8367C_RG1TXC_SEL_MASK 0x4 -+#define RTL8367C_SYNC_1588_EN_OFFSET 1 -+#define RTL8367C_SYNC_1588_EN_MASK 0x2 -+#define RTL8367C_LS_MODE_OFFSET 0 -+#define RTL8367C_LS_MODE_MASK 0x1 -+ -+#define RTL8367C_REG_TOP_CON1 0x1d71 -+#define RTL8367C_TA_CHK_EN_OFFSET 2 -+#define RTL8367C_TA_CHK_EN_MASK 0x4 -+#define RTL8367C_SLV_EG_SEL_OFFSET 1 -+#define RTL8367C_SLV_EG_SEL_MASK 0x2 -+#define RTL8367C_IIC_OP_DRAIN_OFFSET 0 -+#define RTL8367C_IIC_OP_DRAIN_MASK 0x1 -+ -+#define RTL8367C_REG_SWR_FPWM 0x1d72 -+#define RTL8367C_SWR_FPWM_OFFSET 0 -+#define RTL8367C_SWR_FPWM_MASK 0x1 -+ -+#define RTL8367C_REG_EEEP_CTRL_500M 0x1d73 -+ -+#define RTL8367C_REG_SHORT_PRMB 0x1d74 -+#define RTL8367C_SHORT_PRMB_OFFSET 0 -+#define RTL8367C_SHORT_PRMB_MASK 0x1 -+ -+#define RTL8367C_REG_INDSC_THR_CTRL 0x1d75 -+#define RTL8367C_INDSC_THR_CTRL_OFFSET 0 -+#define RTL8367C_INDSC_THR_CTRL_MASK 0x7FF -+ -+#define RTL8367C_REG_SET_PAD_CTRL_NEW 0x1d80 -+#define RTL8367C_SET_PAD_CTRL_NEW_OFFSET 0 -+#define RTL8367C_SET_PAD_CTRL_NEW_MASK 0x1 -+ -+#define RTL8367C_REG_SET_PAD_DRI_0 0x1d81 -+ -+#define RTL8367C_REG_SET_PAD_DRI_1 0x1d82 -+ -+#define RTL8367C_REG_SET_PAD_DRI_2 0x1d83 -+ -+#define RTL8367C_REG_SET_PAD_SLEW_0 0x1d84 -+ -+#define RTL8367C_REG_SET_PAD_SLEW_1 0x1d85 -+ -+#define RTL8367C_REG_SET_PAD_SLEW_2 0x1d86 -+ -+#define RTL8367C_REG_SET_PAD_SMT_0 0x1d87 -+ -+#define RTL8367C_REG_SET_PAD_SMT_1 0x1d88 -+ -+#define RTL8367C_REG_SET_PAD_SMT_2 0x1d89 -+ -+#define RTL8367C_REG_M_I2C_CTL_STA_REG 0x1d8a -+#define RTL8367C_TX_RX_DATA_OFFSET 8 -+#define RTL8367C_TX_RX_DATA_MASK 0xFF00 -+#define RTL8367C_DUMB_RW_ERR_OFFSET 7 -+#define RTL8367C_DUMB_RW_ERR_MASK 0x80 -+#define RTL8367C_SLV_ACK_FLAG_OFFSET 6 -+#define RTL8367C_SLV_ACK_FLAG_MASK 0x40 -+#define RTL8367C_M_I2C_BUS_IDLE_OFFSET 5 -+#define RTL8367C_M_I2C_BUS_IDLE_MASK 0x20 -+#define RTL8367C_I2C_CMD_TYPE_OFFSET 1 -+#define RTL8367C_I2C_CMD_TYPE_MASK 0x1E -+#define RTL8367C_I2C_CMD_EXEC_OFFSET 0 -+#define RTL8367C_I2C_CMD_EXEC_MASK 0x1 -+ -+#define RTL8367C_REG_M_I2C_DUMB_RW_ADDR_0 0x1d8b -+ -+#define RTL8367C_REG_M_I2C_DUMB_RW_ADDR_1 0x1d8c -+ -+#define RTL8367C_REG_M_I2C_DUMB_RW_DATA_0 0x1d8d -+ -+#define RTL8367C_REG_M_I2C_DUMB_RW_DATA_1 0x1d8e -+ -+#define RTL8367C_REG_M_I2C_DUMB_RW_CTL 0x1d8f -+#define RTL8367C_DUMB_I2C_CTL_CODE_OFFSET 8 -+#define RTL8367C_DUMB_I2C_CTL_CODE_MASK 0x7F00 -+#define RTL8367C_DUMB_RW_I2C_FORMAT_OFFSET 4 -+#define RTL8367C_DUMB_RW_I2C_FORMAT_MASK 0x10 -+#define RTL8367C_DUMB_RW_DATA_MODE_OFFSET 2 -+#define RTL8367C_DUMB_RW_DATA_MODE_MASK 0xC -+#define RTL8367C_DUMB_RW_ADDR_MODE_OFFSET 0 -+#define RTL8367C_DUMB_RW_ADDR_MODE_MASK 0x3 -+ -+#define RTL8367C_REG_M_I2C_SYS_CTL 0x1d90 -+#define RTL8367C_M_I2C_SCL_IO_MUX_OFFSET 12 -+#define RTL8367C_M_I2C_SCL_IO_MUX_MASK 0x3000 -+#define RTL8367C_M_I2C_SDA_IO_MUX_OFFSET 10 -+#define RTL8367C_M_I2C_SDA_IO_MUX_MASK 0xC00 -+#define RTL8367C_M_I2C_SDA_OD_EN_OFFSET 9 -+#define RTL8367C_M_I2C_SDA_OD_EN_MASK 0x200 -+#define RTL8367C_M_I2C_SCL_OD_EN_OFFSET 8 -+#define RTL8367C_M_I2C_SCL_OD_EN_MASK 0x100 -+#define RTL8367C_M_I2C_SCL_F_DIV_OFFSET 0 -+#define RTL8367C_M_I2C_SCL_F_DIV_MASK 0xFF -+ -+#define RTL8367C_REG_HT_PB_SRAM_CTRL 0x1da0 -+#define RTL8367C_HTPB_RW_OFFSET 2 -+#define RTL8367C_HTPB_RW_MASK 0x4 -+#define RTL8367C_HTPB_SEL_OFFSET 1 -+#define RTL8367C_HTPB_SEL_MASK 0x2 -+#define RTL8367C_HTPB_CE_OFFSET 0 -+#define RTL8367C_HTPB_CE_MASK 0x1 -+ -+#define RTL8367C_REG_HT_PB_SRAM_ADDR 0x1da1 -+ -+#define RTL8367C_REG_HT_PB_SRAM_DIN0 0x1da2 -+ -+#define RTL8367C_REG_HT_PB_SRAM_DIN1 0x1da3 -+ -+#define RTL8367C_REG_HT_PB_SRAM_DOUT0 0x1da4 -+ -+#define RTL8367C_REG_HT_PB_SRAM_DOUT1 0x1da5 -+ -+#define RTL8367C_REG_PHY_STAT_0 0x1db0 -+ -+#define RTL8367C_REG_PHY_STAT_1 0x1db1 -+ -+#define RTL8367C_REG_PHY_STAT_2 0x1db2 -+ -+#define RTL8367C_REG_PHY_STAT_3 0x1db3 -+ -+#define RTL8367C_REG_PHY_STAT_4 0x1db4 -+ -+#define RTL8367C_REG_PHY_STAT_5 0x1db5 -+ -+#define RTL8367C_REG_PHY_STAT_6 0x1db6 -+ -+#define RTL8367C_REG_PHY_STAT_7 0x1db7 -+ -+#define RTL8367C_REG_SDS_STAT_0 0x1db8 -+ -+#define RTL8367C_REG_SDS_STAT_1 0x1db9 -+ -+#define RTL8367C_REG_MAC_LINK_STAT_0 0x1dba -+#define RTL8367C_MAC_LINK_STAT_CUR_0_OFFSET 8 -+#define RTL8367C_MAC_LINK_STAT_CUR_0_MASK 0xFF00 -+#define RTL8367C_MAC_LINK_STAT_LATCH_0_OFFSET 0 -+#define RTL8367C_MAC_LINK_STAT_LATCH_0_MASK 0xFF -+ -+#define RTL8367C_REG_MAC_LINK_STAT_1 0x1dbb -+#define RTL8367C_MAC_LINK_STAT_1_Reserved_OFFSET 6 -+#define RTL8367C_MAC_LINK_STAT_1_Reserved_MASK 0xFFC0 -+#define RTL8367C_MAC_LINK_STAT_CUR_1_OFFSET 3 -+#define RTL8367C_MAC_LINK_STAT_CUR_1_MASK 0x38 -+#define RTL8367C_MAC_LINK_STAT_LATCH_1_OFFSET 0 -+#define RTL8367C_MAC_LINK_STAT_LATCH_1_MASK 0x7 -+ -+#define RTL8367C_REG_MISC_CONTROL_1 0x1dc0 -+#define RTL8367C_P7_FB_CPL_OFFSET 2 -+#define RTL8367C_P7_FB_CPL_MASK 0x4 -+#define RTL8367C_P6_FB_CPL_OFFSET 1 -+#define RTL8367C_P6_FB_CPL_MASK 0x2 -+#define RTL8367C_P5_FB_CPL_OFFSET 0 -+#define RTL8367C_P5_FB_CPL_MASK 0x1 -+ -+#define RTL8367C_REG_SDS_MISC_1 0x1dc1 -+#define RTL8367C_CFG_SGMII_RXFC_1_OFFSET 14 -+#define RTL8367C_CFG_SGMII_RXFC_1_MASK 0x4000 -+#define RTL8367C_CFG_SGMII_TXFC_1_OFFSET 13 -+#define RTL8367C_CFG_SGMII_TXFC_1_MASK 0x2000 -+#define RTL8367C_CFG_MAC9_SEL_HSGMII_OFFSET 11 -+#define RTL8367C_CFG_MAC9_SEL_HSGMII_MASK 0x800 -+#define RTL8367C_CFG_SGMII_FDUP_1_OFFSET 10 -+#define RTL8367C_CFG_SGMII_FDUP_1_MASK 0x400 -+#define RTL8367C_CFG_SGMII_LINK_1_OFFSET 9 -+#define RTL8367C_CFG_SGMII_LINK_1_MASK 0x200 -+#define RTL8367C_CFG_SGMII_SPD_1_OFFSET 7 -+#define RTL8367C_CFG_SGMII_SPD_1_MASK 0x180 -+#define RTL8367C_CFG_MAC9_SEL_SGMII_OFFSET 6 -+#define RTL8367C_CFG_MAC9_SEL_SGMII_MASK 0x40 -+#define RTL8367C_CFG_SDS_MODE_14C_1_OFFSET 0 -+#define RTL8367C_CFG_SDS_MODE_14C_1_MASK 0x7 -+ -+#define RTL8367C_REG_FIBER_CFG_2_1 0x1dc2 -+#define RTL8367C_SDS_RX_DISABLE_1_OFFSET 6 -+#define RTL8367C_SDS_RX_DISABLE_1_MASK 0xC0 -+#define RTL8367C_SDS_TX_DISABLE_1_OFFSET 4 -+#define RTL8367C_SDS_TX_DISABLE_1_MASK 0x30 -+#define RTL8367C_FIBER_CFG_2_1_SDS_PWR_ISO_1_OFFSET 2 -+#define RTL8367C_FIBER_CFG_2_1_SDS_PWR_ISO_1_MASK 0xC -+#define RTL8367C_SDS_FRC_LD_1_OFFSET 0 -+#define RTL8367C_SDS_FRC_LD_1_MASK 0x3 -+ -+#define RTL8367C_REG_FIBER_CFG_1_1 0x1dc3 -+#define RTL8367C_SDS_FRC_REG4_1_OFFSET 12 -+#define RTL8367C_SDS_FRC_REG4_1_MASK 0x1000 -+#define RTL8367C_SDS_FRC_REG4_FIB100_1_OFFSET 11 -+#define RTL8367C_SDS_FRC_REG4_FIB100_1_MASK 0x800 -+#define RTL8367C_SDS_FRC_MODE_1_OFFSET 3 -+#define RTL8367C_SDS_FRC_MODE_1_MASK 0x8 -+#define RTL8367C_SDS_MODE_1_OFFSET 0 -+#define RTL8367C_SDS_MODE_1_MASK 0x7 -+ -+#define RTL8367C_REG_PHYSTS_CTRL0_1 0x1dc4 -+#define RTL8367C_LNKUP_DLY_EN_EXT2_OFFSET 9 -+#define RTL8367C_LNKUP_DLY_EN_EXT2_MASK 0x200 -+#define RTL8367C_GE_100M_LNKUP_DLY_EXT2_OFFSET 7 -+#define RTL8367C_GE_100M_LNKUP_DLY_EXT2_MASK 0x180 -+#define RTL8367C_PHYSTS_10M_LNKUP_DLY_EXT2_OFFSET 5 -+#define RTL8367C_PHYSTS_10M_LNKUP_DLY_EXT2_MASK 0x60 -+#define RTL8367C_LNKUP_DLY_EN_EXT1_OFFSET 4 -+#define RTL8367C_LNKUP_DLY_EN_EXT1_MASK 0x10 -+#define RTL8367C_GE_100M_LNKUP_DLY_EXT1_OFFSET 2 -+#define RTL8367C_GE_100M_LNKUP_DLY_EXT1_MASK 0xC -+#define RTL8367C_PHYSTS_10M_LNKUP_DLY_EXT1_OFFSET 0 -+#define RTL8367C_PHYSTS_10M_LNKUP_DLY_EXT1_MASK 0x3 -+ -+#define RTL8367C_REG_FIBER_CFG_3_1 0x1dc5 -+#define RTL8367C_FIBER_CFG_3_1_OFFSET 0 -+#define RTL8367C_FIBER_CFG_3_1_MASK 0xFFF -+ -+#define RTL8367C_REG_FIBER_CFG_4_1 0x1dc6 -+ -+#define RTL8367C_REG_BUFF_RST_CTRL2_2 0x1dc7 -+#define RTL8367C_Cfg_buffrst_sysover_thr_1_OFFSET 3 -+#define RTL8367C_Cfg_buffrst_sysover_thr_1_MASK 0x8 -+#define RTL8367C_Cfg_buffrst_qover_thr_OFFSET 2 -+#define RTL8367C_Cfg_buffrst_qover_thr_MASK 0x4 -+#define RTL8367C_Cfg_buffrst_indscover_thr_1_OFFSET 1 -+#define RTL8367C_Cfg_buffrst_indscover_thr_1_MASK 0x2 -+#define RTL8367C_Cfg_buffrst_dscover_thr_1_OFFSET 0 -+#define RTL8367C_Cfg_buffrst_dscover_thr_1_MASK 0x1 -+ -+#define RTL8367C_REG_PHY_DEBUG_CNT_CTRL 0x1dc8 -+#define RTL8367C_PHY_MIB_RST_7_OFFSET 15 -+#define RTL8367C_PHY_MIB_RST_7_MASK 0x8000 -+#define RTL8367C_PHY_MIB_RST_6_OFFSET 14 -+#define RTL8367C_PHY_MIB_RST_6_MASK 0x4000 -+#define RTL8367C_PHY_MIB_RST_5_OFFSET 13 -+#define RTL8367C_PHY_MIB_RST_5_MASK 0x2000 -+#define RTL8367C_PHY_MIB_RST_4_OFFSET 12 -+#define RTL8367C_PHY_MIB_RST_4_MASK 0x1000 -+#define RTL8367C_PHY_MIB_RST_3_OFFSET 11 -+#define RTL8367C_PHY_MIB_RST_3_MASK 0x800 -+#define RTL8367C_PHY_MIB_RST_2_OFFSET 10 -+#define RTL8367C_PHY_MIB_RST_2_MASK 0x400 -+#define RTL8367C_PHY_MIB_RST_1_OFFSET 9 -+#define RTL8367C_PHY_MIB_RST_1_MASK 0x200 -+#define RTL8367C_PHY_MIB_RST_0_OFFSET 8 -+#define RTL8367C_PHY_MIB_RST_0_MASK 0x100 -+#define RTL8367C_PHY_MIB_EN_7_OFFSET 7 -+#define RTL8367C_PHY_MIB_EN_7_MASK 0x80 -+#define RTL8367C_PHY_MIB_EN_6_OFFSET 6 -+#define RTL8367C_PHY_MIB_EN_6_MASK 0x40 -+#define RTL8367C_PHY_MIB_EN_5_OFFSET 5 -+#define RTL8367C_PHY_MIB_EN_5_MASK 0x20 -+#define RTL8367C_PHY_MIB_EN_4_OFFSET 4 -+#define RTL8367C_PHY_MIB_EN_4_MASK 0x10 -+#define RTL8367C_PHY_MIB_EN_3_OFFSET 3 -+#define RTL8367C_PHY_MIB_EN_3_MASK 0x8 -+#define RTL8367C_PHY_MIB_EN_2_OFFSET 2 -+#define RTL8367C_PHY_MIB_EN_2_MASK 0x4 -+#define RTL8367C_PHY_MIB_EN_1_OFFSET 1 -+#define RTL8367C_PHY_MIB_EN_1_MASK 0x2 -+#define RTL8367C_PHY_MIB_EN_0_OFFSET 0 -+#define RTL8367C_PHY_MIB_EN_0_MASK 0x1 -+ -+#define RTL8367C_REG_TXPKT_CNT_L_0 0x1dc9 -+ -+#define RTL8367C_REG_TXPKT_CNT_H_0 0x1dca -+ -+#define RTL8367C_REG_RXPKT_CNT_L_0 0x1dcb -+ -+#define RTL8367C_REG_RXPKT_CNT_H_0 0x1dcc -+ -+#define RTL8367C_REG_TX_CRC_0 0x1dcd -+ -+#define RTL8367C_REG_RX_CRC_0 0x1dce -+ -+#define RTL8367C_REG_TXPKT_CNT_L_1 0x1dcf -+ -+#define RTL8367C_REG_TXPKT_CNT_H_1 0x1dd0 -+ -+#define RTL8367C_REG_RXPKT_CNT_L_1 0x1dd1 -+ -+#define RTL8367C_REG_RXPKT_CNT_H_1 0x1dd2 -+ -+#define RTL8367C_REG_TX_CRC_1 0x1dd3 -+ -+#define RTL8367C_REG_RX_CRC_1 0x1dd4 -+ -+#define RTL8367C_REG_TXPKT_CNT_L_2 0x1dd5 -+ -+#define RTL8367C_REG_TXPKT_CNT_H_2 0x1dd6 -+ -+#define RTL8367C_REG_RXPKT_CNT_L_2 0x1dd7 -+ -+#define RTL8367C_REG_RXPKT_CNT_H_2 0x1dd8 -+ -+#define RTL8367C_REG_TX_CRC_2 0x1dd9 -+ -+#define RTL8367C_REG_RX_CRC_2 0x1dda -+ -+#define RTL8367C_REG_TXPKT_CNT_L_3 0x1ddb -+ -+#define RTL8367C_REG_TXPKT_CNT_H_3 0x1ddc -+ -+#define RTL8367C_REG_RXPKT_CNT_L_3 0x1ddd -+ -+#define RTL8367C_REG_RXPKT_CNT_H_3 0x1dde -+ -+#define RTL8367C_REG_TX_CRC_3 0x1ddf -+ -+#define RTL8367C_REG_RX_CRC_3 0x1de0 -+ -+#define RTL8367C_REG_TXPKT_CNT_L_4 0x1de1 -+ -+#define RTL8367C_REG_TXPKT_CNT_H_4 0x1de2 -+ -+#define RTL8367C_REG_RXPKT_CNT_L_4 0x1de3 -+ -+#define RTL8367C_REG_RXPKT_CNT_H_4 0x1de4 -+ -+#define RTL8367C_REG_TX_CRC_4 0x1de5 -+ -+#define RTL8367C_REG_RX_CRC_4 0x1de6 -+ -+#define RTL8367C_REG_TXPKT_CNT_L_5 0x1de7 -+ -+#define RTL8367C_REG_TXPKT_CNT_H_5 0x1de8 -+ -+#define RTL8367C_REG_RXPKT_CNT_L_5 0x1de9 -+ -+#define RTL8367C_REG_RXPKT_CNT_H_5 0x1dea -+ -+#define RTL8367C_REG_TX_CRC_5 0x1deb -+ -+#define RTL8367C_REG_RX_CRC_5 0x1dec -+ -+#define RTL8367C_REG_TXPKT_CNT_L_6 0x1ded -+ -+#define RTL8367C_REG_TXPKT_CNT_H_6 0x1dee -+ -+#define RTL8367C_REG_RXPKT_CNT_L_6 0x1def -+ -+#define RTL8367C_REG_RXPKT_CNT_H_6 0x1df0 -+ -+#define RTL8367C_REG_TX_CRC_6 0x1df1 -+ -+#define RTL8367C_REG_RX_CRC_6 0x1df2 -+ -+#define RTL8367C_REG_TXPKT_CNT_L_7 0x1df3 -+ -+#define RTL8367C_REG_TXPKT_CNT_H_7 0x1df4 -+ -+#define RTL8367C_REG_RXPKT_CNT_L_7 0x1df5 -+ -+#define RTL8367C_REG_RXPKT_CNT_H_7 0x1df6 -+ -+#define RTL8367C_REG_TX_CRC_7 0x1df7 -+ -+#define RTL8367C_REG_RX_CRC_7 0x1df8 -+ -+#define RTL8367C_REG_BOND_DBG_0 0x1df9 -+ -+#define RTL8367C_REG_BOND_DBG_1 0x1dfa -+ -+#define RTL8367C_REG_STRP_DBG_0 0x1dfb -+ -+#define RTL8367C_REG_STRP_DBG_1 0x1dfc -+ -+#define RTL8367C_REG_STRP_DBG_2 0x1dfd -+ -+/* (16'h1f00)patch_reg */ -+ -+#define RTL8367C_REG_INDRECT_ACCESS_CTRL 0x1f00 -+#define RTL8367C_RW_OFFSET 1 -+#define RTL8367C_RW_MASK 0x2 -+#define RTL8367C_CMD_OFFSET 0 -+#define RTL8367C_CMD_MASK 0x1 -+ -+#define RTL8367C_REG_INDRECT_ACCESS_STATUS 0x1f01 -+#define RTL8367C_INDRECT_ACCESS_STATUS_OFFSET 2 -+#define RTL8367C_INDRECT_ACCESS_STATUS_MASK 0x7 -+ -+#define RTL8367C_REG_INDRECT_ACCESS_ADDRESS 0x1f02 -+ -+#define RTL8367C_REG_INDRECT_ACCESS_WRITE_DATA 0x1f03 -+ -+#define RTL8367C_REG_INDRECT_ACCESS_READ_DATA 0x1f04 -+ -+/* (16'h6200)fib_page */ -+ -+#define RTL8367C_REG_FIB0_CFG00 0x6200 -+#define RTL8367C_FIB0_CFG00_CFG_FIB_RST_OFFSET 15 -+#define RTL8367C_FIB0_CFG00_CFG_FIB_RST_MASK 0x8000 -+#define RTL8367C_FIB0_CFG00_CFG_FIB_LPK_OFFSET 14 -+#define RTL8367C_FIB0_CFG00_CFG_FIB_LPK_MASK 0x4000 -+#define RTL8367C_FIB0_CFG00_CFG_FIB_SPD_RD_0_OFFSET 13 -+#define RTL8367C_FIB0_CFG00_CFG_FIB_SPD_RD_0_MASK 0x2000 -+#define RTL8367C_FIB0_CFG00_CFG_FIB_ANEN_OFFSET 12 -+#define RTL8367C_FIB0_CFG00_CFG_FIB_ANEN_MASK 0x1000 -+#define RTL8367C_FIB0_CFG00_CFG_FIB_PDOWN_OFFSET 11 -+#define RTL8367C_FIB0_CFG00_CFG_FIB_PDOWN_MASK 0x800 -+#define RTL8367C_FIB0_CFG00_CFG_FIB_ISO_OFFSET 10 -+#define RTL8367C_FIB0_CFG00_CFG_FIB_ISO_MASK 0x400 -+#define RTL8367C_FIB0_CFG00_CFG_FIB_RESTART_OFFSET 9 -+#define RTL8367C_FIB0_CFG00_CFG_FIB_RESTART_MASK 0x200 -+#define RTL8367C_FIB0_CFG00_CFG_FIB_FULLDUP_OFFSET 8 -+#define RTL8367C_FIB0_CFG00_CFG_FIB_FULLDUP_MASK 0x100 -+#define RTL8367C_FIB0_CFG00_CFG_FIB_SPD_RD_1_OFFSET 6 -+#define RTL8367C_FIB0_CFG00_CFG_FIB_SPD_RD_1_MASK 0x40 -+#define RTL8367C_FIB0_CFG00_CFG_FIB_FRCTX_OFFSET 5 -+#define RTL8367C_FIB0_CFG00_CFG_FIB_FRCTX_MASK 0x20 -+ -+#define RTL8367C_REG_FIB0_CFG01 0x6201 -+#define RTL8367C_FIB0_CFG01_CAPBILITY_OFFSET 6 -+#define RTL8367C_FIB0_CFG01_CAPBILITY_MASK 0xFFC0 -+#define RTL8367C_FIB0_CFG01_AN_COMPLETE_OFFSET 5 -+#define RTL8367C_FIB0_CFG01_AN_COMPLETE_MASK 0x20 -+#define RTL8367C_FIB0_CFG01_R_FAULT_OFFSET 4 -+#define RTL8367C_FIB0_CFG01_R_FAULT_MASK 0x10 -+#define RTL8367C_FIB0_CFG01_NWAY_ABILITY_OFFSET 3 -+#define RTL8367C_FIB0_CFG01_NWAY_ABILITY_MASK 0x8 -+#define RTL8367C_FIB0_CFG01_LINK_STATUS_OFFSET 2 -+#define RTL8367C_FIB0_CFG01_LINK_STATUS_MASK 0x4 -+#define RTL8367C_FIB0_CFG01_JABBER_DETECT_OFFSET 1 -+#define RTL8367C_FIB0_CFG01_JABBER_DETECT_MASK 0x2 -+#define RTL8367C_FIB0_CFG01_EXTENDED_CAPBILITY_OFFSET 0 -+#define RTL8367C_FIB0_CFG01_EXTENDED_CAPBILITY_MASK 0x1 -+ -+#define RTL8367C_REG_FIB0_CFG02 0x6202 -+ -+#define RTL8367C_REG_FIB0_CFG03 0x6203 -+#define RTL8367C_FIB0_CFG03_REALTEK_OUI5_0_OFFSET 10 -+#define RTL8367C_FIB0_CFG03_REALTEK_OUI5_0_MASK 0xFC00 -+#define RTL8367C_FIB0_CFG03_MODEL_NO_OFFSET 4 -+#define RTL8367C_FIB0_CFG03_MODEL_NO_MASK 0x3F0 -+#define RTL8367C_FIB0_CFG03_REVISION_NO_OFFSET 0 -+#define RTL8367C_FIB0_CFG03_REVISION_NO_MASK 0xF -+ -+#define RTL8367C_REG_FIB0_CFG04 0x6204 -+ -+#define RTL8367C_REG_FIB0_CFG05 0x6205 -+ -+#define RTL8367C_REG_FIB0_CFG06 0x6206 -+#define RTL8367C_FIB0_CFG06_FIB_NP_EN_OFFSET 2 -+#define RTL8367C_FIB0_CFG06_FIB_NP_EN_MASK 0x4 -+#define RTL8367C_FIB0_CFG06_RXPAGE_OFFSET 1 -+#define RTL8367C_FIB0_CFG06_RXPAGE_MASK 0x2 -+ -+#define RTL8367C_REG_FIB0_CFG07 0x6207 -+ -+#define RTL8367C_REG_FIB0_CFG08 0x6208 -+ -+#define RTL8367C_REG_FIB0_CFG09 0x6209 -+ -+#define RTL8367C_REG_FIB0_CFG10 0x620a -+ -+#define RTL8367C_REG_FIB0_CFG11 0x620b -+ -+#define RTL8367C_REG_FIB0_CFG12 0x620c -+ -+#define RTL8367C_REG_FIB0_CFG13 0x620d -+#define RTL8367C_FIB0_CFG13_INDR_FUNC_OFFSET 14 -+#define RTL8367C_FIB0_CFG13_INDR_FUNC_MASK 0xC000 -+#define RTL8367C_FIB0_CFG13_DUMMY_OFFSET 5 -+#define RTL8367C_FIB0_CFG13_DUMMY_MASK 0x3FE0 -+#define RTL8367C_FIB0_CFG13_INDR_DEVAD_OFFSET 0 -+#define RTL8367C_FIB0_CFG13_INDR_DEVAD_MASK 0x1F -+ -+#define RTL8367C_REG_FIB0_CFG14 0x620e -+ -+#define RTL8367C_REG_FIB0_CFG15 0x620f -+ -+#define RTL8367C_REG_FIB1_CFG00 0x6210 -+#define RTL8367C_FIB1_CFG00_CFG_FIB_RST_OFFSET 15 -+#define RTL8367C_FIB1_CFG00_CFG_FIB_RST_MASK 0x8000 -+#define RTL8367C_FIB1_CFG00_CFG_FIB_LPK_OFFSET 14 -+#define RTL8367C_FIB1_CFG00_CFG_FIB_LPK_MASK 0x4000 -+#define RTL8367C_FIB1_CFG00_CFG_FIB_SPD_RD_0_OFFSET 13 -+#define RTL8367C_FIB1_CFG00_CFG_FIB_SPD_RD_0_MASK 0x2000 -+#define RTL8367C_FIB1_CFG00_CFG_FIB_ANEN_OFFSET 12 -+#define RTL8367C_FIB1_CFG00_CFG_FIB_ANEN_MASK 0x1000 -+#define RTL8367C_FIB1_CFG00_CFG_FIB_PDOWN_OFFSET 11 -+#define RTL8367C_FIB1_CFG00_CFG_FIB_PDOWN_MASK 0x800 -+#define RTL8367C_FIB1_CFG00_CFG_FIB_ISO_OFFSET 10 -+#define RTL8367C_FIB1_CFG00_CFG_FIB_ISO_MASK 0x400 -+#define RTL8367C_FIB1_CFG00_CFG_FIB_RESTART_OFFSET 9 -+#define RTL8367C_FIB1_CFG00_CFG_FIB_RESTART_MASK 0x200 -+#define RTL8367C_FIB1_CFG00_CFG_FIB_FULLDUP_OFFSET 8 -+#define RTL8367C_FIB1_CFG00_CFG_FIB_FULLDUP_MASK 0x100 -+#define RTL8367C_FIB1_CFG00_CFG_FIB_SPD_RD_1_OFFSET 6 -+#define RTL8367C_FIB1_CFG00_CFG_FIB_SPD_RD_1_MASK 0x40 -+#define RTL8367C_FIB1_CFG00_CFG_FIB_FRCTX_OFFSET 5 -+#define RTL8367C_FIB1_CFG00_CFG_FIB_FRCTX_MASK 0x20 -+ -+#define RTL8367C_REG_FIB1_CFG01 0x6211 -+#define RTL8367C_FIB1_CFG01_CAPBILITY_OFFSET 6 -+#define RTL8367C_FIB1_CFG01_CAPBILITY_MASK 0xFFC0 -+#define RTL8367C_FIB1_CFG01_AN_COMPLETE_OFFSET 5 -+#define RTL8367C_FIB1_CFG01_AN_COMPLETE_MASK 0x20 -+#define RTL8367C_FIB1_CFG01_R_FAULT_OFFSET 4 -+#define RTL8367C_FIB1_CFG01_R_FAULT_MASK 0x10 -+#define RTL8367C_FIB1_CFG01_NWAY_ABILITY_OFFSET 3 -+#define RTL8367C_FIB1_CFG01_NWAY_ABILITY_MASK 0x8 -+#define RTL8367C_FIB1_CFG01_LINK_STATUS_OFFSET 2 -+#define RTL8367C_FIB1_CFG01_LINK_STATUS_MASK 0x4 -+#define RTL8367C_FIB1_CFG01_JABBER_DETECT_OFFSET 1 -+#define RTL8367C_FIB1_CFG01_JABBER_DETECT_MASK 0x2 -+#define RTL8367C_FIB1_CFG01_EXTENDED_CAPBILITY_OFFSET 0 -+#define RTL8367C_FIB1_CFG01_EXTENDED_CAPBILITY_MASK 0x1 -+ -+#define RTL8367C_REG_FIB1_CFG02 0x6212 -+ -+#define RTL8367C_REG_FIB1_CFG03 0x6213 -+#define RTL8367C_FIB1_CFG03_REALTEK_OUI5_0_OFFSET 10 -+#define RTL8367C_FIB1_CFG03_REALTEK_OUI5_0_MASK 0xFC00 -+#define RTL8367C_FIB1_CFG03_MODEL_NO_OFFSET 4 -+#define RTL8367C_FIB1_CFG03_MODEL_NO_MASK 0x3F0 -+#define RTL8367C_FIB1_CFG03_REVISION_NO_OFFSET 0 -+#define RTL8367C_FIB1_CFG03_REVISION_NO_MASK 0xF -+ -+#define RTL8367C_REG_FIB1_CFG04 0x6214 -+ -+#define RTL8367C_REG_FIB1_CFG05 0x6215 -+ -+#define RTL8367C_REG_FIB1_CFG06 0x6216 -+#define RTL8367C_FIB1_CFG06_FIB_NP_EN_OFFSET 2 -+#define RTL8367C_FIB1_CFG06_FIB_NP_EN_MASK 0x4 -+#define RTL8367C_FIB1_CFG06_RXPAGE_OFFSET 1 -+#define RTL8367C_FIB1_CFG06_RXPAGE_MASK 0x2 -+ -+#define RTL8367C_REG_FIB1_CFG07 0x6217 -+ -+#define RTL8367C_REG_FIB1_CFG08 0x6218 -+ -+#define RTL8367C_REG_FIB1_CFG09 0x6219 -+ -+#define RTL8367C_REG_FIB1_CFG10 0x621a -+ -+#define RTL8367C_REG_FIB1_CFG11 0x621b -+ -+#define RTL8367C_REG_FIB1_CFG12 0x621c -+ -+#define RTL8367C_REG_FIB1_CFG13 0x621d -+#define RTL8367C_FIB1_CFG13_INDR_FUNC_OFFSET 14 -+#define RTL8367C_FIB1_CFG13_INDR_FUNC_MASK 0xC000 -+#define RTL8367C_FIB1_CFG13_DUMMY_OFFSET 5 -+#define RTL8367C_FIB1_CFG13_DUMMY_MASK 0x3FE0 -+#define RTL8367C_FIB1_CFG13_INDR_DEVAD_OFFSET 0 -+#define RTL8367C_FIB1_CFG13_INDR_DEVAD_MASK 0x1F -+ -+#define RTL8367C_REG_FIB1_CFG14 0x621e -+ -+#define RTL8367C_REG_FIB1_CFG15 0x621f -+ -+/* (16'h6400)timer_1588 */ -+ -+#define RTL8367C_REG_PTP_TIME_NSEC_L_NSEC 0x6400 -+ -+#define RTL8367C_REG_PTP_TIME_NSEC_H_NSEC 0x6401 -+#define RTL8367C_PTP_TIME_NSEC_H_EXEC_OFFSET 15 -+#define RTL8367C_PTP_TIME_NSEC_H_EXEC_MASK 0x8000 -+#define RTL8367C_PTP_TIME_NSEC_H_CMD_OFFSET 12 -+#define RTL8367C_PTP_TIME_NSEC_H_CMD_MASK 0x3000 -+#define RTL8367C_PTP_TIME_NSEC_H_NSEC_OFFSET 0 -+#define RTL8367C_PTP_TIME_NSEC_H_NSEC_MASK 0x7FF -+ -+#define RTL8367C_REG_PTP_TIME_SEC_L_SEC 0x6402 -+ -+#define RTL8367C_REG_PTP_TIME_SEC_H_SEC 0x6403 -+ -+#define RTL8367C_REG_PTP_TIME_CFG 0x6404 -+#define RTL8367C_CFG_TIMER_EN_FRC_OFFSET 2 -+#define RTL8367C_CFG_TIMER_EN_FRC_MASK 0x4 -+#define RTL8367C_CFG_TIMER_1588_EN_OFFSET 1 -+#define RTL8367C_CFG_TIMER_1588_EN_MASK 0x2 -+#define RTL8367C_CFG_CLK_SRC_OFFSET 0 -+#define RTL8367C_CFG_CLK_SRC_MASK 0x1 -+ -+#define RTL8367C_REG_OTAG_TPID 0x6405 -+ -+#define RTL8367C_REG_ITAG_TPID 0x6406 -+ -+#define RTL8367C_REG_MAC_ADDR_L 0x6407 -+ -+#define RTL8367C_REG_MAC_ADDR_M 0x6408 -+ -+#define RTL8367C_REG_MAC_ADDR_H 0x6409 -+ -+#define RTL8367C_REG_PTP_TIME_NSEC_L_NSEC_RD 0x640a -+ -+#define RTL8367C_REG_PTP_TIME_NSEC_H_NSEC_RD 0x640b -+#define RTL8367C_PTP_TIME_NSEC_H_NSEC_RD_OFFSET 0 -+#define RTL8367C_PTP_TIME_NSEC_H_NSEC_RD_MASK 0x7FF -+ -+#define RTL8367C_REG_PTP_TIME_SEC_L_SEC_RD 0x640c -+ -+#define RTL8367C_REG_PTP_TIME_SEC_H_SEC_RD 0x640d -+ -+#define RTL8367C_REG_PTP_TIME_CFG2 0x640e -+#define RTL8367C_CFG_EN_OFFLOAD_OFFSET 9 -+#define RTL8367C_CFG_EN_OFFLOAD_MASK 0x200 -+#define RTL8367C_CFG_SAVE_OFF_TS_OFFSET 8 -+#define RTL8367C_CFG_SAVE_OFF_TS_MASK 0x100 -+#define RTL8367C_CFG_IMR_OFFSET 0 -+#define RTL8367C_CFG_IMR_MASK 0xFF -+ -+#define RTL8367C_REG_PTP_INTERRUPT_CFG 0x640f -+#define RTL8367C_P9_INTERRUPT_OFFSET 9 -+#define RTL8367C_P9_INTERRUPT_MASK 0x200 -+#define RTL8367C_P8_INTERRUPT_OFFSET 8 -+#define RTL8367C_P8_INTERRUPT_MASK 0x100 -+#define RTL8367C_P7_INTERRUPT_OFFSET 7 -+#define RTL8367C_P7_INTERRUPT_MASK 0x80 -+#define RTL8367C_P6_INTERRUPT_OFFSET 6 -+#define RTL8367C_P6_INTERRUPT_MASK 0x40 -+#define RTL8367C_P5_INTERRUPT_OFFSET 5 -+#define RTL8367C_P5_INTERRUPT_MASK 0x20 -+#define RTL8367C_P4_INTERRUPT_OFFSET 4 -+#define RTL8367C_P4_INTERRUPT_MASK 0x10 -+#define RTL8367C_P3_INTERRUPT_OFFSET 3 -+#define RTL8367C_P3_INTERRUPT_MASK 0x8 -+#define RTL8367C_P2_INTERRUPT_OFFSET 2 -+#define RTL8367C_P2_INTERRUPT_MASK 0x4 -+#define RTL8367C_P1_INTERRUPT_OFFSET 1 -+#define RTL8367C_P1_INTERRUPT_MASK 0x2 -+#define RTL8367C_P0_INTERRUPT_OFFSET 0 -+#define RTL8367C_P0_INTERRUPT_MASK 0x1 -+ -+#define RTL8367C_REG_P0_TX_SYNC_SEQ_ID 0x6410 -+ -+#define RTL8367C_REG_P0_TX_DELAY_REQ_SEQ_ID 0x6411 -+ -+#define RTL8367C_REG_P0_TX_PDELAY_REQ_SEQ_ID 0x6412 -+ -+#define RTL8367C_REG_P0_TX_PDELAY_RESP_SEQ_ID 0x6413 -+ -+#define RTL8367C_REG_P0_RX_SYNC_SEQ_ID 0x6414 -+ -+#define RTL8367C_REG_P0_RX_DELAY_REQ_SEQ_ID 0x6415 -+ -+#define RTL8367C_REG_P0_RX_PDELAY_REQ_SEQ_ID 0x6416 -+ -+#define RTL8367C_REG_P0_RX_PDELAY_RESP_SEQ_ID 0x6417 -+ -+#define RTL8367C_REG_P0_PORT_NSEC_15_0 0x6418 -+ -+#define RTL8367C_REG_P0_PORT_NSEC_26_16 0x6419 -+#define RTL8367C_P0_PORT_NSEC_26_16_OFFSET 0 -+#define RTL8367C_P0_PORT_NSEC_26_16_MASK 0x7FF -+ -+#define RTL8367C_REG_P0_PORT_SEC_15_0 0x641a -+ -+#define RTL8367C_REG_P0_PORT_SEC_31_16 0x641b -+ -+#define RTL8367C_REG_P0_EAV_CFG 0x641c -+#define RTL8367C_P0_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 -+#define RTL8367C_P0_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 -+#define RTL8367C_P0_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 -+#define RTL8367C_P0_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 -+#define RTL8367C_P0_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 -+#define RTL8367C_P0_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 -+#define RTL8367C_P0_EAV_CFG_RX_DELAY_REQ_OFFSET 5 -+#define RTL8367C_P0_EAV_CFG_RX_DELAY_REQ_MASK 0x20 -+#define RTL8367C_P0_EAV_CFG_RX_SYNC_OFFSET 4 -+#define RTL8367C_P0_EAV_CFG_RX_SYNC_MASK 0x10 -+#define RTL8367C_P0_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 -+#define RTL8367C_P0_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 -+#define RTL8367C_P0_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 -+#define RTL8367C_P0_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 -+#define RTL8367C_P0_EAV_CFG_TX_DELAY_REQ_OFFSET 1 -+#define RTL8367C_P0_EAV_CFG_TX_DELAY_REQ_MASK 0x2 -+#define RTL8367C_P0_EAV_CFG_TX_SYNC_OFFSET 0 -+#define RTL8367C_P0_EAV_CFG_TX_SYNC_MASK 0x1 -+ -+#define RTL8367C_REG_P1_TX_SYNC_SEQ_ID 0x6420 -+ -+#define RTL8367C_REG_P1_TX_DELAY_REQ_SEQ_ID 0x6421 -+ -+#define RTL8367C_REG_P1_TX_PDELAY_REQ_SEQ_ID 0x6422 -+ -+#define RTL8367C_REG_P1_TX_PDELAY_RESP_SEQ_ID 0x6423 -+ -+#define RTL8367C_REG_P1_RX_SYNC_SEQ_ID 0x6424 -+ -+#define RTL8367C_REG_P1_RX_DELAY_REQ_SEQ_ID 0x6425 -+ -+#define RTL8367C_REG_P1_RX_PDELAY_REQ_SEQ_ID 0x6426 -+ -+#define RTL8367C_REG_P1_RX_PDELAY_RESP_SEQ_ID 0x6427 -+ -+#define RTL8367C_REG_P1_PORT_NSEC_15_0 0x6428 -+ -+#define RTL8367C_REG_P1_PORT_NSEC_26_16 0x6429 -+#define RTL8367C_P1_PORT_NSEC_26_16_OFFSET 0 -+#define RTL8367C_P1_PORT_NSEC_26_16_MASK 0x7FF -+ -+#define RTL8367C_REG_P1_PORT_SEC_15_0 0x642a -+ -+#define RTL8367C_REG_P1_PORT_SEC_31_16 0x642b -+ -+#define RTL8367C_REG_P1_EAV_CFG 0x642c -+#define RTL8367C_P1_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 -+#define RTL8367C_P1_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 -+#define RTL8367C_P1_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 -+#define RTL8367C_P1_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 -+#define RTL8367C_P1_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 -+#define RTL8367C_P1_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 -+#define RTL8367C_P1_EAV_CFG_RX_DELAY_REQ_OFFSET 5 -+#define RTL8367C_P1_EAV_CFG_RX_DELAY_REQ_MASK 0x20 -+#define RTL8367C_P1_EAV_CFG_RX_SYNC_OFFSET 4 -+#define RTL8367C_P1_EAV_CFG_RX_SYNC_MASK 0x10 -+#define RTL8367C_P1_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 -+#define RTL8367C_P1_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 -+#define RTL8367C_P1_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 -+#define RTL8367C_P1_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 -+#define RTL8367C_P1_EAV_CFG_TX_DELAY_REQ_OFFSET 1 -+#define RTL8367C_P1_EAV_CFG_TX_DELAY_REQ_MASK 0x2 -+#define RTL8367C_P1_EAV_CFG_TX_SYNC_OFFSET 0 -+#define RTL8367C_P1_EAV_CFG_TX_SYNC_MASK 0x1 -+ -+#define RTL8367C_REG_P2_TX_SYNC_SEQ_ID 0x6430 -+ -+#define RTL8367C_REG_P2_TX_DELAY_REQ_SEQ_ID 0x6431 -+ -+#define RTL8367C_REG_P2_TX_PDELAY_REQ_SEQ_ID 0x6432 -+ -+#define RTL8367C_REG_P2_TX_PDELAY_RESP_SEQ_ID 0x6433 -+ -+#define RTL8367C_REG_P2_RX_SYNC_SEQ_ID 0x6434 -+ -+#define RTL8367C_REG_P2_RX_DELAY_REQ_SEQ_ID 0x6435 -+ -+#define RTL8367C_REG_P2_RX_PDELAY_REQ_SEQ_ID 0x6436 -+ -+#define RTL8367C_REG_P2_RX_PDELAY_RESP_SEQ_ID 0x6437 -+ -+#define RTL8367C_REG_P2_PORT_NSEC_15_0 0x6438 -+ -+#define RTL8367C_REG_P2_PORT_NSEC_26_16 0x6439 -+#define RTL8367C_P2_PORT_NSEC_26_16_OFFSET 0 -+#define RTL8367C_P2_PORT_NSEC_26_16_MASK 0x7FF -+ -+#define RTL8367C_REG_P2_PORT_SEC_15_0 0x643a -+ -+#define RTL8367C_REG_P2_PORT_SEC_31_16 0x643b -+ -+#define RTL8367C_REG_P2_EAV_CFG 0x643c -+#define RTL8367C_P2_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 -+#define RTL8367C_P2_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 -+#define RTL8367C_P2_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 -+#define RTL8367C_P2_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 -+#define RTL8367C_P2_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 -+#define RTL8367C_P2_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 -+#define RTL8367C_P2_EAV_CFG_RX_DELAY_REQ_OFFSET 5 -+#define RTL8367C_P2_EAV_CFG_RX_DELAY_REQ_MASK 0x20 -+#define RTL8367C_P2_EAV_CFG_RX_SYNC_OFFSET 4 -+#define RTL8367C_P2_EAV_CFG_RX_SYNC_MASK 0x10 -+#define RTL8367C_P2_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 -+#define RTL8367C_P2_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 -+#define RTL8367C_P2_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 -+#define RTL8367C_P2_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 -+#define RTL8367C_P2_EAV_CFG_TX_DELAY_REQ_OFFSET 1 -+#define RTL8367C_P2_EAV_CFG_TX_DELAY_REQ_MASK 0x2 -+#define RTL8367C_P2_EAV_CFG_TX_SYNC_OFFSET 0 -+#define RTL8367C_P2_EAV_CFG_TX_SYNC_MASK 0x1 -+ -+#define RTL8367C_REG_P3_TX_SYNC_SEQ_ID 0x6440 -+ -+#define RTL8367C_REG_P3_TX_DELAY_REQ_SEQ_ID 0x6441 -+ -+#define RTL8367C_REG_P3_TX_PDELAY_REQ_SEQ_ID 0x6442 -+ -+#define RTL8367C_REG_P3_TX_PDELAY_RESP_SEQ_ID 0x6443 -+ -+#define RTL8367C_REG_P3_RX_SYNC_SEQ_ID 0x6444 -+ -+#define RTL8367C_REG_P3_RX_DELAY_REQ_SEQ_ID 0x6445 -+ -+#define RTL8367C_REG_P3_RX_PDELAY_REQ_SEQ_ID 0x6446 -+ -+#define RTL8367C_REG_P3_RX_PDELAY_RESP_SEQ_ID 0x6447 -+ -+#define RTL8367C_REG_P3_PORT_NSEC_15_0 0x6448 -+ -+#define RTL8367C_REG_P3_PORT_NSEC_26_16 0x6449 -+#define RTL8367C_P3_PORT_NSEC_26_16_OFFSET 0 -+#define RTL8367C_P3_PORT_NSEC_26_16_MASK 0x7FF -+ -+#define RTL8367C_REG_P3_PORT_SEC_15_0 0x644a -+ -+#define RTL8367C_REG_P3_PORT_SEC_31_16 0x644b -+ -+#define RTL8367C_REG_P3_EAV_CFG 0x644c -+#define RTL8367C_P3_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 -+#define RTL8367C_P3_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 -+#define RTL8367C_P3_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 -+#define RTL8367C_P3_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 -+#define RTL8367C_P3_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 -+#define RTL8367C_P3_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 -+#define RTL8367C_P3_EAV_CFG_RX_DELAY_REQ_OFFSET 5 -+#define RTL8367C_P3_EAV_CFG_RX_DELAY_REQ_MASK 0x20 -+#define RTL8367C_P3_EAV_CFG_RX_SYNC_OFFSET 4 -+#define RTL8367C_P3_EAV_CFG_RX_SYNC_MASK 0x10 -+#define RTL8367C_P3_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 -+#define RTL8367C_P3_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 -+#define RTL8367C_P3_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 -+#define RTL8367C_P3_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 -+#define RTL8367C_P3_EAV_CFG_TX_DELAY_REQ_OFFSET 1 -+#define RTL8367C_P3_EAV_CFG_TX_DELAY_REQ_MASK 0x2 -+#define RTL8367C_P3_EAV_CFG_TX_SYNC_OFFSET 0 -+#define RTL8367C_P3_EAV_CFG_TX_SYNC_MASK 0x1 -+ -+#define RTL8367C_REG_P4_TX_SYNC_SEQ_ID 0x6450 -+ -+#define RTL8367C_REG_P4_TX_DELAY_REQ_SEQ_ID 0x6451 -+ -+#define RTL8367C_REG_P4_TX_PDELAY_REQ_SEQ_ID 0x6452 -+ -+#define RTL8367C_REG_P4_TX_PDELAY_RESP_SEQ_ID 0x6453 -+ -+#define RTL8367C_REG_P4_RX_SYNC_SEQ_ID 0x6454 -+ -+#define RTL8367C_REG_P4_RX_DELAY_REQ_SEQ_ID 0x6455 -+ -+#define RTL8367C_REG_P4_RX_PDELAY_REQ_SEQ_ID 0x6456 -+ -+#define RTL8367C_REG_P4_RX_PDELAY_RESP_SEQ_ID 0x6457 -+ -+#define RTL8367C_REG_P4_PORT_NSEC_15_0 0x6458 -+ -+#define RTL8367C_REG_P4_PORT_NSEC_26_16 0x6459 -+#define RTL8367C_P4_PORT_NSEC_26_16_OFFSET 0 -+#define RTL8367C_P4_PORT_NSEC_26_16_MASK 0x7FF -+ -+#define RTL8367C_REG_P4_PORT_SEC_15_0 0x645a -+ -+#define RTL8367C_REG_P4_PORT_SEC_31_16 0x645b -+ -+#define RTL8367C_REG_P4_EAV_CFG 0x645c -+#define RTL8367C_P4_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 -+#define RTL8367C_P4_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 -+#define RTL8367C_P4_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 -+#define RTL8367C_P4_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 -+#define RTL8367C_P4_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 -+#define RTL8367C_P4_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 -+#define RTL8367C_P4_EAV_CFG_RX_DELAY_REQ_OFFSET 5 -+#define RTL8367C_P4_EAV_CFG_RX_DELAY_REQ_MASK 0x20 -+#define RTL8367C_P4_EAV_CFG_RX_SYNC_OFFSET 4 -+#define RTL8367C_P4_EAV_CFG_RX_SYNC_MASK 0x10 -+#define RTL8367C_P4_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 -+#define RTL8367C_P4_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 -+#define RTL8367C_P4_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 -+#define RTL8367C_P4_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 -+#define RTL8367C_P4_EAV_CFG_TX_DELAY_REQ_OFFSET 1 -+#define RTL8367C_P4_EAV_CFG_TX_DELAY_REQ_MASK 0x2 -+#define RTL8367C_P4_EAV_CFG_TX_SYNC_OFFSET 0 -+#define RTL8367C_P4_EAV_CFG_TX_SYNC_MASK 0x1 -+ -+#define RTL8367C_REG_P6_TX_SYNC_SEQ_ID 0x6460 -+ -+#define RTL8367C_REG_P6_TX_DELAY_REQ_SEQ_ID 0x6461 -+ -+#define RTL8367C_REG_P6_TX_PDELAY_REQ_SEQ_ID 0x6462 -+ -+#define RTL8367C_REG_P6_TX_PDELAY_RESP_SEQ_ID 0x6463 -+ -+#define RTL8367C_REG_P6_RX_SYNC_SEQ_ID 0x6464 -+ -+#define RTL8367C_REG_P6_RX_DELAY_REQ_SEQ_ID 0x6465 -+ -+#define RTL8367C_REG_P6_RX_PDELAY_REQ_SEQ_ID 0x6466 -+ -+#define RTL8367C_REG_P6_RX_PDELAY_RESP_SEQ_ID 0x6467 -+ -+#define RTL8367C_REG_P6_PORT_NSEC_15_0 0x6468 -+ -+#define RTL8367C_REG_P6_PORT_NSEC_26_16 0x6469 -+#define RTL8367C_P6_PORT_NSEC_26_16_OFFSET 0 -+#define RTL8367C_P6_PORT_NSEC_26_16_MASK 0x7FF -+ -+#define RTL8367C_REG_P6_PORT_SEC_15_0 0x646a -+ -+#define RTL8367C_REG_P6_PORT_SEC_31_16 0x646b -+ -+#define RTL8367C_REG_P6_EAV_CFG 0x646c -+#define RTL8367C_P6_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 -+#define RTL8367C_P6_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 -+#define RTL8367C_P6_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 -+#define RTL8367C_P6_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 -+#define RTL8367C_P6_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 -+#define RTL8367C_P6_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 -+#define RTL8367C_P6_EAV_CFG_RX_DELAY_REQ_OFFSET 5 -+#define RTL8367C_P6_EAV_CFG_RX_DELAY_REQ_MASK 0x20 -+#define RTL8367C_P6_EAV_CFG_RX_SYNC_OFFSET 4 -+#define RTL8367C_P6_EAV_CFG_RX_SYNC_MASK 0x10 -+#define RTL8367C_P6_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 -+#define RTL8367C_P6_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 -+#define RTL8367C_P6_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 -+#define RTL8367C_P6_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 -+#define RTL8367C_P6_EAV_CFG_TX_DELAY_REQ_OFFSET 1 -+#define RTL8367C_P6_EAV_CFG_TX_DELAY_REQ_MASK 0x2 -+#define RTL8367C_P6_EAV_CFG_TX_SYNC_OFFSET 0 -+#define RTL8367C_P6_EAV_CFG_TX_SYNC_MASK 0x1 -+ -+#define RTL8367C_REG_P7_TX_SYNC_SEQ_ID 0x6470 -+ -+#define RTL8367C_REG_P7_TX_DELAY_REQ_SEQ_ID 0x6471 -+ -+#define RTL8367C_REG_P7_TX_PDELAY_REQ_SEQ_ID 0x6472 -+ -+#define RTL8367C_REG_P7_TX_PDELAY_RESP_SEQ_ID 0x6473 -+ -+#define RTL8367C_REG_P7_RX_SYNC_SEQ_ID 0x6474 -+ -+#define RTL8367C_REG_P7_RX_DELAY_REQ_SEQ_ID 0x6475 -+ -+#define RTL8367C_REG_P7_RX_PDELAY_REQ_SEQ_ID 0x6476 -+ -+#define RTL8367C_REG_P7_RX_PDELAY_RESP_SEQ_ID 0x6477 -+ -+#define RTL8367C_REG_P7_PORT_NSEC_15_0 0x6478 -+ -+#define RTL8367C_REG_P7_PORT_NSEC_26_16 0x6479 -+#define RTL8367C_P7_PORT_NSEC_26_16_OFFSET 0 -+#define RTL8367C_P7_PORT_NSEC_26_16_MASK 0x7FF -+ -+#define RTL8367C_REG_P7_PORT_SEC_15_0 0x647a -+ -+#define RTL8367C_REG_P7_PORT_SEC_31_16 0x647b -+ -+#define RTL8367C_REG_P7_EAV_CFG 0x647c -+#define RTL8367C_P7_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 -+#define RTL8367C_P7_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 -+#define RTL8367C_P7_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 -+#define RTL8367C_P7_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 -+#define RTL8367C_P7_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 -+#define RTL8367C_P7_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 -+#define RTL8367C_P7_EAV_CFG_RX_DELAY_REQ_OFFSET 5 -+#define RTL8367C_P7_EAV_CFG_RX_DELAY_REQ_MASK 0x20 -+#define RTL8367C_P7_EAV_CFG_RX_SYNC_OFFSET 4 -+#define RTL8367C_P7_EAV_CFG_RX_SYNC_MASK 0x10 -+#define RTL8367C_P7_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 -+#define RTL8367C_P7_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 -+#define RTL8367C_P7_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 -+#define RTL8367C_P7_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 -+#define RTL8367C_P7_EAV_CFG_TX_DELAY_REQ_OFFSET 1 -+#define RTL8367C_P7_EAV_CFG_TX_DELAY_REQ_MASK 0x2 -+#define RTL8367C_P7_EAV_CFG_TX_SYNC_OFFSET 0 -+#define RTL8367C_P7_EAV_CFG_TX_SYNC_MASK 0x1 -+ -+#define RTL8367C_REG_P5_TX_SYNC_SEQ_ID 0x6480 -+ -+#define RTL8367C_REG_P5_TX_DELAY_REQ_SEQ_ID 0x6481 -+ -+#define RTL8367C_REG_P5_TX_PDELAY_REQ_SEQ_ID 0x6482 -+ -+#define RTL8367C_REG_P5_TX_PDELAY_RESP_SEQ_ID 0x6483 -+ -+#define RTL8367C_REG_P5_RX_SYNC_SEQ_ID 0x6484 -+ -+#define RTL8367C_REG_P5_RX_DELAY_REQ_SEQ_ID 0x6485 -+ -+#define RTL8367C_REG_P5_RX_PDELAY_REQ_SEQ_ID 0x6486 -+ -+#define RTL8367C_REG_P5_RX_PDELAY_RESP_SEQ_ID 0x6487 -+ -+#define RTL8367C_REG_P5_PORT_NSEC_15_0 0x6488 -+ -+#define RTL8367C_REG_P5_PORT_NSEC_26_16 0x6489 -+#define RTL8367C_P5_PORT_NSEC_26_16_OFFSET 0 -+#define RTL8367C_P5_PORT_NSEC_26_16_MASK 0x7FF -+ -+#define RTL8367C_REG_P5_PORT_SEC_15_0 0x648a -+ -+#define RTL8367C_REG_P5_PORT_SEC_31_16 0x648b -+ -+#define RTL8367C_REG_P5_EAV_CFG 0x648c -+#define RTL8367C_P5_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 -+#define RTL8367C_P5_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 -+#define RTL8367C_P5_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 -+#define RTL8367C_P5_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 -+#define RTL8367C_P5_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 -+#define RTL8367C_P5_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 -+#define RTL8367C_P5_EAV_CFG_RX_DELAY_REQ_OFFSET 5 -+#define RTL8367C_P5_EAV_CFG_RX_DELAY_REQ_MASK 0x20 -+#define RTL8367C_P5_EAV_CFG_RX_SYNC_OFFSET 4 -+#define RTL8367C_P5_EAV_CFG_RX_SYNC_MASK 0x10 -+#define RTL8367C_P5_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 -+#define RTL8367C_P5_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 -+#define RTL8367C_P5_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 -+#define RTL8367C_P5_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 -+#define RTL8367C_P5_EAV_CFG_TX_DELAY_REQ_OFFSET 1 -+#define RTL8367C_P5_EAV_CFG_TX_DELAY_REQ_MASK 0x2 -+#define RTL8367C_P5_EAV_CFG_TX_SYNC_OFFSET 0 -+#define RTL8367C_P5_EAV_CFG_TX_SYNC_MASK 0x1 -+ -+#define RTL8367C_REG_P8_TX_SYNC_SEQ_ID 0x6490 -+ -+#define RTL8367C_REG_P8_TX_DELAY_REQ_SEQ_ID 0x6491 -+ -+#define RTL8367C_REG_P8_TX_PDELAY_REQ_SEQ_ID 0x6492 -+ -+#define RTL8367C_REG_P8_TX_PDELAY_RESP_SEQ_ID 0x6493 -+ -+#define RTL8367C_REG_P8_RX_SYNC_SEQ_ID 0x6494 -+ -+#define RTL8367C_REG_P8_RX_DELAY_REQ_SEQ_ID 0x6495 -+ -+#define RTL8367C_REG_P8_RX_PDELAY_REQ_SEQ_ID 0x6496 -+ -+#define RTL8367C_REG_P8_RX_PDELAY_RESP_SEQ_ID 0x6497 -+ -+#define RTL8367C_REG_P8_PORT_NSEC_15_0 0x6498 -+ -+#define RTL8367C_REG_P8_PORT_NSEC_26_16 0x6499 -+#define RTL8367C_P8_PORT_NSEC_26_16_OFFSET 0 -+#define RTL8367C_P8_PORT_NSEC_26_16_MASK 0x7FF -+ -+#define RTL8367C_REG_P8_PORT_SEC_15_0 0x649a -+ -+#define RTL8367C_REG_P8_PORT_SEC_31_16 0x649b -+ -+#define RTL8367C_REG_P8_EAV_CFG 0x649c -+#define RTL8367C_P8_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 -+#define RTL8367C_P8_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 -+#define RTL8367C_P8_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 -+#define RTL8367C_P8_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 -+#define RTL8367C_P8_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 -+#define RTL8367C_P8_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 -+#define RTL8367C_P8_EAV_CFG_RX_DELAY_REQ_OFFSET 5 -+#define RTL8367C_P8_EAV_CFG_RX_DELAY_REQ_MASK 0x20 -+#define RTL8367C_P8_EAV_CFG_RX_SYNC_OFFSET 4 -+#define RTL8367C_P8_EAV_CFG_RX_SYNC_MASK 0x10 -+#define RTL8367C_P8_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 -+#define RTL8367C_P8_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 -+#define RTL8367C_P8_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 -+#define RTL8367C_P8_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 -+#define RTL8367C_P8_EAV_CFG_TX_DELAY_REQ_OFFSET 1 -+#define RTL8367C_P8_EAV_CFG_TX_DELAY_REQ_MASK 0x2 -+#define RTL8367C_P8_EAV_CFG_TX_SYNC_OFFSET 0 -+#define RTL8367C_P8_EAV_CFG_TX_SYNC_MASK 0x1 -+ -+#define RTL8367C_REG_P9_TX_SYNC_SEQ_ID 0x64a0 -+ -+#define RTL8367C_REG_P9_TX_DELAY_REQ_SEQ_ID 0x64a1 -+ -+#define RTL8367C_REG_P9_TX_PDELAY_REQ_SEQ_ID 0x64a2 -+ -+#define RTL8367C_REG_P9_TX_PDELAY_RESP_SEQ_ID 0x64a3 -+ -+#define RTL8367C_REG_P9_RX_SYNC_SEQ_ID 0x64a4 -+ -+#define RTL8367C_REG_P9_RX_DELAY_REQ_SEQ_ID 0x64a5 -+ -+#define RTL8367C_REG_P9_RX_PDELAY_REQ_SEQ_ID 0x64a6 -+ -+#define RTL8367C_REG_P9_RX_PDELAY_RESP_SEQ_ID 0x64a7 -+ -+#define RTL8367C_REG_P9_PORT_NSEC_15_0 0x64a8 -+ -+#define RTL8367C_REG_P9_PORT_NSEC_26_16 0x64a9 -+#define RTL8367C_P9_PORT_NSEC_26_16_OFFSET 0 -+#define RTL8367C_P9_PORT_NSEC_26_16_MASK 0x7FF -+ -+#define RTL8367C_REG_P9_PORT_SEC_15_0 0x64aa -+ -+#define RTL8367C_REG_P9_PORT_SEC_31_16 0x64ab -+ -+#define RTL8367C_REG_P9_EAV_CFG 0x64ac -+#define RTL8367C_P9_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 -+#define RTL8367C_P9_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 -+#define RTL8367C_P9_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 -+#define RTL8367C_P9_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 -+#define RTL8367C_P9_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 -+#define RTL8367C_P9_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 -+#define RTL8367C_P9_EAV_CFG_RX_DELAY_REQ_OFFSET 5 -+#define RTL8367C_P9_EAV_CFG_RX_DELAY_REQ_MASK 0x20 -+#define RTL8367C_P9_EAV_CFG_RX_SYNC_OFFSET 4 -+#define RTL8367C_P9_EAV_CFG_RX_SYNC_MASK 0x10 -+#define RTL8367C_P9_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 -+#define RTL8367C_P9_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 -+#define RTL8367C_P9_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 -+#define RTL8367C_P9_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 -+#define RTL8367C_P9_EAV_CFG_TX_DELAY_REQ_OFFSET 1 -+#define RTL8367C_P9_EAV_CFG_TX_DELAY_REQ_MASK 0x2 -+#define RTL8367C_P9_EAV_CFG_TX_SYNC_OFFSET 0 -+#define RTL8367C_P9_EAV_CFG_TX_SYNC_MASK 0x1 -+ -+/* (16'h6600)sds_indacs_reg */ -+ -+#define RTL8367C_REG_SDS_INDACS_CMD 0x6600 -+#define RTL8367C_SDS_CMD_BUSY_OFFSET 8 -+#define RTL8367C_SDS_CMD_BUSY_MASK 0x100 -+#define RTL8367C_SDS_CMD_OFFSET 7 -+#define RTL8367C_SDS_CMD_MASK 0x80 -+#define RTL8367C_SDS_RWOP_OFFSET 6 -+#define RTL8367C_SDS_RWOP_MASK 0x40 -+#define RTL8367C_SDS_INDEX_OFFSET 0 -+#define RTL8367C_SDS_INDEX_MASK 0x3F -+ -+#define RTL8367C_REG_SDS_INDACS_ADR 0x6601 -+#define RTL8367C_SDS_PAGE_OFFSET 5 -+#define RTL8367C_SDS_PAGE_MASK 0x7E0 -+#define RTL8367C_SDS_REGAD_OFFSET 0 -+#define RTL8367C_SDS_REGAD_MASK 0x1F -+ -+#define RTL8367C_REG_SDS_INDACS_DATA 0x6602 -+ -+ -+#endif /*#ifndef _RTL8367C_REG_H_*/ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/smi.h b/drivers/net/phy/rtk/rtl8367c/include/smi.h -new file mode 100644 -index 000000000000..b77d7607113e ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/smi.h -@@ -0,0 +1,54 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * Purpose : RTL8367C switch low-level function for access register -+ * Feature : SMI related functions -+ * -+ */ -+ -+#ifndef __SMI_H__ -+#define __SMI_H__ -+ -+#include -+#include "rtk_error.h" -+ -+#define MDC_MDIO_CTRL0_REG 31 -+#define MDC_MDIO_START_REG 29 -+#define MDC_MDIO_CTRL1_REG 21 -+#define MDC_MDIO_ADDRESS_REG 23 -+#define MDC_MDIO_DATA_WRITE_REG 24 -+#define MDC_MDIO_DATA_READ_REG 25 -+#define MDC_MDIO_PREAMBLE_LEN 32 -+ -+#define MDC_MDIO_START_OP 0xFFFF -+#define MDC_MDIO_ADDR_OP 0x000E -+#define MDC_MDIO_READ_OP 0x0001 -+#define MDC_MDIO_WRITE_OP 0x0003 -+ -+#define SPI_READ_OP 0x3 -+#define SPI_WRITE_OP 0x2 -+#define SPI_READ_OP_LEN 0x8 -+#define SPI_WRITE_OP_LEN 0x8 -+#define SPI_REG_LEN 16 -+#define SPI_DATA_LEN 16 -+ -+#define GPIO_DIR_IN 1 -+#define GPIO_DIR_OUT 0 -+ -+#define ack_timer 5 -+ -+#define DELAY 10000 -+#define CLK_DURATION(clk) { int i; for(i=0; isvid is SVID of SVLAN member configuration. -+ * - rtk_svlan_memberCfg_t->memberport is member port mask of SVLAN member configuration. -+ * - rtk_svlan_memberCfg_t->fid is filtering database of SVLAN member configuration. -+ * - rtk_svlan_memberCfg_t->priority is priority of SVLAN member configuration. -+ */ -+extern rtk_api_ret_t rtk_svlan_memberPortEntry_set(rtk_uint32 svid_idx, rtk_svlan_memberCfg_t *psvlan_cfg); -+ -+/* Function Name: -+ * rtk_svlan_memberPortEntry_get -+ * Description: -+ * Get SVLAN member Configure. -+ * Input: -+ * svid - SVLAN id -+ * Output: -+ * pSvlan_cfg - SVLAN member configuration -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can get system 64 accepted s-tag frame format. Only 64 SVID S-tag frame will be accpeted -+ * to receiving from uplink ports. Other SVID S-tag frame or S-untagged frame will be droped. -+ */ -+extern rtk_api_ret_t rtk_svlan_memberPortEntry_get(rtk_uint32 svid_idx, rtk_svlan_memberCfg_t *pSvlan_cfg); -+ -+/* Function Name: -+ * rtk_svlan_memberPortEntry_adv_set -+ * Description: -+ * Configure system SVLAN member by index -+ * Input: -+ * idx - Index (0 ~ 63) -+ * psvlan_cfg - SVLAN member configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter. -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_PORT_MASK - Invalid portmask. -+ * RT_ERR_SVLAN_TABLE_FULL - SVLAN configuration is full. -+ * Note: -+ * The API can set system 64 accepted s-tag frame format by index. -+ * - rtk_svlan_memberCfg_t->svid is SVID of SVLAN member configuration. -+ * - rtk_svlan_memberCfg_t->memberport is member port mask of SVLAN member configuration. -+ * - rtk_svlan_memberCfg_t->fid is filtering database of SVLAN member configuration. -+ * - rtk_svlan_memberCfg_t->priority is priority of SVLAN member configuration. -+ */ -+extern rtk_api_ret_t rtk_svlan_memberPortEntry_adv_set(rtk_uint32 idx, rtk_svlan_memberCfg_t *pSvlan_cfg); -+ -+/* Function Name: -+ * rtk_svlan_memberPortEntry_adv_get -+ * Description: -+ * Get SVLAN member Configure by index. -+ * Input: -+ * idx - Index (0 ~ 63) -+ * Output: -+ * pSvlan_cfg - SVLAN member configuration -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can get system 64 accepted s-tag frame format. Only 64 SVID S-tag frame will be accpeted -+ * to receiving from uplink ports. Other SVID S-tag frame or S-untagged frame will be droped. -+ */ -+extern rtk_api_ret_t rtk_svlan_memberPortEntry_adv_get(rtk_uint32 idx, rtk_svlan_memberCfg_t *pSvlan_cfg); -+ -+/* Function Name: -+ * rtk_svlan_defaultSvlan_set -+ * Description: -+ * Configure default egress SVLAN. -+ * Input: -+ * port - Source port -+ * svid - SVLAN id -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter. -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. -+ * Note: -+ * The API can set port n S-tag format index while receiving frame from port n -+ * is transmit through uplink port with s-tag field -+ */ -+extern rtk_api_ret_t rtk_svlan_defaultSvlan_set(rtk_port_t port, rtk_vlan_t svid); -+ -+/* Function Name: -+ * rtk_svlan_defaultSvlan_get -+ * Description: -+ * Get the configure default egress SVLAN. -+ * Input: -+ * port - Source port -+ * Output: -+ * pSvid - SVLAN VID -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can get port n S-tag format index while receiving frame from port n -+ * is transmit through uplink port with s-tag field -+ */ -+extern rtk_api_ret_t rtk_svlan_defaultSvlan_get(rtk_port_t port, rtk_vlan_t *pSvid); -+ -+/* Function Name: -+ * rtk_svlan_c2s_add -+ * Description: -+ * Configure SVLAN C2S table -+ * Input: -+ * vid - VLAN ID -+ * src_port - Ingress Port -+ * svid - SVLAN VID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port ID. -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_VLAN_VID - Invalid VID parameter. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can set system C2S configuration. ASIC will check upstream's VID and assign related -+ * SVID to mathed packet. There are 128 SVLAN C2S configurations. -+ */ -+extern rtk_api_ret_t rtk_svlan_c2s_add(rtk_vlan_t vid, rtk_port_t src_port, rtk_vlan_t svid); -+ -+/* Function Name: -+ * rtk_svlan_c2s_del -+ * Description: -+ * Delete one C2S entry -+ * Input: -+ * vid - VLAN ID -+ * src_port - Ingress Port -+ * svid - SVLAN VID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_VLAN_VID - Invalid VID parameter. -+ * RT_ERR_PORT_ID - Invalid port ID. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * Note: -+ * The API can delete system C2S configuration. There are 128 SVLAN C2S configurations. -+ */ -+extern rtk_api_ret_t rtk_svlan_c2s_del(rtk_vlan_t vid, rtk_port_t src_port); -+ -+/* Function Name: -+ * rtk_svlan_c2s_get -+ * Description: -+ * Get configure SVLAN C2S table -+ * Input: -+ * vid - VLAN ID -+ * src_port - Ingress Port -+ * Output: -+ * pSvid - SVLAN ID -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port ID. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * Note: -+ * The API can get system C2S configuration. There are 128 SVLAN C2S configurations. -+ */ -+extern rtk_api_ret_t rtk_svlan_c2s_get(rtk_vlan_t vid, rtk_port_t src_port, rtk_vlan_t *pSvid); -+ -+/* Function Name: -+ * rtk_svlan_untag_action_set -+ * Description: -+ * Configure Action of downstream Un-Stag packet -+ * Input: -+ * action - Action for UnStag -+ * svid - The SVID assigned to UnStag packet -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can configure action of downstream Un-Stag packet. A SVID assigned -+ * to the un-stag is also supported by this API. The parameter of svid is -+ * only referenced when the action is set to UNTAG_ASSIGN -+ */ -+extern rtk_api_ret_t rtk_svlan_untag_action_set(rtk_svlan_untag_action_t action, rtk_vlan_t svid); -+ -+/* Function Name: -+ * rtk_svlan_untag_action_get -+ * Description: -+ * Get Action of downstream Un-Stag packet -+ * Input: -+ * None -+ * Output: -+ * pAction - Action for UnStag -+ * pSvid - The SVID assigned to UnStag packet -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can Get action of downstream Un-Stag packet. A SVID assigned -+ * to the un-stag is also retrieved by this API. The parameter pSvid is -+ * only refernced when the action is UNTAG_ASSIGN -+ */ -+extern rtk_api_ret_t rtk_svlan_untag_action_get(rtk_svlan_untag_action_t *pAction, rtk_vlan_t *pSvid); -+ -+/* Function Name: -+ * rtk_svlan_unmatch_action_set -+ * Description: -+ * Configure Action of downstream Unmatch packet -+ * Input: -+ * action - Action for Unmatch -+ * svid - The SVID assigned to Unmatch packet -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can configure action of downstream Un-match packet. A SVID assigned -+ * to the un-match is also supported by this API. The parameter od svid is -+ * only refernced when the action is set to UNMATCH_ASSIGN -+ */ -+extern rtk_api_ret_t rtk_svlan_unmatch_action_set(rtk_svlan_unmatch_action_t action, rtk_vlan_t svid); -+ -+/* Function Name: -+ * rtk_svlan_unmatch_action_get -+ * Description: -+ * Get Action of downstream Unmatch packet -+ * Input: -+ * None -+ * Output: -+ * pAction - Action for Unmatch -+ * pSvid - The SVID assigned to Unmatch packet -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can Get action of downstream Un-match packet. A SVID assigned -+ * to the un-match is also retrieved by this API. The parameter pSvid is -+ * only refernced when the action is UNMATCH_ASSIGN -+ */ -+extern rtk_api_ret_t rtk_svlan_unmatch_action_get(rtk_svlan_unmatch_action_t *pAction, rtk_vlan_t *pSvid); -+ -+/* Function Name: -+ * rtk_svlan_dmac_vidsel_set -+ * Description: -+ * Set DMAC CVID selection -+ * Input: -+ * port - Port -+ * enable - state of DMAC CVID Selection -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can set DMAC CVID Selection state -+ */ -+extern rtk_api_ret_t rtk_svlan_dmac_vidsel_set(rtk_port_t port, rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_svlan_dmac_vidsel_get -+ * Description: -+ * Get DMAC CVID selection -+ * Input: -+ * port - Port -+ * Output: -+ * pEnable - state of DMAC CVID Selection -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can get DMAC CVID Selection state -+ */ -+extern rtk_api_ret_t rtk_svlan_dmac_vidsel_get(rtk_port_t port, rtk_enable_t *pEnable); -+ -+/* Function Name: -+ * rtk_svlan_ipmc2s_add -+ * Description: -+ * add ip multicast address to SVLAN -+ * Input: -+ * svid - SVLAN VID -+ * ipmc - ip multicast address -+ * ipmcMsk - ip multicast mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can set IP mutlicast to SVID configuration. If upstream packet is IPv4 multicast -+ * packet and DIP is matched MC2S configuration, ASIC will assign egress SVID to the packet. -+ * There are 32 SVLAN multicast configurations for IP and L2 multicast. -+ */ -+extern rtk_api_ret_t rtk_svlan_ipmc2s_add(ipaddr_t ipmc, ipaddr_t ipmcMsk, rtk_vlan_t svid); -+ -+/* Function Name: -+ * rtk_svlan_ipmc2s_del -+ * Description: -+ * delete ip multicast address to SVLAN -+ * Input: -+ * ipmc - ip multicast address -+ * ipmcMsk - ip multicast mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * Note: -+ * The API can delete IP mutlicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. -+ */ -+extern rtk_api_ret_t rtk_svlan_ipmc2s_del(ipaddr_t ipmc, ipaddr_t ipmcMsk); -+ -+/* Function Name: -+ * rtk_svlan_ipmc2s_get -+ * Description: -+ * Get ip multicast address to SVLAN -+ * Input: -+ * ipmc - ip multicast address -+ * ipmcMsk - ip multicast mask -+ * Output: -+ * pSvid - SVLAN VID -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * Note: -+ * The API can get IP mutlicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. -+ */ -+extern rtk_api_ret_t rtk_svlan_ipmc2s_get(ipaddr_t ipmc, ipaddr_t ipmcMsk, rtk_vlan_t *pSvid); -+ -+/* Function Name: -+ * rtk_svlan_l2mc2s_add -+ * Description: -+ * Add L2 multicast address to SVLAN -+ * Input: -+ * mac - L2 multicast address -+ * macMsk - L2 multicast address mask -+ * svid - SVLAN VID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can set L2 Mutlicast to SVID configuration. If upstream packet is L2 multicast -+ * packet and DMAC is matched, ASIC will assign egress SVID to the packet. There are 32 -+ * SVLAN multicast configurations for IP and L2 multicast. -+ */ -+extern rtk_api_ret_t rtk_svlan_l2mc2s_add(rtk_mac_t mac, rtk_mac_t macMsk, rtk_vlan_t svid); -+ -+/* Function Name: -+ * rtk_svlan_l2mc2s_del -+ * Description: -+ * delete L2 multicast address to SVLAN -+ * Input: -+ * mac - L2 multicast address -+ * macMsk - L2 multicast address mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * Note: -+ * The API can delete Mutlicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. -+ */ -+extern rtk_api_ret_t rtk_svlan_l2mc2s_del(rtk_mac_t mac, rtk_mac_t macMsk); -+ -+/* Function Name: -+ * rtk_svlan_l2mc2s_get -+ * Description: -+ * Get L2 multicast address to SVLAN -+ * Input: -+ * mac - L2 multicast address -+ * macMsk - L2 multicast address mask -+ * Output: -+ * pSvid - SVLAN VID -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * Note: -+ * The API can get L2 mutlicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. -+ */ -+extern rtk_api_ret_t rtk_svlan_l2mc2s_get(rtk_mac_t mac, rtk_mac_t macMsk, rtk_vlan_t *pSvid); -+ -+/* Function Name: -+ * rtk_svlan_sp2c_add -+ * Description: -+ * Add system SP2C configuration -+ * Input: -+ * cvid - VLAN ID -+ * dst_port - Destination port of SVLAN to CVLAN configuration -+ * svid - SVLAN VID -+ * -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_VLAN_VID - Invalid VID parameter. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can add SVID & Destination Port to CVLAN configuration. The downstream frames with assigned -+ * SVID will be add C-tag with assigned CVID if the output port is the assigned destination port. -+ * There are 128 SP2C configurations. -+ */ -+extern rtk_api_ret_t rtk_svlan_sp2c_add(rtk_vlan_t svid, rtk_port_t dst_port, rtk_vlan_t cvid); -+ -+/* Function Name: -+ * rtk_svlan_sp2c_get -+ * Description: -+ * Get configure system SP2C content -+ * Input: -+ * svid - SVLAN VID -+ * dst_port - Destination port of SVLAN to CVLAN configuration -+ * Output: -+ * pCvid - VLAN ID -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * Note: -+ * The API can get SVID & Destination Port to CVLAN configuration. There are 128 SP2C configurations. -+ */ -+extern rtk_api_ret_t rtk_svlan_sp2c_get(rtk_vlan_t svid, rtk_port_t dst_port, rtk_vlan_t *pCvid); -+ -+/* Function Name: -+ * rtk_svlan_sp2c_del -+ * Description: -+ * Delete system SP2C configuration -+ * Input: -+ * svid - SVLAN VID -+ * dst_port - Destination port of SVLAN to CVLAN configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * Note: -+ * The API can delete SVID & Destination Port to CVLAN configuration. There are 128 SP2C configurations. -+ */ -+extern rtk_api_ret_t rtk_svlan_sp2c_del(rtk_vlan_t svid, rtk_port_t dst_port); -+ -+ -+/* Function Name: -+ * rtk_svlan_lookupType_set -+ * Description: -+ * Set lookup type of SVLAN -+ * Input: -+ * type - lookup type -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * Note: -+ * none -+ */ -+extern rtk_api_ret_t rtk_svlan_lookupType_set(rtk_svlan_lookupType_t type); -+ -+/* Function Name: -+ * rtk_svlan_lookupType_get -+ * Description: -+ * Get lookup type of SVLAN -+ * Input: -+ * pType - lookup type -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * Note: -+ * none -+ */ -+extern rtk_api_ret_t rtk_svlan_lookupType_get(rtk_svlan_lookupType_t *pType); -+ -+/* Function Name: -+ * rtk_svlan_trapPri_set -+ * Description: -+ * Set svlan trap priority -+ * Input: -+ * priority - priority for trap packets -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_QOS_INT_PRIORITY -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_svlan_trapPri_set(rtk_pri_t priority); -+ -+/* Function Name: -+ * rtk_svlan_trapPri_get -+ * Description: -+ * Get svlan trap priority -+ * Input: -+ * None -+ * Output: -+ * pPriority - priority for trap packets -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_svlan_trapPri_get(rtk_pri_t *pPriority); -+ -+/* Function Name: -+ * rtk_svlan_unassign_action_set -+ * Description: -+ * Configure Action of upstream without svid assign action -+ * Input: -+ * action - Action for Un-assign -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can configure action of upstream Un-assign svid packet. If action is not -+ * trap to CPU, the port-based SVID sure be assign as system need -+ */ -+extern rtk_api_ret_t rtk_svlan_unassign_action_set(rtk_svlan_unassign_action_t action); -+ -+/* Function Name: -+ * rtk_svlan_unassign_action_get -+ * Description: -+ * Get action of upstream without svid assignment -+ * Input: -+ * None -+ * Output: -+ * pAction - Action for Un-assign -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * Note: -+ * None -+ */ -+extern rtk_api_ret_t rtk_svlan_unassign_action_get(rtk_svlan_unassign_action_t *pAction); -+ -+ -+/* Function Name: -+ * rtk_svlan_checkAndCreateMbr -+ * Description: -+ * Check and create Member configuration and return index -+ * Input: -+ * vid - VLAN id. -+ * Output: -+ * pIndex - Member configuration index -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_VLAN_VID - Invalid VLAN ID. -+ * RT_ERR_TBL_FULL - Member Configuration table full -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_svlan_checkAndCreateMbr(rtk_vlan_t vid, rtk_uint32 *pIndex); -+ -+ -+#endif /* __RTK_API_SVLAN_H__ */ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/trap.h b/drivers/net/phy/rtk/rtl8367c/include/trap.h -new file mode 100644 -index 000000000000..0cdb64a77b15 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/trap.h -@@ -0,0 +1,757 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * Purpose : RTL8367/RTL8367C switch high-level API -+ * -+ * Feature : The file includes Trap module high-layer API defination -+ * -+ */ -+ -+#ifndef __RTK_API_TRAP_H__ -+#define __RTK_API_TRAP_H__ -+ -+ -+typedef enum rtk_trap_type_e -+{ -+ TRAP_BRG_GROUP = 0, -+ TRAP_FD_PAUSE, -+ TRAP_SP_MCAST, -+ TRAP_1X_PAE, -+ TRAP_UNDEF_BRG_04, -+ TRAP_UNDEF_BRG_05, -+ TRAP_UNDEF_BRG_06, -+ TRAP_UNDEF_BRG_07, -+ TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, -+ TRAP_UNDEF_BRG_09, -+ TRAP_UNDEF_BRG_0A, -+ TRAP_UNDEF_BRG_0B, -+ TRAP_UNDEF_BRG_0C, -+ TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, -+ TRAP_8021AB, -+ TRAP_UNDEF_BRG_0F, -+ TRAP_BRG_MNGEMENT, -+ TRAP_UNDEFINED_11, -+ TRAP_UNDEFINED_12, -+ TRAP_UNDEFINED_13, -+ TRAP_UNDEFINED_14, -+ TRAP_UNDEFINED_15, -+ TRAP_UNDEFINED_16, -+ TRAP_UNDEFINED_17, -+ TRAP_UNDEFINED_18, -+ TRAP_UNDEFINED_19, -+ TRAP_UNDEFINED_1A, -+ TRAP_UNDEFINED_1B, -+ TRAP_UNDEFINED_1C, -+ TRAP_UNDEFINED_1D, -+ TRAP_UNDEFINED_1E, -+ TRAP_UNDEFINED_1F, -+ TRAP_GMRP, -+ TRAP_GVRP, -+ TRAP_UNDEF_GARP_22, -+ TRAP_UNDEF_GARP_23, -+ TRAP_UNDEF_GARP_24, -+ TRAP_UNDEF_GARP_25, -+ TRAP_UNDEF_GARP_26, -+ TRAP_UNDEF_GARP_27, -+ TRAP_UNDEF_GARP_28, -+ TRAP_UNDEF_GARP_29, -+ TRAP_UNDEF_GARP_2A, -+ TRAP_UNDEF_GARP_2B, -+ TRAP_UNDEF_GARP_2C, -+ TRAP_UNDEF_GARP_2D, -+ TRAP_UNDEF_GARP_2E, -+ TRAP_UNDEF_GARP_2F, -+ TRAP_CDP, -+ TRAP_CSSTP, -+ TRAP_LLDP, -+ TRAP_END, -+}rtk_trap_type_t; -+ -+ -+typedef enum rtk_mcast_type_e -+{ -+ MCAST_L2 = 0, -+ MCAST_IPV4, -+ MCAST_IPV6, -+ MCAST_END -+} rtk_mcast_type_t; -+ -+typedef enum rtk_trap_mcast_action_e -+{ -+ MCAST_ACTION_FORWARD = 0, -+ MCAST_ACTION_DROP, -+ MCAST_ACTION_TRAP2CPU, -+ MCAST_ACTION_ROUTER_PORT, -+ MCAST_ACTION_DROP_EX_RMA, -+ MCAST_ACTION_END -+} rtk_trap_mcast_action_t; -+ -+typedef enum rtk_trap_rma_action_e -+{ -+ RMA_ACTION_FORWARD = 0, -+ RMA_ACTION_TRAP2CPU, -+ RMA_ACTION_DROP, -+ RMA_ACTION_FORWARD_EXCLUDE_CPU, -+ RMA_ACTION_END -+} rtk_trap_rma_action_t; -+ -+typedef enum rtk_trap_ucast_action_e -+{ -+ UCAST_ACTION_FORWARD_PMASK = 0, -+ UCAST_ACTION_DROP, -+ UCAST_ACTION_TRAP2CPU, -+ UCAST_ACTION_FLOODING, -+ UCAST_ACTION_END -+} rtk_trap_ucast_action_t; -+ -+typedef enum rtk_trap_ucast_type_e -+{ -+ UCAST_UNKNOWNDA = 0, -+ UCAST_UNKNOWNSA, -+ UCAST_UNMATCHSA, -+ UCAST_END -+} rtk_trap_ucast_type_t; -+ -+typedef enum rtk_trap_reason_type_e -+{ -+ TRAP_REASON_RMA = 0, -+ TRAP_REASON_OAM, -+ TRAP_REASON_1XUNAUTH, -+ TRAP_REASON_VLANSTACK, -+ TRAP_REASON_UNKNOWNMC, -+ TRAP_REASON_END, -+} rtk_trap_reason_type_t; -+ -+ -+/* Function Name: -+ * rtk_trap_unknownUnicastPktAction_set -+ * Description: -+ * Set unknown unicast packet action configuration. -+ * Input: -+ * port - ingress port ID for unknown unicast packet -+ * ucast_action - Unknown unicast action. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NOT_ALLOWED - Invalid action. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can set unknown unicast packet action configuration. -+ * The unknown unicast action is as following: -+ * - UCAST_ACTION_FORWARD_PMASK -+ * - UCAST_ACTION_DROP -+ * - UCAST_ACTION_TRAP2CPU -+ * - UCAST_ACTION_FLOODING -+ */ -+rtk_api_ret_t rtk_trap_unknownUnicastPktAction_set(rtk_port_t port, rtk_trap_ucast_action_t ucast_action); -+ -+/* Function Name: -+ * rtk_trap_unknownUnicastPktAction_get -+ * Description: -+ * Get unknown unicast packet action configuration. -+ * Input: -+ * port - ingress port ID for unknown unicast packet -+ * Output: -+ * pUcast_action - Unknown unicast action. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NOT_ALLOWED - Invalid action. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * This API can get unknown unicast packet action configuration. -+ * The unknown unicast action is as following: -+ * - UCAST_ACTION_FORWARD_PMASK -+ * - UCAST_ACTION_DROP -+ * - UCAST_ACTION_TRAP2CPU -+ * - UCAST_ACTION_FLOODING -+ */ -+rtk_api_ret_t rtk_trap_unknownUnicastPktAction_get(rtk_port_t port, rtk_trap_ucast_action_t *pUcast_action); -+ -+/* Function Name: -+ * rtk_trap_unknownMacPktAction_set -+ * Description: -+ * Set unknown source MAC packet action configuration. -+ * Input: -+ * ucast_action - Unknown source MAC action. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NOT_ALLOWED - Invalid action. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can set unknown unicast packet action configuration. -+ * The unknown unicast action is as following: -+ * - UCAST_ACTION_FORWARD_PMASK -+ * - UCAST_ACTION_DROP -+ * - UCAST_ACTION_TRAP2CPU -+ */ -+extern rtk_api_ret_t rtk_trap_unknownMacPktAction_set(rtk_trap_ucast_action_t ucast_action); -+ -+/* Function Name: -+ * rtk_trap_unknownMacPktAction_get -+ * Description: -+ * Get unknown source MAC packet action configuration. -+ * Input: -+ * None. -+ * Output: -+ * pUcast_action - Unknown source MAC action. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Null Pointer. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_trap_unknownMacPktAction_get(rtk_trap_ucast_action_t *pUcast_action); -+ -+/* Function Name: -+ * rtk_trap_unmatchMacPktAction_set -+ * Description: -+ * Set unmatch source MAC packet action configuration. -+ * Input: -+ * ucast_action - Unknown source MAC action. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NOT_ALLOWED - Invalid action. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can set unknown unicast packet action configuration. -+ * The unknown unicast action is as following: -+ * - UCAST_ACTION_FORWARD_PMASK -+ * - UCAST_ACTION_DROP -+ * - UCAST_ACTION_TRAP2CPU -+ */ -+extern rtk_api_ret_t rtk_trap_unmatchMacPktAction_set(rtk_trap_ucast_action_t ucast_action); -+ -+/* Function Name: -+ * rtk_trap_unmatchMacPktAction_get -+ * Description: -+ * Get unmatch source MAC packet action configuration. -+ * Input: -+ * None. -+ * Output: -+ * pUcast_action - Unknown source MAC action. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NOT_ALLOWED - Invalid action. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can set unknown unicast packet action configuration. -+ * The unknown unicast action is as following: -+ * - UCAST_ACTION_FORWARD_PMASK -+ * - UCAST_ACTION_DROP -+ * - UCAST_ACTION_TRAP2CPU -+ */ -+extern rtk_api_ret_t rtk_trap_unmatchMacPktAction_get(rtk_trap_ucast_action_t *pUcast_action); -+ -+/* Function Name: -+ * rtk_trap_unmatchMacMoving_set -+ * Description: -+ * Set unmatch source MAC packet moving state. -+ * Input: -+ * port - Port ID. -+ * enable - ENABLED: allow SA moving, DISABLE: don't allow SA moving. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NOT_ALLOWED - Invalid action. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ */ -+extern rtk_api_ret_t rtk_trap_unmatchMacMoving_set(rtk_port_t port, rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_trap_unmatchMacMoving_get -+ * Description: -+ * Set unmatch source MAC packet moving state. -+ * Input: -+ * port - Port ID. -+ * Output: -+ * pEnable - ENABLED: allow SA moving, DISABLE: don't allow SA moving. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NOT_ALLOWED - Invalid action. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ */ -+extern rtk_api_ret_t rtk_trap_unmatchMacMoving_get(rtk_port_t port, rtk_enable_t *pEnable); -+ -+/* Function Name: -+ * rtk_trap_unknownMcastPktAction_set -+ * Description: -+ * Set behavior of unknown multicast -+ * Input: -+ * port - Port id. -+ * type - unknown multicast packet type. -+ * mcast_action - unknown multicast action. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_NOT_ALLOWED - Invalid action. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * When receives an unknown multicast packet, switch may trap, drop or flood this packet -+ * (1) The unknown multicast packet type is as following: -+ * - MCAST_L2 -+ * - MCAST_IPV4 -+ * - MCAST_IPV6 -+ * (2) The unknown multicast action is as following: -+ * - MCAST_ACTION_FORWARD -+ * - MCAST_ACTION_DROP -+ * - MCAST_ACTION_TRAP2CPU -+ */ -+extern rtk_api_ret_t rtk_trap_unknownMcastPktAction_set(rtk_port_t port, rtk_mcast_type_t type, rtk_trap_mcast_action_t mcast_action); -+ -+/* Function Name: -+ * rtk_trap_unknownMcastPktAction_get -+ * Description: -+ * Get behavior of unknown multicast -+ * Input: -+ * type - unknown multicast packet type. -+ * Output: -+ * pMcast_action - unknown multicast action. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_NOT_ALLOWED - Invalid operation. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * When receives an unknown multicast packet, switch may trap, drop or flood this packet -+ * (1) The unknown multicast packet type is as following: -+ * - MCAST_L2 -+ * - MCAST_IPV4 -+ * - MCAST_IPV6 -+ * (2) The unknown multicast action is as following: -+ * - MCAST_ACTION_FORWARD -+ * - MCAST_ACTION_DROP -+ * - MCAST_ACTION_TRAP2CPU -+ */ -+extern rtk_api_ret_t rtk_trap_unknownMcastPktAction_get(rtk_port_t port, rtk_mcast_type_t type, rtk_trap_mcast_action_t *pMcast_action); -+ -+/* Function Name: -+ * rtk_trap_lldpEnable_set -+ * Description: -+ * Set LLDP enable. -+ * Input: -+ * enabled - LLDP enable, 0: follow RMA, 1: use LLDP action. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NOT_ALLOWED - Invalid action. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * - DMAC Assignment -+ * - 01:80:c2:00:00:0e ethertype = 0x88CC LLDP -+ * - 01:80:c2:00:00:03 ethertype = 0x88CC -+ * - 01:80:c2:00:00:00 ethertype = 0x88CC -+ -+ */ -+extern rtk_api_ret_t rtk_trap_lldpEnable_set(rtk_enable_t enabled); -+ -+/* Function Name: -+ * rtk_trap_lldpEnable_get -+ * Description: -+ * Get LLDP status. -+ * Input: -+ * None -+ * Output: -+ * pEnabled - LLDP enable, 0: follow RMA, 1: use LLDP action. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * LLDP is as following definition. -+ * - DMAC Assignment -+ * - 01:80:c2:00:00:0e ethertype = 0x88CC LLDP -+ * - 01:80:c2:00:00:03 ethertype = 0x88CC -+ * - 01:80:c2:00:00:00 ethertype = 0x88CC -+ */ -+extern rtk_api_ret_t rtk_trap_lldpEnable_get(rtk_enable_t *pEnabled); -+ -+/* Function Name: -+ * rtk_trap_reasonTrapToCpuPriority_set -+ * Description: -+ * Set priority value of a packet that trapped to CPU port according to specific reason. -+ * Input: -+ * type - reason that trap to CPU port. -+ * priority - internal priority that is going to be set for specific trap reason. -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_INPUT - Invalid input parameter -+ * Note: -+ * Currently the trap reason that supported are listed as follows: -+ * - TRAP_REASON_RMA -+ * - TRAP_REASON_OAM -+ * - TRAP_REASON_1XUNAUTH -+ * - TRAP_REASON_VLANSTACK -+ * - TRAP_REASON_UNKNOWNMC -+ */ -+extern rtk_api_ret_t rtk_trap_reasonTrapToCpuPriority_set(rtk_trap_reason_type_t type, rtk_pri_t priority); -+ -+/* Function Name: -+ * rtk_trap_reasonTrapToCpuPriority_get -+ * Description: -+ * Get priority value of a packet that trapped to CPU port according to specific reason. -+ * Input: -+ * type - reason that trap to CPU port. -+ * Output: -+ * pPriority - configured internal priority for such reason. -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_INPUT - Invalid input parameter -+ * RT_ERR_NULL_POINTER - NULL pointer -+ * Note: -+ * Currently the trap reason that supported are listed as follows: -+ * - TRAP_REASON_RMA -+ * - TRAP_REASON_OAM -+ * - TRAP_REASON_1XUNAUTH -+ * - TRAP_REASON_VLANSTACK -+ * - TRAP_REASON_UNKNOWNMC -+ */ -+extern rtk_api_ret_t rtk_trap_reasonTrapToCpuPriority_get(rtk_trap_reason_type_t type, rtk_pri_t *pPriority); -+ -+/* Function Name: -+ * rtk_trap_rmaAction_set -+ * Description: -+ * Set Reserved multicast address action configuration. -+ * Input: -+ * type - rma type. -+ * rma_action - RMA action. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_ENABLE - Invalid IFG parameter -+ * Note: -+ * -+ * There are 48 types of Reserved Multicast Address frame for application usage. -+ * (1)They are as following definition. -+ * - TRAP_BRG_GROUP, -+ * - TRAP_FD_PAUSE, -+ * - TRAP_SP_MCAST, -+ * - TRAP_1X_PAE, -+ * - TRAP_UNDEF_BRG_04, -+ * - TRAP_UNDEF_BRG_05, -+ * - TRAP_UNDEF_BRG_06, -+ * - TRAP_UNDEF_BRG_07, -+ * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, -+ * - TRAP_UNDEF_BRG_09, -+ * - TRAP_UNDEF_BRG_0A, -+ * - TRAP_UNDEF_BRG_0B, -+ * - TRAP_UNDEF_BRG_0C, -+ * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, -+ * - TRAP_8021AB, -+ * - TRAP_UNDEF_BRG_0F, -+ * - TRAP_BRG_MNGEMENT, -+ * - TRAP_UNDEFINED_11, -+ * - TRAP_UNDEFINED_12, -+ * - TRAP_UNDEFINED_13, -+ * - TRAP_UNDEFINED_14, -+ * - TRAP_UNDEFINED_15, -+ * - TRAP_UNDEFINED_16, -+ * - TRAP_UNDEFINED_17, -+ * - TRAP_UNDEFINED_18, -+ * - TRAP_UNDEFINED_19, -+ * - TRAP_UNDEFINED_1A, -+ * - TRAP_UNDEFINED_1B, -+ * - TRAP_UNDEFINED_1C, -+ * - TRAP_UNDEFINED_1D, -+ * - TRAP_UNDEFINED_1E, -+ * - TRAP_UNDEFINED_1F, -+ * - TRAP_GMRP, -+ * - TRAP_GVRP, -+ * - TRAP_UNDEF_GARP_22, -+ * - TRAP_UNDEF_GARP_23, -+ * - TRAP_UNDEF_GARP_24, -+ * - TRAP_UNDEF_GARP_25, -+ * - TRAP_UNDEF_GARP_26, -+ * - TRAP_UNDEF_GARP_27, -+ * - TRAP_UNDEF_GARP_28, -+ * - TRAP_UNDEF_GARP_29, -+ * - TRAP_UNDEF_GARP_2A, -+ * - TRAP_UNDEF_GARP_2B, -+ * - TRAP_UNDEF_GARP_2C, -+ * - TRAP_UNDEF_GARP_2D, -+ * - TRAP_UNDEF_GARP_2E, -+ * - TRAP_UNDEF_GARP_2F, -+ * - TRAP_CDP. -+ * - TRAP_CSSTP. -+ * - TRAP_LLDP. -+ * (2) The RMA action is as following: -+ * - RMA_ACTION_FORWARD -+ * - RMA_ACTION_TRAP2CPU -+ * - RMA_ACTION_DROP -+ * - RMA_ACTION_FORWARD_EXCLUDE_CPU -+ */ -+extern rtk_api_ret_t rtk_trap_rmaAction_set(rtk_trap_type_t type, rtk_trap_rma_action_t rma_action); -+ -+/* Function Name: -+ * rtk_trap_rmaAction_get -+ * Description: -+ * Get Reserved multicast address action configuration. -+ * Input: -+ * type - rma type. -+ * Output: -+ * pRma_action - RMA action. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * There are 48 types of Reserved Multicast Address frame for application usage. -+ * (1)They are as following definition. -+ * - TRAP_BRG_GROUP, -+ * - TRAP_FD_PAUSE, -+ * - TRAP_SP_MCAST, -+ * - TRAP_1X_PAE, -+ * - TRAP_UNDEF_BRG_04, -+ * - TRAP_UNDEF_BRG_05, -+ * - TRAP_UNDEF_BRG_06, -+ * - TRAP_UNDEF_BRG_07, -+ * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, -+ * - TRAP_UNDEF_BRG_09, -+ * - TRAP_UNDEF_BRG_0A, -+ * - TRAP_UNDEF_BRG_0B, -+ * - TRAP_UNDEF_BRG_0C, -+ * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, -+ * - TRAP_8021AB, -+ * - TRAP_UNDEF_BRG_0F, -+ * - TRAP_BRG_MNGEMENT, -+ * - TRAP_UNDEFINED_11, -+ * - TRAP_UNDEFINED_12, -+ * - TRAP_UNDEFINED_13, -+ * - TRAP_UNDEFINED_14, -+ * - TRAP_UNDEFINED_15, -+ * - TRAP_UNDEFINED_16, -+ * - TRAP_UNDEFINED_17, -+ * - TRAP_UNDEFINED_18, -+ * - TRAP_UNDEFINED_19, -+ * - TRAP_UNDEFINED_1A, -+ * - TRAP_UNDEFINED_1B, -+ * - TRAP_UNDEFINED_1C, -+ * - TRAP_UNDEFINED_1D, -+ * - TRAP_UNDEFINED_1E, -+ * - TRAP_UNDEFINED_1F, -+ * - TRAP_GMRP, -+ * - TRAP_GVRP, -+ * - TRAP_UNDEF_GARP_22, -+ * - TRAP_UNDEF_GARP_23, -+ * - TRAP_UNDEF_GARP_24, -+ * - TRAP_UNDEF_GARP_25, -+ * - TRAP_UNDEF_GARP_26, -+ * - TRAP_UNDEF_GARP_27, -+ * - TRAP_UNDEF_GARP_28, -+ * - TRAP_UNDEF_GARP_29, -+ * - TRAP_UNDEF_GARP_2A, -+ * - TRAP_UNDEF_GARP_2B, -+ * - TRAP_UNDEF_GARP_2C, -+ * - TRAP_UNDEF_GARP_2D, -+ * - TRAP_UNDEF_GARP_2E, -+ * - TRAP_UNDEF_GARP_2F, -+ * - TRAP_CDP. -+ * - TRAP_CSSTP. -+ * - TRAP_LLDP. -+ * (2) The RMA action is as following: -+ * - RMA_ACTION_FORWARD -+ * - RMA_ACTION_TRAP2CPU -+ * - RMA_ACTION_DROP -+ * - RMA_ACTION_FORWARD_EXCLUDE_CPU -+ */ -+extern rtk_api_ret_t rtk_trap_rmaAction_get(rtk_trap_type_t type, rtk_trap_rma_action_t *pRma_action); -+ -+/* Function Name: -+ * rtk_trap_rmaKeepFormat_set -+ * Description: -+ * Set Reserved multicast address keep format configuration. -+ * Input: -+ * type - rma type. -+ * enable - enable keep format. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_ENABLE - Invalid IFG parameter -+ * Note: -+ * -+ * There are 48 types of Reserved Multicast Address frame for application usage. -+ * They are as following definition. -+ * - TRAP_BRG_GROUP, -+ * - TRAP_FD_PAUSE, -+ * - TRAP_SP_MCAST, -+ * - TRAP_1X_PAE, -+ * - TRAP_UNDEF_BRG_04, -+ * - TRAP_UNDEF_BRG_05, -+ * - TRAP_UNDEF_BRG_06, -+ * - TRAP_UNDEF_BRG_07, -+ * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, -+ * - TRAP_UNDEF_BRG_09, -+ * - TRAP_UNDEF_BRG_0A, -+ * - TRAP_UNDEF_BRG_0B, -+ * - TRAP_UNDEF_BRG_0C, -+ * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, -+ * - TRAP_8021AB, -+ * - TRAP_UNDEF_BRG_0F, -+ * - TRAP_BRG_MNGEMENT, -+ * - TRAP_UNDEFINED_11, -+ * - TRAP_UNDEFINED_12, -+ * - TRAP_UNDEFINED_13, -+ * - TRAP_UNDEFINED_14, -+ * - TRAP_UNDEFINED_15, -+ * - TRAP_UNDEFINED_16, -+ * - TRAP_UNDEFINED_17, -+ * - TRAP_UNDEFINED_18, -+ * - TRAP_UNDEFINED_19, -+ * - TRAP_UNDEFINED_1A, -+ * - TRAP_UNDEFINED_1B, -+ * - TRAP_UNDEFINED_1C, -+ * - TRAP_UNDEFINED_1D, -+ * - TRAP_UNDEFINED_1E, -+ * - TRAP_UNDEFINED_1F, -+ * - TRAP_GMRP, -+ * - TRAP_GVRP, -+ * - TRAP_UNDEF_GARP_22, -+ * - TRAP_UNDEF_GARP_23, -+ * - TRAP_UNDEF_GARP_24, -+ * - TRAP_UNDEF_GARP_25, -+ * - TRAP_UNDEF_GARP_26, -+ * - TRAP_UNDEF_GARP_27, -+ * - TRAP_UNDEF_GARP_28, -+ * - TRAP_UNDEF_GARP_29, -+ * - TRAP_UNDEF_GARP_2A, -+ * - TRAP_UNDEF_GARP_2B, -+ * - TRAP_UNDEF_GARP_2C, -+ * - TRAP_UNDEF_GARP_2D, -+ * - TRAP_UNDEF_GARP_2E, -+ * - TRAP_UNDEF_GARP_2F, -+ * - TRAP_CDP. -+ * - TRAP_CSSTP. -+ * - TRAP_LLDP. -+ */ -+extern rtk_api_ret_t rtk_trap_rmaKeepFormat_set(rtk_trap_type_t type, rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_trap_rmaKeepFormat_get -+ * Description: -+ * Get Reserved multicast address action configuration. -+ * Input: -+ * type - rma type. -+ * Output: -+ * pEnable - keep format status. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * There are 48 types of Reserved Multicast Address frame for application usage. -+ * They are as following definition. -+ * - TRAP_BRG_GROUP, -+ * - TRAP_FD_PAUSE, -+ * - TRAP_SP_MCAST, -+ * - TRAP_1X_PAE, -+ * - TRAP_UNDEF_BRG_04, -+ * - TRAP_UNDEF_BRG_05, -+ * - TRAP_UNDEF_BRG_06, -+ * - TRAP_UNDEF_BRG_07, -+ * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, -+ * - TRAP_UNDEF_BRG_09, -+ * - TRAP_UNDEF_BRG_0A, -+ * - TRAP_UNDEF_BRG_0B, -+ * - TRAP_UNDEF_BRG_0C, -+ * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, -+ * - TRAP_8021AB, -+ * - TRAP_UNDEF_BRG_0F, -+ * - TRAP_BRG_MNGEMENT, -+ * - TRAP_UNDEFINED_11, -+ * - TRAP_UNDEFINED_12, -+ * - TRAP_UNDEFINED_13, -+ * - TRAP_UNDEFINED_14, -+ * - TRAP_UNDEFINED_15, -+ * - TRAP_UNDEFINED_16, -+ * - TRAP_UNDEFINED_17, -+ * - TRAP_UNDEFINED_18, -+ * - TRAP_UNDEFINED_19, -+ * - TRAP_UNDEFINED_1A, -+ * - TRAP_UNDEFINED_1B, -+ * - TRAP_UNDEFINED_1C, -+ * - TRAP_UNDEFINED_1D, -+ * - TRAP_UNDEFINED_1E, -+ * - TRAP_UNDEFINED_1F, -+ * - TRAP_GMRP, -+ * - TRAP_GVRP, -+ * - TRAP_UNDEF_GARP_22, -+ * - TRAP_UNDEF_GARP_23, -+ * - TRAP_UNDEF_GARP_24, -+ * - TRAP_UNDEF_GARP_25, -+ * - TRAP_UNDEF_GARP_26, -+ * - TRAP_UNDEF_GARP_27, -+ * - TRAP_UNDEF_GARP_28, -+ * - TRAP_UNDEF_GARP_29, -+ * - TRAP_UNDEF_GARP_2A, -+ * - TRAP_UNDEF_GARP_2B, -+ * - TRAP_UNDEF_GARP_2C, -+ * - TRAP_UNDEF_GARP_2D, -+ * - TRAP_UNDEF_GARP_2E, -+ * - TRAP_UNDEF_GARP_2F, -+ * - TRAP_CDP. -+ * - TRAP_CSSTP. -+ * - TRAP_LLDP. -+ */ -+extern rtk_api_ret_t rtk_trap_rmaKeepFormat_get(rtk_trap_type_t type, rtk_enable_t *pEnable); -+ -+ -+#endif /* __RTK_API_TRAP_H__ */ -+ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/trunk.h b/drivers/net/phy/rtk/rtl8367c/include/trunk.h -new file mode 100644 -index 000000000000..dff61769dfd2 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/trunk.h -@@ -0,0 +1,328 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * Purpose : RTL8367/RTL8367C switch high-level API -+ * -+ * Feature : The file includes Trunk module high-layer TRUNK defination -+ * -+ */ -+ -+#ifndef __RTK_API_TRUNK_H__ -+#define __RTK_API_TRUNK_H__ -+ -+/* -+ * Data Type Declaration -+ */ -+#define RTK_TRUNK_DPORT_HASH_MASK 0x40 -+#define RTK_TRUNK_SPORT_HASH_MASK 0x20 -+#define RTK_TRUNK_DIP_HASH_MASK 0x10 -+#define RTK_TRUNK_SIP_HASH_MASK 0x8 -+#define RTK_TRUNK_DMAC_HASH_MASK 0x4 -+#define RTK_TRUNK_SMAC_HASH_MASK 0x2 -+#define RTK_TRUNK_SPA_HASH_MASK 0x1 -+ -+ -+#define RTK_MAX_NUM_OF_TRUNK_HASH_VAL 16 -+ -+typedef struct rtk_trunk_hashVal2Port_s -+{ -+ rtk_uint8 value[RTK_MAX_NUM_OF_TRUNK_HASH_VAL]; -+} rtk_trunk_hashVal2Port_t; -+ -+typedef enum rtk_trunk_group_e -+{ -+ TRUNK_GROUP0 = 0, -+ TRUNK_GROUP1, -+ TRUNK_GROUP2, -+ TRUNK_GROUP3, -+ TRUNK_GROUP_END -+} rtk_trunk_group_t; -+ -+typedef enum rtk_trunk_separateType_e -+{ -+ SEPARATE_NONE = 0, -+ SEPARATE_FLOOD, -+ SEPARATE_END -+ -+} rtk_trunk_separateType_t; -+ -+typedef enum rtk_trunk_mode_e -+{ -+ TRUNK_MODE_NORMAL = 0, -+ TRUNK_MODE_DUMB, -+ TRUNK_MODE_END -+} rtk_trunk_mode_t; -+ -+/* Function Name: -+ * rtk_trunk_port_set -+ * Description: -+ * Set trunking group available port mask -+ * Input: -+ * trk_gid - trunk group id -+ * pTrunk_member_portmask - Logic trunking member port mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_LA_TRUNK_ID - Invalid trunking group -+ * RT_ERR_PORT_MASK - Invalid portmask. -+ * Note: -+ * The API can set port trunking group port mask. Each port trunking group has max 4 ports. -+ * If enabled port mask has less than 2 ports available setting, then this trunking group function is disabled. -+ */ -+extern rtk_api_ret_t rtk_trunk_port_set(rtk_trunk_group_t trk_gid, rtk_portmask_t *pTrunk_member_portmask); -+ -+/* Function Name: -+ * rtk_trunk_port_get -+ * Description: -+ * Get trunking group available port mask -+ * Input: -+ * trk_gid - trunk group id -+ * Output: -+ * pTrunk_member_portmask - Logic trunking member port mask -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_LA_TRUNK_ID - Invalid trunking group -+ * Note: -+ * The API can get 2 port trunking group. -+ */ -+extern rtk_api_ret_t rtk_trunk_port_get(rtk_trunk_group_t trk_gid, rtk_portmask_t *pTrunk_member_portmask); -+ -+/* Function Name: -+ * rtk_trunk_distributionAlgorithm_set -+ * Description: -+ * Set port trunking hash select sources -+ * Input: -+ * trk_gid - trunk group id -+ * algo_bitmask - Bitmask of the distribution algorithm -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_LA_TRUNK_ID - Invalid trunking group -+ * RT_ERR_LA_HASHMASK - Hash algorithm selection error. -+ * RT_ERR_PORT_MASK - Invalid portmask. -+ * Note: -+ * The API can set port trunking hash algorithm sources. -+ * 7 bits mask for link aggregation group0 hash parameter selection {DIP, SIP, DMAC, SMAC, SPA} -+ * - 0b0000001: SPA -+ * - 0b0000010: SMAC -+ * - 0b0000100: DMAC -+ * - 0b0001000: SIP -+ * - 0b0010000: DIP -+ * - 0b0100000: TCP/UDP Source Port -+ * - 0b1000000: TCP/UDP Destination Port -+ * Example: -+ * - 0b0000011: SMAC & SPA -+ * - Note that it could be an arbitrary combination or independent set -+ */ -+extern rtk_api_ret_t rtk_trunk_distributionAlgorithm_set(rtk_trunk_group_t trk_gid, rtk_uint32 algo_bitmask); -+ -+/* Function Name: -+ * rtk_trunk_distributionAlgorithm_get -+ * Description: -+ * Get port trunking hash select sources -+ * Input: -+ * trk_gid - trunk group id -+ * Output: -+ * pAlgo_bitmask - Bitmask of the distribution algorithm -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_LA_TRUNK_ID - Invalid trunking group -+ * Note: -+ * The API can get port trunking hash algorithm sources. -+ */ -+extern rtk_api_ret_t rtk_trunk_distributionAlgorithm_get(rtk_trunk_group_t trk_gid, rtk_uint32 *pAlgo_bitmask); -+ -+/* Function Name: -+ * rtk_trunk_trafficSeparate_set -+ * Description: -+ * Set the traffic separation setting of a trunk group from the specified device. -+ * Input: -+ * trk_gid - trunk group id -+ * separateType - traffic separation setting -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_UNIT_ID - invalid unit id -+ * RT_ERR_LA_TRUNK_ID - invalid trunk ID -+ * RT_ERR_LA_HASHMASK - invalid hash mask -+ * Note: -+ * SEPARATE_NONE: disable traffic separation -+ * SEPARATE_FLOOD: trunk MSB link up port is dedicated to TX flooding (L2 lookup miss) traffic -+ */ -+extern rtk_api_ret_t rtk_trunk_trafficSeparate_set(rtk_trunk_group_t trk_gid, rtk_trunk_separateType_t separateType); -+ -+/* Function Name: -+ * rtk_trunk_trafficSeparate_get -+ * Description: -+ * Get the traffic separation setting of a trunk group from the specified device. -+ * Input: -+ * trk_gid - trunk group id -+ * Output: -+ * pSeparateType - pointer separated traffic type -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_UNIT_ID - invalid unit id -+ * RT_ERR_LA_TRUNK_ID - invalid trunk ID -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ * Note: -+ * SEPARATE_NONE: disable traffic separation -+ * SEPARATE_FLOOD: trunk MSB link up port is dedicated to TX flooding (L2 lookup miss) traffic -+ */ -+extern rtk_api_ret_t rtk_trunk_trafficSeparate_get(rtk_trunk_group_t trk_gid, rtk_trunk_separateType_t *pSeparateType); -+ -+ -+/* Function Name: -+ * rtk_trunk_mode_set -+ * Description: -+ * Set the trunk mode to the specified device. -+ * Input: -+ * mode - trunk mode -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_INPUT - invalid input parameter -+ * Note: -+ * The enum of the trunk mode as following -+ * - TRUNK_MODE_NORMAL -+ * - TRUNK_MODE_DUMB -+ */ -+extern rtk_api_ret_t rtk_trunk_mode_set(rtk_trunk_mode_t mode); -+ -+/* Function Name: -+ * rtk_trunk_mode_get -+ * Description: -+ * Get the trunk mode from the specified device. -+ * Input: -+ * None -+ * Output: -+ * pMode - pointer buffer of trunk mode -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ * Note: -+ * The enum of the trunk mode as following -+ * - TRUNK_MODE_NORMAL -+ * - TRUNK_MODE_DUMB -+ */ -+extern rtk_api_ret_t rtk_trunk_mode_get(rtk_trunk_mode_t *pMode); -+ -+/* Function Name: -+ * rtk_trunk_trafficPause_set -+ * Description: -+ * Set the traffic pause setting of a trunk group. -+ * Input: -+ * trk_gid - trunk group id -+ * enable - traffic pause state -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_LA_TRUNK_ID - invalid trunk ID -+ * Note: -+ * None. -+ */ -+extern rtk_api_ret_t rtk_trunk_trafficPause_set(rtk_trunk_group_t trk_gid, rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_trunk_trafficPause_get -+ * Description: -+ * Get the traffic pause setting of a trunk group. -+ * Input: -+ * trk_gid - trunk group id -+ * Output: -+ * pEnable - pointer of traffic pause state. -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_LA_TRUNK_ID - invalid trunk ID -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ * Note: -+ * None. -+ */ -+extern rtk_api_ret_t rtk_trunk_trafficPause_get(rtk_trunk_group_t trk_gid, rtk_enable_t *pEnable); -+ -+/* Function Name: -+ * rtk_trunk_hashMappingTable_set -+ * Description: -+ * Set hash value to port array in the trunk group id from the specified device. -+ * Input: -+ * trk_gid - trunk group id -+ * pHash2Port_array - ports associate with the hash value -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_UNIT_ID - invalid unit id -+ * RT_ERR_LA_TRUNK_ID - invalid trunk ID -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ * RT_ERR_LA_TRUNK_NOT_EXIST - the trunk doesn't exist -+ * RT_ERR_LA_NOT_MEMBER_PORT - the port is not a member port of the trunk -+ * RT_ERR_LA_CPUPORT - CPU port can not be aggregated port -+ * Note: -+ * Trunk group 0 & 1 shares the same hash mapping table. -+ * Trunk group 2 uses a independent table. -+ */ -+extern rtk_api_ret_t rtk_trunk_hashMappingTable_set(rtk_trunk_group_t trk_gid, rtk_trunk_hashVal2Port_t *pHash2Port_array); -+ -+/* Function Name: -+ * rtk_trunk_hashMappingTable_get -+ * Description: -+ * Get hash value to port array in the trunk group id from the specified device. -+ * Input: -+ * trk_gid - trunk group id -+ * Output: -+ * pHash2Port_array - pointer buffer of ports associate with the hash value -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_UNIT_ID - invalid unit id -+ * RT_ERR_LA_TRUNK_ID - invalid trunk ID -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ * Note: -+ * Trunk group 0 & 1 shares the same hash mapping table. -+ * Trunk group 2 uses a independent table. -+ */ -+extern rtk_api_ret_t rtk_trunk_hashMappingTable_get(rtk_trunk_group_t trk_gid, rtk_trunk_hashVal2Port_t *pHash2Port_array); -+ -+/* Function Name: -+ * rtk_trunk_portQueueEmpty_get -+ * Description: -+ * Get the port mask which all queues are empty. -+ * Input: -+ * None. -+ * Output: -+ * pEmpty_portmask - pointer empty port mask -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ * Note: -+ * None. -+ */ -+extern rtk_api_ret_t rtk_trunk_portQueueEmpty_get(rtk_portmask_t *pEmpty_portmask); -+ -+#endif /* __RTK_API_TRUNK_H__ */ -diff --git a/drivers/net/phy/rtk/rtl8367c/include/vlan.h b/drivers/net/phy/rtk/rtl8367c/include/vlan.h -new file mode 100644 -index 000000000000..8569fc0d40f4 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/include/vlan.h -@@ -0,0 +1,892 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * Purpose : RTL8367/RTL8367C switch high-level API -+ * -+ * Feature : The file includes Trap module high-layer VLAN defination -+ * -+ */ -+ -+#ifndef __RTK_API_VLAN_H__ -+#define __RTK_API_VLAN_H__ -+ -+ -+/* -+ * Data Type Declaration -+ */ -+#define RTK_MAX_NUM_OF_PROTO_TYPE 0xFFFF -+#define RTK_MAX_NUM_OF_MSTI 0xF -+#define RTK_FID_MAX 0xF -+ -+typedef struct rtk_vlan_cfg_s -+{ -+ rtk_portmask_t mbr; -+ rtk_portmask_t untag; -+ rtk_uint16 ivl_en; -+ rtk_uint16 fid_msti; -+ rtk_uint16 envlanpol; -+ rtk_uint16 meteridx; -+ rtk_uint16 vbpen; -+ rtk_uint16 vbpri; -+}rtk_vlan_cfg_t; -+ -+typedef struct rtk_vlan_mbrcfg_s -+{ -+ rtk_uint16 evid; -+ rtk_portmask_t mbr; -+ rtk_uint16 fid_msti; -+ rtk_uint16 envlanpol; -+ rtk_uint16 meteridx; -+ rtk_uint16 vbpen; -+ rtk_uint16 vbpri; -+}rtk_vlan_mbrcfg_t; -+ -+typedef rtk_uint32 rtk_stp_msti_id_t; /* MSTI ID */ -+ -+typedef enum rtk_stp_state_e -+{ -+ STP_STATE_DISABLED = 0, -+ STP_STATE_BLOCKING, -+ STP_STATE_LEARNING, -+ STP_STATE_FORWARDING, -+ STP_STATE_END -+} rtk_stp_state_t; -+ -+typedef rtk_uint32 rtk_vlan_proto_type_t; /* protocol and port based VLAN protocol type */ -+ -+ -+typedef enum rtk_vlan_acceptFrameType_e -+{ -+ ACCEPT_FRAME_TYPE_ALL = 0, /* untagged, priority-tagged and tagged */ -+ ACCEPT_FRAME_TYPE_TAG_ONLY, /* tagged */ -+ ACCEPT_FRAME_TYPE_UNTAG_ONLY, /* untagged and priority-tagged */ -+ ACCEPT_FRAME_TYPE_END -+} rtk_vlan_acceptFrameType_t; -+ -+ -+/* frame type of protocol vlan - reference 802.1v standard */ -+typedef enum rtk_vlan_protoVlan_frameType_e -+{ -+ FRAME_TYPE_ETHERNET = 0, -+ FRAME_TYPE_LLCOTHER, -+ FRAME_TYPE_RFC1042, -+ FRAME_TYPE_END -+} rtk_vlan_protoVlan_frameType_t; -+ -+/* Protocol-and-port-based Vlan structure */ -+typedef struct rtk_vlan_protoAndPortInfo_s -+{ -+ rtk_uint32 proto_type; -+ rtk_vlan_protoVlan_frameType_t frame_type; -+ rtk_vlan_t cvid; -+ rtk_pri_t cpri; -+}rtk_vlan_protoAndPortInfo_t; -+ -+/* tagged mode of VLAN - reference realtek private specification */ -+typedef enum rtk_vlan_tagMode_e -+{ -+ VLAN_TAG_MODE_ORIGINAL = 0, -+ VLAN_TAG_MODE_KEEP_FORMAT, -+ VLAN_TAG_MODE_PRI, -+ VLAN_TAG_MODE_REAL_KEEP_FORMAT, -+ VLAN_TAG_MODE_END -+} rtk_vlan_tagMode_t; -+ -+typedef enum rtk_vlan_resVidAction_e -+{ -+ RESVID_ACTION_UNTAG = 0, -+ RESVID_ACTION_TAG, -+ RESVID_ACTION_END -+} -+rtk_vlan_resVidAction_t; -+ -+/* Function Name: -+ * rtk_vlan_init -+ * Description: -+ * Initialize VLAN. -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * VLAN is disabled by default. User has to call this API to enable VLAN before -+ * using it. And It will set a default VLAN(vid 1) including all ports and set -+ * all ports PVID to the default VLAN. -+ */ -+extern rtk_api_ret_t rtk_vlan_init(void); -+ -+/* Function Name: -+ * rtk_vlan_set -+ * Description: -+ * Set a VLAN entry. -+ * Input: -+ * vid - VLAN ID to configure. -+ * pVlanCfg - VLAN Configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_L2_FID - Invalid FID. -+ * RT_ERR_VLAN_PORT_MBR_EXIST - Invalid member port mask. -+ * RT_ERR_VLAN_VID - Invalid VID parameter. -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_vlan_set(rtk_vlan_t vid, rtk_vlan_cfg_t *pVlanCfg); -+ -+/* Function Name: -+ * rtk_vlan_get -+ * Description: -+ * Get a VLAN entry. -+ * Input: -+ * vid - VLAN ID to configure. -+ * Output: -+ * pVlanCfg - VLAN Configuration -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_VLAN_VID - Invalid VID parameter. -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_vlan_get(rtk_vlan_t vid, rtk_vlan_cfg_t *pVlanCfg); -+ -+/* Function Name: -+ * rtk_vlan_egrFilterEnable_set -+ * Description: -+ * Set VLAN egress filter. -+ * Input: -+ * egrFilter - Egress filtering -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_ENABLE - Invalid input parameters. -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_vlan_egrFilterEnable_set(rtk_enable_t egrFilter); -+ -+/* Function Name: -+ * rtk_vlan_egrFilterEnable_get -+ * Description: -+ * Get VLAN egress filter. -+ * Input: -+ * pEgrFilter - Egress filtering -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - NULL Pointer. -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_vlan_egrFilterEnable_get(rtk_enable_t *pEgrFilter); -+ -+/* Function Name: -+ * rtk_vlan_mbrCfg_set -+ * Description: -+ * Set a VLAN Member Configuration entry by index. -+ * Input: -+ * idx - Index of VLAN Member Configuration. -+ * pMbrcfg - VLAN member Configuration. -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_VLAN_VID - Invalid VID parameter. -+ * Note: -+ * Set a VLAN Member Configuration entry by index. -+ */ -+extern rtk_api_ret_t rtk_vlan_mbrCfg_set(rtk_uint32 idx, rtk_vlan_mbrcfg_t *pMbrcfg); -+ -+/* Function Name: -+ * rtk_vlan_mbrCfg_get -+ * Description: -+ * Get a VLAN Member Configuration entry by index. -+ * Input: -+ * idx - Index of VLAN Member Configuration. -+ * Output: -+ * pMbrcfg - VLAN member Configuration. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_VLAN_VID - Invalid VID parameter. -+ * Note: -+ * Get a VLAN Member Configuration entry by index. -+ */ -+extern rtk_api_ret_t rtk_vlan_mbrCfg_get(rtk_uint32 idx, rtk_vlan_mbrcfg_t *pMbrcfg); -+ -+/* Function Name: -+ * rtk_vlan_portPvid_set -+ * Description: -+ * Set port to specified VLAN ID(PVID). -+ * Input: -+ * port - Port id. -+ * pvid - Specified VLAN ID. -+ * priority - 802.1p priority for the PVID. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_VLAN_PRIORITY - Invalid priority. -+ * RT_ERR_VLAN_ENTRY_NOT_FOUND - VLAN entry not found. -+ * RT_ERR_VLAN_VID - Invalid VID parameter. -+ * Note: -+ * The API is used for Port-based VLAN. The untagged frame received from the -+ * port will be classified to the specified VLAN and assigned to the specified priority. -+ */ -+extern rtk_api_ret_t rtk_vlan_portPvid_set(rtk_port_t port, rtk_vlan_t pvid, rtk_pri_t priority); -+ -+/* Function Name: -+ * rtk_vlan_portPvid_get -+ * Description: -+ * Get VLAN ID(PVID) on specified port. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pPvid - Specified VLAN ID. -+ * pPriority - 802.1p priority for the PVID. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get the PVID and 802.1p priority for the PVID of Port-based VLAN. -+ */ -+extern rtk_api_ret_t rtk_vlan_portPvid_get(rtk_port_t port, rtk_vlan_t *pPvid, rtk_pri_t *pPriority); -+ -+/* Function Name: -+ * rtk_vlan_portIgrFilterEnable_set -+ * Description: -+ * Set VLAN ingress for each port. -+ * Input: -+ * port - Port id. -+ * igr_filter - VLAN ingress function enable status. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_ENABLE - Invalid enable input -+ * Note: -+ * The status of vlan ingress filter is as following: -+ * - DISABLED -+ * - ENABLED -+ * While VLAN function is enabled, ASIC will decide VLAN ID for each received frame and get belonged member -+ * ports from VLAN table. If received port is not belonged to VLAN member ports, ASIC will drop received frame if VLAN ingress function is enabled. -+ */ -+extern rtk_api_ret_t rtk_vlan_portIgrFilterEnable_set(rtk_port_t port, rtk_enable_t igr_filter); -+ -+/* Function Name: -+ * rtk_vlan_portIgrFilterEnable_get -+ * Description: -+ * Get VLAN Ingress Filter -+ * Input: -+ * port - Port id. -+ * Output: -+ * pIgr_filter - VLAN ingress function enable status. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can Get the VLAN ingress filter status. -+ * The status of vlan ingress filter is as following: -+ * - DISABLED -+ * - ENABLED -+ */ -+extern rtk_api_ret_t rtk_vlan_portIgrFilterEnable_get(rtk_port_t port, rtk_enable_t *pIgr_filter); -+ -+/* Function Name: -+ * rtk_vlan_portAcceptFrameType_set -+ * Description: -+ * Set VLAN accept_frame_type -+ * Input: -+ * port - Port id. -+ * accept_frame_type - accept frame type -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_VLAN_ACCEPT_FRAME_TYPE - Invalid frame type. -+ * Note: -+ * The API is used for checking 802.1Q tagged frames. -+ * The accept frame type as following: -+ * - ACCEPT_FRAME_TYPE_ALL -+ * - ACCEPT_FRAME_TYPE_TAG_ONLY -+ * - ACCEPT_FRAME_TYPE_UNTAG_ONLY -+ */ -+extern rtk_api_ret_t rtk_vlan_portAcceptFrameType_set(rtk_port_t port, rtk_vlan_acceptFrameType_t accept_frame_type); -+ -+/* Function Name: -+ * rtk_vlan_portAcceptFrameType_get -+ * Description: -+ * Get VLAN accept_frame_type -+ * Input: -+ * port - Port id. -+ * Output: -+ * pAccept_frame_type - accept frame type -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can Get the VLAN ingress filter. -+ * The accept frame type as following: -+ * - ACCEPT_FRAME_TYPE_ALL -+ * - ACCEPT_FRAME_TYPE_TAG_ONLY -+ * - ACCEPT_FRAME_TYPE_UNTAG_ONLY -+ */ -+extern rtk_api_ret_t rtk_vlan_portAcceptFrameType_get(rtk_port_t port, rtk_vlan_acceptFrameType_t *pAccept_frame_type); -+ -+/* Function Name: -+ * rtk_vlan_tagMode_set -+ * Description: -+ * Set CVLAN egress tag mode -+ * Input: -+ * port - Port id. -+ * tag_mode - The egress tag mode. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_INPUT - Invalid input parameter. -+ * RT_ERR_ENABLE - Invalid enable input. -+ * Note: -+ * The API can set Egress tag mode. There are 4 mode for egress tag: -+ * - VLAN_TAG_MODE_ORIGINAL, -+ * - VLAN_TAG_MODE_KEEP_FORMAT, -+ * - VLAN_TAG_MODE_PRI. -+ * - VLAN_TAG_MODE_REAL_KEEP_FORMAT, -+ */ -+extern rtk_api_ret_t rtk_vlan_tagMode_set(rtk_port_t port, rtk_vlan_tagMode_t tag_mode); -+ -+/* Function Name: -+ * rtk_vlan_tagMode_get -+ * Description: -+ * Get CVLAN egress tag mode -+ * Input: -+ * port - Port id. -+ * Output: -+ * pTag_mode - The egress tag mode. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get Egress tag mode. There are 4 mode for egress tag: -+ * - VLAN_TAG_MODE_ORIGINAL, -+ * - VLAN_TAG_MODE_KEEP_FORMAT, -+ * - VLAN_TAG_MODE_PRI. -+ * - VLAN_TAG_MODE_REAL_KEEP_FORMAT, -+ */ -+extern rtk_api_ret_t rtk_vlan_tagMode_get(rtk_port_t port, rtk_vlan_tagMode_t *pTag_mode); -+ -+/* Function Name: -+ * rtk_vlan_transparent_set -+ * Description: -+ * Set VLAN transparent mode -+ * Input: -+ * egr_port - Egress Port id. -+ * pIgr_pmask - Ingress Port Mask. -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * None. -+ */ -+extern rtk_api_ret_t rtk_vlan_transparent_set(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask); -+ -+/* Function Name: -+ * rtk_vlan_transparent_get -+ * Description: -+ * Get VLAN transparent mode -+ * Input: -+ * egr_port - Egress Port id. -+ * Output: -+ * pIgr_pmask - Ingress Port Mask -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * None. -+ */ -+extern rtk_api_ret_t rtk_vlan_transparent_get(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask); -+ -+/* Function Name: -+ * rtk_vlan_keep_set -+ * Description: -+ * Set VLAN egress keep mode -+ * Input: -+ * egr_port - Egress Port id. -+ * pIgr_pmask - Ingress Port Mask. -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * None. -+ */ -+extern rtk_api_ret_t rtk_vlan_keep_set(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask); -+ -+/* Function Name: -+ * rtk_vlan_keep_get -+ * Description: -+ * Get VLAN egress keep mode -+ * Input: -+ * egr_port - Egress Port id. -+ * Output: -+ * pIgr_pmask - Ingress Port Mask -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * None. -+ */ -+extern rtk_api_ret_t rtk_vlan_keep_get(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask); -+ -+/* Function Name: -+ * rtk_vlan_stg_set -+ * Description: -+ * Set spanning tree group instance of the vlan to the specified device -+ * Input: -+ * vid - Specified VLAN ID. -+ * stg - spanning tree group instance. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_MSTI - Invalid msti parameter -+ * RT_ERR_INPUT - Invalid input parameter. -+ * RT_ERR_VLAN_VID - Invalid VID parameter. -+ * Note: -+ * The API can set spanning tree group instance of the vlan to the specified device. -+ */ -+extern rtk_api_ret_t rtk_vlan_stg_set(rtk_vlan_t vid, rtk_stp_msti_id_t stg); -+ -+/* Function Name: -+ * rtk_vlan_stg_get -+ * Description: -+ * Get spanning tree group instance of the vlan to the specified device -+ * Input: -+ * vid - Specified VLAN ID. -+ * Output: -+ * pStg - spanning tree group instance. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_VLAN_VID - Invalid VID parameter. -+ * Note: -+ * The API can get spanning tree group instance of the vlan to the specified device. -+ */ -+extern rtk_api_ret_t rtk_vlan_stg_get(rtk_vlan_t vid, rtk_stp_msti_id_t *pStg); -+ -+/* Function Name: -+ * rtk_vlan_protoAndPortBasedVlan_add -+ * Description: -+ * Add the protocol-and-port-based vlan to the specified port of device. -+ * Input: -+ * port - Port id. -+ * pInfo - Protocol and port based VLAN configuration information. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_VLAN_VID - Invalid VID parameter. -+ * RT_ERR_VLAN_PRIORITY - Invalid priority. -+ * RT_ERR_TBL_FULL - Table is full. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * Note: -+ * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline -+ * The frame type is shown in the following: -+ * - FRAME_TYPE_ETHERNET -+ * - FRAME_TYPE_RFC1042 -+ * - FRAME_TYPE_LLCOTHER -+ */ -+extern rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_add(rtk_port_t port, rtk_vlan_protoAndPortInfo_t *pInfo); -+ -+/* Function Name: -+ * rtk_vlan_protoAndPortBasedVlan_get -+ * Description: -+ * Get the protocol-and-port-based vlan to the specified port of device. -+ * Input: -+ * port - Port id. -+ * proto_type - protocol-and-port-based vlan protocol type. -+ * frame_type - protocol-and-port-based vlan frame type. -+ * Output: -+ * pInfo - Protocol and port based VLAN configuration information. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * RT_ERR_TBL_FULL - Table is full. -+ * Note: -+ * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline -+ * The frame type is shown in the following: -+ * - FRAME_TYPE_ETHERNET -+ * - FRAME_TYPE_RFC1042 -+ * - FRAME_TYPE_LLCOTHER -+ */ -+extern rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_get(rtk_port_t port, rtk_vlan_proto_type_t proto_type, rtk_vlan_protoVlan_frameType_t frame_type, rtk_vlan_protoAndPortInfo_t *pInfo); -+ -+/* Function Name: -+ * rtk_vlan_protoAndPortBasedVlan_del -+ * Description: -+ * Delete the protocol-and-port-based vlan from the specified port of device. -+ * Input: -+ * port - Port id. -+ * proto_type - protocol-and-port-based vlan protocol type. -+ * frame_type - protocol-and-port-based vlan frame type. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * RT_ERR_TBL_FULL - Table is full. -+ * Note: -+ * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline -+ * The frame type is shown in the following: -+ * - FRAME_TYPE_ETHERNET -+ * - FRAME_TYPE_RFC1042 -+ * - FRAME_TYPE_LLCOTHER -+ */ -+extern rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_del(rtk_port_t port, rtk_vlan_proto_type_t proto_type, rtk_vlan_protoVlan_frameType_t frame_type); -+ -+/* Function Name: -+ * rtk_vlan_protoAndPortBasedVlan_delAll -+ * Description: -+ * Delete all protocol-and-port-based vlans from the specified port of device. -+ * Input: -+ * port - Port id. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * Note: -+ * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline -+ * Delete all flow table protocol-and-port-based vlan entries. -+ */ -+extern rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_delAll(rtk_port_t port); -+ -+/* Function Name: -+ * rtk_vlan_portFid_set -+ * Description: -+ * Set port-based filtering database -+ * Input: -+ * port - Port id. -+ * enable - ebable port-based FID -+ * fid - Specified filtering database. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_L2_FID - Invalid fid. -+ * RT_ERR_INPUT - Invalid input parameter. -+ * RT_ERR_PORT_ID - Invalid port ID. -+ * Note: -+ * The API can set port-based filtering database. If the function is enabled, all input -+ * packets will be assigned to the port-based fid regardless vlan tag. -+ */ -+extern rtk_api_ret_t rtk_vlan_portFid_set(rtk_port_t port, rtk_enable_t enable, rtk_fid_t fid); -+ -+/* Function Name: -+ * rtk_vlan_portFid_get -+ * Description: -+ * Get port-based filtering database -+ * Input: -+ * port - Port id. -+ * Output: -+ * pEnable - ebable port-based FID -+ * pFid - Specified filtering database. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port ID. -+ * Note: -+ * The API can get port-based filtering database status. If the function is enabled, all input -+ * packets will be assigned to the port-based fid regardless vlan tag. -+ */ -+extern rtk_api_ret_t rtk_vlan_portFid_get(rtk_port_t port, rtk_enable_t *pEnable, rtk_fid_t *pFid); -+ -+/* Function Name: -+ * rtk_vlan_UntagDscpPriorityEnable_set -+ * Description: -+ * Set Untag DSCP priority assign -+ * Input: -+ * enable - state of Untag DSCP priority assign -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_ENABLE - Invalid input parameters. -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_vlan_UntagDscpPriorityEnable_set(rtk_enable_t enable); -+ -+/* Function Name: -+ * rtk_vlan_UntagDscpPriorityEnable_get -+ * Description: -+ * Get Untag DSCP priority assign -+ * Input: -+ * None -+ * Output: -+ * pEnable - state of Untag DSCP priority assign -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_vlan_UntagDscpPriorityEnable_get(rtk_enable_t *pEnable); -+ -+ -+/*Spanning Tree*/ -+/* Function Name: -+ * rtk_stp_mstpState_set -+ * Description: -+ * Configure spanning tree state per each port. -+ * Input: -+ * port - Port id -+ * msti - Multiple spanning tree instance. -+ * stp_state - Spanning tree state for msti -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_MSTI - Invalid msti parameter. -+ * RT_ERR_MSTP_STATE - Invalid STP state. -+ * Note: -+ * System supports per-port multiple spanning tree state for each msti. -+ * There are four states supported by ASIC. -+ * - STP_STATE_DISABLED -+ * - STP_STATE_BLOCKING -+ * - STP_STATE_LEARNING -+ * - STP_STATE_FORWARDING -+ */ -+extern rtk_api_ret_t rtk_stp_mstpState_set(rtk_stp_msti_id_t msti, rtk_port_t port, rtk_stp_state_t stp_state); -+ -+/* Function Name: -+ * rtk_stp_mstpState_get -+ * Description: -+ * Get spanning tree state per each port. -+ * Input: -+ * port - Port id. -+ * msti - Multiple spanning tree instance. -+ * Output: -+ * pStp_state - Spanning tree state for msti -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_MSTI - Invalid msti parameter. -+ * Note: -+ * System supports per-port multiple spanning tree state for each msti. -+ * There are four states supported by ASIC. -+ * - STP_STATE_DISABLED -+ * - STP_STATE_BLOCKING -+ * - STP_STATE_LEARNING -+ * - STP_STATE_FORWARDING -+ */ -+extern rtk_api_ret_t rtk_stp_mstpState_get(rtk_stp_msti_id_t msti, rtk_port_t port, rtk_stp_state_t *pStp_state); -+ -+/* Function Name: -+ * rtk_vlan_checkAndCreateMbr -+ * Description: -+ * Check and create Member configuration and return index -+ * Input: -+ * vid - VLAN id. -+ * Output: -+ * pIndex - Member configuration index -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_VLAN_VID - Invalid VLAN ID. -+ * RT_ERR_VLAN_ENTRY_NOT_FOUND - VLAN not found -+ * RT_ERR_TBL_FULL - Member Configuration table full -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_vlan_checkAndCreateMbr(rtk_vlan_t vid, rtk_uint32 *pIndex); -+ -+/* Function Name: -+ * rtk_vlan_reservedVidAction_set -+ * Description: -+ * Set Action of VLAN ID = 0 & 4095 tagged packet -+ * Input: -+ * action_vid0 - Action for VID 0. -+ * action_vid4095 - Action for VID 4095. -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_vlan_reservedVidAction_set(rtk_vlan_resVidAction_t action_vid0, rtk_vlan_resVidAction_t action_vid4095); -+ -+/* Function Name: -+ * rtk_vlan_reservedVidAction_get -+ * Description: -+ * Get Action of VLAN ID = 0 & 4095 tagged packet -+ * Input: -+ * pAction_vid0 - Action for VID 0. -+ * pAction_vid4095 - Action for VID 4095. -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - NULL Pointer -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_vlan_reservedVidAction_get(rtk_vlan_resVidAction_t *pAction_vid0, rtk_vlan_resVidAction_t *pAction_vid4095); -+ -+/* Function Name: -+ * rtk_vlan_realKeepRemarkEnable_set -+ * Description: -+ * Set Real keep 1p remarking feature -+ * Input: -+ * enabled - State of 1p remarking at real keep packet -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_vlan_realKeepRemarkEnable_set(rtk_enable_t enabled); -+ -+/* Function Name: -+ * rtk_vlan_realKeepRemarkEnable_get -+ * Description: -+ * Get Real keep 1p remarking feature -+ * Input: -+ * None. -+ * Output: -+ * pEnabled - State of 1p remarking at real keep packet -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * Note: -+ * -+ */ -+extern rtk_api_ret_t rtk_vlan_realKeepRemarkEnable_get(rtk_enable_t *pEnabled); -+ -+/* Function Name: -+ * rtk_vlan_reset -+ * Description: -+ * Reset VLAN -+ * Input: -+ * None. -+ * Output: -+ * pEnabled - State of 1p remarking at real keep packet -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_vlan_reset(void); -+ -+#endif /* __RTK_API_VLAN_H__ */ -diff --git a/drivers/net/phy/rtk/rtl8367c/interrupt.c b/drivers/net/phy/rtk/rtl8367c/interrupt.c -new file mode 100644 -index 000000000000..165ee41721b8 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/interrupt.c -@@ -0,0 +1,434 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTK switch high-level API for RTL8367/RTL8367C -+ * Feature : Here is a list of all functions and variables in Interrupt module. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+/* Function Name: -+ * rtk_int_polarity_set -+ * Description: -+ * Set interrupt polarity configuration. -+ * Input: -+ * type - Interruptpolarity type. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can set interrupt polarity configuration. -+ */ -+rtk_api_ret_t rtk_int_polarity_set(rtk_int_polarity_t type) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(type >= INT_POLAR_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicInterruptPolarity(type)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_int_polarity_get -+ * Description: -+ * Get interrupt polarity configuration. -+ * Input: -+ * None -+ * Output: -+ * pType - Interruptpolarity type. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * The API can get interrupt polarity configuration. -+ */ -+rtk_api_ret_t rtk_int_polarity_get(rtk_int_polarity_t *pType) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pType) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicInterruptPolarity(pType)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_int_control_set -+ * Description: -+ * Set interrupt trigger status configuration. -+ * Input: -+ * type - Interrupt type. -+ * enable - Interrupt status. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_ENABLE - Invalid enable input. -+ * Note: -+ * The API can set interrupt status configuration. -+ * The interrupt trigger status is shown in the following: -+ * - INT_TYPE_LINK_STATUS -+ * - INT_TYPE_METER_EXCEED -+ * - INT_TYPE_LEARN_LIMIT -+ * - INT_TYPE_LINK_SPEED -+ * - INT_TYPE_CONGEST -+ * - INT_TYPE_GREEN_FEATURE -+ * - INT_TYPE_LOOP_DETECT -+ * - INT_TYPE_8051, -+ * - INT_TYPE_CABLE_DIAG, -+ * - INT_TYPE_ACL, -+ * - INT_TYPE_SLIENT -+ */ -+rtk_api_ret_t rtk_int_control_set(rtk_int_type_t type, rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 mask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (type >= INT_TYPE_END) -+ return RT_ERR_INPUT; -+ -+ if (type == INT_TYPE_RESERVED) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_getAsicInterruptMask(&mask)) != RT_ERR_OK) -+ return retVal; -+ -+ if (ENABLED == enable) -+ mask = mask | (1<value[0] & (0x0001 << INT_TYPE_RESERVED)) -+ return RT_ERR_INPUT; -+ -+ if(pStatusMask->value[0] >= (0x0001 << INT_TYPE_END)) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicInterruptStatus((rtk_uint32)pStatusMask->value[0]))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_int_status_get -+ * Description: -+ * Get interrupt trigger status. -+ * Input: -+ * None -+ * Output: -+ * pStatusMask - Interrupt status bit mask. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can get interrupt trigger status when interrupt happened. -+ * The interrupt trigger status is shown in the following: -+ * - INT_TYPE_LINK_STATUS (value[0] (Bit0)) -+ * - INT_TYPE_METER_EXCEED (value[0] (Bit1)) -+ * - INT_TYPE_LEARN_LIMIT (value[0] (Bit2)) -+ * - INT_TYPE_LINK_SPEED (value[0] (Bit3)) -+ * - INT_TYPE_CONGEST (value[0] (Bit4)) -+ * - INT_TYPE_GREEN_FEATURE (value[0] (Bit5)) -+ * - INT_TYPE_LOOP_DETECT (value[0] (Bit6)) -+ * - INT_TYPE_8051 (value[0] (Bit7)) -+ * - INT_TYPE_CABLE_DIAG (value[0] (Bit8)) -+ * - INT_TYPE_ACL (value[0] (Bit9)) -+ * - INT_TYPE_SLIENT (value[0] (Bit11)) -+ * -+ */ -+rtk_api_ret_t rtk_int_status_get(rtk_int_status_t* pStatusMask) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 ims_mask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pStatusMask) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicInterruptStatus(&ims_mask)) != RT_ERR_OK) -+ return retVal; -+ -+ pStatusMask->value[0] = (ims_mask & 0x00000FFF); -+ return RT_ERR_OK; -+} -+ -+#define ADV_NOT_SUPPORT (0xFFFF) -+static rtk_api_ret_t _rtk_int_Advidx_get(rtk_int_advType_t adv_type, rtk_uint32 *pAsic_idx) -+{ -+ rtk_uint32 asic_idx[ADV_END] = -+ { -+ INTRST_L2_LEARN, -+ INTRST_SPEED_CHANGE, -+ INTRST_SPECIAL_CONGESTION, -+ INTRST_PORT_LINKDOWN, -+ INTRST_PORT_LINKUP, -+ ADV_NOT_SUPPORT, -+ INTRST_RLDP_LOOPED, -+ INTRST_RLDP_RELEASED, -+ }; -+ -+ if(adv_type >= ADV_END) -+ return RT_ERR_INPUT; -+ -+ if(asic_idx[adv_type] == ADV_NOT_SUPPORT) -+ return RT_ERR_CHIP_NOT_SUPPORTED; -+ -+ *pAsic_idx = asic_idx[adv_type]; -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_int_advanceInfo_get -+ * Description: -+ * Get interrupt advanced information. -+ * Input: -+ * adv_type - Advanced interrupt type. -+ * Output: -+ * info - Information per type. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can get advanced information when interrupt happened. -+ * The status will be cleared after execute this API. -+ */ -+rtk_api_ret_t rtk_int_advanceInfo_get(rtk_int_advType_t adv_type, rtk_int_info_t *pInfo) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 data; -+ rtk_uint32 intAdvType; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(adv_type >= ADV_END) -+ return RT_ERR_INPUT; -+ -+ if(NULL == pInfo) -+ return RT_ERR_NULL_POINTER; -+ -+ if(adv_type != ADV_METER_EXCEED_MASK) -+ { -+ if((retVal = _rtk_int_Advidx_get(adv_type, &intAdvType)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ switch(adv_type) -+ { -+ case ADV_L2_LEARN_PORT_MASK: -+ /* Get physical portmask */ -+ if((retVal = rtl8367c_getAsicInterruptRelatedStatus(intAdvType, &data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* Clear Advanced Info */ -+ if((retVal = rtl8367c_setAsicInterruptRelatedStatus(intAdvType, 0xFFFF)) != RT_ERR_OK) -+ return retVal; -+ -+ /* Translate to logical portmask */ -+ if((retVal = rtk_switch_portmask_P2L_get(data, &(pInfo->portMask))) != RT_ERR_OK) -+ return retVal; -+ -+ /* Get system learn */ -+ if((retVal = rtl8367c_getAsicInterruptRelatedStatus(INTRST_SYS_LEARN, &data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* Clear system learn */ -+ if((retVal = rtl8367c_setAsicInterruptRelatedStatus(INTRST_SYS_LEARN, 0x0001)) != RT_ERR_OK) -+ return retVal; -+ -+ pInfo->systemLearnOver = data; -+ break; -+ case ADV_SPEED_CHANGE_PORT_MASK: -+ case ADV_SPECIAL_CONGESTION_PORT_MASK: -+ case ADV_PORT_LINKDOWN_PORT_MASK: -+ case ADV_PORT_LINKUP_PORT_MASK: -+ case ADV_RLDP_LOOPED: -+ case ADV_RLDP_RELEASED: -+ /* Get physical portmask */ -+ if((retVal = rtl8367c_getAsicInterruptRelatedStatus(intAdvType, &data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* Clear Advanced Info */ -+ if((retVal = rtl8367c_setAsicInterruptRelatedStatus(intAdvType, 0xFFFF)) != RT_ERR_OK) -+ return retVal; -+ -+ /* Translate to logical portmask */ -+ if((retVal = rtk_switch_portmask_P2L_get(data, &(pInfo->portMask))) != RT_ERR_OK) -+ return retVal; -+ -+ break; -+ case ADV_METER_EXCEED_MASK: -+ /* Get Meter Mask */ -+ if((retVal = rtl8367c_getAsicInterruptRelatedStatus(INTRST_METER0_15, &data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* Clear Advanced Info */ -+ if((retVal = rtl8367c_setAsicInterruptRelatedStatus(INTRST_METER0_15, 0xFFFF)) != RT_ERR_OK) -+ return retVal; -+ -+ pInfo->meterMask = data & 0xFFFF; -+ -+ /* Get Meter Mask */ -+ if((retVal = rtl8367c_getAsicInterruptRelatedStatus(INTRST_METER16_31, &data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* Clear Advanced Info */ -+ if((retVal = rtl8367c_setAsicInterruptRelatedStatus(INTRST_METER16_31, 0xFFFF)) != RT_ERR_OK) -+ return retVal; -+ -+ pInfo->meterMask = pInfo->meterMask | ((data << 16) & 0xFFFF0000); -+ -+ break; -+ default: -+ return RT_ERR_INPUT; -+ } -+ -+ return RT_ERR_OK; -+} -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/l2.c b/drivers/net/phy/rtk/rtl8367c/l2.c -new file mode 100644 -index 000000000000..e73199a4e93d ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/l2.c -@@ -0,0 +1,2911 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTK switch high-level API for RTL8367/RTL8367C -+ * Feature : Here is a list of all functions and variables in L2 module. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+/* Function Name: -+ * rtk_l2_init -+ * Description: -+ * Initialize l2 module of the specified device. -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * Initialize l2 module before calling any l2 APIs. -+ */ -+rtk_api_ret_t rtk_l2_init(void) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 port; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if ((retVal = rtl8367c_setAsicLutIpMulticastLookup(DISABLED)) != RT_ERR_OK) -+ return retVal; -+ -+ /*Enable CAM Usage*/ -+ if ((retVal = rtl8367c_setAsicLutCamTbUsage(ENABLED)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicLutAgeTimerSpeed(6,2)) != RT_ERR_OK) -+ return retVal; -+ -+ RTK_SCAN_ALL_LOG_PORT(port) -+ { -+ if ((retVal = rtl8367c_setAsicLutLearnLimitNo(rtk_switch_port_L2P_get(port), rtk_switch_maxLutAddrNumber_get())) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+ -+/* Function Name: -+ * rtk_l2_addr_add -+ * Description: -+ * Add LUT unicast entry. -+ * Input: -+ * pMac - 6 bytes unicast(I/G bit is 0) mac address to be written into LUT. -+ * pL2_data - Unicast entry parameter -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_MAC - Invalid MAC address. -+ * RT_ERR_L2_FID - Invalid FID . -+ * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * If the unicast mac address already existed in LUT, it will update the status of the entry. -+ * Otherwise, it will find an empty or asic auto learned entry to write. If all the entries -+ * with the same hash value can't be replaced, ASIC will return a RT_ERR_L2_INDEXTBL_FULL error. -+ */ -+rtk_api_ret_t rtk_l2_addr_add(rtk_mac_t *pMac, rtk_l2_ucastAddr_t *pL2_data) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 method; -+ rtl8367c_luttb l2Table; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* must be unicast address */ -+ if ((pMac == NULL) || (pMac->octet[0] & 0x1)) -+ return RT_ERR_MAC; -+ -+ if(pL2_data == NULL) -+ return RT_ERR_MAC; -+ -+ RTK_CHK_PORT_VALID(pL2_data->port); -+ -+ if (pL2_data->ivl >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if (pL2_data->cvid > RTL8367C_VIDMAX) -+ return RT_ERR_L2_VID; -+ -+ if (pL2_data->fid > RTL8367C_FIDMAX) -+ return RT_ERR_L2_FID; -+ -+ if (pL2_data->is_static>= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if (pL2_data->sa_block>= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if (pL2_data->da_block>= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if (pL2_data->auth>= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if (pL2_data->efid> RTL8367C_EFIDMAX) -+ return RT_ERR_INPUT; -+ -+ if (pL2_data->priority > RTL8367C_PRIMAX) -+ return RT_ERR_INPUT; -+ -+ if (pL2_data->sa_pri_en >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if (pL2_data->fwd_pri_en >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); -+ -+ /* fill key (MAC,FID) to get L2 entry */ -+ memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); -+ l2Table.ivl_svl = pL2_data->ivl; -+ l2Table.fid = pL2_data->fid; -+ l2Table.cvid_fid = pL2_data->cvid; -+ l2Table.efid = pL2_data->efid; -+ method = LUTREADMETHOD_MAC; -+ retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); -+ if (RT_ERR_OK == retVal ) -+ { -+ memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); -+ l2Table.ivl_svl = pL2_data->ivl; -+ l2Table.cvid_fid = pL2_data->cvid; -+ l2Table.fid = pL2_data->fid; -+ l2Table.efid = pL2_data->efid; -+ l2Table.spa = rtk_switch_port_L2P_get(pL2_data->port); -+ l2Table.nosalearn = pL2_data->is_static; -+ l2Table.sa_block = pL2_data->sa_block; -+ l2Table.da_block = pL2_data->da_block; -+ l2Table.l3lookup = 0; -+ l2Table.auth = pL2_data->auth; -+ l2Table.age = 6; -+ l2Table.lut_pri = pL2_data->priority; -+ l2Table.sa_en = pL2_data->sa_pri_en; -+ l2Table.fwd_en = pL2_data->fwd_pri_en; -+ if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) -+ return retVal; -+ -+ pL2_data->address = l2Table.address; -+ return RT_ERR_OK; -+ } -+ else if (RT_ERR_L2_ENTRY_NOTFOUND == retVal ) -+ { -+ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); -+ memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); -+ l2Table.ivl_svl = pL2_data->ivl; -+ l2Table.cvid_fid = pL2_data->cvid; -+ l2Table.fid = pL2_data->fid; -+ l2Table.efid = pL2_data->efid; -+ l2Table.spa = rtk_switch_port_L2P_get(pL2_data->port); -+ l2Table.nosalearn = pL2_data->is_static; -+ l2Table.sa_block = pL2_data->sa_block; -+ l2Table.da_block = pL2_data->da_block; -+ l2Table.l3lookup = 0; -+ l2Table.auth = pL2_data->auth; -+ l2Table.age = 6; -+ l2Table.lut_pri = pL2_data->priority; -+ l2Table.sa_en = pL2_data->sa_pri_en; -+ l2Table.fwd_en = pL2_data->fwd_pri_en; -+ -+ if ((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) -+ return retVal; -+ -+ pL2_data->address = l2Table.address; -+ -+ method = LUTREADMETHOD_MAC; -+ retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); -+ if (RT_ERR_L2_ENTRY_NOTFOUND == retVal ) -+ return RT_ERR_L2_INDEXTBL_FULL; -+ else -+ return retVal; -+ } -+ else -+ return retVal; -+ -+} -+ -+/* Function Name: -+ * rtk_l2_addr_get -+ * Description: -+ * Get LUT unicast entry. -+ * Input: -+ * pMac - 6 bytes unicast(I/G bit is 0) mac address to be written into LUT. -+ * Output: -+ * pL2_data - Unicast entry parameter -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_MAC - Invalid MAC address. -+ * RT_ERR_L2_FID - Invalid FID . -+ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * If the unicast mac address existed in LUT, it will return the port and fid where -+ * the mac is learned. Otherwise, it will return a RT_ERR_L2_ENTRY_NOTFOUND error. -+ */ -+rtk_api_ret_t rtk_l2_addr_get(rtk_mac_t *pMac, rtk_l2_ucastAddr_t *pL2_data) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 method; -+ rtl8367c_luttb l2Table; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* must be unicast address */ -+ if ((pMac == NULL) || (pMac->octet[0] & 0x1)) -+ return RT_ERR_MAC; -+ -+ if (pL2_data->fid > RTL8367C_FIDMAX || pL2_data->efid > RTL8367C_EFIDMAX) -+ return RT_ERR_L2_FID; -+ -+ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); -+ -+ memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); -+ l2Table.ivl_svl = pL2_data->ivl; -+ l2Table.cvid_fid = pL2_data->cvid; -+ l2Table.fid = pL2_data->fid; -+ l2Table.efid = pL2_data->efid; -+ method = LUTREADMETHOD_MAC; -+ -+ if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) -+ return retVal; -+ -+ memcpy(pL2_data->mac.octet, pMac->octet,ETHER_ADDR_LEN); -+ pL2_data->port = rtk_switch_port_P2L_get(l2Table.spa); -+ pL2_data->fid = l2Table.fid; -+ pL2_data->efid = l2Table.efid; -+ pL2_data->ivl = l2Table.ivl_svl; -+ pL2_data->cvid = l2Table.cvid_fid; -+ pL2_data->is_static = l2Table.nosalearn; -+ pL2_data->auth = l2Table.auth; -+ pL2_data->sa_block = l2Table.sa_block; -+ pL2_data->da_block = l2Table.da_block; -+ pL2_data->priority = l2Table.lut_pri; -+ pL2_data->sa_pri_en = l2Table.sa_en; -+ pL2_data->fwd_pri_en= l2Table.fwd_en; -+ pL2_data->address = l2Table.address; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_addr_next_get -+ * Description: -+ * Get Next LUT unicast entry. -+ * Input: -+ * read_method - The reading method. -+ * port - The port number if the read_metohd is READMETHOD_NEXT_L2UCSPA -+ * pAddress - The Address ID -+ * Output: -+ * pL2_data - Unicast entry parameter -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_MAC - Invalid MAC address. -+ * RT_ERR_L2_FID - Invalid FID . -+ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * Get the next unicast entry after the current entry pointed by pAddress. -+ * The address of next entry is returned by pAddress. User can use (address + 1) -+ * as pAddress to call this API again for dumping all entries is LUT. -+ */ -+rtk_api_ret_t rtk_l2_addr_next_get(rtk_l2_read_method_t read_method, rtk_port_t port, rtk_uint32 *pAddress, rtk_l2_ucastAddr_t *pL2_data) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 method; -+ rtl8367c_luttb l2Table; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Error Checking */ -+ if ((pL2_data == NULL) || (pAddress == NULL)) -+ return RT_ERR_MAC; -+ -+ if(read_method == READMETHOD_NEXT_L2UC) -+ method = LUTREADMETHOD_NEXT_L2UC; -+ else if(read_method == READMETHOD_NEXT_L2UCSPA) -+ method = LUTREADMETHOD_NEXT_L2UCSPA; -+ else -+ return RT_ERR_INPUT; -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(*pAddress > RTK_MAX_LUT_ADDR_ID ) -+ return RT_ERR_L2_L2UNI_PARAM; -+ -+ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); -+ l2Table.address = *pAddress; -+ -+ if(read_method == READMETHOD_NEXT_L2UCSPA) -+ l2Table.spa = rtk_switch_port_L2P_get(port); -+ -+ if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) -+ return retVal; -+ -+ if(l2Table.address < *pAddress) -+ return RT_ERR_L2_ENTRY_NOTFOUND; -+ -+ memcpy(pL2_data->mac.octet, l2Table.mac.octet, ETHER_ADDR_LEN); -+ pL2_data->port = rtk_switch_port_P2L_get(l2Table.spa); -+ pL2_data->fid = l2Table.fid; -+ pL2_data->efid = l2Table.efid; -+ pL2_data->ivl = l2Table.ivl_svl; -+ pL2_data->cvid = l2Table.cvid_fid; -+ pL2_data->is_static = l2Table.nosalearn; -+ pL2_data->auth = l2Table.auth; -+ pL2_data->sa_block = l2Table.sa_block; -+ pL2_data->da_block = l2Table.da_block; -+ pL2_data->priority = l2Table.lut_pri; -+ pL2_data->sa_pri_en = l2Table.sa_en; -+ pL2_data->fwd_pri_en= l2Table.fwd_en; -+ pL2_data->address = l2Table.address; -+ -+ *pAddress = l2Table.address; -+ -+ return RT_ERR_OK; -+ -+} -+ -+/* Function Name: -+ * rtk_l2_addr_del -+ * Description: -+ * Delete LUT unicast entry. -+ * Input: -+ * pMac - 6 bytes unicast(I/G bit is 0) mac address to be written into LUT. -+ * fid - Filtering database -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_MAC - Invalid MAC address. -+ * RT_ERR_L2_FID - Invalid FID . -+ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * If the mac has existed in the LUT, it will be deleted. Otherwise, it will return RT_ERR_L2_ENTRY_NOTFOUND. -+ */ -+rtk_api_ret_t rtk_l2_addr_del(rtk_mac_t *pMac, rtk_l2_ucastAddr_t *pL2_data) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 method; -+ rtl8367c_luttb l2Table; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* must be unicast address */ -+ if ((pMac == NULL) || (pMac->octet[0] & 0x1)) -+ return RT_ERR_MAC; -+ -+ if (pL2_data->fid > RTL8367C_FIDMAX || pL2_data->efid > RTL8367C_EFIDMAX) -+ return RT_ERR_L2_FID; -+ -+ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); -+ -+ /* fill key (MAC,FID) to get L2 entry */ -+ memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); -+ l2Table.ivl_svl = pL2_data->ivl; -+ l2Table.cvid_fid = pL2_data->cvid; -+ l2Table.fid = pL2_data->fid; -+ l2Table.efid = pL2_data->efid; -+ method = LUTREADMETHOD_MAC; -+ retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); -+ if (RT_ERR_OK == retVal) -+ { -+ memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); -+ l2Table.ivl_svl = pL2_data->ivl; -+ l2Table.cvid_fid = pL2_data->cvid; -+ l2Table.fid = pL2_data->fid; -+ l2Table.efid = pL2_data->efid; -+ l2Table.spa = 0; -+ l2Table.nosalearn = 0; -+ l2Table.sa_block = 0; -+ l2Table.da_block = 0; -+ l2Table.auth = 0; -+ l2Table.age = 0; -+ l2Table.lut_pri = 0; -+ l2Table.sa_en = 0; -+ l2Table.fwd_en = 0; -+ if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) -+ return retVal; -+ -+ pL2_data->address = l2Table.address; -+ return RT_ERR_OK; -+ } -+ else -+ return retVal; -+} -+ -+/* Function Name: -+ * rtk_l2_mcastAddr_add -+ * Description: -+ * Add LUT multicast entry. -+ * Input: -+ * pMcastAddr - L2 multicast entry structure -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_MAC - Invalid MAC address. -+ * RT_ERR_L2_FID - Invalid FID . -+ * RT_ERR_L2_VID - Invalid VID . -+ * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. -+ * RT_ERR_PORT_MASK - Invalid portmask. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * If the multicast mac address already existed in the LUT, it will update the -+ * port mask of the entry. Otherwise, it will find an empty or asic auto learned -+ * entry to write. If all the entries with the same hash value can't be replaced, -+ * ASIC will return a RT_ERR_L2_INDEXTBL_FULL error. -+ */ -+rtk_api_ret_t rtk_l2_mcastAddr_add(rtk_l2_mcastAddr_t *pMcastAddr) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 method; -+ rtl8367c_luttb l2Table; -+ rtk_uint32 pmask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pMcastAddr) -+ return RT_ERR_NULL_POINTER; -+ -+ /* must be L2 multicast address */ -+ if( (pMcastAddr->mac.octet[0] & 0x01) != 0x01) -+ return RT_ERR_MAC; -+ -+ RTK_CHK_PORTMASK_VALID(&pMcastAddr->portmask); -+ -+ if(pMcastAddr->ivl == 1) -+ { -+ if (pMcastAddr->vid > RTL8367C_VIDMAX) -+ return RT_ERR_L2_VID; -+ } -+ else if(pMcastAddr->ivl == 0) -+ { -+ if (pMcastAddr->fid > RTL8367C_FIDMAX) -+ return RT_ERR_L2_FID; -+ } -+ else -+ return RT_ERR_INPUT; -+ -+ if(pMcastAddr->fwd_pri_en >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if(pMcastAddr->priority > RTL8367C_PRIMAX) -+ return RT_ERR_INPUT; -+ -+ /* Get physical port mask */ -+ if ((retVal = rtk_switch_portmask_L2P_get(&pMcastAddr->portmask, &pmask)) != RT_ERR_OK) -+ return retVal; -+ -+ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); -+ -+ /* fill key (MAC,FID) to get L2 entry */ -+ memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); -+ l2Table.ivl_svl = pMcastAddr->ivl; -+ -+ if(pMcastAddr->ivl) -+ l2Table.cvid_fid = pMcastAddr->vid; -+ else -+ l2Table.cvid_fid = pMcastAddr->fid; -+ -+ method = LUTREADMETHOD_MAC; -+ retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); -+ if (RT_ERR_OK == retVal) -+ { -+ memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); -+ l2Table.ivl_svl = pMcastAddr->ivl; -+ -+ if(pMcastAddr->ivl) -+ l2Table.cvid_fid = pMcastAddr->vid; -+ else -+ l2Table.cvid_fid = pMcastAddr->fid; -+ -+ l2Table.mbr = pmask; -+ l2Table.nosalearn = 1; -+ l2Table.l3lookup = 0; -+ l2Table.lut_pri = pMcastAddr->priority; -+ l2Table.fwd_en = pMcastAddr->fwd_pri_en; -+ if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) -+ return retVal; -+ -+ pMcastAddr->address = l2Table.address; -+ return RT_ERR_OK; -+ } -+ else if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) -+ { -+ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); -+ memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); -+ l2Table.ivl_svl = pMcastAddr->ivl; -+ if(pMcastAddr->ivl) -+ l2Table.cvid_fid = pMcastAddr->vid; -+ else -+ l2Table.cvid_fid = pMcastAddr->fid; -+ -+ l2Table.mbr = pmask; -+ l2Table.nosalearn = 1; -+ l2Table.l3lookup = 0; -+ l2Table.lut_pri = pMcastAddr->priority; -+ l2Table.fwd_en = pMcastAddr->fwd_pri_en; -+ if ((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) -+ return retVal; -+ -+ pMcastAddr->address = l2Table.address; -+ -+ method = LUTREADMETHOD_MAC; -+ retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); -+ if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) -+ return RT_ERR_L2_INDEXTBL_FULL; -+ else -+ return retVal; -+ } -+ else -+ return retVal; -+ -+} -+ -+/* Function Name: -+ * rtk_l2_mcastAddr_get -+ * Description: -+ * Get LUT multicast entry. -+ * Input: -+ * pMcastAddr - L2 multicast entry structure -+ * Output: -+ * pMcastAddr - L2 multicast entry structure -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_MAC - Invalid MAC address. -+ * RT_ERR_L2_FID - Invalid FID . -+ * RT_ERR_L2_VID - Invalid VID . -+ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * If the multicast mac address existed in the LUT, it will return the port where -+ * the mac is learned. Otherwise, it will return a RT_ERR_L2_ENTRY_NOTFOUND error. -+ */ -+rtk_api_ret_t rtk_l2_mcastAddr_get(rtk_l2_mcastAddr_t *pMcastAddr) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 method; -+ rtl8367c_luttb l2Table; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pMcastAddr) -+ return RT_ERR_NULL_POINTER; -+ -+ /* must be L2 multicast address */ -+ if( (pMcastAddr->mac.octet[0] & 0x01) != 0x01) -+ return RT_ERR_MAC; -+ -+ if(pMcastAddr->ivl == 1) -+ { -+ if (pMcastAddr->vid > RTL8367C_VIDMAX) -+ return RT_ERR_L2_VID; -+ } -+ else if(pMcastAddr->ivl == 0) -+ { -+ if (pMcastAddr->fid > RTL8367C_FIDMAX) -+ return RT_ERR_L2_FID; -+ } -+ else -+ return RT_ERR_INPUT; -+ -+ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); -+ memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); -+ l2Table.ivl_svl = pMcastAddr->ivl; -+ -+ if(pMcastAddr->ivl) -+ l2Table.cvid_fid = pMcastAddr->vid; -+ else -+ l2Table.cvid_fid = pMcastAddr->fid; -+ -+ method = LUTREADMETHOD_MAC; -+ -+ if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) -+ return retVal; -+ -+ pMcastAddr->priority = l2Table.lut_pri; -+ pMcastAddr->fwd_pri_en = l2Table.fwd_en; -+ pMcastAddr->igmp_asic = l2Table.igmp_asic; -+ pMcastAddr->igmp_index = l2Table.igmpidx; -+ pMcastAddr->address = l2Table.address; -+ -+ /* Get Logical port mask */ -+ if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pMcastAddr->portmask)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_mcastAddr_next_get -+ * Description: -+ * Get Next L2 Multicast entry. -+ * Input: -+ * pAddress - The Address ID -+ * Output: -+ * pMcastAddr - L2 multicast entry structure -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * Get the next L2 multicast entry after the current entry pointed by pAddress. -+ * The address of next entry is returned by pAddress. User can use (address + 1) -+ * as pAddress to call this API again for dumping all multicast entries is LUT. -+ */ -+rtk_api_ret_t rtk_l2_mcastAddr_next_get(rtk_uint32 *pAddress, rtk_l2_mcastAddr_t *pMcastAddr) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_luttb l2Table; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Error Checking */ -+ if ((pAddress == NULL) || (pMcastAddr == NULL)) -+ return RT_ERR_INPUT; -+ -+ if(*pAddress > RTK_MAX_LUT_ADDR_ID ) -+ return RT_ERR_L2_L2UNI_PARAM; -+ -+ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); -+ l2Table.address = *pAddress; -+ -+ if ((retVal = rtl8367c_getAsicL2LookupTb(LUTREADMETHOD_NEXT_L2MC, &l2Table)) != RT_ERR_OK) -+ return retVal; -+ -+ if(l2Table.address < *pAddress) -+ return RT_ERR_L2_ENTRY_NOTFOUND; -+ -+ memcpy(pMcastAddr->mac.octet, l2Table.mac.octet, ETHER_ADDR_LEN); -+ pMcastAddr->ivl = l2Table.ivl_svl; -+ -+ if(pMcastAddr->ivl) -+ pMcastAddr->vid = l2Table.cvid_fid; -+ else -+ pMcastAddr->fid = l2Table.cvid_fid; -+ -+ pMcastAddr->priority = l2Table.lut_pri; -+ pMcastAddr->fwd_pri_en = l2Table.fwd_en; -+ pMcastAddr->igmp_asic = l2Table.igmp_asic; -+ pMcastAddr->igmp_index = l2Table.igmpidx; -+ pMcastAddr->address = l2Table.address; -+ -+ /* Get Logical port mask */ -+ if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pMcastAddr->portmask)) != RT_ERR_OK) -+ return retVal; -+ -+ *pAddress = l2Table.address; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_mcastAddr_del -+ * Description: -+ * Delete LUT multicast entry. -+ * Input: -+ * pMcastAddr - L2 multicast entry structure -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_MAC - Invalid MAC address. -+ * RT_ERR_L2_FID - Invalid FID . -+ * RT_ERR_L2_VID - Invalid VID . -+ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * If the mac has existed in the LUT, it will be deleted. Otherwise, it will return RT_ERR_L2_ENTRY_NOTFOUND. -+ */ -+rtk_api_ret_t rtk_l2_mcastAddr_del(rtk_l2_mcastAddr_t *pMcastAddr) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 method; -+ rtl8367c_luttb l2Table; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pMcastAddr) -+ return RT_ERR_NULL_POINTER; -+ -+ /* must be L2 multicast address */ -+ if( (pMcastAddr->mac.octet[0] & 0x01) != 0x01) -+ return RT_ERR_MAC; -+ -+ if(pMcastAddr->ivl == 1) -+ { -+ if (pMcastAddr->vid > RTL8367C_VIDMAX) -+ return RT_ERR_L2_VID; -+ } -+ else if(pMcastAddr->ivl == 0) -+ { -+ if (pMcastAddr->fid > RTL8367C_FIDMAX) -+ return RT_ERR_L2_FID; -+ } -+ else -+ return RT_ERR_INPUT; -+ -+ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); -+ -+ /* fill key (MAC,FID) to get L2 entry */ -+ memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); -+ l2Table.ivl_svl = pMcastAddr->ivl; -+ -+ if(pMcastAddr->ivl) -+ l2Table.cvid_fid = pMcastAddr->vid; -+ else -+ l2Table.cvid_fid = pMcastAddr->fid; -+ -+ method = LUTREADMETHOD_MAC; -+ retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); -+ if (RT_ERR_OK == retVal) -+ { -+ memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); -+ l2Table.ivl_svl = pMcastAddr->ivl; -+ -+ if(pMcastAddr->ivl) -+ l2Table.cvid_fid = pMcastAddr->vid; -+ else -+ l2Table.cvid_fid = pMcastAddr->fid; -+ -+ l2Table.mbr = 0; -+ l2Table.nosalearn = 0; -+ l2Table.sa_block = 0; -+ l2Table.l3lookup = 0; -+ l2Table.lut_pri = 0; -+ l2Table.fwd_en = 0; -+ if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) -+ return retVal; -+ -+ pMcastAddr->address = l2Table.address; -+ return RT_ERR_OK; -+ } -+ else -+ return retVal; -+} -+ -+/* Function Name: -+ * rtk_l2_ipMcastAddr_add -+ * Description: -+ * Add LUT IP multicast entry -+ * Input: -+ * pIpMcastAddr - IP Multicast entry -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. -+ * RT_ERR_PORT_MASK - Invalid portmask. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * System supports L2 entry with IP multicast DIP/SIP to forward IP multicasting frame as user -+ * desired. If this function is enabled, then system will be looked up L2 IP multicast entry to -+ * forward IP multicast frame directly without flooding. -+ */ -+rtk_api_ret_t rtk_l2_ipMcastAddr_add(rtk_l2_ipMcastAddr_t *pIpMcastAddr) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 method; -+ rtl8367c_luttb l2Table; -+ rtk_uint32 pmask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pIpMcastAddr) -+ return RT_ERR_NULL_POINTER; -+ -+ /* check port mask */ -+ RTK_CHK_PORTMASK_VALID(&pIpMcastAddr->portmask); -+ -+ if( (pIpMcastAddr->dip & 0xF0000000) != 0xE0000000) -+ return RT_ERR_INPUT; -+ -+ if(pIpMcastAddr->fwd_pri_en >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ if(pIpMcastAddr->priority > RTL8367C_PRIMAX) -+ return RT_ERR_INPUT; -+ -+ /* Get Physical port mask */ -+ if ((retVal = rtk_switch_portmask_L2P_get(&pIpMcastAddr->portmask, &pmask)) != RT_ERR_OK) -+ return retVal; -+ -+ memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); -+ l2Table.sip = pIpMcastAddr->sip; -+ l2Table.dip = pIpMcastAddr->dip; -+ l2Table.l3lookup = 1; -+ l2Table.l3vidlookup = 0; -+ method = LUTREADMETHOD_MAC; -+ retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); -+ if (RT_ERR_OK == retVal) -+ { -+ l2Table.sip = pIpMcastAddr->sip; -+ l2Table.dip = pIpMcastAddr->dip; -+ l2Table.mbr = pmask; -+ l2Table.nosalearn = 1; -+ l2Table.l3lookup = 1; -+ l2Table.l3vidlookup = 0; -+ l2Table.lut_pri = pIpMcastAddr->priority; -+ l2Table.fwd_en = pIpMcastAddr->fwd_pri_en; -+ if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) -+ return retVal; -+ -+ pIpMcastAddr->address = l2Table.address; -+ return RT_ERR_OK; -+ } -+ else if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) -+ { -+ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); -+ l2Table.sip = pIpMcastAddr->sip; -+ l2Table.dip = pIpMcastAddr->dip; -+ l2Table.mbr = pmask; -+ l2Table.nosalearn = 1; -+ l2Table.l3lookup = 1; -+ l2Table.l3vidlookup = 0; -+ l2Table.lut_pri = pIpMcastAddr->priority; -+ l2Table.fwd_en = pIpMcastAddr->fwd_pri_en; -+ if ((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) -+ return retVal; -+ -+ pIpMcastAddr->address = l2Table.address; -+ -+ method = LUTREADMETHOD_MAC; -+ retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); -+ if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) -+ return RT_ERR_L2_INDEXTBL_FULL; -+ else -+ return retVal; -+ -+ } -+ else -+ return retVal; -+ -+} -+ -+/* Function Name: -+ * rtk_l2_ipMcastAddr_get -+ * Description: -+ * Get LUT IP multicast entry. -+ * Input: -+ * pIpMcastAddr - IP Multicast entry -+ * Output: -+ * pIpMcastAddr - IP Multicast entry -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can get LUT table of IP multicast entry. -+ */ -+rtk_api_ret_t rtk_l2_ipMcastAddr_get(rtk_l2_ipMcastAddr_t *pIpMcastAddr) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 method; -+ rtl8367c_luttb l2Table; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pIpMcastAddr) -+ return RT_ERR_NULL_POINTER; -+ -+ if( (pIpMcastAddr->dip & 0xF0000000) != 0xE0000000) -+ return RT_ERR_INPUT; -+ -+ memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); -+ l2Table.sip = pIpMcastAddr->sip; -+ l2Table.dip = pIpMcastAddr->dip; -+ l2Table.l3lookup = 1; -+ l2Table.l3vidlookup = 0; -+ method = LUTREADMETHOD_MAC; -+ if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) -+ return retVal; -+ -+ /* Get Logical port mask */ -+ if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pIpMcastAddr->portmask)) != RT_ERR_OK) -+ return retVal; -+ -+ pIpMcastAddr->priority = l2Table.lut_pri; -+ pIpMcastAddr->fwd_pri_en = l2Table.fwd_en; -+ pIpMcastAddr->igmp_asic = l2Table.igmp_asic; -+ pIpMcastAddr->igmp_index = l2Table.igmpidx; -+ pIpMcastAddr->address = l2Table.address; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_ipMcastAddr_next_get -+ * Description: -+ * Get Next IP Multicast entry. -+ * Input: -+ * pAddress - The Address ID -+ * Output: -+ * pIpMcastAddr - IP Multicast entry -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * Get the next IP multicast entry after the current entry pointed by pAddress. -+ * The address of next entry is returned by pAddress. User can use (address + 1) -+ * as pAddress to call this API again for dumping all IP multicast entries is LUT. -+ */ -+rtk_api_ret_t rtk_l2_ipMcastAddr_next_get(rtk_uint32 *pAddress, rtk_l2_ipMcastAddr_t *pIpMcastAddr) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_luttb l2Table; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Error Checking */ -+ if ((pAddress == NULL) || (pIpMcastAddr == NULL) ) -+ return RT_ERR_INPUT; -+ -+ if(*pAddress > RTK_MAX_LUT_ADDR_ID ) -+ return RT_ERR_L2_L2UNI_PARAM; -+ -+ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); -+ l2Table.address = *pAddress; -+ -+ do -+ { -+ if ((retVal = rtl8367c_getAsicL2LookupTb(LUTREADMETHOD_NEXT_L3MC, &l2Table)) != RT_ERR_OK) -+ return retVal; -+ -+ if(l2Table.address < *pAddress) -+ return RT_ERR_L2_ENTRY_NOTFOUND; -+ -+ }while(l2Table.l3vidlookup == 1); -+ -+ pIpMcastAddr->sip = l2Table.sip; -+ pIpMcastAddr->dip = l2Table.dip; -+ -+ /* Get Logical port mask */ -+ if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pIpMcastAddr->portmask)) != RT_ERR_OK) -+ return retVal; -+ -+ pIpMcastAddr->priority = l2Table.lut_pri; -+ pIpMcastAddr->fwd_pri_en = l2Table.fwd_en; -+ pIpMcastAddr->igmp_asic = l2Table.igmp_asic; -+ pIpMcastAddr->igmp_index = l2Table.igmpidx; -+ pIpMcastAddr->address = l2Table.address; -+ *pAddress = l2Table.address; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_ipMcastAddr_del -+ * Description: -+ * Delete a ip multicast address entry from the specified device. -+ * Input: -+ * pIpMcastAddr - IP Multicast entry -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can delete a IP multicast address entry from the specified device. -+ */ -+rtk_api_ret_t rtk_l2_ipMcastAddr_del(rtk_l2_ipMcastAddr_t *pIpMcastAddr) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 method; -+ rtl8367c_luttb l2Table; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Error Checking */ -+ if (pIpMcastAddr == NULL) -+ return RT_ERR_INPUT; -+ -+ if( (pIpMcastAddr->dip & 0xF0000000) != 0xE0000000) -+ return RT_ERR_INPUT; -+ -+ memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); -+ l2Table.sip = pIpMcastAddr->sip; -+ l2Table.dip = pIpMcastAddr->dip; -+ l2Table.l3lookup = 1; -+ l2Table.l3vidlookup = 0; -+ method = LUTREADMETHOD_MAC; -+ retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); -+ if (RT_ERR_OK == retVal) -+ { -+ l2Table.sip = pIpMcastAddr->sip; -+ l2Table.dip = pIpMcastAddr->dip; -+ l2Table.mbr = 0; -+ l2Table.nosalearn = 0; -+ l2Table.l3lookup = 1; -+ l2Table.l3vidlookup = 0; -+ l2Table.lut_pri = 0; -+ l2Table.fwd_en = 0; -+ if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) -+ return retVal; -+ -+ pIpMcastAddr->address = l2Table.address; -+ return RT_ERR_OK; -+ } -+ else -+ return retVal; -+} -+ -+/* Function Name: -+ * rtk_l2_ipVidMcastAddr_add -+ * Description: -+ * Add LUT IP multicast+VID entry -+ * Input: -+ * pIpVidMcastAddr - IP & VID multicast Entry -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. -+ * RT_ERR_PORT_MASK - Invalid portmask. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_l2_ipVidMcastAddr_add(rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 method; -+ rtl8367c_luttb l2Table; -+ rtk_uint32 pmask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pIpVidMcastAddr) -+ return RT_ERR_NULL_POINTER; -+ -+ /* check port mask */ -+ RTK_CHK_PORTMASK_VALID(&pIpVidMcastAddr->portmask); -+ -+ if (pIpVidMcastAddr->vid > RTL8367C_VIDMAX) -+ return RT_ERR_L2_VID; -+ -+ if( (pIpVidMcastAddr->dip & 0xF0000000) != 0xE0000000) -+ return RT_ERR_INPUT; -+ -+ /* Get Physical port mask */ -+ if ((retVal = rtk_switch_portmask_L2P_get(&pIpVidMcastAddr->portmask, &pmask)) != RT_ERR_OK) -+ return retVal; -+ -+ memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); -+ l2Table.sip = pIpVidMcastAddr->sip; -+ l2Table.dip = pIpVidMcastAddr->dip; -+ l2Table.l3lookup = 1; -+ l2Table.l3vidlookup = 1; -+ l2Table.l3_vid = pIpVidMcastAddr->vid; -+ method = LUTREADMETHOD_MAC; -+ retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); -+ if (RT_ERR_OK == retVal) -+ { -+ l2Table.sip = pIpVidMcastAddr->sip; -+ l2Table.dip = pIpVidMcastAddr->dip; -+ l2Table.mbr = pmask; -+ l2Table.nosalearn = 1; -+ l2Table.l3lookup = 1; -+ l2Table.l3vidlookup = 1; -+ l2Table.l3_vid = pIpVidMcastAddr->vid; -+ if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) -+ return retVal; -+ -+ pIpVidMcastAddr->address = l2Table.address; -+ return RT_ERR_OK; -+ } -+ else if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) -+ { -+ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); -+ l2Table.sip = pIpVidMcastAddr->sip; -+ l2Table.dip = pIpVidMcastAddr->dip; -+ l2Table.mbr = pmask; -+ l2Table.nosalearn = 1; -+ l2Table.l3lookup = 1; -+ l2Table.l3vidlookup = 1; -+ l2Table.l3_vid = pIpVidMcastAddr->vid; -+ if ((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) -+ return retVal; -+ -+ pIpVidMcastAddr->address = l2Table.address; -+ -+ method = LUTREADMETHOD_MAC; -+ retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); -+ if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) -+ return RT_ERR_L2_INDEXTBL_FULL; -+ else -+ return retVal; -+ -+ } -+ else -+ return retVal; -+} -+ -+/* Function Name: -+ * rtk_l2_ipVidMcastAddr_get -+ * Description: -+ * Get LUT IP multicast+VID entry. -+ * Input: -+ * pIpVidMcastAddr - IP & VID multicast Entry -+ * Output: -+ * pIpVidMcastAddr - IP & VID multicast Entry -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_l2_ipVidMcastAddr_get(rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 method; -+ rtl8367c_luttb l2Table; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pIpVidMcastAddr) -+ return RT_ERR_NULL_POINTER; -+ -+ if (pIpVidMcastAddr->vid > RTL8367C_VIDMAX) -+ return RT_ERR_L2_VID; -+ -+ if( (pIpVidMcastAddr->dip & 0xF0000000) != 0xE0000000) -+ return RT_ERR_INPUT; -+ -+ memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); -+ l2Table.sip = pIpVidMcastAddr->sip; -+ l2Table.dip = pIpVidMcastAddr->dip; -+ l2Table.l3lookup = 1; -+ l2Table.l3vidlookup = 1; -+ l2Table.l3_vid = pIpVidMcastAddr->vid; -+ method = LUTREADMETHOD_MAC; -+ if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) -+ return retVal; -+ -+ pIpVidMcastAddr->address = l2Table.address; -+ -+ /* Get Logical port mask */ -+ if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pIpVidMcastAddr->portmask)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_ipVidMcastAddr_next_get -+ * Description: -+ * Get Next IP Multicast+VID entry. -+ * Input: -+ * pAddress - The Address ID -+ * Output: -+ * pIpVidMcastAddr - IP & VID multicast Entry -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * Get the next IP multicast entry after the current entry pointed by pAddress. -+ * The address of next entry is returned by pAddress. User can use (address + 1) -+ * as pAddress to call this API again for dumping all IP multicast entries is LUT. -+ */ -+rtk_api_ret_t rtk_l2_ipVidMcastAddr_next_get(rtk_uint32 *pAddress, rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_luttb l2Table; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Error Checking */ -+ if ((pAddress == NULL) || (pIpVidMcastAddr == NULL)) -+ return RT_ERR_INPUT; -+ -+ if(*pAddress > RTK_MAX_LUT_ADDR_ID ) -+ return RT_ERR_L2_L2UNI_PARAM; -+ -+ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); -+ l2Table.address = *pAddress; -+ -+ do -+ { -+ if ((retVal = rtl8367c_getAsicL2LookupTb(LUTREADMETHOD_NEXT_L3MC, &l2Table)) != RT_ERR_OK) -+ return retVal; -+ -+ if(l2Table.address < *pAddress) -+ return RT_ERR_L2_ENTRY_NOTFOUND; -+ -+ }while(l2Table.l3vidlookup == 0); -+ -+ pIpVidMcastAddr->sip = l2Table.sip; -+ pIpVidMcastAddr->dip = l2Table.dip; -+ pIpVidMcastAddr->vid = l2Table.l3_vid; -+ pIpVidMcastAddr->address = l2Table.address; -+ -+ /* Get Logical port mask */ -+ if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pIpVidMcastAddr->portmask)) != RT_ERR_OK) -+ return retVal; -+ -+ *pAddress = l2Table.address; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_ipVidMcastAddr_del -+ * Description: -+ * Delete a ip multicast+VID address entry from the specified device. -+ * Input: -+ * pIpVidMcastAddr - IP & VID multicast Entry -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_l2_ipVidMcastAddr_del(rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 method; -+ rtl8367c_luttb l2Table; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pIpVidMcastAddr) -+ return RT_ERR_NULL_POINTER; -+ -+ if (pIpVidMcastAddr->vid > RTL8367C_VIDMAX) -+ return RT_ERR_L2_VID; -+ -+ if( (pIpVidMcastAddr->dip & 0xF0000000) != 0xE0000000) -+ return RT_ERR_INPUT; -+ -+ memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); -+ l2Table.sip = pIpVidMcastAddr->sip; -+ l2Table.dip = pIpVidMcastAddr->dip; -+ l2Table.l3lookup = 1; -+ l2Table.l3vidlookup = 1; -+ l2Table.l3_vid = pIpVidMcastAddr->vid; -+ method = LUTREADMETHOD_MAC; -+ retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); -+ if (RT_ERR_OK == retVal) -+ { -+ l2Table.sip = pIpVidMcastAddr->sip; -+ l2Table.dip = pIpVidMcastAddr->dip; -+ l2Table.mbr= 0; -+ l2Table.nosalearn = 0; -+ l2Table.l3lookup = 1; -+ l2Table.l3vidlookup = 1; -+ l2Table.l3_vid = pIpVidMcastAddr->vid; -+ if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) -+ return retVal; -+ -+ pIpVidMcastAddr->address = l2Table.address; -+ return RT_ERR_OK; -+ } -+ else -+ return retVal; -+} -+ -+/* Function Name: -+ * rtk_l2_ucastAddr_flush -+ * Description: -+ * Flush L2 mac address by type in the specified device (both dynamic and static). -+ * Input: -+ * pConfig - flush configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_VLAN_VID - Invalid VID parameter. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * flushByVid - 1: Flush by VID, 0: Don't flush by VID -+ * vid - VID (0 ~ 4095) -+ * flushByFid - 1: Flush by FID, 0: Don't flush by FID -+ * fid - FID (0 ~ 15) -+ * flushByPort - 1: Flush by Port, 0: Don't flush by Port -+ * port - Port ID -+ * flushByMac - Not Supported -+ * ucastAddr - Not Supported -+ * flushStaticAddr - 1: Flush both Static and Dynamic entries, 0: Flush only Dynamic entries -+ * flushAddrOnAllPorts - 1: Flush VID-matched entries at all ports, 0: Flush VID-matched entries per port. -+ */ -+rtk_api_ret_t rtk_l2_ucastAddr_flush(rtk_l2_flushCfg_t *pConfig) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(pConfig == NULL) -+ return RT_ERR_NULL_POINTER; -+ -+ if(pConfig->flushByVid >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ if(pConfig->flushByFid >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ if(pConfig->flushByPort >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ if(pConfig->flushByMac >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ if(pConfig->flushStaticAddr >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ if(pConfig->flushAddrOnAllPorts >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ if(pConfig->vid > RTL8367C_VIDMAX) -+ return RT_ERR_VLAN_VID; -+ -+ if(pConfig->fid > RTL8367C_FIDMAX) -+ return RT_ERR_INPUT; -+ -+ /* check port valid */ -+ RTK_CHK_PORT_VALID(pConfig->port); -+ -+ if(pConfig->flushByVid == ENABLED) -+ { -+ if ((retVal = rtl8367c_setAsicLutFlushMode(FLUSHMDOE_VID)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicLutFlushVid(pConfig->vid)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicLutFlushType((pConfig->flushStaticAddr == ENABLED) ? FLUSHTYPE_BOTH : FLUSHTYPE_DYNAMIC)) != RT_ERR_OK) -+ return retVal; -+ -+ if(pConfig->flushAddrOnAllPorts == ENABLED) -+ { -+ if ((retVal = rtl8367c_setAsicLutForceFlush(RTL8367C_PORTMASK)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if(pConfig->flushByPort == ENABLED) -+ { -+ if ((retVal = rtl8367c_setAsicLutForceFlush(1 << rtk_switch_port_L2P_get(pConfig->port))) != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ return RT_ERR_INPUT; -+ } -+ else if(pConfig->flushByFid == ENABLED) -+ { -+ if ((retVal = rtl8367c_setAsicLutFlushMode(FLUSHMDOE_FID)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicLutFlushFid(pConfig->fid)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicLutFlushType((pConfig->flushStaticAddr == ENABLED) ? FLUSHTYPE_BOTH : FLUSHTYPE_DYNAMIC)) != RT_ERR_OK) -+ return retVal; -+ -+ if(pConfig->flushAddrOnAllPorts == ENABLED) -+ { -+ if ((retVal = rtl8367c_setAsicLutForceFlush(RTL8367C_PORTMASK)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if(pConfig->flushByPort == ENABLED) -+ { -+ if ((retVal = rtl8367c_setAsicLutForceFlush(1 << rtk_switch_port_L2P_get(pConfig->port))) != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ return RT_ERR_INPUT; -+ } -+ else if(pConfig->flushByPort == ENABLED) -+ { -+ if ((retVal = rtl8367c_setAsicLutFlushType((pConfig->flushStaticAddr == ENABLED) ? FLUSHTYPE_BOTH : FLUSHTYPE_DYNAMIC)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicLutFlushMode(FLUSHMDOE_PORT)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicLutForceFlush(1 << rtk_switch_port_L2P_get(pConfig->port))) != RT_ERR_OK) -+ return retVal; -+ } -+ else if(pConfig->flushByMac == ENABLED) -+ { -+ /* Should use API "rtk_l2_addr_del" to remove a specified entry*/ -+ return RT_ERR_CHIP_NOT_SUPPORTED; -+ } -+ else -+ return RT_ERR_INPUT; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_table_clear -+ * Description: -+ * Flush all static & dynamic entries in LUT. -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_l2_table_clear(void) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if ((retVal = rtl8367c_setAsicLutFlushAll()) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_table_clearStatus_get -+ * Description: -+ * Get table clear status -+ * Input: -+ * None -+ * Output: -+ * pStatus - Clear status, 1:Busy, 0:finish -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_l2_table_clearStatus_get(rtk_l2_clearStatus_t *pStatus) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pStatus) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicLutFlushAllStatus((rtk_uint32 *)pStatus)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_flushLinkDownPortAddrEnable_set -+ * Description: -+ * Set HW flush linkdown port mac configuration of the specified device. -+ * Input: -+ * port - Port id. -+ * enable - link down flush status -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_ENABLE - Invalid enable input. -+ * Note: -+ * The status of flush linkdown port address is as following: -+ * - DISABLED -+ * - ENABLED -+ */ -+rtk_api_ret_t rtk_l2_flushLinkDownPortAddrEnable_set(rtk_port_t port, rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (port != RTK_WHOLE_SYSTEM) -+ return RT_ERR_PORT_ID; -+ -+ if (enable >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ if ((retVal = rtl8367c_setAsicLutLinkDownForceAging(enable)) != RT_ERR_OK) -+ return retVal; -+ -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_flushLinkDownPortAddrEnable_get -+ * Description: -+ * Get HW flush linkdown port mac configuration of the specified device. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pEnable - link down flush status -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The status of flush linkdown port address is as following: -+ * - DISABLED -+ * - ENABLED -+ */ -+rtk_api_ret_t rtk_l2_flushLinkDownPortAddrEnable_get(rtk_port_t port, rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (port != RTK_WHOLE_SYSTEM) -+ return RT_ERR_PORT_ID; -+ -+ if(NULL == pEnable) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicLutLinkDownForceAging(pEnable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_agingEnable_set -+ * Description: -+ * Set L2 LUT aging status per port setting. -+ * Input: -+ * port - Port id. -+ * enable - Aging status -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_ENABLE - Invalid enable input. -+ * Note: -+ * This API can be used to set L2 LUT aging status per port. -+ */ -+rtk_api_ret_t rtk_l2_agingEnable_set(rtk_port_t port, rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* check port valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (enable >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ if(enable == 1) -+ enable = 0; -+ else -+ enable = 1; -+ -+ if ((retVal = rtl8367c_setAsicLutDisableAging(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_agingEnable_get -+ * Description: -+ * Get L2 LUT aging status per port setting. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pEnable - Aging status -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * This API can be used to get L2 LUT aging function per port. -+ */ -+rtk_api_ret_t rtk_l2_agingEnable_get(rtk_port_t port, rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* check port valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(NULL == pEnable) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicLutDisableAging(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) -+ return retVal; -+ -+ if(*pEnable == 1) -+ *pEnable = 0; -+ else -+ *pEnable = 1; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_limitLearningCnt_set -+ * Description: -+ * Set per-Port auto learning limit number -+ * Input: -+ * port - Port id. -+ * mac_cnt - Auto learning entries limit number -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_LIMITED_L2ENTRY_NUM - Invalid auto learning limit number -+ * Note: -+ * The API can set per-port ASIC auto learning limit number from 0(disable learning) -+ * to 2112. -+ */ -+rtk_api_ret_t rtk_l2_limitLearningCnt_set(rtk_port_t port, rtk_mac_cnt_t mac_cnt) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* check port valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (mac_cnt > rtk_switch_maxLutAddrNumber_get()) -+ return RT_ERR_LIMITED_L2ENTRY_NUM; -+ -+ if ((retVal = rtl8367c_setAsicLutLearnLimitNo(rtk_switch_port_L2P_get(port), mac_cnt)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_limitLearningCnt_get -+ * Description: -+ * Get per-Port auto learning limit number -+ * Input: -+ * port - Port id. -+ * Output: -+ * pMac_cnt - Auto learning entries limit number -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get per-port ASIC auto learning limit number. -+ */ -+rtk_api_ret_t rtk_l2_limitLearningCnt_get(rtk_port_t port, rtk_mac_cnt_t *pMac_cnt) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* check port valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(NULL == pMac_cnt) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicLutLearnLimitNo(rtk_switch_port_L2P_get(port), pMac_cnt)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_limitSystemLearningCnt_set -+ * Description: -+ * Set System auto learning limit number -+ * Input: -+ * mac_cnt - Auto learning entries limit number -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_LIMITED_L2ENTRY_NUM - Invalid auto learning limit number -+ * Note: -+ * The API can set system ASIC auto learning limit number from 0(disable learning) -+ * to 2112. -+ */ -+rtk_api_ret_t rtk_l2_limitSystemLearningCnt_set(rtk_mac_cnt_t mac_cnt) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (mac_cnt > rtk_switch_maxLutAddrNumber_get()) -+ return RT_ERR_LIMITED_L2ENTRY_NUM; -+ -+ if ((retVal = rtl8367c_setAsicSystemLutLearnLimitNo(mac_cnt)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_limitSystemLearningCnt_get -+ * Description: -+ * Get System auto learning limit number -+ * Input: -+ * None -+ * Output: -+ * pMac_cnt - Auto learning entries limit number -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get system ASIC auto learning limit number. -+ */ -+rtk_api_ret_t rtk_l2_limitSystemLearningCnt_get(rtk_mac_cnt_t *pMac_cnt) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pMac_cnt) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicSystemLutLearnLimitNo(pMac_cnt)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_limitLearningCntAction_set -+ * Description: -+ * Configure auto learn over limit number action. -+ * Input: -+ * port - Port id. -+ * action - Auto learning entries limit number -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_NOT_ALLOWED - Invalid learn over action -+ * Note: -+ * The API can set SA unknown packet action while auto learn limit number is over -+ * The action symbol as following: -+ * - LIMIT_LEARN_CNT_ACTION_DROP, -+ * - LIMIT_LEARN_CNT_ACTION_FORWARD, -+ * - LIMIT_LEARN_CNT_ACTION_TO_CPU, -+ */ -+rtk_api_ret_t rtk_l2_limitLearningCntAction_set(rtk_port_t port, rtk_l2_limitLearnCntAction_t action) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 data; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (port != RTK_WHOLE_SYSTEM) -+ return RT_ERR_PORT_ID; -+ -+ if ( LIMIT_LEARN_CNT_ACTION_DROP == action ) -+ data = 1; -+ else if ( LIMIT_LEARN_CNT_ACTION_FORWARD == action ) -+ data = 0; -+ else if ( LIMIT_LEARN_CNT_ACTION_TO_CPU == action ) -+ data = 2; -+ else -+ return RT_ERR_NOT_ALLOWED; -+ -+ if ((retVal = rtl8367c_setAsicLutLearnOverAct(data)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_limitLearningCntAction_get -+ * Description: -+ * Get auto learn over limit number action. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pAction - Learn over action -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get SA unknown packet action while auto learn limit number is over -+ * The action symbol as following: -+ * - LIMIT_LEARN_CNT_ACTION_DROP, -+ * - LIMIT_LEARN_CNT_ACTION_FORWARD, -+ * - LIMIT_LEARN_CNT_ACTION_TO_CPU, -+ */ -+rtk_api_ret_t rtk_l2_limitLearningCntAction_get(rtk_port_t port, rtk_l2_limitLearnCntAction_t *pAction) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 action; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (port != RTK_WHOLE_SYSTEM) -+ return RT_ERR_PORT_ID; -+ -+ if(NULL == pAction) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicLutLearnOverAct(&action)) != RT_ERR_OK) -+ return retVal; -+ -+ if ( 1 == action ) -+ *pAction = LIMIT_LEARN_CNT_ACTION_DROP; -+ else if ( 0 == action ) -+ *pAction = LIMIT_LEARN_CNT_ACTION_FORWARD; -+ else if ( 2 == action ) -+ *pAction = LIMIT_LEARN_CNT_ACTION_TO_CPU; -+ else -+ *pAction = action; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_limitSystemLearningCntAction_set -+ * Description: -+ * Configure system auto learn over limit number action. -+ * Input: -+ * port - Port id. -+ * action - Auto learning entries limit number -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_NOT_ALLOWED - Invalid learn over action -+ * Note: -+ * The API can set SA unknown packet action while auto learn limit number is over -+ * The action symbol as following: -+ * - LIMIT_LEARN_CNT_ACTION_DROP, -+ * - LIMIT_LEARN_CNT_ACTION_FORWARD, -+ * - LIMIT_LEARN_CNT_ACTION_TO_CPU, -+ */ -+rtk_api_ret_t rtk_l2_limitSystemLearningCntAction_set(rtk_l2_limitLearnCntAction_t action) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 data; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if ( LIMIT_LEARN_CNT_ACTION_DROP == action ) -+ data = 1; -+ else if ( LIMIT_LEARN_CNT_ACTION_FORWARD == action ) -+ data = 0; -+ else if ( LIMIT_LEARN_CNT_ACTION_TO_CPU == action ) -+ data = 2; -+ else -+ return RT_ERR_NOT_ALLOWED; -+ -+ if ((retVal = rtl8367c_setAsicSystemLutLearnOverAct(data)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_limitSystemLearningCntAction_get -+ * Description: -+ * Get system auto learn over limit number action. -+ * Input: -+ * None. -+ * Output: -+ * pAction - Learn over action -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get SA unknown packet action while auto learn limit number is over -+ * The action symbol as following: -+ * - LIMIT_LEARN_CNT_ACTION_DROP, -+ * - LIMIT_LEARN_CNT_ACTION_FORWARD, -+ * - LIMIT_LEARN_CNT_ACTION_TO_CPU, -+ */ -+rtk_api_ret_t rtk_l2_limitSystemLearningCntAction_get(rtk_l2_limitLearnCntAction_t *pAction) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 action; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pAction) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicSystemLutLearnOverAct(&action)) != RT_ERR_OK) -+ return retVal; -+ -+ if ( 1 == action ) -+ *pAction = LIMIT_LEARN_CNT_ACTION_DROP; -+ else if ( 0 == action ) -+ *pAction = LIMIT_LEARN_CNT_ACTION_FORWARD; -+ else if ( 2 == action ) -+ *pAction = LIMIT_LEARN_CNT_ACTION_TO_CPU; -+ else -+ *pAction = action; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_limitSystemLearningCntPortMask_set -+ * Description: -+ * Configure system auto learn portmask -+ * Input: -+ * pPortmask - Port Mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Invalid port mask. -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_l2_limitSystemLearningCntPortMask_set(rtk_portmask_t *pPortmask) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pmask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pPortmask) -+ return RT_ERR_NULL_POINTER; -+ -+ /* Check port mask */ -+ RTK_CHK_PORTMASK_VALID(pPortmask); -+ -+ if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicSystemLutLearnPortMask(pmask)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_limitSystemLearningCntPortMask_get -+ * Description: -+ * get system auto learn portmask -+ * Input: -+ * None -+ * Output: -+ * pPortmask - Port Mask -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Null pointer. -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_l2_limitSystemLearningCntPortMask_get(rtk_portmask_t *pPortmask) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pmask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pPortmask) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicSystemLutLearnPortMask(&pmask)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_learningCnt_get -+ * Description: -+ * Get per-Port current auto learning number -+ * Input: -+ * port - Port id. -+ * Output: -+ * pMac_cnt - ASIC auto learning entries number -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get per-port ASIC auto learning number -+ */ -+rtk_api_ret_t rtk_l2_learningCnt_get(rtk_port_t port, rtk_mac_cnt_t *pMac_cnt) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* check port valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(NULL == pMac_cnt) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicLutLearnNo(rtk_switch_port_L2P_get(port), pMac_cnt)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_floodPortMask_set -+ * Description: -+ * Set flooding portmask -+ * Input: -+ * type - flooding type. -+ * pFlood_portmask - flooding portmask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Invalid portmask. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can set the flooding mask. -+ * The flooding type is as following: -+ * - FLOOD_UNKNOWNDA -+ * - FLOOD_UNKNOWNMC -+ * - FLOOD_BC -+ */ -+rtk_api_ret_t rtk_l2_floodPortMask_set(rtk_l2_flood_type_t floood_type, rtk_portmask_t *pFlood_portmask) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pmask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (floood_type >= FLOOD_END) -+ return RT_ERR_INPUT; -+ -+ /* check port valid */ -+ RTK_CHK_PORTMASK_VALID(pFlood_portmask); -+ -+ /* Get Physical port mask */ -+ if ((retVal = rtk_switch_portmask_L2P_get(pFlood_portmask, &pmask))!=RT_ERR_OK) -+ return retVal; -+ -+ switch (floood_type) -+ { -+ case FLOOD_UNKNOWNDA: -+ if ((retVal = rtl8367c_setAsicPortUnknownDaFloodingPortmask(pmask)) != RT_ERR_OK) -+ return retVal; -+ break; -+ case FLOOD_UNKNOWNMC: -+ if ((retVal = rtl8367c_setAsicPortUnknownMulticastFloodingPortmask(pmask)) != RT_ERR_OK) -+ return retVal; -+ break; -+ case FLOOD_BC: -+ if ((retVal = rtl8367c_setAsicPortBcastFloodingPortmask(pmask)) != RT_ERR_OK) -+ return retVal; -+ break; -+ default: -+ break; -+ } -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtk_l2_floodPortMask_get -+ * Description: -+ * Get flooding portmask -+ * Input: -+ * type - flooding type. -+ * Output: -+ * pFlood_portmask - flooding portmask -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * This API can get the flooding mask. -+ * The flooding type is as following: -+ * - FLOOD_UNKNOWNDA -+ * - FLOOD_UNKNOWNMC -+ * - FLOOD_BC -+ */ -+rtk_api_ret_t rtk_l2_floodPortMask_get(rtk_l2_flood_type_t floood_type, rtk_portmask_t *pFlood_portmask) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pmask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (floood_type >= FLOOD_END) -+ return RT_ERR_INPUT; -+ -+ if(NULL == pFlood_portmask) -+ return RT_ERR_NULL_POINTER; -+ -+ switch (floood_type) -+ { -+ case FLOOD_UNKNOWNDA: -+ if ((retVal = rtl8367c_getAsicPortUnknownDaFloodingPortmask(&pmask)) != RT_ERR_OK) -+ return retVal; -+ break; -+ case FLOOD_UNKNOWNMC: -+ if ((retVal = rtl8367c_getAsicPortUnknownMulticastFloodingPortmask(&pmask)) != RT_ERR_OK) -+ return retVal; -+ break; -+ case FLOOD_BC: -+ if ((retVal = rtl8367c_getAsicPortBcastFloodingPortmask(&pmask)) != RT_ERR_OK) -+ return retVal; -+ break; -+ default: -+ break; -+ } -+ -+ /* Get Logical port mask */ -+ if ((retVal = rtk_switch_portmask_P2L_get(pmask, pFlood_portmask))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_localPktPermit_set -+ * Description: -+ * Set permission of frames if source port and destination port are the same. -+ * Input: -+ * port - Port id. -+ * permit - permission status -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_ENABLE - Invalid permit value. -+ * Note: -+ * This API is set to permit frame if its source port is equal to destination port. -+ */ -+rtk_api_ret_t rtk_l2_localPktPermit_set(rtk_port_t port, rtk_enable_t permit) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* check port valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (permit >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ if ((retVal = rtl8367c_setAsicPortBlockSpa(rtk_switch_port_L2P_get(port), permit)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_localPktPermit_get -+ * Description: -+ * Get permission of frames if source port and destination port are the same. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pPermit - permission status -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * This API is to get permission status for frames if its source port is equal to destination port. -+ */ -+rtk_api_ret_t rtk_l2_localPktPermit_get(rtk_port_t port, rtk_enable_t *pPermit) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* check port valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(NULL == pPermit) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicPortBlockSpa(rtk_switch_port_L2P_get(port), pPermit)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_aging_set -+ * Description: -+ * Set LUT ageing out speed -+ * Input: -+ * aging_time - Ageing out time. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * Note: -+ * The API can set LUT ageing out period for each entry and the range is from 45s to 458s. -+ */ -+rtk_api_ret_t rtk_l2_aging_set(rtk_l2_age_time_t aging_time) -+{ -+ rtk_uint32 i; -+ CONST_T rtk_uint32 agePara[10][3] = { -+ {45, 0, 1}, {88, 0, 2}, {133, 0, 3}, {177, 0, 4}, {221, 0, 5}, {266, 0, 6}, {310, 0, 7}, -+ {354, 2, 6}, {413, 2, 7}, {458, 3, 7}}; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (aging_time>agePara[9][0]) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ for (i = 0; i<10; i++) -+ { -+ if (aging_time<=agePara[i][0]) -+ { -+ return rtl8367c_setAsicLutAgeTimerSpeed(agePara[i][2], agePara[i][1]); -+ } -+ } -+ -+ return RT_ERR_FAILED; -+} -+ -+/* Function Name: -+ * rtk_l2_aging_get -+ * Description: -+ * Get LUT ageing out time -+ * Input: -+ * None -+ * Output: -+ * pEnable - Aging status -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get LUT ageing out period for each entry. -+ */ -+rtk_api_ret_t rtk_l2_aging_get(rtk_l2_age_time_t *pAging_time) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 i,time, speed; -+ CONST_T rtk_uint32 agePara[10][3] = { -+ {45, 0, 1}, {88, 0, 2}, {133, 0, 3}, {177, 0, 4}, {221, 0, 5}, {266, 0, 6}, {310, 0, 7}, -+ {354, 2, 6}, {413, 2, 7}, {458, 3, 7}}; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pAging_time) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicLutAgeTimerSpeed(&time, &speed)) != RT_ERR_OK) -+ return retVal; -+ -+ for (i = 0; i<10; i++) -+ { -+ if (time==agePara[i][2]&&speed==agePara[i][1]) -+ { -+ *pAging_time = agePara[i][0]; -+ return RT_ERR_OK; -+ } -+ } -+ -+ return RT_ERR_FAILED; -+} -+ -+/* Function Name: -+ * rtk_l2_ipMcastAddrLookup_set -+ * Description: -+ * Set LUT IP multicast lookup function -+ * Input: -+ * type - Lookup type for IPMC packet. -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * LOOKUP_MAC - Lookup by MAC address -+ * LOOKUP_IP - Lookup by IP address -+ * LOOKUP_IP_VID - Lookup by IP address & VLAN ID -+ */ -+rtk_api_ret_t rtk_l2_ipMcastAddrLookup_set(rtk_l2_ipmc_lookup_type_t type) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(type == LOOKUP_MAC) -+ { -+ if((retVal = rtl8367c_setAsicLutIpMulticastLookup(DISABLED)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if(type == LOOKUP_IP) -+ { -+ if((retVal = rtl8367c_setAsicLutIpMulticastLookup(ENABLED)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicLutIpMulticastVidLookup(DISABLED))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicLutIpLookupMethod(1))!=RT_ERR_OK) -+ return retVal; -+ } -+ else if(type == LOOKUP_IP_VID) -+ { -+ if((retVal = rtl8367c_setAsicLutIpMulticastLookup(ENABLED)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicLutIpMulticastVidLookup(ENABLED))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicLutIpLookupMethod(1))!=RT_ERR_OK) -+ return retVal; -+ } -+ else -+ return RT_ERR_INPUT; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_ipMcastAddrLookup_get -+ * Description: -+ * Get LUT IP multicast lookup function -+ * Input: -+ * None. -+ * Output: -+ * pType - Lookup type for IPMC packet. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None. -+ */ -+rtk_api_ret_t rtk_l2_ipMcastAddrLookup_get(rtk_l2_ipmc_lookup_type_t *pType) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 enabled, vid_lookup; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pType) -+ return RT_ERR_NULL_POINTER; -+ -+ if((retVal = rtl8367c_getAsicLutIpMulticastLookup(&enabled)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicLutIpMulticastVidLookup(&vid_lookup))!=RT_ERR_OK) -+ return retVal; -+ -+ if(enabled == ENABLED) -+ { -+ if(vid_lookup == ENABLED) -+ *pType = LOOKUP_IP_VID; -+ else -+ *pType = LOOKUP_IP; -+ } -+ else -+ *pType = LOOKUP_MAC; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_ipMcastForwardRouterPort_set -+ * Description: -+ * Set IPMC packet forward to router port also or not -+ * Input: -+ * enabled - 1: Include router port, 0, exclude router port -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_l2_ipMcastForwardRouterPort_set(rtk_enable_t enabled) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (enabled >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ if((retVal = rtl8367c_setAsicLutIpmcFwdRouterPort(enabled)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_ipMcastForwardRouterPort_get -+ * Description: -+ * Get IPMC packet forward to router port also or not -+ * Input: -+ * None. -+ * Output: -+ * pEnabled - 1: Include router port, 0, exclude router port -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_l2_ipMcastForwardRouterPort_get(rtk_enable_t *pEnabled) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (NULL == pEnabled) -+ return RT_ERR_NULL_POINTER; -+ -+ if((retVal = rtl8367c_getAsicLutIpmcFwdRouterPort(pEnabled)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_ipMcastGroupEntry_add -+ * Description: -+ * Add an IP Multicast entry to group table -+ * Input: -+ * ip_addr - IP address -+ * vid - VLAN ID -+ * pPortmask - portmask -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_TBL_FULL - Table Full -+ * Note: -+ * Add an entry to IP Multicast Group table. -+ */ -+rtk_api_ret_t rtk_l2_ipMcastGroupEntry_add(ipaddr_t ip_addr, rtk_uint32 vid, rtk_portmask_t *pPortmask) -+{ -+ rtk_uint32 empty_idx = 0xFFFF; -+ rtk_int32 index; -+ ipaddr_t group_addr; -+ rtk_uint32 group_vid; -+ rtk_uint32 pmask; -+ rtk_uint32 valid; -+ rtk_uint32 physicalPortmask; -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (vid > RTL8367C_VIDMAX) -+ return RT_ERR_L2_VID; -+ -+ if(NULL == pPortmask) -+ return RT_ERR_NULL_POINTER; -+ -+ if((ip_addr & 0xF0000000) != 0xE0000000) -+ return RT_ERR_INPUT; -+ -+ /* Get Physical port mask */ -+ if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &physicalPortmask))!=RT_ERR_OK) -+ return retVal; -+ -+ for(index = 0; index <= RTL8367C_LUT_IPMCGRP_TABLE_MAX; index++) -+ { -+ if ((retVal = rtl8367c_getAsicLutIPMCGroup((rtk_uint32)index, &group_addr, &group_vid, &pmask, &valid))!=RT_ERR_OK) -+ return retVal; -+ -+ if( (valid == ENABLED) && (group_addr == ip_addr) && (group_vid == vid) ) -+ { -+ if(pmask != physicalPortmask) -+ { -+ pmask = physicalPortmask; -+ if ((retVal = rtl8367c_setAsicLutIPMCGroup(index, ip_addr, vid, pmask, valid))!=RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+ } -+ -+ if( (valid == DISABLED) && (empty_idx == 0xFFFF) ) /* Unused */ -+ empty_idx = (rtk_uint32)index; -+ } -+ -+ if(empty_idx == 0xFFFF) -+ return RT_ERR_TBL_FULL; -+ -+ pmask = physicalPortmask; -+ if ((retVal = rtl8367c_setAsicLutIPMCGroup(empty_idx, ip_addr, vid, pmask, ENABLED))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_l2_ipMcastGroupEntry_del -+ * Description: -+ * Delete an entry from IP Multicast group table -+ * Input: -+ * ip_addr - IP address -+ * vid - VLAN ID -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_TBL_FULL - Table Full -+ * Note: -+ * Delete an entry from IP Multicast group table. -+ */ -+rtk_api_ret_t rtk_l2_ipMcastGroupEntry_del(ipaddr_t ip_addr, rtk_uint32 vid) -+{ -+ rtk_int32 index; -+ ipaddr_t group_addr; -+ rtk_uint32 group_vid; -+ rtk_uint32 pmask; -+ rtk_uint32 valid; -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (vid > RTL8367C_VIDMAX) -+ return RT_ERR_L2_VID; -+ -+ if((ip_addr & 0xF0000000) != 0xE0000000) -+ return RT_ERR_INPUT; -+ -+ for(index = 0; index <= RTL8367C_LUT_IPMCGRP_TABLE_MAX; index++) -+ { -+ if ((retVal = rtl8367c_getAsicLutIPMCGroup((rtk_uint32)index, &group_addr, &group_vid, &pmask, &valid))!=RT_ERR_OK) -+ return retVal; -+ -+ if( (valid == ENABLED) && (group_addr == ip_addr) && (group_vid == vid) ) -+ { -+ group_addr = 0xE0000000; -+ group_vid = 0; -+ pmask = 0; -+ if ((retVal = rtl8367c_setAsicLutIPMCGroup(index, group_addr, group_vid, pmask, DISABLED))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+ } -+ } -+ -+ return RT_ERR_FAILED; -+} -+ -+/* Function Name: -+ * rtk_l2_ipMcastGroupEntry_get -+ * Description: -+ * get an entry from IP Multicast group table -+ * Input: -+ * ip_addr - IP address -+ * vid - VLAN ID -+ * Output: -+ * pPortmask - member port mask -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_TBL_FULL - Table Full -+ * Note: -+ * Delete an entry from IP Multicast group table. -+ */ -+rtk_api_ret_t rtk_l2_ipMcastGroupEntry_get(ipaddr_t ip_addr, rtk_uint32 vid, rtk_portmask_t *pPortmask) -+{ -+ rtk_int32 index; -+ ipaddr_t group_addr; -+ rtk_uint32 group_vid; -+ rtk_uint32 valid; -+ rtk_uint32 pmask; -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if((ip_addr & 0xF0000000) != 0xE0000000) -+ return RT_ERR_INPUT; -+ -+ if (vid > RTL8367C_VIDMAX) -+ return RT_ERR_L2_VID; -+ -+ if(NULL == pPortmask) -+ return RT_ERR_NULL_POINTER; -+ -+ for(index = 0; index <= RTL8367C_LUT_IPMCGRP_TABLE_MAX; index++) -+ { -+ if ((retVal = rtl8367c_getAsicLutIPMCGroup((rtk_uint32)index, &group_addr, &group_vid, &pmask, &valid))!=RT_ERR_OK) -+ return retVal; -+ -+ if( (valid == ENABLED) && (group_addr == ip_addr) && (group_vid == vid) ) -+ { -+ if ((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+ } -+ } -+ -+ return RT_ERR_FAILED; -+} -+ -+/* Function Name: -+ * rtk_l2_entry_get -+ * Description: -+ * Get LUT unicast entry. -+ * Input: -+ * pL2_entry - Index field in the structure. -+ * Output: -+ * pL2_entry - other fields such as MAC, port, age... -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_L2_EMPTY_ENTRY - Empty LUT entry. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API is used to get address by index from 0~2111. -+ */ -+rtk_api_ret_t rtk_l2_entry_get(rtk_l2_addr_table_t *pL2_entry) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 method; -+ rtl8367c_luttb l2Table; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (pL2_entry->index >= rtk_switch_maxLutAddrNumber_get()) -+ return RT_ERR_INPUT; -+ -+ memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); -+ l2Table.address= pL2_entry->index; -+ method = LUTREADMETHOD_ADDRESS; -+ if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((pL2_entry->index>0x800)&&(l2Table.lookup_hit==0)) -+ return RT_ERR_L2_EMPTY_ENTRY; -+ -+ if(l2Table.l3lookup) -+ { -+ if(l2Table.l3vidlookup) -+ { -+ memset(&pL2_entry->mac, 0, sizeof(rtk_mac_t)); -+ pL2_entry->is_ipmul = l2Table.l3lookup; -+ pL2_entry->sip = l2Table.sip; -+ pL2_entry->dip = l2Table.dip; -+ pL2_entry->is_static = l2Table.nosalearn; -+ -+ /* Get Logical port mask */ -+ if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &(pL2_entry->portmask)))!=RT_ERR_OK) -+ return retVal; -+ -+ pL2_entry->fid = 0; -+ pL2_entry->age = 0; -+ pL2_entry->auth = 0; -+ pL2_entry->sa_block = 0; -+ pL2_entry->is_ipvidmul = 1; -+ pL2_entry->l3_vid = l2Table.l3_vid; -+ } -+ else -+ { -+ memset(&pL2_entry->mac, 0, sizeof(rtk_mac_t)); -+ pL2_entry->is_ipmul = l2Table.l3lookup; -+ pL2_entry->sip = l2Table.sip; -+ pL2_entry->dip = l2Table.dip; -+ pL2_entry->is_static = l2Table.nosalearn; -+ -+ /* Get Logical port mask */ -+ if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &(pL2_entry->portmask)))!=RT_ERR_OK) -+ return retVal; -+ -+ pL2_entry->fid = 0; -+ pL2_entry->age = 0; -+ pL2_entry->auth = 0; -+ pL2_entry->sa_block = 0; -+ pL2_entry->is_ipvidmul = 0; -+ pL2_entry->l3_vid = 0; -+ } -+ } -+ else if(l2Table.mac.octet[0]&0x01) -+ { -+ memset(&pL2_entry->sip, 0, sizeof(ipaddr_t)); -+ memset(&pL2_entry->dip, 0, sizeof(ipaddr_t)); -+ pL2_entry->mac.octet[0] = l2Table.mac.octet[0]; -+ pL2_entry->mac.octet[1] = l2Table.mac.octet[1]; -+ pL2_entry->mac.octet[2] = l2Table.mac.octet[2]; -+ pL2_entry->mac.octet[3] = l2Table.mac.octet[3]; -+ pL2_entry->mac.octet[4] = l2Table.mac.octet[4]; -+ pL2_entry->mac.octet[5] = l2Table.mac.octet[5]; -+ pL2_entry->is_ipmul = l2Table.l3lookup; -+ pL2_entry->is_static = l2Table.nosalearn; -+ -+ /* Get Logical port mask */ -+ if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &(pL2_entry->portmask)))!=RT_ERR_OK) -+ return retVal; -+ -+ pL2_entry->ivl = l2Table.ivl_svl; -+ if(l2Table.ivl_svl == 1) /* IVL */ -+ { -+ pL2_entry->cvid = l2Table.cvid_fid; -+ pL2_entry->fid = 0; -+ } -+ else /* SVL*/ -+ { -+ pL2_entry->cvid = 0; -+ pL2_entry->fid = l2Table.cvid_fid; -+ } -+ pL2_entry->auth = l2Table.auth; -+ pL2_entry->sa_block = l2Table.sa_block; -+ pL2_entry->age = 0; -+ pL2_entry->is_ipvidmul = 0; -+ pL2_entry->l3_vid = 0; -+ } -+ else if((l2Table.age != 0)||(l2Table.nosalearn == 1)) -+ { -+ memset(&pL2_entry->sip, 0, sizeof(ipaddr_t)); -+ memset(&pL2_entry->dip, 0, sizeof(ipaddr_t)); -+ pL2_entry->mac.octet[0] = l2Table.mac.octet[0]; -+ pL2_entry->mac.octet[1] = l2Table.mac.octet[1]; -+ pL2_entry->mac.octet[2] = l2Table.mac.octet[2]; -+ pL2_entry->mac.octet[3] = l2Table.mac.octet[3]; -+ pL2_entry->mac.octet[4] = l2Table.mac.octet[4]; -+ pL2_entry->mac.octet[5] = l2Table.mac.octet[5]; -+ pL2_entry->is_ipmul = l2Table.l3lookup; -+ pL2_entry->is_static = l2Table.nosalearn; -+ -+ /* Get Logical port mask */ -+ if ((retVal = rtk_switch_portmask_P2L_get(1<<(l2Table.spa), &(pL2_entry->portmask)))!=RT_ERR_OK) -+ return retVal; -+ -+ pL2_entry->ivl = l2Table.ivl_svl; -+ pL2_entry->cvid = l2Table.cvid_fid; -+ pL2_entry->fid = l2Table.fid; -+ pL2_entry->auth = l2Table.auth; -+ pL2_entry->sa_block = l2Table.sa_block; -+ pL2_entry->age = l2Table.age; -+ pL2_entry->is_ipvidmul = 0; -+ pL2_entry->l3_vid = 0; -+ } -+ else -+ return RT_ERR_L2_EMPTY_ENTRY; -+ -+ return RT_ERR_OK; -+} -+ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/leaky.c b/drivers/net/phy/rtk/rtl8367c/leaky.c -new file mode 100644 -index 000000000000..1b7d50a9e547 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/leaky.c -@@ -0,0 +1,590 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTK switch high-level API for RTL8367/RTL8367C -+ * Feature : Here is a list of all functions and variables in Leaky module. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+ -+/* Function Name: -+ * rtk_leaky_vlan_set -+ * Description: -+ * Set VLAN leaky. -+ * Input: -+ * type - Packet type for VLAN leaky. -+ * enable - Leaky status. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_ENABLE - Invalid enable input -+ * Note: -+ * This API can set VLAN leaky for RMA ,IGMP/MLD, CDP, CSSTP, and LLDP packets. -+ * The leaky frame types are as following: -+ * - LEAKY_BRG_GROUP, -+ * - LEAKY_FD_PAUSE, -+ * - LEAKY_SP_MCAST, -+ * - LEAKY_1X_PAE, -+ * - LEAKY_UNDEF_BRG_04, -+ * - LEAKY_UNDEF_BRG_05, -+ * - LEAKY_UNDEF_BRG_06, -+ * - LEAKY_UNDEF_BRG_07, -+ * - LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS, -+ * - LEAKY_UNDEF_BRG_09, -+ * - LEAKY_UNDEF_BRG_0A, -+ * - LEAKY_UNDEF_BRG_0B, -+ * - LEAKY_UNDEF_BRG_0C, -+ * - LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS, -+ * - LEAKY_8021AB, -+ * - LEAKY_UNDEF_BRG_0F, -+ * - LEAKY_BRG_MNGEMENT, -+ * - LEAKY_UNDEFINED_11, -+ * - LEAKY_UNDEFINED_12, -+ * - LEAKY_UNDEFINED_13, -+ * - LEAKY_UNDEFINED_14, -+ * - LEAKY_UNDEFINED_15, -+ * - LEAKY_UNDEFINED_16, -+ * - LEAKY_UNDEFINED_17, -+ * - LEAKY_UNDEFINED_18, -+ * - LEAKY_UNDEFINED_19, -+ * - LEAKY_UNDEFINED_1A, -+ * - LEAKY_UNDEFINED_1B, -+ * - LEAKY_UNDEFINED_1C, -+ * - LEAKY_UNDEFINED_1D, -+ * - LEAKY_UNDEFINED_1E, -+ * - LEAKY_UNDEFINED_1F, -+ * - LEAKY_GMRP, -+ * - LEAKY_GVRP, -+ * - LEAKY_UNDEF_GARP_22, -+ * - LEAKY_UNDEF_GARP_23, -+ * - LEAKY_UNDEF_GARP_24, -+ * - LEAKY_UNDEF_GARP_25, -+ * - LEAKY_UNDEF_GARP_26, -+ * - LEAKY_UNDEF_GARP_27, -+ * - LEAKY_UNDEF_GARP_28, -+ * - LEAKY_UNDEF_GARP_29, -+ * - LEAKY_UNDEF_GARP_2A, -+ * - LEAKY_UNDEF_GARP_2B, -+ * - LEAKY_UNDEF_GARP_2C, -+ * - LEAKY_UNDEF_GARP_2D, -+ * - LEAKY_UNDEF_GARP_2E, -+ * - LEAKY_UNDEF_GARP_2F, -+ * - LEAKY_IGMP, -+ * - LEAKY_IPMULTICAST. -+ * - LEAKY_CDP, -+ * - LEAKY_CSSTP, -+ * - LEAKY_LLDP. -+ */ -+rtk_api_ret_t rtk_leaky_vlan_set(rtk_leaky_type_t type, rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 port; -+ rtl8367c_rma_t rmacfg; -+ rtk_uint32 tmp; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (type >= LEAKY_END) -+ return RT_ERR_INPUT; -+ -+ if (enable >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if (type >= 0 && type <= LEAKY_UNDEF_GARP_2F) -+ { -+ if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ rmacfg.vlan_leaky = enable; -+ -+ if ((retVal = rtl8367c_setAsicRma(type, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if (LEAKY_IPMULTICAST == type) -+ { -+ for (port = 0; port <= RTK_PORT_ID_MAX; port++) -+ { -+ if ((retVal = rtl8367c_setAsicIpMulticastVlanLeaky(port,enable)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ else if (LEAKY_IGMP == type) -+ { -+ if ((retVal = rtl8367c_setAsicIGMPVLANLeaky(enable)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if (LEAKY_CDP == type) -+ { -+ if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ rmacfg.vlan_leaky = enable; -+ -+ if ((retVal = rtl8367c_setAsicRmaCdp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if (LEAKY_CSSTP == type) -+ { -+ if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ rmacfg.vlan_leaky = enable; -+ -+ if ((retVal = rtl8367c_setAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if (LEAKY_LLDP == type) -+ { -+ if ((retVal = rtl8367c_getAsicRmaLldp(&tmp,&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ rmacfg.vlan_leaky = enable; -+ -+ if ((retVal = rtl8367c_setAsicRmaLldp(tmp, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_leaky_vlan_get -+ * Description: -+ * Get VLAN leaky. -+ * Input: -+ * type - Packet type for VLAN leaky. -+ * Output: -+ * pEnable - Leaky status. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can get VLAN leaky status for RMA ,IGMP/MLD, CDP, CSSTP, and LLDP packets. -+ * The leaky frame types are as following: -+ * - LEAKY_BRG_GROUP, -+ * - LEAKY_FD_PAUSE, -+ * - LEAKY_SP_MCAST, -+ * - LEAKY_1X_PAE, -+ * - LEAKY_UNDEF_BRG_04, -+ * - LEAKY_UNDEF_BRG_05, -+ * - LEAKY_UNDEF_BRG_06, -+ * - LEAKY_UNDEF_BRG_07, -+ * - LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS, -+ * - LEAKY_UNDEF_BRG_09, -+ * - LEAKY_UNDEF_BRG_0A, -+ * - LEAKY_UNDEF_BRG_0B, -+ * - LEAKY_UNDEF_BRG_0C, -+ * - LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS, -+ * - LEAKY_8021AB, -+ * - LEAKY_UNDEF_BRG_0F, -+ * - LEAKY_BRG_MNGEMENT, -+ * - LEAKY_UNDEFINED_11, -+ * - LEAKY_UNDEFINED_12, -+ * - LEAKY_UNDEFINED_13, -+ * - LEAKY_UNDEFINED_14, -+ * - LEAKY_UNDEFINED_15, -+ * - LEAKY_UNDEFINED_16, -+ * - LEAKY_UNDEFINED_17, -+ * - LEAKY_UNDEFINED_18, -+ * - LEAKY_UNDEFINED_19, -+ * - LEAKY_UNDEFINED_1A, -+ * - LEAKY_UNDEFINED_1B, -+ * - LEAKY_UNDEFINED_1C, -+ * - LEAKY_UNDEFINED_1D, -+ * - LEAKY_UNDEFINED_1E, -+ * - LEAKY_UNDEFINED_1F, -+ * - LEAKY_GMRP, -+ * - LEAKY_GVRP, -+ * - LEAKY_UNDEF_GARP_22, -+ * - LEAKY_UNDEF_GARP_23, -+ * - LEAKY_UNDEF_GARP_24, -+ * - LEAKY_UNDEF_GARP_25, -+ * - LEAKY_UNDEF_GARP_26, -+ * - LEAKY_UNDEF_GARP_27, -+ * - LEAKY_UNDEF_GARP_28, -+ * - LEAKY_UNDEF_GARP_29, -+ * - LEAKY_UNDEF_GARP_2A, -+ * - LEAKY_UNDEF_GARP_2B, -+ * - LEAKY_UNDEF_GARP_2C, -+ * - LEAKY_UNDEF_GARP_2D, -+ * - LEAKY_UNDEF_GARP_2E, -+ * - LEAKY_UNDEF_GARP_2F, -+ * - LEAKY_IGMP, -+ * - LEAKY_IPMULTICAST. -+ * - LEAKY_CDP, -+ * - LEAKY_CSSTP, -+ * - LEAKY_LLDP. -+ */ -+rtk_api_ret_t rtk_leaky_vlan_get(rtk_leaky_type_t type, rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 port,tmp; -+ rtl8367c_rma_t rmacfg; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (type >= LEAKY_END) -+ return RT_ERR_INPUT; -+ -+ if(NULL == pEnable) -+ return RT_ERR_NULL_POINTER; -+ -+ if (type >= 0 && type <= LEAKY_UNDEF_GARP_2F) -+ { -+ if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ *pEnable = rmacfg.vlan_leaky; -+ -+ } -+ else if (LEAKY_IPMULTICAST == type) -+ { -+ for (port = 0; port <= RTK_PORT_ID_MAX; port++) -+ { -+ if ((retVal = rtl8367c_getAsicIpMulticastVlanLeaky(port, &tmp)) != RT_ERR_OK) -+ return retVal; -+ if (port>0&&(tmp!=*pEnable)) -+ return RT_ERR_FAILED; -+ *pEnable = tmp; -+ } -+ } -+ else if (LEAKY_IGMP == type) -+ { -+ if ((retVal = rtl8367c_getAsicIGMPVLANLeaky(&tmp)) != RT_ERR_OK) -+ return retVal; -+ -+ *pEnable = tmp; -+ } -+ else if (LEAKY_CDP == type) -+ { -+ if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ *pEnable = rmacfg.vlan_leaky; -+ } -+ else if (LEAKY_CSSTP == type) -+ { -+ if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ *pEnable = rmacfg.vlan_leaky; -+ } -+ else if (LEAKY_LLDP == type) -+ { -+ if ((retVal = rtl8367c_getAsicRmaLldp(&tmp, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ *pEnable = rmacfg.vlan_leaky; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_leaky_portIsolation_set -+ * Description: -+ * Set port isolation leaky. -+ * Input: -+ * type - Packet type for port isolation leaky. -+ * enable - Leaky status. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_ENABLE - Invalid enable input -+ * Note: -+ * This API can set port isolation leaky for RMA ,IGMP/MLD, CDP, CSSTP, and LLDP packets. -+ * The leaky frame types are as following: -+ * - LEAKY_BRG_GROUP, -+ * - LEAKY_FD_PAUSE, -+ * - LEAKY_SP_MCAST, -+ * - LEAKY_1X_PAE, -+ * - LEAKY_UNDEF_BRG_04, -+ * - LEAKY_UNDEF_BRG_05, -+ * - LEAKY_UNDEF_BRG_06, -+ * - LEAKY_UNDEF_BRG_07, -+ * - LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS, -+ * - LEAKY_UNDEF_BRG_09, -+ * - LEAKY_UNDEF_BRG_0A, -+ * - LEAKY_UNDEF_BRG_0B, -+ * - LEAKY_UNDEF_BRG_0C, -+ * - LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS, -+ * - LEAKY_8021AB, -+ * - LEAKY_UNDEF_BRG_0F, -+ * - LEAKY_BRG_MNGEMENT, -+ * - LEAKY_UNDEFINED_11, -+ * - LEAKY_UNDEFINED_12, -+ * - LEAKY_UNDEFINED_13, -+ * - LEAKY_UNDEFINED_14, -+ * - LEAKY_UNDEFINED_15, -+ * - LEAKY_UNDEFINED_16, -+ * - LEAKY_UNDEFINED_17, -+ * - LEAKY_UNDEFINED_18, -+ * - LEAKY_UNDEFINED_19, -+ * - LEAKY_UNDEFINED_1A, -+ * - LEAKY_UNDEFINED_1B, -+ * - LEAKY_UNDEFINED_1C, -+ * - LEAKY_UNDEFINED_1D, -+ * - LEAKY_UNDEFINED_1E, -+ * - LEAKY_UNDEFINED_1F, -+ * - LEAKY_GMRP, -+ * - LEAKY_GVRP, -+ * - LEAKY_UNDEF_GARP_22, -+ * - LEAKY_UNDEF_GARP_23, -+ * - LEAKY_UNDEF_GARP_24, -+ * - LEAKY_UNDEF_GARP_25, -+ * - LEAKY_UNDEF_GARP_26, -+ * - LEAKY_UNDEF_GARP_27, -+ * - LEAKY_UNDEF_GARP_28, -+ * - LEAKY_UNDEF_GARP_29, -+ * - LEAKY_UNDEF_GARP_2A, -+ * - LEAKY_UNDEF_GARP_2B, -+ * - LEAKY_UNDEF_GARP_2C, -+ * - LEAKY_UNDEF_GARP_2D, -+ * - LEAKY_UNDEF_GARP_2E, -+ * - LEAKY_UNDEF_GARP_2F, -+ * - LEAKY_IGMP, -+ * - LEAKY_IPMULTICAST. -+ * - LEAKY_CDP, -+ * - LEAKY_CSSTP, -+ * - LEAKY_LLDP. -+ */ -+rtk_api_ret_t rtk_leaky_portIsolation_set(rtk_leaky_type_t type, rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 port; -+ rtl8367c_rma_t rmacfg; -+ rtk_uint32 tmp; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (type >= LEAKY_END) -+ return RT_ERR_INPUT; -+ -+ if (enable >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if (type >= 0 && type <= LEAKY_UNDEF_GARP_2F) -+ { -+ if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ rmacfg.portiso_leaky = enable; -+ -+ if ((retVal = rtl8367c_setAsicRma(type, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if (LEAKY_IPMULTICAST == type) -+ { -+ for (port = 0; port < RTK_MAX_NUM_OF_PORT; port++) -+ { -+ if ((retVal = rtl8367c_setAsicIpMulticastPortIsoLeaky(port,enable)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ else if (LEAKY_IGMP == type) -+ { -+ if ((retVal = rtl8367c_setAsicIGMPIsoLeaky(enable)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if (LEAKY_CDP == type) -+ { -+ if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ rmacfg.portiso_leaky = enable; -+ -+ if ((retVal = rtl8367c_setAsicRmaCdp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if (LEAKY_CSSTP == type) -+ { -+ if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ rmacfg.portiso_leaky = enable; -+ -+ if ((retVal = rtl8367c_setAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if (LEAKY_LLDP == type) -+ { -+ if ((retVal = rtl8367c_getAsicRmaLldp(&tmp, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ rmacfg.portiso_leaky = enable; -+ -+ if ((retVal = rtl8367c_setAsicRmaLldp(tmp, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_leaky_portIsolation_get -+ * Description: -+ * Get port isolation leaky. -+ * Input: -+ * type - Packet type for port isolation leaky. -+ * Output: -+ * pEnable - Leaky status. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can get port isolation leaky status for RMA ,IGMP/MLD, CDP, CSSTP, and LLDP packets. -+ * The leaky frame types are as following: -+ * - LEAKY_BRG_GROUP, -+ * - LEAKY_FD_PAUSE, -+ * - LEAKY_SP_MCAST, -+ * - LEAKY_1X_PAE, -+ * - LEAKY_UNDEF_BRG_04, -+ * - LEAKY_UNDEF_BRG_05, -+ * - LEAKY_UNDEF_BRG_06, -+ * - LEAKY_UNDEF_BRG_07, -+ * - LEAKY_PROVIDER_BRIDGE_GROUP_ADDRESS, -+ * - LEAKY_UNDEF_BRG_09, -+ * - LEAKY_UNDEF_BRG_0A, -+ * - LEAKY_UNDEF_BRG_0B, -+ * - LEAKY_UNDEF_BRG_0C, -+ * - LEAKY_PROVIDER_BRIDGE_GVRP_ADDRESS, -+ * - LEAKY_8021AB, -+ * - LEAKY_UNDEF_BRG_0F, -+ * - LEAKY_BRG_MNGEMENT, -+ * - LEAKY_UNDEFINED_11, -+ * - LEAKY_UNDEFINED_12, -+ * - LEAKY_UNDEFINED_13, -+ * - LEAKY_UNDEFINED_14, -+ * - LEAKY_UNDEFINED_15, -+ * - LEAKY_UNDEFINED_16, -+ * - LEAKY_UNDEFINED_17, -+ * - LEAKY_UNDEFINED_18, -+ * - LEAKY_UNDEFINED_19, -+ * - LEAKY_UNDEFINED_1A, -+ * - LEAKY_UNDEFINED_1B, -+ * - LEAKY_UNDEFINED_1C, -+ * - LEAKY_UNDEFINED_1D, -+ * - LEAKY_UNDEFINED_1E, -+ * - LEAKY_UNDEFINED_1F, -+ * - LEAKY_GMRP, -+ * - LEAKY_GVRP, -+ * - LEAKY_UNDEF_GARP_22, -+ * - LEAKY_UNDEF_GARP_23, -+ * - LEAKY_UNDEF_GARP_24, -+ * - LEAKY_UNDEF_GARP_25, -+ * - LEAKY_UNDEF_GARP_26, -+ * - LEAKY_UNDEF_GARP_27, -+ * - LEAKY_UNDEF_GARP_28, -+ * - LEAKY_UNDEF_GARP_29, -+ * - LEAKY_UNDEF_GARP_2A, -+ * - LEAKY_UNDEF_GARP_2B, -+ * - LEAKY_UNDEF_GARP_2C, -+ * - LEAKY_UNDEF_GARP_2D, -+ * - LEAKY_UNDEF_GARP_2E, -+ * - LEAKY_UNDEF_GARP_2F, -+ * - LEAKY_IGMP, -+ * - LEAKY_IPMULTICAST. -+ * - LEAKY_CDP, -+ * - LEAKY_CSSTP, -+ * - LEAKY_LLDP. -+ */ -+rtk_api_ret_t rtk_leaky_portIsolation_get(rtk_leaky_type_t type, rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 port, tmp; -+ rtl8367c_rma_t rmacfg; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (type >= LEAKY_END) -+ return RT_ERR_INPUT; -+ -+ if(NULL == pEnable) -+ return RT_ERR_NULL_POINTER; -+ -+ if (type >= 0 && type <= LEAKY_UNDEF_GARP_2F) -+ { -+ if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ *pEnable = rmacfg.portiso_leaky; -+ -+ } -+ else if (LEAKY_IPMULTICAST == type) -+ { -+ for (port = 0; port < RTK_MAX_NUM_OF_PORT; port++) -+ { -+ if ((retVal = rtl8367c_getAsicIpMulticastPortIsoLeaky(port, &tmp)) != RT_ERR_OK) -+ return retVal; -+ if (port > 0 &&(tmp != *pEnable)) -+ return RT_ERR_FAILED; -+ *pEnable = tmp; -+ } -+ } -+ else if (LEAKY_IGMP == type) -+ { -+ if ((retVal = rtl8367c_getAsicIGMPIsoLeaky(&tmp)) != RT_ERR_OK) -+ return retVal; -+ -+ *pEnable = tmp; -+ } -+ else if (LEAKY_CDP == type) -+ { -+ if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ *pEnable = rmacfg.portiso_leaky; -+ } -+ else if (LEAKY_CSSTP == type) -+ { -+ if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ *pEnable = rmacfg.portiso_leaky; -+ } -+ else if (LEAKY_LLDP == type) -+ { -+ if ((retVal = rtl8367c_getAsicRmaLldp(&tmp, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ *pEnable = rmacfg.portiso_leaky; -+ } -+ -+ -+ return RT_ERR_OK; -+} -diff --git a/drivers/net/phy/rtk/rtl8367c/led.c b/drivers/net/phy/rtk/rtl8367c/led.c -new file mode 100644 -index 000000000000..02e0829dc6e6 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/led.c -@@ -0,0 +1,792 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTK switch high-level API for RTL8367/RTL8367C -+ * Feature : Here is a list of all functions and variables in LED module. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+ -+/* Function Name: -+ * rtk_led_enable_set -+ * Description: -+ * Set Led enable configuration -+ * Input: -+ * group - LED group id. -+ * pPortmask - LED enable port mask. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_MASK - Error portmask -+ * Note: -+ * The API can be used to enable LED per port per group. -+ */ -+rtk_api_ret_t rtk_led_enable_set(rtk_led_group_t group, rtk_portmask_t *pPortmask) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pmask; -+ rtk_port_t port; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (group >= LED_GROUP_END) -+ return RT_ERR_INPUT; -+ -+ RTK_CHK_PORTMASK_VALID(pPortmask); -+ -+ RTK_PORTMASK_SCAN((*pPortmask), port) -+ { -+ if(rtk_switch_isCPUPort(port) == RT_ERR_OK) -+ return RT_ERR_PORT_MASK; -+ } -+ -+ if((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicLedGroupEnable(group, pmask)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_led_enable_get -+ * Description: -+ * Get Led enable configuration -+ * Input: -+ * group - LED group id. -+ * Output: -+ * pPortmask - LED enable port mask. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can be used to get LED enable status. -+ */ -+rtk_api_ret_t rtk_led_enable_get(rtk_led_group_t group, rtk_portmask_t *pPortmask) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pmask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (group >= LED_GROUP_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_getAsicLedGroupEnable(group, &pmask)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+ -+} -+ -+/* Function Name: -+ * rtk_led_operation_set -+ * Description: -+ * Set Led operation mode -+ * Input: -+ * mode - LED operation mode. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can set Led operation mode. -+ * The modes that can be set are as following: -+ * - LED_OP_SCAN, -+ * - LED_OP_PARALLEL, -+ * - LED_OP_SERIAL, -+ */ -+rtk_api_ret_t rtk_led_operation_set(rtk_led_operation_t mode) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 regData; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if ( mode >= LED_OP_END) -+ return RT_ERR_INPUT; -+ -+ switch (mode) -+ { -+ case LED_OP_PARALLEL: -+ regData = LEDOP_PARALLEL; -+ break; -+ case LED_OP_SERIAL: -+ regData = LEDOP_SERIAL; -+ break; -+ default: -+ return RT_ERR_CHIP_NOT_SUPPORTED; -+ break; -+ } -+ -+ if ((retVal = rtl8367c_setAsicLedOperationMode(regData)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_led_operation_get -+ * Description: -+ * Get Led operation mode -+ * Input: -+ * None -+ * Output: -+ * pMode - Support LED operation mode. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can get Led operation mode. -+ * The modes that can be set are as following: -+ * - LED_OP_SCAN, -+ * - LED_OP_PARALLEL, -+ * - LED_OP_SERIAL, -+ */ -+rtk_api_ret_t rtk_led_operation_get(rtk_led_operation_t *pMode) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 regData; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pMode) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicLedOperationMode(®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ if (regData == LEDOP_SERIAL) -+ *pMode = LED_OP_SERIAL; -+ else if (regData ==LEDOP_PARALLEL) -+ *pMode = LED_OP_PARALLEL; -+ else -+ return RT_ERR_FAILED; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_led_modeForce_set -+ * Description: -+ * Set Led group to configuration force mode -+ * Input: -+ * port - port ID -+ * group - Support LED group id. -+ * mode - Support LED force mode. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Error Port ID -+ * Note: -+ * The API can force to one force mode. -+ * The force modes that can be set are as following: -+ * - LED_FORCE_NORMAL, -+ * - LED_FORCE_BLINK, -+ * - LED_FORCE_OFF, -+ * - LED_FORCE_ON. -+ */ -+rtk_api_ret_t rtk_led_modeForce_set(rtk_port_t port, rtk_led_group_t group, rtk_led_force_mode_t mode) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ /* No LED for CPU port */ -+ if(rtk_switch_isCPUPort(port) == RT_ERR_OK) -+ return RT_ERR_PORT_ID; -+ -+ if (group >= LED_GROUP_END) -+ return RT_ERR_INPUT; -+ -+ if (mode >= LED_FORCE_END) -+ return RT_ERR_NOT_ALLOWED; -+ -+ if ((retVal = rtl8367c_setAsicForceLed(rtk_switch_port_L2P_get(port), group, mode)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_led_modeForce_get -+ * Description: -+ * Get Led group to configuration force mode -+ * Input: -+ * port - port ID -+ * group - Support LED group id. -+ * pMode - Support LED force mode. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Error Port ID -+ * Note: -+ * The API can get forced Led group mode. -+ * The force modes that can be set are as following: -+ * - LED_FORCE_NORMAL, -+ * - LED_FORCE_BLINK, -+ * - LED_FORCE_OFF, -+ * - LED_FORCE_ON. -+ */ -+rtk_api_ret_t rtk_led_modeForce_get(rtk_port_t port, rtk_led_group_t group, rtk_led_force_mode_t *pMode) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ /* No LED for CPU port */ -+ if(rtk_switch_isCPUPort(port) == RT_ERR_OK) -+ return RT_ERR_PORT_ID; -+ -+ if (group >= LED_GROUP_END) -+ return RT_ERR_INPUT; -+ -+ if (NULL == pMode) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicForceLed(rtk_switch_port_L2P_get(port), group, pMode)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_led_blinkRate_set -+ * Description: -+ * Set LED blinking rate -+ * Input: -+ * blinkRate - blinking rate. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * ASIC support 6 types of LED blinking rates at 43ms, 84ms, 120ms, 170ms, 340ms and 670ms. -+ */ -+rtk_api_ret_t rtk_led_blinkRate_set(rtk_led_blink_rate_t blinkRate) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (blinkRate >= LED_BLINKRATE_END) -+ return RT_ERR_FAILED; -+ -+ if ((retVal = rtl8367c_setAsicLedBlinkRate(blinkRate)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_led_blinkRate_get -+ * Description: -+ * Get LED blinking rate at mode 0 to mode 3 -+ * Input: -+ * None -+ * Output: -+ * pBlinkRate - blinking rate. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * There are 6 types of LED blinking rates at 43ms, 84ms, 120ms, 170ms, 340ms and 670ms. -+ */ -+rtk_api_ret_t rtk_led_blinkRate_get(rtk_led_blink_rate_t *pBlinkRate) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pBlinkRate) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicLedBlinkRate(pBlinkRate)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_led_groupConfig_set -+ * Description: -+ * Set per group Led to configuration mode -+ * Input: -+ * group - LED group. -+ * config - LED configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can set LED indicated information configuration for each LED group with 1 to 1 led mapping to each port. -+ * - Definition LED Statuses Description -+ * - 0000 LED_Off LED pin Tri-State. -+ * - 0001 Dup/Col Collision, Full duplex Indicator. -+ * - 0010 Link/Act Link, Activity Indicator. -+ * - 0011 Spd1000 1000Mb/s Speed Indicator. -+ * - 0100 Spd100 100Mb/s Speed Indicator. -+ * - 0101 Spd10 10Mb/s Speed Indicator. -+ * - 0110 Spd1000/Act 1000Mb/s Speed/Activity Indicator. -+ * - 0111 Spd100/Act 100Mb/s Speed/Activity Indicator. -+ * - 1000 Spd10/Act 10Mb/s Speed/Activity Indicator. -+ * - 1001 Spd100 (10)/Act 10/100Mb/s Speed/Activity Indicator. -+ * - 1010 LoopDetect LoopDetect Indicator. -+ * - 1011 EEE EEE Indicator. -+ * - 1100 Link/Rx Link, Activity Indicator. -+ * - 1101 Link/Tx Link, Activity Indicator. -+ * - 1110 Master Link on Master Indicator. -+ * - 1111 Act Activity Indicator. Low for link established. -+ */ -+rtk_api_ret_t rtk_led_groupConfig_set(rtk_led_group_t group, rtk_led_congig_t config) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (LED_GROUP_END <= group) -+ return RT_ERR_FAILED; -+ -+ if (LED_CONFIG_END <= config) -+ return RT_ERR_FAILED; -+ -+ if ((retVal = rtl8367c_setAsicLedIndicateInfoConfig(group, config)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_led_groupConfig_get -+ * Description: -+ * Get Led group configuration mode -+ * Input: -+ * group - LED group. -+ * Output: -+ * pConfig - LED configuration. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can get LED indicated information configuration for each LED group. -+ */ -+rtk_api_ret_t rtk_led_groupConfig_get(rtk_led_group_t group, rtk_led_congig_t *pConfig) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (LED_GROUP_END <= group) -+ return RT_ERR_FAILED; -+ -+ if(NULL == pConfig) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicLedIndicateInfoConfig(group, pConfig)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_led_groupAbility_set -+ * Description: -+ * Configure per group Led ability -+ * Input: -+ * group - LED group. -+ * pAbility - LED ability -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * None. -+ */ -+ -+rtk_api_ret_t rtk_led_groupAbility_set(rtk_led_group_t group, rtk_led_ability_t *pAbility) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 regData; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (LED_GROUP_END <= group) -+ return RT_ERR_FAILED; -+ -+ if(pAbility == NULL) -+ return RT_ERR_NULL_POINTER; -+ -+ if( (pAbility->link_10m >= RTK_ENABLE_END) || (pAbility->link_100m >= RTK_ENABLE_END)|| -+ (pAbility->link_500m >= RTK_ENABLE_END) || (pAbility->link_1000m >= RTK_ENABLE_END)|| -+ (pAbility->act_rx >= RTK_ENABLE_END) || (pAbility->act_tx >= RTK_ENABLE_END) ) -+ { -+ return RT_ERR_INPUT; -+ } -+ -+ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_LED0_DATA_CTRL + (rtk_uint32)group, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ if(pAbility->link_10m == ENABLED) -+ regData |= 0x0001; -+ else -+ regData &= ~0x0001; -+ -+ if(pAbility->link_100m == ENABLED) -+ regData |= 0x0002; -+ else -+ regData &= ~0x0002; -+ -+ if(pAbility->link_500m == ENABLED) -+ regData |= 0x0004; -+ else -+ regData &= ~0x0004; -+ -+ if(pAbility->link_1000m == ENABLED) -+ regData |= 0x0008; -+ else -+ regData &= ~0x0008; -+ -+ if(pAbility->act_rx == ENABLED) -+ regData |= 0x0010; -+ else -+ regData &= ~0x0010; -+ -+ if(pAbility->act_tx == ENABLED) -+ regData |= 0x0020; -+ else -+ regData &= ~0x0020; -+ -+ regData |= (0x0001 << 6); -+ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_LED0_DATA_CTRL + (rtk_uint32)group, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_led_groupAbility_get -+ * Description: -+ * Get per group Led ability -+ * Input: -+ * group - LED group. -+ * pAbility - LED ability -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * None. -+ */ -+ -+rtk_api_ret_t rtk_led_groupAbility_get(rtk_led_group_t group, rtk_led_ability_t *pAbility) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 regData; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (LED_GROUP_END <= group) -+ return RT_ERR_FAILED; -+ -+ if(pAbility == NULL) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_LED0_DATA_CTRL + (rtk_uint32)group, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ pAbility->link_10m = (regData & 0x0001) ? ENABLED : DISABLED; -+ pAbility->link_100m = (regData & 0x0002) ? ENABLED : DISABLED; -+ pAbility->link_500m = (regData & 0x0004) ? ENABLED : DISABLED; -+ pAbility->link_1000m = (regData & 0x0008) ? ENABLED : DISABLED; -+ pAbility->act_rx = (regData & 0x0010) ? ENABLED : DISABLED; -+ pAbility->act_tx = (regData & 0x0020) ? ENABLED : DISABLED; -+ -+ return RT_ERR_OK; -+} -+ -+ -+/* Function Name: -+ * rtk_led_serialMode_set -+ * Description: -+ * Set Led serial mode active configuration -+ * Input: -+ * active - LED group. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can set LED serial mode active configuration. -+ */ -+rtk_api_ret_t rtk_led_serialMode_set(rtk_led_active_t active) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if ( active >= LED_ACTIVE_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicLedSerialModeConfig(active,1))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_led_serialMode_get -+ * Description: -+ * Get Led group congiuration mode -+ * Input: -+ * group - LED group. -+ * Output: -+ * pConfig - LED configuration. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can get LED serial mode active configuration. -+ */ -+rtk_api_ret_t rtk_led_serialMode_get(rtk_led_active_t *pActive) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 regData; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pActive) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicLedSerialModeConfig(pActive,®Data))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_led_OutputEnable_set -+ * Description: -+ * This API set LED I/O state. -+ * Input: -+ * enabled - LED I/O state -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error parameter -+ * Note: -+ * This API set LED I/O state. -+ */ -+rtk_api_ret_t rtk_led_OutputEnable_set(rtk_enable_t state) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (state >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicLedOutputEnable(state))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_led_OutputEnable_get -+ * Description: -+ * This API get LED I/O state. -+ * Input: -+ * None. -+ * Output: -+ * pEnabled - LED I/O state -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error parameter -+ * Note: -+ * This API set current LED I/O state. -+ */ -+rtk_api_ret_t rtk_led_OutputEnable_get(rtk_enable_t *pState) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(pState == NULL) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicLedOutputEnable(pState))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+ -+} -+ -+/* Function Name: -+ * rtk_led_serialModePortmask_set -+ * Description: -+ * This API configure Serial LED output Group and portmask -+ * Input: -+ * output - output group -+ * pPortmask - output portmask -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error parameter -+ * Note: -+ * None. -+ */ -+rtk_api_ret_t rtk_led_serialModePortmask_set(rtk_led_serialOutput_t output, rtk_portmask_t *pPortmask) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pmask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(output >= SERIAL_LED_END) -+ return RT_ERR_INPUT; -+ -+ if(pPortmask == NULL) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicLedSerialOutput((rtk_uint32)output, pmask))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_led_serialModePortmask_get -+ * Description: -+ * This API get Serial LED output Group and portmask -+ * Input: -+ * None. -+ * Output: -+ * pOutput - output group -+ * pPortmask - output portmask -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error parameter -+ * Note: -+ * None. -+ */ -+rtk_api_ret_t rtk_led_serialModePortmask_get(rtk_led_serialOutput_t *pOutput, rtk_portmask_t *pPortmask) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pmask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(pOutput == NULL) -+ return RT_ERR_NULL_POINTER; -+ -+ if(pPortmask == NULL) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicLedSerialOutput((rtk_uint32 *)pOutput, &pmask))!=RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/mirror.c b/drivers/net/phy/rtk/rtl8367c/mirror.c -new file mode 100644 -index 000000000000..3bbad8adb65d ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/mirror.c -@@ -0,0 +1,548 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTK switch high-level API for RTL8367/RTL8367C -+ * Feature : Here is a list of all functions and variables in Mirror module. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Function Name: -+ * rtk_mirror_portBased_set -+ * Description: -+ * Set port mirror function. -+ * Input: -+ * mirroring_port - Monitor port. -+ * pMirrored_rx_portmask - Rx mirror port mask. -+ * pMirrored_tx_portmask - Tx mirror port mask. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_PORT_MASK - Invalid portmask. -+ * Note: -+ * The API is to set mirror function of source port and mirror port. -+ * The mirror port can only be set to one port and the TX and RX mirror ports -+ * should be identical. -+ */ -+rtk_api_ret_t rtk_mirror_portBased_set(rtk_port_t mirroring_port, rtk_portmask_t *pMirrored_rx_portmask, rtk_portmask_t *pMirrored_tx_portmask) -+{ -+ rtk_api_ret_t retVal; -+ rtk_enable_t mirRx, mirTx; -+ rtk_uint32 i, pmask; -+ rtk_port_t source_port; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check port valid */ -+ RTK_CHK_PORT_VALID(mirroring_port); -+ -+ if(NULL == pMirrored_rx_portmask) -+ return RT_ERR_NULL_POINTER; -+ -+ if(NULL == pMirrored_tx_portmask) -+ return RT_ERR_NULL_POINTER; -+ -+ RTK_CHK_PORTMASK_VALID(pMirrored_rx_portmask); -+ -+ RTK_CHK_PORTMASK_VALID(pMirrored_tx_portmask); -+ -+ /*Mirror Source Port Mask Check*/ -+ if (pMirrored_tx_portmask->bits[0]!=pMirrored_rx_portmask->bits[0]&&pMirrored_tx_portmask->bits[0]!=0&&pMirrored_rx_portmask->bits[0]!=0) -+ return RT_ERR_PORT_MASK; -+ -+ /*mirror port != source port*/ -+ if(RTK_PORTMASK_IS_PORT_SET((*pMirrored_tx_portmask), mirroring_port) || RTK_PORTMASK_IS_PORT_SET((*pMirrored_rx_portmask), mirroring_port)) -+ return RT_ERR_PORT_MASK; -+ -+ source_port = rtk_switch_maxLogicalPort_get(); -+ -+ RTK_SCAN_ALL_LOG_PORT(i) -+ { -+ if (pMirrored_tx_portmask->bits[0]&(1<bits[0]&(1<bits[0] != 0) -+ { -+ if ((retVal = rtk_switch_portmask_L2P_get(pMirrored_rx_portmask, &pmask)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicPortMirrorMask(pmask)) != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ if ((retVal = rtk_switch_portmask_L2P_get(pMirrored_tx_portmask, &pmask)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicPortMirrorMask(pmask)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ -+ if (pMirrored_rx_portmask->bits[0]) -+ mirRx = ENABLED; -+ else -+ mirRx = DISABLED; -+ -+ if ((retVal = rtl8367c_setAsicPortMirrorRxFunction(mirRx)) != RT_ERR_OK) -+ return retVal; -+ -+ if (pMirrored_tx_portmask->bits[0]) -+ mirTx = ENABLED; -+ else -+ mirTx = DISABLED; -+ -+ if ((retVal = rtl8367c_setAsicPortMirrorTxFunction(mirTx)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+ -+} -+ -+/* Function Name: -+ * rtk_mirror_portBased_get -+ * Description: -+ * Get port mirror function. -+ * Input: -+ * None -+ * Output: -+ * pMirroring_port - Monitor port. -+ * pMirrored_rx_portmask - Rx mirror port mask. -+ * pMirrored_tx_portmask - Tx mirror port mask. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API is to get mirror function of source port and mirror port. -+ */ -+rtk_api_ret_t rtk_mirror_portBased_get(rtk_port_t *pMirroring_port, rtk_portmask_t *pMirrored_rx_portmask, rtk_portmask_t *pMirrored_tx_portmask) -+{ -+ rtk_api_ret_t retVal; -+ rtk_port_t source_port; -+ rtk_enable_t mirRx, mirTx; -+ rtk_uint32 sport, mport, pmask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pMirrored_rx_portmask) -+ return RT_ERR_NULL_POINTER; -+ -+ if(NULL == pMirrored_tx_portmask) -+ return RT_ERR_NULL_POINTER; -+ -+ if(NULL == pMirroring_port) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicPortMirror(&sport, &mport)) != RT_ERR_OK) -+ return retVal; -+ source_port = rtk_switch_port_P2L_get(sport); -+ *pMirroring_port = rtk_switch_port_P2L_get(mport); -+ -+ if ((retVal = rtl8367c_getAsicPortMirrorRxFunction((rtk_uint32*)&mirRx)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicPortMirrorTxFunction((rtk_uint32*)&mirTx)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicPortMirrorMask(&pmask)) != RT_ERR_OK) -+ return retVal; -+ -+ if (DISABLED == mirRx) -+ pMirrored_rx_portmask->bits[0]=0; -+ else -+ { -+ if ((retVal = rtk_switch_portmask_P2L_get(pmask, pMirrored_rx_portmask)) != RT_ERR_OK) -+ return retVal; -+ pMirrored_rx_portmask->bits[0] |= 1<bits[0]=0; -+ else -+ { -+ if ((retVal = rtk_switch_portmask_P2L_get(pmask, pMirrored_tx_portmask)) != RT_ERR_OK) -+ return retVal; -+ pMirrored_tx_portmask->bits[0] |= 1<= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ if ((retVal = rtl8367c_setAsicPortMirrorIsolation(enable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_mirror_portIso_get -+ * Description: -+ * Get mirror port isolation. -+ * Input: -+ * None -+ * Output: -+ * pEnable |Mirror isolation status. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API is to get mirror isolation status. -+ */ -+rtk_api_ret_t rtk_mirror_portIso_get(rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pEnable) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicPortMirrorIsolation(pEnable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_mirror_vlanLeaky_set -+ * Description: -+ * Set mirror VLAN leaky. -+ * Input: -+ * txenable -TX leaky enable. -+ * rxenable - RX leaky enable. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_ENABLE - Invalid enable input -+ * Note: -+ * The API is to set mirror VLAN leaky function forwarding packets to miror port. -+ */ -+rtk_api_ret_t rtk_mirror_vlanLeaky_set(rtk_enable_t txenable, rtk_enable_t rxenable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if ((txenable >= RTK_ENABLE_END) ||(rxenable >= RTK_ENABLE_END)) -+ return RT_ERR_ENABLE; -+ -+ if ((retVal = rtl8367c_setAsicPortMirrorVlanTxLeaky(txenable)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicPortMirrorVlanRxLeaky(rxenable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_mirror_vlanLeaky_get -+ * Description: -+ * Get mirror VLAN leaky. -+ * Input: -+ * None -+ * Output: -+ * pTxenable - TX leaky enable. -+ * pRxenable - RX leaky enable. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API is to get mirror VLAN leaky status. -+ */ -+rtk_api_ret_t rtk_mirror_vlanLeaky_get(rtk_enable_t *pTxenable, rtk_enable_t *pRxenable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if( (NULL == pTxenable) || (NULL == pRxenable) ) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicPortMirrorVlanTxLeaky(pTxenable)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicPortMirrorVlanRxLeaky(pRxenable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_mirror_isolationLeaky_set -+ * Description: -+ * Set mirror Isolation leaky. -+ * Input: -+ * txenable -TX leaky enable. -+ * rxenable - RX leaky enable. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_ENABLE - Invalid enable input -+ * Note: -+ * The API is to set mirror VLAN leaky function forwarding packets to mirror port. -+ */ -+rtk_api_ret_t rtk_mirror_isolationLeaky_set(rtk_enable_t txenable, rtk_enable_t rxenable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if ((txenable >= RTK_ENABLE_END) ||(rxenable >= RTK_ENABLE_END)) -+ return RT_ERR_ENABLE; -+ -+ if ((retVal = rtl8367c_setAsicPortMirrorIsolationTxLeaky(txenable)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicPortMirrorIsolationRxLeaky(rxenable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_mirror_isolationLeaky_get -+ * Description: -+ * Get mirror isolation leaky. -+ * Input: -+ * None -+ * Output: -+ * pTxenable - TX leaky enable. -+ * pRxenable - RX leaky enable. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API is to get mirror isolation leaky status. -+ */ -+rtk_api_ret_t rtk_mirror_isolationLeaky_get(rtk_enable_t *pTxenable, rtk_enable_t *pRxenable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if( (NULL == pTxenable) || (NULL == pRxenable) ) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicPortMirrorIsolationTxLeaky(pTxenable)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicPortMirrorIsolationRxLeaky(pRxenable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_mirror_keep_set -+ * Description: -+ * Set mirror packet format keep. -+ * Input: -+ * mode - -mirror keep mode. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_ENABLE - Invalid enable input -+ * Note: -+ * The API is to set -mirror keep mode. -+ * The mirror keep mode is as following: -+ * - MIRROR_FOLLOW_VLAN -+ * - MIRROR_KEEP_ORIGINAL -+ * - MIRROR_KEEP_END -+ */ -+rtk_api_ret_t rtk_mirror_keep_set(rtk_mirror_keep_t mode) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (mode >= MIRROR_KEEP_END) -+ return RT_ERR_ENABLE; -+ -+ if ((retVal = rtl8367c_setAsicPortMirrorRealKeep(mode)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_mirror_keep_get -+ * Description: -+ * Get mirror packet format keep. -+ * Input: -+ * None -+ * Output: -+ * pMode -mirror keep mode. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API is to get mirror keep mode. -+ * The mirror keep mode is as following: -+ * - MIRROR_FOLLOW_VLAN -+ * - MIRROR_KEEP_ORIGINAL -+ * - MIRROR_KEEP_END -+ */ -+rtk_api_ret_t rtk_mirror_keep_get(rtk_mirror_keep_t *pMode) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pMode) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicPortMirrorRealKeep(pMode)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_mirror_override_set -+ * Description: -+ * Set port mirror override function. -+ * Input: -+ * rxMirror - 1: output mirrored packet, 0: output normal forward packet -+ * txMirror - 1: output mirrored packet, 0: output normal forward packet -+ * aclMirror - 1: output mirrored packet, 0: output normal forward packet -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * The API is to set mirror override function. -+ * This function control the output format when a port output -+ * normal forward & mirrored packet at the same time. -+ */ -+rtk_api_ret_t rtk_mirror_override_set(rtk_enable_t rxMirror, rtk_enable_t txMirror, rtk_enable_t aclMirror) -+{ -+ rtk_api_ret_t retVal; -+ -+ if( (rxMirror >= RTK_ENABLE_END) || (txMirror >= RTK_ENABLE_END) || (aclMirror >= RTK_ENABLE_END)) -+ return RT_ERR_ENABLE; -+ -+ if ((retVal = rtl8367c_setAsicPortMirrorOverride((rtk_uint32)rxMirror, (rtk_uint32)txMirror, (rtk_uint32)aclMirror)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_mirror_override_get -+ * Description: -+ * Get port mirror override function. -+ * Input: -+ * None -+ * Output: -+ * pRxMirror - 1: output mirrored packet, 0: output normal forward packet -+ * pTxMirror - 1: output mirrored packet, 0: output normal forward packet -+ * pAclMirror - 1: output mirrored packet, 0: output normal forward packet -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Null Pointer -+ * Note: -+ * The API is to Get mirror override function. -+ * This function control the output format when a port output -+ * normal forward & mirrored packet at the same time. -+ */ -+rtk_api_ret_t rtk_mirror_override_get(rtk_enable_t *pRxMirror, rtk_enable_t *pTxMirror, rtk_enable_t *pAclMirror) -+{ -+ rtk_api_ret_t retVal; -+ -+ if( (pRxMirror == NULL) || (pTxMirror == NULL) || (pAclMirror == NULL)) -+ return RT_ERR_ENABLE; -+ -+ if ((retVal = rtl8367c_getAsicPortMirrorOverride((rtk_uint32 *)pRxMirror, (rtk_uint32 *)pTxMirror, (rtk_uint32 *)pAclMirror)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -diff --git a/drivers/net/phy/rtk/rtl8367c/oam.c b/drivers/net/phy/rtk/rtl8367c/oam.c -new file mode 100644 -index 000000000000..dc1559ae3ef8 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/oam.c -@@ -0,0 +1,245 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTK switch high-level API for RTL8367/RTL8367C -+ * Feature : Here is a list of all functions and variables in OAM(802.3ah) module. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+ -+/* Module Name : OAM */ -+ -+/* Function Name: -+ * rtk_oam_init -+ * Description: -+ * Initialize oam module. -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * Note: -+ * Must initialize oam module before calling any oam APIs. -+ */ -+rtk_api_ret_t rtk_oam_init(void) -+{ -+ return RT_ERR_OK; -+} /* end of rtk_oam_init */ -+ -+ -+/* Function Name: -+ * rtk_oam_state_set -+ * Description: -+ * This API set OAM state. -+ * Input: -+ * enabled -OAMstate -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error parameter -+ * Note: -+ * This API set OAM state. -+ */ -+rtk_api_ret_t rtk_oam_state_set(rtk_enable_t enabled) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (enabled >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicOamEnable(enabled))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_oam_state_get -+ * Description: -+ * This API get OAM state. -+ * Input: -+ * None. -+ * Output: -+ * pEnabled - H/W IGMP state -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error parameter -+ * Note: -+ * This API set current OAM state. -+ */ -+rtk_api_ret_t rtk_oam_state_get(rtk_enable_t *pEnabled) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if ((retVal = rtl8367c_getAsicOamEnable(pEnabled))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+ -+ -+/* Function Name: -+ * rtk_oam_parserAction_set -+ * Description: -+ * Set OAM parser action -+ * Input: -+ * port - port id -+ * action - parser action -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_PORT_ID - invalid port id -+ * Note: -+ * None -+ */ -+rtk_api_ret_t rtk_oam_parserAction_set(rtk_port_t port, rtk_oam_parser_act_t action) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (action >= OAM_PARSER_ACTION_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicOamParser(rtk_switch_port_L2P_get(port), action))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_oam_parserAction_set -+ * Description: -+ * Get OAM parser action -+ * Input: -+ * port - port id -+ * Output: -+ * pAction - parser action -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_PORT_ID - invalid port id -+ * Note: -+ * None -+ */ -+rtk_api_ret_t rtk_oam_parserAction_get(rtk_port_t port, rtk_oam_parser_act_t *pAction) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if ((retVal = rtl8367c_getAsicOamParser(rtk_switch_port_L2P_get(port), pAction))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+ -+/* Function Name: -+ * rtk_oam_multiplexerAction_set -+ * Description: -+ * Set OAM multiplexer action -+ * Input: -+ * port - port id -+ * action - parser action -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_PORT_ID - invalid port id -+ * Note: -+ * None -+ */ -+rtk_api_ret_t rtk_oam_multiplexerAction_set(rtk_port_t port, rtk_oam_multiplexer_act_t action) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (action >= OAM_MULTIPLEXER_ACTION_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicOamMultiplexer(rtk_switch_port_L2P_get(port), action))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_oam_parserAction_set -+ * Description: -+ * Get OAM multiplexer action -+ * Input: -+ * port - port id -+ * Output: -+ * pAction - parser action -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_PORT_ID - invalid port id -+ * Note: -+ * None -+ */ -+rtk_api_ret_t rtk_oam_multiplexerAction_get(rtk_port_t port, rtk_oam_multiplexer_act_t *pAction) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if ((retVal = rtl8367c_getAsicOamMultiplexer(rtk_switch_port_L2P_get(port), pAction))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/port.c b/drivers/net/phy/rtk/rtl8367c/port.c -new file mode 100644 -index 000000000000..9c7bcd0e38a1 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/port.c -@@ -0,0 +1,2467 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTK switch high-level API for RTL8367/RTL8367C -+ * Feature : Here is a list of all functions and variables in Port module. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#define FIBER_INIT_SIZE 1507 -+CONST_T rtk_uint8 Fiber[FIBER_INIT_SIZE] = { -+0x02,0x04,0x41,0xE4,0xF5,0xA8,0xD2,0xAF, -+0x22,0x00,0x00,0x02,0x05,0x2D,0xE4,0x90, -+0x06,0x2A,0xF0,0xFD,0x7C,0x01,0x7F,0x3F, -+0x7E,0x1D,0x12,0x05,0xAF,0x7D,0x40,0x12, -+0x02,0x5F,0xE4,0xFF,0xFE,0xFD,0x80,0x08, -+0x12,0x05,0x9E,0x50,0x0C,0x12,0x05,0x8B, -+0xFC,0x90,0x06,0x24,0x12,0x03,0x76,0x80, -+0xEF,0xE4,0xF5,0xA8,0xD2,0xAF,0x7D,0x1F, -+0xFC,0x7F,0x49,0x7E,0x13,0x12,0x05,0xAF, -+0x12,0x05,0xD6,0x7D,0xD7,0x12,0x02,0x1E, -+0x7D,0x80,0x12,0x01,0xCA,0x7D,0x94,0x7C, -+0xF9,0x12,0x02,0x3B,0x7D,0x81,0x12,0x01, -+0xCA,0x7D,0xA2,0x7C,0x31,0x12,0x02,0x3B, -+0x7D,0x82,0x12,0x01,0xDF,0x7D,0x60,0x7C, -+0x69,0x12,0x02,0x43,0x7D,0x83,0x12,0x01, -+0xDF,0x7D,0x28,0x7C,0x97,0x12,0x02,0x43, -+0x7D,0x84,0x12,0x01,0xF4,0x7D,0x85,0x7C, -+0x9D,0x12,0x02,0x57,0x7D,0x23,0x12,0x01, -+0xF4,0x7D,0x10,0x7C,0xD8,0x12,0x02,0x57, -+0x7D,0x24,0x7C,0x04,0x12,0x02,0x28,0x7D, -+0x00,0x12,0x02,0x1E,0x7D,0x2F,0x12,0x02, -+0x09,0x7D,0x20,0x7C,0x0F,0x7F,0x02,0x7E, -+0x66,0x12,0x05,0xAF,0x7D,0x01,0x12,0x02, -+0x09,0x7D,0x04,0x7C,0x00,0x7F,0x01,0x7E, -+0x66,0x12,0x05,0xAF,0x7D,0x80,0x7C,0x00, -+0x7F,0x00,0x7E,0x66,0x12,0x05,0xAF,0x7F, -+0x02,0x7E,0x66,0x12,0x02,0x4B,0x44,0x02, -+0xFF,0x90,0x06,0x28,0xEE,0xF0,0xA3,0xEF, -+0xF0,0x44,0x04,0xFF,0x90,0x06,0x28,0xEE, -+0xF0,0xFC,0xA3,0xEF,0xF0,0xFD,0x7F,0x02, -+0x7E,0x66,0x12,0x05,0xAF,0x7D,0x04,0x7C, -+0x00,0x12,0x02,0x28,0x7D,0xB9,0x7C,0x15, -+0x7F,0xEB,0x7E,0x13,0x12,0x05,0xAF,0x7D, -+0x07,0x7C,0x00,0x7F,0xE7,0x7E,0x13,0x12, -+0x05,0xAF,0x7D,0x40,0x7C,0x11,0x7F,0x00, -+0x7E,0x62,0x12,0x05,0xAF,0x12,0x03,0x82, -+0x7D,0x41,0x12,0x02,0x5F,0xE4,0xFF,0xFE, -+0xFD,0x80,0x08,0x12,0x05,0x9E,0x50,0x0C, -+0x12,0x05,0x8B,0xFC,0x90,0x06,0x24,0x12, -+0x03,0x76,0x80,0xEF,0xC2,0x00,0xC2,0x01, -+0xD2,0xA9,0xD2,0x8C,0x7F,0x01,0x7E,0x62, -+0x12,0x02,0x4B,0x30,0xE2,0x05,0xE4,0xA3, -+0xF0,0x80,0xF1,0x90,0x06,0x2A,0xE0,0x70, -+0x12,0x12,0x01,0x89,0x90,0x06,0x2A,0x74, -+0x01,0xF0,0xE4,0x90,0x06,0x2D,0xF0,0xA3, -+0xF0,0x80,0xD9,0xC3,0x90,0x06,0x2E,0xE0, -+0x94,0x64,0x90,0x06,0x2D,0xE0,0x94,0x00, -+0x40,0xCA,0xE4,0xF0,0xA3,0xF0,0x12,0x01, -+0x89,0x90,0x06,0x2A,0x74,0x01,0xF0,0x80, -+0xBB,0x7D,0x04,0xFC,0x7F,0x02,0x7E,0x66, -+0x12,0x05,0xAF,0x7D,0x00,0x7C,0x04,0x7F, -+0x01,0x7E,0x66,0x12,0x05,0xAF,0x7D,0xC0, -+0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12,0x05, -+0xAF,0xE4,0xFD,0xFC,0x7F,0x02,0x7E,0x66, -+0x12,0x05,0xAF,0x7D,0x00,0x7C,0x04,0x7F, -+0x01,0x7E,0x66,0x12,0x05,0xAF,0x7D,0xC0, -+0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12,0x05, -+0xAF,0x22,0x7C,0x04,0x7F,0x01,0x7E,0x66, -+0x12,0x05,0xAF,0x7D,0xC0,0x7C,0x00,0x7F, -+0x00,0x7E,0x66,0x12,0x05,0xAF,0x22,0x7C, -+0x04,0x7F,0x01,0x7E,0x66,0x12,0x05,0xAF, -+0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66, -+0x12,0x05,0xAF,0x22,0x7C,0x04,0x7F,0x01, -+0x7E,0x66,0x12,0x05,0xAF,0x7D,0xC0,0x7C, -+0x00,0x7F,0x00,0x7E,0x66,0x12,0x05,0xAF, -+0x22,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, -+0x05,0xAF,0x7D,0xC0,0x7C,0x00,0x7F,0x00, -+0x7E,0x66,0x12,0x05,0xAF,0x22,0x7C,0x04, -+0x7F,0x02,0x7E,0x66,0x12,0x05,0xAF,0x22, -+0x7F,0x01,0x7E,0x66,0x12,0x05,0xAF,0x7D, -+0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12, -+0x05,0xAF,0x22,0x7F,0x02,0x7E,0x66,0x12, -+0x05,0xAF,0x22,0x7F,0x02,0x7E,0x66,0x12, -+0x05,0xAF,0x22,0x12,0x05,0x67,0x90,0x06, -+0x28,0xEE,0xF0,0xA3,0xEF,0xF0,0x22,0x7F, -+0x02,0x7E,0x66,0x12,0x05,0xAF,0x22,0x7C, -+0x00,0x7F,0x36,0x7E,0x13,0x12,0x05,0xAF, -+0x22,0xC5,0xF0,0xF8,0xA3,0xE0,0x28,0xF0, -+0xC5,0xF0,0xF8,0xE5,0x82,0x15,0x82,0x70, -+0x02,0x15,0x83,0xE0,0x38,0xF0,0x22,0x75, -+0xF0,0x08,0x75,0x82,0x00,0xEF,0x2F,0xFF, -+0xEE,0x33,0xFE,0xCD,0x33,0xCD,0xCC,0x33, -+0xCC,0xC5,0x82,0x33,0xC5,0x82,0x9B,0xED, -+0x9A,0xEC,0x99,0xE5,0x82,0x98,0x40,0x0C, -+0xF5,0x82,0xEE,0x9B,0xFE,0xED,0x9A,0xFD, -+0xEC,0x99,0xFC,0x0F,0xD5,0xF0,0xD6,0xE4, -+0xCE,0xFB,0xE4,0xCD,0xFA,0xE4,0xCC,0xF9, -+0xA8,0x82,0x22,0xB8,0x00,0xC1,0xB9,0x00, -+0x59,0xBA,0x00,0x2D,0xEC,0x8B,0xF0,0x84, -+0xCF,0xCE,0xCD,0xFC,0xE5,0xF0,0xCB,0xF9, -+0x78,0x18,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, -+0xED,0x33,0xFD,0xEC,0x33,0xFC,0xEB,0x33, -+0xFB,0x10,0xD7,0x03,0x99,0x40,0x04,0xEB, -+0x99,0xFB,0x0F,0xD8,0xE5,0xE4,0xF9,0xFA, -+0x22,0x78,0x18,0xEF,0x2F,0xFF,0xEE,0x33, -+0xFE,0xED,0x33,0xFD,0xEC,0x33,0xFC,0xC9, -+0x33,0xC9,0x10,0xD7,0x05,0x9B,0xE9,0x9A, -+0x40,0x07,0xEC,0x9B,0xFC,0xE9,0x9A,0xF9, -+0x0F,0xD8,0xE0,0xE4,0xC9,0xFA,0xE4,0xCC, -+0xFB,0x22,0x75,0xF0,0x10,0xEF,0x2F,0xFF, -+0xEE,0x33,0xFE,0xED,0x33,0xFD,0xCC,0x33, -+0xCC,0xC8,0x33,0xC8,0x10,0xD7,0x07,0x9B, -+0xEC,0x9A,0xE8,0x99,0x40,0x0A,0xED,0x9B, -+0xFD,0xEC,0x9A,0xFC,0xE8,0x99,0xF8,0x0F, -+0xD5,0xF0,0xDA,0xE4,0xCD,0xFB,0xE4,0xCC, -+0xFA,0xE4,0xC8,0xF9,0x22,0xEB,0x9F,0xF5, -+0xF0,0xEA,0x9E,0x42,0xF0,0xE9,0x9D,0x42, -+0xF0,0xE8,0x9C,0x45,0xF0,0x22,0xE0,0xFC, -+0xA3,0xE0,0xFD,0xA3,0xE0,0xFE,0xA3,0xE0, -+0xFF,0x22,0xE0,0xF8,0xA3,0xE0,0xF9,0xA3, -+0xE0,0xFA,0xA3,0xE0,0xFB,0x22,0xEC,0xF0, -+0xA3,0xED,0xF0,0xA3,0xEE,0xF0,0xA3,0xEF, -+0xF0,0x22,0x12,0x03,0xF8,0x12,0x04,0x1A, -+0x44,0x40,0x12,0x04,0x0F,0x7D,0x03,0x7C, -+0x00,0x12,0x04,0x23,0x12,0x05,0xAF,0x12, -+0x03,0xF8,0x12,0x04,0x1A,0x54,0xBF,0x12, -+0x04,0x0F,0x7D,0x03,0x7C,0x00,0x12,0x03, -+0xD0,0x7F,0x02,0x7E,0x66,0x12,0x05,0x67, -+0xEF,0x54,0xFD,0x54,0xFE,0x12,0x04,0x33, -+0x12,0x03,0xD0,0x7F,0x02,0x7E,0x66,0x12, -+0x05,0x67,0xEF,0x44,0x02,0x44,0x01,0x12, -+0x04,0x33,0x12,0x04,0x23,0x02,0x05,0xAF, -+0x7F,0x01,0x7E,0x66,0x12,0x05,0xAF,0x7D, -+0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12, -+0x05,0xAF,0xE4,0xFD,0xFC,0x7F,0x01,0x7E, -+0x66,0x12,0x05,0xAF,0x7D,0x80,0x7C,0x00, -+0x7F,0x00,0x7E,0x66,0x12,0x05,0xAF,0x22, -+0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66, -+0x12,0x05,0xAF,0x7D,0x80,0x7C,0x00,0x7F, -+0x00,0x7E,0x66,0x12,0x05,0xAF,0x22,0xFD, -+0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,0x05, -+0xAF,0x22,0x7F,0x02,0x7E,0x66,0x12,0x05, -+0x67,0xEF,0x22,0x7F,0x01,0x7E,0x66,0x12, -+0x05,0xAF,0x7D,0xC0,0x7C,0x00,0x7F,0x00, -+0x7E,0x66,0x22,0xFD,0xAC,0x06,0x7F,0x02, -+0x7E,0x66,0x12,0x05,0xAF,0xE4,0xFD,0xFC, -+0x22,0x78,0x7F,0xE4,0xF6,0xD8,0xFD,0x75, -+0x81,0x3C,0x02,0x04,0x88,0x02,0x00,0x0E, -+0xE4,0x93,0xA3,0xF8,0xE4,0x93,0xA3,0x40, -+0x03,0xF6,0x80,0x01,0xF2,0x08,0xDF,0xF4, -+0x80,0x29,0xE4,0x93,0xA3,0xF8,0x54,0x07, -+0x24,0x0C,0xC8,0xC3,0x33,0xC4,0x54,0x0F, -+0x44,0x20,0xC8,0x83,0x40,0x04,0xF4,0x56, -+0x80,0x01,0x46,0xF6,0xDF,0xE4,0x80,0x0B, -+0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80, -+0x90,0x05,0xCB,0xE4,0x7E,0x01,0x93,0x60, -+0xBC,0xA3,0xFF,0x54,0x3F,0x30,0xE5,0x09, -+0x54,0x1F,0xFE,0xE4,0x93,0xA3,0x60,0x01, -+0x0E,0xCF,0x54,0xC0,0x25,0xE0,0x60,0xA8, -+0x40,0xB8,0xE4,0x93,0xA3,0xFA,0xE4,0x93, -+0xA3,0xF8,0xE4,0x93,0xA3,0xC8,0xC5,0x82, -+0xC8,0xCA,0xC5,0x83,0xCA,0xF0,0xA3,0xC8, -+0xC5,0x82,0xC8,0xCA,0xC5,0x83,0xCA,0xDF, -+0xE9,0xDE,0xE7,0x80,0xBE,0x75,0x0F,0x80, -+0x75,0x0E,0x7E,0x75,0x0D,0xAA,0x75,0x0C, -+0x83,0xE4,0xF5,0x10,0x75,0x0B,0xA0,0x75, -+0x0A,0xAC,0x75,0x09,0xB9,0x75,0x08,0x03, -+0x75,0x89,0x11,0x7B,0x60,0x7A,0x09,0xF9, -+0xF8,0xAF,0x0B,0xAE,0x0A,0xAD,0x09,0xAC, -+0x08,0x12,0x02,0xBB,0xAD,0x07,0xAC,0x06, -+0xC3,0xE4,0x9D,0xFD,0xE4,0x9C,0xFC,0x78, -+0x17,0xF6,0xAF,0x05,0xEF,0x08,0xF6,0x18, -+0xE6,0xF5,0x8C,0x08,0xE6,0xF5,0x8A,0x74, -+0x0D,0x2D,0xFD,0xE4,0x3C,0x18,0xF6,0xAF, -+0x05,0xEF,0x08,0xF6,0x75,0x88,0x10,0x53, -+0x8E,0xC7,0xD2,0xA9,0x22,0xC0,0xE0,0xC0, -+0xF0,0xC0,0x83,0xC0,0x82,0xC0,0xD0,0x75, -+0xD0,0x00,0xC0,0x00,0x78,0x17,0xE6,0xF5, -+0x8C,0x78,0x18,0xE6,0xF5,0x8A,0x90,0x06, -+0x2B,0xE4,0x75,0xF0,0x01,0x12,0x02,0x69, -+0x90,0x06,0x2D,0xE4,0x75,0xF0,0x01,0x12, -+0x02,0x69,0xD0,0x00,0xD0,0xD0,0xD0,0x82, -+0xD0,0x83,0xD0,0xF0,0xD0,0xE0,0x32,0xC2, -+0xAF,0xAD,0x07,0xAC,0x06,0x8C,0xA2,0x8D, -+0xA3,0x75,0xA0,0x01,0x00,0x00,0x00,0x00, -+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAE, -+0xA1,0xBE,0x00,0xF0,0xAE,0xA6,0xAF,0xA7, -+0xD2,0xAF,0x22,0x90,0x06,0x24,0x12,0x03, -+0x5E,0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE, -+0xE4,0x3D,0xFD,0xE4,0x3C,0x22,0xE4,0x7F, -+0x20,0x7E,0x4E,0xFD,0xFC,0x90,0x06,0x24, -+0x12,0x03,0x6A,0xC3,0x02,0x03,0x4D,0xC2, -+0xAF,0xAB,0x07,0xAA,0x06,0x8A,0xA2,0x8B, -+0xA3,0x8C,0xA4,0x8D,0xA5,0x75,0xA0,0x03, -+0x00,0x00,0x00,0xAA,0xA1,0xBA,0x00,0xF8, -+0xD2,0xAF,0x22,0x42,0x06,0x2D,0x00,0x00, -+0x42,0x06,0x2B,0x00,0x00,0x00,0x12,0x05, -+0xDF,0x12,0x04,0xCD,0x02,0x00,0x03,0xE4, -+0xF5,0x8E,0x22}; -+ -+static rtk_api_ret_t _rtk_port_FiberModeAbility_set(rtk_port_t port, rtk_port_phy_ability_t *pAbility) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 regData; -+ -+ /* Check Combo port or not */ -+ RTK_CHK_PORT_IS_COMBO(port); -+ -+ /* Flow Control */ -+ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_FIB0_CFG04, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ if (pAbility->AsyFC == 1) -+ regData |= (0x0001 << 8); -+ else -+ regData &= ~(0x0001 << 8); -+ -+ if (pAbility->FC == 1) -+ regData |= (0x0001 << 7); -+ else -+ regData &= ~(0x0001 << 7); -+ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_FIB0_CFG04, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ /* Speed ability */ -+ if( (pAbility->Full_1000 == 1) && (pAbility->Full_100 == 1) && (pAbility->AutoNegotiation == 1) ) -+ { -+ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_MODE_OFFSET, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_MODE_MASK, 7)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_FIB0_CFG00, 0x1140)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if(pAbility->Full_1000 == 1) -+ { -+ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_MODE_OFFSET, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_MODE_MASK, 4)) != RT_ERR_OK) -+ return retVal; -+ -+ if(pAbility->AutoNegotiation == 1) -+ { -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_FIB0_CFG00, 0x1140)) != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_FIB0_CFG00, 0x0140)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ else if(pAbility->Full_100 == 1) -+ { -+ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_MODE_OFFSET, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_MODE_MASK, 5)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_FIB0_CFG00, 0x2100)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ /* Digital software reset */ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0003)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x0080)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_SDS_INDACS_DATA, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ regData |= (0x0001 << 6); -+ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0003)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) -+ return retVal; -+ -+ regData &= ~(0x0001 << 6); -+ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0003)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) -+ return retVal; -+ -+ /* CDR reset */ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x1401))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0000))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x1403))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0000))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+static rtk_api_ret_t _rtk_port_FiberModeAbility_get(rtk_port_t port, rtk_port_phy_ability_t *pAbility) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 data, regData; -+ -+ /* Check Combo port or not */ -+ RTK_CHK_PORT_IS_COMBO(port); -+ -+ memset(pAbility, 0x00, sizeof(rtk_port_phy_ability_t)); -+ -+ /* Flow Control */ -+ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_REG4_OFFSET, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_REG4_FIB100_OFFSET, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0044)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x0080)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_SDS_INDACS_DATA, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ if(regData & (0x0001 << 8)) -+ pAbility->AsyFC = 1; -+ -+ if(regData & (0x0001 << 7)) -+ pAbility->FC = 1; -+ -+ /* Speed ability */ -+ if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_MODE_OFFSET, &data)) != RT_ERR_OK) -+ return retVal; -+ -+ if(data == 0) -+ { -+ pAbility->AutoNegotiation = 1; -+ pAbility->Full_1000 = 1; -+ pAbility->Full_100 = 1; -+ } -+ else -+ { -+ if ((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_MODE_MASK, &data)) != RT_ERR_OK) -+ return retVal; -+ -+ if(data == 4) -+ { -+ pAbility->Full_1000 = 1; -+ -+ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_FIB0_CFG00, &data)) != RT_ERR_OK) -+ return retVal; -+ -+ if(data & 0x1000) -+ pAbility->AutoNegotiation = 1; -+ else -+ pAbility->AutoNegotiation = 0; -+ } -+ else if(data == 5) -+ pAbility->Full_100 = 1; -+ else -+ return RT_ERR_FAILED; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_phyAutoNegoAbility_set -+ * Description: -+ * Set Ethernet PHY auto-negotiation desired ability. -+ * Input: -+ * port - port id. -+ * pAbility - Ability structure -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_PHY_REG_ID - Invalid PHY address -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy -+ * Note: -+ * If Full_1000 bit is set to 1, the AutoNegotiation will be automatic set to 1. While both AutoNegotiation and Full_1000 are set to 0, the PHY speed and duplex selection will -+ * be set as following 100F > 100H > 10F > 10H priority sequence. -+ */ -+rtk_api_ret_t rtk_port_phyAutoNegoAbility_set(rtk_port_t port, rtk_port_phy_ability_t *pAbility) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 phyData; -+ rtk_uint32 phyEnMsk0; -+ rtk_uint32 phyEnMsk4; -+ rtk_uint32 phyEnMsk9; -+ rtk_port_media_t media_type; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_IS_UTP(port); -+ -+ if(NULL == pAbility) -+ return RT_ERR_NULL_POINTER; -+ -+ if (pAbility->Half_10 >= RTK_ENABLE_END || pAbility->Full_10 >= RTK_ENABLE_END || -+ pAbility->Half_100 >= RTK_ENABLE_END || pAbility->Full_100 >= RTK_ENABLE_END || -+ pAbility->Full_1000 >= RTK_ENABLE_END || pAbility->AutoNegotiation >= RTK_ENABLE_END || -+ pAbility->AsyFC >= RTK_ENABLE_END || pAbility->FC >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if (rtk_switch_isComboPort(port) == RT_ERR_OK) -+ { -+ if ((retVal = rtk_port_phyComboPortMedia_get(port, &media_type)) != RT_ERR_OK) -+ return retVal; -+ -+ if(media_type == PORT_MEDIA_FIBER) -+ { -+ return _rtk_port_FiberModeAbility_set(port, pAbility); -+ } -+ } -+ -+ /*for PHY auto mode setup*/ -+ pAbility->AutoNegotiation = 1; -+ -+ phyEnMsk0 = 0; -+ phyEnMsk4 = 0; -+ phyEnMsk9 = 0; -+ -+ if (1 == pAbility->Half_10) -+ { -+ /*10BASE-TX half duplex capable in reg 4.5*/ -+ phyEnMsk4 = phyEnMsk4 | (1 << 5); -+ -+ /*Speed selection [1:0] */ -+ /* 11=Reserved*/ -+ /* 10= 1000Mpbs*/ -+ /* 01= 100Mpbs*/ -+ /* 00= 10Mpbs*/ -+ phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); -+ phyEnMsk0 = phyEnMsk0 & (~(1 << 13)); -+ } -+ -+ if (1 == pAbility->Full_10) -+ { -+ /*10BASE-TX full duplex capable in reg 4.6*/ -+ phyEnMsk4 = phyEnMsk4 | (1 << 6); -+ /*Speed selection [1:0] */ -+ /* 11=Reserved*/ -+ /* 10= 1000Mpbs*/ -+ /* 01= 100Mpbs*/ -+ /* 00= 10Mpbs*/ -+ phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); -+ phyEnMsk0 = phyEnMsk0 & (~(1 << 13)); -+ -+ /*Full duplex mode in reg 0.8*/ -+ phyEnMsk0 = phyEnMsk0 | (1 << 8); -+ -+ } -+ -+ if (1 == pAbility->Half_100) -+ { -+ /*100BASE-TX half duplex capable in reg 4.7*/ -+ phyEnMsk4 = phyEnMsk4 | (1 << 7); -+ /*Speed selection [1:0] */ -+ /* 11=Reserved*/ -+ /* 10= 1000Mpbs*/ -+ /* 01= 100Mpbs*/ -+ /* 00= 10Mpbs*/ -+ phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); -+ phyEnMsk0 = phyEnMsk0 | (1 << 13); -+ } -+ -+ -+ if (1 == pAbility->Full_100) -+ { -+ /*100BASE-TX full duplex capable in reg 4.8*/ -+ phyEnMsk4 = phyEnMsk4 | (1 << 8); -+ /*Speed selection [1:0] */ -+ /* 11=Reserved*/ -+ /* 10= 1000Mpbs*/ -+ /* 01= 100Mpbs*/ -+ /* 00= 10Mpbs*/ -+ phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); -+ phyEnMsk0 = phyEnMsk0 | (1 << 13); -+ /*Full duplex mode in reg 0.8*/ -+ phyEnMsk0 = phyEnMsk0 | (1 << 8); -+ } -+ -+ -+ if (1 == pAbility->Full_1000) -+ { -+ /*1000 BASE-T FULL duplex capable setting in reg 9.9*/ -+ phyEnMsk9 = phyEnMsk9 | (1 << 9); -+ -+ /*Speed selection [1:0] */ -+ /* 11=Reserved*/ -+ /* 10= 1000Mpbs*/ -+ /* 01= 100Mpbs*/ -+ /* 00= 10Mpbs*/ -+ phyEnMsk0 = phyEnMsk0 | (1 << 6); -+ phyEnMsk0 = phyEnMsk0 & (~(1 << 13)); -+ -+ -+ /*Auto-Negotiation setting in reg 0.12*/ -+ phyEnMsk0 = phyEnMsk0 | (1 << 12); -+ -+ } -+ -+ if (1 == pAbility->AutoNegotiation) -+ { -+ /*Auto-Negotiation setting in reg 0.12*/ -+ phyEnMsk0 = phyEnMsk0 | (1 << 12); -+ } -+ -+ if (1 == pAbility->AsyFC) -+ { -+ /*Asymetric flow control in reg 4.11*/ -+ phyEnMsk4 = phyEnMsk4 | (1 << 11); -+ } -+ if (1 == pAbility->FC) -+ { -+ /*Flow control in reg 4.10*/ -+ phyEnMsk4 = phyEnMsk4 | (1 << 10); -+ } -+ -+ /*1000 BASE-T control register setting*/ -+ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, &phyData)) != RT_ERR_OK) -+ return retVal; -+ -+ phyData = (phyData & (~0x0200)) | phyEnMsk9 ; -+ -+ if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, phyData)) != RT_ERR_OK) -+ return retVal; -+ -+ /*Auto-Negotiation control register setting*/ -+ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, &phyData)) != RT_ERR_OK) -+ return retVal; -+ -+ phyData = (phyData & (~0x0DE0)) | phyEnMsk4; -+ if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, phyData)) != RT_ERR_OK) -+ return retVal; -+ -+ /*Control register setting and restart auto*/ -+ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, &phyData)) != RT_ERR_OK) -+ return retVal; -+ -+ phyData = (phyData & (~0x3140)) | phyEnMsk0; -+ /*If have auto-negotiation capable, then restart auto negotiation*/ -+ if (1 == pAbility->AutoNegotiation) -+ { -+ phyData = phyData | (1 << 9); -+ } -+ -+ if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, phyData)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_phyAutoNegoAbility_get -+ * Description: -+ * Get PHY ability through PHY registers. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pAbility - Ability structure -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_PHY_REG_ID - Invalid PHY address -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy -+ * Note: -+ * Get the capability of specified PHY. -+ */ -+rtk_api_ret_t rtk_port_phyAutoNegoAbility_get(rtk_port_t port, rtk_port_phy_ability_t *pAbility) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 phyData0; -+ rtk_uint32 phyData4; -+ rtk_uint32 phyData9; -+ rtk_port_media_t media_type; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_IS_UTP(port); -+ -+ if(NULL == pAbility) -+ return RT_ERR_NULL_POINTER; -+ -+ if (rtk_switch_isComboPort(port) == RT_ERR_OK) -+ { -+ if ((retVal = rtk_port_phyComboPortMedia_get(port, &media_type)) != RT_ERR_OK) -+ return retVal; -+ -+ if(media_type == PORT_MEDIA_FIBER) -+ { -+ return _rtk_port_FiberModeAbility_get(port, pAbility); -+ } -+ } -+ -+ /*Control register setting and restart auto*/ -+ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, &phyData0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*Auto-Negotiation control register setting*/ -+ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, &phyData4)) != RT_ERR_OK) -+ return retVal; -+ -+ /*1000 BASE-T control register setting*/ -+ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, &phyData9)) != RT_ERR_OK) -+ return retVal; -+ -+ if (phyData9 & (1 << 9)) -+ pAbility->Full_1000 = 1; -+ else -+ pAbility->Full_1000 = 0; -+ -+ if (phyData4 & (1 << 11)) -+ pAbility->AsyFC = 1; -+ else -+ pAbility->AsyFC = 0; -+ -+ if (phyData4 & (1 << 10)) -+ pAbility->FC = 1; -+ else -+ pAbility->FC = 0; -+ -+ -+ if (phyData4 & (1 << 8)) -+ pAbility->Full_100 = 1; -+ else -+ pAbility->Full_100 = 0; -+ -+ if (phyData4 & (1 << 7)) -+ pAbility->Half_100 = 1; -+ else -+ pAbility->Half_100 = 0; -+ -+ if (phyData4 & (1 << 6)) -+ pAbility->Full_10 = 1; -+ else -+ pAbility->Full_10 = 0; -+ -+ if (phyData4 & (1 << 5)) -+ pAbility->Half_10 = 1; -+ else -+ pAbility->Half_10 = 0; -+ -+ -+ if (phyData0 & (1 << 12)) -+ pAbility->AutoNegotiation = 1; -+ else -+ pAbility->AutoNegotiation = 0; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_phyForceModeAbility_set -+ * Description: -+ * Set the port speed/duplex mode/pause/asy_pause in the PHY force mode. -+ * Input: -+ * port - port id. -+ * pAbility - Ability structure -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_PHY_REG_ID - Invalid PHY address -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy -+ * Note: -+ * While both AutoNegotiation and Full_1000 are set to 0, the PHY speed and duplex selection will -+ * be set as following 100F > 100H > 10F > 10H priority sequence. -+ * This API can be used to configure combo port in fiber mode. -+ * The possible parameters in fiber mode are Full_1000 and Full 100. -+ * All the other fields in rtk_port_phy_ability_t will be ignored in fiber port. -+ */ -+rtk_api_ret_t rtk_port_phyForceModeAbility_set(rtk_port_t port, rtk_port_phy_ability_t *pAbility) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 phyData; -+ rtk_uint32 phyEnMsk0; -+ rtk_uint32 phyEnMsk4; -+ rtk_uint32 phyEnMsk9; -+ rtk_port_media_t media_type; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_IS_UTP(port); -+ -+ if(NULL == pAbility) -+ return RT_ERR_NULL_POINTER; -+ -+ if (pAbility->Half_10 >= RTK_ENABLE_END || pAbility->Full_10 >= RTK_ENABLE_END || -+ pAbility->Half_100 >= RTK_ENABLE_END || pAbility->Full_100 >= RTK_ENABLE_END || -+ pAbility->Full_1000 >= RTK_ENABLE_END || pAbility->AutoNegotiation >= RTK_ENABLE_END || -+ pAbility->AsyFC >= RTK_ENABLE_END || pAbility->FC >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if (rtk_switch_isComboPort(port) == RT_ERR_OK) -+ { -+ if ((retVal = rtk_port_phyComboPortMedia_get(port, &media_type)) != RT_ERR_OK) -+ return retVal; -+ -+ if(media_type == PORT_MEDIA_FIBER) -+ { -+ return _rtk_port_FiberModeAbility_set(port, pAbility); -+ } -+ } -+ -+ if (1 == pAbility->Full_1000) -+ return RT_ERR_INPUT; -+ -+ /*for PHY force mode setup*/ -+ pAbility->AutoNegotiation = 0; -+ -+ phyEnMsk0 = 0; -+ phyEnMsk4 = 0; -+ phyEnMsk9 = 0; -+ -+ if (1 == pAbility->Half_10) -+ { -+ /*10BASE-TX half duplex capable in reg 4.5*/ -+ phyEnMsk4 = phyEnMsk4 | (1 << 5); -+ -+ /*Speed selection [1:0] */ -+ /* 11=Reserved*/ -+ /* 10= 1000Mpbs*/ -+ /* 01= 100Mpbs*/ -+ /* 00= 10Mpbs*/ -+ phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); -+ phyEnMsk0 = phyEnMsk0 & (~(1 << 13)); -+ } -+ -+ if (1 == pAbility->Full_10) -+ { -+ /*10BASE-TX full duplex capable in reg 4.6*/ -+ phyEnMsk4 = phyEnMsk4 | (1 << 6); -+ /*Speed selection [1:0] */ -+ /* 11=Reserved*/ -+ /* 10= 1000Mpbs*/ -+ /* 01= 100Mpbs*/ -+ /* 00= 10Mpbs*/ -+ phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); -+ phyEnMsk0 = phyEnMsk0 & (~(1 << 13)); -+ -+ /*Full duplex mode in reg 0.8*/ -+ phyEnMsk0 = phyEnMsk0 | (1 << 8); -+ -+ } -+ -+ if (1 == pAbility->Half_100) -+ { -+ /*100BASE-TX half duplex capable in reg 4.7*/ -+ phyEnMsk4 = phyEnMsk4 | (1 << 7); -+ /*Speed selection [1:0] */ -+ /* 11=Reserved*/ -+ /* 10= 1000Mpbs*/ -+ /* 01= 100Mpbs*/ -+ /* 00= 10Mpbs*/ -+ phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); -+ phyEnMsk0 = phyEnMsk0 | (1 << 13); -+ } -+ -+ -+ if (1 == pAbility->Full_100) -+ { -+ /*100BASE-TX full duplex capable in reg 4.8*/ -+ phyEnMsk4 = phyEnMsk4 | (1 << 8); -+ /*Speed selection [1:0] */ -+ /* 11=Reserved*/ -+ /* 10= 1000Mpbs*/ -+ /* 01= 100Mpbs*/ -+ /* 00= 10Mpbs*/ -+ phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); -+ phyEnMsk0 = phyEnMsk0 | (1 << 13); -+ /*Full duplex mode in reg 0.8*/ -+ phyEnMsk0 = phyEnMsk0 | (1 << 8); -+ } -+ -+ if (1 == pAbility->AsyFC) -+ { -+ /*Asymmetric flow control in reg 4.11*/ -+ phyEnMsk4 = phyEnMsk4 | (1 << 11); -+ } -+ if (1 == pAbility->FC) -+ { -+ /*Flow control in reg 4.10*/ -+ phyEnMsk4 = phyEnMsk4 | ((1 << 10)); -+ } -+ -+ /*1000 BASE-T control register setting*/ -+ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, &phyData)) != RT_ERR_OK) -+ return retVal; -+ -+ phyData = (phyData & (~0x0200)) | phyEnMsk9 ; -+ -+ if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, phyData)) != RT_ERR_OK) -+ return retVal; -+ -+ /*Auto-Negotiation control register setting*/ -+ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, &phyData)) != RT_ERR_OK) -+ return retVal; -+ -+ phyData = (phyData & (~0x0DE0)) | phyEnMsk4; -+ if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, phyData)) != RT_ERR_OK) -+ return retVal; -+ -+ /*Control register setting and power off/on*/ -+ phyData = phyEnMsk0 & (~(1 << 12)); -+ phyData |= (1 << 11); /* power down PHY, bit 11 should be set to 1 */ -+ if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, phyData)) != RT_ERR_OK) -+ return retVal; -+ -+ phyData = phyData & (~(1 << 11)); /* power on PHY, bit 11 should be set to 0*/ -+ if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, phyData)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_phyForceModeAbility_get -+ * Description: -+ * Get PHY ability through PHY registers. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pAbility - Ability structure -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_PHY_REG_ID - Invalid PHY address -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy -+ * Note: -+ * Get the capability of specified PHY. -+ */ -+rtk_api_ret_t rtk_port_phyForceModeAbility_get(rtk_port_t port, rtk_port_phy_ability_t *pAbility) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 phyData0; -+ rtk_uint32 phyData4; -+ rtk_uint32 phyData9; -+ rtk_port_media_t media_type; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_IS_UTP(port); -+ -+ if(NULL == pAbility) -+ return RT_ERR_NULL_POINTER; -+ -+ if (rtk_switch_isComboPort(port) == RT_ERR_OK) -+ { -+ if ((retVal = rtk_port_phyComboPortMedia_get(port, &media_type)) != RT_ERR_OK) -+ return retVal; -+ -+ if(media_type == PORT_MEDIA_FIBER) -+ { -+ return _rtk_port_FiberModeAbility_get(port, pAbility); -+ } -+ } -+ -+ /*Control register setting and restart auto*/ -+ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, &phyData0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*Auto-Negotiation control register setting*/ -+ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, &phyData4)) != RT_ERR_OK) -+ return retVal; -+ -+ /*1000 BASE-T control register setting*/ -+ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, &phyData9)) != RT_ERR_OK) -+ return retVal; -+ -+ if (phyData9 & (1 << 9)) -+ pAbility->Full_1000 = 1; -+ else -+ pAbility->Full_1000 = 0; -+ -+ if (phyData4 & (1 << 11)) -+ pAbility->AsyFC = 1; -+ else -+ pAbility->AsyFC = 0; -+ -+ if (phyData4 & ((1 << 10))) -+ pAbility->FC = 1; -+ else -+ pAbility->FC = 0; -+ -+ -+ if (phyData4 & (1 << 8)) -+ pAbility->Full_100 = 1; -+ else -+ pAbility->Full_100 = 0; -+ -+ if (phyData4 & (1 << 7)) -+ pAbility->Half_100 = 1; -+ else -+ pAbility->Half_100 = 0; -+ -+ if (phyData4 & (1 << 6)) -+ pAbility->Full_10 = 1; -+ else -+ pAbility->Full_10 = 0; -+ -+ if (phyData4 & (1 << 5)) -+ pAbility->Half_10 = 1; -+ else -+ pAbility->Half_10 = 0; -+ -+ -+ if (phyData0 & (1 << 12)) -+ pAbility->AutoNegotiation = 1; -+ else -+ pAbility->AutoNegotiation = 0; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_phyStatus_get -+ * Description: -+ * Get Ethernet PHY linking status -+ * Input: -+ * port - Port id. -+ * Output: -+ * linkStatus - PHY link status -+ * speed - PHY link speed -+ * duplex - PHY duplex mode -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_PHY_REG_ID - Invalid PHY address -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy -+ * Note: -+ * API will return auto negotiation status of phy. -+ */ -+rtk_api_ret_t rtk_port_phyStatus_get(rtk_port_t port, rtk_port_linkStatus_t *pLinkStatus, rtk_port_speed_t *pSpeed, rtk_port_duplex_t *pDuplex) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 phyData; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_IS_UTP(port); -+ -+ if( (NULL == pLinkStatus) || (NULL == pSpeed) || (NULL == pDuplex) ) -+ return RT_ERR_NULL_POINTER; -+ -+ /*Get PHY resolved register*/ -+ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_RESOLVED_REG, &phyData)) != RT_ERR_OK) -+ return retVal; -+ -+ /*check link status*/ -+ if (phyData & (1<<2)) -+ { -+ *pLinkStatus = 1; -+ -+ /*check link speed*/ -+ *pSpeed = (phyData&0x0030) >> 4; -+ -+ /*check link duplex*/ -+ *pDuplex = (phyData&0x0008) >> 3; -+ } -+ else -+ { -+ *pLinkStatus = 0; -+ *pSpeed = 0; -+ *pDuplex = 0; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_macForceLink_set -+ * Description: -+ * Set port force linking configuration. -+ * Input: -+ * port - port id. -+ * pPortability - port ability configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * This API can set Port/MAC force mode properties. -+ */ -+rtk_api_ret_t rtk_port_macForceLink_set(rtk_port_t port, rtk_port_mac_ability_t *pPortability) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_port_ability_t ability; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_IS_UTP(port); -+ -+ if(NULL == pPortability) -+ return RT_ERR_NULL_POINTER; -+ -+ if (pPortability->forcemode >1|| pPortability->speed > 2 || pPortability->duplex > 1 || -+ pPortability->link > 1 || pPortability->nway > 1 || pPortability->txpause > 1 || pPortability->rxpause > 1) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_getAsicPortForceLink(rtk_switch_port_L2P_get(port), &ability)) != RT_ERR_OK) -+ return retVal; -+ -+ ability.forcemode = pPortability->forcemode; -+ ability.speed = pPortability->speed; -+ ability.duplex = pPortability->duplex; -+ ability.link = pPortability->link; -+ ability.nway = pPortability->nway; -+ ability.txpause = pPortability->txpause; -+ ability.rxpause = pPortability->rxpause; -+ -+ if ((retVal = rtl8367c_setAsicPortForceLink(rtk_switch_port_L2P_get(port), &ability)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_macForceLink_get -+ * Description: -+ * Get port force linking configuration. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pPortability - port ability configuration -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can get Port/MAC force mode properties. -+ */ -+rtk_api_ret_t rtk_port_macForceLink_get(rtk_port_t port, rtk_port_mac_ability_t *pPortability) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_port_ability_t ability; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_IS_UTP(port); -+ -+ if(NULL == pPortability) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicPortForceLink(rtk_switch_port_L2P_get(port), &ability)) != RT_ERR_OK) -+ return retVal; -+ -+ pPortability->forcemode = ability.forcemode; -+ pPortability->speed = ability.speed; -+ pPortability->duplex = ability.duplex; -+ pPortability->link = ability.link; -+ pPortability->nway = ability.nway; -+ pPortability->txpause = ability.txpause; -+ pPortability->rxpause = ability.rxpause; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_macForceLinkExt_set -+ * Description: -+ * Set external interface force linking configuration. -+ * Input: -+ * port - external port ID -+ * mode - external interface mode -+ * pPortability - port ability configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can set external interface force mode properties. -+ * The external interface can be set to: -+ * - MODE_EXT_DISABLE, -+ * - MODE_EXT_RGMII, -+ * - MODE_EXT_MII_MAC, -+ * - MODE_EXT_MII_PHY, -+ * - MODE_EXT_TMII_MAC, -+ * - MODE_EXT_TMII_PHY, -+ * - MODE_EXT_GMII, -+ * - MODE_EXT_RMII_MAC, -+ * - MODE_EXT_RMII_PHY, -+ * - MODE_EXT_SGMII, -+ * - MODE_EXT_HSGMII, -+ * - MODE_EXT_1000X_100FX, -+ * - MODE_EXT_1000X, -+ * - MODE_EXT_100FX, -+ */ -+rtk_api_ret_t rtk_port_macForceLinkExt_set(rtk_port_t port, rtk_mode_ext_t mode, rtk_port_mac_ability_t *pPortability) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_port_ability_t ability; -+ rtk_uint32 ext_id; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_IS_EXT(port); -+ -+ if(NULL == pPortability) -+ return RT_ERR_NULL_POINTER; -+ -+ if (mode >=MODE_EXT_END) -+ return RT_ERR_INPUT; -+ -+ if(mode == MODE_EXT_HSGMII) -+ { -+ if (pPortability->forcemode > 1 || pPortability->speed != PORT_SPEED_2500M || pPortability->duplex != PORT_FULL_DUPLEX || -+ pPortability->link >= PORT_LINKSTATUS_END || pPortability->nway > 1 || pPortability->txpause > 1 || pPortability->rxpause > 1) -+ return RT_ERR_INPUT; -+ -+ if(rtk_switch_isHsgPort(port) != RT_ERR_OK) -+ return RT_ERR_PORT_ID; -+ } -+ else -+ { -+ if (pPortability->forcemode > 1 || pPortability->speed > PORT_SPEED_1000M || pPortability->duplex >= PORT_DUPLEX_END || -+ pPortability->link >= PORT_LINKSTATUS_END || pPortability->nway > 1 || pPortability->txpause > 1 || pPortability->rxpause > 1) -+ return RT_ERR_INPUT; -+ } -+ -+ ext_id = port - 15; -+ -+ if(mode == MODE_EXT_DISABLE) -+ { -+ memset(&ability, 0x00, sizeof(rtl8367c_port_ability_t)); -+ if ((retVal = rtl8367c_setAsicPortForceLinkExt(ext_id, &ability)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicPortExtMode(ext_id, mode)) != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ if ((retVal = rtl8367c_setAsicPortExtMode(ext_id, mode)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicPortForceLinkExt(ext_id, &ability)) != RT_ERR_OK) -+ return retVal; -+ -+ ability.forcemode = pPortability->forcemode; -+ ability.speed = (mode == MODE_EXT_HSGMII) ? PORT_SPEED_1000M : pPortability->speed; -+ ability.duplex = pPortability->duplex; -+ ability.link = pPortability->link; -+ ability.nway = pPortability->nway; -+ ability.txpause = pPortability->txpause; -+ ability.rxpause = pPortability->rxpause; -+ -+ if ((retVal = rtl8367c_setAsicPortForceLinkExt(ext_id, &ability)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_macForceLinkExt_get -+ * Description: -+ * Set external interface force linking configuration. -+ * Input: -+ * port - external port ID -+ * Output: -+ * pMode - external interface mode -+ * pPortability - port ability configuration -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can get external interface force mode properties. -+ */ -+rtk_api_ret_t rtk_port_macForceLinkExt_get(rtk_port_t port, rtk_mode_ext_t *pMode, rtk_port_mac_ability_t *pPortability) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_port_ability_t ability; -+ rtk_uint32 ext_id; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_IS_EXT(port); -+ -+ if(NULL == pMode) -+ return RT_ERR_NULL_POINTER; -+ -+ if(NULL == pPortability) -+ return RT_ERR_NULL_POINTER; -+ -+ ext_id = port - 15; -+ -+ if ((retVal = rtl8367c_getAsicPortExtMode(ext_id, (rtk_uint32 *)pMode)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicPortForceLinkExt(ext_id, &ability)) != RT_ERR_OK) -+ return retVal; -+ -+ pPortability->forcemode = ability.forcemode; -+ pPortability->speed = (*pMode == MODE_EXT_HSGMII) ? PORT_SPEED_2500M : ability.speed; -+ pPortability->duplex = ability.duplex; -+ pPortability->link = ability.link; -+ pPortability->nway = ability.nway; -+ pPortability->txpause = ability.txpause; -+ pPortability->rxpause = ability.rxpause; -+ -+ return RT_ERR_OK; -+ -+} -+ -+/* Function Name: -+ * rtk_port_macStatus_get -+ * Description: -+ * Get port link status. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pPortstatus - port ability configuration -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * This API can get Port/PHY properties. -+ */ -+rtk_api_ret_t rtk_port_macStatus_get(rtk_port_t port, rtk_port_mac_ability_t *pPortstatus) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_port_status_t status; -+ rtk_uint32 hsgsel; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(NULL == pPortstatus) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicPortStatus(rtk_switch_port_L2P_get(port), &status)) != RT_ERR_OK) -+ return retVal; -+ -+ -+ pPortstatus->duplex = status.duplex; -+ pPortstatus->link = status.link; -+ pPortstatus->nway = status.nway; -+ pPortstatus->txpause = status.txpause; -+ pPortstatus->rxpause = status.rxpause; -+ -+ if( (retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET, &hsgsel)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (rtk_switch_isHsgPort(port) == RT_ERR_OK) && (hsgsel == 1) ) -+ pPortstatus->speed = PORT_SPEED_2500M; -+ else -+ pPortstatus->speed = status.speed; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_macLocalLoopbackEnable_set -+ * Description: -+ * Set Port Local Loopback. (Redirect TX to RX.) -+ * Input: -+ * port - Port id. -+ * enable - Loopback state, 0:disable, 1:enable -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * This API can enable/disable Local loopback in MAC. -+ * For UTP port, This API will also enable the digital -+ * loopback bit in PHY register for sync of speed between -+ * PHY and MAC. For EXT port, users need to force the -+ * link state by themselves. -+ */ -+rtk_api_ret_t rtk_port_macLocalLoopbackEnable_set(rtk_port_t port, rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 data; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(enable >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicPortLoopback(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) -+ return retVal; -+ -+ if(rtk_switch_isUtpPort(port) == RT_ERR_OK) -+ { -+ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, &data)) != RT_ERR_OK) -+ return retVal; -+ -+ if(enable == ENABLED) -+ data |= (0x0001 << 14); -+ else -+ data &= ~(0x0001 << 14); -+ -+ if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, data)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_macLocalLoopbackEnable_get -+ * Description: -+ * Get Port Local Loopback. (Redirect TX to RX.) -+ * Input: -+ * port - Port id. -+ * Output: -+ * pEnable - Loopback state, 0:disable, 1:enable -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * None. -+ */ -+rtk_api_ret_t rtk_port_macLocalLoopbackEnable_get(rtk_port_t port, rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(NULL == pEnable) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicPortLoopback(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_phyReg_set -+ * Description: -+ * Set PHY register data of the specific port. -+ * Input: -+ * port - port id. -+ * reg - Register id -+ * regData - Register data -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_PHY_REG_ID - Invalid PHY address -+ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy -+ * Note: -+ * This API can set PHY register data of the specific port. -+ */ -+rtk_api_ret_t rtk_port_phyReg_set(rtk_port_t port, rtk_port_phy_reg_t reg, rtk_port_phy_data_t regData) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_IS_UTP(port); -+ -+ if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), reg, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_phyReg_get -+ * Description: -+ * Get PHY register data of the specific port. -+ * Input: -+ * port - Port id. -+ * reg - Register id -+ * Output: -+ * pData - Register data -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_PHY_REG_ID - Invalid PHY address -+ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy -+ * Note: -+ * This API can get PHY register data of the specific port. -+ */ -+rtk_api_ret_t rtk_port_phyReg_get(rtk_port_t port, rtk_port_phy_reg_t reg, rtk_port_phy_data_t *pData) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_IS_UTP(port); -+ -+ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), reg, pData)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_backpressureEnable_set -+ * Description: -+ * Set the half duplex back-pressure enable status of the specific port. -+ * Input: -+ * port - port id. -+ * enable - Back pressure status. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_ENABLE - Invalid enable input. -+ * Note: -+ * This API can set the half duplex back-pressure enable status of the specific port. -+ * The half duplex back-pressure enable status of the port is as following: -+ * - DISABLE(Defer) -+ * - ENABLE (Back-pressure) -+ */ -+rtk_api_ret_t rtk_port_backpressureEnable_set(rtk_port_t port, rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (port != RTK_WHOLE_SYSTEM) -+ return RT_ERR_PORT_ID; -+ -+ if (enable >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicPortJamMode(!enable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_backpressureEnable_get -+ * Description: -+ * Get the half duplex back-pressure enable status of the specific port. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pEnable - Back pressure status. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * This API can get the half duplex back-pressure enable status of the specific port. -+ * The half duplex back-pressure enable status of the port is as following: -+ * - DISABLE(Defer) -+ * - ENABLE (Back-pressure) -+ */ -+rtk_api_ret_t rtk_port_backpressureEnable_get(rtk_port_t port, rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 regData; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (port != RTK_WHOLE_SYSTEM) -+ return RT_ERR_PORT_ID; -+ -+ if(NULL == pEnable) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicPortJamMode(®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ *pEnable = !regData; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_adminEnable_set -+ * Description: -+ * Set port admin configuration of the specific port. -+ * Input: -+ * port - port id. -+ * enable - Back pressure status. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_ENABLE - Invalid enable input. -+ * Note: -+ * This API can set port admin configuration of the specific port. -+ * The port admin configuration of the port is as following: -+ * - DISABLE -+ * - ENABLE -+ */ -+rtk_api_ret_t rtk_port_adminEnable_set(rtk_port_t port, rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 data; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_IS_UTP(port); -+ -+ if (enable >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtk_port_phyReg_get(port, PHY_CONTROL_REG, &data)) != RT_ERR_OK) -+ return retVal; -+ -+ if (ENABLED == enable) -+ { -+ data &= 0xF7FF; -+ data |= 0x0200; -+ } -+ else if (DISABLED == enable) -+ { -+ data |= 0x0800; -+ } -+ -+ if ((retVal = rtk_port_phyReg_set(port, PHY_CONTROL_REG, data)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_adminEnable_get -+ * Description: -+ * Get port admin configuration of the specific port. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pEnable - Back pressure status. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * This API can get port admin configuration of the specific port. -+ * The port admin configuration of the port is as following: -+ * - DISABLE -+ * - ENABLE -+ */ -+rtk_api_ret_t rtk_port_adminEnable_get(rtk_port_t port, rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 data; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_IS_UTP(port); -+ -+ if(NULL == pEnable) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtk_port_phyReg_get(port, PHY_CONTROL_REG, &data)) != RT_ERR_OK) -+ return retVal; -+ -+ if ( (data & 0x0800) == 0x0800) -+ { -+ *pEnable = DISABLED; -+ } -+ else -+ { -+ *pEnable = ENABLED; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_isolation_set -+ * Description: -+ * Set permitted port isolation portmask -+ * Input: -+ * port - port id. -+ * pPortmask - Permit port mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_PORT_MASK - Invalid portmask. -+ * Note: -+ * This API set the port mask that a port can transmit packet to of each port -+ * A port can only transmit packet to ports included in permitted portmask -+ */ -+rtk_api_ret_t rtk_port_isolation_set(rtk_port_t port, rtk_portmask_t *pPortmask) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pmask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(NULL == pPortmask) -+ return RT_ERR_NULL_POINTER; -+ -+ /* check port mask */ -+ RTK_CHK_PORTMASK_VALID(pPortmask); -+ -+ if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicPortIsolationPermittedPortmask(rtk_switch_port_L2P_get(port), pmask)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_isolation_get -+ * Description: -+ * Get permitted port isolation portmask -+ * Input: -+ * port - Port id. -+ * Output: -+ * pPortmask - Permit port mask -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * This API get the port mask that a port can transmit packet to of each port -+ * A port can only transmit packet to ports included in permitted portmask -+ */ -+rtk_api_ret_t rtk_port_isolation_get(rtk_port_t port, rtk_portmask_t *pPortmask) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pmask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(NULL == pPortmask) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicPortIsolationPermittedPortmask(rtk_switch_port_L2P_get(port), &pmask)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_rgmiiDelayExt_set -+ * Description: -+ * Set RGMII interface delay value for TX and RX. -+ * Input: -+ * txDelay - TX delay value, 1 for delay 2ns and 0 for no-delay -+ * rxDelay - RX delay value, 0~7 for delay setup. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can set external interface 2 RGMII delay. -+ * In TX delay, there are 2 selection: no-delay and 2ns delay. -+ * In RX delay, there are 8 steps for delay tuning. 0 for no-delay, and 7 for maximum delay. -+ */ -+rtk_api_ret_t rtk_port_rgmiiDelayExt_set(rtk_port_t port, rtk_data_t txDelay, rtk_data_t rxDelay) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 regAddr, regData; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_IS_EXT(port); -+ -+ if ((txDelay > 1) || (rxDelay > 7)) -+ return RT_ERR_INPUT; -+ -+ if(port == EXT_PORT0) -+ regAddr = RTL8367C_REG_EXT1_RGMXF; -+ else if(port == EXT_PORT1) -+ regAddr = RTL8367C_REG_EXT2_RGMXF; -+ else -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_getAsicReg(regAddr, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ regData = (regData & 0xFFF0) | ((txDelay << 3) & 0x0008) | (rxDelay & 0x0007); -+ -+ if ((retVal = rtl8367c_setAsicReg(regAddr, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_rgmiiDelayExt_get -+ * Description: -+ * Get RGMII interface delay value for TX and RX. -+ * Input: -+ * None -+ * Output: -+ * pTxDelay - TX delay value -+ * pRxDelay - RX delay value -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can set external interface 2 RGMII delay. -+ * In TX delay, there are 2 selection: no-delay and 2ns delay. -+ * In RX delay, there are 8 steps for delay tuning. 0 for n0-delay, and 7 for maximum delay. -+ */ -+rtk_api_ret_t rtk_port_rgmiiDelayExt_get(rtk_port_t port, rtk_data_t *pTxDelay, rtk_data_t *pRxDelay) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 regAddr, regData; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_IS_EXT(port); -+ -+ if( (NULL == pTxDelay) || (NULL == pRxDelay) ) -+ return RT_ERR_NULL_POINTER; -+ -+ if(port == EXT_PORT0) -+ regAddr = RTL8367C_REG_EXT1_RGMXF; -+ else if(port == EXT_PORT1) -+ regAddr = RTL8367C_REG_EXT2_RGMXF; -+ else -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_getAsicReg(regAddr, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ *pTxDelay = (regData & 0x0008) >> 3; -+ *pRxDelay = regData & 0x0007; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_phyEnableAll_set -+ * Description: -+ * Set all PHY enable status. -+ * Input: -+ * enable - PHY Enable State. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_ENABLE - Invalid enable input. -+ * Note: -+ * This API can set all PHY status. -+ * The configuration of all PHY is as following: -+ * - DISABLE -+ * - ENABLE -+ */ -+rtk_api_ret_t rtk_port_phyEnableAll_set(rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 data; -+ rtk_uint32 port; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (enable >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ if ((retVal = rtl8367c_setAsicPortEnableAll(enable)) != RT_ERR_OK) -+ return retVal; -+ -+ RTK_SCAN_ALL_LOG_PORT(port) -+ { -+ if(rtk_switch_isUtpPort(port) == RT_ERR_OK) -+ { -+ if ((retVal = rtk_port_phyReg_get(port, PHY_CONTROL_REG, &data)) != RT_ERR_OK) -+ return retVal; -+ -+ if (ENABLED == enable) -+ { -+ data &= 0xF7FF; -+ data |= 0x0200; -+ } -+ else -+ { -+ data |= 0x0800; -+ } -+ -+ if ((retVal = rtk_port_phyReg_set(port, PHY_CONTROL_REG, data)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ -+ return RT_ERR_OK; -+ -+} -+ -+/* Function Name: -+ * rtk_port_phyEnableAll_get -+ * Description: -+ * Get all PHY enable status. -+ * Input: -+ * None -+ * Output: -+ * pEnable - PHY Enable State. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * This API can set all PHY status. -+ * The configuration of all PHY is as following: -+ * - DISABLE -+ * - ENABLE -+ */ -+rtk_api_ret_t rtk_port_phyEnableAll_get(rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pEnable) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicPortEnableAll(pEnable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_efid_set -+ * Description: -+ * Set port-based enhanced filtering database -+ * Input: -+ * port - Port id. -+ * efid - Specified enhanced filtering database. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_L2_FID - Invalid fid. -+ * RT_ERR_INPUT - Invalid input parameter. -+ * RT_ERR_PORT_ID - Invalid port ID. -+ * Note: -+ * The API can set port-based enhanced filtering database. -+ */ -+rtk_api_ret_t rtk_port_efid_set(rtk_port_t port, rtk_data_t efid) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ /* efid must be 0~7 */ -+ if (efid > RTK_EFID_MAX) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicPortIsolationEfid(rtk_switch_port_L2P_get(port), efid))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_efid_get -+ * Description: -+ * Get port-based enhanced filtering database -+ * Input: -+ * port - Port id. -+ * Output: -+ * pEfid - Specified enhanced filtering database. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port ID. -+ * Note: -+ * The API can get port-based enhanced filtering database status. -+ */ -+rtk_api_ret_t rtk_port_efid_get(rtk_port_t port, rtk_data_t *pEfid) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(NULL == pEfid) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicPortIsolationEfid(rtk_switch_port_L2P_get(port), pEfid))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_phyComboPortMedia_set -+ * Description: -+ * Set Combo port media type -+ * Input: -+ * port - Port id. -+ * media - Media (COPPER or FIBER) -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port ID. -+ * Note: -+ * The API can Set Combo port media type. -+ */ -+rtk_api_ret_t rtk_port_phyComboPortMedia_set(rtk_port_t port, rtk_port_media_t media) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 regData; -+ rtk_uint32 idx; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_IS_UTP(port); -+ -+ /* Check Combo Port ID */ -+ RTK_CHK_PORT_IS_COMBO(port); -+ -+ if (media >= PORT_MEDIA_END) -+ return RT_ERR_INPUT; -+ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicReg(0x1300, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) -+ return retVal; -+ -+ if(regData != 0x6367) -+ return RT_ERR_CHIP_NOT_SUPPORTED; -+ -+ if(media == PORT_MEDIA_FIBER) -+ { -+ /* software init */ -+ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_CHIP_RESET, RTL8367C_DW8051_RST_OFFSET, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MISCELLANEOUS_CONFIGURE0, RTL8367C_DW8051_EN_OFFSET, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_ACS_IROM_ENABLE_OFFSET, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_IROM_MSB_OFFSET, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ for(idx = 0; idx < FIBER_INIT_SIZE; idx++) -+ { -+ if ((retVal = rtl8367c_setAsicReg(0xE000 + idx, (rtk_uint32)Fiber[idx])) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_IROM_MSB_OFFSET, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_ACS_IROM_ENABLE_OFFSET, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_CHIP_RESET, RTL8367C_DW8051_RST_OFFSET, 0)) != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_UTP_FIB_DET, RTL8367C_UTP_FIRST_OFFSET, 1))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_DW8051_READY_OFFSET, 0)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_phyComboPortMedia_get -+ * Description: -+ * Get Combo port media type -+ * Input: -+ * port - Port id. -+ * Output: -+ * pMedia - Media (COPPER or FIBER) -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port ID. -+ * Note: -+ * The API can Set Combo port media type. -+ */ -+rtk_api_ret_t rtk_port_phyComboPortMedia_get(rtk_port_t port, rtk_port_media_t *pMedia) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 regData; -+ rtk_uint32 data; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_IS_UTP(port); -+ -+ /* Check Combo Port ID */ -+ RTK_CHK_PORT_IS_COMBO(port); -+ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicReg(0x1300, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) -+ return retVal; -+ -+ if(regData != 0x6367) -+ { -+ *pMedia = PORT_MEDIA_COPPER; -+ } -+ else -+ { -+ if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_UTP_FIB_DET, RTL8367C_UTP_FIRST_OFFSET, &data))!=RT_ERR_OK) -+ return retVal; -+ -+ if(data == 1) -+ *pMedia = PORT_MEDIA_COPPER; -+ else -+ *pMedia = PORT_MEDIA_FIBER; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_rtctEnable_set -+ * Description: -+ * Enable RTCT test -+ * Input: -+ * pPortmask - Port mask of RTCT enabled port -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Invalid port mask. -+ * Note: -+ * The API can enable RTCT Test -+ */ -+rtk_api_ret_t rtk_port_rtctEnable_set(rtk_portmask_t *pPortmask) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Mask Valid */ -+ RTK_CHK_PORTMASK_VALID_ONLY_UTP(pPortmask); -+ -+ if ((retVal = rtl8367c_setAsicPortRTCTEnable(pPortmask->bits[0]))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_rtctDisable_set -+ * Description: -+ * Disable RTCT test -+ * Input: -+ * pPortmask - Port mask of RTCT disabled port -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Invalid port mask. -+ * Note: -+ * The API can disable RTCT Test -+ */ -+rtk_api_ret_t rtk_port_rtctDisable_set(rtk_portmask_t *pPortmask) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Mask Valid */ -+ RTK_CHK_PORTMASK_VALID_ONLY_UTP(pPortmask); -+ -+ if ((retVal = rtl8367c_setAsicPortRTCTDisable(pPortmask->bits[0]))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+ -+/* Function Name: -+ * rtk_port_rtctResult_get -+ * Description: -+ * Get the result of RTCT test -+ * Input: -+ * port - Port ID -+ * Output: -+ * pRtctResult - The result of RTCT result -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port ID. -+ * RT_ERR_PHY_RTCT_NOT_FINISH - Testing does not finish. -+ * Note: -+ * The API can get RTCT test result. -+ * RTCT test may takes 4.8 seconds to finish its test at most. -+ * Thus, if this API return RT_ERR_PHY_RTCT_NOT_FINISH or -+ * other error code, the result can not be referenced and -+ * user should call this API again until this API returns -+ * a RT_ERR_OK. -+ * The result is stored at pRtctResult->ge_result -+ * pRtctResult->linkType is unused. -+ * The unit of channel length is 2.5cm. Ex. 300 means 300 * 2.5 = 750cm = 7.5M -+ */ -+rtk_api_ret_t rtk_port_rtctResult_get(rtk_port_t port, rtk_rtctResult_t *pRtctResult) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_port_rtct_result_t result; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_IS_UTP(port); -+ -+ memset(pRtctResult, 0x00, sizeof(rtk_rtctResult_t)); -+ if ((retVal = rtl8367c_getAsicPortRTCTResult(port, &result))!=RT_ERR_OK) -+ return retVal; -+ -+ pRtctResult->result.ge_result.channelALen = result.channelALen; -+ pRtctResult->result.ge_result.channelBLen = result.channelBLen; -+ pRtctResult->result.ge_result.channelCLen = result.channelCLen; -+ pRtctResult->result.ge_result.channelDLen = result.channelDLen; -+ -+ pRtctResult->result.ge_result.channelALinedriver = result.channelALinedriver; -+ pRtctResult->result.ge_result.channelBLinedriver = result.channelBLinedriver; -+ pRtctResult->result.ge_result.channelCLinedriver = result.channelCLinedriver; -+ pRtctResult->result.ge_result.channelDLinedriver = result.channelDLinedriver; -+ -+ pRtctResult->result.ge_result.channelAMismatch = result.channelAMismatch; -+ pRtctResult->result.ge_result.channelBMismatch = result.channelBMismatch; -+ pRtctResult->result.ge_result.channelCMismatch = result.channelCMismatch; -+ pRtctResult->result.ge_result.channelDMismatch = result.channelDMismatch; -+ -+ pRtctResult->result.ge_result.channelAOpen = result.channelAOpen; -+ pRtctResult->result.ge_result.channelBOpen = result.channelBOpen; -+ pRtctResult->result.ge_result.channelCOpen = result.channelCOpen; -+ pRtctResult->result.ge_result.channelDOpen = result.channelDOpen; -+ -+ pRtctResult->result.ge_result.channelAShort = result.channelAShort; -+ pRtctResult->result.ge_result.channelBShort = result.channelBShort; -+ pRtctResult->result.ge_result.channelCShort = result.channelCShort; -+ pRtctResult->result.ge_result.channelDShort = result.channelDShort; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_port_sds_reset -+ * Description: -+ * Reset Serdes -+ * Input: -+ * port - Port ID -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port ID. -+ * Note: -+ * The API can reset Serdes -+ */ -+rtk_api_ret_t rtk_port_sds_reset(rtk_port_t port) -+{ -+ rtk_uint32 ext_id; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ if(rtk_switch_isSgmiiPort(port) != RT_ERR_OK) -+ return RT_ERR_PORT_ID; -+ -+ ext_id = port - 15; -+ return rtl8367c_sdsReset(ext_id); -+} -+ -+/* Function Name: -+ * rtk_port_sgmiiLinkStatus_get -+ * Description: -+ * Get SGMII status -+ * Input: -+ * port - Port ID -+ * Output: -+ * pSignalDetect - Signal detect -+ * pSync - Sync -+ * pLink - Link -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port ID. -+ * Note: -+ * The API can reset Serdes -+ */ -+rtk_api_ret_t rtk_port_sgmiiLinkStatus_get(rtk_port_t port, rtk_data_t *pSignalDetect, rtk_data_t *pSync, rtk_port_linkStatus_t *pLink) -+{ -+ rtk_uint32 ext_id; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ if(rtk_switch_isSgmiiPort(port) != RT_ERR_OK) -+ return RT_ERR_PORT_ID; -+ -+ if(NULL == pSignalDetect) -+ return RT_ERR_NULL_POINTER; -+ -+ if(NULL == pSync) -+ return RT_ERR_NULL_POINTER; -+ -+ if(NULL == pLink) -+ return RT_ERR_NULL_POINTER; -+ -+ ext_id = port - 15; -+ return rtl8367c_getSdsLinkStatus(ext_id, (rtk_uint32 *)pSignalDetect, (rtk_uint32 *)pSync, (rtk_uint32 *)pLink); -+} -+ -+/* Function Name: -+ * rtk_port_sgmiiNway_set -+ * Description: -+ * Configure SGMII/HSGMII port Nway state -+ * Input: -+ * port - Port ID -+ * state - Nway state -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port ID. -+ * Note: -+ * The API configure SGMII/HSGMII port Nway state -+ */ -+rtk_api_ret_t rtk_port_sgmiiNway_set(rtk_port_t port, rtk_enable_t state) -+{ -+ rtk_uint32 ext_id; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ if(rtk_switch_isSgmiiPort(port) != RT_ERR_OK) -+ return RT_ERR_PORT_ID; -+ -+ if(state >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ ext_id = port - 15; -+ return rtl8367c_setSgmiiNway(ext_id, (rtk_uint32)state); -+} -+ -+/* Function Name: -+ * rtk_port_sgmiiNway_get -+ * Description: -+ * Get SGMII/HSGMII port Nway state -+ * Input: -+ * port - Port ID -+ * Output: -+ * pState - Nway state -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port ID. -+ * Note: -+ * The API can get SGMII/HSGMII port Nway state -+ */ -+rtk_api_ret_t rtk_port_sgmiiNway_get(rtk_port_t port, rtk_enable_t *pState) -+{ -+ rtk_uint32 ext_id; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ if(rtk_switch_isSgmiiPort(port) != RT_ERR_OK) -+ return RT_ERR_PORT_ID; -+ -+ if(NULL == pState) -+ return RT_ERR_NULL_POINTER; -+ -+ ext_id = port - 15; -+ return rtl8367c_getSgmiiNway(ext_id, (rtk_uint32 *)pState); -+} -diff --git a/drivers/net/phy/rtk/rtl8367c/ptp.c b/drivers/net/phy/rtk/rtl8367c/ptp.c -new file mode 100644 -index 000000000000..af8ce30912dc ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/ptp.c -@@ -0,0 +1,759 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 39583 $ -+ * $Date: 2013-05-20 16:59:23 +0800 (星期一, 20 五月 2013) $ -+ * -+ * Purpose : RTK switch high-level API for RTL8367/RTL8367C -+ * Feature : Here is a list of all functions and variables in time module. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+/* Function Name: -+ * rtk_ptp_init -+ * Description: -+ * PTP function initialization. -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * This API is used to initialize PTP status. -+ */ -+rtk_api_ret_t rtk_ptp_init(void) -+{ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_ptp_mac_set -+ * Description: -+ * Configure PTP mac address. -+ * Input: -+ * mac - mac address to parser PTP packets. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter. -+ * Note: -+ * None -+ */ -+rtk_api_ret_t rtk_ptp_mac_set(rtk_mac_t mac) -+{ -+ rtk_api_ret_t retVal; -+ ether_addr_t sw_mac; -+ -+ memcpy(sw_mac.octet, mac.octet, ETHER_ADDR_LEN); -+ -+ if((retVal=rtl8367c_setAsicEavMacAddress(sw_mac))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_ptp_mac_get -+ * Description: -+ * Get PTP mac address. -+ * Input: -+ * None -+ * Output: -+ * pMac - mac address to parser PTP packets. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter. -+ * Note: -+ * None -+ */ -+rtk_api_ret_t rtk_ptp_mac_get(rtk_mac_t *pMac) -+{ -+ rtk_api_ret_t retVal; -+ ether_addr_t sw_mac; -+ -+ if((retVal=rtl8367c_getAsicEavMacAddress(&sw_mac))!=RT_ERR_OK) -+ return retVal; -+ -+ memcpy(pMac->octet, sw_mac.octet, ETHER_ADDR_LEN); -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_ptp_tpid_set -+ * Description: -+ * Configure PTP accepted outer & inner tag TPID. -+ * Input: -+ * outerId - Ether type of S-tag frame parsing in PTP ports. -+ * innerId - Ether type of C-tag frame parsing in PTP ports. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter. -+ * Note: -+ * None -+ */ -+rtk_api_ret_t rtk_ptp_tpid_set(rtk_ptp_tpid_t outerId, rtk_ptp_tpid_t innerId) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if ((outerId>RTK_MAX_NUM_OF_TPID) ||(innerId>RTK_MAX_NUM_OF_TPID)) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicEavTpid(outerId, innerId)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_ptp_tpid_get -+ * Description: -+ * Get PTP accepted outer & inner tag TPID. -+ * Input: -+ * None -+ * Output: -+ * pOuterId - Ether type of S-tag frame parsing in PTP ports. -+ * pInnerId - Ether type of C-tag frame parsing in PTP ports. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+rtk_api_ret_t rtk_ptp_tpid_get(rtk_ptp_tpid_t *pOuterId, rtk_ptp_tpid_t *pInnerId) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if ((retVal = rtl8367c_getAsicEavTpid(pOuterId, pInnerId)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_ptp_refTime_set -+ * Description: -+ * Set the reference time of the specified device. -+ * Input: -+ * timeStamp - reference timestamp value -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_INPUT - invalid input parameter -+ * Applicable: -+ * 8390, 8380 -+ * Note: -+ * None -+ */ -+rtk_api_ret_t rtk_ptp_refTime_set(rtk_ptp_timeStamp_t timeStamp) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (timeStamp.nsec > RTK_MAX_NUM_OF_NANO_SECOND) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicEavSysTime(timeStamp.sec, timeStamp.nsec))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_ptp_refTime_get -+ * Description: -+ * Get the reference time of the specified device. -+ * Input: -+ * Output: -+ * pTimeStamp - pointer buffer of the reference time -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_UNIT_ID - invalid unit id -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ * Applicable: -+ * 8390, 8380 -+ * Note: -+ * None -+ */ -+rtk_api_ret_t rtk_ptp_refTime_get(rtk_ptp_timeStamp_t *pTimeStamp) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if ((retVal = rtl8367c_getAsicEavSysTime(&pTimeStamp->sec, &pTimeStamp->nsec))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_ptp_refTimeAdjust_set -+ * Description: -+ * Adjust the reference time. -+ * Input: -+ * unit - unit id -+ * sign - significant -+ * timeStamp - reference timestamp value -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_UNIT_ID - invalid unit id -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_INPUT - invalid input parameter -+ * Note: -+ * sign=0 for positive adjustment, sign=1 for negative adjustment. -+ */ -+rtk_api_ret_t rtk_ptp_refTimeAdjust_set(rtk_ptp_sys_adjust_t sign, rtk_ptp_timeStamp_t timeStamp) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (timeStamp.nsec > RTK_MAX_NUM_OF_NANO_SECOND) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicEavSysTimeAdjust(sign, timeStamp.sec, timeStamp.nsec))!=RT_ERR_OK) -+ return retVal; -+ -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_ptp_refTimeEnable_set -+ * Description: -+ * Set the enable state of reference time of the specified device. -+ * Input: -+ * enable - status -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_INPUT - invalid input parameter -+ * Note: -+ * None -+ */ -+rtk_api_ret_t rtk_ptp_refTimeEnable_set(rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (enable >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ if ((retVal = rtl8367c_setAsicEavSysTimeCtrl(enable))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_ptp_refTimeEnable_get -+ * Description: -+ * Get the enable state of reference time of the specified device. -+ * Input: -+ * Output: -+ * pEnable - status -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_UNIT_ID - invalid unit id -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ * Applicable: -+ * 8390, 8380 -+ * Note: -+ * None -+ */ -+rtk_api_ret_t rtk_ptp_refTimeEnable_get(rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if ((retVal = rtl8367c_getAsicEavSysTimeCtrl(pEnable))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_ptp_portEnable_set -+ * Description: -+ * Set PTP status of the specified port. -+ * Input: -+ * port - port id -+ * enable - status -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_PORT - invalid port id -+ * RT_ERR_INPUT - invalid input parameter -+ * Note: -+ * None -+ */ -+rtk_api_ret_t rtk_ptp_portEnable_set(rtk_port_t port, rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check port is PTP port */ -+ RTK_CHK_PORT_IS_PTP(port); -+ -+ if (enable>=RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicEavPortEnable(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_ptp_portEnable_get -+ * Description: -+ * Get PTP status of the specified port. -+ * Input: -+ * port - port id -+ * Output: -+ * pEnable - status -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_PORT - invalid port id -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ * Note: -+ * None -+ */ -+rtk_api_ret_t rtk_ptp_portEnable_get(rtk_port_t port, rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check port is PTP port */ -+ RTK_CHK_PORT_IS_PTP(port); -+ -+ if ((retVal = rtl8367c_getAsicEavPortEnable(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+ -+/* Function Name: -+ * rtk_ptp_portTimestamp_get -+ * Description: -+ * Get PTP timestamp according to the PTP identifier on the dedicated port from the specified device. -+ * Input: -+ * unit - unit id -+ * port - port id -+ * type - PTP message type -+ * Output: -+ * pInfo - pointer buffer of sequence ID and timestamp -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_PORT_ID - invalid port id -+ * RT_ERR_INPUT - invalid input parameter -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ * Applicable: -+ * 8390, 8380 -+ * Note: -+ * None -+ */ -+rtk_api_ret_t rtk_ptp_portTimestamp_get( rtk_port_t port, rtk_ptp_msgType_t type, rtk_ptp_info_t *pInfo) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_ptp_time_stamp_t time; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check port is PTP port */ -+ RTK_CHK_PORT_IS_PTP(port); -+ -+ if ((retVal = rtl8367c_getAsicEavPortTimeStamp(rtk_switch_port_L2P_get(port), type, &time)) != RT_ERR_OK) -+ return retVal; -+ -+ pInfo->sequenceId = time.sequence_id; -+ pInfo->timeStamp.sec = time.second; -+ pInfo->timeStamp.nsec = time.nano_second; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_ptp_intControl_set -+ * Description: -+ * Set PTP interrupt trigger status configuration. -+ * Input: -+ * type - Interrupt type. -+ * enable - Interrupt status. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_ENABLE - Invalid enable input. -+ * Note: -+ * The API can set PTP interrupt status configuration. -+ * The interrupt trigger status is shown in the following: -+ * PTP_INT_TYPE_TX_SYNC = 0, -+ * PTP_INT_TYPE_TX_DELAY_REQ, -+ * PTP_INT_TYPE_TX_PDELAY_REQ, -+ * PTP_INT_TYPE_TX_PDELAY_RESP, -+ * PTP_INT_TYPE_RX_SYNC, -+ * PTP_INT_TYPE_RX_DELAY_REQ, -+ * PTP_INT_TYPE_RX_PDELAY_REQ, -+ * PTP_INT_TYPE_RX_PDELAY_RESP, -+ * PTP_INT_TYPE_ALL, -+ */ -+rtk_api_ret_t rtk_ptp_intControl_set(rtk_ptp_intType_t type, rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 mask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (type>=PTP_INT_TYPE_END) -+ return RT_ERR_INPUT; -+ -+ if (PTP_INT_TYPE_ALL!=type) -+ { -+ if ((retVal = rtl8367c_getAsicEavInterruptMask(&mask)) != RT_ERR_OK) -+ return retVal; -+ -+ if (ENABLED == enable) -+ mask = mask | (1<=PTP_INT_TYPE_ALL) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_getAsicEavInterruptMask(&mask)) != RT_ERR_OK) -+ return retVal; -+ -+ if (0 == (mask&(1<=RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicEavTrap(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_ptp_portPtpEnable_get -+ * Description: -+ * Get PTP packet trap of the specified port. -+ * Input: -+ * port - port id -+ * Output: -+ * pEnable - status -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_PORT - invalid port id -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ * Note: -+ * None -+ */ -+rtk_api_ret_t rtk_ptp_portTrap_get(rtk_port_t port, rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if ((retVal = rtl8367c_getAsicEavTrap(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/qos.c b/drivers/net/phy/rtk/rtl8367c/qos.c -new file mode 100644 -index 000000000000..9bcb49cfbd64 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/qos.c -@@ -0,0 +1,1452 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTK switch high-level API for RTL8367/RTL8367C -+ * Feature : Here is a list of all functions and variables in QoS module. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+/* Function Name: -+ * rtk_qos_init -+ * Description: -+ * Configure QoS default settings with queue number assignment to each port. -+ * Input: -+ * queueNum - Queue number of each port. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QUEUE_NUM - Invalid queue number. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API will initialize related QoS setting with queue number assignment. -+ * The queue number is from 1 to 8. -+ */ -+rtk_api_ret_t rtk_qos_init(rtk_queue_num_t queueNum) -+{ -+ CONST_T rtk_uint16 g_prioritytToQid[8][8]= { -+ {0, 0,0,0,0,0,0,0}, -+ {0, 0,0,0,7,7,7,7}, -+ {0, 0,0,0,1,1,7,7}, -+ {0, 0,1,1,2,2,7,7}, -+ {0, 0,1,1,2,3,7,7}, -+ {0, 0,1,2,3,4,7,7}, -+ {0, 0,1,2,3,4,5,7}, -+ {0,1,2,3,4,5,6,7} -+ }; -+ -+ CONST_T rtk_uint32 g_priorityDecision[8] = {0x01, 0x80,0x04,0x02,0x20,0x40,0x10,0x08}; -+ CONST_T rtk_uint32 g_prioritytRemap[8] = {0,1,2,3,4,5,6,7}; -+ -+ rtk_api_ret_t retVal; -+ rtk_uint32 qmapidx; -+ rtk_uint32 priority; -+ rtk_uint32 priDec; -+ rtk_uint32 port; -+ rtk_uint32 dscp; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (queueNum <= 0 || queueNum > RTK_MAX_NUM_OF_QUEUE) -+ return RT_ERR_QUEUE_NUM; -+ -+ /*Set Output Queue Number*/ -+ if (RTK_MAX_NUM_OF_QUEUE == queueNum) -+ qmapidx = 0; -+ else -+ qmapidx = queueNum; -+ -+ RTK_SCAN_ALL_PHY_PORTMASK(port) -+ { -+ if ((retVal = rtl8367c_setAsicOutputQueueMappingIndex(port, qmapidx)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ /*Set Priority to Qid*/ -+ for (priority = 0; priority <= RTK_PRIMAX; priority++) -+ { -+ if ((retVal = rtl8367c_setAsicPriorityToQIDMappingTable(queueNum - 1, priority, g_prioritytToQid[queueNum - 1][priority])) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ /*Set Flow Control Type to Ingress Flow Control*/ -+ if ((retVal = rtl8367c_setAsicFlowControlSelect(FC_INGRESS)) != RT_ERR_OK) -+ return retVal; -+ -+ -+ /*Priority Decision Order*/ -+ for (priDec = 0;priDec < PRIDEC_END;priDec++) -+ { -+ if ((retVal = rtl8367c_setAsicPriorityDecision(PRIDECTBL_IDX0, priDec, g_priorityDecision[priDec])) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicPriorityDecision(PRIDECTBL_IDX1, priDec, g_priorityDecision[priDec])) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ /*Set Port-based Priority to 0*/ -+ RTK_SCAN_ALL_PHY_PORTMASK(port) -+ { -+ if ((retVal = rtl8367c_setAsicPriorityPortBased(port, 0)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ /*Disable 1p Remarking*/ -+ RTK_SCAN_ALL_PHY_PORTMASK(port) -+ { -+ if ((retVal = rtl8367c_setAsicRemarkingDot1pAbility(port, DISABLED)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ /*Disable DSCP Remarking*/ -+ if ((retVal = rtl8367c_setAsicRemarkingDscpAbility(DISABLED)) != RT_ERR_OK) -+ return retVal; -+ -+ /*Set 1p & DSCP Priority Remapping & Remarking*/ -+ for (priority = 0; priority <= RTL8367C_PRIMAX; priority++) -+ { -+ if ((retVal = rtl8367c_setAsicPriorityDot1qRemapping(priority, g_prioritytRemap[priority])) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRemarkingDot1pParameter(priority, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRemarkingDscpParameter(priority, 0)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ /*Set DSCP Priority*/ -+ for (dscp = 0; dscp <= 63; dscp++) -+ { -+ if ((retVal = rtl8367c_setAsicPriorityDscpBased(dscp, 0)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ /* Fine-tune B/T value */ -+ if((retVal = rtl8367c_setAsicReg(0x1722, 0x1158)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_qos_priSel_set -+ * Description: -+ * Configure the priority order among different priority mechanism. -+ * Input: -+ * index - Priority decision table index (0~1) -+ * pPriDec - Priority assign for port, dscp, 802.1p, cvlan, svlan, acl based priority decision. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_SEL_PRI_SOURCE - Invalid priority decision source parameter. -+ * Note: -+ * ASIC will follow user priority setting of mechanisms to select mapped queue priority for receiving frame. -+ * If two priority mechanisms are the same, the ASIC will chose the highest priority from mechanisms to -+ * assign queue priority to receiving frame. -+ * The priority sources are: -+ * - PRIDEC_PORT -+ * - PRIDEC_ACL -+ * - PRIDEC_DSCP -+ * - PRIDEC_1Q -+ * - PRIDEC_1AD -+ * - PRIDEC_CVLAN -+ * - PRIDEC_DA -+ * - PRIDEC_SA -+ */ -+rtk_api_ret_t rtk_qos_priSel_set(rtk_qos_priDecTbl_t index, rtk_priority_select_t *pPriDec) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 port_pow; -+ rtk_uint32 dot1q_pow; -+ rtk_uint32 dscp_pow; -+ rtk_uint32 acl_pow; -+ rtk_uint32 svlan_pow; -+ rtk_uint32 cvlan_pow; -+ rtk_uint32 smac_pow; -+ rtk_uint32 dmac_pow; -+ rtk_uint32 i; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (index < 0 || index >= PRIDECTBL_END) -+ return RT_ERR_ENTRY_INDEX; -+ -+ if (pPriDec->port_pri >= 8 || pPriDec->dot1q_pri >= 8 || pPriDec->acl_pri >= 8 || pPriDec->dscp_pri >= 8 || -+ pPriDec->cvlan_pri >= 8 || pPriDec->svlan_pri >= 8 || pPriDec->dmac_pri >= 8 || pPriDec->smac_pri >= 8) -+ return RT_ERR_QOS_SEL_PRI_SOURCE; -+ -+ port_pow = 1; -+ for (i = pPriDec->port_pri; i > 0; i--) -+ port_pow = (port_pow)*2; -+ -+ dot1q_pow = 1; -+ for (i = pPriDec->dot1q_pri; i > 0; i--) -+ dot1q_pow = (dot1q_pow)*2; -+ -+ acl_pow = 1; -+ for (i = pPriDec->acl_pri; i > 0; i--) -+ acl_pow = (acl_pow)*2; -+ -+ dscp_pow = 1; -+ for (i = pPriDec->dscp_pri; i > 0; i--) -+ dscp_pow = (dscp_pow)*2; -+ -+ svlan_pow = 1; -+ for (i = pPriDec->svlan_pri; i > 0; i--) -+ svlan_pow = (svlan_pow)*2; -+ -+ cvlan_pow = 1; -+ for (i = pPriDec->cvlan_pri; i > 0; i--) -+ cvlan_pow = (cvlan_pow)*2; -+ -+ dmac_pow = 1; -+ for (i = pPriDec->dmac_pri; i > 0; i--) -+ dmac_pow = (dmac_pow)*2; -+ -+ smac_pow = 1; -+ for (i = pPriDec->smac_pri; i > 0; i--) -+ smac_pow = (smac_pow)*2; -+ -+ if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_PORT, port_pow)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_ACL, acl_pow)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_DSCP, dscp_pow)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_1Q, dot1q_pow)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_1AD, svlan_pow)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_CVLAN, cvlan_pow)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_DA, dmac_pow)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_SA, smac_pow)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_qos_priSel_get -+ * Description: -+ * Get the priority order configuration among different priority mechanism. -+ * Input: -+ * index - Priority decision table index (0~1) -+ * Output: -+ * pPriDec - Priority assign for port, dscp, 802.1p, cvlan, svlan, acl based priority decision . -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * ASIC will follow user priority setting of mechanisms to select mapped queue priority for receiving frame. -+ * If two priority mechanisms are the same, the ASIC will chose the highest priority from mechanisms to -+ * assign queue priority to receiving frame. -+ * The priority sources are: -+ * - PRIDEC_PORT, -+ * - PRIDEC_ACL, -+ * - PRIDEC_DSCP, -+ * - PRIDEC_1Q, -+ * - PRIDEC_1AD, -+ * - PRIDEC_CVLAN, -+ * - PRIDEC_DA, -+ * - PRIDEC_SA, -+ */ -+rtk_api_ret_t rtk_qos_priSel_get(rtk_qos_priDecTbl_t index, rtk_priority_select_t *pPriDec) -+{ -+ -+ rtk_api_ret_t retVal; -+ rtk_int32 i; -+ rtk_uint32 port_pow; -+ rtk_uint32 dot1q_pow; -+ rtk_uint32 dscp_pow; -+ rtk_uint32 acl_pow; -+ rtk_uint32 svlan_pow; -+ rtk_uint32 cvlan_pow; -+ rtk_uint32 smac_pow; -+ rtk_uint32 dmac_pow; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (index < 0 || index >= PRIDECTBL_END) -+ return RT_ERR_ENTRY_INDEX; -+ -+ if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_PORT, &port_pow)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_ACL, &acl_pow)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_DSCP, &dscp_pow)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_1Q, &dot1q_pow)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_1AD, &svlan_pow)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_CVLAN, &cvlan_pow)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_DA, &dmac_pow)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_SA, &smac_pow)) != RT_ERR_OK) -+ return retVal; -+ -+ for (i = 31; i >= 0; i--) -+ { -+ if (port_pow & (1 << i)) -+ { -+ pPriDec->port_pri = i; -+ break; -+ } -+ } -+ -+ for (i = 31; i >= 0; i--) -+ { -+ if (dot1q_pow & (1 << i)) -+ { -+ pPriDec->dot1q_pri = i; -+ break; -+ } -+ } -+ -+ for (i = 31; i >= 0; i--) -+ { -+ if (acl_pow & (1 << i)) -+ { -+ pPriDec->acl_pri = i; -+ break; -+ } -+ } -+ -+ for (i = 31; i >= 0; i--) -+ { -+ if (dscp_pow & (1 << i)) -+ { -+ pPriDec->dscp_pri = i; -+ break; -+ } -+ } -+ -+ for (i = 31; i >= 0; i--) -+ { -+ if (svlan_pow & (1 << i)) -+ { -+ pPriDec->svlan_pri = i; -+ break; -+ } -+ } -+ -+ for (i = 31;i >= 0; i--) -+ { -+ if (cvlan_pow & (1 << i)) -+ { -+ pPriDec->cvlan_pri = i; -+ break; -+ } -+ } -+ -+ for (i = 31; i >= 0; i--) -+ { -+ if (dmac_pow&(1<dmac_pri = i; -+ break; -+ } -+ } -+ -+ for (i = 31; i >= 0; i--) -+ { -+ if (smac_pow & (1 << i)) -+ { -+ pPriDec->smac_pri = i; -+ break; -+ } -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_qos_1pPriRemap_set -+ * Description: -+ * Configure 1Q priorities mapping to internal absolute priority. -+ * Input: -+ * dot1p_pri - 802.1p priority value. -+ * int_pri - internal priority value. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_VLAN_PRIORITY - Invalid 1p priority. -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority. -+ * Note: -+ * Priority of 802.1Q assignment for internal asic priority, and it is used for queue usage and packet scheduling. -+ */ -+rtk_api_ret_t rtk_qos_1pPriRemap_set(rtk_pri_t dot1p_pri, rtk_pri_t int_pri) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (dot1p_pri > RTL8367C_PRIMAX || int_pri > RTL8367C_PRIMAX) -+ return RT_ERR_VLAN_PRIORITY; -+ -+ if ((retVal = rtl8367c_setAsicPriorityDot1qRemapping(dot1p_pri, int_pri)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_qos_1pPriRemap_get -+ * Description: -+ * Get 1Q priorities mapping to internal absolute priority. -+ * Input: -+ * dot1p_pri - 802.1p priority value . -+ * Output: -+ * pInt_pri - internal priority value. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_VLAN_PRIORITY - Invalid priority. -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority. -+ * Note: -+ * Priority of 802.1Q assignment for internal asic priority, and it is used for queue usage and packet scheduling. -+ */ -+rtk_api_ret_t rtk_qos_1pPriRemap_get(rtk_pri_t dot1p_pri, rtk_pri_t *pInt_pri) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (dot1p_pri > RTL8367C_PRIMAX) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ if ((retVal = rtl8367c_getAsicPriorityDot1qRemapping(dot1p_pri, pInt_pri)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_qos_dscpPriRemap_set -+ * Description: -+ * Map dscp value to internal priority. -+ * Input: -+ * dscp - Dscp value of receiving frame -+ * int_pri - internal priority value . -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value. -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority. -+ * Note: -+ * The Differentiated Service Code Point is a selector for router's per-hop behaviors. As a selector, there is no implication that a numerically -+ * greater DSCP implies a better network service. As can be seen, the DSCP totally overlaps the old precedence field of TOS. So if values of -+ * DSCP are carefully chosen then backward compatibility can be achieved. -+ */ -+rtk_api_ret_t rtk_qos_dscpPriRemap_set(rtk_dscp_t dscp, rtk_pri_t int_pri) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (int_pri > RTL8367C_PRIMAX ) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ if (dscp > RTL8367C_DSCPMAX) -+ return RT_ERR_QOS_DSCP_VALUE; -+ -+ if ((retVal = rtl8367c_setAsicPriorityDscpBased(dscp, int_pri)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_qos_dscpPriRemap_get -+ * Description: -+ * Get dscp value to internal priority. -+ * Input: -+ * dscp - Dscp value of receiving frame -+ * Output: -+ * pInt_pri - internal priority value. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value. -+ * Note: -+ * The Differentiated Service Code Point is a selector for router's per-hop behaviors. As a selector, there is no implication that a numerically -+ * greater DSCP implies a better network service. As can be seen, the DSCP totally overlaps the old precedence field of TOS. So if values of -+ * DSCP are carefully chosen then backward compatibility can be achieved. -+ */ -+rtk_api_ret_t rtk_qos_dscpPriRemap_get(rtk_dscp_t dscp, rtk_pri_t *pInt_pri) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (dscp > RTL8367C_DSCPMAX) -+ return RT_ERR_QOS_DSCP_VALUE; -+ -+ if ((retVal = rtl8367c_getAsicPriorityDscpBased(dscp, pInt_pri)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_qos_portPri_set -+ * Description: -+ * Configure priority usage to each port. -+ * Input: -+ * port - Port id. -+ * int_pri - internal priority value. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_QOS_SEL_PORT_PRI - Invalid port priority. -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority. -+ * Note: -+ * The API can set priority of port assignments for queue usage and packet scheduling. -+ */ -+rtk_api_ret_t rtk_qos_portPri_set(rtk_port_t port, rtk_pri_t int_pri) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (int_pri > RTL8367C_PRIMAX ) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ if ((retVal = rtl8367c_setAsicPriorityPortBased(rtk_switch_port_L2P_get(port), int_pri)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_qos_portPri_get -+ * Description: -+ * Get priority usage to each port. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pInt_pri - internal priority value. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can get priority of port assignments for queue usage and packet scheduling. -+ */ -+rtk_api_ret_t rtk_qos_portPri_get(rtk_port_t port, rtk_pri_t *pInt_pri) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if ((retVal = rtl8367c_getAsicPriorityPortBased(rtk_switch_port_L2P_get(port), pInt_pri)) != RT_ERR_OK) -+ return retVal; -+ -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_qos_queueNum_set -+ * Description: -+ * Set output queue number for each port. -+ * Input: -+ * port - Port id. -+ * index - Mapping queue number (1~8) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_QUEUE_NUM - Invalid queue number. -+ * Note: -+ * The API can set the output queue number of the specified port. The queue number is from 1 to 8. -+ */ -+rtk_api_ret_t rtk_qos_queueNum_set(rtk_port_t port, rtk_queue_num_t queue_num) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if ((0 == queue_num) || (queue_num > RTK_MAX_NUM_OF_QUEUE)) -+ return RT_ERR_FAILED; -+ -+ if (RTK_MAX_NUM_OF_QUEUE == queue_num) -+ queue_num = 0; -+ -+ if ((retVal = rtl8367c_setAsicOutputQueueMappingIndex(rtk_switch_port_L2P_get(port), queue_num)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_qos_queueNum_get -+ * Description: -+ * Get output queue number. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pQueue_num - Mapping queue number -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API will return the output queue number of the specified port. The queue number is from 1 to 8. -+ */ -+rtk_api_ret_t rtk_qos_queueNum_get(rtk_port_t port, rtk_queue_num_t *pQueue_num) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 qidx; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if ((retVal = rtl8367c_getAsicOutputQueueMappingIndex(rtk_switch_port_L2P_get(port), &qidx)) != RT_ERR_OK) -+ return retVal; -+ -+ if (0 == qidx) -+ *pQueue_num = 8; -+ else -+ *pQueue_num = qidx; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_qos_priMap_set -+ * Description: -+ * Set output queue number for each port. -+ * Input: -+ * queue_num - Queue number usage. -+ * pPri2qid - Priority mapping to queue ID. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_QUEUE_NUM - Invalid queue number. -+ * RT_ERR_QUEUE_ID - Invalid queue id. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority. -+ * Note: -+ * ASIC supports priority mapping to queue with different queue number from 1 to 8. -+ * For different queue numbers usage, ASIC supports different internal available queue IDs. -+ */ -+rtk_api_ret_t rtk_qos_priMap_set(rtk_queue_num_t queue_num, rtk_qos_pri2queue_t *pPri2qid) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pri; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if ((0 == queue_num) || (queue_num > RTK_MAX_NUM_OF_QUEUE)) -+ return RT_ERR_QUEUE_NUM; -+ -+ for (pri = 0; pri <= RTK_PRIMAX; pri++) -+ { -+ if (pPri2qid->pri2queue[pri] > RTK_QIDMAX) -+ return RT_ERR_QUEUE_ID; -+ -+ if ((retVal = rtl8367c_setAsicPriorityToQIDMappingTable(queue_num - 1, pri, pPri2qid->pri2queue[pri])) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_qos_priMap_get -+ * Description: -+ * Get priority to queue ID mapping table parameters. -+ * Input: -+ * queue_num - Queue number usage. -+ * Output: -+ * pPri2qid - Priority mapping to queue ID. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_QUEUE_NUM - Invalid queue number. -+ * Note: -+ * The API can return the mapping queue id of the specified priority and queue number. -+ * The queue number is from 1 to 8. -+ */ -+rtk_api_ret_t rtk_qos_priMap_get(rtk_queue_num_t queue_num, rtk_qos_pri2queue_t *pPri2qid) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pri; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if ((0 == queue_num) || (queue_num > RTK_MAX_NUM_OF_QUEUE)) -+ return RT_ERR_QUEUE_NUM; -+ -+ for (pri = 0; pri <= RTK_PRIMAX; pri++) -+ { -+ if ((retVal = rtl8367c_getAsicPriorityToQIDMappingTable(queue_num-1, pri, &pPri2qid->pri2queue[pri])) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_qos_schedulingQueue_set -+ * Description: -+ * Set weight and type of queues in dedicated port. -+ * Input: -+ * port - Port id. -+ * pQweights - The array of weights for WRR/WFQ queue (0 for STRICT_PRIORITY queue). -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_QOS_QUEUE_WEIGHT - Invalid queue weight. -+ * Note: -+ * The API can set weight and type, strict priority or weight fair queue (WFQ) for -+ * dedicated port for using queues. If queue id is not included in queue usage, -+ * then its type and weight setting in dummy for setting. There are priorities -+ * as queue id in strict queues. It means strict queue id 5 carrying higher priority -+ * than strict queue id 4. The WFQ queue weight is from 1 to 127, and weight 0 is -+ * for strict priority queue type. -+ */ -+rtk_api_ret_t rtk_qos_schedulingQueue_set(rtk_port_t port, rtk_qos_queue_weights_t *pQweights) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 qid; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ for (qid = 0; qid < RTL8367C_QUEUENO; qid ++) -+ { -+ -+ if (pQweights->weights[qid] > QOS_WEIGHT_MAX) -+ return RT_ERR_QOS_QUEUE_WEIGHT; -+ -+ if (0 == pQweights->weights[qid]) -+ { -+ if ((retVal = rtl8367c_setAsicQueueType(rtk_switch_port_L2P_get(port), qid, QTYPE_STRICT)) != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ if ((retVal = rtl8367c_setAsicQueueType(rtk_switch_port_L2P_get(port), qid, QTYPE_WFQ)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicWFQWeight(rtk_switch_port_L2P_get(port),qid, pQweights->weights[qid])) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_qos_schedulingQueue_get -+ * Description: -+ * Get weight and type of queues in dedicated port. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pQweights - The array of weights for WRR/WFQ queue (0 for STRICT_PRIORITY queue). -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get weight and type, strict priority or weight fair queue (WFQ) for dedicated port for using queues. -+ * The WFQ queue weight is from 1 to 127, and weight 0 is for strict priority queue type. -+ */ -+rtk_api_ret_t rtk_qos_schedulingQueue_get(rtk_port_t port, rtk_qos_queue_weights_t *pQweights) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 qid,qtype,qweight; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ for (qid = 0; qid < RTL8367C_QUEUENO; qid++) -+ { -+ if ((retVal = rtl8367c_getAsicQueueType(rtk_switch_port_L2P_get(port), qid, &qtype)) != RT_ERR_OK) -+ return retVal; -+ -+ if (QTYPE_STRICT == qtype) -+ { -+ pQweights->weights[qid] = 0; -+ } -+ else if (QTYPE_WFQ == qtype) -+ { -+ if ((retVal = rtl8367c_getAsicWFQWeight(rtk_switch_port_L2P_get(port), qid, &qweight)) != RT_ERR_OK) -+ return retVal; -+ pQweights->weights[qid] = qweight; -+ } -+ } -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_qos_1pRemarkEnable_set -+ * Description: -+ * Set 1p Remarking state -+ * Input: -+ * port - Port id. -+ * enable - State of per-port 1p Remarking -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_ENABLE - Invalid enable parameter. -+ * Note: -+ * The API can enable or disable 802.1p remarking ability for whole system. -+ * The status of 802.1p remark: -+ * - DISABLED -+ * - ENABLED -+ */ -+rtk_api_ret_t rtk_qos_1pRemarkEnable_set(rtk_port_t port, rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (enable >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicRemarkingDot1pAbility(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_qos_1pRemarkEnable_get -+ * Description: -+ * Get 802.1p remarking ability. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pEnable - Status of 802.1p remark. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get 802.1p remarking ability. -+ * The status of 802.1p remark: -+ * - DISABLED -+ * - ENABLED -+ */ -+rtk_api_ret_t rtk_qos_1pRemarkEnable_get(rtk_port_t port, rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if ((retVal = rtl8367c_getAsicRemarkingDot1pAbility(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_qos_1pRemark_set -+ * Description: -+ * Set 802.1p remarking parameter. -+ * Input: -+ * int_pri - Internal priority value. -+ * dot1p_pri - 802.1p priority value. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_VLAN_PRIORITY - Invalid 1p priority. -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority. -+ * Note: -+ * The API can set 802.1p parameters source priority and new priority. -+ */ -+rtk_api_ret_t rtk_qos_1pRemark_set(rtk_pri_t int_pri, rtk_pri_t dot1p_pri) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (int_pri > RTL8367C_PRIMAX ) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ if (dot1p_pri > RTL8367C_PRIMAX) -+ return RT_ERR_VLAN_PRIORITY; -+ -+ if ((retVal = rtl8367c_setAsicRemarkingDot1pParameter(int_pri, dot1p_pri)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_qos_1pRemark_get -+ * Description: -+ * Get 802.1p remarking parameter. -+ * Input: -+ * int_pri - Internal priority value. -+ * Output: -+ * pDot1p_pri - 802.1p priority value. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority. -+ * Note: -+ * The API can get 802.1p remarking parameters. It would return new priority of ingress priority. -+ */ -+rtk_api_ret_t rtk_qos_1pRemark_get(rtk_pri_t int_pri, rtk_pri_t *pDot1p_pri) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (int_pri > RTL8367C_PRIMAX ) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ if ((retVal = rtl8367c_getAsicRemarkingDot1pParameter(int_pri, pDot1p_pri)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_qos_1pRemarkSrcSel_set -+ * Description: -+ * Set remarking source of 802.1p remarking. -+ * Input: -+ * type - remarking source -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_PORT_ID - invalid port id -+ * RT_ERR_INPUT - invalid input parameter -+ -+ * Note: -+ * The API can configure 802.1p remark functionality to map original 802.1p value or internal -+ * priority to TX DSCP value. -+ */ -+rtk_api_ret_t rtk_qos_1pRemarkSrcSel_set(rtk_qos_1pRmkSrc_t type) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (type >= DOT1P_RMK_SRC_END ) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ if ((retVal = rtl8367c_setAsicRemarkingDot1pSrc(type)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_qos_1pRemarkSrcSel_get -+ * Description: -+ * Get remarking source of 802.1p remarking. -+ * Input: -+ * none -+ * Output: -+ * pType - remarking source -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_PORT_ID - invalid port id -+ * RT_ERR_INPUT - invalid input parameter -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ -+ * Note: -+ * None -+ */ -+rtk_api_ret_t rtk_qos_1pRemarkSrcSel_get(rtk_qos_1pRmkSrc_t *pType) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if ((retVal = rtl8367c_getAsicRemarkingDot1pSrc(pType)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+ -+/* Function Name: -+ * rtk_qos_dscpRemarkEnable_set -+ * Description: -+ * Set DSCP remarking ability. -+ * Input: -+ * port - Port id. -+ * enable - status of DSCP remark. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority. -+ * RT_ERR_ENABLE - Invalid enable parameter. -+ * Note: -+ * The API can enable or disable DSCP remarking ability for whole system. -+ * The status of DSCP remark: -+ * - DISABLED -+ * - ENABLED -+ */ -+rtk_api_ret_t rtk_qos_dscpRemarkEnable_set(rtk_port_t port, rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /*for whole system function, the port value should be 0xFF*/ -+ if (port != RTK_WHOLE_SYSTEM) -+ return RT_ERR_PORT_ID; -+ -+ if (enable >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicRemarkingDscpAbility(enable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_qos_dscpRemarkEnable_get -+ * Description: -+ * Get DSCP remarking ability. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pEnable - status of DSCP remarking. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get DSCP remarking ability. -+ * The status of DSCP remark: -+ * - DISABLED -+ * - ENABLED -+ */ -+rtk_api_ret_t rtk_qos_dscpRemarkEnable_get(rtk_port_t port, rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /*for whole system function, the port value should be 0xFF*/ -+ if (port != RTK_WHOLE_SYSTEM) -+ return RT_ERR_PORT_ID; -+ -+ if ((retVal = rtl8367c_getAsicRemarkingDscpAbility(pEnable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_qos_dscpRemark_set -+ * Description: -+ * Set DSCP remarking parameter. -+ * Input: -+ * int_pri - Internal priority value. -+ * dscp - DSCP value. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority. -+ * RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value. -+ * Note: -+ * The API can set DSCP value and mapping priority. -+ */ -+rtk_api_ret_t rtk_qos_dscpRemark_set(rtk_pri_t int_pri, rtk_dscp_t dscp) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (int_pri > RTK_PRIMAX ) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ if (dscp > RTK_DSCPMAX) -+ return RT_ERR_QOS_DSCP_VALUE; -+ -+ if ((retVal = rtl8367c_setAsicRemarkingDscpParameter(int_pri, dscp)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+ -+/* Function Name: -+ * rtk_qos_dscpRemark_get -+ * Description: -+ * Get DSCP remarking parameter. -+ * Input: -+ * int_pri - Internal priority value. -+ * Output: -+ * Dscp - DSCP value. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority. -+ * Note: -+ * The API can get DSCP parameters. It would return DSCP value for mapping priority. -+ */ -+rtk_api_ret_t rtk_qos_dscpRemark_get(rtk_pri_t int_pri, rtk_dscp_t *pDscp) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (int_pri > RTK_PRIMAX ) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ if ((retVal = rtl8367c_getAsicRemarkingDscpParameter(int_pri, pDscp)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_qos_dscpRemarkSrcSel_set -+ * Description: -+ * Set remarking source of DSCP remarking. -+ * Input: -+ * type - remarking source -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_PORT_ID - invalid port id -+ * RT_ERR_INPUT - invalid input parameter -+ -+ * Note: -+ * The API can configure DSCP remark functionality to map original DSCP value or internal -+ * priority to TX DSCP value. -+ */ -+rtk_api_ret_t rtk_qos_dscpRemarkSrcSel_set(rtk_qos_dscpRmkSrc_t type) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (type >= DSCP_RMK_SRC_END ) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ if ((retVal = rtl8367c_setAsicRemarkingDscpSrc(type)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_qos_dcpRemarkSrcSel_get -+ * Description: -+ * Get remarking source of DSCP remarking. -+ * Input: -+ * none -+ * Output: -+ * pType - remarking source -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_PORT_ID - invalid port id -+ * RT_ERR_INPUT - invalid input parameter -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ -+ * Note: -+ * None -+ */ -+rtk_api_ret_t rtk_qos_dscpRemarkSrcSel_get(rtk_qos_dscpRmkSrc_t *pType) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if ((retVal = rtl8367c_getAsicRemarkingDscpSrc(pType)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_qos_dscpRemark2Dscp_set -+ * Description: -+ * Set DSCP to remarked DSCP mapping. -+ * Input: -+ * dscp - DSCP value -+ * rmkDscp - remarked DSCP value -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_QOS_DSCP_VALUE - Invalid dscp value -+ * Note: -+ * dscp parameter can be DSCP value or internal priority according to configuration of API -+ * dal_apollomp_qos_dscpRemarkSrcSel_set(), because DSCP remark functionality can map original DSCP -+ * value or internal priority to TX DSCP value. -+ */ -+rtk_api_ret_t rtk_qos_dscpRemark2Dscp_set(rtk_dscp_t dscp, rtk_dscp_t rmkDscp) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if ((dscp > RTK_DSCPMAX) || (rmkDscp > RTK_DSCPMAX)) -+ return RT_ERR_QOS_DSCP_VALUE; -+ -+ if ((retVal = rtl8367c_setAsicRemarkingDscp2Dscp(dscp, rmkDscp)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_qos_dscpRemark2Dscp_get -+ * Description: -+ * Get DSCP to remarked DSCP mapping. -+ * Input: -+ * dscp - DSCP value -+ * Output: -+ * pDscp - remarked DSCP value -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_QOS_DSCP_VALUE - Invalid dscp value -+ * RT_ERR_NULL_POINTER - NULL pointer -+ * Note: -+ * None. -+ */ -+rtk_api_ret_t rtk_qos_dscpRemark2Dscp_get(rtk_dscp_t dscp, rtk_dscp_t *pDscp) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (dscp > RTK_DSCPMAX) -+ return RT_ERR_QOS_DSCP_VALUE; -+ -+ if ((retVal = rtl8367c_getAsicRemarkingDscp2Dscp(dscp, pDscp)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_qos_portPriSelIndex_set -+ * Description: -+ * Configure priority decision index to each port. -+ * Input: -+ * port - Port id. -+ * index - priority decision index. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_ENTRY_INDEX - Invalid entry index. -+ * Note: -+ * The API can set priority of port assignments for queue usage and packet scheduling. -+ */ -+rtk_api_ret_t rtk_qos_portPriSelIndex_set(rtk_port_t port, rtk_qos_priDecTbl_t index) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (index >= PRIDECTBL_END ) -+ return RT_ERR_ENTRY_INDEX; -+ -+ if ((retVal = rtl8367c_setAsicPortPriorityDecisionIndex(rtk_switch_port_L2P_get(port), index)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_qos_portPriSelIndex_get -+ * Description: -+ * Get priority decision index from each port. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pIndex - priority decision index. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get priority of port assignments for queue usage and packet scheduling. -+ */ -+rtk_api_ret_t rtk_qos_portPriSelIndex_get(rtk_port_t port, rtk_qos_priDecTbl_t *pIndex) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if ((retVal = rtl8367c_getAsicPortPriorityDecisionIndex(rtk_switch_port_L2P_get(port), pIndex)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/rate.c b/drivers/net/phy/rtk/rtl8367c/rate.c -new file mode 100644 -index 000000000000..a077e0c5cc16 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rate.c -@@ -0,0 +1,607 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTK switch high-level API for RTL8367/RTL8367C -+ * Feature : Here is a list of all functions and variables in rate module. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+/* Function Name: -+ * rtk_rate_shareMeter_set -+ * Description: -+ * Set meter configuration -+ * Input: -+ * index - shared meter index -+ * type - shared meter type -+ * rate - rate of share meter -+ * ifg_include - include IFG or not, ENABLE:include DISABLE:exclude -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_FILTER_METER_ID - Invalid meter -+ * RT_ERR_RATE - Invalid rate -+ * RT_ERR_INPUT - Invalid input parameters -+ * Note: -+ * The API can set shared meter rate and ifg include for each meter. -+ * The rate unit is 1 kbps and the range is from 8k to 1048568k if type is METER_TYPE_KBPS and -+ * the granularity of rate is 8 kbps. -+ * The rate unit is packets per second and the range is 1 ~ 0x1FFF if type is METER_TYPE_PPS. -+ * The ifg_include parameter is used -+ * for rate calculation with/without inter-frame-gap and preamble. -+ */ -+rtk_api_ret_t rtk_rate_shareMeter_set(rtk_meter_id_t index, rtk_meter_type_t type, rtk_rate_t rate, rtk_enable_t ifg_include) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (index > RTK_MAX_METER_ID) -+ return RT_ERR_FILTER_METER_ID; -+ -+ if (type >= METER_TYPE_END) -+ return RT_ERR_INPUT; -+ -+ if (ifg_include >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ switch (type) -+ { -+ case METER_TYPE_KBPS: -+ if (rate > RTL8367C_QOS_RATE_INPUT_MAX_HSG || rate < RTL8367C_QOS_RATE_INPUT_MIN) -+ return RT_ERR_RATE ; -+ -+ if ((retVal = rtl8367c_setAsicShareMeter(index, rate >> 3, ifg_include)) != RT_ERR_OK) -+ return retVal; -+ -+ break; -+ case METER_TYPE_PPS: -+ if (rate > RTL8367C_QOS_PPS_INPUT_MAX || rate < RTL8367C_QOS_PPS_INPUT_MIN) -+ return RT_ERR_RATE ; -+ -+ if ((retVal = rtl8367c_setAsicShareMeter(index, rate, ifg_include)) != RT_ERR_OK) -+ return retVal; -+ -+ break; -+ default: -+ return RT_ERR_INPUT; -+ } -+ -+ /* Set Type */ -+ if ((retVal = rtl8367c_setAsicShareMeterType(index, (rtk_uint32)type)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_rate_shareMeter_get -+ * Description: -+ * Get meter configuration -+ * Input: -+ * index - shared meter index -+ * Output: -+ * pType - Meter Type -+ * pRate - pointer of rate of share meter -+ * pIfg_include - include IFG or not, ENABLE:include DISABLE:exclude -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_FILTER_METER_ID - Invalid meter -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_rate_shareMeter_get(rtk_meter_id_t index, rtk_meter_type_t *pType, rtk_rate_t *pRate, rtk_enable_t *pIfg_include) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 regData; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (index > RTK_MAX_METER_ID) -+ return RT_ERR_FILTER_METER_ID; -+ -+ if(NULL == pType) -+ return RT_ERR_NULL_POINTER; -+ -+ if(NULL == pRate) -+ return RT_ERR_NULL_POINTER; -+ -+ if(NULL == pIfg_include) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicShareMeter(index, ®Data, pIfg_include)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicShareMeterType(index, (rtk_uint32 *)pType)) != RT_ERR_OK) -+ return retVal; -+ -+ if(*pType == METER_TYPE_KBPS) -+ *pRate = regData<<3; -+ else -+ *pRate = regData; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_rate_shareMeterBucket_set -+ * Description: -+ * Set meter Bucket Size -+ * Input: -+ * index - shared meter index -+ * bucket_size - Bucket Size -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_INPUT - Error Input -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_FILTER_METER_ID - Invalid meter -+ * Note: -+ * The API can set shared meter bucket size. -+ */ -+rtk_api_ret_t rtk_rate_shareMeterBucket_set(rtk_meter_id_t index, rtk_uint32 bucket_size) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (index > RTK_MAX_METER_ID) -+ return RT_ERR_FILTER_METER_ID; -+ -+ if(bucket_size > RTL8367C_METERBUCKETSIZEMAX) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicShareMeterBucketSize(index, bucket_size)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_rate_shareMeterBucket_get -+ * Description: -+ * Get meter Bucket Size -+ * Input: -+ * index - shared meter index -+ * Output: -+ * pBucket_size - Bucket Size -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_FILTER_METER_ID - Invalid meter -+ * Note: -+ * The API can get shared meter bucket size. -+ */ -+rtk_api_ret_t rtk_rate_shareMeterBucket_get(rtk_meter_id_t index, rtk_uint32 *pBucket_size) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (index > RTK_MAX_METER_ID) -+ return RT_ERR_FILTER_METER_ID; -+ -+ if(NULL == pBucket_size) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicShareMeterBucketSize(index, pBucket_size)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_rate_igrBandwidthCtrlRate_set -+ * Description: -+ * Set port ingress bandwidth control -+ * Input: -+ * port - Port id -+ * rate - Rate of share meter -+ * ifg_include - include IFG or not, ENABLE:include DISABLE:exclude -+ * fc_enable - enable flow control or not, ENABLE:use flow control DISABLE:drop -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_ENABLE - Invalid IFG parameter. -+ * RT_ERR_INBW_RATE - Invalid ingress rate parameter. -+ * Note: -+ * The rate unit is 1 kbps and the range is from 8k to 1048568k. The granularity of rate is 8 kbps. -+ * The ifg_include parameter is used for rate calculation with/without inter-frame-gap and preamble. -+ */ -+rtk_api_ret_t rtk_rate_igrBandwidthCtrlRate_set(rtk_port_t port, rtk_rate_t rate, rtk_enable_t ifg_include, rtk_enable_t fc_enable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(ifg_include >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if(fc_enable >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if(rtk_switch_isHsgPort(port) == RT_ERR_OK) -+ { -+ if ((rate > RTL8367C_QOS_RATE_INPUT_MAX_HSG) || (rate < RTL8367C_QOS_RATE_INPUT_MIN)) -+ return RT_ERR_QOS_EBW_RATE ; -+ } -+ else -+ { -+ if ((rate > RTL8367C_QOS_RATE_INPUT_MAX) || (rate < RTL8367C_QOS_RATE_INPUT_MIN)) -+ return RT_ERR_QOS_EBW_RATE ; -+ } -+ -+ if ((retVal = rtl8367c_setAsicPortIngressBandwidth(rtk_switch_port_L2P_get(port), rate>>3, ifg_include,fc_enable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_rate_igrBandwidthCtrlRate_get -+ * Description: -+ * Get port ingress bandwidth control -+ * Input: -+ * port - Port id -+ * Output: -+ * pRate - Rate of share meter -+ * pIfg_include - Rate's calculation including IFG, ENABLE:include DISABLE:exclude -+ * pFc_enable - enable flow control or not, ENABLE:use flow control DISABLE:drop -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The rate unit is 1 kbps and the range is from 8k to 1048568k. The granularity of rate is 8 kbps. -+ * The ifg_include parameter is used for rate calculation with/without inter-frame-gap and preamble. -+ */ -+rtk_api_ret_t rtk_rate_igrBandwidthCtrlRate_get(rtk_port_t port, rtk_rate_t *pRate, rtk_enable_t *pIfg_include, rtk_enable_t *pFc_enable) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 regData; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(NULL == pIfg_include) -+ return RT_ERR_NULL_POINTER; -+ -+ if(NULL == pFc_enable) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicPortIngressBandwidth(rtk_switch_port_L2P_get(port), ®Data, pIfg_include, pFc_enable)) != RT_ERR_OK) -+ return retVal; -+ -+ *pRate = regData<<3; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_rate_egrBandwidthCtrlRate_set -+ * Description: -+ * Set port egress bandwidth control -+ * Input: -+ * port - Port id -+ * rate - Rate of egress bandwidth -+ * ifg_include - include IFG or not, ENABLE:include DISABLE:exclude -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_QOS_EBW_RATE - Invalid egress bandwidth/rate -+ * Note: -+ * The rate unit is 1 kbps and the range is from 8k to 1048568k. The granularity of rate is 8 kbps. -+ * The ifg_include parameter is used for rate calculation with/without inter-frame-gap and preamble. -+ */ -+rtk_api_ret_t rtk_rate_egrBandwidthCtrlRate_set( rtk_port_t port, rtk_rate_t rate, rtk_enable_t ifg_include) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(rtk_switch_isHsgPort(port) == RT_ERR_OK) -+ { -+ if ((rate > RTL8367C_QOS_RATE_INPUT_MAX_HSG) || (rate < RTL8367C_QOS_RATE_INPUT_MIN)) -+ return RT_ERR_QOS_EBW_RATE ; -+ } -+ else -+ { -+ if ((rate > RTL8367C_QOS_RATE_INPUT_MAX) || (rate < RTL8367C_QOS_RATE_INPUT_MIN)) -+ return RT_ERR_QOS_EBW_RATE ; -+ } -+ -+ if (ifg_include >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ if ((retVal = rtl8367c_setAsicPortEgressRate(rtk_switch_port_L2P_get(port), rate>>3)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicPortEgressRateIfg(ifg_include)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_rate_egrBandwidthCtrlRate_get -+ * Description: -+ * Get port egress bandwidth control -+ * Input: -+ * port - Port id -+ * Output: -+ * pRate - Rate of egress bandwidth -+ * pIfg_include - Rate's calculation including IFG, ENABLE:include DISABLE:exclude -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The rate unit is 1 kbps and the range is from 8k to 1048568k. The granularity of rate is 8 kbps. -+ * The ifg_include parameter is used for rate calculation with/without inter-frame-gap and preamble. -+ */ -+rtk_api_ret_t rtk_rate_egrBandwidthCtrlRate_get(rtk_port_t port, rtk_rate_t *pRate, rtk_enable_t *pIfg_include) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 regData; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(NULL == pRate) -+ return RT_ERR_NULL_POINTER; -+ -+ if(NULL == pIfg_include) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicPortEgressRate(rtk_switch_port_L2P_get(port), ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ *pRate = regData << 3; -+ -+ if ((retVal = rtl8367c_getAsicPortEgressRateIfg((rtk_uint32*)pIfg_include)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+ -+/* Function Name: -+ * rtk_rate_egrQueueBwCtrlEnable_get -+ * Description: -+ * Get enable status of egress bandwidth control on specified queue. -+ * Input: -+ * unit - unit id -+ * port - port id -+ * queue - queue id -+ * Output: -+ * pEnable - Pointer to enable status of egress queue bandwidth control -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_PORT_ID - invalid port id -+ * RT_ERR_QUEUE_ID - invalid queue id -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ * Note: -+ * None -+ */ -+rtk_api_ret_t rtk_rate_egrQueueBwCtrlEnable_get(rtk_port_t port, rtk_qid_t queue, rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ /*for whole port function, the queue value should be 0xFF*/ -+ if (queue != RTK_WHOLE_SYSTEM) -+ return RT_ERR_QUEUE_ID; -+ -+ if(NULL == pEnable) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicAprEnable(rtk_switch_port_L2P_get(port),pEnable))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_rate_egrQueueBwCtrlEnable_set -+ * Description: -+ * Set enable status of egress bandwidth control on specified queue. -+ * Input: -+ * port - port id -+ * queue - queue id -+ * enable - enable status of egress queue bandwidth control -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_PORT_ID - invalid port id -+ * RT_ERR_QUEUE_ID - invalid queue id -+ * RT_ERR_INPUT - invalid input parameter -+ * Note: -+ * None -+ */ -+rtk_api_ret_t rtk_rate_egrQueueBwCtrlEnable_set(rtk_port_t port, rtk_qid_t queue, rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ /*for whole port function, the queue value should be 0xFF*/ -+ if (queue != RTK_WHOLE_SYSTEM) -+ return RT_ERR_QUEUE_ID; -+ -+ if (enable>=RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicAprEnable(rtk_switch_port_L2P_get(port), enable))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_rate_egrQueueBwCtrlRate_get -+ * Description: -+ * Get rate of egress bandwidth control on specified queue. -+ * Input: -+ * port - port id -+ * queue - queue id -+ * pIndex - shared meter index -+ * Output: -+ * pRate - pointer to rate of egress queue bandwidth control -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_PORT_ID - invalid port id -+ * RT_ERR_QUEUE_ID - invalid queue id -+ * RT_ERR_FILTER_METER_ID - Invalid meter id -+ * Note: -+ * The actual rate control is set in shared meters. -+ * The unit of granularity is 8Kbps. -+ */ -+rtk_api_ret_t rtk_rate_egrQueueBwCtrlRate_get(rtk_port_t port, rtk_qid_t queue, rtk_meter_id_t *pIndex) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 offset_idx; -+ rtk_uint32 phy_port; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (queue >= RTK_MAX_NUM_OF_QUEUE) -+ return RT_ERR_QUEUE_ID; -+ -+ if(NULL == pIndex) -+ return RT_ERR_NULL_POINTER; -+ -+ phy_port = rtk_switch_port_L2P_get(port); -+ if ((retVal=rtl8367c_getAsicAprMeter(phy_port, queue,&offset_idx))!=RT_ERR_OK) -+ return retVal; -+ -+ *pIndex = offset_idx + ((phy_port%4)*8); -+ -+ return RT_ERR_OK; -+} -+ -+ -+/* Function Name: -+ * rtk_rate_egrQueueBwCtrlRate_set -+ * Description: -+ * Set rate of egress bandwidth control on specified queue. -+ * Input: -+ * port - port id -+ * queue - queue id -+ * index - shared meter index -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_PORT_ID - invalid port id -+ * RT_ERR_QUEUE_ID - invalid queue id -+ * RT_ERR_FILTER_METER_ID - Invalid meter id -+ * Note: -+ * The actual rate control is set in shared meters. -+ * The unit of granularity is 8Kbps. -+ */ -+rtk_api_ret_t rtk_rate_egrQueueBwCtrlRate_set(rtk_port_t port, rtk_qid_t queue, rtk_meter_id_t index) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 offset_idx; -+ rtk_uint32 phy_port; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (queue >= RTK_MAX_NUM_OF_QUEUE) -+ return RT_ERR_QUEUE_ID; -+ -+ if (index > RTK_MAX_METER_ID) -+ return RT_ERR_FILTER_METER_ID; -+ -+ phy_port = rtk_switch_port_L2P_get(port); -+ if (index < ((phy_port%4)*8) || index > (7 + (phy_port%4)*8)) -+ return RT_ERR_FILTER_METER_ID; -+ -+ offset_idx = index - ((phy_port%4)*8); -+ -+ if ((retVal=rtl8367c_setAsicAprMeter(phy_port,queue,offset_idx))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/rldp.c b/drivers/net/phy/rtk/rtl8367c/rldp.c -new file mode 100644 -index 000000000000..0ecc32a6b571 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rldp.c -@@ -0,0 +1,468 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : Declaration of RLDP and RLPP API -+ * -+ * Feature : The file have include the following module and sub-modules -+ * 1) RLDP and RLPP configuration and status -+ * -+ */ -+ -+ -+/* -+ * Include Files -+ */ -+#include -+#include -+//#include -+#include -+ -+#include -+#include -+ -+/* -+ * Symbol Definition -+ */ -+ -+ -+/* -+ * Data Declaration -+ */ -+ -+ -+/* -+ * Macro Declaration -+ */ -+ -+ -+/* -+ * Function Declaration -+ */ -+ -+/* Module Name : RLDP */ -+ -+/* Function Name: -+ * rtk_rldp_config_set -+ * Description: -+ * Set RLDP module configuration -+ * Input: -+ * pConfig - configuration structure of RLDP -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_INPUT -+ * RT_ERR_NULL_POINTER -+ * Note: -+ * None -+ */ -+rtk_api_ret_t rtk_rldp_config_set(rtk_rldp_config_t *pConfig) -+{ -+ rtk_api_ret_t retVal; -+ ether_addr_t magic; -+ rtk_uint32 pmsk; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (pConfig->rldp_enable >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if (pConfig->trigger_mode >= RTK_RLDP_TRIGGER_END) -+ return RT_ERR_INPUT; -+ -+ if (pConfig->compare_type >= RTK_RLDP_CMPTYPE_END) -+ return RT_ERR_INPUT; -+ -+ if (pConfig->num_check >= RTK_RLDP_NUM_MAX) -+ return RT_ERR_INPUT; -+ -+ if (pConfig->interval_check >= RTK_RLDP_INTERVAL_MAX) -+ return RT_ERR_INPUT; -+ -+ if (pConfig->num_loop >= RTK_RLDP_NUM_MAX) -+ return RT_ERR_INPUT; -+ -+ if (pConfig->interval_loop >= RTK_RLDP_INTERVAL_MAX) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_getAsicRldpTxPortmask(&pmsk))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRldpTxPortmask(0x00))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRldpTxPortmask(pmsk))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRldp(pConfig->rldp_enable))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRldpTriggerMode(pConfig->trigger_mode))!=RT_ERR_OK) -+ return retVal; -+ -+ memcpy(&magic, &pConfig->magic, sizeof(ether_addr_t)); -+ if ((retVal = rtl8367c_setAsicRldpMagicNum(magic))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRldpCompareRandomNumber(pConfig->compare_type))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRldpCompareRandomNumber(pConfig->compare_type))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRldpCheckingStatePara(pConfig->num_check, pConfig->interval_check))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRldpLoopStatePara(pConfig->num_loop, pConfig->interval_loop))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+ -+/* Function Name: -+ * rtk_rldp_config_get -+ * Description: -+ * Get RLDP module configuration -+ * Input: -+ * None -+ * Output: -+ * pConfig - configuration structure of RLDP -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_INPUT -+ * RT_ERR_NULL_POINTER -+ * Note: -+ * None -+ */ -+rtk_api_ret_t rtk_rldp_config_get(rtk_rldp_config_t *pConfig) -+{ -+ rtk_api_ret_t retVal; -+ ether_addr_t magic; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if ((retVal = rtl8367c_getAsicRldp(&pConfig->rldp_enable))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicRldpTriggerMode(&pConfig->trigger_mode))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicRldpMagicNum(&magic))!=RT_ERR_OK) -+ return retVal; -+ memcpy(&pConfig->magic, &magic, sizeof(ether_addr_t)); -+ -+ if ((retVal = rtl8367c_getAsicRldpCompareRandomNumber(&pConfig->compare_type))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicRldpCompareRandomNumber(&pConfig->compare_type))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicRldpCheckingStatePara(&pConfig->num_check, &pConfig->interval_check))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicRldpLoopStatePara(&pConfig->num_loop, &pConfig->interval_loop))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+ -+/* Function Name: -+ * rtk_rldp_portConfig_set -+ * Description: -+ * Set per port RLDP module configuration -+ * Input: -+ * port - port number to be configured -+ * pPortConfig - per port configuration structure of RLDP -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_INPUT -+ * RT_ERR_NULL_POINTER -+ * Note: -+ * None -+ */ -+rtk_api_ret_t rtk_rldp_portConfig_set(rtk_port_t port, rtk_rldp_portConfig_t *pPortConfig) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pmsk; -+ rtk_uint32 phy_port; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (pPortConfig->tx_enable>= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ phy_port = rtk_switch_port_L2P_get(port); -+ -+ if ((retVal = rtl8367c_getAsicRldpTxPortmask(&pmsk))!=RT_ERR_OK) -+ return retVal; -+ -+ if (pPortConfig->tx_enable) -+ { -+ pmsk |=(1<tx_enable = ENABLED; -+ } -+ else -+ { -+ pPortConfig->tx_enable = DISABLED; -+ } -+ -+ return RT_ERR_OK; -+} /* end of rtk_rldp_portConfig_get */ -+ -+ -+/* Function Name: -+ * rtk_rldp_status_get -+ * Description: -+ * Get RLDP module status -+ * Input: -+ * None -+ * Output: -+ * pStatus - status structure of RLDP -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NULL_POINTER -+ * Note: -+ * None -+ */ -+rtk_api_ret_t rtk_rldp_status_get(rtk_rldp_status_t *pStatus) -+{ -+ rtk_api_ret_t retVal; -+ ether_addr_t seed; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if ((retVal = rtl8367c_getAsicRldpRandomNumber(&seed))!=RT_ERR_OK) -+ return retVal; -+ memcpy(&pStatus->id, &seed, sizeof(ether_addr_t)); -+ -+ return RT_ERR_OK; -+} /* end of rtk_rldp_status_get */ -+ -+ -+/* Function Name: -+ * rtk_rldp_portStatus_get -+ * Description: -+ * Get RLDP module status -+ * Input: -+ * port - port number to be get -+ * Output: -+ * pPortStatus - per port status structure of RLDP -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_INPUT -+ * RT_ERR_NULL_POINTER -+ * Note: -+ * None -+ */ -+rtk_api_ret_t rtk_rldp_portStatus_get(rtk_port_t port, rtk_rldp_portStatus_t *pPortStatus) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pmsk; -+ rtk_portmask_t logicalPmask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if ((retVal = rtl8367c_getAsicRldpLoopedPortmask(&pmsk))!=RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtk_switch_portmask_P2L_get(pmsk, &logicalPmask)) != RT_ERR_OK) -+ return retVal; -+ -+ if (logicalPmask.bits[0] & (1<loop_status = RTK_RLDP_LOOPSTS_LOOPING; -+ } -+ else -+ { -+ pPortStatus->loop_status = RTK_RLDP_LOOPSTS_NONE; -+ } -+ -+ if ((retVal = rtl8367c_getAsicRldpEnterLoopedPortmask(&pmsk))!=RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtk_switch_portmask_P2L_get(pmsk, &logicalPmask)) != RT_ERR_OK) -+ return retVal; -+ -+ if (logicalPmask.bits[0] & (1<loop_enter = RTK_RLDP_LOOPSTS_LOOPING; -+ } -+ else -+ { -+ pPortStatus->loop_enter = RTK_RLDP_LOOPSTS_NONE; -+ } -+ -+ if ((retVal = rtl8367c_getAsicRldpLeaveLoopedPortmask(&pmsk))!=RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtk_switch_portmask_P2L_get(pmsk, &logicalPmask)) != RT_ERR_OK) -+ return retVal; -+ -+ if (logicalPmask.bits[0] & (1<loop_leave = RTK_RLDP_LOOPSTS_LOOPING; -+ } -+ else -+ { -+ pPortStatus->loop_leave = RTK_RLDP_LOOPSTS_NONE; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+ -+/* Function Name: -+ * rtk_rldp_portStatus_clear -+ * Description: -+ * Clear RLDP module status -+ * Input: -+ * port - port number to be clear -+ * pPortStatus - per port status structure of RLDP -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_INPUT -+ * RT_ERR_NULL_POINTER -+ * Note: -+ * Clear operation effect loop_enter and loop_leave only, other field in -+ * the structure are don't care. Loop status can't be clean. -+ */ -+rtk_api_ret_t rtk_rldp_portStatus_set(rtk_port_t port, rtk_rldp_portStatus_t *pPortStatus) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pmsk; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ pmsk = (pPortStatus->loop_enter)<loop_leave)< -+#include -+#include "./include/rtk_switch.h" -+#include "./include/vlan.h" -+#include "./include/port.h" -+#include "./include/rate.h" -+#include "./include/rtk_hal.h" -+#include "./include/l2.h" -+#include "./include/stat.h" -+#include "./include/igmp.h" -+#include "./include/trap.h" -+#include "./include/leaky.h" -+#include "./include/mirror.h" -+#include "./include/rtl8367c_asicdrv_port.h" -+#include "./include/rtl8367c_asicdrv_mib.h" -+#include "./include/smi.h" -+#include "./include/qos.h" -+#include "./include/trunk.h" -+ -+void rtk_hal_switch_init(void) -+{ -+ if(rtk_switch_init() != 0) -+ printk("rtk_switch_init failed\n"); -+ mdelay(500); -+ /*vlan init */ -+ if (rtk_vlan_init() != 0) -+ printk("rtk_vlan_init failed\n"); -+} -+ -+void rtk_hal_dump_full_mib(void) -+{ -+ rtk_port_t port; -+ rtk_stat_counter_t Cntr; -+ rtk_stat_port_type_t cntr_idx; -+ -+ for (port = UTP_PORT0; port < (UTP_PORT0 + 5); port++) { -+ printk("\nPort%d\n", port); -+ for (cntr_idx = STAT_IfInOctets; cntr_idx < STAT_PORT_CNTR_END; cntr_idx ++) { -+ rtk_stat_port_get(port, cntr_idx, &Cntr); -+ printk("%8llu ", Cntr); -+ if (((cntr_idx%10) == 9)) -+ printk("\n"); -+ } -+ } -+ -+ for (port = EXT_PORT0; port < (EXT_PORT0 + 2); port++) { -+ printk("\nPort%d\n", port); -+ for (cntr_idx = STAT_IfInOctets; cntr_idx < STAT_PORT_CNTR_END; cntr_idx ++) { -+ rtk_stat_port_get(port, cntr_idx, &Cntr); -+ printk("%8llu ", Cntr); -+ if (((cntr_idx%10) == 9)) -+ printk("\n"); -+ } -+ } -+ rtk_stat_global_reset(); -+} -+void rtk_dump_mib_type(rtk_stat_port_type_t cntr_idx) -+{ -+ rtk_port_t port; -+ rtk_stat_counter_t Cntr; -+ -+ for (port = UTP_PORT0; port < (UTP_PORT0 + 5); port++) { -+ rtk_stat_port_get(port, cntr_idx, &Cntr); -+ printk("%8llu", Cntr); -+ } -+ for (port = EXT_PORT0; port < (EXT_PORT0 + 2); port++) { -+ rtk_stat_port_get(port, cntr_idx, &Cntr); -+ printk("%8llu", Cntr); -+ } -+ printk("\n"); -+} -+ -+void rtk_hal_dump_mib(void) -+{ -+ -+ printk("==================%8s%8s%8s%8s%8s%8s%8s\n", "Port0", "Port1", -+ "Port2", "Port3", "Port4", "Port16", "Port17"); -+ /* Get TX Unicast Pkts */ -+ printk("TX Unicast Pkts :"); -+ rtk_dump_mib_type(STAT_IfOutUcastPkts); -+ /* Get TX Multicast Pkts */ -+ printk("TX Multicast Pkts:"); -+ rtk_dump_mib_type(STAT_IfOutMulticastPkts); -+ /* Get TX BroadCast Pkts */ -+ printk("TX BroadCast Pkts:"); -+ rtk_dump_mib_type(STAT_IfOutBroadcastPkts); -+ /* Get TX Collisions */ -+ /* Get TX Puase Frames */ -+ printk("TX Pause Frames :"); -+ rtk_dump_mib_type(STAT_Dot3OutPauseFrames); -+ /* Get TX Drop Events */ -+ /* Get RX Unicast Pkts */ -+ printk("RX Unicast Pkts :"); -+ rtk_dump_mib_type(STAT_IfInUcastPkts); -+ /* Get RX Multicast Pkts */ -+ printk("RX Multicast Pkts:"); -+ rtk_dump_mib_type(STAT_IfInMulticastPkts); -+ /* Get RX Broadcast Pkts */ -+ printk("RX Broadcast Pkts:"); -+ rtk_dump_mib_type(STAT_IfInBroadcastPkts); -+ /* Get RX FCS Erros */ -+ printk("RX FCS Errors :"); -+ rtk_dump_mib_type(STAT_Dot3StatsFCSErrors); -+ /* Get RX Undersize Pkts */ -+ printk("RX Undersize Pkts:"); -+ rtk_dump_mib_type(STAT_EtherStatsUnderSizePkts); -+ /* Get RX Discard Pkts */ -+ printk("RX Discard Pkts :"); -+ rtk_dump_mib_type(STAT_Dot1dTpPortInDiscards); -+ /* Get RX Fragments */ -+ printk("RX Fragments :"); -+ rtk_dump_mib_type(STAT_EtherStatsFragments); -+ /* Get RX Oversize Pkts */ -+ printk("RX Oversize Pkts :"); -+ rtk_dump_mib_type(STAT_EtherOversizeStats); -+ /* Get RX Jabbers */ -+ printk("RX Jabbers :"); -+ rtk_dump_mib_type(STAT_EtherStatsJabbers); -+ /* Get RX Pause Frames */ -+ printk("RX Pause Frames :"); -+ rtk_dump_mib_type(STAT_Dot3InPauseFrames); -+ /* clear MIB */ -+ rtk_stat_global_reset(); -+} -+EXPORT_SYMBOL(rtk_hal_dump_mib); -+ -+int rtk_hal_dump_vlan(void) -+{ -+ rtk_vlan_cfg_t vlan; -+ int i; -+ -+ printk("vid portmap\n"); -+ for (i = 0; i < RTK_SW_VID_RANGE; i++) { -+ rtk_vlan_get(i, &vlan); -+ printk("%3d ", i); -+ printk("%c", -+ RTK_PORTMASK_IS_PORT_SET(vlan.mbr, -+ UTP_PORT0) ? '1' : '-'); -+ printk("%c", -+ RTK_PORTMASK_IS_PORT_SET(vlan.mbr, -+ UTP_PORT1) ? '1' : '-'); -+ printk("%c", -+ RTK_PORTMASK_IS_PORT_SET(vlan.mbr, -+ UTP_PORT2) ? '1' : '-'); -+ printk("%c", -+ RTK_PORTMASK_IS_PORT_SET(vlan.mbr, -+ UTP_PORT3) ? '1' : '-'); -+ printk("%c", -+ RTK_PORTMASK_IS_PORT_SET(vlan.mbr, -+ UTP_PORT4) ? '1' : '-'); -+ printk("%c", -+ RTK_PORTMASK_IS_PORT_SET(vlan.mbr, -+ EXT_PORT0) ? '1' : '-'); -+ printk("%c", -+ RTK_PORTMASK_IS_PORT_SET(vlan.mbr, -+ EXT_PORT1) ? '1' : '-'); -+ printk("\n"); -+ } -+ return 0; -+} -+ -+void rtk_hal_clear_vlan(void) -+{ -+ rtk_api_ret_t ret; -+ -+ ret = rtk_vlan_reset(); -+ if (ret != RT_ERR_OK) -+ printk("rtk_vlan_reset failed\n"); -+} -+ -+int rtk_hal_set_vlan(struct ra_switch_ioctl_data *data) -+{ -+ rtk_vlan_cfg_t vlan; -+ rtk_api_ret_t ret; -+ int i; -+ -+ /* clear vlan entry first */ -+ memset(&vlan, 0x00, sizeof(rtk_vlan_cfg_t)); -+ RTK_PORTMASK_CLEAR(vlan.mbr); -+ RTK_PORTMASK_CLEAR(vlan.untag); -+ rtk_vlan_set(data->vid, &vlan); -+ -+ memset(&vlan, 0x00, sizeof(rtk_vlan_cfg_t)); -+ for (i = 0; i < 5; i++) { -+ if (data->port_map & (1 << i)) { -+ RTK_PORTMASK_PORT_SET(vlan.mbr, i); -+ RTK_PORTMASK_PORT_SET(vlan.untag, i); -+ rtk_vlan_portPvid_set(i, data->vid, 0); -+ } -+ } -+ for (i = 0; i < 2; i++) { -+ if (data->port_map & (1 << (i + 5))) { -+ RTK_PORTMASK_PORT_SET(vlan.mbr, (i + EXT_PORT0)); -+ RTK_PORTMASK_PORT_SET(vlan.untag, (i + EXT_PORT0)); -+ rtk_vlan_portPvid_set((i + EXT_PORT0), data->vid, 0); -+ } -+ } -+ vlan.ivl_en = 1; -+ ret = rtk_vlan_set(data->vid, &vlan); -+ -+ return 0; -+} -+ -+void rtk_hal_vlan_portpvid_set(rtk_port_t port, rtk_vlan_t pvid, rtk_pri_t priority) -+{ -+ rtk_vlan_portPvid_set(port, pvid, priority); -+} -+ -+int rtk_hal_set_ingress_rate(struct ra_switch_ioctl_data *data) -+{ -+ rtk_api_ret_t ret; -+ -+ if (data->on_off == 1) -+ ret = -+ rtk_rate_igrBandwidthCtrlRate_set(data->port, data->bw, 0, -+ 1); -+ else -+ ret = -+ rtk_rate_igrBandwidthCtrlRate_set(data->port, 1048568, 0, -+ 1); -+ -+ return ret; -+} -+ -+int rtk_hal_set_egress_rate(struct ra_switch_ioctl_data *data) -+{ -+ rtk_api_ret_t ret; -+ -+ if (data->on_off == 1) -+ ret = -+ rtk_rate_egrBandwidthCtrlRate_set(data->port, data->bw, 1); -+ else -+ ret = rtk_rate_egrBandwidthCtrlRate_set(data->port, 1048568, 1); -+ -+ return ret; -+} -+ -+void rtk_hal_dump_table(void) -+{ -+ rtk_uint32 i; -+ rtk_uint32 address = 0; -+ rtk_l2_ucastAddr_t l2_data; -+ rtk_l2_ipMcastAddr_t ipMcastAddr; -+ -+ printk("hash port(0:17) fid vid mac-address\n"); -+ while (1) { -+ if (rtk_l2_addr_next_get(READMETHOD_NEXT_L2UC, UTP_PORT0, &address, &l2_data) != RT_ERR_OK) { -+ break; -+ } else { -+ printk("%03x ", l2_data.address); -+ for (i = 0; i < 5; i++) -+ if ( l2_data.port == i) -+ printk("1"); -+ else -+ printk("-"); -+ for (i = 16; i < 18; i++) -+ if ( l2_data.port == i) -+ printk("1"); -+ else -+ printk("-"); -+ -+ printk(" %2d", l2_data.fid); -+ printk(" %4d", l2_data.cvid); -+ printk(" %02x%02x%02x%02x%02x%02x\n", l2_data.mac.octet[0], -+ l2_data.mac.octet[1], l2_data.mac.octet[2], l2_data.mac.octet[3], -+ l2_data.mac.octet[4], l2_data.mac.octet[5]); -+ address ++; -+ } -+ } -+ -+ address = 0; -+ while (1) { -+ if (rtk_l2_ipMcastAddr_next_get(&address, &ipMcastAddr) != RT_ERR_OK) { -+ break; -+ } else { -+ printk("%03x ", ipMcastAddr.address); -+ for (i = 0; i < 5; i++) -+ printk("%c", RTK_PORTMASK_IS_PORT_SET(ipMcastAddr.portmask, i) ? '1' : '-'); -+ for (i = 16; i < 18; i++) -+ printk("%c", RTK_PORTMASK_IS_PORT_SET(ipMcastAddr.portmask, i) ? '1' : '-'); -+ printk(" "); -+ printk("01005E%06x\n", (ipMcastAddr.dip & 0xefffff)); -+ address ++; -+ } -+ } -+} -+ -+void rtk_hal_clear_table(void) -+{ -+ rtk_api_ret_t ret; -+ -+ ret = rtk_l2_table_clear(); -+ if (ret != RT_ERR_OK) -+ printk("rtk_l2_table_clear failed\n"); -+} -+ -+void rtk_hal_add_table(struct ra_switch_ioctl_data *data) -+{ -+ rtk_api_ret_t ret; -+ rtk_l2_ucastAddr_t l2_entry; -+ rtk_mac_t mac; -+ -+ mac.octet[0] =data->mac[0]; -+ mac.octet[1] =data->mac[1]; -+ mac.octet[2] =data->mac[2]; -+ mac.octet[3] =data->mac[3]; -+ mac.octet[4] =data->mac[4]; -+ mac.octet[5] =data->mac[5]; -+ -+ memset(&l2_entry, 0x00, sizeof(rtk_l2_ucastAddr_t)); -+ l2_entry.port = data->port; -+ l2_entry.ivl = 1; -+ l2_entry.cvid = data->vid; -+ l2_entry.fid = 0; -+ l2_entry.efid = 0; -+ l2_entry.is_static = 1; -+ ret = rtk_l2_addr_add(&mac, &l2_entry); -+ if (ret != RT_ERR_OK) -+ printk("rtk_hal_add_table failed\n"); -+} -+ -+void rtk_hal_del_table(struct ra_switch_ioctl_data *data) -+{ -+ rtk_api_ret_t ret; -+ rtk_l2_ucastAddr_t l2_entry; -+ rtk_mac_t mac; -+ -+ mac.octet[0] =data->mac[0]; -+ mac.octet[1] =data->mac[1]; -+ mac.octet[2] =data->mac[2]; -+ mac.octet[3] =data->mac[3]; -+ mac.octet[4] =data->mac[4]; -+ mac.octet[5] =data->mac[5]; -+ -+ memset(&l2_entry, 0x00, sizeof(rtk_l2_ucastAddr_t)); -+ l2_entry.port = data->port; -+ l2_entry.ivl = 1; -+ l2_entry.cvid = data->vid; -+ l2_entry.fid = 0; -+ l2_entry.efid = 0; -+ ret = rtk_l2_addr_del(&mac, &l2_entry); -+ if (ret != RT_ERR_OK) -+ printk("rtk_hal_add_table failed\n"); -+} -+void rtk_hal_get_phy_status(struct ra_switch_ioctl_data *data) -+{ -+ rtk_port_linkStatus_t linkStatus; -+ rtk_port_speed_t speed; -+ rtk_port_duplex_t duplex; -+ -+ rtk_port_phyStatus_get(data->port, &linkStatus, &speed, &duplex); -+ printk("Port%d Status:\n", data->port); -+ if (linkStatus == 1) { -+ printk("Link Up"); -+ if (speed == 0) -+ printk(" 10M"); -+ else if (speed == 1) -+ printk(" 100M"); -+ else if (speed == 2) -+ printk(" 1000M"); -+ if (duplex == 0) -+ printk(" Half Duplex\n"); -+ else -+ printk(" Full Duplex\n"); -+ } else -+ printk("Link Down\n"); -+ -+} -+ -+void rtk_hal_set_port_mirror(struct ra_switch_ioctl_data *data) -+{ -+ rtk_portmask_t rx_portmask; -+ rtk_portmask_t tx_portmask; -+ rtk_api_ret_t ret; -+ int i; -+ -+ rtk_mirror_portIso_set(ENABLED); -+ RTK_PORTMASK_CLEAR(rx_portmask); -+ RTK_PORTMASK_CLEAR(tx_portmask); -+ for (i = 0; i < 5; i++) -+ if (data->rx_port_map & (1 << i)) -+ RTK_PORTMASK_PORT_SET(rx_portmask, i); -+ for (i = 0; i < 2; i++) -+ if (data->rx_port_map & (1 << (i + 5))) -+ RTK_PORTMASK_PORT_SET(rx_portmask, (i + EXT_PORT0)); -+ -+ RTK_PORTMASK_CLEAR(tx_portmask); -+ for (i = 0; i < 5; i++) -+ if (data->tx_port_map & (1 << i)) -+ RTK_PORTMASK_PORT_SET(tx_portmask, i); -+ for (i = 0; i < 2; i++) -+ if (data->tx_port_map & (1 << (i + 5))) -+ RTK_PORTMASK_PORT_SET(tx_portmask, (i + EXT_PORT0)); -+ -+ ret = rtk_mirror_portBased_set(data->port, &rx_portmask, &tx_portmask); -+ if (!ret) -+ printk("rtk_mirror_portBased_set success\n"); -+} -+ -+void rtk_hal_read_reg(struct ra_switch_ioctl_data *data) -+{ -+ ret_t retVal; -+ -+ retVal = smi_read(data->reg_addr, &data->reg_val); -+ if(retVal != RT_ERR_OK) -+ printk("switch reg read failed\n"); -+ else -+ printk("reg0x%x = 0x%x\n", data->reg_addr, data->reg_val); -+} -+ -+void rtk_hal_write_reg(struct ra_switch_ioctl_data *data) -+{ -+ ret_t retVal; -+ -+ retVal = smi_write(data->reg_addr, data->reg_val); -+ if(retVal != RT_ERR_OK) -+ printk("switch reg write failed\n"); -+ else -+ printk("write switch reg0x%x 0x%x success\n", data->reg_addr, data->reg_val); -+} -+ -+void rtk_hal_get_phy_reg(struct ra_switch_ioctl_data *data) -+{ -+ ret_t retVal; -+ rtk_port_phy_data_t Data; -+ -+ retVal = rtk_port_phyReg_get(data->port, data->reg_addr, &Data); -+ if (retVal == RT_ERR_OK) -+ printk("Get: phy[%d].reg[%d] = 0x%04x\n", data->port, data->reg_addr, Data); -+ else -+ printk("read phy reg failed\n"); -+} -+ -+void rtk_hal_set_phy_reg(struct ra_switch_ioctl_data *data) -+{ -+ ret_t retVal; -+ -+ retVal = rtk_port_phyReg_set(data->port, data->reg_addr, data->reg_val); -+ if (retVal == RT_ERR_OK) -+ printk("Set: phy[%d].reg[%d] = 0x%04x\n", data->port, data->reg_addr, data->reg_val); -+ else -+ printk("write phy reg failed\n"); -+} -+void rtk_hal_qos_en(struct ra_switch_ioctl_data *data) -+{ -+ -+ if (data->on_off == 1) { -+ if (rtk_qos_init(8) != 0) -+ printk("rtk_qos_init(8) failed\n"); -+ } -+ else { -+ if (rtk_qos_init(1) != 0) -+ printk("rtk_qos_init(1) failed\n"); -+ } -+} -+ -+void rtk_hal_qos_set_table2type(struct ra_switch_ioctl_data *data) -+{ -+ rtk_api_ret_t ret; -+ rtk_priority_select_t PriDec; -+ -+ /* write all pri to 0 */ -+ PriDec.port_pri = 0; -+ PriDec.dot1q_pri = 0; -+ PriDec.acl_pri = 0; -+ PriDec.cvlan_pri = 0; -+ PriDec.svlan_pri = 0; -+ PriDec.dscp_pri = 0; -+ PriDec.dmac_pri = 0; -+ PriDec.smac_pri = 0; -+ -+ if (data->qos_type == 0) -+ PriDec.port_pri = 1; -+ else if (data->qos_type == 1) -+ PriDec.dot1q_pri = 1; -+ else if (data->qos_type == 2) -+ PriDec.acl_pri = 1; -+ else if (data->qos_type == 3) -+ PriDec.dscp_pri = 1; -+ else if (data->qos_type == 4) -+ PriDec.cvlan_pri = 1; -+ else if (data->qos_type == 5) -+ PriDec.svlan_pri = 1; -+ else if (data->qos_type == 6) -+ PriDec.dmac_pri = 1; -+ else if (data->qos_type == 7) -+ PriDec.smac_pri = 1; -+ -+ if (data->qos_table_idx == 0) -+ ret = rtk_qos_priSel_set(PRIDECTBL_IDX0, &PriDec); -+ else -+ ret = rtk_qos_priSel_set(PRIDECTBL_IDX1, &PriDec); -+ -+ if (ret != 0) -+ printk("rtk_qos_priSel_set failed\n"); -+ -+} -+ -+void rtk_hal_qos_get_table2type(struct ra_switch_ioctl_data *data) -+{ -+ rtk_api_ret_t ret; -+ rtk_priority_select_t PriDec; -+ -+ if (data->qos_table_idx == 0) -+ ret = rtk_qos_priSel_get(PRIDECTBL_IDX0, &PriDec); -+ else -+ ret = rtk_qos_priSel_get(PRIDECTBL_IDX1, &PriDec); -+ -+ if (ret != 0) -+ printk("rtk_qos_priSel_set failed\n"); -+ else { -+ printk("port_pri = %d\n", PriDec.port_pri); -+ printk("dot1q_pri = %d\n", PriDec.dot1q_pri); -+ printk("acl_pri = %d\n", PriDec.acl_pri); -+ printk("dscp_pri = %d\n", PriDec.dscp_pri); -+ printk("cvlan_pri = %d\n", PriDec.cvlan_pri); -+ printk("svlan_pri = %d\n", PriDec.svlan_pri); -+ printk("dmac_pri = %d\n", PriDec.dmac_pri); -+ printk("smac_pri = %d\n", PriDec.smac_pri); -+ } -+} -+ -+void rtk_hal_qos_set_port2table(struct ra_switch_ioctl_data *data) -+{ -+ rtk_api_ret_t ret; -+ -+ ret = rtk_qos_portPriSelIndex_set(data->port, data->qos_table_idx); -+ if (ret != 0) -+ printk("rtk_qos_portPriSelIndex_set failed\n"); -+} -+ -+void rtk_hal_qos_get_port2table(struct ra_switch_ioctl_data *data) -+{ -+ rtk_api_ret_t ret; -+ rtk_qos_priDecTbl_t Index; -+ -+ ret = rtk_qos_portPriSelIndex_get(data->port, &Index); -+ if (ret != 0) -+ printk("rtk_qos_portPriSelIndex_set failed\n"); -+ else -+ printk("port%d belongs to table%d\n", data->port, Index); -+} -+ -+void rtk_hal_qos_set_port2pri(struct ra_switch_ioctl_data *data) -+{ -+ rtk_api_ret_t ret; -+ -+ ret = rtk_qos_portPri_set(data->port, data->qos_pri); -+ if (ret != 0) -+ printk("rtk_qos_portPri_set failed\n"); -+} -+ -+void rtk_hal_qos_get_port2pri(struct ra_switch_ioctl_data *data) -+{ -+ rtk_api_ret_t ret; -+ rtk_pri_t Int_pri; -+ -+ ret = rtk_qos_portPri_get(data->port, &Int_pri); -+ if (ret != 0) -+ printk("rtk_qos_portPri_set failed\n"); -+ else -+ printk("port%d priority = %d\n", data->port, Int_pri); -+} -+ -+void rtk_hal_qos_set_dscp2pri(struct ra_switch_ioctl_data *data) -+{ -+ rtk_api_ret_t ret; -+ -+ ret = rtk_qos_dscpPriRemap_set(data->qos_dscp, data->qos_pri); -+ if (ret != 0) -+ printk("rtk_qos_dscpPriRemap_set failed\n"); -+} -+ -+void rtk_hal_qos_get_dscp2pri(struct ra_switch_ioctl_data *data) -+{ -+ rtk_api_ret_t ret; -+ rtk_pri_t Int_pri; -+ -+ ret = rtk_qos_dscpPriRemap_get(data->qos_dscp, &Int_pri); -+ if (ret != 0) -+ printk("rtk_qos_dscpPriRemap_set failed\n"); -+ else -+ printk("dscp%d priority is %d\n", data->qos_dscp, Int_pri); -+} -+ -+void rtk_hal_qos_set_pri2queue(struct ra_switch_ioctl_data *data) -+{ -+ rtk_api_ret_t ret; -+ rtk_qos_pri2queue_t pri2qid; -+ -+ ret = rtk_qos_priMap_get(8, &pri2qid); -+ pri2qid.pri2queue[data->qos_queue_num] = data->qos_pri; -+ ret = rtk_qos_priMap_set(8, &pri2qid); -+ if (ret != 0) -+ printk("rtk_qos_priMap_set failed\n"); -+} -+ -+void rtk_hal_qos_get_pri2queue(struct ra_switch_ioctl_data *data) -+{ -+ int i; -+ rtk_api_ret_t ret; -+ rtk_qos_pri2queue_t pri2qid; -+ -+ ret = rtk_qos_priMap_get(8, &pri2qid); -+ if (ret != 0) -+ printk("rtk_qos_priMap_get failed\n"); -+ else { -+ for (i = 0; i < 8; i++) -+ printk("pri2qid.pri2queue[%d] = %d\n", i, pri2qid.pri2queue[i]); -+ } -+} -+ -+void rtk_hal_qos_set_queue_weight(struct ra_switch_ioctl_data *data) -+{ -+ rtk_api_ret_t ret; -+ rtk_qos_queue_weights_t qweights; -+ -+ ret = rtk_qos_schedulingQueue_get(data->port, &qweights); -+ qweights.weights[data->qos_queue_num] = data->qos_weight; -+ ret = rtk_qos_schedulingQueue_set(data->port, &qweights); -+ if (ret != 0) -+ printk("rtk_qos_schedulingQueue_set failed\n"); -+} -+ -+void rtk_hal_qos_get_queue_weight(struct ra_switch_ioctl_data *data) -+{ -+ int i; -+ rtk_api_ret_t ret; -+ rtk_qos_queue_weights_t qweights; -+ -+ ret = rtk_qos_schedulingQueue_get(data->port, &qweights); -+ if (ret != 0) -+ printk("rtk_qos_schedulingQueue_get failed\n"); -+ else { -+ printk("=== Port%d queue weight ===\n", data->port); -+ for (i = 0; i < 8; i++) -+ printk("qweights.weights[%d] = %d\n",i ,qweights.weights[i]); -+ } -+} -+ -+void rtk_hal_enable_igmpsnoop(struct ra_switch_ioctl_data *data) -+{ -+ rtk_api_ret_t ret; -+ rtk_portmask_t pmask; -+ -+ -+ ret = rtk_igmp_init(); -+ if (data->on_off == 1) { -+ RTK_PORTMASK_CLEAR(pmask); -+ RTK_PORTMASK_PORT_SET(pmask, EXT_PORT0); -+ ret |= rtk_igmp_static_router_port_set(&pmask); -+ ret |= rtk_igmp_protocol_set(UTP_PORT4, PROTOCOL_IGMPv1, IGMP_ACTION_FORWARD); -+ ret |= rtk_igmp_protocol_set(UTP_PORT4, PROTOCOL_IGMPv2, IGMP_ACTION_FORWARD); -+ ret |= rtk_igmp_protocol_set(UTP_PORT4, PROTOCOL_MLDv1, IGMP_ACTION_FORWARD); -+ ret |= rtk_igmp_protocol_set(EXT_PORT1, PROTOCOL_IGMPv1, IGMP_ACTION_FORWARD); -+ ret |= rtk_igmp_protocol_set(EXT_PORT1, PROTOCOL_IGMPv2, IGMP_ACTION_FORWARD); -+ ret |= rtk_igmp_protocol_set(EXT_PORT1, PROTOCOL_MLDv1, IGMP_ACTION_FORWARD); -+ ret |= rtk_igmp_protocol_set(UTP_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); -+ ret |= rtk_igmp_protocol_set(UTP_PORT1, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); -+ ret |= rtk_igmp_protocol_set(UTP_PORT2, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); -+ ret |= rtk_igmp_protocol_set(UTP_PORT3, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); -+ ret |= rtk_igmp_protocol_set(EXT_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); -+ -+ ret |= rtk_leaky_vlan_set(LEAKY_IPMULTICAST, ENABLED); -+ ret |= rtk_l2_ipMcastForwardRouterPort_set(DISABLED); -+ /* drop unknown multicast packets*/ -+ /* ret |= rtk_trap_unknownMcastPktAction_set(UTP_PORT4, MCAST_IPV4, MCAST_ACTION_DROP);*/ -+ } else { -+ RTK_PORTMASK_CLEAR(pmask); -+ RTK_PORTMASK_PORT_SET(pmask, EXT_PORT0); -+ RTK_PORTMASK_PORT_SET(pmask, EXT_PORT1); -+ ret |= rtk_igmp_protocol_set(UTP_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); -+ ret |= rtk_igmp_protocol_set(UTP_PORT1, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); -+ ret |= rtk_igmp_protocol_set(UTP_PORT2, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); -+ ret |= rtk_igmp_protocol_set(UTP_PORT3, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); -+ ret |= rtk_igmp_protocol_set(EXT_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); -+ -+ ret |= rtk_igmp_static_router_port_set(&pmask); -+ } -+ if(ret != RT_ERR_OK) -+ printk("enable switch igmpsnoop failed\n"); -+} -+ -+void rtk_hal_disable_igmpsnoop(void) -+{ -+ if (rtk_igmp_state_set(DISABLED) != RT_ERR_OK) -+ printk("Disable IGMP SNOOPING failed\n"); -+} -+ -+rtk_api_ret_t rtk_port_phyTestMode_set(rtk_port_t port, rtk_port_phy_test_mode_t mode) -+{ -+ rtk_uint32 data, regData, i; -+ rtk_api_ret_t retVal; -+ -+ RTK_CHK_PORT_IS_UTP(port); -+ -+ if(mode >= PHY_TEST_MODE_END) -+ return RT_ERR_INPUT; -+ -+ if( (mode == PHY_TEST_MODE_2) || (mode == PHY_TEST_MODE_3) ) -+ return RT_ERR_INPUT; -+ -+ if (PHY_TEST_MODE_NORMAL != mode) -+ { -+ /* Other port should be Normal mode */ -+ RTK_SCAN_ALL_LOG_PORT(i) -+ { -+ if(rtk_switch_isUtpPort(i) == RT_ERR_OK) -+ { -+ if(i != port) -+ { -+ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(i), 9, &data)) != RT_ERR_OK) -+ return retVal; -+ -+ if((data & 0xE000) != 0) -+ return RT_ERR_NOT_ALLOWED; -+ } -+ } -+ } -+ } -+ -+ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), 9, &data)) != RT_ERR_OK) -+ return retVal; -+ -+ data &= ~0xE000; -+ data |= (mode << 13); -+ if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), 9, data)) != RT_ERR_OK) -+ return retVal; -+ -+ if (PHY_TEST_MODE_4 == mode) -+ { -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicReg(0x1300, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (regData == 0x0276) || (regData == 0x0597) ) -+ { -+ if ((retVal = rtl8367c_setAsicPHYOCPReg(rtk_switch_port_L2P_get(port), 0xbcc2, 0xF4F4)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ if( (regData == 0x6367) ) -+ { -+ if ((retVal = rtl8367c_setAsicPHYOCPReg(rtk_switch_port_L2P_get(port), 0xa436, 0x80c1)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicPHYOCPReg(rtk_switch_port_L2P_get(port), 0xa438, 0xfe00)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ -+ return RT_ERR_OK; -+} -+ -+void rtk_hal_set_phy_test_mode(struct ra_switch_ioctl_data *data) -+{ -+ rtk_api_ret_t ret; -+ -+ ret = rtk_port_phyTestMode_set(data->port, data->mode); -+ if (ret != RT_ERR_OK) -+ printk("rtk_port_phyTestMode_set failed\n"); -+ else -+ printk("set port%d in test mode %d.\n", data->port, data->mode); -+} -+ -+void rtk_hal_set_port_trunk(struct ra_switch_ioctl_data *data) -+{ -+ -+ rtk_api_ret_t ret; -+ rtk_portmask_t member; -+ int i; -+ -+ RTK_PORTMASK_CLEAR(member); -+ for (i = 0; i < 4; i++) { -+ if (data->port_map & (1 << i)) -+ RTK_PORTMASK_PORT_SET(member, i); -+ } -+ -+ ret = rtk_trunk_port_set(TRUNK_GROUP0, &member); -+ if (ret != RT_ERR_OK) -+ printk("rtk_trunk_port_set failed\n"); -+ -+ ret = rtk_trunk_distributionAlgorithm_set(RTK_WHOLE_SYSTEM, 0x7F); -+ if (ret != RT_ERR_OK) -+ printk("rtk_trunk_distributionAlgorithm_set failed\n"); -+} -+ -+void rtk_hal_vlan_tag(struct ra_switch_ioctl_data *data) -+{ -+ rtk_api_ret_t ret; -+ rtk_vlan_cfg_t vlan; -+ -+ ret = rtk_vlan_get(data->vid, &vlan); -+ if (ret != RT_ERR_OK) -+ printk("rtk_vlan_get failed\n"); -+ else { -+ if (data->on_off == 0) -+ RTK_PORTMASK_PORT_SET(vlan.untag, data->port); -+ else -+ RTK_PORTMASK_PORT_CLEAR(vlan.untag, data->port); -+ -+ ret = rtk_vlan_set(data->vid, &vlan); -+ if (ret != RT_ERR_OK) -+ printk("rtk_vlan_set failed\n"); -+ } -+} -+ -+void rtk_hal_vlan_mode(struct ra_switch_ioctl_data *data) -+{ -+ rtk_vlan_cfg_t vlan1, vlan2; -+ rtk_api_ret_t ret; -+ -+ ret = rtk_vlan_get(1, &vlan1); -+ if (ret != RT_ERR_OK) -+ printk("rtk_vlan_get failed\n"); -+ -+ ret = rtk_vlan_get(2, &vlan2); -+ if (ret != RT_ERR_OK) -+ printk("rtk_vlan_get failed\n"); -+ -+ if (data->mode == 0) { //ivl -+ vlan1.ivl_en = 1; -+ vlan1.fid_msti = 0; -+ rtk_vlan_set(1, &vlan1); -+ vlan2.ivl_en = 1; -+ vlan2.fid_msti = 0; -+ rtk_vlan_set(2, &vlan2); -+ } else if(data->mode == 1) {//svl -+ vlan1.ivl_en = 0; -+ vlan1.fid_msti = 0; -+ rtk_vlan_set(1, &vlan1); -+ vlan2.ivl_en = 0; -+ vlan2.fid_msti = 1; -+ rtk_vlan_set(2, &vlan2); -+ } else -+ printk("mode not supported\n"); -+} -diff --git a/drivers/net/phy/rtk/rtl8367c/rtk_switch.c b/drivers/net/phy/rtk/rtl8367c/rtk_switch.c -new file mode 100644 -index 000000000000..afa3385f3098 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtk_switch.c -@@ -0,0 +1,1794 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76336 $ -+ * $Date: 2017-03-09 10:41:21 +0800 (週四, 09 三月 2017) $ -+ * -+ * Purpose : RTK switch high-level API -+ * Feature : Here is a list of all functions and variables in this module. -+ * -+ */ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#if defined(FORCE_PROBE_RTL8367C) -+static init_state_t init_state = INIT_COMPLETED; -+#elif defined(FORCE_PROBE_RTL8370B) -+static init_state_t init_state = INIT_COMPLETED; -+#elif defined(FORCE_PROBE_RTL8364B) -+static init_state_t init_state = INIT_COMPLETED; -+#elif defined(FORCE_PROBE_RTL8363SC_VB) -+static init_state_t init_state = INIT_COMPLETED; -+#else -+static init_state_t init_state = INIT_NOT_COMPLETED; -+#endif -+ -+#if ((!defined(FORCE_PROBE_RTL8367C) && !defined(FORCE_PROBE_RTL8370B) && !defined(FORCE_PROBE_RTL8364B) && !defined(FORCE_PROBE_RTL8363SC_VB)) || defined(FORCE_PROBE_RTL8367C)) -+static rtk_switch_halCtrl_t rtl8367c_hal_Ctrl = -+{ -+ /* Switch Chip */ -+ CHIP_RTL8367C, -+ -+ /* Logical to Physical */ -+ {0, 1, 2, 3, 4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -+ 6, 7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, -+ -+ /* Physical to Logical */ -+ {UTP_PORT0, UTP_PORT1, UTP_PORT2, UTP_PORT3, UTP_PORT4, UNDEFINE_PORT, EXT_PORT0, EXT_PORT1, -+ UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, -+ UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, -+ UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT}, -+ -+ /* Port Type */ -+ {UTP_PORT, UTP_PORT, UTP_PORT, UTP_PORT, UTP_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, -+ UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, -+ EXT_PORT, EXT_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, -+ UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT}, -+ -+ /* PTP port */ -+ {1, 1, 1, 1, 1, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0 }, -+ -+ /* Valid port mask */ -+ ( (0x1 << UTP_PORT0) | (0x1 << UTP_PORT1) | (0x1 << UTP_PORT2) | (0x1 << UTP_PORT3) | (0x1 << UTP_PORT4) | (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), -+ -+ /* Valid UTP port mask */ -+ ( (0x1 << UTP_PORT0) | (0x1 << UTP_PORT1) | (0x1 << UTP_PORT2) | (0x1 << UTP_PORT3) | (0x1 << UTP_PORT4) ), -+ -+ /* Valid EXT port mask */ -+ ( (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), -+ -+ /* Valid CPU port mask */ -+ 0x00, -+ -+ /* Minimum physical port number */ -+ 0, -+ -+ /* Maxmum physical port number */ -+ 7, -+ -+ /* Physical port mask */ -+ 0xDF, -+ -+ /* Combo Logical port ID */ -+ 4, -+ -+ /* HSG Logical port ID */ -+ EXT_PORT0, -+ -+ /* SGMII Logical portmask */ -+ (0x1 << EXT_PORT0), -+ -+ /* Max Meter ID */ -+ 31, -+ -+ /* MAX LUT Address Number */ -+ 2112, -+ -+ /* Trunk Group Mask */ -+ 0x03 -+}; -+#endif -+ -+#if ((!defined(FORCE_PROBE_RTL8367C) && !defined(FORCE_PROBE_RTL8370B) && !defined(FORCE_PROBE_RTL8364B) && !defined(FORCE_PROBE_RTL8363SC_VB)) || defined(FORCE_PROBE_RTL8370B)) -+static rtk_switch_halCtrl_t rtl8370b_hal_Ctrl = -+{ -+ /* Switch Chip */ -+ CHIP_RTL8370B, -+ -+ /* Logical to Physical */ -+ {0, 1, 2, 3, 4, 5, 6, 7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -+ 8, 9, 10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, -+ -+ /* Physical to Logical */ -+ {UTP_PORT0, UTP_PORT1, UTP_PORT2, UTP_PORT3, UTP_PORT4, UTP_PORT5, UTP_PORT6, UTP_PORT7, -+ EXT_PORT0, EXT_PORT1, EXT_PORT2, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, -+ UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, -+ UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT}, -+ -+ /* Port Type */ -+ {UTP_PORT, UTP_PORT, UTP_PORT, UTP_PORT, UTP_PORT, UTP_PORT, UTP_PORT, UTP_PORT, -+ UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, -+ EXT_PORT, EXT_PORT, EXT_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, -+ UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT}, -+ -+ /* PTP port */ -+ {1, 1, 1, 1, 1, 1, 1, 1, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 1, 1, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0 }, -+ -+ /* Valid port mask */ -+ ( (0x1 << UTP_PORT0) | (0x1 << UTP_PORT1) | (0x1 << UTP_PORT2) | (0x1 << UTP_PORT3) | (0x1 << UTP_PORT4) | (0x1 << UTP_PORT5) | (0x1 << UTP_PORT6) | (0x1 << UTP_PORT7) | (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) | (0x1 << EXT_PORT2) ), -+ -+ /* Valid UTP port mask */ -+ ( (0x1 << UTP_PORT0) | (0x1 << UTP_PORT1) | (0x1 << UTP_PORT2) | (0x1 << UTP_PORT3) | (0x1 << UTP_PORT4) | (0x1 << UTP_PORT5) | (0x1 << UTP_PORT6) | (0x1 << UTP_PORT7) ), -+ -+ /* Valid EXT port mask */ -+ ( (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) | (0x1 << EXT_PORT2) ), -+ -+ /* Valid CPU port mask */ -+ (0x1 << EXT_PORT2), -+ -+ /* Minimum physical port number */ -+ 0, -+ -+ /* Maximum physical port number */ -+ 10, -+ -+ /* Physical port mask */ -+ 0x7FF, -+ -+ /* Combo Logical port ID */ -+ 7, -+ -+ /* HSG Logical port ID */ -+ EXT_PORT1, -+ -+ /* SGMII Logical portmask */ -+ ( (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), -+ -+ /* Max Meter ID */ -+ 63, -+ -+ /* MAX LUT Address Number 4096 + 64*/ -+ 4160, -+ -+ /* Trunk Group Mask */ -+ 0x07 -+}; -+#endif -+ -+#if ((!defined(FORCE_PROBE_RTL8367C) && !defined(FORCE_PROBE_RTL8370B) && !defined(FORCE_PROBE_RTL8364B) && !defined(FORCE_PROBE_RTL8363SC_VB)) || defined(FORCE_PROBE_RTL8364B)) -+static rtk_switch_halCtrl_t rtl8364b_hal_Ctrl = -+{ -+ /* Switch Chip */ -+ CHIP_RTL8364B, -+ -+ /* Logical to Physical */ -+ {0xFF, 1, 0xFF, 3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -+ 6, 7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, -+ -+ /* Physical to Logical */ -+ {UNDEFINE_PORT, UTP_PORT1, UNDEFINE_PORT, UTP_PORT3, UNDEFINE_PORT, UNDEFINE_PORT, EXT_PORT0, EXT_PORT1, -+ UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, -+ UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, -+ UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT}, -+ -+ /* Port Type */ -+ {UNKNOWN_PORT, UTP_PORT, UNKNOWN_PORT, UTP_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, -+ UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, -+ EXT_PORT, EXT_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, -+ UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT}, -+ -+ /* PTP port */ -+ {0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0 }, -+ -+ /* Valid port mask */ -+ ( (0x1 << UTP_PORT1) | (0x1 << UTP_PORT3) | (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), -+ -+ /* Valid UTP port mask */ -+ ( (0x1 << UTP_PORT1) | (0x1 << UTP_PORT3) ), -+ -+ /* Valid EXT port mask */ -+ ( (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), -+ -+ /* Valid CPU port mask */ -+ 0x00, -+ -+ /* Minimum physical port number */ -+ 0, -+ -+ /* Maximum physical port number */ -+ 7, -+ -+ /* Physical port mask */ -+ 0xCA, -+ -+ /* Combo Logical port ID */ -+ 4, -+ -+ /* HSG Logical port ID */ -+ EXT_PORT0, -+ -+ /* SGMII Logical portmask */ -+ ( (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), -+ -+ /* Max Meter ID */ -+ 32, -+ -+ /* MAX LUT Address Number */ -+ 2112, -+ -+ /* Trunk Group Mask */ -+ 0x01 -+}; -+#endif -+ -+#if ((!defined(FORCE_PROBE_RTL8367C) && !defined(FORCE_PROBE_RTL8370B) && !defined(FORCE_PROBE_RTL8364B) && !defined(FORCE_PROBE_RTL8363SC_VB)) || defined(FORCE_PROBE_RTL8363SC_VB)) -+static rtk_switch_halCtrl_t rtl8363sc_vb_hal_Ctrl = -+{ -+ /* Switch Chip */ -+ CHIP_RTL8363SC_VB, -+ -+ /* Logical to Physical */ -+ {0xFF, 0xFF, 1, 3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -+ 6, 7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, -+ -+ /* Physical to Logical */ -+ {UNDEFINE_PORT, UTP_PORT2, UNDEFINE_PORT, UTP_PORT3, UNDEFINE_PORT, UNDEFINE_PORT, EXT_PORT0, EXT_PORT1, -+ UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, -+ UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, -+ UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT}, -+ -+ /* Port Type */ -+ {UNKNOWN_PORT, UNKNOWN_PORT, UTP_PORT, UTP_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, -+ UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, -+ EXT_PORT, EXT_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, -+ UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT}, -+ -+ /* PTP port */ -+ {0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0 }, -+ -+ /* Valid port mask */ -+ ( (0x1 << UTP_PORT2) | (0x1 << UTP_PORT3) | (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), -+ -+ /* Valid UTP port mask */ -+ ( (0x1 << UTP_PORT2) | (0x1 << UTP_PORT3) ), -+ -+ /* Valid EXT port mask */ -+ ( (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), -+ -+ /* Valid CPU port mask */ -+ 0x00, -+ -+ /* Minimum physical port number */ -+ 0, -+ -+ /* Maximum physical port number */ -+ 7, -+ -+ /* Physical port mask */ -+ 0xCA, -+ -+ /* Combo Logical port ID */ -+ 4, -+ -+ /* HSG Logical port ID */ -+ EXT_PORT0, -+ -+ /* SGMII Logical portmask */ -+ ( (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), -+ -+ /* Max Meter ID */ -+ 32, -+ -+ /* MAX LUT Address Number */ -+ 2112, -+ -+ /* Trunk Group Mask */ -+ 0x01 -+}; -+#endif -+ -+#if defined(FORCE_PROBE_RTL8367C) -+static rtk_switch_halCtrl_t *halCtrl = &rtl8367c_hal_Ctrl; -+#elif defined(FORCE_PROBE_RTL8370B) -+static rtk_switch_halCtrl_t *halCtrl = &rtl8370b_hal_Ctrl; -+#elif defined(FORCE_PROBE_RTL8364B) -+static rtk_switch_halCtrl_t *halCtrl = &rtl8364b_hal_Ctrl; -+#elif defined(FORCE_PROBE_RTL8363SC_VB) -+static rtk_switch_halCtrl_t *halCtrl = &rtl8363sc_vb_hal_Ctrl; -+#else -+static rtk_switch_halCtrl_t *halCtrl = NULL; -+#endif -+ -+static rtk_uint32 PatchChipData[210][2] = -+{ -+ {0xa436, 0x8028}, {0xa438, 0x6800}, {0xb82e, 0x0001}, {0xa436, 0xb820}, {0xa438, 0x0090}, {0xa436, 0xa012}, {0xa438, 0x0000}, {0xa436, 0xa014}, {0xa438, 0x2c04}, {0xa438, 0x2c6c}, -+ {0xa438, 0x2c75}, {0xa438, 0x2c77}, {0xa438, 0x1414}, {0xa438, 0x1579}, {0xa438, 0x1536}, {0xa438, 0xc432}, {0xa438, 0x32c0}, {0xa438, 0x42d6}, {0xa438, 0x32b5}, {0xa438, 0x003e}, -+ {0xa438, 0x614c}, {0xa438, 0x1569}, {0xa438, 0xd705}, {0xa438, 0x318c}, {0xa438, 0x42d6}, {0xa438, 0xd702}, {0xa438, 0x31ef}, {0xa438, 0x42d6}, {0xa438, 0x629c}, {0xa438, 0x2c04}, -+ {0xa438, 0x653c}, {0xa438, 0x422a}, {0xa438, 0x5d83}, {0xa438, 0xd06a}, {0xa438, 0xd1b0}, {0xa438, 0x1536}, {0xa438, 0xc43a}, {0xa438, 0x32c0}, {0xa438, 0x42d6}, {0xa438, 0x32b5}, -+ {0xa438, 0x003e}, {0xa438, 0x314a}, {0xa438, 0x42fe}, {0xa438, 0x337b}, {0xa438, 0x02d6}, {0xa438, 0x3063}, {0xa438, 0x0c1b}, {0xa438, 0x22fe}, {0xa438, 0xc435}, {0xa438, 0xd0be}, -+ {0xa438, 0xd1f7}, {0xa438, 0xe0f0}, {0xa438, 0x1a40}, {0xa438, 0xa320}, {0xa438, 0xd702}, {0xa438, 0x154a}, {0xa438, 0xc434}, {0xa438, 0x32c0}, {0xa438, 0x42d6}, {0xa438, 0x32b5}, -+ {0xa438, 0x003e}, {0xa438, 0x60ec}, {0xa438, 0x1569}, {0xa438, 0xd705}, {0xa438, 0x619f}, {0xa438, 0xd702}, {0xa438, 0x414f}, {0xa438, 0x2c2e}, {0xa438, 0x610a}, {0xa438, 0xd705}, -+ {0xa438, 0x5e1f}, {0xa438, 0xc43f}, {0xa438, 0xc88b}, {0xa438, 0xd702}, {0xa438, 0x7fe0}, {0xa438, 0x22f3}, {0xa438, 0xd0a0}, {0xa438, 0xd1b2}, {0xa438, 0xd0c3}, {0xa438, 0xd1c3}, -+ {0xa438, 0x8d01}, {0xa438, 0x1536}, {0xa438, 0xc438}, {0xa438, 0xe0f0}, {0xa438, 0x1a80}, {0xa438, 0xd706}, {0xa438, 0x60c0}, {0xa438, 0xd710}, {0xa438, 0x409e}, {0xa438, 0xa804}, -+ {0xa438, 0xad01}, {0xa438, 0x8804}, {0xa438, 0xd702}, {0xa438, 0x32c0}, {0xa438, 0x42d6}, {0xa438, 0x32b5}, {0xa438, 0x003e}, {0xa438, 0x405b}, {0xa438, 0x1576}, {0xa438, 0x7c9c}, -+ {0xa438, 0x60ec}, {0xa438, 0x1569}, {0xa438, 0xd702}, {0xa438, 0x5d43}, {0xa438, 0x31ef}, {0xa438, 0x02fe}, {0xa438, 0x22d6}, {0xa438, 0x590a}, {0xa438, 0xd706}, {0xa438, 0x5c80}, -+ {0xa438, 0xd702}, {0xa438, 0x5c44}, {0xa438, 0x3063}, {0xa438, 0x02d6}, {0xa438, 0x5be2}, {0xa438, 0x22fb}, {0xa438, 0xa240}, {0xa438, 0xa104}, {0xa438, 0x8c03}, {0xa438, 0x8178}, -+ {0xa438, 0xd701}, {0xa438, 0x31ad}, {0xa438, 0x4917}, {0xa438, 0x8102}, {0xa438, 0x2917}, {0xa438, 0xc302}, {0xa438, 0x268a}, {0xa436, 0xA01A}, {0xa438, 0x0000}, {0xa436, 0xA006}, -+ {0xa438, 0x0fff}, {0xa436, 0xA004}, {0xa438, 0x0689}, {0xa436, 0xA002}, {0xa438, 0x0911}, {0xa436, 0xA000}, {0xa438, 0x7302}, {0xa436, 0xB820}, {0xa438, 0x0010}, {0xa436, 0x8412}, -+ {0xa438, 0xaf84}, {0xa438, 0x1eaf}, {0xa438, 0x8427}, {0xa438, 0xaf84}, {0xa438, 0x27af}, {0xa438, 0x8427}, {0xa438, 0x0251}, {0xa438, 0x6802}, {0xa438, 0x8427}, {0xa438, 0xaf04}, -+ {0xa438, 0x0af8}, {0xa438, 0xf9bf}, {0xa438, 0x5581}, {0xa438, 0x0255}, {0xa438, 0x27ef}, {0xa438, 0x310d}, {0xa438, 0x345b}, {0xa438, 0x0fa3}, {0xa438, 0x032a}, {0xa438, 0xe087}, -+ {0xa438, 0xffac}, {0xa438, 0x2040}, {0xa438, 0xbf56}, {0xa438, 0x7402}, {0xa438, 0x5527}, {0xa438, 0xef31}, {0xa438, 0xef20}, {0xa438, 0xe787}, {0xa438, 0xfee6}, {0xa438, 0x87fd}, -+ {0xa438, 0xd488}, {0xa438, 0x88bf}, {0xa438, 0x5674}, {0xa438, 0x0254}, {0xa438, 0xe3e0}, {0xa438, 0x87ff}, {0xa438, 0xf720}, {0xa438, 0xe487}, {0xa438, 0xffaf}, {0xa438, 0x847e}, -+ {0xa438, 0xe087}, {0xa438, 0xffad}, {0xa438, 0x2016}, {0xa438, 0xe387}, {0xa438, 0xfee2}, {0xa438, 0x87fd}, {0xa438, 0xef45}, {0xa438, 0xbf56}, {0xa438, 0x7402}, {0xa438, 0x54e3}, -+ {0xa438, 0xe087}, {0xa438, 0xfff6}, {0xa438, 0x20e4}, {0xa438, 0x87ff}, {0xa438, 0xfdfc}, {0xa438, 0x0400}, {0xa436, 0xb818}, {0xa438, 0x0407}, {0xa436, 0xb81a}, {0xa438, 0xfffd}, -+ {0xa436, 0xb81c}, {0xa438, 0xfffd}, {0xa436, 0xb81e}, {0xa438, 0xfffd}, {0xa436, 0xb832}, {0xa438, 0x0001}, {0xb820, 0x0000}, {0xb82e, 0x0000}, {0xa436, 0x8028}, {0xa438, 0x0000} -+}; -+ -+static rtk_api_ret_t _rtk_switch_init_8367c(void) -+{ -+ rtk_port_t port; -+ rtk_uint32 retVal; -+ rtk_uint32 regData; -+ rtk_uint32 regValue; -+ -+ if( (retVal = rtl8367c_setAsicReg(0x13c2, 0x0249)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_getAsicReg(0x1301, ®Value)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(0x13c2, 0x0000)) != RT_ERR_OK) -+ return retVal; -+ -+ RTK_SCAN_ALL_LOG_PORT(port) -+ { -+ if(rtk_switch_isUtpPort(port) == RT_ERR_OK) -+ { -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_PORT0_EEECFG + (0x20 * port), RTL8367C_PORT0_EEECFG_EEE_100M_OFFSET, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_PORT0_EEECFG + (0x20 * port), RTL8367C_PORT0_EEECFG_EEE_GIGA_500M_OFFSET, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_PORT0_EEECFG + (0x20 * port), RTL8367C_PORT0_EEECFG_EEE_TX_OFFSET, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_PORT0_EEECFG + (0x20 * port), RTL8367C_PORT0_EEECFG_EEE_RX_OFFSET, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xA428, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ regData &= ~(0x0200); -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xA428, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ if((regValue & 0x00F0) == 0x00A0) -+ { -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xA5D0, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ regData |= 0x0006; -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xA5D0, regData)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ } -+ -+ if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_UTP_FIB_DET, 0x15BB)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x1303, 0x06D6)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x1304, 0x0700)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x13E2, 0x003F)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x13F9, 0x0090)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x121e, 0x03CA)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x1233, 0x0352)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x1237, 0x00a0)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x123a, 0x0030)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x1239, 0x0084)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x0301, 0x1000)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x1349, 0x001F)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x18e0, 0, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x122b, 14, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBits(0x1305, 0xC000, 3)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+static rtk_api_ret_t _rtk_switch_init_8370b(void) -+{ -+ ret_t retVal; -+ rtk_uint32 regData, tmp = 0; -+ rtk_uint32 i, prf, counter; -+ rtk_uint32 long_link[8] = {0x0210, 0x03e8, 0x0218, 0x03f0, 0x0220, 0x03f8, 0x0208, 0x03e0 }; -+ -+ if((retVal = rtl8367c_setAsicRegBits(0x1205, 0x0300, 3)) != RT_ERR_OK) -+ return retVal; -+ -+ -+ for(i=0; i<8; i++) -+ { -+ if ((retVal = rtl8367c_getAsicPHYOCPReg(i, 0xa420, ®Data)) != RT_ERR_OK) -+ return retVal; -+ tmp = regData & 0x7 ; -+ if(tmp == 0x3) -+ { -+ prf = 1; -+ if((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xb83e, 0x6fa9)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xb840, 0xa9)) != RT_ERR_OK) -+ return retVal; -+ for(counter = 0; counter < 10000; counter++); //delay -+ -+ if ((retVal = rtl8367c_getAsicPHYOCPReg(i, 0xb820, ®Data)) != RT_ERR_OK) -+ return retVal; -+ tmp = regData | 0x10; -+ if ((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xb820, tmp)) != RT_ERR_OK) -+ return retVal; -+ for(counter = 0; counter < 10000; counter++); //delay -+ counter = 0; -+ do{ -+ counter = counter + 1; -+ if ((retVal = rtl8367c_getAsicPHYOCPReg(i, 0xb800, ®Data)) != RT_ERR_OK) -+ return retVal; -+ tmp = regData & 0x40; -+ if(tmp != 0) -+ break; -+ } while (counter < 20); //Wait for patch ready = 1... -+ } -+ } -+ if ((retVal = rtl8367c_getAsicReg(0x1d01, ®Data)) != RT_ERR_OK) -+ return retVal; -+ tmp = regData; -+ tmp = tmp | 0x3BE0; /*Broadcast port enable*/ -+ tmp = tmp & 0xFFE0; /*Phy_id = 0 */ -+ if((retVal = rtl8367c_setAsicReg(0x1d01, tmp)) != RT_ERR_OK) -+ return retVal; -+ -+ for(i=0;i < 210; i++) -+ { -+ if((retVal = rtl8367c_setAsicPHYOCPReg(0, PatchChipData[i][0], PatchChipData[i][1])) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ if((retVal = rtl8367c_setAsicReg(0x1d01, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ for(i=0; i < 8; i++) -+ { -+ if((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xa4b4, long_link[i])) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ if (prf == 0x1) -+ { -+ for(i=0; i<8; i++) -+ { -+ if ((retVal = rtl8367c_getAsicPHYOCPReg(i, 0xb820, ®Data)) != RT_ERR_OK) -+ return retVal; -+ tmp = regData & 0xFFEF; -+ if ((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xb820, tmp)) != RT_ERR_OK) -+ return retVal; -+ -+ for(counter = 0; counter < 10000; counter++); //delay -+ -+ counter = 0; -+ do{ -+ counter = counter + 1; -+ if ((retVal = rtl8367c_getAsicPHYOCPReg(i, 0xb800, ®Data)) != RT_ERR_OK) -+ return retVal; -+ tmp = regData & 0x40; -+ if( tmp == 0 ) -+ break; -+ } while (counter < 20); //Wait for patch ready = 1... -+ if ((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xb83e, 0x6f48)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xb840, 0xfa)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ -+ /*Check phy link status*/ -+ for(i=0; i<8; i++) -+ { -+ if ((retVal = rtl8367c_getAsicPHYOCPReg(i, 0xa400, ®Data)) != RT_ERR_OK) -+ return retVal; -+ tmp = regData & 0x800; -+ if(tmp == 0x0) -+ { -+ tmp = regData | 0x200; -+ if ((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xa400, tmp)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ -+ for(counter = 0; counter < 10000; counter++); //delay -+ -+ return RT_ERR_OK; -+} -+ -+static rtk_api_ret_t _rtk_switch_init_8364b(void) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ -+ /*enable EEE, include mac & phy*/ -+ -+ if ((retVal = rtl8367c_setAsicRegBits(0x38, 0x300, 3)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBits(0x78, 0x300, 3)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBits(0xd8, 0x300, 0)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBits(0xf8, 0x300, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicPHYOCPReg(1, 0xa5d0, 6)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicPHYOCPReg(3, 0xa5d0, 6)) != RT_ERR_OK) -+ return retVal; -+ -+ /*PAD para*/ -+ -+ /*EXT1 PAD Para*/ -+ if ((retVal = rtl8367c_getAsicReg(0x1303, ®Data)) != RT_ERR_OK) -+ return retVal; -+ regData &= 0xFFFFFFFE; -+ regData |= 0x250; -+ if((retVal = rtl8367c_setAsicReg(0x1303, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1304, 0x7000, 0)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBits(0x1304, 0x700, 7)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBits(0x13f9, 0x38, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*EXT2 PAD Para*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1303, 10, 1)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBits(0x13E2, 0x1ff, 0x26)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBits(0x13f9, 0x1c0, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ -+ /*SDS PATCH*/ -+ /*SP_CFG_EN_LINK_FIB1G*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®Data)) != RT_ERR_OK) -+ return retVal; -+ regData |= 0x4; -+ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ /*FIB100 Down-speed*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 1, 0, ®Data)) != RT_ERR_OK) -+ return retVal; -+ regData |= 0x20; -+ if((retVal = rtl8367c_setAsicSdsReg(0,1,0, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+static rtk_api_ret_t _rtk_switch_init_8363sc_vb(void) -+{ -+ -+ ret_t retVal; -+ rtk_uint32 regData; -+ -+ /*enable EEE, include mac & phy*/ -+ -+ if ((retVal = rtl8367c_setAsicRegBits(0x38, 0x300, 3)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBits(0x78, 0x300, 3)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBits(0xd8, 0x300, 0)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBits(0xf8, 0x300, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicPHYOCPReg(1, 0xa5d0, 6)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicPHYOCPReg(3, 0xa5d0, 6)) != RT_ERR_OK) -+ return retVal; -+ -+ /*PAD para*/ -+ -+ /*EXT1 PAD Para*/ -+ if ((retVal = rtl8367c_getAsicReg(0x1303, ®Data)) != RT_ERR_OK) -+ return retVal; -+ regData &= 0xFFFFFFFE; -+ regData |= 0x250; -+ if((retVal = rtl8367c_setAsicReg(0x1303, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1304, 0x7000, 0)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBits(0x1304, 0x700, 7)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBits(0x13f9, 0x38, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*EXT2 PAD Para*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1303, 10, 1)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBits(0x13E2, 0x1ff, 0x26)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBits(0x13f9, 0x1c0, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ -+ /*SDS PATCH*/ -+ /*SP_CFG_EN_LINK_FIB1G*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®Data)) != RT_ERR_OK) -+ return retVal; -+ regData |= 0x4; -+ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ /*FIB100 Down-speed*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 1, 0, ®Data)) != RT_ERR_OK) -+ return retVal; -+ regData |= 0x20; -+ if((retVal = rtl8367c_setAsicSdsReg(0,1,0, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_switch_probe -+ * Description: -+ * Probe switch -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Switch probed -+ * RT_ERR_FAILED - Switch Unprobed. -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_switch_probe(switch_chip_t *pSwitchChip) -+{ -+#if defined(FORCE_PROBE_RTL8367C) -+ -+ *pSwitchChip = CHIP_RTL8367C; -+ halCtrl = &rtl8367c_hal_Ctrl; -+ -+#elif defined(FORCE_PROBE_RTL8370B) -+ -+ *pSwitchChip = CHIP_RTL8370B; -+ halCtrl = &rtl8370b_hal_Ctrl; -+ -+#elif defined(FORCE_PROBE_RTL8364B) -+ -+ *pSwitchChip = CHIP_RTL8364B; -+ halCtrl = &rtl8364b_hal_Ctrl; -+ -+#elif defined(FORCE_PROBE_RTL8363SC_VB) -+ -+ *pSwitchChip = CHIP_RTL8363SC_VB; -+ halCtrl = &rtl8363sc_vb_hal_Ctrl; -+ -+#else -+ rtk_uint32 retVal; -+ rtk_uint32 data, regValue; -+ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicReg(0x1300, &data)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicReg(0x1301, ®Value)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) -+ return retVal; -+ -+ switch (data) -+ { -+ case 0x0276: -+ case 0x0597: -+ case 0x6367: -+ *pSwitchChip = CHIP_RTL8367C; -+ halCtrl = &rtl8367c_hal_Ctrl; -+ break; -+ case 0x0652: -+ case 0x6368: -+ *pSwitchChip = CHIP_RTL8370B; -+ halCtrl = &rtl8370b_hal_Ctrl; -+ break; -+ case 0x0801: -+ case 0x6511: -+ if( (regValue & 0x00F0) == 0x0080) -+ { -+ *pSwitchChip = CHIP_RTL8363SC_VB; -+ halCtrl = &rtl8363sc_vb_hal_Ctrl; -+ } -+ else -+ { -+ *pSwitchChip = CHIP_RTL8364B; -+ halCtrl = &rtl8364b_hal_Ctrl; -+ } -+ break; -+ default: -+ return RT_ERR_FAILED; -+ } -+#endif -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_switch_initialState_set -+ * Description: -+ * Set initial status -+ * Input: -+ * state - Initial state; -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Initialized -+ * RT_ERR_FAILED - Uninitialized -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_switch_initialState_set(init_state_t state) -+{ -+ if(state >= INIT_STATE_END) -+ return RT_ERR_FAILED; -+ -+ init_state = state; -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_switch_initialState_get -+ * Description: -+ * Get initial status -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * INIT_COMPLETED - Initialized -+ * INIT_NOT_COMPLETED - Uninitialized -+ * Note: -+ * -+ */ -+init_state_t rtk_switch_initialState_get(void) -+{ -+ return init_state; -+} -+ -+/* Function Name: -+ * rtk_switch_logicalPortCheck -+ * Description: -+ * Check logical port ID. -+ * Input: -+ * logicalPort - logical port ID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Port ID is correct -+ * RT_ERR_FAILED - Port ID is not correct -+ * RT_ERR_NOT_INIT - Not Initialize -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_switch_logicalPortCheck(rtk_port_t logicalPort) -+{ -+ if(init_state != INIT_COMPLETED) -+ return RT_ERR_NOT_INIT; -+ -+ if(logicalPort >= RTK_SWITCH_PORT_NUM) -+ return RT_ERR_FAILED; -+ -+ if(halCtrl->l2p_port[logicalPort] == 0xFF) -+ return RT_ERR_FAILED; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_switch_isUtpPort -+ * Description: -+ * Check is logical port a UTP port -+ * Input: -+ * logicalPort - logical port ID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Port ID is a UTP port -+ * RT_ERR_FAILED - Port ID is not a UTP port -+ * RT_ERR_NOT_INIT - Not Initialize -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_switch_isUtpPort(rtk_port_t logicalPort) -+{ -+ if(init_state != INIT_COMPLETED) -+ return RT_ERR_NOT_INIT; -+ -+ if(logicalPort >= RTK_SWITCH_PORT_NUM) -+ return RT_ERR_FAILED; -+ -+ if(halCtrl->log_port_type[logicalPort] == UTP_PORT) -+ return RT_ERR_OK; -+ else -+ return RT_ERR_FAILED; -+} -+ -+/* Function Name: -+ * rtk_switch_isExtPort -+ * Description: -+ * Check is logical port a Extension port -+ * Input: -+ * logicalPort - logical port ID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Port ID is a EXT port -+ * RT_ERR_FAILED - Port ID is not a EXT port -+ * RT_ERR_NOT_INIT - Not Initialize -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_switch_isExtPort(rtk_port_t logicalPort) -+{ -+ if(init_state != INIT_COMPLETED) -+ return RT_ERR_NOT_INIT; -+ -+ if(logicalPort >= RTK_SWITCH_PORT_NUM) -+ return RT_ERR_FAILED; -+ -+ if(halCtrl->log_port_type[logicalPort] == EXT_PORT) -+ return RT_ERR_OK; -+ else -+ return RT_ERR_FAILED; -+} -+ -+ -+/* Function Name: -+ * rtk_switch_isHsgPort -+ * Description: -+ * Check is logical port a HSG port -+ * Input: -+ * logicalPort - logical port ID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Port ID is a HSG port -+ * RT_ERR_FAILED - Port ID is not a HSG port -+ * RT_ERR_NOT_INIT - Not Initialize -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_switch_isHsgPort(rtk_port_t logicalPort) -+{ -+ if(init_state != INIT_COMPLETED) -+ return RT_ERR_NOT_INIT; -+ -+ if(logicalPort >= RTK_SWITCH_PORT_NUM) -+ return RT_ERR_FAILED; -+ -+ if(logicalPort == halCtrl->hsg_logical_port) -+ return RT_ERR_OK; -+ else -+ return RT_ERR_FAILED; -+} -+ -+/* Function Name: -+ * rtk_switch_isSgmiiPort -+ * Description: -+ * Check is logical port a SGMII port -+ * Input: -+ * logicalPort - logical port ID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Port ID is a SGMII port -+ * RT_ERR_FAILED - Port ID is not a SGMII port -+ * RT_ERR_NOT_INIT - Not Initialize -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_switch_isSgmiiPort(rtk_port_t logicalPort) -+{ -+ if(init_state != INIT_COMPLETED) -+ return RT_ERR_NOT_INIT; -+ -+ if(logicalPort >= RTK_SWITCH_PORT_NUM) -+ return RT_ERR_FAILED; -+ -+ if( ((0x01 << logicalPort) & halCtrl->sg_logical_portmask) != 0) -+ return RT_ERR_OK; -+ else -+ return RT_ERR_FAILED; -+} -+ -+/* Function Name: -+ * rtk_switch_isCPUPort -+ * Description: -+ * Check is logical port a CPU port -+ * Input: -+ * logicalPort - logical port ID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Port ID is a CPU port -+ * RT_ERR_FAILED - Port ID is not a CPU port -+ * RT_ERR_NOT_INIT - Not Initialize -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_switch_isCPUPort(rtk_port_t logicalPort) -+{ -+ if(init_state != INIT_COMPLETED) -+ return RT_ERR_NOT_INIT; -+ -+ if(logicalPort >= RTK_SWITCH_PORT_NUM) -+ return RT_ERR_FAILED; -+ -+ if( ((0x01 << logicalPort) & halCtrl->valid_cpu_portmask) != 0) -+ return RT_ERR_OK; -+ else -+ return RT_ERR_FAILED; -+} -+ -+/* Function Name: -+ * rtk_switch_isComboPort -+ * Description: -+ * Check is logical port a Combo port -+ * Input: -+ * logicalPort - logical port ID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Port ID is a combo port -+ * RT_ERR_FAILED - Port ID is not a combo port -+ * RT_ERR_NOT_INIT - Not Initialize -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_switch_isComboPort(rtk_port_t logicalPort) -+{ -+ if(init_state != INIT_COMPLETED) -+ return RT_ERR_NOT_INIT; -+ -+ if(logicalPort >= RTK_SWITCH_PORT_NUM) -+ return RT_ERR_FAILED; -+ -+ if(halCtrl->combo_logical_port == logicalPort) -+ return RT_ERR_OK; -+ else -+ return RT_ERR_FAILED; -+} -+ -+/* Function Name: -+ * rtk_switch_ComboPort_get -+ * Description: -+ * Get Combo port ID -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * Port ID of combo port -+ * Note: -+ * -+ */ -+rtk_uint32 rtk_switch_ComboPort_get(void) -+{ -+ return halCtrl->combo_logical_port; -+} -+ -+/* Function Name: -+ * rtk_switch_isPtpPort -+ * Description: -+ * Check is logical port a PTP port -+ * Input: -+ * logicalPort - logical port ID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Port ID is a PTP port -+ * RT_ERR_FAILED - Port ID is not a PTP port -+ * RT_ERR_NOT_INIT - Not Initialize -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_switch_isPtpPort(rtk_port_t logicalPort) -+{ -+ if(init_state != INIT_COMPLETED) -+ return RT_ERR_NOT_INIT; -+ -+ if(logicalPort >= RTK_SWITCH_PORT_NUM) -+ return RT_ERR_FAILED; -+ -+ if(halCtrl->ptp_port[logicalPort] == 1) -+ return RT_ERR_OK; -+ else -+ return RT_ERR_FAILED; -+} -+ -+/* Function Name: -+ * rtk_switch_port_L2P_get -+ * Description: -+ * Get physical port ID -+ * Input: -+ * logicalPort - logical port ID -+ * Output: -+ * None -+ * Return: -+ * Physical port ID -+ * Note: -+ * -+ */ -+rtk_uint32 rtk_switch_port_L2P_get(rtk_port_t logicalPort) -+{ -+ if(init_state != INIT_COMPLETED) -+ return UNDEFINE_PHY_PORT; -+ -+ if(logicalPort >= RTK_SWITCH_PORT_NUM) -+ return UNDEFINE_PHY_PORT; -+ -+ return (halCtrl->l2p_port[logicalPort]); -+} -+ -+/* Function Name: -+ * rtk_switch_port_P2L_get -+ * Description: -+ * Get logical port ID -+ * Input: -+ * physicalPort - physical port ID -+ * Output: -+ * None -+ * Return: -+ * logical port ID -+ * Note: -+ * -+ */ -+rtk_port_t rtk_switch_port_P2L_get(rtk_uint32 physicalPort) -+{ -+ if(init_state != INIT_COMPLETED) -+ return UNDEFINE_PORT; -+ -+ if(physicalPort >= RTK_SWITCH_PORT_NUM) -+ return UNDEFINE_PORT; -+ -+ return (halCtrl->p2l_port[physicalPort]); -+} -+ -+/* Function Name: -+ * rtk_switch_isPortMaskValid -+ * Description: -+ * Check portmask is valid or not -+ * Input: -+ * pPmask - logical port mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - port mask is valid -+ * RT_ERR_FAILED - port mask is not valid -+ * RT_ERR_NOT_INIT - Not Initialize -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_switch_isPortMaskValid(rtk_portmask_t *pPmask) -+{ -+ if(init_state != INIT_COMPLETED) -+ return RT_ERR_NOT_INIT; -+ -+ if(NULL == pPmask) -+ return RT_ERR_NULL_POINTER; -+ -+ if( (pPmask->bits[0] | halCtrl->valid_portmask) != halCtrl->valid_portmask ) -+ return RT_ERR_FAILED; -+ else -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_switch_isPortMaskUtp -+ * Description: -+ * Check all ports in portmask are only UTP port -+ * Input: -+ * pPmask - logical port mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Only UTP port in port mask -+ * RT_ERR_FAILED - Not only UTP port in port mask -+ * RT_ERR_NOT_INIT - Not Initialize -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_switch_isPortMaskUtp(rtk_portmask_t *pPmask) -+{ -+ if(init_state != INIT_COMPLETED) -+ return RT_ERR_NOT_INIT; -+ -+ if(NULL == pPmask) -+ return RT_ERR_NULL_POINTER; -+ -+ if( (pPmask->bits[0] | halCtrl->valid_utp_portmask) != halCtrl->valid_utp_portmask ) -+ return RT_ERR_FAILED; -+ else -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_switch_isPortMaskExt -+ * Description: -+ * Check all ports in portmask are only EXT port -+ * Input: -+ * pPmask - logical port mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Only EXT port in port mask -+ * RT_ERR_FAILED - Not only EXT port in port mask -+ * RT_ERR_NOT_INIT - Not Initialize -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_switch_isPortMaskExt(rtk_portmask_t *pPmask) -+{ -+ if(init_state != INIT_COMPLETED) -+ return RT_ERR_NOT_INIT; -+ -+ if(NULL == pPmask) -+ return RT_ERR_NULL_POINTER; -+ -+ if( (pPmask->bits[0] | halCtrl->valid_ext_portmask) != halCtrl->valid_ext_portmask ) -+ return RT_ERR_FAILED; -+ else -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_switch_portmask_L2P_get -+ * Description: -+ * Get physical portmask from logical portmask -+ * Input: -+ * pLogicalPmask - logical port mask -+ * Output: -+ * pPhysicalPortmask - physical port mask -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_NOT_INIT - Not Initialize -+ * RT_ERR_NULL_POINTER - Null pointer -+ * RT_ERR_PORT_MASK - Error port mask -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_switch_portmask_L2P_get(rtk_portmask_t *pLogicalPmask, rtk_uint32 *pPhysicalPortmask) -+{ -+ rtk_uint32 log_port, phy_port; -+ -+ if(init_state != INIT_COMPLETED) -+ return RT_ERR_NOT_INIT; -+ -+ if(NULL == pLogicalPmask) -+ return RT_ERR_NULL_POINTER; -+ -+ if(NULL == pPhysicalPortmask) -+ return RT_ERR_NULL_POINTER; -+ -+ if(rtk_switch_isPortMaskValid(pLogicalPmask) != RT_ERR_OK) -+ return RT_ERR_PORT_MASK; -+ -+ /* reset physical port mask */ -+ *pPhysicalPortmask = 0; -+ -+ RTK_PORTMASK_SCAN((*pLogicalPmask), log_port) -+ { -+ phy_port = rtk_switch_port_L2P_get((rtk_port_t)log_port); -+ *pPhysicalPortmask |= (0x0001 << phy_port); -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_switch_portmask_P2L_get -+ * Description: -+ * Get logical portmask from physical portmask -+ * Input: -+ * physicalPortmask - physical port mask -+ * Output: -+ * pLogicalPmask - logical port mask -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_NOT_INIT - Not Initialize -+ * RT_ERR_NULL_POINTER - Null pointer -+ * RT_ERR_PORT_MASK - Error port mask -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_switch_portmask_P2L_get(rtk_uint32 physicalPortmask, rtk_portmask_t *pLogicalPmask) -+{ -+ rtk_uint32 log_port, phy_port; -+ -+ if(init_state != INIT_COMPLETED) -+ return RT_ERR_NOT_INIT; -+ -+ if(NULL == pLogicalPmask) -+ return RT_ERR_NULL_POINTER; -+ -+ RTK_PORTMASK_CLEAR(*pLogicalPmask); -+ -+ for(phy_port = halCtrl->min_phy_port; phy_port <= halCtrl->max_phy_port; phy_port++) -+ { -+ if(physicalPortmask & (0x0001 << phy_port)) -+ { -+ log_port = rtk_switch_port_P2L_get(phy_port); -+ if(log_port != UNDEFINE_PORT) -+ { -+ RTK_PORTMASK_PORT_SET(*pLogicalPmask, log_port); -+ } -+ } -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_switch_phyPortMask_get -+ * Description: -+ * Get physical portmask -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * 0x00 - Not Initialize -+ * Other value - Physical port mask -+ * Note: -+ * -+ */ -+rtk_uint32 rtk_switch_phyPortMask_get(void) -+{ -+ if(init_state != INIT_COMPLETED) -+ return 0x00; /* No port in portmask */ -+ -+ return (halCtrl->phy_portmask); -+} -+ -+/* Function Name: -+ * rtk_switch_logPortMask_get -+ * Description: -+ * Get Logical portmask -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_NOT_INIT - Not Initialize -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_switch_logPortMask_get(rtk_portmask_t *pPortmask) -+{ -+ if(init_state != INIT_COMPLETED) -+ return RT_ERR_FAILED; -+ -+ if(NULL == pPortmask) -+ return RT_ERR_NULL_POINTER; -+ -+ pPortmask->bits[0] = halCtrl->valid_portmask; -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_switch_init -+ * Description: -+ * Set chip to default configuration environment -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * The API can set chip registers to default configuration for different release chip model. -+ */ -+rtk_api_ret_t rtk_switch_init(void) -+{ -+ rtk_uint32 retVal; -+ rtl8367c_rma_t rmaCfg; -+ switch_chip_t switchChip; -+ -+ /* probe switch */ -+ if((retVal = rtk_switch_probe(&switchChip)) != RT_ERR_OK) -+ return retVal; -+ -+ /* Set initial state */ -+ -+ if((retVal = rtk_switch_initialState_set(INIT_COMPLETED)) != RT_ERR_OK) -+ return retVal; -+ -+ /* Initial */ -+ switch(switchChip) -+ { -+ case CHIP_RTL8367C: -+ if((retVal = _rtk_switch_init_8367c()) != RT_ERR_OK) -+ return retVal; -+ break; -+ case CHIP_RTL8370B: -+ if((retVal = _rtk_switch_init_8370b()) != RT_ERR_OK) -+ return retVal; -+ break; -+ case CHIP_RTL8364B: -+ if((retVal = _rtk_switch_init_8364b()) != RT_ERR_OK) -+ return retVal; -+ break; -+ case CHIP_RTL8363SC_VB: -+ if((retVal = _rtk_switch_init_8363sc_vb()) != RT_ERR_OK) -+ return retVal; -+ break; -+ default: -+ return RT_ERR_CHIP_NOT_FOUND; -+ } -+ -+ /* Set Old max packet length to 16K */ -+ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_MAX_LENGTH_LIMINT_IPG, RTL8367C_MAX_LENTH_CTRL_MASK, 3)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_MAX_LEN_RX_TX, RTL8367C_MAX_LEN_RX_TX_MASK, 3)) != RT_ERR_OK) -+ return retVal; -+ -+ /* ACL Mode */ -+ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_ACL_ACCESS_MODE, RTL8367C_ACL_ACCESS_MODE_MASK, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /* Max rate */ -+ if((retVal = rtk_rate_igrBandwidthCtrlRate_set(halCtrl->hsg_logical_port, RTL8367C_QOS_RATE_INPUT_MAX_HSG, DISABLED, ENABLED)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtk_rate_egrBandwidthCtrlRate_set(halCtrl->hsg_logical_port, RTL8367C_QOS_RATE_INPUT_MAX_HSG, ENABLED)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x03fa, 0x0007)) != RT_ERR_OK) -+ return retVal; -+ -+ /* Change unknown DA to per port setting */ -+ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_PORT_SECURIT_CTRL_REG, RTL8367C_UNKNOWN_UNICAST_DA_BEHAVE_MASK, 3)) != RT_ERR_OK) -+ return retVal; -+ -+ /* LUT lookup OP = 1 */ -+ if ((retVal = rtl8367c_setAsicLutIpLookupMethod(1))!=RT_ERR_OK) -+ return retVal; -+ -+ /* Set RMA */ -+ rmaCfg.portiso_leaky = 0; -+ rmaCfg.vlan_leaky = 0; -+ rmaCfg.keep_format = 0; -+ rmaCfg.trap_priority = 0; -+ rmaCfg.discard_storm_filter = 0; -+ rmaCfg.operation = 0; -+ if ((retVal = rtl8367c_setAsicRma(2, &rmaCfg))!=RT_ERR_OK) -+ return retVal; -+ -+ /* Enable TX Mirror isolation leaky */ -+ if ((retVal = rtl8367c_setAsicPortMirrorIsolationTxLeaky(ENABLED)) != RT_ERR_OK) -+ return retVal; -+ -+ /* INT EN */ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IO_MISC_FUNC, RTL8367C_INT_EN_OFFSET, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_switch_portMaxPktLen_set -+ * Description: -+ * Set Max packet length -+ * Input: -+ * port - Port ID -+ * speed - Speed -+ * cfgId - Configuration ID -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * Note: -+ */ -+rtk_api_ret_t rtk_switch_portMaxPktLen_set(rtk_port_t port, rtk_switch_maxPktLen_linkSpeed_t speed, rtk_uint32 cfgId) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(speed >= MAXPKTLEN_LINK_SPEED_END) -+ return RT_ERR_INPUT; -+ -+ if(cfgId > MAXPKTLEN_CFG_ID_MAX) -+ return RT_ERR_INPUT; -+ -+ if((retVal = rtl8367c_setAsicMaxLength(rtk_switch_port_L2P_get(port), (rtk_uint32)speed, cfgId)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_switch_portMaxPktLen_get -+ * Description: -+ * Get Max packet length -+ * Input: -+ * port - Port ID -+ * speed - Speed -+ * Output: -+ * pCfgId - Configuration ID -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * Note: -+ */ -+rtk_api_ret_t rtk_switch_portMaxPktLen_get(rtk_port_t port, rtk_switch_maxPktLen_linkSpeed_t speed, rtk_uint32 *pCfgId) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(speed >= MAXPKTLEN_LINK_SPEED_END) -+ return RT_ERR_INPUT; -+ -+ if(NULL == pCfgId) -+ return RT_ERR_NULL_POINTER; -+ -+ if((retVal = rtl8367c_getAsicMaxLength(rtk_switch_port_L2P_get(port), (rtk_uint32)speed, pCfgId)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_switch_maxPktLenCfg_set -+ * Description: -+ * Set Max packet length configuration -+ * Input: -+ * cfgId - Configuration ID -+ * pktLen - Max packet length -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * Note: -+ */ -+rtk_api_ret_t rtk_switch_maxPktLenCfg_set(rtk_uint32 cfgId, rtk_uint32 pktLen) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(cfgId > MAXPKTLEN_CFG_ID_MAX) -+ return RT_ERR_INPUT; -+ -+ if(pktLen > RTK_SWITCH_MAX_PKTLEN) -+ return RT_ERR_INPUT; -+ -+ if((retVal = rtl8367c_setAsicMaxLengthCfg(cfgId, pktLen)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_switch_maxPktLenCfg_get -+ * Description: -+ * Get Max packet length configuration -+ * Input: -+ * cfgId - Configuration ID -+ * pPktLen - Max packet length -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * Note: -+ */ -+rtk_api_ret_t rtk_switch_maxPktLenCfg_get(rtk_uint32 cfgId, rtk_uint32 *pPktLen) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(cfgId > MAXPKTLEN_CFG_ID_MAX) -+ return RT_ERR_INPUT; -+ -+ if(NULL == pPktLen) -+ return RT_ERR_NULL_POINTER; -+ -+ if((retVal = rtl8367c_getAsicMaxLengthCfg(cfgId, pPktLen)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_switch_greenEthernet_set -+ * Description: -+ * Set all Ports Green Ethernet state. -+ * Input: -+ * enable - Green Ethernet state. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_ENABLE - Invalid enable input. -+ * Note: -+ * This API can set all Ports Green Ethernet state. -+ * The configuration is as following: -+ * - DISABLE -+ * - ENABLE -+ */ -+rtk_api_ret_t rtk_switch_greenEthernet_set(rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 port; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ RTK_SCAN_ALL_LOG_PORT(port) -+ { -+ if(rtk_switch_isUtpPort(port) == RT_ERR_OK) -+ { -+ if ((retVal = rtl8367c_setAsicPowerSaving(rtk_switch_port_L2P_get(port),enable))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicGreenEthernet(rtk_switch_port_L2P_get(port), enable))!=RT_ERR_OK) -+ return retVal; -+ } -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_switch_greenEthernet_get -+ * Description: -+ * Get all Ports Green Ethernet state. -+ * Input: -+ * None -+ * Output: -+ * pEnable - Green Ethernet state. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * This API can get Green Ethernet state. -+ */ -+rtk_api_ret_t rtk_switch_greenEthernet_get(rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 port; -+ rtk_uint32 state; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ RTK_SCAN_ALL_LOG_PORT(port) -+ { -+ if(rtk_switch_isUtpPort(port) == RT_ERR_OK) -+ { -+ if ((retVal = rtl8367c_getAsicPowerSaving(rtk_switch_port_L2P_get(port), &state))!=RT_ERR_OK) -+ return retVal; -+ -+ if(state == DISABLED) -+ { -+ *pEnable = DISABLED; -+ return RT_ERR_OK; -+ } -+ -+ if ((retVal = rtl8367c_getAsicGreenEthernet(rtk_switch_port_L2P_get(port), &state))!=RT_ERR_OK) -+ return retVal; -+ -+ if(state == DISABLED) -+ { -+ *pEnable = DISABLED; -+ return RT_ERR_OK; -+ } -+ } -+ } -+ -+ *pEnable = ENABLED; -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_switch_maxLogicalPort_get -+ * Description: -+ * Get Max logical port ID -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * Max logical port -+ * Note: -+ * This API can get max logical port -+ */ -+rtk_port_t rtk_switch_maxLogicalPort_get(void) -+{ -+ rtk_port_t port, maxLogicalPort = 0; -+ -+ /* Check initialization state */ -+ if(rtk_switch_initialState_get() != INIT_COMPLETED) -+ { -+ return UNDEFINE_PORT; -+ } -+ -+ for(port = 0; port < RTK_SWITCH_PORT_NUM; port++) -+ { -+ if( (halCtrl->log_port_type[port] == UTP_PORT) || (halCtrl->log_port_type[port] == EXT_PORT) ) -+ maxLogicalPort = port; -+ } -+ -+ return maxLogicalPort; -+} -+ -+/* Function Name: -+ * rtk_switch_maxMeterId_get -+ * Description: -+ * Get Max Meter ID -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * 0x00 - Not Initialize -+ * Other value - Max Meter ID -+ * Note: -+ * -+ */ -+rtk_uint32 rtk_switch_maxMeterId_get(void) -+{ -+ if(init_state != INIT_COMPLETED) -+ return 0x00; -+ -+ return (halCtrl->max_meter_id); -+} -+ -+/* Function Name: -+ * rtk_switch_maxLutAddrNumber_get -+ * Description: -+ * Get Max LUT Address number -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * 0x00 - Not Initialize -+ * Other value - Max LUT Address number -+ * Note: -+ * -+ */ -+rtk_uint32 rtk_switch_maxLutAddrNumber_get(void) -+{ -+ if(init_state != INIT_COMPLETED) -+ return 0x00; -+ -+ return (halCtrl->max_lut_addr_num); -+} -+ -+/* Function Name: -+ * rtk_switch_isValidTrunkGrpId -+ * Description: -+ * Check if trunk group is valid or not -+ * Input: -+ * grpId - Group ID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Trunk Group ID is valid -+ * RT_ERR_LA_TRUNK_ID - Trunk Group ID is not valid -+ * Note: -+ * -+ */ -+rtk_uint32 rtk_switch_isValidTrunkGrpId(rtk_uint32 grpId) -+{ -+ if(init_state != INIT_COMPLETED) -+ return 0x00; -+ -+ if( (halCtrl->trunk_group_mask & (0x01 << grpId) ) != 0) -+ return RT_ERR_OK; -+ else -+ return RT_ERR_LA_TRUNK_ID; -+ -+} -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv.c -new file mode 100644 -index 000000000000..7858edcf530a ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv.c -@@ -0,0 +1,639 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : -+ * -+ */ -+ -+#include -+ -+#if defined(RTK_X86_ASICDRV) -+#include -+#else -+#include -+#endif -+ -+/*for driver verify testing only*/ -+#ifdef CONFIG_RTL8367C_ASICDRV_TEST -+#define CLE_VIRTUAL_REG_SIZE 0x10000 -+rtk_uint16 CleVirtualReg[CLE_VIRTUAL_REG_SIZE]; -+#endif -+ -+#if defined(CONFIG_RTL865X_CLE) || defined (RTK_X86_CLE) -+rtk_uint32 cleDebuggingDisplay; -+#endif -+ -+#ifdef EMBEDDED_SUPPORT -+extern void setReg(rtk_uint16, rtk_uint16); -+extern rtk_uint16 getReg(rtk_uint16); -+#endif -+ -+/* Function Name: -+ * rtl8367c_setAsicRegBit -+ * Description: -+ * Set a bit value of a specified register -+ * Input: -+ * reg - register's address -+ * bit - bit location -+ * value - value to set. It can be value 0 or 1. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter -+ * Note: -+ * Set a bit of a specified register to 1 or 0. -+ */ -+ret_t rtl8367c_setAsicRegBit(rtk_uint32 reg, rtk_uint32 bit, rtk_uint32 value) -+{ -+ -+#if defined(RTK_X86_ASICDRV) -+ rtk_uint32 regData; -+ ret_t retVal; -+ -+ if(bit >= RTL8367C_REGBITLENGTH) -+ return RT_ERR_INPUT; -+ -+ retVal = Access_Read(reg, 2, ®Data); -+ if(TRUE != retVal) -+ return RT_ERR_SMI; -+ -+ if(0x8367B == cleDebuggingDisplay) -+ PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); -+ -+ if(value) -+ regData = regData | (1 << bit); -+ else -+ regData = regData & (~(1 << bit)); -+ -+ retVal = Access_Write(reg,2, regData); -+ if(TRUE != retVal) -+ return RT_ERR_SMI; -+ -+ if(0x8367B == cleDebuggingDisplay) -+ PRINT("W[0x%4.4x]=0x%4.4x\n", reg, regData); -+ -+ -+#elif defined(CONFIG_RTL8367C_ASICDRV_TEST) -+ -+ if(bit >= RTL8367C_REGBITLENGTH) -+ return RT_ERR_INPUT; -+ -+ else if(reg >= CLE_VIRTUAL_REG_SIZE) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(value) -+ { -+ CleVirtualReg[reg] = CleVirtualReg[reg] | (1 << bit); -+ } -+ else -+ { -+ CleVirtualReg[reg] = CleVirtualReg[reg] & (~(1 << bit)); -+ } -+ -+ if(0x8367B == cleDebuggingDisplay) -+ PRINT("W[0x%4.4x]=0x%4.4x\n", reg, CleVirtualReg[reg]); -+ -+#elif defined(EMBEDDED_SUPPORT) -+ rtk_uint16 tmp; -+ -+ if(reg > RTL8367C_REGDATAMAX || value > 1) -+ return RT_ERR_INPUT; -+ -+ tmp = getReg(reg); -+ tmp &= (1 << bitIdx); -+ tmp |= (value << bitIdx); -+ setReg(reg, tmp); -+ -+#else -+ rtk_uint32 regData; -+ ret_t retVal; -+ -+ if(bit >= RTL8367C_REGBITLENGTH) -+ return RT_ERR_INPUT; -+ -+ retVal = smi_read(reg, ®Data); -+ if(retVal != RT_ERR_OK) -+ return RT_ERR_SMI; -+ -+ #ifdef CONFIG_RTL865X_CLE -+ if(0x8367B == cleDebuggingDisplay) -+ PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); -+ #endif -+ if(value) -+ regData = regData | (1 << bit); -+ else -+ regData = regData & (~(1 << bit)); -+ -+ retVal = smi_write(reg, regData); -+ if(retVal != RT_ERR_OK) -+ return RT_ERR_SMI; -+ -+ #ifdef CONFIG_RTL865X_CLE -+ if(0x8367B == cleDebuggingDisplay) -+ PRINT("W[0x%4.4x]=0x%4.4x\n", reg, regData); -+ #endif -+ -+#endif -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicRegBit -+ * Description: -+ * Get a bit value of a specified register -+ * Input: -+ * reg - register's address -+ * bit - bit location -+ * value - value to get. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicRegBit(rtk_uint32 reg, rtk_uint32 bit, rtk_uint32 *pValue) -+{ -+ -+#if defined(RTK_X86_ASICDRV) -+ -+ rtk_uint32 regData; -+ ret_t retVal; -+ -+ if(bit >= RTL8367C_REGBITLENGTH) -+ return RT_ERR_INPUT; -+ -+ retVal = Access_Read(reg, 2, ®Data); -+ if(TRUE != retVal) -+ return RT_ERR_SMI; -+ -+ *pValue = (regData & (0x1 << bit)) >> bit; -+ -+ if(0x8367B == cleDebuggingDisplay) -+ PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); -+ -+#elif defined(CONFIG_RTL8367C_ASICDRV_TEST) -+ -+ if(bit >= RTL8367C_REGBITLENGTH) -+ return RT_ERR_INPUT; -+ -+ if(reg >= CLE_VIRTUAL_REG_SIZE) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ *pValue = (CleVirtualReg[reg] & (0x1 << bit)) >> bit; -+ -+ if(0x8367B == cleDebuggingDisplay) -+ PRINT("R[0x%4.4x]=0x%4.4x\n", reg, CleVirtualReg[reg]); -+ -+#elif defined(EMBEDDED_SUPPORT) -+ rtk_uint16 tmp; -+ -+ if(reg > RTL8367C_REGDATAMAX ) -+ return RT_ERR_INPUT; -+ -+ tmp = getReg(reg); -+ tmp = tmp >> bitIdx; -+ tmp &= 1; -+ *value = tmp; -+#else -+ rtk_uint32 regData; -+ ret_t retVal; -+ -+ retVal = smi_read(reg, ®Data); -+ if(retVal != RT_ERR_OK) -+ return RT_ERR_SMI; -+ -+ #ifdef CONFIG_RTL865X_CLE -+ if(0x8367B == cleDebuggingDisplay) -+ PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); -+ #endif -+ -+ *pValue = (regData & (0x1 << bit)) >> bit; -+ -+#endif -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicRegBits -+ * Description: -+ * Set bits value of a specified register -+ * Input: -+ * reg - register's address -+ * bits - bits mask for setting -+ * value - bits value for setting -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter -+ * Note: -+ * Set bits of a specified register to value. Both bits and value are be treated as bit-mask -+ */ -+ret_t rtl8367c_setAsicRegBits(rtk_uint32 reg, rtk_uint32 bits, rtk_uint32 value) -+{ -+ -+#if defined(RTK_X86_ASICDRV) -+ -+ rtk_uint32 regData; -+ ret_t retVal; -+ rtk_uint32 bitsShift; -+ rtk_uint32 valueShifted; -+ -+ if(bits >= (1 << RTL8367C_REGBITLENGTH) ) -+ return RT_ERR_INPUT; -+ -+ bitsShift = 0; -+ while(!(bits & (1 << bitsShift))) -+ { -+ bitsShift++; -+ if(bitsShift >= RTL8367C_REGBITLENGTH) -+ return RT_ERR_INPUT; -+ } -+ -+ valueShifted = value << bitsShift; -+ if(valueShifted > RTL8367C_REGDATAMAX) -+ return RT_ERR_INPUT; -+ -+ retVal = Access_Read(reg, 2, ®Data); -+ if(TRUE != retVal) -+ return RT_ERR_SMI; -+ -+ if(0x8367B == cleDebuggingDisplay) -+ PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); -+ -+ regData = regData & (~bits); -+ regData = regData | (valueShifted & bits); -+ -+ retVal = Access_Write(reg,2, regData); -+ if(TRUE != retVal) -+ return RT_ERR_SMI; -+ -+ if(0x8367B == cleDebuggingDisplay) -+ PRINT("W[0x%4.4x]=0x%4.4x\n", reg, regData); -+ -+#elif defined(CONFIG_RTL8367C_ASICDRV_TEST) -+ rtk_uint32 regData; -+ rtk_uint32 bitsShift; -+ rtk_uint32 valueShifted; -+ -+ if(bits >= (1 << RTL8367C_REGBITLENGTH) ) -+ return RT_ERR_INPUT; -+ -+ bitsShift = 0; -+ while(!(bits & (1 << bitsShift))) -+ { -+ bitsShift++; -+ if(bitsShift >= RTL8367C_REGBITLENGTH) -+ return RT_ERR_INPUT; -+ } -+ valueShifted = value << bitsShift; -+ -+ if(valueShifted > RTL8367C_REGDATAMAX) -+ return RT_ERR_INPUT; -+ -+ if(reg >= CLE_VIRTUAL_REG_SIZE) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ regData = CleVirtualReg[reg] & (~bits); -+ regData = regData | (valueShifted & bits); -+ -+ CleVirtualReg[reg] = regData; -+ -+ if(0x8367B == cleDebuggingDisplay) -+ PRINT("W[0x%4.4x]=0x%4.4x\n", reg, regData); -+ -+#elif defined(EMBEDDED_SUPPORT) -+ rtk_uint32 regData; -+ rtk_uint32 bitsShift; -+ rtk_uint32 valueShifted; -+ -+ if(reg > RTL8367C_REGDATAMAX ) -+ return RT_ERR_INPUT; -+ -+ if(bits >= (1 << RTL8367C_REGBITLENGTH) ) -+ return RT_ERR_INPUT; -+ -+ bitsShift = 0; -+ while(!(bits & (1 << bitsShift))) -+ { -+ bitsShift++; -+ if(bitsShift >= RTL8367C_REGBITLENGTH) -+ return RT_ERR_INPUT; -+ } -+ -+ valueShifted = value << bitsShift; -+ if(valueShifted > RTL8367C_REGDATAMAX) -+ return RT_ERR_INPUT; -+ -+ regData = getReg(reg); -+ regData = regData & (~bits); -+ regData = regData | (valueShifted & bits); -+ -+ setReg(reg, regData); -+ -+#else -+ rtk_uint32 regData; -+ ret_t retVal; -+ rtk_uint32 bitsShift; -+ rtk_uint32 valueShifted; -+ -+ if(bits >= (1 << RTL8367C_REGBITLENGTH) ) -+ return RT_ERR_INPUT; -+ -+ bitsShift = 0; -+ while(!(bits & (1 << bitsShift))) -+ { -+ bitsShift++; -+ if(bitsShift >= RTL8367C_REGBITLENGTH) -+ return RT_ERR_INPUT; -+ } -+ valueShifted = value << bitsShift; -+ -+ if(valueShifted > RTL8367C_REGDATAMAX) -+ return RT_ERR_INPUT; -+ -+ retVal = smi_read(reg, ®Data); -+ if(retVal != RT_ERR_OK) -+ return RT_ERR_SMI; -+ #ifdef CONFIG_RTL865X_CLE -+ if(0x8367B == cleDebuggingDisplay) -+ PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); -+ #endif -+ -+ regData = regData & (~bits); -+ regData = regData | (valueShifted & bits); -+ -+ retVal = smi_write(reg, regData); -+ if(retVal != RT_ERR_OK) -+ return RT_ERR_SMI; -+ #ifdef CONFIG_RTL865X_CLE -+ if(0x8367B == cleDebuggingDisplay) -+ PRINT("W[0x%4.4x]=0x%4.4x\n", reg, regData); -+ #endif -+#endif -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicRegBits -+ * Description: -+ * Get bits value of a specified register -+ * Input: -+ * reg - register's address -+ * bits - bits mask for setting -+ * value - bits value for setting -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicRegBits(rtk_uint32 reg, rtk_uint32 bits, rtk_uint32 *pValue) -+{ -+ -+#if defined(RTK_X86_ASICDRV) -+ -+ rtk_uint32 regData; -+ ret_t retVal; -+ rtk_uint32 bitsShift; -+ -+ if(bits >= (1 << RTL8367C_REGBITLENGTH) ) -+ return RT_ERR_INPUT; -+ -+ bitsShift = 0; -+ while(!(bits & (1 << bitsShift))) -+ { -+ bitsShift++; -+ if(bitsShift >= RTL8367C_REGBITLENGTH) -+ return RT_ERR_INPUT; -+ } -+ -+ retVal = Access_Read(reg, 2, ®Data); -+ if(TRUE != retVal) -+ return RT_ERR_SMI; -+ -+ *pValue = (regData & bits) >> bitsShift; -+ -+ if(0x8367B == cleDebuggingDisplay) -+ PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); -+ -+#elif defined(CONFIG_RTL8367C_ASICDRV_TEST) -+ rtk_uint32 bitsShift; -+ -+ if(bits >= (1 << RTL8367C_REGBITLENGTH) ) -+ return RT_ERR_INPUT; -+ -+ bitsShift = 0; -+ while(!(bits & (1 << bitsShift))) -+ { -+ bitsShift++; -+ if(bitsShift >= RTL8367C_REGBITLENGTH) -+ return RT_ERR_INPUT; -+ } -+ -+ if(reg >= CLE_VIRTUAL_REG_SIZE) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ *pValue = (CleVirtualReg[reg] & bits) >> bitsShift; -+ -+ if(0x8367B == cleDebuggingDisplay) -+ PRINT("R[0x%4.4x]=0x%4.4x\n", reg, CleVirtualReg[reg]); -+ -+#elif defined(EMBEDDED_SUPPORT) -+ rtk_uint32 regData; -+ rtk_uint32 bitsShift; -+ -+ if(reg > RTL8367C_REGDATAMAX ) -+ return RT_ERR_INPUT; -+ -+ if(bits >= (1UL << RTL8367C_REGBITLENGTH) ) -+ return RT_ERR_INPUT; -+ -+ bitsShift = 0; -+ while(!(bits & (1UL << bitsShift))) -+ { -+ bitsShift++; -+ if(bitsShift >= RTL8367C_REGBITLENGTH) -+ return RT_ERR_INPUT; -+ } -+ -+ regData = getReg(reg); -+ *value = (regData & bits) >> bitsShift; -+ -+#else -+ rtk_uint32 regData; -+ ret_t retVal; -+ rtk_uint32 bitsShift; -+ -+ if(bits>= (1<= RTL8367C_REGBITLENGTH) -+ return RT_ERR_INPUT; -+ } -+ -+ retVal = smi_read(reg, ®Data); -+ if(retVal != RT_ERR_OK) return RT_ERR_SMI; -+ -+ *pValue = (regData & bits) >> bitsShift; -+ #ifdef CONFIG_RTL865X_CLE -+ if(0x8367B == cleDebuggingDisplay) -+ PRINT("R[0x%4.4x]=0x%4.4x\n",reg, regData); -+ #endif -+ -+#endif -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicReg -+ * Description: -+ * Set content of asic register -+ * Input: -+ * reg - register's address -+ * value - Value setting to register -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * The value will be set to ASIC mapping address only and it is always return RT_ERR_OK while setting un-mapping address registers -+ */ -+ret_t rtl8367c_setAsicReg(rtk_uint32 reg, rtk_uint32 value) -+{ -+#if defined(RTK_X86_ASICDRV)/*RTK-CNSD2-NickWu-20061222: for x86 compile*/ -+ -+ ret_t retVal; -+ -+ retVal = Access_Write(reg,2,value); -+ if(TRUE != retVal) return RT_ERR_SMI; -+ -+ if(0x8367B == cleDebuggingDisplay) -+ PRINT("W[0x%4.4x]=0x%4.4x\n",reg,value); -+ -+#elif defined(CONFIG_RTL8367C_ASICDRV_TEST) -+ -+ /*MIBs emulating*/ -+ if(reg == RTL8367C_REG_MIB_ADDRESS) -+ { -+ CleVirtualReg[RTL8367C_MIB_COUNTER_BASE_REG] = 0x1; -+ CleVirtualReg[RTL8367C_MIB_COUNTER_BASE_REG+1] = 0x2; -+ CleVirtualReg[RTL8367C_MIB_COUNTER_BASE_REG+2] = 0x3; -+ CleVirtualReg[RTL8367C_MIB_COUNTER_BASE_REG+3] = 0x4; -+ } -+ -+ if(reg >= CLE_VIRTUAL_REG_SIZE) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ CleVirtualReg[reg] = value; -+ -+ if(0x8367B == cleDebuggingDisplay) -+ PRINT("W[0x%4.4x]=0x%4.4x\n",reg,CleVirtualReg[reg]); -+ -+#elif defined(EMBEDDED_SUPPORT) -+ if(reg > RTL8367C_REGDATAMAX || value > RTL8367C_REGDATAMAX ) -+ return RT_ERR_INPUT; -+ -+ setReg(reg, value); -+ -+#else -+ ret_t retVal; -+ -+ retVal = smi_write(reg, value); -+ if(retVal != RT_ERR_OK) -+ return RT_ERR_SMI; -+ #ifdef CONFIG_RTL865X_CLE -+ if(0x8367B == cleDebuggingDisplay) -+ PRINT("W[0x%4.4x]=0x%4.4x\n",reg,value); -+ #endif -+ -+#endif -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicReg -+ * Description: -+ * Get content of asic register -+ * Input: -+ * reg - register's address -+ * value - Value setting to register -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * Value 0x0000 will be returned for ASIC un-mapping address -+ */ -+ret_t rtl8367c_getAsicReg(rtk_uint32 reg, rtk_uint32 *pValue) -+{ -+ -+#if defined(RTK_X86_ASICDRV) -+ -+ rtk_uint32 regData; -+ ret_t retVal; -+ -+ retVal = Access_Read(reg, 2, ®Data); -+ if(TRUE != retVal) -+ return RT_ERR_SMI; -+ -+ *pValue = regData; -+ -+ if(0x8367B == cleDebuggingDisplay) -+ PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); -+ -+#elif defined(CONFIG_RTL8367C_ASICDRV_TEST) -+ if(reg >= CLE_VIRTUAL_REG_SIZE) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ *pValue = CleVirtualReg[reg]; -+ -+ if(0x8367B == cleDebuggingDisplay) -+ PRINT("R[0x%4.4x]=0x%4.4x\n", reg, CleVirtualReg[reg]); -+ -+#elif defined(EMBEDDED_SUPPORT) -+ if(reg > RTL8367C_REGDATAMAX ) -+ return RT_ERR_INPUT; -+ -+ *value = getReg(reg); -+ -+#else -+ rtk_uint32 regData; -+ ret_t retVal; -+ -+ retVal = smi_read(reg, ®Data); -+ if(retVal != RT_ERR_OK) -+ return RT_ERR_SMI; -+ -+ *pValue = regData; -+ #ifdef CONFIG_RTL865X_CLE -+ if(0x8367B == cleDebuggingDisplay) -+ PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); -+ #endif -+ -+#endif -+ -+ return RT_ERR_OK; -+} -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_acl.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_acl.c -new file mode 100644 -index 000000000000..1e4d2961e7d1 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_acl.c -@@ -0,0 +1,1173 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : ACL related function drivers -+ * -+ */ -+#include -+ -+#include -+ -+#if defined(CONFIG_RTL8367C_ASICDRV_TEST) -+rtl8367c_aclrulesmi Rtl8370sVirtualAclRuleTable[RTL8367C_ACLRULENO]; -+rtk_uint16 Rtl8370sVirtualAclActTable[RTL8367C_ACLRULENO][RTL8367C_ACL_ACT_TABLE_LEN]; -+#endif -+ -+/* -+ Exchange structure type define with MMI and SMI -+*/ -+static void _rtl8367c_aclRuleStSmi2User( rtl8367c_aclrule *pAclUser, rtl8367c_aclrulesmi *pAclSmi) -+{ -+ rtk_uint8 *care_ptr, *data_ptr; -+ rtk_uint8 care_tmp, data_tmp; -+ rtk_uint32 i; -+ -+ pAclUser->data_bits.active_portmsk = (((pAclSmi->data_bits_ext.rule_info >> 1) & 0x0007) << 8) | ((pAclSmi->data_bits.rule_info >> 8) & 0x00FF); -+ pAclUser->data_bits.type = (pAclSmi->data_bits.rule_info & 0x0007); -+ pAclUser->data_bits.tag_exist = (pAclSmi->data_bits.rule_info & 0x00F8) >> 3; -+ -+ care_ptr = (rtk_uint8*)&pAclSmi->care_bits; -+ data_ptr = (rtk_uint8*)&pAclSmi->data_bits; -+ -+ for ( i = 0; i < sizeof(struct acl_rule_smi_st); i++) -+ { -+ care_tmp = *(care_ptr + i) ^ (*(data_ptr + i)); -+ data_tmp = *(data_ptr + i); -+ -+ *(care_ptr + i) = care_tmp; -+ *(data_ptr + i) = data_tmp; -+ } -+ -+ care_ptr = (rtk_uint8*)&pAclSmi->care_bits_ext; -+ data_ptr = (rtk_uint8*)&pAclSmi->data_bits_ext; -+ care_tmp = (*care_ptr) ^ (*data_ptr); -+ data_tmp = (*data_ptr); -+ *care_ptr = care_tmp; -+ *data_ptr = data_tmp; -+ -+ for(i = 0; i < RTL8367C_ACLRULEFIELDNO; i++) -+ pAclUser->data_bits.field[i] = pAclSmi->data_bits.field[i]; -+ -+ pAclUser->valid = pAclSmi->valid; -+ -+ pAclUser->care_bits.active_portmsk = (((pAclSmi->care_bits_ext.rule_info >> 1) & 0x0007) << 8) | ((pAclSmi->care_bits.rule_info >> 8) & 0x00FF); -+ pAclUser->care_bits.type = (pAclSmi->care_bits.rule_info & 0x0007); -+ pAclUser->care_bits.tag_exist = (pAclSmi->care_bits.rule_info & 0x00F8) >> 3; -+ -+ for(i = 0; i < RTL8367C_ACLRULEFIELDNO; i++) -+ pAclUser->care_bits.field[i] = pAclSmi->care_bits.field[i]; -+} -+ -+/* -+ Exchange structure type define with MMI and SMI -+*/ -+static void _rtl8367c_aclRuleStUser2Smi(rtl8367c_aclrule *pAclUser, rtl8367c_aclrulesmi *pAclSmi) -+{ -+ rtk_uint8 *care_ptr, *data_ptr; -+ rtk_uint8 care_tmp, data_tmp; -+ rtk_uint32 i; -+ -+ pAclSmi->data_bits_ext.rule_info = ((pAclUser->data_bits.active_portmsk >> 8) & 0x7) << 1; -+ pAclSmi->data_bits.rule_info = ((pAclUser->data_bits.active_portmsk & 0xff) << 8) | ((pAclUser->data_bits.tag_exist & 0x1F) << 3) | (pAclUser->data_bits.type & 0x07); -+ -+ for(i = 0;i < RTL8367C_ACLRULEFIELDNO; i++) -+ pAclSmi->data_bits.field[i] = pAclUser->data_bits.field[i]; -+ -+ pAclSmi->valid = pAclUser->valid; -+ -+ pAclSmi->care_bits_ext.rule_info = ((pAclUser->care_bits.active_portmsk >> 8) & 0x7) << 1; -+ pAclSmi->care_bits.rule_info = ((pAclUser->care_bits.active_portmsk & 0xff) << 8) | ((pAclUser->care_bits.tag_exist & 0x1F) << 3) | (pAclUser->care_bits.type & 0x07); -+ -+ for(i = 0; i < RTL8367C_ACLRULEFIELDNO; i++) -+ pAclSmi->care_bits.field[i] = pAclUser->care_bits.field[i]; -+ -+ care_ptr = (rtk_uint8*)&pAclSmi->care_bits; -+ data_ptr = (rtk_uint8*)&pAclSmi->data_bits; -+ -+ for ( i = 0; i < sizeof(struct acl_rule_smi_st); i++) -+ { -+ care_tmp = *(care_ptr + i) & ~(*(data_ptr + i)); -+ data_tmp = *(care_ptr + i) & *(data_ptr + i); -+ -+ *(care_ptr + i) = care_tmp; -+ *(data_ptr + i) = data_tmp; -+ } -+ -+ care_ptr = (rtk_uint8*)&pAclSmi->care_bits_ext; -+ data_ptr = (rtk_uint8*)&pAclSmi->data_bits_ext; -+ care_tmp = *care_ptr & ~(*data_ptr); -+ data_tmp = *care_ptr & *data_ptr; -+ -+ *care_ptr = care_tmp; -+ *data_ptr = data_tmp; -+} -+ -+/* -+ Exchange structure type define with MMI and SMI -+*/ -+static void _rtl8367c_aclActStSmi2User(rtl8367c_acl_act_t *pAclUser, rtk_uint16 *pAclSmi) -+{ -+ pAclUser->cact = (pAclSmi[0] & 0x00C0) >> 6; -+ pAclUser->cvidx_cact = (pAclSmi[0] & 0x003F) | (((pAclSmi[3] & 0x0008) >> 3) << 6); -+ -+ pAclUser->sact = (pAclSmi[0] & 0xC000) >> 14; -+ pAclUser->svidx_sact = ((pAclSmi[0] & 0x3F00) >> 8) | (((pAclSmi[3] & 0x0010) >> 4) << 6); -+ -+ pAclUser->aclmeteridx = (pAclSmi[1] & 0x003F) | (((pAclSmi[3] & 0x0020) >> 5) << 6); -+ -+ pAclUser->fwdact = (pAclSmi[1] & 0xC000) >> 14; -+ pAclUser->fwdpmask = ((pAclSmi[1] & 0x3FC0) >> 6) | (((pAclSmi[3] & 0x01C0) >> 6) << 8); -+ -+ pAclUser->priact = (pAclSmi[2] & 0x00C0) >> 6; -+ pAclUser->pridx = (pAclSmi[2] & 0x003F) | (((pAclSmi[3] & 0x0200) >> 9) << 6); -+ -+ pAclUser->aclint = (pAclSmi[2] & 0x2000) >> 13; -+ pAclUser->gpio_en = (pAclSmi[2] & 0x1000) >> 12; -+ pAclUser->gpio_pin = (pAclSmi[2] & 0x0F00) >> 8; -+ -+ pAclUser->cact_ext = (pAclSmi[2] & 0xC000) >> 14; -+ pAclUser->tag_fmt = (pAclSmi[3] & 0x0003); -+ pAclUser->fwdact_ext = (pAclSmi[3] & 0x0004) >> 2; -+} -+ -+/* -+ Exchange structure type define with MMI and SMI -+*/ -+static void _rtl8367c_aclActStUser2Smi(rtl8367c_acl_act_t *pAclUser, rtk_uint16 *pAclSmi) -+{ -+ pAclSmi[0] |= (pAclUser->cvidx_cact & 0x003F); -+ pAclSmi[0] |= (pAclUser->cact & 0x0003) << 6; -+ pAclSmi[0] |= (pAclUser->svidx_sact & 0x003F) << 8; -+ pAclSmi[0] |= (pAclUser->sact & 0x0003) << 14; -+ -+ pAclSmi[1] |= (pAclUser->aclmeteridx & 0x003F); -+ pAclSmi[1] |= (pAclUser->fwdpmask & 0x00FF) << 6; -+ pAclSmi[1] |= (pAclUser->fwdact & 0x0003) << 14; -+ -+ pAclSmi[2] |= (pAclUser->pridx & 0x003F); -+ pAclSmi[2] |= (pAclUser->priact & 0x0003) << 6; -+ pAclSmi[2] |= (pAclUser->gpio_pin & 0x000F) << 8; -+ pAclSmi[2] |= (pAclUser->gpio_en & 0x0001) << 12; -+ pAclSmi[2] |= (pAclUser->aclint & 0x0001) << 13; -+ pAclSmi[2] |= (pAclUser->cact_ext & 0x0003) << 14; -+ -+ pAclSmi[3] |= (pAclUser->tag_fmt & 0x0003); -+ pAclSmi[3] |= (pAclUser->fwdact_ext & 0x0001) << 2; -+ pAclSmi[3] |= ((pAclUser->cvidx_cact & 0x0040) >> 6) << 3; -+ pAclSmi[3] |= ((pAclUser->svidx_sact & 0x0040) >> 6) << 4; -+ pAclSmi[3] |= ((pAclUser->aclmeteridx & 0x0040) >> 6) << 5; -+ pAclSmi[3] |= ((pAclUser->fwdpmask & 0x0700) >> 8) << 6; -+ pAclSmi[3] |= ((pAclUser->pridx & 0x0040) >> 6) << 9; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicAcl -+ * Description: -+ * Set port ACL function enable/disable -+ * Input: -+ * port - Physical port number (0~10) -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicAcl(rtk_uint32 port, rtk_uint32 enabled) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_ACL_ENABLE_REG, port, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicAcl -+ * Description: -+ * Get port ACL function enable/disable -+ * Input: -+ * port - Physical port number (0~10) -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicAcl(rtk_uint32 port, rtk_uint32* pEnabled) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_ACL_ENABLE_REG, port, pEnabled); -+} -+/* Function Name: -+ * rtl8367c_setAsicAclUnmatchedPermit -+ * Description: -+ * Set port ACL function unmatched permit action -+ * Input: -+ * port - Physical port number (0~10) -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicAclUnmatchedPermit(rtk_uint32 port, rtk_uint32 enabled) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_ACL_UNMATCH_PERMIT_REG, port, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicAclUnmatchedPermit -+ * Description: -+ * Get port ACL function unmatched permit action -+ * Input: -+ * port - Physical port number (0~10) -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicAclUnmatchedPermit(rtk_uint32 port, rtk_uint32* pEnabled) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_ACL_UNMATCH_PERMIT_REG, port, pEnabled); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicAclRule -+ * Description: -+ * Set ACL rule content -+ * Input: -+ * index - ACL rule index (0-95) of 96 ACL rules -+ * pAclRule - ACL rule structure for setting -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-95) -+ * Note: -+ * System supported 95 shared 289-bit ACL ingress rule. Index was available at range 0-95 only. -+ * If software want to modify ACL rule, the ACL function should be disabled at first or unspecified -+ * ACL action will be executed. -+ * One ACL rule structure has three parts setting: -+ * Bit 0-147 Data Bits of this Rule -+ * Bit 148 Valid Bit -+ * Bit 149-296 Care Bits of this Rule -+ * There are four kinds of field in Data Bits and Care Bits: Active Portmask, Type, Tag Exist, and 8 fields -+ */ -+ret_t rtl8367c_setAsicAclRule(rtk_uint32 index, rtl8367c_aclrule* pAclRule) -+{ -+ rtl8367c_aclrulesmi aclRuleSmi; -+ rtk_uint16* tableAddr; -+ rtk_uint32 regAddr; -+ rtk_uint32 regData; -+ rtk_uint32 i; -+ ret_t retVal; -+ -+ if(index > RTL8367C_ACLRULEMAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ memset(&aclRuleSmi, 0x00, sizeof(rtl8367c_aclrulesmi)); -+ -+ _rtl8367c_aclRuleStUser2Smi(pAclRule, &aclRuleSmi); -+ -+ /* Write valid bit = 0 */ -+ regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; -+ if(index >= 64) -+ regData = RTL8367C_ACLRULETBADDR2(DATABITS, index); -+ else -+ regData = RTL8367C_ACLRULETBADDR(DATABITS, index); -+ retVal = rtl8367c_setAsicReg(regAddr,regData); -+ if(retVal !=RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_TABLE_ACCESS_WRDATA_REG(RTL8367C_ACLRULETBLEN), 0x1, 0); -+ if(retVal !=RT_ERR_OK) -+ return retVal; -+ -+ regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; -+ regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_WRITE, TB_TARGET_ACLRULE); -+ retVal = rtl8367c_setAsicReg(regAddr, regData); -+ if(retVal !=RT_ERR_OK) -+ return retVal; -+ -+ -+ -+ /* Write ACS_ADR register */ -+ regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; -+ if(index >= 64) -+ regData = RTL8367C_ACLRULETBADDR2(CAREBITS, index); -+ else -+ regData = RTL8367C_ACLRULETBADDR(CAREBITS, index); -+ retVal = rtl8367c_setAsicReg(regAddr, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ /* Write Care Bits to ACS_DATA registers */ -+ tableAddr = (rtk_uint16*)&aclRuleSmi.care_bits; -+ regAddr = RTL8367C_TABLE_ACCESS_WRDATA_BASE; -+ -+ for(i = 0; i < RTL8367C_ACLRULETBLEN; i++) -+ { -+ regData = *tableAddr; -+ retVal = rtl8367c_setAsicReg(regAddr, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ regAddr++; -+ tableAddr++; -+ } -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_TABLE_ACCESS_WRDATA_REG(RTL8367C_ACLRULETBLEN), (0x0007 << 1), (aclRuleSmi.care_bits_ext.rule_info >> 1) & 0x0007); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ /* Write ACS_CMD register */ -+ regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; -+ regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_WRITE, TB_TARGET_ACLRULE); -+ retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK,regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ -+ -+ /* Write ACS_ADR register for data bits */ -+ regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; -+ if(index >= 64) -+ regData = RTL8367C_ACLRULETBADDR2(DATABITS, index); -+ else -+ regData = RTL8367C_ACLRULETBADDR(DATABITS, index); -+ -+ retVal = rtl8367c_setAsicReg(regAddr, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ /* Write Data Bits to ACS_DATA registers */ -+ tableAddr = (rtk_uint16*)&aclRuleSmi.data_bits; -+ regAddr = RTL8367C_TABLE_ACCESS_WRDATA_BASE; -+ -+ for(i = 0; i < RTL8367C_ACLRULETBLEN; i++) -+ { -+ regData = *tableAddr; -+ retVal = rtl8367c_setAsicReg(regAddr, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ regAddr++; -+ tableAddr++; -+ } -+ -+ retVal = rtl8367c_setAsicRegBit(RTL8367C_TABLE_ACCESS_WRDATA_REG(RTL8367C_ACLRULETBLEN), 0, aclRuleSmi.valid); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_TABLE_ACCESS_WRDATA_REG(RTL8367C_ACLRULETBLEN), (0x0007 << 1), (aclRuleSmi.data_bits_ext.rule_info >> 1) & 0x0007); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ /* Write ACS_CMD register for care bits*/ -+ regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; -+ regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_WRITE, TB_TARGET_ACLRULE); -+ retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+#ifdef CONFIG_RTL8367C_ASICDRV_TEST -+ memcpy(&Rtl8370sVirtualAclRuleTable[index], &aclRuleSmi, sizeof(rtl8367c_aclrulesmi)); -+#endif -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicAclRule -+ * Description: -+ * Get ACL rule content -+ * Input: -+ * index - ACL rule index (0-63) of 64 ACL rules -+ * pAclRule - ACL rule structure for setting -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-63) -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicAclRule(rtk_uint32 index, rtl8367c_aclrule *pAclRule) -+{ -+ rtl8367c_aclrulesmi aclRuleSmi; -+ rtk_uint32 regAddr, regData; -+ ret_t retVal; -+ rtk_uint16* tableAddr; -+ rtk_uint32 i; -+ -+ if(index > RTL8367C_ACLRULEMAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ memset(&aclRuleSmi, 0x00, sizeof(rtl8367c_aclrulesmi)); -+ -+ /* Write ACS_ADR register for data bits */ -+ regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; -+ if(index >= 64) -+ regData = RTL8367C_ACLRULETBADDR2(DATABITS, index); -+ else -+ regData = RTL8367C_ACLRULETBADDR(DATABITS, index); -+ -+ retVal = rtl8367c_setAsicReg(regAddr, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ -+ /* Write ACS_CMD register */ -+ regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; -+ regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_READ, TB_TARGET_ACLRULE); -+ retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ /* Read Data Bits */ -+ regAddr = RTL8367C_TABLE_ACCESS_RDDATA_BASE; -+ tableAddr = (rtk_uint16*)&aclRuleSmi.data_bits; -+ for(i = 0; i < RTL8367C_ACLRULETBLEN; i++) -+ { -+ retVal = rtl8367c_getAsicReg(regAddr, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *tableAddr = regData; -+ -+ regAddr ++; -+ tableAddr ++; -+ } -+ -+ /* Read Valid Bit */ -+ retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_RDDATA_REG(RTL8367C_ACLRULETBLEN), 0, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ aclRuleSmi.valid = regData & 0x1; -+ /* Read active_portmsk_ext Bits */ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_TABLE_ACCESS_RDDATA_REG(RTL8367C_ACLRULETBLEN), 0x7<<1, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ aclRuleSmi.data_bits_ext.rule_info = (regData % 0x0007) << 1; -+ -+ -+ /* Write ACS_ADR register for carebits*/ -+ regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; -+ if(index >= 64) -+ regData = RTL8367C_ACLRULETBADDR2(CAREBITS, index); -+ else -+ regData = RTL8367C_ACLRULETBADDR(CAREBITS, index); -+ -+ retVal = rtl8367c_setAsicReg(regAddr, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ /* Write ACS_CMD register */ -+ regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; -+ regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_READ, TB_TARGET_ACLRULE); -+ retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ /* Read Care Bits */ -+ regAddr = RTL8367C_TABLE_ACCESS_RDDATA_BASE; -+ tableAddr = (rtk_uint16*)&aclRuleSmi.care_bits; -+ for(i = 0; i < RTL8367C_ACLRULETBLEN; i++) -+ { -+ retVal = rtl8367c_getAsicReg(regAddr, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *tableAddr = regData; -+ -+ regAddr ++; -+ tableAddr ++; -+ } -+ /* Read active_portmsk_ext care Bits */ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_TABLE_ACCESS_RDDATA_REG(RTL8367C_ACLRULETBLEN), 0x7<<1, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ aclRuleSmi.care_bits_ext.rule_info = (regData & 0x0007) << 1; -+ -+#ifdef CONFIG_RTL8367C_ASICDRV_TEST -+ memcpy(&aclRuleSmi,&Rtl8370sVirtualAclRuleTable[index], sizeof(rtl8367c_aclrulesmi)); -+#endif -+ -+ _rtl8367c_aclRuleStSmi2User(pAclRule, &aclRuleSmi); -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicAclNot -+ * Description: -+ * Set rule comparison result inversion / no inversion -+ * Input: -+ * index - ACL rule index (0-95) of 96 ACL rules -+ * not - 1: inverse, 0: don't inverse -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-95) -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicAclNot(rtk_uint32 index, rtk_uint32 not) -+{ -+ if(index > RTL8367C_ACLRULEMAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(index < 64) -+ return rtl8367c_setAsicRegBit(RTL8367C_ACL_ACTION_CTRL_REG(index), RTL8367C_ACL_OP_NOT_OFFSET(index), not); -+ else -+ return rtl8367c_setAsicRegBit(RTL8367C_ACL_ACTION_CTRL2_REG(index), RTL8367C_ACL_OP_NOT_OFFSET(index), not); -+ -+} -+/* Function Name: -+ * rtl8367c_getAsicAcl -+ * Description: -+ * Get rule comparison result inversion / no inversion -+ * Input: -+ * index - ACL rule index (0-95) of 95 ACL rules -+ * pNot - 1: inverse, 0: don't inverse -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-95) -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicAclNot(rtk_uint32 index, rtk_uint32* pNot) -+{ -+ if(index > RTL8367C_ACLRULEMAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(index < 64) -+ return rtl8367c_getAsicRegBit(RTL8367C_ACL_ACTION_CTRL_REG(index), RTL8367C_ACL_OP_NOT_OFFSET(index), pNot); -+ else -+ return rtl8367c_getAsicRegBit(RTL8367C_ACL_ACTION_CTRL2_REG(index), RTL8367C_ACL_OP_NOT_OFFSET(index), pNot); -+ -+} -+/* Function Name: -+ * rtl8367c_setAsicAclTemplate -+ * Description: -+ * Set fields of a ACL Template -+ * Input: -+ * index - ACL template index(0~4) -+ * pAclType - ACL type structure for setting -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - Invalid ACL template index(0~4) -+ * Note: -+ * The API can set type field of the 5 ACL rule templates. -+ * Each type has 8 fields. One field means what data in one field of a ACL rule means -+ * 8 fields of ACL rule 0~95 is described by one type in ACL group -+ */ -+ret_t rtl8367c_setAsicAclTemplate(rtk_uint32 index, rtl8367c_acltemplate_t* pAclType) -+{ -+ ret_t retVal; -+ rtk_uint32 i; -+ rtk_uint32 regAddr, regData; -+ -+ if(index >= RTL8367C_ACLTEMPLATENO) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ regAddr = RTL8367C_ACL_RULE_TEMPLATE_CTRL_REG(index); -+ -+ for(i = 0; i < (RTL8367C_ACLRULEFIELDNO/2); i++) -+ { -+ regData = pAclType->field[i*2+1]; -+ regData = regData << 8 | pAclType->field[i*2]; -+ -+ retVal = rtl8367c_setAsicReg(regAddr + i, regData); -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicAclTemplate -+ * Description: -+ * Get fields of a ACL Template -+ * Input: -+ * index - ACL template index(0~4) -+ * pAclType - ACL type structure for setting -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - Invalid ACL template index(0~4) -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicAclTemplate(rtk_uint32 index, rtl8367c_acltemplate_t *pAclType) -+{ -+ ret_t retVal; -+ rtk_uint32 i; -+ rtk_uint32 regData, regAddr; -+ -+ if(index >= RTL8367C_ACLTEMPLATENO) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ regAddr = RTL8367C_ACL_RULE_TEMPLATE_CTRL_REG(index); -+ -+ for(i = 0; i < (RTL8367C_ACLRULEFIELDNO/2); i++) -+ { -+ retVal = rtl8367c_getAsicReg(regAddr + i,®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ pAclType->field[i*2] = regData & 0xFF; -+ pAclType->field[i*2 + 1] = (regData >> 8) & 0xFF; -+ } -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicAclAct -+ * Description: -+ * Set ACL rule matched Action -+ * Input: -+ * index - ACL rule index (0-95) of 96 ACL rules -+ * pAclAct - ACL action structure for setting -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-95) -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicAclAct(rtk_uint32 index, rtl8367c_acl_act_t* pAclAct) -+{ -+ rtk_uint16 aclActSmi[RTL8367C_ACL_ACT_TABLE_LEN]; -+ ret_t retVal; -+ rtk_uint32 regAddr, regData; -+ rtk_uint16* tableAddr; -+ rtk_uint32 i; -+ -+ if(index > RTL8367C_ACLRULEMAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ memset(aclActSmi, 0x00, sizeof(rtk_uint16) * RTL8367C_ACL_ACT_TABLE_LEN); -+ _rtl8367c_aclActStUser2Smi(pAclAct, aclActSmi); -+ -+ /* Write ACS_ADR register for data bits */ -+ regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; -+ regData = index; -+ retVal = rtl8367c_setAsicReg(regAddr, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ /* Write Data Bits to ACS_DATA registers */ -+ tableAddr = aclActSmi; -+ regAddr = RTL8367C_TABLE_ACCESS_WRDATA_BASE; -+ -+ for(i = 0; i < RTL8367C_ACLACTTBLEN; i++) -+ { -+ regData = *tableAddr; -+ retVal = rtl8367c_setAsicReg(regAddr, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ regAddr++; -+ tableAddr++; -+ } -+ -+ /* Write ACS_CMD register for care bits*/ -+ regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; -+ regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_WRITE, TB_TARGET_ACLACT); -+ retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+#ifdef CONFIG_RTL8367C_ASICDRV_TEST -+ memcpy(&Rtl8370sVirtualAclActTable[index][0], aclActSmi, sizeof(rtk_uint16) * RTL8367C_ACL_ACT_TABLE_LEN); -+#endif -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicAclAct -+ * Description: -+ * Get ACL rule matched Action -+ * Input: -+ * index - ACL rule index (0-95) of 96 ACL rules -+ * pAclAct - ACL action structure for setting -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-95) -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicAclAct(rtk_uint32 index, rtl8367c_acl_act_t *pAclAct) -+{ -+ rtk_uint16 aclActSmi[RTL8367C_ACL_ACT_TABLE_LEN]; -+ ret_t retVal; -+ rtk_uint32 regAddr, regData; -+ rtk_uint16 *tableAddr; -+ rtk_uint32 i; -+ -+ if(index > RTL8367C_ACLRULEMAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ memset(aclActSmi, 0x00, sizeof(rtk_uint16) * RTL8367C_ACL_ACT_TABLE_LEN); -+ -+ /* Write ACS_ADR register for data bits */ -+ regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; -+ regData = index; -+ retVal = rtl8367c_setAsicReg(regAddr, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ /* Write ACS_CMD register */ -+ regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; -+ regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_READ, TB_TARGET_ACLACT); -+ retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ /* Read Data Bits */ -+ regAddr = RTL8367C_TABLE_ACCESS_RDDATA_BASE; -+ tableAddr = aclActSmi; -+ for(i = 0; i < RTL8367C_ACLACTTBLEN; i++) -+ { -+ retVal = rtl8367c_getAsicReg(regAddr, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *tableAddr = regData; -+ -+ regAddr ++; -+ tableAddr ++; -+ } -+ -+#ifdef CONFIG_RTL8367C_ASICDRV_TEST -+ memcpy(aclActSmi, &Rtl8370sVirtualAclActTable[index][0], sizeof(rtk_uint16) * RTL8367C_ACL_ACT_TABLE_LEN); -+#endif -+ -+ _rtl8367c_aclActStSmi2User(pAclAct, aclActSmi); -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicAclActCtrl -+ * Description: -+ * Set ACL rule matched Action Control Bits -+ * Input: -+ * index - ACL rule index (0-95) of 96 ACL rules -+ * aclActCtrl - 6 ACL Control Bits -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-95) -+ * Note: -+ * ACL Action Control Bits Indicate which actions will be take when a rule matches -+ */ -+ret_t rtl8367c_setAsicAclActCtrl(rtk_uint32 index, rtk_uint32 aclActCtrl) -+{ -+ ret_t retVal; -+ -+ if(index > RTL8367C_ACLRULEMAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(index >= 64) -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_ACL_ACTION_CTRL2_REG(index), RTL8367C_ACL_OP_ACTION_MASK(index), aclActCtrl); -+ else -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_ACL_ACTION_CTRL_REG(index), RTL8367C_ACL_OP_ACTION_MASK(index), aclActCtrl); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicAclActCtrl -+ * Description: -+ * Get ACL rule matched Action Control Bits -+ * Input: -+ * index - ACL rule index (0-95) of 96 ACL rules -+ * pAclActCtrl - 6 ACL Control Bits -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-95) -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicAclActCtrl(rtk_uint32 index, rtk_uint32 *pAclActCtrl) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ -+ if(index > RTL8367C_ACLRULEMAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(index >= 64) -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_ACL_ACTION_CTRL2_REG(index), RTL8367C_ACL_OP_ACTION_MASK(index), ®Data); -+ else -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_ACL_ACTION_CTRL_REG(index), RTL8367C_ACL_OP_ACTION_MASK(index), ®Data); -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *pAclActCtrl = regData; -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicAclPortRange -+ * Description: -+ * Set ACL TCP/UDP range check -+ * Input: -+ * index - TCP/UDP port range check table index -+ * type - Range check type -+ * upperPort - TCP/UDP port range upper bound -+ * lowerPort - TCP/UDP port range lower bound -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - Invalid TCP/UDP port range check table index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicAclPortRange(rtk_uint32 index, rtk_uint32 type, rtk_uint32 upperPort, rtk_uint32 lowerPort) -+{ -+ ret_t retVal; -+ -+ if(index > RTL8367C_ACLRANGEMAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL2 + index*3, RTL8367C_ACL_SDPORT_RANGE_ENTRY0_CTRL2_MASK, type); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL1 + index*3, upperPort); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL0 + index*3, lowerPort); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicAclPortRange -+ * Description: -+ * Get ACL TCP/UDP range check -+ * Input: -+ * index - TCP/UDP port range check table index -+ * pType - Range check type -+ * pUpperPort - TCP/UDP port range upper bound -+ * pLowerPort - TCP/UDP port range lower bound -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - Invalid TCP/UDP port range check table index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicAclPortRange(rtk_uint32 index, rtk_uint32* pType, rtk_uint32* pUpperPort, rtk_uint32* pLowerPort) -+{ -+ ret_t retVal; -+ -+ if(index > RTL8367C_ACLRANGEMAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL2 + index*3, RTL8367C_ACL_SDPORT_RANGE_ENTRY0_CTRL2_MASK, pType); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL1 + index*3, pUpperPort); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL0 + index*3, pLowerPort); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicAclVidRange -+ * Description: -+ * Set ACL VID range check -+ * Input: -+ * index - ACL VID range check index(0~15) -+ * type - Range check type -+ * upperVid - VID range upper bound -+ * lowerVid - VID range lower bound -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - Invalid ACL VID range check index(0~15) -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicAclVidRange(rtk_uint32 index, rtk_uint32 type, rtk_uint32 upperVid, rtk_uint32 lowerVid) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ -+ if(index > RTL8367C_ACLRANGEMAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ regData = ((type << RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_TYPE_OFFSET) & RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_TYPE_MASK) | -+ (upperVid & RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_HIGH_MASK); -+ -+ retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_VID_RANGE_ENTRY0_CTRL1 + index*2, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_VID_RANGE_ENTRY0_CTRL0 + index*2, lowerVid); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicAclVidRange -+ * Description: -+ * Get ACL VID range check -+ * Input: -+ * index - ACL VID range check index(0~15) -+ * pType - Range check type -+ * pUpperVid - VID range upper bound -+ * pLowerVid - VID range lower bound -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - Invalid ACL VID range check index(0~15) -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicAclVidRange(rtk_uint32 index, rtk_uint32* pType, rtk_uint32* pUpperVid, rtk_uint32* pLowerVid) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ -+ if(index > RTL8367C_ACLRANGEMAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_VID_RANGE_ENTRY0_CTRL1 + index*2, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *pType = (regData & RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_TYPE_MASK) >> RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_TYPE_OFFSET; -+ *pUpperVid = regData & RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_HIGH_MASK; -+ -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_VID_RANGE_ENTRY0_CTRL0 + index*2, pLowerVid); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicAclIpRange -+ * Description: -+ * Set ACL IP range check -+ * Input: -+ * index - ACL IP range check index(0~15) -+ * type - Range check type -+ * upperIp - IP range upper bound -+ * lowerIp - IP range lower bound -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - Invalid ACL IP range check index(0~15) -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicAclIpRange(rtk_uint32 index, rtk_uint32 type, ipaddr_t upperIp, ipaddr_t lowerIp) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ ipaddr_t ipData; -+ -+ if(index > RTL8367C_ACLRANGEMAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL4 + index*5, RTL8367C_ACL_IP_RANGE_ENTRY0_CTRL4_MASK, type); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ ipData = upperIp; -+ -+ regData = ipData & 0xFFFF; -+ retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL2 + index*5, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ regData = (ipData>>16) & 0xFFFF; -+ retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL3 + index*5, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ ipData = lowerIp; -+ -+ regData = ipData & 0xFFFF; -+ retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL0 + index*5, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ regData = (ipData>>16) & 0xFFFF; -+ retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL1 + index*5, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicAclIpRange -+ * Description: -+ * Get ACL IP range check -+ * Input: -+ * index - ACL IP range check index(0~15) -+ * pType - Range check type -+ * pUpperIp - IP range upper bound -+ * pLowerIp - IP range lower bound -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - Invalid ACL IP range check index(0~15) -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicAclIpRange(rtk_uint32 index, rtk_uint32* pType, ipaddr_t* pUpperIp, ipaddr_t* pLowerIp) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ ipaddr_t ipData; -+ -+ if(index > RTL8367C_ACLRANGEMAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL4 + index*5, RTL8367C_ACL_IP_RANGE_ENTRY0_CTRL4_MASK, pType); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL2 + index*5, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ ipData = regData; -+ -+ -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL3 + index*5, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ ipData = (regData <<16) | ipData; -+ *pUpperIp = ipData; -+ -+ -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL0 + index*5, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ ipData = regData; -+ -+ -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL1 + index*5, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ ipData = (regData << 16) | ipData; -+ *pLowerIp = ipData; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicAclGpioPolarity -+ * Description: -+ * Set ACL Goip control polarity -+ * Input: -+ * polarity - 1: High, 0: Low -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * none -+ */ -+ret_t rtl8367c_setAsicAclGpioPolarity(rtk_uint32 polarity) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_ACL_GPIO_POLARITY, RTL8367C_ACL_GPIO_POLARITY_OFFSET, polarity); -+} -+/* Function Name: -+ * rtl8367c_getAsicAclGpioPolarity -+ * Description: -+ * Get ACL Goip control polarity -+ * Input: -+ * pPolarity - 1: High, 0: Low -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * none -+ */ -+ret_t rtl8367c_getAsicAclGpioPolarity(rtk_uint32* pPolarity) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_ACL_GPIO_POLARITY, RTL8367C_ACL_GPIO_POLARITY_OFFSET, pPolarity); -+} -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_cputag.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_cputag.c -new file mode 100644 -index 000000000000..ec9c332e1620 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_cputag.c -@@ -0,0 +1,369 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Proprietary CPU-tag related function drivers -+ * -+ */ -+#include -+/* Function Name: -+ * rtl8367c_setAsicCputagEnable -+ * Description: -+ * Set CPU tag function enable/disable -+ * Input: -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_ENABLE - Invalid enable/disable input -+ * Note: -+ * If CPU tag function is disabled, CPU tag will not be added to frame -+ * forwarded to CPU port, and all ports cannot parse CPU tag. -+ */ -+ret_t rtl8367c_setAsicCputagEnable(rtk_uint32 enabled) -+{ -+ if(enabled > 1) -+ return RT_ERR_ENABLE; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_EN_OFFSET, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicCputagEnable -+ * Description: -+ * Get CPU tag function enable/disable -+ * Input: -+ * pEnabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicCputagEnable(rtk_uint32 *pEnabled) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_EN_OFFSET, pEnabled); -+} -+/* Function Name: -+ * rtl8367c_setAsicCputagTrapPort -+ * Description: -+ * Set CPU tag trap port -+ * Input: -+ * port - port number -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * API can set destination port of trapping frame -+ */ -+ret_t rtl8367c_setAsicCputagTrapPort(rtk_uint32 port) -+{ -+ ret_t retVal; -+ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TRAP_PORT_MASK, port & 7); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TRAP_PORT_EXT_MASK, (port>>3) & 1); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicCputagTrapPort -+ * Description: -+ * Get CPU tag trap port -+ * Input: -+ * pPort - port number -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicCputagTrapPort(rtk_uint32 *pPort) -+{ -+ ret_t retVal; -+ rtk_uint32 tmpPort; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TRAP_PORT_MASK, &tmpPort); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ *pPort = tmpPort; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TRAP_PORT_EXT_MASK, &tmpPort); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ *pPort |= (tmpPort & 1) << 3; -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicCputagPortmask -+ * Description: -+ * Set ports that can parse CPU tag -+ * Input: -+ * portmask - port mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Invalid portmask -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicCputagPortmask(rtk_uint32 portmask) -+{ -+ if(portmask > RTL8367C_PORTMASK) -+ return RT_ERR_PORT_MASK; -+ -+ return rtl8367c_setAsicReg(RTL8367C_CPU_PORT_MASK_REG, portmask); -+} -+/* Function Name: -+ * rtl8367c_getAsicCputagPortmask -+ * Description: -+ * Get ports that can parse CPU tag -+ * Input: -+ * pPortmask - port mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicCputagPortmask(rtk_uint32 *pPortmask) -+{ -+ return rtl8367c_getAsicReg(RTL8367C_CPU_PORT_MASK_REG, pPortmask); -+} -+/* Function Name: -+ * rtl8367c_setAsicCputagInsertMode -+ * Description: -+ * Set CPU-tag insert mode -+ * Input: -+ * mode - 0: insert to all packets; 1: insert to trapped packets; 2: don't insert -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NOT_ALLOWED - Actions not allowed by the function -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicCputagInsertMode(rtk_uint32 mode) -+{ -+ if(mode >= CPUTAG_INSERT_END) -+ return RT_ERR_NOT_ALLOWED; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_INSERTMODE_MASK, mode); -+} -+/* Function Name: -+ * rtl8367c_getAsicCputagInsertMode -+ * Description: -+ * Get CPU-tag insert mode -+ * Input: -+ * pMode - 0: insert to all packets; 1: insert to trapped packets; 2: don't insert -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicCputagInsertMode(rtk_uint32 *pMode) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_INSERTMODE_MASK, pMode); -+} -+/* Function Name: -+ * rtl8367c_setAsicCputagPriorityRemapping -+ * Description: -+ * Set queue assignment of CPU port -+ * Input: -+ * srcPri - internal priority (0~7) -+ * newPri - internal priority after remapping (0~7) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicCputagPriorityRemapping(rtk_uint32 srcPri, rtk_uint32 newPri) -+{ -+ if((srcPri > RTL8367C_PRIMAX) || (newPri > RTL8367C_PRIMAX)) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_REG(srcPri), RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_MASK(srcPri), newPri); -+} -+/* Function Name: -+ * rtl8367c_getAsicCputagPriorityRemapping -+ * Description: -+ * Get queue assignment of CPU port -+ * Input: -+ * srcPri - internal priority (0~7) -+ * pNewPri - internal priority after remapping (0~7) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicCputagPriorityRemapping(rtk_uint32 srcPri, rtk_uint32 *pNewPri) -+{ -+ if(srcPri > RTL8367C_PRIMAX) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_REG(srcPri), RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_MASK(srcPri), pNewPri); -+} -+/* Function Name: -+ * rtl8367c_setAsicCputagPosition -+ * Description: -+ * Set CPU tag insert position -+ * Input: -+ * position - 1: After entire packet(before CRC field), 0: After MAC_SA (Default) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicCputagPosition(rtk_uint32 position) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TAG_POSITION_OFFSET, position); -+} -+/* Function Name: -+ * rtl8367c_getAsicCputagPosition -+ * Description: -+ * Get CPU tag insert position -+ * Input: -+ * pPostion - 1: After entire packet(before CRC field), 0: After MAC_SA (Default) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicCputagPosition(rtk_uint32* pPostion) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TAG_POSITION_OFFSET, pPostion); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicCputagMode -+ * Description: -+ * Set CPU tag mode -+ * Input: -+ * mode - 1: 4bytes mode, 0: 8bytes mode -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters -+ * Note: -+ * If CPU tag function is disabled, CPU tag will not be added to frame -+ * forwarded to CPU port, and all ports cannot parse CPU tag. -+ */ -+ret_t rtl8367c_setAsicCputagMode(rtk_uint32 mode) -+{ -+ if(mode > 1) -+ return RT_ERR_INPUT; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TAG_FORMAT_OFFSET, mode); -+} -+/* Function Name: -+ * rtl8367c_getAsicCputagMode -+ * Description: -+ * Get CPU tag mode -+ * Input: -+ * pMode - 1: 4bytes mode, 0: 8bytes mode -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicCputagMode(rtk_uint32 *pMode) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TAG_FORMAT_OFFSET, pMode); -+} -+/* Function Name: -+ * rtl8367c_setAsicCputagRxMinLength -+ * Description: -+ * Set CPU tag mode -+ * Input: -+ * mode - 1: 64bytes, 0: 72bytes -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters -+ * Note: -+ * If CPU tag function is disabled, CPU tag will not be added to frame -+ * forwarded to CPU port, and all ports cannot parse CPU tag. -+ */ -+ret_t rtl8367c_setAsicCputagRxMinLength(rtk_uint32 mode) -+{ -+ if(mode > 1) -+ return RT_ERR_INPUT; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TAG_RXBYTECOUNT_OFFSET, mode); -+} -+/* Function Name: -+ * rtl8367c_getAsicCputagRxMinLength -+ * Description: -+ * Get CPU tag mode -+ * Input: -+ * pMode - 1: 64bytes, 0: 72bytes -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicCputagRxMinLength(rtk_uint32 *pMode) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TAG_RXBYTECOUNT_OFFSET, pMode); -+} -+ -+ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_dot1x.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_dot1x.c -new file mode 100644 -index 000000000000..73153e177ee9 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_dot1x.c -@@ -0,0 +1,415 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : 802.1X related functions -+ * -+ */ -+#include -+/* Function Name: -+ * rtl8367c_setAsic1xPBEnConfig -+ * Description: -+ * Set 802.1x port-based port enable configuration -+ * Input: -+ * port - Physical port number (0~7) -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsic1xPBEnConfig(rtk_uint32 port, rtk_uint32 enabled) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_DOT1X_PORT_ENABLE_REG, port, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsic1xPBEnConfig -+ * Description: -+ * Get 802.1x port-based port enable configuration -+ * Input: -+ * port - Physical port number (0~7) -+ * pEnabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsic1xPBEnConfig(rtk_uint32 port, rtk_uint32 *pEnabled) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_DOT1X_PORT_ENABLE_REG, port, pEnabled); -+} -+/* Function Name: -+ * rtl8367c_setAsic1xPBAuthConfig -+ * Description: -+ * Set 802.1x port-based authorised port configuration -+ * Input: -+ * port - Physical port number (0~7) -+ * auth - 1: authorised, 0: non-authorised -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsic1xPBAuthConfig(rtk_uint32 port, rtk_uint32 auth) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_DOT1X_PORT_AUTH_REG, port, auth); -+} -+/* Function Name: -+ * rtl8367c_getAsic1xPBAuthConfig -+ * Description: -+ * Get 802.1x port-based authorised port configuration -+ * Input: -+ * port - Physical port number (0~7) -+ * pAuth - 1: authorised, 0: non-authorised -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsic1xPBAuthConfig(rtk_uint32 port, rtk_uint32 *pAuth) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_DOT1X_PORT_AUTH_REG, port, pAuth); -+} -+/* Function Name: -+ * rtl8367c_setAsic1xPBOpdirConfig -+ * Description: -+ * Set 802.1x port-based operational direction -+ * Input: -+ * port - Physical port number (0~7) -+ * opdir - Operation direction 1: IN, 0:BOTH -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsic1xPBOpdirConfig(rtk_uint32 port, rtk_uint32 opdir) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_DOT1X_PORT_OPDIR_REG, port, opdir); -+} -+/* Function Name: -+ * rtl8367c_getAsic1xPBOpdirConfig -+ * Description: -+ * Get 802.1x port-based operational direction -+ * Input: -+ * port - Physical port number (0~7) -+ * pOpdir - Operation direction 1: IN, 0:BOTH -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsic1xPBOpdirConfig(rtk_uint32 port, rtk_uint32* pOpdir) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_DOT1X_PORT_OPDIR_REG, port, pOpdir); -+} -+/* Function Name: -+ * rtl8367c_setAsic1xMBEnConfig -+ * Description: -+ * Set 802.1x mac-based port enable configuration -+ * Input: -+ * port - Physical port number (0~7) -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsic1xMBEnConfig(rtk_uint32 port, rtk_uint32 enabled) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_DOT1X_MAC_ENABLE_REG, port, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsic1xMBEnConfig -+ * Description: -+ * Get 802.1x mac-based port enable configuration -+ * Input: -+ * port - Physical port number (0~7) -+ * pEnabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsic1xMBEnConfig(rtk_uint32 port, rtk_uint32 *pEnabled) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_DOT1X_MAC_ENABLE_REG, port, pEnabled); -+} -+/* Function Name: -+ * rtl8367c_setAsic1xMBOpdirConfig -+ * Description: -+ * Set 802.1x mac-based operational direction -+ * Input: -+ * opdir - Operation direction 1: IN, 0:BOTH -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsic1xMBOpdirConfig(rtk_uint32 opdir) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_DOT1X_CFG_REG, RTL8367C_DOT1X_MAC_OPDIR_OFFSET, opdir); -+} -+/* Function Name: -+ * rtl8367c_getAsic1xMBOpdirConfig -+ * Description: -+ * Get 802.1x mac-based operational direction -+ * Input: -+ * pOpdir - Operation direction 1: IN, 0:BOTH -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsic1xMBOpdirConfig(rtk_uint32 *pOpdir) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_DOT1X_CFG_REG, RTL8367C_DOT1X_MAC_OPDIR_OFFSET, pOpdir); -+} -+/* Function Name: -+ * rtl8367c_setAsic1xProcConfig -+ * Description: -+ * Set 802.1x unauth. behavior configuration -+ * Input: -+ * port - Physical port number (0~7) -+ * proc - 802.1x unauth. behavior configuration 0:drop 1:trap to CPU 2:Guest VLAN -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_DOT1X_PROC - Unauthorized behavior error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsic1xProcConfig(rtk_uint32 port, rtk_uint32 proc) -+{ -+ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ if(proc >= DOT1X_UNAUTH_END) -+ return RT_ERR_DOT1X_PROC; -+ -+ if(port < 8) -+ { -+ return rtl8367c_setAsicRegBits(RTL8367C_DOT1X_UNAUTH_ACT_BASE, RTL8367C_DOT1X_UNAUTH_ACT_MASK(port),proc); -+ } -+ else -+ { -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_DOT1X_UNAUTH_ACT_W1, RTL8367C_DOT1X_UNAUTH_ACT_MASK(port),proc); -+ } -+} -+/* Function Name: -+ * rtl8367c_getAsic1xProcConfig -+ * Description: -+ * Get 802.1x unauth. behavior configuration -+ * Input: -+ * port - Physical port number (0~7) -+ * pProc - 802.1x unauth. behavior configuration 0:drop 1:trap to CPU 2:Guest VLAN -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsic1xProcConfig(rtk_uint32 port, rtk_uint32* pProc) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ if(port < 8) -+ return rtl8367c_getAsicRegBits(RTL8367C_DOT1X_UNAUTH_ACT_BASE, RTL8367C_DOT1X_UNAUTH_ACT_MASK(port),pProc); -+ else -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_DOT1X_UNAUTH_ACT_W1, RTL8367C_DOT1X_UNAUTH_ACT_MASK(port),pProc); -+} -+/* Function Name: -+ * rtl8367c_setAsic1xGuestVidx -+ * Description: -+ * Set 802.1x guest vlan index -+ * Input: -+ * index - 802.1x guest vlan index (0~31) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_DOT1X_GVLANIDX - Invalid cvid index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsic1xGuestVidx(rtk_uint32 index) -+{ -+ if(index >= RTL8367C_CVIDXNO) -+ return RT_ERR_DOT1X_GVLANIDX; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_DOT1X_CFG_REG, RTL8367C_DOT1X_GVIDX_MASK, index); -+} -+/* Function Name: -+ * rtl8367c_getAsic1xGuestVidx -+ * Description: -+ * Get 802.1x guest vlan index -+ * Input: -+ * pIndex - 802.1x guest vlan index (0~31) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsic1xGuestVidx(rtk_uint32 *pIndex) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_DOT1X_CFG_REG, RTL8367C_DOT1X_GVIDX_MASK, pIndex); -+} -+/* Function Name: -+ * rtl8367c_setAsic1xGVOpdir -+ * Description: -+ * Set 802.1x guest vlan talk to auth. DA -+ * Input: -+ * enabled - 0:disable 1:enable -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsic1xGVOpdir(rtk_uint32 enabled) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_DOT1X_CFG_REG, RTL8367C_DOT1X_GVOPDIR_OFFSET, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsic1xGVOpdir -+ * Description: -+ * Get 802.1x guest vlan talk to auth. DA -+ * Input: -+ * pEnabled - 0:disable 1:enable -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsic1xGVOpdir(rtk_uint32 *pEnabled) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_DOT1X_CFG_REG, RTL8367C_DOT1X_GVOPDIR_OFFSET, pEnabled); -+} -+/* Function Name: -+ * rtl8367c_setAsic1xTrapPriority -+ * Description: -+ * Set 802.1x Trap priority -+ * Input: -+ * priority - priority (0~7) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsic1xTrapPriority(rtk_uint32 priority) -+{ -+ if(priority > RTL8367C_PRIMAX) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_QOS_TRAP_PRIORITY0, RTL8367C_DOT1X_PRIORTY_MASK,priority); -+} -+/* Function Name: -+ * rtl8367c_getAsic1xTrapPriority -+ * Description: -+ * Get 802.1x Trap priority -+ * Input: -+ * pPriority - priority (0~7) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsic1xTrapPriority(rtk_uint32 *pPriority) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_QOS_TRAP_PRIORITY0, RTL8367C_DOT1X_PRIORTY_MASK, pPriority); -+} -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eav.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eav.c -new file mode 100644 -index 000000000000..811ee4795441 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eav.c -@@ -0,0 +1,877 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Ethernet AV related functions -+ * -+ */ -+ -+#include -+/* Function Name: -+ * rtl8367c_setAsicEavMacAddress -+ * Description: -+ * Set PTP MAC address -+ * Input: -+ * mac - PTP mac -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicEavMacAddress(ether_addr_t mac) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ rtk_uint8 *accessPtr; -+ rtk_uint32 i; -+ -+ accessPtr = (rtk_uint8*)&mac; -+ -+ regData = *accessPtr; -+ accessPtr ++; -+ regData = (regData << 8) | *accessPtr; -+ accessPtr ++; -+ for(i = 0; i <=2; i++) -+ { -+ retVal = rtl8367c_setAsicReg(RTL8367C_REG_MAC_ADDR_H - i, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ regData = *accessPtr; -+ accessPtr ++; -+ regData = (regData << 8) | *accessPtr; -+ accessPtr ++; -+ } -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicEavMacAddress -+ * Description: -+ * Get PTP MAC address -+ * Input: -+ * None -+ * Output: -+ * pMac - PTP mac -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicEavMacAddress(ether_addr_t *pMac) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ rtk_uint8 *accessPtr; -+ rtk_uint32 i; -+ -+ accessPtr = (rtk_uint8*)pMac; -+ -+ for(i = 0; i <= 2; i++) -+ { -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_MAC_ADDR_H - i, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *accessPtr = (regData & 0xFF00) >> 8; -+ accessPtr ++; -+ *accessPtr = regData & 0xFF; -+ accessPtr ++; -+ } -+ -+ return retVal; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicEavTpid -+ * Description: -+ * Set PTP parser tag TPID. -+ * Input: -+ * outerTag - outer tag TPID -+ * innerTag - inner tag TPID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicEavTpid(rtk_uint32 outerTag, rtk_uint32 innerTag) -+{ -+ ret_t retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_OTAG_TPID, outerTag)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_ITAG_TPID, innerTag)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicEavTpid -+ * Description: -+ * Get PTP parser tag TPID. -+ * Input: -+ * None -+ * Output: -+ * pOuterTag - outer tag TPID -+ * pInnerTag - inner tag TPID -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicEavTpid(rtk_uint32* pOuterTag, rtk_uint32* pInnerTag) -+{ -+ ret_t retVal; -+ -+ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_OTAG_TPID, pOuterTag)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_ITAG_TPID, pInnerTag)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicEavSysTime -+ * Description: -+ * Set PTP system time -+ * Input: -+ * second - seconds -+ * nanoSecond - nano seconds -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * The time granularity is 8 nano seconds. -+ */ -+ret_t rtl8367c_setAsicEavSysTime(rtk_uint32 second, rtk_uint32 nanoSecond) -+{ -+ ret_t retVal; -+ rtk_uint32 sec_h, sec_l, nsec8_h, nsec8_l; -+ rtk_uint32 nano_second_8; -+ rtk_uint32 regData, busyFlag, count; -+ -+ if(nanoSecond > RTL8367C_EAV_NANOSECONDMAX) -+ return RT_ERR_INPUT; -+ -+ regData = 0; -+ sec_h = second >>16; -+ sec_l = second & 0xFFFF; -+ nano_second_8 = nanoSecond >> 3; -+ nsec8_h = (nano_second_8 >>16) & RTL8367C_PTP_TIME_NSEC_H_NSEC_MASK; -+ nsec8_l = nano_second_8 &0xFFFF; -+ -+ if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PTP_TIME_SEC_H_SEC, sec_h)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PTP_TIME_SEC_L_SEC, sec_l)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PTP_TIME_NSEC_L_NSEC, nsec8_l)) != RT_ERR_OK) -+ return retVal; -+ -+ regData = nsec8_h | (PTP_TIME_WRITE<= PTP_TIME_ADJ_END) -+ return RT_ERR_INPUT; -+ if(nanoSecond > RTL8367C_EAV_NANOSECONDMAX) -+ return RT_ERR_INPUT; -+ -+ regData = 0; -+ sec_h = second >>16; -+ sec_l = second & 0xFFFF; -+ nano_second_8 = nanoSecond >> 3; -+ nsec8_h = (nano_second_8 >>16) & RTL8367C_PTP_TIME_NSEC_H_NSEC_MASK; -+ nsec8_l = nano_second_8 &0xFFFF; -+ -+ if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PTP_TIME_SEC_H_SEC, sec_h)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PTP_TIME_SEC_L_SEC, sec_l)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PTP_TIME_NSEC_L_NSEC, nsec8_l)) != RT_ERR_OK) -+ return retVal; -+ -+ if (PTP_TIME_ADJ_INC == type) -+ regData = nsec8_h | (PTP_TIME_INC<=PTP_TIME_CTRL_END) -+ return RT_ERR_INPUT; -+ -+ regData = 0; -+ if (PTP_TIME_CTRL_START == control) -+ regData = RTL8367C_CFG_TIMER_EN_FRC_MASK | RTL8367C_CFG_TIMER_1588_EN_MASK; -+ else -+ regData = 0; -+ -+ if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PTP_TIME_CFG, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicEavSysTimeCtrl -+ * Description: -+ * Get PTP system time control -+ * Input: -+ * None -+ * Output: -+ * pControl - start or stop -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicEavSysTimeCtrl(rtk_uint32* pControl) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ rtk_uint32 mask; -+ -+ mask = RTL8367C_CFG_TIMER_EN_FRC_MASK | RTL8367C_CFG_TIMER_1588_EN_MASK; -+ -+ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_PTP_TIME_CFG, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (regData & mask) == mask) -+ *pControl = PTP_TIME_CTRL_START; -+ else if( (regData & mask) == 0) -+ *pControl = PTP_TIME_CTRL_STOP; -+ else -+ return RT_ERR_NOT_ALLOWED; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicEavInterruptMask -+ * Description: -+ * Set PTP interrupt enable mask -+ * Input: -+ * imr - Interrupt mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * [0]:TX_SYNC, -+ * [1]:TX_DELAY, -+ * [2]:TX_PDELAY_REQ, -+ * [3]:TX_PDELAY_RESP, -+ * [4]:RX_SYNC, -+ * [5]:RX_DELAY, -+ * [6]:RX_PDELAY_REQ, -+ * [7]:RX_PDELAY_RESP, -+ */ -+ret_t rtl8367c_setAsicEavInterruptMask(rtk_uint32 imr) -+{ -+ if ((imr&(RTL8367C_PTP_INTR_MASK<<8))>0) -+ return RT_ERR_INPUT; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_PTP_TIME_CFG2, RTL8367C_PTP_INTR_MASK, imr); -+} -+/* Function Name: -+ * rtl8367c_getAsicEavInterruptMask -+ * Description: -+ * Get PTP interrupt enable mask -+ * Input: -+ * pImr - Interrupt mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * [0]:TX_SYNC, -+ * [1]:TX_DELAY, -+ * [2]:TX_PDELAY_REQ, -+ * [3]:TX_PDELAY_RESP, -+ * [4]:RX_SYNC, -+ * [5]:RX_DELAY, -+ * [6]:RX_PDELAY_REQ, -+ * [7]:RX_PDELAY_RESP, -+ */ -+ret_t rtl8367c_getAsicEavInterruptMask(rtk_uint32* pImr) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_PTP_TIME_CFG2, RTL8367C_PTP_INTR_MASK, pImr); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicEavInterruptStatus -+ * Description: -+ * Get PTP interrupt port status mask -+ * Input: -+ * pIms - Interrupt mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * [0]:p0 interrupt, -+ * [1]:p1 interrupt, -+ * [2]:p2 interrupt, -+ * [3]:p3 interrupt, -+ * [4]:p4 interrupt, -+ */ -+ret_t rtl8367c_getAsicEavInterruptStatus(rtk_uint32* pIms) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_PTP_INTERRUPT_CFG, RTL8367C_PTP_PORT_MASK, pIms); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicInterruptMask -+ * Description: -+ * Clear interrupt enable mask -+ * Input: -+ * ims - Interrupt status mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * This API can be used to clear ASIC interrupt status and register will be cleared by writing 1. -+ * [0]:TX_SYNC, -+ * [1]:TX_DELAY, -+ * [2]:TX_PDELAY_REQ, -+ * [3]:TX_PDELAY_RESP, -+ * [4]:RX_SYNC, -+ * [5]:RX_DELAY, -+ * [6]:RX_PDELAY_REQ, -+ * [7]:RX_PDELAY_RESP, -+ */ -+ret_t rtl8367c_setAsicEavPortInterruptStatus(rtk_uint32 port, rtk_uint32 ims) -+{ -+ -+ if(port > RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ if(port < 5) -+ return rtl8367c_setAsicRegBits(RTL8367C_EAV_PORT_CFG_REG(port), RTL8367C_PTP_INTR_MASK,ims); -+ else if(port == 5) -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_P5_EAV_CFG, RTL8367C_PTP_INTR_MASK,ims); -+ else if(port == 6) -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_P6_EAV_CFG, RTL8367C_PTP_INTR_MASK,ims); -+ else if(port == 7) -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_P7_EAV_CFG, RTL8367C_PTP_INTR_MASK,ims); -+ else if(port == 8) -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_P8_EAV_CFG, RTL8367C_PTP_INTR_MASK,ims); -+ else if(port == 9) -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_P9_EAV_CFG, RTL8367C_PTP_INTR_MASK,ims); -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicInterruptStatus -+ * Description: -+ * Get interrupt enable mask -+ * Input: -+ * pIms - Interrupt status mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * [0]:TX_SYNC, -+ * [1]:TX_DELAY, -+ * [2]:TX_PDELAY_REQ, -+ * [3]:TX_PDELAY_RESP, -+ * [4]:RX_SYNC, -+ * [5]:RX_DELAY, -+ * [6]:RX_PDELAY_REQ, -+ * [7]:RX_PDELAY_RESP, -+ */ -+ret_t rtl8367c_getAsicEavPortInterruptStatus(rtk_uint32 port, rtk_uint32* pIms) -+{ -+ -+ if(port > RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ if(port < 5) -+ return rtl8367c_getAsicRegBits(RTL8367C_EAV_PORT_CFG_REG(port), RTL8367C_PTP_INTR_MASK, pIms); -+ else if(port == 5) -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_P5_EAV_CFG, RTL8367C_PTP_INTR_MASK, pIms); -+ else if(port == 6) -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_P6_EAV_CFG, RTL8367C_PTP_INTR_MASK,pIms); -+ else if(port == 7) -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_P7_EAV_CFG, RTL8367C_PTP_INTR_MASK,pIms); -+ else if(port == 8) -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_P8_EAV_CFG, RTL8367C_PTP_INTR_MASK,pIms); -+ else if(port == 9) -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_P9_EAV_CFG, RTL8367C_PTP_INTR_MASK,pIms); -+ -+ return RT_ERR_OK; -+ -+} -+ -+ -+/* Function Name: -+ * rtl8367c_setAsicEavPortEnable -+ * Description: -+ * Set per-port EAV function enable/disable -+ * Input: -+ * port - Physical port number (0~9) -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * If EAV function is enabled, PTP event message packet will be attached PTP timestamp for trapping -+ */ -+ret_t rtl8367c_setAsicEavPortEnable(rtk_uint32 port, rtk_uint32 enabled) -+{ -+ if(port > RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ if(port < 5) -+ return rtl8367c_setAsicRegBit(RTL8367C_EAV_PORT_CFG_REG(port), RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, enabled); -+ else if(port == 5) -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_P5_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, enabled); -+ else if(port == 6) -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_P6_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, enabled); -+ else if(port == 7) -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_P7_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, enabled); -+ else if(port == 8) -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_P8_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, enabled); -+ else if(port == 9) -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_P9_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, enabled); -+ -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicEavPortEnable -+ * Description: -+ * Get per-port EAV function enable/disable -+ * Input: -+ * port - Physical port number (0~9) -+ * pEnabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicEavPortEnable(rtk_uint32 port, rtk_uint32 *pEnabled) -+{ -+ if(port > RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ -+ -+ if(port < 5) -+ return rtl8367c_getAsicRegBit(RTL8367C_EAV_PORT_CFG_REG(port), RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, pEnabled); -+ else if(port == 5) -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_P5_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, pEnabled); -+ else if(port == 6) -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_P6_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, pEnabled); -+ else if(port == 7) -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_P7_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, pEnabled); -+ else if(port == 8) -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_P8_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, pEnabled); -+ else if(port == 9) -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_P9_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, pEnabled); -+ -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicEavPortTimeStamp -+ * Description: -+ * Get PTP port time stamp -+ * Input: -+ * port - Physical port number (0~9) -+ * type - PTP packet type -+ * Output: -+ * timeStamp - seconds -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * The time granularity is 8 nano seconds. -+ */ -+ret_t rtl8367c_getAsicEavPortTimeStamp(rtk_uint32 port, rtk_uint32 type, rtl8367c_ptp_time_stamp_t* timeStamp) -+{ -+ ret_t retVal; -+ rtk_uint32 sec_h, sec_l, nsec8_h, nsec8_l; -+ rtk_uint32 nano_second_8; -+ -+ if(port > 9) -+ return RT_ERR_PORT_ID; -+ if(type >= PTP_PKT_TYPE_END) -+ return RT_ERR_INPUT; -+ -+ if(port < 5){ -+ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_SEQ_ID(port, type), &timeStamp->sequence_id))!= RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_PORT_SEC_H(port) , &sec_h)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_PORT_SEC_L(port), &sec_l)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_NSEC_H(port) , RTL8367C_PORT_NSEC_H_MASK,&nsec8_h)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_PORT_NSEC_L(port) , &nsec8_l)) != RT_ERR_OK) -+ return retVal; -+ }else if(port == 5){ -+ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P5_TX_SYNC_SEQ_ID+type, &timeStamp->sequence_id))!= RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P5_PORT_SEC_31_16, &sec_h)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P5_PORT_SEC_15_0, &sec_l)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_P5_PORT_NSEC_26_16 , RTL8367C_PORT_NSEC_H_MASK,&nsec8_h)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P5_PORT_NSEC_15_0, &nsec8_l)) != RT_ERR_OK) -+ return retVal; -+ }else if(port == 6){ -+ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P6_TX_SYNC_SEQ_ID+type, &timeStamp->sequence_id))!= RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P6_PORT_SEC_31_16, &sec_h)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P6_PORT_SEC_15_0, &sec_l)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_P6_PORT_NSEC_26_16 , RTL8367C_PORT_NSEC_H_MASK,&nsec8_h)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P6_PORT_NSEC_15_0, &nsec8_l)) != RT_ERR_OK) -+ return retVal; -+ }else if(port == 7){ -+ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P7_TX_SYNC_SEQ_ID+type, &timeStamp->sequence_id))!= RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P7_PORT_SEC_31_16, &sec_h)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P7_PORT_SEC_15_0, &sec_l)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_P7_PORT_NSEC_26_16 , RTL8367C_PORT_NSEC_H_MASK,&nsec8_h)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P7_PORT_NSEC_15_0, &nsec8_l)) != RT_ERR_OK) -+ return retVal; -+ }else if(port == 8){ -+ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P8_TX_SYNC_SEQ_ID+type, &timeStamp->sequence_id))!= RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P8_PORT_SEC_31_16, &sec_h)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P8_PORT_SEC_15_0, &sec_l)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_P8_PORT_NSEC_26_16 , RTL8367C_PORT_NSEC_H_MASK,&nsec8_h)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P8_PORT_NSEC_15_0, &nsec8_l)) != RT_ERR_OK) -+ return retVal; -+ }else if(port == 9){ -+ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P9_TX_SYNC_SEQ_ID+type, &timeStamp->sequence_id))!= RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P9_PORT_SEC_31_16, &sec_h)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P9_PORT_SEC_15_0, &sec_l)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_P9_PORT_NSEC_26_16 , RTL8367C_PORT_NSEC_H_MASK,&nsec8_h)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P9_PORT_NSEC_15_0, &nsec8_l)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ timeStamp->second = (sec_h<<16) | sec_l; -+ nano_second_8 = (nsec8_h<<16) | nsec8_l; -+ timeStamp->nano_second = nano_second_8<<3; -+ -+ return RT_ERR_OK; -+} -+ -+ -+/* Function Name: -+ * rtl8367c_setAsicEavTrap -+ * Description: -+ * Set per-port PTP packet trap to CPU -+ * Input: -+ * port - Physical port number (0~5) -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * If EAV trap enabled, switch will trap PTP packet to CPU -+ */ -+ret_t rtl8367c_setAsicEavTrap(rtk_uint32 port, rtk_uint32 enabled) -+{ -+ if(port > RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_PTP_PORT0_CFG1 + (port * 0x20), RTL8367C_PTP_PORT0_CFG1_OFFSET, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicEavTimeSyncEn -+ * Description: -+ * Get per-port EPTP packet trap to CPU -+ * Input: -+ * port - Physical port number (0~5) -+ * pEnabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicEavTrap(rtk_uint32 port, rtk_uint32 *pEnabled) -+{ -+ if(port > RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_PTP_PORT0_CFG1 + (port * 0x20), RTL8367C_PTP_PORT0_CFG1_OFFSET, pEnabled); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicEavEnable -+ * Description: -+ * Set per-port EAV function enable/disable -+ * Input: -+ * port - Physical port number (0~5) -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * If EAV function is enabled, PTP event message packet will be attached PTP timestamp for trapping -+ */ -+ret_t rtl8367c_setAsicEavEnable(rtk_uint32 port, rtk_uint32 enabled) -+{ -+ if(port > RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_EAV_CTRL0, port, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicEavEnable -+ * Description: -+ * Get per-port EAV function enable/disable -+ * Input: -+ * port - Physical port number (0~5) -+ * pEnabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicEavEnable(rtk_uint32 port, rtk_uint32 *pEnabled) -+{ -+ if(port > RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_EAV_CTRL0, port, pEnabled); -+} -+/* Function Name: -+ * rtl8367c_setAsicEavPriRemapping -+ * Description: -+ * Set non-EAV streaming priority remapping -+ * Input: -+ * srcpriority - Priority value -+ * priority - Absolute priority value -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicEavPriRemapping(rtk_uint32 srcpriority, rtk_uint32 priority) -+{ -+ if(srcpriority > RTL8367C_PRIMAX || priority > RTL8367C_PRIMAX) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_EAV_PRIORITY_REMAPPING_REG(srcpriority), RTL8367C_EAV_PRIORITY_REMAPPING_MASK(srcpriority),priority); -+} -+/* Function Name: -+ * rtl8367c_getAsicEavPriRemapping -+ * Description: -+ * Get non-EAV streaming priority remapping -+ * Input: -+ * srcpriority - Priority value -+ * pPriority - Absolute priority value -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicEavPriRemapping(rtk_uint32 srcpriority, rtk_uint32 *pPriority) -+{ -+ if(srcpriority > RTL8367C_PRIMAX ) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_EAV_PRIORITY_REMAPPING_REG(srcpriority), RTL8367C_EAV_PRIORITY_REMAPPING_MASK(srcpriority),pPriority); -+} -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eee.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eee.c -new file mode 100644 -index 000000000000..f4dda6a6ae6d ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eee.c -@@ -0,0 +1,141 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 48989 $ -+ * $Date: 2014-07-01 15:45:24 +0800 (週二, 01 七月 2014) $ -+ * -+ * Purpose : RTL8370 switch high-level API for RTL8367C -+ * Feature : -+ * -+ */ -+ -+#include -+#include -+ -+/* -+@func ret_t | rtl8367c_setAsicEee100M | Set eee force mode function enable/disable. -+@parm rtk_uint32 | port | The port number. -+@parm rtk_uint32 | enabled | 1: enabled, 0: disabled. -+@rvalue RT_ERR_OK | Success. -+@rvalue RT_ERR_SMI | SMI access error. -+@rvalue RT_ERR_INPUT | Invalid input parameter. -+@comm -+ This API set the 100M EEE enable function. -+ -+*/ -+ret_t rtl8367c_setAsicEee100M(rtk_uint32 port, rtk_uint32 enable) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 regData; -+ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ if (enable > 1) -+ return RT_ERR_INPUT; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, EEE_OCP_PHY_ADDR, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ if(enable) -+ regData |= (0x0001 << 1); -+ else -+ regData &= ~(0x0001 << 1); -+ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, EEE_OCP_PHY_ADDR, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* -+@func ret_t | rtl8367c_getAsicEee100M | Get 100M eee enable/disable. -+@parm rtk_uint32 | port | The port number. -+@parm rtk_uint32* | enabled | 1: enabled, 0: disabled. -+@rvalue RT_ERR_OK | Success. -+@rvalue RT_ERR_SMI | SMI access error. -+@rvalue RT_ERR_INPUT | Invalid input parameter. -+@comm -+ This API get the 100M EEE function. -+*/ -+ret_t rtl8367c_getAsicEee100M(rtk_uint32 port, rtk_uint32 *enable) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 regData; -+ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, EEE_OCP_PHY_ADDR, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ *enable = (regData & (0x0001 << 1)) ? ENABLED : DISABLED; -+ return RT_ERR_OK; -+} -+ -+/* -+@func ret_t | rtl8367c_setAsicEeeGiga | Set eee force mode function enable/disable. -+@parm rtk_uint32 | port | The port number. -+@parm rtk_uint32 | enabled | 1: enabled, 0: disabled. -+@rvalue RT_ERR_OK | Success. -+@rvalue RT_ERR_SMI | SMI access error. -+@rvalue RT_ERR_INPUT | Invalid input parameter. -+@comm -+ This API set the 100M EEE enable function. -+ -+*/ -+ret_t rtl8367c_setAsicEeeGiga(rtk_uint32 port, rtk_uint32 enable) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 regData; -+ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ if (enable > 1) -+ return RT_ERR_INPUT; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, EEE_OCP_PHY_ADDR, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ if(enable) -+ regData |= (0x0001 << 2); -+ else -+ regData &= ~(0x0001 << 2); -+ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, EEE_OCP_PHY_ADDR, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* -+@func ret_t | rtl8367c_getAsicEeeGiga | Get 100M eee enable/disable. -+@parm rtk_uint32 | port | The port number. -+@parm rtk_uint32* | enabled | 1: enabled, 0: disabled. -+@rvalue RT_ERR_OK | Success. -+@rvalue RT_ERR_SMI | SMI access error. -+@rvalue RT_ERR_INPUT | Invalid input parameter. -+@comm -+ This API get the 100M EEE function. -+*/ -+ret_t rtl8367c_getAsicEeeGiga(rtk_uint32 port, rtk_uint32 *enable) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 regData; -+ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, EEE_OCP_PHY_ADDR, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ *enable = (regData & (0x0001 << 2)) ? ENABLED : DISABLED; -+ return RT_ERR_OK; -+} -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_fc.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_fc.c -new file mode 100644 -index 000000000000..b7b102243903 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_fc.c -@@ -0,0 +1,1354 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Flow control related functions -+ * -+ */ -+ -+#include -+/* Function Name: -+ * rtl8367c_setAsicFlowControlSelect -+ * Description: -+ * Set system flow control type -+ * Input: -+ * select - System flow control type 1: Ingress flow control 0:Egress flow control -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicFlowControlSelect(rtk_uint32 select) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_FLOWCTRL_CTRL0, RTL8367C_FLOWCTRL_TYPE_OFFSET, select); -+} -+/* Function Name: -+ * rtl8367c_getAsicFlowControlSelect -+ * Description: -+ * Get system flow control type -+ * Input: -+ * pSelect - System flow control type 1: Ingress flow control 0:Egress flow control -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicFlowControlSelect(rtk_uint32 *pSelect) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_FLOWCTRL_CTRL0, RTL8367C_FLOWCTRL_TYPE_OFFSET, pSelect); -+} -+/* Function Name: -+ * rtl8367c_setAsicFlowControlJumboMode -+ * Description: -+ * Set Jumbo threshold for flow control -+ * Input: -+ * enabled - Jumbo mode flow control 1: Enable 0:Disable -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicFlowControlJumboMode(rtk_uint32 enabled) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_FLOWCTRL_JUMBO_SIZE, RTL8367C_JUMBO_MODE_OFFSET, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicFlowControlJumboMode -+ * Description: -+ * Get Jumbo threshold for flow control -+ * Input: -+ * pEnabled - Jumbo mode flow control 1: Enable 0:Disable -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicFlowControlJumboMode(rtk_uint32* pEnabled) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_FLOWCTRL_JUMBO_SIZE, RTL8367C_JUMBO_MODE_OFFSET, pEnabled); -+} -+/* Function Name: -+ * rtl8367c_setAsicFlowControlJumboModeSize -+ * Description: -+ * Set Jumbo size for Jumbo mode flow control -+ * Input: -+ * size - Jumbo size 0:3Kbytes 1:4Kbytes 2:6Kbytes 3:9Kbytes -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicFlowControlJumboModeSize(rtk_uint32 size) -+{ -+ if(size >= FC_JUMBO_SIZE_END) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SIZE, RTL8367C_JUMBO_SIZE_MASK, size); -+} -+/* Function Name: -+ * rtl8367c_getAsicFlowControlJumboModeSize -+ * Description: -+ * Get Jumbo size for Jumbo mode flow control -+ * Input: -+ * pSize - Jumbo size 0:3Kbytes 1:4Kbytes 2:6Kbytes 3:9Kbytes -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicFlowControlJumboModeSize(rtk_uint32* pSize) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SIZE, RTL8367C_JUMBO_SIZE_MASK, pSize); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicFlowControlQueueEgressEnable -+ * Description: -+ * Set flow control ability for each queue -+ * Input: -+ * port - Physical port number (0~7) -+ * qid - Queue id -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_QUEUE_ID - Invalid queue id -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicFlowControlQueueEgressEnable(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 enabled) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(qid > RTL8367C_QIDMAX) -+ return RT_ERR_QUEUE_ID; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG(port), RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG_OFFSET(port)+ qid, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicFlowControlQueueEgressEnable -+ * Description: -+ * Get flow control ability for each queue -+ * Input: -+ * port - Physical port number (0~7) -+ * qid - Queue id -+ * pEnabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_QUEUE_ID - Invalid queue id -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicFlowControlQueueEgressEnable(rtk_uint32 port, rtk_uint32 qid, rtk_uint32* pEnabled) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(qid > RTL8367C_QIDMAX) -+ return RT_ERR_QUEUE_ID; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG(port), RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG_OFFSET(port)+ qid, pEnabled); -+} -+/* Function Name: -+ * rtl8367c_setAsicFlowControlDropAll -+ * Description: -+ * Set system-based drop parameters -+ * Input: -+ * dropall - Whole system drop threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicFlowControlDropAll(rtk_uint32 dropall) -+{ -+ if(dropall >= RTL8367C_PAGE_NUMBER) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_CTRL0, RTL8367C_DROP_ALL_THRESHOLD_MASK, dropall); -+} -+/* Function Name: -+ * rtl8367c_getAsicFlowControlDropAll -+ * Description: -+ * Get system-based drop parameters -+ * Input: -+ * pDropall - Whole system drop threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicFlowControlDropAll(rtk_uint32* pDropall) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_CTRL0, RTL8367C_DROP_ALL_THRESHOLD_MASK, pDropall); -+} -+/* Function Name: -+ * rtl8367c_setAsicFlowControlPauseAll -+ * Description: -+ * Set system-based all ports enable flow control parameters -+ * Input: -+ * threshold - Whole system pause all threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicFlowControlPauseAllThreshold(rtk_uint32 threshold) -+{ -+ if(threshold >= RTL8367C_PAGE_NUMBER) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_ALL_ON, RTL8367C_FLOWCTRL_ALL_ON_THRESHOLD_MASK, threshold); -+} -+/* Function Name: -+ * rtl8367c_getAsicFlowControlPauseAllThreshold -+ * Description: -+ * Get system-based all ports enable flow control parameters -+ * Input: -+ * pThreshold - Whole system pause all threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicFlowControlPauseAllThreshold(rtk_uint32 *pThreshold) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_ALL_ON, RTL8367C_FLOWCTRL_ALL_ON_THRESHOLD_MASK, pThreshold); -+} -+/* Function Name: -+ * rtl8367c_setAsicFlowControlSystemThreshold -+ * Description: -+ * Set system-based flow control parameters -+ * Input: -+ * onThreshold - Flow control turn ON threshold -+ * offThreshold - Flow control turn OFF threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicFlowControlSystemThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) -+{ -+ ret_t retVal; -+ -+ if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_SYS_OFF, RTL8367C_FLOWCTRL_SYS_OFF_MASK, offThreshold); -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_SYS_ON, RTL8367C_FLOWCTRL_SYS_ON_MASK, onThreshold); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicFlowControlSystemThreshold -+ * Description: -+ * Get system-based flow control parameters -+ * Input: -+ * pOnThreshold - Flow control turn ON threshold -+ * pOffThreshold - Flow control turn OFF threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicFlowControlSystemThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_SYS_OFF, RTL8367C_FLOWCTRL_SYS_OFF_MASK, pOffThreshold); -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_SYS_ON, RTL8367C_FLOWCTRL_SYS_ON_MASK, pOnThreshold); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_setAsicFlowControlSharedThreshold -+ * Description: -+ * Set share-based flow control parameters -+ * Input: -+ * onThreshold - Flow control turn ON threshold -+ * offThreshold - Flow control turn OFF threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicFlowControlSharedThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) -+{ -+ ret_t retVal; -+ -+ if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_SHARE_OFF, RTL8367C_FLOWCTRL_SHARE_OFF_MASK, offThreshold); -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_SHARE_ON, RTL8367C_FLOWCTRL_SHARE_ON_MASK, onThreshold); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicFlowControlSharedThreshold -+ * Description: -+ * Get share-based flow control parameters -+ * Input: -+ * pOnThreshold - Flow control turn ON threshold -+ * pOffThreshold - Flow control turn OFF threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicFlowControlSharedThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_SHARE_OFF, RTL8367C_FLOWCTRL_SHARE_OFF_MASK, pOffThreshold); -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_SHARE_ON, RTL8367C_FLOWCTRL_SHARE_ON_MASK, pOnThreshold); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_setAsicFlowControlPortThreshold -+ * Description: -+ * Set Port-based flow control parameters -+ * Input: -+ * onThreshold - Flow control turn ON threshold -+ * offThreshold - Flow control turn OFF threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicFlowControlPortThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) -+{ -+ ret_t retVal; -+ -+ if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_OFF, RTL8367C_FLOWCTRL_PORT_OFF_MASK, offThreshold); -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_ON, RTL8367C_FLOWCTRL_PORT_ON_MASK, onThreshold); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicFlowControlPortThreshold -+ * Description: -+ * Get Port-based flow control parameters -+ * Input: -+ * pOnThreshold - Flow control turn ON threshold -+ * pOffThreshold - Flow control turn OFF threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicFlowControlPortThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_OFF, RTL8367C_FLOWCTRL_PORT_OFF_MASK, pOffThreshold); -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_ON, RTL8367C_FLOWCTRL_PORT_ON_MASK, pOnThreshold); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_setAsicFlowControlPortPrivateThreshold -+ * Description: -+ * Set Port-private-based flow control parameters -+ * Input: -+ * onThreshold - Flow control turn ON threshold -+ * offThreshold - Flow control turn OFF threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicFlowControlPortPrivateThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) -+{ -+ ret_t retVal; -+ -+ if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_PRIVATE_OFF, RTL8367C_FLOWCTRL_PORT_PRIVATE_OFF_MASK, offThreshold); -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_PRIVATE_ON, RTL8367C_FLOWCTRL_PORT_PRIVATE_ON_MASK, onThreshold); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicFlowControlPortPrivateThreshold -+ * Description: -+ * Get Port-private-based flow control parameters -+ * Input: -+ * pOnThreshold - Flow control turn ON threshold -+ * pOffThreshold - Flow control turn OFF threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicFlowControlPortPrivateThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_PRIVATE_OFF, RTL8367C_FLOWCTRL_PORT_PRIVATE_OFF_MASK, pOffThreshold); -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_PRIVATE_ON, RTL8367C_FLOWCTRL_PORT_PRIVATE_ON_MASK, pOnThreshold); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_setAsicFlowControlSystemDropThreshold -+ * Description: -+ * Set system-based drop parameters -+ * Input: -+ * onThreshold - Drop turn ON threshold -+ * offThreshold - Drop turn OFF threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicFlowControlSystemDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) -+{ -+ ret_t retVal; -+ -+ if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SYS_OFF, RTL8367C_FLOWCTRL_FCOFF_SYS_OFF_MASK, offThreshold); -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SYS_ON, RTL8367C_FLOWCTRL_FCOFF_SYS_ON_MASK, onThreshold); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicFlowControlSystemDropThreshold -+ * Description: -+ * Get system-based drop parameters -+ * Input: -+ * pOnThreshold - Drop turn ON threshold -+ * pOffThreshold - Drop turn OFF threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicFlowControlSystemDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SYS_OFF, RTL8367C_FLOWCTRL_FCOFF_SYS_OFF_MASK, pOffThreshold); -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SYS_ON, RTL8367C_FLOWCTRL_FCOFF_SYS_ON_MASK, pOnThreshold); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_setAsicFlowControlSharedDropThreshold -+ * Description: -+ * Set share-based fdrop parameters -+ * Input: -+ * onThreshold - Drop turn ON threshold -+ * offThreshold - Drop turn OFF threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicFlowControlSharedDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) -+{ -+ ret_t retVal; -+ -+ if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SHARE_OFF, RTL8367C_FLOWCTRL_FCOFF_SHARE_OFF_MASK, offThreshold); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SHARE_ON, RTL8367C_FLOWCTRL_FCOFF_SHARE_ON_MASK, onThreshold); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicFlowControlSharedDropThreshold -+ * Description: -+ * Get share-based fdrop parameters -+ * Input: -+ * pOnThreshold - Drop turn ON threshold -+ * pOffThreshold - Drop turn OFF threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicFlowControlSharedDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SHARE_OFF, RTL8367C_FLOWCTRL_FCOFF_SHARE_OFF_MASK, pOffThreshold); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SHARE_ON, RTL8367C_FLOWCTRL_FCOFF_SHARE_ON_MASK, pOnThreshold); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_setAsicFlowControlPortDropThreshold -+ * Description: -+ * Set Port-based drop parameters -+ * Input: -+ * onThreshold - Drop turn ON threshold -+ * offThreshold - Drop turn OFF threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicFlowControlPortDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) -+{ -+ ret_t retVal; -+ -+ if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_OFF, RTL8367C_FLOWCTRL_FCOFF_PORT_OFF_MASK, offThreshold); -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_ON, RTL8367C_FLOWCTRL_FCOFF_PORT_ON_MASK, onThreshold); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicFlowControlPortDropThreshold -+ * Description: -+ * Get Port-based drop parameters -+ * Input: -+ * pOnThreshold - Drop turn ON threshold -+ * pOffThreshold - Drop turn OFF threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicFlowControlPortDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_OFF, RTL8367C_FLOWCTRL_FCOFF_PORT_OFF_MASK, pOffThreshold); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_ON, RTL8367C_FLOWCTRL_FCOFF_PORT_ON_MASK, pOnThreshold); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_setAsicFlowControlPortPrivateDropThreshold -+ * Description: -+ * Set Port-private-based drop parameters -+ * Input: -+ * onThreshold - Drop turn ON threshold -+ * offThreshold - Drop turn OFF threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicFlowControlPortPrivateDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) -+{ -+ ret_t retVal; -+ -+ if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_PRIVATE_OFF, RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_OFF_MASK, offThreshold); -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_PRIVATE_ON, RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_ON_MASK, onThreshold); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicFlowControlPortPrivateDropThreshold -+ * Description: -+ * Get Port-private-based drop parameters -+ * Input: -+ * pOnThreshold - Drop turn ON threshold -+ * pOffThreshold - Drop turn OFF threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicFlowControlPortPrivateDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_PRIVATE_OFF, RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_OFF_MASK, pOffThreshold); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_PRIVATE_ON, RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_ON_MASK, pOnThreshold); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_setAsicFlowControlSystemJumboThreshold -+ * Description: -+ * Set Jumbo system-based flow control parameters -+ * Input: -+ * onThreshold - Flow control turn ON threshold -+ * offThreshold - Flow control turn OFF threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicFlowControlSystemJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) -+{ -+ ret_t retVal; -+ -+ if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SYS_OFF, RTL8367C_FLOWCTRL_JUMBO_SYS_OFF_MASK, offThreshold); -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SYS_ON, RTL8367C_FLOWCTRL_JUMBO_SYS_ON_MASK, onThreshold); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicFlowControlSystemJumboThreshold -+ * Description: -+ * Get Jumbo system-based flow control parameters -+ * Input: -+ * pOnThreshold - Flow control turn ON threshold -+ * pOffThreshold - Flow control turn OFF threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicFlowControlSystemJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SYS_OFF, RTL8367C_FLOWCTRL_JUMBO_SYS_OFF_MASK, pOffThreshold); -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SYS_ON, RTL8367C_FLOWCTRL_JUMBO_SYS_ON_MASK, pOnThreshold); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_setAsicFlowControlSharedJumboThreshold -+ * Description: -+ * Set Jumbo share-based flow control parameters -+ * Input: -+ * onThreshold - Flow control turn ON threshold -+ * offThreshold - Flow control turn OFF threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicFlowControlSharedJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) -+{ -+ ret_t retVal; -+ -+ if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SHARE_OFF, RTL8367C_FLOWCTRL_JUMBO_SHARE_OFF_MASK, offThreshold); -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SHARE_ON, RTL8367C_FLOWCTRL_JUMBO_SHARE_ON_MASK, onThreshold); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicFlowControlSharedJumboThreshold -+ * Description: -+ * Get Jumbo share-based flow control parameters -+ * Input: -+ * pOnThreshold - Flow control turn ON threshold -+ * pOffThreshold - Flow control turn OFF threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicFlowControlSharedJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SHARE_OFF, RTL8367C_FLOWCTRL_JUMBO_SHARE_OFF_MASK, pOffThreshold); -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SHARE_ON, RTL8367C_FLOWCTRL_JUMBO_SHARE_ON_MASK, pOnThreshold); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_setAsicFlowControlPortJumboThreshold -+ * Description: -+ * Set Jumbo Port-based flow control parameters -+ * Input: -+ * onThreshold - Flow control turn ON threshold -+ * offThreshold - Flow control turn OFF threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicFlowControlPortJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) -+{ -+ ret_t retVal; -+ -+ if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_OFF, RTL8367C_FLOWCTRL_JUMBO_PORT_OFF_MASK, offThreshold); -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_ON, RTL8367C_FLOWCTRL_JUMBO_PORT_ON_MASK, onThreshold); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicFlowControlPortJumboThreshold -+ * Description: -+ * Get Jumbo Port-based flow control parameters -+ * Input: -+ * pOnThreshold - Flow control turn ON threshold -+ * pOffThreshold - Flow control turn OFF threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicFlowControlPortJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_OFF, RTL8367C_FLOWCTRL_JUMBO_PORT_OFF_MASK, pOffThreshold); -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_ON, RTL8367C_FLOWCTRL_JUMBO_PORT_ON_MASK, pOnThreshold); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_setAsicFlowControlPortPrivateJumboThreshold -+ * Description: -+ * Set Jumbo Port-private-based flow control parameters -+ * Input: -+ * onThreshold - Flow control turn ON threshold -+ * offThreshold - Flow control turn OFF threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicFlowControlPortPrivateJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) -+{ -+ ret_t retVal; -+ -+ if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_PRIVATE_OFF, RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_OFF_MASK, offThreshold); -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_PRIVATE_ON, RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_ON_MASK, onThreshold); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicFlowControlPortPrivateJumboThreshold -+ * Description: -+ * Get Jumbo Port-private-based flow control parameters -+ * Input: -+ * pOnThreshold - Flow control turn ON threshold -+ * pOffThreshold - Flow control turn OFF threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicFlowControlPortPrivateJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_PRIVATE_OFF, RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_OFF_MASK, pOffThreshold); -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_PRIVATE_ON, RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_ON_MASK, pOnThreshold); -+ -+ return retVal; -+} -+ -+ -+ -+/* Function Name: -+ * rtl8367c_setAsicEgressFlowControlQueueDropThreshold -+ * Description: -+ * Set Queue-based egress flow control turn on or ingress flow control drop on threshold -+ * Input: -+ * qid - The queue id -+ * threshold - Queue-based flown control/drop turn ON threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * RT_ERR_QUEUE_ID - Invalid queue id -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicEgressFlowControlQueueDropThreshold(rtk_uint32 qid, rtk_uint32 threshold) -+{ -+ if( threshold >= RTL8367C_PAGE_NUMBER) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(qid > RTL8367C_QIDMAX) -+ return RT_ERR_QUEUE_ID; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_FLOWCTRL_QUEUE_DROP_ON_REG(qid), RTL8367C_FLOWCTRL_QUEUE_DROP_ON_MASK, threshold); -+} -+/* Function Name: -+ * rtl8367c_getAsicEgressFlowControlQueueDropThreshold -+ * Description: -+ * Get Queue-based egress flow control turn on or ingress flow control drop on threshold -+ * Input: -+ * qid - The queue id -+ * pThreshold - Queue-based flown control/drop turn ON threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QUEUE_ID - Invalid queue id -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicEgressFlowControlQueueDropThreshold(rtk_uint32 qid, rtk_uint32 *pThreshold) -+{ -+ if(qid > RTL8367C_QIDMAX) -+ return RT_ERR_QUEUE_ID; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_FLOWCTRL_QUEUE_DROP_ON_REG(qid), RTL8367C_FLOWCTRL_QUEUE_DROP_ON_MASK, pThreshold); -+} -+/* Function Name: -+ * rtl8367c_setAsicEgressFlowControlPortDropThreshold -+ * Description: -+ * Set port-based egress flow control turn on or ingress flow control drop on threshold -+ * Input: -+ * port - Physical port number (0~7) -+ * threshold - Queue-based flown control/drop turn ON threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicEgressFlowControlPortDropThreshold(rtk_uint32 port, rtk_uint32 threshold) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(threshold >= RTL8367C_PAGE_NUMBER) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_FLOWCTRL_PORT_DROP_ON_REG(port), RTL8367C_FLOWCTRL_PORT_DROP_ON_MASK, threshold); -+} -+/* Function Name: -+ * rtl8367c_setAsicEgressFlowControlPortDropThreshold -+ * Description: -+ * Set port-based egress flow control turn on or ingress flow control drop on threshold -+ * Input: -+ * port - Physical port number (0~7) -+ * pThreshold - Queue-based flown control/drop turn ON threshold -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicEgressFlowControlPortDropThreshold(rtk_uint32 port, rtk_uint32 *pThreshold) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_FLOWCTRL_PORT_DROP_ON_REG(port), RTL8367C_FLOWCTRL_PORT_DROP_ON_MASK, pThreshold); -+} -+/* Function Name: -+ * rtl8367c_setAsicEgressFlowControlPortDropGap -+ * Description: -+ * Set port-based egress flow control turn off or ingress flow control drop off gap -+ * Input: -+ * gap - Flow control/drop turn OFF threshold = turn ON threshold - gap -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicEgressFlowControlPortDropGap(rtk_uint32 gap) -+{ -+ if(gap >= RTL8367C_PAGE_NUMBER) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_GAP, RTL8367C_FLOWCTRL_PORT_GAP_MASK, gap); -+} -+/* Function Name: -+ * rtl8367c_getAsicEgressFlowControlPortDropGap -+ * Description: -+ * Get port-based egress flow control turn off or ingress flow control drop off gap -+ * Input: -+ * pGap - Flow control/drop turn OFF threshold = turn ON threshold - gap -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicEgressFlowControlPortDropGap(rtk_uint32 *pGap) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_GAP, RTL8367C_FLOWCTRL_PORT_GAP_MASK, pGap); -+} -+/* Function Name: -+ * rtl8367c_setAsicEgressFlowControlQueueDropGap -+ * Description: -+ * Set Queue-based egress flow control turn off or ingress flow control drop off gap -+ * Input: -+ * gap - Flow control/drop turn OFF threshold = turn ON threshold - gap -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicEgressFlowControlQueueDropGap(rtk_uint32 gap) -+{ -+ if(gap >= RTL8367C_PAGE_NUMBER) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_QUEUE_GAP, RTL8367C_FLOWCTRL_QUEUE_GAP_MASK, gap); -+} -+/* Function Name: -+ * rtl8367c_getAsicEgressFlowControlQueueDropGap -+ * Description: -+ * Get Queue-based egress flow control turn off or ingress flow control drop off gap -+ * Input: -+ * pGap - Flow control/drop turn OFF threshold = turn ON threshold - gap -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicEgressFlowControlQueueDropGap(rtk_uint32 *pGap) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_QUEUE_GAP, RTL8367C_FLOWCTRL_QUEUE_GAP_MASK, pGap); -+} -+/* Function Name: -+ * rtl8367c_getAsicEgressQueueEmptyPortMask -+ * Description: -+ * Get queue empty port mask -+ * Input: -+ * pPortmask - Queue empty port mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicEgressQueueEmptyPortMask(rtk_uint32 *pPortmask) -+{ -+ return rtl8367c_getAsicReg(RTL8367C_REG_PORT_QEMPTY, pPortmask); -+} -+/* Function Name: -+ * rtl8367c_getAsicTotalPage -+ * Description: -+ * Get system total page usage number -+ * Input: -+ * pPageCount - page usage number -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicTotalPage(rtk_uint32 *pPageCount) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_TOTAL_PAGE_COUNTER, RTL8367C_FLOWCTRL_TOTAL_PAGE_COUNTER_MASK, pPageCount); -+} -+/* Function Name: -+ * rtl8367c_getAsicPulbicPage -+ * Description: -+ * Get system public page usage number -+ * Input: -+ * pPageCount - page usage number -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPulbicPage(rtk_uint32 *pPageCount) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PUBLIC_PAGE_COUNTER, RTL8367C_FLOWCTRL_PUBLIC_PAGE_COUNTER_MASK, pPageCount); -+} -+/* Function Name: -+ * rtl8367c_getAsicMaxTotalPage -+ * Description: -+ * Get system total page max usage number -+ * Input: -+ * pPageCount - page usage number -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicMaxTotalPage(rtk_uint32 *pPageCount) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_TOTAL_PAGE_MAX, RTL8367C_FLOWCTRL_TOTAL_PAGE_MAX_MASK, pPageCount); -+} -+/* Function Name: -+ * rtl8367c_getAsicPulbicPage -+ * Description: -+ * Get system public page max usage number -+ * Input: -+ * pPageCount - page usage number -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicMaxPulbicPage(rtk_uint32 *pPageCount) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PUBLIC_PAGE_MAX, RTL8367C_FLOWCTRL_PUBLIC_PAGE_MAX_MASK, pPageCount); -+} -+/* Function Name: -+ * rtl8367c_getAsicPortPage -+ * Description: -+ * Get per-port page usage number -+ * Input: -+ * port - Physical port number (0~7) -+ * pPageCount - page usage number -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortPage(rtk_uint32 port, rtk_uint32 *pPageCount) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(port < 8) -+ return rtl8367c_getAsicRegBits(RTL8367C_FLOWCTRL_PORT_PAGE_COUNTER_REG(port), RTL8367C_FLOWCTRL_PORT_PAGE_COUNTER_MASK, pPageCount); -+ else -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT8_PAGE_COUNTER+port - 8, RTL8367C_FLOWCTRL_PORT_PAGE_COUNTER_MASK, pPageCount); -+} -+/* Function Name: -+ * rtl8367c_getAsicPortPage -+ * Description: -+ * Get per-port page max usage number -+ * Input: -+ * port - Physical port number (0~7) -+ * pPageCount - page usage number -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortPageMax(rtk_uint32 port, rtk_uint32 *pPageCount) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ if(port < 8) -+ return rtl8367c_getAsicRegBits(RTL8367C_FLOWCTRL_PORT_PAGE_MAX_REG(port), RTL8367C_FLOWCTRL_PORT_PAGE_MAX_MASK, pPageCount); -+ else -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT0_PAGE_MAX+port-8, RTL8367C_FLOWCTRL_PORT_PAGE_MAX_MASK, pPageCount); -+ -+ -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicFlowControlEgressPortIndep -+ * Description: -+ * Set per-port egress flow control independent -+ * Input: -+ * port - Physical port number (0~7) -+ * enabled - Egress port flow control usage 1:enable 0:disable. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicFlowControlEgressPortIndep(rtk_uint32 port, rtk_uint32 enable) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_PORT0_MISC_CFG + (port *0x20), RTL8367C_PORT0_MISC_CFG_FLOWCTRL_INDEP_OFFSET,enable); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicFlowControlEgressPortIndep -+ * Description: -+ * Get per-port egress flow control independent -+ * Input: -+ * port - Physical port number (0~7) -+ * enabled - Egress port flow control usage 1:enable 0:disable. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicFlowControlEgressPortIndep(rtk_uint32 port, rtk_uint32 *pEnable) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_PORT0_MISC_CFG + (port *0x20),RTL8367C_PORT0_MISC_CFG_FLOWCTRL_INDEP_OFFSET,pEnable); -+} -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_green.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_green.c -new file mode 100644 -index 000000000000..3fb5f57b914b ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_green.c -@@ -0,0 +1,445 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Green Ethernet related functions -+ * -+ */ -+#include -+ -+/* Function Name: -+ * rtl8367c_getAsicGreenPortPage -+ * Description: -+ * Get per-Port ingress page usage per second -+ * Input: -+ * port - Physical port number (0~7) -+ * pPage - page number of ingress packet occurring per second -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * Ingress traffic occurring page number per second for high layer green feature usage -+ */ -+ret_t rtl8367c_getAsicGreenPortPage(rtk_uint32 port, rtk_uint32* pPage) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ rtk_uint32 pageMeter; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ retVal = rtl8367c_getAsicReg(RTL8367C_PAGEMETER_PORT_REG(port), ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ pageMeter = regData; -+ -+ retVal = rtl8367c_getAsicReg(RTL8367C_PAGEMETER_PORT_REG(port) + 1, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ pageMeter = pageMeter + (regData << 16); -+ -+ *pPage = pageMeter; -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicGreenTrafficType -+ * Description: -+ * Set traffic type for each priority -+ * Input: -+ * priority - internal priority (0~7) -+ * traffictype - high/low traffic type, 1:high priority traffic type, 0:low priority traffic type -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicGreenTrafficType(rtk_uint32 priority, rtk_uint32 traffictype) -+{ -+ -+ if(priority > RTL8367C_PRIMAX) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_HIGHPRI_CFG, priority, (traffictype?1:0)); -+} -+/* Function Name: -+ * rtl8367c_getAsicGreenTrafficType -+ * Description: -+ * Get traffic type for each priority -+ * Input: -+ * priority - internal priority (0~7) -+ * pTraffictype - high/low traffic type, 1:high priority traffic type, 0:low priority traffic type -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicGreenTrafficType(rtk_uint32 priority, rtk_uint32* pTraffictype) -+{ -+ if(priority > RTL8367C_PRIMAX) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_HIGHPRI_CFG, priority, pTraffictype); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicGreenHighPriorityTraffic -+ * Description: -+ * Set indicator which ASIC had received high priority traffic -+ * Input: -+ * port - Physical port number (0~7) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicGreenHighPriorityTraffic(rtk_uint32 port) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_HIGHPRI_INDICATOR, port, 1); -+} -+ -+ -+/* Function Name: -+ * rtl8367c_getAsicGreenHighPriorityTraffic -+ * Description: -+ * Get indicator which ASIC had received high priority traffic or not -+ * Input: -+ * port - Physical port number (0~7) -+ * pIndicator - Have received high priority traffic indicator. If 1 means ASCI had received high priority in 1second checking period -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicGreenHighPriorityTraffic(rtk_uint32 port, rtk_uint32* pIndicator) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_HIGHPRI_INDICATOR, port, pIndicator); -+} -+ -+/* -+@func rtk_int32 | rtl8367c_setAsicGreenEthernet | Set green Ethernet function. -+@parm rtk_uint32 | green | Green feature function usage 1:enable 0:disable. -+@rvalue RT_ERR_OK | Success. -+@rvalue RT_ERR_SMI | SMI access error. -+@comm -+ The API can set Green Ethernet function to reduce power consumption. While green feature is enabled, ASIC will automatic -+ detect the cable length and then select different power mode for best performance with minimums power consumption. Link down -+ ports will enter power saving mode in 10 seconds after the cable disconnected if power saving function is enabled. -+*/ -+ret_t rtl8367c_setAsicGreenEthernet(rtk_uint32 port, rtk_uint32 green) -+{ -+ ret_t retVal; -+ rtk_uint32 checkCounter; -+ rtk_uint32 regData; -+ rtk_uint32 phy_status; -+ rtk_uint32 patchData[6][2] = { {0x809A, 0x8911}, {0x80A3, 0x9233}, {0x80AC, 0xA444}, {0x809F, 0x6B20}, {0x80A8, 0x6B22}, {0x80B1, 0x6B23} }; -+ rtk_uint32 idx; -+ rtk_uint32 data; -+ -+ if (green > 1) -+ return RT_ERR_INPUT; -+ -+ /* 0xa420[2:0] */ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xA420, ®Data)) != RT_ERR_OK) -+ return retVal; -+ phy_status = (regData & 0x0007); -+ -+ if(phy_status == 3) -+ { -+ /* 0xb820[4] = 1 */ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xB820, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ regData |= (0x0001 << 4); -+ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xB820, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ /* wait 0xb800[6] = 1 */ -+ checkCounter = 100; -+ while(checkCounter) -+ { -+ retVal = rtl8367c_getAsicPHYOCPReg(port, 0xB800, ®Data); -+ if( (retVal != RT_ERR_OK) || ((regData & 0x0040) != 0x0040) ) -+ { -+ checkCounter --; -+ if(0 == checkCounter) -+ return RT_ERR_BUSYWAIT_TIMEOUT; -+ } -+ else -+ checkCounter = 0; -+ } -+ } -+ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicReg(0x1300, &data)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) -+ return retVal; -+ -+ switch (data) -+ { -+ case 0x0276: -+ case 0x0597: -+ case 0x6367: -+ if(green) -+ { -+ for(idx = 0; idx < 6; idx++ ) -+ { -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xA436, patchData[idx][0])) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xA438, patchData[idx][1])) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ break; -+ default: -+ break;; -+ } -+ -+ -+ -+ /* 0xa436 = 0x8011 */ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xA436, 0x8011)) != RT_ERR_OK) -+ return retVal; -+ -+ /* wr 0xa438[15] = 0: disable, 1: enable */ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xA438, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ if(green) -+ regData |= 0x8000; -+ else -+ regData &= 0x7FFF; -+ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xA438, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ if(phy_status == 3) -+ { -+ /* 0xb820[4] = 0 */ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xB820, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ regData &= ~(0x0001 << 4); -+ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xB820, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ /* wait 0xb800[6] = 0 */ -+ checkCounter = 100; -+ while(checkCounter) -+ { -+ retVal = rtl8367c_getAsicPHYOCPReg(port, 0xB800, ®Data); -+ if( (retVal != RT_ERR_OK) || ((regData & 0x0040) != 0x0000) ) -+ { -+ checkCounter --; -+ if(0 == checkCounter) -+ return RT_ERR_BUSYWAIT_TIMEOUT; -+ } -+ else -+ checkCounter = 0; -+ } -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* -+@func rtk_int32 | rtl8367c_getAsicGreenEthernet | Get green Ethernet function. -+@parm rtk_uint32 | *green | Green feature function usage 1:enable 0:disable. -+@rvalue RT_ERR_OK | Success. -+@rvalue RT_ERR_SMI | SMI access error. -+@comm -+ The API can set Green Ethernet function to reduce power consumption. While green feature is enabled, ASIC will automatic -+ detect the cable length and then select different power mode for best performance with minimums power consumption. Link down -+ ports will enter power saving mode in 10 seconds after the cable disconnected if power saving function is enabled. -+*/ -+ret_t rtl8367c_getAsicGreenEthernet(rtk_uint32 port, rtk_uint32* green) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ -+ /* 0xa436 = 0x8011 */ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xA436, 0x8011)) != RT_ERR_OK) -+ return retVal; -+ -+ /* wr 0xa438[15] = 0: disable, 1: enable */ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xA438, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ if(regData & 0x8000) -+ *green = ENABLED; -+ else -+ *green = DISABLED; -+ -+ return RT_ERR_OK; -+} -+ -+ -+/* -+@func ret_t | rtl8367c_setAsicPowerSaving | Set power saving mode -+@parm rtk_uint32 | phy | phy number -+@parm rtk_uint32 | enable | enable power saving mode. -+@rvalue RT_ERR_OK | Success. -+@rvalue RT_ERR_SMI | SMI access error. -+@rvalue RT_ERR_PORT_ID | Invalid port number. -+@comm -+ The API can set power saving mode per phy. -+*/ -+ret_t rtl8367c_setAsicPowerSaving(rtk_uint32 phy, rtk_uint32 enable) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 phyData; -+ rtk_uint32 regData; -+ rtk_uint32 phy_status; -+ rtk_uint32 checkCounter; -+ -+ if (enable > 1) -+ return RT_ERR_INPUT; -+ -+ /* 0xa420[2:0] */ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(phy, 0xA420, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ phy_status = (regData & 0x0007); -+ -+ if(phy_status == 3) -+ { -+ /* 0xb820[4] = 1 */ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(phy, 0xB820, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ regData |= (0x0001 << 4); -+ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(phy, 0xB820, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ /* wait 0xb800[6] = 1 */ -+ checkCounter = 100; -+ while(checkCounter) -+ { -+ retVal = rtl8367c_getAsicPHYOCPReg(phy, 0xB800, ®Data); -+ if( (retVal != RT_ERR_OK) || ((regData & 0x0040) != 0x0040) ) -+ { -+ checkCounter --; -+ if(0 == checkCounter) -+ { -+ return RT_ERR_BUSYWAIT_TIMEOUT; -+ } -+ } -+ else -+ checkCounter = 0; -+ } -+ } -+ -+ if ((retVal = rtl8367c_getAsicPHYReg(phy,PHY_POWERSAVING_REG,&phyData))!=RT_ERR_OK) -+ return retVal; -+ -+ phyData = phyData & ~(0x0001 << 2); -+ phyData = phyData | (enable << 2); -+ -+ if ((retVal = rtl8367c_setAsicPHYReg(phy,PHY_POWERSAVING_REG,phyData))!=RT_ERR_OK) -+ return retVal; -+ -+ if(phy_status == 3) -+ { -+ /* 0xb820[4] = 0 */ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(phy, 0xB820, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ regData &= ~(0x0001 << 4); -+ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(phy, 0xB820, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ /* wait 0xb800[6] = 0 */ -+ checkCounter = 100; -+ while(checkCounter) -+ { -+ retVal = rtl8367c_getAsicPHYOCPReg(phy, 0xB800, ®Data); -+ if( (retVal != RT_ERR_OK) || ((regData & 0x0040) != 0x0000) ) -+ { -+ checkCounter --; -+ if(0 == checkCounter) -+ { -+ return RT_ERR_BUSYWAIT_TIMEOUT; -+ } -+ } -+ else -+ checkCounter = 0; -+ } -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* -+@func ret_t | rtl8367c_getAsicPowerSaving | Get power saving mode -+@parm rtk_uint32 | port | The port number -+@parm rtk_uint32* | enable | enable power saving mode. -+@rvalue RT_ERR_OK | Success. -+@rvalue RT_ERR_SMI | SMI access error. -+@rvalue RT_ERR_PORT_ID | Invalid port number. -+@comm -+ The API can get power saving mode per phy. -+*/ -+ret_t rtl8367c_getAsicPowerSaving(rtk_uint32 phy, rtk_uint32* enable) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 phyData; -+ -+ if(NULL == enable) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicPHYReg(phy,PHY_POWERSAVING_REG,&phyData))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((phyData & 0x0004) > 0) -+ *enable = 1; -+ else -+ *enable = 0; -+ -+ return RT_ERR_OK; -+} -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_hsb.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_hsb.c -new file mode 100644 -index 000000000000..1b8ef59d9537 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_hsb.c -@@ -0,0 +1,81 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Field selector related functions -+ * -+ */ -+#include -+/* Function Name: -+ * rtl8367c_setAsicFieldSelector -+ * Description: -+ * Set user defined field selectors in HSB -+ * Input: -+ * index - index of field selector 0-15 -+ * format - Format of field selector -+ * offset - Retrieving data offset -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * System support 16 user defined field selectors. -+ * Each selector can be enabled or disable. User can defined retrieving 16-bits in many predefiend -+ * standard l2/l3/l4 payload. -+ */ -+ret_t rtl8367c_setAsicFieldSelector(rtk_uint32 index, rtk_uint32 format, rtk_uint32 offset) -+{ -+ rtk_uint32 regData; -+ -+ if(index > RTL8367C_FIELDSEL_FORMAT_NUMBER) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(format >= FIELDSEL_FORMAT_END) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ regData = (((format << RTL8367C_FIELD_SELECTOR_FORMAT_OFFSET) & RTL8367C_FIELD_SELECTOR_FORMAT_MASK ) | -+ ((offset << RTL8367C_FIELD_SELECTOR_OFFSET_OFFSET) & RTL8367C_FIELD_SELECTOR_OFFSET_MASK )); -+ -+ return rtl8367c_setAsicReg(RTL8367C_FIELD_SELECTOR_REG(index), regData); -+} -+/* Function Name: -+ * rtl8367c_getAsicFieldSelector -+ * Description: -+ * Get user defined field selectors in HSB -+ * Input: -+ * index - index of field selector 0-15 -+ * pFormat - Format of field selector -+ * pOffset - Retrieving data offset -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicFieldSelector(rtk_uint32 index, rtk_uint32* pFormat, rtk_uint32* pOffset) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ -+ retVal = rtl8367c_getAsicReg(RTL8367C_FIELD_SELECTOR_REG(index), ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *pFormat = ((regData & RTL8367C_FIELD_SELECTOR_FORMAT_MASK) >> RTL8367C_FIELD_SELECTOR_FORMAT_OFFSET); -+ *pOffset = ((regData & RTL8367C_FIELD_SELECTOR_OFFSET_MASK) >> RTL8367C_FIELD_SELECTOR_OFFSET_OFFSET); -+ -+ return RT_ERR_OK; -+} -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_i2c.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_i2c.c -new file mode 100644 -index 000000000000..69f20a0188b5 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_i2c.c -@@ -0,0 +1,474 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 38651 $ -+ * $Date: 2016-02-27 14:32:56 +0800 (周三, 17 四月 2016) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : I2C related functions -+ * -+ */ -+ -+ -+#include -+#include -+#include -+ -+ -+ -+/* Function Name: -+ * rtl8367c_setAsicI2C_checkBusIdle -+ * Description: -+ * Check i2c bus status idle or not -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_BUSYWAIT_TIMEOUT - i2c bus is busy -+ * Note: -+ * This API can check i2c bus status. -+ */ -+ret_t rtl8367c_setAsicI2C_checkBusIdle(void) -+{ -+ rtk_uint32 regData; -+ ret_t retVal; -+ -+ if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_M_I2C_BUS_IDLE_OFFSET, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ if(regData == 0x0001) -+ return RT_ERR_OK; /*i2c is idle*/ -+ else -+ return RT_ERR_BUSYWAIT_TIMEOUT; /*i2c is busy*/ -+} -+ -+ -+/* Function Name: -+ * rtl8367c_setAsicI2CStartCmd -+ * Description: -+ * Set I2C start command -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * Note: -+ * This API can set i2c start command ,start a i2c traffic . -+ */ -+ret_t rtl8367c_setAsicI2CStartCmd(void) -+{ -+ rtk_uint32 regData; -+ ret_t retVal; -+ -+ /* Bits [4-1] = 0b0000, Start Command; Bit [0] = 1, Trigger the Command */ -+ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) -+ return retVal; -+ regData &= 0xFFE0; -+ regData |= 0x0001; -+ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ /* wait for command finished */ -+ do{ -+ if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_I2C_CMD_EXEC_OFFSET, ®Data)) != RT_ERR_OK) -+ return retVal; -+ }while( regData != 0x0); -+ -+ return RT_ERR_OK ; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicI2CStopCmd -+ * Description: -+ * Set I2C stop command -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * Note: -+ * This API can set i2c stop command ,stop a i2c traffic. -+ */ -+ret_t rtl8367c_setAsicI2CStopCmd(void) -+{ -+ -+ rtk_uint32 regData; -+ ret_t retVal; -+ -+ /* Bits [4-1] = 0b0001, Stop Command; Bit [0] = 1, Trigger the Command */ -+ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) -+ return retVal; -+ regData &= 0xFFE0; -+ regData |= 0x0003; -+ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ -+ /* wait for command finished */ -+ do{ -+ if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_I2C_CMD_EXEC_OFFSET, ®Data)) != RT_ERR_OK) -+ return retVal; -+ }while( regData != 0x0); -+ -+ return RT_ERR_OK ; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicI2CTxOneCharCmd -+ * Description: -+ * Set I2C Tx a char command, with a 8-bit data -+ * Input: -+ * oneChar - 8-bit data -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * Note: -+ * This API can set i2c Tx command and with a 8-bit data. -+ */ -+ret_t rtl8367c_setAsicI2CTxOneCharCmd(rtk_uint8 oneChar) -+{ -+ rtk_uint32 regData; -+ ret_t retVal; -+ -+ /* Bits [4-1] = 0b0010, tx one char; Bit [0] = 1, Trigger the Command */ -+ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ regData &= 0xFFE0; -+ regData |= 0x0005; -+ regData &= 0x00FF; -+ regData |= (rtk_uint16) (oneChar << 8); -+ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ -+ /* wait for command finished */ -+ do{ -+ if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_I2C_CMD_EXEC_OFFSET, ®Data)) != RT_ERR_OK) -+ return retVal; -+ }while( regData != 0x0); -+ -+ return RT_ERR_OK ; -+} -+ -+ -+/* Function Name: -+ * rtl8367c_setAsicI2CcheckRxAck -+ * Description: -+ * Check if rx an Ack -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * Note: -+ * This API can check if rx an ack from i2c slave. -+ */ -+ret_t rtl8367c_setAsicI2CcheckRxAck(void) -+{ -+ rtk_uint32 regData; -+ ret_t retVal; -+ rtk_uint32 count = 0; -+ -+ do{ -+ count++; -+ if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_SLV_ACK_FLAG_OFFSET, ®Data)) != RT_ERR_OK) -+ return retVal; -+ }while( (regData != 0x1) && (count < TIMEROUT_FOR_MICROSEMI) ); -+ -+ if(regData != 0x1) -+ return RT_ERR_FAILED; -+ else -+ return RT_ERR_OK; -+} -+ -+ -+/* Function Name: -+ * rtl8367c_setAsicI2CRxOneCharCmd -+ * Description: -+ * Set I2C Rx command and get 8-bit data -+ * Input: -+ * None -+ * Output: -+ * pValue - 8bit-data -+ * Return: -+ * RT_ERR_OK - Success -+ * Note: -+ * This API can set I2C Rx command and get 8-bit data. -+ */ -+ret_t rtl8367c_setAsicI2CRxOneCharCmd(rtk_uint8 *pValue) -+{ -+ rtk_uint32 regData; -+ ret_t retVal; -+ -+ /* Bits [4-1] = 0b0011, Rx one char; Bit [0] = 1, Trigger the Command */ -+ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) -+ return retVal; -+ regData &= 0xFFE0; -+ regData |= 0x0007; -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ /* wait for command finished */ -+ do{ -+ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) -+ return retVal; -+ }while( (regData & 0x1) != 0x0); -+ -+ *pValue = (rtk_uint8)(regData >> 8); -+ return RT_ERR_OK ; -+ -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicI2CTxAckCmd -+ * Description: -+ * Set I2C Tx ACK command -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * Note: -+ * This API can set I2C Tx ack command. -+ */ -+ret_t rtl8367c_setAsicI2CTxAckCmd(void) -+{ -+ rtk_uint32 regData; -+ ret_t retVal; -+ -+ /* Bits [4-1] = 0b0100, tx ACK Command; Bit [0] = 1, Trigger the Command */ -+ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) -+ return retVal; -+ regData &= 0xFFE0; -+ regData |= 0x0009; -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ /* wait for command finished */ -+ do{ -+ if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_I2C_CMD_EXEC_OFFSET, ®Data)) != RT_ERR_OK) -+ return retVal; -+ }while( regData != 0x0); -+ -+ return RT_ERR_OK ; -+ -+} -+ -+ -+/* Function Name: -+ * rtl8367c_setAsicI2CTxNoAckCmd -+ * Description: -+ * Set I2C master Tx noACK command -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * Note: -+ * This API can set I2C master Tx noACK command. -+ */ -+ret_t rtl8367c_setAsicI2CTxNoAckCmd(void) -+{ -+ rtk_uint32 regData; -+ ret_t retVal; -+ -+ /* Bits [4-1] = 0b0101, tx noACK Command; Bit [0] = 1, Trigger the Command */ -+ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) -+ return retVal; -+ regData &= 0xFFE0; -+ regData |= 0x000b; -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ /* wait for command finished */ -+ do{ -+ if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_I2C_CMD_EXEC_OFFSET, ®Data)) != RT_ERR_OK) -+ return retVal; -+ }while( regData != 0x0); -+ -+ return RT_ERR_OK ; -+ -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicI2CSoftRSTseqCmd -+ * Description: -+ * set I2C master tx soft reset command -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * Note: -+ * This API can set I2C master tx soft reset command. -+ */ -+ret_t rtl8367c_setAsicI2CSoftRSTseqCmd(void) -+{ -+ -+ rtk_uint32 regData; -+ ret_t retVal; -+ -+ /*Bits [4-1] = 0b0110, tx soft reset Command; Bit [0] = 1, Trigger the Command */ -+ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) -+ return retVal; -+ regData &= 0xFFE0; -+ regData |= 0x000d; -+ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ -+ /* wait for command finished */ -+ do{ -+ if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_I2C_CMD_EXEC_OFFSET, ®Data)) != RT_ERR_OK) -+ return retVal; -+ }while( regData != 0x0); -+ -+ return RT_ERR_OK ; -+} -+ -+ -+/* Function Name: -+ * rtl8367c_setAsicI2CGpioPinGroup -+ * Description: -+ * set I2C function used gpio pins -+ * Input: -+ * pinGroup_ID - gpio pins group -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_INPUT _ Invalid input parameter -+ * Note: -+ * This API can set I2C function used gpio pins. -+ * There are three group gpio pins -+ */ -+ret_t rtl8367c_setAsicI2CGpioPinGroup(rtk_uint32 pinGroup_ID) -+{ -+ rtk_uint32 regData; -+ ret_t retVal; -+ -+ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_SYS_CTL, ®Data)) != RT_ERR_OK) -+ return retVal; -+ if( pinGroup_ID==0 ) -+ { -+ regData &= 0x0FFF; -+ regData |= 0x5000; -+ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_SYS_CTL, regData)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ else if( pinGroup_ID==1 ) -+ { -+ regData &= 0x0FFF; -+ regData |= 0xA000; -+ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_SYS_CTL, regData)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ else if( pinGroup_ID==2 ) -+ { -+ regData &= 0x0FFF; -+ regData |= 0xF000; -+ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_SYS_CTL, regData)) != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ return RT_ERR_INPUT; -+ -+ return RT_ERR_OK ; -+ -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicI2CGpioPinGroup -+ * Description: -+ * set I2C function used gpio pins -+ * Input: -+ * pinGroup_ID - gpio pins group -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_INPUT _ Invalid input parameter -+ * Note: -+ * This API can set I2C function used gpio pins. -+ * There are three group gpio pins -+ */ -+ret_t rtl8367c_getAsicI2CGpioPinGroup(rtk_uint32 * pPinGroup_ID) -+{ -+ -+ rtk_uint32 regData; -+ ret_t retVal; -+ if( (retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_SYS_CTL, ®Data)) != RT_ERR_OK) -+ return retVal; -+ regData &= 0xF000 ; -+ regData = (regData >> 12); -+ -+ if( regData == 0x5 ) -+ *pPinGroup_ID = 0; -+ else if(regData == 0xA) -+ *pPinGroup_ID = 1; -+ else if(regData == 0xF) -+ *pPinGroup_ID = 2; -+ else -+ return RT_ERR_FAILED; -+ return RT_ERR_OK ; -+} -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_igmp.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_igmp.c -new file mode 100644 -index 000000000000..c915d2d61878 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_igmp.c -@@ -0,0 +1,2109 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : IGMP related functions -+ * -+ */ -+#include -+/* Function Name: -+ * rtl8367c_setAsicIgmp -+ * Description: -+ * Set IGMP/MLD state -+ * Input: -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicIgmp(rtk_uint32 enabled) -+{ -+ ret_t retVal; -+ -+ /* Enable/Disable H/W IGMP/MLD */ -+ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_EN_OFFSET, enabled); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicIgmp -+ * Description: -+ * Get IGMP/MLD state -+ * Input: -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIgmp(rtk_uint32 *ptr_enabled) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_EN_OFFSET, ptr_enabled); -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_setAsicIpMulticastVlanLeaky -+ * Description: -+ * Set IP multicast VLAN Leaky function -+ * Input: -+ * port - Physical port number (0~7) -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * When enabling this function, -+ * if the lookup result(forwarding portmap) of IP Multicast packet is over VLAN boundary, -+ * the packet can be forwarded across VLAN -+ */ -+ret_t rtl8367c_setAsicIpMulticastVlanLeaky(rtk_uint32 port, rtk_uint32 enabled) -+{ -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IPMCAST_VLAN_LEAKY, port, enabled); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicIpMulticastVlanLeaky -+ * Description: -+ * Get IP multicast VLAN Leaky function -+ * Input: -+ * port - Physical port number (0~7) -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIpMulticastVlanLeaky(rtk_uint32 port, rtk_uint32 *ptr_enabled) -+{ -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_IPMCAST_VLAN_LEAKY, port, ptr_enabled); -+ -+ return retVal; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicIGMPTableFullOP -+ * Description: -+ * Set Table Full operation -+ * Input: -+ * operation - The operation should be taken when the IGMP table is full. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter is out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicIGMPTableFullOP(rtk_uint32 operation) -+{ -+ ret_t retVal; -+ -+ if(operation >= TABLE_FULL_OP_END) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ /* Table full Operation */ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG1, RTL8367C_TABLE_FULL_OP_MASK, operation); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicIGMPTableFullOP -+ * Description: -+ * Get Table Full operation -+ * Input: -+ * None -+ * Output: -+ * poperation - The operation should be taken when the IGMP table is full. -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIGMPTableFullOP(rtk_uint32 *poperation) -+{ -+ ret_t retVal; -+ rtk_uint32 value; -+ -+ /* Table full Operation */ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG1, RTL8367C_TABLE_FULL_OP_MASK, &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *poperation = value; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicIGMPCRCErrOP -+ * Description: -+ * Set the operation when ASIC receive a Checksum error packet -+ * Input: -+ * operation -The operation when ASIC receive a Checksum error packet -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter is out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicIGMPCRCErrOP(rtk_uint32 operation) -+{ -+ ret_t retVal; -+ -+ if(operation >= CRC_ERR_OP_END) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ /* CRC Error Operation */ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_CKS_ERR_OP_MASK, operation); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicIGMPCRCErrOP -+ * Description: -+ * Get the operation when ASIC receive a Checksum error packet -+ * Input: -+ * None -+ * Output: -+ * poperation - The operation of Checksum error packet -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIGMPCRCErrOP(rtk_uint32 *poperation) -+{ -+ ret_t retVal; -+ rtk_uint32 value; -+ -+ /* CRC Error Operation */ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_CKS_ERR_OP_MASK, &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *poperation = value; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicIGMPFastLeaveEn -+ * Description: -+ * Enable/Disable Fast Leave -+ * Input: -+ * enabled - 1:enable Fast Leave; 0:disable Fast Leave -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicIGMPFastLeaveEn(rtk_uint32 enabled) -+{ -+ ret_t retVal; -+ -+ /* Fast Leave */ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_FAST_LEAVE_EN_MASK, (enabled >= 1) ? 1 : 0); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicIGMPFastLeaveEn -+ * Description: -+ * Get Fast Leave state -+ * Input: -+ * None -+ * Output: -+ * penabled - 1:enable Fast Leave; 0:disable Fast Leave -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIGMPFastLeaveEn(rtk_uint32 *penabled) -+{ -+ ret_t retVal; -+ rtk_uint32 value; -+ -+ /* Fast Leave */ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_FAST_LEAVE_EN_MASK, &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *penabled = value; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicIGMPLeaveTimer -+ * Description: -+ * Set the Leave timer of IGMP/MLD -+ * Input: -+ * leave_timer - Leave timer -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter is out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicIGMPLeaveTimer(rtk_uint32 leave_timer) -+{ -+ ret_t retVal; -+ -+ if(leave_timer > RTL8367C_MAX_LEAVE_TIMER) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ /* Leave timer */ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_LEAVE_TIMER_MASK, leave_timer); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicIGMPLeaveTimer -+ * Description: -+ * Get the Leave timer of IGMP/MLD -+ * Input: -+ * None -+ * Output: -+ * pleave_timer - Leave timer -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIGMPLeaveTimer(rtk_uint32 *pleave_timer) -+{ -+ ret_t retVal; -+ rtk_uint32 value; -+ -+ /* Leave timer */ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_LEAVE_TIMER_MASK, &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *pleave_timer = value; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicIGMPQueryInterval -+ * Description: -+ * Set Query Interval of IGMP/MLD -+ * Input: -+ * interval - Query Interval -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter is out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicIGMPQueryInterval(rtk_uint32 interval) -+{ -+ ret_t retVal; -+ -+ if(interval > RTL8367C_MAX_QUERY_INT) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ /* Query Interval */ -+ retVal = rtl8367c_setAsicReg(RTL8367C_REG_IGMP_MLD_CFG2, interval); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicIGMPQueryInterval -+ * Description: -+ * Get Query Interval of IGMP/MLD -+ * Input: -+ * None -+ * Output: -+ * pinterval - Query Interval -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIGMPQueryInterval(rtk_uint32 *pinterval) -+{ -+ ret_t retVal; -+ rtk_uint32 value; -+ -+ /* Query Interval */ -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_IGMP_MLD_CFG2, &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *pinterval = value; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicIGMPRobVar -+ * Description: -+ * Set Robustness Variable of IGMP/MLD -+ * Input: -+ * rob_var - Robustness Variable -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter is out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicIGMPRobVar(rtk_uint32 rob_var) -+{ -+ ret_t retVal; -+ -+ if(rob_var > RTL8367C_MAX_ROB_VAR) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ /* Robustness variable */ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_ROBUSTNESS_VAR_MASK, rob_var); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicIGMPRobVar -+ * Description: -+ * Get Robustness Variable of IGMP/MLD -+ * Input: -+ * none -+ * Output: -+ * prob_var - Robustness Variable -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIGMPRobVar(rtk_uint32 *prob_var) -+{ -+ ret_t retVal; -+ rtk_uint32 value; -+ -+ /* Robustness variable */ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_ROBUSTNESS_VAR_MASK, &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *prob_var = value; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicIGMPStaticRouterPort -+ * Description: -+ * Set IGMP static router port mask -+ * Input: -+ * pmsk - Static portmask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Invalid port mask -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicIGMPStaticRouterPort(rtk_uint32 pmsk) -+{ -+ if(pmsk > RTL8367C_PORTMASK) -+ return RT_ERR_PORT_MASK; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_STATIC_ROUTER_PORT, RTL8367C_IGMP_STATIC_ROUTER_PORT_MASK, pmsk); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicIGMPStaticRouterPort -+ * Description: -+ * Get IGMP static router port mask -+ * Input: -+ * pmsk - Static portmask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIGMPStaticRouterPort(rtk_uint32 *pmsk) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_STATIC_ROUTER_PORT, RTL8367C_IGMP_STATIC_ROUTER_PORT_MASK, pmsk); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicIGMPAllowDynamicRouterPort -+ * Description: -+ * Set IGMP dynamic router port allow mask -+ * Input: -+ * pmsk - Allow dynamic router port mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Invalid port mask -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicIGMPAllowDynamicRouterPort(rtk_uint32 pmsk) -+{ -+ return rtl8367c_setAsicReg(RTL8367C_REG_IGMP_MLD_CFG4, pmsk); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicIGMPAllowDynamicRouterPort -+ * Description: -+ * Get IGMP dynamic router port allow mask -+ * Input: -+ * None. -+ * Output: -+ * pPmsk - Allow dynamic router port mask -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Invalid port mask -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIGMPAllowDynamicRouterPort(rtk_uint32 *pPmsk) -+{ -+ return rtl8367c_getAsicReg(RTL8367C_REG_IGMP_MLD_CFG4, pPmsk); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicIGMPdynamicRouterPort1 -+ * Description: -+ * Get 1st dynamic router port and timer -+ * Input: -+ * port - Physical port number (0~7) -+ * timer - router port timer -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIGMPdynamicRouterPort1(rtk_uint32 *port, rtk_uint32 *timer) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_DYNAMIC_ROUTER_PORT, RTL8367C_D_ROUTER_PORT_1_MASK, port); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_DYNAMIC_ROUTER_PORT, RTL8367C_D_ROUTER_PORT_TMR_1_MASK, timer); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicIGMPdynamicRouterPort2 -+ * Description: -+ * Get 2nd dynamic router port and timer -+ * Input: -+ * port - Physical port number (0~7) -+ * timer - router port timer -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIGMPdynamicRouterPort2(rtk_uint32 *port, rtk_uint32 *timer) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_DYNAMIC_ROUTER_PORT, RTL8367C_D_ROUTER_PORT_2_MASK, port); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_DYNAMIC_ROUTER_PORT, RTL8367C_D_ROUTER_PORT_TMR_2_MASK, timer); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicIGMPSuppression -+ * Description: -+ * Set the suppression function -+ * Input: -+ * report_supp_enabled - Report suppression, 1:Enable, 0:disable -+ * leave_supp_enabled - Leave suppression, 1:Enable, 0:disable -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicIGMPSuppression(rtk_uint32 report_supp_enabled, rtk_uint32 leave_supp_enabled) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_REPORT_SUPPRESSION_MASK, report_supp_enabled); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_LEAVE_SUPPRESSION_MASK, leave_supp_enabled); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicIGMPSuppression -+ * Description: -+ * Get the suppression function -+ * Input: -+ * report_supp_enabled - Report suppression, 1:Enable, 0:disable -+ * leave_supp_enabled - Leave suppression, 1:Enable, 0:disable -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIGMPSuppression(rtk_uint32 *report_supp_enabled, rtk_uint32 *leave_supp_enabled) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_REPORT_SUPPRESSION_MASK, report_supp_enabled); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_LEAVE_SUPPRESSION_MASK, leave_supp_enabled); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicIGMPQueryRX -+ * Description: -+ * Set port-based Query packet RX allowance -+ * Input: -+ * port - port number -+ * allow_query - allowance of Query packet RX, 1:Allow, 0:Drop -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_PORT_ID - Error PORT ID -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicIGMPQueryRX(rtk_uint32 port, rtk_uint32 allow_query) -+{ -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ /* Allow Query */ -+ if (port < 8) -+ { -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_QUERY_MASK, allow_query); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_QUERY_MASK, allow_query); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicIGMPQueryRX -+ * Description: -+ * Get port-based Query packet RX allowance -+ * Input: -+ * port - port number -+ * Output: -+ * allow_query - allowance of Query packet RX, 1:Allow, 0:Drop -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_PORT_ID - Error PORT ID -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIGMPQueryRX(rtk_uint32 port, rtk_uint32 *allow_query) -+{ -+ ret_t retVal; -+ rtk_uint32 value; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ /* Allow Query */ -+ if (port < 8) -+ { -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_QUERY_MASK, &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_QUERY_MASK, &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ *allow_query = value; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicIGMPReportRX -+ * Description: -+ * Set port-based Report packet RX allowance -+ * Input: -+ * port - port number -+ * allow_report - allowance of Report packet RX, 1:Allow, 0:Drop -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_PORT_ID - Error PORT ID -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicIGMPReportRX(rtk_uint32 port, rtk_uint32 allow_report) -+{ -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(port < 8) -+ { -+ /* Allow Report */ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_REPORT_MASK, allow_report); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_REPORT_MASK, allow_report); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicIGMPReportRX -+ * Description: -+ * Get port-based Report packet RX allowance -+ * Input: -+ * port - port number -+ * Output: -+ * allow_report - allowance of Report packet RX, 1:Allow, 0:Drop -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_PORT_ID - Error PORT ID -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIGMPReportRX(rtk_uint32 port, rtk_uint32 *allow_report) -+{ -+ ret_t retVal; -+ rtk_uint32 value; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(port < 8) -+ { -+ /* Allow Report */ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_REPORT_MASK, &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_REPORT_MASK, &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ *allow_report = value; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicIGMPLeaveRX -+ * Description: -+ * Set port-based Leave packet RX allowance -+ * Input: -+ * port - port number -+ * allow_leave - allowance of Leave packet RX, 1:Allow, 0:Drop -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_PORT_ID - Error PORT ID -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicIGMPLeaveRX(rtk_uint32 port, rtk_uint32 allow_leave) -+{ -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(port < 8) -+ { -+ /* Allow Leave */ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_LEAVE_MASK, allow_leave); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_LEAVE_MASK, allow_leave); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicIGMPLeaveRX -+ * Description: -+ * Get port-based Leave packet RX allowance -+ * Input: -+ * port - port number -+ * Output: -+ * allow_leave - allowance of Leave packet RX, 1:Allow, 0:Drop -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_PORT_ID - Error PORT ID -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIGMPLeaveRX(rtk_uint32 port, rtk_uint32 *allow_leave) -+{ -+ ret_t retVal; -+ rtk_uint32 value; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(port < 8) -+ { -+ /* Allow Leave */ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_LEAVE_MASK, &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_LEAVE_MASK, &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ -+ *allow_leave = value; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicIGMPMRPRX -+ * Description: -+ * Set port-based Multicast Routing Protocol packet RX allowance -+ * Input: -+ * port - port number -+ * allow_mrp - allowance of Multicast Routing Protocol packet RX, 1:Allow, 0:Drop -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_PORT_ID - Error PORT ID -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicIGMPMRPRX(rtk_uint32 port, rtk_uint32 allow_mrp) -+{ -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(port < 8) -+ { -+ /* Allow Multicast Routing Protocol */ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MRP_MASK, allow_mrp); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MRP_MASK, allow_mrp); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicIGMPMRPRX -+ * Description: -+ * Get port-based Multicast Routing Protocol packet RX allowance -+ * Input: -+ * port - port number -+ * Output: -+ * allow_mrp - allowance of Multicast Routing Protocol packet RX, 1:Allow, 0:Drop -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_PORT_ID - Error PORT ID -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIGMPMRPRX(rtk_uint32 port, rtk_uint32 *allow_mrp) -+{ -+ ret_t retVal; -+ rtk_uint32 value; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ /* Allow Multicast Routing Protocol */ -+ if(port < 8) -+ { -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MRP_MASK, &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MRP_MASK, &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ *allow_mrp = value; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicIGMPMcDataRX -+ * Description: -+ * Set port-based Multicast data packet RX allowance -+ * Input: -+ * port - port number -+ * allow_mcdata - allowance of Multicast data packet RX, 1:Allow, 0:Drop -+ * Output: -+ * none -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_PORT_ID - Error PORT ID -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicIGMPMcDataRX(rtk_uint32 port, rtk_uint32 allow_mcdata) -+{ -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ /* Allow Multicast Data */ -+ if(port < 8) -+ { -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MC_DATA_MASK, allow_mcdata); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MC_DATA_MASK, allow_mcdata); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicIGMPMcDataRX -+ * Description: -+ * Get port-based Multicast data packet RX allowance -+ * Input: -+ * port - port number -+ * Output: -+ * allow_mcdata - allowance of Multicast data packet RX, 1:Allow, 0:Drop -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_PORT_ID - Error PORT ID -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIGMPMcDataRX(rtk_uint32 port, rtk_uint32 *allow_mcdata) -+{ -+ ret_t retVal; -+ rtk_uint32 value; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ /* Allow Multicast data */ -+ if(port < 8) -+ { -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MC_DATA_MASK, &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MC_DATA_MASK, &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ -+ *allow_mcdata = value; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicIGMPv1Opeartion -+ * Description: -+ * Set port-based IGMPv1 Control packet action -+ * Input: -+ * port - port number -+ * igmpv1_op - IGMPv1 control packet action -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_PORT_ID - Error PORT ID -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicIGMPv1Opeartion(rtk_uint32 port, rtk_uint32 igmpv1_op) -+{ -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(igmpv1_op >= PROTOCOL_OP_END) -+ return RT_ERR_INPUT; -+ -+ /* IGMPv1 operation */ -+ if(port < 8) -+ { -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_IGMPV1_OP_MASK, igmpv1_op); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_IGMPV1_OP_MASK, igmpv1_op); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicIGMPv1Opeartion -+ * Description: -+ * Get port-based IGMPv1 Control packet action -+ * Input: -+ * port - port number -+ * Output: -+ * igmpv1_op - IGMPv1 control packet action -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_PORT_ID - Error PORT ID -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIGMPv1Opeartion(rtk_uint32 port, rtk_uint32 *igmpv1_op) -+{ -+ ret_t retVal; -+ rtk_uint32 value; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ /* IGMPv1 operation */ -+ if(port < 8) -+ { -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_IGMPV1_OP_MASK, &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_IGMPV1_OP_MASK, &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ -+ *igmpv1_op = value; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicIGMPv2Opeartion -+ * Description: -+ * Set port-based IGMPv2 Control packet action -+ * Input: -+ * port - port number -+ * igmpv2_op - IGMPv2 control packet action -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_PORT_ID - Error PORT ID -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicIGMPv2Opeartion(rtk_uint32 port, rtk_uint32 igmpv2_op) -+{ -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(igmpv2_op >= PROTOCOL_OP_END) -+ return RT_ERR_INPUT; -+ -+ /* IGMPv2 operation */ -+ if(port < 8) -+ { -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_IGMPV2_OP_MASK, igmpv2_op); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_IGMPV2_OP_MASK, igmpv2_op); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicIGMPv2Opeartion -+ * Description: -+ * Get port-based IGMPv2 Control packet action -+ * Input: -+ * port - port number -+ * Output: -+ * igmpv2_op - IGMPv2 control packet action -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_PORT_ID - Error PORT ID -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIGMPv2Opeartion(rtk_uint32 port, rtk_uint32 *igmpv2_op) -+{ -+ ret_t retVal; -+ rtk_uint32 value; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ /* IGMPv2 operation */ -+ if(port < 8) -+ { -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_IGMPV2_OP_MASK, &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_IGMPV2_OP_MASK, &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ -+ *igmpv2_op = value; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicIGMPv3Opeartion -+ * Description: -+ * Set port-based IGMPv3 Control packet action -+ * Input: -+ * port - port number -+ * igmpv3_op - IGMPv3 control packet action -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_PORT_ID - Error PORT ID -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicIGMPv3Opeartion(rtk_uint32 port, rtk_uint32 igmpv3_op) -+{ -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(igmpv3_op >= PROTOCOL_OP_END) -+ return RT_ERR_INPUT; -+ -+ /* IGMPv3 operation */ -+ if(port < 8) -+ { -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_IGMPV3_OP_MASK, igmpv3_op); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_IGMPV3_OP_MASK, igmpv3_op); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicIGMPv3Opeartion -+ * Description: -+ * Get port-based IGMPv3 Control packet action -+ * Input: -+ * port - port number -+ * Output: -+ * igmpv3_op - IGMPv3 control packet action -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_PORT_ID - Error PORT ID -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIGMPv3Opeartion(rtk_uint32 port, rtk_uint32 *igmpv3_op) -+{ -+ ret_t retVal; -+ rtk_uint32 value; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ /* IGMPv3 operation */ -+ if(port < 8) -+ { -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_IGMPV3_OP_MASK, &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_IGMPV3_OP_MASK, &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ -+ *igmpv3_op = value; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicMLDv1Opeartion -+ * Description: -+ * Set port-based MLDv1 Control packet action -+ * Input: -+ * port - port number -+ * mldv1_op - MLDv1 control packet action -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_PORT_ID - Error PORT ID -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicMLDv1Opeartion(rtk_uint32 port, rtk_uint32 mldv1_op) -+{ -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(mldv1_op >= PROTOCOL_OP_END) -+ return RT_ERR_INPUT; -+ -+ /* MLDv1 operation */ -+ if(port < 8) -+ { -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_MLDv1_OP_MASK, mldv1_op); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_MLDv1_OP_MASK, mldv1_op); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicMLDv1Opeartion -+ * Description: -+ * Get port-based MLDv1 Control packet action -+ * Input: -+ * port - port number -+ * Output: -+ * mldv1_op - MLDv1 control packet action -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_PORT_ID - Error PORT ID -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicMLDv1Opeartion(rtk_uint32 port, rtk_uint32 *mldv1_op) -+{ -+ ret_t retVal; -+ rtk_uint32 value; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ /* MLDv1 operation */ -+ if(port < 8) -+ { -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_MLDv1_OP_MASK, &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_MLDv1_OP_MASK, &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ -+ *mldv1_op = value; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicMLDv2Opeartion -+ * Description: -+ * Set port-based MLDv2 Control packet action -+ * Input: -+ * port - port number -+ * mldv2_op - MLDv2 control packet action -+ * Output: -+ * none -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_PORT_ID - Error PORT ID -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicMLDv2Opeartion(rtk_uint32 port, rtk_uint32 mldv2_op) -+{ -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(mldv2_op >= PROTOCOL_OP_END) -+ return RT_ERR_INPUT; -+ -+ /* MLDv2 operation */ -+ if(port < 8) -+ { -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_MLDv2_OP_MASK, mldv2_op); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_MLDv2_OP_MASK, mldv2_op); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicMLDv2Opeartion -+ * Description: -+ * Get port-based MLDv2 Control packet action -+ * Input: -+ * port - port number -+ * Output: -+ * mldv2_op - MLDv2 control packet action -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_PORT_ID - Error PORT ID -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicMLDv2Opeartion(rtk_uint32 port, rtk_uint32 *mldv2_op) -+{ -+ ret_t retVal; -+ rtk_uint32 value; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ /* MLDv2 operation */ -+ if(port < 8) -+ { -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_MLDv2_OP_MASK, &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_MLDv2_OP_MASK, &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ -+ *mldv2_op = value; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicIGMPPortMAXGroup -+ * Description: -+ * Set per-port Max group number -+ * Input: -+ * port - Physical port number (0~7) -+ * max_group - max IGMP group -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicIGMPPortMAXGroup(rtk_uint32 port, rtk_uint32 max_group) -+{ -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(max_group > RTL8367C_IGMP_MAX_GOUP) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(port < 8) -+ { -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT01_MAX_GROUP + (port/2), RTL8367C_PORT0_MAX_GROUP_MASK << (RTL8367C_PORT1_MAX_GROUP_OFFSET * (port%2)), max_group); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT89_MAX_GROUP + (port/2), RTL8367C_PORT0_MAX_GROUP_MASK << (RTL8367C_PORT1_MAX_GROUP_OFFSET * (port%2)), max_group); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicIGMPPortMAXGroup -+ * Description: -+ * Get per-port Max group number -+ * Input: -+ * port - Physical port number (0~7) -+ * max_group - max IGMP group -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIGMPPortMAXGroup(rtk_uint32 port, rtk_uint32 *max_group) -+{ -+ ret_t retVal; -+ rtk_uint32 value; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(port < 8) -+ { -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT01_MAX_GROUP + (port/2), RTL8367C_PORT0_MAX_GROUP_MASK << (RTL8367C_PORT1_MAX_GROUP_OFFSET * (port%2)), &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT89_MAX_GROUP + (port/2), RTL8367C_PORT0_MAX_GROUP_MASK << (RTL8367C_PORT1_MAX_GROUP_OFFSET * (port%2)), &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ -+ *max_group = value; -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicIGMPPortCurrentGroup -+ * Description: -+ * Get per-port current group number -+ * Input: -+ * port - Physical port number (0~7) -+ * current_group - current IGMP group -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIGMPPortCurrentGroup(rtk_uint32 port, rtk_uint32 *current_group) -+{ -+ ret_t retVal; -+ rtk_uint32 value; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(port < 8) -+ { -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT01_CURRENT_GROUP + (port/2), RTL8367C_PORT0_CURRENT_GROUP_MASK << (RTL8367C_PORT1_CURRENT_GROUP_OFFSET * (port%2)), &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT89_CURRENT_GROUP + ((port - 8)/2), RTL8367C_PORT0_CURRENT_GROUP_MASK << (RTL8367C_PORT1_CURRENT_GROUP_OFFSET * (port%2)), &value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ -+ *current_group = value; -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicIGMPGroup -+ * Description: -+ * Get IGMP group -+ * Input: -+ * idx - Group index (0~255) -+ * valid - valid bit -+ * grp - IGMP group -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - Group index is out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIGMPGroup(rtk_uint32 idx, rtk_uint32 *valid, rtl8367c_igmpgroup *grp) -+{ -+ ret_t retVal; -+ rtk_uint32 regAddr, regData; -+ rtk_uint32 i; -+ rtk_uint32 groupInfo = 0; -+ -+ if(idx > RTL8367C_IGMP_MAX_GOUP) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ /* Write ACS_ADR register for data bits */ -+ regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; -+ regData = idx; -+ retVal = rtl8367c_setAsicReg(regAddr, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ /* Write ACS_CMD register */ -+ regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; -+ regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_READ, TB_TARGET_IGMP_GROUP); -+ retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ /* Read Data Bits */ -+ regAddr = RTL8367C_TABLE_ACCESS_RDDATA_BASE; -+ for(i = 0 ;i <= 1; i++) -+ { -+ retVal = rtl8367c_getAsicReg(regAddr, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ groupInfo |= ((regData & 0xFFFF) << (i * 16)); -+ regAddr ++; -+ } -+ -+ grp->p0_timer = groupInfo & 0x00000007; -+ grp->p1_timer = (groupInfo >> 3) & 0x00000007; -+ grp->p2_timer = (groupInfo >> 6) & 0x00000007; -+ grp->p3_timer = (groupInfo >> 9) & 0x00000007; -+ grp->p4_timer = (groupInfo >> 12) & 0x00000007; -+ grp->p5_timer = (groupInfo >> 15) & 0x00000007; -+ grp->p6_timer = (groupInfo >> 18) & 0x00000007; -+ grp->p7_timer = (groupInfo >> 21) & 0x00000007; -+ grp->report_supp_flag = (groupInfo >> 24) & 0x00000001; -+ grp->p8_timer = (groupInfo >> 25) & 0x00000007; -+ grp->p9_timer = (groupInfo >> 28) & 0x00000007; -+ grp->p10_timer = (groupInfo >> 31) & 0x00000001; -+ -+ regAddr = RTL8367C_TABLE_ACCESS_RDDATA_BASE + 2; -+ retVal = rtl8367c_getAsicReg(regAddr, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ grp->p10_timer |= (regData & 0x00000003) << 1; -+ -+ /* Valid bit */ -+ retVal = rtl8367c_getAsicReg(RTL8367C_IGMP_GROUP_USAGE_REG(idx), ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *valid = ((regData & (0x0001 << (idx %16))) != 0) ? 1 : 0; -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicIpMulticastPortIsoLeaky -+ * Description: -+ * Set IP multicast Port Isolation leaky -+ * Input: -+ * port - Physical port number (0~7) -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicIpMulticastPortIsoLeaky(rtk_uint32 port, rtk_uint32 enabled) -+{ -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_IPMCAST_PORTISO_LEAKY_REG, (0x0001 << port), enabled); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicIpMulticastPortIsoLeaky -+ * Description: -+ * Get IP multicast Port Isolation leaky -+ * Input: -+ * port - Physical port number (0~7) -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIpMulticastPortIsoLeaky(rtk_uint32 port, rtk_uint32 *enabled) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_IPMCAST_PORTISO_LEAKY_REG, (0x0001 << port), ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *enabled = regData; -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicIGMPReportLeaveFlood -+ * Description: -+ * Set IGMP/MLD Report/Leave flood -+ * Input: -+ * flood - 0: Reserved, 1: flooding to router ports, 2: flooding to all ports, 3: flooding to router port or to all ports if there is no router port -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicIGMPReportLeaveFlood(rtk_uint32 flood) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG3, RTL8367C_REPORT_LEAVE_FORWARD_MASK, flood); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicIGMPReportLeaveFlood -+ * Description: -+ * Get IGMP/MLD Report/Leave flood -+ * Input: -+ * None -+ * Output: -+ * pflood - 0: Reserved, 1: flooding to router ports, 2: flooding to all ports, 3: flooding to router port or to all ports if there is no router port -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIGMPReportLeaveFlood(rtk_uint32 *pFlood) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG3, RTL8367C_REPORT_LEAVE_FORWARD_MASK, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *pFlood = regData; -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicIGMPDropLeaveZero -+ * Description: -+ * Set the function of dropping Leave packet with group IP = 0.0.0.0 -+ * Input: -+ * drop - 1: Drop, 0:Bypass -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicIGMPDropLeaveZero(rtk_uint32 drop) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG1, RTL8367C_DROP_LEAVE_ZERO_OFFSET, drop); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicIGMPDropLeaveZero -+ * Description: -+ * Get the function of dropping Leave packet with group IP = 0.0.0.0 -+ * Input: -+ * None -+ * Output: -+ * pDrop - 1: Drop, 0:Bypass -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIGMPDropLeaveZero(rtk_uint32 *pDrop) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ -+ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG1, RTL8367C_DROP_LEAVE_ZERO_OFFSET, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *pDrop = regData; -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicIGMPBypassStormCTRL -+ * Description: -+ * Set the function of bypass storm control for IGMP/MLD packet -+ * Input: -+ * bypass - 1: Bypass, 0:not bypass -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicIGMPBypassStormCTRL(rtk_uint32 bypass) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_DISCARD_STORM_FILTER_OFFSET, bypass); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicIGMPBypassStormCTRL -+ * Description: -+ * Set the function of bypass storm control for IGMP/MLD packet -+ * Input: -+ * None -+ * Output: -+ * pBypass - 1: Bypass, 0:not bypass -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIGMPBypassStormCTRL(rtk_uint32 *pBypass) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ -+ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_DISCARD_STORM_FILTER_OFFSET, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *pBypass = regData; -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicIGMPIsoLeaky -+ * Description: -+ * Set Port Isolation leaky for IGMP/MLD packet -+ * Input: -+ * leaky - 1: Leaky, 0:not leaky -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicIGMPIsoLeaky(rtk_uint32 leaky) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_PORTISO_LEAKY_OFFSET, leaky); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicIGMPIsoLeaky -+ * Description: -+ * Get Port Isolation leaky for IGMP/MLD packet -+ * Input: -+ * None -+ * Output: -+ * pLeaky - 1: Leaky, 0:not leaky -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIGMPIsoLeaky(rtk_uint32 *pLeaky) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ -+ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_PORTISO_LEAKY_OFFSET, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *pLeaky = regData; -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicIGMPVLANLeaky -+ * Description: -+ * Set VLAN leaky for IGMP/MLD packet -+ * Input: -+ * leaky - 1: Leaky, 0:not leaky -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicIGMPVLANLeaky(rtk_uint32 leaky) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_VLAN_LEAKY_OFFSET, leaky); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicIGMPVLANLeaky -+ * Description: -+ * Get VLAN leaky for IGMP/MLD packet -+ * Input: -+ * None -+ * Output: -+ * pLeaky - 1: Leaky, 0:not leaky -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIGMPVLANLeaky(rtk_uint32 *pLeaky) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ -+ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_VLAN_LEAKY_OFFSET, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *pLeaky = regData; -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicIGMPBypassGroup -+ * Description: -+ * Set IGMP/MLD Bypass group -+ * Input: -+ * bypassType - Bypass type -+ * enabled - enabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicIGMPBypassGroup(rtk_uint32 bypassType, rtk_uint32 enabled) -+{ -+ ret_t retVal; -+ rtk_uint32 offset; -+ -+ switch(bypassType) -+ { -+ case BYPASS_224_0_0_X: -+ offset = RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_0_OFFSET; -+ break; -+ case BYPASS_224_0_1_X: -+ offset = RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_1_OFFSET; -+ break; -+ case BYPASS_239_255_255_X: -+ offset = RTL8367C_IGMP_MLD_IP4_BYPASS_239_255_255_OFFSET; -+ break; -+ case BYPASS_IPV6_00XX: -+ offset = RTL8367C_IGMP_MLD_IP6_BYPASS_OFFSET; -+ break; -+ default: -+ return RT_ERR_INPUT; -+ } -+ -+ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG3, offset, enabled); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicIGMPBypassGroup -+ * Description: -+ * Get IGMP/MLD Bypass group -+ * Input: -+ * bypassType - Bypass type -+ * Output: -+ * pEnabled - enabled -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicIGMPBypassGroup(rtk_uint32 bypassType, rtk_uint32 *pEnabled) -+{ -+ ret_t retVal; -+ rtk_uint32 offset; -+ -+ switch(bypassType) -+ { -+ case BYPASS_224_0_0_X: -+ offset = RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_0_OFFSET; -+ break; -+ case BYPASS_224_0_1_X: -+ offset = RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_1_OFFSET; -+ break; -+ case BYPASS_239_255_255_X: -+ offset = RTL8367C_IGMP_MLD_IP4_BYPASS_239_255_255_OFFSET; -+ break; -+ case BYPASS_IPV6_00XX: -+ offset = RTL8367C_IGMP_MLD_IP6_BYPASS_OFFSET; -+ break; -+ default: -+ return RT_ERR_INPUT; -+ } -+ -+ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG3, offset, pEnabled); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_inbwctrl.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_inbwctrl.c -new file mode 100644 -index 000000000000..13a7b14246a1 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_inbwctrl.c -@@ -0,0 +1,164 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Ingress bandwidth control related functions -+ * -+ */ -+#include -+/* Function Name: -+ * rtl8367c_setAsicPortIngressBandwidth -+ * Description: -+ * Set per-port total ingress bandwidth -+ * Input: -+ * port - Physical port number (0~7) -+ * bandwidth - The total ingress bandwidth (unit: 8Kbps), 0x1FFFF:disable -+ * preifg - Include preamble and IFG, 0:Exclude, 1:Include -+ * enableFC - Action when input rate exceeds. 0: Drop 1: Flow Control -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortIngressBandwidth(rtk_uint32 port, rtk_uint32 bandwidth, rtk_uint32 preifg, rtk_uint32 enableFC) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ rtk_uint32 regAddr; -+ -+ /* Invalid input parameter */ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ if(bandwidth > RTL8367C_QOS_GRANULARTY_MAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ regAddr = RTL8367C_INGRESSBW_PORT_RATE_LSB_REG(port); -+ regData = bandwidth & RTL8367C_QOS_GRANULARTY_LSB_MASK; -+ retVal = rtl8367c_setAsicReg(regAddr, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ regAddr += 1; -+ regData = (bandwidth & RTL8367C_QOS_GRANULARTY_MSB_MASK) >> RTL8367C_QOS_GRANULARTY_MSB_OFFSET; -+ retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_INGRESSBW_PORT0_RATE_CTRL1_INGRESSBW_RATE16_MASK, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ regAddr = RTL8367C_PORT_MISC_CFG_REG(port); -+ retVal = rtl8367c_setAsicRegBit(regAddr, RTL8367C_PORT0_MISC_CFG_INGRESSBW_IFG_OFFSET, preifg); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ regAddr = RTL8367C_PORT_MISC_CFG_REG(port); -+ retVal = rtl8367c_setAsicRegBit(regAddr, RTL8367C_PORT0_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET, enableFC); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicPortIngressBandwidth -+ * Description: -+ * Get per-port total ingress bandwidth -+ * Input: -+ * port - Physical port number (0~7) -+ * pBandwidth - The total ingress bandwidth (unit: 8Kbps), 0x1FFFF:disable -+ * pPreifg - Include preamble and IFG, 0:Exclude, 1:Include -+ * pEnableFC - Action when input rate exceeds. 0: Drop 1: Flow Control -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortIngressBandwidth(rtk_uint32 port, rtk_uint32* pBandwidth, rtk_uint32* pPreifg, rtk_uint32* pEnableFC) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ rtk_uint32 regAddr; -+ -+ /* Invalid input parameter */ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ regAddr = RTL8367C_INGRESSBW_PORT_RATE_LSB_REG(port); -+ retVal = rtl8367c_getAsicReg(regAddr, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *pBandwidth = regData; -+ -+ regAddr += 1; -+ retVal = rtl8367c_getAsicRegBits(regAddr, RTL8367C_INGRESSBW_PORT0_RATE_CTRL1_INGRESSBW_RATE16_MASK, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *pBandwidth |= (regData << RTL8367C_QOS_GRANULARTY_MSB_OFFSET); -+ -+ regAddr = RTL8367C_PORT_MISC_CFG_REG(port); -+ retVal = rtl8367c_getAsicRegBit(regAddr, RTL8367C_PORT0_MISC_CFG_INGRESSBW_IFG_OFFSET, pPreifg); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ regAddr = RTL8367C_PORT_MISC_CFG_REG(port); -+ retVal = rtl8367c_getAsicRegBit(regAddr, RTL8367C_PORT0_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET, pEnableFC); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicPortIngressBandwidthBypass -+ * Description: -+ * Set ingress bandwidth control bypass 8899, RMA 01-80-C2-00-00-xx and IGMP -+ * Input: -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortIngressBandwidthBypass(rtk_uint32 enabled) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_SW_DUMMY0, RTL8367C_INGRESSBW_BYPASS_EN_OFFSET, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicPortIngressBandwidthBypass -+ * Description: -+ * Set ingress bandwidth control bypass 8899, RMA 01-80-C2-00-00-xx and IGMP -+ * Input: -+ * pEnabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortIngressBandwidthBypass(rtk_uint32* pEnabled) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_SW_DUMMY0, RTL8367C_INGRESSBW_BYPASS_EN_OFFSET, pEnabled); -+} -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_interrupt.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_interrupt.c -new file mode 100644 -index 000000000000..1d5ccfc904ae ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_interrupt.c -@@ -0,0 +1,205 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Interrupt related functions -+ * -+ */ -+#include -+/* Function Name: -+ * rtl8367c_setAsicInterruptPolarity -+ * Description: -+ * Set interrupt trigger polarity -+ * Input: -+ * polarity - 0:pull high 1: pull low -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicInterruptPolarity(rtk_uint32 polarity) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_INTR_CTRL, RTL8367C_INTR_CTRL_OFFSET, polarity); -+} -+/* Function Name: -+ * rtl8367c_getAsicInterruptPolarity -+ * Description: -+ * Get interrupt trigger polarity -+ * Input: -+ * pPolarity - 0:pull high 1: pull low -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicInterruptPolarity(rtk_uint32* pPolarity) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_INTR_CTRL, RTL8367C_INTR_CTRL_OFFSET, pPolarity); -+} -+/* Function Name: -+ * rtl8367c_setAsicInterruptMask -+ * Description: -+ * Set interrupt enable mask -+ * Input: -+ * imr - Interrupt mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicInterruptMask(rtk_uint32 imr) -+{ -+ return rtl8367c_setAsicReg(RTL8367C_REG_INTR_IMR, imr); -+} -+/* Function Name: -+ * rtl8367c_getAsicInterruptMask -+ * Description: -+ * Get interrupt enable mask -+ * Input: -+ * pImr - Interrupt mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicInterruptMask(rtk_uint32* pImr) -+{ -+ return rtl8367c_getAsicReg(RTL8367C_REG_INTR_IMR, pImr); -+} -+/* Function Name: -+ * rtl8367c_setAsicInterruptMask -+ * Description: -+ * Clear interrupt enable mask -+ * Input: -+ * ims - Interrupt status mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * This API can be used to clear ASIC interrupt status and register will be cleared by writing 1. -+ * [0]:Link change, -+ * [1]:Share meter exceed, -+ * [2]:Learn number over, -+ * [3]:Speed Change, -+ * [4]:Tx special congestion -+ * [5]:1 second green feature -+ * [6]:loop detection -+ * [7]:interrupt from 8051 -+ * [8]:Cable diagnostic finish -+ * [9]:ACL action interrupt trigger -+ * [11]: Silent Start -+ */ -+ret_t rtl8367c_setAsicInterruptStatus(rtk_uint32 ims) -+{ -+ return rtl8367c_setAsicReg(RTL8367C_REG_INTR_IMS, ims); -+} -+/* Function Name: -+ * rtl8367c_getAsicInterruptStatus -+ * Description: -+ * Get interrupt enable mask -+ * Input: -+ * pIms - Interrupt status mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicInterruptStatus(rtk_uint32* pIms) -+{ -+ return rtl8367c_getAsicReg(RTL8367C_REG_INTR_IMS, pIms); -+} -+/* Function Name: -+ * rtl8367c_setAsicInterruptRelatedStatus -+ * Description: -+ * Clear interrupt status -+ * Input: -+ * type - per port Learn over, per-port speed change, per-port special congest, share meter exceed status -+ * status - exceed status, write 1 to clear -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicInterruptRelatedStatus(rtk_uint32 type, rtk_uint32 status) -+{ -+ CONST rtk_uint32 indicatorAddress[INTRST_END] = {RTL8367C_REG_LEARN_OVER_INDICATOR, -+ RTL8367C_REG_SPEED_CHANGE_INDICATOR, -+ RTL8367C_REG_SPECIAL_CONGEST_INDICATOR, -+ RTL8367C_REG_PORT_LINKDOWN_INDICATOR, -+ RTL8367C_REG_PORT_LINKUP_INDICATOR, -+ RTL8367C_REG_METER_OVERRATE_INDICATOR0, -+ RTL8367C_REG_METER_OVERRATE_INDICATOR1, -+ RTL8367C_REG_RLDP_LOOPED_INDICATOR, -+ RTL8367C_REG_RLDP_RELEASED_INDICATOR, -+ RTL8367C_REG_SYSTEM_LEARN_OVER_INDICATOR}; -+ -+ if(type >= INTRST_END ) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ return rtl8367c_setAsicReg(indicatorAddress[type], status); -+} -+/* Function Name: -+ * rtl8367c_getAsicInterruptRelatedStatus -+ * Description: -+ * Get interrupt status -+ * Input: -+ * type - per port Learn over, per-port speed change, per-port special congest, share meter exceed status -+ * pStatus - exceed status, write 1 to clear -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicInterruptRelatedStatus(rtk_uint32 type, rtk_uint32* pStatus) -+{ -+ CONST rtk_uint32 indicatorAddress[INTRST_END] = {RTL8367C_REG_LEARN_OVER_INDICATOR, -+ RTL8367C_REG_SPEED_CHANGE_INDICATOR, -+ RTL8367C_REG_SPECIAL_CONGEST_INDICATOR, -+ RTL8367C_REG_PORT_LINKDOWN_INDICATOR, -+ RTL8367C_REG_PORT_LINKUP_INDICATOR, -+ RTL8367C_REG_METER_OVERRATE_INDICATOR0, -+ RTL8367C_REG_METER_OVERRATE_INDICATOR1, -+ RTL8367C_REG_RLDP_LOOPED_INDICATOR, -+ RTL8367C_REG_RLDP_RELEASED_INDICATOR, -+ RTL8367C_REG_SYSTEM_LEARN_OVER_INDICATOR}; -+ -+ if(type >= INTRST_END ) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ return rtl8367c_getAsicReg(indicatorAddress[type], pStatus); -+} -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_led.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_led.c -new file mode 100644 -index 000000000000..6f2617f5aa02 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_led.c -@@ -0,0 +1,727 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : LED related functions -+ * -+ */ -+#include -+/* Function Name: -+ * rtl8367c_setAsicLedIndicateInfoConfig -+ * Description: -+ * Set Leds indicated information mode -+ * Input: -+ * ledno - LED group number. There are 1 to 1 led mapping to each port in each led group -+ * config - Support 16 types configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * The API can set LED indicated information configuration for each LED group with 1 to 1 led mapping to each port. -+ * Definition LED Statuses Description -+ * 0000 LED_Off LED pin Tri-State. -+ * 0001 Dup/Col Collision, Full duplex Indicator. Blinking every 43ms when collision happens. Low for full duplex, and high for half duplex mode. -+ * 0010 Link/Act Link, Activity Indicator. Low for link established. Link/Act Blinks every 43ms when the corresponding port is transmitting or receiving. -+ * 0011 Spd1000 1000Mb/s Speed Indicator. Low for 1000Mb/s. -+ * 0100 Spd100 100Mb/s Speed Indicator. Low for 100Mb/s. -+ * 0101 Spd10 10Mb/s Speed Indicator. Low for 10Mb/s. -+ * 0110 Spd1000/Act 1000Mb/s Speed/Activity Indicator. Low for 1000Mb/s. Blinks every 43ms when the corresponding port is transmitting or receiving. -+ * 0111 Spd100/Act 100Mb/s Speed/Activity Indicator. Low for 100Mb/s. Blinks every 43ms when the corresponding port is transmitting or receiving. -+ * 1000 Spd10/Act 10Mb/s Speed/Activity Indicator. Low for 10Mb/s. Blinks every 43ms when the corresponding port is transmitting or receiving. -+ * 1001 Spd100 (10)/Act 10/100Mb/s Speed/Activity Indicator. Low for 10/100Mb/s. Blinks every 43ms when the corresponding port is transmitting or receiving. -+ * 1010 Fiber Fiber link Indicator. Low for Fiber. -+ * 1011 Fault Auto-negotiation Fault Indicator. Low for Fault. -+ * 1100 Link/Rx Link, Activity Indicator. Low for link established. Link/Rx Blinks every 43ms when the corresponding port is transmitting. -+ * 1101 Link/Tx Link, Activity Indicator. Low for link established. Link/Tx Blinks every 43ms when the corresponding port is receiving. -+ * 1110 Master Link on Master Indicator. Low for link Master established. -+ * 1111 LED_Force Force LED output, LED output value reference -+ */ -+ret_t rtl8367c_setAsicLedIndicateInfoConfig(rtk_uint32 ledno, rtk_uint32 config) -+{ -+ ret_t retVal; -+ CONST rtk_uint16 bits[RTL8367C_LEDGROUPNO] = {RTL8367C_LED0_CFG_MASK, RTL8367C_LED1_CFG_MASK, RTL8367C_LED2_CFG_MASK}; -+ -+ if(ledno >= RTL8367C_LEDGROUPNO) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(config >= LEDCONF_END) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LED_CONFIGURATION, RTL8367C_LED_CONFIG_SEL_OFFSET, 0); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_LED_CONFIGURATION, bits[ledno], config); -+} -+/* Function Name: -+ * rtl8367c_getAsicLedIndicateInfoConfig -+ * Description: -+ * Get Leds indicated information mode -+ * Input: -+ * ledno - LED group number. There are 1 to 1 led mapping to each port in each led group -+ * pConfig - Support 16 types configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicLedIndicateInfoConfig(rtk_uint32 ledno, rtk_uint32* pConfig) -+{ -+ CONST rtk_uint16 bits[RTL8367C_LEDGROUPNO]= {RTL8367C_LED0_CFG_MASK, RTL8367C_LED1_CFG_MASK, RTL8367C_LED2_CFG_MASK}; -+ -+ if(ledno >= RTL8367C_LEDGROUPNO) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ /* Get register value */ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_LED_CONFIGURATION, bits[ledno], pConfig); -+} -+/* Function Name: -+ * rtl8367c_setAsicLedGroupMode -+ * Description: -+ * Set Led Group mode -+ * Input: -+ * mode - LED mode -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicLedGroupMode(rtk_uint32 mode) -+{ -+ ret_t retVal; -+ -+ /* Invalid input parameter */ -+ if(mode >= RTL8367C_LED_MODE_END) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LED_CONFIGURATION, RTL8367C_LED_CONFIG_SEL_OFFSET, 1); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_LED_CONFIGURATION, RTL8367C_DATA_LED_MASK, mode); -+} -+/* Function Name: -+ * rtl8367c_getAsicLedGroupMode -+ * Description: -+ * Get Led Group mode -+ * Input: -+ * pMode - LED mode -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicLedGroupMode(rtk_uint32* pMode) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ -+ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_LED_CONFIGURATION, RTL8367C_LED_CONFIG_SEL_OFFSET, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ if(regData!=1) -+ return RT_ERR_FAILED; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_LED_CONFIGURATION, RTL8367C_DATA_LED_MASK, pMode); -+} -+/* Function Name: -+ * rtl8367c_setAsicForceLeds -+ * Description: -+ * Set group LED mode -+ * Input: -+ * port - Physical port number (0~7) -+ * group - LED group number -+ * mode - LED mode -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicForceLed(rtk_uint32 port, rtk_uint32 group, rtk_uint32 mode) -+{ -+ rtk_uint16 regAddr; -+ ret_t retVal; -+ -+ /* Invalid input parameter */ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(group >= RTL8367C_LEDGROUPNO) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(mode >= LEDFORCEMODE_END) -+ return RT_ERR_OUT_OF_RANGE; -+ /* Set Related Registers */ -+ if(port < 8){ -+ regAddr = RTL8367C_LED_FORCE_MODE_BASE + (group << 1); -+ if((retVal = rtl8367c_setAsicRegBits(regAddr, 0x3 << (port * 2), mode)) != RT_ERR_OK) -+ return retVal; -+ }else if(port >= 8){ -+ regAddr = RTL8367C_REG_CPU_FORCE_LED0_CFG1 + (group << 1); -+ if((retVal = rtl8367c_setAsicRegBits(regAddr, 0x3 << ((port-8) * 2), mode)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicForceLed -+ * Description: -+ * Get group LED mode -+ * Input: -+ * port - Physical port number (0~7) -+ * group - LED group number -+ * pMode - LED mode -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicForceLed(rtk_uint32 port, rtk_uint32 group, rtk_uint32* pMode) -+{ -+ rtk_uint16 regAddr; -+ ret_t retVal; -+ -+ /* Invalid input parameter */ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(group >= RTL8367C_LEDGROUPNO) -+ return RT_ERR_INPUT; -+ -+ /* Get Related Registers */ -+ if(port < 8){ -+ regAddr = RTL8367C_LED_FORCE_MODE_BASE + (group << 1); -+ if((retVal = rtl8367c_getAsicRegBits(regAddr, 0x3 << (port * 2), pMode)) != RT_ERR_OK) -+ return retVal; -+ }else if(port >= 8){ -+ regAddr = RTL8367C_REG_CPU_FORCE_LED0_CFG1 + (group << 1); -+ if((retVal = rtl8367c_getAsicRegBits(regAddr, 0x3 << ((port-8) * 2), pMode)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicForceGroupLed -+ * Description: -+ * Turn on/off Led of all ports -+ * Input: -+ * group - LED group number -+ * mode - 0b00:normal mode, 0b01:force blink, 0b10:force off, 0b11:force on -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicForceGroupLed(rtk_uint32 groupmask, rtk_uint32 mode) -+{ -+ ret_t retVal; -+ rtk_uint32 i,bitmask; -+ CONST rtk_uint16 bits[3]= {0x0004,0x0010,0x0040}; -+ -+ /* Invalid input parameter */ -+ if(groupmask > RTL8367C_LEDGROUPMASK) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(mode >= LEDFORCEMODE_END) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ bitmask = 0; -+ for(i = 0; i < RTL8367C_LEDGROUPNO; i++) -+ { -+ if(groupmask & (1 << i)) -+ { -+ bitmask = bitmask | bits[i]; -+ } -+ -+ } -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_LED_FORCE_CTRL, RTL8367C_LED_FORCE_MODE_MASK, bitmask); -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_LED_FORCE_CTRL, RTL8367C_FORCE_MODE_MASK, mode); -+ -+ if(LEDFORCEMODE_NORMAL == mode) -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_LED_FORCE_CTRL, RTL8367C_LED_FORCE_MODE_MASK, 0); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicForceGroupLed -+ * Description: -+ * Turn on/off Led of all ports -+ * Input: -+ * group - LED group number -+ * pMode - 0b00:normal mode, 0b01:force blink, 0b10:force off, 0b11:force on -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicForceGroupLed(rtk_uint32* groupmask, rtk_uint32* pMode) -+{ -+ ret_t retVal; -+ rtk_uint32 i,regData; -+ CONST rtk_uint16 bits[3] = {0x0004,0x0010,0x0040}; -+ -+ /* Get Related Registers */ -+ if((retVal = rtl8367c_getAsicRegBits(RTL8367C_LED_FORCE_CTRL, RTL8367C_LED_FORCE_MODE_MASK, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ for(i = 0; i< RTL8367C_LEDGROUPNO; i++) -+ { -+ if((regData & bits[i]) == bits[i]) -+ { -+ *groupmask = *groupmask | (1 << i); -+ } -+ } -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_LED_FORCE_CTRL, RTL8367C_FORCE_MODE_MASK, pMode); -+} -+/* Function Name: -+ * rtl8367c_setAsicLedBlinkRate -+ * Description: -+ * Set led blinking rate at mode 0 to mode 3 -+ * Input: -+ * blinkRate - Support 6 blink rates -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * LED blink rate can be at 43ms, 84ms, 120ms, 170ms, 340ms and 670ms -+ */ -+ret_t rtl8367c_setAsicLedBlinkRate(rtk_uint32 blinkRate) -+{ -+ if(blinkRate >= LEDBLINKRATE_END) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_LED_MODE, RTL8367C_SEL_LEDRATE_MASK, blinkRate); -+} -+/* Function Name: -+ * rtl8367c_getAsicLedBlinkRate -+ * Description: -+ * Get led blinking rate at mode 0 to mode 3 -+ * Input: -+ * pBlinkRate - Support 6 blink rates -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicLedBlinkRate(rtk_uint32* pBlinkRate) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_LED_MODE, RTL8367C_SEL_LEDRATE_MASK, pBlinkRate); -+} -+/* Function Name: -+ * rtl8367c_setAsicLedForceBlinkRate -+ * Description: -+ * Set LEd blinking rate for force mode led -+ * Input: -+ * blinkRate - Support 6 blink rates -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicLedForceBlinkRate(rtk_uint32 blinkRate) -+{ -+ if(blinkRate >= LEDFORCERATE_END) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_LED_MODE, RTL8367C_FORCE_RATE_MASK, blinkRate); -+} -+/* Function Name: -+ * rtl8367c_getAsicLedForceBlinkRate -+ * Description: -+ * Get LED blinking rate for force mode led -+ * Input: -+ * pBlinkRate - Support 6 blink rates -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicLedForceBlinkRate(rtk_uint32* pBlinkRate) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_LED_MODE, RTL8367C_FORCE_RATE_MASK, pBlinkRate); -+} -+ -+/* -+@func ret_t | rtl8367c_setAsicLedGroupEnable | Turn on/off Led of all system ports -+@parm rtk_uint32 | group | LED group id. -+@parm rtk_uint32 | portmask | LED port mask. -+@rvalue RT_ERR_OK | Success. -+@rvalue RT_ERR_SMI | SMI access error. -+@rvalue RT_ERR_PORT_ID | Invalid port number. -+@rvalue RT_ERR_INPUT | Invalid input value. -+@comm -+ The API can turn on/off leds of dedicated port while indicated information configuration of LED group is set to force mode. -+ */ -+ret_t rtl8367c_setAsicLedGroupEnable(rtk_uint32 group, rtk_uint32 portmask) -+{ -+ ret_t retVal; -+ rtk_uint32 regAddr; -+ rtk_uint32 regDataMask; -+ -+ if ( group >= RTL8367C_LEDGROUPNO ) -+ return RT_ERR_INPUT; -+ -+ regAddr = RTL8367C_REG_PARA_LED_IO_EN1 + group/2; -+ regDataMask = 0xFF << ((group%2)*8); -+ retVal = rtl8367c_setAsicRegBits(regAddr, regDataMask, portmask&0xff); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ regAddr = RTL8367C_REG_PARA_LED_IO_EN3; -+ regDataMask = 0x3 << (group*2); -+ retVal = rtl8367c_setAsicRegBits(regAddr, regDataMask, (portmask>>8)&0x7); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ -+ return RT_ERR_OK; -+} -+ -+/* -+@func ret_t | rtl8367c_getAsicLedGroupEnable | Get on/off status of Led of all system ports -+@parm rtk_uint32 | group | LED group id. -+@parm rtk_uint32 | *portmask | LED port mask. -+@rvalue RT_ERR_OK | Success. -+@rvalue RT_ERR_SMI | SMI access error. -+@rvalue RT_ERR_PORT_ID | Invalid port number. -+@rvalue RT_ERR_INPUT | Invalid input value. -+@comm -+ The API can turn on/off leds of dedicated port while indicated information configuration of LED group is set to force mode. -+ */ -+ret_t rtl8367c_getAsicLedGroupEnable(rtk_uint32 group, rtk_uint32 *portmask) -+{ -+ ret_t retVal; -+ rtk_uint32 regAddr; -+ rtk_uint32 regDataMask,regData; -+ -+ if ( group >= RTL8367C_LEDGROUPNO ) -+ return RT_ERR_INPUT; -+ -+ regAddr = RTL8367C_REG_PARA_LED_IO_EN1 + group/2; -+ regDataMask = 0xFF << ((group%2)*8); -+ retVal = rtl8367c_getAsicRegBits(regAddr, regDataMask, portmask); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ -+ regAddr = RTL8367C_REG_PARA_LED_IO_EN3; -+ regDataMask = 0x3 << (group*2); -+ retVal = rtl8367c_getAsicRegBits(regAddr, regDataMask, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *portmask = (regData << 8) | *portmask; -+ -+ return RT_ERR_OK; -+} -+ -+/* -+@func ret_t | rtl8367c_setAsicLedOperationMode | Set LED operation mode -+@parm rtk_uint32 | mode | LED mode. 1:scan mode 1, 2:parallel mode, 3:mdx mode (serial mode) -+@rvalue RT_ERR_OK | Success. -+@rvalue RT_ERR_SMI | SMI access error. -+@rvalue RT_ERR_INPUT | Invalid input value. -+@comm -+ The API can turn on/off led serial mode and set signal to active high/low. -+ */ -+ret_t rtl8367c_setAsicLedOperationMode(rtk_uint32 mode) -+{ -+ ret_t retVal; -+ -+ /* Invalid input parameter */ -+ if( mode >= LEDOP_END) -+ return RT_ERR_INPUT; -+ -+ switch(mode) -+ { -+ case LEDOP_PARALLEL: -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LED_SYS_CONFIG, RTL8367C_LED_SELECT_OFFSET, 0))!= RT_ERR_OK) -+ return retVal; -+ /*Disable serial CLK mode*/ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SCAN0_LED_IO_EN1,RTL8367C_LED_SERI_CLK_EN_OFFSET, 0))!= RT_ERR_OK) -+ return retVal; -+ /*Disable serial DATA mode*/ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SCAN0_LED_IO_EN1,RTL8367C_LED_SERI_DATA_EN_OFFSET, 0))!= RT_ERR_OK) -+ return retVal; -+ break; -+ case LEDOP_SERIAL: -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LED_SYS_CONFIG, RTL8367C_LED_SELECT_OFFSET, 1))!= RT_ERR_OK) -+ return retVal; -+ /*Enable serial CLK mode*/ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SCAN0_LED_IO_EN1,RTL8367C_LED_SERI_CLK_EN_OFFSET, 1))!= RT_ERR_OK) -+ return retVal; -+ /*Enable serial DATA mode*/ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SCAN0_LED_IO_EN1,RTL8367C_LED_SERI_DATA_EN_OFFSET, 1))!= RT_ERR_OK) -+ return retVal; -+ break; -+ default: -+ return RT_ERR_INPUT; -+ break; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+ -+/* -+@func ret_t | rtl8367c_getAsicLedOperationMode | Get LED OP mode setup -+@parm rtk_uint32*| mode | LED mode. 1:scan mode 1, 2:parallel mode, 3:mdx mode (serial mode) -+@rvalue RT_ERR_OK | Success. -+@rvalue RT_ERR_SMI | SMI access error. -+@rvalue RT_ERR_INPUT | Invalid input value. -+@comm -+ The API can get LED serial mode setup and get signal active high/low. -+ */ -+ret_t rtl8367c_getAsicLedOperationMode(rtk_uint32 *mode) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ -+ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_LED_SYS_CONFIG, RTL8367C_LED_SELECT_OFFSET, ®Data))!= RT_ERR_OK) -+ return retVal; -+ -+ if (regData == 1) -+ *mode = LEDOP_SERIAL; -+ else if (regData == 0) -+ *mode = LEDOP_PARALLEL; -+ else -+ return RT_ERR_FAILED; -+ -+ return RT_ERR_OK; -+} -+ -+/* -+@func ret_t | rtl8367c_setAsicLedSerialModeConfig | Set LED serial mode -+@parm rtk_uint32 | active | Active High or Low. -+@rvalue RT_ERR_OK | Success. -+@rvalue RT_ERR_SMI | SMI access error. -+@rvalue RT_ERR_INPUT | Invalid input value. -+@comm -+ The API can turn on/off led serial mode and set signal to active high/low. -+ */ -+ret_t rtl8367c_setAsicLedSerialModeConfig(rtk_uint32 active, rtk_uint32 serimode) -+{ -+ ret_t retVal; -+ -+ /* Invalid input parameter */ -+ if( active >= LEDSERACT_MAX) -+ return RT_ERR_INPUT; -+ if( serimode >= LEDSER_MAX) -+ return RT_ERR_INPUT; -+ -+ /* Set Active High or Low */ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LED_SYS_CONFIG, RTL8367C_SERI_LED_ACT_LOW_OFFSET, active)) != RT_ERR_OK) -+ return retVal; -+ -+ /*set to 8G mode (not 16G mode)*/ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LED_MODE, RTL8367C_DLINK_TIME_OFFSET, serimode))!= RT_ERR_OK) -+ return retVal; -+ -+ -+ return RT_ERR_OK; -+} -+ -+ -+/* -+@func ret_t | rtl8367c_getAsicLedSerialModeConfig | Get LED serial mode setup -+@parm rtk_uint32*| active | Active High or Low. -+@rvalue RT_ERR_OK | Success. -+@rvalue RT_ERR_SMI | SMI access error. -+@rvalue RT_ERR_INPUT | Invalid input value. -+@comm -+ The API can get LED serial mode setup and get signal active high/low. -+ */ -+ret_t rtl8367c_getAsicLedSerialModeConfig(rtk_uint32 *active, rtk_uint32 *serimode) -+{ -+ ret_t retVal; -+ -+ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_LED_SYS_CONFIG, RTL8367C_SERI_LED_ACT_LOW_OFFSET, active))!= RT_ERR_OK) -+ return retVal; -+ -+ /*get to 8G mode (not 16G mode)*/ -+ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_LED_MODE, RTL8367C_DLINK_TIME_OFFSET, serimode))!= RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+ -+/* -+@func ret_t | rtl8367c_setAsicLedOutputEnable | Set LED output enable -+@parm rtk_uint32 | enabled | enable or disable. -+@rvalue RT_ERR_OK | Success. -+@rvalue RT_ERR_SMI | SMI access error. -+@rvalue RT_ERR_INPUT | Invalid input value. -+@comm -+ The API can turn on/off LED output Enable -+ */ -+ret_t rtl8367c_setAsicLedOutputEnable(rtk_uint32 enabled) -+{ -+ ret_t retVal; -+ rtk_uint32 regdata; -+ -+ if (enabled == 1) -+ regdata = 0; -+ else -+ regdata = 1; -+ -+ /* Enable/Disable H/W IGMP/MLD */ -+ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LED_SYS_CONFIG, RTL8367C_LED_IO_DISABLE_OFFSET, regdata); -+ -+ return retVal; -+} -+ -+ -+/* -+@func ret_t | rtl8367c_getAsicLedOutputEnable | Get LED serial mode setup -+@parm rtk_uint32*| active | Active High or Low. -+@rvalue RT_ERR_OK | Success. -+@rvalue RT_ERR_SMI | SMI access error. -+@rvalue RT_ERR_INPUT | Invalid input value. -+@comm -+ The API can get LED serial mode setup and get signal active high/low. -+ */ -+ret_t rtl8367c_getAsicLedOutputEnable(rtk_uint32 *ptr_enabled) -+{ -+ ret_t retVal; -+ rtk_uint32 regdata; -+ -+ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_LED_SYS_CONFIG, RTL8367C_LED_IO_DISABLE_OFFSET, ®data); -+ if (retVal != RT_ERR_OK) -+ return retVal; -+ -+ if (regdata == 1) -+ *ptr_enabled = 0; -+ else -+ *ptr_enabled = 1; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicLedSerialOutput -+ * Description: -+ * Set serial LED output group and portmask. -+ * Input: -+ * output - Serial LED output group -+ * pmask - Serial LED output portmask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicLedSerialOutput(rtk_uint32 output, rtk_uint32 pmask) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SERIAL_LED_CTRL, RTL8367C_SERIAL_LED_GROUP_NUM_MASK, output); -+ if (retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SERIAL_LED_CTRL, RTL8367C_SERIAL_LED_PORT_EN_MASK, pmask); -+ if (retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicLedSerialOutput -+ * Description: -+ * Get serial LED output group and portmask. -+ * Input: -+ * None -+ * Output: -+ * pOutput - Serial LED output group -+ * pPmask - Serial LED output portmask -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicLedSerialOutput(rtk_uint32 *pOutput, rtk_uint32 *pPmask) -+{ -+ ret_t retVal; -+ -+ if(pOutput == NULL) -+ return RT_ERR_NULL_POINTER; -+ -+ if(pPmask == NULL) -+ return RT_ERR_NULL_POINTER; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SERIAL_LED_CTRL, RTL8367C_SERIAL_LED_GROUP_NUM_MASK, pOutput); -+ if (retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SERIAL_LED_CTRL, RTL8367C_SERIAL_LED_PORT_EN_MASK, pPmask); -+ if (retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_lut.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_lut.c -new file mode 100644 -index 000000000000..1521467aa8b4 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_lut.c -@@ -0,0 +1,1549 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : LUT related functions -+ * -+ */ -+ -+#include -+ -+#include -+ -+static void _rtl8367c_fdbStUser2Smi( rtl8367c_luttb *pLutSt, rtk_uint16 *pFdbSmi) -+{ -+ /* L3 lookup */ -+ if(pLutSt->l3lookup) -+ { -+ if(pLutSt->l3vidlookup) -+ { -+ pFdbSmi[0] = (pLutSt->sip & 0x0000FFFF); -+ pFdbSmi[1] = (pLutSt->sip & 0xFFFF0000) >> 16; -+ -+ pFdbSmi[2] = (pLutSt->dip & 0x0000FFFF); -+ pFdbSmi[3] = (pLutSt->dip & 0x0FFF0000) >> 16; -+ -+ pFdbSmi[3] |= (pLutSt->l3lookup & 0x0001) << 12; -+ pFdbSmi[3] |= (pLutSt->l3vidlookup & 0x0001) << 13; -+ pFdbSmi[3] |= ((pLutSt->mbr & 0x0300) >> 8) << 14; -+ -+ pFdbSmi[4] |= (pLutSt->mbr & 0x00FF); -+ pFdbSmi[4] |= (pLutSt->l3_vid & 0x00FF) << 8; -+ -+ pFdbSmi[5] |= ((pLutSt->l3_vid & 0x0F00) >> 8); -+ pFdbSmi[5] |= (pLutSt->nosalearn & 0x0001) << 5; -+ pFdbSmi[5] |= ((pLutSt->mbr & 0x0400) >> 10) << 7; -+ } -+ else -+ { -+ pFdbSmi[0] = (pLutSt->sip & 0x0000FFFF); -+ pFdbSmi[1] = (pLutSt->sip & 0xFFFF0000) >> 16; -+ -+ pFdbSmi[2] = (pLutSt->dip & 0x0000FFFF); -+ pFdbSmi[3] = (pLutSt->dip & 0x0FFF0000) >> 16; -+ -+ pFdbSmi[3] |= (pLutSt->l3lookup & 0x0001) << 12; -+ pFdbSmi[3] |= (pLutSt->l3vidlookup & 0x0001) << 13; -+ pFdbSmi[3] |= ((pLutSt->mbr & 0x0300) >> 8) << 14; -+ -+ pFdbSmi[4] |= (pLutSt->mbr & 0x00FF); -+ pFdbSmi[4] |= (pLutSt->igmpidx & 0x00FF) << 8; -+ -+ pFdbSmi[5] |= (pLutSt->igmp_asic & 0x0001); -+ pFdbSmi[5] |= (pLutSt->lut_pri & 0x0007) << 1; -+ pFdbSmi[5] |= (pLutSt->fwd_en & 0x0001) << 4; -+ pFdbSmi[5] |= (pLutSt->nosalearn & 0x0001) << 5; -+ pFdbSmi[5] |= ((pLutSt->mbr & 0x0400) >> 10) << 7; -+ } -+ } -+ else if(pLutSt->mac.octet[0] & 0x01) /*Multicast L2 Lookup*/ -+ { -+ pFdbSmi[0] |= pLutSt->mac.octet[5]; -+ pFdbSmi[0] |= pLutSt->mac.octet[4] << 8; -+ -+ pFdbSmi[1] |= pLutSt->mac.octet[3]; -+ pFdbSmi[1] |= pLutSt->mac.octet[2] << 8; -+ -+ pFdbSmi[2] |= pLutSt->mac.octet[1]; -+ pFdbSmi[2] |= pLutSt->mac.octet[0] << 8; -+ -+ pFdbSmi[3] |= pLutSt->cvid_fid; -+ pFdbSmi[3] |= (pLutSt->l3lookup & 0x0001) << 12; -+ pFdbSmi[3] |= (pLutSt->ivl_svl & 0x0001) << 13; -+ pFdbSmi[3] |= ((pLutSt->mbr & 0x0300) >> 8) << 14; -+ -+ pFdbSmi[4] |= (pLutSt->mbr & 0x00FF); -+ pFdbSmi[4] |= (pLutSt->igmpidx & 0x00FF) << 8; -+ -+ pFdbSmi[5] |= pLutSt->igmp_asic; -+ pFdbSmi[5] |= (pLutSt->lut_pri & 0x0007) << 1; -+ pFdbSmi[5] |= (pLutSt->fwd_en & 0x0001) << 4; -+ pFdbSmi[5] |= (pLutSt->nosalearn & 0x0001) << 5; -+ pFdbSmi[5] |= ((pLutSt->mbr & 0x0400) >> 10) << 7; -+ } -+ else /*Asic auto-learning*/ -+ { -+ pFdbSmi[0] |= pLutSt->mac.octet[5]; -+ pFdbSmi[0] |= pLutSt->mac.octet[4] << 8; -+ -+ pFdbSmi[1] |= pLutSt->mac.octet[3]; -+ pFdbSmi[1] |= pLutSt->mac.octet[2] << 8; -+ -+ pFdbSmi[2] |= pLutSt->mac.octet[1]; -+ pFdbSmi[2] |= pLutSt->mac.octet[0] << 8; -+ -+ pFdbSmi[3] |= pLutSt->cvid_fid; -+ pFdbSmi[3] |= (pLutSt->l3lookup & 0x0001) << 12; -+ pFdbSmi[3] |= (pLutSt->ivl_svl & 0x0001) << 13; -+ pFdbSmi[3] |= ((pLutSt->spa & 0x0008) >> 3) << 15; -+ -+ pFdbSmi[4] |= pLutSt->efid; -+ pFdbSmi[4] |= (pLutSt->fid & 0x000F) << 3; -+ pFdbSmi[4] |= (pLutSt->sa_en & 0x0001) << 7; -+ pFdbSmi[4] |= (pLutSt->spa & 0x0007) << 8; -+ pFdbSmi[4] |= (pLutSt->age & 0x0007) << 11; -+ pFdbSmi[4] |= (pLutSt->auth & 0x0001) << 14; -+ pFdbSmi[4] |= (pLutSt->sa_block & 0x0001) << 15; -+ -+ pFdbSmi[5] |= pLutSt->da_block; -+ pFdbSmi[5] |= (pLutSt->lut_pri & 0x0007) << 1; -+ pFdbSmi[5] |= (pLutSt->fwd_en & 0x0001) << 4; -+ pFdbSmi[5] |= (pLutSt->nosalearn & 0x0001) << 5; -+ } -+} -+ -+ -+static void _rtl8367c_fdbStSmi2User( rtl8367c_luttb *pLutSt, rtk_uint16 *pFdbSmi) -+{ -+ /*L3 lookup*/ -+ if(pFdbSmi[3] & 0x1000) -+ { -+ if(pFdbSmi[3] & 0x2000) -+ { -+ pLutSt->sip = pFdbSmi[0] | (pFdbSmi[1] << 16); -+ pLutSt->dip = pFdbSmi[2] | ((pFdbSmi[3] & 0x0FFF) << 16); -+ -+ pLutSt->mbr = (pFdbSmi[4] & 0x00FF) | (((pFdbSmi[3] & 0xC000) >> 14) << 8) | (((pFdbSmi[5] & 0x0080) >> 7) << 10); -+ pLutSt->l3_vid = ((pFdbSmi[4] & 0xFF00) >> 8) | (pFdbSmi[5] & 0x000F); -+ -+ pLutSt->l3lookup = (pFdbSmi[3] & 0x1000) >> 12; -+ pLutSt->l3vidlookup = (pFdbSmi[3] & 0x2000) >> 13; -+ pLutSt->nosalearn = (pFdbSmi[5] & 0x0020) >> 5; -+ } -+ else -+ { -+ pLutSt->sip = pFdbSmi[0] | (pFdbSmi[1] << 16); -+ pLutSt->dip = pFdbSmi[2] | ((pFdbSmi[3] & 0x0FFF) << 16); -+ -+ pLutSt->lut_pri = (pFdbSmi[5] & 0x000E) >> 1; -+ pLutSt->fwd_en = (pFdbSmi[5] & 0x0010) >> 4; -+ -+ pLutSt->mbr = (pFdbSmi[4] & 0x00FF) | (((pFdbSmi[3] & 0xC000) >> 14) << 8) | (((pFdbSmi[5] & 0x0080) >> 7) << 10); -+ pLutSt->igmpidx = (pFdbSmi[4] & 0xFF00) >> 8; -+ -+ pLutSt->igmp_asic = (pFdbSmi[5] & 0x0001); -+ pLutSt->l3lookup = (pFdbSmi[3] & 0x1000) >> 12; -+ pLutSt->nosalearn = (pFdbSmi[5] & 0x0020) >> 5; -+ } -+ } -+ else if(pFdbSmi[2] & 0x0100) /*Multicast L2 Lookup*/ -+ { -+ pLutSt->mac.octet[0] = (pFdbSmi[2] & 0xFF00) >> 8; -+ pLutSt->mac.octet[1] = (pFdbSmi[2] & 0x00FF); -+ pLutSt->mac.octet[2] = (pFdbSmi[1] & 0xFF00) >> 8; -+ pLutSt->mac.octet[3] = (pFdbSmi[1] & 0x00FF); -+ pLutSt->mac.octet[4] = (pFdbSmi[0] & 0xFF00) >> 8; -+ pLutSt->mac.octet[5] = (pFdbSmi[0] & 0x00FF); -+ -+ pLutSt->cvid_fid = pFdbSmi[3] & 0x0FFF; -+ pLutSt->lut_pri = (pFdbSmi[5] & 0x000E) >> 1; -+ pLutSt->fwd_en = (pFdbSmi[5] & 0x0010) >> 4; -+ -+ pLutSt->mbr = (pFdbSmi[4] & 0x00FF) | (((pFdbSmi[3] & 0xC000) >> 14) << 8) | (((pFdbSmi[5] & 0x0080) >> 7) << 10); -+ pLutSt->igmpidx = (pFdbSmi[4] & 0xFF00) >> 8; -+ -+ pLutSt->igmp_asic = (pFdbSmi[5] & 0x0001); -+ pLutSt->l3lookup = (pFdbSmi[3] & 0x1000) >> 12; -+ pLutSt->ivl_svl = (pFdbSmi[3] & 0x2000) >> 13; -+ pLutSt->nosalearn = (pFdbSmi[5] & 0x0020) >> 5; -+ } -+ else /*Asic auto-learning*/ -+ { -+ pLutSt->mac.octet[0] = (pFdbSmi[2] & 0xFF00) >> 8; -+ pLutSt->mac.octet[1] = (pFdbSmi[2] & 0x00FF); -+ pLutSt->mac.octet[2] = (pFdbSmi[1] & 0xFF00) >> 8; -+ pLutSt->mac.octet[3] = (pFdbSmi[1] & 0x00FF); -+ pLutSt->mac.octet[4] = (pFdbSmi[0] & 0xFF00) >> 8; -+ pLutSt->mac.octet[5] = (pFdbSmi[0] & 0x00FF); -+ -+ pLutSt->cvid_fid = pFdbSmi[3] & 0x0FFF; -+ pLutSt->lut_pri = (pFdbSmi[5] & 0x000E) >> 1; -+ pLutSt->fwd_en = (pFdbSmi[5] & 0x0010) >> 4; -+ -+ pLutSt->sa_en = (pFdbSmi[4] & 0x0080) >> 7; -+ pLutSt->auth = (pFdbSmi[4] & 0x4000) >> 14; -+ pLutSt->spa = ((pFdbSmi[4] & 0x0700) >> 8) | (((pFdbSmi[3] & 0x8000) >> 15) << 3); -+ pLutSt->age = (pFdbSmi[4] & 0x3800) >> 11; -+ pLutSt->fid = (pFdbSmi[4] & 0x0078) >> 3; -+ pLutSt->efid = (pFdbSmi[4] & 0x0007); -+ pLutSt->sa_block = (pFdbSmi[4] & 0x8000) >> 15; -+ -+ pLutSt->da_block = (pFdbSmi[5] & 0x0001); -+ pLutSt->l3lookup = (pFdbSmi[3] & 0x1000) >> 12; -+ pLutSt->ivl_svl = (pFdbSmi[3] & 0x2000) >> 13; -+ pLutSt->nosalearn = (pFdbSmi[3] & 0x0020) >> 5; -+ } -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicLutIpMulticastLookup -+ * Description: -+ * Set LUT IP multicast lookup function -+ * Input: -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicLutIpMulticastLookup(rtk_uint32 enabled) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_LUT_IPMC_HASH_OFFSET, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicLutIpMulticastLookup -+ * Description: -+ * Get LUT IP multicast lookup function -+ * Input: -+ * pEnabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicLutIpMulticastLookup(rtk_uint32* pEnabled) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_LUT_IPMC_HASH_OFFSET, pEnabled); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicLutIpMulticastLookup -+ * Description: -+ * Set LUT IP multicast + VID lookup function -+ * Input: -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicLutIpMulticastVidLookup(rtk_uint32 enabled) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_LUT_CFG2, RTL8367C_LUT_IPMC_VID_HASH_OFFSET, enabled); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicLutIpMulticastVidLookup -+ * Description: -+ * Get LUT IP multicast lookup function -+ * Input: -+ * pEnabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicLutIpMulticastVidLookup(rtk_uint32* pEnabled) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_LUT_CFG2, RTL8367C_LUT_IPMC_VID_HASH_OFFSET, pEnabled); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicLutIpLookupMethod -+ * Description: -+ * Set LUT IP lookup hash with DIP or {DIP,SIP} pair -+ * Input: -+ * type - 1: When DIP can be found in IPMC_GROUP_TABLE, use DIP+SIP Hash, otherwise, use DIP+(SIP=0.0.0.0) Hash. -+ * 0: When DIP can be found in IPMC_GROUP_TABLE, use DIP+(SIP=0.0.0.0) Hash, otherwise use DIP+SIP Hash. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicLutIpLookupMethod(rtk_uint32 type) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_LUT_IPMC_LOOKUP_OP_OFFSET, type); -+} -+/* Function Name: -+ * rtl8367c_getAsicLutIpLookupMethod -+ * Description: -+ * Get LUT IP lookup hash with DIP or {DIP,SIP} pair -+ * Input: -+ * pType - 1: When DIP can be found in IPMC_GROUP_TABLE, use DIP+SIP Hash, otherwise, use DIP+(SIP=0.0.0.0) Hash. -+ * 0: When DIP can be found in IPMC_GROUP_TABLE, use DIP+(SIP=0.0.0.0) Hash, otherwise use DIP+SIP Hash. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicLutIpLookupMethod(rtk_uint32* pType) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_LUT_IPMC_LOOKUP_OP_OFFSET, pType); -+} -+/* Function Name: -+ * rtl8367c_setAsicLutAgeTimerSpeed -+ * Description: -+ * Set LUT ageing out speed -+ * Input: -+ * timer - Ageing out timer 0:Has been aged out -+ * speed - Ageing out speed 0-fastest 3-slowest -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicLutAgeTimerSpeed(rtk_uint32 timer, rtk_uint32 speed) -+{ -+ if(timer>RTL8367C_LUT_AGETIMERMAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(speed >RTL8367C_LUT_AGESPEEDMAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_LUT_CFG, RTL8367C_AGE_TIMER_MASK | RTL8367C_AGE_SPEED_MASK, (timer << RTL8367C_AGE_TIMER_OFFSET) | (speed << RTL8367C_AGE_SPEED_OFFSET)); -+} -+/* Function Name: -+ * rtl8367c_getAsicLutAgeTimerSpeed -+ * Description: -+ * Get LUT ageing out speed -+ * Input: -+ * pTimer - Ageing out timer 0:Has been aged out -+ * pSpeed - Ageing out speed 0-fastest 3-slowest -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicLutAgeTimerSpeed(rtk_uint32* pTimer, rtk_uint32* pSpeed) -+{ -+ rtk_uint32 regData; -+ ret_t retVal; -+ -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_LUT_CFG, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *pTimer = (regData & RTL8367C_AGE_TIMER_MASK) >> RTL8367C_AGE_TIMER_OFFSET; -+ -+ *pSpeed = (regData & RTL8367C_AGE_SPEED_MASK) >> RTL8367C_AGE_SPEED_OFFSET; -+ -+ return RT_ERR_OK; -+ -+} -+/* Function Name: -+ * rtl8367c_setAsicLutCamTbUsage -+ * Description: -+ * Configure LUT CAM table usage -+ * Input: -+ * enabled - L2 CAM table usage 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicLutCamTbUsage(rtk_uint32 enabled) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_BCAM_DISABLE_OFFSET, enabled ? 0 : 1); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicLutCamTbUsage -+ * Description: -+ * Get LUT CAM table usage -+ * Input: -+ * pEnabled - L2 CAM table usage 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicLutCamTbUsage(rtk_uint32* pEnabled) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ -+ if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_BCAM_DISABLE_OFFSET, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ *pEnabled = regData ? 0 : 1; -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicLutLearnLimitNo -+ * Description: -+ * Set per-Port auto learning limit number -+ * Input: -+ * port - Physical port number (0~7) -+ * number - ASIC auto learning entries limit number -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_LIMITED_L2ENTRY_NUM - Invalid auto learning limit number -+ * Note: -+ * None -+ */ -+ /*modification: RTL8367C_PORTIDMAX, RTL8367C_LUT_LEARNLIMITMAX, RTL8367C_LUT_PORT_LEARN_LIMITNO_REG*/ -+ret_t rtl8367c_setAsicLutLearnLimitNo(rtk_uint32 port, rtk_uint32 number) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(number > RTL8367C_LUT_LEARNLIMITMAX) -+ return RT_ERR_LIMITED_L2ENTRY_NUM; -+ -+ if(port < 8) -+ return rtl8367c_setAsicReg(RTL8367C_LUT_PORT_LEARN_LIMITNO_REG(port), number); -+ else -+ return rtl8367c_setAsicReg(RTL8367C_REG_LUT_PORT8_LEARN_LIMITNO+port-8, number); -+ -+} -+/* Function Name: -+ * rtl8367c_getAsicLutLearnLimitNo -+ * Description: -+ * Get per-Port auto learning limit number -+ * Input: -+ * port - Physical port number (0~7) -+ * pNumber - ASIC auto learning entries limit number -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ /*modification: RTL8367C_PORTIDMAX, RTL8367C_LUT_PORT_LEARN_LIMITNO_REG*/ -+ret_t rtl8367c_getAsicLutLearnLimitNo(rtk_uint32 port, rtk_uint32* pNumber) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(port < 8) -+ return rtl8367c_getAsicReg(RTL8367C_LUT_PORT_LEARN_LIMITNO_REG(port), pNumber); -+ else -+ return rtl8367c_getAsicReg(RTL8367C_REG_LUT_PORT8_LEARN_LIMITNO+port-8, pNumber); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicSystemLutLearnLimitNo -+ * Description: -+ * Set system auto learning limit number -+ * Input: -+ * number - ASIC auto learning entries limit number -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_LIMITED_L2ENTRY_NUM - Invalid auto learning limit number -+ * Note: -+ * None -+ */ -+ /*modification: RTL8367C_LUT_LEARNLIMITMAX*/ -+ret_t rtl8367c_setAsicSystemLutLearnLimitNo(rtk_uint32 number) -+{ -+ if(number > RTL8367C_LUT_LEARNLIMITMAX) -+ return RT_ERR_LIMITED_L2ENTRY_NUM; -+ -+ return rtl8367c_setAsicReg(RTL8367C_REG_LUT_SYS_LEARN_LIMITNO, number); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicSystemLutLearnLimitNo -+ * Description: -+ * Get system auto learning limit number -+ * Input: -+ * port - Physical port number (0~7) -+ * pNumber - ASIC auto learning entries limit number -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicSystemLutLearnLimitNo(rtk_uint32 *pNumber) -+{ -+ if(NULL == pNumber) -+ return RT_ERR_NULL_POINTER; -+ -+ return rtl8367c_getAsicReg(RTL8367C_REG_LUT_SYS_LEARN_LIMITNO, pNumber); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicLutLearnOverAct -+ * Description: -+ * Set auto learn over limit number action -+ * Input: -+ * action - Learn over action 0:normal, 1:drop 2:trap -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NOT_ALLOWED - Invalid learn over action -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicLutLearnOverAct(rtk_uint32 action) -+{ -+ if(action >= LRNOVERACT_END) -+ return RT_ERR_NOT_ALLOWED; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_PORT_SECURITY_CTRL, RTL8367C_LUT_LEARN_OVER_ACT_MASK, action); -+} -+/* Function Name: -+ * rtl8367c_getAsicLutLearnOverAct -+ * Description: -+ * Get auto learn over limit number action -+ * Input: -+ * pAction - Learn over action 0:normal, 1:drop 2:trap -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicLutLearnOverAct(rtk_uint32* pAction) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_SECURITY_CTRL, RTL8367C_LUT_LEARN_OVER_ACT_MASK, pAction); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicSystemLutLearnOverAct -+ * Description: -+ * Set system auto learn over limit number action -+ * Input: -+ * action - Learn over action 0:normal, 1:drop, 2:trap -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NOT_ALLOWED - Invalid learn over action -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicSystemLutLearnOverAct(rtk_uint32 action) -+{ -+ if(action >= LRNOVERACT_END) -+ return RT_ERR_NOT_ALLOWED; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_LUT_LRN_SYS_LMT_CTRL, RTL8367C_LUT_SYSTEM_LEARN_OVER_ACT_MASK, action); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicSystemLutLearnOverAct -+ * Description: -+ * Get system auto learn over limit number action -+ * Input: -+ * pAction - Learn over action 0:normal, 1:drop 2:trap -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicSystemLutLearnOverAct(rtk_uint32 *pAction) -+{ -+ if(NULL == pAction) -+ return RT_ERR_NULL_POINTER; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_LUT_LRN_SYS_LMT_CTRL, RTL8367C_LUT_SYSTEM_LEARN_OVER_ACT_MASK, pAction); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicSystemLutLearnPortMask -+ * Description: -+ * Set system auto learn limit port mask -+ * Input: -+ * portmask - port mask of system learning limit -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Error port mask -+ * Note: -+ * None -+ */ -+ /*modification: RTL8367C_LUT_SYSTEM_LEARN_PMASK_MASK*/ -+ret_t rtl8367c_setAsicSystemLutLearnPortMask(rtk_uint32 portmask) -+{ -+ ret_t retVal; -+ -+ if(portmask > RTL8367C_PORTMASK) -+ return RT_ERR_PORT_MASK; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_LUT_LRN_SYS_LMT_CTRL, RTL8367C_LUT_SYSTEM_LEARN_PMASK_MASK, portmask & 0xff); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_LUT_LRN_SYS_LMT_CTRL, RTL8367C_LUT_SYSTEM_LEARN_PMASK1_MASK, (portmask>>8) & 0x7); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+ -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicSystemLutLearnPortMask -+ * Description: -+ * Get system auto learn limit port mask -+ * Input: -+ * None -+ * Output: -+ * pPortmask - port mask of system learning limit -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - NULL pointer -+ * Note: -+ * None -+ */ -+ /*modification: RTL8367C_LUT_SYSTEM_LEARN_PMASK_MASK*/ -+ret_t rtl8367c_getAsicSystemLutLearnPortMask(rtk_uint32 *pPortmask) -+{ -+ rtk_uint32 tmpmask; -+ ret_t retVal; -+ -+ if(NULL == pPortmask) -+ return RT_ERR_NULL_POINTER; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_LUT_LRN_SYS_LMT_CTRL, RTL8367C_LUT_SYSTEM_LEARN_PMASK_MASK, &tmpmask); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ *pPortmask = tmpmask & 0xff; -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_LUT_LRN_SYS_LMT_CTRL, RTL8367C_LUT_SYSTEM_LEARN_PMASK1_MASK, &tmpmask); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ *pPortmask |= (tmpmask & 0x7) << 8; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicL2LookupTb -+ * Description: -+ * Set filtering database entry -+ * Input: -+ * pL2Table - L2 table entry writing to 8K+64 filtering database -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicL2LookupTb(rtl8367c_luttb *pL2Table) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ rtk_uint16 *accessPtr; -+ rtk_uint32 i; -+ rtk_uint16 smil2Table[RTL8367C_LUT_TABLE_SIZE]; -+ rtk_uint32 tblCmd; -+ rtk_uint32 busyCounter; -+ -+ memset(smil2Table, 0x00, sizeof(rtk_uint16) * RTL8367C_LUT_TABLE_SIZE); -+ _rtl8367c_fdbStUser2Smi(pL2Table, smil2Table); -+ -+ if(pL2Table->wait_time == 0) -+ busyCounter = RTL8367C_LUT_BUSY_CHECK_NO; -+ else -+ busyCounter = pL2Table->wait_time; -+ -+ while(busyCounter) -+ { -+ retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_OFFSET,®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ pL2Table->lookup_busy = regData; -+ if(!regData) -+ break; -+ -+ busyCounter --; -+ if(busyCounter == 0) -+ return RT_ERR_BUSYWAIT_TIMEOUT; -+ } -+ -+ accessPtr = smil2Table; -+ regData = *accessPtr; -+ for(i = 0; i < RTL8367C_LUT_ENTRY_SIZE; i++) -+ { -+ retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_WRDATA_BASE + i, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ accessPtr ++; -+ regData = *accessPtr; -+ -+ } -+ -+ tblCmd = (RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_WRITE,TB_TARGET_L2)) & (RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK); -+ /* Write Command */ -+ retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_CTRL_REG, tblCmd); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ if(pL2Table->wait_time == 0) -+ busyCounter = RTL8367C_LUT_BUSY_CHECK_NO; -+ else -+ busyCounter = pL2Table->wait_time; -+ -+ while(busyCounter) -+ { -+ retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_OFFSET,®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ pL2Table->lookup_busy = regData; -+ if(!regData) -+ break; -+ -+ busyCounter --; -+ if(busyCounter == 0) -+ return RT_ERR_BUSYWAIT_TIMEOUT; -+ } -+ -+ /*Read access status*/ -+ retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_HIT_STATUS_OFFSET, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ pL2Table->lookup_hit = regData; -+ if(!pL2Table->lookup_hit) -+ return RT_ERR_FAILED; -+ -+ /*Read access address*/ -+ /* -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_TYPE_MASK | RTL8367C_TABLE_LUT_ADDR_ADDRESS_MASK,®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ pL2Table->address = regData;*/ -+ -+ retVal = rtl8367c_getAsicReg(RTL8367C_TABLE_ACCESS_STATUS_REG, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ pL2Table->address = (regData & 0x7ff) | ((regData & 0x4000) >> 3) | ((regData & 0x800) << 1); -+ pL2Table->lookup_busy = 0; -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicL2LookupTb -+ * Description: -+ * Get filtering database entry -+ * Input: -+ * pL2Table - L2 table entry writing to 2K+64 filtering database -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter -+ * RT_ERR_BUSYWAIT_TIMEOUT - LUT is busy at retrieving -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicL2LookupTb(rtk_uint32 method, rtl8367c_luttb *pL2Table) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ rtk_uint16* accessPtr; -+ rtk_uint32 i; -+ rtk_uint16 smil2Table[RTL8367C_LUT_TABLE_SIZE]; -+ rtk_uint32 busyCounter; -+ rtk_uint32 tblCmd; -+ -+ if(pL2Table->wait_time == 0) -+ busyCounter = RTL8367C_LUT_BUSY_CHECK_NO; -+ else -+ busyCounter = pL2Table->wait_time; -+ -+ while(busyCounter) -+ { -+ retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_OFFSET,®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ pL2Table->lookup_busy = regData; -+ if(!pL2Table->lookup_busy) -+ break; -+ -+ busyCounter --; -+ if(busyCounter == 0) -+ return RT_ERR_BUSYWAIT_TIMEOUT; -+ } -+ -+ -+ tblCmd = (method << RTL8367C_ACCESS_METHOD_OFFSET) & RTL8367C_ACCESS_METHOD_MASK; -+ -+ switch(method) -+ { -+ case LUTREADMETHOD_ADDRESS: -+ case LUTREADMETHOD_NEXT_ADDRESS: -+ case LUTREADMETHOD_NEXT_L2UC: -+ case LUTREADMETHOD_NEXT_L2MC: -+ case LUTREADMETHOD_NEXT_L3MC: -+ case LUTREADMETHOD_NEXT_L2L3MC: -+ retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_ADDR_REG, pL2Table->address); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ break; -+ case LUTREADMETHOD_MAC: -+ memset(smil2Table, 0x00, sizeof(rtk_uint16) * RTL8367C_LUT_TABLE_SIZE); -+ _rtl8367c_fdbStUser2Smi(pL2Table, smil2Table); -+ -+ accessPtr = smil2Table; -+ regData = *accessPtr; -+ for(i=0; iaddress); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ tblCmd = tblCmd | ((pL2Table->spa << RTL8367C_TABLE_ACCESS_CTRL_SPA_OFFSET) & RTL8367C_TABLE_ACCESS_CTRL_SPA_MASK); -+ -+ break; -+ default: -+ return RT_ERR_INPUT; -+ } -+ -+ tblCmd = tblCmd | ((RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_READ,TB_TARGET_L2)) & (RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK)); -+ /* Read Command */ -+ retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_CTRL_REG, tblCmd); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ if(pL2Table->wait_time == 0) -+ busyCounter = RTL8367C_LUT_BUSY_CHECK_NO; -+ else -+ busyCounter = pL2Table->wait_time; -+ -+ while(busyCounter) -+ { -+ retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_OFFSET,®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ pL2Table->lookup_busy = regData; -+ if(!pL2Table->lookup_busy) -+ break; -+ -+ busyCounter --; -+ if(busyCounter == 0) -+ return RT_ERR_BUSYWAIT_TIMEOUT; -+ } -+ -+ retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_HIT_STATUS_OFFSET,®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ pL2Table->lookup_hit = regData; -+ if(!pL2Table->lookup_hit) -+ return RT_ERR_L2_ENTRY_NOTFOUND; -+ -+ /*Read access address*/ -+ //retVal = rtl8367c_getAsicRegBits(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_TYPE_MASK | RTL8367C_TABLE_LUT_ADDR_ADDRESS_MASK,®Data); -+ retVal = rtl8367c_getAsicReg(RTL8367C_TABLE_ACCESS_STATUS_REG, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ pL2Table->address = (regData & 0x7ff) | ((regData & 0x4000) >> 3) | ((regData & 0x800) << 1); -+ -+ /*read L2 entry */ -+ memset(smil2Table, 0x00, sizeof(rtk_uint16) * RTL8367C_LUT_TABLE_SIZE); -+ -+ accessPtr = smil2Table; -+ -+ for(i = 0; i < RTL8367C_LUT_ENTRY_SIZE; i++) -+ { -+ retVal = rtl8367c_getAsicReg(RTL8367C_TABLE_ACCESS_RDDATA_BASE + i, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *accessPtr = regData; -+ -+ accessPtr ++; -+ } -+ -+ _rtl8367c_fdbStSmi2User(pL2Table, smil2Table); -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicLutLearnNo -+ * Description: -+ * Get per-Port auto learning number -+ * Input: -+ * port - Physical port number (0~7) -+ * pNumber - ASIC auto learning entries number -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ /*modification:RTL8367C_PORTIDMAX, RTL8367C_REG_L2_LRN_CNT_REG, port10 reg is not continuous, wait for updating of base.h*/ -+ret_t rtl8367c_getAsicLutLearnNo(rtk_uint32 port, rtk_uint32* pNumber) -+{ -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(port < 10) -+ { -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_L2_LRN_CNT_REG(port), pNumber); -+ if (retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_L2_LRN_CNT_CTRL10, pNumber); -+ if (retVal != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicLutFlushAll -+ * Description: -+ * Flush all entries in LUT. Includes static & dynamic entries -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicLutFlushAll(void) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_L2_FLUSH_CTRL3, RTL8367C_L2_FLUSH_CTRL3_OFFSET, 1); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicLutFlushAllStatus -+ * Description: -+ * Get Flush all status, 1:Busy, 0 normal -+ * Input: -+ * None -+ * Output: -+ * pBusyStatus - Busy state -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicLutFlushAllStatus(rtk_uint32 *pBusyStatus) -+{ -+ if(NULL == pBusyStatus) -+ return RT_ERR_NULL_POINTER; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_L2_FLUSH_CTRL3, RTL8367C_L2_FLUSH_CTRL3_OFFSET, pBusyStatus); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicLutForceFlush -+ * Description: -+ * Set per port force flush setting -+ * Input: -+ * portmask - portmask(0~0xFF) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Invalid portmask -+ * Note: -+ * None -+ */ -+ /*port8~port10 setup is done in a separate register, wait for updating of base.h, reg.h*/ -+ret_t rtl8367c_setAsicLutForceFlush(rtk_uint32 portmask) -+{ -+ ret_t retVal; -+ -+ if(portmask > RTL8367C_PORTMASK) -+ return RT_ERR_PORT_MASK; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_FORCE_FLUSH_REG, RTL8367C_FORCE_FLUSH_PORTMASK_MASK, portmask & 0xff); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FORCE_FLUSH1, RTL8367C_PORTMASK1_MASK, (portmask >> 8) & 0x7); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicLutForceFlushStatus -+ * Description: -+ * Get per port force flush status -+ * Input: -+ * pPortmask - portmask(0~0xFF) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ /*port8~port10 setup is done in a separate register, wait for updating of base.h, reg.h*/ -+ret_t rtl8367c_getAsicLutForceFlushStatus(rtk_uint32 *pPortmask) -+{ -+ rtk_uint32 tmpMask; -+ ret_t retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_FORCE_FLUSH_REG, RTL8367C_BUSY_STATUS_MASK,&tmpMask); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ *pPortmask = tmpMask & 0xff; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FORCE_FLUSH1, RTL8367C_BUSY_STATUS1_MASK,&tmpMask); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ *pPortmask |= (tmpMask & 7) << 8; -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicLutFlushMode -+ * Description: -+ * Set user force L2 pLutSt table flush mode -+ * Input: -+ * mode - 0:Port based 1: Port + VLAN based 2:Port + FID/MSTI based -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NOT_ALLOWED - Actions not allowed by the function -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicLutFlushMode(rtk_uint32 mode) -+{ -+ if( mode >= FLUSHMDOE_END ) -+ return RT_ERR_NOT_ALLOWED; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_L2_FLUSH_CTRL2, RTL8367C_LUT_FLUSH_MODE_MASK, mode); -+} -+/* Function Name: -+ * rtl8367c_getAsicLutFlushMode -+ * Description: -+ * Get user force L2 pLutSt table flush mode -+ * Input: -+ * pMode - 0:Port based 1: Port + VLAN based 2:Port + FID/MSTI based -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicLutFlushMode(rtk_uint32* pMode) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_L2_FLUSH_CTRL2, RTL8367C_LUT_FLUSH_MODE_MASK, pMode); -+} -+/* Function Name: -+ * rtl8367c_setAsicLutFlushType -+ * Description: -+ * Get L2 LUT flush type -+ * Input: -+ * type - 0: dynamic unicast; 1: both dynamic and static unicast entry -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicLutFlushType(rtk_uint32 type) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_L2_FLUSH_CTRL2, RTL8367C_LUT_FLUSH_TYPE_OFFSET,type); -+} -+/* Function Name: -+ * rtl8367c_getAsicLutFlushType -+ * Description: -+ * Set L2 LUT flush type -+ * Input: -+ * pType - 0: dynamic unicast; 1: both dynamic and static unicast entry -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicLutFlushType(rtk_uint32* pType) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_L2_FLUSH_CTRL2, RTL8367C_LUT_FLUSH_TYPE_OFFSET,pType); -+} -+ -+ -+/* Function Name: -+ * rtl8367c_setAsicLutFlushVid -+ * Description: -+ * Set VID of Port + VID pLutSt flush mode -+ * Input: -+ * vid - Vid (0~4095) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_VLAN_VID - Invalid VID parameter (0~4095) -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicLutFlushVid(rtk_uint32 vid) -+{ -+ if( vid > RTL8367C_VIDMAX ) -+ return RT_ERR_VLAN_VID; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_L2_FLUSH_CTRL1, RTL8367C_LUT_FLUSH_VID_MASK, vid); -+} -+/* Function Name: -+ * rtl8367c_getAsicLutFlushVid -+ * Description: -+ * Get VID of Port + VID pLutSt flush mode -+ * Input: -+ * pVid - Vid (0~4095) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicLutFlushVid(rtk_uint32* pVid) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_L2_FLUSH_CTRL1, RTL8367C_LUT_FLUSH_VID_MASK, pVid); -+} -+/* Function Name: -+ * rtl8367c_setAsicPortFlusdFid -+ * Description: -+ * Set FID of Port + FID pLutSt flush mode -+ * Input: -+ * fid - FID/MSTI for force flush -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_L2_FID - Invalid FID (0~15) -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicLutFlushFid(rtk_uint32 fid) -+{ -+ if( fid > RTL8367C_FIDMAX ) -+ return RT_ERR_L2_FID; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_L2_FLUSH_CTRL1, RTL8367C_LUT_FLUSH_FID_MASK, fid); -+} -+/* Function Name: -+ * rtl8367c_getAsicLutFlushFid -+ * Description: -+ * Get FID of Port + FID pLutSt flush mode -+ * Input: -+ * pFid - FID/MSTI for force flush -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicLutFlushFid(rtk_uint32* pFid) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_L2_FLUSH_CTRL1, RTL8367C_LUT_FLUSH_FID_MASK, pFid); -+} -+/* Function Name: -+ * rtl8367c_setAsicLutDisableAging -+ * Description: -+ * Set L2 LUT aging per port setting -+ * Input: -+ * port - Physical port number (0~7) -+ * disabled - 0: enable aging; 1: disabling aging -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ /*modification:RTL8367C_PORTIDMAX*/ -+ret_t rtl8367c_setAsicLutDisableAging(rtk_uint32 port, rtk_uint32 disabled) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_LUT_AGEOUT_CTRL_REG, port, disabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicLutDisableAging -+ * Description: -+ * Get L2 LUT aging per port setting -+ * Input: -+ * port - Physical port number (0~7) -+ * pDisabled - 0: enable aging; 1: disabling aging -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ /*modification:RTL8367C_PORTIDMAX*/ -+ret_t rtl8367c_getAsicLutDisableAging(rtk_uint32 port, rtk_uint32 *pDisabled) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_LUT_AGEOUT_CTRL_REG, port, pDisabled); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicLutIPMCGroup -+ * Description: -+ * Set IPMC Group Table -+ * Input: -+ * index - the entry index in table (0 ~ 63) -+ * group_addr - the multicast group address (224.0.0.0 ~ 239.255.255.255) -+ * vid - VLAN ID -+ * pmask - portmask -+ * valid - valid bit -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid parameter -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicLutIPMCGroup(rtk_uint32 index, ipaddr_t group_addr, rtk_uint32 vid, rtk_uint32 pmask, rtk_uint32 valid) -+{ -+ rtk_uint32 regAddr, regData, bitoffset; -+ ipaddr_t ipData; -+ ret_t retVal; -+ -+ if(index > RTL8367C_LUT_IPMCGRP_TABLE_MAX) -+ return RT_ERR_INPUT; -+ -+ if (vid > RTL8367C_VIDMAX) -+ return RT_ERR_VLAN_VID; -+ -+ ipData = group_addr; -+ -+ if( (ipData & 0xF0000000) != 0xE0000000) /* not in 224.0.0.0 ~ 239.255.255.255 */ -+ return RT_ERR_INPUT; -+ -+ /* Group Address */ -+ regAddr = RTL8367C_REG_IPMC_GROUP_ENTRY0_H + (index * 2); -+ regData = ((ipData & 0x0FFFFFFF) >> 16); -+ -+ if( (retVal = rtl8367c_setAsicReg(regAddr, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ regAddr++; -+ regData = (ipData & 0x0000FFFF); -+ -+ if( (retVal = rtl8367c_setAsicReg(regAddr, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ /* VID */ -+ regAddr = RTL8367C_REG_IPMC_GROUP_VID_00 + index; -+ regData = vid; -+ -+ if( (retVal = rtl8367c_setAsicReg(regAddr, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ /* portmask */ -+ regAddr = RTL8367C_REG_IPMC_GROUP_PMSK_00 + index; -+ regData = pmask; -+ -+ if( (retVal = rtl8367c_setAsicReg(regAddr, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ /* valid */ -+ regAddr = RTL8367C_REG_IPMC_GROUP_VALID_15_0 + (index / 16); -+ bitoffset = index % 16; -+ if( (retVal = rtl8367c_setAsicRegBit(regAddr, bitoffset, valid)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicLutIPMCGroup -+ * Description: -+ * Set IPMC Group Table -+ * Input: -+ * index - the entry index in table (0 ~ 63) -+ * Output: -+ * pGroup_addr - the multicast group address (224.0.0.0 ~ 239.255.255.255) -+ * pVid - VLAN ID -+ * pPmask - portmask -+ * pValid - Valid bit -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid parameter -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicLutIPMCGroup(rtk_uint32 index, ipaddr_t *pGroup_addr, rtk_uint32 *pVid, rtk_uint32 *pPmask, rtk_uint32 *pValid) -+{ -+ rtk_uint32 regAddr, regData, bitoffset; -+ ipaddr_t ipData; -+ ret_t retVal; -+ -+ if(index > RTL8367C_LUT_IPMCGRP_TABLE_MAX) -+ return RT_ERR_INPUT; -+ -+ if (NULL == pGroup_addr) -+ return RT_ERR_NULL_POINTER; -+ -+ if (NULL == pVid) -+ return RT_ERR_NULL_POINTER; -+ -+ if (NULL == pPmask) -+ return RT_ERR_NULL_POINTER; -+ -+ /* Group address */ -+ regAddr = RTL8367C_REG_IPMC_GROUP_ENTRY0_H + (index * 2); -+ if( (retVal = rtl8367c_getAsicReg(regAddr, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ *pGroup_addr = (((regData & 0x00000FFF) << 16) | 0xE0000000); -+ -+ regAddr++; -+ if( (retVal = rtl8367c_getAsicReg(regAddr, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ ipData = (*pGroup_addr | (regData & 0x0000FFFF)); -+ *pGroup_addr = ipData; -+ -+ /* VID */ -+ regAddr = RTL8367C_REG_IPMC_GROUP_VID_00 + index; -+ if( (retVal = rtl8367c_getAsicReg(regAddr, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ *pVid = regData; -+ -+ /* portmask */ -+ regAddr = RTL8367C_REG_IPMC_GROUP_PMSK_00 + index; -+ if( (retVal = rtl8367c_getAsicReg(regAddr, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ *pPmask = regData; -+ -+ /* valid */ -+ regAddr = RTL8367C_REG_IPMC_GROUP_VALID_15_0 + (index / 16); -+ bitoffset = index % 16; -+ if( (retVal = rtl8367c_getAsicRegBit(regAddr, bitoffset, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ *pValid = regData; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicLutLinkDownForceAging -+ * Description: -+ * Set LUT link down aging setting. -+ * Input: -+ * enable - link down aging setting -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_ENABLE - Invalid parameter -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicLutLinkDownForceAging(rtk_uint32 enable) -+{ -+ if(enable > 1) -+ return RT_ERR_ENABLE; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_LINKDOWN_AGEOUT_OFFSET, enable ? 0 : 1); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicLutLinkDownForceAging -+ * Description: -+ * Get LUT link down aging setting. -+ * Input: -+ * pEnable - link down aging setting -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_ENABLE - Invalid parameter -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicLutLinkDownForceAging(rtk_uint32 *pEnable) -+{ -+ rtk_uint32 value; -+ ret_t retVal; -+ -+ if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_LINKDOWN_AGEOUT_OFFSET, &value)) != RT_ERR_OK) -+ return retVal; -+ -+ *pEnable = value ? 0 : 1; -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicLutIpmcFwdRouterPort -+ * Description: -+ * Set IPMC packet forward to router port also or not -+ * Input: -+ * enable - 1: Include router port, 0, exclude router port -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_ENABLE Invalid parameter -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicLutIpmcFwdRouterPort(rtk_uint32 enable) -+{ -+ if(enable > 1) -+ return RT_ERR_ENABLE; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_LUT_CFG2, RTL8367C_LUT_IPMC_FWD_RPORT_OFFSET, enable); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicLutIpmcFwdRouterPort -+ * Description: -+ * Get IPMC packet forward to router port also or not -+ * Input: -+ * None -+ * Output: -+ * pEnable - 1: Include router port, 0, exclude router port -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicLutIpmcFwdRouterPort(rtk_uint32 *pEnable) -+{ -+ if(NULL == pEnable) -+ return RT_ERR_NULL_POINTER; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_LUT_CFG2, RTL8367C_LUT_IPMC_FWD_RPORT_OFFSET, pEnable); -+} -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_meter.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_meter.c -new file mode 100644 -index 000000000000..5412591a8245 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_meter.c -@@ -0,0 +1,305 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Shared meter related functions -+ * -+ */ -+#include -+/* Function Name: -+ * rtl8367c_setAsicShareMeter -+ * Description: -+ * Set meter configuration -+ * Input: -+ * index - hared meter index (0-31) -+ * rate - 17-bits rate of share meter, unit is 8Kpbs -+ * ifg - Including IFG in rate calculation, 1:include 0:exclude -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_FILTER_METER_ID - Invalid meter -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicShareMeter(rtk_uint32 index, rtk_uint32 rate, rtk_uint32 ifg) -+{ -+ ret_t retVal; -+ -+ if(index > RTL8367C_METERMAX) -+ return RT_ERR_FILTER_METER_ID; -+ -+ if(index < 32) -+ { -+ /*19-bits Rate*/ -+ retVal = rtl8367c_setAsicReg(RTL8367C_METER_RATE_REG(index), rate&0xFFFF); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicReg(RTL8367C_METER_RATE_REG(index) + 1, (rate &0x70000) >> 16); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicRegBit(RTL8367C_METER_IFG_CTRL_REG(index), RTL8367C_METER_IFG_OFFSET(index), ifg); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ /*19-bits Rate*/ -+ retVal = rtl8367c_setAsicReg(RTL8367C_REG_METER32_RATE_CTRL0 + ((index-32) << 1), rate&0xFFFF); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicReg(RTL8367C_REG_METER32_RATE_CTRL0 + ((index-32) << 1) + 1, (rate &0x70000) >> 16); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_METER_IFG_CTRL2 + ((index-32) >> 4), RTL8367C_METER_IFG_OFFSET(index), ifg); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicShareMeter -+ * Description: -+ * Get meter configuration -+ * Input: -+ * index - hared meter index (0-31) -+ * pRate - 17-bits rate of share meter, unit is 8Kpbs -+ * pIfg - Including IFG in rate calculation, 1:include 0:exclude -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_FILTER_METER_ID - Invalid meter -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicShareMeter(rtk_uint32 index, rtk_uint32 *pRate, rtk_uint32 *pIfg) -+{ -+ rtk_uint32 regData; -+ rtk_uint32 regData2; -+ ret_t retVal; -+ -+ if(index > RTL8367C_METERMAX) -+ return RT_ERR_FILTER_METER_ID; -+ -+ if(index < 32) -+ { -+ /*17-bits Rate*/ -+ retVal = rtl8367c_getAsicReg(RTL8367C_METER_RATE_REG(index), ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_getAsicReg(RTL8367C_METER_RATE_REG(index) + 1, ®Data2); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *pRate = ((regData2 << 16) & 0x70000) | regData; -+ /*IFG*/ -+ retVal = rtl8367c_getAsicRegBit(RTL8367C_METER_IFG_CTRL_REG(index), RTL8367C_METER_IFG_OFFSET(index), pIfg); -+ -+ return retVal; -+ } -+ else -+ { -+ /*17-bits Rate*/ -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_METER32_RATE_CTRL0 + ((index-32) << 1), ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_METER32_RATE_CTRL0 + ((index-32) << 1) + 1, ®Data2); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *pRate = ((regData2 << 16) & 0x70000) | regData; -+ /*IFG*/ -+ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_METER_IFG_CTRL2 + ((index-32) >> 4), RTL8367C_METER_IFG_OFFSET(index), pIfg); -+ -+ return retVal; -+ } -+} -+/* Function Name: -+ * rtl8367c_setAsicShareMeterBucketSize -+ * Description: -+ * Set meter related leaky bucket threshold -+ * Input: -+ * index - hared meter index (0-31) -+ * lbthreshold - Leaky bucket threshold of meter -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_FILTER_METER_ID - Invalid meter -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicShareMeterBucketSize(rtk_uint32 index, rtk_uint32 lbthreshold) -+{ -+ -+ if(index > RTL8367C_METERMAX) -+ return RT_ERR_FILTER_METER_ID; -+ -+ if(index < 32) -+ return rtl8367c_setAsicReg(RTL8367C_METER_BUCKET_SIZE_REG(index), lbthreshold); -+ else -+ return rtl8367c_setAsicReg(RTL8367C_REG_METER32_BUCKET_SIZE + index - 32, lbthreshold); -+} -+/* Function Name: -+ * rtl8367c_getAsicShareMeterBucketSize -+ * Description: -+ * Get meter related leaky bucket threshold -+ * Input: -+ * index - hared meter index (0-31) -+ * pLbthreshold - Leaky bucket threshold of meter -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_FILTER_METER_ID - Invalid meter -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicShareMeterBucketSize(rtk_uint32 index, rtk_uint32 *pLbthreshold) -+{ -+ if(index > RTL8367C_METERMAX) -+ return RT_ERR_FILTER_METER_ID; -+ -+ if(index < 32) -+ return rtl8367c_getAsicReg(RTL8367C_METER_BUCKET_SIZE_REG(index), pLbthreshold); -+ else -+ return rtl8367c_getAsicReg(RTL8367C_REG_METER32_BUCKET_SIZE + index - 32, pLbthreshold); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicShareMeterType -+ * Description: -+ * Set meter Type -+ * Input: -+ * index - shared meter index (0-31) -+ * Type - 0: kbps, 1: pps -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_FILTER_METER_ID - Invalid meter -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicShareMeterType(rtk_uint32 index, rtk_uint32 type) -+{ -+ rtk_uint32 reg; -+ -+ if(index > RTL8367C_METERMAX) -+ return RT_ERR_FILTER_METER_ID; -+ -+ if(index < 32) -+ reg = RTL8367C_REG_METER_MODE_SETTING0 + (index / 16); -+ else -+ reg = RTL8367C_REG_METER_MODE_SETTING2 + ((index - 32) / 16); -+ return rtl8367c_setAsicRegBit(reg, index % 16, type); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicShareMeterType -+ * Description: -+ * Get meter Type -+ * Input: -+ * index - shared meter index (0-31) -+ * Output: -+ * pType - 0: kbps, 1: pps -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_FILTER_METER_ID - Invalid meter -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicShareMeterType(rtk_uint32 index, rtk_uint32 *pType) -+{ -+ rtk_uint32 reg; -+ -+ if(index > RTL8367C_METERMAX) -+ return RT_ERR_FILTER_METER_ID; -+ -+ if(NULL == pType) -+ return RT_ERR_NULL_POINTER; -+ -+ if(index < 32) -+ reg = RTL8367C_REG_METER_MODE_SETTING0 + (index / 16); -+ else -+ reg = RTL8367C_REG_METER_MODE_SETTING2 + ((index - 32) / 16); -+ return rtl8367c_getAsicRegBit(reg, index % 16, pType); -+} -+ -+ -+/* Function Name: -+ * rtl8367c_setAsicMeterExceedStatus -+ * Description: -+ * Clear shared meter status -+ * Input: -+ * index - hared meter index (0-31) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_FILTER_METER_ID - Invalid meter -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicMeterExceedStatus(rtk_uint32 index) -+{ -+ if(index > RTL8367C_METERMAX) -+ return RT_ERR_FILTER_METER_ID; -+ -+ if(index < 32) -+ return rtl8367c_setAsicRegBit(RTL8367C_METER_OVERRATE_INDICATOR_REG(index), RTL8367C_METER_EXCEED_OFFSET(index), 1); -+ else -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_METER_OVERRATE_INDICATOR2 + ((index - 32) >> 4), RTL8367C_METER_EXCEED_OFFSET(index), 1); -+ -+} -+/* Function Name: -+ * rtl8367c_getAsicMeterExceedStatus -+ * Description: -+ * Get shared meter status -+ * Input: -+ * index - hared meter index (0-31) -+ * pStatus - 0: rate doesn't exceed 1: rate exceeds -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_FILTER_METER_ID - Invalid meter -+ * Note: -+ * If rate is over rate*8Kbps of a meter, the state bit of this meter is set to 1. -+ */ -+ret_t rtl8367c_getAsicMeterExceedStatus(rtk_uint32 index, rtk_uint32* pStatus) -+{ -+ if(index > RTL8367C_METERMAX) -+ return RT_ERR_FILTER_METER_ID; -+ -+ if(index < 32) -+ return rtl8367c_getAsicRegBit(RTL8367C_METER_OVERRATE_INDICATOR_REG(index), RTL8367C_METER_EXCEED_OFFSET(index), pStatus); -+ else -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_METER_OVERRATE_INDICATOR2 + ((index - 32) >> 4), RTL8367C_METER_EXCEED_OFFSET(index), pStatus); -+} -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_mib.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_mib.c -new file mode 100644 -index 000000000000..7da098c49fc9 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_mib.c -@@ -0,0 +1,570 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : MIB related functions -+ * -+ */ -+ -+#include -+/* Function Name: -+ * rtl8367c_setAsicMIBsCounterReset -+ * Description: -+ * Reset global/queue manage or per-port MIB counter -+ * Input: -+ * greset - Global reset -+ * qmreset - Queue management reset -+ * portmask - Port reset mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicMIBsCounterReset(rtk_uint32 greset, rtk_uint32 qmreset, rtk_uint32 portmask) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ rtk_uint32 regBits; -+ -+ regBits = RTL8367C_GLOBAL_RESET_MASK | -+ RTL8367C_QM_RESET_MASK | -+ RTL8367C_MIB_PORT07_MASK | -+ ((rtk_uint32)0x7 << 13); -+ regData = ((greset << RTL8367C_GLOBAL_RESET_OFFSET) & RTL8367C_GLOBAL_RESET_MASK) | -+ ((qmreset << RTL8367C_QM_RESET_OFFSET) & RTL8367C_QM_RESET_MASK) | -+ (((portmask & 0xFF) << RTL8367C_PORT0_RESET_OFFSET) & RTL8367C_MIB_PORT07_MASK) | -+ (((portmask >> 8)&0x7) << 13); -+ -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_MIB_CTRL0, regBits, (regData >> RTL8367C_PORT0_RESET_OFFSET)); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicMIBsCounter -+ * Description: -+ * Get MIBs counter -+ * Input: -+ * port - Physical port number (0~7) -+ * mibIdx - MIB counter index -+ * pCounter - MIB retrieved counter -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_BUSYWAIT_TIMEOUT - MIB is busy at retrieving -+ * RT_ERR_STAT_CNTR_FAIL - MIB is resetting -+ * Note: -+ * Before MIBs counter retrieving, writing accessing address to ASIC at first and check the MIB -+ * control register status. If busy bit of MIB control is set, that means MIB counter have been -+ * waiting for preparing, then software must wait after this busy flag reset by ASIC. This driver -+ * did not recycle reading user desired counter. Software must use driver again to get MIB counter -+ * if return value is not RT_ERR_OK. -+ */ -+ret_t rtl8367c_getAsicMIBsCounter(rtk_uint32 port, RTL8367C_MIBCOUNTER mibIdx, rtk_uint64* pCounter) -+{ -+ ret_t retVal; -+ rtk_uint32 regAddr; -+ rtk_uint32 regData; -+ rtk_uint32 mibAddr; -+ rtk_uint32 mibOff=0; -+ -+ /* address offset to MIBs counter */ -+ CONST rtk_uint16 mibLength[RTL8367C_MIBS_NUMBER]= { -+ 4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, -+ 4,2,2,2,2,2,2,2,2, -+ 4,2,2,2,2,2,2,2,2,2,2,2,2,2,2, -+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}; -+ -+ rtk_uint16 i; -+ rtk_uint64 mibCounter; -+ -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(mibIdx >= RTL8367C_MIBS_NUMBER) -+ return RT_ERR_STAT_INVALID_CNTR; -+ -+ if(dot1dTpLearnedEntryDiscards == mibIdx) -+ { -+ mibAddr = RTL8367C_MIB_LEARNENTRYDISCARD_OFFSET; -+ } -+ else -+ { -+ i = 0; -+ mibOff = RTL8367C_MIB_PORT_OFFSET * port; -+ -+ if(port > 7) -+ mibOff = mibOff + 68; -+ -+ while(i < mibIdx) -+ { -+ mibOff += mibLength[i]; -+ i++; -+ } -+ -+ mibAddr = mibOff; -+ } -+ -+ -+ /*writing access counter address first*/ -+ /*This address is SRAM address, and SRAM address = MIB register address >> 2*/ -+ /*then ASIC will prepare 64bits counter wait for being retrieved*/ -+ /*Write Mib related address to access control register*/ -+ retVal = rtl8367c_setAsicReg(RTL8367C_REG_MIB_ADDRESS, (mibAddr >> 2)); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ -+ -+ /* polling busy flag */ -+ i = 100; -+ while(i > 0) -+ { -+ /*read MIB control register*/ -+ retVal = rtl8367c_getAsicReg(RTL8367C_MIB_CTRL_REG,®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ if((regData & RTL8367C_MIB_CTRL0_BUSY_FLAG_MASK) == 0) -+ { -+ break; -+ } -+ -+ i--; -+ } -+ -+ if(regData & RTL8367C_MIB_CTRL0_BUSY_FLAG_MASK) -+ return RT_ERR_BUSYWAIT_TIMEOUT; -+ -+ if(regData & RTL8367C_RESET_FLAG_MASK) -+ return RT_ERR_STAT_CNTR_FAIL; -+ -+ mibCounter = 0; -+ i = mibLength[mibIdx]; -+ if(4 == i) -+ regAddr = RTL8367C_MIB_COUNTER_BASE_REG + 3; -+ else -+ regAddr = RTL8367C_MIB_COUNTER_BASE_REG + ((mibOff + 1) % 4); -+ -+ while(i) -+ { -+ retVal = rtl8367c_getAsicReg(regAddr, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ mibCounter = (mibCounter << 16) | (regData & 0xFFFF); -+ -+ regAddr --; -+ i --; -+ -+ } -+ -+ *pCounter = mibCounter; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicMIBsLogCounter -+ * Description: -+ * Get MIBs Logging counter -+ * Input: -+ * index - The index of 32 logging counter (0 ~ 31) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_ENTRY_INDEX - Wrong index -+ * RT_ERR_BUSYWAIT_TIMEOUT - MIB is busy at retrieving -+ * RT_ERR_STAT_CNTR_FAIL - MIB is resetting -+ * Note: -+ * This API get 32 logging counter -+ */ -+ret_t rtl8367c_getAsicMIBsLogCounter(rtk_uint32 index, rtk_uint32 *pCounter) -+{ -+ ret_t retVal; -+ rtk_uint32 regAddr; -+ rtk_uint32 regData; -+ rtk_uint32 mibAddr; -+ rtk_uint16 i; -+ rtk_uint64 mibCounter; -+ -+ if(index > RTL8367C_MIB_MAX_LOG_CNT_IDX) -+ return RT_ERR_ENTRY_INDEX; -+ -+ mibAddr = RTL8367C_MIB_LOG_CNT_OFFSET + ((index / 2) * 4); -+ -+ retVal = rtl8367c_setAsicReg(RTL8367C_REG_MIB_ADDRESS, (mibAddr >> 2)); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ /*read MIB control register*/ -+ retVal = rtl8367c_getAsicReg(RTL8367C_MIB_CTRL_REG, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ if(regData & RTL8367C_MIB_CTRL0_BUSY_FLAG_MASK) -+ return RT_ERR_BUSYWAIT_TIMEOUT; -+ -+ if(regData & RTL8367C_RESET_FLAG_MASK) -+ return RT_ERR_STAT_CNTR_FAIL; -+ -+ mibCounter = 0; -+ if((index % 2) == 1) -+ regAddr = RTL8367C_MIB_COUNTER_BASE_REG + 3; -+ else -+ regAddr = RTL8367C_MIB_COUNTER_BASE_REG + 1; -+ -+ for(i = 0; i <= 1; i++) -+ { -+ retVal = rtl8367c_getAsicReg(regAddr, ®Data); -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ mibCounter = (mibCounter << 16) | (regData & 0xFFFF); -+ -+ regAddr --; -+ } -+ -+ *pCounter = mibCounter; -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicMIBsControl -+ * Description: -+ * Get MIB control register -+ * Input: -+ * pMask - MIB control status mask bit[0]-busy bit[1] -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * Software need to check this control register after doing port resetting or global resetting -+ */ -+ret_t rtl8367c_getAsicMIBsControl(rtk_uint32* pMask) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ -+ retVal = rtl8367c_getAsicReg(RTL8367C_MIB_CTRL_REG, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *pMask = regData & (RTL8367C_MIB_CTRL0_BUSY_FLAG_MASK | RTL8367C_RESET_FLAG_MASK); -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicMIBsResetValue -+ * Description: -+ * Reset all counter to 0 or 1 -+ * Input: -+ * value - Reset to value 0 or 1 -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicMIBsResetValue(rtk_uint32 value) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_MIB_CTRL0, RTL8367C_RESET_VALUE_OFFSET, value); -+} -+/* Function Name: -+ * rtl8367c_getAsicMIBsResetValue -+ * Description: -+ * Reset all counter to 0 or 1 -+ * Input: -+ * value - Reset to value 0 or 1 -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicMIBsResetValue(rtk_uint32* value) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_MIB_CTRL0, RTL8367C_RESET_VALUE_OFFSET, value); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicMIBsUsageMode -+ * Description: -+ * MIB update mode -+ * Input: -+ * mode - 1: latch all MIBs by timer 0:normal free run counting -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicMIBsUsageMode(rtk_uint32 mode) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_MIB_CTRL4, RTL8367C_MIB_USAGE_MODE_OFFSET, mode); -+} -+/* Function Name: -+ * rtl8367c_getAsicMIBsUsageMode -+ * Description: -+ * MIB update mode -+ * Input: -+ * pMode - 1: latch all MIBs by timer 0:normal free run counting -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicMIBsUsageMode(rtk_uint32* pMode) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_MIB_CTRL4, RTL8367C_MIB_USAGE_MODE_OFFSET, pMode); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicMIBsTimer -+ * Description: -+ * MIB latching timer -+ * Input: -+ * timer - latch timer, unit 1 second -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicMIBsTimer(rtk_uint32 timer) -+{ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_MIB_CTRL4, RTL8367C_MIB_TIMER_MASK, timer); -+} -+/* Function Name: -+ * rtl8367c_getAsicMIBsTimer -+ * Description: -+ * MIB latching timer -+ * Input: -+ * pTimer - latch timer, unit 1 second -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicMIBsTimer(rtk_uint32* pTimer) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_MIB_CTRL4, RTL8367C_MIB_TIMER_MASK, pTimer); -+} -+/* Function Name: -+ * rtl8367c_setAsicMIBsLoggingMode -+ * Description: -+ * MIB logging counter mode -+ * Input: -+ * index - logging counter mode index (0~15) -+ * mode - 0:32-bits mode 1:64-bits mode -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicMIBsLoggingMode(rtk_uint32 index, rtk_uint32 mode) -+{ -+ if(index > RTL8367C_MIB_MAX_LOG_MODE_IDX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_MIB_CTRL3, index,mode); -+} -+/* Function Name: -+ * rtl8367c_getAsicMIBsLoggingMode -+ * Description: -+ * MIB logging counter mode -+ * Input: -+ * index - logging counter mode index (0~15) -+ * pMode - 0:32-bits mode 1:64-bits mode -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicMIBsLoggingMode(rtk_uint32 index, rtk_uint32* pMode) -+{ -+ if(index > RTL8367C_MIB_MAX_LOG_MODE_IDX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_MIB_CTRL3, index,pMode); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicMIBsLoggingType -+ * Description: -+ * MIB logging counter type -+ * Input: -+ * index - logging counter mode index (0~15) -+ * type - 0:Packet count 1:Byte count -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicMIBsLoggingType(rtk_uint32 index, rtk_uint32 type) -+{ -+ if(index > RTL8367C_MIB_MAX_LOG_MODE_IDX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_MIB_CTRL5, index,type); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicMIBsLoggingType -+ * Description: -+ * MIB logging counter type -+ * Input: -+ * index - logging counter mode index (0~15) -+ * pType - 0:Packet count 1:Byte count -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicMIBsLoggingType(rtk_uint32 index, rtk_uint32* pType) -+{ -+ if(index > RTL8367C_MIB_MAX_LOG_MODE_IDX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_MIB_CTRL5, index,pType); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicMIBsResetLoggingCounter -+ * Description: -+ * MIB logging counter type -+ * Input: -+ * index - logging counter index (0~31) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicMIBsResetLoggingCounter(rtk_uint32 index) -+{ -+ ret_t retVal; -+ -+ if(index > RTL8367C_MIB_MAX_LOG_CNT_IDX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(index < 16) -+ retVal = rtl8367c_setAsicReg(RTL8367C_REG_MIB_CTRL1, 1< -+/* Function Name: -+ * rtl8367c_setAsicPortMirror -+ * Description: -+ * Set port mirror function -+ * Input: -+ * source - Source port -+ * monitor - Monitor (destination) port -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortMirror(rtk_uint32 source, rtk_uint32 monitor) -+{ -+ ret_t retVal; -+ -+ if((source > RTL8367C_PORTIDMAX) || (monitor > RTL8367C_PORTIDMAX)) -+ return RT_ERR_PORT_ID; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_SOURCE_PORT_MASK, source); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_MONITOR_PORT_MASK, monitor); -+} -+/* Function Name: -+ * rtl8367c_getAsicPortMirror -+ * Description: -+ * Get port mirror function -+ * Input: -+ * pSource - Source port -+ * pMonitor - Monitor (destination) port -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortMirror(rtk_uint32 *pSource, rtk_uint32 *pMonitor) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_SOURCE_PORT_MASK, pSource); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_MONITOR_PORT_MASK, pMonitor); -+} -+/* Function Name: -+ * rtl8367c_setAsicPortMirrorRxFunction -+ * Description: -+ * Set the mirror function on RX of the mirrored -+ * Input: -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortMirrorRxFunction(rtk_uint32 enabled) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_RX_OFFSET, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicPortMirrorRxFunction -+ * Description: -+ * Get the mirror function on RX of the mirrored -+ * Input: -+ * pEnabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortMirrorRxFunction(rtk_uint32* pEnabled) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_RX_OFFSET, pEnabled); -+} -+/* Function Name: -+ * rtl8367c_setAsicPortMirrorTxFunction -+ * Description: -+ * Set the mirror function on TX of the mirrored -+ * Input: -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortMirrorTxFunction(rtk_uint32 enabled) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_TX_OFFSET, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicPortMirrorTxFunction -+ * Description: -+ * Get the mirror function on TX of the mirrored -+ * Input: -+ * pEnabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortMirrorTxFunction(rtk_uint32* pEnabled) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_TX_OFFSET, pEnabled); -+} -+/* Function Name: -+ * rtl8367c_setAsicPortMirrorIsolation -+ * Description: -+ * Set the traffic isolation on monitor port -+ * Input: -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortMirrorIsolation(rtk_uint32 enabled) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_ISO_OFFSET, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicPortMirrorIsolation -+ * Description: -+ * Get the traffic isolation on monitor port -+ * Input: -+ * pEnabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortMirrorIsolation(rtk_uint32* pEnabled) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_ISO_OFFSET, pEnabled); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicPortMirrorMask -+ * Description: -+ * Set mirror source port mask -+ * Input: -+ * SourcePortmask - Source Portmask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK- Port Mask Error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortMirrorMask(rtk_uint32 SourcePortmask) -+{ -+ if( SourcePortmask > RTL8367C_PORTMASK) -+ return RT_ERR_PORT_MASK; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_MIRROR_SRC_PMSK, RTL8367C_MIRROR_SRC_PMSK_MASK, SourcePortmask); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicPortMirrorMask -+ * Description: -+ * Get mirror source port mask -+ * Input: -+ * None -+ * Output: -+ * pSourcePortmask - Source Portmask -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK- Port Mask Error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortMirrorMask(rtk_uint32 *pSourcePortmask) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_MIRROR_SRC_PMSK, RTL8367C_MIRROR_SRC_PMSK_MASK, pSourcePortmask); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicPortMirrorVlanRxLeaky -+ * Description: -+ * Set the mirror function of VLAN RX leaky -+ * Input: -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortMirrorVlanRxLeaky(rtk_uint32 enabled) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_RX_VLAN_LEAKY_OFFSET, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicPortMirrorVlanRxLeaky -+ * Description: -+ * Get the mirror function of VLAN RX leaky -+ * Input: -+ * pEnabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortMirrorVlanRxLeaky(rtk_uint32* pEnabled) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_RX_VLAN_LEAKY_OFFSET, pEnabled); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicPortMirrorVlanTxLeaky -+ * Description: -+ * Set the mirror function of VLAN TX leaky -+ * Input: -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortMirrorVlanTxLeaky(rtk_uint32 enabled) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_TX_VLAN_LEAKY_OFFSET, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicPortMirrorVlanTxLeaky -+ * Description: -+ * Get the mirror function of VLAN TX leaky -+ * Input: -+ * pEnabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortMirrorVlanTxLeaky(rtk_uint32* pEnabled) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_TX_VLAN_LEAKY_OFFSET, pEnabled); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicPortMirrorIsolationRxLeaky -+ * Description: -+ * Set the mirror function of Isolation RX leaky -+ * Input: -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortMirrorIsolationRxLeaky(rtk_uint32 enabled) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_RX_ISOLATION_LEAKY_OFFSET, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicPortMirrorIsolationRxLeaky -+ * Description: -+ * Get the mirror function of VLAN RX leaky -+ * Input: -+ * pEnabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortMirrorIsolationRxLeaky(rtk_uint32* pEnabled) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_RX_ISOLATION_LEAKY_OFFSET, pEnabled); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicPortMirrorIsolationTxLeaky -+ * Description: -+ * Set the mirror function of Isolation TX leaky -+ * Input: -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortMirrorIsolationTxLeaky(rtk_uint32 enabled) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_TX_ISOLATION_LEAKY_OFFSET, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicPortMirrorIsolationTxLeaky -+ * Description: -+ * Get the mirror function of VLAN TX leaky -+ * Input: -+ * pEnabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortMirrorIsolationTxLeaky(rtk_uint32* pEnabled) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_TX_ISOLATION_LEAKY_OFFSET, pEnabled); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicPortMirrorRealKeep -+ * Description: -+ * Set the mirror function of keep format -+ * Input: -+ * mode - 1: keep original format, 0: follow VLAN config -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortMirrorRealKeep(rtk_uint32 mode) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_REALKEEP_EN_OFFSET, mode); -+} -+/* Function Name: -+ * rtl8367c_getAsicPortMirrorRealKeep -+ * Description: -+ * Get the mirror function of keep format -+ * Input: -+ * pMode - 1: keep original format, 0: follow VLAN config -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortMirrorRealKeep(rtk_uint32* pMode) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_REALKEEP_EN_OFFSET, pMode); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicPortMirrorOverride -+ * Description: -+ * Set the mirror function of override -+ * Input: -+ * rxMirror - 1: output rx Mirror format, 0: output forward format -+ * txMirror - 1: output tx Mirror format, 0: output forward format -+ * aclMirror - 1: output ACL Mirror format, 0: output forward format -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortMirrorOverride(rtk_uint32 rxMirror, rtk_uint32 txMirror, rtk_uint32 aclMirror) -+{ -+ ret_t retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL3, RTL8367C_MIRROR_RX_OVERRIDE_EN_OFFSET, rxMirror)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL3, RTL8367C_MIRROR_TX_OVERRIDE_EN_OFFSET, txMirror)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL3, RTL8367C_MIRROR_ACL_OVERRIDE_EN_OFFSET, aclMirror)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicPortMirrorOverride -+ * Description: -+ * Get the mirror function of override -+ * Input: -+ * None -+ * Output: -+ * pRxMirror - 1: output rx Mirror format, 0: output forward format -+ * pTxMirror - 1: output tx Mirror format, 0: output forward format -+ * pAclMirror - 1: output ACL Mirror format, 0: output forward format -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortMirrorOverride(rtk_uint32 *pRxMirror, rtk_uint32 *pTxMirror, rtk_uint32 *pAclMirror) -+{ -+ ret_t retVal; -+ -+ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL3, RTL8367C_MIRROR_RX_OVERRIDE_EN_OFFSET, pRxMirror)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL3, RTL8367C_MIRROR_TX_OVERRIDE_EN_OFFSET, pTxMirror)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL3, RTL8367C_MIRROR_ACL_OVERRIDE_EN_OFFSET, pAclMirror)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_misc.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_misc.c -new file mode 100644 -index 000000000000..2189b151c387 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_misc.c -@@ -0,0 +1,268 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Miscellaneous functions -+ * -+ */ -+ -+#include -+/* Function Name: -+ * rtl8367c_setAsicMacAddress -+ * Description: -+ * Set switch MAC address -+ * Input: -+ * mac - switch mac -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicMacAddress(ether_addr_t mac) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ rtk_uint8 *accessPtr; -+ rtk_uint32 i; -+ -+ accessPtr = (rtk_uint8*)&mac; -+ -+ regData = *accessPtr; -+ accessPtr ++; -+ regData = (regData << 8) | *accessPtr; -+ accessPtr ++; -+ for(i = 0; i <=2; i++) -+ { -+ retVal = rtl8367c_setAsicReg(RTL8367C_REG_SWITCH_MAC2 - i, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ regData = *accessPtr; -+ accessPtr ++; -+ regData = (regData << 8) | *accessPtr; -+ accessPtr ++; -+ } -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicMacAddress -+ * Description: -+ * Get switch MAC address -+ * Input: -+ * pMac - switch mac -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicMacAddress(ether_addr_t *pMac) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ rtk_uint8 *accessPtr; -+ rtk_uint32 i; -+ -+ -+ accessPtr = (rtk_uint8*)pMac; -+ -+ for(i = 0; i <= 2; i++) -+ { -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_SWITCH_MAC2 - i, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *accessPtr = (regData & 0xFF00) >> 8; -+ accessPtr ++; -+ *accessPtr = regData & 0xFF; -+ accessPtr ++; -+ } -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicDebugInfo -+ * Description: -+ * Get per-port packet forward debugging information -+ * Input: -+ * port - Physical port number (0~7) -+ * pDebugifo - per-port packet trap/drop/forward reason -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicDebugInfo(rtk_uint32 port, rtk_uint32 *pDebugifo) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_DEBUG_INFO_REG(port), RTL8367C_DEBUG_INFO_MASK(port), pDebugifo); -+} -+/* Function Name: -+ * rtl8367c_setAsicPortJamMode -+ * Description: -+ * Set half duplex flow control setting -+ * Input: -+ * mode - 0: Back-Pressure 1: DEFER -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortJamMode(rtk_uint32 mode) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_CFG_BACKPRESSURE, RTL8367C_LONGTXE_OFFSET,mode); -+} -+/* Function Name: -+ * rtl8367c_getAsicPortJamMode -+ * Description: -+ * Get half duplex flow control setting -+ * Input: -+ * pMode - 0: Back-Pressure 1: DEFER -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortJamMode(rtk_uint32* pMode) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_CFG_BACKPRESSURE, RTL8367C_LONGTXE_OFFSET, pMode); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicMaxLengthCfg -+ * Description: -+ * Set Max packet length configuration -+ * Input: -+ * cfgId - Configuration ID -+ * maxLength - Max Length -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicMaxLengthCfg(rtk_uint32 cfgId, rtk_uint32 maxLength) -+{ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_MAX_LEN_RX_TX_CFG0 + cfgId, RTL8367C_MAX_LEN_RX_TX_CFG0_MASK, maxLength); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicMaxLengthCfg -+ * Description: -+ * Get Max packet length configuration -+ * Input: -+ * cfgId - Configuration ID -+ * maxLength - Max Length -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicMaxLengthCfg(rtk_uint32 cfgId, rtk_uint32 *pMaxLength) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_MAX_LEN_RX_TX_CFG0 + cfgId, RTL8367C_MAX_LEN_RX_TX_CFG0_MASK, pMaxLength); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicMaxLength -+ * Description: -+ * Set Max packet length -+ * Input: -+ * port - port ID -+ * type - 0: 10M/100M speed, 1: giga speed -+ * cfgId - Configuration ID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicMaxLength(rtk_uint32 port, rtk_uint32 type, rtk_uint32 cfgId) -+{ -+ ret_t retVal; -+ -+ if(port < 8) -+ { -+ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MAX_LENGTH_CFG, (type * 8) + port, cfgId); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MAX_LENGTH_CFG_EXT, (type * 3) + port - 8, cfgId); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicMaxLength -+ * Description: -+ * Get Max packet length -+ * Input: -+ * port - port ID -+ * type - 0: 10M/100M speed, 1: giga speed -+ * cfgId - Configuration ID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicMaxLength(rtk_uint32 port, rtk_uint32 type, rtk_uint32 *pCfgId) -+{ -+ ret_t retVal; -+ -+ if(port < 8) -+ { -+ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_MAX_LENGTH_CFG, (type * 8) + port, pCfgId); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_MAX_LENGTH_CFG_EXT, (type * 3) + port - 8, pCfgId); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ return RT_ERR_OK; -+} -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_oam.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_oam.c -new file mode 100644 -index 000000000000..1556f4500d40 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_oam.c -@@ -0,0 +1,194 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 42321 $ -+ * $Date: 2013-08-26 13:51:29 +0800 (週一, 26 八月 2013) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : OAM related functions -+ * -+ */ -+ -+#include -+/* Function Name: -+ * rtl8367c_setAsicOamParser -+ * Description: -+ * Set OAM parser state -+ * Input: -+ * port - Physical port number (0~7) -+ * parser - Per-Port OAM parser state -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_NOT_ALLOWED - Invalid paser state -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicOamParser(rtk_uint32 port, rtk_uint32 parser) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ if(parser > OAM_PARFWDCPU) -+ return RT_ERR_NOT_ALLOWED; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_OAM_PARSER_CTRL0 + port/8, RTL8367C_OAM_PARSER_MASK(port % 8), parser); -+} -+/* Function Name: -+ * rtl8367c_getAsicOamParser -+ * Description: -+ * Get OAM parser state -+ * Input: -+ * port - Physical port number (0~7) -+ * pParser - Per-Port OAM parser state -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicOamParser(rtk_uint32 port, rtk_uint32* pParser) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_OAM_PARSER_CTRL0 + port/8, RTL8367C_OAM_PARSER_MASK(port%8), pParser); -+} -+/* Function Name: -+ * rtl8367c_setAsicOamMultiplexer -+ * Description: -+ * Set OAM multiplexer state -+ * Input: -+ * port - Physical port number (0~7) -+ * multiplexer - Per-Port OAM multiplexer state -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_NOT_ALLOWED - Invalid multiplexer state -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicOamMultiplexer(rtk_uint32 port, rtk_uint32 multiplexer) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ if(multiplexer > OAM_MULCPU) -+ return RT_ERR_NOT_ALLOWED; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_OAM_MULTIPLEXER_CTRL0 + port/8, RTL8367C_OAM_MULTIPLEXER_MASK(port%8), multiplexer); -+} -+/* Function Name: -+ * rtl8367c_getAsicOamMultiplexer -+ * Description: -+ * Get OAM multiplexer state -+ * Input: -+ * port - Physical port number (0~7) -+ * pMultiplexer - Per-Port OAM multiplexer state -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicOamMultiplexer(rtk_uint32 port, rtk_uint32* pMultiplexer) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_OAM_MULTIPLEXER_CTRL0 + port/8, RTL8367C_OAM_MULTIPLEXER_MASK(port%8), pMultiplexer); -+} -+/* Function Name: -+ * rtl8367c_setAsicOamCpuPri -+ * Description: -+ * Set trap priority for OAM packet -+ * Input: -+ * priority - priority (0~7) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicOamCpuPri(rtk_uint32 priority) -+{ -+ if(priority > RTL8367C_PRIMAX) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_QOS_TRAP_PRIORITY0, RTL8367C_OAM_PRIOIRTY_MASK, priority); -+} -+/* Function Name: -+ * rtl8367c_getAsicOamCpuPri -+ * Description: -+ * Get trap priority for OAM packet -+ * Input: -+ * pPriority - priority (0~7) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicOamCpuPri(rtk_uint32 *pPriority) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_QOS_TRAP_PRIORITY0, RTL8367C_OAM_PRIOIRTY_MASK, pPriority); -+} -+/* Function Name: -+ * rtl8367c_setAsicOamEnable -+ * Description: -+ * Set OAM function state -+ * Input: -+ * enabled - OAM function usage 1:enable, 0:disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicOamEnable(rtk_uint32 enabled) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_OAM_CTRL, RTL8367C_OAM_CTRL_OFFSET, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicOamEnable -+ * Description: -+ * Get OAM function state -+ * Input: -+ * pEnabled - OAM function usage 1:enable, 0:disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicOamEnable(rtk_uint32 *pEnabled) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_OAM_CTRL, RTL8367C_OAM_CTRL_OFFSET, pEnabled); -+} -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_phy.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_phy.c -new file mode 100644 -index 000000000000..fb4db113a987 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_phy.c -@@ -0,0 +1,394 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : PHY related functions -+ * -+ */ -+#include -+ -+#if defined(MDC_MDIO_OPERATION) -+/* Function Name: -+ * rtl8367c_setAsicPHYOCPReg -+ * Description: -+ * Set PHY OCP registers -+ * Input: -+ * phyNo - Physical port number (0~7) -+ * ocpAddr - OCP address -+ * ocpData - Writing data -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PHY_REG_ID - invalid PHY address -+ * RT_ERR_PHY_ID - invalid PHY no -+ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPHYOCPReg(rtk_uint32 phyNo, rtk_uint32 ocpAddr, rtk_uint32 ocpData ) -+{ -+ ret_t retVal; -+ rtk_uint32 regAddr; -+ rtk_uint32 ocpAddrPrefix, ocpAddr9_6, ocpAddr5_1; -+ -+ /* OCP prefix */ -+ ocpAddrPrefix = ((ocpAddr & 0xFC00) >> 10); -+ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_GPHY_OCP_MSB_0, RTL8367C_CFG_CPU_OCPADR_MSB_MASK, ocpAddrPrefix)) != RT_ERR_OK) -+ return retVal; -+ -+ /*prepare access address*/ -+ ocpAddr9_6 = ((ocpAddr >> 6) & 0x000F); -+ ocpAddr5_1 = ((ocpAddr >> 1) & 0x001F); -+ regAddr = RTL8367C_PHY_BASE | (ocpAddr9_6 << 8) | (phyNo << RTL8367C_PHY_OFFSET) | ocpAddr5_1; -+ if((retVal = rtl8367c_setAsicReg(regAddr, ocpData)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicPHYOCPReg -+ * Description: -+ * Get PHY OCP registers -+ * Input: -+ * phyNo - Physical port number (0~7) -+ * ocpAddr - PHY address -+ * pRegData - read data -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PHY_REG_ID - invalid PHY address -+ * RT_ERR_PHY_ID - invalid PHY no -+ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPHYOCPReg(rtk_uint32 phyNo, rtk_uint32 ocpAddr, rtk_uint32 *pRegData ) -+{ -+ ret_t retVal; -+ rtk_uint32 regAddr; -+ rtk_uint32 ocpAddrPrefix, ocpAddr9_6, ocpAddr5_1; -+ /* OCP prefix */ -+ ocpAddrPrefix = ((ocpAddr & 0xFC00) >> 10); -+ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_GPHY_OCP_MSB_0, RTL8367C_CFG_CPU_OCPADR_MSB_MASK, ocpAddrPrefix)) != RT_ERR_OK) -+ return retVal; -+ -+ /*prepare access address*/ -+ ocpAddr9_6 = ((ocpAddr >> 6) & 0x000F); -+ ocpAddr5_1 = ((ocpAddr >> 1) & 0x001F); -+ regAddr = RTL8367C_PHY_BASE | (ocpAddr9_6 << 8) | (phyNo << RTL8367C_PHY_OFFSET) | ocpAddr5_1; -+ if((retVal = rtl8367c_getAsicReg(regAddr, pRegData)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+#else -+ -+/* Function Name: -+ * rtl8367c_setAsicPHYOCPReg -+ * Description: -+ * Set PHY OCP registers -+ * Input: -+ * phyNo - Physical port number (0~7) -+ * ocpAddr - OCP address -+ * ocpData - Writing data -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PHY_REG_ID - invalid PHY address -+ * RT_ERR_PHY_ID - invalid PHY no -+ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPHYOCPReg(rtk_uint32 phyNo, rtk_uint32 ocpAddr, rtk_uint32 ocpData ) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ rtk_uint32 busyFlag, checkCounter; -+ rtk_uint32 ocpAddrPrefix, ocpAddr9_6, ocpAddr5_1; -+ -+ /*Check internal phy access busy or not*/ -+ /*retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_INDRECT_ACCESS_STATUS, RTL8367C_INDRECT_ACCESS_STATUS_OFFSET,&busyFlag);*/ -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_STATUS,&busyFlag); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ if(busyFlag) -+ return RT_ERR_BUSYWAIT_TIMEOUT; -+ -+ /* OCP prefix */ -+ ocpAddrPrefix = ((ocpAddr & 0xFC00) >> 10); -+ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_GPHY_OCP_MSB_0, RTL8367C_CFG_CPU_OCPADR_MSB_MASK, ocpAddrPrefix)) != RT_ERR_OK) -+ return retVal; -+ -+ /*prepare access data*/ -+ retVal = rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_WRITE_DATA, ocpData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ /*prepare access address*/ -+ ocpAddr9_6 = ((ocpAddr >> 6) & 0x000F); -+ ocpAddr5_1 = ((ocpAddr >> 1) & 0x001F); -+ regData = RTL8367C_PHY_BASE | (ocpAddr9_6 << 8) | (phyNo << RTL8367C_PHY_OFFSET) | ocpAddr5_1; -+ retVal = rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_ADDRESS, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ /*Set WRITE Command*/ -+ retVal = rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_CTRL, RTL8367C_CMD_MASK | RTL8367C_RW_MASK); -+ -+ checkCounter = 100; -+ while(checkCounter) -+ { -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_STATUS,&busyFlag); -+ if((retVal != RT_ERR_OK) || busyFlag) -+ { -+ checkCounter --; -+ if(0 == checkCounter) -+ return RT_ERR_BUSYWAIT_TIMEOUT; -+ } -+ else -+ { -+ checkCounter = 0; -+ } -+ } -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicPHYOCPReg -+ * Description: -+ * Get PHY OCP registers -+ * Input: -+ * phyNo - Physical port number (0~7) -+ * ocpAddr - PHY address -+ * pRegData - read data -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PHY_REG_ID - invalid PHY address -+ * RT_ERR_PHY_ID - invalid PHY no -+ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPHYOCPReg(rtk_uint32 phyNo, rtk_uint32 ocpAddr, rtk_uint32 *pRegData ) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ rtk_uint32 busyFlag,checkCounter; -+ rtk_uint32 ocpAddrPrefix, ocpAddr9_6, ocpAddr5_1; -+ /*Check internal phy access busy or not*/ -+ /*retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_INDRECT_ACCESS_STATUS, RTL8367C_INDRECT_ACCESS_STATUS_OFFSET,&busyFlag);*/ -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_STATUS,&busyFlag); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ if(busyFlag) -+ return RT_ERR_BUSYWAIT_TIMEOUT; -+ -+ /* OCP prefix */ -+ ocpAddrPrefix = ((ocpAddr & 0xFC00) >> 10); -+ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_GPHY_OCP_MSB_0, RTL8367C_CFG_CPU_OCPADR_MSB_MASK, ocpAddrPrefix)) != RT_ERR_OK) -+ return retVal; -+ -+ /*prepare access address*/ -+ ocpAddr9_6 = ((ocpAddr >> 6) & 0x000F); -+ ocpAddr5_1 = ((ocpAddr >> 1) & 0x001F); -+ regData = RTL8367C_PHY_BASE | (ocpAddr9_6 << 8) | (phyNo << RTL8367C_PHY_OFFSET) | ocpAddr5_1; -+ retVal = rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_ADDRESS, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ /*Set READ Command*/ -+ retVal = rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_CTRL, RTL8367C_CMD_MASK ); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ checkCounter = 100; -+ while(checkCounter) -+ { -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_STATUS,&busyFlag); -+ if((retVal != RT_ERR_OK) || busyFlag) -+ { -+ checkCounter --; -+ if(0 == checkCounter) -+ return RT_ERR_FAILED; -+ } -+ else -+ { -+ checkCounter = 0; -+ } -+ } -+ -+ /*get PHY register*/ -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_READ_DATA, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *pRegData = regData; -+ -+ return RT_ERR_OK; -+} -+ -+#endif -+ -+/* Function Name: -+ * rtl8367c_setAsicPHYReg -+ * Description: -+ * Set PHY registers -+ * Input: -+ * phyNo - Physical port number (0~7) -+ * phyAddr - PHY address (0~31) -+ * phyData - Writing data -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PHY_REG_ID - invalid PHY address -+ * RT_ERR_PHY_ID - invalid PHY no -+ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPHYReg(rtk_uint32 phyNo, rtk_uint32 phyAddr, rtk_uint32 phyData ) -+{ -+ rtk_uint32 ocp_addr; -+ -+ if(phyAddr > RTL8367C_PHY_REGNOMAX) -+ return RT_ERR_PHY_REG_ID; -+ -+ ocp_addr = 0xa400 + phyAddr*2; -+ -+ return rtl8367c_setAsicPHYOCPReg(phyNo, ocp_addr, phyData); -+} -+/* Function Name: -+ * rtl8367c_getAsicPHYReg -+ * Description: -+ * Get PHY registers -+ * Input: -+ * phyNo - Physical port number (0~7) -+ * phyAddr - PHY address (0~31) -+ * pRegData - Writing data -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PHY_REG_ID - invalid PHY address -+ * RT_ERR_PHY_ID - invalid PHY no -+ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPHYReg(rtk_uint32 phyNo, rtk_uint32 phyAddr, rtk_uint32 *pRegData ) -+{ -+ rtk_uint32 ocp_addr; -+ -+ if(phyAddr > RTL8367C_PHY_REGNOMAX) -+ return RT_ERR_PHY_REG_ID; -+ -+ ocp_addr = 0xa400 + phyAddr*2; -+ -+ return rtl8367c_getAsicPHYOCPReg(phyNo, ocp_addr, pRegData); -+} -+ -+ -+/* Function Name: -+ * rtl8367c_setAsicSdsReg -+ * Description: -+ * Set Serdes registers -+ * Input: -+ * sdsId - sdsid (0~1) -+ * sdsReg - reg address (0~31) -+ * sdsPage - Writing data -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ -+ * Note: -+ * None -+ */ -+ -+ret_t rtl8367c_setAsicSdsReg(rtk_uint32 sdsId, rtk_uint32 sdsReg, rtk_uint32 sdsPage, rtk_uint32 value) -+{ -+ rtk_uint32 retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, value)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (sdsPage<<5) | sdsReg)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0|sdsId)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+ -+} -+ -+/* Function Name: -+ * rtl8367c_getAiscSdsReg -+ * Description: -+ * Get Serdes registers -+ * Input: -+ * sdsId - sdsid (0~1) -+ * sdsReg - reg address (0~31) -+ * sdsPage - Writing data -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicSdsReg(rtk_uint32 sdsId, rtk_uint32 sdsReg, rtk_uint32 sdsPage, rtk_uint32 *value) -+{ -+ rtk_uint32 retVal, busy; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (sdsPage<<5) | sdsReg)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x0080|sdsId)) != RT_ERR_OK) -+ return retVal; -+ -+ while(1) -+ { -+ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_SDS_INDACS_CMD, &busy))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((busy & 0x100) == 0) -+ break; -+ } -+ -+ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_SDS_INDACS_DATA, value))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+ -+ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_port.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_port.c -new file mode 100644 -index 000000000000..fae046639d78 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_port.c -@@ -0,0 +1,5752 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76333 $ -+ * $Date: 2017-03-09 09:33:15 +0800 (週四, 09 三月 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Port security related functions -+ * -+ */ -+ -+#include -+ -+#include -+ -+ -+#define FIBER2_AUTO_INIT_SIZE 2038 -+rtk_uint8 Fiber2_Auto[FIBER2_AUTO_INIT_SIZE] = { -+0x02,0x05,0x8F,0xE4,0xF5,0xA8,0xD2,0xAF, -+0x22,0x00,0x00,0x02,0x07,0x2C,0xC5,0xF0, -+0xF8,0xA3,0xE0,0x28,0xF0,0xC5,0xF0,0xF8, -+0xE5,0x82,0x15,0x82,0x70,0x02,0x15,0x83, -+0xE0,0x38,0xF0,0x22,0x75,0xF0,0x08,0x75, -+0x82,0x00,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, -+0xCD,0x33,0xCD,0xCC,0x33,0xCC,0xC5,0x82, -+0x33,0xC5,0x82,0x9B,0xED,0x9A,0xEC,0x99, -+0xE5,0x82,0x98,0x40,0x0C,0xF5,0x82,0xEE, -+0x9B,0xFE,0xED,0x9A,0xFD,0xEC,0x99,0xFC, -+0x0F,0xD5,0xF0,0xD6,0xE4,0xCE,0xFB,0xE4, -+0xCD,0xFA,0xE4,0xCC,0xF9,0xA8,0x82,0x22, -+0xB8,0x00,0xC1,0xB9,0x00,0x59,0xBA,0x00, -+0x2D,0xEC,0x8B,0xF0,0x84,0xCF,0xCE,0xCD, -+0xFC,0xE5,0xF0,0xCB,0xF9,0x78,0x18,0xEF, -+0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33,0xFD, -+0xEC,0x33,0xFC,0xEB,0x33,0xFB,0x10,0xD7, -+0x03,0x99,0x40,0x04,0xEB,0x99,0xFB,0x0F, -+0xD8,0xE5,0xE4,0xF9,0xFA,0x22,0x78,0x18, -+0xEF,0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33, -+0xFD,0xEC,0x33,0xFC,0xC9,0x33,0xC9,0x10, -+0xD7,0x05,0x9B,0xE9,0x9A,0x40,0x07,0xEC, -+0x9B,0xFC,0xE9,0x9A,0xF9,0x0F,0xD8,0xE0, -+0xE4,0xC9,0xFA,0xE4,0xCC,0xFB,0x22,0x75, -+0xF0,0x10,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, -+0xED,0x33,0xFD,0xCC,0x33,0xCC,0xC8,0x33, -+0xC8,0x10,0xD7,0x07,0x9B,0xEC,0x9A,0xE8, -+0x99,0x40,0x0A,0xED,0x9B,0xFD,0xEC,0x9A, -+0xFC,0xE8,0x99,0xF8,0x0F,0xD5,0xF0,0xDA, -+0xE4,0xCD,0xFB,0xE4,0xCC,0xFA,0xE4,0xC8, -+0xF9,0x22,0xEB,0x9F,0xF5,0xF0,0xEA,0x9E, -+0x42,0xF0,0xE9,0x9D,0x42,0xF0,0xE8,0x9C, -+0x45,0xF0,0x22,0xE0,0xFC,0xA3,0xE0,0xFD, -+0xA3,0xE0,0xFE,0xA3,0xE0,0xFF,0x22,0xE0, -+0xF8,0xA3,0xE0,0xF9,0xA3,0xE0,0xFA,0xA3, -+0xE0,0xFB,0x22,0xEC,0xF0,0xA3,0xED,0xF0, -+0xA3,0xEE,0xF0,0xA3,0xEF,0xF0,0x22,0x7D, -+0xD7,0x7C,0x04,0x7F,0x02,0x7E,0x66,0x12, -+0x07,0xAB,0x7D,0x80,0x7C,0x04,0x7F,0x01, -+0x7E,0x66,0x12,0x07,0xAB,0x7D,0xC0,0x7C, -+0x00,0x7F,0x00,0x7E,0x66,0x12,0x07,0xAB, -+0x7D,0x94,0x7C,0xF9,0x7F,0x02,0x7E,0x66, -+0x12,0x07,0xAB,0x7D,0x81,0x7C,0x04,0x7F, -+0x01,0x7E,0x66,0x12,0x07,0xAB,0x7D,0xC0, -+0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12,0x07, -+0xAB,0x7D,0xA2,0x7C,0x31,0x7F,0x02,0x7E, -+0x66,0x12,0x07,0xAB,0x7D,0x82,0x7C,0x04, -+0x7F,0x01,0x7E,0x66,0x12,0x07,0xAB,0x7D, -+0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12, -+0x07,0xAB,0x7D,0x60,0x7C,0x69,0x7F,0x02, -+0x7E,0x66,0x12,0x07,0xAB,0x7D,0x83,0x7C, -+0x04,0x7F,0x01,0x7E,0x66,0x12,0x07,0xAB, -+0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66, -+0x12,0x07,0xAB,0x7D,0x28,0x7C,0x97,0x7F, -+0x02,0x7E,0x66,0x12,0x07,0xAB,0x7D,0x84, -+0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12,0x07, -+0xAB,0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E, -+0x66,0x12,0x07,0xAB,0x7D,0x85,0x7C,0x9D, -+0x7F,0x02,0x7E,0x66,0x12,0x07,0xAB,0x7D, -+0x23,0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12, -+0x07,0xAB,0x7D,0xC0,0x7C,0x00,0x7F,0x00, -+0x7E,0x66,0x12,0x07,0xAB,0x7D,0x10,0x7C, -+0xD8,0x7F,0x02,0x7E,0x66,0x12,0x07,0xAB, -+0x7D,0x24,0x7C,0x04,0x7F,0x01,0x7E,0x66, -+0x12,0x07,0xAB,0x7D,0xC0,0x7C,0x00,0x7F, -+0x00,0x7E,0x66,0x12,0x07,0xAB,0x7D,0x00, -+0x7C,0x04,0x7F,0x02,0x7E,0x66,0x12,0x07, -+0xAB,0x7D,0x2F,0x7C,0x00,0x7F,0x01,0x7E, -+0x66,0x12,0x07,0xAB,0x7D,0xC0,0x7C,0x00, -+0x7F,0x00,0x7E,0x66,0x02,0x07,0xAB,0x7D, -+0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, -+0x07,0xAB,0x7D,0x80,0x7C,0x00,0x7F,0x00, -+0x7E,0x66,0x12,0x07,0xAB,0x7F,0x02,0x7E, -+0x66,0x12,0x07,0x66,0xEF,0x44,0x40,0xFD, -+0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,0x07, -+0xAB,0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E, -+0x66,0x12,0x07,0xAB,0x7D,0xC0,0x7C,0x00, -+0x7F,0x00,0x7E,0x66,0x12,0x07,0xAB,0x7D, -+0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, -+0x07,0xAB,0x7D,0x80,0x7C,0x00,0x7F,0x00, -+0x7E,0x66,0x12,0x07,0xAB,0x7F,0x02,0x7E, -+0x66,0x12,0x07,0x66,0xEF,0x54,0xBF,0xFD, -+0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,0x07, -+0xAB,0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E, -+0x66,0x12,0x07,0xAB,0x7D,0xC0,0x7C,0x00, -+0x7F,0x00,0x7E,0x66,0x12,0x07,0xAB,0xE4, -+0xFD,0xFC,0x7F,0x01,0x7E,0x66,0x12,0x07, -+0xAB,0x7D,0x80,0x7C,0x00,0x7F,0x00,0x7E, -+0x66,0x12,0x07,0xAB,0x7F,0x02,0x7E,0x66, -+0x12,0x07,0x66,0xEF,0x54,0xFD,0x54,0xFE, -+0xFD,0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12, -+0x07,0xAB,0xE4,0xFD,0xFC,0x7F,0x01,0x7E, -+0x66,0x12,0x07,0xAB,0x7D,0xC0,0x7C,0x00, -+0x7F,0x00,0x7E,0x66,0x12,0x07,0xAB,0xE4, -+0xFD,0xFC,0x7F,0x01,0x7E,0x66,0x12,0x07, -+0xAB,0x7D,0x80,0x7C,0x00,0x7F,0x00,0x7E, -+0x66,0x12,0x07,0xAB,0x7F,0x02,0x7E,0x66, -+0x12,0x07,0x66,0xEF,0x44,0x02,0x44,0x01, -+0xFD,0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12, -+0x07,0xAB,0xE4,0xFD,0xFC,0x7F,0x01,0x7E, -+0x66,0x12,0x07,0xAB,0x7D,0xC0,0x7C,0x00, -+0x7F,0x00,0x7E,0x66,0x02,0x07,0xAB,0xE4, -+0x90,0x06,0x2C,0xF0,0xFD,0x7C,0x01,0x7F, -+0x3F,0x7E,0x1D,0x12,0x07,0xAB,0x7D,0x40, -+0x7C,0x00,0x7F,0x36,0x7E,0x13,0x12,0x07, -+0xAB,0xE4,0xFF,0xFE,0xFD,0x80,0x25,0xE4, -+0x7F,0xFF,0x7E,0xFF,0xFD,0xFC,0x90,0x06, -+0x24,0x12,0x01,0x0F,0xC3,0x12,0x00,0xF2, -+0x50,0x1B,0x90,0x06,0x24,0x12,0x01,0x03, -+0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE,0xE4, -+0x3D,0xFD,0xE4,0x3C,0xFC,0x90,0x06,0x24, -+0x12,0x01,0x1B,0x80,0xD2,0xE4,0xF5,0xA8, -+0xD2,0xAF,0x7D,0x1F,0xFC,0x7F,0x49,0x7E, -+0x13,0x12,0x07,0xAB,0x12,0x07,0xDB,0x12, -+0x01,0x27,0x12,0x06,0x1B,0x12,0x07,0x8A, -+0x12,0x06,0xEA,0x7D,0x41,0x7C,0x00,0x7F, -+0x36,0x7E,0x13,0x12,0x07,0xAB,0xE4,0xFF, -+0xFE,0xFD,0x80,0x26,0x7F,0xFF,0x7E,0xFF, -+0x7D,0x05,0x7C,0x00,0x90,0x06,0x24,0x12, -+0x01,0x0F,0xC3,0x12,0x00,0xF2,0x50,0x1B, -+0x90,0x06,0x24,0x12,0x01,0x03,0xEF,0x24, -+0x01,0xFF,0xE4,0x3E,0xFE,0xE4,0x3D,0xFD, -+0xE4,0x3C,0xFC,0x90,0x06,0x24,0x12,0x01, -+0x1B,0x80,0xD1,0xC2,0x00,0xC2,0x01,0xD2, -+0xA9,0xD2,0x8C,0x7F,0x01,0x7E,0x62,0x12, -+0x07,0x66,0xEF,0x30,0xE2,0x07,0xE4,0x90, -+0x06,0x2C,0xF0,0x80,0xEE,0x90,0x06,0x2C, -+0xE0,0x70,0x12,0x12,0x04,0xF0,0x90,0x06, -+0x2C,0x74,0x01,0xF0,0xE4,0x90,0x06,0x33, -+0xF0,0xA3,0xF0,0x80,0xD6,0xC3,0x90,0x06, -+0x34,0xE0,0x94,0x62,0x90,0x06,0x33,0xE0, -+0x94,0x00,0x40,0xC7,0xE4,0xF0,0xA3,0xF0, -+0x12,0x04,0xF0,0x90,0x06,0x2C,0x74,0x01, -+0xF0,0x80,0xB8,0x75,0x0F,0x80,0x75,0x0E, -+0x7E,0x75,0x0D,0xAA,0x75,0x0C,0x83,0xE4, -+0xF5,0x10,0x7F,0x36,0x7E,0x13,0x12,0x07, -+0x66,0xEE,0xC4,0xF8,0x54,0xF0,0xC8,0xEF, -+0xC4,0x54,0x0F,0x48,0x54,0x07,0xFB,0x7A, -+0x00,0xEA,0x70,0x4A,0xEB,0x14,0x60,0x1C, -+0x14,0x60,0x27,0x24,0xFE,0x60,0x31,0x14, -+0x60,0x3C,0x24,0x05,0x70,0x38,0x75,0x0B, -+0x00,0x75,0x0A,0xC2,0x75,0x09,0xEB,0x75, -+0x08,0x0B,0x80,0x36,0x75,0x0B,0x40,0x75, -+0x0A,0x59,0x75,0x09,0x73,0x75,0x08,0x07, -+0x80,0x28,0x75,0x0B,0x00,0x75,0x0A,0xE1, -+0x75,0x09,0xF5,0x75,0x08,0x05,0x80,0x1A, -+0x75,0x0B,0xA0,0x75,0x0A,0xAC,0x75,0x09, -+0xB9,0x75,0x08,0x03,0x80,0x0C,0x75,0x0B, -+0x00,0x75,0x0A,0x62,0x75,0x09,0x3D,0x75, -+0x08,0x01,0x75,0x89,0x11,0xE4,0x7B,0x60, -+0x7A,0x09,0xF9,0xF8,0xAF,0x0B,0xAE,0x0A, -+0xAD,0x09,0xAC,0x08,0x12,0x00,0x60,0xAA, -+0x06,0xAB,0x07,0xC3,0xE4,0x9B,0xFB,0xE4, -+0x9A,0xFA,0x78,0x17,0xF6,0xAF,0x03,0xEF, -+0x08,0xF6,0x18,0xE6,0xF5,0x8C,0x08,0xE6, -+0xF5,0x8A,0x74,0x0D,0x2B,0xFB,0xE4,0x3A, -+0x18,0xF6,0xAF,0x03,0xEF,0x08,0xF6,0x75, -+0x88,0x10,0x53,0x8E,0xC7,0xD2,0xA9,0x22, -+0x7F,0x10,0x7E,0x13,0x12,0x07,0x66,0x90, -+0x06,0x2D,0xEE,0xF0,0xA3,0xEF,0xF0,0xEE, -+0x44,0x10,0xFE,0x90,0x06,0x2D,0xF0,0xA3, -+0xEF,0xF0,0x54,0xEF,0xFF,0x90,0x06,0x2D, -+0xEE,0xF0,0xFC,0xA3,0xEF,0xF0,0xFD,0x7F, -+0x10,0x7E,0x13,0x12,0x07,0xAB,0xE4,0xFF, -+0xFE,0x0F,0xBF,0x00,0x01,0x0E,0xEF,0x64, -+0x64,0x4E,0x70,0xF5,0x7D,0x04,0x7C,0x00, -+0x7F,0x02,0x7E,0x66,0x12,0x07,0xAB,0x7D, -+0x00,0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12, -+0x07,0xAB,0x7D,0xC0,0x7C,0x00,0x7F,0x00, -+0x7E,0x66,0x12,0x07,0xAB,0xE4,0xFD,0xFC, -+0x7F,0x02,0x7E,0x66,0x12,0x07,0xAB,0x7D, -+0x00,0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12, -+0x07,0xAB,0x7D,0xC0,0x7C,0x00,0x7F,0x00, -+0x7E,0x66,0x12,0x07,0xAB,0x7F,0x10,0x7E, -+0x13,0x12,0x07,0x66,0x90,0x06,0x2D,0xEE, -+0xF0,0xA3,0xEF,0xF0,0xEE,0x54,0xEF,0x90, -+0x06,0x2D,0xF0,0xFC,0xA3,0xEF,0xF0,0xFD, -+0x7F,0x10,0x7E,0x13,0x02,0x07,0xAB,0x78, -+0x7F,0xE4,0xF6,0xD8,0xFD,0x75,0x81,0x3C, -+0x02,0x05,0xD6,0x02,0x03,0x2F,0xE4,0x93, -+0xA3,0xF8,0xE4,0x93,0xA3,0x40,0x03,0xF6, -+0x80,0x01,0xF2,0x08,0xDF,0xF4,0x80,0x29, -+0xE4,0x93,0xA3,0xF8,0x54,0x07,0x24,0x0C, -+0xC8,0xC3,0x33,0xC4,0x54,0x0F,0x44,0x20, -+0xC8,0x83,0x40,0x04,0xF4,0x56,0x80,0x01, -+0x46,0xF6,0xDF,0xE4,0x80,0x0B,0x01,0x02, -+0x04,0x08,0x10,0x20,0x40,0x80,0x90,0x07, -+0xE7,0xE4,0x7E,0x01,0x93,0x60,0xBC,0xA3, -+0xFF,0x54,0x3F,0x30,0xE5,0x09,0x54,0x1F, -+0xFE,0xE4,0x93,0xA3,0x60,0x01,0x0E,0xCF, -+0x54,0xC0,0x25,0xE0,0x60,0xA8,0x40,0xB8, -+0xE4,0x93,0xA3,0xFA,0xE4,0x93,0xA3,0xF8, -+0xE4,0x93,0xA3,0xC8,0xC5,0x82,0xC8,0xCA, -+0xC5,0x83,0xCA,0xF0,0xA3,0xC8,0xC5,0x82, -+0xC8,0xCA,0xC5,0x83,0xCA,0xDF,0xE9,0xDE, -+0xE7,0x80,0xBE,0x7D,0x40,0x7C,0x17,0x7F, -+0x11,0x7E,0x1D,0x12,0x07,0xAB,0x7F,0x41, -+0x7E,0x1D,0x12,0x07,0x66,0xEF,0x44,0x20, -+0x44,0x80,0xFD,0xAC,0x06,0x7F,0x41,0x7E, -+0x1D,0x12,0x07,0xAB,0x7D,0xBB,0x7C,0x15, -+0x7F,0xEB,0x7E,0x13,0x12,0x07,0xAB,0x7D, -+0x07,0x7C,0x00,0x7F,0xE7,0x7E,0x13,0x12, -+0x07,0xAB,0x7D,0x40,0x7C,0x11,0x7F,0x00, -+0x7E,0x62,0x12,0x07,0xAB,0x02,0x02,0x2F, -+0x7D,0xC0,0x7C,0x16,0x7F,0x11,0x7E,0x1D, -+0x12,0x07,0xAB,0x7D,0xBB,0x7C,0x15,0x7F, -+0xEB,0x7E,0x13,0x12,0x07,0xAB,0x7D,0x0D, -+0x7C,0x00,0x7F,0xE7,0x7E,0x13,0x12,0x07, -+0xAB,0x7F,0x41,0x7E,0x1D,0x12,0x07,0x66, -+0xEF,0x44,0x20,0x44,0x80,0xFD,0xAC,0x06, -+0x7F,0x41,0x7E,0x1D,0x12,0x07,0xAB,0x7D, -+0x00,0x7C,0x21,0x7F,0x00,0x7E,0x62,0x12, -+0x07,0xAB,0x02,0x02,0x2F,0x7D,0x40,0x7C, -+0x17,0x7F,0x11,0x7E,0x1D,0x12,0x07,0xAB, -+0x7D,0xBB,0x7C,0x15,0x7F,0xEB,0x7E,0x13, -+0x12,0x07,0xAB,0x7D,0x0C,0x7C,0x00,0x7F, -+0xE7,0x7E,0x13,0x12,0x07,0xAB,0x7F,0x41, -+0x7E,0x1D,0x12,0x07,0x66,0xEF,0x44,0x20, -+0x44,0x80,0xFD,0xAC,0x06,0x7F,0x41,0x7E, -+0x1D,0x12,0x07,0xAB,0x7D,0x40,0x7C,0x11, -+0x7F,0x00,0x7E,0x62,0x12,0x07,0xAB,0x02, -+0x02,0x2F,0x7D,0x04,0x7C,0x00,0x7F,0x01, -+0x7E,0x66,0x12,0x07,0xAB,0x7D,0x80,0x7C, -+0x00,0x7F,0x00,0x7E,0x66,0x12,0x07,0xAB, -+0x7F,0x02,0x7E,0x66,0x12,0x07,0x66,0xEF, -+0x44,0x02,0x44,0x04,0xFD,0xAC,0x06,0x7F, -+0x02,0x7E,0x66,0x12,0x07,0xAB,0x7D,0x04, -+0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12,0x07, -+0xAB,0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E, -+0x66,0x02,0x07,0xAB,0xC0,0xE0,0xC0,0xF0, -+0xC0,0x83,0xC0,0x82,0xC0,0xD0,0x75,0xD0, -+0x00,0xC0,0x00,0x78,0x17,0xE6,0xF5,0x8C, -+0x78,0x18,0xE6,0xF5,0x8A,0x90,0x06,0x31, -+0xE4,0x75,0xF0,0x01,0x12,0x00,0x0E,0x90, -+0x06,0x33,0xE4,0x75,0xF0,0x01,0x12,0x00, -+0x0E,0xD0,0x00,0xD0,0xD0,0xD0,0x82,0xD0, -+0x83,0xD0,0xF0,0xD0,0xE0,0x32,0xC2,0xAF, -+0xAD,0x07,0xAC,0x06,0x8C,0xA2,0x8D,0xA3, -+0x75,0xA0,0x01,0x00,0x00,0x00,0x00,0x00, -+0x00,0x00,0x00,0x00,0x00,0x00,0xAE,0xA1, -+0xBE,0x00,0xF0,0xAE,0xA6,0xAF,0xA7,0xD2, -+0xAF,0x22,0x7D,0x20,0x7C,0x0F,0x7F,0x02, -+0x7E,0x66,0x12,0x07,0xAB,0x7D,0x01,0x7C, -+0x00,0x7F,0x01,0x7E,0x66,0x12,0x07,0xAB, -+0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66, -+0x02,0x07,0xAB,0xC2,0xAF,0xAB,0x07,0xAA, -+0x06,0x8A,0xA2,0x8B,0xA3,0x8C,0xA4,0x8D, -+0xA5,0x75,0xA0,0x03,0x00,0x00,0x00,0xAA, -+0xA1,0xBA,0x00,0xF8,0xD2,0xAF,0x22,0x7F, -+0x0C,0x7E,0x13,0x12,0x07,0x66,0xEF,0x44, -+0x50,0xFD,0xAC,0x06,0x7F,0x0C,0x7E,0x13, -+0x02,0x07,0xAB,0x12,0x07,0xC7,0x12,0x07, -+0xF2,0x12,0x04,0x2B,0x02,0x00,0x03,0x42, -+0x06,0x33,0x00,0x00,0x42,0x06,0x31,0x00, -+0x00,0x00,0xE4,0xF5,0x8E,0x22,}; -+ -+#define FIBER2_1G_INIT_SIZE 2032 -+rtk_uint8 Fiber2_1G[FIBER2_1G_INIT_SIZE] = { -+0x02,0x05,0x89,0xE4,0xF5,0xA8,0xD2,0xAF, -+0x22,0x00,0x00,0x02,0x07,0x26,0xC5,0xF0, -+0xF8,0xA3,0xE0,0x28,0xF0,0xC5,0xF0,0xF8, -+0xE5,0x82,0x15,0x82,0x70,0x02,0x15,0x83, -+0xE0,0x38,0xF0,0x22,0x75,0xF0,0x08,0x75, -+0x82,0x00,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, -+0xCD,0x33,0xCD,0xCC,0x33,0xCC,0xC5,0x82, -+0x33,0xC5,0x82,0x9B,0xED,0x9A,0xEC,0x99, -+0xE5,0x82,0x98,0x40,0x0C,0xF5,0x82,0xEE, -+0x9B,0xFE,0xED,0x9A,0xFD,0xEC,0x99,0xFC, -+0x0F,0xD5,0xF0,0xD6,0xE4,0xCE,0xFB,0xE4, -+0xCD,0xFA,0xE4,0xCC,0xF9,0xA8,0x82,0x22, -+0xB8,0x00,0xC1,0xB9,0x00,0x59,0xBA,0x00, -+0x2D,0xEC,0x8B,0xF0,0x84,0xCF,0xCE,0xCD, -+0xFC,0xE5,0xF0,0xCB,0xF9,0x78,0x18,0xEF, -+0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33,0xFD, -+0xEC,0x33,0xFC,0xEB,0x33,0xFB,0x10,0xD7, -+0x03,0x99,0x40,0x04,0xEB,0x99,0xFB,0x0F, -+0xD8,0xE5,0xE4,0xF9,0xFA,0x22,0x78,0x18, -+0xEF,0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33, -+0xFD,0xEC,0x33,0xFC,0xC9,0x33,0xC9,0x10, -+0xD7,0x05,0x9B,0xE9,0x9A,0x40,0x07,0xEC, -+0x9B,0xFC,0xE9,0x9A,0xF9,0x0F,0xD8,0xE0, -+0xE4,0xC9,0xFA,0xE4,0xCC,0xFB,0x22,0x75, -+0xF0,0x10,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, -+0xED,0x33,0xFD,0xCC,0x33,0xCC,0xC8,0x33, -+0xC8,0x10,0xD7,0x07,0x9B,0xEC,0x9A,0xE8, -+0x99,0x40,0x0A,0xED,0x9B,0xFD,0xEC,0x9A, -+0xFC,0xE8,0x99,0xF8,0x0F,0xD5,0xF0,0xDA, -+0xE4,0xCD,0xFB,0xE4,0xCC,0xFA,0xE4,0xC8, -+0xF9,0x22,0xEB,0x9F,0xF5,0xF0,0xEA,0x9E, -+0x42,0xF0,0xE9,0x9D,0x42,0xF0,0xE8,0x9C, -+0x45,0xF0,0x22,0xE0,0xFC,0xA3,0xE0,0xFD, -+0xA3,0xE0,0xFE,0xA3,0xE0,0xFF,0x22,0xE0, -+0xF8,0xA3,0xE0,0xF9,0xA3,0xE0,0xFA,0xA3, -+0xE0,0xFB,0x22,0xEC,0xF0,0xA3,0xED,0xF0, -+0xA3,0xEE,0xF0,0xA3,0xEF,0xF0,0x22,0x7D, -+0xD7,0x7C,0x04,0x7F,0x02,0x7E,0x66,0x12, -+0x07,0xA5,0x7D,0x80,0x7C,0x04,0x7F,0x01, -+0x7E,0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C, -+0x00,0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5, -+0x7D,0x94,0x7C,0xF9,0x7F,0x02,0x7E,0x66, -+0x12,0x07,0xA5,0x7D,0x81,0x7C,0x04,0x7F, -+0x01,0x7E,0x66,0x12,0x07,0xA5,0x7D,0xC0, -+0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12,0x07, -+0xA5,0x7D,0xA2,0x7C,0x31,0x7F,0x02,0x7E, -+0x66,0x12,0x07,0xA5,0x7D,0x82,0x7C,0x04, -+0x7F,0x01,0x7E,0x66,0x12,0x07,0xA5,0x7D, -+0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12, -+0x07,0xA5,0x7D,0x60,0x7C,0x69,0x7F,0x02, -+0x7E,0x66,0x12,0x07,0xA5,0x7D,0x83,0x7C, -+0x04,0x7F,0x01,0x7E,0x66,0x12,0x07,0xA5, -+0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66, -+0x12,0x07,0xA5,0x7D,0x28,0x7C,0x97,0x7F, -+0x02,0x7E,0x66,0x12,0x07,0xA5,0x7D,0x84, -+0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12,0x07, -+0xA5,0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E, -+0x66,0x12,0x07,0xA5,0x7D,0x85,0x7C,0x9D, -+0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5,0x7D, -+0x23,0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12, -+0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F,0x00, -+0x7E,0x66,0x12,0x07,0xA5,0x7D,0x10,0x7C, -+0xD8,0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5, -+0x7D,0x24,0x7C,0x04,0x7F,0x01,0x7E,0x66, -+0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F, -+0x00,0x7E,0x66,0x12,0x07,0xA5,0x7D,0x00, -+0x7C,0x04,0x7F,0x02,0x7E,0x66,0x12,0x07, -+0xA5,0x7D,0x2F,0x7C,0x00,0x7F,0x01,0x7E, -+0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, -+0x7F,0x00,0x7E,0x66,0x02,0x07,0xA5,0x7D, -+0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, -+0x07,0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00, -+0x7E,0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E, -+0x66,0x12,0x07,0x60,0xEF,0x44,0x40,0xFD, -+0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,0x07, -+0xA5,0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E, -+0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, -+0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0x7D, -+0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, -+0x07,0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00, -+0x7E,0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E, -+0x66,0x12,0x07,0x60,0xEF,0x54,0xBF,0xFD, -+0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,0x07, -+0xA5,0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E, -+0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, -+0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0xE4, -+0xFD,0xFC,0x7F,0x01,0x7E,0x66,0x12,0x07, -+0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00,0x7E, -+0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E,0x66, -+0x12,0x07,0x60,0xEF,0x54,0xFD,0x54,0xFE, -+0xFD,0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12, -+0x07,0xA5,0xE4,0xFD,0xFC,0x7F,0x01,0x7E, -+0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, -+0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0xE4, -+0xFD,0xFC,0x7F,0x01,0x7E,0x66,0x12,0x07, -+0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00,0x7E, -+0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E,0x66, -+0x12,0x07,0x60,0xEF,0x44,0x02,0x44,0x01, -+0xFD,0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12, -+0x07,0xA5,0xE4,0xFD,0xFC,0x7F,0x01,0x7E, -+0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, -+0x7F,0x00,0x7E,0x66,0x02,0x07,0xA5,0xE4, -+0x90,0x06,0x2C,0xF0,0xFD,0x7C,0x01,0x7F, -+0x3F,0x7E,0x1D,0x12,0x07,0xA5,0x7D,0x40, -+0x7C,0x00,0x7F,0x36,0x7E,0x13,0x12,0x07, -+0xA5,0xE4,0xFF,0xFE,0xFD,0x80,0x25,0xE4, -+0x7F,0xFF,0x7E,0xFF,0xFD,0xFC,0x90,0x06, -+0x24,0x12,0x01,0x0F,0xC3,0x12,0x00,0xF2, -+0x50,0x1B,0x90,0x06,0x24,0x12,0x01,0x03, -+0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE,0xE4, -+0x3D,0xFD,0xE4,0x3C,0xFC,0x90,0x06,0x24, -+0x12,0x01,0x1B,0x80,0xD2,0xE4,0xF5,0xA8, -+0xD2,0xAF,0x7D,0x1F,0xFC,0x7F,0x49,0x7E, -+0x13,0x12,0x07,0xA5,0x12,0x07,0xD5,0x12, -+0x01,0x27,0x12,0x06,0x9F,0x7D,0x41,0x7C, -+0x00,0x7F,0x36,0x7E,0x13,0x12,0x07,0xA5, -+0xE4,0xFF,0xFE,0xFD,0x80,0x26,0x7F,0xFF, -+0x7E,0xFF,0x7D,0x05,0x7C,0x00,0x90,0x06, -+0x24,0x12,0x01,0x0F,0xC3,0x12,0x00,0xF2, -+0x50,0x1B,0x90,0x06,0x24,0x12,0x01,0x03, -+0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE,0xE4, -+0x3D,0xFD,0xE4,0x3C,0xFC,0x90,0x06,0x24, -+0x12,0x01,0x1B,0x80,0xD1,0xC2,0x00,0xC2, -+0x01,0xD2,0xA9,0xD2,0x8C,0x7F,0x01,0x7E, -+0x62,0x12,0x07,0x60,0xEF,0x30,0xE2,0x07, -+0xE4,0x90,0x06,0x2C,0xF0,0x80,0xEE,0x90, -+0x06,0x2C,0xE0,0x70,0x12,0x12,0x04,0xEA, -+0x90,0x06,0x2C,0x74,0x01,0xF0,0xE4,0x90, -+0x06,0x33,0xF0,0xA3,0xF0,0x80,0xD6,0xC3, -+0x90,0x06,0x34,0xE0,0x94,0x62,0x90,0x06, -+0x33,0xE0,0x94,0x00,0x40,0xC7,0xE4,0xF0, -+0xA3,0xF0,0x12,0x04,0xEA,0x90,0x06,0x2C, -+0x74,0x01,0xF0,0x80,0xB8,0x75,0x0F,0x80, -+0x75,0x0E,0x7E,0x75,0x0D,0xAA,0x75,0x0C, -+0x83,0xE4,0xF5,0x10,0x7F,0x36,0x7E,0x13, -+0x12,0x07,0x60,0xEE,0xC4,0xF8,0x54,0xF0, -+0xC8,0xEF,0xC4,0x54,0x0F,0x48,0x54,0x07, -+0xFB,0x7A,0x00,0xEA,0x70,0x4A,0xEB,0x14, -+0x60,0x1C,0x14,0x60,0x27,0x24,0xFE,0x60, -+0x31,0x14,0x60,0x3C,0x24,0x05,0x70,0x38, -+0x75,0x0B,0x00,0x75,0x0A,0xC2,0x75,0x09, -+0xEB,0x75,0x08,0x0B,0x80,0x36,0x75,0x0B, -+0x40,0x75,0x0A,0x59,0x75,0x09,0x73,0x75, -+0x08,0x07,0x80,0x28,0x75,0x0B,0x00,0x75, -+0x0A,0xE1,0x75,0x09,0xF5,0x75,0x08,0x05, -+0x80,0x1A,0x75,0x0B,0xA0,0x75,0x0A,0xAC, -+0x75,0x09,0xB9,0x75,0x08,0x03,0x80,0x0C, -+0x75,0x0B,0x00,0x75,0x0A,0x62,0x75,0x09, -+0x3D,0x75,0x08,0x01,0x75,0x89,0x11,0xE4, -+0x7B,0x60,0x7A,0x09,0xF9,0xF8,0xAF,0x0B, -+0xAE,0x0A,0xAD,0x09,0xAC,0x08,0x12,0x00, -+0x60,0xAA,0x06,0xAB,0x07,0xC3,0xE4,0x9B, -+0xFB,0xE4,0x9A,0xFA,0x78,0x17,0xF6,0xAF, -+0x03,0xEF,0x08,0xF6,0x18,0xE6,0xF5,0x8C, -+0x08,0xE6,0xF5,0x8A,0x74,0x0D,0x2B,0xFB, -+0xE4,0x3A,0x18,0xF6,0xAF,0x03,0xEF,0x08, -+0xF6,0x75,0x88,0x10,0x53,0x8E,0xC7,0xD2, -+0xA9,0x22,0x7F,0x10,0x7E,0x13,0x12,0x07, -+0x60,0x90,0x06,0x2D,0xEE,0xF0,0xA3,0xEF, -+0xF0,0xEE,0x44,0x10,0xFE,0x90,0x06,0x2D, -+0xF0,0xA3,0xEF,0xF0,0x54,0xEF,0xFF,0x90, -+0x06,0x2D,0xEE,0xF0,0xFC,0xA3,0xEF,0xF0, -+0xFD,0x7F,0x10,0x7E,0x13,0x12,0x07,0xA5, -+0xE4,0xFF,0xFE,0x0F,0xBF,0x00,0x01,0x0E, -+0xEF,0x64,0x64,0x4E,0x70,0xF5,0x7D,0x04, -+0x7C,0x00,0x7F,0x02,0x7E,0x66,0x12,0x07, -+0xA5,0x7D,0x00,0x7C,0x04,0x7F,0x01,0x7E, -+0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, -+0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0xE4, -+0xFD,0xFC,0x7F,0x02,0x7E,0x66,0x12,0x07, -+0xA5,0x7D,0x00,0x7C,0x04,0x7F,0x01,0x7E, -+0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, -+0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0x7F, -+0x10,0x7E,0x13,0x12,0x07,0x60,0x90,0x06, -+0x2D,0xEE,0xF0,0xA3,0xEF,0xF0,0xEE,0x54, -+0xEF,0x90,0x06,0x2D,0xF0,0xFC,0xA3,0xEF, -+0xF0,0xFD,0x7F,0x10,0x7E,0x13,0x02,0x07, -+0xA5,0x78,0x7F,0xE4,0xF6,0xD8,0xFD,0x75, -+0x81,0x3C,0x02,0x05,0xD0,0x02,0x03,0x2F, -+0xE4,0x93,0xA3,0xF8,0xE4,0x93,0xA3,0x40, -+0x03,0xF6,0x80,0x01,0xF2,0x08,0xDF,0xF4, -+0x80,0x29,0xE4,0x93,0xA3,0xF8,0x54,0x07, -+0x24,0x0C,0xC8,0xC3,0x33,0xC4,0x54,0x0F, -+0x44,0x20,0xC8,0x83,0x40,0x04,0xF4,0x56, -+0x80,0x01,0x46,0xF6,0xDF,0xE4,0x80,0x0B, -+0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80, -+0x90,0x07,0xE1,0xE4,0x7E,0x01,0x93,0x60, -+0xBC,0xA3,0xFF,0x54,0x3F,0x30,0xE5,0x09, -+0x54,0x1F,0xFE,0xE4,0x93,0xA3,0x60,0x01, -+0x0E,0xCF,0x54,0xC0,0x25,0xE0,0x60,0xA8, -+0x40,0xB8,0xE4,0x93,0xA3,0xFA,0xE4,0x93, -+0xA3,0xF8,0xE4,0x93,0xA3,0xC8,0xC5,0x82, -+0xC8,0xCA,0xC5,0x83,0xCA,0xF0,0xA3,0xC8, -+0xC5,0x82,0xC8,0xCA,0xC5,0x83,0xCA,0xDF, -+0xE9,0xDE,0xE7,0x80,0xBE,0x7D,0x40,0x7C, -+0x17,0x7F,0x11,0x7E,0x1D,0x12,0x07,0xA5, -+0x7F,0x41,0x7E,0x1D,0x12,0x07,0x60,0xEF, -+0x44,0x20,0x44,0x80,0xFD,0xAC,0x06,0x7F, -+0x41,0x7E,0x1D,0x12,0x07,0xA5,0x7D,0xBB, -+0x7C,0x15,0x7F,0xEB,0x7E,0x13,0x12,0x07, -+0xA5,0x7D,0x07,0x7C,0x00,0x7F,0xE7,0x7E, -+0x13,0x12,0x07,0xA5,0x7D,0x40,0x7C,0x11, -+0x7F,0x00,0x7E,0x62,0x12,0x07,0xA5,0x02, -+0x02,0x2F,0x7D,0xC0,0x7C,0x16,0x7F,0x11, -+0x7E,0x1D,0x12,0x07,0xA5,0x7D,0xBB,0x7C, -+0x15,0x7F,0xEB,0x7E,0x13,0x12,0x07,0xA5, -+0x7D,0x0D,0x7C,0x00,0x7F,0xE7,0x7E,0x13, -+0x12,0x07,0xA5,0x7F,0x41,0x7E,0x1D,0x12, -+0x07,0x60,0xEF,0x44,0x20,0x44,0x80,0xFD, -+0xAC,0x06,0x7F,0x41,0x7E,0x1D,0x12,0x07, -+0xA5,0x7D,0x00,0x7C,0x21,0x7F,0x00,0x7E, -+0x62,0x12,0x07,0xA5,0x02,0x02,0x2F,0x7D, -+0x40,0x7C,0x17,0x7F,0x11,0x7E,0x1D,0x12, -+0x07,0xA5,0x7D,0xBB,0x7C,0x15,0x7F,0xEB, -+0x7E,0x13,0x12,0x07,0xA5,0x7D,0x0C,0x7C, -+0x00,0x7F,0xE7,0x7E,0x13,0x12,0x07,0xA5, -+0x7F,0x41,0x7E,0x1D,0x12,0x07,0x60,0xEF, -+0x44,0x20,0x44,0x80,0xFD,0xAC,0x06,0x7F, -+0x41,0x7E,0x1D,0x12,0x07,0xA5,0x7D,0x40, -+0x7C,0x11,0x7F,0x00,0x7E,0x62,0x12,0x07, -+0xA5,0x02,0x02,0x2F,0x7D,0x04,0x7C,0x00, -+0x7F,0x01,0x7E,0x66,0x12,0x07,0xA5,0x7D, -+0x80,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12, -+0x07,0xA5,0x7F,0x02,0x7E,0x66,0x12,0x07, -+0x60,0xEF,0x44,0x02,0x44,0x04,0xFD,0xAC, -+0x06,0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5, -+0x7D,0x04,0x7C,0x00,0x7F,0x01,0x7E,0x66, -+0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F, -+0x00,0x7E,0x66,0x02,0x07,0xA5,0xC0,0xE0, -+0xC0,0xF0,0xC0,0x83,0xC0,0x82,0xC0,0xD0, -+0x75,0xD0,0x00,0xC0,0x00,0x78,0x17,0xE6, -+0xF5,0x8C,0x78,0x18,0xE6,0xF5,0x8A,0x90, -+0x06,0x31,0xE4,0x75,0xF0,0x01,0x12,0x00, -+0x0E,0x90,0x06,0x33,0xE4,0x75,0xF0,0x01, -+0x12,0x00,0x0E,0xD0,0x00,0xD0,0xD0,0xD0, -+0x82,0xD0,0x83,0xD0,0xF0,0xD0,0xE0,0x32, -+0xC2,0xAF,0xAD,0x07,0xAC,0x06,0x8C,0xA2, -+0x8D,0xA3,0x75,0xA0,0x01,0x00,0x00,0x00, -+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -+0xAE,0xA1,0xBE,0x00,0xF0,0xAE,0xA6,0xAF, -+0xA7,0xD2,0xAF,0x22,0x7D,0x20,0x7C,0x0F, -+0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5,0x7D, -+0x01,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, -+0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F,0x00, -+0x7E,0x66,0x02,0x07,0xA5,0xC2,0xAF,0xAB, -+0x07,0xAA,0x06,0x8A,0xA2,0x8B,0xA3,0x8C, -+0xA4,0x8D,0xA5,0x75,0xA0,0x03,0x00,0x00, -+0x00,0xAA,0xA1,0xBA,0x00,0xF8,0xD2,0xAF, -+0x22,0x7F,0x0C,0x7E,0x13,0x12,0x07,0x60, -+0xEF,0x44,0x50,0xFD,0xAC,0x06,0x7F,0x0C, -+0x7E,0x13,0x02,0x07,0xA5,0x12,0x07,0xC1, -+0x12,0x07,0xEC,0x12,0x04,0x25,0x02,0x00, -+0x03,0x42,0x06,0x33,0x00,0x00,0x42,0x06, -+0x31,0x00,0x00,0x00,0xE4,0xF5,0x8E,0x22,}; -+ -+#define FIBER2_100M_INIT_SIZE 2032 -+rtk_uint8 Fiber2_100M[FIBER2_100M_INIT_SIZE] = { -+0x02,0x05,0x89,0xE4,0xF5,0xA8,0xD2,0xAF, -+0x22,0x00,0x00,0x02,0x07,0x26,0xC5,0xF0, -+0xF8,0xA3,0xE0,0x28,0xF0,0xC5,0xF0,0xF8, -+0xE5,0x82,0x15,0x82,0x70,0x02,0x15,0x83, -+0xE0,0x38,0xF0,0x22,0x75,0xF0,0x08,0x75, -+0x82,0x00,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, -+0xCD,0x33,0xCD,0xCC,0x33,0xCC,0xC5,0x82, -+0x33,0xC5,0x82,0x9B,0xED,0x9A,0xEC,0x99, -+0xE5,0x82,0x98,0x40,0x0C,0xF5,0x82,0xEE, -+0x9B,0xFE,0xED,0x9A,0xFD,0xEC,0x99,0xFC, -+0x0F,0xD5,0xF0,0xD6,0xE4,0xCE,0xFB,0xE4, -+0xCD,0xFA,0xE4,0xCC,0xF9,0xA8,0x82,0x22, -+0xB8,0x00,0xC1,0xB9,0x00,0x59,0xBA,0x00, -+0x2D,0xEC,0x8B,0xF0,0x84,0xCF,0xCE,0xCD, -+0xFC,0xE5,0xF0,0xCB,0xF9,0x78,0x18,0xEF, -+0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33,0xFD, -+0xEC,0x33,0xFC,0xEB,0x33,0xFB,0x10,0xD7, -+0x03,0x99,0x40,0x04,0xEB,0x99,0xFB,0x0F, -+0xD8,0xE5,0xE4,0xF9,0xFA,0x22,0x78,0x18, -+0xEF,0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33, -+0xFD,0xEC,0x33,0xFC,0xC9,0x33,0xC9,0x10, -+0xD7,0x05,0x9B,0xE9,0x9A,0x40,0x07,0xEC, -+0x9B,0xFC,0xE9,0x9A,0xF9,0x0F,0xD8,0xE0, -+0xE4,0xC9,0xFA,0xE4,0xCC,0xFB,0x22,0x75, -+0xF0,0x10,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, -+0xED,0x33,0xFD,0xCC,0x33,0xCC,0xC8,0x33, -+0xC8,0x10,0xD7,0x07,0x9B,0xEC,0x9A,0xE8, -+0x99,0x40,0x0A,0xED,0x9B,0xFD,0xEC,0x9A, -+0xFC,0xE8,0x99,0xF8,0x0F,0xD5,0xF0,0xDA, -+0xE4,0xCD,0xFB,0xE4,0xCC,0xFA,0xE4,0xC8, -+0xF9,0x22,0xEB,0x9F,0xF5,0xF0,0xEA,0x9E, -+0x42,0xF0,0xE9,0x9D,0x42,0xF0,0xE8,0x9C, -+0x45,0xF0,0x22,0xE0,0xFC,0xA3,0xE0,0xFD, -+0xA3,0xE0,0xFE,0xA3,0xE0,0xFF,0x22,0xE0, -+0xF8,0xA3,0xE0,0xF9,0xA3,0xE0,0xFA,0xA3, -+0xE0,0xFB,0x22,0xEC,0xF0,0xA3,0xED,0xF0, -+0xA3,0xEE,0xF0,0xA3,0xEF,0xF0,0x22,0x7D, -+0xD7,0x7C,0x04,0x7F,0x02,0x7E,0x66,0x12, -+0x07,0xA5,0x7D,0x80,0x7C,0x04,0x7F,0x01, -+0x7E,0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C, -+0x00,0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5, -+0x7D,0x94,0x7C,0xF9,0x7F,0x02,0x7E,0x66, -+0x12,0x07,0xA5,0x7D,0x81,0x7C,0x04,0x7F, -+0x01,0x7E,0x66,0x12,0x07,0xA5,0x7D,0xC0, -+0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12,0x07, -+0xA5,0x7D,0xA2,0x7C,0x31,0x7F,0x02,0x7E, -+0x66,0x12,0x07,0xA5,0x7D,0x82,0x7C,0x04, -+0x7F,0x01,0x7E,0x66,0x12,0x07,0xA5,0x7D, -+0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12, -+0x07,0xA5,0x7D,0x60,0x7C,0x69,0x7F,0x02, -+0x7E,0x66,0x12,0x07,0xA5,0x7D,0x83,0x7C, -+0x04,0x7F,0x01,0x7E,0x66,0x12,0x07,0xA5, -+0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66, -+0x12,0x07,0xA5,0x7D,0x28,0x7C,0x97,0x7F, -+0x02,0x7E,0x66,0x12,0x07,0xA5,0x7D,0x84, -+0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12,0x07, -+0xA5,0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E, -+0x66,0x12,0x07,0xA5,0x7D,0x85,0x7C,0x9D, -+0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5,0x7D, -+0x23,0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12, -+0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F,0x00, -+0x7E,0x66,0x12,0x07,0xA5,0x7D,0x10,0x7C, -+0xD8,0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5, -+0x7D,0x24,0x7C,0x04,0x7F,0x01,0x7E,0x66, -+0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F, -+0x00,0x7E,0x66,0x12,0x07,0xA5,0x7D,0x00, -+0x7C,0x04,0x7F,0x02,0x7E,0x66,0x12,0x07, -+0xA5,0x7D,0x2F,0x7C,0x00,0x7F,0x01,0x7E, -+0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, -+0x7F,0x00,0x7E,0x66,0x02,0x07,0xA5,0x7D, -+0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, -+0x07,0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00, -+0x7E,0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E, -+0x66,0x12,0x07,0x60,0xEF,0x44,0x40,0xFD, -+0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,0x07, -+0xA5,0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E, -+0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, -+0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0x7D, -+0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, -+0x07,0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00, -+0x7E,0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E, -+0x66,0x12,0x07,0x60,0xEF,0x54,0xBF,0xFD, -+0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,0x07, -+0xA5,0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E, -+0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, -+0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0xE4, -+0xFD,0xFC,0x7F,0x01,0x7E,0x66,0x12,0x07, -+0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00,0x7E, -+0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E,0x66, -+0x12,0x07,0x60,0xEF,0x54,0xFD,0x54,0xFE, -+0xFD,0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12, -+0x07,0xA5,0xE4,0xFD,0xFC,0x7F,0x01,0x7E, -+0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, -+0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0xE4, -+0xFD,0xFC,0x7F,0x01,0x7E,0x66,0x12,0x07, -+0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00,0x7E, -+0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E,0x66, -+0x12,0x07,0x60,0xEF,0x44,0x02,0x44,0x01, -+0xFD,0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12, -+0x07,0xA5,0xE4,0xFD,0xFC,0x7F,0x01,0x7E, -+0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, -+0x7F,0x00,0x7E,0x66,0x02,0x07,0xA5,0xE4, -+0x90,0x06,0x2C,0xF0,0xFD,0x7C,0x01,0x7F, -+0x3F,0x7E,0x1D,0x12,0x07,0xA5,0x7D,0x40, -+0x7C,0x00,0x7F,0x36,0x7E,0x13,0x12,0x07, -+0xA5,0xE4,0xFF,0xFE,0xFD,0x80,0x25,0xE4, -+0x7F,0xFF,0x7E,0xFF,0xFD,0xFC,0x90,0x06, -+0x24,0x12,0x01,0x0F,0xC3,0x12,0x00,0xF2, -+0x50,0x1B,0x90,0x06,0x24,0x12,0x01,0x03, -+0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE,0xE4, -+0x3D,0xFD,0xE4,0x3C,0xFC,0x90,0x06,0x24, -+0x12,0x01,0x1B,0x80,0xD2,0xE4,0xF5,0xA8, -+0xD2,0xAF,0x7D,0x1F,0xFC,0x7F,0x49,0x7E, -+0x13,0x12,0x07,0xA5,0x12,0x07,0xD5,0x12, -+0x01,0x27,0x12,0x06,0x5A,0x7D,0x41,0x7C, -+0x00,0x7F,0x36,0x7E,0x13,0x12,0x07,0xA5, -+0xE4,0xFF,0xFE,0xFD,0x80,0x26,0x7F,0xFF, -+0x7E,0xFF,0x7D,0x05,0x7C,0x00,0x90,0x06, -+0x24,0x12,0x01,0x0F,0xC3,0x12,0x00,0xF2, -+0x50,0x1B,0x90,0x06,0x24,0x12,0x01,0x03, -+0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE,0xE4, -+0x3D,0xFD,0xE4,0x3C,0xFC,0x90,0x06,0x24, -+0x12,0x01,0x1B,0x80,0xD1,0xC2,0x00,0xC2, -+0x01,0xD2,0xA9,0xD2,0x8C,0x7F,0x01,0x7E, -+0x62,0x12,0x07,0x60,0xEF,0x30,0xE2,0x07, -+0xE4,0x90,0x06,0x2C,0xF0,0x80,0xEE,0x90, -+0x06,0x2C,0xE0,0x70,0x12,0x12,0x04,0xEA, -+0x90,0x06,0x2C,0x74,0x01,0xF0,0xE4,0x90, -+0x06,0x33,0xF0,0xA3,0xF0,0x80,0xD6,0xC3, -+0x90,0x06,0x34,0xE0,0x94,0x62,0x90,0x06, -+0x33,0xE0,0x94,0x00,0x40,0xC7,0xE4,0xF0, -+0xA3,0xF0,0x12,0x04,0xEA,0x90,0x06,0x2C, -+0x74,0x01,0xF0,0x80,0xB8,0x75,0x0F,0x80, -+0x75,0x0E,0x7E,0x75,0x0D,0xAA,0x75,0x0C, -+0x83,0xE4,0xF5,0x10,0x7F,0x36,0x7E,0x13, -+0x12,0x07,0x60,0xEE,0xC4,0xF8,0x54,0xF0, -+0xC8,0xEF,0xC4,0x54,0x0F,0x48,0x54,0x07, -+0xFB,0x7A,0x00,0xEA,0x70,0x4A,0xEB,0x14, -+0x60,0x1C,0x14,0x60,0x27,0x24,0xFE,0x60, -+0x31,0x14,0x60,0x3C,0x24,0x05,0x70,0x38, -+0x75,0x0B,0x00,0x75,0x0A,0xC2,0x75,0x09, -+0xEB,0x75,0x08,0x0B,0x80,0x36,0x75,0x0B, -+0x40,0x75,0x0A,0x59,0x75,0x09,0x73,0x75, -+0x08,0x07,0x80,0x28,0x75,0x0B,0x00,0x75, -+0x0A,0xE1,0x75,0x09,0xF5,0x75,0x08,0x05, -+0x80,0x1A,0x75,0x0B,0xA0,0x75,0x0A,0xAC, -+0x75,0x09,0xB9,0x75,0x08,0x03,0x80,0x0C, -+0x75,0x0B,0x00,0x75,0x0A,0x62,0x75,0x09, -+0x3D,0x75,0x08,0x01,0x75,0x89,0x11,0xE4, -+0x7B,0x60,0x7A,0x09,0xF9,0xF8,0xAF,0x0B, -+0xAE,0x0A,0xAD,0x09,0xAC,0x08,0x12,0x00, -+0x60,0xAA,0x06,0xAB,0x07,0xC3,0xE4,0x9B, -+0xFB,0xE4,0x9A,0xFA,0x78,0x17,0xF6,0xAF, -+0x03,0xEF,0x08,0xF6,0x18,0xE6,0xF5,0x8C, -+0x08,0xE6,0xF5,0x8A,0x74,0x0D,0x2B,0xFB, -+0xE4,0x3A,0x18,0xF6,0xAF,0x03,0xEF,0x08, -+0xF6,0x75,0x88,0x10,0x53,0x8E,0xC7,0xD2, -+0xA9,0x22,0x7F,0x10,0x7E,0x13,0x12,0x07, -+0x60,0x90,0x06,0x2D,0xEE,0xF0,0xA3,0xEF, -+0xF0,0xEE,0x44,0x10,0xFE,0x90,0x06,0x2D, -+0xF0,0xA3,0xEF,0xF0,0x54,0xEF,0xFF,0x90, -+0x06,0x2D,0xEE,0xF0,0xFC,0xA3,0xEF,0xF0, -+0xFD,0x7F,0x10,0x7E,0x13,0x12,0x07,0xA5, -+0xE4,0xFF,0xFE,0x0F,0xBF,0x00,0x01,0x0E, -+0xEF,0x64,0x64,0x4E,0x70,0xF5,0x7D,0x04, -+0x7C,0x00,0x7F,0x02,0x7E,0x66,0x12,0x07, -+0xA5,0x7D,0x00,0x7C,0x04,0x7F,0x01,0x7E, -+0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, -+0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0xE4, -+0xFD,0xFC,0x7F,0x02,0x7E,0x66,0x12,0x07, -+0xA5,0x7D,0x00,0x7C,0x04,0x7F,0x01,0x7E, -+0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, -+0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0x7F, -+0x10,0x7E,0x13,0x12,0x07,0x60,0x90,0x06, -+0x2D,0xEE,0xF0,0xA3,0xEF,0xF0,0xEE,0x54, -+0xEF,0x90,0x06,0x2D,0xF0,0xFC,0xA3,0xEF, -+0xF0,0xFD,0x7F,0x10,0x7E,0x13,0x02,0x07, -+0xA5,0x78,0x7F,0xE4,0xF6,0xD8,0xFD,0x75, -+0x81,0x3C,0x02,0x05,0xD0,0x02,0x03,0x2F, -+0xE4,0x93,0xA3,0xF8,0xE4,0x93,0xA3,0x40, -+0x03,0xF6,0x80,0x01,0xF2,0x08,0xDF,0xF4, -+0x80,0x29,0xE4,0x93,0xA3,0xF8,0x54,0x07, -+0x24,0x0C,0xC8,0xC3,0x33,0xC4,0x54,0x0F, -+0x44,0x20,0xC8,0x83,0x40,0x04,0xF4,0x56, -+0x80,0x01,0x46,0xF6,0xDF,0xE4,0x80,0x0B, -+0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80, -+0x90,0x07,0xE1,0xE4,0x7E,0x01,0x93,0x60, -+0xBC,0xA3,0xFF,0x54,0x3F,0x30,0xE5,0x09, -+0x54,0x1F,0xFE,0xE4,0x93,0xA3,0x60,0x01, -+0x0E,0xCF,0x54,0xC0,0x25,0xE0,0x60,0xA8, -+0x40,0xB8,0xE4,0x93,0xA3,0xFA,0xE4,0x93, -+0xA3,0xF8,0xE4,0x93,0xA3,0xC8,0xC5,0x82, -+0xC8,0xCA,0xC5,0x83,0xCA,0xF0,0xA3,0xC8, -+0xC5,0x82,0xC8,0xCA,0xC5,0x83,0xCA,0xDF, -+0xE9,0xDE,0xE7,0x80,0xBE,0x7D,0x40,0x7C, -+0x17,0x7F,0x11,0x7E,0x1D,0x12,0x07,0xA5, -+0x7F,0x41,0x7E,0x1D,0x12,0x07,0x60,0xEF, -+0x44,0x20,0x44,0x80,0xFD,0xAC,0x06,0x7F, -+0x41,0x7E,0x1D,0x12,0x07,0xA5,0x7D,0xBB, -+0x7C,0x15,0x7F,0xEB,0x7E,0x13,0x12,0x07, -+0xA5,0x7D,0x07,0x7C,0x00,0x7F,0xE7,0x7E, -+0x13,0x12,0x07,0xA5,0x7D,0x40,0x7C,0x11, -+0x7F,0x00,0x7E,0x62,0x12,0x07,0xA5,0x02, -+0x02,0x2F,0x7D,0xC0,0x7C,0x16,0x7F,0x11, -+0x7E,0x1D,0x12,0x07,0xA5,0x7D,0xBB,0x7C, -+0x15,0x7F,0xEB,0x7E,0x13,0x12,0x07,0xA5, -+0x7D,0x0D,0x7C,0x00,0x7F,0xE7,0x7E,0x13, -+0x12,0x07,0xA5,0x7F,0x41,0x7E,0x1D,0x12, -+0x07,0x60,0xEF,0x44,0x20,0x44,0x80,0xFD, -+0xAC,0x06,0x7F,0x41,0x7E,0x1D,0x12,0x07, -+0xA5,0x7D,0x00,0x7C,0x21,0x7F,0x00,0x7E, -+0x62,0x12,0x07,0xA5,0x02,0x02,0x2F,0x7D, -+0x40,0x7C,0x17,0x7F,0x11,0x7E,0x1D,0x12, -+0x07,0xA5,0x7D,0xBB,0x7C,0x15,0x7F,0xEB, -+0x7E,0x13,0x12,0x07,0xA5,0x7D,0x0C,0x7C, -+0x00,0x7F,0xE7,0x7E,0x13,0x12,0x07,0xA5, -+0x7F,0x41,0x7E,0x1D,0x12,0x07,0x60,0xEF, -+0x44,0x20,0x44,0x80,0xFD,0xAC,0x06,0x7F, -+0x41,0x7E,0x1D,0x12,0x07,0xA5,0x7D,0x40, -+0x7C,0x11,0x7F,0x00,0x7E,0x62,0x12,0x07, -+0xA5,0x02,0x02,0x2F,0x7D,0x04,0x7C,0x00, -+0x7F,0x01,0x7E,0x66,0x12,0x07,0xA5,0x7D, -+0x80,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12, -+0x07,0xA5,0x7F,0x02,0x7E,0x66,0x12,0x07, -+0x60,0xEF,0x44,0x02,0x44,0x04,0xFD,0xAC, -+0x06,0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5, -+0x7D,0x04,0x7C,0x00,0x7F,0x01,0x7E,0x66, -+0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F, -+0x00,0x7E,0x66,0x02,0x07,0xA5,0xC0,0xE0, -+0xC0,0xF0,0xC0,0x83,0xC0,0x82,0xC0,0xD0, -+0x75,0xD0,0x00,0xC0,0x00,0x78,0x17,0xE6, -+0xF5,0x8C,0x78,0x18,0xE6,0xF5,0x8A,0x90, -+0x06,0x31,0xE4,0x75,0xF0,0x01,0x12,0x00, -+0x0E,0x90,0x06,0x33,0xE4,0x75,0xF0,0x01, -+0x12,0x00,0x0E,0xD0,0x00,0xD0,0xD0,0xD0, -+0x82,0xD0,0x83,0xD0,0xF0,0xD0,0xE0,0x32, -+0xC2,0xAF,0xAD,0x07,0xAC,0x06,0x8C,0xA2, -+0x8D,0xA3,0x75,0xA0,0x01,0x00,0x00,0x00, -+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -+0xAE,0xA1,0xBE,0x00,0xF0,0xAE,0xA6,0xAF, -+0xA7,0xD2,0xAF,0x22,0x7D,0x20,0x7C,0x0F, -+0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5,0x7D, -+0x01,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, -+0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F,0x00, -+0x7E,0x66,0x02,0x07,0xA5,0xC2,0xAF,0xAB, -+0x07,0xAA,0x06,0x8A,0xA2,0x8B,0xA3,0x8C, -+0xA4,0x8D,0xA5,0x75,0xA0,0x03,0x00,0x00, -+0x00,0xAA,0xA1,0xBA,0x00,0xF8,0xD2,0xAF, -+0x22,0x7F,0x0C,0x7E,0x13,0x12,0x07,0x60, -+0xEF,0x44,0x50,0xFD,0xAC,0x06,0x7F,0x0C, -+0x7E,0x13,0x02,0x07,0xA5,0x12,0x07,0xC1, -+0x12,0x07,0xEC,0x12,0x04,0x25,0x02,0x00, -+0x03,0x42,0x06,0x33,0x00,0x00,0x42,0x06, -+0x31,0x00,0x00,0x00,0xE4,0xF5,0x8E,0x22,}; -+ -+ -+#define SGMII_INIT_SIZE 1183 -+rtk_uint8 Sgmii_Init[SGMII_INIT_SIZE] = { -+0x02,0x03,0x81,0xE4,0xF5,0xA8,0xD2,0xAF, -+0x22,0x00,0x00,0x02,0x04,0x0D,0xC5,0xF0, -+0xF8,0xA3,0xE0,0x28,0xF0,0xC5,0xF0,0xF8, -+0xE5,0x82,0x15,0x82,0x70,0x02,0x15,0x83, -+0xE0,0x38,0xF0,0x22,0x75,0xF0,0x08,0x75, -+0x82,0x00,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, -+0xCD,0x33,0xCD,0xCC,0x33,0xCC,0xC5,0x82, -+0x33,0xC5,0x82,0x9B,0xED,0x9A,0xEC,0x99, -+0xE5,0x82,0x98,0x40,0x0C,0xF5,0x82,0xEE, -+0x9B,0xFE,0xED,0x9A,0xFD,0xEC,0x99,0xFC, -+0x0F,0xD5,0xF0,0xD6,0xE4,0xCE,0xFB,0xE4, -+0xCD,0xFA,0xE4,0xCC,0xF9,0xA8,0x82,0x22, -+0xB8,0x00,0xC1,0xB9,0x00,0x59,0xBA,0x00, -+0x2D,0xEC,0x8B,0xF0,0x84,0xCF,0xCE,0xCD, -+0xFC,0xE5,0xF0,0xCB,0xF9,0x78,0x18,0xEF, -+0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33,0xFD, -+0xEC,0x33,0xFC,0xEB,0x33,0xFB,0x10,0xD7, -+0x03,0x99,0x40,0x04,0xEB,0x99,0xFB,0x0F, -+0xD8,0xE5,0xE4,0xF9,0xFA,0x22,0x78,0x18, -+0xEF,0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33, -+0xFD,0xEC,0x33,0xFC,0xC9,0x33,0xC9,0x10, -+0xD7,0x05,0x9B,0xE9,0x9A,0x40,0x07,0xEC, -+0x9B,0xFC,0xE9,0x9A,0xF9,0x0F,0xD8,0xE0, -+0xE4,0xC9,0xFA,0xE4,0xCC,0xFB,0x22,0x75, -+0xF0,0x10,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, -+0xED,0x33,0xFD,0xCC,0x33,0xCC,0xC8,0x33, -+0xC8,0x10,0xD7,0x07,0x9B,0xEC,0x9A,0xE8, -+0x99,0x40,0x0A,0xED,0x9B,0xFD,0xEC,0x9A, -+0xFC,0xE8,0x99,0xF8,0x0F,0xD5,0xF0,0xDA, -+0xE4,0xCD,0xFB,0xE4,0xCC,0xFA,0xE4,0xC8, -+0xF9,0x22,0xEB,0x9F,0xF5,0xF0,0xEA,0x9E, -+0x42,0xF0,0xE9,0x9D,0x42,0xF0,0xE8,0x9C, -+0x45,0xF0,0x22,0xE0,0xFC,0xA3,0xE0,0xFD, -+0xA3,0xE0,0xFE,0xA3,0xE0,0xFF,0x22,0xE0, -+0xF8,0xA3,0xE0,0xF9,0xA3,0xE0,0xFA,0xA3, -+0xE0,0xFB,0x22,0xEC,0xF0,0xA3,0xED,0xF0, -+0xA3,0xEE,0xF0,0xA3,0xEF,0xF0,0x22,0xE4, -+0x90,0x06,0x2C,0xF0,0xFD,0x7C,0x01,0x7F, -+0x3F,0x7E,0x1D,0x12,0x04,0x6B,0x7D,0x40, -+0x7C,0x00,0x7F,0x36,0x7E,0x13,0x12,0x04, -+0x6B,0xE4,0xFF,0xFE,0xFD,0x80,0x25,0xE4, -+0x7F,0xFF,0x7E,0xFF,0xFD,0xFC,0x90,0x06, -+0x24,0x12,0x01,0x0F,0xC3,0x12,0x00,0xF2, -+0x50,0x1B,0x90,0x06,0x24,0x12,0x01,0x03, -+0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE,0xE4, -+0x3D,0xFD,0xE4,0x3C,0xFC,0x90,0x06,0x24, -+0x12,0x01,0x1B,0x80,0xD2,0xE4,0xF5,0xA8, -+0xD2,0xAF,0x7D,0x1F,0xFC,0x7F,0x49,0x7E, -+0x13,0x12,0x04,0x6B,0x12,0x04,0x92,0x7D, -+0x41,0x7C,0x00,0x7F,0x36,0x7E,0x13,0x12, -+0x04,0x6B,0xE4,0xFF,0xFE,0xFD,0x80,0x25, -+0xE4,0x7F,0x20,0x7E,0x4E,0xFD,0xFC,0x90, -+0x06,0x24,0x12,0x01,0x0F,0xC3,0x12,0x00, -+0xF2,0x50,0x1B,0x90,0x06,0x24,0x12,0x01, -+0x03,0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE, -+0xE4,0x3D,0xFD,0xE4,0x3C,0xFC,0x90,0x06, -+0x24,0x12,0x01,0x1B,0x80,0xD2,0xC2,0x00, -+0xC2,0x01,0xD2,0xA9,0xD2,0x8C,0x7F,0x01, -+0x7E,0x62,0x12,0x04,0x47,0xEF,0x30,0xE2, -+0x07,0xE4,0x90,0x06,0x2C,0xF0,0x80,0xEE, -+0x90,0x06,0x2C,0xE0,0x70,0x12,0x12,0x02, -+0xDB,0x90,0x06,0x2C,0x74,0x01,0xF0,0xE4, -+0x90,0x06,0x2F,0xF0,0xA3,0xF0,0x80,0xD6, -+0xC3,0x90,0x06,0x30,0xE0,0x94,0x62,0x90, -+0x06,0x2F,0xE0,0x94,0x00,0x40,0xC7,0xE4, -+0xF0,0xA3,0xF0,0x12,0x02,0xDB,0x90,0x06, -+0x2C,0x74,0x01,0xF0,0x80,0xB8,0x75,0x0F, -+0x80,0x75,0x0E,0x7E,0x75,0x0D,0xAA,0x75, -+0x0C,0x83,0xE4,0xF5,0x10,0x7F,0x36,0x7E, -+0x13,0x12,0x04,0x47,0xEE,0xC4,0xF8,0x54, -+0xF0,0xC8,0xEF,0xC4,0x54,0x0F,0x48,0x54, -+0x07,0xFB,0x7A,0x00,0xEA,0x70,0x4A,0xEB, -+0x14,0x60,0x1C,0x14,0x60,0x27,0x24,0xFE, -+0x60,0x31,0x14,0x60,0x3C,0x24,0x05,0x70, -+0x38,0x75,0x0B,0x00,0x75,0x0A,0xC2,0x75, -+0x09,0xEB,0x75,0x08,0x0B,0x80,0x36,0x75, -+0x0B,0x40,0x75,0x0A,0x59,0x75,0x09,0x73, -+0x75,0x08,0x07,0x80,0x28,0x75,0x0B,0x00, -+0x75,0x0A,0xE1,0x75,0x09,0xF5,0x75,0x08, -+0x05,0x80,0x1A,0x75,0x0B,0xA0,0x75,0x0A, -+0xAC,0x75,0x09,0xB9,0x75,0x08,0x03,0x80, -+0x0C,0x75,0x0B,0x00,0x75,0x0A,0x62,0x75, -+0x09,0x3D,0x75,0x08,0x01,0x75,0x89,0x11, -+0xE4,0x7B,0x60,0x7A,0x09,0xF9,0xF8,0xAF, -+0x0B,0xAE,0x0A,0xAD,0x09,0xAC,0x08,0x12, -+0x00,0x60,0xAA,0x06,0xAB,0x07,0xC3,0xE4, -+0x9B,0xFB,0xE4,0x9A,0xFA,0x78,0x17,0xF6, -+0xAF,0x03,0xEF,0x08,0xF6,0x18,0xE6,0xF5, -+0x8C,0x08,0xE6,0xF5,0x8A,0x74,0x0D,0x2B, -+0xFB,0xE4,0x3A,0x18,0xF6,0xAF,0x03,0xEF, -+0x08,0xF6,0x75,0x88,0x10,0x53,0x8E,0xC7, -+0xD2,0xA9,0x22,0x7D,0x02,0x7C,0x00,0x7F, -+0x4A,0x7E,0x13,0x12,0x04,0x6B,0x7D,0x46, -+0x7C,0x71,0x7F,0x02,0x7E,0x66,0x12,0x04, -+0x6B,0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E, -+0x66,0x12,0x04,0x6B,0x7D,0xC0,0x7C,0x00, -+0x7F,0x00,0x7E,0x66,0x12,0x04,0x6B,0xE4, -+0xFF,0xFE,0x0F,0xBF,0x00,0x01,0x0E,0xEF, -+0x64,0x64,0x4E,0x70,0xF5,0x7D,0x04,0x7C, -+0x00,0x7F,0x02,0x7E,0x66,0x12,0x04,0x6B, -+0x7D,0x00,0x7C,0x04,0x7F,0x01,0x7E,0x66, -+0x12,0x04,0x6B,0x7D,0xC0,0x7C,0x00,0x7F, -+0x00,0x7E,0x66,0x12,0x04,0x6B,0xE4,0xFD, -+0xFC,0x7F,0x02,0x7E,0x66,0x12,0x04,0x6B, -+0x7D,0x00,0x7C,0x04,0x7F,0x01,0x7E,0x66, -+0x12,0x04,0x6B,0x7D,0xC0,0x7C,0x00,0x7F, -+0x00,0x7E,0x66,0x12,0x04,0x6B,0xE4,0xFD, -+0xFC,0x7F,0x4A,0x7E,0x13,0x12,0x04,0x6B, -+0x7D,0x06,0x7C,0x71,0x7F,0x02,0x7E,0x66, -+0x12,0x04,0x6B,0x7D,0x03,0x7C,0x00,0x7F, -+0x01,0x7E,0x66,0x12,0x04,0x6B,0x7D,0xC0, -+0x7C,0x00,0x7F,0x00,0x7E,0x66,0x02,0x04, -+0x6B,0x78,0x7F,0xE4,0xF6,0xD8,0xFD,0x75, -+0x81,0x3C,0x02,0x03,0xC8,0x02,0x01,0x27, -+0xE4,0x93,0xA3,0xF8,0xE4,0x93,0xA3,0x40, -+0x03,0xF6,0x80,0x01,0xF2,0x08,0xDF,0xF4, -+0x80,0x29,0xE4,0x93,0xA3,0xF8,0x54,0x07, -+0x24,0x0C,0xC8,0xC3,0x33,0xC4,0x54,0x0F, -+0x44,0x20,0xC8,0x83,0x40,0x04,0xF4,0x56, -+0x80,0x01,0x46,0xF6,0xDF,0xE4,0x80,0x0B, -+0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80, -+0x90,0x04,0x87,0xE4,0x7E,0x01,0x93,0x60, -+0xBC,0xA3,0xFF,0x54,0x3F,0x30,0xE5,0x09, -+0x54,0x1F,0xFE,0xE4,0x93,0xA3,0x60,0x01, -+0x0E,0xCF,0x54,0xC0,0x25,0xE0,0x60,0xA8, -+0x40,0xB8,0xE4,0x93,0xA3,0xFA,0xE4,0x93, -+0xA3,0xF8,0xE4,0x93,0xA3,0xC8,0xC5,0x82, -+0xC8,0xCA,0xC5,0x83,0xCA,0xF0,0xA3,0xC8, -+0xC5,0x82,0xC8,0xCA,0xC5,0x83,0xCA,0xDF, -+0xE9,0xDE,0xE7,0x80,0xBE,0xC0,0xE0,0xC0, -+0xF0,0xC0,0x83,0xC0,0x82,0xC0,0xD0,0x75, -+0xD0,0x00,0xC0,0x00,0x78,0x17,0xE6,0xF5, -+0x8C,0x78,0x18,0xE6,0xF5,0x8A,0x90,0x06, -+0x2D,0xE4,0x75,0xF0,0x01,0x12,0x00,0x0E, -+0x90,0x06,0x2F,0xE4,0x75,0xF0,0x01,0x12, -+0x00,0x0E,0xD0,0x00,0xD0,0xD0,0xD0,0x82, -+0xD0,0x83,0xD0,0xF0,0xD0,0xE0,0x32,0xC2, -+0xAF,0xAD,0x07,0xAC,0x06,0x8C,0xA2,0x8D, -+0xA3,0x75,0xA0,0x01,0x00,0x00,0x00,0x00, -+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAE, -+0xA1,0xBE,0x00,0xF0,0xAE,0xA6,0xAF,0xA7, -+0xD2,0xAF,0x22,0xC2,0xAF,0xAB,0x07,0xAA, -+0x06,0x8A,0xA2,0x8B,0xA3,0x8C,0xA4,0x8D, -+0xA5,0x75,0xA0,0x03,0x00,0x00,0x00,0xAA, -+0xA1,0xBA,0x00,0xF8,0xD2,0xAF,0x22,0x42, -+0x06,0x2F,0x00,0x00,0x42,0x06,0x2D,0x00, -+0x00,0x00,0x12,0x04,0x9B,0x12,0x02,0x16, -+0x02,0x00,0x03,0xE4,0xF5,0x8E,0x22,}; -+ -+ -+/* Function Name: -+ * rtl8367c_setAsicPortUnknownDaBehavior -+ * Description: -+ * Set UNDA behavior -+ * Input: -+ * port - port ID -+ * behavior - 0: flooding to unknown DA portmask; 1: drop; 2:trap; 3: flooding -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NOT_ALLOWED - Invalid behavior -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortUnknownDaBehavior(rtk_uint32 port, rtk_uint32 behavior) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ if(behavior >= L2_UNDA_BEHAVE_END) -+ return RT_ERR_NOT_ALLOWED; -+ -+ if(port < 8) -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_UNKNOWN_UNICAST_DA_PORT_BEHAVE, RTL8367C_Port0_ACTION_MASK << (port * 2), behavior); -+ else -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_UNKNOWN_UNICAST_DA_PORT_BEHAVE_EXT, RTL8367C_PORT8_ACTION_MASK << ((port-8) * 2), behavior); -+} -+/* Function Name: -+ * rtl8367c_getAsicPortUnknownDaBehavior -+ * Description: -+ * Get UNDA behavior -+ * Input: -+ * port - port ID -+ * Output: -+ * pBehavior - 0: flooding to unknown DA portmask; 1: drop; 2:trap; 3: flooding -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortUnknownDaBehavior(rtk_uint32 port, rtk_uint32 *pBehavior) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ if(port < 8) -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_UNKNOWN_UNICAST_DA_PORT_BEHAVE, RTL8367C_Port0_ACTION_MASK << (port * 2), pBehavior); -+ else -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_UNKNOWN_UNICAST_DA_PORT_BEHAVE_EXT, RTL8367C_PORT8_ACTION_MASK << ((port-8) * 2), pBehavior); -+} -+/* Function Name: -+ * rtl8367c_setAsicPortUnknownSaBehavior -+ * Description: -+ * Set UNSA behavior -+ * Input: -+ * behavior - 0: flooding; 1: drop; 2:trap -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NOT_ALLOWED - Invalid behavior -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortUnknownSaBehavior(rtk_uint32 behavior) -+{ -+ if(behavior >= L2_BEHAVE_SA_END) -+ return RT_ERR_NOT_ALLOWED; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_PORT_SECURIT_CTRL_REG, RTL8367C_UNKNOWN_SA_BEHAVE_MASK, behavior); -+} -+/* Function Name: -+ * rtl8367c_getAsicPortUnknownSaBehavior -+ * Description: -+ * Get UNSA behavior -+ * Input: -+ * pBehavior - 0: flooding; 1: drop; 2:trap -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortUnknownSaBehavior(rtk_uint32 *pBehavior) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_PORT_SECURIT_CTRL_REG, RTL8367C_UNKNOWN_SA_BEHAVE_MASK, pBehavior); -+} -+/* Function Name: -+ * rtl8367c_setAsicPortUnmatchedSaBehavior -+ * Description: -+ * Set Unmatched SA behavior -+ * Input: -+ * behavior - 0: flooding; 1: drop; 2:trap -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NOT_ALLOWED - Invalid behavior -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortUnmatchedSaBehavior(rtk_uint32 behavior) -+{ -+ if(behavior >= L2_BEHAVE_SA_END) -+ return RT_ERR_NOT_ALLOWED; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_PORT_SECURIT_CTRL_REG, RTL8367C_UNMATCHED_SA_BEHAVE_MASK, behavior); -+} -+/* Function Name: -+ * rtl8367c_getAsicPortUnmatchedSaBehavior -+ * Description: -+ * Get Unmatched SA behavior -+ * Input: -+ * pBehavior - 0: flooding; 1: drop; 2:trap -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortUnmatchedSaBehavior(rtk_uint32 *pBehavior) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_PORT_SECURIT_CTRL_REG, RTL8367C_UNMATCHED_SA_BEHAVE_MASK, pBehavior); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicPortUnmatchedSaMoving -+ * Description: -+ * Set Unmatched SA moving state -+ * Input: -+ * port - Port ID -+ * enabled - 0: can't move to new port; 1: can move to new port -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Error Port ID -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortUnmatchedSaMoving(rtk_uint32 port, rtk_uint32 enabled) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_L2_SA_MOVING_FORBID, port, (enabled == 1) ? 0 : 1); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicPortUnmatchedSaMoving -+ * Description: -+ * Get Unmatched SA moving state -+ * Input: -+ * port - Port ID -+ * Output: -+ * pEnabled - 0: can't move to new port; 1: can move to new port -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Error Port ID -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortUnmatchedSaMoving(rtk_uint32 port, rtk_uint32 *pEnabled) -+{ -+ rtk_uint32 data; -+ ret_t retVal; -+ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_L2_SA_MOVING_FORBID, port, &data)) != RT_ERR_OK) -+ return retVal; -+ -+ *pEnabled = (data == 1) ? 0 : 1; -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicPortUnknownDaFloodingPortmask -+ * Description: -+ * Set UNDA flooding portmask -+ * Input: -+ * portmask - portmask(0~0xFF) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Invalid portmask -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortUnknownDaFloodingPortmask(rtk_uint32 portmask) -+{ -+ if(portmask > RTL8367C_PORTMASK) -+ return RT_ERR_PORT_MASK; -+ -+ return rtl8367c_setAsicReg(RTL8367C_UNUCAST_FLOADING_PMSK_REG, portmask); -+} -+/* Function Name: -+ * rtl8367c_getAsicPortUnknownDaFloodingPortmask -+ * Description: -+ * Get UNDA flooding portmask -+ * Input: -+ * pPortmask - portmask(0~0xFF) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortUnknownDaFloodingPortmask(rtk_uint32 *pPortmask) -+{ -+ return rtl8367c_getAsicReg(RTL8367C_UNUCAST_FLOADING_PMSK_REG, pPortmask); -+} -+/* Function Name: -+ * rtl8367c_setAsicPortUnknownMulticastFloodingPortmask -+ * Description: -+ * Set UNMC flooding portmask -+ * Input: -+ * portmask - portmask(0~0xFF) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Invalid portmask -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortUnknownMulticastFloodingPortmask(rtk_uint32 portmask) -+{ -+ if(portmask > RTL8367C_PORTMASK) -+ return RT_ERR_PORT_MASK; -+ -+ return rtl8367c_setAsicReg(RTL8367C_UNMCAST_FLOADING_PMSK_REG, portmask); -+} -+/* Function Name: -+ * rtl8367c_getAsicPortUnknownMulticastFloodingPortmask -+ * Description: -+ * Get UNMC flooding portmask -+ * Input: -+ * pPortmask - portmask(0~0xFF) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortUnknownMulticastFloodingPortmask(rtk_uint32 *pPortmask) -+{ -+ return rtl8367c_getAsicReg(RTL8367C_UNMCAST_FLOADING_PMSK_REG, pPortmask); -+} -+/* Function Name: -+ * rtl8367c_setAsicPortBcastFloodingPortmask -+ * Description: -+ * Set Bcast flooding portmask -+ * Input: -+ * portmask - portmask(0~0xFF) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Invalid portmask -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortBcastFloodingPortmask(rtk_uint32 portmask) -+{ -+ if(portmask > RTL8367C_PORTMASK) -+ return RT_ERR_PORT_MASK; -+ -+ return rtl8367c_setAsicReg(RTL8367C_BCAST_FLOADING_PMSK_REG, portmask); -+} -+/* Function Name: -+ * rtl8367c_getAsicPortBcastFloodingPortmask -+ * Description: -+ * Get Bcast flooding portmask -+ * Input: -+ * pPortmask - portmask(0~0xFF) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortBcastFloodingPortmask(rtk_uint32 *pPortmask) -+{ -+ return rtl8367c_getAsicReg(RTL8367C_BCAST_FLOADING_PMSK_REG, pPortmask); -+} -+/* Function Name: -+ * rtl8367c_setAsicPortBlockSpa -+ * Description: -+ * Set disabling blocking frame if source port and destination port are the same -+ * Input: -+ * port - Physical port number (0~7) -+ * permit - 0: block; 1: permit -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortBlockSpa(rtk_uint32 port, rtk_uint32 permit) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_SOURCE_PORT_BLOCK_REG, port, permit); -+} -+/* Function Name: -+ * rtl8367c_getAsicPortBlockSpa -+ * Description: -+ * Get disabling blocking frame if source port and destination port are the same -+ * Input: -+ * port - Physical port number (0~7) -+ * pPermit - 0: block; 1: permit -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortBlockSpa(rtk_uint32 port, rtk_uint32* pPermit) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_SOURCE_PORT_BLOCK_REG, port, pPermit); -+} -+/* Function Name: -+ * rtl8367c_setAsicPortDos -+ * Description: -+ * Set DOS function -+ * Input: -+ * type - DOS type -+ * drop - 0: permit; 1: drop -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - Invalid payload index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortDos(rtk_uint32 type, rtk_uint32 drop) -+{ -+ if(type >= DOS_END) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_DOS_CFG, RTL8367C_DROP_DAEQSA_OFFSET + type, drop); -+} -+/* Function Name: -+ * rtl8367c_getAsicPortDos -+ * Description: -+ * Get DOS function -+ * Input: -+ * type - DOS type -+ * pDrop - 0: permit; 1: drop -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - Invalid payload index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortDos(rtk_uint32 type, rtk_uint32* pDrop) -+{ -+ if(type >= DOS_END) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_DOS_CFG, RTL8367C_DROP_DAEQSA_OFFSET + type,pDrop); -+} -+/* Function Name: -+ * rtl8367c_setAsicPortForceLink -+ * Description: -+ * Set port force linking configuration -+ * Input: -+ * port - Physical port number (0~7) -+ * pPortAbility - port ability configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortForceLink(rtk_uint32 port, rtl8367c_port_ability_t *pPortAbility) -+{ -+ rtk_uint32 regData = 0; -+ -+ /* Invalid input parameter */ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ regData |= pPortAbility->forcemode << 12; -+ regData |= pPortAbility->mstfault << 9; -+ regData |= pPortAbility->mstmode << 8; -+ regData |= pPortAbility->nway << 7; -+ regData |= pPortAbility->txpause << 6; -+ regData |= pPortAbility->rxpause << 5; -+ regData |= pPortAbility->link << 4; -+ regData |= pPortAbility->duplex << 2; -+ regData |= pPortAbility->speed; -+ -+ return rtl8367c_setAsicReg(RTL8367C_REG_MAC0_FORCE_SELECT+port, regData); -+} -+/* Function Name: -+ * rtl8367c_getAsicPortForceLink -+ * Description: -+ * Get port force linking configuration -+ * Input: -+ * port - Physical port number (0~7) -+ * pPortAbility - port ability configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortForceLink(rtk_uint32 port, rtl8367c_port_ability_t *pPortAbility) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ -+ /* Invalid input parameter */ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_MAC0_FORCE_SELECT + port, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ pPortAbility->forcemode = (regData >> 12) & 0x0001; -+ pPortAbility->mstfault = (regData >> 9) & 0x0001; -+ pPortAbility->mstmode = (regData >> 8) & 0x0001; -+ pPortAbility->nway = (regData >> 7) & 0x0001; -+ pPortAbility->txpause = (regData >> 6) & 0x0001; -+ pPortAbility->rxpause = (regData >> 5) & 0x0001; -+ pPortAbility->link = (regData >> 4) & 0x0001; -+ pPortAbility->duplex = (regData >> 2) & 0x0001; -+ pPortAbility->speed = regData & 0x0003; -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicPortStatus -+ * Description: -+ * Get port link status -+ * Input: -+ * port - Physical port number (0~7) -+ * pPortAbility - port ability configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortStatus(rtk_uint32 port, rtl8367c_port_status_t *pPortStatus) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ -+ /* Invalid input parameter */ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_PORT0_STATUS+port,®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ pPortStatus->lpi1000 = (regData >> 11) & 0x0001; -+ pPortStatus->lpi100 = (regData >> 10) & 0x0001; -+ pPortStatus->mstfault = (regData >> 9) & 0x0001; -+ pPortStatus->mstmode = (regData >> 8) & 0x0001; -+ pPortStatus->nway = (regData >> 7) & 0x0001; -+ pPortStatus->txpause = (regData >> 6) & 0x0001; -+ pPortStatus->rxpause = (regData >> 5) & 0x0001; -+ pPortStatus->link = (regData >> 4) & 0x0001; -+ pPortStatus->duplex = (regData >> 2) & 0x0001; -+ pPortStatus->speed = regData & 0x0003; -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicPortForceLinkExt -+ * Description: -+ * Set external interface force linking configuration -+ * Input: -+ * id - external interface id (0~2) -+ * portAbility - port ability configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortForceLinkExt(rtk_uint32 id, rtl8367c_port_ability_t *pPortAbility) -+{ -+ rtk_uint32 retVal, regValue, regValue2, type, sgmiibit, hisgmiibit; -+ rtk_uint32 reg_data = 0; -+ rtk_uint32 i = 0; -+ -+ /* Invalid input parameter */ -+ if(id >= RTL8367C_EXTNO) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ reg_data |= pPortAbility->forcemode << 12; -+ reg_data |= pPortAbility->mstfault << 9; -+ reg_data |= pPortAbility->mstmode << 8; -+ reg_data |= pPortAbility->nway << 7; -+ reg_data |= pPortAbility->txpause << 6; -+ reg_data |= pPortAbility->rxpause << 5; -+ reg_data |= pPortAbility->link << 4; -+ reg_data |= pPortAbility->duplex << 2; -+ reg_data |= pPortAbility->speed; -+ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) -+ return retVal; -+ /*get chip ID */ -+ if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) -+ return retVal; -+ -+ type = 0; -+ -+ switch (regValue) -+ { -+ case 0x0276: -+ case 0x0597: -+ case 0x6367: -+ type = 1; -+ break; -+ case 0x0652: -+ case 0x6368: -+ type = 2; -+ break; -+ case 0x0801: -+ case 0x6511: -+ type = 3; -+ break; -+ default: -+ return RT_ERR_FAILED; -+ } -+ -+ if (1 == type) -+ { -+ if(1 == id) -+ { -+ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_REG_TO_ECO4, ®Value)) != RT_ERR_OK) -+ return retVal; -+ -+ if((regValue & (0x0001 << 5)) && (regValue & (0x0001 << 7))) -+ { -+ return RT_ERR_OK; -+ } -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_FDUP_OFFSET, pPortAbility->duplex)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_SPD_MASK, pPortAbility->speed)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_LINK_OFFSET, pPortAbility->link)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_TXFC_OFFSET, pPortAbility->txpause)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_RXFC_OFFSET, pPortAbility->rxpause)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ if(0 == id || 1 == id) -+ return rtl8367c_setAsicReg(RTL8367C_REG_DIGITAL_INTERFACE0_FORCE + id, reg_data); -+ else -+ return rtl8367c_setAsicReg(RTL8367C_REG_DIGITAL_INTERFACE2_FORCE, reg_data); -+ } -+ else if (2 == type) -+ { -+ if (1 == id) -+ { -+ if((retVal = rtl8367c_setAsicRegBit(0x1311, 2, pPortAbility->duplex)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBits(0x1311, 0x3, pPortAbility->speed)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, pPortAbility->link)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x1311, 6, pPortAbility->txpause)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x1311, 5, pPortAbility->rxpause)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x1311, 12, pPortAbility->forcemode)) != RT_ERR_OK) -+ return retVal; -+ -+ if (pPortAbility->link == 1) -+ { -+ if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, 1)) != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ if((retVal = rtl8367c_setAsicRegBits(0x1311, 0x3, 2)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_FDUP_OFFSET, pPortAbility->duplex)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_SPD_MASK, pPortAbility->speed)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_LINK_OFFSET, pPortAbility->link)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_TXFC_OFFSET, pPortAbility->txpause)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_RXFC_OFFSET, pPortAbility->rxpause)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if (2 == id) -+ { -+ if((retVal = rtl8367c_setAsicRegBit(0x13c4, 2, pPortAbility->duplex)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBits(0x13c4, 0x3, pPortAbility->speed)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x13c4, 4, pPortAbility->link)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x13c4, 6, pPortAbility->txpause)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x13c4, 5, pPortAbility->rxpause)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x13c4, 12, pPortAbility->forcemode)) != RT_ERR_OK) -+ return retVal; -+ -+ if (pPortAbility->link == 1) -+ { -+ if((retVal = rtl8367c_setAsicRegBit(0x13c4, 4, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x13c4, 4, 1)) != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ if((retVal = rtl8367c_setAsicRegBits(0x13c4, 0x3, 2)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x1dc1, RTL8367C_CFG_SGMII_FDUP_OFFSET, pPortAbility->duplex)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBits(0x1dc1, RTL8367C_CFG_SGMII_SPD_MASK, pPortAbility->speed)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x1dc1, RTL8367C_CFG_SGMII_LINK_OFFSET, pPortAbility->link)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x1dc1, RTL8367C_CFG_SGMII_TXFC_OFFSET, pPortAbility->txpause)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x1dc1, RTL8367C_CFG_SGMII_RXFC_OFFSET, pPortAbility->rxpause)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ } -+ else if(3 == type) -+ { -+ if(1 == id) -+ { -+ if((retVal = rtl8367c_getAsicRegBit(0x1d11, 6, &sgmiibit)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_getAsicRegBit(0x1d11, 11, &hisgmiibit)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((sgmiibit == 1) || (hisgmiibit == 1)) -+ { -+ /*for 1000x/100fx/1000x_100fx, param has to be set to serdes registers*/ -+ if((retVal = rtl8367c_getAsicReg(0x1d41, ®Value)) != RT_ERR_OK) -+ return retVal; -+ -+ /*bit5: cfg_mac6_fib =1, bit7: cfg_mac6_fib2=1*/ -+ if((regValue & 0xa0) == 0xa0) -+ { -+ /* new_cfg_sds_mode */ -+ if((retVal = rtl8367c_getAsicRegBits(0x1d95, 0x1f00, ®Value2)) != RT_ERR_OK) -+ return retVal; -+ -+ /*1000X*/ -+ if(regValue2 == 0x4) -+ { -+#if 0 -+ /* new_cfg_sds_mode:reset mode */ -+ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) -+ return retVal; -+#endif -+ /* Enable new sds mode config */ -+ if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 4 0 bit 12 set 1, bit15~13 = 4*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFF0FFF; -+ reg_data |= 0x9000; -+ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 0 2 bit 6 set 1, bit13 set to 0, bit12 nway_en*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFFDFFF; -+ reg_data |= 0x40; -+ if(pPortAbility->forcemode) -+ reg_data &= 0xffffefff; -+ else -+ reg_data |= 0x1000; -+ -+ if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) -+ return retVal; -+ -+ if (pPortAbility->txpause) -+ reg_data |= 0x80; -+ else -+ reg_data &= (~0x80); -+ -+ if (pPortAbility->rxpause) -+ reg_data |= 0x100; -+ else -+ reg_data &= (~0x100); -+ -+ if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 4 0 bit 12 set 0*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFFEFFF; -+ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /*new_cfg_sds_mode=1000x*/ -+ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x4)) != RT_ERR_OK) -+ return retVal; -+ -+ } -+ else if(regValue2 == 0x5) -+ { -+#if 0 -+ /*100FX*/ -+ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) -+ return retVal; -+#endif -+ /*cfg_sds_mode_sel_new=1 */ -+ if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 4 0 bit 12 set 1, bit15~13 = 5*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFF0FFF; -+ reg_data |= 0xB000; -+ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 0 2 bit 6 set 0, bit13 set to 1, bit12 0*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFFFFBF; -+ reg_data |= 0x2000; -+ reg_data &= 0xffffefff; -+ -+ if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) -+ return retVal; -+ if (pPortAbility->txpause) -+ reg_data |= 0x80; -+ else -+ reg_data &= (~0x80); -+ if (pPortAbility->rxpause) -+ reg_data |= 0x100; -+ else -+ reg_data &= (~0x100); -+ if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 4 0 bit 12 set 0*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFFEFFF; -+ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) -+ return retVal; -+ /* new_cfg_sds_mode=1000x */ -+ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x5)) != RT_ERR_OK) -+ return retVal; -+ -+ } -+ else if(regValue2 == 0x7) -+ { -+#if 0 -+ /*100FX*/ -+ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) -+ return retVal; -+#endif -+ if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 4 0 bit 12 set 1, bit15~13 = 4*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFF0FFF; -+ reg_data |= 0x9000; -+ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 0 2 bit 6 set 1, bit13 set to 0, bit12 nway_en*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFFDFFF; -+ reg_data |= 0x40; -+ if(pPortAbility->forcemode) -+ reg_data &= 0xffffefff; -+ else -+ reg_data |= 0x1000; -+ -+ if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) -+ return retVal; -+ if (pPortAbility->txpause) -+ reg_data |= 0x80; -+ else -+ reg_data &= (~0x80); -+ if (pPortAbility->rxpause) -+ reg_data |= 0x100; -+ else -+ reg_data &=(~0x100); -+ if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 4 0 bit 12 set 0*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFFEFFF; -+ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 4 0 bit 12 set 1, bit15~13 = 5*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFF0FFF; -+ reg_data |= 0xB000; -+ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 0 2 bit 6 set 0, bit13 set to 1, bit12 0*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFFFFBF; -+ reg_data |= 0x2000; -+ reg_data &= 0xffffefff; -+ -+ if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) -+ return retVal; -+ if (pPortAbility->txpause) -+ reg_data |= 0x80; -+ else -+ reg_data &= 0xffffff7f; -+ if (pPortAbility->rxpause) -+ reg_data |= 0x100; -+ else -+ reg_data &= 0xfffffeff; -+ if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 4 0 bit 12 set 0*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFFEFFF; -+ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) -+ return retVal; -+ /*sds_mode:*/ -+ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x7)) != RT_ERR_OK) -+ return retVal; -+ -+ } -+ -+ /*disable force ability --- */ -+ if((retVal = rtl8367c_setAsicRegBit(0x137c, 12, 0)) != RT_ERR_OK) -+ return retVal; -+ return RT_ERR_OK; -+ -+ } -+ -+ /* new_cfg_sds_mode */ -+ if((retVal = rtl8367c_getAsicRegBits(0x1d95, 0x1f00, ®Value2)) != RT_ERR_OK) -+ return retVal; -+ if(regValue2 == 0x2) -+ { -+#if 0 -+ /*SGMII*/ -+ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) -+ return retVal; -+#endif -+ if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ for(i=0;i<0xfff; i++); -+ -+ /* 0 2 0 bit 8-9 nway*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xfffffcff; -+ if (pPortAbility->nway) -+ reg_data &= 0xfffffcff; -+ else -+ reg_data |= 0x100; -+ if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x2)) != RT_ERR_OK) -+ return retVal; -+ -+ for(i=0;i<0xfff; i++); -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_FDUP_OFFSET, pPortAbility->duplex)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_SPD_MASK, pPortAbility->speed)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_TXFC_OFFSET, pPortAbility->txpause)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_RXFC_OFFSET, pPortAbility->rxpause)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_LINK_OFFSET, pPortAbility->link)) != RT_ERR_OK) -+ return retVal; -+ -+ /*disable force ability --- */ -+ if((retVal = rtl8367c_setAsicRegBit(0x137c, 12, 0)) != RT_ERR_OK) -+ return retVal; -+ return RT_ERR_OK; -+ } -+ else if(regValue2 == 0x12) -+ { -+#if 0 -+ /*HiSGMII*/ -+ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) -+ return retVal; -+#endif -+ if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ for(i=0;i<0xfff; i++); -+ -+ /* 0 2 0 bit 8-9 nway*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xfffffcff; -+ if (pPortAbility->nway) -+ reg_data &= 0xfffffcff; -+ else -+ reg_data |= 0x100; -+ if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ -+ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x12)) != RT_ERR_OK) -+ return retVal; -+ -+ for(i=0;i<0xfff; i++); -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 0x1)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_FDUP_OFFSET, pPortAbility->duplex)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_SPD_MASK, pPortAbility->speed)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_TXFC_OFFSET, pPortAbility->txpause)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_RXFC_OFFSET, pPortAbility->rxpause)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_LINK_OFFSET, pPortAbility->link)) != RT_ERR_OK) -+ return retVal; -+ -+ /*disable force ability --- */ -+ if((retVal = rtl8367c_setAsicRegBit(0x137c, 12, 0)) != RT_ERR_OK) -+ return retVal; -+ return RT_ERR_OK; -+ -+ } -+ } -+ else -+ { -+ if((retVal = rtl8367c_getAsicRegBits(0x1d3d, 10, ®Value2)) != RT_ERR_OK) -+ return retVal; -+ if (regValue2 == 0) -+ { -+ /*ext1_force_ablty*/ -+ if((retVal = rtl8367c_setAsicRegBit(0x1311, 2, pPortAbility->duplex)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBits(0x1311, 0x3, pPortAbility->speed)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, pPortAbility->link)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x1311, 6, pPortAbility->txpause)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x1311, 5, pPortAbility->rxpause)) != RT_ERR_OK) -+ return retVal; -+ -+ /*force mode for ext1*/ -+ if((retVal = rtl8367c_setAsicRegBit(0x1311, 12, pPortAbility->forcemode)) != RT_ERR_OK) -+ return retVal; -+ -+ if (pPortAbility->link == 1) -+ { -+ if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, 1)) != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ if((retVal = rtl8367c_setAsicRegBits(0x1311, 0x3, 2)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ /*disable force ability --- */ -+ if((retVal = rtl8367c_setAsicRegBit(0x137c, 12, 0)) != RT_ERR_OK) -+ return retVal; -+ return RT_ERR_OK; -+ } -+ } -+ -+ -+ } -+ else if (2 == id) -+ { -+ -+ if((retVal = rtl8367c_getAsicRegBit(0x1d95, 0, &sgmiibit)) != RT_ERR_OK) -+ return retVal; -+ if (sgmiibit == 1) -+ { -+ /*for 1000x/100fx/1000x_100fx, param has to bet set to serdes registers*/ -+ if((retVal = rtl8367c_getAsicReg(0x1d95, ®Value)) != RT_ERR_OK) -+ return retVal; -+ /*cfg_mac7_sel_sgmii=1 & cfg_mac7_fib =1*/ -+ if((regValue & 0x3) == 0x3) -+ { -+ if((retVal = rtl8367c_getAsicRegBits(0x1d95, 0x1f00, ®Value2)) != RT_ERR_OK) -+ return retVal; -+ -+ if(regValue2 == 0x4) -+ { -+ /*1000X*/ -+#if 0 -+ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) -+ return retVal; -+#endif -+ if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 4 0 bit 12 set 1, bit15~13 = 4*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFF0FFF; -+ reg_data |= 0x9000; -+ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 0 2 bit 6 set 1, bit13 set to 0, bit12 nway_en*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFFDFFF; -+ reg_data |= 0x40; -+ if(pPortAbility->forcemode) -+ reg_data &= 0xffffefff; -+ else -+ reg_data |= 0x1000; -+ -+ if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) -+ return retVal; -+ if (pPortAbility->txpause) -+ reg_data |= 0x80; -+ else -+ reg_data &= 0xffffff7f; -+ if (pPortAbility->rxpause) -+ reg_data |= 0x100; -+ else -+ reg_data &= 0xfffffeff; -+ if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 4 0 bit 12 set 0*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFFEFFF; -+ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x4)) != RT_ERR_OK) -+ return retVal; -+ -+ } -+ else if(regValue2 == 0x5) -+ { -+ /*100FX*/ -+#if 0 -+ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) -+ return retVal; -+#endif -+ if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 4 0 bit 12 set 1, bit15~13 = 5*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFF0FFF; -+ reg_data |= 0xB000; -+ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 0 2 bit 6 set 0, bit13 set to 1, bit12 0*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFFFFBF; -+ reg_data |= 0x2000; -+ reg_data &= 0xffffefff; -+ -+ if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) -+ return retVal; -+ if (pPortAbility->txpause) -+ reg_data |= 0x80; -+ else -+ reg_data &= 0xffffff7f; -+ if (pPortAbility->rxpause) -+ reg_data |= 0x100; -+ else -+ reg_data &= 0xfffffeff; -+ if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 4 0 bit 12 set 0*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFFEFFF; -+ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x5)) != RT_ERR_OK) -+ return retVal; -+ -+ } -+ else if(regValue2 == 0x7) -+ { -+ /*100FX*/ -+#if 0 -+ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) -+ return retVal; -+#endif -+ if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 4 0 bit 12 set 1, bit15~13 = 4*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFF0FFF; -+ reg_data |= 0x9000; -+ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 0 2 bit 6 set 1, bit13 set to 0, bit12 nway_en*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFFDFFF; -+ reg_data |= 0x40; -+ if(pPortAbility->forcemode) -+ reg_data &= 0xffffefff; -+ else -+ reg_data |= 0x1000; -+ -+ if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) -+ return retVal; -+ if (pPortAbility->txpause) -+ reg_data |= 0x80; -+ else -+ reg_data &= 0xffffff7f; -+ if (pPortAbility->rxpause) -+ reg_data |= 0x100; -+ else -+ reg_data &= 0xfffffeff; -+ if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 4 0 bit 12 set 0*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFFEFFF; -+ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 4 0 bit 12 set 1, bit15~13 = 5*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFF0FFF; -+ reg_data |= 0xB000; -+ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 0 2 bit 6 set 0, bit13 set to 1, bit12 0*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFFFFBF; -+ reg_data |= 0x2000; -+ reg_data &= 0xffffefff; -+ -+ if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) -+ return retVal; -+ if (pPortAbility->txpause) -+ reg_data |= 0x80; -+ else -+ reg_data &= 0xffffff7f; -+ if (pPortAbility->rxpause) -+ reg_data |= 0x100; -+ else -+ reg_data &= 0xfffffeff; -+ if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 4 0 bit 12 set 0*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFFEFFF; -+ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x7)) != RT_ERR_OK) -+ return retVal; -+ -+ } -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x137d, 12, 0)) != RT_ERR_OK) -+ return retVal; -+ return RT_ERR_OK; -+ -+ } -+ /* new_cfg_sds_mode */ -+ if((retVal = rtl8367c_getAsicRegBits(0x1d95, 0x1f00, ®Value2)) != RT_ERR_OK) -+ return retVal; -+ if(regValue2 == 0x2) -+ { -+ /*SGMII*/ -+#if 0 -+ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) -+ return retVal; -+#endif -+ if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ for(i=0;i<0xfff; i++); -+ -+ /* 0 2 0 bit 8-9 nway*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xfffffcff; -+ if (pPortAbility->nway) -+ reg_data &= 0xfffffcff; -+ else -+ reg_data |= 0x100; -+ if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x2)) != RT_ERR_OK) -+ return retVal; -+ -+ for(i=0;i<0xfff; i++); -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_FDUP_OFFSET, pPortAbility->duplex)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_SPD_MASK, pPortAbility->speed)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_TXFC_OFFSET, pPortAbility->txpause)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_RXFC_OFFSET, pPortAbility->rxpause)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_LINK_OFFSET, pPortAbility->link)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x137d, 12, 0)) != RT_ERR_OK) -+ return retVal; -+ return RT_ERR_OK; -+ } -+ } -+ else -+ { -+ -+ /*ext2_force_ablty*/ -+ if((retVal = rtl8367c_setAsicRegBit(0x13c4, 2, pPortAbility->duplex)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBits(0x13c4, 0x3, pPortAbility->speed)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x13c4, 4, pPortAbility->link)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x13c4, 6, pPortAbility->txpause)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x13c4, 5, pPortAbility->rxpause)) != RT_ERR_OK) -+ return retVal; -+ -+ /*force mode for ext2*/ -+ if((retVal = rtl8367c_setAsicRegBit(0x13c4, 12, pPortAbility->forcemode)) != RT_ERR_OK) -+ return retVal; -+ -+ if (pPortAbility->link == 1) -+ { -+ if((retVal = rtl8367c_setAsicRegBit(0x13c4, 4, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x13c4, 4, 1)) != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ if((retVal = rtl8367c_setAsicRegBits(0x13c4, 0x3, 2)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ -+ if((retVal = rtl8367c_getAsicRegBit(0x1d3d, 10, ®_data)) != RT_ERR_OK) -+ return retVal; -+ if(reg_data == 1) -+ { -+ if((retVal = rtl8367c_setAsicRegBit(0x1311, 2, pPortAbility->duplex)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBits(0x1311, 0x3, pPortAbility->speed)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, pPortAbility->link)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x1311, 6, pPortAbility->txpause)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x1311, 5, pPortAbility->rxpause)) != RT_ERR_OK) -+ return retVal; -+ -+ /*force mode for ext1*/ -+ if((retVal = rtl8367c_setAsicRegBit(0x1311, 12, pPortAbility->forcemode)) != RT_ERR_OK) -+ return retVal; -+ -+ if (pPortAbility->link == 1) -+ { -+ if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, 1)) != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ if((retVal = rtl8367c_setAsicRegBits(0x1311, 0x3, 2)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ -+ -+ } -+ -+ /*disable force ability --- */ -+ if((retVal = rtl8367c_setAsicRegBit(0x137d, 12, 0)) != RT_ERR_OK) -+ return retVal; -+ } -+#if 0 -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_FDUP_OFFSET, pPortAbility->duplex)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_SPD_MASK, pPortAbility->speed)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_TXFC_OFFSET, pPortAbility->txpause)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_RXFC_OFFSET, pPortAbility->rxpause)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_LINK_OFFSET, pPortAbility->link)) != RT_ERR_OK) -+ return retVal; -+#endif -+ } -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicPortForceLinkExt -+ * Description: -+ * Get external interface force linking configuration -+ * Input: -+ * id - external interface id (0~1) -+ * pPortAbility - port ability configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortForceLinkExt(rtk_uint32 id, rtl8367c_port_ability_t *pPortAbility) -+{ -+ rtk_uint32 reg_data, regValue, type; -+ rtk_uint32 sgmiiSel; -+ rtk_uint32 hsgmiiSel; -+ ret_t retVal; -+ -+ /* Invalid input parameter */ -+ if(id >= RTL8367C_EXTNO) -+ return RT_ERR_OUT_OF_RANGE; -+ /*cfg_magic_id & get chip_id*/ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) -+ return retVal; -+ -+ type = 0; -+ -+ switch (regValue) -+ { -+ case 0x0276: -+ case 0x0597: -+ case 0x6367: -+ type = 1; -+ break; -+ case 0x0652: -+ case 0x6368: -+ type = 2; -+ break; -+ case 0x0801: -+ case 0x6511: -+ type = 3; -+ break; -+ default: -+ return RT_ERR_FAILED; -+ } -+ -+ if (1 == type) -+ { -+ if(1 == id) -+ { -+ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_SGMII_OFFSET, &sgmiiSel)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET, &hsgmiiSel)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (sgmiiSel == 1) || (hsgmiiSel == 1) ) -+ { -+ memset(pPortAbility, 0x00, sizeof(rtl8367c_port_ability_t)); -+ pPortAbility->forcemode = 1; -+ -+ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_FDUP_OFFSET, ®_data)) != RT_ERR_OK) -+ return retVal; -+ -+ pPortAbility->duplex = reg_data; -+ -+ if((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_SPD_MASK, ®_data)) != RT_ERR_OK) -+ return retVal; -+ -+ pPortAbility->speed = reg_data; -+ -+ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_LINK_OFFSET, ®_data)) != RT_ERR_OK) -+ return retVal; -+ -+ pPortAbility->link = reg_data; -+ -+ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_TXFC_OFFSET, ®_data)) != RT_ERR_OK) -+ return retVal; -+ -+ pPortAbility->txpause = reg_data; -+ -+ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_RXFC_OFFSET, ®_data)) != RT_ERR_OK) -+ return retVal; -+ -+ pPortAbility->rxpause = reg_data; -+ -+ return RT_ERR_OK; -+ } -+ } -+ -+ if(0 == id || 1 == id) -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_DIGITAL_INTERFACE0_FORCE+id, ®_data); -+ else -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_DIGITAL_INTERFACE2_FORCE, ®_data); -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ pPortAbility->forcemode = (reg_data >> 12) & 0x0001; -+ pPortAbility->mstfault = (reg_data >> 9) & 0x0001; -+ pPortAbility->mstmode = (reg_data >> 8) & 0x0001; -+ pPortAbility->nway = (reg_data >> 7) & 0x0001; -+ pPortAbility->txpause = (reg_data >> 6) & 0x0001; -+ pPortAbility->rxpause = (reg_data >> 5) & 0x0001; -+ pPortAbility->link = (reg_data >> 4) & 0x0001; -+ pPortAbility->duplex = (reg_data >> 2) & 0x0001; -+ pPortAbility->speed = reg_data & 0x0003; -+ } -+ else if (2 == type) -+ { -+ if (id == 1) -+ { -+ if ((retVal = rtl8367c_getAsicReg(0x1311, ®_data))!=RT_ERR_OK) -+ return retVal; -+ -+ pPortAbility->forcemode = (reg_data >> 12) & 1; -+ pPortAbility->duplex = (reg_data >> 2) & 1; -+ pPortAbility->link = (reg_data >> 4) & 1; -+ pPortAbility->speed = reg_data & 3; -+ pPortAbility->rxpause = (reg_data >> 5) & 1; -+ pPortAbility->txpause = (reg_data >> 6) & 1; -+ } -+ else if (2 == id) -+ { -+ if ((retVal = rtl8367c_getAsicReg(0x13c4, ®_data))!=RT_ERR_OK) -+ return retVal; -+ -+ pPortAbility->forcemode = (reg_data >> 12) & 1; -+ pPortAbility->duplex = (reg_data >> 2) & 1; -+ pPortAbility->link = (reg_data >> 4) & 1; -+ pPortAbility->speed = reg_data & 3; -+ pPortAbility->rxpause = (reg_data >> 5) & 1; -+ pPortAbility->txpause = (reg_data >> 6) & 1; -+ } -+ } -+ else if (3 == type) -+ { -+ if (id == 1) -+ { -+ if ((retVal = rtl8367c_getAsicReg(0x1311, ®_data))!=RT_ERR_OK) -+ return retVal; -+ -+ pPortAbility->forcemode = (reg_data >> 12) & 1; -+ pPortAbility->duplex = (reg_data >> 2) & 1; -+ pPortAbility->link = (reg_data >> 4) & 1; -+ pPortAbility->speed = reg_data & 3; -+ pPortAbility->rxpause = (reg_data >> 5) & 1; -+ pPortAbility->txpause = (reg_data >> 6) & 1; -+ } -+ else if (2 == id) -+ { -+ if ((retVal = rtl8367c_getAsicReg(0x13c4, ®_data))!=RT_ERR_OK) -+ return retVal; -+ -+ pPortAbility->forcemode = (reg_data >> 12) & 1; -+ pPortAbility->duplex = (reg_data >> 2) & 1; -+ pPortAbility->link = (reg_data >> 4) & 1; -+ pPortAbility->speed = reg_data & 3; -+ pPortAbility->rxpause = (reg_data >> 5) & 1; -+ pPortAbility->txpause = (reg_data >> 6) & 1; -+ } -+ } -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicPortExtMode -+ * Description: -+ * Set external interface mode configuration -+ * Input: -+ * id - external interface id (0~2) -+ * mode - external interface mode -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortExtMode(rtk_uint32 id, rtk_uint32 mode) -+{ -+ ret_t retVal; -+ rtk_uint32 i, regValue, type, option,reg_data; -+ rtk_uint32 idx; -+ rtk_uint32 redData[][2] = { {0x04D7, 0x0480}, {0xF994, 0x0481}, {0x21A2, 0x0482}, {0x6960, 0x0483}, {0x9728, 0x0484}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x83F2, 0x002E} }; -+ rtk_uint32 redDataSB[][2] = { {0x04D7, 0x0480}, {0xF994, 0x0481}, {0x31A2, 0x0482}, {0x6960, 0x0483}, {0x9728, 0x0484}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x83F2, 0x002E} }; -+ rtk_uint32 redData1[][2] = { {0x82F1, 0x0500}, {0xF195, 0x0501}, {0x31A2, 0x0502}, {0x796C, 0x0503}, {0x9728, 0x0504}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x0F80, 0x0001}, {0x83F2, 0x002E} }; -+ rtk_uint32 redData5[][2] = { {0x82F1, 0x0500}, {0xF195, 0x0501}, {0x31A2, 0x0502}, {0x796C, 0x0503}, {0x9728, 0x0504}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x0F80, 0x0001}, {0x83F2, 0x002E} }; -+ rtk_uint32 redData6[][2] = { {0x82F1, 0x0500}, {0xF195, 0x0501}, {0x31A2, 0x0502}, {0x796C, 0x0503}, {0x9728, 0x0504}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x0F80, 0x0001}, {0x83F2, 0x002E} }; -+ rtk_uint32 redData8[][2] = { {0x82F1, 0x0500}, {0xF995, 0x0501}, {0x31A2, 0x0502}, {0x796C, 0x0503}, {0x9728, 0x0504}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x0F80, 0x0001}, {0x83F2, 0x002E} }; -+ rtk_uint32 redData9[][2] = { {0x82F1, 0x0500}, {0xF995, 0x0501}, {0x31A2, 0x0502}, {0x796C, 0x0503}, {0x9728, 0x0504}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x0F80, 0x0001}, {0x83F2, 0x002E} }; -+ rtk_uint32 redDataHB[][2] = { {0x82F0, 0x0500}, {0xF195, 0x0501}, {0x31A2, 0x0502}, {0x7960, 0x0503}, {0x9728, 0x0504}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x0F80, 0x0001}, {0x83F2, 0x002E} }; -+ -+ if(id >= RTL8367C_EXTNO) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(mode >= EXT_END) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ /* magic number*/ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) -+ return retVal; -+ /* Chip num */ -+ if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) -+ return retVal; -+ -+ type = 0; -+ -+ switch (regValue) -+ { -+ case 0x0276: -+ case 0x0597: -+ case 0x6367: -+ type = 1; -+ break; -+ case 0x0652: -+ case 0x6368: -+ type = 2; -+ break; -+ case 0x0801: -+ case 0x6511: -+ type = 3; -+ break; -+ default: -+ return RT_ERR_FAILED; -+ } -+ -+ -+ if (1==type) -+ { -+ if((mode == EXT_1000X_100FX) || (mode == EXT_1000X) || (mode == EXT_100FX)) -+ { -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_REG_TO_ECO4, 5, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_REG_TO_ECO4, 7, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_CHIP_RESET, RTL8367C_DW8051_RST_OFFSET, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MISCELLANEOUS_CONFIGURE0, RTL8367C_DW8051_EN_OFFSET, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_ACS_IROM_ENABLE_OFFSET, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_IROM_MSB_OFFSET, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if(mode == EXT_1000X_100FX) -+ { -+ for(idx = 0; idx < FIBER2_AUTO_INIT_SIZE; idx++) -+ { -+ if ((retVal = rtl8367c_setAsicReg(0xE000 + idx, (rtk_uint32)Fiber2_Auto[idx])) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ -+ if(mode == EXT_1000X) -+ { -+ for(idx = 0; idx < FIBER2_1G_INIT_SIZE; idx++) -+ { -+ if ((retVal = rtl8367c_setAsicReg(0xE000 + idx, (rtk_uint32)Fiber2_1G[idx])) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ -+ if(mode == EXT_100FX) -+ { -+ for(idx = 0; idx < FIBER2_100M_INIT_SIZE; idx++) -+ { -+ if ((retVal = rtl8367c_setAsicReg(0xE000 + idx, (rtk_uint32)Fiber2_100M[idx])) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ -+ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_IROM_MSB_OFFSET, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_ACS_IROM_ENABLE_OFFSET, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_CHIP_RESET, RTL8367C_DW8051_RST_OFFSET, 0)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ if(mode == EXT_GMII) -+ { -+ if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_EXT0_RGMXF, RTL8367C_EXT0_RGTX_INV_OFFSET, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_EXT1_RGMXF, RTL8367C_EXT1_RGTX_INV_OFFSET, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_EXT_TXC_DLY, RTL8367C_EXT1_GMII_TX_DELAY_MASK, 5)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_EXT_TXC_DLY, RTL8367C_EXT0_GMII_TX_DELAY_MASK, 6)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ /* Serdes reset */ -+ if( (mode == EXT_TMII_MAC) || (mode == EXT_TMII_PHY) ) -+ { -+ if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_BYPASS_LINE_RATE, id, 1)) != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_BYPASS_LINE_RATE, id, 0)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ if( (mode == EXT_SGMII) || (mode == EXT_HSGMII) ) -+ { -+ if(id != 1) -+ return RT_ERR_PORT_ID; -+ -+ if((retVal = rtl8367c_setAsicReg(0x13C0, 0x0249)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicReg(0x13C1, &option)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x13C0, 0x0000)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ if(mode == EXT_SGMII) -+ { -+ if(option == 0) -+ { -+ for(i = 0; i <= 7; i++) -+ { -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redData[i][0])) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redData[i][1])) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ else -+ { -+ for(i = 0; i <= 7; i++) -+ { -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redDataSB[i][0])) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redDataSB[i][1])) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ } -+ -+ if(mode == EXT_HSGMII) -+ { -+ if(option == 0) -+ { -+ if( (retVal = rtl8367c_setAsicReg(0x13c2, 0x0249)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_getAsicReg(0x1301, ®Value)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(0x13c2, 0x0000)) != RT_ERR_OK) -+ return retVal; -+ -+ if ( ((regValue & 0x00F0) >> 4) == 0x0001) -+ { -+ for(i = 0; i <= 8; i++) -+ { -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redData1[i][0])) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redData1[i][1])) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ else if ( ((regValue & 0x00F0) >> 4) == 0x0005) -+ { -+ for(i = 0; i <= 8; i++) -+ { -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redData5[i][0])) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redData5[i][1])) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ else if ( ((regValue & 0x00F0) >> 4) == 0x0006) -+ { -+ for(i = 0; i <= 8; i++) -+ { -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redData6[i][0])) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redData6[i][1])) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ else if ( ((regValue & 0x00F0) >> 4) == 0x0008) -+ { -+ for(i = 0; i <= 8; i++) -+ { -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redData8[i][0])) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redData8[i][1])) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ else if ( ((regValue & 0x00F0) >> 4) == 0x0009) -+ { -+ for(i = 0; i <= 8; i++) -+ { -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redData9[i][0])) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redData9[i][1])) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ } -+ else -+ { -+ for(i = 0; i <= 8; i++) -+ { -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redDataHB[i][0])) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redDataHB[i][1])) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ } -+ -+ /* Only one ext port should care SGMII setting */ -+ if(id == 1) -+ { -+ -+ if(mode == EXT_SGMII) -+ { -+ if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_SGMII_OFFSET, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET, 0)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if(mode == EXT_HSGMII) -+ { -+ if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_SGMII_OFFSET, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET, 1)) != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ -+ if((mode != EXT_1000X_100FX) && (mode != EXT_1000X) && (mode != EXT_100FX)) -+ { -+ if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_SGMII_OFFSET, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET, 0)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ } -+ -+ if(0 == id || 1 == id) -+ { -+ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_DIGITAL_INTERFACE_SELECT, RTL8367C_SELECT_GMII_0_MASK << (id * RTL8367C_SELECT_GMII_1_OFFSET), mode)) != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_DIGITAL_INTERFACE_SELECT_1, RTL8367C_SELECT_GMII_2_MASK, mode)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ /* Serdes not reset */ -+ if( (mode == EXT_SGMII) || (mode == EXT_HSGMII) ) -+ { -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x7106)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0003)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ if( (mode == EXT_SGMII) || (mode == EXT_HSGMII) ) -+ { -+ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_CHIP_RESET, RTL8367C_DW8051_RST_OFFSET, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MISCELLANEOUS_CONFIGURE0, RTL8367C_DW8051_EN_OFFSET, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_ACS_IROM_ENABLE_OFFSET, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_IROM_MSB_OFFSET, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ for(idx = 0; idx < SGMII_INIT_SIZE; idx++) -+ { -+ if ((retVal = rtl8367c_setAsicReg(0xE000 + idx, (rtk_uint32)Sgmii_Init[idx])) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_IROM_MSB_OFFSET, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_ACS_IROM_ENABLE_OFFSET, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_CHIP_RESET, RTL8367C_DW8051_RST_OFFSET, 0)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ else if (2 == type) -+ { -+ /* Serdes reset */ -+ if( (mode == EXT_TMII_MAC) || (mode == EXT_TMII_PHY) ) -+ { -+ if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_BYPASS_LINE_RATE, id+2, 1)) != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_BYPASS_LINE_RATE, id+2, 0)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ /*set MAC mode*/ -+ if (id == 1) -+ { -+ if(mode == EXT_HSGMII) -+ return RT_ERR_PORT_ID; -+ -+ if (mode == EXT_SGMII) -+ { -+ /*cfg port8 with MII mac mode*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*enable port8 SGMII*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 14, 1)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if (mode == EXT_1000X || mode == EXT_100FX || mode == EXT_1000X_100FX) -+ { -+ /*cfg port8 with MII mac mode*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*disable port8 SGMII*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 14, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*set fiber link up*/ -+ if((retVal = rtl8367c_setAsicRegBit(0x6210, 11, 0)) != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ /*cfg port8 with MII mac mode*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, mode)) != RT_ERR_OK) -+ return retVal; -+ -+ /*disable port8 SGMII*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 14, 0)) != RT_ERR_OK) -+ return retVal; -+ } -+ /*disable SDS 1*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 0x1f)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if(id == 2) -+ { -+ if (mode == EXT_HSGMII) -+ { -+ if ((retVal = rtl8367c_setAsicReg(0x130, 7)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicReg(0x39f, 7)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicReg(0x3fa, 7)) != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ if ((retVal = rtl8367c_setAsicReg(0x130, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicReg(0x39f, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicReg(0x3fa, 4)) != RT_ERR_OK) -+ return retVal; -+ -+ } -+ -+ -+ if (mode == EXT_SGMII) -+ { -+ /*cfg port9 with MII mac mode*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*enable port9 SGMII*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 6, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /*disable port9 HSGMII*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 7, 0)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if (mode == EXT_HSGMII) -+ { -+ /*cfg port9 with MII mac mode*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*disable port9 SGMII*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 6, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*enable port9 HSGMII*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 7, 1)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if (mode == EXT_1000X || mode == EXT_100FX || mode == EXT_1000X_100FX) -+ { -+ /*cfg port9 with MII mac mode*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*disable port9 SGMII*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 6, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*disable port9 HSGMII*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 7, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*set fiber link up*/ -+ if((retVal = rtl8367c_setAsicRegBit(0x6200, 11, 0)) != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ /*cfg port9 with MII mac mode*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, mode)) != RT_ERR_OK) -+ return retVal; -+ -+ /*disable port9 SGMII*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 6, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*disable port9 HSGMII*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 7, 0)) != RT_ERR_OK) -+ return retVal; -+ } -+ /*disable SDS 0*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 0x1f)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ /*SET TO RGMII MODE*/ -+ if (mode == EXT_RGMII) -+ { -+ /*disable paral led pad*/ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PARA_LED_IO_EN3, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PARA_LED_IO_EN1, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PARA_LED_IO_EN2, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*set MAC8 mode*/ -+ if (id == 1) -+ { -+ /*1: RGMII1 bias work at 3.3V, 0: RGMII1 bias work at 2.5V*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1303, 9, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /*drving 1*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1303, 6, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /*drving 1*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1303, 4, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /*show rate = 0*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1303, 1, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*EXT1 RGMII TXC delay 2ns*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1307, 3, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_Ext1_rgtxc_dly = 0*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x13f9, 0x38, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*RXDLY = 0*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1307, 0x7, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_rg1_dn = 4*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1304, 0x7000, 4)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_rg1_dp = 4*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x13f9, 0x700, 4)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if (id == 2) -+ { -+ /*1: RGMII1 bias work at 3.3V, 0: RGMII1 bias work at 2.5V*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1303, 10, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /*drving 1*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x13e2, 2, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /*drving 1*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x13e2, 1, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /*show rate = 0*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x13e2, 0, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*EXT1 RGMII TXC delay 2ns*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x13c5, 3, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_Ext1_rgtxc_dly = 0*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x13f9, 0x1c0, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*RXDLY = 0*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x13c5, 0x7, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_rg1_dn = 4*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x13e2, 0x1c0, 4)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_rg1_dp = 4*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x13e2, 0x38, 4)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ else if (mode == EXT_SGMII) -+ { -+ if (id == 1) -+ { -+ /*sds 1 reg 1 page 0x21 write value 0xec91*/ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0xec91)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x21<<5) | 1)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C1)) != RT_ERR_OK) -+ return retVal; -+ -+ /*sds 1 reg 5 page 0x24 write value 0x5825*/ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x5825)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x24<<5) | 5)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C1)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 2)) != RT_ERR_OK) -+ return retVal; -+ -+ /*?????????????????*/ -+ -+ } -+ else if (id == 2) -+ { -+ /*sds 0 reg 0 page 0x28 write value 0x942c*/ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x942c)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x28<<5) | 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*sds 0 reg 0 page 0x24 write value 0x942c*/ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x942c)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x24<<5) | 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*sds 0 reg 5 page 0x21 write value 0x8dc3*/ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x8dc3)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x21<<5) | 5)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 2)) != RT_ERR_OK) -+ return retVal; -+ -+ /*?????????????????*/ -+ } -+ } -+ else if (mode == EXT_HSGMII) -+ { -+ if (id == 2) -+ { -+ /*sds 0 reg 0 page 0x28 write value 0x942c*/ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x942c)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x28<<5) | 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*sds 0 reg 0 page 0x24 write value 0x942c*/ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x942c)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x24<<5) | 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*sds 0 reg 5 page 0x21 write value 0x8dc3*/ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x8dc3)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x21<<5) | 5)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) -+ return retVal; -+ -+ -+ /* optimizing HISGMII performance while RGMII used & */ -+ /*sds 0 reg 9 page 0x21 write value 0x3931*/ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x3931)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x21<<5)|9) ) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) -+ return retVal; -+ -+ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 0x12)) != RT_ERR_OK) -+ return retVal; -+ -+ /*?????????????????*/ -+ } -+ } -+ else if (mode == EXT_1000X) -+ { -+ if (id == 1) -+ { -+ -+ if( (retVal = rtl8367c_setAsicSdsReg(1, 1, 0x21, 0xec91)) != RT_ERR_OK) -+ return retVal; -+ if( (retVal = rtl8367c_setAsicSdsReg(1, 5, 0x24, 0x5825)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 4)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 0x1f)) != RT_ERR_OK) -+ return retVal; -+ -+ /*patch speed change sds1 1000M*/ -+ if( (retVal = rtl8367c_getAsicSdsReg(1, 4, 0, ®Value)) != RT_ERR_OK) -+ return retVal; -+ regValue &= 0xFFFF0FFF; -+ regValue |= 0x9000; -+ if( (retVal = rtl8367c_setAsicSdsReg(1, 4, 0, regValue)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_getAsicSdsReg(1, 0, 2, ®Value)) != RT_ERR_OK) -+ return retVal; -+ regValue &= 0xFFFFdFFF; -+ regValue |= 0x40; -+ if( (retVal = rtl8367c_setAsicSdsReg(1, 0, 2, regValue)) != RT_ERR_OK) -+ return retVal; -+ -+ -+ if( (retVal = rtl8367c_getAsicSdsReg(1, 4, 0, ®Value)) != RT_ERR_OK) -+ return retVal; -+ regValue &= 0xFFFFEFFF; -+ if( (retVal = rtl8367c_setAsicSdsReg(1, 4, 0, regValue)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 4)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x6000, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ } -+ else if (id == 2) -+ { -+ if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 0x28, 0x942c)) != RT_ERR_OK) -+ return retVal; -+ if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 0x24, 0x942c)) != RT_ERR_OK) -+ return retVal; -+ if( (retVal = rtl8367c_setAsicSdsReg(0, 5, 0x21, 0x8dc3)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 4)) != RT_ERR_OK) -+ return retVal; -+ -+ /*patch speed change sds0 1000M*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 0x1f)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®Value)) != RT_ERR_OK) -+ return retVal; -+ regValue &= 0xFFFF0FFF; -+ regValue |= 0x9000; -+ if( (retVal = rtl8367c_setAsicSdsReg(0, 4, 0, regValue)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®Value)) != RT_ERR_OK) -+ return retVal; -+ regValue &= 0xFFFFDFFF; -+ regValue |= 0x40; -+ if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 2, regValue)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®Value)) != RT_ERR_OK) -+ return retVal; -+ regValue &= 0xFFFFEFFF; -+ if( (retVal = rtl8367c_setAsicSdsReg(0, 4, 0, regValue)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 4)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0xe0, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ } -+ } -+ else if (mode == EXT_100FX) -+ { -+ if (id == 1) -+ { -+ if( (retVal = rtl8367c_setAsicSdsReg(1, 1, 0x21, 0xec91)) != RT_ERR_OK) -+ return retVal; -+ if( (retVal = rtl8367c_setAsicSdsReg(1, 5, 0x24, 0x5825)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 5)) != RT_ERR_OK) -+ return retVal; -+ -+ /*patch speed change sds1 100M*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 0x1f)) != RT_ERR_OK) -+ return retVal; -+ if( (retVal = rtl8367c_getAsicSdsReg(1, 4, 0, ®Value)) != RT_ERR_OK) -+ return retVal; -+ regValue &= 0xFFFF0FFF; -+ regValue |= 0xb000; -+ if( (retVal = rtl8367c_setAsicSdsReg(1, 4, 0, regValue)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_getAsicSdsReg(1, 0, 2, ®Value)) != RT_ERR_OK) -+ return retVal; -+ regValue &= 0xFFFFFFBF; -+ regValue |= 0x2000; -+ if( (retVal = rtl8367c_setAsicSdsReg(1, 0, 2, regValue)) != RT_ERR_OK) -+ return retVal; -+#if 0 -+ if( (retVal = rtl8367c_setAsicReg(0x6214, 0x1a0)) != RT_ERR_OK) -+ return retVal; -+#endif -+ if( (retVal = rtl8367c_getAsicSdsReg(1, 4, 0, ®Value)) != RT_ERR_OK) -+ return retVal; -+ regValue &= 0xFFFFEFFF; -+ if( (retVal = rtl8367c_setAsicSdsReg(1, 4, 0, regValue)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 5)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x6000, 0)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if (id == 2) -+ { -+ if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 0x28, 0x942c)) != RT_ERR_OK) -+ return retVal; -+ if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 0x24, 0x942c)) != RT_ERR_OK) -+ return retVal; -+ if( (retVal = rtl8367c_setAsicSdsReg(0, 5, 0x21, 0x8dc3)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 5)) != RT_ERR_OK) -+ return retVal; -+ -+ /*patch speed change sds0 100M*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 0x1f)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®Value)) != RT_ERR_OK) -+ return retVal; -+ regValue &= 0xFFFF0FFF; -+ regValue |= 0xb000; -+ if( (retVal = rtl8367c_setAsicSdsReg(0, 4, 0, regValue)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®Value)) != RT_ERR_OK) -+ return retVal; -+ regValue &= 0xFFFFFFBF; -+ regValue |= 0x2000; -+ if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 2, regValue)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®Value)) != RT_ERR_OK) -+ return retVal; -+ regValue &= 0xFFFFEFFF; -+ if( (retVal = rtl8367c_setAsicSdsReg(0, 4, 0, regValue)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 5)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0xe0, 0)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ else if (mode == EXT_1000X_100FX) -+ { -+ if (id == 1) -+ { -+ if( (retVal = rtl8367c_setAsicSdsReg(1, 1, 0x21, 0xec91)) != RT_ERR_OK) -+ return retVal; -+ if( (retVal = rtl8367c_setAsicSdsReg(1, 5, 0x24, 0x5825)) != RT_ERR_OK) -+ return retVal; -+ if( (retVal = rtl8367c_setAsicSdsReg(1, 13, 0, 0x4616)) != RT_ERR_OK) -+ return retVal; -+ if( (retVal = rtl8367c_setAsicSdsReg(1, 1, 0, 0xf20)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 7)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if (id == 2) -+ { -+ if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 0x28, 0x942c)) != RT_ERR_OK) -+ return retVal; -+ if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 0x24, 0x942c)) != RT_ERR_OK) -+ return retVal; -+ if( (retVal = rtl8367c_setAsicSdsReg(0, 5, 0x21, 0x8dc3)) != RT_ERR_OK) -+ return retVal; -+ if( (retVal = rtl8367c_setAsicSdsReg(0, 13, 0, 0x4616)) != RT_ERR_OK) -+ return retVal; -+ if( (retVal = rtl8367c_setAsicSdsReg(0, 1, 0, 0xf20)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 7)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ -+ } -+ else if (3 == type) -+ { -+ -+ /*restore patch, by designer. patch Tx FIFO issue, when not HSGMII 2.5G mode -+ #sds0, page 1, reg 1, bit4=0*/ -+ if( (retVal = rtl8367c_getAsicSdsReg(0, 1, 1, ®Value)) != RT_ERR_OK) -+ return retVal; -+ regValue &= 0xFFFFFFEF; -+ if( (retVal = rtl8367c_setAsicSdsReg(0, 1, 1, regValue)) != RT_ERR_OK) -+ return retVal; -+ -+ /*set for mac 6*/ -+ if (1 == id) -+ { -+ /*force port6 linkdown*/ -+ if ((retVal = rtl8367c_setAsicReg(0x137c, 0x1000)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicRegBit(0x1d9d, 6, ®_data)) != RT_ERR_OK) -+ return retVal; -+ while(reg_data == 0) -+ { -+ if ((retVal = rtl8367c_getAsicRegBit(0x1d9d, 6, ®_data)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ if (mode == EXT_SGMII) -+ { -+ /* disable mac6 mode_ext1 mode*/ -+ if ((retVal = rtl8367c_getAsicRegBit(0x1d3d, 10, ®_data)) != RT_ERR_OK) -+ return retVal; -+ if(reg_data == 0) -+ { -+ if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 0)) != RT_ERR_OK) -+ return retVal; -+ } -+ /*cfg_bypass_line_rate[1]=0*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 1, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ -+ -+ /*bit5: cfg_mac6_fib=0 & bit7: cfg_mac6_fib2=0*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 0)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_mac7_fib=0*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 1, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_mac7_sel_sgmii= 0: MAC7 is not SGMII mode*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 0, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*#cfg_sgmii_link=0*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 9, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_mac6_sel_hsgmii=0*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ -+ /*bit13: cfg_sds_mode_sel_new=1 :Enable new sds mode config method*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 -+ new_cfg_sds_mode=0x1F (reset mode) */ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_mac6_sel_sgmii= 1*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 -+ new_cfg_sds_mode=0x12 */ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x2)) != RT_ERR_OK) -+ return retVal; -+ -+ /* MAC link source*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 2, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ -+ } -+ else if (mode == EXT_HSGMII) -+ { -+ -+ /*restore patch, by designer. patch Tx FIFO issue, when HSGMII 2.5G mode -+ #sds0, page 1, reg 1, bit4=1*/ -+ if( (retVal = rtl8367c_getAsicSdsReg(0, 1, 1, ®Value)) != RT_ERR_OK) -+ return retVal; -+ regValue |= 0x10; -+ if( (retVal = rtl8367c_setAsicSdsReg(0, 1, 1, regValue)) != RT_ERR_OK) -+ return retVal; -+ -+ /* mode_ext1 = disable*/ -+ /* disable mac6 mode_ext1 mode*/ -+ if ((retVal = rtl8367c_getAsicRegBit(0x1d3d, 10, ®_data)) != RT_ERR_OK) -+ return retVal; -+ if(reg_data == 0) -+ { -+ if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 0)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 1, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*bit5: cfg_mac6_fib=0 & bit7: cfg_mac6_fib2=0*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 0)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_mac7_fib=0*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 1, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_mac7_sel_sgmii= 0*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 0, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_mac6_sel_sgmii=0*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 9, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_mac6_sel_hsgmii=1*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_mac6_sel_sgmii= 0*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicReg(0xd0,7)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicReg(0x399, 7)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicReg(0x3fa, 7)) != RT_ERR_OK) -+ return retVal; -+ -+ /*bit13: cfg_sds_mode_sel_new=1 :Enable new sds mode config method*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) -+ return retVal; -+ /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 -+ new_cfg_sds_mode=0x12 */ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x12)) != RT_ERR_OK) -+ return retVal; -+ /* -+ 1: MAC link = SGMII SerDes link -+ 0: MAC link = SGMII config link (cfg_sgmii_link) -+ */ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 2, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ } -+ else if(mode == EXT_1000X) -+ { -+ /* 0 2 0 bit 8~9 set 0, force n-way*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFFFCFF; -+ if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* disable mac6 mode_ext1 mode*/ -+ if ((retVal = rtl8367c_getAsicRegBit(0x1d3d, 10, ®_data)) != RT_ERR_OK) -+ return retVal; -+ if(reg_data == 0) -+ { -+ if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 0)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 1, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicReg(0x1d11, 0x1500)) != RT_ERR_OK) -+ return retVal; -+ -+ /*bit13: cfg_sds_mode_sel_new=1 :Enable new sds mode config method -+ bit[1:0]:cfg_mac7_fib= 0 & cfg_mac7_sel_sgmii=0 -+ */ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /* bit0 :UTP/Fiber auto detect function enable or not, cfg_dis_det=1:disable -+ bit3:Force UTP/Fiber auto detect function enable or not, cfg_force_auto-detect=1 */ -+ if ((retVal = rtl8367c_setAsicReg(0x13eb, 0x15bb)) != RT_ERR_OK) -+ return retVal; -+ -+ /*bit3: Serdes force mode:cfg_sds_frc_mode=1 -+ bit[2:0]: Serdes chip mode, cfg_sds_mode=3b'100 (force sds FIB1G mode) */ -+ if ((retVal = rtl8367c_setAsicReg(0x13e7, 0xc)) != RT_ERR_OK) -+ return retVal; -+ -+ -+ /*bit5: cfg_mac6_fib=1 & bit7: cfg_mac6_fib2=1*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 1)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_mac6_sel_hsgmii=0*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_mac6_sel_sgmii= 1*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 -+ new_cfg_sds_mode=0x4 */ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x4)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if(mode == EXT_100FX) -+ { -+ /* 0 2 0 bit 8~9 set 0, force n-way*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFFFCFF; -+ if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* disable mac6 mode_ext1 mode*/ -+ if ((retVal = rtl8367c_getAsicRegBit(0x1d3d, 10, ®_data)) != RT_ERR_OK) -+ return retVal; -+ if(reg_data == 0) -+ { -+ if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 0)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 1, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicReg(0x1d11, 0x1500)) != RT_ERR_OK) -+ return retVal; -+ -+ /*bit13: cfg_sds_mode_sel_new=1 :Enable new sds mode config method -+ bit[1:0]:cfg_mac7_fib= 0 & cfg_mac7_sel_sgmii=0 -+ */ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /* bit0 :UTP/Fiber auto detect function enable or not, cfg_dis_det=1:disable -+ bit3:Force UTP/Fiber auto detect function enable or not, cfg_force_auto-detect=1 */ -+ if ((retVal = rtl8367c_setAsicReg(0x13eb, 0x15bb)) != RT_ERR_OK) -+ return retVal; -+ -+ /*!!!!! cfg_sds_frc_mode=1 & cfg_sds_mode=3b'101 (force sds fib100M mode)*/ -+ if ((retVal = rtl8367c_setAsicReg(0x13e7, 0xc)) != RT_ERR_OK) -+ return retVal; -+ -+ -+ /*bit5: cfg_mac6_fib=1 & bit7: cfg_mac6_fib2=1*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 1)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_mac6_sel_hsgmii=0*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_mac6_sel_sgmii= 1*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 -+ new_cfg_sds_mode=0x5 */ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x5)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if(mode == EXT_1000X_100FX) -+ { -+ /* 0 2 0 bit 8~9 set 0, force n-way*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFFFCFF; -+ if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /* disable mac6 mode_ext1 mode*/ -+ if ((retVal = rtl8367c_getAsicRegBit(0x1d3d, 10, ®_data)) != RT_ERR_OK) -+ return retVal; -+ if(reg_data == 0) -+ { -+ if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 0)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 1, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicReg(0x1d11, 0x1500)) != RT_ERR_OK) -+ return retVal; -+ -+ /*bit13: cfg_sds_mode_sel_new=1 :Enable new sds mode config method -+ bit[1:0]:cfg_mac7_fib= 0 & cfg_mac7_sel_sgmii=0 -+ */ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 0)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /* bit0 :UTP/Fiber auto detect function enable or not, cfg_dis_det=1:disable -+ bit3:Force UTP/Fiber auto detect function enable or not, cfg_force_auto-detect=1 */ -+ if ((retVal = rtl8367c_setAsicReg(0x13eb, 0x15bb)) != RT_ERR_OK) -+ return retVal; -+ -+ /*!!!!!! cfg_sds_frc_mode=1 & cfg_sds_mode=3'b111: Fib1G/Fib100M auto detect */ -+ if ((retVal = rtl8367c_setAsicReg(0x13e7, 0xc)) != RT_ERR_OK) -+ return retVal; -+ -+ -+ /*bit5: cfg_mac6_fib=1 & bit7: cfg_mac6_fib2=1*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 1)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_mac6_sel_hsgmii=0*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_mac6_sel_sgmii= 1*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 -+ new_cfg_sds_mode=0x7 */ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x7)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if(mode < EXT_SGMII) -+ { -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d3d, 10, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 1, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /* keep default setting, disable mac6 sel SerDes mode,*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 0)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*bit5: cfg_mac6_fib=0 & bit7: cfg_mac6_fib2=0*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 0)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if (mode < EXT_GMII) -+ { -+ /* set mac6 mode*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, mode)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if(mode == EXT_RMII_MAC) -+ { -+ /*!!!!!!*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 7)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if(mode == EXT_RMII_PHY) -+ { -+ if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 8)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ if ((mode == EXT_TMII_MAC) || (mode == EXT_TMII_PHY)) -+ { -+ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 1, 1)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ -+ } -+ else if (2 == id) -+ { -+ -+ /*force port7 linkdown*/ -+ if ((retVal = rtl8367c_setAsicReg(0x137d, 0x1000)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicRegBit(0x1d9d, 7, ®_data)) != RT_ERR_OK) -+ return retVal; -+ while(reg_data == 0) -+ { -+ if ((retVal = rtl8367c_getAsicRegBit(0x1d9d, 7, ®_data)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ if (mode == EXT_SGMII) -+ { -+ /*disable mac7 sel ext2 xMII mode*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf,0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*restore ext2 ability*/ -+ if ((retVal = rtl8367c_setAsicReg(0x13c4, 0)) != RT_ERR_OK) -+ return retVal; -+ /* disable mac7 mode_ext2 */ -+ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*bit5: cfg_mac6_fib=0 & bit7: cfg_mac6_fib2=0*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 0)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /* -+ bit0:cfg_mac7_sel_sgmii=0,MAC7 is not SGMII mode -+ bit1:cfg_mac7_fib= 0 */ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_mac6_sel_hsgmii=0*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_mac6_sel_sgmii= 1*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*Enable new sds mode config method, cfg_sds_mode_sel_new=1*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 -+ new_cfg_sds_mode=0x1F (reset mode) */ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_mac7_sel_sgmii= 1*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 0, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 -+ new_cfg_sds_mode=0x2 (SGMII mode)*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x2)) != RT_ERR_OK) -+ return retVal; -+ -+ /*select MAC link source when port6/7 be set sgmii mode (cfg_sgmii_link)*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 2, 0)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if (mode == EXT_1000X) -+ { -+ /* disable mac7 MII/TMM/RMII/GMII/RGMII mode, mode_ext2 = disable */ -+ if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*restore ext2 ability*/ -+ if ((retVal = rtl8367c_setAsicReg(0x13c4, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 2 0 bit 8~9 set 0, force n-way*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFFFCFF; -+ if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /*restore ext2 ability*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /* keep default setting, disable mac6 sel serdes*/ -+ if ((retVal = rtl8367c_setAsicReg(0x1d11, 0x1500)) != RT_ERR_OK) -+ return retVal; -+ -+ /*Enable new sds mode config method, cfg_sds_mode_sel_new=1*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 -+ new_cfg_sds_mode=0x1F (reset mode) */ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) -+ return retVal; -+ -+ /*bit5: cfg_mac6_fib=0 & bit7: cfg_mac6_fib2=0*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 0)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_mac7_sel_sgmii= 1 & cfg_mac7_fib=1*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 3)) != RT_ERR_OK) -+ return retVal; -+ -+ /*new_cfg_sds_mode=0x4 (FIB1000 mode)*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x4)) != RT_ERR_OK) -+ return retVal; -+ -+ } -+ else if (mode == EXT_100FX) -+ { -+ /* disable mac7 MII/TMM/RMII/GMII/RGMII mode, mode_ext2 = disable */ -+ if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*restore ext2 ability*/ -+ if ((retVal = rtl8367c_setAsicReg(0x13c4, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 2 0 bit 8~9 set 0, force n-way*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFFFCFF; -+ if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /*restore ext2 ability*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /* keep default setting, disable mac6 sel serdes*/ -+ if ((retVal = rtl8367c_setAsicReg(0x1d11, 0x1500)) != RT_ERR_OK) -+ return retVal; -+ -+ /*Enable new sds mode config method, cfg_sds_mode_sel_new=1*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 -+ new_cfg_sds_mode=0x1F (reset mode) */ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) -+ return retVal; -+ -+ /*bit5: cfg_mac6_fib=0 & bit7: cfg_mac6_fib2=0*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 0)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_mac7_sel_sgmii= 1 & cfg_mac7_fib=1*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 3)) != RT_ERR_OK) -+ return retVal; -+ -+ /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 -+ new_cfg_sds_mode=0x5 */ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x5)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if (mode == EXT_1000X_100FX) -+ { -+ /* disable mac7 MII/TMM/RMII/GMII/RGMII mode, mode_ext2 = disable */ -+ if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*restore ext2 ability*/ -+ if ((retVal = rtl8367c_setAsicReg(0x13c4, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /* 0 2 0 bit 8~9 set 0, force n-way*/ -+ if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) -+ return retVal; -+ reg_data &= 0xFFFFFCFF; -+ if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) -+ return retVal; -+ -+ /*restore ext2 ability*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /* keep default setting, disable mac6 sel serdes*/ -+ if ((retVal = rtl8367c_setAsicReg(0x1d11, 0x1500)) != RT_ERR_OK) -+ return retVal; -+ -+ /*Enable new sds mode config method, cfg_sds_mode_sel_new=1*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 -+ new_cfg_sds_mode=0x1F (reset mode) */ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) -+ return retVal; -+ -+ /*bit5: cfg_mac6_fib=0 & bit7: cfg_mac6_fib2=0*/ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 0)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_mac7_sel_sgmii= 1 & cfg_mac7_fib=1*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 3)) != RT_ERR_OK) -+ return retVal; -+ -+ /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 -+ new_cfg_sds_mode=0x7 */ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x7)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if (mode < EXT_SGMII) -+ { -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d3d, 10, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /* keep default setting, disable mac7 sel SerDes mode*/ -+ if ((retVal = rtl8367c_setAsicReg(0x1d95, 0x1f00)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_mac7_sel_sgmii= 0 & cfg_mac7_fib=0*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /* set port7 mode*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, mode)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((mode == EXT_TMII_MAC) || (mode == EXT_TMII_PHY)) -+ { -+ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 1)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ } -+ else if ((mode < EXT_END) && (mode > EXT_100FX)) -+ { -+ if ((retVal = rtl8367c_setAsicRegBits(0x13C3, 0xf, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*cfg_mac7_sel_sgmii= 0 & cfg_mac7_fib=0*/ -+ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d3d, 10, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicRegBit(0x1d11, 11, ®_data)) != RT_ERR_OK) -+ return retVal; -+ if(reg_data == 0) -+ { -+ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 1)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ /* set port7 mode*/ -+ if (mode < EXT_RMII_MAC_2) -+ { -+ if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, (mode-13))) != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, (mode-12))) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ if ((mode == EXT_TMII_MAC_2) || (mode == EXT_TMII_PHY_2)) -+ { -+ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 1)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ -+ } -+ -+ } -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicPortExtMode -+ * Description: -+ * Get external interface mode configuration -+ * Input: -+ * id - external interface id (0~1) -+ * pMode - external interface mode -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortExtMode(rtk_uint32 id, rtk_uint32 *pMode) -+{ -+ ret_t retVal; -+ rtk_uint32 regData, regValue, type; -+ -+ if(id >= RTL8367C_EXTNO) -+ return RT_ERR_OUT_OF_RANGE; -+ /*cfg_magic_id & get chip_id*/ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) -+ return retVal; -+ -+ type = 0; -+ -+ switch (regValue) -+ { -+ case 0x0276: -+ case 0x0597: -+ case 0x6367: -+ type = 1; -+ break; -+ case 0x0652: -+ case 0x6368: -+ type = 2; -+ break; -+ case 0x0801: -+ case 0x6511: -+ type = 3; -+ break; -+ default: -+ return RT_ERR_FAILED; -+ } -+ -+ -+ if (1 == type) -+ { -+ -+ if (1 == id) -+ { -+ if( (retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_SGMII_OFFSET, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ if(1 == regData) -+ { -+ *pMode = EXT_SGMII; -+ return RT_ERR_OK; -+ } -+ -+ if( (retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ if(1 == regData) -+ { -+ *pMode = EXT_HSGMII; -+ return RT_ERR_OK; -+ } -+ } -+ -+ if(0 == id || 1 == id) -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_DIGITAL_INTERFACE_SELECT, RTL8367C_SELECT_GMII_0_MASK << (id * RTL8367C_SELECT_GMII_1_OFFSET), pMode); -+ else -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_DIGITAL_INTERFACE_SELECT_1, RTL8367C_SELECT_GMII_2_MASK, pMode); -+ -+ } -+ else if (2 == type) -+ { -+ if (1 == id) -+ { -+ if ((retVal = rtl8367c_getAsicReg(0x1d92, ®Data))!=RT_ERR_OK) -+ return retVal; -+ -+ if (regData & 0x4000) -+ { -+ *pMode = EXT_SGMII; -+ return RT_ERR_OK; -+ } -+ -+ else if (((regData >> 8) & 0x1f) == 4) -+ { -+ *pMode = EXT_1000X; -+ return RT_ERR_OK; -+ } -+ else if (((regData >> 8) & 0x1f) == 5) -+ { -+ *pMode = EXT_100FX; -+ return RT_ERR_OK; -+ } -+ else if (((regData >> 8) & 0x1f) == 7) -+ { -+ *pMode = EXT_1000X_100FX; -+ return RT_ERR_OK; -+ } -+ -+ return rtl8367c_getAsicRegBits(0x1305, 0xf0, pMode); -+ } -+ else if (2 == id) -+ { -+#if 0 -+ if ((retVal = rtl8367c_getAsicRegBit(0x1d92, 6, ®Data))!=RT_ERR_OK) -+ return retVal; -+ -+ if (regData == 1) -+ { -+ *pMode = EXT_SGMII; -+ return RT_ERR_OK; -+ } -+ -+ if ((retVal = rtl8367c_getAsicRegBit(0x1d92, 7, ®Data))!=RT_ERR_OK) -+ return retVal; -+ -+ if (regData == 1) -+ { -+ *pMode = EXT_HSGMII; -+ return RT_ERR_OK; -+ } -+#endif -+ if ((retVal = rtl8367c_getAsicReg(0x1d92, ®Data))!=RT_ERR_OK) -+ return retVal; -+ -+ if (regData & 0x40) -+ { -+ *pMode = EXT_SGMII; -+ return RT_ERR_OK; -+ } -+ else if (regData & 0x80) -+ { -+ *pMode = EXT_HSGMII; -+ return RT_ERR_OK; -+ } -+ else if ((regData & 0x1f) == 4) -+ { -+ *pMode = EXT_1000X; -+ return RT_ERR_OK; -+ } -+ else if ((regData & 0x1f) == 5) -+ { -+ *pMode = EXT_100FX; -+ return RT_ERR_OK; -+ } -+ else if ((regData & 0x1f) == 7) -+ { -+ *pMode = EXT_1000X_100FX; -+ return RT_ERR_OK; -+ } -+ -+ return rtl8367c_getAsicRegBits(0x1305, 0xf, pMode); -+ } -+ } -+ else if(3 == type) -+ { -+ if (1 == id) -+ { -+ /* SDS_CFG_NEW */ -+ if ((retVal = rtl8367c_getAsicReg(0x1d95, ®Data))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicReg(0x1d41, ®Value))!=RT_ERR_OK) -+ return retVal; -+ -+ /* bit5: cfg_mac6_fib=1 && bit7: cfg_mac6_fib2 =1 */ -+ if((regValue & 0xa0) == 0xa0 ) -+ { -+ /* new_cfg_sds_mode */ -+ regData = regData >> 8; -+ if((regData & 0x1f) == 4) -+ { -+ *pMode = EXT_1000X; -+ return RT_ERR_OK; -+ } -+ else if((regData & 0x1f) == 5) -+ { -+ *pMode = EXT_100FX; -+ return RT_ERR_OK; -+ } -+ else if((regData & 0x1f) == 7) -+ { -+ *pMode = EXT_1000X_100FX; -+ return RT_ERR_OK; -+ } -+ -+ } -+ -+ -+ if ((retVal = rtl8367c_getAsicReg(0x1d11, ®Data))!=RT_ERR_OK) -+ return retVal; -+ -+ /* check cfg_mac6_sel_sgmii */ -+ if((regData >> 6) & 1) -+ { -+ *pMode = EXT_SGMII; -+ return RT_ERR_OK; -+ } -+ else if((regData >> 11) & 1) -+ { -+ *pMode = EXT_HSGMII; -+ return RT_ERR_OK; -+ } -+ else -+ { -+ /* check port6 MAC mode */ -+ if ((retVal = rtl8367c_getAsicRegBits(0x1305, 0xf0, ®Data))!=RT_ERR_OK) -+ return retVal; -+ -+ if(regData < 6) -+ *pMode = regData; -+ else if(regData == 6) -+ *pMode = EXT_RMII_MAC; -+ else if(regData == 7) -+ *pMode = EXT_RMII_PHY; -+ -+ return RT_ERR_OK; -+ } -+ } -+ else if (2 == id) -+ { -+ if ((retVal = rtl8367c_getAsicReg(0x1d95, ®Data))!=RT_ERR_OK) -+ return retVal; -+ -+ /* bit0: cfg_mac7_sel_sgmii -+ bit1: cfg_mac7_fib -+ bit[12:8]: new_cfg_sds_mode*/ -+ if(((regData & 0x3) == 3) && (((regData >> 8) & 0x1f) == 0x4)) -+ { -+ *pMode = EXT_1000X; -+ return RT_ERR_OK; -+ } -+ else if (((regData & 0x3) == 3) && (((regData >> 8) & 0x1f) == 0x5)) -+ { -+ *pMode = EXT_100FX; -+ return RT_ERR_OK; -+ } -+ else if (((regData & 0x3) == 3) && (((regData >> 8) & 0x1f) == 0x7)) -+ { -+ *pMode = EXT_1000X_100FX; -+ return RT_ERR_OK; -+ } -+ else if(regData & 1) -+ { -+ *pMode = EXT_SGMII; -+ return RT_ERR_OK; -+ } -+ else -+ { -+ /* check port7 MAC mode */ -+ if ((retVal = rtl8367c_getAsicRegBits(0x13c3, 0xf, ®Data))!=RT_ERR_OK) -+ return retVal; -+ -+ *pMode = regData; -+ -+ return RT_ERR_OK; -+ } -+ } -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8370_setAsicPortEnableAll -+ * Description: -+ * Set ALL ports enable. -+ * Input: -+ * enable - enable all ports. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortEnableAll(rtk_uint32 enable) -+{ -+ if(enable >= 2) -+ return RT_ERR_INPUT; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_PHY_AD, RTL8367C_PDNPHY_OFFSET, !enable); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicPortEnableAll -+ * Description: -+ * Set ALL ports enable. -+ * Input: -+ * enable - enable all ports. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortEnableAll(rtk_uint32 *pEnable) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ -+ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_PHY_AD, RTL8367C_PDNPHY_OFFSET, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ if (regData==0) -+ *pEnable = 1; -+ else -+ *pEnable = 0; -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicPortSmallIpg -+ * Description: -+ * Set small ipg egress mode -+ * Input: -+ * port - Physical port number (0~7) -+ * enable - 0: normal, 1: small -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortSmallIpg(rtk_uint32 port, rtk_uint32 enable) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_PORT_SMALL_IPG_REG(port), RTL8367C_PORT0_MISC_CFG_SMALL_TAG_IPG_OFFSET, enable); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicPortSmallIpg -+ * Description: -+ * Get small ipg egress mode -+ * Input: -+ * port - Physical port number (0~7) -+ * pEnable - 0: normal, 1: small -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortSmallIpg(rtk_uint32 port, rtk_uint32* pEnable) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_PORT_SMALL_IPG_REG(port), RTL8367C_PORT0_MISC_CFG_SMALL_TAG_IPG_OFFSET, pEnable); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicPortLoopback -+ * Description: -+ * Set MAC loopback -+ * Input: -+ * port - Physical port number (0~7) -+ * enable - 0: Disable, 1: enable -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortLoopback(rtk_uint32 port, rtk_uint32 enable) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_PORT_MISC_CFG_REG(port), RTL8367C_PORT0_MISC_CFG_MAC_LOOPBACK_OFFSET, enable); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicPortLoopback -+ * Description: -+ * Set MAC loopback -+ * Input: -+ * port - Physical port number (0~7) -+ * Output: -+ * pEnable - 0: Disable, 1: enable -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortLoopback(rtk_uint32 port, rtk_uint32 *pEnable) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_PORT_MISC_CFG_REG(port), RTL8367C_PORT0_MISC_CFG_MAC_LOOPBACK_OFFSET, pEnable); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicPortRTCTEnable -+ * Description: -+ * Set RTCT Enable echo response mode -+ * Input: -+ * portmask - Port mask of RTCT enabled (0-4) -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Invalid port mask -+ * Note: -+ * RTCT test takes 4.8 seconds at most. -+ */ -+ret_t rtl8367c_setAsicPortRTCTEnable(rtk_uint32 portmask) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ rtk_uint32 port; -+ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicReg(0x1300, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (regData == 0x0276) || (regData == 0x0597) ) -+ return RT_ERR_CHIP_NOT_SUPPORTED; -+ -+ for(port = 0; port <= 10 ; port++) -+ { -+ if(portmask & (0x0001 << port)) -+ { -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa422, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ regData &= 0x7FFF; -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa422, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ regData |= 0x00F2;/*RTCT set to echo response mode*/ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa422, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ regData |= 0x0001; -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa422, regData)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicPortRTCTDisable -+ * Description: -+ * Set RTCT Disable -+ * Input: -+ * portmask - Port mask of RTCT enabled (0-4) -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Invalid port mask -+ * Note: -+ * RTCT test takes 4.8 seconds at most. -+ */ -+ret_t rtl8367c_setAsicPortRTCTDisable(rtk_uint32 portmask) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ rtk_uint32 port; -+ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicReg(0x1300, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (regData == 0x0276) || (regData == 0x0597) ) -+ return RT_ERR_CHIP_NOT_SUPPORTED; -+ -+ for(port = 0; port <= 10 ; port++) -+ { -+ if(portmask & (0x0001 << port)) -+ { -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa422, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ regData &= 0x7FFF; -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa422, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ regData |= 0x00F0; -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa422, regData)) != RT_ERR_OK) -+ return retVal; -+ -+ regData &= ~0x0001; -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa422, regData)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ -+ return RT_ERR_OK; -+} -+ -+ -+/* Function Name: -+ * rtl8367c_getAsicPortRTCTResult -+ * Description: -+ * Get RTCT result -+ * Input: -+ * port - Port ID of RTCT result -+ * Output: -+ * pResult - The result of port ID -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Invalid port mask -+ * RT_ERR_PHY_RTCT_NOT_FINISH - RTCT test doesn't finish. -+ * Note: -+ * RTCT test takes 4.8 seconds at most. -+ * If this API returns RT_ERR_PHY_RTCT_NOT_FINISH, -+ * users should wait a whole then read it again. -+ */ -+ret_t rtl8367c_getAsicPortRTCTResult(rtk_uint32 port, rtl8367c_port_rtct_result_t *pResult) -+{ -+ ret_t retVal; -+ rtk_uint32 regData, finish = 1; -+ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicReg(0x1300, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (regData == 0x6367) ) -+ { -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa422, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ if((regData & 0x8000) == 0x8000) -+ { -+ /* Channel A */ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802a)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ pResult->channelAOpen = (regData == 0x0048) ? 1 : 0; -+ pResult->channelAShort = (regData == 0x0050) ? 1 : 0; -+ pResult->channelAMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; -+ pResult->channelALinedriver = (regData == 0x0041) ? 1 : 0; -+ -+ /* Channel B */ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802e)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ pResult->channelBOpen = (regData == 0x0048) ? 1 : 0; -+ pResult->channelBShort = (regData == 0x0050) ? 1 : 0; -+ pResult->channelBMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; -+ pResult->channelBLinedriver = (regData == 0x0041) ? 1 : 0; -+ -+ /* Channel C */ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8032)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ pResult->channelCOpen = (regData == 0x0048) ? 1 : 0; -+ pResult->channelCShort = (regData == 0x0050) ? 1 : 0; -+ pResult->channelCMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; -+ pResult->channelCLinedriver = (regData == 0x0041) ? 1 : 0; -+ -+ /* Channel D */ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8036)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ pResult->channelDOpen = (regData == 0x0048) ? 1 : 0; -+ pResult->channelDShort = (regData == 0x0050) ? 1 : 0; -+ pResult->channelDMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; -+ pResult->channelDLinedriver = (regData == 0x0041) ? 1 : 0; -+ -+ /* Channel A Length */ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802c)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ pResult->channelALen = (regData / 2); -+ -+ /* Channel B Length */ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8030)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ pResult->channelBLen = (regData / 2); -+ -+ /* Channel C Length */ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8034)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ pResult->channelCLen = (regData / 2); -+ -+ /* Channel D Length */ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8038)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ pResult->channelDLen = (regData / 2); -+ } -+ else -+ finish = 0; -+ } -+ else if(regData == 0x6368) -+ { -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa422, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ if((regData & 0x8000) == 0x8000) -+ { -+ /* Channel A */ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802b)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ pResult->channelAOpen = (regData == 0x0048) ? 1 : 0; -+ pResult->channelAShort = (regData == 0x0050) ? 1 : 0; -+ pResult->channelAMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; -+ pResult->channelALinedriver = (regData == 0x0041) ? 1 : 0; -+ -+ /* Channel B */ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802f)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ pResult->channelBOpen = (regData == 0x0048) ? 1 : 0; -+ pResult->channelBShort = (regData == 0x0050) ? 1 : 0; -+ pResult->channelBMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; -+ pResult->channelBLinedriver = (regData == 0x0041) ? 1 : 0; -+ -+ /* Channel C */ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8033)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ pResult->channelCOpen = (regData == 0x0048) ? 1 : 0; -+ pResult->channelCShort = (regData == 0x0050) ? 1 : 0; -+ pResult->channelCMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; -+ pResult->channelCLinedriver = (regData == 0x0041) ? 1 : 0; -+ -+ /* Channel D */ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8037)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ pResult->channelDOpen = (regData == 0x0048) ? 1 : 0; -+ pResult->channelDShort = (regData == 0x0050) ? 1 : 0; -+ pResult->channelDMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; -+ pResult->channelDLinedriver = (regData == 0x0041) ? 1 : 0; -+ -+ /* Channel A Length */ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802d)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ pResult->channelALen = (regData / 2); -+ -+ /* Channel B Length */ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8031)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ pResult->channelBLen = (regData / 2); -+ -+ /* Channel C Length */ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8035)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ pResult->channelCLen = (regData / 2); -+ -+ /* Channel D Length */ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8039)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ pResult->channelDLen = (regData / 2); -+ } -+ else -+ finish = 0; -+ -+ } -+ else if((regData == 0x6511) || (regData == 0x0801)) -+ { -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa422, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ if((regData & 0x8000) == 0x8000) -+ { -+ /* Channel A */ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802a)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ pResult->channelAOpen = (regData == 0x0048) ? 1 : 0; -+ pResult->channelAShort = (regData == 0x0050) ? 1 : 0; -+ pResult->channelAMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; -+ pResult->channelALinedriver = (regData == 0x0041) ? 1 : 0; -+ -+ /* Channel B */ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802e)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ pResult->channelBOpen = (regData == 0x0048) ? 1 : 0; -+ pResult->channelBShort = (regData == 0x0050) ? 1 : 0; -+ pResult->channelBMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; -+ pResult->channelBLinedriver = (regData == 0x0041) ? 1 : 0; -+ -+ /* Channel C */ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8032)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ pResult->channelCOpen = (regData == 0x0048) ? 1 : 0; -+ pResult->channelCShort = (regData == 0x0050) ? 1 : 0; -+ pResult->channelCMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; -+ pResult->channelCLinedriver = (regData == 0x0041) ? 1 : 0; -+ -+ /* Channel D */ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8036)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ pResult->channelDOpen = (regData == 0x0048) ? 1 : 0; -+ pResult->channelDShort = (regData == 0x0050) ? 1 : 0; -+ pResult->channelDMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; -+ pResult->channelDLinedriver = (regData == 0x0041) ? 1 : 0; -+ -+ /* Channel A Length */ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802c)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ pResult->channelALen = (regData / 2); -+ -+ /* Channel B Length */ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8030)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ pResult->channelBLen = (regData / 2); -+ -+ /* Channel C Length */ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8034)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ pResult->channelCLen = (regData / 2); -+ -+ /* Channel D Length */ -+ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8038)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ pResult->channelDLen = (regData / 2); -+ } -+ else -+ finish = 0; -+ -+ } -+ else -+ return RT_ERR_CHIP_NOT_SUPPORTED; -+ -+ if(finish == 0) -+ return RT_ERR_PHY_RTCT_NOT_FINISH; -+ else -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_sdsReset -+ * Description: -+ * Reset Serdes -+ * Input: -+ * id - EXT ID -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None. -+ */ -+ret_t rtl8367c_sdsReset(rtk_uint32 id) -+{ -+ rtk_uint32 retVal, regValue, state, i, option, running = 0, retVal2; -+ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) -+ return retVal; -+ -+ switch (regValue) -+ { -+ case 0x0276: -+ case 0x0597: -+ case 0x6367: -+ option = 0; -+ break; -+ case 0x0652: -+ case 0x6368: -+ option = 1; -+ break; -+ case 0x0801: -+ case 0x6511: -+ option = 2; -+ break; -+ default: -+ return RT_ERR_FAILED; -+ } -+ -+ if(option == 0) -+ { -+ if (1 == id) -+ { -+ if ((retVal = rtl8367c_getAsicRegBit(0x130c, 5, &running))!=RT_ERR_OK) -+ return retVal; -+ -+ if(running == 1) -+ { -+ if ((retVal = rtl8367c_setAsicRegBit(0x130c, 5, 0))!=RT_ERR_OK) -+ return retVal; -+ } -+ -+ retVal = rtl8367c_setAsicReg(0x6601, 0x0000); -+ -+ if(retVal == RT_ERR_OK) -+ retVal = rtl8367c_setAsicReg(0x6602, 0x1401); -+ -+ if(retVal == RT_ERR_OK) -+ retVal = rtl8367c_setAsicReg(0x6600, 0x00C0); -+ -+ if(retVal == RT_ERR_OK) -+ retVal = rtl8367c_setAsicReg(0x6601, 0x0000); -+ -+ if(retVal == RT_ERR_OK) -+ retVal = rtl8367c_setAsicReg(0x6602, 0x1403); -+ -+ if(retVal == RT_ERR_OK) -+ retVal = rtl8367c_setAsicReg(0x6600, 0x00C0); -+ -+ if(running == 1) -+ { -+ if ((retVal2 = rtl8367c_setAsicRegBit(0x130c, 5, 1))!=RT_ERR_OK) -+ return retVal2; -+ } -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ return RT_ERR_PORT_ID; -+ } -+ else if(option == 1) -+ { -+ if (1 == id) -+ { -+ if((retVal = rtl8367c_getAsicReg(0x1311, &state)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x1311, 0x66)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x1311, 0x1066)) != RT_ERR_OK) -+ return retVal; -+ -+ while(1) -+ { -+ if((retVal = rtl8367c_getAsicReg(0x1d9d, ®Value)) != RT_ERR_OK) -+ return retVal; -+ if((regValue >> 8) & 1) -+ break; -+ } -+ -+ for (i=0; i<0xffff; i++); -+ -+ if((retVal = rtl8367c_setAsicReg(0x133d, 0x2)) != RT_ERR_OK) -+ return retVal; -+ -+ for (i=0; i<0xffff; i++); -+ -+ if((retVal = rtl8367c_setAsicReg(0x6601, 0x0)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_setAsicReg(0x6602, 0x1401)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_setAsicReg(0x6600, 0xc1)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_setAsicReg(0x6601, 0x0)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_setAsicReg(0x6602, 0x1403)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_setAsicReg(0x6600, 0xc1)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x133d, 0x0)) != RT_ERR_OK) -+ return retVal; -+ -+ for (i=0; i<0xffff; i++); -+ -+ if((retVal = rtl8367c_setAsicReg(0x1311, state)) != RT_ERR_OK) -+ return retVal; -+ -+ -+ } -+ else if (2== id) -+ { -+ if((retVal = rtl8367c_getAsicReg(0x13c4, &state)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x13c4, 0x66)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x13c4, 0x1066)) != RT_ERR_OK) -+ return retVal; -+ -+ while(1) -+ { -+ if((retVal = rtl8367c_getAsicReg(0x1d9d, ®Value)) != RT_ERR_OK) -+ return retVal; -+ if((regValue >> 9) & 1) -+ break; -+ } -+ -+ for (i=0; i<0xffff; i++); -+ -+ if((retVal = rtl8367c_setAsicReg(0x133d, 0x2)) != RT_ERR_OK) -+ return retVal; -+ -+ for (i=0; i<0xffff; i++); -+ -+ if((retVal = rtl8367c_setAsicReg(0x6601, 0x0)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_setAsicReg(0x6602, 0x1401)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_setAsicReg(0x6600, 0xc0)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_setAsicReg(0x6601, 0x0)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_setAsicReg(0x6602, 0x1403)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_setAsicReg(0x6600, 0xc0)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x133d, 0x0)) != RT_ERR_OK) -+ return retVal; -+ -+ for (i=0; i<0xffff; i++); -+ -+ if((retVal = rtl8367c_setAsicReg(0x13c4, state)) != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ return RT_ERR_PORT_ID; -+ } -+ else if(option == 2) -+ { -+ if ((retVal = rtl8367c_getAsicSdsReg(0, 3, 0, ®Value))!=RT_ERR_OK) -+ return retVal; -+ regValue |= 0x40; -+ if ((retVal = rtl8367c_setAsicSdsReg(0, 3, 0, regValue))!=RT_ERR_OK) -+ return retVal; -+ -+ for (i=0; i<0xffff; i++); -+ -+ regValue &= ~(0x40); -+ if ((retVal = rtl8367c_setAsicSdsReg(0, 3, 0, regValue))!=RT_ERR_OK) -+ return retVal; -+ -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getSdsLinkStatus -+ * Description: -+ * Get SGMII status -+ * Input: -+ * id - EXT ID -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None. -+ */ -+ret_t rtl8367c_getSdsLinkStatus(rtk_uint32 ext_id, rtk_uint32 *pSignalDetect, rtk_uint32 *pSync, rtk_uint32 *pLink) -+{ -+ rtk_uint32 retVal, regValue, type, running = 0, retVal2; -+ -+ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) -+ return retVal; -+ -+ switch (regValue) -+ { -+ case 0x0276: -+ case 0x0597: -+ case 0x6367: -+ type = 0; -+ break; -+ case 0x0652: -+ case 0x6368: -+ type = 1; -+ break; -+ case 0x0801: -+ case 0x6511: -+ type = 2; -+ break; -+ default: -+ return RT_ERR_FAILED; -+ } -+ -+ if(type == 0) -+ { -+ if (1 == ext_id) -+ { -+ if ((retVal = rtl8367c_getAsicRegBit(0x130c, 5, &running))!=RT_ERR_OK) -+ return retVal; -+ -+ if(running == 1) -+ { -+ if ((retVal = rtl8367c_setAsicRegBit(0x130c, 5, 0))!=RT_ERR_OK) -+ return retVal; -+ } -+ -+ retVal = rtl8367c_setAsicReg(0x6601, 0x003D); -+ -+ if(retVal == RT_ERR_OK) -+ retVal = rtl8367c_setAsicReg(0x6600, 0x0080); -+ -+ if(retVal == RT_ERR_OK) -+ retVal = rtl8367c_getAsicReg(0x6602, ®Value); -+ -+ if(running == 1) -+ { -+ if ((retVal2 = rtl8367c_setAsicRegBit(0x130c, 5, 1))!=RT_ERR_OK) -+ return retVal2; -+ } -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *pSignalDetect = (regValue & 0x0100) ? 1 : 0; -+ *pSync = (regValue & 0x0001) ? 1 : 0; -+ *pLink = (regValue & 0x0010) ? 1 : 0; -+ } -+ else -+ return RT_ERR_PORT_ID; -+ } -+ else if(type == 1) -+ { -+ if (1 == ext_id) -+ { -+ if ((retVal = rtl8367c_setAsicReg(0x6601, 0x003D))!=RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicReg(0x6600, 0x0081))!=RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_getAsicReg(0x6602, ®Value))!=RT_ERR_OK) -+ return retVal; -+ -+ *pSignalDetect = (regValue & 0x0100) ? 1 : 0; -+ *pSync = (regValue & 0x0001) ? 1 : 0; -+ *pLink = (regValue & 0x0010) ? 1 : 0; -+ } -+ else if (2 == ext_id) -+ { -+ if ((retVal = rtl8367c_setAsicReg(0x6601, 0x003D))!=RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicReg(0x6600, 0x0080))!=RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_getAsicReg(0x6602, ®Value))!=RT_ERR_OK) -+ return retVal; -+ -+ *pSignalDetect = (regValue & 0x0100) ? 1 : 0; -+ *pSync = (regValue & 0x0001) ? 1 : 0; -+ *pLink = (regValue & 0x0010) ? 1 : 0; -+ } -+ else -+ return RT_ERR_PORT_ID; -+ } -+ else if(type == 2) -+ { -+ if((retVal = rtl8367c_getAsicSdsReg(0, 30, 1, ®Value)) != RT_ERR_OK) -+ return retVal; -+ if((retVal = rtl8367c_getAsicSdsReg(0, 30, 1, ®Value)) != RT_ERR_OK) -+ return retVal; -+ -+ *pSignalDetect = (regValue & 0x0100) ? 1 : 0; -+ *pSync = (regValue & 0x0001) ? 1 : 0; -+ *pLink = (regValue & 0x0010) ? 1 : 0; -+ -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setSgmiiNway -+ * Description: -+ * Set SGMII Nway -+ * Input: -+ * ext_id - EXT ID -+ * state - SGMII Nway state -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None. -+ */ -+ret_t rtl8367c_setSgmiiNway(rtk_uint32 ext_id, rtk_uint32 state) -+{ -+ rtk_uint32 retVal, regValue, type, running = 0, retVal2; -+ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) -+ return retVal; -+ -+ switch (regValue) -+ { -+ case 0x0276: -+ case 0x0597: -+ case 0x6367: -+ type = 0; -+ break; -+ case 0x0652: -+ case 0x6368: -+ type = 1; -+ break; -+ case 0x0801: -+ case 0x6511: -+ type = 2; -+ break; -+ default: -+ return RT_ERR_FAILED; -+ } -+ -+ if(type == 0) -+ { -+ if (1 == ext_id) -+ { -+ if ((retVal = rtl8367c_getAsicRegBit(0x130c, 5, &running))!=RT_ERR_OK) -+ return retVal; -+ -+ if(running == 1) -+ { -+ if ((retVal = rtl8367c_setAsicRegBit(0x130c, 5, 0))!=RT_ERR_OK) -+ return retVal; -+ } -+ -+ retVal = rtl8367c_setAsicReg(0x6601, 0x0002); -+ -+ if(retVal == RT_ERR_OK) -+ retVal = rtl8367c_setAsicReg(0x6600, 0x0080); -+ -+ if(retVal == RT_ERR_OK) -+ retVal = rtl8367c_getAsicReg(0x6602, ®Value); -+ -+ if(retVal == RT_ERR_OK) -+ { -+ if(state) -+ regValue |= 0x0200; -+ else -+ regValue &= ~0x0200; -+ -+ regValue |= 0x0100; -+ } -+ -+ if(retVal == RT_ERR_OK) -+ retVal = rtl8367c_setAsicReg(0x6602, regValue); -+ -+ if(retVal == RT_ERR_OK) -+ retVal = rtl8367c_setAsicReg(0x6601, 0x0002); -+ -+ if(retVal == RT_ERR_OK) -+ retVal = rtl8367c_setAsicReg(0x6600, 0x00C0); -+ -+ if(running == 1) -+ { -+ if ((retVal2 = rtl8367c_setAsicRegBit(0x130c, 5, 1))!=RT_ERR_OK) -+ return retVal2; -+ } -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ return RT_ERR_PORT_ID; -+ } -+ else if(type == 1) -+ { -+ if (1 == ext_id) -+ { -+ if ((retVal = rtl8367c_setAsicReg(0x6601, 0x0002))!=RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicReg(0x6600, 0x0081))!=RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_getAsicReg(0x6602, ®Value))!=RT_ERR_OK) -+ return retVal; -+ -+ if(state) -+ regValue |= 0x0200; -+ else -+ regValue &= ~0x0200; -+ -+ regValue |= 0x0100; -+ -+ if ((retVal = rtl8367c_setAsicReg(0x6602, regValue))!=RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicReg(0x6601, 0x0002))!=RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicReg(0x6600, 0x00C1))!=RT_ERR_OK) -+ return retVal; -+ } -+ else if (2 == ext_id) -+ { -+ if ((retVal = rtl8367c_setAsicReg(0x6601, 0x0002))!=RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicReg(0x6600, 0x0080))!=RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_getAsicReg(0x6602, ®Value))!=RT_ERR_OK) -+ return retVal; -+ -+ if(state) -+ regValue |= 0x0200; -+ else -+ regValue &= ~0x0200; -+ -+ regValue |= 0x0100; -+ -+ if ((retVal = rtl8367c_setAsicReg(0x6602, regValue))!=RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicReg(0x6601, 0x0002))!=RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicReg(0x6600, 0x00C0))!=RT_ERR_OK) -+ return retVal; -+ } -+ else -+ return RT_ERR_PORT_ID; -+ } -+ else if(type == 2) -+ { -+ if ((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®Value))!=RT_ERR_OK) -+ return retVal; -+ -+ if(state & 1) -+ regValue &= ~0x100; -+ else -+ regValue |= 0x100; -+ -+ if ((retVal = rtl8367c_setAsicSdsReg(0, 2, 0, regValue))!=RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getSgmiiNway -+ * Description: -+ * Get SGMII Nway -+ * Input: -+ * ext_id - EXT ID -+ * state - SGMII Nway state -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None. -+ */ -+ret_t rtl8367c_getSgmiiNway(rtk_uint32 ext_id, rtk_uint32 *pState) -+{ -+ rtk_uint32 retVal, regValue, type, running = 0, retVal2; -+ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) -+ return retVal; -+ -+ switch (regValue) -+ { -+ case 0x0276: -+ case 0x0597: -+ case 0x6367: -+ type = 0; -+ break; -+ case 0x0652: -+ case 0x6368: -+ type = 1; -+ break; -+ case 0x0801: -+ case 0x6511: -+ type = 2; -+ break; -+ default: -+ return RT_ERR_FAILED; -+ } -+ -+ if(type == 0) -+ { -+ if (1 == ext_id) -+ { -+ if ((retVal = rtl8367c_getAsicRegBit(0x130c, 5, &running))!=RT_ERR_OK) -+ return retVal; -+ -+ if(running == 1) -+ { -+ if ((retVal = rtl8367c_setAsicRegBit(0x130c, 5, 0))!=RT_ERR_OK) -+ return retVal; -+ } -+ -+ retVal = rtl8367c_setAsicReg(0x6601, 0x0002); -+ -+ if(retVal == RT_ERR_OK) -+ retVal = rtl8367c_setAsicReg(0x6600, 0x0080); -+ -+ if(retVal == RT_ERR_OK) -+ retVal = rtl8367c_getAsicReg(0x6602, ®Value); -+ -+ if(running == 1) -+ { -+ if ((retVal2 = rtl8367c_setAsicRegBit(0x130c, 5, 1))!=RT_ERR_OK) -+ return retVal2; -+ } -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ if(regValue & 0x0200) -+ *pState = 1; -+ else -+ *pState = 0; -+ } -+ else -+ return RT_ERR_PORT_ID; -+ } -+ else if(type == 1) -+ { -+ if (1 == ext_id) -+ { -+ if ((retVal = rtl8367c_setAsicReg(0x6601, 0x0002))!=RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicReg(0x6600, 0x0081))!=RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_getAsicReg(0x6602, ®Value))!=RT_ERR_OK) -+ return retVal; -+ -+ if(regValue & 0x0200) -+ *pState = 1; -+ else -+ *pState = 0; -+ } -+ else if (2 == ext_id) -+ { -+ if ((retVal = rtl8367c_setAsicReg(0x6601, 0x0002))!=RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicReg(0x6600, 0x0080))!=RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_getAsicReg(0x6602, ®Value))!=RT_ERR_OK) -+ return retVal; -+ -+ if(regValue & 0x0200) -+ *pState = 1; -+ else -+ *pState = 0; -+ } -+ else -+ return RT_ERR_PORT_ID; -+ } -+ else if(type == 2) -+ { -+ if ((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®Value))!=RT_ERR_OK) -+ return retVal; -+ -+ if(regValue & 0x100) -+ *pState = 0; -+ else -+ *pState = 1; -+ } -+ -+ return RT_ERR_OK; -+} -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_portIsolation.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_portIsolation.c -new file mode 100644 -index 000000000000..e0b9db4bfbeb ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_portIsolation.c -@@ -0,0 +1,119 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Port isolation related functions -+ * -+ */ -+ -+#include -+/* Function Name: -+ * rtl8367c_setAsicPortIsolationPermittedPortmask -+ * Description: -+ * Set permitted port isolation portmask -+ * Input: -+ * port - Physical port number (0~10) -+ * permitPortmask - port mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_PORT_MASK - Invalid portmask -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortIsolationPermittedPortmask(rtk_uint32 port, rtk_uint32 permitPortmask) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ if( permitPortmask > RTL8367C_PORTMASK) -+ return RT_ERR_PORT_MASK; -+ -+ return rtl8367c_setAsicReg(RTL8367C_PORT_ISOLATION_PORT_MASK_REG(port), permitPortmask); -+} -+/* Function Name: -+ * rtl8367c_getAsicPortIsolationPermittedPortmask -+ * Description: -+ * Get permitted port isolation portmask -+ * Input: -+ * port - Physical port number (0~10) -+ * pPermitPortmask - port mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortIsolationPermittedPortmask(rtk_uint32 port, rtk_uint32 *pPermitPortmask) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicReg(RTL8367C_PORT_ISOLATION_PORT_MASK_REG(port), pPermitPortmask); -+} -+/* Function Name: -+ * rtl8367c_setAsicPortIsolationEfid -+ * Description: -+ * Set port isolation EFID -+ * Input: -+ * port - Physical port number (0~10) -+ * efid - EFID (0~7) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_OUT_OF_RANGE - Input parameter out of range -+ * Note: -+ * EFID is used in individual learning in filtering database -+ */ -+ret_t rtl8367c_setAsicPortIsolationEfid(rtk_uint32 port, rtk_uint32 efid) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ if( efid > RTL8367C_EFIDMAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_PORT_EFID_REG(port), RTL8367C_PORT_EFID_MASK(port), efid); -+} -+/* Function Name: -+ * rtl8367c_getAsicPortIsolationEfid -+ * Description: -+ * Get port isolation EFID -+ * Input: -+ * port - Physical port number (0~10) -+ * pEfid - EFID (0~7) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortIsolationEfid(rtk_uint32 port, rtk_uint32 *pEfid) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_PORT_EFID_REG(port), RTL8367C_PORT_EFID_MASK(port), pEfid); -+} -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_qos.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_qos.c -new file mode 100644 -index 000000000000..69081049e336 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_qos.c -@@ -0,0 +1,778 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : QoS related functions -+ * -+ */ -+ -+#include -+/* Function Name: -+ * rtl8367c_setAsicPriorityDot1qRemapping -+ * Description: -+ * Set 802.1Q absolutely priority -+ * Input: -+ * srcpriority - Priority value -+ * priority - Absolute priority value -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPriorityDot1qRemapping(rtk_uint32 srcpriority, rtk_uint32 priority ) -+{ -+ if((srcpriority > RTL8367C_PRIMAX) || (priority > RTL8367C_PRIMAX)) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_QOS_1Q_PRIORITY_REMAPPING_REG(srcpriority), RTL8367C_QOS_1Q_PRIORITY_REMAPPING_MASK(srcpriority),priority); -+} -+/* Function Name: -+ * rtl8367c_getAsicPriorityDot1qRemapping -+ * Description: -+ * Get 802.1Q absolutely priority -+ * Input: -+ * srcpriority - Priority value -+ * pPriority - Absolute priority value -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPriorityDot1qRemapping(rtk_uint32 srcpriority, rtk_uint32 *pPriority ) -+{ -+ if(srcpriority > RTL8367C_PRIMAX ) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_QOS_1Q_PRIORITY_REMAPPING_REG(srcpriority), RTL8367C_QOS_1Q_PRIORITY_REMAPPING_MASK(srcpriority), pPriority); -+} -+/* Function Name: -+ * rtl8367c_setAsicPriorityPortBased -+ * Description: -+ * Set port based priority -+ * Input: -+ * port - Physical port number (0~7) -+ * priority - Priority value -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPriorityPortBased(rtk_uint32 port, rtk_uint32 priority ) -+{ -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(priority > RTL8367C_PRIMAX ) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ if(port < 8) -+ { -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_QOS_PORTBASED_PRIORITY_REG(port), RTL8367C_QOS_PORTBASED_PRIORITY_MASK(port), priority); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_QOS_PORTBASED_PRIORITY_CTRL2, 0x7 << ((port - 8) << 2), priority); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicPriorityPortBased -+ * Description: -+ * Get port based priority -+ * Input: -+ * port - Physical port number (0~7) -+ * pPriority - Priority value -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPriorityPortBased(rtk_uint32 port, rtk_uint32 *pPriority ) -+{ -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(port < 8) -+ { -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_QOS_PORTBASED_PRIORITY_REG(port), RTL8367C_QOS_PORTBASED_PRIORITY_MASK(port), pPriority); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_QOS_PORTBASED_PRIORITY_CTRL2, 0x7 << ((port - 8) << 2), pPriority); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicPriorityDscpBased -+ * Description: -+ * Set DSCP-based priority -+ * Input: -+ * dscp - DSCP value -+ * priority - Priority value -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPriorityDscpBased(rtk_uint32 dscp, rtk_uint32 priority ) -+{ -+ if(priority > RTL8367C_PRIMAX ) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ if(dscp > RTL8367C_DSCPMAX) -+ return RT_ERR_QOS_DSCP_VALUE; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_QOS_DSCP_TO_PRIORITY_REG(dscp), RTL8367C_QOS_DSCP_TO_PRIORITY_MASK(dscp), priority); -+} -+/* Function Name: -+ * rtl8367c_getAsicPriorityDscpBased -+ * Description: -+ * Get DSCP-based priority -+ * Input: -+ * dscp - DSCP value -+ * pPriority - Priority value -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPriorityDscpBased(rtk_uint32 dscp, rtk_uint32 *pPriority ) -+{ -+ if(dscp > RTL8367C_DSCPMAX) -+ return RT_ERR_QOS_DSCP_VALUE; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_QOS_DSCP_TO_PRIORITY_REG(dscp), RTL8367C_QOS_DSCP_TO_PRIORITY_MASK(dscp), pPriority); -+} -+/* Function Name: -+ * rtl8367c_setAsicPriorityDecision -+ * Description: -+ * Set priority decision table -+ * Input: -+ * prisrc - Priority decision source -+ * decisionPri - Decision priority assignment -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority -+ * RT_ERR_QOS_SEL_PRI_SOURCE - Invalid priority decision source parameter -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPriorityDecision(rtk_uint32 index, rtk_uint32 prisrc, rtk_uint32 decisionPri) -+{ -+ ret_t retVal; -+ -+ if(index >= PRIDEC_IDX_END ) -+ return RT_ERR_ENTRY_INDEX; -+ -+ if(prisrc >= PRIDEC_END ) -+ return RT_ERR_QOS_SEL_PRI_SOURCE; -+ -+ if(decisionPri > RTL8367C_DECISIONPRIMAX ) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ switch(index) -+ { -+ case PRIDEC_IDX0: -+ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_REG(prisrc), RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_MASK(prisrc), decisionPri))!= RT_ERR_OK) -+ return retVal; -+ break; -+ case PRIDEC_IDX1: -+ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_REG(prisrc), RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_MASK(prisrc), decisionPri))!= RT_ERR_OK) -+ return retVal; -+ break; -+ default: -+ break; -+ }; -+ -+ return RT_ERR_OK; -+ -+ -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicPriorityDecision -+ * Description: -+ * Get priority decision table -+ * Input: -+ * prisrc - Priority decision source -+ * pDecisionPri - Decision priority assignment -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_SEL_PRI_SOURCE - Invalid priority decision source parameter -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPriorityDecision(rtk_uint32 index, rtk_uint32 prisrc, rtk_uint32* pDecisionPri) -+{ -+ ret_t retVal; -+ -+ if(index >= PRIDEC_IDX_END ) -+ return RT_ERR_ENTRY_INDEX; -+ -+ if(prisrc >= PRIDEC_END ) -+ return RT_ERR_QOS_SEL_PRI_SOURCE; -+ -+ switch(index) -+ { -+ case PRIDEC_IDX0: -+ if((retVal = rtl8367c_getAsicRegBits(RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_REG(prisrc), RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_MASK(prisrc), pDecisionPri))!= RT_ERR_OK) -+ return retVal; -+ break; -+ case PRIDEC_IDX1: -+ if((retVal = rtl8367c_getAsicRegBits(RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_REG(prisrc), RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_MASK(prisrc), pDecisionPri))!= RT_ERR_OK) -+ return retVal; -+ break; -+ default: -+ break; -+ }; -+ -+ return RT_ERR_OK; -+ -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicPortPriorityDecisionIndex -+ * Description: -+ * Set priority decision index for each port -+ * Input: -+ * port - Physical port number (0~7) -+ * index - Table index -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_QUEUE_NUM - Invalid queue number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortPriorityDecisionIndex(rtk_uint32 port, rtk_uint32 index ) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(index >= PRIDEC_IDX_END) -+ return RT_ERR_ENTRY_INDEX; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_IDX_CTRL, port, index); -+} -+/* Function Name: -+ * rtl8367c_getAsicPortPriorityDecisionIndex -+ * Description: -+ * Get priority decision index for each port -+ * Input: -+ * port - Physical port number (0~7) -+ * pIndex - Table index -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortPriorityDecisionIndex(rtk_uint32 port, rtk_uint32 *pIndex ) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_IDX_CTRL, port, pIndex); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicOutputQueueMappingIndex -+ * Description: -+ * Set output queue number for each port -+ * Input: -+ * port - Physical port number (0~7) -+ * index - Mapping table index -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_QUEUE_NUM - Invalid queue number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicOutputQueueMappingIndex(rtk_uint32 port, rtk_uint32 index ) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(index >= RTL8367C_QUEUENO) -+ return RT_ERR_QUEUE_NUM; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_QOS_PORT_QUEUE_NUMBER_REG(port), RTL8367C_QOS_PORT_QUEUE_NUMBER_MASK(port), index); -+} -+/* Function Name: -+ * rtl8367c_getAsicOutputQueueMappingIndex -+ * Description: -+ * Get output queue number for each port -+ * Input: -+ * port - Physical port number (0~7) -+ * pIndex - Mapping table index -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicOutputQueueMappingIndex(rtk_uint32 port, rtk_uint32 *pIndex ) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_QOS_PORT_QUEUE_NUMBER_REG(port), RTL8367C_QOS_PORT_QUEUE_NUMBER_MASK(port), pIndex); -+} -+/* Function Name: -+ * rtl8367c_setAsicPriorityToQIDMappingTable -+ * Description: -+ * Set priority to QID mapping table parameters -+ * Input: -+ * index - Mapping table index -+ * priority - The priority value -+ * qid - Queue id -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QUEUE_ID - Invalid queue id -+ * RT_ERR_QUEUE_NUM - Invalid queue number -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPriorityToQIDMappingTable(rtk_uint32 index, rtk_uint32 priority, rtk_uint32 qid ) -+{ -+ if(index >= RTL8367C_QUEUENO) -+ return RT_ERR_QUEUE_NUM; -+ -+ if(priority > RTL8367C_PRIMAX) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ if(qid > RTL8367C_QIDMAX) -+ return RT_ERR_QUEUE_ID; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_QOS_1Q_PRIORITY_TO_QID_REG(index, priority), RTL8367C_QOS_1Q_PRIORITY_TO_QID_MASK(priority), qid); -+} -+/* Function Name: -+ * rtl8367c_getAsicPriorityToQIDMappingTable -+ * Description: -+ * Get priority to QID mapping table parameters -+ * Input: -+ * index - Mapping table index -+ * priority - The priority value -+ * pQid - Queue id -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QUEUE_NUM - Invalid queue number -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPriorityToQIDMappingTable(rtk_uint32 index, rtk_uint32 priority, rtk_uint32* pQid) -+{ -+ if(index >= RTL8367C_QUEUENO) -+ return RT_ERR_QUEUE_NUM; -+ -+ if(priority > RTL8367C_PRIMAX) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_QOS_1Q_PRIORITY_TO_QID_REG(index, priority), RTL8367C_QOS_1Q_PRIORITY_TO_QID_MASK(priority), pQid); -+} -+/* Function Name: -+ * rtl8367c_setAsicRemarkingDot1pAbility -+ * Description: -+ * Set 802.1p remarking ability -+ * Input: -+ * port - Physical port number (0~7) -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicRemarkingDot1pAbility(rtk_uint32 port, rtk_uint32 enabled) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_PORT_MISC_CFG_REG(port), RTL8367C_1QREMARK_ENABLE_OFFSET, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicRemarkingDot1pAbility -+ * Description: -+ * Get 802.1p remarking ability -+ * Input: -+ * port - Physical port number (0~7) -+ * pEnabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicRemarkingDot1pAbility(rtk_uint32 port, rtk_uint32* pEnabled) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_PORT_MISC_CFG_REG(port), RTL8367C_1QREMARK_ENABLE_OFFSET, pEnabled); -+} -+/* Function Name: -+ * rtl8367c_setAsicRemarkingDot1pParameter -+ * Description: -+ * Set 802.1p remarking parameter -+ * Input: -+ * priority - Priority value -+ * newPriority - New priority value -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicRemarkingDot1pParameter(rtk_uint32 priority, rtk_uint32 newPriority ) -+{ -+ if(priority > RTL8367C_PRIMAX || newPriority > RTL8367C_PRIMAX) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_QOS_1Q_REMARK_REG(priority), RTL8367C_QOS_1Q_REMARK_MASK(priority), newPriority); -+} -+/* Function Name: -+ * rtl8367c_getAsicRemarkingDot1pParameter -+ * Description: -+ * Get 802.1p remarking parameter -+ * Input: -+ * priority - Priority value -+ * pNewPriority - New priority value -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicRemarkingDot1pParameter(rtk_uint32 priority, rtk_uint32 *pNewPriority ) -+{ -+ if(priority > RTL8367C_PRIMAX ) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_QOS_1Q_REMARK_REG(priority), RTL8367C_QOS_1Q_REMARK_MASK(priority), pNewPriority); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicRemarkingDot1pSrc -+ * Description: -+ * Set remarking source of 802.1p remarking. -+ * Input: -+ * type - remarking source -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_PORT_ID - invalid port id -+ * RT_ERR_INPUT - invalid input parameter -+ -+ * Note: -+ * The API can configure 802.1p remark functionality to map original DSCP value or internal -+ * priority to TX DSCP value. -+ */ -+ret_t rtl8367c_setAsicRemarkingDot1pSrc(rtk_uint32 type) -+{ -+ -+ if(type >= DOT1P_PRISEL_END ) -+ return RT_ERR_QOS_SEL_PRI_SOURCE; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_RMK_CFG_SEL_CTRL, RTL8367C_RMK_1Q_CFG_SEL_OFFSET, type); -+} -+ -+ -+/* Function Name: -+ * rtl8367c_getAsicRemarkingDot1pSrc -+ * Description: -+ * Get remarking source of 802.1p remarking. -+ * Output: -+ * pType - remarking source -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_PORT_ID - invalid port id -+ * RT_ERR_INPUT - invalid input parameter -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicRemarkingDot1pSrc(rtk_uint32 *pType) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_RMK_CFG_SEL_CTRL, RTL8367C_RMK_1Q_CFG_SEL_OFFSET, pType); -+} -+ -+ -+ -+ -+ -+/* Function Name: -+ * rtl8367c_setAsicRemarkingDscpAbility -+ * Description: -+ * Set DSCP remarking ability -+ * Input: -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicRemarkingDscpAbility(rtk_uint32 enabled) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REMARKING_CTRL_REG, RTL8367C_REMARKING_DSCP_ENABLE_OFFSET, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicRemarkingDscpAbility -+ * Description: -+ * Get DSCP remarking ability -+ * Input: -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicRemarkingDscpAbility(rtk_uint32* pEnabled) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REMARKING_CTRL_REG, RTL8367C_REMARKING_DSCP_ENABLE_OFFSET, pEnabled); -+} -+/* Function Name: -+ * rtl8367c_setAsicRemarkingDscpParameter -+ * Description: -+ * Set DSCP remarking parameter -+ * Input: -+ * priority - Priority value -+ * newDscp - New DSCP value -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicRemarkingDscpParameter(rtk_uint32 priority, rtk_uint32 newDscp ) -+{ -+ if(priority > RTL8367C_PRIMAX ) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ if(newDscp > RTL8367C_DSCPMAX) -+ return RT_ERR_QOS_DSCP_VALUE; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_QOS_DSCP_REMARK_REG(priority), RTL8367C_QOS_DSCP_REMARK_MASK(priority), newDscp); -+} -+/* Function Name: -+ * rtl8367c_getAsicRemarkingDscpParameter -+ * Description: -+ * Get DSCP remarking parameter -+ * Input: -+ * priority - Priority value -+ * pNewDscp - New DSCP value -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicRemarkingDscpParameter(rtk_uint32 priority, rtk_uint32* pNewDscp ) -+{ -+ if(priority > RTL8367C_PRIMAX ) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_QOS_DSCP_REMARK_REG(priority), RTL8367C_QOS_DSCP_REMARK_MASK(priority), pNewDscp); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicRemarkingDscpSrc -+ * Description: -+ * Set remarking source of DSCP remarking. -+ * Input: -+ * type - remarking source -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_PORT_ID - invalid port id -+ * RT_ERR_INPUT - invalid input parameter -+ -+ * Note: -+ * The API can configure DSCP remark functionality to map original DSCP value or internal -+ * priority to TX DSCP value. -+ */ -+ret_t rtl8367c_setAsicRemarkingDscpSrc(rtk_uint32 type) -+{ -+ -+ if(type >= DSCP_PRISEL_END ) -+ return RT_ERR_QOS_SEL_PRI_SOURCE; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_RMK_CFG_SEL_CTRL, RTL8367C_RMK_DSCP_CFG_SEL_MASK, type); -+} -+ -+ -+/* Function Name: -+ * rtl8367c_getAsicRemarkingDscpSrc -+ * Description: -+ * Get remarking source of DSCP remarking. -+ * Output: -+ * pType - remarking source -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_PORT_ID - invalid port id -+ * RT_ERR_INPUT - invalid input parameter -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicRemarkingDscpSrc(rtk_uint32 *pType) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_RMK_CFG_SEL_CTRL, RTL8367C_RMK_DSCP_CFG_SEL_MASK, pType); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicRemarkingDscp2Dscp -+ * Description: -+ * Set DSCP to remarked DSCP mapping. -+ * Input: -+ * dscp - DSCP value -+ * rmkDscp - remarked DSCP value -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_UNIT_ID - Invalid unit id -+ * RT_ERR_QOS_DSCP_VALUE - Invalid dscp value -+ * Note: -+ * dscp parameter can be DSCP value or internal priority according to configuration of API -+ * dal_apollomp_qos_dscpRemarkSrcSel_set(), because DSCP remark functionality can map original DSCP -+ * value or internal priority to TX DSCP value. -+ */ -+ret_t rtl8367c_setAsicRemarkingDscp2Dscp(rtk_uint32 dscp, rtk_uint32 rmkDscp) -+{ -+ if((dscp > RTL8367C_DSCPMAX ) || (rmkDscp > RTL8367C_DSCPMAX)) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_QOS_DSCP_TO_DSCP_REG(dscp), RTL8367C_QOS_DSCP_TO_DSCP_MASK(dscp), rmkDscp); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicRemarkingDscp2Dscp -+ * Description: -+ * Get DSCP to remarked DSCP mapping. -+ * Input: -+ * dscp - DSCP value -+ * Output: -+ * pRmkDscp - remarked DSCP value -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_QOS_DSCP_VALUE - Invalid dscp value -+ * RT_ERR_NULL_POINTER - NULL pointer -+ * Note: -+ * None. -+ */ -+ret_t rtl8367c_getAsicRemarkingDscp2Dscp(rtk_uint32 dscp, rtk_uint32 *pRmkDscp) -+{ -+ if(dscp > RTL8367C_DSCPMAX) -+ return RT_ERR_QOS_DSCP_VALUE; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_QOS_DSCP_TO_DSCP_REG(dscp), RTL8367C_QOS_DSCP_TO_DSCP_MASK(dscp), pRmkDscp); -+ -+} -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rldp.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rldp.c -new file mode 100644 -index 000000000000..0309689d39b9 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rldp.c -@@ -0,0 +1,674 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 42321 $ -+ * $Date: 2013-08-26 13:51:29 +0800 (週一, 26 八月 2013) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : RLDP related functions -+ * -+ */ -+ -+#include -+/* Function Name: -+ * rtl8367c_setAsicRldp -+ * Description: -+ * Set RLDP function enable/disable -+ * Input: -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicRldp(rtk_uint32 enabled) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_ENABLE_OFFSET, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicRldp -+ * Description: -+ * Get RLDP function enable/disable -+ * Input: -+ * pEnabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicRldp(rtk_uint32 *pEnabled) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_ENABLE_OFFSET, pEnabled); -+} -+/* Function Name: -+ * rtl8367c_setAsicRldpEnable8051 -+ * Description: -+ * Set RLDP function handled by ASIC or 8051 -+ * Input: -+ * enabled - 1: enabled 8051, 0: disabled 8051 (RLDP is handled by ASIC) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicRldpEnable8051(rtk_uint32 enabled) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_8051_ENABLE_OFFSET, enabled); -+} -+/* Function Name: -+ * rtl8367c_setAsicRldrtl8367c_getAsicRldpEnable8051pEnable8051 -+ * Description: -+ * Get RLDP function handled by ASIC or 8051 -+ * Input: -+ * pEnabled - 1: enabled 8051, 0: disabled 8051 (RLDP is handled by ASIC) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicRldpEnable8051(rtk_uint32 *pEnabled) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_8051_ENABLE_OFFSET, pEnabled); -+} -+/* Function Name: -+ * rtl8367c_setAsicRldpCompareRandomNumber -+ * Description: -+ * Set enable compare the random number field and seed field of RLDP frame -+ * Input: -+ * enabled - 1: enabled comparing random number, 0: disabled comparing random number -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicRldpCompareRandomNumber(rtk_uint32 enabled) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_COMP_ID_OFFSET, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicRldpCompareRandomNumber -+ * Description: -+ * Get enable compare the random number field and seed field of RLDP frame -+ * Input: -+ * pEnabled - 1: enabled comparing random number, 0: disabled comparing random number -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicRldpCompareRandomNumber(rtk_uint32 *pEnabled) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_COMP_ID_OFFSET, pEnabled); -+} -+/* Function Name: -+ * rtl8367c_setAsicRldpIndicatorSource -+ * Description: -+ * Set buzzer and LED source when detecting a loop -+ * Input: -+ * src - 0: ASIC, 1: 8051 -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicRldpIndicatorSource(rtk_uint32 src) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_INDICATOR_SOURCE_OFFSET, src); -+} -+/* Function Name: -+ * rtl8367c_getAsicRldpIndicatorSource -+ * Description: -+ * Get buzzer and LED source when detecting a loop -+ * Input: -+ * pSrc - 0: ASIC, 1: 8051 -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicRldpIndicatorSource(rtk_uint32 *pSrc) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_INDICATOR_SOURCE_OFFSET, pSrc); -+} -+/* Function Name: -+ * rtl8367c_setAsicRldpCheckingStatePara -+ * Description: -+ * Set retry count and retry period of checking state -+ * Input: -+ * retryCount - 0~0xFF (times) -+ * retryPeriod - 0~0xFFFF (ms) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicRldpCheckingStatePara(rtk_uint32 retryCount, rtk_uint32 retryPeriod) -+{ -+ ret_t retVal; -+ -+ if(retryCount > 0xFF) -+ return RT_ERR_OUT_OF_RANGE; -+ if(retryPeriod > RTL8367C_REGDATAMAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_RLDP_RETRY_COUNT_REG, RTL8367C_RLDP_RETRY_COUNT_CHKSTATE_MASK, retryCount); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return rtl8367c_setAsicReg(RTL8367C_RLDP_RETRY_PERIOD_CHKSTATE_REG, retryPeriod); -+} -+/* Function Name: -+ * rtl8367c_getAsicRldpCheckingStatePara -+ * Description: -+ * Get retry count and retry period of checking state -+ * Input: -+ * pRetryCount - 0~0xFF (times) -+ * pRetryPeriod - 0~0xFFFF (ms) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicRldpCheckingStatePara(rtk_uint32 *pRetryCount, rtk_uint32 *pRetryPeriod) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_RLDP_RETRY_COUNT_REG, RTL8367C_RLDP_RETRY_COUNT_CHKSTATE_MASK, pRetryCount); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return rtl8367c_getAsicReg(RTL8367C_RLDP_RETRY_PERIOD_CHKSTATE_REG, pRetryPeriod); -+} -+/* Function Name: -+ * rtl8367c_setAsicRldpLoopStatePara -+ * Description: -+ * Set retry count and retry period of loop state -+ * Input: -+ * retryCount - 0~0xFF (times) -+ * retryPeriod - 0~0xFFFF (ms) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicRldpLoopStatePara(rtk_uint32 retryCount, rtk_uint32 retryPeriod) -+{ -+ ret_t retVal; -+ -+ if(retryCount > 0xFF) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(retryPeriod > RTL8367C_REGDATAMAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_RLDP_RETRY_COUNT_REG, RTL8367C_RLDP_RETRY_COUNT_LOOPSTATE_MASK, retryCount); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return rtl8367c_setAsicReg(RTL8367C_RLDP_RETRY_PERIOD_LOOPSTATE_REG, retryPeriod); -+} -+/* Function Name: -+ * rtl8367c_getAsicRldpLoopStatePara -+ * Description: -+ * Get retry count and retry period of loop state -+ * Input: -+ * pRetryCount - 0~0xFF (times) -+ * pRetryPeriod - 0~0xFFFF (ms) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - input parameter out of range -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicRldpLoopStatePara(rtk_uint32 *pRetryCount, rtk_uint32 *pRetryPeriod) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_RLDP_RETRY_COUNT_REG, RTL8367C_RLDP_RETRY_COUNT_LOOPSTATE_MASK, pRetryCount); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return rtl8367c_getAsicReg(RTL8367C_RLDP_RETRY_PERIOD_LOOPSTATE_REG, pRetryPeriod); -+} -+/* Function Name: -+ * rtl8367c_setAsicRldpTxPortmask -+ * Description: -+ * Set portmask that send/forward RLDP frame -+ * Input: -+ * portmask - 0~0xFF -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Invalid portmask -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicRldpTxPortmask(rtk_uint32 portmask) -+{ -+ if(portmask > RTL8367C_PORTMASK) -+ return RT_ERR_PORT_MASK; -+ -+ return rtl8367c_setAsicReg(RTL8367C_RLDP_TX_PMSK_REG, portmask); -+} -+/* Function Name: -+ * rtl8367c_getAsicRldpTxPortmask -+ * Description: -+ * Get portmask that send/forward RLDP frame -+ * Input: -+ * pPortmask - 0~0xFF -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicRldpTxPortmask(rtk_uint32 *pPortmask) -+{ -+ return rtl8367c_getAsicReg(RTL8367C_RLDP_TX_PMSK_REG, pPortmask); -+} -+/* Function Name: -+ * rtl8367c_setAsicRldpMagicNum -+ * Description: -+ * Set Random seed of RLDP -+ * Input: -+ * seed - MAC -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicRldpMagicNum(ether_addr_t seed) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ rtk_uint16 *accessPtr; -+ rtk_uint32 i; -+ -+ accessPtr = (rtk_uint16*)&seed; -+ -+ for (i = 0; i < 3; i++) -+ { -+ regData = *accessPtr; -+ retVal = rtl8367c_setAsicReg(RTL8367C_RLDP_MAGIC_NUM_REG_BASE + i, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ accessPtr++; -+ } -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicRldpMagicNum -+ * Description: -+ * Get Random seed of RLDP -+ * Input: -+ * pSeed - MAC -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicRldpMagicNum(ether_addr_t *pSeed) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ rtk_uint16 *accessPtr; -+ rtk_uint32 i; -+ -+ accessPtr = (rtk_uint16*)pSeed; -+ -+ for(i = 0; i < 3; i++) -+ { -+ retVal = rtl8367c_getAsicReg(RTL8367C_RLDP_MAGIC_NUM_REG_BASE + i, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *accessPtr = regData; -+ accessPtr++; -+ } -+ -+ return retVal; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicRldpLoopedPortmask -+ * Description: -+ * Get looped portmask -+ * Input: -+ * pPortmask - 0~0xFF -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicRldpLoopedPortmask(rtk_uint32 *pPortmask) -+{ -+ return rtl8367c_getAsicReg(RTL8367C_RLDP_LOOP_PMSK_REG, pPortmask); -+} -+/* Function Name: -+ * rtl8367c_getAsicRldpRandomNumber -+ * Description: -+ * Get Random number of RLDP -+ * Input: -+ * pRandNumber - MAC -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicRldpRandomNumber(ether_addr_t *pRandNumber) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ rtk_int16 accessPtr[3]; -+ rtk_uint32 i; -+ -+ for(i = 0; i < 3; i++) -+ { -+ retVal = rtl8367c_getAsicReg(RTL8367C_RLDP_RAND_NUM_REG_BASE+ i, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ accessPtr[i] = regData; -+ } -+ -+ memcpy(pRandNumber, accessPtr, 6); -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicRldpLoopedPortmask -+ * Description: -+ * Get port number of looped pair -+ * Input: -+ * port - Physical port number (0~7) -+ * pLoopedPair - port (0~7) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicRldpLoopedPortPair(rtk_uint32 port, rtk_uint32 *pLoopedPair) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(port < 8) -+ return rtl8367c_getAsicRegBits(RTL8367C_RLDP_LOOP_PORT_REG(port), RTL8367C_RLDP_LOOP_PORT_MASK(port), pLoopedPair); -+ else -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_RLDP_LOOP_PORT_REG4 + ((port - 8) >> 1), RTL8367C_RLDP_LOOP_PORT_MASK(port), pLoopedPair); -+} -+/* Function Name: -+ * rtl8367c_setAsicRlppTrap8051 -+ * Description: -+ * Set trap RLPP packet to 8051 -+ * Input: -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicRlppTrap8051(rtk_uint32 enabled) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLPP_8051_TRAP_OFFSET, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicRlppTrap8051 -+ * Description: -+ * Get trap RLPP packet to 8051 -+ * Input: -+ * pEnabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicRlppTrap8051(rtk_uint32 *pEnabled) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLPP_8051_TRAP_OFFSET, pEnabled); -+} -+/* Function Name: -+ * rtl8367c_setAsicRldpLeaveLoopedPortmask -+ * Description: -+ * Clear leaved looped portmask -+ * Input: -+ * portmask - 0~0xFF -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicRldpLeaveLoopedPortmask(rtk_uint32 portmask) -+{ -+ return rtl8367c_setAsicReg(RTL8367C_REG_RLDP_RELEASED_INDICATOR, portmask); -+} -+/* Function Name: -+ * rtl8367c_getAsicRldpLeaveLoopedPortmask -+ * Description: -+ * Get leaved looped portmask -+ * Input: -+ * pPortmask - 0~0xFF -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicRldpLeaveLoopedPortmask(rtk_uint32 *pPortmask) -+{ -+ return rtl8367c_getAsicReg(RTL8367C_REG_RLDP_RELEASED_INDICATOR, pPortmask); -+} -+/* Function Name: -+ * rtl8367c_setAsicRldpEnterLoopedPortmask -+ * Description: -+ * Clear enter loop portmask -+ * Input: -+ * portmask - 0~0xFF -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicRldpEnterLoopedPortmask(rtk_uint32 portmask) -+{ -+ return rtl8367c_setAsicReg(RTL8367C_REG_RLDP_LOOPED_INDICATOR, portmask); -+} -+/* Function Name: -+ * rtl8367c_getAsicRldpEnterLoopedPortmask -+ * Description: -+ * Get enter loop portmask -+ * Input: -+ * pPortmask - 0~0xFF -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicRldpEnterLoopedPortmask(rtk_uint32 *pPortmask) -+{ -+ return rtl8367c_getAsicReg(RTL8367C_REG_RLDP_LOOPED_INDICATOR, pPortmask); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicRldpTriggerMode -+ * Description: -+ * Set trigger RLDP mode -+ * Input: -+ * mode - 1: Periodically, 0: SA moving -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicRldpTriggerMode(rtk_uint32 enabled) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_TRIGGER_MODE_OFFSET, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicRldpTriggerMode -+ * Description: -+ * Get trigger RLDP mode -+ * Input: -+ * pMode - - 1: Periodically, 0: SA moving -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicRldpTriggerMode(rtk_uint32 *pEnabled) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_TRIGGER_MODE_OFFSET, pEnabled); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicRldp8051Portmask -+ * Description: -+ * Set 8051/CPU configured looped portmask -+ * Input: -+ * portmask - 0~0xFF -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Invalid portmask -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicRldp8051Portmask(rtk_uint32 portmask) -+{ -+ ret_t retVal; -+ if(portmask > RTL8367C_PORTMASK) -+ return RT_ERR_PORT_MASK; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_RLDP_CTRL0_REG,RTL8367C_RLDP_8051_LOOP_PORTMSK_MASK,portmask & 0xff); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_RLDP_CTRL5,RTL8367C_RLDP_CTRL5_MASK,(portmask >> 8) & 7); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicRldp8051Portmask -+ * Description: -+ * Get 8051/CPU configured looped portmask -+ * Input: -+ * pPortmask - 0~0xFF -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicRldp8051Portmask(rtk_uint32 *pPortmask) -+{ -+ rtk_uint32 tmpPmsk; -+ ret_t retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_RLDP_CTRL0_REG,RTL8367C_RLDP_8051_LOOP_PORTMSK_MASK,&tmpPmsk); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ *pPortmask = tmpPmsk & 0xff; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_RLDP_CTRL5,RTL8367C_RLDP_CTRL5_MASK,&tmpPmsk); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ *pPortmask |= (tmpPmsk & 7) <<8; -+ -+ return RT_ERR_OK; -+} -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rma.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rma.c -new file mode 100644 -index 000000000000..f297defa78ac ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rma.c -@@ -0,0 +1,362 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 64716 $ -+ * $Date: 2015-12-31 16:31:55 +0800 (週四, 31 十二月 2015) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : RMA related functions -+ * -+ */ -+ -+#include -+/* Function Name: -+ * rtl8367c_setAsicRma -+ * Description: -+ * Set reserved multicast address for CPU trapping -+ * Input: -+ * index - reserved multicast LSB byte, 0x00~0x2F is available value -+ * pRmacfg - type of RMA for trapping frame type setting -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_RMA_ADDR - Invalid RMA address index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicRma(rtk_uint32 index, rtl8367c_rma_t* pRmacfg) -+{ -+ rtk_uint32 regData = 0; -+ ret_t retVal; -+ -+ if(index > RTL8367C_RMAMAX) -+ return RT_ERR_RMA_ADDR; -+ -+ regData |= (pRmacfg->portiso_leaky & 0x0001); -+ regData |= ((pRmacfg->vlan_leaky & 0x0001) << 1); -+ regData |= ((pRmacfg->keep_format & 0x0001) << 2); -+ regData |= ((pRmacfg->trap_priority & 0x0007) << 3); -+ regData |= ((pRmacfg->discard_storm_filter & 0x0001) << 6); -+ regData |= ((pRmacfg->operation & 0x0003) << 7); -+ -+ if( (index >= 0x4 && index <= 0x7) || (index >= 0x9 && index <= 0x0C) || (0x0F == index)) -+ index = 0x04; -+ else if((index >= 0x13 && index <= 0x17) || (0x19 == index) || (index >= 0x1B && index <= 0x1f)) -+ index = 0x13; -+ else if(index >= 0x22 && index <= 0x2F) -+ index = 0x22; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, pRmacfg->trap_priority); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return rtl8367c_setAsicReg(RTL8367C_REG_RMA_CTRL00+index, regData); -+} -+/* Function Name: -+ * rtl8367c_getAsicRma -+ * Description: -+ * Get reserved multicast address for CPU trapping -+ * Input: -+ * index - reserved multicast LSB byte, 0x00~0x2F is available value -+ * rmacfg - type of RMA for trapping frame type setting -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_RMA_ADDR - Invalid RMA address index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicRma(rtk_uint32 index, rtl8367c_rma_t* pRmacfg) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ -+ if(index > RTL8367C_RMAMAX) -+ return RT_ERR_RMA_ADDR; -+ -+ if( (index >= 0x4 && index <= 0x7) || (index >= 0x9 && index <= 0x0C) || (0x0F == index)) -+ index = 0x04; -+ else if((index >= 0x13 && index <= 0x17) || (0x19 == index) || (index >= 0x1B && index <= 0x1f)) -+ index = 0x13; -+ else if(index >= 0x22 && index <= 0x2F) -+ index = 0x22; -+ -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_RMA_CTRL00+index, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ pRmacfg->operation = ((regData >> 7) & 0x0003); -+ pRmacfg->discard_storm_filter = ((regData >> 6) & 0x0001); -+ pRmacfg->trap_priority = ((regData >> 3) & 0x0007); -+ pRmacfg->keep_format = ((regData >> 2) & 0x0001); -+ pRmacfg->vlan_leaky = ((regData >> 1) & 0x0001); -+ pRmacfg->portiso_leaky = (regData & 0x0001); -+ -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ pRmacfg->trap_priority = regData; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicRmaCdp -+ * Description: -+ * Set CDP(Cisco Discovery Protocol) for CPU trapping -+ * Input: -+ * pRmacfg - type of RMA for trapping frame type setting -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_RMA_ADDR - Invalid RMA address index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicRmaCdp(rtl8367c_rma_t* pRmacfg) -+{ -+ rtk_uint32 regData = 0; -+ ret_t retVal; -+ -+ if(pRmacfg->operation >= RMAOP_END) -+ return RT_ERR_RMA_ACTION; -+ -+ if(pRmacfg->trap_priority > RTL8367C_PRIMAX) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ regData |= (pRmacfg->portiso_leaky & 0x0001); -+ regData |= ((pRmacfg->vlan_leaky & 0x0001) << 1); -+ regData |= ((pRmacfg->keep_format & 0x0001) << 2); -+ regData |= ((pRmacfg->trap_priority & 0x0007) << 3); -+ regData |= ((pRmacfg->discard_storm_filter & 0x0001) << 6); -+ regData |= ((pRmacfg->operation & 0x0003) << 7); -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, pRmacfg->trap_priority); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return rtl8367c_setAsicReg(RTL8367C_REG_RMA_CTRL_CDP, regData); -+} -+/* Function Name: -+ * rtl8367c_getAsicRmaCdp -+ * Description: -+ * Get CDP(Cisco Discovery Protocol) for CPU trapping -+ * Input: -+ * None -+ * Output: -+ * pRmacfg - type of RMA for trapping frame type setting -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_RMA_ADDR - Invalid RMA address index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicRmaCdp(rtl8367c_rma_t* pRmacfg) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_RMA_CTRL_CDP, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ pRmacfg->operation = ((regData >> 7) & 0x0003); -+ pRmacfg->discard_storm_filter = ((regData >> 6) & 0x0001); -+ pRmacfg->trap_priority = ((regData >> 3) & 0x0007); -+ pRmacfg->keep_format = ((regData >> 2) & 0x0001); -+ pRmacfg->vlan_leaky = ((regData >> 1) & 0x0001); -+ pRmacfg->portiso_leaky = (regData & 0x0001); -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ pRmacfg->trap_priority = regData; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicRmaCsstp -+ * Description: -+ * Set CSSTP(Cisco Shared Spanning Tree Protocol) for CPU trapping -+ * Input: -+ * pRmacfg - type of RMA for trapping frame type setting -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_RMA_ADDR - Invalid RMA address index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicRmaCsstp(rtl8367c_rma_t* pRmacfg) -+{ -+ rtk_uint32 regData = 0; -+ ret_t retVal; -+ -+ if(pRmacfg->operation >= RMAOP_END) -+ return RT_ERR_RMA_ACTION; -+ -+ if(pRmacfg->trap_priority > RTL8367C_PRIMAX) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ regData |= (pRmacfg->portiso_leaky & 0x0001); -+ regData |= ((pRmacfg->vlan_leaky & 0x0001) << 1); -+ regData |= ((pRmacfg->keep_format & 0x0001) << 2); -+ regData |= ((pRmacfg->trap_priority & 0x0007) << 3); -+ regData |= ((pRmacfg->discard_storm_filter & 0x0001) << 6); -+ regData |= ((pRmacfg->operation & 0x0003) << 7); -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, pRmacfg->trap_priority); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return rtl8367c_setAsicReg(RTL8367C_REG_RMA_CTRL_CSSTP, regData); -+} -+/* Function Name: -+ * rtl8367c_getAsicRmaCsstp -+ * Description: -+ * Get CSSTP(Cisco Shared Spanning Tree Protocol) for CPU trapping -+ * Input: -+ * None -+ * Output: -+ * pRmacfg - type of RMA for trapping frame type setting -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_RMA_ADDR - Invalid RMA address index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicRmaCsstp(rtl8367c_rma_t* pRmacfg) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_RMA_CTRL_CSSTP, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ pRmacfg->operation = ((regData >> 7) & 0x0003); -+ pRmacfg->discard_storm_filter = ((regData >> 6) & 0x0001); -+ pRmacfg->trap_priority = ((regData >> 3) & 0x0007); -+ pRmacfg->keep_format = ((regData >> 2) & 0x0001); -+ pRmacfg->vlan_leaky = ((regData >> 1) & 0x0001); -+ pRmacfg->portiso_leaky = (regData & 0x0001); -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ pRmacfg->trap_priority = regData; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicRmaLldp -+ * Description: -+ * Set LLDP for CPU trapping -+ * Input: -+ * pRmacfg - type of RMA for trapping frame type setting -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_RMA_ADDR - Invalid RMA address index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicRmaLldp(rtk_uint32 enabled, rtl8367c_rma_t* pRmacfg) -+{ -+ rtk_uint32 regData = 0; -+ ret_t retVal; -+ -+ if(enabled > 1) -+ return RT_ERR_ENABLE; -+ -+ if(pRmacfg->operation >= RMAOP_END) -+ return RT_ERR_RMA_ACTION; -+ -+ if(pRmacfg->trap_priority > RTL8367C_PRIMAX) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_RMA_LLDP_EN, RTL8367C_RMA_LLDP_EN_OFFSET,enabled); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ regData |= (pRmacfg->portiso_leaky & 0x0001); -+ regData |= ((pRmacfg->vlan_leaky & 0x0001) << 1); -+ regData |= ((pRmacfg->keep_format & 0x0001) << 2); -+ regData |= ((pRmacfg->trap_priority & 0x0007) << 3); -+ regData |= ((pRmacfg->discard_storm_filter & 0x0001) << 6); -+ regData |= ((pRmacfg->operation & 0x0003) << 7); -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, pRmacfg->trap_priority); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return rtl8367c_setAsicReg(RTL8367C_REG_RMA_CTRL_LLDP, regData); -+} -+/* Function Name: -+ * rtl8367c_getAsicRmaLldp -+ * Description: -+ * Get LLDP for CPU trapping -+ * Input: -+ * None -+ * Output: -+ * pRmacfg - type of RMA for trapping frame type setting -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_RMA_ADDR - Invalid RMA address index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicRmaLldp(rtk_uint32 *pEnabled, rtl8367c_rma_t* pRmacfg) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ -+ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_RMA_LLDP_EN, RTL8367C_RMA_LLDP_EN_OFFSET,pEnabled); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_getAsicReg(RTL8367C_REG_RMA_CTRL_LLDP, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ pRmacfg->operation = ((regData >> 7) & 0x0003); -+ pRmacfg->discard_storm_filter = ((regData >> 6) & 0x0001); -+ pRmacfg->trap_priority = ((regData >> 3) & 0x0007); -+ pRmacfg->keep_format = ((regData >> 2) & 0x0001); -+ pRmacfg->vlan_leaky = ((regData >> 1) & 0x0001); -+ pRmacfg->portiso_leaky = (regData & 0x0001); -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ pRmacfg->trap_priority = regData; -+ -+ return RT_ERR_OK; -+} -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_scheduling.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_scheduling.c -new file mode 100644 -index 000000000000..32d9b208408d ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_scheduling.c -@@ -0,0 +1,525 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Packet Scheduling related functions -+ * -+ */ -+ -+#include -+/* Function Name: -+ * rtl8367c_setAsicLeakyBucketParameter -+ * Description: -+ * Set Leaky Bucket Parameters -+ * Input: -+ * tick - Tick is used for time slot size unit -+ * token - Token is used for adding budget in each time slot -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_TICK - Invalid TICK -+ * RT_ERR_TOKEN - Invalid TOKEN -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicLeakyBucketParameter(rtk_uint32 tick, rtk_uint32 token) -+{ -+ ret_t retVal; -+ -+ if(tick > 0xFF) -+ return RT_ERR_TICK; -+ -+ if(token > 0xFF) -+ return RT_ERR_TOKEN; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_LEAKY_BUCKET_TICK_REG, RTL8367C_LEAKY_BUCKET_TICK_MASK, tick); -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_LEAKY_BUCKET_TOKEN_REG, RTL8367C_LEAKY_BUCKET_TOKEN_MASK, token); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicLeakyBucketParameter -+ * Description: -+ * Get Leaky Bucket Parameters -+ * Input: -+ * tick - Tick is used for time slot size unit -+ * token - Token is used for adding budget in each time slot -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicLeakyBucketParameter(rtk_uint32 *tick, rtk_uint32 *token) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_LEAKY_BUCKET_TICK_REG, RTL8367C_LEAKY_BUCKET_TICK_MASK, tick); -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_LEAKY_BUCKET_TOKEN_REG, RTL8367C_LEAKY_BUCKET_TOKEN_MASK, token); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_setAsicAprMeter -+ * Description: -+ * Set per-port per-queue APR shared meter index -+ * Input: -+ * port - Physical port number (0~10) -+ * qid - Queue id -+ * apridx - dedicated shared meter index for APR (0~7) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_QUEUE_ID - Invalid queue id -+ * RT_ERR_FILTER_METER_ID - Invalid meter -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicAprMeter(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 apridx) -+{ -+ ret_t retVal; -+ rtk_uint32 regAddr; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(qid > RTL8367C_QIDMAX) -+ return RT_ERR_QUEUE_ID; -+ -+ if(apridx > RTL8367C_PORT_QUEUE_METER_INDEX_MAX) -+ return RT_ERR_FILTER_METER_ID; -+ -+ if(port < 8) -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_SCHEDULE_PORT_APR_METER_REG(port, qid), RTL8367C_SCHEDULE_PORT_APR_METER_MASK(qid), apridx); -+ else { -+ regAddr = RTL8367C_REG_SCHEDULE_PORT8_APR_METER_CTRL0 + ((port-8) << 1) + (qid / 5); -+ retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_SCHEDULE_PORT_APR_METER_MASK(qid), apridx); -+ } -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicAprMeter -+ * Description: -+ * Get per-port per-queue APR shared meter index -+ * Input: -+ * port - Physical port number (0~10) -+ * qid - Queue id -+ * apridx - dedicated shared meter index for APR (0~7) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_QUEUE_ID - Invalid queue id -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicAprMeter(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 *apridx) -+{ -+ ret_t retVal; -+ rtk_uint32 regAddr; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(qid > RTL8367C_QIDMAX) -+ return RT_ERR_QUEUE_ID; -+ -+ if(port < 8) -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_SCHEDULE_PORT_APR_METER_REG(port, qid), RTL8367C_SCHEDULE_PORT_APR_METER_MASK(qid), apridx); -+ else { -+ regAddr = RTL8367C_REG_SCHEDULE_PORT8_APR_METER_CTRL0 + ((port-8) << 1) + (qid / 5); -+ retVal = rtl8367c_getAsicRegBits(regAddr, RTL8367C_SCHEDULE_PORT_APR_METER_MASK(qid), apridx); -+ } -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_setAsicAprEnable -+ * Description: -+ * Set per-port APR enable -+ * Input: -+ * port - Physical port number (0~7) -+ * aprEnable - APR enable setting 1:enable 0:disable -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicAprEnable(rtk_uint32 port, rtk_uint32 aprEnable) -+{ -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ retVal = rtl8367c_setAsicRegBit(RTL8367C_SCHEDULE_APR_CTRL_REG, RTL8367C_SCHEDULE_APR_CTRL_OFFSET(port), aprEnable); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicAprEnable -+ * Description: -+ * Get per-port APR enable -+ * Input: -+ * port - Physical port number (0~7) -+ * aprEnable - APR enable setting 1:enable 0:disable -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicAprEnable(rtk_uint32 port, rtk_uint32 *aprEnable) -+{ -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ retVal = rtl8367c_getAsicRegBit(RTL8367C_SCHEDULE_APR_CTRL_REG, RTL8367C_SCHEDULE_APR_CTRL_OFFSET(port), aprEnable); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_setAsicWFQWeight -+ * Description: -+ * Set weight of a queue -+ * Input: -+ * port - Physical port number (0~10) -+ * qid - The queue ID wanted to set -+ * qWeight - The weight value wanted to set (valid:0~127) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_QUEUE_ID - Invalid queue id -+ * RT_ERR_QOS_QUEUE_WEIGHT - Invalid queue weight -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicWFQWeight(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 qWeight) -+{ -+ ret_t retVal; -+ -+ /* Invalid input parameter */ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(qid > RTL8367C_QIDMAX) -+ return RT_ERR_QUEUE_ID; -+ -+ if(qWeight > RTL8367C_QWEIGHTMAX && qid > 0) -+ return RT_ERR_QOS_QUEUE_WEIGHT; -+ -+ retVal = rtl8367c_setAsicReg(RTL8367C_SCHEDULE_PORT_QUEUE_WFQ_WEIGHT_REG(port, qid), qWeight); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicWFQWeight -+ * Description: -+ * Get weight of a queue -+ * Input: -+ * port - Physical port number (0~10) -+ * qid - The queue ID wanted to set -+ * qWeight - The weight value wanted to set (valid:0~127) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_QUEUE_ID - Invalid queue id -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicWFQWeight(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 *qWeight) -+{ -+ ret_t retVal; -+ -+ -+ /* Invalid input parameter */ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(qid > RTL8367C_QIDMAX) -+ return RT_ERR_QUEUE_ID; -+ -+ -+ retVal = rtl8367c_getAsicReg(RTL8367C_SCHEDULE_PORT_QUEUE_WFQ_WEIGHT_REG(port, qid), qWeight); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_setAsicWFQBurstSize -+ * Description: -+ * Set WFQ leaky bucket burst size -+ * Input: -+ * burstsize - Leaky bucket burst size, unit byte -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicWFQBurstSize(rtk_uint32 burstsize) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_setAsicReg(RTL8367C_SCHEDULE_WFQ_BURST_SIZE_REG, burstsize); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicWFQBurstSize -+ * Description: -+ * Get WFQ leaky bucket burst size -+ * Input: -+ * burstsize - Leaky bucket burst size, unit byte -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicWFQBurstSize(rtk_uint32 *burstsize) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_getAsicReg(RTL8367C_SCHEDULE_WFQ_BURST_SIZE_REG, burstsize); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_setAsicQueueType -+ * Description: -+ * Set type of a queue -+ * Input: -+ * port - Physical port number (0~10) -+ * qid - The queue ID wanted to set -+ * queueType - The specified queue type. 0b0: Strict priority, 0b1: WFQ -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_QUEUE_ID - Invalid queue id -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicQueueType(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 queueType) -+{ -+ ret_t retVal; -+ -+ /* Invalid input parameter */ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(qid > RTL8367C_QIDMAX) -+ return RT_ERR_QUEUE_ID; -+ -+ /* Set Related Registers */ -+ retVal = rtl8367c_setAsicRegBit(RTL8367C_SCHEDULE_QUEUE_TYPE_REG(port), RTL8367C_SCHEDULE_QUEUE_TYPE_OFFSET(port, qid),queueType); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicQueueType -+ * Description: -+ * Get type of a queue -+ * Input: -+ * port - Physical port number (0~7) -+ * qid - The queue ID wanted to set -+ * queueType - The specified queue type. 0b0: Strict priority, 0b1: WFQ -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_QUEUE_ID - Invalid queue id -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicQueueType(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 *queueType) -+{ -+ ret_t retVal; -+ -+ /* Invalid input parameter */ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(qid > RTL8367C_QIDMAX) -+ return RT_ERR_QUEUE_ID; -+ -+ retVal = rtl8367c_getAsicRegBit(RTL8367C_SCHEDULE_QUEUE_TYPE_REG(port), RTL8367C_SCHEDULE_QUEUE_TYPE_OFFSET(port, qid),queueType); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_setAsicPortEgressRate -+ * Description: -+ * Set per-port egress rate -+ * Input: -+ * port - Physical port number (0~10) -+ * rate - Egress rate -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_QOS_EBW_RATE - Invalid bandwidth/rate -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortEgressRate(rtk_uint32 port, rtk_uint32 rate) -+{ -+ ret_t retVal; -+ rtk_uint32 regAddr, regData; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(rate > RTL8367C_QOS_GRANULARTY_MAX) -+ return RT_ERR_QOS_EBW_RATE; -+ -+ regAddr = RTL8367C_PORT_EGRESSBW_LSB_REG(port); -+ regData = RTL8367C_QOS_GRANULARTY_LSB_MASK & rate; -+ -+ retVal = rtl8367c_setAsicReg(regAddr, regData); -+ -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ regAddr = RTL8367C_PORT_EGRESSBW_MSB_REG(port); -+ regData = (RTL8367C_QOS_GRANULARTY_MSB_MASK & rate) >> RTL8367C_QOS_GRANULARTY_MSB_OFFSET; -+ -+ retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_PORT6_EGRESSBW_CTRL1_MASK, regData); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicPortEgressRate -+ * Description: -+ * Get per-port egress rate -+ * Input: -+ * port - Physical port number (0~10) -+ * rate - Egress rate -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortEgressRate(rtk_uint32 port, rtk_uint32 *rate) -+{ -+ ret_t retVal; -+ rtk_uint32 regAddr, regData,regData2; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ regAddr = RTL8367C_PORT_EGRESSBW_LSB_REG(port); -+ -+ retVal = rtl8367c_getAsicReg(regAddr, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ regAddr = RTL8367C_PORT_EGRESSBW_MSB_REG(port); -+ retVal = rtl8367c_getAsicRegBits(regAddr, RTL8367C_PORT6_EGRESSBW_CTRL1_MASK, ®Data2); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *rate = regData | (regData2 << RTL8367C_QOS_GRANULARTY_MSB_OFFSET); -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicPortEgressRateIfg -+ * Description: -+ * Set per-port egress rate calculate include/exclude IFG -+ * Input: -+ * ifg - 1:include IFG 0:exclude IFG -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortEgressRateIfg(rtk_uint32 ifg) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SCHEDULE_WFQ_CTRL, RTL8367C_SCHEDULE_WFQ_CTRL_OFFSET, ifg); -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicPortEgressRateIfg -+ * Description: -+ * Get per-port egress rate calculate include/exclude IFG -+ * Input: -+ * ifg - 1:include IFG 0:exclude IFG -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortEgressRateIfg(rtk_uint32 *ifg) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SCHEDULE_WFQ_CTRL, RTL8367C_SCHEDULE_WFQ_CTRL_OFFSET, ifg); -+ -+ return retVal; -+} -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_storm.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_storm.c -new file mode 100644 -index 000000000000..a29f64769d65 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_storm.c -@@ -0,0 +1,851 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Storm control filtering related functions -+ * -+ */ -+ -+#include -+/* Function Name: -+ * rtl8367c_setAsicStormFilterBroadcastEnable -+ * Description: -+ * Set per-port broadcast storm filter enable/disable -+ * Input: -+ * port - Physical port number (0~7) -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicStormFilterBroadcastEnable(rtk_uint32 port, rtk_uint32 enabled) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_STORM_BCAST_REG, port, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicStormFilterBroadcastEnable -+ * Description: -+ * Get per-port broadcast storm filter enable/disable -+ * Input: -+ * port - Physical port number (0~7) -+ * pEnabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicStormFilterBroadcastEnable(rtk_uint32 port, rtk_uint32 *pEnabled) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_STORM_BCAST_REG, port, pEnabled); -+} -+/* Function Name: -+ * rtl8367c_setAsicStormFilterBroadcastMeter -+ * Description: -+ * Set per-port broadcast storm filter meter -+ * Input: -+ * port - Physical port number (0~7) -+ * meter - meter index (0~31) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_FILTER_METER_ID - Invalid meter index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicStormFilterBroadcastMeter(rtk_uint32 port, rtk_uint32 meter) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ if(meter > RTL8367C_METERMAX) -+ return RT_ERR_FILTER_METER_ID; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_STORM_BCAST_METER_CTRL_REG(port), RTL8367C_STORM_BCAST_METER_CTRL_MASK(port), meter); -+} -+/* Function Name: -+ * rtl8367c_getAsicStormFilterBroadcastMeter -+ * Description: -+ * Get per-port broadcast storm filter meter -+ * Input: -+ * port - Physical port number (0~7) -+ * pMeter - meter index (0~31) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicStormFilterBroadcastMeter(rtk_uint32 port, rtk_uint32 *pMeter) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_STORM_BCAST_METER_CTRL_REG(port), RTL8367C_STORM_BCAST_METER_CTRL_MASK(port), pMeter); -+} -+/* Function Name: -+ * rtl8367c_setAsicStormFilterMulticastEnable -+ * Description: -+ * Set per-port multicast storm filter enable/disable -+ * Input: -+ * port - Physical port number (0~7) -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicStormFilterMulticastEnable(rtk_uint32 port, rtk_uint32 enabled) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_STORM_MCAST_REG, port, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicStormFilterMulticastEnable -+ * Description: -+ * Get per-port multicast storm filter enable/disable -+ * Input: -+ * port - Physical port number (0~7) -+ * pEnabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicStormFilterMulticastEnable(rtk_uint32 port, rtk_uint32 *pEnabled) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_STORM_MCAST_REG, port, pEnabled); -+} -+/* Function Name: -+ * rtl8367c_setAsicStormFilterMulticastMeter -+ * Description: -+ * Set per-port multicast storm filter meter -+ * Input: -+ * port - Physical port number (0~7) -+ * meter - meter index (0~31) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_FILTER_METER_ID - Invalid meter index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicStormFilterMulticastMeter(rtk_uint32 port, rtk_uint32 meter) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ if(meter > RTL8367C_METERMAX) -+ return RT_ERR_FILTER_METER_ID; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_STORM_MCAST_METER_CTRL_REG(port), RTL8367C_STORM_MCAST_METER_CTRL_MASK(port), meter); -+} -+/* Function Name: -+ * rtl8367c_getAsicStormFilterMulticastMeter -+ * Description: -+ * Get per-port multicast storm filter meter -+ * Input: -+ * port - Physical port number (0~7) -+ * pMeter - meter index (0~31) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicStormFilterMulticastMeter(rtk_uint32 port, rtk_uint32 *pMeter) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_STORM_MCAST_METER_CTRL_REG(port), RTL8367C_STORM_MCAST_METER_CTRL_MASK(port), pMeter); -+} -+/* Function Name: -+ * rtl8367c_setAsicStormFilterUnknownMulticastEnable -+ * Description: -+ * Set per-port unknown multicast storm filter enable/disable -+ * Input: -+ * port - Physical port number (0~7) -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicStormFilterUnknownMulticastEnable(rtk_uint32 port, rtk_uint32 enabled) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_STORM_UNKNOWN_MCAST_REG, port, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicStormFilterUnknownMulticastEnable -+ * Description: -+ * Get per-port unknown multicast storm filter enable/disable -+ * Input: -+ * port - Physical port number (0~7) -+ * pEnabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicStormFilterUnknownMulticastEnable(rtk_uint32 port, rtk_uint32 *pEnabled) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_STORM_UNKNOWN_MCAST_REG, port, pEnabled); -+} -+/* Function Name: -+ * rtl8367c_setAsicStormFilterUnknownMulticastMeter -+ * Description: -+ * Set per-port unknown multicast storm filter meter -+ * Input: -+ * port - Physical port number (0~7) -+ * meter - meter index (0~31) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_FILTER_METER_ID - Invalid meter index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicStormFilterUnknownMulticastMeter(rtk_uint32 port, rtk_uint32 meter) -+{ -+ ret_t retVal; -+ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ if(meter > RTL8367C_METERMAX) -+ return RT_ERR_FILTER_METER_ID; -+ -+ if(port < 8) -+ { -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_STORM_UNMC_METER_CTRL_REG(port), RTL8367C_STORM_UNMC_METER_CTRL_MASK(port), meter); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_STORM_UNMC_METER_CTRL4 + ((port - 8) >> 1), RTL8367C_STORM_UNMC_METER_CTRL_MASK(port), meter); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicStormFilterUnknownMulticastMeter -+ * Description: -+ * Get per-port unknown multicast storm filter meter -+ * Input: -+ * port - Physical port number (0~7) -+ * pMeter - meter index (0~31) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicStormFilterUnknownMulticastMeter(rtk_uint32 port, rtk_uint32 *pMeter) -+{ -+ ret_t retVal; -+ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ if(port < 8) -+ { -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_STORM_UNMC_METER_CTRL_REG(port), RTL8367C_STORM_UNMC_METER_CTRL_MASK(port), pMeter); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_STORM_UNMC_METER_CTRL4 + ((port - 8) >> 1), RTL8367C_STORM_UNMC_METER_CTRL_MASK(port), pMeter); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicStormFilterUnknownUnicastEnable -+ * Description: -+ * Set per-port unknown unicast storm filter enable/disable -+ * Input: -+ * port - Physical port number (0~7) -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicStormFilterUnknownUnicastEnable(rtk_uint32 port, rtk_uint32 enabled) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_STORM_UNKNOWN_UCAST_REG, port, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicStormFilterUnknownUnicastEnable -+ * Description: -+ * get per-port unknown unicast storm filter enable/disable -+ * Input: -+ * port - Physical port number (0~7) -+ * pEnabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicStormFilterUnknownUnicastEnable(rtk_uint32 port, rtk_uint32 *pEnabled) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_STORM_UNKNOWN_UCAST_REG, port, pEnabled); -+} -+/* Function Name: -+ * rtl8367c_setAsicStormFilterUnknownUnicastMeter -+ * Description: -+ * Set per-port unknown unicast storm filter meter -+ * Input: -+ * port - Physical port number (0~7) -+ * meter - meter index (0~31) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_FILTER_METER_ID - Invalid meter index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicStormFilterUnknownUnicastMeter(rtk_uint32 port, rtk_uint32 meter) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ if(meter > RTL8367C_METERMAX) -+ return RT_ERR_FILTER_METER_ID; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_STORM_UNDA_METER_CTRL_REG(port), RTL8367C_STORM_UNDA_METER_CTRL_MASK(port), meter); -+} -+/* Function Name: -+ * rtl8367c_getAsicStormFilterUnknownUnicastMeter -+ * Description: -+ * Get per-port unknown unicast storm filter meter -+ * Input: -+ * port - Physical port number (0~7) -+ * pMeter - meter index (0~31) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicStormFilterUnknownUnicastMeter(rtk_uint32 port, rtk_uint32 *pMeter) -+{ -+ if(port >= RTL8367C_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_STORM_UNDA_METER_CTRL_REG(port), RTL8367C_STORM_UNDA_METER_CTRL_MASK(port), pMeter); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicStormFilterExtBroadcastMeter -+ * Description: -+ * Set extension broadcast storm filter meter -+ * Input: -+ * meter - meter index (0~31) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_FILTER_METER_ID - Invalid meter index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicStormFilterExtBroadcastMeter(rtk_uint32 meter) -+{ -+ if(meter > RTL8367C_METERMAX) -+ return RT_ERR_FILTER_METER_ID; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG0, RTL8367C_BC_STORM_EXT_METERIDX_MASK, meter); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicStormFilterExtBroadcastMeter -+ * Description: -+ * get extension broadcast storm filter meter -+ * Input: -+ * None -+ * Output: -+ * pMeter - meter index (0~31) -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Invalid meter index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicStormFilterExtBroadcastMeter(rtk_uint32 *pMeter) -+{ -+ if(NULL == pMeter) -+ return RT_ERR_NULL_POINTER; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG0, RTL8367C_BC_STORM_EXT_METERIDX_MASK, pMeter); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicStormFilterExtMulticastMeter -+ * Description: -+ * Set extension multicast storm filter meter -+ * Input: -+ * meter - meter index (0~31) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_FILTER_METER_ID - Invalid meter index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicStormFilterExtMulticastMeter(rtk_uint32 meter) -+{ -+ if(meter > RTL8367C_METERMAX) -+ return RT_ERR_FILTER_METER_ID; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG0, RTL8367C_MC_STORM_EXT_METERIDX_MASK, meter); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicStormFilterExtMulticastMeter -+ * Description: -+ * get extension multicast storm filter meter -+ * Input: -+ * None -+ * Output: -+ * pMeter - meter index (0~31) -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Invalid meter index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicStormFilterExtMulticastMeter(rtk_uint32 *pMeter) -+{ -+ if(NULL == pMeter) -+ return RT_ERR_NULL_POINTER; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG0, RTL8367C_MC_STORM_EXT_METERIDX_MASK, pMeter); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicStormFilterExtUnknownMulticastMeter -+ * Description: -+ * Set extension unknown multicast storm filter meter -+ * Input: -+ * meter - meter index (0~31) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_FILTER_METER_ID - Invalid meter index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicStormFilterExtUnknownMulticastMeter(rtk_uint32 meter) -+{ -+ if(meter > RTL8367C_METERMAX) -+ return RT_ERR_FILTER_METER_ID; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG1, RTL8367C_UNMC_STORM_EXT_METERIDX_MASK, meter); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicStormFilterExtUnknownMulticastMeter -+ * Description: -+ * get extension unknown multicast storm filter meter -+ * Input: -+ * None -+ * Output: -+ * pMeter - meter index (0~31) -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Invalid meter index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicStormFilterExtUnknownMulticastMeter(rtk_uint32 *pMeter) -+{ -+ if(NULL == pMeter) -+ return RT_ERR_NULL_POINTER; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG1, RTL8367C_UNMC_STORM_EXT_METERIDX_MASK, pMeter); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicStormFilterExtUnknownUnicastMeter -+ * Description: -+ * Set extension unknown unicast storm filter meter -+ * Input: -+ * meter - meter index (0~31) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_FILTER_METER_ID - Invalid meter index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicStormFilterExtUnknownUnicastMeter(rtk_uint32 meter) -+{ -+ if(meter > RTL8367C_METERMAX) -+ return RT_ERR_FILTER_METER_ID; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG1, RTL8367C_UNUC_STORM_EXT_METERIDX_MASK, meter); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicStormFilterExtUnknownUnicastMeter -+ * Description: -+ * get extension unknown unicast storm filter meter -+ * Input: -+ * None -+ * Output: -+ * pMeter - meter index (0~31) -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Invalid meter index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicStormFilterExtUnknownUnicastMeter(rtk_uint32 *pMeter) -+{ -+ if(NULL == pMeter) -+ return RT_ERR_NULL_POINTER; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG1, RTL8367C_UNUC_STORM_EXT_METERIDX_MASK, pMeter); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicStormFilterExtBroadcastEnable -+ * Description: -+ * Set extension broadcast storm filter state -+ * Input: -+ * enabled - state -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicStormFilterExtBroadcastEnable(rtk_uint32 enabled) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_BCAST_EXT_EN_OFFSET, enabled); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicStormFilterExtBroadcastEnable -+ * Description: -+ * Get extension broadcast storm filter state -+ * Input: -+ * None -+ * Output: -+ * pEnabled - state -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicStormFilterExtBroadcastEnable(rtk_uint32 *pEnabled) -+{ -+ if(NULL == pEnabled) -+ return RT_ERR_NULL_POINTER; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_BCAST_EXT_EN_OFFSET, pEnabled); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicStormFilterExtMulticastEnable -+ * Description: -+ * Set extension multicast storm filter state -+ * Input: -+ * enabled - state -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicStormFilterExtMulticastEnable(rtk_uint32 enabled) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_MCAST_EXT_EN_OFFSET, enabled); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicStormFilterExtMulticastEnable -+ * Description: -+ * Get extension multicast storm filter state -+ * Input: -+ * None -+ * Output: -+ * pEnabled - state -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicStormFilterExtMulticastEnable(rtk_uint32 *pEnabled) -+{ -+ if(NULL == pEnabled) -+ return RT_ERR_NULL_POINTER; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_MCAST_EXT_EN_OFFSET, pEnabled); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicStormFilterExtUnknownMulticastEnable -+ * Description: -+ * Set extension unknown multicast storm filter state -+ * Input: -+ * enabled - state -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicStormFilterExtUnknownMulticastEnable(rtk_uint32 enabled) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_UNKNOWN_MCAST_EXT_EN_OFFSET, enabled); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicStormFilterExtUnknownMulticastEnable -+ * Description: -+ * Get extension unknown multicast storm filter state -+ * Input: -+ * None -+ * Output: -+ * pEnabled - state -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicStormFilterExtUnknownMulticastEnable(rtk_uint32 *pEnabled) -+{ -+ if(NULL == pEnabled) -+ return RT_ERR_NULL_POINTER; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_UNKNOWN_MCAST_EXT_EN_OFFSET, pEnabled); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicStormFilterExtUnknownUnicastEnable -+ * Description: -+ * Set extension unknown unicast storm filter state -+ * Input: -+ * enabled - state -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicStormFilterExtUnknownUnicastEnable(rtk_uint32 enabled) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_UNKNOWN_UCAST_EXT_EN_OFFSET, enabled); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicStormFilterExtUnknownUnicastEnable -+ * Description: -+ * Get extension unknown unicast storm filter state -+ * Input: -+ * None -+ * Output: -+ * pEnabled - state -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicStormFilterExtUnknownUnicastEnable(rtk_uint32 *pEnabled) -+{ -+ if(NULL == pEnabled) -+ return RT_ERR_NULL_POINTER; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_UNKNOWN_UCAST_EXT_EN_OFFSET, pEnabled); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicStormFilterExtEnablePortMask -+ * Description: -+ * Set extension storm filter port mask -+ * Input: -+ * portmask - port mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicStormFilterExtEnablePortMask(rtk_uint32 portmask) -+{ -+ ret_t retVal; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_EXT_EN_PORTMASK_MASK, portmask & 0x3FF); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_EXT_EN_PORTMASK_EXT_MASK, (portmask >> 10)&1); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicStormFilterExtEnablePortMask -+ * Description: -+ * Get extension storm filter port mask -+ * Input: -+ * portmask - port mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicStormFilterExtEnablePortMask(rtk_uint32 *pPortmask) -+{ -+ rtk_uint32 tmpPmsk; -+ ret_t retVal; -+ -+ if(NULL == pPortmask) -+ return RT_ERR_NULL_POINTER; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_EXT_EN_PORTMASK_MASK, &tmpPmsk); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ *pPortmask = tmpPmsk & 0x3ff; -+ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_EXT_EN_PORTMASK_EXT_MASK, &tmpPmsk); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ *pPortmask |= (tmpPmsk & 1) << 10; -+ -+ return RT_ERR_OK; -+} -+ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_svlan.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_svlan.c -new file mode 100644 -index 000000000000..e199664b5e73 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_svlan.c -@@ -0,0 +1,1003 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : SVLAN related functions -+ * -+ */ -+#include -+ -+#include -+ -+static void _rtl8367c_svlanConfStUser2Smi( rtl8367c_svlan_memconf_t *pUserSt, rtk_uint16 *pSmiSt) -+{ -+ pSmiSt[0] |= (pUserSt->vs_member & 0x00FF); -+ pSmiSt[0] |= (pUserSt->vs_untag & 0x00FF) << 8; -+ -+ pSmiSt[1] |= (pUserSt->vs_fid_msti & 0x000F); -+ pSmiSt[1] |= (pUserSt->vs_priority & 0x0007) << 4; -+ pSmiSt[1] |= (pUserSt->vs_force_fid & 0x0001) << 7; -+ -+ pSmiSt[2] |= (pUserSt->vs_svid & 0x0FFF); -+ pSmiSt[2] |= (pUserSt->vs_efiden & 0x0001) << 12; -+ pSmiSt[2] |= (pUserSt->vs_efid & 0x0007) << 13; -+ -+ pSmiSt[3] |= ((pUserSt->vs_member & 0x0700) >> 8); -+ pSmiSt[3] |= ((pUserSt->vs_untag & 0x0700) >> 8) << 3; -+} -+ -+static void _rtl8367c_svlanConfStSmi2User( rtl8367c_svlan_memconf_t *pUserSt, rtk_uint16 *pSmiSt) -+{ -+ -+ pUserSt->vs_member = (pSmiSt[0] & 0x00FF) | ((pSmiSt[3] & 0x0007) << 8); -+ pUserSt->vs_untag = ((pSmiSt[0] & 0xFF00) >> 8) | (((pSmiSt[3] & 0x0038) >> 3) << 8); -+ -+ pUserSt->vs_fid_msti = (pSmiSt[1] & 0x000F); -+ pUserSt->vs_priority = (pSmiSt[1] & 0x0070) >> 4; -+ pUserSt->vs_force_fid = (pSmiSt[1] & 0x0080) >> 7; -+ -+ pUserSt->vs_svid = (pSmiSt[2] & 0x0FFF); -+ pUserSt->vs_efiden = (pSmiSt[2] & 0x1000) >> 12; -+ pUserSt->vs_efid = (pSmiSt[2] & 0xE000) >> 13; -+} -+ -+static void _rtl8367c_svlanMc2sStUser2Smi(rtl8367c_svlan_mc2s_t *pUserSt, rtk_uint16 *pSmiSt) -+{ -+ pSmiSt[0] |= (pUserSt->svidx & 0x003F); -+ pSmiSt[0] |= (pUserSt->format & 0x0001) << 6; -+ pSmiSt[0] |= (pUserSt->valid & 0x0001) << 7; -+ -+ pSmiSt[1] = (rtk_uint16)(pUserSt->smask & 0x0000FFFF); -+ pSmiSt[2] = (rtk_uint16)((pUserSt->smask & 0xFFFF0000) >> 16); -+ -+ pSmiSt[3] = (rtk_uint16)(pUserSt->sdata & 0x0000FFFF); -+ pSmiSt[4] = (rtk_uint16)((pUserSt->sdata & 0xFFFF0000) >> 16); -+} -+ -+static void _rtl8367c_svlanMc2sStSmi2User(rtl8367c_svlan_mc2s_t *pUserSt, rtk_uint16 *pSmiSt) -+{ -+ pUserSt->svidx = (pSmiSt[0] & 0x003F); -+ pUserSt->format = (pSmiSt[0] & 0x0040) >> 6; -+ pUserSt->valid = (pSmiSt[0] & 0x0080) >> 7; -+ -+ pUserSt->smask = pSmiSt[1] | (pSmiSt[2] << 16); -+ pUserSt->sdata = pSmiSt[3] | (pSmiSt[4] << 16); -+} -+ -+static void _rtl8367c_svlanSp2cStUser2Smi(rtl8367c_svlan_s2c_t *pUserSt, rtk_uint16 *pSmiSt) -+{ -+ pSmiSt[0] |= (pUserSt->dstport & 0x0007); -+ pSmiSt[0] |= (pUserSt->svidx & 0x003F) << 3; -+ pSmiSt[0] |= ((pUserSt->dstport & 0x0008) >> 3) << 9; -+ -+ pSmiSt[1] |= (pUserSt->vid & 0x0FFF); -+ pSmiSt[1] |= (pUserSt->valid & 0x0001) << 12; -+} -+ -+static void _rtl8367c_svlanSp2cStSmi2User(rtl8367c_svlan_s2c_t *pUserSt, rtk_uint16 *pSmiSt) -+{ -+ pUserSt->dstport = (((pSmiSt[0] & 0x0200) >> 9) << 3) | (pSmiSt[0] & 0x0007); -+ pUserSt->svidx = (pSmiSt[0] & 0x01F8) >> 3; -+ pUserSt->vid = (pSmiSt[1] & 0x0FFF); -+ pUserSt->valid = (pSmiSt[1] & 0x1000) >> 12; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicSvlanUplinkPortMask -+ * Description: -+ * Set uplink ports mask -+ * Input: -+ * portMask - Uplink port mask setting -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicSvlanUplinkPortMask(rtk_uint32 portMask) -+{ -+ return rtl8367c_setAsicReg(RTL8367C_REG_SVLAN_UPLINK_PORTMASK, portMask); -+} -+/* Function Name: -+ * rtl8367c_getAsicSvlanUplinkPortMask -+ * Description: -+ * Get uplink ports mask -+ * Input: -+ * pPortmask - Uplink port mask setting -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicSvlanUplinkPortMask(rtk_uint32* pPortmask) -+{ -+ return rtl8367c_getAsicReg(RTL8367C_REG_SVLAN_UPLINK_PORTMASK, pPortmask); -+} -+/* Function Name: -+ * rtl8367c_setAsicSvlanTpid -+ * Description: -+ * Set accepted S-VLAN ether type. The default ether type of S-VLAN is 0x88a8 -+ * Input: -+ * protocolType - Ether type of S-tag frame parsing in uplink ports -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * Ether type of S-tag in 802.1ad is 0x88a8 and there are existed ether type 0x9100 and 0x9200 -+ * for Q-in-Q SLAN design. User can set matched ether type as service provider supported protocol -+ */ -+ret_t rtl8367c_setAsicSvlanTpid(rtk_uint32 protocolType) -+{ -+ return rtl8367c_setAsicReg(RTL8367C_REG_VS_TPID, protocolType); -+} -+/* Function Name: -+ * rtl8367c_getAsicReg -+ * Description: -+ * Get accepted S-VLAN ether type. The default ether type of S-VLAN is 0x88a8 -+ * Input: -+ * pProtocolType - Ether type of S-tag frame parsing in uplink ports -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicSvlanTpid(rtk_uint32* pProtocolType) -+{ -+ return rtl8367c_getAsicReg(RTL8367C_REG_VS_TPID, pProtocolType); -+} -+/* Function Name: -+ * rtl8367c_setAsicSvlanPrioritySel -+ * Description: -+ * Set SVLAN priority field setting -+ * Input: -+ * priSel - S-priority assignment method, 0:internal priority 1:C-tag priority 2:using Svlan member configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicSvlanPrioritySel(rtk_uint32 priSel) -+{ -+ if(priSel >= SPRISEL_END) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_SPRISEL_MASK, priSel); -+} -+/* Function Name: -+ * rtl8367c_getAsicSvlanPrioritySel -+ * Description: -+ * Get SVLAN priority field setting -+ * Input: -+ * pPriSel - S-priority assignment method, 0:internal priority 1:C-tag priority 2:using Svlan member configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicSvlanPrioritySel(rtk_uint32* pPriSel) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_SPRISEL_MASK, pPriSel); -+} -+/* Function Name: -+ * rtl8367c_setAsicSvlanTrapPriority -+ * Description: -+ * Set trap to CPU priority assignment -+ * Input: -+ * priority - Priority assignment -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicSvlanTrapPriority(rtk_uint32 priority) -+{ -+ if(priority > RTL8367C_PRIMAX) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_QOS_TRAP_PRIORITY0, RTL8367C_SVLAN_PRIOIRTY_MASK, priority); -+} -+/* Function Name: -+ * rtl8367c_getAsicSvlanTrapPriority -+ * Description: -+ * Get trap to CPU priority assignment -+ * Input: -+ * pPriority - Priority assignment -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicSvlanTrapPriority(rtk_uint32* pPriority) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_QOS_TRAP_PRIORITY0, RTL8367C_SVLAN_PRIOIRTY_MASK, pPriority); -+} -+/* Function Name: -+ * rtl8367c_setAsicSvlanDefaultVlan -+ * Description: -+ * Set default egress SVLAN -+ * Input: -+ * port - Physical port number (0~10) -+ * index - index SVLAN member configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_SVLAN_ENTRY_INDEX - Invalid SVLAN index parameter -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicSvlanDefaultVlan(rtk_uint32 port, rtk_uint32 index) -+{ -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(index > RTL8367C_SVIDXMAX) -+ return RT_ERR_SVLAN_ENTRY_INDEX; -+ -+ if(port < 8){ -+ if(port & 1) -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL0 + (port >> 1), RTL8367C_VS_PORT1_SVIDX_MASK,index); -+ else -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL0 + (port >> 1), RTL8367C_VS_PORT0_SVIDX_MASK,index); -+ }else{ -+ switch(port){ -+ case 8: -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL4, RTL8367C_VS_PORT8_SVIDX_MASK,index); -+ break; -+ -+ case 9: -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL4, RTL8367C_VS_PORT9_SVIDX_MASK,index); -+ break; -+ -+ case 10: -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL5, RTL8367C_SVLAN_PORTBASED_SVIDX_CTRL5_MASK,index); -+ break; -+ } -+ } -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicSvlanDefaultVlan -+ * Description: -+ * Get default egress SVLAN -+ * Input: -+ * port - Physical port number (0~7) -+ * pIndex - index SVLAN member configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicSvlanDefaultVlan(rtk_uint32 port, rtk_uint32* pIndex) -+{ -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(port < 8){ -+ if(port & 1) -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL0 + (port >> 1), RTL8367C_VS_PORT1_SVIDX_MASK,pIndex); -+ else -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL0 + (port >> 1), RTL8367C_VS_PORT0_SVIDX_MASK,pIndex); -+ }else{ -+ switch(port){ -+ case 8: -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL4, RTL8367C_VS_PORT8_SVIDX_MASK,pIndex); -+ break; -+ -+ case 9: -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL4, RTL8367C_VS_PORT9_SVIDX_MASK,pIndex); -+ break; -+ -+ case 10: -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL5, RTL8367C_SVLAN_PORTBASED_SVIDX_CTRL5_MASK,pIndex); -+ break; -+ } -+ } -+ -+ return retVal; -+ -+} -+/* Function Name: -+ * rtl8367c_setAsicSvlanIngressUntag -+ * Description: -+ * Set action received un-Stag frame from uplink port -+ * Input: -+ * mode - 0:Drop 1:Trap 2:Assign SVLAN -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicSvlanIngressUntag(rtk_uint32 mode) -+{ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_UNTAG_MASK, mode); -+} -+/* Function Name: -+ * rtl8367c_getAsicSvlanIngressUntag -+ * Description: -+ * Get action received un-Stag frame from uplink port -+ * Input: -+ * pMode - 0:Drop 1:Trap 2:Assign SVLAN -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicSvlanIngressUntag(rtk_uint32* pMode) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_UNTAG_MASK, pMode); -+} -+/* Function Name: -+ * rtl8367c_setAsicSvlanIngressUnmatch -+ * Description: -+ * Set action received unmatched Stag frame from uplink port -+ * Input: -+ * mode - 0:Drop 1:Trap 2:Assign SVLAN -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicSvlanIngressUnmatch(rtk_uint32 mode) -+{ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_UNMAT_MASK, mode); -+} -+/* Function Name: -+ * rtl8367c_getAsicSvlanIngressUnmatch -+ * Description: -+ * Get action received unmatched Stag frame from uplink port -+ * Input: -+ * pMode - 0:Drop 1:Trap 2:Assign SVLAN -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicSvlanIngressUnmatch(rtk_uint32* pMode) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_UNMAT_MASK, pMode); -+ -+} -+/* Function Name: -+ * rtl8367c_setAsicSvlanEgressUnassign -+ * Description: -+ * Set uplink stream without egress SVID action -+ * Input: -+ * enabled - 1:Trap egress unassigned frames to CPU, 0: Use SVLAN setup in VS_CPSVIDX as egress SVID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicSvlanEgressUnassign(rtk_uint32 enabled) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_UIFSEG_OFFSET, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicSvlanEgressUnassign -+ * Description: -+ * Get uplink stream without egress SVID action -+ * Input: -+ * pEnabled - 1:Trap egress unassigned frames to CPU, 0: Use SVLAN setup in VS_CPSVIDX as egress SVID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicSvlanEgressUnassign(rtk_uint32* pEnabled) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_UIFSEG_OFFSET, pEnabled); -+} -+ -+ -+/* Function Name: -+ * rtl8367c_setAsicSvlanMemberConfiguration -+ * Description: -+ * Set system 64 S-tag content -+ * Input: -+ * index - index of 64 s-tag configuration -+ * pSvlanMemCfg - SVLAN member configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_SVLAN_ENTRY_INDEX - Invalid SVLAN index parameter -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicSvlanMemberConfiguration(rtk_uint32 index, rtl8367c_svlan_memconf_t* pSvlanMemCfg) -+{ -+ ret_t retVal; -+ rtk_uint32 regAddr, regData; -+ rtk_uint16 *accessPtr; -+ rtk_uint32 i; -+ rtk_uint16 smiSvlanMemConf[RTL8367C_SVLAN_MEMCONF_LEN]; -+ -+ if(index > RTL8367C_SVIDXMAX) -+ return RT_ERR_SVLAN_ENTRY_INDEX; -+ -+ memset(smiSvlanMemConf, 0x00, sizeof(rtk_uint16) * RTL8367C_SVLAN_MEMCONF_LEN); -+ _rtl8367c_svlanConfStUser2Smi(pSvlanMemCfg, smiSvlanMemConf); -+ -+ accessPtr = smiSvlanMemConf; -+ -+ regData = *accessPtr; -+ for(i = 0; i < 3; i++) -+ { -+ retVal = rtl8367c_setAsicReg(RTL8367C_SVLAN_MEMBERCFG_BASE_REG(index) + i, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ accessPtr ++; -+ regData = *accessPtr; -+ } -+ -+ if(index < 63) -+ regAddr = RTL8367C_REG_SVLAN_MEMBERCFG0_CTRL4+index; -+ else if(index == 63) -+ regAddr = RTL8367C_REG_SVLAN_MEMBERCFG63_CTRL4; -+ -+ retVal = rtl8367c_setAsicReg(regAddr, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+ -+} -+/* Function Name: -+ * rtl8367c_getAsicSvlanMemberConfiguration -+ * Description: -+ * Get system 64 S-tag content -+ * Input: -+ * index - index of 64 s-tag configuration -+ * pSvlanMemCfg - SVLAN member configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_SVLAN_ENTRY_INDEX - Invalid SVLAN index parameter -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicSvlanMemberConfiguration(rtk_uint32 index,rtl8367c_svlan_memconf_t* pSvlanMemCfg) -+{ -+ ret_t retVal; -+ rtk_uint32 regAddr,regData; -+ rtk_uint16 *accessPtr; -+ rtk_uint32 i; -+ rtk_uint16 smiSvlanMemConf[RTL8367C_SVLAN_MEMCONF_LEN]; -+ -+ if(index > RTL8367C_SVIDXMAX) -+ return RT_ERR_SVLAN_ENTRY_INDEX; -+ -+ memset(smiSvlanMemConf, 0x00, sizeof(rtk_uint16) * RTL8367C_SVLAN_MEMCONF_LEN); -+ -+ accessPtr = smiSvlanMemConf; -+ -+ for(i = 0; i < 3; i++) -+ { -+ retVal = rtl8367c_getAsicReg(RTL8367C_SVLAN_MEMBERCFG_BASE_REG(index) + i, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *accessPtr = regData; -+ -+ accessPtr ++; -+ } -+ -+ if(index < 63) -+ regAddr = RTL8367C_REG_SVLAN_MEMBERCFG0_CTRL4+index; -+ else if(index == 63) -+ regAddr = RTL8367C_REG_SVLAN_MEMBERCFG63_CTRL4; -+ -+ retVal = rtl8367c_getAsicReg(regAddr, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *accessPtr = regData; -+ -+ _rtl8367c_svlanConfStSmi2User(pSvlanMemCfg, smiSvlanMemConf); -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicSvlanC2SConf -+ * Description: -+ * Set SVLAN C2S table -+ * Input: -+ * index - index of 128 Svlan C2S configuration -+ * evid - Enhanced VID -+ * portmask - available c2s port mask -+ * svidx - index of 64 Svlan member configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_ENTRY_INDEX - Invalid entry index -+ * Note: -+ * ASIC will check upstream's VID and assign related SVID to matched packet -+ */ -+ret_t rtl8367c_setAsicSvlanC2SConf(rtk_uint32 index, rtk_uint32 evid, rtk_uint32 portmask, rtk_uint32 svidx) -+{ -+ ret_t retVal; -+ -+ if(index > RTL8367C_C2SIDXMAX) -+ return RT_ERR_ENTRY_INDEX; -+ -+ retVal = rtl8367c_setAsicReg(RTL8367C_SVLAN_C2SCFG_BASE_REG(index), svidx); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicReg(RTL8367C_SVLAN_C2SCFG_BASE_REG(index) + 1, portmask); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_setAsicReg(RTL8367C_SVLAN_C2SCFG_BASE_REG(index) + 2, evid); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicSvlanC2SConf -+ * Description: -+ * Get SVLAN C2S table -+ * Input: -+ * index - index of 128 Svlan C2S configuration -+ * pEvid - Enhanced VID -+ * pPortmask - available c2s port mask -+ * pSvidx - index of 64 Svlan member configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_ENTRY_INDEX - Invalid entry index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicSvlanC2SConf(rtk_uint32 index, rtk_uint32* pEvid, rtk_uint32* pPortmask, rtk_uint32* pSvidx) -+{ -+ ret_t retVal; -+ -+ if(index > RTL8367C_C2SIDXMAX) -+ return RT_ERR_ENTRY_INDEX; -+ -+ retVal = rtl8367c_getAsicReg(RTL8367C_SVLAN_C2SCFG_BASE_REG(index), pSvidx); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_getAsicReg(RTL8367C_SVLAN_C2SCFG_BASE_REG(index) + 1, pPortmask); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ retVal = rtl8367c_getAsicReg(RTL8367C_SVLAN_C2SCFG_BASE_REG(index) + 2, pEvid); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicSvlanMC2SConf -+ * Description: -+ * Set system MC2S content -+ * Input: -+ * index - index of 32 SVLAN 32 MC2S configuration -+ * pSvlanMc2sCfg - SVLAN Multicast to SVLAN member configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_ENTRY_INDEX - Invalid entry index -+ * Note: -+ * If upstream packet is L2 multicast or IPv4 multicast packet and DMAC/DIP is matched MC2S -+ * configuration, ASIC will assign egress SVID to the packet -+ */ -+ret_t rtl8367c_setAsicSvlanMC2SConf(rtk_uint32 index,rtl8367c_svlan_mc2s_t* pSvlanMc2sCfg) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ rtk_uint16 *accessPtr; -+ rtk_uint32 i; -+ rtk_uint16 smiSvlanMC2S[RTL8367C_SVLAN_MC2S_LEN]; -+ -+ if(index > RTL8367C_MC2SIDXMAX) -+ return RT_ERR_ENTRY_INDEX; -+ -+ memset(smiSvlanMC2S, 0x00, sizeof(rtk_uint16) * RTL8367C_SVLAN_MC2S_LEN); -+ _rtl8367c_svlanMc2sStUser2Smi(pSvlanMc2sCfg, smiSvlanMC2S); -+ -+ accessPtr = smiSvlanMC2S; -+ -+ regData = *accessPtr; -+ for(i = 0; i < 5; i++) -+ { -+ retVal = rtl8367c_setAsicReg(RTL8367C_SVLAN_MCAST2S_ENTRY_BASE_REG(index) + i, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ accessPtr ++; -+ regData = *accessPtr; -+ } -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicSvlanMC2SConf -+ * Description: -+ * Get system MC2S content -+ * Input: -+ * index - index of 32 SVLAN 32 MC2S configuration -+ * pSvlanMc2sCfg - SVLAN Multicast to SVLAN member configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_ENTRY_INDEX - Invalid entry index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicSvlanMC2SConf(rtk_uint32 index, rtl8367c_svlan_mc2s_t* pSvlanMc2sCfg) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ rtk_uint16 *accessPtr; -+ rtk_uint32 i; -+ rtk_uint16 smiSvlanMC2S[RTL8367C_SVLAN_MC2S_LEN]; -+ -+ if(index > RTL8367C_MC2SIDXMAX) -+ return RT_ERR_ENTRY_INDEX; -+ -+ memset(smiSvlanMC2S, 0x00, sizeof(rtk_uint16) * RTL8367C_SVLAN_MC2S_LEN); -+ -+ accessPtr = smiSvlanMC2S; -+ -+ for(i = 0; i < 5; i++) -+ { -+ retVal = rtl8367c_getAsicReg(RTL8367C_SVLAN_MCAST2S_ENTRY_BASE_REG(index) + i, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *accessPtr = regData; -+ accessPtr ++; -+ } -+ -+ -+ _rtl8367c_svlanMc2sStSmi2User(pSvlanMc2sCfg, smiSvlanMC2S); -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicSvlanSP2CConf -+ * Description: -+ * Set system 128 SP2C content -+ * Input: -+ * index - index of 128 SVLAN & Port to CVLAN configuration -+ * pSvlanSp2cCfg - SVLAN & Port to CVLAN configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_ENTRY_INDEX - Invalid entry index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicSvlanSP2CConf(rtk_uint32 index, rtl8367c_svlan_s2c_t* pSvlanSp2cCfg) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ rtk_uint16 *accessPtr; -+ rtk_uint32 i; -+ rtk_uint16 smiSvlanSP2C[RTL8367C_SVLAN_SP2C_LEN]; -+ -+ if(index > RTL8367C_SP2CMAX) -+ return RT_ERR_ENTRY_INDEX; -+ -+ memset(smiSvlanSP2C, 0x00, sizeof(rtk_uint16) * RTL8367C_SVLAN_SP2C_LEN); -+ _rtl8367c_svlanSp2cStUser2Smi(pSvlanSp2cCfg,smiSvlanSP2C); -+ -+ accessPtr = smiSvlanSP2C; -+ -+ regData = *accessPtr; -+ for(i = 0; i < 2; i++) -+ { -+ retVal = rtl8367c_setAsicReg(RTL8367C_SVLAN_S2C_ENTRY_BASE_REG(index) + i, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ accessPtr ++; -+ regData = *accessPtr; -+ } -+ -+ return retVal; -+} -+/* Function Name: -+ * rtl8367c_getAsicSvlanSP2CConf -+ * Description: -+ * Get system 128 SP2C content -+ * Input: -+ * index - index of 128 SVLAN & Port to CVLAN configuration -+ * pSvlanSp2cCfg - SVLAN & Port to CVLAN configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_ENTRY_INDEX - Invalid entry index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicSvlanSP2CConf(rtk_uint32 index,rtl8367c_svlan_s2c_t* pSvlanSp2cCfg) -+{ -+ ret_t retVal; -+ rtk_uint32 regData; -+ rtk_uint16 *accessPtr; -+ rtk_uint32 i; -+ rtk_uint16 smiSvlanSP2C[RTL8367C_SVLAN_SP2C_LEN]; -+ -+ if(index > RTL8367C_SP2CMAX) -+ return RT_ERR_ENTRY_INDEX; -+ -+ memset(smiSvlanSP2C, 0x00, sizeof(rtk_uint16) * RTL8367C_SVLAN_SP2C_LEN); -+ -+ accessPtr = smiSvlanSP2C; -+ -+ for(i = 0; i < 2; i++) -+ { -+ retVal = rtl8367c_getAsicReg(RTL8367C_SVLAN_S2C_ENTRY_BASE_REG(index) + i, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *accessPtr = regData; -+ -+ accessPtr ++; -+ } -+ -+ _rtl8367c_svlanSp2cStSmi2User(pSvlanSp2cCfg, smiSvlanSP2C); -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicSvlanDmacCvidSel -+ * Description: -+ * Set downstream CVID decision by DMAC -+ * Input: -+ * port - Physical port number (0~7) -+ * enabled - 0:disabled, 1:enabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicSvlanDmacCvidSel(rtk_uint32 port, rtk_uint32 enabled) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(port < 8) -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_PORT0_DMACVIDSEL_OFFSET + port, enabled); -+ else -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_SVLAN_CFG_EXT, RTL8367C_VS_PORT8_DMACVIDSEL_OFFSET + (port-8), enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicSvlanDmacCvidSel -+ * Description: -+ * Get downstream CVID decision by DMAC -+ * Input: -+ * port - Physical port number (0~7) -+ * pEnabled - 0:disabled, 1:enabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicSvlanDmacCvidSel(rtk_uint32 port, rtk_uint32* pEnabled) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(port < 8) -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_PORT0_DMACVIDSEL_OFFSET + port, pEnabled); -+ else -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_SVLAN_CFG_EXT, RTL8367C_VS_PORT8_DMACVIDSEL_OFFSET + (port-8), pEnabled); -+} -+/* Function Name: -+ * rtl8367c_setAsicSvlanUntagVlan -+ * Description: -+ * Set default ingress untag SVLAN -+ * Input: -+ * index - index SVLAN member configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_SVLAN_ENTRY_INDEX - Invalid SVLAN index parameter -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicSvlanUntagVlan(rtk_uint32 index) -+{ -+ if(index > RTL8367C_SVIDXMAX) -+ return RT_ERR_SVLAN_ENTRY_INDEX; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_UNTAG_UNMAT_CFG, RTL8367C_VS_UNTAG_SVIDX_MASK, index); -+} -+/* Function Name: -+ * rtl8367c_getAsicSvlanUntagVlan -+ * Description: -+ * Get default ingress untag SVLAN -+ * Input: -+ * pIndex - index SVLAN member configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicSvlanUntagVlan(rtk_uint32* pIndex) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_UNTAG_UNMAT_CFG, RTL8367C_VS_UNTAG_SVIDX_MASK, pIndex); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicSvlanUnmatchVlan -+ * Description: -+ * Set default ingress unmatch SVLAN -+ * Input: -+ * index - index SVLAN member configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_SVLAN_ENTRY_INDEX - Invalid SVLAN index parameter -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicSvlanUnmatchVlan(rtk_uint32 index) -+{ -+ if(index > RTL8367C_SVIDXMAX) -+ return RT_ERR_SVLAN_ENTRY_INDEX; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_UNTAG_UNMAT_CFG, RTL8367C_VS_UNMAT_SVIDX_MASK, index); -+} -+/* Function Name: -+ * rtl8367c_getAsicSvlanUnmatchVlan -+ * Description: -+ * Get default ingress unmatch SVLAN -+ * Input: -+ * pIndex - index SVLAN member configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicSvlanUnmatchVlan(rtk_uint32* pIndex) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_UNTAG_UNMAT_CFG, RTL8367C_VS_UNMAT_SVIDX_MASK, pIndex); -+} -+ -+ -+/* Function Name: -+ * rtl8367c_setAsicSvlanLookupType -+ * Description: -+ * Set svlan lookup table selection -+ * Input: -+ * type - lookup type -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicSvlanLookupType(rtk_uint32 type) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_SVLAN_LOOKUP_TYPE, RTL8367C_SVLAN_LOOKUP_TYPE_OFFSET, type); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicSvlanLookupType -+ * Description: -+ * Get svlan lookup table selection -+ * Input: -+ * pType - lookup type -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicSvlanLookupType(rtk_uint32* pType) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_SVLAN_LOOKUP_TYPE, RTL8367C_SVLAN_LOOKUP_TYPE_OFFSET, pType); -+} -+ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_trunking.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_trunking.c -new file mode 100644 -index 000000000000..26d4c29b83b9 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_trunking.c -@@ -0,0 +1,356 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Port trunking related functions -+ * -+ */ -+ -+#include -+/* Function Name: -+ * rtl8367c_setAsicTrunkingMode -+ * Description: -+ * Set port trunking mode -+ * Input: -+ * mode - 1:dumb 0:user defined -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicTrunkingMode(rtk_uint32 mode) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_PORT_TRUNK_CTRL, RTL8367C_PORT_TRUNK_DUMB_OFFSET, mode); -+} -+/* Function Name: -+ * rtl8367c_getAsicTrunkingMode -+ * Description: -+ * Get port trunking mode -+ * Input: -+ * pMode - 1:dumb 0:user defined -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicTrunkingMode(rtk_uint32* pMode) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_PORT_TRUNK_CTRL, RTL8367C_PORT_TRUNK_DUMB_OFFSET, pMode); -+} -+/* Function Name: -+ * rtl8367c_setAsicTrunkingFc -+ * Description: -+ * Set port trunking flow control -+ * Input: -+ * group - Trunk Group ID -+ * enabled - 0:disable, 1:enable -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicTrunkingFc(rtk_uint32 group, rtk_uint32 enabled) -+{ -+ ret_t retVal; -+ -+ if(group > RTL8367C_MAX_TRUNK_GID) -+ return RT_ERR_LA_TRUNK_ID; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_PORT_TRUNK_DROP_CTRL, RTL8367C_PORT_TRUNK_DROP_CTRL_OFFSET, ENABLED)) != RT_ERR_OK) -+ return retVal; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_PORT_TRUNK_FLOWCTRL, (RTL8367C_EN_FLOWCTRL_TG0_OFFSET + group), enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicTrunkingFc -+ * Description: -+ * Get port trunking flow control -+ * Input: -+ * group - Trunk Group ID -+ * pEnabled - 0:disable, 1:enable -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicTrunkingFc(rtk_uint32 group, rtk_uint32* pEnabled) -+{ -+ if(group > RTL8367C_MAX_TRUNK_GID) -+ return RT_ERR_LA_TRUNK_ID; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_PORT_TRUNK_FLOWCTRL, (RTL8367C_EN_FLOWCTRL_TG0_OFFSET + group), pEnabled); -+} -+/* Function Name: -+ * rtl8367c_setAsicTrunkingGroup -+ * Description: -+ * Set trunking group available port mask -+ * Input: -+ * group - Trunk Group ID -+ * portmask - Logic trunking enable port mask, max 4 ports -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicTrunkingGroup(rtk_uint32 group, rtk_uint32 portmask) -+{ -+ if(group > RTL8367C_MAX_TRUNK_GID) -+ return RT_ERR_LA_TRUNK_ID; -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_PORT_TRUNK_GROUP_MASK, RTL8367C_PORT_TRUNK_GROUP0_MASK_MASK << (group * 4), portmask); -+} -+/* Function Name: -+ * rtl8367c_getAsicTrunkingGroup -+ * Description: -+ * Get trunking group available port mask -+ * Input: -+ * group - Trunk Group ID -+ * Output: -+ * pPortmask - Logic trunking enable port mask, max 4 ports -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicTrunkingGroup(rtk_uint32 group, rtk_uint32* pPortmask) -+{ -+ if(group > RTL8367C_MAX_TRUNK_GID) -+ return RT_ERR_LA_TRUNK_ID; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_TRUNK_GROUP_MASK, RTL8367C_PORT_TRUNK_GROUP0_MASK_MASK << (group * 4), pPortmask); -+} -+/* Function Name: -+ * rtl8367c_setAsicTrunkingFlood -+ * Description: -+ * Set port trunking flood function -+ * Input: -+ * enabled - Port trunking flooding function 0:disable 1:enable -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicTrunkingFlood(rtk_uint32 enabled) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_PORT_TRUNK_CTRL, RTL8367C_PORT_TRUNK_FLOOD_OFFSET, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicTrunkingFlood -+ * Description: -+ * Get port trunking flood function -+ * Input: -+ * pEnabled - Port trunking flooding function 0:disable 1:enable -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicTrunkingFlood(rtk_uint32* pEnabled) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_PORT_TRUNK_CTRL, RTL8367C_PORT_TRUNK_FLOOD_OFFSET, pEnabled); -+} -+/* Function Name: -+ * rtl8367c_setAsicTrunkingHashSelect -+ * Description: -+ * Set port trunking hash select sources -+ * Input: -+ * hashsel - hash sources mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * 7 bits mask for link aggregation group0 hash parameter selection {DIP, SIP, DMAC, SMAC, SPA} -+ * 0b0000001: SPA -+ * 0b0000010: SMAC -+ * 0b0000100: DMAC -+ * 0b0001000: SIP -+ * 0b0010000: DIP -+ * 0b0100000: TCP/UDP Source Port -+ * 0b1000000: TCP/UDP Destination Port -+ */ -+ret_t rtl8367c_setAsicTrunkingHashSelect(rtk_uint32 hashsel) -+{ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_PORT_TRUNK_CTRL, RTL8367C_PORT_TRUNK_HASH_MASK, hashsel); -+} -+/* Function Name: -+ * rtl8367c_getAsicTrunkingHashSelect -+ * Description: -+ * Get port trunking hash select sources -+ * Input: -+ * pHashsel - hash sources mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicTrunkingHashSelect(rtk_uint32* pHashsel) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_TRUNK_CTRL, RTL8367C_PORT_TRUNK_HASH_MASK, pHashsel); -+} -+/* Function Name: -+ * rtl8367c_getAsicQeueuEmptyStatus -+ * Description: -+ * Get current output queue if empty status -+ * Input: -+ * portmask - queue empty port mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicQeueuEmptyStatus(rtk_uint32* portmask) -+{ -+ return rtl8367c_getAsicReg(RTL8367C_REG_PORT_QEMPTY, portmask); -+} -+/* Function Name: -+ * rtl8367c_setAsicTrunkingHashTable -+ * Description: -+ * Set port trunking hash value mapping table -+ * Input: -+ * hashval - hashing value 0-15 -+ * portId - trunking port id 0-3 -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_OUT_OF_RANGE - Invalid hashing value (0-15) -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicTrunkingHashTable(rtk_uint32 hashval, rtk_uint32 portId) -+{ -+ if(hashval > RTL8367C_TRUNKING_HASHVALUE_MAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(portId >= RTL8367C_TRUNKING_PORTNO) -+ return RT_ERR_PORT_ID; -+ -+ if(hashval >= 8) -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL1, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH8_MASK<<((hashval-8)*2), portId); -+ else -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL0, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH0_MASK<<(hashval*2), portId); -+} -+/* Function Name: -+ * rtl8367c_getAsicTrunkingHashTable -+ * Description: -+ * Get port trunking hash value mapping table -+ * Input: -+ * hashval - hashing value 0-15 -+ * pPortId - trunking port id 0-3 -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - Invalid hashing value (0-15) -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicTrunkingHashTable(rtk_uint32 hashval, rtk_uint32* pPortId) -+{ -+ if(hashval > RTL8367C_TRUNKING_HASHVALUE_MAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(hashval >= 8) -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL1, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH8_MASK<<((hashval-8)*2), pPortId); -+ else -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL0, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH0_MASK<<(hashval*2), pPortId); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicTrunkingHashTable1 -+ * Description: -+ * Set port trunking hash value mapping table -+ * Input: -+ * hashval - hashing value 0-15 -+ * portId - trunking port id 0-3 -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_OUT_OF_RANGE - Invalid hashing value (0-15) -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicTrunkingHashTable1(rtk_uint32 hashval, rtk_uint32 portId) -+{ -+ if(hashval > RTL8367C_TRUNKING_HASHVALUE_MAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(portId >= RTL8367C_TRUNKING1_PORTN0) -+ return RT_ERR_PORT_ID; -+ -+ if(hashval >= 8) -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL3, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH8_MASK<<((hashval-8)*2), portId); -+ else -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL2, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH0_MASK<<(hashval*2), portId); -+} -+/* Function Name: -+ * rtl8367c_getAsicTrunkingHashTable1 -+ * Description: -+ * Get port trunking hash value mapping table -+ * Input: -+ * hashval - hashing value 0-15 -+ * pPortId - trunking port id 0-3 -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_OUT_OF_RANGE - Invalid hashing value (0-15) -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicTrunkingHashTable1(rtk_uint32 hashval, rtk_uint32* pPortId) -+{ -+ if(hashval > RTL8367C_TRUNKING_HASHVALUE_MAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(hashval >= 8) -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL3, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH8_MASK<<((hashval-8)*2), pPortId); -+ else -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL2, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH0_MASK<<(hashval*2), pPortId); -+} -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_unknownMulticast.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_unknownMulticast.c -new file mode 100644 -index 000000000000..a3455bbebdc6 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_unknownMulticast.c -@@ -0,0 +1,238 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : Unknown multicast related functions -+ * -+ */ -+ -+#include -+ -+/* Function Name: -+ * rtl8367c_setAsicUnknownL2MulticastBehavior -+ * Description: -+ * Set behavior of L2 multicast -+ * Input: -+ * port - Physical port number (0~7) -+ * behave - 0: flooding, 1: drop, 2: trap -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_NOT_ALLOWED - Invalid operation -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicUnknownL2MulticastBehavior(rtk_uint32 port, rtk_uint32 behave) -+{ -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(behave >= L2_UNKOWN_MULTICAST_END) -+ return RT_ERR_NOT_ALLOWED; -+ if(port < 8) -+ { -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_UNKNOWN_L2_MULTICAST_REG(port), RTL8367C_UNKNOWN_L2_MULTICAST_MASK(port), behave); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_UNKNOWN_L2_MULTICAST_CTRL1, 3 << ((port - 8) << 1), behave); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicUnknownL2MulticastBehavior -+ * Description: -+ * Get behavior of L2 multicast -+ * Input: -+ * port - Physical port number (0~7) -+ * pBehave - 0: flooding, 1: drop, 2: trap -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicUnknownL2MulticastBehavior(rtk_uint32 port, rtk_uint32 *pBehave) -+{ -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(port < 8) -+ { -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_UNKNOWN_L2_MULTICAST_REG(port), RTL8367C_UNKNOWN_L2_MULTICAST_MASK(port), pBehave); -+ if (retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_UNKNOWN_L2_MULTICAST_CTRL1, 3 << ((port - 8) << 1), pBehave); -+ if (retVal != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicUnknownIPv4MulticastBehavior -+ * Description: -+ * Set behavior of IPv4 multicast -+ * Input: -+ * port - Physical port number (0~7) -+ * behave - 0: flooding, 1: drop, 2: trap -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_NOT_ALLOWED - Invalid operation -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicUnknownIPv4MulticastBehavior(rtk_uint32 port, rtk_uint32 behave) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(behave >= L3_UNKOWN_MULTICAST_END) -+ return RT_ERR_NOT_ALLOWED; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_UNKNOWN_IPV4_MULTICAST_REG(port), RTL8367C_UNKNOWN_IPV4_MULTICAST_MASK(port), behave); -+} -+/* Function Name: -+ * rtl8367c_getAsicUnknownIPv4MulticastBehavior -+ * Description: -+ * Get behavior of IPv4 multicast -+ * Input: -+ * port - Physical port number (0~7) -+ * pBehave - 0: flooding, 1: drop, 2: trap -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicUnknownIPv4MulticastBehavior(rtk_uint32 port, rtk_uint32 *pBehave) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_UNKNOWN_IPV4_MULTICAST_REG(port), RTL8367C_UNKNOWN_IPV4_MULTICAST_MASK(port), pBehave); -+} -+/* Function Name: -+ * rtl8367c_setAsicUnknownIPv6MulticastBehavior -+ * Description: -+ * Set behavior of IPv6 multicast -+ * Input: -+ * port - Physical port number (0~7) -+ * behave - 0: flooding, 1: drop, 2: trap -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_NOT_ALLOWED - Invalid operation -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicUnknownIPv6MulticastBehavior(rtk_uint32 port, rtk_uint32 behave) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(behave >= L3_UNKOWN_MULTICAST_END) -+ return RT_ERR_NOT_ALLOWED; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_UNKNOWN_IPV6_MULTICAST_REG(port), RTL8367C_UNKNOWN_IPV6_MULTICAST_MASK(port), behave); -+} -+/* Function Name: -+ * rtl8367c_getAsicUnknownIPv6MulticastBehavior -+ * Description: -+ * Get behavior of IPv6 multicast -+ * Input: -+ * port - Physical port number (0~7) -+ * pBehave - 0: flooding, 1: drop, 2: trap -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicUnknownIPv6MulticastBehavior(rtk_uint32 port, rtk_uint32 *pBehave) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_UNKNOWN_IPV6_MULTICAST_REG(port), RTL8367C_UNKNOWN_IPV6_MULTICAST_MASK(port), pBehave); -+} -+/* Function Name: -+ * rtl8367c_setAsicUnknownMulticastTrapPriority -+ * Description: -+ * Set trap priority of unknown multicast frame -+ * Input: -+ * priority - priority (0~7) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicUnknownMulticastTrapPriority(rtk_uint32 priority) -+{ -+ if(priority > RTL8367C_PRIMAX) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_QOS_TRAP_PRIORITY_CTRL0_REG, RTL8367C_UNKNOWN_MC_PRIORTY_MASK, priority); -+} -+/* Function Name: -+ * rtl8367c_getAsicUnknownMulticastTrapPriority -+ * Description: -+ * Get trap priority of unknown multicast frame -+ * Input: -+ * pPriority - priority (0~7) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicUnknownMulticastTrapPriority(rtk_uint32 *pPriority) -+{ -+ return rtl8367c_getAsicRegBits(RTL8367C_QOS_TRAP_PRIORITY_CTRL0_REG, RTL8367C_UNKNOWN_MC_PRIORTY_MASK, pPriority); -+} -diff --git a/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_vlan.c b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_vlan.c -new file mode 100644 -index 000000000000..1e283e7432c0 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_vlan.c -@@ -0,0 +1,1505 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTL8367C switch high-level API for RTL8367C -+ * Feature : VLAN related functions -+ * -+ */ -+#include -+ -+#include -+ -+#if defined(CONFIG_RTL8367C_ASICDRV_TEST) -+rtl8367c_user_vlan4kentry Rtl8370sVirtualVlanTable[RTL8367C_VIDMAX + 1]; -+#endif -+ -+static void _rtl8367c_VlanMCStUser2Smi(rtl8367c_vlanconfiguser *pVlanCg, rtk_uint16 *pSmiVlanCfg) -+{ -+ pSmiVlanCfg[0] |= pVlanCg->mbr & 0x07FF; -+ -+ pSmiVlanCfg[1] |= pVlanCg->fid_msti & 0x000F; -+ -+ pSmiVlanCfg[2] |= pVlanCg->vbpen & 0x0001; -+ pSmiVlanCfg[2] |= (pVlanCg->vbpri & 0x0007) << 1; -+ pSmiVlanCfg[2] |= (pVlanCg->envlanpol & 0x0001) << 4; -+ pSmiVlanCfg[2] |= (pVlanCg->meteridx & 0x003F) << 5; -+ -+ pSmiVlanCfg[3] |= pVlanCg->evid & 0x1FFF; -+} -+ -+static void _rtl8367c_VlanMCStSmi2User(rtk_uint16 *pSmiVlanCfg, rtl8367c_vlanconfiguser *pVlanCg) -+{ -+ pVlanCg->mbr = pSmiVlanCfg[0] & 0x07FF; -+ pVlanCg->fid_msti = pSmiVlanCfg[1] & 0x000F; -+ pVlanCg->meteridx = (pSmiVlanCfg[2] >> 5) & 0x003F; -+ pVlanCg->envlanpol = (pSmiVlanCfg[2] >> 4) & 0x0001; -+ pVlanCg->vbpri = (pSmiVlanCfg[2] >> 1) & 0x0007; -+ pVlanCg->vbpen = pSmiVlanCfg[2] & 0x0001; -+ pVlanCg->evid = pSmiVlanCfg[3] & 0x1FFF; -+} -+ -+static void _rtl8367c_Vlan4kStUser2Smi(rtl8367c_user_vlan4kentry *pUserVlan4kEntry, rtk_uint16 *pSmiVlan4kEntry) -+{ -+ pSmiVlan4kEntry[0] |= (pUserVlan4kEntry->mbr & 0x00FF); -+ pSmiVlan4kEntry[0] |= (pUserVlan4kEntry->untag & 0x00FF) << 8; -+ -+ pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->fid_msti & 0x000F); -+ pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->vbpen & 0x0001) << 4; -+ pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->vbpri & 0x0007) << 5; -+ pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->envlanpol & 0x0001) << 8; -+ pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->meteridx & 0x001F) << 9; -+ pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->ivl_svl & 0x0001) << 14; -+ -+ pSmiVlan4kEntry[2] |= ((pUserVlan4kEntry->mbr & 0x0700) >> 8); -+ pSmiVlan4kEntry[2] |= ((pUserVlan4kEntry->untag & 0x0700) >> 8) << 3; -+ pSmiVlan4kEntry[2] |= ((pUserVlan4kEntry->meteridx & 0x0020) >> 5) << 6; -+} -+ -+ -+static void _rtl8367c_Vlan4kStSmi2User(rtk_uint16 *pSmiVlan4kEntry, rtl8367c_user_vlan4kentry *pUserVlan4kEntry) -+{ -+ pUserVlan4kEntry->mbr = (pSmiVlan4kEntry[0] & 0x00FF) | ((pSmiVlan4kEntry[2] & 0x0007) << 8); -+ pUserVlan4kEntry->untag = ((pSmiVlan4kEntry[0] & 0xFF00) >> 8) | (((pSmiVlan4kEntry[2] & 0x0038) >> 3) << 8); -+ pUserVlan4kEntry->fid_msti = pSmiVlan4kEntry[1] & 0x000F; -+ pUserVlan4kEntry->vbpen = (pSmiVlan4kEntry[1] & 0x0010) >> 4; -+ pUserVlan4kEntry->vbpri = (pSmiVlan4kEntry[1] & 0x00E0) >> 5; -+ pUserVlan4kEntry->envlanpol = (pSmiVlan4kEntry[1] & 0x0100) >> 8; -+ pUserVlan4kEntry->meteridx = ((pSmiVlan4kEntry[1] & 0x3E00) >> 9) | (((pSmiVlan4kEntry[2] & 0x0040) >> 6) << 5); -+ pUserVlan4kEntry->ivl_svl = (pSmiVlan4kEntry[1] & 0x4000) >> 14; -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicVlanMemberConfig -+ * Description: -+ * Set 32 VLAN member configurations -+ * Input: -+ * index - VLAN member configuration index (0~31) -+ * pVlanCg - VLAN member configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter -+ * RT_ERR_L2_FID - Invalid FID -+ * RT_ERR_PORT_MASK - Invalid portmask -+ * RT_ERR_FILTER_METER_ID - Invalid meter -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority -+ * RT_ERR_VLAN_ENTRY_NOT_FOUND - Invalid VLAN member configuration index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicVlanMemberConfig(rtk_uint32 index, rtl8367c_vlanconfiguser *pVlanCg) -+{ -+ ret_t retVal; -+ rtk_uint32 regAddr; -+ rtk_uint32 regData; -+ rtk_uint16 *tableAddr; -+ rtk_uint32 page_idx; -+ rtk_uint16 smi_vlancfg[RTL8367C_VLAN_MBRCFG_LEN]; -+ -+ /* Error Checking */ -+ if(index > RTL8367C_CVIDXMAX) -+ return RT_ERR_VLAN_ENTRY_NOT_FOUND; -+ -+ if(pVlanCg->evid > RTL8367C_EVIDMAX) -+ return RT_ERR_INPUT; -+ -+ -+ if(pVlanCg->mbr > RTL8367C_PORTMASK) -+ return RT_ERR_PORT_MASK; -+ -+ if(pVlanCg->fid_msti > RTL8367C_FIDMAX) -+ return RT_ERR_L2_FID; -+ -+ if(pVlanCg->meteridx > RTL8367C_METERMAX) -+ return RT_ERR_FILTER_METER_ID; -+ -+ if(pVlanCg->vbpri > RTL8367C_PRIMAX) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ memset(smi_vlancfg, 0x00, sizeof(rtk_uint16) * RTL8367C_VLAN_MBRCFG_LEN); -+ _rtl8367c_VlanMCStUser2Smi(pVlanCg, smi_vlancfg); -+ tableAddr = smi_vlancfg; -+ -+ for(page_idx = 0; page_idx < 4; page_idx++) /* 4 pages per VLAN Member Config */ -+ { -+ regAddr = RTL8367C_VLAN_MEMBER_CONFIGURATION_BASE + (index * 4) + page_idx; -+ regData = *tableAddr; -+ -+ retVal = rtl8367c_setAsicReg(regAddr, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ tableAddr++; -+ } -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicVlanMemberConfig -+ * Description: -+ * Get 32 VLAN member configurations -+ * Input: -+ * index - VLAN member configuration index (0~31) -+ * pVlanCg - VLAN member configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter -+ * RT_ERR_VLAN_ENTRY_NOT_FOUND - Invalid VLAN member configuration index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicVlanMemberConfig(rtk_uint32 index, rtl8367c_vlanconfiguser *pVlanCg) -+{ -+ ret_t retVal; -+ rtk_uint32 page_idx; -+ rtk_uint32 regAddr; -+ rtk_uint32 regData; -+ rtk_uint16 *tableAddr; -+ rtk_uint16 smi_vlancfg[RTL8367C_VLAN_MBRCFG_LEN]; -+ -+ if(index > RTL8367C_CVIDXMAX) -+ return RT_ERR_VLAN_ENTRY_NOT_FOUND; -+ -+ memset(smi_vlancfg, 0x00, sizeof(rtk_uint16) * RTL8367C_VLAN_MBRCFG_LEN); -+ tableAddr = smi_vlancfg; -+ -+ for(page_idx = 0; page_idx < 4; page_idx++) /* 4 pages per VLAN Member Config */ -+ { -+ regAddr = RTL8367C_VLAN_MEMBER_CONFIGURATION_BASE + (index * 4) + page_idx; -+ -+ retVal = rtl8367c_getAsicReg(regAddr, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *tableAddr = (rtk_uint16)regData; -+ tableAddr++; -+ } -+ -+ _rtl8367c_VlanMCStSmi2User(smi_vlancfg, pVlanCg); -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicVlan4kEntry -+ * Description: -+ * Set VID mapped entry to 4K VLAN table -+ * Input: -+ * pVlan4kEntry - 4K VLAN configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter -+ * RT_ERR_L2_FID - Invalid FID -+ * RT_ERR_VLAN_VID - Invalid VID parameter (0~4095) -+ * RT_ERR_PORT_MASK - Invalid portmask -+ * RT_ERR_FILTER_METER_ID - Invalid meter -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicVlan4kEntry(rtl8367c_user_vlan4kentry *pVlan4kEntry ) -+{ -+ rtk_uint16 vlan_4k_entry[RTL8367C_VLAN_4KTABLE_LEN]; -+ rtk_uint32 page_idx; -+ rtk_uint16 *tableAddr; -+ ret_t retVal; -+ rtk_uint32 regData; -+ -+ if(pVlan4kEntry->vid > RTL8367C_VIDMAX) -+ return RT_ERR_VLAN_VID; -+ -+ if(pVlan4kEntry->mbr > RTL8367C_PORTMASK) -+ return RT_ERR_PORT_MASK; -+ -+ if(pVlan4kEntry->untag > RTL8367C_PORTMASK) -+ return RT_ERR_PORT_MASK; -+ -+ if(pVlan4kEntry->fid_msti > RTL8367C_FIDMAX) -+ return RT_ERR_L2_FID; -+ -+ if(pVlan4kEntry->meteridx > RTL8367C_METERMAX) -+ return RT_ERR_FILTER_METER_ID; -+ -+ if(pVlan4kEntry->vbpri > RTL8367C_PRIMAX) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ memset(vlan_4k_entry, 0x00, sizeof(rtk_uint16) * RTL8367C_VLAN_4KTABLE_LEN); -+ _rtl8367c_Vlan4kStUser2Smi(pVlan4kEntry, vlan_4k_entry); -+ -+ /* Prepare Data */ -+ tableAddr = vlan_4k_entry; -+ for(page_idx = 0; page_idx < RTL8367C_VLAN_4KTABLE_LEN; page_idx++) -+ { -+ regData = *tableAddr; -+ retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_WRDATA_BASE + page_idx, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ tableAddr++; -+ } -+ -+ /* Write Address (VLAN_ID) */ -+ regData = pVlan4kEntry->vid; -+ retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_ADDR_REG, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ /* Write Command */ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_TABLE_ACCESS_CTRL_REG, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK,RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_WRITE,TB_TARGET_CVLAN)); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+#if defined(CONFIG_RTL8367C_ASICDRV_TEST) -+ memcpy(&Rtl8370sVirtualVlanTable[pVlan4kEntry->vid], pVlan4kEntry, sizeof(rtl8367c_user_vlan4kentry)); -+#endif -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicVlan4kEntry -+ * Description: -+ * Get VID mapped entry to 4K VLAN table -+ * Input: -+ * pVlan4kEntry - 4K VLAN configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_VLAN_VID - Invalid VID parameter (0~4095) -+ * RT_ERR_BUSYWAIT_TIMEOUT - LUT is busy at retrieving -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicVlan4kEntry(rtl8367c_user_vlan4kentry *pVlan4kEntry ) -+{ -+ rtk_uint16 vlan_4k_entry[RTL8367C_VLAN_4KTABLE_LEN]; -+ rtk_uint32 page_idx; -+ rtk_uint16 *tableAddr; -+ ret_t retVal; -+ rtk_uint32 regData; -+ rtk_uint32 busyCounter; -+ -+ if(pVlan4kEntry->vid > RTL8367C_VIDMAX) -+ return RT_ERR_VLAN_VID; -+ -+ /* Polling status */ -+ busyCounter = RTL8367C_VLAN_BUSY_CHECK_NO; -+ while(busyCounter) -+ { -+ retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_OFFSET,®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ if(regData == 0) -+ break; -+ -+ busyCounter --; -+ if(busyCounter == 0) -+ return RT_ERR_BUSYWAIT_TIMEOUT; -+ } -+ -+ /* Write Address (VLAN_ID) */ -+ regData = pVlan4kEntry->vid; -+ retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_ADDR_REG, regData); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ /* Read Command */ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_TABLE_ACCESS_CTRL_REG, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK, RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_READ,TB_TARGET_CVLAN)); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ /* Polling status */ -+ busyCounter = RTL8367C_VLAN_BUSY_CHECK_NO; -+ while(busyCounter) -+ { -+ retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_OFFSET,®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ if(regData == 0) -+ break; -+ -+ busyCounter --; -+ if(busyCounter == 0) -+ return RT_ERR_BUSYWAIT_TIMEOUT; -+ } -+ -+ /* Read VLAN data from register */ -+ tableAddr = vlan_4k_entry; -+ for(page_idx = 0; page_idx < RTL8367C_VLAN_4KTABLE_LEN; page_idx++) -+ { -+ retVal = rtl8367c_getAsicReg(RTL8367C_TABLE_ACCESS_RDDATA_BASE + page_idx, ®Data); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *tableAddr = regData; -+ tableAddr++; -+ } -+ -+ _rtl8367c_Vlan4kStSmi2User(vlan_4k_entry, pVlan4kEntry); -+ -+#if defined(CONFIG_RTL8367C_ASICDRV_TEST) -+ memcpy(pVlan4kEntry, &Rtl8370sVirtualVlanTable[pVlan4kEntry->vid], sizeof(rtl8367c_user_vlan4kentry)); -+#endif -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicVlanAccpetFrameType -+ * Description: -+ * Set per-port acceptable frame type -+ * Input: -+ * port - Physical port number (0~10) -+ * frameType - The acceptable frame type -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_VLAN_ACCEPT_FRAME_TYPE - Invalid frame type -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicVlanAccpetFrameType(rtk_uint32 port, rtl8367c_accframetype frameType) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(frameType >= FRAME_TYPE_MAX_BOUND) -+ return RT_ERR_VLAN_ACCEPT_FRAME_TYPE; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_VLAN_ACCEPT_FRAME_TYPE_REG(port), RTL8367C_VLAN_ACCEPT_FRAME_TYPE_MASK(port), frameType); -+} -+/* Function Name: -+ * rtl8367c_getAsicVlanAccpetFrameType -+ * Description: -+ * Get per-port acceptable frame type -+ * Input: -+ * port - Physical port number (0~10) -+ * pFrameType - The acceptable frame type -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_VLAN_ACCEPT_FRAME_TYPE - Invalid frame type -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicVlanAccpetFrameType(rtk_uint32 port, rtl8367c_accframetype *pFrameType) -+{ -+ rtk_uint32 regData; -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if((retVal = rtl8367c_getAsicRegBits(RTL8367C_VLAN_ACCEPT_FRAME_TYPE_REG(port), RTL8367C_VLAN_ACCEPT_FRAME_TYPE_MASK(port), ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ *pFrameType = (rtl8367c_accframetype)regData; -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicVlanIngressFilter -+ * Description: -+ * Set VLAN Ingress Filter -+ * Input: -+ * port - Physical port number (0~10) -+ * enabled - Enable or disable Ingress filter -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicVlanIngressFilter(rtk_uint32 port, rtk_uint32 enabled) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_VLAN_INGRESS_REG, port, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicVlanIngressFilter -+ * Description: -+ * Get VLAN Ingress Filter -+ * Input: -+ * port - Physical port number (0~10) -+ * pEnable - Enable or disable Ingress filter -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicVlanIngressFilter(rtk_uint32 port, rtk_uint32 *pEnable) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_VLAN_INGRESS_REG, port, pEnable); -+} -+/* Function Name: -+ * rtl8367c_setAsicVlanEgressTagMode -+ * Description: -+ * Set CVLAN egress tag mode -+ * Input: -+ * port - Physical port number (0~10) -+ * tagMode - The egress tag mode. Including Original mode, Keep tag mode and Priority tag mode -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicVlanEgressTagMode(rtk_uint32 port, rtl8367c_egtagmode tagMode) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(tagMode >= EG_TAG_MODE_END) -+ return RT_ERR_INPUT; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_PORT_MISC_CFG_REG(port), RTL8367C_VLAN_EGRESS_MDOE_MASK, tagMode); -+} -+/* Function Name: -+ * rtl8367c_getAsicVlanEgressTagMode -+ * Description: -+ * Get CVLAN egress tag mode -+ * Input: -+ * port - Physical port number (0~10) -+ * pTagMode - The egress tag mode. Including Original mode, Keep tag mode and Priority tag mode -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicVlanEgressTagMode(rtk_uint32 port, rtl8367c_egtagmode *pTagMode) -+{ -+ rtk_uint32 regData; -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if((retVal = rtl8367c_getAsicRegBits(RTL8367C_PORT_MISC_CFG_REG(port), RTL8367C_VLAN_EGRESS_MDOE_MASK, ®Data)) != RT_ERR_OK) -+ return retVal; -+ -+ *pTagMode = (rtl8367c_egtagmode)regData; -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicVlanPortBasedVID -+ * Description: -+ * Set port based VID which is indexed to 32 VLAN member configurations -+ * Input: -+ * port - Physical port number (0~10) -+ * index - Index to VLAN member configuration -+ * pri - 1Q Port based VLAN priority -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority -+ * RT_ERR_VLAN_ENTRY_NOT_FOUND - Invalid VLAN member configuration index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicVlanPortBasedVID(rtk_uint32 port, rtk_uint32 index, rtk_uint32 pri) -+{ -+ rtk_uint32 regAddr, bit_mask; -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(index > RTL8367C_CVIDXMAX) -+ return RT_ERR_VLAN_ENTRY_NOT_FOUND; -+ -+ if(pri > RTL8367C_PRIMAX) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ regAddr = RTL8367C_VLAN_PVID_CTRL_REG(port); -+ bit_mask = RTL8367C_PORT_VIDX_MASK(port); -+ retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, index); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ regAddr = RTL8367C_VLAN_PORTBASED_PRIORITY_REG(port); -+ bit_mask = RTL8367C_VLAN_PORTBASED_PRIORITY_MASK(port); -+ retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, pri); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicVlanPortBasedVID -+ * Description: -+ * Get port based VID which is indexed to 32 VLAN member configurations -+ * Input: -+ * port - Physical port number (0~10) -+ * pIndex - Index to VLAN member configuration -+ * pPri - 1Q Port based VLAN priority -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicVlanPortBasedVID(rtk_uint32 port, rtk_uint32 *pIndex, rtk_uint32 *pPri) -+{ -+ rtk_uint32 regAddr,bit_mask; -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ regAddr = RTL8367C_VLAN_PVID_CTRL_REG(port); -+ bit_mask = RTL8367C_PORT_VIDX_MASK(port); -+ retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, pIndex); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ regAddr = RTL8367C_VLAN_PORTBASED_PRIORITY_REG(port); -+ bit_mask = RTL8367C_VLAN_PORTBASED_PRIORITY_MASK(port); -+ retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, pPri); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicVlanProtocolBasedGroupData -+ * Description: -+ * Set protocol and port based group database -+ * Input: -+ * index - Index to VLAN member configuration -+ * pPbCfg - Protocol and port based group database entry -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter -+ * RT_ERR_VLAN_PROTO_AND_PORT - Invalid protocol base group database index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicVlanProtocolBasedGroupData(rtk_uint32 index, rtl8367c_protocolgdatacfg *pPbCfg) -+{ -+ rtk_uint32 frameType; -+ rtk_uint32 etherType; -+ ret_t retVal; -+ -+ /* Error Checking */ -+ if(index > RTL8367C_PROTOVLAN_GIDX_MAX) -+ return RT_ERR_VLAN_PROTO_AND_PORT; -+ -+ if(pPbCfg->frameType >= PPVLAN_FRAME_TYPE_END ) -+ return RT_ERR_INPUT; -+ -+ frameType = pPbCfg->frameType; -+ etherType = pPbCfg->etherType; -+ -+ /* Frame type */ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_VLAN_PPB_FRAMETYPE_REG(index), RTL8367C_VLAN_PPB_FRAMETYPE_MASK, frameType); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ /* Ether type */ -+ retVal = rtl8367c_setAsicReg(RTL8367C_VLAN_PPB_ETHERTYPR_REG(index), etherType); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicVlanProtocolBasedGroupData -+ * Description: -+ * Get protocol and port based group database -+ * Input: -+ * index - Index to VLAN member configuration -+ * pPbCfg - Protocol and port based group database entry -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter -+ * RT_ERR_VLAN_PROTO_AND_PORT - Invalid protocol base group database index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicVlanProtocolBasedGroupData(rtk_uint32 index, rtl8367c_protocolgdatacfg *pPbCfg) -+{ -+ rtk_uint32 frameType; -+ rtk_uint32 etherType; -+ ret_t retVal; -+ -+ /* Error Checking */ -+ if(index > RTL8367C_PROTOVLAN_GIDX_MAX) -+ return RT_ERR_VLAN_PROTO_AND_PORT; -+ -+ /* Read Frame type */ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_VLAN_PPB_FRAMETYPE_REG(index), RTL8367C_VLAN_PPB_FRAMETYPE_MASK, &frameType); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ /* Read Ether type */ -+ retVal = rtl8367c_getAsicReg(RTL8367C_VLAN_PPB_ETHERTYPR_REG(index), ðerType); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ -+ pPbCfg->frameType = frameType; -+ pPbCfg->etherType = etherType; -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicVlanPortAndProtocolBased -+ * Description: -+ * Set protocol and port based VLAN configuration -+ * Input: -+ * port - Physical port number (0~10) -+ * index - Index of protocol and port based database index -+ * pPpbCfg - Protocol and port based VLAN configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_QOS_INT_PRIORITY - Invalid priority -+ * RT_ERR_VLAN_PROTO_AND_PORT - Invalid protocol base group database index -+ * RT_ERR_VLAN_ENTRY_NOT_FOUND - Invalid VLAN member configuration index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicVlanPortAndProtocolBased(rtk_uint32 port, rtk_uint32 index, rtl8367c_protocolvlancfg *pPpbCfg) -+{ -+ rtk_uint32 reg_addr, bit_mask, bit_value; -+ ret_t retVal; -+ -+ /* Error Checking */ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(index > RTL8367C_PROTOVLAN_GIDX_MAX) -+ return RT_ERR_VLAN_PROTO_AND_PORT; -+ -+ if( (pPpbCfg->valid != FALSE) && (pPpbCfg->valid != TRUE) ) -+ return RT_ERR_INPUT; -+ -+ if(pPpbCfg->vlan_idx > RTL8367C_CVIDXMAX) -+ return RT_ERR_VLAN_ENTRY_NOT_FOUND; -+ -+ if(pPpbCfg->priority > RTL8367C_PRIMAX) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ /* Valid bit */ -+ reg_addr = RTL8367C_VLAN_PPB_VALID_REG(index); -+ bit_mask = 0x0001 << port; -+ bit_value = ((TRUE == pPpbCfg->valid) ? 0x1 : 0x0); -+ retVal = rtl8367c_setAsicRegBits(reg_addr, bit_mask, bit_value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ /* Calculate the actual register address for CVLAN index*/ -+ if(port < 8) -+ { -+ reg_addr = RTL8367C_VLAN_PPB_CTRL_REG(index, port); -+ bit_mask = RTL8367C_VLAN_PPB_CTRL_MASK(port); -+ } -+ else if(port == 8) -+ { -+ reg_addr = RTL8367C_REG_VLAN_PPB0_CTRL4; -+ bit_mask = RTL8367C_VLAN_PPB0_CTRL4_PORT8_INDEX_MASK; -+ } -+ else if(port == 9) -+ { -+ reg_addr = RTL8367C_REG_VLAN_PPB0_CTRL4; -+ bit_mask = RTL8367C_VLAN_PPB0_CTRL4_PORT9_INDEX_MASK; -+ } -+ else if(port == 10) -+ { -+ reg_addr = RTL8367C_REG_VLAN_PPB0_CTRL4; -+ bit_mask = RTL8367C_VLAN_PPB0_CTRL4_PORT10_INDEX_MASK; -+ } -+ -+ bit_value = pPpbCfg->vlan_idx; -+ retVal = rtl8367c_setAsicRegBits(reg_addr, bit_mask, bit_value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ /* write priority */ -+ reg_addr = RTL8367C_VLAN_PPB_PRIORITY_ITEM_REG(port, index); -+ bit_mask = RTL8367C_VLAN_PPB_PRIORITY_ITEM_MASK(port); -+ bit_value = pPpbCfg->priority; -+ retVal = rtl8367c_setAsicRegBits(reg_addr, bit_mask, bit_value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_getAsicVlanPortAndProtocolBased -+ * Description: -+ * Get protocol and port based VLAN configuration -+ * Input: -+ * port - Physical port number (0~7) -+ * index - Index of protocol and port based database index -+ * pPpbCfg - Protocol and port based VLAN configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_VLAN_PROTO_AND_PORT - Invalid protocol base group database index -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicVlanPortAndProtocolBased(rtk_uint32 port, rtk_uint32 index, rtl8367c_protocolvlancfg *pPpbCfg) -+{ -+ rtk_uint32 reg_addr, bit_mask, bit_value; -+ ret_t retVal; -+ -+ /* Error Checking */ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(index > RTL8367C_PROTOVLAN_GIDX_MAX) -+ return RT_ERR_VLAN_PROTO_AND_PORT; -+ -+ if(pPpbCfg == NULL) -+ return RT_ERR_INPUT; -+ -+ /* Valid bit */ -+ reg_addr = RTL8367C_VLAN_PPB_VALID_REG(index); -+ bit_mask = 0x0001 << port; -+ retVal = rtl8367c_getAsicRegBits(reg_addr, bit_mask, &bit_value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ pPpbCfg->valid = bit_value; -+ -+ /* CVLAN index */ -+ if(port < 8) -+ { -+ reg_addr = RTL8367C_VLAN_PPB_CTRL_REG(index, port); -+ bit_mask = RTL8367C_VLAN_PPB_CTRL_MASK(port); -+ } -+ else if(port == 8) -+ { -+ reg_addr = RTL8367C_REG_VLAN_PPB0_CTRL4; -+ bit_mask = RTL8367C_VLAN_PPB0_CTRL4_PORT8_INDEX_MASK; -+ } -+ else if(port == 9) -+ { -+ reg_addr = RTL8367C_REG_VLAN_PPB0_CTRL4; -+ bit_mask = RTL8367C_VLAN_PPB0_CTRL4_PORT9_INDEX_MASK; -+ } -+ else if(port == 10) -+ { -+ reg_addr = RTL8367C_REG_VLAN_PPB0_CTRL4; -+ bit_mask = RTL8367C_VLAN_PPB0_CTRL4_PORT10_INDEX_MASK; -+ } -+ -+ retVal = rtl8367c_getAsicRegBits(reg_addr, bit_mask, &bit_value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ pPpbCfg->vlan_idx = bit_value; -+ -+ -+ /* priority */ -+ reg_addr = RTL8367C_VLAN_PPB_PRIORITY_ITEM_REG(port,index); -+ bit_mask = RTL8367C_VLAN_PPB_PRIORITY_ITEM_MASK(port); -+ retVal = rtl8367c_getAsicRegBits(reg_addr, bit_mask, &bit_value); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ pPpbCfg->priority = bit_value; -+ return RT_ERR_OK; -+} -+/* Function Name: -+ * rtl8367c_setAsicVlanFilter -+ * Description: -+ * Set enable CVLAN filtering function -+ * Input: -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicVlanFilter(rtk_uint32 enabled) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_VLAN_CTRL, RTL8367C_VLAN_CTRL_OFFSET, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicVlanFilter -+ * Description: -+ * Get enable CVLAN filtering function -+ * Input: -+ * pEnabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicVlanFilter(rtk_uint32* pEnabled) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_VLAN_CTRL, RTL8367C_VLAN_CTRL_OFFSET, pEnabled); -+} -+/* Function Name: -+ * rtl8367c_setAsicVlanUntagDscpPriorityEn -+ * Description: -+ * Set enable Dscp to untag 1Q priority -+ * Input: -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicVlanUntagDscpPriorityEn(rtk_uint32 enabled) -+{ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_UNTAG_DSCP_PRI_CFG, RTL8367C_UNTAG_DSCP_PRI_CFG_OFFSET, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicVlanUntagDscpPriorityEn -+ * Description: -+ * Get enable Dscp to untag 1Q priority -+ * Input: -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicVlanUntagDscpPriorityEn(rtk_uint32* enabled) -+{ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_UNTAG_DSCP_PRI_CFG, RTL8367C_UNTAG_DSCP_PRI_CFG_OFFSET, enabled); -+} -+/* Function Name: -+ * rtl8367c_setAsicPortBasedFid -+ * Description: -+ * Set port based FID -+ * Input: -+ * port - Physical port number (0~10) -+ * fid - Port based fid -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_L2_FID - Invalid FID -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortBasedFid(rtk_uint32 port, rtk_uint32 fid) -+{ -+ rtk_uint32 reg_addr; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(fid > RTL8367C_FIDMAX) -+ return RT_ERR_L2_FID; -+ -+ if(port < 8) -+ return rtl8367c_setAsicReg(RTL8367C_PORT_PBFID_REG(port),fid); -+ else { -+ reg_addr = RTL8367C_REG_PORT8_PBFID + port-8; -+ return rtl8367c_setAsicReg(reg_addr, fid); -+ } -+ -+} -+/* Function Name: -+ * rtl8367c_getAsicPortBasedFid -+ * Description: -+ * Get port based FID -+ * Input: -+ * port - Physical port number (0~7) -+ * pFid - Port based fid -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortBasedFid(rtk_uint32 port, rtk_uint32* pFid) -+{ -+ rtk_uint32 reg_addr; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(port < 8) -+ return rtl8367c_getAsicReg(RTL8367C_PORT_PBFID_REG(port), pFid); -+ else{ -+ reg_addr = RTL8367C_REG_PORT8_PBFID + port-8; -+ return rtl8367c_getAsicReg(reg_addr, pFid); -+ } -+} -+/* Function Name: -+ * rtl8367c_setAsicPortBasedFidEn -+ * Description: -+ * Set port based FID selection enable -+ * Input: -+ * port - Physical port number (0~10) -+ * enabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicPortBasedFidEn(rtk_uint32 port, rtk_uint32 enabled) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_setAsicRegBit(RTL8367C_REG_PORT_PBFIDEN,port, enabled); -+} -+/* Function Name: -+ * rtl8367c_getAsicPortBasedFidEn -+ * Description: -+ * Get port based FID selection enable -+ * Input: -+ * port - Physical port number (0~10) -+ * pEnabled - 1: enabled, 0: disabled -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicPortBasedFidEn(rtk_uint32 port, rtk_uint32* pEnabled) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBit(RTL8367C_REG_PORT_PBFIDEN,port, pEnabled); -+} -+/* Function Name: -+ * rtl8367c_setAsicSpanningTreeStatus -+ * Description: -+ * Set spanning tree state per each port -+ * Input: -+ * port - Physical port number (0~10) -+ * msti - Multiple spanning tree instance -+ * state - Spanning tree state for msti -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_MSTI - Invalid msti parameter -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_MSTP_STATE - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicSpanningTreeStatus(rtk_uint32 port, rtk_uint32 msti, rtk_uint32 state) -+{ -+ rtk_uint32 reg_addr,bits_msk; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(msti > RTL8367C_MSTIMAX) -+ return RT_ERR_MSTI; -+ -+ if(state > STPST_FORWARDING) -+ return RT_ERR_MSTP_STATE; -+ -+ if(port < 8) -+ return rtl8367c_setAsicRegBits(RTL8367C_VLAN_MSTI_REG(msti,port), RTL8367C_VLAN_MSTI_MASK(port),state); -+ else{ -+ reg_addr = RTL8367C_VLAN_MSTI_REG(msti,port); -+ switch(port){ -+ case 8: bits_msk = RTL8367C_VLAN_MSTI0_CTRL1_PORT8_STATE_MASK;break; -+ case 9: bits_msk = RTL8367C_VLAN_MSTI0_CTRL1_PORT9_STATE_MASK;break; -+ case 10: bits_msk = RTL8367C_VLAN_MSTI0_CTRL1_PORT10_STATE_MASK;break; -+ } -+ return rtl8367c_setAsicRegBits(reg_addr, bits_msk,state); -+ } -+} -+/* Function Name: -+ * rtl8367c_getAsicSpanningTreeStatus -+ * Description: -+ * Set spanning tree state per each port -+ * Input: -+ * port - Physical port number (0~10) -+ * msti - Multiple spanning tree instance -+ * pState - Spanning tree state for msti -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_MSTI - Invalid msti parameter -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicSpanningTreeStatus(rtk_uint32 port, rtk_uint32 msti, rtk_uint32* pState) -+{ -+ rtk_uint32 reg_addr,bits_msk; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(msti > RTL8367C_MSTIMAX) -+ return RT_ERR_MSTI; -+ -+ if(port < 8) -+ return rtl8367c_getAsicRegBits(RTL8367C_VLAN_MSTI_REG(msti,port), RTL8367C_VLAN_MSTI_MASK(port), pState); -+ else{ -+ reg_addr = RTL8367C_VLAN_MSTI_REG(msti,port); -+ switch(port){ -+ case 8: bits_msk = RTL8367C_VLAN_MSTI0_CTRL1_PORT8_STATE_MASK;break; -+ case 9: bits_msk = RTL8367C_VLAN_MSTI0_CTRL1_PORT9_STATE_MASK;break; -+ case 10: bits_msk = RTL8367C_VLAN_MSTI0_CTRL1_PORT10_STATE_MASK;break; -+ } -+ return rtl8367c_getAsicRegBits(reg_addr, bits_msk, pState); -+ } -+ -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicVlanTransparent -+ * Description: -+ * Set VLAN transparent -+ * Input: -+ * port - Physical port number (0~10) -+ * portmask - portmask(0~0xFF) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Invalid portmask -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicVlanTransparent(rtk_uint32 port, rtk_uint32 portmask) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(portmask > RTL8367C_PORTMASK) -+ return RT_ERR_PORT_MASK; -+ -+ return rtl8367c_setAsicRegBits(RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL0 + port, RTL8367C_VLAN_EGRESS_TRANS_CTRL0_MASK, portmask); -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicVlanTransparent -+ * Description: -+ * Get VLAN transparent -+ * Input: -+ * port - Physical port number (0~10) -+ * Output: -+ * pPortmask - Ingress port mask -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Invalid portmask -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicVlanTransparent(rtk_uint32 port, rtk_uint32 *pPortmask) -+{ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ return rtl8367c_getAsicRegBits(RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL0 + port, RTL8367C_VLAN_EGRESS_TRANS_CTRL0_MASK, pPortmask); -+} -+ -+/* Function Name: -+ * rtl8367c_setAsicVlanEgressKeep -+ * Description: -+ * Set per egress port VLAN keep mode -+ * Input: -+ * port - Physical port number (0~10) -+ * portmask - portmask(0~0xFF) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_MASK - Invalid portmask -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setAsicVlanEgressKeep(rtk_uint32 port, rtk_uint32 portmask) -+{ -+ rtk_uint32 regAddr, bit_mask; -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(portmask > RTL8367C_PORTMASK) -+ return RT_ERR_PORT_MASK; -+ -+ if(port < 8){ -+ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL0 + (port>>1),RTL8367C_PORT0_VLAN_KEEP_MASK_MASK<<((port&1)*8),portmask & 0xff); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL0_EXT + (port>>1); -+ bit_mask = RTL8367C_PORT0_VLAN_KEEP_MASK_EXT_MASK; -+ bit_mask <<= (port&1)*3; -+ retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, (portmask>>8)&0x7); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ } -+ else{ -+ switch(port){ -+ case 8: -+ regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4; -+ bit_mask = RTL8367C_PORT8_VLAN_KEEP_MASK_MASK; -+ retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, portmask & 0xff); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4_EXT; -+ bit_mask = RTL8367C_PORT8_VLAN_KEEP_MASK_EXT_MASK; -+ retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, (portmask>>8)&0x7); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ break; -+ -+ case 9: -+ regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4; -+ bit_mask = RTL8367C_PORT9_VLAN_KEEP_MASK_MASK; -+ retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, portmask & 0xff); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4_EXT; -+ bit_mask = RTL8367C_PORT9_VLAN_KEEP_MASK_EXT_MASK; -+ retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, (portmask>>8)&0x7); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ break; -+ -+ case 10: -+ regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL5; -+ bit_mask = RTL8367C_VLAN_EGRESS_KEEP_CTRL5_MASK; -+ retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, portmask & 0xff); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL5_EXT; -+ bit_mask = RTL8367C_VLAN_EGRESS_KEEP_CTRL5_EXT_MASK; -+ retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, (portmask>>8)&0x7); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ break; -+ } -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getAsicVlanEgressKeep -+ * Description: -+ * Get per egress port VLAN keep mode -+ * Input: -+ * port - Physical port number (0~7) -+ * pPortmask - portmask(0~0xFF) -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getAsicVlanEgressKeep(rtk_uint32 port, rtk_uint32* pPortmask) -+{ -+ rtk_uint32 regAddr, bit_mask, regval_l, regval_h; -+ ret_t retVal; -+ -+ if(port > RTL8367C_PORTIDMAX) -+ return RT_ERR_PORT_ID; -+ -+ if(port < 8){ -+ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL0 + (port>>1),RTL8367C_PORT0_VLAN_KEEP_MASK_MASK<<((port&1)*8),®val_l); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL0_EXT + (port>>1); -+ bit_mask = RTL8367C_PORT0_VLAN_KEEP_MASK_EXT_MASK; -+ bit_mask <<= (port&1)*3; -+ retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, ®val_h); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ *pPortmask = (regval_h << 8) | regval_l; -+ } -+ else{ -+ switch(port){ -+ case 8: -+ regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4; -+ bit_mask = RTL8367C_PORT8_VLAN_KEEP_MASK_MASK; -+ retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, ®val_l); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4_EXT; -+ bit_mask = RTL8367C_PORT8_VLAN_KEEP_MASK_EXT_MASK; -+ retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, ®val_h); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *pPortmask = (regval_h << 8) | regval_l; -+ break; -+ -+ case 9: -+ regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4; -+ bit_mask = RTL8367C_PORT9_VLAN_KEEP_MASK_MASK; -+ retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, ®val_l); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4_EXT; -+ bit_mask = RTL8367C_PORT9_VLAN_KEEP_MASK_EXT_MASK; -+ retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, ®val_h); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *pPortmask = (regval_h << 8) | regval_l; -+ break; -+ -+ case 10: -+ regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL5; -+ bit_mask = RTL8367C_VLAN_EGRESS_KEEP_CTRL5_MASK; -+ retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, ®val_l); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL5_EXT; -+ bit_mask = RTL8367C_VLAN_EGRESS_KEEP_CTRL5_EXT_MASK; -+ retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, ®val_h); -+ if(retVal != RT_ERR_OK) -+ return retVal; -+ -+ *pPortmask = (regval_h << 8) | regval_l; -+ break; -+ } -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_setReservedVidAction -+ * Description: -+ * Set reserved VID action -+ * Input: -+ * vid0Action - VID 0 action -+ * vid4095Action - VID 4095 action -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error input -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setReservedVidAction(rtk_uint32 vid0Action, rtk_uint32 vid4095Action) -+{ -+ ret_t retVal; -+ -+ if(vid0Action >= RES_VID_ACT_END) -+ return RT_ERR_INPUT; -+ -+ if(vid4095Action >= RES_VID_ACT_END) -+ return RT_ERR_INPUT; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_VLAN_EXT_CTRL, RTL8367C_VLAN_VID0_TYPE_OFFSET, vid0Action)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_VLAN_EXT_CTRL, RTL8367C_VLAN_VID4095_TYPE_OFFSET, vid4095Action)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getReservedVidAction -+ * Description: -+ * Get reserved VID action -+ * Input: -+ * pVid0Action - VID 0 action -+ * pVid4095Action - VID 4095 action -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getReservedVidAction(rtk_uint32 *pVid0Action, rtk_uint32 *pVid4095Action) -+{ -+ ret_t retVal; -+ -+ if(pVid0Action == NULL) -+ return RT_ERR_NULL_POINTER; -+ -+ if(pVid4095Action == NULL) -+ return RT_ERR_NULL_POINTER; -+ -+ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_VLAN_EXT_CTRL, RTL8367C_VLAN_VID0_TYPE_OFFSET, pVid0Action)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_VLAN_EXT_CTRL, RTL8367C_VLAN_VID4095_TYPE_OFFSET, pVid4095Action)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+ -+} -+ -+/* Function Name: -+ * rtl8367c_setRealKeepRemarkEn -+ * Description: -+ * Set Real Keep Remark -+ * Input: -+ * enabled - 0: 1P remarking is forbidden at real keep packet, 1: 1P remarking is enabled at real keep packet -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error input -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_setRealKeepRemarkEn(rtk_uint32 enabled) -+{ -+ ret_t retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_VLAN_EXT_CTRL, RTL8367C_VLAN_1P_REMARK_BYPASS_REALKEEP_OFFSET, enabled)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_getRealKeepRemarkEn -+ * Description: -+ * Get Real Keep Remark -+ * Input: -+ * None -+ * Output: -+ * pEnabled - 0: 1P remarking is forbidden at real keep packet, 1: 1P remarking is enabled at real keep packet -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error input -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_getRealKeepRemarkEn(rtk_uint32 *pEnabled) -+{ -+ ret_t retVal; -+ -+ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_VLAN_EXT_CTRL, RTL8367C_VLAN_1P_REMARK_BYPASS_REALKEEP_OFFSET, pEnabled)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtl8367c_resetVlan -+ * Description: -+ * Reset VLAN table -+ * Input: -+ * None. -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - Success -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * None -+ */ -+ret_t rtl8367c_resetVlan(void) -+{ -+ ret_t retVal; -+ -+ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_VLAN_EXT_CTRL2, RTL8367C_VLAN_EXT_CTRL2_OFFSET, 1)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/smi.c b/drivers/net/phy/rtk/rtl8367c/smi.c -new file mode 100644 -index 000000000000..e707e4b9c583 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/smi.c -@@ -0,0 +1,442 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * Purpose : RTL8367C switch low-level function for access register -+ * Feature : SMI related functions -+ * -+ */ -+ -+ -+#include -+#include -+#include -+ -+#include "rtk_error.h" -+ -+ -+#if defined(MDC_MDIO_OPERATION) -+/*******************************************************************************/ -+/* MDC/MDIO porting */ -+/*******************************************************************************/ -+/* define the PHY ID currently used */ -+/* carlos */ -+#if 0 -+#define MDC_MDIO_PHY_ID 0 /* PHY ID 0 or 29 */ -+#else -+#define MDC_MDIO_PHY_ID 29 /* PHY ID 0 or 29 */ -+#endif -+ -+/* MDC/MDIO, redefine/implement the following Macro */ /*carlos*/ -+#if 0 -+#define MDC_MDIO_WRITE(preamableLength, phyID, regID, data) -+#define MDC_MDIO_READ(preamableLength, phyID, regID, pData) -+#else -+#define MDC_MDIO_WRITE(preamableLength, phyID, regID, data) mii_mgr_write(phyID, regID, data) -+#define MDC_MDIO_READ(preamableLength, phyID, regID, pData) mii_mgr_read(phyID, regID, pData) -+#endif -+ -+ -+ -+ -+ -+#elif defined(SPI_OPERATION) -+/*******************************************************************************/ -+/* SPI porting */ -+/*******************************************************************************/ -+/* SPI, redefine/implement the following Macro */ -+#define SPI_WRITE(data, length) -+#define SPI_READ(pData, length) -+ -+ -+ -+ -+ -+#else -+/*******************************************************************************/ -+/* I2C porting */ -+/*******************************************************************************/ -+/* Define the GPIO ID for SCK & SDA */ -+rtk_uint32 smi_SCK = 1; /* GPIO used for SMI Clock Generation */ -+rtk_uint32 smi_SDA = 2; /* GPIO used for SMI Data signal */ -+ -+/* I2C, redefine/implement the following Macro */ -+#define GPIO_DIRECTION_SET(gpioID, direction) -+#define GPIO_DATA_SET(gpioID, data) -+#define GPIO_DATA_GET(gpioID, pData) -+ -+ -+ -+ -+ -+#endif -+ -+static void rtlglue_drvMutexLock(void) -+{ -+ /* It is empty currently. Implement this function if Lock/Unlock function is needed */ -+ return; -+} -+ -+static void rtlglue_drvMutexUnlock(void) -+{ -+ /* It is empty currently. Implement this function if Lock/Unlock function is needed */ -+ return; -+} -+ -+ -+ -+#if defined(MDC_MDIO_OPERATION) || defined(SPI_OPERATION) -+ /* No local function in MDC/MDIO & SPI mode */ -+#else -+static void _smi_start(void) -+{ -+ -+ /* change GPIO pin to Output only */ -+ GPIO_DIRECTION_SET(smi_SCK, GPIO_DIR_OUT); -+ GPIO_DIRECTION_SET(smi_SDA, GPIO_DIR_OUT); -+ -+ /* Initial state: SCK: 0, SDA: 1 */ -+ GPIO_DATA_SET(smi_SCK, 0); -+ GPIO_DATA_SET(smi_SDA, 1); -+ CLK_DURATION(DELAY); -+ -+ /* CLK 1: 0 -> 1, 1 -> 0 */ -+ GPIO_DATA_SET(smi_SCK, 1); -+ CLK_DURATION(DELAY); -+ GPIO_DATA_SET(smi_SCK, 0); -+ CLK_DURATION(DELAY); -+ -+ /* CLK 2: */ -+ GPIO_DATA_SET(smi_SCK, 1); -+ CLK_DURATION(DELAY); -+ GPIO_DATA_SET(smi_SDA, 0); -+ CLK_DURATION(DELAY); -+ GPIO_DATA_SET(smi_SCK, 0); -+ CLK_DURATION(DELAY); -+ GPIO_DATA_SET(smi_SDA, 1); -+ -+} -+ -+ -+ -+static void _smi_writeBit(rtk_uint16 signal, rtk_uint32 bitLen) -+{ -+ for( ; bitLen > 0; bitLen--) -+ { -+ CLK_DURATION(DELAY); -+ -+ /* prepare data */ -+ if ( signal & (1<<(bitLen-1)) ) -+ { -+ GPIO_DATA_SET(smi_SDA, 1); -+ } -+ else -+ { -+ GPIO_DATA_SET(smi_SDA, 0); -+ } -+ CLK_DURATION(DELAY); -+ -+ /* clocking */ -+ GPIO_DATA_SET(smi_SCK, 1); -+ CLK_DURATION(DELAY); -+ GPIO_DATA_SET(smi_SCK, 0); -+ } -+} -+ -+ -+ -+static void _smi_readBit(rtk_uint32 bitLen, rtk_uint32 *rData) -+{ -+ rtk_uint32 u = 0; -+ -+ /* change GPIO pin to Input only */ -+ GPIO_DIRECTION_SET(smi_SDA, GPIO_DIR_IN); -+ -+ for (*rData = 0; bitLen > 0; bitLen--) -+ { -+ CLK_DURATION(DELAY); -+ -+ /* clocking */ -+ GPIO_DATA_SET(smi_SCK, 1); -+ CLK_DURATION(DELAY); -+ GPIO_DATA_GET(smi_SDA, &u); -+ GPIO_DATA_SET(smi_SCK, 0); -+ -+ *rData |= (u << (bitLen - 1)); -+ } -+ -+ /* change GPIO pin to Output only */ -+ GPIO_DIRECTION_SET(smi_SDA, GPIO_DIR_OUT); -+} -+ -+ -+ -+static void _smi_stop(void) -+{ -+ -+ CLK_DURATION(DELAY); -+ GPIO_DATA_SET(smi_SDA, 0); -+ GPIO_DATA_SET(smi_SCK, 1); -+ CLK_DURATION(DELAY); -+ GPIO_DATA_SET(smi_SDA, 1); -+ CLK_DURATION(DELAY); -+ GPIO_DATA_SET(smi_SCK, 1); -+ CLK_DURATION(DELAY); -+ GPIO_DATA_SET(smi_SCK, 0); -+ CLK_DURATION(DELAY); -+ GPIO_DATA_SET(smi_SCK, 1); -+ -+ /* add a click */ -+ CLK_DURATION(DELAY); -+ GPIO_DATA_SET(smi_SCK, 0); -+ CLK_DURATION(DELAY); -+ GPIO_DATA_SET(smi_SCK, 1); -+ -+ -+ /* change GPIO pin to Input only */ -+ GPIO_DIRECTION_SET(smi_SDA, GPIO_DIR_IN); -+ GPIO_DIRECTION_SET(smi_SCK, GPIO_DIR_IN); -+} -+ -+#endif /* End of #if defined(MDC_MDIO_OPERATION) || defined(SPI_OPERATION) */ -+ -+rtk_int32 smi_read(rtk_uint32 mAddrs, rtk_uint32 *rData) -+{ -+#if (!defined(MDC_MDIO_OPERATION) && !defined(SPI_OPERATION)) -+ rtk_uint32 rawData=0, ACK; -+ rtk_uint8 con; -+ rtk_uint32 ret = RT_ERR_OK; -+#endif -+ -+ if(mAddrs > 0xFFFF) -+ return RT_ERR_INPUT; -+ -+ if(rData == NULL) -+ return RT_ERR_NULL_POINTER; -+ -+#if defined(MDC_MDIO_OPERATION) -+ -+ /* Lock */ -+ rtlglue_drvMutexLock(); -+ -+ /* Write address control code to register 31 */ -+ MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_CTRL0_REG, MDC_MDIO_ADDR_OP); -+ -+ /* Write address to register 23 */ -+ MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_ADDRESS_REG, mAddrs); -+ -+ /* Write read control code to register 21 */ -+ MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_CTRL1_REG, MDC_MDIO_READ_OP); -+ -+ /* Read data from register 25 */ -+ MDC_MDIO_READ(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_DATA_READ_REG, rData); -+ -+ /* Unlock */ -+ rtlglue_drvMutexUnlock(); -+ -+ return RT_ERR_OK; -+ -+#elif defined(SPI_OPERATION) -+ -+ /* Lock */ -+ rtlglue_drvMutexLock(); -+ -+ /* Write 8 bits READ OP_CODE */ -+ SPI_WRITE(SPI_READ_OP, SPI_READ_OP_LEN); -+ -+ /* Write 16 bits register address */ -+ SPI_WRITE(mAddrs, SPI_REG_LEN); -+ -+ /* Read 16 bits data */ -+ SPI_READ(rData, SPI_DATA_LEN); -+ -+ /* Unlock */ -+ rtlglue_drvMutexUnlock(); -+ -+ return RT_ERR_OK; -+ -+#else -+ -+ /*Disable CPU interrupt to ensure that the SMI operation is atomic. -+ The API is based on RTL865X, rewrite the API if porting to other platform.*/ -+ rtlglue_drvMutexLock(); -+ -+ _smi_start(); /* Start SMI */ -+ -+ _smi_writeBit(0x0b, 4); /* CTRL code: 4'b1011 for RTL8370 */ -+ -+ _smi_writeBit(0x4, 3); /* CTRL code: 3'b100 */ -+ -+ _smi_writeBit(0x1, 1); /* 1: issue READ command */ -+ -+ con = 0; -+ do { -+ con++; -+ _smi_readBit(1, &ACK); /* ACK for issuing READ command*/ -+ } while ((ACK != 0) && (con < ack_timer)); -+ -+ if (ACK != 0) ret = RT_ERR_FAILED; -+ -+ _smi_writeBit((mAddrs&0xff), 8); /* Set reg_addr[7:0] */ -+ -+ con = 0; -+ do { -+ con++; -+ _smi_readBit(1, &ACK); /* ACK for setting reg_addr[7:0] */ -+ } while ((ACK != 0) && (con < ack_timer)); -+ -+ if (ACK != 0) ret = RT_ERR_FAILED; -+ -+ _smi_writeBit((mAddrs>>8), 8); /* Set reg_addr[15:8] */ -+ -+ con = 0; -+ do { -+ con++; -+ _smi_readBit(1, &ACK); /* ACK by RTL8369 */ -+ } while ((ACK != 0) && (con < ack_timer)); -+ if (ACK != 0) ret = RT_ERR_FAILED; -+ -+ _smi_readBit(8, &rawData); /* Read DATA [7:0] */ -+ *rData = rawData&0xff; -+ -+ _smi_writeBit(0x00, 1); /* ACK by CPU */ -+ -+ _smi_readBit(8, &rawData); /* Read DATA [15: 8] */ -+ -+ _smi_writeBit(0x01, 1); /* ACK by CPU */ -+ *rData |= (rawData<<8); -+ -+ _smi_stop(); -+ -+ rtlglue_drvMutexUnlock();/*enable CPU interrupt*/ -+ -+ return ret; -+#endif /* end of #if defined(MDC_MDIO_OPERATION) */ -+} -+ -+ -+ -+rtk_int32 smi_write(rtk_uint32 mAddrs, rtk_uint32 rData) -+{ -+#if (!defined(MDC_MDIO_OPERATION) && !defined(SPI_OPERATION)) -+ rtk_int8 con; -+ rtk_uint32 ACK; -+ rtk_uint32 ret = RT_ERR_OK; -+#endif -+ -+ if(mAddrs > 0xFFFF) -+ return RT_ERR_INPUT; -+ -+ if(rData > 0xFFFF) -+ return RT_ERR_INPUT; -+ -+#if defined(MDC_MDIO_OPERATION) -+ -+ /* Lock */ -+ rtlglue_drvMutexLock(); -+ -+ /* Write address control code to register 31 */ -+ MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_CTRL0_REG, MDC_MDIO_ADDR_OP); -+ -+ /* Write address to register 23 */ -+ MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_ADDRESS_REG, mAddrs); -+ -+ /* Write data to register 24 */ -+ MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_DATA_WRITE_REG, rData); -+ -+ /* Write data control code to register 21 */ -+ MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_CTRL1_REG, MDC_MDIO_WRITE_OP); -+ -+ /* Unlock */ -+ rtlglue_drvMutexUnlock(); -+ -+ return RT_ERR_OK; -+ -+#elif defined(SPI_OPERATION) -+ -+ /* Lock */ -+ rtlglue_drvMutexLock(); -+ -+ /* Write 8 bits WRITE OP_CODE */ -+ SPI_WRITE(SPI_WRITE_OP, SPI_WRITE_OP_LEN); -+ -+ /* Write 16 bits register address */ -+ SPI_WRITE(mAddrs, SPI_REG_LEN); -+ -+ /* Write 16 bits data */ -+ SPI_WRITE(rData, SPI_DATA_LEN); -+ -+ /* Unlock */ -+ rtlglue_drvMutexUnlock(); -+ -+ return RT_ERR_OK; -+#else -+ -+ /*Disable CPU interrupt to ensure that the SMI operation is atomic. -+ The API is based on RTL865X, rewrite the API if porting to other platform.*/ -+ rtlglue_drvMutexLock(); -+ -+ _smi_start(); /* Start SMI */ -+ -+ _smi_writeBit(0x0b, 4); /* CTRL code: 4'b1011 for RTL8370*/ -+ -+ _smi_writeBit(0x4, 3); /* CTRL code: 3'b100 */ -+ -+ _smi_writeBit(0x0, 1); /* 0: issue WRITE command */ -+ -+ con = 0; -+ do { -+ con++; -+ _smi_readBit(1, &ACK); /* ACK for issuing WRITE command*/ -+ } while ((ACK != 0) && (con < ack_timer)); -+ if (ACK != 0) ret = RT_ERR_FAILED; -+ -+ _smi_writeBit((mAddrs&0xff), 8); /* Set reg_addr[7:0] */ -+ -+ con = 0; -+ do { -+ con++; -+ _smi_readBit(1, &ACK); /* ACK for setting reg_addr[7:0] */ -+ } while ((ACK != 0) && (con < ack_timer)); -+ if (ACK != 0) ret = RT_ERR_FAILED; -+ -+ _smi_writeBit((mAddrs>>8), 8); /* Set reg_addr[15:8] */ -+ -+ con = 0; -+ do { -+ con++; -+ _smi_readBit(1, &ACK); /* ACK for setting reg_addr[15:8] */ -+ } while ((ACK != 0) && (con < ack_timer)); -+ if (ACK != 0) ret = RT_ERR_FAILED; -+ -+ _smi_writeBit(rData&0xff, 8); /* Write Data [7:0] out */ -+ -+ con = 0; -+ do { -+ con++; -+ _smi_readBit(1, &ACK); /* ACK for writing data [7:0] */ -+ } while ((ACK != 0) && (con < ack_timer)); -+ if (ACK != 0) ret = RT_ERR_FAILED; -+ -+ _smi_writeBit(rData>>8, 8); /* Write Data [15:8] out */ -+ -+ con = 0; -+ do { -+ con++; -+ _smi_readBit(1, &ACK); /* ACK for writing data [15:8] */ -+ } while ((ACK != 0) && (con < ack_timer)); -+ if (ACK != 0) ret = RT_ERR_FAILED; -+ -+ _smi_stop(); -+ -+ rtlglue_drvMutexUnlock();/*enable CPU interrupt*/ -+ -+ return ret; -+#endif /* end of #if defined(MDC_MDIO_OPERATION) */ -+} -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/stat.c b/drivers/net/phy/rtk/rtl8367c/stat.c -new file mode 100644 -index 000000000000..3fd028a296e4 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/stat.c -@@ -0,0 +1,626 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTK switch high-level API for RTL8367/RTL8367C -+ * Feature : Here is a list of all functions and variables in MIB module. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+/* Function Name: -+ * rtk_stat_global_reset -+ * Description: -+ * Reset global MIB counter. -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * Reset MIB counter of ports. API will use global reset while port mask is all-ports. -+ */ -+rtk_api_ret_t rtk_stat_global_reset(void) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if ((retVal = rtl8367c_setAsicMIBsCounterReset(TRUE,FALSE, 0)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_stat_port_reset -+ * Description: -+ * Reset per port MIB counter by port. -+ * Input: -+ * port - port id. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_stat_port_reset(rtk_port_t port) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check port valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if ((retVal = rtl8367c_setAsicMIBsCounterReset(FALSE,FALSE,1 << rtk_switch_port_L2P_get(port))) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_stat_queueManage_reset -+ * Description: -+ * Reset queue manage MIB counter. -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_stat_queueManage_reset(void) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if ((retVal = rtl8367c_setAsicMIBsCounterReset(FALSE,TRUE,0)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+ -+/* Function Name: -+ * rtk_stat_global_get -+ * Description: -+ * Get global MIB counter -+ * Input: -+ * cntr_idx - global counter index. -+ * Output: -+ * pCntr - global counter value. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * Get global MIB counter by index definition. -+ */ -+rtk_api_ret_t rtk_stat_global_get(rtk_stat_global_type_t cntr_idx, rtk_stat_counter_t *pCntr) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pCntr) -+ return RT_ERR_NULL_POINTER; -+ -+ if (cntr_idx!=DOT1D_TP_LEARNED_ENTRY_DISCARDS_INDEX) -+ return RT_ERR_STAT_INVALID_GLOBAL_CNTR; -+ -+ if ((retVal = rtl8367c_getAsicMIBsCounter(0, (RTL8367C_MIBCOUNTER)cntr_idx, pCntr)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_stat_global_getAll -+ * Description: -+ * Get all global MIB counter -+ * Input: -+ * None -+ * Output: -+ * pGlobal_cntrs - global counter structure. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * Get all global MIB counter by index definition. -+ */ -+rtk_api_ret_t rtk_stat_global_getAll(rtk_stat_global_cntr_t *pGlobal_cntrs) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pGlobal_cntrs) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicMIBsCounter(0, dot1dTpLearnedEntryDiscards, &pGlobal_cntrs->dot1dTpLearnedEntryDiscards)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+#define MIB_NOT_SUPPORT (0xFFFF) -+static rtk_api_ret_t _get_asic_mib_idx(rtk_stat_port_type_t cnt_idx, RTL8367C_MIBCOUNTER *pMib_idx) -+{ -+ RTL8367C_MIBCOUNTER mib_asic_idx[STAT_PORT_CNTR_END]= -+ { -+ ifInOctets, /* STAT_IfInOctets */ -+ dot3StatsFCSErrors, /* STAT_Dot3StatsFCSErrors */ -+ dot3StatsSymbolErrors, /* STAT_Dot3StatsSymbolErrors */ -+ dot3InPauseFrames, /* STAT_Dot3InPauseFrames */ -+ dot3ControlInUnknownOpcodes, /* STAT_Dot3ControlInUnknownOpcodes */ -+ etherStatsFragments, /* STAT_EtherStatsFragments */ -+ etherStatsJabbers, /* STAT_EtherStatsJabbers */ -+ ifInUcastPkts, /* STAT_IfInUcastPkts */ -+ etherStatsDropEvents, /* STAT_EtherStatsDropEvents */ -+ etherStatsOctets, /* STAT_EtherStatsOctets */ -+ etherStatsUnderSizePkts, /* STAT_EtherStatsUnderSizePkts */ -+ etherOversizeStats, /* STAT_EtherOversizeStats */ -+ etherStatsPkts64Octets, /* STAT_EtherStatsPkts64Octets */ -+ etherStatsPkts65to127Octets, /* STAT_EtherStatsPkts65to127Octets */ -+ etherStatsPkts128to255Octets, /* STAT_EtherStatsPkts128to255Octets */ -+ etherStatsPkts256to511Octets, /* STAT_EtherStatsPkts256to511Octets */ -+ etherStatsPkts512to1023Octets, /* STAT_EtherStatsPkts512to1023Octets */ -+ etherStatsPkts1024to1518Octets, /* STAT_EtherStatsPkts1024to1518Octets */ -+ ifInMulticastPkts, /* STAT_EtherStatsMulticastPkts */ -+ ifInBroadcastPkts, /* STAT_EtherStatsBroadcastPkts */ -+ ifOutOctets, /* STAT_IfOutOctets */ -+ dot3StatsSingleCollisionFrames, /* STAT_Dot3StatsSingleCollisionFrames */ -+ dot3StatMultipleCollisionFrames,/* STAT_Dot3StatsMultipleCollisionFrames */ -+ dot3sDeferredTransmissions, /* STAT_Dot3StatsDeferredTransmissions */ -+ dot3StatsLateCollisions, /* STAT_Dot3StatsLateCollisions */ -+ etherStatsCollisions, /* STAT_EtherStatsCollisions */ -+ dot3StatsExcessiveCollisions, /* STAT_Dot3StatsExcessiveCollisions */ -+ dot3OutPauseFrames, /* STAT_Dot3OutPauseFrames */ -+ MIB_NOT_SUPPORT, /* STAT_Dot1dBasePortDelayExceededDiscards */ -+ dot1dTpPortInDiscards, /* STAT_Dot1dTpPortInDiscards */ -+ ifOutUcastPkts, /* STAT_IfOutUcastPkts */ -+ ifOutMulticastPkts, /* STAT_IfOutMulticastPkts */ -+ ifOutBroadcastPkts, /* STAT_IfOutBroadcastPkts */ -+ outOampduPkts, /* STAT_OutOampduPkts */ -+ inOampduPkts, /* STAT_InOampduPkts */ -+ MIB_NOT_SUPPORT, /* STAT_PktgenPkts */ -+ inMldChecksumError, /* STAT_InMldChecksumError */ -+ inIgmpChecksumError, /* STAT_InIgmpChecksumError */ -+ inMldSpecificQuery, /* STAT_InMldSpecificQuery */ -+ inMldGeneralQuery, /* STAT_InMldGeneralQuery */ -+ inIgmpSpecificQuery, /* STAT_InIgmpSpecificQuery */ -+ inIgmpGeneralQuery, /* STAT_InIgmpGeneralQuery */ -+ inMldLeaves, /* STAT_InMldLeaves */ -+ inIgmpLeaves, /* STAT_InIgmpInterfaceLeaves */ -+ inIgmpJoinsSuccess, /* STAT_InIgmpJoinsSuccess */ -+ inIgmpJoinsFail, /* STAT_InIgmpJoinsFail */ -+ inMldJoinsSuccess, /* STAT_InMldJoinsSuccess */ -+ inMldJoinsFail, /* STAT_InMldJoinsFail */ -+ inReportSuppressionDrop, /* STAT_InReportSuppressionDrop */ -+ inLeaveSuppressionDrop, /* STAT_InLeaveSuppressionDrop */ -+ outIgmpReports, /* STAT_OutIgmpReports */ -+ outIgmpLeaves, /* STAT_OutIgmpLeaves */ -+ outIgmpGeneralQuery, /* STAT_OutIgmpGeneralQuery */ -+ outIgmpSpecificQuery, /* STAT_OutIgmpSpecificQuery */ -+ outMldReports, /* STAT_OutMldReports */ -+ outMldLeaves, /* STAT_OutMldLeaves */ -+ outMldGeneralQuery, /* STAT_OutMldGeneralQuery */ -+ outMldSpecificQuery, /* STAT_OutMldSpecificQuery */ -+ inKnownMulticastPkts, /* STAT_InKnownMulticastPkts */ -+ ifInMulticastPkts, /* STAT_IfInMulticastPkts */ -+ ifInBroadcastPkts, /* STAT_IfInBroadcastPkts */ -+ ifOutDiscards /* STAT_IfOutDiscards */ -+ }; -+ -+ if(cnt_idx >= STAT_PORT_CNTR_END) -+ return RT_ERR_STAT_INVALID_PORT_CNTR; -+ -+ if(mib_asic_idx[cnt_idx] == MIB_NOT_SUPPORT) -+ return RT_ERR_CHIP_NOT_SUPPORTED; -+ -+ *pMib_idx = mib_asic_idx[cnt_idx]; -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_stat_port_get -+ * Description: -+ * Get per port MIB counter by index -+ * Input: -+ * port - port id. -+ * cntr_idx - port counter index. -+ * Output: -+ * pCntr - MIB retrieved counter. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * Get per port MIB counter by index definition. -+ */ -+rtk_api_ret_t rtk_stat_port_get(rtk_port_t port, rtk_stat_port_type_t cntr_idx, rtk_stat_counter_t *pCntr) -+{ -+ rtk_api_ret_t retVal; -+ RTL8367C_MIBCOUNTER mib_idx; -+ rtk_stat_counter_t second_cnt; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pCntr) -+ return RT_ERR_NULL_POINTER; -+ -+ /* Check port valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (cntr_idx>=STAT_PORT_CNTR_END) -+ return RT_ERR_STAT_INVALID_PORT_CNTR; -+ -+ if((retVal = _get_asic_mib_idx(cntr_idx, &mib_idx)) != RT_ERR_OK) -+ return retVal; -+ -+ if(mib_idx == MIB_NOT_SUPPORT) -+ return RT_ERR_CHIP_NOT_SUPPORTED; -+ -+ if ((retVal = rtl8367c_getAsicMIBsCounter(rtk_switch_port_L2P_get(port), mib_idx, pCntr)) != RT_ERR_OK) -+ return retVal; -+ -+ if(cntr_idx == STAT_EtherStatsMulticastPkts) -+ { -+ if((retVal = _get_asic_mib_idx(STAT_IfOutMulticastPkts, &mib_idx)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicMIBsCounter(rtk_switch_port_L2P_get(port), mib_idx, &second_cnt)) != RT_ERR_OK) -+ return retVal; -+ -+ *pCntr += second_cnt; -+ } -+ -+ if(cntr_idx == STAT_EtherStatsBroadcastPkts) -+ { -+ if((retVal = _get_asic_mib_idx(STAT_IfOutBroadcastPkts, &mib_idx)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicMIBsCounter(rtk_switch_port_L2P_get(port), mib_idx, &second_cnt)) != RT_ERR_OK) -+ return retVal; -+ -+ *pCntr += second_cnt; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_stat_port_getAll -+ * Description: -+ * Get all counters of one specified port in the specified device. -+ * Input: -+ * port - port id. -+ * Output: -+ * pPort_cntrs - buffer pointer of counter value. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * Get all MIB counters of one port. -+ */ -+rtk_api_ret_t rtk_stat_port_getAll(rtk_port_t port, rtk_stat_port_cntr_t *pPort_cntrs) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 mibIndex; -+ rtk_uint64 mibCounter; -+ rtk_uint32 *accessPtr; -+ /* address offset to MIBs counter */ -+ CONST_T rtk_uint16 mibLength[STAT_PORT_CNTR_END]= { -+ 2,1,1,1,1,1,1,1,1, -+ 2,1,1,1,1,1,1,1,1,1,1, -+ 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, -+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pPort_cntrs) -+ return RT_ERR_NULL_POINTER; -+ -+ /* Check port valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ accessPtr = (rtk_uint32*)pPort_cntrs; -+ for (mibIndex=0;mibIndex RTL8367C_MIB_MAX_LOG_CNT_IDX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if((idx % 2) == 1) -+ return RT_ERR_INPUT; -+ -+ if(mode >= LOGGING_MODE_END) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(type >= LOGGING_TYPE_END) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if((retVal = rtl8367c_setAsicMIBsLoggingType((idx / 2), (rtk_uint32)type)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicMIBsLoggingMode((idx / 2), (rtk_uint32)mode)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_stat_logging_counterCfg_get -+ * Description: -+ * Get the type and mode of Logging Counter -+ * Input: -+ * idx - The index of Logging Counter. Should be even number only.(0,2,4,6,8.....30) -+ * Output: -+ * pMode - 32 bits or 64 bits mode -+ * pType - Packet counter or byte counter -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_OUT_OF_RANGE - Out of range. -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_NULL_POINTER - NULL Pointer -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * Get the type and mode of Logging Counter. -+ */ -+rtk_api_ret_t rtk_stat_logging_counterCfg_get(rtk_uint32 idx, rtk_logging_counter_mode_t *pMode, rtk_logging_counter_type_t *pType) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 type, mode; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(idx > RTL8367C_MIB_MAX_LOG_CNT_IDX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if((idx % 2) == 1) -+ return RT_ERR_INPUT; -+ -+ if(pMode == NULL) -+ return RT_ERR_NULL_POINTER; -+ -+ if(pType == NULL) -+ return RT_ERR_NULL_POINTER; -+ -+ if((retVal = rtl8367c_getAsicMIBsLoggingType((idx / 2), &type)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicMIBsLoggingMode((idx / 2), &mode)) != RT_ERR_OK) -+ return retVal; -+ -+ *pMode = (rtk_logging_counter_mode_t)mode; -+ *pType = (rtk_logging_counter_type_t)type; -+ -+ return RT_ERR_OK; -+} -+ -+ -+/* Function Name: -+ * rtk_stat_logging_counter_reset -+ * Description: -+ * Reset Logging Counter -+ * Input: -+ * idx - The index of Logging Counter. (0~31) -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_OUT_OF_RANGE - Out of range. -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * Reset Logging Counter. -+ */ -+rtk_api_ret_t rtk_stat_logging_counter_reset(rtk_uint32 idx) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(idx > RTL8367C_MIB_MAX_LOG_CNT_IDX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if((retVal = rtl8367c_setAsicMIBsResetLoggingCounter(idx)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_stat_logging_counter_get -+ * Description: -+ * Get Logging Counter -+ * Input: -+ * idx - The index of Logging Counter. (0~31) -+ * Output: -+ * pCnt - Logging counter value -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_OUT_OF_RANGE - Out of range. -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * Get Logging Counter. -+ */ -+rtk_api_ret_t rtk_stat_logging_counter_get(rtk_uint32 idx, rtk_uint32 *pCnt) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pCnt) -+ return RT_ERR_NULL_POINTER; -+ -+ if(idx > RTL8367C_MIB_MAX_LOG_CNT_IDX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if((retVal = rtl8367c_getAsicMIBsLogCounter(idx, pCnt)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_stat_lengthMode_set -+ * Description: -+ * Set Legnth mode. -+ * Input: -+ * txMode - The length counting mode -+ * rxMode - The length counting mode -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_INPUT - Out of range. -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_stat_lengthMode_set(rtk_stat_lengthMode_t txMode, rtk_stat_lengthMode_t rxMode) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(txMode >= LENGTH_MODE_END) -+ return RT_ERR_INPUT; -+ -+ if(rxMode >= LENGTH_MODE_END) -+ return RT_ERR_INPUT; -+ -+ if((retVal = rtl8367c_setAsicMIBsLength((rtk_uint32)txMode, (rtk_uint32)rxMode)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_stat_lengthMode_get -+ * Description: -+ * Get Length mode. -+ * Input: -+ * None. -+ * Output: -+ * pTxMode - The length counting mode -+ * pRxMode - The length counting mode -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_INPUT - Out of range. -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ */ -+rtk_api_ret_t rtk_stat_lengthMode_get(rtk_stat_lengthMode_t *pTxMode, rtk_stat_lengthMode_t *pRxMode) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pTxMode) -+ return RT_ERR_NULL_POINTER; -+ -+ if(NULL == pRxMode) -+ return RT_ERR_NULL_POINTER; -+ -+ if((retVal = rtl8367c_getAsicMIBsLength((rtk_uint32 *)pTxMode, (rtk_uint32 *)pRxMode)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/storm.c b/drivers/net/phy/rtk/rtl8367c/storm.c -new file mode 100644 -index 000000000000..68063cdfa75f ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/storm.c -@@ -0,0 +1,816 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTK switch high-level API for RTL8367/RTL8367C -+ * Feature : Here is a list of all functions and variables in Storm module. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Function Name: -+ * rtk_rate_stormControlMeterIdx_set -+ * Description: -+ * Set the storm control meter index. -+ * Input: -+ * port - port id -+ * storm_type - storm group type -+ * index - storm control meter index. -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_PORT_ID - Invalid port id -+ * RT_ERR_FILTER_METER_ID - Invalid meter -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_rate_stormControlMeterIdx_set(rtk_port_t port, rtk_rate_storm_group_t stormType, rtk_uint32 index) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (stormType >= STORM_GROUP_END) -+ return RT_ERR_SFC_UNKNOWN_GROUP; -+ -+ if (index > RTK_MAX_METER_ID) -+ return RT_ERR_FILTER_METER_ID; -+ -+ switch (stormType) -+ { -+ case STORM_GROUP_UNKNOWN_UNICAST: -+ if ((retVal = rtl8367c_setAsicStormFilterUnknownUnicastMeter(rtk_switch_port_L2P_get(port), index))!=RT_ERR_OK) -+ return retVal; -+ break; -+ case STORM_GROUP_UNKNOWN_MULTICAST: -+ if ((retVal = rtl8367c_setAsicStormFilterUnknownMulticastMeter(rtk_switch_port_L2P_get(port), index))!=RT_ERR_OK) -+ return retVal; -+ break; -+ case STORM_GROUP_MULTICAST: -+ if ((retVal = rtl8367c_setAsicStormFilterMulticastMeter(rtk_switch_port_L2P_get(port), index))!=RT_ERR_OK) -+ return retVal; -+ break; -+ case STORM_GROUP_BROADCAST: -+ if ((retVal = rtl8367c_setAsicStormFilterBroadcastMeter(rtk_switch_port_L2P_get(port), index))!=RT_ERR_OK) -+ return retVal; -+ break; -+ default: -+ break; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_rate_stormControlMeterIdx_get -+ * Description: -+ * Get the storm control meter index. -+ * Input: -+ * port - port id -+ * storm_type - storm group type -+ * Output: -+ * pIndex - storm control meter index. -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_PORT_ID - Invalid port id -+ * RT_ERR_FILTER_METER_ID - Invalid meter -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_rate_stormControlMeterIdx_get(rtk_port_t port, rtk_rate_storm_group_t stormType, rtk_uint32 *pIndex) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (stormType >= STORM_GROUP_END) -+ return RT_ERR_SFC_UNKNOWN_GROUP; -+ -+ if (NULL == pIndex ) -+ return RT_ERR_NULL_POINTER; -+ -+ switch (stormType) -+ { -+ case STORM_GROUP_UNKNOWN_UNICAST: -+ if ((retVal = rtl8367c_getAsicStormFilterUnknownUnicastMeter(rtk_switch_port_L2P_get(port), pIndex))!=RT_ERR_OK) -+ return retVal; -+ break; -+ case STORM_GROUP_UNKNOWN_MULTICAST: -+ if ((retVal = rtl8367c_getAsicStormFilterUnknownMulticastMeter(rtk_switch_port_L2P_get(port), pIndex))!=RT_ERR_OK) -+ return retVal; -+ break; -+ case STORM_GROUP_MULTICAST: -+ if ((retVal = rtl8367c_getAsicStormFilterMulticastMeter(rtk_switch_port_L2P_get(port), pIndex))!=RT_ERR_OK) -+ return retVal; -+ break; -+ case STORM_GROUP_BROADCAST: -+ if ((retVal = rtl8367c_getAsicStormFilterBroadcastMeter(rtk_switch_port_L2P_get(port), pIndex))!=RT_ERR_OK) -+ return retVal; -+ break; -+ default: -+ break; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_rate_stormControlPortEnable_set -+ * Description: -+ * Set enable status of storm control on specified port. -+ * Input: -+ * port - port id -+ * stormType - storm group type -+ * enable - enable status of storm control -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_PORT_ID - invalid port id -+ * RT_ERR_INPUT - invalid input parameter -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_rate_stormControlPortEnable_set(rtk_port_t port, rtk_rate_storm_group_t stormType, rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (stormType >= STORM_GROUP_END) -+ return RT_ERR_SFC_UNKNOWN_GROUP; -+ -+ if (enable >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ switch (stormType) -+ { -+ case STORM_GROUP_UNKNOWN_UNICAST: -+ if ((retVal = rtl8367c_setAsicStormFilterUnknownUnicastEnable(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) -+ return retVal; -+ break; -+ case STORM_GROUP_UNKNOWN_MULTICAST: -+ if ((retVal = rtl8367c_setAsicStormFilterUnknownMulticastEnable(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) -+ return retVal; -+ break; -+ case STORM_GROUP_MULTICAST: -+ if ((retVal = rtl8367c_setAsicStormFilterMulticastEnable(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) -+ return retVal; -+ break; -+ case STORM_GROUP_BROADCAST: -+ if ((retVal = rtl8367c_setAsicStormFilterBroadcastEnable(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) -+ return retVal; -+ break; -+ default: -+ break; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_rate_stormControlPortEnable_set -+ * Description: -+ * Set enable status of storm control on specified port. -+ * Input: -+ * port - port id -+ * stormType - storm group type -+ * Output: -+ * pEnable - enable status of storm control -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_PORT_ID - invalid port id -+ * RT_ERR_INPUT - invalid input parameter -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_rate_stormControlPortEnable_get(rtk_port_t port, rtk_rate_storm_group_t stormType, rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (stormType >= STORM_GROUP_END) -+ return RT_ERR_SFC_UNKNOWN_GROUP; -+ -+ if (NULL == pEnable) -+ return RT_ERR_ENABLE; -+ -+ switch (stormType) -+ { -+ case STORM_GROUP_UNKNOWN_UNICAST: -+ if ((retVal = rtl8367c_getAsicStormFilterUnknownUnicastEnable(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) -+ return retVal; -+ break; -+ case STORM_GROUP_UNKNOWN_MULTICAST: -+ if ((retVal = rtl8367c_getAsicStormFilterUnknownMulticastEnable(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) -+ return retVal; -+ break; -+ case STORM_GROUP_MULTICAST: -+ if ((retVal = rtl8367c_getAsicStormFilterMulticastEnable(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) -+ return retVal; -+ break; -+ case STORM_GROUP_BROADCAST: -+ if ((retVal = rtl8367c_getAsicStormFilterBroadcastEnable(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) -+ return retVal; -+ break; -+ default: -+ break; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_storm_bypass_set -+ * Description: -+ * Set bypass storm filter control configuration. -+ * Input: -+ * type - Bypass storm filter control type. -+ * enable - Bypass status. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_ENABLE - Invalid IFG parameter -+ * Note: -+ * -+ * This API can set per-port bypass storm filter control frame type including RMA and IGMP. -+ * The bypass frame type is as following: -+ * - BYPASS_BRG_GROUP, -+ * - BYPASS_FD_PAUSE, -+ * - BYPASS_SP_MCAST, -+ * - BYPASS_1X_PAE, -+ * - BYPASS_UNDEF_BRG_04, -+ * - BYPASS_UNDEF_BRG_05, -+ * - BYPASS_UNDEF_BRG_06, -+ * - BYPASS_UNDEF_BRG_07, -+ * - BYPASS_PROVIDER_BRIDGE_GROUP_ADDRESS, -+ * - BYPASS_UNDEF_BRG_09, -+ * - BYPASS_UNDEF_BRG_0A, -+ * - BYPASS_UNDEF_BRG_0B, -+ * - BYPASS_UNDEF_BRG_0C, -+ * - BYPASS_PROVIDER_BRIDGE_GVRP_ADDRESS, -+ * - BYPASS_8021AB, -+ * - BYPASS_UNDEF_BRG_0F, -+ * - BYPASS_BRG_MNGEMENT, -+ * - BYPASS_UNDEFINED_11, -+ * - BYPASS_UNDEFINED_12, -+ * - BYPASS_UNDEFINED_13, -+ * - BYPASS_UNDEFINED_14, -+ * - BYPASS_UNDEFINED_15, -+ * - BYPASS_UNDEFINED_16, -+ * - BYPASS_UNDEFINED_17, -+ * - BYPASS_UNDEFINED_18, -+ * - BYPASS_UNDEFINED_19, -+ * - BYPASS_UNDEFINED_1A, -+ * - BYPASS_UNDEFINED_1B, -+ * - BYPASS_UNDEFINED_1C, -+ * - BYPASS_UNDEFINED_1D, -+ * - BYPASS_UNDEFINED_1E, -+ * - BYPASS_UNDEFINED_1F, -+ * - BYPASS_GMRP, -+ * - BYPASS_GVRP, -+ * - BYPASS_UNDEF_GARP_22, -+ * - BYPASS_UNDEF_GARP_23, -+ * - BYPASS_UNDEF_GARP_24, -+ * - BYPASS_UNDEF_GARP_25, -+ * - BYPASS_UNDEF_GARP_26, -+ * - BYPASS_UNDEF_GARP_27, -+ * - BYPASS_UNDEF_GARP_28, -+ * - BYPASS_UNDEF_GARP_29, -+ * - BYPASS_UNDEF_GARP_2A, -+ * - BYPASS_UNDEF_GARP_2B, -+ * - BYPASS_UNDEF_GARP_2C, -+ * - BYPASS_UNDEF_GARP_2D, -+ * - BYPASS_UNDEF_GARP_2E, -+ * - BYPASS_UNDEF_GARP_2F, -+ * - BYPASS_IGMP. -+ * - BYPASS_CDP. -+ * - BYPASS_CSSTP. -+ * - BYPASS_LLDP. -+ */ -+rtk_api_ret_t rtk_storm_bypass_set(rtk_storm_bypass_t type, rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_rma_t rmacfg; -+ rtk_uint32 tmp; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (type >= BYPASS_END) -+ return RT_ERR_INPUT; -+ -+ if (enable >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if (type >= 0 && type <= BYPASS_UNDEF_GARP_2F) -+ { -+ if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ rmacfg.discard_storm_filter = enable; -+ -+ if ((retVal = rtl8367c_setAsicRma(type, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if(type == BYPASS_IGMP) -+ { -+ if ((retVal = rtl8367c_setAsicIGMPBypassStormCTRL(enable)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if (type == BYPASS_CDP) -+ { -+ if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ rmacfg.discard_storm_filter = enable; -+ -+ if ((retVal = rtl8367c_setAsicRmaCdp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if (type == BYPASS_CSSTP) -+ { -+ if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ rmacfg.discard_storm_filter = enable; -+ -+ if ((retVal = rtl8367c_setAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if (type == BYPASS_LLDP) -+ { -+ if ((retVal = rtl8367c_getAsicRmaLldp(&tmp, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ rmacfg.discard_storm_filter = enable; -+ -+ if ((retVal = rtl8367c_setAsicRmaLldp(tmp, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ return RT_ERR_INPUT; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_storm_bypass_get -+ * Description: -+ * Get bypass storm filter control configuration. -+ * Input: -+ * type - Bypass storm filter control type. -+ * Output: -+ * pEnable - Bypass status. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can get per-port bypass storm filter control frame type including RMA and IGMP. -+ * The bypass frame type is as following: -+ * - BYPASS_BRG_GROUP, -+ * - BYPASS_FD_PAUSE, -+ * - BYPASS_SP_MCAST, -+ * - BYPASS_1X_PAE, -+ * - BYPASS_UNDEF_BRG_04, -+ * - BYPASS_UNDEF_BRG_05, -+ * - BYPASS_UNDEF_BRG_06, -+ * - BYPASS_UNDEF_BRG_07, -+ * - BYPASS_PROVIDER_BRIDGE_GROUP_ADDRESS, -+ * - BYPASS_UNDEF_BRG_09, -+ * - BYPASS_UNDEF_BRG_0A, -+ * - BYPASS_UNDEF_BRG_0B, -+ * - BYPASS_UNDEF_BRG_0C, -+ * - BYPASS_PROVIDER_BRIDGE_GVRP_ADDRESS, -+ * - BYPASS_8021AB, -+ * - BYPASS_UNDEF_BRG_0F, -+ * - BYPASS_BRG_MNGEMENT, -+ * - BYPASS_UNDEFINED_11, -+ * - BYPASS_UNDEFINED_12, -+ * - BYPASS_UNDEFINED_13, -+ * - BYPASS_UNDEFINED_14, -+ * - BYPASS_UNDEFINED_15, -+ * - BYPASS_UNDEFINED_16, -+ * - BYPASS_UNDEFINED_17, -+ * - BYPASS_UNDEFINED_18, -+ * - BYPASS_UNDEFINED_19, -+ * - BYPASS_UNDEFINED_1A, -+ * - BYPASS_UNDEFINED_1B, -+ * - BYPASS_UNDEFINED_1C, -+ * - BYPASS_UNDEFINED_1D, -+ * - BYPASS_UNDEFINED_1E, -+ * - BYPASS_UNDEFINED_1F, -+ * - BYPASS_GMRP, -+ * - BYPASS_GVRP, -+ * - BYPASS_UNDEF_GARP_22, -+ * - BYPASS_UNDEF_GARP_23, -+ * - BYPASS_UNDEF_GARP_24, -+ * - BYPASS_UNDEF_GARP_25, -+ * - BYPASS_UNDEF_GARP_26, -+ * - BYPASS_UNDEF_GARP_27, -+ * - BYPASS_UNDEF_GARP_28, -+ * - BYPASS_UNDEF_GARP_29, -+ * - BYPASS_UNDEF_GARP_2A, -+ * - BYPASS_UNDEF_GARP_2B, -+ * - BYPASS_UNDEF_GARP_2C, -+ * - BYPASS_UNDEF_GARP_2D, -+ * - BYPASS_UNDEF_GARP_2E, -+ * - BYPASS_UNDEF_GARP_2F, -+ * - BYPASS_IGMP. -+ * - BYPASS_CDP. -+ * - BYPASS_CSSTP. -+ * - BYPASS_LLDP. -+ */ -+rtk_api_ret_t rtk_storm_bypass_get(rtk_storm_bypass_t type, rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_rma_t rmacfg; -+ rtk_uint32 tmp; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (type >= BYPASS_END) -+ return RT_ERR_INPUT; -+ -+ if(NULL == pEnable) -+ return RT_ERR_NULL_POINTER; -+ -+ if (type >= 0 && type <= BYPASS_UNDEF_GARP_2F) -+ { -+ if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ *pEnable = rmacfg.discard_storm_filter; -+ } -+ else if(type == BYPASS_IGMP) -+ { -+ if ((retVal = rtl8367c_getAsicIGMPBypassStormCTRL(pEnable)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if (type == BYPASS_CDP) -+ { -+ if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ *pEnable = rmacfg.discard_storm_filter; -+ } -+ else if (type == BYPASS_CSSTP) -+ { -+ if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ *pEnable = rmacfg.discard_storm_filter; -+ } -+ else if (type == BYPASS_LLDP) -+ { -+ if ((retVal = rtl8367c_getAsicRmaLldp(&tmp,&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ *pEnable = rmacfg.discard_storm_filter; -+ } -+ else -+ return RT_ERR_INPUT; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_rate_stormControlExtPortmask_set -+ * Description: -+ * Set extension storm control port mask -+ * Input: -+ * pPortmask - port mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_INPUT - invalid input parameter -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_rate_stormControlExtPortmask_set(rtk_portmask_t *pPortmask) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pmask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pPortmask) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicStormFilterExtEnablePortMask(pmask)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_rate_stormControlExtPortmask_get -+ * Description: -+ * Set extension storm control port mask -+ * Input: -+ * None -+ * Output: -+ * pPortmask - port mask -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_INPUT - invalid input parameter -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_rate_stormControlExtPortmask_get(rtk_portmask_t *pPortmask) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pmask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pPortmask) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicStormFilterExtEnablePortMask(&pmask)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_rate_stormControlExtEnable_set -+ * Description: -+ * Set extension storm control state -+ * Input: -+ * stormType - storm group type -+ * enable - extension storm control state -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_INPUT - invalid input parameter -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_rate_stormControlExtEnable_set(rtk_rate_storm_group_t stormType, rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (stormType >= STORM_GROUP_END) -+ return RT_ERR_SFC_UNKNOWN_GROUP; -+ -+ if (enable >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ switch (stormType) -+ { -+ case STORM_GROUP_UNKNOWN_UNICAST: -+ if ((retVal = rtl8367c_setAsicStormFilterExtUnknownUnicastEnable(enable)) != RT_ERR_OK) -+ return retVal; -+ break; -+ case STORM_GROUP_UNKNOWN_MULTICAST: -+ if ((retVal = rtl8367c_setAsicStormFilterExtUnknownMulticastEnable(enable)) != RT_ERR_OK) -+ return retVal; -+ break; -+ case STORM_GROUP_MULTICAST: -+ if ((retVal = rtl8367c_setAsicStormFilterExtMulticastEnable(enable)) != RT_ERR_OK) -+ return retVal; -+ break; -+ case STORM_GROUP_BROADCAST: -+ if ((retVal = rtl8367c_setAsicStormFilterExtBroadcastEnable(enable)) != RT_ERR_OK) -+ return retVal; -+ break; -+ default: -+ break; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_rate_stormControlExtEnable_get -+ * Description: -+ * Get extension storm control state -+ * Input: -+ * stormType - storm group type -+ * Output: -+ * pEnable - extension storm control state -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_INPUT - invalid input parameter -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_rate_stormControlExtEnable_get(rtk_rate_storm_group_t stormType, rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (stormType >= STORM_GROUP_END) -+ return RT_ERR_SFC_UNKNOWN_GROUP; -+ -+ if (NULL == pEnable) -+ return RT_ERR_NULL_POINTER; -+ -+ switch (stormType) -+ { -+ case STORM_GROUP_UNKNOWN_UNICAST: -+ if ((retVal = rtl8367c_getAsicStormFilterExtUnknownUnicastEnable((rtk_uint32 *)pEnable)) != RT_ERR_OK) -+ return retVal; -+ break; -+ case STORM_GROUP_UNKNOWN_MULTICAST: -+ if ((retVal = rtl8367c_getAsicStormFilterExtUnknownMulticastEnable((rtk_uint32 *)pEnable)) != RT_ERR_OK) -+ return retVal; -+ break; -+ case STORM_GROUP_MULTICAST: -+ if ((retVal = rtl8367c_getAsicStormFilterExtMulticastEnable((rtk_uint32 *)pEnable)) != RT_ERR_OK) -+ return retVal; -+ break; -+ case STORM_GROUP_BROADCAST: -+ if ((retVal = rtl8367c_getAsicStormFilterExtBroadcastEnable((rtk_uint32 *)pEnable)) != RT_ERR_OK) -+ return retVal; -+ break; -+ default: -+ break; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_rate_stormControlExtMeterIdx_set -+ * Description: -+ * Set extension storm control meter index -+ * Input: -+ * stormType - storm group type -+ * index - extension storm control state -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_INPUT - invalid input parameter -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_rate_stormControlExtMeterIdx_set(rtk_rate_storm_group_t stormType, rtk_uint32 index) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (stormType >= STORM_GROUP_END) -+ return RT_ERR_SFC_UNKNOWN_GROUP; -+ -+ if (index > RTK_MAX_METER_ID) -+ return RT_ERR_FILTER_METER_ID; -+ -+ switch (stormType) -+ { -+ case STORM_GROUP_UNKNOWN_UNICAST: -+ if ((retVal = rtl8367c_setAsicStormFilterExtUnknownUnicastMeter(index))!=RT_ERR_OK) -+ return retVal; -+ break; -+ case STORM_GROUP_UNKNOWN_MULTICAST: -+ if ((retVal = rtl8367c_setAsicStormFilterExtUnknownMulticastMeter(index))!=RT_ERR_OK) -+ return retVal; -+ break; -+ case STORM_GROUP_MULTICAST: -+ if ((retVal = rtl8367c_setAsicStormFilterExtMulticastMeter(index))!=RT_ERR_OK) -+ return retVal; -+ break; -+ case STORM_GROUP_BROADCAST: -+ if ((retVal = rtl8367c_setAsicStormFilterExtBroadcastMeter(index))!=RT_ERR_OK) -+ return retVal; -+ break; -+ default: -+ break; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_rate_stormControlExtMeterIdx_get -+ * Description: -+ * Get extension storm control meter index -+ * Input: -+ * stormType - storm group type -+ * pIndex - extension storm control state -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_INPUT - invalid input parameter -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_rate_stormControlExtMeterIdx_get(rtk_rate_storm_group_t stormType, rtk_uint32 *pIndex) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (stormType >= STORM_GROUP_END) -+ return RT_ERR_SFC_UNKNOWN_GROUP; -+ -+ if(NULL == pIndex) -+ return RT_ERR_NULL_POINTER; -+ -+ switch (stormType) -+ { -+ case STORM_GROUP_UNKNOWN_UNICAST: -+ if ((retVal = rtl8367c_getAsicStormFilterExtUnknownUnicastMeter(pIndex))!=RT_ERR_OK) -+ return retVal; -+ break; -+ case STORM_GROUP_UNKNOWN_MULTICAST: -+ if ((retVal = rtl8367c_getAsicStormFilterExtUnknownMulticastMeter(pIndex))!=RT_ERR_OK) -+ return retVal; -+ break; -+ case STORM_GROUP_MULTICAST: -+ if ((retVal = rtl8367c_getAsicStormFilterExtMulticastMeter(pIndex))!=RT_ERR_OK) -+ return retVal; -+ break; -+ case STORM_GROUP_BROADCAST: -+ if ((retVal = rtl8367c_getAsicStormFilterExtBroadcastMeter(pIndex))!=RT_ERR_OK) -+ return retVal; -+ break; -+ default: -+ break; -+ } -+ -+ return RT_ERR_OK; -+} -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/svlan.c b/drivers/net/phy/rtk/rtl8367c/svlan.c -new file mode 100644 -index 000000000000..067291526ac8 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/svlan.c -@@ -0,0 +1,2415 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTK switch high-level API for RTL8367/RTL8367C -+ * Feature : Here is a list of all functions and variables in SVLAN module. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+rtk_uint8 svlan_mbrCfgUsage[RTL8367C_SVIDXNO]; -+rtk_uint16 svlan_mbrCfgVid[RTL8367C_SVIDXNO]; -+rtk_svlan_lookupType_t svlan_lookupType; -+/* Function Name: -+ * rtk_svlan_init -+ * Description: -+ * Initialize SVLAN Configuration -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * Ether type of S-tag in 802.1ad is 0x88a8 and there are existed ether type 0x9100 and 0x9200 for Q-in-Q SLAN design. -+ * User can set matched ether type as service provider supported protocol. -+ */ -+rtk_api_ret_t rtk_svlan_init(void) -+{ -+ rtk_uint32 i; -+ rtk_api_ret_t retVal; -+ rtl8367c_svlan_memconf_t svlanMemConf; -+ rtl8367c_svlan_s2c_t svlanSP2CConf; -+ rtl8367c_svlan_mc2s_t svlanMC2SConf; -+ rtk_uint32 svidx; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /*default use C-priority*/ -+ if ((retVal = rtl8367c_setAsicSvlanPrioritySel(SPRISEL_CTAGPRI)) != RT_ERR_OK) -+ return retVal; -+ -+ /*Drop SVLAN untag frame*/ -+ if ((retVal = rtl8367c_setAsicSvlanIngressUntag(UNTAG_DROP)) != RT_ERR_OK) -+ return retVal; -+ -+ /*Drop SVLAN unmatch frame*/ -+ if ((retVal = rtl8367c_setAsicSvlanIngressUnmatch(UNMATCH_DROP)) != RT_ERR_OK) -+ return retVal; -+ -+ /*Set TPID to 0x88a8*/ -+ if ((retVal = rtl8367c_setAsicSvlanTpid(0x88a8)) != RT_ERR_OK) -+ return retVal; -+ -+ /*Clean Uplink Port Mask to none*/ -+ if ((retVal = rtl8367c_setAsicSvlanUplinkPortMask(0)) != RT_ERR_OK) -+ return retVal; -+ -+ /*Clean SVLAN Member Configuration*/ -+ for (i=0; i<= RTL8367C_SVIDXMAX; i++) -+ { -+ memset(&svlanMemConf, 0, sizeof(rtl8367c_svlan_memconf_t)); -+ if ((retVal = rtl8367c_setAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ /*Clean C2S Configuration*/ -+ for (i=0; i<= RTL8367C_C2SIDXMAX; i++) -+ { -+ if ((retVal = rtl8367c_setAsicSvlanC2SConf(i, 0,0,0)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ /*Clean SP2C Configuration*/ -+ for (i=0; i <= RTL8367C_SP2CMAX ; i++) -+ { -+ memset(&svlanSP2CConf, 0, sizeof(rtl8367c_svlan_s2c_t)); -+ if ((retVal = rtl8367c_setAsicSvlanSP2CConf(i, &svlanSP2CConf)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ /*Clean MC2S Configuration*/ -+ for (i=0 ; i<= RTL8367C_MC2SIDXMAX; i++) -+ { -+ memset(&svlanMC2SConf, 0, sizeof(rtl8367c_svlan_mc2s_t)); -+ if ((retVal = rtl8367c_setAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ -+ if ((retVal = rtk_svlan_lookupType_set(SVLAN_LOOKUP_S64MBRCGF)) != RT_ERR_OK) -+ return retVal; -+ -+ -+ for (svidx = 0; svidx <= RTL8367C_SVIDXMAX; svidx++) -+ { -+ svlan_mbrCfgUsage[svidx] = FALSE; -+ } -+ -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_svlan_servicePort_add -+ * Description: -+ * Add one service port in the specified device -+ * Input: -+ * port - Port id. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API is setting which port is connected to provider switch. All frames receiving from this port must -+ * contain accept SVID in S-tag field. -+ */ -+rtk_api_ret_t rtk_svlan_servicePort_add(rtk_port_t port) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pmsk; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* check port valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if ((retVal = rtl8367c_getAsicSvlanUplinkPortMask(&pmsk)) != RT_ERR_OK) -+ return retVal; -+ -+ pmsk = pmsk | (1<RTK_MAX_NUM_OF_PROTO_TYPE) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicSvlanTpid(svlan_tag_id)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_svlan_tpidEntry_get -+ * Description: -+ * Get accepted S-VLAN ether type setting. -+ * Input: -+ * None -+ * Output: -+ * pSvlan_tag_id - Ether type of S-tag frame parsing in uplink ports. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * This API is setting which port is connected to provider switch. All frames receiving from this port must -+ * contain accept SVID in S-tag field. -+ */ -+rtk_api_ret_t rtk_svlan_tpidEntry_get(rtk_svlan_tpid_t *pSvlan_tag_id) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pSvlan_tag_id) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicSvlanTpid(pSvlan_tag_id)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_svlan_priorityRef_set -+ * Description: -+ * Set S-VLAN upstream priority reference setting. -+ * Input: -+ * ref - reference selection parameter. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter. -+ * Note: -+ * The API can set the upstream SVLAN tag priority reference source. The related priority -+ * sources are as following: -+ * - REF_INTERNAL_PRI, -+ * - REF_CTAG_PRI, -+ * - REF_SVLAN_PRI, -+ * - REF_PB_PRI. -+ */ -+rtk_api_ret_t rtk_svlan_priorityRef_set(rtk_svlan_pri_ref_t ref) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (ref >= REF_PRI_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicSvlanPrioritySel(ref)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_svlan_priorityRef_get -+ * Description: -+ * Get S-VLAN upstream priority reference setting. -+ * Input: -+ * None -+ * Output: -+ * pRef - reference selection parameter. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * The API can get the upstream SVLAN tag priority reference source. The related priority -+ * sources are as following: -+ * - REF_INTERNAL_PRI, -+ * - REF_CTAG_PRI, -+ * - REF_SVLAN_PRI, -+ * - REF_PB_PRI -+ */ -+rtk_api_ret_t rtk_svlan_priorityRef_get(rtk_svlan_pri_ref_t *pRef) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pRef) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicSvlanPrioritySel(pRef)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_svlan_memberPortEntry_set -+ * Description: -+ * Configure system SVLAN member content -+ * Input: -+ * svid - SVLAN id -+ * psvlan_cfg - SVLAN member configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter. -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_PORT_MASK - Invalid portmask. -+ * RT_ERR_SVLAN_TABLE_FULL - SVLAN configuration is full. -+ * Note: -+ * The API can set system 64 accepted s-tag frame format. Only 64 SVID S-tag frame will be accepted -+ * to receiving from uplink ports. Other SVID S-tag frame or S-untagged frame will be dropped by default setup. -+ * - rtk_svlan_memberCfg_t->svid is SVID of SVLAN member configuration. -+ * - rtk_svlan_memberCfg_t->memberport is member port mask of SVLAN member configuration. -+ * - rtk_svlan_memberCfg_t->fid is filtering database of SVLAN member configuration. -+ * - rtk_svlan_memberCfg_t->priority is priority of SVLAN member configuration. -+ */ -+rtk_api_ret_t rtk_svlan_memberPortEntry_set(rtk_vlan_t svid, rtk_svlan_memberCfg_t *pSvlan_cfg) -+{ -+ rtk_api_ret_t retVal; -+ rtk_int32 i; -+ rtk_uint32 empty_idx; -+ rtl8367c_svlan_memconf_t svlanMemConf; -+ rtk_uint32 phyMbrPmask; -+ rtk_vlan_cfg_t vlanCfg; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pSvlan_cfg) -+ return RT_ERR_NULL_POINTER; -+ -+ if(svid > RTL8367C_VIDMAX) -+ return RT_ERR_SVLAN_VID; -+ -+ RTK_CHK_PORTMASK_VALID(&(pSvlan_cfg->memberport)); -+ -+ RTK_CHK_PORTMASK_VALID(&(pSvlan_cfg->untagport)); -+ -+ if (pSvlan_cfg->fiden > ENABLED) -+ return RT_ERR_ENABLE; -+ -+ if (pSvlan_cfg->fid > RTL8367C_FIDMAX) -+ return RT_ERR_L2_FID; -+ -+ if (pSvlan_cfg->priority > RTL8367C_PRIMAX) -+ return RT_ERR_VLAN_PRIORITY; -+ -+ if (pSvlan_cfg->efiden > ENABLED) -+ return RT_ERR_ENABLE; -+ -+ if (pSvlan_cfg->efid > RTL8367C_EFIDMAX) -+ return RT_ERR_L2_FID; -+ -+ if(SVLAN_LOOKUP_C4KVLAN == svlan_lookupType) -+ { -+ if ((retVal = rtk_vlan_get(svid, &vlanCfg)) != RT_ERR_OK) -+ return retVal; -+ -+ vlanCfg.mbr = pSvlan_cfg->memberport; -+ vlanCfg.untag = pSvlan_cfg->untagport; -+ -+ if ((retVal = rtk_vlan_set(svid, &vlanCfg)) != RT_ERR_OK) -+ return retVal; -+ -+ empty_idx = 0xFF; -+ -+ for (i = 0; i<= RTL8367C_SVIDXMAX; i++) -+ { -+ if (svid == svlan_mbrCfgVid[i] && TRUE == svlan_mbrCfgUsage[i]) -+ { -+ memset(&svlanMemConf, 0, sizeof(rtl8367c_svlan_memconf_t)); -+ svlanMemConf.vs_svid = svid; -+ svlanMemConf.vs_efiden = pSvlan_cfg->efiden; -+ svlanMemConf.vs_efid = pSvlan_cfg->efid; -+ svlanMemConf.vs_priority = pSvlan_cfg->priority; -+ -+ /*for create check*/ -+ if(0 == svlanMemConf.vs_efiden && 0 == svlanMemConf.vs_efid) -+ svlanMemConf.vs_efid = 1; -+ -+ if ((retVal = rtl8367c_setAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+ } -+ else if (FALSE == svlan_mbrCfgUsage[i] && 0xFF == empty_idx) -+ { -+ empty_idx = i; -+ } -+ } -+ -+ if (empty_idx != 0xFF) -+ { -+ svlan_mbrCfgUsage[empty_idx] = TRUE; -+ svlan_mbrCfgVid[empty_idx] = svid; -+ -+ memset(&svlanMemConf, 0, sizeof(rtl8367c_svlan_memconf_t)); -+ svlanMemConf.vs_svid = svid; -+ svlanMemConf.vs_efiden = pSvlan_cfg->efiden; -+ svlanMemConf.vs_efid = pSvlan_cfg->efid; -+ svlanMemConf.vs_priority = pSvlan_cfg->priority; -+ -+ /*for create check*/ -+ if(0 == svlanMemConf.vs_efiden && 0 == svlanMemConf.vs_efid) -+ svlanMemConf.vs_efid = 1; -+ -+ if ((retVal = rtl8367c_setAsicSvlanMemberConfiguration(empty_idx, &svlanMemConf)) != RT_ERR_OK) -+ return retVal; -+ -+ } -+ -+ return RT_ERR_OK; -+ } -+ -+ -+ empty_idx = 0xFF; -+ -+ for (i = 0; i<= RTL8367C_SVIDXMAX; i++) -+ { -+ /* -+ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) -+ return retVal; -+ */ -+ if (svid == svlan_mbrCfgVid[i] && TRUE == svlan_mbrCfgUsage[i]) -+ { -+ svlanMemConf.vs_svid = svid; -+ -+ if(rtk_switch_portmask_L2P_get(&(pSvlan_cfg->memberport), &phyMbrPmask) != RT_ERR_OK) -+ return RT_ERR_FAILED; -+ -+ svlanMemConf.vs_member = phyMbrPmask; -+ -+ if(rtk_switch_portmask_L2P_get(&(pSvlan_cfg->untagport), &phyMbrPmask) != RT_ERR_OK) -+ return RT_ERR_FAILED; -+ -+ svlanMemConf.vs_untag = phyMbrPmask; -+ -+ svlanMemConf.vs_force_fid = pSvlan_cfg->fiden; -+ svlanMemConf.vs_fid_msti = pSvlan_cfg->fid; -+ svlanMemConf.vs_priority = pSvlan_cfg->priority; -+ svlanMemConf.vs_efiden = pSvlan_cfg->efiden; -+ svlanMemConf.vs_efid = pSvlan_cfg->efid; -+ -+ /*all items are reset means deleting*/ -+ if( 0 == svlanMemConf.vs_member && -+ 0 == svlanMemConf.vs_untag && -+ 0 == svlanMemConf.vs_force_fid && -+ 0 == svlanMemConf.vs_fid_msti && -+ 0 == svlanMemConf.vs_priority && -+ 0 == svlanMemConf.vs_efiden && -+ 0 == svlanMemConf.vs_efid) -+ { -+ svlan_mbrCfgUsage[i] = FALSE; -+ svlan_mbrCfgVid[i] = 0; -+ -+ /* Clear SVID also */ -+ svlanMemConf.vs_svid = 0; -+ } -+ else -+ { -+ svlan_mbrCfgUsage[i] = TRUE; -+ svlan_mbrCfgVid[i] = svlanMemConf.vs_svid; -+ -+ if(0 == svlanMemConf.vs_svid) -+ { -+ /*for create check*/ -+ if(0 == svlanMemConf.vs_efiden && 0 == svlanMemConf.vs_efid) -+ { -+ svlanMemConf.vs_efid = 1; -+ } -+ } -+ } -+ -+ if ((retVal = rtl8367c_setAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+ } -+ else if (FALSE == svlan_mbrCfgUsage[i] && 0xFF == empty_idx) -+ { -+ empty_idx = i; -+ } -+ } -+ -+ if (empty_idx != 0xFF) -+ { -+ memset(&svlanMemConf, 0, sizeof(rtl8367c_svlan_memconf_t)); -+ svlanMemConf.vs_svid = svid; -+ -+ if(rtk_switch_portmask_L2P_get(&(pSvlan_cfg->memberport), &phyMbrPmask) != RT_ERR_OK) -+ return RT_ERR_FAILED; -+ -+ svlanMemConf.vs_member = phyMbrPmask; -+ -+ if(rtk_switch_portmask_L2P_get(&(pSvlan_cfg->untagport), &phyMbrPmask) != RT_ERR_OK) -+ return RT_ERR_FAILED; -+ -+ svlanMemConf.vs_untag = phyMbrPmask; -+ -+ svlanMemConf.vs_force_fid = pSvlan_cfg->fiden; -+ svlanMemConf.vs_fid_msti = pSvlan_cfg->fid; -+ svlanMemConf.vs_priority = pSvlan_cfg->priority; -+ -+ svlanMemConf.vs_efiden = pSvlan_cfg->efiden; -+ svlanMemConf.vs_efid = pSvlan_cfg->efid; -+ -+ /*change efid for empty svid 0*/ -+ if(0 == svlanMemConf.vs_svid) -+ { /*for create check*/ -+ if(0 == svlanMemConf.vs_efiden && 0 == svlanMemConf.vs_efid) -+ { -+ svlanMemConf.vs_efid = 1; -+ } -+ } -+ -+ svlan_mbrCfgUsage[empty_idx] = TRUE; -+ svlan_mbrCfgVid[empty_idx] = svlanMemConf.vs_svid; -+ -+ if ((retVal = rtl8367c_setAsicSvlanMemberConfiguration(empty_idx, &svlanMemConf)) != RT_ERR_OK) -+ { -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+ } -+ -+ return RT_ERR_SVLAN_TABLE_FULL; -+} -+ -+/* Function Name: -+ * rtk_svlan_memberPortEntry_get -+ * Description: -+ * Get SVLAN member Configure. -+ * Input: -+ * svid - SVLAN id -+ * Output: -+ * pSvlan_cfg - SVLAN member configuration -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can get system 64 accepted s-tag frame format. Only 64 SVID S-tag frame will be accepted -+ * to receiving from uplink ports. Other SVID S-tag frame or S-untagged frame will be dropped. -+ */ -+rtk_api_ret_t rtk_svlan_memberPortEntry_get(rtk_vlan_t svid, rtk_svlan_memberCfg_t *pSvlan_cfg) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 i; -+ rtl8367c_svlan_memconf_t svlanMemConf; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pSvlan_cfg) -+ return RT_ERR_NULL_POINTER; -+ -+ if (svid > RTL8367C_VIDMAX) -+ return RT_ERR_SVLAN_VID; -+ -+ -+ for (i = 0; i<= RTL8367C_SVIDXMAX; i++) -+ { -+ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) -+ return retVal; -+ -+ if (svid == svlanMemConf.vs_svid) -+ { -+ pSvlan_cfg->svid = svlanMemConf.vs_svid; -+ -+ if(rtk_switch_portmask_P2L_get(svlanMemConf.vs_member,&(pSvlan_cfg->memberport)) != RT_ERR_OK) -+ return RT_ERR_FAILED; -+ -+ if(rtk_switch_portmask_P2L_get(svlanMemConf.vs_untag,&(pSvlan_cfg->untagport)) != RT_ERR_OK) -+ return RT_ERR_FAILED; -+ -+ pSvlan_cfg->fiden = svlanMemConf.vs_force_fid; -+ pSvlan_cfg->fid = svlanMemConf.vs_fid_msti; -+ pSvlan_cfg->priority = svlanMemConf.vs_priority; -+ pSvlan_cfg->efiden = svlanMemConf.vs_efiden; -+ pSvlan_cfg->efid = svlanMemConf.vs_efid; -+ -+ return RT_ERR_OK; -+ } -+ } -+ -+ return RT_ERR_SVLAN_ENTRY_NOT_FOUND; -+ -+} -+ -+/* Function Name: -+ * rtk_svlan_memberPortEntry_adv_set -+ * Description: -+ * Configure system SVLAN member by index -+ * Input: -+ * idx - Index (0 ~ 63) -+ * psvlan_cfg - SVLAN member configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter. -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_PORT_MASK - Invalid portmask. -+ * RT_ERR_SVLAN_TABLE_FULL - SVLAN configuration is full. -+ * Note: -+ * The API can set system 64 accepted s-tag frame format by index. -+ * - rtk_svlan_memberCfg_t->svid is SVID of SVLAN member configuration. -+ * - rtk_svlan_memberCfg_t->memberport is member port mask of SVLAN member configuration. -+ * - rtk_svlan_memberCfg_t->fid is filtering database of SVLAN member configuration. -+ * - rtk_svlan_memberCfg_t->priority is priority of SVLAN member configuration. -+ */ -+rtk_api_ret_t rtk_svlan_memberPortEntry_adv_set(rtk_uint32 idx, rtk_svlan_memberCfg_t *pSvlan_cfg) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_svlan_memconf_t svlanMemConf; -+ rtk_uint32 phyMbrPmask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pSvlan_cfg) -+ return RT_ERR_NULL_POINTER; -+ -+ if (idx > RTL8367C_SVIDXMAX) -+ return RT_ERR_SVLAN_ENTRY_INDEX; -+ -+ if (pSvlan_cfg->svid>RTL8367C_VIDMAX) -+ return RT_ERR_SVLAN_VID; -+ -+ RTK_CHK_PORTMASK_VALID(&(pSvlan_cfg->memberport)); -+ -+ RTK_CHK_PORTMASK_VALID(&(pSvlan_cfg->untagport)); -+ -+ if (pSvlan_cfg->fiden > ENABLED) -+ return RT_ERR_ENABLE; -+ -+ if (pSvlan_cfg->fid > RTL8367C_FIDMAX) -+ return RT_ERR_L2_FID; -+ -+ if (pSvlan_cfg->priority > RTL8367C_PRIMAX) -+ return RT_ERR_VLAN_PRIORITY; -+ -+ if (pSvlan_cfg->efiden > ENABLED) -+ return RT_ERR_ENABLE; -+ -+ if (pSvlan_cfg->efid > RTL8367C_EFIDMAX) -+ return RT_ERR_L2_FID; -+ -+ memset(&svlanMemConf, 0, sizeof(rtl8367c_svlan_memconf_t)); -+ svlanMemConf.vs_svid = pSvlan_cfg->svid; -+ if(rtk_switch_portmask_L2P_get(&(pSvlan_cfg->memberport), &phyMbrPmask) != RT_ERR_OK) -+ return RT_ERR_FAILED; -+ -+ svlanMemConf.vs_member = phyMbrPmask; -+ -+ if(rtk_switch_portmask_L2P_get(&(pSvlan_cfg->untagport), &phyMbrPmask) != RT_ERR_OK) -+ return RT_ERR_FAILED; -+ -+ svlanMemConf.vs_untag = phyMbrPmask; -+ -+ -+ svlanMemConf.vs_force_fid = pSvlan_cfg->fiden; -+ svlanMemConf.vs_fid_msti = pSvlan_cfg->fid; -+ svlanMemConf.vs_priority = pSvlan_cfg->priority; -+ svlanMemConf.vs_efiden = pSvlan_cfg->efiden; -+ svlanMemConf.vs_efid = pSvlan_cfg->efid; -+ -+ if(0 == svlanMemConf.vs_svid && -+ 0 == svlanMemConf.vs_member && -+ 0 == svlanMemConf.vs_untag && -+ 0 == svlanMemConf.vs_force_fid && -+ 0 == svlanMemConf.vs_fid_msti && -+ 0 == svlanMemConf.vs_priority && -+ 0 == svlanMemConf.vs_efiden && -+ 0 == svlanMemConf.vs_efid) -+ { -+ svlan_mbrCfgUsage[idx] = FALSE; -+ svlan_mbrCfgVid[idx] = 0; -+ } -+ else -+ { -+ svlan_mbrCfgUsage[idx] = TRUE; -+ svlan_mbrCfgVid[idx] = svlanMemConf.vs_svid; -+ } -+ -+ if ((retVal = rtl8367c_setAsicSvlanMemberConfiguration(idx, &svlanMemConf)) != RT_ERR_OK) -+ return retVal; -+ -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_svlan_memberPortEntry_adv_get -+ * Description: -+ * Get SVLAN member Configure by index. -+ * Input: -+ * idx - Index (0 ~ 63) -+ * Output: -+ * pSvlan_cfg - SVLAN member configuration -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can get system 64 accepted s-tag frame format. Only 64 SVID S-tag frame will be accepted -+ * to receiving from uplink ports. Other SVID S-tag frame or S-untagged frame will be dropped. -+ */ -+rtk_api_ret_t rtk_svlan_memberPortEntry_adv_get(rtk_uint32 idx, rtk_svlan_memberCfg_t *pSvlan_cfg) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_svlan_memconf_t svlanMemConf; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pSvlan_cfg) -+ return RT_ERR_NULL_POINTER; -+ -+ if (idx > RTL8367C_SVIDXMAX) -+ return RT_ERR_SVLAN_ENTRY_INDEX; -+ -+ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(idx, &svlanMemConf)) != RT_ERR_OK) -+ return retVal; -+ -+ pSvlan_cfg->svid = svlanMemConf.vs_svid; -+ if(rtk_switch_portmask_P2L_get(svlanMemConf.vs_member,&(pSvlan_cfg->memberport)) != RT_ERR_OK) -+ return RT_ERR_FAILED; -+ -+ if(rtk_switch_portmask_P2L_get(svlanMemConf.vs_untag,&(pSvlan_cfg->untagport)) != RT_ERR_OK) -+ return RT_ERR_FAILED; -+ -+ pSvlan_cfg->fiden = svlanMemConf.vs_force_fid; -+ pSvlan_cfg->fid = svlanMemConf.vs_fid_msti; -+ pSvlan_cfg->priority = svlanMemConf.vs_priority; -+ pSvlan_cfg->efiden = svlanMemConf.vs_efiden; -+ pSvlan_cfg->efid = svlanMemConf.vs_efid; -+ -+ return RT_ERR_OK; -+ -+} -+ -+/* Function Name: -+ * rtk_svlan_defaultSvlan_set -+ * Description: -+ * Configure default egress SVLAN. -+ * Input: -+ * port - Source port -+ * svid - SVLAN id -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameter. -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. -+ * Note: -+ * The API can set port n S-tag format index while receiving frame from port n -+ * is transmit through uplink port with s-tag field -+ */ -+rtk_api_ret_t rtk_svlan_defaultSvlan_set(rtk_port_t port, rtk_vlan_t svid) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 i; -+ rtl8367c_svlan_memconf_t svlanMemConf; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ /* svid must be 0~4095 */ -+ if (svid > RTL8367C_VIDMAX) -+ return RT_ERR_SVLAN_VID; -+ -+ for (i = 0; i < RTL8367C_SVIDXNO; i++) -+ { -+ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) -+ return retVal; -+ -+ if (svid == svlanMemConf.vs_svid) -+ { -+ if ((retVal = rtl8367c_setAsicSvlanDefaultVlan(rtk_switch_port_L2P_get(port), i)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+ } -+ } -+ -+ return RT_ERR_SVLAN_ENTRY_NOT_FOUND; -+} -+ -+/* Function Name: -+ * rtk_svlan_defaultSvlan_get -+ * Description: -+ * Get the configure default egress SVLAN. -+ * Input: -+ * port - Source port -+ * Output: -+ * pSvid - SVLAN VID -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can get port n S-tag format index while receiving frame from port n -+ * is transmit through uplink port with s-tag field -+ */ -+rtk_api_ret_t rtk_svlan_defaultSvlan_get(rtk_port_t port, rtk_vlan_t *pSvid) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 idx; -+ rtl8367c_svlan_memconf_t svlanMemConf; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pSvid) -+ return RT_ERR_NULL_POINTER; -+ -+ /* Check port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if ((retVal = rtl8367c_getAsicSvlanDefaultVlan(rtk_switch_port_L2P_get(port), &idx)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(idx, &svlanMemConf)) != RT_ERR_OK) -+ return retVal; -+ -+ *pSvid = svlanMemConf.vs_svid; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_svlan_c2s_add -+ * Description: -+ * Configure SVLAN C2S table -+ * Input: -+ * vid - VLAN ID -+ * src_port - Ingress Port -+ * svid - SVLAN VID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port ID. -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_VLAN_VID - Invalid VID parameter. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can set system C2S configuration. ASIC will check upstream's VID and assign related -+ * SVID to matched packet. There are 128 SVLAN C2S configurations. -+ */ -+rtk_api_ret_t rtk_svlan_c2s_add(rtk_vlan_t vid, rtk_port_t src_port, rtk_vlan_t svid) -+{ -+ rtk_api_ret_t retVal, i; -+ rtk_uint32 empty_idx; -+ rtk_uint32 evid, pmsk, svidx, c2s_svidx; -+ rtl8367c_svlan_memconf_t svlanMemConf; -+ rtk_port_t phyPort; -+ rtk_uint16 doneFlag; -+ -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ -+ if (vid > RTL8367C_VIDMAX) -+ return RT_ERR_VLAN_VID; -+ -+ if (svid > RTL8367C_VIDMAX) -+ return RT_ERR_SVLAN_VID; -+ -+ /* Check port Valid */ -+ RTK_CHK_PORT_VALID(src_port); -+ -+ phyPort = rtk_switch_port_L2P_get(src_port); -+ -+ empty_idx = 0xFFFF; -+ svidx = 0xFFFF; -+ doneFlag = FALSE; -+ -+ for (i = 0; i<= RTL8367C_SVIDXMAX; i++) -+ { -+ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) -+ return retVal; -+ -+ if (svid == svlanMemConf.vs_svid) -+ { -+ svidx = i; -+ break; -+ } -+ } -+ -+ if (0xFFFF == svidx) -+ return RT_ERR_SVLAN_VID; -+ -+ for (i=RTL8367C_C2SIDXMAX; i>=0; i--) -+ { -+ if ((retVal = rtl8367c_getAsicSvlanC2SConf(i, &evid, &pmsk, &c2s_svidx)) != RT_ERR_OK) -+ return retVal; -+ -+ if (evid == vid) -+ { -+ /* Check Src_port */ -+ if(pmsk & (1 << phyPort)) -+ { -+ /* Check SVIDX */ -+ if(c2s_svidx == svidx) -+ { -+ /* All the same, do nothing */ -+ } -+ else -+ { -+ /* New svidx, remove src_port and find a new slot to add a new entry */ -+ pmsk = pmsk & ~(1 << phyPort); -+ if(pmsk == 0) -+ c2s_svidx = 0; -+ -+ if ((retVal = rtl8367c_setAsicSvlanC2SConf(i, vid, pmsk, c2s_svidx)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ else -+ { -+ if(c2s_svidx == svidx && doneFlag == FALSE) -+ { -+ pmsk = pmsk | (1 << phyPort); -+ if ((retVal = rtl8367c_setAsicSvlanC2SConf(i, vid, pmsk, svidx)) != RT_ERR_OK) -+ return retVal; -+ -+ doneFlag = TRUE; -+ } -+ } -+ } -+ else if (evid==0&&pmsk==0) -+ { -+ empty_idx = i; -+ } -+ } -+ -+ if (0xFFFF != empty_idx && doneFlag ==FALSE) -+ { -+ if ((retVal = rtl8367c_setAsicSvlanC2SConf(empty_idx, vid, (1< RTL8367C_EVIDMAX) -+ return RT_ERR_VLAN_VID; -+ -+ /* Check port Valid */ -+ RTK_CHK_PORT_VALID(src_port); -+ phyPort = rtk_switch_port_L2P_get(src_port); -+ -+ for (i = 0; i <= RTL8367C_C2SIDXMAX; i++) -+ { -+ if ((retVal = rtl8367c_getAsicSvlanC2SConf(i, &evid, &pmsk, &svidx)) != RT_ERR_OK) -+ return retVal; -+ -+ if (evid == vid) -+ { -+ if(pmsk & (1 << phyPort)) -+ { -+ pmsk = pmsk & ~(1 << phyPort); -+ if(pmsk == 0) -+ { -+ vid = 0; -+ svidx = 0; -+ } -+ -+ if ((retVal = rtl8367c_setAsicSvlanC2SConf(i, vid, pmsk, svidx)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+ } -+ } -+ } -+ -+ return RT_ERR_OUT_OF_RANGE; -+} -+ -+/* Function Name: -+ * rtk_svlan_c2s_get -+ * Description: -+ * Get configure SVLAN C2S table -+ * Input: -+ * vid - VLAN ID -+ * src_port - Ingress Port -+ * Output: -+ * pSvid - SVLAN ID -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port ID. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * Note: -+ * The API can get system C2S configuration. There are 128 SVLAN C2S configurations. -+ */ -+rtk_api_ret_t rtk_svlan_c2s_get(rtk_vlan_t vid, rtk_port_t src_port, rtk_vlan_t *pSvid) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 i; -+ rtk_uint32 evid, pmsk, svidx; -+ rtl8367c_svlan_memconf_t svlanMemConf; -+ rtk_port_t phyPort; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pSvid) -+ return RT_ERR_NULL_POINTER; -+ -+ if (vid > RTL8367C_VIDMAX) -+ return RT_ERR_VLAN_VID; -+ -+ /* Check port Valid */ -+ RTK_CHK_PORT_VALID(src_port); -+ phyPort = rtk_switch_port_L2P_get(src_port); -+ -+ for (i = 0; i <= RTL8367C_C2SIDXMAX; i++) -+ { -+ if ((retVal = rtl8367c_getAsicSvlanC2SConf(i, &evid, &pmsk, &svidx)) != RT_ERR_OK) -+ return retVal; -+ -+ if (evid == vid) -+ { -+ if(pmsk & (1 << phyPort)) -+ { -+ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(svidx, &svlanMemConf)) != RT_ERR_OK) -+ return retVal; -+ -+ *pSvid = svlanMemConf.vs_svid; -+ return RT_ERR_OK; -+ } -+ } -+ } -+ -+ return RT_ERR_OUT_OF_RANGE; -+} -+ -+/* Function Name: -+ * rtk_svlan_untag_action_set -+ * Description: -+ * Configure Action of downstream UnStag packet -+ * Input: -+ * action - Action for UnStag -+ * svid - The SVID assigned to UnStag packet -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can configure action of downstream Un-Stag packet. A SVID assigned -+ * to the un-stag is also supported by this API. The parameter of svid is -+ * only referenced when the action is set to UNTAG_ASSIGN -+ */ -+rtk_api_ret_t rtk_svlan_untag_action_set(rtk_svlan_untag_action_t action, rtk_vlan_t svid) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 i; -+ rtl8367c_svlan_memconf_t svlanMemConf; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (action >= UNTAG_END) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if(action == UNTAG_ASSIGN) -+ { -+ if (svid > RTL8367C_VIDMAX) -+ return RT_ERR_SVLAN_VID; -+ } -+ -+ if ((retVal = rtl8367c_setAsicSvlanIngressUntag((rtk_uint32)action)) != RT_ERR_OK) -+ return retVal; -+ -+ if(action == UNTAG_ASSIGN) -+ { -+ for (i = 0; i < RTL8367C_SVIDXNO; i++) -+ { -+ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) -+ return retVal; -+ -+ if (svid == svlanMemConf.vs_svid) -+ { -+ if ((retVal = rtl8367c_setAsicSvlanUntagVlan(i)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+ } -+ } -+ -+ return RT_ERR_SVLAN_ENTRY_NOT_FOUND; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_svlan_untag_action_get -+ * Description: -+ * Get Action of downstream UnStag packet -+ * Input: -+ * None -+ * Output: -+ * pAction - Action for UnStag -+ * pSvid - The SVID assigned to UnStag packet -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can Get action of downstream Un-Stag packet. A SVID assigned -+ * to the un-stag is also retrieved by this API. The parameter pSvid is -+ * only referenced when the action is UNTAG_ASSIGN -+ */ -+rtk_api_ret_t rtk_svlan_untag_action_get(rtk_svlan_untag_action_t *pAction, rtk_vlan_t *pSvid) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 svidx; -+ rtl8367c_svlan_memconf_t svlanMemConf; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pAction || NULL == pSvid) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicSvlanIngressUntag(pAction)) != RT_ERR_OK) -+ return retVal; -+ -+ if(*pAction == UNTAG_ASSIGN) -+ { -+ if ((retVal = rtl8367c_getAsicSvlanUntagVlan(&svidx)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(svidx, &svlanMemConf)) != RT_ERR_OK) -+ return retVal; -+ -+ *pSvid = svlanMemConf.vs_svid; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_svlan_unmatch_action_set -+ * Description: -+ * Configure Action of downstream Unmatch packet -+ * Input: -+ * action - Action for Unmatch -+ * svid - The SVID assigned to Unmatch packet -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can configure action of downstream Un-match packet. A SVID assigned -+ * to the un-match is also supported by this API. The parameter of svid is -+ * only referenced when the action is set to UNMATCH_ASSIGN -+ */ -+rtk_api_ret_t rtk_svlan_unmatch_action_set(rtk_svlan_unmatch_action_t action, rtk_vlan_t svid) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 i; -+ rtl8367c_svlan_memconf_t svlanMemConf; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (action >= UNMATCH_END) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if (action == UNMATCH_ASSIGN) -+ { -+ if (svid > RTL8367C_VIDMAX) -+ return RT_ERR_SVLAN_VID; -+ } -+ -+ if ((retVal = rtl8367c_setAsicSvlanIngressUnmatch((rtk_uint32)action)) != RT_ERR_OK) -+ return retVal; -+ -+ if(action == UNMATCH_ASSIGN) -+ { -+ for (i = 0; i < RTL8367C_SVIDXNO; i++) -+ { -+ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) -+ return retVal; -+ -+ if (svid == svlanMemConf.vs_svid) -+ { -+ if ((retVal = rtl8367c_setAsicSvlanUnmatchVlan(i)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+ } -+ } -+ -+ return RT_ERR_SVLAN_ENTRY_NOT_FOUND; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_svlan_unmatch_action_get -+ * Description: -+ * Get Action of downstream Unmatch packet -+ * Input: -+ * None -+ * Output: -+ * pAction - Action for Unmatch -+ * pSvid - The SVID assigned to Unmatch packet -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can Get action of downstream Un-match packet. A SVID assigned -+ * to the un-match is also retrieved by this API. The parameter pSvid is -+ * only referenced when the action is UNMATCH_ASSIGN -+ */ -+rtk_api_ret_t rtk_svlan_unmatch_action_get(rtk_svlan_unmatch_action_t *pAction, rtk_vlan_t *pSvid) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 svidx; -+ rtl8367c_svlan_memconf_t svlanMemConf; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pAction || NULL == pSvid) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicSvlanIngressUnmatch(pAction)) != RT_ERR_OK) -+ return retVal; -+ -+ if(*pAction == UNMATCH_ASSIGN) -+ { -+ if ((retVal = rtl8367c_getAsicSvlanUnmatchVlan(&svidx)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(svidx, &svlanMemConf)) != RT_ERR_OK) -+ return retVal; -+ -+ *pSvid = svlanMemConf.vs_svid; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_svlan_unassign_action_set -+ * Description: -+ * Configure Action of upstream without svid assign action -+ * Input: -+ * action - Action for Un-assign -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can configure action of upstream Un-assign svid packet. If action is not -+ * trap to CPU, the port-based SVID sure be assign as system need -+ */ -+rtk_api_ret_t rtk_svlan_unassign_action_set(rtk_svlan_unassign_action_t action) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (action >= UNASSIGN_END) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ retVal = rtl8367c_setAsicSvlanEgressUnassign((rtk_uint32)action); -+ -+ return retVal; -+} -+ -+/* Function Name: -+ * rtk_svlan_unassign_action_get -+ * Description: -+ * Get action of upstream without svid assignment -+ * Input: -+ * None -+ * Output: -+ * pAction - Action for Un-assign -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * Note: -+ * None -+ */ -+rtk_api_ret_t rtk_svlan_unassign_action_get(rtk_svlan_unassign_action_t *pAction) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pAction) -+ return RT_ERR_NULL_POINTER; -+ -+ retVal = rtl8367c_getAsicSvlanEgressUnassign(pAction); -+ -+ return retVal; -+} -+ -+/* Function Name: -+ * rtk_svlan_dmac_vidsel_set -+ * Description: -+ * Set DMAC CVID selection -+ * Input: -+ * port - Port -+ * enable - state of DMAC CVID Selection -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can set DMAC CVID Selection state -+ */ -+rtk_api_ret_t rtk_svlan_dmac_vidsel_set(rtk_port_t port, rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (enable >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ if ((retVal = rtl8367c_setAsicSvlanDmacCvidSel(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_svlan_dmac_vidsel_get -+ * Description: -+ * Get DMAC CVID selection -+ * Input: -+ * port - Port -+ * Output: -+ * pEnable - state of DMAC CVID Selection -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can get DMAC CVID Selection state -+ */ -+rtk_api_ret_t rtk_svlan_dmac_vidsel_get(rtk_port_t port, rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pEnable) -+ return RT_ERR_NULL_POINTER; -+ -+ /* Check port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if ((retVal = rtl8367c_getAsicSvlanDmacCvidSel(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_svlan_ipmc2s_add -+ * Description: -+ * add ip multicast address to SVLAN -+ * Input: -+ * svid - SVLAN VID -+ * ipmc - ip multicast address -+ * ipmcMsk - ip multicast mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can set IP multicast to SVID configuration. If upstream packet is IPv4 multicast -+ * packet and DIP is matched MC2S configuration, ASIC will assign egress SVID to the packet. -+ * There are 32 SVLAN multicast configurations for IP and L2 multicast. -+ */ -+rtk_api_ret_t rtk_svlan_ipmc2s_add(ipaddr_t ipmc, ipaddr_t ipmcMsk,rtk_vlan_t svid) -+{ -+ rtk_api_ret_t retVal, i; -+ rtk_uint32 empty_idx; -+ rtk_uint32 svidx; -+ rtl8367c_svlan_memconf_t svlanMemConf; -+ rtl8367c_svlan_mc2s_t svlanMC2SConf; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (svid > RTL8367C_VIDMAX) -+ return RT_ERR_SVLAN_VID; -+ -+ if ((ipmc&0xF0000000)!=0xE0000000) -+ return RT_ERR_INPUT; -+ -+ svidx = 0xFFFF; -+ -+ for (i = 0; i < RTL8367C_SVIDXNO; i++) -+ { -+ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) -+ return retVal; -+ -+ if (svid == svlanMemConf.vs_svid) -+ { -+ svidx = i; -+ break; -+ } -+ } -+ -+ if (0xFFFF == svidx) -+ return RT_ERR_SVLAN_ENTRY_NOT_FOUND; -+ -+ -+ empty_idx = 0xFFFF; -+ -+ for (i = RTL8367C_MC2SIDXMAX; i >= 0; i--) -+ { -+ if ((retVal = rtl8367c_getAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) -+ return retVal; -+ -+ if (TRUE == svlanMC2SConf.valid) -+ { -+ if (svlanMC2SConf.format == SVLAN_MC2S_MODE_IP && -+ svlanMC2SConf.sdata==ipmc&& -+ svlanMC2SConf.smask==ipmcMsk) -+ { -+ svlanMC2SConf.svidx = svidx; -+ if ((retVal = rtl8367c_setAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ else -+ { -+ empty_idx = i; -+ } -+ } -+ -+ if (empty_idx!=0xFFFF) -+ { -+ svlanMC2SConf.valid = TRUE; -+ svlanMC2SConf.svidx = svidx; -+ svlanMC2SConf.format = SVLAN_MC2S_MODE_IP; -+ svlanMC2SConf.sdata = ipmc; -+ svlanMC2SConf.smask = ipmcMsk; -+ if ((retVal = rtl8367c_setAsicSvlanMC2SConf(empty_idx, &svlanMC2SConf)) != RT_ERR_OK) -+ return retVal; -+ return RT_ERR_OK; -+ } -+ -+ return RT_ERR_OUT_OF_RANGE; -+ -+} -+ -+/* Function Name: -+ * rtk_svlan_ipmc2s_del -+ * Description: -+ * delete ip multicast address to SVLAN -+ * Input: -+ * ipmc - ip multicast address -+ * ipmcMsk - ip multicast mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * Note: -+ * The API can delete IP multicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. -+ */ -+rtk_api_ret_t rtk_svlan_ipmc2s_del(ipaddr_t ipmc, ipaddr_t ipmcMsk) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 i; -+ rtl8367c_svlan_mc2s_t svlanMC2SConf; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if ((ipmc&0xF0000000)!=0xE0000000) -+ return RT_ERR_INPUT; -+ -+ for (i = 0; i <= RTL8367C_MC2SIDXMAX; i++) -+ { -+ if ((retVal = rtl8367c_getAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) -+ return retVal; -+ -+ if (TRUE == svlanMC2SConf.valid) -+ { -+ if (svlanMC2SConf.format == SVLAN_MC2S_MODE_IP && -+ svlanMC2SConf.sdata==ipmc&& -+ svlanMC2SConf.smask==ipmcMsk) -+ { -+ memset(&svlanMC2SConf, 0, sizeof(rtl8367c_svlan_mc2s_t)); -+ if ((retVal = rtl8367c_setAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) -+ return retVal; -+ return RT_ERR_OK; -+ } -+ } -+ } -+ -+ return RT_ERR_OUT_OF_RANGE; -+} -+ -+/* Function Name: -+ * rtk_svlan_ipmc2s_get -+ * Description: -+ * Get ip multicast address to SVLAN -+ * Input: -+ * ipmc - ip multicast address -+ * ipmcMsk - ip multicast mask -+ * Output: -+ * pSvid - SVLAN VID -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * Note: -+ * The API can get IP multicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. -+ */ -+rtk_api_ret_t rtk_svlan_ipmc2s_get(ipaddr_t ipmc, ipaddr_t ipmcMsk, rtk_vlan_t *pSvid) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 i; -+ rtl8367c_svlan_memconf_t svlanMemConf; -+ rtl8367c_svlan_mc2s_t svlanMC2SConf; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pSvid) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((ipmc&0xF0000000)!=0xE0000000) -+ return RT_ERR_INPUT; -+ -+ for (i = 0; i <= RTL8367C_MC2SIDXMAX; i++) -+ { -+ if ((retVal = rtl8367c_getAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) -+ return retVal; -+ -+ if (TRUE == svlanMC2SConf.valid && -+ svlanMC2SConf.format == SVLAN_MC2S_MODE_IP && -+ svlanMC2SConf.sdata == ipmc && -+ svlanMC2SConf.smask == ipmcMsk) -+ { -+ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(svlanMC2SConf.svidx, &svlanMemConf)) != RT_ERR_OK) -+ return retVal; -+ *pSvid = svlanMemConf.vs_svid; -+ return RT_ERR_OK; -+ } -+ } -+ -+ return RT_ERR_OUT_OF_RANGE; -+} -+ -+/* Function Name: -+ * rtk_svlan_l2mc2s_add -+ * Description: -+ * Add L2 multicast address to SVLAN -+ * Input: -+ * mac - L2 multicast address -+ * macMsk - L2 multicast address mask -+ * svid - SVLAN VID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can set L2 Multicast to SVID configuration. If upstream packet is L2 multicast -+ * packet and DMAC is matched, ASIC will assign egress SVID to the packet. There are 32 -+ * SVLAN multicast configurations for IP and L2 multicast. -+ */ -+rtk_api_ret_t rtk_svlan_l2mc2s_add(rtk_mac_t mac, rtk_mac_t macMsk, rtk_vlan_t svid) -+{ -+ rtk_api_ret_t retVal, i; -+ rtk_uint32 empty_idx; -+ rtk_uint32 svidx, l2add, l2Mask; -+ rtl8367c_svlan_memconf_t svlanMemConf; -+ rtl8367c_svlan_mc2s_t svlanMC2SConf; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (svid > RTL8367C_VIDMAX) -+ return RT_ERR_SVLAN_VID; -+ -+ if (mac.octet[0]!= 1&&mac.octet[1]!=0) -+ return RT_ERR_INPUT; -+ -+ l2add = (mac.octet[2] << 24) | (mac.octet[3] << 16) | (mac.octet[4] << 8) | mac.octet[5]; -+ l2Mask = (macMsk.octet[2] << 24) | (macMsk.octet[3] << 16) | (macMsk.octet[4] << 8) | macMsk.octet[5]; -+ -+ svidx = 0xFFFF; -+ -+ for (i = 0; i < RTL8367C_SVIDXNO; i++) -+ { -+ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) -+ return retVal; -+ -+ if (svid == svlanMemConf.vs_svid) -+ { -+ svidx = i; -+ break; -+ } -+ } -+ -+ if (0xFFFF == svidx) -+ return RT_ERR_SVLAN_ENTRY_NOT_FOUND; -+ -+ empty_idx = 0xFFFF; -+ -+ for (i = RTL8367C_MC2SIDXMAX; i >=0; i--) -+ { -+ if ((retVal = rtl8367c_getAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) -+ return retVal; -+ -+ if (TRUE == svlanMC2SConf.valid) -+ { -+ if (svlanMC2SConf.format == SVLAN_MC2S_MODE_MAC && -+ svlanMC2SConf.sdata==l2add&& -+ svlanMC2SConf.smask==l2Mask) -+ { -+ svlanMC2SConf.svidx = svidx; -+ if ((retVal = rtl8367c_setAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ else -+ { -+ empty_idx = i; -+ } -+ } -+ -+ if (empty_idx!=0xFFFF) -+ { -+ svlanMC2SConf.valid = TRUE; -+ svlanMC2SConf.svidx = svidx; -+ svlanMC2SConf.format = SVLAN_MC2S_MODE_MAC; -+ svlanMC2SConf.sdata = l2add; -+ svlanMC2SConf.smask = l2Mask; -+ -+ if ((retVal = rtl8367c_setAsicSvlanMC2SConf(empty_idx, &svlanMC2SConf)) != RT_ERR_OK) -+ return retVal; -+ return RT_ERR_OK; -+ } -+ -+ return RT_ERR_OUT_OF_RANGE; -+} -+ -+/* Function Name: -+ * rtk_svlan_l2mc2s_del -+ * Description: -+ * delete L2 multicast address to SVLAN -+ * Input: -+ * mac - L2 multicast address -+ * macMsk - L2 multicast address mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * Note: -+ * The API can delete Multicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. -+ */ -+rtk_api_ret_t rtk_svlan_l2mc2s_del(rtk_mac_t mac, rtk_mac_t macMsk) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 i; -+ rtk_uint32 l2add, l2Mask; -+ rtl8367c_svlan_mc2s_t svlanMC2SConf; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (mac.octet[0]!= 1&&mac.octet[1]!=0) -+ return RT_ERR_INPUT; -+ -+ l2add = (mac.octet[2] << 24) | (mac.octet[3] << 16) | (mac.octet[4] << 8) | mac.octet[5]; -+ l2Mask = (macMsk.octet[2] << 24) | (macMsk.octet[3] << 16) | (macMsk.octet[4] << 8) | macMsk.octet[5]; -+ -+ for (i = 0; i <= RTL8367C_MC2SIDXMAX; i++) -+ { -+ if ((retVal = rtl8367c_getAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) -+ return retVal; -+ -+ if (TRUE == svlanMC2SConf.valid) -+ { -+ if (svlanMC2SConf.format == SVLAN_MC2S_MODE_MAC && -+ svlanMC2SConf.sdata==l2add&& -+ svlanMC2SConf.smask==l2Mask) -+ { -+ memset(&svlanMC2SConf, 0, sizeof(rtl8367c_svlan_mc2s_t)); -+ if ((retVal = rtl8367c_setAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) -+ return retVal; -+ return RT_ERR_OK; -+ } -+ } -+ } -+ -+ return RT_ERR_OUT_OF_RANGE; -+} -+ -+/* Function Name: -+ * rtk_svlan_l2mc2s_get -+ * Description: -+ * Get L2 multicast address to SVLAN -+ * Input: -+ * mac - L2 multicast address -+ * macMsk - L2 multicast address mask -+ * Output: -+ * pSvid - SVLAN VID -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * Note: -+ * The API can get L2 multicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. -+ */ -+rtk_api_ret_t rtk_svlan_l2mc2s_get(rtk_mac_t mac, rtk_mac_t macMsk, rtk_vlan_t *pSvid) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 i; -+ rtk_uint32 l2add,l2Mask; -+ rtl8367c_svlan_memconf_t svlanMemConf; -+ rtl8367c_svlan_mc2s_t svlanMC2SConf; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pSvid) -+ return RT_ERR_NULL_POINTER; -+ -+ if (mac.octet[0]!= 1&&mac.octet[1]!=0) -+ return RT_ERR_INPUT; -+ -+ l2add = (mac.octet[2] << 24) | (mac.octet[3] << 16) | (mac.octet[4] << 8) | mac.octet[5]; -+ l2Mask = (macMsk.octet[2] << 24) | (macMsk.octet[3] << 16) | (macMsk.octet[4] << 8) | macMsk.octet[5]; -+ -+ for (i = 0; i <= RTL8367C_MC2SIDXMAX; i++) -+ { -+ if ((retVal = rtl8367c_getAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) -+ return retVal; -+ -+ if (TRUE == svlanMC2SConf.valid) -+ { -+ if (svlanMC2SConf.format == SVLAN_MC2S_MODE_MAC && -+ svlanMC2SConf.sdata==l2add&& -+ svlanMC2SConf.smask==l2Mask) -+ { -+ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(svlanMC2SConf.svidx, &svlanMemConf)) != RT_ERR_OK) -+ return retVal; -+ *pSvid = svlanMemConf.vs_svid; -+ -+ return RT_ERR_OK; -+ } -+ } -+ } -+ -+ return RT_ERR_OUT_OF_RANGE; -+} -+ -+/* Function Name: -+ * rtk_svlan_sp2c_add -+ * Description: -+ * Add system SP2C configuration -+ * Input: -+ * cvid - VLAN ID -+ * dst_port - Destination port of SVLAN to CVLAN configuration -+ * svid - SVLAN VID -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_VLAN_VID - Invalid VID parameter. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * The API can add SVID & Destination Port to CVLAN configuration. The downstream frames with assigned -+ * SVID will be add C-tag with assigned CVID if the output port is the assigned destination port. -+ * There are 128 SP2C configurations. -+ */ -+rtk_api_ret_t rtk_svlan_sp2c_add(rtk_vlan_t svid, rtk_port_t dst_port, rtk_vlan_t cvid) -+{ -+ rtk_api_ret_t retVal, i; -+ rtk_uint32 empty_idx, svidx; -+ rtl8367c_svlan_memconf_t svlanMemConf; -+ rtl8367c_svlan_s2c_t svlanSP2CConf; -+ rtk_port_t port; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (svid > RTL8367C_VIDMAX) -+ return RT_ERR_SVLAN_VID; -+ -+ if (cvid > RTL8367C_VIDMAX) -+ return RT_ERR_VLAN_VID; -+ -+ /* Check port Valid */ -+ RTK_CHK_PORT_VALID(dst_port); -+ port = rtk_switch_port_L2P_get(dst_port); -+ -+ svidx = 0xFFFF; -+ -+ for (i = 0; i < RTL8367C_SVIDXNO; i++) -+ { -+ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) -+ return retVal; -+ -+ if (svid == svlanMemConf.vs_svid) -+ { -+ svidx = i; -+ break; -+ } -+ } -+ -+ if (0xFFFF == svidx) -+ return RT_ERR_SVLAN_ENTRY_NOT_FOUND; -+ -+ empty_idx = 0xFFFF; -+ -+ for (i=RTL8367C_SP2CMAX; i >=0 ; i--) -+ { -+ if ((retVal = rtl8367c_getAsicSvlanSP2CConf(i, &svlanSP2CConf)) != RT_ERR_OK) -+ return retVal; -+ -+ if ( (svlanSP2CConf.svidx == svidx) && (svlanSP2CConf.dstport == port) && (svlanSP2CConf.valid == 1)) -+ { -+ empty_idx = i; -+ break; -+ } -+ else if (svlanSP2CConf.valid == 0) -+ { -+ empty_idx = i; -+ } -+ } -+ -+ if (empty_idx!=0xFFFF) -+ { -+ svlanSP2CConf.valid = 1; -+ svlanSP2CConf.vid = cvid; -+ svlanSP2CConf.svidx = svidx; -+ svlanSP2CConf.dstport = port; -+ -+ if ((retVal = rtl8367c_setAsicSvlanSP2CConf(empty_idx, &svlanSP2CConf)) != RT_ERR_OK) -+ return retVal; -+ return RT_ERR_OK; -+ } -+ -+ return RT_ERR_OUT_OF_RANGE; -+ -+} -+ -+/* Function Name: -+ * rtk_svlan_sp2c_get -+ * Description: -+ * Get configure system SP2C content -+ * Input: -+ * svid - SVLAN VID -+ * dst_port - Destination port of SVLAN to CVLAN configuration -+ * Output: -+ * pCvid - VLAN ID -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * Note: -+ * The API can get SVID & Destination Port to CVLAN configuration. There are 128 SP2C configurations. -+ */ -+rtk_api_ret_t rtk_svlan_sp2c_get(rtk_vlan_t svid, rtk_port_t dst_port, rtk_vlan_t *pCvid) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 i, svidx; -+ rtl8367c_svlan_memconf_t svlanMemConf; -+ rtl8367c_svlan_s2c_t svlanSP2CConf; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pCvid) -+ return RT_ERR_NULL_POINTER; -+ -+ if (svid > RTL8367C_VIDMAX) -+ return RT_ERR_SVLAN_VID; -+ -+ /* Check port Valid */ -+ RTK_CHK_PORT_VALID(dst_port); -+ dst_port = rtk_switch_port_L2P_get(dst_port); -+ -+ svidx = 0xFFFF; -+ -+ for (i = 0; i < RTL8367C_SVIDXNO; i++) -+ { -+ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) -+ return retVal; -+ -+ if (svid == svlanMemConf.vs_svid) -+ { -+ svidx = i; -+ break; -+ } -+ } -+ -+ if (0xFFFF == svidx) -+ return RT_ERR_SVLAN_ENTRY_NOT_FOUND; -+ -+ for (i = 0; i <= RTL8367C_SP2CMAX; i++) -+ { -+ if ((retVal = rtl8367c_getAsicSvlanSP2CConf(i, &svlanSP2CConf)) != RT_ERR_OK) -+ return retVal; -+ -+ if ( (svlanSP2CConf.svidx == svidx) && (svlanSP2CConf.dstport == dst_port) && (svlanSP2CConf.valid == 1) ) -+ { -+ *pCvid = svlanSP2CConf.vid; -+ return RT_ERR_OK; -+ } -+ } -+ -+ return RT_ERR_OUT_OF_RANGE; -+} -+ -+/* Function Name: -+ * rtk_svlan_sp2c_del -+ * Description: -+ * Delete system SP2C configuration -+ * Input: -+ * svid - SVLAN VID -+ * dst_port - Destination port of SVLAN to CVLAN configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * Note: -+ * The API can delete SVID & Destination Port to CVLAN configuration. There are 128 SP2C configurations. -+ */ -+rtk_api_ret_t rtk_svlan_sp2c_del(rtk_vlan_t svid, rtk_port_t dst_port) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 i, svidx; -+ rtl8367c_svlan_memconf_t svlanMemConf; -+ rtl8367c_svlan_s2c_t svlanSP2CConf; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (svid > RTL8367C_VIDMAX) -+ return RT_ERR_SVLAN_VID; -+ -+ /* Check port Valid */ -+ RTK_CHK_PORT_VALID(dst_port); -+ dst_port = rtk_switch_port_L2P_get(dst_port); -+ -+ svidx = 0xFFFF; -+ -+ for (i = 0; i < RTL8367C_SVIDXNO; i++) -+ { -+ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) -+ return retVal; -+ -+ if (svid == svlanMemConf.vs_svid) -+ { -+ svidx = i; -+ break; -+ } -+ } -+ -+ if (0xFFFF == svidx) -+ return RT_ERR_SVLAN_ENTRY_NOT_FOUND; -+ -+ for (i = 0; i <= RTL8367C_SP2CMAX; i++) -+ { -+ if ((retVal = rtl8367c_getAsicSvlanSP2CConf(i, &svlanSP2CConf)) != RT_ERR_OK) -+ return retVal; -+ -+ if ( (svlanSP2CConf.svidx == svidx) && (svlanSP2CConf.dstport == dst_port) && (svlanSP2CConf.valid == 1) ) -+ { -+ svlanSP2CConf.valid = 0; -+ svlanSP2CConf.vid = 0; -+ svlanSP2CConf.svidx = 0; -+ svlanSP2CConf.dstport = 0; -+ -+ if ((retVal = rtl8367c_setAsicSvlanSP2CConf(i, &svlanSP2CConf)) != RT_ERR_OK) -+ return retVal; -+ return RT_ERR_OK; -+ } -+ -+ } -+ -+ return RT_ERR_OUT_OF_RANGE; -+} -+ -+/* Function Name: -+ * rtk_svlan_lookupType_set -+ * Description: -+ * Set lookup type of SVLAN -+ * Input: -+ * type - lookup type -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * Note: -+ * none -+ */ -+rtk_api_ret_t rtk_svlan_lookupType_set(rtk_svlan_lookupType_t type) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (type >= SVLAN_LOOKUP_END) -+ return RT_ERR_CHIP_NOT_SUPPORTED; -+ -+ -+ svlan_lookupType = type; -+ -+ retVal = rtl8367c_setAsicSvlanLookupType((rtk_uint32)type); -+ -+ return retVal; -+} -+ -+/* Function Name: -+ * rtk_svlan_lookupType_get -+ * Description: -+ * Get lookup type of SVLAN -+ * Input: -+ * pType - lookup type -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * Note: -+ * none -+ */ -+rtk_api_ret_t rtk_svlan_lookupType_get(rtk_svlan_lookupType_t *pType) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pType) -+ return RT_ERR_NULL_POINTER; -+ -+ retVal = rtl8367c_getAsicSvlanLookupType(pType); -+ -+ svlan_lookupType = *pType; -+ -+ return retVal; -+} -+ -+/* Function Name: -+ * rtk_svlan_trapPri_set -+ * Description: -+ * Set svlan trap priority -+ * Input: -+ * priority - priority for trap packets -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_QOS_INT_PRIORITY -+ * Note: -+ * None -+ */ -+rtk_api_ret_t rtk_svlan_trapPri_set(rtk_pri_t priority) -+{ -+ rtk_api_ret_t retVal; -+ -+ RTK_CHK_INIT_STATE(); -+ -+ if(priority > RTL8367C_PRIMAX) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ retVal = rtl8367c_setAsicSvlanTrapPriority(priority); -+ -+ return retVal; -+} /* end of rtk_svlan_trapPri_set */ -+ -+/* Function Name: -+ * rtk_svlan_trapPri_get -+ * Description: -+ * Get svlan trap priority -+ * Input: -+ * None -+ * Output: -+ * pPriority - priority for trap packets -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ * Note: -+ * None -+ */ -+rtk_api_ret_t rtk_svlan_trapPri_get(rtk_pri_t *pPriority) -+{ -+ rtk_api_ret_t retVal; -+ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pPriority) -+ return RT_ERR_NULL_POINTER; -+ -+ retVal = rtl8367c_getAsicSvlanTrapPriority(pPriority); -+ -+ return retVal; -+} /* end of rtk_svlan_trapPri_get */ -+ -+ -+/* Function Name: -+ * rtk_svlan_checkAndCreateMbr -+ * Description: -+ * Check and create Member configuration and return index -+ * Input: -+ * vid - VLAN id. -+ * Output: -+ * pIndex - Member configuration index -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_VLAN_VID - Invalid VLAN ID. -+ * RT_ERR_TBL_FULL - Member Configuration table full -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_svlan_checkAndCreateMbr(rtk_vlan_t vid, rtk_uint32 *pIndex) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 svidx; -+ rtk_uint32 empty_idx = 0xFFFF; -+ rtl8367c_svlan_memconf_t svlan_cfg; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* vid must be 0~4095 */ -+ if (vid > RTL8367C_VIDMAX) -+ return RT_ERR_VLAN_VID; -+ -+ /* Null pointer check */ -+ if(NULL == pIndex) -+ return RT_ERR_NULL_POINTER; -+ -+ /* Search exist entry */ -+ for (svidx = 0; svidx <= RTL8367C_SVIDXMAX; svidx++) -+ { -+ if(svlan_mbrCfgUsage[svidx] == TRUE) -+ { -+ if(svlan_mbrCfgVid[svidx] == vid) -+ { -+ /* Found! return index */ -+ *pIndex = svidx; -+ return RT_ERR_OK; -+ } -+ } -+ else if(empty_idx == 0xFFFF) -+ { -+ empty_idx = svidx; -+ } -+ -+ } -+ -+ if(empty_idx == 0xFFFF) -+ { -+ /* No empty index */ -+ return RT_ERR_TBL_FULL; -+ } -+ -+ svlan_mbrCfgUsage[empty_idx] = TRUE; -+ svlan_mbrCfgVid[empty_idx] = vid; -+ -+ memset(&svlan_cfg, 0, sizeof(rtl8367c_svlan_memconf_t)); -+ -+ svlan_cfg.vs_svid = vid; -+ /*for create check*/ -+ if(vid == 0) -+ { -+ svlan_cfg.vs_efid = 1; -+ } -+ -+ if((retVal = rtl8367c_setAsicSvlanMemberConfiguration(empty_idx, &svlan_cfg)) != RT_ERR_OK) -+ return retVal; -+ -+ *pIndex = empty_idx; -+ return RT_ERR_OK; -+} -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/trap.c b/drivers/net/phy/rtk/rtl8367c/trap.c -new file mode 100644 -index 000000000000..af9661058b27 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/trap.c -@@ -0,0 +1,1229 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTK switch high-level API for RTL8367/RTL8367C -+ * Feature : Here is a list of all functions and variables in Trap module. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Function Name: -+ * rtk_trap_unknownUnicastPktAction_set -+ * Description: -+ * Set unknown unicast packet action configuration. -+ * Input: -+ * port - ingress port ID for unknown unicast packet -+ * ucast_action - Unknown unicast action. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NOT_ALLOWED - Invalid action. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can set unknown unicast packet action configuration. -+ * The unknown unicast action is as following: -+ * - UCAST_ACTION_FORWARD_PMASK -+ * - UCAST_ACTION_DROP -+ * - UCAST_ACTION_TRAP2CPU -+ * - UCAST_ACTION_FLOODING -+ */ -+rtk_api_ret_t rtk_trap_unknownUnicastPktAction_set(rtk_port_t port, rtk_trap_ucast_action_t ucast_action) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* check port valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (ucast_action >= UCAST_ACTION_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicPortUnknownDaBehavior(rtk_switch_port_L2P_get(port), ucast_action)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_trap_unknownUnicastPktAction_get -+ * Description: -+ * Get unknown unicast packet action configuration. -+ * Input: -+ * port - ingress port ID for unknown unicast packet -+ * Output: -+ * pUcast_action - Unknown unicast action. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NOT_ALLOWED - Invalid action. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * This API can get unknown unicast packet action configuration. -+ * The unknown unicast action is as following: -+ * - UCAST_ACTION_FORWARD_PMASK -+ * - UCAST_ACTION_DROP -+ * - UCAST_ACTION_TRAP2CPU -+ * - UCAST_ACTION_FLOODING -+ */ -+rtk_api_ret_t rtk_trap_unknownUnicastPktAction_get(rtk_port_t port, rtk_trap_ucast_action_t *pUcast_action) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* check port valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (NULL == pUcast_action) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicPortUnknownDaBehavior(rtk_switch_port_L2P_get(port), pUcast_action)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_trap_unknownMacPktAction_set -+ * Description: -+ * Set unknown source MAC packet action configuration. -+ * Input: -+ * ucast_action - Unknown source MAC action. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NOT_ALLOWED - Invalid action. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can set unknown unicast packet action configuration. -+ * The unknown unicast action is as following: -+ * - UCAST_ACTION_FORWARD_PMASK -+ * - UCAST_ACTION_DROP -+ * - UCAST_ACTION_TRAP2CPU -+ */ -+rtk_api_ret_t rtk_trap_unknownMacPktAction_set(rtk_trap_ucast_action_t ucast_action) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (ucast_action >= UCAST_ACTION_FLOODING) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicPortUnknownSaBehavior(ucast_action)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_trap_unknownMacPktAction_get -+ * Description: -+ * Get unknown source MAC packet action configuration. -+ * Input: -+ * None. -+ * Output: -+ * pUcast_action - Unknown source MAC action. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Null Pointer. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_trap_unknownMacPktAction_get(rtk_trap_ucast_action_t *pUcast_action) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pUcast_action) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicPortUnknownSaBehavior(pUcast_action)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_trap_unmatchMacPktAction_set -+ * Description: -+ * Set unmatch source MAC packet action configuration. -+ * Input: -+ * ucast_action - Unknown source MAC action. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NOT_ALLOWED - Invalid action. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can set unknown unicast packet action configuration. -+ * The unknown unicast action is as following: -+ * - UCAST_ACTION_FORWARD_PMASK -+ * - UCAST_ACTION_DROP -+ * - UCAST_ACTION_TRAP2CPU -+ */ -+rtk_api_ret_t rtk_trap_unmatchMacPktAction_set(rtk_trap_ucast_action_t ucast_action) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (ucast_action >= UCAST_ACTION_FLOODING) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicPortUnmatchedSaBehavior(ucast_action)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_trap_unmatchMacPktAction_get -+ * Description: -+ * Get unmatch source MAC packet action configuration. -+ * Input: -+ * None. -+ * Output: -+ * pUcast_action - Unknown source MAC action. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NOT_ALLOWED - Invalid action. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * This API can set unknown unicast packet action configuration. -+ * The unknown unicast action is as following: -+ * - UCAST_ACTION_FORWARD_PMASK -+ * - UCAST_ACTION_DROP -+ * - UCAST_ACTION_TRAP2CPU -+ */ -+rtk_api_ret_t rtk_trap_unmatchMacPktAction_get(rtk_trap_ucast_action_t *pUcast_action) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pUcast_action) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicPortUnmatchedSaBehavior(pUcast_action)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_trap_unmatchMacMoving_set -+ * Description: -+ * Set unmatch source MAC packet moving state. -+ * Input: -+ * port - Port ID. -+ * enable - ENABLED: allow SA moving, DISABLE: don't allow SA moving. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NOT_ALLOWED - Invalid action. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ */ -+rtk_api_ret_t rtk_trap_unmatchMacMoving_set(rtk_port_t port, rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* check port valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(enable >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicPortUnmatchedSaMoving(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_trap_unmatchMacMoving_get -+ * Description: -+ * Set unmatch source MAC packet moving state. -+ * Input: -+ * port - Port ID. -+ * Output: -+ * pEnable - ENABLED: allow SA moving, DISABLE: don't allow SA moving. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NOT_ALLOWED - Invalid action. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ */ -+rtk_api_ret_t rtk_trap_unmatchMacMoving_get(rtk_port_t port, rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* check port valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(NULL == pEnable) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicPortUnmatchedSaMoving(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_trap_unknownMcastPktAction_set -+ * Description: -+ * Set behavior of unknown multicast -+ * Input: -+ * port - Port id. -+ * type - unknown multicast packet type. -+ * mcast_action - unknown multicast action. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_NOT_ALLOWED - Invalid action. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * When receives an unknown multicast packet, switch may trap, drop or flood this packet -+ * (1) The unknown multicast packet type is as following: -+ * - MCAST_L2 -+ * - MCAST_IPV4 -+ * - MCAST_IPV6 -+ * (2) The unknown multicast action is as following: -+ * - MCAST_ACTION_FORWARD -+ * - MCAST_ACTION_DROP -+ * - MCAST_ACTION_TRAP2CPU -+ */ -+rtk_api_ret_t rtk_trap_unknownMcastPktAction_set(rtk_port_t port, rtk_mcast_type_t type, rtk_trap_mcast_action_t mcast_action) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 rawAction; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (type >= MCAST_END) -+ return RT_ERR_INPUT; -+ -+ if (mcast_action >= MCAST_ACTION_END) -+ return RT_ERR_INPUT; -+ -+ -+ switch (type) -+ { -+ case MCAST_L2: -+ if (MCAST_ACTION_ROUTER_PORT == mcast_action) -+ return RT_ERR_INPUT; -+ else if(MCAST_ACTION_DROP_EX_RMA == mcast_action) -+ rawAction = L2_UNKOWN_MULTICAST_DROP_EXCLUDE_RMA; -+ else -+ rawAction = (rtk_uint32)mcast_action; -+ -+ if ((retVal = rtl8367c_setAsicUnknownL2MulticastBehavior(rtk_switch_port_L2P_get(port), rawAction)) != RT_ERR_OK) -+ return retVal; -+ -+ break; -+ case MCAST_IPV4: -+ if (MCAST_ACTION_DROP_EX_RMA == mcast_action) -+ return RT_ERR_INPUT; -+ else -+ rawAction = (rtk_uint32)mcast_action; -+ -+ if ((retVal = rtl8367c_setAsicUnknownIPv4MulticastBehavior(rtk_switch_port_L2P_get(port), rawAction)) != RT_ERR_OK) -+ return retVal; -+ -+ break; -+ case MCAST_IPV6: -+ if (MCAST_ACTION_DROP_EX_RMA == mcast_action) -+ return RT_ERR_INPUT; -+ else -+ rawAction = (rtk_uint32)mcast_action; -+ -+ if ((retVal = rtl8367c_setAsicUnknownIPv6MulticastBehavior(rtk_switch_port_L2P_get(port), rawAction)) != RT_ERR_OK) -+ return retVal; -+ -+ break; -+ default: -+ break; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_trap_unknownMcastPktAction_get -+ * Description: -+ * Get behavior of unknown multicast -+ * Input: -+ * type - unknown multicast packet type. -+ * Output: -+ * pMcast_action - unknown multicast action. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_NOT_ALLOWED - Invalid operation. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * When receives an unknown multicast packet, switch may trap, drop or flood this packet -+ * (1) The unknown multicast packet type is as following: -+ * - MCAST_L2 -+ * - MCAST_IPV4 -+ * - MCAST_IPV6 -+ * (2) The unknown multicast action is as following: -+ * - MCAST_ACTION_FORWARD -+ * - MCAST_ACTION_DROP -+ * - MCAST_ACTION_TRAP2CPU -+ */ -+rtk_api_ret_t rtk_trap_unknownMcastPktAction_get(rtk_port_t port, rtk_mcast_type_t type, rtk_trap_mcast_action_t *pMcast_action) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 rawAction; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (type >= MCAST_END) -+ return RT_ERR_INPUT; -+ -+ if(NULL == pMcast_action) -+ return RT_ERR_NULL_POINTER; -+ -+ switch (type) -+ { -+ case MCAST_L2: -+ if ((retVal = rtl8367c_getAsicUnknownL2MulticastBehavior(rtk_switch_port_L2P_get(port), &rawAction)) != RT_ERR_OK) -+ return retVal; -+ -+ if(L2_UNKOWN_MULTICAST_DROP_EXCLUDE_RMA == rawAction) -+ *pMcast_action = MCAST_ACTION_DROP_EX_RMA; -+ else -+ *pMcast_action = (rtk_trap_mcast_action_t)rawAction; -+ -+ break; -+ case MCAST_IPV4: -+ if ((retVal = rtl8367c_getAsicUnknownIPv4MulticastBehavior(rtk_switch_port_L2P_get(port), &rawAction)) != RT_ERR_OK) -+ return retVal; -+ -+ *pMcast_action = (rtk_trap_mcast_action_t)rawAction; -+ break; -+ case MCAST_IPV6: -+ if ((retVal = rtl8367c_getAsicUnknownIPv6MulticastBehavior(rtk_switch_port_L2P_get(port), &rawAction)) != RT_ERR_OK) -+ return retVal; -+ -+ *pMcast_action = (rtk_trap_mcast_action_t)rawAction; -+ break; -+ default: -+ break; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_trap_lldpEnable_set -+ * Description: -+ * Set LLDP enable. -+ * Input: -+ * enabled - LLDP enable, 0: follow RMA, 1: use LLDP action. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NOT_ALLOWED - Invalid action. -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * - DMAC Assignment -+ * - 01:80:c2:00:00:0e ethertype = 0x88CC LLDP -+ * - 01:80:c2:00:00:03 ethertype = 0x88CC -+ * - 01:80:c2:00:00:00 ethertype = 0x88CC -+ -+ */ -+rtk_api_ret_t rtk_trap_lldpEnable_set(rtk_enable_t enabled) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_rma_t rmacfg; -+ rtk_enable_t tmp; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (enabled >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ if ((retVal = rtl8367c_getAsicRmaLldp(&tmp, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicRmaLldp(enabled, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_trap_lldpEnable_get -+ * Description: -+ * Get LLDP status. -+ * Input: -+ * None -+ * Output: -+ * pEnabled - LLDP enable, 0: follow RMA, 1: use LLDP action. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * LLDP is as following definition. -+ * - DMAC Assignment -+ * - 01:80:c2:00:00:0e ethertype = 0x88CC LLDP -+ * - 01:80:c2:00:00:03 ethertype = 0x88CC -+ * - 01:80:c2:00:00:00 ethertype = 0x88CC -+ */ -+rtk_api_ret_t rtk_trap_lldpEnable_get(rtk_enable_t *pEnabled) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_rma_t rmacfg; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pEnabled) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicRmaLldp(pEnabled, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_trap_reasonTrapToCpuPriority_set -+ * Description: -+ * Set priority value of a packet that trapped to CPU port according to specific reason. -+ * Input: -+ * type - reason that trap to CPU port. -+ * priority - internal priority that is going to be set for specific trap reason. -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_INPUT - Invalid input parameter -+ * Note: -+ * Currently the trap reason that supported are listed as follows: -+ * - TRAP_REASON_RMA -+ * - TRAP_REASON_OAM -+ * - TRAP_REASON_1XUNAUTH -+ * - TRAP_REASON_VLANSTACK -+ * - TRAP_REASON_UNKNOWNMC -+ */ -+rtk_api_ret_t rtk_trap_reasonTrapToCpuPriority_set(rtk_trap_reason_type_t type, rtk_pri_t priority) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_rma_t rmacfg; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (type >= TRAP_REASON_END) -+ return RT_ERR_INPUT; -+ -+ if (priority > RTL8367C_PRIMAX) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ switch (type) -+ { -+ case TRAP_REASON_RMA: -+ if ((retVal = rtl8367c_getAsicRma(0, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ rmacfg.trap_priority= priority; -+ if ((retVal = rtl8367c_setAsicRma(0, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ break; -+ case TRAP_REASON_OAM: -+ if ((retVal = rtl8367c_setAsicOamCpuPri(priority)) != RT_ERR_OK) -+ return retVal; -+ -+ break; -+ case TRAP_REASON_1XUNAUTH: -+ if ((retVal = rtl8367c_setAsic1xTrapPriority(priority)) != RT_ERR_OK) -+ return retVal; -+ -+ break; -+ case TRAP_REASON_VLANSTACK: -+ if ((retVal = rtl8367c_setAsicSvlanTrapPriority(priority)) != RT_ERR_OK) -+ return retVal; -+ -+ break; -+ case TRAP_REASON_UNKNOWNMC: -+ if ((retVal = rtl8367c_setAsicUnknownMulticastTrapPriority(priority)) != RT_ERR_OK) -+ return retVal; -+ -+ break; -+ default: -+ return RT_ERR_CHIP_NOT_SUPPORTED; -+ } -+ -+ -+ return RT_ERR_OK; -+} -+ -+ -+/* Function Name: -+ * rtk_trap_reasonTrapToCpuPriority_get -+ * Description: -+ * Get priority value of a packet that trapped to CPU port according to specific reason. -+ * Input: -+ * type - reason that trap to CPU port. -+ * Output: -+ * pPriority - configured internal priority for such reason. -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NOT_INIT - The module is not initial -+ * RT_ERR_INPUT - Invalid input parameter -+ * RT_ERR_NULL_POINTER - NULL pointer -+ * Note: -+ * Currently the trap reason that supported are listed as follows: -+ * - TRAP_REASON_RMA -+ * - TRAP_REASON_OAM -+ * - TRAP_REASON_1XUNAUTH -+ * - TRAP_REASON_VLANSTACK -+ * - TRAP_REASON_UNKNOWNMC -+ */ -+rtk_api_ret_t rtk_trap_reasonTrapToCpuPriority_get(rtk_trap_reason_type_t type, rtk_pri_t *pPriority) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_rma_t rmacfg; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (type >= TRAP_REASON_END) -+ return RT_ERR_INPUT; -+ -+ if(NULL == pPriority) -+ return RT_ERR_NULL_POINTER; -+ -+ switch (type) -+ { -+ case TRAP_REASON_RMA: -+ if ((retVal = rtl8367c_getAsicRma(0, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ *pPriority = rmacfg.trap_priority; -+ -+ break; -+ case TRAP_REASON_OAM: -+ if ((retVal = rtl8367c_getAsicOamCpuPri(pPriority)) != RT_ERR_OK) -+ return retVal; -+ -+ break; -+ case TRAP_REASON_1XUNAUTH: -+ if ((retVal = rtl8367c_getAsic1xTrapPriority(pPriority)) != RT_ERR_OK) -+ return retVal; -+ -+ break; -+ case TRAP_REASON_VLANSTACK: -+ if ((retVal = rtl8367c_getAsicSvlanTrapPriority(pPriority)) != RT_ERR_OK) -+ return retVal; -+ -+ break; -+ case TRAP_REASON_UNKNOWNMC: -+ if ((retVal = rtl8367c_getAsicUnknownMulticastTrapPriority(pPriority)) != RT_ERR_OK) -+ return retVal; -+ -+ break; -+ default: -+ return RT_ERR_CHIP_NOT_SUPPORTED; -+ -+ } -+ -+ return RT_ERR_OK; -+} -+ -+ -+ -+/* Function Name: -+ * rtk_trap_rmaAction_set -+ * Description: -+ * Set Reserved multicast address action configuration. -+ * Input: -+ * type - rma type. -+ * rma_action - RMA action. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * -+ * There are 48 types of Reserved Multicast Address frame for application usage. -+ * (1)They are as following definition. -+ * - TRAP_BRG_GROUP, -+ * - TRAP_FD_PAUSE, -+ * - TRAP_SP_MCAST, -+ * - TRAP_1X_PAE, -+ * - TRAP_UNDEF_BRG_04, -+ * - TRAP_UNDEF_BRG_05, -+ * - TRAP_UNDEF_BRG_06, -+ * - TRAP_UNDEF_BRG_07, -+ * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, -+ * - TRAP_UNDEF_BRG_09, -+ * - TRAP_UNDEF_BRG_0A, -+ * - TRAP_UNDEF_BRG_0B, -+ * - TRAP_UNDEF_BRG_0C, -+ * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, -+ * - TRAP_8021AB, -+ * - TRAP_UNDEF_BRG_0F, -+ * - TRAP_BRG_MNGEMENT, -+ * - TRAP_UNDEFINED_11, -+ * - TRAP_UNDEFINED_12, -+ * - TRAP_UNDEFINED_13, -+ * - TRAP_UNDEFINED_14, -+ * - TRAP_UNDEFINED_15, -+ * - TRAP_UNDEFINED_16, -+ * - TRAP_UNDEFINED_17, -+ * - TRAP_UNDEFINED_18, -+ * - TRAP_UNDEFINED_19, -+ * - TRAP_UNDEFINED_1A, -+ * - TRAP_UNDEFINED_1B, -+ * - TRAP_UNDEFINED_1C, -+ * - TRAP_UNDEFINED_1D, -+ * - TRAP_UNDEFINED_1E, -+ * - TRAP_UNDEFINED_1F, -+ * - TRAP_GMRP, -+ * - TRAP_GVRP, -+ * - TRAP_UNDEF_GARP_22, -+ * - TRAP_UNDEF_GARP_23, -+ * - TRAP_UNDEF_GARP_24, -+ * - TRAP_UNDEF_GARP_25, -+ * - TRAP_UNDEF_GARP_26, -+ * - TRAP_UNDEF_GARP_27, -+ * - TRAP_UNDEF_GARP_28, -+ * - TRAP_UNDEF_GARP_29, -+ * - TRAP_UNDEF_GARP_2A, -+ * - TRAP_UNDEF_GARP_2B, -+ * - TRAP_UNDEF_GARP_2C, -+ * - TRAP_UNDEF_GARP_2D, -+ * - TRAP_UNDEF_GARP_2E, -+ * - TRAP_UNDEF_GARP_2F, -+ * - TRAP_CDP. -+ * - TRAP_CSSTP. -+ * - TRAP_LLDP. -+ * (2) The RMA action is as following: -+ * - RMA_ACTION_FORWARD -+ * - RMA_ACTION_TRAP2CPU -+ * - RMA_ACTION_DROP -+ * - RMA_ACTION_FORWARD_EXCLUDE_CPU -+ */ -+rtk_api_ret_t rtk_trap_rmaAction_set(rtk_trap_type_t type, rtk_trap_rma_action_t rma_action) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_rma_t rmacfg; -+ rtk_uint32 tmp; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (type >= TRAP_END) -+ return RT_ERR_INPUT; -+ -+ if (rma_action >= RMA_ACTION_END) -+ return RT_ERR_RMA_ACTION; -+ -+ if (type >= 0 && type <= TRAP_UNDEF_GARP_2F) -+ { -+ if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ rmacfg.operation = rma_action; -+ -+ if ((retVal = rtl8367c_setAsicRma(type, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if (type == TRAP_CDP) -+ { -+ if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ rmacfg.operation = rma_action; -+ -+ if ((retVal = rtl8367c_setAsicRmaCdp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if (type == TRAP_CSSTP) -+ { -+ if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ rmacfg.operation = rma_action; -+ -+ if ((retVal = rtl8367c_setAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if (type == TRAP_LLDP) -+ { -+ if ((retVal = rtl8367c_getAsicRmaLldp(&tmp, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ rmacfg.operation = rma_action; -+ -+ if ((retVal = rtl8367c_setAsicRmaLldp(tmp, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ return RT_ERR_INPUT; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_trap_rmaAction_get -+ * Description: -+ * Get Reserved multicast address action configuration. -+ * Input: -+ * type - rma type. -+ * Output: -+ * pRma_action - RMA action. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * There are 48 types of Reserved Multicast Address frame for application usage. -+ * (1)They are as following definition. -+ * - TRAP_BRG_GROUP, -+ * - TRAP_FD_PAUSE, -+ * - TRAP_SP_MCAST, -+ * - TRAP_1X_PAE, -+ * - TRAP_UNDEF_BRG_04, -+ * - TRAP_UNDEF_BRG_05, -+ * - TRAP_UNDEF_BRG_06, -+ * - TRAP_UNDEF_BRG_07, -+ * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, -+ * - TRAP_UNDEF_BRG_09, -+ * - TRAP_UNDEF_BRG_0A, -+ * - TRAP_UNDEF_BRG_0B, -+ * - TRAP_UNDEF_BRG_0C, -+ * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, -+ * - TRAP_8021AB, -+ * - TRAP_UNDEF_BRG_0F, -+ * - TRAP_BRG_MNGEMENT, -+ * - TRAP_UNDEFINED_11, -+ * - TRAP_UNDEFINED_12, -+ * - TRAP_UNDEFINED_13, -+ * - TRAP_UNDEFINED_14, -+ * - TRAP_UNDEFINED_15, -+ * - TRAP_UNDEFINED_16, -+ * - TRAP_UNDEFINED_17, -+ * - TRAP_UNDEFINED_18, -+ * - TRAP_UNDEFINED_19, -+ * - TRAP_UNDEFINED_1A, -+ * - TRAP_UNDEFINED_1B, -+ * - TRAP_UNDEFINED_1C, -+ * - TRAP_UNDEFINED_1D, -+ * - TRAP_UNDEFINED_1E, -+ * - TRAP_UNDEFINED_1F, -+ * - TRAP_GMRP, -+ * - TRAP_GVRP, -+ * - TRAP_UNDEF_GARP_22, -+ * - TRAP_UNDEF_GARP_23, -+ * - TRAP_UNDEF_GARP_24, -+ * - TRAP_UNDEF_GARP_25, -+ * - TRAP_UNDEF_GARP_26, -+ * - TRAP_UNDEF_GARP_27, -+ * - TRAP_UNDEF_GARP_28, -+ * - TRAP_UNDEF_GARP_29, -+ * - TRAP_UNDEF_GARP_2A, -+ * - TRAP_UNDEF_GARP_2B, -+ * - TRAP_UNDEF_GARP_2C, -+ * - TRAP_UNDEF_GARP_2D, -+ * - TRAP_UNDEF_GARP_2E, -+ * - TRAP_UNDEF_GARP_2F, -+ * - TRAP_CDP. -+ * - TRAP_CSSTP. -+ * - TRAP_LLDP. -+ * (2) The RMA action is as following: -+ * - RMA_ACTION_FORWARD -+ * - RMA_ACTION_TRAP2CPU -+ * - RMA_ACTION_DROP -+ * - RMA_ACTION_FORWARD_EXCLUDE_CPU -+ */ -+rtk_api_ret_t rtk_trap_rmaAction_get(rtk_trap_type_t type, rtk_trap_rma_action_t *pRma_action) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_rma_t rmacfg; -+ rtk_uint32 tmp; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (type >= TRAP_END) -+ return RT_ERR_INPUT; -+ -+ if(NULL == pRma_action) -+ return RT_ERR_NULL_POINTER; -+ -+ if (type >= 0 && type <= TRAP_UNDEF_GARP_2F) -+ { -+ if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ *pRma_action = rmacfg.operation; -+ } -+ else if (type == TRAP_CDP) -+ { -+ if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ *pRma_action = rmacfg.operation; -+ } -+ else if (type == TRAP_CSSTP) -+ { -+ if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ *pRma_action = rmacfg.operation; -+ } -+ else if (type == TRAP_LLDP) -+ { -+ if ((retVal = rtl8367c_getAsicRmaLldp(&tmp,&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ *pRma_action = rmacfg.operation; -+ } -+ else -+ return RT_ERR_INPUT; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_trap_rmaKeepFormat_set -+ * Description: -+ * Set Reserved multicast address keep format configuration. -+ * Input: -+ * type - rma type. -+ * enable - enable keep format. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_ENABLE - Invalid IFG parameter -+ * Note: -+ * -+ * There are 48 types of Reserved Multicast Address frame for application usage. -+ * They are as following definition. -+ * - TRAP_BRG_GROUP, -+ * - TRAP_FD_PAUSE, -+ * - TRAP_SP_MCAST, -+ * - TRAP_1X_PAE, -+ * - TRAP_UNDEF_BRG_04, -+ * - TRAP_UNDEF_BRG_05, -+ * - TRAP_UNDEF_BRG_06, -+ * - TRAP_UNDEF_BRG_07, -+ * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, -+ * - TRAP_UNDEF_BRG_09, -+ * - TRAP_UNDEF_BRG_0A, -+ * - TRAP_UNDEF_BRG_0B, -+ * - TRAP_UNDEF_BRG_0C, -+ * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, -+ * - TRAP_8021AB, -+ * - TRAP_UNDEF_BRG_0F, -+ * - TRAP_BRG_MNGEMENT, -+ * - TRAP_UNDEFINED_11, -+ * - TRAP_UNDEFINED_12, -+ * - TRAP_UNDEFINED_13, -+ * - TRAP_UNDEFINED_14, -+ * - TRAP_UNDEFINED_15, -+ * - TRAP_UNDEFINED_16, -+ * - TRAP_UNDEFINED_17, -+ * - TRAP_UNDEFINED_18, -+ * - TRAP_UNDEFINED_19, -+ * - TRAP_UNDEFINED_1A, -+ * - TRAP_UNDEFINED_1B, -+ * - TRAP_UNDEFINED_1C, -+ * - TRAP_UNDEFINED_1D, -+ * - TRAP_UNDEFINED_1E, -+ * - TRAP_UNDEFINED_1F, -+ * - TRAP_GMRP, -+ * - TRAP_GVRP, -+ * - TRAP_UNDEF_GARP_22, -+ * - TRAP_UNDEF_GARP_23, -+ * - TRAP_UNDEF_GARP_24, -+ * - TRAP_UNDEF_GARP_25, -+ * - TRAP_UNDEF_GARP_26, -+ * - TRAP_UNDEF_GARP_27, -+ * - TRAP_UNDEF_GARP_28, -+ * - TRAP_UNDEF_GARP_29, -+ * - TRAP_UNDEF_GARP_2A, -+ * - TRAP_UNDEF_GARP_2B, -+ * - TRAP_UNDEF_GARP_2C, -+ * - TRAP_UNDEF_GARP_2D, -+ * - TRAP_UNDEF_GARP_2E, -+ * - TRAP_UNDEF_GARP_2F, -+ * - TRAP_CDP. -+ * - TRAP_CSSTP. -+ * - TRAP_LLDP. -+ */ -+rtk_api_ret_t rtk_trap_rmaKeepFormat_set(rtk_trap_type_t type, rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_rma_t rmacfg; -+ rtk_uint32 tmp; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (type >= TRAP_END) -+ return RT_ERR_INPUT; -+ -+ if (enable >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if (type >= 0 && type <= TRAP_UNDEF_GARP_2F) -+ { -+ if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ rmacfg.keep_format = enable; -+ -+ if ((retVal = rtl8367c_setAsicRma(type, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if (type == TRAP_CDP) -+ { -+ if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ rmacfg.keep_format = enable; -+ -+ if ((retVal = rtl8367c_setAsicRmaCdp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if (type == TRAP_CSSTP) -+ { -+ if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ rmacfg.keep_format = enable; -+ -+ if ((retVal = rtl8367c_setAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ } -+ else if (type == TRAP_LLDP) -+ { -+ if ((retVal = rtl8367c_getAsicRmaLldp(&tmp, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ rmacfg.keep_format = enable; -+ -+ if ((retVal = rtl8367c_setAsicRmaLldp(tmp, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ return RT_ERR_INPUT; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_trap_rmaKeepFormat_get -+ * Description: -+ * Get Reserved multicast address action configuration. -+ * Input: -+ * type - rma type. -+ * Output: -+ * pEnable - keep format status. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * Note: -+ * There are 48 types of Reserved Multicast Address frame for application usage. -+ * They are as following definition. -+ * - TRAP_BRG_GROUP, -+ * - TRAP_FD_PAUSE, -+ * - TRAP_SP_MCAST, -+ * - TRAP_1X_PAE, -+ * - TRAP_UNDEF_BRG_04, -+ * - TRAP_UNDEF_BRG_05, -+ * - TRAP_UNDEF_BRG_06, -+ * - TRAP_UNDEF_BRG_07, -+ * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, -+ * - TRAP_UNDEF_BRG_09, -+ * - TRAP_UNDEF_BRG_0A, -+ * - TRAP_UNDEF_BRG_0B, -+ * - TRAP_UNDEF_BRG_0C, -+ * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, -+ * - TRAP_8021AB, -+ * - TRAP_UNDEF_BRG_0F, -+ * - TRAP_BRG_MNGEMENT, -+ * - TRAP_UNDEFINED_11, -+ * - TRAP_UNDEFINED_12, -+ * - TRAP_UNDEFINED_13, -+ * - TRAP_UNDEFINED_14, -+ * - TRAP_UNDEFINED_15, -+ * - TRAP_UNDEFINED_16, -+ * - TRAP_UNDEFINED_17, -+ * - TRAP_UNDEFINED_18, -+ * - TRAP_UNDEFINED_19, -+ * - TRAP_UNDEFINED_1A, -+ * - TRAP_UNDEFINED_1B, -+ * - TRAP_UNDEFINED_1C, -+ * - TRAP_UNDEFINED_1D, -+ * - TRAP_UNDEFINED_1E, -+ * - TRAP_UNDEFINED_1F, -+ * - TRAP_GMRP, -+ * - TRAP_GVRP, -+ * - TRAP_UNDEF_GARP_22, -+ * - TRAP_UNDEF_GARP_23, -+ * - TRAP_UNDEF_GARP_24, -+ * - TRAP_UNDEF_GARP_25, -+ * - TRAP_UNDEF_GARP_26, -+ * - TRAP_UNDEF_GARP_27, -+ * - TRAP_UNDEF_GARP_28, -+ * - TRAP_UNDEF_GARP_29, -+ * - TRAP_UNDEF_GARP_2A, -+ * - TRAP_UNDEF_GARP_2B, -+ * - TRAP_UNDEF_GARP_2C, -+ * - TRAP_UNDEF_GARP_2D, -+ * - TRAP_UNDEF_GARP_2E, -+ * - TRAP_UNDEF_GARP_2F, -+ * - TRAP_CDP. -+ * - TRAP_CSSTP. -+ * - TRAP_LLDP. -+ */ -+rtk_api_ret_t rtk_trap_rmaKeepFormat_get(rtk_trap_type_t type, rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_rma_t rmacfg; -+ rtk_uint32 tmp; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (type >= TRAP_END) -+ return RT_ERR_INPUT; -+ -+ if(NULL == pEnable) -+ return RT_ERR_NULL_POINTER; -+ -+ if (type >= 0 && type <= TRAP_UNDEF_GARP_2F) -+ { -+ if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ *pEnable = rmacfg.keep_format; -+ } -+ else if (type == TRAP_CDP) -+ { -+ if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ *pEnable = rmacfg.keep_format; -+ } -+ else if (type == TRAP_CSSTP) -+ { -+ if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ *pEnable = rmacfg.keep_format; -+ } -+ else if (type == TRAP_LLDP) -+ { -+ if ((retVal = rtl8367c_getAsicRmaLldp(&tmp,&rmacfg)) != RT_ERR_OK) -+ return retVal; -+ -+ *pEnable = rmacfg.keep_format; -+ } -+ else -+ return RT_ERR_INPUT; -+ -+ return RT_ERR_OK; -+} -+ -+ -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/trunk.c b/drivers/net/phy/rtk/rtl8367c/trunk.c -new file mode 100644 -index 000000000000..8a88dc5ff000 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/trunk.c -@@ -0,0 +1,605 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTK switch high-level API for RTL8367/RTL8367C -+ * Feature : Here is a list of all functions and variables in Trunk module. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+/* Function Name: -+ * rtk_trunk_port_set -+ * Description: -+ * Set trunking group available port mask -+ * Input: -+ * trk_gid - trunk group id -+ * pTrunk_member_portmask - Logic trunking member port mask -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_LA_TRUNK_ID - Invalid trunking group -+ * RT_ERR_PORT_MASK - Invalid portmask. -+ * Note: -+ * The API can set port trunking group port mask. Each port trunking group has max 4 ports. -+ * If enabled port mask has less than 2 ports available setting, then this trunking group function is disabled. -+ */ -+rtk_api_ret_t rtk_trunk_port_set(rtk_trunk_group_t trk_gid, rtk_portmask_t *pTrunk_member_portmask) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pmsk; -+ rtk_uint32 regValue, type, tmp; -+ -+ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) -+ return retVal; -+ -+ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) -+ return retVal; -+ -+ switch (regValue) -+ { -+ case 0x0276: -+ case 0x0597: -+ case 0x6367: -+ type = 0; -+ break; -+ case 0x0652: -+ case 0x6368: -+ type = 1; -+ break; -+ case 0x0801: -+ case 0x6511: -+ type = 2; -+ break; -+ default: -+ return RT_ERR_FAILED; -+ } -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Trunk Group Valid */ -+ RTK_CHK_TRUNK_GROUP_VALID(trk_gid); -+ -+ if(NULL == pTrunk_member_portmask) -+ return RT_ERR_NULL_POINTER; -+ -+ RTK_CHK_PORTMASK_VALID(pTrunk_member_portmask); -+ -+ if((retVal = rtk_switch_portmask_L2P_get(pTrunk_member_portmask, &pmsk)) != RT_ERR_OK) -+ return retVal; -+ -+ if((type == 0) || (type == 1)) -+ { -+ if ((pmsk | RTL8367C_PORT_TRUNK_GROUP_MASK_MASK(trk_gid)) != (rtk_uint32)RTL8367C_PORT_TRUNK_GROUP_MASK_MASK(trk_gid)) -+ return RT_ERR_PORT_MASK; -+ -+ pmsk = (pmsk & RTL8367C_PORT_TRUNK_GROUP_MASK_MASK(trk_gid)) >> RTL8367C_PORT_TRUNK_GROUP_MASK_OFFSET(trk_gid); -+ } -+ else if(type == 2) -+ { -+ tmp = 0; -+ -+ if(pmsk & 0x2) -+ tmp |= 1; -+ if(pmsk & 0x8) -+ tmp |=2; -+ if(pmsk & 0x80) -+ tmp |=8; -+ -+ pmsk = tmp; -+ } -+ -+ if ((retVal = rtl8367c_setAsicTrunkingGroup(trk_gid, pmsk)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_trunk_port_get -+ * Description: -+ * Get trunking group available port mask -+ * Input: -+ * trk_gid - trunk group id -+ * Output: -+ * pTrunk_member_portmask - Logic trunking member port mask -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_LA_TRUNK_ID - Invalid trunking group -+ * Note: -+ * The API can get 2 port trunking group. -+ */ -+rtk_api_ret_t rtk_trunk_port_get(rtk_trunk_group_t trk_gid, rtk_portmask_t *pTrunk_member_portmask) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pmsk; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Trunk Group Valid */ -+ RTK_CHK_TRUNK_GROUP_VALID(trk_gid); -+ -+ if ((retVal = rtl8367c_getAsicTrunkingGroup(trk_gid, &pmsk)) != RT_ERR_OK) -+ return retVal; -+ -+ pmsk = pmsk << RTL8367C_PORT_TRUNK_GROUP_MASK_OFFSET(trk_gid); -+ -+ if((retVal = rtk_switch_portmask_P2L_get(pmsk, pTrunk_member_portmask)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_trunk_distributionAlgorithm_set -+ * Description: -+ * Set port trunking hash select sources -+ * Input: -+ * trk_gid - trunk group id -+ * algo_bitmask - Bitmask of the distribution algorithm -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_LA_TRUNK_ID - Invalid trunking group -+ * RT_ERR_LA_HASHMASK - Hash algorithm selection error. -+ * RT_ERR_PORT_MASK - Invalid portmask. -+ * Note: -+ * The API can set port trunking hash algorithm sources. -+ * 7 bits mask for link aggregation group0 hash parameter selection {DIP, SIP, DMAC, SMAC, SPA} -+ * - 0b0000001: SPA -+ * - 0b0000010: SMAC -+ * - 0b0000100: DMAC -+ * - 0b0001000: SIP -+ * - 0b0010000: DIP -+ * - 0b0100000: TCP/UDP Source Port -+ * - 0b1000000: TCP/UDP Destination Port -+ * Example: -+ * - 0b0000011: SMAC & SPA -+ * - Note that it could be an arbitrary combination or independent set -+ */ -+rtk_api_ret_t rtk_trunk_distributionAlgorithm_set(rtk_trunk_group_t trk_gid, rtk_uint32 algo_bitmask) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (trk_gid != RTK_WHOLE_SYSTEM) -+ return RT_ERR_LA_TRUNK_ID; -+ -+ if (algo_bitmask >= 128) -+ return RT_ERR_LA_HASHMASK; -+ -+ if ((retVal = rtl8367c_setAsicTrunkingHashSelect(algo_bitmask)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_trunk_distributionAlgorithm_get -+ * Description: -+ * Get port trunking hash select sources -+ * Input: -+ * trk_gid - trunk group id -+ * Output: -+ * pAlgo_bitmask - Bitmask of the distribution algorithm -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_LA_TRUNK_ID - Invalid trunking group -+ * Note: -+ * The API can get port trunking hash algorithm sources. -+ */ -+rtk_api_ret_t rtk_trunk_distributionAlgorithm_get(rtk_trunk_group_t trk_gid, rtk_uint32 *pAlgo_bitmask) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (trk_gid != RTK_WHOLE_SYSTEM) -+ return RT_ERR_LA_TRUNK_ID; -+ -+ if(NULL == pAlgo_bitmask) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicTrunkingHashSelect((rtk_uint32 *)pAlgo_bitmask)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_trunk_trafficSeparate_set -+ * Description: -+ * Set the traffic separation setting of a trunk group from the specified device. -+ * Input: -+ * trk_gid - trunk group id -+ * separateType - traffic separation setting -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_UNIT_ID - invalid unit id -+ * RT_ERR_LA_TRUNK_ID - invalid trunk ID -+ * RT_ERR_LA_HASHMASK - invalid hash mask -+ * Note: -+ * SEPARATE_NONE: disable traffic separation -+ * SEPARATE_FLOOD: trunk MSB link up port is dedicated to TX flooding (L2 lookup miss) traffic -+ */ -+rtk_api_ret_t rtk_trunk_trafficSeparate_set(rtk_trunk_group_t trk_gid, rtk_trunk_separateType_t separateType) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 enabled; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (trk_gid != RTK_WHOLE_SYSTEM) -+ return RT_ERR_LA_TRUNK_ID; -+ -+ if(separateType >= SEPARATE_END) -+ return RT_ERR_INPUT; -+ -+ enabled = (separateType == SEPARATE_FLOOD) ? ENABLED : DISABLED; -+ if ((retVal = rtl8367c_setAsicTrunkingFlood(enabled)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_trunk_trafficSeparate_get -+ * Description: -+ * Get the traffic separation setting of a trunk group from the specified device. -+ * Input: -+ * trk_gid - trunk group id -+ * Output: -+ * pSeparateType - pointer separated traffic type -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_UNIT_ID - invalid unit id -+ * RT_ERR_LA_TRUNK_ID - invalid trunk ID -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ * Note: -+ * SEPARATE_NONE: disable traffic separation -+ * SEPARATE_FLOOD: trunk MSB link up port is dedicated to TX flooding (L2 lookup miss) traffic -+ */ -+rtk_api_ret_t rtk_trunk_trafficSeparate_get(rtk_trunk_group_t trk_gid, rtk_trunk_separateType_t *pSeparateType) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 enabled; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if (trk_gid != RTK_WHOLE_SYSTEM) -+ return RT_ERR_LA_TRUNK_ID; -+ -+ if(NULL == pSeparateType) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicTrunkingFlood(&enabled)) != RT_ERR_OK) -+ return retVal; -+ -+ *pSeparateType = (enabled == ENABLED) ? SEPARATE_FLOOD : SEPARATE_NONE; -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_trunk_mode_set -+ * Description: -+ * Set the trunk mode to the specified device. -+ * Input: -+ * mode - trunk mode -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_INPUT - invalid input parameter -+ * Note: -+ * The enum of the trunk mode as following -+ * - TRUNK_MODE_NORMAL -+ * - TRUNK_MODE_DUMB -+ */ -+rtk_api_ret_t rtk_trunk_mode_set(rtk_trunk_mode_t mode) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(mode >= TRUNK_MODE_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicTrunkingMode((rtk_uint32)mode)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_trunk_mode_get -+ * Description: -+ * Get the trunk mode from the specified device. -+ * Input: -+ * None -+ * Output: -+ * pMode - pointer buffer of trunk mode -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ * Note: -+ * The enum of the trunk mode as following -+ * - TRUNK_MODE_NORMAL -+ * - TRUNK_MODE_DUMB -+ */ -+rtk_api_ret_t rtk_trunk_mode_get(rtk_trunk_mode_t *pMode) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pMode) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicTrunkingMode((rtk_uint32 *)pMode)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_trunk_trafficPause_set -+ * Description: -+ * Set the traffic pause setting of a trunk group. -+ * Input: -+ * trk_gid - trunk group id -+ * enable - traffic pause state -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_LA_TRUNK_ID - invalid trunk ID -+ * Note: -+ * None. -+ */ -+rtk_api_ret_t rtk_trunk_trafficPause_set(rtk_trunk_group_t trk_gid, rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Trunk Group Valid */ -+ RTK_CHK_TRUNK_GROUP_VALID(trk_gid); -+ -+ if(enable >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setAsicTrunkingFc((rtk_uint32)trk_gid, (rtk_uint32)enable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_trunk_trafficPause_get -+ * Description: -+ * Get the traffic pause setting of a trunk group. -+ * Input: -+ * trk_gid - trunk group id -+ * Output: -+ * pEnable - pointer of traffic pause state. -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_LA_TRUNK_ID - invalid trunk ID -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ * Note: -+ * None. -+ */ -+rtk_api_ret_t rtk_trunk_trafficPause_get(rtk_trunk_group_t trk_gid, rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Trunk Group Valid */ -+ RTK_CHK_TRUNK_GROUP_VALID(trk_gid); -+ -+ if(NULL == pEnable) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicTrunkingFc((rtk_uint32)trk_gid, (rtk_uint32 *)pEnable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_trunk_hashMappingTable_set -+ * Description: -+ * Set hash value to port array in the trunk group id from the specified device. -+ * Input: -+ * trk_gid - trunk group id -+ * pHash2Port_array - ports associate with the hash value -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_UNIT_ID - invalid unit id -+ * RT_ERR_LA_TRUNK_ID - invalid trunk ID -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ * RT_ERR_LA_TRUNK_NOT_EXIST - the trunk doesn't exist -+ * RT_ERR_LA_NOT_MEMBER_PORT - the port is not a member port of the trunk -+ * RT_ERR_LA_CPUPORT - CPU port can not be aggregated port -+ * Note: -+ * Trunk group 0 & 1 shares the same hash mapping table. -+ * Trunk group 2 uses a independent table. -+ */ -+rtk_api_ret_t rtk_trunk_hashMappingTable_set(rtk_trunk_group_t trk_gid, rtk_trunk_hashVal2Port_t *pHash2Port_array) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 hashValue; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Trunk Group Valid */ -+ RTK_CHK_TRUNK_GROUP_VALID(trk_gid); -+ -+ if(NULL == pHash2Port_array) -+ return RT_ERR_NULL_POINTER; -+ -+ if(trk_gid <= TRUNK_GROUP1) -+ { -+ for(hashValue = 0; hashValue < RTK_MAX_NUM_OF_TRUNK_HASH_VAL; hashValue++) -+ { -+ if ((retVal = rtl8367c_setAsicTrunkingHashTable(hashValue, pHash2Port_array->value[hashValue])) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ else -+ { -+ for(hashValue = 0; hashValue < RTK_MAX_NUM_OF_TRUNK_HASH_VAL; hashValue++) -+ { -+ if ((retVal = rtl8367c_setAsicTrunkingHashTable1(hashValue, pHash2Port_array->value[hashValue])) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_trunk_hashMappingTable_get -+ * Description: -+ * Get hash value to port array in the trunk group id from the specified device. -+ * Input: -+ * trk_gid - trunk group id -+ * Output: -+ * pHash2Port_array - pointer buffer of ports associate with the hash value -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_UNIT_ID - invalid unit id -+ * RT_ERR_LA_TRUNK_ID - invalid trunk ID -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ * Note: -+ * Trunk group 0 & 1 shares the same hash mapping table. -+ * Trunk group 2 uses a independent table. -+ */ -+rtk_api_ret_t rtk_trunk_hashMappingTable_get(rtk_trunk_group_t trk_gid, rtk_trunk_hashVal2Port_t *pHash2Port_array) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 hashValue; -+ rtk_uint32 hashPort; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Trunk Group Valid */ -+ RTK_CHK_TRUNK_GROUP_VALID(trk_gid); -+ -+ if(NULL == pHash2Port_array) -+ return RT_ERR_NULL_POINTER; -+ -+ if(trk_gid <= TRUNK_GROUP1) -+ { -+ for(hashValue = 0; hashValue < RTK_MAX_NUM_OF_TRUNK_HASH_VAL; hashValue++) -+ { -+ if ((retVal = rtl8367c_getAsicTrunkingHashTable(hashValue, &hashPort)) != RT_ERR_OK) -+ return retVal; -+ -+ pHash2Port_array->value[hashValue] = hashPort; -+ } -+ } -+ else -+ { -+ for(hashValue = 0; hashValue < RTK_MAX_NUM_OF_TRUNK_HASH_VAL; hashValue++) -+ { -+ if ((retVal = rtl8367c_getAsicTrunkingHashTable1(hashValue, &hashPort)) != RT_ERR_OK) -+ return retVal; -+ -+ pHash2Port_array->value[hashValue] = hashPort; -+ } -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_trunk_portQueueEmpty_get -+ * Description: -+ * Get the port mask which all queues are empty. -+ * Input: -+ * None. -+ * Output: -+ * pEmpty_portmask - pointer empty port mask -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NULL_POINTER - input parameter may be null pointer -+ * Note: -+ * None. -+ */ -+rtk_api_ret_t rtk_trunk_portQueueEmpty_get(rtk_portmask_t *pEmpty_portmask) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pmask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pEmpty_portmask) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicQeueuEmptyStatus(&pmask)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtk_switch_portmask_P2L_get(pmask, pEmpty_portmask)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -diff --git a/drivers/net/phy/rtk/rtl8367c/vlan.c b/drivers/net/phy/rtk/rtl8367c/vlan.c -new file mode 100644 -index 000000000000..b407c3008cd0 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367c/vlan.c -@@ -0,0 +1,2124 @@ -+/* -+ * Copyright (C) 2013 Realtek Semiconductor Corp. -+ * All Rights Reserved. -+ * -+ * Unless you and Realtek execute a separate written software license -+ * agreement governing use of this software, this software is licensed -+ * to you under the terms of the GNU General Public License version 2, -+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -+ * -+ * $Revision: 76306 $ -+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ -+ * -+ * Purpose : RTK switch high-level API for RTL8367/RTL8367C -+ * Feature : Here is a list of all functions and variables in VLAN module. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+typedef enum vlan_mbrCfgType_e -+{ -+ MBRCFG_UNUSED = 0, -+ MBRCFG_USED_BY_VLAN, -+ MBRCFG_END -+}vlan_mbrCfgType_t; -+ -+static rtk_vlan_t vlan_mbrCfgVid[RTL8367C_CVIDXNO]; -+static vlan_mbrCfgType_t vlan_mbrCfgUsage[RTL8367C_CVIDXNO]; -+ -+/* Function Name: -+ * rtk_vlan_init -+ * Description: -+ * Initialize VLAN. -+ * Input: -+ * None -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * Note: -+ * VLAN is disabled by default. User has to call this API to enable VLAN before -+ * using it. And It will set a default VLAN(vid 1) including all ports and set -+ * all ports PVID to the default VLAN. -+ */ -+rtk_api_ret_t rtk_vlan_init(void) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 i; -+ rtl8367c_user_vlan4kentry vlan4K; -+ rtl8367c_vlanconfiguser vlanMC; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Clean Database */ -+ memset(vlan_mbrCfgVid, 0x00, sizeof(rtk_vlan_t) * RTL8367C_CVIDXNO); -+ memset(vlan_mbrCfgUsage, 0x00, sizeof(vlan_mbrCfgType_t) * RTL8367C_CVIDXNO); -+ -+ /* clean 32 VLAN member configuration */ -+ for (i = 0; i <= RTL8367C_CVIDXMAX; i++) -+ { -+ vlanMC.evid = 0; -+ vlanMC.mbr = 0; -+ vlanMC.fid_msti = 0; -+ vlanMC.envlanpol = 0; -+ vlanMC.meteridx = 0; -+ vlanMC.vbpen = 0; -+ vlanMC.vbpri = 0; -+ if ((retVal = rtl8367c_setAsicVlanMemberConfig(i, &vlanMC)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ /* Set a default VLAN with vid 1 to 4K table for all ports */ -+ memset(&vlan4K, 0, sizeof(rtl8367c_user_vlan4kentry)); -+ vlan4K.vid = 1; -+ vlan4K.mbr = RTK_PHY_PORTMASK_ALL; -+ vlan4K.untag = RTK_PHY_PORTMASK_ALL; -+ vlan4K.fid_msti = 0; -+ if ((retVal = rtl8367c_setAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK) -+ return retVal; -+ -+ /* Also set the default VLAN to 32 member configuration index 0 */ -+ memset(&vlanMC, 0, sizeof(rtl8367c_vlanconfiguser)); -+ vlanMC.evid = 1; -+ vlanMC.mbr = RTK_PHY_PORTMASK_ALL; -+ vlanMC.fid_msti = 0; -+ if ((retVal = rtl8367c_setAsicVlanMemberConfig(0, &vlanMC)) != RT_ERR_OK) -+ return retVal; -+ -+ /* Set all ports PVID to default VLAN and tag-mode to original */ -+ RTK_SCAN_ALL_PHY_PORTMASK(i) -+ { -+ if ((retVal = rtl8367c_setAsicVlanPortBasedVID(i, 0, 0)) != RT_ERR_OK) -+ return retVal; -+ if ((retVal = rtl8367c_setAsicVlanEgressTagMode(i, EG_TAG_MODE_ORI)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ /* Update Database */ -+ vlan_mbrCfgUsage[0] = MBRCFG_USED_BY_VLAN; -+ vlan_mbrCfgVid[0] = 1; -+ -+ /* Enable Ingress filter */ -+ RTK_SCAN_ALL_PHY_PORTMASK(i) -+ { -+ if ((retVal = rtl8367c_setAsicVlanIngressFilter(i, ENABLED)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ /* enable VLAN */ -+ if ((retVal = rtl8367c_setAsicVlanFilter(ENABLED)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_set -+ * Description: -+ * Set a VLAN entry. -+ * Input: -+ * vid - VLAN ID to configure. -+ * pVlanCfg - VLAN Configuration -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_L2_FID - Invalid FID. -+ * RT_ERR_VLAN_PORT_MBR_EXIST - Invalid member port mask. -+ * RT_ERR_VLAN_VID - Invalid VID parameter. -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_vlan_set(rtk_vlan_t vid, rtk_vlan_cfg_t *pVlanCfg) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 phyMbrPmask; -+ rtk_uint32 phyUntagPmask; -+ rtl8367c_user_vlan4kentry vlan4K; -+ rtl8367c_vlanconfiguser vlanMC; -+ rtk_uint32 idx; -+ rtk_uint32 empty_index = 0xffff; -+ rtk_uint32 update_evid = 0; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* vid must be 0~8191 */ -+ if (vid > RTL8367C_EVIDMAX) -+ return RT_ERR_VLAN_VID; -+ -+ /* Null pointer check */ -+ if(NULL == pVlanCfg) -+ return RT_ERR_NULL_POINTER; -+ -+ /* Check port mask valid */ -+ RTK_CHK_PORTMASK_VALID(&(pVlanCfg->mbr)); -+ -+ if (vid <= RTL8367C_VIDMAX) -+ { -+ /* Check untag port mask valid */ -+ RTK_CHK_PORTMASK_VALID(&(pVlanCfg->untag)); -+ } -+ -+ /* IVL_EN */ -+ if(pVlanCfg->ivl_en >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ /* fid must be 0~15 */ -+ if(pVlanCfg->fid_msti > RTL8367C_FIDMAX) -+ return RT_ERR_L2_FID; -+ -+ /* Policing */ -+ if(pVlanCfg->envlanpol >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ /* Meter ID */ -+ if(pVlanCfg->meteridx > RTK_MAX_METER_ID) -+ return RT_ERR_INPUT; -+ -+ /* VLAN based priority */ -+ if(pVlanCfg->vbpen >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ /* Priority */ -+ if(pVlanCfg->vbpri > RTL8367C_PRIMAX) -+ return RT_ERR_INPUT; -+ -+ /* Get physical port mask */ -+ if(rtk_switch_portmask_L2P_get(&(pVlanCfg->mbr), &phyMbrPmask) != RT_ERR_OK) -+ return RT_ERR_FAILED; -+ -+ if(rtk_switch_portmask_L2P_get(&(pVlanCfg->untag), &phyUntagPmask) != RT_ERR_OK) -+ return RT_ERR_FAILED; -+ -+ if (vid <= RTL8367C_VIDMAX) -+ { -+ /* update 4K table */ -+ memset(&vlan4K, 0, sizeof(rtl8367c_user_vlan4kentry)); -+ vlan4K.vid = vid; -+ -+ vlan4K.mbr = (phyMbrPmask & 0xFFFF); -+ vlan4K.untag = (phyUntagPmask & 0xFFFF); -+ -+ vlan4K.ivl_svl = pVlanCfg->ivl_en; -+ vlan4K.fid_msti = pVlanCfg->fid_msti; -+ vlan4K.envlanpol = pVlanCfg->envlanpol; -+ vlan4K.meteridx = pVlanCfg->meteridx; -+ vlan4K.vbpen = pVlanCfg->vbpen; -+ vlan4K.vbpri = pVlanCfg->vbpri; -+ -+ if ((retVal = rtl8367c_setAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK) -+ return retVal; -+ -+ /* Update Member configuration if exist */ -+ for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++) -+ { -+ if(vlan_mbrCfgUsage[idx] == MBRCFG_USED_BY_VLAN) -+ { -+ if(vlan_mbrCfgVid[idx] == vid) -+ { -+ /* Found! Update */ -+ if(phyMbrPmask == 0x00) -+ { -+ /* Member port = 0x00, delete this VLAN from Member Configuration */ -+ memset(&vlanMC, 0x00, sizeof(rtl8367c_vlanconfiguser)); -+ if ((retVal = rtl8367c_setAsicVlanMemberConfig(idx, &vlanMC)) != RT_ERR_OK) -+ return retVal; -+ -+ /* Clear Database */ -+ vlan_mbrCfgUsage[idx] = MBRCFG_UNUSED; -+ vlan_mbrCfgVid[idx] = 0; -+ } -+ else -+ { -+ /* Normal VLAN config, update to member configuration */ -+ vlanMC.evid = vid; -+ vlanMC.mbr = vlan4K.mbr; -+ vlanMC.fid_msti = vlan4K.fid_msti; -+ vlanMC.meteridx = vlan4K.meteridx; -+ vlanMC.envlanpol= vlan4K.envlanpol; -+ vlanMC.vbpen = vlan4K.vbpen; -+ vlanMC.vbpri = vlan4K.vbpri; -+ if ((retVal = rtl8367c_setAsicVlanMemberConfig(idx, &vlanMC)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ break; -+ } -+ } -+ } -+ } -+ else -+ { -+ /* vid > 4095 */ -+ for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++) -+ { -+ if(vlan_mbrCfgUsage[idx] == MBRCFG_USED_BY_VLAN) -+ { -+ if(vlan_mbrCfgVid[idx] == vid) -+ { -+ /* Found! Update */ -+ if(phyMbrPmask == 0x00) -+ { -+ /* Member port = 0x00, delete this VLAN from Member Configuration */ -+ memset(&vlanMC, 0x00, sizeof(rtl8367c_vlanconfiguser)); -+ if ((retVal = rtl8367c_setAsicVlanMemberConfig(idx, &vlanMC)) != RT_ERR_OK) -+ return retVal; -+ -+ /* Clear Database */ -+ vlan_mbrCfgUsage[idx] = MBRCFG_UNUSED; -+ vlan_mbrCfgVid[idx] = 0; -+ } -+ else -+ { -+ /* Normal VLAN config, update to member configuration */ -+ vlanMC.evid = vid; -+ vlanMC.mbr = phyMbrPmask; -+ vlanMC.fid_msti = pVlanCfg->fid_msti; -+ vlanMC.meteridx = pVlanCfg->meteridx; -+ vlanMC.envlanpol= pVlanCfg->envlanpol; -+ vlanMC.vbpen = pVlanCfg->vbpen; -+ vlanMC.vbpri = pVlanCfg->vbpri; -+ if ((retVal = rtl8367c_setAsicVlanMemberConfig(idx, &vlanMC)) != RT_ERR_OK) -+ return retVal; -+ -+ break; -+ } -+ -+ update_evid = 1; -+ } -+ } -+ -+ if(vlan_mbrCfgUsage[idx] == MBRCFG_UNUSED) -+ { -+ if(0xffff == empty_index) -+ empty_index = idx; -+ } -+ } -+ -+ /* doesn't find out same EVID entry and there is empty index in member configuration */ -+ if( (phyMbrPmask != 0x00) && (update_evid == 0) && (empty_index != 0xFFFF) ) -+ { -+ vlanMC.evid = vid; -+ vlanMC.mbr = phyMbrPmask; -+ vlanMC.fid_msti = pVlanCfg->fid_msti; -+ vlanMC.meteridx = pVlanCfg->meteridx; -+ vlanMC.envlanpol= pVlanCfg->envlanpol; -+ vlanMC.vbpen = pVlanCfg->vbpen; -+ vlanMC.vbpri = pVlanCfg->vbpri; -+ if ((retVal = rtl8367c_setAsicVlanMemberConfig(empty_index, &vlanMC)) != RT_ERR_OK) -+ return retVal; -+ -+ vlan_mbrCfgUsage[empty_index] = MBRCFG_USED_BY_VLAN; -+ vlan_mbrCfgVid[empty_index] = vid; -+ -+ } -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_get -+ * Description: -+ * Get a VLAN entry. -+ * Input: -+ * vid - VLAN ID to configure. -+ * Output: -+ * pVlanCfg - VLAN Configuration -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_VLAN_VID - Invalid VID parameter. -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_vlan_get(rtk_vlan_t vid, rtk_vlan_cfg_t *pVlanCfg) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 phyMbrPmask; -+ rtk_uint32 phyUntagPmask; -+ rtl8367c_user_vlan4kentry vlan4K; -+ rtl8367c_vlanconfiguser vlanMC; -+ rtk_uint32 idx; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* vid must be 0~8191 */ -+ if (vid > RTL8367C_EVIDMAX) -+ return RT_ERR_VLAN_VID; -+ -+ /* Null pointer check */ -+ if(NULL == pVlanCfg) -+ return RT_ERR_NULL_POINTER; -+ -+ if (vid <= RTL8367C_VIDMAX) -+ { -+ vlan4K.vid = vid; -+ -+ if ((retVal = rtl8367c_getAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK) -+ return retVal; -+ -+ phyMbrPmask = vlan4K.mbr; -+ phyUntagPmask = vlan4K.untag; -+ if(rtk_switch_portmask_P2L_get(phyMbrPmask, &(pVlanCfg->mbr)) != RT_ERR_OK) -+ return RT_ERR_FAILED; -+ -+ if(rtk_switch_portmask_P2L_get(phyUntagPmask, &(pVlanCfg->untag)) != RT_ERR_OK) -+ return RT_ERR_FAILED; -+ -+ pVlanCfg->ivl_en = vlan4K.ivl_svl; -+ pVlanCfg->fid_msti = vlan4K.fid_msti; -+ pVlanCfg->envlanpol = vlan4K.envlanpol; -+ pVlanCfg->meteridx = vlan4K.meteridx; -+ pVlanCfg->vbpen = vlan4K.vbpen; -+ pVlanCfg->vbpri = vlan4K.vbpri; -+ } -+ else -+ { -+ for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++) -+ { -+ if(vlan_mbrCfgUsage[idx] == MBRCFG_USED_BY_VLAN) -+ { -+ if(vlan_mbrCfgVid[idx] == vid) -+ { -+ if ((retVal = rtl8367c_getAsicVlanMemberConfig(idx, &vlanMC)) != RT_ERR_OK) -+ return retVal; -+ -+ phyMbrPmask = vlanMC.mbr; -+ if(rtk_switch_portmask_P2L_get(phyMbrPmask, &(pVlanCfg->mbr)) != RT_ERR_OK) -+ return RT_ERR_FAILED; -+ -+ pVlanCfg->untag.bits[0] = 0; -+ pVlanCfg->ivl_en = 0; -+ pVlanCfg->fid_msti = vlanMC.fid_msti; -+ pVlanCfg->envlanpol = vlanMC.envlanpol; -+ pVlanCfg->meteridx = vlanMC.meteridx; -+ pVlanCfg->vbpen = vlanMC.vbpen; -+ pVlanCfg->vbpri = vlanMC.vbpri; -+ } -+ } -+ } -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_egrFilterEnable_set -+ * Description: -+ * Set VLAN egress filter. -+ * Input: -+ * egrFilter - Egress filtering -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_ENABLE - Invalid input parameters. -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_vlan_egrFilterEnable_set(rtk_enable_t egrFilter) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(egrFilter >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ /* enable VLAN */ -+ if ((retVal = rtl8367c_setAsicVlanFilter((rtk_uint32)egrFilter)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_egrFilterEnable_get -+ * Description: -+ * Get VLAN egress filter. -+ * Input: -+ * pEgrFilter - Egress filtering -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - NULL Pointer. -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_vlan_egrFilterEnable_get(rtk_enable_t *pEgrFilter) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 state; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pEgrFilter) -+ return RT_ERR_NULL_POINTER; -+ -+ /* enable VLAN */ -+ if ((retVal = rtl8367c_getAsicVlanFilter(&state)) != RT_ERR_OK) -+ return retVal; -+ -+ *pEgrFilter = (rtk_enable_t)state; -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_mbrCfg_set -+ * Description: -+ * Set a VLAN Member Configuration entry by index. -+ * Input: -+ * idx - Index of VLAN Member Configuration. -+ * pMbrcfg - VLAN member Configuration. -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_VLAN_VID - Invalid VID parameter. -+ * Note: -+ * Set a VLAN Member Configuration entry by index. -+ */ -+rtk_api_ret_t rtk_vlan_mbrCfg_set(rtk_uint32 idx, rtk_vlan_mbrcfg_t *pMbrcfg) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 phyMbrPmask; -+ rtl8367c_vlanconfiguser mbrCfg; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Error check */ -+ if(pMbrcfg == NULL) -+ return RT_ERR_NULL_POINTER; -+ -+ if(idx > RTL8367C_CVIDXMAX) -+ return RT_ERR_INPUT; -+ -+ if(pMbrcfg->evid > RTL8367C_EVIDMAX) -+ return RT_ERR_INPUT; -+ -+ if(pMbrcfg->fid_msti > RTL8367C_FIDMAX) -+ return RT_ERR_L2_FID; -+ -+ if(pMbrcfg->envlanpol >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ if(pMbrcfg->meteridx > RTK_MAX_METER_ID) -+ return RT_ERR_FILTER_METER_ID; -+ -+ if(pMbrcfg->vbpen >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ if(pMbrcfg->vbpri > RTL8367C_PRIMAX) -+ return RT_ERR_QOS_INT_PRIORITY; -+ -+ /* Check port mask valid */ -+ RTK_CHK_PORTMASK_VALID(&(pMbrcfg->mbr)); -+ -+ mbrCfg.evid = pMbrcfg->evid; -+ mbrCfg.fid_msti = pMbrcfg->fid_msti; -+ mbrCfg.envlanpol = pMbrcfg->envlanpol; -+ mbrCfg.meteridx = pMbrcfg->meteridx; -+ mbrCfg.vbpen = pMbrcfg->vbpen; -+ mbrCfg.vbpri = pMbrcfg->vbpri; -+ -+ if(rtk_switch_portmask_L2P_get(&(pMbrcfg->mbr), &phyMbrPmask) != RT_ERR_OK) -+ return RT_ERR_FAILED; -+ -+ mbrCfg.mbr = phyMbrPmask; -+ -+ if ((retVal = rtl8367c_setAsicVlanMemberConfig(idx, &mbrCfg)) != RT_ERR_OK) -+ return retVal; -+ -+ /* Update Database */ -+ if( (mbrCfg.evid == 0) && (mbrCfg.mbr == 0) ) -+ { -+ vlan_mbrCfgUsage[idx] = MBRCFG_UNUSED; -+ vlan_mbrCfgVid[idx] = 0; -+ } -+ else -+ { -+ vlan_mbrCfgUsage[idx] = MBRCFG_USED_BY_VLAN; -+ vlan_mbrCfgVid[idx] = mbrCfg.evid; -+ } -+ -+ return RT_ERR_OK; -+ -+} -+ -+/* Function Name: -+ * rtk_vlan_mbrCfg_get -+ * Description: -+ * Get a VLAN Member Configuration entry by index. -+ * Input: -+ * idx - Index of VLAN Member Configuration. -+ * Output: -+ * pMbrcfg - VLAN member Configuration. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_VLAN_VID - Invalid VID parameter. -+ * Note: -+ * Get a VLAN Member Configuration entry by index. -+ */ -+rtk_api_ret_t rtk_vlan_mbrCfg_get(rtk_uint32 idx, rtk_vlan_mbrcfg_t *pMbrcfg) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 phyMbrPmask; -+ rtl8367c_vlanconfiguser mbrCfg; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Error check */ -+ if(pMbrcfg == NULL) -+ return RT_ERR_NULL_POINTER; -+ -+ if(idx > RTL8367C_CVIDXMAX) -+ return RT_ERR_INPUT; -+ -+ memset(&mbrCfg, 0x00, sizeof(rtl8367c_vlanconfiguser)); -+ if ((retVal = rtl8367c_getAsicVlanMemberConfig(idx, &mbrCfg)) != RT_ERR_OK) -+ return retVal; -+ -+ pMbrcfg->evid = mbrCfg.evid; -+ pMbrcfg->fid_msti = mbrCfg.fid_msti; -+ pMbrcfg->envlanpol = mbrCfg.envlanpol; -+ pMbrcfg->meteridx = mbrCfg.meteridx; -+ pMbrcfg->vbpen = mbrCfg.vbpen; -+ pMbrcfg->vbpri = mbrCfg.vbpri; -+ -+ phyMbrPmask = mbrCfg.mbr; -+ if(rtk_switch_portmask_P2L_get(phyMbrPmask, &(pMbrcfg->mbr)) != RT_ERR_OK) -+ return RT_ERR_FAILED; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_portPvid_set -+ * Description: -+ * Set port to specified VLAN ID(PVID). -+ * Input: -+ * port - Port id. -+ * pvid - Specified VLAN ID. -+ * priority - 802.1p priority for the PVID. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_VLAN_PRIORITY - Invalid priority. -+ * RT_ERR_VLAN_ENTRY_NOT_FOUND - VLAN entry not found. -+ * RT_ERR_VLAN_VID - Invalid VID parameter. -+ * Note: -+ * The API is used for Port-based VLAN. The untagged frame received from the -+ * port will be classified to the specified VLAN and assigned to the specified priority. -+ */ -+rtk_api_ret_t rtk_vlan_portPvid_set(rtk_port_t port, rtk_vlan_t pvid, rtk_pri_t priority) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 index; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ /* vid must be 0~8191 */ -+ if (pvid > RTL8367C_EVIDMAX) -+ return RT_ERR_VLAN_VID; -+ -+ /* priority must be 0~7 */ -+ if (priority > RTL8367C_PRIMAX) -+ return RT_ERR_VLAN_PRIORITY; -+ -+ if((retVal = rtk_vlan_checkAndCreateMbr(pvid, &index)) != RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicVlanPortBasedVID(rtk_switch_port_L2P_get(port), index, priority)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_portPvid_get -+ * Description: -+ * Get VLAN ID(PVID) on specified port. -+ * Input: -+ * port - Port id. -+ * Output: -+ * pPvid - Specified VLAN ID. -+ * pPriority - 802.1p priority for the PVID. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get the PVID and 802.1p priority for the PVID of Port-based VLAN. -+ */ -+rtk_api_ret_t rtk_vlan_portPvid_get(rtk_port_t port, rtk_vlan_t *pPvid, rtk_pri_t *pPriority) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 index, pri; -+ rtl8367c_vlanconfiguser mbrCfg; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(NULL == pPvid) -+ return RT_ERR_NULL_POINTER; -+ -+ if(NULL == pPriority) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicVlanPortBasedVID(rtk_switch_port_L2P_get(port), &index, &pri)) != RT_ERR_OK) -+ return retVal; -+ -+ memset(&mbrCfg, 0x00, sizeof(rtl8367c_vlanconfiguser)); -+ if ((retVal = rtl8367c_getAsicVlanMemberConfig(index, &mbrCfg)) != RT_ERR_OK) -+ return retVal; -+ -+ *pPvid = mbrCfg.evid; -+ *pPriority = pri; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_portIgrFilterEnable_set -+ * Description: -+ * Set VLAN ingress for each port. -+ * Input: -+ * port - Port id. -+ * igr_filter - VLAN ingress function enable status. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number -+ * RT_ERR_ENABLE - Invalid enable input -+ * Note: -+ * The status of vlan ingress filter is as following: -+ * - DISABLED -+ * - ENABLED -+ * While VLAN function is enabled, ASIC will decide VLAN ID for each received frame and get belonged member -+ * ports from VLAN table. If received port is not belonged to VLAN member ports, ASIC will drop received frame if VLAN ingress function is enabled. -+ */ -+rtk_api_ret_t rtk_vlan_portIgrFilterEnable_set(rtk_port_t port, rtk_enable_t igr_filter) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (igr_filter >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ if ((retVal = rtl8367c_setAsicVlanIngressFilter(rtk_switch_port_L2P_get(port), igr_filter)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_portIgrFilterEnable_get -+ * Description: -+ * Get VLAN Ingress Filter -+ * Input: -+ * port - Port id. -+ * Output: -+ * pIgr_filter - VLAN ingress function enable status. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can Get the VLAN ingress filter status. -+ * The status of vlan ingress filter is as following: -+ * - DISABLED -+ * - ENABLED -+ */ -+rtk_api_ret_t rtk_vlan_portIgrFilterEnable_get(rtk_port_t port, rtk_enable_t *pIgr_filter) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(NULL == pIgr_filter) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicVlanIngressFilter(rtk_switch_port_L2P_get(port), pIgr_filter)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_portAcceptFrameType_set -+ * Description: -+ * Set VLAN accept_frame_type -+ * Input: -+ * port - Port id. -+ * accept_frame_type - accept frame type -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_VLAN_ACCEPT_FRAME_TYPE - Invalid frame type. -+ * Note: -+ * The API is used for checking 802.1Q tagged frames. -+ * The accept frame type as following: -+ * - ACCEPT_FRAME_TYPE_ALL -+ * - ACCEPT_FRAME_TYPE_TAG_ONLY -+ * - ACCEPT_FRAME_TYPE_UNTAG_ONLY -+ */ -+rtk_api_ret_t rtk_vlan_portAcceptFrameType_set(rtk_port_t port, rtk_vlan_acceptFrameType_t accept_frame_type) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (accept_frame_type >= ACCEPT_FRAME_TYPE_END) -+ return RT_ERR_VLAN_ACCEPT_FRAME_TYPE; -+ -+ if ((retVal = rtl8367c_setAsicVlanAccpetFrameType(rtk_switch_port_L2P_get(port), (rtl8367c_accframetype)accept_frame_type)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_portAcceptFrameType_get -+ * Description: -+ * Get VLAN accept_frame_type -+ * Input: -+ * port - Port id. -+ * Output: -+ * pAccept_frame_type - accept frame type -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can Get the VLAN ingress filter. -+ * The accept frame type as following: -+ * - ACCEPT_FRAME_TYPE_ALL -+ * - ACCEPT_FRAME_TYPE_TAG_ONLY -+ * - ACCEPT_FRAME_TYPE_UNTAG_ONLY -+ */ -+rtk_api_ret_t rtk_vlan_portAcceptFrameType_get(rtk_port_t port, rtk_vlan_acceptFrameType_t *pAccept_frame_type) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_accframetype acc_frm_type; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(NULL == pAccept_frame_type) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicVlanAccpetFrameType(rtk_switch_port_L2P_get(port), &acc_frm_type)) != RT_ERR_OK) -+ return retVal; -+ -+ *pAccept_frame_type = (rtk_vlan_acceptFrameType_t)acc_frm_type; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_protoAndPortBasedVlan_add -+ * Description: -+ * Add the protocol-and-port-based vlan to the specified port of device. -+ * Input: -+ * port - Port id. -+ * pInfo - Protocol and port based VLAN configuration information. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_VLAN_VID - Invalid VID parameter. -+ * RT_ERR_VLAN_PRIORITY - Invalid priority. -+ * RT_ERR_TBL_FULL - Table is full. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * Note: -+ * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline -+ * The frame type is shown in the following: -+ * - FRAME_TYPE_ETHERNET -+ * - FRAME_TYPE_RFC1042 -+ * - FRAME_TYPE_LLCOTHER -+ */ -+rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_add(rtk_port_t port, rtk_vlan_protoAndPortInfo_t *pInfo) -+{ -+ rtk_api_ret_t retVal, i; -+ rtk_uint32 exist, empty, used, index; -+ rtl8367c_protocolgdatacfg ppb_data_cfg; -+ rtl8367c_protocolvlancfg ppb_vlan_cfg; -+ rtl8367c_provlan_frametype tmp; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(NULL == pInfo) -+ return RT_ERR_NULL_POINTER; -+ -+ if (pInfo->proto_type > RTK_MAX_NUM_OF_PROTO_TYPE) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if (pInfo->frame_type >= FRAME_TYPE_END) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if (pInfo->cvid > RTL8367C_VIDMAX) -+ return RT_ERR_VLAN_VID; -+ -+ if (pInfo->cpri > RTL8367C_PRIMAX) -+ return RT_ERR_VLAN_PRIORITY; -+ -+ exist = 0xFF; -+ empty = 0xFF; -+ for (i = RTL8367C_PROTOVLAN_GIDX_MAX; i >= 0; i--) -+ { -+ if ((retVal = rtl8367c_getAsicVlanProtocolBasedGroupData(i, &ppb_data_cfg)) != RT_ERR_OK) -+ return retVal; -+ tmp = (rtl8367c_provlan_frametype)pInfo->frame_type; -+ if (ppb_data_cfg.etherType == pInfo->proto_type && ppb_data_cfg.frameType == tmp) -+ { -+ /*Already exist*/ -+ exist = i; -+ break; -+ } -+ else if (ppb_data_cfg.etherType == 0 && ppb_data_cfg.frameType == 0) -+ { -+ /*find empty index*/ -+ empty = i; -+ } -+ } -+ -+ used = 0xFF; -+ /*No empty and exist index*/ -+ if (0xFF == exist && 0xFF == empty) -+ return RT_ERR_TBL_FULL; -+ else if (existframe_type; -+ ppb_data_cfg.etherType = pInfo->proto_type; -+ if ((retVal = rtl8367c_setAsicVlanProtocolBasedGroupData(empty, &ppb_data_cfg)) != RT_ERR_OK) -+ return retVal; -+ used = empty; -+ } -+ else -+ return RT_ERR_FAILED; -+ -+ if((retVal = rtk_vlan_checkAndCreateMbr(pInfo->cvid, &index)) != RT_ERR_OK) -+ return retVal; -+ -+ ppb_vlan_cfg.vlan_idx = index; -+ ppb_vlan_cfg.valid = TRUE; -+ ppb_vlan_cfg.priority = pInfo->cpri; -+ if ((retVal = rtl8367c_setAsicVlanPortAndProtocolBased(rtk_switch_port_L2P_get(port), used, &ppb_vlan_cfg)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_protoAndPortBasedVlan_get -+ * Description: -+ * Get the protocol-and-port-based vlan to the specified port of device. -+ * Input: -+ * port - Port id. -+ * proto_type - protocol-and-port-based vlan protocol type. -+ * frame_type - protocol-and-port-based vlan frame type. -+ * Output: -+ * pInfo - Protocol and port based VLAN configuration information. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * RT_ERR_TBL_FULL - Table is full. -+ * Note: -+ * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline -+ * The frame type is shown in the following: -+ * - FRAME_TYPE_ETHERNET -+ * - FRAME_TYPE_RFC1042 -+ * - FRAME_TYPE_LLCOTHER -+ */ -+rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_get(rtk_port_t port, rtk_vlan_proto_type_t proto_type, rtk_vlan_protoVlan_frameType_t frame_type, rtk_vlan_protoAndPortInfo_t *pInfo) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 i; -+ rtk_uint32 ppb_idx; -+ rtl8367c_protocolgdatacfg ppb_data_cfg; -+ rtl8367c_protocolvlancfg ppb_vlan_cfg; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (proto_type > RTK_MAX_NUM_OF_PROTO_TYPE) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if (frame_type >= FRAME_TYPE_END) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ ppb_idx = 0; -+ -+ for (i = 0; i<= RTL8367C_PROTOVLAN_GIDX_MAX; i++) -+ { -+ if ((retVal = rtl8367c_getAsicVlanProtocolBasedGroupData(i, &ppb_data_cfg)) != RT_ERR_OK) -+ return retVal; -+ -+ if ( (ppb_data_cfg.frameType == (rtl8367c_provlan_frametype)frame_type) && (ppb_data_cfg.etherType == proto_type) ) -+ { -+ ppb_idx = i; -+ break; -+ } -+ else if (RTL8367C_PROTOVLAN_GIDX_MAX == i) -+ return RT_ERR_TBL_FULL; -+ } -+ -+ if ((retVal = rtl8367c_getAsicVlanPortAndProtocolBased(rtk_switch_port_L2P_get(port), ppb_idx, &ppb_vlan_cfg)) != RT_ERR_OK) -+ return retVal; -+ -+ if (FALSE == ppb_vlan_cfg.valid) -+ return RT_ERR_FAILED; -+ -+ pInfo->frame_type = frame_type; -+ pInfo->proto_type = proto_type; -+ pInfo->cvid = vlan_mbrCfgVid[ppb_vlan_cfg.vlan_idx]; -+ pInfo->cpri = ppb_vlan_cfg.priority; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_protoAndPortBasedVlan_del -+ * Description: -+ * Delete the protocol-and-port-based vlan from the specified port of device. -+ * Input: -+ * port - Port id. -+ * proto_type - protocol-and-port-based vlan protocol type. -+ * frame_type - protocol-and-port-based vlan frame type. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * RT_ERR_TBL_FULL - Table is full. -+ * Note: -+ * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline -+ * The frame type is shown in the following: -+ * - FRAME_TYPE_ETHERNET -+ * - FRAME_TYPE_RFC1042 -+ * - FRAME_TYPE_LLCOTHER -+ */ -+rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_del(rtk_port_t port, rtk_vlan_proto_type_t proto_type, rtk_vlan_protoVlan_frameType_t frame_type) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 i, bUsed; -+ rtk_uint32 ppb_idx; -+ rtl8367c_protocolgdatacfg ppb_data_cfg; -+ rtl8367c_protocolvlancfg ppb_vlan_cfg; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (proto_type > RTK_MAX_NUM_OF_PROTO_TYPE) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ if (frame_type >= FRAME_TYPE_END) -+ return RT_ERR_OUT_OF_RANGE; -+ -+ ppb_idx = 0; -+ -+ for (i = 0; i<= RTL8367C_PROTOVLAN_GIDX_MAX; i++) -+ { -+ if ((retVal = rtl8367c_getAsicVlanProtocolBasedGroupData(i, &ppb_data_cfg)) != RT_ERR_OK) -+ return retVal; -+ -+ if ( (ppb_data_cfg.frameType == (rtl8367c_provlan_frametype)frame_type) && (ppb_data_cfg.etherType == proto_type) ) -+ { -+ ppb_idx = i; -+ ppb_vlan_cfg.valid = FALSE; -+ ppb_vlan_cfg.vlan_idx = 0; -+ ppb_vlan_cfg.priority = 0; -+ if ((retVal = rtl8367c_setAsicVlanPortAndProtocolBased(rtk_switch_port_L2P_get(port), ppb_idx, &ppb_vlan_cfg)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ -+ bUsed = FALSE; -+ RTK_SCAN_ALL_PHY_PORTMASK(i) -+ { -+ if ((retVal = rtl8367c_getAsicVlanPortAndProtocolBased(i, ppb_idx, &ppb_vlan_cfg)) != RT_ERR_OK) -+ return retVal; -+ -+ if (TRUE == ppb_vlan_cfg.valid) -+ { -+ bUsed = TRUE; -+ break; -+ } -+ } -+ -+ if (FALSE == bUsed) /*No Port use this PPB Index, Delete it*/ -+ { -+ ppb_data_cfg.etherType=0; -+ ppb_data_cfg.frameType=0; -+ if ((retVal = rtl8367c_setAsicVlanProtocolBasedGroupData(ppb_idx, &ppb_data_cfg)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_protoAndPortBasedVlan_delAll -+ * Description: -+ * Delete all protocol-and-port-based vlans from the specified port of device. -+ * Input: -+ * port - Port id. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_OUT_OF_RANGE - input out of range. -+ * Note: -+ * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline -+ * Delete all flow table protocol-and-port-based vlan entries. -+ */ -+rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_delAll(rtk_port_t port) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 i, j, bUsed[4]; -+ rtl8367c_protocolgdatacfg ppb_data_cfg; -+ rtl8367c_protocolvlancfg ppb_vlan_cfg; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ for (i = 0; i<= RTL8367C_PROTOVLAN_GIDX_MAX; i++) -+ { -+ ppb_vlan_cfg.valid = FALSE; -+ ppb_vlan_cfg.vlan_idx = 0; -+ ppb_vlan_cfg.priority = 0; -+ if ((retVal = rtl8367c_setAsicVlanPortAndProtocolBased(rtk_switch_port_L2P_get(port), i, &ppb_vlan_cfg)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ bUsed[0] = FALSE; -+ bUsed[1] = FALSE; -+ bUsed[2] = FALSE; -+ bUsed[3] = FALSE; -+ RTK_SCAN_ALL_PHY_PORTMASK(i) -+ { -+ for (j = 0; j <= RTL8367C_PROTOVLAN_GIDX_MAX; j++) -+ { -+ if ((retVal = rtl8367c_getAsicVlanPortAndProtocolBased(i,j, &ppb_vlan_cfg)) != RT_ERR_OK) -+ return retVal; -+ -+ if (TRUE == ppb_vlan_cfg.valid) -+ { -+ bUsed[j] = TRUE; -+ } -+ } -+ } -+ -+ for (i = 0; i<= RTL8367C_PROTOVLAN_GIDX_MAX; i++) -+ { -+ if (FALSE == bUsed[i]) /*No Port use this PPB Index, Delete it*/ -+ { -+ ppb_data_cfg.etherType=0; -+ ppb_data_cfg.frameType=0; -+ if ((retVal = rtl8367c_setAsicVlanProtocolBasedGroupData(i, &ppb_data_cfg)) != RT_ERR_OK) -+ return retVal; -+ } -+ } -+ -+ -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_tagMode_set -+ * Description: -+ * Set CVLAN egress tag mode -+ * Input: -+ * port - Port id. -+ * tag_mode - The egress tag mode. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_INPUT - Invalid input parameter. -+ * RT_ERR_ENABLE - Invalid enable input. -+ * Note: -+ * The API can set Egress tag mode. There are 4 mode for egress tag: -+ * - VLAN_TAG_MODE_ORIGINAL, -+ * - VLAN_TAG_MODE_KEEP_FORMAT, -+ * - VLAN_TAG_MODE_PRI. -+ * - VLAN_TAG_MODE_REAL_KEEP_FORMAT, -+ */ -+rtk_api_ret_t rtk_vlan_tagMode_set(rtk_port_t port, rtk_vlan_tagMode_t tag_mode) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (tag_mode >= VLAN_TAG_MODE_END) -+ return RT_ERR_PORT_ID; -+ -+ if ((retVal = rtl8367c_setAsicVlanEgressTagMode(rtk_switch_port_L2P_get(port), (rtl8367c_egtagmode)tag_mode)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_tagMode_get -+ * Description: -+ * Get CVLAN egress tag mode -+ * Input: -+ * port - Port id. -+ * Output: -+ * pTag_mode - The egress tag mode. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * The API can get Egress tag mode. There are 4 mode for egress tag: -+ * - VLAN_TAG_MODE_ORIGINAL, -+ * - VLAN_TAG_MODE_KEEP_FORMAT, -+ * - VLAN_TAG_MODE_PRI. -+ * - VLAN_TAG_MODE_REAL_KEEP_FORMAT, -+ */ -+rtk_api_ret_t rtk_vlan_tagMode_get(rtk_port_t port, rtk_vlan_tagMode_t *pTag_mode) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_egtagmode mode; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(NULL == pTag_mode) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicVlanEgressTagMode(rtk_switch_port_L2P_get(port), &mode)) != RT_ERR_OK) -+ return retVal; -+ -+ *pTag_mode = (rtk_vlan_tagMode_t)mode; -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_transparent_set -+ * Description: -+ * Set VLAN transparent mode -+ * Input: -+ * egr_port - Egress Port id. -+ * pIgr_pmask - Ingress Port Mask. -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * None. -+ */ -+rtk_api_ret_t rtk_vlan_transparent_set(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pmask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(egr_port); -+ -+ if(NULL == pIgr_pmask) -+ return RT_ERR_NULL_POINTER; -+ -+ RTK_CHK_PORTMASK_VALID(pIgr_pmask); -+ -+ if(rtk_switch_portmask_L2P_get(pIgr_pmask, &pmask) != RT_ERR_OK) -+ return RT_ERR_FAILED; -+ -+ if ((retVal = rtl8367c_setAsicVlanTransparent(rtk_switch_port_L2P_get(egr_port), pmask)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_transparent_get -+ * Description: -+ * Get VLAN transparent mode -+ * Input: -+ * egr_port - Egress Port id. -+ * Output: -+ * pIgr_pmask - Ingress Port Mask -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * None. -+ */ -+rtk_api_ret_t rtk_vlan_transparent_get(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pmask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(egr_port); -+ -+ if(NULL == pIgr_pmask) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicVlanTransparent(rtk_switch_port_L2P_get(egr_port), &pmask)) != RT_ERR_OK) -+ return retVal; -+ -+ if(rtk_switch_portmask_P2L_get(pmask, pIgr_pmask) != RT_ERR_OK) -+ return RT_ERR_FAILED; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_keep_set -+ * Description: -+ * Set VLAN egress keep mode -+ * Input: -+ * egr_port - Egress Port id. -+ * pIgr_pmask - Ingress Port Mask. -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * None. -+ */ -+rtk_api_ret_t rtk_vlan_keep_set(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pmask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(egr_port); -+ -+ if(NULL == pIgr_pmask) -+ return RT_ERR_NULL_POINTER; -+ -+ RTK_CHK_PORTMASK_VALID(pIgr_pmask); -+ -+ if(rtk_switch_portmask_L2P_get(pIgr_pmask, &pmask) != RT_ERR_OK) -+ return RT_ERR_FAILED; -+ -+ if ((retVal = rtl8367c_setAsicVlanEgressKeep(rtk_switch_port_L2P_get(egr_port), pmask)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_keep_get -+ * Description: -+ * Get VLAN egress keep mode -+ * Input: -+ * egr_port - Egress Port id. -+ * Output: -+ * pIgr_pmask - Ingress Port Mask -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port number. -+ * Note: -+ * None. -+ */ -+rtk_api_ret_t rtk_vlan_keep_get(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 pmask; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(egr_port); -+ -+ if(NULL == pIgr_pmask) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicVlanEgressKeep(rtk_switch_port_L2P_get(egr_port), &pmask)) != RT_ERR_OK) -+ return retVal; -+ -+ if(rtk_switch_portmask_P2L_get(pmask, pIgr_pmask) != RT_ERR_OK) -+ return RT_ERR_FAILED; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_stg_set -+ * Description: -+ * Set spanning tree group instance of the vlan to the specified device -+ * Input: -+ * vid - Specified VLAN ID. -+ * stg - spanning tree group instance. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_MSTI - Invalid msti parameter -+ * RT_ERR_INPUT - Invalid input parameter. -+ * RT_ERR_VLAN_VID - Invalid VID parameter. -+ * Note: -+ * The API can set spanning tree group instance of the vlan to the specified device. -+ */ -+rtk_api_ret_t rtk_vlan_stg_set(rtk_vlan_t vid, rtk_stp_msti_id_t stg) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_user_vlan4kentry vlan4K; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* vid must be 0~4095 */ -+ if (vid > RTL8367C_VIDMAX) -+ return RT_ERR_VLAN_VID; -+ -+ /* priority must be 0~15 */ -+ if (stg > RTL8367C_MSTIMAX) -+ return RT_ERR_MSTI; -+ -+ /* update 4K table */ -+ vlan4K.vid = vid; -+ if ((retVal = rtl8367c_getAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK) -+ return retVal; -+ -+ vlan4K.fid_msti= stg; -+ if ((retVal = rtl8367c_setAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_stg_get -+ * Description: -+ * Get spanning tree group instance of the vlan to the specified device -+ * Input: -+ * vid - Specified VLAN ID. -+ * Output: -+ * pStg - spanning tree group instance. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_VLAN_VID - Invalid VID parameter. -+ * Note: -+ * The API can get spanning tree group instance of the vlan to the specified device. -+ */ -+rtk_api_ret_t rtk_vlan_stg_get(rtk_vlan_t vid, rtk_stp_msti_id_t *pStg) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_user_vlan4kentry vlan4K; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* vid must be 0~4095 */ -+ if (vid > RTL8367C_VIDMAX) -+ return RT_ERR_VLAN_VID; -+ -+ if(NULL == pStg) -+ return RT_ERR_NULL_POINTER; -+ -+ /* update 4K table */ -+ vlan4K.vid = vid; -+ if ((retVal = rtl8367c_getAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK) -+ return retVal; -+ -+ *pStg = vlan4K.fid_msti; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_portFid_set -+ * Description: -+ * Set port-based filtering database -+ * Input: -+ * port - Port id. -+ * enable - enable port-based FID -+ * fid - Specified filtering database. -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_L2_FID - Invalid fid. -+ * RT_ERR_INPUT - Invalid input parameter. -+ * RT_ERR_PORT_ID - Invalid port ID. -+ * Note: -+ * The API can set port-based filtering database. If the function is enabled, all input -+ * packets will be assigned to the port-based fid regardless vlan tag. -+ */ -+rtk_api_ret_t rtk_vlan_portFid_set(rtk_port_t port, rtk_enable_t enable, rtk_fid_t fid) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (enable>=RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ /* fid must be 0~4095 */ -+ if (fid > RTK_FID_MAX) -+ return RT_ERR_L2_FID; -+ -+ if ((retVal = rtl8367c_setAsicPortBasedFidEn(rtk_switch_port_L2P_get(port), enable))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_setAsicPortBasedFid(rtk_switch_port_L2P_get(port), fid))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_portFid_get -+ * Description: -+ * Get port-based filtering database -+ * Input: -+ * port - Port id. -+ * Output: -+ * pEnable - enable port-based FID -+ * pFid - Specified filtering database. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Invalid input parameters. -+ * RT_ERR_PORT_ID - Invalid port ID. -+ * Note: -+ * The API can get port-based filtering database status. If the function is enabled, all input -+ * packets will be assigned to the port-based fid regardless vlan tag. -+ */ -+rtk_api_ret_t rtk_vlan_portFid_get(rtk_port_t port, rtk_enable_t *pEnable, rtk_fid_t *pFid) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if(NULL == pEnable) -+ return RT_ERR_NULL_POINTER; -+ -+ if(NULL == pFid) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicPortBasedFidEn(rtk_switch_port_L2P_get(port), pEnable))!=RT_ERR_OK) -+ return retVal; -+ -+ if ((retVal = rtl8367c_getAsicPortBasedFid(rtk_switch_port_L2P_get(port), pFid))!=RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_UntagDscpPriorityEnable_set -+ * Description: -+ * Set Untag DSCP priority assign -+ * Input: -+ * enable - state of Untag DSCP priority assign -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_ENABLE - Invalid input parameters. -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_vlan_UntagDscpPriorityEnable_set(rtk_enable_t enable) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(enable >= RTK_ENABLE_END) -+ return RT_ERR_ENABLE; -+ -+ if ((retVal = rtl8367c_setAsicVlanUntagDscpPriorityEn((rtk_uint32)enable)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_UntagDscpPriorityEnable_get -+ * Description: -+ * Get Untag DSCP priority assign -+ * Input: -+ * None -+ * Output: -+ * pEnable - state of Untag DSCP priority assign -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - Null pointer -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_vlan_UntagDscpPriorityEnable_get(rtk_enable_t *pEnable) -+{ -+ rtk_api_ret_t retVal; -+ rtk_uint32 value; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pEnable) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicVlanUntagDscpPriorityEn(&value)) != RT_ERR_OK) -+ return retVal; -+ -+ *pEnable = (rtk_enable_t)value; -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_stp_mstpState_set -+ * Description: -+ * Configure spanning tree state per each port. -+ * Input: -+ * port - Port id -+ * msti - Multiple spanning tree instance. -+ * stp_state - Spanning tree state for msti -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_MSTI - Invalid msti parameter. -+ * RT_ERR_MSTP_STATE - Invalid STP state. -+ * Note: -+ * System supports per-port multiple spanning tree state for each msti. -+ * There are four states supported by ASIC. -+ * - STP_STATE_DISABLED -+ * - STP_STATE_BLOCKING -+ * - STP_STATE_LEARNING -+ * - STP_STATE_FORWARDING -+ */ -+rtk_api_ret_t rtk_stp_mstpState_set(rtk_stp_msti_id_t msti, rtk_port_t port, rtk_stp_state_t stp_state) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (msti > RTK_MAX_NUM_OF_MSTI) -+ return RT_ERR_MSTI; -+ -+ if (stp_state >= STP_STATE_END) -+ return RT_ERR_MSTP_STATE; -+ -+ if ((retVal = rtl8367c_setAsicSpanningTreeStatus(rtk_switch_port_L2P_get(port), msti, stp_state)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_stp_mstpState_get -+ * Description: -+ * Get spanning tree state per each port. -+ * Input: -+ * port - Port id. -+ * msti - Multiple spanning tree instance. -+ * Output: -+ * pStp_state - Spanning tree state for msti -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_PORT_ID - Invalid port number. -+ * RT_ERR_MSTI - Invalid msti parameter. -+ * Note: -+ * System supports per-port multiple spanning tree state for each msti. -+ * There are four states supported by ASIC. -+ * - STP_STATE_DISABLED -+ * - STP_STATE_BLOCKING -+ * - STP_STATE_LEARNING -+ * - STP_STATE_FORWARDING -+ */ -+rtk_api_ret_t rtk_stp_mstpState_get(rtk_stp_msti_id_t msti, rtk_port_t port, rtk_stp_state_t *pStp_state) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* Check Port Valid */ -+ RTK_CHK_PORT_VALID(port); -+ -+ if (msti > RTK_MAX_NUM_OF_MSTI) -+ return RT_ERR_MSTI; -+ -+ if(NULL == pStp_state) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getAsicSpanningTreeStatus(rtk_switch_port_L2P_get(port), msti, pStp_state)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_checkAndCreateMbr -+ * Description: -+ * Check and create Member configuration and return index -+ * Input: -+ * vid - VLAN id. -+ * Output: -+ * pIndex - Member configuration index -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_VLAN_VID - Invalid VLAN ID. -+ * RT_ERR_VLAN_ENTRY_NOT_FOUND - VLAN not found -+ * RT_ERR_TBL_FULL - Member Configuration table full -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_vlan_checkAndCreateMbr(rtk_vlan_t vid, rtk_uint32 *pIndex) -+{ -+ rtk_api_ret_t retVal; -+ rtl8367c_user_vlan4kentry vlan4K; -+ rtl8367c_vlanconfiguser vlanMC; -+ rtk_uint32 idx; -+ rtk_uint32 empty_idx = 0xFFFF; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ /* vid must be 0~8191 */ -+ if (vid > RTL8367C_EVIDMAX) -+ return RT_ERR_VLAN_VID; -+ -+ /* Null pointer check */ -+ if(NULL == pIndex) -+ return RT_ERR_NULL_POINTER; -+ -+ /* Get 4K VLAN */ -+ if (vid <= RTL8367C_VIDMAX) -+ { -+ memset(&vlan4K, 0x00, sizeof(rtl8367c_user_vlan4kentry)); -+ vlan4K.vid = vid; -+ if ((retVal = rtl8367c_getAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ /* Search exist entry */ -+ for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++) -+ { -+ if(vlan_mbrCfgUsage[idx] == MBRCFG_USED_BY_VLAN) -+ { -+ if(vlan_mbrCfgVid[idx] == vid) -+ { -+ /* Found! return index */ -+ *pIndex = idx; -+ return RT_ERR_OK; -+ } -+ } -+ } -+ -+ /* Not found, Read H/W Member Configuration table to update database */ -+ for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++) -+ { -+ if ((retVal = rtl8367c_getAsicVlanMemberConfig(idx, &vlanMC)) != RT_ERR_OK) -+ return retVal; -+ -+ if( (vlanMC.evid == 0) && (vlanMC.mbr == 0x00)) -+ { -+ vlan_mbrCfgUsage[idx] = MBRCFG_UNUSED; -+ vlan_mbrCfgVid[idx] = 0; -+ } -+ else -+ { -+ vlan_mbrCfgUsage[idx] = MBRCFG_USED_BY_VLAN; -+ vlan_mbrCfgVid[idx] = vlanMC.evid; -+ } -+ } -+ -+ /* Search exist entry again */ -+ for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++) -+ { -+ if(vlan_mbrCfgUsage[idx] == MBRCFG_USED_BY_VLAN) -+ { -+ if(vlan_mbrCfgVid[idx] == vid) -+ { -+ /* Found! return index */ -+ *pIndex = idx; -+ return RT_ERR_OK; -+ } -+ } -+ } -+ -+ /* try to look up an empty index */ -+ for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++) -+ { -+ if(vlan_mbrCfgUsage[idx] == MBRCFG_UNUSED) -+ { -+ empty_idx = idx; -+ break; -+ } -+ } -+ -+ if(empty_idx == 0xFFFF) -+ { -+ /* No empty index */ -+ return RT_ERR_TBL_FULL; -+ } -+ -+ if (vid > RTL8367C_VIDMAX) -+ { -+ /* > 4K, there is no 4K entry, create on member configuration directly */ -+ memset(&vlanMC, 0x00, sizeof(rtl8367c_vlanconfiguser)); -+ vlanMC.evid = vid; -+ if ((retVal = rtl8367c_setAsicVlanMemberConfig(empty_idx, &vlanMC)) != RT_ERR_OK) -+ return retVal; -+ } -+ else -+ { -+ /* Copy from 4K table */ -+ vlanMC.evid = vid; -+ vlanMC.mbr = vlan4K.mbr; -+ vlanMC.fid_msti = vlan4K.fid_msti; -+ vlanMC.meteridx= vlan4K.meteridx; -+ vlanMC.envlanpol= vlan4K.envlanpol; -+ vlanMC.vbpen = vlan4K.vbpen; -+ vlanMC.vbpri = vlan4K.vbpri; -+ if ((retVal = rtl8367c_setAsicVlanMemberConfig(empty_idx, &vlanMC)) != RT_ERR_OK) -+ return retVal; -+ } -+ -+ /* Update Database */ -+ vlan_mbrCfgUsage[empty_idx] = MBRCFG_USED_BY_VLAN; -+ vlan_mbrCfgVid[empty_idx] = vid; -+ -+ *pIndex = empty_idx; -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_reservedVidAction_set -+ * Description: -+ * Set Action of VLAN ID = 0 & 4095 tagged packet -+ * Input: -+ * action_vid0 - Action for VID 0. -+ * action_vid4095 - Action for VID 4095. -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_vlan_reservedVidAction_set(rtk_vlan_resVidAction_t action_vid0, rtk_vlan_resVidAction_t action_vid4095) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(action_vid0 >= RESVID_ACTION_END) -+ return RT_ERR_INPUT; -+ -+ if(action_vid4095 >= RESVID_ACTION_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setReservedVidAction((rtk_uint32)action_vid0, (rtk_uint32)action_vid4095)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_reservedVidAction_get -+ * Description: -+ * Get Action of VLAN ID = 0 & 4095 tagged packet -+ * Input: -+ * pAction_vid0 - Action for VID 0. -+ * pAction_vid4095 - Action for VID 4095. -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_NULL_POINTER - NULL Pointer -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_vlan_reservedVidAction_get(rtk_vlan_resVidAction_t *pAction_vid0, rtk_vlan_resVidAction_t *pAction_vid4095) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(pAction_vid0 == NULL) -+ return RT_ERR_NULL_POINTER; -+ -+ if(pAction_vid4095 == NULL) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getReservedVidAction((rtk_uint32 *)pAction_vid0, (rtk_uint32 *)pAction_vid4095)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_realKeepRemarkEnable_set -+ * Description: -+ * Set Real keep 1p remarking feature -+ * Input: -+ * enabled - State of 1p remarking at real keep packet -+ * Output: -+ * None. -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_vlan_realKeepRemarkEnable_set(rtk_enable_t enabled) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(enabled >= RTK_ENABLE_END) -+ return RT_ERR_INPUT; -+ -+ if ((retVal = rtl8367c_setRealKeepRemarkEn((rtk_uint32)enabled)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_realKeepRemarkEnable_get -+ * Description: -+ * Get Real keep 1p remarking feature -+ * Input: -+ * None. -+ * Output: -+ * pEnabled - State of 1p remarking at real keep packet -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_vlan_realKeepRemarkEnable_get(rtk_enable_t *pEnabled) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if(NULL == pEnabled) -+ return RT_ERR_NULL_POINTER; -+ -+ if ((retVal = rtl8367c_getRealKeepRemarkEn((rtk_uint32 *)pEnabled)) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -+/* Function Name: -+ * rtk_vlan_reset -+ * Description: -+ * Reset VLAN -+ * Input: -+ * None. -+ * Output: -+ * pEnabled - State of 1p remarking at real keep packet -+ * Return: -+ * RT_ERR_OK - OK -+ * RT_ERR_FAILED - Failed -+ * RT_ERR_SMI - SMI access error -+ * RT_ERR_INPUT - Error Input -+ * Note: -+ * -+ */ -+rtk_api_ret_t rtk_vlan_reset(void) -+{ -+ rtk_api_ret_t retVal; -+ -+ /* Check initialization state */ -+ RTK_CHK_INIT_STATE(); -+ -+ if ((retVal = rtl8367c_resetVlan()) != RT_ERR_OK) -+ return retVal; -+ -+ return RT_ERR_OK; -+} -+ -diff --git a/drivers/net/phy/rtk/rtl8367s.c b/drivers/net/phy/rtk/rtl8367s.c -new file mode 100644 -index 000000000000..2988c8af56db ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367s.c -@@ -0,0 +1,580 @@ -+/* -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+//include from rtl8367c dir -+#include "./rtl8367c/include/rtk_switch.h" -+#include "./rtl8367c/include/vlan.h" -+#include "./rtl8367c/include/stat.h" -+#include "./rtl8367c/include/port.h" -+ -+#define RTL8367C_SW_CPU_PORT 6 -+ -+ //RTL8367C_PHY_PORT_NUM + ext0 + ext1 -+#define RTL8367C_NUM_PORTS 7 -+#define RTL8367C_NUM_VIDS 4096 -+ -+struct rtl8367_priv { -+ struct switch_dev swdev; -+ bool global_vlan_enable; -+}; -+ -+struct rtl8367_mib_counter { -+ const char *name; -+}; -+ -+struct rtl8367_vlan_info { -+ unsigned short vid; -+ unsigned int untag; -+ unsigned int member; -+ unsigned char fid; -+}; -+ -+struct rtl8367_priv rtl8367_priv_data; -+ -+unsigned int rtl8367c_port_id[RTL8367C_NUM_PORTS]={0,1,2,3,4,EXT_PORT1,EXT_PORT0}; -+ -+void (*rtl8367_switch_reset_func)(void)=NULL; -+ -+static struct rtl8367_mib_counter rtl8367c_mib_counters[] = { -+ {"ifInOctets"}, -+ {"dot3StatsFCSErrors"}, -+ {"dot3StatsSymbolErrors"}, -+ {"dot3InPauseFrames"}, -+ {"dot3ControlInUnknownOpcodes"}, -+ {"etherStatsFragments"}, -+ {"etherStatsJabbers"}, -+ {"ifInUcastPkts"}, -+ {"etherStatsDropEvents"}, -+ {"etherStatsOctets"}, -+ {"etherStatsUndersizePkts"}, -+ {"etherStatsOversizePkts"}, -+ {"etherStatsPkts64Octets"}, -+ {"etherStatsPkts65to127Octets"}, -+ {"etherStatsPkts128to255Octets"}, -+ {"etherStatsPkts256to511Octets"}, -+ {"etherStatsPkts512to1023Octets"}, -+ {"etherStatsPkts1024toMaxOctets"}, -+ {"etherStatsMcastPkts"}, -+ {"etherStatsBcastPkts"}, -+ {"ifOutOctets"}, -+ {"dot3StatsSingleCollisionFrames"}, -+ {"dot3StatsMultipleCollisionFrames"}, -+ {"dot3StatsDeferredTransmissions"}, -+ {"dot3StatsLateCollisions"}, -+ {"etherStatsCollisions"}, -+ {"dot3StatsExcessiveCollisions"}, -+ {"dot3OutPauseFrames"}, -+ {"dot1dBasePortDelayExceededDiscards"}, -+ {"dot1dTpPortInDiscards"}, -+ {"ifOutUcastPkts"}, -+ {"ifOutMulticastPkts"}, -+ {"ifOutBrocastPkts"}, -+ {"outOampduPkts"}, -+ {"inOampduPkts"}, -+ {"pktgenPkts"}, -+ {"inMldChecksumError"}, -+ {"inIgmpChecksumError"}, -+ {"inMldSpecificQuery"}, -+ {"inMldGeneralQuery"}, -+ {"inIgmpSpecificQuery"}, -+ {"inIgmpGeneralQuery"}, -+ {"inMldLeaves"}, -+ {"inIgmpLeaves"}, -+ {"inIgmpJoinsSuccess"}, -+ {"inIgmpJoinsFail"}, -+ {"inMldJoinsSuccess"}, -+ {"inMldJoinsFail"}, -+ {"inReportSuppressionDrop"}, -+ {"inLeaveSuppressionDrop"}, -+ {"outIgmpReports"}, -+ {"outIgmpLeaves"}, -+ {"outIgmpGeneralQuery"}, -+ {"outIgmpSpecificQuery"}, -+ {"outMldReports"}, -+ {"outMldLeaves"}, -+ {"outMldGeneralQuery"}, -+ {"outMldSpecificQuery"}, -+ {"inKnownMulticastPkts"}, -+ {"ifInMulticastPkts"}, -+ {"ifInBroadcastPkts"}, -+ {"ifOutDiscards"} -+}; -+ -+/*rtl8367c proprietary switch API wrapper */ -+static inline unsigned int rtl8367c_sw_to_phy_port(int port) -+{ -+ return rtl8367c_port_id[port]; -+} -+ -+static inline unsigned int rtl8367c_portmask_phy_to_sw(rtk_portmask_t phy_portmask) -+{ -+ int i; -+ for (i = 0; i < RTL8367C_NUM_PORTS; i++) { -+ if(RTK_PORTMASK_IS_PORT_SET(phy_portmask,rtl8367c_sw_to_phy_port(i))) { -+ RTK_PORTMASK_PORT_CLEAR(phy_portmask,rtl8367c_sw_to_phy_port(i)); -+ RTK_PORTMASK_PORT_SET(phy_portmask,i); -+ } -+ -+ } -+ return (unsigned int)phy_portmask.bits[0]; -+} -+ -+static int rtl8367c_reset_mibs(void) -+{ -+ return rtk_stat_global_reset(); -+} -+ -+static int rtl8367c_reset_port_mibs(int port) -+{ -+ -+ return rtk_stat_port_reset(rtl8367c_sw_to_phy_port(port)); -+} -+ -+static int rtl8367c_get_mibs_num(void) -+{ -+ return ARRAY_SIZE(rtl8367c_mib_counters); -+} -+ -+static const char *rtl8367c_get_mib_name(int idx) -+{ -+ -+ return rtl8367c_mib_counters[idx].name; -+} -+ -+static int rtl8367c_get_port_mib_counter(int idx, int port, unsigned long long *counter) -+{ -+ return rtk_stat_port_get(rtl8367c_sw_to_phy_port(port), idx, counter); -+} -+ -+static int rtl8367c_is_vlan_valid(unsigned int vlan) -+{ -+ unsigned max = RTL8367C_NUM_VIDS; -+ -+ if (vlan == 0 || vlan >= max) -+ return 0; -+ -+ return 1; -+} -+ -+static int rtl8367c_get_vlan( unsigned short vid, struct rtl8367_vlan_info *vlan) -+{ -+ rtk_vlan_cfg_t vlan_cfg; -+ -+ memset(vlan, '\0', sizeof(struct rtl8367_vlan_info)); -+ -+ if (vid >= RTL8367C_NUM_VIDS) -+ return -EINVAL; -+ -+ if(rtk_vlan_get(vid,&vlan_cfg)) -+ return -EINVAL; -+ -+ vlan->vid = vid; -+ vlan->member = rtl8367c_portmask_phy_to_sw(vlan_cfg.mbr); -+ vlan->untag = rtl8367c_portmask_phy_to_sw(vlan_cfg.untag); -+ vlan->fid = vlan_cfg.fid_msti; -+ -+ return 0; -+} -+ -+static int rtl8367c_set_vlan( unsigned short vid, u32 mbr, u32 untag, u8 fid) -+{ -+ rtk_vlan_cfg_t vlan_cfg; -+ int i; -+ -+ memset(&vlan_cfg, 0x00, sizeof(rtk_vlan_cfg_t)); -+ -+ for (i = 0; i < RTL8367C_NUM_PORTS; i++) { -+ if (mbr & (1 << i)) { -+ RTK_PORTMASK_PORT_SET(vlan_cfg.mbr, rtl8367c_sw_to_phy_port(i)); -+ if(untag & (1 << i)) -+ RTK_PORTMASK_PORT_SET(vlan_cfg.untag, rtl8367c_sw_to_phy_port(i)); -+ } -+ } -+ vlan_cfg.fid_msti=fid; -+ vlan_cfg.ivl_en = 1; -+ return rtk_vlan_set(vid, &vlan_cfg); -+} -+ -+ -+static int rtl8367c_get_pvid( int port, int *pvid) -+{ -+ u32 prio=0; -+ -+ if (port >= RTL8367C_NUM_PORTS) -+ return -EINVAL; -+ -+ return rtk_vlan_portPvid_get(rtl8367c_sw_to_phy_port(port),pvid,&prio); -+} -+ -+ -+static int rtl8367c_set_pvid( int port, int pvid) -+{ -+ u32 prio=0; -+ -+ if (port >= RTL8367C_NUM_PORTS) -+ return -EINVAL; -+ -+ return rtk_vlan_portPvid_set(rtl8367c_sw_to_phy_port(port),pvid,prio); -+} -+ -+static int rtl8367c_get_port_link(int port, int *link, int *speed, int *duplex) -+{ -+ -+ if(rtk_port_phyStatus_get(rtl8367c_sw_to_phy_port(port),(rtk_port_linkStatus_t *)link, -+ (rtk_port_speed_t *)speed,(rtk_port_duplex_t *)duplex)) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+/*common rtl8367 swconfig entry API*/ -+ -+static int -+rtl8367_sw_set_vlan_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8367_priv *priv = container_of(dev, struct rtl8367_priv, swdev); -+ -+ priv->global_vlan_enable = val->value.i ; -+ -+ return 0; -+} -+ -+static int -+rtl8367_sw_get_vlan_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8367_priv *priv = container_of(dev, struct rtl8367_priv, swdev); -+ -+ val->value.i = priv->global_vlan_enable; -+ -+ return 0; -+} -+ -+static int rtl8367_sw_reset_mibs(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ return rtl8367c_reset_mibs(); -+} -+ -+ -+static int rtl8367_sw_reset_port_mibs(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ int port; -+ -+ port = val->port_vlan; -+ if (port >= RTL8367C_NUM_PORTS) -+ return -EINVAL; -+ -+ return rtl8367c_reset_port_mibs(port); -+} -+ -+static int rtl8367_sw_get_port_mib(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ int i, len = 0; -+ unsigned long long counter = 0; -+ static char mib_buf[4096]; -+ -+ if (val->port_vlan >= RTL8367C_NUM_PORTS) -+ return -EINVAL; -+ -+ len += snprintf(mib_buf + len, sizeof(mib_buf) - len, -+ "Port %d MIB counters\n", -+ val->port_vlan); -+ -+ for (i = 0; i port_vlan, -+ &counter)) -+ len += snprintf(mib_buf + len, sizeof(mib_buf) - len, -+ "%llu\n", counter); -+ else -+ len += snprintf(mib_buf + len, sizeof(mib_buf) - len, -+ "%s\n", "N/A"); -+ } -+ -+ val->value.s = mib_buf; -+ val->len = len; -+ return 0; -+} -+ -+ -+static int rtl8367_sw_get_vlan_info(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ int i; -+ u32 len = 0; -+ struct rtl8367_vlan_info vlan; -+ static char vlan_buf[256]; -+ int err; -+ -+ if (!rtl8367c_is_vlan_valid(val->port_vlan)) -+ return -EINVAL; -+ -+ memset(vlan_buf, '\0', sizeof(vlan_buf)); -+ -+ err = rtl8367c_get_vlan(val->port_vlan, &vlan); -+ if (err) -+ return err; -+ -+ len += snprintf(vlan_buf + len, sizeof(vlan_buf) - len, -+ "VLAN %d: Ports: '", vlan.vid); -+ -+ for (i = 0; i value.s = vlan_buf; -+ val->len = len; -+ -+ return 0; -+} -+ -+ -+static int rtl8367_sw_get_vlan_ports(struct switch_dev *dev, struct switch_val *val) -+{ -+ struct switch_port *port; -+ struct rtl8367_vlan_info vlan; -+ int i; -+ -+ if (!rtl8367c_is_vlan_valid(val->port_vlan)) -+ return -EINVAL; -+ -+ if(rtl8367c_get_vlan(val->port_vlan, &vlan)) -+ return -EINVAL; -+ -+ port = &val->value.ports[0]; -+ val->len = 0; -+ for (i = 0; i id = i; -+ port->flags = (vlan.untag & BIT(i)) ? -+ 0 : BIT(SWITCH_PORT_FLAG_TAGGED); -+ val->len++; -+ port++; -+ } -+ return 0; -+} -+ -+ -+static int rtl8367_sw_set_vlan_ports(struct switch_dev *dev, struct switch_val *val) -+{ -+ struct switch_port *port; -+ u32 member = 0; -+ u32 untag = 0; -+ u8 fid=0; -+ int err; -+ int i; -+ -+ if (!rtl8367c_is_vlan_valid(val->port_vlan)) -+ return -EINVAL; -+ -+ port = &val->value.ports[0]; -+ for (i = 0; i < val->len; i++, port++) { -+ int pvid = 0; -+ member |= BIT(port->id); -+ -+ if (!(port->flags & BIT(SWITCH_PORT_FLAG_TAGGED))) -+ untag |= BIT(port->id); -+ -+ /* -+ * To ensure that we have a valid MC entry for this VLAN, -+ * initialize the port VLAN ID here. -+ */ -+ err = rtl8367c_get_pvid(port->id, &pvid); -+ if (err < 0) -+ return err; -+ if (pvid == 0) { -+ err = rtl8367c_set_pvid(port->id, val->port_vlan); -+ if (err < 0) -+ return err; -+ } -+ } -+ -+ //pr_info("[%s] vid=%d , mem=%x,untag=%x,fid=%d \n",__func__,val->port_vlan,member,untag,fid); -+ -+ return rtl8367c_set_vlan(val->port_vlan, member, untag, fid); -+ -+} -+ -+ -+static int rtl8367_sw_get_port_pvid(struct switch_dev *dev, int port, int *val) -+{ -+ return rtl8367c_get_pvid(port, val); -+} -+ -+ -+static int rtl8367_sw_set_port_pvid(struct switch_dev *dev, int port, int val) -+{ -+ return rtl8367c_set_pvid(port, val); -+} -+ -+ -+static int rtl8367_sw_reset_switch(struct switch_dev *dev) -+{ -+ if(rtl8367_switch_reset_func) -+ (*rtl8367_switch_reset_func)(); -+ else -+ printk("rest switch is not supported\n"); -+ -+ return 0; -+} -+ -+static int rtl8367_sw_get_port_link(struct switch_dev *dev, int port, -+ struct switch_port_link *link) -+{ -+ int speed; -+ -+ if (port >= RTL8367C_NUM_PORTS) -+ return -EINVAL; -+ -+ if(rtl8367c_get_port_link(port,(int *)&link->link,(int *)&speed,(int *)&link->duplex)) -+ return -EINVAL; -+ -+ if (!link->link) -+ return 0; -+ -+ switch (speed) { -+ case 0: -+ link->speed = SWITCH_PORT_SPEED_10; -+ break; -+ case 1: -+ link->speed = SWITCH_PORT_SPEED_100; -+ break; -+ case 2: -+ link->speed = SWITCH_PORT_SPEED_1000; -+ break; -+ default: -+ link->speed = SWITCH_PORT_SPEED_UNKNOWN; -+ break; -+ } -+ -+ return 0; -+} -+ -+ -+static struct switch_attr rtl8367_globals[] = { -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_vlan", -+ .description = "Enable VLAN mode", -+ .set = rtl8367_sw_set_vlan_enable, -+ .get = rtl8367_sw_get_vlan_enable, -+ .max = 1, -+ }, { -+ .type = SWITCH_TYPE_NOVAL, -+ .name = "reset_mibs", -+ .description = "Reset all MIB counters", -+ .set = rtl8367_sw_reset_mibs, -+ } -+}; -+ -+static struct switch_attr rtl8367_port[] = { -+ { -+ .type = SWITCH_TYPE_NOVAL, -+ .name = "reset_mib", -+ .description = "Reset single port MIB counters", -+ .set = rtl8367_sw_reset_port_mibs, -+ }, { -+ .type = SWITCH_TYPE_STRING, -+ .name = "mib", -+ .description = "Get MIB counters for port", -+ //.max = 33, -+ .set = NULL, -+ .get = rtl8367_sw_get_port_mib, -+ }, -+}; -+ -+static struct switch_attr rtl8367_vlan[] = { -+ { -+ .type = SWITCH_TYPE_STRING, -+ .name = "info", -+ .description = "Get vlan information", -+ .max = 1, -+ .set = NULL, -+ .get = rtl8367_sw_get_vlan_info, -+ }, -+}; -+ -+static const struct switch_dev_ops rtl8367_sw_ops = { -+ .attr_global = { -+ .attr = rtl8367_globals, -+ .n_attr = ARRAY_SIZE(rtl8367_globals), -+ }, -+ .attr_port = { -+ .attr = rtl8367_port, -+ .n_attr = ARRAY_SIZE(rtl8367_port), -+ }, -+ .attr_vlan = { -+ .attr = rtl8367_vlan, -+ .n_attr = ARRAY_SIZE(rtl8367_vlan), -+ }, -+ -+ .get_vlan_ports = rtl8367_sw_get_vlan_ports, -+ .set_vlan_ports = rtl8367_sw_set_vlan_ports, -+ .get_port_pvid = rtl8367_sw_get_port_pvid, -+ .set_port_pvid = rtl8367_sw_set_port_pvid, -+ .reset_switch = rtl8367_sw_reset_switch, -+ .get_port_link = rtl8367_sw_get_port_link, -+}; -+ -+int rtl8367s_swconfig_init(void (*reset_func)(void)) -+{ -+ struct rtl8367_priv *priv = &rtl8367_priv_data; -+ struct switch_dev *dev=&priv->swdev; -+ int err=0; -+ -+ rtl8367_switch_reset_func = reset_func ; -+ -+ memset(priv, 0, sizeof(struct rtl8367_priv)); -+ priv->global_vlan_enable =0; -+ -+ dev->name = "RTL8367C"; -+ dev->cpu_port = RTL8367C_SW_CPU_PORT; -+ dev->ports = RTL8367C_NUM_PORTS; -+ dev->vlans = RTL8367C_NUM_VIDS; -+ dev->ops = &rtl8367_sw_ops; -+ dev->alias = "RTL8367C"; -+ err = register_switch(dev, NULL); -+ -+ pr_info("[%s]\n",__func__); -+ -+ return err; -+} -diff --git a/drivers/net/phy/rtk/rtl8367s_dbg.c b/drivers/net/phy/rtk/rtl8367s_dbg.c -new file mode 100644 -index 000000000000..6bc9cbbf0638 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367s_dbg.c -@@ -0,0 +1,648 @@ -+#include -+#include -+#include -+#include -+#include -+ -+#include "./rtl8367c/include/rtk_switch.h" -+#include "./rtl8367c/include/port.h" -+#include "./rtl8367c/include/vlan.h" -+#include "./rtl8367c/include/rtl8367c_asicdrv_port.h" -+#include "./rtl8367c/include/stat.h" -+#include "./rtl8367c/include/l2.h" -+#include "./rtl8367c/include/smi.h" -+#include "./rtl8367c/include/mirror.h" -+#include "./rtl8367c/include/igmp.h" -+#include "./rtl8367c/include/leaky.h" -+ -+static struct proc_dir_entry *proc_reg_dir; -+static struct proc_dir_entry *proc_esw_cnt; -+static struct proc_dir_entry *proc_vlan_cnt; -+static struct proc_dir_entry *proc_mac_tbl; -+static struct proc_dir_entry *proc_reg; -+static struct proc_dir_entry *proc_phyreg; -+static struct proc_dir_entry *proc_mirror; -+static struct proc_dir_entry *proc_igmp; -+ -+#define PROCREG_ESW_CNT "esw_cnt" -+#define PROCREG_VLAN "vlan" -+#define PROCREG_MAC_TBL "mac_tbl" -+#define PROCREG_REG "reg" -+#define PROCREG_PHYREG "phyreg" -+#define PROCREG_MIRROR "mirror" -+#define PROCREG_IGMP "igmp" -+#define PROCREG_DIR "rtk_gsw" -+ -+#define RTK_SW_VID_RANGE 16 -+ -+static void rtk_dump_mib_type(rtk_stat_port_type_t cntr_idx) -+{ -+ rtk_port_t port; -+ rtk_stat_counter_t Cntr; -+ -+ for (port = UTP_PORT0; port < (UTP_PORT0 + 5); port++) { -+ rtk_stat_port_get(port, cntr_idx, &Cntr); -+ printk("%8llu", Cntr); -+ } -+ -+ for (port = EXT_PORT0; port < (EXT_PORT0 + 2); port++) { -+ rtk_stat_port_get(port, cntr_idx, &Cntr); -+ printk("%8llu", Cntr); -+ } -+ -+ printk("\n"); -+} -+static void rtk_hal_dump_mib(void) -+{ -+ -+ printk("==================%8s%8s%8s%8s%8s%8s%8s\n", "Port0", "Port1", -+ "Port2", "Port3", "Port4", "Port16", "Port17"); -+ /* Get TX Unicast Pkts */ -+ printk("TX Unicast Pkts :"); -+ rtk_dump_mib_type(STAT_IfOutUcastPkts); -+ /* Get TX Multicast Pkts */ -+ printk("TX Multicast Pkts:"); -+ rtk_dump_mib_type(STAT_IfOutMulticastPkts); -+ /* Get TX BroadCast Pkts */ -+ printk("TX BroadCast Pkts:"); -+ rtk_dump_mib_type(STAT_IfOutBroadcastPkts); -+ /* Get TX Collisions */ -+ /* Get TX Puase Frames */ -+ printk("TX Pause Frames :"); -+ rtk_dump_mib_type(STAT_Dot3OutPauseFrames); -+ /* Get TX Drop Events */ -+ /* Get RX Unicast Pkts */ -+ printk("RX Unicast Pkts :"); -+ rtk_dump_mib_type(STAT_IfInUcastPkts); -+ /* Get RX Multicast Pkts */ -+ printk("RX Multicast Pkts:"); -+ rtk_dump_mib_type(STAT_IfInMulticastPkts); -+ /* Get RX Broadcast Pkts */ -+ printk("RX Broadcast Pkts:"); -+ rtk_dump_mib_type(STAT_IfInBroadcastPkts); -+ /* Get RX FCS Erros */ -+ printk("RX FCS Errors :"); -+ rtk_dump_mib_type(STAT_Dot3StatsFCSErrors); -+ /* Get RX Undersize Pkts */ -+ printk("RX Undersize Pkts:"); -+ rtk_dump_mib_type(STAT_EtherStatsUnderSizePkts); -+ /* Get RX Discard Pkts */ -+ printk("RX Discard Pkts :"); -+ rtk_dump_mib_type(STAT_Dot1dTpPortInDiscards); -+ /* Get RX Fragments */ -+ printk("RX Fragments :"); -+ rtk_dump_mib_type(STAT_EtherStatsFragments); -+ /* Get RX Oversize Pkts */ -+ printk("RX Oversize Pkts :"); -+ rtk_dump_mib_type(STAT_EtherOversizeStats); -+ /* Get RX Jabbers */ -+ printk("RX Jabbers :"); -+ rtk_dump_mib_type(STAT_EtherStatsJabbers); -+ /* Get RX Pause Frames */ -+ printk("RX Pause Frames :"); -+ rtk_dump_mib_type(STAT_Dot3InPauseFrames); -+ /* clear MIB */ -+ rtk_stat_global_reset(); -+ -+} -+ -+static int rtk_hal_dump_vlan(void) -+{ -+ rtk_vlan_cfg_t vlan; -+ int i; -+ -+ printk("vid portmap\n"); -+ for (i = 0; i < RTK_SW_VID_RANGE; i++) { -+ rtk_vlan_get(i, &vlan); -+ printk("%3d ", i); -+ printk("%c", -+ RTK_PORTMASK_IS_PORT_SET(vlan.mbr, -+ UTP_PORT0) ? '1' : '-'); -+ printk("%c", -+ RTK_PORTMASK_IS_PORT_SET(vlan.mbr, -+ UTP_PORT1) ? '1' : '-'); -+ printk("%c", -+ RTK_PORTMASK_IS_PORT_SET(vlan.mbr, -+ UTP_PORT2) ? '1' : '-'); -+ printk("%c", -+ RTK_PORTMASK_IS_PORT_SET(vlan.mbr, -+ UTP_PORT3) ? '1' : '-'); -+ printk("%c", -+ RTK_PORTMASK_IS_PORT_SET(vlan.mbr, -+ UTP_PORT4) ? '1' : '-'); -+ printk("%c", -+ RTK_PORTMASK_IS_PORT_SET(vlan.mbr, -+ EXT_PORT0) ? '1' : '-'); -+ printk("%c", -+ RTK_PORTMASK_IS_PORT_SET(vlan.mbr, -+ EXT_PORT1) ? '1' : '-'); -+ printk("\n"); -+ } -+ -+ return 0; -+} -+ -+static void rtk_hal_dump_table(void) -+{ -+ rtk_uint32 i; -+ rtk_uint32 address = 0; -+ rtk_l2_ucastAddr_t l2_data; -+ rtk_l2_ipMcastAddr_t ipMcastAddr; -+ rtk_l2_age_time_t age_timout; -+ -+ rtk_l2_aging_get(&age_timout); -+ printk("Mac table age timeout =%d\n",(unsigned int)age_timout); -+ -+ printk("hash port(0:17) fid vid mac-address\n"); -+ while (1) { -+ if (rtk_l2_addr_next_get(READMETHOD_NEXT_L2UC, UTP_PORT0, &address, &l2_data) != RT_ERR_OK) { -+ break; -+ } else { -+ printk("%03x ", l2_data.address); -+ for (i = 0; i < 5; i++) -+ if ( l2_data.port == i) -+ printk("1"); -+ else -+ printk("-"); -+ for (i = 16; i < 18; i++) -+ if ( l2_data.port == i) -+ printk("1"); -+ else -+ printk("-"); -+ -+ printk(" %2d", l2_data.fid); -+ printk(" %4d", l2_data.cvid); -+ printk(" %02x%02x%02x%02x%02x%02x\n", l2_data.mac.octet[0], -+ l2_data.mac.octet[1], l2_data.mac.octet[2], l2_data.mac.octet[3], -+ l2_data.mac.octet[4], l2_data.mac.octet[5]); -+ address ++; -+ } -+ } -+ -+ address = 0; -+ while (1) { -+ if (rtk_l2_ipMcastAddr_next_get(&address, &ipMcastAddr) != RT_ERR_OK) { -+ break; -+ } else { -+ printk("%03x ", ipMcastAddr.address); -+ for (i = 0; i < 5; i++) -+ printk("%c", RTK_PORTMASK_IS_PORT_SET(ipMcastAddr.portmask, i) ? '1' : '-'); -+ for (i = 16; i < 18; i++) -+ printk("%c", RTK_PORTMASK_IS_PORT_SET(ipMcastAddr.portmask, i) ? '1' : '-'); -+ printk(" "); -+ printk("01005E%06x\n", (ipMcastAddr.dip & 0xefffff)); -+ address ++; -+ } -+ } -+} -+ -+static void rtk_hal_clear_table(void) -+{ -+ rtk_api_ret_t ret; -+ -+ ret = rtk_l2_table_clear(); -+ if (ret != RT_ERR_OK) -+ printk("rtk_l2_table_clear failed\n"); -+} -+ -+static void rtk_hal_read_reg(unsigned int reg_addr) -+{ -+ ret_t retVal; -+ unsigned int reg_val; -+ -+ retVal = smi_read(reg_addr, ®_val); -+ -+ if(retVal != RT_ERR_OK) -+ printk("switch reg read failed\n"); -+ else -+ printk("reg0x%x = 0x%x\n", reg_addr, reg_val); -+} -+ -+static void rtk_hal_write_reg(unsigned int reg_addr , unsigned int reg_val) -+{ -+ ret_t retVal; -+ -+ retVal = smi_write(reg_addr, reg_val); -+ -+ if(retVal != RT_ERR_OK) -+ printk("switch reg write failed\n"); -+ else -+ printk("write switch reg0x%x 0x%x success\n", reg_addr, reg_val); -+} -+ -+static void rtk_hal_get_phy_reg(unsigned int port ,unsigned int reg_addr ) -+{ -+ ret_t retVal; -+ rtk_port_phy_data_t Data; -+ -+ retVal = rtk_port_phyReg_get(port, reg_addr, &Data); -+ if (retVal == RT_ERR_OK) -+ printk("Get: phy[%d].reg[%d] = 0x%04x\n", port, reg_addr, Data); -+ else -+ printk("read phy reg failed\n"); -+} -+ -+static void rtk_hal_set_phy_reg(unsigned int port ,unsigned int reg_addr,unsigned int reg_val) -+{ -+ ret_t retVal; -+ -+ retVal = rtk_port_phyReg_set(port, reg_addr, reg_val); -+ if (retVal == RT_ERR_OK) -+ printk("Set: phy[%d].reg[%d] = 0x%04x\n", port, reg_addr, reg_val); -+ else -+ printk("write phy reg failed\n"); -+} -+ -+static void rtk_hal_set_port_mirror(unsigned int port ,unsigned int rx_port_map,unsigned int tx_port_map) -+{ -+ rtk_portmask_t rx_portmask; -+ rtk_portmask_t tx_portmask; -+ rtk_api_ret_t ret; -+ int i; -+ -+ rtk_mirror_portIso_set(ENABLED); -+ RTK_PORTMASK_CLEAR(rx_portmask); -+ RTK_PORTMASK_CLEAR(tx_portmask); -+ -+ for (i = 0; i < 5; i++) -+ if (rx_port_map & (1 << i)) -+ RTK_PORTMASK_PORT_SET(rx_portmask, i); -+ -+ for (i = 0; i < 2; i++) -+ if (rx_port_map & (1 << (i + 5))) -+ RTK_PORTMASK_PORT_SET(rx_portmask, (i + EXT_PORT0)); -+ -+ RTK_PORTMASK_CLEAR(tx_portmask); -+ -+ for (i = 0; i < 5; i++) -+ if (tx_port_map & (1 << i)) -+ RTK_PORTMASK_PORT_SET(tx_portmask, i); -+ -+ for (i = 0; i < 2; i++) -+ if (tx_port_map & (1 << (i + 5))) -+ RTK_PORTMASK_PORT_SET(tx_portmask, (i + EXT_PORT0)); -+ -+ ret = rtk_mirror_portBased_set(port, &rx_portmask, &tx_portmask); -+ -+ if (!ret) -+ printk("rtk_mirror_portBased_set success\n"); -+ -+} -+ -+static void rtk_hal_enable_igmpsnoop(int hw_on) -+{ -+ rtk_api_ret_t ret; -+ rtk_portmask_t pmask; -+ -+ ret = rtk_igmp_init(); -+ if (hw_on == 1) { -+ RTK_PORTMASK_CLEAR(pmask); -+ RTK_PORTMASK_PORT_SET(pmask, EXT_PORT0); -+ ret |= rtk_igmp_static_router_port_set(&pmask); -+ ret |= rtk_igmp_protocol_set(UTP_PORT4, PROTOCOL_IGMPv1, IGMP_ACTION_FORWARD); -+ ret |= rtk_igmp_protocol_set(UTP_PORT4, PROTOCOL_IGMPv2, IGMP_ACTION_FORWARD); -+ ret |= rtk_igmp_protocol_set(UTP_PORT4, PROTOCOL_MLDv1, IGMP_ACTION_FORWARD); -+ ret |= rtk_igmp_protocol_set(EXT_PORT1, PROTOCOL_IGMPv1, IGMP_ACTION_FORWARD); -+ ret |= rtk_igmp_protocol_set(EXT_PORT1, PROTOCOL_IGMPv2, IGMP_ACTION_FORWARD); -+ ret |= rtk_igmp_protocol_set(EXT_PORT1, PROTOCOL_MLDv1, IGMP_ACTION_FORWARD); -+ ret |= rtk_igmp_protocol_set(UTP_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); -+ ret |= rtk_igmp_protocol_set(UTP_PORT1, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); -+ ret |= rtk_igmp_protocol_set(UTP_PORT2, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); -+ ret |= rtk_igmp_protocol_set(UTP_PORT3, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); -+ ret |= rtk_igmp_protocol_set(EXT_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); -+ -+ ret |= rtk_leaky_vlan_set(LEAKY_IPMULTICAST, ENABLED); -+ ret |= rtk_l2_ipMcastForwardRouterPort_set(DISABLED); -+ /* drop unknown multicast packets*/ -+ /* ret |= rtk_trap_unknownMcastPktAction_set(UTP_PORT4, MCAST_IPV4, MCAST_ACTION_DROP);*/ -+ } else { -+ RTK_PORTMASK_CLEAR(pmask); -+ RTK_PORTMASK_PORT_SET(pmask, EXT_PORT0); -+ RTK_PORTMASK_PORT_SET(pmask, EXT_PORT1); -+ ret |= rtk_igmp_protocol_set(UTP_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); -+ ret |= rtk_igmp_protocol_set(UTP_PORT1, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); -+ ret |= rtk_igmp_protocol_set(UTP_PORT2, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); -+ ret |= rtk_igmp_protocol_set(UTP_PORT3, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); -+ ret |= rtk_igmp_protocol_set(EXT_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); -+ -+ ret |= rtk_igmp_static_router_port_set(&pmask); -+ } -+ -+ if(ret != RT_ERR_OK) -+ printk("enable switch igmpsnoop failed\n"); -+ -+} -+ -+static void rtk_hal_disable_igmpsnoop(void) -+{ -+ if (rtk_igmp_state_set(DISABLED) != RT_ERR_OK) -+ printk("Disable IGMP SNOOPING failed\n"); -+} -+ -+static ssize_t mac_tbl_write(struct file *file, -+ const char __user *buffer, size_t count, -+ loff_t *data) -+{ -+ rtk_hal_clear_table(); -+ -+ return count; -+} -+ -+ -+static ssize_t phyreg_ops(struct file *file, -+ const char __user *buffer, size_t count, -+ loff_t *data) -+{ -+ char buf[64]; -+ unsigned int port; -+ unsigned int offset; -+ unsigned int val; -+ -+ memset(buf, 0, 64); -+ -+ if (copy_from_user(buf, buffer, count)) -+ return -EFAULT; -+ -+ -+ if(buf[0] == 'w') { -+ -+ if(sscanf(buf, "w %d %x %x", &port,&offset,&val) == -1) -+ return -EFAULT; -+ else -+ rtk_hal_set_phy_reg(port,offset,val); -+ -+ } else { -+ -+ if(sscanf(buf, "r %d %x",&port, &offset) == -1) -+ return -EFAULT; -+ else -+ rtk_hal_get_phy_reg(port,offset); -+ } -+ -+ return count; -+} -+ -+static ssize_t reg_ops(struct file *file, -+ const char __user *buffer, size_t count, -+ loff_t *data) -+{ -+ char buf[64]; -+ unsigned int offset; -+ unsigned int val; -+ -+ memset(buf, 0, 64); -+ -+ if (copy_from_user(buf, buffer, count)) -+ return -EFAULT; -+ -+ -+ if(buf[0] == 'w') { -+ -+ if(sscanf(buf, "w %x %x", &offset,&val) == -1) -+ return -EFAULT; -+ else -+ rtk_hal_write_reg(offset,val); -+ -+ } else { -+ -+ if(sscanf(buf, "r %x", &offset) == -1) -+ return -EFAULT; -+ else -+ rtk_hal_read_reg(offset); -+ } -+ -+ return count; -+} -+ -+static ssize_t mirror_ops(struct file *file, -+ const char __user *buffer, size_t count, -+ loff_t *data) -+{ -+ char buf[64]; -+ unsigned int port; -+ unsigned int tx_map,rx_map; -+ -+ memset(buf, 0, 64); -+ -+ if (copy_from_user(buf, buffer, count)) -+ return -EFAULT; -+ -+ if(sscanf(buf, "%d %x %x", &port,&rx_map,&tx_map) == -1) -+ return -EFAULT; -+ else -+ rtk_hal_set_port_mirror(port,rx_map,tx_map); -+ -+ return count; -+} -+ -+ -+static ssize_t igmp_ops(struct file *file, -+ const char __user *buffer, size_t count, -+ loff_t *data) -+{ -+ char buf[8]; -+ unsigned int ops; -+ -+ if (copy_from_user(buf, buffer, count)) -+ return -EFAULT; -+ -+ if(sscanf(buf, "%d", &ops) == -1) -+ return -EFAULT; -+ -+ if(ops == 0) -+ rtk_hal_disable_igmpsnoop(); -+ else if (ops == 1) -+ rtk_hal_enable_igmpsnoop(0); -+ else //hw igmp -+ rtk_hal_enable_igmpsnoop(1); -+ -+ return count; -+} -+ -+ -+static int esw_cnt_read(struct seq_file *seq, void *v) -+{ -+ rtk_hal_dump_mib(); -+ return 0; -+} -+ -+static int vlan_read(struct seq_file *seq, void *v) -+{ -+ rtk_hal_dump_vlan(); -+ return 0; -+} -+ -+static int mac_tbl_read(struct seq_file *seq, void *v) -+{ -+ rtk_hal_dump_table(); -+ return 0; -+} -+ -+static int reg_show(struct seq_file *seq, void *v) -+{ -+ return 0; -+} -+ -+static int phyreg_show(struct seq_file *seq, void *v) -+{ -+ return 0; -+} -+ -+static int mirror_show(struct seq_file *seq, void *v) -+{ -+ return 0; -+} -+ -+static int igmp_show(struct seq_file *seq, void *v) -+{ -+ return 0; -+} -+ -+static int switch_count_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, esw_cnt_read, 0); -+} -+ -+static int switch_vlan_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, vlan_read, 0); -+} -+ -+static int mac_tbl_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, mac_tbl_read, 0); -+} -+ -+static int reg_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, reg_show, 0); -+} -+ -+static int phyreg_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, phyreg_show, 0); -+} -+ -+static int mirror_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, mirror_show, 0); -+} -+ -+static int igmp_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, igmp_show, 0); -+} -+ -+ -+static const struct proc_ops switch_count_fops = { -+ .proc_open = switch_count_open, -+ .proc_read = seq_read, -+ .proc_lseek = seq_lseek, -+ .proc_release = single_release -+}; -+ -+static const struct proc_ops switch_vlan_fops = { -+ .proc_open = switch_vlan_open, -+ .proc_read = seq_read, -+ .proc_lseek = seq_lseek, -+ .proc_release = single_release -+}; -+ -+static const struct proc_ops mac_tbl_fops = { -+ .proc_open = mac_tbl_open, -+ .proc_read = seq_read, -+ .proc_lseek = seq_lseek, -+ .proc_write = mac_tbl_write, -+ .proc_release = single_release -+}; -+ -+static const struct proc_ops reg_fops = { -+ .proc_open = reg_open, -+ .proc_read = seq_read, -+ .proc_lseek = seq_lseek, -+ .proc_write = reg_ops, -+ .proc_release = single_release -+}; -+ -+static const struct proc_ops phyreg_fops = { -+ .proc_open = phyreg_open, -+ .proc_read = seq_read, -+ .proc_lseek = seq_lseek, -+ .proc_write = phyreg_ops, -+ .proc_release = single_release -+}; -+ -+static const struct proc_ops mirror_fops = { -+ .proc_open = mirror_open, -+ .proc_read = seq_read, -+ .proc_lseek = seq_lseek, -+ .proc_write = mirror_ops, -+ .proc_release = single_release -+}; -+ -+static const struct proc_ops igmp_fops = { -+ .proc_open = igmp_open, -+ .proc_read = seq_read, -+ .proc_lseek = seq_lseek, -+ .proc_write = igmp_ops, -+ .proc_release = single_release -+}; -+ -+int gsw_debug_proc_init(void) -+{ -+ -+ if (!proc_reg_dir) -+ proc_reg_dir = proc_mkdir(PROCREG_DIR, NULL); -+ -+ proc_esw_cnt = -+ proc_create(PROCREG_ESW_CNT, 0, proc_reg_dir, &switch_count_fops); -+ -+ if (!proc_esw_cnt) -+ pr_err("!! FAIL to create %s PROC !!\n", PROCREG_ESW_CNT); -+ -+ proc_vlan_cnt = -+ proc_create(PROCREG_VLAN, 0, proc_reg_dir, &switch_vlan_fops); -+ -+ if (!proc_vlan_cnt) -+ pr_err("!! FAIL to create %s PROC !!\n", PROCREG_VLAN); -+ -+ proc_mac_tbl = -+ proc_create(PROCREG_MAC_TBL, 0, proc_reg_dir, &mac_tbl_fops); -+ -+ if (!proc_mac_tbl) -+ pr_err("!! FAIL to create %s PROC !!\n", PROCREG_MAC_TBL); -+ -+ proc_reg = -+ proc_create(PROCREG_REG, 0, proc_reg_dir, ®_fops); -+ -+ if (!proc_reg) -+ pr_err("!! FAIL to create %s PROC !!\n", PROCREG_REG); -+ -+ proc_phyreg = -+ proc_create(PROCREG_PHYREG, 0, proc_reg_dir, &phyreg_fops); -+ -+ if (!proc_phyreg) -+ pr_err("!! FAIL to create %s PROC !!\n", PROCREG_PHYREG); -+ -+ proc_mirror = -+ proc_create(PROCREG_MIRROR, 0, proc_reg_dir, &mirror_fops); -+ -+ if (!proc_mirror) -+ pr_err("!! FAIL to create %s PROC !!\n", PROCREG_MIRROR); -+ -+ proc_igmp = -+ proc_create(PROCREG_IGMP, 0, proc_reg_dir, &igmp_fops); -+ -+ if (!proc_igmp) -+ pr_err("!! FAIL to create %s PROC !!\n", PROCREG_IGMP); -+ -+ return 0; -+} -+ -+void gsw_debug_proc_exit(void) -+{ -+ if (proc_esw_cnt) -+ remove_proc_entry(PROCREG_ESW_CNT, proc_reg_dir); -+} -+ -+ -diff --git a/drivers/net/phy/rtk/rtl8367s_mdio.c b/drivers/net/phy/rtk/rtl8367s_mdio.c -new file mode 100644 -index 000000000000..2f9dc0da6bc1 ---- /dev/null -+++ b/drivers/net/phy/rtk/rtl8367s_mdio.c -@@ -0,0 +1,301 @@ -+/* -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+ -+#include "./rtl8367c/include/rtk_switch.h" -+#include "./rtl8367c/include/port.h" -+#include "./rtl8367c/include/vlan.h" -+#include "./rtl8367c/include/rtl8367c_asicdrv_port.h" -+#include "./rtl8367c/include/rtl8367c_asicdrv_mii_mgr.h" -+ -+struct rtk_gsw { -+ struct device *dev; -+ struct mii_bus *bus; -+ int reset_pin; -+}; -+ -+static struct rtk_gsw *_gsw; -+ -+/*mii_mgr_read/mii_mgr_write is the callback API for rtl8367 driver*/ -+unsigned int mii_mgr_read(unsigned int phy_addr,unsigned int phy_register,unsigned int *read_data) -+{ -+ struct mii_bus *bus = _gsw->bus; -+ -+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ -+ *read_data = bus->read(bus, phy_addr, phy_register); -+ -+ mutex_unlock(&bus->mdio_lock); -+ -+ return 0; -+} -+ -+unsigned int mii_mgr_write(unsigned int phy_addr,unsigned int phy_register,unsigned int write_data) -+{ -+ struct mii_bus *bus = _gsw->bus; -+ -+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ -+ bus->write(bus, phy_addr, phy_register, write_data); -+ -+ mutex_unlock(&bus->mdio_lock); -+ -+ return 0; -+} -+ -+static int rtl8367s_hw_reset(void) -+{ -+ struct rtk_gsw *gsw = _gsw; -+ -+ if (gsw->reset_pin < 0) -+ return 0; -+ -+ gpio_direction_output(gsw->reset_pin, 0); -+ -+ usleep_range(1000, 1100); -+ -+ gpio_set_value(gsw->reset_pin, 1); -+ -+ mdelay(500); -+ -+ return 0; -+} -+ -+static int rtl8367s_vlan_config(int want_at_p0) -+{ -+ rtk_vlan_cfg_t vlan1, vlan2; -+ -+ /* Set LAN/WAN VLAN partition */ -+ memset(&vlan1, 0x00, sizeof(rtk_vlan_cfg_t)); -+ -+ RTK_PORTMASK_PORT_SET(vlan1.mbr, EXT_PORT0); -+ RTK_PORTMASK_PORT_SET(vlan1.mbr, UTP_PORT1); -+ RTK_PORTMASK_PORT_SET(vlan1.mbr, UTP_PORT2); -+ RTK_PORTMASK_PORT_SET(vlan1.mbr, UTP_PORT3); -+ RTK_PORTMASK_PORT_SET(vlan1.untag, EXT_PORT0); -+ RTK_PORTMASK_PORT_SET(vlan1.untag, UTP_PORT1); -+ RTK_PORTMASK_PORT_SET(vlan1.untag, UTP_PORT2); -+ RTK_PORTMASK_PORT_SET(vlan1.untag, UTP_PORT3); -+ -+ if (want_at_p0) { -+ RTK_PORTMASK_PORT_SET(vlan1.mbr, UTP_PORT4); -+ RTK_PORTMASK_PORT_SET(vlan1.untag, UTP_PORT4); -+ } else { -+ RTK_PORTMASK_PORT_SET(vlan1.mbr, UTP_PORT0); -+ RTK_PORTMASK_PORT_SET(vlan1.untag, UTP_PORT0); -+ } -+ -+ vlan1.ivl_en = 1; -+ -+ rtk_vlan_set(1, &vlan1); -+ -+ memset(&vlan2, 0x00, sizeof(rtk_vlan_cfg_t)); -+ -+ RTK_PORTMASK_PORT_SET(vlan2.mbr, EXT_PORT1); -+ RTK_PORTMASK_PORT_SET(vlan2.untag, EXT_PORT1); -+ -+ if (want_at_p0) { -+ RTK_PORTMASK_PORT_SET(vlan2.mbr, UTP_PORT0); -+ RTK_PORTMASK_PORT_SET(vlan2.untag, UTP_PORT0); -+ } else { -+ RTK_PORTMASK_PORT_SET(vlan2.mbr, UTP_PORT4); -+ RTK_PORTMASK_PORT_SET(vlan2.untag, UTP_PORT4); -+ } -+ -+ vlan2.ivl_en = 1; -+ rtk_vlan_set(2, &vlan2); -+ -+ rtk_vlan_portPvid_set(EXT_PORT0, 1, 0); -+ rtk_vlan_portPvid_set(UTP_PORT1, 1, 0); -+ rtk_vlan_portPvid_set(UTP_PORT2, 1, 0); -+ rtk_vlan_portPvid_set(UTP_PORT3, 1, 0); -+ rtk_vlan_portPvid_set(EXT_PORT1, 2, 0); -+ -+ if (want_at_p0) { -+ rtk_vlan_portPvid_set(UTP_PORT0, 2, 0); -+ rtk_vlan_portPvid_set(UTP_PORT4, 1, 0); -+ } else { -+ rtk_vlan_portPvid_set(UTP_PORT0, 1, 0); -+ rtk_vlan_portPvid_set(UTP_PORT4, 2, 0); -+ } -+ -+ return 0; -+} -+ -+static int rtl8367s_hw_init(void) -+{ -+ -+ rtl8367s_hw_reset(); -+ -+ if(rtk_switch_init()) -+ return -1; -+ -+ mdelay(500); -+ -+ if (rtk_vlan_reset()) -+ return -1; -+ -+ if (rtk_vlan_init()) -+ return -1; -+ -+ return 0; -+} -+ -+static void set_rtl8367s_sgmii(void) -+{ -+ rtk_port_mac_ability_t mac_cfg; -+ rtk_mode_ext_t mode; -+ -+ mode = MODE_EXT_HSGMII; -+ mac_cfg.forcemode = MAC_FORCE; -+ mac_cfg.speed = PORT_SPEED_2500M; -+ mac_cfg.duplex = PORT_FULL_DUPLEX; -+ mac_cfg.link = PORT_LINKUP; -+ mac_cfg.nway = DISABLED; -+ mac_cfg.txpause = ENABLED; -+ mac_cfg.rxpause = ENABLED; -+ rtk_port_macForceLinkExt_set(EXT_PORT0, mode, &mac_cfg); -+ rtk_port_sgmiiNway_set(EXT_PORT0, DISABLED); -+ rtk_port_phyEnableAll_set(ENABLED); -+ -+} -+ -+static void set_rtl8367s_rgmii(void) -+{ -+ rtk_port_mac_ability_t mac_cfg; -+ rtk_mode_ext_t mode; -+ -+ mode = MODE_EXT_RGMII; -+ mac_cfg.forcemode = MAC_FORCE; -+ mac_cfg.speed = PORT_SPEED_1000M; -+ mac_cfg.duplex = PORT_FULL_DUPLEX; -+ mac_cfg.link = PORT_LINKUP; -+ mac_cfg.nway = DISABLED; -+ mac_cfg.txpause = ENABLED; -+ mac_cfg.rxpause = ENABLED; -+ rtk_port_macForceLinkExt_set(EXT_PORT1, mode, &mac_cfg); -+ rtk_port_rgmiiDelayExt_set(EXT_PORT1, 1, 3); -+ rtk_port_phyEnableAll_set(ENABLED); -+ -+} -+ -+static void init_gsw(void) -+{ -+ rtl8367s_hw_init(); -+ set_rtl8367s_sgmii(); -+ set_rtl8367s_rgmii(); -+} -+ -+// below are platform driver -+static const struct of_device_id rtk_gsw_match[] = { -+ { .compatible = "mediatek,rtk-gsw" }, -+ {}, -+}; -+ -+MODULE_DEVICE_TABLE(of, rtk_gsw_match); -+ -+static int rtk_gsw_probe(struct platform_device *pdev) -+{ -+ struct device_node *np = pdev->dev.of_node; -+ struct device_node *mdio; -+ struct mii_bus *mdio_bus; -+ struct rtk_gsw *gsw; -+ const char *pm; -+ int ret; -+ -+ mdio = of_parse_phandle(np, "mediatek,mdio", 0); -+ -+ if (!mdio) -+ return -EINVAL; -+ -+ mdio_bus = of_mdio_find_bus(mdio); -+ -+ if (!mdio_bus) -+ return -EPROBE_DEFER; -+ -+ gsw = devm_kzalloc(&pdev->dev, sizeof(struct rtk_gsw), GFP_KERNEL); -+ -+ if (!gsw) -+ return -ENOMEM; -+ -+ gsw->dev = &pdev->dev; -+ -+ gsw->bus = mdio_bus; -+ -+ gsw->reset_pin = of_get_named_gpio(np, "mediatek,reset-pin", 0); -+ if (gsw->reset_pin >= 0) { -+ ret = devm_gpio_request(gsw->dev, gsw->reset_pin, "mediatek,reset-pin"); -+ if (ret) -+ printk("fail to devm_gpio_request\n"); -+ } -+ -+ _gsw = gsw; -+ -+ init_gsw(); -+ -+ //init default vlan or init swconfig -+ if(!of_property_read_string(pdev->dev.of_node, -+ "mediatek,port_map", &pm)) { -+ -+ if (!strcasecmp(pm, "wllll")) -+ rtl8367s_vlan_config(1); -+ else -+ rtl8367s_vlan_config(0); -+ -+ } else { -+#ifdef CONFIG_SWCONFIG -+ rtl8367s_swconfig_init(&init_gsw); -+#else -+ rtl8367s_vlan_config(0); -+#endif -+ } -+ -+ gsw_debug_proc_init(); -+ -+ platform_set_drvdata(pdev, gsw); -+ -+ return 0; -+ -+} -+ -+static void rtk_gsw_remove(struct platform_device *pdev) -+{ -+ platform_set_drvdata(pdev, NULL); -+ gsw_debug_proc_exit(); -+} -+ -+static struct platform_driver gsw_driver = { -+ .probe = rtk_gsw_probe, -+ .remove_new = rtk_gsw_remove, -+ .driver = { -+ .name = "rtk-gsw", -+ .of_match_table = rtk_gsw_match, -+ }, -+}; -+ -+module_platform_driver(gsw_driver); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Mark Lee "); -+MODULE_DESCRIPTION("rtl8367c switch driver for MT7622"); -+ -diff --git a/drivers/net/phy/rtl8261n/Kconfig b/drivers/net/phy/rtl8261n/Kconfig -new file mode 100644 -index 000000000000..cdb5cb74882a ---- /dev/null -+++ b/drivers/net/phy/rtl8261n/Kconfig -@@ -0,0 +1,5 @@ -+ -+config RTL8261N_PHY -+ tristate "Driver for Realtek RTL8261N PHYs" -+ help -+ Currently supports the RTL8261N,RTL8264B PHYs. -diff --git a/drivers/net/phy/rtl8261n/Makefile b/drivers/net/phy/rtl8261n/Makefile -new file mode 100644 -index 000000000000..fd4afb43b509 ---- /dev/null -+++ b/drivers/net/phy/rtl8261n/Makefile -@@ -0,0 +1,11 @@ -+ -+obj-$(CONFIG_RTL8261N_PHY) += rtl8261n.o -+ -+rtl8261n-objs += phy_patch.o -+rtl8261n-objs += phy_rtl826xb_patch.o -+rtl8261n-objs += rtk_osal.o -+rtl8261n-objs += rtk_phy.o -+rtl8261n-objs += rtk_phylib.o -+rtl8261n-objs += rtk_phylib_rtl826xb.o -+ -+ccflags-y += -Werror -DRTK_PHYDRV_IN_LINUX -diff --git a/drivers/net/phy/rtl8261n/construct/conf_rtl8261n_c.c b/drivers/net/phy/rtl8261n/construct/conf_rtl8261n_c.c -new file mode 100644 -index 000000000000..8e7c714fc401 ---- /dev/null -+++ b/drivers/net/phy/rtl8261n/construct/conf_rtl8261n_c.c -@@ -0,0 +1,1465 @@ -+/* -+ * SPDX-License-Identifier: GPL-2.0-only -+ * -+ * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. -+ */ -+ -+//Date: Tue Nov 15 19:53:03 2022 -+ -+rtk_hwpatch_t rtl8261n_c_top_conf[] = { -+ {RTK_PATCH_OP_TOP , 0xf , 2 , 20 , 15, 0 , 0x5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 2 , 21 , 15, 0 , 0x0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 2 , 22 , 15, 0 , 0x280 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 2 , 23 , 15, 0 , 0x0014, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 3 , 16 , 15, 0 , 0x0300, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 3 , 17 , 15, 0 , 0x01ff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 3 , 18 , 15, 0 , 0x000c, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 3 , 19 , 15, 0 , 0x01ff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 3 , 20 , 15, 0 , 0x0200, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 3 , 21 , 15, 0 , 0x0015, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 3 , 22 , 15, 0 , 0x0200, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 3 , 23 , 15, 0 , 0x0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 4 , 16 , 15, 0 , 0x0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 13 , 23 , 8 , 5 , 0x6 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 90 , 18 , 15, 0 , 0x5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 90 , 19 , 15, 0 , 0x5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 90 , 20 , 15, 8 , 0x01 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+}; -+ -+rtk_hwpatch_t rtl8261n_c_sds_conf[] = { -+ {RTK_PATCH_OP_TOP , 0xf , 24 , 18 , 15, 0 , 0x881F, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 24 , 19 , 15, 0 , 0x003F, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 24 , 20 , 15, 0 , 0x003F, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 24 , 21 , 15, 0 , 0x003F, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 24 , 22 , 15, 0 , 0x001F, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x06 , 0x0D , 15, 0 , 0x0F00, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x06 , 0x0E , 15, 0 , 0x3F5A, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x07 , 0x10 , 15, 12, 0x8 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x07 , 0x10 , 7 , 0 , 0x3 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x06 , 0x1D , 15, 0 , 0x0600, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x21 , 0x00 , 15, 0 , 0x4902, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x21 , 0x08 , 15, 0 , 0x0FC0, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x21 , 0x09 , 15, 0 , 0x33F0, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x21 , 0x0C , 15, 0 , 0x08BF, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x21 , 0x12 , 15, 0 , 0x8000, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x36 , 0x07 , 15, 0 , 0x04C0, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x36 , 0x08 , 15, 0 , 0x2000, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2E , 0x0B , 15, 0 , 0x2390, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2E , 0x0C , 15, 0 , 0xAA17, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2E , 0x0D , 15, 0 , 0xFE40, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2E , 0x0E , 15, 0 , 0x12F4, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2E , 0x11 , 15, 0 , 0xF2AD, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2E , 0x15 , 15, 0 , 0x7A41, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2E , 0x16 , 15, 0 , 0x0041, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2F , 0x00 , 15, 0 , 0x1F00, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2F , 0x01 , 15, 0 , 0x2800, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2F , 0x02 , 15, 0 , 0x0FC8, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2F , 0x11 , 15, 0 , 0x3000, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2F , 0x13 , 15, 0 , 0xF400, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2F , 0x1E , 15, 0 , 0x0500, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x34 , 0x0B , 15, 0 , 0x2390, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x34 , 0x0C , 15, 0 , 0xA517, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x34 , 0x0D , 15, 0 , 0xFE41, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x34 , 0x0E , 15, 0 , 0x12F4, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x34 , 0x11 , 15, 0 , 0xF2AD, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x34 , 0x15 , 15, 0 , 0x7A41, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x34 , 0x16 , 15, 0 , 0x0041, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x35 , 0x00 , 15, 0 , 0x1F80, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x35 , 0x01 , 15, 0 , 0x0800, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x35 , 0x02 , 15, 0 , 0x0FC8, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x35 , 0x11 , 15, 0 , 0x3001, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x35 , 0x13 , 15, 0 , 0xF400, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x35 , 0x1E , 15, 0 , 0x0100, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2C , 0x0B , 15, 0 , 0x2390, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2C , 0x0C , 15, 0 , 0xA517, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2C , 0x0D , 15, 0 , 0xFE41, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2C , 0x0E , 15, 0 , 0x12F4, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2C , 0x11 , 15, 0 , 0xF2AD, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2C , 0x15 , 15, 0 , 0x7A61, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2C , 0x16 , 15, 0 , 0x0041, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2D , 0x00 , 15, 0 , 0x1F80, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2D , 0x01 , 15, 0 , 0x0800, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2D , 0x02 , 15, 0 , 0x0FC8, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2D , 0x11 , 15, 0 , 0x3001, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2D , 0x13 , 15, 0 , 0xF400, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2D , 0x1E , 15, 0 , 0x0100, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x28 , 0x0B , 15, 0 , 0x2390, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x28 , 0x0C , 15, 0 , 0xA514, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x28 , 0x0D , 15, 0 , 0xFE43, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x28 , 0x0E , 15, 0 , 0x12F4, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x28 , 0x11 , 15, 0 , 0xF2AD, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x28 , 0x15 , 15, 0 , 0x7A61, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x28 , 0x16 , 15, 0 , 0x0041, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x29 , 0x00 , 15, 0 , 0x1F80, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x29 , 0x01 , 15, 0 , 0x0800, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x29 , 0x02 , 15, 0 , 0x0FC8, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x29 , 0x11 , 15, 0 , 0x3001, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x29 , 0x13 , 15, 0 , 0xF400, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x29 , 0x1E , 15, 0 , 0x0100, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x26 , 0x0B , 15, 0 , 0x2390, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x26 , 0x0C , 15, 0 , 0xA514, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x26 , 0x0D , 15, 0 , 0xFE43, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x26 , 0x0E , 15, 0 , 0x12F4, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x26 , 0x11 , 15, 0 , 0xF2AD, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x26 , 0x15 , 15, 0 , 0x7A41, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x26 , 0x16 , 15, 0 , 0x0041, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x27 , 0x00 , 15, 0 , 0x1F80, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x27 , 0x01 , 15, 0 , 0x0800, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x27 , 0x02 , 15, 0 , 0x0FC8, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x27 , 0x11 , 15, 0 , 0x3001, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x27 , 0x13 , 15, 0 , 0xF400, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x27 , 0x1E , 15, 0 , 0x0100, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x24 , 0x0B , 15, 0 , 0x2390, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x24 , 0x0C , 15, 0 , 0xA514, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x24 , 0x0D , 15, 0 , 0xFE43, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x24 , 0x0E , 15, 0 , 0x12F4, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x24 , 0x11 , 15, 0 , 0xF2AD, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x24 , 0x15 , 15, 0 , 0x7A41, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x24 , 0x16 , 15, 0 , 0x0041, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x25 , 0x00 , 15, 0 , 0x1F80, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x25 , 0x01 , 15, 0 , 0x0800, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x25 , 0x02 , 15, 0 , 0x0FC8, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x25 , 0x11 , 15, 0 , 0x3001, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x25 , 0x13 , 15, 0 , 0xF400, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x25 , 0x1E , 15, 0 , 0x0100, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 24 , 18 , 15, 0 , 0x880D, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 24 , 19 , 15, 0 , 0x0024, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 24 , 20 , 15, 0 , 0x0036, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 24 , 21 , 15, 0 , 0x0035, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 24 , 22 , 15, 0 , 0x001A, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x1F , 0x00 , 15, 0 , 0x001B, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x1F , 0x00 , 15, 0 , 0x0000, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 90 , 20 , 7 , 0 , 0x01 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+}; -+ -+rtk_hwpatch_t rtl8261n_c_afe_conf[] = { -+}; -+ -+rtk_hwpatch_t rtl8261n_c_uc_conf[] = { -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x0 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbd8a, 5 , 3 , 0x3 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbd8c, 6 , 4 , 0x5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x8060, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 12, 10, 0x3 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x8061, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 13, 0x5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa466, 1 , 1 , 0x1 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x8491, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x3D , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+}; -+ -+rtk_hwpatch_t rtl8261n_c_uc2_conf[] = { -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x1 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb87c, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8af6, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb87e, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf8b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8af6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0eaf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8af8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8b41, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8afa}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf8b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8afc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4faf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8afe}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8b5b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b00}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf8b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b02}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xb4af, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b04}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8bc0, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b06}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf8b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b08}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdaaf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b0a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8bda, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b0c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf8ef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b0e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x49f8, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b10}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf70, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b12}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3f02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b14}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6772, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b16}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xad28, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b18}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13e1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b1a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8a55, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b1c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xad28, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b1e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0502, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b20}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5ee2, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b22}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xae0e, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b24}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x025d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b26}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8f02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b28}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8bda, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b2a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xae06, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b2c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x025d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b2e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7002, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b30}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c22, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b32}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe087, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b34}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1ef6, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b36}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x27e4, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b38}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x871e, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b3a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfcef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b3c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x94fc, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b3e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x04a1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b40}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0103, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b42}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x028b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b44}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfee0, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b46}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8a09, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b48}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef23, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b4a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf5e, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b4c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5bac, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b4e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5003, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b50}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf62, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b52}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8a02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b54}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c22, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b56}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf62, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b58}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xb0bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b5a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x68e0, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b5c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0267, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b5e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x72ef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b60}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x31bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b62}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x68dd, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b64}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0267, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b66}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x721e, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b68}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x31ac, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b6a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3819, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b6c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf68, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b6e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe902, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b70}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6772, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b72}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef31, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b74}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf68, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b76}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe602, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b78}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6772, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b7a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1e31, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b7c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xac38, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b7e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cee, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b80}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8933, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b82}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x02ae, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b84}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0aee, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b86}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8933, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b88}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x00ae, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b8a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x04ee, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b8c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8933, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b8e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x01bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b90}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8ff9, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b92}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe189, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b94}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x331a, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b96}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x91db, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b98}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf69, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b9a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4c02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b9c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6772, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b9e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1f00, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ba0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1f22, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ba2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1b45, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ba4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xad27, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ba6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x05e1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ba8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x870d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8baa}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xae03, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bac}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe187, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bae}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0eaf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bb0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2d1a, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bb2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0248, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bb4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf702, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bb6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c46, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bb8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0222, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bba}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4faf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bbc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4176, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bbe}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf8c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bc0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9002, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bc2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70eb, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bc4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf8c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bc6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9f02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bc8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70eb, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bca}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf8c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bcc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa502, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bce}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70eb, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bd0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd300, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bd2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0241, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bd4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7caf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bd6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x46b2, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bd8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf8ef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bda}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x49f8, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bdc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bde}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3a02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8be0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6772, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8be2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xac28, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8be4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x12bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8be6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6d63, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8be8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0267, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bea}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x72e5, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bec}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8ffc, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bee}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bf0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6f02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bf2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6772, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bf4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe58f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bf6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfdfc, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bf8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef94, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bfa}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfc04, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bfc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf8ef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bfe}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x49f8, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c00}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c02}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3a02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c04}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6772, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c06}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xac28, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c08}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x12e1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c0a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8ffe, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c0c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c0e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6302, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c10}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6753, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c12}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe18f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c14}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffbf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c16}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6d6f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c18}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0267, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c1a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x53fc, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c1c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef94, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c1e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfc04, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c20}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf8ef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c22}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x49f8, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c24}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c26}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3a02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c28}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6772, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c2a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xac28, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c2c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x12e1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c2e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8ffc, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c30}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c32}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6302, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c34}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6753, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c36}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe18f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c38}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfdbf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c3a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6d6f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c3c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0267, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c3e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x53fc, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c40}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef94, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c42}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfc04, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c44}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf8fa, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c46}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef69, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c48}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c4a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3a02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c4c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6772, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c4e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xad28, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c50}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0ebf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c52}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c93, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c54}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c56}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf4bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c58}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c90, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c5a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c5c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf4ae, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c5e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2ad1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c60}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0fbf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c62}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c96, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c64}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0267, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c66}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x53bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c68}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c99, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c6a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c6c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xebd1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c6e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x00bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c70}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c9c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c72}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0267, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c74}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x53bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c76}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c9f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c78}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c7a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf4d1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c7c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x00bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c7e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8ca2, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c80}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0267, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c82}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x53bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c84}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8ca5, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c86}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c88}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf4ef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c8a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x96fe, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c8c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfc04, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c8e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x77bd, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c90}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6c66, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c92}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbd6c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c94}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x30bd, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c96}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5444, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c98}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbd54, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c9a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x85bd, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c9c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5e55, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c9e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbd54, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ca0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa7bd, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ca2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5cbb, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ca4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbd5c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ca6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb85e, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x62ba, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb860, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5e56, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb862, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6287, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb864, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2d07, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb886, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4170, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb888, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x46ad, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb88a, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb88c, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb838, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x003f, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x0 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+}; -+ -+rtk_hwpatch_t rtl8261n_c_nctl0_conf[] = { -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x1 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA016, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA012, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA014, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8010, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x801a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x801a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x801a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x801a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x801a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x801a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x801a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd719, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3bb7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8014, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd704, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x406e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x12db, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1301, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA026, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA024, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA022, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA020, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA006, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA004, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA002, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA000, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x12d7, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA008, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0100, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x0 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+}; -+ -+rtk_hwpatch_t rtl8261n_c_nctl1_conf[] = { -+}; -+ -+rtk_hwpatch_t rtl8261n_c_nctl2_conf[] = { -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x1 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA016, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0020, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA012, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA014, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8010, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8029, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8217, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x82d0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x82f9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8322, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8322, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8322, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcb0a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cc7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4127, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c0f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b05, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c38, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0d28, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c0f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b0a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c38, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0d18, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0f73, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8034, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8031, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1bf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd06d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1dd, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd06d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x32}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x33}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x34}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd06e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x35}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x36}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x37}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x38}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5fba, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x39}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd05a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60f1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6113, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6135, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x40}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6157, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x41}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x42}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x43}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x44}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x45}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x46}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x47}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x48}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x49}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf004, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf002, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x142d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x50}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x51}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0ccf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x52}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b40, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x53}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x54}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c24, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x55}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x56}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa340, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x57}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x58}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x147c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x59}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa110, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1435, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8110, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1485, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa304, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x60}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa8c0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x61}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8810, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x62}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x63}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x64}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa310, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x65}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cfc, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x66}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0224, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x67}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0ca0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x68}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0480, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x69}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa340, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd162, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x70}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x71}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x72}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5fba, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x73}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8840, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x74}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1c4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x75}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd045, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x76}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x77}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x78}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x79}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5fba, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6127, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f3b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x88c0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x800a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x80}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x81}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8350, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x82}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x84a0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x83}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffb6, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x84}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xb920, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x85}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd33, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x86}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x87}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x88}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x89}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7fb4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9920, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6065, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f94, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x90}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffee, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x91}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xb820, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x92}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x93}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x94}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x95}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7fa5, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x96}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9820, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x97}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x800a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x98}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x99}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x147c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa108, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1435, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8108, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1485, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa2fc, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa304, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8880, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cc0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0440, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd34, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cc0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xaa}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b80, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xab}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xac3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xac}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c38, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xad}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0d08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xae}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xaf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa810, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa480, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa604, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x80bb, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xba}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd19f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xbb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xbc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xbd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xbe}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xbf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x63f4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4368, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cc0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b40, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d38, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xca}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xcb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xcc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xcd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x80d7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xce}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xcf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x80d4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1f4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1b7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1c6, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xda}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xdb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6074, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xdc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xdd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xde}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xdf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4056, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf004, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x61fc, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfff9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xea}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4070, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xeb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xec}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x81a4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xed}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xee}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xef}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xae80, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x81a4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd05a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60f1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6113, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6135, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xfa}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6157, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xfb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xfc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xfd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xfe}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xff}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x100}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x101}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x102}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x103}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf004, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x104}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x105}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf002, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x106}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x107}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x108}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x142d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x109}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0ccf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b40, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c24, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x110}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa340, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x111}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x112}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x147c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x113}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa110, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x114}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x115}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1435, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x116}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8110, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x117}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x118}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1485, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x119}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa304, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa8c0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8810, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa310, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cfc, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x120}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0224, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x121}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0ca0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x122}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0480, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x123}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8604, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x124}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd35, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x125}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd162, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x126}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x127}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x128}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x129}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5fba, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8840, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1c4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd045, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x130}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x131}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5fba, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x132}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x133}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6127, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x134}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x135}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f3b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x136}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x88c0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x137}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x800a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x138}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x139}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8350, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x84a0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffb8, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbb80, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x140}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5fb4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x141}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xb920, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x142}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd36, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x143}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x144}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x145}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x146}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7fb4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x147}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9920, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x148}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9b80, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x149}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6065, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f94, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffe8, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xb820, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x150}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x151}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x152}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x153}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7fa5, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x154}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9820, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x155}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x800a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x156}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x157}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x158}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x147c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x159}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa108, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1435, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8108, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1485, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa2fc, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x160}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa304, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x161}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8880, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x162}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cc0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x163}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0440, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x164}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd37, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x165}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x166}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x167}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cc0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x168}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b80, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x169}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xac3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c38, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0d08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa810, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x170}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa480, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x171}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa604, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x172}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x173}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x174}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x817e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x175}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x176}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x817b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x177}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x178}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x179}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x180}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x181}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x182}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1463, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x183}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x184}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x185}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x186}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f28, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x187}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x188}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x189}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cc0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b40, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d38, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x190}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x819a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x191}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x192}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8197, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x193}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x194}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x195}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x196}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x197}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x198}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x199}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd189, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1463, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f28, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c0f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b05, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1aa}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60f1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ab}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6113, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ac}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6135, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ad}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6157, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ae}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1af}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf004, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf002, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ba}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1bb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x142d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1bc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa180, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1bd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd38, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1be}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1bf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x81d4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x81cc, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf013, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd100, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ca}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf010, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1cb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1cc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1cd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1b7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ce}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1cf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd100, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1da}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd13b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1db}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd055, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1dc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1dd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1de}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1df}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1463, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa302, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1463, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ea}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f28, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1eb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ec}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ed}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ee}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c12, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ef}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8206, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x81fe, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf013, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1fa}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd100, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1fb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1fc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf010, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1fd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1fe}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ff}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x200}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x201}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x202}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd100, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x203}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd040, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x204}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x205}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x206}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x207}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x208}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x209}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd16b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1463, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x210}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x211}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x212}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x213}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f2a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x214}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x215}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x087a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x216}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x217}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x646d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x218}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x219}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8231, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8227, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x220}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd100, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x221}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x222}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf01a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x223}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x224}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x225}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf017, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x226}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x227}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x228}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x229}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd100, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf010, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x230}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x231}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x232}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x233}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x234}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x235}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x236}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x237}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x238}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x239}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1463, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x240}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x241}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x242}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x243}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f29, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x244}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x245}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x246}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60f1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x247}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6113, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x248}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6135, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x249}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6157, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x250}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x251}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x252}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf004, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x253}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x254}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf002, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x255}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x256}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x257}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x142d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x258}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x259}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8bc0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c09, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa310, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x260}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa420, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x261}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd3b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x262}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x263}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x65ad, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x264}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x43c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x265}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x266}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x267}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x827b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x268}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x269}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8273, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf024, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd15d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x270}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x271}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf021, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x272}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x273}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x274}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1c6, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x275}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x276}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf01c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x277}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd15d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x278}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x279}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf019, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf014, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x280}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x281}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf011, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x282}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x283}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x284}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x828e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x285}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x286}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x828b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x287}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1e5, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x288}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x289}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf009, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd191, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x290}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd16b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x291}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x292}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x293}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1418, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x294}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x295}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1463, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x296}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x297}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x298}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x299}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f2c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40e7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c0f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b05, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c0f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b0a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd3c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x644d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2aa}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x43c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ab}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ac}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ad}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x82c1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ae}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2af}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x82b9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf019, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf016, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ba}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2bb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2bc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf011, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2bd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd13e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2be}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2bf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf009, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ca}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2cb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2cc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2cd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ce}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0956, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2cf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2969, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x82f5, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x82eb, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x82e1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2da}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd15c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2db}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2dc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf01a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2dd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2de}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2df}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf017, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd13e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf010, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ea}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2eb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ec}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ed}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ee}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ef}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x09a0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2969, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2fa}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x831e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2fb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2fc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8314, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2fd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2fe}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x830a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ff}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x300}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x301}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x302}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x303}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd15d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x304}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x305}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf01a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x306}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x307}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x308}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf017, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x309}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd16b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf010, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x310}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x311}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x312}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x313}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x314}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x315}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x316}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x317}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x318}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x319}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1b7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x320}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0a39, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x321}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA10E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA10C, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA10A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA108, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0a12, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA106, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0979, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA104, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x089f, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA102, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0692, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA100, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0f60, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA110, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x001f, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA016, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0020, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA012, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1ff8, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA014, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b0e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ff8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b0e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ff9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b0e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ffa}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ffb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ffc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ffd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ffe}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1fff}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA164, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0baa, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA166, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c19, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA168, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1293, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA16A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3fff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA16C, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3fff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA16E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3fff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA170, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3fff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA172, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3fff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA162, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0007, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x0 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+}; -+ -+rtk_hwpatch_t rtl8261n_c_algxg_conf[] = { -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8165, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x22 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8167, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x33 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x827E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x68 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8013, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x39 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8ffb, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x14 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8ffa, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x1e , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8ff9, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x1e , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x82D9, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x20 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x82DA, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x00 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x816E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0xab , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8159, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x58 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x815A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x99 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8139, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x25 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8125, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x67 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8126, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x89 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x827D, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x42 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+}; -+ -+rtk_hwpatch_t rtl8261n_c_alg_giga_conf[] = { -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x8367, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x5d , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+}; -+ -+rtk_hwpatch_t rtl8261n_c_normal_conf[] = { -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x817d, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x07 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb516, 6 , 0 , 0x0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8ffe, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x04 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8fff, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x05 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8132, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x77 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8134, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x88 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x80ca, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x77 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x80cc, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x88 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8062, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x77 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8064, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x88 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x801E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0005, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+}; -+ -+rtk_hwpatch_t rtl8261n_c_dataram_conf[] = { -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x0 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb896, 0 , 0 , 0x0 , RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb892, 15, 8 , 0x0 , RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC10B, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xD5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC10C, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xD5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC10D, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xD5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC10E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xD5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC10F, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xD5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC110, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xD5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC149, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x08 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC14A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x08 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC14B, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x08 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC14C, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x08 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC14D, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x08 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC14E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x08 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC166, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xEE , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC167, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xEE , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC168, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x07 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC169, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x09 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC16A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x0B , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC16B, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x0D , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC16C, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x13 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC16D, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x0E , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC16E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x11 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC16F, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x14 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC170, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x17 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC171, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x15 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC172, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x10 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC173, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x0B , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC128, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xF7 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC129, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xF7 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC12A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xF8 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC12B, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xF7 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC12C, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xF6 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC12D, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xF5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC12E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xF2 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC12F, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xF7 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC130, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xF5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC131, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xF2 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC132, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xF0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC133, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xF1 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC134, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xF4 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC135, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xF7 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb896, 0 , 0 , 0x1 , RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+}; -+ -+rtk_hwpatch_t rtl8261n_c_rtct_conf[] = { -+}; -+ -diff --git a/drivers/net/phy/rtl8261n/construct/conf_rtl8264b.c b/drivers/net/phy/rtl8261n/construct/conf_rtl8264b.c -new file mode 100644 -index 000000000000..d5cae3fd3bac ---- /dev/null -+++ b/drivers/net/phy/rtl8261n/construct/conf_rtl8264b.c -@@ -0,0 +1,2177 @@ -+/* -+ * SPDX-License-Identifier: GPL-2.0-only -+ * -+ * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. -+ */ -+ -+//Date: Thu Dec 15 16:01:01 2022 -+ -+rtk_hwpatch_t rtl8264b_top_conf[] = { -+ {RTK_PATCH_OP_TOP , 0xf , 2 , 20 , 15, 0 , 0x5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 2 , 21 , 15, 0 , 0x0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 2 , 22 , 15, 0 , 0x280 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 2 , 23 , 15, 0 , 0x0014, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 3 , 16 , 15, 0 , 0x0300, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 3 , 17 , 15, 0 , 0x01ff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 3 , 18 , 15, 0 , 0x000c, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 3 , 19 , 15, 0 , 0x01ff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 3 , 20 , 15, 0 , 0x0200, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 3 , 21 , 15, 0 , 0x0015, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 3 , 22 , 15, 0 , 0x0200, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 3 , 23 , 15, 0 , 0x0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 4 , 16 , 15, 0 , 0x0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 13 , 23 , 8 , 5 , 0x6 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 90 , 18 , 15, 0 , 0xc , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 90 , 19 , 15, 0 , 0xc , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 90 , 20 , 15, 8 , 0x01 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+}; -+ -+rtk_hwpatch_t rtl8264b_sds_conf[] = { -+ {RTK_PATCH_OP_TOP , 0xf , 24 , 18 , 15, 0 , 0x881F, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 24 , 19 , 15, 0 , 0x003F, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 24 , 20 , 15, 0 , 0x003F, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 24 , 21 , 15, 0 , 0x003F, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 24 , 22 , 15, 0 , 0x001F, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x06 , 0x0D , 15, 0 , 0x0F00, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x06 , 0x0E , 15, 0 , 0x3F5A, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x07 , 0x10 , 15, 12, 0x8 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x07 , 0x10 , 7 , 0 , 0x3 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x06 , 0x1D , 15, 0 , 0x0600, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x21 , 0x00 , 15, 0 , 0x4902, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x21 , 0x08 , 15, 0 , 0x0FC0, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x21 , 0x09 , 15, 0 , 0x33F0, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x21 , 0x0C , 15, 0 , 0x08BF, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x21 , 0x12 , 15, 0 , 0x8000, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x36 , 0x07 , 15, 0 , 0x04C0, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x36 , 0x08 , 15, 0 , 0x2000, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2E , 0x0B , 15, 0 , 0x2390, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2E , 0x0C , 15, 0 , 0xAA17, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2E , 0x0D , 15, 0 , 0xFE40, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2E , 0x0E , 15, 0 , 0x12F4, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2E , 0x11 , 15, 0 , 0xF2AD, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2E , 0x15 , 15, 0 , 0x7A41, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2E , 0x16 , 15, 0 , 0x0041, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2F , 0x00 , 15, 0 , 0x1F00, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2F , 0x01 , 15, 0 , 0x2800, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2F , 0x02 , 15, 0 , 0x0FC8, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2F , 0x11 , 15, 0 , 0x3000, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2F , 0x13 , 15, 0 , 0xF400, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2F , 0x1E , 15, 0 , 0x0500, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x34 , 0x0B , 15, 0 , 0x2390, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x34 , 0x0C , 15, 0 , 0xA517, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x34 , 0x0D , 15, 0 , 0xFE41, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x34 , 0x0E , 15, 0 , 0x12F4, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x34 , 0x11 , 15, 0 , 0xF2AD, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x34 , 0x15 , 15, 0 , 0x7A41, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x34 , 0x16 , 15, 0 , 0x0041, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x35 , 0x00 , 15, 0 , 0x1F80, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x35 , 0x01 , 15, 0 , 0x0800, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x35 , 0x02 , 15, 0 , 0x0FC8, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x35 , 0x11 , 15, 0 , 0x3001, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x35 , 0x13 , 15, 0 , 0xF400, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x35 , 0x1E , 15, 0 , 0x0100, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2C , 0x0B , 15, 0 , 0x2390, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2C , 0x0C , 15, 0 , 0xA517, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2C , 0x0D , 15, 0 , 0xFE41, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2C , 0x0E , 15, 0 , 0x12F4, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2C , 0x11 , 15, 0 , 0xF2AD, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2C , 0x15 , 15, 0 , 0x7A61, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2C , 0x16 , 15, 0 , 0x0041, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2D , 0x00 , 15, 0 , 0x1F80, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2D , 0x01 , 15, 0 , 0x0800, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2D , 0x02 , 15, 0 , 0x0FC8, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2D , 0x11 , 15, 0 , 0x3001, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2D , 0x13 , 15, 0 , 0xF400, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x2D , 0x1E , 15, 0 , 0x0100, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x28 , 0x0B , 15, 0 , 0x2390, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x28 , 0x0C , 15, 0 , 0xA514, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x28 , 0x0D , 15, 0 , 0xFE43, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x28 , 0x0E , 15, 0 , 0x12F4, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x28 , 0x11 , 15, 0 , 0xF2AD, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x28 , 0x15 , 15, 0 , 0x7A61, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x28 , 0x16 , 15, 0 , 0x0041, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x29 , 0x00 , 15, 0 , 0x1F80, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x29 , 0x01 , 15, 0 , 0x0800, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x29 , 0x02 , 15, 0 , 0x0FC8, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x29 , 0x11 , 15, 0 , 0x3001, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x29 , 0x13 , 15, 0 , 0xF400, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x29 , 0x1E , 15, 0 , 0x0100, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x26 , 0x0B , 15, 0 , 0x2390, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x26 , 0x0C , 15, 0 , 0xA514, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x26 , 0x0D , 15, 0 , 0xFE43, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x26 , 0x0E , 15, 0 , 0x12F4, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x26 , 0x11 , 15, 0 , 0xF2AD, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x26 , 0x15 , 15, 0 , 0x7A41, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x26 , 0x16 , 15, 0 , 0x0041, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x27 , 0x00 , 15, 0 , 0x1F80, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x27 , 0x01 , 15, 0 , 0x0800, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x27 , 0x02 , 15, 0 , 0x0FC8, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x27 , 0x11 , 15, 0 , 0x3001, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x27 , 0x13 , 15, 0 , 0xF400, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x27 , 0x1E , 15, 0 , 0x0100, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x24 , 0x0B , 15, 0 , 0x2390, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x24 , 0x0C , 15, 0 , 0xA514, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x24 , 0x0D , 15, 0 , 0xFE43, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x24 , 0x0E , 15, 0 , 0x12F4, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x24 , 0x11 , 15, 0 , 0xF2AD, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x24 , 0x15 , 15, 0 , 0x7A41, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x24 , 0x16 , 15, 0 , 0x0041, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x25 , 0x00 , 15, 0 , 0x1F80, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x25 , 0x01 , 15, 0 , 0x0800, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x25 , 0x02 , 15, 0 , 0x0FC8, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x25 , 0x11 , 15, 0 , 0x3001, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x25 , 0x13 , 15, 0 , 0xF400, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x25 , 0x1E , 15, 0 , 0x0100, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 24 , 18 , 15, 0 , 0x880D, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 24 , 19 , 15, 0 , 0x0024, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 24 , 20 , 15, 0 , 0x0036, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 24 , 21 , 15, 0 , 0x0035, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 24 , 22 , 15, 0 , 0x001A, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x1F , 0x00 , 15, 0 , 0x001B, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xf , 0x1F , 0x00 , 15, 0 , 0x0000, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 90 , 20 , 7 , 0 , 0x03 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+}; -+ -+rtk_hwpatch_t rtl8264b_afe_conf[] = { -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbf92, 15, 11, 0x1C , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbfaa, 10, 8 , 0x5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbfae, 8 , 6 , 0x5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbfaa, 12, 11, 0x1 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbf1c, 4 , 4 , 0x1 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbf0e, 5 , 4 , 0x3 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbf1c, 15, 13, 0x5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbf16, 12, 12, 0x0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbc24, 3 , 2 , 0x1 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbc24, 1 , 0 , 0x1 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbf08, 2 , 0 , 0x6 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbf0c, 5 , 3 , 0x7 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbf0c, 8 , 6 , 0x7 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbf0c, 11, 9 , 0x7 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbf0c, 14, 12, 0x7 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_TOP , 0xf , 90 , 21 , 15, 8 , 0x03 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+}; -+ -+rtk_hwpatch_t rtl8264b_uc_conf[] = { -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x0 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbd8a, 5 , 3 , 0x3 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbd8c, 6 , 4 , 0x5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x8060, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 12, 10, 0x3 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x8061, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 13, 0x5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa466, 1 , 1 , 0x1 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x8491, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x1D , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x8018, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 12, 12, 0x1 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x85af, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf85, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85af}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xc7af, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85b1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x85df, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85b3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf86, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85b5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1baf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85b7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8674, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85b9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf86, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85bb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7daf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85bd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x875b, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85bf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf87, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85c1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x67af, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85c3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8774, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85c5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf85, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85c7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdc02, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85c9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6957, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85cb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe48f, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85cd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2ce5, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85cf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8f2d, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85d1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe084, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85d3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x11e1, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85d5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8412, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85d7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf5d, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85d9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x73f6, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85db}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xb01a, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85dd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe08f, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85df}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2ce1, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85e1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8f2d, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85e3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85e5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6802, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85e7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6938, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85e9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85eb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6b02, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85ed}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6938, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85ef}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85f1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6e02, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85f3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6938, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85f5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85f7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7102, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85f9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6938, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85fb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85fd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7402, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x85ff}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70e5, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8601}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8603}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7702, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8605}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70e5, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8607}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8609}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7a02, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x860b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70e5, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x860d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x860f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7d02, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8611}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70e5, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8613}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd784, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8615}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa2af, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8617}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5eed, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8619}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0286, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x861b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x21af, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x861d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x07ad, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x861f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf8f9, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8621}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfaef, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8623}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x69e0, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8625}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8018, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8627}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xad24, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8629}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x39d4, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x862b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x002e, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x862d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6e, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x862f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0402, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8631}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6938, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8633}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd480, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8635}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x03bf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8637}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x866e, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8639}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0269, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x863b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x38d4, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x863d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x000f, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x863f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf86, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8641}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7102, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8643}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6938, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8645}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf86, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8647}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7102, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8649}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70dc, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x864b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd480, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x864d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0bbf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x864f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x866e, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8651}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0269, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8653}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x38d4, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8655}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x000f, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8657}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf86, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8659}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7102, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x865b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6938, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x865d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf86, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x865f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7102, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8661}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70dc, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8663}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0208, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8665}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1eef, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8667}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x96fe, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8669}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfdfc, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x866b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x04f0, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x866d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbd94, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x866f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x30bd, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8671}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9602, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8673}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8621, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8675}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0254, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8677}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdcaf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8679}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x03c1, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x867b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0286, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x867d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2102, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x867f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8686, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8681}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf04, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8683}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x41f8, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8685}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfbef, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8687}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x79e0, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8689}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8018, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x868b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xac20, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x868d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x03af, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x868f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8756, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8691}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6b, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8693}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3402, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8695}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70dc, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8697}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6b, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8699}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3102, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x869b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70e5, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x869d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6f, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x869f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4902, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86a1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70dc, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86a3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6f, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86a5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4c02, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86a7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70e5, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86a9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6f, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86ab}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4f02, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86ad}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70e5, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86af}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6b, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86b1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3702, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86b3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70dc, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86b5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6c, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86b7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c02, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86b9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70dc, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86bb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6b, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86bd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3402, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86bf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70e5, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86c1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1f00, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86c3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe183, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86c5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd4bf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86c7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6bcd, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86c9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0269, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86cb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x38bf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86cd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6bd0, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86cf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0269, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86d1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x38bf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86d3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6bd3, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86d5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0269, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86d7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x38bf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86d9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6bd6, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86db}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0269, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86dd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x38bf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86df}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6bd9, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86e1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86e3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe5bf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86e5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6bdc, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86e7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86e9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe5bf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86eb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6bdf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86ed}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86ef}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe5bf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86f1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6be2, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86f3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86f5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe5bf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86f7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6f46, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86f9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86fb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdce1, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86fd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x83d3, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x86ff}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6f, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8701}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3a02, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8703}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6938, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8705}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0d14, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8707}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6f, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8709}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4002, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x870b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6938, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x870d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0d12, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x870f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6f, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8711}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3d02, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8713}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6938, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8715}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6f, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8717}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4302, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8719}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70dc, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x871b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0238, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x871d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xb5bf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x871f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6bd9, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8721}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8723}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdcbf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8725}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6bdc, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8727}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8729}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdcbf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x872b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6bdf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x872d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x872f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdcbf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8731}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6be2, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8733}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8735}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdcbf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8737}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6b34, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8739}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x873b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdcbf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x873d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6b37, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x873f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8741}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe5bf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8743}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6f4f, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8745}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8747}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdcbf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8749}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6b31, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x874b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x874d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdcbf, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x874f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6f4c, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8751}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0270, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8753}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdcef, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8755}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x97ff, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8757}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfc04, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8759}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xac2f, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x875b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x03af, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x875d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b2a, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x875f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x020e, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8761}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x95af, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8763}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b3f, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8765}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xee84, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8767}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3c00, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8769}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6c, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x876b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c02, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x876d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x70e5, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x876f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf01, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8771}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0300, RTK_PATCH_CMP_SWC , 0, 0xa438, 0xa436, 0x8773}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb818, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5d6d, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb81a, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5eea, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb81c, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x07aa, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb81e, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x03be, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb850, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x043e, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb852, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b26, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb878, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x00fd, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb884, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb832, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x007f, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+}; -+ -+rtk_hwpatch_t rtl8264b_uc2_conf[] = { -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x1 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb87c, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8acf, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb87e, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf8a, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8acf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe7af, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ad1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8b40, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ad3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf8b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ad5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4caf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ad7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8b6a, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ad9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf8b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8adb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xb5af, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8add}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8bd1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8adf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf8c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ae1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x04af, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ae3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c12, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ae5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf67, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ae7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6302, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ae9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x65f5, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8aeb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef31, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8aed}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf67, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8aef}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6002, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8af1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x65f5, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8af3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1e31, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8af5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xac38, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8af7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x19bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8af9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x676c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8afb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0265, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8afd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf5ef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8aff}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x31bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b01}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6769, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b03}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0265, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b05}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf51e, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b07}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x31ac, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b09}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x380c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b0b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xee89, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b0d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2c02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b0f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xae0a, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b11}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xee89, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b13}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2c00, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b15}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xae04, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b17}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xee89, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b19}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2c01, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b1b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf8f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b1d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd5e1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b1f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x892c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b21}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1a91, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b23}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdbbf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b25}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x67cf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b27}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0265, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b29}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf51f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b2b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x001f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b2d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x221b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b2f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x45ad, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b31}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2705, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b33}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe187, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b35}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x06ae, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b37}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x03e1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b39}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8707, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b3b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf2d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b3d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1a02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b3f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c1e, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b41}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x028c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b43}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7b02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b45}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x224f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b47}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf40, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b49}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xb8ac, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b4b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2f0f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b4d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0210, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b4f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x62bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b51}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6d36, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b53}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0265, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b55}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf5e5, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b57}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8fde, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b59}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf10, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b5b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4ae1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b5d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8fde, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b5f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b61}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3602, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b63}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x65d6, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b65}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf10, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b67}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x59e1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b69}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8fdd, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b6b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa100, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b6d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0dbf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b6f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6d36, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b71}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0265, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b73}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf5e5, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b75}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8fdc, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b77}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xee8f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b79}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdd01, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b7b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b7d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3602, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b7f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6f77, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b81}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf86, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b83}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xc7e1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b85}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x892c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b87}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4903, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b89}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1a91, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b8b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef69, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b8d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdbbf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b8f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x67cf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b91}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0265, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b93}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf51f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b95}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x001f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b97}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x22ef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b99}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x741b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b9b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x45ad, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b9d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2711, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8b9f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf86, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ba1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd0d0, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ba3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x00e1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ba5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8fdc, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ba7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ba9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3602, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bab}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x65d6, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bad}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf35, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8baf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x46af, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bb1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3527, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bb3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x026f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bb5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6eee, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bb7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8fdd, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bb9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x00bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bbb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d31, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bbd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x026f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bbf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6ebf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bc1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d40, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bc3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x026f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bc5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6ebf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bc7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d46, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bc9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x026f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bcb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6eaf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bcd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x36a9, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bcf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf8ef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bd1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x49f8, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bd3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6e, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bd5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xc202, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bd7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x65f5, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bd9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xad28, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bdb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13e1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bdd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8a4e, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bdf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xad28, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8be1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0502, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8be3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5d65, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8be5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xae0e, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8be7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x025c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8be9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1202, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8beb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8cc5, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bed}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xae06, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bef}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x025b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bf1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf302, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bf3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d0d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bf5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe087, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bf7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x17f6, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bf9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x27e4, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bfb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8717, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bfd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfcef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8bff}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x94fc, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c01}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x04a1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c03}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0103, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c05}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x028c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c07}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe9e0, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c09}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8a02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c0b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef23, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c0d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf5c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c0f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdeac, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c11}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5003, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c13}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf61, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c15}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0d02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c17}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d0d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c19}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaf61, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c1b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33f8, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c1d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfafb, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c1f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef79, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c21}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfbbf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c23}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6766, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c25}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0265, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c27}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf5ad, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c29}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2810, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c2b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xad30, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c2d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x05d7, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c2f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0002, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c31}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xae16, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c33}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xad32, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c35}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x24d7, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c37}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0003, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c39}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xae0e, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c3b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xad31, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c3d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x05d7, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c3f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c41}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xae06, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c43}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xad33, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c45}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x14d7, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c47}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0001, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c49}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf8f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c4b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdf4f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c4d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0008, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c4f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1a97, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c51}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd78c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c53}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x63d6, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c55}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c7b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c57}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0265, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c59}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3bff, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c5b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef97, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c5d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfffe, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c5f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfc04, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c61}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x206b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c63}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0e20, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c65}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6b11, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c67}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x206b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c69}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1420, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c6b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6b17, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c6d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x206b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c6f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2020, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c71}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6b23, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c73}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x206b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c75}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2600, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c77}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6b29, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c79}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf8fa, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c7b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef69, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c7d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c7f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbd02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c81}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x65f5, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c83}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xad28, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c85}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0ebf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c87}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d34, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c89}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x026f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c8b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x77bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c8d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d31, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c8f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x026f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c91}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x77ae, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c93}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2ad1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c95}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0fbf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c97}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d37, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c99}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0265, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c9b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd6bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c9d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d3a, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8c9f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x026f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ca1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6ed1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ca3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x00bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ca5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d3d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ca7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0265, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ca9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd6bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cab}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d40, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cad}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x026f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8caf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x77d1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cb1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x00bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cb3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d43, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cb5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0265, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cb7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd6bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cb9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d46, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cbb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x026f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cbd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x77ef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cbf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x96fe, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cc1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfc04, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cc3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf8ef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cc5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x49f8, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cc7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cc9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbd02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ccb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x65f5, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ccd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xac28, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ccf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x12bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cd1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6be6, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cd3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0265, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cd5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf5e5, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cd7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8fd8, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cd9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cdb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf202, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cdd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x65f5, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cdf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe58f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ce1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd9fc, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ce3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef94, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ce5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfc04, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ce7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf8ef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ce9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x49f8, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ceb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8ced}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbd02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cef}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x65f5, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cf1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xac28, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cf3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x12e1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cf5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8fda, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cf7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cf9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe602, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cfb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x65d6, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cfd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe18f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8cff}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xdbbf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d01}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6bf2, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d03}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0265, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d05}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd6fc, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d07}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef94, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d09}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfc04, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d0b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf8ef, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d0d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x49f8, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d0f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6d, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d11}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbd02, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d13}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x65f5, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d15}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xac28, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d17}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x12e1, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d19}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8fd8, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d1b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf6b, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d1d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe602, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d1f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x65d6, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d21}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xe18f, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d23}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd9bf, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d25}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6bf2, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d27}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0265, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d29}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd6fc, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d2b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xef94, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d2d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfc04, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d2f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x77bd, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d31}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6c66, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d33}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbd6c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d35}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x30bd, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d37}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5444, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d39}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbd54, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d3b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x85bd, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d3d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5e55, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d3f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbd54, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d41}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa7bd, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d43}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5cbb, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d45}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbd5c, RTK_PATCH_CMP_SWC , 0, 0xb87e, 0xb87c, 0x8d47}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb85e, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2d07, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb860, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40b5, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb862, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1047, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb864, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3504, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb886, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x36A6, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb888, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x613d, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb88a, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5cd9, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb88c, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x610a, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xb838, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x00ff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x0 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+}; -+ -+rtk_hwpatch_t rtl8264b_nctl0_conf[] = { -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x1 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA016, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA012, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA014, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8010, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8015, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8020, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x802a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8030, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8035, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8046, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x806b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd707, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x606f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x801a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd707, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x606f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x801a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce10, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcf01, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd705, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4004, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcf02, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd719, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3bb7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8024, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd704, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x406e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x12bd, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x12e3, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xab80, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd500, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xc402, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x004a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8b80, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd500, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x32}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x33}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0108, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x34}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c0f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x35}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x090f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x36}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c0f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x37}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0a03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x38}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd004, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x39}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1c1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x401c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce00, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd500, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x801a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x40}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd501, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x41}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce01, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x42}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x43}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x44}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0aa9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x45}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd500, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x46}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x47}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2a69, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x48}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8056, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x49}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3f48, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8058, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3f4b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x805a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x618c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3f40, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x805c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x50}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3f43, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x51}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x805e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x52}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x616b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x53}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6187, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x54}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x55}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcc8f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x56}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x57}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcc8d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x58}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x59}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcc8b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcc89, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf004, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcc87, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf002, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcc91, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x60}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x61}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b9a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x62}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x63}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xca80, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x64}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x65}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0ba0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x66}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xca00, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x67}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd504, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x68}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x69}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1658, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa208, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0a88, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0d91, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA026, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0d90, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA024, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1657, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA022, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0aa1, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA020, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0047, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA006, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0049, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA004, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x12b9, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA002, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0be5, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA000, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1811, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA008, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xff00, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA016, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA012, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0ff8, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA014, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xc483, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x0ff8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xc483, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xff9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xffa}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xffb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xffc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xffd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xffe}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xfff}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA152, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1a83, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA154, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1d29, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA156, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3fff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA158, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3fff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA15A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3fff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA15C, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3fff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA15E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3fff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA160, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3fff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA150, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0003, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x0 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+}; -+ -+rtk_hwpatch_t rtl8264b_nctl1_conf[] = { -+}; -+ -+rtk_hwpatch_t rtl8264b_nctl2_conf[] = { -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x1 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA016, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0020, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA012, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA014, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8010, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8022, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8029, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8085, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x808c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8093, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8281, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x829a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8370, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd707, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x416f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd05a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa501, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd701, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5fbd, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8501, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0427, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x040b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8501, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd707, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x406f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x01d8, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x01cb, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd705, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3fa7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8030, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd75f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x699c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1340, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd704, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4066, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x800a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x32}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf002, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x33}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x34}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd705, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x35}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x61b4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x36}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd704, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x37}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x609f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x38}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6150, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x39}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x2d71, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8043, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cf0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x05a0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x3f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x40}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x41}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13b1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x42}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x43}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x44}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8220, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x45}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c30, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x46}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0410, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x47}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x48}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x800a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x49}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x81a0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8302, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8480, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8684, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x4f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8203, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x50}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8340, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x51}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x52}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xaa10, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x53}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8b07, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x54}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x55}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x56}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60f1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x57}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6113, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x58}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6135, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x59}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6157, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce0b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce0b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x5f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce0a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x60}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x61}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce0a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x62}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf004, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x63}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce09, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x64}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf002, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x65}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce09, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x66}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x67}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x68}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa204, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x69}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13e4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xab08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcda0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd705, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x6f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40de, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x70}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd162, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x71}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd045, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x72}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbf10, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x73}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x74}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13b1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x75}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9f10, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x76}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x77}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13b1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x78}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x79}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x607a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13b1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9f10, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x7f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8210, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x80}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa210, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x81}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x82}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x83}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1340, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x84}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x85}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x86}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8df8, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x87}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8370, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x88}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x89}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x01c1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8df8, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8370, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x8f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x90}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x91}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x009e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x92}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x93}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x94}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x809e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x95}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x96}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x809b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x97}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1bf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x98}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd06d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x99}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1dd, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd06d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd06e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x9f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5fba, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd05a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60f1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6113, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xa9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6135, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xaa}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6157, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xab}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xac}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xad}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xae}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xaf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf004, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf002, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13e4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xb9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xba}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xbb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0ccf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xbc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b40, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xbd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xbe}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c24, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xbf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa340, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1433, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa110, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13ec, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8110, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x143c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xc9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa304, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xca}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa8c0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xcb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8810, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xcc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xcd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xce}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa310, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xcf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cfc, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0224, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0ca0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0480, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa340, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd162, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xd9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xda}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xdb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xdc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5fba, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xdd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8840, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xde}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1c4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xdf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd045, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5fba, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6127, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f3b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x88c0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xe9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x800a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xea}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xeb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8350, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xec}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x84a0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xed}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffb6, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xee}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xb920, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xef}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd33, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7fb4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9920, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6065, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xf9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f94, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xfa}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffee, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xfb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xb820, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xfc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xfd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xfe}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0xff}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7fa5, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x100}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9820, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x101}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x800a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x102}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x103}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x104}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1433, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x105}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa108, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x106}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x107}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13ec, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x108}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8108, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x109}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x143c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa2fc, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa304, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8880, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cc0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x10f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0440, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x110}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd34, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x111}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x112}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x113}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cc0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x114}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b80, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x115}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xac3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x116}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c38, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x117}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0d08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x118}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x119}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa810, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa480, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa604, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x11f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x120}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8125, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x121}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x122}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x123}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x124}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd19f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x125}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x126}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x127}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x128}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x129}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x63f4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4368, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x12f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x130}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cc0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x131}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b40, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x132}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x133}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d38, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x134}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x135}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x136}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x137}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8141, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x138}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x139}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x813e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1f4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1b7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x13f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x140}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1c6, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x141}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x142}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x143}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x144}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x145}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6074, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x146}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x147}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x148}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x149}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4056, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf004, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x61fc, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x14f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xfff9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x150}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x151}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x152}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x153}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x154}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4070, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x155}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x156}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x820e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x157}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x158}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x159}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xae80, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x820e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd05a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x15f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x160}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x161}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60f1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x162}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6113, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x163}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6135, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x164}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6157, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x165}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x166}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x167}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x168}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x169}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf004, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x16f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf002, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x170}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x171}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x172}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13e4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x173}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x174}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x175}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0ccf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x176}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b40, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x177}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x178}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c24, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x179}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa340, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1433, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa110, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x17f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13ec, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x180}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8110, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x181}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x182}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x143c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x183}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa304, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x184}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa8c0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x185}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8810, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x186}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x187}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x188}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa310, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x189}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cfc, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0224, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0ca0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0480, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8604, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd35, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x18f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd162, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x190}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x191}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x192}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x193}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x194}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5fba, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x195}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8840, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x196}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1c4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x197}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd045, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x198}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x199}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5fba, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6127, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x19f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f3b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x88c0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x800a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8350, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x84a0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffb8, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xbb80, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1a9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1aa}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5fb4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ab}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xb920, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ac}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd36, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ad}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ae}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1af}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7fb4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9920, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9b80, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6065, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f94, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xffe8, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1b9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xb820, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ba}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1bb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1bc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd71f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1bd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x7fa5, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1be}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9820, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1bf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x800a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1433, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa108, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13ec, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8108, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x143c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1c9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa2fc, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ca}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa304, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1cb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8880, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1cc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cc0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1cd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0440, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ce}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd37, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1cf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cc0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b80, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xac3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c38, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0d08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa810, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1d9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1da}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa480, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1db}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa604, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1dc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1dd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1de}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x81e8, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1df}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x81e5, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1e9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ea}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1eb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ec}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x141a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ed}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ee}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ef}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f28, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cc0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b40, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8c3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8d38, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1f9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1fa}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8204, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1fb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1fc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8201, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1fd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1fe}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ff}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x200}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x201}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x202}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x203}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd189, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x204}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x205}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x206}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x207}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x208}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x141a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x209}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f28, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x20f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c0f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x210}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b05, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x211}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x212}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x213}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x214}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60f1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x215}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6113, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x216}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6135, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x217}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6157, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x218}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x219}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x21f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x220}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf004, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x221}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x222}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf002, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x223}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce08, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x224}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x225}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13e4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x226}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa180, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x227}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd38, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x228}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x229}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x823e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8236, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x22f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x230}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x231}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf013, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x232}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd100, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x233}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x234}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf010, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x235}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x236}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x237}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1b7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x238}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x239}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd100, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x23f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x240}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x241}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x242}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x243}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x244}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd13b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x245}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd055, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x246}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x247}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x248}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x249}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x141a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa302, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x24f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x250}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x141a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x251}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x252}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x253}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x254}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f28, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x255}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x256}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x257}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x258}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c12, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x259}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8270, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8268, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x25f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x260}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x261}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x262}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x263}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf013, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x264}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd100, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x265}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x266}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf010, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x267}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x268}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x269}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd100, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd040, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x26f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x270}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x271}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x272}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x273}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x274}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd16b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x275}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x276}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x277}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x278}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x279}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x141a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f2a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x27f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x085e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x280}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x281}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x282}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcb0a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x283}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0cc7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x284}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x285}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x286}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x287}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4127, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x288}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x289}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c0f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b05, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c38, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0d28, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x28f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x290}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x291}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x292}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c0f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x293}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b0a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x294}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c38, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x295}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0d18, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x296}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x297}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x298}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0f45, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x299}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x646d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x82b4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x82aa, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x29f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd100, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf01a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf017, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2a9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2aa}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ab}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ac}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ad}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd100, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ae}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2af}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf010, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2b9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ba}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2bb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2bc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2bd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2be}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2bf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x141a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f29, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2c9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x60f1, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ca}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6113, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2cb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6135, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2cc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x6157, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2cd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ce}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2cf}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf008, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf004, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf002, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xce06, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2d9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2da}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13e4, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2db}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2dc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2dd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8bc0, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2de}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c3f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2df}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c09, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa120, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa310, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xa420, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd3b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x65ad, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x43c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2e9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ea}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x82fe, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2eb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ec}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x82f6, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ed}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ee}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ef}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f1}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf024, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f2}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd15d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f3}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f4}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf021, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f5}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f6}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f7}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1c6, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2f9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf01c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2fa}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd15d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2fb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2fc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf019, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2fd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2fe}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x2ff}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd199, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x300}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x301}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf014, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x302}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x303}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x304}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf011, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x305}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x306}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x307}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8311, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x308}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x309}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x830e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd1e5, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf009, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd191, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x30f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x310}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x311}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x312}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x313}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd16b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x314}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x315}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x316}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x13cf, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x317}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x318}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x141a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x319}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f7a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd706, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x5f2c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x40e7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x31f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x320}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x321}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c0f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x322}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b05, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x323}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x324}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x325}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c03, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x326}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1502, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x327}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0c0f, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x328}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b0a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x329}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x9503, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x32a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xcd3c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x32b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x32c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x644d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x32d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x43c7, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x32e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd700, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x32f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x37c9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x330}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x8344, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x331}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x33a9, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x332}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x833c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x333}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x334}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x335}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x336}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x337}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf019, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x338}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x339}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x33a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf016, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x33b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x33c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x33d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x33e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x33f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf011, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x340}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd13e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x341}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x342}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf00e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x343}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd702, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x344}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x4098, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x345}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x346}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x347}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf009, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x348}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x349}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd049, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x34a}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf006, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x34b}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x34c}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd04b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x34d}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf003, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x34e}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd17a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x34f}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd048, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x350}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1800, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x351}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x093a, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x352}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA10E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0883, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA10C, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0f32, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA10A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0676, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA108, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x00fa, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA106, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x021d, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA104, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x12fe, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA102, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x01ca, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA100, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x047f, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA110, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x00ff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA016, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0020, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA012, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x1ff8, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA014, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd13e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ff8}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd15c, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ff9}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd16b, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ffa}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xd15d, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ffb}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b0e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ffc}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b0e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ffd}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b0e, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1ffe}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_SWC , 0, 0xa014, 0xa012, 0x1fff}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA164, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0972, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA166, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0968, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA168, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0a0b, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA16A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0a01, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA16C, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0b8a, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA16E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0bf9, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA170, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x125c, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA172, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x3fff, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0xA162, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x007F, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x0 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+}; -+ -+rtk_hwpatch_t rtl8264b_algxg_conf[] = { -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x815B, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x75 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x80CD, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x25 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8065, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x15 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8175, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0xa2 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8176, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0xc5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8077, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x40 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8078, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0xcc , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8969, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x0f , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8957, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x2C , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8959, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x15 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x895A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x3E , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x895F, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x1E , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8165, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x22 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x827E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x68 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8167, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x33 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8013, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x39 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8fd7, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x14 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8fd6, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x1e , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8fd5, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x1e , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x82D9, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x20 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x82DA, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x00 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x816E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0xab , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8159, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x58 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x815A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x99 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8139, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x25 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8125, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x67 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8126, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x89 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x827D, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x42 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+}; -+ -+rtk_hwpatch_t rtl8264b_alg_giga_conf[] = { -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80b8, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x4d , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80b9, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0xcc , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80ba, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80bb, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 13, 8 , 0x0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80bc, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x37 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80bd, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 12, 8 , 0x0c , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80be, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0xBB , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80bf, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0xca , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80c0, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x45 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80c2, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x3b , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80cc, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x16 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80cd, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 10, 8 , 0x4 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80ce, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80cf, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 13, 8 , 0x0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80d0, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x53 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80d1, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 12, 8 , 0x0a , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80d2, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0xB9 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80d3, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0xd0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80d4, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x4a , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80d6, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x35 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80a4, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x0d , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80a5, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0xa4 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80a6, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x59 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80a7, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 13, 8 , 0x05 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80a8, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0xab , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80a9, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 12, 8 , 0x0b , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80aa, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0xef , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80ab, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0xae , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80ac, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0xdf , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x80ae, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x28 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x8367, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x5d , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+}; -+ -+rtk_hwpatch_t rtl8264b_normal_conf[] = { -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbd92, 15, 0 , 0x002e, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbd94, 15, 0 , 0x8003, RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbd96, 3 , 0 , 0xf , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbd96, 3 , 0 , 0x0 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbd94, 15, 0 , 0x800b, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbd96, 3 , 0 , 0xf , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xbd96, 3 , 0 , 0x0 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x817D, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x07 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x8426, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x46 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x8428, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x46 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x84de, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x84e0, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x00fc, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x84e2, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf61a, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x84e4, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x58 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x84e6, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x84e8, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x00fc, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x84ea, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf61a, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x84ec, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x58 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x84ee, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0000, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x84f0, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x00fc, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x84f2, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0xf61a, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x84f4, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 8 , 0x58 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xae32, 5 , 5 , 0x1 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x8018, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 12, 12, 0x1 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8fdf, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x0496, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8fe1, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x03a5, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8fe3, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x02e5, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8fe5, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x020d, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8fe7, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x0496, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8fe9, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x03a5, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8feb, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x02e5, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8fed, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x020d, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8fef, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x0496, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8ff1, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x03a5, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8ff3, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x02e5, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8ff5, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x020d, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8ff7, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x0496, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8ff9, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x03a5, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8ffb, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x02e5, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8ffd, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 0 , 0x020d, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb516, 6 , 0 , 0x0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8fda, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x04 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8fdb, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x05 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8132, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x77 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8134, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x88 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x80ca, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x77 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x80cc, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x88 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8062, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x77 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87c, 15, 0 , 0x8064, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb87e, 15, 8 , 0x88 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa436, 15, 0 , 0x801E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xa438, 15, 0 , 0x0012, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+}; -+ -+rtk_hwpatch_t rtl8264b_dataram_conf[] = { -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb820, 7 , 7 , 0x0 , RTK_PATCH_CMP_WS , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb896, 0 , 0 , 0x0 , RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb892, 15, 8 , 0x0 , RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC037, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x33 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC038, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x2A , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC039, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x25 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC03A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x20 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC03B, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x1C , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC03C, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x17 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC03D, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x13 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC075, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xA1 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC076, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xB1 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC077, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x2E , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC078, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x55 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC079, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x19 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC07A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xDC , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC07B, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xA0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC10B, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xD5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC10C, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xD5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC10D, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xD5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC10E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xD5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC10F, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xD5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC110, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xD5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC149, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x08 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC14A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x08 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC14B, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x08 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC14C, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x08 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC14D, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x08 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC14E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x08 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC166, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xEE , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC167, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xEE , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC168, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x07 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC169, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x09 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC16A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x0B , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC16B, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x0D , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC16C, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x13 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC16D, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x0E , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC16E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x11 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC16F, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x14 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC170, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x17 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC171, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x15 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC172, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0x10 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC173, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0x0B , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC128, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xF7 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC129, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xF7 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC12A, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xF8 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC12B, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xF7 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC12C, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xF6 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC12D, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xF5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC12E, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xF2 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC12F, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xF7 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC130, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xF5 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC131, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xF2 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC132, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xF0 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC133, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xF1 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC134, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 15, 8 , 0xF4 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb88e, 15, 0 , 0xC135, RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb890, 7 , 0 , 0xF7 , RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PHYOCP , 0xf , 0 , 0xb896, 0 , 0 , 0x1 , RTK_PATCH_CMP_W , 0, 0, 0, 0}, -+}; -+ -+rtk_hwpatch_t rtl8264b_rtct_conf[] = { -+}; -+ -diff --git a/drivers/net/phy/rtl8261n/error.h b/drivers/net/phy/rtl8261n/error.h -new file mode 100644 -index 000000000000..d99a996f8c05 ---- /dev/null -+++ b/drivers/net/phy/rtl8261n/error.h -@@ -0,0 +1,165 @@ -+/* -+ * SPDX-License-Identifier: GPL-2.0-only -+ * -+ * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. -+ */ -+ -+#ifndef __COMMON_ERROR_H__ -+#define __COMMON_ERROR_H__ -+ -+/* -+ * Include Files -+ */ -+#if defined(RTK_PHYDRV_IN_LINUX) -+ #include "type.h" -+#else -+ #include -+#endif -+/* -+ * Data Type Declaration -+ */ -+typedef enum rt_error_common_e -+{ -+ RT_ERR_FAILED = -1, /* General Error */ -+ -+ /* 0x0000xxxx for common error code */ -+ RT_ERR_OK = 0, /* 0x00000000, OK */ -+ RT_ERR_INPUT = 0xF001, /* 0x0000F001, invalid input parameter */ -+ RT_ERR_UNIT_ID, /* 0x0000F002, invalid unit id */ -+ RT_ERR_PORT_ID, /* 0x0000F003, invalid port id */ -+ RT_ERR_PORT_MASK, /* 0x0000F004, invalid port mask */ -+ RT_ERR_PORT_LINKDOWN, /* 0x0000F005, link down port status */ -+ RT_ERR_ENTRY_INDEX, /* 0x0000F006, invalid entry index */ -+ RT_ERR_NULL_POINTER, /* 0x0000F007, input parameter is null pointer */ -+ RT_ERR_QUEUE_ID, /* 0x0000F008, invalid queue id */ -+ RT_ERR_QUEUE_NUM, /* 0x0000F009, invalid queue number */ -+ RT_ERR_BUSYWAIT_TIMEOUT, /* 0x0000F00a, busy watting time out */ -+ RT_ERR_MAC, /* 0x0000F00b, invalid mac address */ -+ RT_ERR_OUT_OF_RANGE, /* 0x0000F00c, input parameter out of range */ -+ RT_ERR_CHIP_NOT_SUPPORTED, /* 0x0000F00d, functions not supported by this chip model */ -+ RT_ERR_SMI, /* 0x0000F00e, SMI error */ -+ RT_ERR_NOT_INIT, /* 0x0000F00f, The module is not initial */ -+ RT_ERR_CHIP_NOT_FOUND, /* 0x0000F010, The chip can not found */ -+ RT_ERR_NOT_ALLOWED, /* 0x0000F011, actions not allowed by the function */ -+ RT_ERR_DRIVER_NOT_FOUND, /* 0x0000F012, The driver can not found */ -+ RT_ERR_SEM_LOCK_FAILED, /* 0x0000F013, Failed to lock semaphore */ -+ RT_ERR_SEM_UNLOCK_FAILED, /* 0x0000F014, Failed to unlock semaphore */ -+ RT_ERR_THREAD_EXIST, /* 0x0000F015, Thread exist */ -+ RT_ERR_THREAD_CREATE_FAILED, /* 0x0000F016, Thread create fail */ -+ RT_ERR_FWD_ACTION, /* 0x0000F017, Invalid forwarding Action */ -+ RT_ERR_IPV4_ADDRESS, /* 0x0000F018, Invalid IPv4 address */ -+ RT_ERR_IPV6_ADDRESS, /* 0x0000F019, Invalid IPv6 address */ -+ RT_ERR_PRIORITY, /* 0x0000F01a, Invalid Priority value */ -+ RT_ERR_FID, /* 0x0000F01b, invalid fid */ -+ RT_ERR_ENTRY_NOTFOUND, /* 0x0000F01c, specified entry not found */ -+ RT_ERR_DROP_PRECEDENCE, /* 0x0000F01d, invalid drop precedence */ -+ RT_ERR_NOT_FINISH, /* 0x0000F01e, Action not finish, still need to wait */ -+ RT_ERR_TIMEOUT, /* 0x0000F01f, Time out */ -+ RT_ERR_REG_ARRAY_INDEX_1, /* 0x0000F020, invalid index 1 of register array */ -+ RT_ERR_REG_ARRAY_INDEX_2, /* 0x0000F021, invalid index 2 of register array */ -+ RT_ERR_ETHER_TYPE, /* 0x0000F022, invalid ether type */ -+ RT_ERR_MBUF_PKT_NOT_AVAILABLE, /* 0x0000F023, mbuf->packet is not available */ -+ RT_ERR_QOS_INVLD_RSN, /* 0x0000F024, invalid pkt to CPU reason */ -+ RT_ERR_CB_FUNCTION_EXIST, /* 0x0000F025, Callback function exist */ -+ RT_ERR_CB_FUNCTION_FULL, /* 0x0000F026, Callback function number is full */ -+ RT_ERR_CB_FUNCTION_NOT_FOUND, /* 0x0000F027, Callback function can not found */ -+ RT_ERR_TBL_FULL, /* 0x0000F028, The table is full */ -+ RT_ERR_TRUNK_ID, /* 0x0000F029, invalid trunk id */ -+ RT_ERR_TYPE, /* 0x0000F02a, invalid type */ -+ RT_ERR_ENTRY_EXIST, /* 0x0000F02b, entry exists */ -+ RT_ERR_CHIP_UNDEFINED_VALUE, /* 0x0000F02c, chip returned an undefined value */ -+ RT_ERR_EXCEEDS_CAPACITY, /* 0x0000F02d, exceeds the capacity of hardware */ -+ RT_ERR_ENTRY_REFERRED, /* 0x0000F02e, entry is still being referred */ -+ RT_ERR_OPER_DENIED, /* 0x0000F02f, operation denied */ -+ RT_ERR_PORT_NOT_SUPPORTED, /* 0x0000F030, functions not supported by this port */ -+ RT_ERR_SOCKET, /* 0x0000F031, socket error */ -+ RT_ERR_MEM_ALLOC, /* 0x0000F032, insufficient memory resource */ -+ RT_ERR_ABORT, /* 0x0000F033, operation aborted */ -+ RT_ERR_DEV_ID, /* 0x0000F034, invalid device id */ -+ RT_ERR_DRIVER_NOT_SUPPORTED, /* 0x0000F035, functions not supported by this driver */ -+ RT_ERR_NOT_SUPPORTED, /* 0x0000F036, functions not supported */ -+ RT_ERR_SER, /* 0x0000F037, ECC or parity error */ -+ RT_ERR_MEM_NOT_ALIGN, /* 0x0000F038, memory address is not aligned */ -+ RT_ERR_SEM_FAKELOCK_OK, /* 0x0000F039, attach thread lock a semaphore which was already locked */ -+ RT_ERR_CHECK_FAILED, /* 0x0000F03a, check result is failed */ -+ -+ RT_ERR_COMMON_END = 0xFFFF /* The symbol is the latest symbol of common error */ -+} rt_error_common_t; -+ -+/* -+ * Macro Definition -+ */ -+#define RT_PARAM_CHK(expr, errCode)\ -+do {\ -+ if ((int32)(expr)) {\ -+ return errCode; \ -+ }\ -+} while (0) -+ -+#define RT_PARAM_CHK_EHDL(expr, errCode, err_hdl)\ -+do {\ -+ if ((int32)(expr)) {\ -+ {err_hdl}\ -+ return errCode; \ -+ }\ -+} while (0) -+ -+#define RT_INIT_CHK(state)\ -+do {\ -+ if (INIT_COMPLETED != (state)) {\ -+ return RT_ERR_NOT_INIT;\ -+ }\ -+} while (0) -+ -+#define RT_INIT_REENTRY_CHK(state)\ -+do {\ -+ if (INIT_COMPLETED == (state)) {\ -+ osal_printf(" %s had already been initialized!\n", __FUNCTION__);\ -+ return RT_ERR_OK;\ -+ }\ -+} while (0) -+ -+#define RT_INIT_REENTRY_CHK_NO_WARNING(state)\ -+ do {\ -+ if (INIT_COMPLETED == (state)) {\ -+ return RT_ERR_OK;\ -+ }\ -+ } while (0) -+ -+#define RT_ERR_CHK(op, ret)\ -+do {\ -+ if ((ret = (op)) != RT_ERR_OK)\ -+ return ret;\ -+} while(0) -+ -+#define RT_ERR_HDL(op, errHandle, ret)\ -+do {\ -+ if ((ret = (op)) != RT_ERR_OK)\ -+ goto errHandle;\ -+} while(0) -+ -+#define RT_ERR_CHK_EHDL(op, ret, err_hdl)\ -+do {\ -+ if ((ret = (op)) != RT_ERR_OK)\ -+ {\ -+ {err_hdl}\ -+ return ret;\ -+ }\ -+} while(0) -+ -+#define RT_NULL_HDL(pointer, err_label)\ -+do {\ -+ if (NULL == (pointer)) {\ -+ goto err_label;\ -+ }\ -+} while (0) -+ -+#define RT_ERR_VOID_CHK(op, ret)\ -+do {\ -+ if ((ret = (op)) != RT_ERR_OK) {\ -+ osal_printf("Fail in %s %d, ret %x!\n", __FUNCTION__, __LINE__, ret);\ -+ return ;}\ -+} while(0) -+ -+#endif /* __COMMON_ERROR_H__ */ -+ -diff --git a/drivers/net/phy/rtl8261n/phy_patch.c b/drivers/net/phy/rtl8261n/phy_patch.c -new file mode 100644 -index 000000000000..7563f6705333 ---- /dev/null -+++ b/drivers/net/phy/rtl8261n/phy_patch.c -@@ -0,0 +1,188 @@ -+/* -+ * SPDX-License-Identifier: GPL-2.0-only -+ * -+ * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. -+ */ -+ -+/* -+ * Include Files -+ */ -+#if defined(RTK_PHYDRV_IN_LINUX) -+ #include "rtk_osal.h" -+#else -+ #include -+ #include -+ #include -+ #include -+ #include -+#endif -+ -+/* -+ * Function Declaration -+ */ -+uint8 phy_patch_op_translate(uint8 patch_mode, uint8 patch_op, uint8 compare_op) -+{ -+ if (patch_mode != PHY_PATCH_MODE_CMP) -+ { -+ return patch_op; -+ } -+ else -+ { -+ switch (compare_op) -+ { -+ case RTK_PATCH_CMP_WS: -+ return RTK_PATCH_OP_SKIP; -+ case RTK_PATCH_CMP_W: -+ case RTK_PATCH_CMP_WC: -+ case RTK_PATCH_CMP_SWC: -+ default: -+ return RTK_PATCH_OP_TO_CMP(patch_op, compare_op); -+ } -+ } -+} -+ -+int32 phy_patch_op(rt_phy_patch_db_t *pPhy_patchDb, uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_op, uint16 portmask, uint16 pagemmd, uint16 addr, uint8 msb, uint8 lsb, uint16 data, uint8 patch_mode) -+{ -+ rtk_hwpatch_t op; -+ -+ op.patch_op = patch_op; -+ op.portmask = portmask; -+ op.pagemmd = pagemmd; -+ op.addr = addr; -+ op.msb = msb; -+ op.lsb = lsb; -+ op.data = data; -+ op.compare_op = RTK_PATCH_CMP_W; -+ -+ return pPhy_patchDb->fPatch_op(unit, port, portOffset, &op, patch_mode); -+} -+ -+static int32 _phy_patch_process(uint32 unit, rtk_port_t port, uint8 portOffset, rtk_hwpatch_t *pPatch, int32 size, uint8 patch_mode) -+{ -+ int32 i = 0; -+ int32 ret = 0; -+ int32 chk_ret = RT_ERR_OK; -+ int32 n; -+ rtk_hwpatch_t *patch = pPatch; -+ rt_phy_patch_db_t *pPatchDb = NULL; -+ -+ PHYPATCH_DB_GET(unit, port, pPatchDb); -+ -+ if (size <= 0) -+ { -+ return RT_ERR_OK; -+ } -+ n = size / sizeof(rtk_hwpatch_t); -+ -+ for (i = 0; i < n; i++) -+ { -+ ret = pPatchDb->fPatch_op(unit, port, portOffset, &patch[i], patch_mode); -+ if ((ret != RT_ERR_ABORT) && (ret != RT_ERR_OK)) -+ { -+ if ((ret == RT_ERR_CHECK_FAILED) && (patch_mode == PHY_PATCH_MODE_CMP)) -+ { -+ osal_printf("PATCH CHECK: Failed entry:%u|%u|0x%X|0x%X|%u|%u|0x%X\n", -+ i + 1, patch[i].patch_op, patch[i].pagemmd, patch[i].addr, patch[i].msb, patch[i].lsb, patch[i].data); -+ chk_ret = RT_ERR_CHECK_FAILED; -+ continue; -+ } -+ else -+ { -+ RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u %s failed! %u[%u][0x%X][0x%X][0x%X] ret=0x%X\n", unit, port, __FUNCTION__, -+ i+1, patch[i].patch_op, patch[i].pagemmd, patch[i].addr, patch[i].data, ret); -+ return ret; -+ } -+ } -+ -+ } -+ return (chk_ret == RT_ERR_CHECK_FAILED) ? chk_ret : RT_ERR_OK; -+} -+ -+rtk_hwpatch_t rtl826XB_patch_rtk_conf[] = { -+ {RTK_PATCH_OP_PSDS0 , 0xff , 0x07 , 0x10 , 15, 0, 0x80aa, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+ {RTK_PATCH_OP_PSDS0 , 0xff , 0x06 , 0x12 , 15, 0, 0x5078, RTK_PATCH_CMP_WC , 0, 0, 0, 0}, -+}; -+ -+/* Function Name: -+ * phy_patch -+ * Description: -+ * apply initial patch data to PHY -+ * Input: -+ * unit - unit id -+ * port - port id -+ * portOffset - the index offset of port based the base port in the PHY chip -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_CHECK_FAILED -+ * RT_ERR_NOT_SUPPORTED -+ * Note: -+ * None -+ */ -+int32 phy_patch(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode) -+{ -+ int32 ret = RT_ERR_OK; -+ int32 chk_ret = RT_ERR_OK; -+ uint32 i = 0; -+ uint8 patch_type = 0; -+ rt_phy_patch_db_t *pPatchDb = NULL; -+ rtk_hwpatch_seq_t *table = NULL; -+ -+ PHYPATCH_DB_GET(unit, port, pPatchDb); -+ -+ if ((pPatchDb == NULL) || (pPatchDb->fPatch_op == NULL) || (pPatchDb->fPatch_flow == NULL)) -+ { -+ RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u phy_patch, db is NULL\n", unit, port); -+ return RT_ERR_DRIVER_NOT_SUPPORTED; -+ } -+ -+ if (patch_mode == PHY_PATCH_MODE_CMP) -+ { -+ table = pPatchDb->cmp_table; -+ } -+ else -+ { -+ table = pPatchDb->seq_table; -+ } -+ RT_LOG(LOG_INFO, (MOD_HAL | MOD_PHY), "phy_patch: U%u P%u portOffset:%u patch_mode:%u\n", unit, port, portOffset, patch_mode); -+ -+ for (i = 0; i < RTK_PATCH_SEQ_MAX; i++) -+ { -+ patch_type = table[i].patch_type; -+ RT_LOG(LOG_INFO, (MOD_HAL | MOD_PHY), "phy_patch: table[%u] patch_type:%u\n", i, patch_type); -+ -+ if (RTK_PATCH_TYPE_IS_DATA(patch_type)) -+ { -+ ret = _phy_patch_process(unit, port, portOffset, table[i].patch.data.conf, table[i].patch.data.size, patch_mode); -+ -+ if (ret == RT_ERR_CHECK_FAILED) -+ chk_ret = ret; -+ else if (ret != RT_ERR_OK) -+ { -+ RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u patch_mode:%u id:%u patch-%u failed. ret:0x%X\n", unit, port, patch_mode, i, patch_type, ret); -+ return ret; -+ } -+ } -+ else if (RTK_PATCH_TYPE_IS_FLOW(patch_type)) -+ { -+ RT_ERR_CHK_EHDL(pPatchDb->fPatch_flow(unit, port, portOffset, table[i].patch.flow_id, patch_mode), -+ ret, RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u patch_mode:%u id:%u patch-%u failed. ret:0x%X\n", unit, port, patch_mode, i, patch_type, ret);); -+ } -+ else -+ { -+ break; -+ } -+ } -+ ret = _phy_patch_process(unit, port, portOffset, rtl826XB_patch_rtk_conf, sizeof(rtl826XB_patch_rtk_conf), patch_mode); -+ if (ret == RT_ERR_CHECK_FAILED) -+ chk_ret = ret; -+ else if (ret != RT_ERR_OK) -+ { -+ RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u patch_mode:%u id:%u patch-%u failed. ret:0x%X\n", unit, port, patch_mode, i, patch_type, ret); -+ return ret; -+ } -+ -+ return (chk_ret == RT_ERR_CHECK_FAILED) ? chk_ret : RT_ERR_OK; -+} -diff --git a/drivers/net/phy/rtl8261n/phy_patch.h b/drivers/net/phy/rtl8261n/phy_patch.h -new file mode 100644 -index 000000000000..c2b7b1279c7e ---- /dev/null -+++ b/drivers/net/phy/rtl8261n/phy_patch.h -@@ -0,0 +1,174 @@ -+/* -+ * SPDX-License-Identifier: GPL-2.0-only -+ * -+ * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. -+ */ -+ -+#ifndef __HAL_PHY_PATCH_H__ -+#define __HAL_PHY_PATCH_H__ -+ -+/* -+ * Include Files -+ */ -+#if defined(RTK_PHYDRV_IN_LINUX) -+ #include "rtk_phylib_def.h" -+#else -+ #include -+ #include -+#endif -+ -+/* -+ * Symbol Definition -+ */ -+#define PHYPATCH_PHYCTRL_IN_HALCTRL 0 /* 3.6.x: 1 ,4.0.x: 1, 4.1.x+: 0 */ -+#define PHYPATCH_FMAILY_IN_HWP 0 /* 3.6.x: 1 ,4.0.x: 0, 4.1.x+: 0 */ -+#define PHY_PATCH_MODE_BCAST_DEFAULT PHY_PATCH_MODE_BCAST /* 3.6.x: PHY_PATCH_MODE_BCAST_BUS ,4.0.x+: PHY_PATCH_MODE_BCAST */ -+ -+#define PHY_PATCH_MODE_NORMAL 0 -+#define PHY_PATCH_MODE_CMP 1 -+#define PHY_PATCH_MODE_BCAST 2 -+#define PHY_PATCH_MODE_BCAST_BUS 3 -+ -+#define RTK_PATCH_CMP_W 0 /* write */ -+#define RTK_PATCH_CMP_WC 1 /* compare */ -+#define RTK_PATCH_CMP_SWC 2 /* sram compare */ -+#define RTK_PATCH_CMP_WS 3 /* skip */ -+ -+#define RTK_PATCH_OP_SECTION_SIZE 50 -+#define RTK_PATCH_OP_TO_CMP(_op, _cmp) (_op + (RTK_PATCH_OP_SECTION_SIZE * _cmp)) -+/* 0~49 normal op */ -+#define RTK_PATCH_OP_PHY 0 -+#define RTK_PATCH_OP_PHYOCP 1 -+#define RTK_PATCH_OP_TOP 2 -+#define RTK_PATCH_OP_TOPOCP 3 -+#define RTK_PATCH_OP_PSDS0 4 -+#define RTK_PATCH_OP_PSDS1 5 -+#define RTK_PATCH_OP_MSDS 6 -+#define RTK_PATCH_OP_MAC 7 -+ -+/* 50~99 normal op for compare */ -+#define RTK_PATCH_OP_CMP_PHY RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PHY , RTK_PATCH_CMP_WC) -+#define RTK_PATCH_OP_CMP_PHYOCP RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PHYOCP , RTK_PATCH_CMP_WC) -+#define RTK_PATCH_OP_CMP_TOP RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_TOP , RTK_PATCH_CMP_WC) -+#define RTK_PATCH_OP_CMP_TOPOCP RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_TOPOCP , RTK_PATCH_CMP_WC) -+#define RTK_PATCH_OP_CMP_PSDS0 RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PSDS0 , RTK_PATCH_CMP_WC) -+#define RTK_PATCH_OP_CMP_PSDS1 RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PSDS1 , RTK_PATCH_CMP_WC) -+#define RTK_PATCH_OP_CMP_MSDS RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_MSDS , RTK_PATCH_CMP_WC) -+#define RTK_PATCH_OP_CMP_MAC RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_MAC , RTK_PATCH_CMP_WC) -+ -+/* 100~149 normal op for sram compare */ -+#define RTK_PATCH_OP_CMP_SRAM_PHY RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PHY , RTK_PATCH_CMP_SWC) -+#define RTK_PATCH_OP_CMP_SRAM_PHYOCP RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PHYOCP , RTK_PATCH_CMP_SWC) -+#define RTK_PATCH_OP_CMP_SRAM_TOP RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_TOP , RTK_PATCH_CMP_SWC) -+#define RTK_PATCH_OP_CMP_SRAM_TOPOCP RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_TOPOCP , RTK_PATCH_CMP_SWC) -+#define RTK_PATCH_OP_CMP_SRAM_PSDS0 RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PSDS0 , RTK_PATCH_CMP_SWC) -+#define RTK_PATCH_OP_CMP_SRAM_PSDS1 RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_PSDS1 , RTK_PATCH_CMP_SWC) -+#define RTK_PATCH_OP_CMP_SRAM_MSDS RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_MSDS , RTK_PATCH_CMP_SWC) -+#define RTK_PATCH_OP_CMP_SRAM_MAC RTK_PATCH_OP_TO_CMP(RTK_PATCH_OP_MAC , RTK_PATCH_CMP_SWC) -+ -+/* 200~255 control op */ -+#define RTK_PATCH_OP_DELAY_MS 200 -+#define RTK_PATCH_OP_SKIP 255 -+ -+ -+/* -+ patch type PHY_PATCH_TYPE_NONE => empty -+ patch type: PHY_PATCH_TYPE_TOP ~ (PHY_PATCH_TYPE_END-1) => data array -+ patch type: PHY_PATCH_TYPE_END ~ (PHY_PATCH_TYPE_END + RTK_PATCH_TYPE_FLOW_MAX) => flow -+*/ -+#define RTK_PATCH_TYPE_IS_DATA(_patch_type) (_patch_type > PHY_PATCH_TYPE_NONE && _patch_type < PHY_PATCH_TYPE_END) -+#define RTK_PATCH_TYPE_IS_FLOW(_patch_type) (_patch_type >= PHY_PATCH_TYPE_END && _patch_type <= (PHY_PATCH_TYPE_END + RTK_PATCH_TYPE_FLOWID_MAX)) -+ -+ -+/* -+ * Macro Definition -+ */ -+#if PHYPATCH_PHYCTRL_IN_HALCTRL -+ #define PHYPATCH_DB_GET(_unit, _port, _pPatchDb) \ -+ do {\ -+ hal_control_t *pHalCtrl = NULL;\ -+ if ((pHalCtrl = hal_ctrlInfo_get(_unit)) == NULL)\ -+ return RT_ERR_FAILED;\ -+ _pPatchDb = (pHalCtrl->pPhy_ctrl[_port]->pPhy_patchDb);\ -+ } while(0) -+#else -+ #if defined(RTK_PHYDRV_IN_LINUX) -+ #else -+ #include -+ #include -+ #endif -+ #define PHYPATCH_DB_GET(_unit, _port, _pPatchDb) \ -+ do {\ -+ rt_phyctrl_t *pPhyCtrl = NULL;\ -+ if ((pPhyCtrl = phy_phyctrl_get(_unit, _port)) == NULL)\ -+ return RT_ERR_FAILED;\ -+ _pPatchDb = (pPhyCtrl->pPhy_patchDb);\ -+ } while(0) -+#endif -+ -+#if PHYPATCH_FMAILY_IN_HWP -+ #define PHYPATCH_IS_RTKSDS(_unit) (HWP_9300_FAMILY_ID(_unit) || HWP_9310_FAMILY_ID(_unit)) -+#else -+ #define PHYPATCH_IS_RTKSDS(_unit) (RTK_9300_FAMILY_ID(_unit) || RTK_9310_FAMILY_ID(_unit) || RTK_9311B_FAMILY_ID(_unit) || RTK_9330_FAMILY_ID(_unit)) -+#endif -+ -+#define PHYPATCH_TABLE_ASSIGN(_pPatchDb, _table, _idx, _patch_type, _para) \ -+ do {\ -+ if (RTK_PATCH_TYPE_IS_DATA(_patch_type)) {\ -+ _pPatchDb->_table[_idx].patch_type = _patch_type;\ -+ _pPatchDb->_table[_idx].patch.data.conf = _para;\ -+ _pPatchDb->_table[_idx].patch.data.size = sizeof(_para);\ -+ }\ -+ else if (RTK_PATCH_TYPE_IS_FLOW(_patch_type)) {\ -+ _pPatchDb->_table[_idx].patch_type = _patch_type;\ -+ _pPatchDb->_table[_idx].patch.flow_id = _patch_type;\ -+ }\ -+ else {\ -+ _pPatchDb->_table[_idx].patch_type = PHY_PATCH_TYPE_NONE;\ -+ }\ -+ } while(0) -+#define PHYPATCH_SEQ_TABLE_ASSIGN(_pPatchDb, _idx, _patch_type, _para) PHYPATCH_TABLE_ASSIGN(_pPatchDb, seq_table, _idx, _patch_type, _para) -+#define PHYPATCH_CMP_TABLE_ASSIGN(_pPatchDb, _idx, _patch_type, _para) PHYPATCH_TABLE_ASSIGN(_pPatchDb, cmp_table, _idx, _patch_type, _para) -+ -+#define PHYPATCH_COMPARE(_mmdpage, _reg, _msb, _lsb, _exp, _real, _mask) \ -+ do {\ -+ uint32 _rData = REG32_FIELD_GET(_real, _lsb, _mask);\ -+ if (_exp != _rData) {\ -+ osal_printf("PATCH CHECK: %u(0x%X).%u(0x%X)[%u:%u] = 0x%X (!= 0x%X)\n", _mmdpage, _mmdpage, _reg, _reg, _msb, _lsb, _rData, _exp);\ -+ return RT_ERR_CHECK_FAILED;\ -+ }\ -+ } while (0) -+ -+/* -+ * Function Declaration -+ */ -+ -+extern uint8 phy_patch_op_translate(uint8 patch_mode, uint8 patch_op, uint8 compare_op); -+extern int32 phy_patch_op(rt_phy_patch_db_t *pPhy_patchDb, uint32 unit, rtk_port_t port, uint8 portOffset, -+ uint8 patch_op, uint16 portmask, uint16 pagemmd, uint16 addr, uint8 msb, uint8 lsb, uint16 data, -+ uint8 patch_mode); -+ -+ -+/* Function Name: -+ * phy_patch -+ * Description: -+ * apply initial patch data to PHY -+ * Input: -+ * unit - unit id -+ * port - port id -+ * portOffset - the index offset of port based the base port in the PHY chip -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_CHECK_FAILED -+ * RT_ERR_NOT_SUPPORTED -+ * Note: -+ * None -+ */ -+extern int32 phy_patch(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode); -+ -+ -+ -+#endif /* __HAL_PHY_PATCH_H__ */ -diff --git a/drivers/net/phy/rtl8261n/phy_rtl826xb_patch.c b/drivers/net/phy/rtl8261n/phy_rtl826xb_patch.c -new file mode 100644 -index 000000000000..0bfd93033f83 ---- /dev/null -+++ b/drivers/net/phy/rtl8261n/phy_rtl826xb_patch.c -@@ -0,0 +1,1031 @@ -+/* -+ * SPDX-License-Identifier: GPL-2.0-only -+ * -+ * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. -+ */ -+ -+/* -+ * Include Files -+ */ -+#if defined(RTK_PHYDRV_IN_LINUX) -+ #include "phy_rtl826xb_patch.h" -+ #include "construct/conf_rtl8264b.c" -+ #include "construct/conf_rtl8261n_c.c" -+#else -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #if defined(CONFIG_SDK_RTL826XB) -+ #include -+ #include -+ #include -+ #endif -+#endif -+/* -+ * Symbol Definition -+ */ -+#define PHY_PATCH_WAIT_TIMEOUT 10000000 -+ -+#define PHY_PATCH_LOG LOG_INFO -+ -+/* -+ * Data Declaration -+ */ -+ -+/* -+ * Macro Declaration -+ */ -+ -+/* -+ * Function Declaration -+ */ -+static uint16 _phy_rtl826xb_mmd_convert(uint16 page, uint16 addr) -+{ -+ uint16 reg = 0; -+ if (addr < 16) -+ { -+ reg = 0xA400 + (page * 2); -+ } -+ else if (addr < 24) -+ { -+ reg = (16*page) + ((addr - 16) * 2); -+ } -+ else -+ { -+ reg = 0xA430 + ((addr - 24) * 2); -+ } -+ return reg; -+} -+ -+static int32 -+_phy_rtl826xb_patch_wait(uint32 unit, rtk_port_t port, uint32 mmdAddr, uint32 mmdReg, uint32 data, uint32 mask, uint8 patch_mode) -+{ -+ int32 ret = 0; -+ uint32 rData = 0; -+ uint32 cnt = 0; -+ WAIT_COMPLETE_VAR() -+ -+ rtk_port_t p = 0; -+ uint8 smiBus = HWP_PORT_SMI(unit, port); -+ uint32 phyChip = HWP_PHY_MODEL_BY_PORT(unit, port); -+ uint8 bcast_phyad = HWP_PHY_ADDR(unit, port);; -+ -+ -+ if (patch_mode == PHY_PATCH_MODE_BCAST_BUS) -+ { -+ if ((ret = phy_826xb_ctrl_set(unit, port, RTK_PHY_CTRL_MIIM_BCAST, 0)) != RT_ERR_OK) -+ { -+ RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826XB patch wait disable broadcast failed! 0x%X\n", unit, p, ret); -+ return ret; -+ } -+ -+ HWP_PORT_TRAVS_EXCEPT_CPU(unit, p) -+ { -+ if ((HWP_PORT_SMI(unit, p) == smiBus) && (HWP_PHY_MODEL_BY_PORT(unit, p) == phyChip)) -+ { -+ WAIT_COMPLETE(PHY_PATCH_WAIT_TIMEOUT) -+ { -+ if ((ret = phy_common_general_reg_mmd_get(unit, p, mmdAddr, mmdReg, &rData)) != RT_ERR_OK) -+ { -+ return ret; -+ } -+ ++cnt; -+ -+ if ((rData & mask) == data) -+ break; -+ -+ //osal_time_udelay(10); -+ } -+ -+ if (WAIT_COMPLETE_IS_TIMEOUT()) -+ { -+ RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826XB patch wait[%u,0x%X,0x%X,0x%X]:0x%X cnt:%u\n", unit, p, mmdAddr, mmdReg, data, mask, rData, cnt); -+ return RT_ERR_TIMEOUT; -+ } -+ } -+ } -+ -+ osal_time_mdelay(1); -+ //for port in same SMI bus, set mdio broadcast ENABLE -+ HWP_PORT_TRAVS_EXCEPT_CPU(unit, p) -+ { -+ if ((HWP_PORT_SMI(unit, p) == smiBus) && (HWP_PHY_MODEL_BY_PORT(unit, p) == phyChip)) -+ { -+ if ((ret = phy_826xb_ctrl_set(unit, p, RTK_PHY_CTRL_MIIM_BCAST_PHYAD, (uint32)bcast_phyad)) != RT_ERR_OK) -+ { -+ RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826XB patch wait set broadcast PHYAD failed! 0x%X\n", unit, p, ret); -+ return ret; -+ } -+ -+ if ((ret = phy_826xb_ctrl_set(unit, p, RTK_PHY_CTRL_MIIM_BCAST, 1)) != RT_ERR_OK) -+ { -+ RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826XB patch wait enable broadcast failed! 0x%X\n", unit, p, ret); -+ return ret; -+ } -+ } -+ } -+ } -+ else if (patch_mode == PHY_PATCH_MODE_BCAST) -+ { -+ if ((ret = phy_826xb_ctrl_set(unit, port, RTK_PHY_CTRL_MIIM_BCAST, 0)) != RT_ERR_OK) -+ { -+ RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826x patch wait disable broadcast failed! 0x%X\n", unit, p, ret); -+ return ret; -+ } -+ -+ HWP_PORT_TRAVS_EXCEPT_CPU(unit, p) -+ { -+ if (HWP_PHY_BASE_MACID(unit, p) == HWP_PHY_BASE_MACID(unit, port)) -+ { -+ WAIT_COMPLETE(PHY_PATCH_WAIT_TIMEOUT) -+ { -+ if ((ret = phy_common_general_reg_mmd_get(unit, p, mmdAddr, mmdReg, &rData)) != RT_ERR_OK) -+ { -+ return ret; -+ } -+ ++cnt; -+ -+ if ((rData & mask) == data) -+ break; -+ //osal_time_udelay(10); -+ } -+ -+ if (WAIT_COMPLETE_IS_TIMEOUT()) -+ { -+ RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826x patch wait[%u,0x%X,0x%X,0x%X]:0x%X cnt:%u\n", unit, p, mmdAddr, mmdReg, data, mask, rData, cnt); -+ return RT_ERR_TIMEOUT; -+ } -+ } -+ } -+ -+ osal_time_mdelay(1); -+ //for port in same PHY, set mdio broadcast ENABLE -+ HWP_PORT_TRAVS_EXCEPT_CPU(unit, p) -+ { -+ if (HWP_PHY_BASE_MACID(unit, p) == HWP_PHY_BASE_MACID(unit, port)) -+ { -+ if ((ret = phy_826xb_ctrl_set(unit, p, RTK_PHY_CTRL_MIIM_BCAST_PHYAD, (uint32)bcast_phyad)) != RT_ERR_OK) -+ { -+ RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826XB patch wait set broadcast PHYAD failed! 0x%X\n", unit, p, ret); -+ return ret; -+ } -+ -+ if ((ret = phy_826xb_ctrl_set(unit, p, RTK_PHY_CTRL_MIIM_BCAST, 1)) != RT_ERR_OK) -+ { -+ RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826XB patch wait enable broadcast failed! 0x%X\n", unit, p, ret); -+ return ret; -+ } -+ } -+ } -+ } -+ else -+ { -+ WAIT_COMPLETE(PHY_PATCH_WAIT_TIMEOUT) -+ { -+ if ((ret = phy_common_general_reg_mmd_get(unit, port, mmdAddr, mmdReg, &rData)) != RT_ERR_OK) -+ return ret; -+ -+ ++cnt; -+ if ((rData & mask) == data) -+ break; -+ -+ osal_time_mdelay(1); -+ } -+ -+ if (WAIT_COMPLETE_IS_TIMEOUT()) -+ { -+ RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826XB patch wait[%u,0x%X,0x%X,0x%X]:0x%X cnt:%u\n", unit, port, mmdAddr, mmdReg, data, mask, rData, cnt); -+ return RT_ERR_TIMEOUT; -+ } -+ } -+ -+ return RT_ERR_OK; -+} -+ -+static int32 -+_phy_rtl826xb_patch_wait_not_equal(uint32 unit, rtk_port_t port, uint32 mmdAddr, uint32 mmdReg, uint32 data, uint32 mask, uint8 patch_mode) -+{ -+ int32 ret = 0; -+ uint32 rData = 0; -+ uint32 cnt = 0; -+ WAIT_COMPLETE_VAR() -+ -+ rtk_port_t p = 0; -+ uint8 smiBus = HWP_PORT_SMI(unit, port); -+ uint32 phyChip = HWP_PHY_MODEL_BY_PORT(unit, port); -+ uint8 bcast_phyad = HWP_PHY_ADDR(unit, port); -+ -+ if (patch_mode == PHY_PATCH_MODE_BCAST_BUS) -+ { -+ if ((ret = phy_826xb_ctrl_set(unit, port, RTK_PHY_CTRL_MIIM_BCAST, 0)) != RT_ERR_OK) -+ { -+ RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826XB patch wait disable broadcast failed! 0x%X\n", unit, p, ret); -+ return ret; -+ } -+ -+ HWP_PORT_TRAVS_EXCEPT_CPU(unit, p) -+ { -+ if ((HWP_PORT_SMI(unit, p) == smiBus) && (HWP_PHY_MODEL_BY_PORT(unit, p) == phyChip)) -+ { -+ WAIT_COMPLETE(PHY_PATCH_WAIT_TIMEOUT) -+ { -+ if ((ret = phy_common_general_reg_mmd_get(unit, p, mmdAddr, mmdReg, &rData)) != RT_ERR_OK) -+ { -+ return ret; -+ } -+ ++cnt; -+ -+ if ((rData & mask) != data) -+ break; -+ -+ //osal_time_udelay(10); -+ } -+ if (WAIT_COMPLETE_IS_TIMEOUT()) -+ { -+ RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826XB patch wait[%u,0x%X,0x%X,0x%X]:0x%X cnt:%u\n", unit, p, mmdAddr, mmdReg, data, mask, rData, cnt); -+ return RT_ERR_TIMEOUT; -+ } -+ } -+ } -+ -+ osal_time_mdelay(1); -+ //for port in same SMI bus, set mdio broadcast ENABLE -+ HWP_PORT_TRAVS_EXCEPT_CPU(unit, p) -+ { -+ if ((HWP_PORT_SMI(unit, p) == smiBus) && (HWP_PHY_MODEL_BY_PORT(unit, p) == phyChip)) -+ { -+ if ((ret = phy_826xb_ctrl_set(unit, p, RTK_PHY_CTRL_MIIM_BCAST_PHYAD, (uint32)bcast_phyad)) != RT_ERR_OK) -+ { -+ RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826XB patch wait set broadcast PHYAD failed! 0x%X\n", unit, p, ret); -+ return ret; -+ } -+ -+ if ((ret = phy_826xb_ctrl_set(unit, p, RTK_PHY_CTRL_MIIM_BCAST, 1)) != RT_ERR_OK) -+ { -+ RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826XB patch wait enable broadcast failed! 0x%X\n", unit, p, ret); -+ return ret; -+ } -+ } -+ } -+ } -+ else if (patch_mode == PHY_PATCH_MODE_BCAST) -+ { -+ if ((ret = phy_826xb_ctrl_set(unit, port, RTK_PHY_CTRL_MIIM_BCAST, 0)) != RT_ERR_OK) -+ { -+ RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826x patch wait disable broadcast failed! 0x%X\n", unit, p, ret); -+ return ret; -+ } -+ -+ HWP_PORT_TRAVS_EXCEPT_CPU(unit, p) -+ { -+ if (HWP_PHY_BASE_MACID(unit, p) == HWP_PHY_BASE_MACID(unit, port)) -+ { -+ WAIT_COMPLETE(PHY_PATCH_WAIT_TIMEOUT) -+ { -+ if ((ret = phy_common_general_reg_mmd_get(unit, p, mmdAddr, mmdReg, &rData)) != RT_ERR_OK) -+ { -+ return ret; -+ } -+ ++cnt; -+ -+ if (((rData & mask) != data)) -+ break; -+ -+ //osal_time_udelay(10); -+ } -+ -+ if (WAIT_COMPLETE_IS_TIMEOUT()) -+ { -+ RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826XB patch wait[%u,0x%X,0x%X,0x%X]:0x%X cnt:%u\n", unit, p, mmdAddr, mmdReg, data, mask, rData, cnt); -+ return RT_ERR_TIMEOUT; -+ } -+ } -+ } -+ -+ osal_time_mdelay(1); -+ //for port in same PHY, set mdio broadcast ENABLE -+ HWP_PORT_TRAVS_EXCEPT_CPU(unit, p) -+ { -+ if (HWP_PHY_BASE_MACID(unit, p) == HWP_PHY_BASE_MACID(unit, port)) -+ { -+ if ((ret = phy_826xb_ctrl_set(unit, p, RTK_PHY_CTRL_MIIM_BCAST_PHYAD, (uint32)bcast_phyad)) != RT_ERR_OK) -+ { -+ RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826XB patch wait set broadcast PHYAD failed! 0x%X\n", unit, p, ret); -+ return ret; -+ } -+ -+ if ((ret = phy_826xb_ctrl_set(unit, p, RTK_PHY_CTRL_MIIM_BCAST, 1)) != RT_ERR_OK) -+ { -+ RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826XB patch wait enable broadcast failed! 0x%X\n", unit, p, ret); -+ return ret; -+ } -+ } -+ } -+ } -+ else -+ { -+ WAIT_COMPLETE(PHY_PATCH_WAIT_TIMEOUT) -+ { -+ if ((ret = phy_common_general_reg_mmd_get(unit, port, mmdAddr, mmdReg, &rData)) != RT_ERR_OK) -+ return ret; -+ -+ ++cnt; -+ if ((rData & mask) != data) -+ break; -+ -+ osal_time_mdelay(1); -+ } -+ if (WAIT_COMPLETE_IS_TIMEOUT()) -+ { -+ RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u 826xb patch wait[%u,0x%X,0x%X,0x%X]:0x%X cnt:%u\n", unit, port, mmdAddr, mmdReg, data, mask, rData, cnt); -+ return RT_ERR_TIMEOUT; -+ } -+ -+ } -+ -+ return RT_ERR_OK; -+} -+ -+static int32 -+_phy_rtl826xb_patch_top_get(uint32 unit, rtk_port_t port, uint32 topPage, uint32 topReg, uint32 *pData) -+{ -+ int32 ret = 0; -+ uint32 rData = 0; -+ uint32 topAddr = (topPage * 8) + (topReg - 16); -+ -+ if ((ret = phy_common_general_reg_mmd_get(unit, port, PHY_MMD_VEND1, topAddr, &rData)) != RT_ERR_OK) -+ return ret; -+ *pData = rData; -+ return RT_ERR_OK; -+} -+ -+static int32 -+_phy_rtl826xb_patch_top_set(uint32 unit, rtk_port_t port, uint32 topPage, uint32 topReg, uint32 wData) -+{ -+ int32 ret = 0; -+ uint32 topAddr = (topPage * 8) + (topReg - 16); -+ if ((ret = phy_common_general_reg_mmd_set(unit, port, PHY_MMD_VEND1, topAddr, wData)) != RT_ERR_OK) -+ return ret; -+ return RT_ERR_OK; -+} -+ -+static int32 -+_phy_rtl826xb_patch_sds_get(uint32 unit, rtk_port_t port, uint32 sdsPage, uint32 sdsReg, uint32 *pData) -+{ -+ int32 ret = 0; -+ uint32 rData = 0; -+ uint32 sdsAddr = 0x8000 + (sdsReg << 6) + sdsPage; -+ -+ if ((ret = _phy_rtl826xb_patch_top_set(unit, port, 40, 19, sdsAddr)) != RT_ERR_OK) -+ return ret; -+ if ((ret = _phy_rtl826xb_patch_top_get(unit, port, 40, 18, &rData)) != RT_ERR_OK) -+ return ret; -+ *pData = rData; -+ return _phy_rtl826xb_patch_wait(unit, port, PHY_MMD_VEND1, 0x143, 0, BIT_15, PHY_PATCH_MODE_NORMAL); -+} -+ -+static int32 -+_phy_rtl826xb_patch_sds_set(uint32 unit, rtk_port_t port, uint32 sdsPage, uint32 sdsReg, uint32 wData, uint8 patch_mode) -+{ -+ int32 ret = 0; -+ uint32 sdsAddr = 0x8800 + (sdsReg << 6) + sdsPage; -+ -+ if ((ret = _phy_rtl826xb_patch_top_set(unit, port, 40, 17, wData)) != RT_ERR_OK) -+ return ret; -+ if ((ret = _phy_rtl826xb_patch_top_set(unit, port, 40, 19, sdsAddr)) != RT_ERR_OK) -+ return ret; -+ return _phy_rtl826xb_patch_wait(unit, port, PHY_MMD_VEND1, 0x143, 0, BIT_15, patch_mode); -+} -+ -+static int32 _phy_rtl826xb_flow_r1(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode) -+{ -+ int32 ret = RT_ERR_OK; -+ rt_phy_patch_db_t *pPatchDb = NULL; -+ -+ PHYPATCH_DB_GET(unit, port, pPatchDb); -+ -+ //PHYReg_bit w $PHYID 0xb82 16 4 4 0x1 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xb82, 16, 4, 4, 0x1, patch_mode), ret); -+ //PHYReg_bit w $PHYID 0xb82 16 4 4 0x1 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xb82, 16, 4, 4, 0x1, patch_mode), ret); -+ -+ //set patch_rdy [PHYReg_bit r $PHYID 0xb80 16 6 6] ; Wait for patch ready = 1 -+ RT_ERR_CHK(_phy_rtl826xb_patch_wait(unit, port, 31, _phy_rtl826xb_mmd_convert(0xb80, 16), BIT_6, BIT_6, patch_mode), ret); -+ -+ //PHYReg w $PHYID 0xa43 27 $0x8023 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa43, 27, 15, 0, 0x8023, patch_mode), ret); -+ //PHYReg w $PHYID 0xa43 28 $0x3802 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa43, 28, 15, 0, 0x3802, patch_mode), ret); -+ //PHYReg w $PHYID 0xa43 27 0xB82E -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa43, 27, 15, 0, 0xB82E, patch_mode), ret); -+ //PHYReg w $PHYID 0xa43 28 0x1 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa43, 28, 15, 0, 0x1, patch_mode), ret); -+ -+ return RT_ERR_OK; -+} -+ -+static int32 _phy_rtl826xb_flow_r12(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode) -+{ -+ int32 ret = RT_ERR_OK; -+ rt_phy_patch_db_t *pPatchDb = NULL; -+ -+ PHYPATCH_DB_GET(unit, port, pPatchDb); -+ -+ //PHYReg_bit w $PHYID 0xb82 16 4 4 0x1 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xb82, 16, 4, 4, 0x1, patch_mode), ret); -+ //PHYReg_bit w $PHYID 0xb82 16 4 4 0x1 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xb82, 16, 4, 4, 0x1, patch_mode), ret); -+ -+ //set patch_rdy [PHYReg_bit r $PHYID 0xb80 16 6 6] ; Wait for patch ready = 1 -+ RT_ERR_CHK(_phy_rtl826xb_patch_wait(unit, port, 31, _phy_rtl826xb_mmd_convert(0xb80, 16), BIT_6, BIT_6, patch_mode), ret); -+ -+ //PHYReg w $PHYID 0xa43 27 $0x8023 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa43, 27, 15, 0, 0x8023, patch_mode), ret); -+ //PHYReg w $PHYID 0xa43 28 $0x3800 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa43, 28, 15, 0, 0x3800, patch_mode), ret); -+ //PHYReg w $PHYID 0xa43 27 0xB82E -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa43, 27, 15, 0, 0xB82E, patch_mode), ret); -+ //PHYReg w $PHYID 0xa43 28 0x1 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa43, 28, 15, 0, 0x1, patch_mode), ret); -+ -+ return RT_ERR_OK; -+} -+ -+ -+static int32 _phy_rtl826xb_flow_r2(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode) -+{ -+ int32 ret = RT_ERR_OK; -+ rt_phy_patch_db_t *pPatchDb = NULL; -+ -+ PHYPATCH_DB_GET(unit, port, pPatchDb); -+ -+ //PHYReg w $PHYID 0xa43 27 0x0000 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa43, 27, 15, 0, 0x0000, patch_mode), ret); -+ //PHYReg w $PHYID 0xa43 28 0x0000 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa43, 28, 15, 0, 0x0000, patch_mode), ret); -+ //PHYReg_bit w $PHYID 0xB82 23 0 0 0x0 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xB82, 23, 0, 0, 0x0, patch_mode), ret); -+ //PHYReg w $PHYID 0xa43 27 $0x8023 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa43, 27, 15, 0, 0x8023, patch_mode), ret); -+ //PHYReg w $PHYID 0xa43 28 0x0000 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa43, 28, 15, 0, 0x0000, patch_mode), ret); -+ -+ //PHYReg_bit w $PHYID 0xb82 16 4 4 0x0 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xb82, 16, 4, 4, 0x0, patch_mode), ret); -+ //set patch_rdy [PHYReg_bit r $PHYID 0xb80 16 6 6] ; Wait for patch ready != 1 -+ RT_ERR_CHK( _phy_rtl826xb_patch_wait_not_equal(unit, port, 31, _phy_rtl826xb_mmd_convert(0xb80, 16), BIT_6, BIT_6, patch_mode), ret); -+ -+ return RT_ERR_OK; -+} -+ -+static int32 _phy_rtl826xb_flow_l1(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode) -+{ -+ int32 ret = RT_ERR_OK; -+ rt_phy_patch_db_t *pPatchDb = NULL; -+ -+ PHYPATCH_DB_GET(unit, port, pPatchDb); -+ -+ //PHYReg_bit w $PHYID 0xa4a 16 10 10 0x1 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa4a, 16, 10, 10, 0x1, patch_mode), ret); -+ //PHYReg_bit w $PHYID 0xa4a 16 10 10 0x1 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa4a, 16, 10, 10, 0x1, patch_mode), ret); -+ -+ //set pcs_state [PHYReg_bit r $PHYID 0xa60 16 7 0] ; Wait for pcs state = 1 -+ RT_ERR_CHK( _phy_rtl826xb_patch_wait(unit, port, 31, _phy_rtl826xb_mmd_convert(0xa60, 16), 0x1, 0xFF, patch_mode), ret); -+ -+ return RT_ERR_OK; -+} -+ -+static int32 _phy_rtl826xb_flow_l2(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode) -+{ -+ int32 ret = RT_ERR_OK; -+ rt_phy_patch_db_t *pPatchDb = NULL; -+ -+ PHYPATCH_DB_GET(unit, port, pPatchDb); -+ -+ //PHYReg_bit w $PHYID 0xa4a 16 10 10 0x0 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa4a, 16, 10, 10, 0x0, patch_mode), ret); -+ -+ //set pcs_state [PHYReg_bit r $PHYID 0xa60 16 7 0] ; Wait for pcs state != 1 -+ RT_ERR_CHK( _phy_rtl826xb_patch_wait_not_equal(unit, port, 31, _phy_rtl826xb_mmd_convert(0xa60, 16), 0x1, 0xFF, patch_mode), ret); -+ -+ return RT_ERR_OK; -+} -+ -+static int32 _phy_rtl826xb_flow_pi(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode) -+{ -+ int32 ret = RT_ERR_OK; -+ rt_phy_patch_db_t *pPatchDb = NULL; -+ uint32 rData = 0, cnt = 0; -+ -+ PHYPATCH_DB_GET(unit, port, pPatchDb); -+ -+ _phy_rtl826xb_flow_l1(unit, port, portOffset, patch_mode); -+ -+ // PP_PHYReg_bit w $PHYID 0xbf86 9 9 0x1; #SS_EN_XG = 1 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbf86, 9, 9, 0x1, patch_mode), ret); -+ // PP_PHYReg_bit w $PHYID 0xbf86 8 8 0x0; -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbf86, 8, 8, 0x0, patch_mode), ret); -+ // PP_PHYReg_bit w $PHYID 0xbf86 7 7 0x1; -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbf86, 7, 7, 0x1, patch_mode), ret); -+ // PP_PHYReg_bit w $PHYID 0xbf86 6 6 0x1; -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbf86, 6, 6, 0x1, patch_mode), ret); -+ // PP_PHYReg_bit w $PHYID 0xbf86 5 5 0x1; -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbf86, 5, 5, 0x1, patch_mode), ret); -+ // PP_PHYReg_bit w $PHYID 0xbf86 4 4 0x1; -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbf86, 4, 4, 0x1, patch_mode), ret); -+ // PP_PHYReg_bit w $PHYID 0xbf86 6 6 0x0; -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbf86, 6, 6, 0x0, patch_mode), ret); -+ // PP_PHYReg_bit w $PHYID 0xbf86 9 9 0x0; -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbf86, 9, 9, 0x0, patch_mode), ret); -+ // PP_PHYReg_bit w $PHYID 0xbf86 7 7 0x0; -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbf86, 7, 7, 0x0, patch_mode), ret); -+ -+ //PP_PHYReg_bit r $PHYID 0xbc62 12 8 -+ if ((ret = phy_common_general_reg_mmd_get(unit, port, PHY_MMD_VEND2, 0xbc62, &rData)) != RT_ERR_OK) -+ return ret; -+ rData = REG32_FIELD_GET(rData, 8, 0x1F00); -+ for (cnt = 0; cnt <= rData; cnt++) -+ { -+ //PP_PHYReg_bit w $PHYID 0xbc62 12 8 $t -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbc62, 12, 8, cnt, patch_mode), ret); -+ } -+ -+ // PP_PHYReg_bit w $PHYID 0xbc02 2 2 0x1 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbc02, 2, 2, 0x1, patch_mode), ret); -+ // PP_PHYReg_bit w $PHYID 0xbc02 3 3 0x1 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbc02, 3, 3, 0x1, patch_mode), ret); -+ // PP_PHYReg_bit w $PHYID 0xbf86 6 6 0x1 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbf86, 6, 6, 0x1, patch_mode), ret); -+ // PP_PHYReg_bit w $PHYID 0xbf86 9 9 0x1 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbf86, 9, 9, 0x1, patch_mode), ret); -+ // PP_PHYReg_bit w $PHYID 0xbf86 7 7 0x1 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbf86, 7, 7, 0x1, patch_mode), ret); -+ // PP_PHYReg_bit w $PHYID 0xbc04 9 2 0xff -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHYOCP, 0xFF, 31, 0xbc04, 9, 2, 0xff, patch_mode), ret); -+ -+ _phy_rtl826xb_flow_l2(unit, port, portOffset, patch_mode); -+ return RT_ERR_OK; -+} -+ -+static int32 _phy_rtl826xb_flow_n01(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode) -+{ -+ int32 ret = RT_ERR_OK; -+ rt_phy_patch_db_t *pPatchDb = NULL; -+ -+ PHYPATCH_DB_GET(unit, port, pPatchDb); -+ -+ //PHYReg_bit w $PHYID 0xa01 21 15 0 0x1 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 21, 15, 0, 0x1, patch_mode), ret); -+ //PHYReg_bit w $PHYID 0xa01 19 15 0 0x0000 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 19, 15, 0, 0x0000, patch_mode), ret); -+ //# PHYReg_bit w $PHYID 0xa01 17 15 0 0x0000 -+ //RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 17, 15, 0, 0x0000, patch_mode), ret); -+ -+ return RT_ERR_OK; -+} -+ -+static int32 _phy_rtl826xb_flow_n02(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode) -+{ -+ int32 ret = RT_ERR_OK; -+ rt_phy_patch_db_t *pPatchDb = NULL; -+ -+ PHYPATCH_DB_GET(unit, port, pPatchDb); -+ -+ //PHYReg_bit w $PHYID 0xa01 21 15 0 0x0 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 21, 15, 0, 0x0, patch_mode), ret); -+ //PHYReg_bit w $PHYID 0xa01 19 15 0 0x0000 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 19, 15, 0, 0x0000, patch_mode), ret); -+ //PHYReg_bit w $PHYID 0xa01 17 15 0 0x0000 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 17, 15, 0, 0x0000, patch_mode), ret); -+ return RT_ERR_OK; -+} -+ -+static int32 _phy_rtl826xb_flow_n11(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode) -+{ -+ int32 ret = RT_ERR_OK; -+ rt_phy_patch_db_t *pPatchDb = NULL; -+ -+ PHYPATCH_DB_GET(unit, port, pPatchDb); -+ -+ //PHYReg_bit w $PHYID 0xa01 21 15 0 0x1 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 21, 15, 0, 0x1, patch_mode), ret); -+ //PHYReg_bit w $PHYID 0xa01 19 15 0 0x0010 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 19, 15, 0, 0x0010, patch_mode), ret); -+ //# PHYReg_bit w $PHYID 0xa01 17 15 0 0x0000 -+ //RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 17, 15, 0, 0x0000, patch_mode), ret); -+ -+ return RT_ERR_OK; -+} -+ -+static int32 _phy_rtl826xb_flow_n12(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode) -+{ -+ int32 ret = RT_ERR_OK; -+ rt_phy_patch_db_t *pPatchDb = NULL; -+ -+ PHYPATCH_DB_GET(unit, port, pPatchDb); -+ -+ //PHYReg_bit w $PHYID 0xa01 21 15 0 0x0 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 21, 15, 0, 0x0, patch_mode), ret); -+ //PHYReg_bit w $PHYID 0xa01 19 15 0 0x0010 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 19, 15, 0, 0x0010, patch_mode), ret); -+ //PHYReg_bit w $PHYID 0xa01 17 15 0 0x0000 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 17, 15, 0, 0x0000, patch_mode), ret); -+ -+ return RT_ERR_OK; -+} -+ -+static int32 _phy_rtl826xb_flow_n21(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode) -+{ -+ int32 ret = RT_ERR_OK; -+ rt_phy_patch_db_t *pPatchDb = NULL; -+ -+ PHYPATCH_DB_GET(unit, port, pPatchDb); -+ -+ //PHYReg_bit w $PHYID 0xa01 21 15 0 0x1 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 21, 15, 0, 0x1, patch_mode), ret); -+ //PHYReg_bit w $PHYID 0xa01 19 15 0 0x0020 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 19, 15, 0, 0x0020, patch_mode), ret); -+ //# PHYReg_bit w $PHYID 0xa01 17 15 0 0x0000 -+ //RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 17, 15, 0, 0x0000, patch_mode), ret); -+ -+ return RT_ERR_OK; -+} -+ -+static int32 _phy_rtl826xb_flow_n22(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode) -+{ -+ int32 ret = RT_ERR_OK; -+ rt_phy_patch_db_t *pPatchDb = NULL; -+ -+ PHYPATCH_DB_GET(unit, port, pPatchDb); -+ -+ //PHYReg_bit w $PHYID 0xa01 21 15 0 0x0 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 21, 15, 0, 0x0, patch_mode), ret); -+ //PHYReg_bit w $PHYID 0xa01 19 15 0 0x0020 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 19, 15, 0, 0x0020, patch_mode), ret); -+ //PHYReg_bit w $PHYID 0xa01 17 15 0 0x0000 -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PHY, 0xFF, 0xa01, 17, 15, 0, 0x0000, patch_mode), ret); -+ -+ return RT_ERR_OK; -+} -+ -+static int32 _phy_rtl826xb_flow_s(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_mode) -+{ -+ int32 ret = RT_ERR_OK; -+ rt_phy_patch_db_t *pPatchDb = NULL; -+ -+ if (PHYPATCH_IS_RTKSDS(unit)) -+ { -+ PHYPATCH_DB_GET(unit, port, pPatchDb); -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PSDS0, 0xff, 0x07, 0x10, 15, 0, 0x80aa, patch_mode), ret); -+ RT_ERR_CHK(phy_patch_op(pPatchDb, unit, port, portOffset, RTK_PATCH_OP_PSDS0, 0xff, 0x06, 0x12, 15, 0, 0x5078, patch_mode), ret); -+ } -+ -+ return RT_ERR_OK; -+} -+ -+static int32 phy_rtl826xb_patch_op(uint32 unit, rtk_port_t port, uint8 portOffset, rtk_hwpatch_t *pPatch_data, uint8 patch_mode) -+{ -+ int32 ret = RT_ERR_OK; -+ uint32 rData = 0, wData = 0; -+ uint16 reg = 0; -+ uint8 patch_op = 0; -+ uint32 mask = 0; -+ -+ if ((pPatch_data->portmask & (1 << portOffset)) == 0) -+ { -+ return RT_ERR_ABORT; -+ } -+ mask = UINT32_BITS_MASK(pPatch_data->msb, pPatch_data->lsb); -+ patch_op = phy_patch_op_translate(patch_mode, pPatch_data->patch_op, pPatch_data->compare_op); -+ -+ #if 0 -+ osal_printf("[%s,%d]u%up%u, patch_mode:%u/patch_op:%u/compare_op:%u => op: %u\n", __FUNCTION__, __LINE__, unit, port, -+ patch_mode, pPatch_data->patch_op, pPatch_data->compare_op, -+ patch_op); -+ #endif -+ -+ switch (patch_op) -+ { -+ case RTK_PATCH_OP_PHY: -+ reg = _phy_rtl826xb_mmd_convert(pPatch_data->pagemmd, pPatch_data->addr); -+ if ((pPatch_data->msb != 15) || (pPatch_data->lsb != 0)) -+ { -+ RT_ERR_CHK(phy_common_general_reg_mmd_get(unit, port, 31, reg, &rData), ret); -+ } -+ wData = REG32_FIELD_SET(rData, pPatch_data->data, pPatch_data->lsb, mask); -+ RT_ERR_CHK(phy_common_general_reg_mmd_set(unit, port, 31, reg, wData), ret); -+ break; -+ case RTK_PATCH_OP_CMP_PHY: -+ reg = _phy_rtl826xb_mmd_convert(pPatch_data->pagemmd, pPatch_data->addr); -+ RT_ERR_CHK(phy_common_general_reg_mmd_get(unit, port, 31, reg, &rData), ret); -+ PHYPATCH_COMPARE(pPatch_data->pagemmd, pPatch_data->addr, pPatch_data->msb, pPatch_data->lsb, pPatch_data->data, rData, mask); -+ break; -+ case RTK_PATCH_OP_CMP_SRAM_PHY: -+ reg = _phy_rtl826xb_mmd_convert(pPatch_data->sram_p, pPatch_data->sram_rw); -+ RT_ERR_CHK(phy_common_general_reg_mmd_set(unit, port, 31, reg, pPatch_data->sram_a), ret); -+ reg = _phy_rtl826xb_mmd_convert(pPatch_data->sram_p, pPatch_data->sram_rr); -+ RT_ERR_CHK(phy_common_general_reg_mmd_get(unit, port, 31, reg, &rData), ret); -+ PHYPATCH_COMPARE(pPatch_data->pagemmd, pPatch_data->addr, pPatch_data->msb, pPatch_data->lsb, pPatch_data->data, rData, mask); -+ break; -+ -+ case RTK_PATCH_OP_PHYOCP: -+ if ((pPatch_data->msb != 15) || (pPatch_data->lsb != 0)) -+ { -+ RT_ERR_CHK(phy_common_general_reg_mmd_get(unit, port, 31, pPatch_data->addr, &rData), ret); -+ } -+ wData = REG32_FIELD_SET(rData, pPatch_data->data, pPatch_data->lsb, mask); -+ RT_ERR_CHK(phy_common_general_reg_mmd_set(unit, port, 31, pPatch_data->addr, wData), ret); -+ break; -+ case RTK_PATCH_OP_CMP_PHYOCP: -+ RT_ERR_CHK(phy_common_general_reg_mmd_get(unit, port, 31, pPatch_data->addr, &rData), ret); -+ PHYPATCH_COMPARE(pPatch_data->pagemmd, pPatch_data->addr, pPatch_data->msb, pPatch_data->lsb, pPatch_data->data, rData, mask); -+ break; -+ case RTK_PATCH_OP_CMP_SRAM_PHYOCP: -+ RT_ERR_CHK(phy_common_general_reg_mmd_set(unit, port, 31, pPatch_data->sram_rw, pPatch_data->sram_a), ret); -+ RT_ERR_CHK(phy_common_general_reg_mmd_get(unit, port, 31, pPatch_data->sram_rr, &rData), ret); -+ PHYPATCH_COMPARE(pPatch_data->pagemmd, pPatch_data->addr, pPatch_data->msb, pPatch_data->lsb, pPatch_data->data, rData, mask); -+ break; -+ -+ case RTK_PATCH_OP_TOP: -+ if ((pPatch_data->msb != 15) || (pPatch_data->lsb != 0)) -+ { -+ RT_ERR_CHK(_phy_rtl826xb_patch_top_get(unit, port, pPatch_data->pagemmd, pPatch_data->addr, &rData), ret); -+ } -+ wData = REG32_FIELD_SET(rData, pPatch_data->data, pPatch_data->lsb, mask); -+ RT_ERR_CHK(_phy_rtl826xb_patch_top_set(unit, port, pPatch_data->pagemmd, pPatch_data->addr, wData), ret); -+ break; -+ case RTK_PATCH_OP_CMP_TOP: -+ RT_ERR_CHK(_phy_rtl826xb_patch_top_get(unit, port, pPatch_data->pagemmd, pPatch_data->addr, &rData), ret); -+ PHYPATCH_COMPARE(pPatch_data->pagemmd, pPatch_data->addr, pPatch_data->msb, pPatch_data->lsb, pPatch_data->data, rData, mask); -+ break; -+ case RTK_PATCH_OP_CMP_SRAM_TOP: -+ RT_ERR_CHK(_phy_rtl826xb_patch_top_set(unit, port, pPatch_data->sram_p, pPatch_data->sram_rw, pPatch_data->sram_a), ret); -+ RT_ERR_CHK(_phy_rtl826xb_patch_top_get(unit, port, pPatch_data->sram_p, pPatch_data->sram_rr, &rData), ret); -+ PHYPATCH_COMPARE(pPatch_data->pagemmd, pPatch_data->addr, pPatch_data->msb, pPatch_data->lsb, pPatch_data->data, rData, mask); -+ break; -+ -+ case RTK_PATCH_OP_PSDS0: -+ if ((pPatch_data->msb != 15) || (pPatch_data->lsb != 0)) -+ { -+ RT_ERR_CHK(_phy_rtl826xb_patch_sds_get(unit, port, pPatch_data->pagemmd, pPatch_data->addr, &rData), ret); -+ } -+ wData = REG32_FIELD_SET(rData, pPatch_data->data, pPatch_data->lsb, mask); -+ RT_ERR_CHK(_phy_rtl826xb_patch_sds_set(unit, port, pPatch_data->pagemmd, pPatch_data->addr, wData, patch_mode), ret); -+ break; -+ case RTK_PATCH_OP_CMP_PSDS0: -+ RT_ERR_CHK(_phy_rtl826xb_patch_sds_get(unit, port, pPatch_data->pagemmd, pPatch_data->addr, &rData), ret); -+ PHYPATCH_COMPARE(pPatch_data->pagemmd, pPatch_data->addr, pPatch_data->msb, pPatch_data->lsb, pPatch_data->data, rData, mask); -+ break; -+ case RTK_PATCH_OP_CMP_SRAM_PSDS0: -+ RT_ERR_CHK(_phy_rtl826xb_patch_sds_set(unit, port, pPatch_data->sram_p, pPatch_data->sram_rw, pPatch_data->sram_a, patch_mode), ret); -+ RT_ERR_CHK(_phy_rtl826xb_patch_sds_get(unit, port, pPatch_data->sram_p, pPatch_data->sram_rr, &rData), ret); -+ PHYPATCH_COMPARE(pPatch_data->pagemmd, pPatch_data->addr, pPatch_data->msb, pPatch_data->lsb, pPatch_data->data, rData, mask); -+ break; -+ -+ case RTK_PATCH_OP_SKIP: -+ return RT_ERR_ABORT; -+ -+ default: -+ RT_LOG(LOG_MAJOR_ERR, (MOD_HAL | MOD_PHY), "U%u P%u patch_op:%u not implemented yet!\n", unit, port, pPatch_data->patch_op); -+ return RT_ERR_DRIVER_NOT_SUPPORTED; -+ } -+ -+ return ret; -+} -+ -+static int32 phy_rtl826xb_patch_flow(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_flow, uint8 patch_mode) -+{ -+ int32 ret = RT_ERR_OK; -+ -+ RT_LOG(LOG_INFO, (MOD_HAL | MOD_PHY), "[%s]U%u,P%u,flow%u\n", __FUNCTION__, unit, port, (patch_flow - PHY_PATCH_TYPE_END)); -+ switch (patch_flow) -+ { -+ case RTK_PATCH_TYPE_FLOW(0): -+ RT_ERR_CHK(_phy_rtl826xb_flow_r1(unit, port, portOffset, patch_mode), ret); -+ break; -+ case RTK_PATCH_TYPE_FLOW(1): -+ RT_ERR_CHK(_phy_rtl826xb_flow_r2(unit, port, portOffset, patch_mode), ret); -+ break; -+ -+ case RTK_PATCH_TYPE_FLOW(2): -+ RT_ERR_CHK(_phy_rtl826xb_flow_l1(unit, port, portOffset, patch_mode), ret); -+ break; -+ case RTK_PATCH_TYPE_FLOW(3): -+ RT_ERR_CHK(_phy_rtl826xb_flow_l2(unit, port, portOffset, patch_mode), ret); -+ break; -+ -+ case RTK_PATCH_TYPE_FLOW(4): -+ RT_ERR_CHK(_phy_rtl826xb_flow_n01(unit, port, portOffset, patch_mode), ret); -+ break; -+ case RTK_PATCH_TYPE_FLOW(5): -+ RT_ERR_CHK(_phy_rtl826xb_flow_n02(unit, port, portOffset, patch_mode), ret); -+ break; -+ -+ case RTK_PATCH_TYPE_FLOW(6): -+ RT_ERR_CHK(_phy_rtl826xb_flow_n11(unit, port, portOffset, patch_mode), ret); -+ break; -+ case RTK_PATCH_TYPE_FLOW(7): -+ RT_ERR_CHK(_phy_rtl826xb_flow_n12(unit, port, portOffset, patch_mode), ret); -+ break; -+ -+ case RTK_PATCH_TYPE_FLOW(8): -+ RT_ERR_CHK(_phy_rtl826xb_flow_n21(unit, port, portOffset, patch_mode), ret); -+ break; -+ case RTK_PATCH_TYPE_FLOW(9): -+ RT_ERR_CHK(_phy_rtl826xb_flow_n22(unit, port, portOffset, patch_mode), ret); -+ break; -+ -+ case RTK_PATCH_TYPE_FLOW(10): -+ RT_ERR_CHK(_phy_rtl826xb_flow_s(unit, port, portOffset, patch_mode), ret); -+ break; -+ -+ case RTK_PATCH_TYPE_FLOW(11): -+ RT_ERR_CHK(_phy_rtl826xb_flow_pi(unit, port, portOffset, patch_mode), ret); -+ break; -+ case RTK_PATCH_TYPE_FLOW(12): -+ RT_ERR_CHK(_phy_rtl826xb_flow_r12(unit, port, portOffset, patch_mode), ret); -+ break; -+ -+ default: -+ return RT_ERR_INPUT; -+ } -+ return RT_ERR_OK; -+} -+ -+int32 phy_rtl826xb_patch_db_init(uint32 unit, rtk_port_t port, rt_phy_patch_db_t **pPhy_patchDb) -+{ -+ int32 ret = RT_ERR_OK; -+ rt_phy_patch_db_t *patch_db = NULL; -+ uint32 rData = 0; -+ -+ patch_db = osal_alloc(sizeof(rt_phy_patch_db_t)); -+ RT_PARAM_CHK(NULL == patch_db, RT_ERR_MEM_ALLOC); -+ osal_memset(patch_db, 0x0, sizeof(rt_phy_patch_db_t)); -+ -+ /* patch callback */ -+ patch_db->fPatch_op = phy_rtl826xb_patch_op; -+ patch_db->fPatch_flow = phy_rtl826xb_patch_flow; -+ -+ /* patch table */ -+ RT_ERR_CHK(phy_common_general_reg_mmd_get(unit, port, 30, 0x104, &rData), ret); -+ if ((rData & 0x7) == 0x0) -+ { -+ /* patch */ -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 0, RTK_PATCH_TYPE_FLOW(12), NULL); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 1, PHY_PATCH_TYPE_NCTL0, rtl8264b_nctl0_conf); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 2, PHY_PATCH_TYPE_NCTL1, rtl8264b_nctl1_conf); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 3, PHY_PATCH_TYPE_NCTL2, rtl8264b_nctl2_conf); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 4, PHY_PATCH_TYPE_UC2, rtl8264b_uc2_conf); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 5, PHY_PATCH_TYPE_UC, rtl8264b_uc_conf); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 6, PHY_PATCH_TYPE_DATARAM, rtl8264b_dataram_conf); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 7, RTK_PATCH_TYPE_FLOW(1), NULL); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 8, RTK_PATCH_TYPE_FLOW(2), NULL); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 9, PHY_PATCH_TYPE_ALGXG, rtl8264b_algxg_conf); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 10, PHY_PATCH_TYPE_ALG1G, rtl8264b_alg_giga_conf); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 11, PHY_PATCH_TYPE_NORMAL, rtl8264b_normal_conf); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 12, PHY_PATCH_TYPE_TOP, rtl8264b_top_conf); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 13, PHY_PATCH_TYPE_SDS, rtl8264b_sds_conf); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 14, PHY_PATCH_TYPE_AFE, rtl8264b_afe_conf); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 15, PHY_PATCH_TYPE_RTCT, rtl8264b_rtct_conf); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 16, RTK_PATCH_TYPE_FLOW(3), NULL); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 17, RTK_PATCH_TYPE_FLOW(11), NULL); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 18, RTK_PATCH_TYPE_FLOW(10), NULL); -+ -+ /* compare */ -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 0, PHY_PATCH_TYPE_TOP, rtl8264b_top_conf); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 1, PHY_PATCH_TYPE_SDS, rtl8264b_sds_conf); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 2, PHY_PATCH_TYPE_AFE, rtl8264b_afe_conf); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 3, RTK_PATCH_TYPE_FLOW(4), NULL); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 4, PHY_PATCH_TYPE_NCTL0, rtl8264b_nctl0_conf); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 5, RTK_PATCH_TYPE_FLOW(5), NULL); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 6, RTK_PATCH_TYPE_FLOW(6), NULL); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 7, PHY_PATCH_TYPE_NCTL1, rtl8264b_nctl1_conf); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 8, RTK_PATCH_TYPE_FLOW(7), NULL); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 9, RTK_PATCH_TYPE_FLOW(8), NULL); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 10, PHY_PATCH_TYPE_NCTL2, rtl8264b_nctl2_conf); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 11, RTK_PATCH_TYPE_FLOW(9), NULL); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 12, PHY_PATCH_TYPE_UC, rtl8264b_uc_conf); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 13, PHY_PATCH_TYPE_UC2, rtl8264b_uc2_conf); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 14, RTK_PATCH_TYPE_FLOW(12), NULL); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 15, PHY_PATCH_TYPE_DATARAM, rtl8264b_dataram_conf); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 16, RTK_PATCH_TYPE_FLOW(1), NULL); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 17, PHY_PATCH_TYPE_ALGXG, rtl8264b_algxg_conf); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 18, PHY_PATCH_TYPE_ALG1G, rtl8264b_alg_giga_conf); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 19, PHY_PATCH_TYPE_NORMAL, rtl8264b_normal_conf); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 20, PHY_PATCH_TYPE_RTCT, rtl8264b_rtct_conf); -+ } -+ else -+ { -+ /* patch */ -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 0, RTK_PATCH_TYPE_FLOW(0), NULL); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 1, PHY_PATCH_TYPE_NCTL0, rtl8261n_c_nctl0_conf); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 2, PHY_PATCH_TYPE_NCTL1, rtl8261n_c_nctl1_conf); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 3, PHY_PATCH_TYPE_NCTL2, rtl8261n_c_nctl2_conf); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 4, PHY_PATCH_TYPE_UC2, rtl8261n_c_uc2_conf); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 5, PHY_PATCH_TYPE_UC, rtl8261n_c_uc_conf); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 6, PHY_PATCH_TYPE_DATARAM, rtl8261n_c_dataram_conf); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 7, RTK_PATCH_TYPE_FLOW(1), NULL); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 8, RTK_PATCH_TYPE_FLOW(2), NULL); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 9, PHY_PATCH_TYPE_ALGXG, rtl8261n_c_algxg_conf); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 10, PHY_PATCH_TYPE_ALG1G, rtl8261n_c_alg_giga_conf); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 11, PHY_PATCH_TYPE_NORMAL, rtl8261n_c_normal_conf); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 12, PHY_PATCH_TYPE_TOP, rtl8261n_c_top_conf); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 13, PHY_PATCH_TYPE_SDS, rtl8261n_c_sds_conf); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 14, PHY_PATCH_TYPE_AFE, rtl8261n_c_afe_conf); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 15, PHY_PATCH_TYPE_RTCT, rtl8261n_c_rtct_conf); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 16, RTK_PATCH_TYPE_FLOW(3), NULL); -+ PHYPATCH_SEQ_TABLE_ASSIGN(patch_db, 17, RTK_PATCH_TYPE_FLOW(10), NULL); -+ -+ /* compare */ -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 0, PHY_PATCH_TYPE_TOP, rtl8261n_c_top_conf); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 1, PHY_PATCH_TYPE_SDS, rtl8261n_c_sds_conf); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 2, PHY_PATCH_TYPE_AFE, rtl8261n_c_afe_conf); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 3, RTK_PATCH_TYPE_FLOW(4), NULL); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 4, PHY_PATCH_TYPE_NCTL0, rtl8261n_c_nctl0_conf); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 5, RTK_PATCH_TYPE_FLOW(5), NULL); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 6, RTK_PATCH_TYPE_FLOW(6), NULL); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 7, PHY_PATCH_TYPE_NCTL1, rtl8261n_c_nctl1_conf); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 8, RTK_PATCH_TYPE_FLOW(7), NULL); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 9, RTK_PATCH_TYPE_FLOW(8), NULL); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 10, PHY_PATCH_TYPE_NCTL2, rtl8261n_c_nctl2_conf); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 11, RTK_PATCH_TYPE_FLOW(9), NULL); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 12, PHY_PATCH_TYPE_UC, rtl8261n_c_uc_conf); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 13, PHY_PATCH_TYPE_UC2, rtl8261n_c_uc2_conf); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 14, RTK_PATCH_TYPE_FLOW(0), NULL); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 15, PHY_PATCH_TYPE_DATARAM, rtl8261n_c_dataram_conf); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 16, RTK_PATCH_TYPE_FLOW(1), NULL); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 17, PHY_PATCH_TYPE_ALGXG, rtl8261n_c_algxg_conf); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 18, PHY_PATCH_TYPE_ALG1G, rtl8261n_c_alg_giga_conf); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 19, PHY_PATCH_TYPE_NORMAL, rtl8261n_c_normal_conf); -+ PHYPATCH_CMP_TABLE_ASSIGN(patch_db, 20, PHY_PATCH_TYPE_RTCT, rtl8261n_c_rtct_conf); -+ } -+ *pPhy_patchDb = patch_db; -+ return ret; -+} -+ -+/* Function Name: -+ * phy_rtl826xb_patch -+ * Description: -+ * apply initial patch data to PHY -+ * Input: -+ * unit - unit id -+ * baseport - base port id on the PHY chip -+ * portOffset - the index offset base on baseport for the port to patch -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NOT_SUPPORTED -+ * RT_ERR_ABORT -+ * Note: -+ * None -+ */ -+int32 phy_rtl826xb_patch(uint32 unit, rtk_port_t port, uint8 portOffset) -+{ -+ return phy_patch( unit, port, portOffset, PHY_PATCH_MODE_NORMAL); -+} -+ -+/* Function Name: -+ * phy_rtl826xb_broadcast_patch -+ * Description: -+ * apply patch data to PHY -+ * Input: -+ * unit - unit id -+ * baseport - base port id on the PHY chip -+ * portOffset - the index offset base on baseport for the port to patch -+ * perChip - 1 for per-chip mode, 0 for per-bus mode -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NOT_SUPPORTED -+ * RT_ERR_ABORT -+ * Note: -+ * None -+ */ -+int32 phy_rtl826xb_broadcast_patch(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 perChip) -+{ -+ int32 ret = 0; -+ if (perChip == 0) -+ { -+ ret = phy_patch(unit, port, portOffset, PHY_PATCH_MODE_BCAST_BUS); -+ } -+ else -+ { -+ ret = phy_patch(unit, port, portOffset, PHY_PATCH_MODE_BCAST); -+ } -+ return ret; -+} -+ -diff --git a/drivers/net/phy/rtl8261n/phy_rtl826xb_patch.h b/drivers/net/phy/rtl8261n/phy_rtl826xb_patch.h -new file mode 100644 -index 000000000000..c2311ef2bf46 ---- /dev/null -+++ b/drivers/net/phy/rtl8261n/phy_rtl826xb_patch.h -@@ -0,0 +1,63 @@ -+/* -+ * SPDX-License-Identifier: GPL-2.0-only -+ * -+ * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. -+ */ -+ -+#ifndef __HAL_PHY_PHY_RTL826XB_PATCH_H__ -+#define __HAL_PHY_PHY_RTL826XB_PATCH_H__ -+ -+/* -+ * Include Files -+ */ -+#if defined(RTK_PHYDRV_IN_LINUX) -+ #include "rtk_osal.h" -+ #include "rtk_phylib_def.h" -+#else -+ #include -+ #include -+#endif -+ -+/* Function Name: -+ * phy_rtl826xb_patch -+ * Description: -+ * apply patch data to PHY -+ * Input: -+ * unit - unit id -+ * baseport - base port id on the PHY chip -+ * portOffset - the index offset base on baseport for the port to patch -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NOT_SUPPORTED -+ * RT_ERR_ABORT -+ * Note: -+ * None -+ */ -+extern int32 phy_rtl826xb_patch(uint32 unit, rtk_port_t baseport, uint8 portOffset); -+ -+/* Function Name: -+ * phy_rtl826xb_broadcast_patch -+ * Description: -+ * apply patch data to PHY -+ * Input: -+ * unit - unit id -+ * baseport - base port id on the PHY chip -+ * portOffset - the index offset base on baseport for the port to patch -+ * perChip - 1 for per-chip mode, 0 for per-bus mode -+ * Output: -+ * None -+ * Return: -+ * RT_ERR_OK -+ * RT_ERR_FAILED -+ * RT_ERR_NOT_SUPPORTED -+ * RT_ERR_ABORT -+ * Note: -+ * None -+ */ -+extern int32 phy_rtl826xb_broadcast_patch(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 perChip); -+ -+extern int32 phy_rtl826xb_patch_db_init(uint32 unit, rtk_port_t port, rt_phy_patch_db_t **pPhy_patchDb); -+#endif /* __HAL_PHY_PHY_RTL826XB_PATCH_H__ */ -diff --git a/drivers/net/phy/rtl8261n/rtk_osal.c b/drivers/net/phy/rtl8261n/rtk_osal.c -new file mode 100644 -index 000000000000..35339400d01b ---- /dev/null -+++ b/drivers/net/phy/rtl8261n/rtk_osal.c -@@ -0,0 +1,57 @@ -+/* -+ * SPDX-License-Identifier: GPL-2.0-only -+ * -+ * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. -+ */ -+ -+#include "type.h" -+#include "error.h" -+#include "rtk_phylib_def.h" -+#include "rtk_osal.h" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+int32 -+osal_time_usecs_get(osal_usecs_t *pUsec) -+{ -+ struct timespec64 ts; -+ -+ RT_PARAM_CHK((NULL == pUsec), RT_ERR_NULL_POINTER); -+ -+ ktime_get_ts64(&ts); -+ *pUsec = (osal_usecs_t)((ts.tv_sec * USEC_PER_SEC) + (ts.tv_nsec / NSEC_PER_USEC)); -+ return RT_ERR_OK; -+} -+ -+void * -+osal_alloc(uint32 size) -+{ -+ void *p; -+ p = kmalloc((size_t)size, GFP_ATOMIC); -+ return p; -+} -+ -+int32 -+phy_common_general_reg_mmd_get(uint32 unit, rtk_port_t port, uint32 mmdAddr, uint32 mmdReg, uint32 *pData) -+{ -+ int32 rData = 0; -+ rData = phy_read_mmd(port, mmdAddr, mmdReg); -+ if (rData < 0) -+ return RT_ERR_FAILED; -+ *pData = (uint32)rData; -+ return RT_ERR_OK; -+} -+ -+int32 -+phy_common_general_reg_mmd_set(uint32 unit, rtk_port_t port, uint32 mmdAddr, uint32 mmdReg, uint32 data) -+{ -+ int ret = phy_write_mmd(port, mmdAddr, mmdReg, data); -+ return (ret < 0) ? RT_ERR_FAILED : RT_ERR_OK; -+} -diff --git a/drivers/net/phy/rtl8261n/rtk_osal.h b/drivers/net/phy/rtl8261n/rtk_osal.h -new file mode 100644 -index 000000000000..edf674611efd ---- /dev/null -+++ b/drivers/net/phy/rtl8261n/rtk_osal.h -@@ -0,0 +1,99 @@ -+/* -+ * SPDX-License-Identifier: GPL-2.0-only -+ * -+ * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. -+ */ -+ -+#ifndef __RTK_PHY_OSAL_H -+#define __RTK_PHY_OSAL_H -+ -+#include -+#include -+#include "type.h" -+#include "error.h" -+#include "phy_patch.h" -+#include "rtk_phylib.h" -+ -+#ifdef PHYPATCH_DB_GET -+ #undef PHYPATCH_DB_GET -+#endif -+ -+#define PHYPATCH_DB_GET(_unit, _pPhy_device, _pPatchDb) \ -+ do { \ -+ struct rtk_phy_priv *_pPriv = (_pPhy_device)->priv; \ -+ rt_phy_patch_db_t *_pDb = _pPriv->patch; _pPatchDb = _pDb; \ -+ /*printk("[PHYPATCH_DB_GET] ? [%s]\n", (_pDb != NULL) ? "E":"N");*/ \ -+ } while(0) -+ -+#define HWP_9300_FAMILY_ID(_unit) 0 -+#define HWP_9310_FAMILY_ID(_unit) 0 -+#define RTK_9300_FAMILY_ID(_unit) 0 -+#define RTK_9310_FAMILY_ID(_unit) 0 -+#define RTK_9311B_FAMILY_ID(_unit) 0 -+#define RTK_9330_FAMILY_ID(_unit) 0 -+ -+#ifndef WAIT_COMPLETE_VAR -+#define WAIT_COMPLETE_VAR() \ -+ osal_usecs_t _t, _now, _t_wait=0, _timeout; \ -+ int32 _chkCnt=0; -+ -+#define WAIT_COMPLETE(_timeout_us) \ -+ _timeout = _timeout_us; \ -+ for(osal_time_usecs_get(&_t),osal_time_usecs_get(&_now),_t_wait=0,_chkCnt=0 ; \ -+ (_t_wait <= _timeout); \ -+ osal_time_usecs_get(&_now), _chkCnt++, _t_wait += ((_now >= _t) ? (_now - _t) : (0xFFFFFFFF - _t + _now)),_t = _now \ -+ ) -+ -+#define WAIT_COMPLETE_IS_TIMEOUT() (_t_wait > _timeout) -+#endif -+ -+/* OSAL */ -+#include -+int32 osal_time_usecs_get(osal_usecs_t *pUsec); -+void *osal_alloc(uint32 size); -+#define osal_time_mdelay mdelay -+ -+#include /* for Kernel Space */ -+#include -+#include -+#define osal_strlen strlen -+#define osal_strcmp strcmp -+#define osal_strcpy strcpy -+#define osal_strncpy strncpy -+#define osal_strcat strcat -+#define osal_strchr strchr -+#define osal_memset memset -+#define osal_memcpy memcpy -+#define osal_memcmp memcmp -+#define osal_strdup strdup -+#define osal_strncmp strncmp -+#define osal_strstr strstr -+#define osal_strtok strtok -+#define osal_strtok_r strtok_r -+#define osal_toupper toupper -+ -+#define osal_printf printk -+ -+/* HWP */ -+#define HWP_PORT_SMI(unit, port) 0 -+#define HWP_PHY_MODEL_BY_PORT(unit, port) 0 -+#define HWP_PHY_ADDR(unit, port) 0 -+#define HWP_PHY_BASE_MACID(unit, p) 0 -+#define HWP_PORT_TRAVS_EXCEPT_CPU(unit, p) if (bcast_phyad < 0x1F && p != NULL) -+ -+ -+/* RT_LOG */ -+//#define RT_LOG(level, module, fmt, args...) do { printk("RT_LOG:"fmt, ## args); } while(0) -+#define RT_LOG(level, module, fmt, args...) do {} while(0) -+#define RT_ERR(error_code, module, fmt, args...) do {} while(0) -+#define RT_INIT_ERR(error_code, module, fmt, args...) do {} while(0) -+#define RT_INIT_MSG(fmt, args...) do {} while(0) -+ -+#define phy_826xb_ctrl_set(unit, p, RTK_PHY_CTRL_MIIM_BCAST_PHYAD, bcast_phyad) 0 -+ -+/* reg access */ -+int32 phy_common_general_reg_mmd_get(uint32 unit, rtk_port_t port, uint32 mmdAddr, uint32 mmdReg, uint32 *pData); -+int32 phy_common_general_reg_mmd_set(uint32 unit, rtk_port_t port, uint32 mmdAddr, uint32 mmdReg, uint32 data); -+ -+ -+#endif /* __RTK_PHY_OSAL_H */ -diff --git a/drivers/net/phy/rtl8261n/rtk_phy.c b/drivers/net/phy/rtl8261n/rtk_phy.c -new file mode 100644 -index 000000000000..a1eb2c16149c ---- /dev/null -+++ b/drivers/net/phy/rtl8261n/rtk_phy.c -@@ -0,0 +1,324 @@ -+/* -+ * SPDX-License-Identifier: GPL-2.0-only -+ * -+ * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+ -+#include "phy_rtl826xb_patch.h" -+#include "rtk_phylib_rtl826xb.h" -+#include "rtk_phylib.h" -+ -+#define REALTEK_PHY_ID_RTL8261N 0x001CCAF3 -+#define REALTEK_PHY_ID_RTL8264B 0x001CC813 -+#define REALTEK_PHY_ID_RTL8264 0x001CCAF2 -+ -+#define REALTEK_SERDES_GLOBAL_CFG 0xC1 -+#define REALTEK_HSO_INV BIT(7) -+#define REALTEK_HSI_INV BIT(6) -+ -+static int rtl826xb_get_features(struct phy_device *phydev) -+{ -+ int ret; -+ ret = genphy_c45_pma_read_abilities(phydev); -+ if (ret) -+ return ret; -+ -+ linkmode_or(phydev->supported, phydev->supported, PHY_BASIC_FEATURES); -+ -+ -+ linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, -+ phydev->supported); -+ linkmode_set_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, -+ phydev->supported); -+ -+ /* not support 10M modes */ -+ linkmode_clear_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, -+ phydev->supported); -+ linkmode_clear_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, -+ phydev->supported); -+ -+ return 0; -+} -+ -+static int rtl826xb_probe(struct phy_device *phydev) -+{ -+ struct device *dev = &phydev->mdio.dev; -+ struct rtk_phy_priv *priv = NULL; -+ -+ priv = devm_kzalloc(&phydev->mdio.dev, sizeof(struct rtk_phy_priv), GFP_KERNEL); -+ if (!priv) -+ { -+ return -ENOMEM; -+ } -+ memset(priv, 0, sizeof(struct rtk_phy_priv)); -+ -+ if (phy_rtl826xb_patch_db_init(0, phydev, &(priv->patch)) != RT_ERR_OK) -+ return -ENOMEM; -+ -+ priv->phytype = (phydev->drv->phy_id == REALTEK_PHY_ID_RTL8261N) ? (RTK_PHYLIB_RTL8261N) : (RTK_PHYLIB_RTL8264B); -+ priv->isBasePort = (phydev->drv->phy_id == REALTEK_PHY_ID_RTL8261N) ? (1) : (((phydev->mdio.addr % 4) == 0) ? (1) : (0)); -+ priv->pnswap_rx = device_property_read_bool(dev, "realtek,pnswap-rx"); -+ priv->pnswap_tx = device_property_read_bool(dev, "realtek,pnswap-tx"); -+ phydev->priv = priv; -+ -+ return 0; -+} -+ -+static int rtkphy_config_init(struct phy_device *phydev) -+{ -+ struct rtk_phy_priv *priv = phydev->priv; -+ int ret = 0; -+ switch (phydev->drv->phy_id) -+ { -+ case REALTEK_PHY_ID_RTL8261N: -+ case REALTEK_PHY_ID_RTL8264B: -+ case REALTEK_PHY_ID_RTL8264: -+ phydev_info(phydev, "%s:%u [RTL8261N/RTL8264/RTL826XB] phy_id: 0x%X PHYAD:%d\n", __FUNCTION__, __LINE__, phydev->drv->phy_id, phydev->mdio.addr); -+#ifdef CONFIG_MACH_REALTEK_RTL -+ return 0; -+#endif -+ -+ #if 1 /* toggle reset */ -+ phy_modify_mmd_changed(phydev, 30, 0x145, BIT(0) , 1); -+ phy_modify_mmd_changed(phydev, 30, 0x145, BIT(0) , 0); -+ mdelay(30); -+ #endif -+ -+ ret = phy_patch(0, phydev, 0, PHY_PATCH_MODE_NORMAL); -+ if (ret) -+ { -+ phydev_err(phydev, "%s:%u [RTL8261N/RTL826XB] patch failed!! 0x%X\n", __FUNCTION__, __LINE__, ret); -+ return ret; -+ } -+ #if 0 /* Debug: patch check */ -+ ret = phy_patch(0, phydev, 0, PHY_PATCH_MODE_CMP); -+ if (ret) -+ { -+ phydev_err(phydev, "%s:%u [RTL8261N/RTL826XB] phy_patch failed!! 0x%X\n", __FUNCTION__, __LINE__, ret); -+ return ret; -+ } -+ printk("[%s,%u] patch chk %s\n", __FUNCTION__, __LINE__, (ret == 0) ? "PASS" : "FAIL"); -+ #endif -+ #if 0 /* Debug: USXGMII*/ -+ { -+ uint32 data = 0; -+ rtk_phylib_826xb_sds_read(phydev, 0x07, 0x10, 15, 0, &data); -+ printk("[%s,%u] SDS 0x07, 0x10 : 0x%X\n", __FUNCTION__, __LINE__, data); -+ rtk_phylib_826xb_sds_read(phydev, 0x06, 0x12, 15, 0, &data); -+ printk("[%s,%u] SDS 0x06, 0x12 : 0x%X\n", __FUNCTION__, __LINE__, data); -+ } -+ { -+ u16 sdspage = 0x5, sdsreg = 0x0; -+ u16 regData = (sdspage & 0x3f) | ((sdsreg & 0x1f) << 6) | BIT(15); -+ u16 readData = 0; -+ phy_write_mmd(phydev, 30, 323, regData); -+ do -+ { -+ udelay(10); -+ readData = phy_read_mmd(phydev, 30, 323); -+ } while ((readData & BIT(15)) != 0); -+ readData = phy_read_mmd(phydev, 30, 322); -+ printk("[%s,%d] sds link [%s] (0x%X)\n", __FUNCTION__, __LINE__, (readData & BIT(12)) ? "UP" : "DOWN", readData); -+ } -+ #endif -+ -+ if (priv->pnswap_rx) -+ phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, -+ REALTEK_SERDES_GLOBAL_CFG, -+ REALTEK_HSI_INV); -+ -+ if (priv->pnswap_tx) -+ phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, -+ REALTEK_SERDES_GLOBAL_CFG, -+ REALTEK_HSO_INV); -+ -+ break; -+ default: -+ phydev_err(phydev, "%s:%u Unknow phy_id: 0x%X\n", __FUNCTION__, __LINE__, phydev->drv->phy_id); -+ return -EPERM; -+ } -+ -+ return ret; -+} -+ -+static int rtkphy_c45_suspend(struct phy_device *phydev) -+{ -+ int ret = 0; -+ -+#ifndef CONFIG_MACH_REALTEK_RTL -+ ret = rtk_phylib_c45_power_low(phydev); -+#endif -+ -+ phydev->speed = SPEED_UNKNOWN; -+ phydev->duplex = DUPLEX_UNKNOWN; -+ phydev->pause = 0; -+ phydev->asym_pause = 0; -+ -+ return ret; -+} -+ -+static int rtkphy_c45_resume(struct phy_device *phydev) -+{ -+#ifndef CONFIG_MACH_REALTEK_RTL -+ return rtk_phylib_c45_power_normal(phydev); -+#else -+ return 0; -+#endif -+} -+ -+static int rtkphy_c45_config_aneg(struct phy_device *phydev) -+{ -+ bool changed = false; -+ u16 reg = 0; -+ int ret = 0; -+ -+ phydev->mdix_ctrl = ETH_TP_MDI_AUTO; -+ if (phydev->autoneg == AUTONEG_DISABLE) -+ return genphy_c45_pma_setup_forced(phydev); -+ -+ ret = genphy_c45_an_config_aneg(phydev); -+ if (ret < 0) -+ return ret; -+ if (ret > 0) -+ changed = true; -+ -+ reg = 0; -+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, -+ phydev->advertising)) -+ reg |= BIT(9); -+ -+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, -+ phydev->advertising)) -+ reg |= BIT(8); -+ -+ ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND2, 0xA412, -+ BIT(9) | BIT(8) , reg); -+ if (ret < 0) -+ return ret; -+ if (ret > 0) -+ changed = true; -+ -+ return genphy_c45_check_and_restart_aneg(phydev, changed); -+} -+ -+static int rtkphy_c45_aneg_done(struct phy_device *phydev) -+{ -+ return genphy_c45_aneg_done(phydev); -+} -+ -+static int rtkphy_c45_read_status(struct phy_device *phydev) -+{ -+ int ret = 0, status = 0; -+ phydev->speed = SPEED_UNKNOWN; -+ phydev->duplex = DUPLEX_UNKNOWN; -+ phydev->pause = 0; -+ phydev->asym_pause = 0; -+ -+ ret = genphy_c45_read_link(phydev); -+ if (ret) -+ return ret; -+ -+ if (phydev->autoneg == AUTONEG_ENABLE) -+ { -+ linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, -+ phydev->lp_advertising); -+ -+ ret = genphy_c45_read_lpa(phydev); -+ if (ret) -+ return ret; -+ -+ status = phy_read_mmd(phydev, 31, 0xA414); -+ if (status < 0) -+ return status; -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, -+ phydev->lp_advertising, status & BIT(11)); -+ -+ phy_resolve_aneg_linkmode(phydev); -+ } -+ else -+ { -+ ret = genphy_c45_read_pma(phydev); -+ } -+ -+ /* mdix*/ -+ status = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_SWAPPOL); -+ if (status < 0) -+ return status; -+ -+ switch (status & 0x3) -+ { -+ case MDIO_PMA_10GBT_SWAPPOL_ABNX | MDIO_PMA_10GBT_SWAPPOL_CDNX: -+ phydev->mdix = ETH_TP_MDI; -+ break; -+ -+ case 0: -+ phydev->mdix = ETH_TP_MDI_X; -+ break; -+ -+ default: -+ phydev->mdix = ETH_TP_MDI_INVALID; -+ break; -+ } -+ -+ return ret; -+} -+ -+ -+static struct phy_driver rtk_phy_drivers[] = { -+ { -+ PHY_ID_MATCH_EXACT(REALTEK_PHY_ID_RTL8261N), -+ .name = "Realtek RTL8261N", -+ .get_features = rtl826xb_get_features, -+ .config_init = rtkphy_config_init, -+ .probe = rtl826xb_probe, -+ .suspend = rtkphy_c45_suspend, -+ .resume = rtkphy_c45_resume, -+ .config_aneg = rtkphy_c45_config_aneg, -+ .aneg_done = rtkphy_c45_aneg_done, -+ .read_status = rtkphy_c45_read_status, -+ }, -+ { -+ PHY_ID_MATCH_EXACT(REALTEK_PHY_ID_RTL8264B), -+ .name = "Realtek RTL8264B", -+ .get_features = rtl826xb_get_features, -+ .config_init = rtkphy_config_init, -+ .probe = rtl826xb_probe, -+ .suspend = rtkphy_c45_suspend, -+ .resume = rtkphy_c45_resume, -+ .config_aneg = rtkphy_c45_config_aneg, -+ .aneg_done = rtkphy_c45_aneg_done, -+ .read_status = rtkphy_c45_read_status, -+ }, -+ { -+ PHY_ID_MATCH_EXACT(REALTEK_PHY_ID_RTL8264), -+ .name = "Realtek RTL8264", -+ .get_features = rtl826xb_get_features, -+ .config_init = rtkphy_config_init, -+ .probe = rtl826xb_probe, -+ .suspend = rtkphy_c45_suspend, -+ .resume = rtkphy_c45_resume, -+ .config_aneg = rtkphy_c45_config_aneg, -+ .aneg_done = rtkphy_c45_aneg_done, -+ .read_status = rtkphy_c45_read_status, -+ }, -+}; -+ -+module_phy_driver(rtk_phy_drivers); -+ -+ -+static struct mdio_device_id __maybe_unused rtk_phy_tbl[] = { -+ { PHY_ID_MATCH_EXACT(REALTEK_PHY_ID_RTL8261N) }, -+ { PHY_ID_MATCH_EXACT(REALTEK_PHY_ID_RTL8264B) }, -+ { PHY_ID_MATCH_EXACT(REALTEK_PHY_ID_RTL8264) }, -+ { }, -+}; -+ -+MODULE_DEVICE_TABLE(mdio, rtk_phy_tbl); -+ -+MODULE_AUTHOR("Realtek"); -+MODULE_DESCRIPTION("Realtek PHY drivers"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/net/phy/rtl8261n/rtk_phylib.c b/drivers/net/phy/rtl8261n/rtk_phylib.c -new file mode 100644 -index 000000000000..7dd593ce72df ---- /dev/null -+++ b/drivers/net/phy/rtl8261n/rtk_phylib.c -@@ -0,0 +1,108 @@ -+/* -+ * SPDX-License-Identifier: GPL-2.0-only -+ * -+ * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. -+ */ -+ -+#include "rtk_phylib.h" -+#include -+ -+ -+/* OSAL */ -+ -+void rtk_phylib_mdelay(uint32 msec) -+{ -+#if defined(RTK_PHYDRV_IN_LINUX) -+ mdelay(msec); -+#else -+ osal_time_mdelay(msec); -+#endif -+} -+ -+ -+void rtk_phylib_udelay(uint32 usec) -+{ -+#if defined(RTK_PHYDRV_IN_LINUX) -+ if (1000 <= usec) -+ { -+ mdelay(usec/1000); -+ usec = usec % 1000; -+ } -+ udelay(usec); -+#else -+ osal_time_udelay(usec); -+#endif -+} -+ -+ -+/* Register Access APIs */ -+int32 rtk_phylib_mmd_write(rtk_phydev *phydev, uint32 mmd, uint32 reg, uint8 msb, uint8 lsb, uint32 data) -+{ -+ int32 ret = 0; -+ uint32 mask = 0; -+ mask = UINT32_BITS_MASK(msb,lsb); -+ -+#if defined(RTK_PHYDRV_IN_LINUX) -+ ret = phy_modify_mmd(phydev, mmd, reg, mask, data); -+#else -+ { -+ uint32 rData = 0, wData = 0; -+ if ((msb != 15) || (lsb != 0)) -+ { -+ if ((ret = phy_common_general_reg_mmd_get(phydev->unit, phydev->port, page, reg, &rData)) != RT_ERR_OK) -+ return ret; -+ } -+ wData = REG32_FIELD_SET(rData, data, lsb, mask); -+ ret = phy_common_general_reg_mmd_set(phydev->unit, phydev->port, page, reg, wData); -+ } -+#endif -+ -+ return ret; -+} -+ -+int32 rtk_phylib_mmd_read(rtk_phydev *phydev, uint32 mmd, uint32 reg, uint8 msb, uint8 lsb, uint32 *pData) -+{ -+ int32 ret = 0; -+ uint32 rData = 0; -+ uint32 mask = 0; -+ mask = UINT32_BITS_MASK(msb,lsb); -+ -+#if defined(RTK_PHYDRV_IN_LINUX) -+ rData = phy_read_mmd(phydev, mmd, reg); -+#else -+ { -+ ret = phy_common_general_reg_mmd_get(phydev->unit, phydev->port, page, reg, &rData); -+ } -+#endif -+ -+ *pData = REG32_FIELD_GET(rData, lsb, mask); -+ return ret; -+} -+ -+/* Function Driver */ -+ -+int32 rtk_phylib_c45_power_normal(rtk_phydev *phydev) -+{ -+ int32 ret = 0; -+ RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_write(phydev, 1, 0, 11, 11, 0)); -+ -+ return 0; -+} -+ -+int32 rtk_phylib_c45_power_low(rtk_phydev *phydev) -+{ -+ int32 ret = 0; -+ RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_write(phydev, 1, 0, 11, 11, 1)); -+ -+ return 0; -+} -+ -+int32 rtk_phylib_c45_pcs_loopback(rtk_phydev *phydev, uint32 enable) -+{ -+ int32 ret = 0; -+ RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_write(phydev, 3, 0, 14, 14, (enable == 0) ? 0 : 1)); -+ -+ return 0; -+} -+ -+ -diff --git a/drivers/net/phy/rtl8261n/rtk_phylib.h b/drivers/net/phy/rtl8261n/rtk_phylib.h -new file mode 100644 -index 000000000000..c1253b1ec975 ---- /dev/null -+++ b/drivers/net/phy/rtl8261n/rtk_phylib.h -@@ -0,0 +1,106 @@ -+/* -+ * SPDX-License-Identifier: GPL-2.0-only -+ * -+ * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. -+ */ -+ -+#ifndef __RTK_PHYLIB_H -+#define __RTK_PHYLIB_H -+ -+#if defined(RTK_PHYDRV_IN_LINUX) -+ #include -+ -+ #include "type.h" -+ #include "rtk_phylib_def.h" -+#else -+ //#include SDK headers -+#endif -+ -+#if defined(RTK_PHYDRV_IN_LINUX) -+ #define PR_INFO(_fmt, _args...) pr_info(_fmt, ##_args) -+ #define PR_DBG(_fmt, _args...) pr_debug(_fmt, ##_args) -+ #define PR_ERR(_fmt, _args...) pr_err("ERROR: "_fmt, ##_args) -+ -+ #define RTK_PHYLIB_ERR_FAILED (-EPERM) -+ #define RTK_PHYLIB_ERR_INPUT (-EINVAL) -+ #define RTK_PHYLIB_ERR_EXCEEDS_CAPACITY (-ENOSPC) -+ #define RTK_PHYLIB_ERR_TIMEOUT (-ETIME) -+ #define RTK_PHYLIB_ERR_ENTRY_NOTFOUND (-ENODATA) -+#else -+ #define PR_INFO(_fmt, _args...) RT_LOG(LOG_INFO, (MOD_HAL|MOD_PHY), _fmt, ##_args) -+ #define PR_DBG(_fmt, _args...) RT_LOG(LOG_DEBUG, (MOD_HAL|MOD_PHY), _fmt, ##_args) -+ #define PR_ERR(_fmt, _args...) RT_LOG(LOG_MAJOR_ERR, (MOD_HAL|MOD_PHY), _fmt, ##_args) -+ -+ #define RTK_PHYLIB_ERR_FAILED (RT_ERR_FAILED) -+ #define RTK_PHYLIB_ERR_INPUT (RT_ERR_INPUT) -+ #define RTK_PHYLIB_ERR_EXCEEDS_CAPACITY (RT_ERR_EXCEEDS_CAPACITY) -+ #define RTK_PHYLIB_ERR_TIMEOUT (RT_ERR_BUSYWAIT_TIMEOUT) -+ #define RTK_PHYLIB_ERR_ENTRY_NOTFOUND (RT_ERR_ENTRY_NOTFOUND) -+#endif -+ -+typedef enum rtk_phylib_phy_e -+{ -+ RTK_PHYLIB_NONE, -+ RTK_PHYLIB_RTL8261N, -+ RTK_PHYLIB_RTL8264B, -+ RTK_PHYLIB_END -+} rtk_phylib_phy_t; -+ -+struct rtk_phy_priv { -+ rtk_phylib_phy_t phytype; -+ uint8 isBasePort; -+ rt_phy_patch_db_t *patch; -+ -+ bool pnswap_rx; -+ bool pnswap_tx; -+}; -+ -+#if defined(RTK_PHYDRV_IN_LINUX) -+ typedef struct phy_device rtk_phydev; -+#else -+ struct rtk_phy_dev_s -+ { -+ uint32 unit; -+ rtk_port_t port; -+ -+ struct rtk_phy_priv *priv; -+ }; -+ typedef struct rtk_phy_dev_s rtk_phydev; -+#endif -+ -+#define RTK_PHYLIB_ERR_CHK(op)\ -+do {\ -+ if ((ret = (op)) != 0)\ -+ return ret;\ -+} while(0) -+ -+#define RTK_PHYLIB_VAL_TO_BYTE_ARRAY(_val, _valbytes, _array, _start, _bytes)\ -+do{\ -+ uint32 _i = 0;\ -+ for (_i = 0; _i < _bytes; _i++)\ -+ _array[_start+_i] = (_val >> (8* (_valbytes - _i - 1)));\ -+}while(0) -+ -+#define RTK_PHYLIB_BYTE_ARRAY_TO_VAL(_val, _array, _start, _bytes)\ -+do{\ -+ uint32 _i = 0;\ -+ for (_i = 0; _i < _bytes; _i++)\ -+ _val = (_val << 8) | _array[_start + _i];\ -+}while(0) -+ -+ -+/* OSAL */ -+void rtk_phylib_mdelay(uint32 msec); -+void rtk_phylib_udelay(uint32 usec); -+ -+/* Register Access APIs */ -+int32 rtk_phylib_mmd_write(rtk_phydev *phydev, uint32 mmd, uint32 reg, uint8 msb, uint8 lsb, uint32 data); -+int32 rtk_phylib_mmd_read(rtk_phydev *phydev, uint32 mmd, uint32 reg, uint8 msb, uint8 lsb, uint32 *pData); -+ -+/* Function Driver */ -+int32 rtk_phylib_c45_power_normal(rtk_phydev *phydev); -+int32 rtk_phylib_c45_power_low(rtk_phydev *phydev); -+int32 rtk_phylib_c45_pcs_loopback(rtk_phydev *phydev, uint32 enable); -+ -+ -+#endif /* __RTK_PHYLIB_H */ -diff --git a/drivers/net/phy/rtl8261n/rtk_phylib_def.h b/drivers/net/phy/rtl8261n/rtk_phylib_def.h -new file mode 100644 -index 000000000000..f49f0b547cc3 ---- /dev/null -+++ b/drivers/net/phy/rtl8261n/rtk_phylib_def.h -@@ -0,0 +1,166 @@ -+/* -+ * SPDX-License-Identifier: GPL-2.0-only -+ * -+ * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. -+ */ -+#ifndef __RTK_PHYLIB_DEF_H -+#define __RTK_PHYLIB_DEF_H -+ -+#include "type.h" -+ -+//#define PHY_C22_MMD_PAGE 0 -+#define PHY_C22_MMD_PAGE 0x0A41 -+#define PHY_C22_MMD_DEV_REG 13 -+#define PHY_C22_MMD_ADD_REG 14 -+ -+/* MDIO Manageable Device(MDD) address*/ -+#define PHY_MMD_PMAPMD 1 -+#define PHY_MMD_PCS 3 -+#define PHY_MMD_AN 7 -+#define PHY_MMD_VEND1 30 /* Vendor specific 1 */ -+#define PHY_MMD_VEND2 31 /* Vendor specific 2 */ -+ -+#define BIT_0 0x00000001U -+#define BIT_1 0x00000002U -+#define BIT_2 0x00000004U -+#define BIT_3 0x00000008U -+#define BIT_4 0x00000010U -+#define BIT_5 0x00000020U -+#define BIT_6 0x00000040U -+#define BIT_7 0x00000080U -+#define BIT_8 0x00000100U -+#define BIT_9 0x00000200U -+#define BIT_10 0x00000400U -+#define BIT_11 0x00000800U -+#define BIT_12 0x00001000U -+#define BIT_13 0x00002000U -+#define BIT_14 0x00004000U -+#define BIT_15 0x00008000U -+#define BIT_16 0x00010000U -+#define BIT_17 0x00020000U -+#define BIT_18 0x00040000U -+#define BIT_19 0x00080000U -+#define BIT_20 0x00100000U -+#define BIT_21 0x00200000U -+#define BIT_22 0x00400000U -+#define BIT_23 0x00800000U -+#define BIT_24 0x01000000U -+#define BIT_25 0x02000000U -+#define BIT_26 0x04000000U -+#define BIT_27 0x08000000U -+#define BIT_28 0x10000000U -+#define BIT_29 0x20000000U -+#define BIT_30 0x40000000U -+#define BIT_31 0x80000000U -+ -+#define MASK_1_BITS (BIT_1 - 1) -+#define MASK_2_BITS (BIT_2 - 1) -+#define MASK_3_BITS (BIT_3 - 1) -+#define MASK_4_BITS (BIT_4 - 1) -+#define MASK_5_BITS (BIT_5 - 1) -+#define MASK_6_BITS (BIT_6 - 1) -+#define MASK_7_BITS (BIT_7 - 1) -+#define MASK_8_BITS (BIT_8 - 1) -+#define MASK_9_BITS (BIT_9 - 1) -+#define MASK_10_BITS (BIT_10 - 1) -+#define MASK_11_BITS (BIT_11 - 1) -+#define MASK_12_BITS (BIT_12 - 1) -+#define MASK_13_BITS (BIT_13 - 1) -+#define MASK_14_BITS (BIT_14 - 1) -+#define MASK_15_BITS (BIT_15 - 1) -+#define MASK_16_BITS (BIT_16 - 1) -+#define MASK_17_BITS (BIT_17 - 1) -+#define MASK_18_BITS (BIT_18 - 1) -+#define MASK_19_BITS (BIT_19 - 1) -+#define MASK_20_BITS (BIT_20 - 1) -+#define MASK_21_BITS (BIT_21 - 1) -+#define MASK_22_BITS (BIT_22 - 1) -+#define MASK_23_BITS (BIT_23 - 1) -+#define MASK_24_BITS (BIT_24 - 1) -+#define MASK_25_BITS (BIT_25 - 1) -+#define MASK_26_BITS (BIT_26 - 1) -+#define MASK_27_BITS (BIT_27 - 1) -+#define MASK_28_BITS (BIT_28 - 1) -+#define MASK_29_BITS (BIT_29 - 1) -+#define MASK_30_BITS (BIT_30 - 1) -+#define MASK_31_BITS (BIT_31 - 1) -+ -+#define REG32_FIELD_SET(_data, _val, _fOffset, _fMask) ((_data & ~(_fMask)) | ((_val << (_fOffset)) & (_fMask))) -+#define REG32_FIELD_GET(_data, _fOffset, _fMask) ((_data & (_fMask)) >> (_fOffset)) -+#define UINT32_BITS_MASK(_mBit, _lBit) ((0xFFFFFFFF >> (31 - _mBit)) ^ ((1 << _lBit) - 1)) -+ -+typedef struct phy_device * rtk_port_t; -+ -+#if 1 /* ss\sdk\include\hal\phy\phydef.h */ -+/* unified patch format */ -+typedef enum rtk_phypatch_type_e -+{ -+ PHY_PATCH_TYPE_NONE = 0, -+ PHY_PATCH_TYPE_TOP = 1, -+ PHY_PATCH_TYPE_SDS, -+ PHY_PATCH_TYPE_AFE, -+ PHY_PATCH_TYPE_UC, -+ PHY_PATCH_TYPE_UC2, -+ PHY_PATCH_TYPE_NCTL0, -+ PHY_PATCH_TYPE_NCTL1, -+ PHY_PATCH_TYPE_NCTL2, -+ PHY_PATCH_TYPE_ALGXG, -+ PHY_PATCH_TYPE_ALG1G, -+ PHY_PATCH_TYPE_NORMAL, -+ PHY_PATCH_TYPE_DATARAM, -+ PHY_PATCH_TYPE_RTCT, -+ PHY_PATCH_TYPE_END -+} rtk_phypatch_type_t; -+ -+#define RTK_PATCH_TYPE_FLOW(_id) (PHY_PATCH_TYPE_END + _id) -+#define RTK_PATCH_TYPE_FLOWID_MAX PHY_PATCH_TYPE_END -+#define RTK_PATCH_SEQ_MAX ( PHY_PATCH_TYPE_END + RTK_PATCH_TYPE_FLOWID_MAX -1) -+ -+typedef struct rtk_hwpatch_s -+{ -+ uint8 patch_op; -+ uint8 portmask; -+ uint16 pagemmd; -+ uint16 addr; -+ uint8 msb; -+ uint8 lsb; -+ uint16 data; -+ uint8 compare_op; -+ uint16 sram_p; -+ uint16 sram_rr; -+ uint16 sram_rw; -+ uint16 sram_a; -+} rtk_hwpatch_t; -+ -+typedef struct rtk_hwpatch_data_s -+{ -+ rtk_hwpatch_t *conf; -+ uint32 size; -+} rtk_hwpatch_data_t; -+ -+typedef struct rtk_hwpatch_seq_s -+{ -+ uint8 patch_type; -+ union -+ { -+ rtk_hwpatch_data_t data; -+ uint8 flow_id; -+ } patch; -+} rtk_hwpatch_seq_t; -+ -+typedef struct rt_phy_patch_db_s -+{ -+ /* patch operation */ -+ int32 (*fPatch_op)(uint32 unit, rtk_port_t port, uint8 portOffset, rtk_hwpatch_t *pPatch_data, uint8 patch_mode); -+ int32 (*fPatch_flow)(uint32 unit, rtk_port_t port, uint8 portOffset, uint8 patch_flow, uint8 patch_mode); -+ -+ /* patch data */ -+ rtk_hwpatch_seq_t seq_table[RTK_PATCH_SEQ_MAX]; -+ rtk_hwpatch_seq_t cmp_table[RTK_PATCH_SEQ_MAX]; -+ -+} rt_phy_patch_db_t; -+#endif -+ -+ -+ -+#endif /* __RTK_PHYLIB_DEF_H */ -diff --git a/drivers/net/phy/rtl8261n/rtk_phylib_rtl826xb.c b/drivers/net/phy/rtl8261n/rtk_phylib_rtl826xb.c -new file mode 100644 -index 000000000000..1c33846a70fc ---- /dev/null -+++ b/drivers/net/phy/rtl8261n/rtk_phylib_rtl826xb.c -@@ -0,0 +1,57 @@ -+/* -+ * SPDX-License-Identifier: GPL-2.0-only -+ * -+ * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. -+ */ -+ -+#include "rtk_phylib_rtl826xb.h" -+ -+/* Indirect Register Access APIs */ -+int rtk_phylib_826xb_sds_read(rtk_phydev *phydev, uint32 page, uint32 reg, uint8 msb, uint8 lsb, uint32 *pData) -+{ -+ int32 ret = 0; -+ uint32 rData = 0; -+ uint32 op = (page & 0x3f) | ((reg & 0x1f) << 6) | (0x8000); -+ uint32 i = 0; -+ uint32 mask = 0; -+ mask = UINT32_BITS_MASK(msb,lsb); -+ -+ RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_write(phydev, 30, 323, 15, 0, op)); -+ -+ for (i = 0; i < 10; i++) -+ { -+ RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_read(phydev, 30, 323, 15, 15, &rData)); -+ if (rData == 0) -+ { -+ break; -+ } -+ rtk_phylib_udelay(10); -+ } -+ if (i == 10) -+ { -+ return -1; -+ } -+ -+ RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_read(phydev, 30, 322, 15, 0, &rData)); -+ *pData = REG32_FIELD_GET(rData, lsb, mask); -+ -+ return ret; -+} -+ -+int rtk_phylib_826xb_sds_write(rtk_phydev *phydev, uint32 page, uint32 reg, uint8 msb, uint8 lsb, uint32 data) -+{ -+ int32 ret = 0; -+ uint32 wData = 0, rData = 0; -+ uint32 op = (page & 0x3f) | ((reg & 0x1f) << 6) | (0x8800); -+ uint32 mask = 0; -+ mask = UINT32_BITS_MASK(msb,lsb); -+ -+ RTK_PHYLIB_ERR_CHK(rtk_phylib_826xb_sds_read(phydev, page, reg, 15, 0, &rData)); -+ -+ wData = REG32_FIELD_SET(rData, data, lsb, mask); -+ -+ RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_write(phydev, 30, 321, 15, 0, wData)); -+ RTK_PHYLIB_ERR_CHK(rtk_phylib_mmd_write(phydev, 30, 323, 15, 0, op)); -+ -+ return ret; -+} -diff --git a/drivers/net/phy/rtl8261n/rtk_phylib_rtl826xb.h b/drivers/net/phy/rtl8261n/rtk_phylib_rtl826xb.h -new file mode 100644 -index 000000000000..9f827d4ba254 ---- /dev/null -+++ b/drivers/net/phy/rtl8261n/rtk_phylib_rtl826xb.h -@@ -0,0 +1,19 @@ -+/* -+ * SPDX-License-Identifier: GPL-2.0-only -+ * -+ * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. -+ */ -+ -+#ifndef __RTK_PHYLIB_RTL826XB_H -+#define __RTK_PHYLIB_RTL826XB_H -+ -+#if defined(RTK_PHYDRV_IN_LINUX) -+ #include "rtk_phylib.h" -+#else -+ //#include SDK headers -+#endif -+ -+int rtk_phylib_826xb_sds_read(rtk_phydev *phydev, uint32 page, uint32 reg, uint8 msb, uint8 lsb, uint32 *pData); -+int rtk_phylib_826xb_sds_write(rtk_phydev *phydev, uint32 page, uint32 reg, uint8 msb, uint8 lsb, uint32 data); -+ -+#endif /* __RTK_PHYLIB_RTL826XB_H */ -diff --git a/drivers/net/phy/rtl8261n/type.h b/drivers/net/phy/rtl8261n/type.h -new file mode 100644 -index 000000000000..98d7e15e1e4b ---- /dev/null -+++ b/drivers/net/phy/rtl8261n/type.h -@@ -0,0 +1,117 @@ -+/* -+ * SPDX-License-Identifier: GPL-2.0-only -+ * -+ * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. -+ */ -+ -+#ifndef __COMMON_TYPE_H__ -+#define __COMMON_TYPE_H__ -+ -+/* -+ * Symbol Definition -+ */ -+ -+#define USING_RTSTK_PKT_AS_RAIL -+ -+ -+#ifndef NULL -+#define NULL 0 -+#endif -+ -+#ifndef TRUE -+#define TRUE 1 -+#endif -+ -+#ifndef FALSE -+#define FALSE 0 -+#endif -+ -+#ifndef ETHER_ADDR_LEN -+#define ETHER_ADDR_LEN 6 -+#endif -+ -+#ifndef IP6_ADDR_LEN -+#define IP6_ADDR_LEN 16 -+#endif -+ -+ -+/* -+ * Data Type Declaration -+ */ -+#ifndef uint64 -+typedef unsigned long long uint64; -+#endif -+ -+#ifndef int64 -+typedef signed long long int64; -+#endif -+ -+#ifndef uint32 -+typedef unsigned int uint32; -+#endif -+ -+#ifndef int32 -+typedef signed int int32; -+#endif -+ -+#ifndef uint16 -+typedef unsigned short uint16; -+#endif -+ -+#ifndef int16 -+typedef signed short int16; -+#endif -+ -+#ifndef uint8 -+typedef unsigned char uint8; -+#endif -+ -+#ifndef int8 -+typedef signed char int8; -+#endif -+ -+//#define CONFIG_SDK_WORDSIZE_64 /* not ready */ -+#ifdef CONFIG_SDK_WORDSIZE_64 -+ typedef long int intptr; -+ typedef unsigned long int uintptr; -+#else -+ typedef int intptr; -+ typedef unsigned int uintptr; -+#endif -+ -+ -+#ifndef ipaddr_t -+typedef uint32 ipaddr_t; /* ipv4 address type */ -+#endif -+ -+/* configuration mode type */ -+typedef enum rtk_enable_e -+{ -+ DISABLED = 0, -+ ENABLED, -+ RTK_ENABLE_END -+} rtk_enable_t; -+ -+/* initial state of module */ -+typedef enum init_state_e -+{ -+ INIT_NOT_COMPLETED = 0, -+ INIT_COMPLETED, -+ INIT_STATE_END -+} init_state_t; -+ -+/* ethernet address type */ -+typedef struct rtk_mac_s -+{ -+ uint8 octet[ETHER_ADDR_LEN]; -+} rtk_mac_t; -+ -+typedef uint32 osal_time_t; -+typedef uint32 osal_usecs_t; -+ -+/* -+ * Macro Definition -+ */ -+ -+#endif /* __COMMON_TYPE_H__ */ -+ -diff --git a/drivers/net/phy/rtl8306.c b/drivers/net/phy/rtl8306.c -new file mode 100644 -index 000000000000..9bd1735f67b7 ---- /dev/null -+++ b/drivers/net/phy/rtl8306.c -@@ -0,0 +1,1063 @@ -+/* -+ * rtl8306.c: RTL8306S switch driver -+ * -+ * Copyright (C) 2009 Felix Fietkau -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+//#define DEBUG 1 -+ -+/* Global (PHY0) */ -+#define RTL8306_REG_PAGE 16 -+#define RTL8306_REG_PAGE_LO (1 << 15) -+#define RTL8306_REG_PAGE_HI (1 << 1) /* inverted */ -+ -+#define RTL8306_NUM_VLANS 16 -+#define RTL8306_NUM_PORTS 6 -+#define RTL8306_PORT_CPU 5 -+#define RTL8306_NUM_PAGES 4 -+#define RTL8306_NUM_REGS 32 -+ -+#define RTL_NAME_S "RTL8306S" -+#define RTL_NAME_SD "RTL8306SD" -+#define RTL_NAME_SDM "RTL8306SDM" -+#define RTL_NAME_UNKNOWN "RTL8306(unknown)" -+ -+#define RTL8306_MAGIC 0x8306 -+ -+static LIST_HEAD(phydevs); -+ -+struct rtl_priv { -+ struct list_head list; -+ struct switch_dev dev; -+ int page; -+ int type; -+ int do_cpu; -+ struct mii_bus *bus; -+ char hwname[sizeof(RTL_NAME_UNKNOWN)]; -+ bool fixup; -+}; -+ -+struct rtl_phyregs { -+ int nway; -+ int speed; -+ int duplex; -+}; -+ -+#define to_rtl(_dev) container_of(_dev, struct rtl_priv, dev) -+ -+enum { -+ RTL_TYPE_S, -+ RTL_TYPE_SD, -+ RTL_TYPE_SDM, -+}; -+ -+struct rtl_reg { -+ int page; -+ int phy; -+ int reg; -+ int bits; -+ int shift; -+ int inverted; -+}; -+ -+#define RTL_VLAN_REGOFS(name) \ -+ (RTL_REG_VLAN1_##name - RTL_REG_VLAN0_##name) -+ -+#define RTL_PORT_REGOFS(name) \ -+ (RTL_REG_PORT1_##name - RTL_REG_PORT0_##name) -+ -+#define RTL_PORT_REG(id, reg) \ -+ (RTL_REG_PORT0_##reg + (id * RTL_PORT_REGOFS(reg))) -+ -+#define RTL_VLAN_REG(id, reg) \ -+ (RTL_REG_VLAN0_##reg + (id * RTL_VLAN_REGOFS(reg))) -+ -+#define RTL_GLOBAL_REGATTR(reg) \ -+ .id = RTL_REG_##reg, \ -+ .type = SWITCH_TYPE_INT, \ -+ .ofs = 0, \ -+ .set = rtl_attr_set_int, \ -+ .get = rtl_attr_get_int -+ -+#define RTL_PORT_REGATTR(reg) \ -+ .id = RTL_REG_PORT0_##reg, \ -+ .type = SWITCH_TYPE_INT, \ -+ .ofs = RTL_PORT_REGOFS(reg), \ -+ .set = rtl_attr_set_port_int, \ -+ .get = rtl_attr_get_port_int -+ -+#define RTL_VLAN_REGATTR(reg) \ -+ .id = RTL_REG_VLAN0_##reg, \ -+ .type = SWITCH_TYPE_INT, \ -+ .ofs = RTL_VLAN_REGOFS(reg), \ -+ .set = rtl_attr_set_vlan_int, \ -+ .get = rtl_attr_get_vlan_int -+ -+enum rtl_regidx { -+ RTL_REG_CHIPID, -+ RTL_REG_CHIPVER, -+ RTL_REG_CHIPTYPE, -+ RTL_REG_CPUPORT, -+ -+ RTL_REG_EN_CPUPORT, -+ RTL_REG_EN_TAG_OUT, -+ RTL_REG_EN_TAG_CLR, -+ RTL_REG_EN_TAG_IN, -+ RTL_REG_TRAP_CPU, -+ RTL_REG_CPU_LINKUP, -+ RTL_REG_TRUNK_PORTSEL, -+ RTL_REG_EN_TRUNK, -+ RTL_REG_RESET, -+ -+ RTL_REG_VLAN_ENABLE, -+ RTL_REG_VLAN_FILTER, -+ RTL_REG_VLAN_TAG_ONLY, -+ RTL_REG_VLAN_TAG_AWARE, -+#define RTL_VLAN_ENUM(id) \ -+ RTL_REG_VLAN##id##_VID, \ -+ RTL_REG_VLAN##id##_PORTMASK -+ RTL_VLAN_ENUM(0), -+ RTL_VLAN_ENUM(1), -+ RTL_VLAN_ENUM(2), -+ RTL_VLAN_ENUM(3), -+ RTL_VLAN_ENUM(4), -+ RTL_VLAN_ENUM(5), -+ RTL_VLAN_ENUM(6), -+ RTL_VLAN_ENUM(7), -+ RTL_VLAN_ENUM(8), -+ RTL_VLAN_ENUM(9), -+ RTL_VLAN_ENUM(10), -+ RTL_VLAN_ENUM(11), -+ RTL_VLAN_ENUM(12), -+ RTL_VLAN_ENUM(13), -+ RTL_VLAN_ENUM(14), -+ RTL_VLAN_ENUM(15), -+#define RTL_PORT_ENUM(id) \ -+ RTL_REG_PORT##id##_PVID, \ -+ RTL_REG_PORT##id##_NULL_VID_REPLACE, \ -+ RTL_REG_PORT##id##_NON_PVID_DISCARD, \ -+ RTL_REG_PORT##id##_VID_INSERT, \ -+ RTL_REG_PORT##id##_TAG_INSERT, \ -+ RTL_REG_PORT##id##_LINK, \ -+ RTL_REG_PORT##id##_SPEED, \ -+ RTL_REG_PORT##id##_NWAY, \ -+ RTL_REG_PORT##id##_NRESTART, \ -+ RTL_REG_PORT##id##_DUPLEX, \ -+ RTL_REG_PORT##id##_RXEN, \ -+ RTL_REG_PORT##id##_TXEN -+ RTL_PORT_ENUM(0), -+ RTL_PORT_ENUM(1), -+ RTL_PORT_ENUM(2), -+ RTL_PORT_ENUM(3), -+ RTL_PORT_ENUM(4), -+ RTL_PORT_ENUM(5), -+}; -+ -+static const struct rtl_reg rtl_regs[] = { -+ [RTL_REG_CHIPID] = { 0, 4, 30, 16, 0, 0 }, -+ [RTL_REG_CHIPVER] = { 0, 4, 31, 8, 0, 0 }, -+ [RTL_REG_CHIPTYPE] = { 0, 4, 31, 2, 8, 0 }, -+ -+ /* CPU port number */ -+ [RTL_REG_CPUPORT] = { 2, 4, 21, 3, 0, 0 }, -+ /* Enable CPU port function */ -+ [RTL_REG_EN_CPUPORT] = { 3, 2, 21, 1, 15, 1 }, -+ /* Enable CPU port tag insertion */ -+ [RTL_REG_EN_TAG_OUT] = { 3, 2, 21, 1, 12, 0 }, -+ /* Enable CPU port tag removal */ -+ [RTL_REG_EN_TAG_CLR] = { 3, 2, 21, 1, 11, 0 }, -+ /* Enable CPU port tag checking */ -+ [RTL_REG_EN_TAG_IN] = { 0, 4, 21, 1, 7, 0 }, -+ [RTL_REG_EN_TRUNK] = { 0, 0, 19, 1, 11, 1 }, -+ [RTL_REG_TRUNK_PORTSEL] = { 0, 0, 16, 1, 6, 1 }, -+ [RTL_REG_RESET] = { 0, 0, 16, 1, 12, 0 }, -+ -+ [RTL_REG_TRAP_CPU] = { 3, 2, 22, 1, 6, 0 }, -+ [RTL_REG_CPU_LINKUP] = { 0, 6, 22, 1, 15, 0 }, -+ -+ [RTL_REG_VLAN_TAG_ONLY] = { 0, 0, 16, 1, 8, 1 }, -+ [RTL_REG_VLAN_FILTER] = { 0, 0, 16, 1, 9, 1 }, -+ [RTL_REG_VLAN_TAG_AWARE] = { 0, 0, 16, 1, 10, 1 }, -+ [RTL_REG_VLAN_ENABLE] = { 0, 0, 18, 1, 8, 1 }, -+ -+#define RTL_VLAN_REGS(id, phy, page, regofs) \ -+ [RTL_REG_VLAN##id##_VID] = { page, phy, 25 + regofs, 12, 0, 0 }, \ -+ [RTL_REG_VLAN##id##_PORTMASK] = { page, phy, 24 + regofs, 6, 0, 0 } -+ RTL_VLAN_REGS( 0, 0, 0, 0), -+ RTL_VLAN_REGS( 1, 1, 0, 0), -+ RTL_VLAN_REGS( 2, 2, 0, 0), -+ RTL_VLAN_REGS( 3, 3, 0, 0), -+ RTL_VLAN_REGS( 4, 4, 0, 0), -+ RTL_VLAN_REGS( 5, 0, 1, 2), -+ RTL_VLAN_REGS( 6, 1, 1, 2), -+ RTL_VLAN_REGS( 7, 2, 1, 2), -+ RTL_VLAN_REGS( 8, 3, 1, 2), -+ RTL_VLAN_REGS( 9, 4, 1, 2), -+ RTL_VLAN_REGS(10, 0, 1, 4), -+ RTL_VLAN_REGS(11, 1, 1, 4), -+ RTL_VLAN_REGS(12, 2, 1, 4), -+ RTL_VLAN_REGS(13, 3, 1, 4), -+ RTL_VLAN_REGS(14, 4, 1, 4), -+ RTL_VLAN_REGS(15, 0, 1, 6), -+ -+#define REG_PORT_SETTING(port, phy) \ -+ [RTL_REG_PORT##port##_SPEED] = { 0, phy, 0, 1, 13, 0 }, \ -+ [RTL_REG_PORT##port##_NWAY] = { 0, phy, 0, 1, 12, 0 }, \ -+ [RTL_REG_PORT##port##_NRESTART] = { 0, phy, 0, 1, 9, 0 }, \ -+ [RTL_REG_PORT##port##_DUPLEX] = { 0, phy, 0, 1, 8, 0 }, \ -+ [RTL_REG_PORT##port##_TXEN] = { 0, phy, 24, 1, 11, 0 }, \ -+ [RTL_REG_PORT##port##_RXEN] = { 0, phy, 24, 1, 10, 0 }, \ -+ [RTL_REG_PORT##port##_LINK] = { 0, phy, 1, 1, 2, 0 }, \ -+ [RTL_REG_PORT##port##_NULL_VID_REPLACE] = { 0, phy, 22, 1, 12, 0 }, \ -+ [RTL_REG_PORT##port##_NON_PVID_DISCARD] = { 0, phy, 22, 1, 11, 0 }, \ -+ [RTL_REG_PORT##port##_VID_INSERT] = { 0, phy, 22, 2, 9, 0 }, \ -+ [RTL_REG_PORT##port##_TAG_INSERT] = { 0, phy, 22, 2, 0, 0 } -+ -+ REG_PORT_SETTING(0, 0), -+ REG_PORT_SETTING(1, 1), -+ REG_PORT_SETTING(2, 2), -+ REG_PORT_SETTING(3, 3), -+ REG_PORT_SETTING(4, 4), -+ REG_PORT_SETTING(5, 6), -+ -+#define REG_PORT_PVID(phy, page, regofs) \ -+ { page, phy, 24 + regofs, 4, 12, 0 } -+ [RTL_REG_PORT0_PVID] = REG_PORT_PVID(0, 0, 0), -+ [RTL_REG_PORT1_PVID] = REG_PORT_PVID(1, 0, 0), -+ [RTL_REG_PORT2_PVID] = REG_PORT_PVID(2, 0, 0), -+ [RTL_REG_PORT3_PVID] = REG_PORT_PVID(3, 0, 0), -+ [RTL_REG_PORT4_PVID] = REG_PORT_PVID(4, 0, 0), -+ [RTL_REG_PORT5_PVID] = REG_PORT_PVID(0, 1, 2), -+}; -+ -+ -+static inline void -+rtl_set_page(struct rtl_priv *priv, unsigned int page) -+{ -+ struct mii_bus *bus = priv->bus; -+ u16 pgsel; -+ -+ if (priv->fixup) -+ return; -+ -+ if (priv->page == page) -+ return; -+ -+ BUG_ON(page > RTL8306_NUM_PAGES); -+ pgsel = bus->read(bus, 0, RTL8306_REG_PAGE); -+ pgsel &= ~(RTL8306_REG_PAGE_LO | RTL8306_REG_PAGE_HI); -+ if (page & (1 << 0)) -+ pgsel |= RTL8306_REG_PAGE_LO; -+ if (!(page & (1 << 1))) /* bit is inverted */ -+ pgsel |= RTL8306_REG_PAGE_HI; -+ bus->write(bus, 0, RTL8306_REG_PAGE, pgsel); -+} -+ -+static inline int -+rtl_w16(struct switch_dev *dev, unsigned int page, unsigned int phy, unsigned int reg, u16 val) -+{ -+ struct rtl_priv *priv = to_rtl(dev); -+ struct mii_bus *bus = priv->bus; -+ -+ rtl_set_page(priv, page); -+ bus->write(bus, phy, reg, val); -+ bus->read(bus, phy, reg); /* flush */ -+ return 0; -+} -+ -+static inline int -+rtl_r16(struct switch_dev *dev, unsigned int page, unsigned int phy, unsigned int reg) -+{ -+ struct rtl_priv *priv = to_rtl(dev); -+ struct mii_bus *bus = priv->bus; -+ -+ rtl_set_page(priv, page); -+ return bus->read(bus, phy, reg); -+} -+ -+static inline u16 -+rtl_rmw(struct switch_dev *dev, unsigned int page, unsigned int phy, unsigned int reg, u16 mask, u16 val) -+{ -+ struct rtl_priv *priv = to_rtl(dev); -+ struct mii_bus *bus = priv->bus; -+ u16 r; -+ -+ rtl_set_page(priv, page); -+ r = bus->read(bus, phy, reg); -+ r &= ~mask; -+ r |= val; -+ bus->write(bus, phy, reg, r); -+ return bus->read(bus, phy, reg); /* flush */ -+} -+ -+ -+static inline int -+rtl_get(struct switch_dev *dev, enum rtl_regidx s) -+{ -+ const struct rtl_reg *r = &rtl_regs[s]; -+ u16 val; -+ -+ BUG_ON(s >= ARRAY_SIZE(rtl_regs)); -+ if (r->bits == 0) /* unimplemented */ -+ return 0; -+ -+ val = rtl_r16(dev, r->page, r->phy, r->reg); -+ -+ if (r->shift > 0) -+ val >>= r->shift; -+ -+ if (r->inverted) -+ val = ~val; -+ -+ val &= (1 << r->bits) - 1; -+ -+ return val; -+} -+ -+static int -+rtl_set(struct switch_dev *dev, enum rtl_regidx s, unsigned int val) -+{ -+ const struct rtl_reg *r = &rtl_regs[s]; -+ u16 mask = 0xffff; -+ -+ BUG_ON(s >= ARRAY_SIZE(rtl_regs)); -+ -+ if (r->bits == 0) /* unimplemented */ -+ return 0; -+ -+ if (r->shift > 0) -+ val <<= r->shift; -+ -+ if (r->inverted) -+ val = ~val; -+ -+ if (r->bits != 16) { -+ mask = (1 << r->bits) - 1; -+ mask <<= r->shift; -+ } -+ val &= mask; -+ return rtl_rmw(dev, r->page, r->phy, r->reg, mask, val); -+} -+ -+static void -+rtl_phy_save(struct switch_dev *dev, int port, struct rtl_phyregs *regs) -+{ -+ regs->nway = rtl_get(dev, RTL_PORT_REG(port, NWAY)); -+ regs->speed = rtl_get(dev, RTL_PORT_REG(port, SPEED)); -+ regs->duplex = rtl_get(dev, RTL_PORT_REG(port, DUPLEX)); -+} -+ -+static void -+rtl_phy_restore(struct switch_dev *dev, int port, struct rtl_phyregs *regs) -+{ -+ rtl_set(dev, RTL_PORT_REG(port, NWAY), regs->nway); -+ rtl_set(dev, RTL_PORT_REG(port, SPEED), regs->speed); -+ rtl_set(dev, RTL_PORT_REG(port, DUPLEX), regs->duplex); -+} -+ -+static void -+rtl_port_set_enable(struct switch_dev *dev, int port, int enabled) -+{ -+ rtl_set(dev, RTL_PORT_REG(port, RXEN), enabled); -+ rtl_set(dev, RTL_PORT_REG(port, TXEN), enabled); -+ -+ if ((port >= 5) || !enabled) -+ return; -+ -+ /* restart autonegotiation if enabled */ -+ rtl_set(dev, RTL_PORT_REG(port, NRESTART), 1); -+} -+ -+static int -+rtl_hw_apply(struct switch_dev *dev) -+{ -+ int i; -+ int trunk_en, trunk_psel; -+ struct rtl_phyregs port5; -+ -+ rtl_phy_save(dev, 5, &port5); -+ -+ /* disable rx/tx from PHYs */ -+ for (i = 0; i < RTL8306_NUM_PORTS - 1; i++) { -+ rtl_port_set_enable(dev, i, 0); -+ } -+ -+ /* save trunking status */ -+ trunk_en = rtl_get(dev, RTL_REG_EN_TRUNK); -+ trunk_psel = rtl_get(dev, RTL_REG_TRUNK_PORTSEL); -+ -+ /* trunk port 3 and 4 -+ * XXX: Big WTF, but RealTek seems to do it */ -+ rtl_set(dev, RTL_REG_EN_TRUNK, 1); -+ rtl_set(dev, RTL_REG_TRUNK_PORTSEL, 1); -+ -+ /* execute the software reset */ -+ rtl_set(dev, RTL_REG_RESET, 1); -+ -+ /* wait for the reset to complete, -+ * but don't wait for too long */ -+ for (i = 0; i < 10; i++) { -+ if (rtl_get(dev, RTL_REG_RESET) == 0) -+ break; -+ -+ msleep(1); -+ } -+ -+ /* enable rx/tx from PHYs */ -+ for (i = 0; i < RTL8306_NUM_PORTS - 1; i++) { -+ rtl_port_set_enable(dev, i, 1); -+ } -+ -+ /* restore trunking settings */ -+ rtl_set(dev, RTL_REG_EN_TRUNK, trunk_en); -+ rtl_set(dev, RTL_REG_TRUNK_PORTSEL, trunk_psel); -+ rtl_phy_restore(dev, 5, &port5); -+ -+ rtl_set(dev, RTL_REG_CPU_LINKUP, 1); -+ -+ return 0; -+} -+ -+static void -+rtl_hw_init(struct switch_dev *dev) -+{ -+ struct rtl_priv *priv = to_rtl(dev); -+ int cpu_mask = 1 << dev->cpu_port; -+ int i; -+ -+ rtl_set(dev, RTL_REG_VLAN_ENABLE, 0); -+ rtl_set(dev, RTL_REG_VLAN_FILTER, 0); -+ rtl_set(dev, RTL_REG_EN_TRUNK, 0); -+ rtl_set(dev, RTL_REG_TRUNK_PORTSEL, 0); -+ -+ /* initialize cpu port settings */ -+ if (priv->do_cpu) { -+ rtl_set(dev, RTL_REG_CPUPORT, dev->cpu_port); -+ rtl_set(dev, RTL_REG_EN_CPUPORT, 1); -+ } else { -+ rtl_set(dev, RTL_REG_CPUPORT, 7); -+ rtl_set(dev, RTL_REG_EN_CPUPORT, 0); -+ } -+ rtl_set(dev, RTL_REG_EN_TAG_OUT, 0); -+ rtl_set(dev, RTL_REG_EN_TAG_IN, 0); -+ rtl_set(dev, RTL_REG_EN_TAG_CLR, 0); -+ -+ /* reset all vlans */ -+ for (i = 0; i < RTL8306_NUM_VLANS; i++) { -+ rtl_set(dev, RTL_VLAN_REG(i, VID), i); -+ rtl_set(dev, RTL_VLAN_REG(i, PORTMASK), 0); -+ } -+ -+ /* default to port isolation */ -+ for (i = 0; i < RTL8306_NUM_PORTS; i++) { -+ unsigned long mask; -+ -+ if ((1 << i) == cpu_mask) -+ mask = ((1 << RTL8306_NUM_PORTS) - 1) & ~cpu_mask; /* all bits set */ -+ else -+ mask = cpu_mask | (1 << i); -+ -+ rtl_set(dev, RTL_VLAN_REG(i, PORTMASK), mask); -+ rtl_set(dev, RTL_PORT_REG(i, PVID), i); -+ rtl_set(dev, RTL_PORT_REG(i, NULL_VID_REPLACE), 1); -+ rtl_set(dev, RTL_PORT_REG(i, VID_INSERT), 1); -+ rtl_set(dev, RTL_PORT_REG(i, TAG_INSERT), 3); -+ } -+ rtl_hw_apply(dev); -+} -+ -+#ifdef DEBUG -+static int -+rtl_set_use_cpuport(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ struct rtl_priv *priv = to_rtl(dev); -+ priv->do_cpu = val->value.i; -+ rtl_hw_init(dev); -+ return 0; -+} -+ -+static int -+rtl_get_use_cpuport(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ struct rtl_priv *priv = to_rtl(dev); -+ val->value.i = priv->do_cpu; -+ return 0; -+} -+ -+static int -+rtl_set_cpuport(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ dev->cpu_port = val->value.i; -+ rtl_hw_init(dev); -+ return 0; -+} -+ -+static int -+rtl_get_cpuport(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ val->value.i = dev->cpu_port; -+ return 0; -+} -+#endif -+ -+static int -+rtl_reset(struct switch_dev *dev) -+{ -+ rtl_hw_init(dev); -+ return 0; -+} -+ -+static int -+rtl_attr_set_int(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ int idx = attr->id + (val->port_vlan * attr->ofs); -+ struct rtl_phyregs port; -+ -+ if (attr->id >= ARRAY_SIZE(rtl_regs)) -+ return -EINVAL; -+ -+ if ((attr->max > 0) && (val->value.i > attr->max)) -+ return -EINVAL; -+ -+ /* access to phy register 22 on port 4/5 -+ * needs phy status save/restore */ -+ if ((val->port_vlan > 3) && -+ (rtl_regs[idx].reg == 22) && -+ (rtl_regs[idx].page == 0)) { -+ -+ rtl_phy_save(dev, val->port_vlan, &port); -+ rtl_set(dev, idx, val->value.i); -+ rtl_phy_restore(dev, val->port_vlan, &port); -+ } else { -+ rtl_set(dev, idx, val->value.i); -+ } -+ -+ return 0; -+} -+ -+static int -+rtl_attr_get_int(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ int idx = attr->id + (val->port_vlan * attr->ofs); -+ -+ if (idx >= ARRAY_SIZE(rtl_regs)) -+ return -EINVAL; -+ -+ val->value.i = rtl_get(dev, idx); -+ return 0; -+} -+ -+static int -+rtl_attr_set_port_int(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ if (val->port_vlan >= RTL8306_NUM_PORTS) -+ return -EINVAL; -+ -+ return rtl_attr_set_int(dev, attr, val); -+} -+ -+static int -+rtl_attr_get_port_int(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ if (val->port_vlan >= RTL8306_NUM_PORTS) -+ return -EINVAL; -+ return rtl_attr_get_int(dev, attr, val); -+} -+ -+static int -+rtl_get_port_link(struct switch_dev *dev, int port, struct switch_port_link *link) -+{ -+ if (port >= RTL8306_NUM_PORTS) -+ return -EINVAL; -+ -+ /* in case the link changes from down to up, the register is only updated on read */ -+ link->link = rtl_get(dev, RTL_PORT_REG(port, LINK)); -+ if (!link->link) -+ link->link = rtl_get(dev, RTL_PORT_REG(port, LINK)); -+ -+ if (!link->link) -+ return 0; -+ -+ link->duplex = rtl_get(dev, RTL_PORT_REG(port, DUPLEX)); -+ link->aneg = rtl_get(dev, RTL_PORT_REG(port, NWAY)); -+ -+ if (rtl_get(dev, RTL_PORT_REG(port, SPEED))) -+ link->speed = SWITCH_PORT_SPEED_100; -+ else -+ link->speed = SWITCH_PORT_SPEED_10; -+ -+ return 0; -+} -+ -+static int -+rtl_attr_set_vlan_int(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ if (val->port_vlan >= dev->vlans) -+ return -EINVAL; -+ -+ return rtl_attr_set_int(dev, attr, val); -+} -+ -+static int -+rtl_attr_get_vlan_int(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ if (val->port_vlan >= dev->vlans) -+ return -EINVAL; -+ -+ return rtl_attr_get_int(dev, attr, val); -+} -+ -+static int -+rtl_get_ports(struct switch_dev *dev, struct switch_val *val) -+{ -+ unsigned int i, mask; -+ -+ mask = rtl_get(dev, RTL_VLAN_REG(val->port_vlan, PORTMASK)); -+ for (i = 0; i < RTL8306_NUM_PORTS; i++) { -+ struct switch_port *port; -+ -+ if (!(mask & (1 << i))) -+ continue; -+ -+ port = &val->value.ports[val->len]; -+ port->id = i; -+ if (rtl_get(dev, RTL_PORT_REG(i, TAG_INSERT)) == 2 || i == dev->cpu_port) -+ port->flags = (1 << SWITCH_PORT_FLAG_TAGGED); -+ val->len++; -+ } -+ -+ return 0; -+} -+ -+static int -+rtl_set_vlan(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ struct rtl_priv *priv = to_rtl(dev); -+ struct rtl_phyregs port; -+ int en = val->value.i; -+ int i; -+ -+ rtl_set(dev, RTL_REG_EN_TAG_OUT, en && priv->do_cpu); -+ rtl_set(dev, RTL_REG_EN_TAG_IN, en && priv->do_cpu); -+ rtl_set(dev, RTL_REG_EN_TAG_CLR, en && priv->do_cpu); -+ rtl_set(dev, RTL_REG_VLAN_TAG_AWARE, en); -+ if (en) -+ rtl_set(dev, RTL_REG_VLAN_FILTER, en); -+ -+ for (i = 0; i < RTL8306_NUM_PORTS; i++) { -+ if (i > 3) -+ rtl_phy_save(dev, val->port_vlan, &port); -+ rtl_set(dev, RTL_PORT_REG(i, NULL_VID_REPLACE), 1); -+ rtl_set(dev, RTL_PORT_REG(i, VID_INSERT), (en ? (i == dev->cpu_port ? 0 : 1) : 1)); -+ rtl_set(dev, RTL_PORT_REG(i, TAG_INSERT), (en ? (i == dev->cpu_port ? 2 : 1) : 3)); -+ if (i > 3) -+ rtl_phy_restore(dev, val->port_vlan, &port); -+ } -+ rtl_set(dev, RTL_REG_VLAN_ENABLE, en); -+ -+ return 0; -+} -+ -+static int -+rtl_get_vlan(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) -+{ -+ val->value.i = rtl_get(dev, RTL_REG_VLAN_ENABLE); -+ return 0; -+} -+ -+static int -+rtl_set_ports(struct switch_dev *dev, struct switch_val *val) -+{ -+ unsigned int mask = 0; -+ unsigned int oldmask; -+ int i; -+ -+ for(i = 0; i < val->len; i++) -+ { -+ struct switch_port *port = &val->value.ports[i]; -+ bool tagged = false; -+ -+ mask |= (1 << port->id); -+ -+ if (port->id == dev->cpu_port) -+ continue; -+ -+ if ((i == dev->cpu_port) || -+ (port->flags & (1 << SWITCH_PORT_FLAG_TAGGED))) -+ tagged = true; -+ -+ /* fix up PVIDs for added ports */ -+ if (!tagged) -+ rtl_set(dev, RTL_PORT_REG(port->id, PVID), val->port_vlan); -+ -+ rtl_set(dev, RTL_PORT_REG(port->id, NON_PVID_DISCARD), (tagged ? 0 : 1)); -+ rtl_set(dev, RTL_PORT_REG(port->id, VID_INSERT), (tagged ? 0 : 1)); -+ rtl_set(dev, RTL_PORT_REG(port->id, TAG_INSERT), (tagged ? 2 : 1)); -+ } -+ -+ oldmask = rtl_get(dev, RTL_VLAN_REG(val->port_vlan, PORTMASK)); -+ rtl_set(dev, RTL_VLAN_REG(val->port_vlan, PORTMASK), mask); -+ -+ /* fix up PVIDs for removed ports, default to last vlan */ -+ oldmask &= ~mask; -+ for (i = 0; i < RTL8306_NUM_PORTS; i++) { -+ if (!(oldmask & (1 << i))) -+ continue; -+ -+ if (i == dev->cpu_port) -+ continue; -+ -+ if (rtl_get(dev, RTL_PORT_REG(i, PVID)) == val->port_vlan) -+ rtl_set(dev, RTL_PORT_REG(i, PVID), dev->vlans - 1); -+ } -+ -+ return 0; -+} -+ -+static struct switch_attr rtl_globals[] = { -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_vlan", -+ .description = "Enable VLAN mode", -+ .max = 1, -+ .set = rtl_set_vlan, -+ .get = rtl_get_vlan, -+ }, -+ { -+ RTL_GLOBAL_REGATTR(EN_TRUNK), -+ .name = "trunk", -+ .description = "Enable port trunking", -+ .max = 1, -+ }, -+ { -+ RTL_GLOBAL_REGATTR(TRUNK_PORTSEL), -+ .name = "trunk_sel", -+ .description = "Select ports for trunking (0: 0,1 - 1: 3,4)", -+ .max = 1, -+ }, -+#ifdef DEBUG -+ { -+ RTL_GLOBAL_REGATTR(VLAN_FILTER), -+ .name = "vlan_filter", -+ .description = "Filter incoming packets for allowed VLANS", -+ .max = 1, -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "cpuport", -+ .description = "CPU Port", -+ .set = rtl_set_cpuport, -+ .get = rtl_get_cpuport, -+ .max = RTL8306_NUM_PORTS, -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "use_cpuport", -+ .description = "CPU Port handling flag", -+ .set = rtl_set_use_cpuport, -+ .get = rtl_get_use_cpuport, -+ .max = RTL8306_NUM_PORTS, -+ }, -+ { -+ RTL_GLOBAL_REGATTR(TRAP_CPU), -+ .name = "trap_cpu", -+ .description = "VLAN trap to CPU", -+ .max = 1, -+ }, -+ { -+ RTL_GLOBAL_REGATTR(VLAN_TAG_AWARE), -+ .name = "vlan_tag_aware", -+ .description = "Enable VLAN tag awareness", -+ .max = 1, -+ }, -+ { -+ RTL_GLOBAL_REGATTR(VLAN_TAG_ONLY), -+ .name = "tag_only", -+ .description = "Only accept tagged packets", -+ .max = 1, -+ }, -+#endif -+}; -+static struct switch_attr rtl_port[] = { -+ { -+ RTL_PORT_REGATTR(PVID), -+ .name = "pvid", -+ .description = "Port VLAN ID", -+ .max = RTL8306_NUM_VLANS - 1, -+ }, -+#ifdef DEBUG -+ { -+ RTL_PORT_REGATTR(NULL_VID_REPLACE), -+ .name = "null_vid", -+ .description = "NULL VID gets replaced by port default vid", -+ .max = 1, -+ }, -+ { -+ RTL_PORT_REGATTR(NON_PVID_DISCARD), -+ .name = "non_pvid_discard", -+ .description = "discard packets with VID != PVID", -+ .max = 1, -+ }, -+ { -+ RTL_PORT_REGATTR(VID_INSERT), -+ .name = "vid_insert_remove", -+ .description = "how should the switch insert and remove vids ?", -+ .max = 3, -+ }, -+ { -+ RTL_PORT_REGATTR(TAG_INSERT), -+ .name = "tag_insert", -+ .description = "tag insertion handling", -+ .max = 3, -+ }, -+#endif -+}; -+ -+static struct switch_attr rtl_vlan[] = { -+ { -+ RTL_VLAN_REGATTR(VID), -+ .name = "vid", -+ .description = "VLAN ID (1-4095)", -+ .max = 4095, -+ }, -+}; -+ -+static const struct switch_dev_ops rtl8306_ops = { -+ .attr_global = { -+ .attr = rtl_globals, -+ .n_attr = ARRAY_SIZE(rtl_globals), -+ }, -+ .attr_port = { -+ .attr = rtl_port, -+ .n_attr = ARRAY_SIZE(rtl_port), -+ }, -+ .attr_vlan = { -+ .attr = rtl_vlan, -+ .n_attr = ARRAY_SIZE(rtl_vlan), -+ }, -+ -+ .get_vlan_ports = rtl_get_ports, -+ .set_vlan_ports = rtl_set_ports, -+ .apply_config = rtl_hw_apply, -+ .reset_switch = rtl_reset, -+ .get_port_link = rtl_get_port_link, -+}; -+ -+static int -+rtl8306_config_init(struct phy_device *pdev) -+{ -+ struct net_device *netdev = pdev->attached_dev; -+ struct rtl_priv *priv = pdev->priv; -+ struct switch_dev *dev = &priv->dev; -+ struct switch_val val; -+ unsigned int chipid, chipver, chiptype; -+ int err; -+ -+ /* Only init the switch for the primary PHY */ -+ if (pdev->mdio.addr != 0) -+ return 0; -+ -+ val.value.i = 1; -+ priv->dev.cpu_port = RTL8306_PORT_CPU; -+ priv->dev.ports = RTL8306_NUM_PORTS; -+ priv->dev.vlans = RTL8306_NUM_VLANS; -+ priv->dev.ops = &rtl8306_ops; -+ priv->do_cpu = 0; -+ priv->page = -1; -+ priv->bus = pdev->mdio.bus; -+ -+ chipid = rtl_get(dev, RTL_REG_CHIPID); -+ chipver = rtl_get(dev, RTL_REG_CHIPVER); -+ chiptype = rtl_get(dev, RTL_REG_CHIPTYPE); -+ switch(chiptype) { -+ case 0: -+ case 2: -+ strncpy(priv->hwname, RTL_NAME_S, sizeof(priv->hwname)); -+ priv->type = RTL_TYPE_S; -+ break; -+ case 1: -+ strncpy(priv->hwname, RTL_NAME_SD, sizeof(priv->hwname)); -+ priv->type = RTL_TYPE_SD; -+ break; -+ case 3: -+ strncpy(priv->hwname, RTL_NAME_SDM, sizeof(priv->hwname)); -+ priv->type = RTL_TYPE_SDM; -+ break; -+ default: -+ strncpy(priv->hwname, RTL_NAME_UNKNOWN, sizeof(priv->hwname)); -+ break; -+ } -+ -+ dev->name = priv->hwname; -+ rtl_hw_init(dev); -+ -+ printk(KERN_INFO "Registering %s switch with Chip ID: 0x%04x, version: 0x%04x\n", priv->hwname, chipid, chipver); -+ -+ err = register_switch(dev, netdev); -+ if (err < 0) { -+ kfree(priv); -+ return err; -+ } -+ -+ return 0; -+} -+ -+ -+static int -+rtl8306_fixup(struct phy_device *pdev) -+{ -+ struct rtl_priv priv; -+ u16 chipid; -+ -+ /* Attach to primary LAN port and WAN port */ -+ if (pdev->mdio.addr != 0 && pdev->mdio.addr != 4) -+ return 0; -+ -+ memset(&priv, 0, sizeof(priv)); -+ priv.fixup = true; -+ priv.page = -1; -+ priv.bus = pdev->mdio.bus; -+ chipid = rtl_get(&priv.dev, RTL_REG_CHIPID); -+ if (chipid == 0x5988) -+ pdev->phy_id = RTL8306_MAGIC; -+ -+ return 0; -+} -+ -+static int -+rtl8306_probe(struct phy_device *pdev) -+{ -+ struct rtl_priv *priv; -+ -+ list_for_each_entry(priv, &phydevs, list) { -+ /* -+ * share one rtl_priv instance between virtual phy -+ * devices on the same bus -+ */ -+ if (priv->bus == pdev->mdio.bus) -+ goto found; -+ } -+ priv = kzalloc(sizeof(struct rtl_priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->bus = pdev->mdio.bus; -+ -+found: -+ pdev->priv = priv; -+ return 0; -+} -+ -+static void -+rtl8306_remove(struct phy_device *pdev) -+{ -+ struct rtl_priv *priv = pdev->priv; -+ unregister_switch(&priv->dev); -+ kfree(priv); -+} -+ -+static int -+rtl8306_config_aneg(struct phy_device *pdev) -+{ -+ struct rtl_priv *priv = pdev->priv; -+ -+ /* Only for WAN */ -+ if (pdev->mdio.addr == 0) -+ return 0; -+ -+ /* Restart autonegotiation */ -+ rtl_set(&priv->dev, RTL_PORT_REG(4, NWAY), 1); -+ rtl_set(&priv->dev, RTL_PORT_REG(4, NRESTART), 1); -+ -+ return 0; -+} -+ -+static int -+rtl8306_read_status(struct phy_device *pdev) -+{ -+ struct rtl_priv *priv = pdev->priv; -+ struct switch_dev *dev = &priv->dev; -+ -+ if (pdev->mdio.addr == 4) { -+ /* WAN */ -+ pdev->speed = rtl_get(dev, RTL_PORT_REG(4, SPEED)) ? SPEED_100 : SPEED_10; -+ pdev->duplex = rtl_get(dev, RTL_PORT_REG(4, DUPLEX)) ? DUPLEX_FULL : DUPLEX_HALF; -+ pdev->link = !!rtl_get(dev, RTL_PORT_REG(4, LINK)); -+ } else { -+ /* LAN */ -+ pdev->speed = SPEED_100; -+ pdev->duplex = DUPLEX_FULL; -+ pdev->link = 1; -+ } -+ -+ /* -+ * Bypass generic PHY status read, -+ * it doesn't work with this switch -+ */ -+ if (pdev->link) { -+ pdev->state = PHY_RUNNING; -+ netif_carrier_on(pdev->attached_dev); -+ pdev->adjust_link(pdev->attached_dev); -+ } else { -+ pdev->state = PHY_NOLINK; -+ netif_carrier_off(pdev->attached_dev); -+ pdev->adjust_link(pdev->attached_dev); -+ } -+ -+ return 0; -+} -+ -+ -+static struct phy_driver rtl8306_driver = { -+ .name = "Realtek RTL8306S", -+ .phy_id = RTL8306_MAGIC, -+ .phy_id_mask = 0xffffffff, -+ .features = PHY_BASIC_FEATURES, -+ .probe = &rtl8306_probe, -+ .remove = &rtl8306_remove, -+ .config_init = &rtl8306_config_init, -+ .config_aneg = &rtl8306_config_aneg, -+ .read_status = &rtl8306_read_status, -+}; -+ -+ -+static int __init -+rtl_init(void) -+{ -+ phy_register_fixup_for_id(PHY_ANY_ID, rtl8306_fixup); -+ return phy_driver_register(&rtl8306_driver, THIS_MODULE); -+} -+ -+static void __exit -+rtl_exit(void) -+{ -+ phy_driver_unregister(&rtl8306_driver); -+} -+ -+module_init(rtl_init); -+module_exit(rtl_exit); -+MODULE_LICENSE("GPL"); -+ -diff --git a/drivers/net/phy/rtl8366_smi.c b/drivers/net/phy/rtl8366_smi.c -new file mode 100644 -index 000000000000..89fc04fa64d7 ---- /dev/null -+++ b/drivers/net/phy/rtl8366_smi.c -@@ -0,0 +1,1625 @@ -+/* -+ * Realtek RTL8366 SMI interface driver -+ * -+ * Copyright (C) 2009-2010 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_RTL8366_SMI_DEBUG_FS -+#include -+#endif -+ -+#include "rtl8366_smi.h" -+ -+#define RTL8366_SMI_ACK_RETRY_COUNT 5 -+ -+#define RTL8366_SMI_HW_STOP_DELAY 25 /* msecs */ -+#define RTL8366_SMI_HW_START_DELAY 100 /* msecs */ -+ -+static inline void rtl8366_smi_clk_delay(struct rtl8366_smi *smi) -+{ -+ ndelay(smi->clk_delay); -+} -+ -+static void rtl8366_smi_start(struct rtl8366_smi *smi) -+{ -+ unsigned int sda = smi->gpio_sda; -+ unsigned int sck = smi->gpio_sck; -+ -+ /* -+ * Set GPIO pins to output mode, with initial state: -+ * SCK = 0, SDA = 1 -+ */ -+ gpio_direction_output(sck, 0); -+ gpio_direction_output(sda, 1); -+ rtl8366_smi_clk_delay(smi); -+ -+ /* CLK 1: 0 -> 1, 1 -> 0 */ -+ gpio_set_value(sck, 1); -+ rtl8366_smi_clk_delay(smi); -+ gpio_set_value(sck, 0); -+ rtl8366_smi_clk_delay(smi); -+ -+ /* CLK 2: */ -+ gpio_set_value(sck, 1); -+ rtl8366_smi_clk_delay(smi); -+ gpio_set_value(sda, 0); -+ rtl8366_smi_clk_delay(smi); -+ gpio_set_value(sck, 0); -+ rtl8366_smi_clk_delay(smi); -+ gpio_set_value(sda, 1); -+} -+ -+static void rtl8366_smi_stop(struct rtl8366_smi *smi) -+{ -+ unsigned int sda = smi->gpio_sda; -+ unsigned int sck = smi->gpio_sck; -+ -+ rtl8366_smi_clk_delay(smi); -+ gpio_set_value(sda, 0); -+ gpio_set_value(sck, 1); -+ rtl8366_smi_clk_delay(smi); -+ gpio_set_value(sda, 1); -+ rtl8366_smi_clk_delay(smi); -+ gpio_set_value(sck, 1); -+ rtl8366_smi_clk_delay(smi); -+ gpio_set_value(sck, 0); -+ rtl8366_smi_clk_delay(smi); -+ gpio_set_value(sck, 1); -+ -+ /* add a click */ -+ rtl8366_smi_clk_delay(smi); -+ gpio_set_value(sck, 0); -+ rtl8366_smi_clk_delay(smi); -+ gpio_set_value(sck, 1); -+ -+ /* set GPIO pins to input mode */ -+ gpio_direction_input(sda); -+ gpio_direction_input(sck); -+} -+ -+static void rtl8366_smi_write_bits(struct rtl8366_smi *smi, u32 data, u32 len) -+{ -+ unsigned int sda = smi->gpio_sda; -+ unsigned int sck = smi->gpio_sck; -+ -+ for (; len > 0; len--) { -+ rtl8366_smi_clk_delay(smi); -+ -+ /* prepare data */ -+ gpio_set_value(sda, !!(data & ( 1 << (len - 1)))); -+ rtl8366_smi_clk_delay(smi); -+ -+ /* clocking */ -+ gpio_set_value(sck, 1); -+ rtl8366_smi_clk_delay(smi); -+ gpio_set_value(sck, 0); -+ } -+} -+ -+static void rtl8366_smi_read_bits(struct rtl8366_smi *smi, u32 len, u32 *data) -+{ -+ unsigned int sda = smi->gpio_sda; -+ unsigned int sck = smi->gpio_sck; -+ -+ gpio_direction_input(sda); -+ -+ for (*data = 0; len > 0; len--) { -+ u32 u; -+ -+ rtl8366_smi_clk_delay(smi); -+ -+ /* clocking */ -+ gpio_set_value(sck, 1); -+ rtl8366_smi_clk_delay(smi); -+ u = !!gpio_get_value(sda); -+ gpio_set_value(sck, 0); -+ -+ *data |= (u << (len - 1)); -+ } -+ -+ gpio_direction_output(sda, 0); -+} -+ -+static int rtl8366_smi_wait_for_ack(struct rtl8366_smi *smi) -+{ -+ int retry_cnt; -+ -+ retry_cnt = 0; -+ do { -+ u32 ack; -+ -+ rtl8366_smi_read_bits(smi, 1, &ack); -+ if (ack == 0) -+ break; -+ -+ if (++retry_cnt > RTL8366_SMI_ACK_RETRY_COUNT) { -+ dev_err(smi->parent, "ACK timeout\n"); -+ return -ETIMEDOUT; -+ } -+ } while (1); -+ -+ return 0; -+} -+ -+static int rtl8366_smi_write_byte(struct rtl8366_smi *smi, u8 data) -+{ -+ rtl8366_smi_write_bits(smi, data, 8); -+ return rtl8366_smi_wait_for_ack(smi); -+} -+ -+static int rtl8366_smi_write_byte_noack(struct rtl8366_smi *smi, u8 data) -+{ -+ rtl8366_smi_write_bits(smi, data, 8); -+ return 0; -+} -+ -+static int rtl8366_smi_read_byte0(struct rtl8366_smi *smi, u8 *data) -+{ -+ u32 t; -+ -+ /* read data */ -+ rtl8366_smi_read_bits(smi, 8, &t); -+ *data = (t & 0xff); -+ -+ /* send an ACK */ -+ rtl8366_smi_write_bits(smi, 0x00, 1); -+ -+ return 0; -+} -+ -+static int rtl8366_smi_read_byte1(struct rtl8366_smi *smi, u8 *data) -+{ -+ u32 t; -+ -+ /* read data */ -+ rtl8366_smi_read_bits(smi, 8, &t); -+ *data = (t & 0xff); -+ -+ /* send an ACK */ -+ rtl8366_smi_write_bits(smi, 0x01, 1); -+ -+ return 0; -+} -+ -+static int __rtl8366_smi_read_reg(struct rtl8366_smi *smi, u32 addr, u32 *data) -+{ -+ unsigned long flags; -+ u8 lo = 0; -+ u8 hi = 0; -+ int ret; -+ -+ spin_lock_irqsave(&smi->lock, flags); -+ -+ rtl8366_smi_start(smi); -+ -+ /* send READ command */ -+ ret = rtl8366_smi_write_byte(smi, smi->cmd_read); -+ if (ret) -+ goto out; -+ -+ /* set ADDR[7:0] */ -+ ret = rtl8366_smi_write_byte(smi, addr & 0xff); -+ if (ret) -+ goto out; -+ -+ /* set ADDR[15:8] */ -+ ret = rtl8366_smi_write_byte(smi, addr >> 8); -+ if (ret) -+ goto out; -+ -+ /* read DATA[7:0] */ -+ rtl8366_smi_read_byte0(smi, &lo); -+ /* read DATA[15:8] */ -+ rtl8366_smi_read_byte1(smi, &hi); -+ -+ *data = ((u32) lo) | (((u32) hi) << 8); -+ -+ ret = 0; -+ -+ out: -+ rtl8366_smi_stop(smi); -+ spin_unlock_irqrestore(&smi->lock, flags); -+ -+ return ret; -+} -+/* Read/write via mdiobus */ -+#define MDC_MDIO_CTRL0_REG 31 -+#define MDC_MDIO_START_REG 29 -+#define MDC_MDIO_CTRL1_REG 21 -+#define MDC_MDIO_ADDRESS_REG 23 -+#define MDC_MDIO_DATA_WRITE_REG 24 -+#define MDC_MDIO_DATA_READ_REG 25 -+ -+#define MDC_MDIO_START_OP 0xFFFF -+#define MDC_MDIO_ADDR_OP 0x000E -+#define MDC_MDIO_READ_OP 0x0001 -+#define MDC_MDIO_WRITE_OP 0x0003 -+#define MDC_REALTEK_PHY_ADDR 0x0 -+ -+static int __rtl8366_mdio_read_reg(struct rtl8366_smi *smi, u32 addr, u32 *data) -+{ -+ u32 phy_id = smi->phy_id; -+ struct mii_bus *mbus = smi->ext_mbus; -+ -+ BUG_ON(in_interrupt()); -+ -+ mutex_lock(&mbus->mdio_lock); -+ /* Write Start command to register 29 */ -+ mbus->write(mbus, phy_id, MDC_MDIO_START_REG, MDC_MDIO_START_OP); -+ -+ /* Write address control code to register 31 */ -+ mbus->write(mbus, phy_id, MDC_MDIO_CTRL0_REG, MDC_MDIO_ADDR_OP); -+ -+ /* Write Start command to register 29 */ -+ mbus->write(mbus, phy_id, MDC_MDIO_START_REG, MDC_MDIO_START_OP); -+ -+ /* Write address to register 23 */ -+ mbus->write(mbus, phy_id, MDC_MDIO_ADDRESS_REG, addr); -+ -+ /* Write Start command to register 29 */ -+ mbus->write(mbus, phy_id, MDC_MDIO_START_REG, MDC_MDIO_START_OP); -+ -+ /* Write read control code to register 21 */ -+ mbus->write(mbus, phy_id, MDC_MDIO_CTRL1_REG, MDC_MDIO_READ_OP); -+ -+ /* Write Start command to register 29 */ -+ mbus->write(smi->ext_mbus, phy_id, MDC_MDIO_START_REG, MDC_MDIO_START_OP); -+ -+ /* Read data from register 25 */ -+ *data = mbus->read(mbus, phy_id, MDC_MDIO_DATA_READ_REG); -+ -+ mutex_unlock(&mbus->mdio_lock); -+ -+ return 0; -+} -+ -+static int __rtl8366_mdio_write_reg(struct rtl8366_smi *smi, u32 addr, u32 data) -+{ -+ u32 phy_id = smi->phy_id; -+ struct mii_bus *mbus = smi->ext_mbus; -+ -+ BUG_ON(in_interrupt()); -+ -+ mutex_lock(&mbus->mdio_lock); -+ -+ /* Write Start command to register 29 */ -+ mbus->write(mbus, phy_id, MDC_MDIO_START_REG, MDC_MDIO_START_OP); -+ -+ /* Write address control code to register 31 */ -+ mbus->write(mbus, phy_id, MDC_MDIO_CTRL0_REG, MDC_MDIO_ADDR_OP); -+ -+ /* Write Start command to register 29 */ -+ mbus->write(mbus, phy_id, MDC_MDIO_START_REG, MDC_MDIO_START_OP); -+ -+ /* Write address to register 23 */ -+ mbus->write(mbus, phy_id, MDC_MDIO_ADDRESS_REG, addr); -+ -+ /* Write Start command to register 29 */ -+ mbus->write(mbus, phy_id, MDC_MDIO_START_REG, MDC_MDIO_START_OP); -+ -+ /* Write data to register 24 */ -+ mbus->write(mbus, phy_id, MDC_MDIO_DATA_WRITE_REG, data); -+ -+ /* Write Start command to register 29 */ -+ mbus->write(mbus, phy_id, MDC_MDIO_START_REG, MDC_MDIO_START_OP); -+ -+ /* Write data control code to register 21 */ -+ mbus->write(mbus, phy_id, MDC_MDIO_CTRL1_REG, MDC_MDIO_WRITE_OP); -+ -+ mutex_unlock(&mbus->mdio_lock); -+ return 0; -+} -+ -+int rtl8366_smi_read_reg(struct rtl8366_smi *smi, u32 addr, u32 *data) -+{ -+ if (smi->ext_mbus) -+ return __rtl8366_mdio_read_reg(smi, addr, data); -+ else -+ return __rtl8366_smi_read_reg(smi, addr, data); -+} -+EXPORT_SYMBOL_GPL(rtl8366_smi_read_reg); -+ -+static int __rtl8366_smi_write_reg(struct rtl8366_smi *smi, -+ u32 addr, u32 data, bool ack) -+{ -+ unsigned long flags; -+ int ret; -+ -+ spin_lock_irqsave(&smi->lock, flags); -+ -+ rtl8366_smi_start(smi); -+ -+ /* send WRITE command */ -+ ret = rtl8366_smi_write_byte(smi, smi->cmd_write); -+ if (ret) -+ goto out; -+ -+ /* set ADDR[7:0] */ -+ ret = rtl8366_smi_write_byte(smi, addr & 0xff); -+ if (ret) -+ goto out; -+ -+ /* set ADDR[15:8] */ -+ ret = rtl8366_smi_write_byte(smi, addr >> 8); -+ if (ret) -+ goto out; -+ -+ /* write DATA[7:0] */ -+ ret = rtl8366_smi_write_byte(smi, data & 0xff); -+ if (ret) -+ goto out; -+ -+ /* write DATA[15:8] */ -+ if (ack) -+ ret = rtl8366_smi_write_byte(smi, data >> 8); -+ else -+ ret = rtl8366_smi_write_byte_noack(smi, data >> 8); -+ if (ret) -+ goto out; -+ -+ ret = 0; -+ -+ out: -+ rtl8366_smi_stop(smi); -+ spin_unlock_irqrestore(&smi->lock, flags); -+ -+ return ret; -+} -+ -+int rtl8366_smi_write_reg(struct rtl8366_smi *smi, u32 addr, u32 data) -+{ -+ if (smi->ext_mbus) -+ return __rtl8366_mdio_write_reg(smi, addr, data); -+ else -+ return __rtl8366_smi_write_reg(smi, addr, data, true); -+} -+EXPORT_SYMBOL_GPL(rtl8366_smi_write_reg); -+ -+int rtl8366_smi_write_reg_noack(struct rtl8366_smi *smi, u32 addr, u32 data) -+{ -+ return __rtl8366_smi_write_reg(smi, addr, data, false); -+} -+EXPORT_SYMBOL_GPL(rtl8366_smi_write_reg_noack); -+ -+int rtl8366_smi_rmwr(struct rtl8366_smi *smi, u32 addr, u32 mask, u32 data) -+{ -+ u32 t; -+ int err; -+ -+ err = rtl8366_smi_read_reg(smi, addr, &t); -+ if (err) -+ return err; -+ -+ err = rtl8366_smi_write_reg(smi, addr, (t & ~mask) | data); -+ return err; -+ -+} -+EXPORT_SYMBOL_GPL(rtl8366_smi_rmwr); -+ -+static int rtl8366_reset(struct rtl8366_smi *smi) -+{ -+ if (smi->hw_reset) { -+ smi->hw_reset(smi, true); -+ msleep(RTL8366_SMI_HW_STOP_DELAY); -+ smi->hw_reset(smi, false); -+ msleep(RTL8366_SMI_HW_START_DELAY); -+ return 0; -+ } -+ -+ return smi->ops->reset_chip(smi); -+} -+ -+static int rtl8366_mc_is_used(struct rtl8366_smi *smi, int mc_index, int *used) -+{ -+ int err; -+ int i; -+ -+ *used = 0; -+ for (i = 0; i < smi->num_ports; i++) { -+ int index = 0; -+ -+ err = smi->ops->get_mc_index(smi, i, &index); -+ if (err) -+ return err; -+ -+ if (mc_index == index) { -+ *used = 1; -+ break; -+ } -+ } -+ -+ return 0; -+} -+ -+static int rtl8366_set_vlan(struct rtl8366_smi *smi, int vid, u32 member, -+ u32 untag, u32 fid) -+{ -+ struct rtl8366_vlan_4k vlan4k; -+ int err; -+ int i; -+ -+ /* Update the 4K table */ -+ err = smi->ops->get_vlan_4k(smi, vid, &vlan4k); -+ if (err) -+ return err; -+ -+ vlan4k.member = member; -+ vlan4k.untag = untag; -+ vlan4k.fid = fid; -+ err = smi->ops->set_vlan_4k(smi, &vlan4k); -+ if (err) -+ return err; -+ -+ /* Try to find an existing MC entry for this VID */ -+ for (i = 0; i < smi->num_vlan_mc; i++) { -+ struct rtl8366_vlan_mc vlanmc; -+ -+ err = smi->ops->get_vlan_mc(smi, i, &vlanmc); -+ if (err) -+ return err; -+ -+ if (vid == vlanmc.vid) { -+ /* update the MC entry */ -+ vlanmc.member = member; -+ vlanmc.untag = untag; -+ vlanmc.fid = fid; -+ -+ err = smi->ops->set_vlan_mc(smi, i, &vlanmc); -+ break; -+ } -+ } -+ -+ return err; -+} -+ -+static int rtl8366_get_pvid(struct rtl8366_smi *smi, int port, int *val) -+{ -+ struct rtl8366_vlan_mc vlanmc; -+ int err; -+ int index; -+ -+ err = smi->ops->get_mc_index(smi, port, &index); -+ if (err) -+ return err; -+ -+ err = smi->ops->get_vlan_mc(smi, index, &vlanmc); -+ if (err) -+ return err; -+ -+ *val = vlanmc.vid; -+ return 0; -+} -+ -+static int rtl8366_set_pvid(struct rtl8366_smi *smi, unsigned port, -+ unsigned vid) -+{ -+ struct rtl8366_vlan_mc vlanmc; -+ struct rtl8366_vlan_4k vlan4k; -+ int err; -+ int i; -+ -+ /* Try to find an existing MC entry for this VID */ -+ for (i = 0; i < smi->num_vlan_mc; i++) { -+ err = smi->ops->get_vlan_mc(smi, i, &vlanmc); -+ if (err) -+ return err; -+ -+ if (vid == vlanmc.vid) { -+ err = smi->ops->set_vlan_mc(smi, i, &vlanmc); -+ if (err) -+ return err; -+ -+ err = smi->ops->set_mc_index(smi, port, i); -+ return err; -+ } -+ } -+ -+ /* We have no MC entry for this VID, try to find an empty one */ -+ for (i = 0; i < smi->num_vlan_mc; i++) { -+ err = smi->ops->get_vlan_mc(smi, i, &vlanmc); -+ if (err) -+ return err; -+ -+ if (vlanmc.vid == 0 && vlanmc.member == 0) { -+ /* Update the entry from the 4K table */ -+ err = smi->ops->get_vlan_4k(smi, vid, &vlan4k); -+ if (err) -+ return err; -+ -+ vlanmc.vid = vid; -+ vlanmc.member = vlan4k.member; -+ vlanmc.untag = vlan4k.untag; -+ vlanmc.fid = vlan4k.fid; -+ err = smi->ops->set_vlan_mc(smi, i, &vlanmc); -+ if (err) -+ return err; -+ -+ err = smi->ops->set_mc_index(smi, port, i); -+ return err; -+ } -+ } -+ -+ /* MC table is full, try to find an unused entry and replace it */ -+ for (i = 0; i < smi->num_vlan_mc; i++) { -+ int used; -+ -+ err = rtl8366_mc_is_used(smi, i, &used); -+ if (err) -+ return err; -+ -+ if (!used) { -+ /* Update the entry from the 4K table */ -+ err = smi->ops->get_vlan_4k(smi, vid, &vlan4k); -+ if (err) -+ return err; -+ -+ vlanmc.vid = vid; -+ vlanmc.member = vlan4k.member; -+ vlanmc.untag = vlan4k.untag; -+ vlanmc.fid = vlan4k.fid; -+ err = smi->ops->set_vlan_mc(smi, i, &vlanmc); -+ if (err) -+ return err; -+ -+ err = smi->ops->set_mc_index(smi, port, i); -+ return err; -+ } -+ } -+ -+ dev_err(smi->parent, -+ "all VLAN member configurations are in use\n"); -+ -+ return -ENOSPC; -+} -+ -+static int rtl8366_smi_enable_vlan(struct rtl8366_smi *smi, int enable) -+{ -+ int err; -+ -+ err = smi->ops->enable_vlan(smi, enable); -+ if (err) -+ return err; -+ -+ smi->vlan_enabled = enable; -+ -+ if (!enable) { -+ smi->vlan4k_enabled = 0; -+ err = smi->ops->enable_vlan4k(smi, enable); -+ } -+ -+ return err; -+} -+ -+static int rtl8366_smi_enable_vlan4k(struct rtl8366_smi *smi, int enable) -+{ -+ int err; -+ -+ if (enable) { -+ err = smi->ops->enable_vlan(smi, enable); -+ if (err) -+ return err; -+ -+ smi->vlan_enabled = enable; -+ } -+ -+ err = smi->ops->enable_vlan4k(smi, enable); -+ if (err) -+ return err; -+ -+ smi->vlan4k_enabled = enable; -+ return 0; -+} -+ -+static int rtl8366_smi_enable_all_ports(struct rtl8366_smi *smi, int enable) -+{ -+ int port; -+ int err; -+ -+ for (port = 0; port < smi->num_ports; port++) { -+ err = smi->ops->enable_port(smi, port, enable); -+ if (err) -+ return err; -+ } -+ -+ return 0; -+} -+ -+static int rtl8366_smi_reset_vlan(struct rtl8366_smi *smi) -+{ -+ struct rtl8366_vlan_mc vlanmc; -+ int err; -+ int i; -+ -+ rtl8366_smi_enable_vlan(smi, 0); -+ rtl8366_smi_enable_vlan4k(smi, 0); -+ -+ /* clear VLAN member configurations */ -+ vlanmc.vid = 0; -+ vlanmc.priority = 0; -+ vlanmc.member = 0; -+ vlanmc.untag = 0; -+ vlanmc.fid = 0; -+ for (i = 0; i < smi->num_vlan_mc; i++) { -+ err = smi->ops->set_vlan_mc(smi, i, &vlanmc); -+ if (err) -+ return err; -+ } -+ -+ return 0; -+} -+ -+static int rtl8366_init_vlan(struct rtl8366_smi *smi) -+{ -+ int port; -+ int err; -+ -+ err = rtl8366_smi_reset_vlan(smi); -+ if (err) -+ return err; -+ -+ for (port = 0; port < smi->num_ports; port++) { -+ u32 mask; -+ -+ if (port == smi->cpu_port) -+ mask = (1 << smi->num_ports) - 1; -+ else -+ mask = (1 << port) | (1 << smi->cpu_port); -+ -+ err = rtl8366_set_vlan(smi, (port + 1), mask, mask, 0); -+ if (err) -+ return err; -+ -+ err = rtl8366_set_pvid(smi, port, (port + 1)); -+ if (err) -+ return err; -+ } -+ -+ return rtl8366_smi_enable_vlan(smi, 1); -+} -+ -+#ifdef CONFIG_RTL8366_SMI_DEBUG_FS -+int rtl8366_debugfs_open(struct inode *inode, struct file *file) -+{ -+ file->private_data = inode->i_private; -+ return 0; -+} -+EXPORT_SYMBOL_GPL(rtl8366_debugfs_open); -+ -+static ssize_t rtl8366_read_debugfs_vlan_mc(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rtl8366_smi *smi = (struct rtl8366_smi *)file->private_data; -+ int i, len = 0; -+ char *buf = smi->buf; -+ -+ len += snprintf(buf + len, sizeof(smi->buf) - len, -+ "%2s %6s %4s %6s %6s %3s\n", -+ "id", "vid","prio", "member", "untag", "fid"); -+ -+ for (i = 0; i < smi->num_vlan_mc; ++i) { -+ struct rtl8366_vlan_mc vlanmc; -+ -+ smi->ops->get_vlan_mc(smi, i, &vlanmc); -+ -+ len += snprintf(buf + len, sizeof(smi->buf) - len, -+ "%2d %6d %4d 0x%04x 0x%04x %3d\n", -+ i, vlanmc.vid, vlanmc.priority, -+ vlanmc.member, vlanmc.untag, vlanmc.fid); -+ } -+ -+ return simple_read_from_buffer(user_buf, count, ppos, buf, len); -+} -+ -+#define RTL8366_VLAN4K_PAGE_SIZE 64 -+#define RTL8366_VLAN4K_NUM_PAGES (4096 / RTL8366_VLAN4K_PAGE_SIZE) -+ -+static ssize_t rtl8366_read_debugfs_vlan_4k(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rtl8366_smi *smi = (struct rtl8366_smi *)file->private_data; -+ int i, len = 0; -+ int offset; -+ char *buf = smi->buf; -+ -+ if (smi->dbg_vlan_4k_page >= RTL8366_VLAN4K_NUM_PAGES) { -+ len += snprintf(buf + len, sizeof(smi->buf) - len, -+ "invalid page: %u\n", smi->dbg_vlan_4k_page); -+ return simple_read_from_buffer(user_buf, count, ppos, buf, len); -+ } -+ -+ len += snprintf(buf + len, sizeof(smi->buf) - len, -+ "%4s %6s %6s %3s\n", -+ "vid", "member", "untag", "fid"); -+ -+ offset = RTL8366_VLAN4K_PAGE_SIZE * smi->dbg_vlan_4k_page; -+ for (i = 0; i < RTL8366_VLAN4K_PAGE_SIZE; i++) { -+ struct rtl8366_vlan_4k vlan4k; -+ -+ smi->ops->get_vlan_4k(smi, offset + i, &vlan4k); -+ -+ len += snprintf(buf + len, sizeof(smi->buf) - len, -+ "%4d 0x%04x 0x%04x %3d\n", -+ vlan4k.vid, vlan4k.member, -+ vlan4k.untag, vlan4k.fid); -+ } -+ -+ return simple_read_from_buffer(user_buf, count, ppos, buf, len); -+} -+ -+static ssize_t rtl8366_read_debugfs_pvid(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rtl8366_smi *smi = (struct rtl8366_smi *)file->private_data; -+ char *buf = smi->buf; -+ int len = 0; -+ int i; -+ -+ len += snprintf(buf + len, sizeof(smi->buf) - len, "%4s %4s\n", -+ "port", "pvid"); -+ -+ for (i = 0; i < smi->num_ports; i++) { -+ int pvid; -+ int err; -+ -+ err = rtl8366_get_pvid(smi, i, &pvid); -+ if (err) -+ len += snprintf(buf + len, sizeof(smi->buf) - len, -+ "%4d error\n", i); -+ else -+ len += snprintf(buf + len, sizeof(smi->buf) - len, -+ "%4d %4d\n", i, pvid); -+ } -+ -+ return simple_read_from_buffer(user_buf, count, ppos, buf, len); -+} -+ -+static ssize_t rtl8366_read_debugfs_reg(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rtl8366_smi *smi = (struct rtl8366_smi *)file->private_data; -+ u32 t, reg = smi->dbg_reg; -+ int err, len = 0; -+ char *buf = smi->buf; -+ -+ memset(buf, '\0', sizeof(smi->buf)); -+ -+ err = rtl8366_smi_read_reg(smi, reg, &t); -+ if (err) { -+ len += snprintf(buf, sizeof(smi->buf), -+ "Read failed (reg: 0x%04x)\n", reg); -+ return simple_read_from_buffer(user_buf, count, ppos, buf, len); -+ } -+ -+ len += snprintf(buf, sizeof(smi->buf), "reg = 0x%04x, val = 0x%04x\n", -+ reg, t); -+ -+ return simple_read_from_buffer(user_buf, count, ppos, buf, len); -+} -+ -+static ssize_t rtl8366_write_debugfs_reg(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rtl8366_smi *smi = (struct rtl8366_smi *)file->private_data; -+ unsigned long data; -+ u32 reg = smi->dbg_reg; -+ int err; -+ size_t len; -+ char *buf = smi->buf; -+ -+ len = min(count, sizeof(smi->buf) - 1); -+ if (copy_from_user(buf, user_buf, len)) { -+ dev_err(smi->parent, "copy from user failed\n"); -+ return -EFAULT; -+ } -+ -+ buf[len] = '\0'; -+ if (len > 0 && buf[len - 1] == '\n') -+ buf[len - 1] = '\0'; -+ -+ -+ if (kstrtoul(buf, 16, &data)) { -+ dev_err(smi->parent, "Invalid reg value %s\n", buf); -+ } else { -+ err = rtl8366_smi_write_reg(smi, reg, data); -+ if (err) { -+ dev_err(smi->parent, -+ "writing reg 0x%04x val 0x%04lx failed\n", -+ reg, data); -+ } -+ } -+ -+ return count; -+} -+ -+static ssize_t rtl8366_read_debugfs_mibs(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct rtl8366_smi *smi = file->private_data; -+ int i, j, len = 0; -+ char *buf = smi->buf; -+ -+ len += snprintf(buf + len, sizeof(smi->buf) - len, "%-36s", -+ "Counter"); -+ -+ for (i = 0; i < smi->num_ports; i++) { -+ char port_buf[10]; -+ -+ snprintf(port_buf, sizeof(port_buf), "Port %d", i); -+ len += snprintf(buf + len, sizeof(smi->buf) - len, " %12s", -+ port_buf); -+ } -+ len += snprintf(buf + len, sizeof(smi->buf) - len, "\n"); -+ -+ for (i = 0; i < smi->num_mib_counters; i++) { -+ len += snprintf(buf + len, sizeof(smi->buf) - len, "%-36s ", -+ smi->mib_counters[i].name); -+ for (j = 0; j < smi->num_ports; j++) { -+ unsigned long long counter = 0; -+ -+ if (!smi->ops->get_mib_counter(smi, i, j, &counter)) -+ len += snprintf(buf + len, -+ sizeof(smi->buf) - len, -+ "%12llu ", counter); -+ else -+ len += snprintf(buf + len, -+ sizeof(smi->buf) - len, -+ "%12s ", "error"); -+ } -+ len += snprintf(buf + len, sizeof(smi->buf) - len, "\n"); -+ } -+ -+ return simple_read_from_buffer(user_buf, count, ppos, buf, len); -+} -+ -+static const struct file_operations fops_rtl8366_regs = { -+ .read = rtl8366_read_debugfs_reg, -+ .write = rtl8366_write_debugfs_reg, -+ .open = rtl8366_debugfs_open, -+ .owner = THIS_MODULE -+}; -+ -+static const struct file_operations fops_rtl8366_vlan_mc = { -+ .read = rtl8366_read_debugfs_vlan_mc, -+ .open = rtl8366_debugfs_open, -+ .owner = THIS_MODULE -+}; -+ -+static const struct file_operations fops_rtl8366_vlan_4k = { -+ .read = rtl8366_read_debugfs_vlan_4k, -+ .open = rtl8366_debugfs_open, -+ .owner = THIS_MODULE -+}; -+ -+static const struct file_operations fops_rtl8366_pvid = { -+ .read = rtl8366_read_debugfs_pvid, -+ .open = rtl8366_debugfs_open, -+ .owner = THIS_MODULE -+}; -+ -+static const struct file_operations fops_rtl8366_mibs = { -+ .read = rtl8366_read_debugfs_mibs, -+ .open = rtl8366_debugfs_open, -+ .owner = THIS_MODULE -+}; -+ -+static void rtl8366_debugfs_init(struct rtl8366_smi *smi) -+{ -+ struct dentry *node; -+ struct dentry *root; -+ -+ if (!smi->debugfs_root) -+ smi->debugfs_root = debugfs_create_dir(dev_name(smi->parent), -+ NULL); -+ -+ if (!smi->debugfs_root) { -+ dev_err(smi->parent, "Unable to create debugfs dir\n"); -+ return; -+ } -+ root = smi->debugfs_root; -+ -+ node = debugfs_create_x16("reg", S_IRUGO | S_IWUSR, root, -+ &smi->dbg_reg); -+ if (!node) { -+ dev_err(smi->parent, "Creating debugfs file '%s' failed\n", -+ "reg"); -+ return; -+ } -+ -+ node = debugfs_create_file("val", S_IRUGO | S_IWUSR, root, smi, -+ &fops_rtl8366_regs); -+ if (!node) { -+ dev_err(smi->parent, "Creating debugfs file '%s' failed\n", -+ "val"); -+ return; -+ } -+ -+ node = debugfs_create_file("vlan_mc", S_IRUSR, root, smi, -+ &fops_rtl8366_vlan_mc); -+ if (!node) { -+ dev_err(smi->parent, "Creating debugfs file '%s' failed\n", -+ "vlan_mc"); -+ return; -+ } -+ -+ node = debugfs_create_u8("vlan_4k_page", S_IRUGO | S_IWUSR, root, -+ &smi->dbg_vlan_4k_page); -+ if (!node) { -+ dev_err(smi->parent, "Creating debugfs file '%s' failed\n", -+ "vlan_4k_page"); -+ return; -+ } -+ -+ node = debugfs_create_file("vlan_4k", S_IRUSR, root, smi, -+ &fops_rtl8366_vlan_4k); -+ if (!node) { -+ dev_err(smi->parent, "Creating debugfs file '%s' failed\n", -+ "vlan_4k"); -+ return; -+ } -+ -+ node = debugfs_create_file("pvid", S_IRUSR, root, smi, -+ &fops_rtl8366_pvid); -+ if (!node) { -+ dev_err(smi->parent, "Creating debugfs file '%s' failed\n", -+ "pvid"); -+ return; -+ } -+ -+ node = debugfs_create_file("mibs", S_IRUSR, smi->debugfs_root, smi, -+ &fops_rtl8366_mibs); -+ if (!node) -+ dev_err(smi->parent, "Creating debugfs file '%s' failed\n", -+ "mibs"); -+} -+ -+static void rtl8366_debugfs_remove(struct rtl8366_smi *smi) -+{ -+ if (smi->debugfs_root) { -+ debugfs_remove_recursive(smi->debugfs_root); -+ smi->debugfs_root = NULL; -+ } -+} -+#else -+static inline void rtl8366_debugfs_init(struct rtl8366_smi *smi) {} -+static inline void rtl8366_debugfs_remove(struct rtl8366_smi *smi) {} -+#endif /* CONFIG_RTL8366_SMI_DEBUG_FS */ -+ -+static int rtl8366_smi_mii_init(struct rtl8366_smi *smi) -+{ -+ int ret; -+ -+#ifdef CONFIG_OF -+ struct device_node *np = NULL; -+ -+ np = of_get_child_by_name(smi->parent->of_node, "mdio-bus"); -+#endif -+ -+ smi->mii_bus = mdiobus_alloc(); -+ if (smi->mii_bus == NULL) { -+ ret = -ENOMEM; -+ goto err; -+ } -+ -+ smi->mii_bus->priv = (void *) smi; -+ smi->mii_bus->name = dev_name(smi->parent); -+ smi->mii_bus->read = smi->ops->mii_read; -+ smi->mii_bus->write = smi->ops->mii_write; -+ snprintf(smi->mii_bus->id, MII_BUS_ID_SIZE, "%s", -+ dev_name(smi->parent)); -+ smi->mii_bus->parent = smi->parent; -+ smi->mii_bus->phy_mask = ~(0x1f); -+ -+#ifdef CONFIG_OF -+ if (np) -+ ret = of_mdiobus_register(smi->mii_bus, np); -+ else -+#endif -+ ret = mdiobus_register(smi->mii_bus); -+ -+ if (ret) -+ goto err_free; -+ -+ return 0; -+ -+ err_free: -+ mdiobus_free(smi->mii_bus); -+ err: -+ return ret; -+} -+ -+static void rtl8366_smi_mii_cleanup(struct rtl8366_smi *smi) -+{ -+ mdiobus_unregister(smi->mii_bus); -+ mdiobus_free(smi->mii_bus); -+} -+ -+int rtl8366_sw_reset_switch(struct switch_dev *dev) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ int err; -+ -+ err = rtl8366_reset(smi); -+ if (err) -+ return err; -+ -+ err = smi->ops->setup(smi); -+ if (err) -+ return err; -+ -+ err = rtl8366_smi_reset_vlan(smi); -+ if (err) -+ return err; -+ -+ err = rtl8366_smi_enable_vlan(smi, 1); -+ if (err) -+ return err; -+ -+ return rtl8366_smi_enable_all_ports(smi, 1); -+} -+EXPORT_SYMBOL_GPL(rtl8366_sw_reset_switch); -+ -+int rtl8366_sw_get_port_pvid(struct switch_dev *dev, int port, int *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ return rtl8366_get_pvid(smi, port, val); -+} -+EXPORT_SYMBOL_GPL(rtl8366_sw_get_port_pvid); -+ -+int rtl8366_sw_set_port_pvid(struct switch_dev *dev, int port, int val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ return rtl8366_set_pvid(smi, port, val); -+} -+EXPORT_SYMBOL_GPL(rtl8366_sw_set_port_pvid); -+ -+int rtl8366_sw_get_port_mib(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ int i, len = 0; -+ unsigned long long counter = 0; -+ char *buf = smi->buf; -+ -+ if (val->port_vlan >= smi->num_ports) -+ return -EINVAL; -+ -+ len += snprintf(buf + len, sizeof(smi->buf) - len, -+ "Port %d MIB counters\n", -+ val->port_vlan); -+ -+ for (i = 0; i < smi->num_mib_counters; ++i) { -+ len += snprintf(buf + len, sizeof(smi->buf) - len, -+ "%-36s: ", smi->mib_counters[i].name); -+ if (!smi->ops->get_mib_counter(smi, i, val->port_vlan, -+ &counter)) -+ len += snprintf(buf + len, sizeof(smi->buf) - len, -+ "%llu\n", counter); -+ else -+ len += snprintf(buf + len, sizeof(smi->buf) - len, -+ "%s\n", "error"); -+ } -+ -+ val->value.s = buf; -+ val->len = len; -+ return 0; -+} -+EXPORT_SYMBOL_GPL(rtl8366_sw_get_port_mib); -+ -+int rtl8366_sw_get_port_stats(struct switch_dev *dev, int port, -+ struct switch_port_stats *stats, -+ int txb_id, int rxb_id) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ unsigned long long counter = 0; -+ int ret; -+ -+ if (port >= smi->num_ports) -+ return -EINVAL; -+ -+ ret = smi->ops->get_mib_counter(smi, txb_id, port, &counter); -+ if (ret) -+ return ret; -+ -+ stats->tx_bytes = counter; -+ -+ ret = smi->ops->get_mib_counter(smi, rxb_id, port, &counter); -+ if (ret) -+ return ret; -+ -+ stats->rx_bytes = counter; -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(rtl8366_sw_get_port_stats); -+ -+int rtl8366_sw_get_vlan_info(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ int i; -+ u32 len = 0; -+ struct rtl8366_vlan_4k vlan4k; -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ char *buf = smi->buf; -+ int err; -+ -+ if (!smi->ops->is_vlan_valid(smi, val->port_vlan)) -+ return -EINVAL; -+ -+ memset(buf, '\0', sizeof(smi->buf)); -+ -+ err = smi->ops->get_vlan_4k(smi, val->port_vlan, &vlan4k); -+ if (err) -+ return err; -+ -+ len += snprintf(buf + len, sizeof(smi->buf) - len, -+ "VLAN %d: Ports: '", vlan4k.vid); -+ -+ for (i = 0; i < smi->num_ports; i++) { -+ if (!(vlan4k.member & (1 << i))) -+ continue; -+ -+ len += snprintf(buf + len, sizeof(smi->buf) - len, "%d%s", i, -+ (vlan4k.untag & (1 << i)) ? "" : "t"); -+ } -+ -+ len += snprintf(buf + len, sizeof(smi->buf) - len, -+ "', members=%04x, untag=%04x, fid=%u", -+ vlan4k.member, vlan4k.untag, vlan4k.fid); -+ -+ val->value.s = buf; -+ val->len = len; -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(rtl8366_sw_get_vlan_info); -+ -+int rtl8366_sw_get_vlan_ports(struct switch_dev *dev, struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ struct switch_port *port; -+ struct rtl8366_vlan_4k vlan4k; -+ int i; -+ -+ if (!smi->ops->is_vlan_valid(smi, val->port_vlan)) -+ return -EINVAL; -+ -+ smi->ops->get_vlan_4k(smi, val->port_vlan, &vlan4k); -+ -+ port = &val->value.ports[0]; -+ val->len = 0; -+ for (i = 0; i < smi->num_ports; i++) { -+ if (!(vlan4k.member & BIT(i))) -+ continue; -+ -+ port->id = i; -+ port->flags = (vlan4k.untag & BIT(i)) ? -+ 0 : BIT(SWITCH_PORT_FLAG_TAGGED); -+ val->len++; -+ port++; -+ } -+ return 0; -+} -+EXPORT_SYMBOL_GPL(rtl8366_sw_get_vlan_ports); -+ -+int rtl8366_sw_set_vlan_ports(struct switch_dev *dev, struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ struct switch_port *port; -+ u32 member = 0; -+ u32 untag = 0; -+ int err; -+ int i; -+ -+ if (!smi->ops->is_vlan_valid(smi, val->port_vlan)) -+ return -EINVAL; -+ -+ port = &val->value.ports[0]; -+ for (i = 0; i < val->len; i++, port++) { -+ int pvid = 0; -+ member |= BIT(port->id); -+ -+ if (!(port->flags & BIT(SWITCH_PORT_FLAG_TAGGED))) -+ untag |= BIT(port->id); -+ -+ /* -+ * To ensure that we have a valid MC entry for this VLAN, -+ * initialize the port VLAN ID here. -+ */ -+ err = rtl8366_get_pvid(smi, port->id, &pvid); -+ if (err < 0) -+ return err; -+ if (pvid == 0) { -+ err = rtl8366_set_pvid(smi, port->id, val->port_vlan); -+ if (err < 0) -+ return err; -+ } -+ } -+ -+ return rtl8366_set_vlan(smi, val->port_vlan, member, untag, 0); -+} -+EXPORT_SYMBOL_GPL(rtl8366_sw_set_vlan_ports); -+ -+int rtl8366_sw_get_vlan_fid(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_vlan_4k vlan4k; -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ int err; -+ -+ if (!smi->ops->is_vlan_valid(smi, val->port_vlan)) -+ return -EINVAL; -+ -+ err = smi->ops->get_vlan_4k(smi, val->port_vlan, &vlan4k); -+ if (err) -+ return err; -+ -+ val->value.i = vlan4k.fid; -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(rtl8366_sw_get_vlan_fid); -+ -+int rtl8366_sw_set_vlan_fid(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_vlan_4k vlan4k; -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ int err; -+ -+ if (!smi->ops->is_vlan_valid(smi, val->port_vlan)) -+ return -EINVAL; -+ -+ if (val->value.i < 0 || val->value.i > attr->max) -+ return -EINVAL; -+ -+ err = smi->ops->get_vlan_4k(smi, val->port_vlan, &vlan4k); -+ if (err) -+ return err; -+ -+ return rtl8366_set_vlan(smi, val->port_vlan, -+ vlan4k.member, -+ vlan4k.untag, -+ val->value.i); -+} -+EXPORT_SYMBOL_GPL(rtl8366_sw_set_vlan_fid); -+ -+int rtl8366_sw_get_vlan_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ -+ if (attr->ofs > 2) -+ return -EINVAL; -+ -+ if (attr->ofs == 1) -+ val->value.i = smi->vlan_enabled; -+ else -+ val->value.i = smi->vlan4k_enabled; -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(rtl8366_sw_get_vlan_enable); -+ -+int rtl8366_sw_set_vlan_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ int err; -+ -+ if (attr->ofs > 2) -+ return -EINVAL; -+ -+ if (attr->ofs == 1) -+ err = rtl8366_smi_enable_vlan(smi, val->value.i); -+ else -+ err = rtl8366_smi_enable_vlan4k(smi, val->value.i); -+ -+ return err; -+} -+EXPORT_SYMBOL_GPL(rtl8366_sw_set_vlan_enable); -+ -+struct rtl8366_smi *rtl8366_smi_alloc(struct device *parent) -+{ -+ struct rtl8366_smi *smi; -+ -+ BUG_ON(!parent); -+ -+ smi = kzalloc(sizeof(*smi), GFP_KERNEL); -+ if (!smi) { -+ dev_err(parent, "no memory for private data\n"); -+ return NULL; -+ } -+ -+ smi->parent = parent; -+ return smi; -+} -+EXPORT_SYMBOL_GPL(rtl8366_smi_alloc); -+ -+static int __rtl8366_smi_init(struct rtl8366_smi *smi, const char *name) -+{ -+ int err; -+ -+ if (!smi->ext_mbus) { -+ err = gpio_request(smi->gpio_sda, name); -+ if (err) { -+ printk(KERN_ERR "rtl8366_smi: gpio_request failed for %u, err=%d\n", -+ smi->gpio_sda, err); -+ goto err_out; -+ } -+ -+ err = gpio_request(smi->gpio_sck, name); -+ if (err) { -+ printk(KERN_ERR "rtl8366_smi: gpio_request failed for %u, err=%d\n", -+ smi->gpio_sck, err); -+ goto err_free_sda; -+ } -+ } -+ -+ spin_lock_init(&smi->lock); -+ -+ /* start the switch */ -+ if (smi->hw_reset) { -+ smi->hw_reset(smi, false); -+ msleep(RTL8366_SMI_HW_START_DELAY); -+ } -+ -+ return 0; -+ -+ err_free_sda: -+ gpio_free(smi->gpio_sda); -+ err_out: -+ return err; -+} -+ -+static void __rtl8366_smi_cleanup(struct rtl8366_smi *smi) -+{ -+ if (smi->hw_reset) -+ smi->hw_reset(smi, true); -+ -+ if (!smi->ext_mbus) { -+ gpio_free(smi->gpio_sck); -+ gpio_free(smi->gpio_sda); -+ } -+} -+ -+enum rtl8366_type rtl8366_smi_detect(struct rtl8366_platform_data *pdata) -+{ -+ static struct rtl8366_smi smi; -+ enum rtl8366_type type = RTL8366_TYPE_UNKNOWN; -+ u32 reg = 0; -+ -+ memset(&smi, 0, sizeof(smi)); -+ smi.gpio_sda = pdata->gpio_sda; -+ smi.gpio_sck = pdata->gpio_sck; -+ smi.clk_delay = 10; -+ smi.cmd_read = 0xa9; -+ smi.cmd_write = 0xa8; -+ -+ if (__rtl8366_smi_init(&smi, "rtl8366")) -+ goto out; -+ -+ if (rtl8366_smi_read_reg(&smi, 0x5c, ®)) -+ goto cleanup; -+ -+ switch(reg) { -+ case 0x6027: -+ printk("Found an RTL8366S switch\n"); -+ type = RTL8366_TYPE_S; -+ break; -+ case 0x5937: -+ printk("Found an RTL8366RB switch\n"); -+ type = RTL8366_TYPE_RB; -+ break; -+ default: -+ printk("Found an Unknown RTL8366 switch (id=0x%04x)\n", reg); -+ break; -+ } -+ -+cleanup: -+ __rtl8366_smi_cleanup(&smi); -+out: -+ return type; -+} -+ -+int rtl8366_smi_init(struct rtl8366_smi *smi) -+{ -+ int err; -+ -+ if (!smi->ops) -+ return -EINVAL; -+ -+ err = __rtl8366_smi_init(smi, dev_name(smi->parent)); -+ if (err) -+ goto err_out; -+ -+ if (!smi->ext_mbus) -+ dev_info(smi->parent, "using GPIO pins %u (SDA) and %u (SCK)\n", -+ smi->gpio_sda, smi->gpio_sck); -+ else -+ dev_info(smi->parent, "using MDIO bus '%s'\n", smi->ext_mbus->name); -+ -+ err = smi->ops->detect(smi); -+ if (err) { -+ dev_err(smi->parent, "chip detection failed, err=%d\n", err); -+ goto err_free_sck; -+ } -+ -+ err = rtl8366_reset(smi); -+ if (err) -+ goto err_free_sck; -+ -+ err = smi->ops->setup(smi); -+ if (err) { -+ dev_err(smi->parent, "chip setup failed, err=%d\n", err); -+ goto err_free_sck; -+ } -+ -+ err = rtl8366_init_vlan(smi); -+ if (err) { -+ dev_err(smi->parent, "VLAN initialization failed, err=%d\n", -+ err); -+ goto err_free_sck; -+ } -+ -+ err = rtl8366_smi_enable_all_ports(smi, 1); -+ if (err) -+ goto err_free_sck; -+ -+ err = rtl8366_smi_mii_init(smi); -+ if (err) -+ goto err_free_sck; -+ -+ rtl8366_debugfs_init(smi); -+ -+ return 0; -+ -+ err_free_sck: -+ __rtl8366_smi_cleanup(smi); -+ err_out: -+ return err; -+} -+EXPORT_SYMBOL_GPL(rtl8366_smi_init); -+ -+void rtl8366_smi_cleanup(struct rtl8366_smi *smi) -+{ -+ rtl8366_debugfs_remove(smi); -+ rtl8366_smi_mii_cleanup(smi); -+ __rtl8366_smi_cleanup(smi); -+} -+EXPORT_SYMBOL_GPL(rtl8366_smi_cleanup); -+ -+#ifdef CONFIG_OF -+static void rtl8366_smi_reset(struct rtl8366_smi *smi, bool active) -+{ -+ if (active) -+ reset_control_assert(smi->reset); -+ else -+ reset_control_deassert(smi->reset); -+} -+ -+static int rtl8366_smi_probe_of(struct platform_device *pdev, struct rtl8366_smi *smi) -+{ -+ int sck = of_get_named_gpio(pdev->dev.of_node, "gpio-sck", 0); -+ int sda = of_get_named_gpio(pdev->dev.of_node, "gpio-sda", 0); -+ struct device_node *np = pdev->dev.of_node; -+ struct device_node *mdio_node; -+ -+ mdio_node = of_parse_phandle(np, "mii-bus", 0); -+ if (!mdio_node) { -+ dev_err(&pdev->dev, "cannot find mdio node phandle"); -+ goto try_gpio; -+ } -+ -+ smi->ext_mbus = of_mdio_find_bus(mdio_node); -+ if (!smi->ext_mbus) { -+ dev_info(&pdev->dev, -+ "cannot find mdio bus from bus handle (yet)"); -+ goto try_gpio; -+ } -+ -+ if (of_property_read_u32(np, "phy-id", &smi->phy_id)) -+ smi->phy_id = MDC_REALTEK_PHY_ADDR; -+ -+ return 0; -+ -+try_gpio: -+ if (!gpio_is_valid(sck) || !gpio_is_valid(sda)) { -+ if (!mdio_node) { -+ dev_err(&pdev->dev, "gpios missing in devictree\n"); -+ return -EINVAL; -+ } else { -+ return -EPROBE_DEFER; -+ } -+ } -+ -+ smi->gpio_sda = sda; -+ smi->gpio_sck = sck; -+ smi->reset = devm_reset_control_get(&pdev->dev, "switch"); -+ if (!IS_ERR(smi->reset)) -+ smi->hw_reset = rtl8366_smi_reset; -+ -+ return 0; -+} -+#else -+static inline int rtl8366_smi_probe_of(struct platform_device *pdev, struct rtl8366_smi *smi) -+{ -+ return -ENODEV; -+} -+#endif -+ -+static int rtl8366_smi_probe_plat(struct platform_device *pdev, struct rtl8366_smi *smi) -+{ -+ struct rtl8366_platform_data *pdata = pdev->dev.platform_data; -+ -+ if (!pdev->dev.platform_data) { -+ dev_err(&pdev->dev, "no platform data specified\n"); -+ return -EINVAL; -+ } -+ -+ smi->gpio_sda = pdata->gpio_sda; -+ smi->gpio_sck = pdata->gpio_sck; -+ smi->hw_reset = pdata->hw_reset; -+ smi->phy_id = MDC_REALTEK_PHY_ADDR; -+ -+ return 0; -+} -+ -+ -+struct rtl8366_smi *rtl8366_smi_probe(struct platform_device *pdev) -+{ -+ struct rtl8366_smi *smi; -+ int err; -+ -+ smi = rtl8366_smi_alloc(&pdev->dev); -+ if (!smi) -+ return NULL; -+ -+ if (pdev->dev.of_node) -+ err = rtl8366_smi_probe_of(pdev, smi); -+ else -+ err = rtl8366_smi_probe_plat(pdev, smi); -+ -+ if (err) -+ goto free_smi; -+ -+ return smi; -+ -+free_smi: -+ kfree(smi); -+ return ERR_PTR(err); -+} -+EXPORT_SYMBOL_GPL(rtl8366_smi_probe); -+ -+MODULE_DESCRIPTION("Realtek RTL8366 SMI interface driver"); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_LICENSE("GPL v2"); -diff --git a/drivers/net/phy/rtl8366_smi.h b/drivers/net/phy/rtl8366_smi.h -new file mode 100644 -index 000000000000..2608240bb083 ---- /dev/null -+++ b/drivers/net/phy/rtl8366_smi.h -@@ -0,0 +1,171 @@ -+/* -+ * Realtek RTL8366 SMI interface driver defines -+ * -+ * Copyright (C) 2009-2010 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#ifndef _RTL8366_SMI_H -+#define _RTL8366_SMI_H -+ -+#include -+#include -+#include -+#include -+ -+struct rtl8366_smi_ops; -+struct rtl8366_vlan_ops; -+struct mii_bus; -+struct dentry; -+struct inode; -+struct file; -+ -+typedef enum rtl8367b_chip_e { -+ RTL8367B_CHIP_UNKNOWN, -+ /* Family B */ -+ RTL8367B_CHIP_RTL8367RB, -+ RTL8367B_CHIP_RTL8367R_VB, /* chip with exception in extif assignment */ -+/* Family C */ -+ RTL8367B_CHIP_RTL8367RB_VB, -+ RTL8367B_CHIP_RTL8367S, -+/* Family D */ -+ RTL8367B_CHIP_RTL8367S_VB /* chip with exception in extif assignment */ -+} rtl8367b_chip_t; -+ -+struct rtl8366_mib_counter { -+ unsigned base; -+ unsigned offset; -+ unsigned length; -+ const char *name; -+}; -+ -+struct rtl8366_smi { -+ struct device *parent; -+ unsigned int gpio_sda; -+ unsigned int gpio_sck; -+ void (*hw_reset)(struct rtl8366_smi *smi, bool active); -+ unsigned int clk_delay; /* ns */ -+ u8 cmd_read; -+ u8 cmd_write; -+ spinlock_t lock; -+ struct mii_bus *mii_bus; -+ int mii_irq[PHY_MAX_ADDR]; -+ struct switch_dev sw_dev; -+ -+ unsigned int cpu_port; -+ unsigned int num_ports; -+ unsigned int num_vlan_mc; -+ unsigned int num_mib_counters; -+ struct rtl8366_mib_counter *mib_counters; -+ -+ struct rtl8366_smi_ops *ops; -+ -+ int vlan_enabled; -+ int vlan4k_enabled; -+ -+ char buf[4096]; -+ -+ struct reset_control *reset; -+ -+#ifdef CONFIG_RTL8366_SMI_DEBUG_FS -+ struct dentry *debugfs_root; -+ u16 dbg_reg; -+ u8 dbg_vlan_4k_page; -+#endif -+ u32 phy_id; -+ rtl8367b_chip_t rtl8367b_chip; -+ struct mii_bus *ext_mbus; -+ struct rtl8366_vlan_mc *emu_vlanmc; -+}; -+ -+struct rtl8366_vlan_mc { -+ u16 vid; -+ u16 untag; -+ u16 member; -+ u8 fid; -+ u8 priority; -+}; -+ -+struct rtl8366_vlan_4k { -+ u16 vid; -+ u16 untag; -+ u16 member; -+ u8 fid; -+}; -+ -+struct rtl8366_smi_ops { -+ int (*detect)(struct rtl8366_smi *smi); -+ int (*reset_chip)(struct rtl8366_smi *smi); -+ int (*setup)(struct rtl8366_smi *smi); -+ -+ int (*mii_read)(struct mii_bus *bus, int addr, int reg); -+ int (*mii_write)(struct mii_bus *bus, int addr, int reg, u16 val); -+ -+ int (*get_vlan_mc)(struct rtl8366_smi *smi, u32 index, -+ struct rtl8366_vlan_mc *vlanmc); -+ int (*set_vlan_mc)(struct rtl8366_smi *smi, u32 index, -+ const struct rtl8366_vlan_mc *vlanmc); -+ int (*get_vlan_4k)(struct rtl8366_smi *smi, u32 vid, -+ struct rtl8366_vlan_4k *vlan4k); -+ int (*set_vlan_4k)(struct rtl8366_smi *smi, -+ const struct rtl8366_vlan_4k *vlan4k); -+ int (*get_mc_index)(struct rtl8366_smi *smi, int port, int *val); -+ int (*set_mc_index)(struct rtl8366_smi *smi, int port, int index); -+ int (*get_mib_counter)(struct rtl8366_smi *smi, int counter, -+ int port, unsigned long long *val); -+ int (*is_vlan_valid)(struct rtl8366_smi *smi, unsigned vlan); -+ int (*enable_vlan)(struct rtl8366_smi *smi, int enable); -+ int (*enable_vlan4k)(struct rtl8366_smi *smi, int enable); -+ int (*enable_port)(struct rtl8366_smi *smi, int port, int enable); -+}; -+ -+struct rtl8366_smi *rtl8366_smi_alloc(struct device *parent); -+int rtl8366_smi_init(struct rtl8366_smi *smi); -+void rtl8366_smi_cleanup(struct rtl8366_smi *smi); -+int rtl8366_smi_write_reg(struct rtl8366_smi *smi, u32 addr, u32 data); -+int rtl8366_smi_write_reg_noack(struct rtl8366_smi *smi, u32 addr, u32 data); -+int rtl8366_smi_read_reg(struct rtl8366_smi *smi, u32 addr, u32 *data); -+int rtl8366_smi_rmwr(struct rtl8366_smi *smi, u32 addr, u32 mask, u32 data); -+ -+#ifdef CONFIG_RTL8366_SMI_DEBUG_FS -+int rtl8366_debugfs_open(struct inode *inode, struct file *file); -+#endif -+ -+static inline struct rtl8366_smi *sw_to_rtl8366_smi(struct switch_dev *sw) -+{ -+ return container_of(sw, struct rtl8366_smi, sw_dev); -+} -+ -+int rtl8366_sw_reset_switch(struct switch_dev *dev); -+int rtl8366_sw_get_port_pvid(struct switch_dev *dev, int port, int *val); -+int rtl8366_sw_set_port_pvid(struct switch_dev *dev, int port, int val); -+int rtl8366_sw_get_port_mib(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val); -+int rtl8366_sw_get_vlan_info(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val); -+int rtl8366_sw_get_vlan_fid(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val); -+int rtl8366_sw_set_vlan_fid(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val); -+int rtl8366_sw_get_vlan_ports(struct switch_dev *dev, struct switch_val *val); -+int rtl8366_sw_set_vlan_ports(struct switch_dev *dev, struct switch_val *val); -+int rtl8366_sw_get_vlan_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val); -+int rtl8366_sw_set_vlan_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val); -+int rtl8366_sw_get_port_stats(struct switch_dev *dev, int port, -+ struct switch_port_stats *stats, -+ int txb_id, int rxb_id); -+ -+struct rtl8366_smi* rtl8366_smi_probe(struct platform_device *pdev); -+ -+#endif /* _RTL8366_SMI_H */ -diff --git a/drivers/net/phy/rtl8366rb.c b/drivers/net/phy/rtl8366rb.c -new file mode 100644 -index 000000000000..7057b252526d ---- /dev/null -+++ b/drivers/net/phy/rtl8366rb.c -@@ -0,0 +1,1529 @@ -+/* -+ * Platform driver for the Realtek RTL8366RB ethernet switch -+ * -+ * Copyright (C) 2009-2010 Gabor Juhos -+ * Copyright (C) 2010 Antti Seppälä -+ * Copyright (C) 2010 Roman Yeryomin -+ * Copyright (C) 2011 Colin Leitner -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "rtl8366_smi.h" -+ -+#define RTL8366RB_DRIVER_DESC "Realtek RTL8366RB ethernet switch driver" -+#define RTL8366RB_DRIVER_VER "0.2.4" -+ -+#define RTL8366RB_PHY_NO_MAX 4 -+#define RTL8366RB_PHY_PAGE_MAX 7 -+#define RTL8366RB_PHY_ADDR_MAX 31 -+ -+/* Switch Global Configuration register */ -+#define RTL8366RB_SGCR 0x0000 -+#define RTL8366RB_SGCR_EN_BC_STORM_CTRL BIT(0) -+#define RTL8366RB_SGCR_MAX_LENGTH(_x) (_x << 4) -+#define RTL8366RB_SGCR_MAX_LENGTH_MASK RTL8366RB_SGCR_MAX_LENGTH(0x3) -+#define RTL8366RB_SGCR_MAX_LENGTH_1522 RTL8366RB_SGCR_MAX_LENGTH(0x0) -+#define RTL8366RB_SGCR_MAX_LENGTH_1536 RTL8366RB_SGCR_MAX_LENGTH(0x1) -+#define RTL8366RB_SGCR_MAX_LENGTH_1552 RTL8366RB_SGCR_MAX_LENGTH(0x2) -+#define RTL8366RB_SGCR_MAX_LENGTH_9216 RTL8366RB_SGCR_MAX_LENGTH(0x3) -+#define RTL8366RB_SGCR_EN_VLAN BIT(13) -+#define RTL8366RB_SGCR_EN_VLAN_4KTB BIT(14) -+ -+/* Port Enable Control register */ -+#define RTL8366RB_PECR 0x0001 -+ -+/* Port Mirror Control Register */ -+#define RTL8366RB_PMCR 0x0007 -+#define RTL8366RB_PMCR_SOURCE_PORT(_x) (_x) -+#define RTL8366RB_PMCR_SOURCE_PORT_MASK 0x000f -+#define RTL8366RB_PMCR_MONITOR_PORT(_x) ((_x) << 4) -+#define RTL8366RB_PMCR_MONITOR_PORT_MASK 0x00f0 -+#define RTL8366RB_PMCR_MIRROR_RX BIT(8) -+#define RTL8366RB_PMCR_MIRROR_TX BIT(9) -+#define RTL8366RB_PMCR_MIRROR_SPC BIT(10) -+#define RTL8366RB_PMCR_MIRROR_ISO BIT(11) -+ -+/* Switch Security Control registers */ -+#define RTL8366RB_SSCR0 0x0002 -+#define RTL8366RB_SSCR1 0x0003 -+#define RTL8366RB_SSCR2 0x0004 -+#define RTL8366RB_SSCR2_DROP_UNKNOWN_DA BIT(0) -+ -+#define RTL8366RB_RESET_CTRL_REG 0x0100 -+#define RTL8366RB_CHIP_CTRL_RESET_HW 1 -+#define RTL8366RB_CHIP_CTRL_RESET_SW (1 << 1) -+ -+#define RTL8366RB_CHIP_VERSION_CTRL_REG 0x050A -+#define RTL8366RB_CHIP_VERSION_MASK 0xf -+#define RTL8366RB_CHIP_ID_REG 0x0509 -+#define RTL8366RB_CHIP_ID_8366 0x5937 -+ -+/* PHY registers control */ -+#define RTL8366RB_PHY_ACCESS_CTRL_REG 0x8000 -+#define RTL8366RB_PHY_ACCESS_DATA_REG 0x8002 -+ -+#define RTL8366RB_PHY_CTRL_READ 1 -+#define RTL8366RB_PHY_CTRL_WRITE 0 -+ -+#define RTL8366RB_PHY_REG_MASK 0x1f -+#define RTL8366RB_PHY_PAGE_OFFSET 5 -+#define RTL8366RB_PHY_PAGE_MASK (0xf << 5) -+#define RTL8366RB_PHY_NO_OFFSET 9 -+#define RTL8366RB_PHY_NO_MASK (0x1f << 9) -+ -+#define RTL8366RB_VLAN_INGRESS_CTRL2_REG 0x037f -+ -+/* LED control registers */ -+#define RTL8366RB_LED_BLINKRATE_REG 0x0430 -+#define RTL8366RB_LED_BLINKRATE_BIT 0 -+#define RTL8366RB_LED_BLINKRATE_MASK 0x0007 -+ -+#define RTL8366RB_LED_CTRL_REG 0x0431 -+#define RTL8366RB_LED_0_1_CTRL_REG 0x0432 -+#define RTL8366RB_LED_2_3_CTRL_REG 0x0433 -+ -+#define RTL8366RB_MIB_COUNT 33 -+#define RTL8366RB_GLOBAL_MIB_COUNT 1 -+#define RTL8366RB_MIB_COUNTER_PORT_OFFSET 0x0050 -+#define RTL8366RB_MIB_COUNTER_BASE 0x1000 -+#define RTL8366RB_MIB_CTRL_REG 0x13F0 -+#define RTL8366RB_MIB_CTRL_USER_MASK 0x0FFC -+#define RTL8366RB_MIB_CTRL_BUSY_MASK BIT(0) -+#define RTL8366RB_MIB_CTRL_RESET_MASK BIT(1) -+#define RTL8366RB_MIB_CTRL_PORT_RESET(_p) BIT(2 + (_p)) -+#define RTL8366RB_MIB_CTRL_GLOBAL_RESET BIT(11) -+ -+#define RTL8366RB_PORT_VLAN_CTRL_BASE 0x0063 -+#define RTL8366RB_PORT_VLAN_CTRL_REG(_p) \ -+ (RTL8366RB_PORT_VLAN_CTRL_BASE + (_p) / 4) -+#define RTL8366RB_PORT_VLAN_CTRL_MASK 0xf -+#define RTL8366RB_PORT_VLAN_CTRL_SHIFT(_p) (4 * ((_p) % 4)) -+ -+ -+#define RTL8366RB_VLAN_TABLE_READ_BASE 0x018C -+#define RTL8366RB_VLAN_TABLE_WRITE_BASE 0x0185 -+ -+ -+#define RTL8366RB_TABLE_ACCESS_CTRL_REG 0x0180 -+#define RTL8366RB_TABLE_VLAN_READ_CTRL 0x0E01 -+#define RTL8366RB_TABLE_VLAN_WRITE_CTRL 0x0F01 -+ -+#define RTL8366RB_VLAN_MC_BASE(_x) (0x0020 + (_x) * 3) -+ -+ -+#define RTL8366RB_PORT_LINK_STATUS_BASE 0x0014 -+#define RTL8366RB_PORT_STATUS_SPEED_MASK 0x0003 -+#define RTL8366RB_PORT_STATUS_DUPLEX_MASK 0x0004 -+#define RTL8366RB_PORT_STATUS_LINK_MASK 0x0010 -+#define RTL8366RB_PORT_STATUS_TXPAUSE_MASK 0x0020 -+#define RTL8366RB_PORT_STATUS_RXPAUSE_MASK 0x0040 -+#define RTL8366RB_PORT_STATUS_AN_MASK 0x0080 -+ -+ -+#define RTL8366RB_PORT_NUM_CPU 5 -+#define RTL8366RB_NUM_PORTS 6 -+#define RTL8366RB_NUM_VLANS 16 -+#define RTL8366RB_NUM_LEDGROUPS 4 -+#define RTL8366RB_NUM_VIDS 4096 -+#define RTL8366RB_PRIORITYMAX 7 -+#define RTL8366RB_FIDMAX 7 -+ -+ -+#define RTL8366RB_PORT_1 (1 << 0) /* In userspace port 0 */ -+#define RTL8366RB_PORT_2 (1 << 1) /* In userspace port 1 */ -+#define RTL8366RB_PORT_3 (1 << 2) /* In userspace port 2 */ -+#define RTL8366RB_PORT_4 (1 << 3) /* In userspace port 3 */ -+#define RTL8366RB_PORT_5 (1 << 4) /* In userspace port 4 */ -+ -+#define RTL8366RB_PORT_CPU (1 << 5) /* CPU port */ -+ -+#define RTL8366RB_PORT_ALL (RTL8366RB_PORT_1 | \ -+ RTL8366RB_PORT_2 | \ -+ RTL8366RB_PORT_3 | \ -+ RTL8366RB_PORT_4 | \ -+ RTL8366RB_PORT_5 | \ -+ RTL8366RB_PORT_CPU) -+ -+#define RTL8366RB_PORT_ALL_BUT_CPU (RTL8366RB_PORT_1 | \ -+ RTL8366RB_PORT_2 | \ -+ RTL8366RB_PORT_3 | \ -+ RTL8366RB_PORT_4 | \ -+ RTL8366RB_PORT_5) -+ -+#define RTL8366RB_PORT_ALL_EXTERNAL (RTL8366RB_PORT_1 | \ -+ RTL8366RB_PORT_2 | \ -+ RTL8366RB_PORT_3 | \ -+ RTL8366RB_PORT_4) -+ -+#define RTL8366RB_PORT_ALL_INTERNAL RTL8366RB_PORT_CPU -+ -+#define RTL8366RB_VLAN_VID_MASK 0xfff -+#define RTL8366RB_VLAN_PRIORITY_SHIFT 12 -+#define RTL8366RB_VLAN_PRIORITY_MASK 0x7 -+#define RTL8366RB_VLAN_UNTAG_SHIFT 8 -+#define RTL8366RB_VLAN_UNTAG_MASK 0xff -+#define RTL8366RB_VLAN_MEMBER_MASK 0xff -+#define RTL8366RB_VLAN_FID_MASK 0x7 -+ -+ -+/* Port ingress bandwidth control */ -+#define RTL8366RB_IB_BASE 0x0200 -+#define RTL8366RB_IB_REG(pnum) (RTL8366RB_IB_BASE + pnum) -+#define RTL8366RB_IB_BDTH_MASK 0x3fff -+#define RTL8366RB_IB_PREIFG_OFFSET 14 -+#define RTL8366RB_IB_PREIFG_MASK (1 << RTL8366RB_IB_PREIFG_OFFSET) -+ -+/* Port egress bandwidth control */ -+#define RTL8366RB_EB_BASE 0x02d1 -+#define RTL8366RB_EB_REG(pnum) (RTL8366RB_EB_BASE + pnum) -+#define RTL8366RB_EB_BDTH_MASK 0x3fff -+#define RTL8366RB_EB_PREIFG_REG 0x02f8 -+#define RTL8366RB_EB_PREIFG_OFFSET 9 -+#define RTL8366RB_EB_PREIFG_MASK (1 << RTL8366RB_EB_PREIFG_OFFSET) -+ -+#define RTL8366RB_BDTH_SW_MAX 1048512 -+#define RTL8366RB_BDTH_UNIT 64 -+#define RTL8366RB_BDTH_REG_DEFAULT 16383 -+ -+/* QOS */ -+#define RTL8366RB_QOS_BIT 15 -+#define RTL8366RB_QOS_MASK (1 << RTL8366RB_QOS_BIT) -+/* Include/Exclude Preamble and IFG (20 bytes). 0:Exclude, 1:Include. */ -+#define RTL8366RB_QOS_DEFAULT_PREIFG 1 -+ -+ -+#define RTL8366RB_MIB_RXB_ID 0 /* IfInOctets */ -+#define RTL8366RB_MIB_TXB_ID 20 /* IfOutOctets */ -+ -+static struct rtl8366_mib_counter rtl8366rb_mib_counters[] = { -+ { 0, 0, 4, "IfInOctets" }, -+ { 0, 4, 4, "EtherStatsOctets" }, -+ { 0, 8, 2, "EtherStatsUnderSizePkts" }, -+ { 0, 10, 2, "EtherFragments" }, -+ { 0, 12, 2, "EtherStatsPkts64Octets" }, -+ { 0, 14, 2, "EtherStatsPkts65to127Octets" }, -+ { 0, 16, 2, "EtherStatsPkts128to255Octets" }, -+ { 0, 18, 2, "EtherStatsPkts256to511Octets" }, -+ { 0, 20, 2, "EtherStatsPkts512to1023Octets" }, -+ { 0, 22, 2, "EtherStatsPkts1024to1518Octets" }, -+ { 0, 24, 2, "EtherOversizeStats" }, -+ { 0, 26, 2, "EtherStatsJabbers" }, -+ { 0, 28, 2, "IfInUcastPkts" }, -+ { 0, 30, 2, "EtherStatsMulticastPkts" }, -+ { 0, 32, 2, "EtherStatsBroadcastPkts" }, -+ { 0, 34, 2, "EtherStatsDropEvents" }, -+ { 0, 36, 2, "Dot3StatsFCSErrors" }, -+ { 0, 38, 2, "Dot3StatsSymbolErrors" }, -+ { 0, 40, 2, "Dot3InPauseFrames" }, -+ { 0, 42, 2, "Dot3ControlInUnknownOpcodes" }, -+ { 0, 44, 4, "IfOutOctets" }, -+ { 0, 48, 2, "Dot3StatsSingleCollisionFrames" }, -+ { 0, 50, 2, "Dot3StatMultipleCollisionFrames" }, -+ { 0, 52, 2, "Dot3sDeferredTransmissions" }, -+ { 0, 54, 2, "Dot3StatsLateCollisions" }, -+ { 0, 56, 2, "EtherStatsCollisions" }, -+ { 0, 58, 2, "Dot3StatsExcessiveCollisions" }, -+ { 0, 60, 2, "Dot3OutPauseFrames" }, -+ { 0, 62, 2, "Dot1dBasePortDelayExceededDiscards" }, -+ { 0, 64, 2, "Dot1dTpPortInDiscards" }, -+ { 0, 66, 2, "IfOutUcastPkts" }, -+ { 0, 68, 2, "IfOutMulticastPkts" }, -+ { 0, 70, 2, "IfOutBroadcastPkts" }, -+}; -+ -+#define REG_WR(_smi, _reg, _val) \ -+ do { \ -+ err = rtl8366_smi_write_reg(_smi, _reg, _val); \ -+ if (err) \ -+ return err; \ -+ } while (0) -+ -+#define REG_RMW(_smi, _reg, _mask, _val) \ -+ do { \ -+ err = rtl8366_smi_rmwr(_smi, _reg, _mask, _val); \ -+ if (err) \ -+ return err; \ -+ } while (0) -+ -+static int rtl8366rb_reset_chip(struct rtl8366_smi *smi) -+{ -+ int timeout = 10; -+ u32 data; -+ -+ rtl8366_smi_write_reg_noack(smi, RTL8366RB_RESET_CTRL_REG, -+ RTL8366RB_CHIP_CTRL_RESET_HW); -+ do { -+ msleep(1); -+ if (rtl8366_smi_read_reg(smi, RTL8366RB_RESET_CTRL_REG, &data)) -+ return -EIO; -+ -+ if (!(data & RTL8366RB_CHIP_CTRL_RESET_HW)) -+ break; -+ } while (--timeout); -+ -+ if (!timeout) { -+ printk("Timeout waiting for the switch to reset\n"); -+ return -EIO; -+ } -+ -+ return 0; -+} -+ -+static int rtl8366rb_setup(struct rtl8366_smi *smi) -+{ -+ int err; -+#ifdef CONFIG_OF -+ unsigned i; -+ struct device_node *np; -+ unsigned num_initvals; -+ const __be32 *paddr; -+ -+ np = smi->parent->of_node; -+ -+ paddr = of_get_property(np, "realtek,initvals", &num_initvals); -+ if (paddr) { -+ dev_info(smi->parent, "applying initvals from DTS\n"); -+ -+ if (num_initvals < (2 * sizeof(*paddr))) -+ return -EINVAL; -+ -+ num_initvals /= sizeof(*paddr); -+ -+ for (i = 0; i < num_initvals - 1; i += 2) { -+ u32 reg = be32_to_cpup(paddr + i); -+ u32 val = be32_to_cpup(paddr + i + 1); -+ -+ REG_WR(smi, reg, val); -+ } -+ } -+#endif -+ -+ /* set maximum packet length to 1536 bytes */ -+ REG_RMW(smi, RTL8366RB_SGCR, RTL8366RB_SGCR_MAX_LENGTH_MASK, -+ RTL8366RB_SGCR_MAX_LENGTH_1536); -+ -+ /* enable learning for all ports */ -+ REG_WR(smi, RTL8366RB_SSCR0, 0); -+ -+ /* enable auto ageing for all ports */ -+ REG_WR(smi, RTL8366RB_SSCR1, 0); -+ -+ /* -+ * discard VLAN tagged packets if the port is not a member of -+ * the VLAN with which the packets is associated. -+ */ -+ REG_WR(smi, RTL8366RB_VLAN_INGRESS_CTRL2_REG, RTL8366RB_PORT_ALL); -+ -+ /* don't drop packets whose DA has not been learned */ -+ REG_RMW(smi, RTL8366RB_SSCR2, RTL8366RB_SSCR2_DROP_UNKNOWN_DA, 0); -+ -+ return 0; -+} -+ -+static int rtl8366rb_read_phy_reg(struct rtl8366_smi *smi, -+ u32 phy_no, u32 page, u32 addr, u32 *data) -+{ -+ u32 reg; -+ int ret; -+ -+ if (phy_no > RTL8366RB_PHY_NO_MAX) -+ return -EINVAL; -+ -+ if (page > RTL8366RB_PHY_PAGE_MAX) -+ return -EINVAL; -+ -+ if (addr > RTL8366RB_PHY_ADDR_MAX) -+ return -EINVAL; -+ -+ ret = rtl8366_smi_write_reg(smi, RTL8366RB_PHY_ACCESS_CTRL_REG, -+ RTL8366RB_PHY_CTRL_READ); -+ if (ret) -+ return ret; -+ -+ reg = 0x8000 | (1 << (phy_no + RTL8366RB_PHY_NO_OFFSET)) | -+ ((page << RTL8366RB_PHY_PAGE_OFFSET) & RTL8366RB_PHY_PAGE_MASK) | -+ (addr & RTL8366RB_PHY_REG_MASK); -+ -+ ret = rtl8366_smi_write_reg(smi, reg, 0); -+ if (ret) -+ return ret; -+ -+ ret = rtl8366_smi_read_reg(smi, RTL8366RB_PHY_ACCESS_DATA_REG, data); -+ if (ret) -+ return ret; -+ -+ return 0; -+} -+ -+static int rtl8366rb_write_phy_reg(struct rtl8366_smi *smi, -+ u32 phy_no, u32 page, u32 addr, u32 data) -+{ -+ u32 reg; -+ int ret; -+ -+ if (phy_no > RTL8366RB_PHY_NO_MAX) -+ return -EINVAL; -+ -+ if (page > RTL8366RB_PHY_PAGE_MAX) -+ return -EINVAL; -+ -+ if (addr > RTL8366RB_PHY_ADDR_MAX) -+ return -EINVAL; -+ -+ ret = rtl8366_smi_write_reg(smi, RTL8366RB_PHY_ACCESS_CTRL_REG, -+ RTL8366RB_PHY_CTRL_WRITE); -+ if (ret) -+ return ret; -+ -+ reg = 0x8000 | (1 << (phy_no + RTL8366RB_PHY_NO_OFFSET)) | -+ ((page << RTL8366RB_PHY_PAGE_OFFSET) & RTL8366RB_PHY_PAGE_MASK) | -+ (addr & RTL8366RB_PHY_REG_MASK); -+ -+ ret = rtl8366_smi_write_reg(smi, reg, data); -+ if (ret) -+ return ret; -+ -+ return 0; -+} -+ -+static int rtl8366rb_get_mib_counter(struct rtl8366_smi *smi, int counter, -+ int port, unsigned long long *val) -+{ -+ int i; -+ int err; -+ u32 addr, data; -+ u64 mibvalue; -+ -+ if (port > RTL8366RB_NUM_PORTS || counter >= RTL8366RB_MIB_COUNT) -+ return -EINVAL; -+ -+ addr = RTL8366RB_MIB_COUNTER_BASE + -+ RTL8366RB_MIB_COUNTER_PORT_OFFSET * (port) + -+ rtl8366rb_mib_counters[counter].offset; -+ -+ /* -+ * Writing access counter address first -+ * then ASIC will prepare 64bits counter wait for being retrived -+ */ -+ data = 0; /* writing data will be discard by ASIC */ -+ err = rtl8366_smi_write_reg(smi, addr, data); -+ if (err) -+ return err; -+ -+ /* read MIB control register */ -+ err = rtl8366_smi_read_reg(smi, RTL8366RB_MIB_CTRL_REG, &data); -+ if (err) -+ return err; -+ -+ if (data & RTL8366RB_MIB_CTRL_BUSY_MASK) -+ return -EBUSY; -+ -+ if (data & RTL8366RB_MIB_CTRL_RESET_MASK) -+ return -EIO; -+ -+ mibvalue = 0; -+ for (i = rtl8366rb_mib_counters[counter].length; i > 0; i--) { -+ err = rtl8366_smi_read_reg(smi, addr + (i - 1), &data); -+ if (err) -+ return err; -+ -+ mibvalue = (mibvalue << 16) | (data & 0xFFFF); -+ } -+ -+ *val = mibvalue; -+ return 0; -+} -+ -+static int rtl8366rb_get_vlan_4k(struct rtl8366_smi *smi, u32 vid, -+ struct rtl8366_vlan_4k *vlan4k) -+{ -+ u32 data[3]; -+ int err; -+ int i; -+ -+ memset(vlan4k, '\0', sizeof(struct rtl8366_vlan_4k)); -+ -+ if (vid >= RTL8366RB_NUM_VIDS) -+ return -EINVAL; -+ -+ /* write VID */ -+ err = rtl8366_smi_write_reg(smi, RTL8366RB_VLAN_TABLE_WRITE_BASE, -+ vid & RTL8366RB_VLAN_VID_MASK); -+ if (err) -+ return err; -+ -+ /* write table access control word */ -+ err = rtl8366_smi_write_reg(smi, RTL8366RB_TABLE_ACCESS_CTRL_REG, -+ RTL8366RB_TABLE_VLAN_READ_CTRL); -+ if (err) -+ return err; -+ -+ for (i = 0; i < 3; i++) { -+ err = rtl8366_smi_read_reg(smi, -+ RTL8366RB_VLAN_TABLE_READ_BASE + i, -+ &data[i]); -+ if (err) -+ return err; -+ } -+ -+ vlan4k->vid = vid; -+ vlan4k->untag = (data[1] >> RTL8366RB_VLAN_UNTAG_SHIFT) & -+ RTL8366RB_VLAN_UNTAG_MASK; -+ vlan4k->member = data[1] & RTL8366RB_VLAN_MEMBER_MASK; -+ vlan4k->fid = data[2] & RTL8366RB_VLAN_FID_MASK; -+ -+ return 0; -+} -+ -+static int rtl8366rb_set_vlan_4k(struct rtl8366_smi *smi, -+ const struct rtl8366_vlan_4k *vlan4k) -+{ -+ u32 data[3]; -+ int err; -+ int i; -+ -+ if (vlan4k->vid >= RTL8366RB_NUM_VIDS || -+ vlan4k->member > RTL8366RB_VLAN_MEMBER_MASK || -+ vlan4k->untag > RTL8366RB_VLAN_UNTAG_MASK || -+ vlan4k->fid > RTL8366RB_FIDMAX) -+ return -EINVAL; -+ -+ data[0] = vlan4k->vid & RTL8366RB_VLAN_VID_MASK; -+ data[1] = (vlan4k->member & RTL8366RB_VLAN_MEMBER_MASK) | -+ ((vlan4k->untag & RTL8366RB_VLAN_UNTAG_MASK) << -+ RTL8366RB_VLAN_UNTAG_SHIFT); -+ data[2] = vlan4k->fid & RTL8366RB_VLAN_FID_MASK; -+ -+ for (i = 0; i < 3; i++) { -+ err = rtl8366_smi_write_reg(smi, -+ RTL8366RB_VLAN_TABLE_WRITE_BASE + i, -+ data[i]); -+ if (err) -+ return err; -+ } -+ -+ /* write table access control word */ -+ err = rtl8366_smi_write_reg(smi, RTL8366RB_TABLE_ACCESS_CTRL_REG, -+ RTL8366RB_TABLE_VLAN_WRITE_CTRL); -+ -+ return err; -+} -+ -+static int rtl8366rb_get_vlan_mc(struct rtl8366_smi *smi, u32 index, -+ struct rtl8366_vlan_mc *vlanmc) -+{ -+ u32 data[3]; -+ int err; -+ int i; -+ -+ memset(vlanmc, '\0', sizeof(struct rtl8366_vlan_mc)); -+ -+ if (index >= RTL8366RB_NUM_VLANS) -+ return -EINVAL; -+ -+ for (i = 0; i < 3; i++) { -+ err = rtl8366_smi_read_reg(smi, -+ RTL8366RB_VLAN_MC_BASE(index) + i, -+ &data[i]); -+ if (err) -+ return err; -+ } -+ -+ vlanmc->vid = data[0] & RTL8366RB_VLAN_VID_MASK; -+ vlanmc->priority = (data[0] >> RTL8366RB_VLAN_PRIORITY_SHIFT) & -+ RTL8366RB_VLAN_PRIORITY_MASK; -+ vlanmc->untag = (data[1] >> RTL8366RB_VLAN_UNTAG_SHIFT) & -+ RTL8366RB_VLAN_UNTAG_MASK; -+ vlanmc->member = data[1] & RTL8366RB_VLAN_MEMBER_MASK; -+ vlanmc->fid = data[2] & RTL8366RB_VLAN_FID_MASK; -+ -+ return 0; -+} -+ -+static int rtl8366rb_set_vlan_mc(struct rtl8366_smi *smi, u32 index, -+ const struct rtl8366_vlan_mc *vlanmc) -+{ -+ u32 data[3]; -+ int err; -+ int i; -+ -+ if (index >= RTL8366RB_NUM_VLANS || -+ vlanmc->vid >= RTL8366RB_NUM_VIDS || -+ vlanmc->priority > RTL8366RB_PRIORITYMAX || -+ vlanmc->member > RTL8366RB_VLAN_MEMBER_MASK || -+ vlanmc->untag > RTL8366RB_VLAN_UNTAG_MASK || -+ vlanmc->fid > RTL8366RB_FIDMAX) -+ return -EINVAL; -+ -+ data[0] = (vlanmc->vid & RTL8366RB_VLAN_VID_MASK) | -+ ((vlanmc->priority & RTL8366RB_VLAN_PRIORITY_MASK) << -+ RTL8366RB_VLAN_PRIORITY_SHIFT); -+ data[1] = (vlanmc->member & RTL8366RB_VLAN_MEMBER_MASK) | -+ ((vlanmc->untag & RTL8366RB_VLAN_UNTAG_MASK) << -+ RTL8366RB_VLAN_UNTAG_SHIFT); -+ data[2] = vlanmc->fid & RTL8366RB_VLAN_FID_MASK; -+ -+ for (i = 0; i < 3; i++) { -+ err = rtl8366_smi_write_reg(smi, -+ RTL8366RB_VLAN_MC_BASE(index) + i, -+ data[i]); -+ if (err) -+ return err; -+ } -+ -+ return 0; -+} -+ -+static int rtl8366rb_get_mc_index(struct rtl8366_smi *smi, int port, int *val) -+{ -+ u32 data; -+ int err; -+ -+ if (port >= RTL8366RB_NUM_PORTS) -+ return -EINVAL; -+ -+ err = rtl8366_smi_read_reg(smi, RTL8366RB_PORT_VLAN_CTRL_REG(port), -+ &data); -+ if (err) -+ return err; -+ -+ *val = (data >> RTL8366RB_PORT_VLAN_CTRL_SHIFT(port)) & -+ RTL8366RB_PORT_VLAN_CTRL_MASK; -+ -+ return 0; -+ -+} -+ -+static int rtl8366rb_set_mc_index(struct rtl8366_smi *smi, int port, int index) -+{ -+ if (port >= RTL8366RB_NUM_PORTS || index >= RTL8366RB_NUM_VLANS) -+ return -EINVAL; -+ -+ return rtl8366_smi_rmwr(smi, RTL8366RB_PORT_VLAN_CTRL_REG(port), -+ RTL8366RB_PORT_VLAN_CTRL_MASK << -+ RTL8366RB_PORT_VLAN_CTRL_SHIFT(port), -+ (index & RTL8366RB_PORT_VLAN_CTRL_MASK) << -+ RTL8366RB_PORT_VLAN_CTRL_SHIFT(port)); -+} -+ -+static int rtl8366rb_is_vlan_valid(struct rtl8366_smi *smi, unsigned vlan) -+{ -+ unsigned max = RTL8366RB_NUM_VLANS; -+ -+ if (smi->vlan4k_enabled) -+ max = RTL8366RB_NUM_VIDS - 1; -+ -+ if (vlan == 0 || vlan >= max) -+ return 0; -+ -+ return 1; -+} -+ -+static int rtl8366rb_enable_vlan(struct rtl8366_smi *smi, int enable) -+{ -+ return rtl8366_smi_rmwr(smi, RTL8366RB_SGCR, RTL8366RB_SGCR_EN_VLAN, -+ (enable) ? RTL8366RB_SGCR_EN_VLAN : 0); -+} -+ -+static int rtl8366rb_enable_vlan4k(struct rtl8366_smi *smi, int enable) -+{ -+ return rtl8366_smi_rmwr(smi, RTL8366RB_SGCR, -+ RTL8366RB_SGCR_EN_VLAN_4KTB, -+ (enable) ? RTL8366RB_SGCR_EN_VLAN_4KTB : 0); -+} -+ -+static int rtl8366rb_enable_port(struct rtl8366_smi *smi, int port, int enable) -+{ -+ return rtl8366_smi_rmwr(smi, RTL8366RB_PECR, (1 << port), -+ (enable) ? 0 : (1 << port)); -+} -+ -+static int rtl8366rb_sw_reset_mibs(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ -+ return rtl8366_smi_rmwr(smi, RTL8366RB_MIB_CTRL_REG, 0, -+ RTL8366RB_MIB_CTRL_GLOBAL_RESET); -+} -+ -+static int rtl8366rb_sw_get_blinkrate(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data; -+ -+ rtl8366_smi_read_reg(smi, RTL8366RB_LED_BLINKRATE_REG, &data); -+ -+ val->value.i = (data & (RTL8366RB_LED_BLINKRATE_MASK)); -+ -+ return 0; -+} -+ -+static int rtl8366rb_sw_set_blinkrate(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ -+ if (val->value.i >= 6) -+ return -EINVAL; -+ -+ return rtl8366_smi_rmwr(smi, RTL8366RB_LED_BLINKRATE_REG, -+ RTL8366RB_LED_BLINKRATE_MASK, -+ val->value.i); -+} -+ -+static int rtl8366rb_sw_get_learning_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data; -+ -+ rtl8366_smi_read_reg(smi, RTL8366RB_SSCR0, &data); -+ val->value.i = !data; -+ -+ return 0; -+} -+ -+ -+static int rtl8366rb_sw_set_learning_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 portmask = 0; -+ int err = 0; -+ -+ if (!val->value.i) -+ portmask = RTL8366RB_PORT_ALL; -+ -+ /* set learning for all ports */ -+ REG_WR(smi, RTL8366RB_SSCR0, portmask); -+ -+ /* set auto ageing for all ports */ -+ REG_WR(smi, RTL8366RB_SSCR1, portmask); -+ -+ return 0; -+} -+ -+static int rtl8366rb_sw_get_port_link(struct switch_dev *dev, -+ int port, -+ struct switch_port_link *link) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data = 0; -+ u32 speed; -+ -+ if (port >= RTL8366RB_NUM_PORTS) -+ return -EINVAL; -+ -+ rtl8366_smi_read_reg(smi, RTL8366RB_PORT_LINK_STATUS_BASE + (port / 2), -+ &data); -+ -+ if (port % 2) -+ data = data >> 8; -+ -+ link->link = !!(data & RTL8366RB_PORT_STATUS_LINK_MASK); -+ if (!link->link) -+ return 0; -+ -+ link->duplex = !!(data & RTL8366RB_PORT_STATUS_DUPLEX_MASK); -+ link->rx_flow = !!(data & RTL8366RB_PORT_STATUS_RXPAUSE_MASK); -+ link->tx_flow = !!(data & RTL8366RB_PORT_STATUS_TXPAUSE_MASK); -+ link->aneg = !!(data & RTL8366RB_PORT_STATUS_AN_MASK); -+ -+ speed = (data & RTL8366RB_PORT_STATUS_SPEED_MASK); -+ switch (speed) { -+ case 0: -+ link->speed = SWITCH_PORT_SPEED_10; -+ break; -+ case 1: -+ link->speed = SWITCH_PORT_SPEED_100; -+ break; -+ case 2: -+ link->speed = SWITCH_PORT_SPEED_1000; -+ break; -+ default: -+ link->speed = SWITCH_PORT_SPEED_UNKNOWN; -+ break; -+ } -+ -+ return 0; -+} -+ -+static int rtl8366rb_sw_set_port_led(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data; -+ u32 mask; -+ u32 reg; -+ -+ if (val->port_vlan >= RTL8366RB_NUM_PORTS) -+ return -EINVAL; -+ -+ if (val->port_vlan == RTL8366RB_PORT_NUM_CPU) { -+ reg = RTL8366RB_LED_BLINKRATE_REG; -+ mask = 0xF << 4; -+ data = val->value.i << 4; -+ } else { -+ reg = RTL8366RB_LED_CTRL_REG; -+ mask = 0xF << (val->port_vlan * 4), -+ data = val->value.i << (val->port_vlan * 4); -+ } -+ -+ return rtl8366_smi_rmwr(smi, reg, mask, data); -+} -+ -+static int rtl8366rb_sw_get_port_led(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data = 0; -+ -+ if (val->port_vlan >= RTL8366RB_NUM_LEDGROUPS) -+ return -EINVAL; -+ -+ rtl8366_smi_read_reg(smi, RTL8366RB_LED_CTRL_REG, &data); -+ val->value.i = (data >> (val->port_vlan * 4)) & 0x000F; -+ -+ return 0; -+} -+ -+static int rtl8366rb_sw_set_port_disable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 mask, data; -+ -+ if (val->port_vlan >= RTL8366RB_NUM_PORTS) -+ return -EINVAL; -+ -+ mask = 1 << val->port_vlan ; -+ if (val->value.i) -+ data = mask; -+ else -+ data = 0; -+ -+ return rtl8366_smi_rmwr(smi, RTL8366RB_PECR, mask, data); -+} -+ -+static int rtl8366rb_sw_get_port_disable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data; -+ -+ if (val->port_vlan >= RTL8366RB_NUM_PORTS) -+ return -EINVAL; -+ -+ rtl8366_smi_read_reg(smi, RTL8366RB_PECR, &data); -+ if (data & (1 << val->port_vlan)) -+ val->value.i = 1; -+ else -+ val->value.i = 0; -+ -+ return 0; -+} -+ -+static int rtl8366rb_sw_set_port_rate_in(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ -+ if (val->port_vlan >= RTL8366RB_NUM_PORTS) -+ return -EINVAL; -+ -+ if (val->value.i > 0 && val->value.i < RTL8366RB_BDTH_SW_MAX) -+ val->value.i = (val->value.i - 1) / RTL8366RB_BDTH_UNIT; -+ else -+ val->value.i = RTL8366RB_BDTH_REG_DEFAULT; -+ -+ return rtl8366_smi_rmwr(smi, RTL8366RB_IB_REG(val->port_vlan), -+ RTL8366RB_IB_BDTH_MASK | RTL8366RB_IB_PREIFG_MASK, -+ val->value.i | -+ (RTL8366RB_QOS_DEFAULT_PREIFG << RTL8366RB_IB_PREIFG_OFFSET)); -+ -+} -+ -+static int rtl8366rb_sw_get_port_rate_in(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data; -+ -+ if (val->port_vlan >= RTL8366RB_NUM_PORTS) -+ return -EINVAL; -+ -+ rtl8366_smi_read_reg(smi, RTL8366RB_IB_REG(val->port_vlan), &data); -+ data &= RTL8366RB_IB_BDTH_MASK; -+ if (data < RTL8366RB_IB_BDTH_MASK) -+ data += 1; -+ -+ val->value.i = (int)data * RTL8366RB_BDTH_UNIT; -+ -+ return 0; -+} -+ -+static int rtl8366rb_sw_set_port_rate_out(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ -+ if (val->port_vlan >= RTL8366RB_NUM_PORTS) -+ return -EINVAL; -+ -+ rtl8366_smi_rmwr(smi, RTL8366RB_EB_PREIFG_REG, -+ RTL8366RB_EB_PREIFG_MASK, -+ (RTL8366RB_QOS_DEFAULT_PREIFG << RTL8366RB_EB_PREIFG_OFFSET)); -+ -+ if (val->value.i > 0 && val->value.i < RTL8366RB_BDTH_SW_MAX) -+ val->value.i = (val->value.i - 1) / RTL8366RB_BDTH_UNIT; -+ else -+ val->value.i = RTL8366RB_BDTH_REG_DEFAULT; -+ -+ return rtl8366_smi_rmwr(smi, RTL8366RB_EB_REG(val->port_vlan), -+ RTL8366RB_EB_BDTH_MASK, val->value.i ); -+ -+} -+ -+static int rtl8366rb_sw_get_port_rate_out(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data; -+ -+ if (val->port_vlan >= RTL8366RB_NUM_PORTS) -+ return -EINVAL; -+ -+ rtl8366_smi_read_reg(smi, RTL8366RB_EB_REG(val->port_vlan), &data); -+ data &= RTL8366RB_EB_BDTH_MASK; -+ if (data < RTL8366RB_EB_BDTH_MASK) -+ data += 1; -+ -+ val->value.i = (int)data * RTL8366RB_BDTH_UNIT; -+ -+ return 0; -+} -+ -+static int rtl8366rb_sw_set_qos_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data; -+ -+ if (val->value.i) -+ data = RTL8366RB_QOS_MASK; -+ else -+ data = 0; -+ -+ return rtl8366_smi_rmwr(smi, RTL8366RB_SGCR, RTL8366RB_QOS_MASK, data); -+} -+ -+static int rtl8366rb_sw_get_qos_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data; -+ -+ rtl8366_smi_read_reg(smi, RTL8366RB_SGCR, &data); -+ if (data & RTL8366RB_QOS_MASK) -+ val->value.i = 1; -+ else -+ val->value.i = 0; -+ -+ return 0; -+} -+ -+static int rtl8366rb_sw_set_mirror_rx_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data; -+ -+ if (val->value.i) -+ data = RTL8366RB_PMCR_MIRROR_RX; -+ else -+ data = 0; -+ -+ return rtl8366_smi_rmwr(smi, RTL8366RB_PMCR, RTL8366RB_PMCR_MIRROR_RX, data); -+} -+ -+static int rtl8366rb_sw_get_mirror_rx_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data; -+ -+ rtl8366_smi_read_reg(smi, RTL8366RB_PMCR, &data); -+ if (data & RTL8366RB_PMCR_MIRROR_RX) -+ val->value.i = 1; -+ else -+ val->value.i = 0; -+ -+ return 0; -+} -+ -+static int rtl8366rb_sw_set_mirror_tx_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data; -+ -+ if (val->value.i) -+ data = RTL8366RB_PMCR_MIRROR_TX; -+ else -+ data = 0; -+ -+ return rtl8366_smi_rmwr(smi, RTL8366RB_PMCR, RTL8366RB_PMCR_MIRROR_TX, data); -+} -+ -+static int rtl8366rb_sw_get_mirror_tx_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data; -+ -+ rtl8366_smi_read_reg(smi, RTL8366RB_PMCR, &data); -+ if (data & RTL8366RB_PMCR_MIRROR_TX) -+ val->value.i = 1; -+ else -+ val->value.i = 0; -+ -+ return 0; -+} -+ -+static int rtl8366rb_sw_set_monitor_isolation_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data; -+ -+ if (val->value.i) -+ data = RTL8366RB_PMCR_MIRROR_ISO; -+ else -+ data = 0; -+ -+ return rtl8366_smi_rmwr(smi, RTL8366RB_PMCR, RTL8366RB_PMCR_MIRROR_ISO, data); -+} -+ -+static int rtl8366rb_sw_get_monitor_isolation_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data; -+ -+ rtl8366_smi_read_reg(smi, RTL8366RB_PMCR, &data); -+ if (data & RTL8366RB_PMCR_MIRROR_ISO) -+ val->value.i = 1; -+ else -+ val->value.i = 0; -+ -+ return 0; -+} -+ -+static int rtl8366rb_sw_set_mirror_pause_frames_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data; -+ -+ if (val->value.i) -+ data = RTL8366RB_PMCR_MIRROR_SPC; -+ else -+ data = 0; -+ -+ return rtl8366_smi_rmwr(smi, RTL8366RB_PMCR, RTL8366RB_PMCR_MIRROR_SPC, data); -+} -+ -+static int rtl8366rb_sw_get_mirror_pause_frames_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data; -+ -+ rtl8366_smi_read_reg(smi, RTL8366RB_PMCR, &data); -+ if (data & RTL8366RB_PMCR_MIRROR_SPC) -+ val->value.i = 1; -+ else -+ val->value.i = 0; -+ -+ return 0; -+} -+ -+static int rtl8366rb_sw_set_mirror_monitor_port(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data; -+ -+ data = RTL8366RB_PMCR_MONITOR_PORT(val->value.i); -+ -+ return rtl8366_smi_rmwr(smi, RTL8366RB_PMCR, RTL8366RB_PMCR_MONITOR_PORT_MASK, data); -+} -+ -+static int rtl8366rb_sw_get_mirror_monitor_port(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data; -+ -+ rtl8366_smi_read_reg(smi, RTL8366RB_PMCR, &data); -+ val->value.i = (data & RTL8366RB_PMCR_MONITOR_PORT_MASK) >> 4; -+ -+ return 0; -+} -+ -+static int rtl8366rb_sw_set_mirror_source_port(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data; -+ -+ data = RTL8366RB_PMCR_SOURCE_PORT(val->value.i); -+ -+ return rtl8366_smi_rmwr(smi, RTL8366RB_PMCR, RTL8366RB_PMCR_SOURCE_PORT_MASK, data); -+} -+ -+static int rtl8366rb_sw_get_mirror_source_port(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data; -+ -+ rtl8366_smi_read_reg(smi, RTL8366RB_PMCR, &data); -+ val->value.i = data & RTL8366RB_PMCR_SOURCE_PORT_MASK; -+ -+ return 0; -+} -+ -+static int rtl8366rb_sw_reset_port_mibs(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ -+ if (val->port_vlan >= RTL8366RB_NUM_PORTS) -+ return -EINVAL; -+ -+ return rtl8366_smi_rmwr(smi, RTL8366RB_MIB_CTRL_REG, 0, -+ RTL8366RB_MIB_CTRL_PORT_RESET(val->port_vlan)); -+} -+ -+static int rtl8366rb_sw_get_port_stats(struct switch_dev *dev, int port, -+ struct switch_port_stats *stats) -+{ -+ return (rtl8366_sw_get_port_stats(dev, port, stats, -+ RTL8366RB_MIB_TXB_ID, RTL8366RB_MIB_RXB_ID)); -+} -+ -+static struct switch_attr rtl8366rb_globals[] = { -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_learning", -+ .description = "Enable learning, enable aging", -+ .set = rtl8366rb_sw_set_learning_enable, -+ .get = rtl8366rb_sw_get_learning_enable, -+ .max = 1 -+ }, { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_vlan", -+ .description = "Enable VLAN mode", -+ .set = rtl8366_sw_set_vlan_enable, -+ .get = rtl8366_sw_get_vlan_enable, -+ .max = 1, -+ .ofs = 1 -+ }, { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_vlan4k", -+ .description = "Enable VLAN 4K mode", -+ .set = rtl8366_sw_set_vlan_enable, -+ .get = rtl8366_sw_get_vlan_enable, -+ .max = 1, -+ .ofs = 2 -+ }, { -+ .type = SWITCH_TYPE_NOVAL, -+ .name = "reset_mibs", -+ .description = "Reset all MIB counters", -+ .set = rtl8366rb_sw_reset_mibs, -+ }, { -+ .type = SWITCH_TYPE_INT, -+ .name = "blinkrate", -+ .description = "Get/Set LED blinking rate (0 = 43ms, 1 = 84ms," -+ " 2 = 120ms, 3 = 170ms, 4 = 340ms, 5 = 670ms)", -+ .set = rtl8366rb_sw_set_blinkrate, -+ .get = rtl8366rb_sw_get_blinkrate, -+ .max = 5 -+ }, { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_qos", -+ .description = "Enable QOS", -+ .set = rtl8366rb_sw_set_qos_enable, -+ .get = rtl8366rb_sw_get_qos_enable, -+ .max = 1 -+ }, { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_mirror_rx", -+ .description = "Enable mirroring of RX packets", -+ .set = rtl8366rb_sw_set_mirror_rx_enable, -+ .get = rtl8366rb_sw_get_mirror_rx_enable, -+ .max = 1 -+ }, { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_mirror_tx", -+ .description = "Enable mirroring of TX packets", -+ .set = rtl8366rb_sw_set_mirror_tx_enable, -+ .get = rtl8366rb_sw_get_mirror_tx_enable, -+ .max = 1 -+ }, { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_monitor_isolation", -+ .description = "Enable isolation of monitor port (TX packets will be dropped)", -+ .set = rtl8366rb_sw_set_monitor_isolation_enable, -+ .get = rtl8366rb_sw_get_monitor_isolation_enable, -+ .max = 1 -+ }, { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_mirror_pause_frames", -+ .description = "Enable mirroring of RX pause frames", -+ .set = rtl8366rb_sw_set_mirror_pause_frames_enable, -+ .get = rtl8366rb_sw_get_mirror_pause_frames_enable, -+ .max = 1 -+ }, { -+ .type = SWITCH_TYPE_INT, -+ .name = "mirror_monitor_port", -+ .description = "Mirror monitor port", -+ .set = rtl8366rb_sw_set_mirror_monitor_port, -+ .get = rtl8366rb_sw_get_mirror_monitor_port, -+ .max = 5 -+ }, { -+ .type = SWITCH_TYPE_INT, -+ .name = "mirror_source_port", -+ .description = "Mirror source port", -+ .set = rtl8366rb_sw_set_mirror_source_port, -+ .get = rtl8366rb_sw_get_mirror_source_port, -+ .max = 5 -+ }, -+}; -+ -+static struct switch_attr rtl8366rb_port[] = { -+ { -+ .type = SWITCH_TYPE_NOVAL, -+ .name = "reset_mib", -+ .description = "Reset single port MIB counters", -+ .set = rtl8366rb_sw_reset_port_mibs, -+ }, { -+ .type = SWITCH_TYPE_STRING, -+ .name = "mib", -+ .description = "Get MIB counters for port", -+ .max = 33, -+ .set = NULL, -+ .get = rtl8366_sw_get_port_mib, -+ }, { -+ .type = SWITCH_TYPE_INT, -+ .name = "led", -+ .description = "Get/Set port group (0 - 3) led mode (0 - 15)", -+ .max = 15, -+ .set = rtl8366rb_sw_set_port_led, -+ .get = rtl8366rb_sw_get_port_led, -+ }, { -+ .type = SWITCH_TYPE_INT, -+ .name = "disable", -+ .description = "Get/Set port state (enabled or disabled)", -+ .max = 1, -+ .set = rtl8366rb_sw_set_port_disable, -+ .get = rtl8366rb_sw_get_port_disable, -+ }, { -+ .type = SWITCH_TYPE_INT, -+ .name = "rate_in", -+ .description = "Get/Set port ingress (incoming) bandwidth limit in kbps", -+ .max = RTL8366RB_BDTH_SW_MAX, -+ .set = rtl8366rb_sw_set_port_rate_in, -+ .get = rtl8366rb_sw_get_port_rate_in, -+ }, { -+ .type = SWITCH_TYPE_INT, -+ .name = "rate_out", -+ .description = "Get/Set port egress (outgoing) bandwidth limit in kbps", -+ .max = RTL8366RB_BDTH_SW_MAX, -+ .set = rtl8366rb_sw_set_port_rate_out, -+ .get = rtl8366rb_sw_get_port_rate_out, -+ }, -+}; -+ -+static struct switch_attr rtl8366rb_vlan[] = { -+ { -+ .type = SWITCH_TYPE_STRING, -+ .name = "info", -+ .description = "Get vlan information", -+ .max = 1, -+ .set = NULL, -+ .get = rtl8366_sw_get_vlan_info, -+ }, { -+ .type = SWITCH_TYPE_INT, -+ .name = "fid", -+ .description = "Get/Set vlan FID", -+ .max = RTL8366RB_FIDMAX, -+ .set = rtl8366_sw_set_vlan_fid, -+ .get = rtl8366_sw_get_vlan_fid, -+ }, -+}; -+ -+static const struct switch_dev_ops rtl8366_ops = { -+ .attr_global = { -+ .attr = rtl8366rb_globals, -+ .n_attr = ARRAY_SIZE(rtl8366rb_globals), -+ }, -+ .attr_port = { -+ .attr = rtl8366rb_port, -+ .n_attr = ARRAY_SIZE(rtl8366rb_port), -+ }, -+ .attr_vlan = { -+ .attr = rtl8366rb_vlan, -+ .n_attr = ARRAY_SIZE(rtl8366rb_vlan), -+ }, -+ -+ .get_vlan_ports = rtl8366_sw_get_vlan_ports, -+ .set_vlan_ports = rtl8366_sw_set_vlan_ports, -+ .get_port_pvid = rtl8366_sw_get_port_pvid, -+ .set_port_pvid = rtl8366_sw_set_port_pvid, -+ .reset_switch = rtl8366_sw_reset_switch, -+ .get_port_link = rtl8366rb_sw_get_port_link, -+ .get_port_stats = rtl8366rb_sw_get_port_stats, -+}; -+ -+static int rtl8366rb_switch_init(struct rtl8366_smi *smi) -+{ -+ struct switch_dev *dev = &smi->sw_dev; -+ int err; -+ -+ dev->name = "RTL8366RB"; -+ dev->cpu_port = RTL8366RB_PORT_NUM_CPU; -+ dev->ports = RTL8366RB_NUM_PORTS; -+ dev->vlans = RTL8366RB_NUM_VIDS; -+ dev->ops = &rtl8366_ops; -+ dev->alias = dev_name(smi->parent); -+ -+ err = register_switch(dev, NULL); -+ if (err) -+ dev_err(smi->parent, "switch registration failed\n"); -+ -+ return err; -+} -+ -+static void rtl8366rb_switch_cleanup(struct rtl8366_smi *smi) -+{ -+ unregister_switch(&smi->sw_dev); -+} -+ -+static int rtl8366rb_mii_read(struct mii_bus *bus, int addr, int reg) -+{ -+ struct rtl8366_smi *smi = bus->priv; -+ u32 val = 0; -+ int err; -+ -+ err = rtl8366rb_read_phy_reg(smi, addr, 0, reg, &val); -+ if (err) -+ return 0xffff; -+ -+ return val; -+} -+ -+static int rtl8366rb_mii_write(struct mii_bus *bus, int addr, int reg, u16 val) -+{ -+ struct rtl8366_smi *smi = bus->priv; -+ u32 t; -+ int err; -+ -+ err = rtl8366rb_write_phy_reg(smi, addr, 0, reg, val); -+ /* flush write */ -+ (void) rtl8366rb_read_phy_reg(smi, addr, 0, reg, &t); -+ -+ return err; -+} -+ -+static int rtl8366rb_detect(struct rtl8366_smi *smi) -+{ -+ u32 chip_id = 0; -+ u32 chip_ver = 0; -+ int ret; -+ -+ ret = rtl8366_smi_read_reg(smi, RTL8366RB_CHIP_ID_REG, &chip_id); -+ if (ret) { -+ dev_err(smi->parent, "unable to read chip id\n"); -+ return ret; -+ } -+ -+ switch (chip_id) { -+ case RTL8366RB_CHIP_ID_8366: -+ break; -+ default: -+ dev_err(smi->parent, "unknown chip id (%04x)\n", chip_id); -+ return -ENODEV; -+ } -+ -+ ret = rtl8366_smi_read_reg(smi, RTL8366RB_CHIP_VERSION_CTRL_REG, -+ &chip_ver); -+ if (ret) { -+ dev_err(smi->parent, "unable to read chip version\n"); -+ return ret; -+ } -+ -+ dev_info(smi->parent, "RTL%04x ver. %u chip found\n", -+ chip_id, chip_ver & RTL8366RB_CHIP_VERSION_MASK); -+ -+ return 0; -+} -+ -+static struct rtl8366_smi_ops rtl8366rb_smi_ops = { -+ .detect = rtl8366rb_detect, -+ .reset_chip = rtl8366rb_reset_chip, -+ .setup = rtl8366rb_setup, -+ -+ .mii_read = rtl8366rb_mii_read, -+ .mii_write = rtl8366rb_mii_write, -+ -+ .get_vlan_mc = rtl8366rb_get_vlan_mc, -+ .set_vlan_mc = rtl8366rb_set_vlan_mc, -+ .get_vlan_4k = rtl8366rb_get_vlan_4k, -+ .set_vlan_4k = rtl8366rb_set_vlan_4k, -+ .get_mc_index = rtl8366rb_get_mc_index, -+ .set_mc_index = rtl8366rb_set_mc_index, -+ .get_mib_counter = rtl8366rb_get_mib_counter, -+ .is_vlan_valid = rtl8366rb_is_vlan_valid, -+ .enable_vlan = rtl8366rb_enable_vlan, -+ .enable_vlan4k = rtl8366rb_enable_vlan4k, -+ .enable_port = rtl8366rb_enable_port, -+}; -+ -+static int rtl8366rb_probe(struct platform_device *pdev) -+{ -+ static int rtl8366_smi_version_printed; -+ struct rtl8366_smi *smi; -+ int err; -+ -+ if (!rtl8366_smi_version_printed++) -+ printk(KERN_NOTICE RTL8366RB_DRIVER_DESC -+ " version " RTL8366RB_DRIVER_VER"\n"); -+ -+ smi = rtl8366_smi_probe(pdev); -+ if (IS_ERR(smi)) -+ return PTR_ERR(smi); -+ -+ smi->clk_delay = 10; -+ smi->cmd_read = 0xa9; -+ smi->cmd_write = 0xa8; -+ smi->ops = &rtl8366rb_smi_ops; -+ smi->cpu_port = RTL8366RB_PORT_NUM_CPU; -+ smi->num_ports = RTL8366RB_NUM_PORTS; -+ smi->num_vlan_mc = RTL8366RB_NUM_VLANS; -+ smi->mib_counters = rtl8366rb_mib_counters; -+ smi->num_mib_counters = ARRAY_SIZE(rtl8366rb_mib_counters); -+ -+ err = rtl8366_smi_init(smi); -+ if (err) -+ goto err_free_smi; -+ -+ platform_set_drvdata(pdev, smi); -+ -+ err = rtl8366rb_switch_init(smi); -+ if (err) -+ goto err_clear_drvdata; -+ -+ return 0; -+ -+ err_clear_drvdata: -+ platform_set_drvdata(pdev, NULL); -+ rtl8366_smi_cleanup(smi); -+ err_free_smi: -+ kfree(smi); -+ return err; -+} -+ -+static void rtl8366rb_remove(struct platform_device *pdev) -+{ -+ struct rtl8366_smi *smi = platform_get_drvdata(pdev); -+ -+ if (smi) { -+ rtl8366rb_switch_cleanup(smi); -+ platform_set_drvdata(pdev, NULL); -+ rtl8366_smi_cleanup(smi); -+ kfree(smi); -+ } -+} -+ -+#ifdef CONFIG_OF -+static const struct of_device_id rtl8366rb_match[] = { -+ { .compatible = "realtek,rtl8366rb" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, rtl8366rb_match); -+#endif -+ -+static struct platform_driver rtl8366rb_driver = { -+ .driver = { -+ .name = RTL8366RB_DRIVER_NAME, -+ .of_match_table = of_match_ptr(rtl8366rb_match), -+ }, -+ .probe = rtl8366rb_probe, -+ .remove_new = rtl8366rb_remove, -+}; -+ -+static int __init rtl8366rb_module_init(void) -+{ -+ return platform_driver_register(&rtl8366rb_driver); -+} -+module_init(rtl8366rb_module_init); -+ -+static void __exit rtl8366rb_module_exit(void) -+{ -+ platform_driver_unregister(&rtl8366rb_driver); -+} -+module_exit(rtl8366rb_module_exit); -+ -+MODULE_DESCRIPTION(RTL8366RB_DRIVER_DESC); -+MODULE_VERSION(RTL8366RB_DRIVER_VER); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_AUTHOR("Antti Seppälä "); -+MODULE_AUTHOR("Roman Yeryomin "); -+MODULE_AUTHOR("Colin Leitner "); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:" RTL8366RB_DRIVER_NAME); -diff --git a/drivers/net/phy/rtl8366s.c b/drivers/net/phy/rtl8366s.c -new file mode 100644 -index 000000000000..5458c5048728 ---- /dev/null -+++ b/drivers/net/phy/rtl8366s.c -@@ -0,0 +1,1317 @@ -+/* -+ * Platform driver for the Realtek RTL8366S ethernet switch -+ * -+ * Copyright (C) 2009-2010 Gabor Juhos -+ * Copyright (C) 2010 Antti Seppälä -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "rtl8366_smi.h" -+ -+#define RTL8366S_DRIVER_DESC "Realtek RTL8366S ethernet switch driver" -+#define RTL8366S_DRIVER_VER "0.2.2" -+ -+#define RTL8366S_PHY_NO_MAX 4 -+#define RTL8366S_PHY_PAGE_MAX 7 -+#define RTL8366S_PHY_ADDR_MAX 31 -+ -+/* Switch Global Configuration register */ -+#define RTL8366S_SGCR 0x0000 -+#define RTL8366S_SGCR_EN_BC_STORM_CTRL BIT(0) -+#define RTL8366S_SGCR_MAX_LENGTH(_x) (_x << 4) -+#define RTL8366S_SGCR_MAX_LENGTH_MASK RTL8366S_SGCR_MAX_LENGTH(0x3) -+#define RTL8366S_SGCR_MAX_LENGTH_1522 RTL8366S_SGCR_MAX_LENGTH(0x0) -+#define RTL8366S_SGCR_MAX_LENGTH_1536 RTL8366S_SGCR_MAX_LENGTH(0x1) -+#define RTL8366S_SGCR_MAX_LENGTH_1552 RTL8366S_SGCR_MAX_LENGTH(0x2) -+#define RTL8366S_SGCR_MAX_LENGTH_16000 RTL8366S_SGCR_MAX_LENGTH(0x3) -+#define RTL8366S_SGCR_EN_VLAN BIT(13) -+ -+/* Port Enable Control register */ -+#define RTL8366S_PECR 0x0001 -+ -+/* Green Ethernet Feature (based on GPL_BELKIN_F5D8235-4_v1000 v1.01.24) */ -+#define RTL8366S_GREEN_ETHERNET_CTRL_REG 0x000a -+#define RTL8366S_GREEN_ETHERNET_CTRL_MASK 0x0018 -+#define RTL8366S_GREEN_ETHERNET_TX_BIT (1 << 3) -+#define RTL8366S_GREEN_ETHERNET_RX_BIT (1 << 4) -+ -+/* Switch Security Control registers */ -+#define RTL8366S_SSCR0 0x0002 -+#define RTL8366S_SSCR1 0x0003 -+#define RTL8366S_SSCR2 0x0004 -+#define RTL8366S_SSCR2_DROP_UNKNOWN_DA BIT(0) -+ -+#define RTL8366S_RESET_CTRL_REG 0x0100 -+#define RTL8366S_CHIP_CTRL_RESET_HW 1 -+#define RTL8366S_CHIP_CTRL_RESET_SW (1 << 1) -+ -+#define RTL8366S_CHIP_VERSION_CTRL_REG 0x0104 -+#define RTL8366S_CHIP_VERSION_MASK 0xf -+#define RTL8366S_CHIP_ID_REG 0x0105 -+#define RTL8366S_CHIP_ID_8366 0x8366 -+ -+/* PHY registers control */ -+#define RTL8366S_PHY_ACCESS_CTRL_REG 0x8028 -+#define RTL8366S_PHY_ACCESS_DATA_REG 0x8029 -+ -+#define RTL8366S_PHY_CTRL_READ 1 -+#define RTL8366S_PHY_CTRL_WRITE 0 -+ -+#define RTL8366S_PHY_REG_MASK 0x1f -+#define RTL8366S_PHY_PAGE_OFFSET 5 -+#define RTL8366S_PHY_PAGE_MASK (0x7 << 5) -+#define RTL8366S_PHY_NO_OFFSET 9 -+#define RTL8366S_PHY_NO_MASK (0x1f << 9) -+ -+/* Green Ethernet Feature for PHY ports */ -+#define RTL8366S_PHY_POWER_SAVING_CTRL_REG 12 -+#define RTL8366S_PHY_POWER_SAVING_MASK 0x1000 -+ -+/* LED control registers */ -+#define RTL8366S_LED_BLINKRATE_REG 0x0420 -+#define RTL8366S_LED_BLINKRATE_BIT 0 -+#define RTL8366S_LED_BLINKRATE_MASK 0x0007 -+ -+#define RTL8366S_LED_CTRL_REG 0x0421 -+#define RTL8366S_LED_0_1_CTRL_REG 0x0422 -+#define RTL8366S_LED_2_3_CTRL_REG 0x0423 -+ -+#define RTL8366S_MIB_COUNT 33 -+#define RTL8366S_GLOBAL_MIB_COUNT 1 -+#define RTL8366S_MIB_COUNTER_PORT_OFFSET 0x0040 -+#define RTL8366S_MIB_COUNTER_BASE 0x1000 -+#define RTL8366S_MIB_COUNTER_PORT_OFFSET2 0x0008 -+#define RTL8366S_MIB_COUNTER_BASE2 0x1180 -+#define RTL8366S_MIB_CTRL_REG 0x11F0 -+#define RTL8366S_MIB_CTRL_USER_MASK 0x01FF -+#define RTL8366S_MIB_CTRL_BUSY_MASK 0x0001 -+#define RTL8366S_MIB_CTRL_RESET_MASK 0x0002 -+ -+#define RTL8366S_MIB_CTRL_GLOBAL_RESET_MASK 0x0004 -+#define RTL8366S_MIB_CTRL_PORT_RESET_BIT 0x0003 -+#define RTL8366S_MIB_CTRL_PORT_RESET_MASK 0x01FC -+ -+ -+#define RTL8366S_PORT_VLAN_CTRL_BASE 0x0058 -+#define RTL8366S_PORT_VLAN_CTRL_REG(_p) \ -+ (RTL8366S_PORT_VLAN_CTRL_BASE + (_p) / 4) -+#define RTL8366S_PORT_VLAN_CTRL_MASK 0xf -+#define RTL8366S_PORT_VLAN_CTRL_SHIFT(_p) (4 * ((_p) % 4)) -+ -+ -+#define RTL8366S_VLAN_TABLE_READ_BASE 0x018B -+#define RTL8366S_VLAN_TABLE_WRITE_BASE 0x0185 -+ -+#define RTL8366S_VLAN_TB_CTRL_REG 0x010F -+ -+#define RTL8366S_TABLE_ACCESS_CTRL_REG 0x0180 -+#define RTL8366S_TABLE_VLAN_READ_CTRL 0x0E01 -+#define RTL8366S_TABLE_VLAN_WRITE_CTRL 0x0F01 -+ -+#define RTL8366S_VLAN_MC_BASE(_x) (0x0016 + (_x) * 2) -+ -+#define RTL8366S_VLAN_MEMBERINGRESS_REG 0x0379 -+ -+#define RTL8366S_PORT_LINK_STATUS_BASE 0x0060 -+#define RTL8366S_PORT_STATUS_SPEED_MASK 0x0003 -+#define RTL8366S_PORT_STATUS_DUPLEX_MASK 0x0004 -+#define RTL8366S_PORT_STATUS_LINK_MASK 0x0010 -+#define RTL8366S_PORT_STATUS_TXPAUSE_MASK 0x0020 -+#define RTL8366S_PORT_STATUS_RXPAUSE_MASK 0x0040 -+#define RTL8366S_PORT_STATUS_AN_MASK 0x0080 -+ -+ -+#define RTL8366S_PORT_NUM_CPU 5 -+#define RTL8366S_NUM_PORTS 6 -+#define RTL8366S_NUM_VLANS 16 -+#define RTL8366S_NUM_LEDGROUPS 4 -+#define RTL8366S_NUM_VIDS 4096 -+#define RTL8366S_PRIORITYMAX 7 -+#define RTL8366S_FIDMAX 7 -+ -+ -+#define RTL8366S_PORT_1 (1 << 0) /* In userspace port 0 */ -+#define RTL8366S_PORT_2 (1 << 1) /* In userspace port 1 */ -+#define RTL8366S_PORT_3 (1 << 2) /* In userspace port 2 */ -+#define RTL8366S_PORT_4 (1 << 3) /* In userspace port 3 */ -+ -+#define RTL8366S_PORT_UNKNOWN (1 << 4) /* No known connection */ -+#define RTL8366S_PORT_CPU (1 << 5) /* CPU port */ -+ -+#define RTL8366S_PORT_ALL (RTL8366S_PORT_1 | \ -+ RTL8366S_PORT_2 | \ -+ RTL8366S_PORT_3 | \ -+ RTL8366S_PORT_4 | \ -+ RTL8366S_PORT_UNKNOWN | \ -+ RTL8366S_PORT_CPU) -+ -+#define RTL8366S_PORT_ALL_BUT_CPU (RTL8366S_PORT_1 | \ -+ RTL8366S_PORT_2 | \ -+ RTL8366S_PORT_3 | \ -+ RTL8366S_PORT_4 | \ -+ RTL8366S_PORT_UNKNOWN) -+ -+#define RTL8366S_PORT_ALL_EXTERNAL (RTL8366S_PORT_1 | \ -+ RTL8366S_PORT_2 | \ -+ RTL8366S_PORT_3 | \ -+ RTL8366S_PORT_4) -+ -+#define RTL8366S_PORT_ALL_INTERNAL (RTL8366S_PORT_UNKNOWN | \ -+ RTL8366S_PORT_CPU) -+ -+#define RTL8366S_VLAN_VID_MASK 0xfff -+#define RTL8366S_VLAN_PRIORITY_SHIFT 12 -+#define RTL8366S_VLAN_PRIORITY_MASK 0x7 -+#define RTL8366S_VLAN_MEMBER_MASK 0x3f -+#define RTL8366S_VLAN_UNTAG_SHIFT 6 -+#define RTL8366S_VLAN_UNTAG_MASK 0x3f -+#define RTL8366S_VLAN_FID_SHIFT 12 -+#define RTL8366S_VLAN_FID_MASK 0x7 -+ -+#define RTL8366S_MIB_RXB_ID 0 /* IfInOctets */ -+#define RTL8366S_MIB_TXB_ID 20 /* IfOutOctets */ -+ -+static struct rtl8366_mib_counter rtl8366s_mib_counters[] = { -+ { 0, 0, 4, "IfInOctets" }, -+ { 0, 4, 4, "EtherStatsOctets" }, -+ { 0, 8, 2, "EtherStatsUnderSizePkts" }, -+ { 0, 10, 2, "EtherFragments" }, -+ { 0, 12, 2, "EtherStatsPkts64Octets" }, -+ { 0, 14, 2, "EtherStatsPkts65to127Octets" }, -+ { 0, 16, 2, "EtherStatsPkts128to255Octets" }, -+ { 0, 18, 2, "EtherStatsPkts256to511Octets" }, -+ { 0, 20, 2, "EtherStatsPkts512to1023Octets" }, -+ { 0, 22, 2, "EtherStatsPkts1024to1518Octets" }, -+ { 0, 24, 2, "EtherOversizeStats" }, -+ { 0, 26, 2, "EtherStatsJabbers" }, -+ { 0, 28, 2, "IfInUcastPkts" }, -+ { 0, 30, 2, "EtherStatsMulticastPkts" }, -+ { 0, 32, 2, "EtherStatsBroadcastPkts" }, -+ { 0, 34, 2, "EtherStatsDropEvents" }, -+ { 0, 36, 2, "Dot3StatsFCSErrors" }, -+ { 0, 38, 2, "Dot3StatsSymbolErrors" }, -+ { 0, 40, 2, "Dot3InPauseFrames" }, -+ { 0, 42, 2, "Dot3ControlInUnknownOpcodes" }, -+ { 0, 44, 4, "IfOutOctets" }, -+ { 0, 48, 2, "Dot3StatsSingleCollisionFrames" }, -+ { 0, 50, 2, "Dot3StatMultipleCollisionFrames" }, -+ { 0, 52, 2, "Dot3sDeferredTransmissions" }, -+ { 0, 54, 2, "Dot3StatsLateCollisions" }, -+ { 0, 56, 2, "EtherStatsCollisions" }, -+ { 0, 58, 2, "Dot3StatsExcessiveCollisions" }, -+ { 0, 60, 2, "Dot3OutPauseFrames" }, -+ { 0, 62, 2, "Dot1dBasePortDelayExceededDiscards" }, -+ -+ /* -+ * The following counters are accessible at a different -+ * base address. -+ */ -+ { 1, 0, 2, "Dot1dTpPortInDiscards" }, -+ { 1, 2, 2, "IfOutUcastPkts" }, -+ { 1, 4, 2, "IfOutMulticastPkts" }, -+ { 1, 6, 2, "IfOutBroadcastPkts" }, -+}; -+ -+#define REG_WR(_smi, _reg, _val) \ -+ do { \ -+ err = rtl8366_smi_write_reg(_smi, _reg, _val); \ -+ if (err) \ -+ return err; \ -+ } while (0) -+ -+#define REG_RMW(_smi, _reg, _mask, _val) \ -+ do { \ -+ err = rtl8366_smi_rmwr(_smi, _reg, _mask, _val); \ -+ if (err) \ -+ return err; \ -+ } while (0) -+ -+static int rtl8366s_reset_chip(struct rtl8366_smi *smi) -+{ -+ int timeout = 10; -+ u32 data; -+ -+ rtl8366_smi_write_reg_noack(smi, RTL8366S_RESET_CTRL_REG, -+ RTL8366S_CHIP_CTRL_RESET_HW); -+ do { -+ msleep(1); -+ if (rtl8366_smi_read_reg(smi, RTL8366S_RESET_CTRL_REG, &data)) -+ return -EIO; -+ -+ if (!(data & RTL8366S_CHIP_CTRL_RESET_HW)) -+ break; -+ } while (--timeout); -+ -+ if (!timeout) { -+ printk("Timeout waiting for the switch to reset\n"); -+ return -EIO; -+ } -+ -+ return 0; -+} -+ -+static int rtl8366s_read_phy_reg(struct rtl8366_smi *smi, -+ u32 phy_no, u32 page, u32 addr, u32 *data) -+{ -+ u32 reg; -+ int ret; -+ -+ if (phy_no > RTL8366S_PHY_NO_MAX) -+ return -EINVAL; -+ -+ if (page > RTL8366S_PHY_PAGE_MAX) -+ return -EINVAL; -+ -+ if (addr > RTL8366S_PHY_ADDR_MAX) -+ return -EINVAL; -+ -+ ret = rtl8366_smi_write_reg(smi, RTL8366S_PHY_ACCESS_CTRL_REG, -+ RTL8366S_PHY_CTRL_READ); -+ if (ret) -+ return ret; -+ -+ reg = 0x8000 | (1 << (phy_no + RTL8366S_PHY_NO_OFFSET)) | -+ ((page << RTL8366S_PHY_PAGE_OFFSET) & RTL8366S_PHY_PAGE_MASK) | -+ (addr & RTL8366S_PHY_REG_MASK); -+ -+ ret = rtl8366_smi_write_reg(smi, reg, 0); -+ if (ret) -+ return ret; -+ -+ ret = rtl8366_smi_read_reg(smi, RTL8366S_PHY_ACCESS_DATA_REG, data); -+ if (ret) -+ return ret; -+ -+ return 0; -+} -+ -+static int rtl8366s_write_phy_reg(struct rtl8366_smi *smi, -+ u32 phy_no, u32 page, u32 addr, u32 data) -+{ -+ u32 reg; -+ int ret; -+ -+ if (phy_no > RTL8366S_PHY_NO_MAX) -+ return -EINVAL; -+ -+ if (page > RTL8366S_PHY_PAGE_MAX) -+ return -EINVAL; -+ -+ if (addr > RTL8366S_PHY_ADDR_MAX) -+ return -EINVAL; -+ -+ ret = rtl8366_smi_write_reg(smi, RTL8366S_PHY_ACCESS_CTRL_REG, -+ RTL8366S_PHY_CTRL_WRITE); -+ if (ret) -+ return ret; -+ -+ reg = 0x8000 | (1 << (phy_no + RTL8366S_PHY_NO_OFFSET)) | -+ ((page << RTL8366S_PHY_PAGE_OFFSET) & RTL8366S_PHY_PAGE_MASK) | -+ (addr & RTL8366S_PHY_REG_MASK); -+ -+ ret = rtl8366_smi_write_reg(smi, reg, data); -+ if (ret) -+ return ret; -+ -+ return 0; -+} -+ -+static int rtl8366s_set_green_port(struct rtl8366_smi *smi, int port, int enable) -+{ -+ int err; -+ u32 phyData; -+ -+ if (port >= RTL8366S_NUM_PORTS) -+ return -EINVAL; -+ -+ err = rtl8366s_read_phy_reg(smi, port, 0, RTL8366S_PHY_POWER_SAVING_CTRL_REG, &phyData); -+ if (err) -+ return err; -+ -+ if (enable) -+ phyData |= RTL8366S_PHY_POWER_SAVING_MASK; -+ else -+ phyData &= ~RTL8366S_PHY_POWER_SAVING_MASK; -+ -+ err = rtl8366s_write_phy_reg(smi, port, 0, RTL8366S_PHY_POWER_SAVING_CTRL_REG, phyData); -+ if (err) -+ return err; -+ -+ return 0; -+} -+ -+static int rtl8366s_set_green(struct rtl8366_smi *smi, int enable) -+{ -+ int err; -+ unsigned i; -+ u32 data = 0; -+ -+ if (!enable) { -+ for (i = 0; i <= RTL8366S_PHY_NO_MAX; i++) { -+ rtl8366s_set_green_port(smi, i, 0); -+ } -+ } -+ -+ if (enable) -+ data = (RTL8366S_GREEN_ETHERNET_TX_BIT | RTL8366S_GREEN_ETHERNET_RX_BIT); -+ -+ REG_RMW(smi, RTL8366S_GREEN_ETHERNET_CTRL_REG, RTL8366S_GREEN_ETHERNET_CTRL_MASK, data); -+ -+ return 0; -+} -+ -+static int rtl8366s_setup(struct rtl8366_smi *smi) -+{ -+ struct rtl8366_platform_data *pdata; -+ int err; -+ unsigned i; -+#ifdef CONFIG_OF -+ struct device_node *np; -+ unsigned num_initvals; -+ const __be32 *paddr; -+#endif -+ -+ pdata = smi->parent->platform_data; -+ if (pdata && pdata->num_initvals && pdata->initvals) { -+ dev_info(smi->parent, "applying initvals\n"); -+ for (i = 0; i < pdata->num_initvals; i++) -+ REG_WR(smi, pdata->initvals[i].reg, -+ pdata->initvals[i].val); -+ } -+ -+#ifdef CONFIG_OF -+ np = smi->parent->of_node; -+ -+ paddr = of_get_property(np, "realtek,initvals", &num_initvals); -+ if (paddr) { -+ dev_info(smi->parent, "applying initvals from DTS\n"); -+ -+ if (num_initvals < (2 * sizeof(*paddr))) -+ return -EINVAL; -+ -+ num_initvals /= sizeof(*paddr); -+ -+ for (i = 0; i < num_initvals - 1; i += 2) { -+ u32 reg = be32_to_cpup(paddr + i); -+ u32 val = be32_to_cpup(paddr + i + 1); -+ -+ REG_WR(smi, reg, val); -+ } -+ } -+ -+ if (of_property_read_bool(np, "realtek,green-ethernet-features")) { -+ dev_info(smi->parent, "activating Green Ethernet features\n"); -+ -+ err = rtl8366s_set_green(smi, 1); -+ if (err) -+ return err; -+ -+ for (i = 0; i <= RTL8366S_PHY_NO_MAX; i++) { -+ err = rtl8366s_set_green_port(smi, i, 1); -+ if (err) -+ return err; -+ } -+ } -+#endif -+ -+ /* set maximum packet length to 1536 bytes */ -+ REG_RMW(smi, RTL8366S_SGCR, RTL8366S_SGCR_MAX_LENGTH_MASK, -+ RTL8366S_SGCR_MAX_LENGTH_1536); -+ -+ /* enable learning for all ports */ -+ REG_WR(smi, RTL8366S_SSCR0, 0); -+ -+ /* enable auto ageing for all ports */ -+ REG_WR(smi, RTL8366S_SSCR1, 0); -+ -+ /* -+ * discard VLAN tagged packets if the port is not a member of -+ * the VLAN with which the packets is associated. -+ */ -+ REG_WR(smi, RTL8366S_VLAN_MEMBERINGRESS_REG, RTL8366S_PORT_ALL); -+ -+ /* don't drop packets whose DA has not been learned */ -+ REG_RMW(smi, RTL8366S_SSCR2, RTL8366S_SSCR2_DROP_UNKNOWN_DA, 0); -+ -+ return 0; -+} -+ -+static int rtl8366_get_mib_counter(struct rtl8366_smi *smi, int counter, -+ int port, unsigned long long *val) -+{ -+ int i; -+ int err; -+ u32 addr, data; -+ u64 mibvalue; -+ -+ if (port > RTL8366S_NUM_PORTS || counter >= RTL8366S_MIB_COUNT) -+ return -EINVAL; -+ -+ switch (rtl8366s_mib_counters[counter].base) { -+ case 0: -+ addr = RTL8366S_MIB_COUNTER_BASE + -+ RTL8366S_MIB_COUNTER_PORT_OFFSET * port; -+ break; -+ -+ case 1: -+ addr = RTL8366S_MIB_COUNTER_BASE2 + -+ RTL8366S_MIB_COUNTER_PORT_OFFSET2 * port; -+ break; -+ -+ default: -+ return -EINVAL; -+ } -+ -+ addr += rtl8366s_mib_counters[counter].offset; -+ -+ /* -+ * Writing access counter address first -+ * then ASIC will prepare 64bits counter wait for being retrived -+ */ -+ data = 0; /* writing data will be discard by ASIC */ -+ err = rtl8366_smi_write_reg(smi, addr, data); -+ if (err) -+ return err; -+ -+ /* read MIB control register */ -+ err = rtl8366_smi_read_reg(smi, RTL8366S_MIB_CTRL_REG, &data); -+ if (err) -+ return err; -+ -+ if (data & RTL8366S_MIB_CTRL_BUSY_MASK) -+ return -EBUSY; -+ -+ if (data & RTL8366S_MIB_CTRL_RESET_MASK) -+ return -EIO; -+ -+ mibvalue = 0; -+ for (i = rtl8366s_mib_counters[counter].length; i > 0; i--) { -+ err = rtl8366_smi_read_reg(smi, addr + (i - 1), &data); -+ if (err) -+ return err; -+ -+ mibvalue = (mibvalue << 16) | (data & 0xFFFF); -+ } -+ -+ *val = mibvalue; -+ return 0; -+} -+ -+static int rtl8366s_get_vlan_4k(struct rtl8366_smi *smi, u32 vid, -+ struct rtl8366_vlan_4k *vlan4k) -+{ -+ u32 data[2]; -+ int err; -+ int i; -+ -+ memset(vlan4k, '\0', sizeof(struct rtl8366_vlan_4k)); -+ -+ if (vid >= RTL8366S_NUM_VIDS) -+ return -EINVAL; -+ -+ /* write VID */ -+ err = rtl8366_smi_write_reg(smi, RTL8366S_VLAN_TABLE_WRITE_BASE, -+ vid & RTL8366S_VLAN_VID_MASK); -+ if (err) -+ return err; -+ -+ /* write table access control word */ -+ err = rtl8366_smi_write_reg(smi, RTL8366S_TABLE_ACCESS_CTRL_REG, -+ RTL8366S_TABLE_VLAN_READ_CTRL); -+ if (err) -+ return err; -+ -+ for (i = 0; i < 2; i++) { -+ err = rtl8366_smi_read_reg(smi, -+ RTL8366S_VLAN_TABLE_READ_BASE + i, -+ &data[i]); -+ if (err) -+ return err; -+ } -+ -+ vlan4k->vid = vid; -+ vlan4k->untag = (data[1] >> RTL8366S_VLAN_UNTAG_SHIFT) & -+ RTL8366S_VLAN_UNTAG_MASK; -+ vlan4k->member = data[1] & RTL8366S_VLAN_MEMBER_MASK; -+ vlan4k->fid = (data[1] >> RTL8366S_VLAN_FID_SHIFT) & -+ RTL8366S_VLAN_FID_MASK; -+ -+ return 0; -+} -+ -+static int rtl8366s_set_vlan_4k(struct rtl8366_smi *smi, -+ const struct rtl8366_vlan_4k *vlan4k) -+{ -+ u32 data[2]; -+ int err; -+ int i; -+ -+ if (vlan4k->vid >= RTL8366S_NUM_VIDS || -+ vlan4k->member > RTL8366S_VLAN_MEMBER_MASK || -+ vlan4k->untag > RTL8366S_VLAN_UNTAG_MASK || -+ vlan4k->fid > RTL8366S_FIDMAX) -+ return -EINVAL; -+ -+ data[0] = vlan4k->vid & RTL8366S_VLAN_VID_MASK; -+ data[1] = (vlan4k->member & RTL8366S_VLAN_MEMBER_MASK) | -+ ((vlan4k->untag & RTL8366S_VLAN_UNTAG_MASK) << -+ RTL8366S_VLAN_UNTAG_SHIFT) | -+ ((vlan4k->fid & RTL8366S_VLAN_FID_MASK) << -+ RTL8366S_VLAN_FID_SHIFT); -+ -+ for (i = 0; i < 2; i++) { -+ err = rtl8366_smi_write_reg(smi, -+ RTL8366S_VLAN_TABLE_WRITE_BASE + i, -+ data[i]); -+ if (err) -+ return err; -+ } -+ -+ /* write table access control word */ -+ err = rtl8366_smi_write_reg(smi, RTL8366S_TABLE_ACCESS_CTRL_REG, -+ RTL8366S_TABLE_VLAN_WRITE_CTRL); -+ -+ return err; -+} -+ -+static int rtl8366s_get_vlan_mc(struct rtl8366_smi *smi, u32 index, -+ struct rtl8366_vlan_mc *vlanmc) -+{ -+ u32 data[2]; -+ int err; -+ int i; -+ -+ memset(vlanmc, '\0', sizeof(struct rtl8366_vlan_mc)); -+ -+ if (index >= RTL8366S_NUM_VLANS) -+ return -EINVAL; -+ -+ for (i = 0; i < 2; i++) { -+ err = rtl8366_smi_read_reg(smi, -+ RTL8366S_VLAN_MC_BASE(index) + i, -+ &data[i]); -+ if (err) -+ return err; -+ } -+ -+ vlanmc->vid = data[0] & RTL8366S_VLAN_VID_MASK; -+ vlanmc->priority = (data[0] >> RTL8366S_VLAN_PRIORITY_SHIFT) & -+ RTL8366S_VLAN_PRIORITY_MASK; -+ vlanmc->untag = (data[1] >> RTL8366S_VLAN_UNTAG_SHIFT) & -+ RTL8366S_VLAN_UNTAG_MASK; -+ vlanmc->member = data[1] & RTL8366S_VLAN_MEMBER_MASK; -+ vlanmc->fid = (data[1] >> RTL8366S_VLAN_FID_SHIFT) & -+ RTL8366S_VLAN_FID_MASK; -+ -+ return 0; -+} -+ -+static int rtl8366s_set_vlan_mc(struct rtl8366_smi *smi, u32 index, -+ const struct rtl8366_vlan_mc *vlanmc) -+{ -+ u32 data[2]; -+ int err; -+ int i; -+ -+ if (index >= RTL8366S_NUM_VLANS || -+ vlanmc->vid >= RTL8366S_NUM_VIDS || -+ vlanmc->priority > RTL8366S_PRIORITYMAX || -+ vlanmc->member > RTL8366S_VLAN_MEMBER_MASK || -+ vlanmc->untag > RTL8366S_VLAN_UNTAG_MASK || -+ vlanmc->fid > RTL8366S_FIDMAX) -+ return -EINVAL; -+ -+ data[0] = (vlanmc->vid & RTL8366S_VLAN_VID_MASK) | -+ ((vlanmc->priority & RTL8366S_VLAN_PRIORITY_MASK) << -+ RTL8366S_VLAN_PRIORITY_SHIFT); -+ data[1] = (vlanmc->member & RTL8366S_VLAN_MEMBER_MASK) | -+ ((vlanmc->untag & RTL8366S_VLAN_UNTAG_MASK) << -+ RTL8366S_VLAN_UNTAG_SHIFT) | -+ ((vlanmc->fid & RTL8366S_VLAN_FID_MASK) << -+ RTL8366S_VLAN_FID_SHIFT); -+ -+ for (i = 0; i < 2; i++) { -+ err = rtl8366_smi_write_reg(smi, -+ RTL8366S_VLAN_MC_BASE(index) + i, -+ data[i]); -+ if (err) -+ return err; -+ } -+ -+ return 0; -+} -+ -+static int rtl8366s_get_mc_index(struct rtl8366_smi *smi, int port, int *val) -+{ -+ u32 data; -+ int err; -+ -+ if (port >= RTL8366S_NUM_PORTS) -+ return -EINVAL; -+ -+ err = rtl8366_smi_read_reg(smi, RTL8366S_PORT_VLAN_CTRL_REG(port), -+ &data); -+ if (err) -+ return err; -+ -+ *val = (data >> RTL8366S_PORT_VLAN_CTRL_SHIFT(port)) & -+ RTL8366S_PORT_VLAN_CTRL_MASK; -+ -+ return 0; -+} -+ -+static int rtl8366s_set_mc_index(struct rtl8366_smi *smi, int port, int index) -+{ -+ if (port >= RTL8366S_NUM_PORTS || index >= RTL8366S_NUM_VLANS) -+ return -EINVAL; -+ -+ return rtl8366_smi_rmwr(smi, RTL8366S_PORT_VLAN_CTRL_REG(port), -+ RTL8366S_PORT_VLAN_CTRL_MASK << -+ RTL8366S_PORT_VLAN_CTRL_SHIFT(port), -+ (index & RTL8366S_PORT_VLAN_CTRL_MASK) << -+ RTL8366S_PORT_VLAN_CTRL_SHIFT(port)); -+} -+ -+static int rtl8366s_enable_vlan(struct rtl8366_smi *smi, int enable) -+{ -+ return rtl8366_smi_rmwr(smi, RTL8366S_SGCR, RTL8366S_SGCR_EN_VLAN, -+ (enable) ? RTL8366S_SGCR_EN_VLAN : 0); -+} -+ -+static int rtl8366s_enable_vlan4k(struct rtl8366_smi *smi, int enable) -+{ -+ return rtl8366_smi_rmwr(smi, RTL8366S_VLAN_TB_CTRL_REG, -+ 1, (enable) ? 1 : 0); -+} -+ -+static int rtl8366s_is_vlan_valid(struct rtl8366_smi *smi, unsigned vlan) -+{ -+ unsigned max = RTL8366S_NUM_VLANS; -+ -+ if (smi->vlan4k_enabled) -+ max = RTL8366S_NUM_VIDS - 1; -+ -+ if (vlan == 0 || vlan >= max) -+ return 0; -+ -+ return 1; -+} -+ -+static int rtl8366s_enable_port(struct rtl8366_smi *smi, int port, int enable) -+{ -+ return rtl8366_smi_rmwr(smi, RTL8366S_PECR, (1 << port), -+ (enable) ? 0 : (1 << port)); -+} -+ -+static int rtl8366s_sw_reset_mibs(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ -+ return rtl8366_smi_rmwr(smi, RTL8366S_MIB_CTRL_REG, 0, (1 << 2)); -+} -+ -+static int rtl8366s_sw_get_blinkrate(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data; -+ -+ rtl8366_smi_read_reg(smi, RTL8366S_LED_BLINKRATE_REG, &data); -+ -+ val->value.i = (data & (RTL8366S_LED_BLINKRATE_MASK)); -+ -+ return 0; -+} -+ -+static int rtl8366s_sw_set_blinkrate(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ -+ if (val->value.i >= 6) -+ return -EINVAL; -+ -+ return rtl8366_smi_rmwr(smi, RTL8366S_LED_BLINKRATE_REG, -+ RTL8366S_LED_BLINKRATE_MASK, -+ val->value.i); -+} -+ -+static int rtl8366s_sw_get_max_length(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data; -+ -+ rtl8366_smi_read_reg(smi, RTL8366S_SGCR, &data); -+ -+ val->value.i = ((data & (RTL8366S_SGCR_MAX_LENGTH_MASK)) >> 4); -+ -+ return 0; -+} -+ -+static int rtl8366s_sw_set_max_length(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ char length_code; -+ -+ switch (val->value.i) { -+ case 0: -+ length_code = RTL8366S_SGCR_MAX_LENGTH_1522; -+ break; -+ case 1: -+ length_code = RTL8366S_SGCR_MAX_LENGTH_1536; -+ break; -+ case 2: -+ length_code = RTL8366S_SGCR_MAX_LENGTH_1552; -+ break; -+ case 3: -+ length_code = RTL8366S_SGCR_MAX_LENGTH_16000; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return rtl8366_smi_rmwr(smi, RTL8366S_SGCR, -+ RTL8366S_SGCR_MAX_LENGTH_MASK, -+ length_code); -+} -+ -+static int rtl8366s_sw_get_learning_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data; -+ -+ rtl8366_smi_read_reg(smi,RTL8366S_SSCR0, &data); -+ val->value.i = !data; -+ -+ return 0; -+} -+ -+ -+static int rtl8366s_sw_set_learning_enable(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 portmask = 0; -+ int err = 0; -+ -+ if (!val->value.i) -+ portmask = RTL8366S_PORT_ALL; -+ -+ /* set learning for all ports */ -+ REG_WR(smi, RTL8366S_SSCR0, portmask); -+ -+ /* set auto ageing for all ports */ -+ REG_WR(smi, RTL8366S_SSCR1, portmask); -+ -+ return 0; -+} -+ -+static int rtl8366s_sw_get_green(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data; -+ int err; -+ -+ err = rtl8366_smi_read_reg(smi, RTL8366S_GREEN_ETHERNET_CTRL_REG, &data); -+ if (err) -+ return err; -+ -+ val->value.i = ((data & (RTL8366S_GREEN_ETHERNET_TX_BIT | RTL8366S_GREEN_ETHERNET_RX_BIT)) != 0) ? 1 : 0; -+ -+ return 0; -+} -+ -+static int rtl8366s_sw_set_green(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ -+ return rtl8366s_set_green(smi, val->value.i); -+} -+ -+static int rtl8366s_sw_get_port_link(struct switch_dev *dev, -+ int port, -+ struct switch_port_link *link) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data = 0; -+ u32 speed; -+ -+ if (port >= RTL8366S_NUM_PORTS) -+ return -EINVAL; -+ -+ rtl8366_smi_read_reg(smi, RTL8366S_PORT_LINK_STATUS_BASE + (port / 2), -+ &data); -+ -+ if (port % 2) -+ data = data >> 8; -+ -+ link->link = !!(data & RTL8366S_PORT_STATUS_LINK_MASK); -+ if (!link->link) -+ return 0; -+ -+ link->duplex = !!(data & RTL8366S_PORT_STATUS_DUPLEX_MASK); -+ link->rx_flow = !!(data & RTL8366S_PORT_STATUS_RXPAUSE_MASK); -+ link->tx_flow = !!(data & RTL8366S_PORT_STATUS_TXPAUSE_MASK); -+ link->aneg = !!(data & RTL8366S_PORT_STATUS_AN_MASK); -+ -+ speed = (data & RTL8366S_PORT_STATUS_SPEED_MASK); -+ switch (speed) { -+ case 0: -+ link->speed = SWITCH_PORT_SPEED_10; -+ break; -+ case 1: -+ link->speed = SWITCH_PORT_SPEED_100; -+ break; -+ case 2: -+ link->speed = SWITCH_PORT_SPEED_1000; -+ break; -+ default: -+ link->speed = SWITCH_PORT_SPEED_UNKNOWN; -+ break; -+ } -+ -+ return 0; -+} -+ -+static int rtl8366s_sw_set_port_led(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data; -+ u32 mask; -+ u32 reg; -+ -+ if (val->port_vlan >= RTL8366S_NUM_PORTS || -+ (1 << val->port_vlan) == RTL8366S_PORT_UNKNOWN) -+ return -EINVAL; -+ -+ if (val->port_vlan == RTL8366S_PORT_NUM_CPU) { -+ reg = RTL8366S_LED_BLINKRATE_REG; -+ mask = 0xF << 4; -+ data = val->value.i << 4; -+ } else { -+ reg = RTL8366S_LED_CTRL_REG; -+ mask = 0xF << (val->port_vlan * 4), -+ data = val->value.i << (val->port_vlan * 4); -+ } -+ -+ return rtl8366_smi_rmwr(smi, reg, mask, data); -+} -+ -+static int rtl8366s_sw_get_port_led(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data = 0; -+ -+ if (val->port_vlan >= RTL8366S_NUM_LEDGROUPS) -+ return -EINVAL; -+ -+ rtl8366_smi_read_reg(smi, RTL8366S_LED_CTRL_REG, &data); -+ val->value.i = (data >> (val->port_vlan * 4)) & 0x000F; -+ -+ return 0; -+} -+ -+static int rtl8366s_sw_get_green_port(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ int err; -+ u32 phyData; -+ -+ if (val->port_vlan >= RTL8366S_NUM_PORTS) -+ return -EINVAL; -+ -+ err = rtl8366s_read_phy_reg(smi, val->port_vlan, 0, RTL8366S_PHY_POWER_SAVING_CTRL_REG, &phyData); -+ if (err) -+ return err; -+ -+ val->value.i = ((phyData & RTL8366S_PHY_POWER_SAVING_MASK) != 0) ? 1 : 0; -+ -+ return 0; -+} -+ -+static int rtl8366s_sw_set_green_port(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ return rtl8366s_set_green_port(smi, val->port_vlan, val->value.i); -+} -+ -+static int rtl8366s_sw_reset_port_mibs(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ -+ if (val->port_vlan >= RTL8366S_NUM_PORTS) -+ return -EINVAL; -+ -+ -+ return rtl8366_smi_rmwr(smi, RTL8366S_MIB_CTRL_REG, -+ 0, (1 << (val->port_vlan + 3))); -+} -+ -+static int rtl8366s_sw_get_port_stats(struct switch_dev *dev, int port, -+ struct switch_port_stats *stats) -+{ -+ return (rtl8366_sw_get_port_stats(dev, port, stats, -+ RTL8366S_MIB_TXB_ID, RTL8366S_MIB_RXB_ID)); -+} -+ -+static struct switch_attr rtl8366s_globals[] = { -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_learning", -+ .description = "Enable learning, enable aging", -+ .set = rtl8366s_sw_set_learning_enable, -+ .get = rtl8366s_sw_get_learning_enable, -+ .max = 1, -+ }, { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_vlan", -+ .description = "Enable VLAN mode", -+ .set = rtl8366_sw_set_vlan_enable, -+ .get = rtl8366_sw_get_vlan_enable, -+ .max = 1, -+ .ofs = 1 -+ }, { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_vlan4k", -+ .description = "Enable VLAN 4K mode", -+ .set = rtl8366_sw_set_vlan_enable, -+ .get = rtl8366_sw_get_vlan_enable, -+ .max = 1, -+ .ofs = 2 -+ }, { -+ .type = SWITCH_TYPE_NOVAL, -+ .name = "reset_mibs", -+ .description = "Reset all MIB counters", -+ .set = rtl8366s_sw_reset_mibs, -+ }, { -+ .type = SWITCH_TYPE_INT, -+ .name = "blinkrate", -+ .description = "Get/Set LED blinking rate (0 = 43ms, 1 = 84ms," -+ " 2 = 120ms, 3 = 170ms, 4 = 340ms, 5 = 670ms)", -+ .set = rtl8366s_sw_set_blinkrate, -+ .get = rtl8366s_sw_get_blinkrate, -+ .max = 5 -+ }, { -+ .type = SWITCH_TYPE_INT, -+ .name = "max_length", -+ .description = "Get/Set the maximum length of valid packets" -+ " (0 = 1522, 1 = 1536, 2 = 1552, 3 = 16000 (9216?))", -+ .set = rtl8366s_sw_set_max_length, -+ .get = rtl8366s_sw_get_max_length, -+ .max = 3, -+ }, { -+ .type = SWITCH_TYPE_INT, -+ .name = "green_mode", -+ .description = "Get/Set the router green feature", -+ .set = rtl8366s_sw_set_green, -+ .get = rtl8366s_sw_get_green, -+ .max = 1, -+ }, -+}; -+ -+static struct switch_attr rtl8366s_port[] = { -+ { -+ .type = SWITCH_TYPE_NOVAL, -+ .name = "reset_mib", -+ .description = "Reset single port MIB counters", -+ .set = rtl8366s_sw_reset_port_mibs, -+ }, { -+ .type = SWITCH_TYPE_STRING, -+ .name = "mib", -+ .description = "Get MIB counters for port", -+ .max = 33, -+ .set = NULL, -+ .get = rtl8366_sw_get_port_mib, -+ }, { -+ .type = SWITCH_TYPE_INT, -+ .name = "led", -+ .description = "Get/Set port group (0 - 3) led mode (0 - 15)", -+ .max = 15, -+ .set = rtl8366s_sw_set_port_led, -+ .get = rtl8366s_sw_get_port_led, -+ }, { -+ .type = SWITCH_TYPE_INT, -+ .name = "green_port", -+ .description = "Get/Set port green feature (0 - 1)", -+ .max = 1, -+ .set = rtl8366s_sw_set_green_port, -+ .get = rtl8366s_sw_get_green_port, -+ }, -+}; -+ -+static struct switch_attr rtl8366s_vlan[] = { -+ { -+ .type = SWITCH_TYPE_STRING, -+ .name = "info", -+ .description = "Get vlan information", -+ .max = 1, -+ .set = NULL, -+ .get = rtl8366_sw_get_vlan_info, -+ }, { -+ .type = SWITCH_TYPE_INT, -+ .name = "fid", -+ .description = "Get/Set vlan FID", -+ .max = RTL8366S_FIDMAX, -+ .set = rtl8366_sw_set_vlan_fid, -+ .get = rtl8366_sw_get_vlan_fid, -+ }, -+}; -+ -+static const struct switch_dev_ops rtl8366_ops = { -+ .attr_global = { -+ .attr = rtl8366s_globals, -+ .n_attr = ARRAY_SIZE(rtl8366s_globals), -+ }, -+ .attr_port = { -+ .attr = rtl8366s_port, -+ .n_attr = ARRAY_SIZE(rtl8366s_port), -+ }, -+ .attr_vlan = { -+ .attr = rtl8366s_vlan, -+ .n_attr = ARRAY_SIZE(rtl8366s_vlan), -+ }, -+ -+ .get_vlan_ports = rtl8366_sw_get_vlan_ports, -+ .set_vlan_ports = rtl8366_sw_set_vlan_ports, -+ .get_port_pvid = rtl8366_sw_get_port_pvid, -+ .set_port_pvid = rtl8366_sw_set_port_pvid, -+ .reset_switch = rtl8366_sw_reset_switch, -+ .get_port_link = rtl8366s_sw_get_port_link, -+ .get_port_stats = rtl8366s_sw_get_port_stats, -+}; -+ -+static int rtl8366s_switch_init(struct rtl8366_smi *smi) -+{ -+ struct switch_dev *dev = &smi->sw_dev; -+ int err; -+ -+ dev->name = "RTL8366S"; -+ dev->cpu_port = RTL8366S_PORT_NUM_CPU; -+ dev->ports = RTL8366S_NUM_PORTS; -+ dev->vlans = RTL8366S_NUM_VIDS; -+ dev->ops = &rtl8366_ops; -+ dev->alias = dev_name(smi->parent); -+ -+ err = register_switch(dev, NULL); -+ if (err) -+ dev_err(smi->parent, "switch registration failed\n"); -+ -+ return err; -+} -+ -+static void rtl8366s_switch_cleanup(struct rtl8366_smi *smi) -+{ -+ unregister_switch(&smi->sw_dev); -+} -+ -+static int rtl8366s_mii_read(struct mii_bus *bus, int addr, int reg) -+{ -+ struct rtl8366_smi *smi = bus->priv; -+ u32 val = 0; -+ int err; -+ -+ err = rtl8366s_read_phy_reg(smi, addr, 0, reg, &val); -+ if (err) -+ return 0xffff; -+ -+ return val; -+} -+ -+static int rtl8366s_mii_write(struct mii_bus *bus, int addr, int reg, u16 val) -+{ -+ struct rtl8366_smi *smi = bus->priv; -+ u32 t; -+ int err; -+ -+ err = rtl8366s_write_phy_reg(smi, addr, 0, reg, val); -+ /* flush write */ -+ (void) rtl8366s_read_phy_reg(smi, addr, 0, reg, &t); -+ -+ return err; -+} -+ -+static int rtl8366s_detect(struct rtl8366_smi *smi) -+{ -+ u32 chip_id = 0; -+ u32 chip_ver = 0; -+ int ret; -+ -+ ret = rtl8366_smi_read_reg(smi, RTL8366S_CHIP_ID_REG, &chip_id); -+ if (ret) { -+ dev_err(smi->parent, "unable to read chip id\n"); -+ return ret; -+ } -+ -+ switch (chip_id) { -+ case RTL8366S_CHIP_ID_8366: -+ break; -+ default: -+ dev_err(smi->parent, "unknown chip id (%04x)\n", chip_id); -+ return -ENODEV; -+ } -+ -+ ret = rtl8366_smi_read_reg(smi, RTL8366S_CHIP_VERSION_CTRL_REG, -+ &chip_ver); -+ if (ret) { -+ dev_err(smi->parent, "unable to read chip version\n"); -+ return ret; -+ } -+ -+ dev_info(smi->parent, "RTL%04x ver. %u chip found\n", -+ chip_id, chip_ver & RTL8366S_CHIP_VERSION_MASK); -+ -+ return 0; -+} -+ -+static struct rtl8366_smi_ops rtl8366s_smi_ops = { -+ .detect = rtl8366s_detect, -+ .reset_chip = rtl8366s_reset_chip, -+ .setup = rtl8366s_setup, -+ -+ .mii_read = rtl8366s_mii_read, -+ .mii_write = rtl8366s_mii_write, -+ -+ .get_vlan_mc = rtl8366s_get_vlan_mc, -+ .set_vlan_mc = rtl8366s_set_vlan_mc, -+ .get_vlan_4k = rtl8366s_get_vlan_4k, -+ .set_vlan_4k = rtl8366s_set_vlan_4k, -+ .get_mc_index = rtl8366s_get_mc_index, -+ .set_mc_index = rtl8366s_set_mc_index, -+ .get_mib_counter = rtl8366_get_mib_counter, -+ .is_vlan_valid = rtl8366s_is_vlan_valid, -+ .enable_vlan = rtl8366s_enable_vlan, -+ .enable_vlan4k = rtl8366s_enable_vlan4k, -+ .enable_port = rtl8366s_enable_port, -+}; -+ -+static int rtl8366s_probe(struct platform_device *pdev) -+{ -+ static int rtl8366_smi_version_printed; -+ struct rtl8366_smi *smi; -+ int err; -+ -+ if (!rtl8366_smi_version_printed++) -+ printk(KERN_NOTICE RTL8366S_DRIVER_DESC -+ " version " RTL8366S_DRIVER_VER"\n"); -+ -+ smi = rtl8366_smi_probe(pdev); -+ if (IS_ERR(smi)) -+ return PTR_ERR(smi); -+ -+ smi->clk_delay = 10; -+ smi->cmd_read = 0xa9; -+ smi->cmd_write = 0xa8; -+ smi->ops = &rtl8366s_smi_ops; -+ smi->cpu_port = RTL8366S_PORT_NUM_CPU; -+ smi->num_ports = RTL8366S_NUM_PORTS; -+ smi->num_vlan_mc = RTL8366S_NUM_VLANS; -+ smi->mib_counters = rtl8366s_mib_counters; -+ smi->num_mib_counters = ARRAY_SIZE(rtl8366s_mib_counters); -+ -+ err = rtl8366_smi_init(smi); -+ if (err) -+ goto err_free_smi; -+ -+ platform_set_drvdata(pdev, smi); -+ -+ err = rtl8366s_switch_init(smi); -+ if (err) -+ goto err_clear_drvdata; -+ -+ return 0; -+ -+ err_clear_drvdata: -+ platform_set_drvdata(pdev, NULL); -+ rtl8366_smi_cleanup(smi); -+ err_free_smi: -+ kfree(smi); -+ return err; -+} -+ -+static void rtl8366s_remove(struct platform_device *pdev) -+{ -+ struct rtl8366_smi *smi = platform_get_drvdata(pdev); -+ -+ if (smi) { -+ rtl8366s_switch_cleanup(smi); -+ platform_set_drvdata(pdev, NULL); -+ rtl8366_smi_cleanup(smi); -+ kfree(smi); -+ } -+} -+ -+#ifdef CONFIG_OF -+static const struct of_device_id rtl8366s_match[] = { -+ { .compatible = "realtek,rtl8366s" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, rtl8366s_match); -+#endif -+ -+static struct platform_driver rtl8366s_driver = { -+ .driver = { -+ .name = RTL8366S_DRIVER_NAME, -+#ifdef CONFIG_OF -+ .of_match_table = of_match_ptr(rtl8366s_match), -+#endif -+ }, -+ .probe = rtl8366s_probe, -+ .remove_new = rtl8366s_remove, -+}; -+ -+static int __init rtl8366s_module_init(void) -+{ -+ return platform_driver_register(&rtl8366s_driver); -+} -+module_init(rtl8366s_module_init); -+ -+static void __exit rtl8366s_module_exit(void) -+{ -+ platform_driver_unregister(&rtl8366s_driver); -+} -+module_exit(rtl8366s_module_exit); -+ -+MODULE_DESCRIPTION(RTL8366S_DRIVER_DESC); -+MODULE_VERSION(RTL8366S_DRIVER_VER); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_AUTHOR("Antti Seppälä "); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:" RTL8366S_DRIVER_NAME); -diff --git a/drivers/net/phy/rtl8367.c b/drivers/net/phy/rtl8367.c -new file mode 100644 -index 000000000000..1b996019a614 ---- /dev/null -+++ b/drivers/net/phy/rtl8367.c -@@ -0,0 +1,1859 @@ -+/* -+ * Platform driver for the Realtek RTL8367R/M ethernet switches -+ * -+ * Copyright (C) 2011 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "rtl8366_smi.h" -+ -+#define RTL8367_RESET_DELAY 1000 /* msecs*/ -+ -+#define RTL8367_PHY_ADDR_MAX 8 -+#define RTL8367_PHY_REG_MAX 31 -+ -+#define RTL8367_VID_MASK 0xffff -+#define RTL8367_FID_MASK 0xfff -+#define RTL8367_UNTAG_MASK 0xffff -+#define RTL8367_MEMBER_MASK 0xffff -+ -+#define RTL8367_PORT_CFG_REG(_p) (0x000e + 0x20 * (_p)) -+#define RTL8367_PORT_CFG_EGRESS_MODE_SHIFT 4 -+#define RTL8367_PORT_CFG_EGRESS_MODE_MASK 0x3 -+#define RTL8367_PORT_CFG_EGRESS_MODE_ORIGINAL 0 -+#define RTL8367_PORT_CFG_EGRESS_MODE_KEEP 1 -+#define RTL8367_PORT_CFG_EGRESS_MODE_PRI 2 -+#define RTL8367_PORT_CFG_EGRESS_MODE_REAL 3 -+ -+#define RTL8367_BYPASS_LINE_RATE_REG 0x03f7 -+ -+#define RTL8367_TA_CTRL_REG 0x0500 -+#define RTL8367_TA_CTRL_STATUS BIT(12) -+#define RTL8367_TA_CTRL_METHOD BIT(5) -+#define RTL8367_TA_CTRL_CMD_SHIFT 4 -+#define RTL8367_TA_CTRL_CMD_READ 0 -+#define RTL8367_TA_CTRL_CMD_WRITE 1 -+#define RTL8367_TA_CTRL_TABLE_SHIFT 0 -+#define RTL8367_TA_CTRL_TABLE_ACLRULE 1 -+#define RTL8367_TA_CTRL_TABLE_ACLACT 2 -+#define RTL8367_TA_CTRL_TABLE_CVLAN 3 -+#define RTL8367_TA_CTRL_TABLE_L2 4 -+#define RTL8367_TA_CTRL_CVLAN_READ \ -+ ((RTL8367_TA_CTRL_CMD_READ << RTL8367_TA_CTRL_CMD_SHIFT) | \ -+ RTL8367_TA_CTRL_TABLE_CVLAN) -+#define RTL8367_TA_CTRL_CVLAN_WRITE \ -+ ((RTL8367_TA_CTRL_CMD_WRITE << RTL8367_TA_CTRL_CMD_SHIFT) | \ -+ RTL8367_TA_CTRL_TABLE_CVLAN) -+ -+#define RTL8367_TA_ADDR_REG 0x0501 -+#define RTL8367_TA_ADDR_MASK 0x3fff -+ -+#define RTL8367_TA_DATA_REG(_x) (0x0503 + (_x)) -+#define RTL8367_TA_VLAN_DATA_SIZE 4 -+#define RTL8367_TA_VLAN_VID_MASK RTL8367_VID_MASK -+#define RTL8367_TA_VLAN_MEMBER_SHIFT 0 -+#define RTL8367_TA_VLAN_MEMBER_MASK RTL8367_MEMBER_MASK -+#define RTL8367_TA_VLAN_FID_SHIFT 0 -+#define RTL8367_TA_VLAN_FID_MASK RTL8367_FID_MASK -+#define RTL8367_TA_VLAN_UNTAG1_SHIFT 14 -+#define RTL8367_TA_VLAN_UNTAG1_MASK 0x3 -+#define RTL8367_TA_VLAN_UNTAG2_SHIFT 0 -+#define RTL8367_TA_VLAN_UNTAG2_MASK 0x3fff -+ -+#define RTL8367_VLAN_PVID_CTRL_REG(_p) (0x0700 + (_p) / 2) -+#define RTL8367_VLAN_PVID_CTRL_MASK 0x1f -+#define RTL8367_VLAN_PVID_CTRL_SHIFT(_p) (8 * ((_p) % 2)) -+ -+#define RTL8367_VLAN_MC_BASE(_x) (0x0728 + (_x) * 4) -+#define RTL8367_VLAN_MC_DATA_SIZE 4 -+#define RTL8367_VLAN_MC_MEMBER_SHIFT 0 -+#define RTL8367_VLAN_MC_MEMBER_MASK RTL8367_MEMBER_MASK -+#define RTL8367_VLAN_MC_FID_SHIFT 0 -+#define RTL8367_VLAN_MC_FID_MASK RTL8367_FID_MASK -+#define RTL8367_VLAN_MC_EVID_SHIFT 0 -+#define RTL8367_VLAN_MC_EVID_MASK RTL8367_VID_MASK -+ -+#define RTL8367_VLAN_CTRL_REG 0x07a8 -+#define RTL8367_VLAN_CTRL_ENABLE BIT(0) -+ -+#define RTL8367_VLAN_INGRESS_REG 0x07a9 -+ -+#define RTL8367_PORT_ISOLATION_REG(_p) (0x08a2 + (_p)) -+ -+#define RTL8367_MIB_COUNTER_REG(_x) (0x1000 + (_x)) -+ -+#define RTL8367_MIB_ADDRESS_REG 0x1004 -+ -+#define RTL8367_MIB_CTRL_REG(_x) (0x1005 + (_x)) -+#define RTL8367_MIB_CTRL_GLOBAL_RESET_MASK BIT(11) -+#define RTL8367_MIB_CTRL_QM_RESET_MASK BIT(10) -+#define RTL8367_MIB_CTRL_PORT_RESET_MASK(_p) BIT(2 + (_p)) -+#define RTL8367_MIB_CTRL_RESET_MASK BIT(1) -+#define RTL8367_MIB_CTRL_BUSY_MASK BIT(0) -+ -+#define RTL8367_MIB_COUNT 36 -+#define RTL8367_MIB_COUNTER_PORT_OFFSET 0x0050 -+ -+#define RTL8367_SWC0_REG 0x1200 -+#define RTL8367_SWC0_MAX_LENGTH_SHIFT 13 -+#define RTL8367_SWC0_MAX_LENGTH(_x) ((_x) << 13) -+#define RTL8367_SWC0_MAX_LENGTH_MASK RTL8367_SWC0_MAX_LENGTH(0x3) -+#define RTL8367_SWC0_MAX_LENGTH_1522 RTL8367_SWC0_MAX_LENGTH(0) -+#define RTL8367_SWC0_MAX_LENGTH_1536 RTL8367_SWC0_MAX_LENGTH(1) -+#define RTL8367_SWC0_MAX_LENGTH_1552 RTL8367_SWC0_MAX_LENGTH(2) -+#define RTL8367_SWC0_MAX_LENGTH_16000 RTL8367_SWC0_MAX_LENGTH(3) -+ -+#define RTL8367_CHIP_NUMBER_REG 0x1300 -+ -+#define RTL8367_CHIP_VER_REG 0x1301 -+#define RTL8367_CHIP_VER_RLVID_SHIFT 12 -+#define RTL8367_CHIP_VER_RLVID_MASK 0xf -+#define RTL8367_CHIP_VER_MCID_SHIFT 8 -+#define RTL8367_CHIP_VER_MCID_MASK 0xf -+#define RTL8367_CHIP_VER_BOID_SHIFT 4 -+#define RTL8367_CHIP_VER_BOID_MASK 0xf -+ -+#define RTL8367_CHIP_MODE_REG 0x1302 -+#define RTL8367_CHIP_MODE_MASK 0x7 -+ -+#define RTL8367_CHIP_DEBUG0_REG 0x1303 -+#define RTL8367_CHIP_DEBUG0_DUMMY0(_x) BIT(8 + (_x)) -+ -+#define RTL8367_CHIP_DEBUG1_REG 0x1304 -+ -+#define RTL8367_DIS_REG 0x1305 -+#define RTL8367_DIS_SKIP_MII_RXER(_x) BIT(12 + (_x)) -+#define RTL8367_DIS_RGMII_SHIFT(_x) (4 * (_x)) -+#define RTL8367_DIS_RGMII_MASK 0x7 -+ -+#define RTL8367_EXT_RGMXF_REG(_x) (0x1306 + (_x)) -+#define RTL8367_EXT_RGMXF_DUMMY0_SHIFT 5 -+#define RTL8367_EXT_RGMXF_DUMMY0_MASK 0x7ff -+#define RTL8367_EXT_RGMXF_TXDELAY_SHIFT 3 -+#define RTL8367_EXT_RGMXF_TXDELAY_MASK 1 -+#define RTL8367_EXT_RGMXF_RXDELAY_MASK 0x7 -+ -+#define RTL8367_DI_FORCE_REG(_x) (0x1310 + (_x)) -+#define RTL8367_DI_FORCE_MODE BIT(12) -+#define RTL8367_DI_FORCE_NWAY BIT(7) -+#define RTL8367_DI_FORCE_TXPAUSE BIT(6) -+#define RTL8367_DI_FORCE_RXPAUSE BIT(5) -+#define RTL8367_DI_FORCE_LINK BIT(4) -+#define RTL8367_DI_FORCE_DUPLEX BIT(2) -+#define RTL8367_DI_FORCE_SPEED_MASK 3 -+#define RTL8367_DI_FORCE_SPEED_10 0 -+#define RTL8367_DI_FORCE_SPEED_100 1 -+#define RTL8367_DI_FORCE_SPEED_1000 2 -+ -+#define RTL8367_MAC_FORCE_REG(_x) (0x1312 + (_x)) -+ -+#define RTL8367_CHIP_RESET_REG 0x1322 -+#define RTL8367_CHIP_RESET_SW BIT(1) -+#define RTL8367_CHIP_RESET_HW BIT(0) -+ -+#define RTL8367_PORT_STATUS_REG(_p) (0x1352 + (_p)) -+#define RTL8367_PORT_STATUS_NWAY BIT(7) -+#define RTL8367_PORT_STATUS_TXPAUSE BIT(6) -+#define RTL8367_PORT_STATUS_RXPAUSE BIT(5) -+#define RTL8367_PORT_STATUS_LINK BIT(4) -+#define RTL8367_PORT_STATUS_DUPLEX BIT(2) -+#define RTL8367_PORT_STATUS_SPEED_MASK 0x0003 -+#define RTL8367_PORT_STATUS_SPEED_10 0 -+#define RTL8367_PORT_STATUS_SPEED_100 1 -+#define RTL8367_PORT_STATUS_SPEED_1000 2 -+ -+#define RTL8367_RTL_NO_REG 0x13c0 -+#define RTL8367_RTL_NO_8367R 0x3670 -+#define RTL8367_RTL_NO_8367M 0x3671 -+ -+#define RTL8367_RTL_VER_REG 0x13c1 -+#define RTL8367_RTL_VER_MASK 0xf -+ -+#define RTL8367_RTL_MAGIC_ID_REG 0x13c2 -+#define RTL8367_RTL_MAGIC_ID_VAL 0x0249 -+ -+#define RTL8367_LED_SYS_CONFIG_REG 0x1b00 -+#define RTL8367_LED_MODE_REG 0x1b02 -+#define RTL8367_LED_MODE_RATE_M 0x7 -+#define RTL8367_LED_MODE_RATE_S 1 -+ -+#define RTL8367_LED_CONFIG_REG 0x1b03 -+#define RTL8367_LED_CONFIG_DATA_S 12 -+#define RTL8367_LED_CONFIG_DATA_M 0x3 -+#define RTL8367_LED_CONFIG_SEL BIT(14) -+#define RTL8367_LED_CONFIG_LED_CFG_M 0xf -+ -+#define RTL8367_PARA_LED_IO_EN1_REG 0x1b24 -+#define RTL8367_PARA_LED_IO_EN2_REG 0x1b25 -+#define RTL8367_PARA_LED_IO_EN_PMASK 0xff -+ -+#define RTL8367_IA_CTRL_REG 0x1f00 -+#define RTL8367_IA_CTRL_RW(_x) ((_x) << 1) -+#define RTL8367_IA_CTRL_RW_READ RTL8367_IA_CTRL_RW(0) -+#define RTL8367_IA_CTRL_RW_WRITE RTL8367_IA_CTRL_RW(1) -+#define RTL8367_IA_CTRL_CMD_MASK BIT(0) -+ -+#define RTL8367_IA_STATUS_REG 0x1f01 -+#define RTL8367_IA_STATUS_PHY_BUSY BIT(2) -+#define RTL8367_IA_STATUS_SDS_BUSY BIT(1) -+#define RTL8367_IA_STATUS_MDX_BUSY BIT(0) -+ -+#define RTL8367_IA_ADDRESS_REG 0x1f02 -+ -+#define RTL8367_IA_WRITE_DATA_REG 0x1f03 -+#define RTL8367_IA_READ_DATA_REG 0x1f04 -+ -+#define RTL8367_INTERNAL_PHY_REG(_a, _r) (0x2000 + 32 * (_a) + (_r)) -+ -+#define RTL8367_CPU_PORT_NUM 9 -+#define RTL8367_NUM_PORTS 10 -+#define RTL8367_NUM_VLANS 32 -+#define RTL8367_NUM_LEDGROUPS 4 -+#define RTL8367_NUM_VIDS 4096 -+#define RTL8367_PRIORITYMAX 7 -+#define RTL8367_FIDMAX 7 -+ -+#define RTL8367_PORT_0 BIT(0) -+#define RTL8367_PORT_1 BIT(1) -+#define RTL8367_PORT_2 BIT(2) -+#define RTL8367_PORT_3 BIT(3) -+#define RTL8367_PORT_4 BIT(4) -+#define RTL8367_PORT_5 BIT(5) -+#define RTL8367_PORT_6 BIT(6) -+#define RTL8367_PORT_7 BIT(7) -+#define RTL8367_PORT_E1 BIT(8) /* external port 1 */ -+#define RTL8367_PORT_E0 BIT(9) /* external port 0 */ -+ -+#define RTL8367_PORTS_ALL \ -+ (RTL8367_PORT_0 | RTL8367_PORT_1 | RTL8367_PORT_2 | \ -+ RTL8367_PORT_3 | RTL8367_PORT_4 | RTL8367_PORT_5 | \ -+ RTL8367_PORT_6 | RTL8367_PORT_7 | RTL8367_PORT_E1 | \ -+ RTL8367_PORT_E0) -+ -+#define RTL8367_PORTS_ALL_BUT_CPU \ -+ (RTL8367_PORT_0 | RTL8367_PORT_1 | RTL8367_PORT_2 | \ -+ RTL8367_PORT_3 | RTL8367_PORT_4 | RTL8367_PORT_5 | \ -+ RTL8367_PORT_6 | RTL8367_PORT_7 | RTL8367_PORT_E1) -+ -+struct rtl8367_initval { -+ u16 reg; -+ u16 val; -+}; -+ -+#define RTL8367_MIB_RXB_ID 0 /* IfInOctets */ -+#define RTL8367_MIB_TXB_ID 20 /* IfOutOctets */ -+ -+static struct rtl8366_mib_counter rtl8367_mib_counters[] = { -+ { 0, 0, 4, "IfInOctets" }, -+ { 0, 4, 2, "Dot3StatsFCSErrors" }, -+ { 0, 6, 2, "Dot3StatsSymbolErrors" }, -+ { 0, 8, 2, "Dot3InPauseFrames" }, -+ { 0, 10, 2, "Dot3ControlInUnknownOpcodes" }, -+ { 0, 12, 2, "EtherStatsFragments" }, -+ { 0, 14, 2, "EtherStatsJabbers" }, -+ { 0, 16, 2, "IfInUcastPkts" }, -+ { 0, 18, 2, "EtherStatsDropEvents" }, -+ { 0, 20, 4, "EtherStatsOctets" }, -+ -+ { 0, 24, 2, "EtherStatsUnderSizePkts" }, -+ { 0, 26, 2, "EtherOversizeStats" }, -+ { 0, 28, 2, "EtherStatsPkts64Octets" }, -+ { 0, 30, 2, "EtherStatsPkts65to127Octets" }, -+ { 0, 32, 2, "EtherStatsPkts128to255Octets" }, -+ { 0, 34, 2, "EtherStatsPkts256to511Octets" }, -+ { 0, 36, 2, "EtherStatsPkts512to1023Octets" }, -+ { 0, 38, 2, "EtherStatsPkts1024to1518Octets" }, -+ { 0, 40, 2, "EtherStatsMulticastPkts" }, -+ { 0, 42, 2, "EtherStatsBroadcastPkts" }, -+ -+ { 0, 44, 4, "IfOutOctets" }, -+ -+ { 0, 48, 2, "Dot3StatsSingleCollisionFrames" }, -+ { 0, 50, 2, "Dot3StatMultipleCollisionFrames" }, -+ { 0, 52, 2, "Dot3sDeferredTransmissions" }, -+ { 0, 54, 2, "Dot3StatsLateCollisions" }, -+ { 0, 56, 2, "EtherStatsCollisions" }, -+ { 0, 58, 2, "Dot3StatsExcessiveCollisions" }, -+ { 0, 60, 2, "Dot3OutPauseFrames" }, -+ { 0, 62, 2, "Dot1dBasePortDelayExceededDiscards" }, -+ { 0, 64, 2, "Dot1dTpPortInDiscards" }, -+ { 0, 66, 2, "IfOutUcastPkts" }, -+ { 0, 68, 2, "IfOutMulticastPkts" }, -+ { 0, 70, 2, "IfOutBroadcastPkts" }, -+ { 0, 72, 2, "OutOampduPkts" }, -+ { 0, 74, 2, "InOampduPkts" }, -+ { 0, 76, 2, "PktgenPkts" }, -+}; -+ -+#define REG_RD(_smi, _reg, _val) \ -+ do { \ -+ err = rtl8366_smi_read_reg(_smi, _reg, _val); \ -+ if (err) \ -+ return err; \ -+ } while (0) -+ -+#define REG_WR(_smi, _reg, _val) \ -+ do { \ -+ err = rtl8366_smi_write_reg(_smi, _reg, _val); \ -+ if (err) \ -+ return err; \ -+ } while (0) -+ -+#define REG_RMW(_smi, _reg, _mask, _val) \ -+ do { \ -+ err = rtl8366_smi_rmwr(_smi, _reg, _mask, _val); \ -+ if (err) \ -+ return err; \ -+ } while (0) -+ -+static const struct rtl8367_initval rtl8367_initvals_0_0[] = { -+ {0x133f, 0x0030}, {0x133e, 0x000e}, {0x221f, 0x0000}, {0x2215, 0x1006}, -+ {0x221f, 0x0005}, {0x2200, 0x00c6}, {0x221f, 0x0007}, {0x221e, 0x0048}, -+ {0x2215, 0x6412}, {0x2216, 0x6412}, {0x2217, 0x6412}, {0x2218, 0x6412}, -+ {0x2219, 0x6412}, {0x221A, 0x6412}, {0x221f, 0x0001}, {0x220c, 0xdbf0}, -+ {0x2209, 0x2576}, {0x2207, 0x287E}, {0x220A, 0x68E5}, {0x221D, 0x3DA4}, -+ {0x221C, 0xE7F7}, {0x2214, 0x7F52}, {0x2218, 0x7FCE}, {0x2208, 0x04B7}, -+ {0x2206, 0x4072}, {0x2210, 0xF05E}, {0x221B, 0xB414}, {0x221F, 0x0003}, -+ {0x221A, 0x06A6}, {0x2210, 0xF05E}, {0x2213, 0x06EB}, {0x2212, 0xF4D2}, -+ {0x220E, 0xE120}, {0x2200, 0x7C00}, {0x2202, 0x5FD0}, {0x220D, 0x0207}, -+ {0x221f, 0x0002}, {0x2205, 0x0978}, {0x2202, 0x8C01}, {0x2207, 0x3620}, -+ {0x221C, 0x0001}, {0x2203, 0x0420}, {0x2204, 0x80C8}, {0x133e, 0x0ede}, -+ {0x221f, 0x0002}, {0x220c, 0x0073}, {0x220d, 0xEB65}, {0x220e, 0x51d1}, -+ {0x220f, 0x5dcb}, {0x2210, 0x3044}, {0x2211, 0x1800}, {0x2212, 0x7E00}, -+ {0x2213, 0x0000}, {0x133f, 0x0010}, {0x133e, 0x0ffe}, {0x207f, 0x0002}, -+ {0x2074, 0x3D22}, {0x2075, 0x2000}, {0x2076, 0x6040}, {0x2077, 0x0000}, -+ {0x2078, 0x0f0a}, {0x2079, 0x50AB}, {0x207a, 0x0000}, {0x207b, 0x0f0f}, -+ {0x205f, 0x0002}, {0x2054, 0xFF00}, {0x2055, 0x000A}, {0x2056, 0x000A}, -+ {0x2057, 0x0005}, {0x2058, 0x0005}, {0x2059, 0x0000}, {0x205A, 0x0005}, -+ {0x205B, 0x0005}, {0x205C, 0x0005}, {0x209f, 0x0002}, {0x2094, 0x00AA}, -+ {0x2095, 0x00AA}, {0x2096, 0x00AA}, {0x2097, 0x00AA}, {0x2098, 0x0055}, -+ {0x2099, 0x00AA}, {0x209A, 0x00AA}, {0x209B, 0x00AA}, {0x1363, 0x8354}, -+ {0x1270, 0x3333}, {0x1271, 0x3333}, {0x1272, 0x3333}, {0x1330, 0x00DB}, -+ {0x1203, 0xff00}, {0x1200, 0x7fc4}, {0x121d, 0x1006}, {0x121e, 0x03e8}, -+ {0x121f, 0x02b3}, {0x1220, 0x028f}, {0x1221, 0x029b}, {0x1222, 0x0277}, -+ {0x1223, 0x02b3}, {0x1224, 0x028f}, {0x1225, 0x029b}, {0x1226, 0x0277}, -+ {0x1227, 0x00c0}, {0x1228, 0x00b4}, {0x122f, 0x00c0}, {0x1230, 0x00b4}, -+ {0x1229, 0x0020}, {0x122a, 0x000c}, {0x1231, 0x0030}, {0x1232, 0x0024}, -+ {0x0219, 0x0032}, {0x0200, 0x03e8}, {0x0201, 0x03e8}, {0x0202, 0x03e8}, -+ {0x0203, 0x03e8}, {0x0204, 0x03e8}, {0x0205, 0x03e8}, {0x0206, 0x03e8}, -+ {0x0207, 0x03e8}, {0x0218, 0x0032}, {0x0208, 0x029b}, {0x0209, 0x029b}, -+ {0x020a, 0x029b}, {0x020b, 0x029b}, {0x020c, 0x029b}, {0x020d, 0x029b}, -+ {0x020e, 0x029b}, {0x020f, 0x029b}, {0x0210, 0x029b}, {0x0211, 0x029b}, -+ {0x0212, 0x029b}, {0x0213, 0x029b}, {0x0214, 0x029b}, {0x0215, 0x029b}, -+ {0x0216, 0x029b}, {0x0217, 0x029b}, {0x0900, 0x0000}, {0x0901, 0x0000}, -+ {0x0902, 0x0000}, {0x0903, 0x0000}, {0x0865, 0x3210}, {0x087b, 0x0000}, -+ {0x087c, 0xff00}, {0x087d, 0x0000}, {0x087e, 0x0000}, {0x0801, 0x0100}, -+ {0x0802, 0x0100}, {0x1700, 0x014C}, {0x0301, 0x00FF}, {0x12AA, 0x0096}, -+ {0x133f, 0x0030}, {0x133e, 0x000e}, {0x221f, 0x0005}, {0x2200, 0x00C4}, -+ {0x221f, 0x0000}, {0x2210, 0x05EF}, {0x2204, 0x05E1}, {0x2200, 0x1340}, -+ {0x133f, 0x0010}, {0x20A0, 0x1940}, {0x20C0, 0x1940}, {0x20E0, 0x1940}, -+}; -+ -+static const struct rtl8367_initval rtl8367_initvals_0_1[] = { -+ {0x133f, 0x0030}, {0x133e, 0x000e}, {0x221f, 0x0000}, {0x2215, 0x1006}, -+ {0x221f, 0x0005}, {0x2200, 0x00c6}, {0x221f, 0x0007}, {0x221e, 0x0048}, -+ {0x2215, 0x6412}, {0x2216, 0x6412}, {0x2217, 0x6412}, {0x2218, 0x6412}, -+ {0x2219, 0x6412}, {0x221A, 0x6412}, {0x221f, 0x0001}, {0x220c, 0xdbf0}, -+ {0x2209, 0x2576}, {0x2207, 0x287E}, {0x220A, 0x68E5}, {0x221D, 0x3DA4}, -+ {0x221C, 0xE7F7}, {0x2214, 0x7F52}, {0x2218, 0x7FCE}, {0x2208, 0x04B7}, -+ {0x2206, 0x4072}, {0x2210, 0xF05E}, {0x221B, 0xB414}, {0x221F, 0x0003}, -+ {0x221A, 0x06A6}, {0x2210, 0xF05E}, {0x2213, 0x06EB}, {0x2212, 0xF4D2}, -+ {0x220E, 0xE120}, {0x2200, 0x7C00}, {0x2202, 0x5FD0}, {0x220D, 0x0207}, -+ {0x221f, 0x0002}, {0x2205, 0x0978}, {0x2202, 0x8C01}, {0x2207, 0x3620}, -+ {0x221C, 0x0001}, {0x2203, 0x0420}, {0x2204, 0x80C8}, {0x133e, 0x0ede}, -+ {0x221f, 0x0002}, {0x220c, 0x0073}, {0x220d, 0xEB65}, {0x220e, 0x51d1}, -+ {0x220f, 0x5dcb}, {0x2210, 0x3044}, {0x2211, 0x1800}, {0x2212, 0x7E00}, -+ {0x2213, 0x0000}, {0x133f, 0x0010}, {0x133e, 0x0ffe}, {0x207f, 0x0002}, -+ {0x2074, 0x3D22}, {0x2075, 0x2000}, {0x2076, 0x6040}, {0x2077, 0x0000}, -+ {0x2078, 0x0f0a}, {0x2079, 0x50AB}, {0x207a, 0x0000}, {0x207b, 0x0f0f}, -+ {0x205f, 0x0002}, {0x2054, 0xFF00}, {0x2055, 0x000A}, {0x2056, 0x000A}, -+ {0x2057, 0x0005}, {0x2058, 0x0005}, {0x2059, 0x0000}, {0x205A, 0x0005}, -+ {0x205B, 0x0005}, {0x205C, 0x0005}, {0x209f, 0x0002}, {0x2094, 0x00AA}, -+ {0x2095, 0x00AA}, {0x2096, 0x00AA}, {0x2097, 0x00AA}, {0x2098, 0x0055}, -+ {0x2099, 0x00AA}, {0x209A, 0x00AA}, {0x209B, 0x00AA}, {0x1363, 0x8354}, -+ {0x1270, 0x3333}, {0x1271, 0x3333}, {0x1272, 0x3333}, {0x1330, 0x00DB}, -+ {0x1203, 0xff00}, {0x1200, 0x7fc4}, {0x121d, 0x1b06}, {0x121e, 0x07f0}, -+ {0x121f, 0x0438}, {0x1220, 0x040f}, {0x1221, 0x040f}, {0x1222, 0x03eb}, -+ {0x1223, 0x0438}, {0x1224, 0x040f}, {0x1225, 0x040f}, {0x1226, 0x03eb}, -+ {0x1227, 0x0144}, {0x1228, 0x0138}, {0x122f, 0x0144}, {0x1230, 0x0138}, -+ {0x1229, 0x0020}, {0x122a, 0x000c}, {0x1231, 0x0030}, {0x1232, 0x0024}, -+ {0x0219, 0x0032}, {0x0200, 0x07d0}, {0x0201, 0x07d0}, {0x0202, 0x07d0}, -+ {0x0203, 0x07d0}, {0x0204, 0x07d0}, {0x0205, 0x07d0}, {0x0206, 0x07d0}, -+ {0x0207, 0x07d0}, {0x0218, 0x0032}, {0x0208, 0x0190}, {0x0209, 0x0190}, -+ {0x020a, 0x0190}, {0x020b, 0x0190}, {0x020c, 0x0190}, {0x020d, 0x0190}, -+ {0x020e, 0x0190}, {0x020f, 0x0190}, {0x0210, 0x0190}, {0x0211, 0x0190}, -+ {0x0212, 0x0190}, {0x0213, 0x0190}, {0x0214, 0x0190}, {0x0215, 0x0190}, -+ {0x0216, 0x0190}, {0x0217, 0x0190}, {0x0900, 0x0000}, {0x0901, 0x0000}, -+ {0x0902, 0x0000}, {0x0903, 0x0000}, {0x0865, 0x3210}, {0x087b, 0x0000}, -+ {0x087c, 0xff00}, {0x087d, 0x0000}, {0x087e, 0x0000}, {0x0801, 0x0100}, -+ {0x0802, 0x0100}, {0x1700, 0x0125}, {0x0301, 0x00FF}, {0x12AA, 0x0096}, -+ {0x133f, 0x0030}, {0x133e, 0x000e}, {0x221f, 0x0005}, {0x2200, 0x00C4}, -+ {0x221f, 0x0000}, {0x2210, 0x05EF}, {0x2204, 0x05E1}, {0x2200, 0x1340}, -+ {0x133f, 0x0010}, -+}; -+ -+static const struct rtl8367_initval rtl8367_initvals_1_0[] = { -+ {0x1B24, 0x0000}, {0x1B25, 0x0000}, {0x1B26, 0x0000}, {0x1B27, 0x0000}, -+ {0x207F, 0x0002}, {0x2079, 0x0200}, {0x207F, 0x0000}, {0x133F, 0x0030}, -+ {0x133E, 0x000E}, {0x221F, 0x0005}, {0x2201, 0x0700}, {0x2205, 0x8B82}, -+ {0x2206, 0x05CB}, {0x221F, 0x0002}, {0x2204, 0x80C2}, {0x2205, 0x0938}, -+ {0x221F, 0x0003}, {0x2212, 0xC4D2}, {0x220D, 0x0207}, {0x221F, 0x0001}, -+ {0x2207, 0x267E}, {0x221C, 0xE5F7}, {0x221B, 0x0424}, {0x221F, 0x0007}, -+ {0x221E, 0x0040}, {0x2218, 0x0000}, {0x221F, 0x0007}, {0x221E, 0x002C}, -+ {0x2218, 0x008B}, {0x221F, 0x0005}, {0x2205, 0xFFF6}, {0x2206, 0x0080}, -+ {0x2205, 0x8000}, {0x2206, 0xF8E0}, {0x2206, 0xE000}, {0x2206, 0xE1E0}, -+ {0x2206, 0x01AC}, {0x2206, 0x2408}, {0x2206, 0xE08B}, {0x2206, 0x84F7}, -+ {0x2206, 0x20E4}, {0x2206, 0x8B84}, {0x2206, 0xFC05}, {0x2206, 0xF8FA}, -+ {0x2206, 0xEF69}, {0x2206, 0xE08B}, {0x2206, 0x86AC}, {0x2206, 0x201A}, -+ {0x2206, 0xBF80}, {0x2206, 0x59D0}, {0x2206, 0x2402}, {0x2206, 0x803D}, -+ {0x2206, 0xE0E0}, {0x2206, 0xE4E1}, {0x2206, 0xE0E5}, {0x2206, 0x5806}, -+ {0x2206, 0x68C0}, {0x2206, 0xD1D2}, {0x2206, 0xE4E0}, {0x2206, 0xE4E5}, -+ {0x2206, 0xE0E5}, {0x2206, 0xEF96}, {0x2206, 0xFEFC}, {0x2206, 0x05FB}, -+ {0x2206, 0x0BFB}, {0x2206, 0x58FF}, {0x2206, 0x9E11}, {0x2206, 0x06F0}, -+ {0x2206, 0x0C81}, {0x2206, 0x8AE0}, {0x2206, 0x0019}, {0x2206, 0x1B89}, -+ {0x2206, 0xCFEB}, {0x2206, 0x19EB}, {0x2206, 0x19B0}, {0x2206, 0xEFFF}, -+ {0x2206, 0x0BFF}, {0x2206, 0x0425}, {0x2206, 0x0807}, {0x2206, 0x2640}, -+ {0x2206, 0x7227}, {0x2206, 0x267E}, {0x2206, 0x2804}, {0x2206, 0xB729}, -+ {0x2206, 0x2576}, {0x2206, 0x2A68}, {0x2206, 0xE52B}, {0x2206, 0xAD00}, -+ {0x2206, 0x2CDB}, {0x2206, 0xF02D}, {0x2206, 0x67BB}, {0x2206, 0x2E7B}, -+ {0x2206, 0x0F2F}, {0x2206, 0x7365}, {0x2206, 0x31AC}, {0x2206, 0xCC32}, -+ {0x2206, 0x2300}, {0x2206, 0x332D}, {0x2206, 0x1734}, {0x2206, 0x7F52}, -+ {0x2206, 0x3510}, {0x2206, 0x0036}, {0x2206, 0x0600}, {0x2206, 0x370C}, -+ {0x2206, 0xC038}, {0x2206, 0x7FCE}, {0x2206, 0x3CE5}, {0x2206, 0xF73D}, -+ {0x2206, 0x3DA4}, {0x2206, 0x6530}, {0x2206, 0x3E67}, {0x2206, 0x0053}, -+ {0x2206, 0x69D2}, {0x2206, 0x0F6A}, {0x2206, 0x012C}, {0x2206, 0x6C2B}, -+ {0x2206, 0x136E}, {0x2206, 0xE100}, {0x2206, 0x6F12}, {0x2206, 0xF771}, -+ {0x2206, 0x006B}, {0x2206, 0x7306}, {0x2206, 0xEB74}, {0x2206, 0x94C7}, -+ {0x2206, 0x7698}, {0x2206, 0x0A77}, {0x2206, 0x5000}, {0x2206, 0x788A}, -+ {0x2206, 0x1579}, {0x2206, 0x7F6F}, {0x2206, 0x7A06}, {0x2206, 0xA600}, -+ {0x2205, 0x8B90}, {0x2206, 0x8000}, {0x2205, 0x8B92}, {0x2206, 0x8000}, -+ {0x2205, 0x8B94}, {0x2206, 0x8014}, {0x2208, 0xFFFA}, {0x2202, 0x3C65}, -+ {0x2205, 0xFFF6}, {0x2206, 0x00F7}, {0x221F, 0x0000}, {0x221F, 0x0007}, -+ {0x221E, 0x0042}, {0x2218, 0x0000}, {0x221E, 0x002D}, {0x2218, 0xF010}, -+ {0x221E, 0x0020}, {0x2215, 0x0000}, {0x221E, 0x0023}, {0x2216, 0x8000}, -+ {0x221F, 0x0000}, {0x133F, 0x0010}, {0x133E, 0x0FFE}, {0x1362, 0x0115}, -+ {0x1363, 0x0002}, {0x1363, 0x0000}, {0x1306, 0x000C}, {0x1307, 0x000C}, -+ {0x1303, 0x0067}, {0x1304, 0x4444}, {0x1203, 0xFF00}, {0x1200, 0x7FC4}, -+ {0x121D, 0x7D16}, {0x121E, 0x03E8}, {0x121F, 0x024E}, {0x1220, 0x0230}, -+ {0x1221, 0x0244}, {0x1222, 0x0226}, {0x1223, 0x024E}, {0x1224, 0x0230}, -+ {0x1225, 0x0244}, {0x1226, 0x0226}, {0x1227, 0x00C0}, {0x1228, 0x00B4}, -+ {0x122F, 0x00C0}, {0x1230, 0x00B4}, {0x0208, 0x03E8}, {0x0209, 0x03E8}, -+ {0x020A, 0x03E8}, {0x020B, 0x03E8}, {0x020C, 0x03E8}, {0x020D, 0x03E8}, -+ {0x020E, 0x03E8}, {0x020F, 0x03E8}, {0x0210, 0x03E8}, {0x0211, 0x03E8}, -+ {0x0212, 0x03E8}, {0x0213, 0x03E8}, {0x0214, 0x03E8}, {0x0215, 0x03E8}, -+ {0x0216, 0x03E8}, {0x0217, 0x03E8}, {0x0900, 0x0000}, {0x0901, 0x0000}, -+ {0x0902, 0x0000}, {0x0903, 0x0000}, {0x0865, 0x3210}, {0x087B, 0x0000}, -+ {0x087C, 0xFF00}, {0x087D, 0x0000}, {0x087E, 0x0000}, {0x0801, 0x0100}, -+ {0x0802, 0x0100}, {0x0A20, 0x2040}, {0x0A21, 0x2040}, {0x0A22, 0x2040}, -+ {0x0A23, 0x2040}, {0x0A24, 0x2040}, {0x0A28, 0x2040}, {0x0A29, 0x2040}, -+ {0x133F, 0x0030}, {0x133E, 0x000E}, {0x221F, 0x0000}, {0x2200, 0x1340}, -+ {0x221F, 0x0000}, {0x133F, 0x0010}, {0x133E, 0x0FFE}, {0x20A0, 0x1940}, -+ {0x20C0, 0x1940}, {0x20E0, 0x1940}, {0x130c, 0x0050}, -+}; -+ -+static const struct rtl8367_initval rtl8367_initvals_1_1[] = { -+ {0x1B24, 0x0000}, {0x1B25, 0x0000}, {0x1B26, 0x0000}, {0x1B27, 0x0000}, -+ {0x207F, 0x0002}, {0x2079, 0x0200}, {0x207F, 0x0000}, {0x133F, 0x0030}, -+ {0x133E, 0x000E}, {0x221F, 0x0005}, {0x2201, 0x0700}, {0x2205, 0x8B82}, -+ {0x2206, 0x05CB}, {0x221F, 0x0002}, {0x2204, 0x80C2}, {0x2205, 0x0938}, -+ {0x221F, 0x0003}, {0x2212, 0xC4D2}, {0x220D, 0x0207}, {0x221F, 0x0001}, -+ {0x2207, 0x267E}, {0x221C, 0xE5F7}, {0x221B, 0x0424}, {0x221F, 0x0007}, -+ {0x221E, 0x0040}, {0x2218, 0x0000}, {0x221F, 0x0007}, {0x221E, 0x002C}, -+ {0x2218, 0x008B}, {0x221F, 0x0005}, {0x2205, 0xFFF6}, {0x2206, 0x0080}, -+ {0x2205, 0x8000}, {0x2206, 0xF8E0}, {0x2206, 0xE000}, {0x2206, 0xE1E0}, -+ {0x2206, 0x01AC}, {0x2206, 0x2408}, {0x2206, 0xE08B}, {0x2206, 0x84F7}, -+ {0x2206, 0x20E4}, {0x2206, 0x8B84}, {0x2206, 0xFC05}, {0x2206, 0xF8FA}, -+ {0x2206, 0xEF69}, {0x2206, 0xE08B}, {0x2206, 0x86AC}, {0x2206, 0x201A}, -+ {0x2206, 0xBF80}, {0x2206, 0x59D0}, {0x2206, 0x2402}, {0x2206, 0x803D}, -+ {0x2206, 0xE0E0}, {0x2206, 0xE4E1}, {0x2206, 0xE0E5}, {0x2206, 0x5806}, -+ {0x2206, 0x68C0}, {0x2206, 0xD1D2}, {0x2206, 0xE4E0}, {0x2206, 0xE4E5}, -+ {0x2206, 0xE0E5}, {0x2206, 0xEF96}, {0x2206, 0xFEFC}, {0x2206, 0x05FB}, -+ {0x2206, 0x0BFB}, {0x2206, 0x58FF}, {0x2206, 0x9E11}, {0x2206, 0x06F0}, -+ {0x2206, 0x0C81}, {0x2206, 0x8AE0}, {0x2206, 0x0019}, {0x2206, 0x1B89}, -+ {0x2206, 0xCFEB}, {0x2206, 0x19EB}, {0x2206, 0x19B0}, {0x2206, 0xEFFF}, -+ {0x2206, 0x0BFF}, {0x2206, 0x0425}, {0x2206, 0x0807}, {0x2206, 0x2640}, -+ {0x2206, 0x7227}, {0x2206, 0x267E}, {0x2206, 0x2804}, {0x2206, 0xB729}, -+ {0x2206, 0x2576}, {0x2206, 0x2A68}, {0x2206, 0xE52B}, {0x2206, 0xAD00}, -+ {0x2206, 0x2CDB}, {0x2206, 0xF02D}, {0x2206, 0x67BB}, {0x2206, 0x2E7B}, -+ {0x2206, 0x0F2F}, {0x2206, 0x7365}, {0x2206, 0x31AC}, {0x2206, 0xCC32}, -+ {0x2206, 0x2300}, {0x2206, 0x332D}, {0x2206, 0x1734}, {0x2206, 0x7F52}, -+ {0x2206, 0x3510}, {0x2206, 0x0036}, {0x2206, 0x0600}, {0x2206, 0x370C}, -+ {0x2206, 0xC038}, {0x2206, 0x7FCE}, {0x2206, 0x3CE5}, {0x2206, 0xF73D}, -+ {0x2206, 0x3DA4}, {0x2206, 0x6530}, {0x2206, 0x3E67}, {0x2206, 0x0053}, -+ {0x2206, 0x69D2}, {0x2206, 0x0F6A}, {0x2206, 0x012C}, {0x2206, 0x6C2B}, -+ {0x2206, 0x136E}, {0x2206, 0xE100}, {0x2206, 0x6F12}, {0x2206, 0xF771}, -+ {0x2206, 0x006B}, {0x2206, 0x7306}, {0x2206, 0xEB74}, {0x2206, 0x94C7}, -+ {0x2206, 0x7698}, {0x2206, 0x0A77}, {0x2206, 0x5000}, {0x2206, 0x788A}, -+ {0x2206, 0x1579}, {0x2206, 0x7F6F}, {0x2206, 0x7A06}, {0x2206, 0xA600}, -+ {0x2205, 0x8B90}, {0x2206, 0x8000}, {0x2205, 0x8B92}, {0x2206, 0x8000}, -+ {0x2205, 0x8B94}, {0x2206, 0x8014}, {0x2208, 0xFFFA}, {0x2202, 0x3C65}, -+ {0x2205, 0xFFF6}, {0x2206, 0x00F7}, {0x221F, 0x0000}, {0x221F, 0x0007}, -+ {0x221E, 0x0042}, {0x2218, 0x0000}, {0x221E, 0x002D}, {0x2218, 0xF010}, -+ {0x221E, 0x0020}, {0x2215, 0x0000}, {0x221E, 0x0023}, {0x2216, 0x8000}, -+ {0x221F, 0x0000}, {0x133F, 0x0010}, {0x133E, 0x0FFE}, {0x1362, 0x0115}, -+ {0x1363, 0x0002}, {0x1363, 0x0000}, {0x1306, 0x000C}, {0x1307, 0x000C}, -+ {0x1303, 0x0067}, {0x1304, 0x4444}, {0x1203, 0xFF00}, {0x1200, 0x7FC4}, -+ {0x0900, 0x0000}, {0x0901, 0x0000}, {0x0902, 0x0000}, {0x0903, 0x0000}, -+ {0x0865, 0x3210}, {0x087B, 0x0000}, {0x087C, 0xFF00}, {0x087D, 0x0000}, -+ {0x087E, 0x0000}, {0x0801, 0x0100}, {0x0802, 0x0100}, {0x0A20, 0x2040}, -+ {0x0A21, 0x2040}, {0x0A22, 0x2040}, {0x0A23, 0x2040}, {0x0A24, 0x2040}, -+ {0x0A25, 0x2040}, {0x0A26, 0x2040}, {0x0A27, 0x2040}, {0x0A28, 0x2040}, -+ {0x0A29, 0x2040}, {0x133F, 0x0030}, {0x133E, 0x000E}, {0x221F, 0x0000}, -+ {0x2200, 0x1340}, {0x221F, 0x0000}, {0x133F, 0x0010}, {0x133E, 0x0FFE}, -+ {0x1B03, 0x0876}, -+}; -+ -+static const struct rtl8367_initval rtl8367_initvals_2_0[] = { -+ {0x1b24, 0x0000}, {0x1b25, 0x0000}, {0x1b26, 0x0000}, {0x1b27, 0x0000}, -+ {0x133f, 0x0030}, {0x133e, 0x000e}, {0x221f, 0x0007}, {0x221e, 0x0048}, -+ {0x2219, 0x4012}, {0x221f, 0x0003}, {0x2201, 0x3554}, {0x2202, 0x63e8}, -+ {0x2203, 0x99c2}, {0x2204, 0x0113}, {0x2205, 0x303e}, {0x220d, 0x0207}, -+ {0x220e, 0xe100}, {0x221f, 0x0007}, {0x221e, 0x0040}, {0x2218, 0x0000}, -+ {0x221f, 0x0007}, {0x221e, 0x002c}, {0x2218, 0x008b}, {0x221f, 0x0005}, -+ {0x2205, 0xfff6}, {0x2206, 0x0080}, {0x221f, 0x0005}, {0x2205, 0x8000}, -+ {0x2206, 0x0280}, {0x2206, 0x2bf7}, {0x2206, 0x00e0}, {0x2206, 0xfff7}, -+ {0x2206, 0xa080}, {0x2206, 0x02ae}, {0x2206, 0xf602}, {0x2206, 0x804e}, -+ {0x2206, 0x0201}, {0x2206, 0x5002}, {0x2206, 0x0163}, {0x2206, 0x0201}, -+ {0x2206, 0x79e0}, {0x2206, 0x8b8c}, {0x2206, 0xe18b}, {0x2206, 0x8d1e}, -+ {0x2206, 0x01e1}, {0x2206, 0x8b8e}, {0x2206, 0x1e01}, {0x2206, 0xa000}, -+ {0x2206, 0xe4ae}, {0x2206, 0xd8bf}, {0x2206, 0x8b88}, {0x2206, 0xec00}, -+ {0x2206, 0x19a9}, {0x2206, 0x8b90}, {0x2206, 0xf9ee}, {0x2206, 0xfff6}, -+ {0x2206, 0x00ee}, {0x2206, 0xfff7}, {0x2206, 0xfce0}, {0x2206, 0xe140}, -+ {0x2206, 0xe1e1}, {0x2206, 0x41f7}, {0x2206, 0x2ff6}, {0x2206, 0x28e4}, -+ {0x2206, 0xe140}, {0x2206, 0xe5e1}, {0x2206, 0x4104}, {0x2206, 0xf8fa}, -+ {0x2206, 0xef69}, {0x2206, 0xe08b}, {0x2206, 0x86ac}, {0x2206, 0x201a}, -+ {0x2206, 0xbf80}, {0x2206, 0x77d0}, {0x2206, 0x6c02}, {0x2206, 0x2978}, -+ {0x2206, 0xe0e0}, {0x2206, 0xe4e1}, {0x2206, 0xe0e5}, {0x2206, 0x5806}, -+ {0x2206, 0x68c0}, {0x2206, 0xd1d2}, {0x2206, 0xe4e0}, {0x2206, 0xe4e5}, -+ {0x2206, 0xe0e5}, {0x2206, 0xef96}, {0x2206, 0xfefc}, {0x2206, 0x0425}, -+ {0x2206, 0x0807}, {0x2206, 0x2640}, {0x2206, 0x7227}, {0x2206, 0x267e}, -+ {0x2206, 0x2804}, {0x2206, 0xb729}, {0x2206, 0x2576}, {0x2206, 0x2a68}, -+ {0x2206, 0xe52b}, {0x2206, 0xad00}, {0x2206, 0x2cdb}, {0x2206, 0xf02d}, -+ {0x2206, 0x67bb}, {0x2206, 0x2e7b}, {0x2206, 0x0f2f}, {0x2206, 0x7365}, -+ {0x2206, 0x31ac}, {0x2206, 0xcc32}, {0x2206, 0x2300}, {0x2206, 0x332d}, -+ {0x2206, 0x1734}, {0x2206, 0x7f52}, {0x2206, 0x3510}, {0x2206, 0x0036}, -+ {0x2206, 0x0600}, {0x2206, 0x370c}, {0x2206, 0xc038}, {0x2206, 0x7fce}, -+ {0x2206, 0x3ce5}, {0x2206, 0xf73d}, {0x2206, 0x3da4}, {0x2206, 0x6530}, -+ {0x2206, 0x3e67}, {0x2206, 0x0053}, {0x2206, 0x69d2}, {0x2206, 0x0f6a}, -+ {0x2206, 0x012c}, {0x2206, 0x6c2b}, {0x2206, 0x136e}, {0x2206, 0xe100}, -+ {0x2206, 0x6f12}, {0x2206, 0xf771}, {0x2206, 0x006b}, {0x2206, 0x7306}, -+ {0x2206, 0xeb74}, {0x2206, 0x94c7}, {0x2206, 0x7698}, {0x2206, 0x0a77}, -+ {0x2206, 0x5000}, {0x2206, 0x788a}, {0x2206, 0x1579}, {0x2206, 0x7f6f}, -+ {0x2206, 0x7a06}, {0x2206, 0xa600}, {0x2201, 0x0701}, {0x2200, 0x0405}, -+ {0x221f, 0x0000}, {0x2200, 0x1340}, {0x221f, 0x0000}, {0x133f, 0x0010}, -+ {0x133e, 0x0ffe}, {0x1203, 0xff00}, {0x1200, 0x7fc4}, {0x121d, 0x7D16}, -+ {0x121e, 0x03e8}, {0x121f, 0x024e}, {0x1220, 0x0230}, {0x1221, 0x0244}, -+ {0x1222, 0x0226}, {0x1223, 0x024e}, {0x1224, 0x0230}, {0x1225, 0x0244}, -+ {0x1226, 0x0226}, {0x1227, 0x00c0}, {0x1228, 0x00b4}, {0x122f, 0x00c0}, -+ {0x1230, 0x00b4}, {0x0208, 0x03e8}, {0x0209, 0x03e8}, {0x020a, 0x03e8}, -+ {0x020b, 0x03e8}, {0x020c, 0x03e8}, {0x020d, 0x03e8}, {0x020e, 0x03e8}, -+ {0x020f, 0x03e8}, {0x0210, 0x03e8}, {0x0211, 0x03e8}, {0x0212, 0x03e8}, -+ {0x0213, 0x03e8}, {0x0214, 0x03e8}, {0x0215, 0x03e8}, {0x0216, 0x03e8}, -+ {0x0217, 0x03e8}, {0x0900, 0x0000}, {0x0901, 0x0000}, {0x0902, 0x0000}, -+ {0x0903, 0x0000}, {0x0865, 0x3210}, {0x087b, 0x0000}, {0x087c, 0xff00}, -+ {0x087d, 0x0000}, {0x087e, 0x0000}, {0x0801, 0x0100}, {0x0802, 0x0100}, -+ {0x0A20, 0x2040}, {0x0A21, 0x2040}, {0x0A22, 0x2040}, {0x0A23, 0x2040}, -+ {0x0A24, 0x2040}, {0x0A28, 0x2040}, {0x0A29, 0x2040}, {0x20A0, 0x1940}, -+ {0x20C0, 0x1940}, {0x20E0, 0x1940}, {0x130c, 0x0050}, -+}; -+ -+static const struct rtl8367_initval rtl8367_initvals_2_1[] = { -+ {0x1b24, 0x0000}, {0x1b25, 0x0000}, {0x1b26, 0x0000}, {0x1b27, 0x0000}, -+ {0x133f, 0x0030}, {0x133e, 0x000e}, {0x221f, 0x0007}, {0x221e, 0x0048}, -+ {0x2219, 0x4012}, {0x221f, 0x0003}, {0x2201, 0x3554}, {0x2202, 0x63e8}, -+ {0x2203, 0x99c2}, {0x2204, 0x0113}, {0x2205, 0x303e}, {0x220d, 0x0207}, -+ {0x220e, 0xe100}, {0x221f, 0x0007}, {0x221e, 0x0040}, {0x2218, 0x0000}, -+ {0x221f, 0x0007}, {0x221e, 0x002c}, {0x2218, 0x008b}, {0x221f, 0x0005}, -+ {0x2205, 0xfff6}, {0x2206, 0x0080}, {0x221f, 0x0005}, {0x2205, 0x8000}, -+ {0x2206, 0x0280}, {0x2206, 0x2bf7}, {0x2206, 0x00e0}, {0x2206, 0xfff7}, -+ {0x2206, 0xa080}, {0x2206, 0x02ae}, {0x2206, 0xf602}, {0x2206, 0x804e}, -+ {0x2206, 0x0201}, {0x2206, 0x5002}, {0x2206, 0x0163}, {0x2206, 0x0201}, -+ {0x2206, 0x79e0}, {0x2206, 0x8b8c}, {0x2206, 0xe18b}, {0x2206, 0x8d1e}, -+ {0x2206, 0x01e1}, {0x2206, 0x8b8e}, {0x2206, 0x1e01}, {0x2206, 0xa000}, -+ {0x2206, 0xe4ae}, {0x2206, 0xd8bf}, {0x2206, 0x8b88}, {0x2206, 0xec00}, -+ {0x2206, 0x19a9}, {0x2206, 0x8b90}, {0x2206, 0xf9ee}, {0x2206, 0xfff6}, -+ {0x2206, 0x00ee}, {0x2206, 0xfff7}, {0x2206, 0xfce0}, {0x2206, 0xe140}, -+ {0x2206, 0xe1e1}, {0x2206, 0x41f7}, {0x2206, 0x2ff6}, {0x2206, 0x28e4}, -+ {0x2206, 0xe140}, {0x2206, 0xe5e1}, {0x2206, 0x4104}, {0x2206, 0xf8fa}, -+ {0x2206, 0xef69}, {0x2206, 0xe08b}, {0x2206, 0x86ac}, {0x2206, 0x201a}, -+ {0x2206, 0xbf80}, {0x2206, 0x77d0}, {0x2206, 0x6c02}, {0x2206, 0x2978}, -+ {0x2206, 0xe0e0}, {0x2206, 0xe4e1}, {0x2206, 0xe0e5}, {0x2206, 0x5806}, -+ {0x2206, 0x68c0}, {0x2206, 0xd1d2}, {0x2206, 0xe4e0}, {0x2206, 0xe4e5}, -+ {0x2206, 0xe0e5}, {0x2206, 0xef96}, {0x2206, 0xfefc}, {0x2206, 0x0425}, -+ {0x2206, 0x0807}, {0x2206, 0x2640}, {0x2206, 0x7227}, {0x2206, 0x267e}, -+ {0x2206, 0x2804}, {0x2206, 0xb729}, {0x2206, 0x2576}, {0x2206, 0x2a68}, -+ {0x2206, 0xe52b}, {0x2206, 0xad00}, {0x2206, 0x2cdb}, {0x2206, 0xf02d}, -+ {0x2206, 0x67bb}, {0x2206, 0x2e7b}, {0x2206, 0x0f2f}, {0x2206, 0x7365}, -+ {0x2206, 0x31ac}, {0x2206, 0xcc32}, {0x2206, 0x2300}, {0x2206, 0x332d}, -+ {0x2206, 0x1734}, {0x2206, 0x7f52}, {0x2206, 0x3510}, {0x2206, 0x0036}, -+ {0x2206, 0x0600}, {0x2206, 0x370c}, {0x2206, 0xc038}, {0x2206, 0x7fce}, -+ {0x2206, 0x3ce5}, {0x2206, 0xf73d}, {0x2206, 0x3da4}, {0x2206, 0x6530}, -+ {0x2206, 0x3e67}, {0x2206, 0x0053}, {0x2206, 0x69d2}, {0x2206, 0x0f6a}, -+ {0x2206, 0x012c}, {0x2206, 0x6c2b}, {0x2206, 0x136e}, {0x2206, 0xe100}, -+ {0x2206, 0x6f12}, {0x2206, 0xf771}, {0x2206, 0x006b}, {0x2206, 0x7306}, -+ {0x2206, 0xeb74}, {0x2206, 0x94c7}, {0x2206, 0x7698}, {0x2206, 0x0a77}, -+ {0x2206, 0x5000}, {0x2206, 0x788a}, {0x2206, 0x1579}, {0x2206, 0x7f6f}, -+ {0x2206, 0x7a06}, {0x2206, 0xa600}, {0x2201, 0x0701}, {0x2200, 0x0405}, -+ {0x221f, 0x0000}, {0x2200, 0x1340}, {0x221f, 0x0000}, {0x133f, 0x0010}, -+ {0x133e, 0x0ffe}, {0x1203, 0xff00}, {0x1200, 0x7fc4}, {0x0900, 0x0000}, -+ {0x0901, 0x0000}, {0x0902, 0x0000}, {0x0903, 0x0000}, {0x0865, 0x3210}, -+ {0x087b, 0x0000}, {0x087c, 0xff00}, {0x087d, 0x0000}, {0x087e, 0x0000}, -+ {0x0801, 0x0100}, {0x0802, 0x0100}, {0x0A20, 0x2040}, {0x0A21, 0x2040}, -+ {0x0A22, 0x2040}, {0x0A23, 0x2040}, {0x0A24, 0x2040}, {0x0A25, 0x2040}, -+ {0x0A26, 0x2040}, {0x0A27, 0x2040}, {0x0A28, 0x2040}, {0x0A29, 0x2040}, -+ {0x130c, 0x0050}, -+}; -+ -+static int rtl8367_write_initvals(struct rtl8366_smi *smi, -+ const struct rtl8367_initval *initvals, -+ int count) -+{ -+ int err; -+ int i; -+ -+ for (i = 0; i < count; i++) -+ REG_WR(smi, initvals[i].reg, initvals[i].val); -+ -+ return 0; -+} -+ -+static int rtl8367_read_phy_reg(struct rtl8366_smi *smi, -+ u32 phy_addr, u32 phy_reg, u32 *val) -+{ -+ int timeout; -+ u32 data; -+ int err; -+ -+ if (phy_addr > RTL8367_PHY_ADDR_MAX) -+ return -EINVAL; -+ -+ if (phy_reg > RTL8367_PHY_REG_MAX) -+ return -EINVAL; -+ -+ REG_RD(smi, RTL8367_IA_STATUS_REG, &data); -+ if (data & RTL8367_IA_STATUS_PHY_BUSY) -+ return -ETIMEDOUT; -+ -+ /* prepare address */ -+ REG_WR(smi, RTL8367_IA_ADDRESS_REG, -+ RTL8367_INTERNAL_PHY_REG(phy_addr, phy_reg)); -+ -+ /* send read command */ -+ REG_WR(smi, RTL8367_IA_CTRL_REG, -+ RTL8367_IA_CTRL_CMD_MASK | RTL8367_IA_CTRL_RW_READ); -+ -+ timeout = 5; -+ do { -+ REG_RD(smi, RTL8367_IA_STATUS_REG, &data); -+ if ((data & RTL8367_IA_STATUS_PHY_BUSY) == 0) -+ break; -+ -+ if (timeout--) { -+ dev_err(smi->parent, "phy read timed out\n"); -+ return -ETIMEDOUT; -+ } -+ -+ udelay(1); -+ } while (1); -+ -+ /* read data */ -+ REG_RD(smi, RTL8367_IA_READ_DATA_REG, val); -+ -+ dev_dbg(smi->parent, "phy_read: addr:%02x, reg:%02x, val:%04x\n", -+ phy_addr, phy_reg, *val); -+ return 0; -+} -+ -+static int rtl8367_write_phy_reg(struct rtl8366_smi *smi, -+ u32 phy_addr, u32 phy_reg, u32 val) -+{ -+ int timeout; -+ u32 data; -+ int err; -+ -+ dev_dbg(smi->parent, "phy_write: addr:%02x, reg:%02x, val:%04x\n", -+ phy_addr, phy_reg, val); -+ -+ if (phy_addr > RTL8367_PHY_ADDR_MAX) -+ return -EINVAL; -+ -+ if (phy_reg > RTL8367_PHY_REG_MAX) -+ return -EINVAL; -+ -+ REG_RD(smi, RTL8367_IA_STATUS_REG, &data); -+ if (data & RTL8367_IA_STATUS_PHY_BUSY) -+ return -ETIMEDOUT; -+ -+ /* preapre data */ -+ REG_WR(smi, RTL8367_IA_WRITE_DATA_REG, val); -+ -+ /* prepare address */ -+ REG_WR(smi, RTL8367_IA_ADDRESS_REG, -+ RTL8367_INTERNAL_PHY_REG(phy_addr, phy_reg)); -+ -+ /* send write command */ -+ REG_WR(smi, RTL8367_IA_CTRL_REG, -+ RTL8367_IA_CTRL_CMD_MASK | RTL8367_IA_CTRL_RW_WRITE); -+ -+ timeout = 5; -+ do { -+ REG_RD(smi, RTL8367_IA_STATUS_REG, &data); -+ if ((data & RTL8367_IA_STATUS_PHY_BUSY) == 0) -+ break; -+ -+ if (timeout--) { -+ dev_err(smi->parent, "phy write timed out\n"); -+ return -ETIMEDOUT; -+ } -+ -+ udelay(1); -+ } while (1); -+ -+ return 0; -+} -+ -+static int rtl8367_init_regs0(struct rtl8366_smi *smi, unsigned mode) -+{ -+ const struct rtl8367_initval *initvals; -+ int count; -+ int err; -+ -+ switch (mode) { -+ case 0: -+ initvals = rtl8367_initvals_0_0; -+ count = ARRAY_SIZE(rtl8367_initvals_0_0); -+ break; -+ -+ case 1: -+ case 2: -+ initvals = rtl8367_initvals_0_1; -+ count = ARRAY_SIZE(rtl8367_initvals_0_1); -+ break; -+ -+ default: -+ dev_err(smi->parent, "%s: unknow mode %u\n", __func__, mode); -+ return -ENODEV; -+ } -+ -+ err = rtl8367_write_initvals(smi, initvals, count); -+ if (err) -+ return err; -+ -+ /* TODO: complete this */ -+ -+ return 0; -+} -+ -+static int rtl8367_init_regs1(struct rtl8366_smi *smi, unsigned mode) -+{ -+ const struct rtl8367_initval *initvals; -+ int count; -+ -+ switch (mode) { -+ case 0: -+ initvals = rtl8367_initvals_1_0; -+ count = ARRAY_SIZE(rtl8367_initvals_1_0); -+ break; -+ -+ case 1: -+ case 2: -+ initvals = rtl8367_initvals_1_1; -+ count = ARRAY_SIZE(rtl8367_initvals_1_1); -+ break; -+ -+ default: -+ dev_err(smi->parent, "%s: unknow mode %u\n", __func__, mode); -+ return -ENODEV; -+ } -+ -+ return rtl8367_write_initvals(smi, initvals, count); -+} -+ -+static int rtl8367_init_regs2(struct rtl8366_smi *smi, unsigned mode) -+{ -+ const struct rtl8367_initval *initvals; -+ int count; -+ -+ switch (mode) { -+ case 0: -+ initvals = rtl8367_initvals_2_0; -+ count = ARRAY_SIZE(rtl8367_initvals_2_0); -+ break; -+ -+ case 1: -+ case 2: -+ initvals = rtl8367_initvals_2_1; -+ count = ARRAY_SIZE(rtl8367_initvals_2_1); -+ break; -+ -+ default: -+ dev_err(smi->parent, "%s: unknow mode %u\n", __func__, mode); -+ return -ENODEV; -+ } -+ -+ return rtl8367_write_initvals(smi, initvals, count); -+} -+ -+static int rtl8367_init_regs(struct rtl8366_smi *smi) -+{ -+ u32 data; -+ u32 rlvid; -+ u32 mode; -+ int err; -+ -+ REG_WR(smi, RTL8367_RTL_MAGIC_ID_REG, RTL8367_RTL_MAGIC_ID_VAL); -+ -+ REG_RD(smi, RTL8367_CHIP_VER_REG, &data); -+ rlvid = (data >> RTL8367_CHIP_VER_RLVID_SHIFT) & -+ RTL8367_CHIP_VER_RLVID_MASK; -+ -+ REG_RD(smi, RTL8367_CHIP_MODE_REG, &data); -+ mode = data & RTL8367_CHIP_MODE_MASK; -+ -+ switch (rlvid) { -+ case 0: -+ err = rtl8367_init_regs0(smi, mode); -+ break; -+ -+ case 1: -+ err = rtl8367_write_phy_reg(smi, 0, 31, 5); -+ if (err) -+ break; -+ -+ err = rtl8367_write_phy_reg(smi, 0, 5, 0x3ffe); -+ if (err) -+ break; -+ -+ err = rtl8367_read_phy_reg(smi, 0, 6, &data); -+ if (err) -+ break; -+ -+ if (data == 0x94eb) { -+ err = rtl8367_init_regs1(smi, mode); -+ } else if (data == 0x2104) { -+ err = rtl8367_init_regs2(smi, mode); -+ } else { -+ dev_err(smi->parent, "unknow phy data %04x\n", data); -+ return -ENODEV; -+ } -+ -+ break; -+ -+ default: -+ dev_err(smi->parent, "unknow rlvid %u\n", rlvid); -+ err = -ENODEV; -+ break; -+ } -+ -+ return err; -+} -+ -+static int rtl8367_reset_chip(struct rtl8366_smi *smi) -+{ -+ int timeout = 10; -+ int err; -+ u32 data; -+ -+ REG_WR(smi, RTL8367_CHIP_RESET_REG, RTL8367_CHIP_RESET_HW); -+ msleep(RTL8367_RESET_DELAY); -+ -+ do { -+ REG_RD(smi, RTL8367_CHIP_RESET_REG, &data); -+ if (!(data & RTL8367_CHIP_RESET_HW)) -+ break; -+ -+ msleep(1); -+ } while (--timeout); -+ -+ if (!timeout) { -+ dev_err(smi->parent, "chip reset timed out\n"); -+ return -ETIMEDOUT; -+ } -+ -+ return 0; -+} -+ -+static int rtl8367_extif_set_mode(struct rtl8366_smi *smi, int id, -+ enum rtl8367_extif_mode mode) -+{ -+ int err; -+ -+ /* set port mode */ -+ switch (mode) { -+ case RTL8367_EXTIF_MODE_RGMII: -+ case RTL8367_EXTIF_MODE_RGMII_33V: -+ REG_WR(smi, RTL8367_CHIP_DEBUG0_REG, 0x0367); -+ REG_WR(smi, RTL8367_CHIP_DEBUG1_REG, 0x7777); -+ break; -+ -+ case RTL8367_EXTIF_MODE_TMII_MAC: -+ case RTL8367_EXTIF_MODE_TMII_PHY: -+ REG_RMW(smi, RTL8367_BYPASS_LINE_RATE_REG, -+ BIT((id + 1) % 2), BIT((id + 1) % 2)); -+ break; -+ -+ case RTL8367_EXTIF_MODE_GMII: -+ REG_RMW(smi, RTL8367_CHIP_DEBUG0_REG, -+ RTL8367_CHIP_DEBUG0_DUMMY0(id), -+ RTL8367_CHIP_DEBUG0_DUMMY0(id)); -+ REG_RMW(smi, RTL8367_EXT_RGMXF_REG(id), BIT(6), BIT(6)); -+ break; -+ -+ case RTL8367_EXTIF_MODE_MII_MAC: -+ case RTL8367_EXTIF_MODE_MII_PHY: -+ case RTL8367_EXTIF_MODE_DISABLED: -+ REG_RMW(smi, RTL8367_BYPASS_LINE_RATE_REG, -+ BIT((id + 1) % 2), 0); -+ REG_RMW(smi, RTL8367_EXT_RGMXF_REG(id), BIT(6), 0); -+ break; -+ -+ default: -+ dev_err(smi->parent, -+ "invalid mode for external interface %d\n", id); -+ return -EINVAL; -+ } -+ -+ REG_RMW(smi, RTL8367_DIS_REG, -+ RTL8367_DIS_RGMII_MASK << RTL8367_DIS_RGMII_SHIFT(id), -+ mode << RTL8367_DIS_RGMII_SHIFT(id)); -+ -+ return 0; -+} -+ -+static int rtl8367_extif_set_force(struct rtl8366_smi *smi, int id, -+ struct rtl8367_port_ability *pa) -+{ -+ u32 mask; -+ u32 val; -+ int err; -+ -+ mask = (RTL8367_DI_FORCE_MODE | -+ RTL8367_DI_FORCE_NWAY | -+ RTL8367_DI_FORCE_TXPAUSE | -+ RTL8367_DI_FORCE_RXPAUSE | -+ RTL8367_DI_FORCE_LINK | -+ RTL8367_DI_FORCE_DUPLEX | -+ RTL8367_DI_FORCE_SPEED_MASK); -+ -+ val = pa->speed; -+ val |= pa->force_mode ? RTL8367_DI_FORCE_MODE : 0; -+ val |= pa->nway ? RTL8367_DI_FORCE_NWAY : 0; -+ val |= pa->txpause ? RTL8367_DI_FORCE_TXPAUSE : 0; -+ val |= pa->rxpause ? RTL8367_DI_FORCE_RXPAUSE : 0; -+ val |= pa->link ? RTL8367_DI_FORCE_LINK : 0; -+ val |= pa->duplex ? RTL8367_DI_FORCE_DUPLEX : 0; -+ -+ REG_RMW(smi, RTL8367_DI_FORCE_REG(id), mask, val); -+ -+ return 0; -+} -+ -+static int rtl8367_extif_set_rgmii_delay(struct rtl8366_smi *smi, int id, -+ unsigned txdelay, unsigned rxdelay) -+{ -+ u32 mask; -+ u32 val; -+ int err; -+ -+ mask = (RTL8367_EXT_RGMXF_RXDELAY_MASK | -+ (RTL8367_EXT_RGMXF_TXDELAY_MASK << -+ RTL8367_EXT_RGMXF_TXDELAY_SHIFT)); -+ -+ val = rxdelay; -+ val |= txdelay << RTL8367_EXT_RGMXF_TXDELAY_SHIFT; -+ -+ REG_RMW(smi, RTL8367_EXT_RGMXF_REG(id), mask, val); -+ -+ return 0; -+} -+ -+static int rtl8367_extif_init(struct rtl8366_smi *smi, int id, -+ struct rtl8367_extif_config *cfg) -+{ -+ enum rtl8367_extif_mode mode; -+ int err; -+ -+ mode = (cfg) ? cfg->mode : RTL8367_EXTIF_MODE_DISABLED; -+ -+ err = rtl8367_extif_set_mode(smi, id, mode); -+ if (err) -+ return err; -+ -+ if (mode != RTL8367_EXTIF_MODE_DISABLED) { -+ err = rtl8367_extif_set_force(smi, id, &cfg->ability); -+ if (err) -+ return err; -+ -+ err = rtl8367_extif_set_rgmii_delay(smi, id, cfg->txdelay, -+ cfg->rxdelay); -+ if (err) -+ return err; -+ } -+ -+ return 0; -+} -+ -+static int rtl8367_led_group_set_ports(struct rtl8366_smi *smi, -+ unsigned int group, u16 port_mask) -+{ -+ u32 reg; -+ u32 s; -+ int err; -+ -+ port_mask &= RTL8367_PARA_LED_IO_EN_PMASK; -+ s = (group % 2) * 8; -+ reg = RTL8367_PARA_LED_IO_EN1_REG + (group / 2); -+ -+ REG_RMW(smi, reg, (RTL8367_PARA_LED_IO_EN_PMASK << s), port_mask << s); -+ -+ return 0; -+} -+ -+static int rtl8367_led_group_set_mode(struct rtl8366_smi *smi, -+ unsigned int mode) -+{ -+ u16 mask; -+ u16 set; -+ int err; -+ -+ mode &= RTL8367_LED_CONFIG_DATA_M; -+ -+ mask = (RTL8367_LED_CONFIG_DATA_M << RTL8367_LED_CONFIG_DATA_S) | -+ RTL8367_LED_CONFIG_SEL; -+ set = (mode << RTL8367_LED_CONFIG_DATA_S) | RTL8367_LED_CONFIG_SEL; -+ -+ REG_RMW(smi, RTL8367_LED_CONFIG_REG, mask, set); -+ -+ return 0; -+} -+ -+static int rtl8367_led_group_set_config(struct rtl8366_smi *smi, -+ unsigned int led, unsigned int cfg) -+{ -+ u16 mask; -+ u16 set; -+ int err; -+ -+ mask = (RTL8367_LED_CONFIG_LED_CFG_M << (led * 4)) | -+ RTL8367_LED_CONFIG_SEL; -+ set = (cfg & RTL8367_LED_CONFIG_LED_CFG_M) << (led * 4); -+ -+ REG_RMW(smi, RTL8367_LED_CONFIG_REG, mask, set); -+ return 0; -+} -+ -+static int rtl8367_led_op_select_parallel(struct rtl8366_smi *smi) -+{ -+ int err; -+ -+ REG_WR(smi, RTL8367_LED_SYS_CONFIG_REG, 0x1472); -+ return 0; -+} -+ -+static int rtl8367_led_blinkrate_set(struct rtl8366_smi *smi, unsigned int rate) -+{ -+ u16 mask; -+ u16 set; -+ int err; -+ -+ mask = RTL8367_LED_MODE_RATE_M << RTL8367_LED_MODE_RATE_S; -+ set = (rate & RTL8367_LED_MODE_RATE_M) << RTL8367_LED_MODE_RATE_S; -+ REG_RMW(smi, RTL8367_LED_MODE_REG, mask, set); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_OF -+static int rtl8367_extif_init_of(struct rtl8366_smi *smi, -+ const char *name) -+{ -+ struct rtl8367_extif_config *cfg; -+ const __be32 *prop; -+ int size; -+ int err; -+ unsigned cpu_port; -+ unsigned id = UINT_MAX; -+ -+ prop = of_get_property(smi->parent->of_node, name, &size); -+ if (!prop || (size != (10 * sizeof(*prop)))) { -+ dev_err(smi->parent, "%s property is not defined or invalid\n", name); -+ err = -EINVAL; -+ goto err_init; -+ } -+ -+ cpu_port = be32_to_cpup(prop++); -+ switch (cpu_port) { -+ case RTL8367_CPU_PORT_NUM - 1: -+ case RTL8367_CPU_PORT_NUM: -+ id = RTL8367_CPU_PORT_NUM - cpu_port; -+ if (smi->cpu_port == UINT_MAX) { -+ dev_info(smi->parent, "cpu_port:%u, assigned to extif%u\n", cpu_port, id); -+ smi->cpu_port = cpu_port; -+ } -+ break; -+ default: -+ dev_err(smi->parent, "wrong cpu_port %u in %s property\n", cpu_port, name); -+ err = -EINVAL; -+ goto err_init; -+ } -+ -+ cfg = kzalloc(sizeof(struct rtl8367_extif_config), GFP_KERNEL); -+ if (!cfg) -+ return -ENOMEM; -+ -+ cfg->txdelay = be32_to_cpup(prop++); -+ cfg->rxdelay = be32_to_cpup(prop++); -+ cfg->mode = be32_to_cpup(prop++); -+ cfg->ability.force_mode = be32_to_cpup(prop++); -+ cfg->ability.txpause = be32_to_cpup(prop++); -+ cfg->ability.rxpause = be32_to_cpup(prop++); -+ cfg->ability.link = be32_to_cpup(prop++); -+ cfg->ability.duplex = be32_to_cpup(prop++); -+ cfg->ability.speed = be32_to_cpup(prop++); -+ -+ err = rtl8367_extif_init(smi, id, cfg); -+ kfree(cfg); -+ -+err_init: -+ if (id != 0) rtl8367_extif_init(smi, 0, NULL); -+ if (id != 1) rtl8367_extif_init(smi, 1, NULL); -+ -+ return err; -+} -+#else -+static int rtl8367_extif_init_of(struct rtl8366_smi *smi, -+ const char *name) -+{ -+ return -EINVAL; -+} -+#endif -+ -+static int rtl8367_setup(struct rtl8366_smi *smi) -+{ -+ struct rtl8367_platform_data *pdata; -+ int err; -+ int i; -+ -+ pdata = smi->parent->platform_data; -+ -+ err = rtl8367_init_regs(smi); -+ if (err) -+ return err; -+ -+ /* initialize external interfaces */ -+ if (smi->parent->of_node) { -+ err = rtl8367_extif_init_of(smi, "realtek,extif"); -+ if (err) -+ return err; -+ } else { -+ err = rtl8367_extif_init(smi, 0, pdata->extif0_cfg); -+ if (err) -+ return err; -+ -+ err = rtl8367_extif_init(smi, 1, pdata->extif1_cfg); -+ if (err) -+ return err; -+ } -+ -+ /* set maximum packet length to 1536 bytes */ -+ REG_RMW(smi, RTL8367_SWC0_REG, RTL8367_SWC0_MAX_LENGTH_MASK, -+ RTL8367_SWC0_MAX_LENGTH_1536); -+ -+ /* -+ * discard VLAN tagged packets if the port is not a member of -+ * the VLAN with which the packets is associated. -+ */ -+ REG_WR(smi, RTL8367_VLAN_INGRESS_REG, RTL8367_PORTS_ALL); -+ -+ /* -+ * Setup egress tag mode for each port. -+ */ -+ for (i = 0; i < RTL8367_NUM_PORTS; i++) -+ REG_RMW(smi, -+ RTL8367_PORT_CFG_REG(i), -+ RTL8367_PORT_CFG_EGRESS_MODE_MASK << -+ RTL8367_PORT_CFG_EGRESS_MODE_SHIFT, -+ RTL8367_PORT_CFG_EGRESS_MODE_ORIGINAL << -+ RTL8367_PORT_CFG_EGRESS_MODE_SHIFT); -+ -+ /* setup LEDs */ -+ err = rtl8367_led_group_set_ports(smi, 0, RTL8367_PORTS_ALL); -+ if (err) -+ return err; -+ -+ err = rtl8367_led_group_set_mode(smi, 0); -+ if (err) -+ return err; -+ -+ err = rtl8367_led_op_select_parallel(smi); -+ if (err) -+ return err; -+ -+ err = rtl8367_led_blinkrate_set(smi, 1); -+ if (err) -+ return err; -+ -+ err = rtl8367_led_group_set_config(smi, 0, 2); -+ if (err) -+ return err; -+ -+ return 0; -+} -+ -+static int rtl8367_get_mib_counter(struct rtl8366_smi *smi, int counter, -+ int port, unsigned long long *val) -+{ -+ struct rtl8366_mib_counter *mib; -+ int offset; -+ int i; -+ int err; -+ u32 addr, data; -+ u64 mibvalue; -+ -+ if (port > RTL8367_NUM_PORTS || counter >= RTL8367_MIB_COUNT) -+ return -EINVAL; -+ -+ mib = &rtl8367_mib_counters[counter]; -+ addr = RTL8367_MIB_COUNTER_PORT_OFFSET * port + mib->offset; -+ -+ /* -+ * Writing access counter address first -+ * then ASIC will prepare 64bits counter wait for being retrived -+ */ -+ REG_WR(smi, RTL8367_MIB_ADDRESS_REG, addr >> 2); -+ -+ /* read MIB control register */ -+ REG_RD(smi, RTL8367_MIB_CTRL_REG(0), &data); -+ -+ if (data & RTL8367_MIB_CTRL_BUSY_MASK) -+ return -EBUSY; -+ -+ if (data & RTL8367_MIB_CTRL_RESET_MASK) -+ return -EIO; -+ -+ if (mib->length == 4) -+ offset = 3; -+ else -+ offset = (mib->offset + 1) % 4; -+ -+ mibvalue = 0; -+ for (i = 0; i < mib->length; i++) { -+ REG_RD(smi, RTL8367_MIB_COUNTER_REG(offset - i), &data); -+ mibvalue = (mibvalue << 16) | (data & 0xFFFF); -+ } -+ -+ *val = mibvalue; -+ return 0; -+} -+ -+static int rtl8367_get_vlan_4k(struct rtl8366_smi *smi, u32 vid, -+ struct rtl8366_vlan_4k *vlan4k) -+{ -+ u32 data[RTL8367_TA_VLAN_DATA_SIZE]; -+ int err; -+ int i; -+ -+ memset(vlan4k, '\0', sizeof(struct rtl8366_vlan_4k)); -+ -+ if (vid >= RTL8367_NUM_VIDS) -+ return -EINVAL; -+ -+ /* write VID */ -+ REG_WR(smi, RTL8367_TA_ADDR_REG, vid); -+ -+ /* write table access control word */ -+ REG_WR(smi, RTL8367_TA_CTRL_REG, RTL8367_TA_CTRL_CVLAN_READ); -+ -+ for (i = 0; i < ARRAY_SIZE(data); i++) -+ REG_RD(smi, RTL8367_TA_DATA_REG(i), &data[i]); -+ -+ vlan4k->vid = vid; -+ vlan4k->member = (data[0] >> RTL8367_TA_VLAN_MEMBER_SHIFT) & -+ RTL8367_TA_VLAN_MEMBER_MASK; -+ vlan4k->fid = (data[1] >> RTL8367_TA_VLAN_FID_SHIFT) & -+ RTL8367_TA_VLAN_FID_MASK; -+ vlan4k->untag = (data[2] >> RTL8367_TA_VLAN_UNTAG1_SHIFT) & -+ RTL8367_TA_VLAN_UNTAG1_MASK; -+ vlan4k->untag |= ((data[3] >> RTL8367_TA_VLAN_UNTAG2_SHIFT) & -+ RTL8367_TA_VLAN_UNTAG2_MASK) << 2; -+ -+ return 0; -+} -+ -+static int rtl8367_set_vlan_4k(struct rtl8366_smi *smi, -+ const struct rtl8366_vlan_4k *vlan4k) -+{ -+ u32 data[RTL8367_TA_VLAN_DATA_SIZE]; -+ int err; -+ int i; -+ -+ if (vlan4k->vid >= RTL8367_NUM_VIDS || -+ vlan4k->member > RTL8367_TA_VLAN_MEMBER_MASK || -+ vlan4k->untag > RTL8367_UNTAG_MASK || -+ vlan4k->fid > RTL8367_FIDMAX) -+ return -EINVAL; -+ -+ data[0] = (vlan4k->member & RTL8367_TA_VLAN_MEMBER_MASK) << -+ RTL8367_TA_VLAN_MEMBER_SHIFT; -+ data[1] = (vlan4k->fid & RTL8367_TA_VLAN_FID_MASK) << -+ RTL8367_TA_VLAN_FID_SHIFT; -+ data[2] = (vlan4k->untag & RTL8367_TA_VLAN_UNTAG1_MASK) << -+ RTL8367_TA_VLAN_UNTAG1_SHIFT; -+ data[3] = ((vlan4k->untag >> 2) & RTL8367_TA_VLAN_UNTAG2_MASK) << -+ RTL8367_TA_VLAN_UNTAG2_SHIFT; -+ -+ for (i = 0; i < ARRAY_SIZE(data); i++) -+ REG_WR(smi, RTL8367_TA_DATA_REG(i), data[i]); -+ -+ /* write VID */ -+ REG_WR(smi, RTL8367_TA_ADDR_REG, -+ vlan4k->vid & RTL8367_TA_VLAN_VID_MASK); -+ -+ /* write table access control word */ -+ REG_WR(smi, RTL8367_TA_CTRL_REG, RTL8367_TA_CTRL_CVLAN_WRITE); -+ -+ return 0; -+} -+ -+static int rtl8367_get_vlan_mc(struct rtl8366_smi *smi, u32 index, -+ struct rtl8366_vlan_mc *vlanmc) -+{ -+ u32 data[RTL8367_VLAN_MC_DATA_SIZE]; -+ int err; -+ int i; -+ -+ memset(vlanmc, '\0', sizeof(struct rtl8366_vlan_mc)); -+ -+ if (index >= RTL8367_NUM_VLANS) -+ return -EINVAL; -+ -+ for (i = 0; i < ARRAY_SIZE(data); i++) -+ REG_RD(smi, RTL8367_VLAN_MC_BASE(index) + i, &data[i]); -+ -+ vlanmc->member = (data[0] >> RTL8367_VLAN_MC_MEMBER_SHIFT) & -+ RTL8367_VLAN_MC_MEMBER_MASK; -+ vlanmc->fid = (data[1] >> RTL8367_VLAN_MC_FID_SHIFT) & -+ RTL8367_VLAN_MC_FID_MASK; -+ vlanmc->vid = (data[3] >> RTL8367_VLAN_MC_EVID_SHIFT) & -+ RTL8367_VLAN_MC_EVID_MASK; -+ -+ return 0; -+} -+ -+static int rtl8367_set_vlan_mc(struct rtl8366_smi *smi, u32 index, -+ const struct rtl8366_vlan_mc *vlanmc) -+{ -+ u32 data[RTL8367_VLAN_MC_DATA_SIZE]; -+ int err; -+ int i; -+ -+ if (index >= RTL8367_NUM_VLANS || -+ vlanmc->vid >= RTL8367_NUM_VIDS || -+ vlanmc->priority > RTL8367_PRIORITYMAX || -+ vlanmc->member > RTL8367_VLAN_MC_MEMBER_MASK || -+ vlanmc->untag > RTL8367_UNTAG_MASK || -+ vlanmc->fid > RTL8367_FIDMAX) -+ return -EINVAL; -+ -+ data[0] = (vlanmc->member & RTL8367_VLAN_MC_MEMBER_MASK) << -+ RTL8367_VLAN_MC_MEMBER_SHIFT; -+ data[1] = (vlanmc->fid & RTL8367_VLAN_MC_FID_MASK) << -+ RTL8367_VLAN_MC_FID_SHIFT; -+ data[2] = 0; -+ data[3] = (vlanmc->vid & RTL8367_VLAN_MC_EVID_MASK) << -+ RTL8367_VLAN_MC_EVID_SHIFT; -+ -+ for (i = 0; i < ARRAY_SIZE(data); i++) -+ REG_WR(smi, RTL8367_VLAN_MC_BASE(index) + i, data[i]); -+ -+ return 0; -+} -+ -+static int rtl8367_get_mc_index(struct rtl8366_smi *smi, int port, int *val) -+{ -+ u32 data; -+ int err; -+ -+ if (port >= RTL8367_NUM_PORTS) -+ return -EINVAL; -+ -+ REG_RD(smi, RTL8367_VLAN_PVID_CTRL_REG(port), &data); -+ -+ *val = (data >> RTL8367_VLAN_PVID_CTRL_SHIFT(port)) & -+ RTL8367_VLAN_PVID_CTRL_MASK; -+ -+ return 0; -+} -+ -+static int rtl8367_set_mc_index(struct rtl8366_smi *smi, int port, int index) -+{ -+ if (port >= RTL8367_NUM_PORTS || index >= RTL8367_NUM_VLANS) -+ return -EINVAL; -+ -+ return rtl8366_smi_rmwr(smi, RTL8367_VLAN_PVID_CTRL_REG(port), -+ RTL8367_VLAN_PVID_CTRL_MASK << -+ RTL8367_VLAN_PVID_CTRL_SHIFT(port), -+ (index & RTL8367_VLAN_PVID_CTRL_MASK) << -+ RTL8367_VLAN_PVID_CTRL_SHIFT(port)); -+} -+ -+static int rtl8367_enable_vlan(struct rtl8366_smi *smi, int enable) -+{ -+ return rtl8366_smi_rmwr(smi, RTL8367_VLAN_CTRL_REG, -+ RTL8367_VLAN_CTRL_ENABLE, -+ (enable) ? RTL8367_VLAN_CTRL_ENABLE : 0); -+} -+ -+static int rtl8367_enable_vlan4k(struct rtl8366_smi *smi, int enable) -+{ -+ return 0; -+} -+ -+static int rtl8367_is_vlan_valid(struct rtl8366_smi *smi, unsigned vlan) -+{ -+ unsigned max = RTL8367_NUM_VLANS; -+ -+ if (smi->vlan4k_enabled) -+ max = RTL8367_NUM_VIDS - 1; -+ -+ if (vlan == 0 || vlan >= max) -+ return 0; -+ -+ return 1; -+} -+ -+static int rtl8367_enable_port(struct rtl8366_smi *smi, int port, int enable) -+{ -+ int err; -+ -+ REG_WR(smi, RTL8367_PORT_ISOLATION_REG(port), -+ (enable) ? RTL8367_PORTS_ALL : 0); -+ -+ return 0; -+} -+ -+static int rtl8367_sw_reset_mibs(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ -+ return rtl8366_smi_rmwr(smi, RTL8367_MIB_CTRL_REG(0), 0, -+ RTL8367_MIB_CTRL_GLOBAL_RESET_MASK); -+} -+ -+static int rtl8367_sw_get_port_link(struct switch_dev *dev, -+ int port, -+ struct switch_port_link *link) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data = 0; -+ u32 speed; -+ -+ if (port >= RTL8367_NUM_PORTS) -+ return -EINVAL; -+ -+ rtl8366_smi_read_reg(smi, RTL8367_PORT_STATUS_REG(port), &data); -+ -+ link->link = !!(data & RTL8367_PORT_STATUS_LINK); -+ if (!link->link) -+ return 0; -+ -+ link->duplex = !!(data & RTL8367_PORT_STATUS_DUPLEX); -+ link->rx_flow = !!(data & RTL8367_PORT_STATUS_RXPAUSE); -+ link->tx_flow = !!(data & RTL8367_PORT_STATUS_TXPAUSE); -+ link->aneg = !!(data & RTL8367_PORT_STATUS_NWAY); -+ -+ speed = (data & RTL8367_PORT_STATUS_SPEED_MASK); -+ switch (speed) { -+ case 0: -+ link->speed = SWITCH_PORT_SPEED_10; -+ break; -+ case 1: -+ link->speed = SWITCH_PORT_SPEED_100; -+ break; -+ case 2: -+ link->speed = SWITCH_PORT_SPEED_1000; -+ break; -+ default: -+ link->speed = SWITCH_PORT_SPEED_UNKNOWN; -+ break; -+ } -+ -+ return 0; -+} -+ -+static int rtl8367_sw_get_max_length(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data; -+ -+ rtl8366_smi_read_reg(smi, RTL8367_SWC0_REG, &data); -+ val->value.i = (data & RTL8367_SWC0_MAX_LENGTH_MASK) >> -+ RTL8367_SWC0_MAX_LENGTH_SHIFT; -+ -+ return 0; -+} -+ -+static int rtl8367_sw_set_max_length(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 max_len; -+ -+ switch (val->value.i) { -+ case 0: -+ max_len = RTL8367_SWC0_MAX_LENGTH_1522; -+ break; -+ case 1: -+ max_len = RTL8367_SWC0_MAX_LENGTH_1536; -+ break; -+ case 2: -+ max_len = RTL8367_SWC0_MAX_LENGTH_1552; -+ break; -+ case 3: -+ max_len = RTL8367_SWC0_MAX_LENGTH_16000; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return rtl8366_smi_rmwr(smi, RTL8367_SWC0_REG, -+ RTL8367_SWC0_MAX_LENGTH_MASK, max_len); -+} -+ -+ -+static int rtl8367_sw_reset_port_mibs(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ int port; -+ -+ port = val->port_vlan; -+ if (port >= RTL8367_NUM_PORTS) -+ return -EINVAL; -+ -+ return rtl8366_smi_rmwr(smi, RTL8367_MIB_CTRL_REG(port / 8), 0, -+ RTL8367_MIB_CTRL_PORT_RESET_MASK(port % 8)); -+} -+ -+static int rtl8367_sw_get_port_stats(struct switch_dev *dev, int port, -+ struct switch_port_stats *stats) -+{ -+ return (rtl8366_sw_get_port_stats(dev, port, stats, -+ RTL8367_MIB_TXB_ID, RTL8367_MIB_RXB_ID)); -+} -+ -+static struct switch_attr rtl8367_globals[] = { -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_vlan", -+ .description = "Enable VLAN mode", -+ .set = rtl8366_sw_set_vlan_enable, -+ .get = rtl8366_sw_get_vlan_enable, -+ .max = 1, -+ .ofs = 1 -+ }, { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_vlan4k", -+ .description = "Enable VLAN 4K mode", -+ .set = rtl8366_sw_set_vlan_enable, -+ .get = rtl8366_sw_get_vlan_enable, -+ .max = 1, -+ .ofs = 2 -+ }, { -+ .type = SWITCH_TYPE_NOVAL, -+ .name = "reset_mibs", -+ .description = "Reset all MIB counters", -+ .set = rtl8367_sw_reset_mibs, -+ }, { -+ .type = SWITCH_TYPE_INT, -+ .name = "max_length", -+ .description = "Get/Set the maximum length of valid packets" -+ "(0:1522, 1:1536, 2:1552, 3:16000)", -+ .set = rtl8367_sw_set_max_length, -+ .get = rtl8367_sw_get_max_length, -+ .max = 3, -+ } -+}; -+ -+static struct switch_attr rtl8367_port[] = { -+ { -+ .type = SWITCH_TYPE_NOVAL, -+ .name = "reset_mib", -+ .description = "Reset single port MIB counters", -+ .set = rtl8367_sw_reset_port_mibs, -+ }, { -+ .type = SWITCH_TYPE_STRING, -+ .name = "mib", -+ .description = "Get MIB counters for port", -+ .max = 33, -+ .set = NULL, -+ .get = rtl8366_sw_get_port_mib, -+ }, -+}; -+ -+static struct switch_attr rtl8367_vlan[] = { -+ { -+ .type = SWITCH_TYPE_STRING, -+ .name = "info", -+ .description = "Get vlan information", -+ .max = 1, -+ .set = NULL, -+ .get = rtl8366_sw_get_vlan_info, -+ }, { -+ .type = SWITCH_TYPE_INT, -+ .name = "fid", -+ .description = "Get/Set vlan FID", -+ .max = RTL8367_FIDMAX, -+ .set = rtl8366_sw_set_vlan_fid, -+ .get = rtl8366_sw_get_vlan_fid, -+ }, -+}; -+ -+static const struct switch_dev_ops rtl8367_sw_ops = { -+ .attr_global = { -+ .attr = rtl8367_globals, -+ .n_attr = ARRAY_SIZE(rtl8367_globals), -+ }, -+ .attr_port = { -+ .attr = rtl8367_port, -+ .n_attr = ARRAY_SIZE(rtl8367_port), -+ }, -+ .attr_vlan = { -+ .attr = rtl8367_vlan, -+ .n_attr = ARRAY_SIZE(rtl8367_vlan), -+ }, -+ -+ .get_vlan_ports = rtl8366_sw_get_vlan_ports, -+ .set_vlan_ports = rtl8366_sw_set_vlan_ports, -+ .get_port_pvid = rtl8366_sw_get_port_pvid, -+ .set_port_pvid = rtl8366_sw_set_port_pvid, -+ .reset_switch = rtl8366_sw_reset_switch, -+ .get_port_link = rtl8367_sw_get_port_link, -+ .get_port_stats = rtl8367_sw_get_port_stats, -+}; -+ -+static int rtl8367_switch_init(struct rtl8366_smi *smi) -+{ -+ struct switch_dev *dev = &smi->sw_dev; -+ int err; -+ -+ dev->name = "RTL8367"; -+ dev->cpu_port = smi->cpu_port; -+ dev->ports = RTL8367_NUM_PORTS; -+ dev->vlans = RTL8367_NUM_VIDS; -+ dev->ops = &rtl8367_sw_ops; -+ dev->alias = dev_name(smi->parent); -+ -+ err = register_switch(dev, NULL); -+ if (err) -+ dev_err(smi->parent, "switch registration failed\n"); -+ -+ return err; -+} -+ -+static void rtl8367_switch_cleanup(struct rtl8366_smi *smi) -+{ -+ unregister_switch(&smi->sw_dev); -+} -+ -+static int rtl8367_mii_read(struct mii_bus *bus, int addr, int reg) -+{ -+ struct rtl8366_smi *smi = bus->priv; -+ u32 val = 0; -+ int err; -+ -+ err = rtl8367_read_phy_reg(smi, addr, reg, &val); -+ if (err) -+ return 0xffff; -+ -+ return val; -+} -+ -+static int rtl8367_mii_write(struct mii_bus *bus, int addr, int reg, u16 val) -+{ -+ struct rtl8366_smi *smi = bus->priv; -+ u32 t; -+ int err; -+ -+ err = rtl8367_write_phy_reg(smi, addr, reg, val); -+ if (err) -+ return err; -+ -+ /* flush write */ -+ (void) rtl8367_read_phy_reg(smi, addr, reg, &t); -+ -+ return err; -+} -+ -+static int rtl8367_detect(struct rtl8366_smi *smi) -+{ -+ u32 rtl_no = 0; -+ u32 rtl_ver = 0; -+ char *chip_name; -+ int ret; -+ -+ ret = rtl8366_smi_read_reg(smi, RTL8367_RTL_NO_REG, &rtl_no); -+ if (ret) { -+ dev_err(smi->parent, "unable to read chip number\n"); -+ return ret; -+ } -+ -+ switch (rtl_no) { -+ case RTL8367_RTL_NO_8367R: -+ chip_name = "8367R"; -+ break; -+ case RTL8367_RTL_NO_8367M: -+ chip_name = "8367M"; -+ break; -+ default: -+ dev_err(smi->parent, "unknown chip number (%04x)\n", rtl_no); -+ return -ENODEV; -+ } -+ -+ ret = rtl8366_smi_read_reg(smi, RTL8367_RTL_VER_REG, &rtl_ver); -+ if (ret) { -+ dev_err(smi->parent, "unable to read chip version\n"); -+ return ret; -+ } -+ -+ dev_info(smi->parent, "RTL%s ver. %u chip found\n", -+ chip_name, rtl_ver & RTL8367_RTL_VER_MASK); -+ -+ return 0; -+} -+ -+static struct rtl8366_smi_ops rtl8367_smi_ops = { -+ .detect = rtl8367_detect, -+ .reset_chip = rtl8367_reset_chip, -+ .setup = rtl8367_setup, -+ -+ .mii_read = rtl8367_mii_read, -+ .mii_write = rtl8367_mii_write, -+ -+ .get_vlan_mc = rtl8367_get_vlan_mc, -+ .set_vlan_mc = rtl8367_set_vlan_mc, -+ .get_vlan_4k = rtl8367_get_vlan_4k, -+ .set_vlan_4k = rtl8367_set_vlan_4k, -+ .get_mc_index = rtl8367_get_mc_index, -+ .set_mc_index = rtl8367_set_mc_index, -+ .get_mib_counter = rtl8367_get_mib_counter, -+ .is_vlan_valid = rtl8367_is_vlan_valid, -+ .enable_vlan = rtl8367_enable_vlan, -+ .enable_vlan4k = rtl8367_enable_vlan4k, -+ .enable_port = rtl8367_enable_port, -+}; -+ -+static int rtl8367_probe(struct platform_device *pdev) -+{ -+ struct rtl8366_smi *smi; -+ int err; -+ -+ smi = rtl8366_smi_probe(pdev); -+ if (IS_ERR(smi)) -+ return PTR_ERR(smi); -+ -+ smi->clk_delay = 1500; -+ smi->cmd_read = 0xb9; -+ smi->cmd_write = 0xb8; -+ smi->ops = &rtl8367_smi_ops; -+ smi->cpu_port = UINT_MAX; /* not defined yet */ -+ smi->num_ports = RTL8367_NUM_PORTS; -+ smi->num_vlan_mc = RTL8367_NUM_VLANS; -+ smi->mib_counters = rtl8367_mib_counters; -+ smi->num_mib_counters = ARRAY_SIZE(rtl8367_mib_counters); -+ -+ err = rtl8366_smi_init(smi); -+ if (err) -+ goto err_free_smi; -+ -+ platform_set_drvdata(pdev, smi); -+ -+ err = rtl8367_switch_init(smi); -+ if (err) -+ goto err_clear_drvdata; -+ -+ return 0; -+ -+ err_clear_drvdata: -+ platform_set_drvdata(pdev, NULL); -+ rtl8366_smi_cleanup(smi); -+ err_free_smi: -+ kfree(smi); -+ return err; -+} -+ -+static void rtl8367_remove(struct platform_device *pdev) -+{ -+ struct rtl8366_smi *smi = platform_get_drvdata(pdev); -+ -+ if (smi) { -+ rtl8367_switch_cleanup(smi); -+ platform_set_drvdata(pdev, NULL); -+ rtl8366_smi_cleanup(smi); -+ kfree(smi); -+ } -+} -+ -+static void rtl8367_shutdown(struct platform_device *pdev) -+{ -+ struct rtl8366_smi *smi = platform_get_drvdata(pdev); -+ -+ if (smi) -+ rtl8367_reset_chip(smi); -+} -+ -+#ifdef CONFIG_OF -+static const struct of_device_id rtl8367_match[] = { -+ { .compatible = "realtek,rtl8367" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, rtl8367_match); -+#endif -+ -+static struct platform_driver rtl8367_driver = { -+ .driver = { -+ .name = RTL8367_DRIVER_NAME, -+#ifdef CONFIG_OF -+ .of_match_table = of_match_ptr(rtl8367_match), -+#endif -+ }, -+ .probe = rtl8367_probe, -+ .remove_new = rtl8367_remove, -+ .shutdown = rtl8367_shutdown, -+}; -+ -+static int __init rtl8367_module_init(void) -+{ -+ return platform_driver_register(&rtl8367_driver); -+} -+module_init(rtl8367_module_init); -+ -+static void __exit rtl8367_module_exit(void) -+{ -+ platform_driver_unregister(&rtl8367_driver); -+} -+module_exit(rtl8367_module_exit); -+ -+MODULE_DESCRIPTION("Realtek RTL8367 ethernet switch driver"); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:" RTL8367_DRIVER_NAME); -diff --git a/drivers/net/phy/rtl8367b.c b/drivers/net/phy/rtl8367b.c -new file mode 100644 -index 000000000000..5adcf00f0cac ---- /dev/null -+++ b/drivers/net/phy/rtl8367b.c -@@ -0,0 +1,1649 @@ -+/* -+ * Platform driver for Realtek RTL8367B family chips, i.e. RTL8367RB and RTL8367R-VB -+ * extended with support for RTL8367C family chips, i.e. RTL8367RB-VB and RTL8367S -+ * extended with support for RTL8367D family chips, i.e. RTL8367S-VB -+ * -+ * Copyright (C) 2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "rtl8366_smi.h" -+ -+#define RTL8367B_RESET_DELAY 1000 /* msecs*/ -+ -+#define RTL8367B_PHY_ADDR_MAX 8 -+#define RTL8367B_PHY_REG_MAX 31 -+ -+#define RTL8367B_VID_MASK 0x3fff -+#define RTL8367B_FID_MASK 0xf -+#define RTL8367B_UNTAG_MASK 0xff -+#define RTL8367B_MEMBER_MASK 0xff -+ -+#define RTL8367B_PORT_MISC_CFG_REG(_p) (0x000e + 0x20 * (_p)) -+#define RTL8367B_PORT_MISC_CFG_EGRESS_MODE_SHIFT 4 -+#define RTL8367B_PORT_MISC_CFG_EGRESS_MODE_MASK 0x3 -+#define RTL8367B_PORT_MISC_CFG_EGRESS_MODE_ORIGINAL 0 -+#define RTL8367B_PORT_MISC_CFG_EGRESS_MODE_KEEP 1 -+#define RTL8367B_PORT_MISC_CFG_EGRESS_MODE_PRI 2 -+#define RTL8367B_PORT_MISC_CFG_EGRESS_MODE_REAL 3 -+ -+#define RTL8367B_BYPASS_LINE_RATE_REG 0x03f7 -+ -+#define RTL8367B_TA_CTRL_REG 0x0500 /*GOOD*/ -+#define RTL8367B_TA_CTRL_SPA_SHIFT 8 -+#define RTL8367B_TA_CTRL_SPA_MASK 0x7 -+#define RTL8367B_TA_CTRL_METHOD BIT(4)/*GOOD*/ -+#define RTL8367B_TA_CTRL_CMD_SHIFT 3 -+#define RTL8367B_TA_CTRL_CMD_READ 0 -+#define RTL8367B_TA_CTRL_CMD_WRITE 1 -+#define RTL8367B_TA_CTRL_TABLE_SHIFT 0 /*GOOD*/ -+#define RTL8367B_TA_CTRL_TABLE_ACLRULE 1 -+#define RTL8367B_TA_CTRL_TABLE_ACLACT 2 -+#define RTL8367B_TA_CTRL_TABLE_CVLAN 3 -+#define RTL8367B_TA_CTRL_TABLE_L2 4 -+#define RTL8367B_TA_CTRL_CVLAN_READ \ -+ ((RTL8367B_TA_CTRL_CMD_READ << RTL8367B_TA_CTRL_CMD_SHIFT) | \ -+ RTL8367B_TA_CTRL_TABLE_CVLAN) -+#define RTL8367B_TA_CTRL_CVLAN_WRITE \ -+ ((RTL8367B_TA_CTRL_CMD_WRITE << RTL8367B_TA_CTRL_CMD_SHIFT) | \ -+ RTL8367B_TA_CTRL_TABLE_CVLAN) -+ -+#define RTL8367B_TA_ADDR_REG 0x0501/*GOOD*/ -+#define RTL8367B_TA_ADDR_MASK 0x3fff/*GOOD*/ -+ -+#define RTL8367B_TA_LUT_REG 0x0502/*GOOD*/ -+ -+#define RTL8367B_TA_WRDATA_REG(_x) (0x0510 + (_x))/*GOOD*/ -+#define RTL8367B_TA_VLAN_NUM_WORDS 2 -+#define RTL8367B_TA_VLAN_VID_MASK RTL8367B_VID_MASK -+#define RTL8367B_TA_VLAN0_MEMBER_SHIFT 0 -+#define RTL8367B_TA_VLAN0_MEMBER_MASK RTL8367B_MEMBER_MASK -+#define RTL8367B_TA_VLAN0_UNTAG_SHIFT 8 -+#define RTL8367B_TA_VLAN0_UNTAG_MASK RTL8367B_MEMBER_MASK -+#define RTL8367B_TA_VLAN1_FID_SHIFT 0 -+#define RTL8367B_TA_VLAN1_FID_MASK RTL8367B_FID_MASK -+ -+#define RTL8367B_TA_RDDATA_REG(_x) (0x0520 + (_x))/*GOOD*/ -+ -+#define RTL8367B_VLAN_PVID_CTRL_REG(_p) (0x0700 + (_p) / 2) /*GOOD*/ -+#define RTL8367B_VLAN_PVID_CTRL_MASK 0x1f /*GOOD*/ -+#define RTL8367B_VLAN_PVID_CTRL_SHIFT(_p) (8 * ((_p) % 2)) /*GOOD*/ -+ -+#define RTL8367B_VLAN_MC_BASE(_x) (0x0728 + (_x) * 4) /*GOOD*/ -+#define RTL8367B_VLAN_MC_NUM_WORDS 4 /*GOOD*/ -+#define RTL8367B_VLAN_MC0_MEMBER_SHIFT 0/*GOOD*/ -+#define RTL8367B_VLAN_MC0_MEMBER_MASK RTL8367B_MEMBER_MASK/*GOOD*/ -+#define RTL8367B_VLAN_MC1_FID_SHIFT 0/*GOOD*/ -+#define RTL8367B_VLAN_MC1_FID_MASK RTL8367B_FID_MASK/*GOOD*/ -+#define RTL8367B_VLAN_MC3_EVID_SHIFT 0/*GOOD*/ -+#define RTL8367B_VLAN_MC3_EVID_MASK RTL8367B_VID_MASK/*GOOD*/ -+ -+#define RTL8367B_VLAN_CTRL_REG 0x07a8 /*GOOD*/ -+#define RTL8367B_VLAN_CTRL_ENABLE BIT(0) -+ -+#define RTL8367B_VLAN_INGRESS_REG 0x07a9 /*GOOD*/ -+ -+#define RTL8367B_PORT_ISOLATION_REG(_p) (0x08a2 + (_p)) /*GOOD*/ -+ -+#define RTL8367B_MIB_COUNTER_REG(_x) (0x1000 + (_x)) /*GOOD*/ -+#define RTL8367B_MIB_COUNTER_PORT_OFFSET 0x007c /*GOOD*/ -+ -+#define RTL8367B_MIB_ADDRESS_REG 0x1004 /*GOOD*/ -+ -+#define RTL8367B_MIB_CTRL0_REG(_x) (0x1005 + (_x)) /*GOOD*/ -+#define RTL8367B_MIB_CTRL0_GLOBAL_RESET_MASK BIT(11) /*GOOD*/ -+#define RTL8367B_MIB_CTRL0_QM_RESET_MASK BIT(10) /*GOOD*/ -+#define RTL8367B_MIB_CTRL0_PORT_RESET_MASK(_p) BIT(2 + (_p)) /*GOOD*/ -+#define RTL8367B_MIB_CTRL0_RESET_MASK BIT(1) /*GOOD*/ -+#define RTL8367B_MIB_CTRL0_BUSY_MASK BIT(0) /*GOOD*/ -+ -+#define RTL8367B_SWC0_REG 0x1200/*GOOD*/ -+#define RTL8367B_SWC0_MAX_LENGTH_SHIFT 13/*GOOD*/ -+#define RTL8367B_SWC0_MAX_LENGTH(_x) ((_x) << 13) /*GOOD*/ -+#define RTL8367B_SWC0_MAX_LENGTH_MASK RTL8367B_SWC0_MAX_LENGTH(0x3) -+#define RTL8367B_SWC0_MAX_LENGTH_1522 RTL8367B_SWC0_MAX_LENGTH(0) -+#define RTL8367B_SWC0_MAX_LENGTH_1536 RTL8367B_SWC0_MAX_LENGTH(1) -+#define RTL8367B_SWC0_MAX_LENGTH_1552 RTL8367B_SWC0_MAX_LENGTH(2) -+#define RTL8367B_SWC0_MAX_LENGTH_16000 RTL8367B_SWC0_MAX_LENGTH(3) -+ -+#define RTL8367B_CHIP_NUMBER_REG 0x1300/*GOOD*/ -+ -+#define RTL8367B_CHIP_VER_REG 0x1301/*GOOD*/ -+#define RTL8367B_CHIP_VER_RLVID_SHIFT 12/*GOOD*/ -+#define RTL8367B_CHIP_VER_RLVID_MASK 0xf/*GOOD*/ -+#define RTL8367B_CHIP_VER_MCID_SHIFT 8/*GOOD*/ -+#define RTL8367B_CHIP_VER_MCID_MASK 0xf/*GOOD*/ -+#define RTL8367B_CHIP_VER_BOID_SHIFT 4/*GOOD*/ -+#define RTL8367B_CHIP_VER_BOID_MASK 0xf/*GOOD*/ -+#define RTL8367B_CHIP_VER_AFE_SHIFT 0/*GOOD*/ -+#define RTL8367B_CHIP_VER_AFE_MASK 0x1/*GOOD*/ -+ -+#define RTL8367B_CHIP_MODE_REG 0x1302 -+#define RTL8367B_CHIP_MODE_MASK 0x7 -+ -+#define RTL8367B_CHIP_DEBUG0_REG 0x1303 -+#define RTL8367B_DEBUG0_SEL33(_x) BIT(8 + (_x)) -+#define RTL8367B_DEBUG0_DRI_OTHER BIT(7) -+#define RTL8367B_DEBUG0_DRI_RG(_x) BIT(5 + (_x)) -+#define RTL8367B_DEBUG0_DRI(_x) BIT(3 + (_x)) -+#define RTL8367B_DEBUG0_SLR_OTHER BIT(2) -+#define RTL8367B_DEBUG0_SLR(_x) BIT(_x) -+ -+#define RTL8367B_CHIP_DEBUG1_REG 0x1304 -+#define RTL8367B_DEBUG1_DN_MASK(_x) \ -+ GENMASK(6 + (_x)*8, 4 + (_x)*8) -+#define RTL8367B_DEBUG1_DN_SHIFT(_x) (4 + (_x) * 8) -+#define RTL8367B_DEBUG1_DP_MASK(_x) \ -+ GENMASK(2 + (_x) * 8, (_x) * 8) -+#define RTL8367B_DEBUG1_DP_SHIFT(_x) ((_x) * 8) -+ -+#define RTL8367B_CHIP_DEBUG2_REG 0x13e2 -+#define RTL8367B_DEBUG2_RG2_DN_MASK GENMASK(8, 6) -+#define RTL8367B_DEBUG2_RG2_DN_SHIFT 6 -+#define RTL8367B_DEBUG2_RG2_DP_MASK GENMASK(5, 3) -+#define RTL8367B_DEBUG2_RG2_DP_SHIFT 3 -+#define RTL8367B_DEBUG2_DRI_EXT2_RG BIT(2) -+#define RTL8367B_DEBUG2_DRI_EXT2 BIT(1) -+#define RTL8367B_DEBUG2_SLR_EXT2 BIT(0) -+ -+#define RTL8367B_DIS_REG 0x1305 -+#define RTL8367B_DIS_SKIP_MII_RXER(_x) BIT(12 + (_x)) -+#define RTL8367B_DIS_RGMII_SHIFT(_x) (4 * (_x)) -+#define RTL8367B_DIS_RGMII_MASK 0x7 -+ -+#define RTL8367B_DIS2_REG 0x13c3 -+#define RTL8367B_DIS2_SKIP_MII_RXER_SHIFT 4 -+#define RTL8367B_DIS2_SKIP_MII_RXER 0x10 -+#define RTL8367B_DIS2_RGMII_SHIFT 0 -+#define RTL8367B_DIS2_RGMII_MASK 0xf -+ -+#define RTL8367B_EXT_RGMXF_REG(_x) \ -+ ((_x) == 2 ? 0x13c5 : 0x1306 + (_x)) -+#define RTL8367B_EXT_RGMXF_DUMMY0_SHIFT 5 -+#define RTL8367B_EXT_RGMXF_DUMMY0_MASK 0x7ff -+#define RTL8367B_EXT_RGMXF_TXDELAY_SHIFT 3 -+#define RTL8367B_EXT_RGMXF_TXDELAY_MASK 1 -+#define RTL8367B_EXT_RGMXF_RXDELAY_MASK 0x7 -+ -+#define RTL8367B_DI_FORCE_REG(_x) \ -+ ((_x) == 2 ? 0x13c4 : 0x1310 + (_x)) -+#define RTL8367B_DI_FORCE_MODE BIT(12) -+#define RTL8367B_DI_FORCE_NWAY BIT(7) -+#define RTL8367B_DI_FORCE_TXPAUSE BIT(6) -+#define RTL8367B_DI_FORCE_RXPAUSE BIT(5) -+#define RTL8367B_DI_FORCE_LINK BIT(4) -+#define RTL8367B_DI_FORCE_DUPLEX BIT(2) -+#define RTL8367B_DI_FORCE_SPEED_MASK 3 -+#define RTL8367B_DI_FORCE_SPEED_10 0 -+#define RTL8367B_DI_FORCE_SPEED_100 1 -+#define RTL8367B_DI_FORCE_SPEED_1000 2 -+ -+#define RTL8367B_MAC_FORCE_REG(_x) (0x1312 + (_x)) -+ -+#define RTL8367B_CHIP_RESET_REG 0x1322 /*GOOD*/ -+#define RTL8367B_CHIP_RESET_SW BIT(1) /*GOOD*/ -+#define RTL8367B_CHIP_RESET_HW BIT(0) /*GOOD*/ -+ -+#define RTL8367B_PORT_STATUS_REG(_p) (0x1352 + (_p)) /*GOOD*/ -+#define RTL8367B_PORT_STATUS_EN_1000_SPI BIT(11) /*GOOD*/ -+#define RTL8367B_PORT_STATUS_EN_100_SPI BIT(10)/*GOOD*/ -+#define RTL8367B_PORT_STATUS_NWAY_FAULT BIT(9)/*GOOD*/ -+#define RTL8367B_PORT_STATUS_LINK_MASTER BIT(8)/*GOOD*/ -+#define RTL8367B_PORT_STATUS_NWAY BIT(7)/*GOOD*/ -+#define RTL8367B_PORT_STATUS_TXPAUSE BIT(6)/*GOOD*/ -+#define RTL8367B_PORT_STATUS_RXPAUSE BIT(5)/*GOOD*/ -+#define RTL8367B_PORT_STATUS_LINK BIT(4)/*GOOD*/ -+#define RTL8367B_PORT_STATUS_DUPLEX BIT(2)/*GOOD*/ -+#define RTL8367B_PORT_STATUS_SPEED_MASK 0x0003/*GOOD*/ -+#define RTL8367B_PORT_STATUS_SPEED_10 0/*GOOD*/ -+#define RTL8367B_PORT_STATUS_SPEED_100 1/*GOOD*/ -+#define RTL8367B_PORT_STATUS_SPEED_1000 2/*GOOD*/ -+ -+#define RTL8367B_RTL_MAGIC_ID_REG 0x13c2 -+#define RTL8367B_RTL_MAGIC_ID_VAL 0x0249 -+ -+#define RTL8367B_IA_CTRL_REG 0x1f00 -+#define RTL8367B_IA_CTRL_RW(_x) ((_x) << 1) -+#define RTL8367B_IA_CTRL_RW_READ RTL8367B_IA_CTRL_RW(0) -+#define RTL8367B_IA_CTRL_RW_WRITE RTL8367B_IA_CTRL_RW(1) -+#define RTL8367B_IA_CTRL_CMD_MASK BIT(0) -+ -+#define RTL8367B_IA_STATUS_REG 0x1f01 -+#define RTL8367B_IA_STATUS_PHY_BUSY BIT(2) -+#define RTL8367B_IA_STATUS_SDS_BUSY BIT(1) -+#define RTL8367B_IA_STATUS_MDX_BUSY BIT(0) -+ -+#define RTL8367B_IA_ADDRESS_REG 0x1f02 -+#define RTL8367B_IA_WRITE_DATA_REG 0x1f03 -+#define RTL8367B_IA_READ_DATA_REG 0x1f04 -+ -+#define RTL8367B_INTERNAL_PHY_REG(_a, _r) (0x2000 + 32 * (_a) + (_r)) -+ -+#define RTL8367B_NUM_MIB_COUNTERS 58 -+ -+#define RTL8367B_CPU_PORT_NUM 5 -+#define RTL8367B_NUM_PORTS 8 -+#define RTL8367B_NUM_VLANS 32 -+#define RTL8367B_NUM_VIDS 4096 -+#define RTL8367B_PRIORITYMAX 7 -+#define RTL8367B_FIDMAX 7 -+ -+#define RTL8367B_PORT_0 BIT(0) -+#define RTL8367B_PORT_1 BIT(1) -+#define RTL8367B_PORT_2 BIT(2) -+#define RTL8367B_PORT_3 BIT(3) -+#define RTL8367B_PORT_4 BIT(4) -+#define RTL8367B_PORT_E0 BIT(5) /* External port 0 */ -+#define RTL8367B_PORT_E1 BIT(6) /* External port 1 */ -+#define RTL8367B_PORT_E2 BIT(7) /* External port 2 */ -+ -+#define RTL8367B_PORTS_ALL \ -+ (RTL8367B_PORT_0 | RTL8367B_PORT_1 | RTL8367B_PORT_2 | \ -+ RTL8367B_PORT_3 | RTL8367B_PORT_4 | RTL8367B_PORT_E0 | \ -+ RTL8367B_PORT_E1 | RTL8367B_PORT_E2) -+ -+#define RTL8367B_PORTS_ALL_BUT_CPU \ -+ (RTL8367B_PORT_0 | RTL8367B_PORT_1 | RTL8367B_PORT_2 | \ -+ RTL8367B_PORT_3 | RTL8367B_PORT_4 | RTL8367B_PORT_E1 | \ -+ RTL8367B_PORT_E2) -+ -+struct rtl8367b_initval { -+ u16 reg; -+ u16 val; -+}; -+ -+#define RTL8367B_MIB_RXB_ID 0 /* IfInOctets */ -+#define RTL8367B_MIB_TXB_ID 28 /* IfOutOctets */ -+ -+#define RTL8367D_PORT_STATUS_REG(_p) (0x12d0 + (_p)) -+ -+#define RTL8367D_PORT_STATUS_SPEED1_MASK 0x3000 -+#define RTL8367D_PORT_STATUS_SPEED1_SHIFT 10 /*12-2*/ -+ -+#define RTL8367D_REG_MAC0_FORCE_SELECT 0x12c0 -+#define RTL8367D_REG_MAC0_FORCE_SELECT_EN 0x12c8 -+ -+#define RTL8367D_VLAN_PVID_CTRL_REG(_p) (0x0700 + (_p)) -+#define RTL8367D_VLAN_PVID_CTRL_MASK 0xfff -+#define RTL8367D_VLAN_PVID_CTRL_SHIFT(_p) 0 -+ -+#define RTL8367D_FIDMAX 3 -+#define RTL8367D_FID_MASK 3 -+#define RTL8367D_TA_VLAN1_FID_SHIFT 0 -+#define RTL8367D_TA_VLAN1_FID_MASK RTL8367D_FID_MASK -+ -+#define RTL8367D_VID_MASK 0xfff -+#define RTL8367D_TA_VLAN_VID_MASK RTL8367D_VID_MASK -+ -+#define RTL8367D_REG_EXT_TXC_DLY 0x13f9 -+#define RTL8367D_EXT1_RGMII_TX_DLY_MASK 0x38 -+ -+#define RTL8367D_REG_TOP_CON0 0x1d70 -+#define RTL8367D_MAC7_SEL_EXT1_MASK 0x2000 -+#define RTL8367D_MAC4_SEL_EXT1_MASK 0x1000 -+ -+#define RTL8367D_REG_SDS1_MISC0 0x1d78 -+#define RTL8367D_SDS1_MODE_MASK 0x1f -+#define RTL8367D_PORT_SDS_MODE_DISABLE 0x1f -+ -+static struct rtl8366_mib_counter -+rtl8367b_mib_counters[RTL8367B_NUM_MIB_COUNTERS] = { -+ {0, 0, 4, "ifInOctets" }, -+ {0, 4, 2, "dot3StatsFCSErrors" }, -+ {0, 6, 2, "dot3StatsSymbolErrors" }, -+ {0, 8, 2, "dot3InPauseFrames" }, -+ {0, 10, 2, "dot3ControlInUnknownOpcodes" }, -+ {0, 12, 2, "etherStatsFragments" }, -+ {0, 14, 2, "etherStatsJabbers" }, -+ {0, 16, 2, "ifInUcastPkts" }, -+ {0, 18, 2, "etherStatsDropEvents" }, -+ {0, 20, 2, "ifInMulticastPkts" }, -+ {0, 22, 2, "ifInBroadcastPkts" }, -+ {0, 24, 2, "inMldChecksumError" }, -+ {0, 26, 2, "inIgmpChecksumError" }, -+ {0, 28, 2, "inMldSpecificQuery" }, -+ {0, 30, 2, "inMldGeneralQuery" }, -+ {0, 32, 2, "inIgmpSpecificQuery" }, -+ {0, 34, 2, "inIgmpGeneralQuery" }, -+ {0, 36, 2, "inMldLeaves" }, -+ {0, 38, 2, "inIgmpLeaves" }, -+ -+ {0, 40, 4, "etherStatsOctets" }, -+ {0, 44, 2, "etherStatsUnderSizePkts" }, -+ {0, 46, 2, "etherOversizeStats" }, -+ {0, 48, 2, "etherStatsPkts64Octets" }, -+ {0, 50, 2, "etherStatsPkts65to127Octets" }, -+ {0, 52, 2, "etherStatsPkts128to255Octets" }, -+ {0, 54, 2, "etherStatsPkts256to511Octets" }, -+ {0, 56, 2, "etherStatsPkts512to1023Octets" }, -+ {0, 58, 2, "etherStatsPkts1024to1518Octets" }, -+ -+ {0, 60, 4, "ifOutOctets" }, -+ {0, 64, 2, "dot3StatsSingleCollisionFrames" }, -+ {0, 66, 2, "dot3StatMultipleCollisionFrames" }, -+ {0, 68, 2, "dot3sDeferredTransmissions" }, -+ {0, 70, 2, "dot3StatsLateCollisions" }, -+ {0, 72, 2, "etherStatsCollisions" }, -+ {0, 74, 2, "dot3StatsExcessiveCollisions" }, -+ {0, 76, 2, "dot3OutPauseFrames" }, -+ {0, 78, 2, "ifOutDiscards" }, -+ {0, 80, 2, "dot1dTpPortInDiscards" }, -+ {0, 82, 2, "ifOutUcastPkts" }, -+ {0, 84, 2, "ifOutMulticastPkts" }, -+ {0, 86, 2, "ifOutBroadcastPkts" }, -+ {0, 88, 2, "outOampduPkts" }, -+ {0, 90, 2, "inOampduPkts" }, -+ {0, 92, 2, "inIgmpJoinsSuccess" }, -+ {0, 94, 2, "inIgmpJoinsFail" }, -+ {0, 96, 2, "inMldJoinsSuccess" }, -+ {0, 98, 2, "inMldJoinsFail" }, -+ {0, 100, 2, "inReportSuppressionDrop" }, -+ {0, 102, 2, "inLeaveSuppressionDrop" }, -+ {0, 104, 2, "outIgmpReports" }, -+ {0, 106, 2, "outIgmpLeaves" }, -+ {0, 108, 2, "outIgmpGeneralQuery" }, -+ {0, 110, 2, "outIgmpSpecificQuery" }, -+ {0, 112, 2, "outMldReports" }, -+ {0, 114, 2, "outMldLeaves" }, -+ {0, 116, 2, "outMldGeneralQuery" }, -+ {0, 118, 2, "outMldSpecificQuery" }, -+ {0, 120, 2, "inKnownMulticastPkts" }, -+}; -+ -+#define REG_RD(_smi, _reg, _val) \ -+ do { \ -+ err = rtl8366_smi_read_reg(_smi, _reg, _val); \ -+ if (err) \ -+ return err; \ -+ } while (0) -+ -+#define REG_WR(_smi, _reg, _val) \ -+ do { \ -+ err = rtl8366_smi_write_reg(_smi, _reg, _val); \ -+ if (err) \ -+ return err; \ -+ } while (0) -+ -+#define REG_RMW(_smi, _reg, _mask, _val) \ -+ do { \ -+ err = rtl8366_smi_rmwr(_smi, _reg, _mask, _val); \ -+ if (err) \ -+ return err; \ -+ } while (0) -+ -+static const struct rtl8367b_initval rtl8367b_initvals[] = { -+ {0x1B03, 0x0876}, {0x1200, 0x7FC4}, {0x1305, 0xC000}, {0x121E, 0x03CA}, -+ {0x1233, 0x0352}, {0x1234, 0x0064}, {0x1237, 0x0096}, {0x1238, 0x0078}, -+ {0x1239, 0x0084}, {0x123A, 0x0030}, {0x205F, 0x0002}, {0x2059, 0x1A00}, -+ {0x205F, 0x0000}, {0x207F, 0x0002}, {0x2077, 0x0000}, {0x2078, 0x0000}, -+ {0x2079, 0x0000}, {0x207A, 0x0000}, {0x207B, 0x0000}, {0x207F, 0x0000}, -+ {0x205F, 0x0002}, {0x2053, 0x0000}, {0x2054, 0x0000}, {0x2055, 0x0000}, -+ {0x2056, 0x0000}, {0x2057, 0x0000}, {0x205F, 0x0000}, {0x133F, 0x0030}, -+ {0x133E, 0x000E}, {0x221F, 0x0005}, {0x2205, 0x8B86}, {0x2206, 0x800E}, -+ {0x221F, 0x0000}, {0x133F, 0x0010}, {0x12A3, 0x2200}, {0x6107, 0xE58B}, -+ {0x6103, 0xA970}, {0x0018, 0x0F00}, {0x0038, 0x0F00}, {0x0058, 0x0F00}, -+ {0x0078, 0x0F00}, {0x0098, 0x0F00}, {0x133F, 0x0030}, {0x133E, 0x000E}, -+ {0x221F, 0x0005}, {0x2205, 0x8B6E}, {0x2206, 0x0000}, {0x220F, 0x0100}, -+ {0x2205, 0xFFF6}, {0x2206, 0x0080}, {0x2205, 0x8000}, {0x2206, 0x0280}, -+ {0x2206, 0x2BF7}, {0x2206, 0x00E0}, {0x2206, 0xFFF7}, {0x2206, 0xA080}, -+ {0x2206, 0x02AE}, {0x2206, 0xF602}, {0x2206, 0x0153}, {0x2206, 0x0201}, -+ {0x2206, 0x6602}, {0x2206, 0x8044}, {0x2206, 0x0201}, {0x2206, 0x7CE0}, -+ {0x2206, 0x8B8C}, {0x2206, 0xE18B}, {0x2206, 0x8D1E}, {0x2206, 0x01E1}, -+ {0x2206, 0x8B8E}, {0x2206, 0x1E01}, {0x2206, 0xA000}, {0x2206, 0xE4AE}, -+ {0x2206, 0xD8EE}, {0x2206, 0x85C0}, {0x2206, 0x00EE}, {0x2206, 0x85C1}, -+ {0x2206, 0x00EE}, {0x2206, 0x8AFC}, {0x2206, 0x07EE}, {0x2206, 0x8AFD}, -+ {0x2206, 0x73EE}, {0x2206, 0xFFF6}, {0x2206, 0x00EE}, {0x2206, 0xFFF7}, -+ {0x2206, 0xFC04}, {0x2206, 0xF8E0}, {0x2206, 0x8B8E}, {0x2206, 0xAD20}, -+ {0x2206, 0x0302}, {0x2206, 0x8050}, {0x2206, 0xFC04}, {0x2206, 0xF8F9}, -+ {0x2206, 0xE08B}, {0x2206, 0x85AD}, {0x2206, 0x2548}, {0x2206, 0xE08A}, -+ {0x2206, 0xE4E1}, {0x2206, 0x8AE5}, {0x2206, 0x7C00}, {0x2206, 0x009E}, -+ {0x2206, 0x35EE}, {0x2206, 0x8AE4}, {0x2206, 0x00EE}, {0x2206, 0x8AE5}, -+ {0x2206, 0x00E0}, {0x2206, 0x8AFC}, {0x2206, 0xE18A}, {0x2206, 0xFDE2}, -+ {0x2206, 0x85C0}, {0x2206, 0xE385}, {0x2206, 0xC102}, {0x2206, 0x2DAC}, -+ {0x2206, 0xAD20}, {0x2206, 0x12EE}, {0x2206, 0x8AE4}, {0x2206, 0x03EE}, -+ {0x2206, 0x8AE5}, {0x2206, 0xB7EE}, {0x2206, 0x85C0}, {0x2206, 0x00EE}, -+ {0x2206, 0x85C1}, {0x2206, 0x00AE}, {0x2206, 0x1115}, {0x2206, 0xE685}, -+ {0x2206, 0xC0E7}, {0x2206, 0x85C1}, {0x2206, 0xAE08}, {0x2206, 0xEE85}, -+ {0x2206, 0xC000}, {0x2206, 0xEE85}, {0x2206, 0xC100}, {0x2206, 0xFDFC}, -+ {0x2206, 0x0400}, {0x2205, 0xE142}, {0x2206, 0x0701}, {0x2205, 0xE140}, -+ {0x2206, 0x0405}, {0x220F, 0x0000}, {0x221F, 0x0000}, {0x133E, 0x000E}, -+ {0x133F, 0x0010}, {0x13EB, 0x11BB}, {0x207F, 0x0002}, {0x2073, 0x1D22}, -+ {0x207F, 0x0000}, {0x133F, 0x0030}, {0x133E, 0x000E}, {0x2200, 0x1340}, -+ {0x133E, 0x000E}, {0x133F, 0x0010}, -+}; -+ -+static const struct rtl8367b_initval rtl8367c_initvals[] = { -+ {0x13c2, 0x0000}, {0x0018, 0x0f00}, {0x0038, 0x0f00}, {0x0058, 0x0f00}, -+ {0x0078, 0x0f00}, {0x0098, 0x0f00}, {0x1d15, 0x0a69}, {0x2000, 0x1340}, -+ {0x2020, 0x1340}, {0x2040, 0x1340}, {0x2060, 0x1340}, {0x2080, 0x1340}, -+ {0x13eb, 0x15bb}, {0x1303, 0x06d6}, {0x1304, 0x0700}, {0x13E2, 0x003F}, -+ {0x13F9, 0x0090}, {0x121e, 0x03CA}, {0x1233, 0x0352}, {0x1237, 0x00a0}, -+ {0x123a, 0x0030}, {0x1239, 0x0084}, {0x0301, 0x1000}, {0x1349, 0x001F}, -+ {0x18e0, 0x4004}, {0x122b, 0x641c}, {0x1305, 0xc000}, {0x1200, 0x7fcb}, -+ {0x0884, 0x0003}, {0x06eb, 0x0001}, {0x00cf, 0xffff}, {0x00d0, 0x0007}, -+ {0x00ce, 0x48b0}, {0x00ce, 0x48b0}, {0x0398, 0xffff}, {0x0399, 0x0007}, -+ {0x0300, 0x0001}, {0x03fa, 0x0007}, {0x08c8, 0x00c0}, {0x0a30, 0x020e}, -+ {0x0800, 0x0000}, {0x0802, 0x0000}, {0x09da, 0x0017}, {0x1d32, 0x0002}, -+}; -+ -+static int rtl8367b_write_initvals(struct rtl8366_smi *smi, -+ const struct rtl8367b_initval *initvals, -+ int count) -+{ -+ int err; -+ int i; -+ -+ for (i = 0; i < count; i++) -+ REG_WR(smi, initvals[i].reg, initvals[i].val); -+ -+ return 0; -+} -+ -+static int rtl8367b_read_phy_reg(struct rtl8366_smi *smi, -+ u32 phy_addr, u32 phy_reg, u32 *val) -+{ -+ int timeout; -+ u32 data; -+ int err; -+ -+ if (phy_addr > RTL8367B_PHY_ADDR_MAX) -+ return -EINVAL; -+ -+ if (phy_reg > RTL8367B_PHY_REG_MAX) -+ return -EINVAL; -+ -+ REG_RD(smi, RTL8367B_IA_STATUS_REG, &data); -+ if (data & RTL8367B_IA_STATUS_PHY_BUSY) -+ return -ETIMEDOUT; -+ -+ /* prepare address */ -+ REG_WR(smi, RTL8367B_IA_ADDRESS_REG, -+ RTL8367B_INTERNAL_PHY_REG(phy_addr, phy_reg)); -+ -+ /* send read command */ -+ REG_WR(smi, RTL8367B_IA_CTRL_REG, -+ RTL8367B_IA_CTRL_CMD_MASK | RTL8367B_IA_CTRL_RW_READ); -+ -+ timeout = 5; -+ do { -+ REG_RD(smi, RTL8367B_IA_STATUS_REG, &data); -+ if ((data & RTL8367B_IA_STATUS_PHY_BUSY) == 0) -+ break; -+ -+ if (timeout--) { -+ dev_err(smi->parent, "phy read timed out\n"); -+ return -ETIMEDOUT; -+ } -+ -+ udelay(1); -+ } while (1); -+ -+ /* read data */ -+ REG_RD(smi, RTL8367B_IA_READ_DATA_REG, val); -+ -+ dev_dbg(smi->parent, "phy_read: addr:%02x, reg:%02x, val:%04x\n", -+ phy_addr, phy_reg, *val); -+ return 0; -+} -+ -+static int rtl8367b_write_phy_reg(struct rtl8366_smi *smi, -+ u32 phy_addr, u32 phy_reg, u32 val) -+{ -+ int timeout; -+ u32 data; -+ int err; -+ -+ dev_dbg(smi->parent, "phy_write: addr:%02x, reg:%02x, val:%04x\n", -+ phy_addr, phy_reg, val); -+ -+ if (phy_addr > RTL8367B_PHY_ADDR_MAX) -+ return -EINVAL; -+ -+ if (phy_reg > RTL8367B_PHY_REG_MAX) -+ return -EINVAL; -+ -+ REG_RD(smi, RTL8367B_IA_STATUS_REG, &data); -+ if (data & RTL8367B_IA_STATUS_PHY_BUSY) -+ return -ETIMEDOUT; -+ -+ /* preapre data */ -+ REG_WR(smi, RTL8367B_IA_WRITE_DATA_REG, val); -+ -+ /* prepare address */ -+ REG_WR(smi, RTL8367B_IA_ADDRESS_REG, -+ RTL8367B_INTERNAL_PHY_REG(phy_addr, phy_reg)); -+ -+ /* send write command */ -+ REG_WR(smi, RTL8367B_IA_CTRL_REG, -+ RTL8367B_IA_CTRL_CMD_MASK | RTL8367B_IA_CTRL_RW_WRITE); -+ -+ timeout = 5; -+ do { -+ REG_RD(smi, RTL8367B_IA_STATUS_REG, &data); -+ if ((data & RTL8367B_IA_STATUS_PHY_BUSY) == 0) -+ break; -+ -+ if (timeout--) { -+ dev_err(smi->parent, "phy write timed out\n"); -+ return -ETIMEDOUT; -+ } -+ -+ udelay(1); -+ } while (1); -+ -+ return 0; -+} -+ -+static int rtl8367b_init_regs(struct rtl8366_smi *smi) -+{ -+ const struct rtl8367b_initval *initvals; -+ int count; -+ -+ switch (smi->rtl8367b_chip) { -+ case RTL8367B_CHIP_RTL8367RB: -+ case RTL8367B_CHIP_RTL8367R_VB: -+ initvals = rtl8367b_initvals; -+ count = ARRAY_SIZE(rtl8367b_initvals); -+ break; -+ case RTL8367B_CHIP_RTL8367RB_VB: -+ case RTL8367B_CHIP_RTL8367S: -+ case RTL8367B_CHIP_RTL8367S_VB: -+ initvals = rtl8367c_initvals; -+ count = ARRAY_SIZE(rtl8367c_initvals); -+ if ((smi->rtl8367b_chip == RTL8367B_CHIP_RTL8367S_VB) && (smi->emu_vlanmc == NULL)) { -+ smi->emu_vlanmc = kzalloc(sizeof(struct rtl8366_vlan_mc) * smi->num_vlan_mc, GFP_KERNEL); -+ dev_info(smi->parent, "alloc vlan mc emulator"); -+ } -+ break; -+ default: -+ return -ENODEV; -+ } -+ -+ return rtl8367b_write_initvals(smi, initvals, count); -+} -+ -+static int rtl8367b_reset_chip(struct rtl8366_smi *smi) -+{ -+ int timeout = 10; -+ int err; -+ u32 data; -+ -+ REG_WR(smi, RTL8367B_CHIP_RESET_REG, RTL8367B_CHIP_RESET_HW); -+ msleep(RTL8367B_RESET_DELAY); -+ -+ do { -+ REG_RD(smi, RTL8367B_CHIP_RESET_REG, &data); -+ if (!(data & RTL8367B_CHIP_RESET_HW)) -+ break; -+ -+ msleep(1); -+ } while (--timeout); -+ -+ if (!timeout) { -+ dev_err(smi->parent, "chip reset timed out\n"); -+ return -ETIMEDOUT; -+ } -+ -+ return 0; -+} -+ -+static int rtl8367b_extif_set_mode(struct rtl8366_smi *smi, int id, -+ enum rtl8367_extif_mode mode) -+{ -+ int err; -+ u32 data; -+ -+ /* set port mode */ -+ switch (mode) { -+ case RTL8367_EXTIF_MODE_RGMII: -+ REG_RMW(smi, RTL8367B_CHIP_DEBUG0_REG, -+ RTL8367B_DEBUG0_SEL33(id), -+ RTL8367B_DEBUG0_SEL33(id)); -+ if (id <= 1) { -+ REG_RMW(smi, RTL8367B_CHIP_DEBUG0_REG, -+ RTL8367B_DEBUG0_DRI(id) | -+ RTL8367B_DEBUG0_DRI_RG(id) | -+ RTL8367B_DEBUG0_SLR(id), -+ RTL8367B_DEBUG0_DRI_RG(id) | -+ RTL8367B_DEBUG0_SLR(id)); -+ REG_RMW(smi, RTL8367B_CHIP_DEBUG1_REG, -+ RTL8367B_DEBUG1_DN_MASK(id) | -+ RTL8367B_DEBUG1_DP_MASK(id), -+ (7 << RTL8367B_DEBUG1_DN_SHIFT(id)) | -+ (7 << RTL8367B_DEBUG1_DP_SHIFT(id))); -+ if ((smi->rtl8367b_chip == RTL8367B_CHIP_RTL8367S_VB) && (id == 1)) { -+ REG_RMW(smi, RTL8367D_REG_EXT_TXC_DLY, RTL8367D_EXT1_RGMII_TX_DLY_MASK, 0); -+ /* Configure RGMII/MII mux to port 7 if UTP_PORT4 is not RGMII mode */ -+ REG_RD(smi, RTL8367D_REG_TOP_CON0, &data); -+ data &= RTL8367D_MAC4_SEL_EXT1_MASK; -+ if (data == 0) -+ REG_RMW(smi, RTL8367D_REG_TOP_CON0, RTL8367D_MAC7_SEL_EXT1_MASK, RTL8367D_MAC7_SEL_EXT1_MASK); -+ REG_RMW(smi, RTL8367D_REG_SDS1_MISC0, RTL8367D_SDS1_MODE_MASK, RTL8367D_PORT_SDS_MODE_DISABLE); -+ } -+ } else { -+ REG_RMW(smi, RTL8367B_CHIP_DEBUG2_REG, -+ RTL8367B_DEBUG2_DRI_EXT2 | -+ RTL8367B_DEBUG2_DRI_EXT2_RG | -+ RTL8367B_DEBUG2_SLR_EXT2 | -+ RTL8367B_DEBUG2_RG2_DN_MASK | -+ RTL8367B_DEBUG2_RG2_DP_MASK, -+ RTL8367B_DEBUG2_DRI_EXT2_RG | -+ RTL8367B_DEBUG2_SLR_EXT2 | -+ (7 << RTL8367B_DEBUG2_RG2_DN_SHIFT) | -+ (7 << RTL8367B_DEBUG2_RG2_DP_SHIFT)); -+ } -+ break; -+ -+ case RTL8367_EXTIF_MODE_TMII_MAC: -+ case RTL8367_EXTIF_MODE_TMII_PHY: -+ REG_RMW(smi, RTL8367B_BYPASS_LINE_RATE_REG, BIT(id), BIT(id)); -+ break; -+ -+ case RTL8367_EXTIF_MODE_GMII: -+ REG_RMW(smi, RTL8367B_CHIP_DEBUG0_REG, -+ RTL8367B_DEBUG0_SEL33(id), -+ RTL8367B_DEBUG0_SEL33(id)); -+ REG_RMW(smi, RTL8367B_EXT_RGMXF_REG(id), BIT(6), BIT(6)); -+ break; -+ -+ case RTL8367_EXTIF_MODE_MII_MAC: -+ case RTL8367_EXTIF_MODE_MII_PHY: -+ case RTL8367_EXTIF_MODE_DISABLED: -+ REG_RMW(smi, RTL8367B_BYPASS_LINE_RATE_REG, BIT(id), 0); -+ REG_RMW(smi, RTL8367B_EXT_RGMXF_REG(id), BIT(6), 0); -+ break; -+ -+ default: -+ dev_err(smi->parent, -+ "invalid mode for external interface %d\n", id); -+ return -EINVAL; -+ } -+ -+ if (id <= 1) -+ REG_RMW(smi, RTL8367B_DIS_REG, -+ RTL8367B_DIS_RGMII_MASK << RTL8367B_DIS_RGMII_SHIFT(id), -+ mode << RTL8367B_DIS_RGMII_SHIFT(id)); -+ else -+ REG_RMW(smi, RTL8367B_DIS2_REG, -+ RTL8367B_DIS2_RGMII_MASK << RTL8367B_DIS2_RGMII_SHIFT, -+ mode << RTL8367B_DIS2_RGMII_SHIFT); -+ -+ return 0; -+} -+ -+static int rtl8367b_extif_set_force(struct rtl8366_smi *smi, int id, -+ struct rtl8367_port_ability *pa) -+{ -+ u32 mask; -+ u32 val; -+ int err; -+ -+ val = pa->speed & RTL8367B_DI_FORCE_SPEED_MASK; -+ val |= pa->nway ? RTL8367B_DI_FORCE_NWAY : 0; -+ val |= pa->txpause ? RTL8367B_DI_FORCE_TXPAUSE : 0; -+ val |= pa->rxpause ? RTL8367B_DI_FORCE_RXPAUSE : 0; -+ val |= pa->link ? RTL8367B_DI_FORCE_LINK : 0; -+ val |= pa->duplex ? RTL8367B_DI_FORCE_DUPLEX : 0; -+ -+ if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) { /* Family D */ -+ val |= (pa->speed << RTL8367D_PORT_STATUS_SPEED1_SHIFT) & RTL8367D_PORT_STATUS_SPEED1_MASK; -+ if (smi->cpu_port != UINT_MAX) { -+ REG_WR(smi, RTL8367D_REG_MAC0_FORCE_SELECT + smi->cpu_port, val); -+ REG_WR(smi, RTL8367D_REG_MAC0_FORCE_SELECT_EN + smi->cpu_port, pa->force_mode ? 0xffff : 0x0000); -+ } -+ } else { -+ val |= pa->force_mode ? RTL8367B_DI_FORCE_MODE : 0; -+ mask = (RTL8367B_DI_FORCE_MODE | -+ RTL8367B_DI_FORCE_NWAY | -+ RTL8367B_DI_FORCE_TXPAUSE | -+ RTL8367B_DI_FORCE_RXPAUSE | -+ RTL8367B_DI_FORCE_LINK | -+ RTL8367B_DI_FORCE_DUPLEX | -+ RTL8367B_DI_FORCE_SPEED_MASK); -+ -+ REG_RMW(smi, RTL8367B_DI_FORCE_REG(id), mask, val); -+ } -+ -+ return 0; -+} -+ -+static int rtl8367b_extif_set_rgmii_delay(struct rtl8366_smi *smi, int id, -+ unsigned txdelay, unsigned rxdelay) -+{ -+ u32 mask; -+ u32 val; -+ int err; -+ -+ mask = (RTL8367B_EXT_RGMXF_RXDELAY_MASK | -+ (RTL8367B_EXT_RGMXF_TXDELAY_MASK << -+ RTL8367B_EXT_RGMXF_TXDELAY_SHIFT)); -+ -+ val = rxdelay; -+ val |= txdelay << RTL8367B_EXT_RGMXF_TXDELAY_SHIFT; -+ -+ REG_RMW(smi, RTL8367B_EXT_RGMXF_REG(id), mask, val); -+ -+ return 0; -+} -+ -+static int rtl8367b_extif_init(struct rtl8366_smi *smi, int id, -+ struct rtl8367_extif_config *cfg) -+{ -+ enum rtl8367_extif_mode mode; -+ int err; -+ -+ mode = (cfg) ? cfg->mode : RTL8367_EXTIF_MODE_DISABLED; -+ -+ err = rtl8367b_extif_set_mode(smi, id, mode); -+ if (err) -+ return err; -+ -+ if (mode != RTL8367_EXTIF_MODE_DISABLED) { -+ err = rtl8367b_extif_set_force(smi, id, &cfg->ability); -+ if (err) -+ return err; -+ -+ err = rtl8367b_extif_set_rgmii_delay(smi, id, cfg->txdelay, -+ cfg->rxdelay); -+ if (err) -+ return err; -+ } -+ -+ return 0; -+} -+ -+#ifdef CONFIG_OF -+static int rtl8367b_extif_init_of(struct rtl8366_smi *smi, -+ const char *name) -+{ -+ struct rtl8367_extif_config *cfg; -+ const __be32 *prop; -+ int size; -+ int err; -+ unsigned cpu_port; -+ unsigned id = UINT_MAX; -+ -+ prop = of_get_property(smi->parent->of_node, name, &size); -+ if (!prop || (size != (10 * sizeof(*prop)))) { -+ dev_err(smi->parent, "%s property is not defined or invalid\n", name); -+ err = -EINVAL; -+ goto err_init; -+ } -+ -+ cpu_port = be32_to_cpup(prop++); -+ switch (cpu_port) { -+ case RTL8367B_CPU_PORT_NUM: -+ case RTL8367B_CPU_PORT_NUM + 1: -+ case RTL8367B_CPU_PORT_NUM + 2: -+ if (smi->rtl8367b_chip == RTL8367B_CHIP_RTL8367R_VB) { /* for the RTL8367R-VB chip, cpu_port 5 corresponds to extif1 */ -+ if (cpu_port == RTL8367B_CPU_PORT_NUM) -+ id = 1; -+ else { -+ dev_err(smi->parent, "wrong cpu_port %u in %s property\n", cpu_port, name); -+ err = -EINVAL; -+ goto err_init; -+ } -+ } else if (smi->rtl8367b_chip == RTL8367B_CHIP_RTL8367S_VB) { /* for the RTL8367S-VB chip, cpu_port 7 corresponds to extif1, cpu_port 6 corresponds to extif0 */ -+ if (cpu_port != RTL8367B_CPU_PORT_NUM) { -+ id = cpu_port - RTL8367B_CPU_PORT_NUM - 1; -+ } else { -+ dev_err(smi->parent, "wrong cpu_port %u in %s property\n", cpu_port, name); -+ err = -EINVAL; -+ goto err_init; -+ } -+ } else { -+ id = cpu_port - RTL8367B_CPU_PORT_NUM; -+ } -+ if (smi->cpu_port == UINT_MAX) { -+ dev_info(smi->parent, "cpu_port:%u, assigned to extif%u\n", cpu_port, id); -+ smi->cpu_port = cpu_port; -+ } -+ break; -+ default: -+ dev_err(smi->parent, "wrong cpu_port %u in %s property\n", cpu_port, name); -+ err = -EINVAL; -+ goto err_init; -+ } -+ -+ cfg = kzalloc(sizeof(struct rtl8367_extif_config), GFP_KERNEL); -+ if (!cfg) -+ return -ENOMEM; -+ -+ cfg->txdelay = be32_to_cpup(prop++); -+ cfg->rxdelay = be32_to_cpup(prop++); -+ cfg->mode = be32_to_cpup(prop++); -+ cfg->ability.force_mode = be32_to_cpup(prop++); -+ cfg->ability.txpause = be32_to_cpup(prop++); -+ cfg->ability.rxpause = be32_to_cpup(prop++); -+ cfg->ability.link = be32_to_cpup(prop++); -+ cfg->ability.duplex = be32_to_cpup(prop++); -+ cfg->ability.speed = be32_to_cpup(prop++); -+ -+ err = rtl8367b_extif_init(smi, id, cfg); -+ kfree(cfg); -+ -+err_init: -+ if (id != 0) rtl8367b_extif_init(smi, 0, NULL); -+ if (id != 1) rtl8367b_extif_init(smi, 1, NULL); -+ if (id != 2) rtl8367b_extif_init(smi, 2, NULL); -+ -+ return err; -+} -+#else -+static int rtl8367b_extif_init_of(struct rtl8366_smi *smi, -+ const char *name) -+{ -+ return -EINVAL; -+} -+#endif -+ -+static int rtl8367b_setup(struct rtl8366_smi *smi) -+{ -+ struct rtl8367_platform_data *pdata; -+ int err; -+ int i; -+ -+ pdata = smi->parent->platform_data; -+ -+ err = rtl8367b_init_regs(smi); -+ if (err) -+ return err; -+ -+ /* initialize external interfaces */ -+ if (smi->parent->of_node) { -+ err = rtl8367b_extif_init_of(smi, "realtek,extif"); -+ if (err) -+ return err; -+ } else { -+ err = rtl8367b_extif_init(smi, 0, pdata->extif0_cfg); -+ if (err) -+ return err; -+ -+ err = rtl8367b_extif_init(smi, 1, pdata->extif1_cfg); -+ if (err) -+ return err; -+ } -+ -+ /* set maximum packet length to 1536 bytes */ -+ REG_RMW(smi, RTL8367B_SWC0_REG, RTL8367B_SWC0_MAX_LENGTH_MASK, -+ RTL8367B_SWC0_MAX_LENGTH_1536); -+ -+ /* -+ * discard VLAN tagged packets if the port is not a member of -+ * the VLAN with which the packets is associated. -+ */ -+ REG_WR(smi, RTL8367B_VLAN_INGRESS_REG, RTL8367B_PORTS_ALL); -+ -+ /* -+ * Setup egress tag mode for each port. -+ */ -+ for (i = 0; i < RTL8367B_NUM_PORTS; i++) -+ REG_RMW(smi, -+ RTL8367B_PORT_MISC_CFG_REG(i), -+ RTL8367B_PORT_MISC_CFG_EGRESS_MODE_MASK << -+ RTL8367B_PORT_MISC_CFG_EGRESS_MODE_SHIFT, -+ RTL8367B_PORT_MISC_CFG_EGRESS_MODE_ORIGINAL << -+ RTL8367B_PORT_MISC_CFG_EGRESS_MODE_SHIFT); -+ -+ return 0; -+} -+ -+static int rtl8367b_get_mib_counter(struct rtl8366_smi *smi, int counter, -+ int port, unsigned long long *val) -+{ -+ struct rtl8366_mib_counter *mib; -+ int offset; -+ int i; -+ int err; -+ u32 addr, data; -+ u64 mibvalue; -+ -+ if (port > RTL8367B_NUM_PORTS || -+ counter >= RTL8367B_NUM_MIB_COUNTERS) -+ return -EINVAL; -+ -+ mib = &rtl8367b_mib_counters[counter]; -+ addr = RTL8367B_MIB_COUNTER_PORT_OFFSET * port + mib->offset; -+ -+ /* -+ * Writing access counter address first -+ * then ASIC will prepare 64bits counter wait for being retrived -+ */ -+ REG_WR(smi, RTL8367B_MIB_ADDRESS_REG, addr >> 2); -+ -+ /* read MIB control register */ -+ REG_RD(smi, RTL8367B_MIB_CTRL0_REG(0), &data); -+ -+ if (data & RTL8367B_MIB_CTRL0_BUSY_MASK) -+ return -EBUSY; -+ -+ if (data & RTL8367B_MIB_CTRL0_RESET_MASK) -+ return -EIO; -+ -+ if (mib->length == 4) -+ offset = 3; -+ else -+ offset = (mib->offset + 1) % 4; -+ -+ mibvalue = 0; -+ for (i = 0; i < mib->length; i++) { -+ REG_RD(smi, RTL8367B_MIB_COUNTER_REG(offset - i), &data); -+ mibvalue = (mibvalue << 16) | (data & 0xFFFF); -+ } -+ -+ *val = mibvalue; -+ return 0; -+} -+ -+static int rtl8367b_get_vlan_4k(struct rtl8366_smi *smi, u32 vid, -+ struct rtl8366_vlan_4k *vlan4k) -+{ -+ u32 data[RTL8367B_TA_VLAN_NUM_WORDS]; -+ int err; -+ int i; -+ -+ memset(vlan4k, '\0', sizeof(struct rtl8366_vlan_4k)); -+ -+ if (vid >= RTL8367B_NUM_VIDS) -+ return -EINVAL; -+ -+ /* write VID */ -+ REG_WR(smi, RTL8367B_TA_ADDR_REG, vid); -+ -+ /* write table access control word */ -+ REG_WR(smi, RTL8367B_TA_CTRL_REG, RTL8367B_TA_CTRL_CVLAN_READ); -+ -+ for (i = 0; i < ARRAY_SIZE(data); i++) -+ REG_RD(smi, RTL8367B_TA_RDDATA_REG(i), &data[i]); -+ -+ vlan4k->vid = vid; -+ vlan4k->member = (data[0] >> RTL8367B_TA_VLAN0_MEMBER_SHIFT) & -+ RTL8367B_TA_VLAN0_MEMBER_MASK; -+ vlan4k->untag = (data[0] >> RTL8367B_TA_VLAN0_UNTAG_SHIFT) & -+ RTL8367B_TA_VLAN0_UNTAG_MASK; -+ if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) /* Family D */ -+ vlan4k->fid = (data[1] >> RTL8367D_TA_VLAN1_FID_SHIFT) & -+ RTL8367D_TA_VLAN1_FID_MASK; -+ else -+ vlan4k->fid = (data[1] >> RTL8367B_TA_VLAN1_FID_SHIFT) & -+ RTL8367B_TA_VLAN1_FID_MASK; -+ -+ return 0; -+} -+ -+static int rtl8367b_set_vlan_4k(struct rtl8366_smi *smi, -+ const struct rtl8366_vlan_4k *vlan4k) -+{ -+ u32 data[RTL8367B_TA_VLAN_NUM_WORDS]; -+ int err; -+ int i; -+ -+ if (vlan4k->vid >= RTL8367B_NUM_VIDS || -+ vlan4k->member > RTL8367B_TA_VLAN0_MEMBER_MASK || -+ vlan4k->untag > RTL8367B_UNTAG_MASK || -+ vlan4k->fid > ((smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) ? RTL8367D_FIDMAX : RTL8367B_FIDMAX)) -+ return -EINVAL; -+ -+ memset(data, 0, sizeof(data)); -+ -+ data[0] = (vlan4k->member & RTL8367B_TA_VLAN0_MEMBER_MASK) << -+ RTL8367B_TA_VLAN0_MEMBER_SHIFT; -+ data[0] |= (vlan4k->untag & RTL8367B_TA_VLAN0_UNTAG_MASK) << -+ RTL8367B_TA_VLAN0_UNTAG_SHIFT; -+ -+ if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) /* Family D */ -+ data[1] = ((vlan4k->fid & RTL8367D_TA_VLAN1_FID_MASK) << -+ RTL8367D_TA_VLAN1_FID_SHIFT) | 12; /* ivl_svl - BIT(3), svlan_chek_ivl_svl - BIT(2) */ -+ else -+ data[1] = (vlan4k->fid & RTL8367B_TA_VLAN1_FID_MASK) << -+ RTL8367B_TA_VLAN1_FID_SHIFT; -+ -+ for (i = 0; i < ARRAY_SIZE(data); i++) -+ REG_WR(smi, RTL8367B_TA_WRDATA_REG(i), data[i]); -+ -+ /* write VID */ -+ if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) /* Family D */ -+ REG_WR(smi, RTL8367B_TA_ADDR_REG, -+ vlan4k->vid & RTL8367D_TA_VLAN_VID_MASK); -+ else -+ REG_WR(smi, RTL8367B_TA_ADDR_REG, -+ vlan4k->vid & RTL8367B_TA_VLAN_VID_MASK); -+ -+ /* write table access control word */ -+ REG_WR(smi, RTL8367B_TA_CTRL_REG, RTL8367B_TA_CTRL_CVLAN_WRITE); -+ -+ return 0; -+} -+ -+static int rtl8367b_get_vlan_mc(struct rtl8366_smi *smi, u32 index, -+ struct rtl8366_vlan_mc *vlanmc) -+{ -+ u32 data[RTL8367B_VLAN_MC_NUM_WORDS]; -+ int err; -+ int i; -+ -+ memset(vlanmc, '\0', sizeof(struct rtl8366_vlan_mc)); -+ -+ if (index >= RTL8367B_NUM_VLANS) -+ return -EINVAL; -+ -+ if (smi->emu_vlanmc) { /* use vlan mc emulation */ -+ vlanmc->vid = smi->emu_vlanmc[index].vid; -+ vlanmc->member = smi->emu_vlanmc[index].member; -+ vlanmc->fid = smi->emu_vlanmc[index].fid; -+ vlanmc->untag = smi->emu_vlanmc[index].untag; -+ return 0; -+ } -+ -+ for (i = 0; i < ARRAY_SIZE(data); i++) -+ REG_RD(smi, RTL8367B_VLAN_MC_BASE(index) + i, &data[i]); -+ -+ vlanmc->member = (data[0] >> RTL8367B_VLAN_MC0_MEMBER_SHIFT) & -+ RTL8367B_VLAN_MC0_MEMBER_MASK; -+ vlanmc->fid = (data[1] >> RTL8367B_VLAN_MC1_FID_SHIFT) & -+ RTL8367B_VLAN_MC1_FID_MASK; -+ vlanmc->vid = (data[3] >> RTL8367B_VLAN_MC3_EVID_SHIFT) & -+ RTL8367B_VLAN_MC3_EVID_MASK; -+ -+ return 0; -+} -+ -+static int rtl8367b_set_vlan_mc(struct rtl8366_smi *smi, u32 index, -+ const struct rtl8366_vlan_mc *vlanmc) -+{ -+ u32 data[RTL8367B_VLAN_MC_NUM_WORDS]; -+ int err; -+ int i; -+ -+ if (index >= RTL8367B_NUM_VLANS || -+ vlanmc->vid >= RTL8367B_NUM_VIDS || -+ vlanmc->priority > RTL8367B_PRIORITYMAX || -+ vlanmc->member > RTL8367B_VLAN_MC0_MEMBER_MASK || -+ vlanmc->untag > RTL8367B_UNTAG_MASK || -+ vlanmc->fid > ((smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) ? RTL8367D_FIDMAX : RTL8367B_FIDMAX)) -+ return -EINVAL; -+ -+ if (smi->emu_vlanmc) { /* use vlanmc emulation */ -+ smi->emu_vlanmc[index].vid = vlanmc->vid; -+ smi->emu_vlanmc[index].member = vlanmc->member; -+ smi->emu_vlanmc[index].fid = vlanmc->fid; -+ smi->emu_vlanmc[index].untag = vlanmc->untag; -+ return 0; -+ } -+ -+ data[0] = (vlanmc->member & RTL8367B_VLAN_MC0_MEMBER_MASK) << -+ RTL8367B_VLAN_MC0_MEMBER_SHIFT; -+ data[1] = (vlanmc->fid & RTL8367B_VLAN_MC1_FID_MASK) << -+ RTL8367B_VLAN_MC1_FID_SHIFT; -+ data[2] = 0; -+ data[3] = (vlanmc->vid & RTL8367B_VLAN_MC3_EVID_MASK) << -+ RTL8367B_VLAN_MC3_EVID_SHIFT; -+ -+ for (i = 0; i < ARRAY_SIZE(data); i++) -+ REG_WR(smi, RTL8367B_VLAN_MC_BASE(index) + i, data[i]); -+ -+ return 0; -+} -+ -+static int rtl8367b_get_mc_index(struct rtl8366_smi *smi, int port, int *val) -+{ -+ u32 data; -+ int err; -+ -+ if (port >= RTL8367B_NUM_PORTS) -+ return -EINVAL; -+ -+ if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) { /* Family D */ -+ int i; -+ struct rtl8366_vlan_mc vlanmc; -+ -+ err = rtl8366_smi_read_reg(smi, RTL8367D_VLAN_PVID_CTRL_REG(port), &data); -+ -+ if (err) { -+ dev_err(smi->parent, "read pvid register 0x%04x fail", RTL8367D_VLAN_PVID_CTRL_REG(port)); -+ return err; -+ } -+ -+ data &= RTL8367D_VLAN_PVID_CTRL_MASK; -+ for (i = 0; i < smi->num_vlan_mc; i++) { -+ err = rtl8367b_get_vlan_mc(smi, i, &vlanmc); -+ -+ if (err) { -+ dev_err(smi->parent, "get vlan mc index %d fail", i); -+ return err; -+ } -+ -+ if (data == vlanmc.vid) break; -+ } -+ -+ if (i < smi->num_vlan_mc) { -+ *val = i; -+ } else { -+ dev_err(smi->parent, "vlan mc index for pvid %d not found", data); -+ return -EINVAL; -+ } -+ } else { -+ REG_RD(smi, RTL8367B_VLAN_PVID_CTRL_REG(port), &data); -+ -+ *val = (data >> RTL8367B_VLAN_PVID_CTRL_SHIFT(port)) & -+ RTL8367B_VLAN_PVID_CTRL_MASK; -+ } -+ -+ return 0; -+} -+ -+static int rtl8367b_set_mc_index(struct rtl8366_smi *smi, int port, int index) -+{ -+ if (port >= RTL8367B_NUM_PORTS || index >= RTL8367B_NUM_VLANS) -+ return -EINVAL; -+ -+ if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) { /* Family D */ -+ int pvid, err; -+ struct rtl8366_vlan_mc vlanmc; -+ -+ err = rtl8367b_get_vlan_mc(smi, index, &vlanmc); -+ -+ if (err) { -+ dev_err(smi->parent, "get vlan mc index %d fail", index); -+ return err; -+ } -+ -+ pvid = vlanmc.vid & RTL8367D_VLAN_PVID_CTRL_MASK; -+ err = rtl8366_smi_write_reg(smi, RTL8367D_VLAN_PVID_CTRL_REG(port), pvid); -+ -+ if (err) { -+ dev_err(smi->parent, "set port %d pvid %d fail", port, pvid); -+ return err; -+ } -+ -+ return 0; -+ } else -+ return rtl8366_smi_rmwr(smi, RTL8367B_VLAN_PVID_CTRL_REG(port), -+ RTL8367B_VLAN_PVID_CTRL_MASK << -+ RTL8367B_VLAN_PVID_CTRL_SHIFT(port), -+ (index & RTL8367B_VLAN_PVID_CTRL_MASK) << -+ RTL8367B_VLAN_PVID_CTRL_SHIFT(port)); -+} -+ -+static int rtl8367b_enable_vlan(struct rtl8366_smi *smi, int enable) -+{ -+ return rtl8366_smi_rmwr(smi, RTL8367B_VLAN_CTRL_REG, -+ RTL8367B_VLAN_CTRL_ENABLE, -+ (enable) ? RTL8367B_VLAN_CTRL_ENABLE : 0); -+} -+ -+static int rtl8367b_enable_vlan4k(struct rtl8366_smi *smi, int enable) -+{ -+ return 0; -+} -+ -+static int rtl8367b_is_vlan_valid(struct rtl8366_smi *smi, unsigned vlan) -+{ -+ unsigned max = RTL8367B_NUM_VLANS; -+ -+ if (smi->vlan4k_enabled) -+ max = RTL8367B_NUM_VIDS - 1; -+ -+ if (vlan == 0 || vlan >= max) -+ return 0; -+ -+ return 1; -+} -+ -+static int rtl8367b_enable_port(struct rtl8366_smi *smi, int port, int enable) -+{ -+ int err; -+ -+ REG_WR(smi, RTL8367B_PORT_ISOLATION_REG(port), -+ (enable) ? RTL8367B_PORTS_ALL : 0); -+ -+ return 0; -+} -+ -+static int rtl8367b_sw_reset_mibs(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ -+ return rtl8366_smi_rmwr(smi, RTL8367B_MIB_CTRL0_REG(0), 0, -+ RTL8367B_MIB_CTRL0_GLOBAL_RESET_MASK); -+} -+ -+static int rtl8367b_sw_get_port_link(struct switch_dev *dev, -+ int port, -+ struct switch_port_link *link) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data = 0; -+ u32 speed; -+ -+ if (port >= RTL8367B_NUM_PORTS) -+ return -EINVAL; -+ -+ if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) /* Family D */ -+ rtl8366_smi_read_reg(smi, RTL8367D_PORT_STATUS_REG(port), &data); -+ else -+ rtl8366_smi_read_reg(smi, RTL8367B_PORT_STATUS_REG(port), &data); -+ -+ link->link = !!(data & RTL8367B_PORT_STATUS_LINK); -+ if (!link->link) -+ return 0; -+ -+ link->duplex = !!(data & RTL8367B_PORT_STATUS_DUPLEX); -+ link->rx_flow = !!(data & RTL8367B_PORT_STATUS_RXPAUSE); -+ link->tx_flow = !!(data & RTL8367B_PORT_STATUS_TXPAUSE); -+ link->aneg = !!(data & RTL8367B_PORT_STATUS_NWAY); -+ -+ if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) /* Family D */ -+ speed = (data & RTL8367B_PORT_STATUS_SPEED_MASK) | ((data & RTL8367D_PORT_STATUS_SPEED1_MASK) >> RTL8367D_PORT_STATUS_SPEED1_SHIFT); -+ else -+ speed = (data & RTL8367B_PORT_STATUS_SPEED_MASK); -+ switch (speed) { -+ case RTL8367B_PORT_STATUS_SPEED_10: -+ link->speed = SWITCH_PORT_SPEED_10; -+ break; -+ case RTL8367B_PORT_STATUS_SPEED_100: -+ link->speed = SWITCH_PORT_SPEED_100; -+ break; -+ case RTL8367B_PORT_STATUS_SPEED_1000: -+ link->speed = SWITCH_PORT_SPEED_1000; -+ break; -+ default: -+ link->speed = SWITCH_PORT_SPEED_UNKNOWN; -+ break; -+ } -+ -+ return 0; -+} -+ -+static int rtl8367b_sw_get_max_length(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 data; -+ -+ rtl8366_smi_read_reg(smi, RTL8367B_SWC0_REG, &data); -+ val->value.i = (data & RTL8367B_SWC0_MAX_LENGTH_MASK) >> -+ RTL8367B_SWC0_MAX_LENGTH_SHIFT; -+ -+ return 0; -+} -+ -+static int rtl8367b_sw_set_max_length(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ u32 max_len; -+ -+ switch (val->value.i) { -+ case 0: -+ max_len = RTL8367B_SWC0_MAX_LENGTH_1522; -+ break; -+ case 1: -+ max_len = RTL8367B_SWC0_MAX_LENGTH_1536; -+ break; -+ case 2: -+ max_len = RTL8367B_SWC0_MAX_LENGTH_1552; -+ break; -+ case 3: -+ max_len = RTL8367B_SWC0_MAX_LENGTH_16000; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return rtl8366_smi_rmwr(smi, RTL8367B_SWC0_REG, -+ RTL8367B_SWC0_MAX_LENGTH_MASK, max_len); -+} -+ -+ -+static int rtl8367b_sw_reset_port_mibs(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev); -+ int port; -+ -+ port = val->port_vlan; -+ if (port >= RTL8367B_NUM_PORTS) -+ return -EINVAL; -+ -+ return rtl8366_smi_rmwr(smi, RTL8367B_MIB_CTRL0_REG(port / 8), 0, -+ RTL8367B_MIB_CTRL0_PORT_RESET_MASK(port % 8)); -+} -+ -+static int rtl8367b_sw_get_port_stats(struct switch_dev *dev, int port, -+ struct switch_port_stats *stats) -+{ -+ return (rtl8366_sw_get_port_stats(dev, port, stats, -+ RTL8367B_MIB_TXB_ID, RTL8367B_MIB_RXB_ID)); -+} -+ -+static struct switch_attr rtl8367b_globals[] = { -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_vlan", -+ .description = "Enable VLAN mode", -+ .set = rtl8366_sw_set_vlan_enable, -+ .get = rtl8366_sw_get_vlan_enable, -+ .max = 1, -+ .ofs = 1 -+ }, { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_vlan4k", -+ .description = "Enable VLAN 4K mode", -+ .set = rtl8366_sw_set_vlan_enable, -+ .get = rtl8366_sw_get_vlan_enable, -+ .max = 1, -+ .ofs = 2 -+ }, { -+ .type = SWITCH_TYPE_NOVAL, -+ .name = "reset_mibs", -+ .description = "Reset all MIB counters", -+ .set = rtl8367b_sw_reset_mibs, -+ }, { -+ .type = SWITCH_TYPE_INT, -+ .name = "max_length", -+ .description = "Get/Set the maximum length of valid packets" -+ "(0:1522, 1:1536, 2:1552, 3:16000)", -+ .set = rtl8367b_sw_set_max_length, -+ .get = rtl8367b_sw_get_max_length, -+ .max = 3, -+ } -+}; -+ -+static struct switch_attr rtl8367b_port[] = { -+ { -+ .type = SWITCH_TYPE_NOVAL, -+ .name = "reset_mib", -+ .description = "Reset single port MIB counters", -+ .set = rtl8367b_sw_reset_port_mibs, -+ }, { -+ .type = SWITCH_TYPE_STRING, -+ .name = "mib", -+ .description = "Get MIB counters for port", -+ .max = 33, -+ .set = NULL, -+ .get = rtl8366_sw_get_port_mib, -+ }, -+}; -+ -+static struct switch_attr rtl8367b_vlan[] = { -+ { -+ .type = SWITCH_TYPE_STRING, -+ .name = "info", -+ .description = "Get vlan information", -+ .max = 1, -+ .set = NULL, -+ .get = rtl8366_sw_get_vlan_info, -+ }, -+}; -+ -+static const struct switch_dev_ops rtl8367b_sw_ops = { -+ .attr_global = { -+ .attr = rtl8367b_globals, -+ .n_attr = ARRAY_SIZE(rtl8367b_globals), -+ }, -+ .attr_port = { -+ .attr = rtl8367b_port, -+ .n_attr = ARRAY_SIZE(rtl8367b_port), -+ }, -+ .attr_vlan = { -+ .attr = rtl8367b_vlan, -+ .n_attr = ARRAY_SIZE(rtl8367b_vlan), -+ }, -+ -+ .get_vlan_ports = rtl8366_sw_get_vlan_ports, -+ .set_vlan_ports = rtl8366_sw_set_vlan_ports, -+ .get_port_pvid = rtl8366_sw_get_port_pvid, -+ .set_port_pvid = rtl8366_sw_set_port_pvid, -+ .reset_switch = rtl8366_sw_reset_switch, -+ .get_port_link = rtl8367b_sw_get_port_link, -+ .get_port_stats = rtl8367b_sw_get_port_stats, -+}; -+ -+static int rtl8367b_switch_init(struct rtl8366_smi *smi) -+{ -+ struct switch_dev *dev = &smi->sw_dev; -+ int err; -+ -+ dev->name = "RTL8367B"; -+ dev->cpu_port = smi->cpu_port; -+ dev->ports = RTL8367B_NUM_PORTS; -+ dev->vlans = RTL8367B_NUM_VIDS; -+ dev->ops = &rtl8367b_sw_ops; -+ dev->alias = dev_name(smi->parent); -+ -+ err = register_switch(dev, NULL); -+ if (err) -+ dev_err(smi->parent, "switch registration failed\n"); -+ -+ return err; -+} -+ -+static void rtl8367b_switch_cleanup(struct rtl8366_smi *smi) -+{ -+ unregister_switch(&smi->sw_dev); -+} -+ -+static int rtl8367b_mii_read(struct mii_bus *bus, int addr, int reg) -+{ -+ struct rtl8366_smi *smi = bus->priv; -+ u32 val = 0; -+ int err; -+ -+ err = rtl8367b_read_phy_reg(smi, addr, reg, &val); -+ if (err) -+ return 0xffff; -+ -+ return val; -+} -+ -+static int rtl8367b_mii_write(struct mii_bus *bus, int addr, int reg, u16 val) -+{ -+ struct rtl8366_smi *smi = bus->priv; -+ u32 t; -+ int err; -+ -+ err = rtl8367b_write_phy_reg(smi, addr, reg, val); -+ if (err) -+ return err; -+ -+ /* flush write */ -+ (void) rtl8367b_read_phy_reg(smi, addr, reg, &t); -+ -+ return err; -+} -+ -+static int rtl8367b_detect(struct rtl8366_smi *smi) -+{ -+ const char *chip_name = NULL; -+ u32 chip_num; -+ u32 chip_ver; -+ int ret; -+ -+ smi->emu_vlanmc = NULL; -+ smi->rtl8367b_chip = RTL8367B_CHIP_UNKNOWN; -+ -+ rtl8366_smi_write_reg(smi, RTL8367B_RTL_MAGIC_ID_REG, -+ RTL8367B_RTL_MAGIC_ID_VAL); -+ -+ ret = rtl8366_smi_read_reg(smi, RTL8367B_CHIP_NUMBER_REG, &chip_num); -+ if (ret) { -+ dev_err(smi->parent, "unable to read %s register\n", -+ "chip number"); -+ return ret; -+ } -+ -+ ret = rtl8366_smi_read_reg(smi, RTL8367B_CHIP_VER_REG, &chip_ver); -+ if (ret) { -+ dev_err(smi->parent, "unable to read %s register\n", -+ "chip version"); -+ return ret; -+ } -+ -+ switch (chip_ver) { -+ case 0x0010: -+ if (chip_num == 0x6642) { -+ chip_name = "8367S-VB"; -+ smi->rtl8367b_chip = RTL8367B_CHIP_RTL8367S_VB; -+ } -+ break; -+ case 0x0020: -+ if (chip_num == 0x6367) { -+ chip_name = "8367RB-VB"; -+ smi->rtl8367b_chip = RTL8367B_CHIP_RTL8367RB_VB; -+ } -+ break; -+ case 0x00A0: -+ if (chip_num == 0x6367) { -+ chip_name = "8367S"; -+ smi->rtl8367b_chip = RTL8367B_CHIP_RTL8367S; -+ } -+ break; -+ case 0x1000: -+ chip_name = "8367RB"; -+ smi->rtl8367b_chip = RTL8367B_CHIP_RTL8367RB; -+ break; -+ case 0x1010: -+ chip_name = "8367R-VB"; -+ smi->rtl8367b_chip = RTL8367B_CHIP_RTL8367R_VB; -+ } -+ -+ if (!chip_name) { -+ dev_err(smi->parent, -+ "unknown chip (num:%04x ver:%04x)\n", -+ chip_num, chip_ver); -+ return -ENODEV; -+ } -+ -+ dev_info(smi->parent, "RTL%s chip found (num:%04x ver:%04x)\n", chip_name, chip_num, chip_ver); -+ -+ return 0; -+} -+ -+static struct rtl8366_smi_ops rtl8367b_smi_ops = { -+ .detect = rtl8367b_detect, -+ .reset_chip = rtl8367b_reset_chip, -+ .setup = rtl8367b_setup, -+ -+ .mii_read = rtl8367b_mii_read, -+ .mii_write = rtl8367b_mii_write, -+ -+ .get_vlan_mc = rtl8367b_get_vlan_mc, -+ .set_vlan_mc = rtl8367b_set_vlan_mc, -+ .get_vlan_4k = rtl8367b_get_vlan_4k, -+ .set_vlan_4k = rtl8367b_set_vlan_4k, -+ .get_mc_index = rtl8367b_get_mc_index, -+ .set_mc_index = rtl8367b_set_mc_index, -+ .get_mib_counter = rtl8367b_get_mib_counter, -+ .is_vlan_valid = rtl8367b_is_vlan_valid, -+ .enable_vlan = rtl8367b_enable_vlan, -+ .enable_vlan4k = rtl8367b_enable_vlan4k, -+ .enable_port = rtl8367b_enable_port, -+}; -+ -+static int rtl8367b_probe(struct platform_device *pdev) -+{ -+ struct rtl8366_smi *smi; -+ int err; -+ -+ smi = rtl8366_smi_probe(pdev); -+ if (IS_ERR(smi)) -+ return PTR_ERR(smi); -+ -+ smi->clk_delay = 1500; -+ smi->cmd_read = 0xb9; -+ smi->cmd_write = 0xb8; -+ smi->ops = &rtl8367b_smi_ops; -+ smi->num_ports = RTL8367B_NUM_PORTS; -+ smi->cpu_port = UINT_MAX; /* not defined yet */ -+ smi->num_vlan_mc = RTL8367B_NUM_VLANS; -+ smi->mib_counters = rtl8367b_mib_counters; -+ smi->num_mib_counters = ARRAY_SIZE(rtl8367b_mib_counters); -+ -+ err = rtl8366_smi_init(smi); -+ if (err) -+ goto err_free_smi; -+ -+ platform_set_drvdata(pdev, smi); -+ -+ err = rtl8367b_switch_init(smi); -+ if (err) -+ goto err_clear_drvdata; -+ -+ return 0; -+ -+ err_clear_drvdata: -+ platform_set_drvdata(pdev, NULL); -+ rtl8366_smi_cleanup(smi); -+ err_free_smi: -+ if (smi->emu_vlanmc) -+ kfree(smi->emu_vlanmc); -+ kfree(smi); -+ return err; -+} -+ -+static void rtl8367b_remove(struct platform_device *pdev) -+{ -+ struct rtl8366_smi *smi = platform_get_drvdata(pdev); -+ -+ if (smi) { -+ rtl8367b_switch_cleanup(smi); -+ platform_set_drvdata(pdev, NULL); -+ rtl8366_smi_cleanup(smi); -+ kfree(smi); -+ } -+} -+ -+static void rtl8367b_shutdown(struct platform_device *pdev) -+{ -+ struct rtl8366_smi *smi = platform_get_drvdata(pdev); -+ -+ if (smi) -+ rtl8367b_reset_chip(smi); -+} -+ -+#ifdef CONFIG_OF -+static const struct of_device_id rtl8367b_match[] = { -+ { .compatible = "realtek,rtl8367b" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, rtl8367b_match); -+#endif -+ -+static struct platform_driver rtl8367b_driver = { -+ .driver = { -+ .name = RTL8367B_DRIVER_NAME, -+#ifdef CONFIG_OF -+ .of_match_table = of_match_ptr(rtl8367b_match), -+#endif -+ }, -+ .probe = rtl8367b_probe, -+ .remove_new = rtl8367b_remove, -+ .shutdown = rtl8367b_shutdown, -+}; -+ -+module_platform_driver(rtl8367b_driver); -+ -+MODULE_DESCRIPTION("Realtek RTL8367B ethernet switch driver"); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:" RTL8367B_DRIVER_NAME); -+ -diff --git a/drivers/net/phy/swconfig.c b/drivers/net/phy/swconfig.c -new file mode 100644 -index 000000000000..71dd5b31f541 ---- /dev/null -+++ b/drivers/net/phy/swconfig.c -@@ -0,0 +1,1242 @@ -+/* -+ * swconfig.c: Switch configuration API -+ * -+ * Copyright (C) 2008 Felix Fietkau -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define SWCONFIG_DEVNAME "switch%d" -+ -+#include "swconfig_leds.c" -+ -+MODULE_AUTHOR("Felix Fietkau "); -+MODULE_LICENSE("GPL"); -+ -+static int swdev_id; -+static struct list_head swdevs; -+static DEFINE_MUTEX(swdevs_lock); -+struct swconfig_callback; -+ -+struct swconfig_callback { -+ struct sk_buff *msg; -+ struct genlmsghdr *hdr; -+ struct genl_info *info; -+ int cmd; -+ -+ /* callback for filling in the message data */ -+ int (*fill)(struct swconfig_callback *cb, void *arg); -+ -+ /* callback for closing the message before sending it */ -+ int (*close)(struct swconfig_callback *cb, void *arg); -+ -+ struct nlattr *nest[4]; -+ int args[4]; -+}; -+ -+/* defaults */ -+ -+static int -+swconfig_get_vlan_ports(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ int ret; -+ if (val->port_vlan >= dev->vlans) -+ return -EINVAL; -+ -+ if (!dev->ops->get_vlan_ports) -+ return -EOPNOTSUPP; -+ -+ ret = dev->ops->get_vlan_ports(dev, val); -+ return ret; -+} -+ -+static int -+swconfig_set_vlan_ports(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct switch_port *ports = val->value.ports; -+ const struct switch_dev_ops *ops = dev->ops; -+ int i; -+ -+ if (val->port_vlan >= dev->vlans) -+ return -EINVAL; -+ -+ /* validate ports */ -+ if (val->len > dev->ports) -+ return -EINVAL; -+ -+ if (!ops->set_vlan_ports) -+ return -EOPNOTSUPP; -+ -+ for (i = 0; i < val->len; i++) { -+ if (ports[i].id >= dev->ports) -+ return -EINVAL; -+ -+ if (ops->set_port_pvid && -+ !(ports[i].flags & (1 << SWITCH_PORT_FLAG_TAGGED))) -+ ops->set_port_pvid(dev, ports[i].id, val->port_vlan); -+ } -+ -+ return ops->set_vlan_ports(dev, val); -+} -+ -+static int -+swconfig_set_pvid(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ if (val->port_vlan >= dev->ports) -+ return -EINVAL; -+ -+ if (!dev->ops->set_port_pvid) -+ return -EOPNOTSUPP; -+ -+ return dev->ops->set_port_pvid(dev, val->port_vlan, val->value.i); -+} -+ -+static int -+swconfig_get_pvid(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ if (val->port_vlan >= dev->ports) -+ return -EINVAL; -+ -+ if (!dev->ops->get_port_pvid) -+ return -EOPNOTSUPP; -+ -+ return dev->ops->get_port_pvid(dev, val->port_vlan, &val->value.i); -+} -+ -+static int -+swconfig_set_link(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ if (!dev->ops->set_port_link) -+ return -EOPNOTSUPP; -+ -+ return dev->ops->set_port_link(dev, val->port_vlan, val->value.link); -+} -+ -+static int -+swconfig_get_link(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct switch_port_link *link = val->value.link; -+ -+ if (val->port_vlan >= dev->ports) -+ return -EINVAL; -+ -+ if (!dev->ops->get_port_link) -+ return -EOPNOTSUPP; -+ -+ memset(link, 0, sizeof(*link)); -+ return dev->ops->get_port_link(dev, val->port_vlan, link); -+} -+ -+static int -+swconfig_apply_config(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ /* don't complain if not supported by the switch driver */ -+ if (!dev->ops->apply_config) -+ return 0; -+ -+ return dev->ops->apply_config(dev); -+} -+ -+static int -+swconfig_reset_switch(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ /* don't complain if not supported by the switch driver */ -+ if (!dev->ops->reset_switch) -+ return 0; -+ -+ return dev->ops->reset_switch(dev); -+} -+ -+enum global_defaults { -+ GLOBAL_APPLY, -+ GLOBAL_RESET, -+}; -+ -+enum vlan_defaults { -+ VLAN_PORTS, -+}; -+ -+enum port_defaults { -+ PORT_PVID, -+ PORT_LINK, -+}; -+ -+static struct switch_attr default_global[] = { -+ [GLOBAL_APPLY] = { -+ .type = SWITCH_TYPE_NOVAL, -+ .name = "apply", -+ .description = "Activate changes in the hardware", -+ .set = swconfig_apply_config, -+ }, -+ [GLOBAL_RESET] = { -+ .type = SWITCH_TYPE_NOVAL, -+ .name = "reset", -+ .description = "Reset the switch", -+ .set = swconfig_reset_switch, -+ } -+}; -+ -+static struct switch_attr default_port[] = { -+ [PORT_PVID] = { -+ .type = SWITCH_TYPE_INT, -+ .name = "pvid", -+ .description = "Primary VLAN ID", -+ .set = swconfig_set_pvid, -+ .get = swconfig_get_pvid, -+ }, -+ [PORT_LINK] = { -+ .type = SWITCH_TYPE_LINK, -+ .name = "link", -+ .description = "Get port link information", -+ .set = swconfig_set_link, -+ .get = swconfig_get_link, -+ } -+}; -+ -+static struct switch_attr default_vlan[] = { -+ [VLAN_PORTS] = { -+ .type = SWITCH_TYPE_PORTS, -+ .name = "ports", -+ .description = "VLAN port mapping", -+ .set = swconfig_set_vlan_ports, -+ .get = swconfig_get_vlan_ports, -+ }, -+}; -+ -+static const struct switch_attr * -+swconfig_find_attr_by_name(const struct switch_attrlist *alist, -+ const char *name) -+{ -+ int i; -+ -+ for (i = 0; i < alist->n_attr; i++) -+ if (strcmp(name, alist->attr[i].name) == 0) -+ return &alist->attr[i]; -+ -+ return NULL; -+} -+ -+static void swconfig_defaults_init(struct switch_dev *dev) -+{ -+ const struct switch_dev_ops *ops = dev->ops; -+ -+ dev->def_global = 0; -+ dev->def_vlan = 0; -+ dev->def_port = 0; -+ -+ if (ops->get_vlan_ports || ops->set_vlan_ports) -+ set_bit(VLAN_PORTS, &dev->def_vlan); -+ -+ if (ops->get_port_pvid || ops->set_port_pvid) -+ set_bit(PORT_PVID, &dev->def_port); -+ -+ if (ops->get_port_link && -+ !swconfig_find_attr_by_name(&ops->attr_port, "link")) -+ set_bit(PORT_LINK, &dev->def_port); -+ -+ /* always present, can be no-op */ -+ set_bit(GLOBAL_APPLY, &dev->def_global); -+ set_bit(GLOBAL_RESET, &dev->def_global); -+} -+ -+ -+static struct genl_family switch_fam; -+ -+static const struct nla_policy switch_policy[SWITCH_ATTR_MAX+1] = { -+ [SWITCH_ATTR_ID] = { .type = NLA_U32 }, -+ [SWITCH_ATTR_OP_ID] = { .type = NLA_U32 }, -+ [SWITCH_ATTR_OP_PORT] = { .type = NLA_U32 }, -+ [SWITCH_ATTR_OP_VLAN] = { .type = NLA_U32 }, -+ [SWITCH_ATTR_OP_VALUE_INT] = { .type = NLA_U32 }, -+ [SWITCH_ATTR_OP_VALUE_STR] = { .type = NLA_NUL_STRING }, -+ [SWITCH_ATTR_OP_VALUE_PORTS] = { .type = NLA_NESTED }, -+ [SWITCH_ATTR_TYPE] = { .type = NLA_U32 }, -+}; -+ -+static const struct nla_policy port_policy[SWITCH_PORT_ATTR_MAX+1] = { -+ [SWITCH_PORT_ID] = { .type = NLA_U32 }, -+ [SWITCH_PORT_FLAG_TAGGED] = { .type = NLA_FLAG }, -+}; -+ -+static struct nla_policy link_policy[SWITCH_LINK_ATTR_MAX] = { -+ [SWITCH_LINK_FLAG_DUPLEX] = { .type = NLA_FLAG }, -+ [SWITCH_LINK_FLAG_ANEG] = { .type = NLA_FLAG }, -+ [SWITCH_LINK_SPEED] = { .type = NLA_U32 }, -+}; -+ -+static inline void -+swconfig_lock(void) -+{ -+ mutex_lock(&swdevs_lock); -+} -+ -+static inline void -+swconfig_unlock(void) -+{ -+ mutex_unlock(&swdevs_lock); -+} -+ -+static struct switch_dev * -+swconfig_get_dev(struct genl_info *info) -+{ -+ struct switch_dev *dev = NULL; -+ struct switch_dev *p; -+ int id; -+ -+ if (!info->attrs[SWITCH_ATTR_ID]) -+ goto done; -+ -+ id = nla_get_u32(info->attrs[SWITCH_ATTR_ID]); -+ swconfig_lock(); -+ list_for_each_entry(p, &swdevs, dev_list) { -+ if (id != p->id) -+ continue; -+ -+ dev = p; -+ break; -+ } -+ if (dev) -+ mutex_lock(&dev->sw_mutex); -+ else -+ pr_debug("device %d not found\n", id); -+ swconfig_unlock(); -+done: -+ return dev; -+} -+ -+static inline void -+swconfig_put_dev(struct switch_dev *dev) -+{ -+ mutex_unlock(&dev->sw_mutex); -+} -+ -+static int -+swconfig_dump_attr(struct swconfig_callback *cb, void *arg) -+{ -+ struct switch_attr *op = arg; -+ struct genl_info *info = cb->info; -+ struct sk_buff *msg = cb->msg; -+ int id = cb->args[0]; -+ void *hdr; -+ -+ hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq, &switch_fam, -+ NLM_F_MULTI, SWITCH_CMD_NEW_ATTR); -+ if (IS_ERR(hdr)) -+ return -1; -+ -+ if (nla_put_u32(msg, SWITCH_ATTR_OP_ID, id)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, SWITCH_ATTR_OP_TYPE, op->type)) -+ goto nla_put_failure; -+ if (nla_put_string(msg, SWITCH_ATTR_OP_NAME, op->name)) -+ goto nla_put_failure; -+ if (op->description) -+ if (nla_put_string(msg, SWITCH_ATTR_OP_DESCRIPTION, -+ op->description)) -+ goto nla_put_failure; -+ -+ genlmsg_end(msg, hdr); -+ return msg->len; -+nla_put_failure: -+ genlmsg_cancel(msg, hdr); -+ return -EMSGSIZE; -+} -+ -+/* spread multipart messages across multiple message buffers */ -+static int -+swconfig_send_multipart(struct swconfig_callback *cb, void *arg) -+{ -+ struct genl_info *info = cb->info; -+ int restart = 0; -+ int err; -+ -+ do { -+ if (!cb->msg) { -+ cb->msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); -+ if (cb->msg == NULL) -+ goto error; -+ } -+ -+ if (!(cb->fill(cb, arg) < 0)) -+ break; -+ -+ /* fill failed, check if this was already the second attempt */ -+ if (restart) -+ goto error; -+ -+ /* try again in a new message, send the current one */ -+ restart = 1; -+ if (cb->close) { -+ if (cb->close(cb, arg) < 0) -+ goto error; -+ } -+ err = genlmsg_reply(cb->msg, info); -+ cb->msg = NULL; -+ if (err < 0) -+ goto error; -+ -+ } while (restart); -+ -+ return 0; -+ -+error: -+ if (cb->msg) -+ nlmsg_free(cb->msg); -+ return -1; -+} -+ -+static int -+swconfig_list_attrs(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct genlmsghdr *hdr = nlmsg_data(info->nlhdr); -+ const struct switch_attrlist *alist; -+ struct switch_dev *dev; -+ struct swconfig_callback cb; -+ int err = -EINVAL; -+ int i; -+ -+ /* defaults */ -+ struct switch_attr *def_list; -+ unsigned long *def_active; -+ int n_def; -+ -+ dev = swconfig_get_dev(info); -+ if (!dev) -+ return -EINVAL; -+ -+ switch (hdr->cmd) { -+ case SWITCH_CMD_LIST_GLOBAL: -+ alist = &dev->ops->attr_global; -+ def_list = default_global; -+ def_active = &dev->def_global; -+ n_def = ARRAY_SIZE(default_global); -+ break; -+ case SWITCH_CMD_LIST_VLAN: -+ alist = &dev->ops->attr_vlan; -+ def_list = default_vlan; -+ def_active = &dev->def_vlan; -+ n_def = ARRAY_SIZE(default_vlan); -+ break; -+ case SWITCH_CMD_LIST_PORT: -+ alist = &dev->ops->attr_port; -+ def_list = default_port; -+ def_active = &dev->def_port; -+ n_def = ARRAY_SIZE(default_port); -+ break; -+ default: -+ WARN_ON(1); -+ goto out; -+ } -+ -+ memset(&cb, 0, sizeof(cb)); -+ cb.info = info; -+ cb.fill = swconfig_dump_attr; -+ for (i = 0; i < alist->n_attr; i++) { -+ if (alist->attr[i].disabled) -+ continue; -+ cb.args[0] = i; -+ err = swconfig_send_multipart(&cb, (void *) &alist->attr[i]); -+ if (err < 0) -+ goto error; -+ } -+ -+ /* defaults */ -+ for (i = 0; i < n_def; i++) { -+ if (!test_bit(i, def_active)) -+ continue; -+ cb.args[0] = SWITCH_ATTR_DEFAULTS_OFFSET + i; -+ err = swconfig_send_multipart(&cb, (void *) &def_list[i]); -+ if (err < 0) -+ goto error; -+ } -+ swconfig_put_dev(dev); -+ -+ if (!cb.msg) -+ return 0; -+ -+ return genlmsg_reply(cb.msg, info); -+ -+error: -+ if (cb.msg) -+ nlmsg_free(cb.msg); -+out: -+ swconfig_put_dev(dev); -+ return err; -+} -+ -+static const struct switch_attr * -+swconfig_lookup_attr(struct switch_dev *dev, struct genl_info *info, -+ struct switch_val *val) -+{ -+ struct genlmsghdr *hdr = nlmsg_data(info->nlhdr); -+ const struct switch_attrlist *alist; -+ const struct switch_attr *attr = NULL; -+ unsigned int attr_id; -+ -+ /* defaults */ -+ struct switch_attr *def_list; -+ unsigned long *def_active; -+ int n_def; -+ -+ if (!info->attrs[SWITCH_ATTR_OP_ID]) -+ goto done; -+ -+ switch (hdr->cmd) { -+ case SWITCH_CMD_SET_GLOBAL: -+ case SWITCH_CMD_GET_GLOBAL: -+ alist = &dev->ops->attr_global; -+ def_list = default_global; -+ def_active = &dev->def_global; -+ n_def = ARRAY_SIZE(default_global); -+ break; -+ case SWITCH_CMD_SET_VLAN: -+ case SWITCH_CMD_GET_VLAN: -+ alist = &dev->ops->attr_vlan; -+ def_list = default_vlan; -+ def_active = &dev->def_vlan; -+ n_def = ARRAY_SIZE(default_vlan); -+ if (!info->attrs[SWITCH_ATTR_OP_VLAN]) -+ goto done; -+ val->port_vlan = nla_get_u32(info->attrs[SWITCH_ATTR_OP_VLAN]); -+ if (val->port_vlan >= dev->vlans) -+ goto done; -+ break; -+ case SWITCH_CMD_SET_PORT: -+ case SWITCH_CMD_GET_PORT: -+ alist = &dev->ops->attr_port; -+ def_list = default_port; -+ def_active = &dev->def_port; -+ n_def = ARRAY_SIZE(default_port); -+ if (!info->attrs[SWITCH_ATTR_OP_PORT]) -+ goto done; -+ val->port_vlan = nla_get_u32(info->attrs[SWITCH_ATTR_OP_PORT]); -+ if (val->port_vlan >= dev->ports) -+ goto done; -+ break; -+ default: -+ WARN_ON(1); -+ goto done; -+ } -+ -+ if (!alist) -+ goto done; -+ -+ attr_id = nla_get_u32(info->attrs[SWITCH_ATTR_OP_ID]); -+ if (attr_id >= SWITCH_ATTR_DEFAULTS_OFFSET) { -+ attr_id -= SWITCH_ATTR_DEFAULTS_OFFSET; -+ if (attr_id >= n_def) -+ goto done; -+ if (!test_bit(attr_id, def_active)) -+ goto done; -+ attr = &def_list[attr_id]; -+ } else { -+ if (attr_id >= alist->n_attr) -+ goto done; -+ attr = &alist->attr[attr_id]; -+ } -+ -+ if (attr->disabled) -+ attr = NULL; -+ -+done: -+ if (!attr) -+ pr_debug("attribute lookup failed\n"); -+ val->attr = attr; -+ return attr; -+} -+ -+static int -+swconfig_parse_ports(struct sk_buff *msg, struct nlattr *head, -+ struct switch_val *val, int max) -+{ -+ struct nlattr *nla; -+ int rem; -+ -+ val->len = 0; -+ nla_for_each_nested(nla, head, rem) { -+ struct nlattr *tb[SWITCH_PORT_ATTR_MAX+1]; -+ struct switch_port *port; -+ -+ if (val->len >= max) -+ return -EINVAL; -+ -+ port = &val->value.ports[val->len]; -+ -+ if (nla_parse_nested_deprecated(tb, SWITCH_PORT_ATTR_MAX, nla, -+ port_policy, NULL)) -+ return -EINVAL; -+ -+ if (!tb[SWITCH_PORT_ID]) -+ return -EINVAL; -+ -+ port->id = nla_get_u32(tb[SWITCH_PORT_ID]); -+ if (tb[SWITCH_PORT_FLAG_TAGGED]) -+ port->flags |= (1 << SWITCH_PORT_FLAG_TAGGED); -+ val->len++; -+ } -+ -+ return 0; -+} -+ -+static int -+swconfig_parse_link(struct sk_buff *msg, struct nlattr *nla, -+ struct switch_port_link *link) -+{ -+ struct nlattr *tb[SWITCH_LINK_ATTR_MAX + 1]; -+ -+ if (nla_parse_nested_deprecated(tb, SWITCH_LINK_ATTR_MAX, nla, link_policy, NULL)) -+ return -EINVAL; -+ -+ link->duplex = !!tb[SWITCH_LINK_FLAG_DUPLEX]; -+ link->aneg = !!tb[SWITCH_LINK_FLAG_ANEG]; -+ link->speed = nla_get_u32(tb[SWITCH_LINK_SPEED]); -+ -+ return 0; -+} -+ -+static int -+swconfig_set_attr(struct sk_buff *skb, struct genl_info *info) -+{ -+ const struct switch_attr *attr; -+ struct switch_dev *dev; -+ struct switch_val val; -+ int err = -EINVAL; -+ -+ if (!capable(CAP_NET_ADMIN)) -+ return -EPERM; -+ -+ dev = swconfig_get_dev(info); -+ if (!dev) -+ return -EINVAL; -+ -+ memset(&val, 0, sizeof(val)); -+ attr = swconfig_lookup_attr(dev, info, &val); -+ if (!attr || !attr->set) -+ goto error; -+ -+ val.attr = attr; -+ switch (attr->type) { -+ case SWITCH_TYPE_NOVAL: -+ break; -+ case SWITCH_TYPE_INT: -+ if (!info->attrs[SWITCH_ATTR_OP_VALUE_INT]) -+ goto error; -+ val.value.i = -+ nla_get_u32(info->attrs[SWITCH_ATTR_OP_VALUE_INT]); -+ break; -+ case SWITCH_TYPE_STRING: -+ if (!info->attrs[SWITCH_ATTR_OP_VALUE_STR]) -+ goto error; -+ val.value.s = -+ nla_data(info->attrs[SWITCH_ATTR_OP_VALUE_STR]); -+ break; -+ case SWITCH_TYPE_PORTS: -+ val.value.ports = dev->portbuf; -+ memset(dev->portbuf, 0, -+ sizeof(struct switch_port) * dev->ports); -+ -+ /* TODO: implement multipart? */ -+ if (info->attrs[SWITCH_ATTR_OP_VALUE_PORTS]) { -+ err = swconfig_parse_ports(skb, -+ info->attrs[SWITCH_ATTR_OP_VALUE_PORTS], -+ &val, dev->ports); -+ if (err < 0) -+ goto error; -+ } else { -+ val.len = 0; -+ err = 0; -+ } -+ break; -+ case SWITCH_TYPE_LINK: -+ val.value.link = &dev->linkbuf; -+ memset(&dev->linkbuf, 0, sizeof(struct switch_port_link)); -+ -+ if (info->attrs[SWITCH_ATTR_OP_VALUE_LINK]) { -+ err = swconfig_parse_link(skb, -+ info->attrs[SWITCH_ATTR_OP_VALUE_LINK], -+ val.value.link); -+ if (err < 0) -+ goto error; -+ } else { -+ val.len = 0; -+ err = 0; -+ } -+ break; -+ default: -+ goto error; -+ } -+ -+ err = attr->set(dev, attr, &val); -+error: -+ swconfig_put_dev(dev); -+ return err; -+} -+ -+static int -+swconfig_close_portlist(struct swconfig_callback *cb, void *arg) -+{ -+ if (cb->nest[0]) -+ nla_nest_end(cb->msg, cb->nest[0]); -+ return 0; -+} -+ -+static int -+swconfig_send_port(struct swconfig_callback *cb, void *arg) -+{ -+ const struct switch_port *port = arg; -+ struct nlattr *p = NULL; -+ -+ if (!cb->nest[0]) { -+ cb->nest[0] = nla_nest_start(cb->msg, cb->cmd); -+ if (!cb->nest[0]) -+ return -1; -+ } -+ -+ p = nla_nest_start(cb->msg, SWITCH_ATTR_PORT); -+ if (!p) -+ goto error; -+ -+ if (nla_put_u32(cb->msg, SWITCH_PORT_ID, port->id)) -+ goto nla_put_failure; -+ if (port->flags & (1 << SWITCH_PORT_FLAG_TAGGED)) { -+ if (nla_put_flag(cb->msg, SWITCH_PORT_FLAG_TAGGED)) -+ goto nla_put_failure; -+ } -+ -+ nla_nest_end(cb->msg, p); -+ return 0; -+ -+nla_put_failure: -+ nla_nest_cancel(cb->msg, p); -+error: -+ nla_nest_cancel(cb->msg, cb->nest[0]); -+ return -1; -+} -+ -+static int -+swconfig_send_ports(struct sk_buff **msg, struct genl_info *info, int attr, -+ const struct switch_val *val) -+{ -+ struct swconfig_callback cb; -+ int err = 0; -+ int i; -+ -+ if (!val->value.ports) -+ return -EINVAL; -+ -+ memset(&cb, 0, sizeof(cb)); -+ cb.cmd = attr; -+ cb.msg = *msg; -+ cb.info = info; -+ cb.fill = swconfig_send_port; -+ cb.close = swconfig_close_portlist; -+ -+ cb.nest[0] = nla_nest_start(cb.msg, cb.cmd); -+ for (i = 0; i < val->len; i++) { -+ err = swconfig_send_multipart(&cb, &val->value.ports[i]); -+ if (err) -+ goto done; -+ } -+ err = val->len; -+ swconfig_close_portlist(&cb, NULL); -+ *msg = cb.msg; -+ -+done: -+ return err; -+} -+ -+static int -+swconfig_send_link(struct sk_buff *msg, struct genl_info *info, int attr, -+ const struct switch_port_link *link) -+{ -+ struct nlattr *p = NULL; -+ int err = 0; -+ -+ p = nla_nest_start(msg, attr); -+ if (link->link) { -+ if (nla_put_flag(msg, SWITCH_LINK_FLAG_LINK)) -+ goto nla_put_failure; -+ } -+ if (link->duplex) { -+ if (nla_put_flag(msg, SWITCH_LINK_FLAG_DUPLEX)) -+ goto nla_put_failure; -+ } -+ if (link->aneg) { -+ if (nla_put_flag(msg, SWITCH_LINK_FLAG_ANEG)) -+ goto nla_put_failure; -+ } -+ if (link->tx_flow) { -+ if (nla_put_flag(msg, SWITCH_LINK_FLAG_TX_FLOW)) -+ goto nla_put_failure; -+ } -+ if (link->rx_flow) { -+ if (nla_put_flag(msg, SWITCH_LINK_FLAG_RX_FLOW)) -+ goto nla_put_failure; -+ } -+ if (nla_put_u32(msg, SWITCH_LINK_SPEED, link->speed)) -+ goto nla_put_failure; -+ if (link->eee & ADVERTISED_100baseT_Full) { -+ if (nla_put_flag(msg, SWITCH_LINK_FLAG_EEE_100BASET)) -+ goto nla_put_failure; -+ } -+ if (link->eee & ADVERTISED_1000baseT_Full) { -+ if (nla_put_flag(msg, SWITCH_LINK_FLAG_EEE_1000BASET)) -+ goto nla_put_failure; -+ } -+ nla_nest_end(msg, p); -+ -+ return err; -+ -+nla_put_failure: -+ nla_nest_cancel(msg, p); -+ return -1; -+} -+ -+static int -+swconfig_get_attr(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct genlmsghdr *hdr = nlmsg_data(info->nlhdr); -+ const struct switch_attr *attr; -+ struct switch_dev *dev; -+ struct sk_buff *msg = NULL; -+ struct switch_val val; -+ int err = -EINVAL; -+ int cmd = hdr->cmd; -+ -+ dev = swconfig_get_dev(info); -+ if (!dev) -+ return -EINVAL; -+ -+ memset(&val, 0, sizeof(val)); -+ attr = swconfig_lookup_attr(dev, info, &val); -+ if (!attr || !attr->get) -+ goto error; -+ -+ if (attr->type == SWITCH_TYPE_PORTS) { -+ val.value.ports = dev->portbuf; -+ memset(dev->portbuf, 0, -+ sizeof(struct switch_port) * dev->ports); -+ } else if (attr->type == SWITCH_TYPE_LINK) { -+ val.value.link = &dev->linkbuf; -+ memset(&dev->linkbuf, 0, sizeof(struct switch_port_link)); -+ } -+ -+ err = attr->get(dev, attr, &val); -+ if (err) -+ goto error; -+ -+ msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); -+ if (!msg) -+ goto error; -+ -+ hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq, &switch_fam, -+ 0, cmd); -+ if (IS_ERR(hdr)) -+ goto nla_put_failure; -+ -+ switch (attr->type) { -+ case SWITCH_TYPE_INT: -+ if (nla_put_u32(msg, SWITCH_ATTR_OP_VALUE_INT, val.value.i)) -+ goto nla_put_failure; -+ break; -+ case SWITCH_TYPE_STRING: -+ if (nla_put_string(msg, SWITCH_ATTR_OP_VALUE_STR, val.value.s)) -+ goto nla_put_failure; -+ break; -+ case SWITCH_TYPE_PORTS: -+ err = swconfig_send_ports(&msg, info, -+ SWITCH_ATTR_OP_VALUE_PORTS, &val); -+ if (err < 0) -+ goto nla_put_failure; -+ break; -+ case SWITCH_TYPE_LINK: -+ err = swconfig_send_link(msg, info, -+ SWITCH_ATTR_OP_VALUE_LINK, val.value.link); -+ if (err < 0) -+ goto nla_put_failure; -+ break; -+ default: -+ pr_debug("invalid type in attribute\n"); -+ err = -EINVAL; -+ goto nla_put_failure; -+ } -+ genlmsg_end(msg, hdr); -+ err = msg->len; -+ if (err < 0) -+ goto nla_put_failure; -+ -+ swconfig_put_dev(dev); -+ return genlmsg_reply(msg, info); -+ -+nla_put_failure: -+ if (msg) -+ nlmsg_free(msg); -+error: -+ swconfig_put_dev(dev); -+ if (!err) -+ err = -ENOMEM; -+ return err; -+} -+ -+static int -+swconfig_send_switch(struct sk_buff *msg, u32 pid, u32 seq, int flags, -+ const struct switch_dev *dev) -+{ -+ struct nlattr *p = NULL, *m = NULL; -+ void *hdr; -+ int i; -+ -+ hdr = genlmsg_put(msg, pid, seq, &switch_fam, flags, -+ SWITCH_CMD_NEW_ATTR); -+ if (IS_ERR(hdr)) -+ return -1; -+ -+ if (nla_put_u32(msg, SWITCH_ATTR_ID, dev->id)) -+ goto nla_put_failure; -+ if (nla_put_string(msg, SWITCH_ATTR_DEV_NAME, dev->devname)) -+ goto nla_put_failure; -+ if (nla_put_string(msg, SWITCH_ATTR_ALIAS, dev->alias)) -+ goto nla_put_failure; -+ if (nla_put_string(msg, SWITCH_ATTR_NAME, dev->name)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, SWITCH_ATTR_VLANS, dev->vlans)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, SWITCH_ATTR_PORTS, dev->ports)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, SWITCH_ATTR_CPU_PORT, dev->cpu_port)) -+ goto nla_put_failure; -+ -+ m = nla_nest_start(msg, SWITCH_ATTR_PORTMAP); -+ if (!m) -+ goto nla_put_failure; -+ for (i = 0; i < dev->ports; i++) { -+ p = nla_nest_start(msg, SWITCH_ATTR_PORTS); -+ if (!p) -+ continue; -+ if (dev->portmap[i].s) { -+ if (nla_put_string(msg, SWITCH_PORTMAP_SEGMENT, -+ dev->portmap[i].s)) -+ goto nla_put_failure; -+ if (nla_put_u32(msg, SWITCH_PORTMAP_VIRT, -+ dev->portmap[i].virt)) -+ goto nla_put_failure; -+ } -+ nla_nest_end(msg, p); -+ } -+ nla_nest_end(msg, m); -+ genlmsg_end(msg, hdr); -+ return msg->len; -+nla_put_failure: -+ genlmsg_cancel(msg, hdr); -+ return -EMSGSIZE; -+} -+ -+static int swconfig_dump_switches(struct sk_buff *skb, -+ struct netlink_callback *cb) -+{ -+ struct switch_dev *dev; -+ int start = cb->args[0]; -+ int idx = 0; -+ -+ swconfig_lock(); -+ list_for_each_entry(dev, &swdevs, dev_list) { -+ if (++idx <= start) -+ continue; -+ if (swconfig_send_switch(skb, NETLINK_CB(cb->skb).portid, -+ cb->nlh->nlmsg_seq, NLM_F_MULTI, -+ dev) < 0) -+ break; -+ } -+ swconfig_unlock(); -+ cb->args[0] = idx; -+ -+ return skb->len; -+} -+ -+static int -+swconfig_done(struct netlink_callback *cb) -+{ -+ return 0; -+} -+ -+static struct genl_ops swconfig_ops[] = { -+ { -+ .cmd = SWITCH_CMD_LIST_GLOBAL, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = swconfig_list_attrs, -+ }, -+ { -+ .cmd = SWITCH_CMD_LIST_VLAN, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = swconfig_list_attrs, -+ }, -+ { -+ .cmd = SWITCH_CMD_LIST_PORT, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = swconfig_list_attrs, -+ }, -+ { -+ .cmd = SWITCH_CMD_GET_GLOBAL, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = swconfig_get_attr, -+ }, -+ { -+ .cmd = SWITCH_CMD_GET_VLAN, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = swconfig_get_attr, -+ }, -+ { -+ .cmd = SWITCH_CMD_GET_PORT, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = swconfig_get_attr, -+ }, -+ { -+ .cmd = SWITCH_CMD_SET_GLOBAL, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .flags = GENL_ADMIN_PERM, -+ .doit = swconfig_set_attr, -+ }, -+ { -+ .cmd = SWITCH_CMD_SET_VLAN, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .flags = GENL_ADMIN_PERM, -+ .doit = swconfig_set_attr, -+ }, -+ { -+ .cmd = SWITCH_CMD_SET_PORT, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .flags = GENL_ADMIN_PERM, -+ .doit = swconfig_set_attr, -+ }, -+ { -+ .cmd = SWITCH_CMD_GET_SWITCH, -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .dumpit = swconfig_dump_switches, -+ .done = swconfig_done, -+ } -+}; -+ -+static struct genl_family switch_fam = { -+ .name = "switch", -+ .hdrsize = 0, -+ .version = 1, -+ .maxattr = SWITCH_ATTR_MAX, -+ .policy = switch_policy, -+ .module = THIS_MODULE, -+ .ops = swconfig_ops, -+ .n_ops = ARRAY_SIZE(swconfig_ops), -+ .resv_start_op = SWITCH_CMD_SET_VLAN + 1, -+}; -+ -+#ifdef CONFIG_OF -+static void -+of_switch_load_portmap(struct switch_dev *dev) -+{ -+ struct device_node *port; -+ -+ if (!dev->of_node) -+ return; -+ -+ for_each_child_of_node(dev->of_node, port) { -+ const __be32 *prop; -+ const char *segment; -+ int size, phys; -+ -+ if (!of_device_is_compatible(port, "swconfig,port")) -+ continue; -+ -+ if (of_property_read_string(port, "swconfig,segment", &segment)) -+ continue; -+ -+ prop = of_get_property(port, "swconfig,portmap", &size); -+ if (!prop) -+ continue; -+ -+ if (size != (2 * sizeof(*prop))) { -+ pr_err("%s: failed to parse port mapping\n", -+ port->name); -+ continue; -+ } -+ -+ phys = be32_to_cpup(prop++); -+ if ((phys < 0) | (phys >= dev->ports)) { -+ pr_err("%s: physical port index out of range\n", -+ port->name); -+ continue; -+ } -+ -+ dev->portmap[phys].s = kstrdup(segment, GFP_KERNEL); -+ dev->portmap[phys].virt = be32_to_cpup(prop); -+ pr_debug("Found port: %s, physical: %d, virtual: %d\n", -+ segment, phys, dev->portmap[phys].virt); -+ } -+} -+#endif -+ -+int -+register_switch(struct switch_dev *dev, struct net_device *netdev) -+{ -+ struct switch_dev *sdev; -+ const int max_switches = 8 * sizeof(unsigned long); -+ unsigned long in_use = 0; -+ int err; -+ int i; -+ -+ INIT_LIST_HEAD(&dev->dev_list); -+ if (netdev) { -+ dev->netdev = netdev; -+ if (!dev->alias) -+ dev->alias = netdev->name; -+ } -+ BUG_ON(!dev->alias); -+ -+ /* Make sure swdev_id doesn't overflow */ -+ if (swdev_id == INT_MAX) { -+ return -ENOMEM; -+ } -+ -+ if (dev->ports > 0) { -+ dev->portbuf = kzalloc(sizeof(struct switch_port) * -+ dev->ports, GFP_KERNEL); -+ if (!dev->portbuf) -+ return -ENOMEM; -+ dev->portmap = kzalloc(sizeof(struct switch_portmap) * -+ dev->ports, GFP_KERNEL); -+ if (!dev->portmap) { -+ kfree(dev->portbuf); -+ return -ENOMEM; -+ } -+ } -+ swconfig_defaults_init(dev); -+ mutex_init(&dev->sw_mutex); -+ swconfig_lock(); -+ dev->id = ++swdev_id; -+ -+ list_for_each_entry(sdev, &swdevs, dev_list) { -+ if (!sscanf(sdev->devname, SWCONFIG_DEVNAME, &i)) -+ continue; -+ if (i < 0 || i > max_switches) -+ continue; -+ -+ set_bit(i, &in_use); -+ } -+ i = find_first_zero_bit(&in_use, max_switches); -+ -+ if (i == max_switches) { -+ swconfig_unlock(); -+ return -ENFILE; -+ } -+ -+#ifdef CONFIG_OF -+ if (dev->ports) -+ of_switch_load_portmap(dev); -+#endif -+ -+ /* fill device name */ -+ snprintf(dev->devname, IFNAMSIZ, SWCONFIG_DEVNAME, i); -+ -+ list_add_tail(&dev->dev_list, &swdevs); -+ swconfig_unlock(); -+ -+ err = swconfig_create_led_trigger(dev); -+ if (err) -+ return err; -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(register_switch); -+ -+void -+unregister_switch(struct switch_dev *dev) -+{ -+ swconfig_destroy_led_trigger(dev); -+ kfree(dev->portbuf); -+ mutex_lock(&dev->sw_mutex); -+ swconfig_lock(); -+ list_del(&dev->dev_list); -+ swconfig_unlock(); -+ mutex_unlock(&dev->sw_mutex); -+} -+EXPORT_SYMBOL_GPL(unregister_switch); -+ -+int -+switch_generic_set_link(struct switch_dev *dev, int port, -+ struct switch_port_link *link) -+{ -+ if (WARN_ON(!dev->ops->phy_write16)) -+ return -ENOTSUPP; -+ -+ /* Generic implementation */ -+ if (link->aneg) { -+ dev->ops->phy_write16(dev, port, MII_BMCR, 0x0000); -+ dev->ops->phy_write16(dev, port, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART); -+ } else { -+ u16 bmcr = 0; -+ -+ if (link->duplex) -+ bmcr |= BMCR_FULLDPLX; -+ -+ switch (link->speed) { -+ case SWITCH_PORT_SPEED_10: -+ break; -+ case SWITCH_PORT_SPEED_100: -+ bmcr |= BMCR_SPEED100; -+ break; -+ case SWITCH_PORT_SPEED_1000: -+ bmcr |= BMCR_SPEED1000; -+ break; -+ default: -+ return -ENOTSUPP; -+ } -+ -+ dev->ops->phy_write16(dev, port, MII_BMCR, bmcr); -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(switch_generic_set_link); -+ -+static int __init -+swconfig_init(void) -+{ -+ INIT_LIST_HEAD(&swdevs); -+ -+ return genl_register_family(&switch_fam); -+} -+ -+static void __exit -+swconfig_exit(void) -+{ -+ genl_unregister_family(&switch_fam); -+} -+ -+module_init(swconfig_init); -+module_exit(swconfig_exit); -diff --git a/drivers/net/phy/swconfig_leds.c b/drivers/net/phy/swconfig_leds.c -new file mode 100644 -index 000000000000..1fcd4432b54e ---- /dev/null -+++ b/drivers/net/phy/swconfig_leds.c -@@ -0,0 +1,555 @@ -+/* -+ * swconfig_led.c: LED trigger support for the switch configuration API -+ * -+ * Copyright (C) 2011 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ */ -+ -+#ifdef CONFIG_SWCONFIG_LEDS -+ -+#include -+#include -+#include -+#include -+ -+#define SWCONFIG_LED_TIMER_INTERVAL (HZ / 10) -+#define SWCONFIG_LED_NUM_PORTS 32 -+ -+#define SWCONFIG_LED_PORT_SPEED_NA 0x01 /* unknown speed */ -+#define SWCONFIG_LED_PORT_SPEED_10 0x02 /* 10 Mbps */ -+#define SWCONFIG_LED_PORT_SPEED_100 0x04 /* 100 Mbps */ -+#define SWCONFIG_LED_PORT_SPEED_1000 0x08 /* 1000 Mbps */ -+#define SWCONFIG_LED_PORT_SPEED_ALL (SWCONFIG_LED_PORT_SPEED_NA | \ -+ SWCONFIG_LED_PORT_SPEED_10 | \ -+ SWCONFIG_LED_PORT_SPEED_100 | \ -+ SWCONFIG_LED_PORT_SPEED_1000) -+ -+#define SWCONFIG_LED_MODE_LINK 0x01 -+#define SWCONFIG_LED_MODE_TX 0x02 -+#define SWCONFIG_LED_MODE_RX 0x04 -+#define SWCONFIG_LED_MODE_TXRX (SWCONFIG_LED_MODE_TX | \ -+ SWCONFIG_LED_MODE_RX) -+#define SWCONFIG_LED_MODE_ALL (SWCONFIG_LED_MODE_LINK | \ -+ SWCONFIG_LED_MODE_TX | \ -+ SWCONFIG_LED_MODE_RX) -+ -+struct switch_led_trigger { -+ struct led_trigger trig; -+ struct switch_dev *swdev; -+ -+ struct delayed_work sw_led_work; -+ u32 port_mask; -+ u32 port_link; -+ unsigned long long port_tx_traffic[SWCONFIG_LED_NUM_PORTS]; -+ unsigned long long port_rx_traffic[SWCONFIG_LED_NUM_PORTS]; -+ u8 link_speed[SWCONFIG_LED_NUM_PORTS]; -+}; -+ -+struct swconfig_trig_data { -+ struct led_classdev *led_cdev; -+ struct switch_dev *swdev; -+ -+ rwlock_t lock; -+ u32 port_mask; -+ -+ bool prev_link; -+ unsigned long prev_traffic; -+ enum led_brightness prev_brightness; -+ u8 mode; -+ u8 speed_mask; -+}; -+ -+static void -+swconfig_trig_set_brightness(struct swconfig_trig_data *trig_data, -+ enum led_brightness brightness) -+{ -+ led_set_brightness(trig_data->led_cdev, brightness); -+ trig_data->prev_brightness = brightness; -+} -+ -+static void -+swconfig_trig_update_port_mask(struct led_trigger *trigger) -+{ -+ struct list_head *entry; -+ struct switch_led_trigger *sw_trig; -+ u32 port_mask; -+ -+ if (!trigger) -+ return; -+ -+ sw_trig = (void *) trigger; -+ -+ port_mask = 0; -+ spin_lock(&trigger->leddev_list_lock); -+ list_for_each(entry, &trigger->led_cdevs) { -+ struct led_classdev *led_cdev; -+ struct swconfig_trig_data *trig_data; -+ -+ led_cdev = list_entry(entry, struct led_classdev, trig_list); -+ trig_data = led_cdev->trigger_data; -+ if (trig_data) { -+ read_lock(&trig_data->lock); -+ port_mask |= trig_data->port_mask; -+ read_unlock(&trig_data->lock); -+ } -+ } -+ spin_unlock(&trigger->leddev_list_lock); -+ -+ sw_trig->port_mask = port_mask; -+ -+ if (port_mask) -+ schedule_delayed_work(&sw_trig->sw_led_work, -+ SWCONFIG_LED_TIMER_INTERVAL); -+ else -+ cancel_delayed_work_sync(&sw_trig->sw_led_work); -+} -+ -+static ssize_t -+swconfig_trig_port_mask_store(struct device *dev, struct device_attribute *attr, -+ const char *buf, size_t size) -+{ -+ struct led_classdev *led_cdev = dev_get_drvdata(dev); -+ struct swconfig_trig_data *trig_data = led_cdev->trigger_data; -+ unsigned long port_mask; -+ int ret; -+ bool changed; -+ -+ ret = kstrtoul(buf, 0, &port_mask); -+ if (ret) -+ return ret; -+ -+ write_lock(&trig_data->lock); -+ changed = (trig_data->port_mask != port_mask); -+ trig_data->port_mask = port_mask; -+ write_unlock(&trig_data->lock); -+ -+ if (changed) { -+ if (port_mask == 0) -+ swconfig_trig_set_brightness(trig_data, LED_OFF); -+ -+ swconfig_trig_update_port_mask(led_cdev->trigger); -+ } -+ -+ return size; -+} -+ -+static ssize_t -+swconfig_trig_port_mask_show(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ struct led_classdev *led_cdev = dev_get_drvdata(dev); -+ struct swconfig_trig_data *trig_data = led_cdev->trigger_data; -+ u32 port_mask; -+ -+ read_lock(&trig_data->lock); -+ port_mask = trig_data->port_mask; -+ read_unlock(&trig_data->lock); -+ -+ sprintf(buf, "%#x\n", port_mask); -+ -+ return strlen(buf) + 1; -+} -+ -+static DEVICE_ATTR(port_mask, 0644, swconfig_trig_port_mask_show, -+ swconfig_trig_port_mask_store); -+ -+/* speed_mask file handler - display value */ -+static ssize_t swconfig_trig_speed_mask_show(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct led_classdev *led_cdev = dev_get_drvdata(dev); -+ struct swconfig_trig_data *trig_data = led_cdev->trigger_data; -+ u8 speed_mask; -+ -+ read_lock(&trig_data->lock); -+ speed_mask = trig_data->speed_mask; -+ read_unlock(&trig_data->lock); -+ -+ sprintf(buf, "%#x\n", speed_mask); -+ -+ return strlen(buf) + 1; -+} -+ -+/* speed_mask file handler - store value */ -+static ssize_t swconfig_trig_speed_mask_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t size) -+{ -+ struct led_classdev *led_cdev = dev_get_drvdata(dev); -+ struct swconfig_trig_data *trig_data = led_cdev->trigger_data; -+ u8 speed_mask; -+ int ret; -+ -+ ret = kstrtou8(buf, 0, &speed_mask); -+ if (ret) -+ return ret; -+ -+ write_lock(&trig_data->lock); -+ trig_data->speed_mask = speed_mask & SWCONFIG_LED_PORT_SPEED_ALL; -+ write_unlock(&trig_data->lock); -+ -+ return size; -+} -+ -+/* speed_mask special file */ -+static DEVICE_ATTR(speed_mask, 0644, swconfig_trig_speed_mask_show, -+ swconfig_trig_speed_mask_store); -+ -+static ssize_t swconfig_trig_mode_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct led_classdev *led_cdev = dev_get_drvdata(dev); -+ struct swconfig_trig_data *trig_data = led_cdev->trigger_data; -+ u8 mode; -+ -+ read_lock(&trig_data->lock); -+ mode = trig_data->mode; -+ read_unlock(&trig_data->lock); -+ -+ if (mode == 0) { -+ strcpy(buf, "none\n"); -+ } else { -+ if (mode & SWCONFIG_LED_MODE_LINK) -+ strcat(buf, "link "); -+ if (mode & SWCONFIG_LED_MODE_TX) -+ strcat(buf, "tx "); -+ if (mode & SWCONFIG_LED_MODE_RX) -+ strcat(buf, "rx "); -+ strcat(buf, "\n"); -+ } -+ -+ return strlen(buf)+1; -+} -+ -+static ssize_t swconfig_trig_mode_store(struct device *dev, -+ struct device_attribute *attr, const char *buf, size_t size) -+{ -+ struct led_classdev *led_cdev = dev_get_drvdata(dev); -+ struct swconfig_trig_data *trig_data = led_cdev->trigger_data; -+ char copybuf[128]; -+ int new_mode = -1; -+ char *p, *token; -+ -+ /* take a copy since we don't want to trash the inbound buffer when using strsep */ -+ strncpy(copybuf, buf, sizeof(copybuf)); -+ copybuf[sizeof(copybuf) - 1] = 0; -+ p = copybuf; -+ -+ while ((token = strsep(&p, " \t\n")) != NULL) { -+ if (!*token) -+ continue; -+ -+ if (new_mode < 0) -+ new_mode = 0; -+ -+ if (!strcmp(token, "none")) -+ new_mode = 0; -+ else if (!strcmp(token, "tx")) -+ new_mode |= SWCONFIG_LED_MODE_TX; -+ else if (!strcmp(token, "rx")) -+ new_mode |= SWCONFIG_LED_MODE_RX; -+ else if (!strcmp(token, "link")) -+ new_mode |= SWCONFIG_LED_MODE_LINK; -+ else -+ return -EINVAL; -+ } -+ -+ if (new_mode < 0) -+ return -EINVAL; -+ -+ write_lock(&trig_data->lock); -+ trig_data->mode = (u8)new_mode; -+ write_unlock(&trig_data->lock); -+ -+ return size; -+} -+ -+/* mode special file */ -+static DEVICE_ATTR(mode, 0644, swconfig_trig_mode_show, -+ swconfig_trig_mode_store); -+ -+static int -+swconfig_trig_activate(struct led_classdev *led_cdev) -+{ -+ struct switch_led_trigger *sw_trig; -+ struct swconfig_trig_data *trig_data; -+ int err; -+ -+ trig_data = kzalloc(sizeof(struct swconfig_trig_data), GFP_KERNEL); -+ if (!trig_data) -+ return -ENOMEM; -+ -+ sw_trig = (void *) led_cdev->trigger; -+ -+ rwlock_init(&trig_data->lock); -+ trig_data->led_cdev = led_cdev; -+ trig_data->swdev = sw_trig->swdev; -+ trig_data->speed_mask = SWCONFIG_LED_PORT_SPEED_ALL; -+ trig_data->mode = SWCONFIG_LED_MODE_ALL; -+ led_cdev->trigger_data = trig_data; -+ -+ err = device_create_file(led_cdev->dev, &dev_attr_port_mask); -+ if (err) -+ goto err_free; -+ -+ err = device_create_file(led_cdev->dev, &dev_attr_speed_mask); -+ if (err) -+ goto err_dev_free; -+ -+ err = device_create_file(led_cdev->dev, &dev_attr_mode); -+ if (err) -+ goto err_mode_free; -+ -+ return 0; -+ -+err_mode_free: -+ device_remove_file(led_cdev->dev, &dev_attr_speed_mask); -+ -+err_dev_free: -+ device_remove_file(led_cdev->dev, &dev_attr_port_mask); -+ -+err_free: -+ led_cdev->trigger_data = NULL; -+ kfree(trig_data); -+ -+ return err; -+} -+ -+static void -+swconfig_trig_deactivate(struct led_classdev *led_cdev) -+{ -+ struct swconfig_trig_data *trig_data; -+ -+ swconfig_trig_update_port_mask(led_cdev->trigger); -+ -+ trig_data = (void *) led_cdev->trigger_data; -+ if (trig_data) { -+ device_remove_file(led_cdev->dev, &dev_attr_port_mask); -+ device_remove_file(led_cdev->dev, &dev_attr_speed_mask); -+ device_remove_file(led_cdev->dev, &dev_attr_mode); -+ kfree(trig_data); -+ } -+} -+ -+/* -+ * link off -> led off (can't be any other reason to turn it on) -+ * link on: -+ * mode link: led on by default only if speed matches, else off -+ * mode txrx: blink only if speed matches, else off -+ */ -+static void -+swconfig_trig_led_event(struct switch_led_trigger *sw_trig, -+ struct led_classdev *led_cdev) -+{ -+ struct swconfig_trig_data *trig_data; -+ u32 port_mask; -+ bool link; -+ u8 speed_mask, mode; -+ enum led_brightness led_base, led_blink; -+ -+ trig_data = led_cdev->trigger_data; -+ if (!trig_data) -+ return; -+ -+ read_lock(&trig_data->lock); -+ port_mask = trig_data->port_mask; -+ speed_mask = trig_data->speed_mask; -+ mode = trig_data->mode; -+ read_unlock(&trig_data->lock); -+ -+ link = !!(sw_trig->port_link & port_mask); -+ if (!link) { -+ if (trig_data->prev_brightness != LED_OFF) -+ swconfig_trig_set_brightness(trig_data, LED_OFF); /* and stop */ -+ } -+ else { -+ unsigned long traffic; -+ int speedok; /* link speed flag */ -+ int i; -+ -+ led_base = LED_FULL; -+ led_blink = LED_OFF; -+ traffic = 0; -+ speedok = 0; -+ for (i = 0; i < SWCONFIG_LED_NUM_PORTS; i++) { -+ if (port_mask & (1 << i)) { -+ if (sw_trig->link_speed[i] & speed_mask) { -+ traffic += ((mode & SWCONFIG_LED_MODE_TX) ? -+ sw_trig->port_tx_traffic[i] : 0) + -+ ((mode & SWCONFIG_LED_MODE_RX) ? -+ sw_trig->port_rx_traffic[i] : 0); -+ speedok = 1; -+ } -+ } -+ } -+ -+ if (speedok) { -+ /* At least one port speed matches speed_mask */ -+ if (!(mode & SWCONFIG_LED_MODE_LINK)) { -+ led_base = LED_OFF; -+ led_blink = LED_FULL; -+ } -+ -+ if (trig_data->prev_brightness != led_base) -+ swconfig_trig_set_brightness(trig_data, -+ led_base); -+ else if (traffic != trig_data->prev_traffic) -+ swconfig_trig_set_brightness(trig_data, -+ led_blink); -+ } else if (trig_data->prev_brightness != LED_OFF) -+ swconfig_trig_set_brightness(trig_data, LED_OFF); -+ -+ trig_data->prev_traffic = traffic; -+ } -+ -+ trig_data->prev_link = link; -+} -+ -+static void -+swconfig_trig_update_leds(struct switch_led_trigger *sw_trig) -+{ -+ struct list_head *entry; -+ struct led_trigger *trigger; -+ -+ trigger = &sw_trig->trig; -+ spin_lock(&trigger->leddev_list_lock); -+ list_for_each(entry, &trigger->led_cdevs) { -+ struct led_classdev *led_cdev; -+ -+ led_cdev = list_entry(entry, struct led_classdev, trig_list); -+ swconfig_trig_led_event(sw_trig, led_cdev); -+ } -+ spin_unlock(&trigger->leddev_list_lock); -+} -+ -+static void -+swconfig_led_work_func(struct work_struct *work) -+{ -+ struct switch_led_trigger *sw_trig; -+ struct switch_dev *swdev; -+ u32 port_mask; -+ u32 link; -+ int i; -+ -+ sw_trig = container_of(work, struct switch_led_trigger, -+ sw_led_work.work); -+ -+ port_mask = sw_trig->port_mask; -+ swdev = sw_trig->swdev; -+ -+ link = 0; -+ for (i = 0; i < SWCONFIG_LED_NUM_PORTS; i++) { -+ u32 port_bit; -+ -+ sw_trig->link_speed[i] = 0; -+ -+ port_bit = BIT(i); -+ if ((port_mask & port_bit) == 0) -+ continue; -+ -+ if (swdev->ops->get_port_link) { -+ struct switch_port_link port_link; -+ -+ memset(&port_link, '\0', sizeof(port_link)); -+ swdev->ops->get_port_link(swdev, i, &port_link); -+ -+ if (port_link.link) { -+ link |= port_bit; -+ switch (port_link.speed) { -+ case SWITCH_PORT_SPEED_UNKNOWN: -+ sw_trig->link_speed[i] = -+ SWCONFIG_LED_PORT_SPEED_NA; -+ break; -+ case SWITCH_PORT_SPEED_10: -+ sw_trig->link_speed[i] = -+ SWCONFIG_LED_PORT_SPEED_10; -+ break; -+ case SWITCH_PORT_SPEED_100: -+ sw_trig->link_speed[i] = -+ SWCONFIG_LED_PORT_SPEED_100; -+ break; -+ case SWITCH_PORT_SPEED_1000: -+ sw_trig->link_speed[i] = -+ SWCONFIG_LED_PORT_SPEED_1000; -+ break; -+ } -+ } -+ } -+ -+ if (swdev->ops->get_port_stats) { -+ struct switch_port_stats port_stats; -+ -+ memset(&port_stats, '\0', sizeof(port_stats)); -+ swdev->ops->get_port_stats(swdev, i, &port_stats); -+ sw_trig->port_tx_traffic[i] = port_stats.tx_bytes; -+ sw_trig->port_rx_traffic[i] = port_stats.rx_bytes; -+ } -+ } -+ -+ sw_trig->port_link = link; -+ -+ swconfig_trig_update_leds(sw_trig); -+ -+ schedule_delayed_work(&sw_trig->sw_led_work, -+ SWCONFIG_LED_TIMER_INTERVAL); -+} -+ -+static int -+swconfig_create_led_trigger(struct switch_dev *swdev) -+{ -+ struct switch_led_trigger *sw_trig; -+ int err; -+ -+ if (!swdev->ops->get_port_link) -+ return 0; -+ -+ sw_trig = kzalloc(sizeof(struct switch_led_trigger), GFP_KERNEL); -+ if (!sw_trig) -+ return -ENOMEM; -+ -+ sw_trig->swdev = swdev; -+ sw_trig->trig.name = swdev->devname; -+ sw_trig->trig.activate = swconfig_trig_activate; -+ sw_trig->trig.deactivate = swconfig_trig_deactivate; -+ -+ INIT_DELAYED_WORK(&sw_trig->sw_led_work, swconfig_led_work_func); -+ -+ err = led_trigger_register(&sw_trig->trig); -+ if (err) -+ goto err_free; -+ -+ swdev->led_trigger = sw_trig; -+ -+ return 0; -+ -+err_free: -+ kfree(sw_trig); -+ return err; -+} -+ -+static void -+swconfig_destroy_led_trigger(struct switch_dev *swdev) -+{ -+ struct switch_led_trigger *sw_trig; -+ -+ sw_trig = swdev->led_trigger; -+ if (sw_trig) { -+ cancel_delayed_work_sync(&sw_trig->sw_led_work); -+ led_trigger_unregister(&sw_trig->trig); -+ kfree(sw_trig); -+ } -+} -+ -+#else /* SWCONFIG_LEDS */ -+static inline int -+swconfig_create_led_trigger(struct switch_dev *swdev) { return 0; } -+ -+static inline void -+swconfig_destroy_led_trigger(struct switch_dev *swdev) { } -+#endif /* CONFIG_SWCONFIG_LEDS */ -diff --git a/drivers/nvmem/an8855-efuse.c b/drivers/nvmem/an8855-efuse.c -new file mode 100644 -index 000000000000..7940453d6e58 ---- /dev/null -+++ b/drivers/nvmem/an8855-efuse.c -@@ -0,0 +1,63 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Airoha AN8855 Switch EFUSE Driver -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define AN8855_EFUSE_CELL 50 -+ -+#define AN8855_EFUSE_DATA0 0x1000a500 -+#define AN8855_EFUSE_R50O GENMASK(30, 24) -+ -+static int an8855_efuse_read(void *context, unsigned int offset, -+ void *val, size_t bytes) -+{ -+ struct regmap *regmap = context; -+ -+ return regmap_bulk_read(regmap, AN8855_EFUSE_DATA0 + offset, -+ val, bytes / sizeof(u32)); -+} -+ -+static int an8855_efuse_probe(struct platform_device *pdev) -+{ -+ struct nvmem_config an8855_nvmem_config = { -+ .name = "an8855-efuse", -+ .size = AN8855_EFUSE_CELL * sizeof(u32), -+ .stride = sizeof(u32), -+ .word_size = sizeof(u32), -+ .reg_read = an8855_efuse_read, -+ }; -+ struct device *dev = &pdev->dev; -+ struct nvmem_device *nvmem; -+ -+ /* Assign NVMEM priv to MFD regmap */ -+ an8855_nvmem_config.priv = dev_get_regmap(dev->parent, NULL); -+ an8855_nvmem_config.dev = dev; -+ nvmem = devm_nvmem_register(dev, &an8855_nvmem_config); -+ -+ return PTR_ERR_OR_ZERO(nvmem); -+} -+ -+static const struct of_device_id an8855_efuse_of_match[] = { -+ { .compatible = "airoha,an8855-efuse", }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, an8855_efuse_of_match); -+ -+static struct platform_driver an8855_efuse_driver = { -+ .probe = an8855_efuse_probe, -+ .driver = { -+ .name = "an8855-efuse", -+ .of_match_table = an8855_efuse_of_match, -+ }, -+}; -+module_platform_driver(an8855_efuse_driver); -+ -+MODULE_AUTHOR("Christian Marangi "); -+MODULE_DESCRIPTION("Driver for AN8855 Switch EFUSE"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/platform/mikrotik/Kconfig b/drivers/platform/mikrotik/Kconfig -new file mode 100644 -index 000000000000..85fe7b20503c ---- /dev/null -+++ b/drivers/platform/mikrotik/Kconfig -@@ -0,0 +1,31 @@ -+menuconfig MIKROTIK -+ bool "Platform support for MikroTik RouterBoard virtual devices" -+ help -+ Say Y here to get to see options for the MikroTik RouterBoard platform. -+ This option alone does not add any kernel code. -+ -+ -+if MIKROTIK -+ -+config MIKROTIK_RB_SYSFS -+ tristate "RouterBoot sysfs support" -+ depends on MTD -+ select LZO_DECOMPRESS -+ select CRC32 -+ help -+ This driver exposes RouterBoot configuration in sysfs. -+ -+config NVMEM_LAYOUT_MIKROTIK -+ tristate "RouterBoot NVMEM layout support" -+ depends on NVMEM_LAYOUTS -+ help -+ This driver exposes MikroTik hard_config via NVMEM layout. -+ -+config MIKROTIK_WLAN_DECOMPRESS_LZ77 -+ tristate "Mikrotik factory Wi-Fi caldata LZ77 decompression support" -+ depends on MIKROTIK_RB_SYSFS -+ help -+ Allow Mikrotik LZ77 factory flashed Wi-Fi calibration data to be -+ decompressed -+ -+endif # MIKROTIK -diff --git a/drivers/platform/mikrotik/Makefile b/drivers/platform/mikrotik/Makefile -new file mode 100644 -index 000000000000..9ffb355c1e3d ---- /dev/null -+++ b/drivers/platform/mikrotik/Makefile -@@ -0,0 +1,6 @@ -+# -+# Makefile for MikroTik RouterBoard platform specific drivers -+# -+obj-$(CONFIG_MIKROTIK_RB_SYSFS) += routerboot.o rb_hardconfig.o rb_softconfig.o -+obj-$(CONFIG_NVMEM_LAYOUT_MIKROTIK) += rb_nvmem.o -+obj-$(CONFIG_MIKROTIK_WLAN_DECOMPRESS_LZ77) += rb_lz77.o -diff --git a/drivers/platform/mikrotik/rb_hardconfig.c b/drivers/platform/mikrotik/rb_hardconfig.c -new file mode 100644 -index 000000000000..4c1edad08178 ---- /dev/null -+++ b/drivers/platform/mikrotik/rb_hardconfig.c -@@ -0,0 +1,844 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Driver for MikroTik RouterBoot hard config. -+ * -+ * Copyright (C) 2020 Thibaut VARÈNE -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ * This driver exposes the data encoded in the "hard_config" flash segment of -+ * MikroTik RouterBOARDs devices. It presents the data in a sysfs folder -+ * named "hard_config". The WLAN calibration data is available on demand via -+ * the 'wlan_data' sysfs file in that folder. -+ * -+ * This driver permanently allocates a chunk of RAM as large as the hard_config -+ * MTD partition, although it is technically possible to operate entirely from -+ * the MTD device without using a local buffer (except when requesting WLAN -+ * calibration data), at the cost of a performance penalty. -+ * -+ * Note: PAGE_SIZE is assumed to be >= 4K, hence the device attribute show -+ * routines need not check for output overflow. -+ * -+ * Some constant defines extracted from routerboot.{c,h} by Gabor Juhos -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "rb_hardconfig.h" -+#include "routerboot.h" -+#include "rb_lz77.h" -+ -+#define RB_HARDCONFIG_VER "0.08" -+#define RB_HC_PR_PFX "[rb_hardconfig] " -+ -+/* Bit definitions for hardware options */ -+#define RB_HW_OPT_NO_UART BIT(0) -+#define RB_HW_OPT_HAS_VOLTAGE BIT(1) -+#define RB_HW_OPT_HAS_USB BIT(2) -+#define RB_HW_OPT_HAS_ATTINY BIT(3) -+#define RB_HW_OPT_PULSE_DUTY_CYCLE BIT(9) -+#define RB_HW_OPT_NO_NAND BIT(14) -+#define RB_HW_OPT_HAS_LCD BIT(15) -+#define RB_HW_OPT_HAS_POE_OUT BIT(16) -+#define RB_HW_OPT_HAS_uSD BIT(17) -+#define RB_HW_OPT_HAS_SIM BIT(18) -+#define RB_HW_OPT_HAS_SFP BIT(20) -+#define RB_HW_OPT_HAS_WIFI BIT(21) -+#define RB_HW_OPT_HAS_TS_FOR_ADC BIT(22) -+#define RB_HW_OPT_HAS_PLC BIT(29) -+ -+/* -+ * Tag ID values for ERD data. -+ * Mikrotik used to pack all calibration data under a single tag id 0x1, but -+ * recently switched to a new scheme where each radio calibration gets a -+ * separate tag. The new scheme has tag id bit 15 always set and seems to be -+ * mutually exclusive with the old scheme. -+ */ -+#define RB_WLAN_ERD_ID_SOLO 0x0001 -+#define RB_WLAN_ERD_ID_MULTI_8001 0x8001 -+#define RB_WLAN_ERD_ID_MULTI_8201 0x8201 -+ -+static struct kobject *hc_kobj; -+static u8 *hc_buf; // ro buffer after init(): no locking required -+static size_t hc_buflen; -+ -+/* -+ * For LZOR style WLAN data unpacking. -+ * This binary blob is prepended to the data encoded on some devices as -+ * RB_ID_WLAN_DATA, the result is then first decompressed with LZO, and then -+ * finally RLE-decoded. -+ * This binary blob has been extracted from RouterOS by -+ * https://forum.openwrt.org/u/ius -+ */ -+static const u8 hc_lzor_prefix[] = { -+ 0x00, 0x05, 0x4c, 0x4c, 0x44, 0x00, 0x34, 0xfe, -+ 0xfe, 0x34, 0x11, 0x3c, 0x1e, 0x3c, 0x2e, 0x3c, -+ 0x4c, 0x34, 0x00, 0x52, 0x62, 0x92, 0xa2, 0xb2, -+ 0xc3, 0x2a, 0x14, 0x00, 0x00, 0x05, 0xfe, 0x6a, -+ 0x3c, 0x16, 0x32, 0x16, 0x11, 0x1e, 0x12, 0x46, -+ 0x32, 0x46, 0x11, 0x4e, 0x12, 0x36, 0x32, 0x36, -+ 0x11, 0x3e, 0x12, 0x5a, 0x9a, 0x64, 0x00, 0x04, -+ 0xfe, 0x10, 0x3c, 0x00, 0x01, 0x00, 0x00, 0x28, -+ 0x0c, 0x00, 0x0f, 0xfe, 0x14, 0x00, 0x24, 0x24, -+ 0x23, 0x24, 0x24, 0x23, 0x25, 0x22, 0x21, 0x21, -+ 0x23, 0x22, 0x21, 0x22, 0x21, 0x2d, 0x38, 0x00, -+ 0x0c, 0x25, 0x25, 0x24, 0x25, 0x25, 0x24, 0x23, -+ 0x22, 0x21, 0x20, 0x23, 0x21, 0x21, 0x22, 0x21, -+ 0x2d, 0x38, 0x00, 0x28, 0xb0, 0x00, 0x00, 0x22, -+ 0x00, 0x00, 0xc0, 0xfe, 0x03, 0x00, 0xc0, 0x00, -+ 0x62, 0xff, 0x62, 0xff, 0xfe, 0x06, 0x00, 0xbb, -+ 0xff, 0xba, 0xff, 0xfe, 0x08, 0x00, 0x9e, 0xff, -+ 0xfe, 0x0a, 0x00, 0x53, 0xff, 0xfe, 0x02, 0x00, -+ 0x20, 0xff, 0xb1, 0xfe, 0xfe, 0xb2, 0xfe, 0xfe, -+ 0xed, 0xfe, 0xfe, 0xfe, 0x04, 0x00, 0x3a, 0xff, -+ 0x3a, 0xff, 0xde, 0xfd, 0x5f, 0x04, 0x33, 0xff, -+ 0x4c, 0x74, 0x03, 0x05, 0x05, 0xff, 0x6d, 0xfe, -+ 0xfe, 0x6d, 0xfe, 0xfe, 0xaf, 0x08, 0x63, 0xff, -+ 0x64, 0x6f, 0x08, 0xac, 0xff, 0xbf, 0x6d, 0x08, -+ 0x7a, 0x6d, 0x08, 0x96, 0x74, 0x04, 0x00, 0x08, -+ 0x79, 0xff, 0xda, 0xfe, 0xfe, 0xdb, 0xfe, 0xfe, -+ 0x56, 0xff, 0xfe, 0x04, 0x00, 0x5e, 0xff, 0x5e, -+ 0xff, 0x6c, 0xfe, 0xfe, 0xfe, 0x06, 0x00, 0x41, -+ 0xff, 0x7f, 0x74, 0x03, 0x00, 0x11, 0x44, 0xff, -+ 0xa9, 0xfe, 0xfe, 0xa9, 0xfe, 0xfe, 0xa5, 0x8f, -+ 0x01, 0x00, 0x08, 0x01, 0x01, 0x02, 0x04, 0x08, -+ 0x02, 0x04, 0x08, 0x08, 0x01, 0x01, 0xfe, 0x22, -+ 0x00, 0x4c, 0x60, 0x64, 0x8c, 0x90, 0xd0, 0xd4, -+ 0xd8, 0x5c, 0x10, 0x09, 0xd8, 0xff, 0xb0, 0xff, -+ 0x00, 0x00, 0xba, 0xff, 0x14, 0x00, 0xba, 0xff, -+ 0x64, 0x00, 0x00, 0x08, 0xfe, 0x06, 0x00, 0x74, -+ 0xff, 0x42, 0xff, 0xce, 0xff, 0x60, 0xff, 0x0a, -+ 0x00, 0xb4, 0x00, 0xa0, 0x00, 0xa0, 0xfe, 0x07, -+ 0x00, 0x0a, 0x00, 0xb0, 0xff, 0x96, 0x4d, 0x00, -+ 0x56, 0x57, 0x18, 0xa6, 0xff, 0x92, 0x70, 0x11, -+ 0x00, 0x12, 0x90, 0x90, 0x76, 0x5a, 0x54, 0x54, -+ 0x4c, 0x46, 0x38, 0x00, 0x10, 0x10, 0x08, 0xfe, -+ 0x05, 0x00, 0x38, 0x29, 0x25, 0x23, 0x22, 0x22, -+ 0x1f, 0x00, 0x00, 0x00, 0xf6, 0xe1, 0xdd, 0xf8, -+ 0xfe, 0x00, 0xfe, 0x15, 0x00, 0x00, 0xd0, 0x02, -+ 0x74, 0x02, 0x08, 0xf8, 0xe5, 0xde, 0x02, 0x04, -+ 0x04, 0xfd, 0x00, 0x00, 0x00, 0x07, 0x50, 0x2d, -+ 0x01, 0x90, 0x90, 0x76, 0x60, 0xb0, 0x07, 0x07, -+ 0x0c, 0x0c, 0x04, 0xfe, 0x05, 0x00, 0x66, 0x66, -+ 0x5a, 0x56, 0xbc, 0x01, 0x06, 0xfc, 0xfc, 0xf1, -+ 0xfe, 0x07, 0x00, 0x24, 0x95, 0x70, 0x64, 0x18, -+ 0x06, 0x2c, 0xff, 0xb5, 0xfe, 0xfe, 0xb5, 0xfe, -+ 0xfe, 0xe2, 0x8c, 0x24, 0x02, 0x2f, 0xff, 0x2f, -+ 0xff, 0xb4, 0x78, 0x02, 0x05, 0x73, 0xff, 0xed, -+ 0xfe, 0xfe, 0x4f, 0xff, 0x36, 0x74, 0x1e, 0x09, -+ 0x4f, 0xff, 0x50, 0xff, 0xfe, 0x16, 0x00, 0x70, -+ 0xac, 0x70, 0x8e, 0xac, 0x40, 0x0e, 0x01, 0x70, -+ 0x7f, 0x8e, 0xac, 0x6c, 0x00, 0x0b, 0xfe, 0x02, -+ 0x00, 0xfe, 0x0a, 0x2c, 0x2a, 0x2a, 0x28, 0x26, -+ 0x1e, 0x1e, 0xfe, 0x02, 0x20, 0x65, 0x20, 0x00, -+ 0x00, 0x05, 0x12, 0x00, 0x11, 0x1e, 0x11, 0x11, -+ 0x41, 0x1e, 0x41, 0x11, 0x31, 0x1e, 0x31, 0x11, -+ 0x70, 0x75, 0x7a, 0x7f, 0x84, 0x89, 0x8e, 0x93, -+ 0x98, 0x30, 0x20, 0x00, 0x02, 0x00, 0xfe, 0x06, -+ 0x3c, 0xbc, 0x32, 0x0c, 0x00, 0x00, 0x2a, 0x12, -+ 0x1e, 0x12, 0x2e, 0x12, 0xcc, 0x12, 0x11, 0x1a, -+ 0x1e, 0x1a, 0x2e, 0x1a, 0x4c, 0x10, 0x1e, 0x10, -+ 0x11, 0x18, 0x1e, 0x42, 0x1e, 0x42, 0x2e, 0x42, -+ 0xcc, 0x42, 0x11, 0x4a, 0x1e, 0x4a, 0x2e, 0x4a, -+ 0x4c, 0x40, 0x1e, 0x40, 0x11, 0x48, 0x1e, 0x32, -+ 0x1e, 0x32, 0x2e, 0x32, 0xcc, 0x32, 0x11, 0x3a, -+ 0x1e, 0x3a, 0x2e, 0x3a, 0x4c, 0x30, 0x1e, 0x30, -+ 0x11, 0x38, 0x1e, 0x27, 0x9a, 0x01, 0x9d, 0xa2, -+ 0x2f, 0x28, 0x00, 0x00, 0x46, 0xde, 0xc4, 0xbf, -+ 0xa6, 0x9d, 0x81, 0x7b, 0x5c, 0x61, 0x40, 0xc7, -+ 0xc0, 0xae, 0xa9, 0x8c, 0x83, 0x6a, 0x62, 0x50, -+ 0x3e, 0xce, 0xc2, 0xae, 0xa3, 0x8c, 0x7b, 0x6a, -+ 0x5a, 0x50, 0x35, 0xd7, 0xc2, 0xb7, 0xa4, 0x95, -+ 0x7e, 0x72, 0x5a, 0x59, 0x37, 0xfe, 0x02, 0xf8, -+ 0x8c, 0x95, 0x90, 0x8f, 0x00, 0xd7, 0xc0, 0xb7, -+ 0xa2, 0x95, 0x7b, 0x72, 0x56, 0x59, 0x32, 0xc7, -+ 0xc3, 0xae, 0xad, 0x8c, 0x85, 0x6a, 0x63, 0x50, -+ 0x3e, 0xce, 0xc3, 0xae, 0xa4, 0x8c, 0x7c, 0x6a, -+ 0x59, 0x50, 0x34, 0xd7, 0xc2, 0xb7, 0xa5, 0x95, -+ 0x7e, 0x72, 0x59, 0x59, 0x36, 0xfc, 0x05, 0x00, -+ 0x02, 0xce, 0xc5, 0xae, 0xa5, 0x95, 0x83, 0x72, -+ 0x5c, 0x59, 0x36, 0xbf, 0xc6, 0xa5, 0xab, 0x8c, -+ 0x8c, 0x6a, 0x67, 0x50, 0x41, 0x64, 0x07, 0x00, -+ 0x02, 0x95, 0x8c, 0x72, 0x65, 0x59, 0x3f, 0xce, -+ 0xc7, 0xae, 0xa8, 0x95, 0x86, 0x72, 0x5f, 0x59, -+ 0x39, 0xfe, 0x02, 0xf8, 0x8b, 0x7c, 0x0b, 0x09, -+ 0xb7, 0xc2, 0x9d, 0xa4, 0x83, 0x85, 0x6a, 0x6b, -+ 0x50, 0x44, 0xb7, 0xc1, 0x64, 0x01, 0x00, 0x06, -+ 0x61, 0x5d, 0x48, 0x3d, 0xae, 0xc4, 0x9d, 0xad, -+ 0x7b, 0x85, 0x61, 0x66, 0x48, 0x46, 0xae, 0xc3, -+ 0x95, 0xa3, 0x72, 0x7c, 0x59, 0x56, 0x38, 0x31, -+ 0x7c, 0x0b, 0x00, 0x0c, 0x96, 0x91, 0x8f, 0x00, -+ 0xb7, 0xc0, 0xa5, 0xab, 0x8c, 0x8a, 0x6a, 0x64, -+ 0x50, 0x3c, 0xb7, 0xc0, 0x9d, 0xa0, 0x83, 0x80, -+ 0x6a, 0x64, 0x50, 0x3d, 0xb7, 0xc5, 0x9d, 0xa5, -+ 0x83, 0x87, 0x6c, 0x08, 0x07, 0xae, 0xc0, 0x9d, -+ 0xa8, 0x83, 0x88, 0x6a, 0x6d, 0x50, 0x46, 0xfc, -+ 0x05, 0x00, 0x16, 0xbf, 0xc0, 0xa5, 0xa2, 0x8c, -+ 0x7f, 0x6a, 0x57, 0x50, 0x2f, 0xb7, 0xc7, 0xa5, -+ 0xb1, 0x8c, 0x8e, 0x72, 0x6d, 0x59, 0x45, 0xbf, -+ 0xc6, 0xa5, 0xa8, 0x8c, 0x87, 0x6a, 0x5f, 0x50, -+ 0x37, 0xbf, 0xc2, 0xa5, 0xa4, 0x8c, 0x83, 0x6a, -+ 0x5c, 0x50, 0x34, 0xbc, 0x05, 0x00, 0x0e, 0x90, -+ 0x00, 0xc7, 0xc2, 0xae, 0xaa, 0x95, 0x82, 0x7b, -+ 0x60, 0x61, 0x3f, 0xb7, 0xc6, 0xa5, 0xb1, 0x8c, -+ 0x8d, 0x72, 0x6b, 0x61, 0x51, 0xbf, 0xc4, 0xa5, -+ 0xa5, 0x8c, 0x82, 0x72, 0x61, 0x59, 0x39, 0x6c, -+ 0x26, 0x03, 0x95, 0x82, 0x7b, 0x61, 0x61, 0x40, -+ 0xfc, 0x05, 0x00, 0x00, 0x7e, 0xd7, 0xc3, 0xb7, -+ 0xa8, 0x9d, 0x80, 0x83, 0x5d, 0x6a, 0x3f, 0xbf, -+ 0xc7, 0xa5, 0xa8, 0x8c, 0x84, 0x72, 0x60, 0x61, -+ 0x46, 0xbf, 0xc2, 0xae, 0xb0, 0x9d, 0x92, 0x83, -+ 0x6f, 0x6a, 0x50, 0xd7, 0xc3, 0xb7, 0xa7, 0x9d, -+ 0x80, 0x83, 0x5e, 0x6a, 0x40, 0xfe, 0x02, 0xf8, -+ 0x8d, 0x96, 0x90, 0x90, 0xfe, 0x05, 0x00, 0x8a, -+ 0xc4, 0x63, 0xb8, 0x3c, 0xa6, 0x29, 0x97, 0x16, -+ 0x81, 0x84, 0xb7, 0x5b, 0xa9, 0x33, 0x94, 0x1e, -+ 0x83, 0x11, 0x70, 0xb8, 0xc2, 0x70, 0xb1, 0x4d, -+ 0xa3, 0x2a, 0x8d, 0x1b, 0x7b, 0xa8, 0xbc, 0x68, -+ 0xab, 0x47, 0x9d, 0x27, 0x87, 0x18, 0x75, 0xae, -+ 0xc6, 0x7d, 0xbb, 0x4d, 0xaa, 0x1c, 0x84, 0x11, -+ 0x72, 0xa3, 0xbb, 0x6e, 0xad, 0x3c, 0x97, 0x24, -+ 0x85, 0x16, 0x71, 0x80, 0xb2, 0x57, 0xa4, 0x30, -+ 0x8e, 0x1c, 0x7c, 0x10, 0x68, 0xbb, 0xbd, 0x75, -+ 0xac, 0x4f, 0x9e, 0x2b, 0x87, 0x1a, 0x76, 0x96, -+ 0xc5, 0x5e, 0xb5, 0x3e, 0xa5, 0x1f, 0x8c, 0x12, -+ 0x7a, 0xc1, 0xc6, 0x42, 0x9f, 0x27, 0x8c, 0x16, -+ 0x77, 0x0f, 0x67, 0x9d, 0xbc, 0x68, 0xad, 0x36, -+ 0x95, 0x20, 0x83, 0x11, 0x6d, 0x9b, 0xb8, 0x67, -+ 0xa8, 0x34, 0x90, 0x1f, 0x7c, 0x10, 0x67, 0x9e, -+ 0xc9, 0x6a, 0xbb, 0x37, 0xa4, 0x20, 0x90, 0x11, -+ 0x7b, 0xc6, 0xc8, 0x47, 0xa4, 0x2a, 0x90, 0x18, -+ 0x7b, 0x10, 0x6c, 0xae, 0xc4, 0x5d, 0xad, 0x37, -+ 0x9a, 0x1f, 0x85, 0x13, 0x75, 0x70, 0xad, 0x42, -+ 0x99, 0x25, 0x84, 0x17, 0x74, 0x0b, 0x56, 0x87, -+ 0xc8, 0x57, 0xb8, 0x2b, 0x9e, 0x19, 0x8a, 0x0d, -+ 0x74, 0xa7, 0xc8, 0x6e, 0xb9, 0x36, 0xa0, 0x1f, -+ 0x8b, 0x11, 0x75, 0x94, 0xbe, 0x4b, 0xa5, 0x2a, -+ 0x92, 0x18, 0x7c, 0x0f, 0x6b, 0xaf, 0xc0, 0x58, -+ 0xa8, 0x34, 0x94, 0x1d, 0x7d, 0x12, 0x6d, 0x82, -+ 0xc0, 0x52, 0xb0, 0x25, 0x94, 0x14, 0x7f, 0x0c, -+ 0x68, 0x84, 0xbf, 0x3e, 0xa4, 0x22, 0x8e, 0x10, -+ 0x76, 0x0b, 0x65, 0x88, 0xb6, 0x42, 0x9b, 0x26, -+ 0x87, 0x14, 0x70, 0x0c, 0x5f, 0xc5, 0xc2, 0x3e, -+ 0x97, 0x23, 0x83, 0x13, 0x6c, 0x0c, 0x5c, 0xb1, -+ 0xc9, 0x76, 0xbc, 0x4a, 0xaa, 0x20, 0x8d, 0x12, -+ 0x78, 0x93, 0xbf, 0x46, 0xa3, 0x26, 0x8d, 0x14, -+ 0x74, 0x0c, 0x62, 0xc8, 0xc4, 0x3b, 0x97, 0x21, -+ 0x82, 0x11, 0x6a, 0x0a, 0x59, 0xa3, 0xb9, 0x68, -+ 0xa9, 0x30, 0x8d, 0x1a, 0x78, 0x0f, 0x61, 0xa0, -+ 0xc9, 0x73, 0xbe, 0x50, 0xb1, 0x30, 0x9f, 0x14, -+ 0x80, 0x83, 0xb7, 0x3c, 0x9a, 0x20, 0x84, 0x0e, -+ 0x6a, 0x0a, 0x57, 0xac, 0xc2, 0x68, 0xb0, 0x2e, -+ 0x92, 0x19, 0x7c, 0x0d, 0x63, 0x93, 0xbe, 0x62, -+ 0xb0, 0x3c, 0x9e, 0x1a, 0x80, 0x0e, 0x6b, 0xbb, -+ 0x02, 0xa0, 0x02, 0xa0, 0x02, 0x6f, 0x00, 0x75, -+ 0x00, 0x75, 0x00, 0x00, 0x00, 0xad, 0x02, 0xb3, -+ 0x02, 0x6f, 0x00, 0x87, 0x00, 0x85, 0xfe, 0x03, -+ 0x00, 0xc2, 0x02, 0x82, 0x4d, 0x92, 0x6e, 0x4d, -+ 0xb1, 0xa8, 0x84, 0x01, 0x00, 0x07, 0x7e, 0x00, -+ 0xa8, 0x02, 0xa4, 0x02, 0xa4, 0x02, 0xa2, 0x00, -+ 0xa6, 0x00, 0xa6, 0x00, 0x00, 0x00, 0xb4, 0x02, -+ 0xb4, 0x02, 0x92, 0x00, 0x96, 0x00, 0x96, 0x46, -+ 0x04, 0xb0, 0x02, 0x64, 0x02, 0x0a, 0x8c, 0x00, -+ 0x90, 0x02, 0x98, 0x02, 0x98, 0x02, 0x0e, 0x01, -+ 0x11, 0x01, 0x11, 0x50, 0xc3, 0x08, 0x88, 0x02, -+ 0x88, 0x02, 0x19, 0x01, 0x02, 0x01, 0x02, 0x01, -+ 0xf3, 0x2d, 0x00, 0x00 -+}; -+ -+/* Array of known hw_options bits with human-friendly parsing */ -+static struct hc_hwopt { -+ const u32 bit; -+ const char *str; -+} const hc_hwopts[] = { -+ { -+ .bit = RB_HW_OPT_NO_UART, -+ .str = "no UART\t\t", -+ }, { -+ .bit = RB_HW_OPT_HAS_VOLTAGE, -+ .str = "has Vreg\t", -+ }, { -+ .bit = RB_HW_OPT_HAS_USB, -+ .str = "has usb\t\t", -+ }, { -+ .bit = RB_HW_OPT_HAS_ATTINY, -+ .str = "has ATtiny\t", -+ }, { -+ .bit = RB_HW_OPT_NO_NAND, -+ .str = "no NAND\t\t", -+ }, { -+ .bit = RB_HW_OPT_HAS_LCD, -+ .str = "has LCD\t\t", -+ }, { -+ .bit = RB_HW_OPT_HAS_POE_OUT, -+ .str = "has POE out\t", -+ }, { -+ .bit = RB_HW_OPT_HAS_uSD, -+ .str = "has MicroSD\t", -+ }, { -+ .bit = RB_HW_OPT_HAS_SIM, -+ .str = "has SIM\t\t", -+ }, { -+ .bit = RB_HW_OPT_HAS_SFP, -+ .str = "has SFP\t\t", -+ }, { -+ .bit = RB_HW_OPT_HAS_WIFI, -+ .str = "has WiFi\t", -+ }, { -+ .bit = RB_HW_OPT_HAS_TS_FOR_ADC, -+ .str = "has TS ADC\t", -+ }, { -+ .bit = RB_HW_OPT_HAS_PLC, -+ .str = "has PLC\t\t", -+ }, -+}; -+ -+/* -+ * The MAC is stored network-endian on all devices, in 2 32-bit segments: -+ * . Kernel print has us covered. -+ */ -+static ssize_t hc_tag_show_mac(const u8 *pld, u16 pld_len, char *buf) -+{ -+ if (8 != pld_len) -+ return -EINVAL; -+ -+ return sprintf(buf, "%pM\n", pld); -+} -+ -+/* -+ * Print HW options in a human readable way: -+ * The raw number and in decoded form -+ */ -+static ssize_t hc_tag_show_hwoptions(const u8 *pld, u16 pld_len, char *buf) -+{ -+ char *out = buf; -+ u32 data; // cpu-endian -+ int i; -+ -+ if (sizeof(data) != pld_len) -+ return -EINVAL; -+ -+ data = *(u32 *)pld; -+ out += sprintf(out, "raw\t\t: 0x%08x\n\n", data); -+ -+ for (i = 0; i < ARRAY_SIZE(hc_hwopts); i++) -+ out += sprintf(out, "%s: %s\n", hc_hwopts[i].str, -+ (data & hc_hwopts[i].bit) ? "true" : "false"); -+ -+ return out - buf; -+} -+ -+static ssize_t hc_wlan_data_bin_read(struct file *filp, struct kobject *kobj, -+ struct bin_attribute *attr, char *buf, -+ loff_t off, size_t count); -+ -+static struct hc_wlan_attr { -+ const u16 erd_tag_id; -+ struct bin_attribute battr; -+ u16 pld_ofs; -+ u16 pld_len; -+} hc_wd_multi_battrs[] = { -+ { -+ .erd_tag_id = RB_WLAN_ERD_ID_MULTI_8001, -+ .battr = __BIN_ATTR(data_0, S_IRUSR, hc_wlan_data_bin_read, NULL, 0), -+ }, { -+ .erd_tag_id = RB_WLAN_ERD_ID_MULTI_8201, -+ .battr = __BIN_ATTR(data_2, S_IRUSR, hc_wlan_data_bin_read, NULL, 0), -+ } -+}; -+ -+static struct hc_wlan_attr hc_wd_solo_battr = { -+ .erd_tag_id = RB_WLAN_ERD_ID_SOLO, -+ .battr = __BIN_ATTR(wlan_data, S_IRUSR, hc_wlan_data_bin_read, NULL, 0), -+}; -+ -+static ssize_t hc_attr_show(struct kobject *kobj, struct kobj_attribute *attr, -+ char *buf); -+ -+/* Array of known tags to publish in sysfs */ -+static struct hc_attr { -+ const u16 tag_id; -+ ssize_t (* const tshow)(const u8 *pld, u16 pld_len, char *buf); -+ struct kobj_attribute kattr; -+ u16 pld_ofs; -+ u16 pld_len; -+} hc_attrs[] = { -+ { -+ .tag_id = RB_ID_FLASH_INFO, -+ .tshow = routerboot_tag_show_u32s, -+ .kattr = __ATTR(flash_info, S_IRUSR, hc_attr_show, NULL), -+ }, { -+ .tag_id = RB_ID_MAC_ADDRESS_PACK, -+ .tshow = hc_tag_show_mac, -+ .kattr = __ATTR(mac_base, S_IRUSR, hc_attr_show, NULL), -+ }, { -+ .tag_id = RB_ID_BOARD_PRODUCT_CODE, -+ .tshow = routerboot_tag_show_string, -+ .kattr = __ATTR(board_product_code, S_IRUSR, hc_attr_show, NULL), -+ }, { -+ .tag_id = RB_ID_BIOS_VERSION, -+ .tshow = routerboot_tag_show_string, -+ .kattr = __ATTR(booter_version, S_IRUSR, hc_attr_show, NULL), -+ }, { -+ .tag_id = RB_ID_SERIAL_NUMBER, -+ .tshow = routerboot_tag_show_string, -+ .kattr = __ATTR(board_serial, S_IRUSR, hc_attr_show, NULL), -+ }, { -+ .tag_id = RB_ID_MEMORY_SIZE, -+ .tshow = routerboot_tag_show_u32s, -+ .kattr = __ATTR(mem_size, S_IRUSR, hc_attr_show, NULL), -+ }, { -+ .tag_id = RB_ID_MAC_ADDRESS_COUNT, -+ .tshow = routerboot_tag_show_u32s, -+ .kattr = __ATTR(mac_count, S_IRUSR, hc_attr_show, NULL), -+ }, { -+ .tag_id = RB_ID_HW_OPTIONS, -+ .tshow = hc_tag_show_hwoptions, -+ .kattr = __ATTR(hw_options, S_IRUSR, hc_attr_show, NULL), -+ }, { -+ .tag_id = RB_ID_WLAN_DATA, -+ .tshow = NULL, -+ }, { -+ .tag_id = RB_ID_BOARD_IDENTIFIER, -+ .tshow = routerboot_tag_show_string, -+ .kattr = __ATTR(board_identifier, S_IRUSR, hc_attr_show, NULL), -+ }, { -+ .tag_id = RB_ID_PRODUCT_NAME, -+ .tshow = routerboot_tag_show_string, -+ .kattr = __ATTR(product_name, S_IRUSR, hc_attr_show, NULL), -+ }, { -+ .tag_id = RB_ID_DEFCONF, -+ .tshow = routerboot_tag_show_string, -+ .kattr = __ATTR(defconf, S_IRUSR, hc_attr_show, NULL), -+ }, { -+ .tag_id = RB_ID_BOARD_REVISION, -+ .tshow = routerboot_tag_show_string, -+ .kattr = __ATTR(board_revision, S_IRUSR, hc_attr_show, NULL), -+ } -+}; -+ -+/* -+ * If the RB_ID_WLAN_DATA payload starts with RB_MAGIC_ERD, then past -+ * that magic number the payload itself contains a routerboot tag node -+ * locating the LZO-compressed calibration data. So far this scheme is only -+ * known to use a single tag at id 0x1. -+ */ -+static int hc_wlan_data_unpack_erd(const u16 tag_id, const u8 *inbuf, size_t inlen, -+ void *outbuf, size_t *outlen) -+{ -+ u16 lzo_ofs, lzo_len; -+ int ret; -+ -+ /* Find embedded tag */ -+ ret = routerboot_tag_find(inbuf, inlen, tag_id, &lzo_ofs, &lzo_len); -+ if (ret) { -+ pr_debug(RB_HC_PR_PFX "no ERD data for id 0x%04x\n", tag_id); -+ goto fail; -+ } -+ -+ if (lzo_len > inlen) { -+ pr_debug(RB_HC_PR_PFX "Invalid ERD data length\n"); -+ ret = -EINVAL; -+ goto fail; -+ } -+ -+ ret = lzo1x_decompress_safe(inbuf+lzo_ofs, lzo_len, outbuf, outlen); -+ if (ret) -+ pr_debug(RB_HC_PR_PFX "LZO decompression error (%d)\n", ret); -+ -+fail: -+ return ret; -+} -+ -+/* -+ * If the RB_ID_WLAN_DATA payload starts with RB_MAGIC_LZOR, then past -+ * that magic number is a payload that must be appended to the hc_lzor_prefix, -+ * the resulting blob is LZO-compressed. -+ * If payload starts with RB_MAGIC_LZ77, a separate (bit level LZ77) -+ * decompression function needs to be used. In the decompressed result, -+ * the RB_MAGIC_ERD magic number (aligned) must be located. Following that -+ * magic, there is one or more routerboot tag node(s) locating the RLE-encoded -+ * calibration data payload. -+ */ -+static int hc_wlan_data_unpack_lzor_lz77(const u16 tag_id, const u8 *inbuf, size_t inlen, -+ void *outbuf, size_t *outlen, u32 magic) -+{ -+ u16 rle_ofs, rle_len; -+ const u32 *needle; -+ u8 *tempbuf; -+ size_t templen, lzo_len; -+ int ret; -+ const char lzor[] = "LZOR"; -+ const char lz77[] = "LZ77"; -+ const char *lz_type; -+ -+ /* Temporary buffer same size as the outbuf */ -+ templen = *outlen; -+ tempbuf = kmalloc(templen, GFP_KERNEL); -+ if (!tempbuf) -+ return -ENOMEM; -+ -+ lzo_len = inlen; -+ if (magic == RB_MAGIC_LZOR) -+ lzo_len += sizeof(hc_lzor_prefix); -+ if (lzo_len > *outlen) -+ return -EFBIG; -+ -+ switch (magic) { -+ case RB_MAGIC_LZOR: -+ lz_type = lzor; -+ -+ /* Concatenate into the outbuf */ -+ memcpy(outbuf, hc_lzor_prefix, sizeof(hc_lzor_prefix)); -+ memcpy(outbuf + sizeof(hc_lzor_prefix), inbuf, inlen); -+ -+ /* LZO-decompress lzo_len bytes of outbuf into the tempbuf */ -+ ret = lzo1x_decompress_safe(outbuf, lzo_len, tempbuf, &templen); -+ if (ret) { -+ if (LZO_E_INPUT_NOT_CONSUMED == ret) { -+ /* -+ * The tag length is always aligned thus the LZO payload may be padded, -+ * which can trigger a spurious error which we ignore here. -+ */ -+ pr_debug(RB_HC_PR_PFX "LZOR: LZO EOF before buffer end - this may be harmless\n"); -+ } else { -+ pr_debug(RB_HC_PR_PFX "LZOR: LZO decompression error (%d)\n", ret); -+ goto fail; -+ } -+ } -+ break; -+ case RB_MAGIC_LZ77: -+ lz_type = lz77; -+ /* LZO-decompress lzo_len bytes of inbuf into the tempbuf */ -+ ret = rb_lz77_decompress(inbuf, inlen, tempbuf, &templen); -+ if (ret) { -+ pr_err(RB_HC_PR_PFX "LZ77: LZ77 decompress error %d\n", ret); -+ goto fail; -+ } -+ -+ pr_debug(RB_HC_PR_PFX "LZ77: decompressed from %zu to %zu\n", -+ inlen, templen); -+ break; -+ default: -+ return -EINVAL; -+ break; -+ } -+ -+ /* -+ * Post decompression we have a blob (possibly byproduct of the lzo -+ * dictionary). We need to find RB_MAGIC_ERD. The magic number seems to -+ * be 32bit-aligned in the decompression output. -+ */ -+ needle = (const u32 *)tempbuf; -+ while (RB_MAGIC_ERD != *needle++) { -+ if ((u8 *)needle >= tempbuf+templen) { -+ pr_warn(RB_HC_PR_PFX "%s: ERD magic not found. Decompressed first word: 0x%08x\n", lz_type, *(u32 *)tempbuf); -+ ret = -ENODATA; -+ goto fail; -+ } -+ }; -+ templen -= (u8 *)needle - tempbuf; -+ -+ /* Past magic. Look for tag node */ -+ ret = routerboot_tag_find((u8 *)needle, templen, tag_id, &rle_ofs, &rle_len); -+ if (ret) { -+ pr_debug(RB_HC_PR_PFX "%s: no RLE data for id 0x%04x\n", lz_type, tag_id); -+ goto fail; -+ } -+ -+ if (rle_len > templen) { -+ pr_debug(RB_HC_PR_PFX "%s: Invalid RLE data length\n", lz_type); -+ ret = -EINVAL; -+ goto fail; -+ } -+ -+ /* RLE-decode tempbuf from needle back into the outbuf */ -+ ret = routerboot_rle_decode((u8 *)needle+rle_ofs, rle_len, outbuf, outlen); -+ if (ret) -+ pr_debug(RB_HC_PR_PFX "%s: RLE decoding error (%d)\n", lz_type, ret); -+ -+fail: -+ kfree(tempbuf); -+ return ret; -+} -+ -+static int hc_wlan_data_unpack(const u16 tag_id, const size_t tofs, size_t tlen, -+ void *outbuf, size_t *outlen) -+{ -+ const u8 *lbuf; -+ u32 magic; -+ int ret; -+ -+ /* Caller ensure tlen > 0. tofs is aligned */ -+ if ((tofs + tlen) > hc_buflen) -+ return -EIO; -+ -+ lbuf = hc_buf + tofs; -+ magic = *(u32 *)lbuf; -+ -+ ret = -ENODATA; -+ switch (magic) { -+ case RB_MAGIC_LZ77: -+ /* no known instances of lz77 without 8001/8201 data, skip SOLO */ -+ if (tag_id == RB_WLAN_ERD_ID_SOLO) { -+ pr_debug(RB_HC_PR_PFX "skipped LZ77 decompress in search for SOLO tag\n"); -+ break; -+ } -+ fallthrough; -+ case RB_MAGIC_LZOR: -+ /* Skip magic */ -+ lbuf += sizeof(magic); -+ tlen -= sizeof(magic); -+ ret = hc_wlan_data_unpack_lzor_lz77(tag_id, lbuf, tlen, outbuf, outlen, magic); -+ break; -+ case RB_MAGIC_ERD: -+ /* Skip magic */ -+ lbuf += sizeof(magic); -+ tlen -= sizeof(magic); -+ ret = hc_wlan_data_unpack_erd(tag_id, lbuf, tlen, outbuf, outlen); -+ break; -+ default: -+ /* -+ * If the RB_ID_WLAN_DATA payload doesn't start with a -+ * magic number, the payload itself is the raw RLE-encoded -+ * calibration data. Only RB_WLAN_ERD_ID_SOLO makes sense here. -+ */ -+ if (RB_WLAN_ERD_ID_SOLO == tag_id) { -+ ret = routerboot_rle_decode(lbuf, tlen, outbuf, outlen); -+ if (ret) -+ pr_debug(RB_HC_PR_PFX "RLE decoding error (%d)\n", ret); -+ } -+ break; -+ } -+ -+ return ret; -+} -+ -+static ssize_t hc_attr_show(struct kobject *kobj, struct kobj_attribute *attr, -+ char *buf) -+{ -+ const struct hc_attr *hc_attr; -+ const u8 *pld; -+ u16 pld_len; -+ -+ hc_attr = container_of(attr, typeof(*hc_attr), kattr); -+ -+ if (!hc_attr->pld_len) -+ return -ENOENT; -+ -+ pld = hc_buf + hc_attr->pld_ofs; -+ pld_len = hc_attr->pld_len; -+ -+ return hc_attr->tshow(pld, pld_len, buf); -+} -+ -+/* -+ * This function will allocate and free memory every time it is called. This -+ * is not the fastest way to do this, but since the data is rarely read (mainly -+ * at boot time to load wlan caldata), this makes it possible to save memory for -+ * the system. -+ */ -+static ssize_t hc_wlan_data_bin_read(struct file *filp, struct kobject *kobj, -+ struct bin_attribute *attr, char *buf, -+ loff_t off, size_t count) -+{ -+ struct hc_wlan_attr *hc_wattr; -+ size_t outlen; -+ void *outbuf; -+ int ret; -+ -+ hc_wattr = container_of(attr, typeof(*hc_wattr), battr); -+ -+ if (!hc_wattr->pld_len) -+ return -ENOENT; -+ -+ outlen = RB_ART_SIZE; -+ -+ /* Don't bother unpacking if the source is already too large */ -+ if (hc_wattr->pld_len > outlen) -+ return -EFBIG; -+ -+ outbuf = kmalloc(outlen, GFP_KERNEL); -+ if (!outbuf) -+ return -ENOMEM; -+ -+ ret = hc_wlan_data_unpack(hc_wattr->erd_tag_id, hc_wattr->pld_ofs, hc_wattr->pld_len, outbuf, &outlen); -+ if (ret) { -+ kfree(outbuf); -+ return ret; -+ } -+ -+ if (off >= outlen) { -+ kfree(outbuf); -+ return 0; -+ } -+ -+ if (off + count > outlen) -+ count = outlen - off; -+ -+ memcpy(buf, outbuf + off, count); -+ -+ kfree(outbuf); -+ return count; -+} -+ -+int rb_hardconfig_init(struct kobject *rb_kobj, struct mtd_info *mtd) -+{ -+ struct kobject *hc_wlan_kobj; -+ size_t bytes_read, buflen, outlen; -+ const u8 *buf; -+ void *outbuf; -+ int i, j, ret; -+ u32 magic; -+ -+ hc_buf = NULL; -+ hc_kobj = NULL; -+ hc_wlan_kobj = NULL; -+ -+ ret = __get_mtd_device(mtd); -+ if (ret) -+ return -ENODEV; -+ -+ hc_buflen = mtd->size; -+ hc_buf = kmalloc(hc_buflen, GFP_KERNEL); -+ if (!hc_buf) { -+ __put_mtd_device(mtd); -+ return -ENOMEM; -+ } -+ -+ ret = mtd_read(mtd, 0, hc_buflen, &bytes_read, hc_buf); -+ __put_mtd_device(mtd); -+ -+ if (ret) -+ goto fail; -+ -+ if (bytes_read != hc_buflen) { -+ ret = -EIO; -+ goto fail; -+ } -+ -+ /* Check we have what we expect */ -+ magic = *(const u32 *)hc_buf; -+ if (RB_MAGIC_HARD != magic) { -+ ret = -EINVAL; -+ goto fail; -+ } -+ -+ /* Skip magic */ -+ buf = hc_buf + sizeof(magic); -+ buflen = hc_buflen - sizeof(magic); -+ -+ /* Populate sysfs */ -+ ret = -ENOMEM; -+ hc_kobj = kobject_create_and_add(RB_MTD_HARD_CONFIG, rb_kobj); -+ if (!hc_kobj) -+ goto fail; -+ -+ /* Locate and publish all known tags */ -+ for (i = 0; i < ARRAY_SIZE(hc_attrs); i++) { -+ ret = routerboot_tag_find(buf, buflen, hc_attrs[i].tag_id, -+ &hc_attrs[i].pld_ofs, &hc_attrs[i].pld_len); -+ if (ret) { -+ hc_attrs[i].pld_ofs = hc_attrs[i].pld_len = 0; -+ continue; -+ } -+ -+ /* Account for skipped magic */ -+ hc_attrs[i].pld_ofs += sizeof(magic); -+ -+ /* -+ * Special case RB_ID_WLAN_DATA to prep and create the binary attribute. -+ * We first check if the data is "old style" within a single tag (or no tag at all): -+ * If it is we publish this single blob as a binary attribute child of hc_kobj to -+ * preserve backward compatibility. -+ * If it isn't and instead uses multiple ERD tags, we create a subfolder and -+ * publish the known ones there. -+ */ -+ if ((RB_ID_WLAN_DATA == hc_attrs[i].tag_id) && hc_attrs[i].pld_len) { -+ outlen = RB_ART_SIZE; -+ outbuf = kmalloc(outlen, GFP_KERNEL); -+ if (!outbuf) { -+ pr_warn(RB_HC_PR_PFX "Out of memory parsing WLAN tag\n"); -+ continue; -+ } -+ -+ /* Test ID_SOLO first, if found: done */ -+ ret = hc_wlan_data_unpack(RB_WLAN_ERD_ID_SOLO, hc_attrs[i].pld_ofs, hc_attrs[i].pld_len, outbuf, &outlen); -+ if (!ret) { -+ hc_wd_solo_battr.pld_ofs = hc_attrs[i].pld_ofs; -+ hc_wd_solo_battr.pld_len = hc_attrs[i].pld_len; -+ -+ ret = sysfs_create_bin_file(hc_kobj, &hc_wd_solo_battr.battr); -+ if (ret) -+ pr_warn(RB_HC_PR_PFX "Could not create %s sysfs entry (%d)\n", -+ hc_wd_solo_battr.battr.attr.name, ret); -+ } -+ /* Otherwise, create "wlan_data" subtree and publish known data */ -+ else { -+ hc_wlan_kobj = kobject_create_and_add("wlan_data", hc_kobj); -+ if (!hc_wlan_kobj) { -+ kfree(outbuf); -+ pr_warn(RB_HC_PR_PFX "Could not create wlan_data sysfs folder\n"); -+ continue; -+ } -+ -+ for (j = 0; j < ARRAY_SIZE(hc_wd_multi_battrs); j++) { -+ outlen = RB_ART_SIZE; -+ ret = hc_wlan_data_unpack(hc_wd_multi_battrs[j].erd_tag_id, -+ hc_attrs[i].pld_ofs, hc_attrs[i].pld_len, outbuf, &outlen); -+ if (ret) { -+ hc_wd_multi_battrs[j].pld_ofs = hc_wd_multi_battrs[j].pld_len = 0; -+ continue; -+ } -+ -+ hc_wd_multi_battrs[j].pld_ofs = hc_attrs[i].pld_ofs; -+ hc_wd_multi_battrs[j].pld_len = hc_attrs[i].pld_len; -+ -+ ret = sysfs_create_bin_file(hc_wlan_kobj, &hc_wd_multi_battrs[j].battr); -+ if (ret) -+ pr_warn(RB_HC_PR_PFX "Could not create wlan_data/%s sysfs entry (%d)\n", -+ hc_wd_multi_battrs[j].battr.attr.name, ret); -+ } -+ } -+ -+ kfree(outbuf); -+ } -+ /* All other tags are published via standard attributes */ -+ else { -+ ret = sysfs_create_file(hc_kobj, &hc_attrs[i].kattr.attr); -+ if (ret) -+ pr_warn(RB_HC_PR_PFX "Could not create %s sysfs entry (%d)\n", -+ hc_attrs[i].kattr.attr.name, ret); -+ } -+ } -+ -+ pr_info("MikroTik RouterBOARD hardware configuration sysfs driver v" RB_HARDCONFIG_VER "\n"); -+ -+ return 0; -+ -+fail: -+ kfree(hc_buf); -+ hc_buf = NULL; -+ return ret; -+} -+ -+void rb_hardconfig_exit(void) -+{ -+ kobject_put(hc_kobj); -+ hc_kobj = NULL; -+ kfree(hc_buf); -+ hc_buf = NULL; -+} -diff --git a/drivers/platform/mikrotik/rb_hardconfig.h b/drivers/platform/mikrotik/rb_hardconfig.h -new file mode 100644 -index 000000000000..328f4fe3c32a ---- /dev/null -+++ b/drivers/platform/mikrotik/rb_hardconfig.h -@@ -0,0 +1,32 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Common definitions for MikroTik RouterBoot hard config data. -+ * -+ * Copyright (C) 2020 Thibaut VARÈNE -+ * -+ * Some constant defines extracted from routerboot.{c,h} by Gabor Juhos -+ * -+ */ -+ -+#ifndef _ROUTERBOOT_HARD_CONFIG_H_ -+#define _ROUTERBOOT_HARD_CONFIG_H_ -+ -+/* ID values for hardware settings */ -+#define RB_ID_FLASH_INFO 0x03 -+#define RB_ID_MAC_ADDRESS_PACK 0x04 -+#define RB_ID_BOARD_PRODUCT_CODE 0x05 -+#define RB_ID_BIOS_VERSION 0x06 -+#define RB_ID_SDRAM_TIMINGS 0x08 -+#define RB_ID_DEVICE_TIMINGS 0x09 -+#define RB_ID_SOFTWARE_ID 0x0A -+#define RB_ID_SERIAL_NUMBER 0x0B -+#define RB_ID_MEMORY_SIZE 0x0D -+#define RB_ID_MAC_ADDRESS_COUNT 0x0E -+#define RB_ID_HW_OPTIONS 0x15 -+#define RB_ID_WLAN_DATA 0x16 -+#define RB_ID_BOARD_IDENTIFIER 0x17 -+#define RB_ID_PRODUCT_NAME 0x21 -+#define RB_ID_DEFCONF 0x26 -+#define RB_ID_BOARD_REVISION 0x27 -+ -+#endif /* _ROUTERBOOT_HARD_CONFIG_H_ */ -diff --git a/drivers/platform/mikrotik/rb_lz77.c b/drivers/platform/mikrotik/rb_lz77.c -new file mode 100644 -index 000000000000..d443adb128ee ---- /dev/null -+++ b/drivers/platform/mikrotik/rb_lz77.c -@@ -0,0 +1,446 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * Copyright (C) 2023 John Thomson -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "rb_lz77.h" -+ -+#define MIKRO_LZ77 "[rb lz77] " -+ -+/* -+ * The maximum number of bits used in a counter. -+ * For the look behind window, long instruction match offsets -+ * up to 6449 have been seen in provided compressed caldata blobs -+ * (that would need 21 counter bits: 4 to 12 + 11 to 0). -+ * conservative value here: 27 provides offset up to 0x8000 bytes -+ * uses a u8 in this code -+ */ -+#define MIKRO_LZ77_MAX_COUNT_BIT_LEN 27 -+ -+enum rb_lz77_instruction { -+ INSTR_ERROR = -1, -+ INSTR_LITERAL_BYTE = 0, -+ /* a (non aligned) byte follows this instruction, -+ * which is directly copied into output -+ */ -+ INSTR_PREVIOUS_OFFSET = 1, -+ /* this group is a match, with a bytes length defined by -+ * following counter bits, starting at bitshift 0, -+ * less the built-in count of 1 -+ * using the previous offset as source -+ */ -+ INSTR_LONG = 2 -+ /* this group has two counters, -+ * the first counter starts at bitshift 4, -+ * if this counter == 0, this is a non-matching group -+ * the second counter (bytes length) starts at bitshift 4, -+ * less the built-in count of 11+1. -+ * The final match group has this count 0, -+ * and following bits which pad to byte-alignment. -+ * -+ * if this counter > 0, this is a matching group -+ * this first count is the match offset (in bytes) -+ * the second count is the match length (in bytes), -+ * less the built-in count of 2 -+ * these groups can source bytes that are part of this group -+ */ -+}; -+ -+struct rb_lz77_instr_opcodes { -+ /* group instruction */ -+ enum rb_lz77_instruction instruction; -+ /* if >0, a match group, -+ * which starts at byte output_position - 1*offset -+ */ -+ size_t offset; -+ /* how long the match group is, -+ * or how long the (following counter) non-match group is -+ */ -+ size_t length; -+ /* how many bits were used for this instruction + op code(s) */ -+ size_t bits_used; -+ /* input char */ -+ u8 *in; -+ /* offset where this instruction started */ -+ size_t in_pos; -+}; -+ -+/** -+ * rb_lz77_get_bit -+ * -+ * @in: compressed data ptr -+ * @in_offset_bit: bit offset to extract -+ * -+ * convert the bit offset to byte offset, -+ * shift to modulo of bits per bytes, so that wanted bit is lsb -+ * and to extract only that bit. -+ * Caller is responsible for ensuring that in_offset_bit/8 -+ * does not exceed input length -+ */ -+static inline u8 rb_lz77_get_bit(const u8 *in, const size_t in_offset_bit) -+{ -+ return ((in[in_offset_bit / BITS_PER_BYTE] >> -+ (in_offset_bit % BITS_PER_BYTE)) & -+ 1); -+} -+ -+/** -+ * rb_lz77_get_byte -+ * -+ * @in: compressed data -+ * @in_offset_bit: bit offset to extract byte -+ */ -+static inline u8 rb_lz77_get_byte(const u8 *in, const size_t in_offset_bit) -+{ -+ u8 buf = 0; -+ int i; -+ -+ /* built a reversed byte from (likely) unaligned bits */ -+ for (i = 0; i <= 7; ++i) -+ buf += rb_lz77_get_bit(in, in_offset_bit + i) << (7 - i); -+ return buf; -+} -+ -+/** -+ * rb_lz77_decode_count - decode bits at given offset as a count -+ * -+ * @in: compressed data -+ * @in_len: length of compressed data -+ * @in_offset_bit: bit offset where count starts -+ * @shift: left shift operand value of first count bit -+ * @count: initial count -+ * @bits_used: how many bits were consumed by this count -+ * @max_bits: maximum bit count for this counter -+ * -+ * Returns the decoded count -+ */ -+static int rb_lz77_decode_count(const u8 *in, const size_t in_len, -+ const size_t in_offset_bit, u8 shift, -+ size_t count, u8 *bits_used, const u8 max_bits) -+{ -+ size_t pos = in_offset_bit; -+ const size_t max_pos = min(pos + max_bits, in_len * BITS_PER_BYTE); -+ bool up = true; -+ -+ *bits_used = 0; -+ pr_debug(MIKRO_LZ77 -+ "decode_count inbit: %zu, start shift:%u, initial count:%zu\n", -+ in_offset_bit, shift, count); -+ -+ while (true) { -+ /* check the input offset bit does not overflow the minimum of -+ * a reasonable length for this encoded count, and -+ * the end of the input */ -+ if (unlikely(pos >= max_pos)) { -+ pr_err(MIKRO_LZ77 -+ "max bit index reached before count completed\n"); -+ return -EFBIG; -+ } -+ -+ /* if the bit value at offset is set */ -+ if (rb_lz77_get_bit(in, pos)) -+ count += (1 << shift); -+ -+ /* shift increases until we find an unsed bit */ -+ else if (up) -+ up = false; -+ -+ if (up) -+ ++shift; -+ else { -+ if (!shift) { -+ *bits_used = pos - in_offset_bit + 1; -+ return count; -+ } -+ --shift; -+ } -+ -+ ++pos; -+ } -+ -+ return -EINVAL; -+} -+ -+/** -+ * rb_lz77_decode_instruction -+ * -+ * @in: compressed data -+ * @in_offset_bit: bit offset where instruction starts -+ * @bits_used: how many bits were consumed by this count -+ * -+ * Returns the decoded instruction -+ */ -+static enum rb_lz77_instruction -+rb_lz77_decode_instruction(const u8 *in, size_t in_offset_bit, u8 *bits_used) -+{ -+ if (rb_lz77_get_bit(in, in_offset_bit)) { -+ *bits_used = 2; -+ if (rb_lz77_get_bit(in, ++in_offset_bit)) -+ return INSTR_LONG; -+ else -+ return INSTR_PREVIOUS_OFFSET; -+ } else { -+ *bits_used = 1; -+ return INSTR_LITERAL_BYTE; -+ } -+ return INSTR_ERROR; -+} -+ -+/** -+ * rb_lz77_decode_instruction_operators -+ * -+ * @in: compressed data -+ * @in_len: length of compressed data -+ * @in_offset_bit: bit offset where instruction starts -+ * @previous_offset: last used match offset -+ * @opcode: struct to hold instruction & operators -+ * -+ * Returns error code -+ */ -+static int rb_lz77_decode_instruction_operators( -+ const u8 *in, const size_t in_len, const size_t in_offset_bit, -+ const size_t previous_offset, struct rb_lz77_instr_opcodes *opcode) -+{ -+ enum rb_lz77_instruction instruction; -+ u8 bit_count = 0; -+ u8 bits_used = 0; -+ int offset = 0; -+ int length = 0; -+ -+ instruction = rb_lz77_decode_instruction(in, in_offset_bit, &bit_count); -+ -+ /* skip bits used by instruction */ -+ bits_used += bit_count; -+ -+ switch (instruction) { -+ case INSTR_LITERAL_BYTE: -+ /* non-matching char */ -+ offset = 0; -+ length = 1; -+ break; -+ -+ case INSTR_PREVIOUS_OFFSET: -+ /* matching group uses previous offset */ -+ offset = previous_offset; -+ -+ length = rb_lz77_decode_count(in, in_len, -+ in_offset_bit + bits_used, 0, 1, -+ &bit_count, -+ MIKRO_LZ77_MAX_COUNT_BIT_LEN); -+ if (unlikely(length < 0)) -+ return length; -+ /* skip bits used by count */ -+ bits_used += bit_count; -+ break; -+ -+ case INSTR_LONG: -+ offset = rb_lz77_decode_count(in, in_len, -+ in_offset_bit + bits_used, 4, 0, -+ &bit_count, -+ MIKRO_LZ77_MAX_COUNT_BIT_LEN); -+ if (unlikely(offset < 0)) -+ return offset; -+ -+ /* skip bits used by offset count */ -+ bits_used += bit_count; -+ -+ if (offset == 0) { -+ /* non-matching long group */ -+ length = rb_lz77_decode_count( -+ in, in_len, in_offset_bit + bits_used, 4, 12, -+ &bit_count, MIKRO_LZ77_MAX_COUNT_BIT_LEN); -+ if (unlikely(length < 0)) -+ return length; -+ /* skip bits used by length count */ -+ bits_used += bit_count; -+ } else { -+ /* matching group */ -+ length = rb_lz77_decode_count( -+ in, in_len, in_offset_bit + bits_used, 0, 2, -+ &bit_count, MIKRO_LZ77_MAX_COUNT_BIT_LEN); -+ if (unlikely(length < 0)) -+ return length; -+ /* skip bits used by length count */ -+ bits_used += bit_count; -+ } -+ -+ break; -+ -+ case INSTR_ERROR: -+ return -EINVAL; -+ } -+ -+ opcode->instruction = instruction; -+ opcode->offset = offset; -+ opcode->length = length; -+ opcode->bits_used = bits_used; -+ opcode->in = (u8 *)in; -+ opcode->in_pos = in_offset_bit; -+ return 0; -+} -+ -+/** -+ * rb_lz77_decompress -+ * -+ * @in: compressed data ptr -+ * @in_len: length of compressed data -+ * @out: buffer ptr to decompress into -+ * @out_len: length of decompressed buffer in input, -+ * length of decompressed data in success -+ * -+ * Returns 0 on success, or negative error -+ */ -+int rb_lz77_decompress(const u8 *in, const size_t in_len, u8 *out, -+ size_t *out_len) -+{ -+ u8 *output_ptr; -+ size_t input_bit = 0; -+ const u8 *output_end = out + *out_len; -+ struct rb_lz77_instr_opcodes *opcode; -+ size_t match_offset = 0; -+ int rc = 0; -+ size_t match_length, partial_count, i; -+ -+ output_ptr = out; -+ -+ if (unlikely((in_len * BITS_PER_BYTE) > SIZE_MAX)) { -+ pr_err(MIKRO_LZ77 "input longer than expected\n"); -+ return -EFBIG; -+ } -+ -+ opcode = kmalloc(sizeof(*opcode), GFP_KERNEL); -+ if (!opcode) -+ return -ENOMEM; -+ -+ while (true) { -+ if (unlikely(output_ptr > output_end)) { -+ pr_err(MIKRO_LZ77 "output overrun\n"); -+ rc = -EOVERFLOW; -+ goto free_lz77_struct; -+ } -+ if (unlikely(input_bit > in_len * BITS_PER_BYTE)) { -+ pr_err(MIKRO_LZ77 "input overrun\n"); -+ rc = -ENODATA; -+ goto free_lz77_struct; -+ } -+ -+ rc = rb_lz77_decode_instruction_operators(in, in_len, input_bit, -+ match_offset, opcode); -+ if (unlikely(rc < 0)) { -+ pr_err(MIKRO_LZ77 -+ "instruction operands decode error\n"); -+ goto free_lz77_struct; -+ } -+ -+ pr_debug(MIKRO_LZ77 "inbit:0x%zx->outbyte:0x%zx", input_bit, -+ output_ptr - out); -+ -+ input_bit += opcode->bits_used; -+ switch (opcode->instruction) { -+ case INSTR_LITERAL_BYTE: -+ pr_debug(" short"); -+ fallthrough; -+ case INSTR_LONG: -+ if (opcode->offset == 0) { -+ /* this is a non-matching group */ -+ pr_debug(" non-match, len: 0x%zx\n", -+ opcode->length); -+ /* test end marker */ -+ if (opcode->length == 0xc && -+ ((input_bit + -+ opcode->length * BITS_PER_BYTE) > -+ in_len)) { -+ *out_len = output_ptr - out; -+ pr_debug( -+ MIKRO_LZ77 -+ "lz77 decompressed from %zu to %zu\n", -+ in_len, *out_len); -+ rc = 0; -+ goto free_lz77_struct; -+ } -+ for (i = opcode->length; i > 0; --i) { -+ *output_ptr = -+ rb_lz77_get_byte(in, input_bit); -+ ++output_ptr; -+ input_bit += BITS_PER_BYTE; -+ } -+ /* do no fallthrough if a non-match group */ -+ break; -+ } -+ match_offset = opcode->offset; -+ fallthrough; -+ case INSTR_PREVIOUS_OFFSET: -+ match_length = opcode->length; -+ partial_count = 0; -+ -+ pr_debug(" match, offset: 0x%zx, len: 0x%zx", -+ opcode->offset, match_length); -+ -+ if (unlikely(opcode->offset == 0)) { -+ pr_err(MIKRO_LZ77 -+ "match group missing opcode->offset\n"); -+ rc = -EBADMSG; -+ goto free_lz77_struct; -+ } -+ -+ /* overflow */ -+ if (unlikely((output_ptr + match_length) > -+ output_end)) { -+ pr_err(MIKRO_LZ77 -+ "match group output overflow\n"); -+ rc = -ENOBUFS; -+ goto free_lz77_struct; -+ } -+ -+ /* underflow */ -+ if (unlikely((output_ptr - opcode->offset) < out)) { -+ pr_err(MIKRO_LZ77 -+ "match group offset underflow\n"); -+ rc = -ESPIPE; -+ goto free_lz77_struct; -+ } -+ -+ /* there are cases where the match (length) includes -+ * data that is a part of the same match -+ */ -+ while (opcode->offset < match_length) { -+ ++partial_count; -+ memcpy(output_ptr, output_ptr - opcode->offset, -+ opcode->offset); -+ output_ptr += opcode->offset; -+ match_length -= opcode->offset; -+ } -+ memcpy(output_ptr, output_ptr - opcode->offset, -+ match_length); -+ output_ptr += match_length; -+ if (partial_count) -+ pr_debug(" (%zu partial memcpy)", -+ partial_count); -+ pr_debug("\n"); -+ -+ break; -+ -+ case INSTR_ERROR: -+ rc = -EINVAL; -+ goto free_lz77_struct; -+ } -+ } -+ -+ pr_err(MIKRO_LZ77 "decode loop broken\n"); -+ rc = -EINVAL; -+ -+free_lz77_struct: -+ kfree(opcode); -+ return rc; -+} -+EXPORT_SYMBOL_GPL(rb_lz77_decompress); -+ -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("Mikrotik Wi-Fi caldata LZ77 decompressor"); -+MODULE_AUTHOR("John Thomson"); -diff --git a/drivers/platform/mikrotik/rb_lz77.h b/drivers/platform/mikrotik/rb_lz77.h -new file mode 100644 -index 000000000000..55179fcbc8e0 ---- /dev/null -+++ b/drivers/platform/mikrotik/rb_lz77.h -@@ -0,0 +1,35 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+/* -+ * Copyright (C) 2024 John Thomson -+ */ -+ -+#ifndef __MIKROTIK_WLAN_LZ77_H__ -+#define __MIKROTIK_WLAN_LZ77_H__ -+ -+#include -+ -+#ifdef CONFIG_MIKROTIK_WLAN_DECOMPRESS_LZ77 -+/** -+ * rb_lz77_decompress -+ * -+ * @in: compressed data ptr -+ * @in_len: length of compressed data -+ * @out: buffer ptr to decompress into -+ * @out_len: length of decompressed buffer in input, -+ * length of decompressed data in success -+ * -+ * Returns 0 on success, or negative error -+ */ -+int rb_lz77_decompress(const u8 *in, const size_t in_len, u8 *out, -+ size_t *out_len); -+ -+#else /* CONFIG_MIKROTIK_WLAN_DECOMPRESS_LZ77 */ -+ -+static inline int rb_lz77_decompress(const u8 *in, const size_t in_len, u8 *out, -+ size_t *out_len) -+{ -+ return -EOPNOTSUPP; -+} -+ -+#endif /* CONFIG_MIKROTIK_WLAN_DECOMPRESS_LZ77 */ -+#endif /* __MIKROTIK_WLAN_LZ77_H__ */ -diff --git a/drivers/platform/mikrotik/rb_nvmem.c b/drivers/platform/mikrotik/rb_nvmem.c -new file mode 100644 -index 000000000000..6f785ce7d14d ---- /dev/null -+++ b/drivers/platform/mikrotik/rb_nvmem.c -@@ -0,0 +1,230 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * NVMEM layout driver for MikroTik Routerboard hard config cells -+ * -+ * Copyright (C) 2024 Robert Marko -+ * Based on the sysfs hard config driver by Thibaut VARÈNE -+ * Comments documenting the format carried over from routerboot.c -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "rb_hardconfig.h" -+#include "routerboot.h" -+ -+#define TLV_TAG_MASK GENMASK(15, 0) -+#define TLV_LEN_MASK GENMASK(31, 16) -+ -+static const char *rb_tlv_cell_name(u16 tag) -+{ -+ switch (tag) { -+ case RB_ID_FLASH_INFO: -+ return "flash-info"; -+ case RB_ID_MAC_ADDRESS_PACK: -+ return "base-mac-address"; -+ case RB_ID_BOARD_PRODUCT_CODE: -+ return "board-product-code"; -+ case RB_ID_BIOS_VERSION: -+ return "booter-version"; -+ case RB_ID_SERIAL_NUMBER: -+ return "board-serial"; -+ case RB_ID_MEMORY_SIZE: -+ return "mem-size"; -+ case RB_ID_MAC_ADDRESS_COUNT: -+ return "mac-count"; -+ case RB_ID_HW_OPTIONS: -+ return "hw-options"; -+ case RB_ID_WLAN_DATA: -+ return "wlan-data"; -+ case RB_ID_BOARD_IDENTIFIER: -+ return "board-identifier"; -+ case RB_ID_PRODUCT_NAME: -+ return "product-name"; -+ case RB_ID_DEFCONF: -+ return "defconf"; -+ case RB_ID_BOARD_REVISION: -+ return "board-revision"; -+ default: -+ break; -+ } -+ -+ return NULL; -+} -+ -+static int rb_tlv_mac_read_cb(void *priv, const char *id, int index, -+ unsigned int offset, void *buf, -+ size_t bytes) -+{ -+ if (index < 0) -+ return -EINVAL; -+ -+ if (!is_valid_ether_addr(buf)) -+ return -EINVAL; -+ -+ eth_addr_add(buf, index); -+ -+ return 0; -+} -+ -+static nvmem_cell_post_process_t rb_tlv_read_cb(u16 tag) -+{ -+ switch (tag) { -+ case RB_ID_MAC_ADDRESS_PACK: -+ return &rb_tlv_mac_read_cb; -+ default: -+ break; -+ } -+ -+ return NULL; -+} -+ -+static int rb_add_cells(struct device *dev, struct nvmem_device *nvmem, -+ const size_t data_len, u8 *data) -+{ -+ u32 node, offset = sizeof(RB_MAGIC_HARD); -+ struct nvmem_cell_info cell = {}; -+ struct device_node *layout; -+ u16 tlv_tag, tlv_len; -+ int ret; -+ -+ layout = of_nvmem_layout_get_container(nvmem); -+ if (!layout) -+ return -ENOENT; -+ -+ /* -+ * Routerboot tag nodes are u32 values: -+ * - The low nibble is the tag identification number, -+ * - The high nibble is the tag payload length (node excluded) in bytes. -+ * Tag nodes are CPU-endian. -+ * Tag nodes are 32bit-aligned. -+ * -+ * The payload immediately follows the tag node. -+ * Payload offset will always be aligned. while length may not end on 32bit -+ * boundary (the only known case is when parsing ERD data). -+ * The payload is CPU-endian when applicable. -+ * Tag nodes are not ordered (by ID) on flash. -+ */ -+ while ((offset + sizeof(node)) <= data_len) { -+ node = *((const u32 *) (data + offset)); -+ /* Tag list ends with null node */ -+ if (!node) -+ break; -+ -+ tlv_tag = FIELD_GET(TLV_TAG_MASK, node); -+ tlv_len = FIELD_GET(TLV_LEN_MASK, node); -+ -+ offset += sizeof(node); -+ if (offset + tlv_len > data_len) { -+ dev_err(dev, "Out of bounds field (0x%x bytes at 0x%x)\n", -+ tlv_len, offset); -+ break; -+ } -+ -+ cell.name = rb_tlv_cell_name(tlv_tag); -+ if (!cell.name) -+ goto skip; -+ -+ cell.offset = offset; -+ /* -+ * MikroTik stores MAC-s with length of 8 bytes, -+ * but kernel expects it to be ETH_ALEN (6 bytes), -+ * so we need to make sure that is the case. -+ */ -+ if (tlv_tag == RB_ID_MAC_ADDRESS_PACK) -+ cell.bytes = ETH_ALEN; -+ else -+ cell.bytes = tlv_len; -+ cell.np = of_get_child_by_name(layout, cell.name); -+ cell.read_post_process = rb_tlv_read_cb(tlv_tag); -+ -+ ret = nvmem_add_one_cell(nvmem, &cell); -+ if (ret) { -+ of_node_put(layout); -+ return ret; -+ } -+ -+ /* -+ * The only known situation where len may not end on 32bit -+ * boundary is within ERD data. Since we're only extracting -+ * one tag (the first and only one) from that data, we should -+ * never need to forcefully ALIGN(). Do it anyway, this is not a -+ * performance path. -+ */ -+skip: -+ offset += ALIGN(tlv_len, sizeof(offset)); -+ } -+ -+ of_node_put(layout); -+ -+ return 0; -+} -+ -+static int rb_parse_table(struct nvmem_layout *layout) -+{ -+ struct nvmem_device *nvmem = layout->nvmem; -+ struct device *dev = &layout->dev; -+ size_t mtd_size; -+ u8 *data; -+ u32 hdr; -+ int ret; -+ -+ ret = nvmem_device_read(nvmem, 0, sizeof(hdr), &hdr); -+ if (ret < 0) -+ return ret; -+ -+ if (hdr != RB_MAGIC_HARD) { -+ dev_err(dev, "Invalid header\n"); -+ return -EINVAL; -+ } -+ -+ mtd_size = nvmem_dev_size(nvmem); -+ -+ data = devm_kmalloc(dev, mtd_size, GFP_KERNEL); -+ if (!data) -+ return -ENOMEM; -+ -+ ret = nvmem_device_read(nvmem, 0, mtd_size, data); -+ if (ret != mtd_size) -+ return ret; -+ -+ return rb_add_cells(dev, nvmem, mtd_size, data); -+} -+ -+static int rb_nvmem_probe(struct nvmem_layout *layout) -+{ -+ layout->add_cells = rb_parse_table; -+ -+ return nvmem_layout_register(layout); -+} -+ -+static void rb_nvmem_remove(struct nvmem_layout *layout) -+{ -+ nvmem_layout_unregister(layout); -+} -+ -+static const struct of_device_id rb_nvmem_of_match_table[] = { -+ { .compatible = "mikrotik,routerboot-nvmem", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, rb_nvmem_of_match_table); -+ -+static struct nvmem_layout_driver rb_nvmem_layout = { -+ .probe = rb_nvmem_probe, -+ .remove = rb_nvmem_remove, -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = "rb_nvmem", -+ .of_match_table = rb_nvmem_of_match_table, -+ }, -+}; -+module_nvmem_layout_driver(rb_nvmem_layout); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Robert Marko "); -+MODULE_DESCRIPTION("NVMEM layout driver for MikroTik Routerboard hard config cells"); -diff --git a/drivers/platform/mikrotik/rb_softconfig.c b/drivers/platform/mikrotik/rb_softconfig.c -new file mode 100644 -index 000000000000..5acff6aa9184 ---- /dev/null -+++ b/drivers/platform/mikrotik/rb_softconfig.c -@@ -0,0 +1,795 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Driver for MikroTik RouterBoot soft config. -+ * -+ * Copyright (C) 2020 Thibaut VARÈNE -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ * This driver exposes the data encoded in the "soft_config" flash segment of -+ * MikroTik RouterBOARDs devices. It presents the data in a sysfs folder -+ * named "soft_config". The data is presented in a user/machine-friendly way -+ * with just as much parsing as can be generalized across mikrotik platforms -+ * (as inferred from reverse-engineering). -+ * -+ * The known soft_config tags are presented in the "soft_config" sysfs folder, -+ * with the addition of one specific file named "commit", which is only -+ * available if the driver supports writes to the mtd device: no modifications -+ * made to any of the other attributes are actually written back to flash media -+ * until a true value is input into this file (e.g. [Yy1]). This is to avoid -+ * unnecessary flash wear, and to permit to revert all changes by issuing a -+ * false value ([Nn0]). Reading the content of this file shows the current -+ * status of the driver: if the data in sysfs matches the content of the -+ * soft_config partition, the file will read "clean". Otherwise, it will read -+ * "dirty". -+ * -+ * The writeable sysfs files presented by this driver will accept only inputs -+ * which are in a valid range for the given tag. As a design choice, the driver -+ * will not assess whether the inputs are identical to the existing data. -+ * -+ * Note: PAGE_SIZE is assumed to be >= 4K, hence the device attribute show -+ * routines need not check for output overflow. -+ * -+ * Some constant defines extracted from rbcfg.h by Gabor Juhos -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_ATH79 -+ #include -+#endif -+ -+#include "routerboot.h" -+ -+#define RB_SOFTCONFIG_VER "0.05" -+#define RB_SC_PR_PFX "[rb_softconfig] " -+ -+#define RB_SC_HAS_WRITE_SUPPORT true -+#define RB_SC_WMODE S_IWUSR -+#define RB_SC_RMODE S_IRUSR -+ -+/* ID values for software settings */ -+#define RB_SCID_UART_SPEED 0x01 // u32*1 -+#define RB_SCID_BOOT_DELAY 0x02 // u32*1 -+#define RB_SCID_BOOT_DEVICE 0x03 // u32*1 -+#define RB_SCID_BOOT_KEY 0x04 // u32*1 -+#define RB_SCID_CPU_MODE 0x05 // u32*1 -+#define RB_SCID_BIOS_VERSION 0x06 // str -+#define RB_SCID_BOOT_PROTOCOL 0x09 // u32*1 -+#define RB_SCID_CPU_FREQ_IDX 0x0C // u32*1 -+#define RB_SCID_BOOTER 0x0D // u32*1 -+#define RB_SCID_SILENT_BOOT 0x0F // u32*1 -+/* -+ * protected_routerboot seems to use tag 0x1F. It only works in combination with -+ * RouterOS, resulting in a wiped board otherwise, so it's not implemented here. -+ * The tag values are as follows: -+ * - off: 0x0 -+ * - on: the lower halfword encodes the max value in s for the reset feature, -+ * the higher halfword encodes the min value in s for the reset feature. -+ * Default value when on: 0x00140258: 0x14 = 20s / 0x258= 600s -+ * See details here: https://wiki.mikrotik.com/wiki/Manual:RouterBOARD_settings#Protected_bootloader -+ */ -+ -+/* Tag values */ -+ -+#define RB_UART_SPEED_115200 0 -+#define RB_UART_SPEED_57600 1 -+#define RB_UART_SPEED_38400 2 -+#define RB_UART_SPEED_19200 3 -+#define RB_UART_SPEED_9600 4 -+#define RB_UART_SPEED_4800 5 -+#define RB_UART_SPEED_2400 6 -+#define RB_UART_SPEED_1200 7 -+#define RB_UART_SPEED_OFF 8 -+ -+/* valid boot delay: 1 - 9s in 1s increment */ -+#define RB_BOOT_DELAY_MIN 1 -+#define RB_BOOT_DELAY_MAX 9 -+ -+#define RB_BOOT_DEVICE_ETHER 0 // "boot over Ethernet" -+#define RB_BOOT_DEVICE_NANDETH 1 // "boot from NAND, if fail then Ethernet" -+#define RB_BOOT_DEVICE_CFCARD 2 // (not available in rbcfg) -+#define RB_BOOT_DEVICE_ETHONCE 3 // "boot Ethernet once, then NAND" -+#define RB_BOOT_DEVICE_NANDONLY 5 // "boot from NAND only" -+#define RB_BOOT_DEVICE_FLASHCFG 7 // "boot in flash configuration mode" -+#define RB_BOOT_DEVICE_FLSHONCE 8 // "boot in flash configuration mode once, then NAND" -+ -+/* -+ * ATH79 9xxx CPU frequency indices. -+ * It is unknown if they apply to all ATH79 RBs, and some do not seem to feature -+ * the upper levels (QCA955x), while F is presumably AR9344-only. -+ */ -+#define RB_CPU_FREQ_IDX_ATH79_9X_A (0 << 3) -+#define RB_CPU_FREQ_IDX_ATH79_9X_B (1 << 3) // 0x8 -+#define RB_CPU_FREQ_IDX_ATH79_9X_C (2 << 3) // 0x10 - factory freq for many devices -+#define RB_CPU_FREQ_IDX_ATH79_9X_D (3 << 3) // 0x18 -+#define RB_CPU_FREQ_IDX_ATH79_9X_E (4 << 3) // 0x20 -+#define RB_CPU_FREQ_IDX_ATH79_9X_F (5 << 3) // 0x28 -+ -+#define RB_CPU_FREQ_IDX_ATH79_9X_MIN 0 // all devices support lowest setting -+#define RB_CPU_FREQ_IDX_ATH79_9X_AR9334_MAX 5 // stops at F -+#define RB_CPU_FREQ_IDX_ATH79_9X_QCA953X_MAX 4 // stops at E -+#define RB_CPU_FREQ_IDX_ATH79_9X_QCA9556_MAX 2 // stops at C -+#define RB_CPU_FREQ_IDX_ATH79_9X_QCA9558_MAX 3 // stops at D -+ -+/* ATH79 7xxx CPU frequency indices. */ -+#define RB_CPU_FREQ_IDX_ATH79_7X_A ((0 * 9) << 4) -+#define RB_CPU_FREQ_IDX_ATH79_7X_B ((1 * 9) << 4) -+#define RB_CPU_FREQ_IDX_ATH79_7X_C ((2 * 9) << 4) -+#define RB_CPU_FREQ_IDX_ATH79_7X_D ((3 * 9) << 4) -+#define RB_CPU_FREQ_IDX_ATH79_7X_E ((4 * 9) << 4) -+#define RB_CPU_FREQ_IDX_ATH79_7X_F ((5 * 9) << 4) -+#define RB_CPU_FREQ_IDX_ATH79_7X_G ((6 * 9) << 4) -+#define RB_CPU_FREQ_IDX_ATH79_7X_H ((7 * 9) << 4) -+ -+#define RB_CPU_FREQ_IDX_ATH79_7X_MIN 0 // all devices support lowest setting -+#define RB_CPU_FREQ_IDX_ATH79_7X_AR724X_MAX 3 // stops at D -+#define RB_CPU_FREQ_IDX_ATH79_7X_AR7161_MAX 7 // stops at H - check if applies to all AR71xx devices -+ -+#define RB_SC_CRC32_OFFSET 4 // located right after magic -+ -+static struct kobject *sc_kobj; -+static u8 *sc_buf; -+static size_t sc_buflen; -+static rwlock_t sc_bufrwl; // rw lock to sc_buf -+ -+/* MUST be used with lock held */ -+#define RB_SC_CLRCRC() *(u32 *)(sc_buf + RB_SC_CRC32_OFFSET) = 0 -+#define RB_SC_GETCRC() *(u32 *)(sc_buf + RB_SC_CRC32_OFFSET) -+#define RB_SC_SETCRC(_crc) *(u32 *)(sc_buf + RB_SC_CRC32_OFFSET) = (_crc) -+ -+struct sc_u32tvs { -+ const u32 val; -+ const char *str; -+}; -+ -+#define RB_SC_TVS(_val, _str) { \ -+ .val = (_val), \ -+ .str = (_str), \ -+} -+ -+static ssize_t sc_tag_show_u32tvs(const u8 *pld, u16 pld_len, char *buf, -+ const struct sc_u32tvs tvs[], const int tvselmts) -+{ -+ const char *fmt; -+ char *out = buf; -+ u32 data; // cpu-endian -+ int i; -+ -+ // fallback to raw hex output if we can't handle the input -+ if (tvselmts < 0) -+ return routerboot_tag_show_u32s(pld, pld_len, buf); -+ -+ if (sizeof(data) != pld_len) -+ return -EINVAL; -+ -+ read_lock(&sc_bufrwl); -+ data = *(u32 *)pld; // pld aliases sc_buf -+ read_unlock(&sc_bufrwl); -+ -+ for (i = 0; i < tvselmts; i++) { -+ fmt = (tvs[i].val == data) ? "[%s] " : "%s "; -+ out += sprintf(out, fmt, tvs[i].str); -+ } -+ -+ out += sprintf(out, "\n"); -+ return out - buf; -+} -+ -+static ssize_t sc_tag_store_u32tvs(const u8 *pld, u16 pld_len, const char *buf, size_t count, -+ const struct sc_u32tvs tvs[], const int tvselmts) -+{ -+ int i; -+ -+ if (tvselmts < 0) -+ return tvselmts; -+ -+ if (sizeof(u32) != pld_len) -+ return -EINVAL; -+ -+ for (i = 0; i < tvselmts; i++) { -+ if (sysfs_streq(buf, tvs[i].str)) { -+ write_lock(&sc_bufrwl); -+ *(u32 *)pld = tvs[i].val; // pld aliases sc_buf -+ RB_SC_CLRCRC(); -+ write_unlock(&sc_bufrwl); -+ return count; -+ } -+ } -+ -+ return -EINVAL; -+} -+ -+struct sc_boolts { -+ const char *strfalse; -+ const char *strtrue; -+}; -+ -+static ssize_t sc_tag_show_boolts(const u8 *pld, u16 pld_len, char *buf, -+ const struct sc_boolts *bts) -+{ -+ const char *fmt; -+ char *out = buf; -+ u32 data; // cpu-endian -+ -+ if (sizeof(data) != pld_len) -+ return -EINVAL; -+ -+ read_lock(&sc_bufrwl); -+ data = *(u32 *)pld; // pld aliases sc_buf -+ read_unlock(&sc_bufrwl); -+ -+ fmt = (data) ? "%s [%s]\n" : "[%s] %s\n"; -+ out += sprintf(out, fmt, bts->strfalse, bts->strtrue); -+ -+ return out - buf; -+} -+ -+static ssize_t sc_tag_store_boolts(const u8 *pld, u16 pld_len, const char *buf, size_t count, -+ const struct sc_boolts *bts) -+{ -+ u32 data; // cpu-endian -+ -+ if (sizeof(data) != pld_len) -+ return -EINVAL; -+ -+ if (sysfs_streq(buf, bts->strfalse)) -+ data = 0; -+ else if (sysfs_streq(buf, bts->strtrue)) -+ data = 1; -+ else -+ return -EINVAL; -+ -+ write_lock(&sc_bufrwl); -+ *(u32 *)pld = data; // pld aliases sc_buf -+ RB_SC_CLRCRC(); -+ write_unlock(&sc_bufrwl); -+ -+ return count; -+} -+static struct sc_u32tvs const sc_uartspeeds[] = { -+ RB_SC_TVS(RB_UART_SPEED_OFF, "off"), -+ RB_SC_TVS(RB_UART_SPEED_1200, "1200"), -+ RB_SC_TVS(RB_UART_SPEED_2400, "2400"), -+ RB_SC_TVS(RB_UART_SPEED_4800, "4800"), -+ RB_SC_TVS(RB_UART_SPEED_9600, "9600"), -+ RB_SC_TVS(RB_UART_SPEED_19200, "19200"), -+ RB_SC_TVS(RB_UART_SPEED_38400, "38400"), -+ RB_SC_TVS(RB_UART_SPEED_57600, "57600"), -+ RB_SC_TVS(RB_UART_SPEED_115200, "115200"), -+}; -+ -+/* -+ * While the defines are carried over from rbcfg, use strings that more clearly -+ * show the actual setting purpose (especially since the NAND* settings apply -+ * to both nand- and nor-based devices). "cfcard" was disabled in rbcfg: disable -+ * it here too. -+ */ -+static struct sc_u32tvs const sc_bootdevices[] = { -+ RB_SC_TVS(RB_BOOT_DEVICE_ETHER, "eth"), -+ RB_SC_TVS(RB_BOOT_DEVICE_NANDETH, "flasheth"), -+ //RB_SC_TVS(RB_BOOT_DEVICE_CFCARD, "cfcard"), -+ RB_SC_TVS(RB_BOOT_DEVICE_ETHONCE, "ethonce"), -+ RB_SC_TVS(RB_BOOT_DEVICE_NANDONLY, "flash"), -+ RB_SC_TVS(RB_BOOT_DEVICE_FLASHCFG, "cfg"), -+ RB_SC_TVS(RB_BOOT_DEVICE_FLSHONCE, "cfgonce"), -+}; -+ -+static struct sc_boolts const sc_bootkey = { -+ .strfalse = "any", -+ .strtrue = "del", -+}; -+ -+static struct sc_boolts const sc_cpumode = { -+ .strfalse = "powersave", -+ .strtrue = "regular", -+}; -+ -+static struct sc_boolts const sc_bootproto = { -+ .strfalse = "bootp", -+ .strtrue = "dhcp", -+}; -+ -+static struct sc_boolts const sc_booter = { -+ .strfalse = "regular", -+ .strtrue = "backup", -+}; -+ -+static struct sc_boolts const sc_silent_boot = { -+ .strfalse = "off", -+ .strtrue = "on", -+}; -+ -+#define SC_TAG_SHOW_STORE_U32TVS_FUNCS(_name) \ -+static ssize_t sc_tag_show_##_name(const u8 *pld, u16 pld_len, char *buf) \ -+{ \ -+ return sc_tag_show_u32tvs(pld, pld_len, buf, sc_##_name, ARRAY_SIZE(sc_##_name)); \ -+} \ -+static ssize_t sc_tag_store_##_name(const u8 *pld, u16 pld_len, const char *buf, size_t count) \ -+{ \ -+ return sc_tag_store_u32tvs(pld, pld_len, buf, count, sc_##_name, ARRAY_SIZE(sc_##_name)); \ -+} -+ -+#define SC_TAG_SHOW_STORE_BOOLTS_FUNCS(_name) \ -+static ssize_t sc_tag_show_##_name(const u8 *pld, u16 pld_len, char *buf) \ -+{ \ -+ return sc_tag_show_boolts(pld, pld_len, buf, &sc_##_name); \ -+} \ -+static ssize_t sc_tag_store_##_name(const u8 *pld, u16 pld_len, const char *buf, size_t count) \ -+{ \ -+ return sc_tag_store_boolts(pld, pld_len, buf, count, &sc_##_name); \ -+} -+ -+SC_TAG_SHOW_STORE_U32TVS_FUNCS(uartspeeds) -+SC_TAG_SHOW_STORE_U32TVS_FUNCS(bootdevices) -+SC_TAG_SHOW_STORE_BOOLTS_FUNCS(bootkey) -+SC_TAG_SHOW_STORE_BOOLTS_FUNCS(cpumode) -+SC_TAG_SHOW_STORE_BOOLTS_FUNCS(bootproto) -+SC_TAG_SHOW_STORE_BOOLTS_FUNCS(booter) -+SC_TAG_SHOW_STORE_BOOLTS_FUNCS(silent_boot) -+ -+static ssize_t sc_tag_show_bootdelays(const u8 *pld, u16 pld_len, char *buf) -+{ -+ const char *fmt; -+ char *out = buf; -+ u32 data; // cpu-endian -+ int i; -+ -+ if (sizeof(data) != pld_len) -+ return -EINVAL; -+ -+ read_lock(&sc_bufrwl); -+ data = *(u32 *)pld; // pld aliases sc_buf -+ read_unlock(&sc_bufrwl); -+ -+ for (i = RB_BOOT_DELAY_MIN; i <= RB_BOOT_DELAY_MAX; i++) { -+ fmt = (i == data) ? "[%d] " : "%d "; -+ out += sprintf(out, fmt, i); -+ } -+ -+ out += sprintf(out, "\n"); -+ return out - buf; -+} -+ -+static ssize_t sc_tag_store_bootdelays(const u8 *pld, u16 pld_len, const char *buf, size_t count) -+{ -+ u32 data; // cpu-endian -+ int ret; -+ -+ if (sizeof(data) != pld_len) -+ return -EINVAL; -+ -+ ret = kstrtou32(buf, 10, &data); -+ if (ret) -+ return ret; -+ -+ if ((data < RB_BOOT_DELAY_MIN) || (RB_BOOT_DELAY_MAX < data)) -+ return -EINVAL; -+ -+ write_lock(&sc_bufrwl); -+ *(u32 *)pld = data; // pld aliases sc_buf -+ RB_SC_CLRCRC(); -+ write_unlock(&sc_bufrwl); -+ -+ return count; -+} -+ -+/* Support CPU frequency accessors only when the tag format has been asserted */ -+#if defined(CONFIG_ATH79) -+/* Use the same letter-based nomenclature as RouterBOOT */ -+static struct sc_u32tvs const sc_cpufreq_indexes_ath79_9x[] = { -+ RB_SC_TVS(RB_CPU_FREQ_IDX_ATH79_9X_A, "a"), -+ RB_SC_TVS(RB_CPU_FREQ_IDX_ATH79_9X_B, "b"), -+ RB_SC_TVS(RB_CPU_FREQ_IDX_ATH79_9X_C, "c"), -+ RB_SC_TVS(RB_CPU_FREQ_IDX_ATH79_9X_D, "d"), -+ RB_SC_TVS(RB_CPU_FREQ_IDX_ATH79_9X_E, "e"), -+ RB_SC_TVS(RB_CPU_FREQ_IDX_ATH79_9X_F, "f"), -+}; -+ -+static struct sc_u32tvs const sc_cpufreq_indexes_ath79_7x[] = { -+ RB_SC_TVS(RB_CPU_FREQ_IDX_ATH79_7X_A, "a"), -+ RB_SC_TVS(RB_CPU_FREQ_IDX_ATH79_7X_B, "b"), -+ RB_SC_TVS(RB_CPU_FREQ_IDX_ATH79_7X_C, "c"), -+ RB_SC_TVS(RB_CPU_FREQ_IDX_ATH79_7X_D, "d"), -+ RB_SC_TVS(RB_CPU_FREQ_IDX_ATH79_7X_E, "e"), -+ RB_SC_TVS(RB_CPU_FREQ_IDX_ATH79_7X_F, "f"), -+ RB_SC_TVS(RB_CPU_FREQ_IDX_ATH79_7X_G, "g"), -+ RB_SC_TVS(RB_CPU_FREQ_IDX_ATH79_7X_H, "h"), -+}; -+ -+static int sc_tag_cpufreq_ath79_arraysize(void) -+{ -+ int idx_max; -+ -+ if (ATH79_SOC_AR7161 == ath79_soc) -+ idx_max = RB_CPU_FREQ_IDX_ATH79_7X_AR7161_MAX+1; -+ else if (soc_is_ar724x()) -+ idx_max = RB_CPU_FREQ_IDX_ATH79_7X_AR724X_MAX+1; -+ else if (soc_is_ar9344()) -+ idx_max = RB_CPU_FREQ_IDX_ATH79_9X_AR9334_MAX+1; -+ else if (soc_is_qca953x()) -+ idx_max = RB_CPU_FREQ_IDX_ATH79_9X_QCA953X_MAX+1; -+ else if (soc_is_qca9556()) -+ idx_max = RB_CPU_FREQ_IDX_ATH79_9X_QCA9556_MAX+1; -+ else if (soc_is_qca9558()) -+ idx_max = RB_CPU_FREQ_IDX_ATH79_9X_QCA9558_MAX+1; -+ else -+ idx_max = -EOPNOTSUPP; -+ -+ return idx_max; -+} -+ -+static ssize_t sc_tag_show_cpufreq_indexes(const u8 *pld, u16 pld_len, char *buf) -+{ -+ const struct sc_u32tvs *tvs; -+ -+ if (soc_is_ar71xx() || soc_is_ar724x()) -+ tvs = sc_cpufreq_indexes_ath79_7x; -+ else -+ tvs = sc_cpufreq_indexes_ath79_9x; -+ -+ return sc_tag_show_u32tvs(pld, pld_len, buf, tvs, sc_tag_cpufreq_ath79_arraysize()); -+} -+ -+static ssize_t sc_tag_store_cpufreq_indexes(const u8 *pld, u16 pld_len, const char *buf, size_t count) -+{ -+ const struct sc_u32tvs *tvs; -+ -+ if (soc_is_ar71xx() || soc_is_ar724x()) -+ tvs = sc_cpufreq_indexes_ath79_7x; -+ else -+ tvs = sc_cpufreq_indexes_ath79_9x; -+ -+ return sc_tag_store_u32tvs(pld, pld_len, buf, count, tvs, sc_tag_cpufreq_ath79_arraysize()); -+} -+#else -+ /* By default we only show the raw value to help with reverse-engineering */ -+ #define sc_tag_show_cpufreq_indexes routerboot_tag_show_u32s -+ #define sc_tag_store_cpufreq_indexes NULL -+#endif -+ -+static ssize_t sc_attr_show(struct kobject *kobj, struct kobj_attribute *attr, -+ char *buf); -+static ssize_t sc_attr_store(struct kobject *kobj, struct kobj_attribute *attr, -+ const char *buf, size_t count); -+ -+/* Array of known tags to publish in sysfs */ -+static struct sc_attr { -+ const u16 tag_id; -+ /* sysfs tag show attribute. Must lock sc_buf when dereferencing pld */ -+ ssize_t (* const tshow)(const u8 *pld, u16 pld_len, char *buf); -+ /* sysfs tag store attribute. Must lock sc_buf when dereferencing pld */ -+ ssize_t (* const tstore)(const u8 *pld, u16 pld_len, const char *buf, size_t count); -+ struct kobj_attribute kattr; -+ u16 pld_ofs; -+ u16 pld_len; -+} sc_attrs[] = { -+ { -+ .tag_id = RB_SCID_UART_SPEED, -+ .tshow = sc_tag_show_uartspeeds, -+ .tstore = sc_tag_store_uartspeeds, -+ .kattr = __ATTR(uart_speed, RB_SC_RMODE|RB_SC_WMODE, sc_attr_show, sc_attr_store), -+ }, { -+ .tag_id = RB_SCID_BOOT_DELAY, -+ .tshow = sc_tag_show_bootdelays, -+ .tstore = sc_tag_store_bootdelays, -+ .kattr = __ATTR(boot_delay, RB_SC_RMODE|RB_SC_WMODE, sc_attr_show, sc_attr_store), -+ }, { -+ .tag_id = RB_SCID_BOOT_DEVICE, -+ .tshow = sc_tag_show_bootdevices, -+ .tstore = sc_tag_store_bootdevices, -+ .kattr = __ATTR(boot_device, RB_SC_RMODE|RB_SC_WMODE, sc_attr_show, sc_attr_store), -+ }, { -+ .tag_id = RB_SCID_BOOT_KEY, -+ .tshow = sc_tag_show_bootkey, -+ .tstore = sc_tag_store_bootkey, -+ .kattr = __ATTR(boot_key, RB_SC_RMODE|RB_SC_WMODE, sc_attr_show, sc_attr_store), -+ }, { -+ .tag_id = RB_SCID_CPU_MODE, -+ .tshow = sc_tag_show_cpumode, -+ .tstore = sc_tag_store_cpumode, -+ .kattr = __ATTR(cpu_mode, RB_SC_RMODE|RB_SC_WMODE, sc_attr_show, sc_attr_store), -+ }, { -+ .tag_id = RB_SCID_BIOS_VERSION, -+ .tshow = routerboot_tag_show_string, -+ .tstore = NULL, -+ .kattr = __ATTR(bios_version, RB_SC_RMODE, sc_attr_show, NULL), -+ }, { -+ .tag_id = RB_SCID_BOOT_PROTOCOL, -+ .tshow = sc_tag_show_bootproto, -+ .tstore = sc_tag_store_bootproto, -+ .kattr = __ATTR(boot_proto, RB_SC_RMODE|RB_SC_WMODE, sc_attr_show, sc_attr_store), -+ }, { -+ .tag_id = RB_SCID_CPU_FREQ_IDX, -+ .tshow = sc_tag_show_cpufreq_indexes, -+ .tstore = sc_tag_store_cpufreq_indexes, -+ .kattr = __ATTR(cpufreq_index, RB_SC_RMODE|RB_SC_WMODE, sc_attr_show, sc_attr_store), -+ }, { -+ .tag_id = RB_SCID_BOOTER, -+ .tshow = sc_tag_show_booter, -+ .tstore = sc_tag_store_booter, -+ .kattr = __ATTR(booter, RB_SC_RMODE|RB_SC_WMODE, sc_attr_show, sc_attr_store), -+ }, { -+ .tag_id = RB_SCID_SILENT_BOOT, -+ .tshow = sc_tag_show_silent_boot, -+ .tstore = sc_tag_store_silent_boot, -+ .kattr = __ATTR(silent_boot, RB_SC_RMODE|RB_SC_WMODE, sc_attr_show, sc_attr_store), -+ }, -+}; -+ -+static ssize_t sc_attr_show(struct kobject *kobj, struct kobj_attribute *attr, -+ char *buf) -+{ -+ const struct sc_attr *sc_attr; -+ const u8 *pld; -+ u16 pld_len; -+ -+ sc_attr = container_of(attr, typeof(*sc_attr), kattr); -+ -+ if (!sc_attr->pld_len) -+ return -ENOENT; -+ -+ pld = sc_buf + sc_attr->pld_ofs; // pld aliases sc_buf -> lock! -+ pld_len = sc_attr->pld_len; -+ -+ return sc_attr->tshow(pld, pld_len, buf); -+} -+ -+static ssize_t sc_attr_store(struct kobject *kobj, struct kobj_attribute *attr, -+ const char *buf, size_t count) -+{ -+ const struct sc_attr *sc_attr; -+ const u8 *pld; -+ u16 pld_len; -+ -+ if (!RB_SC_HAS_WRITE_SUPPORT) -+ return -EOPNOTSUPP; -+ -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EACCES; -+ -+ sc_attr = container_of(attr, typeof(*sc_attr), kattr); -+ -+ if (!sc_attr->tstore) -+ return -EOPNOTSUPP; -+ -+ if (!sc_attr->pld_len) -+ return -ENOENT; -+ -+ pld = sc_buf + sc_attr->pld_ofs; // pld aliases sc_buf -> lock! -+ pld_len = sc_attr->pld_len; -+ -+ return sc_attr->tstore(pld, pld_len, buf, count); -+} -+ -+/* -+ * Shows the current buffer status: -+ * "clean": the buffer is in sync with the mtd data -+ * "dirty": the buffer is out of sync with the mtd data -+ */ -+static ssize_t sc_commit_show(struct kobject *kobj, struct kobj_attribute *attr, -+ char *buf) -+{ -+ const char *str; -+ char *out = buf; -+ u32 crc; -+ -+ read_lock(&sc_bufrwl); -+ crc = RB_SC_GETCRC(); -+ read_unlock(&sc_bufrwl); -+ -+ str = (crc) ? "clean" : "dirty"; -+ out += sprintf(out, "%s\n", str); -+ -+ return out - buf; -+} -+ -+/* -+ * Performs buffer flushing: -+ * This routine expects an input compatible with kstrtobool(). -+ * - a "false" input discards the current changes and reads data back from mtd. -+ * - a "true" input commits the current changes to mtd. -+ * If there is no pending changes, this routine is a no-op. -+ * Handling failures is left as an exercise to userspace. -+ */ -+static ssize_t sc_commit_store(struct kobject *kobj, struct kobj_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct mtd_info *mtd; -+ struct erase_info ei; -+ size_t bytes_rw, ret = count; -+ bool flush; -+ u32 crc; -+ -+ if (!RB_SC_HAS_WRITE_SUPPORT) -+ return -EOPNOTSUPP; -+ -+ read_lock(&sc_bufrwl); -+ crc = RB_SC_GETCRC(); -+ read_unlock(&sc_bufrwl); -+ -+ if (crc) -+ return count; // NO-OP -+ -+ ret = kstrtobool(buf, &flush); -+ if (ret) -+ return ret; -+ -+ mtd = get_mtd_device_nm(RB_MTD_SOFT_CONFIG); // TODO allow override -+ if (IS_ERR(mtd)) -+ return -ENODEV; -+ -+ write_lock(&sc_bufrwl); -+ if (!flush) // reread -+ ret = mtd_read(mtd, 0, mtd->size, &bytes_rw, sc_buf); -+ else { // crc32 + commit -+ /* -+ * CRC32 is computed on the entire buffer, excluding the CRC -+ * value itself. CRC is already null when we reach this point, -+ * so we can compute the CRC32 on the buffer as is. -+ * The expected CRC32 is Ethernet FCS style, meaning the seed is -+ * ~0 and the final result is also bitflipped. -+ */ -+ -+ crc = ~crc32(~0, sc_buf, sc_buflen); -+ RB_SC_SETCRC(crc); -+ -+ /* -+ * The soft_config partition is assumed to be entirely contained -+ * in a single eraseblock. -+ */ -+ -+ ei.addr = 0; -+ ei.len = mtd->size; -+ ret = mtd_erase(mtd, &ei); -+ if (!ret) -+ ret = mtd_write(mtd, 0, mtd->size, &bytes_rw, sc_buf); -+ -+ /* -+ * Handling mtd_write() failure here is a tricky situation. The -+ * proposed approach is to let userspace deal with retrying, -+ * with the caveat that it must try to flush the buffer again as -+ * rereading the mtd contents could potentially read garbage. -+ * The rationale is: even if we keep a shadow buffer of the -+ * original content, there is no guarantee that we will ever be -+ * able to write it anyway. -+ * Regardless, it appears that RouterBOOT will ignore an invalid -+ * soft_config (including a completely wiped segment) and will -+ * write back factory defaults when it happens. -+ */ -+ } -+ write_unlock(&sc_bufrwl); -+ -+ put_mtd_device(mtd); -+ -+ if (ret) -+ goto mtdfail; -+ -+ if (bytes_rw != sc_buflen) { -+ ret = -EIO; -+ goto mtdfail; -+ } -+ -+ return count; -+ -+mtdfail: -+ RB_SC_CLRCRC(); // mark buffer content as dirty/invalid -+ return ret; -+} -+ -+static struct kobj_attribute sc_kattrcommit = __ATTR(commit, RB_SC_RMODE|RB_SC_WMODE, sc_commit_show, sc_commit_store); -+ -+int rb_softconfig_init(struct kobject *rb_kobj, struct mtd_info *mtd) -+{ -+ size_t bytes_read, buflen; -+ const u8 *buf; -+ int i, ret; -+ u32 magic; -+ -+ sc_buf = NULL; -+ sc_kobj = NULL; -+ -+ ret = __get_mtd_device(mtd); -+ if (ret) -+ return -ENODEV; -+ -+ sc_buflen = mtd->size; -+ sc_buf = kmalloc(sc_buflen, GFP_KERNEL); -+ if (!sc_buf) { -+ __put_mtd_device(mtd); -+ return -ENOMEM; -+ } -+ -+ ret = mtd_read(mtd, 0, sc_buflen, &bytes_read, sc_buf); -+ __put_mtd_device(mtd); -+ -+ if (ret) -+ goto fail; -+ -+ if (bytes_read != sc_buflen) { -+ ret = -EIO; -+ goto fail; -+ } -+ -+ /* Check we have what we expect */ -+ magic = *(const u32 *)sc_buf; -+ if (RB_MAGIC_SOFT != magic) { -+ ret = -EINVAL; -+ goto fail; -+ } -+ -+ /* Skip magic and 32bit CRC located immediately after */ -+ buf = sc_buf + (sizeof(magic) + sizeof(u32)); -+ buflen = sc_buflen - (sizeof(magic) + sizeof(u32)); -+ -+ /* Populate sysfs */ -+ ret = -ENOMEM; -+ sc_kobj = kobject_create_and_add(RB_MTD_SOFT_CONFIG, rb_kobj); -+ if (!sc_kobj) -+ goto fail; -+ -+ rwlock_init(&sc_bufrwl); -+ -+ /* Locate and publish all known tags */ -+ for (i = 0; i < ARRAY_SIZE(sc_attrs); i++) { -+ ret = routerboot_tag_find(buf, buflen, sc_attrs[i].tag_id, -+ &sc_attrs[i].pld_ofs, &sc_attrs[i].pld_len); -+ if (ret) { -+ sc_attrs[i].pld_ofs = sc_attrs[i].pld_len = 0; -+ continue; -+ } -+ -+ /* Account for skipped magic and crc32 */ -+ sc_attrs[i].pld_ofs += sizeof(magic) + sizeof(u32); -+ -+ ret = sysfs_create_file(sc_kobj, &sc_attrs[i].kattr.attr); -+ if (ret) -+ pr_warn(RB_SC_PR_PFX "Could not create %s sysfs entry (%d)\n", -+ sc_attrs[i].kattr.attr.name, ret); -+ } -+ -+ /* Finally add the 'commit' attribute */ -+ if (RB_SC_HAS_WRITE_SUPPORT) { -+ ret = sysfs_create_file(sc_kobj, &sc_kattrcommit.attr); -+ if (ret) { -+ pr_err(RB_SC_PR_PFX "Could not create %s sysfs entry (%d), aborting!\n", -+ sc_kattrcommit.attr.name, ret); -+ goto sysfsfail; // required attribute -+ } -+ } -+ -+ pr_info("MikroTik RouterBOARD software configuration sysfs driver v" RB_SOFTCONFIG_VER "\n"); -+ -+ return 0; -+ -+sysfsfail: -+ kobject_put(sc_kobj); -+ sc_kobj = NULL; -+fail: -+ kfree(sc_buf); -+ sc_buf = NULL; -+ return ret; -+} -+ -+void rb_softconfig_exit(void) -+{ -+ kobject_put(sc_kobj); -+ sc_kobj = NULL; -+ kfree(sc_buf); -+ sc_buf = NULL; -+} -diff --git a/drivers/platform/mikrotik/routerboot.c b/drivers/platform/mikrotik/routerboot.c -new file mode 100644 -index 000000000000..96f24609161b ---- /dev/null -+++ b/drivers/platform/mikrotik/routerboot.c -@@ -0,0 +1,251 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Driver for MikroTik RouterBoot flash data. Common routines. -+ * -+ * Copyright (C) 2020 Thibaut VARÈNE -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "routerboot.h" -+ -+static struct kobject *rb_kobj; -+ -+/** -+ * routerboot_tag_find() - Locate a given tag in routerboot config data. -+ * @bufhead: the buffer to look into. Must start with a tag node. -+ * @buflen: size of bufhead -+ * @tag_id: the tag identifier to look for -+ * @pld_ofs: will be updated with tag payload offset in bufhead, if tag found -+ * @pld_len: will be updated with tag payload size, if tag found -+ * -+ * This incarnation of tag_find() does only that: it finds a specific routerboot -+ * tag node in the input buffer. Routerboot tag nodes are u32 values: -+ * - The low nibble is the tag identification number, -+ * - The high nibble is the tag payload length (node excluded) in bytes. -+ * The payload immediately follows the tag node. Tag nodes are 32bit-aligned. -+ * The returned pld_ofs will always be aligned. pld_len may not end on 32bit -+ * boundary (the only known case is when parsing ERD data). -+ * The nodes are cpu-endian on the flash media. The payload is cpu-endian when -+ * applicable. Tag nodes are not ordered (by ID) on flash. -+ * -+ * Return: 0 on success (tag found) or errno -+ */ -+int routerboot_tag_find(const u8 *bufhead, const size_t buflen, const u16 tag_id, -+ u16 *pld_ofs, u16 *pld_len) -+{ -+ const u32 *datum, *bufend; -+ u32 node; -+ u16 id, len; -+ int ret; -+ -+ if (!bufhead || !tag_id) -+ return -EINVAL; -+ -+ ret = -ENOENT; -+ datum = (const u32 *)bufhead; -+ bufend = (const u32 *)(bufhead + buflen); -+ -+ while (datum < bufend) { -+ node = *datum++; -+ -+ /* Tag list ends with null node */ -+ if (!node) -+ break; -+ -+ id = node & 0xFFFF; -+ len = node >> 16; -+ -+ if (tag_id == id) { -+ if (datum >= bufend) -+ break; -+ -+ if (pld_ofs) -+ *pld_ofs = (u16)((u8 *)datum - bufhead); -+ if (pld_len) -+ *pld_len = len; -+ -+ ret = 0; -+ break; -+ } -+ -+ /* -+ * The only known situation where len may not end on 32bit -+ * boundary is within ERD data. Since we're only extracting -+ * one tag (the first and only one) from that data, we should -+ * never need to forcefully ALIGN(). Do it anyway, this is not a -+ * performance path. -+ */ -+ len = ALIGN(len, sizeof(*datum)); -+ datum += len / sizeof(*datum); -+ } -+ -+ return ret; -+} -+ -+/** -+ * routerboot_rle_decode() - Simple RLE (MikroTik variant) decoding routine. -+ * @in: input buffer to decode -+ * @inlen: size of in -+ * @out: output buffer to write decoded data to -+ * @outlen: pointer to out size when function is called, will be updated with -+ * size of decoded output on return -+ * -+ * MikroTik's variant of RLE operates as follows, considering a signed run byte: -+ * - positive run => classic RLE -+ * - negative run => the next - bytes must be copied verbatim -+ * The API is matched to the lzo1x routines for convenience. -+ * -+ * NB: The output buffer cannot overlap with the input buffer. -+ * -+ * Return: 0 on success or errno -+ */ -+int routerboot_rle_decode(const u8 *in, size_t inlen, u8 *out, size_t *outlen) -+{ -+ int ret, run, nbytes; // use native types for speed -+ u8 byte; -+ -+ if (!in || (inlen < 2) || !out) -+ return -EINVAL; -+ -+ ret = -ENOSPC; -+ nbytes = 0; -+ while (inlen >= 2) { -+ run = *in++; -+ inlen--; -+ -+ /* Verbatim copies */ -+ if (run & 0x80) { -+ /* Invert run byte sign */ -+ run = ~run & 0xFF; -+ run++; -+ -+ if (run > inlen) -+ goto fail; -+ -+ inlen -= run; -+ -+ nbytes += run; -+ if (nbytes > *outlen) -+ goto fail; -+ -+ /* Basic memcpy */ -+ while (run-- > 0) -+ *out++ = *in++; -+ } -+ /* Stream of half-words RLE: . run == 0 is ignored */ -+ else { -+ byte = *in++; -+ inlen--; -+ -+ nbytes += run; -+ if (nbytes > *outlen) -+ goto fail; -+ -+ while (run-- > 0) -+ *out++ = byte; -+ } -+ } -+ -+ ret = 0; -+fail: -+ *outlen = nbytes; -+ return ret; -+} -+ -+static void routerboot_mtd_notifier_add(struct mtd_info *mtd) -+{ -+ /* Currently routerboot is only known to live on NOR flash */ -+ if (mtd->type != MTD_NORFLASH) -+ return; -+ -+ /* -+ * We ignore the following return values and always register. -+ * These init() routines are designed so that their failed state is -+ * always manageable by the corresponding exit() calls. -+ * Notifier is called with MTD mutex held: use __get/__put variants. -+ * TODO: allow partition names override -+ */ -+ if (!strcmp(mtd->name, RB_MTD_HARD_CONFIG)) -+ rb_hardconfig_init(rb_kobj, mtd); -+ else if (!strcmp(mtd->name, RB_MTD_SOFT_CONFIG)) -+ rb_softconfig_init(rb_kobj, mtd); -+} -+ -+static void routerboot_mtd_notifier_remove(struct mtd_info *mtd) -+{ -+ if (mtd->type != MTD_NORFLASH) -+ return; -+ -+ if (!strcmp(mtd->name, RB_MTD_HARD_CONFIG)) -+ rb_hardconfig_exit(); -+ else if (!strcmp(mtd->name, RB_MTD_SOFT_CONFIG)) -+ rb_softconfig_exit(); -+} -+ -+/* Note: using a notifier prevents qualifying init()/exit() functions with __init/__exit */ -+static struct mtd_notifier routerboot_mtd_notifier = { -+ .add = routerboot_mtd_notifier_add, -+ .remove = routerboot_mtd_notifier_remove, -+}; -+ -+static int __init routerboot_init(void) -+{ -+ rb_kobj = kobject_create_and_add("mikrotik", firmware_kobj); -+ if (!rb_kobj) -+ return -ENOMEM; -+ -+ register_mtd_user(&routerboot_mtd_notifier); -+ -+ return 0; -+} -+ -+static void __exit routerboot_exit(void) -+{ -+ unregister_mtd_user(&routerboot_mtd_notifier); -+ /* Exit routines are idempotent */ -+ rb_softconfig_exit(); -+ rb_hardconfig_exit(); -+ kobject_put(rb_kobj); // recursive afaict -+} -+ -+/* Common routines */ -+ -+ssize_t routerboot_tag_show_string(const u8 *pld, u16 pld_len, char *buf) -+{ -+ return scnprintf(buf, pld_len+1, "%s\n", pld); -+} -+ -+ssize_t routerboot_tag_show_u32s(const u8 *pld, u16 pld_len, char *buf) -+{ -+ char *out = buf; -+ u32 *data; // cpu-endian -+ -+ /* Caller ensures pld_len > 0 */ -+ if (pld_len % sizeof(*data)) -+ return -EINVAL; -+ -+ data = (u32 *)pld; -+ -+ do { -+ out += sprintf(out, "0x%08x\n", *data); -+ data++; -+ } while ((pld_len -= sizeof(*data))); -+ -+ return out - buf; -+} -+ -+module_init(routerboot_init); -+module_exit(routerboot_exit); -+ -+MODULE_LICENSE("GPL v2"); -+MODULE_DESCRIPTION("MikroTik RouterBoot sysfs support"); -+MODULE_AUTHOR("Thibaut VARENE"); -diff --git a/drivers/platform/mikrotik/routerboot.h b/drivers/platform/mikrotik/routerboot.h -new file mode 100644 -index 000000000000..723f993eebe2 ---- /dev/null -+++ b/drivers/platform/mikrotik/routerboot.h -@@ -0,0 +1,38 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Common definitions for MikroTik RouterBoot data. -+ * -+ * Copyright (C) 2020 Thibaut VARÈNE -+ */ -+ -+ -+#ifndef _ROUTERBOOT_H_ -+#define _ROUTERBOOT_H_ -+ -+#include -+ -+// these magic values are stored in cpu-endianness on flash -+#define RB_MAGIC_HARD (('H') | ('a' << 8) | ('r' << 16) | ('d' << 24)) -+#define RB_MAGIC_SOFT (('S') | ('o' << 8) | ('f' << 16) | ('t' << 24)) -+#define RB_MAGIC_LZOR (('L') | ('Z' << 8) | ('O' << 16) | ('R' << 24)) -+#define RB_MAGIC_LZ77 (('L' << 24) | ('Z' << 16) | ('7' << 8) | ('7')) -+#define RB_MAGIC_ERD (('E' << 16) | ('R' << 8) | ('D')) -+ -+#define RB_ART_SIZE 0x10000 -+ -+#define RB_MTD_HARD_CONFIG "hard_config" -+#define RB_MTD_SOFT_CONFIG "soft_config" -+ -+int routerboot_tag_find(const u8 *bufhead, const size_t buflen, const u16 tag_id, u16 *pld_ofs, u16 *pld_len); -+int routerboot_rle_decode(const u8 *in, size_t inlen, u8 *out, size_t *outlen); -+ -+int rb_hardconfig_init(struct kobject *rb_kobj, struct mtd_info *mtd); -+void rb_hardconfig_exit(void); -+ -+int rb_softconfig_init(struct kobject *rb_kobj, struct mtd_info *mtd); -+void rb_softconfig_exit(void); -+ -+ssize_t routerboot_tag_show_string(const u8 *pld, u16 pld_len, char *buf); -+ssize_t routerboot_tag_show_u32s(const u8 *pld, u16 pld_len, char *buf); -+ -+#endif /* _ROUTERBOOT_H_ */ -diff --git a/drivers/ssb/fallback-sprom.c b/drivers/ssb/fallback-sprom.c -new file mode 100644 -index 000000000000..9c2511febe18 ---- /dev/null -+++ b/drivers/ssb/fallback-sprom.c -@@ -0,0 +1,745 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * SSB Fallback SPROM Driver -+ * -+ * Copyright (C) 2020 Álvaro Fernández Rojas -+ * Copyright (C) 2014 Jonas Gorski -+ * Copyright (C) 2008 Maxime Bizon -+ * Copyright (C) 2008 Florian Fainelli -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "fallback-sprom.h" -+ -+#define SSB_FBS_MAX_SIZE 440 -+ -+/* Get the word-offset for a SSB_SPROM_XXX define. */ -+#define SPOFF(offset) ((offset) / sizeof(u16)) -+/* Helper to extract some _offset, which is one of the SSB_SPROM_XXX defines. */ -+#define SPEX16(_outvar, _offset, _mask, _shift) \ -+ out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift)) -+#define SPEX32(_outvar, _offset, _mask, _shift) \ -+ out->_outvar = ((((u32)in[SPOFF((_offset)+2)] << 16 | \ -+ in[SPOFF(_offset)]) & (_mask)) >> (_shift)) -+#define SPEX(_outvar, _offset, _mask, _shift) \ -+ SPEX16(_outvar, _offset, _mask, _shift) -+ -+#define SPEX_ARRAY8(_field, _offset, _mask, _shift) \ -+ do { \ -+ SPEX(_field[0], _offset + 0, _mask, _shift); \ -+ SPEX(_field[1], _offset + 2, _mask, _shift); \ -+ SPEX(_field[2], _offset + 4, _mask, _shift); \ -+ SPEX(_field[3], _offset + 6, _mask, _shift); \ -+ SPEX(_field[4], _offset + 8, _mask, _shift); \ -+ SPEX(_field[5], _offset + 10, _mask, _shift); \ -+ SPEX(_field[6], _offset + 12, _mask, _shift); \ -+ SPEX(_field[7], _offset + 14, _mask, _shift); \ -+ } while (0) -+ -+struct ssb_fbs { -+ struct device *dev; -+ struct list_head list; -+ struct ssb_sprom sprom; -+ u32 pci_bus; -+ u32 pci_dev; -+ bool devid_override; -+}; -+ -+static DEFINE_SPINLOCK(ssb_fbs_lock); -+static struct list_head ssb_fbs_list = LIST_HEAD_INIT(ssb_fbs_list); -+ -+int ssb_get_fallback_sprom(struct ssb_bus *bus, struct ssb_sprom *out) -+{ -+ struct ssb_fbs *pos; -+ u32 pci_bus, pci_dev; -+ -+ if (bus->bustype != SSB_BUSTYPE_PCI) -+ return -ENOENT; -+ -+ pci_bus = bus->host_pci->bus->number; -+ pci_dev = PCI_SLOT(bus->host_pci->devfn); -+ -+ list_for_each_entry(pos, &ssb_fbs_list, list) { -+ if (pos->pci_bus != pci_bus || -+ pos->pci_dev != pci_dev) -+ continue; -+ -+ if (pos->devid_override) -+ bus->host_pci->device = pos->sprom.dev_id; -+ -+ memcpy(out, &pos->sprom, sizeof(struct ssb_sprom)); -+ dev_info(pos->dev, "requested by [%x:%x]", -+ pos->pci_bus, pos->pci_dev); -+ -+ return 0; -+ } -+ -+ pr_err("unable to fill SPROM for [%x:%x]\n", pci_bus, pci_dev); -+ -+ return -EINVAL; -+} -+ -+static s8 sprom_extract_antgain(u8 sprom_revision, const u16 *in, u16 offset, -+ u16 mask, u16 shift) -+{ -+ u16 v; -+ u8 gain; -+ -+ v = in[SPOFF(offset)]; -+ gain = (v & mask) >> shift; -+ if (gain == 0xFF) -+ gain = 2; /* If unset use 2dBm */ -+ if (sprom_revision == 1) { -+ /* Convert to Q5.2 */ -+ gain <<= 2; -+ } else { -+ /* Q5.2 Fractional part is stored in 0xC0 */ -+ gain = ((gain & 0xC0) >> 6) | ((gain & 0x3F) << 2); -+ } -+ -+ return (s8)gain; -+} -+ -+static void sprom_extract_r23(struct ssb_sprom *out, const u16 *in) -+{ -+ SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0); -+ SPEX(opo, SSB_SPROM2_OPO, SSB_SPROM2_OPO_VALUE, 0); -+ SPEX(pa1lob0, SSB_SPROM2_PA1LOB0, 0xFFFF, 0); -+ SPEX(pa1lob1, SSB_SPROM2_PA1LOB1, 0xFFFF, 0); -+ SPEX(pa1lob2, SSB_SPROM2_PA1LOB2, 0xFFFF, 0); -+ SPEX(pa1hib0, SSB_SPROM2_PA1HIB0, 0xFFFF, 0); -+ SPEX(pa1hib1, SSB_SPROM2_PA1HIB1, 0xFFFF, 0); -+ SPEX(pa1hib2, SSB_SPROM2_PA1HIB2, 0xFFFF, 0); -+ SPEX(maxpwr_ah, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_HI, 0); -+ SPEX(maxpwr_al, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_LO, -+ SSB_SPROM2_MAXP_A_LO_SHIFT); -+} -+ -+static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) -+{ -+ SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0); -+ SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A, -+ SSB_SPROM1_ETHPHY_ET1A_SHIFT); -+ SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14); -+ SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15); -+ SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0); -+ SPEX(board_type, SSB_SPROM1_SPID, 0xFFFF, 0); -+ if (out->revision == 1) -+ SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE, -+ SSB_SPROM1_BINF_CCODE_SHIFT); -+ SPEX(ant_available_a, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTA, -+ SSB_SPROM1_BINF_ANTA_SHIFT); -+ SPEX(ant_available_bg, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTBG, -+ SSB_SPROM1_BINF_ANTBG_SHIFT); -+ SPEX(pa0b0, SSB_SPROM1_PA0B0, 0xFFFF, 0); -+ SPEX(pa0b1, SSB_SPROM1_PA0B1, 0xFFFF, 0); -+ SPEX(pa0b2, SSB_SPROM1_PA0B2, 0xFFFF, 0); -+ SPEX(pa1b0, SSB_SPROM1_PA1B0, 0xFFFF, 0); -+ SPEX(pa1b1, SSB_SPROM1_PA1B1, 0xFFFF, 0); -+ SPEX(pa1b2, SSB_SPROM1_PA1B2, 0xFFFF, 0); -+ SPEX(gpio0, SSB_SPROM1_GPIOA, SSB_SPROM1_GPIOA_P0, 0); -+ SPEX(gpio1, SSB_SPROM1_GPIOA, SSB_SPROM1_GPIOA_P1, -+ SSB_SPROM1_GPIOA_P1_SHIFT); -+ SPEX(gpio2, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P2, 0); -+ SPEX(gpio3, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P3, -+ SSB_SPROM1_GPIOB_P3_SHIFT); -+ SPEX(maxpwr_a, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_A, -+ SSB_SPROM1_MAXPWR_A_SHIFT); -+ SPEX(maxpwr_bg, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_BG, 0); -+ SPEX(itssi_a, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_A, -+ SSB_SPROM1_ITSSI_A_SHIFT); -+ SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG, 0); -+ SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0); -+ -+ SPEX(alpha2[0], SSB_SPROM1_CCODE, 0xff00, 8); -+ SPEX(alpha2[1], SSB_SPROM1_CCODE, 0x00ff, 0); -+ -+ /* Extract the antenna gain values. */ -+ out->antenna_gain.a0 = sprom_extract_antgain(out->revision, in, -+ SSB_SPROM1_AGAIN, -+ SSB_SPROM1_AGAIN_BG, -+ SSB_SPROM1_AGAIN_BG_SHIFT); -+ out->antenna_gain.a1 = sprom_extract_antgain(out->revision, in, -+ SSB_SPROM1_AGAIN, -+ SSB_SPROM1_AGAIN_A, -+ SSB_SPROM1_AGAIN_A_SHIFT); -+ if (out->revision >= 2) -+ sprom_extract_r23(out, in); -+} -+ -+/* Revs 4 5 and 8 have partially shared layout */ -+static void sprom_extract_r458(struct ssb_sprom *out, const u16 *in) -+{ -+ SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01, -+ SSB_SPROM4_TXPID2G0, SSB_SPROM4_TXPID2G0_SHIFT); -+ SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01, -+ SSB_SPROM4_TXPID2G1, SSB_SPROM4_TXPID2G1_SHIFT); -+ SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23, -+ SSB_SPROM4_TXPID2G2, SSB_SPROM4_TXPID2G2_SHIFT); -+ SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23, -+ SSB_SPROM4_TXPID2G3, SSB_SPROM4_TXPID2G3_SHIFT); -+ -+ SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01, -+ SSB_SPROM4_TXPID5GL0, SSB_SPROM4_TXPID5GL0_SHIFT); -+ SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01, -+ SSB_SPROM4_TXPID5GL1, SSB_SPROM4_TXPID5GL1_SHIFT); -+ SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23, -+ SSB_SPROM4_TXPID5GL2, SSB_SPROM4_TXPID5GL2_SHIFT); -+ SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23, -+ SSB_SPROM4_TXPID5GL3, SSB_SPROM4_TXPID5GL3_SHIFT); -+ -+ SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01, -+ SSB_SPROM4_TXPID5G0, SSB_SPROM4_TXPID5G0_SHIFT); -+ SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01, -+ SSB_SPROM4_TXPID5G1, SSB_SPROM4_TXPID5G1_SHIFT); -+ SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23, -+ SSB_SPROM4_TXPID5G2, SSB_SPROM4_TXPID5G2_SHIFT); -+ SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23, -+ SSB_SPROM4_TXPID5G3, SSB_SPROM4_TXPID5G3_SHIFT); -+ -+ SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01, -+ SSB_SPROM4_TXPID5GH0, SSB_SPROM4_TXPID5GH0_SHIFT); -+ SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01, -+ SSB_SPROM4_TXPID5GH1, SSB_SPROM4_TXPID5GH1_SHIFT); -+ SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23, -+ SSB_SPROM4_TXPID5GH2, SSB_SPROM4_TXPID5GH2_SHIFT); -+ SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23, -+ SSB_SPROM4_TXPID5GH3, SSB_SPROM4_TXPID5GH3_SHIFT); -+} -+ -+static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in) -+{ -+ static const u16 pwr_info_offset[] = { -+ SSB_SPROM4_PWR_INFO_CORE0, SSB_SPROM4_PWR_INFO_CORE1, -+ SSB_SPROM4_PWR_INFO_CORE2, SSB_SPROM4_PWR_INFO_CORE3 -+ }; -+ int i; -+ -+ BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) != -+ ARRAY_SIZE(out->core_pwr_info)); -+ -+ SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0); -+ SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A, -+ SSB_SPROM4_ETHPHY_ET1A_SHIFT); -+ SPEX(board_rev, SSB_SPROM4_BOARDREV, 0xFFFF, 0); -+ SPEX(board_type, SSB_SPROM1_SPID, 0xFFFF, 0); -+ if (out->revision == 4) { -+ SPEX(alpha2[0], SSB_SPROM4_CCODE, 0xff00, 8); -+ SPEX(alpha2[1], SSB_SPROM4_CCODE, 0x00ff, 0); -+ SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0); -+ SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0); -+ SPEX(boardflags2_lo, SSB_SPROM4_BFL2LO, 0xFFFF, 0); -+ SPEX(boardflags2_hi, SSB_SPROM4_BFL2HI, 0xFFFF, 0); -+ } else { -+ SPEX(alpha2[0], SSB_SPROM5_CCODE, 0xff00, 8); -+ SPEX(alpha2[1], SSB_SPROM5_CCODE, 0x00ff, 0); -+ SPEX(boardflags_lo, SSB_SPROM5_BFLLO, 0xFFFF, 0); -+ SPEX(boardflags_hi, SSB_SPROM5_BFLHI, 0xFFFF, 0); -+ SPEX(boardflags2_lo, SSB_SPROM5_BFL2LO, 0xFFFF, 0); -+ SPEX(boardflags2_hi, SSB_SPROM5_BFL2HI, 0xFFFF, 0); -+ } -+ SPEX(ant_available_a, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_A, -+ SSB_SPROM4_ANTAVAIL_A_SHIFT); -+ SPEX(ant_available_bg, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_BG, -+ SSB_SPROM4_ANTAVAIL_BG_SHIFT); -+ SPEX(maxpwr_bg, SSB_SPROM4_MAXP_BG, SSB_SPROM4_MAXP_BG_MASK, 0); -+ SPEX(itssi_bg, SSB_SPROM4_MAXP_BG, SSB_SPROM4_ITSSI_BG, -+ SSB_SPROM4_ITSSI_BG_SHIFT); -+ SPEX(maxpwr_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_MAXP_A_MASK, 0); -+ SPEX(itssi_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_ITSSI_A, -+ SSB_SPROM4_ITSSI_A_SHIFT); -+ if (out->revision == 4) { -+ SPEX(gpio0, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P0, 0); -+ SPEX(gpio1, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P1, -+ SSB_SPROM4_GPIOA_P1_SHIFT); -+ SPEX(gpio2, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P2, 0); -+ SPEX(gpio3, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P3, -+ SSB_SPROM4_GPIOB_P3_SHIFT); -+ } else { -+ SPEX(gpio0, SSB_SPROM5_GPIOA, SSB_SPROM5_GPIOA_P0, 0); -+ SPEX(gpio1, SSB_SPROM5_GPIOA, SSB_SPROM5_GPIOA_P1, -+ SSB_SPROM5_GPIOA_P1_SHIFT); -+ SPEX(gpio2, SSB_SPROM5_GPIOB, SSB_SPROM5_GPIOB_P2, 0); -+ SPEX(gpio3, SSB_SPROM5_GPIOB, SSB_SPROM5_GPIOB_P3, -+ SSB_SPROM5_GPIOB_P3_SHIFT); -+ } -+ -+ /* Extract the antenna gain values. */ -+ out->antenna_gain.a0 = sprom_extract_antgain(out->revision, in, -+ SSB_SPROM4_AGAIN01, -+ SSB_SPROM4_AGAIN0, -+ SSB_SPROM4_AGAIN0_SHIFT); -+ out->antenna_gain.a1 = sprom_extract_antgain(out->revision, in, -+ SSB_SPROM4_AGAIN01, -+ SSB_SPROM4_AGAIN1, -+ SSB_SPROM4_AGAIN1_SHIFT); -+ out->antenna_gain.a2 = sprom_extract_antgain(out->revision, in, -+ SSB_SPROM4_AGAIN23, -+ SSB_SPROM4_AGAIN2, -+ SSB_SPROM4_AGAIN2_SHIFT); -+ out->antenna_gain.a3 = sprom_extract_antgain(out->revision, in, -+ SSB_SPROM4_AGAIN23, -+ SSB_SPROM4_AGAIN3, -+ SSB_SPROM4_AGAIN3_SHIFT); -+ -+ /* Extract cores power info info */ -+ for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) { -+ u16 o = pwr_info_offset[i]; -+ -+ SPEX(core_pwr_info[i].itssi_2g, o + SSB_SPROM4_2G_MAXP_ITSSI, -+ SSB_SPROM4_2G_ITSSI, SSB_SPROM4_2G_ITSSI_SHIFT); -+ SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SPROM4_2G_MAXP_ITSSI, -+ SSB_SPROM4_2G_MAXP, 0); -+ -+ SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SPROM4_2G_PA_0, ~0, 0); -+ SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SPROM4_2G_PA_1, ~0, 0); -+ SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SPROM4_2G_PA_2, ~0, 0); -+ SPEX(core_pwr_info[i].pa_2g[3], o + SSB_SPROM4_2G_PA_3, ~0, 0); -+ -+ SPEX(core_pwr_info[i].itssi_5g, o + SSB_SPROM4_5G_MAXP_ITSSI, -+ SSB_SPROM4_5G_ITSSI, SSB_SPROM4_5G_ITSSI_SHIFT); -+ SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SPROM4_5G_MAXP_ITSSI, -+ SSB_SPROM4_5G_MAXP, 0); -+ SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM4_5GHL_MAXP, -+ SSB_SPROM4_5GH_MAXP, 0); -+ SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM4_5GHL_MAXP, -+ SSB_SPROM4_5GL_MAXP, SSB_SPROM4_5GL_MAXP_SHIFT); -+ -+ SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SPROM4_5GL_PA_0, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SPROM4_5GL_PA_1, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SPROM4_5GL_PA_2, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5gl[3], o + SSB_SPROM4_5GL_PA_3, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SPROM4_5G_PA_0, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SPROM4_5G_PA_1, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SPROM4_5G_PA_2, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5g[3], o + SSB_SPROM4_5G_PA_3, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SPROM4_5GH_PA_0, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SPROM4_5GH_PA_1, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SPROM4_5GH_PA_2, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5gh[3], o + SSB_SPROM4_5GH_PA_3, ~0, 0); -+ } -+ -+ sprom_extract_r458(out, in); -+ -+ /* TODO - get remaining rev 4 stuff needed */ -+} -+ -+static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in) -+{ -+ int i; -+ u16 o; -+ static const u16 pwr_info_offset[] = { -+ SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1, -+ SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3 -+ }; -+ BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) != -+ ARRAY_SIZE(out->core_pwr_info)); -+ -+ SPEX(board_rev, SSB_SPROM8_BOARDREV, 0xFFFF, 0); -+ SPEX(board_type, SSB_SPROM1_SPID, 0xFFFF, 0); -+ SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8); -+ SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0); -+ SPEX(boardflags_lo, SSB_SPROM8_BFLLO, 0xFFFF, 0); -+ SPEX(boardflags_hi, SSB_SPROM8_BFLHI, 0xFFFF, 0); -+ SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, 0xFFFF, 0); -+ SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, 0xFFFF, 0); -+ SPEX(ant_available_a, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_A, -+ SSB_SPROM8_ANTAVAIL_A_SHIFT); -+ SPEX(ant_available_bg, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_BG, -+ SSB_SPROM8_ANTAVAIL_BG_SHIFT); -+ SPEX(maxpwr_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_MAXP_BG_MASK, 0); -+ SPEX(itssi_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_ITSSI_BG, -+ SSB_SPROM8_ITSSI_BG_SHIFT); -+ SPEX(maxpwr_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_MAXP_A_MASK, 0); -+ SPEX(itssi_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_ITSSI_A, -+ SSB_SPROM8_ITSSI_A_SHIFT); -+ SPEX(maxpwr_ah, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AH_MASK, 0); -+ SPEX(maxpwr_al, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AL_MASK, -+ SSB_SPROM8_MAXP_AL_SHIFT); -+ SPEX(gpio0, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P0, 0); -+ SPEX(gpio1, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P1, -+ SSB_SPROM8_GPIOA_P1_SHIFT); -+ SPEX(gpio2, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P2, 0); -+ SPEX(gpio3, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P3, -+ SSB_SPROM8_GPIOB_P3_SHIFT); -+ SPEX(tri2g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI2G, 0); -+ SPEX(tri5g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI5G, -+ SSB_SPROM8_TRI5G_SHIFT); -+ SPEX(tri5gl, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GL, 0); -+ SPEX(tri5gh, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GH, -+ SSB_SPROM8_TRI5GH_SHIFT); -+ SPEX(rxpo2g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO2G, 0); -+ SPEX(rxpo5g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO5G, -+ SSB_SPROM8_RXPO5G_SHIFT); -+ SPEX(rssismf2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMF2G, 0); -+ SPEX(rssismc2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMC2G, -+ SSB_SPROM8_RSSISMC2G_SHIFT); -+ SPEX(rssisav2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISAV2G, -+ SSB_SPROM8_RSSISAV2G_SHIFT); -+ SPEX(bxa2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_BXA2G, -+ SSB_SPROM8_BXA2G_SHIFT); -+ SPEX(rssismf5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMF5G, 0); -+ SPEX(rssismc5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMC5G, -+ SSB_SPROM8_RSSISMC5G_SHIFT); -+ SPEX(rssisav5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISAV5G, -+ SSB_SPROM8_RSSISAV5G_SHIFT); -+ SPEX(bxa5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_BXA5G, -+ SSB_SPROM8_BXA5G_SHIFT); -+ SPEX(pa0b0, SSB_SPROM8_PA0B0, 0xFFFF, 0); -+ SPEX(pa0b1, SSB_SPROM8_PA0B1, 0xFFFF, 0); -+ SPEX(pa0b2, SSB_SPROM8_PA0B2, 0xFFFF, 0); -+ SPEX(pa1b0, SSB_SPROM8_PA1B0, 0xFFFF, 0); -+ SPEX(pa1b1, SSB_SPROM8_PA1B1, 0xFFFF, 0); -+ SPEX(pa1b2, SSB_SPROM8_PA1B2, 0xFFFF, 0); -+ SPEX(pa1lob0, SSB_SPROM8_PA1LOB0, 0xFFFF, 0); -+ SPEX(pa1lob1, SSB_SPROM8_PA1LOB1, 0xFFFF, 0); -+ SPEX(pa1lob2, SSB_SPROM8_PA1LOB2, 0xFFFF, 0); -+ SPEX(pa1hib0, SSB_SPROM8_PA1HIB0, 0xFFFF, 0); -+ SPEX(pa1hib1, SSB_SPROM8_PA1HIB1, 0xFFFF, 0); -+ SPEX(pa1hib2, SSB_SPROM8_PA1HIB2, 0xFFFF, 0); -+ SPEX(cck2gpo, SSB_SPROM8_CCK2GPO, 0xFFFF, 0); -+ SPEX32(ofdm2gpo, SSB_SPROM8_OFDM2GPO, 0xFFFFFFFF, 0); -+ SPEX32(ofdm5glpo, SSB_SPROM8_OFDM5GLPO, 0xFFFFFFFF, 0); -+ SPEX32(ofdm5gpo, SSB_SPROM8_OFDM5GPO, 0xFFFFFFFF, 0); -+ SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0); -+ -+ /* Extract the antenna gain values. */ -+ out->antenna_gain.a0 = sprom_extract_antgain(out->revision, in, -+ SSB_SPROM8_AGAIN01, -+ SSB_SPROM8_AGAIN0, -+ SSB_SPROM8_AGAIN0_SHIFT); -+ out->antenna_gain.a1 = sprom_extract_antgain(out->revision, in, -+ SSB_SPROM8_AGAIN01, -+ SSB_SPROM8_AGAIN1, -+ SSB_SPROM8_AGAIN1_SHIFT); -+ out->antenna_gain.a2 = sprom_extract_antgain(out->revision, in, -+ SSB_SPROM8_AGAIN23, -+ SSB_SPROM8_AGAIN2, -+ SSB_SPROM8_AGAIN2_SHIFT); -+ out->antenna_gain.a3 = sprom_extract_antgain(out->revision, in, -+ SSB_SPROM8_AGAIN23, -+ SSB_SPROM8_AGAIN3, -+ SSB_SPROM8_AGAIN3_SHIFT); -+ -+ /* Extract cores power info info */ -+ for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) { -+ o = pwr_info_offset[i]; -+ SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI, -+ SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT); -+ SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI, -+ SSB_SPROM8_2G_MAXP, 0); -+ -+ SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0); -+ SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0); -+ SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0); -+ -+ SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI, -+ SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT); -+ SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI, -+ SSB_SPROM8_5G_MAXP, 0); -+ SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP, -+ SSB_SPROM8_5GH_MAXP, 0); -+ SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP, -+ SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT); -+ -+ SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0); -+ } -+ -+ /* Extract FEM info */ -+ SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G, -+ SSB_SROM8_FEM_TSSIPOS, SSB_SROM8_FEM_TSSIPOS_SHIFT); -+ SPEX(fem.ghz2.extpa_gain, SSB_SPROM8_FEM2G, -+ SSB_SROM8_FEM_EXTPA_GAIN, SSB_SROM8_FEM_EXTPA_GAIN_SHIFT); -+ SPEX(fem.ghz2.pdet_range, SSB_SPROM8_FEM2G, -+ SSB_SROM8_FEM_PDET_RANGE, SSB_SROM8_FEM_PDET_RANGE_SHIFT); -+ SPEX(fem.ghz2.tr_iso, SSB_SPROM8_FEM2G, -+ SSB_SROM8_FEM_TR_ISO, SSB_SROM8_FEM_TR_ISO_SHIFT); -+ SPEX(fem.ghz2.antswlut, SSB_SPROM8_FEM2G, -+ SSB_SROM8_FEM_ANTSWLUT, SSB_SROM8_FEM_ANTSWLUT_SHIFT); -+ -+ SPEX(fem.ghz5.tssipos, SSB_SPROM8_FEM5G, -+ SSB_SROM8_FEM_TSSIPOS, SSB_SROM8_FEM_TSSIPOS_SHIFT); -+ SPEX(fem.ghz5.extpa_gain, SSB_SPROM8_FEM5G, -+ SSB_SROM8_FEM_EXTPA_GAIN, SSB_SROM8_FEM_EXTPA_GAIN_SHIFT); -+ SPEX(fem.ghz5.pdet_range, SSB_SPROM8_FEM5G, -+ SSB_SROM8_FEM_PDET_RANGE, SSB_SROM8_FEM_PDET_RANGE_SHIFT); -+ SPEX(fem.ghz5.tr_iso, SSB_SPROM8_FEM5G, -+ SSB_SROM8_FEM_TR_ISO, SSB_SROM8_FEM_TR_ISO_SHIFT); -+ SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G, -+ SSB_SROM8_FEM_ANTSWLUT, SSB_SROM8_FEM_ANTSWLUT_SHIFT); -+ -+ SPEX(leddc_on_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_ON, -+ SSB_SPROM8_LEDDC_ON_SHIFT); -+ SPEX(leddc_off_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_OFF, -+ SSB_SPROM8_LEDDC_OFF_SHIFT); -+ -+ SPEX(txchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_TXCHAIN, -+ SSB_SPROM8_TXRXC_TXCHAIN_SHIFT); -+ SPEX(rxchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_RXCHAIN, -+ SSB_SPROM8_TXRXC_RXCHAIN_SHIFT); -+ SPEX(antswitch, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_SWITCH, -+ SSB_SPROM8_TXRXC_SWITCH_SHIFT); -+ -+ SPEX(opo, SSB_SPROM8_OFDM2GPO, 0x00ff, 0); -+ -+ SPEX_ARRAY8(mcs2gpo, SSB_SPROM8_2G_MCSPO, ~0, 0); -+ SPEX_ARRAY8(mcs5gpo, SSB_SPROM8_5G_MCSPO, ~0, 0); -+ SPEX_ARRAY8(mcs5glpo, SSB_SPROM8_5GL_MCSPO, ~0, 0); -+ SPEX_ARRAY8(mcs5ghpo, SSB_SPROM8_5GH_MCSPO, ~0, 0); -+ -+ SPEX(rawtempsense, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_RAWTEMP, -+ SSB_SPROM8_RAWTS_RAWTEMP_SHIFT); -+ SPEX(measpower, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_MEASPOWER, -+ SSB_SPROM8_RAWTS_MEASPOWER_SHIFT); -+ SPEX(tempsense_slope, SSB_SPROM8_OPT_CORRX, -+ SSB_SPROM8_OPT_CORRX_TEMP_SLOPE, -+ SSB_SPROM8_OPT_CORRX_TEMP_SLOPE_SHIFT); -+ SPEX(tempcorrx, SSB_SPROM8_OPT_CORRX, SSB_SPROM8_OPT_CORRX_TEMPCORRX, -+ SSB_SPROM8_OPT_CORRX_TEMPCORRX_SHIFT); -+ SPEX(tempsense_option, SSB_SPROM8_OPT_CORRX, -+ SSB_SPROM8_OPT_CORRX_TEMP_OPTION, -+ SSB_SPROM8_OPT_CORRX_TEMP_OPTION_SHIFT); -+ SPEX(freqoffset_corr, SSB_SPROM8_HWIQ_IQSWP, -+ SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR, -+ SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR_SHIFT); -+ SPEX(iqcal_swp_dis, SSB_SPROM8_HWIQ_IQSWP, -+ SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP, -+ SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP_SHIFT); -+ SPEX(hw_iqcal_en, SSB_SPROM8_HWIQ_IQSWP, SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL, -+ SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL_SHIFT); -+ -+ SPEX(bw40po, SSB_SPROM8_BW40PO, ~0, 0); -+ SPEX(cddpo, SSB_SPROM8_CDDPO, ~0, 0); -+ SPEX(stbcpo, SSB_SPROM8_STBCPO, ~0, 0); -+ SPEX(bwduppo, SSB_SPROM8_BWDUPPO, ~0, 0); -+ -+ SPEX(tempthresh, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_TRESH, -+ SSB_SPROM8_THERMAL_TRESH_SHIFT); -+ SPEX(tempoffset, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_OFFSET, -+ SSB_SPROM8_THERMAL_OFFSET_SHIFT); -+ SPEX(phycal_tempdelta, SSB_SPROM8_TEMPDELTA, -+ SSB_SPROM8_TEMPDELTA_PHYCAL, -+ SSB_SPROM8_TEMPDELTA_PHYCAL_SHIFT); -+ SPEX(temps_period, SSB_SPROM8_TEMPDELTA, SSB_SPROM8_TEMPDELTA_PERIOD, -+ SSB_SPROM8_TEMPDELTA_PERIOD_SHIFT); -+ SPEX(temps_hysteresis, SSB_SPROM8_TEMPDELTA, -+ SSB_SPROM8_TEMPDELTA_HYSTERESIS, -+ SSB_SPROM8_TEMPDELTA_HYSTERESIS_SHIFT); -+ sprom_extract_r458(out, in); -+ -+ /* TODO - get remaining rev 8 stuff needed */ -+} -+ -+static int sprom_extract(struct ssb_fbs *priv, const u16 *in, u16 size) -+{ -+ struct ssb_sprom *out = &priv->sprom; -+ -+ memset(out, 0, sizeof(*out)); -+ -+ out->revision = in[size - 1] & 0x00FF; -+ -+ switch (out->revision) { -+ case 1: -+ case 2: -+ case 3: -+ sprom_extract_r123(out, in); -+ break; -+ case 4: -+ case 5: -+ sprom_extract_r45(out, in); -+ break; -+ case 8: -+ sprom_extract_r8(out, in); -+ break; -+ default: -+ dev_warn(priv->dev, -+ "Unsupported SPROM revision %d detected." -+ " Will extract v1\n", -+ out->revision); -+ out->revision = 1; -+ sprom_extract_r123(out, in); -+ } -+ -+ if (out->boardflags_lo == 0xFFFF) -+ out->boardflags_lo = 0; /* per specs */ -+ if (out->boardflags_hi == 0xFFFF) -+ out->boardflags_hi = 0; /* per specs */ -+ -+ return 0; -+} -+ -+static void ssb_fbs_fixup(struct ssb_fbs *priv, u16 *sprom) -+{ -+ struct device_node *node = priv->dev->of_node; -+ u32 fixups, off, val; -+ int i = 0; -+ -+ if (!of_get_property(node, "brcm,sprom-fixups", &fixups)) -+ return; -+ -+ fixups /= sizeof(u32); -+ -+ dev_info(priv->dev, "patching SPROM with %u fixups...\n", fixups >> 1); -+ -+ while (i < fixups) { -+ if (of_property_read_u32_index(node, "brcm,sprom-fixups", -+ i++, &off)) { -+ dev_err(priv->dev, "error reading fixup[%u] offset\n", -+ i - 1); -+ return; -+ } -+ -+ if (of_property_read_u32_index(node, "brcm,sprom-fixups", -+ i++, &val)) { -+ dev_err(priv->dev, "error reading fixup[%u] value\n", -+ i - 1); -+ return; -+ } -+ -+ dev_dbg(priv->dev, "fixup[%d]=0x%04x\n", off, val); -+ -+ sprom[off] = val; -+ } -+} -+ -+static bool sprom_override_devid(struct ssb_fbs *priv, struct ssb_sprom *out, -+ const u16 *in) -+{ -+ SPEX(dev_id, SSB_SPROM1_PID, 0xFFFF, 0); -+ return !!out->dev_id; -+} -+ -+static int ssb_fbs_set(struct ssb_fbs *priv, struct device_node *node) -+{ -+ struct ssb_sprom *sprom = &priv->sprom; -+ const struct firmware *fw; -+ const char *sprom_name; -+ int err; -+ -+ if (of_property_read_string(node, "brcm,sprom", &sprom_name)) -+ sprom_name = NULL; -+ -+ if (sprom_name) { -+ err = request_firmware_direct(&fw, sprom_name, priv->dev); -+ if (err) -+ dev_err(priv->dev, "%s load error\n", sprom_name); -+ } else { -+ err = -ENOENT; -+ } -+ -+ if (err) { -+ sprom->revision = 0x02; -+ sprom->board_rev = 0x0017; -+ sprom->country_code = 0x00; -+ sprom->ant_available_bg = 0x03; -+ sprom->pa0b0 = 0x15ae; -+ sprom->pa0b1 = 0xfa85; -+ sprom->pa0b2 = 0xfe8d; -+ sprom->pa1b0 = 0xffff; -+ sprom->pa1b1 = 0xffff; -+ sprom->pa1b2 = 0xffff; -+ sprom->gpio0 = 0xff; -+ sprom->gpio1 = 0xff; -+ sprom->gpio2 = 0xff; -+ sprom->gpio3 = 0xff; -+ sprom->maxpwr_bg = 0x4c; -+ sprom->itssi_bg = 0x00; -+ sprom->boardflags_lo = 0x2848; -+ sprom->boardflags_hi = 0x0000; -+ priv->devid_override = false; -+ -+ dev_warn(priv->dev, "using basic SPROM\n"); -+ } else { -+ size_t size = min(fw->size, (size_t) SSB_FBS_MAX_SIZE); -+ u16 tmp_sprom[SSB_FBS_MAX_SIZE >> 1]; -+ u32 i, j; -+ -+ for (i = 0, j = 0; i < size; i += 2, j++) -+ tmp_sprom[j] = (fw->data[i] << 8) | fw->data[i + 1]; -+ -+ release_firmware(fw); -+ ssb_fbs_fixup(priv, tmp_sprom); -+ sprom_extract(priv, tmp_sprom, size >> 1); -+ -+ priv->devid_override = sprom_override_devid(priv, sprom, -+ tmp_sprom); -+ } -+ -+ return 0; -+} -+ -+static int ssb_fbs_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct device_node *node = dev->of_node; -+ struct ssb_fbs *priv; -+ unsigned long flags; -+ u8 mac[ETH_ALEN]; -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->dev = dev; -+ -+ ssb_fbs_set(priv, node); -+ -+ of_property_read_u32(node, "pci-bus", &priv->pci_bus); -+ of_property_read_u32(node, "pci-dev", &priv->pci_dev); -+ -+ of_get_mac_address(node, mac); -+ if (is_valid_ether_addr(mac)) { -+ dev_info(dev, "mtd mac %pM\n", mac); -+ } else { -+ eth_random_addr(mac); -+ dev_info(dev, "random mac %pM\n", mac); -+ } -+ -+ memcpy(priv->sprom.il0mac, mac, ETH_ALEN); -+ memcpy(priv->sprom.et0mac, mac, ETH_ALEN); -+ memcpy(priv->sprom.et1mac, mac, ETH_ALEN); -+ memcpy(priv->sprom.et2mac, mac, ETH_ALEN); -+ -+ spin_lock_irqsave(&ssb_fbs_lock, flags); -+ list_add(&priv->list, &ssb_fbs_list); -+ spin_unlock_irqrestore(&ssb_fbs_lock, flags); -+ -+ dev_info(dev, "registered SPROM for [%x:%x]\n", -+ priv->pci_bus, priv->pci_dev); -+ -+ return 0; -+} -+ -+static const struct of_device_id ssb_fbs_of_match[] = { -+ { .compatible = "brcm,ssb-sprom", }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, ssb_fbs_of_match); -+ -+static struct platform_driver ssb_fbs_driver = { -+ .probe = ssb_fbs_probe, -+ .driver = { -+ .name = "ssb-sprom", -+ .of_match_table = ssb_fbs_of_match, -+ }, -+}; -+ -+int __init ssb_fbs_register(void) -+{ -+ return platform_driver_register(&ssb_fbs_driver); -+} -diff --git a/drivers/ssb/fallback-sprom.h b/drivers/ssb/fallback-sprom.h -new file mode 100644 -index 000000000000..3966a18b86de ---- /dev/null -+++ b/drivers/ssb/fallback-sprom.h -@@ -0,0 +1,7 @@ -+#ifndef _FALLBACK_SPROM_H -+#define _FALLBACK_SPROM_H -+ -+int __init ssb_fbs_register(void); -+int ssb_get_fallback_sprom(struct ssb_bus *dev, struct ssb_sprom *out); -+ -+#endif /* _FALLBACK_SPROM_H */ -diff --git a/include/dt-bindings/mtd/partitions/uimage.h b/include/dt-bindings/mtd/partitions/uimage.h -new file mode 100644 -index 000000000000..43d5f7b5da87 ---- /dev/null -+++ b/include/dt-bindings/mtd/partitions/uimage.h -@@ -0,0 +1,198 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * *** IMPORTANT *** -+ * This file is not only included from C-code but also from devicetree source -+ * files. As such this file MUST only contain comments and defines. -+ * -+ * Based on image.h from U-Boot which is -+ * (C) Copyright 2008 Semihalf -+ * (C) Copyright 2000-2005 Wolfgang Denk, DENX Software Engineering, wd@denx.de. -+ */ -+ -+#ifndef __UIMAGE_H__ -+#define __UIMAGE_H__ -+ -+/* -+ * Operating System Codes -+ * -+ * The following are exposed to uImage header. -+ * New IDs *MUST* be appended at the end of the list and *NEVER* -+ * inserted for backward compatibility. -+ */ -+#define IH_OS_INVALID 0 /* Invalid OS */ -+#define IH_OS_OPENBSD 1 /* OpenBSD */ -+#define IH_OS_NETBSD 2 /* NetBSD */ -+#define IH_OS_FREEBSD 3 /* FreeBSD */ -+#define IH_OS_4_4BSD 4 /* 4.4BSD */ -+#define IH_OS_LINUX 5 /* Linux */ -+#define IH_OS_SVR4 6 /* SVR4 */ -+#define IH_OS_ESIX 7 /* Esix */ -+#define IH_OS_SOLARIS 8 /* Solaris */ -+#define IH_OS_IRIX 9 /* Irix */ -+#define IH_OS_SCO 10 /* SCO */ -+#define IH_OS_DELL 11 /* Dell */ -+#define IH_OS_NCR 12 /* NCR */ -+#define IH_OS_LYNXOS 13 /* LynxOS */ -+#define IH_OS_VXWORKS 14 /* VxWorks */ -+#define IH_OS_PSOS 15 /* pSOS */ -+#define IH_OS_QNX 16 /* QNX */ -+#define IH_OS_U_BOOT 17 /* Firmware */ -+#define IH_OS_RTEMS 18 /* RTEMS */ -+#define IH_OS_ARTOS 19 /* ARTOS */ -+#define IH_OS_UNITY 20 /* Unity OS */ -+#define IH_OS_INTEGRITY 21 /* INTEGRITY */ -+#define IH_OS_OSE 22 /* OSE */ -+#define IH_OS_PLAN9 23 /* Plan 9 */ -+#define IH_OS_OPENRTOS 24 /* OpenRTOS */ -+#define IH_OS_ARM_TRUSTED_FIRMWARE 25 /* ARM Trusted Firmware */ -+#define IH_OS_TEE 26 /* Trusted Execution Environment */ -+#define IH_OS_OPENSBI 27 /* RISC-V OpenSBI */ -+#define IH_OS_EFI 28 /* EFI Firmware (e.g. GRUB2) */ -+ -+/* -+ * CPU Architecture Codes (supported by Linux) -+ * -+ * The following are exposed to uImage header. -+ * New IDs *MUST* be appended at the end of the list and *NEVER* -+ * inserted for backward compatibility. -+ */ -+#define IH_ARCH_INVALID 0 /* Invalid CPU */ -+#define IH_ARCH_ALPHA 1 /* Alpha */ -+#define IH_ARCH_ARM 2 /* ARM */ -+#define IH_ARCH_I386 3 /* Intel x86 */ -+#define IH_ARCH_IA64 4 /* IA64 */ -+#define IH_ARCH_MIPS 5 /* MIPS */ -+#define IH_ARCH_MIPS64 6 /* MIPS 64 Bit */ -+#define IH_ARCH_PPC 7 /* PowerPC */ -+#define IH_ARCH_S390 8 /* IBM S390 */ -+#define IH_ARCH_SH 9 /* SuperH */ -+#define IH_ARCH_SPARC 10 /* Sparc */ -+#define IH_ARCH_SPARC64 11 /* Sparc 64 Bit */ -+#define IH_ARCH_M68K 12 /* M68K */ -+#define IH_ARCH_NIOS 13 /* Nios-32 */ -+#define IH_ARCH_MICROBLAZE 14 /* MicroBlaze */ -+#define IH_ARCH_NIOS2 15 /* Nios-II */ -+#define IH_ARCH_BLACKFIN 16 /* Blackfin */ -+#define IH_ARCH_AVR32 17 /* AVR32 */ -+#define IH_ARCH_ST200 18 /* STMicroelectronics ST200 */ -+#define IH_ARCH_SANDBOX 19 /* Sandbox architecture (test only) */ -+#define IH_ARCH_NDS32 20 /* ANDES Technology - NDS32 */ -+#define IH_ARCH_OPENRISC 21 /* OpenRISC 1000 */ -+#define IH_ARCH_ARM64 22 /* ARM64 */ -+#define IH_ARCH_ARC 23 /* Synopsys DesignWare ARC */ -+#define IH_ARCH_X86_64 24 /* AMD x86_64, Intel and Via */ -+#define IH_ARCH_XTENSA 25 /* Xtensa */ -+#define IH_ARCH_RISCV 26 /* RISC-V */ -+ -+/* -+ * Image Types -+ * -+ * "Standalone Programs" are directly runnable in the environment -+ * provided by U-Boot; it is expected that (if they behave -+ * well) you can continue to work in U-Boot after return from -+ * the Standalone Program. -+ * "OS Kernel Images" are usually images of some Embedded OS which -+ * will take over control completely. Usually these programs -+ * will install their own set of exception handlers, device -+ * drivers, set up the MMU, etc. - this means, that you cannot -+ * expect to re-enter U-Boot except by resetting the CPU. -+ * "RAMDisk Images" are more or less just data blocks, and their -+ * parameters (address, size) are passed to an OS kernel that is -+ * being started. -+ * "Multi-File Images" contain several images, typically an OS -+ * (Linux) kernel image and one or more data images like -+ * RAMDisks. This construct is useful for instance when you want -+ * to boot over the network using BOOTP etc., where the boot -+ * server provides just a single image file, but you want to get -+ * for instance an OS kernel and a RAMDisk image. -+ * -+ * "Multi-File Images" start with a list of image sizes, each -+ * image size (in bytes) specified by an "uint32_t" in network -+ * byte order. This list is terminated by an "(uint32_t)0". -+ * Immediately after the terminating 0 follow the images, one by -+ * one, all aligned on "uint32_t" boundaries (size rounded up to -+ * a multiple of 4 bytes - except for the last file). -+ * -+ * "Firmware Images" are binary images containing firmware (like -+ * U-Boot or FPGA images) which usually will be programmed to -+ * flash memory. -+ * -+ * "Script files" are command sequences that will be executed by -+ * U-Boot's command interpreter; this feature is especially -+ * useful when you configure U-Boot to use a real shell (hush) -+ * as command interpreter (=> Shell Scripts). -+ * -+ * The following are exposed to uImage header. -+ * New IDs *MUST* be appended at the end of the list and *NEVER* -+ * inserted for backward compatibility. -+ */ -+#define IH_TYPE_INVALID 0 /* Invalid Image */ -+#define IH_TYPE_STANDALONE 1 /* Standalone Program */ -+#define IH_TYPE_KERNEL 2 /* OS Kernel Image */ -+#define IH_TYPE_RAMDISK 3 /* RAMDisk Image */ -+#define IH_TYPE_MULTI 4 /* Multi-File Image */ -+#define IH_TYPE_FIRMWARE 5 /* Firmware Image */ -+#define IH_TYPE_SCRIPT 6 /* Script file */ -+#define IH_TYPE_FILESYSTEM 7 /* Filesystem Image (any type) */ -+#define IH_TYPE_FLATDT 8 /* Binary Flat Device Tree Blob */ -+#define IH_TYPE_KWBIMAGE 9 /* Kirkwood Boot Image */ -+#define IH_TYPE_IMXIMAGE 10 /* Freescale IMXBoot Image */ -+#define IH_TYPE_UBLIMAGE 11 /* Davinci UBL Image */ -+#define IH_TYPE_OMAPIMAGE 12 /* TI OMAP Config Header Image */ -+#define IH_TYPE_AISIMAGE 13 /* TI Davinci AIS Image */ -+ /* OS Kernel Image, can run from any load address */ -+#define IH_TYPE_KERNEL_NOLOAD 14 -+#define IH_TYPE_PBLIMAGE 15 /* Freescale PBL Boot Image */ -+#define IH_TYPE_MXSIMAGE 16 /* Freescale MXSBoot Image */ -+#define IH_TYPE_GPIMAGE 17 /* TI Keystone GPHeader Image */ -+#define IH_TYPE_ATMELIMAGE 18 /* ATMEL ROM bootable Image */ -+#define IH_TYPE_SOCFPGAIMAGE 19 /* Altera SOCFPGA CV/AV Preloader */ -+#define IH_TYPE_X86_SETUP 20 /* x86 setup.bin Image */ -+#define IH_TYPE_LPC32XXIMAGE 21 /* x86 setup.bin Image */ -+#define IH_TYPE_LOADABLE 22 /* A list of typeless images */ -+#define IH_TYPE_RKIMAGE 23 /* Rockchip Boot Image */ -+#define IH_TYPE_RKSD 24 /* Rockchip SD card */ -+#define IH_TYPE_RKSPI 25 /* Rockchip SPI image */ -+#define IH_TYPE_ZYNQIMAGE 26 /* Xilinx Zynq Boot Image */ -+#define IH_TYPE_ZYNQMPIMAGE 27 /* Xilinx ZynqMP Boot Image */ -+#define IH_TYPE_ZYNQMPBIF 28 /* Xilinx ZynqMP Boot Image (bif) */ -+#define IH_TYPE_FPGA 29 /* FPGA Image */ -+#define IH_TYPE_VYBRIDIMAGE 30 /* VYBRID .vyb Image */ -+#define IH_TYPE_TEE 31 /* Trusted Execution Environment OS Image */ -+#define IH_TYPE_FIRMWARE_IVT 32 /* Firmware Image with HABv4 IVT */ -+#define IH_TYPE_PMMC 33 /* TI Power Management Micro-Controller Firmware */ -+#define IH_TYPE_STM32IMAGE 34 /* STMicroelectronics STM32 Image */ -+#define IH_TYPE_SOCFPGAIMAGE_V1 35 /* Altera SOCFPGA A10 Preloader */ -+#define IH_TYPE_MTKIMAGE 36 /* MediaTek BootROM loadable Image */ -+#define IH_TYPE_IMX8MIMAGE 37 /* Freescale IMX8MBoot Image */ -+#define IH_TYPE_IMX8IMAGE 38 /* Freescale IMX8Boot Image */ -+#define IH_TYPE_COPRO 39 /* Coprocessor Image for remoteproc*/ -+ -+ -+/* -+ * Compression Types -+ * -+ * The following are exposed to uImage header. -+ * New IDs *MUST* be appended at the end of the list and *NEVER* -+ * inserted for backward compatibility. -+ */ -+#define IH_COMP_NONE 0 /* No Compression Used */ -+#define IH_COMP_GZIP 1 /* gzip Compression Used */ -+#define IH_COMP_BZIP2 2 /* bzip2 Compression Used */ -+#define IH_COMP_LZMA 3 /* lzma Compression Used */ -+#define IH_COMP_LZO 4 /* lzo Compression Used */ -+#define IH_COMP_LZ4 5 /* lz4 Compression Used */ -+ -+ -+#define LZ4F_MAGIC 0x184D2204 /* LZ4 Magic Number */ -+#define IH_MAGIC 0x27051956 /* Image Magic Number */ -+#define IH_NMLEN 32 /* Image Name Length */ -+ -+/* -+ * Magic values specific to "openwrt,uimage" partitions -+ */ -+#define IH_MAGIC_OKLI 0x4f4b4c49 /* 'OKLI' */ -+#define FW_EDIMAX_OFFSET 20 /* Edimax Firmware Offset */ -+#define FW_MAGIC_EDIMAX 0x43535953 /* Edimax Firmware Magic Number */ -+ -+#endif /* __UIMAGE_H__ */ -diff --git a/include/linux/ar8216_platform.h b/include/linux/ar8216_platform.h -new file mode 100644 -index 000000000000..fff05ffb5c16 ---- /dev/null -+++ b/include/linux/ar8216_platform.h -@@ -0,0 +1,134 @@ -+/* -+ * AR8216 switch driver platform data -+ * -+ * Copyright (C) 2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef AR8216_PLATFORM_H -+#define AR8216_PLATFORM_H -+ -+enum ar8327_pad_mode { -+ AR8327_PAD_NC = 0, -+ AR8327_PAD_MAC2MAC_MII, -+ AR8327_PAD_MAC2MAC_GMII, -+ AR8327_PAD_MAC_SGMII, -+ AR8327_PAD_MAC2PHY_MII, -+ AR8327_PAD_MAC2PHY_GMII, -+ AR8327_PAD_MAC_RGMII, -+ AR8327_PAD_PHY_GMII, -+ AR8327_PAD_PHY_RGMII, -+ AR8327_PAD_PHY_MII, -+}; -+ -+enum ar8327_clk_delay_sel { -+ AR8327_CLK_DELAY_SEL0 = 0, -+ AR8327_CLK_DELAY_SEL1, -+ AR8327_CLK_DELAY_SEL2, -+ AR8327_CLK_DELAY_SEL3, -+}; -+ -+struct ar8327_pad_cfg { -+ enum ar8327_pad_mode mode; -+ bool rxclk_sel; -+ bool txclk_sel; -+ bool pipe_rxclk_sel; -+ bool txclk_delay_en; -+ bool rxclk_delay_en; -+ bool sgmii_delay_en; -+ enum ar8327_clk_delay_sel txclk_delay_sel; -+ enum ar8327_clk_delay_sel rxclk_delay_sel; -+ bool mac06_exchange_dis; -+}; -+ -+enum ar8327_port_speed { -+ AR8327_PORT_SPEED_10 = 0, -+ AR8327_PORT_SPEED_100, -+ AR8327_PORT_SPEED_1000, -+}; -+ -+struct ar8327_port_cfg { -+ int force_link:1; -+ enum ar8327_port_speed speed; -+ int txpause:1; -+ int rxpause:1; -+ int duplex:1; -+}; -+ -+struct ar8327_sgmii_cfg { -+ u32 sgmii_ctrl; -+ bool serdes_aen; -+}; -+ -+struct ar8327_led_cfg { -+ u32 led_ctrl0; -+ u32 led_ctrl1; -+ u32 led_ctrl2; -+ u32 led_ctrl3; -+ bool open_drain; -+}; -+ -+enum ar8327_led_num { -+ AR8327_LED_PHY0_0 = 0, -+ AR8327_LED_PHY0_1, -+ AR8327_LED_PHY0_2, -+ AR8327_LED_PHY1_0, -+ AR8327_LED_PHY1_1, -+ AR8327_LED_PHY1_2, -+ AR8327_LED_PHY2_0, -+ AR8327_LED_PHY2_1, -+ AR8327_LED_PHY2_2, -+ AR8327_LED_PHY3_0, -+ AR8327_LED_PHY3_1, -+ AR8327_LED_PHY3_2, -+ AR8327_LED_PHY4_0, -+ AR8327_LED_PHY4_1, -+ AR8327_LED_PHY4_2, -+}; -+ -+enum ar8327_led_mode { -+ AR8327_LED_MODE_HW = 0, -+ AR8327_LED_MODE_SW, -+}; -+ -+struct ar8327_led_info { -+ const char *name; -+ const char *default_trigger; -+ bool active_low; -+ enum ar8327_led_num led_num; -+ enum ar8327_led_mode mode; -+ struct fwnode_handle *fwnode; -+}; -+ -+#define AR8327_LED_INFO(_led, _mode, _name) { \ -+ .name = (_name), \ -+ .led_num = AR8327_LED_ ## _led, \ -+ .mode = AR8327_LED_MODE_ ## _mode \ -+} -+ -+struct ar8327_platform_data { -+ struct ar8327_pad_cfg *pad0_cfg; -+ struct ar8327_pad_cfg *pad5_cfg; -+ struct ar8327_pad_cfg *pad6_cfg; -+ struct ar8327_sgmii_cfg *sgmii_cfg; -+ struct ar8327_port_cfg port0_cfg; -+ struct ar8327_port_cfg port6_cfg; -+ struct ar8327_led_cfg *led_cfg; -+ -+ int (*get_port_link)(unsigned port); -+ -+ unsigned num_leds; -+ const struct ar8327_led_info *leds; -+}; -+ -+#endif /* AR8216_PLATFORM_H */ -+ -diff --git a/include/linux/ath5k_platform.h b/include/linux/ath5k_platform.h -new file mode 100644 -index 000000000000..ec8522452879 ---- /dev/null -+++ b/include/linux/ath5k_platform.h -@@ -0,0 +1,30 @@ -+/* -+ * Copyright (c) 2008 Atheros Communications Inc. -+ * Copyright (c) 2009 Gabor Juhos -+ * Copyright (c) 2009 Imre Kaloz -+ * Copyright (c) 2010 Daniel Golle -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#ifndef _LINUX_ATH5K_PLATFORM_H -+#define _LINUX_ATH5K_PLATFORM_H -+ -+#define ATH5K_PLAT_EEP_MAX_WORDS 2048 -+ -+struct ath5k_platform_data { -+ u16 *eeprom_data; -+ u8 *macaddr; -+}; -+ -+#endif /* _LINUX_ATH5K_PLATFORM_H */ -diff --git a/include/linux/mfd/airoha-an8855-mfd.h b/include/linux/mfd/airoha-an8855-mfd.h -new file mode 100644 -index 000000000000..56061566a079 ---- /dev/null -+++ b/include/linux/mfd/airoha-an8855-mfd.h -@@ -0,0 +1,41 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * MFD driver for Airoha AN8855 Switch -+ */ -+#ifndef _LINUX_INCLUDE_MFD_AIROHA_AN8855_MFD_H -+#define _LINUX_INCLUDE_MFD_AIROHA_AN8855_MFD_H -+ -+#include -+ -+/* MII Registers */ -+#define AN8855_PHY_SELECT_PAGE 0x1f -+#define AN8855_PHY_PAGE GENMASK(2, 0) -+#define AN8855_PHY_PAGE_STANDARD FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x0) -+#define AN8855_PHY_PAGE_EXTENDED_1 FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x1) -+#define AN8855_PHY_PAGE_EXTENDED_4 FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x4) -+ -+/* MII Registers Page 4 */ -+#define AN8855_PBUS_MODE 0x10 -+#define AN8855_PBUS_MODE_ADDR_FIXED 0x0 -+#define AN8855_PBUS_MODE_ADDR_INCR BIT(15) -+#define AN8855_PBUS_WR_ADDR_HIGH 0x11 -+#define AN8855_PBUS_WR_ADDR_LOW 0x12 -+#define AN8855_PBUS_WR_DATA_HIGH 0x13 -+#define AN8855_PBUS_WR_DATA_LOW 0x14 -+#define AN8855_PBUS_RD_ADDR_HIGH 0x15 -+#define AN8855_PBUS_RD_ADDR_LOW 0x16 -+#define AN8855_PBUS_RD_DATA_HIGH 0x17 -+#define AN8855_PBUS_RD_DATA_LOW 0x18 -+ -+struct an8855_mfd_priv { -+ struct device *dev; -+ struct mii_bus *bus; -+ -+ unsigned int switch_addr; -+ u16 current_page; -+}; -+ -+int an8855_mii_set_page(struct an8855_mfd_priv *priv, u8 phy_id, -+ u8 page); -+ -+#endif -diff --git a/include/linux/mtd/mtk_bmt.h b/include/linux/mtd/mtk_bmt.h -new file mode 100644 -index 000000000000..cbb6d04d8952 ---- /dev/null -+++ b/include/linux/mtd/mtk_bmt.h -@@ -0,0 +1,18 @@ -+#ifndef __MTK_BMT_H -+#define __MTK_BMT_H -+ -+#ifdef CONFIG_MTD_NAND_MTK_BMT -+int mtk_bmt_attach(struct mtd_info *mtd); -+void mtk_bmt_detach(struct mtd_info *mtd); -+#else -+static inline int mtk_bmt_attach(struct mtd_info *mtd) -+{ -+ return 0; -+} -+ -+static inline void mtk_bmt_detach(struct mtd_info *mtd) -+{ -+} -+#endif -+ -+#endif -diff --git a/include/linux/myloader.h b/include/linux/myloader.h -new file mode 100644 -index 000000000000..d89e415fba6c ---- /dev/null -+++ b/include/linux/myloader.h -@@ -0,0 +1,121 @@ -+/* -+ * Compex's MyLoader specific definitions -+ * -+ * Copyright (C) 2006-2008 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+ -+#ifndef _MYLOADER_H_ -+#define _MYLOADER_H_ -+ -+/* Myloader specific magic numbers */ -+#define MYLO_MAGIC_SYS_PARAMS 0x20021107 -+#define MYLO_MAGIC_PARTITIONS 0x20021103 -+#define MYLO_MAGIC_BOARD_PARAMS 0x20021103 -+ -+/* Vendor ID's (seems to be same as the PCI vendor ID's) */ -+#define VENID_COMPEX 0x11F6 -+ -+/* Devices based on the ADM5120 */ -+#define DEVID_COMPEX_NP27G 0x0078 -+#define DEVID_COMPEX_NP28G 0x044C -+#define DEVID_COMPEX_NP28GHS 0x044E -+#define DEVID_COMPEX_WP54Gv1C 0x0514 -+#define DEVID_COMPEX_WP54G 0x0515 -+#define DEVID_COMPEX_WP54AG 0x0546 -+#define DEVID_COMPEX_WPP54AG 0x0550 -+#define DEVID_COMPEX_WPP54G 0x0555 -+ -+/* Devices based on the Atheros AR2317 */ -+#define DEVID_COMPEX_NP25G 0x05E6 -+#define DEVID_COMPEX_WPE53G 0x05DC -+ -+/* Devices based on the Atheros AR71xx */ -+#define DEVID_COMPEX_WP543 0x0640 -+#define DEVID_COMPEX_WPE72 0x0672 -+ -+/* Devices based on the IXP422 */ -+#define DEVID_COMPEX_WP18 0x047E -+#define DEVID_COMPEX_NP18A 0x0489 -+ -+/* Other devices */ -+#define DEVID_COMPEX_NP26G8M 0x03E8 -+#define DEVID_COMPEX_NP26G16M 0x03E9 -+ -+struct mylo_partition { -+ uint16_t flags; /* partition flags */ -+ uint16_t type; /* type of the partition */ -+ uint32_t addr; /* relative address of the partition from the -+ flash start */ -+ uint32_t size; /* size of the partition in bytes */ -+ uint32_t param; /* if this is the active partition, the -+ MyLoader load code to this address */ -+}; -+ -+#define PARTITION_FLAG_ACTIVE 0x8000 /* this is the active partition, -+ * MyLoader loads firmware from here */ -+#define PARTITION_FLAG_ISRAM 0x2000 /* FIXME: this is a RAM partition? */ -+#define PARTIIION_FLAG_RAMLOAD 0x1000 /* FIXME: load this partition into the RAM? */ -+#define PARTITION_FLAG_PRELOAD 0x0800 /* the partition data preloaded to RAM -+ * before decompression */ -+#define PARTITION_FLAG_LZMA 0x0100 /* partition data compressed by LZMA */ -+#define PARTITION_FLAG_HAVEHDR 0x0002 /* the partition data have a header */ -+ -+#define PARTITION_TYPE_FREE 0 -+#define PARTITION_TYPE_USED 1 -+ -+#define MYLO_MAX_PARTITIONS 8 /* maximum number of partitions in the -+ partition table */ -+ -+struct mylo_partition_table { -+ uint32_t magic; /* must be MYLO_MAGIC_PARTITIONS */ -+ uint32_t res0; /* unknown/unused */ -+ uint32_t res1; /* unknown/unused */ -+ uint32_t res2; /* unknown/unused */ -+ struct mylo_partition partitions[MYLO_MAX_PARTITIONS]; -+}; -+ -+struct mylo_partition_header { -+ uint32_t len; /* length of the partition data */ -+ uint32_t crc; /* CRC value of the partition data */ -+}; -+ -+struct mylo_system_params { -+ uint32_t magic; /* must be MYLO_MAGIC_SYS_PARAMS */ -+ uint32_t res0; -+ uint32_t res1; -+ uint32_t mylo_ver; -+ uint16_t vid; /* Vendor ID */ -+ uint16_t did; /* Device ID */ -+ uint16_t svid; /* Sub Vendor ID */ -+ uint16_t sdid; /* Sub Device ID */ -+ uint32_t rev; /* device revision */ -+ uint32_t fwhi; -+ uint32_t fwlo; -+ uint32_t tftp_addr; -+ uint32_t prog_start; -+ uint32_t flash_size; /* size of boot FLASH in bytes */ -+ uint32_t dram_size; /* size of onboard RAM in bytes */ -+}; -+ -+struct mylo_eth_addr { -+ uint8_t mac[6]; -+ uint8_t csum[2]; -+}; -+ -+#define MYLO_ETHADDR_COUNT 8 /* maximum number of ethernet address -+ in the board parameters */ -+ -+struct mylo_board_params { -+ uint32_t magic; /* must be MYLO_MAGIC_BOARD_PARAMS */ -+ uint32_t res0; -+ uint32_t res1; -+ uint32_t res2; -+ struct mylo_eth_addr addr[MYLO_ETHADDR_COUNT]; -+}; -+ -+#endif /* _MYLOADER_H_*/ -diff --git a/include/linux/platform_data/adm6996-gpio.h b/include/linux/platform_data/adm6996-gpio.h -new file mode 100644 -index 000000000000..d5af9bbf6e55 ---- /dev/null -+++ b/include/linux/platform_data/adm6996-gpio.h -@@ -0,0 +1,29 @@ -+/* -+ * ADM6996 GPIO platform data -+ * -+ * Copyright (C) 2013 Hauke Mehrtens -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License v2 as published by the -+ * Free Software Foundation -+ */ -+ -+#ifndef __PLATFORM_ADM6996_GPIO_H -+#define __PLATFORM_ADM6996_GPIO_H -+ -+#include -+ -+enum adm6996_model { -+ ADM6996FC = 1, -+ ADM6996M = 2, -+ ADM6996L = 3, -+}; -+ -+struct adm6996_gpio_platform_data { -+ u8 eecs; -+ u8 eesk; -+ u8 eedi; -+ enum adm6996_model model; -+}; -+ -+#endif -diff --git a/include/linux/routerboot.h b/include/linux/routerboot.h -new file mode 100644 -index 000000000000..3cda858cf9c2 ---- /dev/null -+++ b/include/linux/routerboot.h -@@ -0,0 +1,106 @@ -+/* -+ * Mikrotik's RouterBOOT definitions -+ * -+ * Copyright (C) 2007-2008 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+ -+#ifndef _ROUTERBOOT_H -+#define _ROUTERBOOT_H -+ -+#define RB_MAC_SIZE 6 -+ -+/* -+ * Magic numbers -+ */ -+#define RB_MAGIC_HARD 0x64726148 /* "Hard" */ -+#define RB_MAGIC_SOFT 0x74666F53 /* "Soft" */ -+#define RB_MAGIC_DAWN 0x6E776144 /* "Dawn" */ -+ -+#define RB_ID_TERMINATOR 0 -+ -+/* -+ * ID values for Hardware settings -+ */ -+#define RB_ID_HARD_01 1 -+#define RB_ID_HARD_02 2 -+#define RB_ID_FLASH_INFO 3 -+#define RB_ID_MAC_ADDRESS_PACK 4 -+#define RB_ID_BOARD_NAME 5 -+#define RB_ID_BIOS_VERSION 6 -+#define RB_ID_HARD_07 7 -+#define RB_ID_SDRAM_TIMINGS 8 -+#define RB_ID_DEVICE_TIMINGS 9 -+#define RB_ID_SOFTWARE_ID 10 -+#define RB_ID_SERIAL_NUMBER 11 -+#define RB_ID_HARD_12 12 -+#define RB_ID_MEMORY_SIZE 13 -+#define RB_ID_MAC_ADDRESS_COUNT 14 -+#define RB_ID_HW_OPTIONS 21 -+#define RB_ID_WLAN_DATA 22 -+ -+/* -+ * ID values for Software settings -+ */ -+#define RB_ID_UART_SPEED 1 -+#define RB_ID_BOOT_DELAY 2 -+#define RB_ID_BOOT_DEVICE 3 -+#define RB_ID_BOOT_KEY 4 -+#define RB_ID_CPU_MODE 5 -+#define RB_ID_FW_VERSION 6 -+#define RB_ID_SOFT_07 7 -+#define RB_ID_SOFT_08 8 -+#define RB_ID_BOOT_PROTOCOL 9 -+#define RB_ID_SOFT_10 10 -+#define RB_ID_SOFT_11 11 -+ -+/* -+ * UART_SPEED values -+ */ -+#define RB_UART_SPEED_115200 0 -+#define RB_UART_SPEED_57600 1 -+#define RB_UART_SPEED_38400 2 -+#define RB_UART_SPEED_19200 3 -+#define RB_UART_SPEED_9600 4 -+#define RB_UART_SPEED_4800 5 -+#define RB_UART_SPEED_2400 6 -+#define RB_UART_SPEED_1200 7 -+ -+/* -+ * BOOT_DELAY values -+ */ -+#define RB_BOOT_DELAY_0SEC 0 -+#define RB_BOOT_DELAY_1SEC 1 -+#define RB_BOOT_DELAY_2SEC 2 -+ -+/* -+ * BOOT_DEVICE values -+ */ -+#define RB_BOOT_DEVICE_ETHER 0 -+#define RB_BOOT_DEVICE_NANDETH 1 -+#define RB_BOOT_DEVICE_ETHONCE 2 -+#define RB_BOOT_DEVICE_NANDONLY 3 -+ -+/* -+ * BOOT_KEY values -+ */ -+#define RB_BOOT_KEY_ANY 0 -+#define RB_BOOT_KEY_DEL 1 -+ -+/* -+ * CPU_MODE values -+ */ -+#define RB_CPU_MODE_POWERSAVE 0 -+#define RB_CPU_MODE_REGULAR 1 -+ -+/* -+ * BOOT_PROTOCOL values -+ */ -+#define RB_BOOT_PROTOCOL_BOOTP 0 -+#define RB_BOOT_PROTOCOL_DHCP 1 -+ -+#endif /* _ROUTERBOOT_H */ -diff --git a/include/linux/rtl8366.h b/include/linux/rtl8366.h -new file mode 100644 -index 000000000000..e3ce8f5361eb ---- /dev/null -+++ b/include/linux/rtl8366.h -@@ -0,0 +1,42 @@ -+/* -+ * Platform data definition for the Realtek RTL8366RB/S ethernet switch driver -+ * -+ * Copyright (C) 2009-2010 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#ifndef _RTL8366_H -+#define _RTL8366_H -+ -+#define RTL8366_DRIVER_NAME "rtl8366" -+#define RTL8366S_DRIVER_NAME "rtl8366s" -+#define RTL8366RB_DRIVER_NAME "rtl8366rb" -+ -+struct rtl8366_smi; -+ -+enum rtl8366_type { -+ RTL8366_TYPE_UNKNOWN, -+ RTL8366_TYPE_S, -+ RTL8366_TYPE_RB, -+}; -+ -+struct rtl8366_initval { -+ unsigned reg; -+ u16 val; -+}; -+ -+struct rtl8366_platform_data { -+ unsigned gpio_sda; -+ unsigned gpio_sck; -+ void (*hw_reset)(struct rtl8366_smi *smi, bool active); -+ -+ unsigned num_initvals; -+ struct rtl8366_initval *initvals; -+}; -+ -+enum rtl8366_type rtl8366_smi_detect(struct rtl8366_platform_data *pdata); -+ -+#endif /* _RTL8366_H */ -diff --git a/include/linux/rtl8367.h b/include/linux/rtl8367.h -new file mode 100644 -index 000000000000..14150393e280 ---- /dev/null -+++ b/include/linux/rtl8367.h -@@ -0,0 +1,63 @@ -+/* -+ * Platform data definition for the Realtek RTL8367 ethernet switch driver -+ * -+ * Copyright (C) 2011 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#ifndef _RTL8367_H -+#define _RTL8367_H -+ -+#define RTL8367_DRIVER_NAME "rtl8367" -+#define RTL8367B_DRIVER_NAME "rtl8367b" -+ -+enum rtl8367_port_speed { -+ RTL8367_PORT_SPEED_10 = 0, -+ RTL8367_PORT_SPEED_100, -+ RTL8367_PORT_SPEED_1000, -+}; -+ -+struct rtl8367_port_ability { -+ int force_mode; -+ int nway; -+ int txpause; -+ int rxpause; -+ int link; -+ int duplex; -+ enum rtl8367_port_speed speed; -+}; -+ -+enum rtl8367_extif_mode { -+ RTL8367_EXTIF_MODE_DISABLED = 0, -+ RTL8367_EXTIF_MODE_RGMII, -+ RTL8367_EXTIF_MODE_MII_MAC, -+ RTL8367_EXTIF_MODE_MII_PHY, -+ RTL8367_EXTIF_MODE_TMII_MAC, -+ RTL8367_EXTIF_MODE_TMII_PHY, -+ RTL8367_EXTIF_MODE_GMII, -+ RTL8367_EXTIF_MODE_RGMII_33V, -+ RTL8367B_EXTIF_MODE_RMII_MAC = 7, -+ RTL8367B_EXTIF_MODE_RMII_PHY, -+ RTL8367B_EXTIF_MODE_RGMII_33V, -+}; -+ -+struct rtl8367_extif_config { -+ unsigned int txdelay; -+ unsigned int rxdelay; -+ enum rtl8367_extif_mode mode; -+ struct rtl8367_port_ability ability; -+}; -+ -+struct rtl8367_platform_data { -+ unsigned gpio_sda; -+ unsigned gpio_sck; -+ void (*hw_reset)(bool active); -+ -+ struct rtl8367_extif_config *extif0_cfg; -+ struct rtl8367_extif_config *extif1_cfg; -+}; -+ -+#endif /* _RTL8367_H */ -diff --git a/include/linux/switch.h b/include/linux/switch.h -new file mode 100644 -index 000000000000..4e6238470d30 ---- /dev/null -+++ b/include/linux/switch.h -@@ -0,0 +1,179 @@ -+/* -+ * switch.h: Switch configuration API -+ * -+ * Copyright (C) 2008 Felix Fietkau -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+#ifndef _LINUX_SWITCH_H -+#define _LINUX_SWITCH_H -+ -+#include -+#include -+ -+struct switch_dev; -+struct switch_op; -+struct switch_val; -+struct switch_attr; -+struct switch_attrlist; -+struct switch_led_trigger; -+ -+int register_switch(struct switch_dev *dev, struct net_device *netdev); -+void unregister_switch(struct switch_dev *dev); -+ -+/** -+ * struct switch_attrlist - attribute list -+ * -+ * @n_attr: number of attributes -+ * @attr: pointer to the attributes array -+ */ -+struct switch_attrlist { -+ int n_attr; -+ const struct switch_attr *attr; -+}; -+ -+enum switch_port_speed { -+ SWITCH_PORT_SPEED_UNKNOWN = 0, -+ SWITCH_PORT_SPEED_10 = 10, -+ SWITCH_PORT_SPEED_100 = 100, -+ SWITCH_PORT_SPEED_1000 = 1000, -+}; -+ -+struct switch_port_link { -+ bool link; -+ bool duplex; -+ bool aneg; -+ bool tx_flow; -+ bool rx_flow; -+ enum switch_port_speed speed; -+ /* in ethtool adv_t format */ -+ u32 eee; -+}; -+ -+struct switch_port_stats { -+ unsigned long long tx_bytes; -+ unsigned long long rx_bytes; -+}; -+ -+/** -+ * struct switch_dev_ops - switch driver operations -+ * -+ * @attr_global: global switch attribute list -+ * @attr_port: port attribute list -+ * @attr_vlan: vlan attribute list -+ * -+ * Callbacks: -+ * -+ * @get_vlan_ports: read the port list of a VLAN -+ * @set_vlan_ports: set the port list of a VLAN -+ * -+ * @get_port_pvid: get the primary VLAN ID of a port -+ * @set_port_pvid: set the primary VLAN ID of a port -+ * -+ * @apply_config: apply all changed settings to the switch -+ * @reset_switch: resetting the switch -+ */ -+struct switch_dev_ops { -+ struct switch_attrlist attr_global, attr_port, attr_vlan; -+ -+ int (*get_vlan_ports)(struct switch_dev *dev, struct switch_val *val); -+ int (*set_vlan_ports)(struct switch_dev *dev, struct switch_val *val); -+ -+ int (*get_port_pvid)(struct switch_dev *dev, int port, int *val); -+ int (*set_port_pvid)(struct switch_dev *dev, int port, int val); -+ -+ int (*apply_config)(struct switch_dev *dev); -+ int (*reset_switch)(struct switch_dev *dev); -+ -+ int (*get_port_link)(struct switch_dev *dev, int port, -+ struct switch_port_link *link); -+ int (*set_port_link)(struct switch_dev *dev, int port, -+ struct switch_port_link *link); -+ int (*get_port_stats)(struct switch_dev *dev, int port, -+ struct switch_port_stats *stats); -+ -+ int (*phy_read16)(struct switch_dev *dev, int addr, u8 reg, u16 *value); -+ int (*phy_write16)(struct switch_dev *dev, int addr, u8 reg, u16 value); -+}; -+ -+struct switch_dev { -+ struct device_node *of_node; -+ const struct switch_dev_ops *ops; -+ /* will be automatically filled */ -+ char devname[IFNAMSIZ]; -+ -+ const char *name; -+ /* NB: either alias or netdev must be set */ -+ const char *alias; -+ struct net_device *netdev; -+ -+ unsigned int ports; -+ unsigned int vlans; -+ unsigned int cpu_port; -+ -+ /* the following fields are internal for swconfig */ -+ unsigned int id; -+ struct list_head dev_list; -+ unsigned long def_global, def_port, def_vlan; -+ -+ struct mutex sw_mutex; -+ struct switch_port *portbuf; -+ struct switch_portmap *portmap; -+ struct switch_port_link linkbuf; -+ -+ char buf[128]; -+ -+#ifdef CONFIG_SWCONFIG_LEDS -+ struct switch_led_trigger *led_trigger; -+#endif -+}; -+ -+struct switch_port { -+ u32 id; -+ u32 flags; -+}; -+ -+struct switch_portmap { -+ u32 virt; -+ const char *s; -+}; -+ -+struct switch_val { -+ const struct switch_attr *attr; -+ unsigned int port_vlan; -+ unsigned int len; -+ union { -+ const char *s; -+ u32 i; -+ struct switch_port *ports; -+ struct switch_port_link *link; -+ } value; -+}; -+ -+struct switch_attr { -+ int disabled; -+ int type; -+ const char *name; -+ const char *description; -+ -+ int (*set)(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val); -+ int (*get)(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val); -+ -+ /* for driver internal use */ -+ int id; -+ int ofs; -+ int max; -+}; -+ -+int switch_generic_set_link(struct switch_dev *dev, int port, -+ struct switch_port_link *link); -+ -+#endif /* _LINUX_SWITCH_H */ -diff --git a/include/uapi/linux/switch.h b/include/uapi/linux/switch.h -new file mode 100644 -index 000000000000..ea449653fafa ---- /dev/null -+++ b/include/uapi/linux/switch.h -@@ -0,0 +1,119 @@ -+/* -+ * switch.h: Switch configuration API -+ * -+ * Copyright (C) 2008 Felix Fietkau -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef _UAPI_LINUX_SWITCH_H -+#define _UAPI_LINUX_SWITCH_H -+ -+#include -+#include -+#include -+#include -+#ifndef __KERNEL__ -+#include -+#include -+#include -+#endif -+ -+/* main attributes */ -+enum { -+ SWITCH_ATTR_UNSPEC, -+ /* global */ -+ SWITCH_ATTR_TYPE, -+ /* device */ -+ SWITCH_ATTR_ID, -+ SWITCH_ATTR_DEV_NAME, -+ SWITCH_ATTR_ALIAS, -+ SWITCH_ATTR_NAME, -+ SWITCH_ATTR_VLANS, -+ SWITCH_ATTR_PORTS, -+ SWITCH_ATTR_PORTMAP, -+ SWITCH_ATTR_CPU_PORT, -+ /* attributes */ -+ SWITCH_ATTR_OP_ID, -+ SWITCH_ATTR_OP_TYPE, -+ SWITCH_ATTR_OP_NAME, -+ SWITCH_ATTR_OP_PORT, -+ SWITCH_ATTR_OP_VLAN, -+ SWITCH_ATTR_OP_VALUE_INT, -+ SWITCH_ATTR_OP_VALUE_STR, -+ SWITCH_ATTR_OP_VALUE_PORTS, -+ SWITCH_ATTR_OP_VALUE_LINK, -+ SWITCH_ATTR_OP_DESCRIPTION, -+ /* port lists */ -+ SWITCH_ATTR_PORT, -+ SWITCH_ATTR_MAX -+}; -+ -+enum { -+ /* port map */ -+ SWITCH_PORTMAP_PORTS, -+ SWITCH_PORTMAP_SEGMENT, -+ SWITCH_PORTMAP_VIRT, -+ SWITCH_PORTMAP_MAX -+}; -+ -+/* commands */ -+enum { -+ SWITCH_CMD_UNSPEC, -+ SWITCH_CMD_GET_SWITCH, -+ SWITCH_CMD_NEW_ATTR, -+ SWITCH_CMD_LIST_GLOBAL, -+ SWITCH_CMD_GET_GLOBAL, -+ SWITCH_CMD_SET_GLOBAL, -+ SWITCH_CMD_LIST_PORT, -+ SWITCH_CMD_GET_PORT, -+ SWITCH_CMD_SET_PORT, -+ SWITCH_CMD_LIST_VLAN, -+ SWITCH_CMD_GET_VLAN, -+ SWITCH_CMD_SET_VLAN -+}; -+ -+/* data types */ -+enum switch_val_type { -+ SWITCH_TYPE_UNSPEC, -+ SWITCH_TYPE_INT, -+ SWITCH_TYPE_STRING, -+ SWITCH_TYPE_PORTS, -+ SWITCH_TYPE_LINK, -+ SWITCH_TYPE_NOVAL, -+}; -+ -+/* port nested attributes */ -+enum { -+ SWITCH_PORT_UNSPEC, -+ SWITCH_PORT_ID, -+ SWITCH_PORT_FLAG_TAGGED, -+ SWITCH_PORT_ATTR_MAX -+}; -+ -+/* link nested attributes */ -+enum { -+ SWITCH_LINK_UNSPEC, -+ SWITCH_LINK_FLAG_LINK, -+ SWITCH_LINK_FLAG_DUPLEX, -+ SWITCH_LINK_FLAG_ANEG, -+ SWITCH_LINK_FLAG_TX_FLOW, -+ SWITCH_LINK_FLAG_RX_FLOW, -+ SWITCH_LINK_SPEED, -+ SWITCH_LINK_FLAG_EEE_100BASET, -+ SWITCH_LINK_FLAG_EEE_1000BASET, -+ SWITCH_LINK_ATTR_MAX, -+}; -+ -+#define SWITCH_ATTR_DEFAULTS_OFFSET 0x1000 -+ -+ -+#endif /* _UAPI_LINUX_SWITCH_H */ --- -2.51.0 - - -From 99a7ee0f062c7ea20d18a364a824e63cd95c637a Mon Sep 17 00:00:00 2001 -From: Easwar Hariharan -Date: Wed, 30 Oct 2024 17:47:35 +0000 -Subject: [PATCH 002/517] jiffies: Define secs_to_jiffies() - -secs_to_jiffies() is defined in hci_event.c and cannot be reused by -other call sites. Hoist it into the core code to allow conversion of the -~1150 usages of msecs_to_jiffies() that either: - - - use a multiplier value of 1000 or equivalently MSEC_PER_SEC, or - - have timeouts that are denominated in seconds (i.e. end in 000) - -It's implemented as a macro to allow usage in static initializers. - -This will also allow conversion of yet more sites that use (sec * HZ) -directly, and improve their readability. - -Suggested-by: Michael Kelley -Signed-off-by: Easwar Hariharan -Signed-off-by: Thomas Gleixner -Reviewed-by: Luiz Augusto von Dentz -Link: https://lore.kernel.org/all/20241030-open-coded-timeouts-v3-1-9ba123facf88@linux.microsoft.com ---- - include/linux/jiffies.h | 13 +++++++++++++ - net/bluetooth/hci_event.c | 2 -- - 2 files changed, 13 insertions(+), 2 deletions(-) - -diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h -index 5d21dacd62bc..ed945f42e064 100644 ---- a/include/linux/jiffies.h -+++ b/include/linux/jiffies.h -@@ -526,6 +526,19 @@ static __always_inline unsigned long msecs_to_jiffies(const unsigned int m) - } - } - -+/** -+ * secs_to_jiffies: - convert seconds to jiffies -+ * @_secs: time in seconds -+ * -+ * Conversion is done by simple multiplication with HZ -+ * -+ * secs_to_jiffies() is defined as a macro rather than a static inline -+ * function so it can be used in static initializers. -+ * -+ * Return: jiffies value -+ */ -+#define secs_to_jiffies(_secs) ((_secs) * HZ) -+ - extern unsigned long __usecs_to_jiffies(const unsigned int u); - #if !(USEC_PER_SEC % HZ) - static inline unsigned long _usecs_to_jiffies(const unsigned int u) -diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c -index 1e537ed83ba4..fdaaaf541cac 100644 ---- a/net/bluetooth/hci_event.c -+++ b/net/bluetooth/hci_event.c -@@ -42,8 +42,6 @@ - #define ZERO_KEY "\x00\x00\x00\x00\x00\x00\x00\x00" \ - "\x00\x00\x00\x00\x00\x00\x00\x00" - --#define secs_to_jiffies(_secs) msecs_to_jiffies((_secs) * 1000) -- - /* Handle HCI Event packets */ - - static void *hci_ev_skb_pull(struct hci_dev *hdev, struct sk_buff *skb, --- -2.51.0 - - -From 53a192c572edbbdfc84567d1e5d6c9b443186755 Mon Sep 17 00:00:00 2001 -From: Easwar Hariharan -Date: Thu, 30 Jan 2025 19:26:58 +0000 -Subject: [PATCH 003/517] jiffies: Cast to unsigned long in secs_to_jiffies() - conversion - -While converting users of msecs_to_jiffies(), lkp reported that some range -checks would always be true because of the mismatch between the implied int -value of secs_to_jiffies() vs the unsigned long return value of the -msecs_to_jiffies() calls it was replacing. - -Fix this by casting the secs_to_jiffies() input value to unsigned long. - -Fixes: b35108a51cf7ba ("jiffies: Define secs_to_jiffies()") -Reported-by: kernel test robot -Signed-off-by: Easwar Hariharan -Signed-off-by: Thomas Gleixner -Cc: stable@vger.kernel.org -Link: https://lore.kernel.org/all/20250130192701.99626-1-eahariha@linux.microsoft.com -Closes: https://lore.kernel.org/oe-kbuild-all/202501301334.NB6NszQR-lkp@intel.com/ ---- - include/linux/jiffies.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h -index ed945f42e064..0ea8c9887429 100644 ---- a/include/linux/jiffies.h -+++ b/include/linux/jiffies.h -@@ -537,7 +537,7 @@ static __always_inline unsigned long msecs_to_jiffies(const unsigned int m) - * - * Return: jiffies value - */ --#define secs_to_jiffies(_secs) ((_secs) * HZ) -+#define secs_to_jiffies(_secs) (unsigned long)((_secs) * HZ) - - extern unsigned long __usecs_to_jiffies(const unsigned int u); - #if !(USEC_PER_SEC % HZ) --- -2.51.0 - - -From 49b181f4b38d468ce212fe2926334a12260893d9 Mon Sep 17 00:00:00 2001 -From: Kuninori Morimoto -Date: Thu, 24 Oct 2024 02:20:02 +0000 -Subject: [PATCH 004/517] of: property: add of_graph_get_next_port() - -We have endpoint base functions - - of_graph_get_next_endpoint() - - of_graph_get_endpoint_count() - - for_each_endpoint_of_node() - -Here, for_each_endpoint_of_node() loop finds each endpoints - - ports { - port@0 { -(1) endpoint {...}; - }; - port@1 { -(2) endpoint {...}; - }; - ... - }; - -In above case, it finds endpoint as (1) -> (2) -> ... - -Basically, user/driver knows which port is used for what, but not in -all cases. For example on flexible/generic driver case, how many ports -are used is not fixed. - -For example Sound Generic Card driver which is very flexible/generic and -used from many venders can't know how many ports are used, and used for -what, because it depends on each vender SoC and/or its used board. - -And more, the port can have multi endpoints. For example Generic Sound -Card case, it supports many type of connection between CPU / Codec, and -some of them uses multi endpoint in one port. see below. - - ports { -(A) port@0 { -(1) endpoint@0 {...}; -(2) endpoint@1 {...}; - }; -(B) port@1 { -(3) endpoint {...}; - }; - ... - }; - -Generic Sound Card want to handle each connection via "port" base instead -of "endpoint" base. But, it is very difficult to handle each "port" via -existing for_each_endpoint_of_node(). Because getting each "port" via -of_get_parent() from each "endpoint" doesn't work. For example in above -case, both (1) (2) endpoint has same "port" (= A). - -Add "port" base functions. - -Signed-off-by: Kuninori Morimoto -Link: https://lore.kernel.org/r/87ldyeb5t9.wl-kuninori.morimoto.gx@renesas.com -Signed-off-by: Rob Herring (Arm) ---- - drivers/of/property.c | 54 ++++++++++++++++++++++++++++++++++++++++ - include/linux/of_graph.h | 28 +++++++++++++++++++++ - 2 files changed, 82 insertions(+) - -diff --git a/drivers/of/property.c b/drivers/of/property.c -index 906a33ae717f..7c8fb5dd4cb1 100644 ---- a/drivers/of/property.c -+++ b/drivers/of/property.c -@@ -630,6 +630,43 @@ struct device_node *of_graph_get_port_by_id(struct device_node *parent, u32 id) - } - EXPORT_SYMBOL(of_graph_get_port_by_id); - -+/** -+ * of_graph_get_next_port() - get next port node. -+ * @parent: pointer to the parent device node, or parent ports node -+ * @prev: previous port node, or NULL to get first -+ * -+ * Parent device node can be used as @parent whether device node has ports node -+ * or not. It will work same as ports@0 node. -+ * -+ * Return: A 'port' node pointer with refcount incremented. Refcount -+ * of the passed @prev node is decremented. -+ */ -+struct device_node *of_graph_get_next_port(const struct device_node *parent, -+ struct device_node *prev) -+{ -+ if (!parent) -+ return NULL; -+ -+ if (!prev) { -+ struct device_node *node __free(device_node) = -+ of_get_child_by_name(parent, "ports"); -+ -+ if (node) -+ parent = node; -+ -+ return of_get_child_by_name(parent, "port"); -+ } -+ -+ do { -+ prev = of_get_next_child(parent, prev); -+ if (!prev) -+ break; -+ } while (!of_node_name_eq(prev, "port")); -+ -+ return prev; -+} -+EXPORT_SYMBOL(of_graph_get_next_port); -+ - /** - * of_graph_get_next_endpoint() - get next endpoint node - * @parent: pointer to the parent device node -@@ -823,6 +860,23 @@ unsigned int of_graph_get_endpoint_count(const struct device_node *np) - } - EXPORT_SYMBOL(of_graph_get_endpoint_count); - -+/** -+ * of_graph_get_port_count() - get the number of port in a device or ports node -+ * @np: pointer to the device or ports node -+ * -+ * Return: count of port of this device or ports node -+ */ -+unsigned int of_graph_get_port_count(struct device_node *np) -+{ -+ unsigned int num = 0; -+ -+ for_each_of_graph_port(np, port) -+ num++; -+ -+ return num; -+} -+EXPORT_SYMBOL(of_graph_get_port_count); -+ - /** - * of_graph_get_remote_node() - get remote parent device_node for given port/endpoint - * @node: pointer to parent device_node containing graph port/endpoint -diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h -index a4bea62bfa29..44518f3583a4 100644 ---- a/include/linux/of_graph.h -+++ b/include/linux/of_graph.h -@@ -11,6 +11,7 @@ - #ifndef __LINUX_OF_GRAPH_H - #define __LINUX_OF_GRAPH_H - -+#include - #include - #include - -@@ -37,14 +38,29 @@ struct of_endpoint { - for (child = of_graph_get_next_endpoint(parent, NULL); child != NULL; \ - child = of_graph_get_next_endpoint(parent, child)) - -+/** -+ * for_each_of_graph_port - iterate over every port in a device or ports node -+ * @parent: parent device or ports node containing port -+ * @child: loop variable pointing to the current port node -+ * -+ * When breaking out of the loop, and continue to use the @child, you need to -+ * use return_ptr(@child) or no_free_ptr(@child) not to call __free() for it. -+ */ -+#define for_each_of_graph_port(parent, child) \ -+ for (struct device_node *child __free(device_node) = of_graph_get_next_port(parent, NULL);\ -+ child != NULL; child = of_graph_get_next_port(parent, child)) -+ - #ifdef CONFIG_OF - bool of_graph_is_present(const struct device_node *node); - int of_graph_parse_endpoint(const struct device_node *node, - struct of_endpoint *endpoint); - unsigned int of_graph_get_endpoint_count(const struct device_node *np); -+unsigned int of_graph_get_port_count(struct device_node *np); - struct device_node *of_graph_get_port_by_id(struct device_node *node, u32 id); - struct device_node *of_graph_get_next_endpoint(const struct device_node *parent, - struct device_node *previous); -+struct device_node *of_graph_get_next_port(const struct device_node *parent, -+ struct device_node *port); - struct device_node *of_graph_get_endpoint_by_regs( - const struct device_node *parent, int port_reg, int reg); - struct device_node *of_graph_get_remote_endpoint( -@@ -73,6 +89,11 @@ static inline unsigned int of_graph_get_endpoint_count(const struct device_node - return 0; - } - -+static inline unsigned int of_graph_get_port_count(struct device_node *np) -+{ -+ return 0; -+} -+ - static inline struct device_node *of_graph_get_port_by_id( - struct device_node *node, u32 id) - { -@@ -86,6 +107,13 @@ static inline struct device_node *of_graph_get_next_endpoint( - return NULL; - } - -+static inline struct device_node *of_graph_get_next_port( -+ const struct device_node *parent, -+ struct device_node *previous) -+{ -+ return NULL; -+} -+ - static inline struct device_node *of_graph_get_endpoint_by_regs( - const struct device_node *parent, int port_reg, int reg) - { --- -2.51.0 - - -From 380cec7c796666f368f79a4059b3b7533bc5afd9 Mon Sep 17 00:00:00 2001 -From: Cristian Ciocaltea -Date: Sat, 19 Oct 2024 14:16:00 +0300 -Subject: [PATCH 005/517] clk: Provide devm_clk_bulk_get_all_enabled() helper - -Commit 265b07df758a ("clk: Provide managed helper to get and enable bulk -clocks") added devm_clk_bulk_get_all_enable() function, but missed to -return the number of clocks stored in the clk_bulk_data table referenced -by the clks argument. Without knowing the number, it's not possible to -iterate these clocks when needed, hence the argument is useless and -could have been simply removed. - -Introduce devm_clk_bulk_get_all_enabled() variant, which is consistent -with devm_clk_bulk_get_all() in terms of the returned value: - - > 0 if one or more clocks have been stored - = 0 if there are no clocks - < 0 if an error occurred - -Moreover, the naming is consistent with devm_clk_get_enabled(), i.e. use -the past form of 'enable'. - -To reduce code duplication and improve patch readability, make -devm_clk_bulk_get_all_enable() use the new helper, as suggested by -Stephen Boyd. - -Reviewed-by: AngeloGioacchino Del Regno -Reviewed-by: Manivannan Sadhasivam -Signed-off-by: Cristian Ciocaltea -Link: https://lore.kernel.org/r/20241019-clk_bulk_ena_fix-v4-1-57f108f64e70@collabora.com -Signed-off-by: Stephen Boyd ---- - drivers/clk/clk-devres.c | 9 +++++---- - include/linux/clk.h | 21 ++++++++++++++++----- - 2 files changed, 21 insertions(+), 9 deletions(-) - -diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c -index 82ae1f26e634..5368d92d9b39 100644 ---- a/drivers/clk/clk-devres.c -+++ b/drivers/clk/clk-devres.c -@@ -218,8 +218,8 @@ static void devm_clk_bulk_release_all_enable(struct device *dev, void *res) - clk_bulk_put_all(devres->num_clks, devres->clks); - } - --int __must_check devm_clk_bulk_get_all_enable(struct device *dev, -- struct clk_bulk_data **clks) -+int __must_check devm_clk_bulk_get_all_enabled(struct device *dev, -+ struct clk_bulk_data **clks) - { - struct clk_bulk_devres *devres; - int ret; -@@ -244,11 +244,12 @@ int __must_check devm_clk_bulk_get_all_enable(struct device *dev, - } else { - clk_bulk_put_all(devres->num_clks, devres->clks); - devres_free(devres); -+ return ret; - } - -- return ret; -+ return devres->num_clks; - } --EXPORT_SYMBOL_GPL(devm_clk_bulk_get_all_enable); -+EXPORT_SYMBOL_GPL(devm_clk_bulk_get_all_enabled); - - static int devm_clk_match(struct device *dev, void *res, void *data) - { -diff --git a/include/linux/clk.h b/include/linux/clk.h -index 851a0f2cf42c..1dcee6d701e4 100644 ---- a/include/linux/clk.h -+++ b/include/linux/clk.h -@@ -496,11 +496,13 @@ int __must_check devm_clk_bulk_get_all(struct device *dev, - struct clk_bulk_data **clks); - - /** -- * devm_clk_bulk_get_all_enable - Get and enable all clocks of the consumer (managed) -+ * devm_clk_bulk_get_all_enabled - Get and enable all clocks of the consumer (managed) - * @dev: device for clock "consumer" - * @clks: pointer to the clk_bulk_data table of consumer - * -- * Returns success (0) or negative errno. -+ * Returns a positive value for the number of clocks obtained while the -+ * clock references are stored in the clk_bulk_data table in @clks field. -+ * Returns 0 if there're none and a negative value if something failed. - * - * This helper function allows drivers to get all clocks of the - * consumer and enables them in one operation with management. -@@ -508,8 +510,8 @@ int __must_check devm_clk_bulk_get_all(struct device *dev, - * is unbound. - */ - --int __must_check devm_clk_bulk_get_all_enable(struct device *dev, -- struct clk_bulk_data **clks); -+int __must_check devm_clk_bulk_get_all_enabled(struct device *dev, -+ struct clk_bulk_data **clks); - - /** - * devm_clk_get - lookup and obtain a managed reference to a clock producer. -@@ -1034,7 +1036,7 @@ static inline int __must_check devm_clk_bulk_get_all(struct device *dev, - return 0; - } - --static inline int __must_check devm_clk_bulk_get_all_enable(struct device *dev, -+static inline int __must_check devm_clk_bulk_get_all_enabled(struct device *dev, - struct clk_bulk_data **clks) - { - return 0; -@@ -1136,6 +1138,15 @@ static inline void clk_restore_context(void) {} - - #endif - -+/* Deprecated. Use devm_clk_bulk_get_all_enabled() */ -+static inline int __must_check -+devm_clk_bulk_get_all_enable(struct device *dev, struct clk_bulk_data **clks) -+{ -+ int ret = devm_clk_bulk_get_all_enabled(dev, clks); -+ -+ return ret > 0 ? 0 : ret; -+} -+ - /* clk_prepare_enable helps cases using clk_enable in non-atomic context. */ - static inline int clk_prepare_enable(struct clk *clk) - { --- -2.51.0 - - -From 15d25ea31ecbcaa422e8a49831e06e0b78af0037 Mon Sep 17 00:00:00 2001 -From: Kees Cook -Date: Thu, 12 Dec 2024 17:28:06 -0800 -Subject: [PATCH 006/517] fortify: Hide run-time copy size from value range - tracking -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -GCC performs value range tracking for variables as a way to provide better -diagnostics. One place this is regularly seen is with warnings associated -with bounds-checking, e.g. -Wstringop-overflow, -Wstringop-overread, --Warray-bounds, etc. In order to keep the signal-to-noise ratio high, -warnings aren't emitted when a value range spans the entire value range -representable by a given variable. For example: - - unsigned int len; - char dst[8]; - ... - memcpy(dst, src, len); - -If len's value is unknown, it has the full "unsigned int" range of [0, -UINT_MAX], and GCC's compile-time bounds checks against memcpy() will -be ignored. However, when a code path has been able to narrow the range: - - if (len > 16) - return; - memcpy(dst, src, len); - -Then the range will be updated for the execution path. Above, len is -now [0, 16] when reading memcpy(), so depending on other optimizations, -we might see a -Wstringop-overflow warning like: - - error: '__builtin_memcpy' writing between 9 and 16 bytes into region of size 8 [-Werror=stringop-overflow] - -When building with CONFIG_FORTIFY_SOURCE, the fortified run-time bounds -checking can appear to narrow value ranges of lengths for memcpy(), -depending on how the compiler constructs the execution paths during -optimization passes, due to the checks against the field sizes. For -example: - - if (p_size_field != SIZE_MAX && - p_size != p_size_field && p_size_field < size) - -As intentionally designed, these checks only affect the kernel warnings -emitted at run-time and do not block the potentially overflowing memcpy(), -so GCC thinks it needs to produce a warning about the resulting value -range that might be reaching the memcpy(). - -We have seen this manifest a few times now, with the most recent being -with cpumasks: - -In function ‘bitmap_copy’, - inlined from ‘cpumask_copy’ at ./include/linux/cpumask.h:839:2, - inlined from ‘__padata_set_cpumasks’ at kernel/padata.c:730:2: -./include/linux/fortify-string.h:114:33: error: ‘__builtin_memcpy’ reading between 257 and 536870904 bytes from a region of size 256 [-Werror=stringop-overread] - 114 | #define __underlying_memcpy __builtin_memcpy - | ^ -./include/linux/fortify-string.h:633:9: note: in expansion of macro ‘__underlying_memcpy’ - 633 | __underlying_##op(p, q, __fortify_size); \ - | ^~~~~~~~~~~~~ -./include/linux/fortify-string.h:678:26: note: in expansion of macro ‘__fortify_memcpy_chk’ - 678 | #define memcpy(p, q, s) __fortify_memcpy_chk(p, q, s, \ - | ^~~~~~~~~~~~~~~~~~~~ -./include/linux/bitmap.h:259:17: note: in expansion of macro ‘memcpy’ - 259 | memcpy(dst, src, len); - | ^~~~~~ -kernel/padata.c: In function ‘__padata_set_cpumasks’: -kernel/padata.c:713:48: note: source object ‘pcpumask’ of size [0, 256] - 713 | cpumask_var_t pcpumask, - | ~~~~~~~~~~~~~~^~~~~~~~ - -This warning is _not_ emitted when CONFIG_FORTIFY_SOURCE is disabled, -and with the recent -fdiagnostics-details we can confirm the origin of -the warning is due to FORTIFY's bounds checking: - -../include/linux/bitmap.h:259:17: note: in expansion of macro 'memcpy' - 259 | memcpy(dst, src, len); - | ^~~~~~ - '__padata_set_cpumasks': events 1-2 -../include/linux/fortify-string.h:613:36: - 612 | if (p_size_field != SIZE_MAX && - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 613 | p_size != p_size_field && p_size_field < size) - | ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~ - | | - | (1) when the condition is evaluated to false - | (2) when the condition is evaluated to true - '__padata_set_cpumasks': event 3 - 114 | #define __underlying_memcpy __builtin_memcpy - | ^ - | | - | (3) out of array bounds here - -Note that the cpumask warning started appearing since bitmap functions -were recently marked __always_inline in commit ed8cd2b3bd9f ("bitmap: -Switch from inline to __always_inline"), which allowed GCC to gain -visibility into the variables as they passed through the FORTIFY -implementation. - -In order to silence these false positives but keep otherwise deterministic -compile-time warnings intact, hide the length variable from GCC with -OPTIMIZE_HIDE_VAR() before calling the builtin memcpy. - -Additionally add a comment about why all the macro args have copies with -const storage. - -Reported-by: "Thomas Weißschuh" -Closes: https://lore.kernel.org/all/db7190c8-d17f-4a0d-bc2f-5903c79f36c2@t-8ch.de/ -Reported-by: Nilay Shroff -Closes: https://lore.kernel.org/all/20241112124127.1666300-1-nilay@linux.ibm.com/ -Tested-by: Nilay Shroff -Acked-by: Yury Norov -Acked-by: Greg Kroah-Hartman -Signed-off-by: Kees Cook ---- - include/linux/fortify-string.h | 14 +++++++++++++- - 1 file changed, 13 insertions(+), 1 deletion(-) - -diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h -index 71f9dcf56128..b3b53f8c1b28 100644 ---- a/include/linux/fortify-string.h -+++ b/include/linux/fortify-string.h -@@ -616,6 +616,12 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_size_t size, - return false; - } - -+/* -+ * To work around what seems to be an optimizer bug, the macro arguments -+ * need to have const copies or the values end up changed by the time they -+ * reach fortify_warn_once(). See commit 6f7630b1b5bc ("fortify: Capture -+ * __bos() results in const temp vars") for more details. -+ */ - #define __fortify_memcpy_chk(p, q, size, p_size, q_size, \ - p_size_field, q_size_field, op) ({ \ - const size_t __fortify_size = (size_t)(size); \ -@@ -623,6 +629,8 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_size_t size, - const size_t __q_size = (q_size); \ - const size_t __p_size_field = (p_size_field); \ - const size_t __q_size_field = (q_size_field); \ -+ /* Keep a mutable version of the size for the final copy. */ \ -+ size_t __copy_size = __fortify_size; \ - fortify_warn_once(fortify_memcpy_chk(__fortify_size, __p_size, \ - __q_size, __p_size_field, \ - __q_size_field, FORTIFY_FUNC_ ##op), \ -@@ -630,7 +638,11 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_size_t size, - __fortify_size, \ - "field \"" #p "\" at " FILE_LINE, \ - __p_size_field); \ -- __underlying_##op(p, q, __fortify_size); \ -+ /* Hide only the run-time size from value range tracking to */ \ -+ /* silence compile-time false positive bounds warnings. */ \ -+ if (!__builtin_constant_p(__copy_size)) \ -+ OPTIMIZER_HIDE_VAR(__copy_size); \ -+ __underlying_##op(p, q, __copy_size); \ - }) - - /* --- -2.51.0 - - -From 377e4603cc60869e907fd2e5c1a16d6749cf0cc0 Mon Sep 17 00:00:00 2001 -From: Bohdan Chubuk -Date: Sun, 10 Nov 2024 22:50:47 +0200 -Subject: [PATCH 007/517] mtd: spinand: add support for FORESEE F35SQA001G - -Add support for FORESEE F35SQA001G SPI NAND. - -Similar to F35SQA002G, but differs in capacity. -Datasheet: - - https://cdn.ozdisan.com/ETicaret_Dosya/704795_871495.pdf - -Tested on Xiaomi AX3000T flashed with OpenWRT. - -Signed-off-by: Bohdan Chubuk -Signed-off-by: Miquel Raynal ---- - drivers/mtd/nand/spi/foresee.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/drivers/mtd/nand/spi/foresee.c b/drivers/mtd/nand/spi/foresee.c -index e0d2d9257045..8a01582c0f53 100644 ---- a/drivers/mtd/nand/spi/foresee.c -+++ b/drivers/mtd/nand/spi/foresee.c -@@ -81,6 +81,16 @@ static const struct spinand_info foresee_spinand_table[] = { - SPINAND_HAS_QE_BIT, - SPINAND_ECCINFO(&f35sqa002g_ooblayout, - f35sqa002g_ecc_get_status)), -+ SPINAND_INFO("F35SQA001G", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x71, 0x71), -+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), -+ NAND_ECCREQ(1, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, -+ &write_cache_variants, -+ &update_cache_variants), -+ SPINAND_HAS_QE_BIT, -+ SPINAND_ECCINFO(&f35sqa002g_ooblayout, -+ f35sqa002g_ecc_get_status)), - }; - - static const struct spinand_manufacturer_ops foresee_spinand_manuf_ops = { --- -2.51.0 - - -From 747b700acdaf801e23257c4de2457df42706bbdb Mon Sep 17 00:00:00 2001 -From: Tianling Shen -Date: Mon, 25 Aug 2025 01:00:13 +0800 -Subject: [PATCH 008/517] mtd: spinand: add support for FudanMicro FM25S01A - -Add support for FudanMicro FM25S01A SPI NAND. -Datasheet: http://eng.fmsh.com/nvm/FM25S01A_ds_eng.pdf - -Signed-off-by: Tianling Shen -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20250824170013.3328777-1-cnsztl@gmail.com ---- - drivers/mtd/nand/spi/Makefile | 2 +- - drivers/mtd/nand/spi/core.c | 1 + - drivers/mtd/nand/spi/fmsh.c | 74 +++++++++++++++++++++++++++++++++++ - include/linux/mtd/spinand.h | 1 + - 4 files changed, 77 insertions(+), 1 deletion(-) - create mode 100644 drivers/mtd/nand/spi/fmsh.c - -diff --git a/drivers/mtd/nand/spi/Makefile b/drivers/mtd/nand/spi/Makefile -index 19cc77288ebb..32a696055d9f 100644 ---- a/drivers/mtd/nand/spi/Makefile -+++ b/drivers/mtd/nand/spi/Makefile -@@ -1,4 +1,4 @@ - # SPDX-License-Identifier: GPL-2.0 --spinand-objs := core.o alliancememory.o ato.o esmt.o foresee.o gigadevice.o macronix.o -+spinand-objs := core.o alliancememory.o ato.o esmt.o fmsh.o foresee.o gigadevice.o macronix.o - spinand-objs += micron.o paragon.o toshiba.o winbond.o xtx.o - obj-$(CONFIG_MTD_SPI_NAND) += spinand.o -diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c -index c523a1a22c2b..8e4c825b9789 100644 ---- a/drivers/mtd/nand/spi/core.c -+++ b/drivers/mtd/nand/spi/core.c -@@ -1115,6 +1115,7 @@ static const struct spinand_manufacturer *spinand_manufacturers[] = { - &alliancememory_spinand_manufacturer, - &ato_spinand_manufacturer, - &esmt_c8_spinand_manufacturer, -+ &fmsh_spinand_manufacturer, - &foresee_spinand_manufacturer, - &gigadevice_spinand_manufacturer, - ¯onix_spinand_manufacturer, -diff --git a/drivers/mtd/nand/spi/fmsh.c b/drivers/mtd/nand/spi/fmsh.c -new file mode 100644 -index 000000000000..71922d94f218 ---- /dev/null -+++ b/drivers/mtd/nand/spi/fmsh.c -@@ -0,0 +1,74 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (c) 2020-2021 Rockchip Electronics Co., Ltd. -+ * -+ * Author: Dingqiang Lin -+ */ -+ -+#include -+#include -+#include -+ -+#define SPINAND_MFR_FMSH 0xA1 -+ -+static SPINAND_OP_VARIANTS(read_cache_variants, -+ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); -+ -+static SPINAND_OP_VARIANTS(write_cache_variants, -+ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), -+ SPINAND_PROG_LOAD(true, 0, NULL, 0)); -+ -+static SPINAND_OP_VARIANTS(update_cache_variants, -+ SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), -+ SPINAND_PROG_LOAD(false, 0, NULL, 0)); -+ -+static int fm25s01a_ooblayout_ecc(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *region) -+{ -+ return -ERANGE; -+} -+ -+static int fm25s01a_ooblayout_free(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *region) -+{ -+ if (section) -+ return -ERANGE; -+ -+ region->offset = 2; -+ region->length = 62; -+ -+ return 0; -+} -+ -+static const struct mtd_ooblayout_ops fm25s01a_ooblayout = { -+ .ecc = fm25s01a_ooblayout_ecc, -+ .free = fm25s01a_ooblayout_free, -+}; -+ -+static const struct spinand_info fmsh_spinand_table[] = { -+ SPINAND_INFO("FM25S01A", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE4), -+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), -+ NAND_ECCREQ(1, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, -+ &write_cache_variants, -+ &update_cache_variants), -+ SPINAND_HAS_QE_BIT, -+ SPINAND_ECCINFO(&fm25s01a_ooblayout, NULL)), -+}; -+ -+static const struct spinand_manufacturer_ops fmsh_spinand_manuf_ops = { -+}; -+ -+const struct spinand_manufacturer fmsh_spinand_manufacturer = { -+ .id = SPINAND_MFR_FMSH, -+ .name = "Fudan Micro", -+ .chips = fmsh_spinand_table, -+ .nchips = ARRAY_SIZE(fmsh_spinand_table), -+ .ops = &fmsh_spinand_manuf_ops, -+}; -diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h -index 702e5fb13dae..ba7b73c9675e 100644 ---- a/include/linux/mtd/spinand.h -+++ b/include/linux/mtd/spinand.h -@@ -263,6 +263,7 @@ struct spinand_manufacturer { - extern const struct spinand_manufacturer alliancememory_spinand_manufacturer; - extern const struct spinand_manufacturer ato_spinand_manufacturer; - extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer; -+extern const struct spinand_manufacturer fmsh_spinand_manufacturer; - extern const struct spinand_manufacturer foresee_spinand_manufacturer; - extern const struct spinand_manufacturer gigadevice_spinand_manufacturer; - extern const struct spinand_manufacturer macronix_spinand_manufacturer; --- -2.51.0 - - -From ac22dde59c9dc55647118463603931a1ac92c942 Mon Sep 17 00:00:00 2001 -From: Markus Stockhausen -Date: Wed, 10 Sep 2025 14:32:58 -0400 -Subject: [PATCH 009/517] mtd: nand: move nand_check_erased_ecc_chunk() to - nand/core - -The check function for bitflips in erased blocks will be needed -by the Realtek ECC engine driver (which is currently under -development). Right now it is located in raw/nand_base.c. -While this is sufficient for the current usecases, there is -no real dependency for an ECC engine on the raw nand library. - -Move the function over to a more generic place in core library. - -Suggested-by: Miquel Raynal -Signed-off-by: Markus Stockhausen -Signed-off-by: Miquel Raynal ---- - drivers/mtd/nand/core.c | 131 +++++++++++++++++++++++++++++++ - drivers/mtd/nand/raw/nand_base.c | 131 ------------------------------- - include/linux/mtd/nand.h | 5 ++ - include/linux/mtd/rawnand.h | 5 -- - 4 files changed, 136 insertions(+), 136 deletions(-) - -diff --git a/drivers/mtd/nand/core.c b/drivers/mtd/nand/core.c -index 7737b1a4a177..3e76d127715f 100644 ---- a/drivers/mtd/nand/core.c -+++ b/drivers/mtd/nand/core.c -@@ -12,6 +12,137 @@ - #include - #include - -+/** -+ * nand_check_erased_buf - check if a buffer contains (almost) only 0xff data -+ * @buf: buffer to test -+ * @len: buffer length -+ * @bitflips_threshold: maximum number of bitflips -+ * -+ * Check if a buffer contains only 0xff, which means the underlying region -+ * has been erased and is ready to be programmed. -+ * The bitflips_threshold specify the maximum number of bitflips before -+ * considering the region is not erased. -+ * Note: The logic of this function has been extracted from the memweight -+ * implementation, except that nand_check_erased_buf function exit before -+ * testing the whole buffer if the number of bitflips exceed the -+ * bitflips_threshold value. -+ * -+ * Returns a positive number of bitflips less than or equal to -+ * bitflips_threshold, or -ERROR_CODE for bitflips in excess of the -+ * threshold. -+ */ -+static int nand_check_erased_buf(void *buf, int len, int bitflips_threshold) -+{ -+ const unsigned char *bitmap = buf; -+ int bitflips = 0; -+ int weight; -+ -+ for (; len && ((uintptr_t)bitmap) % sizeof(long); -+ len--, bitmap++) { -+ weight = hweight8(*bitmap); -+ bitflips += BITS_PER_BYTE - weight; -+ if (unlikely(bitflips > bitflips_threshold)) -+ return -EBADMSG; -+ } -+ -+ for (; len >= sizeof(long); -+ len -= sizeof(long), bitmap += sizeof(long)) { -+ unsigned long d = *((unsigned long *)bitmap); -+ if (d == ~0UL) -+ continue; -+ weight = hweight_long(d); -+ bitflips += BITS_PER_LONG - weight; -+ if (unlikely(bitflips > bitflips_threshold)) -+ return -EBADMSG; -+ } -+ -+ for (; len > 0; len--, bitmap++) { -+ weight = hweight8(*bitmap); -+ bitflips += BITS_PER_BYTE - weight; -+ if (unlikely(bitflips > bitflips_threshold)) -+ return -EBADMSG; -+ } -+ -+ return bitflips; -+} -+ -+/** -+ * nand_check_erased_ecc_chunk - check if an ECC chunk contains (almost) only -+ * 0xff data -+ * @data: data buffer to test -+ * @datalen: data length -+ * @ecc: ECC buffer -+ * @ecclen: ECC length -+ * @extraoob: extra OOB buffer -+ * @extraooblen: extra OOB length -+ * @bitflips_threshold: maximum number of bitflips -+ * -+ * Check if a data buffer and its associated ECC and OOB data contains only -+ * 0xff pattern, which means the underlying region has been erased and is -+ * ready to be programmed. -+ * The bitflips_threshold specify the maximum number of bitflips before -+ * considering the region as not erased. -+ * -+ * Note: -+ * 1/ ECC algorithms are working on pre-defined block sizes which are usually -+ * different from the NAND page size. When fixing bitflips, ECC engines will -+ * report the number of errors per chunk, and the NAND core infrastructure -+ * expect you to return the maximum number of bitflips for the whole page. -+ * This is why you should always use this function on a single chunk and -+ * not on the whole page. After checking each chunk you should update your -+ * max_bitflips value accordingly. -+ * 2/ When checking for bitflips in erased pages you should not only check -+ * the payload data but also their associated ECC data, because a user might -+ * have programmed almost all bits to 1 but a few. In this case, we -+ * shouldn't consider the chunk as erased, and checking ECC bytes prevent -+ * this case. -+ * 3/ The extraoob argument is optional, and should be used if some of your OOB -+ * data are protected by the ECC engine. -+ * It could also be used if you support subpages and want to attach some -+ * extra OOB data to an ECC chunk. -+ * -+ * Returns a positive number of bitflips less than or equal to -+ * bitflips_threshold, or -ERROR_CODE for bitflips in excess of the -+ * threshold. In case of success, the passed buffers are filled with 0xff. -+ */ -+int nand_check_erased_ecc_chunk(void *data, int datalen, -+ void *ecc, int ecclen, -+ void *extraoob, int extraooblen, -+ int bitflips_threshold) -+{ -+ int data_bitflips = 0, ecc_bitflips = 0, extraoob_bitflips = 0; -+ -+ data_bitflips = nand_check_erased_buf(data, datalen, -+ bitflips_threshold); -+ if (data_bitflips < 0) -+ return data_bitflips; -+ -+ bitflips_threshold -= data_bitflips; -+ -+ ecc_bitflips = nand_check_erased_buf(ecc, ecclen, bitflips_threshold); -+ if (ecc_bitflips < 0) -+ return ecc_bitflips; -+ -+ bitflips_threshold -= ecc_bitflips; -+ -+ extraoob_bitflips = nand_check_erased_buf(extraoob, extraooblen, -+ bitflips_threshold); -+ if (extraoob_bitflips < 0) -+ return extraoob_bitflips; -+ -+ if (data_bitflips) -+ memset(data, 0xff, datalen); -+ -+ if (ecc_bitflips) -+ memset(ecc, 0xff, ecclen); -+ -+ if (extraoob_bitflips) -+ memset(extraoob, 0xff, extraooblen); -+ -+ return data_bitflips + ecc_bitflips + extraoob_bitflips; -+} -+EXPORT_SYMBOL(nand_check_erased_ecc_chunk); -+ - /** - * nanddev_isbad() - Check if a block is bad - * @nand: NAND device -diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c -index 53e16d39af4b..c1f785a8b7e5 100644 ---- a/drivers/mtd/nand/raw/nand_base.c -+++ b/drivers/mtd/nand/raw/nand_base.c -@@ -2783,137 +2783,6 @@ int nand_set_features(struct nand_chip *chip, int addr, - return nand_set_features_op(chip, addr, subfeature_param); - } - --/** -- * nand_check_erased_buf - check if a buffer contains (almost) only 0xff data -- * @buf: buffer to test -- * @len: buffer length -- * @bitflips_threshold: maximum number of bitflips -- * -- * Check if a buffer contains only 0xff, which means the underlying region -- * has been erased and is ready to be programmed. -- * The bitflips_threshold specify the maximum number of bitflips before -- * considering the region is not erased. -- * Note: The logic of this function has been extracted from the memweight -- * implementation, except that nand_check_erased_buf function exit before -- * testing the whole buffer if the number of bitflips exceed the -- * bitflips_threshold value. -- * -- * Returns a positive number of bitflips less than or equal to -- * bitflips_threshold, or -ERROR_CODE for bitflips in excess of the -- * threshold. -- */ --static int nand_check_erased_buf(void *buf, int len, int bitflips_threshold) --{ -- const unsigned char *bitmap = buf; -- int bitflips = 0; -- int weight; -- -- for (; len && ((uintptr_t)bitmap) % sizeof(long); -- len--, bitmap++) { -- weight = hweight8(*bitmap); -- bitflips += BITS_PER_BYTE - weight; -- if (unlikely(bitflips > bitflips_threshold)) -- return -EBADMSG; -- } -- -- for (; len >= sizeof(long); -- len -= sizeof(long), bitmap += sizeof(long)) { -- unsigned long d = *((unsigned long *)bitmap); -- if (d == ~0UL) -- continue; -- weight = hweight_long(d); -- bitflips += BITS_PER_LONG - weight; -- if (unlikely(bitflips > bitflips_threshold)) -- return -EBADMSG; -- } -- -- for (; len > 0; len--, bitmap++) { -- weight = hweight8(*bitmap); -- bitflips += BITS_PER_BYTE - weight; -- if (unlikely(bitflips > bitflips_threshold)) -- return -EBADMSG; -- } -- -- return bitflips; --} -- --/** -- * nand_check_erased_ecc_chunk - check if an ECC chunk contains (almost) only -- * 0xff data -- * @data: data buffer to test -- * @datalen: data length -- * @ecc: ECC buffer -- * @ecclen: ECC length -- * @extraoob: extra OOB buffer -- * @extraooblen: extra OOB length -- * @bitflips_threshold: maximum number of bitflips -- * -- * Check if a data buffer and its associated ECC and OOB data contains only -- * 0xff pattern, which means the underlying region has been erased and is -- * ready to be programmed. -- * The bitflips_threshold specify the maximum number of bitflips before -- * considering the region as not erased. -- * -- * Note: -- * 1/ ECC algorithms are working on pre-defined block sizes which are usually -- * different from the NAND page size. When fixing bitflips, ECC engines will -- * report the number of errors per chunk, and the NAND core infrastructure -- * expect you to return the maximum number of bitflips for the whole page. -- * This is why you should always use this function on a single chunk and -- * not on the whole page. After checking each chunk you should update your -- * max_bitflips value accordingly. -- * 2/ When checking for bitflips in erased pages you should not only check -- * the payload data but also their associated ECC data, because a user might -- * have programmed almost all bits to 1 but a few. In this case, we -- * shouldn't consider the chunk as erased, and checking ECC bytes prevent -- * this case. -- * 3/ The extraoob argument is optional, and should be used if some of your OOB -- * data are protected by the ECC engine. -- * It could also be used if you support subpages and want to attach some -- * extra OOB data to an ECC chunk. -- * -- * Returns a positive number of bitflips less than or equal to -- * bitflips_threshold, or -ERROR_CODE for bitflips in excess of the -- * threshold. In case of success, the passed buffers are filled with 0xff. -- */ --int nand_check_erased_ecc_chunk(void *data, int datalen, -- void *ecc, int ecclen, -- void *extraoob, int extraooblen, -- int bitflips_threshold) --{ -- int data_bitflips = 0, ecc_bitflips = 0, extraoob_bitflips = 0; -- -- data_bitflips = nand_check_erased_buf(data, datalen, -- bitflips_threshold); -- if (data_bitflips < 0) -- return data_bitflips; -- -- bitflips_threshold -= data_bitflips; -- -- ecc_bitflips = nand_check_erased_buf(ecc, ecclen, bitflips_threshold); -- if (ecc_bitflips < 0) -- return ecc_bitflips; -- -- bitflips_threshold -= ecc_bitflips; -- -- extraoob_bitflips = nand_check_erased_buf(extraoob, extraooblen, -- bitflips_threshold); -- if (extraoob_bitflips < 0) -- return extraoob_bitflips; -- -- if (data_bitflips) -- memset(data, 0xff, datalen); -- -- if (ecc_bitflips) -- memset(ecc, 0xff, ecclen); -- -- if (extraoob_bitflips) -- memset(extraoob, 0xff, extraooblen); -- -- return data_bitflips + ecc_bitflips + extraoob_bitflips; --} --EXPORT_SYMBOL(nand_check_erased_ecc_chunk); -- - /** - * nand_read_page_raw_notsupp - dummy read raw page function - * @chip: nand chip info structure -diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h -index 1e4208040956..f4ee1e4bc18f 100644 ---- a/include/linux/mtd/nand.h -+++ b/include/linux/mtd/nand.h -@@ -1136,4 +1136,9 @@ static inline bool nanddev_bbt_is_initialized(struct nand_device *nand) - int nanddev_mtd_erase(struct mtd_info *mtd, struct erase_info *einfo); - int nanddev_mtd_max_bad_blocks(struct mtd_info *mtd, loff_t offs, size_t len); - -+int nand_check_erased_ecc_chunk(void *data, int datalen, -+ void *ecc, int ecclen, -+ void *extraoob, int extraooblen, -+ int threshold); -+ - #endif /* __LINUX_MTD_NAND_H */ -diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h -index e84522e31301..d30bdc3fcfd7 100644 ---- a/include/linux/mtd/rawnand.h -+++ b/include/linux/mtd/rawnand.h -@@ -1519,11 +1519,6 @@ int rawnand_sw_bch_correct(struct nand_chip *chip, unsigned char *buf, - unsigned char *read_ecc, unsigned char *calc_ecc); - void rawnand_sw_bch_cleanup(struct nand_chip *chip); - --int nand_check_erased_ecc_chunk(void *data, int datalen, -- void *ecc, int ecclen, -- void *extraoob, int extraooblen, -- int threshold); -- - int nand_ecc_choose_conf(struct nand_chip *chip, - const struct nand_ecc_caps *caps, int oobavail); - --- -2.51.0 - - -From 7b26769b0e737b7f7ecb5b0201a0cbf5a72ed150 Mon Sep 17 00:00:00 2001 -From: Md Sadre Alam -Date: Wed, 20 Nov 2024 14:45:00 +0530 -Subject: [PATCH 010/517] mtd: rawnand: qcom: cleanup qcom_nandc driver - -Perform a global cleanup of the Qualcomm NAND -controller driver with the following improvements: - -- Remove register value indirection API - -- Remove set_reg() API - -- Convert read_loc_first & read_loc_last macro to functions - -- Rename multiple variables - -Signed-off-by: Md Sadre Alam -Signed-off-by: Miquel Raynal ---- - drivers/mtd/nand/raw/qcom_nandc.c | 520 ++++++++++++++---------------- - 1 file changed, 236 insertions(+), 284 deletions(-) - -diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c -index 275d34119acd..94a57a0de067 100644 ---- a/drivers/mtd/nand/raw/qcom_nandc.c -+++ b/drivers/mtd/nand/raw/qcom_nandc.c -@@ -189,17 +189,6 @@ - #define ECC_BCH_4BIT BIT(2) - #define ECC_BCH_8BIT BIT(3) - --#define nandc_set_read_loc_first(chip, reg, cw_offset, read_size, is_last_read_loc) \ --nandc_set_reg(chip, reg, \ -- ((cw_offset) << READ_LOCATION_OFFSET) | \ -- ((read_size) << READ_LOCATION_SIZE) | \ -- ((is_last_read_loc) << READ_LOCATION_LAST)) -- --#define nandc_set_read_loc_last(chip, reg, cw_offset, read_size, is_last_read_loc) \ --nandc_set_reg(chip, reg, \ -- ((cw_offset) << READ_LOCATION_OFFSET) | \ -- ((read_size) << READ_LOCATION_SIZE) | \ -- ((is_last_read_loc) << READ_LOCATION_LAST)) - /* - * Returns the actual register address for all NAND_DEV_ registers - * (i.e. NAND_DEV_CMD0, NAND_DEV_CMD1, NAND_DEV_CMD2 and NAND_DEV_CMD_VLD) -@@ -257,8 +246,6 @@ nandc_set_reg(chip, reg, \ - * @tx_sgl_start - start index in data sgl for tx. - * @rx_sgl_pos - current index in data sgl for rx. - * @rx_sgl_start - start index in data sgl for rx. -- * @wait_second_completion - wait for second DMA desc completion before making -- * the NAND transfer completion. - */ - struct bam_transaction { - struct bam_cmd_element *bam_ce; -@@ -275,7 +262,6 @@ struct bam_transaction { - u32 tx_sgl_start; - u32 rx_sgl_pos; - u32 rx_sgl_start; -- bool wait_second_completion; - }; - - /* -@@ -471,9 +457,9 @@ struct qcom_op { - unsigned int data_instr_idx; - unsigned int rdy_timeout_ms; - unsigned int rdy_delay_ns; -- u32 addr1_reg; -- u32 addr2_reg; -- u32 cmd_reg; -+ __le32 addr1_reg; -+ __le32 addr2_reg; -+ __le32 cmd_reg; - u8 flag; - }; - -@@ -549,17 +535,17 @@ struct qcom_nand_host { - * among different NAND controllers. - * @ecc_modes - ecc mode for NAND - * @dev_cmd_reg_start - NAND_DEV_CMD_* registers starting offset -- * @is_bam - whether NAND controller is using BAM -- * @is_qpic - whether NAND CTRL is part of qpic IP -- * @qpic_v2 - flag to indicate QPIC IP version 2 -+ * @supports_bam - whether NAND controller is using Bus Access Manager (BAM) -+ * @nandc_part_of_qpic - whether NAND controller is part of qpic IP -+ * @qpic_version2 - flag to indicate QPIC IP version 2 - * @use_codeword_fixup - whether NAND has different layout for boot partitions - */ - struct qcom_nandc_props { - u32 ecc_modes; - u32 dev_cmd_reg_start; -- bool is_bam; -- bool is_qpic; -- bool qpic_v2; -+ bool supports_bam; -+ bool nandc_part_of_qpic; -+ bool qpic_version2; - bool use_codeword_fixup; - }; - -@@ -613,19 +599,11 @@ static void clear_bam_transaction(struct qcom_nand_controller *nandc) - { - struct bam_transaction *bam_txn = nandc->bam_txn; - -- if (!nandc->props->is_bam) -+ if (!nandc->props->supports_bam) - return; - -- bam_txn->bam_ce_pos = 0; -- bam_txn->bam_ce_start = 0; -- bam_txn->cmd_sgl_pos = 0; -- bam_txn->cmd_sgl_start = 0; -- bam_txn->tx_sgl_pos = 0; -- bam_txn->tx_sgl_start = 0; -- bam_txn->rx_sgl_pos = 0; -- bam_txn->rx_sgl_start = 0; -+ memset(&bam_txn->bam_ce_pos, 0, sizeof(u32) * 8); - bam_txn->last_data_desc = NULL; -- bam_txn->wait_second_completion = false; - - sg_init_table(bam_txn->cmd_sgl, nandc->max_cwperpage * - QPIC_PER_CW_CMD_SGL); -@@ -640,46 +618,35 @@ static void qpic_bam_dma_done(void *data) - { - struct bam_transaction *bam_txn = data; - -- /* -- * In case of data transfer with NAND, 2 callbacks will be generated. -- * One for command channel and another one for data channel. -- * If current transaction has data descriptors -- * (i.e. wait_second_completion is true), then set this to false -- * and wait for second DMA descriptor completion. -- */ -- if (bam_txn->wait_second_completion) -- bam_txn->wait_second_completion = false; -- else -- complete(&bam_txn->txn_done); -+ complete(&bam_txn->txn_done); - } - --static inline struct qcom_nand_host *to_qcom_nand_host(struct nand_chip *chip) -+static struct qcom_nand_host *to_qcom_nand_host(struct nand_chip *chip) - { - return container_of(chip, struct qcom_nand_host, chip); - } - --static inline struct qcom_nand_controller * -+static struct qcom_nand_controller * - get_qcom_nand_controller(struct nand_chip *chip) - { - return container_of(chip->controller, struct qcom_nand_controller, - controller); - } - --static inline u32 nandc_read(struct qcom_nand_controller *nandc, int offset) -+static u32 nandc_read(struct qcom_nand_controller *nandc, int offset) - { - return ioread32(nandc->base + offset); - } - --static inline void nandc_write(struct qcom_nand_controller *nandc, int offset, -- u32 val) -+static void nandc_write(struct qcom_nand_controller *nandc, int offset, -+ u32 val) - { - iowrite32(val, nandc->base + offset); - } - --static inline void nandc_read_buffer_sync(struct qcom_nand_controller *nandc, -- bool is_cpu) -+static void nandc_dev_to_mem(struct qcom_nand_controller *nandc, bool is_cpu) - { -- if (!nandc->props->is_bam) -+ if (!nandc->props->supports_bam) - return; - - if (is_cpu) -@@ -694,93 +661,90 @@ static inline void nandc_read_buffer_sync(struct qcom_nand_controller *nandc, - DMA_FROM_DEVICE); - } - --static __le32 *offset_to_nandc_reg(struct nandc_regs *regs, int offset) --{ -- switch (offset) { -- case NAND_FLASH_CMD: -- return ®s->cmd; -- case NAND_ADDR0: -- return ®s->addr0; -- case NAND_ADDR1: -- return ®s->addr1; -- case NAND_FLASH_CHIP_SELECT: -- return ®s->chip_sel; -- case NAND_EXEC_CMD: -- return ®s->exec; -- case NAND_FLASH_STATUS: -- return ®s->clrflashstatus; -- case NAND_DEV0_CFG0: -- return ®s->cfg0; -- case NAND_DEV0_CFG1: -- return ®s->cfg1; -- case NAND_DEV0_ECC_CFG: -- return ®s->ecc_bch_cfg; -- case NAND_READ_STATUS: -- return ®s->clrreadstatus; -- case NAND_DEV_CMD1: -- return ®s->cmd1; -- case NAND_DEV_CMD1_RESTORE: -- return ®s->orig_cmd1; -- case NAND_DEV_CMD_VLD: -- return ®s->vld; -- case NAND_DEV_CMD_VLD_RESTORE: -- return ®s->orig_vld; -- case NAND_EBI2_ECC_BUF_CFG: -- return ®s->ecc_buf_cfg; -- case NAND_READ_LOCATION_0: -- return ®s->read_location0; -- case NAND_READ_LOCATION_1: -- return ®s->read_location1; -- case NAND_READ_LOCATION_2: -- return ®s->read_location2; -- case NAND_READ_LOCATION_3: -- return ®s->read_location3; -- case NAND_READ_LOCATION_LAST_CW_0: -- return ®s->read_location_last0; -- case NAND_READ_LOCATION_LAST_CW_1: -- return ®s->read_location_last1; -- case NAND_READ_LOCATION_LAST_CW_2: -- return ®s->read_location_last2; -- case NAND_READ_LOCATION_LAST_CW_3: -- return ®s->read_location_last3; -- default: -- return NULL; -- } -+/* Helper to check whether this is the last CW or not */ -+static bool qcom_nandc_is_last_cw(struct nand_ecc_ctrl *ecc, int cw) -+{ -+ return cw == (ecc->steps - 1); - } - --static void nandc_set_reg(struct nand_chip *chip, int offset, -- u32 val) -+/** -+ * nandc_set_read_loc_first() - to set read location first register -+ * @chip: NAND Private Flash Chip Data -+ * @reg_base: location register base -+ * @cw_offset: code word offset -+ * @read_size: code word read length -+ * @is_last_read_loc: is this the last read location -+ * -+ * This function will set location register value -+ */ -+static void nandc_set_read_loc_first(struct nand_chip *chip, -+ int reg_base, u32 cw_offset, -+ u32 read_size, u32 is_last_read_loc) - { - struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); -- struct nandc_regs *regs = nandc->regs; -- __le32 *reg; -- -- reg = offset_to_nandc_reg(regs, offset); -+ __le32 locreg_val; -+ u32 val = (((cw_offset) << READ_LOCATION_OFFSET) | -+ ((read_size) << READ_LOCATION_SIZE) | -+ ((is_last_read_loc) << READ_LOCATION_LAST)); -+ -+ locreg_val = cpu_to_le32(val); -+ -+ if (reg_base == NAND_READ_LOCATION_0) -+ nandc->regs->read_location0 = locreg_val; -+ else if (reg_base == NAND_READ_LOCATION_1) -+ nandc->regs->read_location1 = locreg_val; -+ else if (reg_base == NAND_READ_LOCATION_2) -+ nandc->regs->read_location2 = locreg_val; -+ else if (reg_base == NAND_READ_LOCATION_3) -+ nandc->regs->read_location3 = locreg_val; -+} -+ -+/** -+ * nandc_set_read_loc_last - to set read location last register -+ * @chip: NAND Private Flash Chip Data -+ * @reg_base: location register base -+ * @cw_offset: code word offset -+ * @read_size: code word read length -+ * @is_last_read_loc: is this the last read location -+ * -+ * This function will set location last register value -+ */ -+static void nandc_set_read_loc_last(struct nand_chip *chip, -+ int reg_base, u32 cw_offset, -+ u32 read_size, u32 is_last_read_loc) -+{ -+ struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); -+ __le32 locreg_val; -+ u32 val = (((cw_offset) << READ_LOCATION_OFFSET) | -+ ((read_size) << READ_LOCATION_SIZE) | -+ ((is_last_read_loc) << READ_LOCATION_LAST)); - -- if (reg) -- *reg = cpu_to_le32(val); --} -+ locreg_val = cpu_to_le32(val); - --/* Helper to check the code word, whether it is last cw or not */ --static bool qcom_nandc_is_last_cw(struct nand_ecc_ctrl *ecc, int cw) --{ -- return cw == (ecc->steps - 1); -+ if (reg_base == NAND_READ_LOCATION_LAST_CW_0) -+ nandc->regs->read_location_last0 = locreg_val; -+ else if (reg_base == NAND_READ_LOCATION_LAST_CW_1) -+ nandc->regs->read_location_last1 = locreg_val; -+ else if (reg_base == NAND_READ_LOCATION_LAST_CW_2) -+ nandc->regs->read_location_last2 = locreg_val; -+ else if (reg_base == NAND_READ_LOCATION_LAST_CW_3) -+ nandc->regs->read_location_last3 = locreg_val; - } - - /* helper to configure location register values */ - static void nandc_set_read_loc(struct nand_chip *chip, int cw, int reg, -- int cw_offset, int read_size, int is_last_read_loc) -+ u32 cw_offset, u32 read_size, u32 is_last_read_loc) - { - struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); - struct nand_ecc_ctrl *ecc = &chip->ecc; - int reg_base = NAND_READ_LOCATION_0; - -- if (nandc->props->qpic_v2 && qcom_nandc_is_last_cw(ecc, cw)) -+ if (nandc->props->qpic_version2 && qcom_nandc_is_last_cw(ecc, cw)) - reg_base = NAND_READ_LOCATION_LAST_CW_0; - - reg_base += reg * 4; - -- if (nandc->props->qpic_v2 && qcom_nandc_is_last_cw(ecc, cw)) -+ if (nandc->props->qpic_version2 && qcom_nandc_is_last_cw(ecc, cw)) - return nandc_set_read_loc_last(chip, reg_base, cw_offset, - read_size, is_last_read_loc); - else -@@ -792,12 +756,13 @@ static void nandc_set_read_loc(struct nand_chip *chip, int cw, int reg, - static void set_address(struct qcom_nand_host *host, u16 column, int page) - { - struct nand_chip *chip = &host->chip; -+ struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); - - if (chip->options & NAND_BUSWIDTH_16) - column >>= 1; - -- nandc_set_reg(chip, NAND_ADDR0, page << 16 | column); -- nandc_set_reg(chip, NAND_ADDR1, page >> 16 & 0xff); -+ nandc->regs->addr0 = cpu_to_le32(page << 16 | column); -+ nandc->regs->addr1 = cpu_to_le32(page >> 16 & 0xff); - } - - /* -@@ -811,41 +776,43 @@ static void set_address(struct qcom_nand_host *host, u16 column, int page) - static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read, int cw) - { - struct nand_chip *chip = &host->chip; -- u32 cmd, cfg0, cfg1, ecc_bch_cfg; -+ __le32 cmd, cfg0, cfg1, ecc_bch_cfg; - struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); - - if (read) { - if (host->use_ecc) -- cmd = OP_PAGE_READ_WITH_ECC | PAGE_ACC | LAST_PAGE; -+ cmd = cpu_to_le32(OP_PAGE_READ_WITH_ECC | PAGE_ACC | LAST_PAGE); - else -- cmd = OP_PAGE_READ | PAGE_ACC | LAST_PAGE; -+ cmd = cpu_to_le32(OP_PAGE_READ | PAGE_ACC | LAST_PAGE); - } else { -- cmd = OP_PROGRAM_PAGE | PAGE_ACC | LAST_PAGE; -+ cmd = cpu_to_le32(OP_PROGRAM_PAGE | PAGE_ACC | LAST_PAGE); - } - - if (host->use_ecc) { -- cfg0 = (host->cfg0 & ~(7U << CW_PER_PAGE)) | -- (num_cw - 1) << CW_PER_PAGE; -+ cfg0 = cpu_to_le32((host->cfg0 & ~(7U << CW_PER_PAGE)) | -+ (num_cw - 1) << CW_PER_PAGE); - -- cfg1 = host->cfg1; -- ecc_bch_cfg = host->ecc_bch_cfg; -+ cfg1 = cpu_to_le32(host->cfg1); -+ ecc_bch_cfg = cpu_to_le32(host->ecc_bch_cfg); - } else { -- cfg0 = (host->cfg0_raw & ~(7U << CW_PER_PAGE)) | -- (num_cw - 1) << CW_PER_PAGE; -+ cfg0 = cpu_to_le32((host->cfg0_raw & ~(7U << CW_PER_PAGE)) | -+ (num_cw - 1) << CW_PER_PAGE); - -- cfg1 = host->cfg1_raw; -- ecc_bch_cfg = 1 << ECC_CFG_ECC_DISABLE; -+ cfg1 = cpu_to_le32(host->cfg1_raw); -+ ecc_bch_cfg = cpu_to_le32(1 << ECC_CFG_ECC_DISABLE); - } - -- nandc_set_reg(chip, NAND_FLASH_CMD, cmd); -- nandc_set_reg(chip, NAND_DEV0_CFG0, cfg0); -- nandc_set_reg(chip, NAND_DEV0_CFG1, cfg1); -- nandc_set_reg(chip, NAND_DEV0_ECC_CFG, ecc_bch_cfg); -- if (!nandc->props->qpic_v2) -- nandc_set_reg(chip, NAND_EBI2_ECC_BUF_CFG, host->ecc_buf_cfg); -- nandc_set_reg(chip, NAND_FLASH_STATUS, host->clrflashstatus); -- nandc_set_reg(chip, NAND_READ_STATUS, host->clrreadstatus); -- nandc_set_reg(chip, NAND_EXEC_CMD, 1); -+ nandc->regs->cmd = cmd; -+ nandc->regs->cfg0 = cfg0; -+ nandc->regs->cfg1 = cfg1; -+ nandc->regs->ecc_bch_cfg = ecc_bch_cfg; -+ -+ if (!nandc->props->qpic_version2) -+ nandc->regs->ecc_buf_cfg = cpu_to_le32(host->ecc_buf_cfg); -+ -+ nandc->regs->clrflashstatus = cpu_to_le32(host->clrflashstatus); -+ nandc->regs->clrreadstatus = cpu_to_le32(host->clrreadstatus); -+ nandc->regs->exec = cpu_to_le32(1); - - if (read) - nandc_set_read_loc(chip, cw, 0, 0, host->use_ecc ? -@@ -1121,7 +1088,7 @@ static int read_reg_dma(struct qcom_nand_controller *nandc, int first, - if (first == NAND_DEV_CMD_VLD || first == NAND_DEV_CMD1) - first = dev_cmd_reg_addr(nandc, first); - -- if (nandc->props->is_bam) -+ if (nandc->props->supports_bam) - return prep_bam_dma_desc_cmd(nandc, true, first, vaddr, - num_regs, flags); - -@@ -1136,25 +1103,16 @@ static int read_reg_dma(struct qcom_nand_controller *nandc, int first, - * write_reg_dma: prepares a descriptor to write a given number of - * contiguous registers - * -+ * @vaddr: contiguous memory from where register value will -+ * be written - * @first: offset of the first register in the contiguous block - * @num_regs: number of registers to write - * @flags: flags to control DMA descriptor preparation - */ --static int write_reg_dma(struct qcom_nand_controller *nandc, int first, -- int num_regs, unsigned int flags) -+static int write_reg_dma(struct qcom_nand_controller *nandc, __le32 *vaddr, -+ int first, int num_regs, unsigned int flags) - { - bool flow_control = false; -- struct nandc_regs *regs = nandc->regs; -- void *vaddr; -- -- vaddr = offset_to_nandc_reg(regs, first); -- -- if (first == NAND_ERASED_CW_DETECT_CFG) { -- if (flags & NAND_ERASED_CW_SET) -- vaddr = ®s->erased_cw_detect_cfg_set; -- else -- vaddr = ®s->erased_cw_detect_cfg_clr; -- } - - if (first == NAND_EXEC_CMD) - flags |= NAND_BAM_NWD; -@@ -1165,7 +1123,7 @@ static int write_reg_dma(struct qcom_nand_controller *nandc, int first, - if (first == NAND_DEV_CMD_VLD_RESTORE || first == NAND_DEV_CMD_VLD) - first = dev_cmd_reg_addr(nandc, NAND_DEV_CMD_VLD); - -- if (nandc->props->is_bam) -+ if (nandc->props->supports_bam) - return prep_bam_dma_desc_cmd(nandc, false, first, vaddr, - num_regs, flags); - -@@ -1188,7 +1146,7 @@ static int write_reg_dma(struct qcom_nand_controller *nandc, int first, - static int read_data_dma(struct qcom_nand_controller *nandc, int reg_off, - const u8 *vaddr, int size, unsigned int flags) - { -- if (nandc->props->is_bam) -+ if (nandc->props->supports_bam) - return prep_bam_dma_desc_data(nandc, true, vaddr, size, flags); - - return prep_adm_dma_desc(nandc, true, reg_off, vaddr, size, false); -@@ -1206,7 +1164,7 @@ static int read_data_dma(struct qcom_nand_controller *nandc, int reg_off, - static int write_data_dma(struct qcom_nand_controller *nandc, int reg_off, - const u8 *vaddr, int size, unsigned int flags) - { -- if (nandc->props->is_bam) -+ if (nandc->props->supports_bam) - return prep_bam_dma_desc_data(nandc, false, vaddr, size, flags); - - return prep_adm_dma_desc(nandc, false, reg_off, vaddr, size, false); -@@ -1220,13 +1178,14 @@ static void config_nand_page_read(struct nand_chip *chip) - { - struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); - -- write_reg_dma(nandc, NAND_ADDR0, 2, 0); -- write_reg_dma(nandc, NAND_DEV0_CFG0, 3, 0); -- if (!nandc->props->qpic_v2) -- write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1, 0); -- write_reg_dma(nandc, NAND_ERASED_CW_DETECT_CFG, 1, 0); -- write_reg_dma(nandc, NAND_ERASED_CW_DETECT_CFG, 1, -- NAND_ERASED_CW_SET | NAND_BAM_NEXT_SGL); -+ write_reg_dma(nandc, &nandc->regs->addr0, NAND_ADDR0, 2, 0); -+ write_reg_dma(nandc, &nandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0); -+ if (!nandc->props->qpic_version2) -+ write_reg_dma(nandc, &nandc->regs->ecc_buf_cfg, NAND_EBI2_ECC_BUF_CFG, 1, 0); -+ write_reg_dma(nandc, &nandc->regs->erased_cw_detect_cfg_clr, -+ NAND_ERASED_CW_DETECT_CFG, 1, 0); -+ write_reg_dma(nandc, &nandc->regs->erased_cw_detect_cfg_set, -+ NAND_ERASED_CW_DETECT_CFG, 1, NAND_ERASED_CW_SET | NAND_BAM_NEXT_SGL); - } - - /* -@@ -1239,16 +1198,16 @@ config_nand_cw_read(struct nand_chip *chip, bool use_ecc, int cw) - struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); - struct nand_ecc_ctrl *ecc = &chip->ecc; - -- int reg = NAND_READ_LOCATION_0; -+ __le32 *reg = &nandc->regs->read_location0; - -- if (nandc->props->qpic_v2 && qcom_nandc_is_last_cw(ecc, cw)) -- reg = NAND_READ_LOCATION_LAST_CW_0; -+ if (nandc->props->qpic_version2 && qcom_nandc_is_last_cw(ecc, cw)) -+ reg = &nandc->regs->read_location_last0; - -- if (nandc->props->is_bam) -- write_reg_dma(nandc, reg, 4, NAND_BAM_NEXT_SGL); -+ if (nandc->props->supports_bam) -+ write_reg_dma(nandc, reg, NAND_READ_LOCATION_0, 4, NAND_BAM_NEXT_SGL); - -- write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL); -- write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); -+ write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL); -+ write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); - - if (use_ecc) { - read_reg_dma(nandc, NAND_FLASH_STATUS, 2, 0); -@@ -1279,10 +1238,10 @@ static void config_nand_page_write(struct nand_chip *chip) - { - struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); - -- write_reg_dma(nandc, NAND_ADDR0, 2, 0); -- write_reg_dma(nandc, NAND_DEV0_CFG0, 3, 0); -- if (!nandc->props->qpic_v2) -- write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1, -+ write_reg_dma(nandc, &nandc->regs->addr0, NAND_ADDR0, 2, 0); -+ write_reg_dma(nandc, &nandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0); -+ if (!nandc->props->qpic_version2) -+ write_reg_dma(nandc, &nandc->regs->ecc_buf_cfg, NAND_EBI2_ECC_BUF_CFG, 1, - NAND_BAM_NEXT_SGL); - } - -@@ -1294,13 +1253,13 @@ static void config_nand_cw_write(struct nand_chip *chip) - { - struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); - -- write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL); -- write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); -+ write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL); -+ write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); - - read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL); - -- write_reg_dma(nandc, NAND_FLASH_STATUS, 1, 0); -- write_reg_dma(nandc, NAND_READ_STATUS, 1, NAND_BAM_NEXT_SGL); -+ write_reg_dma(nandc, &nandc->regs->clrflashstatus, NAND_FLASH_STATUS, 1, 0); -+ write_reg_dma(nandc, &nandc->regs->clrreadstatus, NAND_READ_STATUS, 1, NAND_BAM_NEXT_SGL); - } - - /* helpers to submit/free our list of dma descriptors */ -@@ -1311,7 +1270,7 @@ static int submit_descs(struct qcom_nand_controller *nandc) - struct bam_transaction *bam_txn = nandc->bam_txn; - int ret = 0; - -- if (nandc->props->is_bam) { -+ if (nandc->props->supports_bam) { - if (bam_txn->rx_sgl_pos > bam_txn->rx_sgl_start) { - ret = prepare_bam_async_desc(nandc, nandc->rx_chan, 0); - if (ret) -@@ -1336,14 +1295,9 @@ static int submit_descs(struct qcom_nand_controller *nandc) - list_for_each_entry(desc, &nandc->desc_list, node) - cookie = dmaengine_submit(desc->dma_desc); - -- if (nandc->props->is_bam) { -+ if (nandc->props->supports_bam) { - bam_txn->last_cmd_desc->callback = qpic_bam_dma_done; - bam_txn->last_cmd_desc->callback_param = bam_txn; -- if (bam_txn->last_data_desc) { -- bam_txn->last_data_desc->callback = qpic_bam_dma_done; -- bam_txn->last_data_desc->callback_param = bam_txn; -- bam_txn->wait_second_completion = true; -- } - - dma_async_issue_pending(nandc->tx_chan); - dma_async_issue_pending(nandc->rx_chan); -@@ -1365,7 +1319,7 @@ static int submit_descs(struct qcom_nand_controller *nandc) - list_for_each_entry_safe(desc, n, &nandc->desc_list, node) { - list_del(&desc->node); - -- if (nandc->props->is_bam) -+ if (nandc->props->supports_bam) - dma_unmap_sg(nandc->dev, desc->bam_sgl, - desc->sgl_cnt, desc->dir); - else -@@ -1382,7 +1336,7 @@ static int submit_descs(struct qcom_nand_controller *nandc) - static void clear_read_regs(struct qcom_nand_controller *nandc) - { - nandc->reg_read_pos = 0; -- nandc_read_buffer_sync(nandc, false); -+ nandc_dev_to_mem(nandc, false); - } - - /* -@@ -1446,7 +1400,7 @@ static int check_flash_errors(struct qcom_nand_host *host, int cw_cnt) - struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); - int i; - -- nandc_read_buffer_sync(nandc, true); -+ nandc_dev_to_mem(nandc, true); - - for (i = 0; i < cw_cnt; i++) { - u32 flash = le32_to_cpu(nandc->reg_read_buf[i]); -@@ -1476,7 +1430,7 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip, - clear_read_regs(nandc); - host->use_ecc = false; - -- if (nandc->props->qpic_v2) -+ if (nandc->props->qpic_version2) - raw_cw = ecc->steps - 1; - - clear_bam_transaction(nandc); -@@ -1497,7 +1451,7 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip, - oob_size2 = host->ecc_bytes_hw + host->spare_bytes; - } - -- if (nandc->props->is_bam) { -+ if (nandc->props->supports_bam) { - nandc_set_read_loc(chip, cw, 0, read_loc, data_size1, 0); - read_loc += data_size1; - -@@ -1621,7 +1575,7 @@ static int parse_read_errors(struct qcom_nand_host *host, u8 *data_buf, - u8 *data_buf_start = data_buf, *oob_buf_start = oob_buf; - - buf = (struct read_stats *)nandc->reg_read_buf; -- nandc_read_buffer_sync(nandc, true); -+ nandc_dev_to_mem(nandc, true); - - for (i = 0; i < ecc->steps; i++, buf++) { - u32 flash, buffer, erased_cw; -@@ -1734,7 +1688,7 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf, - oob_size = host->ecc_bytes_hw + host->spare_bytes; - } - -- if (nandc->props->is_bam) { -+ if (nandc->props->supports_bam) { - if (data_buf && oob_buf) { - nandc_set_read_loc(chip, i, 0, 0, data_size, 0); - nandc_set_read_loc(chip, i, 1, data_size, -@@ -2455,14 +2409,14 @@ static int qcom_nand_attach_chip(struct nand_chip *chip) - - mtd_set_ooblayout(mtd, &qcom_nand_ooblayout_ops); - /* Free the initially allocated BAM transaction for reading the ONFI params */ -- if (nandc->props->is_bam) -+ if (nandc->props->supports_bam) - free_bam_transaction(nandc); - - nandc->max_cwperpage = max_t(unsigned int, nandc->max_cwperpage, - cwperpage); - - /* Now allocate the BAM transaction based on updated max_cwperpage */ -- if (nandc->props->is_bam) { -+ if (nandc->props->supports_bam) { - nandc->bam_txn = alloc_bam_transaction(nandc); - if (!nandc->bam_txn) { - dev_err(nandc->dev, -@@ -2522,7 +2476,7 @@ static int qcom_nand_attach_chip(struct nand_chip *chip) - | ecc_mode << ECC_MODE - | host->ecc_bytes_hw << ECC_PARITY_SIZE_BYTES_BCH; - -- if (!nandc->props->qpic_v2) -+ if (!nandc->props->qpic_version2) - host->ecc_buf_cfg = 0x203 << NUM_STEPS; - - host->clrflashstatus = FS_READY_BSY_N; -@@ -2556,7 +2510,7 @@ static int qcom_op_cmd_mapping(struct nand_chip *chip, u8 opcode, - cmd = OP_FETCH_ID; - break; - case NAND_CMD_PARAM: -- if (nandc->props->qpic_v2) -+ if (nandc->props->qpic_version2) - cmd = OP_PAGE_READ_ONFI_READ; - else - cmd = OP_PAGE_READ; -@@ -2609,7 +2563,7 @@ static int qcom_parse_instructions(struct nand_chip *chip, - if (ret < 0) - return ret; - -- q_op->cmd_reg = ret; -+ q_op->cmd_reg = cpu_to_le32(ret); - q_op->rdy_delay_ns = instr->delay_ns; - break; - -@@ -2619,10 +2573,10 @@ static int qcom_parse_instructions(struct nand_chip *chip, - addrs = &instr->ctx.addr.addrs[offset]; - - for (i = 0; i < min_t(unsigned int, 4, naddrs); i++) -- q_op->addr1_reg |= addrs[i] << (i * 8); -+ q_op->addr1_reg |= cpu_to_le32(addrs[i] << (i * 8)); - - if (naddrs > 4) -- q_op->addr2_reg |= addrs[4]; -+ q_op->addr2_reg |= cpu_to_le32(addrs[4]); - - q_op->rdy_delay_ns = instr->delay_ns; - break; -@@ -2663,7 +2617,7 @@ static int qcom_wait_rdy_poll(struct nand_chip *chip, unsigned int time_ms) - unsigned long start = jiffies + msecs_to_jiffies(time_ms); - u32 flash; - -- nandc_read_buffer_sync(nandc, true); -+ nandc_dev_to_mem(nandc, true); - - do { - flash = le32_to_cpu(nandc->reg_read_buf[0]); -@@ -2706,11 +2660,11 @@ static int qcom_read_status_exec(struct nand_chip *chip, - clear_read_regs(nandc); - clear_bam_transaction(nandc); - -- nandc_set_reg(chip, NAND_FLASH_CMD, q_op.cmd_reg); -- nandc_set_reg(chip, NAND_EXEC_CMD, 1); -+ nandc->regs->cmd = q_op.cmd_reg; -+ nandc->regs->exec = cpu_to_le32(1); - -- write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL); -- write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); -+ write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL); -+ write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); - read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL); - - ret = submit_descs(nandc); -@@ -2719,7 +2673,7 @@ static int qcom_read_status_exec(struct nand_chip *chip, - goto err_out; - } - -- nandc_read_buffer_sync(nandc, true); -+ nandc_dev_to_mem(nandc, true); - - for (i = 0; i < num_cw; i++) { - flash_status = le32_to_cpu(nandc->reg_read_buf[i]); -@@ -2763,16 +2717,14 @@ static int qcom_read_id_type_exec(struct nand_chip *chip, const struct nand_subo - clear_read_regs(nandc); - clear_bam_transaction(nandc); - -- nandc_set_reg(chip, NAND_FLASH_CMD, q_op.cmd_reg); -- nandc_set_reg(chip, NAND_ADDR0, q_op.addr1_reg); -- nandc_set_reg(chip, NAND_ADDR1, q_op.addr2_reg); -- nandc_set_reg(chip, NAND_FLASH_CHIP_SELECT, -- nandc->props->is_bam ? 0 : DM_EN); -- -- nandc_set_reg(chip, NAND_EXEC_CMD, 1); -+ nandc->regs->cmd = q_op.cmd_reg; -+ nandc->regs->addr0 = q_op.addr1_reg; -+ nandc->regs->addr1 = q_op.addr2_reg; -+ nandc->regs->chip_sel = cpu_to_le32(nandc->props->supports_bam ? 0 : DM_EN); -+ nandc->regs->exec = cpu_to_le32(1); - -- write_reg_dma(nandc, NAND_FLASH_CMD, 4, NAND_BAM_NEXT_SGL); -- write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); -+ write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 4, NAND_BAM_NEXT_SGL); -+ write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); - - read_reg_dma(nandc, NAND_READ_ID, 1, NAND_BAM_NEXT_SGL); - -@@ -2786,7 +2738,7 @@ static int qcom_read_id_type_exec(struct nand_chip *chip, const struct nand_subo - op_id = q_op.data_instr_idx; - len = nand_subop_get_data_len(subop, op_id); - -- nandc_read_buffer_sync(nandc, true); -+ nandc_dev_to_mem(nandc, true); - memcpy(instr->ctx.data.buf.in, nandc->reg_read_buf, len); - - err_out: -@@ -2807,15 +2759,14 @@ static int qcom_misc_cmd_type_exec(struct nand_chip *chip, const struct nand_sub - - if (q_op.flag == OP_PROGRAM_PAGE) { - goto wait_rdy; -- } else if (q_op.cmd_reg == OP_BLOCK_ERASE) { -- q_op.cmd_reg |= PAGE_ACC | LAST_PAGE; -- nandc_set_reg(chip, NAND_ADDR0, q_op.addr1_reg); -- nandc_set_reg(chip, NAND_ADDR1, q_op.addr2_reg); -- nandc_set_reg(chip, NAND_DEV0_CFG0, -- host->cfg0_raw & ~(7 << CW_PER_PAGE)); -- nandc_set_reg(chip, NAND_DEV0_CFG1, host->cfg1_raw); -+ } else if (q_op.cmd_reg == cpu_to_le32(OP_BLOCK_ERASE)) { -+ q_op.cmd_reg |= cpu_to_le32(PAGE_ACC | LAST_PAGE); -+ nandc->regs->addr0 = q_op.addr1_reg; -+ nandc->regs->addr1 = q_op.addr2_reg; -+ nandc->regs->cfg0 = cpu_to_le32(host->cfg0_raw & ~(7 << CW_PER_PAGE)); -+ nandc->regs->cfg1 = cpu_to_le32(host->cfg1_raw); - instrs = 3; -- } else if (q_op.cmd_reg != OP_RESET_DEVICE) { -+ } else if (q_op.cmd_reg != cpu_to_le32(OP_RESET_DEVICE)) { - return 0; - } - -@@ -2826,14 +2777,14 @@ static int qcom_misc_cmd_type_exec(struct nand_chip *chip, const struct nand_sub - clear_read_regs(nandc); - clear_bam_transaction(nandc); - -- nandc_set_reg(chip, NAND_FLASH_CMD, q_op.cmd_reg); -- nandc_set_reg(chip, NAND_EXEC_CMD, 1); -+ nandc->regs->cmd = q_op.cmd_reg; -+ nandc->regs->exec = cpu_to_le32(1); - -- write_reg_dma(nandc, NAND_FLASH_CMD, instrs, NAND_BAM_NEXT_SGL); -- if (q_op.cmd_reg == OP_BLOCK_ERASE) -- write_reg_dma(nandc, NAND_DEV0_CFG0, 2, NAND_BAM_NEXT_SGL); -+ write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, instrs, NAND_BAM_NEXT_SGL); -+ if (q_op.cmd_reg == cpu_to_le32(OP_BLOCK_ERASE)) -+ write_reg_dma(nandc, &nandc->regs->cfg0, NAND_DEV0_CFG0, 2, NAND_BAM_NEXT_SGL); - -- write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); -+ write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); - read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL); - - ret = submit_descs(nandc); -@@ -2862,14 +2813,14 @@ static int qcom_param_page_type_exec(struct nand_chip *chip, const struct nand_ - - reg_base = NAND_READ_LOCATION_0; - -- if (nandc->props->qpic_v2) -+ if (nandc->props->qpic_version2) - reg_base = NAND_READ_LOCATION_LAST_CW_0; - - ret = qcom_parse_instructions(chip, subop, &q_op); - if (ret) - return ret; - -- q_op.cmd_reg |= PAGE_ACC | LAST_PAGE; -+ q_op.cmd_reg |= cpu_to_le32(PAGE_ACC | LAST_PAGE); - - nandc->buf_count = 0; - nandc->buf_start = 0; -@@ -2877,52 +2828,52 @@ static int qcom_param_page_type_exec(struct nand_chip *chip, const struct nand_ - clear_read_regs(nandc); - clear_bam_transaction(nandc); - -- nandc_set_reg(chip, NAND_FLASH_CMD, q_op.cmd_reg); -- -- nandc_set_reg(chip, NAND_ADDR0, 0); -- nandc_set_reg(chip, NAND_ADDR1, 0); -- nandc_set_reg(chip, NAND_DEV0_CFG0, 0 << CW_PER_PAGE -- | 512 << UD_SIZE_BYTES -- | 5 << NUM_ADDR_CYCLES -- | 0 << SPARE_SIZE_BYTES); -- nandc_set_reg(chip, NAND_DEV0_CFG1, 7 << NAND_RECOVERY_CYCLES -- | 0 << CS_ACTIVE_BSY -- | 17 << BAD_BLOCK_BYTE_NUM -- | 1 << BAD_BLOCK_IN_SPARE_AREA -- | 2 << WR_RD_BSY_GAP -- | 0 << WIDE_FLASH -- | 1 << DEV0_CFG1_ECC_DISABLE); -- if (!nandc->props->qpic_v2) -- nandc_set_reg(chip, NAND_EBI2_ECC_BUF_CFG, 1 << ECC_CFG_ECC_DISABLE); -+ nandc->regs->cmd = q_op.cmd_reg; -+ nandc->regs->addr0 = 0; -+ nandc->regs->addr1 = 0; -+ -+ nandc->regs->cfg0 = cpu_to_le32(0 << CW_PER_PAGE | -+ 512 << UD_SIZE_BYTES | -+ 5 << NUM_ADDR_CYCLES | -+ 0 << SPARE_SIZE_BYTES); -+ -+ nandc->regs->cfg1 = cpu_to_le32(7 << NAND_RECOVERY_CYCLES | -+ 0 << CS_ACTIVE_BSY | -+ 17 << BAD_BLOCK_BYTE_NUM | -+ 1 << BAD_BLOCK_IN_SPARE_AREA | -+ 2 << WR_RD_BSY_GAP | -+ 0 << WIDE_FLASH | -+ 1 << DEV0_CFG1_ECC_DISABLE); -+ -+ if (!nandc->props->qpic_version2) -+ nandc->regs->ecc_buf_cfg = cpu_to_le32(1 << ECC_CFG_ECC_DISABLE); - - /* configure CMD1 and VLD for ONFI param probing in QPIC v1 */ -- if (!nandc->props->qpic_v2) { -- nandc_set_reg(chip, NAND_DEV_CMD_VLD, -- (nandc->vld & ~READ_START_VLD)); -- nandc_set_reg(chip, NAND_DEV_CMD1, -- (nandc->cmd1 & ~(0xFF << READ_ADDR)) -- | NAND_CMD_PARAM << READ_ADDR); -+ if (!nandc->props->qpic_version2) { -+ nandc->regs->vld = cpu_to_le32((nandc->vld & ~READ_START_VLD)); -+ nandc->regs->cmd1 = cpu_to_le32((nandc->cmd1 & ~(0xFF << READ_ADDR)) -+ | NAND_CMD_PARAM << READ_ADDR); - } - -- nandc_set_reg(chip, NAND_EXEC_CMD, 1); -+ nandc->regs->exec = cpu_to_le32(1); - -- if (!nandc->props->qpic_v2) { -- nandc_set_reg(chip, NAND_DEV_CMD1_RESTORE, nandc->cmd1); -- nandc_set_reg(chip, NAND_DEV_CMD_VLD_RESTORE, nandc->vld); -+ if (!nandc->props->qpic_version2) { -+ nandc->regs->orig_cmd1 = cpu_to_le32(nandc->cmd1); -+ nandc->regs->orig_vld = cpu_to_le32(nandc->vld); - } - - instr = q_op.data_instr; - op_id = q_op.data_instr_idx; - len = nand_subop_get_data_len(subop, op_id); - -- if (nandc->props->qpic_v2) -+ if (nandc->props->qpic_version2) - nandc_set_read_loc_last(chip, reg_base, 0, len, 1); - else - nandc_set_read_loc_first(chip, reg_base, 0, len, 1); - -- if (!nandc->props->qpic_v2) { -- write_reg_dma(nandc, NAND_DEV_CMD_VLD, 1, 0); -- write_reg_dma(nandc, NAND_DEV_CMD1, 1, NAND_BAM_NEXT_SGL); -+ if (!nandc->props->qpic_version2) { -+ write_reg_dma(nandc, &nandc->regs->vld, NAND_DEV_CMD_VLD, 1, 0); -+ write_reg_dma(nandc, &nandc->regs->cmd1, NAND_DEV_CMD1, 1, NAND_BAM_NEXT_SGL); - } - - nandc->buf_count = 512; -@@ -2934,9 +2885,10 @@ static int qcom_param_page_type_exec(struct nand_chip *chip, const struct nand_ - nandc->buf_count, 0); - - /* restore CMD1 and VLD regs */ -- if (!nandc->props->qpic_v2) { -- write_reg_dma(nandc, NAND_DEV_CMD1_RESTORE, 1, 0); -- write_reg_dma(nandc, NAND_DEV_CMD_VLD_RESTORE, 1, NAND_BAM_NEXT_SGL); -+ if (!nandc->props->qpic_version2) { -+ write_reg_dma(nandc, &nandc->regs->orig_cmd1, NAND_DEV_CMD1_RESTORE, 1, 0); -+ write_reg_dma(nandc, &nandc->regs->orig_vld, NAND_DEV_CMD_VLD_RESTORE, 1, -+ NAND_BAM_NEXT_SGL); - } - - ret = submit_descs(nandc); -@@ -3025,7 +2977,7 @@ static const struct nand_controller_ops qcom_nandc_ops = { - - static void qcom_nandc_unalloc(struct qcom_nand_controller *nandc) - { -- if (nandc->props->is_bam) { -+ if (nandc->props->supports_bam) { - if (!dma_mapping_error(nandc->dev, nandc->reg_read_dma)) - dma_unmap_single(nandc->dev, nandc->reg_read_dma, - MAX_REG_RD * -@@ -3078,7 +3030,7 @@ static int qcom_nandc_alloc(struct qcom_nand_controller *nandc) - if (!nandc->reg_read_buf) - return -ENOMEM; - -- if (nandc->props->is_bam) { -+ if (nandc->props->supports_bam) { - nandc->reg_read_dma = - dma_map_single(nandc->dev, nandc->reg_read_buf, - MAX_REG_RD * -@@ -3159,15 +3111,15 @@ static int qcom_nandc_setup(struct qcom_nand_controller *nandc) - u32 nand_ctrl; - - /* kill onenand */ -- if (!nandc->props->is_qpic) -+ if (!nandc->props->nandc_part_of_qpic) - nandc_write(nandc, SFLASHC_BURST_CFG, 0); - -- if (!nandc->props->qpic_v2) -+ if (!nandc->props->qpic_version2) - nandc_write(nandc, dev_cmd_reg_addr(nandc, NAND_DEV_CMD_VLD), - NAND_DEV_CMD_VLD_VAL); - - /* enable ADM or BAM DMA */ -- if (nandc->props->is_bam) { -+ if (nandc->props->supports_bam) { - nand_ctrl = nandc_read(nandc, NAND_CTRL); - - /* -@@ -3184,7 +3136,7 @@ static int qcom_nandc_setup(struct qcom_nand_controller *nandc) - } - - /* save the original values of these registers */ -- if (!nandc->props->qpic_v2) { -+ if (!nandc->props->qpic_version2) { - nandc->cmd1 = nandc_read(nandc, dev_cmd_reg_addr(nandc, NAND_DEV_CMD1)); - nandc->vld = NAND_DEV_CMD_VLD_VAL; - } -@@ -3357,7 +3309,7 @@ static int qcom_nandc_parse_dt(struct platform_device *pdev) - struct device_node *np = nandc->dev->of_node; - int ret; - -- if (!nandc->props->is_bam) { -+ if (!nandc->props->supports_bam) { - ret = of_property_read_u32(np, "qcom,cmd-crci", - &nandc->cmd_crci); - if (ret) { -@@ -3482,30 +3434,30 @@ static void qcom_nandc_remove(struct platform_device *pdev) - - static const struct qcom_nandc_props ipq806x_nandc_props = { - .ecc_modes = (ECC_RS_4BIT | ECC_BCH_8BIT), -- .is_bam = false, -+ .supports_bam = false, - .use_codeword_fixup = true, - .dev_cmd_reg_start = 0x0, - }; - - static const struct qcom_nandc_props ipq4019_nandc_props = { - .ecc_modes = (ECC_BCH_4BIT | ECC_BCH_8BIT), -- .is_bam = true, -- .is_qpic = true, -+ .supports_bam = true, -+ .nandc_part_of_qpic = true, - .dev_cmd_reg_start = 0x0, - }; - - static const struct qcom_nandc_props ipq8074_nandc_props = { - .ecc_modes = (ECC_BCH_4BIT | ECC_BCH_8BIT), -- .is_bam = true, -- .is_qpic = true, -+ .supports_bam = true, -+ .nandc_part_of_qpic = true, - .dev_cmd_reg_start = 0x7000, - }; - - static const struct qcom_nandc_props sdx55_nandc_props = { - .ecc_modes = (ECC_BCH_4BIT | ECC_BCH_8BIT), -- .is_bam = true, -- .is_qpic = true, -- .qpic_v2 = true, -+ .supports_bam = true, -+ .nandc_part_of_qpic = true, -+ .qpic_version2 = true, - .dev_cmd_reg_start = 0x7000, - }; - --- -2.51.0 - - -From 3eb84d95e970b09e7ceeff3bcae17bd351aeabe0 Mon Sep 17 00:00:00 2001 -From: Md Sadre Alam -Date: Wed, 20 Nov 2024 14:45:01 +0530 -Subject: [PATCH 011/517] mtd: rawnand: qcom: Add qcom prefix to common api - -Add qcom prefix to all the api which will be commonly -used by spi nand driver and raw nand driver. - -Reviewed-by: Konrad Dybcio -Signed-off-by: Md Sadre Alam -Signed-off-by: Miquel Raynal ---- - drivers/mtd/nand/raw/qcom_nandc.c | 320 +++++++++++++++--------------- - 1 file changed, 160 insertions(+), 160 deletions(-) - -diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c -index 94a57a0de067..ee73876f7244 100644 ---- a/drivers/mtd/nand/raw/qcom_nandc.c -+++ b/drivers/mtd/nand/raw/qcom_nandc.c -@@ -53,7 +53,7 @@ - #define NAND_READ_LOCATION_LAST_CW_2 0xf48 - #define NAND_READ_LOCATION_LAST_CW_3 0xf4c - --/* dummy register offsets, used by write_reg_dma */ -+/* dummy register offsets, used by qcom_write_reg_dma */ - #define NAND_DEV_CMD1_RESTORE 0xdead - #define NAND_DEV_CMD_VLD_RESTORE 0xbeef - -@@ -211,7 +211,7 @@ - - /* - * Flags used in DMA descriptor preparation helper functions -- * (i.e. read_reg_dma/write_reg_dma/read_data_dma/write_data_dma) -+ * (i.e. qcom_read_reg_dma/qcom_write_reg_dma/qcom_read_data_dma/qcom_write_data_dma) - */ - /* Don't set the EOT in current tx BAM sgl */ - #define NAND_BAM_NO_EOT BIT(0) -@@ -550,7 +550,7 @@ struct qcom_nandc_props { - }; - - /* Frees the BAM transaction memory */ --static void free_bam_transaction(struct qcom_nand_controller *nandc) -+static void qcom_free_bam_transaction(struct qcom_nand_controller *nandc) - { - struct bam_transaction *bam_txn = nandc->bam_txn; - -@@ -559,7 +559,7 @@ static void free_bam_transaction(struct qcom_nand_controller *nandc) - - /* Allocates and Initializes the BAM transaction */ - static struct bam_transaction * --alloc_bam_transaction(struct qcom_nand_controller *nandc) -+qcom_alloc_bam_transaction(struct qcom_nand_controller *nandc) - { - struct bam_transaction *bam_txn; - size_t bam_txn_size; -@@ -595,7 +595,7 @@ alloc_bam_transaction(struct qcom_nand_controller *nandc) - } - - /* Clears the BAM transaction indexes */ --static void clear_bam_transaction(struct qcom_nand_controller *nandc) -+static void qcom_clear_bam_transaction(struct qcom_nand_controller *nandc) - { - struct bam_transaction *bam_txn = nandc->bam_txn; - -@@ -614,7 +614,7 @@ static void clear_bam_transaction(struct qcom_nand_controller *nandc) - } - - /* Callback for DMA descriptor completion */ --static void qpic_bam_dma_done(void *data) -+static void qcom_qpic_bam_dma_done(void *data) - { - struct bam_transaction *bam_txn = data; - -@@ -644,7 +644,7 @@ static void nandc_write(struct qcom_nand_controller *nandc, int offset, - iowrite32(val, nandc->base + offset); - } - --static void nandc_dev_to_mem(struct qcom_nand_controller *nandc, bool is_cpu) -+static void qcom_nandc_dev_to_mem(struct qcom_nand_controller *nandc, bool is_cpu) - { - if (!nandc->props->supports_bam) - return; -@@ -824,9 +824,9 @@ static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read, i - * for BAM. This descriptor will be added in the NAND DMA descriptor queue - * which will be submitted to DMA engine. - */ --static int prepare_bam_async_desc(struct qcom_nand_controller *nandc, -- struct dma_chan *chan, -- unsigned long flags) -+static int qcom_prepare_bam_async_desc(struct qcom_nand_controller *nandc, -+ struct dma_chan *chan, -+ unsigned long flags) - { - struct desc_info *desc; - struct scatterlist *sgl; -@@ -903,9 +903,9 @@ static int prepare_bam_async_desc(struct qcom_nand_controller *nandc, - * NAND_BAM_NEXT_SGL will be used for starting the separate SGL - * after the current command element. - */ --static int prep_bam_dma_desc_cmd(struct qcom_nand_controller *nandc, bool read, -- int reg_off, const void *vaddr, -- int size, unsigned int flags) -+static int qcom_prep_bam_dma_desc_cmd(struct qcom_nand_controller *nandc, bool read, -+ int reg_off, const void *vaddr, -+ int size, unsigned int flags) - { - int bam_ce_size; - int i, ret; -@@ -943,9 +943,9 @@ static int prep_bam_dma_desc_cmd(struct qcom_nand_controller *nandc, bool read, - bam_txn->bam_ce_start = bam_txn->bam_ce_pos; - - if (flags & NAND_BAM_NWD) { -- ret = prepare_bam_async_desc(nandc, nandc->cmd_chan, -- DMA_PREP_FENCE | -- DMA_PREP_CMD); -+ ret = qcom_prepare_bam_async_desc(nandc, nandc->cmd_chan, -+ DMA_PREP_FENCE | -+ DMA_PREP_CMD); - if (ret) - return ret; - } -@@ -958,9 +958,8 @@ static int prep_bam_dma_desc_cmd(struct qcom_nand_controller *nandc, bool read, - * Prepares the data descriptor for BAM DMA which will be used for NAND - * data reads and writes. - */ --static int prep_bam_dma_desc_data(struct qcom_nand_controller *nandc, bool read, -- const void *vaddr, -- int size, unsigned int flags) -+static int qcom_prep_bam_dma_desc_data(struct qcom_nand_controller *nandc, bool read, -+ const void *vaddr, int size, unsigned int flags) - { - int ret; - struct bam_transaction *bam_txn = nandc->bam_txn; -@@ -979,8 +978,8 @@ static int prep_bam_dma_desc_data(struct qcom_nand_controller *nandc, bool read, - * is not set, form the DMA descriptor - */ - if (!(flags & NAND_BAM_NO_EOT)) { -- ret = prepare_bam_async_desc(nandc, nandc->tx_chan, -- DMA_PREP_INTERRUPT); -+ ret = qcom_prepare_bam_async_desc(nandc, nandc->tx_chan, -+ DMA_PREP_INTERRUPT); - if (ret) - return ret; - } -@@ -989,9 +988,9 @@ static int prep_bam_dma_desc_data(struct qcom_nand_controller *nandc, bool read, - return 0; - } - --static int prep_adm_dma_desc(struct qcom_nand_controller *nandc, bool read, -- int reg_off, const void *vaddr, int size, -- bool flow_control) -+static int qcom_prep_adm_dma_desc(struct qcom_nand_controller *nandc, bool read, -+ int reg_off, const void *vaddr, int size, -+ bool flow_control) - { - struct desc_info *desc; - struct dma_async_tx_descriptor *dma_desc; -@@ -1069,15 +1068,15 @@ static int prep_adm_dma_desc(struct qcom_nand_controller *nandc, bool read, - } - - /* -- * read_reg_dma: prepares a descriptor to read a given number of -+ * qcom_read_reg_dma: prepares a descriptor to read a given number of - * contiguous registers to the reg_read_buf pointer - * - * @first: offset of the first register in the contiguous block - * @num_regs: number of registers to read - * @flags: flags to control DMA descriptor preparation - */ --static int read_reg_dma(struct qcom_nand_controller *nandc, int first, -- int num_regs, unsigned int flags) -+static int qcom_read_reg_dma(struct qcom_nand_controller *nandc, int first, -+ int num_regs, unsigned int flags) - { - bool flow_control = false; - void *vaddr; -@@ -1089,18 +1088,18 @@ static int read_reg_dma(struct qcom_nand_controller *nandc, int first, - first = dev_cmd_reg_addr(nandc, first); - - if (nandc->props->supports_bam) -- return prep_bam_dma_desc_cmd(nandc, true, first, vaddr, -+ return qcom_prep_bam_dma_desc_cmd(nandc, true, first, vaddr, - num_regs, flags); - - if (first == NAND_READ_ID || first == NAND_FLASH_STATUS) - flow_control = true; - -- return prep_adm_dma_desc(nandc, true, first, vaddr, -+ return qcom_prep_adm_dma_desc(nandc, true, first, vaddr, - num_regs * sizeof(u32), flow_control); - } - - /* -- * write_reg_dma: prepares a descriptor to write a given number of -+ * qcom_write_reg_dma: prepares a descriptor to write a given number of - * contiguous registers - * - * @vaddr: contiguous memory from where register value will -@@ -1109,8 +1108,8 @@ static int read_reg_dma(struct qcom_nand_controller *nandc, int first, - * @num_regs: number of registers to write - * @flags: flags to control DMA descriptor preparation - */ --static int write_reg_dma(struct qcom_nand_controller *nandc, __le32 *vaddr, -- int first, int num_regs, unsigned int flags) -+static int qcom_write_reg_dma(struct qcom_nand_controller *nandc, __le32 *vaddr, -+ int first, int num_regs, unsigned int flags) - { - bool flow_control = false; - -@@ -1124,18 +1123,18 @@ static int write_reg_dma(struct qcom_nand_controller *nandc, __le32 *vaddr, - first = dev_cmd_reg_addr(nandc, NAND_DEV_CMD_VLD); - - if (nandc->props->supports_bam) -- return prep_bam_dma_desc_cmd(nandc, false, first, vaddr, -+ return qcom_prep_bam_dma_desc_cmd(nandc, false, first, vaddr, - num_regs, flags); - - if (first == NAND_FLASH_CMD) - flow_control = true; - -- return prep_adm_dma_desc(nandc, false, first, vaddr, -+ return qcom_prep_adm_dma_desc(nandc, false, first, vaddr, - num_regs * sizeof(u32), flow_control); - } - - /* -- * read_data_dma: prepares a DMA descriptor to transfer data from the -+ * qcom_read_data_dma: prepares a DMA descriptor to transfer data from the - * controller's internal buffer to the buffer 'vaddr' - * - * @reg_off: offset within the controller's data buffer -@@ -1143,17 +1142,17 @@ static int write_reg_dma(struct qcom_nand_controller *nandc, __le32 *vaddr, - * @size: DMA transaction size in bytes - * @flags: flags to control DMA descriptor preparation - */ --static int read_data_dma(struct qcom_nand_controller *nandc, int reg_off, -- const u8 *vaddr, int size, unsigned int flags) -+static int qcom_read_data_dma(struct qcom_nand_controller *nandc, int reg_off, -+ const u8 *vaddr, int size, unsigned int flags) - { - if (nandc->props->supports_bam) -- return prep_bam_dma_desc_data(nandc, true, vaddr, size, flags); -+ return qcom_prep_bam_dma_desc_data(nandc, true, vaddr, size, flags); - -- return prep_adm_dma_desc(nandc, true, reg_off, vaddr, size, false); -+ return qcom_prep_adm_dma_desc(nandc, true, reg_off, vaddr, size, false); - } - - /* -- * write_data_dma: prepares a DMA descriptor to transfer data from -+ * qcom_write_data_dma: prepares a DMA descriptor to transfer data from - * 'vaddr' to the controller's internal buffer - * - * @reg_off: offset within the controller's data buffer -@@ -1161,13 +1160,13 @@ static int read_data_dma(struct qcom_nand_controller *nandc, int reg_off, - * @size: DMA transaction size in bytes - * @flags: flags to control DMA descriptor preparation - */ --static int write_data_dma(struct qcom_nand_controller *nandc, int reg_off, -- const u8 *vaddr, int size, unsigned int flags) -+static int qcom_write_data_dma(struct qcom_nand_controller *nandc, int reg_off, -+ const u8 *vaddr, int size, unsigned int flags) - { - if (nandc->props->supports_bam) -- return prep_bam_dma_desc_data(nandc, false, vaddr, size, flags); -+ return qcom_prep_bam_dma_desc_data(nandc, false, vaddr, size, flags); - -- return prep_adm_dma_desc(nandc, false, reg_off, vaddr, size, false); -+ return qcom_prep_adm_dma_desc(nandc, false, reg_off, vaddr, size, false); - } - - /* -@@ -1178,14 +1177,14 @@ static void config_nand_page_read(struct nand_chip *chip) - { - struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); - -- write_reg_dma(nandc, &nandc->regs->addr0, NAND_ADDR0, 2, 0); -- write_reg_dma(nandc, &nandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0); -+ qcom_write_reg_dma(nandc, &nandc->regs->addr0, NAND_ADDR0, 2, 0); -+ qcom_write_reg_dma(nandc, &nandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0); - if (!nandc->props->qpic_version2) -- write_reg_dma(nandc, &nandc->regs->ecc_buf_cfg, NAND_EBI2_ECC_BUF_CFG, 1, 0); -- write_reg_dma(nandc, &nandc->regs->erased_cw_detect_cfg_clr, -- NAND_ERASED_CW_DETECT_CFG, 1, 0); -- write_reg_dma(nandc, &nandc->regs->erased_cw_detect_cfg_set, -- NAND_ERASED_CW_DETECT_CFG, 1, NAND_ERASED_CW_SET | NAND_BAM_NEXT_SGL); -+ qcom_write_reg_dma(nandc, &nandc->regs->ecc_buf_cfg, NAND_EBI2_ECC_BUF_CFG, 1, 0); -+ qcom_write_reg_dma(nandc, &nandc->regs->erased_cw_detect_cfg_clr, -+ NAND_ERASED_CW_DETECT_CFG, 1, 0); -+ qcom_write_reg_dma(nandc, &nandc->regs->erased_cw_detect_cfg_set, -+ NAND_ERASED_CW_DETECT_CFG, 1, NAND_ERASED_CW_SET | NAND_BAM_NEXT_SGL); - } - - /* -@@ -1204,17 +1203,17 @@ config_nand_cw_read(struct nand_chip *chip, bool use_ecc, int cw) - reg = &nandc->regs->read_location_last0; - - if (nandc->props->supports_bam) -- write_reg_dma(nandc, reg, NAND_READ_LOCATION_0, 4, NAND_BAM_NEXT_SGL); -+ qcom_write_reg_dma(nandc, reg, NAND_READ_LOCATION_0, 4, NAND_BAM_NEXT_SGL); - -- write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL); -- write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); -+ qcom_write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL); -+ qcom_write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); - - if (use_ecc) { -- read_reg_dma(nandc, NAND_FLASH_STATUS, 2, 0); -- read_reg_dma(nandc, NAND_ERASED_CW_DETECT_STATUS, 1, -- NAND_BAM_NEXT_SGL); -+ qcom_read_reg_dma(nandc, NAND_FLASH_STATUS, 2, 0); -+ qcom_read_reg_dma(nandc, NAND_ERASED_CW_DETECT_STATUS, 1, -+ NAND_BAM_NEXT_SGL); - } else { -- read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL); -+ qcom_read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL); - } - } - -@@ -1238,11 +1237,11 @@ static void config_nand_page_write(struct nand_chip *chip) - { - struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); - -- write_reg_dma(nandc, &nandc->regs->addr0, NAND_ADDR0, 2, 0); -- write_reg_dma(nandc, &nandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0); -+ qcom_write_reg_dma(nandc, &nandc->regs->addr0, NAND_ADDR0, 2, 0); -+ qcom_write_reg_dma(nandc, &nandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0); - if (!nandc->props->qpic_version2) -- write_reg_dma(nandc, &nandc->regs->ecc_buf_cfg, NAND_EBI2_ECC_BUF_CFG, 1, -- NAND_BAM_NEXT_SGL); -+ qcom_write_reg_dma(nandc, &nandc->regs->ecc_buf_cfg, NAND_EBI2_ECC_BUF_CFG, 1, -+ NAND_BAM_NEXT_SGL); - } - - /* -@@ -1253,17 +1252,18 @@ static void config_nand_cw_write(struct nand_chip *chip) - { - struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); - -- write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL); -- write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); -+ qcom_write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL); -+ qcom_write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); - -- read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL); -+ qcom_read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL); - -- write_reg_dma(nandc, &nandc->regs->clrflashstatus, NAND_FLASH_STATUS, 1, 0); -- write_reg_dma(nandc, &nandc->regs->clrreadstatus, NAND_READ_STATUS, 1, NAND_BAM_NEXT_SGL); -+ qcom_write_reg_dma(nandc, &nandc->regs->clrflashstatus, NAND_FLASH_STATUS, 1, 0); -+ qcom_write_reg_dma(nandc, &nandc->regs->clrreadstatus, NAND_READ_STATUS, 1, -+ NAND_BAM_NEXT_SGL); - } - - /* helpers to submit/free our list of dma descriptors */ --static int submit_descs(struct qcom_nand_controller *nandc) -+static int qcom_submit_descs(struct qcom_nand_controller *nandc) - { - struct desc_info *desc, *n; - dma_cookie_t cookie = 0; -@@ -1272,21 +1272,21 @@ static int submit_descs(struct qcom_nand_controller *nandc) - - if (nandc->props->supports_bam) { - if (bam_txn->rx_sgl_pos > bam_txn->rx_sgl_start) { -- ret = prepare_bam_async_desc(nandc, nandc->rx_chan, 0); -+ ret = qcom_prepare_bam_async_desc(nandc, nandc->rx_chan, 0); - if (ret) - goto err_unmap_free_desc; - } - - if (bam_txn->tx_sgl_pos > bam_txn->tx_sgl_start) { -- ret = prepare_bam_async_desc(nandc, nandc->tx_chan, -- DMA_PREP_INTERRUPT); -+ ret = qcom_prepare_bam_async_desc(nandc, nandc->tx_chan, -+ DMA_PREP_INTERRUPT); - if (ret) - goto err_unmap_free_desc; - } - - if (bam_txn->cmd_sgl_pos > bam_txn->cmd_sgl_start) { -- ret = prepare_bam_async_desc(nandc, nandc->cmd_chan, -- DMA_PREP_CMD); -+ ret = qcom_prepare_bam_async_desc(nandc, nandc->cmd_chan, -+ DMA_PREP_CMD); - if (ret) - goto err_unmap_free_desc; - } -@@ -1296,7 +1296,7 @@ static int submit_descs(struct qcom_nand_controller *nandc) - cookie = dmaengine_submit(desc->dma_desc); - - if (nandc->props->supports_bam) { -- bam_txn->last_cmd_desc->callback = qpic_bam_dma_done; -+ bam_txn->last_cmd_desc->callback = qcom_qpic_bam_dma_done; - bam_txn->last_cmd_desc->callback_param = bam_txn; - - dma_async_issue_pending(nandc->tx_chan); -@@ -1314,7 +1314,7 @@ static int submit_descs(struct qcom_nand_controller *nandc) - err_unmap_free_desc: - /* - * Unmap the dma sg_list and free the desc allocated by both -- * prepare_bam_async_desc() and prep_adm_dma_desc() functions. -+ * qcom_prepare_bam_async_desc() and qcom_prep_adm_dma_desc() functions. - */ - list_for_each_entry_safe(desc, n, &nandc->desc_list, node) { - list_del(&desc->node); -@@ -1333,10 +1333,10 @@ static int submit_descs(struct qcom_nand_controller *nandc) - } - - /* reset the register read buffer for next NAND operation */ --static void clear_read_regs(struct qcom_nand_controller *nandc) -+static void qcom_clear_read_regs(struct qcom_nand_controller *nandc) - { - nandc->reg_read_pos = 0; -- nandc_dev_to_mem(nandc, false); -+ qcom_nandc_dev_to_mem(nandc, false); - } - - /* -@@ -1400,7 +1400,7 @@ static int check_flash_errors(struct qcom_nand_host *host, int cw_cnt) - struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); - int i; - -- nandc_dev_to_mem(nandc, true); -+ qcom_nandc_dev_to_mem(nandc, true); - - for (i = 0; i < cw_cnt; i++) { - u32 flash = le32_to_cpu(nandc->reg_read_buf[i]); -@@ -1427,13 +1427,13 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip, - nand_read_page_op(chip, page, 0, NULL, 0); - nandc->buf_count = 0; - nandc->buf_start = 0; -- clear_read_regs(nandc); -+ qcom_clear_read_regs(nandc); - host->use_ecc = false; - - if (nandc->props->qpic_version2) - raw_cw = ecc->steps - 1; - -- clear_bam_transaction(nandc); -+ qcom_clear_bam_transaction(nandc); - set_address(host, host->cw_size * cw, page); - update_rw_regs(host, 1, true, raw_cw); - config_nand_page_read(chip); -@@ -1466,18 +1466,18 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip, - - config_nand_cw_read(chip, false, raw_cw); - -- read_data_dma(nandc, reg_off, data_buf, data_size1, 0); -+ qcom_read_data_dma(nandc, reg_off, data_buf, data_size1, 0); - reg_off += data_size1; - -- read_data_dma(nandc, reg_off, oob_buf, oob_size1, 0); -+ qcom_read_data_dma(nandc, reg_off, oob_buf, oob_size1, 0); - reg_off += oob_size1; - -- read_data_dma(nandc, reg_off, data_buf + data_size1, data_size2, 0); -+ qcom_read_data_dma(nandc, reg_off, data_buf + data_size1, data_size2, 0); - reg_off += data_size2; - -- read_data_dma(nandc, reg_off, oob_buf + oob_size1, oob_size2, 0); -+ qcom_read_data_dma(nandc, reg_off, oob_buf + oob_size1, oob_size2, 0); - -- ret = submit_descs(nandc); -+ ret = qcom_submit_descs(nandc); - if (ret) { - dev_err(nandc->dev, "failure to read raw cw %d\n", cw); - return ret; -@@ -1575,7 +1575,7 @@ static int parse_read_errors(struct qcom_nand_host *host, u8 *data_buf, - u8 *data_buf_start = data_buf, *oob_buf_start = oob_buf; - - buf = (struct read_stats *)nandc->reg_read_buf; -- nandc_dev_to_mem(nandc, true); -+ qcom_nandc_dev_to_mem(nandc, true); - - for (i = 0; i < ecc->steps; i++, buf++) { - u32 flash, buffer, erased_cw; -@@ -1704,8 +1704,8 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf, - config_nand_cw_read(chip, true, i); - - if (data_buf) -- read_data_dma(nandc, FLASH_BUF_ACC, data_buf, -- data_size, 0); -+ qcom_read_data_dma(nandc, FLASH_BUF_ACC, data_buf, -+ data_size, 0); - - /* - * when ecc is enabled, the controller doesn't read the real -@@ -1720,8 +1720,8 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf, - for (j = 0; j < host->bbm_size; j++) - *oob_buf++ = 0xff; - -- read_data_dma(nandc, FLASH_BUF_ACC + data_size, -- oob_buf, oob_size, 0); -+ qcom_read_data_dma(nandc, FLASH_BUF_ACC + data_size, -+ oob_buf, oob_size, 0); - } - - if (data_buf) -@@ -1730,7 +1730,7 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf, - oob_buf += oob_size; - } - -- ret = submit_descs(nandc); -+ ret = qcom_submit_descs(nandc); - if (ret) { - dev_err(nandc->dev, "failure to read page/oob\n"); - return ret; -@@ -1751,7 +1751,7 @@ static int copy_last_cw(struct qcom_nand_host *host, int page) - int size; - int ret; - -- clear_read_regs(nandc); -+ qcom_clear_read_regs(nandc); - - size = host->use_ecc ? host->cw_data : host->cw_size; - -@@ -1763,9 +1763,9 @@ static int copy_last_cw(struct qcom_nand_host *host, int page) - - config_nand_single_cw_page_read(chip, host->use_ecc, ecc->steps - 1); - -- read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, size, 0); -+ qcom_read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, size, 0); - -- ret = submit_descs(nandc); -+ ret = qcom_submit_descs(nandc); - if (ret) - dev_err(nandc->dev, "failed to copy last codeword\n"); - -@@ -1851,14 +1851,14 @@ static int qcom_nandc_read_page(struct nand_chip *chip, u8 *buf, - nandc->buf_count = 0; - nandc->buf_start = 0; - host->use_ecc = true; -- clear_read_regs(nandc); -+ qcom_clear_read_regs(nandc); - set_address(host, 0, page); - update_rw_regs(host, ecc->steps, true, 0); - - data_buf = buf; - oob_buf = oob_required ? chip->oob_poi : NULL; - -- clear_bam_transaction(nandc); -+ qcom_clear_bam_transaction(nandc); - - return read_page_ecc(host, data_buf, oob_buf, page); - } -@@ -1899,8 +1899,8 @@ static int qcom_nandc_read_oob(struct nand_chip *chip, int page) - if (host->nr_boot_partitions) - qcom_nandc_codeword_fixup(host, page); - -- clear_read_regs(nandc); -- clear_bam_transaction(nandc); -+ qcom_clear_read_regs(nandc); -+ qcom_clear_bam_transaction(nandc); - - host->use_ecc = true; - set_address(host, 0, page); -@@ -1927,8 +1927,8 @@ static int qcom_nandc_write_page(struct nand_chip *chip, const u8 *buf, - set_address(host, 0, page); - nandc->buf_count = 0; - nandc->buf_start = 0; -- clear_read_regs(nandc); -- clear_bam_transaction(nandc); -+ qcom_clear_read_regs(nandc); -+ qcom_clear_bam_transaction(nandc); - - data_buf = (u8 *)buf; - oob_buf = chip->oob_poi; -@@ -1949,8 +1949,8 @@ static int qcom_nandc_write_page(struct nand_chip *chip, const u8 *buf, - oob_size = ecc->bytes; - } - -- write_data_dma(nandc, FLASH_BUF_ACC, data_buf, data_size, -- i == (ecc->steps - 1) ? NAND_BAM_NO_EOT : 0); -+ qcom_write_data_dma(nandc, FLASH_BUF_ACC, data_buf, data_size, -+ i == (ecc->steps - 1) ? NAND_BAM_NO_EOT : 0); - - /* - * when ECC is enabled, we don't really need to write anything -@@ -1962,8 +1962,8 @@ static int qcom_nandc_write_page(struct nand_chip *chip, const u8 *buf, - if (qcom_nandc_is_last_cw(ecc, i)) { - oob_buf += host->bbm_size; - -- write_data_dma(nandc, FLASH_BUF_ACC + data_size, -- oob_buf, oob_size, 0); -+ qcom_write_data_dma(nandc, FLASH_BUF_ACC + data_size, -+ oob_buf, oob_size, 0); - } - - config_nand_cw_write(chip); -@@ -1972,7 +1972,7 @@ static int qcom_nandc_write_page(struct nand_chip *chip, const u8 *buf, - oob_buf += oob_size; - } - -- ret = submit_descs(nandc); -+ ret = qcom_submit_descs(nandc); - if (ret) { - dev_err(nandc->dev, "failure to write page\n"); - return ret; -@@ -1997,8 +1997,8 @@ static int qcom_nandc_write_page_raw(struct nand_chip *chip, - qcom_nandc_codeword_fixup(host, page); - - nand_prog_page_begin_op(chip, page, 0, NULL, 0); -- clear_read_regs(nandc); -- clear_bam_transaction(nandc); -+ qcom_clear_read_regs(nandc); -+ qcom_clear_bam_transaction(nandc); - - data_buf = (u8 *)buf; - oob_buf = chip->oob_poi; -@@ -2024,28 +2024,28 @@ static int qcom_nandc_write_page_raw(struct nand_chip *chip, - oob_size2 = host->ecc_bytes_hw + host->spare_bytes; - } - -- write_data_dma(nandc, reg_off, data_buf, data_size1, -- NAND_BAM_NO_EOT); -+ qcom_write_data_dma(nandc, reg_off, data_buf, data_size1, -+ NAND_BAM_NO_EOT); - reg_off += data_size1; - data_buf += data_size1; - -- write_data_dma(nandc, reg_off, oob_buf, oob_size1, -- NAND_BAM_NO_EOT); -+ qcom_write_data_dma(nandc, reg_off, oob_buf, oob_size1, -+ NAND_BAM_NO_EOT); - reg_off += oob_size1; - oob_buf += oob_size1; - -- write_data_dma(nandc, reg_off, data_buf, data_size2, -- NAND_BAM_NO_EOT); -+ qcom_write_data_dma(nandc, reg_off, data_buf, data_size2, -+ NAND_BAM_NO_EOT); - reg_off += data_size2; - data_buf += data_size2; - -- write_data_dma(nandc, reg_off, oob_buf, oob_size2, 0); -+ qcom_write_data_dma(nandc, reg_off, oob_buf, oob_size2, 0); - oob_buf += oob_size2; - - config_nand_cw_write(chip); - } - -- ret = submit_descs(nandc); -+ ret = qcom_submit_descs(nandc); - if (ret) { - dev_err(nandc->dev, "failure to write raw page\n"); - return ret; -@@ -2075,7 +2075,7 @@ static int qcom_nandc_write_oob(struct nand_chip *chip, int page) - qcom_nandc_codeword_fixup(host, page); - - host->use_ecc = true; -- clear_bam_transaction(nandc); -+ qcom_clear_bam_transaction(nandc); - - /* calculate the data and oob size for the last codeword/step */ - data_size = ecc->size - ((ecc->steps - 1) << 2); -@@ -2090,11 +2090,11 @@ static int qcom_nandc_write_oob(struct nand_chip *chip, int page) - update_rw_regs(host, 1, false, 0); - - config_nand_page_write(chip); -- write_data_dma(nandc, FLASH_BUF_ACC, -- nandc->data_buffer, data_size + oob_size, 0); -+ qcom_write_data_dma(nandc, FLASH_BUF_ACC, -+ nandc->data_buffer, data_size + oob_size, 0); - config_nand_cw_write(chip); - -- ret = submit_descs(nandc); -+ ret = qcom_submit_descs(nandc); - if (ret) { - dev_err(nandc->dev, "failure to write oob\n"); - return ret; -@@ -2121,7 +2121,7 @@ static int qcom_nandc_block_bad(struct nand_chip *chip, loff_t ofs) - */ - host->use_ecc = false; - -- clear_bam_transaction(nandc); -+ qcom_clear_bam_transaction(nandc); - ret = copy_last_cw(host, page); - if (ret) - goto err; -@@ -2148,8 +2148,8 @@ static int qcom_nandc_block_markbad(struct nand_chip *chip, loff_t ofs) - struct nand_ecc_ctrl *ecc = &chip->ecc; - int page, ret; - -- clear_read_regs(nandc); -- clear_bam_transaction(nandc); -+ qcom_clear_read_regs(nandc); -+ qcom_clear_bam_transaction(nandc); - - /* - * to mark the BBM as bad, we flash the entire last codeword with 0s. -@@ -2166,11 +2166,11 @@ static int qcom_nandc_block_markbad(struct nand_chip *chip, loff_t ofs) - update_rw_regs(host, 1, false, ecc->steps - 1); - - config_nand_page_write(chip); -- write_data_dma(nandc, FLASH_BUF_ACC, -- nandc->data_buffer, host->cw_size, 0); -+ qcom_write_data_dma(nandc, FLASH_BUF_ACC, -+ nandc->data_buffer, host->cw_size, 0); - config_nand_cw_write(chip); - -- ret = submit_descs(nandc); -+ ret = qcom_submit_descs(nandc); - if (ret) { - dev_err(nandc->dev, "failure to update BBM\n"); - return ret; -@@ -2410,14 +2410,14 @@ static int qcom_nand_attach_chip(struct nand_chip *chip) - mtd_set_ooblayout(mtd, &qcom_nand_ooblayout_ops); - /* Free the initially allocated BAM transaction for reading the ONFI params */ - if (nandc->props->supports_bam) -- free_bam_transaction(nandc); -+ qcom_free_bam_transaction(nandc); - - nandc->max_cwperpage = max_t(unsigned int, nandc->max_cwperpage, - cwperpage); - - /* Now allocate the BAM transaction based on updated max_cwperpage */ - if (nandc->props->supports_bam) { -- nandc->bam_txn = alloc_bam_transaction(nandc); -+ nandc->bam_txn = qcom_alloc_bam_transaction(nandc); - if (!nandc->bam_txn) { - dev_err(nandc->dev, - "failed to allocate bam transaction\n"); -@@ -2617,7 +2617,7 @@ static int qcom_wait_rdy_poll(struct nand_chip *chip, unsigned int time_ms) - unsigned long start = jiffies + msecs_to_jiffies(time_ms); - u32 flash; - -- nandc_dev_to_mem(nandc, true); -+ qcom_nandc_dev_to_mem(nandc, true); - - do { - flash = le32_to_cpu(nandc->reg_read_buf[0]); -@@ -2657,23 +2657,23 @@ static int qcom_read_status_exec(struct nand_chip *chip, - nandc->buf_start = 0; - host->use_ecc = false; - -- clear_read_regs(nandc); -- clear_bam_transaction(nandc); -+ qcom_clear_read_regs(nandc); -+ qcom_clear_bam_transaction(nandc); - - nandc->regs->cmd = q_op.cmd_reg; - nandc->regs->exec = cpu_to_le32(1); - -- write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL); -- write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); -- read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL); -+ qcom_write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL); -+ qcom_write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); -+ qcom_read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL); - -- ret = submit_descs(nandc); -+ ret = qcom_submit_descs(nandc); - if (ret) { - dev_err(nandc->dev, "failure in submitting status descriptor\n"); - goto err_out; - } - -- nandc_dev_to_mem(nandc, true); -+ qcom_nandc_dev_to_mem(nandc, true); - - for (i = 0; i < num_cw; i++) { - flash_status = le32_to_cpu(nandc->reg_read_buf[i]); -@@ -2714,8 +2714,8 @@ static int qcom_read_id_type_exec(struct nand_chip *chip, const struct nand_subo - nandc->buf_start = 0; - host->use_ecc = false; - -- clear_read_regs(nandc); -- clear_bam_transaction(nandc); -+ qcom_clear_read_regs(nandc); -+ qcom_clear_bam_transaction(nandc); - - nandc->regs->cmd = q_op.cmd_reg; - nandc->regs->addr0 = q_op.addr1_reg; -@@ -2723,12 +2723,12 @@ static int qcom_read_id_type_exec(struct nand_chip *chip, const struct nand_subo - nandc->regs->chip_sel = cpu_to_le32(nandc->props->supports_bam ? 0 : DM_EN); - nandc->regs->exec = cpu_to_le32(1); - -- write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 4, NAND_BAM_NEXT_SGL); -- write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); -+ qcom_write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 4, NAND_BAM_NEXT_SGL); -+ qcom_write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); - -- read_reg_dma(nandc, NAND_READ_ID, 1, NAND_BAM_NEXT_SGL); -+ qcom_read_reg_dma(nandc, NAND_READ_ID, 1, NAND_BAM_NEXT_SGL); - -- ret = submit_descs(nandc); -+ ret = qcom_submit_descs(nandc); - if (ret) { - dev_err(nandc->dev, "failure in submitting read id descriptor\n"); - goto err_out; -@@ -2738,7 +2738,7 @@ static int qcom_read_id_type_exec(struct nand_chip *chip, const struct nand_subo - op_id = q_op.data_instr_idx; - len = nand_subop_get_data_len(subop, op_id); - -- nandc_dev_to_mem(nandc, true); -+ qcom_nandc_dev_to_mem(nandc, true); - memcpy(instr->ctx.data.buf.in, nandc->reg_read_buf, len); - - err_out: -@@ -2774,20 +2774,20 @@ static int qcom_misc_cmd_type_exec(struct nand_chip *chip, const struct nand_sub - nandc->buf_start = 0; - host->use_ecc = false; - -- clear_read_regs(nandc); -- clear_bam_transaction(nandc); -+ qcom_clear_read_regs(nandc); -+ qcom_clear_bam_transaction(nandc); - - nandc->regs->cmd = q_op.cmd_reg; - nandc->regs->exec = cpu_to_le32(1); - -- write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, instrs, NAND_BAM_NEXT_SGL); -+ qcom_write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, instrs, NAND_BAM_NEXT_SGL); - if (q_op.cmd_reg == cpu_to_le32(OP_BLOCK_ERASE)) -- write_reg_dma(nandc, &nandc->regs->cfg0, NAND_DEV0_CFG0, 2, NAND_BAM_NEXT_SGL); -+ qcom_write_reg_dma(nandc, &nandc->regs->cfg0, NAND_DEV0_CFG0, 2, NAND_BAM_NEXT_SGL); - -- write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); -- read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL); -+ qcom_write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); -+ qcom_read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL); - -- ret = submit_descs(nandc); -+ ret = qcom_submit_descs(nandc); - if (ret) { - dev_err(nandc->dev, "failure in submitting misc descriptor\n"); - goto err_out; -@@ -2825,8 +2825,8 @@ static int qcom_param_page_type_exec(struct nand_chip *chip, const struct nand_ - nandc->buf_count = 0; - nandc->buf_start = 0; - host->use_ecc = false; -- clear_read_regs(nandc); -- clear_bam_transaction(nandc); -+ qcom_clear_read_regs(nandc); -+ qcom_clear_bam_transaction(nandc); - - nandc->regs->cmd = q_op.cmd_reg; - nandc->regs->addr0 = 0; -@@ -2872,8 +2872,8 @@ static int qcom_param_page_type_exec(struct nand_chip *chip, const struct nand_ - nandc_set_read_loc_first(chip, reg_base, 0, len, 1); - - if (!nandc->props->qpic_version2) { -- write_reg_dma(nandc, &nandc->regs->vld, NAND_DEV_CMD_VLD, 1, 0); -- write_reg_dma(nandc, &nandc->regs->cmd1, NAND_DEV_CMD1, 1, NAND_BAM_NEXT_SGL); -+ qcom_write_reg_dma(nandc, &nandc->regs->vld, NAND_DEV_CMD_VLD, 1, 0); -+ qcom_write_reg_dma(nandc, &nandc->regs->cmd1, NAND_DEV_CMD1, 1, NAND_BAM_NEXT_SGL); - } - - nandc->buf_count = 512; -@@ -2881,17 +2881,17 @@ static int qcom_param_page_type_exec(struct nand_chip *chip, const struct nand_ - - config_nand_single_cw_page_read(chip, false, 0); - -- read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, -- nandc->buf_count, 0); -+ qcom_read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, -+ nandc->buf_count, 0); - - /* restore CMD1 and VLD regs */ - if (!nandc->props->qpic_version2) { -- write_reg_dma(nandc, &nandc->regs->orig_cmd1, NAND_DEV_CMD1_RESTORE, 1, 0); -- write_reg_dma(nandc, &nandc->regs->orig_vld, NAND_DEV_CMD_VLD_RESTORE, 1, -- NAND_BAM_NEXT_SGL); -+ qcom_write_reg_dma(nandc, &nandc->regs->orig_cmd1, NAND_DEV_CMD1_RESTORE, 1, 0); -+ qcom_write_reg_dma(nandc, &nandc->regs->orig_vld, NAND_DEV_CMD_VLD_RESTORE, 1, -+ NAND_BAM_NEXT_SGL); - } - -- ret = submit_descs(nandc); -+ ret = qcom_submit_descs(nandc); - if (ret) { - dev_err(nandc->dev, "failure in submitting param page descriptor\n"); - goto err_out; -@@ -3075,7 +3075,7 @@ static int qcom_nandc_alloc(struct qcom_nand_controller *nandc) - * maximum codeword size - */ - nandc->max_cwperpage = 1; -- nandc->bam_txn = alloc_bam_transaction(nandc); -+ nandc->bam_txn = qcom_alloc_bam_transaction(nandc); - if (!nandc->bam_txn) { - dev_err(nandc->dev, - "failed to allocate bam transaction\n"); --- -2.51.0 - - -From 6c04b5738159ccfc2447219245c49e71c7428db0 Mon Sep 17 00:00:00 2001 -From: Md Sadre Alam -Date: Wed, 20 Nov 2024 14:45:02 +0530 -Subject: [PATCH 012/517] mtd: nand: Add qpic_common API file - -Add qpic_common.c file which hold all the common -qpic APIs which will be used by both qpic raw nand -driver and qpic spi nand driver. - -Signed-off-by: Md Sadre Alam -Signed-off-by: Miquel Raynal ---- - drivers/mtd/nand/Makefile | 2 +- - drivers/mtd/nand/qpic_common.c | 759 ++++++++++++++++++ - drivers/mtd/nand/raw/qcom_nandc.c | 1092 +------------------------- - include/linux/mtd/nand-qpic-common.h | 468 +++++++++++ - 4 files changed, 1240 insertions(+), 1081 deletions(-) - create mode 100644 drivers/mtd/nand/qpic_common.c - create mode 100644 include/linux/mtd/nand-qpic-common.h - -diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile -index 19e1291ac4d5..da1586a36574 100644 ---- a/drivers/mtd/nand/Makefile -+++ b/drivers/mtd/nand/Makefile -@@ -3,7 +3,7 @@ - nandcore-objs := core.o bbt.o - obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o - obj-$(CONFIG_MTD_NAND_ECC_MEDIATEK) += ecc-mtk.o -- -+obj-$(CONFIG_MTD_NAND_QCOM) += qpic_common.o - obj-y += onenand/ - obj-y += raw/ - obj-y += spi/ -diff --git a/drivers/mtd/nand/qpic_common.c b/drivers/mtd/nand/qpic_common.c -new file mode 100644 -index 000000000000..8abbb960a7ce ---- /dev/null -+++ b/drivers/mtd/nand/qpic_common.c -@@ -0,0 +1,759 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2016, The Linux Foundation. All rights reserved. -+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/** -+ * qcom_free_bam_transaction() - Frees the BAM transaction memory -+ * @nandc: qpic nand controller -+ * -+ * This function frees the bam transaction memory -+ */ -+void qcom_free_bam_transaction(struct qcom_nand_controller *nandc) -+{ -+ struct bam_transaction *bam_txn = nandc->bam_txn; -+ -+ kfree(bam_txn); -+} -+EXPORT_SYMBOL(qcom_free_bam_transaction); -+ -+/** -+ * qcom_alloc_bam_transaction() - allocate BAM transaction -+ * @nandc: qpic nand controller -+ * -+ * This function will allocate and initialize the BAM transaction structure -+ */ -+struct bam_transaction * -+qcom_alloc_bam_transaction(struct qcom_nand_controller *nandc) -+{ -+ struct bam_transaction *bam_txn; -+ size_t bam_txn_size; -+ unsigned int num_cw = nandc->max_cwperpage; -+ void *bam_txn_buf; -+ -+ bam_txn_size = -+ sizeof(*bam_txn) + num_cw * -+ ((sizeof(*bam_txn->bam_ce) * QPIC_PER_CW_CMD_ELEMENTS) + -+ (sizeof(*bam_txn->cmd_sgl) * QPIC_PER_CW_CMD_SGL) + -+ (sizeof(*bam_txn->data_sgl) * QPIC_PER_CW_DATA_SGL)); -+ -+ bam_txn_buf = kzalloc(bam_txn_size, GFP_KERNEL); -+ if (!bam_txn_buf) -+ return NULL; -+ -+ bam_txn = bam_txn_buf; -+ bam_txn_buf += sizeof(*bam_txn); -+ -+ bam_txn->bam_ce = bam_txn_buf; -+ bam_txn_buf += -+ sizeof(*bam_txn->bam_ce) * QPIC_PER_CW_CMD_ELEMENTS * num_cw; -+ -+ bam_txn->cmd_sgl = bam_txn_buf; -+ bam_txn_buf += -+ sizeof(*bam_txn->cmd_sgl) * QPIC_PER_CW_CMD_SGL * num_cw; -+ -+ bam_txn->data_sgl = bam_txn_buf; -+ -+ init_completion(&bam_txn->txn_done); -+ -+ return bam_txn; -+} -+EXPORT_SYMBOL(qcom_alloc_bam_transaction); -+ -+/** -+ * qcom_clear_bam_transaction() - Clears the BAM transaction -+ * @nandc: qpic nand controller -+ * -+ * This function will clear the BAM transaction indexes. -+ */ -+void qcom_clear_bam_transaction(struct qcom_nand_controller *nandc) -+{ -+ struct bam_transaction *bam_txn = nandc->bam_txn; -+ -+ if (!nandc->props->supports_bam) -+ return; -+ -+ memset(&bam_txn->bam_ce_pos, 0, sizeof(u32) * 8); -+ bam_txn->last_data_desc = NULL; -+ -+ sg_init_table(bam_txn->cmd_sgl, nandc->max_cwperpage * -+ QPIC_PER_CW_CMD_SGL); -+ sg_init_table(bam_txn->data_sgl, nandc->max_cwperpage * -+ QPIC_PER_CW_DATA_SGL); -+ -+ reinit_completion(&bam_txn->txn_done); -+} -+EXPORT_SYMBOL(qcom_clear_bam_transaction); -+ -+/** -+ * qcom_qpic_bam_dma_done() - Callback for DMA descriptor completion -+ * @data: data pointer -+ * -+ * This function is a callback for DMA descriptor completion -+ */ -+void qcom_qpic_bam_dma_done(void *data) -+{ -+ struct bam_transaction *bam_txn = data; -+ -+ complete(&bam_txn->txn_done); -+} -+EXPORT_SYMBOL(qcom_qpic_bam_dma_done); -+ -+/** -+ * qcom_nandc_dev_to_mem() - Check for dma sync for cpu or device -+ * @nandc: qpic nand controller -+ * @is_cpu: cpu or Device -+ * -+ * This function will check for dma sync for cpu or device -+ */ -+inline void qcom_nandc_dev_to_mem(struct qcom_nand_controller *nandc, bool is_cpu) -+{ -+ if (!nandc->props->supports_bam) -+ return; -+ -+ if (is_cpu) -+ dma_sync_single_for_cpu(nandc->dev, nandc->reg_read_dma, -+ MAX_REG_RD * -+ sizeof(*nandc->reg_read_buf), -+ DMA_FROM_DEVICE); -+ else -+ dma_sync_single_for_device(nandc->dev, nandc->reg_read_dma, -+ MAX_REG_RD * -+ sizeof(*nandc->reg_read_buf), -+ DMA_FROM_DEVICE); -+} -+EXPORT_SYMBOL(qcom_nandc_dev_to_mem); -+ -+/** -+ * qcom_prepare_bam_async_desc() - Prepare DMA descriptor -+ * @nandc: qpic nand controller -+ * @chan: dma channel -+ * @flags: flags to control DMA descriptor preparation -+ * -+ * This function maps the scatter gather list for DMA transfer and forms the -+ * DMA descriptor for BAM.This descriptor will be added in the NAND DMA -+ * descriptor queue which will be submitted to DMA engine. -+ */ -+int qcom_prepare_bam_async_desc(struct qcom_nand_controller *nandc, -+ struct dma_chan *chan, unsigned long flags) -+{ -+ struct desc_info *desc; -+ struct scatterlist *sgl; -+ unsigned int sgl_cnt; -+ int ret; -+ struct bam_transaction *bam_txn = nandc->bam_txn; -+ enum dma_transfer_direction dir_eng; -+ struct dma_async_tx_descriptor *dma_desc; -+ -+ desc = kzalloc(sizeof(*desc), GFP_KERNEL); -+ if (!desc) -+ return -ENOMEM; -+ -+ if (chan == nandc->cmd_chan) { -+ sgl = &bam_txn->cmd_sgl[bam_txn->cmd_sgl_start]; -+ sgl_cnt = bam_txn->cmd_sgl_pos - bam_txn->cmd_sgl_start; -+ bam_txn->cmd_sgl_start = bam_txn->cmd_sgl_pos; -+ dir_eng = DMA_MEM_TO_DEV; -+ desc->dir = DMA_TO_DEVICE; -+ } else if (chan == nandc->tx_chan) { -+ sgl = &bam_txn->data_sgl[bam_txn->tx_sgl_start]; -+ sgl_cnt = bam_txn->tx_sgl_pos - bam_txn->tx_sgl_start; -+ bam_txn->tx_sgl_start = bam_txn->tx_sgl_pos; -+ dir_eng = DMA_MEM_TO_DEV; -+ desc->dir = DMA_TO_DEVICE; -+ } else { -+ sgl = &bam_txn->data_sgl[bam_txn->rx_sgl_start]; -+ sgl_cnt = bam_txn->rx_sgl_pos - bam_txn->rx_sgl_start; -+ bam_txn->rx_sgl_start = bam_txn->rx_sgl_pos; -+ dir_eng = DMA_DEV_TO_MEM; -+ desc->dir = DMA_FROM_DEVICE; -+ } -+ -+ sg_mark_end(sgl + sgl_cnt - 1); -+ ret = dma_map_sg(nandc->dev, sgl, sgl_cnt, desc->dir); -+ if (ret == 0) { -+ dev_err(nandc->dev, "failure in mapping desc\n"); -+ kfree(desc); -+ return -ENOMEM; -+ } -+ -+ desc->sgl_cnt = sgl_cnt; -+ desc->bam_sgl = sgl; -+ -+ dma_desc = dmaengine_prep_slave_sg(chan, sgl, sgl_cnt, dir_eng, -+ flags); -+ -+ if (!dma_desc) { -+ dev_err(nandc->dev, "failure in prep desc\n"); -+ dma_unmap_sg(nandc->dev, sgl, sgl_cnt, desc->dir); -+ kfree(desc); -+ return -EINVAL; -+ } -+ -+ desc->dma_desc = dma_desc; -+ -+ /* update last data/command descriptor */ -+ if (chan == nandc->cmd_chan) -+ bam_txn->last_cmd_desc = dma_desc; -+ else -+ bam_txn->last_data_desc = dma_desc; -+ -+ list_add_tail(&desc->node, &nandc->desc_list); -+ -+ return 0; -+} -+EXPORT_SYMBOL(qcom_prepare_bam_async_desc); -+ -+/** -+ * qcom_prep_bam_dma_desc_cmd() - Prepares the command descriptor for BAM DMA -+ * @nandc: qpic nand controller -+ * @read: read or write type -+ * @reg_off: offset within the controller's data buffer -+ * @vaddr: virtual address of the buffer we want to write to -+ * @size: DMA transaction size in bytes -+ * @flags: flags to control DMA descriptor preparation -+ * -+ * This function will prepares the command descriptor for BAM DMA -+ * which will be used for NAND register reads and writes. -+ */ -+int qcom_prep_bam_dma_desc_cmd(struct qcom_nand_controller *nandc, bool read, -+ int reg_off, const void *vaddr, -+ int size, unsigned int flags) -+{ -+ int bam_ce_size; -+ int i, ret; -+ struct bam_cmd_element *bam_ce_buffer; -+ struct bam_transaction *bam_txn = nandc->bam_txn; -+ -+ bam_ce_buffer = &bam_txn->bam_ce[bam_txn->bam_ce_pos]; -+ -+ /* fill the command desc */ -+ for (i = 0; i < size; i++) { -+ if (read) -+ bam_prep_ce(&bam_ce_buffer[i], -+ nandc_reg_phys(nandc, reg_off + 4 * i), -+ BAM_READ_COMMAND, -+ reg_buf_dma_addr(nandc, -+ (__le32 *)vaddr + i)); -+ else -+ bam_prep_ce_le32(&bam_ce_buffer[i], -+ nandc_reg_phys(nandc, reg_off + 4 * i), -+ BAM_WRITE_COMMAND, -+ *((__le32 *)vaddr + i)); -+ } -+ -+ bam_txn->bam_ce_pos += size; -+ -+ /* use the separate sgl after this command */ -+ if (flags & NAND_BAM_NEXT_SGL) { -+ bam_ce_buffer = &bam_txn->bam_ce[bam_txn->bam_ce_start]; -+ bam_ce_size = (bam_txn->bam_ce_pos - -+ bam_txn->bam_ce_start) * -+ sizeof(struct bam_cmd_element); -+ sg_set_buf(&bam_txn->cmd_sgl[bam_txn->cmd_sgl_pos], -+ bam_ce_buffer, bam_ce_size); -+ bam_txn->cmd_sgl_pos++; -+ bam_txn->bam_ce_start = bam_txn->bam_ce_pos; -+ -+ if (flags & NAND_BAM_NWD) { -+ ret = qcom_prepare_bam_async_desc(nandc, nandc->cmd_chan, -+ DMA_PREP_FENCE | DMA_PREP_CMD); -+ if (ret) -+ return ret; -+ } -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(qcom_prep_bam_dma_desc_cmd); -+ -+/** -+ * qcom_prep_bam_dma_desc_data() - Prepares the data descriptor for BAM DMA -+ * @nandc: qpic nand controller -+ * @read: read or write type -+ * @vaddr: virtual address of the buffer we want to write to -+ * @size: DMA transaction size in bytes -+ * @flags: flags to control DMA descriptor preparation -+ * -+ * This function will prepares the data descriptor for BAM DMA which -+ * will be used for NAND data reads and writes. -+ */ -+int qcom_prep_bam_dma_desc_data(struct qcom_nand_controller *nandc, bool read, -+ const void *vaddr, int size, unsigned int flags) -+{ -+ int ret; -+ struct bam_transaction *bam_txn = nandc->bam_txn; -+ -+ if (read) { -+ sg_set_buf(&bam_txn->data_sgl[bam_txn->rx_sgl_pos], -+ vaddr, size); -+ bam_txn->rx_sgl_pos++; -+ } else { -+ sg_set_buf(&bam_txn->data_sgl[bam_txn->tx_sgl_pos], -+ vaddr, size); -+ bam_txn->tx_sgl_pos++; -+ -+ /* -+ * BAM will only set EOT for DMA_PREP_INTERRUPT so if this flag -+ * is not set, form the DMA descriptor -+ */ -+ if (!(flags & NAND_BAM_NO_EOT)) { -+ ret = qcom_prepare_bam_async_desc(nandc, nandc->tx_chan, -+ DMA_PREP_INTERRUPT); -+ if (ret) -+ return ret; -+ } -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(qcom_prep_bam_dma_desc_data); -+ -+/** -+ * qcom_prep_adm_dma_desc() - Prepare descriptor for adma -+ * @nandc: qpic nand controller -+ * @read: read or write type -+ * @reg_off: offset within the controller's data buffer -+ * @vaddr: virtual address of the buffer we want to write to -+ * @size: adm dma transaction size in bytes -+ * @flow_control: flow controller -+ * -+ * This function will prepare descriptor for adma -+ */ -+int qcom_prep_adm_dma_desc(struct qcom_nand_controller *nandc, bool read, -+ int reg_off, const void *vaddr, int size, -+ bool flow_control) -+{ -+ struct qcom_adm_peripheral_config periph_conf = {}; -+ struct dma_async_tx_descriptor *dma_desc; -+ struct dma_slave_config slave_conf = {0}; -+ enum dma_transfer_direction dir_eng; -+ struct desc_info *desc; -+ struct scatterlist *sgl; -+ int ret; -+ -+ desc = kzalloc(sizeof(*desc), GFP_KERNEL); -+ if (!desc) -+ return -ENOMEM; -+ -+ sgl = &desc->adm_sgl; -+ -+ sg_init_one(sgl, vaddr, size); -+ -+ if (read) { -+ dir_eng = DMA_DEV_TO_MEM; -+ desc->dir = DMA_FROM_DEVICE; -+ } else { -+ dir_eng = DMA_MEM_TO_DEV; -+ desc->dir = DMA_TO_DEVICE; -+ } -+ -+ ret = dma_map_sg(nandc->dev, sgl, 1, desc->dir); -+ if (!ret) { -+ ret = -ENOMEM; -+ goto err; -+ } -+ -+ slave_conf.device_fc = flow_control; -+ if (read) { -+ slave_conf.src_maxburst = 16; -+ slave_conf.src_addr = nandc->base_dma + reg_off; -+ if (nandc->data_crci) { -+ periph_conf.crci = nandc->data_crci; -+ slave_conf.peripheral_config = &periph_conf; -+ slave_conf.peripheral_size = sizeof(periph_conf); -+ } -+ } else { -+ slave_conf.dst_maxburst = 16; -+ slave_conf.dst_addr = nandc->base_dma + reg_off; -+ if (nandc->cmd_crci) { -+ periph_conf.crci = nandc->cmd_crci; -+ slave_conf.peripheral_config = &periph_conf; -+ slave_conf.peripheral_size = sizeof(periph_conf); -+ } -+ } -+ -+ ret = dmaengine_slave_config(nandc->chan, &slave_conf); -+ if (ret) { -+ dev_err(nandc->dev, "failed to configure dma channel\n"); -+ goto err; -+ } -+ -+ dma_desc = dmaengine_prep_slave_sg(nandc->chan, sgl, 1, dir_eng, 0); -+ if (!dma_desc) { -+ dev_err(nandc->dev, "failed to prepare desc\n"); -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ desc->dma_desc = dma_desc; -+ -+ list_add_tail(&desc->node, &nandc->desc_list); -+ -+ return 0; -+err: -+ kfree(desc); -+ -+ return ret; -+} -+EXPORT_SYMBOL(qcom_prep_adm_dma_desc); -+ -+/** -+ * qcom_read_reg_dma() - read a given number of registers to the reg_read_buf pointer -+ * @nandc: qpic nand controller -+ * @first: offset of the first register in the contiguous block -+ * @num_regs: number of registers to read -+ * @flags: flags to control DMA descriptor preparation -+ * -+ * This function will prepares a descriptor to read a given number of -+ * contiguous registers to the reg_read_buf pointer. -+ */ -+int qcom_read_reg_dma(struct qcom_nand_controller *nandc, int first, -+ int num_regs, unsigned int flags) -+{ -+ bool flow_control = false; -+ void *vaddr; -+ -+ vaddr = nandc->reg_read_buf + nandc->reg_read_pos; -+ nandc->reg_read_pos += num_regs; -+ -+ if (first == NAND_DEV_CMD_VLD || first == NAND_DEV_CMD1) -+ first = dev_cmd_reg_addr(nandc, first); -+ -+ if (nandc->props->supports_bam) -+ return qcom_prep_bam_dma_desc_cmd(nandc, true, first, vaddr, -+ num_regs, flags); -+ -+ if (first == NAND_READ_ID || first == NAND_FLASH_STATUS) -+ flow_control = true; -+ -+ return qcom_prep_adm_dma_desc(nandc, true, first, vaddr, -+ num_regs * sizeof(u32), flow_control); -+} -+EXPORT_SYMBOL(qcom_read_reg_dma); -+ -+/** -+ * qcom_write_reg_dma() - write a given number of registers -+ * @nandc: qpic nand controller -+ * @vaddr: contiguous memory from where register value will -+ * be written -+ * @first: offset of the first register in the contiguous block -+ * @num_regs: number of registers to write -+ * @flags: flags to control DMA descriptor preparation -+ * -+ * This function will prepares a descriptor to write a given number of -+ * contiguous registers -+ */ -+int qcom_write_reg_dma(struct qcom_nand_controller *nandc, __le32 *vaddr, -+ int first, int num_regs, unsigned int flags) -+{ -+ bool flow_control = false; -+ -+ if (first == NAND_EXEC_CMD) -+ flags |= NAND_BAM_NWD; -+ -+ if (first == NAND_DEV_CMD1_RESTORE || first == NAND_DEV_CMD1) -+ first = dev_cmd_reg_addr(nandc, NAND_DEV_CMD1); -+ -+ if (first == NAND_DEV_CMD_VLD_RESTORE || first == NAND_DEV_CMD_VLD) -+ first = dev_cmd_reg_addr(nandc, NAND_DEV_CMD_VLD); -+ -+ if (nandc->props->supports_bam) -+ return qcom_prep_bam_dma_desc_cmd(nandc, false, first, vaddr, -+ num_regs, flags); -+ -+ if (first == NAND_FLASH_CMD) -+ flow_control = true; -+ -+ return qcom_prep_adm_dma_desc(nandc, false, first, vaddr, -+ num_regs * sizeof(u32), flow_control); -+} -+EXPORT_SYMBOL(qcom_write_reg_dma); -+ -+/** -+ * qcom_read_data_dma() - transfer data -+ * @nandc: qpic nand controller -+ * @reg_off: offset within the controller's data buffer -+ * @vaddr: virtual address of the buffer we want to write to -+ * @size: DMA transaction size in bytes -+ * @flags: flags to control DMA descriptor preparation -+ * -+ * This function will prepares a DMA descriptor to transfer data from the -+ * controller's internal buffer to the buffer 'vaddr' -+ */ -+int qcom_read_data_dma(struct qcom_nand_controller *nandc, int reg_off, -+ const u8 *vaddr, int size, unsigned int flags) -+{ -+ if (nandc->props->supports_bam) -+ return qcom_prep_bam_dma_desc_data(nandc, true, vaddr, size, flags); -+ -+ return qcom_prep_adm_dma_desc(nandc, true, reg_off, vaddr, size, false); -+} -+EXPORT_SYMBOL(qcom_read_data_dma); -+ -+/** -+ * qcom_write_data_dma() - transfer data -+ * @nandc: qpic nand controller -+ * @reg_off: offset within the controller's data buffer -+ * @vaddr: virtual address of the buffer we want to read from -+ * @size: DMA transaction size in bytes -+ * @flags: flags to control DMA descriptor preparation -+ * -+ * This function will prepares a DMA descriptor to transfer data from -+ * 'vaddr' to the controller's internal buffer -+ */ -+int qcom_write_data_dma(struct qcom_nand_controller *nandc, int reg_off, -+ const u8 *vaddr, int size, unsigned int flags) -+{ -+ if (nandc->props->supports_bam) -+ return qcom_prep_bam_dma_desc_data(nandc, false, vaddr, size, flags); -+ -+ return qcom_prep_adm_dma_desc(nandc, false, reg_off, vaddr, size, false); -+} -+EXPORT_SYMBOL(qcom_write_data_dma); -+ -+/** -+ * qcom_submit_descs() - submit dma descriptor -+ * @nandc: qpic nand controller -+ * -+ * This function will submit all the prepared dma descriptor -+ * cmd or data descriptor -+ */ -+int qcom_submit_descs(struct qcom_nand_controller *nandc) -+{ -+ struct desc_info *desc, *n; -+ dma_cookie_t cookie = 0; -+ struct bam_transaction *bam_txn = nandc->bam_txn; -+ int ret = 0; -+ -+ if (nandc->props->supports_bam) { -+ if (bam_txn->rx_sgl_pos > bam_txn->rx_sgl_start) { -+ ret = qcom_prepare_bam_async_desc(nandc, nandc->rx_chan, 0); -+ if (ret) -+ goto err_unmap_free_desc; -+ } -+ -+ if (bam_txn->tx_sgl_pos > bam_txn->tx_sgl_start) { -+ ret = qcom_prepare_bam_async_desc(nandc, nandc->tx_chan, -+ DMA_PREP_INTERRUPT); -+ if (ret) -+ goto err_unmap_free_desc; -+ } -+ -+ if (bam_txn->cmd_sgl_pos > bam_txn->cmd_sgl_start) { -+ ret = qcom_prepare_bam_async_desc(nandc, nandc->cmd_chan, -+ DMA_PREP_CMD); -+ if (ret) -+ goto err_unmap_free_desc; -+ } -+ } -+ -+ list_for_each_entry(desc, &nandc->desc_list, node) -+ cookie = dmaengine_submit(desc->dma_desc); -+ -+ if (nandc->props->supports_bam) { -+ bam_txn->last_cmd_desc->callback = qcom_qpic_bam_dma_done; -+ bam_txn->last_cmd_desc->callback_param = bam_txn; -+ -+ dma_async_issue_pending(nandc->tx_chan); -+ dma_async_issue_pending(nandc->rx_chan); -+ dma_async_issue_pending(nandc->cmd_chan); -+ -+ if (!wait_for_completion_timeout(&bam_txn->txn_done, -+ QPIC_NAND_COMPLETION_TIMEOUT)) -+ ret = -ETIMEDOUT; -+ } else { -+ if (dma_sync_wait(nandc->chan, cookie) != DMA_COMPLETE) -+ ret = -ETIMEDOUT; -+ } -+ -+err_unmap_free_desc: -+ /* -+ * Unmap the dma sg_list and free the desc allocated by both -+ * qcom_prepare_bam_async_desc() and qcom_prep_adm_dma_desc() functions. -+ */ -+ list_for_each_entry_safe(desc, n, &nandc->desc_list, node) { -+ list_del(&desc->node); -+ -+ if (nandc->props->supports_bam) -+ dma_unmap_sg(nandc->dev, desc->bam_sgl, -+ desc->sgl_cnt, desc->dir); -+ else -+ dma_unmap_sg(nandc->dev, &desc->adm_sgl, 1, -+ desc->dir); -+ -+ kfree(desc); -+ } -+ -+ return ret; -+} -+EXPORT_SYMBOL(qcom_submit_descs); -+ -+/** -+ * qcom_clear_read_regs() - reset the read register buffer -+ * @nandc: qpic nand controller -+ * -+ * This function reset the register read buffer for next NAND operation -+ */ -+void qcom_clear_read_regs(struct qcom_nand_controller *nandc) -+{ -+ nandc->reg_read_pos = 0; -+ qcom_nandc_dev_to_mem(nandc, false); -+} -+EXPORT_SYMBOL(qcom_clear_read_regs); -+ -+/** -+ * qcom_nandc_unalloc() - unallocate qpic nand controller -+ * @nandc: qpic nand controller -+ * -+ * This function will unallocate memory alloacted for qpic nand controller -+ */ -+void qcom_nandc_unalloc(struct qcom_nand_controller *nandc) -+{ -+ if (nandc->props->supports_bam) { -+ if (!dma_mapping_error(nandc->dev, nandc->reg_read_dma)) -+ dma_unmap_single(nandc->dev, nandc->reg_read_dma, -+ MAX_REG_RD * -+ sizeof(*nandc->reg_read_buf), -+ DMA_FROM_DEVICE); -+ -+ if (nandc->tx_chan) -+ dma_release_channel(nandc->tx_chan); -+ -+ if (nandc->rx_chan) -+ dma_release_channel(nandc->rx_chan); -+ -+ if (nandc->cmd_chan) -+ dma_release_channel(nandc->cmd_chan); -+ } else { -+ if (nandc->chan) -+ dma_release_channel(nandc->chan); -+ } -+} -+EXPORT_SYMBOL(qcom_nandc_unalloc); -+ -+/** -+ * qcom_nandc_alloc() - Allocate qpic nand controller -+ * @nandc: qpic nand controller -+ * -+ * This function will allocate memory for qpic nand controller -+ */ -+int qcom_nandc_alloc(struct qcom_nand_controller *nandc) -+{ -+ int ret; -+ -+ ret = dma_set_coherent_mask(nandc->dev, DMA_BIT_MASK(32)); -+ if (ret) { -+ dev_err(nandc->dev, "failed to set DMA mask\n"); -+ return ret; -+ } -+ -+ /* -+ * we use the internal buffer for reading ONFI params, reading small -+ * data like ID and status, and preforming read-copy-write operations -+ * when writing to a codeword partially. 532 is the maximum possible -+ * size of a codeword for our nand controller -+ */ -+ nandc->buf_size = 532; -+ -+ nandc->data_buffer = devm_kzalloc(nandc->dev, nandc->buf_size, GFP_KERNEL); -+ if (!nandc->data_buffer) -+ return -ENOMEM; -+ -+ nandc->regs = devm_kzalloc(nandc->dev, sizeof(*nandc->regs), GFP_KERNEL); -+ if (!nandc->regs) -+ return -ENOMEM; -+ -+ nandc->reg_read_buf = devm_kcalloc(nandc->dev, MAX_REG_RD, -+ sizeof(*nandc->reg_read_buf), -+ GFP_KERNEL); -+ if (!nandc->reg_read_buf) -+ return -ENOMEM; -+ -+ if (nandc->props->supports_bam) { -+ nandc->reg_read_dma = -+ dma_map_single(nandc->dev, nandc->reg_read_buf, -+ MAX_REG_RD * -+ sizeof(*nandc->reg_read_buf), -+ DMA_FROM_DEVICE); -+ if (dma_mapping_error(nandc->dev, nandc->reg_read_dma)) { -+ dev_err(nandc->dev, "failed to DMA MAP reg buffer\n"); -+ return -EIO; -+ } -+ -+ nandc->tx_chan = dma_request_chan(nandc->dev, "tx"); -+ if (IS_ERR(nandc->tx_chan)) { -+ ret = PTR_ERR(nandc->tx_chan); -+ nandc->tx_chan = NULL; -+ dev_err_probe(nandc->dev, ret, -+ "tx DMA channel request failed\n"); -+ goto unalloc; -+ } -+ -+ nandc->rx_chan = dma_request_chan(nandc->dev, "rx"); -+ if (IS_ERR(nandc->rx_chan)) { -+ ret = PTR_ERR(nandc->rx_chan); -+ nandc->rx_chan = NULL; -+ dev_err_probe(nandc->dev, ret, -+ "rx DMA channel request failed\n"); -+ goto unalloc; -+ } -+ -+ nandc->cmd_chan = dma_request_chan(nandc->dev, "cmd"); -+ if (IS_ERR(nandc->cmd_chan)) { -+ ret = PTR_ERR(nandc->cmd_chan); -+ nandc->cmd_chan = NULL; -+ dev_err_probe(nandc->dev, ret, -+ "cmd DMA channel request failed\n"); -+ goto unalloc; -+ } -+ -+ /* -+ * Initially allocate BAM transaction to read ONFI param page. -+ * After detecting all the devices, this BAM transaction will -+ * be freed and the next BAM transaction will be allocated with -+ * maximum codeword size -+ */ -+ nandc->max_cwperpage = 1; -+ nandc->bam_txn = qcom_alloc_bam_transaction(nandc); -+ if (!nandc->bam_txn) { -+ dev_err(nandc->dev, -+ "failed to allocate bam transaction\n"); -+ ret = -ENOMEM; -+ goto unalloc; -+ } -+ } else { -+ nandc->chan = dma_request_chan(nandc->dev, "rxtx"); -+ if (IS_ERR(nandc->chan)) { -+ ret = PTR_ERR(nandc->chan); -+ nandc->chan = NULL; -+ dev_err_probe(nandc->dev, ret, -+ "rxtx DMA channel request failed\n"); -+ return ret; -+ } -+ } -+ -+ INIT_LIST_HEAD(&nandc->desc_list); -+ INIT_LIST_HEAD(&nandc->host_list); -+ -+ return 0; -+unalloc: -+ qcom_nandc_unalloc(nandc); -+ return ret; -+} -+EXPORT_SYMBOL(qcom_nandc_alloc); -+ -+MODULE_DESCRIPTION("QPIC controller common api"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c -index ee73876f7244..f07871532ef0 100644 ---- a/drivers/mtd/nand/raw/qcom_nandc.c -+++ b/drivers/mtd/nand/raw/qcom_nandc.c -@@ -15,417 +15,7 @@ - #include - #include - #include -- --/* NANDc reg offsets */ --#define NAND_FLASH_CMD 0x00 --#define NAND_ADDR0 0x04 --#define NAND_ADDR1 0x08 --#define NAND_FLASH_CHIP_SELECT 0x0c --#define NAND_EXEC_CMD 0x10 --#define NAND_FLASH_STATUS 0x14 --#define NAND_BUFFER_STATUS 0x18 --#define NAND_DEV0_CFG0 0x20 --#define NAND_DEV0_CFG1 0x24 --#define NAND_DEV0_ECC_CFG 0x28 --#define NAND_AUTO_STATUS_EN 0x2c --#define NAND_DEV1_CFG0 0x30 --#define NAND_DEV1_CFG1 0x34 --#define NAND_READ_ID 0x40 --#define NAND_READ_STATUS 0x44 --#define NAND_DEV_CMD0 0xa0 --#define NAND_DEV_CMD1 0xa4 --#define NAND_DEV_CMD2 0xa8 --#define NAND_DEV_CMD_VLD 0xac --#define SFLASHC_BURST_CFG 0xe0 --#define NAND_ERASED_CW_DETECT_CFG 0xe8 --#define NAND_ERASED_CW_DETECT_STATUS 0xec --#define NAND_EBI2_ECC_BUF_CFG 0xf0 --#define FLASH_BUF_ACC 0x100 -- --#define NAND_CTRL 0xf00 --#define NAND_VERSION 0xf08 --#define NAND_READ_LOCATION_0 0xf20 --#define NAND_READ_LOCATION_1 0xf24 --#define NAND_READ_LOCATION_2 0xf28 --#define NAND_READ_LOCATION_3 0xf2c --#define NAND_READ_LOCATION_LAST_CW_0 0xf40 --#define NAND_READ_LOCATION_LAST_CW_1 0xf44 --#define NAND_READ_LOCATION_LAST_CW_2 0xf48 --#define NAND_READ_LOCATION_LAST_CW_3 0xf4c -- --/* dummy register offsets, used by qcom_write_reg_dma */ --#define NAND_DEV_CMD1_RESTORE 0xdead --#define NAND_DEV_CMD_VLD_RESTORE 0xbeef -- --/* NAND_FLASH_CMD bits */ --#define PAGE_ACC BIT(4) --#define LAST_PAGE BIT(5) -- --/* NAND_FLASH_CHIP_SELECT bits */ --#define NAND_DEV_SEL 0 --#define DM_EN BIT(2) -- --/* NAND_FLASH_STATUS bits */ --#define FS_OP_ERR BIT(4) --#define FS_READY_BSY_N BIT(5) --#define FS_MPU_ERR BIT(8) --#define FS_DEVICE_STS_ERR BIT(16) --#define FS_DEVICE_WP BIT(23) -- --/* NAND_BUFFER_STATUS bits */ --#define BS_UNCORRECTABLE_BIT BIT(8) --#define BS_CORRECTABLE_ERR_MSK 0x1f -- --/* NAND_DEVn_CFG0 bits */ --#define DISABLE_STATUS_AFTER_WRITE 4 --#define CW_PER_PAGE 6 --#define UD_SIZE_BYTES 9 --#define UD_SIZE_BYTES_MASK GENMASK(18, 9) --#define ECC_PARITY_SIZE_BYTES_RS 19 --#define SPARE_SIZE_BYTES 23 --#define SPARE_SIZE_BYTES_MASK GENMASK(26, 23) --#define NUM_ADDR_CYCLES 27 --#define STATUS_BFR_READ 30 --#define SET_RD_MODE_AFTER_STATUS 31 -- --/* NAND_DEVn_CFG0 bits */ --#define DEV0_CFG1_ECC_DISABLE 0 --#define WIDE_FLASH 1 --#define NAND_RECOVERY_CYCLES 2 --#define CS_ACTIVE_BSY 5 --#define BAD_BLOCK_BYTE_NUM 6 --#define BAD_BLOCK_IN_SPARE_AREA 16 --#define WR_RD_BSY_GAP 17 --#define ENABLE_BCH_ECC 27 -- --/* NAND_DEV0_ECC_CFG bits */ --#define ECC_CFG_ECC_DISABLE 0 --#define ECC_SW_RESET 1 --#define ECC_MODE 4 --#define ECC_PARITY_SIZE_BYTES_BCH 8 --#define ECC_NUM_DATA_BYTES 16 --#define ECC_NUM_DATA_BYTES_MASK GENMASK(25, 16) --#define ECC_FORCE_CLK_OPEN 30 -- --/* NAND_DEV_CMD1 bits */ --#define READ_ADDR 0 -- --/* NAND_DEV_CMD_VLD bits */ --#define READ_START_VLD BIT(0) --#define READ_STOP_VLD BIT(1) --#define WRITE_START_VLD BIT(2) --#define ERASE_START_VLD BIT(3) --#define SEQ_READ_START_VLD BIT(4) -- --/* NAND_EBI2_ECC_BUF_CFG bits */ --#define NUM_STEPS 0 -- --/* NAND_ERASED_CW_DETECT_CFG bits */ --#define ERASED_CW_ECC_MASK 1 --#define AUTO_DETECT_RES 0 --#define MASK_ECC BIT(ERASED_CW_ECC_MASK) --#define RESET_ERASED_DET BIT(AUTO_DETECT_RES) --#define ACTIVE_ERASED_DET (0 << AUTO_DETECT_RES) --#define CLR_ERASED_PAGE_DET (RESET_ERASED_DET | MASK_ECC) --#define SET_ERASED_PAGE_DET (ACTIVE_ERASED_DET | MASK_ECC) -- --/* NAND_ERASED_CW_DETECT_STATUS bits */ --#define PAGE_ALL_ERASED BIT(7) --#define CODEWORD_ALL_ERASED BIT(6) --#define PAGE_ERASED BIT(5) --#define CODEWORD_ERASED BIT(4) --#define ERASED_PAGE (PAGE_ALL_ERASED | PAGE_ERASED) --#define ERASED_CW (CODEWORD_ALL_ERASED | CODEWORD_ERASED) -- --/* NAND_READ_LOCATION_n bits */ --#define READ_LOCATION_OFFSET 0 --#define READ_LOCATION_SIZE 16 --#define READ_LOCATION_LAST 31 -- --/* Version Mask */ --#define NAND_VERSION_MAJOR_MASK 0xf0000000 --#define NAND_VERSION_MAJOR_SHIFT 28 --#define NAND_VERSION_MINOR_MASK 0x0fff0000 --#define NAND_VERSION_MINOR_SHIFT 16 -- --/* NAND OP_CMDs */ --#define OP_PAGE_READ 0x2 --#define OP_PAGE_READ_WITH_ECC 0x3 --#define OP_PAGE_READ_WITH_ECC_SPARE 0x4 --#define OP_PAGE_READ_ONFI_READ 0x5 --#define OP_PROGRAM_PAGE 0x6 --#define OP_PAGE_PROGRAM_WITH_ECC 0x7 --#define OP_PROGRAM_PAGE_SPARE 0x9 --#define OP_BLOCK_ERASE 0xa --#define OP_CHECK_STATUS 0xc --#define OP_FETCH_ID 0xb --#define OP_RESET_DEVICE 0xd -- --/* Default Value for NAND_DEV_CMD_VLD */ --#define NAND_DEV_CMD_VLD_VAL (READ_START_VLD | WRITE_START_VLD | \ -- ERASE_START_VLD | SEQ_READ_START_VLD) -- --/* NAND_CTRL bits */ --#define BAM_MODE_EN BIT(0) -- --/* -- * the NAND controller performs reads/writes with ECC in 516 byte chunks. -- * the driver calls the chunks 'step' or 'codeword' interchangeably -- */ --#define NANDC_STEP_SIZE 512 -- --/* -- * the largest page size we support is 8K, this will have 16 steps/codewords -- * of 512 bytes each -- */ --#define MAX_NUM_STEPS (SZ_8K / NANDC_STEP_SIZE) -- --/* we read at most 3 registers per codeword scan */ --#define MAX_REG_RD (3 * MAX_NUM_STEPS) -- --/* ECC modes supported by the controller */ --#define ECC_NONE BIT(0) --#define ECC_RS_4BIT BIT(1) --#define ECC_BCH_4BIT BIT(2) --#define ECC_BCH_8BIT BIT(3) -- --/* -- * Returns the actual register address for all NAND_DEV_ registers -- * (i.e. NAND_DEV_CMD0, NAND_DEV_CMD1, NAND_DEV_CMD2 and NAND_DEV_CMD_VLD) -- */ --#define dev_cmd_reg_addr(nandc, reg) ((nandc)->props->dev_cmd_reg_start + (reg)) -- --/* Returns the NAND register physical address */ --#define nandc_reg_phys(chip, offset) ((chip)->base_phys + (offset)) -- --/* Returns the dma address for reg read buffer */ --#define reg_buf_dma_addr(chip, vaddr) \ -- ((chip)->reg_read_dma + \ -- ((u8 *)(vaddr) - (u8 *)(chip)->reg_read_buf)) -- --#define QPIC_PER_CW_CMD_ELEMENTS 32 --#define QPIC_PER_CW_CMD_SGL 32 --#define QPIC_PER_CW_DATA_SGL 8 -- --#define QPIC_NAND_COMPLETION_TIMEOUT msecs_to_jiffies(2000) -- --/* -- * Flags used in DMA descriptor preparation helper functions -- * (i.e. qcom_read_reg_dma/qcom_write_reg_dma/qcom_read_data_dma/qcom_write_data_dma) -- */ --/* Don't set the EOT in current tx BAM sgl */ --#define NAND_BAM_NO_EOT BIT(0) --/* Set the NWD flag in current BAM sgl */ --#define NAND_BAM_NWD BIT(1) --/* Finish writing in the current BAM sgl and start writing in another BAM sgl */ --#define NAND_BAM_NEXT_SGL BIT(2) --/* -- * Erased codeword status is being used two times in single transfer so this -- * flag will determine the current value of erased codeword status register -- */ --#define NAND_ERASED_CW_SET BIT(4) -- --#define MAX_ADDRESS_CYCLE 5 -- --/* -- * This data type corresponds to the BAM transaction which will be used for all -- * NAND transfers. -- * @bam_ce - the array of BAM command elements -- * @cmd_sgl - sgl for NAND BAM command pipe -- * @data_sgl - sgl for NAND BAM consumer/producer pipe -- * @last_data_desc - last DMA desc in data channel (tx/rx). -- * @last_cmd_desc - last DMA desc in command channel. -- * @txn_done - completion for NAND transfer. -- * @bam_ce_pos - the index in bam_ce which is available for next sgl -- * @bam_ce_start - the index in bam_ce which marks the start position ce -- * for current sgl. It will be used for size calculation -- * for current sgl -- * @cmd_sgl_pos - current index in command sgl. -- * @cmd_sgl_start - start index in command sgl. -- * @tx_sgl_pos - current index in data sgl for tx. -- * @tx_sgl_start - start index in data sgl for tx. -- * @rx_sgl_pos - current index in data sgl for rx. -- * @rx_sgl_start - start index in data sgl for rx. -- */ --struct bam_transaction { -- struct bam_cmd_element *bam_ce; -- struct scatterlist *cmd_sgl; -- struct scatterlist *data_sgl; -- struct dma_async_tx_descriptor *last_data_desc; -- struct dma_async_tx_descriptor *last_cmd_desc; -- struct completion txn_done; -- u32 bam_ce_pos; -- u32 bam_ce_start; -- u32 cmd_sgl_pos; -- u32 cmd_sgl_start; -- u32 tx_sgl_pos; -- u32 tx_sgl_start; -- u32 rx_sgl_pos; -- u32 rx_sgl_start; --}; -- --/* -- * This data type corresponds to the nand dma descriptor -- * @dma_desc - low level DMA engine descriptor -- * @list - list for desc_info -- * -- * @adm_sgl - sgl which will be used for single sgl dma descriptor. Only used by -- * ADM -- * @bam_sgl - sgl which will be used for dma descriptor. Only used by BAM -- * @sgl_cnt - number of SGL in bam_sgl. Only used by BAM -- * @dir - DMA transfer direction -- */ --struct desc_info { -- struct dma_async_tx_descriptor *dma_desc; -- struct list_head node; -- -- union { -- struct scatterlist adm_sgl; -- struct { -- struct scatterlist *bam_sgl; -- int sgl_cnt; -- }; -- }; -- enum dma_data_direction dir; --}; -- --/* -- * holds the current register values that we want to write. acts as a contiguous -- * chunk of memory which we use to write the controller registers through DMA. -- */ --struct nandc_regs { -- __le32 cmd; -- __le32 addr0; -- __le32 addr1; -- __le32 chip_sel; -- __le32 exec; -- -- __le32 cfg0; -- __le32 cfg1; -- __le32 ecc_bch_cfg; -- -- __le32 clrflashstatus; -- __le32 clrreadstatus; -- -- __le32 cmd1; -- __le32 vld; -- -- __le32 orig_cmd1; -- __le32 orig_vld; -- -- __le32 ecc_buf_cfg; -- __le32 read_location0; -- __le32 read_location1; -- __le32 read_location2; -- __le32 read_location3; -- __le32 read_location_last0; -- __le32 read_location_last1; -- __le32 read_location_last2; -- __le32 read_location_last3; -- -- __le32 erased_cw_detect_cfg_clr; -- __le32 erased_cw_detect_cfg_set; --}; -- --/* -- * NAND controller data struct -- * -- * @dev: parent device -- * -- * @base: MMIO base -- * -- * @core_clk: controller clock -- * @aon_clk: another controller clock -- * -- * @regs: a contiguous chunk of memory for DMA register -- * writes. contains the register values to be -- * written to controller -- * -- * @props: properties of current NAND controller, -- * initialized via DT match data -- * -- * @controller: base controller structure -- * @host_list: list containing all the chips attached to the -- * controller -- * -- * @chan: dma channel -- * @cmd_crci: ADM DMA CRCI for command flow control -- * @data_crci: ADM DMA CRCI for data flow control -- * -- * @desc_list: DMA descriptor list (list of desc_infos) -- * -- * @data_buffer: our local DMA buffer for page read/writes, -- * used when we can't use the buffer provided -- * by upper layers directly -- * @reg_read_buf: local buffer for reading back registers via DMA -- * -- * @base_phys: physical base address of controller registers -- * @base_dma: dma base address of controller registers -- * @reg_read_dma: contains dma address for register read buffer -- * -- * @buf_size/count/start: markers for chip->legacy.read_buf/write_buf -- * functions -- * @max_cwperpage: maximum QPIC codewords required. calculated -- * from all connected NAND devices pagesize -- * -- * @reg_read_pos: marker for data read in reg_read_buf -- * -- * @cmd1/vld: some fixed controller register values -- * -- * @exec_opwrite: flag to select correct number of code word -- * while reading status -- */ --struct qcom_nand_controller { -- struct device *dev; -- -- void __iomem *base; -- -- struct clk *core_clk; -- struct clk *aon_clk; -- -- struct nandc_regs *regs; -- struct bam_transaction *bam_txn; -- -- const struct qcom_nandc_props *props; -- -- struct nand_controller controller; -- struct list_head host_list; -- -- union { -- /* will be used only by QPIC for BAM DMA */ -- struct { -- struct dma_chan *tx_chan; -- struct dma_chan *rx_chan; -- struct dma_chan *cmd_chan; -- }; -- -- /* will be used only by EBI2 for ADM DMA */ -- struct { -- struct dma_chan *chan; -- unsigned int cmd_crci; -- unsigned int data_crci; -- }; -- }; -- -- struct list_head desc_list; -- -- u8 *data_buffer; -- __le32 *reg_read_buf; -- -- phys_addr_t base_phys; -- dma_addr_t base_dma; -- dma_addr_t reg_read_dma; -- -- int buf_size; -- int buf_count; -- int buf_start; -- unsigned int max_cwperpage; -- -- int reg_read_pos; -- -- u32 cmd1, vld; -- bool exec_opwrite; --}; -+#include - - /* - * NAND special boot partitions -@@ -530,97 +120,6 @@ struct qcom_nand_host { - bool bch_enabled; - }; - --/* -- * This data type corresponds to the NAND controller properties which varies -- * among different NAND controllers. -- * @ecc_modes - ecc mode for NAND -- * @dev_cmd_reg_start - NAND_DEV_CMD_* registers starting offset -- * @supports_bam - whether NAND controller is using Bus Access Manager (BAM) -- * @nandc_part_of_qpic - whether NAND controller is part of qpic IP -- * @qpic_version2 - flag to indicate QPIC IP version 2 -- * @use_codeword_fixup - whether NAND has different layout for boot partitions -- */ --struct qcom_nandc_props { -- u32 ecc_modes; -- u32 dev_cmd_reg_start; -- bool supports_bam; -- bool nandc_part_of_qpic; -- bool qpic_version2; -- bool use_codeword_fixup; --}; -- --/* Frees the BAM transaction memory */ --static void qcom_free_bam_transaction(struct qcom_nand_controller *nandc) --{ -- struct bam_transaction *bam_txn = nandc->bam_txn; -- -- devm_kfree(nandc->dev, bam_txn); --} -- --/* Allocates and Initializes the BAM transaction */ --static struct bam_transaction * --qcom_alloc_bam_transaction(struct qcom_nand_controller *nandc) --{ -- struct bam_transaction *bam_txn; -- size_t bam_txn_size; -- unsigned int num_cw = nandc->max_cwperpage; -- void *bam_txn_buf; -- -- bam_txn_size = -- sizeof(*bam_txn) + num_cw * -- ((sizeof(*bam_txn->bam_ce) * QPIC_PER_CW_CMD_ELEMENTS) + -- (sizeof(*bam_txn->cmd_sgl) * QPIC_PER_CW_CMD_SGL) + -- (sizeof(*bam_txn->data_sgl) * QPIC_PER_CW_DATA_SGL)); -- -- bam_txn_buf = devm_kzalloc(nandc->dev, bam_txn_size, GFP_KERNEL); -- if (!bam_txn_buf) -- return NULL; -- -- bam_txn = bam_txn_buf; -- bam_txn_buf += sizeof(*bam_txn); -- -- bam_txn->bam_ce = bam_txn_buf; -- bam_txn_buf += -- sizeof(*bam_txn->bam_ce) * QPIC_PER_CW_CMD_ELEMENTS * num_cw; -- -- bam_txn->cmd_sgl = bam_txn_buf; -- bam_txn_buf += -- sizeof(*bam_txn->cmd_sgl) * QPIC_PER_CW_CMD_SGL * num_cw; -- -- bam_txn->data_sgl = bam_txn_buf; -- -- init_completion(&bam_txn->txn_done); -- -- return bam_txn; --} -- --/* Clears the BAM transaction indexes */ --static void qcom_clear_bam_transaction(struct qcom_nand_controller *nandc) --{ -- struct bam_transaction *bam_txn = nandc->bam_txn; -- -- if (!nandc->props->supports_bam) -- return; -- -- memset(&bam_txn->bam_ce_pos, 0, sizeof(u32) * 8); -- bam_txn->last_data_desc = NULL; -- -- sg_init_table(bam_txn->cmd_sgl, nandc->max_cwperpage * -- QPIC_PER_CW_CMD_SGL); -- sg_init_table(bam_txn->data_sgl, nandc->max_cwperpage * -- QPIC_PER_CW_DATA_SGL); -- -- reinit_completion(&bam_txn->txn_done); --} -- --/* Callback for DMA descriptor completion */ --static void qcom_qpic_bam_dma_done(void *data) --{ -- struct bam_transaction *bam_txn = data; -- -- complete(&bam_txn->txn_done); --} -- - static struct qcom_nand_host *to_qcom_nand_host(struct nand_chip *chip) - { - return container_of(chip, struct qcom_nand_host, chip); -@@ -629,8 +128,8 @@ static struct qcom_nand_host *to_qcom_nand_host(struct nand_chip *chip) - static struct qcom_nand_controller * - get_qcom_nand_controller(struct nand_chip *chip) - { -- return container_of(chip->controller, struct qcom_nand_controller, -- controller); -+ return (struct qcom_nand_controller *) -+ ((u8 *)chip->controller - sizeof(struct qcom_nand_controller)); - } - - static u32 nandc_read(struct qcom_nand_controller *nandc, int offset) -@@ -644,23 +143,6 @@ static void nandc_write(struct qcom_nand_controller *nandc, int offset, - iowrite32(val, nandc->base + offset); - } - --static void qcom_nandc_dev_to_mem(struct qcom_nand_controller *nandc, bool is_cpu) --{ -- if (!nandc->props->supports_bam) -- return; -- -- if (is_cpu) -- dma_sync_single_for_cpu(nandc->dev, nandc->reg_read_dma, -- MAX_REG_RD * -- sizeof(*nandc->reg_read_buf), -- DMA_FROM_DEVICE); -- else -- dma_sync_single_for_device(nandc->dev, nandc->reg_read_dma, -- MAX_REG_RD * -- sizeof(*nandc->reg_read_buf), -- DMA_FROM_DEVICE); --} -- - /* Helper to check whether this is the last CW or not */ - static bool qcom_nandc_is_last_cw(struct nand_ecc_ctrl *ecc, int cw) - { -@@ -819,356 +301,6 @@ static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read, i - host->cw_data : host->cw_size, 1); - } - --/* -- * Maps the scatter gather list for DMA transfer and forms the DMA descriptor -- * for BAM. This descriptor will be added in the NAND DMA descriptor queue -- * which will be submitted to DMA engine. -- */ --static int qcom_prepare_bam_async_desc(struct qcom_nand_controller *nandc, -- struct dma_chan *chan, -- unsigned long flags) --{ -- struct desc_info *desc; -- struct scatterlist *sgl; -- unsigned int sgl_cnt; -- int ret; -- struct bam_transaction *bam_txn = nandc->bam_txn; -- enum dma_transfer_direction dir_eng; -- struct dma_async_tx_descriptor *dma_desc; -- -- desc = kzalloc(sizeof(*desc), GFP_KERNEL); -- if (!desc) -- return -ENOMEM; -- -- if (chan == nandc->cmd_chan) { -- sgl = &bam_txn->cmd_sgl[bam_txn->cmd_sgl_start]; -- sgl_cnt = bam_txn->cmd_sgl_pos - bam_txn->cmd_sgl_start; -- bam_txn->cmd_sgl_start = bam_txn->cmd_sgl_pos; -- dir_eng = DMA_MEM_TO_DEV; -- desc->dir = DMA_TO_DEVICE; -- } else if (chan == nandc->tx_chan) { -- sgl = &bam_txn->data_sgl[bam_txn->tx_sgl_start]; -- sgl_cnt = bam_txn->tx_sgl_pos - bam_txn->tx_sgl_start; -- bam_txn->tx_sgl_start = bam_txn->tx_sgl_pos; -- dir_eng = DMA_MEM_TO_DEV; -- desc->dir = DMA_TO_DEVICE; -- } else { -- sgl = &bam_txn->data_sgl[bam_txn->rx_sgl_start]; -- sgl_cnt = bam_txn->rx_sgl_pos - bam_txn->rx_sgl_start; -- bam_txn->rx_sgl_start = bam_txn->rx_sgl_pos; -- dir_eng = DMA_DEV_TO_MEM; -- desc->dir = DMA_FROM_DEVICE; -- } -- -- sg_mark_end(sgl + sgl_cnt - 1); -- ret = dma_map_sg(nandc->dev, sgl, sgl_cnt, desc->dir); -- if (ret == 0) { -- dev_err(nandc->dev, "failure in mapping desc\n"); -- kfree(desc); -- return -ENOMEM; -- } -- -- desc->sgl_cnt = sgl_cnt; -- desc->bam_sgl = sgl; -- -- dma_desc = dmaengine_prep_slave_sg(chan, sgl, sgl_cnt, dir_eng, -- flags); -- -- if (!dma_desc) { -- dev_err(nandc->dev, "failure in prep desc\n"); -- dma_unmap_sg(nandc->dev, sgl, sgl_cnt, desc->dir); -- kfree(desc); -- return -EINVAL; -- } -- -- desc->dma_desc = dma_desc; -- -- /* update last data/command descriptor */ -- if (chan == nandc->cmd_chan) -- bam_txn->last_cmd_desc = dma_desc; -- else -- bam_txn->last_data_desc = dma_desc; -- -- list_add_tail(&desc->node, &nandc->desc_list); -- -- return 0; --} -- --/* -- * Prepares the command descriptor for BAM DMA which will be used for NAND -- * register reads and writes. The command descriptor requires the command -- * to be formed in command element type so this function uses the command -- * element from bam transaction ce array and fills the same with required -- * data. A single SGL can contain multiple command elements so -- * NAND_BAM_NEXT_SGL will be used for starting the separate SGL -- * after the current command element. -- */ --static int qcom_prep_bam_dma_desc_cmd(struct qcom_nand_controller *nandc, bool read, -- int reg_off, const void *vaddr, -- int size, unsigned int flags) --{ -- int bam_ce_size; -- int i, ret; -- struct bam_cmd_element *bam_ce_buffer; -- struct bam_transaction *bam_txn = nandc->bam_txn; -- -- bam_ce_buffer = &bam_txn->bam_ce[bam_txn->bam_ce_pos]; -- -- /* fill the command desc */ -- for (i = 0; i < size; i++) { -- if (read) -- bam_prep_ce(&bam_ce_buffer[i], -- nandc_reg_phys(nandc, reg_off + 4 * i), -- BAM_READ_COMMAND, -- reg_buf_dma_addr(nandc, -- (__le32 *)vaddr + i)); -- else -- bam_prep_ce_le32(&bam_ce_buffer[i], -- nandc_reg_phys(nandc, reg_off + 4 * i), -- BAM_WRITE_COMMAND, -- *((__le32 *)vaddr + i)); -- } -- -- bam_txn->bam_ce_pos += size; -- -- /* use the separate sgl after this command */ -- if (flags & NAND_BAM_NEXT_SGL) { -- bam_ce_buffer = &bam_txn->bam_ce[bam_txn->bam_ce_start]; -- bam_ce_size = (bam_txn->bam_ce_pos - -- bam_txn->bam_ce_start) * -- sizeof(struct bam_cmd_element); -- sg_set_buf(&bam_txn->cmd_sgl[bam_txn->cmd_sgl_pos], -- bam_ce_buffer, bam_ce_size); -- bam_txn->cmd_sgl_pos++; -- bam_txn->bam_ce_start = bam_txn->bam_ce_pos; -- -- if (flags & NAND_BAM_NWD) { -- ret = qcom_prepare_bam_async_desc(nandc, nandc->cmd_chan, -- DMA_PREP_FENCE | -- DMA_PREP_CMD); -- if (ret) -- return ret; -- } -- } -- -- return 0; --} -- --/* -- * Prepares the data descriptor for BAM DMA which will be used for NAND -- * data reads and writes. -- */ --static int qcom_prep_bam_dma_desc_data(struct qcom_nand_controller *nandc, bool read, -- const void *vaddr, int size, unsigned int flags) --{ -- int ret; -- struct bam_transaction *bam_txn = nandc->bam_txn; -- -- if (read) { -- sg_set_buf(&bam_txn->data_sgl[bam_txn->rx_sgl_pos], -- vaddr, size); -- bam_txn->rx_sgl_pos++; -- } else { -- sg_set_buf(&bam_txn->data_sgl[bam_txn->tx_sgl_pos], -- vaddr, size); -- bam_txn->tx_sgl_pos++; -- -- /* -- * BAM will only set EOT for DMA_PREP_INTERRUPT so if this flag -- * is not set, form the DMA descriptor -- */ -- if (!(flags & NAND_BAM_NO_EOT)) { -- ret = qcom_prepare_bam_async_desc(nandc, nandc->tx_chan, -- DMA_PREP_INTERRUPT); -- if (ret) -- return ret; -- } -- } -- -- return 0; --} -- --static int qcom_prep_adm_dma_desc(struct qcom_nand_controller *nandc, bool read, -- int reg_off, const void *vaddr, int size, -- bool flow_control) --{ -- struct desc_info *desc; -- struct dma_async_tx_descriptor *dma_desc; -- struct scatterlist *sgl; -- struct dma_slave_config slave_conf; -- struct qcom_adm_peripheral_config periph_conf = {}; -- enum dma_transfer_direction dir_eng; -- int ret; -- -- desc = kzalloc(sizeof(*desc), GFP_KERNEL); -- if (!desc) -- return -ENOMEM; -- -- sgl = &desc->adm_sgl; -- -- sg_init_one(sgl, vaddr, size); -- -- if (read) { -- dir_eng = DMA_DEV_TO_MEM; -- desc->dir = DMA_FROM_DEVICE; -- } else { -- dir_eng = DMA_MEM_TO_DEV; -- desc->dir = DMA_TO_DEVICE; -- } -- -- ret = dma_map_sg(nandc->dev, sgl, 1, desc->dir); -- if (ret == 0) { -- ret = -ENOMEM; -- goto err; -- } -- -- memset(&slave_conf, 0x00, sizeof(slave_conf)); -- -- slave_conf.device_fc = flow_control; -- if (read) { -- slave_conf.src_maxburst = 16; -- slave_conf.src_addr = nandc->base_dma + reg_off; -- if (nandc->data_crci) { -- periph_conf.crci = nandc->data_crci; -- slave_conf.peripheral_config = &periph_conf; -- slave_conf.peripheral_size = sizeof(periph_conf); -- } -- } else { -- slave_conf.dst_maxburst = 16; -- slave_conf.dst_addr = nandc->base_dma + reg_off; -- if (nandc->cmd_crci) { -- periph_conf.crci = nandc->cmd_crci; -- slave_conf.peripheral_config = &periph_conf; -- slave_conf.peripheral_size = sizeof(periph_conf); -- } -- } -- -- ret = dmaengine_slave_config(nandc->chan, &slave_conf); -- if (ret) { -- dev_err(nandc->dev, "failed to configure dma channel\n"); -- goto err; -- } -- -- dma_desc = dmaengine_prep_slave_sg(nandc->chan, sgl, 1, dir_eng, 0); -- if (!dma_desc) { -- dev_err(nandc->dev, "failed to prepare desc\n"); -- ret = -EINVAL; -- goto err; -- } -- -- desc->dma_desc = dma_desc; -- -- list_add_tail(&desc->node, &nandc->desc_list); -- -- return 0; --err: -- kfree(desc); -- -- return ret; --} -- --/* -- * qcom_read_reg_dma: prepares a descriptor to read a given number of -- * contiguous registers to the reg_read_buf pointer -- * -- * @first: offset of the first register in the contiguous block -- * @num_regs: number of registers to read -- * @flags: flags to control DMA descriptor preparation -- */ --static int qcom_read_reg_dma(struct qcom_nand_controller *nandc, int first, -- int num_regs, unsigned int flags) --{ -- bool flow_control = false; -- void *vaddr; -- -- vaddr = nandc->reg_read_buf + nandc->reg_read_pos; -- nandc->reg_read_pos += num_regs; -- -- if (first == NAND_DEV_CMD_VLD || first == NAND_DEV_CMD1) -- first = dev_cmd_reg_addr(nandc, first); -- -- if (nandc->props->supports_bam) -- return qcom_prep_bam_dma_desc_cmd(nandc, true, first, vaddr, -- num_regs, flags); -- -- if (first == NAND_READ_ID || first == NAND_FLASH_STATUS) -- flow_control = true; -- -- return qcom_prep_adm_dma_desc(nandc, true, first, vaddr, -- num_regs * sizeof(u32), flow_control); --} -- --/* -- * qcom_write_reg_dma: prepares a descriptor to write a given number of -- * contiguous registers -- * -- * @vaddr: contiguous memory from where register value will -- * be written -- * @first: offset of the first register in the contiguous block -- * @num_regs: number of registers to write -- * @flags: flags to control DMA descriptor preparation -- */ --static int qcom_write_reg_dma(struct qcom_nand_controller *nandc, __le32 *vaddr, -- int first, int num_regs, unsigned int flags) --{ -- bool flow_control = false; -- -- if (first == NAND_EXEC_CMD) -- flags |= NAND_BAM_NWD; -- -- if (first == NAND_DEV_CMD1_RESTORE || first == NAND_DEV_CMD1) -- first = dev_cmd_reg_addr(nandc, NAND_DEV_CMD1); -- -- if (first == NAND_DEV_CMD_VLD_RESTORE || first == NAND_DEV_CMD_VLD) -- first = dev_cmd_reg_addr(nandc, NAND_DEV_CMD_VLD); -- -- if (nandc->props->supports_bam) -- return qcom_prep_bam_dma_desc_cmd(nandc, false, first, vaddr, -- num_regs, flags); -- -- if (first == NAND_FLASH_CMD) -- flow_control = true; -- -- return qcom_prep_adm_dma_desc(nandc, false, first, vaddr, -- num_regs * sizeof(u32), flow_control); --} -- --/* -- * qcom_read_data_dma: prepares a DMA descriptor to transfer data from the -- * controller's internal buffer to the buffer 'vaddr' -- * -- * @reg_off: offset within the controller's data buffer -- * @vaddr: virtual address of the buffer we want to write to -- * @size: DMA transaction size in bytes -- * @flags: flags to control DMA descriptor preparation -- */ --static int qcom_read_data_dma(struct qcom_nand_controller *nandc, int reg_off, -- const u8 *vaddr, int size, unsigned int flags) --{ -- if (nandc->props->supports_bam) -- return qcom_prep_bam_dma_desc_data(nandc, true, vaddr, size, flags); -- -- return qcom_prep_adm_dma_desc(nandc, true, reg_off, vaddr, size, false); --} -- --/* -- * qcom_write_data_dma: prepares a DMA descriptor to transfer data from -- * 'vaddr' to the controller's internal buffer -- * -- * @reg_off: offset within the controller's data buffer -- * @vaddr: virtual address of the buffer we want to read from -- * @size: DMA transaction size in bytes -- * @flags: flags to control DMA descriptor preparation -- */ --static int qcom_write_data_dma(struct qcom_nand_controller *nandc, int reg_off, -- const u8 *vaddr, int size, unsigned int flags) --{ -- if (nandc->props->supports_bam) -- return qcom_prep_bam_dma_desc_data(nandc, false, vaddr, size, flags); -- -- return qcom_prep_adm_dma_desc(nandc, false, reg_off, vaddr, size, false); --} -- - /* - * Helper to prepare DMA descriptors for configuring registers - * before reading a NAND page. -@@ -1262,83 +394,6 @@ static void config_nand_cw_write(struct nand_chip *chip) - NAND_BAM_NEXT_SGL); - } - --/* helpers to submit/free our list of dma descriptors */ --static int qcom_submit_descs(struct qcom_nand_controller *nandc) --{ -- struct desc_info *desc, *n; -- dma_cookie_t cookie = 0; -- struct bam_transaction *bam_txn = nandc->bam_txn; -- int ret = 0; -- -- if (nandc->props->supports_bam) { -- if (bam_txn->rx_sgl_pos > bam_txn->rx_sgl_start) { -- ret = qcom_prepare_bam_async_desc(nandc, nandc->rx_chan, 0); -- if (ret) -- goto err_unmap_free_desc; -- } -- -- if (bam_txn->tx_sgl_pos > bam_txn->tx_sgl_start) { -- ret = qcom_prepare_bam_async_desc(nandc, nandc->tx_chan, -- DMA_PREP_INTERRUPT); -- if (ret) -- goto err_unmap_free_desc; -- } -- -- if (bam_txn->cmd_sgl_pos > bam_txn->cmd_sgl_start) { -- ret = qcom_prepare_bam_async_desc(nandc, nandc->cmd_chan, -- DMA_PREP_CMD); -- if (ret) -- goto err_unmap_free_desc; -- } -- } -- -- list_for_each_entry(desc, &nandc->desc_list, node) -- cookie = dmaengine_submit(desc->dma_desc); -- -- if (nandc->props->supports_bam) { -- bam_txn->last_cmd_desc->callback = qcom_qpic_bam_dma_done; -- bam_txn->last_cmd_desc->callback_param = bam_txn; -- -- dma_async_issue_pending(nandc->tx_chan); -- dma_async_issue_pending(nandc->rx_chan); -- dma_async_issue_pending(nandc->cmd_chan); -- -- if (!wait_for_completion_timeout(&bam_txn->txn_done, -- QPIC_NAND_COMPLETION_TIMEOUT)) -- ret = -ETIMEDOUT; -- } else { -- if (dma_sync_wait(nandc->chan, cookie) != DMA_COMPLETE) -- ret = -ETIMEDOUT; -- } -- --err_unmap_free_desc: -- /* -- * Unmap the dma sg_list and free the desc allocated by both -- * qcom_prepare_bam_async_desc() and qcom_prep_adm_dma_desc() functions. -- */ -- list_for_each_entry_safe(desc, n, &nandc->desc_list, node) { -- list_del(&desc->node); -- -- if (nandc->props->supports_bam) -- dma_unmap_sg(nandc->dev, desc->bam_sgl, -- desc->sgl_cnt, desc->dir); -- else -- dma_unmap_sg(nandc->dev, &desc->adm_sgl, 1, -- desc->dir); -- -- kfree(desc); -- } -- -- return ret; --} -- --/* reset the register read buffer for next NAND operation */ --static void qcom_clear_read_regs(struct qcom_nand_controller *nandc) --{ -- nandc->reg_read_pos = 0; -- qcom_nandc_dev_to_mem(nandc, false); --} -- - /* - * when using BCH ECC, the HW flags an error in NAND_FLASH_STATUS if it read - * an erased CW, and reports an erased CW in NAND_ERASED_CW_DETECT_STATUS. -@@ -2975,141 +2030,14 @@ static const struct nand_controller_ops qcom_nandc_ops = { - .exec_op = qcom_nand_exec_op, - }; - --static void qcom_nandc_unalloc(struct qcom_nand_controller *nandc) --{ -- if (nandc->props->supports_bam) { -- if (!dma_mapping_error(nandc->dev, nandc->reg_read_dma)) -- dma_unmap_single(nandc->dev, nandc->reg_read_dma, -- MAX_REG_RD * -- sizeof(*nandc->reg_read_buf), -- DMA_FROM_DEVICE); -- -- if (nandc->tx_chan) -- dma_release_channel(nandc->tx_chan); -- -- if (nandc->rx_chan) -- dma_release_channel(nandc->rx_chan); -- -- if (nandc->cmd_chan) -- dma_release_channel(nandc->cmd_chan); -- } else { -- if (nandc->chan) -- dma_release_channel(nandc->chan); -- } --} -- --static int qcom_nandc_alloc(struct qcom_nand_controller *nandc) --{ -- int ret; -- -- ret = dma_set_coherent_mask(nandc->dev, DMA_BIT_MASK(32)); -- if (ret) { -- dev_err(nandc->dev, "failed to set DMA mask\n"); -- return ret; -- } -- -- /* -- * we use the internal buffer for reading ONFI params, reading small -- * data like ID and status, and preforming read-copy-write operations -- * when writing to a codeword partially. 532 is the maximum possible -- * size of a codeword for our nand controller -- */ -- nandc->buf_size = 532; -- -- nandc->data_buffer = devm_kzalloc(nandc->dev, nandc->buf_size, GFP_KERNEL); -- if (!nandc->data_buffer) -- return -ENOMEM; -- -- nandc->regs = devm_kzalloc(nandc->dev, sizeof(*nandc->regs), GFP_KERNEL); -- if (!nandc->regs) -- return -ENOMEM; -- -- nandc->reg_read_buf = devm_kcalloc(nandc->dev, MAX_REG_RD, -- sizeof(*nandc->reg_read_buf), -- GFP_KERNEL); -- if (!nandc->reg_read_buf) -- return -ENOMEM; -- -- if (nandc->props->supports_bam) { -- nandc->reg_read_dma = -- dma_map_single(nandc->dev, nandc->reg_read_buf, -- MAX_REG_RD * -- sizeof(*nandc->reg_read_buf), -- DMA_FROM_DEVICE); -- if (dma_mapping_error(nandc->dev, nandc->reg_read_dma)) { -- dev_err(nandc->dev, "failed to DMA MAP reg buffer\n"); -- return -EIO; -- } -- -- nandc->tx_chan = dma_request_chan(nandc->dev, "tx"); -- if (IS_ERR(nandc->tx_chan)) { -- ret = PTR_ERR(nandc->tx_chan); -- nandc->tx_chan = NULL; -- dev_err_probe(nandc->dev, ret, -- "tx DMA channel request failed\n"); -- goto unalloc; -- } -- -- nandc->rx_chan = dma_request_chan(nandc->dev, "rx"); -- if (IS_ERR(nandc->rx_chan)) { -- ret = PTR_ERR(nandc->rx_chan); -- nandc->rx_chan = NULL; -- dev_err_probe(nandc->dev, ret, -- "rx DMA channel request failed\n"); -- goto unalloc; -- } -- -- nandc->cmd_chan = dma_request_chan(nandc->dev, "cmd"); -- if (IS_ERR(nandc->cmd_chan)) { -- ret = PTR_ERR(nandc->cmd_chan); -- nandc->cmd_chan = NULL; -- dev_err_probe(nandc->dev, ret, -- "cmd DMA channel request failed\n"); -- goto unalloc; -- } -- -- /* -- * Initially allocate BAM transaction to read ONFI param page. -- * After detecting all the devices, this BAM transaction will -- * be freed and the next BAM transaction will be allocated with -- * maximum codeword size -- */ -- nandc->max_cwperpage = 1; -- nandc->bam_txn = qcom_alloc_bam_transaction(nandc); -- if (!nandc->bam_txn) { -- dev_err(nandc->dev, -- "failed to allocate bam transaction\n"); -- ret = -ENOMEM; -- goto unalloc; -- } -- } else { -- nandc->chan = dma_request_chan(nandc->dev, "rxtx"); -- if (IS_ERR(nandc->chan)) { -- ret = PTR_ERR(nandc->chan); -- nandc->chan = NULL; -- dev_err_probe(nandc->dev, ret, -- "rxtx DMA channel request failed\n"); -- return ret; -- } -- } -- -- INIT_LIST_HEAD(&nandc->desc_list); -- INIT_LIST_HEAD(&nandc->host_list); -- -- nand_controller_init(&nandc->controller); -- nandc->controller.ops = &qcom_nandc_ops; -- -- return 0; --unalloc: -- qcom_nandc_unalloc(nandc); -- return ret; --} -- - /* one time setup of a few nand controller registers */ - static int qcom_nandc_setup(struct qcom_nand_controller *nandc) - { - u32 nand_ctrl; - -+ nand_controller_init(nandc->controller); -+ nandc->controller->ops = &qcom_nandc_ops; -+ - /* kill onenand */ - if (!nandc->props->nandc_part_of_qpic) - nandc_write(nandc, SFLASHC_BURST_CFG, 0); -@@ -3248,7 +2176,7 @@ static int qcom_nand_host_init_and_register(struct qcom_nand_controller *nandc, - chip->legacy.block_bad = qcom_nandc_block_bad; - chip->legacy.block_markbad = qcom_nandc_block_markbad; - -- chip->controller = &nandc->controller; -+ chip->controller = nandc->controller; - chip->options |= NAND_NO_SUBPAGE_WRITE | NAND_USES_DMA | - NAND_SKIP_BBTSCAN; - -@@ -3331,17 +2259,21 @@ static int qcom_nandc_parse_dt(struct platform_device *pdev) - static int qcom_nandc_probe(struct platform_device *pdev) - { - struct qcom_nand_controller *nandc; -+ struct nand_controller *controller; - const void *dev_data; - struct device *dev = &pdev->dev; - struct resource *res; - int ret; - -- nandc = devm_kzalloc(&pdev->dev, sizeof(*nandc), GFP_KERNEL); -+ nandc = devm_kzalloc(&pdev->dev, sizeof(*nandc) + sizeof(*controller), -+ GFP_KERNEL); - if (!nandc) - return -ENOMEM; -+ controller = (struct nand_controller *)&nandc[1]; - - platform_set_drvdata(pdev, nandc); - nandc->dev = dev; -+ nandc->controller = controller; - - dev_data = of_device_get_match_data(dev); - if (!dev_data) { -diff --git a/include/linux/mtd/nand-qpic-common.h b/include/linux/mtd/nand-qpic-common.h -new file mode 100644 -index 000000000000..425994429387 ---- /dev/null -+++ b/include/linux/mtd/nand-qpic-common.h -@@ -0,0 +1,468 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * QCOM QPIC common APIs header file -+ * -+ * Copyright (c) 2023 Qualcomm Inc. -+ * Authors: Md sadre Alam -+ * -+ */ -+#ifndef __MTD_NAND_QPIC_COMMON_H__ -+#define __MTD_NAND_QPIC_COMMON_H__ -+ -+/* NANDc reg offsets */ -+#define NAND_FLASH_CMD 0x00 -+#define NAND_ADDR0 0x04 -+#define NAND_ADDR1 0x08 -+#define NAND_FLASH_CHIP_SELECT 0x0c -+#define NAND_EXEC_CMD 0x10 -+#define NAND_FLASH_STATUS 0x14 -+#define NAND_BUFFER_STATUS 0x18 -+#define NAND_DEV0_CFG0 0x20 -+#define NAND_DEV0_CFG1 0x24 -+#define NAND_DEV0_ECC_CFG 0x28 -+#define NAND_AUTO_STATUS_EN 0x2c -+#define NAND_DEV1_CFG0 0x30 -+#define NAND_DEV1_CFG1 0x34 -+#define NAND_READ_ID 0x40 -+#define NAND_READ_STATUS 0x44 -+#define NAND_DEV_CMD0 0xa0 -+#define NAND_DEV_CMD1 0xa4 -+#define NAND_DEV_CMD2 0xa8 -+#define NAND_DEV_CMD_VLD 0xac -+#define SFLASHC_BURST_CFG 0xe0 -+#define NAND_ERASED_CW_DETECT_CFG 0xe8 -+#define NAND_ERASED_CW_DETECT_STATUS 0xec -+#define NAND_EBI2_ECC_BUF_CFG 0xf0 -+#define FLASH_BUF_ACC 0x100 -+ -+#define NAND_CTRL 0xf00 -+#define NAND_VERSION 0xf08 -+#define NAND_READ_LOCATION_0 0xf20 -+#define NAND_READ_LOCATION_1 0xf24 -+#define NAND_READ_LOCATION_2 0xf28 -+#define NAND_READ_LOCATION_3 0xf2c -+#define NAND_READ_LOCATION_LAST_CW_0 0xf40 -+#define NAND_READ_LOCATION_LAST_CW_1 0xf44 -+#define NAND_READ_LOCATION_LAST_CW_2 0xf48 -+#define NAND_READ_LOCATION_LAST_CW_3 0xf4c -+ -+/* dummy register offsets, used by qcom_write_reg_dma */ -+#define NAND_DEV_CMD1_RESTORE 0xdead -+#define NAND_DEV_CMD_VLD_RESTORE 0xbeef -+ -+/* NAND_FLASH_CMD bits */ -+#define PAGE_ACC BIT(4) -+#define LAST_PAGE BIT(5) -+ -+/* NAND_FLASH_CHIP_SELECT bits */ -+#define NAND_DEV_SEL 0 -+#define DM_EN BIT(2) -+ -+/* NAND_FLASH_STATUS bits */ -+#define FS_OP_ERR BIT(4) -+#define FS_READY_BSY_N BIT(5) -+#define FS_MPU_ERR BIT(8) -+#define FS_DEVICE_STS_ERR BIT(16) -+#define FS_DEVICE_WP BIT(23) -+ -+/* NAND_BUFFER_STATUS bits */ -+#define BS_UNCORRECTABLE_BIT BIT(8) -+#define BS_CORRECTABLE_ERR_MSK 0x1f -+ -+/* NAND_DEVn_CFG0 bits */ -+#define DISABLE_STATUS_AFTER_WRITE 4 -+#define CW_PER_PAGE 6 -+#define UD_SIZE_BYTES 9 -+#define UD_SIZE_BYTES_MASK GENMASK(18, 9) -+#define ECC_PARITY_SIZE_BYTES_RS 19 -+#define SPARE_SIZE_BYTES 23 -+#define SPARE_SIZE_BYTES_MASK GENMASK(26, 23) -+#define NUM_ADDR_CYCLES 27 -+#define STATUS_BFR_READ 30 -+#define SET_RD_MODE_AFTER_STATUS 31 -+ -+/* NAND_DEVn_CFG0 bits */ -+#define DEV0_CFG1_ECC_DISABLE 0 -+#define WIDE_FLASH 1 -+#define NAND_RECOVERY_CYCLES 2 -+#define CS_ACTIVE_BSY 5 -+#define BAD_BLOCK_BYTE_NUM 6 -+#define BAD_BLOCK_IN_SPARE_AREA 16 -+#define WR_RD_BSY_GAP 17 -+#define ENABLE_BCH_ECC 27 -+ -+/* NAND_DEV0_ECC_CFG bits */ -+#define ECC_CFG_ECC_DISABLE 0 -+#define ECC_SW_RESET 1 -+#define ECC_MODE 4 -+#define ECC_PARITY_SIZE_BYTES_BCH 8 -+#define ECC_NUM_DATA_BYTES 16 -+#define ECC_NUM_DATA_BYTES_MASK GENMASK(25, 16) -+#define ECC_FORCE_CLK_OPEN 30 -+ -+/* NAND_DEV_CMD1 bits */ -+#define READ_ADDR 0 -+ -+/* NAND_DEV_CMD_VLD bits */ -+#define READ_START_VLD BIT(0) -+#define READ_STOP_VLD BIT(1) -+#define WRITE_START_VLD BIT(2) -+#define ERASE_START_VLD BIT(3) -+#define SEQ_READ_START_VLD BIT(4) -+ -+/* NAND_EBI2_ECC_BUF_CFG bits */ -+#define NUM_STEPS 0 -+ -+/* NAND_ERASED_CW_DETECT_CFG bits */ -+#define ERASED_CW_ECC_MASK 1 -+#define AUTO_DETECT_RES 0 -+#define MASK_ECC BIT(ERASED_CW_ECC_MASK) -+#define RESET_ERASED_DET BIT(AUTO_DETECT_RES) -+#define ACTIVE_ERASED_DET (0 << AUTO_DETECT_RES) -+#define CLR_ERASED_PAGE_DET (RESET_ERASED_DET | MASK_ECC) -+#define SET_ERASED_PAGE_DET (ACTIVE_ERASED_DET | MASK_ECC) -+ -+/* NAND_ERASED_CW_DETECT_STATUS bits */ -+#define PAGE_ALL_ERASED BIT(7) -+#define CODEWORD_ALL_ERASED BIT(6) -+#define PAGE_ERASED BIT(5) -+#define CODEWORD_ERASED BIT(4) -+#define ERASED_PAGE (PAGE_ALL_ERASED | PAGE_ERASED) -+#define ERASED_CW (CODEWORD_ALL_ERASED | CODEWORD_ERASED) -+ -+/* NAND_READ_LOCATION_n bits */ -+#define READ_LOCATION_OFFSET 0 -+#define READ_LOCATION_SIZE 16 -+#define READ_LOCATION_LAST 31 -+ -+/* Version Mask */ -+#define NAND_VERSION_MAJOR_MASK 0xf0000000 -+#define NAND_VERSION_MAJOR_SHIFT 28 -+#define NAND_VERSION_MINOR_MASK 0x0fff0000 -+#define NAND_VERSION_MINOR_SHIFT 16 -+ -+/* NAND OP_CMDs */ -+#define OP_PAGE_READ 0x2 -+#define OP_PAGE_READ_WITH_ECC 0x3 -+#define OP_PAGE_READ_WITH_ECC_SPARE 0x4 -+#define OP_PAGE_READ_ONFI_READ 0x5 -+#define OP_PROGRAM_PAGE 0x6 -+#define OP_PAGE_PROGRAM_WITH_ECC 0x7 -+#define OP_PROGRAM_PAGE_SPARE 0x9 -+#define OP_BLOCK_ERASE 0xa -+#define OP_CHECK_STATUS 0xc -+#define OP_FETCH_ID 0xb -+#define OP_RESET_DEVICE 0xd -+ -+/* Default Value for NAND_DEV_CMD_VLD */ -+#define NAND_DEV_CMD_VLD_VAL (READ_START_VLD | WRITE_START_VLD | \ -+ ERASE_START_VLD | SEQ_READ_START_VLD) -+ -+/* NAND_CTRL bits */ -+#define BAM_MODE_EN BIT(0) -+ -+/* -+ * the NAND controller performs reads/writes with ECC in 516 byte chunks. -+ * the driver calls the chunks 'step' or 'codeword' interchangeably -+ */ -+#define NANDC_STEP_SIZE 512 -+ -+/* -+ * the largest page size we support is 8K, this will have 16 steps/codewords -+ * of 512 bytes each -+ */ -+#define MAX_NUM_STEPS (SZ_8K / NANDC_STEP_SIZE) -+ -+/* we read at most 3 registers per codeword scan */ -+#define MAX_REG_RD (3 * MAX_NUM_STEPS) -+ -+/* ECC modes supported by the controller */ -+#define ECC_NONE BIT(0) -+#define ECC_RS_4BIT BIT(1) -+#define ECC_BCH_4BIT BIT(2) -+#define ECC_BCH_8BIT BIT(3) -+ -+/* -+ * Returns the actual register address for all NAND_DEV_ registers -+ * (i.e. NAND_DEV_CMD0, NAND_DEV_CMD1, NAND_DEV_CMD2 and NAND_DEV_CMD_VLD) -+ */ -+#define dev_cmd_reg_addr(nandc, reg) ((nandc)->props->dev_cmd_reg_start + (reg)) -+ -+/* Returns the NAND register physical address */ -+#define nandc_reg_phys(chip, offset) ((chip)->base_phys + (offset)) -+ -+/* Returns the dma address for reg read buffer */ -+#define reg_buf_dma_addr(chip, vaddr) \ -+ ((chip)->reg_read_dma + \ -+ ((u8 *)(vaddr) - (u8 *)(chip)->reg_read_buf)) -+ -+#define QPIC_PER_CW_CMD_ELEMENTS 32 -+#define QPIC_PER_CW_CMD_SGL 32 -+#define QPIC_PER_CW_DATA_SGL 8 -+ -+#define QPIC_NAND_COMPLETION_TIMEOUT msecs_to_jiffies(2000) -+ -+/* -+ * Flags used in DMA descriptor preparation helper functions -+ * (i.e. qcom_read_reg_dma/qcom_write_reg_dma/qcom_read_data_dma/qcom_write_data_dma) -+ */ -+/* Don't set the EOT in current tx BAM sgl */ -+#define NAND_BAM_NO_EOT BIT(0) -+/* Set the NWD flag in current BAM sgl */ -+#define NAND_BAM_NWD BIT(1) -+/* Finish writing in the current BAM sgl and start writing in another BAM sgl */ -+#define NAND_BAM_NEXT_SGL BIT(2) -+/* -+ * Erased codeword status is being used two times in single transfer so this -+ * flag will determine the current value of erased codeword status register -+ */ -+#define NAND_ERASED_CW_SET BIT(4) -+ -+#define MAX_ADDRESS_CYCLE 5 -+ -+/* -+ * This data type corresponds to the BAM transaction which will be used for all -+ * NAND transfers. -+ * @bam_ce - the array of BAM command elements -+ * @cmd_sgl - sgl for NAND BAM command pipe -+ * @data_sgl - sgl for NAND BAM consumer/producer pipe -+ * @last_data_desc - last DMA desc in data channel (tx/rx). -+ * @last_cmd_desc - last DMA desc in command channel. -+ * @txn_done - completion for NAND transfer. -+ * @bam_ce_pos - the index in bam_ce which is available for next sgl -+ * @bam_ce_start - the index in bam_ce which marks the start position ce -+ * for current sgl. It will be used for size calculation -+ * for current sgl -+ * @cmd_sgl_pos - current index in command sgl. -+ * @cmd_sgl_start - start index in command sgl. -+ * @tx_sgl_pos - current index in data sgl for tx. -+ * @tx_sgl_start - start index in data sgl for tx. -+ * @rx_sgl_pos - current index in data sgl for rx. -+ * @rx_sgl_start - start index in data sgl for rx. -+ */ -+struct bam_transaction { -+ struct bam_cmd_element *bam_ce; -+ struct scatterlist *cmd_sgl; -+ struct scatterlist *data_sgl; -+ struct dma_async_tx_descriptor *last_data_desc; -+ struct dma_async_tx_descriptor *last_cmd_desc; -+ struct completion txn_done; -+ u32 bam_ce_pos; -+ u32 bam_ce_start; -+ u32 cmd_sgl_pos; -+ u32 cmd_sgl_start; -+ u32 tx_sgl_pos; -+ u32 tx_sgl_start; -+ u32 rx_sgl_pos; -+ u32 rx_sgl_start; -+}; -+ -+/* -+ * This data type corresponds to the nand dma descriptor -+ * @dma_desc - low level DMA engine descriptor -+ * @list - list for desc_info -+ * -+ * @adm_sgl - sgl which will be used for single sgl dma descriptor. Only used by -+ * ADM -+ * @bam_sgl - sgl which will be used for dma descriptor. Only used by BAM -+ * @sgl_cnt - number of SGL in bam_sgl. Only used by BAM -+ * @dir - DMA transfer direction -+ */ -+struct desc_info { -+ struct dma_async_tx_descriptor *dma_desc; -+ struct list_head node; -+ -+ union { -+ struct scatterlist adm_sgl; -+ struct { -+ struct scatterlist *bam_sgl; -+ int sgl_cnt; -+ }; -+ }; -+ enum dma_data_direction dir; -+}; -+ -+/* -+ * holds the current register values that we want to write. acts as a contiguous -+ * chunk of memory which we use to write the controller registers through DMA. -+ */ -+struct nandc_regs { -+ __le32 cmd; -+ __le32 addr0; -+ __le32 addr1; -+ __le32 chip_sel; -+ __le32 exec; -+ -+ __le32 cfg0; -+ __le32 cfg1; -+ __le32 ecc_bch_cfg; -+ -+ __le32 clrflashstatus; -+ __le32 clrreadstatus; -+ -+ __le32 cmd1; -+ __le32 vld; -+ -+ __le32 orig_cmd1; -+ __le32 orig_vld; -+ -+ __le32 ecc_buf_cfg; -+ __le32 read_location0; -+ __le32 read_location1; -+ __le32 read_location2; -+ __le32 read_location3; -+ __le32 read_location_last0; -+ __le32 read_location_last1; -+ __le32 read_location_last2; -+ __le32 read_location_last3; -+ -+ __le32 erased_cw_detect_cfg_clr; -+ __le32 erased_cw_detect_cfg_set; -+}; -+ -+/* -+ * NAND controller data struct -+ * -+ * @dev: parent device -+ * -+ * @base: MMIO base -+ * -+ * @core_clk: controller clock -+ * @aon_clk: another controller clock -+ * -+ * @regs: a contiguous chunk of memory for DMA register -+ * writes. contains the register values to be -+ * written to controller -+ * -+ * @props: properties of current NAND controller, -+ * initialized via DT match data -+ * -+ * @controller: base controller structure -+ * @host_list: list containing all the chips attached to the -+ * controller -+ * -+ * @chan: dma channel -+ * @cmd_crci: ADM DMA CRCI for command flow control -+ * @data_crci: ADM DMA CRCI for data flow control -+ * -+ * @desc_list: DMA descriptor list (list of desc_infos) -+ * -+ * @data_buffer: our local DMA buffer for page read/writes, -+ * used when we can't use the buffer provided -+ * by upper layers directly -+ * @reg_read_buf: local buffer for reading back registers via DMA -+ * -+ * @base_phys: physical base address of controller registers -+ * @base_dma: dma base address of controller registers -+ * @reg_read_dma: contains dma address for register read buffer -+ * -+ * @buf_size/count/start: markers for chip->legacy.read_buf/write_buf -+ * functions -+ * @max_cwperpage: maximum QPIC codewords required. calculated -+ * from all connected NAND devices pagesize -+ * -+ * @reg_read_pos: marker for data read in reg_read_buf -+ * -+ * @cmd1/vld: some fixed controller register values -+ * -+ * @exec_opwrite: flag to select correct number of code word -+ * while reading status -+ */ -+struct qcom_nand_controller { -+ struct device *dev; -+ -+ void __iomem *base; -+ -+ struct clk *core_clk; -+ struct clk *aon_clk; -+ -+ struct nandc_regs *regs; -+ struct bam_transaction *bam_txn; -+ -+ const struct qcom_nandc_props *props; -+ -+ struct nand_controller *controller; -+ struct list_head host_list; -+ -+ union { -+ /* will be used only by QPIC for BAM DMA */ -+ struct { -+ struct dma_chan *tx_chan; -+ struct dma_chan *rx_chan; -+ struct dma_chan *cmd_chan; -+ }; -+ -+ /* will be used only by EBI2 for ADM DMA */ -+ struct { -+ struct dma_chan *chan; -+ unsigned int cmd_crci; -+ unsigned int data_crci; -+ }; -+ }; -+ -+ struct list_head desc_list; -+ -+ u8 *data_buffer; -+ __le32 *reg_read_buf; -+ -+ phys_addr_t base_phys; -+ dma_addr_t base_dma; -+ dma_addr_t reg_read_dma; -+ -+ int buf_size; -+ int buf_count; -+ int buf_start; -+ unsigned int max_cwperpage; -+ -+ int reg_read_pos; -+ -+ u32 cmd1, vld; -+ bool exec_opwrite; -+}; -+ -+/* -+ * This data type corresponds to the NAND controller properties which varies -+ * among different NAND controllers. -+ * @ecc_modes - ecc mode for NAND -+ * @dev_cmd_reg_start - NAND_DEV_CMD_* registers starting offset -+ * @supports_bam - whether NAND controller is using BAM -+ * @nandc_part_of_qpic - whether NAND controller is part of qpic IP -+ * @qpic_version2 - flag to indicate QPIC IP version 2 -+ * @use_codeword_fixup - whether NAND has different layout for boot partitions -+ */ -+struct qcom_nandc_props { -+ u32 ecc_modes; -+ u32 dev_cmd_reg_start; -+ bool supports_bam; -+ bool nandc_part_of_qpic; -+ bool qpic_version2; -+ bool use_codeword_fixup; -+}; -+ -+void qcom_free_bam_transaction(struct qcom_nand_controller *nandc); -+struct bam_transaction *qcom_alloc_bam_transaction(struct qcom_nand_controller *nandc); -+void qcom_clear_bam_transaction(struct qcom_nand_controller *nandc); -+void qcom_qpic_bam_dma_done(void *data); -+void qcom_nandc_dev_to_mem(struct qcom_nand_controller *nandc, bool is_cpu); -+int qcom_prepare_bam_async_desc(struct qcom_nand_controller *nandc, -+ struct dma_chan *chan, unsigned long flags); -+int qcom_prep_bam_dma_desc_cmd(struct qcom_nand_controller *nandc, bool read, -+ int reg_off, const void *vaddr, int size, unsigned int flags); -+int qcom_prep_bam_dma_desc_data(struct qcom_nand_controller *nandc, bool read, -+ const void *vaddr, int size, unsigned int flags); -+int qcom_prep_adm_dma_desc(struct qcom_nand_controller *nandc, bool read, int reg_off, -+ const void *vaddr, int size, bool flow_control); -+int qcom_read_reg_dma(struct qcom_nand_controller *nandc, int first, int num_regs, -+ unsigned int flags); -+int qcom_write_reg_dma(struct qcom_nand_controller *nandc, __le32 *vaddr, int first, -+ int num_regs, unsigned int flags); -+int qcom_read_data_dma(struct qcom_nand_controller *nandc, int reg_off, const u8 *vaddr, -+ int size, unsigned int flags); -+int qcom_write_data_dma(struct qcom_nand_controller *nandc, int reg_off, const u8 *vaddr, -+ int size, unsigned int flags); -+int qcom_submit_descs(struct qcom_nand_controller *nandc); -+void qcom_clear_read_regs(struct qcom_nand_controller *nandc); -+void qcom_nandc_unalloc(struct qcom_nand_controller *nandc); -+int qcom_nandc_alloc(struct qcom_nand_controller *nandc); -+#endif -+ --- -2.51.0 - - -From 70800832162a019d19111fdac370e50ae4afad08 Mon Sep 17 00:00:00 2001 -From: Md Sadre Alam -Date: Wed, 20 Nov 2024 14:45:03 +0530 -Subject: [PATCH 013/517] mtd: rawnand: qcom: use FIELD_PREP and GENMASK - -Use the bitfield macro FIELD_PREP, and GENMASK to -do the shift and mask in one go. This makes the code -more readable. - -Reviewed-by: Konrad Dybcio -Signed-off-by: Md Sadre Alam -Signed-off-by: Miquel Raynal ---- - drivers/mtd/nand/raw/qcom_nandc.c | 97 ++++++++++++++-------------- - include/linux/mtd/nand-qpic-common.h | 31 +++++---- - 2 files changed, 67 insertions(+), 61 deletions(-) - -diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c -index f07871532ef0..086cb139adf1 100644 ---- a/drivers/mtd/nand/raw/qcom_nandc.c -+++ b/drivers/mtd/nand/raw/qcom_nandc.c -@@ -281,7 +281,7 @@ static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read, i - (num_cw - 1) << CW_PER_PAGE); - - cfg1 = cpu_to_le32(host->cfg1_raw); -- ecc_bch_cfg = cpu_to_le32(1 << ECC_CFG_ECC_DISABLE); -+ ecc_bch_cfg = cpu_to_le32(ECC_CFG_ECC_DISABLE); - } - - nandc->regs->cmd = cmd; -@@ -1494,42 +1494,41 @@ static int qcom_nand_attach_chip(struct nand_chip *chip) - host->cw_size = host->cw_data + ecc->bytes; - bad_block_byte = mtd->writesize - host->cw_size * (cwperpage - 1) + 1; - -- host->cfg0 = (cwperpage - 1) << CW_PER_PAGE -- | host->cw_data << UD_SIZE_BYTES -- | 0 << DISABLE_STATUS_AFTER_WRITE -- | 5 << NUM_ADDR_CYCLES -- | host->ecc_bytes_hw << ECC_PARITY_SIZE_BYTES_RS -- | 0 << STATUS_BFR_READ -- | 1 << SET_RD_MODE_AFTER_STATUS -- | host->spare_bytes << SPARE_SIZE_BYTES; -- -- host->cfg1 = 7 << NAND_RECOVERY_CYCLES -- | 0 << CS_ACTIVE_BSY -- | bad_block_byte << BAD_BLOCK_BYTE_NUM -- | 0 << BAD_BLOCK_IN_SPARE_AREA -- | 2 << WR_RD_BSY_GAP -- | wide_bus << WIDE_FLASH -- | host->bch_enabled << ENABLE_BCH_ECC; -- -- host->cfg0_raw = (cwperpage - 1) << CW_PER_PAGE -- | host->cw_size << UD_SIZE_BYTES -- | 5 << NUM_ADDR_CYCLES -- | 0 << SPARE_SIZE_BYTES; -- -- host->cfg1_raw = 7 << NAND_RECOVERY_CYCLES -- | 0 << CS_ACTIVE_BSY -- | 17 << BAD_BLOCK_BYTE_NUM -- | 1 << BAD_BLOCK_IN_SPARE_AREA -- | 2 << WR_RD_BSY_GAP -- | wide_bus << WIDE_FLASH -- | 1 << DEV0_CFG1_ECC_DISABLE; -- -- host->ecc_bch_cfg = !host->bch_enabled << ECC_CFG_ECC_DISABLE -- | 0 << ECC_SW_RESET -- | host->cw_data << ECC_NUM_DATA_BYTES -- | 1 << ECC_FORCE_CLK_OPEN -- | ecc_mode << ECC_MODE -- | host->ecc_bytes_hw << ECC_PARITY_SIZE_BYTES_BCH; -+ host->cfg0 = FIELD_PREP(CW_PER_PAGE_MASK, (cwperpage - 1)) | -+ FIELD_PREP(UD_SIZE_BYTES_MASK, host->cw_data) | -+ FIELD_PREP(DISABLE_STATUS_AFTER_WRITE, 0) | -+ FIELD_PREP(NUM_ADDR_CYCLES_MASK, 5) | -+ FIELD_PREP(ECC_PARITY_SIZE_BYTES_RS, host->ecc_bytes_hw) | -+ FIELD_PREP(STATUS_BFR_READ, 0) | -+ FIELD_PREP(SET_RD_MODE_AFTER_STATUS, 1) | -+ FIELD_PREP(SPARE_SIZE_BYTES_MASK, host->spare_bytes); -+ -+ host->cfg1 = FIELD_PREP(NAND_RECOVERY_CYCLES_MASK, 7) | -+ FIELD_PREP(BAD_BLOCK_BYTE_NUM_MASK, bad_block_byte) | -+ FIELD_PREP(BAD_BLOCK_IN_SPARE_AREA, 0) | -+ FIELD_PREP(WR_RD_BSY_GAP_MASK, 2) | -+ FIELD_PREP(WIDE_FLASH, wide_bus) | -+ FIELD_PREP(ENABLE_BCH_ECC, host->bch_enabled); -+ -+ host->cfg0_raw = FIELD_PREP(CW_PER_PAGE_MASK, (cwperpage - 1)) | -+ FIELD_PREP(UD_SIZE_BYTES_MASK, host->cw_size) | -+ FIELD_PREP(NUM_ADDR_CYCLES_MASK, 5) | -+ FIELD_PREP(SPARE_SIZE_BYTES_MASK, 0); -+ -+ host->cfg1_raw = FIELD_PREP(NAND_RECOVERY_CYCLES_MASK, 7) | -+ FIELD_PREP(CS_ACTIVE_BSY, 0) | -+ FIELD_PREP(BAD_BLOCK_BYTE_NUM_MASK, 17) | -+ FIELD_PREP(BAD_BLOCK_IN_SPARE_AREA, 1) | -+ FIELD_PREP(WR_RD_BSY_GAP_MASK, 2) | -+ FIELD_PREP(WIDE_FLASH, wide_bus) | -+ FIELD_PREP(DEV0_CFG1_ECC_DISABLE, 1); -+ -+ host->ecc_bch_cfg = FIELD_PREP(ECC_CFG_ECC_DISABLE, !host->bch_enabled) | -+ FIELD_PREP(ECC_SW_RESET, 0) | -+ FIELD_PREP(ECC_NUM_DATA_BYTES_MASK, host->cw_data) | -+ FIELD_PREP(ECC_FORCE_CLK_OPEN, 1) | -+ FIELD_PREP(ECC_MODE_MASK, ecc_mode) | -+ FIELD_PREP(ECC_PARITY_SIZE_BYTES_BCH_MASK, host->ecc_bytes_hw); - - if (!nandc->props->qpic_version2) - host->ecc_buf_cfg = 0x203 << NUM_STEPS; -@@ -1887,21 +1886,21 @@ static int qcom_param_page_type_exec(struct nand_chip *chip, const struct nand_ - nandc->regs->addr0 = 0; - nandc->regs->addr1 = 0; - -- nandc->regs->cfg0 = cpu_to_le32(0 << CW_PER_PAGE | -- 512 << UD_SIZE_BYTES | -- 5 << NUM_ADDR_CYCLES | -- 0 << SPARE_SIZE_BYTES); -+ host->cfg0 = FIELD_PREP(CW_PER_PAGE_MASK, 0) | -+ FIELD_PREP(UD_SIZE_BYTES_MASK, 512) | -+ FIELD_PREP(NUM_ADDR_CYCLES_MASK, 5) | -+ FIELD_PREP(SPARE_SIZE_BYTES_MASK, 0); - -- nandc->regs->cfg1 = cpu_to_le32(7 << NAND_RECOVERY_CYCLES | -- 0 << CS_ACTIVE_BSY | -- 17 << BAD_BLOCK_BYTE_NUM | -- 1 << BAD_BLOCK_IN_SPARE_AREA | -- 2 << WR_RD_BSY_GAP | -- 0 << WIDE_FLASH | -- 1 << DEV0_CFG1_ECC_DISABLE); -+ host->cfg1 = FIELD_PREP(NAND_RECOVERY_CYCLES_MASK, 7) | -+ FIELD_PREP(BAD_BLOCK_BYTE_NUM_MASK, 17) | -+ FIELD_PREP(CS_ACTIVE_BSY, 0) | -+ FIELD_PREP(BAD_BLOCK_IN_SPARE_AREA, 1) | -+ FIELD_PREP(WR_RD_BSY_GAP_MASK, 2) | -+ FIELD_PREP(WIDE_FLASH, 0) | -+ FIELD_PREP(DEV0_CFG1_ECC_DISABLE, 1); - - if (!nandc->props->qpic_version2) -- nandc->regs->ecc_buf_cfg = cpu_to_le32(1 << ECC_CFG_ECC_DISABLE); -+ nandc->regs->ecc_buf_cfg = cpu_to_le32(ECC_CFG_ECC_DISABLE); - - /* configure CMD1 and VLD for ONFI param probing in QPIC v1 */ - if (!nandc->props->qpic_version2) { -diff --git a/include/linux/mtd/nand-qpic-common.h b/include/linux/mtd/nand-qpic-common.h -index 425994429387..e79c79775eb8 100644 ---- a/include/linux/mtd/nand-qpic-common.h -+++ b/include/linux/mtd/nand-qpic-common.h -@@ -70,35 +70,42 @@ - #define BS_CORRECTABLE_ERR_MSK 0x1f - - /* NAND_DEVn_CFG0 bits */ --#define DISABLE_STATUS_AFTER_WRITE 4 -+#define DISABLE_STATUS_AFTER_WRITE BIT(4) - #define CW_PER_PAGE 6 -+#define CW_PER_PAGE_MASK GENMASK(8, 6) - #define UD_SIZE_BYTES 9 - #define UD_SIZE_BYTES_MASK GENMASK(18, 9) --#define ECC_PARITY_SIZE_BYTES_RS 19 -+#define ECC_PARITY_SIZE_BYTES_RS GENMASK(22, 19) - #define SPARE_SIZE_BYTES 23 - #define SPARE_SIZE_BYTES_MASK GENMASK(26, 23) - #define NUM_ADDR_CYCLES 27 --#define STATUS_BFR_READ 30 --#define SET_RD_MODE_AFTER_STATUS 31 -+#define NUM_ADDR_CYCLES_MASK GENMASK(29, 27) -+#define STATUS_BFR_READ BIT(30) -+#define SET_RD_MODE_AFTER_STATUS BIT(31) - - /* NAND_DEVn_CFG0 bits */ --#define DEV0_CFG1_ECC_DISABLE 0 --#define WIDE_FLASH 1 -+#define DEV0_CFG1_ECC_DISABLE BIT(0) -+#define WIDE_FLASH BIT(1) - #define NAND_RECOVERY_CYCLES 2 --#define CS_ACTIVE_BSY 5 -+#define NAND_RECOVERY_CYCLES_MASK GENMASK(4, 2) -+#define CS_ACTIVE_BSY BIT(5) - #define BAD_BLOCK_BYTE_NUM 6 --#define BAD_BLOCK_IN_SPARE_AREA 16 -+#define BAD_BLOCK_BYTE_NUM_MASK GENMASK(15, 6) -+#define BAD_BLOCK_IN_SPARE_AREA BIT(16) - #define WR_RD_BSY_GAP 17 --#define ENABLE_BCH_ECC 27 -+#define WR_RD_BSY_GAP_MASK GENMASK(22, 17) -+#define ENABLE_BCH_ECC BIT(27) - - /* NAND_DEV0_ECC_CFG bits */ --#define ECC_CFG_ECC_DISABLE 0 --#define ECC_SW_RESET 1 -+#define ECC_CFG_ECC_DISABLE BIT(0) -+#define ECC_SW_RESET BIT(1) - #define ECC_MODE 4 -+#define ECC_MODE_MASK GENMASK(5, 4) - #define ECC_PARITY_SIZE_BYTES_BCH 8 -+#define ECC_PARITY_SIZE_BYTES_BCH_MASK GENMASK(12, 8) - #define ECC_NUM_DATA_BYTES 16 - #define ECC_NUM_DATA_BYTES_MASK GENMASK(25, 16) --#define ECC_FORCE_CLK_OPEN 30 -+#define ECC_FORCE_CLK_OPEN BIT(30) - - /* NAND_DEV_CMD1 bits */ - #define READ_ADDR 0 --- -2.51.0 - - -From 7f26e2256fd3b07d0d72101cd313fbe8adc0b6c5 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 7 Feb 2025 20:42:38 +0100 -Subject: [PATCH 014/517] mtd: rawnand: qcom: fix broken config in - qcom_param_page_type_exec - -Fix broken config in qcom_param_page_type_exec caused by copy-paste error -from commit 0c08080fd71c ("mtd: rawnand: qcom: use FIELD_PREP and GENMASK") - -In qcom_param_page_type_exec the value needs to be set to -nandc->regs->cfg0 instead of host->cfg0. This wrong configuration caused -the Qcom NANDC driver to malfunction on any device that makes use of it -(IPQ806x, IPQ40xx, IPQ807x, IPQ60xx) with the following error: - -[ 0.885369] nand: device found, Manufacturer ID: 0x2c, Chip ID: 0xaa -[ 0.885909] nand: Micron NAND 256MiB 1,8V 8-bit -[ 0.892499] nand: 256 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64 -[ 0.896823] nand: ECC (step, strength) = (512, 8) does not fit in OOB -[ 0.896836] qcom-nandc 79b0000.nand-controller: No valid ECC settings possible -[ 0.910996] bam-dma-engine 7984000.dma-controller: Cannot free busy channel -[ 0.918070] qcom-nandc: probe of 79b0000.nand-controller failed with error -28 - -Restore original configuration fix the problem and makes the driver work -again. - -Cc: stable@vger.kernel.org -Fixes: 0c08080fd71c ("mtd: rawnand: qcom: use FIELD_PREP and GENMASK") -Signed-off-by: Christian Marangi ---- - drivers/mtd/nand/raw/qcom_nandc.c | 24 ++++++++++++------------ - 1 file changed, 12 insertions(+), 12 deletions(-) - -diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c -index 086cb139adf1..c3b26fee55a8 100644 ---- a/drivers/mtd/nand/raw/qcom_nandc.c -+++ b/drivers/mtd/nand/raw/qcom_nandc.c -@@ -1886,18 +1886,18 @@ static int qcom_param_page_type_exec(struct nand_chip *chip, const struct nand_ - nandc->regs->addr0 = 0; - nandc->regs->addr1 = 0; - -- host->cfg0 = FIELD_PREP(CW_PER_PAGE_MASK, 0) | -- FIELD_PREP(UD_SIZE_BYTES_MASK, 512) | -- FIELD_PREP(NUM_ADDR_CYCLES_MASK, 5) | -- FIELD_PREP(SPARE_SIZE_BYTES_MASK, 0); -- -- host->cfg1 = FIELD_PREP(NAND_RECOVERY_CYCLES_MASK, 7) | -- FIELD_PREP(BAD_BLOCK_BYTE_NUM_MASK, 17) | -- FIELD_PREP(CS_ACTIVE_BSY, 0) | -- FIELD_PREP(BAD_BLOCK_IN_SPARE_AREA, 1) | -- FIELD_PREP(WR_RD_BSY_GAP_MASK, 2) | -- FIELD_PREP(WIDE_FLASH, 0) | -- FIELD_PREP(DEV0_CFG1_ECC_DISABLE, 1); -+ nandc->regs->cfg0 = FIELD_PREP(CW_PER_PAGE_MASK, 0) | -+ FIELD_PREP(UD_SIZE_BYTES_MASK, 512) | -+ FIELD_PREP(NUM_ADDR_CYCLES_MASK, 5) | -+ FIELD_PREP(SPARE_SIZE_BYTES_MASK, 0); -+ -+ nandc->regs->cfg1 = FIELD_PREP(NAND_RECOVERY_CYCLES_MASK, 7) | -+ FIELD_PREP(BAD_BLOCK_BYTE_NUM_MASK, 17) | -+ FIELD_PREP(CS_ACTIVE_BSY, 0) | -+ FIELD_PREP(BAD_BLOCK_IN_SPARE_AREA, 1) | -+ FIELD_PREP(WR_RD_BSY_GAP_MASK, 2) | -+ FIELD_PREP(WIDE_FLASH, 0) | -+ FIELD_PREP(DEV0_CFG1_ECC_DISABLE, 1); - - if (!nandc->props->qpic_version2) - nandc->regs->ecc_buf_cfg = cpu_to_le32(ECC_CFG_ECC_DISABLE); --- -2.51.0 - - -From 49f737acfea2251c082d8669fe62fabb1f13f626 Mon Sep 17 00:00:00 2001 -From: Md Sadre Alam -Date: Mon, 6 Jan 2025 18:45:58 +0530 -Subject: [PATCH 015/517] mtd: rawnand: qcom: Fix build issue on x86 - architecture -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Fix a buffer overflow issue in qcom_clear_bam_transaction by using -struct_group to group related fields and avoid FORTIFY_SOURCE warnings. - -On x86 architecture, the following error occurs due to warnings being -treated as errors: - -In function ‘fortify_memset_chk’, - inlined from ‘qcom_clear_bam_transaction’ at -drivers/mtd/nand/qpic_common.c:88:2: -./include/linux/fortify-string.h:480:25: error: call to ‘__write_overflow_field’ -declared with attribute warning: detected write beyond size of field -(1st parameter); maybe use struct_group()? [-Werror=attribute-warning] - 480 | __write_overflow_field(p_size_field, size); - | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - LD [M] drivers/mtd/nand/nandcore.o - CC [M] drivers/w1/masters/mxc_w1.o -cc1: all warnings being treated as errors - -This patch addresses the issue by grouping the related fields in -struct bam_transaction using struct_group and updating the memset call -accordingly. - -Fixes: 8c52932da5e6 ("mtd: rawnand: qcom: cleanup qcom_nandc driver") -Signed-off-by: Md Sadre Alam -Signed-off-by: Miquel Raynal ---- - drivers/mtd/nand/qpic_common.c | 2 +- - include/linux/mtd/nand-qpic-common.h | 19 +++++++++++-------- - 2 files changed, 12 insertions(+), 9 deletions(-) - -diff --git a/drivers/mtd/nand/qpic_common.c b/drivers/mtd/nand/qpic_common.c -index 8abbb960a7ce..e0ed25b5afea 100644 ---- a/drivers/mtd/nand/qpic_common.c -+++ b/drivers/mtd/nand/qpic_common.c -@@ -85,7 +85,7 @@ void qcom_clear_bam_transaction(struct qcom_nand_controller *nandc) - if (!nandc->props->supports_bam) - return; - -- memset(&bam_txn->bam_ce_pos, 0, sizeof(u32) * 8); -+ memset(&bam_txn->bam_positions, 0, sizeof(bam_txn->bam_positions)); - bam_txn->last_data_desc = NULL; - - sg_init_table(bam_txn->cmd_sgl, nandc->max_cwperpage * -diff --git a/include/linux/mtd/nand-qpic-common.h b/include/linux/mtd/nand-qpic-common.h -index e79c79775eb8..4d9b736ff8b7 100644 ---- a/include/linux/mtd/nand-qpic-common.h -+++ b/include/linux/mtd/nand-qpic-common.h -@@ -254,14 +254,17 @@ struct bam_transaction { - struct dma_async_tx_descriptor *last_data_desc; - struct dma_async_tx_descriptor *last_cmd_desc; - struct completion txn_done; -- u32 bam_ce_pos; -- u32 bam_ce_start; -- u32 cmd_sgl_pos; -- u32 cmd_sgl_start; -- u32 tx_sgl_pos; -- u32 tx_sgl_start; -- u32 rx_sgl_pos; -- u32 rx_sgl_start; -+ struct_group(bam_positions, -+ u32 bam_ce_pos; -+ u32 bam_ce_start; -+ u32 cmd_sgl_pos; -+ u32 cmd_sgl_start; -+ u32 tx_sgl_pos; -+ u32 tx_sgl_start; -+ u32 rx_sgl_pos; -+ u32 rx_sgl_start; -+ -+ ); - }; - - /* --- -2.51.0 - - -From ab61cede0b93c3d9c961220f76bf9918611d2884 Mon Sep 17 00:00:00 2001 -From: Md Sadre Alam -Date: Mon, 24 Feb 2025 16:44:14 +0530 -Subject: [PATCH 016/517] spi: spi-qpic: add driver for QCOM SPI NAND flash - Interface - -This driver implements support for the SPI-NAND mode of QCOM NAND Flash -Interface as a SPI-MEM controller with pipelined ECC capability. - -Co-developed-by: Sricharan Ramabadhran -Signed-off-by: Sricharan Ramabadhran -Co-developed-by: Varadarajan Narayanan -Signed-off-by: Varadarajan Narayanan -Signed-off-by: Md Sadre Alam -Link: https://patch.msgid.link/20250224111414.2809669-3-quic_mdalam@quicinc.com -Signed-off-by: Mark Brown ---- - drivers/mtd/nand/Makefile | 4 + - drivers/spi/Kconfig | 9 + - drivers/spi/Makefile | 1 + - drivers/spi/spi-qpic-snand.c | 1631 ++++++++++++++++++++++++++ - include/linux/mtd/nand-qpic-common.h | 7 + - 5 files changed, 1652 insertions(+) - create mode 100644 drivers/spi/spi-qpic-snand.c - -diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile -index da1586a36574..db516a45f0c5 100644 ---- a/drivers/mtd/nand/Makefile -+++ b/drivers/mtd/nand/Makefile -@@ -3,7 +3,11 @@ - nandcore-objs := core.o bbt.o - obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o - obj-$(CONFIG_MTD_NAND_ECC_MEDIATEK) += ecc-mtk.o -+ifeq ($(CONFIG_SPI_QPIC_SNAND),y) -+obj-$(CONFIG_SPI_QPIC_SNAND) += qpic_common.o -+else - obj-$(CONFIG_MTD_NAND_QCOM) += qpic_common.o -+endif - obj-y += onenand/ - obj-y += raw/ - obj-y += spi/ -diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig -index 823797217404..98c5fa460fb1 100644 ---- a/drivers/spi/Kconfig -+++ b/drivers/spi/Kconfig -@@ -898,6 +898,15 @@ config SPI_QCOM_QSPI - help - QSPI(Quad SPI) driver for Qualcomm QSPI controller. - -+config SPI_QPIC_SNAND -+ bool "QPIC SNAND controller" -+ depends on ARCH_QCOM || COMPILE_TEST -+ select MTD -+ help -+ QPIC_SNAND (QPIC SPI NAND) driver for Qualcomm QPIC controller. -+ QPIC controller supports both parallel nand and serial nand. -+ This config will enable serial nand driver for QPIC controller. -+ - config SPI_QUP - tristate "Qualcomm SPI controller with QUP interface" - depends on ARCH_QCOM || COMPILE_TEST -diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile -index a9b1bc259b68..d9d674eb84a6 100644 ---- a/drivers/spi/Makefile -+++ b/drivers/spi/Makefile -@@ -114,6 +114,7 @@ obj-$(CONFIG_SPI_PXA2XX) += spi-pxa2xx-platform.o - obj-$(CONFIG_SPI_PXA2XX_PCI) += spi-pxa2xx-pci.o - obj-$(CONFIG_SPI_QCOM_GENI) += spi-geni-qcom.o - obj-$(CONFIG_SPI_QCOM_QSPI) += spi-qcom-qspi.o -+obj-$(CONFIG_SPI_QPIC_SNAND) += spi-qpic-snand.o - obj-$(CONFIG_SPI_QUP) += spi-qup.o - obj-$(CONFIG_SPI_ROCKCHIP) += spi-rockchip.o - obj-$(CONFIG_SPI_ROCKCHIP_SFC) += spi-rockchip-sfc.o -diff --git a/drivers/spi/spi-qpic-snand.c b/drivers/spi/spi-qpic-snand.c -new file mode 100644 -index 000000000000..1a4746d0fd62 ---- /dev/null -+++ b/drivers/spi/spi-qpic-snand.c -@@ -0,0 +1,1631 @@ -+/* -+ * SPDX-License-Identifier: GPL-2.0 -+ * -+ * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved. -+ * -+ * Authors: -+ * Md Sadre Alam -+ * Sricharan R -+ * Varadarajan Narayanan -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define NAND_FLASH_SPI_CFG 0xc0 -+#define NAND_NUM_ADDR_CYCLES 0xc4 -+#define NAND_BUSY_CHECK_WAIT_CNT 0xc8 -+#define NAND_FLASH_FEATURES 0xf64 -+ -+/* QSPI NAND config reg bits */ -+#define LOAD_CLK_CNTR_INIT_EN BIT(28) -+#define CLK_CNTR_INIT_VAL_VEC 0x924 -+#define CLK_CNTR_INIT_VAL_VEC_MASK GENMASK(27, 16) -+#define FEA_STATUS_DEV_ADDR 0xc0 -+#define FEA_STATUS_DEV_ADDR_MASK GENMASK(15, 8) -+#define SPI_CFG BIT(0) -+#define SPI_NUM_ADDR 0xDA4DB -+#define SPI_WAIT_CNT 0x10 -+#define QPIC_QSPI_NUM_CS 1 -+#define SPI_TRANSFER_MODE_x1 BIT(29) -+#define SPI_TRANSFER_MODE_x4 (3 << 29) -+#define SPI_WP BIT(28) -+#define SPI_HOLD BIT(27) -+#define QPIC_SET_FEATURE BIT(31) -+ -+#define SPINAND_RESET 0xff -+#define SPINAND_READID 0x9f -+#define SPINAND_GET_FEATURE 0x0f -+#define SPINAND_SET_FEATURE 0x1f -+#define SPINAND_READ 0x13 -+#define SPINAND_ERASE 0xd8 -+#define SPINAND_WRITE_EN 0x06 -+#define SPINAND_PROGRAM_EXECUTE 0x10 -+#define SPINAND_PROGRAM_LOAD 0x84 -+ -+#define ACC_FEATURE 0xe -+#define BAD_BLOCK_MARKER_SIZE 0x2 -+#define OOB_BUF_SIZE 128 -+#define ecceng_to_qspi(eng) container_of(eng, struct qpic_spi_nand, ecc_eng) -+ -+struct qpic_snand_op { -+ u32 cmd_reg; -+ u32 addr1_reg; -+ u32 addr2_reg; -+}; -+ -+struct snandc_read_status { -+ __le32 snandc_flash; -+ __le32 snandc_buffer; -+ __le32 snandc_erased_cw; -+}; -+ -+/* -+ * ECC state struct -+ * @corrected: ECC corrected -+ * @bitflips: Max bit flip -+ * @failed: ECC failed -+ */ -+struct qcom_ecc_stats { -+ u32 corrected; -+ u32 bitflips; -+ u32 failed; -+}; -+ -+struct qpic_ecc { -+ struct device *dev; -+ int ecc_bytes_hw; -+ int spare_bytes; -+ int bbm_size; -+ int ecc_mode; -+ int bytes; -+ int steps; -+ int step_size; -+ int strength; -+ int cw_size; -+ int cw_data; -+ u32 cfg0; -+ u32 cfg1; -+ u32 cfg0_raw; -+ u32 cfg1_raw; -+ u32 ecc_buf_cfg; -+ u32 ecc_bch_cfg; -+ u32 clrflashstatus; -+ u32 clrreadstatus; -+ bool bch_enabled; -+}; -+ -+struct qpic_spi_nand { -+ struct qcom_nand_controller *snandc; -+ struct spi_controller *ctlr; -+ struct mtd_info *mtd; -+ struct clk *iomacro_clk; -+ struct qpic_ecc *ecc; -+ struct qcom_ecc_stats ecc_stats; -+ struct nand_ecc_engine ecc_eng; -+ u8 *data_buf; -+ u8 *oob_buf; -+ u32 wlen; -+ __le32 addr1; -+ __le32 addr2; -+ __le32 cmd; -+ u32 num_cw; -+ bool oob_rw; -+ bool page_rw; -+ bool raw_rw; -+}; -+ -+static void qcom_spi_set_read_loc_first(struct qcom_nand_controller *snandc, -+ int reg, int cw_offset, int read_size, -+ int is_last_read_loc) -+{ -+ __le32 locreg_val; -+ u32 val = (((cw_offset) << READ_LOCATION_OFFSET) | -+ ((read_size) << READ_LOCATION_SIZE) | ((is_last_read_loc) -+ << READ_LOCATION_LAST)); -+ -+ locreg_val = cpu_to_le32(val); -+ -+ if (reg == NAND_READ_LOCATION_0) -+ snandc->regs->read_location0 = locreg_val; -+ else if (reg == NAND_READ_LOCATION_1) -+ snandc->regs->read_location1 = locreg_val; -+ else if (reg == NAND_READ_LOCATION_2) -+ snandc->regs->read_location1 = locreg_val; -+ else if (reg == NAND_READ_LOCATION_3) -+ snandc->regs->read_location3 = locreg_val; -+} -+ -+static void qcom_spi_set_read_loc_last(struct qcom_nand_controller *snandc, -+ int reg, int cw_offset, int read_size, -+ int is_last_read_loc) -+{ -+ __le32 locreg_val; -+ u32 val = (((cw_offset) << READ_LOCATION_OFFSET) | -+ ((read_size) << READ_LOCATION_SIZE) | ((is_last_read_loc) -+ << READ_LOCATION_LAST)); -+ -+ locreg_val = cpu_to_le32(val); -+ -+ if (reg == NAND_READ_LOCATION_LAST_CW_0) -+ snandc->regs->read_location_last0 = locreg_val; -+ else if (reg == NAND_READ_LOCATION_LAST_CW_1) -+ snandc->regs->read_location_last1 = locreg_val; -+ else if (reg == NAND_READ_LOCATION_LAST_CW_2) -+ snandc->regs->read_location_last2 = locreg_val; -+ else if (reg == NAND_READ_LOCATION_LAST_CW_3) -+ snandc->regs->read_location_last3 = locreg_val; -+} -+ -+static struct qcom_nand_controller *nand_to_qcom_snand(struct nand_device *nand) -+{ -+ struct nand_ecc_engine *eng = nand->ecc.engine; -+ struct qpic_spi_nand *qspi = ecceng_to_qspi(eng); -+ -+ return qspi->snandc; -+} -+ -+static int qcom_spi_init(struct qcom_nand_controller *snandc) -+{ -+ u32 snand_cfg_val = 0x0; -+ int ret; -+ -+ snand_cfg_val = FIELD_PREP(CLK_CNTR_INIT_VAL_VEC_MASK, CLK_CNTR_INIT_VAL_VEC) | -+ FIELD_PREP(LOAD_CLK_CNTR_INIT_EN, 0) | -+ FIELD_PREP(FEA_STATUS_DEV_ADDR_MASK, FEA_STATUS_DEV_ADDR) | -+ FIELD_PREP(SPI_CFG, 0); -+ -+ snandc->regs->spi_cfg = cpu_to_le32(snand_cfg_val); -+ snandc->regs->num_addr_cycle = cpu_to_le32(SPI_NUM_ADDR); -+ snandc->regs->busy_wait_cnt = cpu_to_le32(SPI_WAIT_CNT); -+ -+ qcom_write_reg_dma(snandc, &snandc->regs->spi_cfg, NAND_FLASH_SPI_CFG, 1, 0); -+ -+ snand_cfg_val &= ~LOAD_CLK_CNTR_INIT_EN; -+ snandc->regs->spi_cfg = cpu_to_le32(snand_cfg_val); -+ -+ qcom_write_reg_dma(snandc, &snandc->regs->spi_cfg, NAND_FLASH_SPI_CFG, 1, 0); -+ -+ qcom_write_reg_dma(snandc, &snandc->regs->num_addr_cycle, NAND_NUM_ADDR_CYCLES, 1, 0); -+ qcom_write_reg_dma(snandc, &snandc->regs->busy_wait_cnt, NAND_BUSY_CHECK_WAIT_CNT, 1, -+ NAND_BAM_NEXT_SGL); -+ -+ ret = qcom_submit_descs(snandc); -+ if (ret) { -+ dev_err(snandc->dev, "failure in submitting spi init descriptor\n"); -+ return ret; -+ } -+ -+ return ret; -+} -+ -+static int qcom_spi_ooblayout_ecc(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ struct nand_device *nand = mtd_to_nanddev(mtd); -+ struct qcom_nand_controller *snandc = nand_to_qcom_snand(nand); -+ struct qpic_ecc *qecc = snandc->qspi->ecc; -+ -+ if (section > 1) -+ return -ERANGE; -+ -+ oobregion->length = qecc->ecc_bytes_hw + qecc->spare_bytes; -+ oobregion->offset = mtd->oobsize - oobregion->length; -+ -+ return 0; -+} -+ -+static int qcom_spi_ooblayout_free(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ struct nand_device *nand = mtd_to_nanddev(mtd); -+ struct qcom_nand_controller *snandc = nand_to_qcom_snand(nand); -+ struct qpic_ecc *qecc = snandc->qspi->ecc; -+ -+ if (section) -+ return -ERANGE; -+ -+ oobregion->length = qecc->steps * 4; -+ oobregion->offset = ((qecc->steps - 1) * qecc->bytes) + qecc->bbm_size; -+ -+ return 0; -+} -+ -+static const struct mtd_ooblayout_ops qcom_spi_ooblayout = { -+ .ecc = qcom_spi_ooblayout_ecc, -+ .free = qcom_spi_ooblayout_free, -+}; -+ -+static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand) -+{ -+ struct qcom_nand_controller *snandc = nand_to_qcom_snand(nand); -+ struct nand_ecc_props *conf = &nand->ecc.ctx.conf; -+ struct mtd_info *mtd = nanddev_to_mtd(nand); -+ int cwperpage, bad_block_byte; -+ struct qpic_ecc *ecc_cfg; -+ -+ cwperpage = mtd->writesize / NANDC_STEP_SIZE; -+ snandc->qspi->num_cw = cwperpage; -+ -+ ecc_cfg = kzalloc(sizeof(*ecc_cfg), GFP_KERNEL); -+ if (!ecc_cfg) -+ return -ENOMEM; -+ snandc->qspi->oob_buf = kzalloc(mtd->writesize + mtd->oobsize, -+ GFP_KERNEL); -+ if (!snandc->qspi->oob_buf) -+ return -ENOMEM; -+ -+ memset(snandc->qspi->oob_buf, 0xff, mtd->writesize + mtd->oobsize); -+ -+ nand->ecc.ctx.priv = ecc_cfg; -+ snandc->qspi->mtd = mtd; -+ -+ ecc_cfg->ecc_bytes_hw = 7; -+ ecc_cfg->spare_bytes = 4; -+ ecc_cfg->bbm_size = 1; -+ ecc_cfg->bch_enabled = true; -+ ecc_cfg->bytes = ecc_cfg->ecc_bytes_hw + ecc_cfg->spare_bytes + ecc_cfg->bbm_size; -+ -+ ecc_cfg->steps = 4; -+ ecc_cfg->strength = 4; -+ ecc_cfg->step_size = 512; -+ ecc_cfg->cw_data = 516; -+ ecc_cfg->cw_size = ecc_cfg->cw_data + ecc_cfg->bytes; -+ bad_block_byte = mtd->writesize - ecc_cfg->cw_size * (cwperpage - 1) + 1; -+ -+ mtd_set_ooblayout(mtd, &qcom_spi_ooblayout); -+ -+ ecc_cfg->cfg0 = FIELD_PREP(CW_PER_PAGE_MASK, (cwperpage - 1)) | -+ FIELD_PREP(UD_SIZE_BYTES_MASK, ecc_cfg->cw_data) | -+ FIELD_PREP(DISABLE_STATUS_AFTER_WRITE, 1) | -+ FIELD_PREP(NUM_ADDR_CYCLES_MASK, 3) | -+ FIELD_PREP(ECC_PARITY_SIZE_BYTES_RS, ecc_cfg->ecc_bytes_hw) | -+ FIELD_PREP(STATUS_BFR_READ, 0) | -+ FIELD_PREP(SET_RD_MODE_AFTER_STATUS, 1) | -+ FIELD_PREP(SPARE_SIZE_BYTES_MASK, ecc_cfg->spare_bytes); -+ -+ ecc_cfg->cfg1 = FIELD_PREP(NAND_RECOVERY_CYCLES_MASK, 0) | -+ FIELD_PREP(CS_ACTIVE_BSY, 0) | -+ FIELD_PREP(BAD_BLOCK_BYTE_NUM_MASK, bad_block_byte) | -+ FIELD_PREP(BAD_BLOCK_IN_SPARE_AREA, 0) | -+ FIELD_PREP(WR_RD_BSY_GAP_MASK, 20) | -+ FIELD_PREP(WIDE_FLASH, 0) | -+ FIELD_PREP(ENABLE_BCH_ECC, ecc_cfg->bch_enabled); -+ -+ ecc_cfg->cfg0_raw = FIELD_PREP(CW_PER_PAGE_MASK, (cwperpage - 1)) | -+ FIELD_PREP(NUM_ADDR_CYCLES_MASK, 3) | -+ FIELD_PREP(UD_SIZE_BYTES_MASK, ecc_cfg->cw_size) | -+ FIELD_PREP(SPARE_SIZE_BYTES_MASK, 0); -+ -+ ecc_cfg->cfg1_raw = FIELD_PREP(NAND_RECOVERY_CYCLES_MASK, 0) | -+ FIELD_PREP(CS_ACTIVE_BSY, 0) | -+ FIELD_PREP(BAD_BLOCK_BYTE_NUM_MASK, 17) | -+ FIELD_PREP(BAD_BLOCK_IN_SPARE_AREA, 1) | -+ FIELD_PREP(WR_RD_BSY_GAP_MASK, 20) | -+ FIELD_PREP(WIDE_FLASH, 0) | -+ FIELD_PREP(DEV0_CFG1_ECC_DISABLE, 1); -+ -+ ecc_cfg->ecc_bch_cfg = FIELD_PREP(ECC_CFG_ECC_DISABLE, !ecc_cfg->bch_enabled) | -+ FIELD_PREP(ECC_SW_RESET, 0) | -+ FIELD_PREP(ECC_NUM_DATA_BYTES_MASK, ecc_cfg->cw_data) | -+ FIELD_PREP(ECC_FORCE_CLK_OPEN, 1) | -+ FIELD_PREP(ECC_MODE_MASK, 0) | -+ FIELD_PREP(ECC_PARITY_SIZE_BYTES_BCH_MASK, ecc_cfg->ecc_bytes_hw); -+ -+ ecc_cfg->ecc_buf_cfg = 0x203 << NUM_STEPS; -+ ecc_cfg->clrflashstatus = FS_READY_BSY_N; -+ ecc_cfg->clrreadstatus = 0xc0; -+ -+ conf->step_size = ecc_cfg->step_size; -+ conf->strength = ecc_cfg->strength; -+ -+ snandc->regs->erased_cw_detect_cfg_clr = cpu_to_le32(CLR_ERASED_PAGE_DET); -+ snandc->regs->erased_cw_detect_cfg_set = cpu_to_le32(SET_ERASED_PAGE_DET); -+ -+ dev_dbg(snandc->dev, "ECC strength: %u bits per %u bytes\n", -+ ecc_cfg->strength, ecc_cfg->step_size); -+ -+ return 0; -+} -+ -+static void qcom_spi_ecc_cleanup_ctx_pipelined(struct nand_device *nand) -+{ -+ struct qpic_ecc *ecc_cfg = nand_to_ecc_ctx(nand); -+ -+ kfree(ecc_cfg); -+} -+ -+static int qcom_spi_ecc_prepare_io_req_pipelined(struct nand_device *nand, -+ struct nand_page_io_req *req) -+{ -+ struct qcom_nand_controller *snandc = nand_to_qcom_snand(nand); -+ struct qpic_ecc *ecc_cfg = nand_to_ecc_ctx(nand); -+ -+ snandc->qspi->ecc = ecc_cfg; -+ snandc->qspi->raw_rw = false; -+ snandc->qspi->oob_rw = false; -+ snandc->qspi->page_rw = false; -+ -+ if (req->datalen) -+ snandc->qspi->page_rw = true; -+ -+ if (req->ooblen) -+ snandc->qspi->oob_rw = true; -+ -+ if (req->mode == MTD_OPS_RAW) -+ snandc->qspi->raw_rw = true; -+ -+ return 0; -+} -+ -+static int qcom_spi_ecc_finish_io_req_pipelined(struct nand_device *nand, -+ struct nand_page_io_req *req) -+{ -+ struct qcom_nand_controller *snandc = nand_to_qcom_snand(nand); -+ struct mtd_info *mtd = nanddev_to_mtd(nand); -+ -+ if (req->mode == MTD_OPS_RAW || req->type != NAND_PAGE_READ) -+ return 0; -+ -+ if (snandc->qspi->ecc_stats.failed) -+ mtd->ecc_stats.failed += snandc->qspi->ecc_stats.failed; -+ else -+ mtd->ecc_stats.corrected += snandc->qspi->ecc_stats.corrected; -+ -+ if (snandc->qspi->ecc_stats.failed) -+ return -EBADMSG; -+ else -+ return snandc->qspi->ecc_stats.bitflips; -+} -+ -+static struct nand_ecc_engine_ops qcom_spi_ecc_engine_ops_pipelined = { -+ .init_ctx = qcom_spi_ecc_init_ctx_pipelined, -+ .cleanup_ctx = qcom_spi_ecc_cleanup_ctx_pipelined, -+ .prepare_io_req = qcom_spi_ecc_prepare_io_req_pipelined, -+ .finish_io_req = qcom_spi_ecc_finish_io_req_pipelined, -+}; -+ -+/* helper to configure location register values */ -+static void qcom_spi_set_read_loc(struct qcom_nand_controller *snandc, int cw, int reg, -+ int cw_offset, int read_size, int is_last_read_loc) -+{ -+ int reg_base = NAND_READ_LOCATION_0; -+ int num_cw = snandc->qspi->num_cw; -+ -+ if (cw == (num_cw - 1)) -+ reg_base = NAND_READ_LOCATION_LAST_CW_0; -+ -+ reg_base += reg * 4; -+ -+ if (cw == (num_cw - 1)) -+ return qcom_spi_set_read_loc_last(snandc, reg_base, cw_offset, -+ read_size, is_last_read_loc); -+ else -+ return qcom_spi_set_read_loc_first(snandc, reg_base, cw_offset, -+ read_size, is_last_read_loc); -+} -+ -+static void -+qcom_spi_config_cw_read(struct qcom_nand_controller *snandc, bool use_ecc, int cw) -+{ -+ __le32 *reg = &snandc->regs->read_location0; -+ int num_cw = snandc->qspi->num_cw; -+ -+ qcom_write_reg_dma(snandc, reg, NAND_READ_LOCATION_0, 4, NAND_BAM_NEXT_SGL); -+ if (cw == (num_cw - 1)) { -+ reg = &snandc->regs->read_location_last0; -+ qcom_write_reg_dma(snandc, reg, NAND_READ_LOCATION_LAST_CW_0, 4, -+ NAND_BAM_NEXT_SGL); -+ } -+ -+ qcom_write_reg_dma(snandc, &snandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL); -+ qcom_write_reg_dma(snandc, &snandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); -+ -+ qcom_read_reg_dma(snandc, NAND_FLASH_STATUS, 2, 0); -+ qcom_read_reg_dma(snandc, NAND_ERASED_CW_DETECT_STATUS, 1, -+ NAND_BAM_NEXT_SGL); -+} -+ -+static int qcom_spi_block_erase(struct qcom_nand_controller *snandc) -+{ -+ struct qpic_ecc *ecc_cfg = snandc->qspi->ecc; -+ int ret; -+ -+ snandc->buf_count = 0; -+ snandc->buf_start = 0; -+ qcom_clear_read_regs(snandc); -+ qcom_clear_bam_transaction(snandc); -+ -+ snandc->regs->cmd = snandc->qspi->cmd; -+ snandc->regs->addr0 = snandc->qspi->addr1; -+ snandc->regs->addr1 = snandc->qspi->addr2; -+ snandc->regs->cfg0 = cpu_to_le32(ecc_cfg->cfg0_raw & ~(7 << CW_PER_PAGE)); -+ snandc->regs->cfg1 = cpu_to_le32(ecc_cfg->cfg1_raw); -+ snandc->regs->exec = cpu_to_le32(1); -+ -+ qcom_write_reg_dma(snandc, &snandc->regs->cmd, NAND_FLASH_CMD, 3, NAND_BAM_NEXT_SGL); -+ qcom_write_reg_dma(snandc, &snandc->regs->cfg0, NAND_DEV0_CFG0, 2, NAND_BAM_NEXT_SGL); -+ qcom_write_reg_dma(snandc, &snandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); -+ -+ ret = qcom_submit_descs(snandc); -+ if (ret) { -+ dev_err(snandc->dev, "failure to erase block\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static void qcom_spi_config_single_cw_page_read(struct qcom_nand_controller *snandc, -+ bool use_ecc, int cw) -+{ -+ __le32 *reg = &snandc->regs->read_location0; -+ int num_cw = snandc->qspi->num_cw; -+ -+ qcom_write_reg_dma(snandc, &snandc->regs->addr0, NAND_ADDR0, 2, 0); -+ qcom_write_reg_dma(snandc, &snandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0); -+ qcom_write_reg_dma(snandc, &snandc->regs->erased_cw_detect_cfg_clr, -+ NAND_ERASED_CW_DETECT_CFG, 1, 0); -+ qcom_write_reg_dma(snandc, &snandc->regs->erased_cw_detect_cfg_set, -+ NAND_ERASED_CW_DETECT_CFG, 1, -+ NAND_ERASED_CW_SET | NAND_BAM_NEXT_SGL); -+ -+ if (cw == (num_cw - 1)) { -+ reg = &snandc->regs->read_location_last0; -+ qcom_write_reg_dma(snandc, reg, NAND_READ_LOCATION_LAST_CW_0, 4, NAND_BAM_NEXT_SGL); -+ } -+ qcom_write_reg_dma(snandc, &snandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL); -+ qcom_write_reg_dma(snandc, &snandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); -+ -+ qcom_read_reg_dma(snandc, NAND_FLASH_STATUS, 1, 0); -+} -+ -+static int qcom_spi_read_last_cw(struct qcom_nand_controller *snandc, -+ const struct spi_mem_op *op) -+{ -+ struct qpic_ecc *ecc_cfg = snandc->qspi->ecc; -+ struct mtd_info *mtd = snandc->qspi->mtd; -+ int size, ret = 0; -+ int col, bbpos; -+ u32 cfg0, cfg1, ecc_bch_cfg; -+ u32 num_cw = snandc->qspi->num_cw; -+ -+ qcom_clear_bam_transaction(snandc); -+ qcom_clear_read_regs(snandc); -+ -+ size = ecc_cfg->cw_size; -+ col = ecc_cfg->cw_size * (num_cw - 1); -+ -+ memset(snandc->data_buffer, 0xff, size); -+ snandc->regs->addr0 = (snandc->qspi->addr1 | cpu_to_le32(col)); -+ snandc->regs->addr1 = snandc->qspi->addr2; -+ -+ cfg0 = (ecc_cfg->cfg0_raw & ~(7U << CW_PER_PAGE)) | -+ 0 << CW_PER_PAGE; -+ cfg1 = ecc_cfg->cfg1_raw; -+ ecc_bch_cfg = 1 << ECC_CFG_ECC_DISABLE; -+ -+ snandc->regs->cmd = snandc->qspi->cmd; -+ snandc->regs->cfg0 = cpu_to_le32(cfg0); -+ snandc->regs->cfg1 = cpu_to_le32(cfg1); -+ snandc->regs->ecc_bch_cfg = cpu_to_le32(ecc_bch_cfg); -+ snandc->regs->clrflashstatus = cpu_to_le32(ecc_cfg->clrflashstatus); -+ snandc->regs->clrreadstatus = cpu_to_le32(ecc_cfg->clrreadstatus); -+ snandc->regs->exec = cpu_to_le32(1); -+ -+ qcom_spi_set_read_loc(snandc, num_cw - 1, 0, 0, ecc_cfg->cw_size, 1); -+ -+ qcom_spi_config_single_cw_page_read(snandc, false, num_cw - 1); -+ -+ qcom_read_data_dma(snandc, FLASH_BUF_ACC, snandc->data_buffer, size, 0); -+ -+ ret = qcom_submit_descs(snandc); -+ if (ret) { -+ dev_err(snandc->dev, "failed to read last cw\n"); -+ return ret; -+ } -+ -+ qcom_nandc_dev_to_mem(snandc, true); -+ u32 flash = le32_to_cpu(snandc->reg_read_buf[0]); -+ -+ if (flash & (FS_OP_ERR | FS_MPU_ERR)) -+ return -EIO; -+ -+ bbpos = mtd->writesize - ecc_cfg->cw_size * (num_cw - 1); -+ -+ if (snandc->data_buffer[bbpos] == 0xff) -+ snandc->data_buffer[bbpos + 1] = 0xff; -+ if (snandc->data_buffer[bbpos] != 0xff) -+ snandc->data_buffer[bbpos + 1] = snandc->data_buffer[bbpos]; -+ -+ memcpy(op->data.buf.in, snandc->data_buffer + bbpos, op->data.nbytes); -+ -+ return ret; -+} -+ -+static int qcom_spi_check_error(struct qcom_nand_controller *snandc, u8 *data_buf, u8 *oob_buf) -+{ -+ struct snandc_read_status *buf; -+ struct qpic_ecc *ecc_cfg = snandc->qspi->ecc; -+ int i, num_cw = snandc->qspi->num_cw; -+ bool flash_op_err = false, erased; -+ unsigned int max_bitflips = 0; -+ unsigned int uncorrectable_cws = 0; -+ -+ snandc->qspi->ecc_stats.failed = 0; -+ snandc->qspi->ecc_stats.corrected = 0; -+ -+ qcom_nandc_dev_to_mem(snandc, true); -+ buf = (struct snandc_read_status *)snandc->reg_read_buf; -+ -+ for (i = 0; i < num_cw; i++, buf++) { -+ u32 flash, buffer, erased_cw; -+ int data_len, oob_len; -+ -+ if (i == (num_cw - 1)) { -+ data_len = NANDC_STEP_SIZE - ((num_cw - 1) << 2); -+ oob_len = num_cw << 2; -+ } else { -+ data_len = ecc_cfg->cw_data; -+ oob_len = 0; -+ } -+ -+ flash = le32_to_cpu(buf->snandc_flash); -+ buffer = le32_to_cpu(buf->snandc_buffer); -+ erased_cw = le32_to_cpu(buf->snandc_erased_cw); -+ -+ if ((flash & FS_OP_ERR) && (buffer & BS_UNCORRECTABLE_BIT)) { -+ if (ecc_cfg->bch_enabled) -+ erased = (erased_cw & ERASED_CW) == ERASED_CW; -+ else -+ erased = false; -+ -+ if (!erased) -+ uncorrectable_cws |= BIT(i); -+ -+ } else if (flash & (FS_OP_ERR | FS_MPU_ERR)) { -+ flash_op_err = true; -+ } else { -+ unsigned int stat; -+ -+ stat = buffer & BS_CORRECTABLE_ERR_MSK; -+ snandc->qspi->ecc_stats.corrected += stat; -+ max_bitflips = max(max_bitflips, stat); -+ } -+ -+ if (data_buf) -+ data_buf += data_len; -+ if (oob_buf) -+ oob_buf += oob_len + ecc_cfg->bytes; -+ } -+ -+ if (flash_op_err) -+ return -EIO; -+ -+ if (!uncorrectable_cws) -+ snandc->qspi->ecc_stats.bitflips = max_bitflips; -+ else -+ snandc->qspi->ecc_stats.failed++; -+ -+ return 0; -+} -+ -+static int qcom_spi_check_raw_flash_errors(struct qcom_nand_controller *snandc, int cw_cnt) -+{ -+ int i; -+ -+ qcom_nandc_dev_to_mem(snandc, true); -+ -+ for (i = 0; i < cw_cnt; i++) { -+ u32 flash = le32_to_cpu(snandc->reg_read_buf[i]); -+ -+ if (flash & (FS_OP_ERR | FS_MPU_ERR)) -+ return -EIO; -+ } -+ -+ return 0; -+} -+ -+static int qcom_spi_read_cw_raw(struct qcom_nand_controller *snandc, u8 *data_buf, -+ u8 *oob_buf, int cw) -+{ -+ struct qpic_ecc *ecc_cfg = snandc->qspi->ecc; -+ struct mtd_info *mtd = snandc->qspi->mtd; -+ int data_size1, data_size2, oob_size1, oob_size2; -+ int ret, reg_off = FLASH_BUF_ACC, read_loc = 0; -+ int raw_cw = cw; -+ u32 cfg0, cfg1, ecc_bch_cfg, num_cw = snandc->qspi->num_cw; -+ int col; -+ -+ snandc->buf_count = 0; -+ snandc->buf_start = 0; -+ qcom_clear_read_regs(snandc); -+ qcom_clear_bam_transaction(snandc); -+ raw_cw = num_cw - 1; -+ -+ cfg0 = (ecc_cfg->cfg0_raw & ~(7U << CW_PER_PAGE)) | -+ 0 << CW_PER_PAGE; -+ cfg1 = ecc_cfg->cfg1_raw; -+ ecc_bch_cfg = ECC_CFG_ECC_DISABLE; -+ -+ col = ecc_cfg->cw_size * cw; -+ -+ snandc->regs->addr0 = (snandc->qspi->addr1 | cpu_to_le32(col)); -+ snandc->regs->addr1 = snandc->qspi->addr2; -+ snandc->regs->cmd = snandc->qspi->cmd; -+ snandc->regs->cfg0 = cpu_to_le32(cfg0); -+ snandc->regs->cfg1 = cpu_to_le32(cfg1); -+ snandc->regs->ecc_bch_cfg = cpu_to_le32(ecc_bch_cfg); -+ snandc->regs->clrflashstatus = cpu_to_le32(ecc_cfg->clrflashstatus); -+ snandc->regs->clrreadstatus = cpu_to_le32(ecc_cfg->clrreadstatus); -+ snandc->regs->exec = cpu_to_le32(1); -+ -+ qcom_spi_set_read_loc(snandc, raw_cw, 0, 0, ecc_cfg->cw_size, 1); -+ -+ qcom_write_reg_dma(snandc, &snandc->regs->addr0, NAND_ADDR0, 2, 0); -+ qcom_write_reg_dma(snandc, &snandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0); -+ qcom_write_reg_dma(snandc, &snandc->regs->ecc_buf_cfg, NAND_EBI2_ECC_BUF_CFG, 1, 0); -+ -+ qcom_write_reg_dma(snandc, &snandc->regs->erased_cw_detect_cfg_clr, -+ NAND_ERASED_CW_DETECT_CFG, 1, 0); -+ qcom_write_reg_dma(snandc, &snandc->regs->erased_cw_detect_cfg_set, -+ NAND_ERASED_CW_DETECT_CFG, 1, -+ NAND_ERASED_CW_SET | NAND_BAM_NEXT_SGL); -+ -+ data_size1 = mtd->writesize - ecc_cfg->cw_size * (num_cw - 1); -+ oob_size1 = ecc_cfg->bbm_size; -+ -+ if (cw == (num_cw - 1)) { -+ data_size2 = NANDC_STEP_SIZE - data_size1 - -+ ((num_cw - 1) * 4); -+ oob_size2 = (num_cw * 4) + ecc_cfg->ecc_bytes_hw + -+ ecc_cfg->spare_bytes; -+ } else { -+ data_size2 = ecc_cfg->cw_data - data_size1; -+ oob_size2 = ecc_cfg->ecc_bytes_hw + ecc_cfg->spare_bytes; -+ } -+ -+ qcom_spi_set_read_loc(snandc, cw, 0, read_loc, data_size1, 0); -+ read_loc += data_size1; -+ -+ qcom_spi_set_read_loc(snandc, cw, 1, read_loc, oob_size1, 0); -+ read_loc += oob_size1; -+ -+ qcom_spi_set_read_loc(snandc, cw, 2, read_loc, data_size2, 0); -+ read_loc += data_size2; -+ -+ qcom_spi_set_read_loc(snandc, cw, 3, read_loc, oob_size2, 1); -+ -+ qcom_spi_config_cw_read(snandc, false, raw_cw); -+ -+ qcom_read_data_dma(snandc, reg_off, data_buf, data_size1, 0); -+ reg_off += data_size1; -+ -+ qcom_read_data_dma(snandc, reg_off, oob_buf, oob_size1, 0); -+ reg_off += oob_size1; -+ -+ qcom_read_data_dma(snandc, reg_off, data_buf + data_size1, data_size2, 0); -+ reg_off += data_size2; -+ -+ qcom_read_data_dma(snandc, reg_off, oob_buf + oob_size1, oob_size2, 0); -+ -+ ret = qcom_submit_descs(snandc); -+ if (ret) { -+ dev_err(snandc->dev, "failure to read raw cw %d\n", cw); -+ return ret; -+ } -+ -+ return qcom_spi_check_raw_flash_errors(snandc, 1); -+} -+ -+static int qcom_spi_read_page_raw(struct qcom_nand_controller *snandc, -+ const struct spi_mem_op *op) -+{ -+ struct qpic_ecc *ecc_cfg = snandc->qspi->ecc; -+ u8 *data_buf = NULL, *oob_buf = NULL; -+ int ret, cw; -+ u32 num_cw = snandc->qspi->num_cw; -+ -+ if (snandc->qspi->page_rw) -+ data_buf = op->data.buf.in; -+ -+ oob_buf = snandc->qspi->oob_buf; -+ memset(oob_buf, 0xff, OOB_BUF_SIZE); -+ -+ for (cw = 0; cw < num_cw; cw++) { -+ ret = qcom_spi_read_cw_raw(snandc, data_buf, oob_buf, cw); -+ if (ret) -+ return ret; -+ -+ if (data_buf) -+ data_buf += ecc_cfg->cw_data; -+ if (oob_buf) -+ oob_buf += ecc_cfg->bytes; -+ } -+ -+ return 0; -+} -+ -+static int qcom_spi_read_page_ecc(struct qcom_nand_controller *snandc, -+ const struct spi_mem_op *op) -+{ -+ struct qpic_ecc *ecc_cfg = snandc->qspi->ecc; -+ u8 *data_buf = NULL, *data_buf_start, *oob_buf = NULL, *oob_buf_start; -+ int ret, i; -+ u32 cfg0, cfg1, ecc_bch_cfg, num_cw = snandc->qspi->num_cw; -+ -+ data_buf = op->data.buf.in; -+ data_buf_start = data_buf; -+ -+ oob_buf = snandc->qspi->oob_buf; -+ oob_buf_start = oob_buf; -+ -+ snandc->buf_count = 0; -+ snandc->buf_start = 0; -+ qcom_clear_read_regs(snandc); -+ -+ cfg0 = (ecc_cfg->cfg0 & ~(7U << CW_PER_PAGE)) | -+ (num_cw - 1) << CW_PER_PAGE; -+ cfg1 = ecc_cfg->cfg1; -+ ecc_bch_cfg = ecc_cfg->ecc_bch_cfg; -+ -+ snandc->regs->addr0 = snandc->qspi->addr1; -+ snandc->regs->addr1 = snandc->qspi->addr2; -+ snandc->regs->cmd = snandc->qspi->cmd; -+ snandc->regs->cfg0 = cpu_to_le32(cfg0); -+ snandc->regs->cfg1 = cpu_to_le32(cfg1); -+ snandc->regs->ecc_bch_cfg = cpu_to_le32(ecc_bch_cfg); -+ snandc->regs->clrflashstatus = cpu_to_le32(ecc_cfg->clrflashstatus); -+ snandc->regs->clrreadstatus = cpu_to_le32(ecc_cfg->clrreadstatus); -+ snandc->regs->exec = cpu_to_le32(1); -+ -+ qcom_spi_set_read_loc(snandc, 0, 0, 0, ecc_cfg->cw_data, 1); -+ -+ qcom_clear_bam_transaction(snandc); -+ -+ qcom_write_reg_dma(snandc, &snandc->regs->addr0, NAND_ADDR0, 2, 0); -+ qcom_write_reg_dma(snandc, &snandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0); -+ qcom_write_reg_dma(snandc, &snandc->regs->erased_cw_detect_cfg_clr, -+ NAND_ERASED_CW_DETECT_CFG, 1, 0); -+ qcom_write_reg_dma(snandc, &snandc->regs->erased_cw_detect_cfg_set, -+ NAND_ERASED_CW_DETECT_CFG, 1, -+ NAND_ERASED_CW_SET | NAND_BAM_NEXT_SGL); -+ -+ for (i = 0; i < num_cw; i++) { -+ int data_size, oob_size; -+ -+ if (i == (num_cw - 1)) { -+ data_size = 512 - ((num_cw - 1) << 2); -+ oob_size = (num_cw << 2) + ecc_cfg->ecc_bytes_hw + -+ ecc_cfg->spare_bytes; -+ } else { -+ data_size = ecc_cfg->cw_data; -+ oob_size = ecc_cfg->ecc_bytes_hw + ecc_cfg->spare_bytes; -+ } -+ -+ if (data_buf && oob_buf) { -+ qcom_spi_set_read_loc(snandc, i, 0, 0, data_size, 0); -+ qcom_spi_set_read_loc(snandc, i, 1, data_size, oob_size, 1); -+ } else if (data_buf) { -+ qcom_spi_set_read_loc(snandc, i, 0, 0, data_size, 1); -+ } else { -+ qcom_spi_set_read_loc(snandc, i, 0, data_size, oob_size, 1); -+ } -+ -+ qcom_spi_config_cw_read(snandc, true, i); -+ -+ if (data_buf) -+ qcom_read_data_dma(snandc, FLASH_BUF_ACC, data_buf, -+ data_size, 0); -+ if (oob_buf) { -+ int j; -+ -+ for (j = 0; j < ecc_cfg->bbm_size; j++) -+ *oob_buf++ = 0xff; -+ -+ qcom_read_data_dma(snandc, FLASH_BUF_ACC + data_size, -+ oob_buf, oob_size, 0); -+ } -+ -+ if (data_buf) -+ data_buf += data_size; -+ if (oob_buf) -+ oob_buf += oob_size; -+ } -+ -+ ret = qcom_submit_descs(snandc); -+ if (ret) { -+ dev_err(snandc->dev, "failure to read page\n"); -+ return ret; -+ } -+ -+ return qcom_spi_check_error(snandc, data_buf_start, oob_buf_start); -+} -+ -+static int qcom_spi_read_page_oob(struct qcom_nand_controller *snandc, -+ const struct spi_mem_op *op) -+{ -+ struct qpic_ecc *ecc_cfg = snandc->qspi->ecc; -+ u8 *data_buf = NULL, *data_buf_start, *oob_buf = NULL, *oob_buf_start; -+ int ret, i; -+ u32 cfg0, cfg1, ecc_bch_cfg, num_cw = snandc->qspi->num_cw; -+ -+ oob_buf = op->data.buf.in; -+ oob_buf_start = oob_buf; -+ -+ data_buf_start = data_buf; -+ -+ snandc->buf_count = 0; -+ snandc->buf_start = 0; -+ qcom_clear_read_regs(snandc); -+ qcom_clear_bam_transaction(snandc); -+ -+ cfg0 = (ecc_cfg->cfg0 & ~(7U << CW_PER_PAGE)) | -+ (num_cw - 1) << CW_PER_PAGE; -+ cfg1 = ecc_cfg->cfg1; -+ ecc_bch_cfg = ecc_cfg->ecc_bch_cfg; -+ -+ snandc->regs->addr0 = snandc->qspi->addr1; -+ snandc->regs->addr1 = snandc->qspi->addr2; -+ snandc->regs->cmd = snandc->qspi->cmd; -+ snandc->regs->cfg0 = cpu_to_le32(cfg0); -+ snandc->regs->cfg1 = cpu_to_le32(cfg1); -+ snandc->regs->ecc_bch_cfg = cpu_to_le32(ecc_bch_cfg); -+ snandc->regs->clrflashstatus = cpu_to_le32(ecc_cfg->clrflashstatus); -+ snandc->regs->clrreadstatus = cpu_to_le32(ecc_cfg->clrreadstatus); -+ snandc->regs->exec = cpu_to_le32(1); -+ -+ qcom_spi_set_read_loc(snandc, 0, 0, 0, ecc_cfg->cw_data, 1); -+ -+ qcom_write_reg_dma(snandc, &snandc->regs->addr0, NAND_ADDR0, 2, 0); -+ qcom_write_reg_dma(snandc, &snandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0); -+ qcom_write_reg_dma(snandc, &snandc->regs->erased_cw_detect_cfg_clr, -+ NAND_ERASED_CW_DETECT_CFG, 1, 0); -+ qcom_write_reg_dma(snandc, &snandc->regs->erased_cw_detect_cfg_set, -+ NAND_ERASED_CW_DETECT_CFG, 1, -+ NAND_ERASED_CW_SET | NAND_BAM_NEXT_SGL); -+ -+ for (i = 0; i < num_cw; i++) { -+ int data_size, oob_size; -+ -+ if (i == (num_cw - 1)) { -+ data_size = NANDC_STEP_SIZE - ((num_cw - 1) << 2); -+ oob_size = (num_cw << 2) + ecc_cfg->ecc_bytes_hw + -+ ecc_cfg->spare_bytes; -+ } else { -+ data_size = ecc_cfg->cw_data; -+ oob_size = ecc_cfg->ecc_bytes_hw + ecc_cfg->spare_bytes; -+ } -+ -+ qcom_spi_set_read_loc(snandc, i, 0, data_size, oob_size, 1); -+ -+ qcom_spi_config_cw_read(snandc, true, i); -+ -+ if (oob_buf) { -+ int j; -+ -+ for (j = 0; j < ecc_cfg->bbm_size; j++) -+ *oob_buf++ = 0xff; -+ -+ qcom_read_data_dma(snandc, FLASH_BUF_ACC + data_size, -+ oob_buf, oob_size, 0); -+ } -+ -+ if (oob_buf) -+ oob_buf += oob_size; -+ } -+ -+ ret = qcom_submit_descs(snandc); -+ if (ret) { -+ dev_err(snandc->dev, "failure to read oob\n"); -+ return ret; -+ } -+ -+ return qcom_spi_check_error(snandc, data_buf_start, oob_buf_start); -+} -+ -+static int qcom_spi_read_page(struct qcom_nand_controller *snandc, -+ const struct spi_mem_op *op) -+{ -+ if (snandc->qspi->page_rw && snandc->qspi->raw_rw) -+ return qcom_spi_read_page_raw(snandc, op); -+ -+ if (snandc->qspi->page_rw) -+ return qcom_spi_read_page_ecc(snandc, op); -+ -+ if (snandc->qspi->oob_rw && snandc->qspi->raw_rw) -+ return qcom_spi_read_last_cw(snandc, op); -+ -+ if (snandc->qspi->oob_rw) -+ return qcom_spi_read_page_oob(snandc, op); -+ -+ return 0; -+} -+ -+static void qcom_spi_config_page_write(struct qcom_nand_controller *snandc) -+{ -+ qcom_write_reg_dma(snandc, &snandc->regs->addr0, NAND_ADDR0, 2, 0); -+ qcom_write_reg_dma(snandc, &snandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0); -+ qcom_write_reg_dma(snandc, &snandc->regs->ecc_buf_cfg, NAND_EBI2_ECC_BUF_CFG, -+ 1, NAND_BAM_NEXT_SGL); -+} -+ -+static void qcom_spi_config_cw_write(struct qcom_nand_controller *snandc) -+{ -+ qcom_write_reg_dma(snandc, &snandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL); -+ qcom_write_reg_dma(snandc, &snandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); -+ qcom_read_reg_dma(snandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL); -+ -+ qcom_write_reg_dma(snandc, &snandc->regs->clrflashstatus, NAND_FLASH_STATUS, 1, 0); -+ qcom_write_reg_dma(snandc, &snandc->regs->clrreadstatus, NAND_READ_STATUS, 1, -+ NAND_BAM_NEXT_SGL); -+} -+ -+static int qcom_spi_program_raw(struct qcom_nand_controller *snandc, -+ const struct spi_mem_op *op) -+{ -+ struct qpic_ecc *ecc_cfg = snandc->qspi->ecc; -+ struct mtd_info *mtd = snandc->qspi->mtd; -+ u8 *data_buf = NULL, *oob_buf = NULL; -+ int i, ret; -+ int num_cw = snandc->qspi->num_cw; -+ u32 cfg0, cfg1, ecc_bch_cfg; -+ -+ cfg0 = (ecc_cfg->cfg0_raw & ~(7U << CW_PER_PAGE)) | -+ (num_cw - 1) << CW_PER_PAGE; -+ cfg1 = ecc_cfg->cfg1_raw; -+ ecc_bch_cfg = ECC_CFG_ECC_DISABLE; -+ -+ data_buf = snandc->qspi->data_buf; -+ -+ oob_buf = snandc->qspi->oob_buf; -+ memset(oob_buf, 0xff, OOB_BUF_SIZE); -+ -+ snandc->buf_count = 0; -+ snandc->buf_start = 0; -+ qcom_clear_read_regs(snandc); -+ qcom_clear_bam_transaction(snandc); -+ -+ snandc->regs->addr0 = snandc->qspi->addr1; -+ snandc->regs->addr1 = snandc->qspi->addr2; -+ snandc->regs->cmd = snandc->qspi->cmd; -+ snandc->regs->cfg0 = cpu_to_le32(cfg0); -+ snandc->regs->cfg1 = cpu_to_le32(cfg1); -+ snandc->regs->ecc_bch_cfg = cpu_to_le32(ecc_bch_cfg); -+ snandc->regs->clrflashstatus = cpu_to_le32(ecc_cfg->clrflashstatus); -+ snandc->regs->clrreadstatus = cpu_to_le32(ecc_cfg->clrreadstatus); -+ snandc->regs->exec = cpu_to_le32(1); -+ -+ qcom_spi_config_page_write(snandc); -+ -+ for (i = 0; i < num_cw; i++) { -+ int data_size1, data_size2, oob_size1, oob_size2; -+ int reg_off = FLASH_BUF_ACC; -+ -+ data_size1 = mtd->writesize - ecc_cfg->cw_size * (num_cw - 1); -+ oob_size1 = ecc_cfg->bbm_size; -+ -+ if (i == (num_cw - 1)) { -+ data_size2 = NANDC_STEP_SIZE - data_size1 - -+ ((num_cw - 1) << 2); -+ oob_size2 = (num_cw << 2) + ecc_cfg->ecc_bytes_hw + -+ ecc_cfg->spare_bytes; -+ } else { -+ data_size2 = ecc_cfg->cw_data - data_size1; -+ oob_size2 = ecc_cfg->ecc_bytes_hw + ecc_cfg->spare_bytes; -+ } -+ -+ qcom_write_data_dma(snandc, reg_off, data_buf, data_size1, -+ NAND_BAM_NO_EOT); -+ reg_off += data_size1; -+ data_buf += data_size1; -+ -+ qcom_write_data_dma(snandc, reg_off, oob_buf, oob_size1, -+ NAND_BAM_NO_EOT); -+ oob_buf += oob_size1; -+ reg_off += oob_size1; -+ -+ qcom_write_data_dma(snandc, reg_off, data_buf, data_size2, -+ NAND_BAM_NO_EOT); -+ reg_off += data_size2; -+ data_buf += data_size2; -+ -+ qcom_write_data_dma(snandc, reg_off, oob_buf, oob_size2, 0); -+ oob_buf += oob_size2; -+ -+ qcom_spi_config_cw_write(snandc); -+ } -+ -+ ret = qcom_submit_descs(snandc); -+ if (ret) { -+ dev_err(snandc->dev, "failure to write raw page\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int qcom_spi_program_ecc(struct qcom_nand_controller *snandc, -+ const struct spi_mem_op *op) -+{ -+ struct qpic_ecc *ecc_cfg = snandc->qspi->ecc; -+ u8 *data_buf = NULL, *oob_buf = NULL; -+ int i, ret; -+ int num_cw = snandc->qspi->num_cw; -+ u32 cfg0, cfg1, ecc_bch_cfg, ecc_buf_cfg; -+ -+ cfg0 = (ecc_cfg->cfg0 & ~(7U << CW_PER_PAGE)) | -+ (num_cw - 1) << CW_PER_PAGE; -+ cfg1 = ecc_cfg->cfg1; -+ ecc_bch_cfg = ecc_cfg->ecc_bch_cfg; -+ ecc_buf_cfg = ecc_cfg->ecc_buf_cfg; -+ -+ if (snandc->qspi->data_buf) -+ data_buf = snandc->qspi->data_buf; -+ -+ oob_buf = snandc->qspi->oob_buf; -+ -+ snandc->buf_count = 0; -+ snandc->buf_start = 0; -+ qcom_clear_read_regs(snandc); -+ qcom_clear_bam_transaction(snandc); -+ -+ snandc->regs->addr0 = snandc->qspi->addr1; -+ snandc->regs->addr1 = snandc->qspi->addr2; -+ snandc->regs->cmd = snandc->qspi->cmd; -+ snandc->regs->cfg0 = cpu_to_le32(cfg0); -+ snandc->regs->cfg1 = cpu_to_le32(cfg1); -+ snandc->regs->ecc_bch_cfg = cpu_to_le32(ecc_bch_cfg); -+ snandc->regs->ecc_buf_cfg = cpu_to_le32(ecc_buf_cfg); -+ snandc->regs->exec = cpu_to_le32(1); -+ -+ qcom_spi_config_page_write(snandc); -+ -+ for (i = 0; i < num_cw; i++) { -+ int data_size, oob_size; -+ -+ if (i == (num_cw - 1)) { -+ data_size = NANDC_STEP_SIZE - ((num_cw - 1) << 2); -+ oob_size = (num_cw << 2) + ecc_cfg->ecc_bytes_hw + -+ ecc_cfg->spare_bytes; -+ } else { -+ data_size = ecc_cfg->cw_data; -+ oob_size = ecc_cfg->bytes; -+ } -+ -+ if (data_buf) -+ qcom_write_data_dma(snandc, FLASH_BUF_ACC, data_buf, data_size, -+ i == (num_cw - 1) ? NAND_BAM_NO_EOT : 0); -+ -+ if (i == (num_cw - 1)) { -+ if (oob_buf) { -+ oob_buf += ecc_cfg->bbm_size; -+ qcom_write_data_dma(snandc, FLASH_BUF_ACC + data_size, -+ oob_buf, oob_size, 0); -+ } -+ } -+ -+ qcom_spi_config_cw_write(snandc); -+ -+ if (data_buf) -+ data_buf += data_size; -+ if (oob_buf) -+ oob_buf += oob_size; -+ } -+ -+ ret = qcom_submit_descs(snandc); -+ if (ret) { -+ dev_err(snandc->dev, "failure to write page\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int qcom_spi_program_oob(struct qcom_nand_controller *snandc, -+ const struct spi_mem_op *op) -+{ -+ struct qpic_ecc *ecc_cfg = snandc->qspi->ecc; -+ u8 *oob_buf = NULL; -+ int ret, col, data_size, oob_size; -+ int num_cw = snandc->qspi->num_cw; -+ u32 cfg0, cfg1, ecc_bch_cfg, ecc_buf_cfg; -+ -+ cfg0 = (ecc_cfg->cfg0 & ~(7U << CW_PER_PAGE)) | -+ (num_cw - 1) << CW_PER_PAGE; -+ cfg1 = ecc_cfg->cfg1; -+ ecc_bch_cfg = ecc_cfg->ecc_bch_cfg; -+ ecc_buf_cfg = ecc_cfg->ecc_buf_cfg; -+ -+ col = ecc_cfg->cw_size * (num_cw - 1); -+ -+ oob_buf = snandc->qspi->data_buf; -+ -+ snandc->buf_count = 0; -+ snandc->buf_start = 0; -+ qcom_clear_read_regs(snandc); -+ qcom_clear_bam_transaction(snandc); -+ snandc->regs->addr0 = (snandc->qspi->addr1 | cpu_to_le32(col)); -+ snandc->regs->addr1 = snandc->qspi->addr2; -+ snandc->regs->cmd = snandc->qspi->cmd; -+ snandc->regs->cfg0 = cpu_to_le32(cfg0); -+ snandc->regs->cfg1 = cpu_to_le32(cfg1); -+ snandc->regs->ecc_bch_cfg = cpu_to_le32(ecc_bch_cfg); -+ snandc->regs->ecc_buf_cfg = cpu_to_le32(ecc_buf_cfg); -+ snandc->regs->exec = cpu_to_le32(1); -+ -+ /* calculate the data and oob size for the last codeword/step */ -+ data_size = NANDC_STEP_SIZE - ((num_cw - 1) << 2); -+ oob_size = snandc->qspi->mtd->oobavail; -+ -+ memset(snandc->data_buffer, 0xff, ecc_cfg->cw_data); -+ /* override new oob content to last codeword */ -+ mtd_ooblayout_get_databytes(snandc->qspi->mtd, snandc->data_buffer + data_size, -+ oob_buf, 0, snandc->qspi->mtd->oobavail); -+ qcom_spi_config_page_write(snandc); -+ qcom_write_data_dma(snandc, FLASH_BUF_ACC, snandc->data_buffer, data_size + oob_size, 0); -+ qcom_spi_config_cw_write(snandc); -+ -+ ret = qcom_submit_descs(snandc); -+ if (ret) { -+ dev_err(snandc->dev, "failure to write oob\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int qcom_spi_program_execute(struct qcom_nand_controller *snandc, -+ const struct spi_mem_op *op) -+{ -+ if (snandc->qspi->page_rw && snandc->qspi->raw_rw) -+ return qcom_spi_program_raw(snandc, op); -+ -+ if (snandc->qspi->page_rw) -+ return qcom_spi_program_ecc(snandc, op); -+ -+ if (snandc->qspi->oob_rw) -+ return qcom_spi_program_oob(snandc, op); -+ -+ return 0; -+} -+ -+static int qcom_spi_cmd_mapping(struct qcom_nand_controller *snandc, u32 opcode, u32 *cmd) -+{ -+ switch (opcode) { -+ case SPINAND_RESET: -+ *cmd = (SPI_WP | SPI_HOLD | SPI_TRANSFER_MODE_x1 | OP_RESET_DEVICE); -+ break; -+ case SPINAND_READID: -+ *cmd = (SPI_WP | SPI_HOLD | SPI_TRANSFER_MODE_x1 | OP_FETCH_ID); -+ break; -+ case SPINAND_GET_FEATURE: -+ *cmd = (SPI_TRANSFER_MODE_x1 | SPI_WP | SPI_HOLD | ACC_FEATURE); -+ break; -+ case SPINAND_SET_FEATURE: -+ *cmd = (SPI_TRANSFER_MODE_x1 | SPI_WP | SPI_HOLD | ACC_FEATURE | -+ QPIC_SET_FEATURE); -+ break; -+ case SPINAND_READ: -+ if (snandc->qspi->raw_rw) { -+ *cmd = (PAGE_ACC | LAST_PAGE | SPI_TRANSFER_MODE_x1 | -+ SPI_WP | SPI_HOLD | OP_PAGE_READ); -+ } else { -+ *cmd = (PAGE_ACC | LAST_PAGE | SPI_TRANSFER_MODE_x1 | -+ SPI_WP | SPI_HOLD | OP_PAGE_READ_WITH_ECC); -+ } -+ -+ break; -+ case SPINAND_ERASE: -+ *cmd = OP_BLOCK_ERASE | PAGE_ACC | LAST_PAGE | SPI_WP | -+ SPI_HOLD | SPI_TRANSFER_MODE_x1; -+ break; -+ case SPINAND_WRITE_EN: -+ *cmd = SPINAND_WRITE_EN; -+ break; -+ case SPINAND_PROGRAM_EXECUTE: -+ *cmd = (PAGE_ACC | LAST_PAGE | SPI_TRANSFER_MODE_x1 | -+ SPI_WP | SPI_HOLD | OP_PROGRAM_PAGE); -+ break; -+ case SPINAND_PROGRAM_LOAD: -+ *cmd = SPINAND_PROGRAM_LOAD; -+ break; -+ default: -+ dev_err(snandc->dev, "Opcode not supported: %u\n", opcode); -+ return -EOPNOTSUPP; -+ } -+ -+ return 0; -+} -+ -+static int qcom_spi_write_page(struct qcom_nand_controller *snandc, -+ const struct spi_mem_op *op) -+{ -+ int ret; -+ u32 cmd; -+ -+ ret = qcom_spi_cmd_mapping(snandc, op->cmd.opcode, &cmd); -+ if (ret < 0) -+ return ret; -+ -+ if (op->cmd.opcode == SPINAND_PROGRAM_LOAD) -+ snandc->qspi->data_buf = (u8 *)op->data.buf.out; -+ -+ return 0; -+} -+ -+static int qcom_spi_send_cmdaddr(struct qcom_nand_controller *snandc, -+ const struct spi_mem_op *op) -+{ -+ struct qpic_snand_op s_op = {}; -+ u32 cmd; -+ int ret, opcode; -+ -+ ret = qcom_spi_cmd_mapping(snandc, op->cmd.opcode, &cmd); -+ if (ret < 0) -+ return ret; -+ -+ s_op.cmd_reg = cmd; -+ s_op.addr1_reg = op->addr.val; -+ s_op.addr2_reg = 0; -+ -+ opcode = op->cmd.opcode; -+ -+ switch (opcode) { -+ case SPINAND_WRITE_EN: -+ return 0; -+ case SPINAND_PROGRAM_EXECUTE: -+ s_op.addr1_reg = op->addr.val << 16; -+ s_op.addr2_reg = op->addr.val >> 16 & 0xff; -+ snandc->qspi->addr1 = cpu_to_le32(s_op.addr1_reg); -+ snandc->qspi->addr2 = cpu_to_le32(s_op.addr2_reg); -+ snandc->qspi->cmd = cpu_to_le32(cmd); -+ return qcom_spi_program_execute(snandc, op); -+ case SPINAND_READ: -+ s_op.addr1_reg = (op->addr.val << 16); -+ s_op.addr2_reg = op->addr.val >> 16 & 0xff; -+ snandc->qspi->addr1 = cpu_to_le32(s_op.addr1_reg); -+ snandc->qspi->addr2 = cpu_to_le32(s_op.addr2_reg); -+ snandc->qspi->cmd = cpu_to_le32(cmd); -+ return 0; -+ case SPINAND_ERASE: -+ s_op.addr2_reg = (op->addr.val >> 16) & 0xffff; -+ s_op.addr1_reg = op->addr.val; -+ snandc->qspi->addr1 = cpu_to_le32(s_op.addr1_reg << 16); -+ snandc->qspi->addr2 = cpu_to_le32(s_op.addr2_reg); -+ snandc->qspi->cmd = cpu_to_le32(cmd); -+ qcom_spi_block_erase(snandc); -+ return 0; -+ default: -+ break; -+ } -+ -+ snandc->buf_count = 0; -+ snandc->buf_start = 0; -+ qcom_clear_read_regs(snandc); -+ qcom_clear_bam_transaction(snandc); -+ -+ snandc->regs->cmd = cpu_to_le32(s_op.cmd_reg); -+ snandc->regs->exec = cpu_to_le32(1); -+ snandc->regs->addr0 = cpu_to_le32(s_op.addr1_reg); -+ snandc->regs->addr1 = cpu_to_le32(s_op.addr2_reg); -+ -+ qcom_write_reg_dma(snandc, &snandc->regs->cmd, NAND_FLASH_CMD, 3, NAND_BAM_NEXT_SGL); -+ qcom_write_reg_dma(snandc, &snandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); -+ -+ ret = qcom_submit_descs(snandc); -+ if (ret) -+ dev_err(snandc->dev, "failure in submitting cmd descriptor\n"); -+ -+ return ret; -+} -+ -+static int qcom_spi_io_op(struct qcom_nand_controller *snandc, const struct spi_mem_op *op) -+{ -+ int ret, val, opcode; -+ bool copy = false, copy_ftr = false; -+ -+ ret = qcom_spi_send_cmdaddr(snandc, op); -+ if (ret) -+ return ret; -+ -+ snandc->buf_count = 0; -+ snandc->buf_start = 0; -+ qcom_clear_read_regs(snandc); -+ qcom_clear_bam_transaction(snandc); -+ opcode = op->cmd.opcode; -+ -+ switch (opcode) { -+ case SPINAND_READID: -+ snandc->buf_count = 4; -+ qcom_read_reg_dma(snandc, NAND_READ_ID, 1, NAND_BAM_NEXT_SGL); -+ copy = true; -+ break; -+ case SPINAND_GET_FEATURE: -+ snandc->buf_count = 4; -+ qcom_read_reg_dma(snandc, NAND_FLASH_FEATURES, 1, NAND_BAM_NEXT_SGL); -+ copy_ftr = true; -+ break; -+ case SPINAND_SET_FEATURE: -+ snandc->regs->flash_feature = cpu_to_le32(*(u32 *)op->data.buf.out); -+ qcom_write_reg_dma(snandc, &snandc->regs->flash_feature, -+ NAND_FLASH_FEATURES, 1, NAND_BAM_NEXT_SGL); -+ break; -+ case SPINAND_PROGRAM_EXECUTE: -+ case SPINAND_WRITE_EN: -+ case SPINAND_RESET: -+ case SPINAND_ERASE: -+ case SPINAND_READ: -+ return 0; -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ ret = qcom_submit_descs(snandc); -+ if (ret) -+ dev_err(snandc->dev, "failure in submitting descriptor for:%d\n", opcode); -+ -+ if (copy) { -+ qcom_nandc_dev_to_mem(snandc, true); -+ memcpy(op->data.buf.in, snandc->reg_read_buf, snandc->buf_count); -+ } -+ -+ if (copy_ftr) { -+ qcom_nandc_dev_to_mem(snandc, true); -+ val = le32_to_cpu(*(__le32 *)snandc->reg_read_buf); -+ val >>= 8; -+ memcpy(op->data.buf.in, &val, snandc->buf_count); -+ } -+ -+ return ret; -+} -+ -+static bool qcom_spi_is_page_op(const struct spi_mem_op *op) -+{ -+ if (op->addr.buswidth != 1 && op->addr.buswidth != 2 && op->addr.buswidth != 4) -+ return false; -+ -+ if (op->data.dir == SPI_MEM_DATA_IN) { -+ if (op->addr.buswidth == 4 && op->data.buswidth == 4) -+ return true; -+ -+ if (op->addr.nbytes == 2 && op->addr.buswidth == 1) -+ return true; -+ -+ } else if (op->data.dir == SPI_MEM_DATA_OUT) { -+ if (op->data.buswidth == 4) -+ return true; -+ if (op->addr.nbytes == 2 && op->addr.buswidth == 1) -+ return true; -+ } -+ -+ return false; -+} -+ -+static bool qcom_spi_supports_op(struct spi_mem *mem, const struct spi_mem_op *op) -+{ -+ if (!spi_mem_default_supports_op(mem, op)) -+ return false; -+ -+ if (op->cmd.nbytes != 1 || op->cmd.buswidth != 1) -+ return false; -+ -+ if (qcom_spi_is_page_op(op)) -+ return true; -+ -+ return ((!op->addr.nbytes || op->addr.buswidth == 1) && -+ (!op->dummy.nbytes || op->dummy.buswidth == 1) && -+ (!op->data.nbytes || op->data.buswidth == 1)); -+} -+ -+static int qcom_spi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) -+{ -+ struct qcom_nand_controller *snandc = spi_controller_get_devdata(mem->spi->controller); -+ -+ dev_dbg(snandc->dev, "OP %02x ADDR %08llX@%d:%u DATA %d:%u", op->cmd.opcode, -+ op->addr.val, op->addr.buswidth, op->addr.nbytes, -+ op->data.buswidth, op->data.nbytes); -+ -+ if (qcom_spi_is_page_op(op)) { -+ if (op->data.dir == SPI_MEM_DATA_IN) -+ return qcom_spi_read_page(snandc, op); -+ if (op->data.dir == SPI_MEM_DATA_OUT) -+ return qcom_spi_write_page(snandc, op); -+ } else { -+ return qcom_spi_io_op(snandc, op); -+ } -+ -+ return 0; -+} -+ -+static const struct spi_controller_mem_ops qcom_spi_mem_ops = { -+ .supports_op = qcom_spi_supports_op, -+ .exec_op = qcom_spi_exec_op, -+}; -+ -+static const struct spi_controller_mem_caps qcom_spi_mem_caps = { -+ .ecc = true, -+}; -+ -+static int qcom_spi_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct spi_controller *ctlr; -+ struct qcom_nand_controller *snandc; -+ struct qpic_spi_nand *qspi; -+ struct qpic_ecc *ecc; -+ struct resource *res; -+ const void *dev_data; -+ int ret; -+ -+ ecc = devm_kzalloc(dev, sizeof(*ecc), GFP_KERNEL); -+ if (!ecc) -+ return -ENOMEM; -+ -+ qspi = devm_kzalloc(dev, sizeof(*qspi), GFP_KERNEL); -+ if (!qspi) -+ return -ENOMEM; -+ -+ ctlr = __devm_spi_alloc_controller(dev, sizeof(*snandc), false); -+ if (!ctlr) -+ return -ENOMEM; -+ -+ platform_set_drvdata(pdev, ctlr); -+ -+ snandc = spi_controller_get_devdata(ctlr); -+ qspi->snandc = snandc; -+ -+ snandc->dev = dev; -+ snandc->qspi = qspi; -+ snandc->qspi->ctlr = ctlr; -+ snandc->qspi->ecc = ecc; -+ -+ dev_data = of_device_get_match_data(dev); -+ if (!dev_data) { -+ dev_err(&pdev->dev, "failed to get device data\n"); -+ return -ENODEV; -+ } -+ -+ snandc->props = dev_data; -+ snandc->dev = &pdev->dev; -+ -+ snandc->core_clk = devm_clk_get(dev, "core"); -+ if (IS_ERR(snandc->core_clk)) -+ return PTR_ERR(snandc->core_clk); -+ -+ snandc->aon_clk = devm_clk_get(dev, "aon"); -+ if (IS_ERR(snandc->aon_clk)) -+ return PTR_ERR(snandc->aon_clk); -+ -+ snandc->qspi->iomacro_clk = devm_clk_get(dev, "iom"); -+ if (IS_ERR(snandc->qspi->iomacro_clk)) -+ return PTR_ERR(snandc->qspi->iomacro_clk); -+ -+ snandc->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); -+ if (IS_ERR(snandc->base)) -+ return PTR_ERR(snandc->base); -+ -+ snandc->base_phys = res->start; -+ snandc->base_dma = dma_map_resource(dev, res->start, resource_size(res), -+ DMA_BIDIRECTIONAL, 0); -+ if (dma_mapping_error(dev, snandc->base_dma)) -+ return -ENXIO; -+ -+ ret = clk_prepare_enable(snandc->core_clk); -+ if (ret) -+ goto err_dis_core_clk; -+ -+ ret = clk_prepare_enable(snandc->aon_clk); -+ if (ret) -+ goto err_dis_aon_clk; -+ -+ ret = clk_prepare_enable(snandc->qspi->iomacro_clk); -+ if (ret) -+ goto err_dis_iom_clk; -+ -+ ret = qcom_nandc_alloc(snandc); -+ if (ret) -+ goto err_snand_alloc; -+ -+ ret = qcom_spi_init(snandc); -+ if (ret) -+ goto err_spi_init; -+ -+ /* setup ECC engine */ -+ snandc->qspi->ecc_eng.dev = &pdev->dev; -+ snandc->qspi->ecc_eng.integration = NAND_ECC_ENGINE_INTEGRATION_PIPELINED; -+ snandc->qspi->ecc_eng.ops = &qcom_spi_ecc_engine_ops_pipelined; -+ snandc->qspi->ecc_eng.priv = snandc; -+ -+ ret = nand_ecc_register_on_host_hw_engine(&snandc->qspi->ecc_eng); -+ if (ret) { -+ dev_err(&pdev->dev, "failed to register ecc engine:%d\n", ret); -+ goto err_spi_init; -+ } -+ -+ ctlr->num_chipselect = QPIC_QSPI_NUM_CS; -+ ctlr->mem_ops = &qcom_spi_mem_ops; -+ ctlr->mem_caps = &qcom_spi_mem_caps; -+ ctlr->dev.of_node = pdev->dev.of_node; -+ ctlr->mode_bits = SPI_TX_DUAL | SPI_RX_DUAL | -+ SPI_TX_QUAD | SPI_RX_QUAD; -+ -+ ret = spi_register_controller(ctlr); -+ if (ret) { -+ dev_err(&pdev->dev, "spi_register_controller failed.\n"); -+ goto err_spi_init; -+ } -+ -+ return 0; -+ -+err_spi_init: -+ qcom_nandc_unalloc(snandc); -+err_snand_alloc: -+ clk_disable_unprepare(snandc->qspi->iomacro_clk); -+err_dis_iom_clk: -+ clk_disable_unprepare(snandc->aon_clk); -+err_dis_aon_clk: -+ clk_disable_unprepare(snandc->core_clk); -+err_dis_core_clk: -+ dma_unmap_resource(dev, res->start, resource_size(res), -+ DMA_BIDIRECTIONAL, 0); -+ return ret; -+} -+ -+static void qcom_spi_remove(struct platform_device *pdev) -+{ -+ struct spi_controller *ctlr = platform_get_drvdata(pdev); -+ struct qcom_nand_controller *snandc = spi_controller_get_devdata(ctlr); -+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ -+ spi_unregister_controller(ctlr); -+ -+ qcom_nandc_unalloc(snandc); -+ -+ clk_disable_unprepare(snandc->aon_clk); -+ clk_disable_unprepare(snandc->core_clk); -+ clk_disable_unprepare(snandc->qspi->iomacro_clk); -+ -+ dma_unmap_resource(&pdev->dev, snandc->base_dma, resource_size(res), -+ DMA_BIDIRECTIONAL, 0); -+} -+ -+static const struct qcom_nandc_props ipq9574_snandc_props = { -+ .dev_cmd_reg_start = 0x7000, -+ .supports_bam = true, -+}; -+ -+static const struct of_device_id qcom_snandc_of_match[] = { -+ { -+ .compatible = "qcom,ipq9574-snand", -+ .data = &ipq9574_snandc_props, -+ }, -+ {} -+} -+MODULE_DEVICE_TABLE(of, qcom_snandc_of_match); -+ -+static struct platform_driver qcom_spi_driver = { -+ .driver = { -+ .name = "qcom_snand", -+ .of_match_table = qcom_snandc_of_match, -+ }, -+ .probe = qcom_spi_probe, -+ .remove_new = qcom_spi_remove, -+}; -+module_platform_driver(qcom_spi_driver); -+ -+MODULE_DESCRIPTION("SPI driver for QPIC QSPI cores"); -+MODULE_AUTHOR("Md Sadre Alam "); -+MODULE_LICENSE("GPL"); -+ -diff --git a/include/linux/mtd/nand-qpic-common.h b/include/linux/mtd/nand-qpic-common.h -index 4d9b736ff8b7..7760154de581 100644 ---- a/include/linux/mtd/nand-qpic-common.h -+++ b/include/linux/mtd/nand-qpic-common.h -@@ -325,6 +325,10 @@ struct nandc_regs { - __le32 read_location_last1; - __le32 read_location_last2; - __le32 read_location_last3; -+ __le32 spi_cfg; -+ __le32 num_addr_cycle; -+ __le32 busy_wait_cnt; -+ __le32 flash_feature; - - __le32 erased_cw_detect_cfg_clr; - __le32 erased_cw_detect_cfg_set; -@@ -339,6 +343,7 @@ struct nandc_regs { - * - * @core_clk: controller clock - * @aon_clk: another controller clock -+ * @iomacro_clk: io macro clock - * - * @regs: a contiguous chunk of memory for DMA register - * writes. contains the register values to be -@@ -348,6 +353,7 @@ struct nandc_regs { - * initialized via DT match data - * - * @controller: base controller structure -+ * @qspi: qpic spi structure - * @host_list: list containing all the chips attached to the - * controller - * -@@ -392,6 +398,7 @@ struct qcom_nand_controller { - const struct qcom_nandc_props *props; - - struct nand_controller *controller; -+ struct qpic_spi_nand *qspi; - struct list_head host_list; - - union { --- -2.51.0 - - -From 5f4a73da9c92fc7c87503e7865997fb54a39783c Mon Sep 17 00:00:00 2001 -From: Dan Carpenter -Date: Thu, 6 Mar 2025 12:40:01 +0300 -Subject: [PATCH 017/517] spi: spi-qpic-snand: Fix ECC_CFG_ECC_DISABLE shift in - qcom_spi_read_last_cw() - -The ECC_CFG_ECC_DISABLE define is BIT(0). It's supposed to be used -directly instead of used as a shifter. - -Fixes: 7304d1909080 ("spi: spi-qpic: add driver for QCOM SPI NAND flash Interface") -Signed-off-by: Dan Carpenter -Link: https://patch.msgid.link/2f4b0a0b-2c03-41c0-8a4a-3d789a83832d@stanley.mountain -Signed-off-by: Mark Brown ---- - drivers/spi/spi-qpic-snand.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/spi/spi-qpic-snand.c b/drivers/spi/spi-qpic-snand.c -index 1a4746d0fd62..d7a43ed5e304 100644 ---- a/drivers/spi/spi-qpic-snand.c -+++ b/drivers/spi/spi-qpic-snand.c -@@ -514,7 +514,7 @@ static int qcom_spi_read_last_cw(struct qcom_nand_controller *snandc, - cfg0 = (ecc_cfg->cfg0_raw & ~(7U << CW_PER_PAGE)) | - 0 << CW_PER_PAGE; - cfg1 = ecc_cfg->cfg1_raw; -- ecc_bch_cfg = 1 << ECC_CFG_ECC_DISABLE; -+ ecc_bch_cfg = ECC_CFG_ECC_DISABLE; - - snandc->regs->cmd = snandc->qspi->cmd; - snandc->regs->cfg0 = cpu_to_le32(cfg0); --- -2.51.0 - - -From 619c0af9a03bdca0c0346277ba75b1d42c4d6f04 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Thu, 13 Mar 2025 19:31:21 +0100 -Subject: [PATCH 018/517] spi: spi-qpic-snand: avoid memleak in - qcom_spi_ecc_init_ctx_pipelined() - -When the allocation of the OOB buffer fails, the -qcom_spi_ecc_init_ctx_pipelined() function returns without freeing -the memory allocated for 'ecc_cfg' thus it can cause a memory leak. - -Call kfree() to free 'ecc_cfg' before returning from the function -to avoid that. - -Fixes: 7304d1909080 ("spi: spi-qpic: add driver for QCOM SPI NAND flash Interface") -Signed-off-by: Gabor Juhos -Link: https://patch.msgid.link/20250313-qpic-snand-memleak-fix-v1-1-e54e78d1da3a@gmail.com -Signed-off-by: Mark Brown ---- - drivers/spi/spi-qpic-snand.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/drivers/spi/spi-qpic-snand.c b/drivers/spi/spi-qpic-snand.c -index d7a43ed5e304..3b8020f37f97 100644 ---- a/drivers/spi/spi-qpic-snand.c -+++ b/drivers/spi/spi-qpic-snand.c -@@ -263,8 +263,10 @@ static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand) - return -ENOMEM; - snandc->qspi->oob_buf = kzalloc(mtd->writesize + mtd->oobsize, - GFP_KERNEL); -- if (!snandc->qspi->oob_buf) -+ if (!snandc->qspi->oob_buf) { -+ kfree(ecc_cfg); - return -ENOMEM; -+ } - - memset(snandc->qspi->oob_buf, 0xff, mtd->writesize + mtd->oobsize); - --- -2.51.0 - - -From 420047e7ae6f00cf8aa3e6d37b679f63390f586b Mon Sep 17 00:00:00 2001 -From: Geert Uytterhoeven -Date: Wed, 26 Mar 2025 15:22:19 +0100 -Subject: [PATCH 019/517] spi: SPI_QPIC_SNAND should be tristate and depend on - MTD - -SPI_QPIC_SNAND is the only driver that selects MTD instead of depending -on it, which could lead to circular dependencies. Moreover, as -SPI_QPIC_SNAND is bool, this forces MTD (and various related symbols) to -be built-in, as can be seen in an allmodconfig kernel. - -Except for a missing semicolon, there is no reason why SPI_QPIC_SNAND -cannot be tristate; all MODULE_*() boilerplate is already present. -Hence make SPI_QPIC_SNAND tristate, let it depend on MTD, and add the -missing semicolon. - -Fixes: 7304d1909080ef0c ("spi: spi-qpic: add driver for QCOM SPI NAND flash Interface") -Signed-off-by: Geert Uytterhoeven -Link: https://patch.msgid.link/b63db431cbf35223a4400e44c296293d32c4543c.1742998909.git.geert+renesas@glider.be -Signed-off-by: Mark Brown ---- - drivers/spi/Kconfig | 4 ++-- - drivers/spi/spi-qpic-snand.c | 2 +- - 2 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig -index 98c5fa460fb1..712cf74a73d9 100644 ---- a/drivers/spi/Kconfig -+++ b/drivers/spi/Kconfig -@@ -899,9 +899,9 @@ config SPI_QCOM_QSPI - QSPI(Quad SPI) driver for Qualcomm QSPI controller. - - config SPI_QPIC_SNAND -- bool "QPIC SNAND controller" -+ tristate "QPIC SNAND controller" - depends on ARCH_QCOM || COMPILE_TEST -- select MTD -+ depends on MTD - help - QPIC_SNAND (QPIC SPI NAND) driver for Qualcomm QPIC controller. - QPIC controller supports both parallel nand and serial nand. -diff --git a/drivers/spi/spi-qpic-snand.c b/drivers/spi/spi-qpic-snand.c -index 3b8020f37f97..10ce98bcacef 100644 ---- a/drivers/spi/spi-qpic-snand.c -+++ b/drivers/spi/spi-qpic-snand.c -@@ -1614,7 +1614,7 @@ static const struct of_device_id qcom_snandc_of_match[] = { - .data = &ipq9574_snandc_props, - }, - {} --} -+}; - MODULE_DEVICE_TABLE(of, qcom_snandc_of_match); - - static struct platform_driver qcom_spi_driver = { --- -2.51.0 - - -From 4c2cc0b314a1f1635b9e563add9ef8b5f99fd4f3 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Wed, 23 Apr 2025 21:31:57 +0200 -Subject: [PATCH 020/517] spi: spi-qpic-snand: propagate errors from - qcom_spi_block_erase() - -The qcom_spi_block_erase() function returns with error in case of -failure. Change the qcom_spi_send_cmdaddr() function to propagate -these errors to the callers instead of returning with success. - -Fixes: 7304d1909080 ("spi: spi-qpic: add driver for QCOM SPI NAND flash Interface") -Signed-off-by: Gabor Juhos -Reviewed-by: Abel Vesa -Reviewed-by: Md Sadre Alam ---- - drivers/spi/spi-qpic-snand.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/drivers/spi/spi-qpic-snand.c b/drivers/spi/spi-qpic-snand.c -index 10ce98bcacef..4f08cd0e41cc 100644 ---- a/drivers/spi/spi-qpic-snand.c -+++ b/drivers/spi/spi-qpic-snand.c -@@ -1307,8 +1307,7 @@ static int qcom_spi_send_cmdaddr(struct qcom_nand_controller *snandc, - snandc->qspi->addr1 = cpu_to_le32(s_op.addr1_reg << 16); - snandc->qspi->addr2 = cpu_to_le32(s_op.addr2_reg); - snandc->qspi->cmd = cpu_to_le32(cmd); -- qcom_spi_block_erase(snandc); -- return 0; -+ return qcom_spi_block_erase(snandc); - default: - break; - } --- -2.51.0 - - -From 3a06d824412d2e8082d82f9f527b7b805e849a33 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Mon, 28 Apr 2025 09:30:55 +0200 -Subject: [PATCH 021/517] spi: spi-qpic-snand: fix NAND_READ_LOCATION_2 - register handling - -The precomputed value for the NAND_READ_LOCATION_2 register should be -stored in 'snandc->regs->read_location2'. - -Fix the qcom_spi_set_read_loc_first() function accordingly. - -Fixes: 7304d1909080 ("spi: spi-qpic: add driver for QCOM SPI NAND flash Interface") -Signed-off-by: Gabor Juhos -Reviewed-by: Md Sadre Alam ---- - drivers/spi/spi-qpic-snand.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/spi/spi-qpic-snand.c b/drivers/spi/spi-qpic-snand.c -index 4f08cd0e41cc..f01f9517c15d 100644 ---- a/drivers/spi/spi-qpic-snand.c -+++ b/drivers/spi/spi-qpic-snand.c -@@ -142,7 +142,7 @@ static void qcom_spi_set_read_loc_first(struct qcom_nand_controller *snandc, - else if (reg == NAND_READ_LOCATION_1) - snandc->regs->read_location1 = locreg_val; - else if (reg == NAND_READ_LOCATION_2) -- snandc->regs->read_location1 = locreg_val; -+ snandc->regs->read_location2 = locreg_val; - else if (reg == NAND_READ_LOCATION_3) - snandc->regs->read_location3 = locreg_val; - } --- -2.51.0 - - -From 4de9243c76e9bb34f53b9804e1fe7479084a896d Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Thu, 20 Mar 2025 19:11:59 +0100 -Subject: [PATCH 022/517] spi: spi-qpic-snand: use kmalloc() for OOB buffer - allocation - -The qcom_spi_ecc_init_ctx_pipelined() function allocates zeroed -memory for the OOB buffer, then it fills the buffer with '0xff' -bytes right after the allocation. In this case zeroing the memory -during allocation is superfluous, so use kmalloc() instead of -kzalloc() to avoid that. - -Signed-off-by: Gabor Juhos -Link: https://patch.msgid.link/20250320-qpic-snand-kmalloc-v1-1-94e267550675@gmail.com -Signed-off-by: Mark Brown ---- - drivers/spi/spi-qpic-snand.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/spi/spi-qpic-snand.c b/drivers/spi/spi-qpic-snand.c -index f01f9517c15d..b03ab39727da 100644 ---- a/drivers/spi/spi-qpic-snand.c -+++ b/drivers/spi/spi-qpic-snand.c -@@ -261,7 +261,7 @@ static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand) - ecc_cfg = kzalloc(sizeof(*ecc_cfg), GFP_KERNEL); - if (!ecc_cfg) - return -ENOMEM; -- snandc->qspi->oob_buf = kzalloc(mtd->writesize + mtd->oobsize, -+ snandc->qspi->oob_buf = kmalloc(mtd->writesize + mtd->oobsize, - GFP_KERNEL); - if (!snandc->qspi->oob_buf) { - kfree(ecc_cfg); --- -2.51.0 - - -From c07685fe8817b098d96bf963114d077fb44574da Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Thu, 24 Apr 2025 20:10:59 +0200 -Subject: [PATCH 023/517] spi: spi-qpic-snand: remove unused 'wlen' member of - 'struct qpic_spi_nand' - -The 'wlen' member of the qpic_spi_nand structure is never used in the -code so remove that. - -Signed-off-by: Gabor Juhos ---- - drivers/spi/spi-qpic-snand.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/drivers/spi/spi-qpic-snand.c b/drivers/spi/spi-qpic-snand.c -index b03ab39727da..98d32d269d55 100644 ---- a/drivers/spi/spi-qpic-snand.c -+++ b/drivers/spi/spi-qpic-snand.c -@@ -116,7 +116,6 @@ struct qpic_spi_nand { - struct nand_ecc_engine ecc_eng; - u8 *data_buf; - u8 *oob_buf; -- u32 wlen; - __le32 addr1; - __le32 addr2; - __le32 cmd; --- -2.51.0 - - -From 992315f651da18bc66f4c200cdfcb5f54ed9acd7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= -Date: Wed, 14 May 2025 08:14:54 +0200 -Subject: [PATCH 024/517] mtd: rawnand: brcmnand: remove unused parameters -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -last_cmd and last_byte are now unused brcmnand_host members. -last_addr is only written and never read so we can remove it too. - -Signed-off-by: Álvaro Fernández Rojas -Reviewed-by: Florian Fainelli -Reviewed-by: William Zhang -Signed-off-by: Miquel Raynal ---- - drivers/mtd/nand/raw/brcmnand/brcmnand.c | 24 ++++++------------------ - 1 file changed, 6 insertions(+), 18 deletions(-) - -diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c -index 2eb44c1428fb..3bea54fe5a73 100644 ---- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c -+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c -@@ -310,9 +310,6 @@ struct brcmnand_host { - struct platform_device *pdev; - int cs; - -- unsigned int last_cmd; -- unsigned int last_byte; -- u64 last_addr; - struct brcmnand_cfg hwcfg; - struct brcmnand_controller *ctrl; - }; -@@ -2233,14 +2230,11 @@ static int brcmnand_read_page(struct nand_chip *chip, uint8_t *buf, - int oob_required, int page) - { - struct mtd_info *mtd = nand_to_mtd(chip); -- struct brcmnand_host *host = nand_get_controller_data(chip); - u8 *oob = oob_required ? (u8 *)chip->oob_poi : NULL; - u64 addr = (u64)page << chip->page_shift; - -- host->last_addr = addr; -- -- return brcmnand_read(mtd, chip, host->last_addr, -- mtd->writesize >> FC_SHIFT, (u32 *)buf, oob); -+ return brcmnand_read(mtd, chip, addr, mtd->writesize >> FC_SHIFT, -+ (u32 *)buf, oob); - } - - static int brcmnand_read_page_raw(struct nand_chip *chip, uint8_t *buf, -@@ -2252,11 +2246,9 @@ static int brcmnand_read_page_raw(struct nand_chip *chip, uint8_t *buf, - int ret; - u64 addr = (u64)page << chip->page_shift; - -- host->last_addr = addr; -- - brcmnand_set_ecc_enabled(host, 0); -- ret = brcmnand_read(mtd, chip, host->last_addr, -- mtd->writesize >> FC_SHIFT, (u32 *)buf, oob); -+ ret = brcmnand_read(mtd, chip, addr, mtd->writesize >> FC_SHIFT, -+ (u32 *)buf, oob); - brcmnand_set_ecc_enabled(host, 1); - return ret; - } -@@ -2363,13 +2355,10 @@ static int brcmnand_write_page(struct nand_chip *chip, const uint8_t *buf, - int oob_required, int page) - { - struct mtd_info *mtd = nand_to_mtd(chip); -- struct brcmnand_host *host = nand_get_controller_data(chip); - void *oob = oob_required ? chip->oob_poi : NULL; - u64 addr = (u64)page << chip->page_shift; - -- host->last_addr = addr; -- -- return brcmnand_write(mtd, chip, host->last_addr, (const u32 *)buf, oob); -+ return brcmnand_write(mtd, chip, addr, (const u32 *)buf, oob); - } - - static int brcmnand_write_page_raw(struct nand_chip *chip, const uint8_t *buf, -@@ -2381,9 +2370,8 @@ static int brcmnand_write_page_raw(struct nand_chip *chip, const uint8_t *buf, - u64 addr = (u64)page << chip->page_shift; - int ret = 0; - -- host->last_addr = addr; - brcmnand_set_ecc_enabled(host, 0); -- ret = brcmnand_write(mtd, chip, host->last_addr, (const u32 *)buf, oob); -+ ret = brcmnand_write(mtd, chip, addr, (const u32 *)buf, oob); - brcmnand_set_ecc_enabled(host, 1); - - return ret; --- -2.51.0 - - -From c59673659b207ba134af6ede988607ee22aa3f57 Mon Sep 17 00:00:00 2001 -From: David Regan -Date: Thu, 22 May 2025 10:25:17 -0700 -Subject: [PATCH 025/517] mtd: nand: brcmnand: fix NAND timeout when accessing - eMMC - -When booting a board to NAND and accessing NAND while eMMC -transactions are occurring the NAND will sometimes timeout. This -is due to both NAND and eMMC controller sharing the same data bus -on BCMBCA chips. Fix is to extend NAND timeout to allow eMMC -transactions time to complete. - -Signed-off-by: David Regan -Reviewed-by: William Zhang -Reviewed-by: Florian Fainelli -Signed-off-by: Miquel Raynal ---- - drivers/mtd/nand/raw/brcmnand/brcmnand.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c -index 3bea54fe5a73..7593b88f7c99 100644 ---- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c -+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c -@@ -101,7 +101,7 @@ struct brcm_nand_dma_desc { - #define BRCMNAND_MIN_DEVSIZE (4ULL * 1024 * 1024) - - #define NAND_CTRL_RDY (INTFC_CTLR_READY | INTFC_FLASH_READY) --#define NAND_POLL_STATUS_TIMEOUT_MS 100 -+#define NAND_POLL_STATUS_TIMEOUT_MS 500 - - #define EDU_CMD_WRITE 0x00 - #define EDU_CMD_READ 0x01 --- -2.51.0 - - -From bdbbf888ee66c9275304629c89a7f57d977d1074 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= -Date: Wed, 21 May 2025 10:03:25 +0200 -Subject: [PATCH 026/517] mtd: rawnand: brcmnand: legacy exec_op implementation -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Commit 3c8260ce7663 ("mtd: rawnand: brcmnand: exec_op implementation") -removed legacy interface functions, breaking < v5.0 controllers support. -In order to fix older controllers we need to add an alternative exec_op -implementation which doesn't rely on low level registers. - -Fixes: 3c8260ce7663 ("mtd: rawnand: brcmnand: exec_op implementation") -Signed-off-by: Álvaro Fernández Rojas -Reviewed-by: David Regan -Reviewed-by: Florian Fainelli -Reviewed-by: William Zhang -Signed-off-by: Miquel Raynal ---- - drivers/mtd/nand/raw/brcmnand/brcmnand.c | 222 ++++++++++++++++++++++- - 1 file changed, 215 insertions(+), 7 deletions(-) - -diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c -index 7593b88f7c99..59568c430315 100644 ---- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c -+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c -@@ -65,6 +65,7 @@ module_param(wp_on, int, 0444); - #define CMD_PARAMETER_READ 0x0e - #define CMD_PARAMETER_CHANGE_COL 0x0f - #define CMD_LOW_LEVEL_OP 0x10 -+#define CMD_NOT_SUPPORTED 0xff - - struct brcm_nand_dma_desc { - u32 next_desc; -@@ -199,6 +200,30 @@ static const u16 flash_dma_regs_v4[] = { - [FLASH_DMA_CURRENT_DESC_EXT] = 0x34, - }; - -+/* Native command conversion for legacy controllers (< v5.0) */ -+static const u8 native_cmd_conv[] = { -+ [NAND_CMD_READ0] = CMD_NOT_SUPPORTED, -+ [NAND_CMD_READ1] = CMD_NOT_SUPPORTED, -+ [NAND_CMD_RNDOUT] = CMD_PARAMETER_CHANGE_COL, -+ [NAND_CMD_PAGEPROG] = CMD_NOT_SUPPORTED, -+ [NAND_CMD_READOOB] = CMD_NOT_SUPPORTED, -+ [NAND_CMD_ERASE1] = CMD_BLOCK_ERASE, -+ [NAND_CMD_STATUS] = CMD_NOT_SUPPORTED, -+ [NAND_CMD_SEQIN] = CMD_NOT_SUPPORTED, -+ [NAND_CMD_RNDIN] = CMD_NOT_SUPPORTED, -+ [NAND_CMD_READID] = CMD_DEVICE_ID_READ, -+ [NAND_CMD_ERASE2] = CMD_NULL, -+ [NAND_CMD_PARAM] = CMD_PARAMETER_READ, -+ [NAND_CMD_GET_FEATURES] = CMD_NOT_SUPPORTED, -+ [NAND_CMD_SET_FEATURES] = CMD_NOT_SUPPORTED, -+ [NAND_CMD_RESET] = CMD_NOT_SUPPORTED, -+ [NAND_CMD_READSTART] = CMD_NOT_SUPPORTED, -+ [NAND_CMD_READCACHESEQ] = CMD_NOT_SUPPORTED, -+ [NAND_CMD_READCACHEEND] = CMD_NOT_SUPPORTED, -+ [NAND_CMD_RNDOUTSTART] = CMD_NULL, -+ [NAND_CMD_CACHEDPROG] = CMD_NOT_SUPPORTED, -+}; -+ - /* Controller feature flags */ - enum { - BRCMNAND_HAS_1K_SECTORS = BIT(0), -@@ -237,6 +262,12 @@ struct brcmnand_controller { - /* List of NAND hosts (one for each chip-select) */ - struct list_head host_list; - -+ /* Functions to be called from exec_op */ -+ int (*check_instr)(struct nand_chip *chip, -+ const struct nand_operation *op); -+ int (*exec_instr)(struct nand_chip *chip, -+ const struct nand_operation *op); -+ - /* EDU info, per-transaction */ - const u16 *edu_offsets; - void __iomem *edu_base; -@@ -2478,18 +2509,190 @@ static int brcmnand_op_is_reset(const struct nand_operation *op) - return 0; - } - -+static int brcmnand_check_instructions(struct nand_chip *chip, -+ const struct nand_operation *op) -+{ -+ return 0; -+} -+ -+static int brcmnand_exec_instructions(struct nand_chip *chip, -+ const struct nand_operation *op) -+{ -+ struct brcmnand_host *host = nand_get_controller_data(chip); -+ unsigned int i; -+ int ret = 0; -+ -+ for (i = 0; i < op->ninstrs; i++) { -+ ret = brcmnand_exec_instr(host, i, op); -+ if (ret) -+ break; -+ } -+ -+ return ret; -+} -+ -+static int brcmnand_check_instructions_legacy(struct nand_chip *chip, -+ const struct nand_operation *op) -+{ -+ const struct nand_op_instr *instr; -+ unsigned int i; -+ u8 cmd; -+ -+ for (i = 0; i < op->ninstrs; i++) { -+ instr = &op->instrs[i]; -+ -+ switch (instr->type) { -+ case NAND_OP_CMD_INSTR: -+ cmd = native_cmd_conv[instr->ctx.cmd.opcode]; -+ if (cmd == CMD_NOT_SUPPORTED) -+ return -EOPNOTSUPP; -+ break; -+ case NAND_OP_ADDR_INSTR: -+ case NAND_OP_DATA_IN_INSTR: -+ case NAND_OP_WAITRDY_INSTR: -+ break; -+ default: -+ return -EOPNOTSUPP; -+ } -+ } -+ -+ return 0; -+} -+ -+static int brcmnand_exec_instructions_legacy(struct nand_chip *chip, -+ const struct nand_operation *op) -+{ -+ struct mtd_info *mtd = nand_to_mtd(chip); -+ struct brcmnand_host *host = nand_get_controller_data(chip); -+ struct brcmnand_controller *ctrl = host->ctrl; -+ const struct nand_op_instr *instr; -+ unsigned int i, j; -+ u8 cmd = CMD_NULL, last_cmd = CMD_NULL; -+ int ret = 0; -+ u64 last_addr; -+ -+ for (i = 0; i < op->ninstrs; i++) { -+ instr = &op->instrs[i]; -+ -+ if (instr->type == NAND_OP_CMD_INSTR) { -+ cmd = native_cmd_conv[instr->ctx.cmd.opcode]; -+ if (cmd == CMD_NOT_SUPPORTED) { -+ dev_err(ctrl->dev, "unsupported cmd=%d\n", -+ instr->ctx.cmd.opcode); -+ ret = -EOPNOTSUPP; -+ break; -+ } -+ } else if (instr->type == NAND_OP_ADDR_INSTR) { -+ u64 addr = 0; -+ -+ if (cmd == CMD_NULL) -+ continue; -+ -+ if (instr->ctx.addr.naddrs > 8) { -+ dev_err(ctrl->dev, "unsupported naddrs=%u\n", -+ instr->ctx.addr.naddrs); -+ ret = -EOPNOTSUPP; -+ break; -+ } -+ -+ for (j = 0; j < instr->ctx.addr.naddrs; j++) -+ addr |= (instr->ctx.addr.addrs[j]) << (j << 3); -+ -+ if (cmd == CMD_BLOCK_ERASE) -+ addr <<= chip->page_shift; -+ else if (cmd == CMD_PARAMETER_CHANGE_COL) -+ addr &= ~((u64)(FC_BYTES - 1)); -+ -+ brcmnand_set_cmd_addr(mtd, addr); -+ brcmnand_send_cmd(host, cmd); -+ last_addr = addr; -+ last_cmd = cmd; -+ cmd = CMD_NULL; -+ brcmnand_waitfunc(chip); -+ -+ if (last_cmd == CMD_PARAMETER_READ || -+ last_cmd == CMD_PARAMETER_CHANGE_COL) { -+ /* Copy flash cache word-wise */ -+ u32 *flash_cache = (u32 *)ctrl->flash_cache; -+ -+ brcmnand_soc_data_bus_prepare(ctrl->soc, true); -+ -+ /* -+ * Must cache the FLASH_CACHE now, since changes in -+ * SECTOR_SIZE_1K may invalidate it -+ */ -+ for (j = 0; j < FC_WORDS; j++) -+ /* -+ * Flash cache is big endian for parameter pages, at -+ * least on STB SoCs -+ */ -+ flash_cache[j] = be32_to_cpu(brcmnand_read_fc(ctrl, j)); -+ -+ brcmnand_soc_data_bus_unprepare(ctrl->soc, true); -+ } -+ } else if (instr->type == NAND_OP_DATA_IN_INSTR) { -+ u8 *in = instr->ctx.data.buf.in; -+ -+ if (last_cmd == CMD_DEVICE_ID_READ) { -+ u32 val; -+ -+ if (instr->ctx.data.len > 8) { -+ dev_err(ctrl->dev, "unsupported len=%u\n", -+ instr->ctx.data.len); -+ ret = -EOPNOTSUPP; -+ break; -+ } -+ -+ for (j = 0; j < instr->ctx.data.len; j++) { -+ if (j == 0) -+ val = brcmnand_read_reg(ctrl, BRCMNAND_ID); -+ else if (j == 4) -+ val = brcmnand_read_reg(ctrl, BRCMNAND_ID_EXT); -+ -+ in[j] = (val >> (24 - ((j % 4) << 3))) & 0xff; -+ } -+ } else if (last_cmd == CMD_PARAMETER_READ || -+ last_cmd == CMD_PARAMETER_CHANGE_COL) { -+ u64 addr; -+ u32 offs; -+ -+ for (j = 0; j < instr->ctx.data.len; j++) { -+ addr = last_addr + j; -+ offs = addr & (FC_BYTES - 1); -+ -+ if (j > 0 && offs == 0) -+ nand_change_read_column_op(chip, addr, NULL, 0, -+ false); -+ -+ in[j] = ctrl->flash_cache[offs]; -+ } -+ } -+ } else if (instr->type == NAND_OP_WAITRDY_INSTR) { -+ ret = bcmnand_ctrl_poll_status(host, NAND_CTRL_RDY, NAND_CTRL_RDY, 0); -+ if (ret) -+ break; -+ } else { -+ dev_err(ctrl->dev, "unsupported instruction type: %d\n", instr->type); -+ ret = -EOPNOTSUPP; -+ break; -+ } -+ } -+ -+ return ret; -+} -+ - static int brcmnand_exec_op(struct nand_chip *chip, - const struct nand_operation *op, - bool check_only) - { - struct brcmnand_host *host = nand_get_controller_data(chip); -+ struct brcmnand_controller *ctrl = host->ctrl; - struct mtd_info *mtd = nand_to_mtd(chip); - u8 *status; -- unsigned int i; - int ret = 0; - - if (check_only) -- return 0; -+ return ctrl->check_instr(chip, op); - - if (brcmnand_op_is_status(op)) { - status = op->instrs[1].ctx.data.buf.in; -@@ -2513,11 +2716,7 @@ static int brcmnand_exec_op(struct nand_chip *chip, - if (op->deassert_wp) - brcmnand_wp(mtd, 0); - -- for (i = 0; i < op->ninstrs; i++) { -- ret = brcmnand_exec_instr(host, i, op); -- if (ret) -- break; -- } -+ ret = ctrl->exec_instr(chip, op); - - if (op->deassert_wp) - brcmnand_wp(mtd, 1); -@@ -3130,6 +3329,15 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) - if (ret) - goto err; - -+ /* Only v5.0+ controllers have low level ops support */ -+ if (ctrl->nand_version >= 0x0500) { -+ ctrl->check_instr = brcmnand_check_instructions; -+ ctrl->exec_instr = brcmnand_exec_instructions; -+ } else { -+ ctrl->check_instr = brcmnand_check_instructions_legacy; -+ ctrl->exec_instr = brcmnand_exec_instructions_legacy; -+ } -+ - /* - * Most chips have this cache at a fixed offset within 'nand' block. - * Some must specify this region separately. --- -2.51.0 - - -From 498ecabf18426e22786a167b9f59652ff36cdb26 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 3 Oct 2024 00:11:41 +0200 -Subject: [PATCH 027/517] block: add support for defining read-only partitions - -Add support for defining read-only partitions and complete support for -it in the cmdline partition parser as the additional "ro" after a -partition is scanned but never actually applied. - -Signed-off-by: Christian Marangi -Reviewed-by: Christoph Hellwig -Link: https://lore.kernel.org/r/20241002221306.4403-2-ansuelsmth@gmail.com -Signed-off-by: Jens Axboe ---- - block/blk.h | 1 + - block/partitions/cmdline.c | 3 +++ - block/partitions/core.c | 3 +++ - 3 files changed, 7 insertions(+) - -diff --git a/block/blk.h b/block/blk.h -index e91012247ff2..a8ac9c6dbb85 100644 ---- a/block/blk.h -+++ b/block/blk.h -@@ -556,6 +556,7 @@ void blk_free_ext_minor(unsigned int minor); - #define ADDPART_FLAG_NONE 0 - #define ADDPART_FLAG_RAID 1 - #define ADDPART_FLAG_WHOLEDISK 2 -+#define ADDPART_FLAG_READONLY 4 - int bdev_add_partition(struct gendisk *disk, int partno, sector_t start, - sector_t length); - int bdev_del_partition(struct gendisk *disk, int partno); -diff --git a/block/partitions/cmdline.c b/block/partitions/cmdline.c -index 152c85df92b2..da3e719d8e51 100644 ---- a/block/partitions/cmdline.c -+++ b/block/partitions/cmdline.c -@@ -237,6 +237,9 @@ static int add_part(int slot, struct cmdline_subpart *subpart, - put_partition(state, slot, subpart->from >> 9, - subpart->size >> 9); - -+ if (subpart->flags & PF_RDONLY) -+ state->parts[slot].flags |= ADDPART_FLAG_READONLY; -+ - info = &state->parts[slot].info; - - strscpy(info->volname, subpart->name, sizeof(info->volname)); -diff --git a/block/partitions/core.c b/block/partitions/core.c -index 5bd7a603092e..629ed08b9ab9 100644 ---- a/block/partitions/core.c -+++ b/block/partitions/core.c -@@ -373,6 +373,9 @@ static struct block_device *add_partition(struct gendisk *disk, int partno, - goto out_del; - } - -+ if (flags & ADDPART_FLAG_READONLY) -+ bdev_set_flag(bdev, BD_READ_ONLY); -+ - /* everything is up and running, commence */ - err = xa_insert(&disk->part_tbl, partno, bdev, GFP_KERNEL); - if (err) --- -2.51.0 - - -From b9b466eecefdedee1240f5f182b4083a0cd8627b Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 3 Oct 2024 00:11:43 +0200 -Subject: [PATCH 028/517] block: introduce add_disk_fwnode() - -Introduce add_disk_fwnode() as a replacement of device_add_disk() that -permits to pass and attach a fwnode to disk dev. - -This variant can be useful for eMMC that might have the partition table -for the disk defined in DT. A parser can later make use of the attached -fwnode to parse the related table and init the hardcoded partition for -the disk. - -device_add_disk() is converted to a simple wrapper of add_disk_fwnode() -with the fwnode entry set as NULL. - -Signed-off-by: Christian Marangi -Reviewed-by: Christoph Hellwig -Link: https://lore.kernel.org/r/20241002221306.4403-4-ansuelsmth@gmail.com -Signed-off-by: Jens Axboe ---- - block/genhd.c | 28 ++++++++++++++++++++++++---- - include/linux/blkdev.h | 3 +++ - 2 files changed, 27 insertions(+), 4 deletions(-) - -diff --git a/block/genhd.c b/block/genhd.c -index 99344f53c789..342a92f1391e 100644 ---- a/block/genhd.c -+++ b/block/genhd.c -@@ -383,16 +383,18 @@ int disk_scan_partitions(struct gendisk *disk, blk_mode_t mode) - } - - /** -- * device_add_disk - add disk information to kernel list -+ * add_disk_fwnode - add disk information to kernel list with fwnode - * @parent: parent device for the disk - * @disk: per-device partitioning information - * @groups: Additional per-device sysfs groups -+ * @fwnode: attached disk fwnode - * - * This function registers the partitioning information in @disk -- * with the kernel. -+ * with the kernel. Also attach a fwnode to the disk device. - */ --int __must_check device_add_disk(struct device *parent, struct gendisk *disk, -- const struct attribute_group **groups) -+int __must_check add_disk_fwnode(struct device *parent, struct gendisk *disk, -+ const struct attribute_group **groups, -+ struct fwnode_handle *fwnode) - - { - struct device *ddev = disk_to_dev(disk); -@@ -452,6 +454,8 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk, - ddev->parent = parent; - ddev->groups = groups; - dev_set_name(ddev, "%s", disk->disk_name); -+ if (fwnode) -+ device_set_node(ddev, fwnode); - if (!(disk->flags & GENHD_FL_HIDDEN)) - ddev->devt = MKDEV(disk->major, disk->first_minor); - ret = device_add(ddev); -@@ -553,6 +557,22 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk, - elevator_exit(disk->queue); - return ret; - } -+EXPORT_SYMBOL_GPL(add_disk_fwnode); -+ -+/** -+ * device_add_disk - add disk information to kernel list -+ * @parent: parent device for the disk -+ * @disk: per-device partitioning information -+ * @groups: Additional per-device sysfs groups -+ * -+ * This function registers the partitioning information in @disk -+ * with the kernel. -+ */ -+int __must_check device_add_disk(struct device *parent, struct gendisk *disk, -+ const struct attribute_group **groups) -+{ -+ return add_disk_fwnode(parent, disk, groups, NULL); -+} - EXPORT_SYMBOL(device_add_disk); - - static void blk_report_disk_dead(struct gendisk *disk, bool surprise) -diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h -index cd9c97f6f948..fa9d324b7069 100644 ---- a/include/linux/blkdev.h -+++ b/include/linux/blkdev.h -@@ -789,6 +789,9 @@ static inline unsigned int blk_queue_depth(struct request_queue *q) - #define for_each_bio(_bio) \ - for (; _bio; _bio = _bio->bi_next) - -+int __must_check add_disk_fwnode(struct device *parent, struct gendisk *disk, -+ const struct attribute_group **groups, -+ struct fwnode_handle *fwnode); - int __must_check device_add_disk(struct device *parent, struct gendisk *disk, - const struct attribute_group **groups); - static inline int __must_check add_disk(struct gendisk *disk) --- -2.51.0 - - -From 3272770722c2740510bba41e7d07d4ccda7b7439 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 3 Oct 2024 00:11:44 +0200 -Subject: [PATCH 029/517] mmc: block: attach partitions fwnode if found in - mmc-card - -Attach partitions fwnode if found in mmc-card and register disk with it. - -This permits block partition to reference the node and register a -partition table defined in DT for the special case for embedded device -that doesn't have a partition table flashed but have an hardcoded -partition table passed from the system. - -JEDEC BOOT partition boot0/boot1 are supported but in DT we refer with -the JEDEC name of boot1 and boot2 to better adhere to documentation. - -Also JEDEC GP partition gp0/1/2/3 are supported but in DT we refer with -the JEDEC name of gp1/2/3/4 to better adhere to documentration. - -Signed-off-by: Christian Marangi -Reviewed-by: Linus Walleij -Link: https://lore.kernel.org/r/20241002221306.4403-5-ansuelsmth@gmail.com -Signed-off-by: Jens Axboe ---- - drivers/mmc/core/block.c | 55 +++++++++++++++++++++++++++++++++++++++- - 1 file changed, 54 insertions(+), 1 deletion(-) - -diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c -index 08b8276e1da9..28882b75ba26 100644 ---- a/drivers/mmc/core/block.c -+++ b/drivers/mmc/core/block.c -@@ -2517,6 +2517,56 @@ static inline int mmc_blk_readonly(struct mmc_card *card) - !(card->csd.cmdclass & CCC_BLOCK_WRITE); - } - -+/* -+ * Search for a declared partitions node for the disk in mmc-card related node. -+ * -+ * This is to permit support for partition table defined in DT in special case -+ * where a partition table is not written in the disk and is expected to be -+ * passed from the running system. -+ * -+ * For the user disk, "partitions" node is searched. -+ * For the special HW disk, "partitions-" node with the appended name is used -+ * following this conversion table (to adhere to JEDEC naming) -+ * - boot0 -> partitions-boot1 -+ * - boot1 -> partitions-boot2 -+ * - gp0 -> partitions-gp1 -+ * - gp1 -> partitions-gp2 -+ * - gp2 -> partitions-gp3 -+ * - gp3 -> partitions-gp4 -+ */ -+static struct fwnode_handle *mmc_blk_get_partitions_node(struct device *mmc_dev, -+ const char *subname) -+{ -+ const char *node_name = "partitions"; -+ -+ if (subname) { -+ mmc_dev = mmc_dev->parent; -+ -+ /* -+ * Check if we are allocating a BOOT disk boot0/1 disk. -+ * In DT we use the JEDEC naming boot1/2. -+ */ -+ if (!strcmp(subname, "boot0")) -+ node_name = "partitions-boot1"; -+ if (!strcmp(subname, "boot1")) -+ node_name = "partitions-boot2"; -+ /* -+ * Check if we are allocating a GP disk gp0/1/2/3 disk. -+ * In DT we use the JEDEC naming gp1/2/3/4. -+ */ -+ if (!strcmp(subname, "gp0")) -+ node_name = "partitions-gp1"; -+ if (!strcmp(subname, "gp1")) -+ node_name = "partitions-gp2"; -+ if (!strcmp(subname, "gp2")) -+ node_name = "partitions-gp3"; -+ if (!strcmp(subname, "gp3")) -+ node_name = "partitions-gp4"; -+ } -+ -+ return device_get_named_child_node(mmc_dev, node_name); -+} -+ - static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, - struct device *parent, - sector_t size, -@@ -2525,6 +2575,7 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, - int area_type, - unsigned int part_type) - { -+ struct fwnode_handle *disk_fwnode; - struct mmc_blk_data *md; - int devidx, ret; - char cap_str[10]; -@@ -2626,7 +2677,9 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, - /* used in ->open, must be set before add_disk: */ - if (area_type == MMC_BLK_DATA_AREA_MAIN) - dev_set_drvdata(&card->dev, md); -- ret = device_add_disk(md->parent, md->disk, mmc_disk_attr_groups); -+ disk_fwnode = mmc_blk_get_partitions_node(parent, subname); -+ ret = add_disk_fwnode(md->parent, md->disk, mmc_disk_attr_groups, -+ disk_fwnode); - if (ret) - goto err_put_disk; - return md; --- -2.51.0 - - -From 230f71eab625c48464071341ff4c0170831bce2c Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 3 Oct 2024 00:11:45 +0200 -Subject: [PATCH 030/517] block: add support for partition table defined in OF - -Add support for partition table defined in Device Tree. Similar to how -it's done with MTD, add support for defining a fixed partition table in -device tree. - -A common scenario for this is fixed block (eMMC) embedded devices that -have no MBR or GPT partition table to save storage space. Bootloader -access the block device with absolute address of data. - -This is to complete the functionality with an equivalent implementation -with providing partition table with bootargs, for case where the booargs -can't be modified and tweaking the Device Tree is the only solution to -have an usabe partition table. - -The implementation follow the fixed-partitions parser used on MTD -devices where a "partitions" node is expected to be declared with -"fixed-partitions" compatible in the OF node of the disk device -(mmc-card for eMMC for example) and each child node declare a label -and a reg with offset and size. If label is not declared, the node name -is used as fallback. Eventually is also possible to declare the read-only -property to flag the partition as read-only. - -Signed-off-by: Christian Marangi -Reviewed-by: Christoph Hellwig -Link: https://lore.kernel.org/r/20241002221306.4403-6-ansuelsmth@gmail.com -Signed-off-by: Jens Axboe ---- - block/partitions/Kconfig | 9 ++++ - block/partitions/Makefile | 1 + - block/partitions/check.h | 1 + - block/partitions/core.c | 3 ++ - block/partitions/of.c | 110 ++++++++++++++++++++++++++++++++++++++ - 5 files changed, 124 insertions(+) - create mode 100644 block/partitions/of.c - -diff --git a/block/partitions/Kconfig b/block/partitions/Kconfig -index 7aff4eb81c60..ce17e41451af 100644 ---- a/block/partitions/Kconfig -+++ b/block/partitions/Kconfig -@@ -270,4 +270,13 @@ config CMDLINE_PARTITION - Say Y here if you want to read the partition table from bootargs. - The format for the command line is just like mtdparts. - -+config OF_PARTITION -+ bool "Device Tree partition support" if PARTITION_ADVANCED -+ depends on OF -+ help -+ Say Y here if you want to enable support for partition table -+ defined in Device Tree. (mainly for eMMC) -+ The format for the device tree node is just like MTD fixed-partition -+ schema. -+ - endmenu -diff --git a/block/partitions/Makefile b/block/partitions/Makefile -index a7f05cdb02a8..25d424922c6e 100644 ---- a/block/partitions/Makefile -+++ b/block/partitions/Makefile -@@ -12,6 +12,7 @@ obj-$(CONFIG_CMDLINE_PARTITION) += cmdline.o - obj-$(CONFIG_MAC_PARTITION) += mac.o - obj-$(CONFIG_LDM_PARTITION) += ldm.o - obj-$(CONFIG_MSDOS_PARTITION) += msdos.o -+obj-$(CONFIG_OF_PARTITION) += of.o - obj-$(CONFIG_OSF_PARTITION) += osf.o - obj-$(CONFIG_SGI_PARTITION) += sgi.o - obj-$(CONFIG_SUN_PARTITION) += sun.o -diff --git a/block/partitions/check.h b/block/partitions/check.h -index 8d70a880c372..e5c1c61eb353 100644 ---- a/block/partitions/check.h -+++ b/block/partitions/check.h -@@ -62,6 +62,7 @@ int karma_partition(struct parsed_partitions *state); - int ldm_partition(struct parsed_partitions *state); - int mac_partition(struct parsed_partitions *state); - int msdos_partition(struct parsed_partitions *state); -+int of_partition(struct parsed_partitions *state); - int osf_partition(struct parsed_partitions *state); - int sgi_partition(struct parsed_partitions *state); - int sun_partition(struct parsed_partitions *state); -diff --git a/block/partitions/core.c b/block/partitions/core.c -index 629ed08b9ab9..cdad05f97647 100644 ---- a/block/partitions/core.c -+++ b/block/partitions/core.c -@@ -43,6 +43,9 @@ static int (*const check_part[])(struct parsed_partitions *) = { - #ifdef CONFIG_CMDLINE_PARTITION - cmdline_partition, - #endif -+#ifdef CONFIG_OF_PARTITION -+ of_partition, /* cmdline have priority to OF */ -+#endif - #ifdef CONFIG_EFI_PARTITION - efi_partition, /* this must come before msdos */ - #endif -diff --git a/block/partitions/of.c b/block/partitions/of.c -new file mode 100644 -index 000000000000..4e760fdffb3f ---- /dev/null -+++ b/block/partitions/of.c -@@ -0,0 +1,110 @@ -+// SPDX-License-Identifier: GPL-2.0 -+ -+#include -+#include -+#include -+#include -+#include "check.h" -+ -+static int validate_of_partition(struct device_node *np, int slot) -+{ -+ u64 offset, size; -+ int len; -+ -+ const __be32 *reg = of_get_property(np, "reg", &len); -+ int a_cells = of_n_addr_cells(np); -+ int s_cells = of_n_size_cells(np); -+ -+ /* Make sure reg len match the expected addr and size cells */ -+ if (len / sizeof(*reg) != a_cells + s_cells) -+ return -EINVAL; -+ -+ /* Validate offset conversion from bytes to sectors */ -+ offset = of_read_number(reg, a_cells); -+ if (offset % SECTOR_SIZE) -+ return -EINVAL; -+ -+ /* Validate size conversion from bytes to sectors */ -+ size = of_read_number(reg + a_cells, s_cells); -+ if (!size || size % SECTOR_SIZE) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static void add_of_partition(struct parsed_partitions *state, int slot, -+ struct device_node *np) -+{ -+ struct partition_meta_info *info; -+ char tmp[sizeof(info->volname) + 4]; -+ const char *partname; -+ int len; -+ -+ const __be32 *reg = of_get_property(np, "reg", &len); -+ int a_cells = of_n_addr_cells(np); -+ int s_cells = of_n_size_cells(np); -+ -+ /* Convert bytes to sector size */ -+ u64 offset = of_read_number(reg, a_cells) / SECTOR_SIZE; -+ u64 size = of_read_number(reg + a_cells, s_cells) / SECTOR_SIZE; -+ -+ put_partition(state, slot, offset, size); -+ -+ if (of_property_read_bool(np, "read-only")) -+ state->parts[slot].flags |= ADDPART_FLAG_READONLY; -+ -+ /* -+ * Follow MTD label logic, search for label property, -+ * fallback to node name if not found. -+ */ -+ info = &state->parts[slot].info; -+ partname = of_get_property(np, "label", &len); -+ if (!partname) -+ partname = of_get_property(np, "name", &len); -+ strscpy(info->volname, partname, sizeof(info->volname)); -+ -+ snprintf(tmp, sizeof(tmp), "(%s)", info->volname); -+ strlcat(state->pp_buf, tmp, PAGE_SIZE); -+} -+ -+int of_partition(struct parsed_partitions *state) -+{ -+ struct device *ddev = disk_to_dev(state->disk); -+ struct device_node *np; -+ int slot; -+ -+ struct device_node *partitions_np = of_node_get(ddev->of_node); -+ -+ if (!partitions_np || -+ !of_device_is_compatible(partitions_np, "fixed-partitions")) -+ return 0; -+ -+ slot = 1; -+ /* Validate parition offset and size */ -+ for_each_child_of_node(partitions_np, np) { -+ if (validate_of_partition(np, slot)) { -+ of_node_put(np); -+ of_node_put(partitions_np); -+ -+ return -1; -+ } -+ -+ slot++; -+ } -+ -+ slot = 1; -+ for_each_child_of_node(partitions_np, np) { -+ if (slot >= state->limit) { -+ of_node_put(np); -+ break; -+ } -+ -+ add_of_partition(state, slot, np); -+ -+ slot++; -+ } -+ -+ strlcat(state->pp_buf, "\n", PAGE_SIZE); -+ -+ return 1; -+} --- -2.51.0 - - -From 564834bbaef7bec34bc5c34c25ad2f5a509c23f9 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Fri, 8 Nov 2024 16:01:44 +0000 -Subject: [PATCH 031/517] net: phylink: move manual flow control setting - -Move the handling of manual flow control configuration to a common -location during resolve. We currently evaluate this for all but -fixed links. - -Signed-off-by: Russell King (Oracle) -Link: https://patch.msgid.link/E1t9RQe-002Feh-T1@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c -index b78dfcbec936..8fc59aba1ded 100644 ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -1484,7 +1484,6 @@ static void phylink_resolve(struct work_struct *w) - switch (pl->cur_link_an_mode) { - case MLO_AN_PHY: - link_state = pl->phy_state; -- phylink_apply_manual_flow(pl, &link_state); - mac_config = link_state.link; - break; - -@@ -1545,11 +1544,13 @@ static void phylink_resolve(struct work_struct *w) - link_state.pause = pl->phy_state.pause; - mac_config = true; - } -- phylink_apply_manual_flow(pl, &link_state); - break; - } - } - -+ if (pl->cur_link_an_mode != MLO_AN_FIXED) -+ phylink_apply_manual_flow(pl, &link_state); -+ - if (mac_config) { - if (link_state.interface != pl->link_config.interface) { - /* The interface has changed, force the link down and --- -2.51.0 - - -From b2650f725996177178c95ba69b7d2fe5edd85eca Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Fri, 8 Nov 2024 16:01:50 +0000 -Subject: [PATCH 032/517] net: phylink: move MLO_AN_FIXED resolve handling to - if() statement - -The switch() statement doesn't sit very well with the preceeding if() -statements, and results in excessive indentation that spoils code -readability. Begin cleaning this up by converting the MLO_AN_FIXED case -to an if() statement. - -Signed-off-by: Russell King (Oracle) -Link: https://patch.msgid.link/E1t9RQk-002Fen-1A@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 8 +++----- - 1 file changed, 3 insertions(+), 5 deletions(-) - -diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c -index 8fc59aba1ded..f1d97db70f58 100644 ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -1480,6 +1480,9 @@ static void phylink_resolve(struct work_struct *w) - } else if (pl->link_failed) { - link_state.link = false; - retrigger = true; -+ } else if (pl->cur_link_an_mode == MLO_AN_FIXED) { -+ phylink_get_fixed_state(pl, &link_state); -+ mac_config = link_state.link; - } else { - switch (pl->cur_link_an_mode) { - case MLO_AN_PHY: -@@ -1487,11 +1490,6 @@ static void phylink_resolve(struct work_struct *w) - mac_config = link_state.link; - break; - -- case MLO_AN_FIXED: -- phylink_get_fixed_state(pl, &link_state); -- mac_config = link_state.link; -- break; -- - case MLO_AN_INBAND: - phylink_mac_pcs_get_state(pl, &link_state); - --- -2.51.0 - - -From 3740814469f6222bdbaa014e71911970fb45223f Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Fri, 8 Nov 2024 16:01:55 +0000 -Subject: [PATCH 033/517] net: phylink: move MLO_AN_PHY resolve handling to - if() statement - -The switch() statement doesn't sit very well with the preceeding if() -statements, and results in excessive indentation that spoils code -readability. Continue cleaning this up by converting the MLO_AN_PHY -case to use an if() statmeent. - -Signed-off-by: Russell King (Oracle) -Link: https://patch.msgid.link/E1t9RQp-002Fet-5W@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 8 +++----- - 1 file changed, 3 insertions(+), 5 deletions(-) - -diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c -index f1d97db70f58..1169ffb30a31 100644 ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -1483,13 +1483,11 @@ static void phylink_resolve(struct work_struct *w) - } else if (pl->cur_link_an_mode == MLO_AN_FIXED) { - phylink_get_fixed_state(pl, &link_state); - mac_config = link_state.link; -+ } else if (pl->cur_link_an_mode == MLO_AN_PHY) { -+ link_state = pl->phy_state; -+ mac_config = link_state.link; - } else { - switch (pl->cur_link_an_mode) { -- case MLO_AN_PHY: -- link_state = pl->phy_state; -- mac_config = link_state.link; -- break; -- - case MLO_AN_INBAND: - phylink_mac_pcs_get_state(pl, &link_state); - --- -2.51.0 - - -From 001a54bc68e2061d58af85a76f1cb9d2908c0031 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Fri, 8 Nov 2024 16:02:00 +0000 -Subject: [PATCH 034/517] net: phylink: remove switch() statement in resolve - handling - -The switch() statement doesn't sit very well with the preceeding if() -statements, so let's just convert everything to if()s. As a result of -the two preceding commits, there is now only one case in the switch() -statement. Remove the switch statement and reduce the code indentation. -Code reformatting will be in the following commit. - -Signed-off-by: Russell King (Oracle) -Link: https://patch.msgid.link/E1t9RQu-002Fez-AA@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 94 +++++++++++++++++++-------------------- - 1 file changed, 45 insertions(+), 49 deletions(-) - -diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c -index 1169ffb30a31..cee1f1aa11a1 100644 ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -1487,60 +1487,56 @@ static void phylink_resolve(struct work_struct *w) - link_state = pl->phy_state; - mac_config = link_state.link; - } else { -- switch (pl->cur_link_an_mode) { -- case MLO_AN_INBAND: -- phylink_mac_pcs_get_state(pl, &link_state); -- -- /* The PCS may have a latching link-fail indicator. -- * If the link was up, bring the link down and -- * re-trigger the resolve. Otherwise, re-read the -- * PCS state to get the current status of the link. -+ phylink_mac_pcs_get_state(pl, &link_state); -+ -+ /* The PCS may have a latching link-fail indicator. -+ * If the link was up, bring the link down and -+ * re-trigger the resolve. Otherwise, re-read the -+ * PCS state to get the current status of the link. -+ */ -+ if (!link_state.link) { -+ if (cur_link_state) -+ retrigger = true; -+ else -+ phylink_mac_pcs_get_state(pl, -+ &link_state); -+ } -+ -+ /* If we have a phy, the "up" state is the union of -+ * both the PHY and the MAC -+ */ -+ if (pl->phydev) -+ link_state.link &= pl->phy_state.link; -+ -+ /* Only update if the PHY link is up */ -+ if (pl->phydev && pl->phy_state.link) { -+ /* If the interface has changed, force a -+ * link down event if the link isn't already -+ * down, and re-resolve. - */ -- if (!link_state.link) { -- if (cur_link_state) -- retrigger = true; -- else -- phylink_mac_pcs_get_state(pl, -- &link_state); -+ if (link_state.interface != -+ pl->phy_state.interface) { -+ retrigger = true; -+ link_state.link = false; - } -+ link_state.interface = pl->phy_state.interface; - -- /* If we have a phy, the "up" state is the union of -- * both the PHY and the MAC -+ /* If we are doing rate matching, then the -+ * link speed/duplex comes from the PHY - */ -- if (pl->phydev) -- link_state.link &= pl->phy_state.link; -- -- /* Only update if the PHY link is up */ -- if (pl->phydev && pl->phy_state.link) { -- /* If the interface has changed, force a -- * link down event if the link isn't already -- * down, and re-resolve. -- */ -- if (link_state.interface != -- pl->phy_state.interface) { -- retrigger = true; -- link_state.link = false; -- } -- link_state.interface = pl->phy_state.interface; -- -- /* If we are doing rate matching, then the -- * link speed/duplex comes from the PHY -- */ -- if (pl->phy_state.rate_matching) { -- link_state.rate_matching = -- pl->phy_state.rate_matching; -- link_state.speed = pl->phy_state.speed; -- link_state.duplex = -- pl->phy_state.duplex; -- } -- -- /* If we have a PHY, we need to update with -- * the PHY flow control bits. -- */ -- link_state.pause = pl->phy_state.pause; -- mac_config = true; -+ if (pl->phy_state.rate_matching) { -+ link_state.rate_matching = -+ pl->phy_state.rate_matching; -+ link_state.speed = pl->phy_state.speed; -+ link_state.duplex = -+ pl->phy_state.duplex; - } -- break; -+ -+ /* If we have a PHY, we need to update with -+ * the PHY flow control bits. -+ */ -+ link_state.pause = pl->phy_state.pause; -+ mac_config = true; - } - } - --- -2.51.0 - - -From 921cbed2099d406e77b90ae879b77b716398851f Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Fri, 8 Nov 2024 16:02:05 +0000 -Subject: [PATCH 035/517] net: phylink: clean up phylink_resolve() - -Now that we have reduced the indentation level, clean up the code -formatting. - -Signed-off-by: Russell King (Oracle) -Link: https://patch.msgid.link/E1t9RQz-002Ff5-EA@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 35 ++++++++++++++++------------------- - 1 file changed, 16 insertions(+), 19 deletions(-) - -diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c -index cee1f1aa11a1..e4fc28820bd5 100644 ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -1489,51 +1489,48 @@ static void phylink_resolve(struct work_struct *w) - } else { - phylink_mac_pcs_get_state(pl, &link_state); - -- /* The PCS may have a latching link-fail indicator. -- * If the link was up, bring the link down and -- * re-trigger the resolve. Otherwise, re-read the -- * PCS state to get the current status of the link. -+ /* The PCS may have a latching link-fail indicator. If the link -+ * was up, bring the link down and re-trigger the resolve. -+ * Otherwise, re-read the PCS state to get the current status -+ * of the link. - */ - if (!link_state.link) { - if (cur_link_state) - retrigger = true; - else -- phylink_mac_pcs_get_state(pl, -- &link_state); -+ phylink_mac_pcs_get_state(pl, &link_state); - } - -- /* If we have a phy, the "up" state is the union of -- * both the PHY and the MAC -+ /* If we have a phy, the "up" state is the union of both the -+ * PHY and the MAC - */ - if (pl->phydev) - link_state.link &= pl->phy_state.link; - - /* Only update if the PHY link is up */ - if (pl->phydev && pl->phy_state.link) { -- /* If the interface has changed, force a -- * link down event if the link isn't already -- * down, and re-resolve. -+ /* If the interface has changed, force a link down -+ * event if the link isn't already down, and re-resolve. - */ -- if (link_state.interface != -- pl->phy_state.interface) { -+ if (link_state.interface != pl->phy_state.interface) { - retrigger = true; - link_state.link = false; - } -+ - link_state.interface = pl->phy_state.interface; - -- /* If we are doing rate matching, then the -- * link speed/duplex comes from the PHY -+ /* If we are doing rate matching, then the link -+ * speed/duplex comes from the PHY - */ - if (pl->phy_state.rate_matching) { - link_state.rate_matching = - pl->phy_state.rate_matching; - link_state.speed = pl->phy_state.speed; -- link_state.duplex = -- pl->phy_state.duplex; -+ link_state.duplex = pl->phy_state.duplex; - } - -- /* If we have a PHY, we need to update with -- * the PHY flow control bits. -+ /* If we have a PHY, we need to update with the PHY -+ * flow control bits. - */ - link_state.pause = pl->phy_state.pause; - mac_config = true; --- -2.51.0 - - -From 7d2cfc89b6392219e11a8f9d30313f5177a84611 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 3 Dec 2024 15:30:47 +0000 -Subject: [PATCH 036/517] net: phylink: pass phylink and pcs into - phylink_pcs_neg_mode() - -Move the call to phylink_pcs_neg_mode() in phylink_major_config() after -we have selected the appropriate PCS to allow the PCS to be passed in. - -Add struct phylink and struct phylink_pcs pointers to -phylink_pcs_neg_mode() and pass in the appropriate structures. Set -pl->pcs_neg_mode before returning, and remove the return value. - -This will allow the capabilities of the PCS and any PHY to be used when -deciding which pcs_neg_mode should be used. - -Reviewed-by: Andrew Lunn -Signed-off-by: Russell King (Oracle) -Link: https://patch.msgid.link/E1tIUrP-006ITh-6u@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 26 +++++++++++++------------- - 1 file changed, 13 insertions(+), 13 deletions(-) - -diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c -index e4fc28820bd5..ae7e529c70e2 100644 ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -1102,7 +1102,8 @@ static void phylink_pcs_an_restart(struct phylink *pl) - - /** - * phylink_pcs_neg_mode() - helper to determine PCS inband mode -- * @mode: one of %MLO_AN_FIXED, %MLO_AN_PHY, %MLO_AN_INBAND. -+ * @pl: a pointer to a &struct phylink returned from phylink_create() -+ * @pcs: a pointer to &struct phylink_pcs - * @interface: interface mode to be used - * @advertising: adertisement ethtool link mode mask - * -@@ -1119,11 +1120,13 @@ static void phylink_pcs_an_restart(struct phylink *pl) - * Note: this is for cases where the PCS itself is involved in negotiation - * (e.g. Clause 37, SGMII and similar) not Clause 73. - */ --static unsigned int phylink_pcs_neg_mode(unsigned int mode, -- phy_interface_t interface, -- const unsigned long *advertising) -+static void phylink_pcs_neg_mode(struct phylink *pl, struct phylink_pcs *pcs, -+ phy_interface_t interface, -+ const unsigned long *advertising) - { -- unsigned int neg_mode; -+ unsigned int neg_mode, mode; -+ -+ mode = pl->cur_link_an_mode; - - switch (interface) { - case PHY_INTERFACE_MODE_SGMII: -@@ -1164,7 +1167,7 @@ static unsigned int phylink_pcs_neg_mode(unsigned int mode, - break; - } - -- return neg_mode; -+ pl->pcs_neg_mode = neg_mode; - } - - static void phylink_major_config(struct phylink *pl, bool restart, -@@ -1178,10 +1181,6 @@ static void phylink_major_config(struct phylink *pl, bool restart, - - phylink_dbg(pl, "major config %s\n", phy_modes(state->interface)); - -- pl->pcs_neg_mode = phylink_pcs_neg_mode(pl->cur_link_an_mode, -- state->interface, -- state->advertising); -- - if (pl->using_mac_select_pcs) { - pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface); - if (IS_ERR(pcs)) { -@@ -1194,6 +1193,8 @@ static void phylink_major_config(struct phylink *pl, bool restart, - pcs_changed = pcs && pl->pcs != pcs; - } - -+ phylink_pcs_neg_mode(pl, pcs, state->interface, state->advertising); -+ - phylink_pcs_poll_stop(pl); - - if (pl->mac_ops->mac_prepare) { -@@ -1284,9 +1285,8 @@ static int phylink_change_inband_advert(struct phylink *pl) - pl->link_config.pause); - - /* Recompute the PCS neg mode */ -- pl->pcs_neg_mode = phylink_pcs_neg_mode(pl->cur_link_an_mode, -- pl->link_config.interface, -- pl->link_config.advertising); -+ phylink_pcs_neg_mode(pl, pl->pcs, pl->link_config.interface, -+ pl->link_config.advertising); - - neg_mode = pl->cur_link_an_mode; - if (pl->pcs->neg_mode) --- -2.51.0 - - -From fa2a79a5315cad8983a76f23e445621b9d34cd2c Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 3 Dec 2024 15:30:52 +0000 -Subject: [PATCH 037/517] net: phylink: split cur_link_an_mode into requested - and active - -There is an interdependence between the current link_an_mode and -pcs_neg_mode that some drivers rely upon to know whether inband or PHY -mode will be used. - -In order to support detection of PCS and PHY inband capabilities -resulting in automatic selection of inband or PHY mode, we need to -cater for this, and support changing the MAC link_an_mode. However, we -end up with an inter-dependency between the current link_an_mode and -pcs_neg_mode. - -To solve this, split the current link_an_mode into the requested -link_an_mode and active link_an_mode. The requested link_an_mode will -always be passed to phylink_pcs_neg_mode(), and the active link_an_mode -will be used for everything else, and only updated during -phylink_major_config(). This will ensure that phylink_pcs_neg_mode()'s -link_an_mode will not depend on the active link_an_mode that will, -in a future patch, depend on pcs_neg_mode. - -Reviewed-by: Andrew Lunn -Signed-off-by: Russell King (Oracle) -Link: https://patch.msgid.link/E1tIUrU-006ITn-Ai@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 60 ++++++++++++++++++++------------------- - 1 file changed, 31 insertions(+), 29 deletions(-) - -diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c -index ae7e529c70e2..5290afd0f54e 100644 ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -56,7 +56,8 @@ struct phylink { - struct phy_device *phydev; - phy_interface_t link_interface; /* PHY_INTERFACE_xxx */ - u8 cfg_link_an_mode; /* MLO_AN_xxx */ -- u8 cur_link_an_mode; -+ u8 req_link_an_mode; /* Requested MLO_AN_xxx mode */ -+ u8 act_link_an_mode; /* Active MLO_AN_xxx mode */ - u8 link_port; /* The current non-phy ethtool port */ - __ETHTOOL_DECLARE_LINK_MODE_MASK(supported); - -@@ -1082,13 +1083,13 @@ static void phylink_mac_config(struct phylink *pl, - - phylink_dbg(pl, - "%s: mode=%s/%s/%s adv=%*pb pause=%02x\n", -- __func__, phylink_an_mode_str(pl->cur_link_an_mode), -+ __func__, phylink_an_mode_str(pl->act_link_an_mode), - phy_modes(st.interface), - phy_rate_matching_to_str(st.rate_matching), - __ETHTOOL_LINK_MODE_MASK_NBITS, st.advertising, - st.pause); - -- pl->mac_ops->mac_config(pl->config, pl->cur_link_an_mode, &st); -+ pl->mac_ops->mac_config(pl->config, pl->act_link_an_mode, &st); - } - - static void phylink_pcs_an_restart(struct phylink *pl) -@@ -1096,7 +1097,7 @@ static void phylink_pcs_an_restart(struct phylink *pl) - if (pl->pcs && linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, - pl->link_config.advertising) && - phy_interface_mode_is_8023z(pl->link_config.interface) && -- phylink_autoneg_inband(pl->cur_link_an_mode)) -+ phylink_autoneg_inband(pl->act_link_an_mode)) - pl->pcs->ops->pcs_an_restart(pl->pcs); - } - -@@ -1126,7 +1127,7 @@ static void phylink_pcs_neg_mode(struct phylink *pl, struct phylink_pcs *pcs, - { - unsigned int neg_mode, mode; - -- mode = pl->cur_link_an_mode; -+ mode = pl->req_link_an_mode; - - switch (interface) { - case PHY_INTERFACE_MODE_SGMII: -@@ -1168,6 +1169,7 @@ static void phylink_pcs_neg_mode(struct phylink *pl, struct phylink_pcs *pcs, - } - - pl->pcs_neg_mode = neg_mode; -+ pl->act_link_an_mode = mode; - } - - static void phylink_major_config(struct phylink *pl, bool restart, -@@ -1198,7 +1200,7 @@ static void phylink_major_config(struct phylink *pl, bool restart, - phylink_pcs_poll_stop(pl); - - if (pl->mac_ops->mac_prepare) { -- err = pl->mac_ops->mac_prepare(pl->config, pl->cur_link_an_mode, -+ err = pl->mac_ops->mac_prepare(pl->config, pl->act_link_an_mode, - state->interface); - if (err < 0) { - phylink_err(pl, "mac_prepare failed: %pe\n", -@@ -1232,7 +1234,7 @@ static void phylink_major_config(struct phylink *pl, bool restart, - if (pl->pcs_state == PCS_STATE_STARTING || pcs_changed) - phylink_pcs_enable(pl->pcs); - -- neg_mode = pl->cur_link_an_mode; -+ neg_mode = pl->act_link_an_mode; - if (pl->pcs && pl->pcs->neg_mode) - neg_mode = pl->pcs_neg_mode; - -@@ -1248,7 +1250,7 @@ static void phylink_major_config(struct phylink *pl, bool restart, - phylink_pcs_an_restart(pl); - - if (pl->mac_ops->mac_finish) { -- err = pl->mac_ops->mac_finish(pl->config, pl->cur_link_an_mode, -+ err = pl->mac_ops->mac_finish(pl->config, pl->act_link_an_mode, - state->interface); - if (err < 0) - phylink_err(pl, "mac_finish failed: %pe\n", -@@ -1279,7 +1281,7 @@ static int phylink_change_inband_advert(struct phylink *pl) - return 0; - - phylink_dbg(pl, "%s: mode=%s/%s adv=%*pb pause=%02x\n", __func__, -- phylink_an_mode_str(pl->cur_link_an_mode), -+ phylink_an_mode_str(pl->req_link_an_mode), - phy_modes(pl->link_config.interface), - __ETHTOOL_LINK_MODE_MASK_NBITS, pl->link_config.advertising, - pl->link_config.pause); -@@ -1288,7 +1290,7 @@ static int phylink_change_inband_advert(struct phylink *pl) - phylink_pcs_neg_mode(pl, pl->pcs, pl->link_config.interface, - pl->link_config.advertising); - -- neg_mode = pl->cur_link_an_mode; -+ neg_mode = pl->act_link_an_mode; - if (pl->pcs->neg_mode) - neg_mode = pl->pcs_neg_mode; - -@@ -1353,7 +1355,7 @@ static void phylink_mac_initial_config(struct phylink *pl, bool force_restart) - { - struct phylink_link_state link_state; - -- switch (pl->cur_link_an_mode) { -+ switch (pl->req_link_an_mode) { - case MLO_AN_PHY: - link_state = pl->phy_state; - break; -@@ -1427,14 +1429,14 @@ static void phylink_link_up(struct phylink *pl, - - pl->cur_interface = link_state.interface; - -- neg_mode = pl->cur_link_an_mode; -+ neg_mode = pl->act_link_an_mode; - if (pl->pcs && pl->pcs->neg_mode) - neg_mode = pl->pcs_neg_mode; - - phylink_pcs_link_up(pl->pcs, neg_mode, pl->cur_interface, speed, - duplex); - -- pl->mac_ops->mac_link_up(pl->config, pl->phydev, pl->cur_link_an_mode, -+ pl->mac_ops->mac_link_up(pl->config, pl->phydev, pl->act_link_an_mode, - pl->cur_interface, speed, duplex, - !!(link_state.pause & MLO_PAUSE_TX), rx_pause); - -@@ -1454,7 +1456,7 @@ static void phylink_link_down(struct phylink *pl) - - if (ndev) - netif_carrier_off(ndev); -- pl->mac_ops->mac_link_down(pl->config, pl->cur_link_an_mode, -+ pl->mac_ops->mac_link_down(pl->config, pl->act_link_an_mode, - pl->cur_interface); - phylink_info(pl, "Link is Down\n"); - } -@@ -1480,10 +1482,10 @@ static void phylink_resolve(struct work_struct *w) - } else if (pl->link_failed) { - link_state.link = false; - retrigger = true; -- } else if (pl->cur_link_an_mode == MLO_AN_FIXED) { -+ } else if (pl->act_link_an_mode == MLO_AN_FIXED) { - phylink_get_fixed_state(pl, &link_state); - mac_config = link_state.link; -- } else if (pl->cur_link_an_mode == MLO_AN_PHY) { -+ } else if (pl->act_link_an_mode == MLO_AN_PHY) { - link_state = pl->phy_state; - mac_config = link_state.link; - } else { -@@ -1537,7 +1539,7 @@ static void phylink_resolve(struct work_struct *w) - } - } - -- if (pl->cur_link_an_mode != MLO_AN_FIXED) -+ if (pl->act_link_an_mode != MLO_AN_FIXED) - phylink_apply_manual_flow(pl, &link_state); - - if (mac_config) { -@@ -1661,7 +1663,7 @@ int phylink_set_fixed_link(struct phylink *pl, - pl->link_config.an_complete = 1; - - pl->cfg_link_an_mode = MLO_AN_FIXED; -- pl->cur_link_an_mode = pl->cfg_link_an_mode; -+ pl->req_link_an_mode = pl->cfg_link_an_mode; - - return 0; - } -@@ -1756,7 +1758,7 @@ struct phylink *phylink_create(struct phylink_config *config, - } - } - -- pl->cur_link_an_mode = pl->cfg_link_an_mode; -+ pl->req_link_an_mode = pl->cfg_link_an_mode; - - ret = phylink_register_sfp(pl, fwnode); - if (ret < 0) { -@@ -2213,7 +2215,7 @@ void phylink_start(struct phylink *pl) - ASSERT_RTNL(); - - phylink_info(pl, "configuring for %s/%s link mode\n", -- phylink_an_mode_str(pl->cur_link_an_mode), -+ phylink_an_mode_str(pl->req_link_an_mode), - phy_modes(pl->link_config.interface)); - - /* Always set the carrier off */ -@@ -2472,7 +2474,7 @@ int phylink_ethtool_ksettings_get(struct phylink *pl, - - linkmode_copy(kset->link_modes.supported, pl->supported); - -- switch (pl->cur_link_an_mode) { -+ switch (pl->act_link_an_mode) { - case MLO_AN_FIXED: - /* We are using fixed settings. Report these as the - * current link settings - and note that these also -@@ -2564,7 +2566,7 @@ int phylink_ethtool_ksettings_set(struct phylink *pl, - /* If we have a fixed link, refuse to change link parameters. - * If the link parameters match, accept them but do nothing. - */ -- if (pl->cur_link_an_mode == MLO_AN_FIXED) { -+ if (pl->req_link_an_mode == MLO_AN_FIXED) { - if (s->speed != pl->link_config.speed || - s->duplex != pl->link_config.duplex) - return -EINVAL; -@@ -2580,7 +2582,7 @@ int phylink_ethtool_ksettings_set(struct phylink *pl, - * is our default case) but do not allow the advertisement to - * be changed. If the advertisement matches, simply return. - */ -- if (pl->cur_link_an_mode == MLO_AN_FIXED) { -+ if (pl->req_link_an_mode == MLO_AN_FIXED) { - if (!linkmode_equal(config.advertising, - pl->link_config.advertising)) - return -EINVAL; -@@ -2620,7 +2622,7 @@ int phylink_ethtool_ksettings_set(struct phylink *pl, - linkmode_copy(support, pl->supported); - if (phylink_validate(pl, support, &config)) { - phylink_err(pl, "validation of %s/%s with support %*pb failed\n", -- phylink_an_mode_str(pl->cur_link_an_mode), -+ phylink_an_mode_str(pl->req_link_an_mode), - phy_modes(config.interface), - __ETHTOOL_LINK_MODE_MASK_NBITS, support); - return -EINVAL; -@@ -2720,7 +2722,7 @@ int phylink_ethtool_set_pauseparam(struct phylink *pl, - - ASSERT_RTNL(); - -- if (pl->cur_link_an_mode == MLO_AN_FIXED) -+ if (pl->req_link_an_mode == MLO_AN_FIXED) - return -EOPNOTSUPP; - - if (!phylink_test(pl->supported, Pause) && -@@ -2984,7 +2986,7 @@ static int phylink_mii_read(struct phylink *pl, unsigned int phy_id, - struct phylink_link_state state; - int val = 0xffff; - -- switch (pl->cur_link_an_mode) { -+ switch (pl->act_link_an_mode) { - case MLO_AN_FIXED: - if (phy_id == 0) { - phylink_get_fixed_state(pl, &state); -@@ -3009,7 +3011,7 @@ static int phylink_mii_read(struct phylink *pl, unsigned int phy_id, - static int phylink_mii_write(struct phylink *pl, unsigned int phy_id, - unsigned int reg, unsigned int val) - { -- switch (pl->cur_link_an_mode) { -+ switch (pl->act_link_an_mode) { - case MLO_AN_FIXED: - break; - -@@ -3199,9 +3201,9 @@ static void phylink_sfp_set_config(struct phylink *pl, u8 mode, - changed = true; - } - -- if (pl->cur_link_an_mode != mode || -+ if (pl->req_link_an_mode != mode || - pl->link_config.interface != state->interface) { -- pl->cur_link_an_mode = mode; -+ pl->req_link_an_mode = mode; - pl->link_config.interface = state->interface; - - changed = true; --- -2.51.0 - - -From 015e4e7cba0f05b10e53d1ce833f5dc67d2db231 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 3 Dec 2024 15:30:57 +0000 -Subject: [PATCH 038/517] net: phylink: add debug for phylink_major_config() - -Now that we have a more complexity in phylink_major_config(), augment -the debugging so we can see what's going on there. - -Reviewed-by: Andrew Lunn -Signed-off-by: Russell King (Oracle) -Link: https://patch.msgid.link/E1tIUrZ-006ITt-Fa@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 27 ++++++++++++++++++++++++++- - 1 file changed, 26 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c -index 5290afd0f54e..aa89c1f4706e 100644 ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -176,6 +176,24 @@ static const char *phylink_an_mode_str(unsigned int mode) - return mode < ARRAY_SIZE(modestr) ? modestr[mode] : "unknown"; - } - -+static const char *phylink_pcs_mode_str(unsigned int mode) -+{ -+ if (!mode) -+ return "none"; -+ -+ if (mode & PHYLINK_PCS_NEG_OUTBAND) -+ return "outband"; -+ -+ if (mode & PHYLINK_PCS_NEG_INBAND) { -+ if (mode & PHYLINK_PCS_NEG_ENABLED) -+ return "inband,an-enabled"; -+ else -+ return "inband,an-disabled"; -+ } -+ -+ return "unknown"; -+} -+ - static unsigned int phylink_interface_signal_rate(phy_interface_t interface) - { - switch (interface) { -@@ -1181,7 +1199,9 @@ static void phylink_major_config(struct phylink *pl, bool restart, - unsigned int neg_mode; - int err; - -- phylink_dbg(pl, "major config %s\n", phy_modes(state->interface)); -+ phylink_dbg(pl, "major config, requested %s/%s\n", -+ phylink_an_mode_str(pl->req_link_an_mode), -+ phy_modes(state->interface)); - - if (pl->using_mac_select_pcs) { - pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface); -@@ -1197,6 +1217,11 @@ static void phylink_major_config(struct phylink *pl, bool restart, - - phylink_pcs_neg_mode(pl, pcs, state->interface, state->advertising); - -+ phylink_dbg(pl, "major config, active %s/%s/%s\n", -+ phylink_an_mode_str(pl->act_link_an_mode), -+ phylink_pcs_mode_str(pl->pcs_neg_mode), -+ phy_modes(state->interface)); -+ - phylink_pcs_poll_stop(pl); - - if (pl->mac_ops->mac_prepare) { --- -2.51.0 - - -From 6d67fd0b655cd00cc2da9f15e01e6a26d8ec9f8e Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 3 Dec 2024 15:31:02 +0000 -Subject: [PATCH 039/517] net: phy: add phy_inband_caps() - -Add a method to query the PHY's in-band capabilities for a PHY -interface mode. - -Where the interface mode does not have in-band capability, or the PHY -driver has not been updated to return this information, then -phy_inband_caps() should return zero. Otherwise, PHY drivers will -return a value consisting of the following flags: - -LINK_INBAND_DISABLE indicates that the hardware does not support -in-band signalling, or can have in-band signalling configured via -software to be disabled. - -LINK_INBAND_ENABLE indicates that the hardware will use in-band -signalling, or can have in-band signalling configured via software -to be enabled. - -LINK_INBAND_BYPASS indicates that the hardware has the ability to -bypass in-band signalling when enabled after a timeout if the link -partner does not respond to its in-band signalling. - -This reports the PHY capabilities for the particular interface mode, -not the current configuration. - -Reviewed-by: Andrew Lunn -Signed-off-by: Russell King (Oracle) -Link: https://patch.msgid.link/E1tIUre-006ITz-KF@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phy.c | 21 +++++++++++++++++++++ - include/linux/phy.h | 28 ++++++++++++++++++++++++++++ - 2 files changed, 49 insertions(+) - -diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c -index c9cfdc33fc5f..8d91922d3bb9 100644 ---- a/drivers/net/phy/phy.c -+++ b/drivers/net/phy/phy.c -@@ -1048,6 +1048,27 @@ static int phy_check_link_status(struct phy_device *phydev) - return 0; - } - -+/** -+ * phy_inband_caps - query which in-band signalling modes are supported -+ * @phydev: a pointer to a &struct phy_device -+ * @interface: the interface mode for the PHY -+ * -+ * Returns zero if it is unknown what in-band signalling is supported by the -+ * PHY (e.g. because the PHY driver doesn't implement the method.) Otherwise, -+ * returns a bit mask of the LINK_INBAND_* values from -+ * &enum link_inband_signalling to describe which inband modes are supported -+ * by the PHY for this interface mode. -+ */ -+unsigned int phy_inband_caps(struct phy_device *phydev, -+ phy_interface_t interface) -+{ -+ if (phydev->drv && phydev->drv->inband_caps) -+ return phydev->drv->inband_caps(phydev, interface); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(phy_inband_caps); -+ - /** - * _phy_start_aneg - start auto-negotiation for this PHY device - * @phydev: the phy_device struct -diff --git a/include/linux/phy.h b/include/linux/phy.h -index dfc7b97f9648..fee0fad7538d 100644 ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -815,6 +815,24 @@ struct phy_tdr_config { - }; - #define PHY_PAIR_ALL -1 - -+/** -+ * enum link_inband_signalling - in-band signalling modes that are supported -+ * -+ * @LINK_INBAND_DISABLE: in-band signalling can be disabled -+ * @LINK_INBAND_ENABLE: in-band signalling can be enabled without bypass -+ * @LINK_INBAND_BYPASS: in-band signalling can be enabled with bypass -+ * -+ * The possible and required bits can only be used if the valid bit is set. -+ * If possible is clear, that means inband signalling can not be used. -+ * Required is only valid when possible is set, and means that inband -+ * signalling must be used. -+ */ -+enum link_inband_signalling { -+ LINK_INBAND_DISABLE = BIT(0), -+ LINK_INBAND_ENABLE = BIT(1), -+ LINK_INBAND_BYPASS = BIT(2), -+}; -+ - /** - * struct phy_plca_cfg - Configuration of the PLCA (Physical Layer Collision - * Avoidance) Reconciliation Sublayer. -@@ -953,6 +971,14 @@ struct phy_driver { - */ - int (*get_features)(struct phy_device *phydev); - -+ /** -+ * @inband_caps: query whether in-band is supported for the given PHY -+ * interface mode. Returns a bitmask of bits defined by enum -+ * link_inband_signalling. -+ */ -+ unsigned int (*inband_caps)(struct phy_device *phydev, -+ phy_interface_t interface); -+ - /** - * @get_rate_matching: Get the supported type of rate matching for a - * particular phy interface. This is used by phy consumers to determine -@@ -1832,6 +1858,8 @@ int phy_config_aneg(struct phy_device *phydev); - int _phy_start_aneg(struct phy_device *phydev); - int phy_start_aneg(struct phy_device *phydev); - int phy_aneg_done(struct phy_device *phydev); -+unsigned int phy_inband_caps(struct phy_device *phydev, -+ phy_interface_t interface); - int phy_speed_down(struct phy_device *phydev, bool sync); - int phy_speed_up(struct phy_device *phydev); - bool phy_check_valid(int speed, int duplex, unsigned long *features); --- -2.51.0 - - -From 8c321641d38995ad5b4412960e323283add4ecac Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 3 Dec 2024 15:31:07 +0000 -Subject: [PATCH 040/517] net: phy: bcm84881: implement phy_inband_caps() - method - -BCM84881 has no support for inband signalling, so this is a trivial -implementation that returns no support for inband. - -Reviewed-by: Andrew Lunn -Signed-off-by: Russell King (Oracle) -Acked-by: Florian Fainelli -Link: https://patch.msgid.link/E1tIUrj-006IU6-ON@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/bcm84881.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/drivers/net/phy/bcm84881.c b/drivers/net/phy/bcm84881.c -index 97da3aee4942..47405bded677 100644 ---- a/drivers/net/phy/bcm84881.c -+++ b/drivers/net/phy/bcm84881.c -@@ -235,11 +235,21 @@ static int bcm84881_read_status(struct phy_device *phydev) - return genphy_c45_read_mdix(phydev); - } - -+/* The Broadcom BCM84881 in the Methode DM7052 is unable to provide a SGMII -+ * or 802.3z control word, so inband will not work. -+ */ -+static unsigned int bcm84881_inband_caps(struct phy_device *phydev, -+ phy_interface_t interface) -+{ -+ return LINK_INBAND_DISABLE; -+} -+ - static struct phy_driver bcm84881_drivers[] = { - { - .phy_id = 0xae025150, - .phy_id_mask = 0xfffffff0, - .name = "Broadcom BCM84881", -+ .inband_caps = bcm84881_inband_caps, - .config_init = bcm84881_config_init, - .probe = bcm84881_probe, - .get_features = bcm84881_get_features, --- -2.51.0 - - -From d51b2838d0daaf2ca36abb4dd616b7ba170a2992 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 3 Dec 2024 15:31:12 +0000 -Subject: [PATCH 041/517] net: phy: marvell: implement phy_inband_caps() method - -Provide an implementation for phy_inband_caps() for Marvell PHYs used -on SFP modules, so that phylink knows the PHYs capabilities. - -Reviewed-by: Andrew Lunn -Signed-off-by: Russell King (Oracle) -Link: https://patch.msgid.link/E1tIUro-006IUC-Rq@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/marvell.c | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c -index 9964bf3dea2f..53f6711df93b 100644 ---- a/drivers/net/phy/marvell.c -+++ b/drivers/net/phy/marvell.c -@@ -716,6 +716,20 @@ static int marvell_config_aneg_fiber(struct phy_device *phydev) - return genphy_check_and_restart_aneg(phydev, changed); - } - -+static unsigned int m88e1111_inband_caps(struct phy_device *phydev, -+ phy_interface_t interface) -+{ -+ /* In 1000base-X and SGMII modes, the inband mode can be changed -+ * through the Fibre page BMCR ANENABLE bit. -+ */ -+ if (interface == PHY_INTERFACE_MODE_1000BASEX || -+ interface == PHY_INTERFACE_MODE_SGMII) -+ return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE | -+ LINK_INBAND_BYPASS; -+ -+ return 0; -+} -+ - static int m88e1111_config_aneg(struct phy_device *phydev) - { - int extsr = phy_read(phydev, MII_M1111_PHY_EXT_SR); -@@ -3667,6 +3681,7 @@ static struct phy_driver marvell_drivers[] = { - .name = "Marvell 88E1112", - /* PHY_GBIT_FEATURES */ - .probe = marvell_probe, -+ .inband_caps = m88e1111_inband_caps, - .config_init = m88e1112_config_init, - .config_aneg = marvell_config_aneg, - .config_intr = marvell_config_intr, -@@ -3688,6 +3703,7 @@ static struct phy_driver marvell_drivers[] = { - /* PHY_GBIT_FEATURES */ - .flags = PHY_POLL_CABLE_TEST, - .probe = marvell_probe, -+ .inband_caps = m88e1111_inband_caps, - .config_init = m88e1111gbe_config_init, - .config_aneg = m88e1111_config_aneg, - .read_status = marvell_read_status, -@@ -3711,6 +3727,7 @@ static struct phy_driver marvell_drivers[] = { - .name = "Marvell 88E1111 (Finisar)", - /* PHY_GBIT_FEATURES */ - .probe = marvell_probe, -+ .inband_caps = m88e1111_inband_caps, - .config_init = m88e1111gbe_config_init, - .config_aneg = m88e1111_config_aneg, - .read_status = marvell_read_status, --- -2.51.0 - - -From 3f3d8f3025892a86b501b3b2247438dc6d23f3bd Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 3 Dec 2024 15:31:18 +0000 -Subject: [PATCH 042/517] net: phy: add phy_config_inband() - -Add a method to configure the PHY's in-band mode. - -Reviewed-by: Andrew Lunn -Signed-off-by: Russell King (Oracle) -Link: https://patch.msgid.link/E1tIUru-006IUI-08@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phy.c | 32 ++++++++++++++++++++++++++++++++ - include/linux/phy.h | 6 ++++++ - 2 files changed, 38 insertions(+) - -diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c -index 8d91922d3bb9..1ab58bb5e6db 100644 ---- a/drivers/net/phy/phy.c -+++ b/drivers/net/phy/phy.c -@@ -1069,6 +1069,38 @@ unsigned int phy_inband_caps(struct phy_device *phydev, - } - EXPORT_SYMBOL_GPL(phy_inband_caps); - -+/** -+ * phy_config_inband - configure the desired PHY in-band mode -+ * @phydev: the phy_device struct -+ * @modes: in-band modes to configure -+ * -+ * Description: disables, enables or enables-with-bypass in-band signalling -+ * between the PHY and host system. -+ * -+ * Returns: zero on success, or negative errno value. -+ */ -+int phy_config_inband(struct phy_device *phydev, unsigned int modes) -+{ -+ int err; -+ -+ if (!!(modes & LINK_INBAND_DISABLE) + -+ !!(modes & LINK_INBAND_ENABLE) + -+ !!(modes & LINK_INBAND_BYPASS) != 1) -+ return -EINVAL; -+ -+ mutex_lock(&phydev->lock); -+ if (!phydev->drv) -+ err = -EIO; -+ else if (!phydev->drv->config_inband) -+ err = -EOPNOTSUPP; -+ else -+ err = phydev->drv->config_inband(phydev, modes); -+ mutex_unlock(&phydev->lock); -+ -+ return err; -+} -+EXPORT_SYMBOL(phy_config_inband); -+ - /** - * _phy_start_aneg - start auto-negotiation for this PHY device - * @phydev: the phy_device struct -diff --git a/include/linux/phy.h b/include/linux/phy.h -index fee0fad7538d..81c504d9850e 100644 ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -979,6 +979,11 @@ struct phy_driver { - unsigned int (*inband_caps)(struct phy_device *phydev, - phy_interface_t interface); - -+ /** -+ * @config_inband: configure in-band mode for the PHY -+ */ -+ int (*config_inband)(struct phy_device *phydev, unsigned int modes); -+ - /** - * @get_rate_matching: Get the supported type of rate matching for a - * particular phy interface. This is used by phy consumers to determine -@@ -1860,6 +1865,7 @@ int phy_start_aneg(struct phy_device *phydev); - int phy_aneg_done(struct phy_device *phydev); - unsigned int phy_inband_caps(struct phy_device *phydev, - phy_interface_t interface); -+int phy_config_inband(struct phy_device *phydev, unsigned int modes); - int phy_speed_down(struct phy_device *phydev, bool sync); - int phy_speed_up(struct phy_device *phydev); - bool phy_check_valid(int speed, int duplex, unsigned long *features); --- -2.51.0 - - -From e46d8359ab3011442c642952753d45c2482a605c Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 3 Dec 2024 15:31:23 +0000 -Subject: [PATCH 043/517] net: phy: marvell: implement config_inband() method - -Implement the config_inband() method for Marvell 88E1112, 88E1111, -and Finisar's 88E1111 variant. - -Reviewed-by: Andrew Lunn -Signed-off-by: Russell King (Oracle) -Link: https://patch.msgid.link/E1tIUrz-006IUO-3r@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/marvell.c | 31 +++++++++++++++++++++++++++++++ - 1 file changed, 31 insertions(+) - -diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c -index 53f6711df93b..b7d2951d979d 100644 ---- a/drivers/net/phy/marvell.c -+++ b/drivers/net/phy/marvell.c -@@ -730,6 +730,34 @@ static unsigned int m88e1111_inband_caps(struct phy_device *phydev, - return 0; - } - -+static int m88e1111_config_inband(struct phy_device *phydev, unsigned int modes) -+{ -+ u16 extsr, bmcr; -+ int err; -+ -+ if (phydev->interface != PHY_INTERFACE_MODE_1000BASEX && -+ phydev->interface != PHY_INTERFACE_MODE_SGMII) -+ return -EINVAL; -+ -+ if (modes == LINK_INBAND_BYPASS) -+ extsr = MII_M1111_HWCFG_SERIAL_AN_BYPASS; -+ else -+ extsr = 0; -+ -+ if (modes == LINK_INBAND_DISABLE) -+ bmcr = 0; -+ else -+ bmcr = BMCR_ANENABLE; -+ -+ err = phy_modify(phydev, MII_M1111_PHY_EXT_SR, -+ MII_M1111_HWCFG_SERIAL_AN_BYPASS, extsr); -+ if (err < 0) -+ return extsr; -+ -+ return phy_modify_paged(phydev, MII_MARVELL_FIBER_PAGE, MII_BMCR, -+ BMCR_ANENABLE, bmcr); -+} -+ - static int m88e1111_config_aneg(struct phy_device *phydev) - { - int extsr = phy_read(phydev, MII_M1111_PHY_EXT_SR); -@@ -3682,6 +3710,7 @@ static struct phy_driver marvell_drivers[] = { - /* PHY_GBIT_FEATURES */ - .probe = marvell_probe, - .inband_caps = m88e1111_inband_caps, -+ .config_inband = m88e1111_config_inband, - .config_init = m88e1112_config_init, - .config_aneg = marvell_config_aneg, - .config_intr = marvell_config_intr, -@@ -3704,6 +3733,7 @@ static struct phy_driver marvell_drivers[] = { - .flags = PHY_POLL_CABLE_TEST, - .probe = marvell_probe, - .inband_caps = m88e1111_inband_caps, -+ .config_inband = m88e1111_config_inband, - .config_init = m88e1111gbe_config_init, - .config_aneg = m88e1111_config_aneg, - .read_status = marvell_read_status, -@@ -3728,6 +3758,7 @@ static struct phy_driver marvell_drivers[] = { - /* PHY_GBIT_FEATURES */ - .probe = marvell_probe, - .inband_caps = m88e1111_inband_caps, -+ .config_inband = m88e1111_config_inband, - .config_init = m88e1111gbe_config_init, - .config_aneg = m88e1111_config_aneg, - .read_status = marvell_read_status, --- -2.51.0 - - -From 53185318bdfaf4dbfcc0568513e3b3883e30520c Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 3 Dec 2024 15:31:28 +0000 -Subject: [PATCH 044/517] net: phylink: add pcs_inband_caps() method - -Add a pcs_inband_caps() method to query the PCS for its inband link -capabilities, and use this to determine whether link modes used with -optical SFPs can be supported. - -When a PCS does not provide a method, we allow inband negotiation to -be either on or off, making this a no-op until the pcs_inband_caps() -method is implemented by a PCS driver. - -Reviewed-by: Andrew Lunn -Signed-off-by: Russell King (Oracle) -Link: https://patch.msgid.link/E1tIUs4-006IUU-7K@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 60 +++++++++++++++++++++++++++++++++++++++ - include/linux/phylink.h | 17 +++++++++++ - 2 files changed, 77 insertions(+) - -diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c -index aa89c1f4706e..c358ab5c16a7 100644 ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -1007,6 +1007,15 @@ static void phylink_resolve_an_pause(struct phylink_link_state *state) - } - } - -+static unsigned int phylink_pcs_inband_caps(struct phylink_pcs *pcs, -+ phy_interface_t interface) -+{ -+ if (pcs && pcs->ops->pcs_inband_caps) -+ return pcs->ops->pcs_inband_caps(pcs, interface); -+ -+ return 0; -+} -+ - static void phylink_pcs_pre_config(struct phylink_pcs *pcs, - phy_interface_t interface) - { -@@ -1060,6 +1069,24 @@ static void phylink_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode, - pcs->ops->pcs_link_up(pcs, neg_mode, interface, speed, duplex); - } - -+/* Query inband for a specific interface mode, asking the MAC for the -+ * PCS which will be used to handle the interface mode. -+ */ -+static unsigned int phylink_inband_caps(struct phylink *pl, -+ phy_interface_t interface) -+{ -+ struct phylink_pcs *pcs; -+ -+ if (!pl->mac_ops->mac_select_pcs) -+ return 0; -+ -+ pcs = pl->mac_ops->mac_select_pcs(pl->config, interface); -+ if (!pcs) -+ return 0; -+ -+ return phylink_pcs_inband_caps(pcs, interface); -+} -+ - static void phylink_pcs_poll_stop(struct phylink *pl) - { - if (pl->cfg_link_an_mode == MLO_AN_INBAND) -@@ -2530,6 +2557,26 @@ int phylink_ethtool_ksettings_get(struct phylink *pl, - } - EXPORT_SYMBOL_GPL(phylink_ethtool_ksettings_get); - -+static bool phylink_validate_pcs_inband_autoneg(struct phylink *pl, -+ phy_interface_t interface, -+ unsigned long *adv) -+{ -+ unsigned int inband = phylink_inband_caps(pl, interface); -+ unsigned int mask; -+ -+ /* If the PCS doesn't implement inband support, be permissive. */ -+ if (!inband) -+ return true; -+ -+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, adv)) -+ mask = LINK_INBAND_ENABLE; -+ else -+ mask = LINK_INBAND_DISABLE; -+ -+ /* Check whether the PCS implements the required mode */ -+ return !!(inband & mask); -+} -+ - /** - * phylink_ethtool_ksettings_set() - set the link settings - * @pl: a pointer to a &struct phylink returned from phylink_create() -@@ -2665,6 +2712,13 @@ int phylink_ethtool_ksettings_set(struct phylink *pl, - phylink_is_empty_linkmode(config.advertising)) - return -EINVAL; - -+ /* Validate the autonegotiation state. We don't have a PHY in this -+ * situation, so the PCS is the media-facing entity. -+ */ -+ if (!phylink_validate_pcs_inband_autoneg(pl, config.interface, -+ config.advertising)) -+ return -EINVAL; -+ - mutex_lock(&pl->state_mutex); - pl->link_config.speed = config.speed; - pl->link_config.duplex = config.duplex; -@@ -3349,6 +3403,12 @@ static int phylink_sfp_config_optical(struct phylink *pl) - phylink_dbg(pl, "optical SFP: chosen %s interface\n", - phy_modes(interface)); - -+ if (!phylink_validate_pcs_inband_autoneg(pl, interface, -+ config.advertising)) { -+ phylink_err(pl, "autoneg setting not compatible with PCS"); -+ return -EINVAL; -+ } -+ - config.interface = interface; - - /* Ignore errors if we're expecting a PHY to attach later */ -diff --git a/include/linux/phylink.h b/include/linux/phylink.h -index 5c01048860c4..5462cc6a37dc 100644 ---- a/include/linux/phylink.h -+++ b/include/linux/phylink.h -@@ -419,6 +419,7 @@ struct phylink_pcs { - /** - * struct phylink_pcs_ops - MAC PCS operations structure. - * @pcs_validate: validate the link configuration. -+ * @pcs_inband_caps: query inband support for interface mode. - * @pcs_enable: enable the PCS. - * @pcs_disable: disable the PCS. - * @pcs_pre_config: pre-mac_config method (for errata) -@@ -434,6 +435,8 @@ struct phylink_pcs { - struct phylink_pcs_ops { - int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported, - const struct phylink_link_state *state); -+ unsigned int (*pcs_inband_caps)(struct phylink_pcs *pcs, -+ phy_interface_t interface); - int (*pcs_enable)(struct phylink_pcs *pcs); - void (*pcs_disable)(struct phylink_pcs *pcs); - void (*pcs_pre_config)(struct phylink_pcs *pcs, -@@ -470,6 +473,20 @@ struct phylink_pcs_ops { - int pcs_validate(struct phylink_pcs *pcs, unsigned long *supported, - const struct phylink_link_state *state); - -+/** -+ * pcs_inband_caps - query PCS in-band capabilities for interface mode. -+ * @pcs: a pointer to a &struct phylink_pcs. -+ * @interface: interface mode to be queried -+ * -+ * Returns zero if it is unknown what in-band signalling is supported by the -+ * PHY (e.g. because the PHY driver doesn't implement the method.) Otherwise, -+ * returns a bit mask of the LINK_INBAND_* values from -+ * &enum link_inband_signalling to describe which inband modes are supported -+ * for this interface mode. -+ */ -+unsigned int pcs_inband_caps(struct phylink_pcs *pcs, -+ phy_interface_t interface); -+ - /** - * pcs_enable() - enable the PCS. - * @pcs: a pointer to a &struct phylink_pcs. --- -2.51.0 - - -From d39d93def7796638ddfe476907564390b4a97191 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 3 Dec 2024 15:31:33 +0000 -Subject: [PATCH 045/517] net: mvneta: implement pcs_inband_caps() method - -Report the PCS in-band capabilities to phylink for Marvell NETA -interfaces. - -Reviewed-by: Andrew Lunn -Signed-off-by: Russell King (Oracle) -Link: https://patch.msgid.link/E1tIUs9-006IUb-Au@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/marvell/mvneta.c | 27 +++++++++++++++++---------- - 1 file changed, 17 insertions(+), 10 deletions(-) - -diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c -index d72b2d5f96db..0a5b93857fb5 100644 ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -3960,20 +3960,27 @@ static struct mvneta_port *mvneta_pcs_to_port(struct phylink_pcs *pcs) - return container_of(pcs, struct mvneta_port, phylink_pcs); - } - --static int mvneta_pcs_validate(struct phylink_pcs *pcs, -- unsigned long *supported, -- const struct phylink_link_state *state) -+static unsigned int mvneta_pcs_inband_caps(struct phylink_pcs *pcs, -+ phy_interface_t interface) - { -- /* We only support QSGMII, SGMII, 802.3z and RGMII modes. -- * When in 802.3z mode, we must have AN enabled: -+ /* When operating in an 802.3z mode, we must have AN enabled: - * "Bit 2 Field InBandAnEn In-band Auto-Negotiation enable. ... - * When = 1 (1000BASE-X) this field must be set to 1." -+ * Therefore, inband is "required". - */ -- if (phy_interface_mode_is_8023z(state->interface) && -- !phylink_test(state->advertising, Autoneg)) -- return -EINVAL; -+ if (phy_interface_mode_is_8023z(interface)) -+ return LINK_INBAND_ENABLE; - -- return 0; -+ /* QSGMII, SGMII and RGMII can be configured to use inband -+ * signalling of the AN result. Indicate these as "possible". -+ */ -+ if (interface == PHY_INTERFACE_MODE_SGMII || -+ interface == PHY_INTERFACE_MODE_QSGMII || -+ phy_interface_mode_is_rgmii(interface)) -+ return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE; -+ -+ /* For any other modes, indicate that inband is not supported. */ -+ return LINK_INBAND_DISABLE; - } - - static void mvneta_pcs_get_state(struct phylink_pcs *pcs, -@@ -4071,7 +4078,7 @@ static void mvneta_pcs_an_restart(struct phylink_pcs *pcs) - } - - static const struct phylink_pcs_ops mvneta_phylink_pcs_ops = { -- .pcs_validate = mvneta_pcs_validate, -+ .pcs_inband_caps = mvneta_pcs_inband_caps, - .pcs_get_state = mvneta_pcs_get_state, - .pcs_config = mvneta_pcs_config, - .pcs_an_restart = mvneta_pcs_an_restart, --- -2.51.0 - - -From a1520f83646272782f463024a858f31623494124 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 3 Dec 2024 15:31:38 +0000 -Subject: [PATCH 046/517] net: mvpp2: implement pcs_inband_caps() method - -Report the PCS in-band capabilities to phylink for Marvell PP2 -interfaces. - -Reviewed-by: Andrew Lunn -Signed-off-by: Russell King (Oracle) -Link: https://patch.msgid.link/E1tIUsE-006IUh-E7@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 25 ++++++++++++------- - 1 file changed, 16 insertions(+), 9 deletions(-) - -diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c -index 66b5a80c9c28..ebb49c04a7a0 100644 ---- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c -+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c -@@ -6237,19 +6237,26 @@ static const struct phylink_pcs_ops mvpp2_phylink_xlg_pcs_ops = { - .pcs_config = mvpp2_xlg_pcs_config, - }; - --static int mvpp2_gmac_pcs_validate(struct phylink_pcs *pcs, -- unsigned long *supported, -- const struct phylink_link_state *state) -+static unsigned int mvpp2_gmac_pcs_inband_caps(struct phylink_pcs *pcs, -+ phy_interface_t interface) - { -- /* When in 802.3z mode, we must have AN enabled: -+ /* When operating in an 802.3z mode, we must have AN enabled: - * Bit 2 Field InBandAnEn In-band Auto-Negotiation enable. ... - * When = 1 (1000BASE-X) this field must be set to 1. -+ * Therefore, inband is "required". - */ -- if (phy_interface_mode_is_8023z(state->interface) && -- !phylink_test(state->advertising, Autoneg)) -- return -EINVAL; -+ if (phy_interface_mode_is_8023z(interface)) -+ return LINK_INBAND_ENABLE; - -- return 0; -+ /* SGMII and RGMII can be configured to use inband signalling of the -+ * AN result. Indicate these as "possible". -+ */ -+ if (interface == PHY_INTERFACE_MODE_SGMII || -+ phy_interface_mode_is_rgmii(interface)) -+ return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE; -+ -+ /* For any other modes, indicate that inband is not supported. */ -+ return LINK_INBAND_DISABLE; - } - - static void mvpp2_gmac_pcs_get_state(struct phylink_pcs *pcs, -@@ -6356,7 +6363,7 @@ static void mvpp2_gmac_pcs_an_restart(struct phylink_pcs *pcs) - } - - static const struct phylink_pcs_ops mvpp2_phylink_gmac_pcs_ops = { -- .pcs_validate = mvpp2_gmac_pcs_validate, -+ .pcs_inband_caps = mvpp2_gmac_pcs_inband_caps, - .pcs_get_state = mvpp2_gmac_pcs_get_state, - .pcs_config = mvpp2_gmac_pcs_config, - .pcs_an_restart = mvpp2_gmac_pcs_an_restart, --- -2.51.0 - - -From c34544c535d20859435b80f2dd0052323036eb9e Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 3 Dec 2024 15:31:43 +0000 -Subject: [PATCH 047/517] net: phylink: add negotiation of in-band capabilities - -Support for in-band signalling with Serdes links is uncertain. Some -PHYs do not support in-band for e.g. SGMII. Some PCS do not support -in-band for 2500Base-X. Some PCS require in-band for Base-X protocols. - -Simply using what is in DT is insufficient when we have hot-pluggable -PHYs e.g. in the form of SFP modules, which may not provide the -in-band signalling. - -In order to address this, we have introduced phy_inband_caps() and -pcs_inband_caps() functions to allow phylink to retrieve the -capabilities from each end of the PCS/PHY link. This commit adds code -to resolve whether in-band will be used in the various scenarios that -we have: In-band not being used, PHY present using SGMII or Base-X, -PHY not present. We also deal with no capabilties provided. - -Signed-off-by: Russell King (Oracle) -Link: https://patch.msgid.link/E1tIUsJ-006IUn-H3@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 154 +++++++++++++++++++++++++++++++++++--- - 1 file changed, 144 insertions(+), 10 deletions(-) - -diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c -index c358ab5c16a7..f07c674816db 100644 ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -75,6 +75,7 @@ struct phylink { - - struct mutex state_mutex; - struct phylink_link_state phy_state; -+ unsigned int phy_ib_mode; - struct work_struct resolve; - unsigned int pcs_neg_mode; - unsigned int pcs_state; -@@ -1170,10 +1171,18 @@ static void phylink_pcs_neg_mode(struct phylink *pl, struct phylink_pcs *pcs, - phy_interface_t interface, - const unsigned long *advertising) - { -+ unsigned int pcs_ib_caps = 0; -+ unsigned int phy_ib_caps = 0; - unsigned int neg_mode, mode; -+ enum { -+ INBAND_CISCO_SGMII, -+ INBAND_BASEX, -+ } type; - - mode = pl->req_link_an_mode; - -+ pl->phy_ib_mode = 0; -+ - switch (interface) { - case PHY_INTERFACE_MODE_SGMII: - case PHY_INTERFACE_MODE_QSGMII: -@@ -1185,10 +1194,7 @@ static void phylink_pcs_neg_mode(struct phylink *pl, struct phylink_pcs *pcs, - * inband communication. Note: there exist PHYs that run - * with SGMII but do not send the inband data. - */ -- if (!phylink_autoneg_inband(mode)) -- neg_mode = PHYLINK_PCS_NEG_OUTBAND; -- else -- neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED; -+ type = INBAND_CISCO_SGMII; - break; - - case PHY_INTERFACE_MODE_1000BASEX: -@@ -1199,18 +1205,139 @@ static void phylink_pcs_neg_mode(struct phylink *pl, struct phylink_pcs *pcs, - * as well, but drivers may not support this, so may - * need to override this. - */ -- if (!phylink_autoneg_inband(mode)) -+ type = INBAND_BASEX; -+ break; -+ -+ default: -+ pl->pcs_neg_mode = PHYLINK_PCS_NEG_NONE; -+ pl->act_link_an_mode = mode; -+ return; -+ } -+ -+ if (pcs) -+ pcs_ib_caps = phylink_pcs_inband_caps(pcs, interface); -+ -+ if (pl->phydev) -+ phy_ib_caps = phy_inband_caps(pl->phydev, interface); -+ -+ phylink_dbg(pl, "interface %s inband modes: pcs=%02x phy=%02x\n", -+ phy_modes(interface), pcs_ib_caps, phy_ib_caps); -+ -+ if (!phylink_autoneg_inband(mode)) { -+ bool pcs_ib_only = false; -+ bool phy_ib_only = false; -+ -+ if (pcs_ib_caps && pcs_ib_caps != LINK_INBAND_DISABLE) { -+ /* PCS supports reporting in-band capabilities, and -+ * supports more than disable mode. -+ */ -+ if (pcs_ib_caps & LINK_INBAND_DISABLE) -+ neg_mode = PHYLINK_PCS_NEG_OUTBAND; -+ else if (pcs_ib_caps & LINK_INBAND_ENABLE) -+ pcs_ib_only = true; -+ } -+ -+ if (phy_ib_caps && phy_ib_caps != LINK_INBAND_DISABLE) { -+ /* PHY supports in-band capabilities, and supports -+ * more than disable mode. -+ */ -+ if (phy_ib_caps & LINK_INBAND_DISABLE) -+ pl->phy_ib_mode = LINK_INBAND_DISABLE; -+ else if (phy_ib_caps & LINK_INBAND_BYPASS) -+ pl->phy_ib_mode = LINK_INBAND_BYPASS; -+ else if (phy_ib_caps & LINK_INBAND_ENABLE) -+ phy_ib_only = true; -+ } -+ -+ /* If either the PCS or PHY requires inband to be enabled, -+ * this is an invalid configuration. Provide a diagnostic -+ * message for this case, but don't try to force the issue. -+ */ -+ if (pcs_ib_only || phy_ib_only) -+ phylink_warn(pl, -+ "firmware wants %s mode, but %s%s%s requires inband\n", -+ phylink_an_mode_str(mode), -+ pcs_ib_only ? "PCS" : "", -+ pcs_ib_only && phy_ib_only ? " and " : "", -+ phy_ib_only ? "PHY" : ""); -+ -+ neg_mode = PHYLINK_PCS_NEG_OUTBAND; -+ } else if (type == INBAND_CISCO_SGMII || pl->phydev) { -+ /* For SGMII modes which are designed to be used with PHYs, or -+ * Base-X with a PHY, we try to use in-band mode where-ever -+ * possible. However, there are some PHYs e.g. BCM84881 which -+ * do not support in-band. -+ */ -+ const unsigned int inband_ok = LINK_INBAND_ENABLE | -+ LINK_INBAND_BYPASS; -+ const unsigned int outband_ok = LINK_INBAND_DISABLE | -+ LINK_INBAND_BYPASS; -+ /* PCS PHY -+ * D E D E -+ * 0 0 0 0 no information inband enabled -+ * 1 0 0 0 pcs doesn't support outband -+ * 0 1 0 0 pcs required inband enabled -+ * 1 1 0 0 pcs optional inband enabled -+ * 0 0 1 0 phy doesn't support outband -+ * 1 0 1 0 pcs+phy doesn't support outband -+ * 0 1 1 0 pcs required, phy doesn't support, invalid -+ * 1 1 1 0 pcs optional, phy doesn't support, outband -+ * 0 0 0 1 phy required inband enabled -+ * 1 0 0 1 pcs doesn't support, phy required, invalid -+ * 0 1 0 1 pcs+phy required inband enabled -+ * 1 1 0 1 pcs optional, phy required inband enabled -+ * 0 0 1 1 phy optional inband enabled -+ * 1 0 1 1 pcs doesn't support, phy optional, outband -+ * 0 1 1 1 pcs required, phy optional inband enabled -+ * 1 1 1 1 pcs+phy optional inband enabled -+ */ -+ if ((!pcs_ib_caps || pcs_ib_caps & inband_ok) && -+ (!phy_ib_caps || phy_ib_caps & inband_ok)) { -+ /* In-band supported or unknown at both ends. Enable -+ * in-band mode with or without bypass at the PHY. -+ */ -+ if (phy_ib_caps & LINK_INBAND_ENABLE) -+ pl->phy_ib_mode = LINK_INBAND_ENABLE; -+ else if (phy_ib_caps & LINK_INBAND_BYPASS) -+ pl->phy_ib_mode = LINK_INBAND_BYPASS; -+ -+ neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED; -+ } else if ((!pcs_ib_caps || pcs_ib_caps & outband_ok) && -+ (!phy_ib_caps || phy_ib_caps & outband_ok)) { -+ /* Either in-band not supported at at least one end. -+ * In-band bypass at the other end is possible. -+ */ -+ if (phy_ib_caps & LINK_INBAND_DISABLE) -+ pl->phy_ib_mode = LINK_INBAND_DISABLE; -+ else if (phy_ib_caps & LINK_INBAND_BYPASS) -+ pl->phy_ib_mode = LINK_INBAND_BYPASS; -+ - neg_mode = PHYLINK_PCS_NEG_OUTBAND; -+ if (pl->phydev) -+ mode = MLO_AN_PHY; -+ } else { -+ /* invalid */ -+ phylink_warn(pl, "%s: incompatible in-band capabilities, trying in-band", -+ phy_modes(interface)); -+ neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED; -+ } -+ } else { -+ /* For Base-X without a PHY */ -+ if (pcs_ib_caps == LINK_INBAND_DISABLE) -+ /* If the PCS doesn't support inband, then inband must -+ * be disabled. -+ */ -+ neg_mode = PHYLINK_PCS_NEG_INBAND_DISABLED; -+ else if (pcs_ib_caps == LINK_INBAND_ENABLE) -+ /* If the PCS requires inband, then inband must always -+ * be enabled. -+ */ -+ neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED; - else if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, - advertising)) - neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED; - else - neg_mode = PHYLINK_PCS_NEG_INBAND_DISABLED; -- break; -- -- default: -- neg_mode = PHYLINK_PCS_NEG_NONE; -- break; - } - - pl->pcs_neg_mode = neg_mode; -@@ -1309,6 +1436,13 @@ static void phylink_major_config(struct phylink *pl, bool restart, - ERR_PTR(err)); - } - -+ if (pl->phydev && pl->phy_ib_mode) { -+ err = phy_config_inband(pl->phydev, pl->phy_ib_mode); -+ if (err < 0) -+ phylink_err(pl, "phy_config_inband: %pe\n", -+ ERR_PTR(err)); -+ } -+ - if (pl->sfp_bus) { - rate_kbd = phylink_interface_signal_rate(state->interface); - if (rate_kbd) --- -2.51.0 - - -From 99013b966414b56578184ade8275d7065a49d243 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 3 Dec 2024 15:31:48 +0000 -Subject: [PATCH 048/517] net: phylink: remove phylink_phy_no_inband() - -Remove phylink_phy_no_inband() now that we are handling the lack of -inband negotiation by querying the capabilities of the PHY and PCS, -and the BCM84881 PHY driver provides us the information necessary to -make the decision. - -Reviewed-by: Andrew Lunn -Signed-off-by: Russell King (Oracle) -Link: https://patch.msgid.link/E1tIUsO-006IUt-KN@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 29 +++++++---------------------- - 1 file changed, 7 insertions(+), 22 deletions(-) - -diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c -index f07c674816db..ede93109f9c5 100644 ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -3394,10 +3394,11 @@ static phy_interface_t phylink_choose_sfp_interface(struct phylink *pl, - return interface; - } - --static void phylink_sfp_set_config(struct phylink *pl, u8 mode, -+static void phylink_sfp_set_config(struct phylink *pl, - unsigned long *supported, - struct phylink_link_state *state) - { -+ u8 mode = MLO_AN_INBAND; - bool changed = false; - - phylink_dbg(pl, "requesting link mode %s/%s with support %*pb\n", -@@ -3431,8 +3432,7 @@ static void phylink_sfp_set_config(struct phylink *pl, u8 mode, - phylink_mac_initial_config(pl, false); - } - --static int phylink_sfp_config_phy(struct phylink *pl, u8 mode, -- struct phy_device *phy) -+static int phylink_sfp_config_phy(struct phylink *pl, struct phy_device *phy) - { - __ETHTOOL_DECLARE_LINK_MODE_MASK(support1); - __ETHTOOL_DECLARE_LINK_MODE_MASK(support); -@@ -3472,7 +3472,7 @@ static int phylink_sfp_config_phy(struct phylink *pl, u8 mode, - if (ret) { - phylink_err(pl, - "validation of %s/%s with support %*pb failed: %pe\n", -- phylink_an_mode_str(mode), -+ phylink_an_mode_str(pl->req_link_an_mode), - phy_modes(config.interface), - __ETHTOOL_LINK_MODE_MASK_NBITS, support, - ERR_PTR(ret)); -@@ -3481,7 +3481,7 @@ static int phylink_sfp_config_phy(struct phylink *pl, u8 mode, - - pl->link_port = pl->sfp_port; - -- phylink_sfp_set_config(pl, mode, support, &config); -+ phylink_sfp_set_config(pl, support, &config); - - return 0; - } -@@ -3556,7 +3556,7 @@ static int phylink_sfp_config_optical(struct phylink *pl) - - pl->link_port = pl->sfp_port; - -- phylink_sfp_set_config(pl, MLO_AN_INBAND, pl->sfp_support, &config); -+ phylink_sfp_set_config(pl, pl->sfp_support, &config); - - return 0; - } -@@ -3627,20 +3627,10 @@ static void phylink_sfp_link_up(void *upstream) - phylink_enable_and_run_resolve(pl, PHYLINK_DISABLE_LINK); - } - --/* The Broadcom BCM84881 in the Methode DM7052 is unable to provide a SGMII -- * or 802.3z control word, so inband will not work. -- */ --static bool phylink_phy_no_inband(struct phy_device *phy) --{ -- return phy->is_c45 && phy_id_compare(phy->c45_ids.device_ids[1], -- 0xae025150, 0xfffffff0); --} -- - static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy) - { - struct phylink *pl = upstream; - phy_interface_t interface; -- u8 mode; - int ret; - - /* -@@ -3652,17 +3642,12 @@ static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy) - */ - phy_support_asym_pause(phy); - -- if (phylink_phy_no_inband(phy)) -- mode = MLO_AN_PHY; -- else -- mode = MLO_AN_INBAND; -- - /* Set the PHY's host supported interfaces */ - phy_interface_and(phy->host_interfaces, phylink_sfp_interfaces, - pl->config->supported_interfaces); - - /* Do the initial configuration */ -- ret = phylink_sfp_config_phy(pl, mode, phy); -+ ret = phylink_sfp_config_phy(pl, phy); - if (ret < 0) - return ret; - --- -2.51.0 - - -From 68b5488d76a29ee77592a116997e837791415755 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 5 Dec 2024 09:42:24 +0000 -Subject: [PATCH 049/517] net: pcs: pcs-lynx: implement pcs_inband_caps() - method - -Report the PCS in-band capabilities to phylink for the Lynx PCS. - -Reviewed-by: Maxime Chevallier -Signed-off-by: Russell King (Oracle) -Link: https://patch.msgid.link/E1tJ8NM-006L5J-AH@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/pcs/pcs-lynx.c | 22 ++++++++++++++++++++++ - 1 file changed, 22 insertions(+) - -diff --git a/drivers/net/pcs/pcs-lynx.c b/drivers/net/pcs/pcs-lynx.c -index b79aedad855b..767a8c0714ac 100644 ---- a/drivers/net/pcs/pcs-lynx.c -+++ b/drivers/net/pcs/pcs-lynx.c -@@ -35,6 +35,27 @@ enum sgmii_speed { - #define phylink_pcs_to_lynx(pl_pcs) container_of((pl_pcs), struct lynx_pcs, pcs) - #define lynx_to_phylink_pcs(lynx) (&(lynx)->pcs) - -+static unsigned int lynx_pcs_inband_caps(struct phylink_pcs *pcs, -+ phy_interface_t interface) -+{ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_1000BASEX: -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_QSGMII: -+ return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE; -+ -+ case PHY_INTERFACE_MODE_10GBASER: -+ case PHY_INTERFACE_MODE_2500BASEX: -+ return LINK_INBAND_DISABLE; -+ -+ case PHY_INTERFACE_MODE_USXGMII: -+ return LINK_INBAND_ENABLE; -+ -+ default: -+ return 0; -+ } -+} -+ - static void lynx_pcs_get_state_usxgmii(struct mdio_device *pcs, - struct phylink_link_state *state) - { -@@ -306,6 +327,7 @@ static void lynx_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode, - } - - static const struct phylink_pcs_ops lynx_pcs_phylink_ops = { -+ .pcs_inband_caps = lynx_pcs_inband_caps, - .pcs_get_state = lynx_pcs_get_state, - .pcs_config = lynx_pcs_config, - .pcs_an_restart = lynx_pcs_an_restart, --- -2.51.0 - - -From 82dcb9cbcc5292ffb27082e1f6376298cca39999 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 5 Dec 2024 09:42:29 +0000 -Subject: [PATCH 050/517] net: pcs: pcs-mtk-lynxi: implement pcs_inband_caps() - method - -Report the PCS in-band capabilities to phylink for the LynxI PCS. - -Signed-off-by: Russell King (Oracle) -Link: https://patch.msgid.link/E1tJ8NR-006L5P-E3@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/pcs/pcs-mtk-lynxi.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/drivers/net/pcs/pcs-mtk-lynxi.c b/drivers/net/pcs/pcs-mtk-lynxi.c -index 4f63abe638c4..7de804535229 100644 ---- a/drivers/net/pcs/pcs-mtk-lynxi.c -+++ b/drivers/net/pcs/pcs-mtk-lynxi.c -@@ -88,6 +88,21 @@ static struct mtk_pcs_lynxi *pcs_to_mtk_pcs_lynxi(struct phylink_pcs *pcs) - return container_of(pcs, struct mtk_pcs_lynxi, pcs); - } - -+static unsigned int mtk_pcs_lynxi_inband_caps(struct phylink_pcs *pcs, -+ phy_interface_t interface) -+{ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_1000BASEX: -+ case PHY_INTERFACE_MODE_2500BASEX: -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_QSGMII: -+ return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE; -+ -+ default: -+ return 0; -+ } -+} -+ - static void mtk_pcs_lynxi_get_state(struct phylink_pcs *pcs, - struct phylink_link_state *state) - { -@@ -241,6 +256,7 @@ static void mtk_pcs_lynxi_disable(struct phylink_pcs *pcs) - } - - static const struct phylink_pcs_ops mtk_pcs_lynxi_ops = { -+ .pcs_inband_caps = mtk_pcs_lynxi_inband_caps, - .pcs_get_state = mtk_pcs_lynxi_get_state, - .pcs_config = mtk_pcs_lynxi_config, - .pcs_an_restart = mtk_pcs_lynxi_restart_an, --- -2.51.0 - - -From 4e4de8707612bd5ed15b49af0be4f10efdaec455 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 5 Dec 2024 09:42:34 +0000 -Subject: [PATCH 051/517] net: pcs: xpcs: implement pcs_inband_caps() method - -Report the PCS inband capabilities to phylink for XPCS. - -Signed-off-by: Russell King (Oracle) -Link: https://patch.msgid.link/E1tJ8NW-006L5V-I9@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/pcs/pcs-xpcs.c | 28 ++++++++++++++++++++++++++++ - 1 file changed, 28 insertions(+) - -diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c -index 82463f9d50c8..1f0ec847895c 100644 ---- a/drivers/net/pcs/pcs-xpcs.c -+++ b/drivers/net/pcs/pcs-xpcs.c -@@ -608,6 +608,33 @@ static int xpcs_validate(struct phylink_pcs *pcs, unsigned long *supported, - return 0; - } - -+static unsigned int xpcs_inband_caps(struct phylink_pcs *pcs, -+ phy_interface_t interface) -+{ -+ struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs); -+ const struct dw_xpcs_compat *compat; -+ -+ compat = xpcs_find_compat(xpcs->desc, interface); -+ if (!compat) -+ return 0; -+ -+ switch (compat->an_mode) { -+ case DW_AN_C73: -+ return LINK_INBAND_ENABLE; -+ -+ case DW_AN_C37_SGMII: -+ case DW_AN_C37_1000BASEX: -+ return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE; -+ -+ case DW_10GBASER: -+ case DW_2500BASEX: -+ return LINK_INBAND_DISABLE; -+ -+ default: -+ return 0; -+ } -+} -+ - void xpcs_get_interfaces(struct dw_xpcs *xpcs, unsigned long *interfaces) - { - int i, j; -@@ -1365,6 +1392,7 @@ static const struct dw_xpcs_desc xpcs_desc_list[] = { - - static const struct phylink_pcs_ops xpcs_phylink_ops = { - .pcs_validate = xpcs_validate, -+ .pcs_inband_caps = xpcs_inband_caps, - .pcs_config = xpcs_config, - .pcs_get_state = xpcs_get_state, - .pcs_an_restart = xpcs_an_restart, --- -2.51.0 - - -From 7c06d850aae8abcc6caefb76d9bebe7013353c3e Mon Sep 17 00:00:00 2001 -From: Rosen Penev -Date: Sun, 27 Oct 2024 21:48:28 -0700 -Subject: [PATCH 052/517] net: dsa: use ethtool string helpers - -These are the preferred way to copy ethtool strings. - -Avoids incrementing pointers all over the place. - -Signed-off-by: Rosen Penev -(for hellcreek driver) -Reviewed-by: Kurt Kanzenbach -Link: https://patch.msgid.link/20241028044828.1639668-1-rosenp@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/b53/b53_common.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c -index c903c6fcc666..ad07efa44c55 100644 ---- a/drivers/net/dsa/b53/b53_common.c -+++ b/drivers/net/dsa/b53/b53_common.c -@@ -1086,8 +1086,7 @@ void b53_get_strings(struct dsa_switch *ds, int port, u32 stringset, - - if (stringset == ETH_SS_STATS) { - for (i = 0; i < mib_size; i++) -- strscpy(data + i * ETH_GSTRING_LEN, -- mibs[i].name, ETH_GSTRING_LEN); -+ ethtool_puts(&data, mibs[i].name); - } else if (stringset == ETH_SS_PHY_STATS) { - phydev = b53_get_phy_device(ds, port); - if (!phydev) --- -2.51.0 - - -From 6eb6aee9c622b03602f9189203fd73d5f11bfc6b Mon Sep 17 00:00:00 2001 -From: Torben Nielsen -Date: Mon, 17 Feb 2025 09:05:01 +0100 -Subject: [PATCH 053/517] net: dsa: b53: mdio: add support for BCM53101 - -BCM53101 is a ethernet switch, very similar to the BCM53115. -Enable support for it, in the existing b53 dsa driver. - -Signed-off-by: Torben Nielsen -Signed-off-by: Claus Stovgaard -Link: https://patch.msgid.link/20250217080503.1390282-1-claus.stovgaard@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/b53/b53_common.c | 14 ++++++++++++++ - drivers/net/dsa/b53/b53_mdio.c | 1 + - drivers/net/dsa/b53/b53_priv.h | 2 ++ - 3 files changed, 17 insertions(+) - -diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c -index ad07efa44c55..0598c8c60c85 100644 ---- a/drivers/net/dsa/b53/b53_common.c -+++ b/drivers/net/dsa/b53/b53_common.c -@@ -2583,6 +2583,19 @@ static const struct b53_chip_data b53_switch_chips[] = { - .jumbo_pm_reg = B53_JUMBO_PORT_MASK, - .jumbo_size_reg = B53_JUMBO_MAX_SIZE, - }, -+ { -+ .chip_id = BCM53101_DEVICE_ID, -+ .dev_name = "BCM53101", -+ .vlans = 4096, -+ .enabled_ports = 0x11f, -+ .arl_bins = 4, -+ .arl_buckets = 512, -+ .vta_regs = B53_VTA_REGS, -+ .imp_port = 8, -+ .duplex_reg = B53_DUPLEX_STAT_GE, -+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE, -+ }, - { - .chip_id = BCM53115_DEVICE_ID, - .dev_name = "BCM53115", -@@ -2964,6 +2977,7 @@ int b53_switch_detect(struct b53_device *dev) - return ret; - - switch (id32) { -+ case BCM53101_DEVICE_ID: - case BCM53115_DEVICE_ID: - case BCM53125_DEVICE_ID: - case BCM53128_DEVICE_ID: -diff --git a/drivers/net/dsa/b53/b53_mdio.c b/drivers/net/dsa/b53/b53_mdio.c -index 31d070bf161a..43a3b37b731b 100644 ---- a/drivers/net/dsa/b53/b53_mdio.c -+++ b/drivers/net/dsa/b53/b53_mdio.c -@@ -374,6 +374,7 @@ static void b53_mdio_shutdown(struct mdio_device *mdiodev) - - static const struct of_device_id b53_of_match[] = { - { .compatible = "brcm,bcm5325" }, -+ { .compatible = "brcm,bcm53101" }, - { .compatible = "brcm,bcm53115" }, - { .compatible = "brcm,bcm53125" }, - { .compatible = "brcm,bcm53128" }, -diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h -index e908397e8b9a..4b52a4807029 100644 ---- a/drivers/net/dsa/b53/b53_priv.h -+++ b/drivers/net/dsa/b53/b53_priv.h -@@ -66,6 +66,7 @@ enum { - BCM5395_DEVICE_ID = 0x95, - BCM5397_DEVICE_ID = 0x97, - BCM5398_DEVICE_ID = 0x98, -+ BCM53101_DEVICE_ID = 0x53101, - BCM53115_DEVICE_ID = 0x53115, - BCM53125_DEVICE_ID = 0x53125, - BCM53128_DEVICE_ID = 0x53128, -@@ -190,6 +191,7 @@ static inline int is531x5(struct b53_device *dev) - { - return dev->chip_id == BCM53115_DEVICE_ID || - dev->chip_id == BCM53125_DEVICE_ID || -+ dev->chip_id == BCM53101_DEVICE_ID || - dev->chip_id == BCM53128_DEVICE_ID || - dev->chip_id == BCM53134_DEVICE_ID; - } --- -2.51.0 - - -From 427c593a29ae93f1675b83cc6ee5562c7a05ee23 Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Sat, 10 May 2025 11:22:11 +0200 -Subject: [PATCH 054/517] net: dsa: b53: implement setting ageing time - -b53 supported switches support configuring ageing time between 1 and -1,048,575 seconds, so add an appropriate setter. - -This allows b53 to pass the FDB learning test for both vlan aware and -vlan unaware bridges. - -Signed-off-by: Jonas Gorski -Reviewed-by: Florian Fainelli -Link: https://patch.msgid.link/20250510092211.276541-1-jonas.gorski@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/b53/b53_common.c | 28 ++++++++++++++++++++++++++++ - drivers/net/dsa/b53/b53_priv.h | 1 + - drivers/net/dsa/b53/b53_regs.h | 7 +++++++ - 3 files changed, 36 insertions(+) - -diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c -index 0598c8c60c85..d3589b94c356 100644 ---- a/drivers/net/dsa/b53/b53_common.c -+++ b/drivers/net/dsa/b53/b53_common.c -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -1227,6 +1228,10 @@ static int b53_setup(struct dsa_switch *ds) - */ - ds->untag_vlan_aware_bridge_pvid = true; - -+ /* Ageing time is set in seconds */ -+ ds->ageing_time_min = 1 * 1000; -+ ds->ageing_time_max = AGE_TIME_MAX * 1000; -+ - ret = b53_reset_switch(dev); - if (ret) { - dev_err(ds->dev, "failed to reset switch\n"); -@@ -2444,6 +2449,28 @@ static int b53_get_max_mtu(struct dsa_switch *ds, int port) - return B53_MAX_MTU; - } - -+int b53_set_ageing_time(struct dsa_switch *ds, unsigned int msecs) -+{ -+ struct b53_device *dev = ds->priv; -+ u32 atc; -+ int reg; -+ -+ if (is63xx(dev)) -+ reg = B53_AGING_TIME_CONTROL_63XX; -+ else -+ reg = B53_AGING_TIME_CONTROL; -+ -+ atc = DIV_ROUND_CLOSEST(msecs, 1000); -+ -+ if (!is5325(dev) && !is5365(dev)) -+ atc |= AGE_CHANGE; -+ -+ b53_write32(dev, B53_MGMT_PAGE, reg, atc); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(b53_set_ageing_time); -+ - static const struct phylink_mac_ops b53_phylink_mac_ops = { - .mac_select_pcs = b53_phylink_mac_select_pcs, - .mac_config = b53_phylink_mac_config, -@@ -2468,6 +2495,7 @@ static const struct dsa_switch_ops b53_switch_ops = { - .support_eee = b53_support_eee, - .get_mac_eee = b53_get_mac_eee, - .set_mac_eee = b53_set_mac_eee, -+ .set_ageing_time = b53_set_ageing_time, - .port_bridge_join = b53_br_join, - .port_bridge_leave = b53_br_leave, - .port_pre_bridge_flags = b53_br_flags_pre, -diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h -index 4b52a4807029..72f00f9e177c 100644 ---- a/drivers/net/dsa/b53/b53_priv.h -+++ b/drivers/net/dsa/b53/b53_priv.h -@@ -343,6 +343,7 @@ void b53_get_strings(struct dsa_switch *ds, int port, u32 stringset, - void b53_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data); - int b53_get_sset_count(struct dsa_switch *ds, int port, int sset); - void b53_get_ethtool_phy_stats(struct dsa_switch *ds, int port, uint64_t *data); -+int b53_set_ageing_time(struct dsa_switch *ds, unsigned int msecs); - int b53_br_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge, - bool *tx_fwd_offload, struct netlink_ext_ack *extack); - void b53_br_leave(struct dsa_switch *ds, int port, struct dsa_bridge bridge); -diff --git a/drivers/net/dsa/b53/b53_regs.h b/drivers/net/dsa/b53/b53_regs.h -index 5741231e0841..f2caf8fe5699 100644 ---- a/drivers/net/dsa/b53/b53_regs.h -+++ b/drivers/net/dsa/b53/b53_regs.h -@@ -225,6 +225,13 @@ - #define BRCM_HDR_P5_EN BIT(1) /* Enable tagging on port 5 */ - #define BRCM_HDR_P7_EN BIT(2) /* Enable tagging on port 7 */ - -+/* Aging Time control register (32 bit) */ -+#define B53_AGING_TIME_CONTROL 0x06 -+#define B53_AGING_TIME_CONTROL_63XX 0x08 -+#define AGE_CHANGE BIT(20) -+#define AGE_TIME_MASK 0x7ffff -+#define AGE_TIME_MAX 1048575 -+ - /* Mirror capture control register (16 bit) */ - #define B53_MIR_CAP_CTL 0x10 - #define CAP_PORT_MASK 0xf --- -2.51.0 - - -From 3198631f2e9d7a63611917584f509b56dfbd7401 Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Mon, 2 Jun 2025 21:39:51 +0200 -Subject: [PATCH 055/517] net: dsa: b53: do not configure bcm63xx's IMP port - interface - -The IMP port is not a valid RGMII interface, but hard wired to internal, -so we shouldn't touch the undefined register B53_RGMII_CTRL_IMP. - -While this does not seem to have any side effects, let's not touch it at -all, so limit RGMII configuration on bcm63xx to the actual RGMII ports. - -Fixes: ce3bf94871f7 ("net: dsa: b53: add support for BCM63xx RGMIIs") -Signed-off-by: Jonas Gorski -Reviewed-by: Florian Fainelli -Link: https://patch.msgid.link/20250602193953.1010487-4-jonas.gorski@gmail.com -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/b53/b53_common.c | 22 ++++++++-------------- - 1 file changed, 8 insertions(+), 14 deletions(-) - -diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c -index d3589b94c356..d7a56dbc7d07 100644 ---- a/drivers/net/dsa/b53/b53_common.c -+++ b/drivers/net/dsa/b53/b53_common.c -@@ -22,6 +22,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -1360,24 +1361,17 @@ static void b53_adjust_63xx_rgmii(struct dsa_switch *ds, int port, - phy_interface_t interface) - { - struct b53_device *dev = ds->priv; -- u8 rgmii_ctrl = 0, off; -- -- if (port == dev->imp_port) -- off = B53_RGMII_CTRL_IMP; -- else -- off = B53_RGMII_CTRL_P(port); -+ u8 rgmii_ctrl = 0; - -- b53_read8(dev, B53_CTRL_PAGE, off, &rgmii_ctrl); -+ b53_read8(dev, B53_CTRL_PAGE, B53_RGMII_CTRL_P(port), &rgmii_ctrl); - rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC); - -- if (port != dev->imp_port) { -- if (is63268(dev)) -- rgmii_ctrl |= RGMII_CTRL_MII_OVERRIDE; -+ if (is63268(dev)) -+ rgmii_ctrl |= RGMII_CTRL_MII_OVERRIDE; - -- rgmii_ctrl |= RGMII_CTRL_ENABLE_GMII; -- } -+ rgmii_ctrl |= RGMII_CTRL_ENABLE_GMII; - -- b53_write8(dev, B53_CTRL_PAGE, off, rgmii_ctrl); -+ b53_write8(dev, B53_CTRL_PAGE, B53_RGMII_CTRL_P(port), rgmii_ctrl); - - dev_dbg(ds->dev, "Configured port %d for %s\n", port, - phy_modes(interface)); -@@ -1528,7 +1522,7 @@ static void b53_phylink_mac_config(struct phylink_config *config, - struct b53_device *dev = ds->priv; - int port = dp->index; - -- if (is63xx(dev) && port >= B53_63XX_RGMII0) -+ if (is63xx(dev) && in_range(port, B53_63XX_RGMII0, 4)) - b53_adjust_63xx_rgmii(ds, port, interface); - - if (mode == MLO_AN_FIXED) { --- -2.51.0 - - -From 58ff441b8e9051c9495e489887994c702ad0abe7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= -Date: Sat, 14 Jun 2025 09:59:47 +0200 -Subject: [PATCH 056/517] net: dsa: tag_brcm: legacy: reorganize functions -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Move brcm_leg_tag_rcv() definition to top. -This function is going to be shared between two different tags. - -Reviewed-by: Florian Fainelli -Signed-off-by: Álvaro Fernández Rojas -Link: https://patch.msgid.link/20250614080000.1884236-2-noltari@gmail.com -Signed-off-by: Jakub Kicinski ---- - net/dsa/tag_brcm.c | 64 +++++++++++++++++++++++----------------------- - 1 file changed, 32 insertions(+), 32 deletions(-) - -diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c -index fe75821623a4..9f4b0bcd95cd 100644 ---- a/net/dsa/tag_brcm.c -+++ b/net/dsa/tag_brcm.c -@@ -213,6 +213,38 @@ MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM, BRCM_NAME); - #endif - - #if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY) -+static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb, -+ struct net_device *dev) -+{ -+ int len = BRCM_LEG_TAG_LEN; -+ int source_port; -+ u8 *brcm_tag; -+ -+ if (unlikely(!pskb_may_pull(skb, BRCM_LEG_TAG_LEN + VLAN_HLEN))) -+ return NULL; -+ -+ brcm_tag = dsa_etype_header_pos_rx(skb); -+ -+ source_port = brcm_tag[5] & BRCM_LEG_PORT_ID; -+ -+ skb->dev = dsa_conduit_find_user(dev, 0, source_port); -+ if (!skb->dev) -+ return NULL; -+ -+ /* VLAN tag is added by BCM63xx internal switch */ -+ if (netdev_uses_dsa(skb->dev)) -+ len += VLAN_HLEN; -+ -+ /* Remove Broadcom tag and update checksum */ -+ skb_pull_rcsum(skb, len); -+ -+ dsa_default_offload_fwd_mark(skb); -+ -+ dsa_strip_etype_header(skb, len); -+ -+ return skb; -+} -+ - static struct sk_buff *brcm_leg_tag_xmit(struct sk_buff *skb, - struct net_device *dev) - { -@@ -250,38 +282,6 @@ static struct sk_buff *brcm_leg_tag_xmit(struct sk_buff *skb, - return skb; - } - --static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb, -- struct net_device *dev) --{ -- int len = BRCM_LEG_TAG_LEN; -- int source_port; -- u8 *brcm_tag; -- -- if (unlikely(!pskb_may_pull(skb, BRCM_LEG_TAG_LEN + VLAN_HLEN))) -- return NULL; -- -- brcm_tag = dsa_etype_header_pos_rx(skb); -- -- source_port = brcm_tag[5] & BRCM_LEG_PORT_ID; -- -- skb->dev = dsa_conduit_find_user(dev, 0, source_port); -- if (!skb->dev) -- return NULL; -- -- /* VLAN tag is added by BCM63xx internal switch */ -- if (netdev_uses_dsa(skb->dev)) -- len += VLAN_HLEN; -- -- /* Remove Broadcom tag and update checksum */ -- skb_pull_rcsum(skb, len); -- -- dsa_default_offload_fwd_mark(skb); -- -- dsa_strip_etype_header(skb, len); -- -- return skb; --} -- - static const struct dsa_device_ops brcm_legacy_netdev_ops = { - .name = BRCM_LEGACY_NAME, - .proto = DSA_TAG_PROTO_BRCM_LEGACY, --- -2.51.0 - - -From fe2df740c952ccd825ba3eea0797b7eb5690ef1a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= -Date: Sat, 14 Jun 2025 09:59:48 +0200 -Subject: [PATCH 057/517] net: dsa: tag_brcm: add support for legacy FCS tags -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add support for legacy Broadcom FCS tags, which are similar to -DSA_TAG_PROTO_BRCM_LEGACY. -BCM5325 and BCM5365 switches require including the original FCS value and -length, as opposed to BCM63xx switches. -Adding the original FCS value and length to DSA_TAG_PROTO_BRCM_LEGACY would -impact performance of BCM63xx switches, so it's better to create a new tag. - -Signed-off-by: Álvaro Fernández Rojas -Reviewed-by: Florian Fainelli -Link: https://patch.msgid.link/20250614080000.1884236-3-noltari@gmail.com -Signed-off-by: Jakub Kicinski ---- - include/net/dsa.h | 2 ++ - net/dsa/Kconfig | 16 ++++++++-- - net/dsa/tag_brcm.c | 73 +++++++++++++++++++++++++++++++++++++++++++++- - 3 files changed, 88 insertions(+), 3 deletions(-) - -diff --git a/include/net/dsa.h b/include/net/dsa.h -index 877f9b270cf6..6f2a397fbe1c 100644 ---- a/include/net/dsa.h -+++ b/include/net/dsa.h -@@ -54,11 +54,13 @@ struct tc_action; - #define DSA_TAG_PROTO_RZN1_A5PSW_VALUE 26 - #define DSA_TAG_PROTO_LAN937X_VALUE 27 - #define DSA_TAG_PROTO_VSC73XX_8021Q_VALUE 28 -+#define DSA_TAG_PROTO_BRCM_LEGACY_FCS_VALUE 29 - - enum dsa_tag_protocol { - DSA_TAG_PROTO_NONE = DSA_TAG_PROTO_NONE_VALUE, - DSA_TAG_PROTO_BRCM = DSA_TAG_PROTO_BRCM_VALUE, - DSA_TAG_PROTO_BRCM_LEGACY = DSA_TAG_PROTO_BRCM_LEGACY_VALUE, -+ DSA_TAG_PROTO_BRCM_LEGACY_FCS = DSA_TAG_PROTO_BRCM_LEGACY_FCS_VALUE, - DSA_TAG_PROTO_BRCM_PREPEND = DSA_TAG_PROTO_BRCM_PREPEND_VALUE, - DSA_TAG_PROTO_DSA = DSA_TAG_PROTO_DSA_VALUE, - DSA_TAG_PROTO_EDSA = DSA_TAG_PROTO_EDSA_VALUE, -diff --git a/net/dsa/Kconfig b/net/dsa/Kconfig -index 2dfe9063613f..869cbe57162f 100644 ---- a/net/dsa/Kconfig -+++ b/net/dsa/Kconfig -@@ -42,12 +42,24 @@ config NET_DSA_TAG_BRCM - Broadcom switches which place the tag after the MAC source address. - - config NET_DSA_TAG_BRCM_LEGACY -- tristate "Tag driver for Broadcom legacy switches using in-frame headers" -+ tristate "Tag driver for BCM63xx legacy switches using in-frame headers" - select NET_DSA_TAG_BRCM_COMMON - help - Say Y if you want to enable support for tagging frames for the -- Broadcom legacy switches which place the tag after the MAC source -+ BCM63xx legacy switches which place the tag after the MAC source - address. -+ This tag is used in BCM63xx legacy switches which work without the -+ original FCS and length before the tag insertion. -+ -+config NET_DSA_TAG_BRCM_LEGACY_FCS -+ tristate "Tag driver for BCM53xx legacy switches using in-frame headers" -+ select NET_DSA_TAG_BRCM_COMMON -+ help -+ Say Y if you want to enable support for tagging frames for the -+ BCM53xx legacy switches which place the tag after the MAC source -+ address. -+ This tag is used in BCM53xx legacy switches which expect original -+ FCS and length before the tag insertion to be present. - - config NET_DSA_TAG_BRCM_PREPEND - tristate "Tag driver for Broadcom switches using prepended headers" -diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c -index 9f4b0bcd95cd..26bb657ceac3 100644 ---- a/net/dsa/tag_brcm.c -+++ b/net/dsa/tag_brcm.c -@@ -15,6 +15,7 @@ - - #define BRCM_NAME "brcm" - #define BRCM_LEGACY_NAME "brcm-legacy" -+#define BRCM_LEGACY_FCS_NAME "brcm-legacy-fcs" - #define BRCM_PREPEND_NAME "brcm-prepend" - - /* Legacy Broadcom tag (6 bytes) */ -@@ -32,6 +33,10 @@ - #define BRCM_LEG_MULTICAST (1 << 5) - #define BRCM_LEG_EGRESS (2 << 5) - #define BRCM_LEG_INGRESS (3 << 5) -+#define BRCM_LEG_LEN_HI(x) (((x) >> 8) & 0x7) -+ -+/* 4th byte in the tag */ -+#define BRCM_LEG_LEN_LO(x) ((x) & 0xff) - - /* 6th byte in the tag */ - #define BRCM_LEG_PORT_ID (0xf) -@@ -212,7 +217,8 @@ DSA_TAG_DRIVER(brcm_netdev_ops); - MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM, BRCM_NAME); - #endif - --#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY) -+#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY) || \ -+ IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY_FCS) - static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb, - struct net_device *dev) - { -@@ -244,7 +250,9 @@ static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb, - - return skb; - } -+#endif /* CONFIG_NET_DSA_TAG_BRCM_LEGACY || CONFIG_NET_DSA_TAG_BRCM_LEGACY_FCS */ - -+#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY) - static struct sk_buff *brcm_leg_tag_xmit(struct sk_buff *skb, - struct net_device *dev) - { -@@ -294,6 +302,66 @@ DSA_TAG_DRIVER(brcm_legacy_netdev_ops); - MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM_LEGACY, BRCM_LEGACY_NAME); - #endif /* CONFIG_NET_DSA_TAG_BRCM_LEGACY */ - -+#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY_FCS) -+static struct sk_buff *brcm_leg_fcs_tag_xmit(struct sk_buff *skb, -+ struct net_device *dev) -+{ -+ struct dsa_port *dp = dsa_user_to_port(dev); -+ unsigned int fcs_len; -+ __le32 fcs_val; -+ u8 *brcm_tag; -+ -+ /* The Ethernet switch we are interfaced with needs packets to be at -+ * least 64 bytes (including FCS) otherwise they will be discarded when -+ * they enter the switch port logic. When Broadcom tags are enabled, we -+ * need to make sure that packets are at least 70 bytes (including FCS -+ * and tag) because the length verification is done after the Broadcom -+ * tag is stripped off the ingress packet. -+ * -+ * Let dsa_user_xmit() free the SKB. -+ */ -+ if (__skb_put_padto(skb, ETH_ZLEN + BRCM_LEG_TAG_LEN, false)) -+ return NULL; -+ -+ fcs_len = skb->len; -+ fcs_val = cpu_to_le32(crc32_le(~0, skb->data, fcs_len) ^ ~0); -+ -+ skb_push(skb, BRCM_LEG_TAG_LEN); -+ -+ dsa_alloc_etype_header(skb, BRCM_LEG_TAG_LEN); -+ -+ brcm_tag = skb->data + 2 * ETH_ALEN; -+ -+ /* Broadcom tag type */ -+ brcm_tag[0] = BRCM_LEG_TYPE_HI; -+ brcm_tag[1] = BRCM_LEG_TYPE_LO; -+ -+ /* Broadcom tag value */ -+ brcm_tag[2] = BRCM_LEG_EGRESS | BRCM_LEG_LEN_HI(fcs_len); -+ brcm_tag[3] = BRCM_LEG_LEN_LO(fcs_len); -+ brcm_tag[4] = 0; -+ brcm_tag[5] = dp->index & BRCM_LEG_PORT_ID; -+ -+ /* Original FCS value */ -+ if (__skb_pad(skb, ETH_FCS_LEN, false)) -+ return NULL; -+ skb_put_data(skb, &fcs_val, ETH_FCS_LEN); -+ -+ return skb; -+} -+ -+static const struct dsa_device_ops brcm_legacy_fcs_netdev_ops = { -+ .name = BRCM_LEGACY_FCS_NAME, -+ .proto = DSA_TAG_PROTO_BRCM_LEGACY_FCS, -+ .xmit = brcm_leg_fcs_tag_xmit, -+ .rcv = brcm_leg_tag_rcv, -+ .needed_headroom = BRCM_LEG_TAG_LEN, -+}; -+ -+DSA_TAG_DRIVER(brcm_legacy_fcs_netdev_ops); -+MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_BRCM_LEGACY_FCS, BRCM_LEGACY_FCS_NAME); -+#endif /* CONFIG_NET_DSA_TAG_BRCM_LEGACY_FCS */ -+ - #if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_PREPEND) - static struct sk_buff *brcm_tag_xmit_prepend(struct sk_buff *skb, - struct net_device *dev) -@@ -328,6 +396,9 @@ static struct dsa_tag_driver *dsa_tag_driver_array[] = { - #if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY) - &DSA_TAG_DRIVER_NAME(brcm_legacy_netdev_ops), - #endif -+#if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_LEGACY_FCS) -+ &DSA_TAG_DRIVER_NAME(brcm_legacy_fcs_netdev_ops), -+#endif - #if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_PREPEND) - &DSA_TAG_DRIVER_NAME(brcm_prepend_netdev_ops), - #endif --- -2.51.0 - - -From 57d5fd907ba1839df4933da2fd6c7f3924f4030c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= -Date: Sat, 14 Jun 2025 09:59:49 +0200 -Subject: [PATCH 058/517] net: dsa: b53: support legacy FCS tags -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Commit 46c5176c586c ("net: dsa: b53: support legacy tags") introduced -support for legacy tags, but it turns out that BCM5325 and BCM5365 -switches require the original FCS value and length, so they have to be -treated differently. - -Reviewed-by: Florian Fainelli -Signed-off-by: Álvaro Fernández Rojas -Link: https://patch.msgid.link/20250614080000.1884236-4-noltari@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/b53/Kconfig | 1 + - drivers/net/dsa/b53/b53_common.c | 7 +++++-- - 2 files changed, 6 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/dsa/b53/Kconfig b/drivers/net/dsa/b53/Kconfig -index ebaa4a80d544..915008e8eff5 100644 ---- a/drivers/net/dsa/b53/Kconfig -+++ b/drivers/net/dsa/b53/Kconfig -@@ -5,6 +5,7 @@ menuconfig B53 - select NET_DSA_TAG_NONE - select NET_DSA_TAG_BRCM - select NET_DSA_TAG_BRCM_LEGACY -+ select NET_DSA_TAG_BRCM_LEGACY_FCS - select NET_DSA_TAG_BRCM_PREPEND - help - This driver adds support for Broadcom managed switch chips. It supports -diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c -index d7a56dbc7d07..4291f2be7de4 100644 ---- a/drivers/net/dsa/b53/b53_common.c -+++ b/drivers/net/dsa/b53/b53_common.c -@@ -2285,8 +2285,11 @@ enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port, - goto out; - } - -- /* Older models require a different 6 byte tag */ -- if (is5325(dev) || is5365(dev) || is63xx(dev)) { -+ /* Older models require different 6 byte tags */ -+ if (is5325(dev) || is5365(dev)) { -+ dev->tag_protocol = DSA_TAG_PROTO_BRCM_LEGACY_FCS; -+ goto out; -+ } else if (is63xx(dev)) { - dev->tag_protocol = DSA_TAG_PROTO_BRCM_LEGACY; - goto out; - } --- -2.51.0 - - -From 9341e0f0fe6412e8a855c2f0188d38091904152c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= -Date: Sat, 14 Jun 2025 09:59:50 +0200 -Subject: [PATCH 059/517] net: dsa: b53: detect BCM5325 variants -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -We need to be able to differentiate the BCM5325 variants because: -- BCM5325M switches lack the ARLIO_PAGE->VLAN_ID_IDX register. -- BCM5325E have less 512 ARL buckets instead of 1024. - -Signed-off-by: Álvaro Fernández Rojas -Reviewed-by: Florian Fainelli -Link: https://patch.msgid.link/20250614080000.1884236-5-noltari@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/b53/b53_common.c | 24 +++++++++++++++++++++--- - drivers/net/dsa/b53/b53_priv.h | 19 +++++++++++++++++++ - 2 files changed, 40 insertions(+), 3 deletions(-) - -diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c -index 4291f2be7de4..1b4445d90612 100644 ---- a/drivers/net/dsa/b53/b53_common.c -+++ b/drivers/net/dsa/b53/b53_common.c -@@ -1816,7 +1816,8 @@ static int b53_arl_op(struct b53_device *dev, int op, int port, - - /* Perform a read for the given MAC and VID */ - b53_write48(dev, B53_ARLIO_PAGE, B53_MAC_ADDR_IDX, mac); -- b53_write16(dev, B53_ARLIO_PAGE, B53_VLAN_ID_IDX, vid); -+ if (!is5325m(dev)) -+ b53_write16(dev, B53_ARLIO_PAGE, B53_VLAN_ID_IDX, vid); - - /* Issue a read operation for this MAC */ - ret = b53_arl_rw_op(dev, 1); -@@ -2884,6 +2885,9 @@ static int b53_switch_init(struct b53_device *dev) - } - } - -+ if (is5325e(dev)) -+ dev->num_arl_buckets = 512; -+ - dev->num_ports = fls(dev->enabled_ports); - - dev->ds->num_ports = min_t(unsigned int, dev->num_ports, DSA_MAX_PORTS); -@@ -2985,10 +2989,24 @@ int b53_switch_detect(struct b53_device *dev) - b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_25, 0xf); - b53_read16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_25, &tmp); - -- if (tmp == 0xf) -+ if (tmp == 0xf) { -+ u32 phy_id; -+ int val; -+ - dev->chip_id = BCM5325_DEVICE_ID; -- else -+ -+ val = b53_phy_read16(dev->ds, 0, MII_PHYSID1); -+ phy_id = (val & 0xffff) << 16; -+ val = b53_phy_read16(dev->ds, 0, MII_PHYSID2); -+ phy_id |= (val & 0xfff0); -+ -+ if (phy_id == 0x00406330) -+ dev->variant_id = B53_VARIANT_5325M; -+ else if (phy_id == 0x0143bc30) -+ dev->variant_id = B53_VARIANT_5325E; -+ } else { - dev->chip_id = BCM5365_DEVICE_ID; -+ } - break; - case BCM5389_DEVICE_ID: - case BCM5395_DEVICE_ID: -diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h -index 72f00f9e177c..6bf8f591cdc1 100644 ---- a/drivers/net/dsa/b53/b53_priv.h -+++ b/drivers/net/dsa/b53/b53_priv.h -@@ -84,6 +84,12 @@ enum { - BCM53134_DEVICE_ID = 0x5075, - }; - -+enum b53_variant_id { -+ B53_VARIANT_NONE = 0, -+ B53_VARIANT_5325E, -+ B53_VARIANT_5325M, -+}; -+ - struct b53_pcs { - struct phylink_pcs pcs; - struct b53_device *dev; -@@ -118,6 +124,7 @@ struct b53_device { - - /* chip specific data */ - u32 chip_id; -+ enum b53_variant_id variant_id; - u8 core_rev; - u8 vta_regs[3]; - u8 duplex_reg; -@@ -165,6 +172,18 @@ static inline int is5325(struct b53_device *dev) - return dev->chip_id == BCM5325_DEVICE_ID; - } - -+static inline int is5325e(struct b53_device *dev) -+{ -+ return is5325(dev) && -+ dev->variant_id == B53_VARIANT_5325E; -+} -+ -+static inline int is5325m(struct b53_device *dev) -+{ -+ return is5325(dev) && -+ dev->variant_id == B53_VARIANT_5325M; -+} -+ - static inline int is5365(struct b53_device *dev) - { - #ifdef CONFIG_BCM47XX --- -2.51.0 - - -From 3fccfaadb3356a5d30d38bcec04eca1ef60691c5 Mon Sep 17 00:00:00 2001 -From: Florian Fainelli -Date: Sat, 14 Jun 2025 09:59:51 +0200 -Subject: [PATCH 060/517] net: dsa: b53: add support for FDB operations on - 5325/5365 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -BCM5325 and BCM5365 are part of a much older generation of switches which, -due to their limited number of ports and VLAN entries (up to 256) allowed -a single 64-bit register to hold a full ARL entry. -This requires a little bit of massaging when reading, writing and -converting ARL entries in both directions. - -Signed-off-by: Florian Fainelli -Signed-off-by: Álvaro Fernández Rojas -Link: https://patch.msgid.link/20250614080000.1884236-6-noltari@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/b53/b53_common.c | 101 +++++++++++++++++++++++++------ - drivers/net/dsa/b53/b53_priv.h | 29 +++++++++ - drivers/net/dsa/b53/b53_regs.h | 7 ++- - 3 files changed, 115 insertions(+), 22 deletions(-) - -diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c -index 1b4445d90612..807c49880932 100644 ---- a/drivers/net/dsa/b53/b53_common.c -+++ b/drivers/net/dsa/b53/b53_common.c -@@ -1802,6 +1802,45 @@ static int b53_arl_read(struct b53_device *dev, u64 mac, - return *idx >= dev->num_arl_bins ? -ENOSPC : -ENOENT; - } - -+static int b53_arl_read_25(struct b53_device *dev, u64 mac, -+ u16 vid, struct b53_arl_entry *ent, u8 *idx) -+{ -+ DECLARE_BITMAP(free_bins, B53_ARLTBL_MAX_BIN_ENTRIES); -+ unsigned int i; -+ int ret; -+ -+ ret = b53_arl_op_wait(dev); -+ if (ret) -+ return ret; -+ -+ bitmap_zero(free_bins, dev->num_arl_bins); -+ -+ /* Read the bins */ -+ for (i = 0; i < dev->num_arl_bins; i++) { -+ u64 mac_vid; -+ -+ b53_read64(dev, B53_ARLIO_PAGE, -+ B53_ARLTBL_MAC_VID_ENTRY(i), &mac_vid); -+ -+ b53_arl_to_entry_25(ent, mac_vid); -+ -+ if (!(mac_vid & ARLTBL_VALID_25)) { -+ set_bit(i, free_bins); -+ continue; -+ } -+ if ((mac_vid & ARLTBL_MAC_MASK) != mac) -+ continue; -+ if (dev->vlan_enabled && -+ ((mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25) != vid) -+ continue; -+ *idx = i; -+ return 0; -+ } -+ -+ *idx = find_first_bit(free_bins, dev->num_arl_bins); -+ return *idx >= dev->num_arl_bins ? -ENOSPC : -ENOENT; -+} -+ - static int b53_arl_op(struct b53_device *dev, int op, int port, - const unsigned char *addr, u16 vid, bool is_valid) - { -@@ -1824,7 +1863,10 @@ static int b53_arl_op(struct b53_device *dev, int op, int port, - if (ret) - return ret; - -- ret = b53_arl_read(dev, mac, vid, &ent, &idx); -+ if (is5325(dev) || is5365(dev)) -+ ret = b53_arl_read_25(dev, mac, vid, &ent, &idx); -+ else -+ ret = b53_arl_read(dev, mac, vid, &ent, &idx); - - /* If this is a read, just finish now */ - if (op) -@@ -1868,12 +1910,17 @@ static int b53_arl_op(struct b53_device *dev, int op, int port, - ent.is_static = true; - ent.is_age = false; - memcpy(ent.mac, addr, ETH_ALEN); -- b53_arl_from_entry(&mac_vid, &fwd_entry, &ent); -+ if (is5325(dev) || is5365(dev)) -+ b53_arl_from_entry_25(&mac_vid, &ent); -+ else -+ b53_arl_from_entry(&mac_vid, &fwd_entry, &ent); - - b53_write64(dev, B53_ARLIO_PAGE, - B53_ARLTBL_MAC_VID_ENTRY(idx), mac_vid); -- b53_write32(dev, B53_ARLIO_PAGE, -- B53_ARLTBL_DATA_ENTRY(idx), fwd_entry); -+ -+ if (!is5325(dev) && !is5365(dev)) -+ b53_write32(dev, B53_ARLIO_PAGE, -+ B53_ARLTBL_DATA_ENTRY(idx), fwd_entry); - - return b53_arl_rw_op(dev, 0); - } -@@ -1885,12 +1932,6 @@ int b53_fdb_add(struct dsa_switch *ds, int port, - struct b53_device *priv = ds->priv; - int ret; - -- /* 5325 and 5365 require some more massaging, but could -- * be supported eventually -- */ -- if (is5325(priv) || is5365(priv)) -- return -EOPNOTSUPP; -- - mutex_lock(&priv->arl_mutex); - ret = b53_arl_op(priv, 0, port, addr, vid, true); - mutex_unlock(&priv->arl_mutex); -@@ -1917,10 +1958,15 @@ EXPORT_SYMBOL(b53_fdb_del); - static int b53_arl_search_wait(struct b53_device *dev) - { - unsigned int timeout = 1000; -- u8 reg; -+ u8 reg, offset; -+ -+ if (is5325(dev) || is5365(dev)) -+ offset = B53_ARL_SRCH_CTL_25; -+ else -+ offset = B53_ARL_SRCH_CTL; - - do { -- b53_read8(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_CTL, ®); -+ b53_read8(dev, B53_ARLIO_PAGE, offset, ®); - if (!(reg & ARL_SRCH_STDN)) - return 0; - -@@ -1937,13 +1983,24 @@ static void b53_arl_search_rd(struct b53_device *dev, u8 idx, - struct b53_arl_entry *ent) - { - u64 mac_vid; -- u32 fwd_entry; - -- b53_read64(dev, B53_ARLIO_PAGE, -- B53_ARL_SRCH_RSTL_MACVID(idx), &mac_vid); -- b53_read32(dev, B53_ARLIO_PAGE, -- B53_ARL_SRCH_RSTL(idx), &fwd_entry); -- b53_arl_to_entry(ent, mac_vid, fwd_entry); -+ if (is5325(dev)) { -+ b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_25, -+ &mac_vid); -+ b53_arl_to_entry_25(ent, mac_vid); -+ } else if (is5365(dev)) { -+ b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_65, -+ &mac_vid); -+ b53_arl_to_entry_25(ent, mac_vid); -+ } else { -+ u32 fwd_entry; -+ -+ b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_MACVID(idx), -+ &mac_vid); -+ b53_read32(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL(idx), -+ &fwd_entry); -+ b53_arl_to_entry(ent, mac_vid, fwd_entry); -+ } - } - - static int b53_fdb_copy(int port, const struct b53_arl_entry *ent, -@@ -1964,14 +2021,20 @@ int b53_fdb_dump(struct dsa_switch *ds, int port, - struct b53_device *priv = ds->priv; - struct b53_arl_entry results[2]; - unsigned int count = 0; -+ u8 offset; - int ret; - u8 reg; - - mutex_lock(&priv->arl_mutex); - -+ if (is5325(priv) || is5365(priv)) -+ offset = B53_ARL_SRCH_CTL_25; -+ else -+ offset = B53_ARL_SRCH_CTL; -+ - /* Start search operation */ - reg = ARL_SRCH_STDN; -- b53_write8(priv, B53_ARLIO_PAGE, B53_ARL_SRCH_CTL, reg); -+ b53_write8(priv, offset, B53_ARL_SRCH_CTL, reg); - - do { - ret = b53_arl_search_wait(priv); -diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h -index 6bf8f591cdc1..3e8204c7c02e 100644 ---- a/drivers/net/dsa/b53/b53_priv.h -+++ b/drivers/net/dsa/b53/b53_priv.h -@@ -317,6 +317,19 @@ static inline void b53_arl_to_entry(struct b53_arl_entry *ent, - ent->vid = mac_vid >> ARLTBL_VID_S; - } - -+static inline void b53_arl_to_entry_25(struct b53_arl_entry *ent, -+ u64 mac_vid) -+{ -+ memset(ent, 0, sizeof(*ent)); -+ ent->port = (mac_vid >> ARLTBL_DATA_PORT_ID_S_25) & -+ ARLTBL_DATA_PORT_ID_MASK_25; -+ ent->is_valid = !!(mac_vid & ARLTBL_VALID_25); -+ ent->is_age = !!(mac_vid & ARLTBL_AGE_25); -+ ent->is_static = !!(mac_vid & ARLTBL_STATIC_25); -+ u64_to_ether_addr(mac_vid, ent->mac); -+ ent->vid = mac_vid >> ARLTBL_VID_S_65; -+} -+ - static inline void b53_arl_from_entry(u64 *mac_vid, u32 *fwd_entry, - const struct b53_arl_entry *ent) - { -@@ -331,6 +344,22 @@ static inline void b53_arl_from_entry(u64 *mac_vid, u32 *fwd_entry, - *fwd_entry |= ARLTBL_AGE; - } - -+static inline void b53_arl_from_entry_25(u64 *mac_vid, -+ const struct b53_arl_entry *ent) -+{ -+ *mac_vid = ether_addr_to_u64(ent->mac); -+ *mac_vid |= (u64)(ent->port & ARLTBL_DATA_PORT_ID_MASK_25) << -+ ARLTBL_DATA_PORT_ID_S_25; -+ *mac_vid |= (u64)(ent->vid & ARLTBL_VID_MASK_25) << -+ ARLTBL_VID_S_65; -+ if (ent->is_valid) -+ *mac_vid |= ARLTBL_VALID_25; -+ if (ent->is_static) -+ *mac_vid |= ARLTBL_STATIC_25; -+ if (ent->is_age) -+ *mac_vid |= ARLTBL_AGE_25; -+} -+ - #ifdef CONFIG_BCM47XX - - #include -diff --git a/drivers/net/dsa/b53/b53_regs.h b/drivers/net/dsa/b53/b53_regs.h -index f2caf8fe5699..b6ef32d481ca 100644 ---- a/drivers/net/dsa/b53/b53_regs.h -+++ b/drivers/net/dsa/b53/b53_regs.h -@@ -329,9 +329,10 @@ - #define ARLTBL_VID_MASK 0xfff - #define ARLTBL_DATA_PORT_ID_S_25 48 - #define ARLTBL_DATA_PORT_ID_MASK_25 0xf --#define ARLTBL_AGE_25 BIT(61) --#define ARLTBL_STATIC_25 BIT(62) --#define ARLTBL_VALID_25 BIT(63) -+#define ARLTBL_VID_S_65 53 -+#define ARLTBL_AGE_25 BIT_ULL(61) -+#define ARLTBL_STATIC_25 BIT_ULL(62) -+#define ARLTBL_VALID_25 BIT_ULL(63) - - /* ARL Table Data Entry N Registers (32 bit) */ - #define B53_ARLTBL_DATA_ENTRY(n) ((0x10 * (n)) + 0x18) --- -2.51.0 - - -From ca4b9423fc2d29191875ce73e57afc26bfd12194 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= -Date: Sat, 14 Jun 2025 09:59:52 +0200 -Subject: [PATCH 061/517] net: dsa: b53: prevent FAST_AGE access on BCM5325 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -BCM5325 doesn't implement FAST_AGE registers so we should avoid reading or -writing them. - -Signed-off-by: Álvaro Fernández Rojas -Reviewed-by: Florian Fainelli -Link: https://patch.msgid.link/20250614080000.1884236-7-noltari@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/b53/b53_common.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c -index 807c49880932..8606eabcaaa8 100644 ---- a/drivers/net/dsa/b53/b53_common.c -+++ b/drivers/net/dsa/b53/b53_common.c -@@ -492,6 +492,9 @@ static int b53_flush_arl(struct b53_device *dev, u8 mask) - { - unsigned int i; - -+ if (is5325(dev)) -+ return 0; -+ - b53_write8(dev, B53_CTRL_PAGE, B53_FAST_AGE_CTRL, - FAST_AGE_DONE | FAST_AGE_DYNAMIC | mask); - -@@ -516,6 +519,9 @@ static int b53_flush_arl(struct b53_device *dev, u8 mask) - - static int b53_fast_age_port(struct b53_device *dev, int port) - { -+ if (is5325(dev)) -+ return 0; -+ - b53_write8(dev, B53_CTRL_PAGE, B53_FAST_AGE_PORT_CTRL, port); - - return b53_flush_arl(dev, FAST_AGE_PORT); -@@ -523,6 +529,9 @@ static int b53_fast_age_port(struct b53_device *dev, int port) - - static int b53_fast_age_vlan(struct b53_device *dev, u16 vid) - { -+ if (is5325(dev)) -+ return 0; -+ - b53_write16(dev, B53_CTRL_PAGE, B53_FAST_AGE_VID_CTRL, vid); - - return b53_flush_arl(dev, FAST_AGE_VLAN); --- -2.51.0 - - -From 3d97487faefb90c06ad9e3d5b52d2f4c80bf96a5 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= -Date: Sat, 14 Jun 2025 09:59:56 +0200 -Subject: [PATCH 062/517] net: dsa: b53: prevent BRCM_HDR access on older - devices -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Older switches don't implement BRCM_HDR register so we should avoid -reading or writing it. - -Reviewed-by: Florian Fainelli -Signed-off-by: Álvaro Fernández Rojas -Link: https://patch.msgid.link/20250614080000.1884236-11-noltari@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/b53/b53_common.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c -index 8606eabcaaa8..f3c01ac88e3a 100644 ---- a/drivers/net/dsa/b53/b53_common.c -+++ b/drivers/net/dsa/b53/b53_common.c -@@ -747,6 +747,11 @@ void b53_brcm_hdr_setup(struct dsa_switch *ds, int port) - hdr_ctl |= GC_FRM_MGMT_PORT_M; - b53_write8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, hdr_ctl); - -+ /* B53_BRCM_HDR not present on devices with legacy tags */ -+ if (dev->tag_protocol == DSA_TAG_PROTO_BRCM_LEGACY || -+ dev->tag_protocol == DSA_TAG_PROTO_BRCM_LEGACY_FCS) -+ return; -+ - /* Enable Broadcom tags for IMP port */ - b53_read8(dev, B53_MGMT_PAGE, B53_BRCM_HDR, &hdr_ctl); - if (tag_en) --- -2.51.0 - - -From 1f5369fdb49ca6051756ed11be3600e0c3535e70 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= -Date: Sat, 14 Jun 2025 09:59:58 +0200 -Subject: [PATCH 063/517] net: dsa: b53: fix unicast/multicast flooding on - BCM5325 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -BCM5325 doesn't implement UC_FLOOD_MASK, MC_FLOOD_MASK and IPMC_FLOOD_MASK -registers. -This has to be handled differently with other pages and registers. - -Signed-off-by: Álvaro Fernández Rojas -Reviewed-by: Florian Fainelli -Link: https://patch.msgid.link/20250614080000.1884236-13-noltari@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/b53/b53_common.c | 60 ++++++++++++++++++++++---------- - drivers/net/dsa/b53/b53_regs.h | 13 +++++++ - 2 files changed, 55 insertions(+), 18 deletions(-) - -diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c -index f3c01ac88e3a..051d9504b0de 100644 ---- a/drivers/net/dsa/b53/b53_common.c -+++ b/drivers/net/dsa/b53/b53_common.c -@@ -564,12 +564,24 @@ static void b53_port_set_ucast_flood(struct b53_device *dev, int port, - { - u16 uc; - -- b53_read16(dev, B53_CTRL_PAGE, B53_UC_FLOOD_MASK, &uc); -- if (unicast) -- uc |= BIT(port); -- else -- uc &= ~BIT(port); -- b53_write16(dev, B53_CTRL_PAGE, B53_UC_FLOOD_MASK, uc); -+ if (is5325(dev)) { -+ if (port == B53_CPU_PORT_25) -+ port = B53_CPU_PORT; -+ -+ b53_read16(dev, B53_IEEE_PAGE, B53_IEEE_UCAST_DLF, &uc); -+ if (unicast) -+ uc |= BIT(port) | B53_IEEE_UCAST_DROP_EN; -+ else -+ uc &= ~BIT(port); -+ b53_write16(dev, B53_IEEE_PAGE, B53_IEEE_UCAST_DLF, uc); -+ } else { -+ b53_read16(dev, B53_CTRL_PAGE, B53_UC_FLOOD_MASK, &uc); -+ if (unicast) -+ uc |= BIT(port); -+ else -+ uc &= ~BIT(port); -+ b53_write16(dev, B53_CTRL_PAGE, B53_UC_FLOOD_MASK, uc); -+ } - } - - static void b53_port_set_mcast_flood(struct b53_device *dev, int port, -@@ -577,19 +589,31 @@ static void b53_port_set_mcast_flood(struct b53_device *dev, int port, - { - u16 mc; - -- b53_read16(dev, B53_CTRL_PAGE, B53_MC_FLOOD_MASK, &mc); -- if (multicast) -- mc |= BIT(port); -- else -- mc &= ~BIT(port); -- b53_write16(dev, B53_CTRL_PAGE, B53_MC_FLOOD_MASK, mc); -+ if (is5325(dev)) { -+ if (port == B53_CPU_PORT_25) -+ port = B53_CPU_PORT; - -- b53_read16(dev, B53_CTRL_PAGE, B53_IPMC_FLOOD_MASK, &mc); -- if (multicast) -- mc |= BIT(port); -- else -- mc &= ~BIT(port); -- b53_write16(dev, B53_CTRL_PAGE, B53_IPMC_FLOOD_MASK, mc); -+ b53_read16(dev, B53_IEEE_PAGE, B53_IEEE_MCAST_DLF, &mc); -+ if (multicast) -+ mc |= BIT(port) | B53_IEEE_MCAST_DROP_EN; -+ else -+ mc &= ~BIT(port); -+ b53_write16(dev, B53_IEEE_PAGE, B53_IEEE_MCAST_DLF, mc); -+ } else { -+ b53_read16(dev, B53_CTRL_PAGE, B53_MC_FLOOD_MASK, &mc); -+ if (multicast) -+ mc |= BIT(port); -+ else -+ mc &= ~BIT(port); -+ b53_write16(dev, B53_CTRL_PAGE, B53_MC_FLOOD_MASK, mc); -+ -+ b53_read16(dev, B53_CTRL_PAGE, B53_IPMC_FLOOD_MASK, &mc); -+ if (multicast) -+ mc |= BIT(port); -+ else -+ mc &= ~BIT(port); -+ b53_write16(dev, B53_CTRL_PAGE, B53_IPMC_FLOOD_MASK, mc); -+ } - } - - static void b53_port_set_learning(struct b53_device *dev, int port, -diff --git a/drivers/net/dsa/b53/b53_regs.h b/drivers/net/dsa/b53/b53_regs.h -index b6ef32d481ca..309fe0e46dad 100644 ---- a/drivers/net/dsa/b53/b53_regs.h -+++ b/drivers/net/dsa/b53/b53_regs.h -@@ -29,6 +29,7 @@ - #define B53_ARLIO_PAGE 0x05 /* ARL Access */ - #define B53_FRAMEBUF_PAGE 0x06 /* Management frame access */ - #define B53_MEM_ACCESS_PAGE 0x08 /* Memory access */ -+#define B53_IEEE_PAGE 0x0a /* IEEE 802.1X */ - - /* PHY Registers */ - #define B53_PORT_MII_PAGE(i) (0x10 + (i)) /* Port i MII Registers */ -@@ -371,6 +372,18 @@ - #define B53_ARL_SRCH_RSTL_MACVID(x) (B53_ARL_SRCH_RSTL_0_MACVID + ((x) * 0x10)) - #define B53_ARL_SRCH_RSTL(x) (B53_ARL_SRCH_RSTL_0 + ((x) * 0x10)) - -+/************************************************************************* -+ * IEEE 802.1X Registers -+ *************************************************************************/ -+ -+/* Multicast DLF Drop Control register (16 bit) */ -+#define B53_IEEE_MCAST_DLF 0x94 -+#define B53_IEEE_MCAST_DROP_EN BIT(11) -+ -+/* Unicast DLF Drop Control register (16 bit) */ -+#define B53_IEEE_UCAST_DLF 0x96 -+#define B53_IEEE_UCAST_DROP_EN BIT(11) -+ - /************************************************************************* - * Port VLAN Registers - *************************************************************************/ --- -2.51.0 - - -From ca931dc100c6aa5d9857b962ed84febb44c3b8d1 Mon Sep 17 00:00:00 2001 -From: Qingfang Deng -Date: Sat, 1 Mar 2025 21:55:16 +0800 -Subject: [PATCH 064/517] ppp: use IFF_NO_QUEUE in virtual interfaces -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -For PPPoE, PPTP, and PPPoL2TP, the start_xmit() function directly -forwards packets to the underlying network stack and never returns -anything other than 1. So these interfaces do not require a qdisc, -and the IFF_NO_QUEUE flag should be set. - -Introduces a direct_xmit flag in struct ppp_channel to indicate when -IFF_NO_QUEUE should be applied. The flag is set in ppp_connect_channel() -for relevant protocols. - -While at it, remove the usused latency member from struct ppp_channel. - -Signed-off-by: Qingfang Deng -Reviewed-by: Toke Høiland-Jørgensen -Link: https://patch.msgid.link/20250301135517.695809-1-dqfext@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ppp/ppp_generic.c | 4 ++++ - drivers/net/ppp/pppoe.c | 1 + - drivers/net/ppp/pptp.c | 1 + - include/linux/ppp_channel.h | 3 +-- - net/l2tp/l2tp_ppp.c | 1 + - 5 files changed, 8 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c -index afc1566488b3..9b8ddf644ac3 100644 ---- a/drivers/net/ppp/ppp_generic.c -+++ b/drivers/net/ppp/ppp_generic.c -@@ -3504,6 +3504,10 @@ ppp_connect_channel(struct channel *pch, int unit) - ret = -ENOTCONN; - goto outl; - } -+ if (pch->chan->direct_xmit) -+ ppp->dev->priv_flags |= IFF_NO_QUEUE; -+ else -+ ppp->dev->priv_flags &= ~IFF_NO_QUEUE; - spin_unlock_bh(&pch->downl); - if (pch->file.hdrlen > ppp->file.hdrlen) - ppp->file.hdrlen = pch->file.hdrlen; -diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c -index 2ea4f4890d23..68e631718ab0 100644 ---- a/drivers/net/ppp/pppoe.c -+++ b/drivers/net/ppp/pppoe.c -@@ -693,6 +693,7 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr, - po->chan.mtu = dev->mtu - sizeof(struct pppoe_hdr) - 2; - po->chan.private = sk; - po->chan.ops = &pppoe_chan_ops; -+ po->chan.direct_xmit = true; - - error = ppp_register_net_channel(dev_net(dev), &po->chan); - if (error) { -diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c -index cec3bb22471b..90737cb71892 100644 ---- a/drivers/net/ppp/pptp.c -+++ b/drivers/net/ppp/pptp.c -@@ -469,6 +469,7 @@ static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr, - po->chan.mtu -= PPTP_HEADER_OVERHEAD; - - po->chan.hdrlen = 2 + sizeof(struct pptp_gre_header); -+ po->chan.direct_xmit = true; - error = ppp_register_channel(&po->chan); - if (error) { - pr_err("PPTP: failed to register PPP channel (%d)\n", error); -diff --git a/include/linux/ppp_channel.h b/include/linux/ppp_channel.h -index 45e6e427ceb8..f73fbea0dbc2 100644 ---- a/include/linux/ppp_channel.h -+++ b/include/linux/ppp_channel.h -@@ -42,8 +42,7 @@ struct ppp_channel { - int hdrlen; /* amount of headroom channel needs */ - void *ppp; /* opaque to channel */ - int speed; /* transfer rate (bytes/second) */ -- /* the following is not used at present */ -- int latency; /* overhead time in milliseconds */ -+ bool direct_xmit; /* no qdisc, xmit directly */ - }; - - #ifdef __KERNEL__ -diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c -index 16c514f628ea..5e12e7ce17d8 100644 ---- a/net/l2tp/l2tp_ppp.c -+++ b/net/l2tp/l2tp_ppp.c -@@ -796,6 +796,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, - po->chan.private = sk; - po->chan.ops = &pppol2tp_chan_ops; - po->chan.mtu = pppol2tp_tunnel_mtu(tunnel); -+ po->chan.direct_xmit = true; - - error = ppp_register_net_channel(sock_net(sk), &po->chan); - if (error) { --- -2.51.0 - - -From 1bdc62e6e933d77990348c17ebbff861f37e160a Mon Sep 17 00:00:00 2001 -From: Shengyu Qu -Date: Mon, 14 Apr 2025 18:56:01 +0800 -Subject: [PATCH 065/517] net: bridge: locally receive all multicast packets if - IFF_ALLMULTI is set - -If multicast snooping is enabled, multicast packets may not always end up -on the local bridge interface, if the host is not a member of the multicast -group. Similar to how IFF_PROMISC allows all packets to be received -locally, let IFF_ALLMULTI allow all multicast packets to be received. - -OpenWrt uses a user space daemon for DHCPv6/RA/NDP handling, and in relay -mode it sets the ALLMULTI flag in order to receive all relevant queries on -the network. - -This works for normal network interfaces and non-snooping bridges, but not -snooping bridges (unless multicast routing is enabled). - -Reported-by: Felix Fietkau -Closes: https://github.com/openwrt/openwrt/issues/15857#issuecomment-2662851243 -Signed-off-by: Shengyu Qu -Reviewed-by: Ido Schimmel -Acked-by: Nikolay Aleksandrov -Link: https://patch.msgid.link/OSZPR01MB8434308370ACAFA90A22980798B32@OSZPR01MB8434.jpnprd01.prod.outlook.com -Signed-off-by: Jakub Kicinski ---- - net/bridge/br_input.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c -index ceaa5a89b947..c059e5657db3 100644 ---- a/net/bridge/br_input.c -+++ b/net/bridge/br_input.c -@@ -184,7 +184,8 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb - if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) && - br_multicast_querier_exists(brmctx, eth_hdr(skb), mdst)) { - if ((mdst && mdst->host_joined) || -- br_multicast_is_router(brmctx, skb)) { -+ br_multicast_is_router(brmctx, skb) || -+ br->dev->flags & IFF_ALLMULTI) { - local_rcv = true; - DEV_STATS_INC(br->dev, multicast); - } --- -2.51.0 - - -From a0238cb711e97c201f11e6686882562dab61e6d4 Mon Sep 17 00:00:00 2001 -From: Rui Salvaterra -Date: Wed, 5 Mar 2025 11:53:56 +0000 -Subject: [PATCH 066/517] igc: enable HW vlan tag insertion/stripping by - default - -This is enabled by default in other Intel drivers I've checked (e1000, e1000e, -iavf, igb and ice). Fixes an out-of-the-box performance issue when running -OpenWrt on typical mini-PCs with igc-supported Ethernet controllers and 802.1Q -VLAN configurations, as ethtool isn't part of the default packages and sane -defaults are expected. - -In my specific case, with an Intel N100-based machine with four I226-V Ethernet -controllers, my upload performance increased from under 30 Mb/s to the expected -~1 Gb/s. - -Signed-off-by: Rui Salvaterra ---- - drivers/net/ethernet/intel/igc/igc_main.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c -index 9ba41a427e14..cbe751d963bc 100644 ---- a/drivers/net/ethernet/intel/igc/igc_main.c -+++ b/drivers/net/ethernet/intel/igc/igc_main.c -@@ -7070,6 +7070,9 @@ static int igc_probe(struct pci_dev *pdev, - netdev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT | - NETDEV_XDP_ACT_XSK_ZEROCOPY; - -+ /* enable HW vlan tag insertion/stripping by default */ -+ netdev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX; -+ - /* MTU range: 68 - 9216 */ - netdev->min_mtu = ETH_MIN_MTU; - netdev->max_mtu = MAX_STD_JUMBO_FRAME_SIZE; --- -2.51.0 - - -From d358cb92d517772c5cf4267a1ecf504178bd5439 Mon Sep 17 00:00:00 2001 -From: "SkyLake.Huang" -Date: Thu, 17 Oct 2024 11:22:11 +0800 -Subject: [PATCH 067/517] net: phy: mediatek-ge-soc: Fix coding style - -This patch fixes spelling errors, re-arrange vars with -reverse Xmas tree and remove unnecessary parens in -mediatek-ge-soc.c. - -Signed-off-by: SkyLake.Huang -Reviewed-by: Simon Horman -Signed-off-by: Andrew Lunn ---- - drivers/net/phy/mediatek-ge-soc.c | 36 ++++++++++++++++--------------- - 1 file changed, 19 insertions(+), 17 deletions(-) - -diff --git a/drivers/net/phy/mediatek-ge-soc.c b/drivers/net/phy/mediatek-ge-soc.c -index f4f9412d0cd7..e9c422f4e24b 100644 ---- a/drivers/net/phy/mediatek-ge-soc.c -+++ b/drivers/net/phy/mediatek-ge-soc.c -@@ -408,16 +408,17 @@ static int tx_offset_cal_efuse(struct phy_device *phydev, u32 *buf) - - static int tx_amp_fill_result(struct phy_device *phydev, u16 *buf) - { -- int i; -- int bias[16] = {}; -- const int vals_9461[16] = { 7, 1, 4, 7, -- 7, 1, 4, 7, -- 7, 1, 4, 7, -- 7, 1, 4, 7 }; - const int vals_9481[16] = { 10, 6, 6, 10, - 10, 6, 6, 10, - 10, 6, 6, 10, - 10, 6, 6, 10 }; -+ const int vals_9461[16] = { 7, 1, 4, 7, -+ 7, 1, 4, 7, -+ 7, 1, 4, 7, -+ 7, 1, 4, 7 }; -+ int bias[16] = {}; -+ int i; -+ - switch (phydev->drv->phy_id) { - case MTK_GPHY_ID_MT7981: - /* We add some calibration to efuse values -@@ -1069,10 +1070,10 @@ static int start_cal(struct phy_device *phydev, enum CAL_ITEM cal_item, - - static int mt798x_phy_calibration(struct phy_device *phydev) - { -+ struct nvmem_cell *cell; - int ret = 0; -- u32 *buf; - size_t len; -- struct nvmem_cell *cell; -+ u32 *buf; - - cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data"); - if (IS_ERR(cell)) { -@@ -1210,14 +1211,15 @@ static int mt798x_phy_led_brightness_set(struct phy_device *phydev, - return mt798x_phy_hw_led_on_set(phydev, index, (value != LED_OFF)); - } - --static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_FULL_DUPLEX) | -- BIT(TRIGGER_NETDEV_HALF_DUPLEX) | -- BIT(TRIGGER_NETDEV_LINK) | -- BIT(TRIGGER_NETDEV_LINK_10) | -- BIT(TRIGGER_NETDEV_LINK_100) | -- BIT(TRIGGER_NETDEV_LINK_1000) | -- BIT(TRIGGER_NETDEV_RX) | -- BIT(TRIGGER_NETDEV_TX)); -+static const unsigned long supported_triggers = -+ BIT(TRIGGER_NETDEV_FULL_DUPLEX) | -+ BIT(TRIGGER_NETDEV_HALF_DUPLEX) | -+ BIT(TRIGGER_NETDEV_LINK) | -+ BIT(TRIGGER_NETDEV_LINK_10) | -+ BIT(TRIGGER_NETDEV_LINK_100) | -+ BIT(TRIGGER_NETDEV_LINK_1000) | -+ BIT(TRIGGER_NETDEV_RX) | -+ BIT(TRIGGER_NETDEV_TX); - - static int mt798x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index, - unsigned long rules) -@@ -1415,7 +1417,7 @@ static int mt7988_phy_probe_shared(struct phy_device *phydev) - * LED_C and LED_D respectively. At the same time those pins are used to - * bootstrap configuration of the reference clock source (LED_A), - * DRAM DDRx16b x2/x1 (LED_B) and boot device (LED_C, LED_D). -- * In practise this is done using a LED and a resistor pulling the pin -+ * In practice this is done using a LED and a resistor pulling the pin - * either to GND or to VIO. - * The detected value at boot time is accessible at run-time using the - * TPBANK0 register located in the gpio base of the pinctrl, in order --- -2.51.0 - - -From 450ae2beafadb9d3a78227c4c882e9635a55b0f3 Mon Sep 17 00:00:00 2001 -From: "SkyLake.Huang" -Date: Thu, 17 Oct 2024 11:22:12 +0800 -Subject: [PATCH 068/517] net: phy: mediatek-ge-soc: Shrink line wrapping to 80 - characters - -This patch shrinks line wrapping to 80 chars. Also, in -tx_amp_fill_result(), use FIELD_PREP() to prettify code. - -Signed-off-by: SkyLake.Huang -Reviewed-by: Simon Horman -Signed-off-by: Andrew Lunn ---- - drivers/net/phy/mediatek-ge-soc.c | 125 +++++++++++++++++++++--------- - 1 file changed, 88 insertions(+), 37 deletions(-) - -diff --git a/drivers/net/phy/mediatek-ge-soc.c b/drivers/net/phy/mediatek-ge-soc.c -index e9c422f4e24b..1d7719b6c351 100644 ---- a/drivers/net/phy/mediatek-ge-soc.c -+++ b/drivers/net/phy/mediatek-ge-soc.c -@@ -342,7 +342,8 @@ static int cal_cycle(struct phy_device *phydev, int devad, - ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, - MTK_PHY_RG_AD_CAL_CLK, reg_val, - reg_val & MTK_PHY_DA_CAL_CLK, 500, -- ANALOG_INTERNAL_OPERATION_MAX_US, false); -+ ANALOG_INTERNAL_OPERATION_MAX_US, -+ false); - if (ret) { - phydev_err(phydev, "Calibration cycle timeout\n"); - return ret; -@@ -441,40 +442,72 @@ static int tx_amp_fill_result(struct phy_device *phydev, u16 *buf) - } - - phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG, -- MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, (buf[0] + bias[0]) << 10); -+ MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, -+ FIELD_PREP(MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, -+ buf[0] + bias[0])); - phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG, -- MTK_PHY_DA_TX_I2MPB_A_TBT_MASK, buf[0] + bias[1]); -+ MTK_PHY_DA_TX_I2MPB_A_TBT_MASK, -+ FIELD_PREP(MTK_PHY_DA_TX_I2MPB_A_TBT_MASK, -+ buf[0] + bias[1])); - phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2, -- MTK_PHY_DA_TX_I2MPB_A_HBT_MASK, (buf[0] + bias[2]) << 10); -+ MTK_PHY_DA_TX_I2MPB_A_HBT_MASK, -+ FIELD_PREP(MTK_PHY_DA_TX_I2MPB_A_HBT_MASK, -+ buf[0] + bias[2])); - phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2, -- MTK_PHY_DA_TX_I2MPB_A_TST_MASK, buf[0] + bias[3]); -+ MTK_PHY_DA_TX_I2MPB_A_TST_MASK, -+ FIELD_PREP(MTK_PHY_DA_TX_I2MPB_A_TST_MASK, -+ buf[0] + bias[3])); - - phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1, -- MTK_PHY_DA_TX_I2MPB_B_GBE_MASK, (buf[1] + bias[4]) << 8); -+ MTK_PHY_DA_TX_I2MPB_B_GBE_MASK, -+ FIELD_PREP(MTK_PHY_DA_TX_I2MPB_B_GBE_MASK, -+ buf[1] + bias[4])); - phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1, -- MTK_PHY_DA_TX_I2MPB_B_TBT_MASK, buf[1] + bias[5]); -+ MTK_PHY_DA_TX_I2MPB_B_TBT_MASK, -+ FIELD_PREP(MTK_PHY_DA_TX_I2MPB_B_TBT_MASK, -+ buf[1] + bias[5])); - phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2, -- MTK_PHY_DA_TX_I2MPB_B_HBT_MASK, (buf[1] + bias[6]) << 8); -+ MTK_PHY_DA_TX_I2MPB_B_HBT_MASK, -+ FIELD_PREP(MTK_PHY_DA_TX_I2MPB_B_HBT_MASK, -+ buf[1] + bias[6])); - phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2, -- MTK_PHY_DA_TX_I2MPB_B_TST_MASK, buf[1] + bias[7]); -+ MTK_PHY_DA_TX_I2MPB_B_TST_MASK, -+ FIELD_PREP(MTK_PHY_DA_TX_I2MPB_B_TST_MASK, -+ buf[1] + bias[7])); - - phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1, -- MTK_PHY_DA_TX_I2MPB_C_GBE_MASK, (buf[2] + bias[8]) << 8); -+ MTK_PHY_DA_TX_I2MPB_C_GBE_MASK, -+ FIELD_PREP(MTK_PHY_DA_TX_I2MPB_C_GBE_MASK, -+ buf[2] + bias[8])); - phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1, -- MTK_PHY_DA_TX_I2MPB_C_TBT_MASK, buf[2] + bias[9]); -+ MTK_PHY_DA_TX_I2MPB_C_TBT_MASK, -+ FIELD_PREP(MTK_PHY_DA_TX_I2MPB_C_TBT_MASK, -+ buf[2] + bias[9])); - phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2, -- MTK_PHY_DA_TX_I2MPB_C_HBT_MASK, (buf[2] + bias[10]) << 8); -+ MTK_PHY_DA_TX_I2MPB_C_HBT_MASK, -+ FIELD_PREP(MTK_PHY_DA_TX_I2MPB_C_HBT_MASK, -+ buf[2] + bias[10])); - phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2, -- MTK_PHY_DA_TX_I2MPB_C_TST_MASK, buf[2] + bias[11]); -+ MTK_PHY_DA_TX_I2MPB_C_TST_MASK, -+ FIELD_PREP(MTK_PHY_DA_TX_I2MPB_C_TST_MASK, -+ buf[2] + bias[11])); - - phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1, -- MTK_PHY_DA_TX_I2MPB_D_GBE_MASK, (buf[3] + bias[12]) << 8); -+ MTK_PHY_DA_TX_I2MPB_D_GBE_MASK, -+ FIELD_PREP(MTK_PHY_DA_TX_I2MPB_D_GBE_MASK, -+ buf[3] + bias[12])); - phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1, -- MTK_PHY_DA_TX_I2MPB_D_TBT_MASK, buf[3] + bias[13]); -+ MTK_PHY_DA_TX_I2MPB_D_TBT_MASK, -+ FIELD_PREP(MTK_PHY_DA_TX_I2MPB_D_TBT_MASK, -+ buf[3] + bias[13])); - phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2, -- MTK_PHY_DA_TX_I2MPB_D_HBT_MASK, (buf[3] + bias[14]) << 8); -+ MTK_PHY_DA_TX_I2MPB_D_HBT_MASK, -+ FIELD_PREP(MTK_PHY_DA_TX_I2MPB_D_HBT_MASK, -+ buf[3] + bias[14])); - phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2, -- MTK_PHY_DA_TX_I2MPB_D_TST_MASK, buf[3] + bias[15]); -+ MTK_PHY_DA_TX_I2MPB_D_TST_MASK, -+ FIELD_PREP(MTK_PHY_DA_TX_I2MPB_D_TST_MASK, -+ buf[3] + bias[15])); - - return 0; - } -@@ -663,7 +696,8 @@ static int tx_vcm_cal_sw(struct phy_device *phydev, u8 rg_txreserve_x) - goto restore; - - /* We calibrate TX-VCM in different logic. Check upper index and then -- * lower index. If this calibration is valid, apply lower index's result. -+ * lower index. If this calibration is valid, apply lower index's -+ * result. - */ - ret = upper_ret - lower_ret; - if (ret == 1) { -@@ -692,7 +726,8 @@ static int tx_vcm_cal_sw(struct phy_device *phydev, u8 rg_txreserve_x) - } else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 && - lower_ret == 0) { - ret = 0; -- phydev_warn(phydev, "TX-VCM SW cal result at high margin 0x%x\n", -+ phydev_warn(phydev, -+ "TX-VCM SW cal result at high margin 0x%x\n", - upper_idx); - } else { - ret = -EINVAL; -@@ -796,7 +831,8 @@ static void mt7981_phy_finetune(struct phy_device *phydev) - - /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9 */ - phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234, -- MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK, -+ MTK_PHY_TR_OPEN_LOOP_EN_MASK | -+ MTK_PHY_LPF_X_AVERAGE_MASK, - BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9)); - - /* rg_tr_lpf_cnt_val = 512 */ -@@ -865,7 +901,8 @@ static void mt7988_phy_finetune(struct phy_device *phydev) - - /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 10 */ - phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234, -- MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK, -+ MTK_PHY_TR_OPEN_LOOP_EN_MASK | -+ MTK_PHY_LPF_X_AVERAGE_MASK, - BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0xa)); - - /* rg_tr_lpf_cnt_val = 1023 */ -@@ -977,7 +1014,8 @@ static void mt798x_phy_eee(struct phy_device *phydev) - phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); - - phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_3); -- __phy_modify(phydev, MTK_PHY_LPI_REG_14, MTK_PHY_LPI_WAKE_TIMER_1000_MASK, -+ __phy_modify(phydev, MTK_PHY_LPI_REG_14, -+ MTK_PHY_LPI_WAKE_TIMER_1000_MASK, - FIELD_PREP(MTK_PHY_LPI_WAKE_TIMER_1000_MASK, 0x19c)); - - __phy_modify(phydev, MTK_PHY_LPI_REG_1c, MTK_PHY_SMI_DET_ON_THRESH_MASK, -@@ -987,7 +1025,8 @@ static void mt798x_phy_eee(struct phy_device *phydev) - phy_modify_mmd(phydev, MDIO_MMD_VEND1, - MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122, - MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK, -- FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK, 0xff)); -+ FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK, -+ 0xff)); - } - - static int cal_sw(struct phy_device *phydev, enum CAL_ITEM cal_item, -@@ -1147,7 +1186,8 @@ static int mt798x_phy_hw_led_on_set(struct phy_device *phydev, u8 index, - (index ? 16 : 0), &priv->led_state); - if (changed) - return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ? -- MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL, -+ MTK_PHY_LED1_ON_CTRL : -+ MTK_PHY_LED0_ON_CTRL, - MTK_PHY_LED_ON_MASK, - on ? MTK_PHY_LED_ON_FORCE_ON : 0); - else -@@ -1157,7 +1197,8 @@ static int mt798x_phy_hw_led_on_set(struct phy_device *phydev, u8 index, - static int mt798x_phy_hw_led_blink_set(struct phy_device *phydev, u8 index, - bool blinking) - { -- unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0); -+ unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + -+ (index ? 16 : 0); - struct mtk_socphy_priv *priv = phydev->priv; - bool changed; - -@@ -1170,8 +1211,10 @@ static int mt798x_phy_hw_led_blink_set(struct phy_device *phydev, u8 index, - (index ? 16 : 0), &priv->led_state); - if (changed) - return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ? -- MTK_PHY_LED1_BLINK_CTRL : MTK_PHY_LED0_BLINK_CTRL, -- blinking ? MTK_PHY_LED_BLINK_FORCE_BLINK : 0); -+ MTK_PHY_LED1_BLINK_CTRL : -+ MTK_PHY_LED0_BLINK_CTRL, -+ blinking ? -+ MTK_PHY_LED_BLINK_FORCE_BLINK : 0); - else - return 0; - } -@@ -1237,7 +1280,8 @@ static int mt798x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index, - static int mt798x_phy_led_hw_control_get(struct phy_device *phydev, u8 index, - unsigned long *rules) - { -- unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0); -+ unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + -+ (index ? 16 : 0); - unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0); - unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0); - struct mtk_socphy_priv *priv = phydev->priv; -@@ -1258,8 +1302,8 @@ static int mt798x_phy_led_hw_control_get(struct phy_device *phydev, u8 index, - if (blink < 0) - return -EIO; - -- if ((on & (MTK_PHY_LED_ON_LINK | MTK_PHY_LED_ON_FDX | MTK_PHY_LED_ON_HDX | -- MTK_PHY_LED_ON_LINKDOWN)) || -+ if ((on & (MTK_PHY_LED_ON_LINK | MTK_PHY_LED_ON_FDX | -+ MTK_PHY_LED_ON_HDX | MTK_PHY_LED_ON_LINKDOWN)) || - (blink & (MTK_PHY_LED_BLINK_RX | MTK_PHY_LED_BLINK_TX))) - set_bit(bit_netdev, &priv->led_state); - else -@@ -1333,17 +1377,23 @@ static int mt798x_phy_led_hw_control_set(struct phy_device *phydev, u8 index, - - if (rules & BIT(TRIGGER_NETDEV_RX)) { - blink |= (on & MTK_PHY_LED_ON_LINK) ? -- (((on & MTK_PHY_LED_ON_LINK10) ? MTK_PHY_LED_BLINK_10RX : 0) | -- ((on & MTK_PHY_LED_ON_LINK100) ? MTK_PHY_LED_BLINK_100RX : 0) | -- ((on & MTK_PHY_LED_ON_LINK1000) ? MTK_PHY_LED_BLINK_1000RX : 0)) : -+ (((on & MTK_PHY_LED_ON_LINK10) ? -+ MTK_PHY_LED_BLINK_10RX : 0) | -+ ((on & MTK_PHY_LED_ON_LINK100) ? -+ MTK_PHY_LED_BLINK_100RX : 0) | -+ ((on & MTK_PHY_LED_ON_LINK1000) ? -+ MTK_PHY_LED_BLINK_1000RX : 0)) : - MTK_PHY_LED_BLINK_RX; - } - - if (rules & BIT(TRIGGER_NETDEV_TX)) { - blink |= (on & MTK_PHY_LED_ON_LINK) ? -- (((on & MTK_PHY_LED_ON_LINK10) ? MTK_PHY_LED_BLINK_10TX : 0) | -- ((on & MTK_PHY_LED_ON_LINK100) ? MTK_PHY_LED_BLINK_100TX : 0) | -- ((on & MTK_PHY_LED_ON_LINK1000) ? MTK_PHY_LED_BLINK_1000TX : 0)) : -+ (((on & MTK_PHY_LED_ON_LINK10) ? -+ MTK_PHY_LED_BLINK_10TX : 0) | -+ ((on & MTK_PHY_LED_ON_LINK100) ? -+ MTK_PHY_LED_BLINK_100TX : 0) | -+ ((on & MTK_PHY_LED_ON_LINK1000) ? -+ MTK_PHY_LED_BLINK_1000TX : 0)) : - MTK_PHY_LED_BLINK_TX; - } - -@@ -1400,7 +1450,8 @@ static int mt7988_phy_fix_leds_polarities(struct phy_device *phydev) - /* Only now setup pinctrl to avoid bogus blinking */ - pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "gbe-led"); - if (IS_ERR(pinctrl)) -- dev_err(&phydev->mdio.bus->dev, "Failed to setup PHY LED pinctrl\n"); -+ dev_err(&phydev->mdio.bus->dev, -+ "Failed to setup PHY LED pinctrl\n"); - - return 0; - } --- -2.51.0 - - -From 2c093d2f19967ec88a8f318d63fbad315b3435df Mon Sep 17 00:00:00 2001 -From: "SkyLake.Huang" -Date: Thu, 17 Oct 2024 11:22:13 +0800 -Subject: [PATCH 069/517] net: phy: mediatek-ge-soc: Propagate error code - correctly in cal_cycle() - -This patch propagates error code correctly in cal_cycle() -and improve with FIELD_GET(). - -Signed-off-by: SkyLake.Huang -Reviewed-by: Simon Horman -Signed-off-by: Andrew Lunn ---- - drivers/net/phy/mediatek-ge-soc.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/drivers/net/phy/mediatek-ge-soc.c b/drivers/net/phy/mediatek-ge-soc.c -index 1d7719b6c351..a931832b1418 100644 ---- a/drivers/net/phy/mediatek-ge-soc.c -+++ b/drivers/net/phy/mediatek-ge-soc.c -@@ -110,7 +110,7 @@ - #define MTK_PHY_CR_TX_AMP_OFFSET_D_MASK GENMASK(6, 0) - - #define MTK_PHY_RG_AD_CAL_COMP 0x17a --#define MTK_PHY_AD_CAL_COMP_OUT_SHIFT (8) -+#define MTK_PHY_AD_CAL_COMP_OUT_MASK GENMASK(8, 8) - - #define MTK_PHY_RG_AD_CAL_CLK 0x17b - #define MTK_PHY_DA_CAL_CLK BIT(0) -@@ -351,8 +351,10 @@ static int cal_cycle(struct phy_device *phydev, int devad, - - phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN, - MTK_PHY_DA_CALIN_FLAG); -- ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CAL_COMP) >> -- MTK_PHY_AD_CAL_COMP_OUT_SHIFT; -+ ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CAL_COMP); -+ if (ret < 0) -+ return ret; -+ ret = FIELD_GET(MTK_PHY_AD_CAL_COMP_OUT_MASK, ret); - phydev_dbg(phydev, "cal_val: 0x%x, ret: %d\n", cal_val, ret); - - return ret; --- -2.51.0 - - -From d0e33fc271ee343d7da7e84dbbc07e3999b2b5af Mon Sep 17 00:00:00 2001 -From: "SkyLake.Huang" -Date: Sat, 9 Nov 2024 00:34:51 +0800 -Subject: [PATCH 070/517] net: phy: mediatek: Re-organize MediaTek ethernet phy - drivers - -Re-organize MediaTek ethernet phy driver files and get ready to integrate -some common functions and add new 2.5G phy driver. -mtk-ge.c: MT7530 Gphy on MT7621 & MT7531 Gphy -mtk-ge-soc.c: Built-in Gphy on MT7981 & Built-in switch Gphy on MT7988 -mtk-2p5ge.c: Planned for built-in 2.5G phy on MT7988 - -Reviewed-by: Andrew Lunn -Signed-off-by: SkyLake.Huang -Signed-off-by: David S. Miller ---- - MAINTAINERS | 4 ++-- - drivers/net/phy/Kconfig | 17 +------------- - drivers/net/phy/Makefile | 3 +-- - drivers/net/phy/mediatek/Kconfig | 22 +++++++++++++++++++ - drivers/net/phy/mediatek/Makefile | 3 +++ - .../mtk-ge-soc.c} | 0 - .../phy/{mediatek-ge.c => mediatek/mtk-ge.c} | 0 - 7 files changed, 29 insertions(+), 20 deletions(-) - create mode 100644 drivers/net/phy/mediatek/Kconfig - create mode 100644 drivers/net/phy/mediatek/Makefile - rename drivers/net/phy/{mediatek-ge-soc.c => mediatek/mtk-ge-soc.c} (100%) - rename drivers/net/phy/{mediatek-ge.c => mediatek/mtk-ge.c} (100%) - -diff --git a/MAINTAINERS b/MAINTAINERS -index d0f18fdba068..7aab943889e0 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -14427,8 +14427,8 @@ M: Qingfang Deng - M: SkyLake Huang - L: netdev@vger.kernel.org - S: Maintained --F: drivers/net/phy/mediatek-ge-soc.c --F: drivers/net/phy/mediatek-ge.c -+F: drivers/net/phy/mediatek/mtk-ge-soc.c -+F: drivers/net/phy/mediatek/mtk-ge.c - F: drivers/phy/mediatek/phy-mtk-xfi-tphy.c - - MEDIATEK I2C CONTROLLER DRIVER -diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig -index 01b235b3bb7e..4e78a4d8fd2a 100644 ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -266,22 +266,7 @@ config MAXLINEAR_GPHY - Support for the Maxlinear GPY115, GPY211, GPY212, GPY215, - GPY241, GPY245 PHYs. - --config MEDIATEK_GE_PHY -- tristate "MediaTek Gigabit Ethernet PHYs" -- help -- Supports the MediaTek Gigabit Ethernet PHYs. -- --config MEDIATEK_GE_SOC_PHY -- tristate "MediaTek SoC Ethernet PHYs" -- depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST -- depends on NVMEM_MTK_EFUSE -- help -- Supports MediaTek SoC built-in Gigabit Ethernet PHYs. -- -- Include support for built-in Ethernet PHYs which are present in -- the MT7981 and MT7988 SoCs. These PHYs need calibration data -- present in the SoCs efuse and will dynamically calibrate VCM -- (common-mode voltage) during startup. -+source "drivers/net/phy/mediatek/Kconfig" - - config MICREL_PHY - tristate "Micrel PHYs" -diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile -index 90f886844381..e6145153e837 100644 ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -74,8 +74,7 @@ obj-$(CONFIG_MARVELL_PHY) += marvell.o - obj-$(CONFIG_MARVELL_88Q2XXX_PHY) += marvell-88q2xxx.o - obj-$(CONFIG_MARVELL_88X2222_PHY) += marvell-88x2222.o - obj-$(CONFIG_MAXLINEAR_GPHY) += mxl-gpy.o --obj-$(CONFIG_MEDIATEK_GE_PHY) += mediatek-ge.o --obj-$(CONFIG_MEDIATEK_GE_SOC_PHY) += mediatek-ge-soc.o -+obj-y += mediatek/ - obj-$(CONFIG_MESON_GXL_PHY) += meson-gxl.o - obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o - obj-$(CONFIG_MICREL_PHY) += micrel.o -diff --git a/drivers/net/phy/mediatek/Kconfig b/drivers/net/phy/mediatek/Kconfig -new file mode 100644 -index 000000000000..112d9c0f219c ---- /dev/null -+++ b/drivers/net/phy/mediatek/Kconfig -@@ -0,0 +1,22 @@ -+# SPDX-License-Identifier: GPL-2.0-only -+config MEDIATEK_GE_PHY -+ tristate "MediaTek Gigabit Ethernet PHYs" -+ help -+ Supports the MediaTek non-built-in Gigabit Ethernet PHYs. -+ -+ Non-built-in Gigabit Ethernet PHYs include mt7530/mt7531. -+ You may find mt7530 inside mt7621. This driver shares some -+ common operations with MediaTek SoC built-in Gigabit -+ Ethernet PHYs. -+ -+config MEDIATEK_GE_SOC_PHY -+ tristate "MediaTek SoC Ethernet PHYs" -+ depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST -+ depends on NVMEM_MTK_EFUSE -+ help -+ Supports MediaTek SoC built-in Gigabit Ethernet PHYs. -+ -+ Include support for built-in Ethernet PHYs which are present in -+ the MT7981 and MT7988 SoCs. These PHYs need calibration data -+ present in the SoCs efuse and will dynamically calibrate VCM -+ (common-mode voltage) during startup. -diff --git a/drivers/net/phy/mediatek/Makefile b/drivers/net/phy/mediatek/Makefile -new file mode 100644 -index 000000000000..005bde26c1d7 ---- /dev/null -+++ b/drivers/net/phy/mediatek/Makefile -@@ -0,0 +1,3 @@ -+# SPDX-License-Identifier: GPL-2.0 -+obj-$(CONFIG_MEDIATEK_GE_PHY) += mtk-ge.o -+obj-$(CONFIG_MEDIATEK_GE_SOC_PHY) += mtk-ge-soc.o -diff --git a/drivers/net/phy/mediatek-ge-soc.c b/drivers/net/phy/mediatek/mtk-ge-soc.c -similarity index 100% -rename from drivers/net/phy/mediatek-ge-soc.c -rename to drivers/net/phy/mediatek/mtk-ge-soc.c -diff --git a/drivers/net/phy/mediatek-ge.c b/drivers/net/phy/mediatek/mtk-ge.c -similarity index 100% -rename from drivers/net/phy/mediatek-ge.c -rename to drivers/net/phy/mediatek/mtk-ge.c --- -2.51.0 - - -From fcd36b51e49bdef0ba98bc6e63df359b475f2870 Mon Sep 17 00:00:00 2001 -From: "SkyLake.Huang" -Date: Sat, 9 Nov 2024 00:34:52 +0800 -Subject: [PATCH 071/517] net: phy: mediatek: Move LED helper functions into - mtk phy lib - -This patch creates mtk-phy-lib.c & mtk-phy.h and integrates mtk-ge-soc.c's -LED helper functions so that we can use those helper functions in other -MTK's ethernet phy driver. - -Reviewed-by: Andrew Lunn -Signed-off-by: SkyLake.Huang -Signed-off-by: David S. Miller ---- - MAINTAINERS | 2 + - drivers/net/phy/mediatek/Kconfig | 4 + - drivers/net/phy/mediatek/Makefile | 1 + - drivers/net/phy/mediatek/mtk-ge-soc.c | 280 +++---------------------- - drivers/net/phy/mediatek/mtk-phy-lib.c | 254 ++++++++++++++++++++++ - drivers/net/phy/mediatek/mtk.h | 86 ++++++++ - 6 files changed, 372 insertions(+), 255 deletions(-) - create mode 100644 drivers/net/phy/mediatek/mtk-phy-lib.c - create mode 100644 drivers/net/phy/mediatek/mtk.h - -diff --git a/MAINTAINERS b/MAINTAINERS -index 7aab943889e0..7d694e7b4f42 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -14428,7 +14428,9 @@ M: SkyLake Huang - L: netdev@vger.kernel.org - S: Maintained - F: drivers/net/phy/mediatek/mtk-ge-soc.c -+F: drivers/net/phy/mediatek/mtk-phy-lib.c - F: drivers/net/phy/mediatek/mtk-ge.c -+F: drivers/net/phy/mediatek/mtk.h - F: drivers/phy/mediatek/phy-mtk-xfi-tphy.c - - MEDIATEK I2C CONTROLLER DRIVER -diff --git a/drivers/net/phy/mediatek/Kconfig b/drivers/net/phy/mediatek/Kconfig -index 112d9c0f219c..19b5d23e7cd0 100644 ---- a/drivers/net/phy/mediatek/Kconfig -+++ b/drivers/net/phy/mediatek/Kconfig -@@ -1,4 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0-only -+config MTK_NET_PHYLIB -+ tristate -+ - config MEDIATEK_GE_PHY - tristate "MediaTek Gigabit Ethernet PHYs" - help -@@ -13,6 +16,7 @@ config MEDIATEK_GE_SOC_PHY - tristate "MediaTek SoC Ethernet PHYs" - depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST - depends on NVMEM_MTK_EFUSE -+ select MTK_NET_PHYLIB - help - Supports MediaTek SoC built-in Gigabit Ethernet PHYs. - -diff --git a/drivers/net/phy/mediatek/Makefile b/drivers/net/phy/mediatek/Makefile -index 005bde26c1d7..814879d0abe5 100644 ---- a/drivers/net/phy/mediatek/Makefile -+++ b/drivers/net/phy/mediatek/Makefile -@@ -1,3 +1,4 @@ - # SPDX-License-Identifier: GPL-2.0 -+obj-$(CONFIG_MTK_NET_PHYLIB) += mtk-phy-lib.o - obj-$(CONFIG_MEDIATEK_GE_PHY) += mtk-ge.o - obj-$(CONFIG_MEDIATEK_GE_SOC_PHY) += mtk-ge-soc.o -diff --git a/drivers/net/phy/mediatek/mtk-ge-soc.c b/drivers/net/phy/mediatek/mtk-ge-soc.c -index a931832b1418..d3a8b3946056 100644 ---- a/drivers/net/phy/mediatek/mtk-ge-soc.c -+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c -@@ -8,6 +8,8 @@ - #include - #include - -+#include "mtk.h" -+ - #define MTK_GPHY_ID_MT7981 0x03a29461 - #define MTK_GPHY_ID_MT7988 0x03a29481 - -@@ -210,41 +212,6 @@ - #define MTK_PHY_DA_TX_R50_PAIR_D 0x540 - - /* Registers on MDIO_MMD_VEND2 */ --#define MTK_PHY_LED0_ON_CTRL 0x24 --#define MTK_PHY_LED1_ON_CTRL 0x26 --#define MTK_PHY_LED_ON_MASK GENMASK(6, 0) --#define MTK_PHY_LED_ON_LINK1000 BIT(0) --#define MTK_PHY_LED_ON_LINK100 BIT(1) --#define MTK_PHY_LED_ON_LINK10 BIT(2) --#define MTK_PHY_LED_ON_LINK (MTK_PHY_LED_ON_LINK10 |\ -- MTK_PHY_LED_ON_LINK100 |\ -- MTK_PHY_LED_ON_LINK1000) --#define MTK_PHY_LED_ON_LINKDOWN BIT(3) --#define MTK_PHY_LED_ON_FDX BIT(4) /* Full duplex */ --#define MTK_PHY_LED_ON_HDX BIT(5) /* Half duplex */ --#define MTK_PHY_LED_ON_FORCE_ON BIT(6) --#define MTK_PHY_LED_ON_POLARITY BIT(14) --#define MTK_PHY_LED_ON_ENABLE BIT(15) -- --#define MTK_PHY_LED0_BLINK_CTRL 0x25 --#define MTK_PHY_LED1_BLINK_CTRL 0x27 --#define MTK_PHY_LED_BLINK_1000TX BIT(0) --#define MTK_PHY_LED_BLINK_1000RX BIT(1) --#define MTK_PHY_LED_BLINK_100TX BIT(2) --#define MTK_PHY_LED_BLINK_100RX BIT(3) --#define MTK_PHY_LED_BLINK_10TX BIT(4) --#define MTK_PHY_LED_BLINK_10RX BIT(5) --#define MTK_PHY_LED_BLINK_RX (MTK_PHY_LED_BLINK_10RX |\ -- MTK_PHY_LED_BLINK_100RX |\ -- MTK_PHY_LED_BLINK_1000RX) --#define MTK_PHY_LED_BLINK_TX (MTK_PHY_LED_BLINK_10TX |\ -- MTK_PHY_LED_BLINK_100TX |\ -- MTK_PHY_LED_BLINK_1000TX) --#define MTK_PHY_LED_BLINK_COLLISION BIT(6) --#define MTK_PHY_LED_BLINK_RX_CRC_ERR BIT(7) --#define MTK_PHY_LED_BLINK_RX_IDLE_ERR BIT(8) --#define MTK_PHY_LED_BLINK_FORCE_BLINK BIT(9) -- - #define MTK_PHY_LED1_DEFAULT_POLARITIES BIT(1) - - #define MTK_PHY_RG_BG_RASEL 0x115 -@@ -299,14 +266,6 @@ enum CAL_MODE { - SW_M - }; - --#define MTK_PHY_LED_STATE_FORCE_ON 0 --#define MTK_PHY_LED_STATE_FORCE_BLINK 1 --#define MTK_PHY_LED_STATE_NETDEV 2 -- --struct mtk_socphy_priv { -- unsigned long led_state; --}; -- - struct mtk_socphy_shared { - u32 boottrap; - struct mtk_socphy_priv priv[4]; -@@ -1172,76 +1131,23 @@ static int mt798x_phy_config_init(struct phy_device *phydev) - return mt798x_phy_calibration(phydev); - } - --static int mt798x_phy_hw_led_on_set(struct phy_device *phydev, u8 index, -- bool on) --{ -- unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0); -- struct mtk_socphy_priv *priv = phydev->priv; -- bool changed; -- -- if (on) -- changed = !test_and_set_bit(bit_on, &priv->led_state); -- else -- changed = !!test_and_clear_bit(bit_on, &priv->led_state); -- -- changed |= !!test_and_clear_bit(MTK_PHY_LED_STATE_NETDEV + -- (index ? 16 : 0), &priv->led_state); -- if (changed) -- return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ? -- MTK_PHY_LED1_ON_CTRL : -- MTK_PHY_LED0_ON_CTRL, -- MTK_PHY_LED_ON_MASK, -- on ? MTK_PHY_LED_ON_FORCE_ON : 0); -- else -- return 0; --} -- --static int mt798x_phy_hw_led_blink_set(struct phy_device *phydev, u8 index, -- bool blinking) --{ -- unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + -- (index ? 16 : 0); -- struct mtk_socphy_priv *priv = phydev->priv; -- bool changed; -- -- if (blinking) -- changed = !test_and_set_bit(bit_blink, &priv->led_state); -- else -- changed = !!test_and_clear_bit(bit_blink, &priv->led_state); -- -- changed |= !!test_bit(MTK_PHY_LED_STATE_NETDEV + -- (index ? 16 : 0), &priv->led_state); -- if (changed) -- return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ? -- MTK_PHY_LED1_BLINK_CTRL : -- MTK_PHY_LED0_BLINK_CTRL, -- blinking ? -- MTK_PHY_LED_BLINK_FORCE_BLINK : 0); -- else -- return 0; --} -- - static int mt798x_phy_led_blink_set(struct phy_device *phydev, u8 index, - unsigned long *delay_on, - unsigned long *delay_off) - { - bool blinking = false; -- int err = 0; -- -- if (index > 1) -- return -EINVAL; -+ int err; - -- if (delay_on && delay_off && (*delay_on > 0) && (*delay_off > 0)) { -- blinking = true; -- *delay_on = 50; -- *delay_off = 50; -- } -+ err = mtk_phy_led_num_dly_cfg(index, delay_on, delay_off, &blinking); -+ if (err < 0) -+ return err; - -- err = mt798x_phy_hw_led_blink_set(phydev, index, blinking); -+ err = mtk_phy_hw_led_blink_set(phydev, index, blinking); - if (err) - return err; - -- return mt798x_phy_hw_led_on_set(phydev, index, false); -+ return mtk_phy_hw_led_on_set(phydev, index, MTK_GPHY_LED_ON_MASK, -+ false); - } - - static int mt798x_phy_led_brightness_set(struct phy_device *phydev, -@@ -1249,11 +1155,12 @@ static int mt798x_phy_led_brightness_set(struct phy_device *phydev, - { - int err; - -- err = mt798x_phy_hw_led_blink_set(phydev, index, false); -+ err = mtk_phy_hw_led_blink_set(phydev, index, false); - if (err) - return err; - -- return mt798x_phy_hw_led_on_set(phydev, index, (value != LED_OFF)); -+ return mtk_phy_hw_led_on_set(phydev, index, MTK_GPHY_LED_ON_MASK, -+ (value != LED_OFF)); - } - - static const unsigned long supported_triggers = -@@ -1269,155 +1176,26 @@ static const unsigned long supported_triggers = - static int mt798x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index, - unsigned long rules) - { -- if (index > 1) -- return -EINVAL; -- -- /* All combinations of the supported triggers are allowed */ -- if (rules & ~supported_triggers) -- return -EOPNOTSUPP; -- -- return 0; --}; -+ return mtk_phy_led_hw_is_supported(phydev, index, rules, -+ supported_triggers); -+} - - static int mt798x_phy_led_hw_control_get(struct phy_device *phydev, u8 index, - unsigned long *rules) - { -- unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + -- (index ? 16 : 0); -- unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0); -- unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0); -- struct mtk_socphy_priv *priv = phydev->priv; -- int on, blink; -- -- if (index > 1) -- return -EINVAL; -- -- on = phy_read_mmd(phydev, MDIO_MMD_VEND2, -- index ? MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL); -- -- if (on < 0) -- return -EIO; -- -- blink = phy_read_mmd(phydev, MDIO_MMD_VEND2, -- index ? MTK_PHY_LED1_BLINK_CTRL : -- MTK_PHY_LED0_BLINK_CTRL); -- if (blink < 0) -- return -EIO; -- -- if ((on & (MTK_PHY_LED_ON_LINK | MTK_PHY_LED_ON_FDX | -- MTK_PHY_LED_ON_HDX | MTK_PHY_LED_ON_LINKDOWN)) || -- (blink & (MTK_PHY_LED_BLINK_RX | MTK_PHY_LED_BLINK_TX))) -- set_bit(bit_netdev, &priv->led_state); -- else -- clear_bit(bit_netdev, &priv->led_state); -- -- if (on & MTK_PHY_LED_ON_FORCE_ON) -- set_bit(bit_on, &priv->led_state); -- else -- clear_bit(bit_on, &priv->led_state); -- -- if (blink & MTK_PHY_LED_BLINK_FORCE_BLINK) -- set_bit(bit_blink, &priv->led_state); -- else -- clear_bit(bit_blink, &priv->led_state); -- -- if (!rules) -- return 0; -- -- if (on & MTK_PHY_LED_ON_LINK) -- *rules |= BIT(TRIGGER_NETDEV_LINK); -- -- if (on & MTK_PHY_LED_ON_LINK10) -- *rules |= BIT(TRIGGER_NETDEV_LINK_10); -- -- if (on & MTK_PHY_LED_ON_LINK100) -- *rules |= BIT(TRIGGER_NETDEV_LINK_100); -- -- if (on & MTK_PHY_LED_ON_LINK1000) -- *rules |= BIT(TRIGGER_NETDEV_LINK_1000); -- -- if (on & MTK_PHY_LED_ON_FDX) -- *rules |= BIT(TRIGGER_NETDEV_FULL_DUPLEX); -- -- if (on & MTK_PHY_LED_ON_HDX) -- *rules |= BIT(TRIGGER_NETDEV_HALF_DUPLEX); -- -- if (blink & MTK_PHY_LED_BLINK_RX) -- *rules |= BIT(TRIGGER_NETDEV_RX); -- -- if (blink & MTK_PHY_LED_BLINK_TX) -- *rules |= BIT(TRIGGER_NETDEV_TX); -- -- return 0; -+ return mtk_phy_led_hw_ctrl_get(phydev, index, rules, -+ MTK_GPHY_LED_ON_SET, -+ MTK_GPHY_LED_RX_BLINK_SET, -+ MTK_GPHY_LED_TX_BLINK_SET); - }; - - static int mt798x_phy_led_hw_control_set(struct phy_device *phydev, u8 index, - unsigned long rules) - { -- unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0); -- struct mtk_socphy_priv *priv = phydev->priv; -- u16 on = 0, blink = 0; -- int ret; -- -- if (index > 1) -- return -EINVAL; -- -- if (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX)) -- on |= MTK_PHY_LED_ON_FDX; -- -- if (rules & BIT(TRIGGER_NETDEV_HALF_DUPLEX)) -- on |= MTK_PHY_LED_ON_HDX; -- -- if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK))) -- on |= MTK_PHY_LED_ON_LINK10; -- -- if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK))) -- on |= MTK_PHY_LED_ON_LINK100; -- -- if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK))) -- on |= MTK_PHY_LED_ON_LINK1000; -- -- if (rules & BIT(TRIGGER_NETDEV_RX)) { -- blink |= (on & MTK_PHY_LED_ON_LINK) ? -- (((on & MTK_PHY_LED_ON_LINK10) ? -- MTK_PHY_LED_BLINK_10RX : 0) | -- ((on & MTK_PHY_LED_ON_LINK100) ? -- MTK_PHY_LED_BLINK_100RX : 0) | -- ((on & MTK_PHY_LED_ON_LINK1000) ? -- MTK_PHY_LED_BLINK_1000RX : 0)) : -- MTK_PHY_LED_BLINK_RX; -- } -- -- if (rules & BIT(TRIGGER_NETDEV_TX)) { -- blink |= (on & MTK_PHY_LED_ON_LINK) ? -- (((on & MTK_PHY_LED_ON_LINK10) ? -- MTK_PHY_LED_BLINK_10TX : 0) | -- ((on & MTK_PHY_LED_ON_LINK100) ? -- MTK_PHY_LED_BLINK_100TX : 0) | -- ((on & MTK_PHY_LED_ON_LINK1000) ? -- MTK_PHY_LED_BLINK_1000TX : 0)) : -- MTK_PHY_LED_BLINK_TX; -- } -- -- if (blink || on) -- set_bit(bit_netdev, &priv->led_state); -- else -- clear_bit(bit_netdev, &priv->led_state); -- -- ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ? -- MTK_PHY_LED1_ON_CTRL : -- MTK_PHY_LED0_ON_CTRL, -- MTK_PHY_LED_ON_FDX | -- MTK_PHY_LED_ON_HDX | -- MTK_PHY_LED_ON_LINK, -- on); -- -- if (ret) -- return ret; -- -- return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ? -- MTK_PHY_LED1_BLINK_CTRL : -- MTK_PHY_LED0_BLINK_CTRL, blink); -+ return mtk_phy_led_hw_ctrl_set(phydev, index, rules, -+ MTK_GPHY_LED_ON_SET, -+ MTK_GPHY_LED_RX_BLINK_SET, -+ MTK_GPHY_LED_TX_BLINK_SET); - }; - - static bool mt7988_phy_led_get_polarity(struct phy_device *phydev, int led_num) -@@ -1492,14 +1270,6 @@ static int mt7988_phy_probe_shared(struct phy_device *phydev) - return 0; - } - --static void mt798x_phy_leds_state_init(struct phy_device *phydev) --{ -- int i; -- -- for (i = 0; i < 2; ++i) -- mt798x_phy_led_hw_control_get(phydev, i, NULL); --} -- - static int mt7988_phy_probe(struct phy_device *phydev) - { - struct mtk_socphy_shared *shared; -@@ -1525,7 +1295,7 @@ static int mt7988_phy_probe(struct phy_device *phydev) - - phydev->priv = priv; - -- mt798x_phy_leds_state_init(phydev); -+ mtk_phy_leds_state_init(phydev); - - err = mt7988_phy_fix_leds_polarities(phydev); - if (err) -@@ -1552,7 +1322,7 @@ static int mt7981_phy_probe(struct phy_device *phydev) - - phydev->priv = priv; - -- mt798x_phy_leds_state_init(phydev); -+ mtk_phy_leds_state_init(phydev); - - return mt798x_phy_calibration(phydev); - } -diff --git a/drivers/net/phy/mediatek/mtk-phy-lib.c b/drivers/net/phy/mediatek/mtk-phy-lib.c -new file mode 100644 -index 000000000000..34b0957b201b ---- /dev/null -+++ b/drivers/net/phy/mediatek/mtk-phy-lib.c -@@ -0,0 +1,254 @@ -+// SPDX-License-Identifier: GPL-2.0 -+#include -+#include -+ -+#include -+ -+#include "mtk.h" -+ -+int mtk_phy_led_hw_is_supported(struct phy_device *phydev, u8 index, -+ unsigned long rules, -+ unsigned long supported_triggers) -+{ -+ if (index > 1) -+ return -EINVAL; -+ -+ /* All combinations of the supported triggers are allowed */ -+ if (rules & ~supported_triggers) -+ return -EOPNOTSUPP; -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(mtk_phy_led_hw_is_supported); -+ -+int mtk_phy_led_hw_ctrl_get(struct phy_device *phydev, u8 index, -+ unsigned long *rules, u16 on_set, -+ u16 rx_blink_set, u16 tx_blink_set) -+{ -+ unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + -+ (index ? 16 : 0); -+ unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0); -+ unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0); -+ struct mtk_socphy_priv *priv = phydev->priv; -+ int on, blink; -+ -+ if (index > 1) -+ return -EINVAL; -+ -+ on = phy_read_mmd(phydev, MDIO_MMD_VEND2, -+ index ? MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL); -+ -+ if (on < 0) -+ return -EIO; -+ -+ blink = phy_read_mmd(phydev, MDIO_MMD_VEND2, -+ index ? MTK_PHY_LED1_BLINK_CTRL : -+ MTK_PHY_LED0_BLINK_CTRL); -+ if (blink < 0) -+ return -EIO; -+ -+ if ((on & (on_set | MTK_PHY_LED_ON_FDX | -+ MTK_PHY_LED_ON_HDX | MTK_PHY_LED_ON_LINKDOWN)) || -+ (blink & (rx_blink_set | tx_blink_set))) -+ set_bit(bit_netdev, &priv->led_state); -+ else -+ clear_bit(bit_netdev, &priv->led_state); -+ -+ if (on & MTK_PHY_LED_ON_FORCE_ON) -+ set_bit(bit_on, &priv->led_state); -+ else -+ clear_bit(bit_on, &priv->led_state); -+ -+ if (blink & MTK_PHY_LED_BLINK_FORCE_BLINK) -+ set_bit(bit_blink, &priv->led_state); -+ else -+ clear_bit(bit_blink, &priv->led_state); -+ -+ if (!rules) -+ return 0; -+ -+ if (on & on_set) -+ *rules |= BIT(TRIGGER_NETDEV_LINK); -+ -+ if (on & MTK_PHY_LED_ON_LINK10) -+ *rules |= BIT(TRIGGER_NETDEV_LINK_10); -+ -+ if (on & MTK_PHY_LED_ON_LINK100) -+ *rules |= BIT(TRIGGER_NETDEV_LINK_100); -+ -+ if (on & MTK_PHY_LED_ON_LINK1000) -+ *rules |= BIT(TRIGGER_NETDEV_LINK_1000); -+ -+ if (on & MTK_PHY_LED_ON_LINK2500) -+ *rules |= BIT(TRIGGER_NETDEV_LINK_2500); -+ -+ if (on & MTK_PHY_LED_ON_FDX) -+ *rules |= BIT(TRIGGER_NETDEV_FULL_DUPLEX); -+ -+ if (on & MTK_PHY_LED_ON_HDX) -+ *rules |= BIT(TRIGGER_NETDEV_HALF_DUPLEX); -+ -+ if (blink & rx_blink_set) -+ *rules |= BIT(TRIGGER_NETDEV_RX); -+ -+ if (blink & tx_blink_set) -+ *rules |= BIT(TRIGGER_NETDEV_TX); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(mtk_phy_led_hw_ctrl_get); -+ -+int mtk_phy_led_hw_ctrl_set(struct phy_device *phydev, u8 index, -+ unsigned long rules, u16 on_set, -+ u16 rx_blink_set, u16 tx_blink_set) -+{ -+ unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0); -+ struct mtk_socphy_priv *priv = phydev->priv; -+ u16 on = 0, blink = 0; -+ int ret; -+ -+ if (index > 1) -+ return -EINVAL; -+ -+ if (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX)) -+ on |= MTK_PHY_LED_ON_FDX; -+ -+ if (rules & BIT(TRIGGER_NETDEV_HALF_DUPLEX)) -+ on |= MTK_PHY_LED_ON_HDX; -+ -+ if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK))) -+ on |= MTK_PHY_LED_ON_LINK10; -+ -+ if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK))) -+ on |= MTK_PHY_LED_ON_LINK100; -+ -+ if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK))) -+ on |= MTK_PHY_LED_ON_LINK1000; -+ -+ if (rules & (BIT(TRIGGER_NETDEV_LINK_2500) | BIT(TRIGGER_NETDEV_LINK))) -+ on |= MTK_PHY_LED_ON_LINK2500; -+ -+ if (rules & BIT(TRIGGER_NETDEV_RX)) { -+ blink |= (on & on_set) ? -+ (((on & MTK_PHY_LED_ON_LINK10) ? -+ MTK_PHY_LED_BLINK_10RX : 0) | -+ ((on & MTK_PHY_LED_ON_LINK100) ? -+ MTK_PHY_LED_BLINK_100RX : 0) | -+ ((on & MTK_PHY_LED_ON_LINK1000) ? -+ MTK_PHY_LED_BLINK_1000RX : 0) | -+ ((on & MTK_PHY_LED_ON_LINK2500) ? -+ MTK_PHY_LED_BLINK_2500RX : 0)) : -+ rx_blink_set; -+ } -+ -+ if (rules & BIT(TRIGGER_NETDEV_TX)) { -+ blink |= (on & on_set) ? -+ (((on & MTK_PHY_LED_ON_LINK10) ? -+ MTK_PHY_LED_BLINK_10TX : 0) | -+ ((on & MTK_PHY_LED_ON_LINK100) ? -+ MTK_PHY_LED_BLINK_100TX : 0) | -+ ((on & MTK_PHY_LED_ON_LINK1000) ? -+ MTK_PHY_LED_BLINK_1000TX : 0) | -+ ((on & MTK_PHY_LED_ON_LINK2500) ? -+ MTK_PHY_LED_BLINK_2500TX : 0)) : -+ tx_blink_set; -+ } -+ -+ if (blink || on) -+ set_bit(bit_netdev, &priv->led_state); -+ else -+ clear_bit(bit_netdev, &priv->led_state); -+ -+ ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ? -+ MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL, -+ MTK_PHY_LED_ON_FDX | MTK_PHY_LED_ON_HDX | on_set, -+ on); -+ -+ if (ret) -+ return ret; -+ -+ return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ? -+ MTK_PHY_LED1_BLINK_CTRL : -+ MTK_PHY_LED0_BLINK_CTRL, blink); -+} -+EXPORT_SYMBOL_GPL(mtk_phy_led_hw_ctrl_set); -+ -+int mtk_phy_led_num_dly_cfg(u8 index, unsigned long *delay_on, -+ unsigned long *delay_off, bool *blinking) -+{ -+ if (index > 1) -+ return -EINVAL; -+ -+ if (delay_on && delay_off && (*delay_on > 0) && (*delay_off > 0)) { -+ *blinking = true; -+ *delay_on = 50; -+ *delay_off = 50; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(mtk_phy_led_num_dly_cfg); -+ -+int mtk_phy_hw_led_on_set(struct phy_device *phydev, u8 index, -+ u16 led_on_mask, bool on) -+{ -+ unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0); -+ struct mtk_socphy_priv *priv = phydev->priv; -+ bool changed; -+ -+ if (on) -+ changed = !test_and_set_bit(bit_on, &priv->led_state); -+ else -+ changed = !!test_and_clear_bit(bit_on, &priv->led_state); -+ -+ changed |= !!test_and_clear_bit(MTK_PHY_LED_STATE_NETDEV + -+ (index ? 16 : 0), &priv->led_state); -+ if (changed) -+ return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ? -+ MTK_PHY_LED1_ON_CTRL : -+ MTK_PHY_LED0_ON_CTRL, -+ led_on_mask, -+ on ? MTK_PHY_LED_ON_FORCE_ON : 0); -+ else -+ return 0; -+} -+EXPORT_SYMBOL_GPL(mtk_phy_hw_led_on_set); -+ -+int mtk_phy_hw_led_blink_set(struct phy_device *phydev, u8 index, bool blinking) -+{ -+ unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + -+ (index ? 16 : 0); -+ struct mtk_socphy_priv *priv = phydev->priv; -+ bool changed; -+ -+ if (blinking) -+ changed = !test_and_set_bit(bit_blink, &priv->led_state); -+ else -+ changed = !!test_and_clear_bit(bit_blink, &priv->led_state); -+ -+ changed |= !!test_bit(MTK_PHY_LED_STATE_NETDEV + -+ (index ? 16 : 0), &priv->led_state); -+ if (changed) -+ return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ? -+ MTK_PHY_LED1_BLINK_CTRL : -+ MTK_PHY_LED0_BLINK_CTRL, -+ blinking ? -+ MTK_PHY_LED_BLINK_FORCE_BLINK : 0); -+ else -+ return 0; -+} -+EXPORT_SYMBOL_GPL(mtk_phy_hw_led_blink_set); -+ -+void mtk_phy_leds_state_init(struct phy_device *phydev) -+{ -+ int i; -+ -+ for (i = 0; i < 2; ++i) -+ phydev->drv->led_hw_control_get(phydev, i, NULL); -+} -+EXPORT_SYMBOL_GPL(mtk_phy_leds_state_init); -+ -+MODULE_DESCRIPTION("MediaTek Ethernet PHY driver common"); -+MODULE_AUTHOR("Sky Huang "); -+MODULE_AUTHOR("Daniel Golle "); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/net/phy/mediatek/mtk.h b/drivers/net/phy/mediatek/mtk.h -new file mode 100644 -index 000000000000..9aaff2c2270d ---- /dev/null -+++ b/drivers/net/phy/mediatek/mtk.h -@@ -0,0 +1,86 @@ -+/* SPDX-License-Identifier: GPL-2.0 -+ * -+ * Common definition for Mediatek Ethernet PHYs -+ * Author: SkyLake Huang -+ * Copyright (c) 2024 MediaTek Inc. -+ */ -+ -+#ifndef _MTK_EPHY_H_ -+#define _MTK_EPHY_H_ -+ -+#define MTK_EXT_PAGE_ACCESS 0x1f -+ -+/* Registers on MDIO_MMD_VEND2 */ -+#define MTK_PHY_LED0_ON_CTRL 0x24 -+#define MTK_PHY_LED1_ON_CTRL 0x26 -+#define MTK_GPHY_LED_ON_MASK GENMASK(6, 0) -+#define MTK_2P5GPHY_LED_ON_MASK GENMASK(7, 0) -+#define MTK_PHY_LED_ON_LINK1000 BIT(0) -+#define MTK_PHY_LED_ON_LINK100 BIT(1) -+#define MTK_PHY_LED_ON_LINK10 BIT(2) -+#define MTK_PHY_LED_ON_LINKDOWN BIT(3) -+#define MTK_PHY_LED_ON_FDX BIT(4) /* Full duplex */ -+#define MTK_PHY_LED_ON_HDX BIT(5) /* Half duplex */ -+#define MTK_PHY_LED_ON_FORCE_ON BIT(6) -+#define MTK_PHY_LED_ON_LINK2500 BIT(7) -+#define MTK_PHY_LED_ON_POLARITY BIT(14) -+#define MTK_PHY_LED_ON_ENABLE BIT(15) -+ -+#define MTK_PHY_LED0_BLINK_CTRL 0x25 -+#define MTK_PHY_LED1_BLINK_CTRL 0x27 -+#define MTK_PHY_LED_BLINK_1000TX BIT(0) -+#define MTK_PHY_LED_BLINK_1000RX BIT(1) -+#define MTK_PHY_LED_BLINK_100TX BIT(2) -+#define MTK_PHY_LED_BLINK_100RX BIT(3) -+#define MTK_PHY_LED_BLINK_10TX BIT(4) -+#define MTK_PHY_LED_BLINK_10RX BIT(5) -+#define MTK_PHY_LED_BLINK_COLLISION BIT(6) -+#define MTK_PHY_LED_BLINK_RX_CRC_ERR BIT(7) -+#define MTK_PHY_LED_BLINK_RX_IDLE_ERR BIT(8) -+#define MTK_PHY_LED_BLINK_FORCE_BLINK BIT(9) -+#define MTK_PHY_LED_BLINK_2500TX BIT(10) -+#define MTK_PHY_LED_BLINK_2500RX BIT(11) -+ -+#define MTK_GPHY_LED_ON_SET (MTK_PHY_LED_ON_LINK1000 | \ -+ MTK_PHY_LED_ON_LINK100 | \ -+ MTK_PHY_LED_ON_LINK10) -+#define MTK_GPHY_LED_RX_BLINK_SET (MTK_PHY_LED_BLINK_1000RX | \ -+ MTK_PHY_LED_BLINK_100RX | \ -+ MTK_PHY_LED_BLINK_10RX) -+#define MTK_GPHY_LED_TX_BLINK_SET (MTK_PHY_LED_BLINK_1000RX | \ -+ MTK_PHY_LED_BLINK_100RX | \ -+ MTK_PHY_LED_BLINK_10RX) -+ -+#define MTK_2P5GPHY_LED_ON_SET (MTK_PHY_LED_ON_LINK2500 | \ -+ MTK_GPHY_LED_ON_SET) -+#define MTK_2P5GPHY_LED_RX_BLINK_SET (MTK_PHY_LED_BLINK_2500RX | \ -+ MTK_GPHY_LED_RX_BLINK_SET) -+#define MTK_2P5GPHY_LED_TX_BLINK_SET (MTK_PHY_LED_BLINK_2500RX | \ -+ MTK_GPHY_LED_TX_BLINK_SET) -+ -+#define MTK_PHY_LED_STATE_FORCE_ON 0 -+#define MTK_PHY_LED_STATE_FORCE_BLINK 1 -+#define MTK_PHY_LED_STATE_NETDEV 2 -+ -+struct mtk_socphy_priv { -+ unsigned long led_state; -+}; -+ -+int mtk_phy_led_hw_is_supported(struct phy_device *phydev, u8 index, -+ unsigned long rules, -+ unsigned long supported_triggers); -+int mtk_phy_led_hw_ctrl_set(struct phy_device *phydev, u8 index, -+ unsigned long rules, u16 on_set, -+ u16 rx_blink_set, u16 tx_blink_set); -+int mtk_phy_led_hw_ctrl_get(struct phy_device *phydev, u8 index, -+ unsigned long *rules, u16 on_set, -+ u16 rx_blink_set, u16 tx_blink_set); -+int mtk_phy_led_num_dly_cfg(u8 index, unsigned long *delay_on, -+ unsigned long *delay_off, bool *blinking); -+int mtk_phy_hw_led_on_set(struct phy_device *phydev, u8 index, -+ u16 led_on_mask, bool on); -+int mtk_phy_hw_led_blink_set(struct phy_device *phydev, u8 index, -+ bool blinking); -+void mtk_phy_leds_state_init(struct phy_device *phydev); -+ -+#endif /* _MTK_EPHY_H_ */ --- -2.51.0 - - -From 6dc997fe3e72a302032cfcc171a4a7ee5f4faf5c Mon Sep 17 00:00:00 2001 -From: "SkyLake.Huang" -Date: Sat, 9 Nov 2024 00:34:53 +0800 -Subject: [PATCH 072/517] net: phy: mediatek: Improve readability of - mtk-phy-lib.c's mtk_phy_led_hw_ctrl_set() - -This patch removes parens around TRIGGER_NETDEV_RX/TRIGGER_NETDEV_TX in -mtk_phy_led_hw_ctrl_set(), which improves readability. - -Reviewed-by: Andrew Lunn -Signed-off-by: SkyLake.Huang -Signed-off-by: David S. Miller ---- - drivers/net/phy/mediatek/mtk-phy-lib.c | 44 ++++++++++++++------------ - 1 file changed, 24 insertions(+), 20 deletions(-) - -diff --git a/drivers/net/phy/mediatek/mtk-phy-lib.c b/drivers/net/phy/mediatek/mtk-phy-lib.c -index 34b0957b201b..8d795bcc8b2d 100644 ---- a/drivers/net/phy/mediatek/mtk-phy-lib.c -+++ b/drivers/net/phy/mediatek/mtk-phy-lib.c -@@ -129,29 +129,33 @@ int mtk_phy_led_hw_ctrl_set(struct phy_device *phydev, u8 index, - on |= MTK_PHY_LED_ON_LINK2500; - - if (rules & BIT(TRIGGER_NETDEV_RX)) { -- blink |= (on & on_set) ? -- (((on & MTK_PHY_LED_ON_LINK10) ? -- MTK_PHY_LED_BLINK_10RX : 0) | -- ((on & MTK_PHY_LED_ON_LINK100) ? -- MTK_PHY_LED_BLINK_100RX : 0) | -- ((on & MTK_PHY_LED_ON_LINK1000) ? -- MTK_PHY_LED_BLINK_1000RX : 0) | -- ((on & MTK_PHY_LED_ON_LINK2500) ? -- MTK_PHY_LED_BLINK_2500RX : 0)) : -- rx_blink_set; -+ if (on & on_set) { -+ if (on & MTK_PHY_LED_ON_LINK10) -+ blink |= MTK_PHY_LED_BLINK_10RX; -+ if (on & MTK_PHY_LED_ON_LINK100) -+ blink |= MTK_PHY_LED_BLINK_100RX; -+ if (on & MTK_PHY_LED_ON_LINK1000) -+ blink |= MTK_PHY_LED_BLINK_1000RX; -+ if (on & MTK_PHY_LED_ON_LINK2500) -+ blink |= MTK_PHY_LED_BLINK_2500RX; -+ } else { -+ blink |= rx_blink_set; -+ } - } - - if (rules & BIT(TRIGGER_NETDEV_TX)) { -- blink |= (on & on_set) ? -- (((on & MTK_PHY_LED_ON_LINK10) ? -- MTK_PHY_LED_BLINK_10TX : 0) | -- ((on & MTK_PHY_LED_ON_LINK100) ? -- MTK_PHY_LED_BLINK_100TX : 0) | -- ((on & MTK_PHY_LED_ON_LINK1000) ? -- MTK_PHY_LED_BLINK_1000TX : 0) | -- ((on & MTK_PHY_LED_ON_LINK2500) ? -- MTK_PHY_LED_BLINK_2500TX : 0)) : -- tx_blink_set; -+ if (on & on_set) { -+ if (on & MTK_PHY_LED_ON_LINK10) -+ blink |= MTK_PHY_LED_BLINK_10TX; -+ if (on & MTK_PHY_LED_ON_LINK100) -+ blink |= MTK_PHY_LED_BLINK_100TX; -+ if (on & MTK_PHY_LED_ON_LINK1000) -+ blink |= MTK_PHY_LED_BLINK_1000TX; -+ if (on & MTK_PHY_LED_ON_LINK2500) -+ blink |= MTK_PHY_LED_BLINK_2500TX; -+ } else { -+ blink |= tx_blink_set; -+ } - } - - if (blink || on) --- -2.51.0 - - -From 2d3dc5ebaa6a3858e2132c14bbf9245f26979f40 Mon Sep 17 00:00:00 2001 -From: "SkyLake.Huang" -Date: Sat, 9 Nov 2024 00:34:54 +0800 -Subject: [PATCH 073/517] net: phy: mediatek: Integrate read/write page helper - functions - -This patch integrates read/write page helper functions as MTK phy lib. -They are basically the same in mtk-ge.c & mtk-ge-soc.c. - -Signed-off-by: SkyLake.Huang -Signed-off-by: David S. Miller ---- - drivers/net/phy/mediatek/Kconfig | 1 + - drivers/net/phy/mediatek/mtk-ge-soc.c | 18 ++++-------------- - drivers/net/phy/mediatek/mtk-ge.c | 20 ++++++-------------- - drivers/net/phy/mediatek/mtk-phy-lib.c | 12 ++++++++++++ - drivers/net/phy/mediatek/mtk.h | 3 +++ - 5 files changed, 26 insertions(+), 28 deletions(-) - -diff --git a/drivers/net/phy/mediatek/Kconfig b/drivers/net/phy/mediatek/Kconfig -index 19b5d23e7cd0..2a8ac5aed0f8 100644 ---- a/drivers/net/phy/mediatek/Kconfig -+++ b/drivers/net/phy/mediatek/Kconfig -@@ -4,6 +4,7 @@ config MTK_NET_PHYLIB - - config MEDIATEK_GE_PHY - tristate "MediaTek Gigabit Ethernet PHYs" -+ select MTK_NET_PHYLIB - help - Supports the MediaTek non-built-in Gigabit Ethernet PHYs. - -diff --git a/drivers/net/phy/mediatek/mtk-ge-soc.c b/drivers/net/phy/mediatek/mtk-ge-soc.c -index d3a8b3946056..38dc898eaf7b 100644 ---- a/drivers/net/phy/mediatek/mtk-ge-soc.c -+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c -@@ -271,16 +271,6 @@ struct mtk_socphy_shared { - struct mtk_socphy_priv priv[4]; - }; - --static int mtk_socphy_read_page(struct phy_device *phydev) --{ -- return __phy_read(phydev, MTK_EXT_PAGE_ACCESS); --} -- --static int mtk_socphy_write_page(struct phy_device *phydev, int page) --{ -- return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page); --} -- - /* One calibration cycle consists of: - * 1.Set DA_CALIN_FLAG high to start calibration. Keep it high - * until AD_CAL_COMP is ready to output calibration result. -@@ -1337,8 +1327,8 @@ static struct phy_driver mtk_socphy_driver[] = { - .probe = mt7981_phy_probe, - .suspend = genphy_suspend, - .resume = genphy_resume, -- .read_page = mtk_socphy_read_page, -- .write_page = mtk_socphy_write_page, -+ .read_page = mtk_phy_read_page, -+ .write_page = mtk_phy_write_page, - .led_blink_set = mt798x_phy_led_blink_set, - .led_brightness_set = mt798x_phy_led_brightness_set, - .led_hw_is_supported = mt798x_phy_led_hw_is_supported, -@@ -1354,8 +1344,8 @@ static struct phy_driver mtk_socphy_driver[] = { - .probe = mt7988_phy_probe, - .suspend = genphy_suspend, - .resume = genphy_resume, -- .read_page = mtk_socphy_read_page, -- .write_page = mtk_socphy_write_page, -+ .read_page = mtk_phy_read_page, -+ .write_page = mtk_phy_write_page, - .led_blink_set = mt798x_phy_led_blink_set, - .led_brightness_set = mt798x_phy_led_brightness_set, - .led_hw_is_supported = mt798x_phy_led_hw_is_supported, -diff --git a/drivers/net/phy/mediatek/mtk-ge.c b/drivers/net/phy/mediatek/mtk-ge.c -index 54ea64a37ab3..912289928fb3 100644 ---- a/drivers/net/phy/mediatek/mtk-ge.c -+++ b/drivers/net/phy/mediatek/mtk-ge.c -@@ -3,6 +3,8 @@ - #include - #include - -+#include "mtk.h" -+ - #define MTK_EXT_PAGE_ACCESS 0x1f - #define MTK_PHY_PAGE_STANDARD 0x0000 - #define MTK_PHY_PAGE_EXTENDED 0x0001 -@@ -11,16 +13,6 @@ - #define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30 - #define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5 - --static int mtk_gephy_read_page(struct phy_device *phydev) --{ -- return __phy_read(phydev, MTK_EXT_PAGE_ACCESS); --} -- --static int mtk_gephy_write_page(struct phy_device *phydev, int page) --{ -- return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page); --} -- - static void mtk_gephy_config_init(struct phy_device *phydev) - { - /* Enable HW auto downshift */ -@@ -77,8 +69,8 @@ static struct phy_driver mtk_gephy_driver[] = { - .handle_interrupt = genphy_handle_interrupt_no_ack, - .suspend = genphy_suspend, - .resume = genphy_resume, -- .read_page = mtk_gephy_read_page, -- .write_page = mtk_gephy_write_page, -+ .read_page = mtk_phy_read_page, -+ .write_page = mtk_phy_write_page, - }, - { - PHY_ID_MATCH_EXACT(0x03a29441), -@@ -91,8 +83,8 @@ static struct phy_driver mtk_gephy_driver[] = { - .handle_interrupt = genphy_handle_interrupt_no_ack, - .suspend = genphy_suspend, - .resume = genphy_resume, -- .read_page = mtk_gephy_read_page, -- .write_page = mtk_gephy_write_page, -+ .read_page = mtk_phy_read_page, -+ .write_page = mtk_phy_write_page, - }, - }; - -diff --git a/drivers/net/phy/mediatek/mtk-phy-lib.c b/drivers/net/phy/mediatek/mtk-phy-lib.c -index 8d795bcc8b2d..98a09d670e9c 100644 ---- a/drivers/net/phy/mediatek/mtk-phy-lib.c -+++ b/drivers/net/phy/mediatek/mtk-phy-lib.c -@@ -6,6 +6,18 @@ - - #include "mtk.h" - -+int mtk_phy_read_page(struct phy_device *phydev) -+{ -+ return __phy_read(phydev, MTK_EXT_PAGE_ACCESS); -+} -+EXPORT_SYMBOL_GPL(mtk_phy_read_page); -+ -+int mtk_phy_write_page(struct phy_device *phydev, int page) -+{ -+ return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page); -+} -+EXPORT_SYMBOL_GPL(mtk_phy_write_page); -+ - int mtk_phy_led_hw_is_supported(struct phy_device *phydev, u8 index, - unsigned long rules, - unsigned long supported_triggers) -diff --git a/drivers/net/phy/mediatek/mtk.h b/drivers/net/phy/mediatek/mtk.h -index 9aaff2c2270d..63d9fe179b8f 100644 ---- a/drivers/net/phy/mediatek/mtk.h -+++ b/drivers/net/phy/mediatek/mtk.h -@@ -66,6 +66,9 @@ struct mtk_socphy_priv { - unsigned long led_state; - }; - -+int mtk_phy_read_page(struct phy_device *phydev); -+int mtk_phy_write_page(struct phy_device *phydev, int page); -+ - int mtk_phy_led_hw_is_supported(struct phy_device *phydev, u8 index, - unsigned long rules, - unsigned long supported_triggers); --- -2.51.0 - - -From c856cf37c2c09bc633f445f7b106868ecbecf773 Mon Sep 17 00:00:00 2001 -From: "SkyLake.Huang" -Date: Sat, 9 Nov 2024 00:34:55 +0800 -Subject: [PATCH 074/517] net: phy: mediatek: add MT7530 & MT7531's PHY ID - macros - -This patch adds MT7530 & MT7531's PHY ID macros in mtk-ge.c so that -it follows the same rule of mtk-ge-soc.c. - -Reviewed-by: Andrew Lunn -Signed-off-by: SkyLake.Huang -Signed-off-by: David S. Miller ---- - drivers/net/phy/mediatek/mtk-ge.c | 11 +++++++---- - 1 file changed, 7 insertions(+), 4 deletions(-) - -diff --git a/drivers/net/phy/mediatek/mtk-ge.c b/drivers/net/phy/mediatek/mtk-ge.c -index 912289928fb3..ed2617bc20f4 100644 ---- a/drivers/net/phy/mediatek/mtk-ge.c -+++ b/drivers/net/phy/mediatek/mtk-ge.c -@@ -5,6 +5,9 @@ - - #include "mtk.h" - -+#define MTK_GPHY_ID_MT7530 0x03a29412 -+#define MTK_GPHY_ID_MT7531 0x03a29441 -+ - #define MTK_EXT_PAGE_ACCESS 0x1f - #define MTK_PHY_PAGE_STANDARD 0x0000 - #define MTK_PHY_PAGE_EXTENDED 0x0001 -@@ -59,7 +62,7 @@ static int mt7531_phy_config_init(struct phy_device *phydev) - - static struct phy_driver mtk_gephy_driver[] = { - { -- PHY_ID_MATCH_EXACT(0x03a29412), -+ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7530), - .name = "MediaTek MT7530 PHY", - .config_init = mt7530_phy_config_init, - /* Interrupts are handled by the switch, not the PHY -@@ -73,7 +76,7 @@ static struct phy_driver mtk_gephy_driver[] = { - .write_page = mtk_phy_write_page, - }, - { -- PHY_ID_MATCH_EXACT(0x03a29441), -+ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7531), - .name = "MediaTek MT7531 PHY", - .config_init = mt7531_phy_config_init, - /* Interrupts are handled by the switch, not the PHY -@@ -91,8 +94,8 @@ static struct phy_driver mtk_gephy_driver[] = { - module_phy_driver(mtk_gephy_driver); - - static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = { -- { PHY_ID_MATCH_EXACT(0x03a29441) }, -- { PHY_ID_MATCH_EXACT(0x03a29412) }, -+ { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7530) }, -+ { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7531) }, - { } - }; - --- -2.51.0 - - -From 7a3462a3d00deab364b02b53bb9dd57e767b0a38 Mon Sep 17 00:00:00 2001 -From: Christophe JAILLET -Date: Sun, 12 Jan 2025 15:14:50 +0100 -Subject: [PATCH 075/517] net: phy: Constify struct mdio_device_id - -'struct mdio_device_id' is not modified in these drivers. - -Constifying these structures moves some data to a read-only section, so -increase overall security. - -On a x86_64, with allmodconfig, as an example: -Before: -====== - text data bss dec hex filename - 27014 12792 0 39806 9b7e drivers/net/phy/broadcom.o - -After: -===== - text data bss dec hex filename - 27206 12600 0 39806 9b7e drivers/net/phy/broadcom.o - -Signed-off-by: Christophe JAILLET -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/403c381b7d9156b67ad68ffc44b8eee70c5e86a9.1736691226.git.christophe.jaillet@wanadoo.fr -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/adin.c | 2 +- - drivers/net/phy/adin1100.c | 2 +- - drivers/net/phy/air_en8811h.c | 2 +- - drivers/net/phy/amd.c | 2 +- - drivers/net/phy/aquantia/aquantia_main.c | 2 +- - drivers/net/phy/ax88796b.c | 2 +- - drivers/net/phy/bcm-cygnus.c | 2 +- - drivers/net/phy/bcm54140.c | 2 +- - drivers/net/phy/bcm63xx.c | 2 +- - drivers/net/phy/bcm7xxx.c | 2 +- - drivers/net/phy/bcm84881.c | 2 +- - drivers/net/phy/broadcom.c | 2 +- - drivers/net/phy/cicada.c | 2 +- - drivers/net/phy/cortina.c | 2 +- - drivers/net/phy/davicom.c | 2 +- - drivers/net/phy/dp83640.c | 2 +- - drivers/net/phy/dp83822.c | 2 +- - drivers/net/phy/dp83848.c | 2 +- - drivers/net/phy/dp83867.c | 2 +- - drivers/net/phy/dp83869.c | 2 +- - drivers/net/phy/dp83tc811.c | 2 +- - drivers/net/phy/dp83td510.c | 2 +- - drivers/net/phy/dp83tg720.c | 2 +- - drivers/net/phy/et1011c.c | 2 +- - drivers/net/phy/icplus.c | 2 +- - drivers/net/phy/intel-xway.c | 2 +- - drivers/net/phy/lxt.c | 2 +- - drivers/net/phy/marvell-88q2xxx.c | 2 +- - drivers/net/phy/marvell-88x2222.c | 2 +- - drivers/net/phy/marvell.c | 2 +- - drivers/net/phy/marvell10g.c | 2 +- - drivers/net/phy/mediatek/mtk-ge-soc.c | 2 +- - drivers/net/phy/mediatek/mtk-ge.c | 2 +- - drivers/net/phy/meson-gxl.c | 2 +- - drivers/net/phy/micrel.c | 2 +- - drivers/net/phy/microchip.c | 2 +- - drivers/net/phy/microchip_t1.c | 2 +- - drivers/net/phy/microchip_t1s.c | 2 +- - drivers/net/phy/mscc/mscc_main.c | 2 +- - drivers/net/phy/mxl-gpy.c | 2 +- - drivers/net/phy/national.c | 2 +- - drivers/net/phy/ncn26000.c | 2 +- - drivers/net/phy/nxp-c45-tja11xx.c | 2 +- - drivers/net/phy/nxp-cbtx.c | 2 +- - drivers/net/phy/nxp-tja11xx.c | 2 +- - drivers/net/phy/qcom/at803x.c | 2 +- - drivers/net/phy/qcom/qca807x.c | 2 +- - drivers/net/phy/qcom/qca808x.c | 2 +- - drivers/net/phy/qcom/qca83xx.c | 2 +- - drivers/net/phy/qsemi.c | 2 +- - drivers/net/phy/rockchip.c | 2 +- - drivers/net/phy/smsc.c | 2 +- - drivers/net/phy/ste10Xp.c | 2 +- - drivers/net/phy/teranetics.c | 2 +- - drivers/net/phy/uPD60620.c | 2 +- - drivers/net/phy/vitesse.c | 2 +- - 56 files changed, 56 insertions(+), 56 deletions(-) - -diff --git a/drivers/net/phy/adin.c b/drivers/net/phy/adin.c -index 2e1a46e121d9..fcd5eecbbf77 100644 ---- a/drivers/net/phy/adin.c -+++ b/drivers/net/phy/adin.c -@@ -1040,7 +1040,7 @@ static struct phy_driver adin_driver[] = { - - module_phy_driver(adin_driver); - --static struct mdio_device_id __maybe_unused adin_tbl[] = { -+static const struct mdio_device_id __maybe_unused adin_tbl[] = { - { PHY_ID_MATCH_MODEL(PHY_ID_ADIN1200) }, - { PHY_ID_MATCH_MODEL(PHY_ID_ADIN1300) }, - { } -diff --git a/drivers/net/phy/adin1100.c b/drivers/net/phy/adin1100.c -index 85f910e2d4fb..6bb469429b9d 100644 ---- a/drivers/net/phy/adin1100.c -+++ b/drivers/net/phy/adin1100.c -@@ -340,7 +340,7 @@ static struct phy_driver adin_driver[] = { - - module_phy_driver(adin_driver); - --static struct mdio_device_id __maybe_unused adin_tbl[] = { -+static const struct mdio_device_id __maybe_unused adin_tbl[] = { - { PHY_ID_MATCH_MODEL(PHY_ID_ADIN1100) }, - { PHY_ID_MATCH_MODEL(PHY_ID_ADIN1110) }, - { PHY_ID_MATCH_MODEL(PHY_ID_ADIN2111) }, -diff --git a/drivers/net/phy/air_en8811h.c b/drivers/net/phy/air_en8811h.c -index 8d076b9609fd..e9fd24cb7270 100644 ---- a/drivers/net/phy/air_en8811h.c -+++ b/drivers/net/phy/air_en8811h.c -@@ -1075,7 +1075,7 @@ static struct phy_driver en8811h_driver[] = { - - module_phy_driver(en8811h_driver); - --static struct mdio_device_id __maybe_unused en8811h_tbl[] = { -+static const struct mdio_device_id __maybe_unused en8811h_tbl[] = { - { PHY_ID_MATCH_MODEL(EN8811H_PHY_ID) }, - { } - }; -diff --git a/drivers/net/phy/amd.c b/drivers/net/phy/amd.c -index 930b15fa6ce9..75b5fe65500a 100644 ---- a/drivers/net/phy/amd.c -+++ b/drivers/net/phy/amd.c -@@ -111,7 +111,7 @@ static struct phy_driver am79c_drivers[] = { - - module_phy_driver(am79c_drivers); - --static struct mdio_device_id __maybe_unused amd_tbl[] = { -+static const struct mdio_device_id __maybe_unused amd_tbl[] = { - { PHY_ID_AC101L, 0xfffffff0 }, - { PHY_ID_AM79C874, 0xfffffff0 }, - { } -diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c -index c33a5ef34ba0..840ef5ad07ff 100644 ---- a/drivers/net/phy/aquantia/aquantia_main.c -+++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -1096,7 +1096,7 @@ static struct phy_driver aqr_driver[] = { - - module_phy_driver(aqr_driver); - --static struct mdio_device_id __maybe_unused aqr_tbl[] = { -+static const struct mdio_device_id __maybe_unused aqr_tbl[] = { - { PHY_ID_MATCH_MODEL(PHY_ID_AQ1202) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQ2104) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQR105) }, -diff --git a/drivers/net/phy/ax88796b.c b/drivers/net/phy/ax88796b.c -index eb74a8cf8df1..694df1401aa2 100644 ---- a/drivers/net/phy/ax88796b.c -+++ b/drivers/net/phy/ax88796b.c -@@ -121,7 +121,7 @@ static struct phy_driver asix_driver[] = { - - module_phy_driver(asix_driver); - --static struct mdio_device_id __maybe_unused asix_tbl[] = { -+static const struct mdio_device_id __maybe_unused asix_tbl[] = { - { PHY_ID_MATCH_EXACT(PHY_ID_ASIX_AX88772A) }, - { PHY_ID_MATCH_EXACT(PHY_ID_ASIX_AX88772C) }, - { PHY_ID_ASIX_AX88796B, 0xfffffff0 }, -diff --git a/drivers/net/phy/bcm-cygnus.c b/drivers/net/phy/bcm-cygnus.c -index da8f7cb41b44..15cbef8202bc 100644 ---- a/drivers/net/phy/bcm-cygnus.c -+++ b/drivers/net/phy/bcm-cygnus.c -@@ -278,7 +278,7 @@ static struct phy_driver bcm_cygnus_phy_driver[] = { - } - }; - --static struct mdio_device_id __maybe_unused bcm_cygnus_phy_tbl[] = { -+static const struct mdio_device_id __maybe_unused bcm_cygnus_phy_tbl[] = { - { PHY_ID_BCM_CYGNUS, 0xfffffff0, }, - { PHY_ID_BCM_OMEGA, 0xfffffff0, }, - { } -diff --git a/drivers/net/phy/bcm54140.c b/drivers/net/phy/bcm54140.c -index 2eea3d09b1e6..7969345f6b35 100644 ---- a/drivers/net/phy/bcm54140.c -+++ b/drivers/net/phy/bcm54140.c -@@ -883,7 +883,7 @@ static struct phy_driver bcm54140_drivers[] = { - }; - module_phy_driver(bcm54140_drivers); - --static struct mdio_device_id __maybe_unused bcm54140_tbl[] = { -+static const struct mdio_device_id __maybe_unused bcm54140_tbl[] = { - { PHY_ID_BCM54140, BCM54140_PHY_ID_MASK }, - { } - }; -diff --git a/drivers/net/phy/bcm63xx.c b/drivers/net/phy/bcm63xx.c -index 0eb33be824f1..b46a736a3130 100644 ---- a/drivers/net/phy/bcm63xx.c -+++ b/drivers/net/phy/bcm63xx.c -@@ -93,7 +93,7 @@ static struct phy_driver bcm63xx_driver[] = { - - module_phy_driver(bcm63xx_driver); - --static struct mdio_device_id __maybe_unused bcm63xx_tbl[] = { -+static const struct mdio_device_id __maybe_unused bcm63xx_tbl[] = { - { 0x00406000, 0xfffffc00 }, - { 0x002bdc00, 0xfffffc00 }, - { } -diff --git a/drivers/net/phy/bcm7xxx.c b/drivers/net/phy/bcm7xxx.c -index 97638ba7ae85..00e8fa14aa77 100644 ---- a/drivers/net/phy/bcm7xxx.c -+++ b/drivers/net/phy/bcm7xxx.c -@@ -929,7 +929,7 @@ static struct phy_driver bcm7xxx_driver[] = { - BCM7XXX_16NM_EPHY(PHY_ID_BCM7712, "Broadcom BCM7712"), - }; - --static struct mdio_device_id __maybe_unused bcm7xxx_tbl[] = { -+static const struct mdio_device_id __maybe_unused bcm7xxx_tbl[] = { - { PHY_ID_BCM72113, 0xfffffff0 }, - { PHY_ID_BCM72116, 0xfffffff0, }, - { PHY_ID_BCM72165, 0xfffffff0, }, -diff --git a/drivers/net/phy/bcm84881.c b/drivers/net/phy/bcm84881.c -index 47405bded677..d7f7cc44c532 100644 ---- a/drivers/net/phy/bcm84881.c -+++ b/drivers/net/phy/bcm84881.c -@@ -262,7 +262,7 @@ static struct phy_driver bcm84881_drivers[] = { - module_phy_driver(bcm84881_drivers); - - /* FIXME: module auto-loading for Clause 45 PHYs seems non-functional */ --static struct mdio_device_id __maybe_unused bcm84881_tbl[] = { -+static const struct mdio_device_id __maybe_unused bcm84881_tbl[] = { - { 0xae025150, 0xfffffff0 }, - { }, - }; -diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c -index 9260c822e467..f4b1d98d6b18 100644 ---- a/drivers/net/phy/broadcom.c -+++ b/drivers/net/phy/broadcom.c -@@ -1734,7 +1734,7 @@ static struct phy_driver broadcom_drivers[] = { - - module_phy_driver(broadcom_drivers); - --static struct mdio_device_id __maybe_unused broadcom_tbl[] = { -+static const struct mdio_device_id __maybe_unused broadcom_tbl[] = { - { PHY_ID_BCM5411, 0xfffffff0 }, - { PHY_ID_BCM5421, 0xfffffff0 }, - { PHY_ID_BCM54210E, 0xfffffff0 }, -diff --git a/drivers/net/phy/cicada.c b/drivers/net/phy/cicada.c -index ef5f412e101f..d87cf8b94cf8 100644 ---- a/drivers/net/phy/cicada.c -+++ b/drivers/net/phy/cicada.c -@@ -145,7 +145,7 @@ static struct phy_driver cis820x_driver[] = { - - module_phy_driver(cis820x_driver); - --static struct mdio_device_id __maybe_unused cicada_tbl[] = { -+static const struct mdio_device_id __maybe_unused cicada_tbl[] = { - { 0x000fc410, 0x000ffff0 }, - { 0x000fc440, 0x000fffc0 }, - { } -diff --git a/drivers/net/phy/cortina.c b/drivers/net/phy/cortina.c -index 40514a94e6ff..3b65f37f1c57 100644 ---- a/drivers/net/phy/cortina.c -+++ b/drivers/net/phy/cortina.c -@@ -87,7 +87,7 @@ static struct phy_driver cortina_driver[] = { - - module_phy_driver(cortina_driver); - --static struct mdio_device_id __maybe_unused cortina_tbl[] = { -+static const struct mdio_device_id __maybe_unused cortina_tbl[] = { - { PHY_ID_CS4340, 0xffffffff}, - {}, - }; -diff --git a/drivers/net/phy/davicom.c b/drivers/net/phy/davicom.c -index 4ac4bce1bf32..fa3692508f16 100644 ---- a/drivers/net/phy/davicom.c -+++ b/drivers/net/phy/davicom.c -@@ -209,7 +209,7 @@ static struct phy_driver dm91xx_driver[] = { - - module_phy_driver(dm91xx_driver); - --static struct mdio_device_id __maybe_unused davicom_tbl[] = { -+static const struct mdio_device_id __maybe_unused davicom_tbl[] = { - { 0x0181b880, 0x0ffffff0 }, - { 0x0181b8b0, 0x0ffffff0 }, - { 0x0181b8a0, 0x0ffffff0 }, -diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c -index 075d2beea716..85e231451093 100644 ---- a/drivers/net/phy/dp83640.c -+++ b/drivers/net/phy/dp83640.c -@@ -1548,7 +1548,7 @@ MODULE_LICENSE("GPL"); - module_init(dp83640_init); - module_exit(dp83640_exit); - --static struct mdio_device_id __maybe_unused dp83640_tbl[] = { -+static const struct mdio_device_id __maybe_unused dp83640_tbl[] = { - { DP83640_PHY_ID, 0xfffffff0 }, - { } - }; -diff --git a/drivers/net/phy/dp83822.c b/drivers/net/phy/dp83822.c -index 3ab64e04a01c..537e152dd156 100644 ---- a/drivers/net/phy/dp83822.c -+++ b/drivers/net/phy/dp83822.c -@@ -825,7 +825,7 @@ static struct phy_driver dp83822_driver[] = { - }; - module_phy_driver(dp83822_driver); - --static struct mdio_device_id __maybe_unused dp83822_tbl[] = { -+static const struct mdio_device_id __maybe_unused dp83822_tbl[] = { - { DP83822_PHY_ID, 0xfffffff0 }, - { DP83825I_PHY_ID, 0xfffffff0 }, - { DP83826C_PHY_ID, 0xfffffff0 }, -diff --git a/drivers/net/phy/dp83848.c b/drivers/net/phy/dp83848.c -index 351411f0aa6f..d88b1999d596 100644 ---- a/drivers/net/phy/dp83848.c -+++ b/drivers/net/phy/dp83848.c -@@ -123,7 +123,7 @@ static int dp83848_config_init(struct phy_device *phydev) - return 0; - } - --static struct mdio_device_id __maybe_unused dp83848_tbl[] = { -+static const struct mdio_device_id __maybe_unused dp83848_tbl[] = { - { TI_DP83848C_PHY_ID, 0xfffffff0 }, - { NS_DP83848C_PHY_ID, 0xfffffff0 }, - { TI_DP83620_PHY_ID, 0xfffffff0 }, -diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c -index 4120385c5a79..c1451df430ac 100644 ---- a/drivers/net/phy/dp83867.c -+++ b/drivers/net/phy/dp83867.c -@@ -1210,7 +1210,7 @@ static struct phy_driver dp83867_driver[] = { - }; - module_phy_driver(dp83867_driver); - --static struct mdio_device_id __maybe_unused dp83867_tbl[] = { -+static const struct mdio_device_id __maybe_unused dp83867_tbl[] = { - { DP83867_PHY_ID, 0xfffffff0 }, - { } - }; -diff --git a/drivers/net/phy/dp83869.c b/drivers/net/phy/dp83869.c -index b6b38caf9c0e..a62cd838a9ea 100644 ---- a/drivers/net/phy/dp83869.c -+++ b/drivers/net/phy/dp83869.c -@@ -928,7 +928,7 @@ static struct phy_driver dp83869_driver[] = { - }; - module_phy_driver(dp83869_driver); - --static struct mdio_device_id __maybe_unused dp83869_tbl[] = { -+static const struct mdio_device_id __maybe_unused dp83869_tbl[] = { - { PHY_ID_MATCH_MODEL(DP83869_PHY_ID) }, - { PHY_ID_MATCH_MODEL(DP83561_PHY_ID) }, - { } -diff --git a/drivers/net/phy/dp83tc811.c b/drivers/net/phy/dp83tc811.c -index 7ea32fb77190..e480c2a07450 100644 ---- a/drivers/net/phy/dp83tc811.c -+++ b/drivers/net/phy/dp83tc811.c -@@ -403,7 +403,7 @@ static struct phy_driver dp83811_driver[] = { - }; - module_phy_driver(dp83811_driver); - --static struct mdio_device_id __maybe_unused dp83811_tbl[] = { -+static const struct mdio_device_id __maybe_unused dp83811_tbl[] = { - { DP83TC811_PHY_ID, 0xfffffff0 }, - { }, - }; -diff --git a/drivers/net/phy/dp83td510.c b/drivers/net/phy/dp83td510.c -index 92aa3a2b9744..56ae24ad6c90 100644 ---- a/drivers/net/phy/dp83td510.c -+++ b/drivers/net/phy/dp83td510.c -@@ -605,7 +605,7 @@ static struct phy_driver dp83td510_driver[] = { - } }; - module_phy_driver(dp83td510_driver); - --static struct mdio_device_id __maybe_unused dp83td510_tbl[] = { -+static const struct mdio_device_id __maybe_unused dp83td510_tbl[] = { - { PHY_ID_MATCH_MODEL(DP83TD510E_PHY_ID) }, - { } - }; -diff --git a/drivers/net/phy/dp83tg720.c b/drivers/net/phy/dp83tg720.c -index 0ef4d7dba065..da9230b1ba30 100644 ---- a/drivers/net/phy/dp83tg720.c -+++ b/drivers/net/phy/dp83tg720.c -@@ -361,7 +361,7 @@ static struct phy_driver dp83tg720_driver[] = { - } }; - module_phy_driver(dp83tg720_driver); - --static struct mdio_device_id __maybe_unused dp83tg720_tbl[] = { -+static const struct mdio_device_id __maybe_unused dp83tg720_tbl[] = { - { PHY_ID_MATCH_MODEL(DP83TG720S_PHY_ID) }, - { } - }; -diff --git a/drivers/net/phy/et1011c.c b/drivers/net/phy/et1011c.c -index be1b71d7cab7..6cd8d77586fd 100644 ---- a/drivers/net/phy/et1011c.c -+++ b/drivers/net/phy/et1011c.c -@@ -94,7 +94,7 @@ static struct phy_driver et1011c_driver[] = { { - - module_phy_driver(et1011c_driver); - --static struct mdio_device_id __maybe_unused et1011c_tbl[] = { -+static const struct mdio_device_id __maybe_unused et1011c_tbl[] = { - { 0x0282f014, 0xfffffff0 }, - { } - }; -diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c -index a00a667454a9..feed270ab4ea 100644 ---- a/drivers/net/phy/icplus.c -+++ b/drivers/net/phy/icplus.c -@@ -624,7 +624,7 @@ static struct phy_driver icplus_driver[] = { - - module_phy_driver(icplus_driver); - --static struct mdio_device_id __maybe_unused icplus_tbl[] = { -+static const struct mdio_device_id __maybe_unused icplus_tbl[] = { - { PHY_ID_MATCH_MODEL(IP175C_PHY_ID) }, - { PHY_ID_MATCH_MODEL(IP1001_PHY_ID) }, - { PHY_ID_MATCH_EXACT(IP101A_PHY_ID) }, -diff --git a/drivers/net/phy/intel-xway.c b/drivers/net/phy/intel-xway.c -index 3c032868ef04..fad411b93c15 100644 ---- a/drivers/net/phy/intel-xway.c -+++ b/drivers/net/phy/intel-xway.c -@@ -456,7 +456,7 @@ static struct phy_driver xway_gphy[] = { - }; - module_phy_driver(xway_gphy); - --static struct mdio_device_id __maybe_unused xway_gphy_tbl[] = { -+static const struct mdio_device_id __maybe_unused xway_gphy_tbl[] = { - { PHY_ID_PHY11G_1_3, 0xffffffff }, - { PHY_ID_PHY22F_1_3, 0xffffffff }, - { PHY_ID_PHY11G_1_4, 0xffffffff }, -diff --git a/drivers/net/phy/lxt.c b/drivers/net/phy/lxt.c -index e3bf827b7959..5251a61c8b0f 100644 ---- a/drivers/net/phy/lxt.c -+++ b/drivers/net/phy/lxt.c -@@ -348,7 +348,7 @@ static struct phy_driver lxt97x_driver[] = { - - module_phy_driver(lxt97x_driver); - --static struct mdio_device_id __maybe_unused lxt_tbl[] = { -+static const struct mdio_device_id __maybe_unused lxt_tbl[] = { - { 0x78100000, 0xfffffff0 }, - { 0x001378e0, 0xfffffff0 }, - { 0x00137a10, 0xfffffff0 }, -diff --git a/drivers/net/phy/marvell-88q2xxx.c b/drivers/net/phy/marvell-88q2xxx.c -index b3a5a0af19da..d0856a06a9e7 100644 ---- a/drivers/net/phy/marvell-88q2xxx.c -+++ b/drivers/net/phy/marvell-88q2xxx.c -@@ -940,7 +940,7 @@ static struct phy_driver mv88q2xxx_driver[] = { - - module_phy_driver(mv88q2xxx_driver); - --static struct mdio_device_id __maybe_unused mv88q2xxx_tbl[] = { -+static const struct mdio_device_id __maybe_unused mv88q2xxx_tbl[] = { - { MARVELL_PHY_ID_88Q2110, MARVELL_PHY_ID_MASK }, - { MARVELL_PHY_ID_88Q2220, MARVELL_PHY_ID_MASK }, - { /*sentinel*/ } -diff --git a/drivers/net/phy/marvell-88x2222.c b/drivers/net/phy/marvell-88x2222.c -index 0b777cdd7078..fad2f54c1eac 100644 ---- a/drivers/net/phy/marvell-88x2222.c -+++ b/drivers/net/phy/marvell-88x2222.c -@@ -613,7 +613,7 @@ static struct phy_driver mv2222_drivers[] = { - }; - module_phy_driver(mv2222_drivers); - --static struct mdio_device_id __maybe_unused mv2222_tbl[] = { -+static const struct mdio_device_id __maybe_unused mv2222_tbl[] = { - { MARVELL_PHY_ID_88X2222, MARVELL_PHY_ID_MASK }, - { } - }; -diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c -index b7d2951d979d..9c761b855026 100644 ---- a/drivers/net/phy/marvell.c -+++ b/drivers/net/phy/marvell.c -@@ -4181,7 +4181,7 @@ static struct phy_driver marvell_drivers[] = { - - module_phy_driver(marvell_drivers); - --static struct mdio_device_id __maybe_unused marvell_tbl[] = { -+static const struct mdio_device_id __maybe_unused marvell_tbl[] = { - { MARVELL_PHY_ID_88E1101, MARVELL_PHY_ID_MASK }, - { MARVELL_PHY_ID_88E3082, MARVELL_PHY_ID_MASK }, - { MARVELL_PHY_ID_88E1112, MARVELL_PHY_ID_MASK }, -diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c -index 6642eb642d4b..623bdb8466b8 100644 ---- a/drivers/net/phy/marvell10g.c -+++ b/drivers/net/phy/marvell10g.c -@@ -1484,7 +1484,7 @@ static struct phy_driver mv3310_drivers[] = { - - module_phy_driver(mv3310_drivers); - --static struct mdio_device_id __maybe_unused mv3310_tbl[] = { -+static const struct mdio_device_id __maybe_unused mv3310_tbl[] = { - { MARVELL_PHY_ID_88X3310, MARVELL_PHY_ID_MASK }, - { MARVELL_PHY_ID_88E2110, MARVELL_PHY_ID_MASK }, - { }, -diff --git a/drivers/net/phy/mediatek/mtk-ge-soc.c b/drivers/net/phy/mediatek/mtk-ge-soc.c -index 38dc898eaf7b..bdf99b327029 100644 ---- a/drivers/net/phy/mediatek/mtk-ge-soc.c -+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c -@@ -1356,7 +1356,7 @@ static struct phy_driver mtk_socphy_driver[] = { - - module_phy_driver(mtk_socphy_driver); - --static struct mdio_device_id __maybe_unused mtk_socphy_tbl[] = { -+static const struct mdio_device_id __maybe_unused mtk_socphy_tbl[] = { - { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981) }, - { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988) }, - { } -diff --git a/drivers/net/phy/mediatek/mtk-ge.c b/drivers/net/phy/mediatek/mtk-ge.c -index ed2617bc20f4..b517ca8573e7 100644 ---- a/drivers/net/phy/mediatek/mtk-ge.c -+++ b/drivers/net/phy/mediatek/mtk-ge.c -@@ -93,7 +93,7 @@ static struct phy_driver mtk_gephy_driver[] = { - - module_phy_driver(mtk_gephy_driver); - --static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = { -+static const struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = { - { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7530) }, - { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7531) }, - { } -diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c -index bb9b33b6bce2..962ebbbc1348 100644 ---- a/drivers/net/phy/meson-gxl.c -+++ b/drivers/net/phy/meson-gxl.c -@@ -221,7 +221,7 @@ static struct phy_driver meson_gxl_phy[] = { - }, - }; - --static struct mdio_device_id __maybe_unused meson_gxl_tbl[] = { -+static const struct mdio_device_id __maybe_unused meson_gxl_tbl[] = { - { PHY_ID_MATCH_VENDOR(0x01814400) }, - { PHY_ID_MATCH_VENDOR(0x01803301) }, - { } -diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c -index 92e9eb4146d9..655769765bc8 100644 ---- a/drivers/net/phy/micrel.c -+++ b/drivers/net/phy/micrel.c -@@ -5701,7 +5701,7 @@ MODULE_DESCRIPTION("Micrel PHY driver"); - MODULE_AUTHOR("David J. Choi"); - MODULE_LICENSE("GPL"); - --static struct mdio_device_id __maybe_unused micrel_tbl[] = { -+static const struct mdio_device_id __maybe_unused micrel_tbl[] = { - { PHY_ID_KSZ9021, 0x000ffffe }, - { PHY_ID_KSZ9031, MICREL_PHY_ID_MASK }, - { PHY_ID_KSZ9131, MICREL_PHY_ID_MASK }, -diff --git a/drivers/net/phy/microchip.c b/drivers/net/phy/microchip.c -index ffca1cec4ec9..55822d36889c 100644 ---- a/drivers/net/phy/microchip.c -+++ b/drivers/net/phy/microchip.c -@@ -509,7 +509,7 @@ static struct phy_driver microchip_phy_driver[] = { - - module_phy_driver(microchip_phy_driver); - --static struct mdio_device_id __maybe_unused microchip_tbl[] = { -+static const struct mdio_device_id __maybe_unused microchip_tbl[] = { - { 0x0007c132, 0xfffffff2 }, - { PHY_ID_MATCH_MODEL(PHY_ID_LAN937X_TX) }, - { } -diff --git a/drivers/net/phy/microchip_t1.c b/drivers/net/phy/microchip_t1.c -index a5ef8fe50704..4ddc407e405c 100644 ---- a/drivers/net/phy/microchip_t1.c -+++ b/drivers/net/phy/microchip_t1.c -@@ -1886,7 +1886,7 @@ static struct phy_driver microchip_t1_phy_driver[] = { - - module_phy_driver(microchip_t1_phy_driver); - --static struct mdio_device_id __maybe_unused microchip_t1_tbl[] = { -+static const struct mdio_device_id __maybe_unused microchip_t1_tbl[] = { - { PHY_ID_MATCH_MODEL(PHY_ID_LAN87XX) }, - { PHY_ID_MATCH_MODEL(PHY_ID_LAN937X) }, - { PHY_ID_MATCH_MODEL(PHY_ID_LAN887X) }, -diff --git a/drivers/net/phy/microchip_t1s.c b/drivers/net/phy/microchip_t1s.c -index 3614839a8e51..78c54d826c97 100644 ---- a/drivers/net/phy/microchip_t1s.c -+++ b/drivers/net/phy/microchip_t1s.c -@@ -323,7 +323,7 @@ static struct phy_driver microchip_t1s_driver[] = { - - module_phy_driver(microchip_t1s_driver); - --static struct mdio_device_id __maybe_unused tbl[] = { -+static const struct mdio_device_id __maybe_unused tbl[] = { - { PHY_ID_MATCH_EXACT(PHY_ID_LAN867X_REVB1) }, - { PHY_ID_MATCH_EXACT(PHY_ID_LAN865X_REVB0) }, - { } -diff --git a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c -index 19983b206405..cc2bb9ed4fd2 100644 ---- a/drivers/net/phy/mscc/mscc_main.c -+++ b/drivers/net/phy/mscc/mscc_main.c -@@ -2710,7 +2710,7 @@ static struct phy_driver vsc85xx_driver[] = { - - module_phy_driver(vsc85xx_driver); - --static struct mdio_device_id __maybe_unused vsc85xx_tbl[] = { -+static const struct mdio_device_id __maybe_unused vsc85xx_tbl[] = { - { PHY_ID_MATCH_VENDOR(PHY_VENDOR_MSCC) }, - { } - }; -diff --git a/drivers/net/phy/mxl-gpy.c b/drivers/net/phy/mxl-gpy.c -index e5f8ac4b4604..d145b67a067f 100644 ---- a/drivers/net/phy/mxl-gpy.c -+++ b/drivers/net/phy/mxl-gpy.c -@@ -1047,7 +1047,7 @@ static struct phy_driver gpy_drivers[] = { - }; - module_phy_driver(gpy_drivers); - --static struct mdio_device_id __maybe_unused gpy_tbl[] = { -+static const struct mdio_device_id __maybe_unused gpy_tbl[] = { - {PHY_ID_MATCH_MODEL(PHY_ID_GPY2xx)}, - {PHY_ID_GPY115B, PHY_ID_GPYx15B_MASK}, - {PHY_ID_MATCH_MODEL(PHY_ID_GPY115C)}, -diff --git a/drivers/net/phy/national.c b/drivers/net/phy/national.c -index 9ae9cc6b23c2..7f3ff322892e 100644 ---- a/drivers/net/phy/national.c -+++ b/drivers/net/phy/national.c -@@ -173,7 +173,7 @@ MODULE_DESCRIPTION("NatSemi PHY driver"); - MODULE_AUTHOR("Stuart Menefy"); - MODULE_LICENSE("GPL"); - --static struct mdio_device_id __maybe_unused ns_tbl[] = { -+static const struct mdio_device_id __maybe_unused ns_tbl[] = { - { DP83865_PHY_ID, 0xfffffff0 }, - { } - }; -diff --git a/drivers/net/phy/ncn26000.c b/drivers/net/phy/ncn26000.c -index 5680584f659e..cabdd83c614f 100644 ---- a/drivers/net/phy/ncn26000.c -+++ b/drivers/net/phy/ncn26000.c -@@ -159,7 +159,7 @@ static struct phy_driver ncn26000_driver[] = { - - module_phy_driver(ncn26000_driver); - --static struct mdio_device_id __maybe_unused ncn26000_tbl[] = { -+static const struct mdio_device_id __maybe_unused ncn26000_tbl[] = { - { PHY_ID_MATCH_MODEL(PHY_ID_NCN26000) }, - { } - }; -diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c -index 99a5eee77bec..9d6b336f9971 100644 ---- a/drivers/net/phy/nxp-c45-tja11xx.c -+++ b/drivers/net/phy/nxp-c45-tja11xx.c -@@ -2102,7 +2102,7 @@ static struct phy_driver nxp_c45_driver[] = { - - module_phy_driver(nxp_c45_driver); - --static struct mdio_device_id __maybe_unused nxp_c45_tbl[] = { -+static const struct mdio_device_id __maybe_unused nxp_c45_tbl[] = { - { PHY_ID_MATCH_MODEL(PHY_ID_TJA_1103) }, - { PHY_ID_MATCH_MODEL(PHY_ID_TJA_1120) }, - { /*sentinel*/ }, -diff --git a/drivers/net/phy/nxp-cbtx.c b/drivers/net/phy/nxp-cbtx.c -index 145703f0a406..d0ff22f68cd2 100644 ---- a/drivers/net/phy/nxp-cbtx.c -+++ b/drivers/net/phy/nxp-cbtx.c -@@ -215,7 +215,7 @@ static struct phy_driver cbtx_driver[] = { - - module_phy_driver(cbtx_driver); - --static struct mdio_device_id __maybe_unused cbtx_tbl[] = { -+static const struct mdio_device_id __maybe_unused cbtx_tbl[] = { - { PHY_ID_MATCH_MODEL(PHY_ID_CBTX_SJA1110) }, - { }, - }; -diff --git a/drivers/net/phy/nxp-tja11xx.c b/drivers/net/phy/nxp-tja11xx.c -index 2c263ae44b4f..ed7fa26bac8e 100644 ---- a/drivers/net/phy/nxp-tja11xx.c -+++ b/drivers/net/phy/nxp-tja11xx.c -@@ -888,7 +888,7 @@ static struct phy_driver tja11xx_driver[] = { - - module_phy_driver(tja11xx_driver); - --static struct mdio_device_id __maybe_unused tja11xx_tbl[] = { -+static const struct mdio_device_id __maybe_unused tja11xx_tbl[] = { - { PHY_ID_MATCH_MODEL(PHY_ID_TJA1100) }, - { PHY_ID_MATCH_MODEL(PHY_ID_TJA1101) }, - { PHY_ID_MATCH_MODEL(PHY_ID_TJA1102) }, -diff --git a/drivers/net/phy/qcom/at803x.c b/drivers/net/phy/qcom/at803x.c -index ac909ad8a87b..8f26e395e39f 100644 ---- a/drivers/net/phy/qcom/at803x.c -+++ b/drivers/net/phy/qcom/at803x.c -@@ -1071,7 +1071,7 @@ static struct phy_driver at803x_driver[] = { - - module_phy_driver(at803x_driver); - --static struct mdio_device_id __maybe_unused atheros_tbl[] = { -+static const struct mdio_device_id __maybe_unused atheros_tbl[] = { - { ATH8030_PHY_ID, AT8030_PHY_ID_MASK }, - { PHY_ID_MATCH_EXACT(ATH8031_PHY_ID) }, - { PHY_ID_MATCH_EXACT(ATH8032_PHY_ID) }, -diff --git a/drivers/net/phy/qcom/qca807x.c b/drivers/net/phy/qcom/qca807x.c -index ec336c3e338d..2ad8c2586d64 100644 ---- a/drivers/net/phy/qcom/qca807x.c -+++ b/drivers/net/phy/qcom/qca807x.c -@@ -828,7 +828,7 @@ static struct phy_driver qca807x_drivers[] = { - }; - module_phy_driver(qca807x_drivers); - --static struct mdio_device_id __maybe_unused qca807x_tbl[] = { -+static const struct mdio_device_id __maybe_unused qca807x_tbl[] = { - { PHY_ID_MATCH_EXACT(PHY_ID_QCA8072) }, - { PHY_ID_MATCH_EXACT(PHY_ID_QCA8075) }, - { } -diff --git a/drivers/net/phy/qcom/qca808x.c b/drivers/net/phy/qcom/qca808x.c -index c3aad0e6b700..6de16c0eaa08 100644 ---- a/drivers/net/phy/qcom/qca808x.c -+++ b/drivers/net/phy/qcom/qca808x.c -@@ -655,7 +655,7 @@ static struct phy_driver qca808x_driver[] = { - - module_phy_driver(qca808x_driver); - --static struct mdio_device_id __maybe_unused qca808x_tbl[] = { -+static const struct mdio_device_id __maybe_unused qca808x_tbl[] = { - { PHY_ID_MATCH_EXACT(QCA8081_PHY_ID) }, - { } - }; -diff --git a/drivers/net/phy/qcom/qca83xx.c b/drivers/net/phy/qcom/qca83xx.c -index a05d0df6fa16..b32c2fbec927 100644 ---- a/drivers/net/phy/qcom/qca83xx.c -+++ b/drivers/net/phy/qcom/qca83xx.c -@@ -261,7 +261,7 @@ static struct phy_driver qca83xx_driver[] = { - - module_phy_driver(qca83xx_driver); - --static struct mdio_device_id __maybe_unused qca83xx_tbl[] = { -+static const struct mdio_device_id __maybe_unused qca83xx_tbl[] = { - { PHY_ID_MATCH_EXACT(QCA8337_PHY_ID) }, - { PHY_ID_MATCH_EXACT(QCA8327_A_PHY_ID) }, - { PHY_ID_MATCH_EXACT(QCA8327_B_PHY_ID) }, -diff --git a/drivers/net/phy/qsemi.c b/drivers/net/phy/qsemi.c -index 30d15f7c9b03..7b70ba6cab66 100644 ---- a/drivers/net/phy/qsemi.c -+++ b/drivers/net/phy/qsemi.c -@@ -155,7 +155,7 @@ static struct phy_driver qs6612_driver[] = { { - - module_phy_driver(qs6612_driver); - --static struct mdio_device_id __maybe_unused qs6612_tbl[] = { -+static const struct mdio_device_id __maybe_unused qs6612_tbl[] = { - { 0x00181440, 0xfffffff0 }, - { } - }; -diff --git a/drivers/net/phy/rockchip.c b/drivers/net/phy/rockchip.c -index bb13e75183ee..b338f385e15a 100644 ---- a/drivers/net/phy/rockchip.c -+++ b/drivers/net/phy/rockchip.c -@@ -188,7 +188,7 @@ static struct phy_driver rockchip_phy_driver[] = { - - module_phy_driver(rockchip_phy_driver); - --static struct mdio_device_id __maybe_unused rockchip_phy_tbl[] = { -+static const struct mdio_device_id __maybe_unused rockchip_phy_tbl[] = { - { INTERNAL_EPHY_ID, 0xfffffff0 }, - { } - }; -diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c -index de66b621eb99..1acac288972d 100644 ---- a/drivers/net/phy/smsc.c -+++ b/drivers/net/phy/smsc.c -@@ -885,7 +885,7 @@ MODULE_DESCRIPTION("SMSC PHY driver"); - MODULE_AUTHOR("Herbert Valerio Riedel"); - MODULE_LICENSE("GPL"); - --static struct mdio_device_id __maybe_unused smsc_tbl[] = { -+static const struct mdio_device_id __maybe_unused smsc_tbl[] = { - { 0x0007c0a0, 0xfffffff0 }, - { 0x0007c0b0, 0xfffffff0 }, - { 0x0007c0c0, 0xfffffff0 }, -diff --git a/drivers/net/phy/ste10Xp.c b/drivers/net/phy/ste10Xp.c -index 309e4c3496c4..d4835d4c50e0 100644 ---- a/drivers/net/phy/ste10Xp.c -+++ b/drivers/net/phy/ste10Xp.c -@@ -124,7 +124,7 @@ static struct phy_driver ste10xp_pdriver[] = { - - module_phy_driver(ste10xp_pdriver); - --static struct mdio_device_id __maybe_unused ste10Xp_tbl[] = { -+static const struct mdio_device_id __maybe_unused ste10Xp_tbl[] = { - { STE101P_PHY_ID, 0xfffffff0 }, - { STE100P_PHY_ID, 0xffffffff }, - { } -diff --git a/drivers/net/phy/teranetics.c b/drivers/net/phy/teranetics.c -index 8057ea8dbc21..752d4bf7bb99 100644 ---- a/drivers/net/phy/teranetics.c -+++ b/drivers/net/phy/teranetics.c -@@ -87,7 +87,7 @@ static struct phy_driver teranetics_driver[] = { - - module_phy_driver(teranetics_driver); - --static struct mdio_device_id __maybe_unused teranetics_tbl[] = { -+static const struct mdio_device_id __maybe_unused teranetics_tbl[] = { - { PHY_ID_TN2020, 0xffffffff }, - { } - }; -diff --git a/drivers/net/phy/uPD60620.c b/drivers/net/phy/uPD60620.c -index 38834347a427..900cb756c366 100644 ---- a/drivers/net/phy/uPD60620.c -+++ b/drivers/net/phy/uPD60620.c -@@ -90,7 +90,7 @@ static struct phy_driver upd60620_driver[1] = { { - - module_phy_driver(upd60620_driver); - --static struct mdio_device_id __maybe_unused upd60620_tbl[] = { -+static const struct mdio_device_id __maybe_unused upd60620_tbl[] = { - { UPD60620_PHY_ID, 0xfffffffe }, - { } - }; -diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c -index 2377179de017..b1b7bbba284e 100644 ---- a/drivers/net/phy/vitesse.c -+++ b/drivers/net/phy/vitesse.c -@@ -674,7 +674,7 @@ static struct phy_driver vsc82xx_driver[] = { - - module_phy_driver(vsc82xx_driver); - --static struct mdio_device_id __maybe_unused vitesse_tbl[] = { -+static const struct mdio_device_id __maybe_unused vitesse_tbl[] = { - { PHY_ID_VSC8234, 0x000ffff0 }, - { PHY_ID_VSC8244, 0x000fffc0 }, - { PHY_ID_VSC8572, 0x000ffff0 }, --- -2.51.0 - - -From 9c63de87a5aab32fe251f0d50e2da397138cf3a2 Mon Sep 17 00:00:00 2001 -From: Sky Huang -Date: Thu, 13 Feb 2025 16:05:49 +0800 -Subject: [PATCH 076/517] net: phy: mediatek: Change to more meaningful macros - -Replace magic number with more meaningful macros in mtk-ge.c. -Also, move some common macros into mtk-phy-lib.c. - -Signed-off-by: Sky Huang -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/20250213080553.921434-2-SkyLake.Huang@mediatek.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/mediatek/mtk-ge-soc.c | 1 - - drivers/net/phy/mediatek/mtk-ge.c | 71 +++++++++++++++++++++------ - drivers/net/phy/mediatek/mtk.h | 2 + - 3 files changed, 57 insertions(+), 17 deletions(-) - -diff --git a/drivers/net/phy/mediatek/mtk-ge-soc.c b/drivers/net/phy/mediatek/mtk-ge-soc.c -index bdf99b327029..69cd6a1cbad4 100644 ---- a/drivers/net/phy/mediatek/mtk-ge-soc.c -+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c -@@ -24,7 +24,6 @@ - #define MTK_PHY_SMI_DET_ON_THRESH_MASK GENMASK(13, 8) - - #define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30 --#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5 - - #define ANALOG_INTERNAL_OPERATION_MAX_US 20 - #define TXRESERVE_MIN 0 -diff --git a/drivers/net/phy/mediatek/mtk-ge.c b/drivers/net/phy/mediatek/mtk-ge.c -index b517ca8573e7..75e1b0387710 100644 ---- a/drivers/net/phy/mediatek/mtk-ge.c -+++ b/drivers/net/phy/mediatek/mtk-ge.c -@@ -8,18 +8,38 @@ - #define MTK_GPHY_ID_MT7530 0x03a29412 - #define MTK_GPHY_ID_MT7531 0x03a29441 - --#define MTK_EXT_PAGE_ACCESS 0x1f --#define MTK_PHY_PAGE_STANDARD 0x0000 --#define MTK_PHY_PAGE_EXTENDED 0x0001 --#define MTK_PHY_PAGE_EXTENDED_2 0x0002 --#define MTK_PHY_PAGE_EXTENDED_3 0x0003 --#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30 --#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5 -+#define MTK_PHY_PAGE_EXTENDED_1 0x0001 -+#define MTK_PHY_AUX_CTRL_AND_STATUS 0x14 -+#define MTK_PHY_ENABLE_DOWNSHIFT BIT(4) -+ -+#define MTK_PHY_PAGE_EXTENDED_2 0x0002 -+#define MTK_PHY_PAGE_EXTENDED_3 0x0003 -+#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG11 0x11 -+ -+#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30 -+ -+/* Registers on MDIO_MMD_VEND1 */ -+#define MTK_PHY_GBE_MODE_TX_DELAY_SEL 0x13 -+#define MTK_PHY_TEST_MODE_TX_DELAY_SEL 0x14 -+#define MTK_TX_DELAY_PAIR_B_MASK GENMASK(10, 8) -+#define MTK_TX_DELAY_PAIR_D_MASK GENMASK(2, 0) -+ -+#define MTK_PHY_MCC_CTRL_AND_TX_POWER_CTRL 0xa6 -+#define MTK_MCC_NEARECHO_OFFSET_MASK GENMASK(15, 8) -+ -+#define MTK_PHY_RXADC_CTRL_RG7 0xc6 -+#define MTK_PHY_DA_AD_BUF_BIAS_LP_MASK GENMASK(9, 8) -+ -+#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG123 0x123 -+#define MTK_PHY_LPI_NORM_MSE_LO_THRESH100_MASK GENMASK(15, 8) -+#define MTK_PHY_LPI_NORM_MSE_HI_THRESH100_MASK GENMASK(7, 0) - - static void mtk_gephy_config_init(struct phy_device *phydev) - { - /* Enable HW auto downshift */ -- phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4)); -+ phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED_1, -+ MTK_PHY_AUX_CTRL_AND_STATUS, -+ 0, MTK_PHY_ENABLE_DOWNSHIFT); - - /* Increase SlvDPSready time */ - phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); -@@ -29,10 +49,20 @@ static void mtk_gephy_config_init(struct phy_device *phydev) - phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); - - /* Adjust 100_mse_threshold */ -- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff); -- -- /* Disable mcc */ -- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300); -+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, -+ MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG123, -+ MTK_PHY_LPI_NORM_MSE_LO_THRESH100_MASK | -+ MTK_PHY_LPI_NORM_MSE_HI_THRESH100_MASK, -+ FIELD_PREP(MTK_PHY_LPI_NORM_MSE_LO_THRESH100_MASK, -+ 0xff) | -+ FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH100_MASK, -+ 0xff)); -+ -+ /* If echo time is narrower than 0x3, it will be regarded as noise */ -+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, -+ MTK_PHY_MCC_CTRL_AND_TX_POWER_CTRL, -+ MTK_MCC_NEARECHO_OFFSET_MASK, -+ FIELD_PREP(MTK_MCC_NEARECHO_OFFSET_MASK, 0x3)); - } - - static int mt7530_phy_config_init(struct phy_device *phydev) -@@ -40,7 +70,8 @@ static int mt7530_phy_config_init(struct phy_device *phydev) - mtk_gephy_config_init(phydev); - - /* Increase post_update_timer */ -- phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b); -+ phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, -+ MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG11, 0x4b); - - return 0; - } -@@ -51,11 +82,19 @@ static int mt7531_phy_config_init(struct phy_device *phydev) - - /* PHY link down power saving enable */ - phy_set_bits(phydev, 0x17, BIT(4)); -- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300); -+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7, -+ MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, -+ FIELD_PREP(MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3)); - - /* Set TX Pair delay selection */ -- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404); -- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404); -+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_GBE_MODE_TX_DELAY_SEL, -+ MTK_TX_DELAY_PAIR_B_MASK | MTK_TX_DELAY_PAIR_D_MASK, -+ FIELD_PREP(MTK_TX_DELAY_PAIR_B_MASK, 0x4) | -+ FIELD_PREP(MTK_TX_DELAY_PAIR_D_MASK, 0x4)); -+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TEST_MODE_TX_DELAY_SEL, -+ MTK_TX_DELAY_PAIR_B_MASK | MTK_TX_DELAY_PAIR_D_MASK, -+ FIELD_PREP(MTK_TX_DELAY_PAIR_B_MASK, 0x4) | -+ FIELD_PREP(MTK_TX_DELAY_PAIR_D_MASK, 0x4)); - - return 0; - } -diff --git a/drivers/net/phy/mediatek/mtk.h b/drivers/net/phy/mediatek/mtk.h -index 63d9fe179b8f..a888e2e1dd6b 100644 ---- a/drivers/net/phy/mediatek/mtk.h -+++ b/drivers/net/phy/mediatek/mtk.h -@@ -9,6 +9,8 @@ - #define _MTK_EPHY_H_ - - #define MTK_EXT_PAGE_ACCESS 0x1f -+#define MTK_PHY_PAGE_STANDARD 0x0000 -+#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5 - - /* Registers on MDIO_MMD_VEND2 */ - #define MTK_PHY_LED0_ON_CTRL 0x24 --- -2.51.0 - - -From 0b2e6555cf36c1011c636b73e0202590247ca124 Mon Sep 17 00:00:00 2001 -From: Sky Huang -Date: Thu, 13 Feb 2025 16:05:50 +0800 -Subject: [PATCH 077/517] net: phy: mediatek: Add token ring access helper - functions in mtk-phy-lib - -This patch adds TR(token ring) manipulations and adds correct -macro names for those magic numbers. TR is a way to access -proprietary registers on page 52b5. Use these helper functions -so we can see which fields we're going to modify/set/clear. - -TR functions with __* prefix mean that the operations inside -aren't wrapped by page select/restore functions. - -This patch doesn't really change registers' settings but just -enhances readability and maintainability. - -Signed-off-by: Sky Huang -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/20250213080553.921434-3-SkyLake.Huang@mediatek.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/mediatek/mtk-ge-soc.c | 231 +++++++++++++++++-------- - drivers/net/phy/mediatek/mtk-ge.c | 11 +- - drivers/net/phy/mediatek/mtk-phy-lib.c | 63 +++++++ - drivers/net/phy/mediatek/mtk.h | 5 + - 4 files changed, 230 insertions(+), 80 deletions(-) - -diff --git a/drivers/net/phy/mediatek/mtk-ge-soc.c b/drivers/net/phy/mediatek/mtk-ge-soc.c -index 69cd6a1cbad4..5d7373793659 100644 ---- a/drivers/net/phy/mediatek/mtk-ge-soc.c -+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c -@@ -25,6 +25,90 @@ - - #define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30 - -+/* Registers on Token Ring debug nodes */ -+/* ch_addr = 0x0, node_addr = 0x7, data_addr = 0x15 */ -+/* NormMseLoThresh */ -+#define NORMAL_MSE_LO_THRESH_MASK GENMASK(15, 8) -+ -+/* ch_addr = 0x0, node_addr = 0xf, data_addr = 0x3c */ -+/* RemAckCntLimitCtrl */ -+#define REMOTE_ACK_COUNT_LIMIT_CTRL_MASK GENMASK(2, 1) -+ -+/* ch_addr = 0x1, node_addr = 0xd, data_addr = 0x20 */ -+/* VcoSlicerThreshBitsHigh */ -+#define VCO_SLICER_THRESH_HIGH_MASK GENMASK(23, 0) -+ -+/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x0 */ -+/* DfeTailEnableVgaThresh1000 */ -+#define DFE_TAIL_EANBLE_VGA_TRHESH_1000 GENMASK(5, 1) -+ -+/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x1 */ -+/* MrvlTrFix100Kp */ -+#define MRVL_TR_FIX_100KP_MASK GENMASK(22, 20) -+/* MrvlTrFix100Kf */ -+#define MRVL_TR_FIX_100KF_MASK GENMASK(19, 17) -+/* MrvlTrFix1000Kp */ -+#define MRVL_TR_FIX_1000KP_MASK GENMASK(16, 14) -+/* MrvlTrFix1000Kf */ -+#define MRVL_TR_FIX_1000KF_MASK GENMASK(13, 11) -+ -+/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x12 */ -+/* VgaDecRate */ -+#define VGA_DECIMATION_RATE_MASK GENMASK(8, 5) -+ -+/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x17 */ -+/* SlvDSPreadyTime */ -+#define SLAVE_DSP_READY_TIME_MASK GENMASK(22, 15) -+/* MasDSPreadyTime */ -+#define MASTER_DSP_READY_TIME_MASK GENMASK(14, 7) -+ -+/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x20 */ -+/* ResetSyncOffset */ -+#define RESET_SYNC_OFFSET_MASK GENMASK(11, 8) -+ -+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x0 */ -+/* FfeUpdGainForceVal */ -+#define FFE_UPDATE_GAIN_FORCE_VAL_MASK GENMASK(9, 7) -+/* FfeUpdGainForce */ -+#define FFE_UPDATE_GAIN_FORCE BIT(6) -+ -+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x6 */ -+/* SS: Steady-state, KP: Proportional Gain */ -+/* SSTrKp100 */ -+#define SS_TR_KP100_MASK GENMASK(21, 19) -+/* SSTrKf100 */ -+#define SS_TR_KF100_MASK GENMASK(18, 16) -+/* SSTrKp1000Mas */ -+#define SS_TR_KP1000_MASTER_MASK GENMASK(15, 13) -+/* SSTrKf1000Mas */ -+#define SS_TR_KF1000_MASTER_MASK GENMASK(12, 10) -+/* SSTrKp1000Slv */ -+#define SS_TR_KP1000_SLAVE_MASK GENMASK(9, 7) -+/* SSTrKf1000Slv */ -+#define SS_TR_KF1000_SLAVE_MASK GENMASK(6, 4) -+ -+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0xd */ -+/* RegEEE_st2TrKf1000 */ -+#define EEE1000_STAGE2_TR_KF_MASK GENMASK(13, 11) -+ -+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0xf */ -+/* RegEEE_slv_waketr_timer_tar */ -+#define SLAVE_WAKETR_TIMER_MASK GENMASK(20, 11) -+/* RegEEE_slv_remtx_timer_tar */ -+#define SLAVE_REMTX_TIMER_MASK GENMASK(10, 1) -+ -+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x10 */ -+/* RegEEE_slv_wake_int_timer_tar */ -+#define SLAVE_WAKEINT_TIMER_MASK GENMASK(10, 1) -+ -+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x14 */ -+/* RegEEE_trfreeze_timer2 */ -+#define TR_FREEZE_TIMER2_MASK GENMASK(9, 0) -+ -+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x1c */ -+/* RegEEE100Stg1_tar */ -+#define EEE100_LPSYNC_STAGE1_UPDATE_TIMER_MASK GENMASK(8, 0) -+ - #define ANALOG_INTERNAL_OPERATION_MAX_US 20 - #define TXRESERVE_MIN 0 - #define TXRESERVE_MAX 7 -@@ -700,40 +784,41 @@ static int tx_vcm_cal_sw(struct phy_device *phydev, u8 rg_txreserve_x) - static void mt798x_phy_common_finetune(struct phy_device *phydev) - { - phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); -- /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */ -- __phy_write(phydev, 0x11, 0xc71); -- __phy_write(phydev, 0x12, 0xc); -- __phy_write(phydev, 0x10, 0x8fae); -+ __mtk_tr_modify(phydev, 0x1, 0xf, 0x17, -+ SLAVE_DSP_READY_TIME_MASK | MASTER_DSP_READY_TIME_MASK, -+ FIELD_PREP(SLAVE_DSP_READY_TIME_MASK, 0x18) | -+ FIELD_PREP(MASTER_DSP_READY_TIME_MASK, 0x18)); - - /* EnabRandUpdTrig = 1 */ - __phy_write(phydev, 0x11, 0x2f00); - __phy_write(phydev, 0x12, 0xe); - __phy_write(phydev, 0x10, 0x8fb0); - -- /* NormMseLoThresh = 85 */ -- __phy_write(phydev, 0x11, 0x55a0); -- __phy_write(phydev, 0x12, 0x0); -- __phy_write(phydev, 0x10, 0x83aa); -+ __mtk_tr_modify(phydev, 0x0, 0x7, 0x15, -+ NORMAL_MSE_LO_THRESH_MASK, -+ FIELD_PREP(NORMAL_MSE_LO_THRESH_MASK, 0x55)); - -- /* FfeUpdGainForce = 1(Enable), FfeUpdGainForceVal = 4 */ -- __phy_write(phydev, 0x11, 0x240); -- __phy_write(phydev, 0x12, 0x0); -- __phy_write(phydev, 0x10, 0x9680); -+ __mtk_tr_modify(phydev, 0x2, 0xd, 0x0, -+ FFE_UPDATE_GAIN_FORCE_VAL_MASK, -+ FIELD_PREP(FFE_UPDATE_GAIN_FORCE_VAL_MASK, 0x4) | -+ FFE_UPDATE_GAIN_FORCE); - - /* TrFreeze = 0 (mt7988 default) */ - __phy_write(phydev, 0x11, 0x0); - __phy_write(phydev, 0x12, 0x0); - __phy_write(phydev, 0x10, 0x9686); - -- /* SSTrKp100 = 5 */ -- /* SSTrKf100 = 6 */ -- /* SSTrKp1000Mas = 5 */ -- /* SSTrKf1000Mas = 6 */ -- /* SSTrKp1000Slv = 5 */ -- /* SSTrKf1000Slv = 6 */ -- __phy_write(phydev, 0x11, 0xbaef); -- __phy_write(phydev, 0x12, 0x2e); -- __phy_write(phydev, 0x10, 0x968c); -+ __mtk_tr_modify(phydev, 0x2, 0xd, 0x6, -+ SS_TR_KP100_MASK | SS_TR_KF100_MASK | -+ SS_TR_KP1000_MASTER_MASK | SS_TR_KF1000_MASTER_MASK | -+ SS_TR_KP1000_SLAVE_MASK | SS_TR_KF1000_SLAVE_MASK, -+ FIELD_PREP(SS_TR_KP100_MASK, 0x5) | -+ FIELD_PREP(SS_TR_KF100_MASK, 0x6) | -+ FIELD_PREP(SS_TR_KP1000_MASTER_MASK, 0x5) | -+ FIELD_PREP(SS_TR_KF1000_MASTER_MASK, 0x6) | -+ FIELD_PREP(SS_TR_KP1000_SLAVE_MASK, 0x5) | -+ FIELD_PREP(SS_TR_KF1000_SLAVE_MASK, 0x6)); -+ - phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); - } - -@@ -756,27 +841,29 @@ static void mt7981_phy_finetune(struct phy_device *phydev) - } - - phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); -- /* ResetSyncOffset = 6 */ -- __phy_write(phydev, 0x11, 0x600); -- __phy_write(phydev, 0x12, 0x0); -- __phy_write(phydev, 0x10, 0x8fc0); -+ __mtk_tr_modify(phydev, 0x1, 0xf, 0x20, -+ RESET_SYNC_OFFSET_MASK, -+ FIELD_PREP(RESET_SYNC_OFFSET_MASK, 0x6)); - -- /* VgaDecRate = 1 */ -- __phy_write(phydev, 0x11, 0x4c2a); -- __phy_write(phydev, 0x12, 0x3e); -- __phy_write(phydev, 0x10, 0x8fa4); -+ __mtk_tr_modify(phydev, 0x1, 0xf, 0x12, -+ VGA_DECIMATION_RATE_MASK, -+ FIELD_PREP(VGA_DECIMATION_RATE_MASK, 0x1)); - - /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2, - * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2 - */ -- __phy_write(phydev, 0x11, 0xd10a); -- __phy_write(phydev, 0x12, 0x34); -- __phy_write(phydev, 0x10, 0x8f82); -+ __mtk_tr_modify(phydev, 0x1, 0xf, 0x1, -+ MRVL_TR_FIX_100KP_MASK | MRVL_TR_FIX_100KF_MASK | -+ MRVL_TR_FIX_1000KP_MASK | MRVL_TR_FIX_1000KF_MASK, -+ FIELD_PREP(MRVL_TR_FIX_100KP_MASK, 0x3) | -+ FIELD_PREP(MRVL_TR_FIX_100KF_MASK, 0x2) | -+ FIELD_PREP(MRVL_TR_FIX_1000KP_MASK, 0x3) | -+ FIELD_PREP(MRVL_TR_FIX_1000KF_MASK, 0x2)); - - /* VcoSlicerThreshBitsHigh */ -- __phy_write(phydev, 0x11, 0x5555); -- __phy_write(phydev, 0x12, 0x55); -- __phy_write(phydev, 0x10, 0x8ec0); -+ __mtk_tr_modify(phydev, 0x1, 0xd, 0x20, -+ VCO_SLICER_THRESH_HIGH_MASK, -+ FIELD_PREP(VCO_SLICER_THRESH_HIGH_MASK, 0x555555)); - phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); - - /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9 */ -@@ -828,25 +915,23 @@ static void mt7988_phy_finetune(struct phy_device *phydev) - phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5); - - phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); -- /* ResetSyncOffset = 5 */ -- __phy_write(phydev, 0x11, 0x500); -- __phy_write(phydev, 0x12, 0x0); -- __phy_write(phydev, 0x10, 0x8fc0); -+ __mtk_tr_modify(phydev, 0x1, 0xf, 0x20, -+ RESET_SYNC_OFFSET_MASK, -+ FIELD_PREP(RESET_SYNC_OFFSET_MASK, 0x5)); - - /* VgaDecRate is 1 at default on mt7988 */ - -- /* MrvlTrFix100Kp = 6, MrvlTrFix100Kf = 7, -- * MrvlTrFix1000Kp = 6, MrvlTrFix1000Kf = 7 -- */ -- __phy_write(phydev, 0x11, 0xb90a); -- __phy_write(phydev, 0x12, 0x6f); -- __phy_write(phydev, 0x10, 0x8f82); -- -- /* RemAckCntLimitCtrl = 1 */ -- __phy_write(phydev, 0x11, 0xfbba); -- __phy_write(phydev, 0x12, 0xc3); -- __phy_write(phydev, 0x10, 0x87f8); -- -+ __mtk_tr_modify(phydev, 0x1, 0xf, 0x1, -+ MRVL_TR_FIX_100KP_MASK | MRVL_TR_FIX_100KF_MASK | -+ MRVL_TR_FIX_1000KP_MASK | MRVL_TR_FIX_1000KF_MASK, -+ FIELD_PREP(MRVL_TR_FIX_100KP_MASK, 0x6) | -+ FIELD_PREP(MRVL_TR_FIX_100KF_MASK, 0x7) | -+ FIELD_PREP(MRVL_TR_FIX_1000KP_MASK, 0x6) | -+ FIELD_PREP(MRVL_TR_FIX_1000KF_MASK, 0x7)); -+ -+ __mtk_tr_modify(phydev, 0x0, 0xf, 0x3c, -+ REMOTE_ACK_COUNT_LIMIT_CTRL_MASK, -+ FIELD_PREP(REMOTE_ACK_COUNT_LIMIT_CTRL_MASK, 0x1)); - phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); - - /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 10 */ -@@ -927,40 +1012,36 @@ static void mt798x_phy_eee(struct phy_device *phydev) - __phy_write(phydev, 0x12, 0x0); - __phy_write(phydev, 0x10, 0x9690); - -- /* REG_EEE_st2TrKf1000 = 2 */ -- __phy_write(phydev, 0x11, 0x114f); -- __phy_write(phydev, 0x12, 0x2); -- __phy_write(phydev, 0x10, 0x969a); -+ __mtk_tr_modify(phydev, 0x2, 0xd, 0xd, -+ EEE1000_STAGE2_TR_KF_MASK, -+ FIELD_PREP(EEE1000_STAGE2_TR_KF_MASK, 0x2)); - -- /* RegEEE_slv_wake_tr_timer_tar = 6, RegEEE_slv_remtx_timer_tar = 20 */ -- __phy_write(phydev, 0x11, 0x3028); -- __phy_write(phydev, 0x12, 0x0); -- __phy_write(phydev, 0x10, 0x969e); -+ __mtk_tr_modify(phydev, 0x2, 0xd, 0xf, -+ SLAVE_WAKETR_TIMER_MASK | SLAVE_REMTX_TIMER_MASK, -+ FIELD_PREP(SLAVE_WAKETR_TIMER_MASK, 0x6) | -+ FIELD_PREP(SLAVE_REMTX_TIMER_MASK, 0x14)); - -- /* RegEEE_slv_wake_int_timer_tar = 8 */ -- __phy_write(phydev, 0x11, 0x5010); -- __phy_write(phydev, 0x12, 0x0); -- __phy_write(phydev, 0x10, 0x96a0); -+ __mtk_tr_modify(phydev, 0x2, 0xd, 0x10, -+ SLAVE_WAKEINT_TIMER_MASK, -+ FIELD_PREP(SLAVE_WAKEINT_TIMER_MASK, 0x8)); - -- /* RegEEE_trfreeze_timer2 = 586 */ -- __phy_write(phydev, 0x11, 0x24a); -- __phy_write(phydev, 0x12, 0x0); -- __phy_write(phydev, 0x10, 0x96a8); -+ __mtk_tr_modify(phydev, 0x2, 0xd, 0x14, -+ TR_FREEZE_TIMER2_MASK, -+ FIELD_PREP(TR_FREEZE_TIMER2_MASK, 0x24a)); - -- /* RegEEE100Stg1_tar = 16 */ -- __phy_write(phydev, 0x11, 0x3210); -- __phy_write(phydev, 0x12, 0x0); -- __phy_write(phydev, 0x10, 0x96b8); -+ __mtk_tr_modify(phydev, 0x2, 0xd, 0x1c, -+ EEE100_LPSYNC_STAGE1_UPDATE_TIMER_MASK, -+ FIELD_PREP(EEE100_LPSYNC_STAGE1_UPDATE_TIMER_MASK, -+ 0x10)); - - /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 0 */ - __phy_write(phydev, 0x11, 0x1463); - __phy_write(phydev, 0x12, 0x0); - __phy_write(phydev, 0x10, 0x96ca); - -- /* DfeTailEnableVgaThresh1000 = 27 */ -- __phy_write(phydev, 0x11, 0x36); -- __phy_write(phydev, 0x12, 0x0); -- __phy_write(phydev, 0x10, 0x8f80); -+ __mtk_tr_modify(phydev, 0x1, 0xf, 0x0, -+ DFE_TAIL_EANBLE_VGA_TRHESH_1000, -+ FIELD_PREP(DFE_TAIL_EANBLE_VGA_TRHESH_1000, 0x1b)); - phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); - - phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_3); -diff --git a/drivers/net/phy/mediatek/mtk-ge.c b/drivers/net/phy/mediatek/mtk-ge.c -index 75e1b0387710..a24c5ba469ba 100644 ---- a/drivers/net/phy/mediatek/mtk-ge.c -+++ b/drivers/net/phy/mediatek/mtk-ge.c -@@ -18,6 +18,10 @@ - - #define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30 - -+/* Registers on Token Ring debug nodes */ -+/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x17 */ -+#define SLAVE_DSP_READY_TIME_MASK GENMASK(22, 15) -+ - /* Registers on MDIO_MMD_VEND1 */ - #define MTK_PHY_GBE_MODE_TX_DELAY_SEL 0x13 - #define MTK_PHY_TEST_MODE_TX_DELAY_SEL 0x14 -@@ -42,11 +46,8 @@ static void mtk_gephy_config_init(struct phy_device *phydev) - 0, MTK_PHY_ENABLE_DOWNSHIFT); - - /* Increase SlvDPSready time */ -- phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); -- __phy_write(phydev, 0x10, 0xafae); -- __phy_write(phydev, 0x12, 0x2f); -- __phy_write(phydev, 0x10, 0x8fae); -- phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); -+ mtk_tr_modify(phydev, 0x1, 0xf, 0x17, SLAVE_DSP_READY_TIME_MASK, -+ FIELD_PREP(SLAVE_DSP_READY_TIME_MASK, 0x5e)); - - /* Adjust 100_mse_threshold */ - phy_modify_mmd(phydev, MDIO_MMD_VEND1, -diff --git a/drivers/net/phy/mediatek/mtk-phy-lib.c b/drivers/net/phy/mediatek/mtk-phy-lib.c -index 98a09d670e9c..7275e4ee2298 100644 ---- a/drivers/net/phy/mediatek/mtk-phy-lib.c -+++ b/drivers/net/phy/mediatek/mtk-phy-lib.c -@@ -6,6 +6,69 @@ - - #include "mtk.h" - -+/* Difference between functions with mtk_tr* and __mtk_tr* prefixes is -+ * mtk_tr* functions: wrapped by page switching operations -+ * __mtk_tr* functions: no page switching operations -+ */ -+ -+static void __mtk_tr_access(struct phy_device *phydev, bool read, u8 ch_addr, -+ u8 node_addr, u8 data_addr) -+{ -+ u16 tr_cmd = BIT(15); /* bit 14 & 0 are reserved */ -+ -+ if (read) -+ tr_cmd |= BIT(13); -+ -+ tr_cmd |= (((ch_addr & 0x3) << 11) | -+ ((node_addr & 0xf) << 7) | -+ ((data_addr & 0x3f) << 1)); -+ dev_dbg(&phydev->mdio.dev, "tr_cmd: 0x%x\n", tr_cmd); -+ __phy_write(phydev, 0x10, tr_cmd); -+} -+ -+static void __mtk_tr_read(struct phy_device *phydev, u8 ch_addr, u8 node_addr, -+ u8 data_addr, u16 *tr_high, u16 *tr_low) -+{ -+ __mtk_tr_access(phydev, true, ch_addr, node_addr, data_addr); -+ *tr_low = __phy_read(phydev, 0x11); -+ *tr_high = __phy_read(phydev, 0x12); -+ dev_dbg(&phydev->mdio.dev, "tr_high read: 0x%x, tr_low read: 0x%x\n", -+ *tr_high, *tr_low); -+} -+ -+static void __mtk_tr_write(struct phy_device *phydev, u8 ch_addr, u8 node_addr, -+ u8 data_addr, u32 tr_data) -+{ -+ __phy_write(phydev, 0x11, tr_data & 0xffff); -+ __phy_write(phydev, 0x12, tr_data >> 16); -+ dev_dbg(&phydev->mdio.dev, "tr_high write: 0x%x, tr_low write: 0x%x\n", -+ tr_data >> 16, tr_data & 0xffff); -+ __mtk_tr_access(phydev, false, ch_addr, node_addr, data_addr); -+} -+ -+void __mtk_tr_modify(struct phy_device *phydev, u8 ch_addr, u8 node_addr, -+ u8 data_addr, u32 mask, u32 set) -+{ -+ u32 tr_data; -+ u16 tr_high; -+ u16 tr_low; -+ -+ __mtk_tr_read(phydev, ch_addr, node_addr, data_addr, &tr_high, &tr_low); -+ tr_data = (tr_high << 16) | tr_low; -+ tr_data = (tr_data & ~mask) | set; -+ __mtk_tr_write(phydev, ch_addr, node_addr, data_addr, tr_data); -+} -+EXPORT_SYMBOL_GPL(__mtk_tr_modify); -+ -+void mtk_tr_modify(struct phy_device *phydev, u8 ch_addr, u8 node_addr, -+ u8 data_addr, u32 mask, u32 set) -+{ -+ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); -+ __mtk_tr_modify(phydev, ch_addr, node_addr, data_addr, mask, set); -+ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); -+} -+EXPORT_SYMBOL_GPL(mtk_tr_modify); -+ - int mtk_phy_read_page(struct phy_device *phydev) - { - return __phy_read(phydev, MTK_EXT_PAGE_ACCESS); -diff --git a/drivers/net/phy/mediatek/mtk.h b/drivers/net/phy/mediatek/mtk.h -index a888e2e1dd6b..af44d1ad8c9e 100644 ---- a/drivers/net/phy/mediatek/mtk.h -+++ b/drivers/net/phy/mediatek/mtk.h -@@ -68,6 +68,11 @@ struct mtk_socphy_priv { - unsigned long led_state; - }; - -+void __mtk_tr_modify(struct phy_device *phydev, u8 ch_addr, u8 node_addr, -+ u8 data_addr, u32 mask, u32 set); -+void mtk_tr_modify(struct phy_device *phydev, u8 ch_addr, u8 node_addr, -+ u8 data_addr, u32 mask, u32 set); -+ - int mtk_phy_read_page(struct phy_device *phydev); - int mtk_phy_write_page(struct phy_device *phydev, int page); - --- -2.51.0 - - -From 3452f1a79d2394d16043c7d1ac424f16db88c232 Mon Sep 17 00:00:00 2001 -From: Sky Huang -Date: Thu, 13 Feb 2025 16:05:51 +0800 -Subject: [PATCH 078/517] net: phy: mediatek: Add token ring set bit operation - support - -Previously in mtk-ge-soc.c, we set some register bits via token -ring, which were implemented in three __phy_write(). -Now we can do the same thing via __mtk_tr_set_bits() helper. - -Signed-off-by: Sky Huang -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/20250213080553.921434-4-SkyLake.Huang@mediatek.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/mediatek/mtk-ge-soc.c | 10 ++++++---- - drivers/net/phy/mediatek/mtk-phy-lib.c | 7 +++++++ - drivers/net/phy/mediatek/mtk.h | 2 ++ - 3 files changed, 15 insertions(+), 4 deletions(-) - -diff --git a/drivers/net/phy/mediatek/mtk-ge-soc.c b/drivers/net/phy/mediatek/mtk-ge-soc.c -index 5d7373793659..37777ad104d8 100644 ---- a/drivers/net/phy/mediatek/mtk-ge-soc.c -+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c -@@ -62,6 +62,10 @@ - /* MasDSPreadyTime */ - #define MASTER_DSP_READY_TIME_MASK GENMASK(14, 7) - -+/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x18 */ -+/* EnabRandUpdTrig */ -+#define ENABLE_RANDOM_UPDOWN_COUNTER_TRIGGER BIT(8) -+ - /* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x20 */ - /* ResetSyncOffset */ - #define RESET_SYNC_OFFSET_MASK GENMASK(11, 8) -@@ -789,10 +793,8 @@ static void mt798x_phy_common_finetune(struct phy_device *phydev) - FIELD_PREP(SLAVE_DSP_READY_TIME_MASK, 0x18) | - FIELD_PREP(MASTER_DSP_READY_TIME_MASK, 0x18)); - -- /* EnabRandUpdTrig = 1 */ -- __phy_write(phydev, 0x11, 0x2f00); -- __phy_write(phydev, 0x12, 0xe); -- __phy_write(phydev, 0x10, 0x8fb0); -+ __mtk_tr_set_bits(phydev, 0x1, 0xf, 0x18, -+ ENABLE_RANDOM_UPDOWN_COUNTER_TRIGGER); - - __mtk_tr_modify(phydev, 0x0, 0x7, 0x15, - NORMAL_MSE_LO_THRESH_MASK, -diff --git a/drivers/net/phy/mediatek/mtk-phy-lib.c b/drivers/net/phy/mediatek/mtk-phy-lib.c -index 7275e4ee2298..df8fdadcc0f4 100644 ---- a/drivers/net/phy/mediatek/mtk-phy-lib.c -+++ b/drivers/net/phy/mediatek/mtk-phy-lib.c -@@ -69,6 +69,13 @@ void mtk_tr_modify(struct phy_device *phydev, u8 ch_addr, u8 node_addr, - } - EXPORT_SYMBOL_GPL(mtk_tr_modify); - -+void __mtk_tr_set_bits(struct phy_device *phydev, u8 ch_addr, u8 node_addr, -+ u8 data_addr, u32 set) -+{ -+ __mtk_tr_modify(phydev, ch_addr, node_addr, data_addr, 0, set); -+} -+EXPORT_SYMBOL_GPL(__mtk_tr_set_bits); -+ - int mtk_phy_read_page(struct phy_device *phydev) - { - return __phy_read(phydev, MTK_EXT_PAGE_ACCESS); -diff --git a/drivers/net/phy/mediatek/mtk.h b/drivers/net/phy/mediatek/mtk.h -index af44d1ad8c9e..2d8e5b934a02 100644 ---- a/drivers/net/phy/mediatek/mtk.h -+++ b/drivers/net/phy/mediatek/mtk.h -@@ -72,6 +72,8 @@ void __mtk_tr_modify(struct phy_device *phydev, u8 ch_addr, u8 node_addr, - u8 data_addr, u32 mask, u32 set); - void mtk_tr_modify(struct phy_device *phydev, u8 ch_addr, u8 node_addr, - u8 data_addr, u32 mask, u32 set); -+void __mtk_tr_set_bits(struct phy_device *phydev, u8 ch_addr, u8 node_addr, -+ u8 data_addr, u32 set); - - int mtk_phy_read_page(struct phy_device *phydev); - int mtk_phy_write_page(struct phy_device *phydev, int page); --- -2.51.0 - - -From ed0b08bbd81086c8298ae9dee01d0d935a74f374 Mon Sep 17 00:00:00 2001 -From: Sky Huang -Date: Thu, 13 Feb 2025 16:05:52 +0800 -Subject: [PATCH 079/517] net: phy: mediatek: Add token ring clear bit - operation support - -Similar to __mtk_tr_set_bits() support. Previously in mtk-ge-soc.c, -we clear some register bits via token ring, which were also implemented -in three __phy_write(). Now we can do the same thing via -__mtk_tr_clr_bits() helper. - -Signed-off-by: Sky Huang -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/20250213080553.921434-5-SkyLake.Huang@mediatek.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/mediatek/mtk-ge-soc.c | 30 +++++++++++++++----------- - drivers/net/phy/mediatek/mtk-phy-lib.c | 7 ++++++ - drivers/net/phy/mediatek/mtk.h | 2 ++ - 3 files changed, 27 insertions(+), 12 deletions(-) - -diff --git a/drivers/net/phy/mediatek/mtk-ge-soc.c b/drivers/net/phy/mediatek/mtk-ge-soc.c -index 37777ad104d8..9de6fbb45564 100644 ---- a/drivers/net/phy/mediatek/mtk-ge-soc.c -+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c -@@ -76,6 +76,10 @@ - /* FfeUpdGainForce */ - #define FFE_UPDATE_GAIN_FORCE BIT(6) - -+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x3 */ -+/* TrFreeze */ -+#define TR_FREEZE_MASK GENMASK(11, 0) -+ - /* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x6 */ - /* SS: Steady-state, KP: Proportional Gain */ - /* SSTrKp100 */ -@@ -91,6 +95,11 @@ - /* SSTrKf1000Slv */ - #define SS_TR_KF1000_SLAVE_MASK GENMASK(6, 4) - -+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x8 */ -+/* clear this bit if wanna select from AFE */ -+/* Regsigdet_sel_1000 */ -+#define EEE1000_SELECT_SIGNAL_DETECTION_FROM_DFE BIT(4) -+ - /* ch_addr = 0x2, node_addr = 0xd, data_addr = 0xd */ - /* RegEEE_st2TrKf1000 */ - #define EEE1000_STAGE2_TR_KF_MASK GENMASK(13, 11) -@@ -113,6 +122,10 @@ - /* RegEEE100Stg1_tar */ - #define EEE100_LPSYNC_STAGE1_UPDATE_TIMER_MASK GENMASK(8, 0) - -+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x25 */ -+/* REGEEE_wake_slv_tr_wait_dfesigdet_en */ -+#define WAKE_SLAVE_TR_WAIT_DFE_DETECTION_EN BIT(11) -+ - #define ANALOG_INTERNAL_OPERATION_MAX_US 20 - #define TXRESERVE_MIN 0 - #define TXRESERVE_MAX 7 -@@ -805,10 +818,7 @@ static void mt798x_phy_common_finetune(struct phy_device *phydev) - FIELD_PREP(FFE_UPDATE_GAIN_FORCE_VAL_MASK, 0x4) | - FFE_UPDATE_GAIN_FORCE); - -- /* TrFreeze = 0 (mt7988 default) */ -- __phy_write(phydev, 0x11, 0x0); -- __phy_write(phydev, 0x12, 0x0); -- __phy_write(phydev, 0x10, 0x9686); -+ __mtk_tr_clr_bits(phydev, 0x2, 0xd, 0x3, TR_FREEZE_MASK); - - __mtk_tr_modify(phydev, 0x2, 0xd, 0x6, - SS_TR_KP100_MASK | SS_TR_KF100_MASK | -@@ -1009,10 +1019,8 @@ static void mt798x_phy_eee(struct phy_device *phydev) - MTK_PHY_TR_READY_SKIP_AFE_WAKEUP); - - phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); -- /* Regsigdet_sel_1000 = 0 */ -- __phy_write(phydev, 0x11, 0xb); -- __phy_write(phydev, 0x12, 0x0); -- __phy_write(phydev, 0x10, 0x9690); -+ __mtk_tr_clr_bits(phydev, 0x2, 0xd, 0x8, -+ EEE1000_SELECT_SIGNAL_DETECTION_FROM_DFE); - - __mtk_tr_modify(phydev, 0x2, 0xd, 0xd, - EEE1000_STAGE2_TR_KF_MASK, -@@ -1036,10 +1044,8 @@ static void mt798x_phy_eee(struct phy_device *phydev) - FIELD_PREP(EEE100_LPSYNC_STAGE1_UPDATE_TIMER_MASK, - 0x10)); - -- /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 0 */ -- __phy_write(phydev, 0x11, 0x1463); -- __phy_write(phydev, 0x12, 0x0); -- __phy_write(phydev, 0x10, 0x96ca); -+ __mtk_tr_clr_bits(phydev, 0x2, 0xd, 0x25, -+ WAKE_SLAVE_TR_WAIT_DFE_DETECTION_EN); - - __mtk_tr_modify(phydev, 0x1, 0xf, 0x0, - DFE_TAIL_EANBLE_VGA_TRHESH_1000, -diff --git a/drivers/net/phy/mediatek/mtk-phy-lib.c b/drivers/net/phy/mediatek/mtk-phy-lib.c -index df8fdadcc0f4..dfd0f4e439a2 100644 ---- a/drivers/net/phy/mediatek/mtk-phy-lib.c -+++ b/drivers/net/phy/mediatek/mtk-phy-lib.c -@@ -76,6 +76,13 @@ void __mtk_tr_set_bits(struct phy_device *phydev, u8 ch_addr, u8 node_addr, - } - EXPORT_SYMBOL_GPL(__mtk_tr_set_bits); - -+void __mtk_tr_clr_bits(struct phy_device *phydev, u8 ch_addr, u8 node_addr, -+ u8 data_addr, u32 clr) -+{ -+ __mtk_tr_modify(phydev, ch_addr, node_addr, data_addr, clr, 0); -+} -+EXPORT_SYMBOL_GPL(__mtk_tr_clr_bits); -+ - int mtk_phy_read_page(struct phy_device *phydev) - { - return __phy_read(phydev, MTK_EXT_PAGE_ACCESS); -diff --git a/drivers/net/phy/mediatek/mtk.h b/drivers/net/phy/mediatek/mtk.h -index 2d8e5b934a02..4e4468dc0234 100644 ---- a/drivers/net/phy/mediatek/mtk.h -+++ b/drivers/net/phy/mediatek/mtk.h -@@ -74,6 +74,8 @@ void mtk_tr_modify(struct phy_device *phydev, u8 ch_addr, u8 node_addr, - u8 data_addr, u32 mask, u32 set); - void __mtk_tr_set_bits(struct phy_device *phydev, u8 ch_addr, u8 node_addr, - u8 data_addr, u32 set); -+void __mtk_tr_clr_bits(struct phy_device *phydev, u8 ch_addr, u8 node_addr, -+ u8 data_addr, u32 clr); - - int mtk_phy_read_page(struct phy_device *phydev); - int mtk_phy_write_page(struct phy_device *phydev, int page); --- -2.51.0 - - -From d3ad9045643e6c80993d9e1e033bf6fc8b4c35a5 Mon Sep 17 00:00:00 2001 -From: Sky Huang -Date: Thu, 13 Feb 2025 16:05:53 +0800 -Subject: [PATCH 080/517] net: phy: mediatek: Move some macros to phy-lib for - later use - -Move some macros to phy-lib because MediaTek's 2.5G built-in -ethernet PHY will also use them. - -Signed-off-by: Sky Huang -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/20250213080553.921434-6-SkyLake.Huang@mediatek.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/mediatek/mtk-ge.c | 4 ---- - drivers/net/phy/mediatek/mtk.h | 4 ++++ - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/drivers/net/phy/mediatek/mtk-ge.c b/drivers/net/phy/mediatek/mtk-ge.c -index a24c5ba469ba..73d9b72f9d9e 100644 ---- a/drivers/net/phy/mediatek/mtk-ge.c -+++ b/drivers/net/phy/mediatek/mtk-ge.c -@@ -8,10 +8,6 @@ - #define MTK_GPHY_ID_MT7530 0x03a29412 - #define MTK_GPHY_ID_MT7531 0x03a29441 - --#define MTK_PHY_PAGE_EXTENDED_1 0x0001 --#define MTK_PHY_AUX_CTRL_AND_STATUS 0x14 --#define MTK_PHY_ENABLE_DOWNSHIFT BIT(4) -- - #define MTK_PHY_PAGE_EXTENDED_2 0x0002 - #define MTK_PHY_PAGE_EXTENDED_3 0x0003 - #define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG11 0x11 -diff --git a/drivers/net/phy/mediatek/mtk.h b/drivers/net/phy/mediatek/mtk.h -index 4e4468dc0234..320f76ffa81f 100644 ---- a/drivers/net/phy/mediatek/mtk.h -+++ b/drivers/net/phy/mediatek/mtk.h -@@ -8,7 +8,11 @@ - #ifndef _MTK_EPHY_H_ - #define _MTK_EPHY_H_ - -+#define MTK_PHY_AUX_CTRL_AND_STATUS 0x14 -+#define MTK_PHY_ENABLE_DOWNSHIFT BIT(4) -+ - #define MTK_EXT_PAGE_ACCESS 0x1f -+#define MTK_PHY_PAGE_EXTENDED_1 0x0001 - #define MTK_PHY_PAGE_STANDARD 0x0000 - #define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5 - --- -2.51.0 - - -From af060cc711880b488a95c56cf7e0fb28f2e71b22 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 10 Apr 2025 12:04:03 +0200 -Subject: [PATCH 081/517] net: phy: mediatek: permit to compile test GE SOC PHY - driver - -When commit 462a3daad679 ("net: phy: mediatek: fix compile-test -dependencies") fixed the dependency, it should have also introduced -an or on COMPILE_TEST to permit this driver to be compile-tested even if -NVMEM_MTK_EFUSE wasn't selected. The driver makes use of NVMEM API that -are always compiled (return error) so the driver can actually be -compiled even without that config. - -Fix and simplify the dependency condition of this kernel config. - -Fixes: 462a3daad679 ("net: phy: mediatek: fix compile-test dependencies") -Acked-by: Daniel Golle -Reviewed-by: Andrew Lunn -Signed-off-by: Christian Marangi -Acked-by: Arnd Bergmann -Link: https://patch.msgid.link/20250410100410.348-1-ansuelsmth@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/mediatek/Kconfig | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/drivers/net/phy/mediatek/Kconfig b/drivers/net/phy/mediatek/Kconfig -index 2a8ac5aed0f8..6a4c2b328c41 100644 ---- a/drivers/net/phy/mediatek/Kconfig -+++ b/drivers/net/phy/mediatek/Kconfig -@@ -15,8 +15,7 @@ config MEDIATEK_GE_PHY - - config MEDIATEK_GE_SOC_PHY - tristate "MediaTek SoC Ethernet PHYs" -- depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST -- depends on NVMEM_MTK_EFUSE -+ depends on (ARM64 && ARCH_MEDIATEK && NVMEM_MTK_EFUSE) || COMPILE_TEST - select MTK_NET_PHYLIB - help - Supports MediaTek SoC built-in Gigabit Ethernet PHYs. --- -2.51.0 - - -From 42073f8fa909d98142b7754ce0f020d96b0bf48e Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 10 Apr 2025 12:04:04 +0200 -Subject: [PATCH 082/517] net: phy: mediatek: add Airoha PHY ID to SoC driver - -Airoha AN7581 SoC ship with a Switch based on the MT753x Switch embedded -in other SoC like the MT7581 and the MT7988. Similar to these they -require configuring some pin to enable LED PHYs. - -Add support for the PHY ID for the Airoha embedded Switch and define a -simple probe function to toggle these pins. Also fill the LED functions -and add dedicated function to define LED polarity. - -Reviewed-by: Andrew Lunn -Signed-off-by: Christian Marangi -Link: https://patch.msgid.link/20250410100410.348-2-ansuelsmth@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/mediatek/Kconfig | 4 +- - drivers/net/phy/mediatek/mtk-ge-soc.c | 62 +++++++++++++++++++++++++++ - 2 files changed, 65 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/phy/mediatek/Kconfig b/drivers/net/phy/mediatek/Kconfig -index 6a4c2b328c41..4308002bb82c 100644 ---- a/drivers/net/phy/mediatek/Kconfig -+++ b/drivers/net/phy/mediatek/Kconfig -@@ -15,7 +15,9 @@ config MEDIATEK_GE_PHY - - config MEDIATEK_GE_SOC_PHY - tristate "MediaTek SoC Ethernet PHYs" -- depends on (ARM64 && ARCH_MEDIATEK && NVMEM_MTK_EFUSE) || COMPILE_TEST -+ depends on ARM64 || COMPILE_TEST -+ depends on ARCH_AIROHA || (ARCH_MEDIATEK && NVMEM_MTK_EFUSE) || \ -+ COMPILE_TEST - select MTK_NET_PHYLIB - help - Supports MediaTek SoC built-in Gigabit Ethernet PHYs. -diff --git a/drivers/net/phy/mediatek/mtk-ge-soc.c b/drivers/net/phy/mediatek/mtk-ge-soc.c -index 9de6fbb45564..fea2a55764f1 100644 ---- a/drivers/net/phy/mediatek/mtk-ge-soc.c -+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c -@@ -10,8 +10,11 @@ - - #include "mtk.h" - -+#define MTK_PHY_MAX_LEDS 2 -+ - #define MTK_GPHY_ID_MT7981 0x03a29461 - #define MTK_GPHY_ID_MT7988 0x03a29481 -+#define MTK_GPHY_ID_AN7581 0x03a294c1 - - #define MTK_EXT_PAGE_ACCESS 0x1f - #define MTK_PHY_PAGE_STANDARD 0x0000 -@@ -1405,6 +1408,53 @@ static int mt7981_phy_probe(struct phy_device *phydev) - return mt798x_phy_calibration(phydev); - } - -+static int an7581_phy_probe(struct phy_device *phydev) -+{ -+ struct mtk_socphy_priv *priv; -+ struct pinctrl *pinctrl; -+ -+ /* Toggle pinctrl to enable PHY LED */ -+ pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "gbe-led"); -+ if (IS_ERR(pinctrl)) -+ dev_err(&phydev->mdio.bus->dev, -+ "Failed to setup PHY LED pinctrl\n"); -+ -+ priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ phydev->priv = priv; -+ -+ return 0; -+} -+ -+static int an7581_phy_led_polarity_set(struct phy_device *phydev, int index, -+ unsigned long modes) -+{ -+ u32 mode; -+ u16 val; -+ -+ if (index >= MTK_PHY_MAX_LEDS) -+ return -EINVAL; -+ -+ for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) { -+ switch (mode) { -+ case PHY_LED_ACTIVE_LOW: -+ val = MTK_PHY_LED_ON_POLARITY; -+ break; -+ case PHY_LED_ACTIVE_HIGH: -+ val = 0; -+ break; -+ default: -+ return -EINVAL; -+ } -+ } -+ -+ return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ? -+ MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL, -+ MTK_PHY_LED_ON_POLARITY, val); -+} -+ - static struct phy_driver mtk_socphy_driver[] = { - { - PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981), -@@ -1440,6 +1490,17 @@ static struct phy_driver mtk_socphy_driver[] = { - .led_hw_control_set = mt798x_phy_led_hw_control_set, - .led_hw_control_get = mt798x_phy_led_hw_control_get, - }, -+ { -+ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_AN7581), -+ .name = "Airoha AN7581 PHY", -+ .probe = an7581_phy_probe, -+ .led_blink_set = mt798x_phy_led_blink_set, -+ .led_brightness_set = mt798x_phy_led_brightness_set, -+ .led_hw_is_supported = mt798x_phy_led_hw_is_supported, -+ .led_hw_control_set = mt798x_phy_led_hw_control_set, -+ .led_hw_control_get = mt798x_phy_led_hw_control_get, -+ .led_polarity_set = an7581_phy_led_polarity_set, -+ }, - }; - - module_phy_driver(mtk_socphy_driver); -@@ -1447,6 +1508,7 @@ module_phy_driver(mtk_socphy_driver); - static const struct mdio_device_id __maybe_unused mtk_socphy_tbl[] = { - { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981) }, - { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988) }, -+ { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_AN7581) }, - { } - }; - --- -2.51.0 - - -From 1b9be68d030e01f77d09abc1307fb7abb7f3a351 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 15 Apr 2025 12:53:05 +0200 -Subject: [PATCH 083/517] net: phy: mediatek: init val in .phy_led_polarity_set - for AN7581 - -Fix smatch warning for uninitialised val in .phy_led_polarity_set for -AN7581 driver. - -Correctly init to 0 to set polarity high by default. - -Reported-by: Simon Horman -Fixes: 6a325aed130b ("net: phy: mediatek: add Airoha PHY ID to SoC driver") -Signed-off-by: Christian Marangi -Link: https://patch.msgid.link/20250415105313.3409-1-ansuelsmth@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/mediatek/mtk-ge-soc.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/drivers/net/phy/mediatek/mtk-ge-soc.c b/drivers/net/phy/mediatek/mtk-ge-soc.c -index fea2a55764f1..6be49447d10d 100644 ---- a/drivers/net/phy/mediatek/mtk-ge-soc.c -+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c -@@ -1431,8 +1431,8 @@ static int an7581_phy_probe(struct phy_device *phydev) - static int an7581_phy_led_polarity_set(struct phy_device *phydev, int index, - unsigned long modes) - { -+ u16 val = 0; - u32 mode; -- u16 val; - - if (index >= MTK_PHY_MAX_LEDS) - return -EINVAL; -@@ -1443,7 +1443,6 @@ static int an7581_phy_led_polarity_set(struct phy_device *phydev, int index, - val = MTK_PHY_LED_ON_POLARITY; - break; - case PHY_LED_ACTIVE_HIGH: -- val = 0; - break; - default: - return -EINVAL; --- -2.51.0 - - -From 613f6f7764030e9abaace9416e36333b26dbbd65 Mon Sep 17 00:00:00 2001 -From: Qingfang Deng -Date: Mon, 17 Feb 2025 17:40:21 +0800 -Subject: [PATCH 084/517] net: ethernet: mediatek: add EEE support - -Add EEE support to MediaTek SoC Ethernet. The register fields are -similar to the ones in MT7531, except that the LPI threshold is in -milliseconds. - -Signed-off-by: Qingfang Deng ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 69 +++++++++++++++++++++ - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 13 ++++ - 2 files changed, 82 insertions(+) - -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -index 64d86068b51e..2a0be107b3d7 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -782,6 +782,7 @@ static void mtk_mac_link_up(struct phylink_config *config, - - mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); - mcr &= ~(MAC_MCR_SPEED_100 | MAC_MCR_SPEED_1000 | -+ MAC_MCR_EEE100M | MAC_MCR_EEE1G | - MAC_MCR_FORCE_DPX | MAC_MCR_FORCE_TX_FC | - MAC_MCR_FORCE_RX_FC); - -@@ -807,6 +808,15 @@ static void mtk_mac_link_up(struct phylink_config *config, - if (rx_pause) - mcr |= MAC_MCR_FORCE_RX_FC; - -+ if (mode == MLO_AN_PHY && phy && mac->tx_lpi_enabled && phy_init_eee(phy, false) >= 0) { -+ mcr |= MAC_MCR_EEE100M | MAC_MCR_EEE1G; -+ mtk_w32(mac->hw, -+ FIELD_PREP(MAC_EEE_WAKEUP_TIME_1000, 17) | -+ FIELD_PREP(MAC_EEE_WAKEUP_TIME_100, 36) | -+ FIELD_PREP(MAC_EEE_LPI_TXIDLE_THD, mac->txidle_thd_ms), -+ MTK_MAC_EEECR(mac->id)); -+ } -+ - mcr |= MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK; - mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); - } -@@ -4514,6 +4524,61 @@ static int mtk_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam - return phylink_ethtool_set_pauseparam(mac->phylink, pause); - } - -+static int mtk_get_eee(struct net_device *dev, struct ethtool_keee *eee) -+{ -+ struct mtk_mac *mac = netdev_priv(dev); -+ u32 reg; -+ int ret; -+ -+ ret = phylink_ethtool_get_eee(mac->phylink, eee); -+ if (ret) -+ return ret; -+ -+ reg = mtk_r32(mac->hw, MTK_MAC_EEECR(mac->id)); -+ eee->tx_lpi_enabled = mac->tx_lpi_enabled; -+ eee->tx_lpi_timer = FIELD_GET(MAC_EEE_LPI_TXIDLE_THD, reg) * 1000; -+ -+ return 0; -+} -+ -+static int mtk_set_eee(struct net_device *dev, struct ethtool_keee *eee) -+{ -+ struct mtk_mac *mac = netdev_priv(dev); -+ u32 txidle_thd_ms, reg; -+ int ret; -+ -+ /* Tx idle timer in ms */ -+ txidle_thd_ms = DIV_ROUND_UP(eee->tx_lpi_timer, 1000); -+ if (!FIELD_FIT(MAC_EEE_LPI_TXIDLE_THD, txidle_thd_ms)) -+ return -EINVAL; -+ -+ reg = FIELD_PREP(MAC_EEE_LPI_TXIDLE_THD, txidle_thd_ms); -+ -+ /* PHY Wake-up time, this field does not have a reset value, so use the -+ * reset value from MT7531 (36us for 100BaseT and 17us for 1000BaseT). -+ */ -+ reg |= FIELD_PREP(MAC_EEE_WAKEUP_TIME_1000, 17) | -+ FIELD_PREP(MAC_EEE_WAKEUP_TIME_100, 36); -+ -+ if (!txidle_thd_ms) -+ /* Force LPI Mode without a delay */ -+ reg |= MAC_EEE_LPI_MODE; -+ -+ ret = phylink_ethtool_set_eee(mac->phylink, eee); -+ if (ret) -+ return ret; -+ -+ mac->tx_lpi_enabled = eee->tx_lpi_enabled; -+ mac->txidle_thd_ms = txidle_thd_ms; -+ mtk_w32(mac->hw, reg, MTK_MAC_EEECR(mac->id)); -+ if (eee->eee_enabled && eee->eee_active && eee->tx_lpi_enabled) -+ mtk_m32(mac->hw, 0, MAC_MCR_EEE100M | MAC_MCR_EEE1G, MTK_MAC_MCR(mac->id)); -+ else -+ mtk_m32(mac->hw, MAC_MCR_EEE100M | MAC_MCR_EEE1G, 0, MTK_MAC_MCR(mac->id)); -+ -+ return 0; -+} -+ - static u16 mtk_select_queue(struct net_device *dev, struct sk_buff *skb, - struct net_device *sb_dev) - { -@@ -4546,6 +4611,8 @@ static const struct ethtool_ops mtk_ethtool_ops = { - .set_pauseparam = mtk_set_pauseparam, - .get_rxnfc = mtk_get_rxnfc, - .set_rxnfc = mtk_set_rxnfc, -+ .get_eee = mtk_get_eee, -+ .set_eee = mtk_set_eee, - }; - - static const struct net_device_ops mtk_netdev_ops = { -@@ -4606,6 +4673,8 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) - } - mac = netdev_priv(eth->netdev[id]); - eth->mac[id] = mac; -+ mac->tx_lpi_enabled = true; -+ mac->txidle_thd_ms = 1; - mac->id = id; - mac->hw = eth; - mac->of_node = np; -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -index 0570623e569d..723475570ff7 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -461,6 +461,8 @@ - #define MAC_MCR_RX_FIFO_CLR_DIS BIT(12) - #define MAC_MCR_BACKOFF_EN BIT(9) - #define MAC_MCR_BACKPR_EN BIT(8) -+#define MAC_MCR_EEE1G BIT(7) -+#define MAC_MCR_EEE100M BIT(6) - #define MAC_MCR_FORCE_RX_FC BIT(5) - #define MAC_MCR_FORCE_TX_FC BIT(4) - #define MAC_MCR_SPEED_1000 BIT(3) -@@ -469,6 +471,15 @@ - #define MAC_MCR_FORCE_LINK BIT(0) - #define MAC_MCR_FORCE_LINK_DOWN (MAC_MCR_FORCE_MODE) - -+/* Mac EEE control registers */ -+#define MTK_MAC_EEECR(x) (0x10104 + (x * 0x100)) -+#define MAC_EEE_WAKEUP_TIME_1000 GENMASK(31, 24) -+#define MAC_EEE_WAKEUP_TIME_100 GENMASK(23, 16) -+#define MAC_EEE_LPI_TXIDLE_THD GENMASK(15, 8) -+#define MAC_EEE_CKG_TXIDLE BIT(3) -+#define MAC_EEE_CKG_RXLPI BIT(2) -+#define MAC_EEE_LPI_MODE BIT(0) -+ - /* Mac status registers */ - #define MTK_MAC_MSR(x) (0x10108 + (x * 0x100)) - #define MAC_MSR_EEE1G BIT(7) -@@ -1316,6 +1327,8 @@ struct mtk_mac { - int id; - phy_interface_t interface; - u8 ppe_idx; -+ bool tx_lpi_enabled; -+ u8 txidle_thd_ms; - int speed; - struct device_node *of_node; - struct phylink *phylink; --- -2.51.0 - - -From 14f7dbcdc4a40f631df9774ef69d7ba583ad830d Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Fri, 4 Oct 2024 17:18:16 +0100 -Subject: [PATCH 085/517] net: phy: aquantia: allow forcing order of MDI pairs - -Despite supporting Auto MDI-X, it looks like Aquantia only supports -swapping pair (1,2) with pair (3,6) like it used to be for MDI-X on -100MBit/s networks. - -When all 4 pairs are in use (for 1000MBit/s or faster) the link does not -come up with pair order is not configured correctly, either using -MDI_CFG pin or using the "PMA Receive Reserved Vendor Provisioning 1" -register. - -Normally, the order of MDI pairs being either ABCD or DCBA is configured -by pulling the MDI_CFG pin. - -However, some hardware designs require overriding the value configured -by that bootstrap pin. The PHY allows doing that by setting a bit in -"PMA Receive Reserved Vendor Provisioning 1" register which allows -ignoring the state of the MDI_CFG pin and another bit configuring -whether the order of MDI pairs should be normal (ABCD) or reverse -(DCBA). Pair polarity is not affected and remains identical in both -settings. - -Introduce property "marvell,mdi-cfg-order" which allows forcing either -normal or reverse order of the MDI pairs from DT. - -If the property isn't present, the behavior is unchanged and MDI pair -order configuration is untouched (ie. either the result of MDI_CFG pin -pull-up/pull-down, or pair order override already configured by the -bootloader before Linux is started). - -Forcing normal pair order is required on the Adtran SDG-8733A Wi-Fi 7 -residential gateway. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/9ed760ff87d5fc456f31e407ead548bbb754497d.1728058550.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/aquantia/aquantia_main.c | 33 ++++++++++++++++++++++++ - 1 file changed, 33 insertions(+) - -diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c -index 840ef5ad07ff..5cdc16fade22 100644 ---- a/drivers/net/phy/aquantia/aquantia_main.c -+++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - #include - - #include "aquantia.h" -@@ -71,6 +72,11 @@ - #define MDIO_AN_TX_VEND_INT_MASK2 0xd401 - #define MDIO_AN_TX_VEND_INT_MASK2_LINK BIT(0) - -+#define PMAPMD_RSVD_VEND_PROV 0xe400 -+#define PMAPMD_RSVD_VEND_PROV_MDI_CONF GENMASK(1, 0) -+#define PMAPMD_RSVD_VEND_PROV_MDI_REVERSE BIT(0) -+#define PMAPMD_RSVD_VEND_PROV_MDI_FORCE BIT(1) -+ - #define MDIO_AN_RX_LP_STAT1 0xe820 - #define MDIO_AN_RX_LP_STAT1_1000BASET_FULL BIT(15) - #define MDIO_AN_RX_LP_STAT1_1000BASET_HALF BIT(14) -@@ -485,6 +491,29 @@ static void aqr107_chip_info(struct phy_device *phydev) - fw_major, fw_minor, build_id, prov_id); - } - -+static int aqr107_config_mdi(struct phy_device *phydev) -+{ -+ struct device_node *np = phydev->mdio.dev.of_node; -+ u32 mdi_conf; -+ int ret; -+ -+ ret = of_property_read_u32(np, "marvell,mdi-cfg-order", &mdi_conf); -+ -+ /* Do nothing in case property "marvell,mdi-cfg-order" is not present */ -+ if (ret == -ENOENT) -+ return 0; -+ -+ if (ret) -+ return ret; -+ -+ if (mdi_conf & ~PMAPMD_RSVD_VEND_PROV_MDI_REVERSE) -+ return -EINVAL; -+ -+ return phy_modify_mmd(phydev, MDIO_MMD_PMAPMD, PMAPMD_RSVD_VEND_PROV, -+ PMAPMD_RSVD_VEND_PROV_MDI_CONF, -+ mdi_conf | PMAPMD_RSVD_VEND_PROV_MDI_FORCE); -+} -+ - static int aqr107_config_init(struct phy_device *phydev) - { - struct aqr107_priv *priv = phydev->priv; -@@ -514,6 +543,10 @@ static int aqr107_config_init(struct phy_device *phydev) - if (ret) - return ret; - -+ ret = aqr107_config_mdi(phydev); -+ if (ret) -+ return ret; -+ - /* Restore LED polarity state after reset */ - for_each_set_bit(led_active_low, &priv->leds_active_low, AQR_MAX_LEDS) { - ret = aqr_phy_led_active_low_set(phydev, led_active_low, true); --- -2.51.0 - - -From 4894e830a84456398eef38e8084612ae21934af3 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Fri, 11 Oct 2024 22:28:43 +0100 -Subject: [PATCH 086/517] net: phy: aquantia: fix return value check in - aqr107_config_mdi() - -of_property_read_u32() returns -EINVAL in case the property cannot be -found rather than -ENOENT. Fix the check to not abort probing in case -of the property being missing, and also in case CONFIG_OF is not set -which will result in -ENOSYS. - -Fixes: a2e1ba275eae ("net: phy: aquantia: allow forcing order of MDI pairs") -Reported-by: Jon Hunter -Closes: https://lore.kernel.org/all/114b4c03-5d16-42ed-945d-cf78eabea12b@nvidia.com/ -Suggested-by: Hans-Frieder Vogt -Signed-off-by: Daniel Golle ---- - drivers/net/phy/aquantia/aquantia_main.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c -index 5cdc16fade22..2c9bc3ea6b7e 100644 ---- a/drivers/net/phy/aquantia/aquantia_main.c -+++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -500,7 +500,7 @@ static int aqr107_config_mdi(struct phy_device *phydev) - ret = of_property_read_u32(np, "marvell,mdi-cfg-order", &mdi_conf); - - /* Do nothing in case property "marvell,mdi-cfg-order" is not present */ -- if (ret == -ENOENT) -+ if (ret == -EINVAL || ret == -ENOSYS) - return 0; - - if (ret) --- -2.51.0 - - -From 287435caf87bb50f31293db553d5a838b668c98b Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 10 Oct 2024 13:54:19 +0100 -Subject: [PATCH 087/517] net: phy: support 'active-high' property for PHY LEDs - -In addition to 'active-low' and 'inactive-high-impedance' also -support 'active-high' property for PHY LED pin configuration. -As only either 'active-high' or 'active-low' can be set at the -same time, WARN and return an error in case both are set. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/91598487773d768f254d5faf06cf65b13e972f0e.1728558223.git.daniel@makrotopia.org -Signed-off-by: Paolo Abeni ---- - drivers/net/phy/phy_device.c | 6 ++++++ - include/linux/phy.h | 5 +++-- - 2 files changed, 9 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c -index 834624a61060..762f909242b4 100644 ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -3387,11 +3387,17 @@ static int of_phy_led(struct phy_device *phydev, - if (index > U8_MAX) - return -EINVAL; - -+ if (of_property_read_bool(led, "active-high")) -+ set_bit(PHY_LED_ACTIVE_HIGH, &modes); - if (of_property_read_bool(led, "active-low")) - set_bit(PHY_LED_ACTIVE_LOW, &modes); - if (of_property_read_bool(led, "inactive-high-impedance")) - set_bit(PHY_LED_INACTIVE_HIGH_IMPEDANCE, &modes); - -+ if (WARN_ON(modes & BIT(PHY_LED_ACTIVE_LOW) && -+ modes & BIT(PHY_LED_ACTIVE_HIGH))) -+ return -EINVAL; -+ - if (modes) { - /* Return error if asked to set polarity modes but not supported */ - if (!phydev->drv->led_polarity_set) -diff --git a/include/linux/phy.h b/include/linux/phy.h -index 81c504d9850e..df147d9d302f 100644 ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -892,8 +892,9 @@ struct phy_plca_status { - - /* Modes for PHY LED configuration */ - enum phy_led_modes { -- PHY_LED_ACTIVE_LOW = 0, -- PHY_LED_INACTIVE_HIGH_IMPEDANCE = 1, -+ PHY_LED_ACTIVE_HIGH = 0, -+ PHY_LED_ACTIVE_LOW = 1, -+ PHY_LED_INACTIVE_HIGH_IMPEDANCE = 2, - - /* keep it last */ - __PHY_LED_MODES_NUM, --- -2.51.0 - - -From ade63dd8be886ca940ab87741aa9497e52fec15f Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 10 Oct 2024 13:55:00 +0100 -Subject: [PATCH 088/517] net: phy: aquantia: correctly describe LED polarity - override - -Use newly defined 'active-high' property to set the -VEND1_GLOBAL_LED_DRIVE_VDD bit and let 'active-low' clear that bit. This -reflects the technical reality which was inverted in the previous -description in which the 'active-low' property was used to actually set -the VEND1_GLOBAL_LED_DRIVE_VDD bit, which means that VDD (ie. supply -voltage) of the LED is driven rather than GND. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/86a413b4387c42dcb54f587cc2433a06f16aae83.1728558223.git.daniel@makrotopia.org -Signed-off-by: Paolo Abeni ---- - drivers/net/phy/aquantia/aquantia.h | 1 + - drivers/net/phy/aquantia/aquantia_leds.c | 19 ++++++++++++++----- - drivers/net/phy/aquantia/aquantia_main.c | 12 +++++++++--- - 3 files changed, 24 insertions(+), 8 deletions(-) - -diff --git a/drivers/net/phy/aquantia/aquantia.h b/drivers/net/phy/aquantia/aquantia.h -index 2465345081f8..0c78bfabace5 100644 ---- a/drivers/net/phy/aquantia/aquantia.h -+++ b/drivers/net/phy/aquantia/aquantia.h -@@ -177,6 +177,7 @@ static const struct aqr107_hw_stat aqr107_hw_stats[] = { - struct aqr107_priv { - u64 sgmii_stats[AQR107_SGMII_STAT_SZ]; - unsigned long leds_active_low; -+ unsigned long leds_active_high; - }; - - #if IS_REACHABLE(CONFIG_HWMON) -diff --git a/drivers/net/phy/aquantia/aquantia_leds.c b/drivers/net/phy/aquantia/aquantia_leds.c -index 201c8df93fad..00ad2313fed3 100644 ---- a/drivers/net/phy/aquantia/aquantia_leds.c -+++ b/drivers/net/phy/aquantia/aquantia_leds.c -@@ -121,13 +121,13 @@ int aqr_phy_led_active_low_set(struct phy_device *phydev, int index, bool enable - { - return phy_modify_mmd(phydev, MDIO_MMD_VEND1, AQR_LED_DRIVE(index), - VEND1_GLOBAL_LED_DRIVE_VDD, -- enable ? VEND1_GLOBAL_LED_DRIVE_VDD : 0); -+ enable ? 0 : VEND1_GLOBAL_LED_DRIVE_VDD); - } - - int aqr_phy_led_polarity_set(struct phy_device *phydev, int index, unsigned long modes) - { -+ bool force_active_low = false, force_active_high = false; - struct aqr107_priv *priv = phydev->priv; -- bool active_low = false; - u32 mode; - - if (index >= AQR_MAX_LEDS) -@@ -136,7 +136,10 @@ int aqr_phy_led_polarity_set(struct phy_device *phydev, int index, unsigned long - for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) { - switch (mode) { - case PHY_LED_ACTIVE_LOW: -- active_low = true; -+ force_active_low = true; -+ break; -+ case PHY_LED_ACTIVE_HIGH: -+ force_active_high = true; - break; - default: - return -EINVAL; -@@ -144,8 +147,14 @@ int aqr_phy_led_polarity_set(struct phy_device *phydev, int index, unsigned long - } - - /* Save LED driver vdd state to restore on SW reset */ -- if (active_low) -+ if (force_active_low) - priv->leds_active_low |= BIT(index); - -- return aqr_phy_led_active_low_set(phydev, index, active_low); -+ if (force_active_high) -+ priv->leds_active_high |= BIT(index); -+ -+ if (force_active_high || force_active_low) -+ return aqr_phy_led_active_low_set(phydev, index, force_active_low); -+ -+ unreachable(); - } -diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c -index 2c9bc3ea6b7e..2008b98c689e 100644 ---- a/drivers/net/phy/aquantia/aquantia_main.c -+++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -517,7 +517,7 @@ static int aqr107_config_mdi(struct phy_device *phydev) - static int aqr107_config_init(struct phy_device *phydev) - { - struct aqr107_priv *priv = phydev->priv; -- u32 led_active_low; -+ u32 led_idx; - int ret; - - /* Check that the PHY interface type is compatible */ -@@ -548,8 +548,14 @@ static int aqr107_config_init(struct phy_device *phydev) - return ret; - - /* Restore LED polarity state after reset */ -- for_each_set_bit(led_active_low, &priv->leds_active_low, AQR_MAX_LEDS) { -- ret = aqr_phy_led_active_low_set(phydev, led_active_low, true); -+ for_each_set_bit(led_idx, &priv->leds_active_low, AQR_MAX_LEDS) { -+ ret = aqr_phy_led_active_low_set(phydev, led_idx, true); -+ if (ret) -+ return ret; -+ } -+ -+ for_each_set_bit(led_idx, &priv->leds_active_high, AQR_MAX_LEDS) { -+ ret = aqr_phy_led_active_low_set(phydev, led_idx, false); - if (ret) - return ret; - } --- -2.51.0 - - -From a42b398e079cfe3f521ca96540d1b2c7f5ce4a57 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 1 Oct 2024 01:17:18 +0100 -Subject: [PATCH 089/517] net: phy: mxl-gpy: add basic LED support - -Add basic support for LEDs connected to MaxLinear GPY2xx and GPY115 PHYs. -The PHYs allow up to 4 LEDs to be connected. -Implement controlling LEDs in software as well as netdev trigger offloading -and LED polarity setup. - -The hardware claims to support 16 PWM brightness levels but there is no -documentation on how to use that feature, hence this is not supported. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/b6ec9050339f8244ff898898a1cecc33b13a48fc.1727741563.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/mxl-gpy.c | 218 ++++++++++++++++++++++++++++++++++++++ - 1 file changed, 218 insertions(+) - -diff --git a/drivers/net/phy/mxl-gpy.c b/drivers/net/phy/mxl-gpy.c -index d145b67a067f..9930e6167f89 100644 ---- a/drivers/net/phy/mxl-gpy.c -+++ b/drivers/net/phy/mxl-gpy.c -@@ -38,6 +38,7 @@ - #define PHY_MIISTAT 0x18 /* MII state */ - #define PHY_IMASK 0x19 /* interrupt mask */ - #define PHY_ISTAT 0x1A /* interrupt status */ -+#define PHY_LED 0x1B /* LEDs */ - #define PHY_FWV 0x1E /* firmware version */ - - #define PHY_MIISTAT_SPD_MASK GENMASK(2, 0) -@@ -61,6 +62,11 @@ - PHY_IMASK_ADSC | \ - PHY_IMASK_ANC) - -+#define GPY_MAX_LEDS 4 -+#define PHY_LED_POLARITY(idx) BIT(12 + (idx)) -+#define PHY_LED_HWCONTROL(idx) BIT(8 + (idx)) -+#define PHY_LED_ON(idx) BIT(idx) -+ - #define PHY_FWV_REL_MASK BIT(15) - #define PHY_FWV_MAJOR_MASK GENMASK(11, 8) - #define PHY_FWV_MINOR_MASK GENMASK(7, 0) -@@ -72,6 +78,23 @@ - #define PHY_MDI_MDI_X_CD 0x1 - #define PHY_MDI_MDI_X_CROSS 0x0 - -+/* LED */ -+#define VSPEC1_LED(idx) (1 + (idx)) -+#define VSPEC1_LED_BLINKS GENMASK(15, 12) -+#define VSPEC1_LED_PULSE GENMASK(11, 8) -+#define VSPEC1_LED_CON GENMASK(7, 4) -+#define VSPEC1_LED_BLINKF GENMASK(3, 0) -+ -+#define VSPEC1_LED_LINK10 BIT(0) -+#define VSPEC1_LED_LINK100 BIT(1) -+#define VSPEC1_LED_LINK1000 BIT(2) -+#define VSPEC1_LED_LINK2500 BIT(3) -+ -+#define VSPEC1_LED_TXACT BIT(0) -+#define VSPEC1_LED_RXACT BIT(1) -+#define VSPEC1_LED_COL BIT(2) -+#define VSPEC1_LED_NO_CON BIT(3) -+ - /* SGMII */ - #define VSPEC1_SGMII_CTRL 0x08 - #define VSPEC1_SGMII_CTRL_ANEN BIT(12) /* Aneg enable */ -@@ -835,6 +858,156 @@ static int gpy115_loopback(struct phy_device *phydev, bool enable) - return genphy_soft_reset(phydev); - } - -+static int gpy_led_brightness_set(struct phy_device *phydev, -+ u8 index, enum led_brightness value) -+{ -+ int ret; -+ -+ if (index >= GPY_MAX_LEDS) -+ return -EINVAL; -+ -+ /* clear HWCONTROL and set manual LED state */ -+ ret = phy_modify(phydev, PHY_LED, -+ ((value == LED_OFF) ? PHY_LED_HWCONTROL(index) : 0) | -+ PHY_LED_ON(index), -+ (value == LED_OFF) ? 0 : PHY_LED_ON(index)); -+ if (ret) -+ return ret; -+ -+ /* ToDo: set PWM brightness */ -+ -+ /* clear HW LED setup */ -+ if (value == LED_OFF) -+ return phy_write_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_LED(index), 0); -+ else -+ return 0; -+} -+ -+static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_LINK) | -+ BIT(TRIGGER_NETDEV_LINK_100) | -+ BIT(TRIGGER_NETDEV_LINK_1000) | -+ BIT(TRIGGER_NETDEV_LINK_2500) | -+ BIT(TRIGGER_NETDEV_RX) | -+ BIT(TRIGGER_NETDEV_TX)); -+ -+static int gpy_led_hw_is_supported(struct phy_device *phydev, u8 index, -+ unsigned long rules) -+{ -+ if (index >= GPY_MAX_LEDS) -+ return -EINVAL; -+ -+ /* All combinations of the supported triggers are allowed */ -+ if (rules & ~supported_triggers) -+ return -EOPNOTSUPP; -+ -+ return 0; -+} -+ -+static int gpy_led_hw_control_get(struct phy_device *phydev, u8 index, -+ unsigned long *rules) -+{ -+ int val; -+ -+ if (index >= GPY_MAX_LEDS) -+ return -EINVAL; -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_LED(index)); -+ if (val < 0) -+ return val; -+ -+ if (FIELD_GET(VSPEC1_LED_CON, val) & VSPEC1_LED_LINK10) -+ *rules |= BIT(TRIGGER_NETDEV_LINK_10); -+ -+ if (FIELD_GET(VSPEC1_LED_CON, val) & VSPEC1_LED_LINK100) -+ *rules |= BIT(TRIGGER_NETDEV_LINK_100); -+ -+ if (FIELD_GET(VSPEC1_LED_CON, val) & VSPEC1_LED_LINK1000) -+ *rules |= BIT(TRIGGER_NETDEV_LINK_1000); -+ -+ if (FIELD_GET(VSPEC1_LED_CON, val) & VSPEC1_LED_LINK2500) -+ *rules |= BIT(TRIGGER_NETDEV_LINK_2500); -+ -+ if (FIELD_GET(VSPEC1_LED_CON, val) == (VSPEC1_LED_LINK10 | -+ VSPEC1_LED_LINK100 | -+ VSPEC1_LED_LINK1000 | -+ VSPEC1_LED_LINK2500)) -+ *rules |= BIT(TRIGGER_NETDEV_LINK); -+ -+ if (FIELD_GET(VSPEC1_LED_PULSE, val) & VSPEC1_LED_TXACT) -+ *rules |= BIT(TRIGGER_NETDEV_TX); -+ -+ if (FIELD_GET(VSPEC1_LED_PULSE, val) & VSPEC1_LED_RXACT) -+ *rules |= BIT(TRIGGER_NETDEV_RX); -+ -+ return 0; -+} -+ -+static int gpy_led_hw_control_set(struct phy_device *phydev, u8 index, -+ unsigned long rules) -+{ -+ u16 val = 0; -+ int ret; -+ -+ if (index >= GPY_MAX_LEDS) -+ return -EINVAL; -+ -+ if (rules & BIT(TRIGGER_NETDEV_LINK) || -+ rules & BIT(TRIGGER_NETDEV_LINK_10)) -+ val |= FIELD_PREP(VSPEC1_LED_CON, VSPEC1_LED_LINK10); -+ -+ if (rules & BIT(TRIGGER_NETDEV_LINK) || -+ rules & BIT(TRIGGER_NETDEV_LINK_100)) -+ val |= FIELD_PREP(VSPEC1_LED_CON, VSPEC1_LED_LINK100); -+ -+ if (rules & BIT(TRIGGER_NETDEV_LINK) || -+ rules & BIT(TRIGGER_NETDEV_LINK_1000)) -+ val |= FIELD_PREP(VSPEC1_LED_CON, VSPEC1_LED_LINK1000); -+ -+ if (rules & BIT(TRIGGER_NETDEV_LINK) || -+ rules & BIT(TRIGGER_NETDEV_LINK_2500)) -+ val |= FIELD_PREP(VSPEC1_LED_CON, VSPEC1_LED_LINK2500); -+ -+ if (rules & BIT(TRIGGER_NETDEV_TX)) -+ val |= FIELD_PREP(VSPEC1_LED_PULSE, VSPEC1_LED_TXACT); -+ -+ if (rules & BIT(TRIGGER_NETDEV_RX)) -+ val |= FIELD_PREP(VSPEC1_LED_PULSE, VSPEC1_LED_RXACT); -+ -+ /* allow RX/TX pulse without link indication */ -+ if ((rules & BIT(TRIGGER_NETDEV_TX) || rules & BIT(TRIGGER_NETDEV_RX)) && -+ !(val & VSPEC1_LED_CON)) -+ val |= FIELD_PREP(VSPEC1_LED_PULSE, VSPEC1_LED_NO_CON) | VSPEC1_LED_CON; -+ -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_LED(index), val); -+ if (ret) -+ return ret; -+ -+ return phy_set_bits(phydev, PHY_LED, PHY_LED_HWCONTROL(index)); -+} -+ -+static int gpy_led_polarity_set(struct phy_device *phydev, int index, -+ unsigned long modes) -+{ -+ bool active_low = false; -+ u32 mode; -+ -+ if (index >= GPY_MAX_LEDS) -+ return -EINVAL; -+ -+ for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) { -+ switch (mode) { -+ case PHY_LED_ACTIVE_LOW: -+ active_low = true; -+ break; -+ default: -+ return -EINVAL; -+ } -+ } -+ -+ return phy_modify(phydev, PHY_LED, PHY_LED_POLARITY(index), -+ active_low ? 0 : PHY_LED_POLARITY(index)); -+} -+ - static struct phy_driver gpy_drivers[] = { - { - PHY_ID_MATCH_MODEL(PHY_ID_GPY2xx), -@@ -852,6 +1025,11 @@ static struct phy_driver gpy_drivers[] = { - .set_wol = gpy_set_wol, - .get_wol = gpy_get_wol, - .set_loopback = gpy_loopback, -+ .led_brightness_set = gpy_led_brightness_set, -+ .led_hw_is_supported = gpy_led_hw_is_supported, -+ .led_hw_control_get = gpy_led_hw_control_get, -+ .led_hw_control_set = gpy_led_hw_control_set, -+ .led_polarity_set = gpy_led_polarity_set, - }, - { - .phy_id = PHY_ID_GPY115B, -@@ -870,6 +1048,11 @@ static struct phy_driver gpy_drivers[] = { - .set_wol = gpy_set_wol, - .get_wol = gpy_get_wol, - .set_loopback = gpy115_loopback, -+ .led_brightness_set = gpy_led_brightness_set, -+ .led_hw_is_supported = gpy_led_hw_is_supported, -+ .led_hw_control_get = gpy_led_hw_control_get, -+ .led_hw_control_set = gpy_led_hw_control_set, -+ .led_polarity_set = gpy_led_polarity_set, - }, - { - PHY_ID_MATCH_MODEL(PHY_ID_GPY115C), -@@ -887,6 +1070,11 @@ static struct phy_driver gpy_drivers[] = { - .set_wol = gpy_set_wol, - .get_wol = gpy_get_wol, - .set_loopback = gpy115_loopback, -+ .led_brightness_set = gpy_led_brightness_set, -+ .led_hw_is_supported = gpy_led_hw_is_supported, -+ .led_hw_control_get = gpy_led_hw_control_get, -+ .led_hw_control_set = gpy_led_hw_control_set, -+ .led_polarity_set = gpy_led_polarity_set, - }, - { - .phy_id = PHY_ID_GPY211B, -@@ -905,6 +1093,11 @@ static struct phy_driver gpy_drivers[] = { - .set_wol = gpy_set_wol, - .get_wol = gpy_get_wol, - .set_loopback = gpy_loopback, -+ .led_brightness_set = gpy_led_brightness_set, -+ .led_hw_is_supported = gpy_led_hw_is_supported, -+ .led_hw_control_get = gpy_led_hw_control_get, -+ .led_hw_control_set = gpy_led_hw_control_set, -+ .led_polarity_set = gpy_led_polarity_set, - }, - { - PHY_ID_MATCH_MODEL(PHY_ID_GPY211C), -@@ -922,6 +1115,11 @@ static struct phy_driver gpy_drivers[] = { - .set_wol = gpy_set_wol, - .get_wol = gpy_get_wol, - .set_loopback = gpy_loopback, -+ .led_brightness_set = gpy_led_brightness_set, -+ .led_hw_is_supported = gpy_led_hw_is_supported, -+ .led_hw_control_get = gpy_led_hw_control_get, -+ .led_hw_control_set = gpy_led_hw_control_set, -+ .led_polarity_set = gpy_led_polarity_set, - }, - { - .phy_id = PHY_ID_GPY212B, -@@ -940,6 +1138,11 @@ static struct phy_driver gpy_drivers[] = { - .set_wol = gpy_set_wol, - .get_wol = gpy_get_wol, - .set_loopback = gpy_loopback, -+ .led_brightness_set = gpy_led_brightness_set, -+ .led_hw_is_supported = gpy_led_hw_is_supported, -+ .led_hw_control_get = gpy_led_hw_control_get, -+ .led_hw_control_set = gpy_led_hw_control_set, -+ .led_polarity_set = gpy_led_polarity_set, - }, - { - PHY_ID_MATCH_MODEL(PHY_ID_GPY212C), -@@ -957,6 +1160,11 @@ static struct phy_driver gpy_drivers[] = { - .set_wol = gpy_set_wol, - .get_wol = gpy_get_wol, - .set_loopback = gpy_loopback, -+ .led_brightness_set = gpy_led_brightness_set, -+ .led_hw_is_supported = gpy_led_hw_is_supported, -+ .led_hw_control_get = gpy_led_hw_control_get, -+ .led_hw_control_set = gpy_led_hw_control_set, -+ .led_polarity_set = gpy_led_polarity_set, - }, - { - .phy_id = PHY_ID_GPY215B, -@@ -975,6 +1183,11 @@ static struct phy_driver gpy_drivers[] = { - .set_wol = gpy_set_wol, - .get_wol = gpy_get_wol, - .set_loopback = gpy_loopback, -+ .led_brightness_set = gpy_led_brightness_set, -+ .led_hw_is_supported = gpy_led_hw_is_supported, -+ .led_hw_control_get = gpy_led_hw_control_get, -+ .led_hw_control_set = gpy_led_hw_control_set, -+ .led_polarity_set = gpy_led_polarity_set, - }, - { - PHY_ID_MATCH_MODEL(PHY_ID_GPY215C), -@@ -992,6 +1205,11 @@ static struct phy_driver gpy_drivers[] = { - .set_wol = gpy_set_wol, - .get_wol = gpy_get_wol, - .set_loopback = gpy_loopback, -+ .led_brightness_set = gpy_led_brightness_set, -+ .led_hw_is_supported = gpy_led_hw_is_supported, -+ .led_hw_control_get = gpy_led_hw_control_get, -+ .led_hw_control_set = gpy_led_hw_control_set, -+ .led_polarity_set = gpy_led_polarity_set, - }, - { - PHY_ID_MATCH_MODEL(PHY_ID_GPY241B), --- -2.51.0 - - -From 4f581169cc4a1bc0610a94c19e7a7e7dcee4bc42 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Fri, 4 Oct 2024 16:56:35 +0100 -Subject: [PATCH 090/517] net: phy: mxl-gpy: add missing support for - TRIGGER_NETDEV_LINK_10 - -The PHY also support 10MBit/s links as well as the corresponding link -indication trigger to be offloaded. Add TRIGGER_NETDEV_LINK_10 to the -supported triggers. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/cc5da0a989af8b0d49d823656d88053c4de2ab98.1728057367.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/mxl-gpy.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/net/phy/mxl-gpy.c b/drivers/net/phy/mxl-gpy.c -index 9930e6167f89..9864b9d2944f 100644 ---- a/drivers/net/phy/mxl-gpy.c -+++ b/drivers/net/phy/mxl-gpy.c -@@ -884,6 +884,7 @@ static int gpy_led_brightness_set(struct phy_device *phydev, - } - - static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_LINK) | -+ BIT(TRIGGER_NETDEV_LINK_10) | - BIT(TRIGGER_NETDEV_LINK_100) | - BIT(TRIGGER_NETDEV_LINK_1000) | - BIT(TRIGGER_NETDEV_LINK_2500) | --- -2.51.0 - - -From af00b072a7746a00880530c75cd1b9d35e1427e8 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 10 Oct 2024 13:55:17 +0100 -Subject: [PATCH 091/517] net: phy: mxl-gpy: correctly describe LED polarity - -According the datasheet covering the LED (0x1b) register: -0B Active High LEDx pin driven high when activated -1B Active Low LEDx pin driven low when activated - -Make use of the now available 'active-high' property and correctly -reflect the polarity setting which was previously inverted. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/180ccafa837f09908b852a8a874a3808c5ecd2d0.1728558223.git.daniel@makrotopia.org -Signed-off-by: Paolo Abeni ---- - drivers/net/phy/mxl-gpy.c | 16 ++++++++++++---- - 1 file changed, 12 insertions(+), 4 deletions(-) - -diff --git a/drivers/net/phy/mxl-gpy.c b/drivers/net/phy/mxl-gpy.c -index 9864b9d2944f..e0bdbb66df5c 100644 ---- a/drivers/net/phy/mxl-gpy.c -+++ b/drivers/net/phy/mxl-gpy.c -@@ -989,7 +989,7 @@ static int gpy_led_hw_control_set(struct phy_device *phydev, u8 index, - static int gpy_led_polarity_set(struct phy_device *phydev, int index, - unsigned long modes) - { -- bool active_low = false; -+ bool force_active_low = false, force_active_high = false; - u32 mode; - - if (index >= GPY_MAX_LEDS) -@@ -998,15 +998,23 @@ static int gpy_led_polarity_set(struct phy_device *phydev, int index, - for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) { - switch (mode) { - case PHY_LED_ACTIVE_LOW: -- active_low = true; -+ force_active_low = true; -+ break; -+ case PHY_LED_ACTIVE_HIGH: -+ force_active_high = true; - break; - default: - return -EINVAL; - } - } - -- return phy_modify(phydev, PHY_LED, PHY_LED_POLARITY(index), -- active_low ? 0 : PHY_LED_POLARITY(index)); -+ if (force_active_low) -+ return phy_set_bits(phydev, PHY_LED, PHY_LED_POLARITY(index)); -+ -+ if (force_active_high) -+ return phy_clear_bits(phydev, PHY_LED, PHY_LED_POLARITY(index)); -+ -+ unreachable(); - } - - static struct phy_driver gpy_drivers[] = { --- -2.51.0 - - -From 7ca1cf2b83a6acbdebc09b38921704e387945d88 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 10 Oct 2024 13:55:29 +0100 -Subject: [PATCH 092/517] net: phy: intel-xway: add support for PHY LEDs - -The intel-xway PHY driver predates the PHY LED framework and currently -initializes all LED pins to equal default values. - -Add PHY LED functions to the drivers and don't set default values if -LEDs are defined in device tree. - -According the datasheets 3 LEDs are supported on all Intel XWAY PHYs. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/81f4717ab9acf38f3239727a4540ae96fd01109b.1728558223.git.daniel@makrotopia.org -Signed-off-by: Paolo Abeni ---- - drivers/net/phy/intel-xway.c | 253 +++++++++++++++++++++++++++++++++-- - 1 file changed, 244 insertions(+), 9 deletions(-) - -diff --git a/drivers/net/phy/intel-xway.c b/drivers/net/phy/intel-xway.c -index fad411b93c15..62ab1fbef16c 100644 ---- a/drivers/net/phy/intel-xway.c -+++ b/drivers/net/phy/intel-xway.c -@@ -151,6 +151,13 @@ - #define XWAY_MMD_LED3H 0x01E8 - #define XWAY_MMD_LED3L 0x01E9 - -+#define XWAY_GPHY_MAX_LEDS 3 -+#define XWAY_GPHY_LED_INV(idx) BIT(12 + (idx)) -+#define XWAY_GPHY_LED_EN(idx) BIT(8 + (idx)) -+#define XWAY_GPHY_LED_DA(idx) BIT(idx) -+#define XWAY_MMD_LEDxH(idx) (XWAY_MMD_LED0H + 2 * (idx)) -+#define XWAY_MMD_LEDxL(idx) (XWAY_MMD_LED0L + 2 * (idx)) -+ - #define PHY_ID_PHY11G_1_3 0x030260D1 - #define PHY_ID_PHY22F_1_3 0x030260E1 - #define PHY_ID_PHY11G_1_4 0xD565A400 -@@ -229,20 +236,12 @@ static int xway_gphy_rgmii_init(struct phy_device *phydev) - XWAY_MDIO_MIICTRL_TXSKEW_MASK, val); - } - --static int xway_gphy_config_init(struct phy_device *phydev) -+static int xway_gphy_init_leds(struct phy_device *phydev) - { - int err; - u32 ledxh; - u32 ledxl; - -- /* Mask all interrupts */ -- err = phy_write(phydev, XWAY_MDIO_IMASK, 0); -- if (err) -- return err; -- -- /* Clear all pending interrupts */ -- phy_read(phydev, XWAY_MDIO_ISTAT); -- - /* Ensure that integrated led function is enabled for all leds */ - err = phy_write(phydev, XWAY_MDIO_LED, - XWAY_MDIO_LED_LED0_EN | -@@ -276,6 +275,26 @@ static int xway_gphy_config_init(struct phy_device *phydev) - phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED2H, ledxh); - phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED2L, ledxl); - -+ return 0; -+} -+ -+static int xway_gphy_config_init(struct phy_device *phydev) -+{ -+ struct device_node *np = phydev->mdio.dev.of_node; -+ int err; -+ -+ /* Mask all interrupts */ -+ err = phy_write(phydev, XWAY_MDIO_IMASK, 0); -+ if (err) -+ return err; -+ -+ /* Use default LED configuration if 'leds' node isn't defined */ -+ if (!of_get_child_by_name(np, "leds")) -+ xway_gphy_init_leds(phydev); -+ -+ /* Clear all pending interrupts */ -+ phy_read(phydev, XWAY_MDIO_ISTAT); -+ - err = xway_gphy_rgmii_init(phydev); - if (err) - return err; -@@ -347,6 +366,172 @@ static irqreturn_t xway_gphy_handle_interrupt(struct phy_device *phydev) - return IRQ_HANDLED; - } - -+static int xway_gphy_led_brightness_set(struct phy_device *phydev, -+ u8 index, enum led_brightness value) -+{ -+ int ret; -+ -+ if (index >= XWAY_GPHY_MAX_LEDS) -+ return -EINVAL; -+ -+ /* clear EN and set manual LED state */ -+ ret = phy_modify(phydev, XWAY_MDIO_LED, -+ ((value == LED_OFF) ? XWAY_GPHY_LED_EN(index) : 0) | -+ XWAY_GPHY_LED_DA(index), -+ (value == LED_OFF) ? 0 : XWAY_GPHY_LED_DA(index)); -+ if (ret) -+ return ret; -+ -+ /* clear HW LED setup */ -+ if (value == LED_OFF) { -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDxH(index), 0); -+ if (ret) -+ return ret; -+ -+ return phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDxL(index), 0); -+ } else { -+ return 0; -+ } -+} -+ -+static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_LINK) | -+ BIT(TRIGGER_NETDEV_LINK_10) | -+ BIT(TRIGGER_NETDEV_LINK_100) | -+ BIT(TRIGGER_NETDEV_LINK_1000) | -+ BIT(TRIGGER_NETDEV_RX) | -+ BIT(TRIGGER_NETDEV_TX)); -+ -+static int xway_gphy_led_hw_is_supported(struct phy_device *phydev, u8 index, -+ unsigned long rules) -+{ -+ if (index >= XWAY_GPHY_MAX_LEDS) -+ return -EINVAL; -+ -+ /* activity triggers are not possible without combination with a link -+ * trigger. -+ */ -+ if (rules & (BIT(TRIGGER_NETDEV_RX) | BIT(TRIGGER_NETDEV_TX)) && -+ !(rules & (BIT(TRIGGER_NETDEV_LINK) | -+ BIT(TRIGGER_NETDEV_LINK_10) | -+ BIT(TRIGGER_NETDEV_LINK_100) | -+ BIT(TRIGGER_NETDEV_LINK_1000)))) -+ return -EOPNOTSUPP; -+ -+ /* All other combinations of the supported triggers are allowed */ -+ if (rules & ~supported_triggers) -+ return -EOPNOTSUPP; -+ -+ return 0; -+} -+ -+static int xway_gphy_led_hw_control_get(struct phy_device *phydev, u8 index, -+ unsigned long *rules) -+{ -+ int lval, hval; -+ -+ if (index >= XWAY_GPHY_MAX_LEDS) -+ return -EINVAL; -+ -+ hval = phy_read_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDxH(index)); -+ if (hval < 0) -+ return hval; -+ -+ lval = phy_read_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDxL(index)); -+ if (lval < 0) -+ return lval; -+ -+ if (hval & XWAY_MMD_LEDxH_CON_LINK10) -+ *rules |= BIT(TRIGGER_NETDEV_LINK_10); -+ -+ if (hval & XWAY_MMD_LEDxH_CON_LINK100) -+ *rules |= BIT(TRIGGER_NETDEV_LINK_100); -+ -+ if (hval & XWAY_MMD_LEDxH_CON_LINK1000) -+ *rules |= BIT(TRIGGER_NETDEV_LINK_1000); -+ -+ if ((hval & XWAY_MMD_LEDxH_CON_LINK10) && -+ (hval & XWAY_MMD_LEDxH_CON_LINK100) && -+ (hval & XWAY_MMD_LEDxH_CON_LINK1000)) -+ *rules |= BIT(TRIGGER_NETDEV_LINK); -+ -+ if (lval & XWAY_MMD_LEDxL_PULSE_TXACT) -+ *rules |= BIT(TRIGGER_NETDEV_TX); -+ -+ if (lval & XWAY_MMD_LEDxL_PULSE_RXACT) -+ *rules |= BIT(TRIGGER_NETDEV_RX); -+ -+ return 0; -+} -+ -+static int xway_gphy_led_hw_control_set(struct phy_device *phydev, u8 index, -+ unsigned long rules) -+{ -+ u16 hval = 0, lval = 0; -+ int ret; -+ -+ if (index >= XWAY_GPHY_MAX_LEDS) -+ return -EINVAL; -+ -+ if (rules & BIT(TRIGGER_NETDEV_LINK) || -+ rules & BIT(TRIGGER_NETDEV_LINK_10)) -+ hval |= XWAY_MMD_LEDxH_CON_LINK10; -+ -+ if (rules & BIT(TRIGGER_NETDEV_LINK) || -+ rules & BIT(TRIGGER_NETDEV_LINK_100)) -+ hval |= XWAY_MMD_LEDxH_CON_LINK100; -+ -+ if (rules & BIT(TRIGGER_NETDEV_LINK) || -+ rules & BIT(TRIGGER_NETDEV_LINK_1000)) -+ hval |= XWAY_MMD_LEDxH_CON_LINK1000; -+ -+ if (rules & BIT(TRIGGER_NETDEV_TX)) -+ lval |= XWAY_MMD_LEDxL_PULSE_TXACT; -+ -+ if (rules & BIT(TRIGGER_NETDEV_RX)) -+ lval |= XWAY_MMD_LEDxL_PULSE_RXACT; -+ -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDxH(index), hval); -+ if (ret) -+ return ret; -+ -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDxL(index), lval); -+ if (ret) -+ return ret; -+ -+ return phy_set_bits(phydev, XWAY_MDIO_LED, XWAY_GPHY_LED_EN(index)); -+} -+ -+static int xway_gphy_led_polarity_set(struct phy_device *phydev, int index, -+ unsigned long modes) -+{ -+ bool force_active_low = false, force_active_high = false; -+ u32 mode; -+ -+ if (index >= XWAY_GPHY_MAX_LEDS) -+ return -EINVAL; -+ -+ for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) { -+ switch (mode) { -+ case PHY_LED_ACTIVE_LOW: -+ force_active_low = true; -+ break; -+ case PHY_LED_ACTIVE_HIGH: -+ force_active_high = true; -+ break; -+ default: -+ return -EINVAL; -+ } -+ } -+ -+ if (force_active_low) -+ return phy_set_bits(phydev, XWAY_MDIO_LED, XWAY_GPHY_LED_INV(index)); -+ -+ if (force_active_high) -+ return phy_clear_bits(phydev, XWAY_MDIO_LED, XWAY_GPHY_LED_INV(index)); -+ -+ unreachable(); -+} -+ - static struct phy_driver xway_gphy[] = { - { - .phy_id = PHY_ID_PHY11G_1_3, -@@ -359,6 +544,11 @@ static struct phy_driver xway_gphy[] = { - .config_intr = xway_gphy_config_intr, - .suspend = genphy_suspend, - .resume = genphy_resume, -+ .led_brightness_set = xway_gphy_led_brightness_set, -+ .led_hw_is_supported = xway_gphy_led_hw_is_supported, -+ .led_hw_control_get = xway_gphy_led_hw_control_get, -+ .led_hw_control_set = xway_gphy_led_hw_control_set, -+ .led_polarity_set = xway_gphy_led_polarity_set, - }, { - .phy_id = PHY_ID_PHY22F_1_3, - .phy_id_mask = 0xffffffff, -@@ -370,6 +560,11 @@ static struct phy_driver xway_gphy[] = { - .config_intr = xway_gphy_config_intr, - .suspend = genphy_suspend, - .resume = genphy_resume, -+ .led_brightness_set = xway_gphy_led_brightness_set, -+ .led_hw_is_supported = xway_gphy_led_hw_is_supported, -+ .led_hw_control_get = xway_gphy_led_hw_control_get, -+ .led_hw_control_set = xway_gphy_led_hw_control_set, -+ .led_polarity_set = xway_gphy_led_polarity_set, - }, { - .phy_id = PHY_ID_PHY11G_1_4, - .phy_id_mask = 0xffffffff, -@@ -381,6 +576,11 @@ static struct phy_driver xway_gphy[] = { - .config_intr = xway_gphy_config_intr, - .suspend = genphy_suspend, - .resume = genphy_resume, -+ .led_brightness_set = xway_gphy_led_brightness_set, -+ .led_hw_is_supported = xway_gphy_led_hw_is_supported, -+ .led_hw_control_get = xway_gphy_led_hw_control_get, -+ .led_hw_control_set = xway_gphy_led_hw_control_set, -+ .led_polarity_set = xway_gphy_led_polarity_set, - }, { - .phy_id = PHY_ID_PHY22F_1_4, - .phy_id_mask = 0xffffffff, -@@ -392,6 +592,11 @@ static struct phy_driver xway_gphy[] = { - .config_intr = xway_gphy_config_intr, - .suspend = genphy_suspend, - .resume = genphy_resume, -+ .led_brightness_set = xway_gphy_led_brightness_set, -+ .led_hw_is_supported = xway_gphy_led_hw_is_supported, -+ .led_hw_control_get = xway_gphy_led_hw_control_get, -+ .led_hw_control_set = xway_gphy_led_hw_control_set, -+ .led_polarity_set = xway_gphy_led_polarity_set, - }, { - .phy_id = PHY_ID_PHY11G_1_5, - .phy_id_mask = 0xffffffff, -@@ -402,6 +607,11 @@ static struct phy_driver xway_gphy[] = { - .config_intr = xway_gphy_config_intr, - .suspend = genphy_suspend, - .resume = genphy_resume, -+ .led_brightness_set = xway_gphy_led_brightness_set, -+ .led_hw_is_supported = xway_gphy_led_hw_is_supported, -+ .led_hw_control_get = xway_gphy_led_hw_control_get, -+ .led_hw_control_set = xway_gphy_led_hw_control_set, -+ .led_polarity_set = xway_gphy_led_polarity_set, - }, { - .phy_id = PHY_ID_PHY22F_1_5, - .phy_id_mask = 0xffffffff, -@@ -412,6 +622,11 @@ static struct phy_driver xway_gphy[] = { - .config_intr = xway_gphy_config_intr, - .suspend = genphy_suspend, - .resume = genphy_resume, -+ .led_brightness_set = xway_gphy_led_brightness_set, -+ .led_hw_is_supported = xway_gphy_led_hw_is_supported, -+ .led_hw_control_get = xway_gphy_led_hw_control_get, -+ .led_hw_control_set = xway_gphy_led_hw_control_set, -+ .led_polarity_set = xway_gphy_led_polarity_set, - }, { - .phy_id = PHY_ID_PHY11G_VR9_1_1, - .phy_id_mask = 0xffffffff, -@@ -422,6 +637,11 @@ static struct phy_driver xway_gphy[] = { - .config_intr = xway_gphy_config_intr, - .suspend = genphy_suspend, - .resume = genphy_resume, -+ .led_brightness_set = xway_gphy_led_brightness_set, -+ .led_hw_is_supported = xway_gphy_led_hw_is_supported, -+ .led_hw_control_get = xway_gphy_led_hw_control_get, -+ .led_hw_control_set = xway_gphy_led_hw_control_set, -+ .led_polarity_set = xway_gphy_led_polarity_set, - }, { - .phy_id = PHY_ID_PHY22F_VR9_1_1, - .phy_id_mask = 0xffffffff, -@@ -432,6 +652,11 @@ static struct phy_driver xway_gphy[] = { - .config_intr = xway_gphy_config_intr, - .suspend = genphy_suspend, - .resume = genphy_resume, -+ .led_brightness_set = xway_gphy_led_brightness_set, -+ .led_hw_is_supported = xway_gphy_led_hw_is_supported, -+ .led_hw_control_get = xway_gphy_led_hw_control_get, -+ .led_hw_control_set = xway_gphy_led_hw_control_set, -+ .led_polarity_set = xway_gphy_led_polarity_set, - }, { - .phy_id = PHY_ID_PHY11G_VR9_1_2, - .phy_id_mask = 0xffffffff, -@@ -442,6 +667,11 @@ static struct phy_driver xway_gphy[] = { - .config_intr = xway_gphy_config_intr, - .suspend = genphy_suspend, - .resume = genphy_resume, -+ .led_brightness_set = xway_gphy_led_brightness_set, -+ .led_hw_is_supported = xway_gphy_led_hw_is_supported, -+ .led_hw_control_get = xway_gphy_led_hw_control_get, -+ .led_hw_control_set = xway_gphy_led_hw_control_set, -+ .led_polarity_set = xway_gphy_led_polarity_set, - }, { - .phy_id = PHY_ID_PHY22F_VR9_1_2, - .phy_id_mask = 0xffffffff, -@@ -452,6 +682,11 @@ static struct phy_driver xway_gphy[] = { - .config_intr = xway_gphy_config_intr, - .suspend = genphy_suspend, - .resume = genphy_resume, -+ .led_brightness_set = xway_gphy_led_brightness_set, -+ .led_hw_is_supported = xway_gphy_led_hw_is_supported, -+ .led_hw_control_get = xway_gphy_led_hw_control_get, -+ .led_hw_control_set = xway_gphy_led_hw_control_set, -+ .led_polarity_set = xway_gphy_led_polarity_set, - }, - }; - module_phy_driver(xway_gphy); --- -2.51.0 - - -From 1bb33829d7d380fe3083f49d28968e268c6faf00 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 12 Aug 2025 06:57:23 +0200 -Subject: [PATCH 093/517] net: mediatek: wed: Introduce MT7992 WED support to - MT7988 SoC - -Introduce the second WDMA RX ring in WED driver for MT7988 SoC since the -Mediatek MT7992 WiFi chipset supports two separated WDMA rings. -Add missing MT7988 configurations to properly support WED for MT7992 in -MT76 driver. - -Co-developed-by: Rex Lu -Signed-off-by: Rex Lu -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20250812-mt7992-wed-support-v3-1-9ada78a819a4@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_wed.c | 33 ++++++++++++++++++++----- - drivers/net/ethernet/mediatek/mtk_wed.h | 2 +- - include/linux/soc/mediatek/mtk_wed.h | 2 +- - 3 files changed, 29 insertions(+), 8 deletions(-) - -diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c -index 499ca7000125..e7021d0622b0 100644 ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -59,7 +59,9 @@ struct mtk_wed_flow_block_priv { - static const struct mtk_wed_soc_data mt7622_data = { - .regmap = { - .tx_bm_tkid = 0x088, -- .wpdma_rx_ring0 = 0x770, -+ .wpdma_rx_ring = { -+ 0x770, -+ }, - .reset_idx_tx_mask = GENMASK(3, 0), - .reset_idx_rx_mask = GENMASK(17, 16), - }, -@@ -70,7 +72,9 @@ static const struct mtk_wed_soc_data mt7622_data = { - static const struct mtk_wed_soc_data mt7986_data = { - .regmap = { - .tx_bm_tkid = 0x0c8, -- .wpdma_rx_ring0 = 0x770, -+ .wpdma_rx_ring = { -+ 0x770, -+ }, - .reset_idx_tx_mask = GENMASK(1, 0), - .reset_idx_rx_mask = GENMASK(7, 6), - }, -@@ -81,7 +85,10 @@ static const struct mtk_wed_soc_data mt7986_data = { - static const struct mtk_wed_soc_data mt7988_data = { - .regmap = { - .tx_bm_tkid = 0x0c8, -- .wpdma_rx_ring0 = 0x7d0, -+ .wpdma_rx_ring = { -+ 0x7d0, -+ 0x7d8, -+ }, - .reset_idx_tx_mask = GENMASK(1, 0), - .reset_idx_rx_mask = GENMASK(7, 6), - }, -@@ -621,8 +628,8 @@ mtk_wed_amsdu_init(struct mtk_wed_device *dev) - return ret; - } - -- /* eagle E1 PCIE1 tx ring 22 flow control issue */ -- if (dev->wlan.id == 0x7991) -+ /* Kite and Eagle E1 PCIE1 tx ring 22 flow control issue */ -+ if (dev->wlan.id == 0x7991 || dev->wlan.id == 0x7992) - wed_clr(dev, MTK_WED_AMSDU_FIFO, MTK_WED_AMSDU_IS_PRIOR0_RING); - - wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_AMSDU_EN); -@@ -1239,7 +1246,11 @@ mtk_wed_set_wpdma(struct mtk_wed_device *dev) - return; - - wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo); -- wed_w32(dev, dev->hw->soc->regmap.wpdma_rx_ring0, dev->wlan.wpdma_rx); -+ wed_w32(dev, dev->hw->soc->regmap.wpdma_rx_ring[0], -+ dev->wlan.wpdma_rx[0]); -+ if (mtk_wed_is_v3_or_greater(dev->hw)) -+ wed_w32(dev, dev->hw->soc->regmap.wpdma_rx_ring[1], -+ dev->wlan.wpdma_rx[1]); - - if (!dev->wlan.hw_rro) - return; -@@ -2335,6 +2346,16 @@ mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask) - if (!dev->rx_wdma[i].desc) - mtk_wed_wdma_rx_ring_setup(dev, i, 16, false); - -+ if (dev->wlan.hw_rro) { -+ for (i = 0; i < MTK_WED_RX_PAGE_QUEUES; i++) { -+ u32 addr = MTK_WED_RRO_MSDU_PG_CTRL0(i) + -+ MTK_WED_RING_OFS_COUNT; -+ -+ if (!wed_r32(dev, addr)) -+ wed_w32(dev, addr, 1); -+ } -+ } -+ - mtk_wed_hw_init(dev); - mtk_wed_configure_irq(dev, irq_mask); - -diff --git a/drivers/net/ethernet/mediatek/mtk_wed.h b/drivers/net/ethernet/mediatek/mtk_wed.h -index c1f0479d7a71..b49aee9a8b65 100644 ---- a/drivers/net/ethernet/mediatek/mtk_wed.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed.h -@@ -17,7 +17,7 @@ struct mtk_wed_wo; - struct mtk_wed_soc_data { - struct { - u32 tx_bm_tkid; -- u32 wpdma_rx_ring0; -+ u32 wpdma_rx_ring[MTK_WED_RX_QUEUES]; - u32 reset_idx_tx_mask; - u32 reset_idx_rx_mask; - } regmap; -diff --git a/include/linux/soc/mediatek/mtk_wed.h b/include/linux/soc/mediatek/mtk_wed.h -index a476648858a6..5ab3a93a7be9 100644 ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -147,7 +147,7 @@ struct mtk_wed_device { - u32 wpdma_tx; - u32 wpdma_txfree; - u32 wpdma_rx_glo; -- u32 wpdma_rx; -+ u32 wpdma_rx[MTK_WED_RX_QUEUES]; - u32 wpdma_rx_rro[MTK_WED_RX_QUEUES]; - u32 wpdma_rx_pg; - --- -2.51.0 - - -From 528e2e4d166e49dadcb780d5a37cda03bbe9e399 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Wed, 8 Oct 2025 12:41:48 +0200 -Subject: [PATCH 094/517] wifi: mt76: wed: use proper wed reference in mt76 wed - driver callabacks - -MT7996 driver can use both wed and wed_hif2 devices to offload traffic -from/to the wireless NIC. In the current codebase we assume to always -use the primary wed device in wed callbacks resulting in the following -crash if the hw runs wed_hif2 (e.g. 6GHz link). - -[ 297.455876] Unable to handle kernel read from unreadable memory at virtual address 000000000000080a -[ 297.464928] Mem abort info: -[ 297.467722] ESR = 0x0000000096000005 -[ 297.471461] EC = 0x25: DABT (current EL), IL = 32 bits -[ 297.476766] SET = 0, FnV = 0 -[ 297.479809] EA = 0, S1PTW = 0 -[ 297.482940] FSC = 0x05: level 1 translation fault -[ 297.487809] Data abort info: -[ 297.490679] ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000 -[ 297.496156] CM = 0, WnR = 0, TnD = 0, TagAccess = 0 -[ 297.501196] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 -[ 297.506500] user pgtable: 4k pages, 39-bit VAs, pgdp=0000000107480000 -[ 297.512927] [000000000000080a] pgd=08000001097fb003, p4d=08000001097fb003, pud=08000001097fb003, pmd=0000000000000000 -[ 297.523532] Internal error: Oops: 0000000096000005 [#1] SMP -[ 297.715393] CPU: 2 UID: 0 PID: 45 Comm: kworker/u16:2 Tainted: G O 6.12.50 #0 -[ 297.723908] Tainted: [O]=OOT_MODULE -[ 297.727384] Hardware name: Banana Pi BPI-R4 (2x SFP+) (DT) -[ 297.732857] Workqueue: nf_ft_offload_del nf_flow_rule_route_ipv6 [nf_flow_table] -[ 297.740254] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) -[ 297.747205] pc : mt76_wed_offload_disable+0x64/0xa0 [mt76] -[ 297.752688] lr : mtk_wed_flow_remove+0x58/0x80 -[ 297.757126] sp : ffffffc080fe3ae0 -[ 297.760430] x29: ffffffc080fe3ae0 x28: ffffffc080fe3be0 x27: 00000000deadbef7 -[ 297.767557] x26: ffffff80c5ebca00 x25: 0000000000000001 x24: ffffff80c85f4c00 -[ 297.774683] x23: ffffff80c1875b78 x22: ffffffc080d42cd0 x21: ffffffc080660018 -[ 297.781809] x20: ffffff80c6a076d0 x19: ffffff80c6a043c8 x18: 0000000000000000 -[ 297.788935] x17: 0000000000000000 x16: 0000000000000001 x15: 0000000000000000 -[ 297.796060] x14: 0000000000000019 x13: ffffff80c0ad8ec0 x12: 00000000fa83b2da -[ 297.803185] x11: ffffff80c02700c0 x10: ffffff80c0ad8ec0 x9 : ffffff81fef96200 -[ 297.810311] x8 : ffffff80c02700c0 x7 : ffffff80c02700d0 x6 : 0000000000000002 -[ 297.817435] x5 : 0000000000000400 x4 : 0000000000000000 x3 : 0000000000000000 -[ 297.824561] x2 : 0000000000000001 x1 : 0000000000000800 x0 : ffffff80c6a063c8 -[ 297.831686] Call trace: -[ 297.834123] mt76_wed_offload_disable+0x64/0xa0 [mt76] -[ 297.839254] mtk_wed_flow_remove+0x58/0x80 -[ 297.843342] mtk_flow_offload_cmd+0x434/0x574 -[ 297.847689] mtk_wed_setup_tc_block_cb+0x30/0x40 -[ 297.852295] nf_flow_offload_ipv6_hook+0x7f4/0x964 [nf_flow_table] -[ 297.858466] nf_flow_rule_route_ipv6+0x438/0x4a4 [nf_flow_table] -[ 297.864463] process_one_work+0x174/0x300 -[ 297.868465] worker_thread+0x278/0x430 -[ 297.872204] kthread+0xd8/0xdc -[ 297.875251] ret_from_fork+0x10/0x20 -[ 297.878820] Code: 928b5ae0 8b000273 91400a60 f943fa61 (79401421) -[ 297.884901] ---[ end trace 0000000000000000 ]--- - -Fix the issue detecting the proper wed reference to use running wed -callabacks. - --- Partial backport for data structure change only (rest is in the mt76 package) - -Fixes: 83eafc9251d6 ("wifi: mt76: mt7996: add wed tx support") -Tested-by: Daniel Pawlik -Tested-by: Matteo Croce -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20251008-wed-fixes-v1-1-8f7678583385@kernel.org -Signed-off-by: Felix Fietkau ---- - include/linux/soc/mediatek/mtk_wed.h | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/include/linux/soc/mediatek/mtk_wed.h b/include/linux/soc/mediatek/mtk_wed.h -index 5ab3a93a7be9..5c3358e033df 100644 ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -154,6 +154,7 @@ struct mtk_wed_device { - bool wcid_512; - bool hw_rro; - bool msi; -+ bool hif2; - - u16 token_start; - unsigned int nbuf; --- -2.51.0 - - -From 91f5d4afc87aa13b8a58ce06713b4166ec5aeae0 Mon Sep 17 00:00:00 2001 -From: Rex Lu -Date: Thu, 9 Oct 2025 08:29:34 +0200 -Subject: [PATCH 095/517] net: mtk: wed: add dma mask limitation and GFP_DMA32 - for device with more than 4GB DRAM - -Limit tx/rx buffer address to 32-bit address space for board with more -than 4GB DRAM. - -Fixes: 804775dfc2885 ("net: ethernet: mtk_eth_soc: add support for Wireless Ethernet Dispatch (WED)") -Fixes: 6757d345dd7db ("net: ethernet: mtk_wed: introduce hw_rro support for MT7988") -Tested-by: Daniel Pawlik -Tested-by: Matteo Croce -Signed-off-by: Rex Lu -Co-developed-by: Lorenzo Bianconi -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/mtk_wed.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c -index e7021d0622b0..1e369a059edd 100644 ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -677,7 +677,7 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev) - void *buf; - int s; - -- page = __dev_alloc_page(GFP_KERNEL); -+ page = __dev_alloc_page(GFP_KERNEL | GFP_DMA32); - if (!page) - return -ENOMEM; - -@@ -800,7 +800,7 @@ mtk_wed_hwrro_buffer_alloc(struct mtk_wed_device *dev) - struct page *page; - int s; - -- page = __dev_alloc_page(GFP_KERNEL); -+ page = __dev_alloc_page(GFP_KERNEL | GFP_DMA32); - if (!page) - return -ENOMEM; - -@@ -2438,6 +2438,10 @@ mtk_wed_attach(struct mtk_wed_device *dev) - dev->version = hw->version; - dev->hw->pcie_base = mtk_wed_get_pcie_base(dev); - -+ ret = dma_set_mask_and_coherent(hw->dev, DMA_BIT_MASK(32)); -+ if (ret) -+ goto out; -+ - if (hw->eth->dma_dev == hw->eth->dev && - of_dma_is_coherent(hw->eth->dev->of_node)) - mtk_eth_set_dma_device(hw->eth, hw->dev); --- -2.51.0 - - -From 41f6a1b75d6742130804539509cff2ef9294196b Mon Sep 17 00:00:00 2001 -From: Linus Walleij -Date: Fri, 13 Oct 2023 00:08:35 +0200 -Subject: [PATCH 096/517] net: dsa: mv88e6xxx: Support LED control - -This adds control over the hardware LEDs in the Marvell -MV88E6xxx DSA switch and enables it for MV88E6352. - -This fixes an imminent problem on the Inteno XG6846 which -has a WAN LED that simply do not work with hardware -defaults: driver amendment is necessary. - -The patch is modeled after Christian Marangis LED support -code for the QCA8k DSA switch, I got help with the register -definitions from Tim Harvey. - -After this patch it is possible to activate hardware link -indication like this (or with a similar script): - - cd /sys/class/leds/Marvell\ 88E6352:05:00:green:wan/ - echo netdev > trigger - echo 1 > link - -This makes the green link indicator come up on any link -speed. It is also possible to be more elaborate, like this: - - cd /sys/class/leds/Marvell\ 88E6352:05:00:green:wan/ - echo netdev > trigger - echo 1 > link_1000 - cd /sys/class/leds/Marvell\ 88E6352:05:01:amber:wan/ - echo netdev > trigger - echo 1 > link_100 - -Making the green LED come on for a gigabit link and the -amber LED come on for a 100 mbit link. - -Each port has 2 LED slots (the hardware may use just one or -none) and the hardware triggers are specified in four bits per -LED, and some of the hardware triggers are only available on the -SFP (fiber) uplink. The restrictions are described in the -port.h header file where the registers are described. For -example, selector 1 set for LED 1 on port 5 or 6 will indicate -Fiber 1000 (gigabit) and activity with a blinking LED, but -ONLY for an SFP connection. If port 5/6 is used with something -not SFP, this selector is a noop: something else need to be -selected. - -After the previous series rewriting the MV88E6xxx DT -bindings to use YAML a "leds" subnode is already valid -for each port, in my scratch device tree it looks like -this: - - leds { - #address-cells = <1>; - #size-cells = <0>; - - led@0 { - reg = <0>; - color = ; - function = LED_FUNCTION_LAN; - default-state = "off"; - linux,default-trigger = "netdev"; - }; - led@1 { - reg = <1>; - color = ; - function = LED_FUNCTION_LAN; - default-state = "off"; - }; - }; - -This DT config is not yet configuring everything: when the netdev -default trigger is assigned the hw acceleration callbacks are -not called, and there is no way to set the netdev sub-trigger -type (such as link_1000) from the device tree, such as if you want -a gigabit link indicator. This has to be done from userspace at -this point. - -We add LED operations to all switches in the 6352 family: -6172, 6176, 6240 and 6352. - -Signed-off-by: Linus Walleij ---- - drivers/net/dsa/mv88e6xxx/Kconfig | 10 + - drivers/net/dsa/mv88e6xxx/Makefile | 1 + - drivers/net/dsa/mv88e6xxx/chip.c | 38 +- - drivers/net/dsa/mv88e6xxx/chip.h | 11 + - drivers/net/dsa/mv88e6xxx/leds.c | 839 +++++++++++++++++++++++++++++ - drivers/net/dsa/mv88e6xxx/port.c | 1 + - drivers/net/dsa/mv88e6xxx/port.h | 133 +++++ - 7 files changed, 1031 insertions(+), 2 deletions(-) - create mode 100644 drivers/net/dsa/mv88e6xxx/leds.c - -diff --git a/drivers/net/dsa/mv88e6xxx/Kconfig b/drivers/net/dsa/mv88e6xxx/Kconfig -index e3181d5471df..64ae3882d17c 100644 ---- a/drivers/net/dsa/mv88e6xxx/Kconfig -+++ b/drivers/net/dsa/mv88e6xxx/Kconfig -@@ -17,3 +17,13 @@ config NET_DSA_MV88E6XXX_PTP - help - Say Y to enable PTP hardware timestamping on Marvell 88E6xxx switch - chips that support it. -+ -+config NET_DSA_MV88E6XXX_LEDS -+ bool "LED support for Marvell 88E6xxx" -+ default y -+ depends on NET_DSA_MV88E6XXX -+ depends on LEDS_CLASS=y || LEDS_CLASS=NET_DSA_MV88E6XXX -+ depends on LEDS_TRIGGERS -+ help -+ This enabled support for controlling the LEDs attached to the -+ Marvell 88E6xxx switch chips. -diff --git a/drivers/net/dsa/mv88e6xxx/Makefile b/drivers/net/dsa/mv88e6xxx/Makefile -index a9a9651187db..dd961081d631 100644 ---- a/drivers/net/dsa/mv88e6xxx/Makefile -+++ b/drivers/net/dsa/mv88e6xxx/Makefile -@@ -9,6 +9,7 @@ mv88e6xxx-objs += global2.o - mv88e6xxx-objs += global2_avb.o - mv88e6xxx-objs += global2_scratch.o - mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_PTP) += hwtstamp.o -+mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_LEDS) += leds.o - mv88e6xxx-objs += pcs-6185.o - mv88e6xxx-objs += pcs-6352.o - mv88e6xxx-objs += pcs-639x.o -diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c -index 211c219dd52d..43e0482fe1fd 100644 ---- a/drivers/net/dsa/mv88e6xxx/chip.c -+++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -27,6 +27,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -3412,14 +3413,43 @@ static int mv88e6xxx_setup_upstream_port(struct mv88e6xxx_chip *chip, int port) - static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port) - { - struct device_node *phy_handle = NULL; -+ struct fwnode_handle *ports_fwnode; -+ struct fwnode_handle *port_fwnode; - struct dsa_switch *ds = chip->ds; -+ struct mv88e6xxx_port *p; - struct dsa_port *dp; - int tx_amp; - int err; - u16 reg; -+ u32 val; -+ -+ p = &chip->ports[port]; -+ p->chip = chip; -+ p->port = port; -+ -+ /* Look up corresponding fwnode if any */ -+ ports_fwnode = device_get_named_child_node(chip->dev, "ethernet-ports"); -+ if (!ports_fwnode) -+ ports_fwnode = device_get_named_child_node(chip->dev, "ports"); -+ if (ports_fwnode) { -+ fwnode_for_each_child_node(ports_fwnode, port_fwnode) { -+ if (fwnode_property_read_u32(port_fwnode, "reg", &val)) -+ continue; -+ if (val == port) { -+ p->fwnode = port_fwnode; -+ p->fiber = fwnode_property_present(port_fwnode, "sfp"); -+ break; -+ } -+ } -+ } else { -+ dev_dbg(chip->dev, "no ethernet ports node defined for the device\n"); -+ } - -- chip->ports[port].chip = chip; -- chip->ports[port].port = port; -+ if (chip->info->ops->port_setup_leds) { -+ err = chip->info->ops->port_setup_leds(chip, port); -+ if (err && err != -EOPNOTSUPP) -+ return err; -+ } - - err = mv88e6xxx_port_setup_mac(chip, port, LINK_UNFORCED, - SPEED_UNFORCED, DUPLEX_UNFORCED, -@@ -4653,6 +4683,7 @@ static const struct mv88e6xxx_ops mv88e6172_ops = { - .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, - .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, - .port_get_cmode = mv88e6352_port_get_cmode, -+ .port_setup_leds = mv88e6xxx_port_setup_leds, - .port_setup_message_port = mv88e6xxx_setup_message_port, - .stats_snapshot = mv88e6320_g1_stats_snapshot, - .stats_set_histogram = mv88e6095_g1_stats_set_histogram, -@@ -4755,6 +4786,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = { - .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, - .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, - .port_get_cmode = mv88e6352_port_get_cmode, -+ .port_setup_leds = mv88e6xxx_port_setup_leds, - .port_setup_message_port = mv88e6xxx_setup_message_port, - .stats_snapshot = mv88e6320_g1_stats_snapshot, - .stats_set_histogram = mv88e6095_g1_stats_set_histogram, -@@ -5030,6 +5062,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = { - .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, - .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, - .port_get_cmode = mv88e6352_port_get_cmode, -+ .port_setup_leds = mv88e6xxx_port_setup_leds, - .port_setup_message_port = mv88e6xxx_setup_message_port, - .stats_snapshot = mv88e6320_g1_stats_snapshot, - .stats_set_histogram = mv88e6095_g1_stats_set_histogram, -@@ -5460,6 +5493,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = { - .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, - .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, - .port_get_cmode = mv88e6352_port_get_cmode, -+ .port_setup_leds = mv88e6xxx_port_setup_leds, - .port_setup_message_port = mv88e6xxx_setup_message_port, - .stats_snapshot = mv88e6320_g1_stats_snapshot, - .stats_set_histogram = mv88e6095_g1_stats_set_histogram, -diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h -index a54682240839..71a8fd9ff374 100644 ---- a/drivers/net/dsa/mv88e6xxx/chip.h -+++ b/drivers/net/dsa/mv88e6xxx/chip.h -@@ -13,7 +13,9 @@ - #include - #include - #include -+#include - #include -+#include - #include - #include - #include -@@ -276,6 +278,7 @@ struct mv88e6xxx_vlan { - struct mv88e6xxx_port { - struct mv88e6xxx_chip *chip; - int port; -+ struct fwnode_handle *fwnode; - struct mv88e6xxx_vlan bridge_pvid; - u64 serdes_stats[2]; - u64 atu_member_violation; -@@ -290,6 +293,11 @@ struct mv88e6xxx_port { - struct devlink_region *region; - void *pcs_private; - -+ /* LED related information */ -+ bool fiber; -+ struct led_classdev led0; -+ struct led_classdev led1; -+ - /* MacAuth Bypass control flag */ - bool mab; - }; -@@ -574,6 +582,9 @@ struct mv88e6xxx_ops { - phy_interface_t mode); - int (*port_get_cmode)(struct mv88e6xxx_chip *chip, int port, u8 *cmode); - -+ /* LED control */ -+ int (*port_setup_leds)(struct mv88e6xxx_chip *chip, int port); -+ - /* Some devices have a per port register indicating what is - * the upstream port this port should forward to. - */ -diff --git a/drivers/net/dsa/mv88e6xxx/leds.c b/drivers/net/dsa/mv88e6xxx/leds.c -new file mode 100644 -index 000000000000..1c88bfaea46b ---- /dev/null -+++ b/drivers/net/dsa/mv88e6xxx/leds.c -@@ -0,0 +1,839 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+#include -+#include -+#include -+ -+#include "chip.h" -+#include "global2.h" -+#include "port.h" -+ -+/* Offset 0x16: LED control */ -+ -+static int mv88e6xxx_port_led_write(struct mv88e6xxx_chip *chip, int port, u16 reg) -+{ -+ reg |= MV88E6XXX_PORT_LED_CONTROL_UPDATE; -+ -+ return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_LED_CONTROL, reg); -+} -+ -+static int mv88e6xxx_port_led_read(struct mv88e6xxx_chip *chip, int port, -+ u16 ptr, u16 *val) -+{ -+ int err; -+ -+ err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_LED_CONTROL, ptr); -+ if (err) -+ return err; -+ -+ err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_LED_CONTROL, val); -+ *val &= 0x3ff; -+ -+ return err; -+} -+ -+static int mv88e6xxx_led_brightness_set(struct mv88e6xxx_port *p, int led, -+ int brightness) -+{ -+ u16 reg; -+ int err; -+ -+ err = mv88e6xxx_port_led_read(p->chip, p->port, -+ MV88E6XXX_PORT_LED_CONTROL_POINTER_LED01_CTRL, -+ ®); -+ if (err) -+ return err; -+ -+ if (led == 1) -+ reg &= ~MV88E6XXX_PORT_LED_CONTROL_LED1_SEL_MASK; -+ else -+ reg &= ~MV88E6XXX_PORT_LED_CONTROL_LED0_SEL_MASK; -+ -+ if (brightness) { -+ /* Selector 0x0f == Force LED ON */ -+ if (led == 1) -+ reg |= MV88E6XXX_PORT_LED_CONTROL_LED1_SELF; -+ else -+ reg |= MV88E6XXX_PORT_LED_CONTROL_LED0_SELF; -+ } else { -+ /* Selector 0x0e == Force LED OFF */ -+ if (led == 1) -+ reg |= MV88E6XXX_PORT_LED_CONTROL_LED1_SELE; -+ else -+ reg |= MV88E6XXX_PORT_LED_CONTROL_LED0_SELE; -+ } -+ -+ reg |= MV88E6XXX_PORT_LED_CONTROL_POINTER_LED01_CTRL; -+ -+ return mv88e6xxx_port_led_write(p->chip, p->port, reg); -+} -+ -+static int mv88e6xxx_led0_brightness_set_blocking(struct led_classdev *ldev, -+ enum led_brightness brightness) -+{ -+ struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led0); -+ int err; -+ -+ mv88e6xxx_reg_lock(p->chip); -+ err = mv88e6xxx_led_brightness_set(p, 0, brightness); -+ mv88e6xxx_reg_unlock(p->chip); -+ -+ return err; -+} -+ -+static int mv88e6xxx_led1_brightness_set_blocking(struct led_classdev *ldev, -+ enum led_brightness brightness) -+{ -+ struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led1); -+ int err; -+ -+ mv88e6xxx_reg_lock(p->chip); -+ err = mv88e6xxx_led_brightness_set(p, 1, brightness); -+ mv88e6xxx_reg_unlock(p->chip); -+ -+ return err; -+} -+ -+struct mv88e6xxx_led_hwconfig { -+ int led; -+ u8 portmask; -+ unsigned long rules; -+ bool fiber; -+ bool blink_activity; -+ u16 selector; -+}; -+ -+/* The following is a lookup table to check what rules we can support on a -+ * certain LED given restrictions such as that some rules only work with fiber -+ * (SFP) connections and some blink on activity by default. -+ */ -+#define MV88E6XXX_PORTS_0_3 (BIT(0) | BIT(1) | BIT(2) | BIT(3)) -+#define MV88E6XXX_PORTS_4_5 (BIT(4) | BIT(5)) -+#define MV88E6XXX_PORT_4 BIT(4) -+#define MV88E6XXX_PORT_5 BIT(5) -+ -+/* Entries are listed in selector order. -+ * -+ * These configurations vary across different switch families, list -+ * different tables per-family here. -+ */ -+static const struct mv88e6xxx_led_hwconfig mv88e6352_led_hwconfigs[] = { -+ { -+ .led = 0, -+ .portmask = MV88E6XXX_PORT_4, -+ .rules = BIT(TRIGGER_NETDEV_LINK), -+ .blink_activity = true, -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED0_SEL0, -+ }, -+ { -+ .led = 1, -+ .portmask = MV88E6XXX_PORT_5, -+ .rules = BIT(TRIGGER_NETDEV_LINK_1000), -+ .blink_activity = true, -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SEL0, -+ }, -+ { -+ .led = 0, -+ .portmask = MV88E6XXX_PORTS_0_3, -+ .rules = BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK_1000), -+ .blink_activity = true, -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED0_SEL1, -+ }, -+ { -+ .led = 1, -+ .portmask = MV88E6XXX_PORTS_0_3, -+ .rules = BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK_100), -+ .blink_activity = true, -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SEL1, -+ }, -+ { -+ .led = 0, -+ .portmask = MV88E6XXX_PORTS_4_5, -+ .rules = BIT(TRIGGER_NETDEV_LINK_100), -+ .blink_activity = true, -+ .fiber = true, -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED0_SEL1, -+ }, -+ { -+ .led = 1, -+ .portmask = MV88E6XXX_PORTS_4_5, -+ .rules = BIT(TRIGGER_NETDEV_LINK_1000), -+ .blink_activity = true, -+ .fiber = true, -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SEL1, -+ }, -+ { -+ .led = 0, -+ .portmask = MV88E6XXX_PORTS_0_3, -+ .rules = BIT(TRIGGER_NETDEV_LINK_1000), -+ .blink_activity = true, -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED0_SEL2, -+ }, -+ { -+ .led = 1, -+ .portmask = MV88E6XXX_PORTS_0_3, -+ .rules = BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK_100), -+ .blink_activity = true, -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SEL2, -+ }, -+ { -+ .led = 0, -+ .portmask = MV88E6XXX_PORTS_4_5, -+ .rules = BIT(TRIGGER_NETDEV_LINK_1000), -+ .blink_activity = true, -+ .fiber = true, -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED0_SEL2, -+ }, -+ { -+ .led = 1, -+ .portmask = MV88E6XXX_PORTS_4_5, -+ .rules = BIT(TRIGGER_NETDEV_LINK_100), -+ .blink_activity = true, -+ .fiber = true, -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SEL2, -+ }, -+ { -+ .led = 0, -+ .portmask = MV88E6XXX_PORTS_0_3, -+ .rules = BIT(TRIGGER_NETDEV_LINK), -+ .blink_activity = true, -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED0_SEL3, -+ }, -+ { -+ .led = 1, -+ .portmask = MV88E6XXX_PORTS_0_3, -+ .rules = BIT(TRIGGER_NETDEV_LINK_1000), -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SEL3, -+ }, -+ { -+ .led = 1, -+ .portmask = MV88E6XXX_PORTS_4_5, -+ .rules = BIT(TRIGGER_NETDEV_LINK), -+ .fiber = true, -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SEL3, -+ }, -+ { -+ .led = 1, -+ .portmask = MV88E6XXX_PORT_4, -+ .rules = BIT(TRIGGER_NETDEV_LINK), -+ .blink_activity = true, -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SEL4, -+ }, -+ { -+ .led = 1, -+ .portmask = MV88E6XXX_PORT_5, -+ .rules = BIT(TRIGGER_NETDEV_LINK), -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SEL5, -+ }, -+ { -+ .led = 0, -+ .portmask = MV88E6XXX_PORTS_0_3, -+ .rules = BIT(TRIGGER_NETDEV_FULL_DUPLEX), -+ .blink_activity = true, -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED0_SEL6, -+ }, -+ { -+ .led = 1, -+ .portmask = MV88E6XXX_PORTS_0_3, -+ .rules = BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK_1000), -+ .blink_activity = true, -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SEL6, -+ }, -+ { -+ .led = 0, -+ .portmask = MV88E6XXX_PORT_4, -+ .rules = BIT(TRIGGER_NETDEV_FULL_DUPLEX), -+ .blink_activity = true, -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED0_SEL6, -+ }, -+ { -+ .led = 1, -+ .portmask = MV88E6XXX_PORT_5, -+ .rules = BIT(TRIGGER_NETDEV_FULL_DUPLEX), -+ .blink_activity = true, -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SEL6, -+ }, -+ { -+ .led = 0, -+ .portmask = MV88E6XXX_PORTS_0_3, -+ .rules = BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK_1000), -+ .blink_activity = true, -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED0_SEL7, -+ }, -+ { -+ .led = 1, -+ .portmask = MV88E6XXX_PORTS_0_3, -+ .rules = BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK_1000), -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SEL7, -+ }, -+ { -+ .led = 0, -+ .portmask = MV88E6XXX_PORTS_0_3, -+ .rules = BIT(TRIGGER_NETDEV_LINK), -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED0_SEL8, -+ }, -+ { -+ .led = 1, -+ .portmask = MV88E6XXX_PORTS_0_3, -+ .rules = BIT(TRIGGER_NETDEV_LINK), -+ .blink_activity = true, -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SEL8, -+ }, -+ { -+ .led = 0, -+ .portmask = MV88E6XXX_PORT_5, -+ .rules = BIT(TRIGGER_NETDEV_LINK), -+ .blink_activity = true, -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED0_SEL8, -+ }, -+ { -+ .led = 0, -+ .portmask = MV88E6XXX_PORTS_0_3, -+ .rules = BIT(TRIGGER_NETDEV_LINK_10), -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED0_SEL9, -+ }, -+ { -+ .led = 1, -+ .portmask = MV88E6XXX_PORTS_0_3, -+ .rules = BIT(TRIGGER_NETDEV_LINK_100), -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SEL9, -+ }, -+ { -+ .led = 0, -+ .portmask = MV88E6XXX_PORTS_0_3, -+ .rules = BIT(TRIGGER_NETDEV_LINK_10), -+ .blink_activity = true, -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED0_SELA, -+ }, -+ { -+ .led = 1, -+ .portmask = MV88E6XXX_PORTS_0_3, -+ .rules = BIT(TRIGGER_NETDEV_LINK_100), -+ .blink_activity = true, -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SELA, -+ }, -+ { -+ .led = 0, -+ .portmask = MV88E6XXX_PORTS_0_3, -+ .rules = BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK_1000), -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED0_SELB, -+ }, -+ { -+ .led = 1, -+ .portmask = MV88E6XXX_PORTS_0_3, -+ .rules = BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK_1000), -+ .blink_activity = true, -+ .selector = MV88E6XXX_PORT_LED_CONTROL_LED1_SELB, -+ }, -+}; -+ -+/* mv88e6xxx_led_match_selector() - look up the appropriate LED mode selector -+ * @p: port state container -+ * @led: LED number, 0 or 1 -+ * @blink_activity: blink the LED (usually blink on indicated activity) -+ * @fiber: the link is connected to fiber such as SFP -+ * @rules: LED status flags from the LED classdev core -+ * @selector: fill in the selector in this parameter with an OR operation -+ */ -+static int mv88e6xxx_led_match_selector(struct mv88e6xxx_port *p, int led, bool blink_activity, -+ bool fiber, unsigned long rules, u16 *selector) -+{ -+ const struct mv88e6xxx_led_hwconfig *conf; -+ int i; -+ -+ /* No rules means we turn the LED off */ -+ if (!rules) { -+ if (led == 1) -+ *selector |= MV88E6XXX_PORT_LED_CONTROL_LED1_SELE; -+ else -+ *selector |= MV88E6XXX_PORT_LED_CONTROL_LED0_SELE; -+ return 0; -+ } -+ -+ /* TODO: these rules are for MV88E6352, when adding other families, -+ * think about making sure you select the table that match the -+ * specific switch family. -+ */ -+ for (i = 0; i < ARRAY_SIZE(mv88e6352_led_hwconfigs); i++) { -+ conf = &mv88e6352_led_hwconfigs[i]; -+ -+ if (conf->led != led) -+ continue; -+ -+ if (!(conf->portmask & BIT(p->port))) -+ continue; -+ -+ if (conf->blink_activity != blink_activity) -+ continue; -+ -+ if (conf->fiber != fiber) -+ continue; -+ -+ if (conf->rules == rules) { -+ dev_dbg(p->chip->dev, "port%d LED %d set selector %04x for rules %08lx\n", -+ p->port, led, conf->selector, rules); -+ *selector |= conf->selector; -+ return 0; -+ } -+ } -+ -+ return -EOPNOTSUPP; -+} -+ -+/* mv88e6xxx_led_match_selector() - find Linux netdev rules from a selector value -+ * @p: port state container -+ * @selector: the selector value from the LED actity register -+ * @led: LED number, 0 or 1 -+ * @rules: Linux netdev activity rules found from selector -+ */ -+static int -+mv88e6xxx_led_match_rule(struct mv88e6xxx_port *p, u16 selector, int led, unsigned long *rules) -+{ -+ const struct mv88e6xxx_led_hwconfig *conf; -+ int i; -+ -+ /* Find the selector in the table, we just look for the right selector -+ * and ignore if the activity has special properties such as blinking -+ * or is fiber-only. -+ */ -+ for (i = 0; i < ARRAY_SIZE(mv88e6352_led_hwconfigs); i++) { -+ conf = &mv88e6352_led_hwconfigs[i]; -+ -+ if (conf->led != led) -+ continue; -+ -+ if (!(conf->portmask & BIT(p->port))) -+ continue; -+ -+ if (conf->selector == selector) { -+ dev_dbg(p->chip->dev, "port%d LED %d has selector %04x, rules %08lx\n", -+ p->port, led, selector, conf->rules); -+ *rules = conf->rules; -+ return 0; -+ } -+ } -+ -+ return -EINVAL; -+} -+ -+/* mv88e6xxx_led_get_selector() - get the appropriate LED mode selector -+ * @p: port state container -+ * @led: LED number, 0 or 1 -+ * @fiber: the link is connected to fiber such as SFP -+ * @rules: LED status flags from the LED classdev core -+ * @selector: fill in the selector in this parameter with an OR operation -+ */ -+static int mv88e6xxx_led_get_selector(struct mv88e6xxx_port *p, int led, -+ bool fiber, unsigned long rules, u16 *selector) -+{ -+ int err; -+ -+ /* What happens here is that we first try to locate a trigger with solid -+ * indicator (such as LED is on for a 1000 link) else we try a second -+ * sweep to find something suitable with a trigger that will blink on -+ * activity. -+ */ -+ err = mv88e6xxx_led_match_selector(p, led, false, fiber, rules, selector); -+ if (err) -+ return mv88e6xxx_led_match_selector(p, led, true, fiber, rules, selector); -+ -+ return 0; -+} -+ -+/* Sets up the hardware blinking period */ -+static int mv88e6xxx_led_set_blinking_period(struct mv88e6xxx_port *p, int led, -+ unsigned long delay_on, unsigned long delay_off) -+{ -+ unsigned long period; -+ u16 reg; -+ -+ period = delay_on + delay_off; -+ -+ reg = 0; -+ -+ switch (period) { -+ case 21: -+ reg |= MV88E6XXX_PORT_LED_CONTROL_0x06_BLINK_RATE_21MS; -+ break; -+ case 42: -+ reg |= MV88E6XXX_PORT_LED_CONTROL_0x06_BLINK_RATE_42MS; -+ break; -+ case 84: -+ reg |= MV88E6XXX_PORT_LED_CONTROL_0x06_BLINK_RATE_84MS; -+ break; -+ case 168: -+ reg |= MV88E6XXX_PORT_LED_CONTROL_0x06_BLINK_RATE_168MS; -+ break; -+ case 336: -+ reg |= MV88E6XXX_PORT_LED_CONTROL_0x06_BLINK_RATE_336MS; -+ break; -+ case 672: -+ reg |= MV88E6XXX_PORT_LED_CONTROL_0x06_BLINK_RATE_672MS; -+ break; -+ default: -+ /* Fall back to software blinking */ -+ return -EINVAL; -+ } -+ -+ /* This is essentially PWM duty cycle: how long time of the period -+ * will the LED be on. Zero isn't great in most cases. -+ */ -+ switch (delay_on) { -+ case 0: -+ /* This is usually pretty useless and will make the LED look OFF */ -+ reg |= MV88E6XXX_PORT_LED_CONTROL_0x06_PULSE_STRETCH_NONE; -+ break; -+ case 21: -+ reg |= MV88E6XXX_PORT_LED_CONTROL_0x06_PULSE_STRETCH_21MS; -+ break; -+ case 42: -+ reg |= MV88E6XXX_PORT_LED_CONTROL_0x06_PULSE_STRETCH_42MS; -+ break; -+ case 84: -+ reg |= MV88E6XXX_PORT_LED_CONTROL_0x06_PULSE_STRETCH_84MS; -+ break; -+ case 168: -+ reg |= MV88E6XXX_PORT_LED_CONTROL_0x06_PULSE_STRETCH_168MS; -+ break; -+ default: -+ /* Just use something non-zero */ -+ reg |= MV88E6XXX_PORT_LED_CONTROL_0x06_PULSE_STRETCH_21MS; -+ break; -+ } -+ -+ /* Set up blink rate */ -+ reg |= MV88E6XXX_PORT_LED_CONTROL_POINTER_STRETCH_BLINK; -+ -+ return mv88e6xxx_port_led_write(p->chip, p->port, reg); -+} -+ -+static int mv88e6xxx_led_blink_set(struct mv88e6xxx_port *p, int led, -+ unsigned long *delay_on, unsigned long *delay_off) -+{ -+ u16 reg; -+ int err; -+ -+ /* Choose a sensible default 336 ms (~3 Hz) */ -+ if ((*delay_on == 0) && (*delay_off == 0)) { -+ *delay_on = 168; -+ *delay_off = 168; -+ } -+ -+ /* No off delay is just on */ -+ if (*delay_off == 0) -+ return mv88e6xxx_led_brightness_set(p, led, 1); -+ -+ err = mv88e6xxx_led_set_blinking_period(p, led, *delay_on, *delay_off); -+ if (err) -+ return err; -+ -+ err = mv88e6xxx_port_led_read(p->chip, p->port, -+ MV88E6XXX_PORT_LED_CONTROL_POINTER_LED01_CTRL, -+ ®); -+ if (err) -+ return err; -+ -+ if (led == 1) -+ reg &= ~MV88E6XXX_PORT_LED_CONTROL_LED1_SEL_MASK; -+ else -+ reg &= ~MV88E6XXX_PORT_LED_CONTROL_LED0_SEL_MASK; -+ -+ /* This will select the forced blinking status */ -+ if (led == 1) -+ reg |= MV88E6XXX_PORT_LED_CONTROL_LED1_SELD; -+ else -+ reg |= MV88E6XXX_PORT_LED_CONTROL_LED0_SELD; -+ -+ reg |= MV88E6XXX_PORT_LED_CONTROL_POINTER_LED01_CTRL; -+ -+ return mv88e6xxx_port_led_write(p->chip, p->port, reg); -+} -+ -+static int mv88e6xxx_led0_blink_set(struct led_classdev *ldev, -+ unsigned long *delay_on, -+ unsigned long *delay_off) -+{ -+ struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led0); -+ int err; -+ -+ mv88e6xxx_reg_lock(p->chip); -+ err = mv88e6xxx_led_blink_set(p, 0, delay_on, delay_off); -+ mv88e6xxx_reg_unlock(p->chip); -+ -+ return err; -+} -+ -+static int mv88e6xxx_led1_blink_set(struct led_classdev *ldev, -+ unsigned long *delay_on, -+ unsigned long *delay_off) -+{ -+ struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led1); -+ int err; -+ -+ mv88e6xxx_reg_lock(p->chip); -+ err = mv88e6xxx_led_blink_set(p, 1, delay_on, delay_off); -+ mv88e6xxx_reg_unlock(p->chip); -+ -+ return err; -+} -+ -+static int -+mv88e6xxx_led0_hw_control_is_supported(struct led_classdev *ldev, unsigned long rules) -+{ -+ struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led0); -+ u16 selector = 0; -+ -+ return mv88e6xxx_led_get_selector(p, 0, p->fiber, rules, &selector); -+} -+ -+static int -+mv88e6xxx_led1_hw_control_is_supported(struct led_classdev *ldev, unsigned long rules) -+{ -+ struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led1); -+ u16 selector = 0; -+ -+ return mv88e6xxx_led_get_selector(p, 1, p->fiber, rules, &selector); -+} -+ -+static int mv88e6xxx_led_hw_control_set(struct mv88e6xxx_port *p, -+ int led, unsigned long rules) -+{ -+ u16 reg; -+ int err; -+ -+ err = mv88e6xxx_port_led_read(p->chip, p->port, -+ MV88E6XXX_PORT_LED_CONTROL_POINTER_LED01_CTRL, -+ ®); -+ if (err) -+ return err; -+ -+ if (led == 1) -+ reg &= ~MV88E6XXX_PORT_LED_CONTROL_LED1_SEL_MASK; -+ else -+ reg &= ~MV88E6XXX_PORT_LED_CONTROL_LED0_SEL_MASK; -+ -+ err = mv88e6xxx_led_get_selector(p, led, p->fiber, rules, ®); -+ if (err) -+ return err; -+ -+ reg |= MV88E6XXX_PORT_LED_CONTROL_POINTER_LED01_CTRL; -+ -+ if (led == 0) -+ dev_dbg(p->chip->dev, "LED 0 hw control on port %d trigger selector 0x%02x\n", -+ p->port, -+ (unsigned int)(reg & MV88E6XXX_PORT_LED_CONTROL_LED0_SEL_MASK)); -+ else -+ dev_dbg(p->chip->dev, "LED 1 hw control on port %d trigger selector 0x%02x\n", -+ p->port, -+ (unsigned int)(reg & MV88E6XXX_PORT_LED_CONTROL_LED1_SEL_MASK) >> 4); -+ -+ return mv88e6xxx_port_led_write(p->chip, p->port, reg); -+} -+ -+static int -+mv88e6xxx_led_hw_control_get(struct mv88e6xxx_port *p, int led, unsigned long *rules) -+{ -+ u16 val; -+ int err; -+ -+ mv88e6xxx_reg_lock(p->chip); -+ err = mv88e6xxx_port_led_read(p->chip, p->port, -+ MV88E6XXX_PORT_LED_CONTROL_POINTER_LED01_CTRL, &val); -+ mv88e6xxx_reg_unlock(p->chip); -+ if (err) -+ return err; -+ -+ /* Mask out the selector bits for this port */ -+ if (led == 1) { -+ val &= MV88E6XXX_PORT_LED_CONTROL_LED1_SEL_MASK; -+ /* It's forced blinking/OFF/ON */ -+ if (val == MV88E6XXX_PORT_LED_CONTROL_LED1_SELD || -+ val == MV88E6XXX_PORT_LED_CONTROL_LED1_SELE || -+ val == MV88E6XXX_PORT_LED_CONTROL_LED1_SELF) { -+ *rules = 0; -+ return 0; -+ } -+ } else { -+ val &= MV88E6XXX_PORT_LED_CONTROL_LED0_SEL_MASK; -+ /* It's forced blinking/OFF/ON */ -+ if (val == MV88E6XXX_PORT_LED_CONTROL_LED0_SELD || -+ val == MV88E6XXX_PORT_LED_CONTROL_LED0_SELE || -+ val == MV88E6XXX_PORT_LED_CONTROL_LED0_SELF) { -+ *rules = 0; -+ return 0; -+ } -+ } -+ -+ err = mv88e6xxx_led_match_rule(p, val, led, rules); -+ if (!err) -+ return 0; -+ -+ dev_dbg(p->chip->dev, "couldn't find matching selector for %04x\n", val); -+ *rules = 0; -+ return 0; -+} -+ -+static int -+mv88e6xxx_led0_hw_control_set(struct led_classdev *ldev, unsigned long rules) -+{ -+ struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led0); -+ int err; -+ -+ mv88e6xxx_reg_lock(p->chip); -+ err = mv88e6xxx_led_hw_control_set(p, 0, rules); -+ mv88e6xxx_reg_unlock(p->chip); -+ -+ return err; -+} -+ -+static int -+mv88e6xxx_led1_hw_control_set(struct led_classdev *ldev, unsigned long rules) -+{ -+ struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led1); -+ int err; -+ -+ mv88e6xxx_reg_lock(p->chip); -+ err = mv88e6xxx_led_hw_control_set(p, 1, rules); -+ mv88e6xxx_reg_unlock(p->chip); -+ -+ return err; -+} -+ -+static int -+mv88e6xxx_led0_hw_control_get(struct led_classdev *ldev, unsigned long *rules) -+{ -+ struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led0); -+ -+ return mv88e6xxx_led_hw_control_get(p, 0, rules); -+} -+ -+static int -+mv88e6xxx_led1_hw_control_get(struct led_classdev *ldev, unsigned long *rules) -+{ -+ struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led1); -+ -+ return mv88e6xxx_led_hw_control_get(p, 1, rules); -+} -+ -+static struct device *mv88e6xxx_led_hw_control_get_device(struct mv88e6xxx_port *p) -+{ -+ struct dsa_port *dp; -+ -+ dp = dsa_to_port(p->chip->ds, p->port); -+ if (!dp) -+ return NULL; -+ if (dp->user) -+ return &dp->user->dev; -+ return NULL; -+} -+ -+static struct device * -+mv88e6xxx_led0_hw_control_get_device(struct led_classdev *ldev) -+{ -+ struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led0); -+ -+ return mv88e6xxx_led_hw_control_get_device(p); -+} -+ -+static struct device * -+mv88e6xxx_led1_hw_control_get_device(struct led_classdev *ldev) -+{ -+ struct mv88e6xxx_port *p = container_of(ldev, struct mv88e6xxx_port, led1); -+ -+ return mv88e6xxx_led_hw_control_get_device(p); -+} -+ -+int mv88e6xxx_port_setup_leds(struct mv88e6xxx_chip *chip, int port) -+{ -+ struct fwnode_handle *led = NULL, *leds = NULL; -+ struct led_init_data init_data = { }; -+ enum led_default_state state; -+ struct mv88e6xxx_port *p; -+ struct led_classdev *l; -+ struct device *dev; -+ u32 led_num; -+ int ret; -+ -+ /* LEDs are on ports 1,2,3,4, 5 and 6 (index 0..5), no more */ -+ if (port > 5) -+ return -EOPNOTSUPP; -+ -+ p = &chip->ports[port]; -+ if (!p->fwnode) -+ return 0; -+ -+ dev = chip->dev; -+ -+ leds = fwnode_get_named_child_node(p->fwnode, "leds"); -+ if (!leds) { -+ dev_dbg(dev, "No Leds node specified in device tree for port %d!\n", -+ port); -+ return 0; -+ } -+ -+ fwnode_for_each_child_node(leds, led) { -+ /* Reg represent the led number of the port, max 2 -+ * LEDs can be connected to each port, in some designs -+ * only one LED is connected. -+ */ -+ if (fwnode_property_read_u32(led, "reg", &led_num)) -+ continue; -+ if (led_num > 1) { -+ dev_err(dev, "invalid LED specified port %d\n", port); -+ return -EINVAL; -+ } -+ -+ if (led_num == 0) -+ l = &p->led0; -+ else -+ l = &p->led1; -+ -+ state = led_init_default_state_get(led); -+ switch (state) { -+ case LEDS_DEFSTATE_ON: -+ l->brightness = 1; -+ mv88e6xxx_led_brightness_set(p, led_num, 1); -+ break; -+ case LEDS_DEFSTATE_KEEP: -+ break; -+ default: -+ l->brightness = 0; -+ mv88e6xxx_led_brightness_set(p, led_num, 0); -+ } -+ -+ l->max_brightness = 1; -+ if (led_num == 0) { -+ l->brightness_set_blocking = mv88e6xxx_led0_brightness_set_blocking; -+ l->blink_set = mv88e6xxx_led0_blink_set; -+ l->hw_control_is_supported = mv88e6xxx_led0_hw_control_is_supported; -+ l->hw_control_set = mv88e6xxx_led0_hw_control_set; -+ l->hw_control_get = mv88e6xxx_led0_hw_control_get; -+ l->hw_control_get_device = mv88e6xxx_led0_hw_control_get_device; -+ } else { -+ l->brightness_set_blocking = mv88e6xxx_led1_brightness_set_blocking; -+ l->blink_set = mv88e6xxx_led1_blink_set; -+ l->hw_control_is_supported = mv88e6xxx_led1_hw_control_is_supported; -+ l->hw_control_set = mv88e6xxx_led1_hw_control_set; -+ l->hw_control_get = mv88e6xxx_led1_hw_control_get; -+ l->hw_control_get_device = mv88e6xxx_led1_hw_control_get_device; -+ } -+ l->hw_control_trigger = "netdev"; -+ -+ init_data.default_label = ":port"; -+ init_data.fwnode = led; -+ init_data.devname_mandatory = true; -+ init_data.devicename = kasprintf(GFP_KERNEL, "%s:0%d:0%d", chip->info->name, -+ port, led_num); -+ if (!init_data.devicename) -+ return -ENOMEM; -+ -+ ret = devm_led_classdev_register_ext(dev, l, &init_data); -+ kfree(init_data.devicename); -+ -+ if (ret) { -+ dev_err(dev, "Failed to init LED %d for port %d", led_num, port); -+ return ret; -+ } -+ } -+ -+ return 0; -+} -diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c -index 04053fdc6489..dc777ddce1f3 100644 ---- a/drivers/net/dsa/mv88e6xxx/port.c -+++ b/drivers/net/dsa/mv88e6xxx/port.c -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - - #include "chip.h" - #include "global2.h" -diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h -index ddadeb9bfdae..c1d2f99efb1c 100644 ---- a/drivers/net/dsa/mv88e6xxx/port.h -+++ b/drivers/net/dsa/mv88e6xxx/port.h -@@ -309,6 +309,130 @@ - /* Offset 0x13: OutFiltered Counter */ - #define MV88E6XXX_PORT_OUT_FILTERED 0x13 - -+/* Offset 0x16: LED Control */ -+#define MV88E6XXX_PORT_LED_CONTROL 0x16 -+#define MV88E6XXX_PORT_LED_CONTROL_UPDATE BIT(15) -+#define MV88E6XXX_PORT_LED_CONTROL_POINTER_MASK GENMASK(14, 12) -+#define MV88E6XXX_PORT_LED_CONTROL_POINTER_LED01_CTRL (0x00 << 12) /* Control for LED 0 and 1 */ -+#define MV88E6XXX_PORT_LED_CONTROL_POINTER_STRETCH_BLINK (0x06 << 12) /* Stetch and Blink Rate */ -+#define MV88E6XXX_PORT_LED_CONTROL_POINTER_CNTL_SPECIAL (0x07 << 12) /* Control for the Port's Special LED */ -+#define MV88E6XXX_PORT_LED_CONTROL_DATA_MASK GENMASK(10, 0) -+/* Selection masks valid for either port 1,2,3,4 or 5 */ -+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SEL_MASK GENMASK(3, 0) -+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SEL_MASK GENMASK(7, 4) -+/* Selection control for LED 0 and 1, ports 5 and 6 only has LED 0 -+ * Bits Function -+ * 0..3 LED 0 control selector on ports 1-5 -+ * 4..7 LED 1 control selector on ports 1-4 on port 5 this controls LED 0 of port 6 -+ * -+ * Sel Port LED Function for the 6352 family: -+ * 0 1-4 0 Link/Act/Speed by Blink Rate (off=no link, on=link, blink=activity, blink speed=link speed) -+ * 1-4 1 Port 2's Special LED -+ * 5-6 0 Port 5 Link/Act (off=no link, on=link, blink=activity) -+ * 5-6 1 Port 6 Link/Act (off=no link, on=link 1000, blink=activity) -+ * 1 1-4 0 100/1000 Link/Act (off=no link, on=100 or 1000 link, blink=activity) -+ * 1-4 1 10/100 Link Act (off=no link, on=10 or 100 link, blink=activity) -+ * 5-6 0 Fiber 100 Link/Act (off=no link, on=link 100, blink=activity) -+ * 5-6 1 Fiber 1000 Link/Act (off=no link, on=link 1000, blink=activity) -+ * 2 1-4 0 1000 Link/Act (off=no link, on=link 1000, blink=activity) -+ * 1-4 1 10/100 Link/Act (off=no link, on=10 or 100 link, blink=activity) -+ * 5-6 0 Fiber 1000 Link/Act (off=no link, on=link 1000, blink=activity) -+ * 5-6 1 Fiber 100 Link/Act (off=no link, on=link 100, blink=activity) -+ * 3 1-4 0 Link/Act (off=no link, on=link, blink=activity) -+ * 1-4 1 1000 Link (off=no link, on=1000 link) -+ * 5-6 0 Port 0's Special LED -+ * 5-6 1 Fiber Link (off=no link, on=link) -+ * 4 1-4 0 Port 0's Special LED -+ * 1-4 1 Port 1's Special LED -+ * 5-6 0 Port 1's Special LED -+ * 5-6 1 Port 5 Link/Act (off=no link, on=link, blink=activity) -+ * 5 1-4 0 Reserved -+ * 1-4 1 Reserved -+ * 5-6 0 Port 2's Special LED -+ * 5-6 1 Port 6 Link (off=no link, on=link) -+ * 6 1-4 0 Duplex/Collision (off=half-duplex,on=full-duplex,blink=collision) -+ * 1-4 1 10/1000 Link/Act (off=no link, on=10 or 1000 link, blink=activity) -+ * 5-6 0 Port 5 Duplex/Collision (off=half-duplex, on=full-duplex, blink=col) -+ * 5-6 1 Port 6 Duplex/Collision (off=half-duplex, on=full-duplex, blink=col) -+ * 7 1-4 0 10/1000 Link/Act (off=no link, on=10 or 1000 link, blink=activity) -+ * 1-4 1 10/1000 Link (off=no link, on=10 or 1000 link) -+ * 5-6 0 Port 5 Link/Act/Speed by Blink rate (off=no link, on=link, blink=activity, blink speed=link speed) -+ * 5-6 1 Port 6 Link/Act/Speed by Blink rate (off=no link, on=link, blink=activity, blink speed=link speed) -+ * 8 1-4 0 Link (off=no link, on=link) -+ * 1-4 1 Activity (off=no link, blink on=activity) -+ * 5-6 0 Port 6 Link/Act (off=no link, on=link, blink=activity) -+ * 5-6 1 Port 0's Special LED -+ * 9 1-4 0 10 Link (off=no link, on=10 link) -+ * 1-4 1 100 Link (off=no link, on=100 link) -+ * 5-6 0 Reserved -+ * 5-6 1 Port 1's Special LED -+ * a 1-4 0 10 Link/Act (off=no link, on=10 link, blink=activity) -+ * 1-4 1 100 Link/Act (off=no link, on=100 link, blink=activity) -+ * 5-6 0 Reserved -+ * 5-6 1 Port 2's Special LED -+ * b 1-4 0 100/1000 Link (off=no link, on=100 or 1000 link) -+ * 1-4 1 10/100 Link (off=no link, on=100 link, blink=activity) -+ * 5-6 0 Reserved -+ * 5-6 1 Reserved -+ * c * * PTP Act (blink on=PTP activity) -+ * d * * Force Blink -+ * e * * Force Off -+ * f * * Force On -+ */ -+/* Select LED0 output */ -+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SEL0 0x0 -+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SEL1 0x1 -+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SEL2 0x2 -+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SEL3 0x3 -+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SEL4 0x4 -+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SEL5 0x5 -+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SEL6 0x6 -+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SEL7 0x7 -+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SEL8 0x8 -+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SEL9 0x9 -+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SELA 0xa -+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SELB 0xb -+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SELC 0xc -+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SELD 0xd -+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SELE 0xe -+#define MV88E6XXX_PORT_LED_CONTROL_LED0_SELF 0xf -+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SEL0 (0x0 << 4) -+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SEL1 (0x1 << 4) -+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SEL2 (0x2 << 4) -+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SEL3 (0x3 << 4) -+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SEL4 (0x4 << 4) -+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SEL5 (0x5 << 4) -+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SEL6 (0x6 << 4) -+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SEL7 (0x7 << 4) -+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SEL8 (0x8 << 4) -+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SEL9 (0x9 << 4) -+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SELA (0xa << 4) -+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SELB (0xb << 4) -+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SELC (0xc << 4) -+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SELD (0xd << 4) -+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SELE (0xe << 4) -+#define MV88E6XXX_PORT_LED_CONTROL_LED1_SELF (0xf << 4) -+/* Stretch and Blink Rate Control (Index 0x06 of LED Control) */ -+/* Pulse Stretch Selection for all LED's on this port */ -+#define MV88E6XXX_PORT_LED_CONTROL_0x06_PULSE_STRETCH_NONE (0 << 4) -+#define MV88E6XXX_PORT_LED_CONTROL_0x06_PULSE_STRETCH_21MS (1 << 4) -+#define MV88E6XXX_PORT_LED_CONTROL_0x06_PULSE_STRETCH_42MS (2 << 4) -+#define MV88E6XXX_PORT_LED_CONTROL_0x06_PULSE_STRETCH_84MS (3 << 4) -+#define MV88E6XXX_PORT_LED_CONTROL_0x06_PULSE_STRETCH_168MS (4 << 4) -+/* Blink Rate Selection for all LEDs on this port */ -+#define MV88E6XXX_PORT_LED_CONTROL_0x06_BLINK_RATE_21MS 0 -+#define MV88E6XXX_PORT_LED_CONTROL_0x06_BLINK_RATE_42MS 1 -+#define MV88E6XXX_PORT_LED_CONTROL_0x06_BLINK_RATE_84MS 2 -+#define MV88E6XXX_PORT_LED_CONTROL_0x06_BLINK_RATE_168MS 3 -+#define MV88E6XXX_PORT_LED_CONTROL_0x06_BLINK_RATE_336MS 4 -+#define MV88E6XXX_PORT_LED_CONTROL_0x06_BLINK_RATE_672MS 5 -+ /* Control for Special LED (Index 0x7 of LED Control on Port0) */ -+#define MV88E6XXX_PORT_LED_CONTROL_0x07_P0_LAN_LINKACT_SHIFT 0 /* bits 6:0 LAN Link Activity LED */ -+/* Control for Special LED (Index 0x7 of LED Control on Port 1) */ -+#define MV88E6XXX_PORT_LED_CONTROL_0x07_P1_WAN_LINKACT_SHIFT 0 /* bits 6:0 WAN Link Activity LED */ -+/* Control for Special LED (Index 0x7 of LED Control on Port 2) */ -+#define MV88E6XXX_PORT_LED_CONTROL_0x07_P2_PTP_ACT 0 /* bits 6:0 PTP Activity */ -+ - /* Offset 0x18: IEEE Priority Mapping Table */ - #define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE 0x18 - #define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE 0x8000 -@@ -457,6 +581,15 @@ int mv88e6393x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, - phy_interface_t mode); - int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode); - int mv88e6352_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode); -+#ifdef CONFIG_NET_DSA_MV88E6XXX_LEDS -+int mv88e6xxx_port_setup_leds(struct mv88e6xxx_chip *chip, int port); -+#else -+static inline int mv88e6xxx_port_setup_leds(struct mv88e6xxx_chip *chip, -+ int port) -+{ -+ return 0; -+} -+#endif - int mv88e6xxx_port_drop_untagged(struct mv88e6xxx_chip *chip, int port, - bool drop_untagged); - int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip *chip, int port, bool map); --- -2.51.0 - - -From 75caf17387cec21649e7981585617b6f1bd850ea Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Wed, 9 Oct 2024 07:48:05 +0200 -Subject: [PATCH 097/517] r8169: remove original workaround for RTL8125 broken - rx issue - -Now that we have b9c7ac4fe22c ("r8169: disable ALDPS per default for -RTL8125"), the first attempt to fix the issue shouldn't be needed -any longer. So let's effectively revert 621735f59064 ("r8169: fix -rare issue with broken rx after link-down on RTL8125") and see -whether anybody complains. - -Signed-off-by: Heiner Kallweit -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/382d8c88-cbce-400f-ad62-fda0181c7e38@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/r8169_main.c | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index 80b5262d0d57..4ef3a23f9f95 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -4813,11 +4813,7 @@ static void r8169_phylink_handler(struct net_device *ndev) - if (netif_carrier_ok(ndev)) { - rtl_link_chg_patch(tp); - pm_request_resume(d); -- netif_wake_queue(tp->dev); - } else { -- /* In few cases rx is broken after link-down otherwise */ -- if (rtl_is_8125(tp)) -- rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE); - pm_runtime_idle(d); - } - --- -2.51.0 - - -From 876e8c0219f3c916926131747aded27d275a1cfd Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Thu, 10 Oct 2024 12:58:02 +0200 -Subject: [PATCH 098/517] r8169: enable SG/TSO on selected chip versions per - default - -Due to problem reports in the past SG and TSO/TSO6 are disabled per -default. It's not fully clear which chip versions are affected, so we -may impact also users of unaffected chip versions, unless they know -how to use ethtool for enabling SG/TSO/TSO6. -Vendor drivers r8168/r8125 enable SG/TSO/TSO6 for selected chip -versions per default, I'd interpret this as confirmation that these -chip versions are unaffected. So let's do the same here. - -Signed-off-by: Heiner Kallweit -Reviewed-by: Simon Horman -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/realtek/r8169_main.c | 16 +++++++++++----- - 1 file changed, 11 insertions(+), 5 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index 4ef3a23f9f95..9a01b5a9facd 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -5527,11 +5527,6 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) - - dev->features |= dev->hw_features; - -- /* There has been a number of reports that using SG/TSO results in -- * tx timeouts. However for a lot of people SG/TSO works fine. -- * Therefore disable both features by default, but allow users to -- * enable them. Use at own risk! -- */ - if (rtl_chip_supports_csum_v2(tp)) { - dev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6; - netif_set_tso_max_size(dev, RTL_GSO_MAX_SIZE_V2); -@@ -5542,6 +5537,17 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) - netif_set_tso_max_segs(dev, RTL_GSO_MAX_SEGS_V1); - } - -+ /* There has been a number of reports that using SG/TSO results in -+ * tx timeouts. However for a lot of people SG/TSO works fine. -+ * It's not fully clear which chip versions are affected. Vendor -+ * drivers enable SG/TSO for certain chip versions per default, -+ * let's mimic this here. On other chip versions users can -+ * use ethtool to enable SG/TSO, use at own risk! -+ */ -+ if (tp->mac_version >= RTL_GIGA_MAC_VER_46 && -+ tp->mac_version != RTL_GIGA_MAC_VER_61) -+ dev->features |= dev->hw_features; -+ - dev->hw_features |= NETIF_F_RXALL; - dev->hw_features |= NETIF_F_RXFCS; - --- -2.51.0 - - -From cc333d732be713e617a9e2673d01e660ca905e2e Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Sun, 13 Oct 2024 11:17:39 +0200 -Subject: [PATCH 099/517] r8169: implement additional ethtool stats ops - -This adds support for ethtool standard statistics, and makes use of the -extended hardware statistics being available from RTl8125. - -Signed-off-by: Heiner Kallweit -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/58e0da73-a7dd-4be3-82ae-d5b3f9069bde@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/r8169_main.c | 82 +++++++++++++++++++++++ - 1 file changed, 82 insertions(+) - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index 9a01b5a9facd..27633b4802f8 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -2160,6 +2160,19 @@ static void rtl8169_get_ringparam(struct net_device *dev, - data->tx_pending = NUM_TX_DESC; - } - -+static void rtl8169_get_pause_stats(struct net_device *dev, -+ struct ethtool_pause_stats *pause_stats) -+{ -+ struct rtl8169_private *tp = netdev_priv(dev); -+ -+ if (!rtl_is_8125(tp)) -+ return; -+ -+ rtl8169_update_counters(tp); -+ pause_stats->tx_pause_frames = le32_to_cpu(tp->counters->tx_pause_on); -+ pause_stats->rx_pause_frames = le32_to_cpu(tp->counters->rx_pause_on); -+} -+ - static void rtl8169_get_pauseparam(struct net_device *dev, - struct ethtool_pauseparam *data) - { -@@ -2186,6 +2199,69 @@ static int rtl8169_set_pauseparam(struct net_device *dev, - return 0; - } - -+static void rtl8169_get_eth_mac_stats(struct net_device *dev, -+ struct ethtool_eth_mac_stats *mac_stats) -+{ -+ struct rtl8169_private *tp = netdev_priv(dev); -+ -+ rtl8169_update_counters(tp); -+ -+ mac_stats->FramesTransmittedOK = -+ le64_to_cpu(tp->counters->tx_packets); -+ mac_stats->SingleCollisionFrames = -+ le32_to_cpu(tp->counters->tx_one_collision); -+ mac_stats->MultipleCollisionFrames = -+ le32_to_cpu(tp->counters->tx_multi_collision); -+ mac_stats->FramesReceivedOK = -+ le64_to_cpu(tp->counters->rx_packets); -+ mac_stats->AlignmentErrors = -+ le16_to_cpu(tp->counters->align_errors); -+ mac_stats->FramesLostDueToIntMACXmitError = -+ le64_to_cpu(tp->counters->tx_errors); -+ mac_stats->BroadcastFramesReceivedOK = -+ le64_to_cpu(tp->counters->rx_broadcast); -+ mac_stats->MulticastFramesReceivedOK = -+ le32_to_cpu(tp->counters->rx_multicast); -+ -+ if (!rtl_is_8125(tp)) -+ return; -+ -+ mac_stats->AlignmentErrors = -+ le32_to_cpu(tp->counters->align_errors32); -+ mac_stats->OctetsTransmittedOK = -+ le64_to_cpu(tp->counters->tx_octets); -+ mac_stats->LateCollisions = -+ le32_to_cpu(tp->counters->tx_late_collision); -+ mac_stats->FramesAbortedDueToXSColls = -+ le32_to_cpu(tp->counters->tx_aborted32); -+ mac_stats->OctetsReceivedOK = -+ le64_to_cpu(tp->counters->rx_octets); -+ mac_stats->FramesLostDueToIntMACRcvError = -+ le32_to_cpu(tp->counters->rx_mac_error); -+ mac_stats->MulticastFramesXmittedOK = -+ le64_to_cpu(tp->counters->tx_multicast64); -+ mac_stats->BroadcastFramesXmittedOK = -+ le64_to_cpu(tp->counters->tx_broadcast64); -+ mac_stats->MulticastFramesReceivedOK = -+ le64_to_cpu(tp->counters->rx_multicast64); -+ mac_stats->FrameTooLongErrors = -+ le32_to_cpu(tp->counters->rx_frame_too_long); -+} -+ -+static void rtl8169_get_eth_ctrl_stats(struct net_device *dev, -+ struct ethtool_eth_ctrl_stats *ctrl_stats) -+{ -+ struct rtl8169_private *tp = netdev_priv(dev); -+ -+ if (!rtl_is_8125(tp)) -+ return; -+ -+ rtl8169_update_counters(tp); -+ -+ ctrl_stats->UnsupportedOpcodesReceived = -+ le32_to_cpu(tp->counters->rx_unknown_opcode); -+} -+ - static const struct ethtool_ops rtl8169_ethtool_ops = { - .supported_coalesce_params = ETHTOOL_COALESCE_USECS | - ETHTOOL_COALESCE_MAX_FRAMES, -@@ -2207,8 +2283,11 @@ static const struct ethtool_ops rtl8169_ethtool_ops = { - .get_link_ksettings = phy_ethtool_get_link_ksettings, - .set_link_ksettings = phy_ethtool_set_link_ksettings, - .get_ringparam = rtl8169_get_ringparam, -+ .get_pause_stats = rtl8169_get_pause_stats, - .get_pauseparam = rtl8169_get_pauseparam, - .set_pauseparam = rtl8169_set_pauseparam, -+ .get_eth_mac_stats = rtl8169_get_eth_mac_stats, -+ .get_eth_ctrl_stats = rtl8169_get_eth_ctrl_stats, - }; - - static enum mac_version rtl8169_get_mac_version(u16 xid, bool gmii) -@@ -3929,6 +4008,9 @@ static void rtl_hw_start_8125(struct rtl8169_private *tp) - break; - } - -+ /* enable extended tally counter */ -+ r8168_mac_ocp_modify(tp, 0xea84, 0, BIT(1) | BIT(0)); -+ - rtl_hw_config(tp); - } - --- -2.51.0 - - -From 346f3face3f8c7e50c37eb4c9afa0fedc0231401 Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Wed, 16 Oct 2024 22:05:57 +0200 -Subject: [PATCH 100/517] r8169: don't take RTNL lock in rtl_task() - -There's not really a benefit here in taking the RTNL lock. The task -handler does exception handling only, so we're in trouble anyway when -we come here, and there's no need to protect against e.g. a parallel -ethtool call. -A benefit of removing the RTNL lock here is that we now can -synchronously cancel the workqueue from a context holding the RTNL mutex. - -Signed-off-by: Heiner Kallweit -Signed-off-by: Andrew Lunn ---- - drivers/net/ethernet/realtek/r8169_main.c | 8 ++------ - 1 file changed, 2 insertions(+), 6 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index 27633b4802f8..793c3740b623 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -4836,10 +4836,8 @@ static void rtl_task(struct work_struct *work) - container_of(work, struct rtl8169_private, wk.work); - int ret; - -- rtnl_lock(); -- - if (!test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags)) -- goto out_unlock; -+ return; - - if (test_and_clear_bit(RTL_FLAG_TASK_TX_TIMEOUT, tp->wk.flags)) { - /* if chip isn't accessible, reset bus to revive it */ -@@ -4848,7 +4846,7 @@ static void rtl_task(struct work_struct *work) - if (ret < 0) { - netdev_err(tp->dev, "Can't reset secondary PCI bus, detach NIC\n"); - netif_device_detach(tp->dev); -- goto out_unlock; -+ return; - } - } - -@@ -4867,8 +4865,6 @@ static void rtl_task(struct work_struct *work) - } else if (test_and_clear_bit(RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE, tp->wk.flags)) { - rtl_reset_work(tp); - } --out_unlock: -- rtnl_unlock(); - } - - static int rtl8169_poll(struct napi_struct *napi, int budget) --- -2.51.0 - - -From 946357f990b9bdbdfcea45e565acafab66b877f8 Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Wed, 16 Oct 2024 22:06:53 +0200 -Subject: [PATCH 101/517] r8169: replace custom flag with disable_work() et al - -So far we use a custom flag to define when a task can be scheduled and -when not. Let's use the standard mechanism with disable_work() et al -instead. -Note that in rtl8169_close() we can remove the call to cancel_work() -because we now call disable_work_sync() in rtl8169_down() already. - -Signed-off-by: Heiner Kallweit -Signed-off-by: Andrew Lunn ---- - drivers/net/ethernet/realtek/r8169_main.c | 18 ++++++------------ - 1 file changed, 6 insertions(+), 12 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index 793c3740b623..a4d659612c0b 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -619,7 +619,6 @@ struct rtl8169_tc_offsets { - }; - - enum rtl_flag { -- RTL_FLAG_TASK_ENABLED = 0, - RTL_FLAG_TASK_RESET_PENDING, - RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE, - RTL_FLAG_TASK_TX_TIMEOUT, -@@ -2505,11 +2504,9 @@ u16 rtl8168h_2_get_adc_bias_ioffset(struct rtl8169_private *tp) - - static void rtl_schedule_task(struct rtl8169_private *tp, enum rtl_flag flag) - { -- if (!test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags)) -- return; -- - set_bit(flag, tp->wk.flags); -- schedule_work(&tp->wk.work); -+ if (!schedule_work(&tp->wk.work)) -+ clear_bit(flag, tp->wk.flags); - } - - static void rtl8169_init_phy(struct rtl8169_private *tp) -@@ -4836,9 +4833,6 @@ static void rtl_task(struct work_struct *work) - container_of(work, struct rtl8169_private, wk.work); - int ret; - -- if (!test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags)) -- return; -- - if (test_and_clear_bit(RTL_FLAG_TASK_TX_TIMEOUT, tp->wk.flags)) { - /* if chip isn't accessible, reset bus to revive it */ - if (RTL_R32(tp, TxConfig) == ~0) { -@@ -4922,6 +4916,7 @@ static int r8169_phy_connect(struct rtl8169_private *tp) - - static void rtl8169_down(struct rtl8169_private *tp) - { -+ disable_work_sync(&tp->wk.work); - /* Clear all task flags */ - bitmap_zero(tp->wk.flags, RTL_FLAG_MAX); - -@@ -4950,7 +4945,7 @@ static void rtl8169_up(struct rtl8169_private *tp) - phy_resume(tp->phydev); - rtl8169_init_phy(tp); - napi_enable(&tp->napi); -- set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags); -+ enable_work(&tp->wk.work); - rtl_reset_work(tp); - - phy_start(tp->phydev); -@@ -4967,8 +4962,6 @@ static int rtl8169_close(struct net_device *dev) - rtl8169_down(tp); - rtl8169_rx_clear(tp); - -- cancel_work(&tp->wk.work); -- - free_irq(tp->irq, tp); - - phy_disconnect(tp->phydev); -@@ -5202,7 +5195,7 @@ static void rtl_remove_one(struct pci_dev *pdev) - if (pci_dev_run_wake(pdev)) - pm_runtime_get_noresume(&pdev->dev); - -- cancel_work_sync(&tp->wk.work); -+ disable_work_sync(&tp->wk.work); - - if (IS_ENABLED(CONFIG_R8169_LEDS)) - r8169_remove_leds(tp->leds); -@@ -5580,6 +5573,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) - tp->irq = pci_irq_vector(pdev, 0); - - INIT_WORK(&tp->wk.work, rtl_task); -+ disable_work(&tp->wk.work); - - rtl_init_mac_address(tp); - --- -2.51.0 - - -From a96d084288956bdc353e2d978982680e65c30f55 Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Wed, 16 Oct 2024 22:29:39 +0200 -Subject: [PATCH 102/517] r8169: avoid duplicated messages if loading firmware - fails and switch to warn level - -In case of a problem with firmware loading we inform at the driver level, -in addition the firmware load code itself issues warnings. Therefore -switch to firmware_request_nowarn() to avoid duplicated error messages. -In addition switch to warn level because the firmware is optional and -typically just fixes compatibility issues. - -Signed-off-by: Heiner Kallweit -Reviewed-by: Simon Horman -Message-ID: -Signed-off-by: Andrew Lunn ---- - drivers/net/ethernet/realtek/r8169_firmware.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/r8169_firmware.c b/drivers/net/ethernet/realtek/r8169_firmware.c -index ed6e721b1555..bf055078a855 100644 ---- a/drivers/net/ethernet/realtek/r8169_firmware.c -+++ b/drivers/net/ethernet/realtek/r8169_firmware.c -@@ -215,7 +215,7 @@ int rtl_fw_request_firmware(struct rtl_fw *rtl_fw) - { - int rc; - -- rc = request_firmware(&rtl_fw->fw, rtl_fw->fw_name, rtl_fw->dev); -+ rc = firmware_request_nowarn(&rtl_fw->fw, rtl_fw->fw_name, rtl_fw->dev); - if (rc < 0) - goto out; - -@@ -227,7 +227,7 @@ int rtl_fw_request_firmware(struct rtl_fw *rtl_fw) - - return 0; - out: -- dev_err(rtl_fw->dev, "Unable to load firmware %s (%d)\n", -- rtl_fw->fw_name, rc); -+ dev_warn(rtl_fw->dev, "Unable to load firmware %s (%d)\n", -+ rtl_fw->fw_name, rc); - return rc; - } --- -2.51.0 - - -From 56661855d12fe1c72a1028936f9d3e5fb9c82478 Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Wed, 16 Oct 2024 22:31:10 +0200 -Subject: [PATCH 103/517] r8169: remove rtl_dash_loop_wait_high/low - -Remove rtl_dash_loop_wait_high/low to simplify the code. - -Signed-off-by: Heiner Kallweit -Reviewed-by: Simon Horman -Message-ID: -Signed-off-by: Andrew Lunn ---- - drivers/net/ethernet/realtek/r8169_main.c | 35 ++++++----------------- - 1 file changed, 8 insertions(+), 27 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index a4d659612c0b..d9682329f6e7 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -1348,40 +1348,19 @@ static void rtl8168ep_stop_cmac(struct rtl8169_private *tp) - RTL_W8(tp, IBCR0, RTL_R8(tp, IBCR0) & ~0x01); - } - --static void rtl_dash_loop_wait(struct rtl8169_private *tp, -- const struct rtl_cond *c, -- unsigned long usecs, int n, bool high) --{ -- if (!tp->dash_enabled) -- return; -- rtl_loop_wait(tp, c, usecs, n, high); --} -- --static void rtl_dash_loop_wait_high(struct rtl8169_private *tp, -- const struct rtl_cond *c, -- unsigned long d, int n) --{ -- rtl_dash_loop_wait(tp, c, d, n, true); --} -- --static void rtl_dash_loop_wait_low(struct rtl8169_private *tp, -- const struct rtl_cond *c, -- unsigned long d, int n) --{ -- rtl_dash_loop_wait(tp, c, d, n, false); --} -- - static void rtl8168dp_driver_start(struct rtl8169_private *tp) - { - r8168dp_oob_notify(tp, OOB_CMD_DRIVER_START); -- rtl_dash_loop_wait_high(tp, &rtl_dp_ocp_read_cond, 10000, 10); -+ if (tp->dash_enabled) -+ rtl_loop_wait_high(tp, &rtl_dp_ocp_read_cond, 10000, 10); - } - - static void rtl8168ep_driver_start(struct rtl8169_private *tp) - { - r8168ep_ocp_write(tp, 0x01, 0x180, OOB_CMD_DRIVER_START); - r8168ep_ocp_write(tp, 0x01, 0x30, r8168ep_ocp_read(tp, 0x30) | 0x01); -- rtl_dash_loop_wait_high(tp, &rtl_ep_ocp_read_cond, 10000, 30); -+ if (tp->dash_enabled) -+ rtl_loop_wait_high(tp, &rtl_ep_ocp_read_cond, 10000, 30); - } - - static void rtl8168_driver_start(struct rtl8169_private *tp) -@@ -1395,7 +1374,8 @@ static void rtl8168_driver_start(struct rtl8169_private *tp) - static void rtl8168dp_driver_stop(struct rtl8169_private *tp) - { - r8168dp_oob_notify(tp, OOB_CMD_DRIVER_STOP); -- rtl_dash_loop_wait_low(tp, &rtl_dp_ocp_read_cond, 10000, 10); -+ if (tp->dash_enabled) -+ rtl_loop_wait_low(tp, &rtl_dp_ocp_read_cond, 10000, 10); - } - - static void rtl8168ep_driver_stop(struct rtl8169_private *tp) -@@ -1403,7 +1383,8 @@ static void rtl8168ep_driver_stop(struct rtl8169_private *tp) - rtl8168ep_stop_cmac(tp); - r8168ep_ocp_write(tp, 0x01, 0x180, OOB_CMD_DRIVER_STOP); - r8168ep_ocp_write(tp, 0x01, 0x30, r8168ep_ocp_read(tp, 0x30) | 0x01); -- rtl_dash_loop_wait_low(tp, &rtl_ep_ocp_read_cond, 10000, 10); -+ if (tp->dash_enabled) -+ rtl_loop_wait_low(tp, &rtl_ep_ocp_read_cond, 10000, 10); - } - - static void rtl8168_driver_stop(struct rtl8169_private *tp) --- -2.51.0 - - -From 7f019b21702006b9e9dd50ad8c9e2107face00db Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Thu, 17 Oct 2024 22:27:44 +0200 -Subject: [PATCH 104/517] r8169: enable EEE at 2.5G per default on RTL8125B - -Register a6d/12 is shadowing register MDIO_AN_EEE_ADV2. So this line -disables advertisement of EEE at 2.5G. Latest vendor driver r8125 -doesn't do this (any longer?), so this mode seems to be safe. -EEE saves quite some energy, therefore enable this mode per default. - -Signed-off-by: Heiner Kallweit -Reviewed-by: Simon Horman -Message-ID: <95dd5a0c-09ea-4847-94d9-b7aa3063e8ff@gmail.com> -Signed-off-by: Andrew Lunn ---- - drivers/net/ethernet/realtek/r8169_phy_config.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/drivers/net/ethernet/realtek/r8169_phy_config.c b/drivers/net/ethernet/realtek/r8169_phy_config.c -index d09b2a41cd06..8739f4b42aaf 100644 ---- a/drivers/net/ethernet/realtek/r8169_phy_config.c -+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c -@@ -99,7 +99,6 @@ static void rtl8125a_config_eee_phy(struct phy_device *phydev) - - static void rtl8125b_config_eee_phy(struct phy_device *phydev) - { -- phy_modify_paged(phydev, 0xa6d, 0x12, 0x0001, 0x0000); - phy_modify_paged(phydev, 0xa6d, 0x14, 0x0010, 0x0000); - phy_modify_paged(phydev, 0xa42, 0x14, 0x0080, 0x0000); - phy_modify_paged(phydev, 0xa4a, 0x11, 0x0200, 0x0000); --- -2.51.0 - - -From 28b4af371b12a73bf9a0fef04753076b4d5446e1 Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Thu, 24 Oct 2024 22:48:59 +0200 -Subject: [PATCH 105/517] r8169: fix inconsistent indenting in - rtl8169_get_eth_mac_stats - -This fixes an inconsistent indenting introduced with e3fc5139bd8f -("r8169: implement additional ethtool stats ops"). - -Reported-by: kernel test robot -Closes: https://lore.kernel.org/oe-kbuild-all/202410220413.1gAxIJ4t-lkp@intel.com/ -Signed-off-by: Heiner Kallweit -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20fd6f39-3c1b-4af0-9adc-7d1f49728fad@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/r8169_main.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index d9682329f6e7..0091f1460036 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -2224,7 +2224,7 @@ static void rtl8169_get_eth_mac_stats(struct net_device *dev, - le64_to_cpu(tp->counters->tx_broadcast64); - mac_stats->MulticastFramesReceivedOK = - le64_to_cpu(tp->counters->rx_multicast64); -- mac_stats->FrameTooLongErrors = -+ mac_stats->FrameTooLongErrors = - le32_to_cpu(tp->counters->rx_frame_too_long); - } - --- -2.51.0 - - -From c325ddc8e8248f828deef9638176039f3f83eae5 Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Thu, 31 Oct 2024 22:42:52 +0100 -Subject: [PATCH 106/517] r8169: align RTL8125 EEE config with vendor driver - -Align the EEE config for RTL8125A/RTL8125B with vendor driver r8125. -This should help to avoid compatibility issues. - -Signed-off-by: Heiner Kallweit -Link: https://patch.msgid.link/044c925e-8669-4b98-87df-95b4056f4f5f@gmail.com -Signed-off-by: Jakub Kicinski ---- - .../net/ethernet/realtek/r8169_phy_config.c | 18 ++++++++++++------ - 1 file changed, 12 insertions(+), 6 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/r8169_phy_config.c b/drivers/net/ethernet/realtek/r8169_phy_config.c -index 8739f4b42aaf..a0ecfa9c60ae 100644 ---- a/drivers/net/ethernet/realtek/r8169_phy_config.c -+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c -@@ -89,19 +89,25 @@ static void rtl8168h_config_eee_phy(struct phy_device *phydev) - phy_modify_paged(phydev, 0xa42, 0x14, 0x0000, 0x0080); - } - --static void rtl8125a_config_eee_phy(struct phy_device *phydev) -+static void rtl8125_common_config_eee_phy(struct phy_device *phydev) - { -- rtl8168h_config_eee_phy(phydev); -+ phy_modify_paged(phydev, 0xa6d, 0x14, 0x0010, 0x0000); -+ phy_modify_paged(phydev, 0xa42, 0x14, 0x0080, 0x0000); -+ phy_modify_paged(phydev, 0xa4a, 0x11, 0x0200, 0x0000); -+} - -+static void rtl8125a_config_eee_phy(struct phy_device *phydev) -+{ -+ rtl8168g_config_eee_phy(phydev); -+ /* disable EEE at 2.5Gbps */ - phy_modify_paged(phydev, 0xa6d, 0x12, 0x0001, 0x0000); -- phy_modify_paged(phydev, 0xa6d, 0x14, 0x0010, 0x0000); -+ rtl8125_common_config_eee_phy(phydev); - } - - static void rtl8125b_config_eee_phy(struct phy_device *phydev) - { -- phy_modify_paged(phydev, 0xa6d, 0x14, 0x0010, 0x0000); -- phy_modify_paged(phydev, 0xa42, 0x14, 0x0080, 0x0000); -- phy_modify_paged(phydev, 0xa4a, 0x11, 0x0200, 0x0000); -+ rtl8168g_config_eee_phy(phydev); -+ rtl8125_common_config_eee_phy(phydev); - } - - static void rtl8169s_hw_phy_config(struct rtl8169_private *tp, --- -2.51.0 - - -From 0ec8e3bb0f649ceb7c034d76957b3e74999f95dd Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Thu, 31 Oct 2024 22:43:45 +0100 -Subject: [PATCH 107/517] r8169: align RTL8125/RTL8126 PHY config with vendor - driver - -This aligns some parameters with vendor driver r8125/r8126 to avoid -compatibility issues. Note that for RTL8125B there's no functional -change, just the open-coded version of the function is replaced. - -Signed-off-by: Heiner Kallweit -Link: https://patch.msgid.link/a8a9d896-fbe6-41f2-bf87-666567d3cdb3@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/r8169_phy_config.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/ethernet/realtek/r8169_phy_config.c b/drivers/net/ethernet/realtek/r8169_phy_config.c -index a0ecfa9c60ae..54b254b9bf6c 100644 ---- a/drivers/net/ethernet/realtek/r8169_phy_config.c -+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c -@@ -1073,8 +1073,8 @@ static void rtl8125b_hw_phy_config(struct rtl8169_private *tp, - struct phy_device *phydev) - { - r8169_apply_firmware(tp); -+ rtl8168g_enable_gphy_10m(phydev); - -- phy_modify_paged(phydev, 0xa44, 0x11, 0x0000, 0x0800); - phy_modify_paged(phydev, 0xac4, 0x13, 0x00f0, 0x0090); - phy_modify_paged(phydev, 0xad3, 0x10, 0x0003, 0x0001); - -@@ -1113,6 +1113,7 @@ static void rtl8125d_hw_phy_config(struct rtl8169_private *tp, - struct phy_device *phydev) - { - r8169_apply_firmware(tp); -+ rtl8168g_enable_gphy_10m(phydev); - rtl8125_legacy_force_mode(phydev); - rtl8168g_disable_aldps(phydev); - rtl8125b_config_eee_phy(phydev); -@@ -1122,6 +1123,9 @@ static void rtl8126a_hw_phy_config(struct rtl8169_private *tp, - struct phy_device *phydev) - { - r8169_apply_firmware(tp); -+ rtl8168g_enable_gphy_10m(phydev); -+ rtl8125_legacy_force_mode(phydev); -+ rtl8168g_disable_aldps(phydev); - } - - void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev, --- -2.51.0 - - -From 390ace441dd012d005dddb5aed3bfb7e022f4c2a Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Thu, 31 Oct 2024 22:44:36 +0100 -Subject: [PATCH 108/517] r8169: align RTL8126 EEE config with vendor driver - -Align the EEE config for RTL8126A with vendor driver r8126 to avoid -compatibility issues. - -Signed-off-by: Heiner Kallweit -Link: https://patch.msgid.link/71e4859e-4cd0-4b6b-b7fa-621d7721992f@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/r8169_phy_config.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/net/ethernet/realtek/r8169_phy_config.c b/drivers/net/ethernet/realtek/r8169_phy_config.c -index 54b254b9bf6c..1d5b33f6c4b5 100644 ---- a/drivers/net/ethernet/realtek/r8169_phy_config.c -+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c -@@ -1126,6 +1126,7 @@ static void rtl8126a_hw_phy_config(struct rtl8169_private *tp, - rtl8168g_enable_gphy_10m(phydev); - rtl8125_legacy_force_mode(phydev); - rtl8168g_disable_aldps(phydev); -+ rtl8125_common_config_eee_phy(phydev); - } - - void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev, --- -2.51.0 - - -From b40777ebd76e985658185127b635c20e00c38199 Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Sat, 2 Nov 2024 14:49:01 +0100 -Subject: [PATCH 109/517] r8169: improve initialization of RSS registers on - RTL8125/RTL8126 - -Replace the register addresses with the names used in r8125/r8126 -vendor driver, and consider that RSS_CTRL_8125 is a 32 bit register. - -Signed-off-by: Heiner Kallweit -Link: https://patch.msgid.link/3bf2f340-b369-4174-97bf-fd38d4217492@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/r8169_main.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index 0091f1460036..ab8300984a2b 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -346,6 +346,8 @@ enum rtl8125_registers { - TxPoll_8125 = 0x90, - LEDSEL3 = 0x96, - MAC0_BKP = 0x19e0, -+ RSS_CTRL_8125 = 0x4500, -+ Q_NUM_CTRL_8125 = 0x4800, - EEE_TXIDLE_TIMER_8125 = 0x6048, - }; - -@@ -3791,8 +3793,8 @@ static void rtl_hw_start_8125_common(struct rtl8169_private *tp) - rtl_pcie_state_l2l3_disable(tp); - - RTL_W16(tp, 0x382, 0x221b); -- RTL_W8(tp, 0x4500, 0); -- RTL_W16(tp, 0x4800, 0); -+ RTL_W32(tp, RSS_CTRL_8125, 0); -+ RTL_W16(tp, Q_NUM_CTRL_8125, 0); - - /* disable UPS */ - r8168_mac_ocp_modify(tp, 0xd40a, 0x0010, 0x0000); --- -2.51.0 - - -From aa67f9dc507adfc19a82b9392692926658de1590 Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Mon, 4 Nov 2024 23:16:20 +0100 -Subject: [PATCH 110/517] r8169: remove leftover locks after reverted change - -After e31a9fedc7d8 ("Revert "r8169: disable ASPM during NAPI poll"") -these locks aren't needed any longer. - -Signed-off-by: Heiner Kallweit -Link: https://patch.msgid.link/680f2606-ac7d-4ced-8694-e5033855da9b@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/r8169_main.c | 29 ++--------------------- - 1 file changed, 2 insertions(+), 27 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index ab8300984a2b..5d708053c37c 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -661,13 +661,9 @@ struct rtl8169_private { - struct work_struct work; - } wk; - -- raw_spinlock_t config25_lock; - raw_spinlock_t mac_ocp_lock; - struct mutex led_lock; /* serialize LED ctrl RMW access */ - -- raw_spinlock_t cfg9346_usage_lock; -- int cfg9346_usage_count; -- - unsigned supports_gmii:1; - unsigned aspm_manageable:1; - unsigned dash_enabled:1; -@@ -721,22 +717,12 @@ static inline struct device *tp_to_dev(struct rtl8169_private *tp) - - static void rtl_lock_config_regs(struct rtl8169_private *tp) - { -- unsigned long flags; -- -- raw_spin_lock_irqsave(&tp->cfg9346_usage_lock, flags); -- if (!--tp->cfg9346_usage_count) -- RTL_W8(tp, Cfg9346, Cfg9346_Lock); -- raw_spin_unlock_irqrestore(&tp->cfg9346_usage_lock, flags); -+ RTL_W8(tp, Cfg9346, Cfg9346_Lock); - } - - static void rtl_unlock_config_regs(struct rtl8169_private *tp) - { -- unsigned long flags; -- -- raw_spin_lock_irqsave(&tp->cfg9346_usage_lock, flags); -- if (!tp->cfg9346_usage_count++) -- RTL_W8(tp, Cfg9346, Cfg9346_Unlock); -- raw_spin_unlock_irqrestore(&tp->cfg9346_usage_lock, flags); -+ RTL_W8(tp, Cfg9346, Cfg9346_Unlock); - } - - static void rtl_pci_commit(struct rtl8169_private *tp) -@@ -747,24 +733,18 @@ static void rtl_pci_commit(struct rtl8169_private *tp) - - static void rtl_mod_config2(struct rtl8169_private *tp, u8 clear, u8 set) - { -- unsigned long flags; - u8 val; - -- raw_spin_lock_irqsave(&tp->config25_lock, flags); - val = RTL_R8(tp, Config2); - RTL_W8(tp, Config2, (val & ~clear) | set); -- raw_spin_unlock_irqrestore(&tp->config25_lock, flags); - } - - static void rtl_mod_config5(struct rtl8169_private *tp, u8 clear, u8 set) - { -- unsigned long flags; - u8 val; - -- raw_spin_lock_irqsave(&tp->config25_lock, flags); - val = RTL_R8(tp, Config5); - RTL_W8(tp, Config5, (val & ~clear) | set); -- raw_spin_unlock_irqrestore(&tp->config25_lock, flags); - } - - static bool rtl_is_8125(struct rtl8169_private *tp) -@@ -1570,7 +1550,6 @@ static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts) - { WAKE_MAGIC, Config3, MagicPacket } - }; - unsigned int i, tmp = ARRAY_SIZE(cfg); -- unsigned long flags; - u8 options; - - rtl_unlock_config_regs(tp); -@@ -1589,14 +1568,12 @@ static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts) - r8168_mac_ocp_modify(tp, 0xc0b6, BIT(0), 0); - } - -- raw_spin_lock_irqsave(&tp->config25_lock, flags); - for (i = 0; i < tmp; i++) { - options = RTL_R8(tp, cfg[i].reg) & ~cfg[i].mask; - if (wolopts & cfg[i].opt) - options |= cfg[i].mask; - RTL_W8(tp, cfg[i].reg, options); - } -- raw_spin_unlock_irqrestore(&tp->config25_lock, flags); - - switch (tp->mac_version) { - case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06: -@@ -5480,8 +5457,6 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) - tp->supports_gmii = ent->driver_data == RTL_CFG_NO_GBIT ? 0 : 1; - tp->ocp_base = OCP_STD_PHY_BASE; - -- raw_spin_lock_init(&tp->cfg9346_usage_lock); -- raw_spin_lock_init(&tp->config25_lock); - raw_spin_lock_init(&tp->mac_ocp_lock); - mutex_init(&tp->led_lock); - --- -2.51.0 - - -From 70713cb39f81777f2e78d556869f76dbc9ec6879 Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Wed, 6 Nov 2024 17:55:45 +0100 -Subject: [PATCH 111/517] r8169: improve __rtl8169_set_wol - -Add helper r8169_mod_reg8_cond() what allows to significantly simplify -__rtl8169_set_wol(). - -Signed-off-by: Heiner Kallweit -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/697b197a-8eac-40c6-8847-27093cacec36@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/r8169_main.c | 55 ++++++++++------------- - 1 file changed, 24 insertions(+), 31 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index 5d708053c37c..bb5784654cec 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -747,6 +747,20 @@ static void rtl_mod_config5(struct rtl8169_private *tp, u8 clear, u8 set) - RTL_W8(tp, Config5, (val & ~clear) | set); - } - -+static void r8169_mod_reg8_cond(struct rtl8169_private *tp, int reg, -+ u8 bits, bool cond) -+{ -+ u8 val, old_val; -+ -+ old_val = RTL_R8(tp, reg); -+ if (cond) -+ val = old_val | bits; -+ else -+ val = old_val & ~bits; -+ if (val != old_val) -+ RTL_W8(tp, reg, val); -+} -+ - static bool rtl_is_8125(struct rtl8169_private *tp) - { - return tp->mac_version >= RTL_GIGA_MAC_VER_61; -@@ -1537,58 +1551,37 @@ static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) - - static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts) - { -- static const struct { -- u32 opt; -- u16 reg; -- u8 mask; -- } cfg[] = { -- { WAKE_PHY, Config3, LinkUp }, -- { WAKE_UCAST, Config5, UWF }, -- { WAKE_BCAST, Config5, BWF }, -- { WAKE_MCAST, Config5, MWF }, -- { WAKE_ANY, Config5, LanWake }, -- { WAKE_MAGIC, Config3, MagicPacket } -- }; -- unsigned int i, tmp = ARRAY_SIZE(cfg); -- u8 options; -- - rtl_unlock_config_regs(tp); - - if (rtl_is_8168evl_up(tp)) { -- tmp--; - if (wolopts & WAKE_MAGIC) - rtl_eri_set_bits(tp, 0x0dc, MagicPacket_v2); - else - rtl_eri_clear_bits(tp, 0x0dc, MagicPacket_v2); - } else if (rtl_is_8125(tp)) { -- tmp--; - if (wolopts & WAKE_MAGIC) - r8168_mac_ocp_modify(tp, 0xc0b6, 0, BIT(0)); - else - r8168_mac_ocp_modify(tp, 0xc0b6, BIT(0), 0); -+ } else { -+ r8169_mod_reg8_cond(tp, Config3, MagicPacket, -+ wolopts & WAKE_MAGIC); - } - -- for (i = 0; i < tmp; i++) { -- options = RTL_R8(tp, cfg[i].reg) & ~cfg[i].mask; -- if (wolopts & cfg[i].opt) -- options |= cfg[i].mask; -- RTL_W8(tp, cfg[i].reg, options); -- } -+ r8169_mod_reg8_cond(tp, Config3, LinkUp, wolopts & WAKE_PHY); -+ r8169_mod_reg8_cond(tp, Config5, UWF, wolopts & WAKE_UCAST); -+ r8169_mod_reg8_cond(tp, Config5, BWF, wolopts & WAKE_BCAST); -+ r8169_mod_reg8_cond(tp, Config5, MWF, wolopts & WAKE_MCAST); -+ r8169_mod_reg8_cond(tp, Config5, LanWake, wolopts); - - switch (tp->mac_version) { - case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06: -- options = RTL_R8(tp, Config1) & ~PMEnable; -- if (wolopts) -- options |= PMEnable; -- RTL_W8(tp, Config1, options); -+ r8169_mod_reg8_cond(tp, Config1, PMEnable, wolopts); - break; - case RTL_GIGA_MAC_VER_34: - case RTL_GIGA_MAC_VER_37: - case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_66: -- if (wolopts) -- rtl_mod_config2(tp, 0, PME_SIGNAL); -- else -- rtl_mod_config2(tp, PME_SIGNAL, 0); -+ r8169_mod_reg8_cond(tp, Config2, PME_SIGNAL, wolopts); - break; - default: - break; --- -2.51.0 - - -From d3852405b70dcc37cc63b0f66bf77a7fbf825e8f Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Wed, 6 Nov 2024 17:56:28 +0100 -Subject: [PATCH 112/517] r8169: improve rtl_set_d3_pll_down - -Make use of new helper r8169_mod_reg8_cond() and move from a switch() -to an if() clause. Benefit is that we don't have to touch this piece of -code each time support for a new chip version is added. - -Signed-off-by: Heiner Kallweit -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/e1ccdb85-a4ed-4800-89c2-89770ff06452@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/r8169_main.c | 18 +++++------------- - 1 file changed, 5 insertions(+), 13 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index bb5784654cec..e963e4f9fff7 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -1430,19 +1430,11 @@ static enum rtl_dash_type rtl_get_dash_type(struct rtl8169_private *tp) - - static void rtl_set_d3_pll_down(struct rtl8169_private *tp, bool enable) - { -- switch (tp->mac_version) { -- case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_26: -- case RTL_GIGA_MAC_VER_29 ... RTL_GIGA_MAC_VER_30: -- case RTL_GIGA_MAC_VER_32 ... RTL_GIGA_MAC_VER_37: -- case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_66: -- if (enable) -- RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) & ~D3_NO_PLL_DOWN); -- else -- RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) | D3_NO_PLL_DOWN); -- break; -- default: -- break; -- } -+ if (tp->mac_version >= RTL_GIGA_MAC_VER_25 && -+ tp->mac_version != RTL_GIGA_MAC_VER_28 && -+ tp->mac_version != RTL_GIGA_MAC_VER_31 && -+ tp->mac_version != RTL_GIGA_MAC_VER_38) -+ r8169_mod_reg8_cond(tp, PMCH, D3_NO_PLL_DOWN, !enable); - } - - static void rtl_reset_packet_filter(struct rtl8169_private *tp) --- -2.51.0 - - -From 45dd32ce075f308916c99e45bb6b5e140e299dbd Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Wed, 6 Nov 2024 17:57:08 +0100 -Subject: [PATCH 113/517] r8169: align WAKE_PHY handling with r8125/r8126 - vendor drivers - -Vendor drivers r8125/r8126 apply this additional magic setting when -enabling WAKE_PHY, so do the same here. - -Signed-off-by: Heiner Kallweit -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/51130715-45be-4db5-abb7-05d87e1f5df9@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/r8169_main.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index e963e4f9fff7..bd42f548fbda 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -1561,6 +1561,9 @@ static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts) - } - - r8169_mod_reg8_cond(tp, Config3, LinkUp, wolopts & WAKE_PHY); -+ if (rtl_is_8125(tp)) -+ r8168_mac_ocp_modify(tp, 0xe0c6, 0x3f, -+ wolopts & WAKE_PHY ? 0x13 : 0); - r8169_mod_reg8_cond(tp, Config5, UWF, wolopts & WAKE_UCAST); - r8169_mod_reg8_cond(tp, Config5, BWF, wolopts & WAKE_BCAST); - r8169_mod_reg8_cond(tp, Config5, MWF, wolopts & WAKE_MCAST); --- -2.51.0 - - -From 5d248ce8f3584802bfc97c437bff82778b2517a3 Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Sat, 9 Nov 2024 23:12:12 +0100 -Subject: [PATCH 114/517] r8169: use helper r8169_mod_reg8_cond to simplify - rtl_jumbo_config - -Use recently added helper r8169_mod_reg8_cond() to simplify jumbo -mode configuration. - -Signed-off-by: Heiner Kallweit -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/3df1d484-a02e-46e7-8f75-db5b428e422e@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/r8169_main.c | 77 ++++------------------- - 1 file changed, 11 insertions(+), 66 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index bd42f548fbda..aafe113d3bed 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -2542,86 +2542,31 @@ static void rtl8169_init_ring_indexes(struct rtl8169_private *tp) - tp->dirty_tx = tp->cur_tx = tp->cur_rx = 0; - } - --static void r8168c_hw_jumbo_enable(struct rtl8169_private *tp) --{ -- RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0); -- RTL_W8(tp, Config4, RTL_R8(tp, Config4) | Jumbo_En1); --} -- --static void r8168c_hw_jumbo_disable(struct rtl8169_private *tp) --{ -- RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0); -- RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~Jumbo_En1); --} -- --static void r8168dp_hw_jumbo_enable(struct rtl8169_private *tp) --{ -- RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0); --} -- --static void r8168dp_hw_jumbo_disable(struct rtl8169_private *tp) --{ -- RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0); --} -- --static void r8168e_hw_jumbo_enable(struct rtl8169_private *tp) --{ -- RTL_W8(tp, MaxTxPacketSize, 0x24); -- RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0); -- RTL_W8(tp, Config4, RTL_R8(tp, Config4) | 0x01); --} -- --static void r8168e_hw_jumbo_disable(struct rtl8169_private *tp) --{ -- RTL_W8(tp, MaxTxPacketSize, 0x3f); -- RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0); -- RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~0x01); --} -- --static void r8168b_1_hw_jumbo_enable(struct rtl8169_private *tp) --{ -- RTL_W8(tp, Config4, RTL_R8(tp, Config4) | (1 << 0)); --} -- --static void r8168b_1_hw_jumbo_disable(struct rtl8169_private *tp) --{ -- RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~(1 << 0)); --} -- - static void rtl_jumbo_config(struct rtl8169_private *tp) - { - bool jumbo = tp->dev->mtu > ETH_DATA_LEN; - int readrq = 4096; - -+ if (jumbo && tp->mac_version >= RTL_GIGA_MAC_VER_17 && -+ tp->mac_version <= RTL_GIGA_MAC_VER_26) -+ readrq = 512; -+ - rtl_unlock_config_regs(tp); - switch (tp->mac_version) { - case RTL_GIGA_MAC_VER_17: -- if (jumbo) { -- readrq = 512; -- r8168b_1_hw_jumbo_enable(tp); -- } else { -- r8168b_1_hw_jumbo_disable(tp); -- } -+ r8169_mod_reg8_cond(tp, Config4, BIT(0), jumbo); - break; - case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_26: -- if (jumbo) { -- readrq = 512; -- r8168c_hw_jumbo_enable(tp); -- } else { -- r8168c_hw_jumbo_disable(tp); -- } -+ r8169_mod_reg8_cond(tp, Config3, Jumbo_En0, jumbo); -+ r8169_mod_reg8_cond(tp, Config4, Jumbo_En1, jumbo); - break; - case RTL_GIGA_MAC_VER_28: -- if (jumbo) -- r8168dp_hw_jumbo_enable(tp); -- else -- r8168dp_hw_jumbo_disable(tp); -+ r8169_mod_reg8_cond(tp, Config3, Jumbo_En0, jumbo); - break; - case RTL_GIGA_MAC_VER_31 ... RTL_GIGA_MAC_VER_33: -- if (jumbo) -- r8168e_hw_jumbo_enable(tp); -- else -- r8168e_hw_jumbo_disable(tp); -+ RTL_W8(tp, MaxTxPacketSize, jumbo ? 0x24 : 0x3f); -+ r8169_mod_reg8_cond(tp, Config3, Jumbo_En0, jumbo); -+ r8169_mod_reg8_cond(tp, Config4, BIT(0), jumbo); - break; - default: - break; --- -2.51.0 - - -From 5c600144ed1b77cb7771b5d1e43098850d6d01fe Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Fri, 8 Nov 2024 08:08:24 +0100 -Subject: [PATCH 115/517] r8169: copy vendor driver 2.5G/5G EEE advertisement - constraints - -Vendor driver r8125 doesn't advertise 2.5G EEE on RTL8125A, and r8126 -doesn't advertise 5G EEE. Likely there are compatibility issues, -therefore do the same in r8169. -With this change we don't have to disable 2.5G EEE advertisement in -rtl8125a_config_eee_phy() any longer. -We use new phylib accessor phy_set_eee_broken() to mark the respective -EEE modes as broken. - -Signed-off-by: Heiner Kallweit -Link: https://patch.msgid.link/ce185e10-8a2f-4cf8-a49b-fd8fb3c3c8a1@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/r8169_main.c | 5 +++++ - drivers/net/ethernet/realtek/r8169_phy_config.c | 16 ++++------------ - 2 files changed, 9 insertions(+), 12 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index aafe113d3bed..1f519eecc1f7 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -5256,6 +5256,11 @@ static int r8169_mdio_register(struct rtl8169_private *tp) - phy_support_eee(tp->phydev); - phy_support_asym_pause(tp->phydev); - -+ /* mimic behavior of r8125/r8126 vendor drivers */ -+ if (tp->mac_version == RTL_GIGA_MAC_VER_61) -+ tp->phydev->eee_broken_modes |= MDIO_EEE_2_5GT; -+ tp->phydev->eee_broken_modes |= MDIO_EEE_5GT; -+ - /* PHY will be woken up in rtl_open() */ - phy_suspend(tp->phydev); - -diff --git a/drivers/net/ethernet/realtek/r8169_phy_config.c b/drivers/net/ethernet/realtek/r8169_phy_config.c -index 1d5b33f6c4b5..5307c6ff4e25 100644 ---- a/drivers/net/ethernet/realtek/r8169_phy_config.c -+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c -@@ -96,15 +96,7 @@ static void rtl8125_common_config_eee_phy(struct phy_device *phydev) - phy_modify_paged(phydev, 0xa4a, 0x11, 0x0200, 0x0000); - } - --static void rtl8125a_config_eee_phy(struct phy_device *phydev) --{ -- rtl8168g_config_eee_phy(phydev); -- /* disable EEE at 2.5Gbps */ -- phy_modify_paged(phydev, 0xa6d, 0x12, 0x0001, 0x0000); -- rtl8125_common_config_eee_phy(phydev); --} -- --static void rtl8125b_config_eee_phy(struct phy_device *phydev) -+static void rtl8125_config_eee_phy(struct phy_device *phydev) - { - rtl8168g_config_eee_phy(phydev); - rtl8125_common_config_eee_phy(phydev); -@@ -1066,7 +1058,7 @@ static void rtl8125a_2_hw_phy_config(struct rtl8169_private *tp, - rtl8168g_enable_gphy_10m(phydev); - - rtl8168g_disable_aldps(phydev); -- rtl8125a_config_eee_phy(phydev); -+ rtl8125_config_eee_phy(phydev); - } - - static void rtl8125b_hw_phy_config(struct rtl8169_private *tp, -@@ -1106,7 +1098,7 @@ static void rtl8125b_hw_phy_config(struct rtl8169_private *tp, - - rtl8125_legacy_force_mode(phydev); - rtl8168g_disable_aldps(phydev); -- rtl8125b_config_eee_phy(phydev); -+ rtl8125_config_eee_phy(phydev); - } - - static void rtl8125d_hw_phy_config(struct rtl8169_private *tp, -@@ -1116,7 +1108,7 @@ static void rtl8125d_hw_phy_config(struct rtl8169_private *tp, - rtl8168g_enable_gphy_10m(phydev); - rtl8125_legacy_force_mode(phydev); - rtl8168g_disable_aldps(phydev); -- rtl8125b_config_eee_phy(phydev); -+ rtl8125_config_eee_phy(phydev); - } - - static void rtl8126a_hw_phy_config(struct rtl8169_private *tp, --- -2.51.0 - - -From a924fb5a747c493e99bae0ce528f55ae30a93a8e Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Mon, 2 Dec 2024 21:14:35 +0100 -Subject: [PATCH 116/517] r8169: remove unused flag - RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE - -After 854d71c555dfc3 ("r8169: remove original workaround for RTL8125 -broken rx issue") this flag isn't used any longer. So remove it. - -Signed-off-by: Heiner Kallweit -Reviewed-by: Michal Swiatkowski -Link: https://patch.msgid.link/d9dd214b-3027-4f60-b0e8-6f34a0c76582@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/r8169_main.c | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index 1f519eecc1f7..4ec51251615b 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -622,7 +622,6 @@ struct rtl8169_tc_offsets { - - enum rtl_flag { - RTL_FLAG_TASK_RESET_PENDING, -- RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE, - RTL_FLAG_TASK_TX_TIMEOUT, - RTL_FLAG_MAX - }; -@@ -4749,8 +4748,6 @@ static void rtl_task(struct work_struct *work) - reset: - rtl_reset_work(tp); - netif_wake_queue(tp->dev); -- } else if (test_and_clear_bit(RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE, tp->wk.flags)) { -- rtl_reset_work(tp); - } - } - --- -2.51.0 - - -From 31e5c12785164a84028c96e7cc39f3cb6e81c27e Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Mon, 2 Dec 2024 21:20:02 +0100 -Subject: [PATCH 117/517] r8169: remove support for chip version 11 - -This is a follow-up to 982300c115d2 ("r8169: remove detection of chip -version 11 (early RTL8168b)"). Nobody complained yet, so remove -support for this chip version. - -Signed-off-by: Heiner Kallweit -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/b689ab6d-20b5-4b64-bd7e-531a0a972ba3@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/r8169.h | 2 +- - drivers/net/ethernet/realtek/r8169_main.c | 14 +------------- - drivers/net/ethernet/realtek/r8169_phy_config.c | 10 ---------- - 3 files changed, 2 insertions(+), 24 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/r8169.h b/drivers/net/ethernet/realtek/r8169.h -index be4c9622618d..8904aae41aca 100644 ---- a/drivers/net/ethernet/realtek/r8169.h -+++ b/drivers/net/ethernet/realtek/r8169.h -@@ -23,7 +23,7 @@ enum mac_version { - RTL_GIGA_MAC_VER_08, - RTL_GIGA_MAC_VER_09, - RTL_GIGA_MAC_VER_10, -- RTL_GIGA_MAC_VER_11, -+ /* support for RTL_GIGA_MAC_VER_11 has been removed */ - /* RTL_GIGA_MAC_VER_12 was handled the same as VER_17 */ - /* RTL_GIGA_MAC_VER_13 was merged with VER_10 */ - RTL_GIGA_MAC_VER_14, -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index 4ec51251615b..e435f17fa722 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -103,7 +103,6 @@ static const struct { - [RTL_GIGA_MAC_VER_08] = {"RTL8102e" }, - [RTL_GIGA_MAC_VER_09] = {"RTL8102e/RTL8103e" }, - [RTL_GIGA_MAC_VER_10] = {"RTL8101e/RTL8100e" }, -- [RTL_GIGA_MAC_VER_11] = {"RTL8168b/8111b" }, - [RTL_GIGA_MAC_VER_14] = {"RTL8401" }, - [RTL_GIGA_MAC_VER_17] = {"RTL8168b/8111b" }, - [RTL_GIGA_MAC_VER_18] = {"RTL8168cp/8111cp" }, -@@ -2334,7 +2333,7 @@ static enum mac_version rtl8169_get_mac_version(u16 xid, bool gmii) - - /* 8168B family. */ - { 0x7c8, 0x380, RTL_GIGA_MAC_VER_17 }, -- /* This one is very old and rare, let's see if anybody complains. -+ /* This one is very old and rare, support has been removed. - * { 0x7c8, 0x300, RTL_GIGA_MAC_VER_11 }, - */ - -@@ -3829,7 +3828,6 @@ static void rtl_hw_config(struct rtl8169_private *tp) - [RTL_GIGA_MAC_VER_08] = rtl_hw_start_8102e_3, - [RTL_GIGA_MAC_VER_09] = rtl_hw_start_8102e_2, - [RTL_GIGA_MAC_VER_10] = NULL, -- [RTL_GIGA_MAC_VER_11] = rtl_hw_start_8168b, - [RTL_GIGA_MAC_VER_14] = rtl_hw_start_8401, - [RTL_GIGA_MAC_VER_17] = rtl_hw_start_8168b, - [RTL_GIGA_MAC_VER_18] = rtl_hw_start_8168cp_1, -@@ -4705,12 +4703,6 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) - if (status & LinkChg) - phy_mac_interrupt(tp->phydev); - -- if (unlikely(status & RxFIFOOver && -- tp->mac_version == RTL_GIGA_MAC_VER_11)) { -- netif_stop_queue(tp->dev); -- rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); -- } -- - rtl_irq_disable(tp); - napi_schedule(&tp->napi); - out: -@@ -5127,9 +5119,6 @@ static void rtl_set_irq_mask(struct rtl8169_private *tp) - - if (tp->mac_version <= RTL_GIGA_MAC_VER_06) - tp->irq_mask |= SYSErr | RxFIFOOver; -- else if (tp->mac_version == RTL_GIGA_MAC_VER_11) -- /* special workaround needed */ -- tp->irq_mask |= RxFIFOOver; - } - - static int rtl_alloc_irq(struct rtl8169_private *tp) -@@ -5324,7 +5313,6 @@ static int rtl_jumbo_max(struct rtl8169_private *tp) - case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06: - return JUMBO_7K; - /* RTL8168b */ -- case RTL_GIGA_MAC_VER_11: - case RTL_GIGA_MAC_VER_17: - return JUMBO_4K; - /* RTL8168c */ -diff --git a/drivers/net/ethernet/realtek/r8169_phy_config.c b/drivers/net/ethernet/realtek/r8169_phy_config.c -index 5307c6ff4e25..b28b30390e84 100644 ---- a/drivers/net/ethernet/realtek/r8169_phy_config.c -+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c -@@ -276,15 +276,6 @@ static void rtl8169sce_hw_phy_config(struct rtl8169_private *tp, - rtl_writephy_batch(phydev, phy_reg_init); - } - --static void rtl8168bb_hw_phy_config(struct rtl8169_private *tp, -- struct phy_device *phydev) --{ -- phy_write(phydev, 0x1f, 0x0001); -- phy_set_bits(phydev, 0x16, BIT(0)); -- phy_write(phydev, 0x10, 0xf41b); -- phy_write(phydev, 0x1f, 0x0000); --} -- - static void rtl8168bef_hw_phy_config(struct rtl8169_private *tp, - struct phy_device *phydev) - { -@@ -1136,7 +1127,6 @@ void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev, - [RTL_GIGA_MAC_VER_08] = rtl8102e_hw_phy_config, - [RTL_GIGA_MAC_VER_09] = rtl8102e_hw_phy_config, - [RTL_GIGA_MAC_VER_10] = NULL, -- [RTL_GIGA_MAC_VER_11] = rtl8168bb_hw_phy_config, - [RTL_GIGA_MAC_VER_14] = rtl8401_hw_phy_config, - [RTL_GIGA_MAC_VER_17] = rtl8168bef_hw_phy_config, - [RTL_GIGA_MAC_VER_18] = rtl8168cp_1_hw_phy_config, --- -2.51.0 - - -From 29bfd059af1164901861876a59ff00abe5571d04 Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Fri, 13 Dec 2024 20:01:41 +0100 -Subject: [PATCH 118/517] r8169: adjust version numbering for RTL8126 - -Adjust version numbering for RTL8126, so that it doesn't overlap with -new RTL8125 versions. - -Signed-off-by: Heiner Kallweit -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/6a354364-20e9-48ad-a198-468264288757@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/r8169.h | 4 +- - drivers/net/ethernet/realtek/r8169_main.c | 62 +++++++++---------- - .../net/ethernet/realtek/r8169_phy_config.c | 4 +- - 3 files changed, 35 insertions(+), 35 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/r8169.h b/drivers/net/ethernet/realtek/r8169.h -index 8904aae41aca..00d74e76c6f2 100644 ---- a/drivers/net/ethernet/realtek/r8169.h -+++ b/drivers/net/ethernet/realtek/r8169.h -@@ -69,8 +69,8 @@ enum mac_version { - RTL_GIGA_MAC_VER_61, - RTL_GIGA_MAC_VER_63, - RTL_GIGA_MAC_VER_64, -- RTL_GIGA_MAC_VER_65, -- RTL_GIGA_MAC_VER_66, -+ RTL_GIGA_MAC_VER_70, -+ RTL_GIGA_MAC_VER_71, - RTL_GIGA_MAC_NONE - }; - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index e435f17fa722..f0d6261f92bb 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -139,8 +139,8 @@ static const struct { - /* reserve 62 for CFG_METHOD_4 in the vendor driver */ - [RTL_GIGA_MAC_VER_63] = {"RTL8125B", FIRMWARE_8125B_2}, - [RTL_GIGA_MAC_VER_64] = {"RTL8125D", FIRMWARE_8125D_1}, -- [RTL_GIGA_MAC_VER_65] = {"RTL8126A", FIRMWARE_8126A_2}, -- [RTL_GIGA_MAC_VER_66] = {"RTL8126A", FIRMWARE_8126A_3}, -+ [RTL_GIGA_MAC_VER_70] = {"RTL8126A", FIRMWARE_8126A_2}, -+ [RTL_GIGA_MAC_VER_71] = {"RTL8126A", FIRMWARE_8126A_3}, - }; - - static const struct pci_device_id rtl8169_pci_tbl[] = { -@@ -1227,7 +1227,7 @@ static void rtl_writephy(struct rtl8169_private *tp, int location, int val) - case RTL_GIGA_MAC_VER_31: - r8168dp_2_mdio_write(tp, location, val); - break; -- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_66: -+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_71: - r8168g_mdio_write(tp, location, val); - break; - default: -@@ -1242,7 +1242,7 @@ static int rtl_readphy(struct rtl8169_private *tp, int location) - case RTL_GIGA_MAC_VER_28: - case RTL_GIGA_MAC_VER_31: - return r8168dp_2_mdio_read(tp, location); -- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_66: -+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_71: - return r8168g_mdio_read(tp, location); - default: - return r8169_mdio_read(tp, location); -@@ -1573,7 +1573,7 @@ static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts) - break; - case RTL_GIGA_MAC_VER_34: - case RTL_GIGA_MAC_VER_37: -- case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_66: -+ case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_71: - r8169_mod_reg8_cond(tp, Config2, PME_SIGNAL, wolopts); - break; - default: -@@ -2046,7 +2046,7 @@ static void rtl_set_eee_txidle_timer(struct rtl8169_private *tp) - tp->tx_lpi_timer = timer_val; - r8168_mac_ocp_write(tp, 0xe048, timer_val); - break; -- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_66: -+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71: - tp->tx_lpi_timer = timer_val; - RTL_W16(tp, EEE_TXIDLE_TIMER_8125, timer_val); - break; -@@ -2254,8 +2254,8 @@ static enum mac_version rtl8169_get_mac_version(u16 xid, bool gmii) - enum mac_version ver; - } mac_info[] = { - /* 8126A family. */ -- { 0x7cf, 0x64a, RTL_GIGA_MAC_VER_66 }, -- { 0x7cf, 0x649, RTL_GIGA_MAC_VER_65 }, -+ { 0x7cf, 0x64a, RTL_GIGA_MAC_VER_71 }, -+ { 0x7cf, 0x649, RTL_GIGA_MAC_VER_70 }, - - /* 8125D family. */ - { 0x7cf, 0x688, RTL_GIGA_MAC_VER_64 }, -@@ -2525,7 +2525,7 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp) - case RTL_GIGA_MAC_VER_61: - RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST); - break; -- case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_66: -+ case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_71: - RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST | - RX_PAUSE_SLOT_ON); - break; -@@ -2657,7 +2657,7 @@ static void rtl_wait_txrx_fifo_empty(struct rtl8169_private *tp) - case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_61: - rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42); - break; -- case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_66: -+ case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_71: - RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq); - rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42); - rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond_2, 100, 42); -@@ -2926,7 +2926,7 @@ static void rtl_enable_exit_l1(struct rtl8169_private *tp) - case RTL_GIGA_MAC_VER_37 ... RTL_GIGA_MAC_VER_38: - rtl_eri_set_bits(tp, 0xd4, 0x0c00); - break; -- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_66: -+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_71: - r8168_mac_ocp_modify(tp, 0xc0ac, 0, 0x1f80); - break; - default: -@@ -2940,7 +2940,7 @@ static void rtl_disable_exit_l1(struct rtl8169_private *tp) - case RTL_GIGA_MAC_VER_34 ... RTL_GIGA_MAC_VER_38: - rtl_eri_clear_bits(tp, 0xd4, 0x1f00); - break; -- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_66: -+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_71: - r8168_mac_ocp_modify(tp, 0xc0ac, 0x1f80, 0); - break; - default: -@@ -2966,8 +2966,8 @@ static void rtl_hw_aspm_clkreq_enable(struct rtl8169_private *tp, bool enable) - - rtl_mod_config5(tp, 0, ASPM_en); - switch (tp->mac_version) { -- case RTL_GIGA_MAC_VER_65: -- case RTL_GIGA_MAC_VER_66: -+ case RTL_GIGA_MAC_VER_70: -+ case RTL_GIGA_MAC_VER_71: - val8 = RTL_R8(tp, INT_CFG0_8125) | INT_CFG0_CLKREQEN; - RTL_W8(tp, INT_CFG0_8125, val8); - break; -@@ -2978,7 +2978,7 @@ static void rtl_hw_aspm_clkreq_enable(struct rtl8169_private *tp, bool enable) - - switch (tp->mac_version) { - case RTL_GIGA_MAC_VER_46 ... RTL_GIGA_MAC_VER_48: -- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_66: -+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71: - /* reset ephy tx/rx disable timer */ - r8168_mac_ocp_modify(tp, 0xe094, 0xff00, 0); - /* chip can trigger L1.2 */ -@@ -2990,7 +2990,7 @@ static void rtl_hw_aspm_clkreq_enable(struct rtl8169_private *tp, bool enable) - } else { - switch (tp->mac_version) { - case RTL_GIGA_MAC_VER_46 ... RTL_GIGA_MAC_VER_48: -- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_66: -+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71: - r8168_mac_ocp_modify(tp, 0xe092, 0x00ff, 0); - break; - default: -@@ -2998,8 +2998,8 @@ static void rtl_hw_aspm_clkreq_enable(struct rtl8169_private *tp, bool enable) - } - - switch (tp->mac_version) { -- case RTL_GIGA_MAC_VER_65: -- case RTL_GIGA_MAC_VER_66: -+ case RTL_GIGA_MAC_VER_70: -+ case RTL_GIGA_MAC_VER_71: - val8 = RTL_R8(tp, INT_CFG0_8125) & ~INT_CFG0_CLKREQEN; - RTL_W8(tp, INT_CFG0_8125, val8); - break; -@@ -3719,12 +3719,12 @@ static void rtl_hw_start_8125_common(struct rtl8169_private *tp) - /* disable new tx descriptor format */ - r8168_mac_ocp_modify(tp, 0xeb58, 0x0001, 0x0000); - -- if (tp->mac_version == RTL_GIGA_MAC_VER_65 || -- tp->mac_version == RTL_GIGA_MAC_VER_66) -+ if (tp->mac_version == RTL_GIGA_MAC_VER_70 || -+ tp->mac_version == RTL_GIGA_MAC_VER_71) - RTL_W8(tp, 0xD8, RTL_R8(tp, 0xD8) & ~0x02); - -- if (tp->mac_version == RTL_GIGA_MAC_VER_65 || -- tp->mac_version == RTL_GIGA_MAC_VER_66) -+ if (tp->mac_version == RTL_GIGA_MAC_VER_70 || -+ tp->mac_version == RTL_GIGA_MAC_VER_71) - r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0400); - else if (tp->mac_version == RTL_GIGA_MAC_VER_63) - r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0200); -@@ -3742,8 +3742,8 @@ static void rtl_hw_start_8125_common(struct rtl8169_private *tp) - r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0030); - r8168_mac_ocp_modify(tp, 0xe040, 0x1000, 0x0000); - r8168_mac_ocp_modify(tp, 0xea1c, 0x0003, 0x0001); -- if (tp->mac_version == RTL_GIGA_MAC_VER_65 || -- tp->mac_version == RTL_GIGA_MAC_VER_66) -+ if (tp->mac_version == RTL_GIGA_MAC_VER_70 || -+ tp->mac_version == RTL_GIGA_MAC_VER_71) - r8168_mac_ocp_modify(tp, 0xea1c, 0x0300, 0x0000); - else - r8168_mac_ocp_modify(tp, 0xea1c, 0x0004, 0x0000); -@@ -3863,8 +3863,8 @@ static void rtl_hw_config(struct rtl8169_private *tp) - [RTL_GIGA_MAC_VER_61] = rtl_hw_start_8125a_2, - [RTL_GIGA_MAC_VER_63] = rtl_hw_start_8125b, - [RTL_GIGA_MAC_VER_64] = rtl_hw_start_8125d, -- [RTL_GIGA_MAC_VER_65] = rtl_hw_start_8126a, -- [RTL_GIGA_MAC_VER_66] = rtl_hw_start_8126a, -+ [RTL_GIGA_MAC_VER_70] = rtl_hw_start_8126a, -+ [RTL_GIGA_MAC_VER_71] = rtl_hw_start_8126a, - }; - - if (hw_configs[tp->mac_version]) -@@ -3885,8 +3885,8 @@ static void rtl_hw_start_8125(struct rtl8169_private *tp) - RTL_W32(tp, i, 0); - break; - case RTL_GIGA_MAC_VER_63: -- case RTL_GIGA_MAC_VER_65: -- case RTL_GIGA_MAC_VER_66: -+ case RTL_GIGA_MAC_VER_70: -+ case RTL_GIGA_MAC_VER_71: - for (i = 0xa00; i < 0xa80; i += 4) - RTL_W32(tp, i, 0); - RTL_W16(tp, INT_CFG1_8125, 0x0000); -@@ -4118,7 +4118,7 @@ static void rtl8169_cleanup(struct rtl8169_private *tp) - RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq); - rtl_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666); - break; -- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_66: -+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_71: - rtl_enable_rxdvgate(tp); - fsleep(2000); - break; -@@ -4275,7 +4275,7 @@ static unsigned int rtl_quirk_packet_padto(struct rtl8169_private *tp, - - switch (tp->mac_version) { - case RTL_GIGA_MAC_VER_34: -- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_66: -+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71: - padto = max_t(unsigned int, padto, ETH_ZLEN); - break; - default: -@@ -5294,7 +5294,7 @@ static void rtl_hw_initialize(struct rtl8169_private *tp) - case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_48: - rtl_hw_init_8168g(tp); - break; -- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_66: -+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71: - rtl_hw_init_8125(tp); - break; - default: -diff --git a/drivers/net/ethernet/realtek/r8169_phy_config.c b/drivers/net/ethernet/realtek/r8169_phy_config.c -index b28b30390e84..bc498ea78034 100644 ---- a/drivers/net/ethernet/realtek/r8169_phy_config.c -+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c -@@ -1162,8 +1162,8 @@ void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev, - [RTL_GIGA_MAC_VER_61] = rtl8125a_2_hw_phy_config, - [RTL_GIGA_MAC_VER_63] = rtl8125b_hw_phy_config, - [RTL_GIGA_MAC_VER_64] = rtl8125d_hw_phy_config, -- [RTL_GIGA_MAC_VER_65] = rtl8126a_hw_phy_config, -- [RTL_GIGA_MAC_VER_66] = rtl8126a_hw_phy_config, -+ [RTL_GIGA_MAC_VER_70] = rtl8126a_hw_phy_config, -+ [RTL_GIGA_MAC_VER_71] = rtl8126a_hw_phy_config, - }; - - if (phy_configs[ver]) --- -2.51.0 - - -From df24521b323b138471e6ea933e24af5f77c30f33 Mon Sep 17 00:00:00 2001 -From: ChunHao Lin -Date: Fri, 13 Dec 2024 20:02:58 +0100 -Subject: [PATCH 119/517] r8169: add support for RTL8125D rev.b - -Add support for RTL8125D rev.b. Its XID is 0x689. It is basically -based on the one with XID 0x688, but with different firmware file. - -Signed-off-by: ChunHao Lin -[hkallweit1@gmail.com: rebased after adjusted version numbering] -Signed-off-by: Heiner Kallweit -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/75e5e9ec-d01f-43ac-b0f4-e7456baf18d1@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/r8169.h | 1 + - drivers/net/ethernet/realtek/r8169_main.c | 6 ++++++ - drivers/net/ethernet/realtek/r8169_phy_config.c | 1 + - 3 files changed, 8 insertions(+) - -diff --git a/drivers/net/ethernet/realtek/r8169.h b/drivers/net/ethernet/realtek/r8169.h -index 00d74e76c6f2..e0817f2a311a 100644 ---- a/drivers/net/ethernet/realtek/r8169.h -+++ b/drivers/net/ethernet/realtek/r8169.h -@@ -69,6 +69,7 @@ enum mac_version { - RTL_GIGA_MAC_VER_61, - RTL_GIGA_MAC_VER_63, - RTL_GIGA_MAC_VER_64, -+ RTL_GIGA_MAC_VER_65, - RTL_GIGA_MAC_VER_70, - RTL_GIGA_MAC_VER_71, - RTL_GIGA_MAC_NONE -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index f0d6261f92bb..16c1e74554b2 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -56,6 +56,7 @@ - #define FIRMWARE_8125A_3 "rtl_nic/rtl8125a-3.fw" - #define FIRMWARE_8125B_2 "rtl_nic/rtl8125b-2.fw" - #define FIRMWARE_8125D_1 "rtl_nic/rtl8125d-1.fw" -+#define FIRMWARE_8125D_2 "rtl_nic/rtl8125d-2.fw" - #define FIRMWARE_8126A_2 "rtl_nic/rtl8126a-2.fw" - #define FIRMWARE_8126A_3 "rtl_nic/rtl8126a-3.fw" - -@@ -139,6 +140,7 @@ static const struct { - /* reserve 62 for CFG_METHOD_4 in the vendor driver */ - [RTL_GIGA_MAC_VER_63] = {"RTL8125B", FIRMWARE_8125B_2}, - [RTL_GIGA_MAC_VER_64] = {"RTL8125D", FIRMWARE_8125D_1}, -+ [RTL_GIGA_MAC_VER_65] = {"RTL8125D", FIRMWARE_8125D_2}, - [RTL_GIGA_MAC_VER_70] = {"RTL8126A", FIRMWARE_8126A_2}, - [RTL_GIGA_MAC_VER_71] = {"RTL8126A", FIRMWARE_8126A_3}, - }; -@@ -705,6 +707,7 @@ MODULE_FIRMWARE(FIRMWARE_8107E_2); - MODULE_FIRMWARE(FIRMWARE_8125A_3); - MODULE_FIRMWARE(FIRMWARE_8125B_2); - MODULE_FIRMWARE(FIRMWARE_8125D_1); -+MODULE_FIRMWARE(FIRMWARE_8125D_2); - MODULE_FIRMWARE(FIRMWARE_8126A_2); - MODULE_FIRMWARE(FIRMWARE_8126A_3); - -@@ -2258,6 +2261,7 @@ static enum mac_version rtl8169_get_mac_version(u16 xid, bool gmii) - { 0x7cf, 0x649, RTL_GIGA_MAC_VER_70 }, - - /* 8125D family. */ -+ { 0x7cf, 0x689, RTL_GIGA_MAC_VER_65 }, - { 0x7cf, 0x688, RTL_GIGA_MAC_VER_64 }, - - /* 8125B family. */ -@@ -3863,6 +3867,7 @@ static void rtl_hw_config(struct rtl8169_private *tp) - [RTL_GIGA_MAC_VER_61] = rtl_hw_start_8125a_2, - [RTL_GIGA_MAC_VER_63] = rtl_hw_start_8125b, - [RTL_GIGA_MAC_VER_64] = rtl_hw_start_8125d, -+ [RTL_GIGA_MAC_VER_65] = rtl_hw_start_8125d, - [RTL_GIGA_MAC_VER_70] = rtl_hw_start_8126a, - [RTL_GIGA_MAC_VER_71] = rtl_hw_start_8126a, - }; -@@ -3881,6 +3886,7 @@ static void rtl_hw_start_8125(struct rtl8169_private *tp) - switch (tp->mac_version) { - case RTL_GIGA_MAC_VER_61: - case RTL_GIGA_MAC_VER_64: -+ case RTL_GIGA_MAC_VER_65: - for (i = 0xa00; i < 0xb00; i += 4) - RTL_W32(tp, i, 0); - break; -diff --git a/drivers/net/ethernet/realtek/r8169_phy_config.c b/drivers/net/ethernet/realtek/r8169_phy_config.c -index bc498ea78034..968c8a2185a4 100644 ---- a/drivers/net/ethernet/realtek/r8169_phy_config.c -+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c -@@ -1162,6 +1162,7 @@ void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev, - [RTL_GIGA_MAC_VER_61] = rtl8125a_2_hw_phy_config, - [RTL_GIGA_MAC_VER_63] = rtl8125b_hw_phy_config, - [RTL_GIGA_MAC_VER_64] = rtl8125d_hw_phy_config, -+ [RTL_GIGA_MAC_VER_65] = rtl8125d_hw_phy_config, - [RTL_GIGA_MAC_VER_70] = rtl8126a_hw_phy_config, - [RTL_GIGA_MAC_VER_71] = rtl8126a_hw_phy_config, - }; --- -2.51.0 - - -From acdb177b82422fdb3c015b9cc048720f11cc944e Mon Sep 17 00:00:00 2001 -From: ChunHao Lin -Date: Tue, 7 Jan 2025 14:43:55 +0800 -Subject: [PATCH 120/517] r8169: add support for RTL8125BP rev.b - -Add support for RTL8125BP rev.b. Its XID is 0x689. This chip supports -DASH and its dash type is "RTL_DASH_25_BP". - -Signed-off-by: ChunHao Lin -Reviewed-by: Heiner Kallweit -Link: https://patch.msgid.link/20250107064355.104711-1-hau@realtek.com -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/realtek/r8169.h | 1 + - drivers/net/ethernet/realtek/r8169_main.c | 30 +++++++++++++++++++ - .../net/ethernet/realtek/r8169_phy_config.c | 23 ++++++++++++++ - 3 files changed, 54 insertions(+) - -diff --git a/drivers/net/ethernet/realtek/r8169.h b/drivers/net/ethernet/realtek/r8169.h -index e0817f2a311a..7a194a8ab989 100644 ---- a/drivers/net/ethernet/realtek/r8169.h -+++ b/drivers/net/ethernet/realtek/r8169.h -@@ -70,6 +70,7 @@ enum mac_version { - RTL_GIGA_MAC_VER_63, - RTL_GIGA_MAC_VER_64, - RTL_GIGA_MAC_VER_65, -+ RTL_GIGA_MAC_VER_66, - RTL_GIGA_MAC_VER_70, - RTL_GIGA_MAC_VER_71, - RTL_GIGA_MAC_NONE -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index 16c1e74554b2..b99ddcbec526 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -57,6 +57,7 @@ - #define FIRMWARE_8125B_2 "rtl_nic/rtl8125b-2.fw" - #define FIRMWARE_8125D_1 "rtl_nic/rtl8125d-1.fw" - #define FIRMWARE_8125D_2 "rtl_nic/rtl8125d-2.fw" -+#define FIRMWARE_8125BP_2 "rtl_nic/rtl8125bp-2.fw" - #define FIRMWARE_8126A_2 "rtl_nic/rtl8126a-2.fw" - #define FIRMWARE_8126A_3 "rtl_nic/rtl8126a-3.fw" - -@@ -141,6 +142,7 @@ static const struct { - [RTL_GIGA_MAC_VER_63] = {"RTL8125B", FIRMWARE_8125B_2}, - [RTL_GIGA_MAC_VER_64] = {"RTL8125D", FIRMWARE_8125D_1}, - [RTL_GIGA_MAC_VER_65] = {"RTL8125D", FIRMWARE_8125D_2}, -+ [RTL_GIGA_MAC_VER_66] = {"RTL8125BP", FIRMWARE_8125BP_2}, - [RTL_GIGA_MAC_VER_70] = {"RTL8126A", FIRMWARE_8126A_2}, - [RTL_GIGA_MAC_VER_71] = {"RTL8126A", FIRMWARE_8126A_3}, - }; -@@ -631,6 +633,7 @@ enum rtl_dash_type { - RTL_DASH_NONE, - RTL_DASH_DP, - RTL_DASH_EP, -+ RTL_DASH_25_BP, - }; - - struct rtl8169_private { -@@ -708,6 +711,7 @@ MODULE_FIRMWARE(FIRMWARE_8125A_3); - MODULE_FIRMWARE(FIRMWARE_8125B_2); - MODULE_FIRMWARE(FIRMWARE_8125D_1); - MODULE_FIRMWARE(FIRMWARE_8125D_2); -+MODULE_FIRMWARE(FIRMWARE_8125BP_2); - MODULE_FIRMWARE(FIRMWARE_8126A_2); - MODULE_FIRMWARE(FIRMWARE_8126A_3); - -@@ -1360,10 +1364,19 @@ static void rtl8168ep_driver_start(struct rtl8169_private *tp) - rtl_loop_wait_high(tp, &rtl_ep_ocp_read_cond, 10000, 30); - } - -+static void rtl8125bp_driver_start(struct rtl8169_private *tp) -+{ -+ r8168ep_ocp_write(tp, 0x01, 0x14, OOB_CMD_DRIVER_START); -+ r8168ep_ocp_write(tp, 0x01, 0x18, 0x00); -+ r8168ep_ocp_write(tp, 0x01, 0x10, 0x01); -+} -+ - static void rtl8168_driver_start(struct rtl8169_private *tp) - { - if (tp->dash_type == RTL_DASH_DP) - rtl8168dp_driver_start(tp); -+ else if (tp->dash_type == RTL_DASH_25_BP) -+ rtl8125bp_driver_start(tp); - else - rtl8168ep_driver_start(tp); - } -@@ -1384,10 +1397,19 @@ static void rtl8168ep_driver_stop(struct rtl8169_private *tp) - rtl_loop_wait_low(tp, &rtl_ep_ocp_read_cond, 10000, 10); - } - -+static void rtl8125bp_driver_stop(struct rtl8169_private *tp) -+{ -+ r8168ep_ocp_write(tp, 0x01, 0x14, OOB_CMD_DRIVER_STOP); -+ r8168ep_ocp_write(tp, 0x01, 0x18, 0x00); -+ r8168ep_ocp_write(tp, 0x01, 0x10, 0x01); -+} -+ - static void rtl8168_driver_stop(struct rtl8169_private *tp) - { - if (tp->dash_type == RTL_DASH_DP) - rtl8168dp_driver_stop(tp); -+ else if (tp->dash_type == RTL_DASH_25_BP) -+ rtl8125bp_driver_stop(tp); - else - rtl8168ep_driver_stop(tp); - } -@@ -1410,6 +1432,7 @@ static bool rtl_dash_is_enabled(struct rtl8169_private *tp) - case RTL_DASH_DP: - return r8168dp_check_dash(tp); - case RTL_DASH_EP: -+ case RTL_DASH_25_BP: - return r8168ep_check_dash(tp); - default: - return false; -@@ -1424,6 +1447,8 @@ static enum rtl_dash_type rtl_get_dash_type(struct rtl8169_private *tp) - return RTL_DASH_DP; - case RTL_GIGA_MAC_VER_51 ... RTL_GIGA_MAC_VER_53: - return RTL_DASH_EP; -+ case RTL_GIGA_MAC_VER_66: -+ return RTL_DASH_25_BP; - default: - return RTL_DASH_NONE; - } -@@ -2260,6 +2285,9 @@ static enum mac_version rtl8169_get_mac_version(u16 xid, bool gmii) - { 0x7cf, 0x64a, RTL_GIGA_MAC_VER_71 }, - { 0x7cf, 0x649, RTL_GIGA_MAC_VER_70 }, - -+ /* 8125BP family. */ -+ { 0x7cf, 0x681, RTL_GIGA_MAC_VER_66 }, -+ - /* 8125D family. */ - { 0x7cf, 0x689, RTL_GIGA_MAC_VER_65 }, - { 0x7cf, 0x688, RTL_GIGA_MAC_VER_64 }, -@@ -3868,6 +3896,7 @@ static void rtl_hw_config(struct rtl8169_private *tp) - [RTL_GIGA_MAC_VER_63] = rtl_hw_start_8125b, - [RTL_GIGA_MAC_VER_64] = rtl_hw_start_8125d, - [RTL_GIGA_MAC_VER_65] = rtl_hw_start_8125d, -+ [RTL_GIGA_MAC_VER_66] = rtl_hw_start_8125d, - [RTL_GIGA_MAC_VER_70] = rtl_hw_start_8126a, - [RTL_GIGA_MAC_VER_71] = rtl_hw_start_8126a, - }; -@@ -3887,6 +3916,7 @@ static void rtl_hw_start_8125(struct rtl8169_private *tp) - case RTL_GIGA_MAC_VER_61: - case RTL_GIGA_MAC_VER_64: - case RTL_GIGA_MAC_VER_65: -+ case RTL_GIGA_MAC_VER_66: - for (i = 0xa00; i < 0xb00; i += 4) - RTL_W32(tp, i, 0); - break; -diff --git a/drivers/net/ethernet/realtek/r8169_phy_config.c b/drivers/net/ethernet/realtek/r8169_phy_config.c -index 968c8a2185a4..cf95e579c65d 100644 ---- a/drivers/net/ethernet/realtek/r8169_phy_config.c -+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c -@@ -1102,6 +1102,28 @@ static void rtl8125d_hw_phy_config(struct rtl8169_private *tp, - rtl8125_config_eee_phy(phydev); - } - -+static void rtl8125bp_hw_phy_config(struct rtl8169_private *tp, -+ struct phy_device *phydev) -+{ -+ r8169_apply_firmware(tp); -+ rtl8168g_enable_gphy_10m(phydev); -+ -+ r8168g_phy_param(phydev, 0x8010, 0x0800, 0x0000); -+ -+ phy_write(phydev, 0x1f, 0x0b87); -+ phy_write(phydev, 0x16, 0x8088); -+ phy_modify(phydev, 0x17, 0xff00, 0x9000); -+ phy_write(phydev, 0x16, 0x808f); -+ phy_modify(phydev, 0x17, 0xff00, 0x9000); -+ phy_write(phydev, 0x1f, 0x0000); -+ -+ r8168g_phy_param(phydev, 0x8174, 0x2000, 0x1800); -+ -+ rtl8125_legacy_force_mode(phydev); -+ rtl8168g_disable_aldps(phydev); -+ rtl8125_config_eee_phy(phydev); -+} -+ - static void rtl8126a_hw_phy_config(struct rtl8169_private *tp, - struct phy_device *phydev) - { -@@ -1163,6 +1185,7 @@ void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev, - [RTL_GIGA_MAC_VER_63] = rtl8125b_hw_phy_config, - [RTL_GIGA_MAC_VER_64] = rtl8125d_hw_phy_config, - [RTL_GIGA_MAC_VER_65] = rtl8125d_hw_phy_config, -+ [RTL_GIGA_MAC_VER_66] = rtl8125bp_hw_phy_config, - [RTL_GIGA_MAC_VER_70] = rtl8126a_hw_phy_config, - [RTL_GIGA_MAC_VER_71] = rtl8126a_hw_phy_config, - }; --- -2.51.0 - - -From 3ff41a19c5246bfa3fbe37fe5d4b091393dd949a Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Mon, 3 Feb 2025 21:35:24 +0100 -Subject: [PATCH 121/517] r8169: make Kconfig option for LED support - user-visible - -Make config option R8169_LEDS user-visible, so that users can remove -support if not needed. - -Signed-off-by: Heiner Kallweit -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/d29f0cdb-32bf-435f-b59d-dc96bca1e3ab@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/Kconfig | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/ethernet/realtek/Kconfig b/drivers/net/ethernet/realtek/Kconfig -index 8a8ea51c639e..fe136f61586f 100644 ---- a/drivers/net/ethernet/realtek/Kconfig -+++ b/drivers/net/ethernet/realtek/Kconfig -@@ -114,7 +114,8 @@ config R8169 - will be called r8169. This is recommended. - - config R8169_LEDS -- def_bool R8169 && LEDS_TRIGGER_NETDEV -+ bool "Support for controlling the NIC LEDs" -+ depends on R8169 && LEDS_TRIGGER_NETDEV - depends on !(R8169=y && LEDS_CLASS=m) - help - Optional support for controlling the NIC LED's with the netdev --- -2.51.0 - - -From f0f1c081b8621b6572e2e1fb59c598b8ebca85d5 Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Wed, 12 Feb 2025 08:03:56 +0100 -Subject: [PATCH 122/517] r8169: add support for Intel Killer E5000 - -This adds support for the Intel Killer E5000 which seems to be a -rebranded RTL8126. Copied from r8126 vendor driver. - -Signed-off-by: Heiner Kallweit -Link: https://patch.msgid.link/9db73e9b-e2e8-45de-97a5-041c5f71d774@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/r8169_main.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index b99ddcbec526..c6acf6709524 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -169,6 +169,7 @@ static const struct pci_device_id rtl8169_pci_tbl[] = { - { PCI_VDEVICE(REALTEK, 0x8125) }, - { PCI_VDEVICE(REALTEK, 0x8126) }, - { PCI_VDEVICE(REALTEK, 0x3000) }, -+ { PCI_VDEVICE(REALTEK, 0x5000) }, - {} - }; - --- -2.51.0 - - -From 6c0325b41afeb91bf75bf5e75b0062834b033190 Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Thu, 13 Feb 2025 20:15:42 +0100 -Subject: [PATCH 123/517] r8169: add PHY c45 ops for MDIO_MMD_VENDOR2 registers - -The integrated PHYs on chip versions from RTL8168g allow to address -MDIO_MMD_VEND2 registers. All c22 standard registers are mapped to -MDIO_MMD_VEND2 registers. So far the paging mechanism is used to -address PHY registers. Add support for c45 ops to address MDIO_MMD_VEND2 -registers directly, w/o the paging. - -Signed-off-by: Heiner Kallweit -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/d6f97eaa-0f13-468f-89cb-75a41087bc4a@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/r8169_main.c | 32 +++++++++++++++++++++++ - 1 file changed, 32 insertions(+) - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index c6acf6709524..d974461db6b0 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -5228,6 +5228,33 @@ static int r8169_mdio_write_reg(struct mii_bus *mii_bus, int phyaddr, - return 0; - } - -+static int r8169_mdio_read_reg_c45(struct mii_bus *mii_bus, int addr, -+ int devnum, int regnum) -+{ -+ struct rtl8169_private *tp = mii_bus->priv; -+ -+ if (addr > 0) -+ return -ENODEV; -+ -+ if (devnum == MDIO_MMD_VEND2 && regnum > MDIO_STAT2) -+ return r8168_phy_ocp_read(tp, regnum); -+ -+ return 0; -+} -+ -+static int r8169_mdio_write_reg_c45(struct mii_bus *mii_bus, int addr, -+ int devnum, int regnum, u16 val) -+{ -+ struct rtl8169_private *tp = mii_bus->priv; -+ -+ if (addr > 0 || devnum != MDIO_MMD_VEND2 || regnum <= MDIO_STAT2) -+ return -ENODEV; -+ -+ r8168_phy_ocp_write(tp, regnum, val); -+ -+ return 0; -+} -+ - static int r8169_mdio_register(struct rtl8169_private *tp) - { - struct pci_dev *pdev = tp->pci_dev; -@@ -5258,6 +5285,11 @@ static int r8169_mdio_register(struct rtl8169_private *tp) - new_bus->read = r8169_mdio_read_reg; - new_bus->write = r8169_mdio_write_reg; - -+ if (tp->mac_version >= RTL_GIGA_MAC_VER_40) { -+ new_bus->read_c45 = r8169_mdio_read_reg_c45; -+ new_bus->write_c45 = r8169_mdio_write_reg_c45; -+ } -+ - ret = devm_mdiobus_register(&pdev->dev, new_bus); - if (ret) - return ret; --- -2.51.0 - - -From 8589e361c146c0a256bfa01874126364a1a6c540 Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Fri, 7 Mar 2025 08:29:47 +0100 -Subject: [PATCH 124/517] r8169: increase max jumbo packet size on - RTL8125/RTL8126 - -Realtek confirmed that all RTL8125/RTL8126 chip versions support up to -16K jumbo packets. Reflect this in the driver. - -Tested by Rui on RTL8125B with 12K jumbo packets. - -Suggested-by: Rui Salvaterra -Tested-by: Rui Salvaterra -Signed-off-by: Heiner Kallweit -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/396762ad-cc65-4e60-b01e-8847db89e98b@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/r8169_main.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index d974461db6b0..90585f44ed77 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -89,6 +89,7 @@ - #define JUMBO_6K (6 * SZ_1K - VLAN_ETH_HLEN - ETH_FCS_LEN) - #define JUMBO_7K (7 * SZ_1K - VLAN_ETH_HLEN - ETH_FCS_LEN) - #define JUMBO_9K (9 * SZ_1K - VLAN_ETH_HLEN - ETH_FCS_LEN) -+#define JUMBO_16K (SZ_16K - VLAN_ETH_HLEN - ETH_FCS_LEN) - - static const struct { - const char *name; -@@ -5387,6 +5388,9 @@ static int rtl_jumbo_max(struct rtl8169_private *tp) - /* RTL8168c */ - case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_24: - return JUMBO_6K; -+ /* RTL8125/8126 */ -+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71: -+ return JUMBO_16K; - default: - return JUMBO_9K; - } --- -2.51.0 - - -From 685a636e3096ae8ba35b8f928ba1bc4ec10462ba Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Wed, 12 Mar 2025 20:21:42 +0100 -Subject: [PATCH 125/517] r8169: switch away from deprecated pcim_iomap_table - -Avoid using deprecated pcim_iomap_table by switching to -pcim_iomap_region. - -Signed-off-by: Heiner Kallweit -Reviewed-by: Jacob Keller -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/a36b4cf3-c792-40fa-8164-5dc9d5f14dd0@gmail.com -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/realtek/r8169_main.c | 9 ++++----- - 1 file changed, 4 insertions(+), 5 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index 90585f44ed77..37e1cbf87e2d 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -5474,11 +5474,10 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) - if (region < 0) - return dev_err_probe(&pdev->dev, -ENODEV, "no MMIO resource found\n"); - -- rc = pcim_iomap_regions(pdev, BIT(region), KBUILD_MODNAME); -- if (rc < 0) -- return dev_err_probe(&pdev->dev, rc, "cannot remap MMIO, aborting\n"); -- -- tp->mmio_addr = pcim_iomap_table(pdev)[region]; -+ tp->mmio_addr = pcim_iomap_region(pdev, region, KBUILD_MODNAME); -+ if (IS_ERR(tp->mmio_addr)) -+ return dev_err_probe(&pdev->dev, PTR_ERR(tp->mmio_addr), -+ "cannot remap MMIO, aborting\n"); - - txconfig = RTL_R32(tp, TxConfig); - if (txconfig == ~0U) --- -2.51.0 - - -From ae7d0b24a7b500d0d2b5f87dc2311464714542d9 Mon Sep 17 00:00:00 2001 -From: ChunHao Lin -Date: Tue, 18 Mar 2025 16:37:20 +0800 -Subject: [PATCH 126/517] r8169: enable RTL8168H/RTL8168EP/RTL8168FP ASPM - support - -This patch will enable RTL8168H/RTL8168EP/RTL8168FP ASPM support on -the platforms that have tested with ASPM enabled. - -Signed-off-by: ChunHao Lin -Reviewed-by: Heiner Kallweit -Link: https://patch.msgid.link/20250318083721.4127-2-hau@realtek.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/r8169_main.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index 37e1cbf87e2d..f5150c9a0f66 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -5425,7 +5425,7 @@ static void rtl_init_mac_address(struct rtl8169_private *tp) - /* register is set if system vendor successfully tested ASPM 1.2 */ - static bool rtl_aspm_is_safe(struct rtl8169_private *tp) - { -- if (tp->mac_version >= RTL_GIGA_MAC_VER_61 && -+ if (tp->mac_version >= RTL_GIGA_MAC_VER_46 && - r8168_mac_ocp_read(tp, 0xc0b2) & 0xf) - return true; - --- -2.51.0 - - -From c20f71142b7d50326a236e242a375831f453193a Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Wed, 9 Apr 2025 21:05:37 +0200 -Subject: [PATCH 127/517] r8169: add helper rtl_csi_mod for accessing extended - config space - -Add a helper for the Realtek-specific mechanism for accessing extended -config space if native access isn't possible. -This avoids code duplication. - -Signed-off-by: Heiner Kallweit -Link: https://patch.msgid.link/b368fd91-57d7-4cb5-9342-98b4d8fe9aea@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/r8169_main.c | 26 ++++++++++++++--------- - 1 file changed, 16 insertions(+), 10 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index f5150c9a0f66..efdfa95ff693 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -2852,10 +2852,23 @@ static u32 rtl_csi_read(struct rtl8169_private *tp, int addr) - RTL_R32(tp, CSIDR) : ~0; - } - -+static void rtl_csi_mod(struct rtl8169_private *tp, int addr, -+ u32 mask, u32 set) -+{ -+ u32 val; -+ -+ WARN(addr % 4, "Invalid CSI address %#x\n", addr); -+ -+ netdev_notice_once(tp->dev, -+ "No native access to PCI extended config space, falling back to CSI\n"); -+ -+ val = rtl_csi_read(tp, addr); -+ rtl_csi_write(tp, addr, (val & ~mask) | set); -+} -+ - static void rtl_disable_zrxdc_timeout(struct rtl8169_private *tp) - { - struct pci_dev *pdev = tp->pci_dev; -- u32 csi; - int rc; - u8 val; - -@@ -2872,16 +2885,12 @@ static void rtl_disable_zrxdc_timeout(struct rtl8169_private *tp) - } - } - -- netdev_notice_once(tp->dev, -- "No native access to PCI extended config space, falling back to CSI\n"); -- csi = rtl_csi_read(tp, RTL_GEN3_RELATED_OFF); -- rtl_csi_write(tp, RTL_GEN3_RELATED_OFF, csi & ~RTL_GEN3_ZRXDC_NONCOMPL); -+ rtl_csi_mod(tp, RTL_GEN3_RELATED_OFF, RTL_GEN3_ZRXDC_NONCOMPL, 0); - } - - static void rtl_set_aspm_entry_latency(struct rtl8169_private *tp, u8 val) - { - struct pci_dev *pdev = tp->pci_dev; -- u32 csi; - - /* According to Realtek the value at config space address 0x070f - * controls the L0s/L1 entrance latency. We try standard ECAM access -@@ -2893,10 +2902,7 @@ static void rtl_set_aspm_entry_latency(struct rtl8169_private *tp, u8 val) - pci_write_config_byte(pdev, 0x070f, val) == PCIBIOS_SUCCESSFUL) - return; - -- netdev_notice_once(tp->dev, -- "No native access to PCI extended config space, falling back to CSI\n"); -- csi = rtl_csi_read(tp, 0x070c) & 0x00ffffff; -- rtl_csi_write(tp, 0x070c, csi | val << 24); -+ rtl_csi_mod(tp, 0x070c, 0xff000000, val << 24); - } - - static void rtl_set_def_aspm_entry_latency(struct rtl8169_private *tp) --- -2.51.0 - - -From aaf2eb9eaec5f513d9a4870701574ca85343f144 Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Wed, 9 Apr 2025 21:14:47 +0200 -Subject: [PATCH 128/517] r8169: add helper rtl8125_phy_param - -The integrated PHY's of RTL8125/8126 have an own mechanism to access -PHY parameters, similar to what r8168g_phy_param does on earlier PHY -versions. Add helper rtl8125_phy_param to simplify the code. - -Signed-off-by: Heiner Kallweit -Link: https://patch.msgid.link/847b7356-12d6-441b-ade9-4b6e1539b84a@gmail.com -Signed-off-by: Jakub Kicinski ---- - .../net/ethernet/realtek/r8169_phy_config.c | 36 +++++++++---------- - 1 file changed, 16 insertions(+), 20 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/r8169_phy_config.c b/drivers/net/ethernet/realtek/r8169_phy_config.c -index cf95e579c65d..748ca8b212ba 100644 ---- a/drivers/net/ethernet/realtek/r8169_phy_config.c -+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c -@@ -50,6 +50,15 @@ static void r8168g_phy_param(struct phy_device *phydev, u16 parm, - phy_restore_page(phydev, oldpage, 0); - } - -+static void rtl8125_phy_param(struct phy_device *phydev, u16 parm, -+ u16 mask, u16 val) -+{ -+ phy_lock_mdio_bus(phydev); -+ __phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xb87c, parm); -+ __phy_modify_mmd(phydev, MDIO_MMD_VEND2, 0xb87e, mask, val); -+ phy_unlock_mdio_bus(phydev); -+} -+ - struct phy_reg { - u16 reg; - u16 val; -@@ -1004,12 +1013,8 @@ static void rtl8125a_2_hw_phy_config(struct rtl8169_private *tp, - phy_write_paged(phydev, 0xac5, 0x16, 0x01ff); - phy_modify_paged(phydev, 0xac8, 0x15, 0x00f0, 0x0030); - -- phy_write(phydev, 0x1f, 0x0b87); -- phy_write(phydev, 0x16, 0x80a2); -- phy_write(phydev, 0x17, 0x0153); -- phy_write(phydev, 0x16, 0x809c); -- phy_write(phydev, 0x17, 0x0153); -- phy_write(phydev, 0x1f, 0x0000); -+ rtl8125_phy_param(phydev, 0x80a2, 0xffff, 0x0153); -+ rtl8125_phy_param(phydev, 0x809c, 0xffff, 0x0153); - - phy_write(phydev, 0x1f, 0x0a43); - phy_write(phydev, 0x13, 0x81B3); -@@ -1061,14 +1066,9 @@ static void rtl8125b_hw_phy_config(struct rtl8169_private *tp, - phy_modify_paged(phydev, 0xac4, 0x13, 0x00f0, 0x0090); - phy_modify_paged(phydev, 0xad3, 0x10, 0x0003, 0x0001); - -- phy_write(phydev, 0x1f, 0x0b87); -- phy_write(phydev, 0x16, 0x80f5); -- phy_write(phydev, 0x17, 0x760e); -- phy_write(phydev, 0x16, 0x8107); -- phy_write(phydev, 0x17, 0x360e); -- phy_write(phydev, 0x16, 0x8551); -- phy_modify(phydev, 0x17, 0xff00, 0x0800); -- phy_write(phydev, 0x1f, 0x0000); -+ rtl8125_phy_param(phydev, 0x80f5, 0xffff, 0x760e); -+ rtl8125_phy_param(phydev, 0x8107, 0xffff, 0x360e); -+ rtl8125_phy_param(phydev, 0x8551, 0xff00, 0x0800); - - phy_modify_paged(phydev, 0xbf0, 0x10, 0xe000, 0xa000); - phy_modify_paged(phydev, 0xbf4, 0x13, 0x0f00, 0x0300); -@@ -1110,12 +1110,8 @@ static void rtl8125bp_hw_phy_config(struct rtl8169_private *tp, - - r8168g_phy_param(phydev, 0x8010, 0x0800, 0x0000); - -- phy_write(phydev, 0x1f, 0x0b87); -- phy_write(phydev, 0x16, 0x8088); -- phy_modify(phydev, 0x17, 0xff00, 0x9000); -- phy_write(phydev, 0x16, 0x808f); -- phy_modify(phydev, 0x17, 0xff00, 0x9000); -- phy_write(phydev, 0x1f, 0x0000); -+ rtl8125_phy_param(phydev, 0x8088, 0xff00, 0x9000); -+ rtl8125_phy_param(phydev, 0x808f, 0xff00, 0x9000); - - r8168g_phy_param(phydev, 0x8174, 0x2000, 0x1800); - --- -2.51.0 - - -From 09aaa64852d52817e4cd8421cc789e862de34eae Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Tue, 15 Apr 2025 21:29:34 +0200 -Subject: [PATCH 129/517] r8169: refactor chip version detection - -Refactor chip version detection and merge both configuration tables. -Apart from reducing the code by a third, this paves the way for -merging chip version handling if only difference is the firmware. - -Signed-off-by: Heiner Kallweit -Reviewed-by: Michal Swiatkowski -Link: https://patch.msgid.link/1fea533a-dd5a-4198-a9e2-895e11083947@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/r8169_main.c | 325 +++++++++------------- - 1 file changed, 128 insertions(+), 197 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index efdfa95ff693..140577e626bd 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -91,61 +91,114 @@ - #define JUMBO_9K (9 * SZ_1K - VLAN_ETH_HLEN - ETH_FCS_LEN) - #define JUMBO_16K (SZ_16K - VLAN_ETH_HLEN - ETH_FCS_LEN) - --static const struct { -+static const struct rtl_chip_info { -+ u16 mask; -+ u16 val; -+ enum mac_version mac_version; - const char *name; - const char *fw_name; - } rtl_chip_infos[] = { -- /* PCI devices. */ -- [RTL_GIGA_MAC_VER_02] = {"RTL8169s" }, -- [RTL_GIGA_MAC_VER_03] = {"RTL8110s" }, -- [RTL_GIGA_MAC_VER_04] = {"RTL8169sb/8110sb" }, -- [RTL_GIGA_MAC_VER_05] = {"RTL8169sc/8110sc" }, -- [RTL_GIGA_MAC_VER_06] = {"RTL8169sc/8110sc" }, -- /* PCI-E devices. */ -- [RTL_GIGA_MAC_VER_07] = {"RTL8102e" }, -- [RTL_GIGA_MAC_VER_08] = {"RTL8102e" }, -- [RTL_GIGA_MAC_VER_09] = {"RTL8102e/RTL8103e" }, -- [RTL_GIGA_MAC_VER_10] = {"RTL8101e/RTL8100e" }, -- [RTL_GIGA_MAC_VER_14] = {"RTL8401" }, -- [RTL_GIGA_MAC_VER_17] = {"RTL8168b/8111b" }, -- [RTL_GIGA_MAC_VER_18] = {"RTL8168cp/8111cp" }, -- [RTL_GIGA_MAC_VER_19] = {"RTL8168c/8111c" }, -- [RTL_GIGA_MAC_VER_20] = {"RTL8168c/8111c" }, -- [RTL_GIGA_MAC_VER_21] = {"RTL8168c/8111c" }, -- [RTL_GIGA_MAC_VER_22] = {"RTL8168c/8111c" }, -- [RTL_GIGA_MAC_VER_23] = {"RTL8168cp/8111cp" }, -- [RTL_GIGA_MAC_VER_24] = {"RTL8168cp/8111cp" }, -- [RTL_GIGA_MAC_VER_25] = {"RTL8168d/8111d", FIRMWARE_8168D_1}, -- [RTL_GIGA_MAC_VER_26] = {"RTL8168d/8111d", FIRMWARE_8168D_2}, -- [RTL_GIGA_MAC_VER_28] = {"RTL8168dp/8111dp" }, -- [RTL_GIGA_MAC_VER_29] = {"RTL8105e", FIRMWARE_8105E_1}, -- [RTL_GIGA_MAC_VER_30] = {"RTL8105e", FIRMWARE_8105E_1}, -- [RTL_GIGA_MAC_VER_31] = {"RTL8168dp/8111dp" }, -- [RTL_GIGA_MAC_VER_32] = {"RTL8168e/8111e", FIRMWARE_8168E_1}, -- [RTL_GIGA_MAC_VER_33] = {"RTL8168e/8111e", FIRMWARE_8168E_2}, -- [RTL_GIGA_MAC_VER_34] = {"RTL8168evl/8111evl", FIRMWARE_8168E_3}, -- [RTL_GIGA_MAC_VER_35] = {"RTL8168f/8111f", FIRMWARE_8168F_1}, -- [RTL_GIGA_MAC_VER_36] = {"RTL8168f/8111f", FIRMWARE_8168F_2}, -- [RTL_GIGA_MAC_VER_37] = {"RTL8402", FIRMWARE_8402_1 }, -- [RTL_GIGA_MAC_VER_38] = {"RTL8411", FIRMWARE_8411_1 }, -- [RTL_GIGA_MAC_VER_39] = {"RTL8106e", FIRMWARE_8106E_1}, -- [RTL_GIGA_MAC_VER_40] = {"RTL8168g/8111g", FIRMWARE_8168G_2}, -- [RTL_GIGA_MAC_VER_42] = {"RTL8168gu/8111gu", FIRMWARE_8168G_3}, -- [RTL_GIGA_MAC_VER_43] = {"RTL8106eus", FIRMWARE_8106E_2}, -- [RTL_GIGA_MAC_VER_44] = {"RTL8411b", FIRMWARE_8411_2 }, -- [RTL_GIGA_MAC_VER_46] = {"RTL8168h/8111h", FIRMWARE_8168H_2}, -- [RTL_GIGA_MAC_VER_48] = {"RTL8107e", FIRMWARE_8107E_2}, -- [RTL_GIGA_MAC_VER_51] = {"RTL8168ep/8111ep" }, -- [RTL_GIGA_MAC_VER_52] = {"RTL8168fp/RTL8117", FIRMWARE_8168FP_3}, -- [RTL_GIGA_MAC_VER_53] = {"RTL8168fp/RTL8117", }, -- [RTL_GIGA_MAC_VER_61] = {"RTL8125A", FIRMWARE_8125A_3}, -- /* reserve 62 for CFG_METHOD_4 in the vendor driver */ -- [RTL_GIGA_MAC_VER_63] = {"RTL8125B", FIRMWARE_8125B_2}, -- [RTL_GIGA_MAC_VER_64] = {"RTL8125D", FIRMWARE_8125D_1}, -- [RTL_GIGA_MAC_VER_65] = {"RTL8125D", FIRMWARE_8125D_2}, -- [RTL_GIGA_MAC_VER_66] = {"RTL8125BP", FIRMWARE_8125BP_2}, -- [RTL_GIGA_MAC_VER_70] = {"RTL8126A", FIRMWARE_8126A_2}, -- [RTL_GIGA_MAC_VER_71] = {"RTL8126A", FIRMWARE_8126A_3}, -+ /* 8126A family. */ -+ { 0x7cf, 0x64a, RTL_GIGA_MAC_VER_71, "RTL8126A", FIRMWARE_8126A_3 }, -+ { 0x7cf, 0x649, RTL_GIGA_MAC_VER_70, "RTL8126A", FIRMWARE_8126A_2 }, -+ -+ /* 8125BP family. */ -+ { 0x7cf, 0x681, RTL_GIGA_MAC_VER_66, "RTL8125BP", FIRMWARE_8125BP_2 }, -+ -+ /* 8125D family. */ -+ { 0x7cf, 0x689, RTL_GIGA_MAC_VER_65, "RTL8125D", FIRMWARE_8125D_2 }, -+ { 0x7cf, 0x688, RTL_GIGA_MAC_VER_64, "RTL8125D", FIRMWARE_8125D_1 }, -+ -+ /* 8125B family. */ -+ { 0x7cf, 0x641, RTL_GIGA_MAC_VER_63, "RTL8125B", FIRMWARE_8125B_2 }, -+ -+ /* 8125A family. */ -+ { 0x7cf, 0x609, RTL_GIGA_MAC_VER_61, "RTL8125A", FIRMWARE_8125A_3 }, -+ -+ /* RTL8117 */ -+ { 0x7cf, 0x54b, RTL_GIGA_MAC_VER_53, "RTL8168fp/RTL8117" }, -+ { 0x7cf, 0x54a, RTL_GIGA_MAC_VER_52, "RTL8168fp/RTL8117", -+ FIRMWARE_8168FP_3 }, -+ -+ /* 8168EP family. */ -+ { 0x7cf, 0x502, RTL_GIGA_MAC_VER_51, "RTL8168ep/8111ep" }, -+ -+ /* 8168H family. */ -+ { 0x7cf, 0x541, RTL_GIGA_MAC_VER_46, "RTL8168h/8111h", -+ FIRMWARE_8168H_2 }, -+ /* Realtek calls it RTL8168M, but it's handled like RTL8168H */ -+ { 0x7cf, 0x6c0, RTL_GIGA_MAC_VER_46, "RTL8168M", FIRMWARE_8168H_2 }, -+ -+ /* 8168G family. */ -+ { 0x7cf, 0x5c8, RTL_GIGA_MAC_VER_44, "RTL8411b", FIRMWARE_8411_2 }, -+ { 0x7cf, 0x509, RTL_GIGA_MAC_VER_42, "RTL8168gu/8111gu", -+ FIRMWARE_8168G_3 }, -+ { 0x7cf, 0x4c0, RTL_GIGA_MAC_VER_40, "RTL8168g/8111g", -+ FIRMWARE_8168G_2 }, -+ -+ /* 8168F family. */ -+ { 0x7c8, 0x488, RTL_GIGA_MAC_VER_38, "RTL8411", FIRMWARE_8411_1 }, -+ { 0x7cf, 0x481, RTL_GIGA_MAC_VER_36, "RTL8168f/8111f", -+ FIRMWARE_8168F_2 }, -+ { 0x7cf, 0x480, RTL_GIGA_MAC_VER_35, "RTL8168f/8111f", -+ FIRMWARE_8168F_1 }, -+ -+ /* 8168E family. */ -+ { 0x7c8, 0x2c8, RTL_GIGA_MAC_VER_34, "RTL8168evl/8111evl", -+ FIRMWARE_8168E_3 }, -+ { 0x7cf, 0x2c1, RTL_GIGA_MAC_VER_32, "RTL8168e/8111e", -+ FIRMWARE_8168E_1 }, -+ { 0x7c8, 0x2c0, RTL_GIGA_MAC_VER_33, "RTL8168e/8111e", -+ FIRMWARE_8168E_2 }, -+ -+ /* 8168D family. */ -+ { 0x7cf, 0x281, RTL_GIGA_MAC_VER_25, "RTL8168d/8111d", -+ FIRMWARE_8168D_1 }, -+ { 0x7c8, 0x280, RTL_GIGA_MAC_VER_26, "RTL8168d/8111d", -+ FIRMWARE_8168D_2 }, -+ -+ /* 8168DP family. */ -+ { 0x7cf, 0x28a, RTL_GIGA_MAC_VER_28, "RTL8168dp/8111dp" }, -+ { 0x7cf, 0x28b, RTL_GIGA_MAC_VER_31, "RTL8168dp/8111dp" }, -+ -+ /* 8168C family. */ -+ { 0x7cf, 0x3c9, RTL_GIGA_MAC_VER_23, "RTL8168cp/8111cp" }, -+ { 0x7cf, 0x3c8, RTL_GIGA_MAC_VER_18, "RTL8168cp/8111cp" }, -+ { 0x7c8, 0x3c8, RTL_GIGA_MAC_VER_24, "RTL8168cp/8111cp" }, -+ { 0x7cf, 0x3c0, RTL_GIGA_MAC_VER_19, "RTL8168c/8111c" }, -+ { 0x7cf, 0x3c2, RTL_GIGA_MAC_VER_20, "RTL8168c/8111c" }, -+ { 0x7cf, 0x3c3, RTL_GIGA_MAC_VER_21, "RTL8168c/8111c" }, -+ { 0x7c8, 0x3c0, RTL_GIGA_MAC_VER_22, "RTL8168c/8111c" }, -+ -+ /* 8168B family. */ -+ { 0x7c8, 0x380, RTL_GIGA_MAC_VER_17, "RTL8168b/8111b" }, -+ /* This one is very old and rare, support has been removed. -+ * { 0x7c8, 0x300, RTL_GIGA_MAC_VER_11, "RTL8168b/8111b" }, -+ */ -+ -+ /* 8101 family. */ -+ { 0x7c8, 0x448, RTL_GIGA_MAC_VER_39, "RTL8106e", FIRMWARE_8106E_1 }, -+ { 0x7c8, 0x440, RTL_GIGA_MAC_VER_37, "RTL8402", FIRMWARE_8402_1 }, -+ { 0x7cf, 0x409, RTL_GIGA_MAC_VER_29, "RTL8105e", FIRMWARE_8105E_1 }, -+ { 0x7c8, 0x408, RTL_GIGA_MAC_VER_30, "RTL8105e", FIRMWARE_8105E_1 }, -+ { 0x7cf, 0x349, RTL_GIGA_MAC_VER_08, "RTL8102e" }, -+ { 0x7cf, 0x249, RTL_GIGA_MAC_VER_08, "RTL8102e" }, -+ { 0x7cf, 0x348, RTL_GIGA_MAC_VER_07, "RTL8102e" }, -+ { 0x7cf, 0x248, RTL_GIGA_MAC_VER_07, "RTL8102e" }, -+ { 0x7cf, 0x240, RTL_GIGA_MAC_VER_14, "RTL8401" }, -+ { 0x7c8, 0x348, RTL_GIGA_MAC_VER_09, "RTL8102e/RTL8103e" }, -+ { 0x7c8, 0x248, RTL_GIGA_MAC_VER_09, "RTL8102e/RTL8103e" }, -+ { 0x7c8, 0x340, RTL_GIGA_MAC_VER_10, "RTL8101e/RTL8100e" }, -+ -+ /* 8110 family. */ -+ { 0xfc8, 0x980, RTL_GIGA_MAC_VER_06, "RTL8169sc/8110sc" }, -+ { 0xfc8, 0x180, RTL_GIGA_MAC_VER_05, "RTL8169sc/8110sc" }, -+ { 0xfc8, 0x100, RTL_GIGA_MAC_VER_04, "RTL8169sb/8110sb" }, -+ { 0xfc8, 0x040, RTL_GIGA_MAC_VER_03, "RTL8110s" }, -+ { 0xfc8, 0x008, RTL_GIGA_MAC_VER_02, "RTL8169s" }, -+ -+ /* Catch-all */ -+ { 0x000, 0x000, RTL_GIGA_MAC_NONE } - }; - - static const struct pci_device_id rtl8169_pci_tbl[] = { -@@ -2265,151 +2318,30 @@ static const struct ethtool_ops rtl8169_ethtool_ops = { - .get_eth_ctrl_stats = rtl8169_get_eth_ctrl_stats, - }; - --static enum mac_version rtl8169_get_mac_version(u16 xid, bool gmii) -+static const struct rtl_chip_info *rtl8169_get_chip_version(u16 xid, bool gmii) - { -- /* -- * The driver currently handles the 8168Bf and the 8168Be identically -- * but they can be identified more specifically through the test below -- * if needed: -- * -- * (RTL_R32(tp, TxConfig) & 0x700000) == 0x500000 ? 8168Bf : 8168Be -- * -- * Same thing for the 8101Eb and the 8101Ec: -- * -- * (RTL_R32(tp, TxConfig) & 0x700000) == 0x200000 ? 8101Eb : 8101Ec -- */ -- static const struct rtl_mac_info { -- u16 mask; -- u16 val; -- enum mac_version ver; -- } mac_info[] = { -- /* 8126A family. */ -- { 0x7cf, 0x64a, RTL_GIGA_MAC_VER_71 }, -- { 0x7cf, 0x649, RTL_GIGA_MAC_VER_70 }, -- -- /* 8125BP family. */ -- { 0x7cf, 0x681, RTL_GIGA_MAC_VER_66 }, -- -- /* 8125D family. */ -- { 0x7cf, 0x689, RTL_GIGA_MAC_VER_65 }, -- { 0x7cf, 0x688, RTL_GIGA_MAC_VER_64 }, -- -- /* 8125B family. */ -- { 0x7cf, 0x641, RTL_GIGA_MAC_VER_63 }, -- -- /* 8125A family. */ -- { 0x7cf, 0x609, RTL_GIGA_MAC_VER_61 }, -- /* It seems only XID 609 made it to the mass market. -- * { 0x7cf, 0x608, RTL_GIGA_MAC_VER_60 }, -- * { 0x7c8, 0x608, RTL_GIGA_MAC_VER_61 }, -- */ -- -- /* RTL8117 */ -- { 0x7cf, 0x54b, RTL_GIGA_MAC_VER_53 }, -- { 0x7cf, 0x54a, RTL_GIGA_MAC_VER_52 }, -- -- /* 8168EP family. */ -- { 0x7cf, 0x502, RTL_GIGA_MAC_VER_51 }, -- /* It seems this chip version never made it to -- * the wild. Let's disable detection. -- * { 0x7cf, 0x501, RTL_GIGA_MAC_VER_50 }, -- * { 0x7cf, 0x500, RTL_GIGA_MAC_VER_49 }, -- */ -- -- /* 8168H family. */ -- { 0x7cf, 0x541, RTL_GIGA_MAC_VER_46 }, -- /* It seems this chip version never made it to -- * the wild. Let's disable detection. -- * { 0x7cf, 0x540, RTL_GIGA_MAC_VER_45 }, -- */ -- /* Realtek calls it RTL8168M, but it's handled like RTL8168H */ -- { 0x7cf, 0x6c0, RTL_GIGA_MAC_VER_46 }, -- -- /* 8168G family. */ -- { 0x7cf, 0x5c8, RTL_GIGA_MAC_VER_44 }, -- { 0x7cf, 0x509, RTL_GIGA_MAC_VER_42 }, -- /* It seems this chip version never made it to -- * the wild. Let's disable detection. -- * { 0x7cf, 0x4c1, RTL_GIGA_MAC_VER_41 }, -- */ -- { 0x7cf, 0x4c0, RTL_GIGA_MAC_VER_40 }, -- -- /* 8168F family. */ -- { 0x7c8, 0x488, RTL_GIGA_MAC_VER_38 }, -- { 0x7cf, 0x481, RTL_GIGA_MAC_VER_36 }, -- { 0x7cf, 0x480, RTL_GIGA_MAC_VER_35 }, -- -- /* 8168E family. */ -- { 0x7c8, 0x2c8, RTL_GIGA_MAC_VER_34 }, -- { 0x7cf, 0x2c1, RTL_GIGA_MAC_VER_32 }, -- { 0x7c8, 0x2c0, RTL_GIGA_MAC_VER_33 }, -- -- /* 8168D family. */ -- { 0x7cf, 0x281, RTL_GIGA_MAC_VER_25 }, -- { 0x7c8, 0x280, RTL_GIGA_MAC_VER_26 }, -- -- /* 8168DP family. */ -- /* It seems this early RTL8168dp version never made it to -- * the wild. Support has been removed. -- * { 0x7cf, 0x288, RTL_GIGA_MAC_VER_27 }, -- */ -- { 0x7cf, 0x28a, RTL_GIGA_MAC_VER_28 }, -- { 0x7cf, 0x28b, RTL_GIGA_MAC_VER_31 }, -- -- /* 8168C family. */ -- { 0x7cf, 0x3c9, RTL_GIGA_MAC_VER_23 }, -- { 0x7cf, 0x3c8, RTL_GIGA_MAC_VER_18 }, -- { 0x7c8, 0x3c8, RTL_GIGA_MAC_VER_24 }, -- { 0x7cf, 0x3c0, RTL_GIGA_MAC_VER_19 }, -- { 0x7cf, 0x3c2, RTL_GIGA_MAC_VER_20 }, -- { 0x7cf, 0x3c3, RTL_GIGA_MAC_VER_21 }, -- { 0x7c8, 0x3c0, RTL_GIGA_MAC_VER_22 }, -- -- /* 8168B family. */ -- { 0x7c8, 0x380, RTL_GIGA_MAC_VER_17 }, -- /* This one is very old and rare, support has been removed. -- * { 0x7c8, 0x300, RTL_GIGA_MAC_VER_11 }, -- */ -- -- /* 8101 family. */ -- { 0x7c8, 0x448, RTL_GIGA_MAC_VER_39 }, -- { 0x7c8, 0x440, RTL_GIGA_MAC_VER_37 }, -- { 0x7cf, 0x409, RTL_GIGA_MAC_VER_29 }, -- { 0x7c8, 0x408, RTL_GIGA_MAC_VER_30 }, -- { 0x7cf, 0x349, RTL_GIGA_MAC_VER_08 }, -- { 0x7cf, 0x249, RTL_GIGA_MAC_VER_08 }, -- { 0x7cf, 0x348, RTL_GIGA_MAC_VER_07 }, -- { 0x7cf, 0x248, RTL_GIGA_MAC_VER_07 }, -- { 0x7cf, 0x240, RTL_GIGA_MAC_VER_14 }, -- { 0x7c8, 0x348, RTL_GIGA_MAC_VER_09 }, -- { 0x7c8, 0x248, RTL_GIGA_MAC_VER_09 }, -- { 0x7c8, 0x340, RTL_GIGA_MAC_VER_10 }, -- -- /* 8110 family. */ -- { 0xfc8, 0x980, RTL_GIGA_MAC_VER_06 }, -- { 0xfc8, 0x180, RTL_GIGA_MAC_VER_05 }, -- { 0xfc8, 0x100, RTL_GIGA_MAC_VER_04 }, -- { 0xfc8, 0x040, RTL_GIGA_MAC_VER_03 }, -- { 0xfc8, 0x008, RTL_GIGA_MAC_VER_02 }, -- -- /* Catch-all */ -- { 0x000, 0x000, RTL_GIGA_MAC_NONE } -+ /* Chips combining a 1Gbps MAC with a 100Mbps PHY */ -+ static const struct rtl_chip_info rtl8106eus_info = { -+ .mac_version = RTL_GIGA_MAC_VER_43, -+ .name = "RTL8106eus", -+ .fw_name = FIRMWARE_8106E_2, -+ }; -+ static const struct rtl_chip_info rtl8107e_info = { -+ .mac_version = RTL_GIGA_MAC_VER_48, -+ .name = "RTL8107e", -+ .fw_name = FIRMWARE_8107E_2, - }; -- const struct rtl_mac_info *p = mac_info; -- enum mac_version ver; -+ const struct rtl_chip_info *p = rtl_chip_infos; - - while ((xid & p->mask) != p->val) - p++; -- ver = p->ver; - -- if (ver != RTL_GIGA_MAC_NONE && !gmii) { -- if (ver == RTL_GIGA_MAC_VER_42) -- ver = RTL_GIGA_MAC_VER_43; -- else if (ver == RTL_GIGA_MAC_VER_46) -- ver = RTL_GIGA_MAC_VER_48; -- } -+ if (p->mac_version == RTL_GIGA_MAC_VER_42 && !gmii) -+ return &rtl8106eus_info; -+ if (p->mac_version == RTL_GIGA_MAC_VER_46 && !gmii) -+ return &rtl8107e_info; - -- return ver; -+ return p; - } - - static void rtl_release_firmware(struct rtl8169_private *tp) -@@ -5440,9 +5372,9 @@ static bool rtl_aspm_is_safe(struct rtl8169_private *tp) - - static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) - { -+ const struct rtl_chip_info *chip; - struct rtl8169_private *tp; - int jumbo_max, region, rc; -- enum mac_version chipset; - struct net_device *dev; - u32 txconfig; - u16 xid; -@@ -5492,12 +5424,13 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) - xid = (txconfig >> 20) & 0xfcf; - - /* Identify chip attached to board */ -- chipset = rtl8169_get_mac_version(xid, tp->supports_gmii); -- if (chipset == RTL_GIGA_MAC_NONE) -+ chip = rtl8169_get_chip_version(xid, tp->supports_gmii); -+ if (chip->mac_version == RTL_GIGA_MAC_NONE) - return dev_err_probe(&pdev->dev, -ENODEV, - "unknown chip XID %03x, contact r8169 maintainers (see MAINTAINERS file)\n", - xid); -- tp->mac_version = chipset; -+ tp->mac_version = chip->mac_version; -+ tp->fw_name = chip->fw_name; - - /* Disable ASPM L1 as that cause random device stop working - * problems as well as full system hangs for some PCIe devices users. -@@ -5602,8 +5535,6 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) - - rtl_set_irq_mask(tp); - -- tp->fw_name = rtl_chip_infos[chipset].fw_name; -- - tp->counters = dmam_alloc_coherent (&pdev->dev, sizeof(*tp->counters), - &tp->counters_phys_addr, - GFP_KERNEL); -@@ -5628,7 +5559,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) - } - - netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n", -- rtl_chip_infos[chipset].name, dev->dev_addr, xid, tp->irq); -+ chip->name, dev->dev_addr, xid, tp->irq); - - if (jumbo_max) - netdev_info(dev, "jumbo features [frames: %d bytes, tx checksumming: %s]\n", --- -2.51.0 - - -From 6d1a8e18dcd206964f87e9b4cf3b0296eb2aea68 Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Tue, 15 Apr 2025 21:39:23 +0200 -Subject: [PATCH 130/517] r8169: add RTL_GIGA_MAC_VER_LAST to facilitate adding - support for new chip versions - -Add a new mac_version enum value RTL_GIGA_MAC_VER_LAST. Benefit is that -when adding support for a new chip version we have to touch less code, -except something changes fundamentally. - -Signed-off-by: Heiner Kallweit -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/06991f47-2aec-4aa2-8918-2c6e79332303@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/r8169.h | 3 ++- - drivers/net/ethernet/realtek/r8169_main.c | 28 +++++++++++------------ - 2 files changed, 16 insertions(+), 15 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/r8169.h b/drivers/net/ethernet/realtek/r8169.h -index 7a194a8ab989..9f784840ea0d 100644 ---- a/drivers/net/ethernet/realtek/r8169.h -+++ b/drivers/net/ethernet/realtek/r8169.h -@@ -73,7 +73,8 @@ enum mac_version { - RTL_GIGA_MAC_VER_66, - RTL_GIGA_MAC_VER_70, - RTL_GIGA_MAC_VER_71, -- RTL_GIGA_MAC_NONE -+ RTL_GIGA_MAC_NONE, -+ RTL_GIGA_MAC_VER_LAST = RTL_GIGA_MAC_NONE - 1 - }; - - struct rtl8169_private; -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index 140577e626bd..55fd902da0a0 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -1289,7 +1289,7 @@ static void rtl_writephy(struct rtl8169_private *tp, int location, int val) - case RTL_GIGA_MAC_VER_31: - r8168dp_2_mdio_write(tp, location, val); - break; -- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_71: -+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_LAST: - r8168g_mdio_write(tp, location, val); - break; - default: -@@ -1304,7 +1304,7 @@ static int rtl_readphy(struct rtl8169_private *tp, int location) - case RTL_GIGA_MAC_VER_28: - case RTL_GIGA_MAC_VER_31: - return r8168dp_2_mdio_read(tp, location); -- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_71: -+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_LAST: - return r8168g_mdio_read(tp, location); - default: - return r8169_mdio_read(tp, location); -@@ -1656,7 +1656,7 @@ static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts) - break; - case RTL_GIGA_MAC_VER_34: - case RTL_GIGA_MAC_VER_37: -- case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_71: -+ case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_LAST: - r8169_mod_reg8_cond(tp, Config2, PME_SIGNAL, wolopts); - break; - default: -@@ -2129,7 +2129,7 @@ static void rtl_set_eee_txidle_timer(struct rtl8169_private *tp) - tp->tx_lpi_timer = timer_val; - r8168_mac_ocp_write(tp, 0xe048, timer_val); - break; -- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71: -+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_LAST: - tp->tx_lpi_timer = timer_val; - RTL_W16(tp, EEE_TXIDLE_TIMER_8125, timer_val); - break; -@@ -2491,7 +2491,7 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp) - case RTL_GIGA_MAC_VER_61: - RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST); - break; -- case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_71: -+ case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_LAST: - RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST | - RX_PAUSE_SLOT_ON); - break; -@@ -2623,7 +2623,7 @@ static void rtl_wait_txrx_fifo_empty(struct rtl8169_private *tp) - case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_61: - rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42); - break; -- case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_71: -+ case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_LAST: - RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq); - rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42); - rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond_2, 100, 42); -@@ -2898,7 +2898,7 @@ static void rtl_enable_exit_l1(struct rtl8169_private *tp) - case RTL_GIGA_MAC_VER_37 ... RTL_GIGA_MAC_VER_38: - rtl_eri_set_bits(tp, 0xd4, 0x0c00); - break; -- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_71: -+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_LAST: - r8168_mac_ocp_modify(tp, 0xc0ac, 0, 0x1f80); - break; - default: -@@ -2912,7 +2912,7 @@ static void rtl_disable_exit_l1(struct rtl8169_private *tp) - case RTL_GIGA_MAC_VER_34 ... RTL_GIGA_MAC_VER_38: - rtl_eri_clear_bits(tp, 0xd4, 0x1f00); - break; -- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_71: -+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_LAST: - r8168_mac_ocp_modify(tp, 0xc0ac, 0x1f80, 0); - break; - default: -@@ -2950,7 +2950,7 @@ static void rtl_hw_aspm_clkreq_enable(struct rtl8169_private *tp, bool enable) - - switch (tp->mac_version) { - case RTL_GIGA_MAC_VER_46 ... RTL_GIGA_MAC_VER_48: -- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71: -+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_LAST: - /* reset ephy tx/rx disable timer */ - r8168_mac_ocp_modify(tp, 0xe094, 0xff00, 0); - /* chip can trigger L1.2 */ -@@ -2962,7 +2962,7 @@ static void rtl_hw_aspm_clkreq_enable(struct rtl8169_private *tp, bool enable) - } else { - switch (tp->mac_version) { - case RTL_GIGA_MAC_VER_46 ... RTL_GIGA_MAC_VER_48: -- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71: -+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_LAST: - r8168_mac_ocp_modify(tp, 0xe092, 0x00ff, 0); - break; - default: -@@ -4094,7 +4094,7 @@ static void rtl8169_cleanup(struct rtl8169_private *tp) - RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq); - rtl_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666); - break; -- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_71: -+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_LAST: - rtl_enable_rxdvgate(tp); - fsleep(2000); - break; -@@ -4251,7 +4251,7 @@ static unsigned int rtl_quirk_packet_padto(struct rtl8169_private *tp, - - switch (tp->mac_version) { - case RTL_GIGA_MAC_VER_34: -- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71: -+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_LAST: - padto = max_t(unsigned int, padto, ETH_ZLEN); - break; - default: -@@ -5302,7 +5302,7 @@ static void rtl_hw_initialize(struct rtl8169_private *tp) - case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_48: - rtl_hw_init_8168g(tp); - break; -- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71: -+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_LAST: - rtl_hw_init_8125(tp); - break; - default: -@@ -5327,7 +5327,7 @@ static int rtl_jumbo_max(struct rtl8169_private *tp) - case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_24: - return JUMBO_6K; - /* RTL8125/8126 */ -- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71: -+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_LAST: - return JUMBO_16K; - default: - return JUMBO_9K; --- -2.51.0 - - -From 4e4662eb811cb1f8b8d71110751c9e3a8ba11a94 Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Mon, 21 Apr 2025 11:25:18 +0200 -Subject: [PATCH 131/517] r8169: use pci_prepare_to_sleep in rtl_shutdown - -Use pci_prepare_to_sleep() like PCI core does in pci_pm_suspend_noirq. -This aligns setting a low-power mode during shutdown with the handling -of the transition to system suspend. Also the transition to runtime -suspend uses pci_target_state() instead of setting D3hot unconditionally. - -Note: pci_prepare_to_sleep() uses device_may_wakeup() to check whether - device may generate wakeup events. So we don't lose anything by - not passing tp->saved_wolopts any longer. - -Signed-off-by: Heiner Kallweit -Reviewed-by: Jacob Keller -Link: https://patch.msgid.link/f573fdbd-ba6d-41c1-b68f-311d3c88db2c@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/r8169_main.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index 55fd902da0a0..6e353efd342f 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -5040,10 +5040,8 @@ static void rtl_shutdown(struct pci_dev *pdev) - /* Restore original MAC address */ - rtl_rar_set(tp, tp->dev->perm_addr); - -- if (system_state == SYSTEM_POWER_OFF && !tp->dash_enabled) { -- pci_wake_from_d3(pdev, tp->saved_wolopts); -- pci_set_power_state(pdev, PCI_D3hot); -- } -+ if (system_state == SYSTEM_POWER_OFF && !tp->dash_enabled) -+ pci_prepare_to_sleep(pdev); - } - - static void rtl_remove_one(struct pci_dev *pdev) --- -2.51.0 - - -From 871a69f8e15d5804a59dca57da8ede9740f16d3f Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Fri, 18 Apr 2025 11:23:45 +0200 -Subject: [PATCH 132/517] r8169: merge chip versions 70 and 71 (RTL8126A) - -Handling of both chip versions is the same, only difference is -the firmware. So we can merge handling of both chip versions. - -Signed-off-by: Heiner Kallweit -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/97d7ae79-d021-4b6b-b424-89e5e305b029@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/r8169.h | 1 - - drivers/net/ethernet/realtek/r8169_main.c | 15 ++++----------- - drivers/net/ethernet/realtek/r8169_phy_config.c | 1 - - 3 files changed, 4 insertions(+), 13 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/r8169.h b/drivers/net/ethernet/realtek/r8169.h -index 9f784840ea0d..3f7182dc8c9e 100644 ---- a/drivers/net/ethernet/realtek/r8169.h -+++ b/drivers/net/ethernet/realtek/r8169.h -@@ -72,7 +72,6 @@ enum mac_version { - RTL_GIGA_MAC_VER_65, - RTL_GIGA_MAC_VER_66, - RTL_GIGA_MAC_VER_70, -- RTL_GIGA_MAC_VER_71, - RTL_GIGA_MAC_NONE, - RTL_GIGA_MAC_VER_LAST = RTL_GIGA_MAC_NONE - 1 - }; -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index 6e353efd342f..b7ff554ca611 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -99,7 +99,7 @@ static const struct rtl_chip_info { - const char *fw_name; - } rtl_chip_infos[] = { - /* 8126A family. */ -- { 0x7cf, 0x64a, RTL_GIGA_MAC_VER_71, "RTL8126A", FIRMWARE_8126A_3 }, -+ { 0x7cf, 0x64a, RTL_GIGA_MAC_VER_70, "RTL8126A", FIRMWARE_8126A_3 }, - { 0x7cf, 0x649, RTL_GIGA_MAC_VER_70, "RTL8126A", FIRMWARE_8126A_2 }, - - /* 8125BP family. */ -@@ -2939,7 +2939,6 @@ static void rtl_hw_aspm_clkreq_enable(struct rtl8169_private *tp, bool enable) - rtl_mod_config5(tp, 0, ASPM_en); - switch (tp->mac_version) { - case RTL_GIGA_MAC_VER_70: -- case RTL_GIGA_MAC_VER_71: - val8 = RTL_R8(tp, INT_CFG0_8125) | INT_CFG0_CLKREQEN; - RTL_W8(tp, INT_CFG0_8125, val8); - break; -@@ -2971,7 +2970,6 @@ static void rtl_hw_aspm_clkreq_enable(struct rtl8169_private *tp, bool enable) - - switch (tp->mac_version) { - case RTL_GIGA_MAC_VER_70: -- case RTL_GIGA_MAC_VER_71: - val8 = RTL_R8(tp, INT_CFG0_8125) & ~INT_CFG0_CLKREQEN; - RTL_W8(tp, INT_CFG0_8125, val8); - break; -@@ -3691,12 +3689,10 @@ static void rtl_hw_start_8125_common(struct rtl8169_private *tp) - /* disable new tx descriptor format */ - r8168_mac_ocp_modify(tp, 0xeb58, 0x0001, 0x0000); - -- if (tp->mac_version == RTL_GIGA_MAC_VER_70 || -- tp->mac_version == RTL_GIGA_MAC_VER_71) -+ if (tp->mac_version == RTL_GIGA_MAC_VER_70) - RTL_W8(tp, 0xD8, RTL_R8(tp, 0xD8) & ~0x02); - -- if (tp->mac_version == RTL_GIGA_MAC_VER_70 || -- tp->mac_version == RTL_GIGA_MAC_VER_71) -+ if (tp->mac_version == RTL_GIGA_MAC_VER_70) - r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0400); - else if (tp->mac_version == RTL_GIGA_MAC_VER_63) - r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0200); -@@ -3714,8 +3710,7 @@ static void rtl_hw_start_8125_common(struct rtl8169_private *tp) - r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0030); - r8168_mac_ocp_modify(tp, 0xe040, 0x1000, 0x0000); - r8168_mac_ocp_modify(tp, 0xea1c, 0x0003, 0x0001); -- if (tp->mac_version == RTL_GIGA_MAC_VER_70 || -- tp->mac_version == RTL_GIGA_MAC_VER_71) -+ if (tp->mac_version == RTL_GIGA_MAC_VER_70) - r8168_mac_ocp_modify(tp, 0xea1c, 0x0300, 0x0000); - else - r8168_mac_ocp_modify(tp, 0xea1c, 0x0004, 0x0000); -@@ -3838,7 +3833,6 @@ static void rtl_hw_config(struct rtl8169_private *tp) - [RTL_GIGA_MAC_VER_65] = rtl_hw_start_8125d, - [RTL_GIGA_MAC_VER_66] = rtl_hw_start_8125d, - [RTL_GIGA_MAC_VER_70] = rtl_hw_start_8126a, -- [RTL_GIGA_MAC_VER_71] = rtl_hw_start_8126a, - }; - - if (hw_configs[tp->mac_version]) -@@ -3862,7 +3856,6 @@ static void rtl_hw_start_8125(struct rtl8169_private *tp) - break; - case RTL_GIGA_MAC_VER_63: - case RTL_GIGA_MAC_VER_70: -- case RTL_GIGA_MAC_VER_71: - for (i = 0xa00; i < 0xa80; i += 4) - RTL_W32(tp, i, 0); - RTL_W16(tp, INT_CFG1_8125, 0x0000); -diff --git a/drivers/net/ethernet/realtek/r8169_phy_config.c b/drivers/net/ethernet/realtek/r8169_phy_config.c -index 748ca8b212ba..7f513086ba96 100644 ---- a/drivers/net/ethernet/realtek/r8169_phy_config.c -+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c -@@ -1183,7 +1183,6 @@ void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev, - [RTL_GIGA_MAC_VER_65] = rtl8125d_hw_phy_config, - [RTL_GIGA_MAC_VER_66] = rtl8125bp_hw_phy_config, - [RTL_GIGA_MAC_VER_70] = rtl8126a_hw_phy_config, -- [RTL_GIGA_MAC_VER_71] = rtl8126a_hw_phy_config, - }; - - if (phy_configs[ver]) --- -2.51.0 - - -From 26be2181b358372db7fb62af9e69d9f4fb70d0b0 Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Fri, 18 Apr 2025 11:24:30 +0200 -Subject: [PATCH 133/517] r8169: merge chip versions 64 and 65 (RTL8125D) - -Handling of both chip versions is the same, only difference is -the firmware. So we can merge handling of both chip versions. - -Signed-off-by: Heiner Kallweit -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/0baad123-c679-4154-923f-fdc12783e900@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/r8169.h | 1 - - drivers/net/ethernet/realtek/r8169_main.c | 4 +--- - drivers/net/ethernet/realtek/r8169_phy_config.c | 1 - - 3 files changed, 1 insertion(+), 5 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/r8169.h b/drivers/net/ethernet/realtek/r8169.h -index 3f7182dc8c9e..1878c44ece91 100644 ---- a/drivers/net/ethernet/realtek/r8169.h -+++ b/drivers/net/ethernet/realtek/r8169.h -@@ -69,7 +69,6 @@ enum mac_version { - RTL_GIGA_MAC_VER_61, - RTL_GIGA_MAC_VER_63, - RTL_GIGA_MAC_VER_64, -- RTL_GIGA_MAC_VER_65, - RTL_GIGA_MAC_VER_66, - RTL_GIGA_MAC_VER_70, - RTL_GIGA_MAC_NONE, -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index b7ff554ca611..0c5afbc8f5fe 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -106,7 +106,7 @@ static const struct rtl_chip_info { - { 0x7cf, 0x681, RTL_GIGA_MAC_VER_66, "RTL8125BP", FIRMWARE_8125BP_2 }, - - /* 8125D family. */ -- { 0x7cf, 0x689, RTL_GIGA_MAC_VER_65, "RTL8125D", FIRMWARE_8125D_2 }, -+ { 0x7cf, 0x689, RTL_GIGA_MAC_VER_64, "RTL8125D", FIRMWARE_8125D_2 }, - { 0x7cf, 0x688, RTL_GIGA_MAC_VER_64, "RTL8125D", FIRMWARE_8125D_1 }, - - /* 8125B family. */ -@@ -3830,7 +3830,6 @@ static void rtl_hw_config(struct rtl8169_private *tp) - [RTL_GIGA_MAC_VER_61] = rtl_hw_start_8125a_2, - [RTL_GIGA_MAC_VER_63] = rtl_hw_start_8125b, - [RTL_GIGA_MAC_VER_64] = rtl_hw_start_8125d, -- [RTL_GIGA_MAC_VER_65] = rtl_hw_start_8125d, - [RTL_GIGA_MAC_VER_66] = rtl_hw_start_8125d, - [RTL_GIGA_MAC_VER_70] = rtl_hw_start_8126a, - }; -@@ -3849,7 +3848,6 @@ static void rtl_hw_start_8125(struct rtl8169_private *tp) - switch (tp->mac_version) { - case RTL_GIGA_MAC_VER_61: - case RTL_GIGA_MAC_VER_64: -- case RTL_GIGA_MAC_VER_65: - case RTL_GIGA_MAC_VER_66: - for (i = 0xa00; i < 0xb00; i += 4) - RTL_W32(tp, i, 0); -diff --git a/drivers/net/ethernet/realtek/r8169_phy_config.c b/drivers/net/ethernet/realtek/r8169_phy_config.c -index 7f513086ba96..e3adfafa2b1b 100644 ---- a/drivers/net/ethernet/realtek/r8169_phy_config.c -+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c -@@ -1180,7 +1180,6 @@ void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev, - [RTL_GIGA_MAC_VER_61] = rtl8125a_2_hw_phy_config, - [RTL_GIGA_MAC_VER_63] = rtl8125b_hw_phy_config, - [RTL_GIGA_MAC_VER_64] = rtl8125d_hw_phy_config, -- [RTL_GIGA_MAC_VER_65] = rtl8125d_hw_phy_config, - [RTL_GIGA_MAC_VER_66] = rtl8125bp_hw_phy_config, - [RTL_GIGA_MAC_VER_70] = rtl8126a_hw_phy_config, - }; --- -2.51.0 - - -From 6d604938ecae971d603aeae185c08c65492c24e4 Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Fri, 18 Apr 2025 11:25:17 +0200 -Subject: [PATCH 134/517] r8169: merge chip versions 52 and 53 (RTL8117) - -Handling of both chip versions is the same, only difference is -the firmware. So we can merge handling of both chip versions. - -Signed-off-by: Heiner Kallweit -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/ae866b71-c904-434e-befb-848c831e33ff@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/r8169.h | 1 - - drivers/net/ethernet/realtek/r8169_main.c | 17 +++++++---------- - drivers/net/ethernet/realtek/r8169_phy_config.c | 1 - - 3 files changed, 7 insertions(+), 12 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/r8169.h b/drivers/net/ethernet/realtek/r8169.h -index 1878c44ece91..f05231030925 100644 ---- a/drivers/net/ethernet/realtek/r8169.h -+++ b/drivers/net/ethernet/realtek/r8169.h -@@ -64,7 +64,6 @@ enum mac_version { - /* support for RTL_GIGA_MAC_VER_50 has been removed */ - RTL_GIGA_MAC_VER_51, - RTL_GIGA_MAC_VER_52, -- RTL_GIGA_MAC_VER_53, - /* support for RTL_GIGA_MAC_VER_60 has been removed */ - RTL_GIGA_MAC_VER_61, - RTL_GIGA_MAC_VER_63, -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index 0c5afbc8f5fe..1af644a62968 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -116,7 +116,7 @@ static const struct rtl_chip_info { - { 0x7cf, 0x609, RTL_GIGA_MAC_VER_61, "RTL8125A", FIRMWARE_8125A_3 }, - - /* RTL8117 */ -- { 0x7cf, 0x54b, RTL_GIGA_MAC_VER_53, "RTL8168fp/RTL8117" }, -+ { 0x7cf, 0x54b, RTL_GIGA_MAC_VER_52, "RTL8168fp/RTL8117" }, - { 0x7cf, 0x54a, RTL_GIGA_MAC_VER_52, "RTL8168fp/RTL8117", - FIRMWARE_8168FP_3 }, - -@@ -830,7 +830,7 @@ static bool rtl_is_8168evl_up(struct rtl8169_private *tp) - { - return tp->mac_version >= RTL_GIGA_MAC_VER_34 && - tp->mac_version != RTL_GIGA_MAC_VER_39 && -- tp->mac_version <= RTL_GIGA_MAC_VER_53; -+ tp->mac_version <= RTL_GIGA_MAC_VER_52; - } - - static bool rtl_supports_eee(struct rtl8169_private *tp) -@@ -998,9 +998,7 @@ void r8169_get_led_name(struct rtl8169_private *tp, int idx, - static void r8168fp_adjust_ocp_cmd(struct rtl8169_private *tp, u32 *cmd, int type) - { - /* based on RTL8168FP_OOBMAC_BASE in vendor driver */ -- if (type == ERIAR_OOB && -- (tp->mac_version == RTL_GIGA_MAC_VER_52 || -- tp->mac_version == RTL_GIGA_MAC_VER_53)) -+ if (type == ERIAR_OOB && tp->mac_version == RTL_GIGA_MAC_VER_52) - *cmd |= 0xf70 << 18; - } - -@@ -1500,7 +1498,7 @@ static enum rtl_dash_type rtl_get_dash_type(struct rtl8169_private *tp) - case RTL_GIGA_MAC_VER_28: - case RTL_GIGA_MAC_VER_31: - return RTL_DASH_DP; -- case RTL_GIGA_MAC_VER_51 ... RTL_GIGA_MAC_VER_53: -+ case RTL_GIGA_MAC_VER_51 ... RTL_GIGA_MAC_VER_52: - return RTL_DASH_EP; - case RTL_GIGA_MAC_VER_66: - return RTL_DASH_25_BP; -@@ -2485,7 +2483,7 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp) - case RTL_GIGA_MAC_VER_38: - RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST); - break; -- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_53: -+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_52: - RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | RX_EARLY_OFF); - break; - case RTL_GIGA_MAC_VER_61: -@@ -2616,7 +2614,7 @@ DECLARE_RTL_COND(rtl_rxtx_empty_cond_2) - static void rtl_wait_txrx_fifo_empty(struct rtl8169_private *tp) - { - switch (tp->mac_version) { -- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_53: -+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_52: - rtl_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 42); - rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42); - break; -@@ -3826,7 +3824,6 @@ static void rtl_hw_config(struct rtl8169_private *tp) - [RTL_GIGA_MAC_VER_48] = rtl_hw_start_8168h_1, - [RTL_GIGA_MAC_VER_51] = rtl_hw_start_8168ep_3, - [RTL_GIGA_MAC_VER_52] = rtl_hw_start_8117, -- [RTL_GIGA_MAC_VER_53] = rtl_hw_start_8117, - [RTL_GIGA_MAC_VER_61] = rtl_hw_start_8125a_2, - [RTL_GIGA_MAC_VER_63] = rtl_hw_start_8125b, - [RTL_GIGA_MAC_VER_64] = rtl_hw_start_8125d, -@@ -5285,7 +5282,7 @@ static void rtl_hw_init_8125(struct rtl8169_private *tp) - static void rtl_hw_initialize(struct rtl8169_private *tp) - { - switch (tp->mac_version) { -- case RTL_GIGA_MAC_VER_51 ... RTL_GIGA_MAC_VER_53: -+ case RTL_GIGA_MAC_VER_51 ... RTL_GIGA_MAC_VER_52: - rtl8168ep_stop_cmac(tp); - fallthrough; - case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_48: -diff --git a/drivers/net/ethernet/realtek/r8169_phy_config.c b/drivers/net/ethernet/realtek/r8169_phy_config.c -index e3adfafa2b1b..5403f8202c79 100644 ---- a/drivers/net/ethernet/realtek/r8169_phy_config.c -+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c -@@ -1176,7 +1176,6 @@ void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev, - [RTL_GIGA_MAC_VER_48] = rtl8168h_2_hw_phy_config, - [RTL_GIGA_MAC_VER_51] = rtl8168ep_2_hw_phy_config, - [RTL_GIGA_MAC_VER_52] = rtl8117_hw_phy_config, -- [RTL_GIGA_MAC_VER_53] = rtl8117_hw_phy_config, - [RTL_GIGA_MAC_VER_61] = rtl8125a_2_hw_phy_config, - [RTL_GIGA_MAC_VER_63] = rtl8125b_hw_phy_config, - [RTL_GIGA_MAC_VER_64] = rtl8125d_hw_phy_config, --- -2.51.0 - - -From c3fdac7c0b9944f77753c0293f813b86ea29a0e4 Mon Sep 17 00:00:00 2001 -From: ChunHao Lin -Date: Thu, 15 May 2025 17:53:03 +0800 -Subject: [PATCH 135/517] r8169: add support for RTL8127A - -This adds support for 10Gbs chip RTL8127A. - -Signed-off-by: ChunHao Lin -Reviewed-by: Heiner Kallweit -Link: https://patch.msgid.link/20250515095303.3138-1-hau@realtek.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/realtek/r8169.h | 1 + - drivers/net/ethernet/realtek/r8169_main.c | 29 ++- - .../net/ethernet/realtek/r8169_phy_config.c | 166 ++++++++++++++++++ - 3 files changed, 193 insertions(+), 3 deletions(-) - -diff --git a/drivers/net/ethernet/realtek/r8169.h b/drivers/net/ethernet/realtek/r8169.h -index f05231030925..2c1a0c21af8d 100644 ---- a/drivers/net/ethernet/realtek/r8169.h -+++ b/drivers/net/ethernet/realtek/r8169.h -@@ -70,6 +70,7 @@ enum mac_version { - RTL_GIGA_MAC_VER_64, - RTL_GIGA_MAC_VER_66, - RTL_GIGA_MAC_VER_70, -+ RTL_GIGA_MAC_VER_80, - RTL_GIGA_MAC_NONE, - RTL_GIGA_MAC_VER_LAST = RTL_GIGA_MAC_NONE - 1 - }; -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index 1af644a62968..c16741eec0bd 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -60,6 +60,7 @@ - #define FIRMWARE_8125BP_2 "rtl_nic/rtl8125bp-2.fw" - #define FIRMWARE_8126A_2 "rtl_nic/rtl8126a-2.fw" - #define FIRMWARE_8126A_3 "rtl_nic/rtl8126a-3.fw" -+#define FIRMWARE_8127A_1 "rtl_nic/rtl8127a-1.fw" - - #define TX_DMA_BURST 7 /* Maximum PCI burst, '7' is unlimited */ - #define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ -@@ -98,6 +99,9 @@ static const struct rtl_chip_info { - const char *name; - const char *fw_name; - } rtl_chip_infos[] = { -+ /* 8127A family. */ -+ { 0x7cf, 0x6c9, RTL_GIGA_MAC_VER_80, "RTL8127A", FIRMWARE_8127A_1 }, -+ - /* 8126A family. */ - { 0x7cf, 0x64a, RTL_GIGA_MAC_VER_70, "RTL8126A", FIRMWARE_8126A_3 }, - { 0x7cf, 0x649, RTL_GIGA_MAC_VER_70, "RTL8126A", FIRMWARE_8126A_2 }, -@@ -222,8 +226,10 @@ static const struct pci_device_id rtl8169_pci_tbl[] = { - { 0x0001, 0x8168, PCI_ANY_ID, 0x2410 }, - { PCI_VDEVICE(REALTEK, 0x8125) }, - { PCI_VDEVICE(REALTEK, 0x8126) }, -+ { PCI_VDEVICE(REALTEK, 0x8127) }, - { PCI_VDEVICE(REALTEK, 0x3000) }, - { PCI_VDEVICE(REALTEK, 0x5000) }, -+ { PCI_VDEVICE(REALTEK, 0x0e10) }, - {} - }; - -@@ -769,6 +775,7 @@ MODULE_FIRMWARE(FIRMWARE_8125D_2); - MODULE_FIRMWARE(FIRMWARE_8125BP_2); - MODULE_FIRMWARE(FIRMWARE_8126A_2); - MODULE_FIRMWARE(FIRMWARE_8126A_3); -+MODULE_FIRMWARE(FIRMWARE_8127A_1); - - static inline struct device *tp_to_dev(struct rtl8169_private *tp) - { -@@ -2937,6 +2944,7 @@ static void rtl_hw_aspm_clkreq_enable(struct rtl8169_private *tp, bool enable) - rtl_mod_config5(tp, 0, ASPM_en); - switch (tp->mac_version) { - case RTL_GIGA_MAC_VER_70: -+ case RTL_GIGA_MAC_VER_80: - val8 = RTL_R8(tp, INT_CFG0_8125) | INT_CFG0_CLKREQEN; - RTL_W8(tp, INT_CFG0_8125, val8); - break; -@@ -2968,6 +2976,7 @@ static void rtl_hw_aspm_clkreq_enable(struct rtl8169_private *tp, bool enable) - - switch (tp->mac_version) { - case RTL_GIGA_MAC_VER_70: -+ case RTL_GIGA_MAC_VER_80: - val8 = RTL_R8(tp, INT_CFG0_8125) & ~INT_CFG0_CLKREQEN; - RTL_W8(tp, INT_CFG0_8125, val8); - break; -@@ -3687,10 +3696,13 @@ static void rtl_hw_start_8125_common(struct rtl8169_private *tp) - /* disable new tx descriptor format */ - r8168_mac_ocp_modify(tp, 0xeb58, 0x0001, 0x0000); - -- if (tp->mac_version == RTL_GIGA_MAC_VER_70) -+ if (tp->mac_version == RTL_GIGA_MAC_VER_70 || -+ tp->mac_version == RTL_GIGA_MAC_VER_80) - RTL_W8(tp, 0xD8, RTL_R8(tp, 0xD8) & ~0x02); - -- if (tp->mac_version == RTL_GIGA_MAC_VER_70) -+ if (tp->mac_version == RTL_GIGA_MAC_VER_80) -+ r8168_mac_ocp_modify(tp, 0xe614, 0x0f00, 0x0f00); -+ else if (tp->mac_version == RTL_GIGA_MAC_VER_70) - r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0400); - else if (tp->mac_version == RTL_GIGA_MAC_VER_63) - r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0200); -@@ -3708,7 +3720,8 @@ static void rtl_hw_start_8125_common(struct rtl8169_private *tp) - r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0030); - r8168_mac_ocp_modify(tp, 0xe040, 0x1000, 0x0000); - r8168_mac_ocp_modify(tp, 0xea1c, 0x0003, 0x0001); -- if (tp->mac_version == RTL_GIGA_MAC_VER_70) -+ if (tp->mac_version == RTL_GIGA_MAC_VER_70 || -+ tp->mac_version == RTL_GIGA_MAC_VER_80) - r8168_mac_ocp_modify(tp, 0xea1c, 0x0300, 0x0000); - else - r8168_mac_ocp_modify(tp, 0xea1c, 0x0004, 0x0000); -@@ -3786,6 +3799,12 @@ static void rtl_hw_start_8126a(struct rtl8169_private *tp) - rtl_hw_start_8125_common(tp); - } - -+static void rtl_hw_start_8127a(struct rtl8169_private *tp) -+{ -+ rtl_set_def_aspm_entry_latency(tp); -+ rtl_hw_start_8125_common(tp); -+} -+ - static void rtl_hw_config(struct rtl8169_private *tp) - { - static const rtl_generic_fct hw_configs[] = { -@@ -3829,6 +3848,7 @@ static void rtl_hw_config(struct rtl8169_private *tp) - [RTL_GIGA_MAC_VER_64] = rtl_hw_start_8125d, - [RTL_GIGA_MAC_VER_66] = rtl_hw_start_8125d, - [RTL_GIGA_MAC_VER_70] = rtl_hw_start_8126a, -+ [RTL_GIGA_MAC_VER_80] = rtl_hw_start_8127a, - }; - - if (hw_configs[tp->mac_version]) -@@ -3846,8 +3866,11 @@ static void rtl_hw_start_8125(struct rtl8169_private *tp) - case RTL_GIGA_MAC_VER_61: - case RTL_GIGA_MAC_VER_64: - case RTL_GIGA_MAC_VER_66: -+ case RTL_GIGA_MAC_VER_80: - for (i = 0xa00; i < 0xb00; i += 4) - RTL_W32(tp, i, 0); -+ if (tp->mac_version == RTL_GIGA_MAC_VER_80) -+ RTL_W16(tp, INT_CFG1_8125, 0x0000); - break; - case RTL_GIGA_MAC_VER_63: - case RTL_GIGA_MAC_VER_70: -diff --git a/drivers/net/ethernet/realtek/r8169_phy_config.c b/drivers/net/ethernet/realtek/r8169_phy_config.c -index 5403f8202c79..032d9d2cfa2a 100644 ---- a/drivers/net/ethernet/realtek/r8169_phy_config.c -+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c -@@ -1130,6 +1130,171 @@ static void rtl8126a_hw_phy_config(struct rtl8169_private *tp, - rtl8125_common_config_eee_phy(phydev); - } - -+static void rtl8127a_1_hw_phy_config(struct rtl8169_private *tp, -+ struct phy_device *phydev) -+{ -+ r8169_apply_firmware(tp); -+ rtl8168g_enable_gphy_10m(phydev); -+ -+ r8168g_phy_param(phydev, 0x8415, 0xff00, 0x9300); -+ r8168g_phy_param(phydev, 0x81a3, 0xff00, 0x0f00); -+ r8168g_phy_param(phydev, 0x81ae, 0xff00, 0x0f00); -+ r8168g_phy_param(phydev, 0x81b9, 0xff00, 0xb900); -+ rtl8125_phy_param(phydev, 0x83b0, 0x0e00, 0x0000); -+ rtl8125_phy_param(phydev, 0x83C5, 0x0e00, 0x0000); -+ rtl8125_phy_param(phydev, 0x83da, 0x0e00, 0x0000); -+ rtl8125_phy_param(phydev, 0x83ef, 0x0e00, 0x0000); -+ phy_modify_paged(phydev, 0x0bf3, 0x14, 0x01f0, 0x0160); -+ phy_modify_paged(phydev, 0x0bf3, 0x15, 0x001f, 0x0014); -+ phy_modify_paged(phydev, 0x0bf2, 0x14, 0x6000, 0x0000); -+ phy_modify_paged(phydev, 0x0bf2, 0x16, 0xc000, 0x0000); -+ phy_modify_paged(phydev, 0x0bf2, 0x14, 0x1fff, 0x0187); -+ phy_modify_paged(phydev, 0x0bf2, 0x15, 0x003f, 0x0003); -+ -+ r8168g_phy_param(phydev, 0x8173, 0xffff, 0x8620); -+ r8168g_phy_param(phydev, 0x8175, 0xffff, 0x8671); -+ r8168g_phy_param(phydev, 0x817c, 0x0000, 0x2000); -+ r8168g_phy_param(phydev, 0x8187, 0x0000, 0x2000); -+ r8168g_phy_param(phydev, 0x8192, 0x0000, 0x2000); -+ r8168g_phy_param(phydev, 0x819d, 0x0000, 0x2000); -+ r8168g_phy_param(phydev, 0x81a8, 0x2000, 0x0000); -+ r8168g_phy_param(phydev, 0x81b3, 0x2000, 0x0000); -+ r8168g_phy_param(phydev, 0x81be, 0x0000, 0x2000); -+ r8168g_phy_param(phydev, 0x817d, 0xff00, 0xa600); -+ r8168g_phy_param(phydev, 0x8188, 0xff00, 0xa600); -+ r8168g_phy_param(phydev, 0x8193, 0xff00, 0xa600); -+ r8168g_phy_param(phydev, 0x819e, 0xff00, 0xa600); -+ r8168g_phy_param(phydev, 0x81a9, 0xff00, 0x1400); -+ r8168g_phy_param(phydev, 0x81b4, 0xff00, 0x1400); -+ r8168g_phy_param(phydev, 0x81bf, 0xff00, 0xa600); -+ -+ phy_modify_paged(phydev, 0x0aea, 0x15, 0x0028, 0x0000); -+ -+ rtl8125_phy_param(phydev, 0x84f0, 0xffff, 0x201c); -+ rtl8125_phy_param(phydev, 0x84f2, 0xffff, 0x3117); -+ -+ phy_write_paged(phydev, 0x0aec, 0x13, 0x0000); -+ phy_write_paged(phydev, 0x0ae2, 0x10, 0xffff); -+ phy_write_paged(phydev, 0x0aec, 0x17, 0xffff); -+ phy_write_paged(phydev, 0x0aed, 0x11, 0xffff); -+ phy_write_paged(phydev, 0x0aec, 0x14, 0x0000); -+ phy_modify_paged(phydev, 0x0aed, 0x10, 0x0001, 0x0000); -+ phy_write_paged(phydev, 0x0adb, 0x14, 0x0150); -+ rtl8125_phy_param(phydev, 0x8197, 0xff00, 0x5000); -+ rtl8125_phy_param(phydev, 0x8231, 0xff00, 0x5000); -+ rtl8125_phy_param(phydev, 0x82cb, 0xff00, 0x5000); -+ rtl8125_phy_param(phydev, 0x82cd, 0xff00, 0x5700); -+ rtl8125_phy_param(phydev, 0x8233, 0xff00, 0x5700); -+ rtl8125_phy_param(phydev, 0x8199, 0xff00, 0x5700); -+ -+ rtl8125_phy_param(phydev, 0x815a, 0xffff, 0x0150); -+ rtl8125_phy_param(phydev, 0x81f4, 0xffff, 0x0150); -+ rtl8125_phy_param(phydev, 0x828e, 0xffff, 0x0150); -+ rtl8125_phy_param(phydev, 0x81b1, 0xffff, 0x0000); -+ rtl8125_phy_param(phydev, 0x824b, 0xffff, 0x0000); -+ rtl8125_phy_param(phydev, 0x82e5, 0xffff, 0x0000); -+ -+ rtl8125_phy_param(phydev, 0x84f7, 0xff00, 0x2800); -+ phy_modify_paged(phydev, 0x0aec, 0x11, 0x0000, 0x1000); -+ rtl8125_phy_param(phydev, 0x81b3, 0xff00, 0xad00); -+ rtl8125_phy_param(phydev, 0x824d, 0xff00, 0xad00); -+ rtl8125_phy_param(phydev, 0x82e7, 0xff00, 0xad00); -+ phy_modify_paged(phydev, 0x0ae4, 0x17, 0x000f, 0x0001); -+ rtl8125_phy_param(phydev, 0x82ce, 0xf000, 0x4000); -+ -+ rtl8125_phy_param(phydev, 0x84ac, 0xffff, 0x0000); -+ rtl8125_phy_param(phydev, 0x84ae, 0xffff, 0x0000); -+ rtl8125_phy_param(phydev, 0x84b0, 0xffff, 0xf818); -+ rtl8125_phy_param(phydev, 0x84b2, 0xff00, 0x6000); -+ -+ rtl8125_phy_param(phydev, 0x8ffc, 0xffff, 0x6008); -+ rtl8125_phy_param(phydev, 0x8ffe, 0xffff, 0xf450); -+ -+ rtl8125_phy_param(phydev, 0x8015, 0x0000, 0x0200); -+ rtl8125_phy_param(phydev, 0x8016, 0x0800, 0x0000); -+ rtl8125_phy_param(phydev, 0x8fe6, 0xff00, 0x0800); -+ rtl8125_phy_param(phydev, 0x8fe4, 0xffff, 0x2114); -+ -+ rtl8125_phy_param(phydev, 0x8647, 0xffff, 0xa7b1); -+ rtl8125_phy_param(phydev, 0x8649, 0xffff, 0xbbca); -+ rtl8125_phy_param(phydev, 0x864b, 0xff00, 0xdc00); -+ -+ rtl8125_phy_param(phydev, 0x8154, 0xc000, 0x4000); -+ rtl8125_phy_param(phydev, 0x8158, 0xc000, 0x0000); -+ -+ rtl8125_phy_param(phydev, 0x826c, 0xffff, 0xffff); -+ rtl8125_phy_param(phydev, 0x826e, 0xffff, 0xffff); -+ -+ rtl8125_phy_param(phydev, 0x8872, 0xff00, 0x0e00); -+ r8168g_phy_param(phydev, 0x8012, 0x0000, 0x0800); -+ r8168g_phy_param(phydev, 0x8012, 0x0000, 0x4000); -+ phy_modify_paged(phydev, 0x0b57, 0x13, 0x0000, 0x0001); -+ r8168g_phy_param(phydev, 0x834a, 0xff00, 0x0700); -+ rtl8125_phy_param(phydev, 0x8217, 0x3f00, 0x2a00); -+ r8168g_phy_param(phydev, 0x81b1, 0xff00, 0x0b00); -+ rtl8125_phy_param(phydev, 0x8fed, 0xff00, 0x4e00); -+ -+ rtl8125_phy_param(phydev, 0x88ac, 0xff00, 0x2300); -+ phy_modify_paged(phydev, 0x0bf0, 0x16, 0x0000, 0x3800); -+ rtl8125_phy_param(phydev, 0x88de, 0xff00, 0x0000); -+ rtl8125_phy_param(phydev, 0x80b4, 0xffff, 0x5195); -+ -+ r8168g_phy_param(phydev, 0x8370, 0xffff, 0x8671); -+ r8168g_phy_param(phydev, 0x8372, 0xffff, 0x86c8); -+ -+ r8168g_phy_param(phydev, 0x8401, 0xffff, 0x86c8); -+ r8168g_phy_param(phydev, 0x8403, 0xffff, 0x86da); -+ r8168g_phy_param(phydev, 0x8406, 0x1800, 0x1000); -+ r8168g_phy_param(phydev, 0x8408, 0x1800, 0x1000); -+ r8168g_phy_param(phydev, 0x840a, 0x1800, 0x1000); -+ r8168g_phy_param(phydev, 0x840c, 0x1800, 0x1000); -+ r8168g_phy_param(phydev, 0x840e, 0x1800, 0x1000); -+ r8168g_phy_param(phydev, 0x8410, 0x1800, 0x1000); -+ r8168g_phy_param(phydev, 0x8412, 0x1800, 0x1000); -+ r8168g_phy_param(phydev, 0x8414, 0x1800, 0x1000); -+ r8168g_phy_param(phydev, 0x8416, 0x1800, 0x1000); -+ -+ r8168g_phy_param(phydev, 0x82bd, 0xffff, 0x1f40); -+ -+ phy_modify_paged(phydev, 0x0bfb, 0x12, 0x07ff, 0x0328); -+ phy_write_paged(phydev, 0x0bfb, 0x13, 0x3e14); -+ -+ r8168g_phy_param(phydev, 0x81c4, 0xffff, 0x003b); -+ r8168g_phy_param(phydev, 0x81c6, 0xffff, 0x0086); -+ r8168g_phy_param(phydev, 0x81c8, 0xffff, 0x00b7); -+ r8168g_phy_param(phydev, 0x81ca, 0xffff, 0x00db); -+ r8168g_phy_param(phydev, 0x81cc, 0xffff, 0x00fe); -+ r8168g_phy_param(phydev, 0x81ce, 0xffff, 0x00fe); -+ r8168g_phy_param(phydev, 0x81d0, 0xffff, 0x00fe); -+ r8168g_phy_param(phydev, 0x81d2, 0xffff, 0x00fe); -+ r8168g_phy_param(phydev, 0x81d4, 0xffff, 0x00c3); -+ r8168g_phy_param(phydev, 0x81d6, 0xffff, 0x0078); -+ r8168g_phy_param(phydev, 0x81d8, 0xffff, 0x0047); -+ r8168g_phy_param(phydev, 0x81da, 0xffff, 0x0023); -+ -+ rtl8125_phy_param(phydev, 0x88d7, 0xffff, 0x01a0); -+ rtl8125_phy_param(phydev, 0x88d9, 0xffff, 0x01a0); -+ rtl8125_phy_param(phydev, 0x8ffa, 0xffff, 0x002a); -+ -+ rtl8125_phy_param(phydev, 0x8fee, 0xffff, 0xffdf); -+ rtl8125_phy_param(phydev, 0x8ff0, 0xffff, 0xffff); -+ rtl8125_phy_param(phydev, 0x8ff2, 0xffff, 0x0a4a); -+ rtl8125_phy_param(phydev, 0x8ff4, 0xffff, 0xaa5a); -+ rtl8125_phy_param(phydev, 0x8ff6, 0xffff, 0x0a4a); -+ -+ rtl8125_phy_param(phydev, 0x8ff8, 0xffff, 0xaa5a); -+ rtl8125_phy_param(phydev, 0x88d5, 0xff00, 0x0200); -+ -+ r8168g_phy_param(phydev, 0x84bb, 0xff00, 0x0a00); -+ r8168g_phy_param(phydev, 0x84c0, 0xff00, 0x1600); -+ -+ phy_modify_paged(phydev, 0x0a43, 0x10, 0x0000, 0x0003); -+ -+ rtl8125_legacy_force_mode(phydev); -+ rtl8168g_disable_aldps(phydev); -+ rtl8125_common_config_eee_phy(phydev); -+} -+ - void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev, - enum mac_version ver) - { -@@ -1181,6 +1346,7 @@ void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev, - [RTL_GIGA_MAC_VER_64] = rtl8125d_hw_phy_config, - [RTL_GIGA_MAC_VER_66] = rtl8125bp_hw_phy_config, - [RTL_GIGA_MAC_VER_70] = rtl8126a_hw_phy_config, -+ [RTL_GIGA_MAC_VER_80] = rtl8127a_1_hw_phy_config, - }; - - if (phy_configs[ver]) --- -2.51.0 - - -From 76bb2f3d8a700c0e1e0de6582d7c4469d51dbee6 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 10 Oct 2024 14:07:16 +0100 -Subject: [PATCH 136/517] net: phy: realtek: read duplex and gbit master from - PHYSR register - -The PHYSR MMD register is present and defined equally for all RTL82xx -Ethernet PHYs. -Read duplex and Gbit master bits from rtlgen_decode_speed() and rename -it to rtlgen_decode_physr(). - -Signed-off-by: Daniel Golle -Link: https://patch.msgid.link/b9a76341da851a18c985bc4774fa295babec79bb.1728565530.git.daniel@makrotopia.org -Signed-off-by: Paolo Abeni ---- - drivers/net/phy/realtek.c | 41 +++++++++++++++++++++++++++++++-------- - 1 file changed, 33 insertions(+), 8 deletions(-) - -diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c -index 8ce5705af69c..f620cd7b17c8 100644 ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -80,15 +80,18 @@ - - #define RTL822X_VND2_GANLPAR 0xa414 - --#define RTL822X_VND2_PHYSR 0xa434 -- - #define RTL8366RB_POWER_SAVE 0x15 - #define RTL8366RB_POWER_SAVE_ON BIT(12) - - #define RTL9000A_GINMR 0x14 - #define RTL9000A_GINMR_LINK_STATUS BIT(4) - --#define RTLGEN_SPEED_MASK 0x0630 -+#define RTL_VND2_PHYSR 0xa434 -+#define RTL_VND2_PHYSR_DUPLEX BIT(3) -+#define RTL_VND2_PHYSR_SPEEDL GENMASK(5, 4) -+#define RTL_VND2_PHYSR_SPEEDH GENMASK(10, 9) -+#define RTL_VND2_PHYSR_MASTER BIT(11) -+#define RTL_VND2_PHYSR_SPEED_MASK (RTL_VND2_PHYSR_SPEEDL | RTL_VND2_PHYSR_SPEEDH) - - #define RTL_GENERIC_PHYID 0x001cc800 - #define RTL_8211FVD_PHYID 0x001cc878 -@@ -661,9 +664,18 @@ static int rtl8366rb_config_init(struct phy_device *phydev) - } - - /* get actual speed to cover the downshift case */ --static void rtlgen_decode_speed(struct phy_device *phydev, int val) -+static void rtlgen_decode_physr(struct phy_device *phydev, int val) - { -- switch (val & RTLGEN_SPEED_MASK) { -+ /* bit 3 -+ * 0: Half Duplex -+ * 1: Full Duplex -+ */ -+ if (val & RTL_VND2_PHYSR_DUPLEX) -+ phydev->duplex = DUPLEX_FULL; -+ else -+ phydev->duplex = DUPLEX_HALF; -+ -+ switch (val & RTL_VND2_PHYSR_SPEED_MASK) { - case 0x0000: - phydev->speed = SPEED_10; - break; -@@ -685,6 +697,19 @@ static void rtlgen_decode_speed(struct phy_device *phydev, int val) - default: - break; - } -+ -+ /* bit 11 -+ * 0: Slave Mode -+ * 1: Master Mode -+ */ -+ if (phydev->speed >= 1000) { -+ if (val & RTL_VND2_PHYSR_MASTER) -+ phydev->master_slave_state = MASTER_SLAVE_STATE_MASTER; -+ else -+ phydev->master_slave_state = MASTER_SLAVE_STATE_SLAVE; -+ } else { -+ phydev->master_slave_state = MASTER_SLAVE_STATE_UNSUPPORTED; -+ } - } - - static int rtlgen_read_status(struct phy_device *phydev) -@@ -702,7 +727,7 @@ static int rtlgen_read_status(struct phy_device *phydev) - if (val < 0) - return val; - -- rtlgen_decode_speed(phydev, val); -+ rtlgen_decode_physr(phydev, val); - - return 0; - } -@@ -1008,11 +1033,11 @@ static int rtl822x_c45_read_status(struct phy_device *phydev) - return 0; - - /* Read actual speed from vendor register. */ -- val = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_PHYSR); -+ val = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL_VND2_PHYSR); - if (val < 0) - return val; - -- rtlgen_decode_speed(phydev, val); -+ rtlgen_decode_physr(phydev, val); - - return 0; - } --- -2.51.0 - - -From 8044888966fcc83cca44c0ed9d74bfbc9b342d31 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 10 Oct 2024 14:07:26 +0100 -Subject: [PATCH 137/517] net: phy: realtek: change order of calls in C22 - read_status() - -Always call rtlgen_read_status() first, so genphy_read_status() which -is called by it clears bits in case auto-negotiation has not completed. -Also clear 10GBT link-partner advertisement bits in case auto-negotiation -is disabled or has not completed. - -Suggested-by: Russell King (Oracle) -Signed-off-by: Daniel Golle -Link: https://patch.msgid.link/b15929a41621d215c6b2b57393368086589569ec.1728565530.git.daniel@makrotopia.org -Signed-off-by: Paolo Abeni ---- - drivers/net/phy/realtek.c | 22 +++++++++++++++------- - 1 file changed, 15 insertions(+), 7 deletions(-) - -diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c -index f620cd7b17c8..c724ab0c4501 100644 ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -950,17 +950,25 @@ static void rtl822xb_update_interface(struct phy_device *phydev) - - static int rtl822x_read_status(struct phy_device *phydev) - { -- if (phydev->autoneg == AUTONEG_ENABLE) { -- int lpadv = phy_read_paged(phydev, 0xa5d, 0x13); -+ int lpadv, ret; - -- if (lpadv < 0) -- return lpadv; -+ ret = rtlgen_read_status(phydev); -+ if (ret < 0) -+ return ret; - -- mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, -- lpadv); -+ if (phydev->autoneg == AUTONEG_DISABLE || -+ !phydev->autoneg_complete) { -+ mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, 0); -+ return 0; - } - -- return rtlgen_read_status(phydev); -+ lpadv = phy_read_paged(phydev, 0xa5d, 0x13); -+ if (lpadv < 0) -+ return lpadv; -+ -+ mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, lpadv); -+ -+ return 0; - } - - static int rtl822xb_read_status(struct phy_device *phydev) --- -2.51.0 - - -From 12f9b03a9a0219fb6995129ff24d18858903e949 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 10 Oct 2024 14:07:39 +0100 -Subject: [PATCH 138/517] net: phy: realtek: clear 1000Base-T link partner - advertisement - -Clear 1000Base-T link partner advertisement bits in Clause-45 -read_status() function in case auto-negotiation is disabled or has not -been completed. - -Signed-off-by: Daniel Golle -Link: https://patch.msgid.link/9dc9b47b2d675708afef3ad366bfd78eb584d958.1728565530.git.daniel@makrotopia.org -Signed-off-by: Paolo Abeni ---- - drivers/net/phy/realtek.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c -index c724ab0c4501..f65d7f1f348e 100644 ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -1027,6 +1027,10 @@ static int rtl822x_c45_read_status(struct phy_device *phydev) - if (ret < 0) - return ret; - -+ if (phydev->autoneg == AUTONEG_DISABLE || -+ !genphy_c45_aneg_done(phydev)) -+ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, 0); -+ - /* Vendor register as C45 has no standardized support for 1000BaseT */ - if (phydev->autoneg == AUTONEG_ENABLE) { - val = phy_read_mmd(phydev, MDIO_MMD_VEND2, --- -2.51.0 - - -From af5aaa6a8e593cc32687a2d570336c20a446b23a Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Sat, 11 Jan 2025 21:49:31 +0100 -Subject: [PATCH 139/517] net: phy: realtek: add support for reading - MDIO_MMD_VEND2 regs on RTL8125/RTL8126 - -RTL8125/RTL8126 don't support MMD access to the internal PHY, but -provide a mechanism to access at least all MDIO_MMD_VEND2 registers. -By exposing this mechanism standard MMD access functions can be used -to access the MDIO_MMD_VEND2 registers. - -Signed-off-by: Heiner Kallweit -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/e821b302-5fe6-49ab-aabd-05da500581c0@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/realtek.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c -index f65d7f1f348e..af9874143f0c 100644 ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -736,7 +736,11 @@ static int rtlgen_read_mmd(struct phy_device *phydev, int devnum, u16 regnum) - { - int ret; - -- if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE) { -+ if (devnum == MDIO_MMD_VEND2) { -+ rtl821x_write_page(phydev, regnum >> 4); -+ ret = __phy_read(phydev, 0x10 + ((regnum & 0xf) >> 1)); -+ rtl821x_write_page(phydev, 0); -+ } else if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE) { - rtl821x_write_page(phydev, 0xa5c); - ret = __phy_read(phydev, 0x12); - rtl821x_write_page(phydev, 0); -@@ -760,7 +764,11 @@ static int rtlgen_write_mmd(struct phy_device *phydev, int devnum, u16 regnum, - { - int ret; - -- if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) { -+ if (devnum == MDIO_MMD_VEND2) { -+ rtl821x_write_page(phydev, regnum >> 4); -+ ret = __phy_write(phydev, 0x10 + ((regnum & 0xf) >> 1), val); -+ rtl821x_write_page(phydev, 0); -+ } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) { - rtl821x_write_page(phydev, 0xa5d); - ret = __phy_write(phydev, 0x10, val); - rtl821x_write_page(phydev, 0); --- -2.51.0 - - -From 99f16566ae0a8e2efe07c07dc3bdfa47c42563d0 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Wed, 15 Jan 2025 14:43:35 +0000 -Subject: [PATCH 140/517] net: phy: realtek: clear 1000Base-T lpa if link is - down - -Only read 1000Base-T link partner advertisement if autonegotiation has -completed and otherwise 1000Base-T link partner advertisement bits. - -This fixes bogus 1000Base-T link partner advertisement after link goes -down (eg. by disconnecting the wire). -Fixes: 5cb409b3960e ("net: phy: realtek: clear 1000Base-T link partner advertisement") -Signed-off-by: Daniel Golle -Reviewed-by: Michal Swiatkowski -Signed-off-by: David S. Miller ---- - drivers/net/phy/realtek.c | 19 ++++++++----------- - 1 file changed, 8 insertions(+), 11 deletions(-) - -diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c -index af9874143f0c..201c10f3718a 100644 ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -1031,23 +1031,20 @@ static int rtl822x_c45_read_status(struct phy_device *phydev) - { - int ret, val; - -- ret = genphy_c45_read_status(phydev); -- if (ret < 0) -- return ret; -- -- if (phydev->autoneg == AUTONEG_DISABLE || -- !genphy_c45_aneg_done(phydev)) -- mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, 0); -- - /* Vendor register as C45 has no standardized support for 1000BaseT */ -- if (phydev->autoneg == AUTONEG_ENABLE) { -+ if (phydev->autoneg == AUTONEG_ENABLE && genphy_c45_aneg_done(phydev)) { - val = phy_read_mmd(phydev, MDIO_MMD_VEND2, - RTL822X_VND2_GANLPAR); - if (val < 0) - return val; -- -- mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, val); -+ } else { -+ val = 0; - } -+ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, val); -+ -+ ret = genphy_c45_read_status(phydev); -+ if (ret < 0) -+ return ret; - - if (!phydev->link) - return 0; --- -2.51.0 - - -From 2020fe683da044996ed029f65c578d58f01b6a34 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Wed, 15 Jan 2025 14:43:43 +0000 -Subject: [PATCH 141/517] net: phy: realtek: clear master_slave_state if link - is down - -rtlgen_decode_physr() which sets master_slave_state isn't called in case -the link is down and other than rtlgen_read_status(), -rtl822x_c45_read_status() doesn't implicitely clear master_slave_state. - -Avoid stale master_slave_state by always setting it to -MASTER_SLAVE_STATE_UNKNOWN in rtl822x_c45_read_status() in case the link -is down. - -Fixes: 081c9c0265c9 ("net: phy: realtek: read duplex and gbit master from PHYSR register") -Signed-off-by: Daniel Golle -Reviewed-by: Michal Swiatkowski -Signed-off-by: David S. Miller ---- - drivers/net/phy/realtek.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c -index 201c10f3718a..138e608c4043 100644 ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -1046,8 +1046,10 @@ static int rtl822x_c45_read_status(struct phy_device *phydev) - if (ret < 0) - return ret; - -- if (!phydev->link) -+ if (!phydev->link) { -+ phydev->master_slave_state = MASTER_SLAVE_STATE_UNKNOWN; - return 0; -+ } - - /* Read actual speed from vendor register. */ - val = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL_VND2_PHYSR); --- -2.51.0 - - -From cb90466e609fa150db720a90f4a79a3b1c1899a2 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Wed, 15 Jan 2025 14:45:00 +0000 -Subject: [PATCH 142/517] net: phy: realtek: always clear NBase-T lpa - -Clear NBase-T link partner advertisement before calling -rtlgen_read_status() to avoid phy_resolve_aneg_linkmode() wrongly -setting speed and duplex. - -This fixes bogus 2.5G/5G/10G link partner advertisement and thus -speed and duplex being set by phy_resolve_aneg_linkmode() due to stale -NBase-T lpa. - -Fixes: 68d5cd09e891 ("net: phy: realtek: change order of calls in C22 read_status()") -Signed-off-by: Daniel Golle -Reviewed-by: Michal Swiatkowski -Signed-off-by: David S. Miller ---- - drivers/net/phy/realtek.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c -index 138e608c4043..44c7bdb88d76 100644 ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -960,15 +960,15 @@ static int rtl822x_read_status(struct phy_device *phydev) - { - int lpadv, ret; - -+ mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, 0); -+ - ret = rtlgen_read_status(phydev); - if (ret < 0) - return ret; - - if (phydev->autoneg == AUTONEG_DISABLE || -- !phydev->autoneg_complete) { -- mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, 0); -+ !phydev->autoneg_complete) - return 0; -- } - - lpadv = phy_read_paged(phydev, 0xa5d, 0x13); - if (lpadv < 0) --- -2.51.0 - - -From 4ea28dcb44149566275d2f6ef46787057043cdb2 Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Sat, 11 Jan 2025 21:50:19 +0100 -Subject: [PATCH 143/517] net: phy: move realtek PHY driver to its own - subdirectory - -In preparation of adding a source file with hwmon support, move the -Realtek PHY driver to its own subdirectory and rename realtek.c to -realtek_main.c. - -Signed-off-by: Heiner Kallweit -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/c566551b-c915-4e34-9b33-129a6ddd6e4c@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/Kconfig | 5 +---- - drivers/net/phy/Makefile | 2 +- - drivers/net/phy/realtek/Kconfig | 5 +++++ - drivers/net/phy/realtek/Makefile | 3 +++ - drivers/net/phy/{realtek.c => realtek/realtek_main.c} | 0 - 5 files changed, 10 insertions(+), 5 deletions(-) - create mode 100644 drivers/net/phy/realtek/Kconfig - create mode 100644 drivers/net/phy/realtek/Makefile - rename drivers/net/phy/{realtek.c => realtek/realtek_main.c} (100%) - -diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig -index 4e78a4d8fd2a..f7e21a2761b8 100644 ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -343,10 +343,7 @@ config QSEMI_PHY - help - Currently supports the qs6612 - --config REALTEK_PHY -- tristate "Realtek PHYs" -- help -- Supports the Realtek 821x PHY. -+source "drivers/net/phy/realtek/Kconfig" - - config RENESAS_PHY - tristate "Renesas PHYs" -diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile -index e6145153e837..a38b01f74db7 100644 ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -94,7 +94,7 @@ obj-$(CONFIG_NXP_CBTX_PHY) += nxp-cbtx.o - obj-$(CONFIG_NXP_TJA11XX_PHY) += nxp-tja11xx.o - obj-y += qcom/ - obj-$(CONFIG_QSEMI_PHY) += qsemi.o --obj-$(CONFIG_REALTEK_PHY) += realtek.o -+obj-$(CONFIG_REALTEK_PHY) += realtek/ - obj-$(CONFIG_RENESAS_PHY) += uPD60620.o - obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o - obj-$(CONFIG_SMSC_PHY) += smsc.o -diff --git a/drivers/net/phy/realtek/Kconfig b/drivers/net/phy/realtek/Kconfig -new file mode 100644 -index 000000000000..5b9e6e6db834 ---- /dev/null -+++ b/drivers/net/phy/realtek/Kconfig -@@ -0,0 +1,5 @@ -+# SPDX-License-Identifier: GPL-2.0-only -+config REALTEK_PHY -+ tristate "Realtek PHYs" -+ help -+ Currently supports RTL821x/RTL822x and fast ethernet PHYs -diff --git a/drivers/net/phy/realtek/Makefile b/drivers/net/phy/realtek/Makefile -new file mode 100644 -index 000000000000..996a80642431 ---- /dev/null -+++ b/drivers/net/phy/realtek/Makefile -@@ -0,0 +1,3 @@ -+# SPDX-License-Identifier: GPL-2.0 -+realtek-y += realtek_main.o -+obj-$(CONFIG_REALTEK_PHY) += realtek.o -diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek/realtek_main.c -similarity index 100% -rename from drivers/net/phy/realtek.c -rename to drivers/net/phy/realtek/realtek_main.c --- -2.51.0 - - -From 4dd3c0207f8b32828710d42d82ba2fa24497dcf4 Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Sat, 11 Jan 2025 21:51:24 +0100 -Subject: [PATCH 144/517] net: phy: realtek: add hwmon support for temp sensor - on RTL822x - -This adds hwmon support for the temperature sensor on RTL822x. -It's available on the standalone versions of the PHY's, and on -the integrated PHY's in RTL8125B/RTL8125D/RTL8126. - -Signed-off-by: Heiner Kallweit -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/ad6bfe9f-6375-4a00-84b4-bfb38a21bd71@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/realtek/Kconfig | 6 ++ - drivers/net/phy/realtek/Makefile | 1 + - drivers/net/phy/realtek/realtek.h | 10 ++++ - drivers/net/phy/realtek/realtek_hwmon.c | 79 +++++++++++++++++++++++++ - drivers/net/phy/realtek/realtek_main.c | 12 ++++ - 5 files changed, 108 insertions(+) - create mode 100644 drivers/net/phy/realtek/realtek.h - create mode 100644 drivers/net/phy/realtek/realtek_hwmon.c - -diff --git a/drivers/net/phy/realtek/Kconfig b/drivers/net/phy/realtek/Kconfig -index 5b9e6e6db834..31935f147d87 100644 ---- a/drivers/net/phy/realtek/Kconfig -+++ b/drivers/net/phy/realtek/Kconfig -@@ -3,3 +3,9 @@ config REALTEK_PHY - tristate "Realtek PHYs" - help - Currently supports RTL821x/RTL822x and fast ethernet PHYs -+ -+config REALTEK_PHY_HWMON -+ def_bool REALTEK_PHY && HWMON -+ depends on !(REALTEK_PHY=y && HWMON=m) -+ help -+ Optional hwmon support for the temperature sensor -diff --git a/drivers/net/phy/realtek/Makefile b/drivers/net/phy/realtek/Makefile -index 996a80642431..dd21cf87f2f1 100644 ---- a/drivers/net/phy/realtek/Makefile -+++ b/drivers/net/phy/realtek/Makefile -@@ -1,3 +1,4 @@ - # SPDX-License-Identifier: GPL-2.0 - realtek-y += realtek_main.o -+realtek-$(CONFIG_REALTEK_PHY_HWMON) += realtek_hwmon.o - obj-$(CONFIG_REALTEK_PHY) += realtek.o -diff --git a/drivers/net/phy/realtek/realtek.h b/drivers/net/phy/realtek/realtek.h -new file mode 100644 -index 000000000000..a39b44fa18a0 ---- /dev/null -+++ b/drivers/net/phy/realtek/realtek.h -@@ -0,0 +1,10 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+ -+#ifndef REALTEK_H -+#define REALTEK_H -+ -+#include -+ -+int rtl822x_hwmon_init(struct phy_device *phydev); -+ -+#endif /* REALTEK_H */ -diff --git a/drivers/net/phy/realtek/realtek_hwmon.c b/drivers/net/phy/realtek/realtek_hwmon.c -new file mode 100644 -index 000000000000..1ecb410bb941 ---- /dev/null -+++ b/drivers/net/phy/realtek/realtek_hwmon.c -@@ -0,0 +1,79 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * HWMON support for Realtek PHY's -+ * -+ * Author: Heiner Kallweit -+ */ -+ -+#include -+#include -+ -+#include "realtek.h" -+ -+#define RTL822X_VND2_TSALRM 0xa662 -+#define RTL822X_VND2_TSRR 0xbd84 -+#define RTL822X_VND2_TSSR 0xb54c -+ -+static int rtl822x_hwmon_get_temp(int raw) -+{ -+ if (raw >= 512) -+ raw -= 1024; -+ -+ return 1000 * raw / 2; -+} -+ -+static int rtl822x_hwmon_read(struct device *dev, enum hwmon_sensor_types type, -+ u32 attr, int channel, long *val) -+{ -+ struct phy_device *phydev = dev_get_drvdata(dev); -+ int raw; -+ -+ switch (attr) { -+ case hwmon_temp_input: -+ raw = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_TSRR) & 0x3ff; -+ *val = rtl822x_hwmon_get_temp(raw); -+ break; -+ case hwmon_temp_max: -+ /* Chip reduces speed to 1G if threshold is exceeded */ -+ raw = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_TSSR) >> 6; -+ *val = rtl822x_hwmon_get_temp(raw); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static const struct hwmon_ops rtl822x_hwmon_ops = { -+ .visible = 0444, -+ .read = rtl822x_hwmon_read, -+}; -+ -+static const struct hwmon_channel_info * const rtl822x_hwmon_info[] = { -+ HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_MAX), -+ NULL -+}; -+ -+static const struct hwmon_chip_info rtl822x_hwmon_chip_info = { -+ .ops = &rtl822x_hwmon_ops, -+ .info = rtl822x_hwmon_info, -+}; -+ -+int rtl822x_hwmon_init(struct phy_device *phydev) -+{ -+ struct device *hwdev, *dev = &phydev->mdio.dev; -+ const char *name; -+ -+ /* Ensure over-temp alarm is reset. */ -+ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_TSALRM, 3); -+ -+ name = devm_hwmon_sanitize_name(dev, dev_name(dev)); -+ if (IS_ERR(name)) -+ return PTR_ERR(name); -+ -+ hwdev = devm_hwmon_device_register_with_info(dev, name, phydev, -+ &rtl822x_hwmon_chip_info, -+ NULL); -+ return PTR_ERR_OR_ZERO(hwdev); -+} -diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index 44c7bdb88d76..1eaa66a613a1 100644 ---- a/drivers/net/phy/realtek/realtek_main.c -+++ b/drivers/net/phy/realtek/realtek_main.c -@@ -14,6 +14,8 @@ - #include - #include - -+#include "realtek.h" -+ - #define RTL821x_PHYSR 0x11 - #define RTL821x_PHYSR_DUPLEX BIT(13) - #define RTL821x_PHYSR_SPEED GENMASK(15, 14) -@@ -820,6 +822,15 @@ static int rtl822x_write_mmd(struct phy_device *phydev, int devnum, u16 regnum, - return ret; - } - -+static int rtl822x_probe(struct phy_device *phydev) -+{ -+ if (IS_ENABLED(CONFIG_REALTEK_PHY_HWMON) && -+ phydev->phy_id != RTL_GENERIC_PHYID) -+ return rtl822x_hwmon_init(phydev); -+ -+ return 0; -+} -+ - static int rtl822xb_config_init(struct phy_device *phydev) - { - bool has_2500, has_sgmii; -@@ -1518,6 +1529,7 @@ static struct phy_driver realtek_drvs[] = { - .match_phy_device = rtl_internal_nbaset_match_phy_device, - .name = "Realtek Internal NBASE-T PHY", - .flags = PHY_IS_INTERNAL, -+ .probe = rtl822x_probe, - .get_features = rtl822x_get_features, - .config_aneg = rtl822x_config_aneg, - .read_status = rtl822x_read_status, --- -2.51.0 - - -From 9d206755298602fa6e1ac888d793a898b6e3c27c Mon Sep 17 00:00:00 2001 -From: Aleksander Jan Bajkowski -Date: Fri, 17 Jan 2025 23:24:21 +0100 -Subject: [PATCH 145/517] net: phy: realtek: HWMON support for standalone - versions of RTL8221B and RTL8251 - -HWMON support has been added for the RTL8221/8251 PHYs integrated together -with the MAC inside the RTL8125/8126 chips. This patch extends temperature -reading support for standalone variants of the mentioned PHYs. - -I don't know whether the earlier revisions of the RTL8226 also have a -built-in temperature sensor, so they have been skipped for now. - -Tested on RTL8221B-VB-CG. - -Signed-off-by: Aleksander Jan Bajkowski -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/realtek/realtek_main.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index 1eaa66a613a1..572a933636b0 100644 ---- a/drivers/net/phy/realtek/realtek_main.c -+++ b/drivers/net/phy/realtek/realtek_main.c -@@ -1474,6 +1474,7 @@ static struct phy_driver realtek_drvs[] = { - }, { - .match_phy_device = rtl8221b_vb_cg_c22_match_phy_device, - .name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)", -+ .probe = rtl822x_probe, - .get_features = rtl822x_get_features, - .config_aneg = rtl822x_config_aneg, - .config_init = rtl822xb_config_init, -@@ -1486,6 +1487,7 @@ static struct phy_driver realtek_drvs[] = { - }, { - .match_phy_device = rtl8221b_vb_cg_c45_match_phy_device, - .name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)", -+ .probe = rtl822x_probe, - .config_init = rtl822xb_config_init, - .get_rate_matching = rtl822xb_get_rate_matching, - .get_features = rtl822x_c45_get_features, -@@ -1496,6 +1498,7 @@ static struct phy_driver realtek_drvs[] = { - }, { - .match_phy_device = rtl8221b_vn_cg_c22_match_phy_device, - .name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)", -+ .probe = rtl822x_probe, - .get_features = rtl822x_get_features, - .config_aneg = rtl822x_config_aneg, - .config_init = rtl822xb_config_init, -@@ -1508,6 +1511,7 @@ static struct phy_driver realtek_drvs[] = { - }, { - .match_phy_device = rtl8221b_vn_cg_c45_match_phy_device, - .name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)", -+ .probe = rtl822x_probe, - .config_init = rtl822xb_config_init, - .get_rate_matching = rtl822xb_get_rate_matching, - .get_features = rtl822x_c45_get_features, -@@ -1518,6 +1522,7 @@ static struct phy_driver realtek_drvs[] = { - }, { - .match_phy_device = rtl8251b_c45_match_phy_device, - .name = "RTL8251B 5Gbps PHY", -+ .probe = rtl822x_probe, - .get_features = rtl822x_get_features, - .config_aneg = rtl822x_config_aneg, - .read_status = rtl822x_read_status, --- -2.51.0 - - -From df5a2f57e71d7ecb6eb08c4f26f7fbc216d44c73 Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Mon, 3 Feb 2025 21:33:39 +0100 -Subject: [PATCH 146/517] net: phy: realtek: make HWMON support a user-visible - Kconfig symbol - -Make config symbol REALTEK_PHY_HWMON user-visible, so that users can -remove support if not needed. - -Suggested-by: Geert Uytterhoeven -Signed-off-by: Heiner Kallweit -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/3466ee92-166a-4b0f-9ae7-42b9e046f333@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/realtek/Kconfig | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/phy/realtek/Kconfig b/drivers/net/phy/realtek/Kconfig -index 31935f147d87..b05c2a1e9024 100644 ---- a/drivers/net/phy/realtek/Kconfig -+++ b/drivers/net/phy/realtek/Kconfig -@@ -4,8 +4,12 @@ config REALTEK_PHY - help - Currently supports RTL821x/RTL822x and fast ethernet PHYs - -+if REALTEK_PHY -+ - config REALTEK_PHY_HWMON -- def_bool REALTEK_PHY && HWMON -- depends on !(REALTEK_PHY=y && HWMON=m) -+ bool "HWMON support for Realtek PHYs" -+ depends on HWMON && !(REALTEK_PHY=y && HWMON=m) - help - Optional hwmon support for the temperature sensor -+ -+endif # REALTEK_PHY --- -2.51.0 - - -From 24028387bf45cc84b5c1eeb792b2466b8edf4564 Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Mon, 3 Feb 2025 21:41:36 +0100 -Subject: [PATCH 147/517] net: phy: realtek: use string choices helpers - -Use string choices helpers to simplify the code. - -Reported-by: kernel test robot -Closes: https://lore.kernel.org/oe-kbuild-all/202501190707.qQS8PGHW-lkp@intel.com/ -Signed-off-by: Heiner Kallweit -Reviewed-by: Simon Horman -Signed-off-by: David S. Miller ---- - drivers/net/phy/realtek/realtek_main.c | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index 572a933636b0..210fefac44d4 100644 ---- a/drivers/net/phy/realtek/realtek_main.c -+++ b/drivers/net/phy/realtek/realtek_main.c -@@ -13,6 +13,7 @@ - #include - #include - #include -+#include - - #include "realtek.h" - -@@ -422,11 +423,11 @@ static int rtl8211f_config_init(struct phy_device *phydev) - } else if (ret) { - dev_dbg(dev, - "%s 2ns TX delay (and changing the value from pin-strapping RXD1 or the bootloader)\n", -- val_txdly ? "Enabling" : "Disabling"); -+ str_enable_disable(val_txdly)); - } else { - dev_dbg(dev, - "2ns TX delay was already %s (by pin-strapping RXD1 or bootloader configuration)\n", -- val_txdly ? "enabled" : "disabled"); -+ str_enabled_disabled(val_txdly)); - } - - ret = phy_modify_paged_changed(phydev, 0xd08, 0x15, RTL8211F_RX_DELAY, -@@ -437,11 +438,11 @@ static int rtl8211f_config_init(struct phy_device *phydev) - } else if (ret) { - dev_dbg(dev, - "%s 2ns RX delay (and changing the value from pin-strapping RXD0 or the bootloader)\n", -- val_rxdly ? "Enabling" : "Disabling"); -+ str_enable_disable(val_rxdly)); - } else { - dev_dbg(dev, - "2ns RX delay was already %s (by pin-strapping RXD0 or bootloader configuration)\n", -- val_rxdly ? "enabled" : "disabled"); -+ str_enabled_disabled(val_rxdly)); - } - - if (priv->has_phycr2) { --- -2.51.0 - - -From c7696aeb0135b79aa1648db6b358c5ab33ffd849 Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Thu, 13 Feb 2025 20:18:17 +0100 -Subject: [PATCH 148/517] net: phy: realtek: improve mmd register access for - internal PHY's - -r8169 provides the MDIO bus for the internal PHY's. It has been extended -with c45 access functions for addressing MDIO_MMD_VEND2 registers. -So we can switch from paged access to directly addressing the -MDIO_MMD_VEND2 registers. - -Signed-off-by: Heiner Kallweit -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/a5f2333c-dda9-48ad-9801-77049766e632@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/realtek/realtek_main.c | 79 +++++++++++--------------- - 1 file changed, 33 insertions(+), 46 deletions(-) - -diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index 210fefac44d4..2e2c5353c5af 100644 ---- a/drivers/net/phy/realtek/realtek_main.c -+++ b/drivers/net/phy/realtek/realtek_main.c -@@ -735,29 +735,31 @@ static int rtlgen_read_status(struct phy_device *phydev) - return 0; - } - -+static int rtlgen_read_vend2(struct phy_device *phydev, int regnum) -+{ -+ return __mdiobus_c45_read(phydev->mdio.bus, 0, MDIO_MMD_VEND2, regnum); -+} -+ -+static int rtlgen_write_vend2(struct phy_device *phydev, int regnum, u16 val) -+{ -+ return __mdiobus_c45_write(phydev->mdio.bus, 0, MDIO_MMD_VEND2, regnum, -+ val); -+} -+ - static int rtlgen_read_mmd(struct phy_device *phydev, int devnum, u16 regnum) - { - int ret; - -- if (devnum == MDIO_MMD_VEND2) { -- rtl821x_write_page(phydev, regnum >> 4); -- ret = __phy_read(phydev, 0x10 + ((regnum & 0xf) >> 1)); -- rtl821x_write_page(phydev, 0); -- } else if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE) { -- rtl821x_write_page(phydev, 0xa5c); -- ret = __phy_read(phydev, 0x12); -- rtl821x_write_page(phydev, 0); -- } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) { -- rtl821x_write_page(phydev, 0xa5d); -- ret = __phy_read(phydev, 0x10); -- rtl821x_write_page(phydev, 0); -- } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE) { -- rtl821x_write_page(phydev, 0xa5d); -- ret = __phy_read(phydev, 0x11); -- rtl821x_write_page(phydev, 0); -- } else { -+ if (devnum == MDIO_MMD_VEND2) -+ ret = rtlgen_read_vend2(phydev, regnum); -+ else if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE) -+ ret = rtlgen_read_vend2(phydev, 0xa5c4); -+ else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) -+ ret = rtlgen_read_vend2(phydev, 0xa5d0); -+ else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE) -+ ret = rtlgen_read_vend2(phydev, 0xa5d2); -+ else - ret = -EOPNOTSUPP; -- } - - return ret; - } -@@ -767,17 +769,12 @@ static int rtlgen_write_mmd(struct phy_device *phydev, int devnum, u16 regnum, - { - int ret; - -- if (devnum == MDIO_MMD_VEND2) { -- rtl821x_write_page(phydev, regnum >> 4); -- ret = __phy_write(phydev, 0x10 + ((regnum & 0xf) >> 1), val); -- rtl821x_write_page(phydev, 0); -- } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) { -- rtl821x_write_page(phydev, 0xa5d); -- ret = __phy_write(phydev, 0x10, val); -- rtl821x_write_page(phydev, 0); -- } else { -+ if (devnum == MDIO_MMD_VEND2) -+ ret = rtlgen_write_vend2(phydev, regnum, val); -+ else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) -+ ret = rtlgen_write_vend2(phydev, regnum, 0xa5d0); -+ else - ret = -EOPNOTSUPP; -- } - - return ret; - } -@@ -789,19 +786,12 @@ static int rtl822x_read_mmd(struct phy_device *phydev, int devnum, u16 regnum) - if (ret != -EOPNOTSUPP) - return ret; - -- if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE2) { -- rtl821x_write_page(phydev, 0xa6e); -- ret = __phy_read(phydev, 0x16); -- rtl821x_write_page(phydev, 0); -- } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV2) { -- rtl821x_write_page(phydev, 0xa6d); -- ret = __phy_read(phydev, 0x12); -- rtl821x_write_page(phydev, 0); -- } else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE2) { -- rtl821x_write_page(phydev, 0xa6d); -- ret = __phy_read(phydev, 0x10); -- rtl821x_write_page(phydev, 0); -- } -+ if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE2) -+ ret = rtlgen_read_vend2(phydev, 0xa6ec); -+ else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV2) -+ ret = rtlgen_read_vend2(phydev, 0xa6d4); -+ else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE2) -+ ret = rtlgen_read_vend2(phydev, 0xa6d0); - - return ret; - } -@@ -814,11 +804,8 @@ static int rtl822x_write_mmd(struct phy_device *phydev, int devnum, u16 regnum, - if (ret != -EOPNOTSUPP) - return ret; - -- if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV2) { -- rtl821x_write_page(phydev, 0xa6d); -- ret = __phy_write(phydev, 0x12, val); -- rtl821x_write_page(phydev, 0); -- } -+ if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV2) -+ ret = rtlgen_write_vend2(phydev, 0xa6d4, val); - - return ret; - } --- -2.51.0 - - -From 0a937df4d8245909b4d8777209ee0dfb07340350 Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Thu, 13 Feb 2025 20:19:14 +0100 -Subject: [PATCH 149/517] net: phy: realtek: switch from paged to MMD ops in - rtl822x functions - -The MDIO bus provided by r8169 for the internal PHY's now supports -c45 ops for the MDIO_MMD_VEND2 device. So we can switch to standard -MMD ops here. - -Signed-off-by: Heiner Kallweit -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/81416f95-0fac-4225-87b4-828e3738b8ed@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/realtek/realtek_main.c | 11 +++++------ - 1 file changed, 5 insertions(+), 6 deletions(-) - -diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index 2e2c5353c5af..34be1d752ef8 100644 ---- a/drivers/net/phy/realtek/realtek_main.c -+++ b/drivers/net/phy/realtek/realtek_main.c -@@ -901,7 +901,7 @@ static int rtl822x_get_features(struct phy_device *phydev) - { - int val; - -- val = phy_read_paged(phydev, 0xa61, 0x13); -+ val = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xa616); - if (val < 0) - return val; - -@@ -922,10 +922,9 @@ static int rtl822x_config_aneg(struct phy_device *phydev) - if (phydev->autoneg == AUTONEG_ENABLE) { - u16 adv = linkmode_adv_to_mii_10gbt_adv_t(phydev->advertising); - -- ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12, -- MDIO_AN_10GBT_CTRL_ADV2_5G | -- MDIO_AN_10GBT_CTRL_ADV5G, -- adv); -+ ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND2, 0xa5d4, -+ MDIO_AN_10GBT_CTRL_ADV2_5G | -+ MDIO_AN_10GBT_CTRL_ADV5G, adv); - if (ret < 0) - return ret; - } -@@ -969,7 +968,7 @@ static int rtl822x_read_status(struct phy_device *phydev) - !phydev->autoneg_complete) - return 0; - -- lpadv = phy_read_paged(phydev, 0xa5d, 0x13); -+ lpadv = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xa5d6); - if (lpadv < 0) - return lpadv; - --- -2.51.0 - - -From a30ba9540ea58da2d711e0ec47a05fdabcdf04fe Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Fri, 14 Feb 2025 21:31:14 +0100 -Subject: [PATCH 150/517] net: phy: realtek: add helper RTL822X_VND2_C22_REG - -C22 register space is mapped to 0xa400 in MMD VEND2 register space. -Add a helper to access mapped C22 registers. - -Signed-off-by: Heiner Kallweit -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/6344277b-c5c7-449b-ac89-d5425306ca76@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/realtek/realtek_main.c | 9 ++++----- - 1 file changed, 4 insertions(+), 5 deletions(-) - -diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index 34be1d752ef8..b877057348d5 100644 ---- a/drivers/net/phy/realtek/realtek_main.c -+++ b/drivers/net/phy/realtek/realtek_main.c -@@ -79,9 +79,7 @@ - /* RTL822X_VND2_XXXXX registers are only accessible when phydev->is_c45 - * is set, they cannot be accessed by C45-over-C22. - */ --#define RTL822X_VND2_GBCR 0xa412 -- --#define RTL822X_VND2_GANLPAR 0xa414 -+#define RTL822X_VND2_C22_REG(reg) (0xa400 + 2 * (reg)) - - #define RTL8366RB_POWER_SAVE 0x15 - #define RTL8366RB_POWER_SAVE_ON BIT(12) -@@ -1015,7 +1013,8 @@ static int rtl822x_c45_config_aneg(struct phy_device *phydev) - val = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising); - - /* Vendor register as C45 has no standardized support for 1000BaseT */ -- ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND2, RTL822X_VND2_GBCR, -+ ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND2, -+ RTL822X_VND2_C22_REG(MII_CTRL1000), - ADVERTISE_1000FULL, val); - if (ret < 0) - return ret; -@@ -1032,7 +1031,7 @@ static int rtl822x_c45_read_status(struct phy_device *phydev) - /* Vendor register as C45 has no standardized support for 1000BaseT */ - if (phydev->autoneg == AUTONEG_ENABLE && genphy_c45_aneg_done(phydev)) { - val = phy_read_mmd(phydev, MDIO_MMD_VEND2, -- RTL822X_VND2_GANLPAR); -+ RTL822X_VND2_C22_REG(MII_STAT1000)); - if (val < 0) - return val; - } else { --- -2.51.0 - - -From 10dc716faf022f4c1e733b7cc7730effb0387309 Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Sat, 15 Feb 2025 14:29:15 +0100 -Subject: [PATCH 151/517] net: phy: realtek: add defines for shadowed c45 - standard registers - -Realtek shadows standard c45 registers in VEND2 device register space. -Add defines for these VEND2 registers, based on the names of the -standard c45 registers. - -Signed-off-by: Heiner Kallweit -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/c90bdf76-f8b8-4d06-9656-7a52d5658ee6@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/realtek/realtek_main.c | 33 +++++++++++++++++--------- - 1 file changed, 22 insertions(+), 11 deletions(-) - -diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index b877057348d5..7a0b19d66aca 100644 ---- a/drivers/net/phy/realtek/realtek_main.c -+++ b/drivers/net/phy/realtek/realtek_main.c -@@ -94,6 +94,16 @@ - #define RTL_VND2_PHYSR_MASTER BIT(11) - #define RTL_VND2_PHYSR_SPEED_MASK (RTL_VND2_PHYSR_SPEEDL | RTL_VND2_PHYSR_SPEEDH) - -+#define RTL_MDIO_PCS_EEE_ABLE 0xa5c4 -+#define RTL_MDIO_AN_EEE_ADV 0xa5d0 -+#define RTL_MDIO_AN_EEE_LPABLE 0xa5d2 -+#define RTL_MDIO_AN_10GBT_CTRL 0xa5d4 -+#define RTL_MDIO_AN_10GBT_STAT 0xa5d6 -+#define RTL_MDIO_PMA_SPEED 0xa616 -+#define RTL_MDIO_AN_EEE_LPABLE2 0xa6d0 -+#define RTL_MDIO_AN_EEE_ADV2 0xa6d4 -+#define RTL_MDIO_PCS_EEE_ABLE2 0xa6ec -+ - #define RTL_GENERIC_PHYID 0x001cc800 - #define RTL_8211FVD_PHYID 0x001cc878 - #define RTL_8221B 0x001cc840 -@@ -751,11 +761,11 @@ static int rtlgen_read_mmd(struct phy_device *phydev, int devnum, u16 regnum) - if (devnum == MDIO_MMD_VEND2) - ret = rtlgen_read_vend2(phydev, regnum); - else if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE) -- ret = rtlgen_read_vend2(phydev, 0xa5c4); -+ ret = rtlgen_read_vend2(phydev, RTL_MDIO_PCS_EEE_ABLE); - else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) -- ret = rtlgen_read_vend2(phydev, 0xa5d0); -+ ret = rtlgen_read_vend2(phydev, RTL_MDIO_AN_EEE_ADV); - else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE) -- ret = rtlgen_read_vend2(phydev, 0xa5d2); -+ ret = rtlgen_read_vend2(phydev, RTL_MDIO_AN_EEE_LPABLE); - else - ret = -EOPNOTSUPP; - -@@ -770,7 +780,7 @@ static int rtlgen_write_mmd(struct phy_device *phydev, int devnum, u16 regnum, - if (devnum == MDIO_MMD_VEND2) - ret = rtlgen_write_vend2(phydev, regnum, val); - else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) -- ret = rtlgen_write_vend2(phydev, regnum, 0xa5d0); -+ ret = rtlgen_write_vend2(phydev, regnum, RTL_MDIO_AN_EEE_ADV); - else - ret = -EOPNOTSUPP; - -@@ -785,11 +795,11 @@ static int rtl822x_read_mmd(struct phy_device *phydev, int devnum, u16 regnum) - return ret; - - if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE2) -- ret = rtlgen_read_vend2(phydev, 0xa6ec); -+ ret = rtlgen_read_vend2(phydev, RTL_MDIO_PCS_EEE_ABLE2); - else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV2) -- ret = rtlgen_read_vend2(phydev, 0xa6d4); -+ ret = rtlgen_read_vend2(phydev, RTL_MDIO_AN_EEE_ADV2); - else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_LPABLE2) -- ret = rtlgen_read_vend2(phydev, 0xa6d0); -+ ret = rtlgen_read_vend2(phydev, RTL_MDIO_AN_EEE_LPABLE2); - - return ret; - } -@@ -803,7 +813,7 @@ static int rtl822x_write_mmd(struct phy_device *phydev, int devnum, u16 regnum, - return ret; - - if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV2) -- ret = rtlgen_write_vend2(phydev, 0xa6d4, val); -+ ret = rtlgen_write_vend2(phydev, RTL_MDIO_AN_EEE_ADV2, val); - - return ret; - } -@@ -899,7 +909,7 @@ static int rtl822x_get_features(struct phy_device *phydev) - { - int val; - -- val = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xa616); -+ val = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL_MDIO_PMA_SPEED); - if (val < 0) - return val; - -@@ -920,7 +930,8 @@ static int rtl822x_config_aneg(struct phy_device *phydev) - if (phydev->autoneg == AUTONEG_ENABLE) { - u16 adv = linkmode_adv_to_mii_10gbt_adv_t(phydev->advertising); - -- ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND2, 0xa5d4, -+ ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND2, -+ RTL_MDIO_AN_10GBT_CTRL, - MDIO_AN_10GBT_CTRL_ADV2_5G | - MDIO_AN_10GBT_CTRL_ADV5G, adv); - if (ret < 0) -@@ -966,7 +977,7 @@ static int rtl822x_read_status(struct phy_device *phydev) - !phydev->autoneg_complete) - return 0; - -- lpadv = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xa5d6); -+ lpadv = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL_MDIO_AN_10GBT_STAT); - if (lpadv < 0) - return lpadv; - --- -2.51.0 - - -From 0f352608b9659c2a38aaae383a9dfb7198c92550 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Sun, 16 Mar 2025 12:39:54 +0000 -Subject: [PATCH 152/517] net: phy: realtek: disable PHY-mode EEE - -Realtek RTL8211F has a "PHY-mode" EEE support which interferes with an -IEEE 802.3 compliant implementation. This mode defaults to enabled, and -results in the MAC receive path not seeing the link transition to LPI -state. - -Fix this by disabling PHY-mode EEE. - -Signed-off-by: Russell King (Oracle) -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/E1ttnHW-00785s-Uq@rmk-PC.armlinux.org.uk -Signed-off-by: Paolo Abeni ---- - drivers/net/phy/realtek/realtek_main.c | 11 +++++++++-- - 1 file changed, 9 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index 7a0b19d66aca..893c82479671 100644 ---- a/drivers/net/phy/realtek/realtek_main.c -+++ b/drivers/net/phy/realtek/realtek_main.c -@@ -33,6 +33,9 @@ - - #define RTL8211F_PHYCR1 0x18 - #define RTL8211F_PHYCR2 0x19 -+#define RTL8211F_CLKOUT_EN BIT(0) -+#define RTL8211F_PHYCR2_PHY_EEE_ENABLE BIT(5) -+ - #define RTL8211F_INSR 0x1d - - #define RTL8211F_LEDCR 0x10 -@@ -55,8 +58,6 @@ - #define RTL8211E_TX_DELAY BIT(12) - #define RTL8211E_RX_DELAY BIT(11) - --#define RTL8211F_CLKOUT_EN BIT(0) -- - #define RTL8201F_ISR 0x1e - #define RTL8201F_ISR_ANERR BIT(15) - #define RTL8201F_ISR_DUPLEX BIT(13) -@@ -453,6 +454,12 @@ static int rtl8211f_config_init(struct phy_device *phydev) - str_enabled_disabled(val_rxdly)); - } - -+ /* Disable PHY-mode EEE so LPI is passed to the MAC */ -+ ret = phy_modify_paged(phydev, 0xa43, RTL8211F_PHYCR2, -+ RTL8211F_PHYCR2_PHY_EEE_ENABLE, 0); -+ if (ret) -+ return ret; -+ - if (priv->has_phycr2) { - ret = phy_modify_paged(phydev, 0xa43, RTL8211F_PHYCR2, - RTL8211F_CLKOUT_EN, priv->phycr2); --- -2.51.0 - - -From 94a3d70ce477f33f92c9a49223563adc2382a80b Mon Sep 17 00:00:00 2001 -From: Daniel Braunwarth -Date: Tue, 29 Apr 2025 13:33:37 +0200 -Subject: [PATCH 153/517] net: phy: realtek: Add support for WOL magic packet - on RTL8211F - -The RTL8211F supports multiple WOL modes. This patch adds support for -magic packets. - -The PHY notifies the system via the INTB/PMEB pin when a WOL event -occurs. - -Signed-off-by: Daniel Braunwarth -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/20250429-realtek_wol-v2-1-8f84def1ef2c@kuka.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/realtek/realtek_main.c | 69 ++++++++++++++++++++++++++ - 1 file changed, 69 insertions(+) - -diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index 893c82479671..05c4f4d394a5 100644 ---- a/drivers/net/phy/realtek/realtek_main.c -+++ b/drivers/net/phy/realtek/realtek_main.c -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -38,6 +39,24 @@ - - #define RTL8211F_INSR 0x1d - -+/* RTL8211F WOL interrupt configuration */ -+#define RTL8211F_INTBCR_PAGE 0xd40 -+#define RTL8211F_INTBCR 0x16 -+#define RTL8211F_INTBCR_INTB_PMEB BIT(5) -+ -+/* RTL8211F WOL settings */ -+#define RTL8211F_WOL_SETTINGS_PAGE 0xd8a -+#define RTL8211F_WOL_SETTINGS_EVENTS 16 -+#define RTL8211F_WOL_EVENT_MAGIC BIT(12) -+#define RTL8211F_WOL_SETTINGS_STATUS 17 -+#define RTL8211F_WOL_STATUS_RESET (BIT(15) | 0x1fff) -+ -+/* RTL8211F Unique phyiscal and multicast address (WOL) */ -+#define RTL8211F_PHYSICAL_ADDR_PAGE 0xd8c -+#define RTL8211F_PHYSICAL_ADDR_WORD0 16 -+#define RTL8211F_PHYSICAL_ADDR_WORD1 17 -+#define RTL8211F_PHYSICAL_ADDR_WORD2 18 -+ - #define RTL8211F_LEDCR 0x10 - #define RTL8211F_LEDCR_MODE BIT(15) - #define RTL8211F_LEDCR_ACT_TXRX BIT(4) -@@ -123,6 +142,7 @@ struct rtl821x_priv { - u16 phycr2; - bool has_phycr2; - struct clk *clk; -+ u32 saved_wolopts; - }; - - static int rtl821x_read_page(struct phy_device *phydev) -@@ -354,6 +374,53 @@ static irqreturn_t rtl8211f_handle_interrupt(struct phy_device *phydev) - return IRQ_HANDLED; - } - -+static void rtl8211f_get_wol(struct phy_device *dev, struct ethtool_wolinfo *wol) -+{ -+ wol->supported = WAKE_MAGIC; -+ if (phy_read_paged(dev, RTL8211F_WOL_SETTINGS_PAGE, RTL8211F_WOL_SETTINGS_EVENTS) -+ & RTL8211F_WOL_EVENT_MAGIC) -+ wol->wolopts = WAKE_MAGIC; -+} -+ -+static int rtl8211f_set_wol(struct phy_device *dev, struct ethtool_wolinfo *wol) -+{ -+ const u8 *mac_addr = dev->attached_dev->dev_addr; -+ int oldpage; -+ -+ oldpage = phy_save_page(dev); -+ if (oldpage < 0) -+ goto err; -+ -+ if (wol->wolopts & WAKE_MAGIC) { -+ /* Store the device address for the magic packet */ -+ rtl821x_write_page(dev, RTL8211F_PHYSICAL_ADDR_PAGE); -+ __phy_write(dev, RTL8211F_PHYSICAL_ADDR_WORD0, mac_addr[1] << 8 | (mac_addr[0])); -+ __phy_write(dev, RTL8211F_PHYSICAL_ADDR_WORD1, mac_addr[3] << 8 | (mac_addr[2])); -+ __phy_write(dev, RTL8211F_PHYSICAL_ADDR_WORD2, mac_addr[5] << 8 | (mac_addr[4])); -+ -+ /* Enable magic packet matching and reset WOL status */ -+ rtl821x_write_page(dev, RTL8211F_WOL_SETTINGS_PAGE); -+ __phy_write(dev, RTL8211F_WOL_SETTINGS_EVENTS, RTL8211F_WOL_EVENT_MAGIC); -+ __phy_write(dev, RTL8211F_WOL_SETTINGS_STATUS, RTL8211F_WOL_STATUS_RESET); -+ -+ /* Enable the WOL interrupt */ -+ rtl821x_write_page(dev, RTL8211F_INTBCR_PAGE); -+ __phy_set_bits(dev, RTL8211F_INTBCR, RTL8211F_INTBCR_INTB_PMEB); -+ } else { -+ /* Disable the WOL interrupt */ -+ rtl821x_write_page(dev, RTL8211F_INTBCR_PAGE); -+ __phy_clear_bits(dev, RTL8211F_INTBCR, RTL8211F_INTBCR_INTB_PMEB); -+ -+ /* Disable magic packet matching and reset WOL status */ -+ rtl821x_write_page(dev, RTL8211F_WOL_SETTINGS_PAGE); -+ __phy_write(dev, RTL8211F_WOL_SETTINGS_EVENTS, 0); -+ __phy_write(dev, RTL8211F_WOL_SETTINGS_STATUS, RTL8211F_WOL_STATUS_RESET); -+ } -+ -+err: -+ return phy_restore_page(dev, oldpage, 0); -+} -+ - static int rtl8211_config_aneg(struct phy_device *phydev) - { - int ret; -@@ -1400,6 +1467,8 @@ static struct phy_driver realtek_drvs[] = { - .read_status = rtlgen_read_status, - .config_intr = &rtl8211f_config_intr, - .handle_interrupt = rtl8211f_handle_interrupt, -+ .set_wol = rtl8211f_set_wol, -+ .get_wol = rtl8211f_get_wol, - .suspend = rtl821x_suspend, - .resume = rtl821x_resume, - .read_page = rtl821x_read_page, --- -2.51.0 - - -From ddd234bd4736f05f5f0ed506bee9f1a9b26cbd07 Mon Sep 17 00:00:00 2001 -From: Michael Klein -Date: Sun, 4 May 2025 19:29:11 +0200 -Subject: [PATCH 154/517] net: phy: realtek: remove unsed RTL821x_PHYSR* macros - -These macros have there since the first revision but were never used, so -let's just remove them. - -Signed-off-by: Michael Klein -Link: https://patch.msgid.link/20250504172916.243185-2-michael@fossekall.de -Signed-off-by: Paolo Abeni ---- - drivers/net/phy/realtek/realtek_main.c | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index 05c4f4d394a5..a6d21dfb1073 100644 ---- a/drivers/net/phy/realtek/realtek_main.c -+++ b/drivers/net/phy/realtek/realtek_main.c -@@ -18,10 +18,6 @@ - - #include "realtek.h" - --#define RTL821x_PHYSR 0x11 --#define RTL821x_PHYSR_DUPLEX BIT(13) --#define RTL821x_PHYSR_SPEED GENMASK(15, 14) -- - #define RTL821x_INER 0x12 - #define RTL8211B_INER_INIT 0x6400 - #define RTL8211E_INER_LINK_STATUS BIT(10) --- -2.51.0 - - -From 66803c7f8be64574b376190cc5b712c2f46c124d Mon Sep 17 00:00:00 2001 -From: Michael Klein -Date: Sun, 4 May 2025 19:29:12 +0200 -Subject: [PATCH 155/517] net: phy: realtek: Clean up RTL821x ExtPage access - -Factor out RTL8211E extension page access code to -rtl821x_modify_ext_page() and clean up rtl8211e_config_init() - -Signed-off-by: Michael Klein -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/20250504172916.243185-3-michael@fossekall.de -Signed-off-by: Paolo Abeni ---- - drivers/net/phy/realtek/realtek_main.c | 38 ++++++++++++++++---------- - 1 file changed, 23 insertions(+), 15 deletions(-) - -diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index a6d21dfb1073..0f005a449719 100644 ---- a/drivers/net/phy/realtek/realtek_main.c -+++ b/drivers/net/phy/realtek/realtek_main.c -@@ -26,7 +26,9 @@ - #define RTL821x_INSR 0x13 - - #define RTL821x_EXT_PAGE_SELECT 0x1e -+ - #define RTL821x_PAGE_SELECT 0x1f -+#define RTL821x_SET_EXT_PAGE 0x07 - - #define RTL8211F_PHYCR1 0x18 - #define RTL8211F_PHYCR2 0x19 -@@ -69,9 +71,12 @@ - #define RTL8211F_ALDPS_ENABLE BIT(2) - #define RTL8211F_ALDPS_XTAL_OFF BIT(12) - -+#define RTL8211E_RGMII_EXT_PAGE 0xa4 -+#define RTL8211E_RGMII_DELAY 0x1c - #define RTL8211E_CTRL_DELAY BIT(13) - #define RTL8211E_TX_DELAY BIT(12) - #define RTL8211E_RX_DELAY BIT(11) -+#define RTL8211E_DELAY_MASK GENMASK(13, 11) - - #define RTL8201F_ISR 0x1e - #define RTL8201F_ISR_ANERR BIT(15) -@@ -151,6 +156,21 @@ static int rtl821x_write_page(struct phy_device *phydev, int page) - return __phy_write(phydev, RTL821x_PAGE_SELECT, page); - } - -+static int rtl821x_modify_ext_page(struct phy_device *phydev, u16 ext_page, -+ u32 regnum, u16 mask, u16 set) -+{ -+ int oldpage, ret = 0; -+ -+ oldpage = phy_select_page(phydev, RTL821x_SET_EXT_PAGE); -+ if (oldpage >= 0) { -+ ret = __phy_write(phydev, RTL821x_EXT_PAGE_SELECT, ext_page); -+ if (ret == 0) -+ ret = __phy_modify(phydev, regnum, mask, set); -+ } -+ -+ return phy_restore_page(phydev, oldpage, ret); -+} -+ - static int rtl821x_probe(struct phy_device *phydev) - { - struct device *dev = &phydev->mdio.dev; -@@ -670,7 +690,6 @@ static int rtl8211f_led_hw_control_set(struct phy_device *phydev, u8 index, - - static int rtl8211e_config_init(struct phy_device *phydev) - { -- int ret = 0, oldpage; - u16 val; - - /* enable TX/RX delay for rgmii-* modes, and disable them for rgmii. */ -@@ -700,20 +719,9 @@ static int rtl8211e_config_init(struct phy_device *phydev) - * 12 = RX Delay, 11 = TX Delay - * 10:0 = Test && debug settings reserved by realtek - */ -- oldpage = phy_select_page(phydev, 0x7); -- if (oldpage < 0) -- goto err_restore_page; -- -- ret = __phy_write(phydev, RTL821x_EXT_PAGE_SELECT, 0xa4); -- if (ret) -- goto err_restore_page; -- -- ret = __phy_modify(phydev, 0x1c, RTL8211E_CTRL_DELAY -- | RTL8211E_TX_DELAY | RTL8211E_RX_DELAY, -- val); -- --err_restore_page: -- return phy_restore_page(phydev, oldpage, ret); -+ return rtl821x_modify_ext_page(phydev, RTL8211E_RGMII_EXT_PAGE, -+ RTL8211E_RGMII_DELAY, -+ RTL8211E_DELAY_MASK, val); - } - - static int rtl8211b_suspend(struct phy_device *phydev) --- -2.51.0 - - -From 798b8b7ae7fd1757c5106f7bcd71938f31cb4296 Mon Sep 17 00:00:00 2001 -From: Michael Klein -Date: Sun, 4 May 2025 19:29:13 +0200 -Subject: [PATCH 156/517] net: phy: realtek: add RTL8211F register defines - -Add some more defines for RTL8211F page and register numbers. - -Signed-off-by: Michael Klein -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/20250504172916.243185-4-michael@fossekall.de -Signed-off-by: Paolo Abeni ---- - drivers/net/phy/realtek/realtek_main.c | 34 ++++++++++++++++++-------- - 1 file changed, 24 insertions(+), 10 deletions(-) - -diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index 0f005a449719..ca6d2903b1c9 100644 ---- a/drivers/net/phy/realtek/realtek_main.c -+++ b/drivers/net/phy/realtek/realtek_main.c -@@ -30,11 +30,14 @@ - #define RTL821x_PAGE_SELECT 0x1f - #define RTL821x_SET_EXT_PAGE 0x07 - -+/* RTL8211F PHY configuration */ -+#define RTL8211F_PHYCR_PAGE 0xa43 - #define RTL8211F_PHYCR1 0x18 - #define RTL8211F_PHYCR2 0x19 - #define RTL8211F_CLKOUT_EN BIT(0) - #define RTL8211F_PHYCR2_PHY_EEE_ENABLE BIT(5) - -+#define RTL8211F_INSR_PAGE 0xa43 - #define RTL8211F_INSR 0x1d - - /* RTL8211F WOL interrupt configuration */ -@@ -55,6 +58,8 @@ - #define RTL8211F_PHYSICAL_ADDR_WORD1 17 - #define RTL8211F_PHYSICAL_ADDR_WORD2 18 - -+/* RTL8211F LED configuration */ -+#define RTL8211F_LEDCR_PAGE 0xd04 - #define RTL8211F_LEDCR 0x10 - #define RTL8211F_LEDCR_MODE BIT(15) - #define RTL8211F_LEDCR_ACT_TXRX BIT(4) -@@ -64,7 +69,13 @@ - #define RTL8211F_LEDCR_MASK GENMASK(4, 0) - #define RTL8211F_LEDCR_SHIFT 5 - -+/* RTL8211F RGMII configuration */ -+#define RTL8211F_RGMII_PAGE 0xd08 -+ -+#define RTL8211F_TXCR 0x11 - #define RTL8211F_TX_DELAY BIT(8) -+ -+#define RTL8211F_RXCR 0x15 - #define RTL8211F_RX_DELAY BIT(3) - - #define RTL8211F_ALDPS_PLL_OFF BIT(1) -@@ -187,7 +198,7 @@ static int rtl821x_probe(struct phy_device *phydev) - return dev_err_probe(dev, PTR_ERR(priv->clk), - "failed to get phy clock\n"); - -- ret = phy_read_paged(phydev, 0xa43, RTL8211F_PHYCR1); -+ ret = phy_read_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR1); - if (ret < 0) - return ret; - -@@ -197,7 +208,7 @@ static int rtl821x_probe(struct phy_device *phydev) - - priv->has_phycr2 = !(phy_id == RTL_8211FVD_PHYID); - if (priv->has_phycr2) { -- ret = phy_read_paged(phydev, 0xa43, RTL8211F_PHYCR2); -+ ret = phy_read_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR2); - if (ret < 0) - return ret; - -@@ -233,7 +244,7 @@ static int rtl8211f_ack_interrupt(struct phy_device *phydev) - { - int err; - -- err = phy_read_paged(phydev, 0xa43, RTL8211F_INSR); -+ err = phy_read_paged(phydev, RTL8211F_INSR_PAGE, RTL8211F_INSR); - - return (err < 0) ? err : 0; - } -@@ -376,7 +387,7 @@ static irqreturn_t rtl8211f_handle_interrupt(struct phy_device *phydev) - { - int irq_status; - -- irq_status = phy_read_paged(phydev, 0xa43, RTL8211F_INSR); -+ irq_status = phy_read_paged(phydev, RTL8211F_INSR_PAGE, RTL8211F_INSR); - if (irq_status < 0) { - phy_error(phydev); - return IRQ_NONE; -@@ -473,7 +484,7 @@ static int rtl8211f_config_init(struct phy_device *phydev) - u16 val_txdly, val_rxdly; - int ret; - -- ret = phy_modify_paged_changed(phydev, 0xa43, RTL8211F_PHYCR1, -+ ret = phy_modify_paged_changed(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR1, - RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF, - priv->phycr1); - if (ret < 0) { -@@ -507,7 +518,8 @@ static int rtl8211f_config_init(struct phy_device *phydev) - return 0; - } - -- ret = phy_modify_paged_changed(phydev, 0xd08, 0x11, RTL8211F_TX_DELAY, -+ ret = phy_modify_paged_changed(phydev, RTL8211F_RGMII_PAGE, -+ RTL8211F_TXCR, RTL8211F_TX_DELAY, - val_txdly); - if (ret < 0) { - dev_err(dev, "Failed to update the TX delay register\n"); -@@ -522,7 +534,8 @@ static int rtl8211f_config_init(struct phy_device *phydev) - str_enabled_disabled(val_txdly)); - } - -- ret = phy_modify_paged_changed(phydev, 0xd08, 0x15, RTL8211F_RX_DELAY, -+ ret = phy_modify_paged_changed(phydev, RTL8211F_RGMII_PAGE, -+ RTL8211F_RXCR, RTL8211F_RX_DELAY, - val_rxdly); - if (ret < 0) { - dev_err(dev, "Failed to update the RX delay register\n"); -@@ -538,14 +551,15 @@ static int rtl8211f_config_init(struct phy_device *phydev) - } - - /* Disable PHY-mode EEE so LPI is passed to the MAC */ -- ret = phy_modify_paged(phydev, 0xa43, RTL8211F_PHYCR2, -+ ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR2, - RTL8211F_PHYCR2_PHY_EEE_ENABLE, 0); - if (ret) - return ret; - - if (priv->has_phycr2) { -- ret = phy_modify_paged(phydev, 0xa43, RTL8211F_PHYCR2, -- RTL8211F_CLKOUT_EN, priv->phycr2); -+ ret = phy_modify_paged(phydev, RTL8211F_PHYCR_PAGE, -+ RTL8211F_PHYCR2, RTL8211F_CLKOUT_EN, -+ priv->phycr2); - if (ret < 0) { - dev_err(dev, "clkout configuration failed: %pe\n", - ERR_PTR(ret)); --- -2.51.0 - - -From 825c23aae9ae86718d9d0b15090994b8e2b99265 Mon Sep 17 00:00:00 2001 -From: Michael Klein -Date: Sun, 4 May 2025 19:29:14 +0200 -Subject: [PATCH 157/517] net: phy: realtek: Group RTL82* macro definitions - -Group macro definitions by PHY in lexicographic order. Within each PHY -block, definitions are order by page number and then register number. - -Signed-off-by: Michael Klein -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/20250504172916.243185-5-michael@fossekall.de -Signed-off-by: Paolo Abeni ---- - drivers/net/phy/realtek/realtek_main.c | 72 +++++++++++++------------- - 1 file changed, 37 insertions(+), 35 deletions(-) - -diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index ca6d2903b1c9..e01b13a9b5c3 100644 ---- a/drivers/net/phy/realtek/realtek_main.c -+++ b/drivers/net/phy/realtek/realtek_main.c -@@ -18,6 +18,16 @@ - - #include "realtek.h" - -+#define RTL8201F_IER 0x13 -+ -+#define RTL8201F_ISR 0x1e -+#define RTL8201F_ISR_ANERR BIT(15) -+#define RTL8201F_ISR_DUPLEX BIT(13) -+#define RTL8201F_ISR_LINK BIT(11) -+#define RTL8201F_ISR_MASK (RTL8201F_ISR_ANERR | \ -+ RTL8201F_ISR_DUPLEX | \ -+ RTL8201F_ISR_LINK) -+ - #define RTL821x_INER 0x12 - #define RTL8211B_INER_INIT 0x6400 - #define RTL8211E_INER_LINK_STATUS BIT(10) -@@ -30,9 +40,21 @@ - #define RTL821x_PAGE_SELECT 0x1f - #define RTL821x_SET_EXT_PAGE 0x07 - -+/* RTL8211E extension page 164/0xa4 */ -+#define RTL8211E_RGMII_EXT_PAGE 0xa4 -+#define RTL8211E_RGMII_DELAY 0x1c -+#define RTL8211E_CTRL_DELAY BIT(13) -+#define RTL8211E_TX_DELAY BIT(12) -+#define RTL8211E_RX_DELAY BIT(11) -+#define RTL8211E_DELAY_MASK GENMASK(13, 11) -+ - /* RTL8211F PHY configuration */ - #define RTL8211F_PHYCR_PAGE 0xa43 - #define RTL8211F_PHYCR1 0x18 -+#define RTL8211F_ALDPS_PLL_OFF BIT(1) -+#define RTL8211F_ALDPS_ENABLE BIT(2) -+#define RTL8211F_ALDPS_XTAL_OFF BIT(12) -+ - #define RTL8211F_PHYCR2 0x19 - #define RTL8211F_CLKOUT_EN BIT(0) - #define RTL8211F_PHYCR2_PHY_EEE_ENABLE BIT(5) -@@ -40,24 +62,6 @@ - #define RTL8211F_INSR_PAGE 0xa43 - #define RTL8211F_INSR 0x1d - --/* RTL8211F WOL interrupt configuration */ --#define RTL8211F_INTBCR_PAGE 0xd40 --#define RTL8211F_INTBCR 0x16 --#define RTL8211F_INTBCR_INTB_PMEB BIT(5) -- --/* RTL8211F WOL settings */ --#define RTL8211F_WOL_SETTINGS_PAGE 0xd8a --#define RTL8211F_WOL_SETTINGS_EVENTS 16 --#define RTL8211F_WOL_EVENT_MAGIC BIT(12) --#define RTL8211F_WOL_SETTINGS_STATUS 17 --#define RTL8211F_WOL_STATUS_RESET (BIT(15) | 0x1fff) -- --/* RTL8211F Unique phyiscal and multicast address (WOL) */ --#define RTL8211F_PHYSICAL_ADDR_PAGE 0xd8c --#define RTL8211F_PHYSICAL_ADDR_WORD0 16 --#define RTL8211F_PHYSICAL_ADDR_WORD1 17 --#define RTL8211F_PHYSICAL_ADDR_WORD2 18 -- - /* RTL8211F LED configuration */ - #define RTL8211F_LEDCR_PAGE 0xd04 - #define RTL8211F_LEDCR 0x10 -@@ -78,25 +82,23 @@ - #define RTL8211F_RXCR 0x15 - #define RTL8211F_RX_DELAY BIT(3) - --#define RTL8211F_ALDPS_PLL_OFF BIT(1) --#define RTL8211F_ALDPS_ENABLE BIT(2) --#define RTL8211F_ALDPS_XTAL_OFF BIT(12) -+/* RTL8211F WOL interrupt configuration */ -+#define RTL8211F_INTBCR_PAGE 0xd40 -+#define RTL8211F_INTBCR 0x16 -+#define RTL8211F_INTBCR_INTB_PMEB BIT(5) - --#define RTL8211E_RGMII_EXT_PAGE 0xa4 --#define RTL8211E_RGMII_DELAY 0x1c --#define RTL8211E_CTRL_DELAY BIT(13) --#define RTL8211E_TX_DELAY BIT(12) --#define RTL8211E_RX_DELAY BIT(11) --#define RTL8211E_DELAY_MASK GENMASK(13, 11) -+/* RTL8211F WOL settings */ -+#define RTL8211F_WOL_SETTINGS_PAGE 0xd8a -+#define RTL8211F_WOL_SETTINGS_EVENTS 16 -+#define RTL8211F_WOL_EVENT_MAGIC BIT(12) -+#define RTL8211F_WOL_SETTINGS_STATUS 17 -+#define RTL8211F_WOL_STATUS_RESET (BIT(15) | 0x1fff) - --#define RTL8201F_ISR 0x1e --#define RTL8201F_ISR_ANERR BIT(15) --#define RTL8201F_ISR_DUPLEX BIT(13) --#define RTL8201F_ISR_LINK BIT(11) --#define RTL8201F_ISR_MASK (RTL8201F_ISR_ANERR | \ -- RTL8201F_ISR_DUPLEX | \ -- RTL8201F_ISR_LINK) --#define RTL8201F_IER 0x13 -+/* RTL8211F Unique phyiscal and multicast address (WOL) */ -+#define RTL8211F_PHYSICAL_ADDR_PAGE 0xd8c -+#define RTL8211F_PHYSICAL_ADDR_WORD0 16 -+#define RTL8211F_PHYSICAL_ADDR_WORD1 17 -+#define RTL8211F_PHYSICAL_ADDR_WORD2 18 - - #define RTL822X_VND1_SERDES_OPTION 0x697a - #define RTL822X_VND1_SERDES_OPTION_MODE_MASK GENMASK(5, 0) --- -2.51.0 - - -From 6013af9a8dd65b8c5e941f33ec2dcf99f78c67d7 Mon Sep 17 00:00:00 2001 -From: Michael Klein -Date: Sun, 4 May 2025 19:29:15 +0200 -Subject: [PATCH 158/517] net: phy: realtek: use __set_bit() in - rtl8211f_led_hw_control_get() - -rtl8211f_led_hw_control_get() does not need atomic bit operations, -replace set_bit() by __set_bit(). - -Signed-off-by: Michael Klein -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/20250504172916.243185-6-michael@fossekall.de -Signed-off-by: Paolo Abeni ---- - drivers/net/phy/realtek/realtek_main.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index e01b13a9b5c3..e26098a2ff27 100644 ---- a/drivers/net/phy/realtek/realtek_main.c -+++ b/drivers/net/phy/realtek/realtek_main.c -@@ -659,17 +659,17 @@ static int rtl8211f_led_hw_control_get(struct phy_device *phydev, u8 index, - val &= RTL8211F_LEDCR_MASK; - - if (val & RTL8211F_LEDCR_LINK_10) -- set_bit(TRIGGER_NETDEV_LINK_10, rules); -+ __set_bit(TRIGGER_NETDEV_LINK_10, rules); - - if (val & RTL8211F_LEDCR_LINK_100) -- set_bit(TRIGGER_NETDEV_LINK_100, rules); -+ __set_bit(TRIGGER_NETDEV_LINK_100, rules); - - if (val & RTL8211F_LEDCR_LINK_1000) -- set_bit(TRIGGER_NETDEV_LINK_1000, rules); -+ __set_bit(TRIGGER_NETDEV_LINK_1000, rules); - - if (val & RTL8211F_LEDCR_ACT_TXRX) { -- set_bit(TRIGGER_NETDEV_RX, rules); -- set_bit(TRIGGER_NETDEV_TX, rules); -+ __set_bit(TRIGGER_NETDEV_RX, rules); -+ __set_bit(TRIGGER_NETDEV_TX, rules); - } - - return 0; --- -2.51.0 - - -From af5ac7b353e93a7d31448c80a90f687b38805116 Mon Sep 17 00:00:00 2001 -From: Michael Klein -Date: Sun, 4 May 2025 19:29:16 +0200 -Subject: [PATCH 159/517] net: phy: realtek: Add support for PHY LEDs on - RTL8211E - -Like the RTL8211F, the RTL8211E PHY supports up to three LEDs. -Add netdev trigger support for them, too. - -Signed-off-by: Michael Klein -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/20250504172916.243185-7-michael@fossekall.de -Signed-off-by: Paolo Abeni ---- - drivers/net/phy/realtek/realtek_main.c | 125 +++++++++++++++++++++++-- - 1 file changed, 119 insertions(+), 6 deletions(-) - -diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index e26098a2ff27..301fbe141b9b 100644 ---- a/drivers/net/phy/realtek/realtek_main.c -+++ b/drivers/net/phy/realtek/realtek_main.c -@@ -40,6 +40,20 @@ - #define RTL821x_PAGE_SELECT 0x1f - #define RTL821x_SET_EXT_PAGE 0x07 - -+/* RTL8211E extension page 44/0x2c */ -+#define RTL8211E_LEDCR_EXT_PAGE 0x2c -+#define RTL8211E_LEDCR1 0x1a -+#define RTL8211E_LEDCR1_ACT_TXRX BIT(4) -+#define RTL8211E_LEDCR1_MASK BIT(4) -+#define RTL8211E_LEDCR1_SHIFT 1 -+ -+#define RTL8211E_LEDCR2 0x1c -+#define RTL8211E_LEDCR2_LINK_1000 BIT(2) -+#define RTL8211E_LEDCR2_LINK_100 BIT(1) -+#define RTL8211E_LEDCR2_LINK_10 BIT(0) -+#define RTL8211E_LEDCR2_MASK GENMASK(2, 0) -+#define RTL8211E_LEDCR2_SHIFT 4 -+ - /* RTL8211E extension page 164/0xa4 */ - #define RTL8211E_RGMII_EXT_PAGE 0xa4 - #define RTL8211E_RGMII_DELAY 0x1c -@@ -145,7 +159,8 @@ - #define RTL_8221B_VN_CG 0x001cc84a - #define RTL_8251B 0x001cc862 - --#define RTL8211F_LED_COUNT 3 -+/* RTL8211E and RTL8211F support up to three LEDs */ -+#define RTL8211x_LED_COUNT 3 - - MODULE_DESCRIPTION("Realtek PHY driver"); - MODULE_AUTHOR("Johnson Leung"); -@@ -169,6 +184,21 @@ static int rtl821x_write_page(struct phy_device *phydev, int page) - return __phy_write(phydev, RTL821x_PAGE_SELECT, page); - } - -+static int rtl821x_read_ext_page(struct phy_device *phydev, u16 ext_page, -+ u32 regnum) -+{ -+ int oldpage, ret = 0; -+ -+ oldpage = phy_select_page(phydev, RTL821x_SET_EXT_PAGE); -+ if (oldpage >= 0) { -+ ret = __phy_write(phydev, RTL821x_EXT_PAGE_SELECT, ext_page); -+ if (ret == 0) -+ ret = __phy_read(phydev, regnum); -+ } -+ -+ return phy_restore_page(phydev, oldpage, ret); -+} -+ - static int rtl821x_modify_ext_page(struct phy_device *phydev, u16 ext_page, - u32 regnum, u16 mask, u16 set) - { -@@ -608,7 +638,7 @@ static int rtl821x_resume(struct phy_device *phydev) - return 0; - } - --static int rtl8211f_led_hw_is_supported(struct phy_device *phydev, u8 index, -+static int rtl8211x_led_hw_is_supported(struct phy_device *phydev, u8 index, - unsigned long rules) - { - const unsigned long mask = BIT(TRIGGER_NETDEV_LINK_10) | -@@ -627,9 +657,11 @@ static int rtl8211f_led_hw_is_supported(struct phy_device *phydev, u8 index, - * rates and Active indication always at all three 10+100+1000 - * link rates. - * This code currently uses mode B only. -+ * -+ * RTL8211E PHY LED has one mode, which works like RTL8211F mode B. - */ - -- if (index >= RTL8211F_LED_COUNT) -+ if (index >= RTL8211x_LED_COUNT) - return -EINVAL; - - /* Filter out any other unsupported triggers. */ -@@ -648,7 +680,7 @@ static int rtl8211f_led_hw_control_get(struct phy_device *phydev, u8 index, - { - int val; - -- if (index >= RTL8211F_LED_COUNT) -+ if (index >= RTL8211x_LED_COUNT) - return -EINVAL; - - val = phy_read_paged(phydev, 0xd04, RTL8211F_LEDCR); -@@ -681,7 +713,7 @@ static int rtl8211f_led_hw_control_set(struct phy_device *phydev, u8 index, - const u16 mask = RTL8211F_LEDCR_MASK << (RTL8211F_LEDCR_SHIFT * index); - u16 reg = 0; - -- if (index >= RTL8211F_LED_COUNT) -+ if (index >= RTL8211x_LED_COUNT) - return -EINVAL; - - if (test_bit(TRIGGER_NETDEV_LINK_10, &rules)) -@@ -704,6 +736,84 @@ static int rtl8211f_led_hw_control_set(struct phy_device *phydev, u8 index, - return phy_modify_paged(phydev, 0xd04, RTL8211F_LEDCR, mask, reg); - } - -+static int rtl8211e_led_hw_control_get(struct phy_device *phydev, u8 index, -+ unsigned long *rules) -+{ -+ int ret; -+ u16 cr1, cr2; -+ -+ if (index >= RTL8211x_LED_COUNT) -+ return -EINVAL; -+ -+ ret = rtl821x_read_ext_page(phydev, RTL8211E_LEDCR_EXT_PAGE, -+ RTL8211E_LEDCR1); -+ if (ret < 0) -+ return ret; -+ -+ cr1 = ret >> RTL8211E_LEDCR1_SHIFT * index; -+ if (cr1 & RTL8211E_LEDCR1_ACT_TXRX) { -+ __set_bit(TRIGGER_NETDEV_RX, rules); -+ __set_bit(TRIGGER_NETDEV_TX, rules); -+ } -+ -+ ret = rtl821x_read_ext_page(phydev, RTL8211E_LEDCR_EXT_PAGE, -+ RTL8211E_LEDCR2); -+ if (ret < 0) -+ return ret; -+ -+ cr2 = ret >> RTL8211E_LEDCR2_SHIFT * index; -+ if (cr2 & RTL8211E_LEDCR2_LINK_10) -+ __set_bit(TRIGGER_NETDEV_LINK_10, rules); -+ -+ if (cr2 & RTL8211E_LEDCR2_LINK_100) -+ __set_bit(TRIGGER_NETDEV_LINK_100, rules); -+ -+ if (cr2 & RTL8211E_LEDCR2_LINK_1000) -+ __set_bit(TRIGGER_NETDEV_LINK_1000, rules); -+ -+ return ret; -+} -+ -+static int rtl8211e_led_hw_control_set(struct phy_device *phydev, u8 index, -+ unsigned long rules) -+{ -+ const u16 cr1mask = -+ RTL8211E_LEDCR1_MASK << (RTL8211E_LEDCR1_SHIFT * index); -+ const u16 cr2mask = -+ RTL8211E_LEDCR2_MASK << (RTL8211E_LEDCR2_SHIFT * index); -+ u16 cr1 = 0, cr2 = 0; -+ int ret; -+ -+ if (index >= RTL8211x_LED_COUNT) -+ return -EINVAL; -+ -+ if (test_bit(TRIGGER_NETDEV_RX, &rules) || -+ test_bit(TRIGGER_NETDEV_TX, &rules)) { -+ cr1 |= RTL8211E_LEDCR1_ACT_TXRX; -+ } -+ -+ cr1 <<= RTL8211E_LEDCR1_SHIFT * index; -+ ret = rtl821x_modify_ext_page(phydev, RTL8211E_LEDCR_EXT_PAGE, -+ RTL8211E_LEDCR1, cr1mask, cr1); -+ if (ret < 0) -+ return ret; -+ -+ if (test_bit(TRIGGER_NETDEV_LINK_10, &rules)) -+ cr2 |= RTL8211E_LEDCR2_LINK_10; -+ -+ if (test_bit(TRIGGER_NETDEV_LINK_100, &rules)) -+ cr2 |= RTL8211E_LEDCR2_LINK_100; -+ -+ if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules)) -+ cr2 |= RTL8211E_LEDCR2_LINK_1000; -+ -+ cr2 <<= RTL8211E_LEDCR2_SHIFT * index; -+ ret = rtl821x_modify_ext_page(phydev, RTL8211E_LEDCR_EXT_PAGE, -+ RTL8211E_LEDCR2, cr2mask, cr2); -+ -+ return ret; -+} -+ - static int rtl8211e_config_init(struct phy_device *phydev) - { - u16 val; -@@ -1479,6 +1589,9 @@ static struct phy_driver realtek_drvs[] = { - .resume = genphy_resume, - .read_page = rtl821x_read_page, - .write_page = rtl821x_write_page, -+ .led_hw_is_supported = rtl8211x_led_hw_is_supported, -+ .led_hw_control_get = rtl8211e_led_hw_control_get, -+ .led_hw_control_set = rtl8211e_led_hw_control_set, - }, { - PHY_ID_MATCH_EXACT(0x001cc916), - .name = "RTL8211F Gigabit Ethernet", -@@ -1494,7 +1607,7 @@ static struct phy_driver realtek_drvs[] = { - .read_page = rtl821x_read_page, - .write_page = rtl821x_write_page, - .flags = PHY_ALWAYS_CALL_SUSPEND, -- .led_hw_is_supported = rtl8211f_led_hw_is_supported, -+ .led_hw_is_supported = rtl8211x_led_hw_is_supported, - .led_hw_control_get = rtl8211f_led_hw_control_get, - .led_hw_control_set = rtl8211f_led_hw_control_set, - }, { --- -2.51.0 - - -From 955251d7b04d32610229bef09ec0a27ccbd8e370 Mon Sep 17 00:00:00 2001 -From: ChunHao Lin -Date: Fri, 16 May 2025 13:56:22 +0800 -Subject: [PATCH 160/517] net: phy: realtek: add RTL8127-internal PHY - -RTL8127-internal PHY is RTL8261C which is a integrated 10Gbps PHY with ID -0x001cc890. It follows the code path of RTL8125/RTL8126 internal NBase-T -PHY. - -Signed-off-by: ChunHao Lin -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/20250516055622.3772-1-hau@realtek.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/realtek/realtek_main.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index 301fbe141b9b..b5e00cdf0123 100644 ---- a/drivers/net/phy/realtek/realtek_main.c -+++ b/drivers/net/phy/realtek/realtek_main.c -@@ -158,6 +158,7 @@ - #define RTL_8221B_VB_CG 0x001cc849 - #define RTL_8221B_VN_CG 0x001cc84a - #define RTL_8251B 0x001cc862 -+#define RTL_8261C 0x001cc890 - - /* RTL8211E and RTL8211F support up to three LEDs */ - #define RTL8211x_LED_COUNT 3 -@@ -1370,6 +1371,7 @@ static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev) - case RTL_GENERIC_PHYID: - case RTL_8221B: - case RTL_8251B: -+ case RTL_8261C: - case 0x001cc841: - break; - default: --- -2.51.0 - - -From c1c8742b69103888ee85bb7e55353066d4ef5457 Mon Sep 17 00:00:00 2001 -From: Markus Stockhausen -Date: Wed, 13 Aug 2025 01:44:07 -0400 -Subject: [PATCH 161/517] net: phy: realtek: convert RTL8226-CG to c45 only - -Short: Convert the RTL8226-CG to c45 so it can be used in its -Realtek based ecosystems. - -Long: The RTL8226-CG can be mainly found on devices of the -Realtek Otto switch platform. Devices like the Zyxel XGS1210-12 -are based on it. These implement a hardware based phy polling -in the background to update SoC status registers. - -The hardware provides 4 smi busses where phys are attached to. -For each bus one can decide if it is polled in c45 or c22 mode. -See https://svanheule.net/realtek/longan/register/smi_glb_ctrl -With this setting the register access will be limited by the -hardware. This is very complex (including caching and special -c45-over-c22 handling). But basically it boils down to "enable -protocol x and SoC will disable register access via protocol y". - -Mainline already gained support for the rtl9300 mdio driver -in commit 24e31e474769 ("net: mdio: Add RTL9300 MDIO driver"). - -It covers the basic features, but a lot effort is still needed -to understand hardware properly. So it runs a simple setup by -selecting the proper bus mode during startup. - - /* Put the interfaces into C45 mode if required */ - glb_ctrl_mask = GENMASK(19, 16); - for (i = 0; i < MAX_SMI_BUSSES; i++) - if (priv->smi_bus_is_c45[i]) - glb_ctrl_val |= GLB_CTRL_INTF_SEL(i); - ... - err = regmap_update_bits(regmap, SMI_GLB_CTRL, - glb_ctrl_mask, glb_ctrl_val); - -To avoid complex coding later on, it limits access by only -providing either c22 or c45: - - bus->name = "Realtek Switch MDIO Bus"; - if (priv->smi_bus_is_c45[mdio_bus]) { - bus->read_c45 = rtl9300_mdio_read_c45; - bus->write_c45 = rtl9300_mdio_write_c45; - } else { - bus->read = rtl9300_mdio_read_c22; - bus->write = rtl9300_mdio_write_c22; - } - -Because of these limitations the existing RTL8226 phy driver -is not working at all on Realtek switches. Convert the driver -to c45-only. - -Luckily the RTL8226 seems to support proper MDIO_PMA_EXTABLE -flags. So standard function genphy_c45_pma_read_abilities() can -call genphy_c45_pma_read_ext_abilities() and 10/100/1000 is -populated right. Thus conversion is straight forward. - -Outputs before - REMARK: For this a "hacked" bus was used that -toggles the mode for each c22/c45 access. But that is slow and -produces unstable data in the SoC status registers). - -Settings for lan9: - Supported ports: [ TP MII ] - Supported link modes: 10baseT/Half 10baseT/Full - 100baseT/Half 100baseT/Full - 1000baseT/Full - 2500baseT/Full - Supported pause frame use: Symmetric Receive-only - Supports auto-negotiation: Yes - Supported FEC modes: Not reported - Advertised link modes: 10baseT/Half 10baseT/Full - 100baseT/Half 100baseT/Full - 1000baseT/Full - 2500baseT/Full - Advertised pause frame use: Symmetric Receive-only - Advertised auto-negotiation: Yes - Advertised FEC modes: Not reported - Speed: Unknown! - Duplex: Unknown! (255) - Port: Twisted Pair - PHYAD: 24 - Transceiver: external - Auto-negotiation: on - MDI-X: Unknown - Supports Wake-on: d - Wake-on: d - Link detected: no - -Outputs with this commit: - -Settings for lan9: - Supported ports: [ TP ] - Supported link modes: 10baseT/Half 10baseT/Full - 100baseT/Half 100baseT/Full - 1000baseT/Full - 2500baseT/Full - Supported pause frame use: Symmetric Receive-only - Supports auto-negotiation: Yes - Supported FEC modes: Not reported - Advertised link modes: 10baseT/Half 10baseT/Full - 100baseT/Half 100baseT/Full - 1000baseT/Full - 2500baseT/Full - Advertised pause frame use: Symmetric Receive-only - Advertised auto-negotiation: Yes - Advertised FEC modes: Not reported - Speed: Unknown! - Duplex: Unknown! (255) - Port: Twisted Pair - PHYAD: 24 - Transceiver: external - Auto-negotiation: on - MDI-X: Unknown - Supports Wake-on: d - Wake-on: d - Link detected: no - -Signed-off-by: Markus Stockhausen -Link: https://patch.msgid.link/20250813054407.1108285-1-markus.stockhausen@gmx.de -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/realtek/realtek_main.c | 28 +++++++++++++++++++------- - 1 file changed, 21 insertions(+), 7 deletions(-) - -diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index b5e00cdf0123..bcfd9305e8b7 100644 ---- a/drivers/net/phy/realtek/realtek_main.c -+++ b/drivers/net/phy/realtek/realtek_main.c -@@ -1274,6 +1274,21 @@ static int rtl822x_c45_read_status(struct phy_device *phydev) - return 0; - } - -+static int rtl822x_c45_soft_reset(struct phy_device *phydev) -+{ -+ int ret, val; -+ -+ ret = phy_modify_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1, -+ MDIO_CTRL1_RESET, MDIO_CTRL1_RESET); -+ if (ret < 0) -+ return ret; -+ -+ return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_PMAPMD, -+ MDIO_CTRL1, val, -+ !(val & MDIO_CTRL1_RESET), -+ 5000, 100000, true); -+} -+ - static int rtl822xb_c45_read_status(struct phy_device *phydev) - { - int ret; -@@ -1660,13 +1675,12 @@ static struct phy_driver realtek_drvs[] = { - }, { - PHY_ID_MATCH_EXACT(0x001cc838), - .name = "RTL8226-CG 2.5Gbps PHY", -- .get_features = rtl822x_get_features, -- .config_aneg = rtl822x_config_aneg, -- .read_status = rtl822x_read_status, -- .suspend = genphy_suspend, -- .resume = rtlgen_resume, -- .read_page = rtl821x_read_page, -- .write_page = rtl821x_write_page, -+ .soft_reset = rtl822x_c45_soft_reset, -+ .get_features = rtl822x_c45_get_features, -+ .config_aneg = rtl822x_c45_config_aneg, -+ .read_status = rtl822x_c45_read_status, -+ .suspend = genphy_c45_pma_suspend, -+ .resume = rtlgen_c45_resume, - }, { - PHY_ID_MATCH_EXACT(0x001cc848), - .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY", --- -2.51.0 - - -From 19770c92bfab8e1cfb144fa63e2a6fa8a9a9c791 Mon Sep 17 00:00:00 2001 -From: Markus Stockhausen -Date: Fri, 15 Aug 2025 04:20:09 -0400 -Subject: [PATCH 162/517] net: phy: realtek: enable serdes option mode for - RTL8226-CG - -The RTL8226-CG can make use of the serdes option mode feature to -dynamically switch between SGMII and 2500base-X. From what is -known the setup sequence is much simpler with no magic values. - -Convert the exiting config_init() into a helper that configures -the PHY depending on generation 1 or 2. Call the helper from two -separated new config_init() functions. - -Finally convert the phy_driver specs of the RTL8226-CG to make -use of the new configuration and switch over to the extended -read_status() function to dynamically change the interface -according to the serdes mode. - -Remark! The logic could be simpler if the serdes mode could be -set before all other generation 2 magic values. Due to missing -RTL8221B test hardware the mmd command order was kept. - -Tested on Zyxel XGS1210-12. - -Signed-off-by: Markus Stockhausen -Link: https://patch.msgid.link/20250815082009.3678865-1-markus.stockhausen@gmx.de -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/realtek/realtek_main.c | 26 ++++++++++++++++++++------ - 1 file changed, 20 insertions(+), 6 deletions(-) - -diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index bcfd9305e8b7..c0981932429b 100644 ---- a/drivers/net/phy/realtek/realtek_main.c -+++ b/drivers/net/phy/realtek/realtek_main.c -@@ -1032,7 +1032,7 @@ static int rtl822x_probe(struct phy_device *phydev) - return 0; - } - --static int rtl822xb_config_init(struct phy_device *phydev) -+static int rtl822x_set_serdes_option_mode(struct phy_device *phydev, bool gen1) - { - bool has_2500, has_sgmii; - u16 mode; -@@ -1067,15 +1067,18 @@ static int rtl822xb_config_init(struct phy_device *phydev) - /* the following sequence with magic numbers sets up the SerDes - * option mode - */ -- ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x75f3, 0); -- if (ret < 0) -- return ret; -+ -+ if (!gen1) { -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x75f3, 0); -+ if (ret < 0) -+ return ret; -+ } - - ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND1, - RTL822X_VND1_SERDES_OPTION, - RTL822X_VND1_SERDES_OPTION_MODE_MASK, - mode); -- if (ret < 0) -+ if (gen1 || ret < 0) - return ret; - - ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6a04, 0x0503); -@@ -1089,6 +1092,16 @@ static int rtl822xb_config_init(struct phy_device *phydev) - return phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020); - } - -+static int rtl822x_config_init(struct phy_device *phydev) -+{ -+ return rtl822x_set_serdes_option_mode(phydev, true); -+} -+ -+static int rtl822xb_config_init(struct phy_device *phydev) -+{ -+ return rtl822x_set_serdes_option_mode(phydev, false); -+} -+ - static int rtl822xb_get_rate_matching(struct phy_device *phydev, - phy_interface_t iface) - { -@@ -1678,7 +1691,8 @@ static struct phy_driver realtek_drvs[] = { - .soft_reset = rtl822x_c45_soft_reset, - .get_features = rtl822x_c45_get_features, - .config_aneg = rtl822x_c45_config_aneg, -- .read_status = rtl822x_c45_read_status, -+ .config_init = rtl822x_config_init, -+ .read_status = rtl822xb_c45_read_status, - .suspend = genphy_c45_pma_suspend, - .resume = rtlgen_c45_resume, - }, { --- -2.51.0 - - -From 3eda64f56ef81929d383b568d8642b7439cba90e Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Sat, 17 May 2025 22:13:45 +0200 -Subject: [PATCH 163/517] net: phy: pass PHY driver to .match_phy_device OP - -Pass PHY driver pointer to .match_phy_device OP in addition to phydev. -Having access to the PHY driver struct might be useful to check the -PHY ID of the driver is being matched for in case the PHY ID scanned in -the phydev is not consistent. - -A scenario for this is a PHY that change PHY ID after a firmware is -loaded, in such case, the PHY ID stored in PHY device struct is not -valid anymore and PHY will manually scan the ID in the match_phy_device -function. - -Having the PHY driver info is also useful for those PHY driver that -implement multiple simple .match_phy_device OP to match specific MMD PHY -ID. With this extra info if the parsing logic is the same, the matching -function can be generalized by using the phy_id in the PHY driver -instead of hardcoding. - -Rust wrapper callback is updated to align to the new match_phy_device -arguments. - -Suggested-by: Russell King (Oracle) -Reviewed-by: Russell King (Oracle) -Signed-off-by: Christian Marangi -Reviewed-by: Benno Lossin # for Rust -Reviewed-by: FUJITA Tomonori -Link: https://patch.msgid.link/20250517201353.5137-2-ansuelsmth@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/bcm87xx.c | 6 ++++-- - drivers/net/phy/icplus.c | 6 ++++-- - drivers/net/phy/marvell10g.c | 12 ++++++++---- - drivers/net/phy/micrel.c | 6 ++++-- - drivers/net/phy/nxp-c45-tja11xx.c | 6 ++++-- - drivers/net/phy/nxp-tja11xx.c | 6 ++++-- - drivers/net/phy/phy_device.c | 2 +- - drivers/net/phy/realtek/realtek_main.c | 27 +++++++++++++++++--------- - drivers/net/phy/teranetics.c | 3 ++- - include/linux/phy.h | 3 ++- - rust/kernel/net/phy.rs | 1 + - 11 files changed, 52 insertions(+), 26 deletions(-) - -diff --git a/drivers/net/phy/bcm87xx.c b/drivers/net/phy/bcm87xx.c -index e81404bf8994..1e1e2259fc2b 100644 ---- a/drivers/net/phy/bcm87xx.c -+++ b/drivers/net/phy/bcm87xx.c -@@ -185,12 +185,14 @@ static irqreturn_t bcm87xx_handle_interrupt(struct phy_device *phydev) - return IRQ_HANDLED; - } - --static int bcm8706_match_phy_device(struct phy_device *phydev) -+static int bcm8706_match_phy_device(struct phy_device *phydev, -+ const struct phy_driver *phydrv) - { - return phydev->c45_ids.device_ids[4] == PHY_ID_BCM8706; - } - --static int bcm8727_match_phy_device(struct phy_device *phydev) -+static int bcm8727_match_phy_device(struct phy_device *phydev, -+ const struct phy_driver *phydrv) - { - return phydev->c45_ids.device_ids[4] == PHY_ID_BCM8727; - } -diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c -index feed270ab4ea..c6950b7145c1 100644 ---- a/drivers/net/phy/icplus.c -+++ b/drivers/net/phy/icplus.c -@@ -520,12 +520,14 @@ static int ip101a_g_match_phy_device(struct phy_device *phydev, bool ip101a) - return ip101a == !ret; - } - --static int ip101a_match_phy_device(struct phy_device *phydev) -+static int ip101a_match_phy_device(struct phy_device *phydev, -+ const struct phy_driver *phydrv) - { - return ip101a_g_match_phy_device(phydev, true); - } - --static int ip101g_match_phy_device(struct phy_device *phydev) -+static int ip101g_match_phy_device(struct phy_device *phydev, -+ const struct phy_driver *phydrv) - { - return ip101a_g_match_phy_device(phydev, false); - } -diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c -index 623bdb8466b8..2994a3570128 100644 ---- a/drivers/net/phy/marvell10g.c -+++ b/drivers/net/phy/marvell10g.c -@@ -1284,7 +1284,8 @@ static int mv3310_get_number_of_ports(struct phy_device *phydev) - return ret + 1; - } - --static int mv3310_match_phy_device(struct phy_device *phydev) -+static int mv3310_match_phy_device(struct phy_device *phydev, -+ const struct phy_driver *phydrv) - { - if ((phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] & - MARVELL_PHY_ID_MASK) != MARVELL_PHY_ID_88X3310) -@@ -1293,7 +1294,8 @@ static int mv3310_match_phy_device(struct phy_device *phydev) - return mv3310_get_number_of_ports(phydev) == 1; - } - --static int mv3340_match_phy_device(struct phy_device *phydev) -+static int mv3340_match_phy_device(struct phy_device *phydev, -+ const struct phy_driver *phydrv) - { - if ((phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] & - MARVELL_PHY_ID_MASK) != MARVELL_PHY_ID_88X3310) -@@ -1317,12 +1319,14 @@ static int mv211x_match_phy_device(struct phy_device *phydev, bool has_5g) - return !!(val & MDIO_PCS_SPEED_5G) == has_5g; - } - --static int mv2110_match_phy_device(struct phy_device *phydev) -+static int mv2110_match_phy_device(struct phy_device *phydev, -+ const struct phy_driver *phydrv) - { - return mv211x_match_phy_device(phydev, true); - } - --static int mv2111_match_phy_device(struct phy_device *phydev) -+static int mv2111_match_phy_device(struct phy_device *phydev, -+ const struct phy_driver *phydrv) - { - return mv211x_match_phy_device(phydev, false); - } -diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c -index 655769765bc8..2c6e75789eb7 100644 ---- a/drivers/net/phy/micrel.c -+++ b/drivers/net/phy/micrel.c -@@ -768,7 +768,8 @@ static int ksz8051_ksz8795_match_phy_device(struct phy_device *phydev, - return !ret; - } - --static int ksz8051_match_phy_device(struct phy_device *phydev) -+static int ksz8051_match_phy_device(struct phy_device *phydev, -+ const struct phy_driver *phydrv) - { - return ksz8051_ksz8795_match_phy_device(phydev, true); - } -@@ -888,7 +889,8 @@ static int ksz8061_config_init(struct phy_device *phydev) - return kszphy_config_init(phydev); - } - --static int ksz8795_match_phy_device(struct phy_device *phydev) -+static int ksz8795_match_phy_device(struct phy_device *phydev, -+ const struct phy_driver *phydrv) - { - return ksz8051_ksz8795_match_phy_device(phydev, false); - } -diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c -index 9d6b336f9971..9aeae2a6c638 100644 ---- a/drivers/net/phy/nxp-c45-tja11xx.c -+++ b/drivers/net/phy/nxp-c45-tja11xx.c -@@ -1944,13 +1944,15 @@ static int nxp_c45_macsec_ability(struct phy_device *phydev) - return macsec_ability; - } - --static int tja1103_match_phy_device(struct phy_device *phydev) -+static int tja1103_match_phy_device(struct phy_device *phydev, -+ const struct phy_driver *phydrv) - { - return phy_id_compare(phydev->phy_id, PHY_ID_TJA_1103, PHY_ID_MASK) && - !nxp_c45_macsec_ability(phydev); - } - --static int tja1104_match_phy_device(struct phy_device *phydev) -+static int tja1104_match_phy_device(struct phy_device *phydev, -+ const struct phy_driver *phydrv) - { - return phy_id_compare(phydev->phy_id, PHY_ID_TJA_1103, PHY_ID_MASK) && - nxp_c45_macsec_ability(phydev); -diff --git a/drivers/net/phy/nxp-tja11xx.c b/drivers/net/phy/nxp-tja11xx.c -index ed7fa26bac8e..08dda6926732 100644 ---- a/drivers/net/phy/nxp-tja11xx.c -+++ b/drivers/net/phy/nxp-tja11xx.c -@@ -646,12 +646,14 @@ static int tja1102_match_phy_device(struct phy_device *phydev, bool port0) - return !ret; - } - --static int tja1102_p0_match_phy_device(struct phy_device *phydev) -+static int tja1102_p0_match_phy_device(struct phy_device *phydev, -+ const struct phy_driver *phydrv) - { - return tja1102_match_phy_device(phydev, true); - } - --static int tja1102_p1_match_phy_device(struct phy_device *phydev) -+static int tja1102_p1_match_phy_device(struct phy_device *phydev, -+ const struct phy_driver *phydrv) - { - return tja1102_match_phy_device(phydev, false); - } -diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c -index 762f909242b4..71f6cadde109 100644 ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -600,7 +600,7 @@ static int phy_bus_match(struct device *dev, const struct device_driver *drv) - return 0; - - if (phydrv->match_phy_device) -- return phydrv->match_phy_device(phydev); -+ return phydrv->match_phy_device(phydev, phydrv); - - if (phydev->is_c45) { - for (i = 1; i < num_ids; i++) { -diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index c0981932429b..114d219562f1 100644 ---- a/drivers/net/phy/realtek/realtek_main.c -+++ b/drivers/net/phy/realtek/realtek_main.c -@@ -1343,13 +1343,15 @@ static bool rtlgen_supports_mmd(struct phy_device *phydev) - return val > 0; - } - --static int rtlgen_match_phy_device(struct phy_device *phydev) -+static int rtlgen_match_phy_device(struct phy_device *phydev, -+ const struct phy_driver *phydrv) - { - return phydev->phy_id == RTL_GENERIC_PHYID && - !rtlgen_supports_2_5gbps(phydev); - } - --static int rtl8226_match_phy_device(struct phy_device *phydev) -+static int rtl8226_match_phy_device(struct phy_device *phydev, -+ const struct phy_driver *phydrv) - { - return phydev->phy_id == RTL_GENERIC_PHYID && - rtlgen_supports_2_5gbps(phydev) && -@@ -1365,32 +1367,38 @@ static int rtlgen_is_c45_match(struct phy_device *phydev, unsigned int id, - return !is_c45 && (id == phydev->phy_id); - } - --static int rtl8221b_match_phy_device(struct phy_device *phydev) -+static int rtl8221b_match_phy_device(struct phy_device *phydev, -+ const struct phy_driver *phydrv) - { - return phydev->phy_id == RTL_8221B && rtlgen_supports_mmd(phydev); - } - --static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev) -+static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev, -+ const struct phy_driver *phydrv) - { - return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, false); - } - --static int rtl8221b_vb_cg_c45_match_phy_device(struct phy_device *phydev) -+static int rtl8221b_vb_cg_c45_match_phy_device(struct phy_device *phydev, -+ const struct phy_driver *phydrv) - { - return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, true); - } - --static int rtl8221b_vn_cg_c22_match_phy_device(struct phy_device *phydev) -+static int rtl8221b_vn_cg_c22_match_phy_device(struct phy_device *phydev, -+ const struct phy_driver *phydrv) - { - return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, false); - } - --static int rtl8221b_vn_cg_c45_match_phy_device(struct phy_device *phydev) -+static int rtl8221b_vn_cg_c45_match_phy_device(struct phy_device *phydev, -+ const struct phy_driver *phydrv) - { - return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true); - } - --static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev) -+static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev, -+ const struct phy_driver *phydrv) - { - if (phydev->is_c45) - return false; -@@ -1409,7 +1417,8 @@ static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev) - return rtlgen_supports_2_5gbps(phydev) && !rtlgen_supports_mmd(phydev); - } - --static int rtl8251b_c45_match_phy_device(struct phy_device *phydev) -+static int rtl8251b_c45_match_phy_device(struct phy_device *phydev, -+ const struct phy_driver *phydrv) - { - return rtlgen_is_c45_match(phydev, RTL_8251B, true); - } -diff --git a/drivers/net/phy/teranetics.c b/drivers/net/phy/teranetics.c -index 752d4bf7bb99..46c5ff7d7b56 100644 ---- a/drivers/net/phy/teranetics.c -+++ b/drivers/net/phy/teranetics.c -@@ -67,7 +67,8 @@ static int teranetics_read_status(struct phy_device *phydev) - return 0; - } - --static int teranetics_match_phy_device(struct phy_device *phydev) -+static int teranetics_match_phy_device(struct phy_device *phydev, -+ const struct phy_driver *phydrv) - { - return phydev->c45_ids.device_ids[3] == PHY_ID_TN2020; - } -diff --git a/include/linux/phy.h b/include/linux/phy.h -index df147d9d302f..1bdcc3dd8b66 100644 ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -1035,7 +1035,8 @@ struct phy_driver { - * driver for the given phydev. If NULL, matching is based on - * phy_id and phy_id_mask. - */ -- int (*match_phy_device)(struct phy_device *phydev); -+ int (*match_phy_device)(struct phy_device *phydev, -+ const struct phy_driver *phydrv); - - /** - * @set_wol: Some devices (e.g. qnap TS-119P II) require PHY -diff --git a/rust/kernel/net/phy.rs b/rust/kernel/net/phy.rs -index beb62ec712c3..40214bbe4677 100644 ---- a/rust/kernel/net/phy.rs -+++ b/rust/kernel/net/phy.rs -@@ -421,6 +421,7 @@ impl Adapter { - /// `phydev` must be passed by the corresponding callback in `phy_driver`. - unsafe extern "C" fn match_phy_device_callback( - phydev: *mut bindings::phy_device, -+ _phydrv: *const bindings::phy_driver, - ) -> crate::ffi::c_int { - // SAFETY: This callback is called only in contexts - // where we hold `phy_device->lock`, so the accessors on --- -2.51.0 - - -From 175ba11ce1ac5beacdbe65b7fd3acbe9002f8d1f Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Sat, 17 May 2025 22:13:48 +0200 -Subject: [PATCH 164/517] net: phy: introduce genphy_match_phy_device() - -Introduce new API, genphy_match_phy_device(), to provide a way to check -to match a PHY driver for a PHY device based on the info stored in the -PHY device struct. - -The function generalize the logic used in phy_bus_match() to check the -PHY ID whether if C45 or C22 ID should be used for matching. - -This is useful for custom .match_phy_device function that wants to use -the generic logic under some condition. (example a PHY is already setup -and provide the correct PHY ID) - -Reviewed-by: Russell King (Oracle) -Signed-off-by: Christian Marangi -Link: https://patch.msgid.link/20250517201353.5137-5-ansuelsmth@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phy_device.c | 52 +++++++++++++++++++++++++----------- - include/linux/phy.h | 3 +++ - 2 files changed, 40 insertions(+), 15 deletions(-) - -diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c -index 71f6cadde109..2e08d20a3cfb 100644 ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -589,20 +589,26 @@ static int phy_scan_fixups(struct phy_device *phydev) - return 0; - } - --static int phy_bus_match(struct device *dev, const struct device_driver *drv) -+/** -+ * genphy_match_phy_device - match a PHY device with a PHY driver -+ * @phydev: target phy_device struct -+ * @phydrv: target phy_driver struct -+ * -+ * Description: Checks whether the given PHY device matches the specified -+ * PHY driver. For Clause 45 PHYs, iterates over the available device -+ * identifiers and compares them against the driver's expected PHY ID, -+ * applying the provided mask. For Clause 22 PHYs, a direct ID comparison -+ * is performed. -+ * -+ * Return: 1 if the PHY device matches the driver, 0 otherwise. -+ */ -+int genphy_match_phy_device(struct phy_device *phydev, -+ const struct phy_driver *phydrv) - { -- struct phy_device *phydev = to_phy_device(dev); -- const struct phy_driver *phydrv = to_phy_driver(drv); -- const int num_ids = ARRAY_SIZE(phydev->c45_ids.device_ids); -- int i; -- -- if (!(phydrv->mdiodrv.flags & MDIO_DEVICE_IS_PHY)) -- return 0; -- -- if (phydrv->match_phy_device) -- return phydrv->match_phy_device(phydev, phydrv); -- - if (phydev->is_c45) { -+ const int num_ids = ARRAY_SIZE(phydev->c45_ids.device_ids); -+ int i; -+ - for (i = 1; i < num_ids; i++) { - if (phydev->c45_ids.device_ids[i] == 0xffffffff) - continue; -@@ -611,11 +617,27 @@ static int phy_bus_match(struct device *dev, const struct device_driver *drv) - phydrv->phy_id, phydrv->phy_id_mask)) - return 1; - } -+ - return 0; -- } else { -- return phy_id_compare(phydev->phy_id, phydrv->phy_id, -- phydrv->phy_id_mask); - } -+ -+ return phy_id_compare(phydev->phy_id, phydrv->phy_id, -+ phydrv->phy_id_mask); -+} -+EXPORT_SYMBOL_GPL(genphy_match_phy_device); -+ -+static int phy_bus_match(struct device *dev, const struct device_driver *drv) -+{ -+ struct phy_device *phydev = to_phy_device(dev); -+ const struct phy_driver *phydrv = to_phy_driver(drv); -+ -+ if (!(phydrv->mdiodrv.flags & MDIO_DEVICE_IS_PHY)) -+ return 0; -+ -+ if (phydrv->match_phy_device) -+ return phydrv->match_phy_device(phydev, phydrv); -+ -+ return genphy_match_phy_device(phydev, phydrv); - } - - static ssize_t -diff --git a/include/linux/phy.h b/include/linux/phy.h -index 1bdcc3dd8b66..85217937e489 100644 ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -1940,6 +1940,9 @@ char *phy_attached_info_irq(struct phy_device *phydev) - __malloc; - void phy_attached_info(struct phy_device *phydev); - -+int genphy_match_phy_device(struct phy_device *phydev, -+ const struct phy_driver *phydrv); -+ - /* Clause 22 PHY */ - int genphy_read_abilities(struct phy_device *phydev); - int genphy_setup_forced(struct phy_device *phydev); --- -2.51.0 - - -From 607e13a6b9b9484da3e5e549dee6883ad71fe0d3 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Sat, 17 May 2025 22:13:49 +0200 -Subject: [PATCH 165/517] net: phy: Add support for Aeonsemi AS21xxx PHYs - -Add support for Aeonsemi AS21xxx 10G C45 PHYs. These PHYs integrate -an IPC to setup some configuration and require special handling to -sync with the parity bit. The parity bit is a way the IPC use to -follow correct order of command sent. - -Supported PHYs AS21011JB1, AS21011PB1, AS21010JB1, AS21010PB1, -AS21511JB1, AS21511PB1, AS21510JB1, AS21510PB1, AS21210JB1, -AS21210PB1 that all register with the PHY ID 0x7500 0x7510 -before the firmware is loaded. - -They all support up to 5 LEDs with various HW mode supported. - -While implementing it was found some strange coincidence with using the -same logic for implementing C22 in MMD regs in Broadcom PHYs. - -For reference here the AS21xxx PHY name logic: - -AS21x1xxB1 - ^ ^^ - | |J: Supports SyncE/PTP - | |P: No SyncE/PTP support - | 1: Supports 2nd Serdes - | 2: Not 2nd Serdes support - 0: 10G, 5G, 2.5G - 5: 5G, 2.5G - 2: 2.5G - -Reviewed-by: Andrew Lunn -Signed-off-by: Christian Marangi -Link: https://patch.msgid.link/20250517201353.5137-6-ansuelsmth@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/Kconfig | 12 + - drivers/net/phy/Makefile | 1 + - drivers/net/phy/as21xxx.c | 1087 +++++++++++++++++++++++++++++++++++++ - 3 files changed, 1100 insertions(+) - create mode 100644 drivers/net/phy/as21xxx.c - -diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig -index f7e21a2761b8..01cc31817357 100644 ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -79,6 +79,18 @@ config SFP - - comment "MII PHY device drivers" - -+config AS21XXX_PHY -+ tristate "Aeonsemi AS21xxx PHYs" -+ help -+ Currently supports the Aeonsemi AS21xxx PHY. -+ -+ These are C45 PHYs 10G that require all a generic firmware. -+ -+ Supported PHYs AS21011JB1, AS21011PB1, AS21010JB1, AS21010PB1, -+ AS21511JB1, AS21511PB1, AS21510JB1, AS21510PB1, AS21210JB1, -+ AS21210PB1 that all register with the PHY ID 0x7500 0x7500 -+ before the firmware is loaded. -+ - config AIR_EN8811H_PHY - tristate "Airoha EN8811H 2.5 Gigabit PHY" - help -diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile -index a38b01f74db7..768d1e8ebf80 100644 ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -39,6 +39,7 @@ obj-$(CONFIG_AIR_EN8811H_PHY) += air_en8811h.o - obj-$(CONFIG_AMD_PHY) += amd.o - obj-$(CONFIG_AMCC_QT2025_PHY) += qt2025.o - obj-$(CONFIG_AQUANTIA_PHY) += aquantia/ -+obj-$(CONFIG_AS21XXX_PHY) += as21xxx.o - ifdef CONFIG_AX88796B_RUST_PHY - obj-$(CONFIG_AX88796B_PHY) += ax88796b_rust.o - else -diff --git a/drivers/net/phy/as21xxx.c b/drivers/net/phy/as21xxx.c -new file mode 100644 -index 000000000000..037d79944eca ---- /dev/null -+++ b/drivers/net/phy/as21xxx.c -@@ -0,0 +1,1087 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Aeonsemi AS21XXxX PHY Driver -+ * -+ * Author: Christian Marangi -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define VEND1_GLB_REG_CPU_RESET_ADDR_LO_BASEADDR 0x3 -+#define VEND1_GLB_REG_CPU_RESET_ADDR_HI_BASEADDR 0x4 -+ -+#define VEND1_GLB_REG_CPU_CTRL 0xe -+#define VEND1_GLB_CPU_CTRL_MASK GENMASK(4, 0) -+#define VEND1_GLB_CPU_CTRL_LED_POLARITY_MASK GENMASK(12, 8) -+#define VEND1_GLB_CPU_CTRL_LED_POLARITY(_n) FIELD_PREP(VEND1_GLB_CPU_CTRL_LED_POLARITY_MASK, \ -+ BIT(_n)) -+ -+#define VEND1_FW_START_ADDR 0x100 -+ -+#define VEND1_GLB_REG_MDIO_INDIRECT_ADDRCMD 0x101 -+#define VEND1_GLB_REG_MDIO_INDIRECT_LOAD 0x102 -+ -+#define VEND1_GLB_REG_MDIO_INDIRECT_STATUS 0x103 -+ -+#define VEND1_PTP_CLK 0x142 -+#define VEND1_PTP_CLK_EN BIT(6) -+ -+/* 5 LED at step of 0x20 -+ * FE: Fast-Ethernet (10/100) -+ * GE: Gigabit-Ethernet (1000) -+ * NG: New-Generation (2500/5000/10000) -+ */ -+#define VEND1_LED_REG(_n) (0x1800 + ((_n) * 0x10)) -+#define VEND1_LED_REG_A_EVENT GENMASK(15, 11) -+#define VEND1_LED_CONF 0x1881 -+#define VEND1_LED_CONFG_BLINK GENMASK(7, 0) -+ -+#define VEND1_SPEED_STATUS 0x4002 -+#define VEND1_SPEED_MASK GENMASK(7, 0) -+#define VEND1_SPEED_10000 FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x3) -+#define VEND1_SPEED_5000 FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x5) -+#define VEND1_SPEED_2500 FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x9) -+#define VEND1_SPEED_1000 FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x10) -+#define VEND1_SPEED_100 FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x20) -+#define VEND1_SPEED_10 FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x0) -+ -+#define VEND1_IPC_CMD 0x5801 -+#define AEON_IPC_CMD_PARITY BIT(15) -+#define AEON_IPC_CMD_SIZE GENMASK(10, 6) -+#define AEON_IPC_CMD_OPCODE GENMASK(5, 0) -+ -+#define IPC_CMD_NOOP 0x0 /* Do nothing */ -+#define IPC_CMD_INFO 0x1 /* Get Firmware Version */ -+#define IPC_CMD_SYS_CPU 0x2 /* SYS_CPU */ -+#define IPC_CMD_BULK_DATA 0xa /* Pass bulk data in ipc registers. */ -+#define IPC_CMD_BULK_WRITE 0xc /* Write bulk data to memory */ -+#define IPC_CMD_CFG_PARAM 0x1a /* Write config parameters to memory */ -+#define IPC_CMD_NG_TESTMODE 0x1b /* Set NG test mode and tone */ -+#define IPC_CMD_TEMP_MON 0x15 /* Temperature monitoring function */ -+#define IPC_CMD_SET_LED 0x23 /* Set led */ -+ -+#define VEND1_IPC_STS 0x5802 -+#define AEON_IPC_STS_PARITY BIT(15) -+#define AEON_IPC_STS_SIZE GENMASK(14, 10) -+#define AEON_IPC_STS_OPCODE GENMASK(9, 4) -+#define AEON_IPC_STS_STATUS GENMASK(3, 0) -+#define AEON_IPC_STS_STATUS_RCVD FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0x1) -+#define AEON_IPC_STS_STATUS_PROCESS FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0x2) -+#define AEON_IPC_STS_STATUS_SUCCESS FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0x4) -+#define AEON_IPC_STS_STATUS_ERROR FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0x8) -+#define AEON_IPC_STS_STATUS_BUSY FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0xe) -+#define AEON_IPC_STS_STATUS_READY FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0xf) -+ -+#define VEND1_IPC_DATA0 0x5808 -+#define VEND1_IPC_DATA1 0x5809 -+#define VEND1_IPC_DATA2 0x580a -+#define VEND1_IPC_DATA3 0x580b -+#define VEND1_IPC_DATA4 0x580c -+#define VEND1_IPC_DATA5 0x580d -+#define VEND1_IPC_DATA6 0x580e -+#define VEND1_IPC_DATA7 0x580f -+#define VEND1_IPC_DATA(_n) (VEND1_IPC_DATA0 + (_n)) -+ -+/* Sub command of CMD_INFO */ -+#define IPC_INFO_VERSION 0x1 -+ -+/* Sub command of CMD_SYS_CPU */ -+#define IPC_SYS_CPU_REBOOT 0x3 -+#define IPC_SYS_CPU_IMAGE_OFST 0x4 -+#define IPC_SYS_CPU_IMAGE_CHECK 0x5 -+#define IPC_SYS_CPU_PHY_ENABLE 0x6 -+ -+/* Sub command of CMD_CFG_PARAM */ -+#define IPC_CFG_PARAM_DIRECT 0x4 -+ -+/* CFG DIRECT sub command */ -+#define IPC_CFG_PARAM_DIRECT_NG_PHYCTRL 0x1 -+#define IPC_CFG_PARAM_DIRECT_CU_AN 0x2 -+#define IPC_CFG_PARAM_DIRECT_SDS_PCS 0x3 -+#define IPC_CFG_PARAM_DIRECT_AUTO_EEE 0x4 -+#define IPC_CFG_PARAM_DIRECT_SDS_PMA 0x5 -+#define IPC_CFG_PARAM_DIRECT_DPC_RA 0x6 -+#define IPC_CFG_PARAM_DIRECT_DPC_PKT_CHK 0x7 -+#define IPC_CFG_PARAM_DIRECT_DPC_SDS_WAIT_ETH 0x8 -+#define IPC_CFG_PARAM_DIRECT_WDT 0x9 -+#define IPC_CFG_PARAM_DIRECT_SDS_RESTART_AN 0x10 -+#define IPC_CFG_PARAM_DIRECT_TEMP_MON 0x11 -+#define IPC_CFG_PARAM_DIRECT_WOL 0x12 -+ -+/* Sub command of CMD_TEMP_MON */ -+#define IPC_CMD_TEMP_MON_GET 0x4 -+ -+#define AS21XXX_MDIO_AN_C22 0xffe0 -+ -+#define PHY_ID_AS21XXX 0x75009410 -+/* AS21xxx ID Legend -+ * AS21x1xxB1 -+ * ^ ^^ -+ * | |J: Supports SyncE/PTP -+ * | |P: No SyncE/PTP support -+ * | 1: Supports 2nd Serdes -+ * | 2: Not 2nd Serdes support -+ * 0: 10G, 5G, 2.5G -+ * 5: 5G, 2.5G -+ * 2: 2.5G -+ */ -+#define PHY_ID_AS21011JB1 0x75009402 -+#define PHY_ID_AS21011PB1 0x75009412 -+#define PHY_ID_AS21010JB1 0x75009422 -+#define PHY_ID_AS21010PB1 0x75009432 -+#define PHY_ID_AS21511JB1 0x75009442 -+#define PHY_ID_AS21511PB1 0x75009452 -+#define PHY_ID_AS21510JB1 0x75009462 -+#define PHY_ID_AS21510PB1 0x75009472 -+#define PHY_ID_AS21210JB1 0x75009482 -+#define PHY_ID_AS21210PB1 0x75009492 -+#define PHY_VENDOR_AEONSEMI 0x75009400 -+ -+#define AEON_MAX_LEDS 5 -+#define AEON_IPC_DELAY 10000 -+#define AEON_IPC_TIMEOUT (AEON_IPC_DELAY * 100) -+#define AEON_IPC_DATA_NUM_REGISTERS 8 -+#define AEON_IPC_DATA_MAX (AEON_IPC_DATA_NUM_REGISTERS * sizeof(u16)) -+ -+#define AEON_BOOT_ADDR 0x1000 -+#define AEON_CPU_BOOT_ADDR 0x2000 -+#define AEON_CPU_CTRL_FW_LOAD (BIT(4) | BIT(2) | BIT(1) | BIT(0)) -+#define AEON_CPU_CTRL_FW_START BIT(0) -+ -+enum as21xxx_led_event { -+ VEND1_LED_REG_A_EVENT_ON_10 = 0x0, -+ VEND1_LED_REG_A_EVENT_ON_100, -+ VEND1_LED_REG_A_EVENT_ON_1000, -+ VEND1_LED_REG_A_EVENT_ON_2500, -+ VEND1_LED_REG_A_EVENT_ON_5000, -+ VEND1_LED_REG_A_EVENT_ON_10000, -+ VEND1_LED_REG_A_EVENT_ON_FE_GE, -+ VEND1_LED_REG_A_EVENT_ON_NG, -+ VEND1_LED_REG_A_EVENT_ON_FULL_DUPLEX, -+ VEND1_LED_REG_A_EVENT_ON_COLLISION, -+ VEND1_LED_REG_A_EVENT_BLINK_TX, -+ VEND1_LED_REG_A_EVENT_BLINK_RX, -+ VEND1_LED_REG_A_EVENT_BLINK_ACT, -+ VEND1_LED_REG_A_EVENT_ON_LINK, -+ VEND1_LED_REG_A_EVENT_ON_LINK_BLINK_ACT, -+ VEND1_LED_REG_A_EVENT_ON_LINK_BLINK_RX, -+ VEND1_LED_REG_A_EVENT_ON_FE_GE_BLINK_ACT, -+ VEND1_LED_REG_A_EVENT_ON_NG_BLINK_ACT, -+ VEND1_LED_REG_A_EVENT_ON_NG_BLINK_FE_GE, -+ VEND1_LED_REG_A_EVENT_ON_FD_BLINK_COLLISION, -+ VEND1_LED_REG_A_EVENT_ON, -+ VEND1_LED_REG_A_EVENT_OFF, -+}; -+ -+struct as21xxx_led_pattern_info { -+ unsigned int pattern; -+ u16 val; -+}; -+ -+struct as21xxx_priv { -+ bool parity_status; -+ /* Protect concurrent IPC access */ -+ struct mutex ipc_lock; -+}; -+ -+static struct as21xxx_led_pattern_info as21xxx_led_supported_pattern[] = { -+ { -+ .pattern = BIT(TRIGGER_NETDEV_LINK_10), -+ .val = VEND1_LED_REG_A_EVENT_ON_10 -+ }, -+ { -+ .pattern = BIT(TRIGGER_NETDEV_LINK_100), -+ .val = VEND1_LED_REG_A_EVENT_ON_100 -+ }, -+ { -+ .pattern = BIT(TRIGGER_NETDEV_LINK_1000), -+ .val = VEND1_LED_REG_A_EVENT_ON_1000 -+ }, -+ { -+ .pattern = BIT(TRIGGER_NETDEV_LINK_2500), -+ .val = VEND1_LED_REG_A_EVENT_ON_2500 -+ }, -+ { -+ .pattern = BIT(TRIGGER_NETDEV_LINK_5000), -+ .val = VEND1_LED_REG_A_EVENT_ON_5000 -+ }, -+ { -+ .pattern = BIT(TRIGGER_NETDEV_LINK_10000), -+ .val = VEND1_LED_REG_A_EVENT_ON_10000 -+ }, -+ { -+ .pattern = BIT(TRIGGER_NETDEV_LINK), -+ .val = VEND1_LED_REG_A_EVENT_ON_LINK -+ }, -+ { -+ .pattern = BIT(TRIGGER_NETDEV_LINK_10) | -+ BIT(TRIGGER_NETDEV_LINK_100) | -+ BIT(TRIGGER_NETDEV_LINK_1000), -+ .val = VEND1_LED_REG_A_EVENT_ON_FE_GE -+ }, -+ { -+ .pattern = BIT(TRIGGER_NETDEV_LINK_2500) | -+ BIT(TRIGGER_NETDEV_LINK_5000) | -+ BIT(TRIGGER_NETDEV_LINK_10000), -+ .val = VEND1_LED_REG_A_EVENT_ON_NG -+ }, -+ { -+ .pattern = BIT(TRIGGER_NETDEV_FULL_DUPLEX), -+ .val = VEND1_LED_REG_A_EVENT_ON_FULL_DUPLEX -+ }, -+ { -+ .pattern = BIT(TRIGGER_NETDEV_TX), -+ .val = VEND1_LED_REG_A_EVENT_BLINK_TX -+ }, -+ { -+ .pattern = BIT(TRIGGER_NETDEV_RX), -+ .val = VEND1_LED_REG_A_EVENT_BLINK_RX -+ }, -+ { -+ .pattern = BIT(TRIGGER_NETDEV_TX) | -+ BIT(TRIGGER_NETDEV_RX), -+ .val = VEND1_LED_REG_A_EVENT_BLINK_ACT -+ }, -+ { -+ .pattern = BIT(TRIGGER_NETDEV_LINK_10) | -+ BIT(TRIGGER_NETDEV_LINK_100) | -+ BIT(TRIGGER_NETDEV_LINK_1000) | -+ BIT(TRIGGER_NETDEV_LINK_2500) | -+ BIT(TRIGGER_NETDEV_LINK_5000) | -+ BIT(TRIGGER_NETDEV_LINK_10000), -+ .val = VEND1_LED_REG_A_EVENT_ON_LINK -+ }, -+ { -+ .pattern = BIT(TRIGGER_NETDEV_LINK_10) | -+ BIT(TRIGGER_NETDEV_LINK_100) | -+ BIT(TRIGGER_NETDEV_LINK_1000) | -+ BIT(TRIGGER_NETDEV_LINK_2500) | -+ BIT(TRIGGER_NETDEV_LINK_5000) | -+ BIT(TRIGGER_NETDEV_LINK_10000) | -+ BIT(TRIGGER_NETDEV_TX) | -+ BIT(TRIGGER_NETDEV_RX), -+ .val = VEND1_LED_REG_A_EVENT_ON_LINK_BLINK_ACT -+ }, -+ { -+ .pattern = BIT(TRIGGER_NETDEV_LINK_10) | -+ BIT(TRIGGER_NETDEV_LINK_100) | -+ BIT(TRIGGER_NETDEV_LINK_1000) | -+ BIT(TRIGGER_NETDEV_LINK_2500) | -+ BIT(TRIGGER_NETDEV_LINK_5000) | -+ BIT(TRIGGER_NETDEV_LINK_10000) | -+ BIT(TRIGGER_NETDEV_RX), -+ .val = VEND1_LED_REG_A_EVENT_ON_LINK_BLINK_RX -+ }, -+ { -+ .pattern = BIT(TRIGGER_NETDEV_LINK_10) | -+ BIT(TRIGGER_NETDEV_LINK_100) | -+ BIT(TRIGGER_NETDEV_LINK_1000) | -+ BIT(TRIGGER_NETDEV_TX) | -+ BIT(TRIGGER_NETDEV_RX), -+ .val = VEND1_LED_REG_A_EVENT_ON_FE_GE_BLINK_ACT -+ }, -+ { -+ .pattern = BIT(TRIGGER_NETDEV_LINK_2500) | -+ BIT(TRIGGER_NETDEV_LINK_5000) | -+ BIT(TRIGGER_NETDEV_LINK_10000) | -+ BIT(TRIGGER_NETDEV_TX) | -+ BIT(TRIGGER_NETDEV_RX), -+ .val = VEND1_LED_REG_A_EVENT_ON_NG_BLINK_ACT -+ } -+}; -+ -+static int aeon_firmware_boot(struct phy_device *phydev, const u8 *data, -+ size_t size) -+{ -+ int i, ret; -+ u16 val; -+ -+ ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLB_REG_CPU_CTRL, -+ VEND1_GLB_CPU_CTRL_MASK, AEON_CPU_CTRL_FW_LOAD); -+ if (ret) -+ return ret; -+ -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_FW_START_ADDR, -+ AEON_BOOT_ADDR); -+ if (ret) -+ return ret; -+ -+ ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, -+ VEND1_GLB_REG_MDIO_INDIRECT_ADDRCMD, -+ 0x3ffc, 0xc000); -+ if (ret) -+ return ret; -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, -+ VEND1_GLB_REG_MDIO_INDIRECT_STATUS); -+ if (val > 1) { -+ phydev_err(phydev, "wrong origin mdio_indirect_status: %x\n", val); -+ return -EINVAL; -+ } -+ -+ /* Firmware is always aligned to u16 */ -+ for (i = 0; i < size; i += 2) { -+ val = data[i + 1] << 8 | data[i]; -+ -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, -+ VEND1_GLB_REG_MDIO_INDIRECT_LOAD, val); -+ if (ret) -+ return ret; -+ } -+ -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, -+ VEND1_GLB_REG_CPU_RESET_ADDR_LO_BASEADDR, -+ lower_16_bits(AEON_CPU_BOOT_ADDR)); -+ if (ret) -+ return ret; -+ -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, -+ VEND1_GLB_REG_CPU_RESET_ADDR_HI_BASEADDR, -+ upper_16_bits(AEON_CPU_BOOT_ADDR)); -+ if (ret) -+ return ret; -+ -+ return phy_modify_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLB_REG_CPU_CTRL, -+ VEND1_GLB_CPU_CTRL_MASK, AEON_CPU_CTRL_FW_START); -+} -+ -+static int aeon_firmware_load(struct phy_device *phydev) -+{ -+ struct device *dev = &phydev->mdio.dev; -+ const struct firmware *fw; -+ const char *fw_name; -+ int ret; -+ -+ ret = of_property_read_string(dev->of_node, "firmware-name", -+ &fw_name); -+ if (ret) -+ return ret; -+ -+ ret = request_firmware(&fw, fw_name, dev); -+ if (ret) { -+ phydev_err(phydev, "failed to find FW file %s (%d)\n", -+ fw_name, ret); -+ return ret; -+ } -+ -+ ret = aeon_firmware_boot(phydev, fw->data, fw->size); -+ -+ release_firmware(fw); -+ -+ return ret; -+} -+ -+static bool aeon_ipc_ready(u16 val, bool parity_status) -+{ -+ u16 status; -+ -+ if (FIELD_GET(AEON_IPC_STS_PARITY, val) != parity_status) -+ return false; -+ -+ status = val & AEON_IPC_STS_STATUS; -+ -+ return status != AEON_IPC_STS_STATUS_RCVD && -+ status != AEON_IPC_STS_STATUS_PROCESS && -+ status != AEON_IPC_STS_STATUS_BUSY; -+} -+ -+static int aeon_ipc_wait_cmd(struct phy_device *phydev, bool parity_status) -+{ -+ u16 val; -+ -+ /* Exit condition logic: -+ * - Wait for parity bit equal -+ * - Wait for status success, error OR ready -+ */ -+ return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, VEND1_IPC_STS, val, -+ aeon_ipc_ready(val, parity_status), -+ AEON_IPC_DELAY, AEON_IPC_TIMEOUT, false); -+} -+ -+static int aeon_ipc_send_cmd(struct phy_device *phydev, -+ struct as21xxx_priv *priv, -+ u16 cmd, u16 *ret_sts) -+{ -+ bool curr_parity; -+ int ret; -+ -+ /* The IPC sync by using a single parity bit. -+ * Each CMD have alternately this bit set or clear -+ * to understand correct flow and packet order. -+ */ -+ curr_parity = priv->parity_status; -+ if (priv->parity_status) -+ cmd |= AEON_IPC_CMD_PARITY; -+ -+ /* Always update parity for next packet */ -+ priv->parity_status = !priv->parity_status; -+ -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_IPC_CMD, cmd); -+ if (ret) -+ return ret; -+ -+ /* Wait for packet to be processed */ -+ usleep_range(AEON_IPC_DELAY, AEON_IPC_DELAY + 5000); -+ -+ /* With no ret_sts, ignore waiting for packet completion -+ * (ipc parity bit sync) -+ */ -+ if (!ret_sts) -+ return 0; -+ -+ ret = aeon_ipc_wait_cmd(phydev, curr_parity); -+ if (ret) -+ return ret; -+ -+ ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_IPC_STS); -+ if (ret < 0) -+ return ret; -+ -+ *ret_sts = ret; -+ if ((*ret_sts & AEON_IPC_STS_STATUS) != AEON_IPC_STS_STATUS_SUCCESS) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+/* If data is NULL, return 0 or negative error. -+ * If data not NULL, return number of Bytes received from IPC or -+ * a negative error. -+ */ -+static int aeon_ipc_send_msg(struct phy_device *phydev, -+ u16 opcode, u16 *data, unsigned int data_len, -+ u16 *ret_data) -+{ -+ struct as21xxx_priv *priv = phydev->priv; -+ unsigned int ret_size; -+ u16 cmd, ret_sts; -+ int ret; -+ int i; -+ -+ /* IPC have a max of 8 register to transfer data, -+ * make sure we never exceed this. -+ */ -+ if (data_len > AEON_IPC_DATA_MAX) -+ return -EINVAL; -+ -+ for (i = 0; i < data_len / sizeof(u16); i++) -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_IPC_DATA(i), -+ data[i]); -+ -+ cmd = FIELD_PREP(AEON_IPC_CMD_SIZE, data_len) | -+ FIELD_PREP(AEON_IPC_CMD_OPCODE, opcode); -+ -+ mutex_lock(&priv->ipc_lock); -+ -+ ret = aeon_ipc_send_cmd(phydev, priv, cmd, &ret_sts); -+ if (ret) { -+ phydev_err(phydev, "failed to send ipc msg for %x: %d\n", -+ opcode, ret); -+ goto out; -+ } -+ -+ if (!data) -+ goto out; -+ -+ if ((ret_sts & AEON_IPC_STS_STATUS) == AEON_IPC_STS_STATUS_ERROR) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ /* Prevent IPC from stack smashing the kernel. -+ * We can't trust IPC to return a good value and we always -+ * preallocate space for 16 Bytes. -+ */ -+ ret_size = FIELD_GET(AEON_IPC_STS_SIZE, ret_sts); -+ if (ret_size > AEON_IPC_DATA_MAX) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ /* Read data from IPC data register for ret_size value from IPC */ -+ for (i = 0; i < DIV_ROUND_UP(ret_size, sizeof(u16)); i++) { -+ ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_IPC_DATA(i)); -+ if (ret < 0) -+ goto out; -+ -+ ret_data[i] = ret; -+ } -+ -+ ret = ret_size; -+ -+out: -+ mutex_unlock(&priv->ipc_lock); -+ -+ return ret; -+} -+ -+static int aeon_ipc_noop(struct phy_device *phydev, -+ struct as21xxx_priv *priv, u16 *ret_sts) -+{ -+ u16 cmd; -+ -+ cmd = FIELD_PREP(AEON_IPC_CMD_SIZE, 0) | -+ FIELD_PREP(AEON_IPC_CMD_OPCODE, IPC_CMD_NOOP); -+ -+ return aeon_ipc_send_cmd(phydev, priv, cmd, ret_sts); -+} -+ -+/* Logic to sync parity bit with IPC. -+ * We send 2 NOP cmd with same partity and we wait for IPC -+ * to handle the packet only for the second one. This way -+ * we make sure we are sync for every next cmd. -+ */ -+static int aeon_ipc_sync_parity(struct phy_device *phydev, -+ struct as21xxx_priv *priv) -+{ -+ u16 ret_sts; -+ int ret; -+ -+ mutex_lock(&priv->ipc_lock); -+ -+ /* Send NOP with no parity */ -+ aeon_ipc_noop(phydev, priv, NULL); -+ -+ /* Reset packet parity */ -+ priv->parity_status = false; -+ -+ /* Send second NOP with no parity */ -+ ret = aeon_ipc_noop(phydev, priv, &ret_sts); -+ -+ mutex_unlock(&priv->ipc_lock); -+ -+ /* We expect to return -EINVAL */ -+ if (ret != -EINVAL) -+ return ret; -+ -+ if ((ret_sts & AEON_IPC_STS_STATUS) != AEON_IPC_STS_STATUS_READY) { -+ phydev_err(phydev, "Invalid IPC status on sync parity: %x\n", -+ ret_sts); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int aeon_ipc_get_fw_version(struct phy_device *phydev) -+{ -+ u16 ret_data[AEON_IPC_DATA_NUM_REGISTERS], data[1]; -+ char fw_version[AEON_IPC_DATA_MAX + 1]; -+ int ret; -+ -+ data[0] = IPC_INFO_VERSION; -+ -+ ret = aeon_ipc_send_msg(phydev, IPC_CMD_INFO, data, -+ sizeof(data), ret_data); -+ if (ret < 0) -+ return ret; -+ -+ /* Make sure FW version is NULL terminated */ -+ memcpy(fw_version, ret_data, ret); -+ fw_version[ret] = '\0'; -+ -+ phydev_info(phydev, "Firmware Version: %s\n", fw_version); -+ -+ return 0; -+} -+ -+static int aeon_dpc_ra_enable(struct phy_device *phydev) -+{ -+ u16 data[2]; -+ -+ data[0] = IPC_CFG_PARAM_DIRECT; -+ data[1] = IPC_CFG_PARAM_DIRECT_DPC_RA; -+ -+ return aeon_ipc_send_msg(phydev, IPC_CMD_CFG_PARAM, data, -+ sizeof(data), NULL); -+} -+ -+static int as21xxx_probe(struct phy_device *phydev) -+{ -+ struct as21xxx_priv *priv; -+ int ret; -+ -+ priv = devm_kzalloc(&phydev->mdio.dev, -+ sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ phydev->priv = priv; -+ -+ ret = devm_mutex_init(&phydev->mdio.dev, -+ &priv->ipc_lock); -+ if (ret) -+ return ret; -+ -+ ret = aeon_ipc_sync_parity(phydev, priv); -+ if (ret) -+ return ret; -+ -+ ret = aeon_ipc_get_fw_version(phydev); -+ if (ret) -+ return ret; -+ -+ /* Enable PTP clk if not already Enabled */ -+ ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_PTP_CLK, -+ VEND1_PTP_CLK_EN); -+ if (ret) -+ return ret; -+ -+ return aeon_dpc_ra_enable(phydev); -+} -+ -+static int as21xxx_read_link(struct phy_device *phydev, int *bmcr) -+{ -+ int status; -+ -+ /* Normal C22 BMCR report inconsistent data, use -+ * the mapped C22 in C45 to have more consistent link info. -+ */ -+ *bmcr = phy_read_mmd(phydev, MDIO_MMD_AN, -+ AS21XXX_MDIO_AN_C22 + MII_BMCR); -+ if (*bmcr < 0) -+ return *bmcr; -+ -+ /* Autoneg is being started, therefore disregard current -+ * link status and report link as down. -+ */ -+ if (*bmcr & BMCR_ANRESTART) { -+ phydev->link = 0; -+ return 0; -+ } -+ -+ status = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1); -+ if (status < 0) -+ return status; -+ -+ phydev->link = !!(status & MDIO_STAT1_LSTATUS); -+ -+ return 0; -+} -+ -+static int as21xxx_read_c22_lpa(struct phy_device *phydev) -+{ -+ int lpagb; -+ -+ /* MII_STAT1000 are only filled in the mapped C22 -+ * in C45, use that to fill lpagb values and check. -+ */ -+ lpagb = phy_read_mmd(phydev, MDIO_MMD_AN, -+ AS21XXX_MDIO_AN_C22 + MII_STAT1000); -+ if (lpagb < 0) -+ return lpagb; -+ -+ if (lpagb & LPA_1000MSFAIL) { -+ int adv = phy_read_mmd(phydev, MDIO_MMD_AN, -+ AS21XXX_MDIO_AN_C22 + MII_CTRL1000); -+ -+ if (adv < 0) -+ return adv; -+ -+ if (adv & CTL1000_ENABLE_MASTER) -+ phydev_err(phydev, "Master/Slave resolution failed, maybe conflicting manual settings?\n"); -+ else -+ phydev_err(phydev, "Master/Slave resolution failed\n"); -+ return -ENOLINK; -+ } -+ -+ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, -+ lpagb); -+ -+ return 0; -+} -+ -+static int as21xxx_read_status(struct phy_device *phydev) -+{ -+ int bmcr, old_link = phydev->link; -+ int ret; -+ -+ ret = as21xxx_read_link(phydev, &bmcr); -+ if (ret) -+ return ret; -+ -+ /* why bother the PHY if nothing can have changed */ -+ if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link) -+ return 0; -+ -+ phydev->speed = SPEED_UNKNOWN; -+ phydev->duplex = DUPLEX_UNKNOWN; -+ phydev->pause = 0; -+ phydev->asym_pause = 0; -+ -+ if (phydev->autoneg == AUTONEG_ENABLE) { -+ ret = genphy_c45_read_lpa(phydev); -+ if (ret) -+ return ret; -+ -+ ret = as21xxx_read_c22_lpa(phydev); -+ if (ret) -+ return ret; -+ -+ phy_resolve_aneg_linkmode(phydev); -+ } else { -+ int speed; -+ -+ linkmode_zero(phydev->lp_advertising); -+ -+ speed = phy_read_mmd(phydev, MDIO_MMD_VEND1, -+ VEND1_SPEED_STATUS); -+ if (speed < 0) -+ return speed; -+ -+ switch (speed & VEND1_SPEED_STATUS) { -+ case VEND1_SPEED_10000: -+ phydev->speed = SPEED_10000; -+ phydev->duplex = DUPLEX_FULL; -+ break; -+ case VEND1_SPEED_5000: -+ phydev->speed = SPEED_5000; -+ phydev->duplex = DUPLEX_FULL; -+ break; -+ case VEND1_SPEED_2500: -+ phydev->speed = SPEED_2500; -+ phydev->duplex = DUPLEX_FULL; -+ break; -+ case VEND1_SPEED_1000: -+ phydev->speed = SPEED_1000; -+ if (bmcr & BMCR_FULLDPLX) -+ phydev->duplex = DUPLEX_FULL; -+ else -+ phydev->duplex = DUPLEX_HALF; -+ break; -+ case VEND1_SPEED_100: -+ phydev->speed = SPEED_100; -+ phydev->duplex = DUPLEX_FULL; -+ break; -+ case VEND1_SPEED_10: -+ phydev->speed = SPEED_10; -+ phydev->duplex = DUPLEX_FULL; -+ break; -+ default: -+ return -EINVAL; -+ } -+ } -+ -+ return 0; -+} -+ -+static int as21xxx_led_brightness_set(struct phy_device *phydev, -+ u8 index, enum led_brightness value) -+{ -+ u16 val = VEND1_LED_REG_A_EVENT_OFF; -+ -+ if (index > AEON_MAX_LEDS) -+ return -EINVAL; -+ -+ if (value) -+ val = VEND1_LED_REG_A_EVENT_ON; -+ -+ return phy_modify_mmd(phydev, MDIO_MMD_VEND1, -+ VEND1_LED_REG(index), -+ VEND1_LED_REG_A_EVENT, -+ FIELD_PREP(VEND1_LED_REG_A_EVENT, val)); -+} -+ -+static int as21xxx_led_hw_is_supported(struct phy_device *phydev, u8 index, -+ unsigned long rules) -+{ -+ int i; -+ -+ if (index > AEON_MAX_LEDS) -+ return -EINVAL; -+ -+ for (i = 0; i < ARRAY_SIZE(as21xxx_led_supported_pattern); i++) -+ if (rules == as21xxx_led_supported_pattern[i].pattern) -+ return 0; -+ -+ return -EOPNOTSUPP; -+} -+ -+static int as21xxx_led_hw_control_get(struct phy_device *phydev, u8 index, -+ unsigned long *rules) -+{ -+ int i, val; -+ -+ if (index > AEON_MAX_LEDS) -+ return -EINVAL; -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_LED_REG(index)); -+ if (val < 0) -+ return val; -+ -+ val = FIELD_GET(VEND1_LED_REG_A_EVENT, val); -+ for (i = 0; i < ARRAY_SIZE(as21xxx_led_supported_pattern); i++) -+ if (val == as21xxx_led_supported_pattern[i].val) { -+ *rules = as21xxx_led_supported_pattern[i].pattern; -+ return 0; -+ } -+ -+ /* Should be impossible */ -+ return -EINVAL; -+} -+ -+static int as21xxx_led_hw_control_set(struct phy_device *phydev, u8 index, -+ unsigned long rules) -+{ -+ u16 val = 0; -+ int i; -+ -+ if (index > AEON_MAX_LEDS) -+ return -EINVAL; -+ -+ for (i = 0; i < ARRAY_SIZE(as21xxx_led_supported_pattern); i++) -+ if (rules == as21xxx_led_supported_pattern[i].pattern) { -+ val = as21xxx_led_supported_pattern[i].val; -+ break; -+ } -+ -+ return phy_modify_mmd(phydev, MDIO_MMD_VEND1, -+ VEND1_LED_REG(index), -+ VEND1_LED_REG_A_EVENT, -+ FIELD_PREP(VEND1_LED_REG_A_EVENT, val)); -+} -+ -+static int as21xxx_led_polarity_set(struct phy_device *phydev, int index, -+ unsigned long modes) -+{ -+ bool led_active_low = false; -+ u16 mask, val = 0; -+ u32 mode; -+ -+ if (index > AEON_MAX_LEDS) -+ return -EINVAL; -+ -+ for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) { -+ switch (mode) { -+ case PHY_LED_ACTIVE_LOW: -+ led_active_low = true; -+ break; -+ case PHY_LED_ACTIVE_HIGH: /* default mode */ -+ led_active_low = false; -+ break; -+ default: -+ return -EINVAL; -+ } -+ } -+ -+ mask = VEND1_GLB_CPU_CTRL_LED_POLARITY(index); -+ if (led_active_low) -+ val = VEND1_GLB_CPU_CTRL_LED_POLARITY(index); -+ -+ return phy_modify_mmd(phydev, MDIO_MMD_VEND1, -+ VEND1_GLB_REG_CPU_CTRL, -+ mask, val); -+} -+ -+static int as21xxx_match_phy_device(struct phy_device *phydev, -+ const struct phy_driver *phydrv) -+{ -+ struct as21xxx_priv *priv; -+ u16 ret_sts; -+ u32 phy_id; -+ int ret; -+ -+ /* Skip PHY that are not AS21xxx or already have firmware loaded */ -+ if (phydev->c45_ids.device_ids[MDIO_MMD_PCS] != PHY_ID_AS21XXX) -+ return genphy_match_phy_device(phydev, (struct phy_driver *)phydrv); -+ -+ /* Read PHY ID to handle firmware just loaded */ -+ ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MII_PHYSID1); -+ if (ret < 0) -+ return ret; -+ phy_id = ret << 16; -+ -+ ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MII_PHYSID2); -+ if (ret < 0) -+ return ret; -+ phy_id |= ret; -+ -+ /* With PHY ID not the generic AS21xxx one assume -+ * the firmware just loaded -+ */ -+ if (phy_id != PHY_ID_AS21XXX) -+ return phy_id == phydrv->phy_id; -+ -+ /* Allocate temp priv and load the firmware */ -+ priv = kzalloc(sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ mutex_init(&priv->ipc_lock); -+ -+ ret = aeon_firmware_load(phydev); -+ if (ret) -+ goto out; -+ -+ /* Sync parity... */ -+ ret = aeon_ipc_sync_parity(phydev, priv); -+ if (ret) -+ goto out; -+ -+ /* ...and send a third NOOP cmd to wait for firmware finish loading */ -+ ret = aeon_ipc_noop(phydev, priv, &ret_sts); -+ if (ret) -+ goto out; -+ -+out: -+ mutex_destroy(&priv->ipc_lock); -+ kfree(priv); -+ -+ /* Return can either be 0 or a negative error code. -+ * Returning 0 here means THIS is NOT a suitable PHY. -+ * -+ * For the specific case of the generic Aeonsemi PHY ID that -+ * needs the firmware the be loaded first to have a correct PHY ID, -+ * this is OK as a matching PHY ID will be found right after. -+ * This relies on the driver probe order where the first PHY driver -+ * probed is the generic one. -+ */ -+ return ret; -+} -+ -+static struct phy_driver as21xxx_drivers[] = { -+ { -+ /* PHY expose in C45 as 0x7500 0x9410 -+ * before firmware is loaded. -+ * This driver entry must be attempted first to load -+ * the firmware and thus update the ID registers. -+ */ -+ PHY_ID_MATCH_EXACT(PHY_ID_AS21XXX), -+ .name = "Aeonsemi AS21xxx", -+ .match_phy_device = as21xxx_match_phy_device, -+ }, -+ { -+ PHY_ID_MATCH_EXACT(PHY_ID_AS21011JB1), -+ .name = "Aeonsemi AS21011JB1", -+ .probe = as21xxx_probe, -+ .match_phy_device = as21xxx_match_phy_device, -+ .read_status = as21xxx_read_status, -+ .led_brightness_set = as21xxx_led_brightness_set, -+ .led_hw_is_supported = as21xxx_led_hw_is_supported, -+ .led_hw_control_set = as21xxx_led_hw_control_set, -+ .led_hw_control_get = as21xxx_led_hw_control_get, -+ .led_polarity_set = as21xxx_led_polarity_set, -+ }, -+ { -+ PHY_ID_MATCH_EXACT(PHY_ID_AS21011PB1), -+ .name = "Aeonsemi AS21011PB1", -+ .probe = as21xxx_probe, -+ .match_phy_device = as21xxx_match_phy_device, -+ .read_status = as21xxx_read_status, -+ .led_brightness_set = as21xxx_led_brightness_set, -+ .led_hw_is_supported = as21xxx_led_hw_is_supported, -+ .led_hw_control_set = as21xxx_led_hw_control_set, -+ .led_hw_control_get = as21xxx_led_hw_control_get, -+ .led_polarity_set = as21xxx_led_polarity_set, -+ }, -+ { -+ PHY_ID_MATCH_EXACT(PHY_ID_AS21010PB1), -+ .name = "Aeonsemi AS21010PB1", -+ .probe = as21xxx_probe, -+ .match_phy_device = as21xxx_match_phy_device, -+ .read_status = as21xxx_read_status, -+ .led_brightness_set = as21xxx_led_brightness_set, -+ .led_hw_is_supported = as21xxx_led_hw_is_supported, -+ .led_hw_control_set = as21xxx_led_hw_control_set, -+ .led_hw_control_get = as21xxx_led_hw_control_get, -+ .led_polarity_set = as21xxx_led_polarity_set, -+ }, -+ { -+ PHY_ID_MATCH_EXACT(PHY_ID_AS21010JB1), -+ .name = "Aeonsemi AS21010JB1", -+ .probe = as21xxx_probe, -+ .match_phy_device = as21xxx_match_phy_device, -+ .read_status = as21xxx_read_status, -+ .led_brightness_set = as21xxx_led_brightness_set, -+ .led_hw_is_supported = as21xxx_led_hw_is_supported, -+ .led_hw_control_set = as21xxx_led_hw_control_set, -+ .led_hw_control_get = as21xxx_led_hw_control_get, -+ .led_polarity_set = as21xxx_led_polarity_set, -+ }, -+ { -+ PHY_ID_MATCH_EXACT(PHY_ID_AS21210PB1), -+ .name = "Aeonsemi AS21210PB1", -+ .probe = as21xxx_probe, -+ .match_phy_device = as21xxx_match_phy_device, -+ .read_status = as21xxx_read_status, -+ .led_brightness_set = as21xxx_led_brightness_set, -+ .led_hw_is_supported = as21xxx_led_hw_is_supported, -+ .led_hw_control_set = as21xxx_led_hw_control_set, -+ .led_hw_control_get = as21xxx_led_hw_control_get, -+ .led_polarity_set = as21xxx_led_polarity_set, -+ }, -+ { -+ PHY_ID_MATCH_EXACT(PHY_ID_AS21510JB1), -+ .name = "Aeonsemi AS21510JB1", -+ .probe = as21xxx_probe, -+ .match_phy_device = as21xxx_match_phy_device, -+ .read_status = as21xxx_read_status, -+ .led_brightness_set = as21xxx_led_brightness_set, -+ .led_hw_is_supported = as21xxx_led_hw_is_supported, -+ .led_hw_control_set = as21xxx_led_hw_control_set, -+ .led_hw_control_get = as21xxx_led_hw_control_get, -+ .led_polarity_set = as21xxx_led_polarity_set, -+ }, -+ { -+ PHY_ID_MATCH_EXACT(PHY_ID_AS21510PB1), -+ .name = "Aeonsemi AS21510PB1", -+ .probe = as21xxx_probe, -+ .match_phy_device = as21xxx_match_phy_device, -+ .read_status = as21xxx_read_status, -+ .led_brightness_set = as21xxx_led_brightness_set, -+ .led_hw_is_supported = as21xxx_led_hw_is_supported, -+ .led_hw_control_set = as21xxx_led_hw_control_set, -+ .led_hw_control_get = as21xxx_led_hw_control_get, -+ .led_polarity_set = as21xxx_led_polarity_set, -+ }, -+ { -+ PHY_ID_MATCH_EXACT(PHY_ID_AS21511JB1), -+ .name = "Aeonsemi AS21511JB1", -+ .probe = as21xxx_probe, -+ .match_phy_device = as21xxx_match_phy_device, -+ .read_status = as21xxx_read_status, -+ .led_brightness_set = as21xxx_led_brightness_set, -+ .led_hw_is_supported = as21xxx_led_hw_is_supported, -+ .led_hw_control_set = as21xxx_led_hw_control_set, -+ .led_hw_control_get = as21xxx_led_hw_control_get, -+ .led_polarity_set = as21xxx_led_polarity_set, -+ }, -+ { -+ PHY_ID_MATCH_EXACT(PHY_ID_AS21210JB1), -+ .name = "Aeonsemi AS21210JB1", -+ .probe = as21xxx_probe, -+ .match_phy_device = as21xxx_match_phy_device, -+ .read_status = as21xxx_read_status, -+ .led_brightness_set = as21xxx_led_brightness_set, -+ .led_hw_is_supported = as21xxx_led_hw_is_supported, -+ .led_hw_control_set = as21xxx_led_hw_control_set, -+ .led_hw_control_get = as21xxx_led_hw_control_get, -+ .led_polarity_set = as21xxx_led_polarity_set, -+ }, -+ { -+ PHY_ID_MATCH_EXACT(PHY_ID_AS21511PB1), -+ .name = "Aeonsemi AS21511PB1", -+ .probe = as21xxx_probe, -+ .match_phy_device = as21xxx_match_phy_device, -+ .read_status = as21xxx_read_status, -+ .led_brightness_set = as21xxx_led_brightness_set, -+ .led_hw_is_supported = as21xxx_led_hw_is_supported, -+ .led_hw_control_set = as21xxx_led_hw_control_set, -+ .led_hw_control_get = as21xxx_led_hw_control_get, -+ .led_polarity_set = as21xxx_led_polarity_set, -+ }, -+}; -+module_phy_driver(as21xxx_drivers); -+ -+static struct mdio_device_id __maybe_unused as21xxx_tbl[] = { -+ { PHY_ID_MATCH_VENDOR(PHY_VENDOR_AEONSEMI) }, -+ { } -+}; -+MODULE_DEVICE_TABLE(mdio, as21xxx_tbl); -+ -+MODULE_DESCRIPTION("Aeonsemi AS21xxx PHY driver"); -+MODULE_AUTHOR("Christian Marangi "); -+MODULE_LICENSE("GPL"); --- -2.51.0 - - -From 1eef9ac782f05b464534e831280399d76c3eba32 Mon Sep 17 00:00:00 2001 -From: Linus Walleij -Date: Wed, 13 Aug 2025 23:43:03 +0200 -Subject: [PATCH 166/517] net: dsa: Move KS8995 to the DSA subsystem - -By reading the datasheets for the KS8995 it is obvious that this -is a 100 Mbit DSA switch. - -Let us start the refactoring by moving it to the DSA subsystem to -preserve development history. - -Verified that the chip still probes the same after this patch -provided CONFIG_HAVE_NET_DSA, CONFIG_NET_DSA and CONFIG_DSA_KS8995 -are selected. - -Signed-off-by: Linus Walleij -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/20250813-ks8995-to-dsa-v1-1-75c359ede3a5@linaro.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/Kconfig | 7 +++++++ - drivers/net/dsa/Makefile | 1 + - drivers/net/{phy/spi_ks8995.c => dsa/ks8995.c} | 0 - drivers/net/phy/Kconfig | 4 ---- - drivers/net/phy/Makefile | 1 - - 5 files changed, 8 insertions(+), 5 deletions(-) - rename drivers/net/{phy/spi_ks8995.c => dsa/ks8995.c} (100%) - -diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig -index 2d10b4d6cfbb..4367cbdb92d5 100644 ---- a/drivers/net/dsa/Kconfig -+++ b/drivers/net/dsa/Kconfig -@@ -98,6 +98,13 @@ config NET_DSA_RZN1_A5PSW - This driver supports the A5PSW switch, which is embedded in Renesas - RZ/N1 SoC. - -+config NET_DSA_KS8995 -+ tristate "Micrel KS8995 family 5-ports 10/100 Ethernet switches" -+ depends on SPI -+ help -+ This driver supports the Micrel KS8995 family of 10/100 Mbit ethernet -+ switches, managed over SPI. -+ - config NET_DSA_SMSC_LAN9303 - tristate - select NET_DSA_TAG_LAN9303 -diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile -index cb9a97340e58..23dbdf1a36a8 100644 ---- a/drivers/net/dsa/Makefile -+++ b/drivers/net/dsa/Makefile -@@ -5,6 +5,7 @@ obj-$(CONFIG_NET_DSA_LOOP) += dsa_loop.o - ifdef CONFIG_NET_DSA_LOOP - obj-$(CONFIG_FIXED_PHY) += dsa_loop_bdinfo.o - endif -+obj-$(CONFIG_NET_DSA_KS8995) += ks8995.o - obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o - obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o - obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o -diff --git a/drivers/net/phy/spi_ks8995.c b/drivers/net/dsa/ks8995.c -similarity index 100% -rename from drivers/net/phy/spi_ks8995.c -rename to drivers/net/dsa/ks8995.c -diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig -index 01cc31817357..bf7c34402e74 100644 ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -443,7 +443,3 @@ config XILINX_GMII2RGMII - Ethernet physical media devices and the Gigabit Ethernet controller. - - endif # PHYLIB -- --config MICREL_KS8995MA -- tristate "Micrel KS8995MA 5-ports 10/100 managed Ethernet switch" -- depends on SPI -diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile -index 768d1e8ebf80..a9080b8d604e 100644 ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -77,7 +77,6 @@ obj-$(CONFIG_MARVELL_88X2222_PHY) += marvell-88x2222.o - obj-$(CONFIG_MAXLINEAR_GPHY) += mxl-gpy.o - obj-y += mediatek/ - obj-$(CONFIG_MESON_GXL_PHY) += meson-gxl.o --obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o - obj-$(CONFIG_MICREL_PHY) += micrel.o - obj-$(CONFIG_MICROCHIP_PHY) += microchip.o - obj-$(CONFIG_MICROCHIP_T1_PHY) += microchip_t1.o --- -2.51.0 - - -From b5868880d0272cf14e28b438c869027c53ce97e8 Mon Sep 17 00:00:00 2001 -From: Linus Walleij -Date: Wed, 13 Aug 2025 23:43:04 +0200 -Subject: [PATCH 167/517] net: dsa: ks8995: Add proper RESET delay - -According to the datasheet we need to wait 100us before accessing -any registers in the KS8995 after a reset de-assertion. - -Add this delay, if and only if we obtained a GPIO descriptor, -otherwise it is just a pointless delay. - -Signed-off-by: Linus Walleij -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/20250813-ks8995-to-dsa-v1-2-75c359ede3a5@linaro.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/ks8995.c | 12 +++++++++--- - 1 file changed, 9 insertions(+), 3 deletions(-) - -diff --git a/drivers/net/dsa/ks8995.c b/drivers/net/dsa/ks8995.c -index 7196e927c2cd..ab266b3ead02 100644 ---- a/drivers/net/dsa/ks8995.c -+++ b/drivers/net/dsa/ks8995.c -@@ -438,9 +438,15 @@ static int ks8995_probe(struct spi_device *spi) - if (err) - return err; - -- /* de-assert switch reset */ -- /* FIXME: this likely requires a delay */ -- gpiod_set_value_cansleep(ks->reset_gpio, 0); -+ if (ks->reset_gpio) { -+ /* -+ * If a reset line was obtained, wait for 100us after -+ * de-asserting RESET before accessing any registers, see -+ * the KS8995MA datasheet, page 44. -+ */ -+ gpiod_set_value_cansleep(ks->reset_gpio, 0); -+ udelay(100); -+ } - - spi_set_drvdata(spi, ks); - --- -2.51.0 - - -From eb531dff7bf14239f05748e1f299a346633f6165 Mon Sep 17 00:00:00 2001 -From: Linus Walleij -Date: Wed, 13 Aug 2025 23:43:05 +0200 -Subject: [PATCH 168/517] net: dsa: ks8995: Delete sysfs register access - -There is some sysfs file to read and write registers randomly -in the ks8995 driver. - -The contemporary way to achieve the same thing is to implement -regmap abstractions, if needed. Delete this and implement -regmap later if we want to be able to inspect individual registers. - -Signed-off-by: Linus Walleij -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/20250813-ks8995-to-dsa-v1-3-75c359ede3a5@linaro.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/ks8995.c | 48 ---------------------------------------- - 1 file changed, 48 deletions(-) - -diff --git a/drivers/net/dsa/ks8995.c b/drivers/net/dsa/ks8995.c -index ab266b3ead02..45f01c81d0b8 100644 ---- a/drivers/net/dsa/ks8995.c -+++ b/drivers/net/dsa/ks8995.c -@@ -140,7 +140,6 @@ struct ks8995_switch { - struct spi_device *spi; - struct mutex lock; - struct gpio_desc *reset_gpio; -- struct bin_attribute regs_attr; - const struct ks8995_chip_params *chip; - int revision_id; - }; -@@ -288,30 +287,6 @@ static int ks8995_reset(struct ks8995_switch *ks) - return ks8995_start(ks); - } - --static ssize_t ks8995_registers_read(struct file *filp, struct kobject *kobj, -- struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) --{ -- struct device *dev; -- struct ks8995_switch *ks8995; -- -- dev = kobj_to_dev(kobj); -- ks8995 = dev_get_drvdata(dev); -- -- return ks8995_read(ks8995, buf, off, count); --} -- --static ssize_t ks8995_registers_write(struct file *filp, struct kobject *kobj, -- struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) --{ -- struct device *dev; -- struct ks8995_switch *ks8995; -- -- dev = kobj_to_dev(kobj); -- ks8995 = dev_get_drvdata(dev); -- -- return ks8995_write(ks8995, buf, off, count); --} -- - /* ks8995_get_revision - get chip revision - * @ks: pointer to switch instance - * -@@ -395,16 +370,6 @@ static int ks8995_get_revision(struct ks8995_switch *ks) - return err; - } - --static const struct bin_attribute ks8995_registers_attr = { -- .attr = { -- .name = "registers", -- .mode = 0600, -- }, -- .size = KS8995_REGS_SIZE, -- .read = ks8995_registers_read, -- .write = ks8995_registers_write, --}; -- - /* ------------------------------------------------------------------------ */ - static int ks8995_probe(struct spi_device *spi) - { -@@ -462,21 +427,10 @@ static int ks8995_probe(struct spi_device *spi) - if (err) - return err; - -- memcpy(&ks->regs_attr, &ks8995_registers_attr, sizeof(ks->regs_attr)); -- ks->regs_attr.size = ks->chip->regs_size; -- - err = ks8995_reset(ks); - if (err) - return err; - -- sysfs_attr_init(&ks->regs_attr.attr); -- err = sysfs_create_bin_file(&spi->dev.kobj, &ks->regs_attr); -- if (err) { -- dev_err(&spi->dev, "unable to create sysfs file, err=%d\n", -- err); -- return err; -- } -- - dev_info(&spi->dev, "%s device found, Chip ID:%x, Revision:%x\n", - ks->chip->name, ks->chip->chip_id, ks->revision_id); - -@@ -487,8 +441,6 @@ static void ks8995_remove(struct spi_device *spi) - { - struct ks8995_switch *ks = spi_get_drvdata(spi); - -- sysfs_remove_bin_file(&spi->dev.kobj, &ks->regs_attr); -- - /* assert reset */ - gpiod_set_value_cansleep(ks->reset_gpio, 1); - } --- -2.51.0 - - -From 20f057c95e429fc9d1a85736837129570f4714b1 Mon Sep 17 00:00:00 2001 -From: Linus Walleij -Date: Wed, 13 Aug 2025 23:43:06 +0200 -Subject: [PATCH 169/517] net: dsa: ks8995: Add basic switch set-up - -We start to extend the KS8995 driver by simply registering it -as a DSA device and implementing a few switch callbacks for -STP set-up and such to begin with. - -No special tags or other advanced stuff: we use DSA_TAG_NONE -and rely on the default set-up in the switch with the special -DSA tags turned off. This makes the switch wire up properly -to all its PHY's and simple bridge traffic works properly. - -After this the bridge DT bindings are respected, ports and their -PHYs get connected to the switch and react appropriately through -the phylib when cables are plugged in etc. - -Tested like this in a hacky OpenWrt image: - -Bring up conduit interface manually: -ixp4xx_eth c8009000.ethernet eth0: eth0: link up, - speed 100 Mb/s, full duplex - -spi-ks8995 spi0.0: enable port 0 -spi-ks8995 spi0.0: set KS8995_REG_PC2 for port 0 to 06 -spi-ks8995 spi0.0 lan1: configuring for phy/mii link mode -spi-ks8995 spi0.0 lan1: Link is Up - 100Mbps/Full - flow control rx/tx - -PING 169.254.1.1 (169.254.1.1): 56 data bytes -64 bytes from 169.254.1.1: seq=0 ttl=64 time=1.629 ms -64 bytes from 169.254.1.1: seq=1 ttl=64 time=0.951 ms - -I also tested SSH from the device to the host and it works fine. - -It also works fine to ping the device from the host and to SSH -into the device from the host. - -This brings the ks8995 driver to a reasonable state where it can -be used from the current device tree bindings and the existing -device trees in the kernel. - -Signed-off-by: Linus Walleij -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/20250813-ks8995-to-dsa-v1-4-75c359ede3a5@linaro.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/Kconfig | 1 + - drivers/net/dsa/ks8995.c | 398 ++++++++++++++++++++++++++++++++++++++- - 2 files changed, 396 insertions(+), 3 deletions(-) - -diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig -index 4367cbdb92d5..b7b473e3fc02 100644 ---- a/drivers/net/dsa/Kconfig -+++ b/drivers/net/dsa/Kconfig -@@ -101,6 +101,7 @@ config NET_DSA_RZN1_A5PSW - config NET_DSA_KS8995 - tristate "Micrel KS8995 family 5-ports 10/100 Ethernet switches" - depends on SPI -+ select NET_DSA_TAG_NONE - help - This driver supports the Micrel KS8995 family of 10/100 Mbit ethernet - switches, managed over SPI. -diff --git a/drivers/net/dsa/ks8995.c b/drivers/net/dsa/ks8995.c -index 45f01c81d0b8..364e8d16c936 100644 ---- a/drivers/net/dsa/ks8995.c -+++ b/drivers/net/dsa/ks8995.c -@@ -3,6 +3,7 @@ - * SPI driver for Micrel/Kendin KS8995M and KSZ8864RMN ethernet switches - * - * Copyright (C) 2008 Gabor Juhos -+ * Copyright (C) 2025 Linus Walleij - * - * This file was based on: drivers/spi/at25.c - * Copyright (C) 2006 David Brownell -@@ -10,6 +11,9 @@ - - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -+#include -+#include -+#include - #include - #include - #include -@@ -17,8 +21,8 @@ - #include - #include - #include -- - #include -+#include - - #define DRV_VERSION "0.1.1" - #define DRV_DESC "Micrel KS8995 Ethernet switch SPI driver" -@@ -29,18 +33,59 @@ - #define KS8995_REG_ID1 0x01 /* Chip ID1 */ - - #define KS8995_REG_GC0 0x02 /* Global Control 0 */ -+ -+#define KS8995_GC0_P5_PHY BIT(3) /* Port 5 PHY enabled */ -+ - #define KS8995_REG_GC1 0x03 /* Global Control 1 */ - #define KS8995_REG_GC2 0x04 /* Global Control 2 */ -+ -+#define KS8995_GC2_HUGE BIT(2) /* Huge packet support */ -+#define KS8995_GC2_LEGAL BIT(1) /* Legal size override */ -+ - #define KS8995_REG_GC3 0x05 /* Global Control 3 */ - #define KS8995_REG_GC4 0x06 /* Global Control 4 */ -+ -+#define KS8995_GC4_10BT BIT(4) /* Force switch to 10Mbit */ -+#define KS8995_GC4_MII_FLOW BIT(5) /* MII full-duplex flow control enable */ -+#define KS8995_GC4_MII_HD BIT(6) /* MII half-duplex mode enable */ -+ - #define KS8995_REG_GC5 0x07 /* Global Control 5 */ - #define KS8995_REG_GC6 0x08 /* Global Control 6 */ - #define KS8995_REG_GC7 0x09 /* Global Control 7 */ - #define KS8995_REG_GC8 0x0a /* Global Control 8 */ - #define KS8995_REG_GC9 0x0b /* Global Control 9 */ - --#define KS8995_REG_PC(p, r) ((0x10 * p) + r) /* Port Control */ --#define KS8995_REG_PS(p, r) ((0x10 * p) + r + 0xe) /* Port Status */ -+#define KS8995_GC9_SPECIAL BIT(0) /* Special tagging mode (DSA) */ -+ -+/* In DSA the ports 1-4 are numbered 0-3 and the CPU port is port 4 */ -+#define KS8995_REG_PC(p, r) (0x10 + (0x10 * (p)) + (r)) /* Port Control */ -+#define KS8995_REG_PS(p, r) (0x1e + (0x10 * (p)) + (r)) /* Port Status */ -+ -+#define KS8995_REG_PC0 0x00 /* Port Control 0 */ -+#define KS8995_REG_PC1 0x01 /* Port Control 1 */ -+#define KS8995_REG_PC2 0x02 /* Port Control 2 */ -+#define KS8995_REG_PC3 0x03 /* Port Control 3 */ -+#define KS8995_REG_PC4 0x04 /* Port Control 4 */ -+#define KS8995_REG_PC5 0x05 /* Port Control 5 */ -+#define KS8995_REG_PC6 0x06 /* Port Control 6 */ -+#define KS8995_REG_PC7 0x07 /* Port Control 7 */ -+#define KS8995_REG_PC8 0x08 /* Port Control 8 */ -+#define KS8995_REG_PC9 0x09 /* Port Control 9 */ -+#define KS8995_REG_PC10 0x0a /* Port Control 10 */ -+#define KS8995_REG_PC11 0x0b /* Port Control 11 */ -+#define KS8995_REG_PC12 0x0c /* Port Control 12 */ -+#define KS8995_REG_PC13 0x0d /* Port Control 13 */ -+ -+#define KS8995_PC0_TAG_INS BIT(2) /* Enable tag insertion on port */ -+#define KS8995_PC0_TAG_REM BIT(1) /* Enable tag removal on port */ -+#define KS8995_PC0_PRIO_EN BIT(0) /* Enable priority handling */ -+ -+#define KS8995_PC2_TXEN BIT(2) /* Enable TX on port */ -+#define KS8995_PC2_RXEN BIT(1) /* Enable RX on port */ -+#define KS8995_PC2_LEARN_DIS BIT(0) /* Disable learning on port */ -+ -+#define KS8995_PC13_TXDIS BIT(6) /* Disable transmitter */ -+#define KS8995_PC13_PWDN BIT(3) /* Power down */ - - #define KS8995_REG_TPC0 0x60 /* TOS Priority Control 0 */ - #define KS8995_REG_TPC1 0x61 /* TOS Priority Control 1 */ -@@ -91,6 +136,8 @@ - #define KS8995_CMD_WRITE 0x02U - #define KS8995_CMD_READ 0x03U - -+#define KS8995_CPU_PORT 4 -+#define KS8995_NUM_PORTS 5 /* 5 ports including the CPU port */ - #define KS8995_RESET_DELAY 10 /* usec */ - - enum ks8995_chip_variant { -@@ -138,10 +185,13 @@ static const struct ks8995_chip_params ks8995_chip[] = { - - struct ks8995_switch { - struct spi_device *spi; -+ struct device *dev; -+ struct dsa_switch *ds; - struct mutex lock; - struct gpio_desc *reset_gpio; - const struct ks8995_chip_params *chip; - int revision_id; -+ unsigned int max_mtu[KS8995_NUM_PORTS]; - }; - - static const struct spi_device_id ks8995_id[] = { -@@ -370,6 +420,327 @@ static int ks8995_get_revision(struct ks8995_switch *ks) - return err; - } - -+static int ks8995_check_config(struct ks8995_switch *ks) -+{ -+ int ret; -+ u8 val; -+ -+ ret = ks8995_read_reg(ks, KS8995_REG_GC0, &val); -+ if (ret) { -+ dev_err(ks->dev, "failed to read KS8995_REG_GC0\n"); -+ return ret; -+ } -+ -+ dev_dbg(ks->dev, "port 5 PHY %senabled\n", -+ (val & KS8995_GC0_P5_PHY) ? "" : "not "); -+ -+ val |= KS8995_GC0_P5_PHY; -+ ret = ks8995_write_reg(ks, KS8995_REG_GC0, val); -+ if (ret) -+ dev_err(ks->dev, "failed to set KS8995_REG_GC0\n"); -+ -+ dev_dbg(ks->dev, "set KS8995_REG_GC0 to 0x%02x\n", val); -+ -+ return 0; -+} -+ -+static void -+ks8995_mac_config(struct phylink_config *config, unsigned int mode, -+ const struct phylink_link_state *state) -+{ -+} -+ -+static void -+ks8995_mac_link_up(struct phylink_config *config, struct phy_device *phydev, -+ unsigned int mode, phy_interface_t interface, -+ int speed, int duplex, bool tx_pause, bool rx_pause) -+{ -+ struct dsa_port *dp = dsa_phylink_to_port(config); -+ struct ks8995_switch *ks = dp->ds->priv; -+ int port = dp->index; -+ int ret; -+ u8 val; -+ -+ /* Allow forcing the mode on the fixed CPU port, no autonegotiation. -+ * We assume autonegotiation works on the PHY-facing ports. -+ */ -+ if (port != KS8995_CPU_PORT) -+ return; -+ -+ dev_dbg(ks->dev, "MAC link up on CPU port (%d)\n", port); -+ -+ ret = ks8995_read_reg(ks, KS8995_REG_GC4, &val); -+ if (ret) { -+ dev_err(ks->dev, "failed to read KS8995_REG_GC4\n"); -+ return; -+ } -+ -+ /* Conjure port config */ -+ switch (speed) { -+ case SPEED_10: -+ dev_dbg(ks->dev, "set switch MII to 100Mbit mode\n"); -+ val |= KS8995_GC4_10BT; -+ break; -+ case SPEED_100: -+ default: -+ dev_dbg(ks->dev, "set switch MII to 100Mbit mode\n"); -+ val &= ~KS8995_GC4_10BT; -+ break; -+ } -+ -+ if (duplex == DUPLEX_HALF) { -+ dev_dbg(ks->dev, "set switch MII to half duplex\n"); -+ val |= KS8995_GC4_MII_HD; -+ } else { -+ dev_dbg(ks->dev, "set switch MII to full duplex\n"); -+ val &= ~KS8995_GC4_MII_HD; -+ } -+ -+ dev_dbg(ks->dev, "set KS8995_REG_GC4 to %02x\n", val); -+ -+ /* Enable the CPU port */ -+ ret = ks8995_write_reg(ks, KS8995_REG_GC4, val); -+ if (ret) -+ dev_err(ks->dev, "failed to set KS8995_REG_GC4\n"); -+} -+ -+static void -+ks8995_mac_link_down(struct phylink_config *config, unsigned int mode, -+ phy_interface_t interface) -+{ -+ struct dsa_port *dp = dsa_phylink_to_port(config); -+ struct ks8995_switch *ks = dp->ds->priv; -+ int port = dp->index; -+ -+ if (port != KS8995_CPU_PORT) -+ return; -+ -+ dev_dbg(ks->dev, "MAC link down on CPU port (%d)\n", port); -+ -+ /* Disable the CPU port */ -+} -+ -+static const struct phylink_mac_ops ks8995_phylink_mac_ops = { -+ .mac_config = ks8995_mac_config, -+ .mac_link_up = ks8995_mac_link_up, -+ .mac_link_down = ks8995_mac_link_down, -+}; -+ -+static enum -+dsa_tag_protocol ks8995_get_tag_protocol(struct dsa_switch *ds, -+ int port, -+ enum dsa_tag_protocol mp) -+{ -+ /* This switch actually uses the 6 byte KS8995 protocol */ -+ return DSA_TAG_PROTO_NONE; -+} -+ -+static int ks8995_setup(struct dsa_switch *ds) -+{ -+ return 0; -+} -+ -+static int ks8995_port_enable(struct dsa_switch *ds, int port, -+ struct phy_device *phy) -+{ -+ struct ks8995_switch *ks = ds->priv; -+ -+ dev_dbg(ks->dev, "enable port %d\n", port); -+ -+ return 0; -+} -+ -+static void ks8995_port_disable(struct dsa_switch *ds, int port) -+{ -+ struct ks8995_switch *ks = ds->priv; -+ -+ dev_dbg(ks->dev, "disable port %d\n", port); -+} -+ -+static int ks8995_port_pre_bridge_flags(struct dsa_switch *ds, int port, -+ struct switchdev_brport_flags flags, -+ struct netlink_ext_ack *extack) -+{ -+ /* We support enabling/disabling learning */ -+ if (flags.mask & ~(BR_LEARNING)) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static int ks8995_port_bridge_flags(struct dsa_switch *ds, int port, -+ struct switchdev_brport_flags flags, -+ struct netlink_ext_ack *extack) -+{ -+ struct ks8995_switch *ks = ds->priv; -+ int ret; -+ u8 val; -+ -+ if (flags.mask & BR_LEARNING) { -+ ret = ks8995_read_reg(ks, KS8995_REG_PC(port, KS8995_REG_PC2), &val); -+ if (ret) { -+ dev_err(ks->dev, "failed to read KS8995_REG_PC2 on port %d\n", port); -+ return ret; -+ } -+ -+ if (flags.val & BR_LEARNING) -+ val &= ~KS8995_PC2_LEARN_DIS; -+ else -+ val |= KS8995_PC2_LEARN_DIS; -+ -+ ret = ks8995_write_reg(ks, KS8995_REG_PC(port, KS8995_REG_PC2), val); -+ if (ret) { -+ dev_err(ks->dev, "failed to write KS8995_REG_PC2 on port %d\n", port); -+ return ret; -+ } -+ } -+ -+ return 0; -+} -+ -+static void ks8995_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) -+{ -+ struct ks8995_switch *ks = ds->priv; -+ int ret; -+ u8 val; -+ -+ ret = ks8995_read_reg(ks, KS8995_REG_PC(port, KS8995_REG_PC2), &val); -+ if (ret) { -+ dev_err(ks->dev, "failed to read KS8995_REG_PC2 on port %d\n", port); -+ return; -+ } -+ -+ /* Set the bits for the different STP states in accordance with -+ * the datasheet, pages 36-37 "Spanning tree support". -+ */ -+ switch (state) { -+ case BR_STATE_DISABLED: -+ case BR_STATE_BLOCKING: -+ case BR_STATE_LISTENING: -+ val &= ~KS8995_PC2_TXEN; -+ val &= ~KS8995_PC2_RXEN; -+ val |= KS8995_PC2_LEARN_DIS; -+ break; -+ case BR_STATE_LEARNING: -+ val &= ~KS8995_PC2_TXEN; -+ val &= ~KS8995_PC2_RXEN; -+ val &= ~KS8995_PC2_LEARN_DIS; -+ break; -+ case BR_STATE_FORWARDING: -+ val |= KS8995_PC2_TXEN; -+ val |= KS8995_PC2_RXEN; -+ val &= ~KS8995_PC2_LEARN_DIS; -+ break; -+ default: -+ dev_err(ks->dev, "unknown bridge state requested\n"); -+ return; -+ } -+ -+ ret = ks8995_write_reg(ks, KS8995_REG_PC(port, KS8995_REG_PC2), val); -+ if (ret) { -+ dev_err(ks->dev, "failed to write KS8995_REG_PC2 on port %d\n", port); -+ return; -+ } -+ -+ dev_dbg(ks->dev, "set KS8995_REG_PC2 for port %d to %02x\n", port, val); -+} -+ -+static void ks8995_phylink_get_caps(struct dsa_switch *dsa, int port, -+ struct phylink_config *config) -+{ -+ unsigned long *interfaces = config->supported_interfaces; -+ -+ if (port == KS8995_CPU_PORT) -+ __set_bit(PHY_INTERFACE_MODE_MII, interfaces); -+ -+ if (port <= 3) { -+ /* Internal PHYs */ -+ __set_bit(PHY_INTERFACE_MODE_INTERNAL, interfaces); -+ /* phylib default */ -+ __set_bit(PHY_INTERFACE_MODE_MII, interfaces); -+ } -+ -+ config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100; -+} -+ -+/* Huge packet support up to 1916 byte packages "inclusive" -+ * which means that tags are included. If the bit is not set -+ * it is 1536 bytes "inclusive". We present the length without -+ * tags or ethernet headers. The setting affects all ports. -+ */ -+static int ks8995_change_mtu(struct dsa_switch *ds, int port, int new_mtu) -+{ -+ struct ks8995_switch *ks = ds->priv; -+ unsigned int max_mtu; -+ int ret; -+ u8 val; -+ int i; -+ -+ ks->max_mtu[port] = new_mtu; -+ -+ /* Roof out the MTU for the entire switch to the greatest -+ * common denominator: the biggest set for any one port will -+ * be the biggest MTU for the switch. -+ */ -+ max_mtu = ETH_DATA_LEN; -+ for (i = 0; i < KS8995_NUM_PORTS; i++) { -+ if (ks->max_mtu[i] > max_mtu) -+ max_mtu = ks->max_mtu[i]; -+ } -+ -+ /* Translate to layer 2 size. -+ * Add ethernet and (possible) VLAN headers, and checksum to the size. -+ * For ETH_DATA_LEN (1500 bytes) this will add up to 1522 bytes. -+ */ -+ max_mtu += VLAN_ETH_HLEN; -+ max_mtu += ETH_FCS_LEN; -+ -+ ret = ks8995_read_reg(ks, KS8995_REG_GC2, &val); -+ if (ret) { -+ dev_err(ks->dev, "failed to read KS8995_REG_GC2\n"); -+ return ret; -+ } -+ -+ if (max_mtu <= 1522) { -+ val &= ~KS8995_GC2_HUGE; -+ val &= ~KS8995_GC2_LEGAL; -+ } else if (max_mtu > 1522 && max_mtu <= 1536) { -+ /* This accepts packets up to 1536 bytes */ -+ val &= ~KS8995_GC2_HUGE; -+ val |= KS8995_GC2_LEGAL; -+ } else { -+ /* This accepts packets up to 1916 bytes */ -+ val |= KS8995_GC2_HUGE; -+ val |= KS8995_GC2_LEGAL; -+ } -+ -+ dev_dbg(ks->dev, "new max MTU %d bytes (inclusive)\n", max_mtu); -+ -+ ret = ks8995_write_reg(ks, KS8995_REG_GC2, val); -+ if (ret) -+ dev_err(ks->dev, "failed to set KS8995_REG_GC2\n"); -+ -+ return ret; -+} -+ -+static int ks8995_get_max_mtu(struct dsa_switch *ds, int port) -+{ -+ return 1916 - ETH_HLEN - ETH_FCS_LEN; -+} -+ -+static const struct dsa_switch_ops ks8995_ds_ops = { -+ .get_tag_protocol = ks8995_get_tag_protocol, -+ .setup = ks8995_setup, -+ .port_pre_bridge_flags = ks8995_port_pre_bridge_flags, -+ .port_bridge_flags = ks8995_port_bridge_flags, -+ .port_enable = ks8995_port_enable, -+ .port_disable = ks8995_port_disable, -+ .port_stp_state_set = ks8995_port_stp_state_set, -+ .port_change_mtu = ks8995_change_mtu, -+ .port_max_mtu = ks8995_get_max_mtu, -+ .phylink_get_caps = ks8995_phylink_get_caps, -+}; -+ - /* ------------------------------------------------------------------------ */ - static int ks8995_probe(struct spi_device *spi) - { -@@ -388,6 +759,7 @@ static int ks8995_probe(struct spi_device *spi) - - mutex_init(&ks->lock); - ks->spi = spi; -+ ks->dev = &spi->dev; - ks->chip = &ks8995_chip[variant]; - - ks->reset_gpio = devm_gpiod_get_optional(&spi->dev, "reset", -@@ -434,6 +806,25 @@ static int ks8995_probe(struct spi_device *spi) - dev_info(&spi->dev, "%s device found, Chip ID:%x, Revision:%x\n", - ks->chip->name, ks->chip->chip_id, ks->revision_id); - -+ err = ks8995_check_config(ks); -+ if (err) -+ return err; -+ -+ ks->ds = devm_kzalloc(&spi->dev, sizeof(*ks->ds), GFP_KERNEL); -+ if (!ks->ds) -+ return -ENOMEM; -+ -+ ks->ds->dev = &spi->dev; -+ ks->ds->num_ports = KS8995_NUM_PORTS; -+ ks->ds->ops = &ks8995_ds_ops; -+ ks->ds->phylink_mac_ops = &ks8995_phylink_mac_ops; -+ ks->ds->priv = ks; -+ -+ err = dsa_register_switch(ks->ds); -+ if (err) -+ return dev_err_probe(&spi->dev, err, -+ "unable to register DSA switch\n"); -+ - return 0; - } - -@@ -441,6 +832,7 @@ static void ks8995_remove(struct spi_device *spi) - { - struct ks8995_switch *ks = spi_get_drvdata(spi); - -+ dsa_unregister_switch(ks->ds); - /* assert reset */ - gpiod_set_value_cansleep(ks->reset_gpio, 1); - } --- -2.51.0 - - -From c5a714e79548a715750999c9547a52a486e0e851 Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Thu, 10 Oct 2024 21:35:42 +0200 -Subject: [PATCH 170/517] hwmon: Add static visibility member to struct - hwmon_ops - -Several drivers return the same static value in their is_visible -callback, what results in code duplication. Therefore add an option -for drivers to specify a static visibility directly. - -Signed-off-by: Heiner Kallweit -Message-ID: <89690b81-2c73-47ae-9ae9-45c77b45ca0c@gmail.com> -groeck: Renamed hwmon_ops_is_visible -> hwmon_is_visible -Signed-off-by: Guenter Roeck ---- - drivers/hwmon/hwmon.c | 19 +++++++++++++++---- - include/linux/hwmon.h | 5 ++++- - 2 files changed, 19 insertions(+), 5 deletions(-) - -diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c -index 9c35c4d0369d..49b366254529 100644 ---- a/drivers/hwmon/hwmon.c -+++ b/drivers/hwmon/hwmon.c -@@ -145,6 +145,17 @@ static const struct class hwmon_class = { - - static DEFINE_IDA(hwmon_ida); - -+static umode_t hwmon_is_visible(const struct hwmon_ops *ops, -+ const void *drvdata, -+ enum hwmon_sensor_types type, -+ u32 attr, int channel) -+{ -+ if (ops->visible) -+ return ops->visible; -+ -+ return ops->is_visible(drvdata, type, attr, channel); -+} -+ - /* Thermal zone handling */ - - /* -@@ -267,8 +278,8 @@ static int hwmon_thermal_register_sensors(struct device *dev) - int err; - - if (!(info[i]->config[j] & HWMON_T_INPUT) || -- !chip->ops->is_visible(drvdata, hwmon_temp, -- hwmon_temp_input, j)) -+ !hwmon_is_visible(chip->ops, drvdata, hwmon_temp, -+ hwmon_temp_input, j)) - continue; - - err = hwmon_thermal_add_sensor(dev, j); -@@ -506,7 +517,7 @@ static struct attribute *hwmon_genattr(const void *drvdata, - const char *name; - bool is_string = is_string_attr(type, attr); - -- mode = ops->is_visible(drvdata, type, attr, index); -+ mode = hwmon_is_visible(ops, drvdata, type, attr, index); - if (!mode) - return ERR_PTR(-ENOENT); - -@@ -1033,7 +1044,7 @@ hwmon_device_register_with_info(struct device *dev, const char *name, - if (!dev || !name || !chip) - return ERR_PTR(-EINVAL); - -- if (!chip->ops || !chip->ops->is_visible || !chip->info) -+ if (!chip->ops || !(chip->ops->visible || chip->ops->is_visible) || !chip->info) - return ERR_PTR(-EINVAL); - - return __hwmon_device_register(dev, name, drvdata, chip, extra_groups); -diff --git a/include/linux/hwmon.h b/include/linux/hwmon.h -index 5c6a421ad580..3a63dff62d03 100644 ---- a/include/linux/hwmon.h -+++ b/include/linux/hwmon.h -@@ -368,7 +368,9 @@ enum hwmon_intrusion_attributes { - - /** - * struct hwmon_ops - hwmon device operations -- * @is_visible: Callback to return attribute visibility. Mandatory. -+ * @visible: Static visibility. If non-zero, 'is_visible' is ignored. -+ * @is_visible: Callback to return attribute visibility. Mandatory unless -+ * 'visible' is non-zero. - * Parameters are: - * @const void *drvdata: - * Pointer to driver-private data structure passed -@@ -412,6 +414,7 @@ enum hwmon_intrusion_attributes { - * The function returns 0 on success or a negative error number. - */ - struct hwmon_ops { -+ umode_t visible; - umode_t (*is_visible)(const void *drvdata, enum hwmon_sensor_types type, - u32 attr, int channel); - int (*read)(struct device *dev, enum hwmon_sensor_types type, --- -2.51.0 - - -From e49d38bee83d91a1cf8d4e8fa67b2bc455ddd028 Mon Sep 17 00:00:00 2001 -From: Heiko Stuebner -Date: Fri, 6 Sep 2024 10:25:07 +0200 -Subject: [PATCH 171/517] dt-bindings: clocks: add binding for - gated-fixed-clocks - -In contrast to fixed clocks that are described as ungateable, boards -sometimes use additional oscillators for things like PCIe reference -clocks, that need actual supplies to get enabled and enable-gpios to be -toggled for them to work. - -This adds a binding for such oscillators that are not configurable -themself, but need to handle supplies for them to work. - -In schematics they often can be seen as - - ---------------- -Enable - | 100MHz,3.3V, | - VDD - | 3225 | - GND - | | - OUT - ---------------- - -or similar. The enable pin might be separate but can also just be tied -to the vdd supply, hence it is optional in the binding. - -Signed-off-by: Heiko Stuebner -Reviewed-by: Rob Herring (Arm) -Reviewed-by: Conor Dooley -Link: https://lore.kernel.org/r/20240906082511.2963890-2-heiko@sntech.de -Signed-off-by: Stephen Boyd ---- - .../bindings/clock/gated-fixed-clock.yaml | 49 +++++++++++++++++++ - 1 file changed, 49 insertions(+) - create mode 100644 Documentation/devicetree/bindings/clock/gated-fixed-clock.yaml - -diff --git a/Documentation/devicetree/bindings/clock/gated-fixed-clock.yaml b/Documentation/devicetree/bindings/clock/gated-fixed-clock.yaml -new file mode 100644 -index 000000000000..d3e0faf3c64d ---- /dev/null -+++ b/Documentation/devicetree/bindings/clock/gated-fixed-clock.yaml -@@ -0,0 +1,49 @@ -+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/clock/gated-fixed-clock.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: Gated Fixed clock -+ -+maintainers: -+ - Heiko Stuebner -+ -+properties: -+ compatible: -+ const: gated-fixed-clock -+ -+ "#clock-cells": -+ const: 0 -+ -+ clock-frequency: true -+ -+ clock-output-names: -+ maxItems: 1 -+ -+ enable-gpios: -+ description: -+ Contains a single GPIO specifier for the GPIO that enables and disables -+ the oscillator. -+ maxItems: 1 -+ -+ vdd-supply: -+ description: handle of the regulator that provides the supply voltage -+ -+required: -+ - compatible -+ - "#clock-cells" -+ - clock-frequency -+ - vdd-supply -+ -+additionalProperties: false -+ -+examples: -+ - | -+ clock-1000000000 { -+ compatible = "gated-fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <1000000000>; -+ vdd-supply = <®_vdd>; -+ }; -+... --- -2.51.0 - - -From a821d7186c5d4f7289edfbcc0091f744729e0880 Mon Sep 17 00:00:00 2001 -From: Heiko Stuebner -Date: Fri, 6 Sep 2024 10:25:08 +0200 -Subject: [PATCH 172/517] clk: clk-gpio: update documentation for gpio-gate - clock - -The main documentation block seems to be from a time before the driver -handled sleeping and non-sleeping gpios and with that change it seems -updating the doc was overlooked. So do that now. - -Signed-off-by: Heiko Stuebner -Link: https://lore.kernel.org/r/20240906082511.2963890-3-heiko@sntech.de -Signed-off-by: Stephen Boyd ---- - drivers/clk/clk-gpio.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c -index 5b114043771d..98415782f9a2 100644 ---- a/drivers/clk/clk-gpio.c -+++ b/drivers/clk/clk-gpio.c -@@ -22,8 +22,9 @@ - * DOC: basic gpio gated clock which can be enabled and disabled - * with gpio output - * Traits of this clock: -- * prepare - clk_(un)prepare only ensures parent is (un)prepared -- * enable - clk_enable and clk_disable are functional & control gpio -+ * prepare - clk_(un)prepare are functional and control a gpio that can sleep -+ * enable - clk_enable and clk_disable are functional & control -+ * non-sleeping gpio - * rate - inherits rate from parent. No clk_set_rate support - * parent - fixed parent. No clk_set_parent support - */ --- -2.51.0 - - -From 1d8ecd6adc09ddf3d97c8d3db6c13fc109f9f24d Mon Sep 17 00:00:00 2001 -From: Heiko Stuebner -Date: Fri, 6 Sep 2024 10:25:09 +0200 -Subject: [PATCH 173/517] clk: clk-gpio: use dev_err_probe for gpio-get failure - -This is a real driver and dev_err_probe will hide the distinction between -EPROBE_DEFER and other errors automatically, so there is no need to -open-code this. - -Signed-off-by: Heiko Stuebner -Link: https://lore.kernel.org/r/20240906082511.2963890-4-heiko@sntech.de -Signed-off-by: Stephen Boyd ---- - drivers/clk/clk-gpio.c | 15 +++------------ - 1 file changed, 3 insertions(+), 12 deletions(-) - -diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c -index 98415782f9a2..cda362a2eca0 100644 ---- a/drivers/clk/clk-gpio.c -+++ b/drivers/clk/clk-gpio.c -@@ -200,7 +200,6 @@ static int gpio_clk_driver_probe(struct platform_device *pdev) - struct gpio_desc *gpiod; - struct clk_hw *hw; - bool is_mux; -- int ret; - - is_mux = of_device_is_compatible(node, "gpio-mux-clock"); - -@@ -212,17 +211,9 @@ static int gpio_clk_driver_probe(struct platform_device *pdev) - - gpio_name = is_mux ? "select" : "enable"; - gpiod = devm_gpiod_get(dev, gpio_name, GPIOD_OUT_LOW); -- if (IS_ERR(gpiod)) { -- ret = PTR_ERR(gpiod); -- if (ret == -EPROBE_DEFER) -- pr_debug("%pOFn: %s: GPIOs not yet available, retry later\n", -- node, __func__); -- else -- pr_err("%pOFn: %s: Can't get '%s' named GPIO property\n", -- node, __func__, -- gpio_name); -- return ret; -- } -+ if (IS_ERR(gpiod)) -+ return dev_err_probe(dev, PTR_ERR(gpiod), -+ "Can't get '%s' named GPIO property\n", gpio_name); - - if (is_mux) - hw = clk_hw_register_gpio_mux(dev, gpiod); --- -2.51.0 - - -From ee31cfe9b43e3d8aa62c15b695cdb655bf428db5 Mon Sep 17 00:00:00 2001 -From: Heiko Stuebner -Date: Fri, 6 Sep 2024 10:25:10 +0200 -Subject: [PATCH 174/517] clk: clk-gpio: add driver for gated-fixed-clocks - -In contrast to fixed clocks that are described as ungateable, boards -sometimes use additional oscillators for things like PCIe reference -clocks, that need actual supplies to get enabled and enable-gpios to be -toggled for them to work. - -This adds a driver for those generic gated-fixed-clocks -that can show up in schematics looking like - - ---------------- -Enable - | 100MHz,3.3V, | - VDD - | 3225 | - GND - | | - OUT - ---------------- - -The new driver gets grouped together with the existing gpio-gate and -gpio-mux, as it for one re-uses a lot of the gpio-gate functions -and also in its core it's just another gpio-controlled clock, just -with a fixed rate and a regulator-supply added in. - -The regulator-API provides function stubs for the !CONFIG_REGULATOR case, -so no special handling is necessary. - -Signed-off-by: Heiko Stuebner -Link: https://lore.kernel.org/r/20240906082511.2963890-5-heiko@sntech.de -Signed-off-by: Stephen Boyd ---- - drivers/clk/clk-gpio.c | 185 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 185 insertions(+) - -diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c -index cda362a2eca0..9099c57e2715 100644 ---- a/drivers/clk/clk-gpio.c -+++ b/drivers/clk/clk-gpio.c -@@ -17,6 +17,7 @@ - #include - #include - #include -+#include - - /** - * DOC: basic gpio gated clock which can be enabled and disabled -@@ -239,3 +240,187 @@ static struct platform_driver gpio_clk_driver = { - }, - }; - builtin_platform_driver(gpio_clk_driver); -+ -+/** -+ * DOC: gated fixed clock, controlled with a gpio output and a regulator -+ * Traits of this clock: -+ * prepare - clk_prepare and clk_unprepare are function & control regulator -+ * optionally a gpio that can sleep -+ * enable - clk_enable and clk_disable are functional & control gpio -+ * rate - rate is fixed and set on clock registration -+ * parent - fixed clock is a root clock and has no parent -+ */ -+ -+/** -+ * struct clk_gated_fixed - Gateable fixed rate clock -+ * @clk_gpio: instance of clk_gpio for gate-gpio -+ * @supply: supply regulator -+ * @rate: fixed rate -+ */ -+struct clk_gated_fixed { -+ struct clk_gpio clk_gpio; -+ struct regulator *supply; -+ unsigned long rate; -+}; -+ -+#define to_clk_gated_fixed(_clk_gpio) container_of(_clk_gpio, struct clk_gated_fixed, clk_gpio) -+ -+static unsigned long clk_gated_fixed_recalc_rate(struct clk_hw *hw, -+ unsigned long parent_rate) -+{ -+ return to_clk_gated_fixed(to_clk_gpio(hw))->rate; -+} -+ -+static int clk_gated_fixed_prepare(struct clk_hw *hw) -+{ -+ struct clk_gated_fixed *clk = to_clk_gated_fixed(to_clk_gpio(hw)); -+ -+ if (!clk->supply) -+ return 0; -+ -+ return regulator_enable(clk->supply); -+} -+ -+static void clk_gated_fixed_unprepare(struct clk_hw *hw) -+{ -+ struct clk_gated_fixed *clk = to_clk_gated_fixed(to_clk_gpio(hw)); -+ -+ if (!clk->supply) -+ return; -+ -+ regulator_disable(clk->supply); -+} -+ -+static int clk_gated_fixed_is_prepared(struct clk_hw *hw) -+{ -+ struct clk_gated_fixed *clk = to_clk_gated_fixed(to_clk_gpio(hw)); -+ -+ if (!clk->supply) -+ return true; -+ -+ return regulator_is_enabled(clk->supply); -+} -+ -+/* -+ * Fixed gated clock with non-sleeping gpio. -+ * -+ * Prepare operation turns on the supply regulator -+ * and the enable operation switches the enable-gpio. -+ */ -+static const struct clk_ops clk_gated_fixed_ops = { -+ .prepare = clk_gated_fixed_prepare, -+ .unprepare = clk_gated_fixed_unprepare, -+ .is_prepared = clk_gated_fixed_is_prepared, -+ .enable = clk_gpio_gate_enable, -+ .disable = clk_gpio_gate_disable, -+ .is_enabled = clk_gpio_gate_is_enabled, -+ .recalc_rate = clk_gated_fixed_recalc_rate, -+}; -+ -+static int clk_sleeping_gated_fixed_prepare(struct clk_hw *hw) -+{ -+ int ret; -+ -+ ret = clk_gated_fixed_prepare(hw); -+ if (ret) -+ return ret; -+ -+ ret = clk_sleeping_gpio_gate_prepare(hw); -+ if (ret) -+ clk_gated_fixed_unprepare(hw); -+ -+ return ret; -+} -+ -+static void clk_sleeping_gated_fixed_unprepare(struct clk_hw *hw) -+{ -+ clk_gated_fixed_unprepare(hw); -+ clk_sleeping_gpio_gate_unprepare(hw); -+} -+ -+/* -+ * Fixed gated clock with non-sleeping gpio. -+ * -+ * Enabling the supply regulator and switching the enable-gpio happens -+ * both in the prepare step. -+ * is_prepared only needs to check the gpio state, as toggling the -+ * gpio is the last step when preparing. -+ */ -+static const struct clk_ops clk_sleeping_gated_fixed_ops = { -+ .prepare = clk_sleeping_gated_fixed_prepare, -+ .unprepare = clk_sleeping_gated_fixed_unprepare, -+ .is_prepared = clk_sleeping_gpio_gate_is_prepared, -+ .recalc_rate = clk_gated_fixed_recalc_rate, -+}; -+ -+static int clk_gated_fixed_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct clk_gated_fixed *clk; -+ const struct clk_ops *ops; -+ const char *clk_name; -+ u32 rate; -+ int ret; -+ -+ clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL); -+ if (!clk) -+ return -ENOMEM; -+ -+ ret = device_property_read_u32(dev, "clock-frequency", &rate); -+ if (ret) -+ return dev_err_probe(dev, ret, "Failed to get clock-frequency\n"); -+ clk->rate = rate; -+ -+ ret = device_property_read_string(dev, "clock-output-names", &clk_name); -+ if (ret) -+ clk_name = fwnode_get_name(dev->fwnode); -+ -+ clk->supply = devm_regulator_get_optional(dev, "vdd"); -+ if (IS_ERR(clk->supply)) { -+ if (PTR_ERR(clk->supply) != -ENODEV) -+ return dev_err_probe(dev, PTR_ERR(clk->supply), -+ "Failed to get regulator\n"); -+ clk->supply = NULL; -+ } -+ -+ clk->clk_gpio.gpiod = devm_gpiod_get_optional(dev, "enable", -+ GPIOD_OUT_LOW); -+ if (IS_ERR(clk->clk_gpio.gpiod)) -+ return dev_err_probe(dev, PTR_ERR(clk->clk_gpio.gpiod), -+ "Failed to get gpio\n"); -+ -+ if (gpiod_cansleep(clk->clk_gpio.gpiod)) -+ ops = &clk_sleeping_gated_fixed_ops; -+ else -+ ops = &clk_gated_fixed_ops; -+ -+ clk->clk_gpio.hw.init = CLK_HW_INIT_NO_PARENT(clk_name, ops, 0); -+ -+ /* register the clock */ -+ ret = devm_clk_hw_register(dev, &clk->clk_gpio.hw); -+ if (ret) -+ return dev_err_probe(dev, ret, -+ "Failed to register clock\n"); -+ -+ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, -+ &clk->clk_gpio.hw); -+ if (ret) -+ return dev_err_probe(dev, ret, -+ "Failed to register clock provider\n"); -+ -+ return 0; -+} -+ -+static const struct of_device_id gated_fixed_clk_match_table[] = { -+ { .compatible = "gated-fixed-clock" }, -+ { /* sentinel */ } -+}; -+ -+static struct platform_driver gated_fixed_clk_driver = { -+ .probe = clk_gated_fixed_probe, -+ .driver = { -+ .name = "gated-fixed-clk", -+ .of_match_table = gated_fixed_clk_match_table, -+ }, -+}; -+builtin_platform_driver(gated_fixed_clk_driver); --- -2.51.0 - - -From 039a2eb86e84a84208a807044b945bde9f844f55 Mon Sep 17 00:00:00 2001 -From: Sander Vanheule -Date: Tue, 7 Jan 2025 21:16:20 +0100 -Subject: [PATCH 175/517] gpio: regmap: Use generic request/free ops - -Set the gpiochip request and free ops to the generic implementations. -This way a user can provide a gpio-ranges property defined for a pinmux, -easing muxing of gpio functions. Provided that the pin controller -implementents the pinmux op .gpio_request_enable(), pins will -automatically be muxed to their GPIO function when requested. - -Signed-off-by: Sander Vanheule -Acked-by: Michael Walle -Link: https://lore.kernel.org/r/20250107201621.12467-1-sander@svanheule.net -Signed-off-by: Bartosz Golaszewski ---- - drivers/gpio/gpio-regmap.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/gpio/gpio-regmap.c b/drivers/gpio/gpio-regmap.c -index 71684dee2ca5..05f8781b5204 100644 ---- a/drivers/gpio/gpio-regmap.c -+++ b/drivers/gpio/gpio-regmap.c -@@ -262,6 +262,8 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config - chip->label = config->label ?: dev_name(config->parent); - chip->can_sleep = regmap_might_sleep(config->regmap); - -+ chip->request = gpiochip_generic_request; -+ chip->free = gpiochip_generic_free; - chip->get = gpio_regmap_get; - if (gpio->reg_set_base && gpio->reg_clr_base) - chip->set = gpio_regmap_set_with_clear; --- -2.51.0 - - -From 555fd2a1b2e46bbede23b8477230cd77af346fe2 Mon Sep 17 00:00:00 2001 -From: Kees Cook -Date: Wed, 16 Apr 2025 15:27:41 -0700 -Subject: [PATCH 176/517] power: supply: sysfs: Remove duplicate NUL - termination - -GCC 15's new -Wunterminated-string-initialization notices that one of -the sysfs attr strings would lack the implicit trailing NUL byte during -initialization: - -drivers/power/supply/power_supply_sysfs.c:183:57: warning: initializer-string for array of 'char' truncates NUL terminator but destination lacks 'nonstring' attribute (32 chars into 31 available) [-Wunterminated-string-initialization] - 183 | POWER_SUPPLY_ATTR(CHARGE_CONTROL_START_THRESHOLD), - | ^ -drivers/power/supply/power_supply_sysfs.c:36:23: note: in definition of macro '_POWER_SUPPLY_ATTR' - 36 | .attr_name = #_name "\0", \ - | ^~~~~ -drivers/power/supply/power_supply_sysfs.c:183:9: note: in expansion of macro 'POWER_SUPPLY_ATTR' - 183 | POWER_SUPPLY_ATTR(CHARGE_CONTROL_START_THRESHOLD), - | ^~~~~~~~~~~~~~~~~ - -However, the macro used was explicitly adding a trailing NUL byte (which -is not needed). Remove this to avoid the GCC warning. No binary -differences are seen after this change (there was always run for a NUL -byte, it's just that the _second_ NUL byte was getting truncated). - -Signed-off-by: Kees Cook -Link: https://lore.kernel.org/r/20250416222740.work.569-kees@kernel.org -Signed-off-by: Sebastian Reichel ---- - drivers/power/supply/power_supply_sysfs.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c -index 16b3c5880cd8..df6b16c77279 100644 ---- a/drivers/power/supply/power_supply_sysfs.c -+++ b/drivers/power/supply/power_supply_sysfs.c -@@ -33,7 +33,7 @@ struct power_supply_attr { - [POWER_SUPPLY_PROP_ ## _name] = \ - { \ - .prop_name = #_name, \ -- .attr_name = #_name "\0", \ -+ .attr_name = #_name, \ - .text_values = _text, \ - .text_values_len = _len, \ - } --- -2.51.0 - - -From 7fb95e70810dd24974c57ab56fb2dc919e5b1665 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Thu, 22 Oct 2020 22:00:03 +0200 -Subject: [PATCH 177/517] compiler.h: only include asm/rwonce.h for kernel code - -This header file is not in uapi, which makes any user space code that includes -linux/compiler.h to fail with the error 'asm/rwonce.h: No such file or directory' - -Fixes: e506ea451254 ("compiler.h: Split {READ,WRITE}_ONCE definitions out into rwonce.h") -Signed-off-by: Felix Fietkau ---- - include/linux/compiler.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/include/linux/compiler.h b/include/linux/compiler.h -index d18542d7e17b..23b43f6093b1 100644 ---- a/include/linux/compiler.h -+++ b/include/linux/compiler.h -@@ -191,6 +191,8 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val, - __v; \ - }) - -+#include -+ - #endif /* __KERNEL__ */ - - /** -@@ -298,6 +300,4 @@ static inline void *offset_to_ptr(const int *off) - */ - #define prevent_tail_call_optimization() mb() - --#include -- - #endif /* __LINUX_COMPILER_H */ --- -2.51.0 - - -From 65c264e73e6464600d94d7aa80a1513b0cc13d77 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Wed, 18 Apr 2018 10:50:05 +0200 -Subject: [PATCH 178/517] MIPS: only process negative stack offsets on stack - traces - -Fixes endless back traces in cases where the compiler emits a stack -pointer increase in a branch delay slot (probably for some form of -function return). - -[ 3.475442] BUG: MAX_STACK_TRACE_ENTRIES too low! -[ 3.480070] turning off the locking correctness validator. -[ 3.485521] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.14.34 #0 -[ 3.491475] Stack : 00000000 00000000 00000000 00000000 80e0fce2 00000034 00000000 00000000 -[ 3.499764] 87c3838c 80696377 8061047c 00000000 00000001 00000001 87c2d850 6534689f -[ 3.508059] 00000000 00000000 80e10000 00000000 00000000 000000cf 0000000f 00000000 -[ 3.516353] 00000000 806a0000 00076891 00000000 00000000 00000000 ffffffff 00000000 -[ 3.524648] 806c0000 00000004 80e10000 806a0000 00000003 80690000 00000000 80700000 -[ 3.532942] ... -[ 3.535362] Call Trace: -[ 3.537818] [<80010a48>] show_stack+0x58/0x100 -[ 3.542207] [<804c2f78>] dump_stack+0xe8/0x170 -[ 3.546613] [<80079f90>] save_trace+0xf0/0x110 -[ 3.551010] [<8007b1ec>] mark_lock+0x33c/0x78c -[ 3.555413] [<8007bf48>] __lock_acquire+0x2ac/0x1a08 -[ 3.560337] [<8007de60>] lock_acquire+0x64/0x8c -[ 3.564846] [<804e1570>] _raw_spin_lock_irqsave+0x54/0x78 -[ 3.570186] [<801b618c>] kernfs_notify+0x94/0xac -[ 3.574770] [<801b7b10>] sysfs_notify+0x74/0xa0 -[ 3.579257] [<801b618c>] kernfs_notify+0x94/0xac -[ 3.583839] [<801b7b10>] sysfs_notify+0x74/0xa0 -[ 3.588329] [<801b618c>] kernfs_notify+0x94/0xac -[ 3.592911] [<801b7b10>] sysfs_notify+0x74/0xa0 -[ 3.597401] [<801b618c>] kernfs_notify+0x94/0xac -[ 3.601983] [<801b7b10>] sysfs_notify+0x74/0xa0 -[ 3.606473] [<801b618c>] kernfs_notify+0x94/0xac -[ 3.611055] [<801b7b10>] sysfs_notify+0x74/0xa0 -[ 3.615545] [<801b618c>] kernfs_notify+0x94/0xac -[ 3.620125] [<801b7b10>] sysfs_notify+0x74/0xa0 -[ 3.624619] [<801b618c>] kernfs_notify+0x94/0xac -[ 3.629197] [<801b7b10>] sysfs_notify+0x74/0xa0 -[ 3.633691] [<801b618c>] kernfs_notify+0x94/0xac -[ 3.638269] [<801b7b10>] sysfs_notify+0x74/0xa0 -[ 3.642763] [<801b618c>] kernfs_notify+0x94/0xac - -Signed-off-by: Felix Fietkau ---- - arch/mips/kernel/process.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c -index 02aa6a04a21d..d84ff2484e6b 100644 ---- a/arch/mips/kernel/process.c -+++ b/arch/mips/kernel/process.c -@@ -395,6 +395,8 @@ static inline int is_sp_move_ins(union mips_instruction *ip, int *frame_size) - - if (ip->i_format.opcode == addiu_op || - ip->i_format.opcode == daddiu_op) { -+ if (ip->i_format.simmediate > 0) -+ return 0; - *frame_size = -ip->i_format.simmediate; - return 1; - } --- -2.51.0 - - -From 5fb9ed3fa96df7607d624af7500a8b28005008bb Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Sun, 9 Jul 2017 00:26:53 +0200 -Subject: [PATCH 179/517] kernel: add compile fix for linux 4.9 on x86 - -Signed-off-by: Felix Fietkau ---- - Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile b/Makefile -index d4c679b2d4bc..adebb89c7db4 100644 ---- a/Makefile -+++ b/Makefile -@@ -589,7 +589,7 @@ export RUSTC_BOOTSTRAP := 1 - # Allows finding `.clippy.toml` in out-of-srctree builds. - export CLIPPY_CONF_DIR := $(srctree) - --export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC HOSTPKG_CONFIG -+export ARCH SRCARCH SUBARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC HOSTPKG_CONFIG - export RUSTC RUSTDOC RUSTFMT RUSTC_OR_CLIPPY_QUIET RUSTC_OR_CLIPPY BINDGEN - export HOSTRUSTC KBUILD_HOSTRUSTFLAGS - export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL --- -2.51.0 - - -From 24ba3611cd2096392227e4f47f8970e7fc03d445 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pali=20Roh=C3=A1r?= -Date: Thu, 28 Apr 2022 11:13:23 +0200 -Subject: [PATCH 180/517] watchdog: max63xx_wdt: Add support for specifying WDI - logic via GPIO -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -On some boards is WDI logic of max6370 chip connected via GPIO. -So extend max63xx_wdt driver to allow specifying WDI logic via GPIO. - -Signed-off-by: Pali Rohár ---- - drivers/watchdog/max63xx_wdt.c | 24 ++++++++++++++++++++++++ - 1 file changed, 24 insertions(+) - -diff --git a/drivers/watchdog/max63xx_wdt.c b/drivers/watchdog/max63xx_wdt.c -index 21935f9620e4..041ae121f981 100644 ---- a/drivers/watchdog/max63xx_wdt.c -+++ b/drivers/watchdog/max63xx_wdt.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - - #define DEFAULT_HEARTBEAT 60 - #define MAX_HEARTBEAT 60 -@@ -50,6 +51,9 @@ struct max63xx_wdt { - void __iomem *base; - spinlock_t lock; - -+ /* GPIOs */ -+ struct gpio_desc *gpio_wdi; -+ - /* WDI and WSET bits write access routines */ - void (*ping)(struct max63xx_wdt *wdt); - void (*set)(struct max63xx_wdt *wdt, u8 set); -@@ -155,6 +159,17 @@ static const struct watchdog_info max63xx_wdt_info = { - .identity = "max63xx Watchdog", - }; - -+static void max63xx_gpio_ping(struct max63xx_wdt *wdt) -+{ -+ spin_lock(&wdt->lock); -+ -+ gpiod_set_value(wdt->gpio_wdi, 1); -+ udelay(1); -+ gpiod_set_value(wdt->gpio_wdi, 0); -+ -+ spin_unlock(&wdt->lock); -+} -+ - static void max63xx_mmap_ping(struct max63xx_wdt *wdt) - { - u8 val; -@@ -222,10 +237,19 @@ static int max63xx_wdt_probe(struct platform_device *pdev) - return -EINVAL; - } - -+ wdt->gpio_wdi = devm_gpiod_get(dev, NULL, GPIOD_FLAGS_BIT_DIR_OUT); -+ if (IS_ERR(wdt->gpio_wdi) && PTR_ERR(wdt->gpio_wdi) != -ENOENT) -+ return dev_err_probe(dev, PTR_ERR(wdt->gpio_wdi), -+ "unable to request gpio: %ld\n", -+ PTR_ERR(wdt->gpio_wdi)); -+ - err = max63xx_mmap_init(pdev, wdt); - if (err) - return err; - -+ if (!IS_ERR(wdt->gpio_wdi)) -+ wdt->ping = max63xx_gpio_ping; -+ - platform_set_drvdata(pdev, &wdt->wdd); - watchdog_set_drvdata(&wdt->wdd, wdt); - --- -2.51.0 - - -From 3a45749cae25f2d9e0eb86b03f7283dab7086b14 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Mon, 3 Nov 2025 15:49:31 +0100 -Subject: [PATCH 181/517] jffs2: use .rename2 and add RENAME_WHITEOUT support - -It is required for renames on overlayfs - -Signed-off-by: Felix Fietkau ---- - fs/jffs2/dir.c | 36 +++++++++++++++++++++++++++++------- - 1 file changed, 29 insertions(+), 7 deletions(-) - -diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c -index 2b2938970da3..8ceef593258e 100644 ---- a/fs/jffs2/dir.c -+++ b/fs/jffs2/dir.c -@@ -620,8 +620,8 @@ static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry) - return ret; - } - --static int jffs2_mknod (struct mnt_idmap *idmap, struct inode *dir_i, -- struct dentry *dentry, umode_t mode, dev_t rdev) -+static int __jffs2_mknod (struct mnt_idmap *idmap, struct inode *dir_i, -+ struct dentry *dentry, umode_t mode, dev_t rdev, bool whiteout) - { - struct jffs2_inode_info *f, *dir_f; - struct jffs2_sb_info *c; -@@ -761,7 +761,11 @@ static int jffs2_mknod (struct mnt_idmap *idmap, struct inode *dir_i, - mutex_unlock(&dir_f->sem); - jffs2_complete_reservation(c); - -- d_instantiate_new(dentry, inode); -+ if (!whiteout) -+ d_instantiate_new(dentry, inode); -+ else -+ unlock_new_inode(inode); -+ - return 0; - - fail: -@@ -769,6 +773,19 @@ static int jffs2_mknod (struct mnt_idmap *idmap, struct inode *dir_i, - return ret; - } - -+static int jffs2_mknod (struct mnt_idmap *idmap, struct inode *dir_i, -+ struct dentry *dentry, umode_t mode, dev_t rdev) -+{ -+ return __jffs2_mknod(idmap, dir_i, dentry, mode, rdev, false); -+} -+ -+static int jffs2_whiteout (struct mnt_idmap *idmap, struct inode *old_dir, -+ struct dentry *old_dentry) -+{ -+ return __jffs2_mknod(idmap, old_dir, old_dentry, S_IFCHR | WHITEOUT_MODE, -+ WHITEOUT_DEV, true); -+} -+ - static int jffs2_rename (struct mnt_idmap *idmap, - struct inode *old_dir_i, struct dentry *old_dentry, - struct inode *new_dir_i, struct dentry *new_dentry, -@@ -780,7 +797,7 @@ static int jffs2_rename (struct mnt_idmap *idmap, - uint8_t type; - uint32_t now; - -- if (flags & ~RENAME_NOREPLACE) -+ if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT)) - return -EINVAL; - - /* The VFS will check for us and prevent trying to rename a -@@ -846,9 +863,14 @@ static int jffs2_rename (struct mnt_idmap *idmap, - if (d_is_dir(old_dentry) && !victim_f) - inc_nlink(new_dir_i); - -- /* Unlink the original */ -- ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), -- old_dentry->d_name.name, old_dentry->d_name.len, NULL, now); -+ if (flags & RENAME_WHITEOUT) -+ /* Replace with whiteout */ -+ ret = jffs2_whiteout(idmap, old_dir_i, old_dentry); -+ else -+ /* Unlink the original */ -+ ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), -+ old_dentry->d_name.name, -+ old_dentry->d_name.len, NULL, now); - - /* We don't touch inode->i_nlink */ - --- -2.51.0 - - -From 3b035d50ebdd949b59df84accf8c390e5857869b Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Mon, 3 Nov 2025 15:49:32 +0100 -Subject: [PATCH 182/517] jffs2: add RENAME_EXCHANGE support - -Signed-off-by: Felix Fietkau ---- - fs/jffs2/dir.c | 27 +++++++++++++++++++++++---- - 1 file changed, 23 insertions(+), 4 deletions(-) - -diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c -index 8ceef593258e..198bc4bf6aed 100644 ---- a/fs/jffs2/dir.c -+++ b/fs/jffs2/dir.c -@@ -794,18 +794,31 @@ static int jffs2_rename (struct mnt_idmap *idmap, - int ret; - struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb); - struct jffs2_inode_info *victim_f = NULL; -+ struct inode *fst_inode = d_inode(old_dentry); -+ struct inode *snd_inode = d_inode(new_dentry); - uint8_t type; - uint32_t now; - -- if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT)) -+ if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT|RENAME_EXCHANGE)) - return -EINVAL; - -+ if ((flags & RENAME_EXCHANGE) && (old_dir_i != new_dir_i)) { -+ if (S_ISDIR(fst_inode->i_mode) && !S_ISDIR(snd_inode->i_mode)) { -+ inc_nlink(new_dir_i); -+ drop_nlink(old_dir_i); -+ } -+ else if (!S_ISDIR(fst_inode->i_mode) && S_ISDIR(snd_inode->i_mode)) { -+ drop_nlink(new_dir_i); -+ inc_nlink(old_dir_i); -+ } -+ } -+ - /* The VFS will check for us and prevent trying to rename a - * file over a directory and vice versa, but if it's a directory, - * the VFS can't check whether the victim is empty. The filesystem - * needs to do that for itself. - */ -- if (d_really_is_positive(new_dentry)) { -+ if (d_really_is_positive(new_dentry) && !(flags & RENAME_EXCHANGE)) { - victim_f = JFFS2_INODE_INFO(d_inode(new_dentry)); - if (d_is_dir(new_dentry)) { - struct jffs2_full_dirent *fd; -@@ -840,7 +853,7 @@ static int jffs2_rename (struct mnt_idmap *idmap, - if (ret) - return ret; - -- if (victim_f) { -+ if (victim_f && !(flags & RENAME_EXCHANGE)) { - /* There was a victim. Kill it off nicely */ - if (d_is_dir(new_dentry)) - clear_nlink(d_inode(new_dentry)); -@@ -866,6 +879,12 @@ static int jffs2_rename (struct mnt_idmap *idmap, - if (flags & RENAME_WHITEOUT) - /* Replace with whiteout */ - ret = jffs2_whiteout(idmap, old_dir_i, old_dentry); -+ else if (flags & RENAME_EXCHANGE) -+ /* Replace the original */ -+ ret = jffs2_do_link(c, JFFS2_INODE_INFO(old_dir_i), -+ d_inode(new_dentry)->i_ino, type, -+ old_dentry->d_name.name, old_dentry->d_name.len, -+ now); - else - /* Unlink the original */ - ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), -@@ -898,7 +917,7 @@ static int jffs2_rename (struct mnt_idmap *idmap, - return ret; - } - -- if (d_is_dir(old_dentry)) -+ if (d_is_dir(old_dentry) && !(flags & RENAME_EXCHANGE)) - drop_nlink(old_dir_i); - - inode_set_mtime_to_ts(old_dir_i, --- -2.51.0 - - -From 45c9e05782807facb6e64541dc9a86119ed266f1 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Mon, 3 Nov 2025 15:49:32 +0100 -Subject: [PATCH 183/517] jffs2: add splice ops - -Add splice_read using generic_file_splice_read. -Add splice_write using iter_file_splice_write - -Signed-off-by: Felix Fietkau ---- - fs/jffs2/file.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c -index 13c18ccc13b0..b08616967891 100644 ---- a/fs/jffs2/file.c -+++ b/fs/jffs2/file.c -@@ -53,6 +53,8 @@ const struct file_operations jffs2_file_operations = - .open = generic_file_open, - .read_iter = generic_file_read_iter, - .write_iter = generic_file_write_iter, -+ .splice_read = filemap_splice_read, -+ .splice_write = iter_file_splice_write, - .unlocked_ioctl=jffs2_ioctl, - .mmap = generic_file_readonly_mmap, - .fsync = jffs2_fsync, --- -2.51.0 - - -From f772c8f03f55a56dc910561555de3b1237994f1e Mon Sep 17 00:00:00 2001 -From: Stephen Hemminger -Date: Mon, 3 Nov 2025 15:49:32 +0100 -Subject: [PATCH 184/517] bridge: allow receiption on disabled port - -When an ethernet device is enslaved to a bridge, and the bridge STP -detects loss of carrier (or operational state down), then normally -packet receiption is blocked. - -This breaks control applications like WPA which maybe expecting to -receive packets to negotiate to bring link up. The bridge needs to -block forwarding packets from these disabled ports, but there is no -hard requirement to not allow local packet delivery. - -Signed-off-by: Stephen Hemminger -Signed-off-by: Felix Fietkau ---- - net/bridge/br_input.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c -index c059e5657db3..0332371d19ab 100644 ---- a/net/bridge/br_input.c -+++ b/net/bridge/br_input.c -@@ -245,6 +245,9 @@ static void __br_handle_local_finish(struct sk_buff *skb) - /* note: already called with rcu_read_lock */ - static int br_handle_local_finish(struct net *net, struct sock *sk, struct sk_buff *skb) - { -+ struct net_bridge_port *p = br_port_get_rcu(skb->dev); -+ -+ if (p->state != BR_STATE_DISABLED) - __br_handle_local_finish(skb); - - /* return 1 to signal the okfn() was called so it's ok to use the skb */ -@@ -416,6 +419,17 @@ static rx_handler_result_t br_handle_frame(struct sk_buff **pskb) - goto defer_stp_filtering; - - switch (p->state) { -+ case BR_STATE_DISABLED: -+ if (ether_addr_equal(p->br->dev->dev_addr, dest)) -+ skb->pkt_type = PACKET_HOST; -+ -+ if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, -+ dev_net(skb->dev), NULL, skb, skb->dev, NULL, -+ br_handle_local_finish) == 1) { -+ return RX_HANDLER_PASS; -+ } -+ break; -+ - case BR_STATE_FORWARDING: - case BR_STATE_LEARNING: - defer_stp_filtering: --- -2.51.0 - - -From f8a675acf745105364469ccd2c10ae11f0ff58dd Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Thu, 4 Jan 2024 15:21:21 +0100 -Subject: [PATCH 185/517] net: bridge: do not send arp replies if src and - target hw addr is the same - -There are broken devices in the wild that handle duplicate IP address -detection by sending out ARP requests for the IP that they received from a -DHCP server and refuse the address if they get a reply. -When proxyarp is enabled, they would go into a loop of requesting an address -and then NAKing it again. - -Link: https://github.com/openwrt/openwrt/issues/14309 -Signed-off-by: Felix Fietkau ---- - net/bridge/br_arp_nd_proxy.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/net/bridge/br_arp_nd_proxy.c b/net/bridge/br_arp_nd_proxy.c -index c7869a286df4..3a2770938374 100644 ---- a/net/bridge/br_arp_nd_proxy.c -+++ b/net/bridge/br_arp_nd_proxy.c -@@ -204,7 +204,10 @@ void br_do_proxy_suppress_arp(struct sk_buff *skb, struct net_bridge *br, - if ((p && (p->flags & BR_PROXYARP)) || - (f->dst && (f->dst->flags & BR_PROXYARP_WIFI)) || - br_is_neigh_suppress_enabled(f->dst, vid)) { -- if (!vid) -+ replied = true; -+ if (!memcmp(n->ha, sha, dev->addr_len)) -+ replied = false; -+ else if (!vid) - br_arp_send(br, p, skb->dev, sip, tip, - sha, n->ha, sha, 0, 0); - else -@@ -212,7 +215,6 @@ void br_do_proxy_suppress_arp(struct sk_buff *skb, struct net_bridge *br, - sha, n->ha, sha, - skb->vlan_proto, - skb_vlan_tag_get(skb)); -- replied = true; - } - - /* If we have replied or as long as we know the --- -2.51.0 - - -From 5e09714675351cc1bfc7be2cdf06a96371415a00 Mon Sep 17 00:00:00 2001 -From: Kees Cook -Date: Wed, 21 May 2025 23:27:04 +0200 -Subject: [PATCH 186/517] wireguard: global: add __nonstring annotations for - unterminated strings - -When a character array without a terminating NUL character has a static -initializer, GCC 15's -Wunterminated-string-initialization will only -warn if the array lacks the "nonstring" attribute[1]. Mark the arrays -with __nonstring to correctly identify the char array as "not a C string" -and thereby eliminate the warning: - -../drivers/net/wireguard/cookie.c:29:56: warning: initializer-string for array of 'unsigned char' truncates NUL terminator but destination lacks 'nonstring' attribute (9 chars into 8 available) [-Wunterminated-string-initialization] - 29 | static const u8 mac1_key_label[COOKIE_KEY_LABEL_LEN] = "mac1----"; - | ^~~~~~~~~~ -../drivers/net/wireguard/cookie.c:30:58: warning: initializer-string for array of 'unsigned char' truncates NUL terminator but destination lacks 'nonstring' attribute (9 chars into 8 available) [-Wunterminated-string-initialization] - 30 | static const u8 cookie_key_label[COOKIE_KEY_LABEL_LEN] = "cookie--"; - | ^~~~~~~~~~ -../drivers/net/wireguard/noise.c:28:38: warning: initializer-string for array of 'unsigned char' truncates NUL terminator but destination lacks 'nonstring' attribute (38 chars into 37 available) [-Wunterminated-string-initialization] - 28 | static const u8 handshake_name[37] = "Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s"; - | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -../drivers/net/wireguard/noise.c:29:39: warning: initializer-string for array of 'unsigned char' truncates NUL terminator but destination lacks 'nonstring' attribute (35 chars into 34 available) [-Wunterminated-string-initialization] - 29 | static const u8 identifier_name[34] = "WireGuard v1 zx2c4 Jason@zx2c4.com"; - | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The arrays are always used with their fixed size, so use __nonstring. - -Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117178 [1] -Signed-off-by: Kees Cook -Signed-off-by: Jason A. Donenfeld -Link: https://patch.msgid.link/20250521212707.1767879-3-Jason@zx2c4.com -Signed-off-by: Paolo Abeni ---- - drivers/net/wireguard/cookie.c | 4 ++-- - drivers/net/wireguard/noise.c | 4 ++-- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/drivers/net/wireguard/cookie.c b/drivers/net/wireguard/cookie.c -index f89581b5e8cb..94d0a7206084 100644 ---- a/drivers/net/wireguard/cookie.c -+++ b/drivers/net/wireguard/cookie.c -@@ -26,8 +26,8 @@ void wg_cookie_checker_init(struct cookie_checker *checker, - } - - enum { COOKIE_KEY_LABEL_LEN = 8 }; --static const u8 mac1_key_label[COOKIE_KEY_LABEL_LEN] = "mac1----"; --static const u8 cookie_key_label[COOKIE_KEY_LABEL_LEN] = "cookie--"; -+static const u8 mac1_key_label[COOKIE_KEY_LABEL_LEN] __nonstring = "mac1----"; -+static const u8 cookie_key_label[COOKIE_KEY_LABEL_LEN] __nonstring = "cookie--"; - - static void precompute_key(u8 key[NOISE_SYMMETRIC_KEY_LEN], - const u8 pubkey[NOISE_PUBLIC_KEY_LEN], -diff --git a/drivers/net/wireguard/noise.c b/drivers/net/wireguard/noise.c -index 202a33af5a72..7eb9a23a3d4d 100644 ---- a/drivers/net/wireguard/noise.c -+++ b/drivers/net/wireguard/noise.c -@@ -25,8 +25,8 @@ - * <- e, ee, se, psk, {} - */ - --static const u8 handshake_name[37] = "Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s"; --static const u8 identifier_name[34] = "WireGuard v1 zx2c4 Jason@zx2c4.com"; -+static const u8 handshake_name[37] __nonstring = "Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s"; -+static const u8 identifier_name[34] __nonstring = "WireGuard v1 zx2c4 Jason@zx2c4.com"; - static u8 handshake_init_hash[NOISE_HASH_LEN] __ro_after_init; - static u8 handshake_init_chaining_key[NOISE_HASH_LEN] __ro_after_init; - static atomic64_t keypair_counter = ATOMIC64_INIT(0); --- -2.51.0 - - -From 521a25813c3413cc25032dd5b0b090950f0057c8 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Daniel=20Gonz=C3=A1lez=20Cabanelas?= -Date: Mon, 3 Nov 2025 15:49:33 +0100 -Subject: [PATCH 187/517] rtc: rs5c372: support alarms up to 1 week -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The Ricoh R2221x, R2223x, RS5C372, RV5C387A chips can handle 1 week -alarms. - -Read the "wday" alarm register and convert it to a date to support up 1 -week in our driver. - -Signed-off-by: Daniel González Cabanelas ---- - drivers/rtc/rtc-rs5c372.c | 48 ++++++++++++++++++++++++++++++++++----- - 1 file changed, 42 insertions(+), 6 deletions(-) - -diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c -index f8fab0205f8c..e19aef158938 100644 ---- a/drivers/rtc/rtc-rs5c372.c -+++ b/drivers/rtc/rtc-rs5c372.c -@@ -399,7 +399,9 @@ static int rs5c_read_alarm(struct device *dev, struct rtc_wkalrm *t) - { - struct i2c_client *client = to_i2c_client(dev); - struct rs5c372 *rs5c = i2c_get_clientdata(client); -- int status; -+ int status, wday_offs; -+ struct rtc_time rtc; -+ unsigned long alarm_secs; - - status = rs5c_get_regs(rs5c); - if (status < 0) -@@ -409,6 +411,30 @@ static int rs5c_read_alarm(struct device *dev, struct rtc_wkalrm *t) - t->time.tm_sec = 0; - t->time.tm_min = bcd2bin(rs5c->regs[RS5C_REG_ALARM_A_MIN] & 0x7f); - t->time.tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C_REG_ALARM_A_HOURS]); -+ t->time.tm_wday = ffs(rs5c->regs[RS5C_REG_ALARM_A_WDAY] & 0x7f) - 1; -+ -+ /* determine the day, month and year based on alarm wday, taking as a -+ * reference the current time from the rtc -+ */ -+ status = rs5c372_rtc_read_time(dev, &rtc); -+ if (status < 0) -+ return status; -+ -+ wday_offs = t->time.tm_wday - rtc.tm_wday; -+ alarm_secs = mktime64(rtc.tm_year + 1900, -+ rtc.tm_mon + 1, -+ rtc.tm_mday + wday_offs, -+ t->time.tm_hour, -+ t->time.tm_min, -+ t->time.tm_sec); -+ -+ if (wday_offs < 0 || (wday_offs == 0 && -+ (t->time.tm_hour < rtc.tm_hour || -+ (t->time.tm_hour == rtc.tm_hour && -+ t->time.tm_min <= rtc.tm_min)))) -+ alarm_secs += 7 * 86400; -+ -+ rtc_time64_to_tm(alarm_secs, &t->time); - - /* ... and status */ - t->enabled = !!(rs5c->regs[RS5C_REG_CTRL1] & RS5C_CTRL1_AALE); -@@ -423,12 +449,20 @@ static int rs5c_set_alarm(struct device *dev, struct rtc_wkalrm *t) - struct rs5c372 *rs5c = i2c_get_clientdata(client); - int status, addr, i; - unsigned char buf[3]; -+ struct rtc_time rtc_tm; -+ unsigned long rtc_secs, alarm_secs; - -- /* only handle up to 24 hours in the future, like RTC_ALM_SET */ -- if (t->time.tm_mday != -1 -- || t->time.tm_mon != -1 -- || t->time.tm_year != -1) -+ /* chip only can handle alarms up to one week in the future*/ -+ status = rs5c372_rtc_read_time(dev, &rtc_tm); -+ if (status) -+ return status; -+ rtc_secs = rtc_tm_to_time64(&rtc_tm); -+ alarm_secs = rtc_tm_to_time64(&t->time); -+ if (alarm_secs >= rtc_secs + 7 * 86400) { -+ dev_err(dev, "%s: alarm maximum is one week in the future (%d)\n", -+ __func__, status); - return -EINVAL; -+ } - - /* REVISIT: round up tm_sec */ - -@@ -449,7 +483,9 @@ static int rs5c_set_alarm(struct device *dev, struct rtc_wkalrm *t) - /* set alarm */ - buf[0] = bin2bcd(t->time.tm_min); - buf[1] = rs5c_hr2reg(rs5c, t->time.tm_hour); -- buf[2] = 0x7f; /* any/all days */ -+ /* each bit is the day of the week, 0x7f means all days */ -+ buf[2] = (t->time.tm_wday >= 0 && t->time.tm_wday < 7) ? -+ BIT(t->time.tm_wday) : 0x7f; - - for (i = 0; i < sizeof(buf); i++) { - addr = RS5C_ADDR(RS5C_REG_ALARM_A_MIN + i); --- -2.51.0 - - -From 3625b65094981635964c425d20e84532c4f9ac11 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Daniel=20Gonz=C3=A1lez=20Cabanelas?= -Date: Mon, 3 Nov 2025 15:49:33 +0100 -Subject: [PATCH 188/517] rtc: rs5c372: let the alarm to be used as wakeup - source -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Currently there is no use for the interrupts on the rs5c372 RTC and the -wakealarm isn't enabled. There are some devices like NASes which use this -RTC to wake up from the power off state when the INTR pin is activated by -the alarm clock. - -Enable the alarm and let to be used as a wakeup source. - -Tested on a Buffalo LS421DE NAS. - -Signed-off-by: Daniel González Cabanelas ---- - drivers/rtc/rtc-rs5c372.c | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c -index e19aef158938..b3f7e859e5d5 100644 ---- a/drivers/rtc/rtc-rs5c372.c -+++ b/drivers/rtc/rtc-rs5c372.c -@@ -832,6 +832,7 @@ static int rs5c372_probe(struct i2c_client *client) - int err = 0; - int smbus_mode = 0; - struct rs5c372 *rs5c372; -+ bool rs5c372_can_wakeup_device = false; - - dev_dbg(&client->dev, "%s\n", __func__); - -@@ -868,6 +869,12 @@ static int rs5c372_probe(struct i2c_client *client) - rs5c372->type = id->driver_data; - } - -+#ifdef CONFIG_OF -+ if(of_property_read_bool(client->dev.of_node, -+ "wakeup-source")) -+ rs5c372_can_wakeup_device = true; -+#endif -+ - /* we read registers 0x0f then 0x00-0x0f; skip the first one */ - rs5c372->regs = &rs5c372->buf[1]; - rs5c372->smbus = smbus_mode; -@@ -901,6 +908,8 @@ static int rs5c372_probe(struct i2c_client *client) - goto exit; - } - -+ rs5c372->has_irq = 1; -+ - /* if the oscillator lost power and no other software (like - * the bootloader) set it up, do it here. - * -@@ -927,6 +936,10 @@ static int rs5c372_probe(struct i2c_client *client) - ); - - /* REVISIT use client->irq to register alarm irq ... */ -+ if (rs5c372_can_wakeup_device) { -+ device_init_wakeup(&client->dev, true); -+ } -+ - rs5c372->rtc = devm_rtc_device_register(&client->dev, - rs5c372_driver.driver.name, - &rs5c372_rtc_ops, THIS_MODULE); -@@ -940,6 +953,10 @@ static int rs5c372_probe(struct i2c_client *client) - if (err) - goto exit; - -+ /* the rs5c372 alarm only supports a minute accuracy */ -+ set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rs5c372->rtc->features); -+ clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rs5c372->rtc->features); -+ - return 0; - - exit: --- -2.51.0 - - -From aaa9613d88cfc960918632f6cdc33972cf14729b Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 15 Apr 2025 23:16:40 +0200 -Subject: [PATCH 189/517] ARM: 9404/1: arm32: fix boot hang with - HAVE_LD_DEAD_CODE_DATA_ELIMINATION - -It was reported that some SoC (mvebu based for example) hang on kernel -loading. A variant of the feature was present in OpenWrt from long ago -and adding the additional entry with KEEP, fix the problem. - -Fixes: ed0f94102251 ("ARM: 9404/1: arm32: enable HAVE_LD_DEAD_CODE_DATA_ELIMINATION") -Signed-off-by: Christian Marangi ---- - arch/arm/include/asm/vmlinux.lds.h | 10 +++++----- - arch/arm/kernel/vmlinux.lds.S | 4 ++-- - 2 files changed, 7 insertions(+), 7 deletions(-) - -diff --git a/arch/arm/include/asm/vmlinux.lds.h b/arch/arm/include/asm/vmlinux.lds.h -index 14811b4f48ec..c69205878256 100644 ---- a/arch/arm/include/asm/vmlinux.lds.h -+++ b/arch/arm/include/asm/vmlinux.lds.h -@@ -54,7 +54,7 @@ - #define IDMAP_TEXT \ - ALIGN_FUNCTION(); \ - __idmap_text_start = .; \ -- *(.idmap.text) \ -+ KEEP(*(.idmap.text)) \ - __idmap_text_end = .; \ - - #define ARM_DISCARD \ -@@ -114,12 +114,12 @@ - . = ALIGN(8); \ - .ARM.unwind_idx : { \ - __start_unwind_idx = .; \ -- *(.ARM.exidx*) \ -+ KEEP(*(.ARM.exidx*)) \ - __stop_unwind_idx = .; \ - } \ - .ARM.unwind_tab : { \ - __start_unwind_tab = .; \ -- *(.ARM.extab*) \ -+ KEEP(*(.ARM.extab*)) \ - __stop_unwind_tab = .; \ - } - -@@ -131,7 +131,7 @@ - __vectors_lma = .; \ - OVERLAY 0xffff0000 : NOCROSSREFS AT(__vectors_lma) { \ - .vectors { \ -- OVERLAY_KEEP(*(.vectors)) \ -+ KEEP(*(.vectors)) \ - } \ - .vectors.bhb.loop8 { \ - OVERLAY_KEEP(*(.vectors.bhb.loop8)) \ -@@ -149,7 +149,7 @@ - \ - __stubs_lma = .; \ - .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_lma) { \ -- *(.stubs) \ -+ KEEP(*(.stubs)) \ - } \ - ARM_LMA(__stubs, .stubs); \ - . = __stubs_lma + SIZEOF(.stubs); \ -diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S -index de373c6c2ae8..4d2ea49d6f84 100644 ---- a/arch/arm/kernel/vmlinux.lds.S -+++ b/arch/arm/kernel/vmlinux.lds.S -@@ -104,13 +104,13 @@ SECTIONS - } - .init.tagtable : { - __tagtable_begin = .; -- *(.taglist.init) -+ KEEP(*(.taglist.init)) - __tagtable_end = .; - } - #ifdef CONFIG_SMP_ON_UP - .init.smpalt : { - __smpalt_begin = .; -- *(.alt.smp.init) -+ KEEP(*(.alt.smp.init)) - __smpalt_end = .; - } - #endif --- -2.51.0 - - -From 66801cda68c3e0f05d3962565caf52d4abb6c98b Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Mon, 3 Nov 2025 15:49:34 +0100 -Subject: [PATCH 190/517] kernel: add a config option for keeping the kallsyms - table uncompressed, saving ~9kb kernel size after lzma on ar71xx - -[john@phrozen.org: added to my upstream queue 30.12.2016] -lede-commit: e0e3509b5ce2ccf93d4d67ea907613f5f7ec2eed -Signed-off-by: Felix Fietkau ---- - init/Kconfig | 11 +++++++++ - kernel/kallsyms.c | 8 ++++++ - kernel/vmcore_info.c | 2 ++ - scripts/kallsyms.c | 54 ++++++++++++++++++++++++++--------------- - scripts/link-vmlinux.sh | 4 +++ - 5 files changed, 59 insertions(+), 20 deletions(-) - -diff --git a/init/Kconfig b/init/Kconfig -index 219ccdb0af73..9b04e413be82 100644 ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -1534,6 +1534,17 @@ config SYSCTL_ARCH_UNALIGN_ALLOW - the unaligned access emulation. - see arch/parisc/kernel/unaligned.c for reference - -+config KALLSYMS_UNCOMPRESSED -+ bool "Keep kallsyms uncompressed" -+ depends on KALLSYMS -+ help -+ Normally kallsyms contains compressed symbols (using a token table), -+ reducing the uncompressed kernel image size. Keeping the symbol table -+ uncompressed significantly improves the size of this part in compressed -+ kernel images. -+ -+ Say N unless you need compressed kernel images to be small. -+ - config HAVE_PCSPKR_PLATFORM - bool - -diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c -index a9a0ca605d4a..82c9b31f5bf3 100644 ---- a/kernel/kallsyms.c -+++ b/kernel/kallsyms.c -@@ -69,6 +69,11 @@ static unsigned int kallsyms_expand_symbol(unsigned int off, - * For every byte on the compressed symbol data, copy the table - * entry for that byte. - */ -+#ifdef CONFIG_KALLSYMS_UNCOMPRESSED -+ memcpy(result, data + 1, len - 1); -+ result += len - 1; -+ len = 0; -+#endif - while (len) { - tptr = &kallsyms_token_table[kallsyms_token_index[*data]]; - data++; -@@ -101,6 +106,9 @@ static unsigned int kallsyms_expand_symbol(unsigned int off, - */ - static char kallsyms_get_symbol_type(unsigned int off) - { -+#ifdef CONFIG_KALLSYMS_UNCOMPRESSED -+ return kallsyms_names[off + 1]; -+#endif - /* - * Get just the first code, look it up in the token table, - * and return the first char from this token. -diff --git a/kernel/vmcore_info.c b/kernel/vmcore_info.c -index 1fec61603ef3..9345ac6cb454 100644 ---- a/kernel/vmcore_info.c -+++ b/kernel/vmcore_info.c -@@ -214,8 +214,10 @@ static int __init crash_save_vmcoreinfo_init(void) - #ifdef CONFIG_KALLSYMS - VMCOREINFO_SYMBOL(kallsyms_names); - VMCOREINFO_SYMBOL(kallsyms_num_syms); -+#ifndef CONFIG_KALLSYMS_UNCOMPRESSED - VMCOREINFO_SYMBOL(kallsyms_token_table); - VMCOREINFO_SYMBOL(kallsyms_token_index); -+#endif - VMCOREINFO_SYMBOL(kallsyms_offsets); - VMCOREINFO_SYMBOL(kallsyms_relative_base); - #endif /* CONFIG_KALLSYMS */ -diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c -index 03852da3d249..0c50cc494850 100644 ---- a/scripts/kallsyms.c -+++ b/scripts/kallsyms.c -@@ -62,6 +62,7 @@ static struct addr_range percpu_range = { - static struct sym_entry **table; - static unsigned int table_size, table_cnt; - static int all_symbols; -+static int uncompressed; - static int absolute_percpu; - - static int token_profit[0x10000]; -@@ -412,13 +413,17 @@ static void write_src(void) - for (k = 0; k < table[i]->len; k++) - printf(", 0x%02x", table[i]->sym[k]); - -- /* -- * Now that we wrote out the compressed symbol name, restore the -- * original name and print it in the comment. -- */ -- expand_symbol(table[i]->sym, table[i]->len, buf); -- strcpy((char *)table[i]->sym, buf); -- printf("\t/* %s */\n", table[i]->sym); -+ if (!uncompressed) { -+ /* -+ * Now that we wrote out the compressed symbol name, restore the -+ * original name and print it in the comment. -+ */ -+ expand_symbol(table[i]->sym, table[i]->len, buf); -+ strcpy((char *)table[i]->sym, buf); -+ printf("\t/* %s */\n", table[i]->sym); -+ } else { -+ printf("\n"); -+ } - } - printf("\n"); - -@@ -429,20 +434,22 @@ static void write_src(void) - - free(markers); - -- output_label("kallsyms_token_table"); -- off = 0; -- for (i = 0; i < 256; i++) { -- best_idx[i] = off; -- expand_symbol(best_table[i], best_table_len[i], buf); -- printf("\t.asciz\t\"%s\"\n", buf); -- off += strlen(buf) + 1; -- } -- printf("\n"); -+ if (!uncompressed) { -+ output_label("kallsyms_token_table"); -+ off = 0; -+ for (i = 0; i < 256; i++) { -+ best_idx[i] = off; -+ expand_symbol(best_table[i], best_table_len[i], buf); -+ printf("\t.asciz\t\"%s\"\n", buf); -+ off += strlen(buf) + 1; -+ } -+ printf("\n"); - -- output_label("kallsyms_token_index"); -- for (i = 0; i < 256; i++) -- printf("\t.short\t%d\n", best_idx[i]); -- printf("\n"); -+ output_label("kallsyms_token_index"); -+ for (i = 0; i < 256; i++) -+ printf("\t.short\t%d\n", best_idx[i]); -+ printf("\n"); -+ } - - output_label("kallsyms_offsets"); - -@@ -532,6 +539,9 @@ static unsigned char *find_token(unsigned char *str, int len, - { - int i; - -+ if (uncompressed) -+ return NULL; -+ - for (i = 0; i < len - 1; i++) { - if (str[i] == token[0] && str[i+1] == token[1]) - return &str[i]; -@@ -604,6 +614,9 @@ static void optimize_result(void) - { - int i, best; - -+ if (uncompressed) -+ return; -+ - /* using the '\0' symbol last allows compress_symbols to use standard - * fast string functions */ - for (i = 255; i >= 0; i--) { -@@ -763,6 +776,7 @@ int main(int argc, char **argv) - static const struct option long_options[] = { - {"all-symbols", no_argument, &all_symbols, 1}, - {"absolute-percpu", no_argument, &absolute_percpu, 1}, -+ {"uncompressed", no_argument, &uncompressed, 1}, - {}, - }; - -diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh -index a9b3f34a78d2..8013f57047b1 100755 ---- a/scripts/link-vmlinux.sh -+++ b/scripts/link-vmlinux.sh -@@ -144,6 +144,10 @@ kallsyms() - kallsymopt="${kallsymopt} --absolute-percpu" - fi - -+ if is_enabled CONFIG_KALLSYMS_UNCOMPRESSED; then -+ kallsymopt="${kallsymopt} --uncompressed" -+ fi -+ - info KSYMS "${2}.S" - scripts/kallsyms ${kallsymopt} "${1}" > "${2}.S" - --- -2.51.0 - - -From 27f5413d1222b8bde41e5383d85ecf0c9b1db242 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Mon, 3 Nov 2025 15:49:34 +0100 -Subject: [PATCH 191/517] kernel: when KALLSYMS is disabled, print module - address + size for matching backtrace entries - -[john@phrozen.org: felix will add this to his upstream queue] - -lede-commit 53827cdc824556cda910b23ce5030c363b8f1461 -Signed-off-by: Felix Fietkau ---- - lib/vsprintf.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - -diff --git a/lib/vsprintf.c b/lib/vsprintf.c -index a69e71a1ca55..5026d8912563 100644 ---- a/lib/vsprintf.c -+++ b/lib/vsprintf.c -@@ -983,8 +983,10 @@ char *symbol_string(char *buf, char *end, void *ptr, - struct printf_spec spec, const char *fmt) - { - unsigned long value; --#ifdef CONFIG_KALLSYMS - char sym[KSYM_SYMBOL_LEN]; -+#ifndef CONFIG_KALLSYMS -+ struct module *mod; -+ int len; - #endif - - if (fmt[1] == 'R') -@@ -1005,8 +1007,14 @@ char *symbol_string(char *buf, char *end, void *ptr, - - return string_nocheck(buf, end, sym, spec); - #else -- return special_hex_number(buf, end, value, sizeof(void *)); -+ len = snprintf(sym, sizeof(sym), "0x%lx", value); -+ mod = __module_address(value); -+ if (mod) -+ snprintf(sym + len, sizeof(sym) - len, " [%s@%p+0x%x]", -+ mod->name, mod->mem[MOD_TEXT].base, -+ mod->mem[MOD_TEXT].size); - #endif -+ return string(buf, end, sym, spec); - } - - static const struct printf_spec default_str_spec = { --- -2.51.0 - - -From 30746abd35d5550aed9f5b0152ebece730c5a889 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Mon, 3 Nov 2025 15:49:34 +0100 -Subject: [PATCH 192/517] usr: sanitize deps_initramfs list - -If any filename in the intramfs dependency -list contains a colon, that causes a kernel -build error like this: - -/devel/openwrt/build_dir/linux-ar71xx_generic/linux-3.6.6/usr/Makefile:58: *** multiple target patterns. Stop. -make[5]: *** [usr] Error 2 - -Fix it by removing such filenames from the -deps_initramfs list. - -Signed-off-by: Gabor Juhos -Signed-off-by: Felix Fietkau ---- - usr/Makefile | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/usr/Makefile b/usr/Makefile -index f1779496bca7..90398a751588 100644 ---- a/usr/Makefile -+++ b/usr/Makefile -@@ -56,6 +56,8 @@ hostprogs := gen_init_cpio - # The dependency list is generated by gen_initramfs.sh -l - -include $(obj)/.initramfs_data.cpio.d - -+deps_initramfs := $(foreach v,$(deps_initramfs),$(if $(findstring :,$(v)),,$(v))) -+ - # do not try to update files included in initramfs - $(deps_initramfs): ; - --- -2.51.0 - - -From 49d8ded1302b4decccc20ce90bc53db1b63a2107 Mon Sep 17 00:00:00 2001 -From: Hauke Mehrtens -Date: Fri, 27 Jun 2025 11:09:04 +0100 -Subject: [PATCH 193/517] kernel/fork: Increase minimum number of allowed - threads - -A modern Linux system creates much more than 20 threads at bootup. -When I booted up OpenWrt in qemu the system sometimes failed to boot up -when it wanted to create the 419th thread. The VM had 128MB RAM and the -calculation in set_max_threads() calculated that max_threads should be -set to 419. When the system booted up it tried to notify the user space -about every device it created because CONFIG_UEVENT_HELPER was set and -used. I counted 1299 calls to call_usermodehelper_setup(), all of -them try to create a new thread and call the userspace hotplug script in -it. - -This fixes bootup of Linux on systems with low memory. - -I saw the problem with qemu 10.0.2 using these commands: -qemu-system-aarch64 -machine virt -cpu cortex-a57 -nographic - -Cc: stable@vger.kernel.org -Signed-off-by: Hauke Mehrtens ---- - kernel/fork.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/kernel/fork.c b/kernel/fork.c -index e5ec098a6f61..4e2c63a1e737 100644 ---- a/kernel/fork.c -+++ b/kernel/fork.c -@@ -123,7 +123,7 @@ - /* - * Minimum number of threads to boot the kernel - */ --#define MIN_THREADS 20 -+#define MIN_THREADS 600 - - /* - * Maximum number of threads --- -2.51.0 - - -From 2efc136e2a89b64cb447127e0ebc0624a54e79f6 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Thibaut=20VAR=C3=88NE?= -Date: Sat, 28 Mar 2020 12:11:50 +0100 -Subject: [PATCH 194/517] generic: platform/mikrotik build bits (5.4) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This patch adds platform/mikrotik kernel build bits - -Signed-off-by: Thibaut VARÈNE ---- - drivers/platform/Kconfig | 2 ++ - drivers/platform/Makefile | 1 + - 2 files changed, 3 insertions(+) - -diff --git a/drivers/platform/Kconfig b/drivers/platform/Kconfig -index 960fd6a82450..ca7df46dcfd7 100644 ---- a/drivers/platform/Kconfig -+++ b/drivers/platform/Kconfig -@@ -18,3 +18,5 @@ source "drivers/platform/surface/Kconfig" - source "drivers/platform/x86/Kconfig" - - source "drivers/platform/arm64/Kconfig" -+ -+source "drivers/platform/mikrotik/Kconfig" -diff --git a/drivers/platform/Makefile b/drivers/platform/Makefile -index 19ac54648586..b77585bdc5cf 100644 ---- a/drivers/platform/Makefile -+++ b/drivers/platform/Makefile -@@ -13,3 +13,4 @@ obj-$(CONFIG_CHROME_PLATFORMS) += chrome/ - obj-$(CONFIG_CZNIC_PLATFORMS) += cznic/ - obj-$(CONFIG_SURFACE_PLATFORMS) += surface/ - obj-$(CONFIG_ARM64_PLATFORM_DEVICES) += arm64/ -+obj-$(CONFIG_MIKROTIK) += mikrotik/ --- -2.51.0 - - -From 1db3bd42bc37da847f5708ddaea12d9e1dc1c667 Mon Sep 17 00:00:00 2001 -From: Mark Miller -Date: Mon, 3 Nov 2025 15:49:35 +0100 -Subject: [PATCH 195/517] mips: expose CONFIG_BOOT_RAW - -This exposes the CONFIG_BOOT_RAW symbol in Kconfig. This is needed on -certain Broadcom chipsets running CFE in order to load the kernel. - -Signed-off-by: Mark Miller -Acked-by: Rob Landley ---- - arch/mips/Kconfig | 15 ++++++++++++--- - 1 file changed, 12 insertions(+), 3 deletions(-) - -diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig -index 5078ebf071ec..a330c7152049 100644 ---- a/arch/mips/Kconfig -+++ b/arch/mips/Kconfig -@@ -1055,9 +1055,6 @@ config FW_ARC - config ARCH_MAY_HAVE_PC_FDC - bool - --config BOOT_RAW -- bool -- - config CEVT_BCM1480 - bool - -@@ -2990,6 +2987,18 @@ choice - bool "Extend builtin kernel arguments with bootloader arguments" - endchoice - -+config BOOT_RAW -+ bool "Enable the kernel to be executed from the load address" -+ default n -+ help -+ Allow the kernel to be executed from the load address for -+ bootloaders which cannot read the ELF format. This places -+ a jump to start_kernel at the load address. -+ -+ If unsure, say N. -+ -+ -+ - endmenu - - config LOCKDEP_SUPPORT --- -2.51.0 - - -From cab68d173bcc34e6e4d7cfec9c69bb102bd5a6a9 Mon Sep 17 00:00:00 2001 -From: Paul Burton -Date: Mon, 22 Feb 2016 18:09:44 +0000 -Subject: [PATCH 196/517] MIPS: Add barriers between dcache & icache flushes - -Index-based cache operations may be arbitrarily reordered by out of -order CPUs. Thus code which writes back the dcache & then invalidates -the icache using indexed cache ops must include a barrier between -operating on the 2 caches in order to prevent the scenario in which: - - - icache invalidation occurs. - - - icache fetch occurs, due to speculation. - - - dcache writeback occurs. - -If the above were allowed to happen then the icache would contain stale -data. Forcing the dcache writeback to complete before the icache -invalidation avoids this. - -Signed-off-by: Paul Burton -Cc: James Hogan ---- - arch/mips/mm/c-r4k.c | 13 +++++++++++-- - 1 file changed, 11 insertions(+), 2 deletions(-) - -diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c -index 10413b6f6662..8e263048280f 100644 ---- a/arch/mips/mm/c-r4k.c -+++ b/arch/mips/mm/c-r4k.c -@@ -403,6 +403,7 @@ static inline void local_r4k___flush_cache_all(void * args) - - default: - r4k_blast_dcache(); -+ mb(); /* cache instructions may be reordered */ - r4k_blast_icache(); - break; - } -@@ -483,8 +484,10 @@ static inline void local_r4k_flush_cache_range(void * args) - if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) - r4k_blast_dcache(); - /* If executable, blast stale lines from icache */ -- if (exec) -+ if (exec) { -+ mb(); /* cache instructions may be reordered */ - r4k_blast_icache(); -+ } - } - - static void r4k_flush_cache_range(struct vm_area_struct *vma, -@@ -586,8 +589,13 @@ static inline void local_r4k_flush_cache_page(void *args) - if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) { - vaddr ? r4k_blast_dcache_page(addr) : - r4k_blast_dcache_user_page(addr); -- if (exec && !cpu_icache_snoops_remote_store) -+ if (exec) -+ mb(); /* cache instructions may be reordered */ -+ -+ if (exec && !cpu_icache_snoops_remote_store) { - r4k_blast_scache_page(addr); -+ mb(); /* cache instructions may be reordered */ -+ } - } - if (exec) { - if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) { -@@ -654,6 +662,7 @@ static inline void __local_r4k_flush_icache_range(unsigned long start, - else - blast_dcache_range(start, end); - } -+ mb(); /* cache instructions may be reordered */ - } - - if (type == R4K_INDEX || --- -2.51.0 - - -From 554dfd27393451b9120c52c5712714b3c1adf213 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Mon, 3 Nov 2025 15:49:36 +0100 -Subject: [PATCH 197/517] mips: use -mno-branch-likely for kernel and userspace - -saves ~11k kernel size after lzma and ~12k squashfs size in the - -lede-commit: 41a039f46450ffae9483d6216422098669da2900 -Signed-off-by: Felix Fietkau ---- - arch/mips/Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/mips/Makefile b/arch/mips/Makefile -index 5785a3d5ccfb..3e673b4a4a72 100644 ---- a/arch/mips/Makefile -+++ b/arch/mips/Makefile -@@ -94,7 +94,7 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlinuz - # machines may also. Since BFD is incredibly buggy with respect to - # crossformat linking we rely on the elf2ecoff tool for format conversion. - # --cflags-y += -G 0 -mno-abicalls -fno-pic -pipe -+cflags-y += -G 0 -mno-abicalls -fno-pic -pipe -mno-branch-likely - cflags-y += -msoft-float -Wa,-msoft-float - LDFLAGS_vmlinux += -G 0 -static -n -nostdlib - KBUILD_AFLAGS_MODULE += -mlong-calls --- -2.51.0 - - -From 7c5fa3df92251694f8253c39f0ee00b486676db5 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Mon, 3 Nov 2025 15:49:36 +0100 -Subject: [PATCH 198/517] kernel: add -mtune=34kc to MIPS CFLAGS when building - for mips32r2 - -This provides a good tradeoff across at least 24Kc-74Kc, while also -producing smaller code. - -Signed-off-by: Felix Fietkau ---- - arch/mips/Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/mips/Makefile b/arch/mips/Makefile -index 3e673b4a4a72..2a770f13a0cc 100644 ---- a/arch/mips/Makefile -+++ b/arch/mips/Makefile -@@ -153,7 +153,7 @@ cflags-$(CONFIG_CPU_R4300) += $(call cc-option,-march=r4300,-march=mips3) -Wa,-- - cflags-$(CONFIG_CPU_R4X00) += $(call cc-option,-march=r4600,-march=mips3) -Wa,--trap - cflags-$(CONFIG_CPU_TX49XX) += $(call cc-option,-march=r4600,-march=mips3) -Wa,--trap - cflags-$(CONFIG_CPU_MIPS32_R1) += -march=mips32 -Wa,--trap --cflags-$(CONFIG_CPU_MIPS32_R2) += -march=mips32r2 -Wa,--trap -+cflags-$(CONFIG_CPU_MIPS32_R2) += -march=mips32r2 -mtune=34kc -Wa,--trap - cflags-$(CONFIG_CPU_MIPS32_R5) += -march=mips32r5 -Wa,--trap -modd-spreg - cflags-$(CONFIG_CPU_MIPS32_R6) += -march=mips32r6 -Wa,--trap -modd-spreg - cflags-$(CONFIG_CPU_MIPS64_R1) += -march=mips64 -Wa,--trap --- -2.51.0 - - -From ace85c5c8e52425cb032edeba73b212530ee01f3 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Mon, 3 Nov 2025 15:49:36 +0100 -Subject: [PATCH 199/517] fix errors in unresolved weak symbols on arm - -lede-commit: 570699d4838a907c3ef9f2819bf19eb72997b32f -Signed-off-by: Felix Fietkau ---- - arch/arm/kernel/module.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c -index da488d92e7a0..2c4772fc494d 100644 ---- a/arch/arm/kernel/module.c -+++ b/arch/arm/kernel/module.c -@@ -112,6 +112,10 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, - return -ENOEXEC; - } - -+ if ((IS_ERR_VALUE(sym->st_value) || !sym->st_value) && -+ ELF_ST_BIND(sym->st_info) == STB_WEAK) -+ continue; -+ - loc = dstsec->sh_addr + rel->r_offset; - - switch (ELF32_R_TYPE(rel->r_info)) { --- -2.51.0 - - -From 52f2fac4a7eb8fb01f41028391e9f5686c11ecb6 Mon Sep 17 00:00:00 2001 -From: Yousong Zhou -Date: Mon, 3 Nov 2025 15:49:37 +0100 -Subject: [PATCH 200/517] MIPS: kexec: Accept command line parameters from - userspace. - -Signed-off-by: Yousong Zhou ---- - arch/mips/kernel/machine_kexec.c | 140 ++++++++++++++++++++++++++--- - arch/mips/kernel/machine_kexec.h | 20 +++++ - arch/mips/kernel/relocate_kernel.S | 20 +++-- - 3 files changed, 162 insertions(+), 18 deletions(-) - create mode 100644 arch/mips/kernel/machine_kexec.h - -diff --git a/arch/mips/kernel/machine_kexec.c b/arch/mips/kernel/machine_kexec.c -index 4e3579bbd620..528880faad34 100644 ---- a/arch/mips/kernel/machine_kexec.c -+++ b/arch/mips/kernel/machine_kexec.c -@@ -10,14 +10,11 @@ - #include - #include - -+#include - #include - #include -- --extern const unsigned char relocate_new_kernel[]; --extern const size_t relocate_new_kernel_size; -- --extern unsigned long kexec_start_address; --extern unsigned long kexec_indirection_page; -+#include -+#include "machine_kexec.h" - - static unsigned long reboot_code_buffer; - -@@ -31,6 +28,101 @@ void (*_crash_smp_send_stop)(void) = NULL; - void (*_machine_kexec_shutdown)(void) = NULL; - void (*_machine_crash_shutdown)(struct pt_regs *regs) = NULL; - -+static void machine_kexec_print_args(void) -+{ -+ unsigned long argc = (int)kexec_args[0]; -+ int i; -+ -+ pr_info("kexec_args[0] (argc): %lu\n", argc); -+ pr_info("kexec_args[1] (argv): %p\n", (void *)kexec_args[1]); -+ pr_info("kexec_args[2] (env ): %p\n", (void *)kexec_args[2]); -+ pr_info("kexec_args[3] (desc): %p\n", (void *)kexec_args[3]); -+ -+ for (i = 0; i < argc; i++) { -+ pr_info("kexec_argv[%d] = %p, %s\n", -+ i, kexec_argv[i], kexec_argv[i]); -+ } -+} -+ -+static void machine_kexec_init_argv(struct kimage *image) -+{ -+ void __user *buf = NULL; -+ size_t bufsz; -+ size_t size; -+ int i; -+ -+ bufsz = 0; -+ for (i = 0; i < image->nr_segments; i++) { -+ struct kexec_segment *seg; -+ -+ seg = &image->segment[i]; -+ if (seg->bufsz < 6) -+ continue; -+ -+ if (strncmp((char *) seg->buf, "kexec ", 6)) -+ continue; -+ -+ buf = seg->buf; -+ bufsz = seg->bufsz; -+ break; -+ } -+ -+ if (!buf) -+ return; -+ -+ size = KEXEC_COMMAND_LINE_SIZE; -+ size = min(size, bufsz); -+ if (size < bufsz) -+ pr_warn("kexec command line truncated to %zd bytes\n", size); -+ -+ /* Copy to kernel space */ -+ if (copy_from_user(kexec_argv_buf, buf, size)) -+ pr_warn("kexec command line copy to kernel space failed\n"); -+ -+ kexec_argv_buf[size - 1] = 0; -+} -+ -+static void machine_kexec_parse_argv(struct kimage *image) -+{ -+ char *reboot_code_buffer; -+ int reloc_delta; -+ char *ptr; -+ int argc; -+ int i; -+ -+ ptr = kexec_argv_buf; -+ argc = 0; -+ -+ /* -+ * convert command line string to array of parameters -+ * (as bootloader does). -+ */ -+ while (ptr && *ptr && (KEXEC_MAX_ARGC > argc)) { -+ if (*ptr == ' ') { -+ *ptr++ = '\0'; -+ continue; -+ } -+ -+ kexec_argv[argc++] = ptr; -+ ptr = strchr(ptr, ' '); -+ } -+ -+ if (!argc) -+ return; -+ -+ kexec_args[0] = argc; -+ kexec_args[1] = (unsigned long)kexec_argv; -+ kexec_args[2] = 0; -+ kexec_args[3] = 0; -+ -+ reboot_code_buffer = page_address(image->control_code_page); -+ reloc_delta = reboot_code_buffer - (char *)kexec_relocate_new_kernel; -+ -+ kexec_args[1] += reloc_delta; -+ for (i = 0; i < argc; i++) -+ kexec_argv[i] += reloc_delta; -+} -+ - static void kexec_image_info(const struct kimage *kimage) - { - unsigned long i; -@@ -100,6 +192,18 @@ machine_kexec_prepare(struct kimage *kimage) - #endif - - kexec_image_info(kimage); -+ /* -+ * Whenever arguments passed from kexec-tools, Init the arguments as -+ * the original ones to try avoiding booting failure. -+ */ -+ -+ kexec_args[0] = fw_arg0; -+ kexec_args[1] = fw_arg1; -+ kexec_args[2] = fw_arg2; -+ kexec_args[3] = fw_arg3; -+ -+ machine_kexec_init_argv(kimage); -+ machine_kexec_parse_argv(kimage); - - if (_machine_kexec_prepare) - return _machine_kexec_prepare(kimage); -@@ -162,7 +266,7 @@ machine_crash_shutdown(struct pt_regs *regs) - void kexec_nonboot_cpu_jump(void) - { - local_flush_icache_range((unsigned long)relocated_kexec_smp_wait, -- reboot_code_buffer + relocate_new_kernel_size); -+ reboot_code_buffer + KEXEC_RELOCATE_NEW_KERNEL_SIZE); - - relocated_kexec_smp_wait(NULL); - } -@@ -200,7 +304,7 @@ void kexec_reboot(void) - * machine_kexec() CPU. - */ - local_flush_icache_range(reboot_code_buffer, -- reboot_code_buffer + relocate_new_kernel_size); -+ reboot_code_buffer + KEXEC_RELOCATE_NEW_KERNEL_SIZE); - - do_kexec = (void *)reboot_code_buffer; - do_kexec(); -@@ -213,10 +317,12 @@ machine_kexec(struct kimage *image) - unsigned long *ptr; - - reboot_code_buffer = -- (unsigned long)page_address(image->control_code_page); -+ (unsigned long)page_address(image->control_code_page); -+ pr_info("reboot_code_buffer = %p\n", (void *)reboot_code_buffer); - - kexec_start_address = - (unsigned long) phys_to_virt(image->start); -+ pr_info("kexec_start_address = %p\n", (void *)kexec_start_address); - - if (image->type == KEXEC_TYPE_DEFAULT) { - kexec_indirection_page = -@@ -224,9 +330,19 @@ machine_kexec(struct kimage *image) - } else { - kexec_indirection_page = (unsigned long)&image->head; - } -+ pr_info("kexec_indirection_page = %p\n", (void *)kexec_indirection_page); -+ -+ pr_info("Where is memcpy: %p\n", memcpy); -+ pr_info("kexec_relocate_new_kernel = %p, kexec_relocate_new_kernel_end = %p\n", -+ (void *)kexec_relocate_new_kernel, &kexec_relocate_new_kernel_end); -+ pr_info("Copy %lu bytes from %p to %p\n", KEXEC_RELOCATE_NEW_KERNEL_SIZE, -+ (void *)kexec_relocate_new_kernel, (void *)reboot_code_buffer); -+ memcpy((void*)reboot_code_buffer, kexec_relocate_new_kernel, -+ KEXEC_RELOCATE_NEW_KERNEL_SIZE); - -- memcpy((void*)reboot_code_buffer, relocate_new_kernel, -- relocate_new_kernel_size); -+ pr_info("Before _print_args().\n"); -+ machine_kexec_print_args(); -+ pr_info("Before eval loop.\n"); - - /* - * The generic kexec code builds a page list with physical -@@ -257,7 +373,7 @@ machine_kexec(struct kimage *image) - #ifdef CONFIG_SMP - /* All secondary cpus now may jump to kexec_wait cycle */ - relocated_kexec_smp_wait = reboot_code_buffer + -- (void *)(kexec_smp_wait - relocate_new_kernel); -+ (void *)(kexec_smp_wait - kexec_relocate_new_kernel); - smp_wmb(); - atomic_set(&kexec_ready_to_reboot, 1); - #endif -diff --git a/arch/mips/kernel/machine_kexec.h b/arch/mips/kernel/machine_kexec.h -new file mode 100644 -index 000000000000..ae0961e29820 ---- /dev/null -+++ b/arch/mips/kernel/machine_kexec.h -@@ -0,0 +1,20 @@ -+#ifndef _MACHINE_KEXEC_H -+#define _MACHINE_KEXEC_H -+ -+#ifndef __ASSEMBLY__ -+extern const unsigned char kexec_relocate_new_kernel[]; -+extern unsigned long kexec_relocate_new_kernel_end; -+extern unsigned long kexec_start_address; -+extern unsigned long kexec_indirection_page; -+ -+extern char kexec_argv_buf[]; -+extern char *kexec_argv[]; -+ -+#define KEXEC_RELOCATE_NEW_KERNEL_SIZE ((unsigned long)&kexec_relocate_new_kernel_end - (unsigned long)kexec_relocate_new_kernel) -+#endif /* !__ASSEMBLY__ */ -+ -+#define KEXEC_COMMAND_LINE_SIZE 256 -+#define KEXEC_ARGV_SIZE (KEXEC_COMMAND_LINE_SIZE / 16) -+#define KEXEC_MAX_ARGC (KEXEC_ARGV_SIZE / sizeof(long)) -+ -+#endif -diff --git a/arch/mips/kernel/relocate_kernel.S b/arch/mips/kernel/relocate_kernel.S -index de894a0211d7..a43c683cfd2b 100644 ---- a/arch/mips/kernel/relocate_kernel.S -+++ b/arch/mips/kernel/relocate_kernel.S -@@ -10,10 +10,11 @@ - #include - #include - #include -+#include "machine_kexec.h" - - #include - --LEAF(relocate_new_kernel) -+LEAF(kexec_relocate_new_kernel) - PTR_L a0, arg0 - PTR_L a1, arg1 - PTR_L a2, arg2 -@@ -97,7 +98,7 @@ done: - #endif - /* jump to kexec_start_address */ - j s1 -- END(relocate_new_kernel) -+ END(kexec_relocate_new_kernel) - - #ifdef CONFIG_SMP - /* -@@ -176,8 +177,15 @@ EXPORT(kexec_indirection_page) - PTR_WD 0 - .size kexec_indirection_page, PTRSIZE - --relocate_new_kernel_end: -+kexec_argv_buf: -+ EXPORT(kexec_argv_buf) -+ .skip KEXEC_COMMAND_LINE_SIZE -+ .size kexec_argv_buf, KEXEC_COMMAND_LINE_SIZE - --EXPORT(relocate_new_kernel_size) -- PTR_WD relocate_new_kernel_end - relocate_new_kernel -- .size relocate_new_kernel_size, PTRSIZE -+kexec_argv: -+ EXPORT(kexec_argv) -+ .skip KEXEC_ARGV_SIZE -+ .size kexec_argv, KEXEC_ARGV_SIZE -+ -+kexec_relocate_new_kernel_end: -+ EXPORT(kexec_relocate_new_kernel_end) --- -2.51.0 - - -From 5c80cdad5775fcd000f09a0bc2895dd3c6140644 Mon Sep 17 00:00:00 2001 -From: Evgeniy Didin -Date: Fri, 15 Mar 2019 18:53:38 +0300 -Subject: [PATCH 201/517] arc add OWRTDTB section - -This change allows OpenWRT to patch resulting kernel binary with -external .dtb. - -That allows us to re-use exactky the same vmlinux on different boards -given its ARC core configurations match (at least cache line sizes etc). - -""patch-dtb" searches for ASCII "OWRTDTB:" strign and copies external -.dtb right after it, keeping the string in place. - -Signed-off-by: Eugeniy Paltsev -Signed-off-by: Alexey Brodkin -Signed-off-by: Evgeniy Didin ---- - arch/arc/kernel/head.S | 10 ++++++++++ - arch/arc/kernel/setup.c | 4 +++- - arch/arc/kernel/vmlinux.lds.S | 13 +++++++++++++ - 3 files changed, 26 insertions(+), 1 deletion(-) - -diff --git a/arch/arc/kernel/head.S b/arch/arc/kernel/head.S -index 8d541f53fae3..c37f130c4bcc 100644 ---- a/arch/arc/kernel/head.S -+++ b/arch/arc/kernel/head.S -@@ -88,6 +88,16 @@ - DSP_EARLY_INIT - .endm - -+ ; Here "patch-dtb" will embed external .dtb -+ ; Note "patch-dtb" searches for ASCII "OWRTDTB:" string -+ ; and pastes .dtb right after it, hense the string precedes -+ ; __image_dtb symbol. -+ .section .owrt, "aw",@progbits -+ .ascii "OWRTDTB:" -+ENTRY(__image_dtb) -+ .fill 0x4000 -+END(__image_dtb) -+ - .section .init.text, "ax",@progbits - - ;---------------------------------------------------------------- -diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c -index 7b6a9beba9db..0d07dfea5c00 100644 ---- a/arch/arc/kernel/setup.c -+++ b/arch/arc/kernel/setup.c -@@ -450,6 +450,8 @@ static inline bool uboot_arg_invalid(unsigned long addr) - /* We always pass 0 as magic from U-boot */ - #define UBOOT_MAGIC_VALUE 0 - -+extern struct boot_param_header __image_dtb; -+ - void __init handle_uboot_args(void) - { - bool use_embedded_dtb = true; -@@ -488,7 +490,7 @@ void __init handle_uboot_args(void) - ignore_uboot_args: - - if (use_embedded_dtb) { -- machine_desc = setup_machine_fdt(__dtb_start); -+ machine_desc = setup_machine_fdt(&__image_dtb); - if (!machine_desc) - panic("Embedded DT invalid\n"); - } -diff --git a/arch/arc/kernel/vmlinux.lds.S b/arch/arc/kernel/vmlinux.lds.S -index 61a1b2b96e1d..eef52a1711dd 100644 ---- a/arch/arc/kernel/vmlinux.lds.S -+++ b/arch/arc/kernel/vmlinux.lds.S -@@ -27,6 +27,19 @@ SECTIONS - - . = CONFIG_LINUX_LINK_BASE; - -+ /* -+ * In OpenWRT we want to patch built binary embedding .dtb of choice. -+ * This is implemented with "patch-dtb" utility which searches for -+ * "OWRTDTB:" string in first 16k of image and if it is found -+ * copies .dtb right after mentioned string. -+ * -+ * Note: "OWRTDTB:" won't be overwritten with .dtb, .dtb will follow it. -+ */ -+ .owrt : { -+ *(.owrt) -+ . = ALIGN(PAGE_SIZE); -+ } -+ - _int_vec_base_lds = .; - .vector : { - *(.vector) --- -2.51.0 - - -From f935ead65589a7cd7b0ad26c3927095d6431cc61 Mon Sep 17 00:00:00 2001 -From: Alexey Brodkin -Date: Mon, 3 Nov 2025 15:49:37 +0100 -Subject: [PATCH 202/517] arc: enable unaligned access in kernel mode - -This enables misaligned access handling even in kernel mode. -Some wireless drivers (ath9k-htc and mt7601u) use misaligned accesses -here and there and to cope with that without fixing stuff in the drivers -we're just gracefully handling it on ARC. - -Signed-off-by: Alexey Brodkin ---- - arch/arc/kernel/unaligned.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arc/kernel/unaligned.c b/arch/arc/kernel/unaligned.c -index d2f5ceaaed1b..691db93b7808 100644 ---- a/arch/arc/kernel/unaligned.c -+++ b/arch/arc/kernel/unaligned.c -@@ -203,7 +203,7 @@ int misaligned_fixup(unsigned long address, struct pt_regs *regs, - char buf[TASK_COMM_LEN]; - - /* handle user mode only and only if enabled by sysadmin */ -- if (!user_mode(regs) || !unaligned_enabled) -+ if (!unaligned_enabled) - return 1; - - if (no_unaligned_warning) { --- -2.51.0 - - -From 1bcfd87046f51fc0cee1585efd6503f2ab964de2 Mon Sep 17 00:00:00 2001 -From: Pawel Dembicki -Date: Fri, 24 May 2019 17:56:19 +0200 -Subject: [PATCH 203/517] powerpc: Enable kernel XZ compression option on - PPC_85xx - -Enable kernel XZ compression option on PPC_85xx. Tested with -simpleImage on TP-Link TL-WDR4900 (Freescale P1014 processor). - -Suggested-by: Christian Lamparter -Signed-off-by: Pawel Dembicki ---- - arch/powerpc/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig -index c7b420d6787c..3ac7c2b165bf 100644 ---- a/arch/powerpc/Kconfig -+++ b/arch/powerpc/Kconfig -@@ -254,7 +254,7 @@ config PPC - select HAVE_KERNEL_GZIP - select HAVE_KERNEL_LZMA if DEFAULT_UIMAGE - select HAVE_KERNEL_LZO if DEFAULT_UIMAGE -- select HAVE_KERNEL_XZ if PPC_BOOK3S || 44x -+ select HAVE_KERNEL_XZ if PPC_BOOK3S || 44x || PPC_85xx - select HAVE_KPROBES - select HAVE_KPROBES_ON_FTRACE - select HAVE_KRETPROBES --- -2.51.0 - - -From 1d71b6137b632023a25f974e578be3d2c522c4d7 Mon Sep 17 00:00:00 2001 -From: Shiji Yang -Date: Wed, 13 Mar 2024 20:28:37 +0800 -Subject: [PATCH 204/517] mips: kernel: fix detect_memory_region() function - -1. Do not use memcmp() on unallocated memory, as the new introduced - fortify dynamic object size check[1] will report unexpected result. -2. Use a fixed pattern instead of a random function pointer as the - magic value. -3. Flip magic value and double check it. -4. Enable this feature only for 32-bit CPUs. Currently, only ath79 and - ralink CPUs are using it. - -[1] 439a1bcac648 ("fortify: Use __builtin_dynamic_object_size() when available") -Signed-off-by: Shiji Yang ---- - arch/mips/include/asm/bootinfo.h | 2 ++ - arch/mips/kernel/setup.c | 17 ++++++++++++----- - 2 files changed, 14 insertions(+), 5 deletions(-) - -diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h -index 2128ba903391..8516c11916a4 100644 ---- a/arch/mips/include/asm/bootinfo.h -+++ b/arch/mips/include/asm/bootinfo.h -@@ -93,7 +93,9 @@ const char *get_system_type(void); - - extern unsigned long mips_machtype; - -+#ifndef CONFIG_64BIT - extern void detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max); -+#endif - - extern void prom_init(void); - extern void prom_free_prom_memory(void); -diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c -index 12a1a4ffb602..3a3bc1b7e62e 100644 ---- a/arch/mips/kernel/setup.c -+++ b/arch/mips/kernel/setup.c -@@ -86,21 +86,27 @@ static struct resource bss_resource = { .name = "Kernel bss", }; - unsigned long __kaslr_offset __ro_after_init; - EXPORT_SYMBOL(__kaslr_offset); - --static void *detect_magic __initdata = detect_memory_region; -- - #ifdef CONFIG_MIPS_AUTO_PFN_OFFSET - unsigned long ARCH_PFN_OFFSET; - EXPORT_SYMBOL(ARCH_PFN_OFFSET); - #endif - -+#ifndef CONFIG_64BIT -+static u32 detect_magic __initdata; -+#define MIPS_MEM_TEST_PATTERN 0xaa5555aa -+ - void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max) - { -- void *dm = &detect_magic; -+ void *dm = (void *)KSEG1ADDR(&detect_magic); - phys_addr_t size; - - for (size = sz_min; size < sz_max; size <<= 1) { -- if (!memcmp(dm, dm + size, sizeof(detect_magic))) -- break; -+ __raw_writel(MIPS_MEM_TEST_PATTERN, dm); -+ if (__raw_readl(dm) == __raw_readl(dm + size)) { -+ __raw_writel(~MIPS_MEM_TEST_PATTERN, dm); -+ if (__raw_readl(dm) == __raw_readl(dm + size)) -+ break; -+ } - } - - pr_debug("Memory: %lluMB of RAM detected at 0x%llx (min: %lluMB, max: %lluMB)\n", -@@ -111,6 +117,7 @@ void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_add - - memblock_add(start, size); - } -+#endif /* CONFIG_64BIT */ - - /* - * Manage initrd --- -2.51.0 - - -From ee65cfab6741cd60ae4734b50f82919a58205ae2 Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 11:47:35 +0200 -Subject: [PATCH 205/517] mtd: mtdsplit support - ---- - drivers/mtd/Kconfig | 19 ++++ - drivers/mtd/Makefile | 2 + - drivers/mtd/mtdpart.c | 170 ++++++++++++++++++++++++++++----- - include/linux/mtd/mtd.h | 25 +++++ - include/linux/mtd/partitions.h | 7 ++ - 5 files changed, 198 insertions(+), 25 deletions(-) - -diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig -index 796a2eccbef0..f9ed93c4cf0f 100644 ---- a/drivers/mtd/Kconfig -+++ b/drivers/mtd/Kconfig -@@ -12,6 +12,25 @@ menuconfig MTD - - if MTD - -+menu "OpenWrt specific MTD options" -+ -+config MTD_ROOTFS_ROOT_DEV -+ bool "Automatically set 'rootfs' partition to be root filesystem" -+ default y -+ -+config MTD_SPLIT_FIRMWARE -+ bool "Automatically split firmware partition for kernel+rootfs" -+ default y -+ -+config MTD_SPLIT_FIRMWARE_NAME -+ string "Firmware partition name" -+ depends on MTD_SPLIT_FIRMWARE -+ default "firmware" -+ -+source "drivers/mtd/mtdsplit/Kconfig" -+ -+endmenu -+ - config MTD_TESTS - tristate "MTD tests support (DANGEROUS)" - depends on m -diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile -index 593d0593a038..b14b7fe0f597 100644 ---- a/drivers/mtd/Makefile -+++ b/drivers/mtd/Makefile -@@ -9,6 +9,8 @@ mtd-y := mtdcore.o mtdsuper.o mtdconcat.o mtdpart.o mtdchar.o - - obj-y += parsers/ - -+obj-$(CONFIG_MTD_SPLIT) += mtdsplit/ -+ - # 'Users' - code which presents functionality to userspace. - obj-$(CONFIG_MTD_BLKDEVS) += mtd_blkdevs.o - obj-$(CONFIG_MTD_BLOCK) += mtdblock.o -diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c -index 6811a714349d..10ae49b9702a 100644 ---- a/drivers/mtd/mtdpart.c -+++ b/drivers/mtd/mtdpart.c -@@ -15,11 +15,13 @@ - #include - #include - #include -+#include - #include - #include - #include - - #include "mtdcore.h" -+#include "mtdsplit/mtdsplit.h" - - /* - * MTD methods which simply translate the effective address and pass through -@@ -242,6 +244,147 @@ static int mtd_add_partition_attrs(struct mtd_info *new) - return ret; - } - -+static DEFINE_SPINLOCK(part_parser_lock); -+static LIST_HEAD(part_parsers); -+ -+static struct mtd_part_parser *mtd_part_parser_get(const char *name) -+{ -+ struct mtd_part_parser *p, *ret = NULL; -+ -+ spin_lock(&part_parser_lock); -+ -+ list_for_each_entry(p, &part_parsers, list) -+ if (!strcmp(p->name, name) && try_module_get(p->owner)) { -+ ret = p; -+ break; -+ } -+ -+ spin_unlock(&part_parser_lock); -+ -+ return ret; -+} -+ -+static inline void mtd_part_parser_put(const struct mtd_part_parser *p) -+{ -+ module_put(p->owner); -+} -+ -+static struct mtd_part_parser * -+get_partition_parser_by_type(enum mtd_parser_type type, -+ struct mtd_part_parser *start) -+{ -+ struct mtd_part_parser *p, *ret = NULL; -+ -+ spin_lock(&part_parser_lock); -+ -+ p = list_prepare_entry(start, &part_parsers, list); -+ if (start) -+ mtd_part_parser_put(start); -+ -+ list_for_each_entry_continue(p, &part_parsers, list) { -+ if (p->type == type && try_module_get(p->owner)) { -+ ret = p; -+ break; -+ } -+ } -+ -+ spin_unlock(&part_parser_lock); -+ -+ return ret; -+} -+ -+static int parse_mtd_partitions_by_type(struct mtd_info *master, -+ enum mtd_parser_type type, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct mtd_part_parser *prev = NULL; -+ int ret = 0; -+ -+ while (1) { -+ struct mtd_part_parser *parser; -+ -+ parser = get_partition_parser_by_type(type, prev); -+ if (!parser) -+ break; -+ -+ ret = (*parser->parse_fn)(master, pparts, data); -+ -+ if (ret > 0) { -+ mtd_part_parser_put(parser); -+ printk(KERN_NOTICE -+ "%d %s partitions found on MTD device %s\n", -+ ret, parser->name, master->name); -+ break; -+ } -+ -+ prev = parser; -+ } -+ -+ return ret; -+} -+ -+static int -+run_parsers_by_type(struct mtd_info *child, enum mtd_parser_type type) -+{ -+ struct mtd_partition *parts; -+ int nr_parts; -+ int i; -+ -+ nr_parts = parse_mtd_partitions_by_type(child, type, (const struct mtd_partition **)&parts, -+ NULL); -+ if (nr_parts <= 0) -+ return nr_parts; -+ -+ if (WARN_ON(!parts)) -+ return 0; -+ -+ for (i = 0; i < nr_parts; i++) { -+ /* adjust partition offsets */ -+ parts[i].offset += child->part.offset; -+ -+ mtd_add_partition(child->parent, -+ parts[i].name, -+ parts[i].offset, -+ parts[i].size); -+ } -+ -+ kfree(parts); -+ -+ return nr_parts; -+} -+ -+#ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME -+#define SPLIT_FIRMWARE_NAME CONFIG_MTD_SPLIT_FIRMWARE_NAME -+#else -+#define SPLIT_FIRMWARE_NAME "unused" -+#endif -+ -+static void split_firmware(struct mtd_info *master, struct mtd_info *part) -+{ -+ run_parsers_by_type(part, MTD_PARSER_TYPE_FIRMWARE); -+} -+ -+static void mtd_partition_split(struct mtd_info *master, struct mtd_info *part) -+{ -+ static int rootfs_found = 0; -+ -+ if (rootfs_found) -+ return; -+ -+ if (of_find_property(mtd_get_of_node(part), "linux,rootfs", NULL) || -+ !strcmp(part->name, "rootfs")) { -+ run_parsers_by_type(part, MTD_PARSER_TYPE_ROOTFS); -+ -+ rootfs_found = 1; -+ } -+ -+ if (IS_ENABLED(CONFIG_MTD_SPLIT_FIRMWARE) && -+ !strcmp(part->name, SPLIT_FIRMWARE_NAME) && -+ !of_find_property(mtd_get_of_node(part), "compatible", NULL)) -+ split_firmware(master, part); -+} -+ - int mtd_add_partition(struct mtd_info *parent, const char *name, - long long offset, long long length) - { -@@ -280,6 +423,7 @@ int mtd_add_partition(struct mtd_info *parent, const char *name, - if (ret) - goto err_remove_part; - -+ mtd_partition_split(parent, child); - mtd_add_partition_attrs(child); - - return 0; -@@ -423,6 +567,7 @@ int add_mtd_partitions(struct mtd_info *parent, - goto err_del_partitions; - } - -+ mtd_partition_split(master, child); - mtd_add_partition_attrs(child); - - /* Look for subpartitions */ -@@ -443,31 +588,6 @@ int add_mtd_partitions(struct mtd_info *parent, - return ret; - } - --static DEFINE_SPINLOCK(part_parser_lock); --static LIST_HEAD(part_parsers); -- --static struct mtd_part_parser *mtd_part_parser_get(const char *name) --{ -- struct mtd_part_parser *p, *ret = NULL; -- -- spin_lock(&part_parser_lock); -- -- list_for_each_entry(p, &part_parsers, list) -- if (!strcmp(p->name, name) && try_module_get(p->owner)) { -- ret = p; -- break; -- } -- -- spin_unlock(&part_parser_lock); -- -- return ret; --} -- --static inline void mtd_part_parser_put(const struct mtd_part_parser *p) --{ -- module_put(p->owner); --} -- - /* - * Many partition parsers just expected the core to kfree() all their data in - * one chunk. Do that by default. -diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h -index 8d10d9d2e830..ed22b5e4cfc6 100644 ---- a/include/linux/mtd/mtd.h -+++ b/include/linux/mtd/mtd.h -@@ -615,6 +615,24 @@ static inline void mtd_align_erase_req(struct mtd_info *mtd, - req->len += mtd->erasesize - mod; - } - -+static inline uint64_t mtd_roundup_to_eb(uint64_t sz, struct mtd_info *mtd) -+{ -+ if (mtd_mod_by_eb(sz, mtd) == 0) -+ return sz; -+ -+ /* Round up to next erase block */ -+ return (mtd_div_by_eb(sz, mtd) + 1) * mtd->erasesize; -+} -+ -+static inline uint64_t mtd_rounddown_to_eb(uint64_t sz, struct mtd_info *mtd) -+{ -+ if (mtd_mod_by_eb(sz, mtd) == 0) -+ return sz; -+ -+ /* Round down to the start of the current erase block */ -+ return (mtd_div_by_eb(sz, mtd)) * mtd->erasesize; -+} -+ - static inline uint32_t mtd_div_by_ws(uint64_t sz, struct mtd_info *mtd) - { - if (mtd->writesize_shift) -@@ -688,6 +706,13 @@ extern struct mtd_info *of_get_mtd_device_by_node(struct device_node *np); - extern struct mtd_info *get_mtd_device_nm(const char *name); - extern void put_mtd_device(struct mtd_info *mtd); - -+static inline uint64_t mtdpart_get_offset(const struct mtd_info *mtd) -+{ -+ if (!mtd_is_partition(mtd)) -+ return 0; -+ -+ return mtd->part.offset; -+} - - struct mtd_notifier { - void (*add)(struct mtd_info *mtd); -diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h -index b74a539ec581..65ba0dbf961d 100644 ---- a/include/linux/mtd/partitions.h -+++ b/include/linux/mtd/partitions.h -@@ -75,6 +75,12 @@ struct mtd_part_parser_data { - * Functions dealing with the various ways of partitioning the space - */ - -+enum mtd_parser_type { -+ MTD_PARSER_TYPE_DEVICE = 0, -+ MTD_PARSER_TYPE_ROOTFS, -+ MTD_PARSER_TYPE_FIRMWARE, -+}; -+ - struct mtd_part_parser { - struct list_head list; - struct module *owner; -@@ -83,6 +89,7 @@ struct mtd_part_parser { - int (*parse_fn)(struct mtd_info *, const struct mtd_partition **, - struct mtd_part_parser_data *); - void (*cleanup)(const struct mtd_partition *pparts, int nr_parts); -+ enum mtd_parser_type type; - }; - - /* Container for passing around a set of parsed partitions */ --- -2.51.0 - - -From b1bb268ee57b27be82e74377901ac602f9d049e4 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Tue, 31 Oct 2023 15:51:01 +0100 -Subject: [PATCH 206/517] mtd: don't register NVMEM devices for partitions with - custom drivers -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This fixes issue exposed by upstream commit f4cf4e5db331 ("Revert -"nvmem: add new config option""). - -Signed-off-by: Rafał Miłecki ---- - drivers/mtd/mtdcore.c | 23 +++++++++++++++++++++++ - 1 file changed, 23 insertions(+) - -diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c -index 724f917f91ba..0aa3f8e44fa1 100644 ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -549,6 +549,29 @@ static int mtd_nvmem_add(struct mtd_info *mtd) - struct device_node *node = mtd_get_of_node(mtd); - struct nvmem_config config = {}; - -+ /* -+ * Do NOT register NVMEM device for any partition that is meant to be -+ * handled by a U-Boot env driver. That would result in associating two -+ * different NVMEM devices with the same OF node. -+ * -+ * An example of unwanted behaviour of above (forwardtrace): -+ * of_get_mac_addr_nvmem() -+ * of_nvmem_cell_get() -+ * __nvmem_device_get() -+ * -+ * We can't have __nvmem_device_get() return "mtdX" NVMEM device instead -+ * of U-Boot env NVMEM device. That would result in failing to find -+ * NVMEM cell. -+ * -+ * This issue seems to affect U-Boot env case only and will go away with -+ * switch to NVMEM layouts. -+ */ -+ if (of_device_is_compatible(node, "u-boot,env") || -+ of_device_is_compatible(node, "u-boot,env-redundant-bool") || -+ of_device_is_compatible(node, "u-boot,env-redundant-count") || -+ of_device_is_compatible(node, "brcm,env")) -+ return 0; -+ - config.id = NVMEM_DEVID_NONE; - config.dev = &mtd->dev; - config.name = dev_name(&mtd->dev); --- -2.51.0 - - -From afeb87fd61a00460b0302e447b98e086f03485a7 Mon Sep 17 00:00:00 2001 -From: John Thomson -Date: Fri, 25 Dec 2020 18:50:08 +1000 -Subject: [PATCH 207/517] mtd: spi-nor: write support for minor aligned - partitions -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Do not prevent writing to mtd partitions where a partition boundary sits -on a minor erasesize boundary. -This addresses a FIXME that has been present since the start of the -linux git history: -/* Doesn't start on a boundary of major erase size */ -/* FIXME: Let it be writable if it is on a boundary of - * _minor_ erase size though */ - -Allow a uniform erase region spi-nor device to be configured -to use the non-uniform erase regions code path for an erase with: -CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y - -On supporting hardware (SECT_4K: majority of current SPI-NOR device) -provide the facility for an erase to use the least number -of SPI-NOR operations, as well as access to 4K erase without -requiring CONFIG_MTD_SPI_NOR_USE_4K_SECTORS - -Introduce erasesize_minor to the mtd struct, -the smallest erasesize supported by the device - -On existing devices, this is useful where write support is wanted -for data on a 4K partition, such as some u-boot-env partitions, -or RouterBoot soft_config, while still netting the performance -benefits of using 64K sectors - -Performance: -time mtd erase firmware -OpenWrt 5.10 ramips MT7621 w25q128jv 0xfc0000 partition length - -Without this patch -MTD_SPI_NOR_USE_4K_SECTORS=y |n -real 2m 11.66s |0m 50.86s -user 0m 0.00s |0m 0.00s -sys 1m 56.20s |0m 50.80s - -With this patch -MTD_SPI_NOR_USE_VARIABLE_ERASE=n|y |4K_SECTORS=y -real 0m 51.68s |0m 50.85s |2m 12.89s -user 0m 0.00s |0m 0.00s |0m 0.01s -sys 0m 46.94s |0m 50.38s |2m 12.46s - -Signed-off-by: John Thomson -Signed-off-by: Thibaut VARÈNE ---- - drivers/mtd/mtdcore.c | 10 ++++++++++ - drivers/mtd/mtdpart.c | 35 +++++++++++++++++++++++++---------- - drivers/mtd/spi-nor/Kconfig | 10 ++++++++++ - drivers/mtd/spi-nor/core.c | 11 +++++++++-- - include/linux/mtd/mtd.h | 2 ++ - 5 files changed, 56 insertions(+), 12 deletions(-) - -diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c -index 0aa3f8e44fa1..6b98d581ceeb 100644 ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -199,6 +199,15 @@ static ssize_t mtd_erasesize_show(struct device *dev, - } - MTD_DEVICE_ATTR_RO(erasesize); - -+static ssize_t mtd_erasesize_minor_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct mtd_info *mtd = dev_get_drvdata(dev); -+ -+ return sysfs_emit(buf, "%lu\n", (unsigned long)mtd->erasesize_minor); -+} -+MTD_DEVICE_ATTR_RO(erasesize_minor); -+ - static ssize_t mtd_writesize_show(struct device *dev, - struct device_attribute *attr, char *buf) - { -@@ -344,6 +353,7 @@ static struct attribute *mtd_attrs[] = { - &dev_attr_flags.attr, - &dev_attr_size.attr, - &dev_attr_erasesize.attr, -+ &dev_attr_erasesize_minor.attr, - &dev_attr_writesize.attr, - &dev_attr_subpagesize.attr, - &dev_attr_oobsize.attr, -diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c -index 10ae49b9702a..58eb32021874 100644 ---- a/drivers/mtd/mtdpart.c -+++ b/drivers/mtd/mtdpart.c -@@ -47,6 +47,7 @@ static struct mtd_info *allocate_partition(struct mtd_info *parent, - struct mtd_info *master = mtd_get_master(parent); - int wr_alignment = (parent->flags & MTD_NO_ERASE) ? - master->writesize : master->erasesize; -+ int wr_alignment_minor = 0; - u64 parent_size = mtd_is_partition(parent) ? - parent->part.size : parent->size; - struct mtd_info *child; -@@ -171,6 +172,7 @@ static struct mtd_info *allocate_partition(struct mtd_info *parent, - } else { - /* Single erase size */ - child->erasesize = master->erasesize; -+ child->erasesize_minor = master->erasesize_minor; - } - - /* -@@ -178,26 +180,39 @@ static struct mtd_info *allocate_partition(struct mtd_info *parent, - * exposes several regions with different erasesize. Adjust - * wr_alignment accordingly. - */ -- if (!(child->flags & MTD_NO_ERASE)) -+ if (!(child->flags & MTD_NO_ERASE)) { - wr_alignment = child->erasesize; -+ wr_alignment_minor = child->erasesize_minor; -+ } - - tmp = mtd_get_master_ofs(child, 0); - remainder = do_div(tmp, wr_alignment); - if ((child->flags & MTD_WRITEABLE) && remainder) { -- /* Doesn't start on a boundary of major erase size */ -- /* FIXME: Let it be writable if it is on a boundary of -- * _minor_ erase size though */ -- child->flags &= ~MTD_WRITEABLE; -- printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase/write block boundary -- force read-only\n", -- part->name); -+ if (wr_alignment_minor) { -+ /* rely on minor being a factor of major erasesize */ -+ tmp = remainder; -+ remainder = do_div(tmp, wr_alignment_minor); -+ } -+ if (remainder) { -+ child->flags &= ~MTD_WRITEABLE; -+ printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase/write block boundary -- force read-only\n", -+ part->name); -+ } - } - - tmp = mtd_get_master_ofs(child, 0) + child->part.size; - remainder = do_div(tmp, wr_alignment); - if ((child->flags & MTD_WRITEABLE) && remainder) { -- child->flags &= ~MTD_WRITEABLE; -- printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase/write block -- force read-only\n", -- part->name); -+ if (wr_alignment_minor) { -+ tmp = remainder; -+ remainder = do_div(tmp, wr_alignment_minor); -+ } -+ -+ if (remainder) { -+ child->flags &= ~MTD_WRITEABLE; -+ printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase/write block -- force read-only\n", -+ part->name); -+ } - } - - child->size = child->part.size; -diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig -index 24cd25de2b8b..09df9f1a8127 100644 ---- a/drivers/mtd/spi-nor/Kconfig -+++ b/drivers/mtd/spi-nor/Kconfig -@@ -10,6 +10,16 @@ menuconfig MTD_SPI_NOR - - if MTD_SPI_NOR - -+config MTD_SPI_NOR_USE_VARIABLE_ERASE -+ bool "Disable uniform_erase to allow use of all hardware supported erasesizes" -+ depends on !MTD_SPI_NOR_USE_4K_SECTORS -+ default n -+ help -+ Allow mixed use of all hardware supported erasesizes, -+ by forcing spi_nor to use the multiple eraseregions code path. -+ For example: A 68K erase will use one 64K erase, and one 4K erase -+ on supporting hardware. -+ - config MTD_SPI_NOR_USE_4K_SECTORS - bool "Use small 4096 B erase sectors" - default y -diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c -index 9d6e85bf227b..8da860d84e6d 100644 ---- a/drivers/mtd/spi-nor/core.c -+++ b/drivers/mtd/spi-nor/core.c -@@ -1158,6 +1158,8 @@ static u8 spi_nor_convert_3to4_erase(u8 opcode) - - static bool spi_nor_has_uniform_erase(const struct spi_nor *nor) - { -+ if (IS_ENABLED(CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE)) -+ return false; - return !!nor->params->erase_map.uniform_region.erase_mask; - } - -@@ -2516,6 +2518,7 @@ static int spi_nor_select_erase(struct spi_nor *nor) - { - struct spi_nor_erase_map *map = &nor->params->erase_map; - const struct spi_nor_erase_type *erase = NULL; -+ const struct spi_nor_erase_type *erase_minor = NULL; - struct mtd_info *mtd = &nor->mtd; - int i; - -@@ -2542,8 +2545,9 @@ static int spi_nor_select_erase(struct spi_nor *nor) - */ - for (i = SNOR_ERASE_TYPE_MAX - 1; i >= 0; i--) { - if (map->erase_type[i].size) { -- erase = &map->erase_type[i]; -- break; -+ if (!erase) -+ erase = &map->erase_type[i]; -+ erase_minor = &map->erase_type[i]; - } - } - -@@ -2551,6 +2555,9 @@ static int spi_nor_select_erase(struct spi_nor *nor) - return -EINVAL; - - mtd->erasesize = erase->size; -+ if (IS_ENABLED(CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE) && -+ erase_minor && erase_minor->size < erase->size) -+ mtd->erasesize_minor = erase_minor->size; - return 0; - } - -diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h -index ed22b5e4cfc6..86f7efa43faa 100644 ---- a/include/linux/mtd/mtd.h -+++ b/include/linux/mtd/mtd.h -@@ -245,6 +245,8 @@ struct mtd_info { - * information below if they desire - */ - uint32_t erasesize; -+ /* "Minor" (smallest) erase size supported by the whole device */ -+ uint32_t erasesize_minor; - /* Minimal writable flash unit size. In case of NOR flash it is 1 (even - * though individual bits can be cleared), in case of NAND flash it is - * one NAND page (or half, or one-fourths of it), in case of ECC-ed NOR --- -2.51.0 - - -From c1e81cf689836ae1cc7a75f0d3b749cf98818a0e Mon Sep 17 00:00:00 2001 -From: Mikhail Kshevetskiy -Date: Sun, 3 Aug 2025 17:23:27 +0300 -Subject: [PATCH 208/517] mtd: spinand: fix direct mapping creation sizes - -Continuous mode is only supported for data reads, thus writing -requires only single flash page mapping. - -Signed-off-by: Mikhail Kshevetskiy ---- - drivers/mtd/nand/spi/core.c | 14 +++++++------- - 1 file changed, 7 insertions(+), 7 deletions(-) - -diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c -index 8e4c825b9789..abae584de706 100644 ---- a/drivers/mtd/nand/spi/core.c -+++ b/drivers/mtd/nand/spi/core.c -@@ -1028,18 +1028,13 @@ static int spinand_create_dirmap(struct spinand_device *spinand, - unsigned int plane) - { - struct nand_device *nand = spinand_to_nand(spinand); -- struct spi_mem_dirmap_info info = { -- .length = nanddev_page_size(nand) + -- nanddev_per_page_oobsize(nand), -- }; -+ struct spi_mem_dirmap_info info = { 0 }; - struct spi_mem_dirmap_desc *desc; - -- if (spinand->cont_read_possible) -- info.length = nanddev_eraseblock_size(nand); -- - /* The plane number is passed in MSB just above the column address */ - info.offset = plane << fls(nand->memorg.pagesize); - -+ info.length = nanddev_page_size(nand) + nanddev_per_page_oobsize(nand); - info.op_tmpl = *spinand->op_templates.update_cache; - desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev, - spinand->spimem, &info); -@@ -1048,6 +1043,8 @@ static int spinand_create_dirmap(struct spinand_device *spinand, - - spinand->dirmaps[plane].wdesc = desc; - -+ if (spinand->cont_read_possible) -+ info.length = nanddev_eraseblock_size(nand); - info.op_tmpl = *spinand->op_templates.read_cache; - desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev, - spinand->spimem, &info); -@@ -1063,6 +1060,7 @@ static int spinand_create_dirmap(struct spinand_device *spinand, - return 0; - } - -+ info.length = nanddev_page_size(nand) + nanddev_per_page_oobsize(nand); - info.op_tmpl = *spinand->op_templates.update_cache; - info.op_tmpl.data.ecc = true; - desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev, -@@ -1072,6 +1070,8 @@ static int spinand_create_dirmap(struct spinand_device *spinand, - - spinand->dirmaps[plane].wdesc_ecc = desc; - -+ if (spinand->cont_read_possible) -+ info.length = nanddev_eraseblock_size(nand); - info.op_tmpl = *spinand->op_templates.read_cache; - info.op_tmpl.data.ecc = true; - desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev, --- -2.51.0 - - -From f2aa382fe9e8fd76760cbd59e6463011f116ca30 Mon Sep 17 00:00:00 2001 -From: Mikhail Kshevetskiy -Date: Sun, 3 Aug 2025 19:06:40 +0300 -Subject: [PATCH 209/517] mtd: spinand: try a regular dirmap if creating a - dirmap for continuous reading fails - -Continuous reading may result in multiple flash pages reading in one -operation. Typically only one flash page has read/written (a little bit -more than 2-4 Kb), but continuous reading requires the spi controller -to read up to 512 Kb in one operation without toggling CS in beetween. - -Roughly speaking spi controllers can be divided on 2 categories: - * spi controllers without dirmap acceleration support - * spi controllers with dirmap acceleration support - -Firt of them will have issues with continuous reading if restriction on -the transfer length is implemented in the adjust_op_size() handler. -Second group often supports acceleration of single page only reading. -Thus enabling of continuous reading can break flash reading. - -This patch tries to create dirmap for continuous reading first and -fallback to regular reading if spi controller refuses to create it. - -Signed-off-by: Mikhail Kshevetskiy ---- - drivers/mtd/nand/spi/core.c | 43 ++++++++++++++++++++++++++++++------- - 1 file changed, 35 insertions(+), 8 deletions(-) - -diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c -index abae584de706..cb96b9cd2a73 100644 ---- a/drivers/mtd/nand/spi/core.c -+++ b/drivers/mtd/nand/spi/core.c -@@ -1024,6 +1024,39 @@ static int spinand_mtd_block_isreserved(struct mtd_info *mtd, loff_t offs) - return ret; - } - -+static struct spi_mem_dirmap_desc *spinand_create_rdesc( -+ struct spinand_device *spinand, -+ struct spi_mem_dirmap_info *info) -+{ -+ struct nand_device *nand = spinand_to_nand(spinand); -+ struct spi_mem_dirmap_desc *desc = NULL; -+ -+ if (spinand->cont_read_possible) { -+ /* -+ * spi controller may return an error if info->length is -+ * too large -+ */ -+ info->length = nanddev_eraseblock_size(nand); -+ desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev, -+ spinand->spimem, info); -+ } -+ -+ if (IS_ERR_OR_NULL(desc)) { -+ /* -+ * continuous reading is not supported by flash or -+ * its spi controller, use regular reading -+ */ -+ spinand->cont_read_possible = false; -+ -+ info->length = nanddev_page_size(nand) + -+ nanddev_per_page_oobsize(nand); -+ desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev, -+ spinand->spimem, info); -+ } -+ -+ return desc; -+} -+ - static int spinand_create_dirmap(struct spinand_device *spinand, - unsigned int plane) - { -@@ -1043,11 +1076,8 @@ static int spinand_create_dirmap(struct spinand_device *spinand, - - spinand->dirmaps[plane].wdesc = desc; - -- if (spinand->cont_read_possible) -- info.length = nanddev_eraseblock_size(nand); - info.op_tmpl = *spinand->op_templates.read_cache; -- desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev, -- spinand->spimem, &info); -+ desc = spinand_create_rdesc(spinand, &info); - if (IS_ERR(desc)) - return PTR_ERR(desc); - -@@ -1070,12 +1100,9 @@ static int spinand_create_dirmap(struct spinand_device *spinand, - - spinand->dirmaps[plane].wdesc_ecc = desc; - -- if (spinand->cont_read_possible) -- info.length = nanddev_eraseblock_size(nand); - info.op_tmpl = *spinand->op_templates.read_cache; - info.op_tmpl.data.ecc = true; -- desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev, -- spinand->spimem, &info); -+ desc = spinand_create_rdesc(spinand, &info); - if (IS_ERR(desc)) - return PTR_ERR(desc); - --- -2.51.0 - - -From e713688e842578fcfa97303206ae0b1f7c3da4bc Mon Sep 17 00:00:00 2001 -From: Mikhail Kshevetskiy -Date: Sun, 3 Aug 2025 17:54:17 +0300 -Subject: [PATCH 210/517] mtd: spinand: repeat reading in regular mode if - continuous reading fails - -Continuous reading may result in multiple flash pages reading in one -operation. Unfortunately, not all spinand controllers support such -large reading. They will read less data. Unfortunately, the operation -can't be continued. - -In this case: - * disable continuous reading on this (not good enough) spi controller - * repeat reading in regular mode. - -Signed-off-by: Mikhail Kshevetskiy ---- - drivers/mtd/nand/spi/core.c | 25 +++++++++++++++++++++---- - 1 file changed, 21 insertions(+), 4 deletions(-) - -diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c -index cb96b9cd2a73..f3787a63a355 100644 ---- a/drivers/mtd/nand/spi/core.c -+++ b/drivers/mtd/nand/spi/core.c -@@ -427,8 +427,16 @@ static int spinand_read_from_cache_op(struct spinand_device *spinand, - * Dirmap accesses are allowed to toggle the CS. - * Toggling the CS during a continuous read is forbidden. - */ -- if (nbytes && req->continuous) -- return -EIO; -+ if (nbytes && req->continuous) { -+ /* -+ * Spi controller with broken support of continuous -+ * reading was detected. Disable future use of -+ * continuous reading and return -EAGAIN to retry -+ * reading within regular mode. -+ */ -+ spinand->cont_read_possible = false; -+ return -EAGAIN; -+ } - } - - if (req->datalen) -@@ -841,10 +849,19 @@ static int spinand_mtd_read(struct mtd_info *mtd, loff_t from, - - old_stats = mtd->ecc_stats; - -- if (spinand_use_cont_read(mtd, from, ops)) -+ if (spinand_use_cont_read(mtd, from, ops)) { - ret = spinand_mtd_continuous_page_read(mtd, from, ops, &max_bitflips); -- else -+ if (ret == -EAGAIN && !spinand->cont_read_possible) { -+ /* -+ * Spi controller with broken support of continuous -+ * reading was detected (see spinand_read_from_cache_op()), -+ * repeat reading in regular mode. -+ */ -+ ret = spinand_mtd_regular_page_read(mtd, from, ops, &max_bitflips); -+ } -+ } else { - ret = spinand_mtd_regular_page_read(mtd, from, ops, &max_bitflips); -+ } - - if (ops->stats) { - ops->stats->uncorrectable_errors += --- -2.51.0 - - -From 59fce38e6f0e95196bc9523cf5447c5aa1f597bc Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Thu, 1 May 2025 18:19:16 +0200 -Subject: [PATCH 211/517] spi: spi-qpic-snand: validate user/chip specific ECC - properties - -The driver only supports 512 bytes ECC step size and 4 bit ECC strength -at the moment, however it does not reject unsupported step/strength -configurations. Due to this, whenever the driver is used with a flash -chip which needs stronger ECC protection, the following warning is shown -in the kernel log: - - [ 0.574648] spi-nand spi0.0: GigaDevice SPI NAND was found. - [ 0.635748] spi-nand spi0.0: 256 MiB, block size: 128 KiB, page size: 2048, OOB size: 128 - [ 0.649079] nand: WARNING: (null): the ECC used on your system is too weak compared to the one required by the NAND chip - -Although the message indicates that something is wrong, but it often gets -unnoticed, which can cause serious problems. For example when the user -writes something into the flash chip despite the warning, the written data -may won't be readable by the bootloader or by the boot ROM. In the worst -case, when the attached SPI NAND chip is the boot device, the board may not -be able to boot anymore. - -Also, it is not even possible to create a backup of the flash, because -reading its content results in bogus data. For example, dumping the first -page of the flash gives this: - - # hexdump -C -n 2048 /dev/mtd0 - 00000000 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f |................| - * - 00000040 0f 0f 0f 0f 0f 0f 0f 0d 0f 0f 0f 0f 0f 0f 0f 0f |................| - 00000050 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f |................| - * - 000001c0 0f 0f 0f 0f ff 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f |................| - 000001d0 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f |................| - * - 00000200 0f 0f 0f 0f f5 5b ff ff 0f 0f 0f 0f 0f 0f 0f 0f |.....[..........| - 00000210 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f |................| - * - 000002f0 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 1f 0f 0f |................| - 00000300 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f |................| - * - 000003c0 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f ff 0f 0f 0f |................| - 000003d0 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f |................| - * - 00000400 0f 0f 0f 0f 0f 0f 0f 0f e9 74 c9 06 f5 5b ff ff |.........t...[..| - 00000410 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f |................| - * - 000005d0 0f 0f 0f 0f ff 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f |................| - 000005e0 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f |................| - * - 00000600 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f c6 be 0f c3 |................| - 00000610 e9 74 c9 06 f5 5b ff ff 0f 0f 0f 0f 0f 0f 0f 0f |.t...[..........| - 00000620 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f |................| - * - 00000770 0f 0f 0f 0f 8f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f |................| - 00000780 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f |................| - * - 00000800 - # - -Doing the same by using the downstream kernel results in different output: - - # hexdump -C -n 2048 /dev/mtd0 - 00000000 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f |................| - * - 00000800 - # - -This patch adds some sanity checks to the code to prevent using the driver -with unsupported ECC step/strength configurations. After the change, probing -of the driver fails in such cases: - - [ 0.655038] spi-nand spi0.0: GigaDevice SPI NAND was found. - [ 0.659159] spi-nand spi0.0: 256 MiB, block size: 128 KiB, page size: 2048, OOB size: 128 - [ 0.669138] qcom_snand 79b0000.spi: only 4 bits ECC strength is supported - [ 0.677476] nand: No suitable ECC configuration - [ 0.689909] spi-nand spi0.0: probe with driver spi-nand failed with error -95 - -This helps to avoid the aforementioned hassles until support for 8 bit ECC -strength gets implemented. - -Fixes: 7304d1909080 ("spi: spi-qpic: add driver for QCOM SPI NAND flash Interface") -Signed-off-by: Gabor Juhos ---- - drivers/spi/spi-qpic-snand.c | 42 +++++++++++++++++++++++++++++++----- - 1 file changed, 37 insertions(+), 5 deletions(-) - -diff --git a/drivers/spi/spi-qpic-snand.c b/drivers/spi/spi-qpic-snand.c -index 98d32d269d55..3fa50db3b824 100644 ---- a/drivers/spi/spi-qpic-snand.c -+++ b/drivers/spi/spi-qpic-snand.c -@@ -249,9 +249,11 @@ static const struct mtd_ooblayout_ops qcom_spi_ooblayout = { - static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand) - { - struct qcom_nand_controller *snandc = nand_to_qcom_snand(nand); -+ struct nand_ecc_props *reqs = &nand->ecc.requirements; -+ struct nand_ecc_props *user = &nand->ecc.user_conf; - struct nand_ecc_props *conf = &nand->ecc.ctx.conf; - struct mtd_info *mtd = nanddev_to_mtd(nand); -- int cwperpage, bad_block_byte; -+ int cwperpage, bad_block_byte, ret; - struct qpic_ecc *ecc_cfg; - - cwperpage = mtd->writesize / NANDC_STEP_SIZE; -@@ -260,11 +262,39 @@ static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand) - ecc_cfg = kzalloc(sizeof(*ecc_cfg), GFP_KERNEL); - if (!ecc_cfg) - return -ENOMEM; -+ -+ if (user->step_size && user->strength) { -+ ecc_cfg->step_size = user->step_size; -+ ecc_cfg->strength = user->strength; -+ } else if (reqs->step_size && reqs->strength) { -+ ecc_cfg->step_size = reqs->step_size; -+ ecc_cfg->strength = reqs->strength; -+ } else { -+ /* use defaults */ -+ ecc_cfg->step_size = NANDC_STEP_SIZE; -+ ecc_cfg->strength = 4; -+ } -+ -+ if (ecc_cfg->step_size != NANDC_STEP_SIZE) { -+ dev_err(snandc->dev, -+ "only %u bytes ECC step size is supported\n", -+ NANDC_STEP_SIZE); -+ ret = -EOPNOTSUPP; -+ goto err_free_ecc_cfg; -+ } -+ -+ if (ecc_cfg->strength != 4) { -+ dev_err(snandc->dev, -+ "only 4 bits ECC strength is supported\n"); -+ ret = -EOPNOTSUPP; -+ goto err_free_ecc_cfg; -+ } -+ - snandc->qspi->oob_buf = kmalloc(mtd->writesize + mtd->oobsize, - GFP_KERNEL); - if (!snandc->qspi->oob_buf) { -- kfree(ecc_cfg); -- return -ENOMEM; -+ ret = -ENOMEM; -+ goto err_free_ecc_cfg; - } - - memset(snandc->qspi->oob_buf, 0xff, mtd->writesize + mtd->oobsize); -@@ -279,8 +309,6 @@ static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand) - ecc_cfg->bytes = ecc_cfg->ecc_bytes_hw + ecc_cfg->spare_bytes + ecc_cfg->bbm_size; - - ecc_cfg->steps = 4; -- ecc_cfg->strength = 4; -- ecc_cfg->step_size = 512; - ecc_cfg->cw_data = 516; - ecc_cfg->cw_size = ecc_cfg->cw_data + ecc_cfg->bytes; - bad_block_byte = mtd->writesize - ecc_cfg->cw_size * (cwperpage - 1) + 1; -@@ -338,6 +366,10 @@ static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand) - ecc_cfg->strength, ecc_cfg->step_size); - - return 0; -+ -+err_free_ecc_cfg: -+ kfree(ecc_cfg); -+ return ret; - } - - static void qcom_spi_ecc_cleanup_ctx_pipelined(struct nand_device *nand) --- -2.51.0 - - -From de42aad3a7d57d9e1d896b8e613a62c35cdf4201 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Fri, 2 May 2025 21:31:16 +0200 -Subject: [PATCH 212/517] mtd: nand: qpic-common: add defines for ECC_MODE - values - -Add defines for the values of the ECC_MODE field of the NAND_DEV0_ECC_CFG -register and change both the 'qcom-nandc' and 'spi-qpic-snand' drivers to -use those instead of magic numbers. - -No functional changes. This is in preparation for adding 8 bit ECC strength -support for the 'spi-qpic-snand' driver. - -Signed-off-by: Gabor Juhos ---- - drivers/mtd/nand/raw/qcom_nandc.c | 6 +++--- - drivers/spi/spi-qpic-snand.c | 2 +- - include/linux/mtd/nand-qpic-common.h | 2 ++ - 3 files changed, 6 insertions(+), 4 deletions(-) - -diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c -index c3b26fee55a8..efceee833abc 100644 ---- a/drivers/mtd/nand/raw/qcom_nandc.c -+++ b/drivers/mtd/nand/raw/qcom_nandc.c -@@ -1379,7 +1379,7 @@ static int qcom_nand_attach_chip(struct nand_chip *chip) - struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); - int cwperpage, bad_block_byte, ret; - bool wide_bus; -- int ecc_mode = 1; -+ int ecc_mode = ECC_MODE_8BIT; - - /* controller only supports 512 bytes data steps */ - ecc->size = NANDC_STEP_SIZE; -@@ -1400,7 +1400,7 @@ static int qcom_nand_attach_chip(struct nand_chip *chip) - if (ecc->strength >= 8) { - /* 8 bit ECC defaults to BCH ECC on all platforms */ - host->bch_enabled = true; -- ecc_mode = 1; -+ ecc_mode = ECC_MODE_8BIT; - - if (wide_bus) { - host->ecc_bytes_hw = 14; -@@ -1420,7 +1420,7 @@ static int qcom_nand_attach_chip(struct nand_chip *chip) - if (nandc->props->ecc_modes & ECC_BCH_4BIT) { - /* BCH */ - host->bch_enabled = true; -- ecc_mode = 0; -+ ecc_mode = ECC_MODE_4BIT; - - if (wide_bus) { - host->ecc_bytes_hw = 8; -diff --git a/drivers/spi/spi-qpic-snand.c b/drivers/spi/spi-qpic-snand.c -index 3fa50db3b824..d1b32453d33b 100644 ---- a/drivers/spi/spi-qpic-snand.c -+++ b/drivers/spi/spi-qpic-snand.c -@@ -349,7 +349,7 @@ static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand) - FIELD_PREP(ECC_SW_RESET, 0) | - FIELD_PREP(ECC_NUM_DATA_BYTES_MASK, ecc_cfg->cw_data) | - FIELD_PREP(ECC_FORCE_CLK_OPEN, 1) | -- FIELD_PREP(ECC_MODE_MASK, 0) | -+ FIELD_PREP(ECC_MODE_MASK, ECC_MODE_4BIT) | - FIELD_PREP(ECC_PARITY_SIZE_BYTES_BCH_MASK, ecc_cfg->ecc_bytes_hw); - - ecc_cfg->ecc_buf_cfg = 0x203 << NUM_STEPS; -diff --git a/include/linux/mtd/nand-qpic-common.h b/include/linux/mtd/nand-qpic-common.h -index 7760154de581..00c718a22a6f 100644 ---- a/include/linux/mtd/nand-qpic-common.h -+++ b/include/linux/mtd/nand-qpic-common.h -@@ -101,6 +101,8 @@ - #define ECC_SW_RESET BIT(1) - #define ECC_MODE 4 - #define ECC_MODE_MASK GENMASK(5, 4) -+#define ECC_MODE_4BIT 0 -+#define ECC_MODE_8BIT 1 - #define ECC_PARITY_SIZE_BYTES_BCH 8 - #define ECC_PARITY_SIZE_BYTES_BCH_MASK GENMASK(12, 8) - #define ECC_NUM_DATA_BYTES 16 --- -2.51.0 - - -From 52969428d8075f5f312e7e6ac566fc4fa7b3bd6c Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Fri, 2 May 2025 21:31:17 +0200 -Subject: [PATCH 213/517] spi: spi-qpic-snand: add support for 8 bits ECC - strength - -Even though the hardware supports 8 bits ECC strength, but that is not -handled in the driver yet. This change adds the missing bits in order -to allow using the driver with chips which require 8 bits ECC strength. - -No functional changes intended with regard to the existing 4 bits ECC -strength support. - -Tested on an IPQ9574 platform using a GigaDevice GD5F2GM7REYIG chip. - -Signed-off-by: Gabor Juhos ---- - drivers/spi/spi-qpic-snand.c | 21 ++++++++++++++++----- - 1 file changed, 16 insertions(+), 5 deletions(-) - -diff --git a/drivers/spi/spi-qpic-snand.c b/drivers/spi/spi-qpic-snand.c -index d1b32453d33b..79e815062db7 100644 ---- a/drivers/spi/spi-qpic-snand.c -+++ b/drivers/spi/spi-qpic-snand.c -@@ -283,9 +283,22 @@ static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand) - goto err_free_ecc_cfg; - } - -- if (ecc_cfg->strength != 4) { -+ switch (ecc_cfg->strength) { -+ case 4: -+ ecc_cfg->ecc_mode = ECC_MODE_4BIT; -+ ecc_cfg->ecc_bytes_hw = 7; -+ ecc_cfg->spare_bytes = 4; -+ break; -+ -+ case 8: -+ ecc_cfg->ecc_mode = ECC_MODE_8BIT; -+ ecc_cfg->ecc_bytes_hw = 13; -+ ecc_cfg->spare_bytes = 2; -+ break; -+ -+ default: - dev_err(snandc->dev, -- "only 4 bits ECC strength is supported\n"); -+ "only 4 or 8 bits ECC strength is supported\n"); - ret = -EOPNOTSUPP; - goto err_free_ecc_cfg; - } -@@ -302,8 +315,6 @@ static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand) - nand->ecc.ctx.priv = ecc_cfg; - snandc->qspi->mtd = mtd; - -- ecc_cfg->ecc_bytes_hw = 7; -- ecc_cfg->spare_bytes = 4; - ecc_cfg->bbm_size = 1; - ecc_cfg->bch_enabled = true; - ecc_cfg->bytes = ecc_cfg->ecc_bytes_hw + ecc_cfg->spare_bytes + ecc_cfg->bbm_size; -@@ -349,7 +360,7 @@ static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand) - FIELD_PREP(ECC_SW_RESET, 0) | - FIELD_PREP(ECC_NUM_DATA_BYTES_MASK, ecc_cfg->cw_data) | - FIELD_PREP(ECC_FORCE_CLK_OPEN, 1) | -- FIELD_PREP(ECC_MODE_MASK, ECC_MODE_4BIT) | -+ FIELD_PREP(ECC_MODE_MASK, ecc_cfg->ecc_mode) | - FIELD_PREP(ECC_PARITY_SIZE_BYTES_BCH_MASK, ecc_cfg->ecc_bytes_hw); - - ecc_cfg->ecc_buf_cfg = 0x203 << NUM_STEPS; --- -2.51.0 - - -From 8475879cf5aeed333f5a449a806f4e54afa7cf9d Mon Sep 17 00:00:00 2001 -From: Chukun Pan -Date: Tue, 10 Jun 2025 23:10:16 +0800 -Subject: [PATCH 214/517] mtd: spi-nand: macronix: disable continuous read for - MX35LFxGE4AD - -In on-die ECC mode, enabling continuous read will cause ubi_io_read error. -[ 7.852000] ubi0 warning: ubi_io_read: error -5 while reading ... - -So disable it first. Tested on GL.iNet GL-MT3000 with MX35LF2GE4AD flash. - -Fixes: 11813857864f ("mtd: spi-nand: macronix: Continuous read support") -Signed-off-by: Chukun Pan ---- - drivers/mtd/nand/spi/macronix.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c -index d277c3220fdc..49ee3fd4581f 100644 ---- a/drivers/mtd/nand/spi/macronix.c -+++ b/drivers/mtd/nand/spi/macronix.c -@@ -167,8 +167,7 @@ static const struct spinand_info macronix_spinand_table[] = { - &update_cache_variants), - SPINAND_HAS_QE_BIT, - SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, -- macronix_ecc_get_status), -- SPINAND_CONT_READ(macronix_set_cont_read)), -+ macronix_ecc_get_status)), - SPINAND_INFO("MX35LF4GE4AD", - SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x37, 0x03), - NAND_MEMORG(1, 4096, 128, 64, 2048, 40, 1, 1, 1), -@@ -178,8 +177,7 @@ static const struct spinand_info macronix_spinand_table[] = { - &update_cache_variants), - SPINAND_HAS_QE_BIT, - SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, -- macronix_ecc_get_status), -- SPINAND_CONT_READ(macronix_set_cont_read)), -+ macronix_ecc_get_status)), - SPINAND_INFO("MX35LF1G24AD", - SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x14, 0x03), - NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), --- -2.51.0 - - -From df45909871c0bf05bc62ee888a5d45230be19f27 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Mon, 3 Nov 2025 15:49:41 +0100 -Subject: [PATCH 215/517] add patch for including unpartitioned space in the - rootfs partition for redboot devices (if applicable) - -[john@phrozen.org: used by ixp and others] - -lede-commit: 394918851f84e4d00fa16eb900e7700e95091f00 -Signed-off-by: Felix Fietkau ---- - drivers/mtd/parsers/redboot.c | 19 +++++++++++++------ - 1 file changed, 13 insertions(+), 6 deletions(-) - -diff --git a/drivers/mtd/parsers/redboot.c b/drivers/mtd/parsers/redboot.c -index 3b55b676ca6b..979427ffef9e 100644 ---- a/drivers/mtd/parsers/redboot.c -+++ b/drivers/mtd/parsers/redboot.c -@@ -278,14 +278,21 @@ static int parse_redboot_partitions(struct mtd_info *master, - #endif - names += strlen(names) + 1; - --#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED - if (fl->next && fl->img->flash_base + fl->img->size + master->erasesize <= fl->next->img->flash_base) { -- i++; -- parts[i].offset = parts[i - 1].size + parts[i - 1].offset; -- parts[i].size = fl->next->img->flash_base - parts[i].offset; -- parts[i].name = nullname; -- } -+ if (!strcmp(parts[i].name, "rootfs")) { -+ parts[i].size = fl->next->img->flash_base; -+ parts[i].size &= ~(master->erasesize - 1); -+ parts[i].size -= parts[i].offset; -+#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED -+ nrparts--; -+ } else { -+ i++; -+ parts[i].offset = parts[i-1].size + parts[i-1].offset; -+ parts[i].size = fl->next->img->flash_base - parts[i].offset; -+ parts[i].name = nullname; - #endif -+ } -+ } - tmp_fl = fl; - fl = fl->next; - kfree(tmp_fl); --- -2.51.0 - - -From 683715c54bf280f2544981603e8a8ea167738833 Mon Sep 17 00:00:00 2001 -From: Florian Fainelli -Date: Mon, 3 Nov 2025 15:49:41 +0100 -Subject: [PATCH 216/517] Add myloader partition table parser - -[john@phozen.org: shoud be upstreamable] - -lede-commit: d8bf22859b51faa09d22c056fe221a45d2f7a3b8 -Signed-off-by: Florian Fainelli -[adjust for kernel 5.4, add myloader.c to patch] -Signed-off-by: Adrian Schmutzler ---- - drivers/mtd/parsers/Kconfig | 16 +++ - drivers/mtd/parsers/Makefile | 1 + - drivers/mtd/parsers/myloader.c | 181 +++++++++++++++++++++++++++++++++ - 3 files changed, 198 insertions(+) - create mode 100644 drivers/mtd/parsers/myloader.c - -diff --git a/drivers/mtd/parsers/Kconfig b/drivers/mtd/parsers/Kconfig -index da03ab6efe04..879d193f83f7 100644 ---- a/drivers/mtd/parsers/Kconfig -+++ b/drivers/mtd/parsers/Kconfig -@@ -62,6 +62,22 @@ config MTD_CMDLINE_PARTS - - If unsure, say 'N'. - -+config MTD_MYLOADER_PARTS -+ tristate "MyLoader partition parsing" -+ depends on ADM5120 || ATH79 -+ help -+ MyLoader is a bootloader which allows the user to define partitions -+ in flash devices, by putting a table in the second erase block -+ on the device, similar to a partition table. This table gives the -+ offsets and lengths of the user defined partitions. -+ -+ If you need code which can detect and parse these tables, and -+ register MTD 'partitions' corresponding to each image detected, -+ enable this option. -+ -+ You will still need the parsing functions to be called by the driver -+ for your particular device. It won't happen automatically. -+ - config MTD_OF_PARTS - tristate "OpenFirmware (device tree) partitioning parser" - default y -diff --git a/drivers/mtd/parsers/Makefile b/drivers/mtd/parsers/Makefile -index 9b00c62b837a..e3d3ade33a48 100644 ---- a/drivers/mtd/parsers/Makefile -+++ b/drivers/mtd/parsers/Makefile -@@ -3,6 +3,7 @@ obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm47xxpart.o - obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o - obj-$(CONFIG_MTD_BRCM_U_BOOT) += brcm_u-boot.o - obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o -+obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o - obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o - ofpart-y += ofpart_core.o - ofpart-$(CONFIG_MTD_OF_PARTS_BCM4908) += ofpart_bcm4908.o -diff --git a/drivers/mtd/parsers/myloader.c b/drivers/mtd/parsers/myloader.c -new file mode 100644 -index 000000000000..50ed8b197ed2 ---- /dev/null -+++ b/drivers/mtd/parsers/myloader.c -@@ -0,0 +1,181 @@ -+/* -+ * Parse MyLoader-style flash partition tables and produce a Linux partition -+ * array to match. -+ * -+ * Copyright (C) 2007-2009 Gabor Juhos -+ * -+ * This file was based on drivers/mtd/redboot.c -+ * Author: Red Hat, Inc. - David Woodhouse -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define BLOCK_LEN_MIN 0x10000 -+#define PART_NAME_LEN 32 -+ -+struct part_data { -+ struct mylo_partition_table tab; -+ char names[MYLO_MAX_PARTITIONS][PART_NAME_LEN]; -+}; -+ -+static int myloader_parse_partitions(struct mtd_info *master, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct part_data *buf; -+ struct mylo_partition_table *tab; -+ struct mylo_partition *part; -+ struct mtd_partition *mtd_parts; -+ struct mtd_partition *mtd_part; -+ int num_parts; -+ int ret, i; -+ size_t retlen; -+ char *names; -+ unsigned long offset; -+ unsigned long blocklen; -+ -+ buf = vmalloc(sizeof(*buf)); -+ if (!buf) { -+ return -ENOMEM; -+ goto out; -+ } -+ tab = &buf->tab; -+ -+ blocklen = master->erasesize; -+ if (blocklen < BLOCK_LEN_MIN) -+ blocklen = BLOCK_LEN_MIN; -+ -+ offset = blocklen; -+ -+ /* Find the partition table */ -+ for (i = 0; i < 4; i++, offset += blocklen) { -+ printk(KERN_DEBUG "%s: searching for MyLoader partition table" -+ " at offset 0x%lx\n", master->name, offset); -+ -+ ret = mtd_read(master, offset, sizeof(*buf), &retlen, -+ (void *)buf); -+ if (ret) -+ goto out_free_buf; -+ -+ if (retlen != sizeof(*buf)) { -+ ret = -EIO; -+ goto out_free_buf; -+ } -+ -+ /* Check for Partition Table magic number */ -+ if (tab->magic == le32_to_cpu(MYLO_MAGIC_PARTITIONS)) -+ break; -+ -+ } -+ -+ if (tab->magic != le32_to_cpu(MYLO_MAGIC_PARTITIONS)) { -+ printk(KERN_DEBUG "%s: no MyLoader partition table found\n", -+ master->name); -+ ret = 0; -+ goto out_free_buf; -+ } -+ -+ /* The MyLoader and the Partition Table is always present */ -+ num_parts = 2; -+ -+ /* Detect number of used partitions */ -+ for (i = 0; i < MYLO_MAX_PARTITIONS; i++) { -+ part = &tab->partitions[i]; -+ -+ if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE) -+ continue; -+ -+ num_parts++; -+ } -+ -+ mtd_parts = kzalloc((num_parts * sizeof(*mtd_part) + -+ num_parts * PART_NAME_LEN), GFP_KERNEL); -+ -+ if (!mtd_parts) { -+ ret = -ENOMEM; -+ goto out_free_buf; -+ } -+ -+ mtd_part = mtd_parts; -+ names = (char *)&mtd_parts[num_parts]; -+ -+ strncpy(names, "myloader", PART_NAME_LEN); -+ mtd_part->name = names; -+ mtd_part->offset = 0; -+ mtd_part->size = offset; -+ mtd_part->mask_flags = MTD_WRITEABLE; -+ mtd_part++; -+ names += PART_NAME_LEN; -+ -+ strncpy(names, "partition_table", PART_NAME_LEN); -+ mtd_part->name = names; -+ mtd_part->offset = offset; -+ mtd_part->size = blocklen; -+ mtd_part->mask_flags = MTD_WRITEABLE; -+ mtd_part++; -+ names += PART_NAME_LEN; -+ -+ for (i = 0; i < MYLO_MAX_PARTITIONS; i++) { -+ part = &tab->partitions[i]; -+ -+ if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE) -+ continue; -+ -+ if ((buf->names[i][0]) && (buf->names[i][0] != '\xff')) -+ strncpy(names, buf->names[i], PART_NAME_LEN); -+ else -+ snprintf(names, PART_NAME_LEN, "partition%d", i); -+ -+ mtd_part->offset = le32_to_cpu(part->addr); -+ mtd_part->size = le32_to_cpu(part->size); -+ mtd_part->name = names; -+ mtd_part++; -+ names += PART_NAME_LEN; -+ } -+ -+ *pparts = mtd_parts; -+ ret = num_parts; -+ -+ out_free_buf: -+ vfree(buf); -+ out: -+ return ret; -+} -+ -+static struct mtd_part_parser myloader_mtd_parser = { -+ .owner = THIS_MODULE, -+ .parse_fn = myloader_parse_partitions, -+ .name = "MyLoader", -+}; -+ -+static int __init myloader_mtd_parser_init(void) -+{ -+ register_mtd_parser(&myloader_mtd_parser); -+ -+ return 0; -+} -+ -+static void __exit myloader_mtd_parser_exit(void) -+{ -+ deregister_mtd_parser(&myloader_mtd_parser); -+} -+ -+module_init(myloader_mtd_parser_init); -+module_exit(myloader_mtd_parser_exit); -+ -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_DESCRIPTION("Parsing code for MyLoader partition tables"); -+MODULE_LICENSE("GPL v2"); --- -2.51.0 - - -From bd16a24ae191e56a7073eceb9961fa21e017a00d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Mon, 3 Nov 2025 15:49:42 +0100 -Subject: [PATCH 217/517] mtd: bcm47xxpart: check for bad blocks when - calculating offsets -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Rafał Miłecki ---- - drivers/mtd/parsers/parser_trx.c | 35 ++++++++++++++++++++++++++++---- - 1 file changed, 31 insertions(+), 4 deletions(-) - -diff --git a/drivers/mtd/parsers/parser_trx.c b/drivers/mtd/parsers/parser_trx.c -index 4814cf218e17..a1aed25d433f 100644 ---- a/drivers/mtd/parsers/parser_trx.c -+++ b/drivers/mtd/parsers/parser_trx.c -@@ -25,6 +25,33 @@ struct trx_header { - uint32_t offset[3]; - } __packed; - -+/* -+ * Calculate real end offset (address) for a given amount of data. It checks -+ * all blocks skipping bad ones. -+ */ -+static size_t parser_trx_real_offset(struct mtd_info *mtd, size_t bytes) -+{ -+ size_t real_offset = 0; -+ -+ if (mtd_block_isbad(mtd, real_offset)) -+ pr_warn("Base offset shouldn't be at bad block"); -+ -+ while (bytes >= mtd->erasesize) { -+ bytes -= mtd->erasesize; -+ real_offset += mtd->erasesize; -+ while (mtd_block_isbad(mtd, real_offset)) { -+ real_offset += mtd->erasesize; -+ -+ if (real_offset >= mtd->size) -+ return real_offset - mtd->erasesize; -+ } -+ } -+ -+ real_offset += bytes; -+ -+ return real_offset; -+} -+ - static const char *parser_trx_data_part_name(struct mtd_info *master, - size_t offset) - { -@@ -86,21 +113,21 @@ static int parser_trx_parse(struct mtd_info *mtd, - if (trx.offset[2]) { - part = &parts[curr_part++]; - part->name = "loader"; -- part->offset = trx.offset[i]; -+ part->offset = parser_trx_real_offset(mtd, trx.offset[i]); - i++; - } - - if (trx.offset[i]) { - part = &parts[curr_part++]; - part->name = "linux"; -- part->offset = trx.offset[i]; -+ part->offset = parser_trx_real_offset(mtd, trx.offset[i]); - i++; - } - - if (trx.offset[i]) { - part = &parts[curr_part++]; -- part->name = parser_trx_data_part_name(mtd, trx.offset[i]); -- part->offset = trx.offset[i]; -+ part->offset = parser_trx_real_offset(mtd, trx.offset[i]); -+ part->name = parser_trx_data_part_name(mtd, part->offset); - i++; - } - --- -2.51.0 - - -From cf018b2b9b3a91fe6a8f81ebc86aed81c9feb202 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Mon, 3 Nov 2025 15:49:42 +0100 -Subject: [PATCH 218/517] mtd: bcm47xxpart: detect T_Meter partition -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It can be found on many Netgear devices. It consists of many 0x30 blocks -starting with 4D 54. - -Signed-off-by: Rafał Miłecki ---- - drivers/mtd/parsers/bcm47xxpart.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/drivers/mtd/parsers/bcm47xxpart.c b/drivers/mtd/parsers/bcm47xxpart.c -index 49c8e7f27f21..b4a5391afce7 100644 ---- a/drivers/mtd/parsers/bcm47xxpart.c -+++ b/drivers/mtd/parsers/bcm47xxpart.c -@@ -35,6 +35,7 @@ - #define NVRAM_HEADER 0x48534C46 /* FLSH */ - #define POT_MAGIC1 0x54544f50 /* POTT */ - #define POT_MAGIC2 0x504f /* OP */ -+#define T_METER_MAGIC 0x4D540000 /* MT */ - #define ML_MAGIC1 0x39685a42 - #define ML_MAGIC2 0x26594131 - #define TRX_MAGIC 0x30524448 -@@ -179,6 +180,15 @@ static int bcm47xxpart_parse(struct mtd_info *master, - continue; - } - -+ /* T_Meter */ -+ if ((le32_to_cpu(buf[0x000 / 4]) & 0xFFFF0000) == T_METER_MAGIC && -+ (le32_to_cpu(buf[0x030 / 4]) & 0xFFFF0000) == T_METER_MAGIC && -+ (le32_to_cpu(buf[0x060 / 4]) & 0xFFFF0000) == T_METER_MAGIC) { -+ bcm47xxpart_add_part(&parts[curr_part++], "T_Meter", offset, -+ MTD_WRITEABLE); -+ continue; -+ } -+ - /* TRX */ - if (buf[0x000 / 4] == TRX_MAGIC) { - struct trx_header *trx; --- -2.51.0 - - -From b7841b2dd346ac51024fd841247b87267a41eaf2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Thibaut=20VAR=C3=88NE?= -Date: Tue, 24 Mar 2020 11:45:07 +0100 -Subject: [PATCH 219/517] generic: routerboot partition build bits (5.4) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This patch adds routerbootpart kernel build bits - -Signed-off-by: Thibaut VARÈNE ---- - drivers/mtd/parsers/Kconfig | 9 +++++++++ - drivers/mtd/parsers/Makefile | 1 + - 2 files changed, 10 insertions(+) - -diff --git a/drivers/mtd/parsers/Kconfig b/drivers/mtd/parsers/Kconfig -index 879d193f83f7..87dde317f9dd 100644 ---- a/drivers/mtd/parsers/Kconfig -+++ b/drivers/mtd/parsers/Kconfig -@@ -231,3 +231,12 @@ config MTD_SERCOMM_PARTS - partition map. This partition table contains real partition - offsets, which may differ from device to device depending on the - number and location of bad blocks on NAND. -+ -+config MTD_ROUTERBOOT_PARTS -+ tristate "RouterBoot flash partition parser" -+ depends on MTD && OF -+ help -+ MikroTik RouterBoot is implemented as a multi segment system on the -+ flash, some of which are fixed and some of which are located at -+ variable offsets. This parser handles both cases via properly -+ formatted DTS. -diff --git a/drivers/mtd/parsers/Makefile b/drivers/mtd/parsers/Makefile -index e3d3ade33a48..e6b06b56b046 100644 ---- a/drivers/mtd/parsers/Makefile -+++ b/drivers/mtd/parsers/Makefile -@@ -16,3 +16,4 @@ obj-$(CONFIG_MTD_SERCOMM_PARTS) += scpart.o - obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o - obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o - obj-$(CONFIG_MTD_QCOMSMEM_PARTS) += qcomsmempart.o -+obj-$(CONFIG_MTD_ROUTERBOOT_PARTS) += routerbootpart.o --- -2.51.0 - - -From 539d84630ee1e7d03afccbf4d62527fa34d0e592 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 7 Oct 2024 23:36:14 +0100 -Subject: [PATCH 220/517] block: allow setting partition of_node - -Allow partition parsers to set the Device Tree node for a partition by -introducing of_put_partition() and extending struct parsed_partitions -accordingly. - -As the partition information is preallocated independently of the actual -number of partitions the additional pointer takes about 2 kiB of allocated -memory which is worth avoiding in case CONFIG_OF is not set. This is -achieved by only adding the corresponding field to the struct in case -CONFIG_OF is set using #ifdef'ery. - -Signed-off-by: Daniel Golle ---- - block/partitions/check.h | 16 +++++++++++++++- - block/partitions/core.c | 14 +++++++++++--- - 2 files changed, 26 insertions(+), 4 deletions(-) - -diff --git a/block/partitions/check.h b/block/partitions/check.h -index e5c1c61eb353..0b326086b1b6 100644 ---- a/block/partitions/check.h -+++ b/block/partitions/check.h -@@ -1,6 +1,7 @@ - /* SPDX-License-Identifier: GPL-2.0 */ - #include - #include -+#include - #include "../blk.h" - - /* -@@ -16,6 +17,9 @@ struct parsed_partitions { - int flags; - bool has_info; - struct partition_meta_info info; -+#ifdef CONFIG_OF -+ struct device_node *np; -+#endif - } *parts; - int next; - int limit; -@@ -34,18 +38,28 @@ static inline void put_dev_sector(Sector p) - } - - static inline void --put_partition(struct parsed_partitions *p, int n, sector_t from, sector_t size) -+of_put_partition(struct parsed_partitions *p, int n, sector_t from, sector_t size, -+ struct device_node *np) - { - if (n < p->limit) { - char tmp[1 + BDEVNAME_SIZE + 10 + 1]; - - p->parts[n].from = from; - p->parts[n].size = size; -+#ifdef CONFIG_OF -+ p->parts[n].np = np; -+#endif - snprintf(tmp, sizeof(tmp), " %s%d", p->name, n); - strlcat(p->pp_buf, tmp, PAGE_SIZE); - } - } - -+static inline void -+put_partition(struct parsed_partitions *p, int n, sector_t from, sector_t size) -+{ -+ of_put_partition(p, n, from, size, NULL); -+} -+ - /* detection routines go here in alphabetical order: */ - int adfspart_check_ADFS(struct parsed_partitions *state); - int adfspart_check_CUMANA(struct parsed_partitions *state); -diff --git a/block/partitions/core.c b/block/partitions/core.c -index cdad05f97647..f5b5360dd518 100644 ---- a/block/partitions/core.c -+++ b/block/partitions/core.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - #include - #include "check.h" - -@@ -290,7 +291,8 @@ static const DEVICE_ATTR(whole_disk, 0444, whole_disk_show, NULL); - */ - static struct block_device *add_partition(struct gendisk *disk, int partno, - sector_t start, sector_t len, int flags, -- struct partition_meta_info *info) -+ struct partition_meta_info *info, -+ struct device_node *np) - { - dev_t devt = MKDEV(0, 0); - struct device *ddev = disk_to_dev(disk); -@@ -339,6 +341,7 @@ static struct block_device *add_partition(struct gendisk *disk, int partno, - pdev->class = &block_class; - pdev->type = &part_type; - pdev->parent = ddev; -+ device_set_node(pdev, of_fwnode_handle(np)); - - /* in consecutive minor range? */ - if (bdev_partno(bdev) < disk->minors) { -@@ -445,7 +448,7 @@ int bdev_add_partition(struct gendisk *disk, int partno, sector_t start, - } - - part = add_partition(disk, partno, start, length, -- ADDPART_FLAG_NONE, NULL); -+ ADDPART_FLAG_NONE, NULL, NULL); - ret = PTR_ERR_OR_ZERO(part); - out: - mutex_unlock(&disk->open_mutex); -@@ -559,8 +562,13 @@ static bool blk_add_partition(struct gendisk *disk, - size = get_capacity(disk) - from; - } - -+#ifdef CONFIG_OF - part = add_partition(disk, p, from, size, state->parts[p].flags, -- &state->parts[p].info); -+ &state->parts[p].info, state->parts[p].np); -+#else -+ part = add_partition(disk, p, from, size, state->parts[p].flags, -+ &state->parts[p].info, NULL); -+#endif - if (IS_ERR(part)) { - if (PTR_ERR(part) != -ENXIO) { - printk(KERN_ERR " %s: p%d could not be added: %pe\n", --- -2.51.0 - - -From f63140ada721fe7cd8818daf12912032df2dff53 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 7 Oct 2024 23:43:32 +0100 -Subject: [PATCH 221/517] block: partitions: of: assign Device Tree node to - partition - -Assign partition of_node so other drivers are able to identify a -partition by its Device Tree node. - -Signed-off-by: Daniel Golle ---- - block/partitions/of.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/block/partitions/of.c b/block/partitions/of.c -index 4e760fdffb3f..8b82f9f39686 100644 ---- a/block/partitions/of.c -+++ b/block/partitions/of.c -@@ -48,7 +48,7 @@ static void add_of_partition(struct parsed_partitions *state, int slot, - u64 offset = of_read_number(reg, a_cells) / SECTOR_SIZE; - u64 size = of_read_number(reg + a_cells, s_cells) / SECTOR_SIZE; - -- put_partition(state, slot, offset, size); -+ of_put_partition(state, slot, offset, size, np); - - if (of_property_read_bool(np, "read-only")) - state->parts[slot].flags |= ADDPART_FLAG_READONLY; --- -2.51.0 - - -From 15a3c6b896f516d704bf3b54a4f3f2837e738481 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 7 Oct 2024 23:22:53 +0100 -Subject: [PATCH 222/517] partitions/efi: apply Linux code style - -Fix (mostly white space related) coding style issues in -block/partitions/efi.c by use of clang-format. - -Signed-off-by: Daniel Golle ---- - block/partitions/efi.c | 235 +++++++++++++++++++++-------------------- - 1 file changed, 121 insertions(+), 114 deletions(-) - -diff --git a/block/partitions/efi.c b/block/partitions/efi.c -index 7acba66eed48..4e31f6c09f70 100644 ---- a/block/partitions/efi.c -+++ b/block/partitions/efi.c -@@ -95,15 +95,13 @@ - * the partition tables happens after init too. - */ - static int force_gpt; --static int __init --force_gpt_fn(char *str) -+static int __init force_gpt_fn(char *str) - { - force_gpt = 1; - return 1; - } - __setup("gpt", force_gpt_fn); - -- - /** - * efi_crc32() - EFI version of crc32 function - * @buf: buffer to calculate crc32 of -@@ -116,8 +114,7 @@ __setup("gpt", force_gpt_fn); - * Note, the EFI Specification, v1.02, has a reference to - * Dr. Dobbs Journal, May 1994 (actually it's in May 1992). - */ --static inline u32 --efi_crc32(const void *buf, unsigned long len) -+static inline u32 efi_crc32(const void *buf, unsigned long len) - { - return (crc32(~0L, buf, len) ^ ~0L); - } -@@ -134,7 +131,8 @@ efi_crc32(const void *buf, unsigned long len) - static u64 last_lba(struct gendisk *disk) - { - return div_u64(bdev_nr_bytes(disk->part0), -- queue_logical_block_size(disk->queue)) - 1ULL; -+ queue_logical_block_size(disk->queue)) - -+ 1ULL; - } - - static inline int pmbr_part_valid(gpt_mbr_record *part) -@@ -195,7 +193,7 @@ static int is_pmbr_valid(legacy_mbr *mbr, sector_t total_sectors) - check_hybrid: - for (i = 0; i < 4; i++) - if ((mbr->partition_record[i].os_type != -- EFI_PMBR_OSTYPE_EFI_GPT) && -+ EFI_PMBR_OSTYPE_EFI_GPT) && - (mbr->partition_record[i].os_type != 0x00)) - ret = GPT_MBR_HYBRID; - -@@ -213,10 +211,11 @@ static int is_pmbr_valid(legacy_mbr *mbr, sector_t total_sectors) - */ - if (ret == GPT_MBR_PROTECTIVE) { - sz = le32_to_cpu(mbr->partition_record[part].size_in_lba); -- if (sz != (uint32_t) total_sectors - 1 && sz != 0xFFFFFFFF) -- pr_debug("GPT: mbr size in lba (%u) different than whole disk (%u).\n", -- sz, min_t(uint32_t, -- total_sectors - 1, 0xFFFFFFFF)); -+ if (sz != (uint32_t)total_sectors - 1 && sz != 0xFFFFFFFF) -+ pr_debug( -+ "GPT: mbr size in lba (%u) different than whole disk (%u).\n", -+ sz, -+ min_t(uint32_t, total_sectors - 1, 0xFFFFFFFF)); - } - done: - return ret; -@@ -232,15 +231,14 @@ static int is_pmbr_valid(legacy_mbr *mbr, sector_t total_sectors) - * Description: Reads @count bytes from @state->disk into @buffer. - * Returns number of bytes read on success, 0 on error. - */ --static size_t read_lba(struct parsed_partitions *state, -- u64 lba, u8 *buffer, size_t count) -+static size_t read_lba(struct parsed_partitions *state, u64 lba, u8 *buffer, -+ size_t count) - { - size_t totalreadcount = 0; -- sector_t n = lba * -- (queue_logical_block_size(state->disk->queue) / 512); -+ sector_t n = lba * (queue_logical_block_size(state->disk->queue) / 512); - - if (!buffer || lba > last_lba(state->disk)) -- return 0; -+ return 0; - - while (count) { - int copied = 512; -@@ -253,7 +251,7 @@ static size_t read_lba(struct parsed_partitions *state, - memcpy(buffer, data, copied); - put_dev_sector(sect); - buffer += copied; -- totalreadcount +=copied; -+ totalreadcount += copied; - count -= copied; - } - return totalreadcount; -@@ -278,17 +276,17 @@ static gpt_entry *alloc_read_gpt_entries(struct parsed_partitions *state, - return NULL; - - count = (size_t)le32_to_cpu(gpt->num_partition_entries) * -- le32_to_cpu(gpt->sizeof_partition_entry); -+ le32_to_cpu(gpt->sizeof_partition_entry); - if (!count) - return NULL; - pte = kmalloc(count, GFP_KERNEL); - if (!pte) - return NULL; - -- if (read_lba(state, le64_to_cpu(gpt->partition_entry_lba), -- (u8 *) pte, count) < count) { -+ if (read_lba(state, le64_to_cpu(gpt->partition_entry_lba), (u8 *)pte, -+ count) < count) { - kfree(pte); -- pte=NULL; -+ pte = NULL; - return NULL; - } - return pte; -@@ -313,9 +311,9 @@ static gpt_header *alloc_read_gpt_header(struct parsed_partitions *state, - if (!gpt) - return NULL; - -- if (read_lba(state, lba, (u8 *) gpt, ssz) < ssz) { -+ if (read_lba(state, lba, (u8 *)gpt, ssz) < ssz) { - kfree(gpt); -- gpt=NULL; -+ gpt = NULL; - return NULL; - } - -@@ -354,8 +352,9 @@ static int is_gpt_valid(struct parsed_partitions *state, u64 lba, - - /* Check the GUID Partition Table header size is too big */ - if (le32_to_cpu((*gpt)->header_size) > -- queue_logical_block_size(state->disk->queue)) { -- pr_debug("GUID Partition Table Header size is too large: %u > %u\n", -+ queue_logical_block_size(state->disk->queue)) { -+ pr_debug( -+ "GUID Partition Table Header size is too large: %u > %u\n", - le32_to_cpu((*gpt)->header_size), - queue_logical_block_size(state->disk->queue)); - goto fail; -@@ -363,16 +362,17 @@ static int is_gpt_valid(struct parsed_partitions *state, u64 lba, - - /* Check the GUID Partition Table header size is too small */ - if (le32_to_cpu((*gpt)->header_size) < sizeof(gpt_header)) { -- pr_debug("GUID Partition Table Header size is too small: %u < %zu\n", -- le32_to_cpu((*gpt)->header_size), -- sizeof(gpt_header)); -+ pr_debug( -+ "GUID Partition Table Header size is too small: %u < %zu\n", -+ le32_to_cpu((*gpt)->header_size), sizeof(gpt_header)); - goto fail; - } - - /* Check the GUID Partition Table CRC */ - origcrc = le32_to_cpu((*gpt)->header_crc32); - (*gpt)->header_crc32 = 0; -- crc = efi_crc32((const unsigned char *) (*gpt), le32_to_cpu((*gpt)->header_size)); -+ crc = efi_crc32((const unsigned char *)(*gpt), -+ le32_to_cpu((*gpt)->header_size)); - - if (crc != origcrc) { - pr_debug("GUID Partition Table Header CRC is wrong: %x != %x\n", -@@ -396,20 +396,25 @@ static int is_gpt_valid(struct parsed_partitions *state, u64 lba, - lastlba = last_lba(state->disk); - if (le64_to_cpu((*gpt)->first_usable_lba) > lastlba) { - pr_debug("GPT: first_usable_lba incorrect: %lld > %lld\n", -- (unsigned long long)le64_to_cpu((*gpt)->first_usable_lba), -+ (unsigned long long)le64_to_cpu( -+ (*gpt)->first_usable_lba), - (unsigned long long)lastlba); - goto fail; - } - if (le64_to_cpu((*gpt)->last_usable_lba) > lastlba) { - pr_debug("GPT: last_usable_lba incorrect: %lld > %lld\n", -- (unsigned long long)le64_to_cpu((*gpt)->last_usable_lba), -+ (unsigned long long)le64_to_cpu( -+ (*gpt)->last_usable_lba), - (unsigned long long)lastlba); - goto fail; - } -- if (le64_to_cpu((*gpt)->last_usable_lba) < le64_to_cpu((*gpt)->first_usable_lba)) { -+ if (le64_to_cpu((*gpt)->last_usable_lba) < -+ le64_to_cpu((*gpt)->first_usable_lba)) { - pr_debug("GPT: last_usable_lba incorrect: %lld > %lld\n", -- (unsigned long long)le64_to_cpu((*gpt)->last_usable_lba), -- (unsigned long long)le64_to_cpu((*gpt)->first_usable_lba)); -+ (unsigned long long)le64_to_cpu( -+ (*gpt)->last_usable_lba), -+ (unsigned long long)le64_to_cpu( -+ (*gpt)->first_usable_lba)); - goto fail; - } - /* Check that sizeof_partition_entry has the correct value */ -@@ -420,10 +425,11 @@ static int is_gpt_valid(struct parsed_partitions *state, u64 lba, - - /* Sanity check partition table size */ - pt_size = (u64)le32_to_cpu((*gpt)->num_partition_entries) * -- le32_to_cpu((*gpt)->sizeof_partition_entry); -+ le32_to_cpu((*gpt)->sizeof_partition_entry); - if (pt_size > KMALLOC_MAX_SIZE) { -- pr_debug("GUID Partition Table is too large: %llu > %lu bytes\n", -- (unsigned long long)pt_size, KMALLOC_MAX_SIZE); -+ pr_debug( -+ "GUID Partition Table is too large: %llu > %lu bytes\n", -+ (unsigned long long)pt_size, KMALLOC_MAX_SIZE); - goto fail; - } - -@@ -431,7 +437,7 @@ static int is_gpt_valid(struct parsed_partitions *state, u64 lba, - goto fail; - - /* Check the GUID Partition Entry Array CRC */ -- crc = efi_crc32((const unsigned char *) (*ptes), pt_size); -+ crc = efi_crc32((const unsigned char *)(*ptes), pt_size); - - if (crc != le32_to_cpu((*gpt)->partition_entry_array_crc32)) { - pr_debug("GUID Partition Entry Array CRC check failed.\n"); -@@ -441,10 +447,10 @@ static int is_gpt_valid(struct parsed_partitions *state, u64 lba, - /* We're done, all's well */ - return 1; - -- fail_ptes: -+fail_ptes: - kfree(*ptes); - *ptes = NULL; -- fail: -+fail: - kfree(*gpt); - *gpt = NULL; - return 0; -@@ -457,12 +463,11 @@ static int is_gpt_valid(struct parsed_partitions *state, u64 lba, - * - * Description: returns 1 if valid, 0 on error. - */ --static inline int --is_pte_valid(const gpt_entry *pte, const u64 lastlba) -+static inline int is_pte_valid(const gpt_entry *pte, const u64 lastlba) - { - if ((!efi_guidcmp(pte->partition_type_guid, NULL_GUID)) || -- le64_to_cpu(pte->starting_lba) > lastlba || -- le64_to_cpu(pte->ending_lba) > lastlba) -+ le64_to_cpu(pte->starting_lba) > lastlba || -+ le64_to_cpu(pte->ending_lba) > lastlba) - return 0; - return 1; - } -@@ -477,8 +482,7 @@ is_pte_valid(const gpt_entry *pte, const u64 lastlba) - * and prints warnings on discrepancies. - * - */ --static void --compare_gpts(gpt_header *pgpt, gpt_header *agpt, u64 lastlba) -+static void compare_gpts(gpt_header *pgpt, gpt_header *agpt, u64 lastlba) - { - int error_found = 0; - if (!pgpt || !agpt) -@@ -486,31 +490,32 @@ compare_gpts(gpt_header *pgpt, gpt_header *agpt, u64 lastlba) - if (le64_to_cpu(pgpt->my_lba) != le64_to_cpu(agpt->alternate_lba)) { - pr_warn("GPT:Primary header LBA != Alt. header alternate_lba\n"); - pr_warn("GPT:%lld != %lld\n", -- (unsigned long long)le64_to_cpu(pgpt->my_lba), -- (unsigned long long)le64_to_cpu(agpt->alternate_lba)); -+ (unsigned long long)le64_to_cpu(pgpt->my_lba), -+ (unsigned long long)le64_to_cpu(agpt->alternate_lba)); - error_found++; - } - if (le64_to_cpu(pgpt->alternate_lba) != le64_to_cpu(agpt->my_lba)) { - pr_warn("GPT:Primary header alternate_lba != Alt. header my_lba\n"); - pr_warn("GPT:%lld != %lld\n", -- (unsigned long long)le64_to_cpu(pgpt->alternate_lba), -- (unsigned long long)le64_to_cpu(agpt->my_lba)); -+ (unsigned long long)le64_to_cpu(pgpt->alternate_lba), -+ (unsigned long long)le64_to_cpu(agpt->my_lba)); - error_found++; - } - if (le64_to_cpu(pgpt->first_usable_lba) != -- le64_to_cpu(agpt->first_usable_lba)) { -+ le64_to_cpu(agpt->first_usable_lba)) { - pr_warn("GPT:first_usable_lbas don't match.\n"); - pr_warn("GPT:%lld != %lld\n", -- (unsigned long long)le64_to_cpu(pgpt->first_usable_lba), -- (unsigned long long)le64_to_cpu(agpt->first_usable_lba)); -+ (unsigned long long)le64_to_cpu(pgpt->first_usable_lba), -+ (unsigned long long)le64_to_cpu( -+ agpt->first_usable_lba)); - error_found++; - } - if (le64_to_cpu(pgpt->last_usable_lba) != -- le64_to_cpu(agpt->last_usable_lba)) { -+ le64_to_cpu(agpt->last_usable_lba)) { - pr_warn("GPT:last_usable_lbas don't match.\n"); - pr_warn("GPT:%lld != %lld\n", -- (unsigned long long)le64_to_cpu(pgpt->last_usable_lba), -- (unsigned long long)le64_to_cpu(agpt->last_usable_lba)); -+ (unsigned long long)le64_to_cpu(pgpt->last_usable_lba), -+ (unsigned long long)le64_to_cpu(agpt->last_usable_lba)); - error_found++; - } - if (efi_guidcmp(pgpt->disk_guid, agpt->disk_guid)) { -@@ -518,27 +523,27 @@ compare_gpts(gpt_header *pgpt, gpt_header *agpt, u64 lastlba) - error_found++; - } - if (le32_to_cpu(pgpt->num_partition_entries) != -- le32_to_cpu(agpt->num_partition_entries)) { -+ le32_to_cpu(agpt->num_partition_entries)) { - pr_warn("GPT:num_partition_entries don't match: " -- "0x%x != 0x%x\n", -- le32_to_cpu(pgpt->num_partition_entries), -- le32_to_cpu(agpt->num_partition_entries)); -+ "0x%x != 0x%x\n", -+ le32_to_cpu(pgpt->num_partition_entries), -+ le32_to_cpu(agpt->num_partition_entries)); - error_found++; - } - if (le32_to_cpu(pgpt->sizeof_partition_entry) != -- le32_to_cpu(agpt->sizeof_partition_entry)) { -+ le32_to_cpu(agpt->sizeof_partition_entry)) { - pr_warn("GPT:sizeof_partition_entry values don't match: " -- "0x%x != 0x%x\n", -- le32_to_cpu(pgpt->sizeof_partition_entry), -- le32_to_cpu(agpt->sizeof_partition_entry)); -+ "0x%x != 0x%x\n", -+ le32_to_cpu(pgpt->sizeof_partition_entry), -+ le32_to_cpu(agpt->sizeof_partition_entry)); - error_found++; - } - if (le32_to_cpu(pgpt->partition_entry_array_crc32) != -- le32_to_cpu(agpt->partition_entry_array_crc32)) { -+ le32_to_cpu(agpt->partition_entry_array_crc32)) { - pr_warn("GPT:partition_entry_array_crc32 values don't match: " -- "0x%x != 0x%x\n", -- le32_to_cpu(pgpt->partition_entry_array_crc32), -- le32_to_cpu(agpt->partition_entry_array_crc32)); -+ "0x%x != 0x%x\n", -+ le32_to_cpu(pgpt->partition_entry_array_crc32), -+ le32_to_cpu(agpt->partition_entry_array_crc32)); - error_found++; - } - if (le64_to_cpu(pgpt->alternate_lba) != lastlba) { -@@ -594,7 +599,7 @@ static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt, - return 0; - - lastlba = last_lba(state->disk); -- if (!force_gpt) { -+ if (!force_gpt) { - /* This will be added to the EFI Spec. per Intel after v1.02. */ - legacymbr = kzalloc(sizeof(*legacymbr), GFP_KERNEL); - if (!legacymbr) -@@ -608,18 +613,17 @@ static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt, - goto fail; - - pr_debug("Device has a %s MBR\n", -- good_pmbr == GPT_MBR_PROTECTIVE ? -- "protective" : "hybrid"); -+ good_pmbr == GPT_MBR_PROTECTIVE ? "protective" : -+ "hybrid"); - } - -- good_pgpt = is_gpt_valid(state, GPT_PRIMARY_PARTITION_TABLE_LBA, -- &pgpt, &pptes); -- if (good_pgpt) -- good_agpt = is_gpt_valid(state, -- le64_to_cpu(pgpt->alternate_lba), -- &agpt, &aptes); -- if (!good_agpt && force_gpt) -- good_agpt = is_gpt_valid(state, lastlba, &agpt, &aptes); -+ good_pgpt = is_gpt_valid(state, GPT_PRIMARY_PARTITION_TABLE_LBA, &pgpt, -+ &pptes); -+ if (good_pgpt) -+ good_agpt = is_gpt_valid( -+ state, le64_to_cpu(pgpt->alternate_lba), &agpt, &aptes); -+ if (!good_agpt && force_gpt) -+ good_agpt = is_gpt_valid(state, lastlba, &agpt, &aptes); - - if (!good_agpt && force_gpt && fops->alternative_gpt_sector) { - sector_t agpt_sector; -@@ -627,43 +631,42 @@ static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt, - - err = fops->alternative_gpt_sector(disk, &agpt_sector); - if (!err) -- good_agpt = is_gpt_valid(state, agpt_sector, -- &agpt, &aptes); -+ good_agpt = -+ is_gpt_valid(state, agpt_sector, &agpt, &aptes); - } - -- /* The obviously unsuccessful case */ -- if (!good_pgpt && !good_agpt) -- goto fail; -+ /* The obviously unsuccessful case */ -+ if (!good_pgpt && !good_agpt) -+ goto fail; - -- compare_gpts(pgpt, agpt, lastlba); -+ compare_gpts(pgpt, agpt, lastlba); - -- /* The good cases */ -- if (good_pgpt) { -- *gpt = pgpt; -- *ptes = pptes; -- kfree(agpt); -- kfree(aptes); -+ /* The good cases */ -+ if (good_pgpt) { -+ *gpt = pgpt; -+ *ptes = pptes; -+ kfree(agpt); -+ kfree(aptes); - if (!good_agpt) -- pr_warn("Alternate GPT is invalid, using primary GPT.\n"); -- return 1; -- } -- else if (good_agpt) { -- *gpt = agpt; -- *ptes = aptes; -- kfree(pgpt); -- kfree(pptes); -+ pr_warn("Alternate GPT is invalid, using primary GPT.\n"); -+ return 1; -+ } else if (good_agpt) { -+ *gpt = agpt; -+ *ptes = aptes; -+ kfree(pgpt); -+ kfree(pptes); - pr_warn("Primary GPT is invalid, using alternate GPT.\n"); -- return 1; -- } -- -- fail: -- kfree(pgpt); -- kfree(agpt); -- kfree(pptes); -- kfree(aptes); -- *gpt = NULL; -- *ptes = NULL; -- return 0; -+ return 1; -+ } -+ -+fail: -+ kfree(pgpt); -+ kfree(agpt); -+ kfree(pptes); -+ kfree(aptes); -+ *gpt = NULL; -+ *ptes = NULL; -+ return 0; - } - - /** -@@ -725,7 +728,9 @@ int efi_partition(struct parsed_partitions *state) - - pr_debug("GUID Partition Table is valid! Yea!\n"); - -- for (i = 0; i < le32_to_cpu(gpt->num_partition_entries) && i < state->limit-1; i++) { -+ for (i = 0; i < le32_to_cpu(gpt->num_partition_entries) && -+ i < state->limit - 1; -+ i++) { - struct partition_meta_info *info; - unsigned label_max; - u64 start = le64_to_cpu(ptes[i].starting_lba); -@@ -735,10 +740,11 @@ int efi_partition(struct parsed_partitions *state) - if (!is_pte_valid(&ptes[i], last_lba(state->disk))) - continue; - -- put_partition(state, i+1, start * ssz, size * ssz); -+ put_partition(state, i + 1, start * ssz, size * ssz); - - /* If this is a RAID volume, tell md */ -- if (!efi_guidcmp(ptes[i].partition_type_guid, PARTITION_LINUX_RAID_GUID)) -+ if (!efi_guidcmp(ptes[i].partition_type_guid, -+ PARTITION_LINUX_RAID_GUID)) - state->parts[i + 1].flags = ADDPART_FLAG_RAID; - - info = &state->parts[i + 1].info; -@@ -747,7 +753,8 @@ int efi_partition(struct parsed_partitions *state) - /* Naively convert UTF16-LE to 7 bits. */ - label_max = min(ARRAY_SIZE(info->volname) - 1, - ARRAY_SIZE(ptes[i].partition_name)); -- utf16_le_to_7bit(ptes[i].partition_name, label_max, info->volname); -+ utf16_le_to_7bit(ptes[i].partition_name, label_max, -+ info->volname); - state->parts[i + 1].has_info = true; - } - kfree(ptes); --- -2.51.0 - - -From fb79f53b4383405a574e9d12a6101ea4ff10e3d2 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 8 Oct 2024 00:25:12 +0100 -Subject: [PATCH 223/517] partitions/efi: allow assigning partition Device Tree - node - -Signed-off-by: Daniel Golle ---- - block/partitions/efi.c | 34 +++++++++++++++++++++++++++++++++- - 1 file changed, 33 insertions(+), 1 deletion(-) - -diff --git a/block/partitions/efi.c b/block/partitions/efi.c -index 4e31f6c09f70..ac2c7d3c4993 100644 ---- a/block/partitions/efi.c -+++ b/block/partitions/efi.c -@@ -86,6 +86,7 @@ - #include - #include - #include -+#include - #include - #include "check.h" - #include "efi.h" -@@ -694,6 +695,34 @@ static void utf16_le_to_7bit(const __le16 *in, unsigned int size, u8 *out) - } - } - -+static struct device_node *find_partition_of_node(struct device_node *partitions_np, -+ gpt_entry *ptes) -+{ -+ char volname[64], partuuid[UUID_STRING_LEN + 1]; -+ const char *uuid, *name; -+ -+ if (!partitions_np || -+ !of_device_is_compatible(partitions_np, "gpt-partitions")) -+ return NULL; -+ -+ efi_guid_to_str(&ptes->unique_partition_guid, partuuid); -+ utf16_le_to_7bit(ptes->partition_name, ARRAY_SIZE(volname) - 1, volname); -+ -+ for_each_available_child_of_node_scoped(partitions_np, np) { -+ if (!of_property_read_string(np, "uuid", &uuid) && -+ strncmp(uuid, partuuid, ARRAY_SIZE(partuuid))) -+ continue; -+ -+ if (!of_property_read_string(np, "partname", &name) && -+ strncmp(name, volname, ARRAY_SIZE(volname))) -+ continue; -+ -+ return np; -+ } -+ -+ return NULL; -+} -+ - /** - * efi_partition - scan for GPT partitions - * @state: disk parsed partitions -@@ -719,6 +748,8 @@ int efi_partition(struct parsed_partitions *state) - gpt_entry *ptes = NULL; - u32 i; - unsigned ssz = queue_logical_block_size(state->disk->queue) / 512; -+ struct device *ddev = disk_to_dev(state->disk); -+ struct device_node *partitions_np = of_node_get(ddev->of_node); - - if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) { - kfree(gpt); -@@ -740,7 +771,8 @@ int efi_partition(struct parsed_partitions *state) - if (!is_pte_valid(&ptes[i], last_lba(state->disk))) - continue; - -- put_partition(state, i + 1, start * ssz, size * ssz); -+ of_put_partition(state, i + 1, start * ssz, size * ssz, -+ find_partition_of_node(partitions_np, &ptes[i])); - - /* If this is a RAID volume, tell md */ - if (!efi_guidcmp(ptes[i].partition_type_guid, --- -2.51.0 - - -From d4f29e2f7c6db41a6ea7112427078c805d8bd3e3 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Wed, 15 May 2024 08:19:51 +0100 -Subject: [PATCH 224/517] block: add support for notifications - -Add notifier block to notify other subsystems about the addition or -removal of block devices. - -Signed-off-by: Daniel Golle ---- - block/Kconfig | 6 +++ - block/Makefile | 1 + - block/blk-notify.c | 107 +++++++++++++++++++++++++++++++++++++++++ - include/linux/blkdev.h | 8 +++ - 4 files changed, 122 insertions(+) - create mode 100644 block/blk-notify.c - -diff --git a/block/Kconfig b/block/Kconfig -index 5b623b876d3b..67cd4f92378a 100644 ---- a/block/Kconfig -+++ b/block/Kconfig -@@ -209,6 +209,12 @@ config BLK_INLINE_ENCRYPTION_FALLBACK - by falling back to the kernel crypto API when inline - encryption hardware is not present. - -+config BLOCK_NOTIFIERS -+ bool "Enable support for notifications in block layer" -+ help -+ Enable this option to provide notifiers for other subsystems -+ upon addition or removal of block devices. -+ - source "block/partitions/Kconfig" - - config BLK_MQ_PCI -diff --git a/block/Makefile b/block/Makefile -index ddfd21c1a9ff..a131fa7d6b26 100644 ---- a/block/Makefile -+++ b/block/Makefile -@@ -38,3 +38,4 @@ obj-$(CONFIG_BLK_INLINE_ENCRYPTION) += blk-crypto.o blk-crypto-profile.o \ - blk-crypto-sysfs.o - obj-$(CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK) += blk-crypto-fallback.o - obj-$(CONFIG_BLOCK_HOLDER_DEPRECATED) += holder.o -+obj-$(CONFIG_BLOCK_NOTIFIERS) += blk-notify.o -diff --git a/block/blk-notify.c b/block/blk-notify.c -new file mode 100644 -index 000000000000..880e48a3f765 ---- /dev/null -+++ b/block/blk-notify.c -@@ -0,0 +1,107 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * Notifiers for addition and removal of block devices -+ * -+ * Copyright (c) 2024 Daniel Golle -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "blk.h" -+ -+struct blk_device_list { -+ struct device *dev; -+ struct list_head list; -+}; -+ -+static RAW_NOTIFIER_HEAD(blk_notifier_list); -+static DEFINE_MUTEX(blk_notifier_lock); -+static LIST_HEAD(blk_devices); -+ -+struct blk_notify_event { -+ struct delayed_work work; -+ struct device *dev; -+}; -+ -+void blk_register_notify(struct notifier_block *nb) -+{ -+ struct blk_device_list *existing_blkdev; -+ -+ mutex_lock(&blk_notifier_lock); -+ raw_notifier_chain_register(&blk_notifier_list, nb); -+ -+ list_for_each_entry(existing_blkdev, &blk_devices, list) -+ nb->notifier_call(nb, BLK_DEVICE_ADD, existing_blkdev->dev); -+ -+ mutex_unlock(&blk_notifier_lock); -+} -+EXPORT_SYMBOL_GPL(blk_register_notify); -+ -+void blk_unregister_notify(struct notifier_block *nb) -+{ -+ mutex_lock(&blk_notifier_lock); -+ raw_notifier_chain_unregister(&blk_notifier_list, nb); -+ mutex_unlock(&blk_notifier_lock); -+} -+EXPORT_SYMBOL_GPL(blk_unregister_notify); -+ -+static void blk_notify_work(struct work_struct *work) -+{ -+ struct blk_notify_event *ev = -+ container_of(work, struct blk_notify_event, work.work); -+ -+ raw_notifier_call_chain(&blk_notifier_list, BLK_DEVICE_ADD, ev->dev); -+ kfree(ev); -+} -+ -+static int blk_call_notifier_add(struct device *dev) -+{ -+ struct blk_device_list *new_blkdev; -+ struct blk_notify_event *ev; -+ -+ new_blkdev = kmalloc(sizeof (*new_blkdev), GFP_KERNEL); -+ if (!new_blkdev) -+ return -ENOMEM; -+ -+ ev = kmalloc(sizeof(*ev), GFP_KERNEL); -+ INIT_DEFERRABLE_WORK(&ev->work, blk_notify_work); -+ ev->dev = dev; -+ new_blkdev->dev = dev; -+ mutex_lock(&blk_notifier_lock); -+ list_add_tail(&new_blkdev->list, &blk_devices); -+ schedule_delayed_work(&ev->work, msecs_to_jiffies(500)); -+ mutex_unlock(&blk_notifier_lock); -+ -+ return 0; -+} -+ -+static void blk_call_notifier_remove(struct device *dev) -+{ -+ struct blk_device_list *old_blkdev, *tmp; -+ -+ mutex_lock(&blk_notifier_lock); -+ list_for_each_entry_safe(old_blkdev, tmp, &blk_devices, list) { -+ if (old_blkdev->dev != dev) -+ continue; -+ -+ list_del(&old_blkdev->list); -+ kfree(old_blkdev); -+ } -+ raw_notifier_call_chain(&blk_notifier_list, BLK_DEVICE_REMOVE, dev); -+ mutex_unlock(&blk_notifier_lock); -+} -+ -+static struct class_interface blk_notifications_bus_interface __refdata = { -+ .class = &block_class, -+ .add_dev = &blk_call_notifier_add, -+ .remove_dev = &blk_call_notifier_remove, -+}; -+ -+static int __init blk_notifications_init(void) -+{ -+ return class_interface_register(&blk_notifications_bus_interface); -+} -+device_initcall(blk_notifications_init); -diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h -index fa9d324b7069..822b8daec45d 100644 ---- a/include/linux/blkdev.h -+++ b/include/linux/blkdev.h -@@ -1753,4 +1753,12 @@ static inline bool bdev_can_atomic_write(struct block_device *bdev) - - #define DEFINE_IO_COMP_BATCH(name) struct io_comp_batch name = { } - -+ -+#ifdef CONFIG_BLOCK_NOTIFIERS -+#define BLK_DEVICE_ADD 1 -+#define BLK_DEVICE_REMOVE 2 -+extern void blk_register_notify(struct notifier_block *nb); -+extern void blk_unregister_notify(struct notifier_block *nb); -+#endif -+ - #endif /* _LINUX_BLKDEV_H */ --- -2.51.0 - - -From 80ab21df365232ab1db9e4734a474940f24b741e Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 21 Mar 2024 19:33:49 +0000 -Subject: [PATCH 225/517] block: add new genhd flag GENHD_FL_NVMEM - -Add new flag to destinguish block devices which may act as an NVMEM -provider. - -Signed-off-by: Daniel Golle ---- - include/linux/blkdev.h | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h -index 822b8daec45d..8213eb3670fe 100644 ---- a/include/linux/blkdev.h -+++ b/include/linux/blkdev.h -@@ -82,11 +82,13 @@ struct partition_meta_info { - * ``GENHD_FL_NO_PART``: partition support is disabled. The kernel will not - * scan for partitions from add_disk, and users can't add partitions manually. - * -+ * ``GENHD_FL_NVMEM``: the block device should be considered as NVMEM provider. - */ - enum { - GENHD_FL_REMOVABLE = 1 << 0, - GENHD_FL_HIDDEN = 1 << 1, - GENHD_FL_NO_PART = 1 << 2, -+ GENHD_FL_NVMEM = 1 << 3, - }; - - enum { --- -2.51.0 - - -From 505eb071cbc1260ffb37d27dd638d2154af1cea8 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Wed, 15 May 2024 18:18:37 +0300 -Subject: [PATCH 226/517] nvmem: implement block NVMEM provider - -On embedded devices using an eMMC it is common that one or more partitions -on the eMMC are used to store MAC addresses and Wi-Fi calibration EEPROM -data. Allow referencing any block device or partition in Device Tree to -allow e.g. Ethernet and Wi-Fi drivers accessing them via the NVMEM layer. - -Signed-off-by: Daniel Golle ---- - drivers/nvmem/Kconfig | 11 +++ - drivers/nvmem/Makefile | 2 + - drivers/nvmem/block.c | 198 +++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 211 insertions(+) - create mode 100644 drivers/nvmem/block.c - -diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig -index d2c384f58028..40b5fd1bfde4 100644 ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -40,6 +40,17 @@ config NVMEM_APPLE_EFUSES - This driver can also be built as a module. If so, the module will - be called nvmem-apple-efuses. - -+config NVMEM_BLOCK -+ tristate "Block device NVMEM provider" -+ depends on BLOCK -+ depends on OF -+ depends on NVMEM -+ select BLOCK_NOTIFIERS -+ help -+ Allow block devices (or partitions) to act as NVMEM prodivers, -+ typically used with eMMC to store MAC addresses or Wi-Fi -+ calibration data on embedded devices. -+ - config NVMEM_BCM_OCOTP - tristate "Broadcom On-Chip OTP Controller support" - depends on ARCH_BCM_IPROC || COMPILE_TEST -diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile -index cdd01fbf1313..68fcf845f417 100644 ---- a/drivers/nvmem/Makefile -+++ b/drivers/nvmem/Makefile -@@ -14,6 +14,8 @@ obj-$(CONFIG_NVMEM_APPLE_EFUSES) += nvmem-apple-efuses.o - nvmem-apple-efuses-y := apple-efuses.o - obj-$(CONFIG_NVMEM_BCM_OCOTP) += nvmem-bcm-ocotp.o - nvmem-bcm-ocotp-y := bcm-ocotp.o -+obj-$(CONFIG_NVMEM_BLOCK) += nvmem-block.o -+nvmem-block-y := block.o - obj-$(CONFIG_NVMEM_BRCM_NVRAM) += nvmem_brcm_nvram.o - nvmem_brcm_nvram-y := brcm_nvram.o - obj-$(CONFIG_NVMEM_IMX_IIM) += nvmem-imx-iim.o -diff --git a/drivers/nvmem/block.c b/drivers/nvmem/block.c -new file mode 100644 -index 000000000000..dc9e43f98616 ---- /dev/null -+++ b/drivers/nvmem/block.c -@@ -0,0 +1,198 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * block device NVMEM provider -+ * -+ * Copyright (c) 2024 Daniel Golle -+ * -+ * Useful on devices using a partition on an eMMC for MAC addresses or -+ * Wi-Fi calibration EEPROM data. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+/* List of all NVMEM devices */ -+static LIST_HEAD(nvmem_devices); -+static DEFINE_MUTEX(devices_mutex); -+ -+struct blk_nvmem { -+ struct nvmem_device *nvmem; -+ struct device *dev; -+ struct list_head list; -+}; -+ -+static int blk_nvmem_reg_read(void *priv, unsigned int from, -+ void *val, size_t bytes) -+{ -+ blk_mode_t mode = BLK_OPEN_READ | BLK_OPEN_RESTRICT_WRITES; -+ unsigned long offs = from & ~PAGE_MASK, to_read; -+ pgoff_t f_index = from >> PAGE_SHIFT; -+ struct blk_nvmem *bnv = priv; -+ size_t bytes_left = bytes; -+ struct file *bdev_file; -+ struct folio *folio; -+ void *p; -+ int ret = 0; -+ -+ bdev_file = bdev_file_open_by_dev(bnv->dev->devt, mode, priv, NULL); -+ if (!bdev_file) -+ return -ENODEV; -+ -+ if (IS_ERR(bdev_file)) -+ return PTR_ERR(bdev_file); -+ -+ while (bytes_left) { -+ folio = read_mapping_folio(bdev_file->f_mapping, f_index++, NULL); -+ if (IS_ERR(folio)) { -+ ret = PTR_ERR(folio); -+ goto err_release_bdev; -+ } -+ to_read = min_t(unsigned long, bytes_left, PAGE_SIZE - offs); -+ p = folio_address(folio) + offset_in_folio(folio, offs); -+ memcpy(val, p, to_read); -+ offs = 0; -+ bytes_left -= to_read; -+ val += to_read; -+ folio_put(folio); -+ } -+ -+err_release_bdev: -+ fput(bdev_file); -+ -+ return ret; -+} -+ -+static int blk_nvmem_register(struct device *dev) -+{ -+ struct block_device *bdev = dev_to_bdev(dev); -+ struct device_node *np = dev_of_node(dev); -+ struct nvmem_config config = {}; -+ struct blk_nvmem *bnv; -+ -+ /* skip devices which do not have a device tree node */ -+ if (!np) -+ return 0; -+ -+ /* skip devices without an nvmem layout defined */ -+ if (!of_get_child_by_name(np, "nvmem-layout")) -+ return 0; -+ -+ /* -+ * skip devices which don't have GENHD_FL_NVMEM set -+ * -+ * This flag is used for mtdblock and ubiblock devices because -+ * both, MTD and UBI already implement their own NVMEM provider. -+ * To avoid registering multiple NVMEM providers for the same -+ * device node, don't register the block NVMEM provider for them. -+ */ -+ if (!(bdev->bd_disk->flags & GENHD_FL_NVMEM)) -+ return 0; -+ -+ /* -+ * skip block device too large to be represented as NVMEM devices -+ * which are using an 'int' as address -+ */ -+ if (bdev_nr_bytes(bdev) > INT_MAX) -+ return -EFBIG; -+ -+ bnv = kzalloc(sizeof(struct blk_nvmem), GFP_KERNEL); -+ if (!bnv) -+ return -ENOMEM; -+ -+ config.id = NVMEM_DEVID_NONE; -+ config.dev = &bdev->bd_device; -+ config.name = dev_name(&bdev->bd_device); -+ config.owner = THIS_MODULE; -+ config.priv = bnv; -+ config.reg_read = blk_nvmem_reg_read; -+ config.size = bdev_nr_bytes(bdev); -+ config.word_size = 1; -+ config.stride = 1; -+ config.read_only = true; -+ config.root_only = true; -+ config.ignore_wp = true; -+ config.of_node = to_of_node(dev->fwnode); -+ -+ bnv->dev = &bdev->bd_device; -+ bnv->nvmem = nvmem_register(&config); -+ if (IS_ERR(bnv->nvmem)) { -+ dev_err_probe(&bdev->bd_device, PTR_ERR(bnv->nvmem), -+ "Failed to register NVMEM device\n"); -+ -+ kfree(bnv); -+ return PTR_ERR(bnv->nvmem); -+ } -+ -+ mutex_lock(&devices_mutex); -+ list_add_tail(&bnv->list, &nvmem_devices); -+ mutex_unlock(&devices_mutex); -+ -+ return 0; -+} -+ -+static void blk_nvmem_unregister(struct device *dev) -+{ -+ struct blk_nvmem *bnv_c, *bnv = NULL; -+ -+ mutex_lock(&devices_mutex); -+ list_for_each_entry(bnv_c, &nvmem_devices, list) { -+ if (bnv_c->dev == dev) { -+ bnv = bnv_c; -+ break; -+ } -+ } -+ -+ if (!bnv) { -+ mutex_unlock(&devices_mutex); -+ return; -+ } -+ -+ list_del(&bnv->list); -+ mutex_unlock(&devices_mutex); -+ nvmem_unregister(bnv->nvmem); -+ kfree(bnv); -+} -+ -+static int blk_nvmem_handler(struct notifier_block *this, unsigned long code, void *obj) -+{ -+ struct device *dev = (struct device *)obj; -+ -+ switch (code) { -+ case BLK_DEVICE_ADD: -+ return blk_nvmem_register(dev); -+ break; -+ case BLK_DEVICE_REMOVE: -+ blk_nvmem_unregister(dev); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static struct notifier_block blk_nvmem_notifier = { -+ .notifier_call = blk_nvmem_handler, -+}; -+ -+static int __init blk_nvmem_init(void) -+{ -+ blk_register_notify(&blk_nvmem_notifier); -+ -+ return 0; -+} -+ -+static void __exit blk_nvmem_exit(void) -+{ -+ blk_unregister_notify(&blk_nvmem_notifier); -+} -+ -+module_init(blk_nvmem_init); -+module_exit(blk_nvmem_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Daniel Golle "); -+MODULE_DESCRIPTION("block device NVMEM provider"); --- -2.51.0 - - -From a157318671df5bf489e72723f2b02b462415855f Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 20 Jul 2023 17:36:44 +0100 -Subject: [PATCH 227/517] mmc: block: set GENHD_FL_NVMEM - -Set flag to consider MMC block devices as NVMEM providers. - -Signed-off-by: Daniel Golle ---- - drivers/mmc/core/block.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c -index 28882b75ba26..f56eb44ec450 100644 ---- a/drivers/mmc/core/block.c -+++ b/drivers/mmc/core/block.c -@@ -2644,6 +2644,7 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, - md->disk->major = MMC_BLOCK_MAJOR; - md->disk->minors = perdev_minors; - md->disk->first_minor = devidx * perdev_minors; -+ md->disk->flags = GENHD_FL_NVMEM; - md->disk->fops = &mmc_bdops; - md->disk->private_data = md; - md->parent = parent; --- -2.51.0 - - -From 601eabca6855ce5433b4753cf64b7de87cfbd935 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Mon, 3 Nov 2025 15:49:45 +0100 -Subject: [PATCH 228/517] kernel: disable cfi cmdset 0002 erase suspend - -on some platforms, erase suspend leads to data corruption and lockups when write -ops collide with erase ops. this has been observed on the buffalo wzr-hp-g300nh. -rather than play whack-a-mole with a hard to reproduce issue on a variety of devices, -simply disable erase suspend, as it will usually not produce any useful gain on -the small filesystems used on embedded hardware. - -Signed-off-by: Felix Fietkau ---- - drivers/mtd/chips/cfi_cmdset_0002.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c -index 9f2223d3e8e1..cd513f719177 100644 ---- a/drivers/mtd/chips/cfi_cmdset_0002.c -+++ b/drivers/mtd/chips/cfi_cmdset_0002.c -@@ -906,7 +906,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr - return 0; - - case FL_ERASING: -- if (!cfip || !(cfip->EraseSuspend & (0x1|0x2)) || -+ if (1 /* no suspend */ || !cfip || !(cfip->EraseSuspend & (0x1|0x2)) || - !(mode == FL_READY || mode == FL_POINT || - (mode == FL_WRITING && (cfip->EraseSuspend & 0x2)))) - goto sleep; --- -2.51.0 - - -From 0aca8172b13a5bbbbd97f3d2ece4e916bbdb41d4 Mon Sep 17 00:00:00 2001 -From: George Kashperko -Date: Mon, 3 Nov 2025 15:49:45 +0100 -Subject: [PATCH 229/517] Issue map read after Write Buffer Load command to - ensure chip is ready to receive data. - -Signed-off-by: George Kashperko ---- - drivers/mtd/chips/cfi_cmdset_0002.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c -index cd513f719177..b589ddc4a3c9 100644 ---- a/drivers/mtd/chips/cfi_cmdset_0002.c -+++ b/drivers/mtd/chips/cfi_cmdset_0002.c -@@ -2050,6 +2050,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, - - /* Write Buffer Load */ - map_write(map, CMD(0x25), cmd_adr); -+ (void) map_read(map, cmd_adr); - - chip->state = FL_WRITING_TO_BUFFER; - --- -2.51.0 - - -From 1e60d2ebf7e0a305b8ba49ff8bdcad70ef15bd63 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Mon, 3 Nov 2025 15:49:45 +0100 -Subject: [PATCH 230/517] Disable software protection bits for Macronix - flashes. - -Signed-off-by: Felix Fietkau ---- - drivers/mtd/spi-nor/macronix.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/mtd/spi-nor/macronix.c b/drivers/mtd/spi-nor/macronix.c -index ea6be95e75a5..ac125b89e7ba 100644 ---- a/drivers/mtd/spi-nor/macronix.c -+++ b/drivers/mtd/spi-nor/macronix.c -@@ -194,6 +194,7 @@ static int macronix_nor_late_init(struct spi_nor *nor) - { - if (!nor->params->set_4byte_addr_mode) - nor->params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode_en4b_ex4b; -+ nor->flags |= SNOR_F_HAS_LOCK; - - return 0; - } --- -2.51.0 - - -From de1e4ccd801c181b0f1d543e91f63a1743d3a092 Mon Sep 17 00:00:00 2001 -From: Piotr Dymacz -Date: Mon, 3 Nov 2025 15:49:46 +0100 -Subject: [PATCH 231/517] kernel/mtd: add support for EON EN25Q128 - -Signed-off-by: Piotr Dymacz ---- - drivers/mtd/spi-nor/eon.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/drivers/mtd/spi-nor/eon.c b/drivers/mtd/spi-nor/eon.c -index c1ddf662f782..d43b68873cf1 100644 ---- a/drivers/mtd/spi-nor/eon.c -+++ b/drivers/mtd/spi-nor/eon.c -@@ -17,6 +17,11 @@ static const struct flash_info eon_nor_parts[] = { - .id = SNOR_ID(0x1c, 0x20, 0x17), - .name = "en25p64", - .size = SZ_8M, -+ }, { -+ .id = SNOR_ID(0x1c, 0x30, 0x18), -+ .name = "en25q128", -+ .size = SZ_16M, -+ .no_sfdp_flags = SECT_4K, - }, { - .id = SNOR_ID(0x1c, 0x30, 0x14), - .name = "en25q80a", --- -2.51.0 - - -From ebe89a767bbf9f8a9704db8a1364c28f6c8bf044 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 3 Nov 2025 15:49:46 +0100 -Subject: [PATCH 232/517] kernel/mtd: add support for EON EN25QX128A - -Add support for EON EN25QX128A with no flags as it does -support SFDP parsing. - -Signed-off-by: Christian Marangi ---- - drivers/mtd/spi-nor/eon.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/drivers/mtd/spi-nor/eon.c b/drivers/mtd/spi-nor/eon.c -index d43b68873cf1..a3b57a6871a3 100644 ---- a/drivers/mtd/spi-nor/eon.c -+++ b/drivers/mtd/spi-nor/eon.c -@@ -22,6 +22,10 @@ static const struct flash_info eon_nor_parts[] = { - .name = "en25q128", - .size = SZ_16M, - .no_sfdp_flags = SECT_4K, -+ }, { -+ .id = SNOR_ID(0x1c, 0x71, 0x18), -+ .name = "en25qx128a", -+ .size = SZ_16M, - }, { - .id = SNOR_ID(0x1c, 0x30, 0x14), - .name = "en25q80a", --- -2.51.0 - - -From 7eefc27020e72b4715c3a3e0570c8c3ea96710e3 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 6 Feb 2020 19:19:41 +0200 -Subject: [PATCH 233/517] mtd: spi-nor: Add support for xt25f128b chip - -Add XT25F128B made by XTX Technology (Shenzhen) Limited. -This chip supports dual and quad read and uniform 4K-byte erase. -Verified on Teltonika RUT955 which comes with XT25F128B in recent -versions of the device. - -Signed-off-by: Daniel Golle -Signed-off-by: Felix Fietkau ---- - drivers/mtd/spi-nor/Makefile | 1 + - drivers/mtd/spi-nor/core.c | 1 + - drivers/mtd/spi-nor/core.h | 1 + - drivers/mtd/spi-nor/xtx.c | 20 ++++++++++++++++++++ - 4 files changed, 23 insertions(+) - create mode 100644 drivers/mtd/spi-nor/xtx.c - -diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile -index 5dd9c35f6b6f..1072cf609dac 100644 ---- a/drivers/mtd/spi-nor/Makefile -+++ b/drivers/mtd/spi-nor/Makefile -@@ -14,6 +14,7 @@ spi-nor-objs += spansion.o - spi-nor-objs += sst.o - spi-nor-objs += winbond.o - spi-nor-objs += xmc.o -+spi-nor-objs += xtx.o - spi-nor-$(CONFIG_DEBUG_FS) += debugfs.o - obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o - -diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c -index 8da860d84e6d..5bb7da0ef34d 100644 ---- a/drivers/mtd/spi-nor/core.c -+++ b/drivers/mtd/spi-nor/core.c -@@ -1979,6 +1979,7 @@ static const struct spi_nor_manufacturer *manufacturers[] = { - &spi_nor_sst, - &spi_nor_winbond, - &spi_nor_xmc, -+ &spi_nor_xtx, - }; - - static const struct flash_info spi_nor_generic_flash = { -diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h -index 1516b6d0dc37..c81829b01cfd 100644 ---- a/drivers/mtd/spi-nor/core.h -+++ b/drivers/mtd/spi-nor/core.h -@@ -593,6 +593,7 @@ extern const struct spi_nor_manufacturer spi_nor_spansion; - extern const struct spi_nor_manufacturer spi_nor_sst; - extern const struct spi_nor_manufacturer spi_nor_winbond; - extern const struct spi_nor_manufacturer spi_nor_xmc; -+extern const struct spi_nor_manufacturer spi_nor_xtx; - - extern const struct attribute_group *spi_nor_sysfs_groups[]; - -diff --git a/drivers/mtd/spi-nor/xtx.c b/drivers/mtd/spi-nor/xtx.c -new file mode 100644 -index 000000000000..f16d08db483f ---- /dev/null -+++ b/drivers/mtd/spi-nor/xtx.c -@@ -0,0 +1,20 @@ -+// SPDX-License-Identifier: GPL-2.0 -+#include -+ -+#include "core.h" -+ -+static const struct flash_info xtx_parts[] = { -+ /* XTX Technology (Shenzhen) Limited */ -+ { -+ .id = SNOR_ID(0x0B, 0x40, 0x18), -+ .name = "xt25f128b", -+ .size = SZ_16M, -+ .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, -+ }, -+}; -+ -+const struct spi_nor_manufacturer spi_nor_xtx = { -+ .name = "xtx", -+ .parts = xtx_parts, -+ .nparts = ARRAY_SIZE(xtx_parts), -+}; --- -2.51.0 - - -From be18324af44ad5c426c6168eb7d8b071d76937c9 Mon Sep 17 00:00:00 2001 -From: Koen Vandeputte -Date: Mon, 6 Jan 2020 13:07:56 +0100 -Subject: [PATCH 234/517] mtd: spi-nor: add support for Gigadevice GD25D05 - -Signed-off-by: Koen Vandeputte ---- - drivers/mtd/spi-nor/gigadevice.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/drivers/mtd/spi-nor/gigadevice.c b/drivers/mtd/spi-nor/gigadevice.c -index ef1edd0add70..2cf2db123751 100644 ---- a/drivers/mtd/spi-nor/gigadevice.c -+++ b/drivers/mtd/spi-nor/gigadevice.c -@@ -35,6 +35,12 @@ static const struct spi_nor_fixups gd25q256_fixups = { - - static const struct flash_info gigadevice_nor_parts[] = { - { -+ .id = SNOR_ID(0xc8, 0x40, 0x10), -+ .name = "gd25q05", -+ .size = SZ_64K, -+ .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB, -+ .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, -+ }, { - .id = SNOR_ID(0xc8, 0x40, 0x15), - .name = "gd25q16", - .size = SZ_2M, --- -2.51.0 - - -From b044e7954a158d0fc0b2414e4e6a9f1a937bf08f Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Thu, 14 Jul 2022 08:38:07 +0200 -Subject: [PATCH 235/517] spi-nor/gigadevic: add gd25q512 - ---- - drivers/mtd/spi-nor/gigadevice.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/drivers/mtd/spi-nor/gigadevice.c b/drivers/mtd/spi-nor/gigadevice.c -index 2cf2db123751..c4bf82b41914 100644 ---- a/drivers/mtd/spi-nor/gigadevice.c -+++ b/drivers/mtd/spi-nor/gigadevice.c -@@ -70,6 +70,13 @@ static const struct flash_info gigadevice_nor_parts[] = { - .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6, - .fixups = &gd25q256_fixups, - .fixup_flags = SPI_NOR_4B_OPCODES, -+ }, { -+ .id = SNOR_ID(0xc8, 0x40, 0x20), -+ .name = "gd25q512", -+ .size = SZ_64M, -+ .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB, -+ .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, -+ .fixup_flags = SPI_NOR_4B_OPCODES, - }, { - .id = SNOR_ID(0xc8, 0x60, 0x16), - .name = "gd25lq32", --- -2.51.0 - - -From 5c449e62a92715acb21fdf74e0ec3d3b7188ff8c Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 12:17:21 +0200 -Subject: [PATCH 236/517] spi-nor/esmt.c: add esmt f25l16pa - -This fixes support for Dongwon T&I DW02-412H which uses F25L16PA(2S) -flash. ---- - drivers/mtd/spi-nor/esmt.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/drivers/mtd/spi-nor/esmt.c b/drivers/mtd/spi-nor/esmt.c -index 089fcd1aa794..3c546c5d5d9b 100644 ---- a/drivers/mtd/spi-nor/esmt.c -+++ b/drivers/mtd/spi-nor/esmt.c -@@ -10,6 +10,12 @@ - - static const struct flash_info esmt_nor_parts[] = { - { -+ .id = SNOR_ID(0x8c, 0x21, 0x15), -+ .name = "f25l16pa-2s", -+ .size = SZ_2M, -+ .flags = SPI_NOR_HAS_LOCK, -+ .no_sfdp_flags = SECT_4K, -+ }, { - .id = SNOR_ID(0x8c, 0x20, 0x16), - .name = "f25l32pa", - .size = SZ_4M, --- -2.51.0 - - -From 769f8546d57a69c758d67e0dcaf5f63b8aa163cb Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 12:19:01 +0200 -Subject: [PATCH 237/517] spi-nor/xmc.c: add xm25qh128c - -The XMC XM25QH128C is a 16MB SPI NOR chip. The patch is verified on -Ruijie RG-EW3200GX PRO. -Datasheet available at https://www.xmcwh.com/uploads/435/XM25QH128C.pdf ---- - drivers/mtd/spi-nor/xmc.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/drivers/mtd/spi-nor/xmc.c b/drivers/mtd/spi-nor/xmc.c -index d5a06054b0dd..8eb2d957c8ad 100644 ---- a/drivers/mtd/spi-nor/xmc.c -+++ b/drivers/mtd/spi-nor/xmc.c -@@ -19,6 +19,11 @@ static const struct flash_info xmc_nor_parts[] = { - .name = "XM25QH128A", - .size = SZ_16M, - .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, -+ }, { -+ .id = SNOR_ID(0x20, 0x40, 0x18), -+ .name = "XM25QH128C", -+ .size = SZ_16M, -+ .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, - }, - }; - --- -2.51.0 - - -From 5fcfdcd3d02f2707b544005c7f657ebb852d3e46 Mon Sep 17 00:00:00 2001 -From: Daniel Danzberger -Date: Wed, 3 Aug 2022 17:31:03 +0200 -Subject: [PATCH 238/517] mtd: spinand: Add support for Etron EM73D044VCx - -Airoha is a new ARM platform based on Cortex-A53 which has recently been -merged into linux-next. - -Due to BootROM limitations on this platform, the Cortex-A53 can't run in -Aarch64 mode and code must be compiled for 32-Bit ARM. - -This support is based mostly on those linux-next commits backported -for kernel 5.15. - -Patches: -1 - platform support = linux-next -2 - clock driver = linux-next -3 - gpio driver = linux-next -4 - linux,usable-memory-range dts support = linux-next -5 - mtd spinand driver -6 - spi driver -7 - pci driver (kconfig only, uses mediatek PCI) = linux-next - -Still missing: -- Ethernet driver -- Sysupgrade support - -A.t.m there exists one subtarget EN7523 with only one evaluation -board. - -The initramfs can be run with the following commands from u-boot: -- -u-boot> setenv bootfile \ - openwrt-airoha-airoha_en7523-evb-initramfs-kernel.bin -u-boot> tftpboot -u-boot> bootm 0x81800000 -- - -Submitted-by: Daniel Danzberger ---- - drivers/mtd/nand/spi/Makefile | 4 +- - drivers/mtd/nand/spi/core.c | 1 + - drivers/mtd/nand/spi/etron.c | 98 +++++++++++++++++++++++++++++++++++ - include/linux/mtd/spinand.h | 1 + - 4 files changed, 102 insertions(+), 2 deletions(-) - create mode 100644 drivers/mtd/nand/spi/etron.c - -diff --git a/drivers/mtd/nand/spi/Makefile b/drivers/mtd/nand/spi/Makefile -index 32a696055d9f..f725f0c67307 100644 ---- a/drivers/mtd/nand/spi/Makefile -+++ b/drivers/mtd/nand/spi/Makefile -@@ -1,4 +1,4 @@ - # SPDX-License-Identifier: GPL-2.0 --spinand-objs := core.o alliancememory.o ato.o esmt.o fmsh.o foresee.o gigadevice.o macronix.o --spinand-objs += micron.o paragon.o toshiba.o winbond.o xtx.o -+spinand-objs := core.o alliancememory.o ato.o esmt.o etron.o fmsh.o foresee.o gigadevice.o -+spinand-objs += macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o - obj-$(CONFIG_MTD_SPI_NAND) += spinand.o -diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c -index f3787a63a355..8e56ca65ac4f 100644 ---- a/drivers/mtd/nand/spi/core.c -+++ b/drivers/mtd/nand/spi/core.c -@@ -1159,6 +1159,7 @@ static const struct spinand_manufacturer *spinand_manufacturers[] = { - &alliancememory_spinand_manufacturer, - &ato_spinand_manufacturer, - &esmt_c8_spinand_manufacturer, -+ &etron_spinand_manufacturer, - &fmsh_spinand_manufacturer, - &foresee_spinand_manufacturer, - &gigadevice_spinand_manufacturer, -diff --git a/drivers/mtd/nand/spi/etron.c b/drivers/mtd/nand/spi/etron.c -new file mode 100644 -index 000000000000..653092be5938 ---- /dev/null -+++ b/drivers/mtd/nand/spi/etron.c -@@ -0,0 +1,98 @@ -+// SPDX-License-Identifier: GPL-2.0 -+ -+#include -+#include -+#include -+ -+#define SPINAND_MFR_ETRON 0xd5 -+ -+ -+static SPINAND_OP_VARIANTS(read_cache_variants, -+ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); -+ -+static SPINAND_OP_VARIANTS(write_cache_variants, -+ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), -+ SPINAND_PROG_LOAD(true, 0, NULL, 0)); -+ -+static SPINAND_OP_VARIANTS(update_cache_variants, -+ SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), -+ SPINAND_PROG_LOAD(false, 0, NULL, 0)); -+ -+static int etron_ooblayout_ecc(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ if (section) -+ return -ERANGE; -+ -+ oobregion->offset = 72; -+ oobregion->length = 56; -+ -+ return 0; -+} -+ -+static int etron_ooblayout_free(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ if (section) -+ return -ERANGE; -+ -+ oobregion->offset = 1; -+ oobregion->length = 71; -+ -+ return 0; -+} -+ -+static int etron_ecc_get_status(struct spinand_device *spinand, u8 status) -+{ -+ switch (status & STATUS_ECC_MASK) { -+ case STATUS_ECC_NO_BITFLIPS: -+ return 0; -+ -+ case STATUS_ECC_HAS_BITFLIPS: -+ /* Between 1-7 bitflips were corrected */ -+ return 7; -+ -+ case STATUS_ECC_MASK: -+ /* Maximum bitflips were corrected */ -+ return 8; -+ -+ case STATUS_ECC_UNCOR_ERROR: -+ return -EBADMSG; -+ } -+ -+ return -EINVAL; -+} -+ -+static const struct mtd_ooblayout_ops etron_ooblayout = { -+ .ecc = etron_ooblayout_ecc, -+ .free = etron_ooblayout_free, -+}; -+ -+static const struct spinand_info etron_spinand_table[] = { -+ SPINAND_INFO("EM73D044VCx", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x1f), -+ // bpc, pagesize, oobsize, pagesperblock, bperlun, maxbadplun, ppl, lpt, #t -+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), -+ NAND_ECCREQ(8, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, -+ &write_cache_variants, -+ &update_cache_variants), -+ SPINAND_HAS_QE_BIT, -+ SPINAND_ECCINFO(&etron_ooblayout, etron_ecc_get_status)), -+}; -+ -+static const struct spinand_manufacturer_ops etron_spinand_manuf_ops = { -+}; -+ -+const struct spinand_manufacturer etron_spinand_manufacturer = { -+ .id = SPINAND_MFR_ETRON, -+ .name = "Etron", -+ .chips = etron_spinand_table, -+ .nchips = ARRAY_SIZE(etron_spinand_table), -+ .ops = &etron_spinand_manuf_ops, -+}; -diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h -index ba7b73c9675e..e5b6ac340383 100644 ---- a/include/linux/mtd/spinand.h -+++ b/include/linux/mtd/spinand.h -@@ -263,6 +263,7 @@ struct spinand_manufacturer { - extern const struct spinand_manufacturer alliancememory_spinand_manufacturer; - extern const struct spinand_manufacturer ato_spinand_manufacturer; - extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer; -+extern const struct spinand_manufacturer etron_spinand_manufacturer; - extern const struct spinand_manufacturer fmsh_spinand_manufacturer; - extern const struct spinand_manufacturer foresee_spinand_manufacturer; - extern const struct spinand_manufacturer gigadevice_spinand_manufacturer; --- -2.51.0 - - -From 41816d01e19a9ff217b6851b822598895cc37a48 Mon Sep 17 00:00:00 2001 -From: Joe Mullally -Date: Mon, 3 Nov 2025 15:49:48 +0100 -Subject: [PATCH 239/517] mtd/spi-nor/xmc: add support for XMC XM25QH64C - -The XMC XM25QH64C is a 8MB SPI NOR chip. The patch is verified on TL-WPA8631P v3. -Datasheet available at https://www.xmcwh.com/uploads/442/XM25QH64C.pdf - -Signed-off-by: Joe Mullally ---- - drivers/mtd/spi-nor/xmc.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/drivers/mtd/spi-nor/xmc.c b/drivers/mtd/spi-nor/xmc.c -index 8eb2d957c8ad..d52756562489 100644 ---- a/drivers/mtd/spi-nor/xmc.c -+++ b/drivers/mtd/spi-nor/xmc.c -@@ -14,6 +14,11 @@ static const struct flash_info xmc_nor_parts[] = { - .name = "XM25QH64A", - .size = SZ_8M, - .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, -+ }, { -+ .id = SNOR_ID(0x20, 0x40, 0x17), -+ .name = "XM25QH64C", -+ .size = SZ_8M, -+ .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, - }, { - .id = SNOR_ID(0x20, 0x70, 0x18), - .name = "XM25QH128A", --- -2.51.0 - - -From e361d0ef02084d0b709b8930a3aaf52a75df6ecc Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Nov 2025 15:49:48 +0100 -Subject: [PATCH 240/517] ubi: auto-attach mtd device named "ubi" or "data" on - boot - -Signed-off-by: Daniel Golle ---- - drivers/mtd/ubi/build.c | 80 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 80 insertions(+) - -diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c -index ef6a22f372f9..82247bfe0332 100644 ---- a/drivers/mtd/ubi/build.c -+++ b/drivers/mtd/ubi/build.c -@@ -1263,6 +1263,80 @@ static struct mtd_notifier ubi_mtd_notifier = { - .remove = ubi_notify_remove, - }; - -+ -+/* -+ * This function tries attaching mtd partitions named either "ubi" or "data" -+ * during boot. -+ */ -+static void __init ubi_auto_attach(void) -+{ -+ int err; -+ struct mtd_info *mtd; -+ struct device_node *np; -+ loff_t offset = 0; -+ size_t len; -+ char magic[4]; -+ -+ /* try attaching mtd device named "ubi" or "data" */ -+ mtd = open_mtd_device("ubi"); -+ if (IS_ERR(mtd)) -+ mtd = open_mtd_device("data"); -+ -+ if (IS_ERR(mtd)) -+ return; -+ -+ /* skip "linux,ubi" mtd as it has already been attached */ -+ np = mtd_get_of_node(mtd); -+ if (of_device_is_compatible(np, "linux,ubi")) -+ goto cleanup; -+ -+ /* get the first not bad block */ -+ if (mtd_can_have_bb(mtd)) -+ while (mtd_block_isbad(mtd, offset)) { -+ offset += mtd->erasesize; -+ -+ if (offset > mtd->size) { -+ pr_err("UBI error: Failed to find a non-bad " -+ "block on mtd%d\n", mtd->index); -+ goto cleanup; -+ } -+ } -+ -+ /* check if the read from flash was successful */ -+ err = mtd_read(mtd, offset, 4, &len, (void *) magic); -+ if ((err && !mtd_is_bitflip(err)) || len != 4) { -+ pr_err("UBI error: unable to read from mtd%d\n", mtd->index); -+ goto cleanup; -+ } -+ -+ /* check for a valid ubi magic */ -+ if (strncmp(magic, "UBI#", 4)) { -+ pr_err("UBI error: no valid UBI magic found inside mtd%d\n", mtd->index); -+ goto cleanup; -+ } -+ -+ /* don't auto-add media types where UBI doesn't makes sense */ -+ if (mtd->type != MTD_NANDFLASH && -+ mtd->type != MTD_NORFLASH && -+ mtd->type != MTD_DATAFLASH && -+ mtd->type != MTD_MLCNANDFLASH) -+ goto cleanup; -+ -+ mutex_lock(&ubi_devices_mutex); -+ pr_notice("UBI: auto-attach mtd%d\n", mtd->index); -+ err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, 0, 0, false, false); -+ mutex_unlock(&ubi_devices_mutex); -+ if (err < 0) { -+ pr_err("UBI error: cannot attach mtd%d\n", mtd->index); -+ goto cleanup; -+ } -+ -+ return; -+ -+cleanup: -+ put_mtd_device(mtd); -+} -+ - static int __init ubi_init_attach(void) - { - int err, i, k; -@@ -1314,6 +1388,12 @@ static int __init ubi_init_attach(void) - } - } - -+ /* auto-attach mtd devices only if built-in to the kernel and no ubi.mtd -+ * parameter was given */ -+ if (IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) && -+ !ubi_is_module() && !mtd_devs) -+ ubi_auto_attach(); -+ - return 0; - - out_detach: --- -2.51.0 - - -From cad4fa01f1219cb6fa41fd18dc398100e5963f23 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Nov 2025 15:49:48 +0100 -Subject: [PATCH 241/517] ubi: auto-create ubiblock device for rootfs - -Signed-off-by: Daniel Golle ---- - drivers/mtd/ubi/block.c | 42 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 42 insertions(+) - -diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c -index 60d0155be869..3d2f89cfbab0 100644 ---- a/drivers/mtd/ubi/block.c -+++ b/drivers/mtd/ubi/block.c -@@ -575,10 +575,47 @@ match_volume_desc(struct ubi_volume_info *vi, const char *name, int ubi_num, int - return true; - } - -+#define UBIFS_NODE_MAGIC 0x06101831 -+static inline int ubi_vol_is_ubifs(struct ubi_volume_desc *desc) -+{ -+ int ret; -+ uint32_t magic_of, magic; -+ ret = ubi_read(desc, 0, (char *)&magic_of, 0, 4); -+ if (ret) -+ return 0; -+ magic = le32_to_cpu(magic_of); -+ return magic == UBIFS_NODE_MAGIC; -+} -+ -+static void ubiblock_create_auto_rootfs(struct ubi_volume_info *vi) -+{ -+ int ret, is_ubifs; -+ struct ubi_volume_desc *desc; -+ -+ if (strcmp(vi->name, "rootfs") && -+ strcmp(vi->name, "fit")) -+ return; -+ -+ desc = ubi_open_volume(vi->ubi_num, vi->vol_id, UBI_READONLY); -+ if (IS_ERR(desc)) -+ return; -+ -+ is_ubifs = ubi_vol_is_ubifs(desc); -+ ubi_close_volume(desc); -+ if (is_ubifs) -+ return; -+ -+ ret = ubiblock_create(vi); -+ if (ret) -+ pr_err("UBI error: block: can't add '%s' volume, err=%d\n", -+ vi->name, ret); -+} -+ - static void - ubiblock_create_from_param(struct ubi_volume_info *vi) - { - int i, ret = 0; -+ bool got_param = false; - struct ubiblock_param *p; - - /* -@@ -591,6 +628,7 @@ ubiblock_create_from_param(struct ubi_volume_info *vi) - if (!match_volume_desc(vi, p->name, p->ubi_num, p->vol_id)) - continue; - -+ got_param = true; - ret = ubiblock_create(vi); - if (ret) { - pr_err( -@@ -599,6 +637,10 @@ ubiblock_create_from_param(struct ubi_volume_info *vi) - } - break; - } -+ -+ /* auto-attach "rootfs" volume if existing and non-ubifs */ -+ if (!got_param && IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV)) -+ ubiblock_create_auto_rootfs(vi); - } - - static int ubiblock_notify(struct notifier_block *nb, --- -2.51.0 - - -From 74dbb1605aced27216d2caa82680008159d34baf Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Nov 2025 15:49:49 +0100 -Subject: [PATCH 242/517] try auto-mounting ubi0:rootfs in init/do_mounts.c - -Signed-off-by: Daniel Golle ---- - init/do_mounts.c | 30 +++++++++++++++++++++++++++++- - 1 file changed, 29 insertions(+), 1 deletion(-) - -diff --git a/init/do_mounts.c b/init/do_mounts.c -index 6af29da8889e..cbb4237700aa 100644 ---- a/init/do_mounts.c -+++ b/init/do_mounts.c -@@ -250,7 +250,30 @@ void __init mount_root_generic(char *name, char *pretty_name, int flags) - out: - put_page(page); - } -- -+ -+#ifdef CONFIG_MTD_ROOTFS_ROOT_DEV -+static int __init mount_ubi_rootfs(void) -+{ -+ int flags = MS_SILENT; -+ int err, tried = 0; -+ -+ while (tried < 2) { -+ err = do_mount_root("ubi0:rootfs", "ubifs", flags, \ -+ root_mount_data); -+ switch (err) { -+ case -EACCES: -+ flags |= MS_RDONLY; -+ tried++; -+ break; -+ default: -+ return err; -+ } -+ } -+ -+ return -EINVAL; -+} -+#endif -+ - #ifdef CONFIG_ROOT_NFS - - #define NFSROOT_TIMEOUT_MIN 5 -@@ -387,6 +410,11 @@ static inline void mount_block_root(char *root_device_name) - - void __init mount_root(char *root_device_name) - { -+#ifdef CONFIG_MTD_ROOTFS_ROOT_DEV -+ if (!mount_ubi_rootfs()) -+ return; -+#endif -+ - switch (ROOT_DEV) { - case Root_NFS: - mount_nfs_root(); --- -2.51.0 - - -From 91bf41024ca9e5396631a8b1aadf12b6c3396d3b Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Nov 2025 15:49:49 +0100 -Subject: [PATCH 243/517] ubi: set ROOT_DEV to ubiblock "rootfs" if unset - -Signed-off-by: Daniel Golle ---- - drivers/mtd/ubi/block.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c -index 3d2f89cfbab0..b45f9ca8866a 100644 ---- a/drivers/mtd/ubi/block.c -+++ b/drivers/mtd/ubi/block.c -@@ -41,6 +41,7 @@ - #include - #include - #include -+#include - - #include "ubi-media.h" - #include "ubi.h" -@@ -431,6 +432,15 @@ int ubiblock_create(struct ubi_volume_info *vi) - dev_info(disk_to_dev(dev->gd), "created from ubi%d:%d(%s)", - dev->ubi_num, dev->vol_id, vi->name); - mutex_unlock(&devices_mutex); -+ -+ if (!strcmp(vi->name, "rootfs") && -+ IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) && -+ ROOT_DEV == 0) { -+ pr_notice("ubiblock: device ubiblock%d_%d (%s) set to be root filesystem\n", -+ dev->ubi_num, dev->vol_id, vi->name); -+ ROOT_DEV = MKDEV(gd->major, gd->first_minor); -+ } -+ - return 0; - - out_remove_minor: --- -2.51.0 - - -From e756171aa3fa371557bab27c509acd4f23b1f2f8 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Mon, 3 Nov 2025 15:49:49 +0100 -Subject: [PATCH 244/517] mtd: add EOF marker support to the UBI layer - -Signed-off-by: Gabor Juhos ---- - drivers/mtd/ubi/attach.c | 25 ++++++++++++++++++++++--- - drivers/mtd/ubi/ubi.h | 1 + - 2 files changed, 23 insertions(+), 3 deletions(-) - -diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c -index adc47b87b38a..7eae13888f1c 100644 ---- a/drivers/mtd/ubi/attach.c -+++ b/drivers/mtd/ubi/attach.c -@@ -926,6 +926,13 @@ static bool vol_ignored(int vol_id) - #endif - } - -+static bool ec_hdr_has_eof(struct ubi_ec_hdr *ech) -+{ -+ return ech->padding1[0] == 'E' && -+ ech->padding1[1] == 'O' && -+ ech->padding1[2] == 'F'; -+} -+ - /** - * scan_peb - scan and process UBI headers of a PEB. - * @ubi: UBI device description object -@@ -958,9 +965,21 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, - return 0; - } - -- err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); -- if (err < 0) -- return err; -+ if (!ai->eof_found) { -+ err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); -+ if (err < 0) -+ return err; -+ -+ if (ec_hdr_has_eof(ech)) { -+ pr_notice("UBI: EOF marker found, PEBs from %d will be erased\n", -+ pnum); -+ ai->eof_found = true; -+ } -+ } -+ -+ if (ai->eof_found) -+ err = UBI_IO_FF_BITFLIPS; -+ - switch (err) { - case 0: - break; -diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h -index 1c9e874e8ede..690f25ffddc2 100644 ---- a/drivers/mtd/ubi/ubi.h -+++ b/drivers/mtd/ubi/ubi.h -@@ -778,6 +778,7 @@ struct ubi_attach_info { - int mean_ec; - uint64_t ec_sum; - int ec_count; -+ bool eof_found; - struct kmem_cache *aeb_slab_cache; - struct ubi_ec_hdr *ech; - struct ubi_vid_io_buf *vidb; --- -2.51.0 - - -From 4604417d761220471f5000b78a352f879a81b611 Mon Sep 17 00:00:00 2001 -From: Bernhard Frauendienst -Date: Wed, 5 Sep 2018 01:32:51 +0200 -Subject: [PATCH 245/517] dt-bindings: add bindings for mtd-concat devices - -Document virtual mtd-concat device bindings. - -Signed-off-by: Bernhard Frauendienst ---- - .../devicetree/bindings/mtd/mtd-concat.txt | 36 +++++++++++++++++++ - 1 file changed, 36 insertions(+) - create mode 100644 Documentation/devicetree/bindings/mtd/mtd-concat.txt - -diff --git a/Documentation/devicetree/bindings/mtd/mtd-concat.txt b/Documentation/devicetree/bindings/mtd/mtd-concat.txt -new file mode 100644 -index 000000000000..2daf3157b163 ---- /dev/null -+++ b/Documentation/devicetree/bindings/mtd/mtd-concat.txt -@@ -0,0 +1,36 @@ -+Virtual MTD concat device -+ -+Requires properties: -+- devices: list of phandles to mtd nodes that should be concatenated -+ -+Example: -+ -+&spi { -+ flash0: flash@0 { -+ ... -+ }; -+ flash1: flash@1 { -+ ... -+ }; -+}; -+ -+flash { -+ compatible = "mtd-concat"; -+ -+ devices = <&flash0 &flash1>; -+ -+ partitions { -+ compatible = "fixed-partitions"; -+ -+ partition@0 { -+ label = "boot"; -+ reg = <0x0000000 0x0040000>; -+ read-only; -+ }; -+ -+ partition@40000 { -+ label = "firmware"; -+ reg = <0x0040000 0x1fc0000>; -+ }; -+ } -+} --- -2.51.0 - - -From f8d352e43303fc728b050bad1ec4f0684a348978 Mon Sep 17 00:00:00 2001 -From: Bernhard Frauendienst -Date: Sat, 25 Aug 2018 12:35:22 +0200 -Subject: [PATCH 246/517] mtd: mtdconcat: add dt driver for concat devices - -Some mtd drivers like physmap variants have support for concatenating -multiple mtd devices, but there is no generic way to define such a -concat device from within the device tree. - -This is useful for some SoC boards that use multiple flash chips as -memory banks of a single mtd device, with partitions spanning chip -borders. - -This commit adds a driver for creating virtual mtd-concat devices. They -must have a compatible = "mtd-concat" line, and define a list of devices -to concat in the 'devices' property, for example: - -flash { - compatible = "mtd-concat"; - - devices = <&flash0 &flash1>; - - partitions { - ... - }; -}; - -The driver is added to the very end of the mtd Makefile to increase the -likelyhood of all child devices already being loaded at the time of -probing, preventing unnecessary deferred probes. - -Signed-off-by: Bernhard Frauendienst ---- - drivers/mtd/Kconfig | 2 + - drivers/mtd/Makefile | 3 + - drivers/mtd/composite/Kconfig | 12 +++ - drivers/mtd/composite/Makefile | 6 ++ - drivers/mtd/composite/virt_concat.c | 127 ++++++++++++++++++++++++++++ - 5 files changed, 150 insertions(+) - create mode 100644 drivers/mtd/composite/Kconfig - create mode 100644 drivers/mtd/composite/Makefile - create mode 100644 drivers/mtd/composite/virt_concat.c - -diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig -index f9ed93c4cf0f..7e4a3fa1dfd0 100644 ---- a/drivers/mtd/Kconfig -+++ b/drivers/mtd/Kconfig -@@ -241,4 +241,6 @@ source "drivers/mtd/ubi/Kconfig" - - source "drivers/mtd/hyperbus/Kconfig" - -+source "drivers/mtd/composite/Kconfig" -+ - endif # MTD -diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile -index b14b7fe0f597..fbea3736b488 100644 ---- a/drivers/mtd/Makefile -+++ b/drivers/mtd/Makefile -@@ -33,3 +33,6 @@ obj-y += chips/ lpddr/ maps/ devices/ nand/ tests/ - obj-$(CONFIG_MTD_SPI_NOR) += spi-nor/ - obj-$(CONFIG_MTD_UBI) += ubi/ - obj-$(CONFIG_MTD_HYPERBUS) += hyperbus/ -+ -+# Composite drivers must be loaded last -+obj-y += composite/ -diff --git a/drivers/mtd/composite/Kconfig b/drivers/mtd/composite/Kconfig -new file mode 100644 -index 000000000000..0490fc0284bb ---- /dev/null -+++ b/drivers/mtd/composite/Kconfig -@@ -0,0 +1,12 @@ -+menu "Composite MTD device drivers" -+ depends on MTD!=n -+ -+config MTD_VIRT_CONCAT -+ tristate "Virtual concat MTD device" -+ help -+ This driver allows creation of a virtual MTD concat device, which -+ concatenates multiple underlying MTD devices to a single device. -+ This is required by some SoC boards where multiple memory banks are -+ used as one device with partitions spanning across device boundaries. -+ -+endmenu -diff --git a/drivers/mtd/composite/Makefile b/drivers/mtd/composite/Makefile -new file mode 100644 -index 000000000000..8421a0a30606 ---- /dev/null -+++ b/drivers/mtd/composite/Makefile -@@ -0,0 +1,6 @@ -+# SPDX-License-Identifier: GPL-2.0 -+# -+# linux/drivers/mtd/composite/Makefile -+# -+ -+obj-$(CONFIG_MTD_VIRT_CONCAT) += virt_concat.o -diff --git a/drivers/mtd/composite/virt_concat.c b/drivers/mtd/composite/virt_concat.c -new file mode 100644 -index 000000000000..05b4b9a7539e ---- /dev/null -+++ b/drivers/mtd/composite/virt_concat.c -@@ -0,0 +1,127 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Virtual concat MTD device driver -+ * -+ * Copyright (C) 2018 Bernhard Frauendienst -+ * Author: Bernhard Frauendienst, kernel@nospam.obeliks.de -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* -+ * struct of_virt_concat - platform device driver data. -+ * @cmtd the final mtd_concat device -+ * @num_devices the number of devices in @devices -+ * @devices points to an array of devices already loaded -+ */ -+struct of_virt_concat { -+ struct mtd_info *cmtd; -+ int num_devices; -+ struct mtd_info **devices; -+}; -+ -+static void virt_concat_remove(struct platform_device *pdev) -+{ -+ struct of_virt_concat *info; -+ int i; -+ -+ info = platform_get_drvdata(pdev); -+ if (!info) -+ return; -+ -+ // unset data for when this is called after a probe error -+ platform_set_drvdata(pdev, NULL); -+ -+ if (info->cmtd) { -+ mtd_device_unregister(info->cmtd); -+ mtd_concat_destroy(info->cmtd); -+ } -+ -+ if (info->devices) { -+ for (i = 0; i < info->num_devices; i++) -+ put_mtd_device(info->devices[i]); -+ } -+} -+ -+static int virt_concat_probe(struct platform_device *pdev) -+{ -+ struct device_node *node = pdev->dev.of_node; -+ struct of_phandle_iterator it; -+ struct of_virt_concat *info; -+ struct mtd_info *mtd; -+ int err = 0, count; -+ -+ count = of_count_phandle_with_args(node, "devices", NULL); -+ if (count <= 0) -+ return -EINVAL; -+ -+ info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); -+ if (!info) -+ return -ENOMEM; -+ info->devices = devm_kcalloc(&pdev->dev, count, -+ sizeof(*(info->devices)), GFP_KERNEL); -+ if (!info->devices) { -+ err = -ENOMEM; -+ goto err_remove; -+ } -+ -+ platform_set_drvdata(pdev, info); -+ -+ of_for_each_phandle(&it, err, node, "devices", NULL, 0) { -+ mtd = of_get_mtd_device_by_node(it.node); -+ if (IS_ERR(mtd)) { -+ of_node_put(it.node); -+ err = -EPROBE_DEFER; -+ goto err_remove; -+ } -+ -+ info->devices[info->num_devices++] = mtd; -+ } -+ -+ info->cmtd = mtd_concat_create(info->devices, info->num_devices, -+ dev_name(&pdev->dev)); -+ if (!info->cmtd) { -+ err = -ENXIO; -+ goto err_remove; -+ } -+ -+ info->cmtd->dev.parent = &pdev->dev; -+ mtd_set_of_node(info->cmtd, node); -+ mtd_device_register(info->cmtd, NULL, 0); -+ -+ return 0; -+ -+err_remove: -+ virt_concat_remove(pdev); -+ -+ return err; -+} -+ -+static const struct of_device_id virt_concat_of_match[] = { -+ { .compatible = "mtd-concat", }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, virt_concat_of_match); -+ -+static struct platform_driver virt_concat_driver = { -+ .probe = virt_concat_probe, -+ .remove = virt_concat_remove, -+ .driver = { -+ .name = "virt-mtdconcat", -+ .of_match_table = virt_concat_of_match, -+ }, -+}; -+ -+module_platform_driver(virt_concat_driver); -+ -+MODULE_LICENSE("GPL v2"); -+MODULE_AUTHOR("Bernhard Frauendienst "); -+MODULE_DESCRIPTION("Virtual concat MTD device driver"); --- -2.51.0 - - -From 347c5537f56a96c67c3a22c4f3779c4b95dc11a5 Mon Sep 17 00:00:00 2001 -From: Nick Hainke -Date: Mon, 27 Dec 2021 00:38:13 +0100 -Subject: [PATCH 247/517] mtd: spi-nor: locking support for MX25L6405D - -Macronix MX25L6405D supports locking with four block-protection bits. -Currently, the driver only sets three bits. If the bootloader does not -sustain the flash chip in an unlocked state, the flash might be -non-writeable. Add the corresponding flag to enable locking support with -four bits in the status register. - -Tested on Nanostation M2 XM. - -Similar to commit 7ea40b54e83b ("mtd: spi-nor: enable locking support for -MX25L12805D") - -Signed-off-by: David Bauer -Signed-off-by: Nick Hainke ---- - drivers/mtd/spi-nor/macronix.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/mtd/spi-nor/macronix.c b/drivers/mtd/spi-nor/macronix.c -index ac125b89e7ba..d31b2590c849 100644 ---- a/drivers/mtd/spi-nor/macronix.c -+++ b/drivers/mtd/spi-nor/macronix.c -@@ -66,6 +66,7 @@ static const struct flash_info macronix_nor_parts[] = { - .id = SNOR_ID(0xc2, 0x20, 0x17), - .name = "mx25l6405d", - .size = SZ_8M, -+ .flags = SPI_NOR_HAS_LOCK | SPI_NOR_4BIT_BP, - .no_sfdp_flags = SECT_4K, - }, { - .id = SNOR_ID(0xc2, 0x20, 0x18), --- -2.51.0 - - -From 9fa9e3569e11cbb64b50a208ae98a4b2e09e00c4 Mon Sep 17 00:00:00 2001 -From: Nick Hainke -Date: Mon, 27 Dec 2021 09:33:13 +0100 -Subject: [PATCH 248/517] mtd: spi-nor: disable 16-bit-sr for macronix - -Macronix flash chips seem to consist of only one status register. -These chips will not work with the "16-bit Write Status (01h) Command". -Disable SNOR_F_HAS_16BIT_SR for all Macronix chips. - -Tested with MX25L6405D. - -Fixes: 39d1e3340c73 ("mtd: spi-nor: Fix clearing of QE bit on -lock()/unlock()") - -Signed-off-by: David Bauer -Signed-off-by: Nick Hainke ---- - drivers/mtd/spi-nor/macronix.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/mtd/spi-nor/macronix.c b/drivers/mtd/spi-nor/macronix.c -index d31b2590c849..873c199616ee 100644 ---- a/drivers/mtd/spi-nor/macronix.c -+++ b/drivers/mtd/spi-nor/macronix.c -@@ -195,6 +195,7 @@ static int macronix_nor_late_init(struct spi_nor *nor) - { - if (!nor->params->set_4byte_addr_mode) - nor->params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode_en4b_ex4b; -+ nor->flags &= ~SNOR_F_HAS_16BIT_SR; - nor->flags |= SNOR_F_HAS_LOCK; - - return 0; --- -2.51.0 - - -From c57f1d7da4a3684160aad8280a29764983fc99e0 Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 12:21:15 +0200 -Subject: [PATCH 249/517] fs: add cdrom dependency - ---- - fs/hfs/Kconfig | 1 + - fs/hfsplus/Kconfig | 1 + - fs/isofs/Kconfig | 1 + - fs/udf/Kconfig | 1 + - 4 files changed, 4 insertions(+) - -diff --git a/fs/hfs/Kconfig b/fs/hfs/Kconfig -index 5ea5cd8ecea9..8a0ca259dc58 100644 ---- a/fs/hfs/Kconfig -+++ b/fs/hfs/Kconfig -@@ -2,6 +2,7 @@ - config HFS_FS - tristate "Apple Macintosh file system support" - depends on BLOCK -+ select CDROM - select BUFFER_HEAD - select NLS - select LEGACY_DIRECT_IO -diff --git a/fs/hfsplus/Kconfig b/fs/hfsplus/Kconfig -index 8ce4a33a9ac7..f3f07878dbbd 100644 ---- a/fs/hfsplus/Kconfig -+++ b/fs/hfsplus/Kconfig -@@ -2,6 +2,7 @@ - config HFSPLUS_FS - tristate "Apple Extended HFS file system support" - depends on BLOCK -+ select CDROM - select BUFFER_HEAD - select NLS - select NLS_UTF8 -diff --git a/fs/isofs/Kconfig b/fs/isofs/Kconfig -index 51434f2a471b..9847d2e3aac2 100644 ---- a/fs/isofs/Kconfig -+++ b/fs/isofs/Kconfig -@@ -1,6 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0-only - config ISO9660_FS - tristate "ISO 9660 CDROM file system support" -+ select CDROM - select BUFFER_HEAD - help - This is the standard file system used on CD-ROMs. It was previously -diff --git a/fs/udf/Kconfig b/fs/udf/Kconfig -index 8f7ce30d47fd..0b015b1a455a 100644 ---- a/fs/udf/Kconfig -+++ b/fs/udf/Kconfig -@@ -1,6 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0-only - config UDF_FS - tristate "UDF file system support" -+ select CDROM - select BUFFER_HEAD - select CRC_ITU_T - select NLS --- -2.51.0 - - -From 518d8e07b43f2428a02fef795710a7ddab3e7ae1 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Wed, 16 Nov 2022 12:49:52 +0000 -Subject: [PATCH 250/517] block: add uImage.FIT subimage block driver - -Add a small block driver which exposes filesystem sub-images contained -in U-Boot uImage.FIT images as block devices. - -The uImage.FIT image has to be stored directly on a block device or -partition, MTD device or partition, or UBI volume. - -The driver is intended for systems using the U-Boot bootloader and -uses the root device hint left by the bootloader (or the user) in -the 'chosen' section of the device-tree. - -Example: -/dts-v1/; -/ { - chosen { - rootdisk = <&mmc0_part3>; - }; -}; - -Signed-off-by: Daniel Golle ---- - MAINTAINERS | 6 + - drivers/block/Kconfig | 12 + - drivers/block/Makefile | 2 + - drivers/block/fitblk.c | 660 ++++++++++++++++++++++++++++++++++++ - include/uapi/linux/fitblk.h | 10 + - 5 files changed, 690 insertions(+) - create mode 100644 drivers/block/fitblk.c - create mode 100644 include/uapi/linux/fitblk.h - -diff --git a/MAINTAINERS b/MAINTAINERS -index 7d694e7b4f42..dcb5c71bc204 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -23668,6 +23668,12 @@ F: Documentation/filesystems/ubifs-authentication.rst - F: Documentation/filesystems/ubifs.rst - F: fs/ubifs/ - -+U-BOOT UIMAGE.FIT PARSER -+M: Daniel Golle -+L: linux-block@vger.kernel.org -+S: Maintained -+F: drivers/block/fitblk.c -+ - UBLK USERSPACE BLOCK DRIVER - M: Ming Lei - L: linux-block@vger.kernel.org -diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig -index ed209f4f2798..c777065f70e4 100644 ---- a/drivers/block/Kconfig -+++ b/drivers/block/Kconfig -@@ -363,6 +363,18 @@ config BLK_DEV_RUST_NULL - - If unsure, say N. - -+config UIMAGE_FIT_BLK -+ bool "uImage.FIT block driver" -+ help -+ This driver allows using filesystems contained in uImage.FIT images -+ by mapping them as block devices. -+ -+ It can currently not be built as a module due to libfdt symbols not -+ being exported. -+ -+ Say Y if you want to mount filesystems sub-images of a uImage.FIT -+ stored in a block device partition, mtdblock or ubiblock device. -+ - config BLK_DEV_RBD - tristate "Rados block device (RBD)" - depends on INET && BLOCK -diff --git a/drivers/block/Makefile b/drivers/block/Makefile -index 1105a2d4fdcb..2ba7b5ad8f6f 100644 ---- a/drivers/block/Makefile -+++ b/drivers/block/Makefile -@@ -42,4 +42,6 @@ obj-$(CONFIG_BLK_DEV_NULL_BLK) += null_blk/ - - obj-$(CONFIG_BLK_DEV_UBLK) += ublk_drv.o - -+obj-$(CONFIG_UIMAGE_FIT_BLK) += fitblk.o -+ - swim_mod-y := swim.o swim_asm.o -diff --git a/drivers/block/fitblk.c b/drivers/block/fitblk.c -new file mode 100644 -index 000000000000..b6d8e0fd25a0 ---- /dev/null -+++ b/drivers/block/fitblk.c -@@ -0,0 +1,660 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * uImage.FIT virtual block device driver. -+ * -+ * Copyright (C) 2023 Daniel Golle -+ * Copyright (C) 2007 Nick Piggin -+ * Copyright (C) 2007 Novell Inc. -+ * -+ * Initially derived from drivers/block/brd.c which is in parts derived from -+ * drivers/block/rd.c, and drivers/block/loop.c, copyright of their respective -+ * owners. -+ * -+ * uImage.FIT headers extracted from Das U-Boot -+ * (C) Copyright 2008 Semihalf -+ * (C) Copyright 2000-2005 -+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define FIT_DEVICE_PREFIX "fit" -+ -+/* maximum number of pages used for the uImage.FIT index structure */ -+#define FIT_MAX_PAGES 1024 -+ -+/* minimum free sectors to map as read-write "remainder" volume */ -+#define MIN_FREE_SECT 16 -+ -+/* maximum number of mapped loadables */ -+#define MAX_FIT_LOADABLES 16 -+ -+/* constants for uImage.FIT structrure traversal */ -+#define FIT_IMAGES_PATH "/images" -+#define FIT_CONFS_PATH "/configurations" -+ -+/* hash/signature/key node */ -+#define FIT_HASH_NODENAME "hash" -+#define FIT_ALGO_PROP "algo" -+#define FIT_VALUE_PROP "value" -+#define FIT_IGNORE_PROP "uboot-ignore" -+#define FIT_SIG_NODENAME "signature" -+#define FIT_KEY_REQUIRED "required" -+#define FIT_KEY_HINT "key-name-hint" -+ -+/* cipher node */ -+#define FIT_CIPHER_NODENAME "cipher" -+#define FIT_ALGO_PROP "algo" -+ -+/* image node */ -+#define FIT_DATA_PROP "data" -+#define FIT_DATA_POSITION_PROP "data-position" -+#define FIT_DATA_OFFSET_PROP "data-offset" -+#define FIT_DATA_SIZE_PROP "data-size" -+#define FIT_TIMESTAMP_PROP "timestamp" -+#define FIT_DESC_PROP "description" -+#define FIT_ARCH_PROP "arch" -+#define FIT_TYPE_PROP "type" -+#define FIT_OS_PROP "os" -+#define FIT_COMP_PROP "compression" -+#define FIT_ENTRY_PROP "entry" -+#define FIT_LOAD_PROP "load" -+ -+/* configuration node */ -+#define FIT_KERNEL_PROP "kernel" -+#define FIT_FILESYSTEM_PROP "filesystem" -+#define FIT_RAMDISK_PROP "ramdisk" -+#define FIT_FDT_PROP "fdt" -+#define FIT_LOADABLE_PROP "loadables" -+#define FIT_DEFAULT_PROP "default" -+#define FIT_SETUP_PROP "setup" -+#define FIT_FPGA_PROP "fpga" -+#define FIT_FIRMWARE_PROP "firmware" -+#define FIT_STANDALONE_PROP "standalone" -+ -+/* fitblk driver data */ -+static const char *_fitblk_claim_ptr = "I belong to fitblk"; -+static const char *ubootver; -+struct device_node *rootdisk; -+static struct platform_device *pdev; -+static LIST_HEAD(fitblk_devices); -+static DEFINE_MUTEX(devices_mutex); -+refcount_t num_devs; -+ -+struct fitblk { -+ struct platform_device *pdev; -+ struct file *bdev_file; -+ sector_t start_sect; -+ struct gendisk *disk; -+ struct work_struct remove_work; -+ struct list_head list; -+ bool dead; -+}; -+ -+static int fitblk_open(struct gendisk *disk, fmode_t mode) -+{ -+ struct fitblk *fitblk = disk->private_data; -+ -+ if (fitblk->dead) -+ return -ENOENT; -+ -+ return 0; -+} -+ -+static void fitblk_release(struct gendisk *disk) -+{ -+ return; -+} -+ -+static void fitblk_submit_bio(struct bio *orig_bio) -+{ -+ struct bio *bio = orig_bio; -+ struct fitblk *fitblk = bio->bi_bdev->bd_disk->private_data; -+ -+ if (fitblk->dead) -+ return; -+ -+ /* mangle bio and re-submit */ -+ while (bio) { -+ bio->bi_iter.bi_sector += fitblk->start_sect; -+ bio->bi_bdev = file_bdev(fitblk->bdev_file); -+ bio = bio->bi_next; -+ } -+ submit_bio(orig_bio); -+} -+ -+static void fitblk_remove(struct fitblk *fitblk) -+{ -+ blk_mark_disk_dead(fitblk->disk); -+ mutex_lock(&devices_mutex); -+ fitblk->dead = true; -+ list_del(&fitblk->list); -+ mutex_unlock(&devices_mutex); -+ -+ schedule_work(&fitblk->remove_work); -+} -+ -+static int fitblk_ioctl(struct block_device *bdev, fmode_t mode, -+ unsigned int cmd, unsigned long arg) -+{ -+ struct fitblk *fitblk = bdev->bd_disk->private_data; -+ -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EACCES; -+ -+ if (fitblk->dead) -+ return -ENOENT; -+ -+ switch (cmd) { -+ case FITBLK_RELEASE: -+ fitblk_remove(fitblk); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static const struct block_device_operations fitblk_fops = { -+ .owner = THIS_MODULE, -+ .ioctl = fitblk_ioctl, -+ .open = fitblk_open, -+ .release = fitblk_release, -+ .submit_bio = fitblk_submit_bio, -+}; -+ -+static void fitblk_purge(struct work_struct *work) -+{ -+ struct fitblk *fitblk = container_of(work, struct fitblk, remove_work); -+ -+ del_gendisk(fitblk->disk); -+ refcount_dec(&num_devs); -+ platform_device_del(fitblk->pdev); -+ platform_device_put(fitblk->pdev); -+ -+ if (refcount_dec_if_one(&num_devs)) { -+ sysfs_remove_link(&pdev->dev.kobj, "lower_dev"); -+ fput(fitblk->bdev_file); -+ } -+ -+ kfree(fitblk); -+} -+ -+static int add_fit_subimage_device(struct file *bdev_file, -+ unsigned int slot, sector_t start_sect, -+ sector_t nr_sect, bool readonly) -+{ -+ struct block_device *bdev = file_bdev(bdev_file); -+ struct fitblk *fitblk; -+ struct gendisk *disk; -+ int err; -+ -+ mutex_lock(&devices_mutex); -+ if (!refcount_inc_not_zero(&num_devs)) -+ return -EBADF; -+ -+ fitblk = kzalloc(sizeof(struct fitblk), GFP_KERNEL); -+ if (!fitblk) { -+ err = -ENOMEM; -+ goto out_unlock; -+ } -+ -+ fitblk->bdev_file = bdev_file; -+ fitblk->start_sect = start_sect; -+ INIT_WORK(&fitblk->remove_work, fitblk_purge); -+ -+ disk = blk_alloc_disk(&bdev->bd_disk->queue->limits, NUMA_NO_NODE); -+ if (!disk) { -+ err = -ENOMEM; -+ goto out_free_fitblk; -+ } -+ -+ disk->first_minor = 0; -+ disk->flags = bdev->bd_disk->flags | GENHD_FL_NO_PART; -+ disk->fops = &fitblk_fops; -+ disk->private_data = fitblk; -+ if (readonly) { -+ set_disk_ro(disk, 1); -+ snprintf(disk->disk_name, sizeof(disk->disk_name), FIT_DEVICE_PREFIX "%u", slot); -+ } else { -+ strcpy(disk->disk_name, FIT_DEVICE_PREFIX "rw"); -+ } -+ -+ set_capacity(disk, nr_sect); -+ disk->queue->queue_flags = bdev->bd_disk->queue->queue_flags; -+ -+ fitblk->disk = disk; -+ fitblk->pdev = platform_device_alloc(disk->disk_name, PLATFORM_DEVID_NONE); -+ if (!fitblk->pdev) { -+ err = -ENOMEM; -+ goto out_cleanup_disk; -+ } -+ -+ fitblk->pdev->dev.parent = &pdev->dev; -+ err = platform_device_add(fitblk->pdev); -+ if (err) -+ goto out_put_pdev; -+ -+ err = device_add_disk(&fitblk->pdev->dev, disk, NULL); -+ if (err) -+ goto out_del_pdev; -+ -+ if (!ROOT_DEV) -+ ROOT_DEV = disk->part0->bd_dev; -+ -+ list_add_tail(&fitblk->list, &fitblk_devices); -+ -+ mutex_unlock(&devices_mutex); -+ -+ return 0; -+ -+out_del_pdev: -+ platform_device_del(fitblk->pdev); -+out_put_pdev: -+ platform_device_put(fitblk->pdev); -+out_cleanup_disk: -+ put_disk(disk); -+out_free_fitblk: -+ kfree(fitblk); -+out_unlock: -+ refcount_dec(&num_devs); -+ mutex_unlock(&devices_mutex); -+ return err; -+} -+ -+static void fitblk_mark_dead(struct block_device *bdev, bool surprise) -+{ -+ struct list_head *n, *tmp; -+ struct fitblk *fitblk; -+ -+ mutex_lock(&devices_mutex); -+ list_for_each_safe(n, tmp, &fitblk_devices) { -+ fitblk = list_entry(n, struct fitblk, list); -+ if (file_bdev(fitblk->bdev_file) != bdev) -+ continue; -+ -+ fitblk->dead = true; -+ list_del(&fitblk->list); -+ /* removal needs to be deferred to avoid deadlock */ -+ schedule_work(&fitblk->remove_work); -+ } -+ mutex_unlock(&devices_mutex); -+} -+ -+static const struct blk_holder_ops fitblk_hops = { -+ .mark_dead = fitblk_mark_dead, -+}; -+ -+static int parse_fit_on_dev(struct device *dev) -+{ -+ struct file *bdev_file; -+ struct block_device *bdev; -+ struct address_space *mapping; -+ struct folio *folio; -+ pgoff_t f_index = 0; -+ size_t bytes_left, bytes_to_copy; -+ void *pre_fit, *fit, *fit_c; -+ u64 dsize, dsectors, imgmaxsect = 0; -+ u32 size, image_pos, image_len; -+ const __be32 *image_offset_be, *image_len_be, *image_pos_be; -+ int ret = 0, node, images, config; -+ const char *image_name, *image_type, *image_description, -+ *config_default, *config_description, *config_loadables; -+ u32 image_name_len, image_type_len, image_description_len, -+ bootconf_len, config_default_len, config_description_len, -+ config_loadables_len; -+ sector_t start_sect, nr_sects; -+ struct device_node *np = NULL; -+ const char *bootconf_c; -+ const char *loadable; -+ char *bootconf = NULL, *bootconf_term; -+ bool found; -+ int loadables_rem_len, loadable_len; -+ u16 loadcnt; -+ unsigned int slot = 0; -+ -+ /* Exclusive open the block device to receive holder notifications */ -+ bdev_file = bdev_file_open_by_dev(dev->devt, -+ BLK_OPEN_READ | BLK_OPEN_RESTRICT_WRITES, -+ &_fitblk_claim_ptr, &fitblk_hops); -+ if (!bdev_file) -+ return -ENODEV; -+ -+ if (IS_ERR(bdev_file)) -+ return PTR_ERR(bdev_file); -+ -+ bdev = file_bdev(bdev_file); -+ mapping = bdev_file->f_mapping; -+ -+ /* map first page */ -+ folio = read_mapping_folio(mapping, f_index++, NULL); -+ if (IS_ERR(folio)) { -+ ret = PTR_ERR(folio); -+ goto out_blkdev; -+ } -+ pre_fit = folio_address(folio) + offset_in_folio(folio, 0); -+ -+ /* uImage.FIT is based on flattened device tree structure */ -+ if (fdt_check_header(pre_fit)) { -+ ret = -EINVAL; -+ folio_put(folio); -+ goto out_blkdev; -+ } -+ -+ size = fdt_totalsize(pre_fit); -+ -+ if (size > PAGE_SIZE * FIT_MAX_PAGES) { -+ ret = -EOPNOTSUPP; -+ folio_put(folio); -+ goto out_blkdev; -+ } -+ -+ /* acquire disk size */ -+ dsectors = bdev_nr_sectors(bdev); -+ dsize = dsectors << SECTOR_SHIFT; -+ -+ /* abort if FIT structure is larger than disk or partition size */ -+ if (size >= dsize) { -+ ret = -EFBIG; -+ folio_put(folio); -+ goto out_blkdev; -+ } -+ -+ fit = kmalloc(size, GFP_KERNEL); -+ if (!fit) { -+ ret = -ENOMEM; -+ folio_put(folio); -+ goto out_blkdev; -+ } -+ -+ bytes_left = size; -+ fit_c = fit; -+ while (bytes_left > 0) { -+ bytes_to_copy = min_t(size_t, bytes_left, -+ folio_size(folio) - offset_in_folio(folio, 0)); -+ memcpy(fit_c, pre_fit, bytes_to_copy); -+ fit_c += bytes_to_copy; -+ bytes_left -= bytes_to_copy; -+ if (bytes_left) { -+ folio_put(folio); -+ folio = read_mapping_folio(mapping, f_index++, NULL); -+ if (IS_ERR(folio)) { -+ ret = PTR_ERR(folio); -+ goto out_blkdev; -+ }; -+ pre_fit = folio_address(folio) + offset_in_folio(folio, 0); -+ } -+ } -+ folio_put(folio); -+ -+ /* set boot config node name U-Boot may have added to the device tree */ -+ np = of_find_node_by_path("/chosen"); -+ if (np) { -+ bootconf_c = of_get_property(np, "u-boot,bootconf", &bootconf_len); -+ if (bootconf_c && bootconf_len) -+ bootconf = kmemdup_nul(bootconf_c, bootconf_len, GFP_KERNEL); -+ } -+ -+ if (bootconf) { -+ bootconf_term = strchr(bootconf, '#'); -+ if (bootconf_term) -+ *bootconf_term = '\0'; -+ } -+ -+ /* find configuration path in uImage.FIT */ -+ config = fdt_path_offset(fit, FIT_CONFS_PATH); -+ if (config < 0) { -+ pr_err("FIT: Cannot find %s node: %d\n", -+ FIT_CONFS_PATH, config); -+ ret = -ENOENT; -+ goto out_bootconf; -+ } -+ -+ /* get default configuration node name */ -+ config_default = -+ fdt_getprop(fit, config, FIT_DEFAULT_PROP, &config_default_len); -+ -+ /* make sure we got either default or selected boot config node name */ -+ if (!config_default && !bootconf) { -+ pr_err("FIT: Cannot find default configuration\n"); -+ ret = -ENOENT; -+ goto out_bootconf; -+ } -+ -+ /* find selected boot config node, fallback on default config node */ -+ node = fdt_subnode_offset(fit, config, bootconf ?: config_default); -+ if (node < 0) { -+ pr_err("FIT: Cannot find %s node: %d\n", -+ bootconf ?: config_default, node); -+ ret = -ENOENT; -+ goto out_bootconf; -+ } -+ -+ pr_info("FIT: Detected U-Boot %s\n", ubootver); -+ -+ /* get selected configuration data */ -+ config_description = -+ fdt_getprop(fit, node, FIT_DESC_PROP, &config_description_len); -+ config_loadables = fdt_getprop(fit, node, FIT_LOADABLE_PROP, -+ &config_loadables_len); -+ -+ pr_info("FIT: %s configuration: \"%.*s\"%s%.*s%s\n", -+ bootconf ? "Selected" : "Default", -+ bootconf ? bootconf_len : config_default_len, -+ bootconf ?: config_default, -+ config_description ? " (" : "", -+ config_description ? config_description_len : 0, -+ config_description ?: "", -+ config_description ? ")" : ""); -+ -+ if (!config_loadables || !config_loadables_len) { -+ pr_err("FIT: No loadables configured in \"%s\"\n", -+ bootconf ?: config_default); -+ ret = -ENOENT; -+ goto out_bootconf; -+ } -+ -+ /* get images path in uImage.FIT */ -+ images = fdt_path_offset(fit, FIT_IMAGES_PATH); -+ if (images < 0) { -+ pr_err("FIT: Cannot find %s node: %d\n", FIT_IMAGES_PATH, images); -+ ret = -EINVAL; -+ goto out_bootconf; -+ } -+ -+ /* iterate over images in uImage.FIT */ -+ fdt_for_each_subnode(node, fit, images) { -+ image_name = fdt_get_name(fit, node, &image_name_len); -+ image_type = fdt_getprop(fit, node, FIT_TYPE_PROP, &image_type_len); -+ image_offset_be = fdt_getprop(fit, node, FIT_DATA_OFFSET_PROP, NULL); -+ image_pos_be = fdt_getprop(fit, node, FIT_DATA_POSITION_PROP, NULL); -+ image_len_be = fdt_getprop(fit, node, FIT_DATA_SIZE_PROP, NULL); -+ -+ if (!image_name || !image_type || !image_len_be || -+ !image_name_len || !image_type_len) -+ continue; -+ -+ image_len = be32_to_cpu(*image_len_be); -+ if (!image_len) -+ continue; -+ -+ if (image_offset_be) -+ image_pos = be32_to_cpu(*image_offset_be) + size; -+ else if (image_pos_be) -+ image_pos = be32_to_cpu(*image_pos_be); -+ else -+ continue; -+ -+ image_description = fdt_getprop(fit, node, FIT_DESC_PROP, -+ &image_description_len); -+ -+ pr_info("FIT: %16s sub-image 0x%08x..0x%08x \"%.*s\"%s%.*s%s\n", -+ image_type, image_pos, image_pos + image_len - 1, -+ image_name_len, image_name, image_description ? " (" : "", -+ image_description ? image_description_len : 0, -+ image_description ?: "", image_description ? ") " : ""); -+ -+ /* only 'filesystem' images should be mapped as partitions */ -+ if (strncmp(image_type, FIT_FILESYSTEM_PROP, image_type_len)) -+ continue; -+ -+ /* check if sub-image is part of configured loadables */ -+ found = false; -+ loadable = config_loadables; -+ loadables_rem_len = config_loadables_len; -+ for (loadcnt = 0; loadables_rem_len > 1 && -+ loadcnt < MAX_FIT_LOADABLES; ++loadcnt) { -+ loadable_len = -+ strnlen(loadable, loadables_rem_len - 1) + 1; -+ loadables_rem_len -= loadable_len; -+ if (!strncmp(image_name, loadable, loadable_len)) { -+ found = true; -+ break; -+ } -+ loadable += loadable_len; -+ } -+ if (!found) -+ continue; -+ -+ if (image_pos % (1 << PAGE_SHIFT)) { -+ dev_err(dev, "FIT: image %.*s start not aligned to page boundaries, skipping\n", -+ image_name_len, image_name); -+ continue; -+ } -+ -+ if (image_len % (1 << PAGE_SHIFT)) { -+ dev_err(dev, "FIT: sub-image %.*s end not aligned to page boundaries, skipping\n", -+ image_name_len, image_name); -+ continue; -+ } -+ -+ start_sect = image_pos >> SECTOR_SHIFT; -+ nr_sects = image_len >> SECTOR_SHIFT; -+ imgmaxsect = max_t(sector_t, imgmaxsect, start_sect + nr_sects); -+ -+ if (start_sect + nr_sects > dsectors) { -+ dev_err(dev, "FIT: sub-image %.*s disk access beyond EOD\n", -+ image_name_len, image_name); -+ continue; -+ } -+ -+ if (!slot) { -+ ret = sysfs_create_link_nowarn(&pdev->dev.kobj, bdev_kobj(bdev), "lower_dev"); -+ if (ret && ret != -EEXIST) -+ goto out_bootconf; -+ -+ ret = 0; -+ } -+ -+ add_fit_subimage_device(bdev_file, slot++, start_sect, nr_sects, true); -+ } -+ -+ if (!slot) -+ goto out_bootconf; -+ -+ dev_info(dev, "mapped %u uImage.FIT filesystem sub-image%s as /dev/fit%s%u%s\n", -+ slot, (slot > 1)?"s":"", (slot > 1)?"[0...":"", slot - 1, -+ (slot > 1)?"]":""); -+ -+ /* in case uImage.FIT is stored in a partition, map the remaining space */ -+ if (!bdev_read_only(bdev) && bdev_is_partition(bdev) && -+ (imgmaxsect + MIN_FREE_SECT) < dsectors) { -+ add_fit_subimage_device(bdev_file, slot++, imgmaxsect, -+ dsectors - imgmaxsect, false); -+ dev_info(dev, "mapped remaining space as /dev/fitrw\n"); -+ } -+ -+out_bootconf: -+ kfree(bootconf); -+ kfree(fit); -+out_blkdev: -+ if (!slot) -+ fput(bdev_file); -+ -+ return ret; -+} -+ -+static int fitblk_match_of_node(struct device *dev, const void *np) -+{ -+ int ret; -+ -+ ret = device_match_of_node(dev, np); -+ if (ret) -+ return ret; -+ -+ /* -+ * To match ubiblock and mtdblock devices by their parent ubi -+ * or mtd device, also consider block device parent -+ */ -+ if (!dev->parent) -+ return 0; -+ -+ return device_match_of_node(dev->parent, np); -+} -+ -+static int fitblk_probe(struct platform_device *pdev) -+{ -+ struct device *dev; -+ -+ dev = class_find_device(&block_class, NULL, rootdisk, fitblk_match_of_node); -+ if (!dev) -+ return -EPROBE_DEFER; -+ -+ return parse_fit_on_dev(dev); -+} -+ -+static struct platform_driver fitblk_driver = { -+ .probe = fitblk_probe, -+ .driver = { -+ .name = "fitblk", -+ }, -+}; -+ -+static int __init fitblk_init(void) -+{ -+ /* detect U-Boot firmware */ -+ ubootver = of_get_property(of_chosen, "u-boot,version", NULL); -+ if (!ubootver) -+ return 0; -+ -+ /* parse 'rootdisk' property phandle */ -+ rootdisk = of_parse_phandle(of_chosen, "rootdisk", 0); -+ if (!rootdisk) -+ return 0; -+ -+ if (platform_driver_register(&fitblk_driver)) -+ return -ENODEV; -+ -+ refcount_set(&num_devs, 1); -+ pdev = platform_device_register_simple("fitblk", -1, NULL, 0); -+ if (IS_ERR(pdev)) -+ return PTR_ERR(pdev); -+ -+ return 0; -+} -+device_initcall(fitblk_init); -diff --git a/include/uapi/linux/fitblk.h b/include/uapi/linux/fitblk.h -new file mode 100644 -index 000000000000..a8f80a5e990a ---- /dev/null -+++ b/include/uapi/linux/fitblk.h -@@ -0,0 +1,10 @@ -+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ -+#ifndef _UAPI_LINUX_FITBLK_H -+#define _UAPI_LINUX_FITBLK_H -+ -+/* -+ * IOCTL commands --- we will commandeer 0x46 ('F') -+ */ -+#define FITBLK_RELEASE 0x4600 -+ -+#endif /* _UAPI_LINUX_FITBLK_H */ --- -2.51.0 - - -From fa659019e6589fd4399c41dc7e4d4543fc7a54b3 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 12 Jun 2023 03:58:42 +0100 -Subject: [PATCH 251/517] init: bypass device lookup for /dev/fit* rootfs - -Allow 'rootwait' as /dev/fit* can show up late if the underlaying -device is probed late. - -Signed-off-by: Daniel Golle ---- - init/do_mounts.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/init/do_mounts.c b/init/do_mounts.c -index cbb4237700aa..113708a9eb3d 100644 ---- a/init/do_mounts.c -+++ b/init/do_mounts.c -@@ -465,7 +465,8 @@ static dev_t __init parse_root_device(char *root_device_name) - int error; - dev_t dev; - -- if (!strncmp(root_device_name, "mtd", 3) || -+ if (!strncmp(root_device_name, "fit", 3) || -+ !strncmp(root_device_name, "mtd", 3) || - !strncmp(root_device_name, "ubi", 3)) - return Root_Generic; - if (strcmp(root_device_name, "/dev/nfs") == 0) --- -2.51.0 - - -From 43633b0334e99dc60bb38af2f75632f17506046d Mon Sep 17 00:00:00 2001 -From: "Alexandros C. Couloumbis" -Date: Mon, 3 Nov 2025 15:49:52 +0100 -Subject: [PATCH 252/517] fs: add jffs2/lzma support (not activated by default - yet) - -lede-commit: c2c88d315fa0e881f8b19da07b62859b915b11b2 -Signed-off-by: Alexandros C. Couloumbis ---- - fs/jffs2/Kconfig | 9 + - fs/jffs2/Makefile | 3 + - fs/jffs2/compr.c | 6 + - fs/jffs2/compr.h | 13 +- - fs/jffs2/compr_lzma.c | 128 ++ - fs/jffs2/super.c | 33 +- - include/linux/lzma.h | 62 + - include/linux/lzma/LzFind.h | 115 ++ - include/linux/lzma/LzHash.h | 54 + - include/linux/lzma/LzmaDec.h | 231 ++++ - include/linux/lzma/LzmaEnc.h | 80 ++ - include/linux/lzma/Types.h | 226 ++++ - include/uapi/linux/jffs2.h | 1 + - lib/Kconfig | 6 + - lib/Makefile | 12 + - lib/lzma/LzFind.c | 761 ++++++++++++ - lib/lzma/LzmaDec.c | 999 +++++++++++++++ - lib/lzma/LzmaEnc.c | 2271 ++++++++++++++++++++++++++++++++++ - lib/lzma/Makefile | 7 + - 19 files changed, 5011 insertions(+), 6 deletions(-) - create mode 100644 fs/jffs2/compr_lzma.c - create mode 100644 include/linux/lzma.h - create mode 100644 include/linux/lzma/LzFind.h - create mode 100644 include/linux/lzma/LzHash.h - create mode 100644 include/linux/lzma/LzmaDec.h - create mode 100644 include/linux/lzma/LzmaEnc.h - create mode 100644 include/linux/lzma/Types.h - create mode 100644 lib/lzma/LzFind.c - create mode 100644 lib/lzma/LzmaDec.c - create mode 100644 lib/lzma/LzmaEnc.c - create mode 100644 lib/lzma/Makefile - -diff --git a/fs/jffs2/Kconfig b/fs/jffs2/Kconfig -index 560187d61562..9c7b1df2206d 100644 ---- a/fs/jffs2/Kconfig -+++ b/fs/jffs2/Kconfig -@@ -136,6 +136,15 @@ config JFFS2_LZO - This feature was added in July, 2007. Say 'N' if you need - compatibility with older bootloaders or kernels. - -+config JFFS2_LZMA -+ bool "JFFS2 LZMA compression support" if JFFS2_COMPRESSION_OPTIONS -+ select LZMA_COMPRESS -+ select LZMA_DECOMPRESS -+ depends on JFFS2_FS -+ default n -+ help -+ JFFS2 wrapper to the LZMA C SDK -+ - config JFFS2_RTIME - bool "JFFS2 RTIME compression support" if JFFS2_COMPRESSION_OPTIONS - depends on JFFS2_FS -diff --git a/fs/jffs2/Makefile b/fs/jffs2/Makefile -index 5294969d5bf9..11a89b96e5f3 100644 ---- a/fs/jffs2/Makefile -+++ b/fs/jffs2/Makefile -@@ -19,4 +19,7 @@ jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rubin.o - jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o - jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o - jffs2-$(CONFIG_JFFS2_LZO) += compr_lzo.o -+jffs2-$(CONFIG_JFFS2_LZMA) += compr_lzma.o - jffs2-$(CONFIG_JFFS2_SUMMARY) += summary.o -+ -+CFLAGS_compr_lzma.o += -Iinclude/linux -Ilib/lzma -diff --git a/fs/jffs2/compr.c b/fs/jffs2/compr.c -index 764f19dec3f0..6b5e82b3f6c6 100644 ---- a/fs/jffs2/compr.c -+++ b/fs/jffs2/compr.c -@@ -381,6 +381,9 @@ int __init jffs2_compressors_init(void) - ret = jffs2_lzo_init(); - if (ret) - goto exit_dynrubin; -+ ret = jffs2_lzma_init(); -+ if (ret) -+ goto exit_lzo; - - - /* Setting default compression mode */ -@@ -402,6 +405,8 @@ int __init jffs2_compressors_init(void) - #endif - return 0; - -+exit_lzo: -+ jffs2_lzo_exit(); - exit_dynrubin: - jffs2_dynrubin_exit(); - exit_runinmips: -@@ -417,6 +422,7 @@ int __init jffs2_compressors_init(void) - int jffs2_compressors_exit(void) - { - /* Unregistering compressors */ -+ jffs2_lzma_exit(); - jffs2_lzo_exit(); - jffs2_dynrubin_exit(); - jffs2_rubinmips_exit(); -diff --git a/fs/jffs2/compr.h b/fs/jffs2/compr.h -index 3716b6b7924c..00689727a1c5 100644 ---- a/fs/jffs2/compr.h -+++ b/fs/jffs2/compr.h -@@ -29,9 +29,9 @@ - #define JFFS2_DYNRUBIN_PRIORITY 20 - #define JFFS2_LZARI_PRIORITY 30 - #define JFFS2_RTIME_PRIORITY 50 --#define JFFS2_ZLIB_PRIORITY 60 --#define JFFS2_LZO_PRIORITY 80 -- -+#define JFFS2_LZMA_PRIORITY 70 -+#define JFFS2_ZLIB_PRIORITY 80 -+#define JFFS2_LZO_PRIORITY 90 - - #define JFFS2_RUBINMIPS_DISABLED /* RUBINs will be used only */ - #define JFFS2_DYNRUBIN_DISABLED /* for decompression */ -@@ -115,5 +115,12 @@ extern void jffs2_lzo_exit(void); - static inline int jffs2_lzo_init(void) { return 0; } - static inline void jffs2_lzo_exit(void) {} - #endif -+#ifdef CONFIG_JFFS2_LZMA -+extern int jffs2_lzma_init(void); -+extern void jffs2_lzma_exit(void); -+#else -+static inline int jffs2_lzma_init(void) { return 0; } -+static inline void jffs2_lzma_exit(void) {} -+#endif - - #endif /* __JFFS2_COMPR_H__ */ -diff --git a/fs/jffs2/compr_lzma.c b/fs/jffs2/compr_lzma.c -new file mode 100644 -index 000000000000..ec0d9a6020de ---- /dev/null -+++ b/fs/jffs2/compr_lzma.c -@@ -0,0 +1,128 @@ -+/* -+ * JFFS2 -- Journalling Flash File System, Version 2. -+ * -+ * For licensing information, see the file 'LICENCE' in this directory. -+ * -+ * JFFS2 wrapper to the LZMA C SDK -+ * -+ */ -+ -+#include -+#include "compr.h" -+ -+#ifdef __KERNEL__ -+ static DEFINE_MUTEX(deflate_mutex); -+#endif -+ -+CLzmaEncHandle *p; -+Byte propsEncoded[LZMA_PROPS_SIZE]; -+SizeT propsSize = sizeof(propsEncoded); -+ -+STATIC void lzma_free_workspace(void) -+{ -+ LzmaEnc_Destroy(p, &lzma_alloc, &lzma_alloc); -+} -+ -+STATIC int INIT lzma_alloc_workspace(CLzmaEncProps *props) -+{ -+ if ((p = (CLzmaEncHandle *)LzmaEnc_Create(&lzma_alloc)) == NULL) -+ { -+ PRINT_ERROR("Failed to allocate lzma deflate workspace\n"); -+ return -ENOMEM; -+ } -+ -+ if (LzmaEnc_SetProps(p, props) != SZ_OK) -+ { -+ lzma_free_workspace(); -+ return -1; -+ } -+ -+ if (LzmaEnc_WriteProperties(p, propsEncoded, &propsSize) != SZ_OK) -+ { -+ lzma_free_workspace(); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+STATIC int jffs2_lzma_compress(unsigned char *data_in, unsigned char *cpage_out, -+ uint32_t *sourcelen, uint32_t *dstlen) -+{ -+ SizeT compress_size = (SizeT)(*dstlen); -+ int ret; -+ -+ #ifdef __KERNEL__ -+ mutex_lock(&deflate_mutex); -+ #endif -+ -+ ret = LzmaEnc_MemEncode(p, cpage_out, &compress_size, data_in, *sourcelen, -+ 0, NULL, &lzma_alloc, &lzma_alloc); -+ -+ #ifdef __KERNEL__ -+ mutex_unlock(&deflate_mutex); -+ #endif -+ -+ if (ret != SZ_OK) -+ return -1; -+ -+ *dstlen = (uint32_t)compress_size; -+ -+ return 0; -+} -+ -+STATIC int jffs2_lzma_decompress(unsigned char *data_in, unsigned char *cpage_out, -+ uint32_t srclen, uint32_t destlen) -+{ -+ int ret; -+ SizeT dl = (SizeT)destlen; -+ SizeT sl = (SizeT)srclen; -+ ELzmaStatus status; -+ -+ ret = LzmaDecode(cpage_out, &dl, data_in, &sl, propsEncoded, -+ propsSize, LZMA_FINISH_ANY, &status, &lzma_alloc); -+ -+ if (ret != SZ_OK || status == LZMA_STATUS_NOT_FINISHED || dl != (SizeT)destlen) -+ return -1; -+ -+ return 0; -+} -+ -+static struct jffs2_compressor jffs2_lzma_comp = { -+ .priority = JFFS2_LZMA_PRIORITY, -+ .name = "lzma", -+ .compr = JFFS2_COMPR_LZMA, -+ .compress = &jffs2_lzma_compress, -+ .decompress = &jffs2_lzma_decompress, -+ .disabled = 0, -+}; -+ -+int INIT jffs2_lzma_init(void) -+{ -+ int ret; -+ CLzmaEncProps props; -+ LzmaEncProps_Init(&props); -+ -+ props.dictSize = LZMA_BEST_DICT(0x2000); -+ props.level = LZMA_BEST_LEVEL; -+ props.lc = LZMA_BEST_LC; -+ props.lp = LZMA_BEST_LP; -+ props.pb = LZMA_BEST_PB; -+ props.fb = LZMA_BEST_FB; -+ -+ ret = lzma_alloc_workspace(&props); -+ if (ret < 0) -+ return ret; -+ -+ ret = jffs2_register_compressor(&jffs2_lzma_comp); -+ if (ret) -+ lzma_free_workspace(); -+ -+ return ret; -+} -+ -+void jffs2_lzma_exit(void) -+{ -+ jffs2_unregister_compressor(&jffs2_lzma_comp); -+ lzma_free_workspace(); -+} -diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c -index 4545f885c41e..ef4b26ff04c6 100644 ---- a/fs/jffs2/super.c -+++ b/fs/jffs2/super.c -@@ -376,14 +376,41 @@ static int __init init_jffs2_fs(void) - BUILD_BUG_ON(sizeof(struct jffs2_raw_inode) != 68); - BUILD_BUG_ON(sizeof(struct jffs2_raw_summary) != 32); - -- pr_info("version 2.2." -+ pr_info("version 2.2" - #ifdef CONFIG_JFFS2_FS_WRITEBUFFER - " (NAND)" - #endif - #ifdef CONFIG_JFFS2_SUMMARY -- " (SUMMARY) " -+ " (SUMMARY)" - #endif -- " © 2001-2006 Red Hat, Inc.\n"); -+#ifdef CONFIG_JFFS2_ZLIB -+ " (ZLIB)" -+#endif -+#ifdef CONFIG_JFFS2_LZO -+ " (LZO)" -+#endif -+#ifdef CONFIG_JFFS2_LZMA -+ " (LZMA)" -+#endif -+#ifdef CONFIG_JFFS2_RTIME -+ " (RTIME)" -+#endif -+#ifdef CONFIG_JFFS2_RUBIN -+ " (RUBIN)" -+#endif -+#ifdef CONFIG_JFFS2_CMODE_NONE -+ " (CMODE_NONE)" -+#endif -+#ifdef CONFIG_JFFS2_CMODE_PRIORITY -+ " (CMODE_PRIORITY)" -+#endif -+#ifdef CONFIG_JFFS2_CMODE_SIZE -+ " (CMODE_SIZE)" -+#endif -+#ifdef CONFIG_JFFS2_CMODE_FAVOURLZO -+ " (CMODE_FAVOURLZO)" -+#endif -+ " (c) 2001-2006 Red Hat, Inc.\n"); - - jffs2_inode_cachep = kmem_cache_create("jffs2_i", - sizeof(struct jffs2_inode_info), -diff --git a/include/linux/lzma.h b/include/linux/lzma.h -new file mode 100644 -index 000000000000..492ad6c4405c ---- /dev/null -+++ b/include/linux/lzma.h -@@ -0,0 +1,62 @@ -+#ifndef __LZMA_H__ -+#define __LZMA_H__ -+ -+#ifdef __KERNEL__ -+ #include -+ #include -+ #include -+ #include -+ #include -+ #define LZMA_MALLOC vmalloc -+ #define LZMA_FREE vfree -+ #define PRINT_ERROR(msg) printk(KERN_WARNING #msg) -+ #define INIT __init -+ #define STATIC static -+#else -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #ifndef PAGE_SIZE -+ extern int page_size; -+ #define PAGE_SIZE page_size -+ #endif -+ #define LZMA_MALLOC malloc -+ #define LZMA_FREE free -+ #define PRINT_ERROR(msg) fprintf(stderr, msg) -+ #define INIT -+ #define STATIC -+#endif -+ -+#include "lzma/LzmaDec.h" -+#include "lzma/LzmaEnc.h" -+ -+#define LZMA_BEST_LEVEL (9) -+#define LZMA_BEST_LC (0) -+#define LZMA_BEST_LP (0) -+#define LZMA_BEST_PB (0) -+#define LZMA_BEST_FB (273) -+ -+#define LZMA_BEST_DICT(n) (((int)((n) / 2)) * 2) -+ -+static void *p_lzma_malloc(void *p, size_t size) -+{ -+ if (size == 0) -+ return NULL; -+ -+ return LZMA_MALLOC(size); -+} -+ -+static void p_lzma_free(void *p, void *address) -+{ -+ if (address != NULL) -+ LZMA_FREE(address); -+} -+ -+static ISzAlloc lzma_alloc = { .Alloc = p_lzma_malloc, .Free = p_lzma_free }; -+ -+#endif -diff --git a/include/linux/lzma/LzFind.h b/include/linux/lzma/LzFind.h -new file mode 100644 -index 000000000000..010c4b92ba33 ---- /dev/null -+++ b/include/linux/lzma/LzFind.h -@@ -0,0 +1,115 @@ -+/* LzFind.h -- Match finder for LZ algorithms -+2009-04-22 : Igor Pavlov : Public domain */ -+ -+#ifndef __LZ_FIND_H -+#define __LZ_FIND_H -+ -+#include "Types.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+typedef UInt32 CLzRef; -+ -+typedef struct _CMatchFinder -+{ -+ Byte *buffer; -+ UInt32 pos; -+ UInt32 posLimit; -+ UInt32 streamPos; -+ UInt32 lenLimit; -+ -+ UInt32 cyclicBufferPos; -+ UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */ -+ -+ UInt32 matchMaxLen; -+ CLzRef *hash; -+ CLzRef *son; -+ UInt32 hashMask; -+ UInt32 cutValue; -+ -+ Byte *bufferBase; -+ ISeqInStream *stream; -+ int streamEndWasReached; -+ -+ UInt32 blockSize; -+ UInt32 keepSizeBefore; -+ UInt32 keepSizeAfter; -+ -+ UInt32 numHashBytes; -+ int directInput; -+ size_t directInputRem; -+ int btMode; -+ int bigHash; -+ UInt32 historySize; -+ UInt32 fixedHashSize; -+ UInt32 hashSizeSum; -+ UInt32 numSons; -+ SRes result; -+ UInt32 crc[256]; -+} CMatchFinder; -+ -+#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer) -+#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)]) -+ -+#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos) -+ -+int MatchFinder_NeedMove(CMatchFinder *p); -+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); -+void MatchFinder_MoveBlock(CMatchFinder *p); -+void MatchFinder_ReadIfRequired(CMatchFinder *p); -+ -+void MatchFinder_Construct(CMatchFinder *p); -+ -+/* Conditions: -+ historySize <= 3 GB -+ keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB -+*/ -+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, -+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, -+ ISzAlloc *alloc); -+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); -+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems); -+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); -+ -+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son, -+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, -+ UInt32 *distances, UInt32 maxLen); -+ -+/* -+Conditions: -+ Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func. -+ Mf_GetPointerToCurrentPos_Func's result must be used only before any other function -+*/ -+ -+typedef void (*Mf_Init_Func)(void *object); -+typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index); -+typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object); -+typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object); -+typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances); -+typedef void (*Mf_Skip_Func)(void *object, UInt32); -+ -+typedef struct _IMatchFinder -+{ -+ Mf_Init_Func Init; -+ Mf_GetIndexByte_Func GetIndexByte; -+ Mf_GetNumAvailableBytes_Func GetNumAvailableBytes; -+ Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos; -+ Mf_GetMatches_Func GetMatches; -+ Mf_Skip_Func Skip; -+} IMatchFinder; -+ -+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); -+ -+void MatchFinder_Init(CMatchFinder *p); -+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); -+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); -+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); -+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif -diff --git a/include/linux/lzma/LzHash.h b/include/linux/lzma/LzHash.h -new file mode 100644 -index 000000000000..f3e89966cc70 ---- /dev/null -+++ b/include/linux/lzma/LzHash.h -@@ -0,0 +1,54 @@ -+/* LzHash.h -- HASH functions for LZ algorithms -+2009-02-07 : Igor Pavlov : Public domain */ -+ -+#ifndef __LZ_HASH_H -+#define __LZ_HASH_H -+ -+#define kHash2Size (1 << 10) -+#define kHash3Size (1 << 16) -+#define kHash4Size (1 << 20) -+ -+#define kFix3HashSize (kHash2Size) -+#define kFix4HashSize (kHash2Size + kHash3Size) -+#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size) -+ -+#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8); -+ -+#define HASH3_CALC { \ -+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -+ hash2Value = temp & (kHash2Size - 1); \ -+ hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; } -+ -+#define HASH4_CALC { \ -+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -+ hash2Value = temp & (kHash2Size - 1); \ -+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ -+ hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; } -+ -+#define HASH5_CALC { \ -+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -+ hash2Value = temp & (kHash2Size - 1); \ -+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ -+ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \ -+ hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \ -+ hash4Value &= (kHash4Size - 1); } -+ -+/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */ -+#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF; -+ -+ -+#define MT_HASH2_CALC \ -+ hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1); -+ -+#define MT_HASH3_CALC { \ -+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -+ hash2Value = temp & (kHash2Size - 1); \ -+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); } -+ -+#define MT_HASH4_CALC { \ -+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -+ hash2Value = temp & (kHash2Size - 1); \ -+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ -+ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); } -+ -+#endif -diff --git a/include/linux/lzma/LzmaDec.h b/include/linux/lzma/LzmaDec.h -new file mode 100644 -index 000000000000..7927acd0d4eb ---- /dev/null -+++ b/include/linux/lzma/LzmaDec.h -@@ -0,0 +1,231 @@ -+/* LzmaDec.h -- LZMA Decoder -+2009-02-07 : Igor Pavlov : Public domain */ -+ -+#ifndef __LZMA_DEC_H -+#define __LZMA_DEC_H -+ -+#include "Types.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+/* #define _LZMA_PROB32 */ -+/* _LZMA_PROB32 can increase the speed on some CPUs, -+ but memory usage for CLzmaDec::probs will be doubled in that case */ -+ -+#ifdef _LZMA_PROB32 -+#define CLzmaProb UInt32 -+#else -+#define CLzmaProb UInt16 -+#endif -+ -+ -+/* ---------- LZMA Properties ---------- */ -+ -+#define LZMA_PROPS_SIZE 5 -+ -+typedef struct _CLzmaProps -+{ -+ unsigned lc, lp, pb; -+ UInt32 dicSize; -+} CLzmaProps; -+ -+/* LzmaProps_Decode - decodes properties -+Returns: -+ SZ_OK -+ SZ_ERROR_UNSUPPORTED - Unsupported properties -+*/ -+ -+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); -+ -+ -+/* ---------- LZMA Decoder state ---------- */ -+ -+/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. -+ Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ -+ -+#define LZMA_REQUIRED_INPUT_MAX 20 -+ -+typedef struct -+{ -+ CLzmaProps prop; -+ CLzmaProb *probs; -+ Byte *dic; -+ const Byte *buf; -+ UInt32 range, code; -+ SizeT dicPos; -+ SizeT dicBufSize; -+ UInt32 processedPos; -+ UInt32 checkDicSize; -+ unsigned state; -+ UInt32 reps[4]; -+ unsigned remainLen; -+ int needFlush; -+ int needInitState; -+ UInt32 numProbs; -+ unsigned tempBufSize; -+ Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; -+} CLzmaDec; -+ -+#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } -+ -+void LzmaDec_Init(CLzmaDec *p); -+ -+/* There are two types of LZMA streams: -+ 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. -+ 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ -+ -+typedef enum -+{ -+ LZMA_FINISH_ANY, /* finish at any point */ -+ LZMA_FINISH_END /* block must be finished at the end */ -+} ELzmaFinishMode; -+ -+/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! -+ -+ You must use LZMA_FINISH_END, when you know that current output buffer -+ covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. -+ -+ If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, -+ and output value of destLen will be less than output buffer size limit. -+ You can check status result also. -+ -+ You can use multiple checks to test data integrity after full decompression: -+ 1) Check Result and "status" variable. -+ 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. -+ 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. -+ You must use correct finish mode in that case. */ -+ -+typedef enum -+{ -+ LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ -+ LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ -+ LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ -+ LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ -+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */ -+} ELzmaStatus; -+ -+/* ELzmaStatus is used only as output value for function call */ -+ -+ -+/* ---------- Interfaces ---------- */ -+ -+/* There are 3 levels of interfaces: -+ 1) Dictionary Interface -+ 2) Buffer Interface -+ 3) One Call Interface -+ You can select any of these interfaces, but don't mix functions from different -+ groups for same object. */ -+ -+ -+/* There are two variants to allocate state for Dictionary Interface: -+ 1) LzmaDec_Allocate / LzmaDec_Free -+ 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs -+ You can use variant 2, if you set dictionary buffer manually. -+ For Buffer Interface you must always use variant 1. -+ -+LzmaDec_Allocate* can return: -+ SZ_OK -+ SZ_ERROR_MEM - Memory allocation error -+ SZ_ERROR_UNSUPPORTED - Unsupported properties -+*/ -+ -+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); -+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); -+ -+SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); -+void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); -+ -+/* ---------- Dictionary Interface ---------- */ -+ -+/* You can use it, if you want to eliminate the overhead for data copying from -+ dictionary to some other external buffer. -+ You must work with CLzmaDec variables directly in this interface. -+ -+ STEPS: -+ LzmaDec_Constr() -+ LzmaDec_Allocate() -+ for (each new stream) -+ { -+ LzmaDec_Init() -+ while (it needs more decompression) -+ { -+ LzmaDec_DecodeToDic() -+ use data from CLzmaDec::dic and update CLzmaDec::dicPos -+ } -+ } -+ LzmaDec_Free() -+*/ -+ -+/* LzmaDec_DecodeToDic -+ -+ The decoding to internal dictionary buffer (CLzmaDec::dic). -+ You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! -+ -+finishMode: -+ It has meaning only if the decoding reaches output limit (dicLimit). -+ LZMA_FINISH_ANY - Decode just dicLimit bytes. -+ LZMA_FINISH_END - Stream must be finished after dicLimit. -+ -+Returns: -+ SZ_OK -+ status: -+ LZMA_STATUS_FINISHED_WITH_MARK -+ LZMA_STATUS_NOT_FINISHED -+ LZMA_STATUS_NEEDS_MORE_INPUT -+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK -+ SZ_ERROR_DATA - Data error -+*/ -+ -+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, -+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); -+ -+ -+/* ---------- Buffer Interface ---------- */ -+ -+/* It's zlib-like interface. -+ See LzmaDec_DecodeToDic description for information about STEPS and return results, -+ but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need -+ to work with CLzmaDec variables manually. -+ -+finishMode: -+ It has meaning only if the decoding reaches output limit (*destLen). -+ LZMA_FINISH_ANY - Decode just destLen bytes. -+ LZMA_FINISH_END - Stream must be finished after (*destLen). -+*/ -+ -+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, -+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); -+ -+ -+/* ---------- One Call Interface ---------- */ -+ -+/* LzmaDecode -+ -+finishMode: -+ It has meaning only if the decoding reaches output limit (*destLen). -+ LZMA_FINISH_ANY - Decode just destLen bytes. -+ LZMA_FINISH_END - Stream must be finished after (*destLen). -+ -+Returns: -+ SZ_OK -+ status: -+ LZMA_STATUS_FINISHED_WITH_MARK -+ LZMA_STATUS_NOT_FINISHED -+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK -+ SZ_ERROR_DATA - Data error -+ SZ_ERROR_MEM - Memory allocation error -+ SZ_ERROR_UNSUPPORTED - Unsupported properties -+ SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). -+*/ -+ -+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, -+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, -+ ELzmaStatus *status, ISzAlloc *alloc); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif -diff --git a/include/linux/lzma/LzmaEnc.h b/include/linux/lzma/LzmaEnc.h -new file mode 100644 -index 000000000000..200d60eb83cd ---- /dev/null -+++ b/include/linux/lzma/LzmaEnc.h -@@ -0,0 +1,80 @@ -+/* LzmaEnc.h -- LZMA Encoder -+2009-02-07 : Igor Pavlov : Public domain */ -+ -+#ifndef __LZMA_ENC_H -+#define __LZMA_ENC_H -+ -+#include "Types.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#define LZMA_PROPS_SIZE 5 -+ -+typedef struct _CLzmaEncProps -+{ -+ int level; /* 0 <= level <= 9 */ -+ UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version -+ (1 << 12) <= dictSize <= (1 << 30) for 64-bit version -+ default = (1 << 24) */ -+ int lc; /* 0 <= lc <= 8, default = 3 */ -+ int lp; /* 0 <= lp <= 4, default = 0 */ -+ int pb; /* 0 <= pb <= 4, default = 2 */ -+ int algo; /* 0 - fast, 1 - normal, default = 1 */ -+ int fb; /* 5 <= fb <= 273, default = 32 */ -+ int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */ -+ int numHashBytes; /* 2, 3 or 4, default = 4 */ -+ UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */ -+ unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */ -+ int numThreads; /* 1 or 2, default = 2 */ -+} CLzmaEncProps; -+ -+void LzmaEncProps_Init(CLzmaEncProps *p); -+void LzmaEncProps_Normalize(CLzmaEncProps *p); -+UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2); -+ -+ -+/* ---------- CLzmaEncHandle Interface ---------- */ -+ -+/* LzmaEnc_* functions can return the following exit codes: -+Returns: -+ SZ_OK - OK -+ SZ_ERROR_MEM - Memory allocation error -+ SZ_ERROR_PARAM - Incorrect paramater in props -+ SZ_ERROR_WRITE - Write callback error. -+ SZ_ERROR_PROGRESS - some break from progress callback -+ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -+*/ -+ -+typedef void * CLzmaEncHandle; -+ -+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc); -+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig); -+SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); -+SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); -+SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, -+ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); -+SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -+ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); -+ -+/* ---------- One Call Interface ---------- */ -+ -+/* LzmaEncode -+Return code: -+ SZ_OK - OK -+ SZ_ERROR_MEM - Memory allocation error -+ SZ_ERROR_PARAM - Incorrect paramater -+ SZ_ERROR_OUTPUT_EOF - output buffer overflow -+ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -+*/ -+ -+SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -+ const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, -+ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif -diff --git a/include/linux/lzma/Types.h b/include/linux/lzma/Types.h -new file mode 100644 -index 000000000000..4751acde0722 ---- /dev/null -+++ b/include/linux/lzma/Types.h -@@ -0,0 +1,226 @@ -+/* Types.h -- Basic types -+2009-11-23 : Igor Pavlov : Public domain */ -+ -+#ifndef __7Z_TYPES_H -+#define __7Z_TYPES_H -+ -+#include -+ -+#ifdef _WIN32 -+#include -+#endif -+ -+#ifndef EXTERN_C_BEGIN -+#ifdef __cplusplus -+#define EXTERN_C_BEGIN extern "C" { -+#define EXTERN_C_END } -+#else -+#define EXTERN_C_BEGIN -+#define EXTERN_C_END -+#endif -+#endif -+ -+EXTERN_C_BEGIN -+ -+#define SZ_OK 0 -+ -+#define SZ_ERROR_DATA 1 -+#define SZ_ERROR_MEM 2 -+#define SZ_ERROR_CRC 3 -+#define SZ_ERROR_UNSUPPORTED 4 -+#define SZ_ERROR_PARAM 5 -+#define SZ_ERROR_INPUT_EOF 6 -+#define SZ_ERROR_OUTPUT_EOF 7 -+#define SZ_ERROR_READ 8 -+#define SZ_ERROR_WRITE 9 -+#define SZ_ERROR_PROGRESS 10 -+#define SZ_ERROR_FAIL 11 -+#define SZ_ERROR_THREAD 12 -+ -+#define SZ_ERROR_ARCHIVE 16 -+#define SZ_ERROR_NO_ARCHIVE 17 -+ -+typedef int SRes; -+ -+#ifdef _WIN32 -+typedef DWORD WRes; -+#else -+typedef int WRes; -+#endif -+ -+#ifndef RINOK -+#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } -+#endif -+ -+typedef unsigned char Byte; -+typedef short Int16; -+typedef unsigned short UInt16; -+ -+#ifdef _LZMA_UINT32_IS_ULONG -+typedef long Int32; -+typedef unsigned long UInt32; -+#else -+typedef int Int32; -+typedef unsigned int UInt32; -+#endif -+ -+#ifdef _SZ_NO_INT_64 -+ -+/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers. -+ NOTES: Some code will work incorrectly in that case! */ -+ -+typedef long Int64; -+typedef unsigned long UInt64; -+ -+#else -+ -+#if defined(_MSC_VER) || defined(__BORLANDC__) -+typedef __int64 Int64; -+typedef unsigned __int64 UInt64; -+#else -+typedef long long int Int64; -+typedef unsigned long long int UInt64; -+#endif -+ -+#endif -+ -+#ifdef _LZMA_NO_SYSTEM_SIZE_T -+typedef UInt32 SizeT; -+#else -+typedef size_t SizeT; -+#endif -+ -+typedef int Bool; -+#define True 1 -+#define False 0 -+ -+ -+#ifdef _WIN32 -+#define MY_STD_CALL __stdcall -+#else -+#define MY_STD_CALL -+#endif -+ -+#ifdef _MSC_VER -+ -+#if _MSC_VER >= 1300 -+#define MY_NO_INLINE __declspec(noinline) -+#else -+#define MY_NO_INLINE -+#endif -+ -+#define MY_CDECL __cdecl -+#define MY_FAST_CALL __fastcall -+ -+#else -+ -+#define MY_CDECL -+#define MY_FAST_CALL -+ -+#endif -+ -+ -+/* The following interfaces use first parameter as pointer to structure */ -+ -+typedef struct -+{ -+ SRes (*Read)(void *p, void *buf, size_t *size); -+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. -+ (output(*size) < input(*size)) is allowed */ -+} ISeqInStream; -+ -+/* it can return SZ_ERROR_INPUT_EOF */ -+SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size); -+SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType); -+SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf); -+ -+typedef struct -+{ -+ size_t (*Write)(void *p, const void *buf, size_t size); -+ /* Returns: result - the number of actually written bytes. -+ (result < size) means error */ -+} ISeqOutStream; -+ -+typedef enum -+{ -+ SZ_SEEK_SET = 0, -+ SZ_SEEK_CUR = 1, -+ SZ_SEEK_END = 2 -+} ESzSeek; -+ -+typedef struct -+{ -+ SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ -+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); -+} ISeekInStream; -+ -+typedef struct -+{ -+ SRes (*Look)(void *p, void **buf, size_t *size); -+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. -+ (output(*size) > input(*size)) is not allowed -+ (output(*size) < input(*size)) is allowed */ -+ SRes (*Skip)(void *p, size_t offset); -+ /* offset must be <= output(*size) of Look */ -+ -+ SRes (*Read)(void *p, void *buf, size_t *size); -+ /* reads directly (without buffer). It's same as ISeqInStream::Read */ -+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); -+} ILookInStream; -+ -+SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size); -+SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset); -+ -+/* reads via ILookInStream::Read */ -+SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType); -+SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size); -+ -+#define LookToRead_BUF_SIZE (1 << 14) -+ -+typedef struct -+{ -+ ILookInStream s; -+ ISeekInStream *realStream; -+ size_t pos; -+ size_t size; -+ Byte buf[LookToRead_BUF_SIZE]; -+} CLookToRead; -+ -+void LookToRead_CreateVTable(CLookToRead *p, int lookahead); -+void LookToRead_Init(CLookToRead *p); -+ -+typedef struct -+{ -+ ISeqInStream s; -+ ILookInStream *realStream; -+} CSecToLook; -+ -+void SecToLook_CreateVTable(CSecToLook *p); -+ -+typedef struct -+{ -+ ISeqInStream s; -+ ILookInStream *realStream; -+} CSecToRead; -+ -+void SecToRead_CreateVTable(CSecToRead *p); -+ -+typedef struct -+{ -+ SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); -+ /* Returns: result. (result != SZ_OK) means break. -+ Value (UInt64)(Int64)-1 for size means unknown value. */ -+} ICompressProgress; -+ -+typedef struct -+{ -+ void *(*Alloc)(void *p, size_t size); -+ void (*Free)(void *p, void *address); /* address can be 0 */ -+} ISzAlloc; -+ -+#define IAlloc_Alloc(p, size) (p)->Alloc((p), size) -+#define IAlloc_Free(p, a) (p)->Free((p), a) -+ -+EXTERN_C_END -+ -+#endif -diff --git a/include/uapi/linux/jffs2.h b/include/uapi/linux/jffs2.h -index 637ee4a793cf..11aeaa4e8520 100644 ---- a/include/uapi/linux/jffs2.h -+++ b/include/uapi/linux/jffs2.h -@@ -46,6 +46,7 @@ - #define JFFS2_COMPR_DYNRUBIN 0x05 - #define JFFS2_COMPR_ZLIB 0x06 - #define JFFS2_COMPR_LZO 0x07 -+#define JFFS2_COMPR_LZMA 0x08 - /* Compatibility flags. */ - #define JFFS2_COMPAT_MASK 0xc000 /* What do to if an unknown nodetype is found */ - #define JFFS2_NODE_ACCURATE 0x2000 -diff --git a/lib/Kconfig b/lib/Kconfig -index b893c9288c14..e9088bd10a6c 100644 ---- a/lib/Kconfig -+++ b/lib/Kconfig -@@ -353,6 +353,12 @@ config ZSTD_DECOMPRESS - - source "lib/xz/Kconfig" - -+config LZMA_COMPRESS -+ tristate -+ -+config LZMA_DECOMPRESS -+ tristate -+ - # - # These all provide a common interface (hence the apparent duplication with - # ZLIB_INFLATE; DECOMPRESS_GZIP is just a wrapper.) -diff --git a/lib/Makefile b/lib/Makefile -index fc878e716825..460d99a479be 100644 ---- a/lib/Makefile -+++ b/lib/Makefile -@@ -126,6 +126,16 @@ CFLAGS_kobject.o += -DDEBUG - CFLAGS_kobject_uevent.o += -DDEBUG - endif - -+ifdef CONFIG_JFFS2_ZLIB -+ CONFIG_ZLIB_INFLATE:=y -+ CONFIG_ZLIB_DEFLATE:=y -+endif -+ -+ifdef CONFIG_JFFS2_LZMA -+ CONFIG_LZMA_DECOMPRESS:=y -+ CONFIG_LZMA_COMPRESS:=y -+endif -+ - obj-$(CONFIG_DEBUG_INFO_REDUCED) += debug_info.o - CFLAGS_debug_info.o += $(call cc-option, -femit-struct-debug-detailed=any) - -@@ -185,6 +195,8 @@ obj-$(CONFIG_ZSTD_COMPRESS) += zstd/ - obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd/ - obj-$(CONFIG_XZ_DEC) += xz/ - obj-$(CONFIG_RAID6_PQ) += raid6/ -+obj-$(CONFIG_LZMA_COMPRESS) += lzma/ -+obj-$(CONFIG_LZMA_DECOMPRESS) += lzma/ - - lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o - lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o -diff --git a/lib/lzma/LzFind.c b/lib/lzma/LzFind.c -new file mode 100644 -index 000000000000..a02621a1f8f5 ---- /dev/null -+++ b/lib/lzma/LzFind.c -@@ -0,0 +1,761 @@ -+/* LzFind.c -- Match finder for LZ algorithms -+2009-04-22 : Igor Pavlov : Public domain */ -+ -+#include -+ -+#include "LzFind.h" -+#include "LzHash.h" -+ -+#define kEmptyHashValue 0 -+#define kMaxValForNormalize ((UInt32)0xFFFFFFFF) -+#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */ -+#define kNormalizeMask (~(kNormalizeStepMin - 1)) -+#define kMaxHistorySize ((UInt32)3 << 30) -+ -+#define kStartMaxLen 3 -+ -+static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc) -+{ -+ if (!p->directInput) -+ { -+ alloc->Free(alloc, p->bufferBase); -+ p->bufferBase = 0; -+ } -+} -+ -+/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */ -+ -+static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc) -+{ -+ UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv; -+ if (p->directInput) -+ { -+ p->blockSize = blockSize; -+ return 1; -+ } -+ if (p->bufferBase == 0 || p->blockSize != blockSize) -+ { -+ LzInWindow_Free(p, alloc); -+ p->blockSize = blockSize; -+ p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize); -+ } -+ return (p->bufferBase != 0); -+} -+ -+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } -+static Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; } -+ -+static UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } -+ -+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) -+{ -+ p->posLimit -= subValue; -+ p->pos -= subValue; -+ p->streamPos -= subValue; -+} -+ -+static void MatchFinder_ReadBlock(CMatchFinder *p) -+{ -+ if (p->streamEndWasReached || p->result != SZ_OK) -+ return; -+ if (p->directInput) -+ { -+ UInt32 curSize = 0xFFFFFFFF - p->streamPos; -+ if (curSize > p->directInputRem) -+ curSize = (UInt32)p->directInputRem; -+ p->directInputRem -= curSize; -+ p->streamPos += curSize; -+ if (p->directInputRem == 0) -+ p->streamEndWasReached = 1; -+ return; -+ } -+ for (;;) -+ { -+ Byte *dest = p->buffer + (p->streamPos - p->pos); -+ size_t size = (p->bufferBase + p->blockSize - dest); -+ if (size == 0) -+ return; -+ p->result = p->stream->Read(p->stream, dest, &size); -+ if (p->result != SZ_OK) -+ return; -+ if (size == 0) -+ { -+ p->streamEndWasReached = 1; -+ return; -+ } -+ p->streamPos += (UInt32)size; -+ if (p->streamPos - p->pos > p->keepSizeAfter) -+ return; -+ } -+} -+ -+void MatchFinder_MoveBlock(CMatchFinder *p) -+{ -+ memmove(p->bufferBase, -+ p->buffer - p->keepSizeBefore, -+ (size_t)(p->streamPos - p->pos + p->keepSizeBefore)); -+ p->buffer = p->bufferBase + p->keepSizeBefore; -+} -+ -+int MatchFinder_NeedMove(CMatchFinder *p) -+{ -+ if (p->directInput) -+ return 0; -+ /* if (p->streamEndWasReached) return 0; */ -+ return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter); -+} -+ -+void MatchFinder_ReadIfRequired(CMatchFinder *p) -+{ -+ if (p->streamEndWasReached) -+ return; -+ if (p->keepSizeAfter >= p->streamPos - p->pos) -+ MatchFinder_ReadBlock(p); -+} -+ -+static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p) -+{ -+ if (MatchFinder_NeedMove(p)) -+ MatchFinder_MoveBlock(p); -+ MatchFinder_ReadBlock(p); -+} -+ -+static void MatchFinder_SetDefaultSettings(CMatchFinder *p) -+{ -+ p->cutValue = 32; -+ p->btMode = 1; -+ p->numHashBytes = 4; -+ p->bigHash = 0; -+} -+ -+#define kCrcPoly 0xEDB88320 -+ -+void MatchFinder_Construct(CMatchFinder *p) -+{ -+ UInt32 i; -+ p->bufferBase = 0; -+ p->directInput = 0; -+ p->hash = 0; -+ MatchFinder_SetDefaultSettings(p); -+ -+ for (i = 0; i < 256; i++) -+ { -+ UInt32 r = i; -+ int j; -+ for (j = 0; j < 8; j++) -+ r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); -+ p->crc[i] = r; -+ } -+} -+ -+static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc) -+{ -+ alloc->Free(alloc, p->hash); -+ p->hash = 0; -+} -+ -+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc) -+{ -+ MatchFinder_FreeThisClassMemory(p, alloc); -+ LzInWindow_Free(p, alloc); -+} -+ -+static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc) -+{ -+ size_t sizeInBytes = (size_t)num * sizeof(CLzRef); -+ if (sizeInBytes / sizeof(CLzRef) != num) -+ return 0; -+ return (CLzRef *)alloc->Alloc(alloc, sizeInBytes); -+} -+ -+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, -+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, -+ ISzAlloc *alloc) -+{ -+ UInt32 sizeReserv; -+ if (historySize > kMaxHistorySize) -+ { -+ MatchFinder_Free(p, alloc); -+ return 0; -+ } -+ sizeReserv = historySize >> 1; -+ if (historySize > ((UInt32)2 << 30)) -+ sizeReserv = historySize >> 2; -+ sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19); -+ -+ p->keepSizeBefore = historySize + keepAddBufferBefore + 1; -+ p->keepSizeAfter = matchMaxLen + keepAddBufferAfter; -+ /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */ -+ if (LzInWindow_Create(p, sizeReserv, alloc)) -+ { -+ UInt32 newCyclicBufferSize = historySize + 1; -+ UInt32 hs; -+ p->matchMaxLen = matchMaxLen; -+ { -+ p->fixedHashSize = 0; -+ if (p->numHashBytes == 2) -+ hs = (1 << 16) - 1; -+ else -+ { -+ hs = historySize - 1; -+ hs |= (hs >> 1); -+ hs |= (hs >> 2); -+ hs |= (hs >> 4); -+ hs |= (hs >> 8); -+ hs >>= 1; -+ hs |= 0xFFFF; /* don't change it! It's required for Deflate */ -+ if (hs > (1 << 24)) -+ { -+ if (p->numHashBytes == 3) -+ hs = (1 << 24) - 1; -+ else -+ hs >>= 1; -+ } -+ } -+ p->hashMask = hs; -+ hs++; -+ if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size; -+ if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size; -+ if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size; -+ hs += p->fixedHashSize; -+ } -+ -+ { -+ UInt32 prevSize = p->hashSizeSum + p->numSons; -+ UInt32 newSize; -+ p->historySize = historySize; -+ p->hashSizeSum = hs; -+ p->cyclicBufferSize = newCyclicBufferSize; -+ p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize); -+ newSize = p->hashSizeSum + p->numSons; -+ if (p->hash != 0 && prevSize == newSize) -+ return 1; -+ MatchFinder_FreeThisClassMemory(p, alloc); -+ p->hash = AllocRefs(newSize, alloc); -+ if (p->hash != 0) -+ { -+ p->son = p->hash + p->hashSizeSum; -+ return 1; -+ } -+ } -+ } -+ MatchFinder_Free(p, alloc); -+ return 0; -+} -+ -+static void MatchFinder_SetLimits(CMatchFinder *p) -+{ -+ UInt32 limit = kMaxValForNormalize - p->pos; -+ UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos; -+ if (limit2 < limit) -+ limit = limit2; -+ limit2 = p->streamPos - p->pos; -+ if (limit2 <= p->keepSizeAfter) -+ { -+ if (limit2 > 0) -+ limit2 = 1; -+ } -+ else -+ limit2 -= p->keepSizeAfter; -+ if (limit2 < limit) -+ limit = limit2; -+ { -+ UInt32 lenLimit = p->streamPos - p->pos; -+ if (lenLimit > p->matchMaxLen) -+ lenLimit = p->matchMaxLen; -+ p->lenLimit = lenLimit; -+ } -+ p->posLimit = p->pos + limit; -+} -+ -+void MatchFinder_Init(CMatchFinder *p) -+{ -+ UInt32 i; -+ for (i = 0; i < p->hashSizeSum; i++) -+ p->hash[i] = kEmptyHashValue; -+ p->cyclicBufferPos = 0; -+ p->buffer = p->bufferBase; -+ p->pos = p->streamPos = p->cyclicBufferSize; -+ p->result = SZ_OK; -+ p->streamEndWasReached = 0; -+ MatchFinder_ReadBlock(p); -+ MatchFinder_SetLimits(p); -+} -+ -+static UInt32 MatchFinder_GetSubValue(CMatchFinder *p) -+{ -+ return (p->pos - p->historySize - 1) & kNormalizeMask; -+} -+ -+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) -+{ -+ UInt32 i; -+ for (i = 0; i < numItems; i++) -+ { -+ UInt32 value = items[i]; -+ if (value <= subValue) -+ value = kEmptyHashValue; -+ else -+ value -= subValue; -+ items[i] = value; -+ } -+} -+ -+static void MatchFinder_Normalize(CMatchFinder *p) -+{ -+ UInt32 subValue = MatchFinder_GetSubValue(p); -+ MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons); -+ MatchFinder_ReduceOffsets(p, subValue); -+} -+ -+static void MatchFinder_CheckLimits(CMatchFinder *p) -+{ -+ if (p->pos == kMaxValForNormalize) -+ MatchFinder_Normalize(p); -+ if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos) -+ MatchFinder_CheckAndMoveAndRead(p); -+ if (p->cyclicBufferPos == p->cyclicBufferSize) -+ p->cyclicBufferPos = 0; -+ MatchFinder_SetLimits(p); -+} -+ -+static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, -+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, -+ UInt32 *distances, UInt32 maxLen) -+{ -+ son[_cyclicBufferPos] = curMatch; -+ for (;;) -+ { -+ UInt32 delta = pos - curMatch; -+ if (cutValue-- == 0 || delta >= _cyclicBufferSize) -+ return distances; -+ { -+ const Byte *pb = cur - delta; -+ curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)]; -+ if (pb[maxLen] == cur[maxLen] && *pb == *cur) -+ { -+ UInt32 len = 0; -+ while (++len != lenLimit) -+ if (pb[len] != cur[len]) -+ break; -+ if (maxLen < len) -+ { -+ *distances++ = maxLen = len; -+ *distances++ = delta - 1; -+ if (len == lenLimit) -+ return distances; -+ } -+ } -+ } -+ } -+} -+ -+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, -+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, -+ UInt32 *distances, UInt32 maxLen) -+{ -+ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; -+ CLzRef *ptr1 = son + (_cyclicBufferPos << 1); -+ UInt32 len0 = 0, len1 = 0; -+ for (;;) -+ { -+ UInt32 delta = pos - curMatch; -+ if (cutValue-- == 0 || delta >= _cyclicBufferSize) -+ { -+ *ptr0 = *ptr1 = kEmptyHashValue; -+ return distances; -+ } -+ { -+ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); -+ const Byte *pb = cur - delta; -+ UInt32 len = (len0 < len1 ? len0 : len1); -+ if (pb[len] == cur[len]) -+ { -+ if (++len != lenLimit && pb[len] == cur[len]) -+ while (++len != lenLimit) -+ if (pb[len] != cur[len]) -+ break; -+ if (maxLen < len) -+ { -+ *distances++ = maxLen = len; -+ *distances++ = delta - 1; -+ if (len == lenLimit) -+ { -+ *ptr1 = pair[0]; -+ *ptr0 = pair[1]; -+ return distances; -+ } -+ } -+ } -+ if (pb[len] < cur[len]) -+ { -+ *ptr1 = curMatch; -+ ptr1 = pair + 1; -+ curMatch = *ptr1; -+ len1 = len; -+ } -+ else -+ { -+ *ptr0 = curMatch; -+ ptr0 = pair; -+ curMatch = *ptr0; -+ len0 = len; -+ } -+ } -+ } -+} -+ -+static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, -+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue) -+{ -+ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; -+ CLzRef *ptr1 = son + (_cyclicBufferPos << 1); -+ UInt32 len0 = 0, len1 = 0; -+ for (;;) -+ { -+ UInt32 delta = pos - curMatch; -+ if (cutValue-- == 0 || delta >= _cyclicBufferSize) -+ { -+ *ptr0 = *ptr1 = kEmptyHashValue; -+ return; -+ } -+ { -+ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); -+ const Byte *pb = cur - delta; -+ UInt32 len = (len0 < len1 ? len0 : len1); -+ if (pb[len] == cur[len]) -+ { -+ while (++len != lenLimit) -+ if (pb[len] != cur[len]) -+ break; -+ { -+ if (len == lenLimit) -+ { -+ *ptr1 = pair[0]; -+ *ptr0 = pair[1]; -+ return; -+ } -+ } -+ } -+ if (pb[len] < cur[len]) -+ { -+ *ptr1 = curMatch; -+ ptr1 = pair + 1; -+ curMatch = *ptr1; -+ len1 = len; -+ } -+ else -+ { -+ *ptr0 = curMatch; -+ ptr0 = pair; -+ curMatch = *ptr0; -+ len0 = len; -+ } -+ } -+ } -+} -+ -+#define MOVE_POS \ -+ ++p->cyclicBufferPos; \ -+ p->buffer++; \ -+ if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p); -+ -+#define MOVE_POS_RET MOVE_POS return offset; -+ -+static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } -+ -+#define GET_MATCHES_HEADER2(minLen, ret_op) \ -+ UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \ -+ lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \ -+ cur = p->buffer; -+ -+#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0) -+#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue) -+ -+#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue -+ -+#define GET_MATCHES_FOOTER(offset, maxLen) \ -+ offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \ -+ distances + offset, maxLen) - distances); MOVE_POS_RET; -+ -+#define SKIP_FOOTER \ -+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS; -+ -+static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+{ -+ UInt32 offset; -+ GET_MATCHES_HEADER(2) -+ HASH2_CALC; -+ curMatch = p->hash[hashValue]; -+ p->hash[hashValue] = p->pos; -+ offset = 0; -+ GET_MATCHES_FOOTER(offset, 1) -+} -+ -+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+{ -+ UInt32 offset; -+ GET_MATCHES_HEADER(3) -+ HASH_ZIP_CALC; -+ curMatch = p->hash[hashValue]; -+ p->hash[hashValue] = p->pos; -+ offset = 0; -+ GET_MATCHES_FOOTER(offset, 2) -+} -+ -+static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+{ -+ UInt32 hash2Value, delta2, maxLen, offset; -+ GET_MATCHES_HEADER(3) -+ -+ HASH3_CALC; -+ -+ delta2 = p->pos - p->hash[hash2Value]; -+ curMatch = p->hash[kFix3HashSize + hashValue]; -+ -+ p->hash[hash2Value] = -+ p->hash[kFix3HashSize + hashValue] = p->pos; -+ -+ -+ maxLen = 2; -+ offset = 0; -+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) -+ { -+ for (; maxLen != lenLimit; maxLen++) -+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) -+ break; -+ distances[0] = maxLen; -+ distances[1] = delta2 - 1; -+ offset = 2; -+ if (maxLen == lenLimit) -+ { -+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); -+ MOVE_POS_RET; -+ } -+ } -+ GET_MATCHES_FOOTER(offset, maxLen) -+} -+ -+static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+{ -+ UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; -+ GET_MATCHES_HEADER(4) -+ -+ HASH4_CALC; -+ -+ delta2 = p->pos - p->hash[ hash2Value]; -+ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; -+ curMatch = p->hash[kFix4HashSize + hashValue]; -+ -+ p->hash[ hash2Value] = -+ p->hash[kFix3HashSize + hash3Value] = -+ p->hash[kFix4HashSize + hashValue] = p->pos; -+ -+ maxLen = 1; -+ offset = 0; -+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) -+ { -+ distances[0] = maxLen = 2; -+ distances[1] = delta2 - 1; -+ offset = 2; -+ } -+ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) -+ { -+ maxLen = 3; -+ distances[offset + 1] = delta3 - 1; -+ offset += 2; -+ delta2 = delta3; -+ } -+ if (offset != 0) -+ { -+ for (; maxLen != lenLimit; maxLen++) -+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) -+ break; -+ distances[offset - 2] = maxLen; -+ if (maxLen == lenLimit) -+ { -+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); -+ MOVE_POS_RET; -+ } -+ } -+ if (maxLen < 3) -+ maxLen = 3; -+ GET_MATCHES_FOOTER(offset, maxLen) -+} -+ -+static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+{ -+ UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; -+ GET_MATCHES_HEADER(4) -+ -+ HASH4_CALC; -+ -+ delta2 = p->pos - p->hash[ hash2Value]; -+ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; -+ curMatch = p->hash[kFix4HashSize + hashValue]; -+ -+ p->hash[ hash2Value] = -+ p->hash[kFix3HashSize + hash3Value] = -+ p->hash[kFix4HashSize + hashValue] = p->pos; -+ -+ maxLen = 1; -+ offset = 0; -+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) -+ { -+ distances[0] = maxLen = 2; -+ distances[1] = delta2 - 1; -+ offset = 2; -+ } -+ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) -+ { -+ maxLen = 3; -+ distances[offset + 1] = delta3 - 1; -+ offset += 2; -+ delta2 = delta3; -+ } -+ if (offset != 0) -+ { -+ for (; maxLen != lenLimit; maxLen++) -+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) -+ break; -+ distances[offset - 2] = maxLen; -+ if (maxLen == lenLimit) -+ { -+ p->son[p->cyclicBufferPos] = curMatch; -+ MOVE_POS_RET; -+ } -+ } -+ if (maxLen < 3) -+ maxLen = 3; -+ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), -+ distances + offset, maxLen) - (distances)); -+ MOVE_POS_RET -+} -+ -+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+{ -+ UInt32 offset; -+ GET_MATCHES_HEADER(3) -+ HASH_ZIP_CALC; -+ curMatch = p->hash[hashValue]; -+ p->hash[hashValue] = p->pos; -+ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), -+ distances, 2) - (distances)); -+ MOVE_POS_RET -+} -+ -+static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+{ -+ do -+ { -+ SKIP_HEADER(2) -+ HASH2_CALC; -+ curMatch = p->hash[hashValue]; -+ p->hash[hashValue] = p->pos; -+ SKIP_FOOTER -+ } -+ while (--num != 0); -+} -+ -+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+{ -+ do -+ { -+ SKIP_HEADER(3) -+ HASH_ZIP_CALC; -+ curMatch = p->hash[hashValue]; -+ p->hash[hashValue] = p->pos; -+ SKIP_FOOTER -+ } -+ while (--num != 0); -+} -+ -+static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+{ -+ do -+ { -+ UInt32 hash2Value; -+ SKIP_HEADER(3) -+ HASH3_CALC; -+ curMatch = p->hash[kFix3HashSize + hashValue]; -+ p->hash[hash2Value] = -+ p->hash[kFix3HashSize + hashValue] = p->pos; -+ SKIP_FOOTER -+ } -+ while (--num != 0); -+} -+ -+static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+{ -+ do -+ { -+ UInt32 hash2Value, hash3Value; -+ SKIP_HEADER(4) -+ HASH4_CALC; -+ curMatch = p->hash[kFix4HashSize + hashValue]; -+ p->hash[ hash2Value] = -+ p->hash[kFix3HashSize + hash3Value] = p->pos; -+ p->hash[kFix4HashSize + hashValue] = p->pos; -+ SKIP_FOOTER -+ } -+ while (--num != 0); -+} -+ -+static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+{ -+ do -+ { -+ UInt32 hash2Value, hash3Value; -+ SKIP_HEADER(4) -+ HASH4_CALC; -+ curMatch = p->hash[kFix4HashSize + hashValue]; -+ p->hash[ hash2Value] = -+ p->hash[kFix3HashSize + hash3Value] = -+ p->hash[kFix4HashSize + hashValue] = p->pos; -+ p->son[p->cyclicBufferPos] = curMatch; -+ MOVE_POS -+ } -+ while (--num != 0); -+} -+ -+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+{ -+ do -+ { -+ SKIP_HEADER(3) -+ HASH_ZIP_CALC; -+ curMatch = p->hash[hashValue]; -+ p->hash[hashValue] = p->pos; -+ p->son[p->cyclicBufferPos] = curMatch; -+ MOVE_POS -+ } -+ while (--num != 0); -+} -+ -+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable) -+{ -+ vTable->Init = (Mf_Init_Func)MatchFinder_Init; -+ vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte; -+ vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes; -+ vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos; -+ if (!p->btMode) -+ { -+ vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches; -+ vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip; -+ } -+ else if (p->numHashBytes == 2) -+ { -+ vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches; -+ vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip; -+ } -+ else if (p->numHashBytes == 3) -+ { -+ vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches; -+ vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip; -+ } -+ else -+ { -+ vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; -+ vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; -+ } -+} -diff --git a/lib/lzma/LzmaDec.c b/lib/lzma/LzmaDec.c -new file mode 100644 -index 000000000000..7bc3ce91a6a0 ---- /dev/null -+++ b/lib/lzma/LzmaDec.c -@@ -0,0 +1,999 @@ -+/* LzmaDec.c -- LZMA Decoder -+2009-09-20 : Igor Pavlov : Public domain */ -+ -+#include "LzmaDec.h" -+ -+#include -+ -+#define kNumTopBits 24 -+#define kTopValue ((UInt32)1 << kNumTopBits) -+ -+#define kNumBitModelTotalBits 11 -+#define kBitModelTotal (1 << kNumBitModelTotalBits) -+#define kNumMoveBits 5 -+ -+#define RC_INIT_SIZE 5 -+ -+#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } -+ -+#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) -+#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); -+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); -+#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ -+ { UPDATE_0(p); i = (i + i); A0; } else \ -+ { UPDATE_1(p); i = (i + i) + 1; A1; } -+#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;) -+ -+#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } -+#define TREE_DECODE(probs, limit, i) \ -+ { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } -+ -+/* #define _LZMA_SIZE_OPT */ -+ -+#ifdef _LZMA_SIZE_OPT -+#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) -+#else -+#define TREE_6_DECODE(probs, i) \ -+ { i = 1; \ -+ TREE_GET_BIT(probs, i); \ -+ TREE_GET_BIT(probs, i); \ -+ TREE_GET_BIT(probs, i); \ -+ TREE_GET_BIT(probs, i); \ -+ TREE_GET_BIT(probs, i); \ -+ TREE_GET_BIT(probs, i); \ -+ i -= 0x40; } -+#endif -+ -+#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } -+ -+#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) -+#define UPDATE_0_CHECK range = bound; -+#define UPDATE_1_CHECK range -= bound; code -= bound; -+#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ -+ { UPDATE_0_CHECK; i = (i + i); A0; } else \ -+ { UPDATE_1_CHECK; i = (i + i) + 1; A1; } -+#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) -+#define TREE_DECODE_CHECK(probs, limit, i) \ -+ { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } -+ -+ -+#define kNumPosBitsMax 4 -+#define kNumPosStatesMax (1 << kNumPosBitsMax) -+ -+#define kLenNumLowBits 3 -+#define kLenNumLowSymbols (1 << kLenNumLowBits) -+#define kLenNumMidBits 3 -+#define kLenNumMidSymbols (1 << kLenNumMidBits) -+#define kLenNumHighBits 8 -+#define kLenNumHighSymbols (1 << kLenNumHighBits) -+ -+#define LenChoice 0 -+#define LenChoice2 (LenChoice + 1) -+#define LenLow (LenChoice2 + 1) -+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) -+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) -+#define kNumLenProbs (LenHigh + kLenNumHighSymbols) -+ -+ -+#define kNumStates 12 -+#define kNumLitStates 7 -+ -+#define kStartPosModelIndex 4 -+#define kEndPosModelIndex 14 -+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) -+ -+#define kNumPosSlotBits 6 -+#define kNumLenToPosStates 4 -+ -+#define kNumAlignBits 4 -+#define kAlignTableSize (1 << kNumAlignBits) -+ -+#define kMatchMinLen 2 -+#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) -+ -+#define IsMatch 0 -+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) -+#define IsRepG0 (IsRep + kNumStates) -+#define IsRepG1 (IsRepG0 + kNumStates) -+#define IsRepG2 (IsRepG1 + kNumStates) -+#define IsRep0Long (IsRepG2 + kNumStates) -+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) -+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) -+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) -+#define LenCoder (Align + kAlignTableSize) -+#define RepLenCoder (LenCoder + kNumLenProbs) -+#define Literal (RepLenCoder + kNumLenProbs) -+ -+#define LZMA_BASE_SIZE 1846 -+#define LZMA_LIT_SIZE 768 -+ -+#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) -+ -+#if Literal != LZMA_BASE_SIZE -+StopCompilingDueBUG -+#endif -+ -+#define LZMA_DIC_MIN (1 << 12) -+ -+/* First LZMA-symbol is always decoded. -+And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization -+Out: -+ Result: -+ SZ_OK - OK -+ SZ_ERROR_DATA - Error -+ p->remainLen: -+ < kMatchSpecLenStart : normal remain -+ = kMatchSpecLenStart : finished -+ = kMatchSpecLenStart + 1 : Flush marker -+ = kMatchSpecLenStart + 2 : State Init Marker -+*/ -+ -+static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit) -+{ -+ CLzmaProb *probs = p->probs; -+ -+ unsigned state = p->state; -+ UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; -+ unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; -+ unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; -+ unsigned lc = p->prop.lc; -+ -+ Byte *dic = p->dic; -+ SizeT dicBufSize = p->dicBufSize; -+ SizeT dicPos = p->dicPos; -+ -+ UInt32 processedPos = p->processedPos; -+ UInt32 checkDicSize = p->checkDicSize; -+ unsigned len = 0; -+ -+ const Byte *buf = p->buf; -+ UInt32 range = p->range; -+ UInt32 code = p->code; -+ -+ do -+ { -+ CLzmaProb *prob; -+ UInt32 bound; -+ unsigned ttt; -+ unsigned posState = processedPos & pbMask; -+ -+ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; -+ IF_BIT_0(prob) -+ { -+ unsigned symbol; -+ UPDATE_0(prob); -+ prob = probs + Literal; -+ if (checkDicSize != 0 || processedPos != 0) -+ prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + -+ (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); -+ -+ if (state < kNumLitStates) -+ { -+ state -= (state < 4) ? state : 3; -+ symbol = 1; -+ do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); -+ } -+ else -+ { -+ unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; -+ unsigned offs = 0x100; -+ state -= (state < 10) ? 3 : 6; -+ symbol = 1; -+ do -+ { -+ unsigned bit; -+ CLzmaProb *probLit; -+ matchByte <<= 1; -+ bit = (matchByte & offs); -+ probLit = prob + offs + bit + symbol; -+ GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) -+ } -+ while (symbol < 0x100); -+ } -+ dic[dicPos++] = (Byte)symbol; -+ processedPos++; -+ continue; -+ } -+ else -+ { -+ UPDATE_1(prob); -+ prob = probs + IsRep + state; -+ IF_BIT_0(prob) -+ { -+ UPDATE_0(prob); -+ state += kNumStates; -+ prob = probs + LenCoder; -+ } -+ else -+ { -+ UPDATE_1(prob); -+ if (checkDicSize == 0 && processedPos == 0) -+ return SZ_ERROR_DATA; -+ prob = probs + IsRepG0 + state; -+ IF_BIT_0(prob) -+ { -+ UPDATE_0(prob); -+ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; -+ IF_BIT_0(prob) -+ { -+ UPDATE_0(prob); -+ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; -+ dicPos++; -+ processedPos++; -+ state = state < kNumLitStates ? 9 : 11; -+ continue; -+ } -+ UPDATE_1(prob); -+ } -+ else -+ { -+ UInt32 distance; -+ UPDATE_1(prob); -+ prob = probs + IsRepG1 + state; -+ IF_BIT_0(prob) -+ { -+ UPDATE_0(prob); -+ distance = rep1; -+ } -+ else -+ { -+ UPDATE_1(prob); -+ prob = probs + IsRepG2 + state; -+ IF_BIT_0(prob) -+ { -+ UPDATE_0(prob); -+ distance = rep2; -+ } -+ else -+ { -+ UPDATE_1(prob); -+ distance = rep3; -+ rep3 = rep2; -+ } -+ rep2 = rep1; -+ } -+ rep1 = rep0; -+ rep0 = distance; -+ } -+ state = state < kNumLitStates ? 8 : 11; -+ prob = probs + RepLenCoder; -+ } -+ { -+ unsigned limit, offset; -+ CLzmaProb *probLen = prob + LenChoice; -+ IF_BIT_0(probLen) -+ { -+ UPDATE_0(probLen); -+ probLen = prob + LenLow + (posState << kLenNumLowBits); -+ offset = 0; -+ limit = (1 << kLenNumLowBits); -+ } -+ else -+ { -+ UPDATE_1(probLen); -+ probLen = prob + LenChoice2; -+ IF_BIT_0(probLen) -+ { -+ UPDATE_0(probLen); -+ probLen = prob + LenMid + (posState << kLenNumMidBits); -+ offset = kLenNumLowSymbols; -+ limit = (1 << kLenNumMidBits); -+ } -+ else -+ { -+ UPDATE_1(probLen); -+ probLen = prob + LenHigh; -+ offset = kLenNumLowSymbols + kLenNumMidSymbols; -+ limit = (1 << kLenNumHighBits); -+ } -+ } -+ TREE_DECODE(probLen, limit, len); -+ len += offset; -+ } -+ -+ if (state >= kNumStates) -+ { -+ UInt32 distance; -+ prob = probs + PosSlot + -+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); -+ TREE_6_DECODE(prob, distance); -+ if (distance >= kStartPosModelIndex) -+ { -+ unsigned posSlot = (unsigned)distance; -+ int numDirectBits = (int)(((distance >> 1) - 1)); -+ distance = (2 | (distance & 1)); -+ if (posSlot < kEndPosModelIndex) -+ { -+ distance <<= numDirectBits; -+ prob = probs + SpecPos + distance - posSlot - 1; -+ { -+ UInt32 mask = 1; -+ unsigned i = 1; -+ do -+ { -+ GET_BIT2(prob + i, i, ; , distance |= mask); -+ mask <<= 1; -+ } -+ while (--numDirectBits != 0); -+ } -+ } -+ else -+ { -+ numDirectBits -= kNumAlignBits; -+ do -+ { -+ NORMALIZE -+ range >>= 1; -+ -+ { -+ UInt32 t; -+ code -= range; -+ t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ -+ distance = (distance << 1) + (t + 1); -+ code += range & t; -+ } -+ /* -+ distance <<= 1; -+ if (code >= range) -+ { -+ code -= range; -+ distance |= 1; -+ } -+ */ -+ } -+ while (--numDirectBits != 0); -+ prob = probs + Align; -+ distance <<= kNumAlignBits; -+ { -+ unsigned i = 1; -+ GET_BIT2(prob + i, i, ; , distance |= 1); -+ GET_BIT2(prob + i, i, ; , distance |= 2); -+ GET_BIT2(prob + i, i, ; , distance |= 4); -+ GET_BIT2(prob + i, i, ; , distance |= 8); -+ } -+ if (distance == (UInt32)0xFFFFFFFF) -+ { -+ len += kMatchSpecLenStart; -+ state -= kNumStates; -+ break; -+ } -+ } -+ } -+ rep3 = rep2; -+ rep2 = rep1; -+ rep1 = rep0; -+ rep0 = distance + 1; -+ if (checkDicSize == 0) -+ { -+ if (distance >= processedPos) -+ return SZ_ERROR_DATA; -+ } -+ else if (distance >= checkDicSize) -+ return SZ_ERROR_DATA; -+ state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; -+ } -+ -+ len += kMatchMinLen; -+ -+ if (limit == dicPos) -+ return SZ_ERROR_DATA; -+ { -+ SizeT rem = limit - dicPos; -+ unsigned curLen = ((rem < len) ? (unsigned)rem : len); -+ SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); -+ -+ processedPos += curLen; -+ -+ len -= curLen; -+ if (pos + curLen <= dicBufSize) -+ { -+ Byte *dest = dic + dicPos; -+ ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; -+ const Byte *lim = dest + curLen; -+ dicPos += curLen; -+ do -+ *(dest) = (Byte)*(dest + src); -+ while (++dest != lim); -+ } -+ else -+ { -+ do -+ { -+ dic[dicPos++] = dic[pos]; -+ if (++pos == dicBufSize) -+ pos = 0; -+ } -+ while (--curLen != 0); -+ } -+ } -+ } -+ } -+ while (dicPos < limit && buf < bufLimit); -+ NORMALIZE; -+ p->buf = buf; -+ p->range = range; -+ p->code = code; -+ p->remainLen = len; -+ p->dicPos = dicPos; -+ p->processedPos = processedPos; -+ p->reps[0] = rep0; -+ p->reps[1] = rep1; -+ p->reps[2] = rep2; -+ p->reps[3] = rep3; -+ p->state = state; -+ -+ return SZ_OK; -+} -+ -+static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) -+{ -+ if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) -+ { -+ Byte *dic = p->dic; -+ SizeT dicPos = p->dicPos; -+ SizeT dicBufSize = p->dicBufSize; -+ unsigned len = p->remainLen; -+ UInt32 rep0 = p->reps[0]; -+ if (limit - dicPos < len) -+ len = (unsigned)(limit - dicPos); -+ -+ if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) -+ p->checkDicSize = p->prop.dicSize; -+ -+ p->processedPos += len; -+ p->remainLen -= len; -+ while (len-- != 0) -+ { -+ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; -+ dicPos++; -+ } -+ p->dicPos = dicPos; -+ } -+} -+ -+static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) -+{ -+ do -+ { -+ SizeT limit2 = limit; -+ if (p->checkDicSize == 0) -+ { -+ UInt32 rem = p->prop.dicSize - p->processedPos; -+ if (limit - p->dicPos > rem) -+ limit2 = p->dicPos + rem; -+ } -+ RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); -+ if (p->processedPos >= p->prop.dicSize) -+ p->checkDicSize = p->prop.dicSize; -+ LzmaDec_WriteRem(p, limit); -+ } -+ while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); -+ -+ if (p->remainLen > kMatchSpecLenStart) -+ { -+ p->remainLen = kMatchSpecLenStart; -+ } -+ return 0; -+} -+ -+typedef enum -+{ -+ DUMMY_ERROR, /* unexpected end of input stream */ -+ DUMMY_LIT, -+ DUMMY_MATCH, -+ DUMMY_REP -+} ELzmaDummy; -+ -+static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) -+{ -+ UInt32 range = p->range; -+ UInt32 code = p->code; -+ const Byte *bufLimit = buf + inSize; -+ CLzmaProb *probs = p->probs; -+ unsigned state = p->state; -+ ELzmaDummy res; -+ -+ { -+ CLzmaProb *prob; -+ UInt32 bound; -+ unsigned ttt; -+ unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); -+ -+ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK -+ -+ /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ -+ -+ prob = probs + Literal; -+ if (p->checkDicSize != 0 || p->processedPos != 0) -+ prob += (LZMA_LIT_SIZE * -+ ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + -+ (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); -+ -+ if (state < kNumLitStates) -+ { -+ unsigned symbol = 1; -+ do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); -+ } -+ else -+ { -+ unsigned matchByte = p->dic[p->dicPos - p->reps[0] + -+ ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; -+ unsigned offs = 0x100; -+ unsigned symbol = 1; -+ do -+ { -+ unsigned bit; -+ CLzmaProb *probLit; -+ matchByte <<= 1; -+ bit = (matchByte & offs); -+ probLit = prob + offs + bit + symbol; -+ GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) -+ } -+ while (symbol < 0x100); -+ } -+ res = DUMMY_LIT; -+ } -+ else -+ { -+ unsigned len; -+ UPDATE_1_CHECK; -+ -+ prob = probs + IsRep + state; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK; -+ state = 0; -+ prob = probs + LenCoder; -+ res = DUMMY_MATCH; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ res = DUMMY_REP; -+ prob = probs + IsRepG0 + state; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK; -+ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK; -+ NORMALIZE_CHECK; -+ return DUMMY_REP; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ } -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ prob = probs + IsRepG1 + state; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ prob = probs + IsRepG2 + state; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ } -+ } -+ } -+ state = kNumStates; -+ prob = probs + RepLenCoder; -+ } -+ { -+ unsigned limit, offset; -+ CLzmaProb *probLen = prob + LenChoice; -+ IF_BIT_0_CHECK(probLen) -+ { -+ UPDATE_0_CHECK; -+ probLen = prob + LenLow + (posState << kLenNumLowBits); -+ offset = 0; -+ limit = 1 << kLenNumLowBits; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ probLen = prob + LenChoice2; -+ IF_BIT_0_CHECK(probLen) -+ { -+ UPDATE_0_CHECK; -+ probLen = prob + LenMid + (posState << kLenNumMidBits); -+ offset = kLenNumLowSymbols; -+ limit = 1 << kLenNumMidBits; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ probLen = prob + LenHigh; -+ offset = kLenNumLowSymbols + kLenNumMidSymbols; -+ limit = 1 << kLenNumHighBits; -+ } -+ } -+ TREE_DECODE_CHECK(probLen, limit, len); -+ len += offset; -+ } -+ -+ if (state < 4) -+ { -+ unsigned posSlot; -+ prob = probs + PosSlot + -+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << -+ kNumPosSlotBits); -+ TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); -+ if (posSlot >= kStartPosModelIndex) -+ { -+ int numDirectBits = ((posSlot >> 1) - 1); -+ -+ /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ -+ -+ if (posSlot < kEndPosModelIndex) -+ { -+ prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; -+ } -+ else -+ { -+ numDirectBits -= kNumAlignBits; -+ do -+ { -+ NORMALIZE_CHECK -+ range >>= 1; -+ code -= range & (((code - range) >> 31) - 1); -+ /* if (code >= range) code -= range; */ -+ } -+ while (--numDirectBits != 0); -+ prob = probs + Align; -+ numDirectBits = kNumAlignBits; -+ } -+ { -+ unsigned i = 1; -+ do -+ { -+ GET_BIT_CHECK(prob + i, i); -+ } -+ while (--numDirectBits != 0); -+ } -+ } -+ } -+ } -+ } -+ NORMALIZE_CHECK; -+ return res; -+} -+ -+ -+static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) -+{ -+ p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]); -+ p->range = 0xFFFFFFFF; -+ p->needFlush = 0; -+} -+ -+static void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) -+{ -+ p->needFlush = 1; -+ p->remainLen = 0; -+ p->tempBufSize = 0; -+ -+ if (initDic) -+ { -+ p->processedPos = 0; -+ p->checkDicSize = 0; -+ p->needInitState = 1; -+ } -+ if (initState) -+ p->needInitState = 1; -+} -+ -+void LzmaDec_Init(CLzmaDec *p) -+{ -+ p->dicPos = 0; -+ LzmaDec_InitDicAndState(p, True, True); -+} -+ -+static void LzmaDec_InitStateReal(CLzmaDec *p) -+{ -+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); -+ UInt32 i; -+ CLzmaProb *probs = p->probs; -+ for (i = 0; i < numProbs; i++) -+ probs[i] = kBitModelTotal >> 1; -+ p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; -+ p->state = 0; -+ p->needInitState = 0; -+} -+ -+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, -+ ELzmaFinishMode finishMode, ELzmaStatus *status) -+{ -+ SizeT inSize = *srcLen; -+ (*srcLen) = 0; -+ LzmaDec_WriteRem(p, dicLimit); -+ -+ *status = LZMA_STATUS_NOT_SPECIFIED; -+ -+ while (p->remainLen != kMatchSpecLenStart) -+ { -+ int checkEndMarkNow; -+ -+ if (p->needFlush != 0) -+ { -+ for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) -+ p->tempBuf[p->tempBufSize++] = *src++; -+ if (p->tempBufSize < RC_INIT_SIZE) -+ { -+ *status = LZMA_STATUS_NEEDS_MORE_INPUT; -+ return SZ_OK; -+ } -+ if (p->tempBuf[0] != 0) -+ return SZ_ERROR_DATA; -+ -+ LzmaDec_InitRc(p, p->tempBuf); -+ p->tempBufSize = 0; -+ } -+ -+ checkEndMarkNow = 0; -+ if (p->dicPos >= dicLimit) -+ { -+ if (p->remainLen == 0 && p->code == 0) -+ { -+ *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; -+ return SZ_OK; -+ } -+ if (finishMode == LZMA_FINISH_ANY) -+ { -+ *status = LZMA_STATUS_NOT_FINISHED; -+ return SZ_OK; -+ } -+ if (p->remainLen != 0) -+ { -+ *status = LZMA_STATUS_NOT_FINISHED; -+ return SZ_ERROR_DATA; -+ } -+ checkEndMarkNow = 1; -+ } -+ -+ if (p->needInitState) -+ LzmaDec_InitStateReal(p); -+ -+ if (p->tempBufSize == 0) -+ { -+ SizeT processed; -+ const Byte *bufLimit; -+ if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) -+ { -+ int dummyRes = LzmaDec_TryDummy(p, src, inSize); -+ if (dummyRes == DUMMY_ERROR) -+ { -+ memcpy(p->tempBuf, src, inSize); -+ p->tempBufSize = (unsigned)inSize; -+ (*srcLen) += inSize; -+ *status = LZMA_STATUS_NEEDS_MORE_INPUT; -+ return SZ_OK; -+ } -+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH) -+ { -+ *status = LZMA_STATUS_NOT_FINISHED; -+ return SZ_ERROR_DATA; -+ } -+ bufLimit = src; -+ } -+ else -+ bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; -+ p->buf = src; -+ if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) -+ return SZ_ERROR_DATA; -+ processed = (SizeT)(p->buf - src); -+ (*srcLen) += processed; -+ src += processed; -+ inSize -= processed; -+ } -+ else -+ { -+ unsigned rem = p->tempBufSize, lookAhead = 0; -+ while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) -+ p->tempBuf[rem++] = src[lookAhead++]; -+ p->tempBufSize = rem; -+ if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) -+ { -+ int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); -+ if (dummyRes == DUMMY_ERROR) -+ { -+ (*srcLen) += lookAhead; -+ *status = LZMA_STATUS_NEEDS_MORE_INPUT; -+ return SZ_OK; -+ } -+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH) -+ { -+ *status = LZMA_STATUS_NOT_FINISHED; -+ return SZ_ERROR_DATA; -+ } -+ } -+ p->buf = p->tempBuf; -+ if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) -+ return SZ_ERROR_DATA; -+ lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); -+ (*srcLen) += lookAhead; -+ src += lookAhead; -+ inSize -= lookAhead; -+ p->tempBufSize = 0; -+ } -+ } -+ if (p->code == 0) -+ *status = LZMA_STATUS_FINISHED_WITH_MARK; -+ return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; -+} -+ -+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) -+{ -+ SizeT outSize = *destLen; -+ SizeT inSize = *srcLen; -+ *srcLen = *destLen = 0; -+ for (;;) -+ { -+ SizeT inSizeCur = inSize, outSizeCur, dicPos; -+ ELzmaFinishMode curFinishMode; -+ SRes res; -+ if (p->dicPos == p->dicBufSize) -+ p->dicPos = 0; -+ dicPos = p->dicPos; -+ if (outSize > p->dicBufSize - dicPos) -+ { -+ outSizeCur = p->dicBufSize; -+ curFinishMode = LZMA_FINISH_ANY; -+ } -+ else -+ { -+ outSizeCur = dicPos + outSize; -+ curFinishMode = finishMode; -+ } -+ -+ res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); -+ src += inSizeCur; -+ inSize -= inSizeCur; -+ *srcLen += inSizeCur; -+ outSizeCur = p->dicPos - dicPos; -+ memcpy(dest, p->dic + dicPos, outSizeCur); -+ dest += outSizeCur; -+ outSize -= outSizeCur; -+ *destLen += outSizeCur; -+ if (res != 0) -+ return res; -+ if (outSizeCur == 0 || outSize == 0) -+ return SZ_OK; -+ } -+} -+ -+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) -+{ -+ alloc->Free(alloc, p->probs); -+ p->probs = 0; -+} -+ -+static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) -+{ -+ alloc->Free(alloc, p->dic); -+ p->dic = 0; -+} -+ -+void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) -+{ -+ LzmaDec_FreeProbs(p, alloc); -+ LzmaDec_FreeDict(p, alloc); -+} -+ -+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) -+{ -+ UInt32 dicSize; -+ Byte d; -+ -+ if (size < LZMA_PROPS_SIZE) -+ return SZ_ERROR_UNSUPPORTED; -+ else -+ dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); -+ -+ if (dicSize < LZMA_DIC_MIN) -+ dicSize = LZMA_DIC_MIN; -+ p->dicSize = dicSize; -+ -+ d = data[0]; -+ if (d >= (9 * 5 * 5)) -+ return SZ_ERROR_UNSUPPORTED; -+ -+ p->lc = d % 9; -+ d /= 9; -+ p->pb = d / 5; -+ p->lp = d % 5; -+ -+ return SZ_OK; -+} -+ -+static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) -+{ -+ UInt32 numProbs = LzmaProps_GetNumProbs(propNew); -+ if (p->probs == 0 || numProbs != p->numProbs) -+ { -+ LzmaDec_FreeProbs(p, alloc); -+ p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); -+ p->numProbs = numProbs; -+ if (p->probs == 0) -+ return SZ_ERROR_MEM; -+ } -+ return SZ_OK; -+} -+ -+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) -+{ -+ CLzmaProps propNew; -+ RINOK(LzmaProps_Decode(&propNew, props, propsSize)); -+ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); -+ p->prop = propNew; -+ return SZ_OK; -+} -+ -+SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) -+{ -+ CLzmaProps propNew; -+ SizeT dicBufSize; -+ RINOK(LzmaProps_Decode(&propNew, props, propsSize)); -+ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); -+ dicBufSize = propNew.dicSize; -+ if (p->dic == 0 || dicBufSize != p->dicBufSize) -+ { -+ LzmaDec_FreeDict(p, alloc); -+ p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); -+ if (p->dic == 0) -+ { -+ LzmaDec_FreeProbs(p, alloc); -+ return SZ_ERROR_MEM; -+ } -+ } -+ p->dicBufSize = dicBufSize; -+ p->prop = propNew; -+ return SZ_OK; -+} -+ -+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, -+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, -+ ELzmaStatus *status, ISzAlloc *alloc) -+{ -+ CLzmaDec p; -+ SRes res; -+ SizeT inSize = *srcLen; -+ SizeT outSize = *destLen; -+ *srcLen = *destLen = 0; -+ if (inSize < RC_INIT_SIZE) -+ return SZ_ERROR_INPUT_EOF; -+ -+ LzmaDec_Construct(&p); -+ res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); -+ if (res != 0) -+ return res; -+ p.dic = dest; -+ p.dicBufSize = outSize; -+ -+ LzmaDec_Init(&p); -+ -+ *srcLen = inSize; -+ res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); -+ -+ if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) -+ res = SZ_ERROR_INPUT_EOF; -+ -+ (*destLen) = p.dicPos; -+ LzmaDec_FreeProbs(&p, alloc); -+ return res; -+} -diff --git a/lib/lzma/LzmaEnc.c b/lib/lzma/LzmaEnc.c -new file mode 100644 -index 000000000000..b81f0863f7d8 ---- /dev/null -+++ b/lib/lzma/LzmaEnc.c -@@ -0,0 +1,2271 @@ -+/* LzmaEnc.c -- LZMA Encoder -+2009-11-24 : Igor Pavlov : Public domain */ -+ -+#include -+ -+/* #define SHOW_STAT */ -+/* #define SHOW_STAT2 */ -+ -+#if defined(SHOW_STAT) || defined(SHOW_STAT2) -+#include -+#endif -+ -+#include "LzmaEnc.h" -+ -+/* disable MT */ -+#define _7ZIP_ST -+ -+#include "LzFind.h" -+#ifndef _7ZIP_ST -+#include "LzFindMt.h" -+#endif -+ -+#ifdef SHOW_STAT -+static int ttt = 0; -+#endif -+ -+#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1) -+ -+#define kBlockSize (9 << 10) -+#define kUnpackBlockSize (1 << 18) -+#define kMatchArraySize (1 << 21) -+#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX) -+ -+#define kNumMaxDirectBits (31) -+ -+#define kNumTopBits 24 -+#define kTopValue ((UInt32)1 << kNumTopBits) -+ -+#define kNumBitModelTotalBits 11 -+#define kBitModelTotal (1 << kNumBitModelTotalBits) -+#define kNumMoveBits 5 -+#define kProbInitValue (kBitModelTotal >> 1) -+ -+#define kNumMoveReducingBits 4 -+#define kNumBitPriceShiftBits 4 -+#define kBitPrice (1 << kNumBitPriceShiftBits) -+ -+void LzmaEncProps_Init(CLzmaEncProps *p) -+{ -+ p->level = 5; -+ p->dictSize = p->mc = 0; -+ p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1; -+ p->writeEndMark = 0; -+} -+ -+void LzmaEncProps_Normalize(CLzmaEncProps *p) -+{ -+ int level = p->level; -+ if (level < 0) level = 5; -+ p->level = level; -+ if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26))); -+ if (p->lc < 0) p->lc = 3; -+ if (p->lp < 0) p->lp = 0; -+ if (p->pb < 0) p->pb = 2; -+ if (p->algo < 0) p->algo = (level < 5 ? 0 : 1); -+ if (p->fb < 0) p->fb = (level < 7 ? 32 : 64); -+ if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1); -+ if (p->numHashBytes < 0) p->numHashBytes = 4; -+ if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1); -+ if (p->numThreads < 0) -+ p->numThreads = -+ #ifndef _7ZIP_ST -+ ((p->btMode && p->algo) ? 2 : 1); -+ #else -+ 1; -+ #endif -+} -+ -+UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) -+{ -+ CLzmaEncProps props = *props2; -+ LzmaEncProps_Normalize(&props); -+ return props.dictSize; -+} -+ -+/* #define LZMA_LOG_BSR */ -+/* Define it for Intel's CPU */ -+ -+ -+#ifdef LZMA_LOG_BSR -+ -+#define kDicLogSizeMaxCompress 30 -+ -+#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); } -+ -+UInt32 GetPosSlot1(UInt32 pos) -+{ -+ UInt32 res; -+ BSR2_RET(pos, res); -+ return res; -+} -+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } -+#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); } -+ -+#else -+ -+#define kNumLogBits (9 + (int)sizeof(size_t) / 2) -+#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) -+ -+static void LzmaEnc_FastPosInit(Byte *g_FastPos) -+{ -+ int c = 2, slotFast; -+ g_FastPos[0] = 0; -+ g_FastPos[1] = 1; -+ -+ for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++) -+ { -+ UInt32 k = (1 << ((slotFast >> 1) - 1)); -+ UInt32 j; -+ for (j = 0; j < k; j++, c++) -+ g_FastPos[c] = (Byte)slotFast; -+ } -+} -+ -+#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \ -+ (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \ -+ res = p->g_FastPos[pos >> i] + (i * 2); } -+/* -+#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \ -+ p->g_FastPos[pos >> 6] + 12 : \ -+ p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; } -+*/ -+ -+#define GetPosSlot1(pos) p->g_FastPos[pos] -+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } -+#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); } -+ -+#endif -+ -+ -+#define LZMA_NUM_REPS 4 -+ -+typedef unsigned CState; -+ -+typedef struct -+{ -+ UInt32 price; -+ -+ CState state; -+ int prev1IsChar; -+ int prev2; -+ -+ UInt32 posPrev2; -+ UInt32 backPrev2; -+ -+ UInt32 posPrev; -+ UInt32 backPrev; -+ UInt32 backs[LZMA_NUM_REPS]; -+} COptimal; -+ -+#define kNumOpts (1 << 12) -+ -+#define kNumLenToPosStates 4 -+#define kNumPosSlotBits 6 -+#define kDicLogSizeMin 0 -+#define kDicLogSizeMax 32 -+#define kDistTableSizeMax (kDicLogSizeMax * 2) -+ -+ -+#define kNumAlignBits 4 -+#define kAlignTableSize (1 << kNumAlignBits) -+#define kAlignMask (kAlignTableSize - 1) -+ -+#define kStartPosModelIndex 4 -+#define kEndPosModelIndex 14 -+#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex) -+ -+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) -+ -+#ifdef _LZMA_PROB32 -+#define CLzmaProb UInt32 -+#else -+#define CLzmaProb UInt16 -+#endif -+ -+#define LZMA_PB_MAX 4 -+#define LZMA_LC_MAX 8 -+#define LZMA_LP_MAX 4 -+ -+#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX) -+ -+ -+#define kLenNumLowBits 3 -+#define kLenNumLowSymbols (1 << kLenNumLowBits) -+#define kLenNumMidBits 3 -+#define kLenNumMidSymbols (1 << kLenNumMidBits) -+#define kLenNumHighBits 8 -+#define kLenNumHighSymbols (1 << kLenNumHighBits) -+ -+#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) -+ -+#define LZMA_MATCH_LEN_MIN 2 -+#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1) -+ -+#define kNumStates 12 -+ -+typedef struct -+{ -+ CLzmaProb choice; -+ CLzmaProb choice2; -+ CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits]; -+ CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits]; -+ CLzmaProb high[kLenNumHighSymbols]; -+} CLenEnc; -+ -+typedef struct -+{ -+ CLenEnc p; -+ UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal]; -+ UInt32 tableSize; -+ UInt32 counters[LZMA_NUM_PB_STATES_MAX]; -+} CLenPriceEnc; -+ -+typedef struct -+{ -+ UInt32 range; -+ Byte cache; -+ UInt64 low; -+ UInt64 cacheSize; -+ Byte *buf; -+ Byte *bufLim; -+ Byte *bufBase; -+ ISeqOutStream *outStream; -+ UInt64 processed; -+ SRes res; -+} CRangeEnc; -+ -+typedef struct -+{ -+ CLzmaProb *litProbs; -+ -+ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; -+ CLzmaProb isRep[kNumStates]; -+ CLzmaProb isRepG0[kNumStates]; -+ CLzmaProb isRepG1[kNumStates]; -+ CLzmaProb isRepG2[kNumStates]; -+ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; -+ -+ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; -+ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; -+ CLzmaProb posAlignEncoder[1 << kNumAlignBits]; -+ -+ CLenPriceEnc lenEnc; -+ CLenPriceEnc repLenEnc; -+ -+ UInt32 reps[LZMA_NUM_REPS]; -+ UInt32 state; -+} CSaveState; -+ -+typedef struct -+{ -+ IMatchFinder matchFinder; -+ void *matchFinderObj; -+ -+ #ifndef _7ZIP_ST -+ Bool mtMode; -+ CMatchFinderMt matchFinderMt; -+ #endif -+ -+ CMatchFinder matchFinderBase; -+ -+ #ifndef _7ZIP_ST -+ Byte pad[128]; -+ #endif -+ -+ UInt32 optimumEndIndex; -+ UInt32 optimumCurrentIndex; -+ -+ UInt32 longestMatchLength; -+ UInt32 numPairs; -+ UInt32 numAvail; -+ COptimal opt[kNumOpts]; -+ -+ #ifndef LZMA_LOG_BSR -+ Byte g_FastPos[1 << kNumLogBits]; -+ #endif -+ -+ UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; -+ UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1]; -+ UInt32 numFastBytes; -+ UInt32 additionalOffset; -+ UInt32 reps[LZMA_NUM_REPS]; -+ UInt32 state; -+ -+ UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; -+ UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances]; -+ UInt32 alignPrices[kAlignTableSize]; -+ UInt32 alignPriceCount; -+ -+ UInt32 distTableSize; -+ -+ unsigned lc, lp, pb; -+ unsigned lpMask, pbMask; -+ -+ CLzmaProb *litProbs; -+ -+ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; -+ CLzmaProb isRep[kNumStates]; -+ CLzmaProb isRepG0[kNumStates]; -+ CLzmaProb isRepG1[kNumStates]; -+ CLzmaProb isRepG2[kNumStates]; -+ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; -+ -+ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; -+ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; -+ CLzmaProb posAlignEncoder[1 << kNumAlignBits]; -+ -+ CLenPriceEnc lenEnc; -+ CLenPriceEnc repLenEnc; -+ -+ unsigned lclp; -+ -+ Bool fastMode; -+ -+ CRangeEnc rc; -+ -+ Bool writeEndMark; -+ UInt64 nowPos64; -+ UInt32 matchPriceCount; -+ Bool finished; -+ Bool multiThread; -+ -+ SRes result; -+ UInt32 dictSize; -+ UInt32 matchFinderCycles; -+ -+ int needInit; -+ -+ CSaveState saveState; -+} CLzmaEnc; -+ -+/*void LzmaEnc_SaveState(CLzmaEncHandle pp) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ CSaveState *dest = &p->saveState; -+ int i; -+ dest->lenEnc = p->lenEnc; -+ dest->repLenEnc = p->repLenEnc; -+ dest->state = p->state; -+ -+ for (i = 0; i < kNumStates; i++) -+ { -+ memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); -+ memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); -+ } -+ for (i = 0; i < kNumLenToPosStates; i++) -+ memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); -+ memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); -+ memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); -+ memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); -+ memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); -+ memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); -+ memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); -+ memcpy(dest->reps, p->reps, sizeof(p->reps)); -+ memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb)); -+}*/ -+ -+/*void LzmaEnc_RestoreState(CLzmaEncHandle pp) -+{ -+ CLzmaEnc *dest = (CLzmaEnc *)pp; -+ const CSaveState *p = &dest->saveState; -+ int i; -+ dest->lenEnc = p->lenEnc; -+ dest->repLenEnc = p->repLenEnc; -+ dest->state = p->state; -+ -+ for (i = 0; i < kNumStates; i++) -+ { -+ memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); -+ memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); -+ } -+ for (i = 0; i < kNumLenToPosStates; i++) -+ memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); -+ memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); -+ memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); -+ memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); -+ memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); -+ memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); -+ memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); -+ memcpy(dest->reps, p->reps, sizeof(p->reps)); -+ memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb)); -+}*/ -+ -+SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ CLzmaEncProps props = *props2; -+ LzmaEncProps_Normalize(&props); -+ -+ if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX || -+ props.dictSize > (1 << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30)) -+ return SZ_ERROR_PARAM; -+ p->dictSize = props.dictSize; -+ p->matchFinderCycles = props.mc; -+ { -+ unsigned fb = props.fb; -+ if (fb < 5) -+ fb = 5; -+ if (fb > LZMA_MATCH_LEN_MAX) -+ fb = LZMA_MATCH_LEN_MAX; -+ p->numFastBytes = fb; -+ } -+ p->lc = props.lc; -+ p->lp = props.lp; -+ p->pb = props.pb; -+ p->fastMode = (props.algo == 0); -+ p->matchFinderBase.btMode = props.btMode; -+ { -+ UInt32 numHashBytes = 4; -+ if (props.btMode) -+ { -+ if (props.numHashBytes < 2) -+ numHashBytes = 2; -+ else if (props.numHashBytes < 4) -+ numHashBytes = props.numHashBytes; -+ } -+ p->matchFinderBase.numHashBytes = numHashBytes; -+ } -+ -+ p->matchFinderBase.cutValue = props.mc; -+ -+ p->writeEndMark = props.writeEndMark; -+ -+ #ifndef _7ZIP_ST -+ /* -+ if (newMultiThread != _multiThread) -+ { -+ ReleaseMatchFinder(); -+ _multiThread = newMultiThread; -+ } -+ */ -+ p->multiThread = (props.numThreads > 1); -+ #endif -+ -+ return SZ_OK; -+} -+ -+static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5}; -+static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10}; -+static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; -+static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11}; -+ -+#define IsCharState(s) ((s) < 7) -+ -+#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1) -+ -+#define kInfinityPrice (1 << 30) -+ -+static void RangeEnc_Construct(CRangeEnc *p) -+{ -+ p->outStream = 0; -+ p->bufBase = 0; -+} -+ -+#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize) -+ -+#define RC_BUF_SIZE (1 << 16) -+static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc) -+{ -+ if (p->bufBase == 0) -+ { -+ p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE); -+ if (p->bufBase == 0) -+ return 0; -+ p->bufLim = p->bufBase + RC_BUF_SIZE; -+ } -+ return 1; -+} -+ -+static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc) -+{ -+ alloc->Free(alloc, p->bufBase); -+ p->bufBase = 0; -+} -+ -+static void RangeEnc_Init(CRangeEnc *p) -+{ -+ /* Stream.Init(); */ -+ p->low = 0; -+ p->range = 0xFFFFFFFF; -+ p->cacheSize = 1; -+ p->cache = 0; -+ -+ p->buf = p->bufBase; -+ -+ p->processed = 0; -+ p->res = SZ_OK; -+} -+ -+static void RangeEnc_FlushStream(CRangeEnc *p) -+{ -+ size_t num; -+ if (p->res != SZ_OK) -+ return; -+ num = p->buf - p->bufBase; -+ if (num != p->outStream->Write(p->outStream, p->bufBase, num)) -+ p->res = SZ_ERROR_WRITE; -+ p->processed += num; -+ p->buf = p->bufBase; -+} -+ -+static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p) -+{ -+ if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0) -+ { -+ Byte temp = p->cache; -+ do -+ { -+ Byte *buf = p->buf; -+ *buf++ = (Byte)(temp + (Byte)(p->low >> 32)); -+ p->buf = buf; -+ if (buf == p->bufLim) -+ RangeEnc_FlushStream(p); -+ temp = 0xFF; -+ } -+ while (--p->cacheSize != 0); -+ p->cache = (Byte)((UInt32)p->low >> 24); -+ } -+ p->cacheSize++; -+ p->low = (UInt32)p->low << 8; -+} -+ -+static void RangeEnc_FlushData(CRangeEnc *p) -+{ -+ int i; -+ for (i = 0; i < 5; i++) -+ RangeEnc_ShiftLow(p); -+} -+ -+static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits) -+{ -+ do -+ { -+ p->range >>= 1; -+ p->low += p->range & (0 - ((value >> --numBits) & 1)); -+ if (p->range < kTopValue) -+ { -+ p->range <<= 8; -+ RangeEnc_ShiftLow(p); -+ } -+ } -+ while (numBits != 0); -+} -+ -+static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol) -+{ -+ UInt32 ttt = *prob; -+ UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt; -+ if (symbol == 0) -+ { -+ p->range = newBound; -+ ttt += (kBitModelTotal - ttt) >> kNumMoveBits; -+ } -+ else -+ { -+ p->low += newBound; -+ p->range -= newBound; -+ ttt -= ttt >> kNumMoveBits; -+ } -+ *prob = (CLzmaProb)ttt; -+ if (p->range < kTopValue) -+ { -+ p->range <<= 8; -+ RangeEnc_ShiftLow(p); -+ } -+} -+ -+static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol) -+{ -+ symbol |= 0x100; -+ do -+ { -+ RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1); -+ symbol <<= 1; -+ } -+ while (symbol < 0x10000); -+} -+ -+static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte) -+{ -+ UInt32 offs = 0x100; -+ symbol |= 0x100; -+ do -+ { -+ matchByte <<= 1; -+ RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1); -+ symbol <<= 1; -+ offs &= ~(matchByte ^ symbol); -+ } -+ while (symbol < 0x10000); -+} -+ -+static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) -+{ -+ UInt32 i; -+ for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits)) -+ { -+ const int kCyclesBits = kNumBitPriceShiftBits; -+ UInt32 w = i; -+ UInt32 bitCount = 0; -+ int j; -+ for (j = 0; j < kCyclesBits; j++) -+ { -+ w = w * w; -+ bitCount <<= 1; -+ while (w >= ((UInt32)1 << 16)) -+ { -+ w >>= 1; -+ bitCount++; -+ } -+ } -+ ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount); -+ } -+} -+ -+ -+#define GET_PRICE(prob, symbol) \ -+ p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; -+ -+#define GET_PRICEa(prob, symbol) \ -+ ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; -+ -+#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits] -+#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] -+ -+#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits] -+#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] -+ -+static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices) -+{ -+ UInt32 price = 0; -+ symbol |= 0x100; -+ do -+ { -+ price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1); -+ symbol <<= 1; -+ } -+ while (symbol < 0x10000); -+ return price; -+} -+ -+static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices) -+{ -+ UInt32 price = 0; -+ UInt32 offs = 0x100; -+ symbol |= 0x100; -+ do -+ { -+ matchByte <<= 1; -+ price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1); -+ symbol <<= 1; -+ offs &= ~(matchByte ^ symbol); -+ } -+ while (symbol < 0x10000); -+ return price; -+} -+ -+ -+static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) -+{ -+ UInt32 m = 1; -+ int i; -+ for (i = numBitLevels; i != 0;) -+ { -+ UInt32 bit; -+ i--; -+ bit = (symbol >> i) & 1; -+ RangeEnc_EncodeBit(rc, probs + m, bit); -+ m = (m << 1) | bit; -+ } -+} -+ -+static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) -+{ -+ UInt32 m = 1; -+ int i; -+ for (i = 0; i < numBitLevels; i++) -+ { -+ UInt32 bit = symbol & 1; -+ RangeEnc_EncodeBit(rc, probs + m, bit); -+ m = (m << 1) | bit; -+ symbol >>= 1; -+ } -+} -+ -+static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) -+{ -+ UInt32 price = 0; -+ symbol |= (1 << numBitLevels); -+ while (symbol != 1) -+ { -+ price += GET_PRICEa(probs[symbol >> 1], symbol & 1); -+ symbol >>= 1; -+ } -+ return price; -+} -+ -+static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) -+{ -+ UInt32 price = 0; -+ UInt32 m = 1; -+ int i; -+ for (i = numBitLevels; i != 0; i--) -+ { -+ UInt32 bit = symbol & 1; -+ symbol >>= 1; -+ price += GET_PRICEa(probs[m], bit); -+ m = (m << 1) | bit; -+ } -+ return price; -+} -+ -+ -+static void LenEnc_Init(CLenEnc *p) -+{ -+ unsigned i; -+ p->choice = p->choice2 = kProbInitValue; -+ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++) -+ p->low[i] = kProbInitValue; -+ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++) -+ p->mid[i] = kProbInitValue; -+ for (i = 0; i < kLenNumHighSymbols; i++) -+ p->high[i] = kProbInitValue; -+} -+ -+static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState) -+{ -+ if (symbol < kLenNumLowSymbols) -+ { -+ RangeEnc_EncodeBit(rc, &p->choice, 0); -+ RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol); -+ } -+ else -+ { -+ RangeEnc_EncodeBit(rc, &p->choice, 1); -+ if (symbol < kLenNumLowSymbols + kLenNumMidSymbols) -+ { -+ RangeEnc_EncodeBit(rc, &p->choice2, 0); -+ RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols); -+ } -+ else -+ { -+ RangeEnc_EncodeBit(rc, &p->choice2, 1); -+ RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols); -+ } -+ } -+} -+ -+static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices) -+{ -+ UInt32 a0 = GET_PRICE_0a(p->choice); -+ UInt32 a1 = GET_PRICE_1a(p->choice); -+ UInt32 b0 = a1 + GET_PRICE_0a(p->choice2); -+ UInt32 b1 = a1 + GET_PRICE_1a(p->choice2); -+ UInt32 i = 0; -+ for (i = 0; i < kLenNumLowSymbols; i++) -+ { -+ if (i >= numSymbols) -+ return; -+ prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices); -+ } -+ for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++) -+ { -+ if (i >= numSymbols) -+ return; -+ prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices); -+ } -+ for (; i < numSymbols; i++) -+ prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices); -+} -+ -+static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices) -+{ -+ LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices); -+ p->counters[posState] = p->tableSize; -+} -+ -+static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices) -+{ -+ UInt32 posState; -+ for (posState = 0; posState < numPosStates; posState++) -+ LenPriceEnc_UpdateTable(p, posState, ProbPrices); -+} -+ -+static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices) -+{ -+ LenEnc_Encode(&p->p, rc, symbol, posState); -+ if (updatePrice) -+ if (--p->counters[posState] == 0) -+ LenPriceEnc_UpdateTable(p, posState, ProbPrices); -+} -+ -+ -+ -+ -+static void MovePos(CLzmaEnc *p, UInt32 num) -+{ -+ #ifdef SHOW_STAT -+ ttt += num; -+ printf("\n MovePos %d", num); -+ #endif -+ if (num != 0) -+ { -+ p->additionalOffset += num; -+ p->matchFinder.Skip(p->matchFinderObj, num); -+ } -+} -+ -+static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes) -+{ -+ UInt32 lenRes = 0, numPairs; -+ p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); -+ numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches); -+ #ifdef SHOW_STAT -+ printf("\n i = %d numPairs = %d ", ttt, numPairs / 2); -+ ttt++; -+ { -+ UInt32 i; -+ for (i = 0; i < numPairs; i += 2) -+ printf("%2d %6d | ", p->matches[i], p->matches[i + 1]); -+ } -+ #endif -+ if (numPairs > 0) -+ { -+ lenRes = p->matches[numPairs - 2]; -+ if (lenRes == p->numFastBytes) -+ { -+ const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -+ UInt32 distance = p->matches[numPairs - 1] + 1; -+ UInt32 numAvail = p->numAvail; -+ if (numAvail > LZMA_MATCH_LEN_MAX) -+ numAvail = LZMA_MATCH_LEN_MAX; -+ { -+ const Byte *pby2 = pby - distance; -+ for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++); -+ } -+ } -+ } -+ p->additionalOffset++; -+ *numDistancePairsRes = numPairs; -+ return lenRes; -+} -+ -+ -+#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False; -+#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False; -+#define IsShortRep(p) ((p)->backPrev == 0) -+ -+static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState) -+{ -+ return -+ GET_PRICE_0(p->isRepG0[state]) + -+ GET_PRICE_0(p->isRep0Long[state][posState]); -+} -+ -+static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState) -+{ -+ UInt32 price; -+ if (repIndex == 0) -+ { -+ price = GET_PRICE_0(p->isRepG0[state]); -+ price += GET_PRICE_1(p->isRep0Long[state][posState]); -+ } -+ else -+ { -+ price = GET_PRICE_1(p->isRepG0[state]); -+ if (repIndex == 1) -+ price += GET_PRICE_0(p->isRepG1[state]); -+ else -+ { -+ price += GET_PRICE_1(p->isRepG1[state]); -+ price += GET_PRICE(p->isRepG2[state], repIndex - 2); -+ } -+ } -+ return price; -+} -+ -+static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState) -+{ -+ return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] + -+ GetPureRepPrice(p, repIndex, state, posState); -+} -+ -+static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur) -+{ -+ UInt32 posMem = p->opt[cur].posPrev; -+ UInt32 backMem = p->opt[cur].backPrev; -+ p->optimumEndIndex = cur; -+ do -+ { -+ if (p->opt[cur].prev1IsChar) -+ { -+ MakeAsChar(&p->opt[posMem]) -+ p->opt[posMem].posPrev = posMem - 1; -+ if (p->opt[cur].prev2) -+ { -+ p->opt[posMem - 1].prev1IsChar = False; -+ p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2; -+ p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2; -+ } -+ } -+ { -+ UInt32 posPrev = posMem; -+ UInt32 backCur = backMem; -+ -+ backMem = p->opt[posPrev].backPrev; -+ posMem = p->opt[posPrev].posPrev; -+ -+ p->opt[posPrev].backPrev = backCur; -+ p->opt[posPrev].posPrev = cur; -+ cur = posPrev; -+ } -+ } -+ while (cur != 0); -+ *backRes = p->opt[0].backPrev; -+ p->optimumCurrentIndex = p->opt[0].posPrev; -+ return p->optimumCurrentIndex; -+} -+ -+#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300) -+ -+static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) -+{ -+ UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur; -+ UInt32 matchPrice, repMatchPrice, normalMatchPrice; -+ UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS]; -+ UInt32 *matches; -+ const Byte *data; -+ Byte curByte, matchByte; -+ if (p->optimumEndIndex != p->optimumCurrentIndex) -+ { -+ const COptimal *opt = &p->opt[p->optimumCurrentIndex]; -+ UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex; -+ *backRes = opt->backPrev; -+ p->optimumCurrentIndex = opt->posPrev; -+ return lenRes; -+ } -+ p->optimumCurrentIndex = p->optimumEndIndex = 0; -+ -+ if (p->additionalOffset == 0) -+ mainLen = ReadMatchDistances(p, &numPairs); -+ else -+ { -+ mainLen = p->longestMatchLength; -+ numPairs = p->numPairs; -+ } -+ -+ numAvail = p->numAvail; -+ if (numAvail < 2) -+ { -+ *backRes = (UInt32)(-1); -+ return 1; -+ } -+ if (numAvail > LZMA_MATCH_LEN_MAX) -+ numAvail = LZMA_MATCH_LEN_MAX; -+ -+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -+ repMaxIndex = 0; -+ for (i = 0; i < LZMA_NUM_REPS; i++) -+ { -+ UInt32 lenTest; -+ const Byte *data2; -+ reps[i] = p->reps[i]; -+ data2 = data - (reps[i] + 1); -+ if (data[0] != data2[0] || data[1] != data2[1]) -+ { -+ repLens[i] = 0; -+ continue; -+ } -+ for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); -+ repLens[i] = lenTest; -+ if (lenTest > repLens[repMaxIndex]) -+ repMaxIndex = i; -+ } -+ if (repLens[repMaxIndex] >= p->numFastBytes) -+ { -+ UInt32 lenRes; -+ *backRes = repMaxIndex; -+ lenRes = repLens[repMaxIndex]; -+ MovePos(p, lenRes - 1); -+ return lenRes; -+ } -+ -+ matches = p->matches; -+ if (mainLen >= p->numFastBytes) -+ { -+ *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; -+ MovePos(p, mainLen - 1); -+ return mainLen; -+ } -+ curByte = *data; -+ matchByte = *(data - (reps[0] + 1)); -+ -+ if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2) -+ { -+ *backRes = (UInt32)-1; -+ return 1; -+ } -+ -+ p->opt[0].state = (CState)p->state; -+ -+ posState = (position & p->pbMask); -+ -+ { -+ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); -+ p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) + -+ (!IsCharState(p->state) ? -+ LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : -+ LitEnc_GetPrice(probs, curByte, p->ProbPrices)); -+ } -+ -+ MakeAsChar(&p->opt[1]); -+ -+ matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]); -+ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]); -+ -+ if (matchByte == curByte) -+ { -+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState); -+ if (shortRepPrice < p->opt[1].price) -+ { -+ p->opt[1].price = shortRepPrice; -+ MakeAsShortRep(&p->opt[1]); -+ } -+ } -+ lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]); -+ -+ if (lenEnd < 2) -+ { -+ *backRes = p->opt[1].backPrev; -+ return 1; -+ } -+ -+ p->opt[1].posPrev = 0; -+ for (i = 0; i < LZMA_NUM_REPS; i++) -+ p->opt[0].backs[i] = reps[i]; -+ -+ len = lenEnd; -+ do -+ p->opt[len--].price = kInfinityPrice; -+ while (len >= 2); -+ -+ for (i = 0; i < LZMA_NUM_REPS; i++) -+ { -+ UInt32 repLen = repLens[i]; -+ UInt32 price; -+ if (repLen < 2) -+ continue; -+ price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState); -+ do -+ { -+ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2]; -+ COptimal *opt = &p->opt[repLen]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = 0; -+ opt->backPrev = i; -+ opt->prev1IsChar = False; -+ } -+ } -+ while (--repLen >= 2); -+ } -+ -+ normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]); -+ -+ len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2); -+ if (len <= mainLen) -+ { -+ UInt32 offs = 0; -+ while (len > matches[offs]) -+ offs += 2; -+ for (; ; len++) -+ { -+ COptimal *opt; -+ UInt32 distance = matches[offs + 1]; -+ -+ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN]; -+ UInt32 lenToPosState = GetLenToPosState(len); -+ if (distance < kNumFullDistances) -+ curAndLenPrice += p->distancesPrices[lenToPosState][distance]; -+ else -+ { -+ UInt32 slot; -+ GetPosSlot2(distance, slot); -+ curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot]; -+ } -+ opt = &p->opt[len]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = 0; -+ opt->backPrev = distance + LZMA_NUM_REPS; -+ opt->prev1IsChar = False; -+ } -+ if (len == matches[offs]) -+ { -+ offs += 2; -+ if (offs == numPairs) -+ break; -+ } -+ } -+ } -+ -+ cur = 0; -+ -+ #ifdef SHOW_STAT2 -+ if (position >= 0) -+ { -+ unsigned i; -+ printf("\n pos = %4X", position); -+ for (i = cur; i <= lenEnd; i++) -+ printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price); -+ } -+ #endif -+ -+ for (;;) -+ { -+ UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen; -+ UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice; -+ Bool nextIsChar; -+ Byte curByte, matchByte; -+ const Byte *data; -+ COptimal *curOpt; -+ COptimal *nextOpt; -+ -+ cur++; -+ if (cur == lenEnd) -+ return Backward(p, backRes, cur); -+ -+ newLen = ReadMatchDistances(p, &numPairs); -+ if (newLen >= p->numFastBytes) -+ { -+ p->numPairs = numPairs; -+ p->longestMatchLength = newLen; -+ return Backward(p, backRes, cur); -+ } -+ position++; -+ curOpt = &p->opt[cur]; -+ posPrev = curOpt->posPrev; -+ if (curOpt->prev1IsChar) -+ { -+ posPrev--; -+ if (curOpt->prev2) -+ { -+ state = p->opt[curOpt->posPrev2].state; -+ if (curOpt->backPrev2 < LZMA_NUM_REPS) -+ state = kRepNextStates[state]; -+ else -+ state = kMatchNextStates[state]; -+ } -+ else -+ state = p->opt[posPrev].state; -+ state = kLiteralNextStates[state]; -+ } -+ else -+ state = p->opt[posPrev].state; -+ if (posPrev == cur - 1) -+ { -+ if (IsShortRep(curOpt)) -+ state = kShortRepNextStates[state]; -+ else -+ state = kLiteralNextStates[state]; -+ } -+ else -+ { -+ UInt32 pos; -+ const COptimal *prevOpt; -+ if (curOpt->prev1IsChar && curOpt->prev2) -+ { -+ posPrev = curOpt->posPrev2; -+ pos = curOpt->backPrev2; -+ state = kRepNextStates[state]; -+ } -+ else -+ { -+ pos = curOpt->backPrev; -+ if (pos < LZMA_NUM_REPS) -+ state = kRepNextStates[state]; -+ else -+ state = kMatchNextStates[state]; -+ } -+ prevOpt = &p->opt[posPrev]; -+ if (pos < LZMA_NUM_REPS) -+ { -+ UInt32 i; -+ reps[0] = prevOpt->backs[pos]; -+ for (i = 1; i <= pos; i++) -+ reps[i] = prevOpt->backs[i - 1]; -+ for (; i < LZMA_NUM_REPS; i++) -+ reps[i] = prevOpt->backs[i]; -+ } -+ else -+ { -+ UInt32 i; -+ reps[0] = (pos - LZMA_NUM_REPS); -+ for (i = 1; i < LZMA_NUM_REPS; i++) -+ reps[i] = prevOpt->backs[i - 1]; -+ } -+ } -+ curOpt->state = (CState)state; -+ -+ curOpt->backs[0] = reps[0]; -+ curOpt->backs[1] = reps[1]; -+ curOpt->backs[2] = reps[2]; -+ curOpt->backs[3] = reps[3]; -+ -+ curPrice = curOpt->price; -+ nextIsChar = False; -+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -+ curByte = *data; -+ matchByte = *(data - (reps[0] + 1)); -+ -+ posState = (position & p->pbMask); -+ -+ curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]); -+ { -+ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); -+ curAnd1Price += -+ (!IsCharState(state) ? -+ LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : -+ LitEnc_GetPrice(probs, curByte, p->ProbPrices)); -+ } -+ -+ nextOpt = &p->opt[cur + 1]; -+ -+ if (curAnd1Price < nextOpt->price) -+ { -+ nextOpt->price = curAnd1Price; -+ nextOpt->posPrev = cur; -+ MakeAsChar(nextOpt); -+ nextIsChar = True; -+ } -+ -+ matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]); -+ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]); -+ -+ if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0)) -+ { -+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState); -+ if (shortRepPrice <= nextOpt->price) -+ { -+ nextOpt->price = shortRepPrice; -+ nextOpt->posPrev = cur; -+ MakeAsShortRep(nextOpt); -+ nextIsChar = True; -+ } -+ } -+ numAvailFull = p->numAvail; -+ { -+ UInt32 temp = kNumOpts - 1 - cur; -+ if (temp < numAvailFull) -+ numAvailFull = temp; -+ } -+ -+ if (numAvailFull < 2) -+ continue; -+ numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes); -+ -+ if (!nextIsChar && matchByte != curByte) /* speed optimization */ -+ { -+ /* try Literal + rep0 */ -+ UInt32 temp; -+ UInt32 lenTest2; -+ const Byte *data2 = data - (reps[0] + 1); -+ UInt32 limit = p->numFastBytes + 1; -+ if (limit > numAvailFull) -+ limit = numAvailFull; -+ -+ for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++); -+ lenTest2 = temp - 1; -+ if (lenTest2 >= 2) -+ { -+ UInt32 state2 = kLiteralNextStates[state]; -+ UInt32 posStateNext = (position + 1) & p->pbMask; -+ UInt32 nextRepMatchPrice = curAnd1Price + -+ GET_PRICE_1(p->isMatch[state2][posStateNext]) + -+ GET_PRICE_1(p->isRep[state2]); -+ /* for (; lenTest2 >= 2; lenTest2--) */ -+ { -+ UInt32 curAndLenPrice; -+ COptimal *opt; -+ UInt32 offset = cur + 1 + lenTest2; -+ while (lenEnd < offset) -+ p->opt[++lenEnd].price = kInfinityPrice; -+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); -+ opt = &p->opt[offset]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = cur + 1; -+ opt->backPrev = 0; -+ opt->prev1IsChar = True; -+ opt->prev2 = False; -+ } -+ } -+ } -+ } -+ -+ startLen = 2; /* speed optimization */ -+ { -+ UInt32 repIndex; -+ for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++) -+ { -+ UInt32 lenTest; -+ UInt32 lenTestTemp; -+ UInt32 price; -+ const Byte *data2 = data - (reps[repIndex] + 1); -+ if (data[0] != data2[0] || data[1] != data2[1]) -+ continue; -+ for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); -+ while (lenEnd < cur + lenTest) -+ p->opt[++lenEnd].price = kInfinityPrice; -+ lenTestTemp = lenTest; -+ price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState); -+ do -+ { -+ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2]; -+ COptimal *opt = &p->opt[cur + lenTest]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = cur; -+ opt->backPrev = repIndex; -+ opt->prev1IsChar = False; -+ } -+ } -+ while (--lenTest >= 2); -+ lenTest = lenTestTemp; -+ -+ if (repIndex == 0) -+ startLen = lenTest + 1; -+ -+ /* if (_maxMode) */ -+ { -+ UInt32 lenTest2 = lenTest + 1; -+ UInt32 limit = lenTest2 + p->numFastBytes; -+ UInt32 nextRepMatchPrice; -+ if (limit > numAvailFull) -+ limit = numAvailFull; -+ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); -+ lenTest2 -= lenTest + 1; -+ if (lenTest2 >= 2) -+ { -+ UInt32 state2 = kRepNextStates[state]; -+ UInt32 posStateNext = (position + lenTest) & p->pbMask; -+ UInt32 curAndLenCharPrice = -+ price + p->repLenEnc.prices[posState][lenTest - 2] + -+ GET_PRICE_0(p->isMatch[state2][posStateNext]) + -+ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), -+ data[lenTest], data2[lenTest], p->ProbPrices); -+ state2 = kLiteralNextStates[state2]; -+ posStateNext = (position + lenTest + 1) & p->pbMask; -+ nextRepMatchPrice = curAndLenCharPrice + -+ GET_PRICE_1(p->isMatch[state2][posStateNext]) + -+ GET_PRICE_1(p->isRep[state2]); -+ -+ /* for (; lenTest2 >= 2; lenTest2--) */ -+ { -+ UInt32 curAndLenPrice; -+ COptimal *opt; -+ UInt32 offset = cur + lenTest + 1 + lenTest2; -+ while (lenEnd < offset) -+ p->opt[++lenEnd].price = kInfinityPrice; -+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); -+ opt = &p->opt[offset]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = cur + lenTest + 1; -+ opt->backPrev = 0; -+ opt->prev1IsChar = True; -+ opt->prev2 = True; -+ opt->posPrev2 = cur; -+ opt->backPrev2 = repIndex; -+ } -+ } -+ } -+ } -+ } -+ } -+ /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */ -+ if (newLen > numAvail) -+ { -+ newLen = numAvail; -+ for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2); -+ matches[numPairs] = newLen; -+ numPairs += 2; -+ } -+ if (newLen >= startLen) -+ { -+ UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]); -+ UInt32 offs, curBack, posSlot; -+ UInt32 lenTest; -+ while (lenEnd < cur + newLen) -+ p->opt[++lenEnd].price = kInfinityPrice; -+ -+ offs = 0; -+ while (startLen > matches[offs]) -+ offs += 2; -+ curBack = matches[offs + 1]; -+ GetPosSlot2(curBack, posSlot); -+ for (lenTest = /*2*/ startLen; ; lenTest++) -+ { -+ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN]; -+ UInt32 lenToPosState = GetLenToPosState(lenTest); -+ COptimal *opt; -+ if (curBack < kNumFullDistances) -+ curAndLenPrice += p->distancesPrices[lenToPosState][curBack]; -+ else -+ curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask]; -+ -+ opt = &p->opt[cur + lenTest]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = cur; -+ opt->backPrev = curBack + LZMA_NUM_REPS; -+ opt->prev1IsChar = False; -+ } -+ -+ if (/*_maxMode && */lenTest == matches[offs]) -+ { -+ /* Try Match + Literal + Rep0 */ -+ const Byte *data2 = data - (curBack + 1); -+ UInt32 lenTest2 = lenTest + 1; -+ UInt32 limit = lenTest2 + p->numFastBytes; -+ UInt32 nextRepMatchPrice; -+ if (limit > numAvailFull) -+ limit = numAvailFull; -+ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); -+ lenTest2 -= lenTest + 1; -+ if (lenTest2 >= 2) -+ { -+ UInt32 state2 = kMatchNextStates[state]; -+ UInt32 posStateNext = (position + lenTest) & p->pbMask; -+ UInt32 curAndLenCharPrice = curAndLenPrice + -+ GET_PRICE_0(p->isMatch[state2][posStateNext]) + -+ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), -+ data[lenTest], data2[lenTest], p->ProbPrices); -+ state2 = kLiteralNextStates[state2]; -+ posStateNext = (posStateNext + 1) & p->pbMask; -+ nextRepMatchPrice = curAndLenCharPrice + -+ GET_PRICE_1(p->isMatch[state2][posStateNext]) + -+ GET_PRICE_1(p->isRep[state2]); -+ -+ /* for (; lenTest2 >= 2; lenTest2--) */ -+ { -+ UInt32 offset = cur + lenTest + 1 + lenTest2; -+ UInt32 curAndLenPrice; -+ COptimal *opt; -+ while (lenEnd < offset) -+ p->opt[++lenEnd].price = kInfinityPrice; -+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); -+ opt = &p->opt[offset]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = cur + lenTest + 1; -+ opt->backPrev = 0; -+ opt->prev1IsChar = True; -+ opt->prev2 = True; -+ opt->posPrev2 = cur; -+ opt->backPrev2 = curBack + LZMA_NUM_REPS; -+ } -+ } -+ } -+ offs += 2; -+ if (offs == numPairs) -+ break; -+ curBack = matches[offs + 1]; -+ if (curBack >= kNumFullDistances) -+ GetPosSlot2(curBack, posSlot); -+ } -+ } -+ } -+ } -+} -+ -+#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist)) -+ -+static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes) -+{ -+ UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i; -+ const Byte *data; -+ const UInt32 *matches; -+ -+ if (p->additionalOffset == 0) -+ mainLen = ReadMatchDistances(p, &numPairs); -+ else -+ { -+ mainLen = p->longestMatchLength; -+ numPairs = p->numPairs; -+ } -+ -+ numAvail = p->numAvail; -+ *backRes = (UInt32)-1; -+ if (numAvail < 2) -+ return 1; -+ if (numAvail > LZMA_MATCH_LEN_MAX) -+ numAvail = LZMA_MATCH_LEN_MAX; -+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -+ -+ repLen = repIndex = 0; -+ for (i = 0; i < LZMA_NUM_REPS; i++) -+ { -+ UInt32 len; -+ const Byte *data2 = data - (p->reps[i] + 1); -+ if (data[0] != data2[0] || data[1] != data2[1]) -+ continue; -+ for (len = 2; len < numAvail && data[len] == data2[len]; len++); -+ if (len >= p->numFastBytes) -+ { -+ *backRes = i; -+ MovePos(p, len - 1); -+ return len; -+ } -+ if (len > repLen) -+ { -+ repIndex = i; -+ repLen = len; -+ } -+ } -+ -+ matches = p->matches; -+ if (mainLen >= p->numFastBytes) -+ { -+ *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; -+ MovePos(p, mainLen - 1); -+ return mainLen; -+ } -+ -+ mainDist = 0; /* for GCC */ -+ if (mainLen >= 2) -+ { -+ mainDist = matches[numPairs - 1]; -+ while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1) -+ { -+ if (!ChangePair(matches[numPairs - 3], mainDist)) -+ break; -+ numPairs -= 2; -+ mainLen = matches[numPairs - 2]; -+ mainDist = matches[numPairs - 1]; -+ } -+ if (mainLen == 2 && mainDist >= 0x80) -+ mainLen = 1; -+ } -+ -+ if (repLen >= 2 && ( -+ (repLen + 1 >= mainLen) || -+ (repLen + 2 >= mainLen && mainDist >= (1 << 9)) || -+ (repLen + 3 >= mainLen && mainDist >= (1 << 15)))) -+ { -+ *backRes = repIndex; -+ MovePos(p, repLen - 1); -+ return repLen; -+ } -+ -+ if (mainLen < 2 || numAvail <= 2) -+ return 1; -+ -+ p->longestMatchLength = ReadMatchDistances(p, &p->numPairs); -+ if (p->longestMatchLength >= 2) -+ { -+ UInt32 newDistance = matches[p->numPairs - 1]; -+ if ((p->longestMatchLength >= mainLen && newDistance < mainDist) || -+ (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) || -+ (p->longestMatchLength > mainLen + 1) || -+ (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist))) -+ return 1; -+ } -+ -+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -+ for (i = 0; i < LZMA_NUM_REPS; i++) -+ { -+ UInt32 len, limit; -+ const Byte *data2 = data - (p->reps[i] + 1); -+ if (data[0] != data2[0] || data[1] != data2[1]) -+ continue; -+ limit = mainLen - 1; -+ for (len = 2; len < limit && data[len] == data2[len]; len++); -+ if (len >= limit) -+ return 1; -+ } -+ *backRes = mainDist + LZMA_NUM_REPS; -+ MovePos(p, mainLen - 2); -+ return mainLen; -+} -+ -+static void WriteEndMarker(CLzmaEnc *p, UInt32 posState) -+{ -+ UInt32 len; -+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); -+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); -+ p->state = kMatchNextStates[p->state]; -+ len = LZMA_MATCH_LEN_MIN; -+ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); -+ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1); -+ RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits); -+ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask); -+} -+ -+static SRes CheckErrors(CLzmaEnc *p) -+{ -+ if (p->result != SZ_OK) -+ return p->result; -+ if (p->rc.res != SZ_OK) -+ p->result = SZ_ERROR_WRITE; -+ if (p->matchFinderBase.result != SZ_OK) -+ p->result = SZ_ERROR_READ; -+ if (p->result != SZ_OK) -+ p->finished = True; -+ return p->result; -+} -+ -+static SRes Flush(CLzmaEnc *p, UInt32 nowPos) -+{ -+ /* ReleaseMFStream(); */ -+ p->finished = True; -+ if (p->writeEndMark) -+ WriteEndMarker(p, nowPos & p->pbMask); -+ RangeEnc_FlushData(&p->rc); -+ RangeEnc_FlushStream(&p->rc); -+ return CheckErrors(p); -+} -+ -+static void FillAlignPrices(CLzmaEnc *p) -+{ -+ UInt32 i; -+ for (i = 0; i < kAlignTableSize; i++) -+ p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices); -+ p->alignPriceCount = 0; -+} -+ -+static void FillDistancesPrices(CLzmaEnc *p) -+{ -+ UInt32 tempPrices[kNumFullDistances]; -+ UInt32 i, lenToPosState; -+ for (i = kStartPosModelIndex; i < kNumFullDistances; i++) -+ { -+ UInt32 posSlot = GetPosSlot1(i); -+ UInt32 footerBits = ((posSlot >> 1) - 1); -+ UInt32 base = ((2 | (posSlot & 1)) << footerBits); -+ tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices); -+ } -+ -+ for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++) -+ { -+ UInt32 posSlot; -+ const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState]; -+ UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState]; -+ for (posSlot = 0; posSlot < p->distTableSize; posSlot++) -+ posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices); -+ for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++) -+ posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits); -+ -+ { -+ UInt32 *distancesPrices = p->distancesPrices[lenToPosState]; -+ UInt32 i; -+ for (i = 0; i < kStartPosModelIndex; i++) -+ distancesPrices[i] = posSlotPrices[i]; -+ for (; i < kNumFullDistances; i++) -+ distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i]; -+ } -+ } -+ p->matchPriceCount = 0; -+} -+ -+static void LzmaEnc_Construct(CLzmaEnc *p) -+{ -+ RangeEnc_Construct(&p->rc); -+ MatchFinder_Construct(&p->matchFinderBase); -+ #ifndef _7ZIP_ST -+ MatchFinderMt_Construct(&p->matchFinderMt); -+ p->matchFinderMt.MatchFinder = &p->matchFinderBase; -+ #endif -+ -+ { -+ CLzmaEncProps props; -+ LzmaEncProps_Init(&props); -+ LzmaEnc_SetProps(p, &props); -+ } -+ -+ #ifndef LZMA_LOG_BSR -+ LzmaEnc_FastPosInit(p->g_FastPos); -+ #endif -+ -+ LzmaEnc_InitPriceTables(p->ProbPrices); -+ p->litProbs = 0; -+ p->saveState.litProbs = 0; -+} -+ -+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc) -+{ -+ void *p; -+ p = alloc->Alloc(alloc, sizeof(CLzmaEnc)); -+ if (p != 0) -+ LzmaEnc_Construct((CLzmaEnc *)p); -+ return p; -+} -+ -+static void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) -+{ -+ alloc->Free(alloc, p->litProbs); -+ alloc->Free(alloc, p->saveState.litProbs); -+ p->litProbs = 0; -+ p->saveState.litProbs = 0; -+} -+ -+static void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ #ifndef _7ZIP_ST -+ MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); -+ #endif -+ MatchFinder_Free(&p->matchFinderBase, allocBig); -+ LzmaEnc_FreeLits(p, alloc); -+ RangeEnc_Free(&p->rc, alloc); -+} -+ -+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig); -+ alloc->Free(alloc, p); -+} -+ -+static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize) -+{ -+ UInt32 nowPos32, startPos32; -+ if (p->needInit) -+ { -+ p->matchFinder.Init(p->matchFinderObj); -+ p->needInit = 0; -+ } -+ -+ if (p->finished) -+ return p->result; -+ RINOK(CheckErrors(p)); -+ -+ nowPos32 = (UInt32)p->nowPos64; -+ startPos32 = nowPos32; -+ -+ if (p->nowPos64 == 0) -+ { -+ UInt32 numPairs; -+ Byte curByte; -+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) -+ return Flush(p, nowPos32); -+ ReadMatchDistances(p, &numPairs); -+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0); -+ p->state = kLiteralNextStates[p->state]; -+ curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset); -+ LitEnc_Encode(&p->rc, p->litProbs, curByte); -+ p->additionalOffset--; -+ nowPos32++; -+ } -+ -+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0) -+ for (;;) -+ { -+ UInt32 pos, len, posState; -+ -+ if (p->fastMode) -+ len = GetOptimumFast(p, &pos); -+ else -+ len = GetOptimum(p, nowPos32, &pos); -+ -+ #ifdef SHOW_STAT2 -+ printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos); -+ #endif -+ -+ posState = nowPos32 & p->pbMask; -+ if (len == 1 && pos == (UInt32)-1) -+ { -+ Byte curByte; -+ CLzmaProb *probs; -+ const Byte *data; -+ -+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0); -+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; -+ curByte = *data; -+ probs = LIT_PROBS(nowPos32, *(data - 1)); -+ if (IsCharState(p->state)) -+ LitEnc_Encode(&p->rc, probs, curByte); -+ else -+ LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1)); -+ p->state = kLiteralNextStates[p->state]; -+ } -+ else -+ { -+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); -+ if (pos < LZMA_NUM_REPS) -+ { -+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1); -+ if (pos == 0) -+ { -+ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0); -+ RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1)); -+ } -+ else -+ { -+ UInt32 distance = p->reps[pos]; -+ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1); -+ if (pos == 1) -+ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0); -+ else -+ { -+ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1); -+ RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2); -+ if (pos == 3) -+ p->reps[3] = p->reps[2]; -+ p->reps[2] = p->reps[1]; -+ } -+ p->reps[1] = p->reps[0]; -+ p->reps[0] = distance; -+ } -+ if (len == 1) -+ p->state = kShortRepNextStates[p->state]; -+ else -+ { -+ LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); -+ p->state = kRepNextStates[p->state]; -+ } -+ } -+ else -+ { -+ UInt32 posSlot; -+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); -+ p->state = kMatchNextStates[p->state]; -+ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); -+ pos -= LZMA_NUM_REPS; -+ GetPosSlot(pos, posSlot); -+ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot); -+ -+ if (posSlot >= kStartPosModelIndex) -+ { -+ UInt32 footerBits = ((posSlot >> 1) - 1); -+ UInt32 base = ((2 | (posSlot & 1)) << footerBits); -+ UInt32 posReduced = pos - base; -+ -+ if (posSlot < kEndPosModelIndex) -+ RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced); -+ else -+ { -+ RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits); -+ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask); -+ p->alignPriceCount++; -+ } -+ } -+ p->reps[3] = p->reps[2]; -+ p->reps[2] = p->reps[1]; -+ p->reps[1] = p->reps[0]; -+ p->reps[0] = pos; -+ p->matchPriceCount++; -+ } -+ } -+ p->additionalOffset -= len; -+ nowPos32 += len; -+ if (p->additionalOffset == 0) -+ { -+ UInt32 processed; -+ if (!p->fastMode) -+ { -+ if (p->matchPriceCount >= (1 << 7)) -+ FillDistancesPrices(p); -+ if (p->alignPriceCount >= kAlignTableSize) -+ FillAlignPrices(p); -+ } -+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) -+ break; -+ processed = nowPos32 - startPos32; -+ if (useLimits) -+ { -+ if (processed + kNumOpts + 300 >= maxUnpackSize || -+ RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize) -+ break; -+ } -+ else if (processed >= (1 << 15)) -+ { -+ p->nowPos64 += nowPos32 - startPos32; -+ return CheckErrors(p); -+ } -+ } -+ } -+ p->nowPos64 += nowPos32 - startPos32; -+ return Flush(p, nowPos32); -+} -+ -+#define kBigHashDicLimit ((UInt32)1 << 24) -+ -+static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ UInt32 beforeSize = kNumOpts; -+ Bool btMode; -+ if (!RangeEnc_Alloc(&p->rc, alloc)) -+ return SZ_ERROR_MEM; -+ btMode = (p->matchFinderBase.btMode != 0); -+ #ifndef _7ZIP_ST -+ p->mtMode = (p->multiThread && !p->fastMode && btMode); -+ #endif -+ -+ { -+ unsigned lclp = p->lc + p->lp; -+ if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp) -+ { -+ LzmaEnc_FreeLits(p, alloc); -+ p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); -+ p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); -+ if (p->litProbs == 0 || p->saveState.litProbs == 0) -+ { -+ LzmaEnc_FreeLits(p, alloc); -+ return SZ_ERROR_MEM; -+ } -+ p->lclp = lclp; -+ } -+ } -+ -+ p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit); -+ -+ if (beforeSize + p->dictSize < keepWindowSize) -+ beforeSize = keepWindowSize - p->dictSize; -+ -+ #ifndef _7ZIP_ST -+ if (p->mtMode) -+ { -+ RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)); -+ p->matchFinderObj = &p->matchFinderMt; -+ MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder); -+ } -+ else -+ #endif -+ { -+ if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)) -+ return SZ_ERROR_MEM; -+ p->matchFinderObj = &p->matchFinderBase; -+ MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder); -+ } -+ return SZ_OK; -+} -+ -+static void LzmaEnc_Init(CLzmaEnc *p) -+{ -+ UInt32 i; -+ p->state = 0; -+ for (i = 0 ; i < LZMA_NUM_REPS; i++) -+ p->reps[i] = 0; -+ -+ RangeEnc_Init(&p->rc); -+ -+ -+ for (i = 0; i < kNumStates; i++) -+ { -+ UInt32 j; -+ for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++) -+ { -+ p->isMatch[i][j] = kProbInitValue; -+ p->isRep0Long[i][j] = kProbInitValue; -+ } -+ p->isRep[i] = kProbInitValue; -+ p->isRepG0[i] = kProbInitValue; -+ p->isRepG1[i] = kProbInitValue; -+ p->isRepG2[i] = kProbInitValue; -+ } -+ -+ { -+ UInt32 num = 0x300 << (p->lp + p->lc); -+ for (i = 0; i < num; i++) -+ p->litProbs[i] = kProbInitValue; -+ } -+ -+ { -+ for (i = 0; i < kNumLenToPosStates; i++) -+ { -+ CLzmaProb *probs = p->posSlotEncoder[i]; -+ UInt32 j; -+ for (j = 0; j < (1 << kNumPosSlotBits); j++) -+ probs[j] = kProbInitValue; -+ } -+ } -+ { -+ for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++) -+ p->posEncoders[i] = kProbInitValue; -+ } -+ -+ LenEnc_Init(&p->lenEnc.p); -+ LenEnc_Init(&p->repLenEnc.p); -+ -+ for (i = 0; i < (1 << kNumAlignBits); i++) -+ p->posAlignEncoder[i] = kProbInitValue; -+ -+ p->optimumEndIndex = 0; -+ p->optimumCurrentIndex = 0; -+ p->additionalOffset = 0; -+ -+ p->pbMask = (1 << p->pb) - 1; -+ p->lpMask = (1 << p->lp) - 1; -+} -+ -+static void LzmaEnc_InitPrices(CLzmaEnc *p) -+{ -+ if (!p->fastMode) -+ { -+ FillDistancesPrices(p); -+ FillAlignPrices(p); -+ } -+ -+ p->lenEnc.tableSize = -+ p->repLenEnc.tableSize = -+ p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN; -+ LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices); -+ LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices); -+} -+ -+static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ UInt32 i; -+ for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++) -+ if (p->dictSize <= ((UInt32)1 << i)) -+ break; -+ p->distTableSize = i * 2; -+ -+ p->finished = False; -+ p->result = SZ_OK; -+ RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig)); -+ LzmaEnc_Init(p); -+ LzmaEnc_InitPrices(p); -+ p->nowPos64 = 0; -+ return SZ_OK; -+} -+ -+static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, -+ ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ p->matchFinderBase.stream = inStream; -+ p->needInit = 1; -+ p->rc.outStream = outStream; -+ return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); -+} -+ -+/*SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, -+ ISeqInStream *inStream, UInt32 keepWindowSize, -+ ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ p->matchFinderBase.stream = inStream; -+ p->needInit = 1; -+ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); -+}*/ -+ -+static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) -+{ -+ p->matchFinderBase.directInput = 1; -+ p->matchFinderBase.bufferBase = (Byte *)src; -+ p->matchFinderBase.directInputRem = srcLen; -+} -+ -+static SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, -+ UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ LzmaEnc_SetInputBuf(p, src, srcLen); -+ p->needInit = 1; -+ -+ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); -+} -+ -+static void LzmaEnc_Finish(CLzmaEncHandle pp) -+{ -+ #ifndef _7ZIP_ST -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ if (p->mtMode) -+ MatchFinderMt_ReleaseStream(&p->matchFinderMt); -+ #else -+ pp = pp; -+ #endif -+} -+ -+typedef struct -+{ -+ ISeqOutStream funcTable; -+ Byte *data; -+ SizeT rem; -+ Bool overflow; -+} CSeqOutStreamBuf; -+ -+static size_t MyWrite(void *pp, const void *data, size_t size) -+{ -+ CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp; -+ if (p->rem < size) -+ { -+ size = p->rem; -+ p->overflow = True; -+ } -+ memcpy(p->data, data, size); -+ p->rem -= size; -+ p->data += size; -+ return size; -+} -+ -+ -+/*UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp) -+{ -+ const CLzmaEnc *p = (CLzmaEnc *)pp; -+ return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); -+}*/ -+ -+/*const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) -+{ -+ const CLzmaEnc *p = (CLzmaEnc *)pp; -+ return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; -+}*/ -+ -+/* SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, -+ Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ UInt64 nowPos64; -+ SRes res; -+ CSeqOutStreamBuf outStream; -+ -+ outStream.funcTable.Write = MyWrite; -+ outStream.data = dest; -+ outStream.rem = *destLen; -+ outStream.overflow = False; -+ -+ p->writeEndMark = False; -+ p->finished = False; -+ p->result = SZ_OK; -+ -+ if (reInit) -+ LzmaEnc_Init(p); -+ LzmaEnc_InitPrices(p); -+ nowPos64 = p->nowPos64; -+ RangeEnc_Init(&p->rc); -+ p->rc.outStream = &outStream.funcTable; -+ -+ res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize); -+ -+ *unpackSize = (UInt32)(p->nowPos64 - nowPos64); -+ *destLen -= outStream.rem; -+ if (outStream.overflow) -+ return SZ_ERROR_OUTPUT_EOF; -+ -+ return res; -+}*/ -+ -+static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) -+{ -+ SRes res = SZ_OK; -+ -+ #ifndef _7ZIP_ST -+ Byte allocaDummy[0x300]; -+ int i = 0; -+ for (i = 0; i < 16; i++) -+ allocaDummy[i] = (Byte)i; -+ #endif -+ -+ for (;;) -+ { -+ res = LzmaEnc_CodeOneBlock(p, False, 0, 0); -+ if (res != SZ_OK || p->finished != 0) -+ break; -+ if (progress != 0) -+ { -+ res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc)); -+ if (res != SZ_OK) -+ { -+ res = SZ_ERROR_PROGRESS; -+ break; -+ } -+ } -+ } -+ LzmaEnc_Finish(p); -+ return res; -+} -+ -+SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, -+ ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig)); -+ return LzmaEnc_Encode2((CLzmaEnc *)pp, progress); -+} -+ -+SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ int i; -+ UInt32 dictSize = p->dictSize; -+ if (*size < LZMA_PROPS_SIZE) -+ return SZ_ERROR_PARAM; -+ *size = LZMA_PROPS_SIZE; -+ props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc); -+ -+ for (i = 11; i <= 30; i++) -+ { -+ if (dictSize <= ((UInt32)2 << i)) -+ { -+ dictSize = (2 << i); -+ break; -+ } -+ if (dictSize <= ((UInt32)3 << i)) -+ { -+ dictSize = (3 << i); -+ break; -+ } -+ } -+ -+ for (i = 0; i < 4; i++) -+ props[1 + i] = (Byte)(dictSize >> (8 * i)); -+ return SZ_OK; -+} -+ -+SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -+ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ SRes res; -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ -+ CSeqOutStreamBuf outStream; -+ -+ LzmaEnc_SetInputBuf(p, src, srcLen); -+ -+ outStream.funcTable.Write = MyWrite; -+ outStream.data = dest; -+ outStream.rem = *destLen; -+ outStream.overflow = False; -+ -+ p->writeEndMark = writeEndMark; -+ -+ p->rc.outStream = &outStream.funcTable; -+ res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig); -+ if (res == SZ_OK) -+ res = LzmaEnc_Encode2(p, progress); -+ -+ *destLen -= outStream.rem; -+ if (outStream.overflow) -+ return SZ_ERROR_OUTPUT_EOF; -+ return res; -+} -+ -+SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -+ const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, -+ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); -+ SRes res; -+ if (p == 0) -+ return SZ_ERROR_MEM; -+ -+ res = LzmaEnc_SetProps(p, props); -+ if (res == SZ_OK) -+ { -+ res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize); -+ if (res == SZ_OK) -+ res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen, -+ writeEndMark, progress, alloc, allocBig); -+ } -+ -+ LzmaEnc_Destroy(p, alloc, allocBig); -+ return res; -+} -diff --git a/lib/lzma/Makefile b/lib/lzma/Makefile -new file mode 100644 -index 000000000000..02e799c99381 ---- /dev/null -+++ b/lib/lzma/Makefile -@@ -0,0 +1,7 @@ -+lzma_compress-objs := LzFind.o LzmaEnc.o -+lzma_decompress-objs := LzmaDec.o -+ -+obj-$(CONFIG_LZMA_COMPRESS) += lzma_compress.o -+obj-$(CONFIG_LZMA_DECOMPRESS) += lzma_decompress.o -+ -+EXTRA_CFLAGS += -Iinclude/linux -Iinclude/linux/lzma -include types.h --- -2.51.0 - - -From 0749420ddd81391f698d65098ee2e56e19f4cf16 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Mon, 3 Nov 2025 15:49:52 +0100 -Subject: [PATCH 253/517] fs: jffs2: EOF marker - -Signed-off-by: Felix Fietkau ---- - fs/jffs2/build.c | 10 ++++++++++ - fs/jffs2/scan.c | 21 +++++++++++++++++++-- - 2 files changed, 29 insertions(+), 2 deletions(-) - -diff --git a/fs/jffs2/build.c b/fs/jffs2/build.c -index 6ae9d6fefb86..d21a7ecec6ee 100644 ---- a/fs/jffs2/build.c -+++ b/fs/jffs2/build.c -@@ -117,6 +117,16 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c) - dbg_fsbuild("scanned flash completely\n"); - jffs2_dbg_dump_block_lists_nolock(c); - -+ if (c->flags & (1 << 7)) { -+ printk("%s(): unlocking the mtd device... ", __func__); -+ mtd_unlock(c->mtd, 0, c->mtd->size); -+ printk("done.\n"); -+ -+ printk("%s(): erasing all blocks after the end marker... ", __func__); -+ jffs2_erase_pending_blocks(c, -1); -+ printk("done.\n"); -+ } -+ - dbg_fsbuild("pass 1 starting\n"); - c->flags |= JFFS2_SB_FLAG_BUILDING; - /* Now scan the directory tree, increasing nlink according to every dirent found. */ -diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c -index 62879c218d4b..cb928d2414ed 100644 ---- a/fs/jffs2/scan.c -+++ b/fs/jffs2/scan.c -@@ -148,8 +148,14 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) - /* reset summary info for next eraseblock scan */ - jffs2_sum_reset_collected(s); - -- ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset), -- buf_size, s); -+ if (c->flags & (1 << 7)) { -+ if (mtd_block_isbad(c->mtd, jeb->offset)) -+ ret = BLK_STATE_BADBLOCK; -+ else -+ ret = BLK_STATE_ALLFF; -+ } else -+ ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset), -+ buf_size, s); - - if (ret < 0) - goto out; -@@ -569,6 +575,17 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo - return err; - } - -+ if ((buf[0] == 0xde) && -+ (buf[1] == 0xad) && -+ (buf[2] == 0xc0) && -+ (buf[3] == 0xde)) { -+ /* end of filesystem. erase everything after this point */ -+ printk("%s(): End of filesystem marker found at 0x%x\n", __func__, jeb->offset); -+ c->flags |= (1 << 7); -+ -+ return BLK_STATE_ALLFF; -+ } -+ - /* We temporarily use 'ofs' as a pointer into the buffer/jeb */ - ofs = 0; - max_ofs = EMPTY_SCAN_SIZE(c->sector_size); --- -2.51.0 - - -From a62f2a7232e826e000cc8364899b074427f3ca34 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Mon, 3 Nov 2025 15:49:52 +0100 -Subject: [PATCH 254/517] netfilter: add support for flushing conntrack via - /proc - -lede-commit 8193bbe59a74d34d6a26d4a8cb857b1952905314 -Signed-off-by: Felix Fietkau ---- - net/netfilter/nf_conntrack_standalone.c | 58 ++++++++++++++++++++++++- - 1 file changed, 56 insertions(+), 2 deletions(-) - -diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c -index 3ea60ff7a6a4..39fd99016360 100644 ---- a/net/netfilter/nf_conntrack_standalone.c -+++ b/net/netfilter/nf_conntrack_standalone.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - #include - #ifdef CONFIG_SYSCTL - #include -@@ -458,6 +459,58 @@ static int ct_cpu_seq_show(struct seq_file *seq, void *v) - return 0; - } - -+struct kill_request { -+ u16 family; -+ union nf_inet_addr addr; -+}; -+ -+static int kill_matching(struct nf_conn *i, void *data) -+{ -+ struct kill_request *kr = data; -+ struct nf_conntrack_tuple *t1 = &i->tuplehash[IP_CT_DIR_ORIGINAL].tuple; -+ struct nf_conntrack_tuple *t2 = &i->tuplehash[IP_CT_DIR_REPLY].tuple; -+ -+ if (!kr->family) -+ return 1; -+ -+ if (t1->src.l3num != kr->family) -+ return 0; -+ -+ return (nf_inet_addr_cmp(&kr->addr, &t1->src.u3) || -+ nf_inet_addr_cmp(&kr->addr, &t1->dst.u3) || -+ nf_inet_addr_cmp(&kr->addr, &t2->src.u3) || -+ nf_inet_addr_cmp(&kr->addr, &t2->dst.u3)); -+} -+ -+static int ct_file_write(struct file *file, char *buf, size_t count) -+{ -+ struct seq_file *seq = file->private_data; -+ struct nf_ct_iter_data iter_data; -+ struct kill_request kr = { }; -+ -+ if (count == 0) -+ return 0; -+ -+ if (count >= INET6_ADDRSTRLEN) -+ count = INET6_ADDRSTRLEN - 1; -+ -+ if (strnchr(buf, count, ':')) { -+ kr.family = AF_INET6; -+ if (!in6_pton(buf, count, (void *)&kr.addr, '\n', NULL)) -+ return -EINVAL; -+ } else if (strnchr(buf, count, '.')) { -+ kr.family = AF_INET; -+ if (!in4_pton(buf, count, (void *)&kr.addr, '\n', NULL)) -+ return -EINVAL; -+ } -+ -+ iter_data.net = seq_file_net(seq); -+ iter_data.data = &kr; -+ nf_ct_iterate_cleanup_net(kill_matching, &iter_data); -+ -+ return 0; -+} -+ - static const struct seq_operations ct_cpu_seq_ops = { - .start = ct_cpu_seq_start, - .next = ct_cpu_seq_next, -@@ -471,8 +524,9 @@ static int nf_conntrack_standalone_init_proc(struct net *net) - kuid_t root_uid; - kgid_t root_gid; - -- pde = proc_create_net("nf_conntrack", 0440, net->proc_net, &ct_seq_ops, -- sizeof(struct ct_iter_state)); -+ pde = proc_create_net_data_write("nf_conntrack", 0440, net->proc_net, -+ &ct_seq_ops, &ct_file_write, -+ sizeof(struct ct_iter_state), NULL); - if (!pde) - goto out_nf_conntrack; - --- -2.51.0 - - -From 92d7c8f5e0513a7b12c993c38792ba7edc72dee9 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Mon, 3 Nov 2025 15:49:53 +0100 -Subject: [PATCH 255/517] kernel: add a new version of my netfilter speedup - patches for linux 2.6.39 and 3.0 - -Signed-off-by: Felix Fietkau ---- - include/uapi/linux/netfilter_ipv4/ip_tables.h | 1 + - net/ipv4/netfilter/ip_tables.c | 42 ++++++++++++++++++- - 2 files changed, 42 insertions(+), 1 deletion(-) - -diff --git a/include/uapi/linux/netfilter_ipv4/ip_tables.h b/include/uapi/linux/netfilter_ipv4/ip_tables.h -index 1485df28b239..250350c37ef5 100644 ---- a/include/uapi/linux/netfilter_ipv4/ip_tables.h -+++ b/include/uapi/linux/netfilter_ipv4/ip_tables.h -@@ -89,6 +89,7 @@ struct ipt_ip { - #define IPT_F_FRAG 0x01 /* Set if rule is a fragment rule */ - #define IPT_F_GOTO 0x02 /* Set if jump is a goto */ - #define IPT_F_MASK 0x03 /* All possible flag bits mask. */ -+#define IPT_F_NO_DEF_MATCH 0x80 /* Internal: no default match rules present */ - - /* Values for "inv" field in struct ipt_ip. */ - #define IPT_INV_VIA_IN 0x01 /* Invert the sense of IN IFACE. */ -diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c -index 3d101613f27f..43ee82554011 100644 ---- a/net/ipv4/netfilter/ip_tables.c -+++ b/net/ipv4/netfilter/ip_tables.c -@@ -48,6 +48,9 @@ ip_packet_match(const struct iphdr *ip, - { - unsigned long ret; - -+ if (ipinfo->flags & IPT_F_NO_DEF_MATCH) -+ return true; -+ - if (NF_INVF(ipinfo, IPT_INV_SRCIP, - (ip->saddr & ipinfo->smsk.s_addr) != ipinfo->src.s_addr) || - NF_INVF(ipinfo, IPT_INV_DSTIP, -@@ -78,6 +81,29 @@ ip_packet_match(const struct iphdr *ip, - return true; - } - -+static void -+ip_checkdefault(struct ipt_ip *ip) -+{ -+ static const char iface_mask[IFNAMSIZ] = {}; -+ -+ if (ip->invflags || ip->flags & IPT_F_FRAG) -+ return; -+ -+ if (memcmp(ip->iniface_mask, iface_mask, IFNAMSIZ) != 0) -+ return; -+ -+ if (memcmp(ip->outiface_mask, iface_mask, IFNAMSIZ) != 0) -+ return; -+ -+ if (ip->smsk.s_addr || ip->dmsk.s_addr) -+ return; -+ -+ if (ip->proto) -+ return; -+ -+ ip->flags |= IPT_F_NO_DEF_MATCH; -+} -+ - static bool - ip_checkentry(const struct ipt_ip *ip) - { -@@ -523,6 +549,8 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name, - struct xt_mtchk_param mtpar; - struct xt_entry_match *ematch; - -+ ip_checkdefault(&e->ip); -+ - if (!xt_percpu_counter_alloc(alloc_state, &e->counters)) - return -ENOMEM; - -@@ -817,6 +845,7 @@ copy_entries_to_user(unsigned int total_size, - const struct xt_table_info *private = table->private; - int ret = 0; - const void *loc_cpu_entry; -+ u8 flags; - - counters = alloc_counters(table); - if (IS_ERR(counters)) -@@ -844,6 +873,14 @@ copy_entries_to_user(unsigned int total_size, - goto free_counters; - } - -+ flags = e->ip.flags & IPT_F_MASK; -+ if (copy_to_user(userptr + off -+ + offsetof(struct ipt_entry, ip.flags), -+ &flags, sizeof(flags)) != 0) { -+ ret = -EFAULT; -+ goto free_counters; -+ } -+ - for (i = sizeof(struct ipt_entry); - i < e->target_offset; - i += m->u.match_size) { -@@ -1225,12 +1262,15 @@ compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr, - compat_uint_t origsize; - const struct xt_entry_match *ematch; - int ret = 0; -+ u8 flags = e->ip.flags & IPT_F_MASK; - - origsize = *size; - ce = *dstptr; - if (copy_to_user(ce, e, sizeof(struct ipt_entry)) != 0 || - copy_to_user(&ce->counters, &counters[i], -- sizeof(counters[i])) != 0) -+ sizeof(counters[i])) != 0 || -+ copy_to_user(&ce->ip.flags, &flags, -+ sizeof(flags)) != 0) - return -EFAULT; - - *dstptr += sizeof(struct compat_ipt_entry); --- -2.51.0 - - -From 12cf7d07371762ca70888fb3b9511a3250211a88 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Mon, 3 Nov 2025 15:49:53 +0100 -Subject: [PATCH 256/517] netfilter: match bypass default table - -Signed-off-by: Felix Fietkau ---- - net/ipv4/netfilter/ip_tables.c | 69 ++++++++++++++++++++++++++-------- - 1 file changed, 53 insertions(+), 16 deletions(-) - -diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c -index 43ee82554011..8325e81b9827 100644 ---- a/net/ipv4/netfilter/ip_tables.c -+++ b/net/ipv4/netfilter/ip_tables.c -@@ -244,6 +244,33 @@ struct ipt_entry *ipt_next_entry(const struct ipt_entry *entry) - return (void *)entry + entry->next_offset; - } - -+static bool -+ipt_handle_default_rule(struct ipt_entry *e, unsigned int *verdict) -+{ -+ struct xt_entry_target *t; -+ struct xt_standard_target *st; -+ -+ if (e->target_offset != sizeof(struct ipt_entry)) -+ return false; -+ -+ if (!(e->ip.flags & IPT_F_NO_DEF_MATCH)) -+ return false; -+ -+ t = ipt_get_target(e); -+ if (t->u.kernel.target->target) -+ return false; -+ -+ st = (struct xt_standard_target *) t; -+ if (st->verdict == XT_RETURN) -+ return false; -+ -+ if (st->verdict >= 0) -+ return false; -+ -+ *verdict = (unsigned)(-st->verdict) - 1; -+ return true; -+} -+ - /* Returns one of the generic firewall policies, like NF_ACCEPT. */ - unsigned int - ipt_do_table(void *priv, -@@ -265,27 +292,28 @@ ipt_do_table(void *priv, - unsigned int addend; - - /* Initialization */ -+ WARN_ON(!(table->valid_hooks & (1 << hook))); -+ local_bh_disable(); -+ private = READ_ONCE(table->private); /* Address dependency. */ -+ cpu = smp_processor_id(); -+ table_base = private->entries; -+ -+ e = get_entry(table_base, private->hook_entry[hook]); -+ if (ipt_handle_default_rule(e, &verdict)) { -+ struct xt_counters *counter; -+ -+ counter = xt_get_this_cpu_counter(&e->counters); -+ ADD_COUNTER(*counter, skb->len, 1); -+ local_bh_enable(); -+ return verdict; -+ } -+ - stackidx = 0; - ip = ip_hdr(skb); - indev = state->in ? state->in->name : nulldevname; - outdev = state->out ? state->out->name : nulldevname; -- /* We handle fragments by dealing with the first fragment as -- * if it was a normal packet. All other fragments are treated -- * normally, except that they will NEVER match rules that ask -- * things we don't know, ie. tcp syn flag or ports). If the -- * rule is also a fragment-specific rule, non-fragments won't -- * match it. */ -- acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET; -- acpar.thoff = ip_hdrlen(skb); -- acpar.hotdrop = false; -- acpar.state = state; - -- WARN_ON(!(table->valid_hooks & (1 << hook))); -- local_bh_disable(); - addend = xt_write_recseq_begin(); -- private = READ_ONCE(table->private); /* Address dependency. */ -- cpu = smp_processor_id(); -- table_base = private->entries; - jumpstack = (struct ipt_entry **)private->jumpstack[cpu]; - - /* Switch to alternate jumpstack if we're being invoked via TEE. -@@ -298,7 +326,16 @@ ipt_do_table(void *priv, - if (static_key_false(&xt_tee_enabled)) - jumpstack += private->stacksize * __this_cpu_read(nf_skb_duplicated); - -- e = get_entry(table_base, private->hook_entry[hook]); -+ /* We handle fragments by dealing with the first fragment as -+ * if it was a normal packet. All other fragments are treated -+ * normally, except that they will NEVER match rules that ask -+ * things we don't know, ie. tcp syn flag or ports). If the -+ * rule is also a fragment-specific rule, non-fragments won't -+ * match it. */ -+ acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET; -+ acpar.thoff = ip_hdrlen(skb); -+ acpar.hotdrop = false; -+ acpar.state = state; - - do { - const struct xt_entry_target *t; --- -2.51.0 - - -From 34ea6fee7df6d495f35ff6fd7045b334c50325ba Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Mon, 3 Nov 2025 15:49:53 +0100 -Subject: [PATCH 257/517] netfilter: reduce match memory access - -Signed-off-by: Felix Fietkau ---- - net/ipv4/netfilter/ip_tables.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c -index 8325e81b9827..d03e2121810b 100644 ---- a/net/ipv4/netfilter/ip_tables.c -+++ b/net/ipv4/netfilter/ip_tables.c -@@ -51,9 +51,9 @@ ip_packet_match(const struct iphdr *ip, - if (ipinfo->flags & IPT_F_NO_DEF_MATCH) - return true; - -- if (NF_INVF(ipinfo, IPT_INV_SRCIP, -+ if (NF_INVF(ipinfo, IPT_INV_SRCIP, ipinfo->smsk.s_addr && - (ip->saddr & ipinfo->smsk.s_addr) != ipinfo->src.s_addr) || -- NF_INVF(ipinfo, IPT_INV_DSTIP, -+ NF_INVF(ipinfo, IPT_INV_DSTIP, ipinfo->dmsk.s_addr && - (ip->daddr & ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr)) - return false; - --- -2.51.0 - - -From db287f2364f5f532223610146e83950c43e89a11 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Mon, 3 Nov 2025 15:49:53 +0100 -Subject: [PATCH 258/517] net: add an optimization for dealing with raw sockets - -lede-commit: 4898039703d7315f0f3431c860123338ec3be0f6 -Signed-off-by: Felix Fietkau ---- - include/uapi/linux/if_packet.h | 3 +++ - net/packet/af_packet.c | 34 +++++++++++++++++++++++++++------- - net/packet/internal.h | 1 + - 3 files changed, 31 insertions(+), 7 deletions(-) - -diff --git a/include/uapi/linux/if_packet.h b/include/uapi/linux/if_packet.h -index 1d2718dd9647..a52deea9d653 100644 ---- a/include/uapi/linux/if_packet.h -+++ b/include/uapi/linux/if_packet.h -@@ -33,6 +33,8 @@ struct sockaddr_ll { - #define PACKET_KERNEL 7 /* To kernel space */ - /* Unused, PACKET_FASTROUTE and PACKET_LOOPBACK are invisible to user space */ - #define PACKET_FASTROUTE 6 /* Fastrouted frame */ -+#define PACKET_MASK_ANY 0xffffffff /* mask for packet type bits */ -+ - - /* Packet socket options */ - -@@ -60,6 +62,7 @@ struct sockaddr_ll { - #define PACKET_FANOUT_DATA 22 - #define PACKET_IGNORE_OUTGOING 23 - #define PACKET_VNET_HDR_SZ 24 -+#define PACKET_RECV_TYPE 25 - - #define PACKET_FANOUT_HASH 0 - #define PACKET_FANOUT_LB 1 -diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c -index e8589fede4d4..e2c5b44c0e60 100644 ---- a/net/packet/af_packet.c -+++ b/net/packet/af_packet.c -@@ -1911,6 +1911,7 @@ static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev, - { - struct sock *sk; - struct sockaddr_pkt *spkt; -+ struct packet_sock *po; - - /* - * When we registered the protocol we saved the socket in the data -@@ -1918,6 +1919,7 @@ static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev, - */ - - sk = pt->af_packet_priv; -+ po = pkt_sk(sk); - - /* - * Yank back the headers [hope the device set this -@@ -1930,7 +1932,7 @@ static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev, - * so that this procedure is noop. - */ - -- if (skb->pkt_type == PACKET_LOOPBACK) -+ if (!(po->pkt_type & (1 << skb->pkt_type))) - goto out; - - if (!net_eq(dev_net(dev), sock_net(sk))) -@@ -2175,12 +2177,12 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, - int skb_len = skb->len; - unsigned int snaplen, res; - -- if (skb->pkt_type == PACKET_LOOPBACK) -- goto drop; -- - sk = pt->af_packet_priv; - po = pkt_sk(sk); - -+ if (!(po->pkt_type & (1 << skb->pkt_type))) -+ goto drop; -+ - if (!net_eq(dev_net(dev), sock_net(sk))) - goto drop; - -@@ -2304,12 +2306,12 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, - BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h2)) != 32); - BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h3)) != 48); - -- if (skb->pkt_type == PACKET_LOOPBACK) -- goto drop; -- - sk = pt->af_packet_priv; - po = pkt_sk(sk); - -+ if (!(po->pkt_type & (1 << skb->pkt_type))) -+ goto drop; -+ - if (!net_eq(dev_net(dev), sock_net(sk))) - goto drop; - -@@ -3429,6 +3431,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol, - mutex_init(&po->pg_vec_lock); - po->rollover = NULL; - po->prot_hook.func = packet_rcv; -+ po->pkt_type = PACKET_MASK_ANY & ~(1 << PACKET_LOOPBACK); - - if (sock->type == SOCK_PACKET) - po->prot_hook.func = packet_rcv_spkt; -@@ -4096,6 +4099,16 @@ packet_setsockopt(struct socket *sock, int level, int optname, sockptr_t optval, - packet_sock_flag_set(po, PACKET_SOCK_QDISC_BYPASS, val); - return 0; - } -+ case PACKET_RECV_TYPE: -+ { -+ unsigned int val; -+ if (optlen != sizeof(val)) -+ return -EINVAL; -+ if (copy_from_sockptr(&val, optval, sizeof(val))) -+ return -EFAULT; -+ po->pkt_type = val & ~BIT(PACKET_LOOPBACK); -+ return 0; -+ } - default: - return -ENOPROTOOPT; - } -@@ -4158,6 +4171,13 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, - case PACKET_COPY_THRESH: - val = READ_ONCE(pkt_sk(sk)->copy_thresh); - break; -+ case PACKET_RECV_TYPE: -+ if (len > sizeof(unsigned int)) -+ len = sizeof(unsigned int); -+ val = po->pkt_type; -+ -+ data = &val; -+ break; - case PACKET_VERSION: - val = po->tp_version; - break; -diff --git a/net/packet/internal.h b/net/packet/internal.h -index d5d70712007a..891df18a6947 100644 ---- a/net/packet/internal.h -+++ b/net/packet/internal.h -@@ -131,6 +131,7 @@ struct packet_sock { - struct net_device __rcu *cached_dev; - struct packet_type prot_hook ____cacheline_aligned_in_smp; - atomic_t tp_drops ____cacheline_aligned_in_smp; -+ unsigned int pkt_type; - }; - - #define pkt_sk(ptr) container_of_const(ptr, struct packet_sock, sk) --- -2.51.0 - - -From d187d050110d76efe46d7d7eb669a335ec25e330 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Thu, 22 Aug 2024 18:02:17 +0200 -Subject: [PATCH 259/517] net: bridge: fix switchdev host mdb entry updates - -When a mdb entry is removed, the bridge switchdev code can issue a -switchdev_port_obj_del call for a port that was not offloaded. - -This leads to an imbalance in switchdev_port_obj_add/del calls, since -br_switchdev_mdb_replay has not been called for the port before. - -This can lead to potential multicast forwarding issues and messages such as: -mt7915e 0000:01:00.0 wl1-ap0: Failed to del Host Multicast Database entry - (object id=3) with error: -ENOENT (-2). - -Fix this issue by checking the port offload status when iterating over -lower devs. - -Signed-off-by: Felix Fietkau ---- - net/bridge/br_switchdev.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c -index f10bd6a233dc..6dffac613768 100644 ---- a/net/bridge/br_switchdev.c -+++ b/net/bridge/br_switchdev.c -@@ -571,10 +571,18 @@ static void br_switchdev_host_mdb(struct net_device *dev, - struct net_bridge_mdb_entry *mp, int type) - { - struct net_device *lower_dev; -+ struct net_bridge_port *port; - struct list_head *iter; - -- netdev_for_each_lower_dev(dev, lower_dev, iter) -+ rcu_read_lock(); -+ netdev_for_each_lower_dev(dev, lower_dev, iter) { -+ port = br_port_get_rcu(lower_dev); -+ if (!port || !port->offload_count) -+ continue; -+ - br_switchdev_host_mdb_one(dev, lower_dev, mp, type); -+ } -+ rcu_read_unlock(); - } - - static int --- -2.51.0 - - -From ee69dd931652725a53e666564b5e9f405be3a770 Mon Sep 17 00:00:00 2001 -From: "Leon M. Busch-George" -Date: Sun, 20 Oct 2024 18:20:14 +0200 -Subject: [PATCH 260/517] net: bridge: switchdev: Don't drop packets between - ports with no hwdom - -nbp_switchdev_allowed_egress uses hwdom to determine whether or not a -packet has already been forwarded to a hardware domain. For -net_bridge_ports that aren't set up to use forward offloading, hwdom is -set to 0. When both ingress and egress port have no hwdom, -'cb->src_hwdom != p->hwdom' indicates that the packet is already known in -the target domain - which it isn't - and the packet is wrongly dropped. - -The error was found on a bridge containing a wifi device and a VLAN -tagging device (e.g. eth0.12). With VLAN filtering, this shouldn't happen. - -This patch adds a check for p->hwdom != 0 before comparing hardware -domains to restore forwarding between ports with hwdom = 0. - -fwd_hwdoms are only set for ports with offloading enabled, which also -implies a valid hwdom, so the check '!test_bit(p->hwdom, &cb->fwd_hwdoms)' -doesn't fail in this way (yet - fingers crossed..) and it is left in place. - -Co-developed-by: Felix Fietkau -Signed-off-by: Felix Fietkau -Signed-off-by: Leon M. Busch-George ---- - net/bridge/br_switchdev.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c -index 6dffac613768..98ef0642dda4 100644 ---- a/net/bridge/br_switchdev.c -+++ b/net/bridge/br_switchdev.c -@@ -70,7 +70,7 @@ bool nbp_switchdev_allowed_egress(const struct net_bridge_port *p, - struct br_input_skb_cb *cb = BR_INPUT_SKB_CB(skb); - - return !test_bit(p->hwdom, &cb->fwd_hwdoms) && -- (!skb->offload_fwd_mark || cb->src_hwdom != p->hwdom); -+ (!skb->offload_fwd_mark || !p->hwdom || cb->src_hwdom != p->hwdom); - } - - /* Flags that can be offloaded to hardware */ --- -2.51.0 - - -From c2a69cffa26902e6c10ea558dd5d6dc305f1dd48 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Tue, 15 Jul 2025 12:37:45 +0200 -Subject: [PATCH 261/517] net: pppoe: implement GRO support - -Only handles packets where the pppoe header length field matches the exact -packet length. Significantly improves rx throughput. - -When running NAT traffic through a MediaTek MT7621 devices from a host -behind PPPoE to a host directly connected via ethernet, the TCP throughput -that the device is able to handle improves from ~130 Mbit/s to ~630 Mbit/s, -using fraglist GRO. - -Signed-off-by: Felix Fietkau ---- - drivers/net/ppp/pppoe.c | 160 +++++++++++++++++++++++++++++++++++++++- - net/ipv4/af_inet.c | 2 + - net/ipv6/ip6_offload.c | 2 + - 3 files changed, 163 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c -index 68e631718ab0..3d145fb7a6ab 100644 ---- a/drivers/net/ppp/pppoe.c -+++ b/drivers/net/ppp/pppoe.c -@@ -77,6 +77,7 @@ - #include - #include - #include -+#include - - #include - -@@ -435,7 +436,7 @@ static int pppoe_rcv(struct sk_buff *skb, struct net_device *dev, - if (skb->len < len) - goto drop; - -- if (pskb_trim_rcsum(skb, len)) -+ if (!skb_is_gso(skb) && pskb_trim_rcsum(skb, len)) - goto drop; - - ph = pppoe_hdr(skb); -@@ -1173,6 +1174,161 @@ static struct pernet_operations pppoe_net_ops = { - .size = sizeof(struct pppoe_net), - }; - -+static u16 -+compare_pppoe_header(struct pppoe_hdr *phdr, struct pppoe_hdr *phdr2) -+{ -+ return (__force __u16)((phdr->sid ^ phdr2->sid) | -+ (phdr->tag[0].tag_type ^ phdr2->tag[0].tag_type)); -+} -+ -+static __be16 pppoe_hdr_proto(struct pppoe_hdr *phdr) -+{ -+ switch (phdr->tag[0].tag_type) { -+ case cpu_to_be16(PPP_IP): -+ return cpu_to_be16(ETH_P_IP); -+ case cpu_to_be16(PPP_IPV6): -+ return cpu_to_be16(ETH_P_IPV6); -+ default: -+ return 0; -+ } -+ -+} -+ -+static struct sk_buff *pppoe_gro_receive(struct list_head *head, -+ struct sk_buff *skb) -+{ -+ const struct packet_offload *ptype; -+ unsigned int hlen, off_pppoe; -+ struct sk_buff *pp = NULL; -+ struct pppoe_hdr *phdr; -+ struct sk_buff *p; -+ int flush = 1; -+ __be16 type; -+ -+ off_pppoe = skb_gro_offset(skb); -+ hlen = off_pppoe + sizeof(*phdr); -+ phdr = skb_gro_header(skb, hlen + 2, off_pppoe); -+ if (unlikely(!phdr)) -+ goto out; -+ -+ /* ignore packets with padding or invalid length */ -+ if (skb_gro_len(skb) != be16_to_cpu(phdr->length) + hlen) -+ goto out; -+ -+ type = pppoe_hdr_proto(phdr); -+ if (!type) -+ goto out; -+ -+ ptype = gro_find_receive_by_type(type); -+ if (!ptype) -+ goto out; -+ -+ flush = 0; -+ -+ list_for_each_entry(p, head, list) { -+ struct pppoe_hdr *phdr2; -+ -+ if (!NAPI_GRO_CB(p)->same_flow) -+ continue; -+ -+ phdr2 = (struct pppoe_hdr *)(p->data + off_pppoe); -+ if (compare_pppoe_header(phdr, phdr2)) -+ NAPI_GRO_CB(p)->same_flow = 0; -+ } -+ -+ skb_gro_pull(skb, sizeof(*phdr) + 2); -+ skb_gro_postpull_rcsum(skb, phdr, sizeof(*phdr) + 2); -+ -+ pp = indirect_call_gro_receive_inet(ptype->callbacks.gro_receive, -+ ipv6_gro_receive, inet_gro_receive, -+ head, skb); -+ -+out: -+ skb_gro_flush_final(skb, pp, flush); -+ -+ return pp; -+} -+ -+static int pppoe_gro_complete(struct sk_buff *skb, int nhoff) -+{ -+ struct pppoe_hdr *phdr = (struct pppoe_hdr *)(skb->data + nhoff); -+ __be16 type = pppoe_hdr_proto(phdr); -+ struct packet_offload *ptype; -+ int len, err; -+ -+ ptype = gro_find_complete_by_type(type); -+ if (!ptype) -+ return -ENOENT; -+ -+ err = INDIRECT_CALL_INET(ptype->callbacks.gro_complete, -+ ipv6_gro_complete, inet_gro_complete, -+ skb, nhoff + sizeof(*phdr) + 2); -+ if (err) -+ return err; -+ -+ len = skb->len - (nhoff + sizeof(*phdr)); -+ phdr->length = cpu_to_be16(len); -+ -+ return 0; -+} -+ -+static struct sk_buff *pppoe_gso_segment(struct sk_buff *skb, -+ netdev_features_t features) -+{ -+ unsigned int pppoe_hlen = sizeof(struct pppoe_hdr) + 2; -+ struct sk_buff *segs = ERR_PTR(-EINVAL); -+ u16 mac_offset = skb->mac_header; -+ struct packet_offload *ptype; -+ u16 mac_len = skb->mac_len; -+ struct pppoe_hdr *phdr; -+ __be16 orig_type, type; -+ int len, nhoff; -+ -+ skb_reset_network_header(skb); -+ nhoff = skb_network_header(skb) - skb_mac_header(skb); -+ -+ if (unlikely(!pskb_may_pull(skb, pppoe_hlen))) -+ goto out; -+ -+ phdr = (struct pppoe_hdr *)skb_network_header(skb); -+ type = pppoe_hdr_proto(phdr); -+ ptype = gro_find_complete_by_type(type); -+ if (!ptype) -+ goto out; -+ -+ orig_type = skb->protocol; -+ __skb_pull(skb, pppoe_hlen); -+ segs = ptype->callbacks.gso_segment(skb, features); -+ if (IS_ERR_OR_NULL(segs)) { -+ skb_gso_error_unwind(skb, orig_type, pppoe_hlen, mac_offset, -+ mac_len); -+ goto out; -+ } -+ -+ skb = segs; -+ do { -+ phdr = (struct pppoe_hdr *)(skb_mac_header(skb) + nhoff); -+ len = skb->len - (nhoff + sizeof(*phdr)); -+ phdr->length = cpu_to_be16(len); -+ skb->network_header = (u8 *)phdr - skb->head; -+ skb->protocol = orig_type; -+ skb_reset_mac_len(skb); -+ } while ((skb = skb->next)); -+ -+out: -+ return segs; -+} -+ -+static struct packet_offload pppoe_packet_offload __read_mostly = { -+ .type = cpu_to_be16(ETH_P_PPP_SES), -+ .priority = 20, -+ .callbacks = { -+ .gro_receive = pppoe_gro_receive, -+ .gro_complete = pppoe_gro_complete, -+ .gso_segment = pppoe_gso_segment, -+ }, -+}; -+ - static int __init pppoe_init(void) - { - int err; -@@ -1189,6 +1345,7 @@ static int __init pppoe_init(void) - if (err) - goto out_unregister_pppoe_proto; - -+ dev_add_offload(&pppoe_packet_offload); - dev_add_pack(&pppoes_ptype); - dev_add_pack(&pppoed_ptype); - register_netdevice_notifier(&pppoe_notifier); -@@ -1208,6 +1365,7 @@ static void __exit pppoe_exit(void) - unregister_netdevice_notifier(&pppoe_notifier); - dev_remove_pack(&pppoed_ptype); - dev_remove_pack(&pppoes_ptype); -+ dev_remove_offload(&pppoe_packet_offload); - unregister_pppox_proto(PX_PROTO_OE); - proto_unregister(&pppoe_sk_proto); - unregister_pernet_device(&pppoe_net_ops); -diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c -index 8095e82de808..a1a7d91c42f6 100644 ---- a/net/ipv4/af_inet.c -+++ b/net/ipv4/af_inet.c -@@ -1546,6 +1546,7 @@ struct sk_buff *inet_gro_receive(struct list_head *head, struct sk_buff *skb) - - return pp; - } -+EXPORT_INDIRECT_CALLABLE(inet_gro_receive); - - static struct sk_buff *ipip_gro_receive(struct list_head *head, - struct sk_buff *skb) -@@ -1631,6 +1632,7 @@ int inet_gro_complete(struct sk_buff *skb, int nhoff) - out: - return err; - } -+EXPORT_INDIRECT_CALLABLE(inet_gro_complete); - - static int ipip_gro_complete(struct sk_buff *skb, int nhoff) - { -diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c -index fce91183797a..9e3640b018a4 100644 ---- a/net/ipv6/ip6_offload.c -+++ b/net/ipv6/ip6_offload.c -@@ -306,6 +306,7 @@ INDIRECT_CALLABLE_SCOPE struct sk_buff *ipv6_gro_receive(struct list_head *head, - - return pp; - } -+EXPORT_INDIRECT_CALLABLE(ipv6_gro_receive); - - static struct sk_buff *sit_ip6ip6_gro_receive(struct list_head *head, - struct sk_buff *skb) -@@ -388,6 +389,7 @@ INDIRECT_CALLABLE_SCOPE int ipv6_gro_complete(struct sk_buff *skb, int nhoff) - out: - return err; - } -+EXPORT_INDIRECT_CALLABLE(ipv6_gro_complete); - - static int sit_gro_complete(struct sk_buff *skb, int nhoff) - { --- -2.51.0 - - -From 2e462085b5c2cff943dd6a5620e0f541be7acaeb Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Mon, 3 Nov 2025 15:49:54 +0100 -Subject: [PATCH 262/517] kernel: add a few patches for avoiding unnecessary - skb reallocations - significantly improves ethernet<->wireless performance - -lede-commit: 6f89cffc9add6939d44a6b54cf9a5e77849aa7fd -Signed-off-by: Felix Fietkau ---- - include/linux/skbuff.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h -index 314328ab0b84..eb7b94939f46 100644 ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -3209,7 +3209,7 @@ static inline int pskb_network_may_pull(struct sk_buff *skb, unsigned int len) - * NET_IP_ALIGN(2) + ethernet_header(14) + IP_header(20/40) + ports(8) - */ - #ifndef NET_SKB_PAD --#define NET_SKB_PAD max(32, L1_CACHE_BYTES) -+#define NET_SKB_PAD max(64, L1_CACHE_BYTES) - #endif - - int ___pskb_trim(struct sk_buff *skb, unsigned int len); --- -2.51.0 - - -From 7c39dc46af4ecff37c87b8ed7e9061f44e1401ce Mon Sep 17 00:00:00 2001 -From: Steven Barth -Date: Mon, 3 Nov 2025 15:49:55 +0100 -Subject: [PATCH 263/517] Add support for MAP-E FMRs (mesh mode) - -MAP-E FMRs (draft-ietf-softwire-map-10) are rules for IPv4-communication -between MAP CEs (mesh mode) without the need to forward such data to a -border relay. This is similar to how 6rd works but for IPv4 over IPv6. - -Signed-off-by: Steven Barth ---- - include/net/ip6_tunnel.h | 13 ++ - include/uapi/linux/if_tunnel.h | 13 ++ - net/ipv6/ip6_tunnel.c | 281 ++++++++++++++++++++++++++++++++- - 3 files changed, 299 insertions(+), 8 deletions(-) - -diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h -index 399592405c72..79b066a4d13b 100644 ---- a/include/net/ip6_tunnel.h -+++ b/include/net/ip6_tunnel.h -@@ -18,6 +18,18 @@ - /* determine capability on a per-packet basis */ - #define IP6_TNL_F_CAP_PER_PACKET 0x40000 - -+/* IPv6 tunnel FMR */ -+struct __ip6_tnl_fmr { -+ struct __ip6_tnl_fmr *next; /* next fmr in list */ -+ struct in6_addr ip6_prefix; -+ struct in_addr ip4_prefix; -+ -+ __u8 ip6_prefix_len; -+ __u8 ip4_prefix_len; -+ __u8 ea_len; -+ __u8 offset; -+}; -+ - struct __ip6_tnl_parm { - char name[IFNAMSIZ]; /* name of tunnel device */ - int link; /* ifindex of underlying L2 interface */ -@@ -29,6 +41,7 @@ struct __ip6_tnl_parm { - __u32 flags; /* tunnel flags */ - struct in6_addr laddr; /* local tunnel end-point address */ - struct in6_addr raddr; /* remote tunnel end-point address */ -+ struct __ip6_tnl_fmr *fmrs; /* FMRs */ - - IP_TUNNEL_DECLARE_FLAGS(i_flags); - IP_TUNNEL_DECLARE_FLAGS(o_flags); -diff --git a/include/uapi/linux/if_tunnel.h b/include/uapi/linux/if_tunnel.h -index e1a246dd8c62..fda447945078 100644 ---- a/include/uapi/linux/if_tunnel.h -+++ b/include/uapi/linux/if_tunnel.h -@@ -77,10 +77,23 @@ enum { - IFLA_IPTUN_ENCAP_DPORT, - IFLA_IPTUN_COLLECT_METADATA, - IFLA_IPTUN_FWMARK, -+ IFLA_IPTUN_FMRS, - __IFLA_IPTUN_MAX, - }; - #define IFLA_IPTUN_MAX (__IFLA_IPTUN_MAX - 1) - -+enum { -+ IFLA_IPTUN_FMR_UNSPEC, -+ IFLA_IPTUN_FMR_IP6_PREFIX, -+ IFLA_IPTUN_FMR_IP4_PREFIX, -+ IFLA_IPTUN_FMR_IP6_PREFIX_LEN, -+ IFLA_IPTUN_FMR_IP4_PREFIX_LEN, -+ IFLA_IPTUN_FMR_EA_LEN, -+ IFLA_IPTUN_FMR_OFFSET, -+ __IFLA_IPTUN_FMR_MAX, -+}; -+#define IFLA_IPTUN_FMR_MAX (__IFLA_IPTUN_FMR_MAX - 1) -+ - enum tunnel_encap_types { - TUNNEL_ENCAP_NONE, - TUNNEL_ENCAP_FOU, -diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c -index b72ca1034906..ff58b562758e 100644 ---- a/net/ipv6/ip6_tunnel.c -+++ b/net/ipv6/ip6_tunnel.c -@@ -11,6 +11,9 @@ - * linux/net/ipv6/sit.c and linux/net/ipv4/ipip.c - * - * RFC 2473 -+ * -+ * Changes: -+ * Steven Barth : MAP-E FMR support - */ - - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -@@ -68,9 +71,9 @@ static bool log_ecn_error = true; - module_param(log_ecn_error, bool, 0644); - MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN"); - --static u32 HASH(const struct in6_addr *addr1, const struct in6_addr *addr2) -+static u32 HASH(const struct in6_addr *addr) - { -- u32 hash = ipv6_addr_hash(addr1) ^ ipv6_addr_hash(addr2); -+ u32 hash = ipv6_addr_hash(addr); - - return hash_32(hash, IP6_TUNNEL_HASH_SIZE_SHIFT); - } -@@ -115,17 +118,33 @@ static struct ip6_tnl * - ip6_tnl_lookup(struct net *net, int link, - const struct in6_addr *remote, const struct in6_addr *local) - { -- unsigned int hash = HASH(remote, local); -+ unsigned int hash = HASH(local); - struct ip6_tnl *t, *cand = NULL; - struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); - struct in6_addr any; - - for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) { - if (!ipv6_addr_equal(local, &t->parms.laddr) || -- !ipv6_addr_equal(remote, &t->parms.raddr) || - !(t->dev->flags & IFF_UP)) - continue; - -+ if (!ipv6_addr_equal(remote, &t->parms.raddr)) { -+ struct __ip6_tnl_fmr *fmr; -+ bool found = false; -+ -+ for (fmr = t->parms.fmrs; fmr; fmr = fmr->next) { -+ if (!ipv6_prefix_equal(remote, &fmr->ip6_prefix, -+ fmr->ip6_prefix_len)) -+ continue; -+ -+ found = true; -+ break; -+ } -+ -+ if (!found) -+ continue; -+ } -+ - if (link == t->parms.link) - return t; - else -@@ -133,7 +152,7 @@ ip6_tnl_lookup(struct net *net, int link, - } - - memset(&any, 0, sizeof(any)); -- hash = HASH(&any, local); -+ hash = HASH(local); - for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) { - if (!ipv6_addr_equal(local, &t->parms.laddr) || - !ipv6_addr_any(&t->parms.raddr) || -@@ -146,7 +165,7 @@ ip6_tnl_lookup(struct net *net, int link, - cand = t; - } - -- hash = HASH(remote, &any); -+ hash = HASH(&any); - for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) { - if (!ipv6_addr_equal(remote, &t->parms.raddr) || - !ipv6_addr_any(&t->parms.laddr) || -@@ -195,7 +214,7 @@ ip6_tnl_bucket(struct ip6_tnl_net *ip6n, const struct __ip6_tnl_parm *p) - - if (!ipv6_addr_any(remote) || !ipv6_addr_any(local)) { - prio = 1; -- h = HASH(remote, local); -+ h = HASH(local); - } - return &ip6n->tnls[prio][h]; - } -@@ -376,6 +395,12 @@ ip6_tnl_dev_uninit(struct net_device *dev) - struct net *net = t->net; - struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); - -+ while (t->parms.fmrs) { -+ struct __ip6_tnl_fmr *next = t->parms.fmrs->next; -+ kfree(t->parms.fmrs); -+ t->parms.fmrs = next; -+ } -+ - if (dev == ip6n->fb_tnl_dev) - RCU_INIT_POINTER(ip6n->tnls_wc[0], NULL); - else -@@ -790,6 +815,107 @@ int ip6_tnl_rcv_ctl(struct ip6_tnl *t, - } - EXPORT_SYMBOL_GPL(ip6_tnl_rcv_ctl); - -+/** -+ * ip4ip6_fmr_calc - calculate target / source IPv6-address based on FMR -+ * @dest: destination IPv6 address buffer -+ * @skb: received socket buffer -+ * @fmr: MAP FMR -+ * @xmit: Calculate for xmit or rcv -+ **/ -+static void ip4ip6_fmr_calc(struct in6_addr *dest, -+ const struct iphdr *iph, const uint8_t *end, -+ const struct __ip6_tnl_fmr *fmr, bool xmit) -+{ -+ int psidlen = fmr->ea_len - (32 - fmr->ip4_prefix_len); -+ u8 *portp = NULL; -+ bool use_dest_addr; -+ const struct iphdr *dsth = iph; -+ -+ if ((u8*)dsth >= end) -+ return; -+ -+ /* find significant IP header */ -+ if (iph->protocol == IPPROTO_ICMP) { -+ struct icmphdr *ih = (struct icmphdr*)(((u8*)dsth) + dsth->ihl * 4); -+ if (ih && ((u8*)&ih[1]) <= end && ( -+ ih->type == ICMP_DEST_UNREACH || -+ ih->type == ICMP_SOURCE_QUENCH || -+ ih->type == ICMP_TIME_EXCEEDED || -+ ih->type == ICMP_PARAMETERPROB || -+ ih->type == ICMP_REDIRECT)) -+ dsth = (const struct iphdr*)&ih[1]; -+ } -+ -+ /* in xmit-path use dest port by default and source port only if -+ this is an ICMP reply to something else; vice versa in rcv-path */ -+ use_dest_addr = (xmit && dsth == iph) || (!xmit && dsth != iph); -+ -+ /* get dst port */ -+ if (((u8*)&dsth[1]) <= end && ( -+ dsth->protocol == IPPROTO_UDP || -+ dsth->protocol == IPPROTO_TCP || -+ dsth->protocol == IPPROTO_SCTP || -+ dsth->protocol == IPPROTO_DCCP)) { -+ /* for UDP, TCP, SCTP and DCCP source and dest port -+ follow IPv4 header directly */ -+ portp = ((u8*)dsth) + dsth->ihl * 4; -+ -+ if (use_dest_addr) -+ portp += sizeof(u16); -+ } else if (iph->protocol == IPPROTO_ICMP) { -+ struct icmphdr *ih = (struct icmphdr*)(((u8*)dsth) + dsth->ihl * 4); -+ -+ /* use icmp identifier as port */ -+ if (((u8*)&ih) <= end && ( -+ (use_dest_addr && ( -+ ih->type == ICMP_ECHOREPLY || -+ ih->type == ICMP_TIMESTAMPREPLY || -+ ih->type == ICMP_INFO_REPLY || -+ ih->type == ICMP_ADDRESSREPLY)) || -+ (!use_dest_addr && ( -+ ih->type == ICMP_ECHO || -+ ih->type == ICMP_TIMESTAMP || -+ ih->type == ICMP_INFO_REQUEST || -+ ih->type == ICMP_ADDRESS) -+ ))) -+ portp = (u8*)&ih->un.echo.id; -+ } -+ -+ if ((portp && &portp[2] <= end) || psidlen == 0) { -+ int frombyte = fmr->ip6_prefix_len / 8; -+ int fromrem = fmr->ip6_prefix_len % 8; -+ int bytes = sizeof(struct in6_addr) - frombyte; -+ const u32 *addr = (use_dest_addr) ? &iph->daddr : &iph->saddr; -+ u64 eabits = ((u64)ntohl(*addr)) << (32 + fmr->ip4_prefix_len); -+ u64 t = 0; -+ -+ /* extract PSID from port and add it to eabits */ -+ u16 psidbits = 0; -+ if (psidlen > 0) { -+ psidbits = ((u16)portp[0]) << 8 | ((u16)portp[1]); -+ psidbits >>= 16 - psidlen - fmr->offset; -+ psidbits = (u16)(psidbits << (16 - psidlen)); -+ eabits |= ((u64)psidbits) << (48 - (fmr->ea_len - psidlen)); -+ } -+ -+ /* rewrite destination address */ -+ *dest = fmr->ip6_prefix; -+ memcpy(&dest->s6_addr[10], addr, sizeof(*addr)); -+ dest->s6_addr16[7] = htons(psidbits >> (16 - psidlen)); -+ -+ if (bytes > sizeof(u64)) -+ bytes = sizeof(u64); -+ -+ /* insert eabits */ -+ memcpy(&t, &dest->s6_addr[frombyte], bytes); -+ t = be64_to_cpu(t) & ~(((((u64)1) << fmr->ea_len) - 1) -+ << (64 - fmr->ea_len - fromrem)); -+ t = cpu_to_be64(t | (eabits >> fromrem)); -+ memcpy(&dest->s6_addr[frombyte], &t, bytes); -+ } -+} -+ -+ - static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb, - const struct tnl_ptk_info *tpi, - struct metadata_dst *tun_dst, -@@ -855,6 +981,27 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb, - - memset(skb->cb, 0, sizeof(struct inet6_skb_parm)); - -+ if (tpi->proto == htons(ETH_P_IP) && tunnel->parms.fmrs && -+ !ipv6_addr_equal(&ipv6h->saddr, &tunnel->parms.raddr)) { -+ /* Packet didn't come from BR, so lookup FMR */ -+ struct __ip6_tnl_fmr *fmr; -+ struct in6_addr expected = tunnel->parms.raddr; -+ for (fmr = tunnel->parms.fmrs; fmr; fmr = fmr->next) -+ if (ipv6_prefix_equal(&ipv6h->saddr, -+ &fmr->ip6_prefix, fmr->ip6_prefix_len)) -+ break; -+ -+ /* Check that IPv6 matches IPv4 source to prevent spoofing */ -+ if (fmr) -+ ip4ip6_fmr_calc(&expected, ip_hdr(skb), -+ skb_tail_pointer(skb), fmr, false); -+ -+ if (!ipv6_addr_equal(&ipv6h->saddr, &expected)) { -+ rcu_read_unlock(); -+ goto drop; -+ } -+ } -+ - __skb_tunnel_rx(skb, tunnel->dev, tunnel->net); - - err = dscp_ecn_decapsulate(tunnel, ipv6h, skb); -@@ -1004,6 +1151,7 @@ static void init_tel_txopt(struct ipv6_tel_txoption *opt, __u8 encap_limit) - opt->ops.opt_nflen = 8; - } - -+ - /** - * ip6_tnl_addr_conflict - compare packet addresses to tunnel's own - * @t: the outgoing tunnel device -@@ -1293,6 +1441,7 @@ ipxip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, - u8 protocol) - { - struct ip6_tnl *t = netdev_priv(dev); -+ struct __ip6_tnl_fmr *fmr; - struct ipv6hdr *ipv6h; - const struct iphdr *iph; - int encap_limit = -1; -@@ -1392,6 +1541,18 @@ ipxip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, - fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL); - dsfield = INET_ECN_encapsulate(dsfield, orig_dsfield); - -+ /* try to find matching FMR */ -+ for (fmr = t->parms.fmrs; fmr; fmr = fmr->next) { -+ unsigned mshift = 32 - fmr->ip4_prefix_len; -+ if (ntohl(fmr->ip4_prefix.s_addr) >> mshift == -+ ntohl(ip_hdr(skb)->daddr) >> mshift) -+ break; -+ } -+ -+ /* change dstaddr according to FMR */ -+ if (fmr) -+ ip4ip6_fmr_calc(&fl6.daddr, ip_hdr(skb), skb_tail_pointer(skb), fmr, true); -+ - if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6)) - return -1; - -@@ -1545,6 +1706,14 @@ ip6_tnl_change(struct ip6_tnl *t, const struct __ip6_tnl_parm *p) - t->parms.link = p->link; - t->parms.proto = p->proto; - t->parms.fwmark = p->fwmark; -+ -+ while (t->parms.fmrs) { -+ struct __ip6_tnl_fmr *next = t->parms.fmrs->next; -+ kfree(t->parms.fmrs); -+ t->parms.fmrs = next; -+ } -+ t->parms.fmrs = p->fmrs; -+ - dst_cache_reset(&t->dst_cache); - ip6_tnl_link_config(t); - } -@@ -1579,6 +1748,7 @@ ip6_tnl_parm_from_user(struct __ip6_tnl_parm *p, const struct ip6_tnl_parm *u) - p->flowinfo = u->flowinfo; - p->link = u->link; - p->proto = u->proto; -+ p->fmrs = NULL; - memcpy(p->name, u->name, sizeof(u->name)); - } - -@@ -1962,6 +2132,15 @@ static int ip6_tnl_validate(struct nlattr *tb[], struct nlattr *data[], - return 0; - } - -+static const struct nla_policy ip6_tnl_fmr_policy[IFLA_IPTUN_FMR_MAX + 1] = { -+ [IFLA_IPTUN_FMR_IP6_PREFIX] = { .len = sizeof(struct in6_addr) }, -+ [IFLA_IPTUN_FMR_IP4_PREFIX] = { .len = sizeof(struct in_addr) }, -+ [IFLA_IPTUN_FMR_IP6_PREFIX_LEN] = { .type = NLA_U8 }, -+ [IFLA_IPTUN_FMR_IP4_PREFIX_LEN] = { .type = NLA_U8 }, -+ [IFLA_IPTUN_FMR_EA_LEN] = { .type = NLA_U8 }, -+ [IFLA_IPTUN_FMR_OFFSET] = { .type = NLA_U8 } -+}; -+ - static void ip6_tnl_netlink_parms(struct nlattr *data[], - struct __ip6_tnl_parm *parms) - { -@@ -1999,6 +2178,46 @@ static void ip6_tnl_netlink_parms(struct nlattr *data[], - - if (data[IFLA_IPTUN_FWMARK]) - parms->fwmark = nla_get_u32(data[IFLA_IPTUN_FWMARK]); -+ -+ if (data[IFLA_IPTUN_FMRS]) { -+ unsigned rem; -+ struct nlattr *fmr; -+ nla_for_each_nested(fmr, data[IFLA_IPTUN_FMRS], rem) { -+ struct nlattr *fmrd[IFLA_IPTUN_FMR_MAX + 1], *c; -+ struct __ip6_tnl_fmr *nfmr; -+ -+ nla_parse_nested(fmrd, IFLA_IPTUN_FMR_MAX, -+ fmr, ip6_tnl_fmr_policy, NULL); -+ -+ if (!(nfmr = kzalloc(sizeof(*nfmr), GFP_KERNEL))) -+ continue; -+ -+ nfmr->offset = 6; -+ -+ if ((c = fmrd[IFLA_IPTUN_FMR_IP6_PREFIX])) -+ nla_memcpy(&nfmr->ip6_prefix, fmrd[IFLA_IPTUN_FMR_IP6_PREFIX], -+ sizeof(nfmr->ip6_prefix)); -+ -+ if ((c = fmrd[IFLA_IPTUN_FMR_IP4_PREFIX])) -+ nla_memcpy(&nfmr->ip4_prefix, fmrd[IFLA_IPTUN_FMR_IP4_PREFIX], -+ sizeof(nfmr->ip4_prefix)); -+ -+ if ((c = fmrd[IFLA_IPTUN_FMR_IP6_PREFIX_LEN])) -+ nfmr->ip6_prefix_len = nla_get_u8(c); -+ -+ if ((c = fmrd[IFLA_IPTUN_FMR_IP4_PREFIX_LEN])) -+ nfmr->ip4_prefix_len = nla_get_u8(c); -+ -+ if ((c = fmrd[IFLA_IPTUN_FMR_EA_LEN])) -+ nfmr->ea_len = nla_get_u8(c); -+ -+ if ((c = fmrd[IFLA_IPTUN_FMR_OFFSET])) -+ nfmr->offset = nla_get_u8(c); -+ -+ nfmr->next = parms->fmrs; -+ parms->fmrs = nfmr; -+ } -+ } - } - - static int ip6_tnl_newlink(struct net *src_net, struct net_device *dev, -@@ -2083,6 +2302,12 @@ static void ip6_tnl_dellink(struct net_device *dev, struct list_head *head) - - static size_t ip6_tnl_get_size(const struct net_device *dev) - { -+ const struct ip6_tnl *t = netdev_priv(dev); -+ struct __ip6_tnl_fmr *c; -+ int fmrs = 0; -+ for (c = t->parms.fmrs; c; c = c->next) -+ ++fmrs; -+ - return - /* IFLA_IPTUN_LINK */ - nla_total_size(4) + -@@ -2112,6 +2337,24 @@ static size_t ip6_tnl_get_size(const struct net_device *dev) - nla_total_size(0) + - /* IFLA_IPTUN_FWMARK */ - nla_total_size(4) + -+ /* IFLA_IPTUN_FMRS */ -+ nla_total_size(0) + -+ ( -+ /* nest */ -+ nla_total_size(0) + -+ /* IFLA_IPTUN_FMR_IP6_PREFIX */ -+ nla_total_size(sizeof(struct in6_addr)) + -+ /* IFLA_IPTUN_FMR_IP4_PREFIX */ -+ nla_total_size(sizeof(struct in_addr)) + -+ /* IFLA_IPTUN_FMR_EA_LEN */ -+ nla_total_size(1) + -+ /* IFLA_IPTUN_FMR_IP6_PREFIX_LEN */ -+ nla_total_size(1) + -+ /* IFLA_IPTUN_FMR_IP4_PREFIX_LEN */ -+ nla_total_size(1) + -+ /* IFLA_IPTUN_FMR_OFFSET */ -+ nla_total_size(1) -+ ) * fmrs + - 0; - } - -@@ -2119,6 +2362,9 @@ static int ip6_tnl_fill_info(struct sk_buff *skb, const struct net_device *dev) - { - struct ip6_tnl *tunnel = netdev_priv(dev); - struct __ip6_tnl_parm *parm = &tunnel->parms; -+ struct __ip6_tnl_fmr *c; -+ int fmrcnt = 0; -+ struct nlattr *fmrs; - - if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) || - nla_put_in6_addr(skb, IFLA_IPTUN_LOCAL, &parm->laddr) || -@@ -2128,9 +2374,27 @@ static int ip6_tnl_fill_info(struct sk_buff *skb, const struct net_device *dev) - nla_put_be32(skb, IFLA_IPTUN_FLOWINFO, parm->flowinfo) || - nla_put_u32(skb, IFLA_IPTUN_FLAGS, parm->flags) || - nla_put_u8(skb, IFLA_IPTUN_PROTO, parm->proto) || -- nla_put_u32(skb, IFLA_IPTUN_FWMARK, parm->fwmark)) -+ nla_put_u32(skb, IFLA_IPTUN_FWMARK, parm->fwmark) || -+ !(fmrs = nla_nest_start(skb, IFLA_IPTUN_FMRS))) - goto nla_put_failure; - -+ for (c = parm->fmrs; c; c = c->next) { -+ struct nlattr *fmr = nla_nest_start(skb, ++fmrcnt); -+ if (!fmr || -+ nla_put(skb, IFLA_IPTUN_FMR_IP6_PREFIX, -+ sizeof(c->ip6_prefix), &c->ip6_prefix) || -+ nla_put(skb, IFLA_IPTUN_FMR_IP4_PREFIX, -+ sizeof(c->ip4_prefix), &c->ip4_prefix) || -+ nla_put_u8(skb, IFLA_IPTUN_FMR_IP6_PREFIX_LEN, c->ip6_prefix_len) || -+ nla_put_u8(skb, IFLA_IPTUN_FMR_IP4_PREFIX_LEN, c->ip4_prefix_len) || -+ nla_put_u8(skb, IFLA_IPTUN_FMR_EA_LEN, c->ea_len) || -+ nla_put_u8(skb, IFLA_IPTUN_FMR_OFFSET, c->offset)) -+ goto nla_put_failure; -+ -+ nla_nest_end(skb, fmr); -+ } -+ nla_nest_end(skb, fmrs); -+ - if (nla_put_u16(skb, IFLA_IPTUN_ENCAP_TYPE, tunnel->encap.type) || - nla_put_be16(skb, IFLA_IPTUN_ENCAP_SPORT, tunnel->encap.sport) || - nla_put_be16(skb, IFLA_IPTUN_ENCAP_DPORT, tunnel->encap.dport) || -@@ -2170,6 +2434,7 @@ static const struct nla_policy ip6_tnl_policy[IFLA_IPTUN_MAX + 1] = { - [IFLA_IPTUN_ENCAP_DPORT] = { .type = NLA_U16 }, - [IFLA_IPTUN_COLLECT_METADATA] = { .type = NLA_FLAG }, - [IFLA_IPTUN_FWMARK] = { .type = NLA_U32 }, -+ [IFLA_IPTUN_FMRS] = { .type = NLA_NESTED }, - }; - - static struct rtnl_link_ops ip6_link_ops __read_mostly = { --- -2.51.0 - - -From 3878b9edc9d3b56abb5439d09dc4f05403518e35 Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Mon, 3 Nov 2025 15:49:55 +0100 -Subject: [PATCH 264/517] ipv6: allow rejecting with "source address failed - policy" - -RFC6204 L-14 requires rejecting traffic from invalid addresses with -ICMPv6 Destination Unreachable, Code 5 (Source address failed ingress/ -egress policy) on the LAN side, so add an appropriate rule for that. - -Signed-off-by: Jonas Gorski ---- - include/net/netns/ipv6.h | 1 + - include/uapi/linux/fib_rules.h | 4 +++ - include/uapi/linux/rtnetlink.h | 1 + - net/ipv4/fib_semantics.c | 4 +++ - net/ipv4/fib_trie.c | 1 + - net/ipv4/ipmr.c | 1 + - net/ipv6/fib6_rules.c | 4 +++ - net/ipv6/ip6mr.c | 2 ++ - net/ipv6/route.c | 56 ++++++++++++++++++++++++++++++++-- - 9 files changed, 72 insertions(+), 2 deletions(-) - -diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h -index 5f2cfd84570a..c56a4b0e9636 100644 ---- a/include/net/netns/ipv6.h -+++ b/include/net/netns/ipv6.h -@@ -86,6 +86,7 @@ struct netns_ipv6 { - unsigned int fib6_routes_require_src; - #endif - struct rt6_info *ip6_prohibit_entry; -+ struct rt6_info *ip6_policy_failed_entry; - struct rt6_info *ip6_blk_hole_entry; - struct fib6_table *fib6_local_tbl; - struct fib_rules_ops *fib6_rules_ops; -diff --git a/include/uapi/linux/fib_rules.h b/include/uapi/linux/fib_rules.h -index a6924dd3aff1..4b3e1d99a654 100644 ---- a/include/uapi/linux/fib_rules.h -+++ b/include/uapi/linux/fib_rules.h -@@ -83,6 +83,10 @@ enum { - FR_ACT_BLACKHOLE, /* Drop without notification */ - FR_ACT_UNREACHABLE, /* Drop with ENETUNREACH */ - FR_ACT_PROHIBIT, /* Drop with EACCES */ -+ FR_ACT_RES9, -+ FR_ACT_RES10, -+ FR_ACT_RES11, -+ FR_ACT_POLICY_FAILED, /* Drop with EACCES */ - __FR_ACT_MAX, - }; - -diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h -index db7254d52d93..d49560d2bd71 100644 ---- a/include/uapi/linux/rtnetlink.h -+++ b/include/uapi/linux/rtnetlink.h -@@ -265,6 +265,7 @@ enum { - RTN_THROW, /* Not in this table */ - RTN_NAT, /* Translate this address */ - RTN_XRESOLVE, /* Use external resolver */ -+ RTN_POLICY_FAILED, /* Failed ingress/egress policy */ - __RTN_MAX - }; - -diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c -index ba2df3d2ac15..f70f87839faa 100644 ---- a/net/ipv4/fib_semantics.c -+++ b/net/ipv4/fib_semantics.c -@@ -145,6 +145,10 @@ const struct fib_prop fib_props[RTN_MAX + 1] = { - .error = -EINVAL, - .scope = RT_SCOPE_NOWHERE, - }, -+ [RTN_POLICY_FAILED] = { -+ .error = -EACCES, -+ .scope = RT_SCOPE_UNIVERSE, -+ }, - }; - - static void rt_fibinfo_free(struct rtable __rcu **rtp) -diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c -index cc86031d2050..b7440806041b 100644 ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -2762,6 +2762,7 @@ static const char *const rtn_type_names[__RTN_MAX] = { - [RTN_THROW] = "THROW", - [RTN_NAT] = "NAT", - [RTN_XRESOLVE] = "XRESOLVE", -+ [RTN_POLICY_FAILED] = "POLICY_FAILED", - }; - - static inline const char *rtn_type(char *buf, size_t len, unsigned int t) -diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c -index de0d9cc7806a..bef0f63f4fd4 100644 ---- a/net/ipv4/ipmr.c -+++ b/net/ipv4/ipmr.c -@@ -191,6 +191,7 @@ static int ipmr_rule_action(struct fib_rule *rule, struct flowi *flp, - case FR_ACT_UNREACHABLE: - return -ENETUNREACH; - case FR_ACT_PROHIBIT: -+ case FR_ACT_POLICY_FAILED: - return -EACCES; - case FR_ACT_BLACKHOLE: - default: -diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c -index 29185c9ebd02..369fcdcfd0f0 100644 ---- a/net/ipv6/fib6_rules.c -+++ b/net/ipv6/fib6_rules.c -@@ -222,6 +222,10 @@ static int __fib6_rule_action(struct fib_rule *rule, struct flowi *flp, - err = -EACCES; - rt = net->ipv6.ip6_prohibit_entry; - goto discard_pkt; -+ case FR_ACT_POLICY_FAILED: -+ err = -EACCES; -+ rt = net->ipv6.ip6_policy_failed_entry; -+ goto discard_pkt; - } - - tb_id = fib_rule_get_table(rule, arg); -diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c -index 68bc518500f9..685d4c37b6ed 100644 ---- a/net/ipv6/ip6mr.c -+++ b/net/ipv6/ip6mr.c -@@ -180,6 +180,8 @@ static int ip6mr_rule_action(struct fib_rule *rule, struct flowi *flp, - return -ENETUNREACH; - case FR_ACT_PROHIBIT: - return -EACCES; -+ case FR_ACT_POLICY_FAILED: -+ return -EACCES; - case FR_ACT_BLACKHOLE: - default: - return -EINVAL; -diff --git a/net/ipv6/route.c b/net/ipv6/route.c -index 22866444efc0..33cfc2dc9aaf 100644 ---- a/net/ipv6/route.c -+++ b/net/ipv6/route.c -@@ -98,6 +98,8 @@ static int ip6_pkt_discard(struct sk_buff *skb); - static int ip6_pkt_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb); - static int ip6_pkt_prohibit(struct sk_buff *skb); - static int ip6_pkt_prohibit_out(struct net *net, struct sock *sk, struct sk_buff *skb); -+static int ip6_pkt_policy_failed(struct sk_buff *skb); -+static int ip6_pkt_policy_failed_out(struct net *net, struct sock *sk, struct sk_buff *skb); - static void ip6_link_failure(struct sk_buff *skb); - static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, - struct sk_buff *skb, u32 mtu, -@@ -316,6 +318,18 @@ static const struct rt6_info ip6_prohibit_entry_template = { - .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), - }; - -+static const struct rt6_info ip6_policy_failed_entry_template = { -+ .dst = { -+ .__rcuref = RCUREF_INIT(1), -+ .__use = 1, -+ .obsolete = DST_OBSOLETE_FORCE_CHK, -+ .error = -EACCES, -+ .input = ip6_pkt_policy_failed, -+ .output = ip6_pkt_policy_failed_out, -+ }, -+ .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), -+}; -+ - static const struct rt6_info ip6_blk_hole_entry_template = { - .dst = { - .__rcuref = RCUREF_INIT(1), -@@ -1085,6 +1099,7 @@ static const int fib6_prop[RTN_MAX + 1] = { - [RTN_BLACKHOLE] = -EINVAL, - [RTN_UNREACHABLE] = -EHOSTUNREACH, - [RTN_PROHIBIT] = -EACCES, -+ [RTN_POLICY_FAILED] = -EACCES, - [RTN_THROW] = -EAGAIN, - [RTN_NAT] = -EINVAL, - [RTN_XRESOLVE] = -EINVAL, -@@ -1120,6 +1135,10 @@ static void ip6_rt_init_dst_reject(struct rt6_info *rt, u8 fib6_type) - rt->dst.output = ip6_pkt_prohibit_out; - rt->dst.input = ip6_pkt_prohibit; - break; -+ case RTN_POLICY_FAILED: -+ rt->dst.output = ip6_pkt_policy_failed_out; -+ rt->dst.input = ip6_pkt_policy_failed; -+ break; - case RTN_THROW: - case RTN_UNREACHABLE: - default: -@@ -4598,6 +4617,17 @@ static int ip6_pkt_prohibit_out(struct net *net, struct sock *sk, struct sk_buff - return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); - } - -+static int ip6_pkt_policy_failed(struct sk_buff *skb) -+{ -+ return ip6_pkt_drop(skb, ICMPV6_POLICY_FAIL, IPSTATS_MIB_INNOROUTES); -+} -+ -+static int ip6_pkt_policy_failed_out(struct net *net, struct sock *sk, struct sk_buff *skb) -+{ -+ skb->dev = skb_dst(skb)->dev; -+ return ip6_pkt_drop(skb, ICMPV6_POLICY_FAIL, IPSTATS_MIB_OUTNOROUTES); -+} -+ - /* - * Allocate a dst for local (unicast / anycast) address. - */ -@@ -5089,7 +5119,8 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, - if (rtm->rtm_type == RTN_UNREACHABLE || - rtm->rtm_type == RTN_BLACKHOLE || - rtm->rtm_type == RTN_PROHIBIT || -- rtm->rtm_type == RTN_THROW) -+ rtm->rtm_type == RTN_THROW || -+ rtm->rtm_type == RTN_POLICY_FAILED) - cfg->fc_flags |= RTF_REJECT; - - if (rtm->rtm_type == RTN_LOCAL) -@@ -6357,6 +6388,8 @@ static int ip6_route_dev_notify(struct notifier_block *this, - #ifdef CONFIG_IPV6_MULTIPLE_TABLES - net->ipv6.ip6_prohibit_entry->dst.dev = dev; - net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev); -+ net->ipv6.ip6_policy_failed_entry->dst.dev = dev; -+ net->ipv6.ip6_policy_failed_entry->rt6i_idev = in6_dev_get(dev); - net->ipv6.ip6_blk_hole_entry->dst.dev = dev; - net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev); - #endif -@@ -6368,6 +6401,7 @@ static int ip6_route_dev_notify(struct notifier_block *this, - in6_dev_put_clear(&net->ipv6.ip6_null_entry->rt6i_idev); - #ifdef CONFIG_IPV6_MULTIPLE_TABLES - in6_dev_put_clear(&net->ipv6.ip6_prohibit_entry->rt6i_idev); -+ in6_dev_put_clear(&net->ipv6.ip6_policy_failed_entry->rt6i_idev); - in6_dev_put_clear(&net->ipv6.ip6_blk_hole_entry->rt6i_idev); - #endif - } -@@ -6563,6 +6597,8 @@ static int __net_init ip6_route_net_init(struct net *net) - - #ifdef CONFIG_IPV6_MULTIPLE_TABLES - net->ipv6.fib6_has_custom_rules = false; -+ -+ - net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template, - sizeof(*net->ipv6.ip6_prohibit_entry), - GFP_KERNEL); -@@ -6573,11 +6609,21 @@ static int __net_init ip6_route_net_init(struct net *net) - ip6_template_metrics, true); - INIT_LIST_HEAD(&net->ipv6.ip6_prohibit_entry->dst.rt_uncached); - -+ net->ipv6.ip6_policy_failed_entry = -+ kmemdup(&ip6_policy_failed_entry_template, -+ sizeof(*net->ipv6.ip6_policy_failed_entry), GFP_KERNEL); -+ if (!net->ipv6.ip6_policy_failed_entry) -+ goto out_ip6_prohibit_entry; -+ net->ipv6.ip6_policy_failed_entry->dst.ops = &net->ipv6.ip6_dst_ops; -+ dst_init_metrics(&net->ipv6.ip6_policy_failed_entry->dst, -+ ip6_template_metrics, true); -+ INIT_LIST_HEAD(&net->ipv6.ip6_policy_failed_entry->dst.rt_uncached); -+ - net->ipv6.ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template, - sizeof(*net->ipv6.ip6_blk_hole_entry), - GFP_KERNEL); - if (!net->ipv6.ip6_blk_hole_entry) -- goto out_ip6_prohibit_entry; -+ goto out_ip6_policy_failed_entry; - net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops; - dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst, - ip6_template_metrics, true); -@@ -6604,6 +6650,8 @@ static int __net_init ip6_route_net_init(struct net *net) - return ret; - - #ifdef CONFIG_IPV6_MULTIPLE_TABLES -+out_ip6_policy_failed_entry: -+ kfree(net->ipv6.ip6_policy_failed_entry); - out_ip6_prohibit_entry: - kfree(net->ipv6.ip6_prohibit_entry); - out_ip6_null_entry: -@@ -6623,6 +6671,7 @@ static void __net_exit ip6_route_net_exit(struct net *net) - kfree(net->ipv6.ip6_null_entry); - #ifdef CONFIG_IPV6_MULTIPLE_TABLES - kfree(net->ipv6.ip6_prohibit_entry); -+ kfree(net->ipv6.ip6_policy_failed_entry); - kfree(net->ipv6.ip6_blk_hole_entry); - #endif - dst_entries_destroy(&net->ipv6.ip6_dst_ops); -@@ -6706,6 +6755,9 @@ void __init ip6_route_init_special_entries(void) - init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); - init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev; - init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); -+ init_net.ipv6.ip6_policy_failed_entry->dst.dev = init_net.loopback_dev; -+ init_net.ipv6.ip6_policy_failed_entry->rt6i_idev = -+ in6_dev_get(init_net.loopback_dev); - #endif - } - --- -2.51.0 - - -From afd618b85af8f8aac217bd64b5626dd6062caf19 Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Mon, 3 Nov 2025 15:49:55 +0100 -Subject: [PATCH 265/517] net: provide defines for _POLICY_FAILED until all - code is updated - -Upstream introduced ICMPV6_POLICY_FAIL for code 5 of destination -unreachable, conflicting with our name. - -Add appropriate defines to allow our code to build with the new -name until we have updated our local patches for older kernels -and userspace packages. - -Signed-off-by: Jonas Gorski ---- - include/uapi/linux/fib_rules.h | 2 ++ - include/uapi/linux/icmpv6.h | 2 ++ - include/uapi/linux/rtnetlink.h | 2 ++ - 3 files changed, 6 insertions(+) - -diff --git a/include/uapi/linux/fib_rules.h b/include/uapi/linux/fib_rules.h -index 4b3e1d99a654..598fe9d0f409 100644 ---- a/include/uapi/linux/fib_rules.h -+++ b/include/uapi/linux/fib_rules.h -@@ -90,6 +90,8 @@ enum { - __FR_ACT_MAX, - }; - -+#define FR_ACT_FAILED_POLICY FR_ACT_POLICY_FAILED -+ - #define FR_ACT_MAX (__FR_ACT_MAX - 1) - - #endif -diff --git a/include/uapi/linux/icmpv6.h b/include/uapi/linux/icmpv6.h -index 4eaab89e2856..1d7e12b488ac 100644 ---- a/include/uapi/linux/icmpv6.h -+++ b/include/uapi/linux/icmpv6.h -@@ -127,6 +127,8 @@ struct icmp6hdr { - #define ICMPV6_POLICY_FAIL 5 - #define ICMPV6_REJECT_ROUTE 6 - -+#define ICMPV6_FAILED_POLICY ICMPV6_POLICY_FAIL -+ - /* - * Codes for Time Exceeded - */ -diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h -index d49560d2bd71..795736ef4217 100644 ---- a/include/uapi/linux/rtnetlink.h -+++ b/include/uapi/linux/rtnetlink.h -@@ -269,6 +269,8 @@ enum { - __RTN_MAX - }; - -+#define RTN_FAILED_POLICY RTN_POLICY_FAILED -+ - #define RTN_MAX (__RTN_MAX - 1) - - --- -2.51.0 - - -From d1e0e08702e53d8608d0464cace36a3e1ef428b3 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Thu, 15 Aug 2024 21:15:13 +0200 -Subject: [PATCH 266/517] net: remove NETIF_F_GSO_FRAGLIST from - NETIF_F_GSO_SOFTWARE - -Several drivers set NETIF_F_GSO_SOFTWARE, but mangle fraglist GRO packets -in a way that they can't be properly segmented anymore. -In order to properly deal with this, remove fraglist GSO from -NETIF_F_GSO_SOFTWARE and switch to NETIF_F_GSO_SOFTWARE_ALL (which includes -fraglist GSO) in places where it's safe to add. - -Signed-off-by: Felix Fietkau ---- - drivers/net/dummy.c | 2 +- - drivers/net/loopback.c | 2 +- - drivers/net/macvlan.c | 2 +- - include/linux/netdev_features.h | 5 +++-- - net/8021q/vlan.h | 2 +- - net/8021q/vlan_dev.c | 4 ++-- - net/core/sock.c | 2 +- - net/mac80211/ieee80211_i.h | 2 +- - net/openvswitch/vport-internal_dev.c | 2 +- - 9 files changed, 12 insertions(+), 11 deletions(-) - -diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c -index e9c5e1e11fa0..d32b6190bde1 100644 ---- a/drivers/net/dummy.c -+++ b/drivers/net/dummy.c -@@ -111,7 +111,7 @@ static void dummy_setup(struct net_device *dev) - dev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_NO_QUEUE; - dev->lltx = true; - dev->features |= NETIF_F_SG | NETIF_F_FRAGLIST; -- dev->features |= NETIF_F_GSO_SOFTWARE; -+ dev->features |= NETIF_F_GSO_SOFTWARE_ALL; - dev->features |= NETIF_F_HW_CSUM | NETIF_F_HIGHDMA; - dev->features |= NETIF_F_GSO_ENCAP_ALL; - dev->hw_features |= dev->features; -diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c -index 491e56b3263f..602396bec287 100644 ---- a/drivers/net/loopback.c -+++ b/drivers/net/loopback.c -@@ -174,7 +174,7 @@ static void gen_lo_setup(struct net_device *dev, - dev->lltx = true; - dev->netns_local = true; - netif_keep_dst(dev); -- dev->hw_features = NETIF_F_GSO_SOFTWARE; -+ dev->hw_features = NETIF_F_GSO_SOFTWARE_ALL; - dev->features = NETIF_F_SG | NETIF_F_FRAGLIST - | NETIF_F_GSO_SOFTWARE - | NETIF_F_HW_CSUM -diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c -index cf18e66de142..e1a501061d21 100644 ---- a/drivers/net/macvlan.c -+++ b/drivers/net/macvlan.c -@@ -897,7 +897,7 @@ static int macvlan_hwtstamp_set(struct net_device *dev, - static struct lock_class_key macvlan_netdev_addr_lock_key; - - #define ALWAYS_ON_OFFLOADS \ -- (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE | \ -+ (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE_ALL | \ - NETIF_F_GSO_ROBUST | NETIF_F_GSO_ENCAP_ALL) - - #define ALWAYS_ON_FEATURES ALWAYS_ON_OFFLOADS -diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h -index 11be70a7929f..e2e3dd919068 100644 ---- a/include/linux/netdev_features.h -+++ b/include/linux/netdev_features.h -@@ -211,13 +211,14 @@ static inline int find_next_netdev_feature(u64 feature, unsigned long start) - - /* List of features with software fallbacks. */ - #define NETIF_F_GSO_SOFTWARE (NETIF_F_ALL_TSO | NETIF_F_GSO_SCTP | \ -- NETIF_F_GSO_UDP_L4 | NETIF_F_GSO_FRAGLIST) -+ NETIF_F_GSO_UDP_L4) -+#define NETIF_F_GSO_SOFTWARE_ALL (NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_FRAGLIST) - - /* - * If one device supports one of these features, then enable them - * for all in netdev_increment_features. - */ --#define NETIF_F_ONE_FOR_ALL (NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ROBUST | \ -+#define NETIF_F_ONE_FOR_ALL (NETIF_F_GSO_SOFTWARE_ALL | NETIF_F_GSO_ROBUST | \ - NETIF_F_SG | NETIF_F_HIGHDMA | \ - NETIF_F_FRAGLIST | NETIF_F_VLAN_CHALLENGED) - -diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h -index c7ffe591d593..8a446f996172 100644 ---- a/net/8021q/vlan.h -+++ b/net/8021q/vlan.h -@@ -109,7 +109,7 @@ static inline netdev_features_t vlan_tnl_features(struct net_device *real_dev) - netdev_features_t ret; - - ret = real_dev->hw_enc_features & -- (NETIF_F_CSUM_MASK | NETIF_F_GSO_SOFTWARE | -+ (NETIF_F_CSUM_MASK | NETIF_F_GSO_SOFTWARE_ALL | - NETIF_F_GSO_ENCAP_ALL); - - if ((ret & NETIF_F_GSO_ENCAP_ALL) && (ret & NETIF_F_CSUM_MASK)) -diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c -index 9184cf7eb128..3cecafc13a3e 100644 ---- a/net/8021q/vlan_dev.c -+++ b/net/8021q/vlan_dev.c -@@ -538,7 +538,7 @@ static int vlan_dev_init(struct net_device *dev) - dev->state |= (1 << __LINK_STATE_NOCARRIER); - - dev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG | -- NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE | -+ NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE_ALL | - NETIF_F_GSO_ENCAP_ALL | - NETIF_F_HIGHDMA | NETIF_F_SCTP_CRC | - NETIF_F_FCOE_CRC | NETIF_F_FSO; -@@ -634,7 +634,7 @@ static netdev_features_t vlan_dev_fix_features(struct net_device *dev, - if (lower_features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM)) - lower_features |= NETIF_F_HW_CSUM; - features = netdev_intersect_features(features, lower_features); -- features |= old_features & (NETIF_F_SOFT_FEATURES | NETIF_F_GSO_SOFTWARE); -+ features |= old_features & (NETIF_F_SOFT_FEATURES | NETIF_F_GSO_SOFTWARE_ALL); - - return features; - } -diff --git a/net/core/sock.c b/net/core/sock.c -index a5f248a91404..57fafa7cb47b 100644 ---- a/net/core/sock.c -+++ b/net/core/sock.c -@@ -2554,7 +2554,7 @@ void sk_setup_caps(struct sock *sk, struct dst_entry *dst) - icsk->icsk_ack.dst_quick_ack = dst_metric(dst, RTAX_QUICKACK); - } - if (sk->sk_route_caps & NETIF_F_GSO) -- sk->sk_route_caps |= NETIF_F_GSO_SOFTWARE; -+ sk->sk_route_caps |= NETIF_F_GSO_SOFTWARE_ALL; - if (unlikely(sk->sk_gso_disabled)) - sk->sk_route_caps &= ~NETIF_F_GSO_MASK; - if (sk_can_gso(sk)) { -diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h -index 2f017dbbcb97..6289ba270e23 100644 ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -2021,7 +2021,7 @@ void ieee80211_color_collision_detection_work(struct wiphy *wiphy, - /* interface handling */ - #define MAC80211_SUPPORTED_FEATURES_TX (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \ - NETIF_F_HW_CSUM | NETIF_F_SG | \ -- NETIF_F_HIGHDMA | NETIF_F_GSO_SOFTWARE | \ -+ NETIF_F_HIGHDMA | NETIF_F_GSO_SOFTWARE_ALL | \ - NETIF_F_HW_TC) - #define MAC80211_SUPPORTED_FEATURES_RX (NETIF_F_RXCSUM) - #define MAC80211_SUPPORTED_FEATURES (MAC80211_SUPPORTED_FEATURES_TX | \ -diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c -index 5858d65ea1a9..2bc32affb98a 100644 ---- a/net/openvswitch/vport-internal_dev.c -+++ b/net/openvswitch/vport-internal_dev.c -@@ -109,7 +109,7 @@ static void do_setup(struct net_device *netdev) - netdev->rtnl_link_ops = &internal_dev_link_ops; - - netdev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | -- NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE | -+ NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE_ALL | - NETIF_F_GSO_ENCAP_ALL; - - netdev->vlan_features = netdev->features; --- -2.51.0 - - -From 1d33d41f90da611376b78c3db81b12643fd330da Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 12:22:48 +0200 -Subject: [PATCH 267/517] of/of_net: write back netdev MAC-address to - device-tree - -The label-mac logic relies on the mac-address property of a netdev -devices of-node. However, the mac address can also be stored as a -different property or read from e.g. an mtd device. - -Create this node when reading a mac-address from OF if it does not -already exist and copy the mac-address used for the device to this -property. This way, the MAC address can be accessed using procfs. ---- - net/core/of_net.c | 35 +++++++++++++++++++++++++++++++---- - 1 file changed, 31 insertions(+), 4 deletions(-) - -diff --git a/net/core/of_net.c b/net/core/of_net.c -index 93ea425b9248..2497ae67dad5 100644 ---- a/net/core/of_net.c -+++ b/net/core/of_net.c -@@ -97,6 +97,27 @@ int of_get_mac_address_nvmem(struct device_node *np, u8 *addr) - } - EXPORT_SYMBOL(of_get_mac_address_nvmem); - -+static int of_add_mac_address(struct device_node *np, u8* addr) -+{ -+ struct property *prop; -+ -+ prop = kzalloc(sizeof(*prop), GFP_KERNEL); -+ if (!prop) -+ return -ENOMEM; -+ -+ prop->name = "mac-address"; -+ prop->length = ETH_ALEN; -+ prop->value = kmemdup(addr, ETH_ALEN, GFP_KERNEL); -+ if (!prop->value || of_update_property(np, prop)) -+ goto free; -+ -+ return 0; -+free: -+ kfree(prop->value); -+ kfree(prop); -+ return -ENOMEM; -+} -+ - /** - * of_get_mac_address() - * @np: Caller's Device Node -@@ -132,17 +153,23 @@ int of_get_mac_address(struct device_node *np, u8 *addr) - - ret = of_get_mac_addr(np, "mac-address", addr); - if (!ret) -- return 0; -+ goto found; - - ret = of_get_mac_addr(np, "local-mac-address", addr); - if (!ret) -- return 0; -+ goto found; - - ret = of_get_mac_addr(np, "address", addr); - if (!ret) -- return 0; -+ goto found; - -- return of_get_mac_address_nvmem(np, addr); -+ ret = of_get_mac_address_nvmem(np, addr); -+ if (ret) -+ return ret; -+ -+found: -+ ret = of_add_mac_address(np, addr); -+ return ret; - } - EXPORT_SYMBOL(of_get_mac_address); - --- -2.51.0 - - -From f601c2883cdc25ee169350d3477da082fe5c5779 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Tue, 7 May 2024 11:24:50 +0200 -Subject: [PATCH 268/517] net: add missing check for TCP fraglist GRO - -It turns out that the existing checks do not guarantee that the skb can be -pulled up to the GRO offset. When using the usb r8152 network driver with -GRO fraglist, the BUG() in __skb_pull is often triggered. -Fix the crash by adding the missing check. - -Fixes: 8d95dc474f85 ("net: add code for TCP fraglist GRO") -Signed-off-by: Felix Fietkau ---- - net/ipv4/tcp_offload.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/net/ipv4/tcp_offload.c b/net/ipv4/tcp_offload.c -index 3a9c5c14c310..eaf92be2d7fe 100644 ---- a/net/ipv4/tcp_offload.c -+++ b/net/ipv4/tcp_offload.c -@@ -354,6 +354,7 @@ struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb, - flush |= (__force int)(flags ^ tcp_flag_word(th2)); - flush |= skb->ip_summed != p->ip_summed; - flush |= skb->csum_level != p->csum_level; -+ flush |= !pskb_may_pull(skb, skb_gro_offset(skb)); - flush |= NAPI_GRO_CB(p)->count >= 64; - skb_set_network_header(skb, skb_gro_receive_network_offset(skb)); - --- -2.51.0 - - -From 7cdbd6508ee5fe893169c25d43598829a6fecc1d Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Thu, 25 Jan 2018 12:58:55 +0100 -Subject: [PATCH 269/517] netfilter: nft_flow_offload: handle netdevice events - from nf_flow_table - -Move the code that deals with device events to the core. - -Signed-off-by: Pablo Neira Ayuso ---- - net/netfilter/nf_flow_table_core.c | 22 +++++++++++++++++++ - net/netfilter/nft_flow_offload.c | 35 +----------------------------- - 2 files changed, 23 insertions(+), 34 deletions(-) - -diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c -index df72b0376970..54881f0e878a 100644 ---- a/net/netfilter/nf_flow_table_core.c -+++ b/net/netfilter/nf_flow_table_core.c -@@ -658,6 +658,23 @@ static struct pernet_operations nf_flow_table_net_ops = { - .exit_batch = nf_flow_table_pernet_exit, - }; - -+static int nf_flow_table_netdev_event(struct notifier_block *this, -+ unsigned long event, void *ptr) -+{ -+ struct net_device *dev = netdev_notifier_info_to_dev(ptr); -+ -+ if (event != NETDEV_DOWN) -+ return NOTIFY_DONE; -+ -+ nf_flow_table_cleanup(dev); -+ -+ return NOTIFY_DONE; -+} -+ -+static struct notifier_block flow_offload_netdev_notifier = { -+ .notifier_call = nf_flow_table_netdev_event, -+}; -+ - static int __init nf_flow_table_module_init(void) - { - int ret; -@@ -674,6 +691,10 @@ static int __init nf_flow_table_module_init(void) - if (ret) - goto out_bpf; - -+ ret = register_netdevice_notifier(&flow_offload_netdev_notifier); -+ if (ret) -+ goto out_bpf; -+ - return 0; - - out_bpf: -@@ -685,6 +706,7 @@ static int __init nf_flow_table_module_init(void) - - static void __exit nf_flow_table_module_exit(void) - { -+ unregister_netdevice_notifier(&flow_offload_netdev_notifier); - nf_flow_table_offload_exit(); - unregister_pernet_subsys(&nf_flow_table_net_ops); - } -diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c -index da9ebd00b198..a7611b8a7ca2 100644 ---- a/net/netfilter/nft_flow_offload.c -+++ b/net/netfilter/nft_flow_offload.c -@@ -487,47 +487,14 @@ static struct nft_expr_type nft_flow_offload_type __read_mostly = { - .owner = THIS_MODULE, - }; - --static int flow_offload_netdev_event(struct notifier_block *this, -- unsigned long event, void *ptr) --{ -- struct net_device *dev = netdev_notifier_info_to_dev(ptr); -- -- if (event != NETDEV_DOWN) -- return NOTIFY_DONE; -- -- nf_flow_table_cleanup(dev); -- -- return NOTIFY_DONE; --} -- --static struct notifier_block flow_offload_netdev_notifier = { -- .notifier_call = flow_offload_netdev_event, --}; -- - static int __init nft_flow_offload_module_init(void) - { -- int err; -- -- err = register_netdevice_notifier(&flow_offload_netdev_notifier); -- if (err) -- goto err; -- -- err = nft_register_expr(&nft_flow_offload_type); -- if (err < 0) -- goto register_expr; -- -- return 0; -- --register_expr: -- unregister_netdevice_notifier(&flow_offload_netdev_notifier); --err: -- return err; -+ return nft_register_expr(&nft_flow_offload_type); - } - - static void __exit nft_flow_offload_module_exit(void) - { - nft_unregister_expr(&nft_flow_offload_type); -- unregister_netdevice_notifier(&flow_offload_netdev_notifier); - } - - module_init(nft_flow_offload_module_init); --- -2.51.0 - - -From 508c09b7af27f9d86d0dd3621932d17b40731195 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Thu, 31 Aug 2023 21:48:38 +0200 -Subject: [PATCH 270/517] netfilter: nf_tables: ignore -EOPNOTSUPP on flowtable - device offload setup - -On many embedded devices, it is common to configure flowtable offloading for -a mix of different devices, some of which have hardware offload support and -some of which don't. -The current code limits the ability of user space to properly set up such a -configuration by only allowing adding devices with hardware offload support to -a offload-enabled flowtable. -Given that offload-enabled flowtables also imply fallback to pure software -offloading, this limitation makes little sense. -Fix it by not bailing out when the offload setup returns -EOPNOTSUPP - -Signed-off-by: Felix Fietkau ---- - net/netfilter/nf_tables_api.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c -index 3028d388b293..3b94f0d3995c 100644 ---- a/net/netfilter/nf_tables_api.c -+++ b/net/netfilter/nf_tables_api.c -@@ -8666,7 +8666,7 @@ static int nft_register_flowtable_net_hooks(struct net *net, - err = flowtable->data.type->setup(&flowtable->data, - hook->ops.dev, - FLOW_BLOCK_BIND); -- if (err < 0) -+ if (err < 0 && err != -EOPNOTSUPP) - goto err_unregister_net_hooks; - - err = nf_register_net_hook(net, &hook->ops); --- -2.51.0 - - -From 7c144c4befb80c567d4225bbd64484bbcaece728 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Mon, 21 Mar 2022 20:39:59 +0100 -Subject: [PATCH 271/517] net: ethernet: mtk_eth_soc: enable threaded NAPI - -This can improve performance under load by ensuring that NAPI processing is -not pinned on CPU 0. - -Signed-off-by: Felix Fietkau ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -index 2a0be107b3d7..e51ca80b4f15 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -5148,6 +5148,8 @@ static int mtk_probe(struct platform_device *pdev) - dev_err(eth->dev, "failed to allocated dummy device\n"); - goto err_unreg_netdev; - } -+ eth->dummy_dev->threaded = 1; -+ strcpy(eth->dummy_dev->name, "mtk_eth"); - netif_napi_add(eth->dummy_dev, ð->tx_napi, mtk_napi_tx); - netif_napi_add(eth->dummy_dev, ð->rx_napi, mtk_napi_rx); - --- -2.51.0 - - -From 6fce75728838d9ed2cea822d5558eb619d3fd80a Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Mon, 3 Nov 2025 15:49:57 +0100 -Subject: [PATCH 272/517] generic: add detach callback to struct phy_driver - -lede-commit: fe61fc2d7d0b3fb348b502f68f98243b3ddf5867 - -Signed-off-by: Gabor Juhos ---- - drivers/net/phy/phy_device.c | 3 +++ - include/linux/phy.h | 6 ++++++ - 2 files changed, 9 insertions(+) - -diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c -index 2e08d20a3cfb..6e81501e5687 100644 ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -2037,6 +2037,9 @@ void phy_detach(struct phy_device *phydev) - phydev->devlink = NULL; - } - -+ if (phydev->drv && phydev->drv->detach) -+ phydev->drv->detach(phydev); -+ - if (phydev->sysfs_links) { - if (dev) - sysfs_remove_link(&dev->dev.kobj, "phydev"); -diff --git a/include/linux/phy.h b/include/linux/phy.h -index 85217937e489..b6c372ea4e2d 100644 ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -1027,6 +1027,12 @@ struct phy_driver { - /** @handle_interrupt: Override default interrupt handling */ - irqreturn_t (*handle_interrupt)(struct phy_device *phydev); - -+ /* -+ * Called before an ethernet device is detached -+ * from the PHY. -+ */ -+ void (*detach)(struct phy_device *phydev); -+ - /** @remove: Clears up any memory if needed */ - void (*remove)(struct phy_device *phydev); - --- -2.51.0 - - -From b164fe2b20f203a4b1456889693c9855179251c5 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 6 May 2022 21:38:42 +0200 -Subject: [PATCH 273/517] net: dsa: tag_mtk: add padding for tx packets - -Padding for transmitted packets needs to account for the special tag. -With not enough padding, garbage bytes are inserted by the switch at the -end of small packets. - -Fixes: 5cd8985a1909 ("net-next: dsa: add Mediatek tag RX/TX handler") -Signed-off-by: Felix Fietkau ---- - net/dsa/tag_mtk.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/net/dsa/tag_mtk.c b/net/dsa/tag_mtk.c -index b670e3c53e91..791f87349ba6 100644 ---- a/net/dsa/tag_mtk.c -+++ b/net/dsa/tag_mtk.c -@@ -29,6 +29,13 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb, - - skb_set_queue_mapping(skb, dp->index); - -+ /* The Ethernet switch we are interfaced with needs packets to be at -+ * least 64 bytes (including FCS) otherwise their padding might be -+ * corrupted. With tags enabled, we need to make sure that packets are -+ * at least 68 bytes (including FCS and tag). -+ */ -+ eth_skb_pad(skb); -+ - /* Build the special tag after the MAC Source Address. If VLAN header - * is present, it's required that VLAN header and special tag is - * being combined. Only in this way we can allow the switch can parse --- -2.51.0 - - -From 3d059952a5f51a3ee562b27a845b860bdeba7869 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 8 Oct 2024 23:58:41 +0100 -Subject: [PATCH 274/517] net: phy: populate host_interfaces when attaching PHY - -Use bitmask of interfaces supported by the MAC for the PHY to choose -from if the declared interface mode is among those using a single pair -of SerDes lanes. -This will allow 2500Base-T PHYs to switch to SGMII on most hosts, which -results in half-duplex being supported in case the MAC supports them. -Without this change, 2500Base-T PHYs will always operate in 2500Base-X -mode with rate-matching, which is not only wasteful in terms of energy -consumption, but also limits the supported interface modes to -full-duplex only. - -Signed-off-by: Daniel Golle ---- - drivers/net/phy/phylink.c | 21 ++++++++++++++++++++- - 1 file changed, 20 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c -index ede93109f9c5..e168766e465e 100644 ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -2264,7 +2264,7 @@ int phylink_fwnode_phy_connect(struct phylink *pl, - { - struct fwnode_handle *phy_fwnode; - struct phy_device *phy_dev; -- int ret; -+ int i, ret; - - /* Fixed links and 802.3z are handled without needing a PHY */ - if (pl->cfg_link_an_mode == MLO_AN_FIXED || -@@ -2294,6 +2294,25 @@ int phylink_fwnode_phy_connect(struct phylink *pl, - if (pl->config->mac_requires_rxc) - flags |= PHY_F_RXC_ALWAYS_ON; - -+ /* Assume single-lane SerDes interface modes share the same -+ * lanes and allow the PHY to switch to slower also supported modes -+ */ -+ for (i = ARRAY_SIZE(phylink_sfp_interface_preference) - 1; i >= 0; i--) { -+ /* skip unsupported modes */ -+ if (!test_bit(phylink_sfp_interface_preference[i], pl->config->supported_interfaces)) -+ continue; -+ -+ __set_bit(phylink_sfp_interface_preference[i], phy_dev->host_interfaces); -+ -+ /* skip all faster modes */ -+ if (phylink_sfp_interface_preference[i] == pl->link_interface) -+ break; -+ } -+ -+ if (test_bit(pl->link_interface, phylink_sfp_interfaces)) -+ phy_interface_and(phy_dev->host_interfaces, phylink_sfp_interfaces, -+ pl->config->supported_interfaces); -+ - ret = phy_attach_direct(pl->netdev, phy_dev, flags, - pl->link_interface); - phy_device_free(phy_dev); --- -2.51.0 - - -From 71873c04d3b023c84d1292d6ac910270998aece5 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 27 Aug 2021 12:22:32 +0200 -Subject: [PATCH 275/517] bridge: add knob for filtering rx/tx BPDU packets on - a port - -Some devices (e.g. wireless APs) can't have devices behind them be part of -a bridge topology with redundant links, due to address limitations. -Additionally, broadcast traffic on these devices is somewhat expensive, due to -the low data rate and wakeups of clients in powersave mode. -This knob can be used to ensure that BPDU packets are never sent or forwarded -to/from these devices - -Signed-off-by: Felix Fietkau ---- - include/linux/if_bridge.h | 1 + - include/uapi/linux/if_link.h | 1 + - net/bridge/br_forward.c | 5 +++++ - net/bridge/br_input.c | 2 ++ - net/bridge/br_netlink.c | 6 +++++- - net/bridge/br_stp_bpdu.c | 9 +++++++-- - net/bridge/br_sysfs_if.c | 2 ++ - net/core/rtnetlink.c | 6 ++++-- - 8 files changed, 27 insertions(+), 5 deletions(-) - -diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h -index 3ff96ae31bf6..cff03a1dfd68 100644 ---- a/include/linux/if_bridge.h -+++ b/include/linux/if_bridge.h -@@ -61,6 +61,7 @@ struct br_ip_list { - #define BR_PORT_LOCKED BIT(21) - #define BR_PORT_MAB BIT(22) - #define BR_NEIGH_VLAN_SUPPRESS BIT(23) -+#define BR_BPDU_FILTER BIT(24) - - #define BR_DEFAULT_AGEING_TIME (300 * HZ) - -diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h -index 2acc7687e017..493ca8617d33 100644 ---- a/include/uapi/linux/if_link.h -+++ b/include/uapi/linux/if_link.h -@@ -1094,6 +1094,7 @@ enum { - IFLA_BRPORT_MCAST_MAX_GROUPS, - IFLA_BRPORT_NEIGH_VLAN_SUPPRESS, - IFLA_BRPORT_BACKUP_NHID, -+ IFLA_BRPORT_BPDU_FILTER, - __IFLA_BRPORT_MAX - }; - #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1) -diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c -index e19b583ff2c6..20925747f36e 100644 ---- a/net/bridge/br_forward.c -+++ b/net/bridge/br_forward.c -@@ -201,6 +201,7 @@ void br_flood(struct net_bridge *br, struct sk_buff *skb, - enum br_pkt_type pkt_type, bool local_rcv, bool local_orig, - u16 vid) - { -+ const unsigned char *dest = eth_hdr(skb)->h_dest; - struct net_bridge_port *prev = NULL; - struct net_bridge_port *p; - -@@ -218,6 +219,10 @@ void br_flood(struct net_bridge *br, struct sk_buff *skb, - case BR_PKT_MULTICAST: - if (!(p->flags & BR_MCAST_FLOOD) && skb->dev != br->dev) - continue; -+ if ((p->flags & BR_BPDU_FILTER) && -+ unlikely(is_link_local_ether_addr(dest) && -+ dest[5] == 0)) -+ continue; - break; - case BR_PKT_BROADCAST: - if (!(p->flags & BR_BCAST_FLOOD) && skb->dev != br->dev) -diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c -index 0332371d19ab..da0ccd6b0034 100644 ---- a/net/bridge/br_input.c -+++ b/net/bridge/br_input.c -@@ -368,6 +368,8 @@ static rx_handler_result_t br_handle_frame(struct sk_buff **pskb) - fwd_mask |= p->group_fwd_mask; - switch (dest[5]) { - case 0x00: /* Bridge Group Address */ -+ if (p->flags & BR_BPDU_FILTER) -+ goto drop; - /* If STP is turned off, - then must forward to keep loop detection */ - if (p->br->stp_enabled == BR_NO_STP || -diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c -index 6b97ae47f855..5a6fdf3f9c86 100644 ---- a/net/bridge/br_netlink.c -+++ b/net/bridge/br_netlink.c -@@ -190,6 +190,7 @@ static inline size_t br_port_info_size(void) - + nla_total_size(1) /* IFLA_BRPORT_LOCKED */ - + nla_total_size(1) /* IFLA_BRPORT_MAB */ - + nla_total_size(1) /* IFLA_BRPORT_NEIGH_VLAN_SUPPRESS */ -+ + nla_total_size(1) /* IFLA_BRPORT_BPDU_FILTER */ - + nla_total_size(sizeof(struct ifla_bridge_id)) /* IFLA_BRPORT_ROOT_ID */ - + nla_total_size(sizeof(struct ifla_bridge_id)) /* IFLA_BRPORT_BRIDGE_ID */ - + nla_total_size(sizeof(u16)) /* IFLA_BRPORT_DESIGNATED_PORT */ -@@ -282,7 +283,8 @@ static int br_port_fill_attrs(struct sk_buff *skb, - nla_put_u8(skb, IFLA_BRPORT_LOCKED, !!(p->flags & BR_PORT_LOCKED)) || - nla_put_u8(skb, IFLA_BRPORT_MAB, !!(p->flags & BR_PORT_MAB)) || - nla_put_u8(skb, IFLA_BRPORT_NEIGH_VLAN_SUPPRESS, -- !!(p->flags & BR_NEIGH_VLAN_SUPPRESS))) -+ !!(p->flags & BR_NEIGH_VLAN_SUPPRESS)) || -+ nla_put_u8(skb, IFLA_BRPORT_BPDU_FILTER, !!(p->flags & BR_BPDU_FILTER))) - return -EMSGSIZE; - - timerval = br_timer_value(&p->message_age_timer); -@@ -902,6 +904,7 @@ static const struct nla_policy br_port_policy[IFLA_BRPORT_MAX + 1] = { - [IFLA_BRPORT_MCAST_MAX_GROUPS] = { .type = NLA_U32 }, - [IFLA_BRPORT_NEIGH_VLAN_SUPPRESS] = NLA_POLICY_MAX(NLA_U8, 1), - [IFLA_BRPORT_BACKUP_NHID] = { .type = NLA_U32 }, -+ [IFLA_BRPORT_BPDU_FILTER] = { .type = NLA_U8 }, - }; - - /* Change the state of the port and notify spanning tree */ -@@ -970,6 +973,7 @@ static int br_setport(struct net_bridge_port *p, struct nlattr *tb[], - br_set_port_flag(p, tb, IFLA_BRPORT_MAB, BR_PORT_MAB); - br_set_port_flag(p, tb, IFLA_BRPORT_NEIGH_VLAN_SUPPRESS, - BR_NEIGH_VLAN_SUPPRESS); -+ br_set_port_flag(p, tb, IFLA_BRPORT_BPDU_FILTER, BR_BPDU_FILTER); - - if ((p->flags & BR_PORT_MAB) && - (!(p->flags & BR_PORT_LOCKED) || !(p->flags & BR_LEARNING))) { -diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c -index 7895489ac6fe..34c7ae7c9d63 100644 ---- a/net/bridge/br_stp_bpdu.c -+++ b/net/bridge/br_stp_bpdu.c -@@ -80,7 +80,8 @@ void br_send_config_bpdu(struct net_bridge_port *p, struct br_config_bpdu *bpdu) - { - unsigned char buf[35]; - -- if (p->br->stp_enabled != BR_KERNEL_STP) -+ if (p->br->stp_enabled != BR_KERNEL_STP || -+ (p->flags & BR_BPDU_FILTER)) - return; - - buf[0] = 0; -@@ -127,7 +128,8 @@ void br_send_tcn_bpdu(struct net_bridge_port *p) - { - unsigned char buf[4]; - -- if (p->br->stp_enabled != BR_KERNEL_STP) -+ if (p->br->stp_enabled != BR_KERNEL_STP || -+ (p->flags & BR_BPDU_FILTER)) - return; - - buf[0] = 0; -@@ -172,6 +174,9 @@ void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb, - if (!(br->dev->flags & IFF_UP)) - goto out; - -+ if (p->flags & BR_BPDU_FILTER) -+ goto out; -+ - if (p->state == BR_STATE_DISABLED) - goto out; - -diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c -index 74fdd8105dca..aee7c5902206 100644 ---- a/net/bridge/br_sysfs_if.c -+++ b/net/bridge/br_sysfs_if.c -@@ -240,6 +240,7 @@ BRPORT_ATTR_FLAG(multicast_flood, BR_MCAST_FLOOD); - BRPORT_ATTR_FLAG(broadcast_flood, BR_BCAST_FLOOD); - BRPORT_ATTR_FLAG(neigh_suppress, BR_NEIGH_SUPPRESS); - BRPORT_ATTR_FLAG(isolated, BR_ISOLATED); -+BRPORT_ATTR_FLAG(bpdu_filter, BR_BPDU_FILTER); - - #ifdef CONFIG_BRIDGE_IGMP_SNOOPING - static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf) -@@ -292,6 +293,7 @@ static const struct brport_attribute *brport_attrs[] = { - &brport_attr_group_fwd_mask, - &brport_attr_neigh_suppress, - &brport_attr_isolated, -+ &brport_attr_bpdu_filter, - &brport_attr_backup_port, - NULL - }; -diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c -index 4d0ee1c9002a..e88f76b7ff00 100644 ---- a/net/core/rtnetlink.c -+++ b/net/core/rtnetlink.c -@@ -62,7 +62,7 @@ - #include "dev.h" - - #define RTNL_MAX_TYPE 50 --#define RTNL_SLAVE_MAX_TYPE 44 -+#define RTNL_SLAVE_MAX_TYPE 45 - - struct rtnl_link { - rtnl_doit_func doit; -@@ -5012,7 +5012,9 @@ int ndo_dflt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, - brport_nla_put_flag(skb, flags, mask, - IFLA_BRPORT_MCAST_FLOOD, BR_MCAST_FLOOD) || - brport_nla_put_flag(skb, flags, mask, -- IFLA_BRPORT_BCAST_FLOOD, BR_BCAST_FLOOD)) { -+ IFLA_BRPORT_BCAST_FLOOD, BR_BCAST_FLOOD) || -+ brport_nla_put_flag(skb, flags, mask, -+ IFLA_BRPORT_BPDU_FILTER, BR_BPDU_FILTER)) { - nla_nest_cancel(skb, protinfo); - goto nla_put_failure; - } --- -2.51.0 - - -From a76fd2c1b182f24e3594eb106794b778f7287f1d Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 4 Jul 2023 22:50:12 +0200 -Subject: [PATCH 276/517] net: dsa: qca8k: implement lag_fdb_add/del ops - -Implement lag_fdb_add/del ops to correctly support using LAG interface. -Qca8k switch supports declaring fdb entry for link aggregation by simply -setting the DES_PORT bits to all the LAG member. - -Signed-off-by: Christian Marangi ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 2 ++ - drivers/net/dsa/qca/qca8k-common.c | 36 ++++++++++++++++++++++++++++++ - drivers/net/dsa/qca/qca8k.h | 6 +++++ - 3 files changed, 44 insertions(+) - -diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c -index 59b4a7240b58..de3d1227d1ae 100644 ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -2031,6 +2031,8 @@ static const struct dsa_switch_ops qca8k_switch_ops = { - .port_fdb_add = qca8k_port_fdb_add, - .port_fdb_del = qca8k_port_fdb_del, - .port_fdb_dump = qca8k_port_fdb_dump, -+ .lag_fdb_add = qca8k_lag_fdb_add, -+ .lag_fdb_del = qca8k_lag_fdb_del, - .port_mdb_add = qca8k_port_mdb_add, - .port_mdb_del = qca8k_port_mdb_del, - .port_mirror_add = qca8k_port_mirror_add, -diff --git a/drivers/net/dsa/qca/qca8k-common.c b/drivers/net/dsa/qca/qca8k-common.c -index 560c74c4ac3d..2194f706aed5 100644 ---- a/drivers/net/dsa/qca/qca8k-common.c -+++ b/drivers/net/dsa/qca/qca8k-common.c -@@ -1234,6 +1234,42 @@ int qca8k_port_lag_leave(struct dsa_switch *ds, int port, - return qca8k_lag_refresh_portmap(ds, port, lag, true); - } - -+int qca8k_lag_fdb_add(struct dsa_switch *ds, struct dsa_lag lag, -+ const unsigned char *addr, u16 vid, -+ struct dsa_db db) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ struct dsa_port *dp; -+ u16 port_mask = 0; -+ -+ /* Set the vid to the port vlan id if no vid is set */ -+ if (!vid) -+ vid = QCA8K_PORT_VID_DEF; -+ -+ dsa_lag_foreach_port(dp, ds->dst, &lag) -+ port_mask |= BIT(dp->index); -+ -+ return qca8k_port_fdb_insert(priv, addr, port_mask, vid); -+} -+ -+int qca8k_lag_fdb_del(struct dsa_switch *ds, struct dsa_lag lag, -+ const unsigned char *addr, u16 vid, -+ struct dsa_db db) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ struct dsa_port *dp; -+ u16 port_mask = 0; -+ -+ /* Set the vid to the port vlan id if no vid is set */ -+ if (!vid) -+ vid = QCA8K_PORT_VID_DEF; -+ -+ dsa_lag_foreach_port(dp, ds->dst, &lag) -+ port_mask |= BIT(dp->index); -+ -+ return qca8k_fdb_del(priv, addr, port_mask, vid); -+} -+ - int qca8k_read_switch_id(struct qca8k_priv *priv) - { - u32 val; -diff --git a/drivers/net/dsa/qca/qca8k.h b/drivers/net/dsa/qca/qca8k.h -index 3664a2e2f1f6..894bd1f1e123 100644 ---- a/drivers/net/dsa/qca/qca8k.h -+++ b/drivers/net/dsa/qca/qca8k.h -@@ -592,5 +592,11 @@ int qca8k_port_lag_join(struct dsa_switch *ds, int port, struct dsa_lag lag, - struct netlink_ext_ack *extack); - int qca8k_port_lag_leave(struct dsa_switch *ds, int port, - struct dsa_lag lag); -+int qca8k_lag_fdb_add(struct dsa_switch *ds, struct dsa_lag lag, -+ const unsigned char *addr, u16 vid, -+ struct dsa_db db); -+int qca8k_lag_fdb_del(struct dsa_switch *ds, struct dsa_lag lag, -+ const unsigned char *addr, u16 vid, -+ struct dsa_db db); - - #endif /* __QCA8K_H */ --- -2.51.0 - - -From 1ab637936c9a5b4385ad741d2228accb5d12580e Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 20 Jun 2023 21:48:24 +0200 -Subject: [PATCH 277/517] net: dsa: qca8k: enable flooding to both CPU port - -To permit a multi-CPU setup, flood all unknown frames to all CPU ports. -Each CPU port should have correct LOOKUP MEMBER configuration to -prevent receiving duplicate packets from user ports. - -Signed-off-by: Christian Marangi ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 13 +++++-------- - 1 file changed, 5 insertions(+), 8 deletions(-) - -diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c -index de3d1227d1ae..552feb99d33c 100644 ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -1913,15 +1913,12 @@ qca8k_setup(struct dsa_switch *ds) - } - } - -- /* Forward all unknown frames to CPU port for Linux processing -- * Notice that in multi-cpu config only one port should be set -- * for igmp, unknown, multicast and broadcast packet -- */ -+ /* Forward all unknown frames to CPU port for Linux processing */ - ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1, -- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, BIT(cpu_port)) | -- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, BIT(cpu_port)) | -- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, BIT(cpu_port)) | -- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, BIT(cpu_port))); -+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, dsa_cpu_ports(ds)) | -+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, dsa_cpu_ports(ds)) | -+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, dsa_cpu_ports(ds)) | -+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, dsa_cpu_ports(ds))); - if (ret) - return ret; - --- -2.51.0 - - -From 5b32eeb255186bab8c0dc100a1b31b671bb89b69 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 20 Jun 2023 07:57:38 +0200 -Subject: [PATCH 278/517] net: dsa: qca8k: add support for port_change_master - -Add support for port_change_master to permit assigning an alternative -CPU port if the switch have both CPU port connected or create a LAG on -both CPU port and assign the LAG as DSA master. - -On port change master request, we check if the master is a LAG. -With LAG we compose the cpu_port_mask with the CPU port in the LAG, if -master is a simple dsa_port, we derive the index. - -Finally we apply the new cpu_port_mask to the LOOKUP MEMBER to permit -the port to receive packet by the new CPU port setup for the port and we -refresh the CPU ports LOOKUP MEMBER configuration to reflect the new -user port state. - -port_lag_join/leave is updated to refresh the user ports if we detect -that the LAG is a DSA master and we have user port using it as a master. - -Signed-off-by: Christian Marangi ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 116 ++++++++++++++++++++++++++++++- - 1 file changed, 114 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c -index 552feb99d33c..aad8a20e72c7 100644 ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -1750,6 +1750,117 @@ qca8k_get_tag_protocol(struct dsa_switch *ds, int port, - return DSA_TAG_PROTO_QCA; - } - -+static int qca8k_port_change_master(struct dsa_switch *ds, int port, -+ struct net_device *master, -+ struct netlink_ext_ack *extack) -+{ -+ struct dsa_switch_tree *dst = ds->dst; -+ struct qca8k_priv *priv = ds->priv; -+ u8 cpu_port_mask = 0; -+ struct dsa_port *dp; -+ u32 val; -+ int ret; -+ -+ /* With LAG of CPU port, compose the mask for port LOOKUP MEMBER */ -+ if (netif_is_lag_master(master)) { -+ struct dsa_lag *lag; -+ int id; -+ -+ id = dsa_lag_id(dst, master); -+ lag = dsa_lag_by_id(dst, id); -+ -+ dsa_lag_foreach_port(dp, dst, lag) -+ if (dsa_port_is_cpu(dp)) -+ cpu_port_mask |= BIT(dp->index); -+ } else { -+ dp = master->dsa_ptr; -+ cpu_port_mask |= BIT(dp->index); -+ } -+ -+ /* Connect port to new cpu port */ -+ ret = regmap_read(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port), &val); -+ if (ret) -+ return ret; -+ -+ /* Reset connected CPU port in port LOOKUP MEMBER */ -+ val &= ~dsa_cpu_ports(ds); -+ /* Assign the new CPU port in port LOOKUP MEMBER */ -+ val |= cpu_port_mask; -+ -+ ret = regmap_update_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port), -+ QCA8K_PORT_LOOKUP_MEMBER, -+ val); -+ if (ret) -+ return ret; -+ -+ /* Refresh CPU port LOOKUP MEMBER with new port */ -+ dsa_tree_for_each_cpu_port(dp, ds->dst) { -+ u32 reg = QCA8K_PORT_LOOKUP_CTRL(dp->index); -+ -+ /* If CPU port in mask assign port, else remove port */ -+ if (BIT(dp->index) & cpu_port_mask) -+ ret = regmap_set_bits(priv->regmap, reg, BIT(port)); -+ else -+ ret = regmap_clear_bits(priv->regmap, reg, BIT(port)); -+ -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int qca8k_port_lag_refresh_user_ports(struct dsa_switch *ds, -+ struct dsa_lag lag) -+{ -+ struct net_device *lag_dev = lag.dev; -+ struct dsa_port *dp; -+ int ret; -+ -+ /* Ignore if LAG is not a DSA master */ -+ if (!netif_is_lag_master(lag_dev)) -+ return 0; -+ -+ dsa_switch_for_each_user_port(dp, ds) { -+ /* Skip if assigned master is not the LAG */ -+ if (dsa_port_to_conduit(dp) != lag_dev) -+ continue; -+ -+ ret = qca8k_port_change_master(ds, dp->index, -+ lag_dev, NULL); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int qca8xxx_port_lag_join(struct dsa_switch *ds, int port, -+ struct dsa_lag lag, -+ struct netdev_lag_upper_info *info, -+ struct netlink_ext_ack *extack) -+{ -+ int ret; -+ -+ ret = qca8k_port_lag_join(ds, port, lag, info, extack); -+ if (ret) -+ return ret; -+ -+ return qca8k_port_lag_refresh_user_ports(ds, lag); -+} -+ -+static int qca8xxx_port_lag_leave(struct dsa_switch *ds, int port, -+ struct dsa_lag lag) -+{ -+ int ret; -+ -+ ret = qca8k_port_lag_leave(ds, port, lag); -+ if (ret) -+ return ret; -+ -+ return qca8k_port_lag_refresh_user_ports(ds, lag); -+} -+ - static void - qca8k_conduit_change(struct dsa_switch *ds, const struct net_device *conduit, - bool operational) -@@ -2039,8 +2150,9 @@ static const struct dsa_switch_ops qca8k_switch_ops = { - .port_vlan_del = qca8k_port_vlan_del, - .phylink_get_caps = qca8k_phylink_get_caps, - .get_phy_flags = qca8k_get_phy_flags, -- .port_lag_join = qca8k_port_lag_join, -- .port_lag_leave = qca8k_port_lag_leave, -+ .port_lag_join = qca8xxx_port_lag_join, -+ .port_lag_leave = qca8xxx_port_lag_leave, -+ .port_change_conduit = qca8k_port_change_master, - .conduit_state_change = qca8k_conduit_change, - .connect_tag_protocol = qca8k_connect_tag_protocol, - }; --- -2.51.0 - - -From d4996d68368205d76f6d715a69bf755bc441e721 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 6 Oct 2023 12:44:00 +0200 -Subject: [PATCH 279/517] net: dsa: qca8k: enable assisted learning on CPU port - -Enable assisted learning on CPU port. - -It has been verified that there is a problem in packet roaming -from one BSS to another in the same security settings from one -physical R7800 to another physical R7800 where they are in the -same L2 broadcast domain backhauled/linked together via one -of the ethernet ports. -DHCP will fail to complete and traffic cannot flow for around 300 -seconds. - -Signed-off-by: Christian Marangi ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 14 +++++++++----- - 1 file changed, 9 insertions(+), 5 deletions(-) - -diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c -index aad8a20e72c7..de56bbc09cf9 100644 ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -2022,6 +2022,12 @@ qca8k_setup(struct dsa_switch *ds) - dev_err(priv->dev, "failed enabling QCA header mode on port %d", dp->index); - return ret; - } -+ -+ /* Disable learning by default on all ports */ -+ ret = regmap_clear_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(dp->index), -+ QCA8K_PORT_LOOKUP_LEARN); -+ if (ret) -+ return ret; - } - - /* Forward all unknown frames to CPU port for Linux processing */ -@@ -2051,11 +2057,6 @@ qca8k_setup(struct dsa_switch *ds) - if (ret) - return ret; - -- ret = regmap_clear_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port), -- QCA8K_PORT_LOOKUP_LEARN); -- if (ret) -- return ret; -- - /* For port based vlans to work we need to set the - * default egress vid - */ -@@ -2107,6 +2108,9 @@ qca8k_setup(struct dsa_switch *ds) - /* Set max number of LAGs supported */ - ds->num_lag_ids = QCA8K_NUM_LAGS; - -+ /* HW learn on CPU port is limited and require manual setting */ -+ ds->assisted_learning_on_cpu_port = true; -+ - return 0; - } - --- -2.51.0 - - -From cf6f77006d285fcf40f251a7988911316d99c134 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sun, 2 Apr 2023 23:56:16 +0100 -Subject: [PATCH 280/517] net: phy: realtek: use genphy_soft_reset for 2.5G - PHYs - -Some vendor bootloaders do weird things with those PHYs which result in -link modes being reported wrongly. Start from a clean sheet by resetting -the PHY. - -Reported-by: Yevhen Kolomeiko -Signed-off-by: Daniel Golle ---- - drivers/net/phy/realtek/realtek_main.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index 114d219562f1..2d2ed0a9d360 100644 ---- a/drivers/net/phy/realtek/realtek_main.c -+++ b/drivers/net/phy/realtek/realtek_main.c -@@ -1675,6 +1675,7 @@ static struct phy_driver realtek_drvs[] = { - }, { - .name = "RTL8226 2.5Gbps PHY", - .match_phy_device = rtl8226_match_phy_device, -+ .soft_reset = genphy_soft_reset, - .get_features = rtl822x_get_features, - .config_aneg = rtl822x_config_aneg, - .read_status = rtl822x_read_status, -@@ -1685,6 +1686,7 @@ static struct phy_driver realtek_drvs[] = { - }, { - .match_phy_device = rtl8221b_match_phy_device, - .name = "RTL8226B_RTL8221B 2.5Gbps PHY", -+ .soft_reset = genphy_soft_reset, - .get_features = rtl822x_get_features, - .config_aneg = rtl822x_config_aneg, - .config_init = rtl822xb_config_init, -@@ -1707,6 +1709,7 @@ static struct phy_driver realtek_drvs[] = { - }, { - PHY_ID_MATCH_EXACT(0x001cc848), - .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY", -+ .soft_reset = genphy_soft_reset, - .get_features = rtl822x_get_features, - .config_aneg = rtl822x_config_aneg, - .config_init = rtl822xb_config_init, -@@ -1719,6 +1722,7 @@ static struct phy_driver realtek_drvs[] = { - }, { - .match_phy_device = rtl8221b_vb_cg_c22_match_phy_device, - .name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)", -+ .soft_reset = genphy_soft_reset, - .probe = rtl822x_probe, - .get_features = rtl822x_get_features, - .config_aneg = rtl822x_config_aneg, -@@ -1732,6 +1736,7 @@ static struct phy_driver realtek_drvs[] = { - }, { - .match_phy_device = rtl8221b_vb_cg_c45_match_phy_device, - .name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)", -+ .soft_reset = rtl822x_c45_soft_reset, - .probe = rtl822x_probe, - .config_init = rtl822xb_config_init, - .get_rate_matching = rtl822xb_get_rate_matching, -@@ -1743,6 +1748,7 @@ static struct phy_driver realtek_drvs[] = { - }, { - .match_phy_device = rtl8221b_vn_cg_c22_match_phy_device, - .name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)", -+ .soft_reset = genphy_soft_reset, - .probe = rtl822x_probe, - .get_features = rtl822x_get_features, - .config_aneg = rtl822x_config_aneg, -@@ -1756,6 +1762,7 @@ static struct phy_driver realtek_drvs[] = { - }, { - .match_phy_device = rtl8221b_vn_cg_c45_match_phy_device, - .name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)", -+ .soft_reset = rtl822x_c45_soft_reset, - .probe = rtl822x_probe, - .config_init = rtl822xb_config_init, - .get_rate_matching = rtl822xb_get_rate_matching, --- -2.51.0 - - -From d1c87314cf69950550a4c6e3a64c4c194006f502 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 01:21:57 +0300 -Subject: [PATCH 281/517] net: phy: realtek: disable SGMII in-band AN for 2.5G - PHYs - -MAC drivers don't use SGMII in-band autonegotiation unless told to do so -in device tree using 'managed = "in-band-status"'. When using MDIO to -access a PHY, in-band-status is unneeded as we have link-status via -MDIO. Switch off SGMII in-band autonegotiation using magic values. - -Reported-by: Chen Minqiang -Reported-by: Chukun Pan -Reported-by: Yevhen Kolomeiko -Tested-by: Yevhen Kolomeiko -Signed-off-by: Daniel Golle ---- - drivers/net/phy/realtek/realtek_main.c | 34 ++++++++++++++++++++++---- - 1 file changed, 29 insertions(+), 5 deletions(-) - -diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index 2d2ed0a9d360..0b2ec2ee0cf3 100644 ---- a/drivers/net/phy/realtek/realtek_main.c -+++ b/drivers/net/phy/realtek/realtek_main.c -@@ -1035,8 +1035,8 @@ static int rtl822x_probe(struct phy_device *phydev) - static int rtl822x_set_serdes_option_mode(struct phy_device *phydev, bool gen1) - { - bool has_2500, has_sgmii; -+ int ret, val; - u16 mode; -- int ret; - - has_2500 = test_bit(PHY_INTERFACE_MODE_2500BASEX, - phydev->host_interfaces) || -@@ -1078,18 +1078,42 @@ static int rtl822x_set_serdes_option_mode(struct phy_device *phydev, bool gen1) - RTL822X_VND1_SERDES_OPTION, - RTL822X_VND1_SERDES_OPTION_MODE_MASK, - mode); -- if (gen1 || ret < 0) -+ if (ret < 0) - return ret; - -- ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6a04, 0x0503); -+ if (!gen1) { -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6a04, 0x0503); -+ if (ret < 0) -+ return ret; -+ -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f10, 0xd455); -+ if (ret < 0) -+ return ret; -+ -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020); -+ if (ret < 0) -+ return ret; -+ } -+ -+ /* Disable SGMII AN */ -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7588, 0x2); -+ if (ret < 0) -+ return ret; -+ -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7589, 0x71d0); - if (ret < 0) - return ret; - -- ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f10, 0xd455); -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7587, 0x3); - if (ret < 0) - return ret; - -- return phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020); -+ ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, 0x7587, -+ val, !(val & BIT(0)), 500, 100000, false); -+ if (ret < 0) -+ return ret; -+ -+ return 0; - } - - static int rtl822x_config_init(struct phy_device *phydev) --- -2.51.0 - - -From 1b0e9bd766fd803b1df1b13ed2d6e4ac159f20d5 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sat, 22 Apr 2023 01:21:14 +0100 -Subject: [PATCH 282/517] net: phy: realtek: make sure paged read is protected - by mutex - -As we cannot rely on phy_read_paged function before the PHY is -identified, the paged read in rtlgen_supports_2_5gbps needs to be open -coded as it is being called by the match_phy_device function, ie. before -.read_page and .write_page have been populated. - -Make sure it is also protected by the MDIO bus mutex and use -rtl821x_write_page instead of 3 individually locked MDIO bus operations. - -Signed-off-by: Daniel Golle ---- - drivers/net/phy/realtek/realtek_main.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index 0b2ec2ee0cf3..3bd9d52ce109 100644 ---- a/drivers/net/phy/realtek/realtek_main.c -+++ b/drivers/net/phy/realtek/realtek_main.c -@@ -1343,9 +1343,11 @@ static bool rtlgen_supports_2_5gbps(struct phy_device *phydev) - { - int val; - -- phy_write(phydev, RTL821x_PAGE_SELECT, 0xa61); -- val = phy_read(phydev, 0x13); -- phy_write(phydev, RTL821x_PAGE_SELECT, 0); -+ mutex_lock(&phydev->mdio.bus->mdio_lock); -+ rtl821x_write_page(phydev, 0xa61); -+ val = __phy_read(phydev, 0x13); -+ rtl821x_write_page(phydev, 0); -+ mutex_unlock(&phydev->mdio.bus->mdio_lock); - - return val >= 0 && val & MDIO_PMA_SPEED_2_5G; - } --- -2.51.0 - - -From 6b913911a8983435f5435892606fe4e418b94f39 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sat, 22 Apr 2023 03:26:01 +0100 -Subject: [PATCH 283/517] net: phy: realtek: setup ALDPS on RTL822x - -Setup Link Down Power Saving Mode according the DTS property -just like for RTL821x 1GE PHYs. - -Signed-off-by: Daniel Golle ---- - drivers/net/phy/realtek/realtek_main.c | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - -diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index 3bd9d52ce109..036b27ab244e 100644 ---- a/drivers/net/phy/realtek/realtek_main.c -+++ b/drivers/net/phy/realtek/realtek_main.c -@@ -129,6 +129,10 @@ - */ - #define RTL822X_VND2_C22_REG(reg) (0xa400 + 2 * (reg)) - -+#define RTL8221B_PHYCR1 0xa430 -+#define RTL8221B_PHYCR1_ALDPS_EN BIT(2) -+#define RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN BIT(12) -+ - #define RTL8366RB_POWER_SAVE 0x15 - #define RTL8366RB_POWER_SAVE_ON BIT(12) - -@@ -1095,6 +1099,15 @@ static int rtl822x_set_serdes_option_mode(struct phy_device *phydev, bool gen1) - return ret; - } - -+ if (of_property_read_bool(phydev->mdio.dev.of_node, "realtek,aldps-enable")) -+ ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, RTL8221B_PHYCR1, -+ RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN); -+ else -+ ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, RTL8221B_PHYCR1, -+ RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN); -+ if (ret < 0) -+ return ret; -+ - /* Disable SGMII AN */ - ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7588, 0x2); - if (ret < 0) --- -2.51.0 - - -From 4bc0f42ffef605a9a323a18105c572a0f26b7cdd Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sun, 30 Apr 2023 00:15:41 +0100 -Subject: [PATCH 284/517] net: phy: realtek: detect early version of RTL8221B - -Early versions (?) of the RTL8221B PHY cannot be identified in a regular -Clause-45 bus scan as the PHY doesn't report the implemented MMDs -correctly but returns 0 instead. -Implement custom identify function using the PKGID instead of iterating -over the implemented MMDs. - -Signed-off-by: Daniel Golle -[forward-port by @namiltd] -Signed-off-by: Mieczyslaw Nalewaj ---- - drivers/net/phy/realtek/realtek_main.c | 28 +++++++++++++++++++++++--- - 1 file changed, 25 insertions(+), 3 deletions(-) - -diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index 036b27ab244e..88beb4c5c9db 100644 ---- a/drivers/net/phy/realtek/realtek_main.c -+++ b/drivers/net/phy/realtek/realtek_main.c -@@ -1400,10 +1400,32 @@ static int rtl8226_match_phy_device(struct phy_device *phydev, - static int rtlgen_is_c45_match(struct phy_device *phydev, unsigned int id, - bool is_c45) - { -- if (phydev->is_c45) -- return is_c45 && (id == phydev->c45_ids.device_ids[1]); -- else -+ if (phydev->is_c45) { -+ u32 rid; -+ -+ if (!is_c45) -+ return 0; -+ -+ rid = phydev->c45_ids.device_ids[1]; -+ if ((rid == 0xffffffff) && phydev->mdio.bus->read_c45) { -+ int val; -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID1); -+ if (val < 0) -+ return 0; -+ -+ rid = val << 16; -+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID2); -+ if (val < 0) -+ return 0; -+ -+ rid |= val; -+ } -+ -+ return (id == rid); -+ } else { - return !is_c45 && (id == phydev->phy_id); -+ } - } - - static int rtl8221b_match_phy_device(struct phy_device *phydev, --- -2.51.0 - - -From d501f6a78763e0dfdce00fed1842bdb93f06b306 Mon Sep 17 00:00:00 2001 -From: Jianhui Zhao -Date: Sun, 24 Sep 2023 22:15:00 +0800 -Subject: [PATCH 285/517] net: phy: realtek: add interrupt support for RTL8221B - -This commit introduces interrupt support for RTL8221B. - -Signed-off-by: Jianhui Zhao ---- - drivers/net/phy/realtek/realtek_main.c | 53 ++++++++++++++++++++++++++ - 1 file changed, 53 insertions(+) - -diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index 88beb4c5c9db..c4cd0df5f971 100644 ---- a/drivers/net/phy/realtek/realtek_main.c -+++ b/drivers/net/phy/realtek/realtek_main.c -@@ -1619,6 +1619,51 @@ static irqreturn_t rtl9000a_handle_interrupt(struct phy_device *phydev) - return IRQ_HANDLED; - } - -+static int rtl8221b_ack_interrupt(struct phy_device *phydev) -+{ -+ int err; -+ -+ err = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xa4d4); -+ -+ return (err < 0) ? err : 0; -+} -+ -+static int rtl8221b_config_intr(struct phy_device *phydev) -+{ -+ int err; -+ -+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { -+ err = rtl8221b_ack_interrupt(phydev); -+ if (err) -+ return err; -+ -+ err = phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xa4d2, 0x7ff); -+ } else { -+ err = phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xa4d2, 0x0); -+ if (err) -+ return err; -+ -+ err = rtl8221b_ack_interrupt(phydev); -+ } -+ -+ return err; -+} -+ -+static irqreturn_t rtl8221b_handle_interrupt(struct phy_device *phydev) -+{ -+ int err; -+ -+ err = rtl8221b_ack_interrupt(phydev); -+ if (err) { -+ phy_error(phydev); -+ return IRQ_NONE; -+ } -+ -+ phy_trigger_machine(phydev); -+ -+ return IRQ_HANDLED; -+} -+ - static struct phy_driver realtek_drvs[] = { - { - PHY_ID_MATCH_EXACT(0x00008201), -@@ -1783,6 +1828,8 @@ static struct phy_driver realtek_drvs[] = { - }, { - .match_phy_device = rtl8221b_vb_cg_c22_match_phy_device, - .name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)", -+ .config_intr = rtl8221b_config_intr, -+ .handle_interrupt = rtl8221b_handle_interrupt, - .soft_reset = genphy_soft_reset, - .probe = rtl822x_probe, - .get_features = rtl822x_get_features, -@@ -1797,6 +1844,8 @@ static struct phy_driver realtek_drvs[] = { - }, { - .match_phy_device = rtl8221b_vb_cg_c45_match_phy_device, - .name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)", -+ .config_intr = rtl8221b_config_intr, -+ .handle_interrupt = rtl8221b_handle_interrupt, - .soft_reset = rtl822x_c45_soft_reset, - .probe = rtl822x_probe, - .config_init = rtl822xb_config_init, -@@ -1809,6 +1858,8 @@ static struct phy_driver realtek_drvs[] = { - }, { - .match_phy_device = rtl8221b_vn_cg_c22_match_phy_device, - .name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)", -+ .config_intr = rtl8221b_config_intr, -+ .handle_interrupt = rtl8221b_handle_interrupt, - .soft_reset = genphy_soft_reset, - .probe = rtl822x_probe, - .get_features = rtl822x_get_features, -@@ -1823,6 +1874,8 @@ static struct phy_driver realtek_drvs[] = { - }, { - .match_phy_device = rtl8221b_vn_cg_c45_match_phy_device, - .name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)", -+ .config_intr = rtl8221b_config_intr, -+ .handle_interrupt = rtl8221b_handle_interrupt, - .soft_reset = rtl822x_c45_soft_reset, - .probe = rtl822x_probe, - .config_init = rtl822xb_config_init, --- -2.51.0 - - -From 9715b901b205b49e6d1a24c5915ffef7936afd23 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 23 Jan 2025 03:25:29 +0000 -Subject: [PATCH 286/517] net: phy: realtek: mark existing MMDs as present - -When using Clause-45 mode to access RealTek RTL8221B 2.5G PHYs some -versions of the PHY fail to report the MMDs present on the PHY. -Mark MMDs PMAPMD, PCS and AN which are always existing according to -the datasheet as present to fix that. - -Signed-off-by: Daniel Golle ---- - drivers/net/phy/realtek/realtek_main.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index c4cd0df5f971..cd4c452508ae 100644 ---- a/drivers/net/phy/realtek/realtek_main.c -+++ b/drivers/net/phy/realtek/realtek_main.c -@@ -1259,6 +1259,9 @@ static int rtl822x_c45_get_features(struct phy_device *phydev) - linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT, - phydev->supported); - -+ phydev->c45_ids.mmds_present |= MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | -+ MDIO_DEVS_AN; -+ - return genphy_c45_pma_read_abilities(phydev); - } - --- -2.51.0 - - -From 5348f3256a254426ca1fd4c6e828e2b5bd1913d9 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 30 Jan 2025 05:33:12 +0000 -Subject: [PATCH 287/517] net: phy: realtek: work around broken SerDes - -For still unknown reasons the SerDes init sequence may sometimes -time out because a self-clearing bit never clears, indicating the -PHY has entered an unrecoverable error state. - -Work-around the issue by triggering a hardware reset and retry the -setup sequence while warning the user that this has happened. -This is really more of a work-around than a fix, and should be -replaced by a better actual fix in future (hopefully). - -Signed-off-by: Daniel Golle ---- - drivers/net/phy/realtek/realtek_main.c | 20 ++++++++++++++++++-- - 1 file changed, 18 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index cd4c452508ae..7620935988ce 100644 ---- a/drivers/net/phy/realtek/realtek_main.c -+++ b/drivers/net/phy/realtek/realtek_main.c -@@ -1139,6 +1139,22 @@ static int rtl822xb_config_init(struct phy_device *phydev) - return rtl822x_set_serdes_option_mode(phydev, false); - } - -+static int rtl822xb_config_init_war(struct phy_device *phydev) -+{ -+ int ret; -+ -+ ret = rtl822xb_config_init(phydev); -+ -+ if (ret == -ETIMEDOUT) { -+ phydev_warn(phydev, "SerDes setup timed out, retrying\n"); -+ phy_device_reset(phydev, 1); -+ phy_device_reset(phydev, 0); -+ ret = rtl822xb_config_init(phydev); -+ } -+ -+ return ret; -+} -+ - static int rtl822xb_get_rate_matching(struct phy_device *phydev, - phy_interface_t iface) - { -@@ -1851,7 +1867,7 @@ static struct phy_driver realtek_drvs[] = { - .handle_interrupt = rtl8221b_handle_interrupt, - .soft_reset = rtl822x_c45_soft_reset, - .probe = rtl822x_probe, -- .config_init = rtl822xb_config_init, -+ .config_init = rtl822xb_config_init_war, - .get_rate_matching = rtl822xb_get_rate_matching, - .get_features = rtl822x_c45_get_features, - .config_aneg = rtl822x_c45_config_aneg, -@@ -1881,7 +1897,7 @@ static struct phy_driver realtek_drvs[] = { - .handle_interrupt = rtl8221b_handle_interrupt, - .soft_reset = rtl822x_c45_soft_reset, - .probe = rtl822x_probe, -- .config_init = rtl822xb_config_init, -+ .config_init = rtl822xb_config_init_war, - .get_rate_matching = rtl822xb_get_rate_matching, - .get_features = rtl822x_c45_get_features, - .config_aneg = rtl822x_c45_config_aneg, --- -2.51.0 - - -From 90d35efb01b9a152f1409a9029eae2e344115750 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 30 Jan 2025 05:38:31 +0000 -Subject: [PATCH 288/517] net: phy: realtek: disable MDIO broadcast - -RealTek's PHYs by default also listen on MDIO address 0 which is defined -as broadcast address. This can lead to problems if there is an actual PHY -(such as MT7981 built-in PHY) present at this address, as accessing that -PHY may then confuse the RealTek PHY. - -Disabled listening on the MDIO broadcast address to avoid such problems. - -Signed-off-by: Daniel Golle ---- - drivers/net/phy/realtek/realtek_main.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c -index 7620935988ce..d9455b8a3db7 100644 ---- a/drivers/net/phy/realtek/realtek_main.c -+++ b/drivers/net/phy/realtek/realtek_main.c -@@ -1050,6 +1050,11 @@ static int rtl822x_set_serdes_option_mode(struct phy_device *phydev, bool gen1) - phydev->host_interfaces) || - phydev->interface == PHY_INTERFACE_MODE_SGMII; - -+ /* disable listening on MDIO broadcast address (0) */ -+ ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, 0xa430, BIT(13)); -+ if (ret < 0) -+ return ret; -+ - /* fill in possible interfaces */ - __assign_bit(PHY_INTERFACE_MODE_2500BASEX, phydev->possible_interfaces, - has_2500); --- -2.51.0 - - -From f90b4d719f26a1089016a54d8a675d44654649e1 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 20 Oct 2022 03:34:43 +0200 -Subject: [PATCH 289/517] net: permit ieee80211_ptr even with no CFG82111 - support - -Introduce a new flag CONFIG_CFG80211_HEADERS to compile in ieee80211_ptr -even if CFG80211 support is not compiled in. This is needed for the -backports project and for any downstream wireless driver that loads in -the kernel dynamically. - -Signed-off-by: Christian Marangi ---- - include/linux/netdevice.h | 2 +- - net/batman-adv/hard-interface.c | 2 +- - net/wireless/Kconfig | 4 ++++ - 3 files changed, 6 insertions(+), 2 deletions(-) - -diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h -index 35b886385f32..c0a26b22f590 100644 ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -2224,7 +2224,7 @@ struct net_device { - #if IS_ENABLED(CONFIG_AX25) - struct ax25_dev __rcu *ax25_ptr; - #endif --#if IS_ENABLED(CONFIG_CFG80211) -+#if IS_ENABLED(CONFIG_CFG80211_HEADERS) - struct wireless_dev *ieee80211_ptr; - #endif - #if IS_ENABLED(CONFIG_IEEE802154) || IS_ENABLED(CONFIG_6LOWPAN) -diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c -index 96a412beab2d..abfa4dc9e050 100644 ---- a/net/batman-adv/hard-interface.c -+++ b/net/batman-adv/hard-interface.c -@@ -309,7 +309,7 @@ static bool batadv_is_cfg80211_netdev(struct net_device *net_device) - if (!net_device) - return false; - --#if IS_ENABLED(CONFIG_CFG80211) -+#if IS_ENABLED(CONFIG_CFG80211_HEADERS) - /* cfg80211 drivers have to set ieee80211_ptr */ - if (net_device->ieee80211_ptr) - return true; -diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig -index 10345388ad13..c141a1b74240 100644 ---- a/net/wireless/Kconfig -+++ b/net/wireless/Kconfig -@@ -26,6 +26,7 @@ config CFG80211 - # using a different algorithm, though right now they shouldn't - # (this is here rather than below to allow it to be a module) - select CRYPTO_SHA256 if CFG80211_USE_KERNEL_REGDB_KEYS -+ select CFG80211_HEADERS - help - cfg80211 is the Linux wireless LAN (802.11) configuration API. - Enable this if you have a wireless device. -@@ -36,6 +37,9 @@ config CFG80211 - - When built as a module it will be called cfg80211. - -+config CFG80211_HEADERS -+ bool "cfg80211 - headers support" -+ - if CFG80211 - - config NL80211_TESTMODE --- -2.51.0 - - -From adbd719bddb099f80db240cd3d80788d7d76096a Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Thu, 27 Oct 2022 23:39:52 +0200 -Subject: [PATCH 290/517] net: ethernet: mtk_eth_soc: compile out netsys v2 - code on mt7621 - -Avoid some branches in the hot path on low-end devices with limited CPU power, -and reduce code size - -Signed-off-by: Felix Fietkau ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -index 723475570ff7..232659c596c4 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1344,6 +1344,22 @@ struct mtk_mac { - /* the struct describing the SoC. these are declared in the soc_xyz.c files */ - extern const struct of_device_id of_mtk_match[]; - -+#ifdef CONFIG_SOC_MT7621 -+static inline bool mtk_is_netsys_v1(struct mtk_eth *eth) -+{ -+ return true; -+} -+ -+static inline bool mtk_is_netsys_v2_or_greater(struct mtk_eth *eth) -+{ -+ return false; -+} -+ -+static inline bool mtk_is_netsys_v3_or_greater(struct mtk_eth *eth) -+{ -+ return false; -+} -+#else - static inline bool mtk_is_netsys_v1(struct mtk_eth *eth) - { - return eth->soc->version == 1; -@@ -1358,6 +1374,7 @@ static inline bool mtk_is_netsys_v3_or_greater(struct mtk_eth *eth) - { - return eth->soc->version > 2; - } -+#endif - - static inline struct mtk_foe_entry * - mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash) --- -2.51.0 - - -From 8586fb600da61306b61d7a714af292fbf5e1ce43 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Thu, 3 Nov 2022 12:38:49 +0100 -Subject: [PATCH 291/517] net: ethernet: mtk_eth_soc: work around issue with - sending small fragments - -When lots of frames are sent with a number of very small fragments, an -internal FIFO can overflow, causing the DMA engine to lock up lock up and -transmit attempts time out. - -Fix this on MT7986 by increasing the reserved FIFO space. -Fix this on older chips by detecting the presence of small fragments and use -skb_gso_segment + skb_linearize to deal with them. - -Signed-off-by: Felix Fietkau ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 39 +++++++++++++++++++-- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 +- - 2 files changed, 38 insertions(+), 3 deletions(-) - -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -index e51ca80b4f15..0ab06e1ce084 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - #include - - #include "mtk_eth_soc.h" -@@ -1607,12 +1608,28 @@ static void mtk_wake_queue(struct mtk_eth *eth) - } - } - -+static bool mtk_skb_has_small_frag(struct sk_buff *skb) -+{ -+ int min_size = 16; -+ int i; -+ -+ if (skb_headlen(skb) < min_size) -+ return true; -+ -+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) -+ if (skb_frag_size(&skb_shinfo(skb)->frags[i]) < min_size) -+ return true; -+ -+ return false; -+} -+ - static netdev_tx_t mtk_start_xmit(struct sk_buff *skb, struct net_device *dev) - { - struct mtk_mac *mac = netdev_priv(dev); - struct mtk_eth *eth = mac->hw; - struct mtk_tx_ring *ring = ð->tx_ring; - struct net_device_stats *stats = &dev->stats; -+ struct sk_buff *segs, *next; - bool gso = false; - int tx_num; - -@@ -1641,6 +1658,18 @@ static netdev_tx_t mtk_start_xmit(struct sk_buff *skb, struct net_device *dev) - return NETDEV_TX_BUSY; - } - -+ if (mtk_is_netsys_v1(eth) && -+ skb_is_gso(skb) && mtk_skb_has_small_frag(skb)) { -+ segs = skb_gso_segment(skb, dev->features & ~NETIF_F_ALL_TSO); -+ if (IS_ERR(segs)) -+ goto drop; -+ -+ if (segs) { -+ consume_skb(skb); -+ skb = segs; -+ } -+ } -+ - /* TSO: fill MSS info in tcp checksum field */ - if (skb_is_gso(skb)) { - if (skb_cow_head(skb, 0)) { -@@ -1656,8 +1685,14 @@ static netdev_tx_t mtk_start_xmit(struct sk_buff *skb, struct net_device *dev) - } - } - -- if (mtk_tx_map(skb, dev, tx_num, ring, gso) < 0) -- goto drop; -+ skb_list_walk_safe(skb, skb, next) { -+ if ((mtk_is_netsys_v1(eth) && -+ mtk_skb_has_small_frag(skb) && skb_linearize(skb)) || -+ mtk_tx_map(skb, dev, tx_num, ring, gso) < 0) { -+ stats->tx_dropped++; -+ dev_kfree_skb_any(skb); -+ } -+ } - - if (unlikely(atomic_read(&ring->free_count) <= ring->thresh)) - netif_tx_stop_all_queues(dev); -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -index 232659c596c4..45ca9c17683a 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -278,7 +278,7 @@ - #define MTK_CHK_DDONE_EN BIT(28) - #define MTK_DMAD_WR_WDONE BIT(26) - #define MTK_WCOMP_EN BIT(24) --#define MTK_RESV_BUF (0x40 << 16) -+#define MTK_RESV_BUF (0x80 << 16) - #define MTK_MUTLI_CNT (0x4 << 12) - #define MTK_LEAKY_BUCKET_EN BIT(11) - --- -2.51.0 - - -From badd05196d60a325cb7fc144c802fb6354b219aa Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Tue, 15 Oct 2024 12:52:56 +0200 -Subject: [PATCH 292/517] net: ethernet: mtk_eth_soc: optimize dma ring - address/index calculation - -Since DMA descriptor sizes are all power of 2, we can avoid costly integer -division in favor or simple shifts. - -Signed-off-by: Felix Fietkau ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 112 +++++++++++--------- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 6 +- - 2 files changed, 62 insertions(+), 56 deletions(-) - -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -index 0ab06e1ce084..ff25dba46922 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -43,6 +43,11 @@ MODULE_PARM_DESC(msg_level, "Message level (-1=defaults,0=none,...,16=all)"); - offsetof(struct mtk_hw_stats, xdp_stats.x) / \ - sizeof(u64) } - -+#define RX_DESC_OFS(eth, i) \ -+ ((i) << (eth)->soc->rx.desc_shift) -+#define TX_DESC_OFS(eth, i) \ -+ ((i) << (eth)->soc->tx.desc_shift) -+ - static const struct mtk_reg_map mtk_reg_map = { - .tx_irq_mask = 0x1a1c, - .tx_irq_status = 0x1a18, -@@ -1160,14 +1165,14 @@ static int mtk_init_fq_dma(struct mtk_eth *eth) - eth->scratch_ring = eth->sram_base; - else - eth->scratch_ring = dma_alloc_coherent(eth->dma_dev, -- cnt * soc->tx.desc_size, -+ TX_DESC_OFS(eth, cnt), - ð->phy_scratch_ring, - GFP_KERNEL); - - if (unlikely(!eth->scratch_ring)) - return -ENOMEM; - -- phy_ring_tail = eth->phy_scratch_ring + soc->tx.desc_size * (cnt - 1); -+ phy_ring_tail = eth->phy_scratch_ring + TX_DESC_OFS(eth, cnt - 1); - - for (j = 0; j < DIV_ROUND_UP(soc->tx.fq_dma_size, MTK_FQ_DMA_LENGTH); j++) { - len = min_t(int, cnt - j * MTK_FQ_DMA_LENGTH, MTK_FQ_DMA_LENGTH); -@@ -1186,11 +1191,11 @@ static int mtk_init_fq_dma(struct mtk_eth *eth) - for (i = 0; i < len; i++) { - struct mtk_tx_dma_v2 *txd; - -- txd = eth->scratch_ring + (j * MTK_FQ_DMA_LENGTH + i) * soc->tx.desc_size; -+ txd = eth->scratch_ring + TX_DESC_OFS(eth, j * MTK_FQ_DMA_LENGTH + i); - txd->txd1 = dma_addr + i * MTK_QDMA_PAGE_SIZE; - if (j * MTK_FQ_DMA_LENGTH + i < cnt) - txd->txd2 = eth->phy_scratch_ring + -- (j * MTK_FQ_DMA_LENGTH + i + 1) * soc->tx.desc_size; -+ TX_DESC_OFS(eth, j * MTK_FQ_DMA_LENGTH + i + 1); - - txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE); - if (MTK_HAS_CAPS(soc->caps, MTK_36BIT_DMA)) -@@ -1220,9 +1225,9 @@ static void *mtk_qdma_phys_to_virt(struct mtk_tx_ring *ring, u32 desc) - } - - static struct mtk_tx_buf *mtk_desc_to_tx_buf(struct mtk_tx_ring *ring, -- void *txd, u32 txd_size) -+ void *txd, u32 txd_shift) - { -- int idx = (txd - ring->dma) / txd_size; -+ int idx = (txd - ring->dma) >> txd_shift; - - return &ring->buf[idx]; - } -@@ -1233,9 +1238,9 @@ static struct mtk_tx_dma *qdma_to_pdma(struct mtk_tx_ring *ring, - return ring->dma_pdma - (struct mtk_tx_dma *)ring->dma + dma; - } - --static int txd_to_idx(struct mtk_tx_ring *ring, void *dma, u32 txd_size) -+static int txd_to_idx(struct mtk_tx_ring *ring, void *dma, u32 txd_shift) - { -- return (dma - ring->dma) / txd_size; -+ return (dma - ring->dma) >> txd_shift; - } - - static void mtk_tx_unmap(struct mtk_eth *eth, struct mtk_tx_buf *tx_buf, -@@ -1443,7 +1448,7 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, - if (itxd == ring->last_free) - return -ENOMEM; - -- itx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_size); -+ itx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_shift); - memset(itx_buf, 0, sizeof(*itx_buf)); - - txd_info.addr = dma_map_single(eth->dma_dev, skb->data, txd_info.size, -@@ -1497,7 +1502,7 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, - mtk_tx_set_dma_desc(dev, txd, &txd_info); - - tx_buf = mtk_desc_to_tx_buf(ring, txd, -- soc->tx.desc_size); -+ soc->tx.desc_shift); - if (new_desc) - memset(tx_buf, 0, sizeof(*tx_buf)); - tx_buf->data = (void *)MTK_DMA_DUMMY_DESC; -@@ -1540,7 +1545,7 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, - } else { - int next_idx; - -- next_idx = NEXT_DESP_IDX(txd_to_idx(ring, txd, soc->tx.desc_size), -+ next_idx = NEXT_DESP_IDX(txd_to_idx(ring, txd, soc->tx.desc_shift), - ring->dma_size); - mtk_w32(eth, next_idx, MT7628_TX_CTX_IDX0); - } -@@ -1549,7 +1554,7 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, - - err_dma: - do { -- tx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_size); -+ tx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_shift); - - /* unmap dma */ - mtk_tx_unmap(eth, tx_buf, NULL, false); -@@ -1723,7 +1728,7 @@ static struct mtk_rx_ring *mtk_get_rx_ring(struct mtk_eth *eth) - - ring = ð->rx_ring[i]; - idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size); -- rxd = ring->dma + idx * eth->soc->rx.desc_size; -+ rxd = ring->dma + RX_DESC_OFS(eth, idx); - if (rxd->rxd2 & RX_DMA_DONE) { - ring->calc_idx_update = true; - return ring; -@@ -1891,7 +1896,7 @@ static int mtk_xdp_submit_frame(struct mtk_eth *eth, struct xdp_frame *xdpf, - } - htxd = txd; - -- tx_buf = mtk_desc_to_tx_buf(ring, txd, soc->tx.desc_size); -+ tx_buf = mtk_desc_to_tx_buf(ring, txd, soc->tx.desc_shift); - memset(tx_buf, 0, sizeof(*tx_buf)); - htx_buf = tx_buf; - -@@ -1910,7 +1915,7 @@ static int mtk_xdp_submit_frame(struct mtk_eth *eth, struct xdp_frame *xdpf, - goto unmap; - - tx_buf = mtk_desc_to_tx_buf(ring, txd, -- soc->tx.desc_size); -+ soc->tx.desc_shift); - memset(tx_buf, 0, sizeof(*tx_buf)); - n_desc++; - } -@@ -1948,7 +1953,7 @@ static int mtk_xdp_submit_frame(struct mtk_eth *eth, struct xdp_frame *xdpf, - } else { - int idx; - -- idx = txd_to_idx(ring, txd, soc->tx.desc_size); -+ idx = txd_to_idx(ring, txd, soc->tx.desc_shift); - mtk_w32(eth, NEXT_DESP_IDX(idx, ring->dma_size), - MT7628_TX_CTX_IDX0); - } -@@ -1959,7 +1964,7 @@ static int mtk_xdp_submit_frame(struct mtk_eth *eth, struct xdp_frame *xdpf, - - unmap: - while (htxd != txd) { -- tx_buf = mtk_desc_to_tx_buf(ring, htxd, soc->tx.desc_size); -+ tx_buf = mtk_desc_to_tx_buf(ring, htxd, soc->tx.desc_shift); - mtk_tx_unmap(eth, tx_buf, NULL, false); - - htxd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU; -@@ -2091,7 +2096,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget, - goto rx_done; - - idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size); -- rxd = ring->dma + idx * eth->soc->rx.desc_size; -+ rxd = ring->dma + RX_DESC_OFS(eth, idx); - data = ring->data[idx]; - - if (!mtk_rx_get_desc(eth, &trxd, rxd)) -@@ -2355,7 +2360,7 @@ static int mtk_poll_tx_qdma(struct mtk_eth *eth, int budget, - break; - - tx_buf = mtk_desc_to_tx_buf(ring, desc, -- eth->soc->tx.desc_size); -+ eth->soc->tx.desc_shift); - if (!tx_buf->data) - break; - -@@ -2406,7 +2411,7 @@ static int mtk_poll_tx_pdma(struct mtk_eth *eth, int budget, - } - mtk_tx_unmap(eth, tx_buf, &bq, true); - -- desc = ring->dma + cpu * eth->soc->tx.desc_size; -+ desc = ring->dma + TX_DESC_OFS(eth, cpu); - ring->last_free = desc; - atomic_inc(&ring->free_count); - -@@ -2524,7 +2529,7 @@ static int mtk_tx_alloc(struct mtk_eth *eth) - { - const struct mtk_soc_data *soc = eth->soc; - struct mtk_tx_ring *ring = ð->tx_ring; -- int i, sz = soc->tx.desc_size; -+ int i, sz = TX_DESC_OFS(eth, 1); - struct mtk_tx_dma_v2 *txd; - int ring_size; - u32 ofs, val; -@@ -2571,7 +2576,7 @@ static int mtk_tx_alloc(struct mtk_eth *eth) - * descriptors in ring->dma_pdma. - */ - if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { -- ring->dma_pdma = dma_alloc_coherent(eth->dma_dev, ring_size * sz, -+ ring->dma_pdma = dma_alloc_coherent(eth->dma_dev, TX_DESC_OFS(eth, ring_size), - &ring->phys_pdma, GFP_KERNEL); - if (!ring->dma_pdma) - goto no_tx_mem; -@@ -2586,7 +2591,7 @@ static int mtk_tx_alloc(struct mtk_eth *eth) - atomic_set(&ring->free_count, ring_size - 2); - ring->next_free = ring->dma; - ring->last_free = (void *)txd; -- ring->last_free_ptr = (u32)(ring->phys + ((ring_size - 1) * sz)); -+ ring->last_free_ptr = (u32)(ring->phys + TX_DESC_OFS(eth, ring_size - 1)); - ring->thresh = MAX_SKB_FRAGS; - - /* make sure that all changes to the dma ring are flushed before we -@@ -2598,7 +2603,7 @@ static int mtk_tx_alloc(struct mtk_eth *eth) - mtk_w32(eth, ring->phys, soc->reg_map->qdma.ctx_ptr); - mtk_w32(eth, ring->phys, soc->reg_map->qdma.dtx_ptr); - mtk_w32(eth, -- ring->phys + ((ring_size - 1) * sz), -+ ring->phys + TX_DESC_OFS(eth, ring_size - 1), - soc->reg_map->qdma.crx_ptr); - mtk_w32(eth, ring->last_free_ptr, soc->reg_map->qdma.drx_ptr); - -@@ -2647,14 +2652,14 @@ static void mtk_tx_clean(struct mtk_eth *eth) - } - if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && ring->dma) { - dma_free_coherent(eth->dma_dev, -- ring->dma_size * soc->tx.desc_size, -+ TX_DESC_OFS(eth, ring->dma_size), - ring->dma, ring->phys); - ring->dma = NULL; - } - - if (ring->dma_pdma) { - dma_free_coherent(eth->dma_dev, -- ring->dma_size * soc->tx.desc_size, -+ TX_DESC_OFS(eth, ring->dma_size), - ring->dma_pdma, ring->phys_pdma); - ring->dma_pdma = NULL; - } -@@ -2710,15 +2715,13 @@ static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag) - if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM) || - rx_flag != MTK_RX_FLAGS_NORMAL) { - ring->dma = dma_alloc_coherent(eth->dma_dev, -- rx_dma_size * eth->soc->rx.desc_size, -+ RX_DESC_OFS(eth, rx_dma_size), - &ring->phys, GFP_KERNEL); - } else { - struct mtk_tx_ring *tx_ring = ð->tx_ring; - -- ring->dma = tx_ring->dma + tx_ring_size * -- eth->soc->tx.desc_size * (ring_no + 1); -- ring->phys = tx_ring->phys + tx_ring_size * -- eth->soc->tx.desc_size * (ring_no + 1); -+ ring->dma = tx_ring->dma + TX_DESC_OFS(eth, tx_ring_size * (ring_no + 1)); -+ ring->phys = tx_ring->phys + TX_DESC_OFS(eth, tx_ring_size * (ring_no + 1)); - } - - if (!ring->dma) -@@ -2729,7 +2732,7 @@ static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag) - dma_addr_t dma_addr; - void *data; - -- rxd = ring->dma + i * eth->soc->rx.desc_size; -+ rxd = ring->dma + RX_DESC_OFS(eth, i); - if (ring->page_pool) { - data = mtk_page_pool_get_buff(ring->page_pool, - &dma_addr, GFP_KERNEL); -@@ -2820,7 +2823,7 @@ static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring, bool in_ - if (!ring->data[i]) - continue; - -- rxd = ring->dma + i * eth->soc->rx.desc_size; -+ rxd = ring->dma + RX_DESC_OFS(eth, i); - if (!rxd->rxd1) - continue; - -@@ -2837,7 +2840,7 @@ static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring, bool in_ - - if (!in_sram && ring->dma) { - dma_free_coherent(eth->dma_dev, -- ring->dma_size * eth->soc->rx.desc_size, -+ RX_DESC_OFS(eth, ring->dma_size), - ring->dma, ring->phys); - ring->dma = NULL; - } -@@ -3208,7 +3211,7 @@ static void mtk_dma_free(struct mtk_eth *eth) - - if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && eth->scratch_ring) { - dma_free_coherent(eth->dma_dev, -- MTK_QDMA_RING_SIZE * soc->tx.desc_size, -+ TX_DESC_OFS(eth, MTK_QDMA_RING_SIZE), - eth->scratch_ring, eth->phy_scratch_ring); - eth->scratch_ring = NULL; - eth->phy_scratch_ring = 0; -@@ -5236,6 +5239,9 @@ static void mtk_remove(struct platform_device *pdev) - mtk_mdio_cleanup(eth); - } - -+#define DESC_SIZE(struct_name) \ -+ .desc_shift = const_ilog2(sizeof(struct_name)) -+ - static const struct mtk_soc_data mt2701_data = { - .reg_map = &mtk_reg_map, - .caps = MT7623_CAPS | MTK_HWLRO, -@@ -5244,14 +5250,14 @@ static const struct mtk_soc_data mt2701_data = { - .required_pctl = true, - .version = 1, - .tx = { -- .desc_size = sizeof(struct mtk_tx_dma), -+ DESC_SIZE(struct mtk_tx_dma), - .dma_max_len = MTK_TX_DMA_BUF_LEN, - .dma_len_offset = 16, - .dma_size = MTK_DMA_SIZE(2K), - .fq_dma_size = MTK_DMA_SIZE(2K), - }, - .rx = { -- .desc_size = sizeof(struct mtk_rx_dma), -+ DESC_SIZE(struct mtk_rx_dma), - .irq_done_mask = MTK_RX_DONE_INT, - .dma_l4_valid = RX_DMA_L4_VALID, - .dma_size = MTK_DMA_SIZE(2K), -@@ -5272,14 +5278,14 @@ static const struct mtk_soc_data mt7621_data = { - .hash_offset = 2, - .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, - .tx = { -- .desc_size = sizeof(struct mtk_tx_dma), -+ DESC_SIZE(struct mtk_tx_dma), - .dma_max_len = MTK_TX_DMA_BUF_LEN, - .dma_len_offset = 16, - .dma_size = MTK_DMA_SIZE(2K), - .fq_dma_size = MTK_DMA_SIZE(2K), - }, - .rx = { -- .desc_size = sizeof(struct mtk_rx_dma), -+ DESC_SIZE(struct mtk_rx_dma), - .irq_done_mask = MTK_RX_DONE_INT, - .dma_l4_valid = RX_DMA_L4_VALID, - .dma_size = MTK_DMA_SIZE(2K), -@@ -5302,14 +5308,14 @@ static const struct mtk_soc_data mt7622_data = { - .has_accounting = true, - .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, - .tx = { -- .desc_size = sizeof(struct mtk_tx_dma), -+ DESC_SIZE(struct mtk_tx_dma), - .dma_max_len = MTK_TX_DMA_BUF_LEN, - .dma_len_offset = 16, - .dma_size = MTK_DMA_SIZE(2K), - .fq_dma_size = MTK_DMA_SIZE(2K), - }, - .rx = { -- .desc_size = sizeof(struct mtk_rx_dma), -+ DESC_SIZE(struct mtk_rx_dma), - .irq_done_mask = MTK_RX_DONE_INT, - .dma_l4_valid = RX_DMA_L4_VALID, - .dma_size = MTK_DMA_SIZE(2K), -@@ -5331,14 +5337,14 @@ static const struct mtk_soc_data mt7623_data = { - .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, - .disable_pll_modes = true, - .tx = { -- .desc_size = sizeof(struct mtk_tx_dma), -+ DESC_SIZE(struct mtk_tx_dma), - .dma_max_len = MTK_TX_DMA_BUF_LEN, - .dma_len_offset = 16, - .dma_size = MTK_DMA_SIZE(2K), - .fq_dma_size = MTK_DMA_SIZE(2K), - }, - .rx = { -- .desc_size = sizeof(struct mtk_rx_dma), -+ DESC_SIZE(struct mtk_rx_dma), - .irq_done_mask = MTK_RX_DONE_INT, - .dma_l4_valid = RX_DMA_L4_VALID, - .dma_size = MTK_DMA_SIZE(2K), -@@ -5357,14 +5363,14 @@ static const struct mtk_soc_data mt7629_data = { - .has_accounting = true, - .version = 1, - .tx = { -- .desc_size = sizeof(struct mtk_tx_dma), -+ DESC_SIZE(struct mtk_tx_dma), - .dma_max_len = MTK_TX_DMA_BUF_LEN, - .dma_len_offset = 16, - .dma_size = MTK_DMA_SIZE(2K), - .fq_dma_size = MTK_DMA_SIZE(2K), - }, - .rx = { -- .desc_size = sizeof(struct mtk_rx_dma), -+ DESC_SIZE(struct mtk_rx_dma), - .irq_done_mask = MTK_RX_DONE_INT, - .dma_l4_valid = RX_DMA_L4_VALID, - .dma_size = MTK_DMA_SIZE(2K), -@@ -5387,14 +5393,14 @@ static const struct mtk_soc_data mt7981_data = { - .has_accounting = true, - .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE, - .tx = { -- .desc_size = sizeof(struct mtk_tx_dma_v2), -+ DESC_SIZE(struct mtk_tx_dma_v2), - .dma_max_len = MTK_TX_DMA_BUF_LEN_V2, - .dma_len_offset = 8, - .dma_size = MTK_DMA_SIZE(2K), - .fq_dma_size = MTK_DMA_SIZE(2K), - }, - .rx = { -- .desc_size = sizeof(struct mtk_rx_dma), -+ DESC_SIZE(struct mtk_rx_dma), - .irq_done_mask = MTK_RX_DONE_INT, - .dma_l4_valid = RX_DMA_L4_VALID_V2, - .dma_max_len = MTK_TX_DMA_BUF_LEN, -@@ -5417,14 +5423,14 @@ static const struct mtk_soc_data mt7986_data = { - .has_accounting = true, - .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE, - .tx = { -- .desc_size = sizeof(struct mtk_tx_dma_v2), -+ DESC_SIZE(struct mtk_tx_dma_v2), - .dma_max_len = MTK_TX_DMA_BUF_LEN_V2, - .dma_len_offset = 8, - .dma_size = MTK_DMA_SIZE(2K), - .fq_dma_size = MTK_DMA_SIZE(2K), - }, - .rx = { -- .desc_size = sizeof(struct mtk_rx_dma), -+ DESC_SIZE(struct mtk_rx_dma), - .irq_done_mask = MTK_RX_DONE_INT, - .dma_l4_valid = RX_DMA_L4_VALID_V2, - .dma_max_len = MTK_TX_DMA_BUF_LEN, -@@ -5447,14 +5453,14 @@ static const struct mtk_soc_data mt7988_data = { - .has_accounting = true, - .foe_entry_size = MTK_FOE_ENTRY_V3_SIZE, - .tx = { -- .desc_size = sizeof(struct mtk_tx_dma_v2), -+ DESC_SIZE(struct mtk_tx_dma_v2), - .dma_max_len = MTK_TX_DMA_BUF_LEN_V2, - .dma_len_offset = 8, - .dma_size = MTK_DMA_SIZE(2K), - .fq_dma_size = MTK_DMA_SIZE(4K), - }, - .rx = { -- .desc_size = sizeof(struct mtk_rx_dma_v2), -+ DESC_SIZE(struct mtk_rx_dma_v2), - .irq_done_mask = MTK_RX_DONE_INT_V2, - .dma_l4_valid = RX_DMA_L4_VALID_V2, - .dma_max_len = MTK_TX_DMA_BUF_LEN_V2, -@@ -5471,13 +5477,13 @@ static const struct mtk_soc_data rt5350_data = { - .required_pctl = false, - .version = 1, - .tx = { -- .desc_size = sizeof(struct mtk_tx_dma), -+ DESC_SIZE(struct mtk_tx_dma), - .dma_max_len = MTK_TX_DMA_BUF_LEN, - .dma_len_offset = 16, - .dma_size = MTK_DMA_SIZE(2K), - }, - .rx = { -- .desc_size = sizeof(struct mtk_rx_dma), -+ DESC_SIZE(struct mtk_rx_dma), - .irq_done_mask = MTK_RX_DONE_INT, - .dma_l4_valid = RX_DMA_L4_VALID_PDMA, - .dma_max_len = MTK_TX_DMA_BUF_LEN, -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -index 45ca9c17683a..b4699cdd65fa 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1160,7 +1160,7 @@ struct mtk_reg_map { - * @foe_entry_size Foe table entry size. - * @has_accounting Bool indicating support for accounting of - * offloaded flows. -- * @desc_size Tx/Rx DMA descriptor size. -+ * @desc_shift Tx/Rx DMA descriptor size (in power-of-2). - * @irq_done_mask Rx irq done register mask. - * @dma_l4_valid Rx DMA valid register mask. - * @dma_max_len Max DMA tx/rx buffer length. -@@ -1181,14 +1181,14 @@ struct mtk_soc_data { - bool has_accounting; - bool disable_pll_modes; - struct { -- u32 desc_size; -+ u32 desc_shift; - u32 dma_max_len; - u32 dma_len_offset; - u32 dma_size; - u32 fq_dma_size; - } tx; - struct { -- u32 desc_size; -+ u32 desc_shift; - u32 irq_done_mask; - u32 dma_l4_valid; - u32 dma_max_len; --- -2.51.0 - - -From 83c9e69493e9c550f16796ba7ca7859d07e50159 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Mon, 14 Jul 2025 10:52:59 +0200 -Subject: [PATCH 293/517] net: ethernet: mtk_eth_soc: shrink struct mtk_tx_buf - -There is no need to track the difference between dma_map_page -and dma_map_single, since they're unmapped in exactly the same way. -Also reorder fields in order to avoid padding. - -Signed-off-by: Felix Fietkau ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 42 ++++++--------------- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 13 +------ - 2 files changed, 14 insertions(+), 41 deletions(-) - -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -index ff25dba46922..1d64979195c1 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1246,32 +1246,19 @@ static int txd_to_idx(struct mtk_tx_ring *ring, void *dma, u32 txd_shift) - static void mtk_tx_unmap(struct mtk_eth *eth, struct mtk_tx_buf *tx_buf, - struct xdp_frame_bulk *bq, bool napi) - { -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) { -- if (tx_buf->flags & MTK_TX_FLAGS_SINGLE0) { -- dma_unmap_single(eth->dma_dev, -- dma_unmap_addr(tx_buf, dma_addr0), -- dma_unmap_len(tx_buf, dma_len0), -- DMA_TO_DEVICE); -- } else if (tx_buf->flags & MTK_TX_FLAGS_PAGE0) { -- dma_unmap_page(eth->dma_dev, -- dma_unmap_addr(tx_buf, dma_addr0), -- dma_unmap_len(tx_buf, dma_len0), -- DMA_TO_DEVICE); -- } -- } else { -- if (dma_unmap_len(tx_buf, dma_len0)) { -- dma_unmap_page(eth->dma_dev, -- dma_unmap_addr(tx_buf, dma_addr0), -- dma_unmap_len(tx_buf, dma_len0), -- DMA_TO_DEVICE); -- } -+ if (dma_unmap_len(tx_buf, dma_len0)) { -+ dma_unmap_page(eth->dma_dev, -+ dma_unmap_addr(tx_buf, dma_addr0), -+ dma_unmap_len(tx_buf, dma_len0), -+ DMA_TO_DEVICE); -+ } - -- if (dma_unmap_len(tx_buf, dma_len1)) { -- dma_unmap_page(eth->dma_dev, -- dma_unmap_addr(tx_buf, dma_addr1), -- dma_unmap_len(tx_buf, dma_len1), -- DMA_TO_DEVICE); -- } -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA) && -+ dma_unmap_len(tx_buf, dma_len1)) { -+ dma_unmap_page(eth->dma_dev, -+ dma_unmap_addr(tx_buf, dma_addr1), -+ dma_unmap_len(tx_buf, dma_len1), -+ DMA_TO_DEVICE); - } - - if (tx_buf->data && tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { -@@ -1293,7 +1280,6 @@ static void mtk_tx_unmap(struct mtk_eth *eth, struct mtk_tx_buf *tx_buf, - xdp_return_frame(xdpf); - } - } -- tx_buf->flags = 0; - tx_buf->data = NULL; - } - -@@ -1458,7 +1444,6 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, - - mtk_tx_set_dma_desc(dev, itxd, &txd_info); - -- itx_buf->flags |= MTK_TX_FLAGS_SINGLE0; - itx_buf->mac_id = mac->id; - setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size, - k++); -@@ -1506,7 +1491,6 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, - if (new_desc) - memset(tx_buf, 0, sizeof(*tx_buf)); - tx_buf->data = (void *)MTK_DMA_DUMMY_DESC; -- tx_buf->flags |= MTK_TX_FLAGS_PAGE0; - tx_buf->mac_id = mac->id; - - setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr, -@@ -1839,8 +1823,6 @@ static int mtk_xdp_frame_map(struct mtk_eth *eth, struct net_device *dev, - txd_info->size, DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(eth->dma_dev, txd_info->addr))) - return -ENOMEM; -- -- tx_buf->flags |= MTK_TX_FLAGS_SINGLE0; - } else { - struct page *page = virt_to_head_page(data); - -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -index b4699cdd65fa..b5aad9a7360c 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -701,14 +701,6 @@ struct mtk_hw_stats { - struct u64_stats_sync syncp; - }; - --enum mtk_tx_flags { -- /* PDMA descriptor can point at 1-2 segments. This enum allows us to -- * track how memory was allocated so that it can be freed properly. -- */ -- MTK_TX_FLAGS_SINGLE0 = 0x01, -- MTK_TX_FLAGS_PAGE0 = 0x02, --}; -- - /* This enum allows us to identify how the clock is defined on the array of the - * clock in the order - */ -@@ -881,13 +873,12 @@ enum mtk_tx_buf_type { - */ - struct mtk_tx_buf { - enum mtk_tx_buf_type type; -+ u16 mac_id; - void *data; - -- u16 mac_id; -- u16 flags; - DEFINE_DMA_UNMAP_ADDR(dma_addr0); -- DEFINE_DMA_UNMAP_LEN(dma_len0); - DEFINE_DMA_UNMAP_ADDR(dma_addr1); -+ DEFINE_DMA_UNMAP_LEN(dma_len0); - DEFINE_DMA_UNMAP_LEN(dma_len1); - }; - --- -2.51.0 - - -From 930617345e8d124cf3ae225a46476dc20d03b264 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Mon, 14 Jul 2025 10:41:27 +0200 -Subject: [PATCH 294/517] net: ethernet: mtk_eth_soc: add support for sending - fraglist GSO packets - -When primarily forwarding traffic, TCP fraglist GRO can be noticeably more -efficient than regular TCP GRO. In order to avoid the overhead of -unnecessary segmentation on ethernet tx, add support for sending fraglist -GRO packets. - -Signed-off-by: Felix Fietkau ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 355 ++++++++++++++------ - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 + - 2 files changed, 259 insertions(+), 98 deletions(-) - -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -index 1d64979195c1..98266707bc22 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -18,6 +18,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - #include -@@ -27,6 +29,7 @@ - #include - #include - #include -+#include - #include - - #include "mtk_eth_soc.h" -@@ -1404,119 +1407,244 @@ static void mtk_tx_set_dma_desc(struct net_device *dev, void *txd, - mtk_tx_set_dma_desc_v1(dev, txd, info); - } - -+struct mtk_tx_map_state { -+ struct mtk_tx_dma *txd, *txd_pdma; -+ struct mtk_tx_buf *tx_buf; -+ int nbuf; -+ int ndesc; -+}; -+ -+static void -+mtk_tx_map_set_txd(struct mtk_tx_map_state *state, struct mtk_tx_ring *ring, -+ const struct mtk_soc_data *soc, struct mtk_tx_dma *txd) -+{ -+ state->txd = txd; -+ state->txd_pdma = qdma_to_pdma(ring, txd); -+ state->tx_buf = mtk_desc_to_tx_buf(ring, txd, soc->tx.desc_shift); -+ memset(state->tx_buf, 0, sizeof(*state->tx_buf)); -+} -+ -+static int -+mtk_tx_map_info(struct mtk_eth *eth, struct mtk_tx_ring *ring, -+ struct net_device *dev, struct mtk_tx_map_state *state, -+ struct mtk_tx_dma_desc_info *txd_info) -+{ -+ const struct mtk_soc_data *soc = eth->soc; -+ struct mtk_tx_buf *tx_buf = state->tx_buf; -+ struct mtk_tx_dma *txd = state->txd; -+ struct mtk_mac *mac = netdev_priv(dev); -+ -+ if (state->nbuf && -+ (MTK_HAS_CAPS(soc->caps, MTK_QDMA) || (state->nbuf & 1) == 0)) { -+ txd = mtk_qdma_phys_to_virt(ring, txd->txd2); -+ if (txd == ring->last_free) -+ return -1; -+ -+ mtk_tx_map_set_txd(state, ring, soc, txd); -+ state->ndesc++; -+ } -+ -+ mtk_tx_set_dma_desc(dev, txd, txd_info); -+ tx_buf = state->tx_buf; -+ tx_buf->data = (void *)MTK_DMA_DUMMY_DESC; -+ tx_buf->mac_id = mac->id; -+ -+ setup_tx_buf(eth, tx_buf, state->txd_pdma, txd_info->addr, -+ txd_info->size, state->nbuf++); -+ return 0; -+} -+ -+static void -+mtk_tx_update_ipaddr(struct sk_buff *skb, -+ struct iphdr *iph, struct tcphdr *th, -+ __be32 *old_ip, __be32 new_ip) -+{ -+ if (*old_ip == new_ip) -+ return; -+ -+ inet_proto_csum_replace4(&th->check, skb, *old_ip, new_ip, true); -+ csum_replace4(&iph->check, *old_ip, new_ip); -+ *old_ip = new_ip; -+} -+ -+static void -+mtk_tx_update_ip6addr(struct sk_buff *skb, struct ipv6hdr *iph, -+ struct tcphdr *th, struct in6_addr *old_ip, -+ const struct in6_addr *new_ip) -+{ -+ if (ipv6_addr_equal(old_ip, new_ip)) -+ return; -+ -+ inet_proto_csum_replace16(&th->check, skb, old_ip->s6_addr32, -+ new_ip->s6_addr32, true); -+ *old_ip = *new_ip; -+} -+ -+static void -+mtk_tx_update_port(struct sk_buff *skb, struct tcphdr *th, -+ __be16 *old_port, __be16 new_port) -+{ -+ if (*old_port == new_port) -+ return; -+ -+ inet_proto_csum_replace2(&th->check, skb, *old_port, new_port, false); -+ *old_port = new_port; -+} -+ - static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, -- int tx_num, struct mtk_tx_ring *ring, bool gso) -+ int tx_num, struct mtk_tx_ring *ring, bool gso, -+ unsigned int header_len) - { -- struct mtk_tx_dma_desc_info txd_info = { -- .size = skb_headlen(skb), -- .gso = gso, -- .csum = skb->ip_summed == CHECKSUM_PARTIAL, -- .vlan = skb_vlan_tag_present(skb), -- .qid = skb_get_queue_mapping(skb), -- .vlan_tci = skb_vlan_tag_get(skb), -- .first = true, -- .last = !skb_is_nonlinear(skb), -+ struct mtk_tx_dma_desc_info txd_info; -+ struct mtk_tx_map_state state = { -+ .ndesc = 1, - }; - struct netdev_queue *txq; - struct mtk_mac *mac = netdev_priv(dev); - struct mtk_eth *eth = mac->hw; - const struct mtk_soc_data *soc = eth->soc; -- struct mtk_tx_dma *itxd, *txd; -- struct mtk_tx_dma *itxd_pdma, *txd_pdma; -- struct mtk_tx_buf *itx_buf, *tx_buf; -- int i, n_desc = 1; -+ struct mtk_tx_dma *itxd; -+ struct sk_buff *cur_skb, *next_skb; - int queue = skb_get_queue_mapping(skb); -- int k = 0; -+ int offset = 0; -+ int i, frag_size; -+ bool gso_v4; - - txq = netdev_get_tx_queue(dev, queue); - itxd = ring->next_free; -- itxd_pdma = qdma_to_pdma(ring, itxd); - if (itxd == ring->last_free) - return -ENOMEM; - -- itx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_shift); -- memset(itx_buf, 0, sizeof(*itx_buf)); -+ cur_skb = skb; -+ next_skb = skb_shinfo(skb)->frag_list; -+ mtk_tx_map_set_txd(&state, ring, soc, itxd); -+ gso_v4 = skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4; - -- txd_info.addr = dma_map_single(eth->dma_dev, skb->data, txd_info.size, -- DMA_TO_DEVICE); -- if (unlikely(dma_mapping_error(eth->dma_dev, txd_info.addr))) -- return -ENOMEM; -+next: -+ txd_info = (struct mtk_tx_dma_desc_info){ -+ .gso = gso, -+ .qid = queue, -+ .csum = cur_skb->ip_summed == CHECKSUM_PARTIAL || gso, -+ .vlan = skb_vlan_tag_present(skb), -+ .vlan_tci = skb_vlan_tag_get(skb), -+ .first = true, -+ }; - -- mtk_tx_set_dma_desc(dev, itxd, &txd_info); -+ offset = 0; -+ frag_size = skb_headlen(cur_skb); -+ if (cur_skb != skb) { -+ struct tcphdr *th, *th2; - -- itx_buf->mac_id = mac->id; -- setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size, -- k++); -+ if (skb_cow_head(cur_skb, header_len)) -+ goto err_dma; - -- /* TX SG offload */ -- txd = itxd; -- txd_pdma = qdma_to_pdma(ring, txd); -+ memcpy(cur_skb->data - header_len, skb->data, -+ skb_network_offset(skb)); - -- for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { -- skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; -- unsigned int offset = 0; -- int frag_size = skb_frag_size(frag); -+ th = tcp_hdr(cur_skb); -+ th2 = tcp_hdr(skb); -+ if (gso_v4) { -+ struct iphdr *iph = ip_hdr(cur_skb); -+ struct iphdr *iph2 = ip_hdr(skb); - -- while (frag_size) { -- bool new_desc = true; -+ mtk_tx_update_ipaddr(skb, iph, th, &iph->saddr, -+ iph2->saddr); -+ mtk_tx_update_ipaddr(skb, iph, th, &iph->daddr, -+ iph2->daddr); -+ } else { -+ struct ipv6hdr *iph = ipv6_hdr(cur_skb); -+ struct ipv6hdr *iph2 = ipv6_hdr(skb); - -- if (MTK_HAS_CAPS(soc->caps, MTK_QDMA) || -- (i & 0x1)) { -- txd = mtk_qdma_phys_to_virt(ring, txd->txd2); -- txd_pdma = qdma_to_pdma(ring, txd); -- if (txd == ring->last_free) -- goto err_dma; -+ mtk_tx_update_ip6addr(skb, iph, th, &iph->saddr, -+ &iph2->saddr); -+ mtk_tx_update_ip6addr(skb, iph, th, &iph->daddr, -+ &iph2->daddr); -+ } - -- n_desc++; -- } else { -- new_desc = false; -- } -+ mtk_tx_update_port(skb, th, &th->source, th2->source); -+ mtk_tx_update_port(skb, th, &th->dest, th2->dest); - -- memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info)); -+ offset = -header_len; -+ frag_size += header_len; -+ } else if (next_skb) { -+ unsigned int ip_len = skb_pagelen(skb) - skb_network_offset(skb); -+ if (gso_v4) { -+ struct iphdr *iph = ip_hdr(cur_skb); -+ __be16 ip_len_val = cpu_to_be16(ip_len); -+ -+ csum_replace2(&iph->check, iph->tot_len, ip_len_val); -+ iph->tot_len = ip_len_val; -+ } else { -+ struct ipv6hdr *iph = ipv6_hdr(cur_skb); -+ __be16 ip_len_val = cpu_to_be16(ip_len - sizeof(*iph)); -+ -+ iph->payload_len = ip_len_val; -+ } -+ } -+ -+ while (frag_size) { -+ txd_info.size = min_t(unsigned int, frag_size, -+ soc->tx.dma_max_len); -+ txd_info.addr = dma_map_single(eth->dma_dev, cur_skb->data + offset, -+ txd_info.size, DMA_TO_DEVICE); -+ if (unlikely(dma_mapping_error(eth->dma_dev, txd_info.addr))) -+ goto err_dma; -+ -+ frag_size -= txd_info.size; -+ offset += txd_info.size; -+ txd_info.last = !frag_size && !skb_shinfo(cur_skb)->nr_frags; -+ if (mtk_tx_map_info(eth, ring, dev, &state, &txd_info) < 0) -+ goto err_dma; -+ } -+ -+ for (i = 0; i < skb_shinfo(cur_skb)->nr_frags; i++) { -+ skb_frag_t *frag = &skb_shinfo(cur_skb)->frags[i]; -+ -+ frag_size = skb_frag_size(frag); -+ memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info)); -+ txd_info.qid = queue; -+ offset = 0; -+ while (frag_size) { - txd_info.size = min_t(unsigned int, frag_size, - soc->tx.dma_max_len); -- txd_info.qid = queue; -- txd_info.last = i == skb_shinfo(skb)->nr_frags - 1 && -- !(frag_size - txd_info.size); -- txd_info.addr = skb_frag_dma_map(eth->dma_dev, frag, -- offset, txd_info.size, -- DMA_TO_DEVICE); -+ txd_info.addr = skb_frag_dma_map(eth->dma_dev, frag, offset, -+ txd_info.size, DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(eth->dma_dev, txd_info.addr))) - goto err_dma; - -- mtk_tx_set_dma_desc(dev, txd, &txd_info); -- -- tx_buf = mtk_desc_to_tx_buf(ring, txd, -- soc->tx.desc_shift); -- if (new_desc) -- memset(tx_buf, 0, sizeof(*tx_buf)); -- tx_buf->data = (void *)MTK_DMA_DUMMY_DESC; -- tx_buf->mac_id = mac->id; -- -- setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr, -- txd_info.size, k++); -- - frag_size -= txd_info.size; - offset += txd_info.size; -+ txd_info.last = i == skb_shinfo(cur_skb)->nr_frags - 1 && -+ !frag_size; -+ if (mtk_tx_map_info(eth, ring, dev, &state, &txd_info) < 0) -+ goto err_dma; - } - } - -- /* store skb to cleanup */ -- itx_buf->type = MTK_TYPE_SKB; -- itx_buf->data = skb; -- - if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { -- if (k & 0x1) -- txd_pdma->txd2 |= TX_DMA_LS0; -- else -- txd_pdma->txd2 |= TX_DMA_LS1; -+ if (state.nbuf & 0x1) { -+ state.txd_pdma->txd2 |= TX_DMA_LS0; -+ state.nbuf++; -+ } else { -+ state.txd_pdma->txd2 |= TX_DMA_LS1; -+ } -+ } -+ -+ if (next_skb) { -+ cur_skb = next_skb; -+ next_skb = cur_skb->next; -+ goto next; - } - -+ /* store skb to cleanup */ -+ state.tx_buf->type = MTK_TYPE_SKB; -+ state.tx_buf->data = skb; -+ - netdev_tx_sent_queue(txq, skb->len); - skb_tx_timestamp(skb); - -- ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2); -- atomic_sub(n_desc, &ring->free_count); -+ ring->next_free = mtk_qdma_phys_to_virt(ring, state.txd->txd2); -+ atomic_sub(state.ndesc, &ring->free_count); - - /* make sure that all changes to the dma ring are flushed before we - * continue -@@ -1525,11 +1653,11 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, - - if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { - if (netif_xmit_stopped(txq) || !netdev_xmit_more()) -- mtk_w32(eth, txd->txd2, soc->reg_map->qdma.ctx_ptr); -+ mtk_w32(eth, state.txd->txd2, soc->reg_map->qdma.ctx_ptr); - } else { - int next_idx; - -- next_idx = NEXT_DESP_IDX(txd_to_idx(ring, txd, soc->tx.desc_shift), -+ next_idx = NEXT_DESP_IDX(txd_to_idx(ring, state.txd, soc->tx.desc_shift), - ring->dma_size); - mtk_w32(eth, next_idx, MT7628_TX_CTX_IDX0); - } -@@ -1538,18 +1666,20 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, - - err_dma: - do { -- tx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_shift); -+ struct mtk_tx_dma *itxd_pdma = qdma_to_pdma(ring, itxd); -+ struct mtk_tx_buf *itx_buf; -+ -+ itx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_shift); - - /* unmap dma */ -- mtk_tx_unmap(eth, tx_buf, NULL, false); -+ mtk_tx_unmap(eth, itx_buf, NULL, false); - - itxd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU; - if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) - itxd_pdma->txd2 = TX_DMA_DESP2_DEF; - - itxd = mtk_qdma_phys_to_virt(ring, itxd->txd2); -- itxd_pdma = qdma_to_pdma(ring, itxd); -- } while (itxd != txd); -+ } while (itxd != state.txd); - - return -ENOMEM; - } -@@ -1569,6 +1699,9 @@ static int mtk_cal_txd_req(struct mtk_eth *eth, struct sk_buff *skb) - nfrags += skb_shinfo(skb)->nr_frags; - } - -+ for (skb = skb_shinfo(skb)->frag_list; skb; skb = skb->next) -+ nfrags += mtk_cal_txd_req(eth, skb) + 1; -+ - return nfrags; - } - -@@ -1609,9 +1742,29 @@ static bool mtk_skb_has_small_frag(struct sk_buff *skb) - if (skb_frag_size(&skb_shinfo(skb)->frags[i]) < min_size) - return true; - -+ for (skb = skb_shinfo(skb)->frag_list; skb; skb = skb->next) -+ if (mtk_skb_has_small_frag(skb)) -+ return true; -+ - return false; - } - -+static bool mtk_skb_valid_gso(struct mtk_eth *eth, struct sk_buff *skb, -+ unsigned int header_len) -+{ -+ if (mtk_is_netsys_v1(eth) && mtk_skb_has_small_frag(skb)) -+ return false; -+ -+ if (!(skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST)) -+ return true; -+ -+ if (skb_tnl_header_len(skb)) -+ return false; -+ -+ return skb_pagelen(skb) - header_len == skb_shinfo(skb)->gso_size && -+ skb_headlen(skb) > header_len; -+} -+ - static netdev_tx_t mtk_start_xmit(struct sk_buff *skb, struct net_device *dev) - { - struct mtk_mac *mac = netdev_priv(dev); -@@ -1619,6 +1772,7 @@ static netdev_tx_t mtk_start_xmit(struct sk_buff *skb, struct net_device *dev) - struct mtk_tx_ring *ring = ð->tx_ring; - struct net_device_stats *stats = &dev->stats; - struct sk_buff *segs, *next; -+ unsigned int header_len = 0; - bool gso = false; - int tx_num; - -@@ -1647,37 +1801,42 @@ static netdev_tx_t mtk_start_xmit(struct sk_buff *skb, struct net_device *dev) - return NETDEV_TX_BUSY; - } - -- if (mtk_is_netsys_v1(eth) && -- skb_is_gso(skb) && mtk_skb_has_small_frag(skb)) { -- segs = skb_gso_segment(skb, dev->features & ~NETIF_F_ALL_TSO); -- if (IS_ERR(segs)) -- goto drop; -- -- if (segs) { -- consume_skb(skb); -- skb = segs; -- } -- } -- -- /* TSO: fill MSS info in tcp checksum field */ - if (skb_is_gso(skb)) { -- if (skb_cow_head(skb, 0)) { -- netif_warn(eth, tx_err, dev, -- "GSO expand head fail.\n"); -- goto drop; -+ header_len = skb_tcp_all_headers(skb); -+ if (!mtk_skb_valid_gso(eth, skb, header_len)) { -+ segs = skb_gso_segment(skb, dev->features & ~NETIF_F_ALL_TSO); -+ if (IS_ERR(segs)) -+ goto drop; -+ -+ if (segs) { -+ consume_skb(skb); -+ skb = segs; -+ } -+ goto send; - } - -+ if ((skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST)) -+ goto send; -+ - if (skb_shinfo(skb)->gso_type & - (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) { -+ /* TSO: fill MSS info in tcp checksum field */ - gso = true; -+ if (skb_cow_head(skb, 0)) { -+ netif_warn(eth, tx_err, dev, -+ "GSO expand head fail.\n"); -+ goto drop; -+ } -+ - tcp_hdr(skb)->check = htons(skb_shinfo(skb)->gso_size); - } - } - -+send: - skb_list_walk_safe(skb, skb, next) { - if ((mtk_is_netsys_v1(eth) && - mtk_skb_has_small_frag(skb) && skb_linearize(skb)) || -- mtk_tx_map(skb, dev, tx_num, ring, gso) < 0) { -+ mtk_tx_map(skb, dev, tx_num, ring, gso, header_len) < 0) { - stats->tx_dropped++; - dev_kfree_skb_any(skb); - } -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -index b5aad9a7360c..1cf701b4126c 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -51,6 +51,8 @@ - NETIF_F_HW_VLAN_CTAG_TX | \ - NETIF_F_SG | NETIF_F_TSO | \ - NETIF_F_TSO6 | \ -+ NETIF_F_FRAGLIST | \ -+ NETIF_F_GSO_FRAGLIST | \ - NETIF_F_IPV6_CSUM |\ - NETIF_F_HW_TC) - #define MTK_HW_FEATURES_MT7628 (NETIF_F_SG | NETIF_F_RXCSUM) --- -2.51.0 - - -From 878fe32f74d05f5e8b1ab976b2ac1b6caec2e6c7 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Mon, 20 May 2024 14:29:58 +0200 -Subject: [PATCH 295/517] net: ethernet: mtk_eth_soc: use napi_build_skb() - -The napi_build_skb() can reuse the skb in skb cache per CPU or -can allocate skbs in bulk, which helps improve the performance. - -Signed-off-by: Felix Fietkau ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -index 98266707bc22..4f7fdb29ad5b 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -2305,7 +2305,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget, - if (ret != XDP_PASS) - goto skip_rx; - -- skb = build_skb(data, PAGE_SIZE); -+ skb = napi_build_skb(data, PAGE_SIZE); - if (unlikely(!skb)) { - page_pool_put_full_page(ring->page_pool, - page, true); -@@ -2343,7 +2343,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget, - dma_unmap_single(eth->dma_dev, ((u64)trxd.rxd1 | addr64), - ring->buf_size, DMA_FROM_DEVICE); - -- skb = build_skb(data, ring->frag_size); -+ skb = napi_build_skb(data, ring->frag_size); - if (unlikely(!skb)) { - netdev->stats.rx_dropped++; - skb_free_frag(data); --- -2.51.0 - - -From c29fb4a652ba3554f49264320bea3f3355480ee3 Mon Sep 17 00:00:00 2001 -From: Chad Monroe -Date: Mon, 16 Sep 2024 19:29:03 -0700 -Subject: [PATCH 296/517] net: ethernet: mediatek: increase QDMA RESV_BUF size - -Increase QDMA RESV_BUF from 2K to 3K for netsys v2 to match Mediatek SDK[1]. -This helps reduce the possibility of Ethernet transmit timeouts. - -[1]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/19d8456c3051e5f6dabf42fa770916a2126ea4bf - -Signed-off-by: Chad Monroe ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 6 ++++-- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 + - 2 files changed, 5 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -index 4f7fdb29ad5b..ba9b3d6be8b2 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3476,12 +3476,14 @@ static int mtk_start_dma(struct mtk_eth *eth) - MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO | - MTK_RX_2B_OFFSET | MTK_TX_WB_DDONE; - -- if (mtk_is_netsys_v2_or_greater(eth)) -+ if (mtk_is_netsys_v2_or_greater(eth)) { -+ val &= ~MTK_RESV_BUF_MASK; - val |= MTK_MUTLI_CNT | MTK_RESV_BUF | - MTK_WCOMP_EN | MTK_DMAD_WR_WDONE | - MTK_CHK_DDONE_EN; -- else -+ } else { - val |= MTK_RX_BT_32DWORDS; -+ } - mtk_w32(eth, val, reg_map->qdma.glo_cfg); - - mtk_w32(eth, -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -index 1cf701b4126c..88dee7983642 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -282,6 +282,7 @@ - #define MTK_WCOMP_EN BIT(24) - #define MTK_RESV_BUF (0x80 << 16) - #define MTK_MUTLI_CNT (0x4 << 12) -+#define MTK_RESV_BUF_MASK (0xff << 16) - #define MTK_LEAKY_BUCKET_EN BIT(11) - - /* QDMA Flow Control Register */ --- -2.51.0 - - -From 39e91a55c5696f31f8afd9d764863578695c3028 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Thu, 23 Mar 2023 10:24:11 +0100 -Subject: [PATCH 297/517] net: ethernet: mtk_eth_soc: improve keeping track of - offloaded flows - -Unify tracking of L2 and L3 flows. Use the generic list field in struct -mtk_foe_entry for tracking L2 subflows. Preparation for improving -flow accounting support. - -Signed-off-by: Felix Fietkau ---- - drivers/net/ethernet/mediatek/mtk_ppe.c | 162 ++++++++++++------------ - drivers/net/ethernet/mediatek/mtk_ppe.h | 15 +-- - 2 files changed, 86 insertions(+), 91 deletions(-) - -diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c -index ada852adc5f7..5b352ab64ef7 100644 ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -479,42 +479,43 @@ int mtk_foe_entry_set_queue(struct mtk_eth *eth, struct mtk_foe_entry *entry, - return 0; - } - -+static int -+mtk_flow_entry_match_len(struct mtk_eth *eth, struct mtk_foe_entry *entry) -+{ -+ int type = mtk_get_ib1_pkt_type(eth, entry->ib1); -+ -+ if (type > MTK_PPE_PKT_TYPE_IPV4_DSLITE) -+ return offsetof(struct mtk_foe_entry, ipv6._rsv); -+ else -+ return offsetof(struct mtk_foe_entry, ipv4.ib2); -+} -+ - static bool - mtk_flow_entry_match(struct mtk_eth *eth, struct mtk_flow_entry *entry, -- struct mtk_foe_entry *data) -+ struct mtk_foe_entry *data, int len) - { -- int type, len; -- - if ((data->ib1 ^ entry->data.ib1) & MTK_FOE_IB1_UDP) - return false; - -- type = mtk_get_ib1_pkt_type(eth, entry->data.ib1); -- if (type > MTK_PPE_PKT_TYPE_IPV4_DSLITE) -- len = offsetof(struct mtk_foe_entry, ipv6._rsv); -- else -- len = offsetof(struct mtk_foe_entry, ipv4.ib2); -- - return !memcmp(&entry->data.data, &data->data, len - 4); - } - - static void --__mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) -+__mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, -+ bool set_state) - { -- struct hlist_head *head; - struct hlist_node *tmp; - - if (entry->type == MTK_FLOW_TYPE_L2) { - rhashtable_remove_fast(&ppe->l2_flows, &entry->l2_node, - mtk_flow_l2_ht_params); - -- head = &entry->l2_flows; -- hlist_for_each_entry_safe(entry, tmp, head, l2_data.list) -- __mtk_foe_entry_clear(ppe, entry); -+ hlist_for_each_entry_safe(entry, tmp, &entry->l2_flows, l2_list) -+ __mtk_foe_entry_clear(ppe, entry, set_state); - return; - } - -- hlist_del_init(&entry->list); -- if (entry->hash != 0xffff) { -+ if (entry->hash != 0xffff && set_state) { - struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, entry->hash); - - hwe->ib1 &= ~MTK_FOE_IB1_STATE; -@@ -535,7 +536,8 @@ __mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - if (entry->type != MTK_FLOW_TYPE_L2_SUBFLOW) - return; - -- hlist_del_init(&entry->l2_data.list); -+ hlist_del_init(&entry->l2_list); -+ hlist_del_init(&entry->list); - kfree(entry); - } - -@@ -551,68 +553,57 @@ static int __mtk_foe_entry_idle_time(struct mtk_ppe *ppe, u32 ib1) - return now - timestamp; - } - -+static bool -+mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) -+{ -+ struct mtk_foe_entry foe = {}; -+ struct mtk_foe_entry *hwe; -+ u16 hash = entry->hash; -+ int len; -+ -+ if (hash == 0xffff) -+ return false; -+ -+ hwe = mtk_foe_get_entry(ppe, hash); -+ len = mtk_flow_entry_match_len(ppe->eth, &entry->data); -+ memcpy(&foe, hwe, len); -+ -+ if (!mtk_flow_entry_match(ppe->eth, entry, &foe, len) || -+ FIELD_GET(MTK_FOE_IB1_STATE, foe.ib1) != MTK_FOE_STATE_BIND) -+ return false; -+ -+ entry->data.ib1 = foe.ib1; -+ -+ return true; -+} -+ - static void - mtk_flow_entry_update_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { - u32 ib1_ts_mask = mtk_get_ib1_ts_mask(ppe->eth); - struct mtk_flow_entry *cur; -- struct mtk_foe_entry *hwe; - struct hlist_node *tmp; - int idle; - - idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1); -- hlist_for_each_entry_safe(cur, tmp, &entry->l2_flows, l2_data.list) { -+ hlist_for_each_entry_safe(cur, tmp, &entry->l2_flows, l2_list) { - int cur_idle; -- u32 ib1; -- -- hwe = mtk_foe_get_entry(ppe, cur->hash); -- ib1 = READ_ONCE(hwe->ib1); - -- if (FIELD_GET(MTK_FOE_IB1_STATE, ib1) != MTK_FOE_STATE_BIND) { -- cur->hash = 0xffff; -- __mtk_foe_entry_clear(ppe, cur); -+ if (!mtk_flow_entry_update(ppe, cur)) { -+ __mtk_foe_entry_clear(ppe, entry, false); - continue; - } - -- cur_idle = __mtk_foe_entry_idle_time(ppe, ib1); -+ cur_idle = __mtk_foe_entry_idle_time(ppe, cur->data.ib1); - if (cur_idle >= idle) - continue; - - idle = cur_idle; - entry->data.ib1 &= ~ib1_ts_mask; -- entry->data.ib1 |= ib1 & ib1_ts_mask; -+ entry->data.ib1 |= cur->data.ib1 & ib1_ts_mask; - } - } - --static void --mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) --{ -- struct mtk_foe_entry foe = {}; -- struct mtk_foe_entry *hwe; -- -- spin_lock_bh(&ppe_lock); -- -- if (entry->type == MTK_FLOW_TYPE_L2) { -- mtk_flow_entry_update_l2(ppe, entry); -- goto out; -- } -- -- if (entry->hash == 0xffff) -- goto out; -- -- hwe = mtk_foe_get_entry(ppe, entry->hash); -- memcpy(&foe, hwe, ppe->eth->soc->foe_entry_size); -- if (!mtk_flow_entry_match(ppe->eth, entry, &foe)) { -- entry->hash = 0xffff; -- goto out; -- } -- -- entry->data.ib1 = foe.ib1; -- --out: -- spin_unlock_bh(&ppe_lock); --} -- - static void - __mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry, - u16 hash) -@@ -653,7 +644,8 @@ __mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry, - void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { - spin_lock_bh(&ppe_lock); -- __mtk_foe_entry_clear(ppe, entry); -+ __mtk_foe_entry_clear(ppe, entry, true); -+ hlist_del_init(&entry->list); - spin_unlock_bh(&ppe_lock); - } - -@@ -700,8 +692,8 @@ mtk_foe_entry_commit_subflow(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, - { - const struct mtk_soc_data *soc = ppe->eth->soc; - struct mtk_flow_entry *flow_info; -- struct mtk_foe_entry foe = {}, *hwe; - struct mtk_foe_mac_info *l2; -+ struct mtk_foe_entry *hwe; - u32 ib1_mask = mtk_get_ib1_pkt_type_mask(ppe->eth) | MTK_FOE_IB1_UDP; - int type; - -@@ -709,30 +701,30 @@ mtk_foe_entry_commit_subflow(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, - if (!flow_info) - return; - -- flow_info->l2_data.base_flow = entry; - flow_info->type = MTK_FLOW_TYPE_L2_SUBFLOW; - flow_info->hash = hash; - hlist_add_head(&flow_info->list, - &ppe->foe_flow[hash / soc->hash_offset]); -- hlist_add_head(&flow_info->l2_data.list, &entry->l2_flows); -+ hlist_add_head(&flow_info->l2_list, &entry->l2_flows); - - hwe = mtk_foe_get_entry(ppe, hash); -- memcpy(&foe, hwe, soc->foe_entry_size); -- foe.ib1 &= ib1_mask; -- foe.ib1 |= entry->data.ib1 & ~ib1_mask; -+ memcpy(&flow_info->data, hwe, soc->foe_entry_size); -+ flow_info->data.ib1 &= ib1_mask; -+ flow_info->data.ib1 |= entry->data.ib1 & ~ib1_mask; - -- l2 = mtk_foe_entry_l2(ppe->eth, &foe); -+ l2 = mtk_foe_entry_l2(ppe->eth, &flow_info->data); - memcpy(l2, &entry->data.bridge.l2, sizeof(*l2)); - -- type = mtk_get_ib1_pkt_type(ppe->eth, foe.ib1); -+ type = mtk_get_ib1_pkt_type(ppe->eth, flow_info->data.ib1); - if (type == MTK_PPE_PKT_TYPE_IPV4_HNAPT) -- memcpy(&foe.ipv4.new, &foe.ipv4.orig, sizeof(foe.ipv4.new)); -+ memcpy(&flow_info->data.ipv4.new, &flow_info->data.ipv4.orig, -+ sizeof(flow_info->data.ipv4.new)); - else if (type >= MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T && l2->etype == ETH_P_IP) - l2->etype = ETH_P_IPV6; - -- *mtk_foe_entry_ib2(ppe->eth, &foe) = entry->data.bridge.ib2; -+ *mtk_foe_entry_ib2(ppe->eth, &flow_info->data) = entry->data.bridge.ib2; - -- __mtk_foe_entry_commit(ppe, &foe, hash); -+ __mtk_foe_entry_commit(ppe, &flow_info->data, hash); - } - - void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash) -@@ -742,9 +734,11 @@ void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash) - struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, hash); - struct mtk_flow_entry *entry; - struct mtk_foe_bridge key = {}; -+ struct mtk_foe_entry foe = {}; - struct hlist_node *n; - struct ethhdr *eh; - bool found = false; -+ int entry_len; - u8 *tag; - - spin_lock_bh(&ppe_lock); -@@ -752,20 +746,14 @@ void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash) - if (FIELD_GET(MTK_FOE_IB1_STATE, hwe->ib1) == MTK_FOE_STATE_BIND) - goto out; - -- hlist_for_each_entry_safe(entry, n, head, list) { -- if (entry->type == MTK_FLOW_TYPE_L2_SUBFLOW) { -- if (unlikely(FIELD_GET(MTK_FOE_IB1_STATE, hwe->ib1) == -- MTK_FOE_STATE_BIND)) -- continue; -- -- entry->hash = 0xffff; -- __mtk_foe_entry_clear(ppe, entry); -- continue; -- } -+ entry_len = mtk_flow_entry_match_len(ppe->eth, hwe); -+ memcpy(&foe, hwe, entry_len); - -- if (found || !mtk_flow_entry_match(ppe->eth, entry, hwe)) { -+ hlist_for_each_entry_safe(entry, n, head, list) { -+ if (found || -+ !mtk_flow_entry_match(ppe->eth, entry, &foe, entry_len)) { - if (entry->hash != 0xffff) -- entry->hash = 0xffff; -+ __mtk_foe_entry_clear(ppe, entry, false); - continue; - } - -@@ -816,9 +804,17 @@ void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash) - - int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { -- mtk_flow_entry_update(ppe, entry); -+ int idle; -+ -+ spin_lock_bh(&ppe_lock); -+ if (entry->type == MTK_FLOW_TYPE_L2) -+ mtk_flow_entry_update_l2(ppe, entry); -+ else -+ mtk_flow_entry_update(ppe, entry); -+ idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1); -+ spin_unlock_bh(&ppe_lock); - -- return __mtk_foe_entry_idle_time(ppe, entry->data.ib1); -+ return idle; - } - - int mtk_ppe_prepare_reset(struct mtk_ppe *ppe) -diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.h b/drivers/net/ethernet/mediatek/mtk_ppe.h -index 223f709e2704..aa0799c1ce95 100644 ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -286,7 +286,12 @@ enum { - - struct mtk_flow_entry { - union { -- struct hlist_node list; -+ /* regular flows + L2 subflows */ -+ struct { -+ struct hlist_node list; -+ struct hlist_node l2_list; -+ }; -+ /* L2 flows */ - struct { - struct rhash_head l2_node; - struct hlist_head l2_flows; -@@ -296,13 +301,7 @@ struct mtk_flow_entry { - s8 wed_index; - u8 ppe_index; - u16 hash; -- union { -- struct mtk_foe_entry data; -- struct { -- struct mtk_flow_entry *base_flow; -- struct hlist_node list; -- } l2_data; -- }; -+ struct mtk_foe_entry data; - struct rhash_head node; - unsigned long cookie; - }; --- -2.51.0 - - -From 5fc20c1af300b58d2ee1f802ae8d630ef24f3573 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Thu, 23 Mar 2023 11:05:22 +0100 -Subject: [PATCH 298/517] net: ethernet: mediatek: fix ppe flow accounting for - L2 flows - -For L2 flows, the packet/byte counters should report the sum of the -counters of their subflows, both current and expired. -In order to make this work, change the way that accounting data is tracked. -Reset counters when a flow enters bind. Once it expires (or enters unbind), -store the last counter value in struct mtk_flow_entry. - -Signed-off-by: Felix Fietkau ---- - drivers/net/ethernet/mediatek/mtk_ppe.c | 140 ++++++++++-------- - drivers/net/ethernet/mediatek/mtk_ppe.h | 8 +- - .../net/ethernet/mediatek/mtk_ppe_debugfs.c | 2 +- - .../net/ethernet/mediatek/mtk_ppe_offload.c | 17 +-- - 4 files changed, 89 insertions(+), 78 deletions(-) - -diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c -index 5b352ab64ef7..96365a75b198 100644 ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -83,9 +83,9 @@ static int mtk_ppe_mib_wait_busy(struct mtk_ppe *ppe) - int ret; - u32 val; - -- ret = readl_poll_timeout(ppe->base + MTK_PPE_MIB_SER_CR, val, -- !(val & MTK_PPE_MIB_SER_CR_ST), -- 20, MTK_PPE_WAIT_TIMEOUT_US); -+ ret = readl_poll_timeout_atomic(ppe->base + MTK_PPE_MIB_SER_CR, val, -+ !(val & MTK_PPE_MIB_SER_CR_ST), -+ 20, MTK_PPE_WAIT_TIMEOUT_US); - - if (ret) - dev_err(ppe->dev, "MIB table busy"); -@@ -93,17 +93,31 @@ static int mtk_ppe_mib_wait_busy(struct mtk_ppe *ppe) - return ret; - } - --static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *packets) -+static inline struct mtk_foe_accounting * -+mtk_ppe_acct_data(struct mtk_ppe *ppe, u16 index) -+{ -+ if (!ppe->acct_table) -+ return NULL; -+ -+ return ppe->acct_table + index * sizeof(struct mtk_foe_accounting); -+} -+ -+struct mtk_foe_accounting *mtk_ppe_mib_entry_read(struct mtk_ppe *ppe, u16 index) - { - u32 val, cnt_r0, cnt_r1, cnt_r2; -+ struct mtk_foe_accounting *acct; - int ret; - - val = FIELD_PREP(MTK_PPE_MIB_SER_CR_ADDR, index) | MTK_PPE_MIB_SER_CR_ST; - ppe_w32(ppe, MTK_PPE_MIB_SER_CR, val); - -+ acct = mtk_ppe_acct_data(ppe, index); -+ if (!acct) -+ return NULL; -+ - ret = mtk_ppe_mib_wait_busy(ppe); - if (ret) -- return ret; -+ return acct; - - cnt_r0 = readl(ppe->base + MTK_PPE_MIB_SER_R0); - cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1); -@@ -112,19 +126,19 @@ static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *p - if (mtk_is_netsys_v3_or_greater(ppe->eth)) { - /* 64 bit for each counter */ - u32 cnt_r3 = readl(ppe->base + MTK_PPE_MIB_SER_R3); -- *bytes = ((u64)cnt_r1 << 32) | cnt_r0; -- *packets = ((u64)cnt_r3 << 32) | cnt_r2; -+ acct->bytes += ((u64)cnt_r1 << 32) | cnt_r0; -+ acct->packets += ((u64)cnt_r3 << 32) | cnt_r2; - } else { - /* 48 bit byte counter, 40 bit packet counter */ - u32 byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0); - u32 byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1); - u32 pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1); - u32 pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2); -- *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low; -- *packets = ((u64)pkt_cnt_high << 16) | pkt_cnt_low; -+ acct->bytes += ((u64)byte_cnt_high << 32) | byte_cnt_low; -+ acct->packets += ((u64)pkt_cnt_high << 16) | pkt_cnt_low; - } - -- return 0; -+ return acct; - } - - static void mtk_ppe_cache_clear(struct mtk_ppe *ppe) -@@ -522,14 +536,6 @@ __mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, - hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID); - dma_wmb(); - mtk_ppe_cache_clear(ppe); -- -- if (ppe->accounting) { -- struct mtk_foe_accounting *acct; -- -- acct = ppe->acct_table + entry->hash * sizeof(*acct); -- acct->packets = 0; -- acct->bytes = 0; -- } - } - entry->hash = 0xffff; - -@@ -554,11 +560,14 @@ static int __mtk_foe_entry_idle_time(struct mtk_ppe *ppe, u32 ib1) - } - - static bool --mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) -+mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, -+ u64 *packets, u64 *bytes) - { -+ struct mtk_foe_accounting *acct; - struct mtk_foe_entry foe = {}; - struct mtk_foe_entry *hwe; - u16 hash = entry->hash; -+ bool ret = false; - int len; - - if (hash == 0xffff) -@@ -569,18 +578,35 @@ mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - memcpy(&foe, hwe, len); - - if (!mtk_flow_entry_match(ppe->eth, entry, &foe, len) || -- FIELD_GET(MTK_FOE_IB1_STATE, foe.ib1) != MTK_FOE_STATE_BIND) -- return false; -+ FIELD_GET(MTK_FOE_IB1_STATE, foe.ib1) != MTK_FOE_STATE_BIND) { -+ acct = mtk_ppe_acct_data(ppe, hash); -+ if (acct) { -+ entry->prev_packets += acct->packets; -+ entry->prev_bytes += acct->bytes; -+ } -+ -+ goto out; -+ } - - entry->data.ib1 = foe.ib1; -+ acct = mtk_ppe_mib_entry_read(ppe, hash); -+ ret = true; -+ -+out: -+ if (acct) { -+ *packets += acct->packets; -+ *bytes += acct->bytes; -+ } - -- return true; -+ return ret; - } - - static void - mtk_flow_entry_update_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { - u32 ib1_ts_mask = mtk_get_ib1_ts_mask(ppe->eth); -+ u64 *packets = &entry->packets; -+ u64 *bytes = &entry->bytes; - struct mtk_flow_entry *cur; - struct hlist_node *tmp; - int idle; -@@ -589,7 +615,9 @@ mtk_flow_entry_update_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - hlist_for_each_entry_safe(cur, tmp, &entry->l2_flows, l2_list) { - int cur_idle; - -- if (!mtk_flow_entry_update(ppe, cur)) { -+ if (!mtk_flow_entry_update(ppe, cur, packets, bytes)) { -+ entry->prev_packets += cur->prev_packets; -+ entry->prev_bytes += cur->prev_bytes; - __mtk_foe_entry_clear(ppe, entry, false); - continue; - } -@@ -604,10 +632,29 @@ mtk_flow_entry_update_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - } - } - -+void mtk_foe_entry_get_stats(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, -+ int *idle) -+{ -+ entry->packets = entry->prev_packets; -+ entry->bytes = entry->prev_bytes; -+ -+ spin_lock_bh(&ppe_lock); -+ -+ if (entry->type == MTK_FLOW_TYPE_L2) -+ mtk_flow_entry_update_l2(ppe, entry); -+ else -+ mtk_flow_entry_update(ppe, entry, &entry->packets, &entry->bytes); -+ -+ *idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1); -+ -+ spin_unlock_bh(&ppe_lock); -+} -+ - static void - __mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry, - u16 hash) - { -+ struct mtk_foe_accounting *acct; - struct mtk_eth *eth = ppe->eth; - u16 timestamp = mtk_eth_timestamp(eth); - struct mtk_foe_entry *hwe; -@@ -638,6 +685,12 @@ __mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry, - - dma_wmb(); - -+ acct = mtk_ppe_mib_entry_read(ppe, hash); -+ if (acct) { -+ acct->packets = 0; -+ acct->bytes = 0; -+ } -+ - mtk_ppe_cache_clear(ppe); - } - -@@ -802,21 +855,6 @@ void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash) - spin_unlock_bh(&ppe_lock); - } - --int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) --{ -- int idle; -- -- spin_lock_bh(&ppe_lock); -- if (entry->type == MTK_FLOW_TYPE_L2) -- mtk_flow_entry_update_l2(ppe, entry); -- else -- mtk_flow_entry_update(ppe, entry); -- idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1); -- spin_unlock_bh(&ppe_lock); -- -- return idle; --} -- - int mtk_ppe_prepare_reset(struct mtk_ppe *ppe) - { - if (!ppe) -@@ -844,32 +882,6 @@ int mtk_ppe_prepare_reset(struct mtk_ppe *ppe) - return mtk_ppe_wait_busy(ppe); - } - --struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index, -- struct mtk_foe_accounting *diff) --{ -- struct mtk_foe_accounting *acct; -- int size = sizeof(struct mtk_foe_accounting); -- u64 bytes, packets; -- -- if (!ppe->accounting) -- return NULL; -- -- if (mtk_mib_entry_read(ppe, index, &bytes, &packets)) -- return NULL; -- -- acct = ppe->acct_table + index * size; -- -- acct->bytes += bytes; -- acct->packets += packets; -- -- if (diff) { -- diff->bytes = bytes; -- diff->packets = packets; -- } -- -- return acct; --} -- - struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index) - { - bool accounting = eth->soc->has_accounting; -diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.h b/drivers/net/ethernet/mediatek/mtk_ppe.h -index aa0799c1ce95..9a4990aa5fa5 100644 ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -304,6 +304,8 @@ struct mtk_flow_entry { - struct mtk_foe_entry data; - struct rhash_head node; - unsigned long cookie; -+ u64 prev_packets, prev_bytes; -+ u64 packets, bytes; - }; - - struct mtk_mib_entry { -@@ -348,6 +350,7 @@ void mtk_ppe_deinit(struct mtk_eth *eth); - void mtk_ppe_start(struct mtk_ppe *ppe); - int mtk_ppe_stop(struct mtk_ppe *ppe); - int mtk_ppe_prepare_reset(struct mtk_ppe *ppe); -+struct mtk_foe_accounting *mtk_ppe_mib_entry_read(struct mtk_ppe *ppe, u16 index); - - void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash); - -@@ -397,9 +400,8 @@ int mtk_foe_entry_set_queue(struct mtk_eth *eth, struct mtk_foe_entry *entry, - unsigned int queue); - int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); - void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); --int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); - int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index); --struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index, -- struct mtk_foe_accounting *diff); -+void mtk_foe_entry_get_stats(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, -+ int *idle); - - #endif -diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c -index 570ebf91f693..9259d0925b88 100644 ---- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c -@@ -97,7 +97,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file *m, void *private, bool bind) - if (bind && state != MTK_FOE_STATE_BIND) - continue; - -- acct = mtk_foe_entry_get_mib(ppe, i, NULL); -+ acct = mtk_ppe_mib_entry_read(ppe, i); - - type = mtk_get_ib1_pkt_type(ppe->eth, entry->ib1); - seq_printf(m, "%05x %s %7s", i, -diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -index e9bd32741983..af8e0107fb93 100644 ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -522,24 +522,21 @@ static int - mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f) - { - struct mtk_flow_entry *entry; -- struct mtk_foe_accounting diff; -- u32 idle; -+ u64 packets, bytes; -+ int idle; - - entry = rhashtable_lookup(ð->flow_table, &f->cookie, - mtk_flow_ht_params); - if (!entry) - return -ENOENT; - -- idle = mtk_foe_entry_idle_time(eth->ppe[entry->ppe_index], entry); -+ packets = entry->packets; -+ bytes = entry->bytes; -+ mtk_foe_entry_get_stats(eth->ppe[entry->ppe_index], entry, &idle); -+ f->stats.pkts += entry->packets - packets; -+ f->stats.bytes += entry->bytes - bytes; - f->stats.lastused = jiffies - idle * HZ; - -- if (entry->hash != 0xFFFF && -- mtk_foe_entry_get_mib(eth->ppe[entry->ppe_index], entry->hash, -- &diff)) { -- f->stats.pkts += diff.packets; -- f->stats.bytes += diff.bytes; -- } -- - return 0; - } - --- -2.51.0 - - -From 6ece59fe862195dec63a973bd2a6099bee78859d Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 12 Sep 2025 14:18:14 +0200 -Subject: [PATCH 299/517] net: ethernet: mtk_eth_soc: zero initialize PPE flow - table - -Avoid picking up flows from last boot or other invalid data - -Signed-off-by: Felix Fietkau ---- - drivers/net/ethernet/mediatek/mtk_ppe.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c -index 96365a75b198..cb08d132bad9 100644 ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -914,6 +914,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index) - if (!foe) - goto err_free_l2_flows; - -+ memset(foe, 0, MTK_PPE_ENTRIES * soc->foe_entry_size); - ppe->foe_table = foe; - - foe_flow_size = (MTK_PPE_ENTRIES / soc->hash_offset) * -@@ -928,6 +929,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index) - if (!mib) - return NULL; - -+ memset(mib, 0, MTK_PPE_ENTRIES * sizeof(*mib)); - ppe->mib_table = mib; - - acct = devm_kzalloc(dev, MTK_PPE_ENTRIES * sizeof(*acct), --- -2.51.0 - - -From a6edd3042d35a2553e33b9d880226c6187bc6579 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 12 Dec 2023 03:51:14 +0000 -Subject: [PATCH 300/517] net: ethernet: mtk_eth_soc: add paths and SerDes - modes for MT7988 - -MT7988 comes with a built-in 2.5G PHY as well as SerDes lanes to -connect external PHYs or transceivers in USXGMII, 10GBase-R, 5GBase-R, -2500Base-X, 1000Base-X and Cisco SGMII interface modes. - -Implement support for configuring for the new paths to SerDes interfaces -and the internal 2.5G PHY. - -Add USXGMII PCS driver for 10GBase-R, 5GBase-R and USXGMII mode, and -setup the new PHYA on MT7988 to access the also still existing old -LynxI PCS for 1000Base-X, 2500Base-X and Cisco SGMII PCS interface -modes. - -Signed-off-by: Daniel Golle ---- - drivers/net/ethernet/mediatek/mtk_eth_path.c | 122 +++++++- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 288 +++++++++++++++++-- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 93 +++++- - 3 files changed, 470 insertions(+), 33 deletions(-) - -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_path.c b/drivers/net/ethernet/mediatek/mtk_eth_path.c -index 7c27a19c4d8f..3f4f4cfe6a23 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_path.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c -@@ -31,10 +31,20 @@ static const char *mtk_eth_path_name(u64 path) - return "gmac2_rgmii"; - case MTK_ETH_PATH_GMAC2_SGMII: - return "gmac2_sgmii"; -+ case MTK_ETH_PATH_GMAC2_2P5GPHY: -+ return "gmac2_2p5gphy"; - case MTK_ETH_PATH_GMAC2_GEPHY: - return "gmac2_gephy"; -+ case MTK_ETH_PATH_GMAC3_SGMII: -+ return "gmac3_sgmii"; - case MTK_ETH_PATH_GDM1_ESW: - return "gdm1_esw"; -+ case MTK_ETH_PATH_GMAC1_USXGMII: -+ return "gmac1_usxgmii"; -+ case MTK_ETH_PATH_GMAC2_USXGMII: -+ return "gmac2_usxgmii"; -+ case MTK_ETH_PATH_GMAC3_USXGMII: -+ return "gmac3_usxgmii"; - default: - return "unknown path"; - } -@@ -127,6 +137,27 @@ static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, u64 path) - return 0; - } - -+static int set_mux_gmac2_to_2p5gphy(struct mtk_eth *eth, u64 path) -+{ -+ int ret; -+ -+ if (path == MTK_ETH_PATH_GMAC2_2P5GPHY) { -+ ret = regmap_clear_bits(eth->ethsys, ETHSYS_SYSCFG0, SYSCFG0_SGMII_GMAC2_V2); -+ if (ret) -+ return ret; -+ -+ /* Setup mux to 2p5g PHY */ -+ ret = regmap_clear_bits(eth->infra, TOP_MISC_NETSYS_PCS_MUX, MUX_G2_USXGMII_SEL); -+ if (ret) -+ return ret; -+ -+ dev_dbg(eth->dev, "path %s in %s updated\n", -+ mtk_eth_path_name(path), __func__); -+ } -+ -+ return 0; -+} -+ - static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path) - { - unsigned int val = 0; -@@ -165,7 +196,48 @@ static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path) - return 0; - } - --static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path) -+static int set_mux_gmac123_to_usxgmii(struct mtk_eth *eth, u64 path) -+{ -+ unsigned int val = 0; -+ bool updated = true; -+ int mac_id = 0; -+ -+ /* Disable SYSCFG1 SGMII */ -+ regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val); -+ -+ switch (path) { -+ case MTK_ETH_PATH_GMAC1_USXGMII: -+ val &= ~(u32)SYSCFG0_SGMII_GMAC1_V2; -+ mac_id = MTK_GMAC1_ID; -+ break; -+ case MTK_ETH_PATH_GMAC2_USXGMII: -+ val &= ~(u32)SYSCFG0_SGMII_GMAC2_V2; -+ mac_id = MTK_GMAC2_ID; -+ break; -+ case MTK_ETH_PATH_GMAC3_USXGMII: -+ val &= ~(u32)SYSCFG0_SGMII_GMAC3_V2; -+ mac_id = MTK_GMAC3_ID; -+ break; -+ default: -+ updated = false; -+ }; -+ -+ if (updated) { -+ regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0, -+ SYSCFG0_SGMII_MASK, val); -+ -+ if (mac_id == MTK_GMAC2_ID) -+ regmap_set_bits(eth->infra, TOP_MISC_NETSYS_PCS_MUX, -+ MUX_G2_USXGMII_SEL); -+ } -+ -+ dev_dbg(eth->dev, "path %s in %s updated = %d\n", -+ mtk_eth_path_name(path), __func__, updated); -+ -+ return 0; -+} -+ -+static int set_mux_gmac123_to_gephy_sgmii(struct mtk_eth *eth, u64 path) - { - unsigned int val = 0; - bool updated = true; -@@ -182,6 +254,9 @@ static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path) - case MTK_ETH_PATH_GMAC2_SGMII: - val |= SYSCFG0_SGMII_GMAC2_V2; - break; -+ case MTK_ETH_PATH_GMAC3_SGMII: -+ val |= SYSCFG0_SGMII_GMAC3_V2; -+ break; - default: - updated = false; - } -@@ -209,6 +284,10 @@ static const struct mtk_eth_muxc mtk_eth_muxc[] = { - .name = "mux_u3_gmac2_to_qphy", - .cap_bit = MTK_ETH_MUX_U3_GMAC2_TO_QPHY, - .set_path = set_mux_u3_gmac2_to_qphy, -+ }, { -+ .name = "mux_gmac2_to_2p5gphy", -+ .cap_bit = MTK_ETH_MUX_GMAC2_TO_2P5GPHY, -+ .set_path = set_mux_gmac2_to_2p5gphy, - }, { - .name = "mux_gmac1_gmac2_to_sgmii_rgmii", - .cap_bit = MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII, -@@ -216,7 +295,15 @@ static const struct mtk_eth_muxc mtk_eth_muxc[] = { - }, { - .name = "mux_gmac12_to_gephy_sgmii", - .cap_bit = MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII, -- .set_path = set_mux_gmac12_to_gephy_sgmii, -+ .set_path = set_mux_gmac123_to_gephy_sgmii, -+ }, { -+ .name = "mux_gmac123_to_gephy_sgmii", -+ .cap_bit = MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII, -+ .set_path = set_mux_gmac123_to_gephy_sgmii, -+ }, { -+ .name = "mux_gmac123_to_usxgmii", -+ .cap_bit = MTK_ETH_MUX_GMAC123_TO_USXGMII, -+ .set_path = set_mux_gmac123_to_usxgmii, - }, - }; - -@@ -249,12 +336,39 @@ static int mtk_eth_mux_setup(struct mtk_eth *eth, u64 path) - return err; - } - -+int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id) -+{ -+ u64 path; -+ -+ path = (mac_id == MTK_GMAC1_ID) ? MTK_ETH_PATH_GMAC1_USXGMII : -+ (mac_id == MTK_GMAC2_ID) ? MTK_ETH_PATH_GMAC2_USXGMII : -+ MTK_ETH_PATH_GMAC3_USXGMII; -+ -+ /* Setup proper MUXes along the path */ -+ return mtk_eth_mux_setup(eth, path); -+} -+ - int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id) - { - u64 path; - -- path = (mac_id == 0) ? MTK_ETH_PATH_GMAC1_SGMII : -- MTK_ETH_PATH_GMAC2_SGMII; -+ path = (mac_id == MTK_GMAC1_ID) ? MTK_ETH_PATH_GMAC1_SGMII : -+ (mac_id == MTK_GMAC2_ID) ? MTK_ETH_PATH_GMAC2_SGMII : -+ MTK_ETH_PATH_GMAC3_SGMII; -+ -+ /* Setup proper MUXes along the path */ -+ return mtk_eth_mux_setup(eth, path); -+} -+ -+int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id) -+{ -+ u64 path = 0; -+ -+ if (mac_id == MTK_GMAC2_ID) -+ path = MTK_ETH_PATH_GMAC2_2P5GPHY; -+ -+ if (!path) -+ return -EINVAL; - - /* Setup proper MUXes along the path */ - return mtk_eth_mux_setup(eth, path); -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -index ba9b3d6be8b2..2883f53c016a 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -24,6 +24,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - #include -@@ -522,6 +524,30 @@ static void mtk_setup_bridge_switch(struct mtk_eth *eth) - MTK_GSW_CFG); - } - -+static bool mtk_check_gmac23_idle(struct mtk_mac *mac) -+{ -+ u32 mac_fsm, gdm_fsm; -+ -+ mac_fsm = mtk_r32(mac->hw, MTK_MAC_FSM(mac->id)); -+ -+ switch (mac->id) { -+ case MTK_GMAC2_ID: -+ gdm_fsm = mtk_r32(mac->hw, MTK_FE_GDM2_FSM); -+ break; -+ case MTK_GMAC3_ID: -+ gdm_fsm = mtk_r32(mac->hw, MTK_FE_GDM3_FSM); -+ break; -+ default: -+ return true; -+ }; -+ -+ if ((mac_fsm & 0xFFFF0000) == 0x01010000 && -+ (gdm_fsm & 0xFFFF0000) == 0x00000000) -+ return true; -+ -+ return false; -+} -+ - static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config, - phy_interface_t interface) - { -@@ -530,6 +556,21 @@ static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config, - struct mtk_eth *eth = mac->hw; - unsigned int sid; - -+ if (mtk_is_netsys_v3_or_greater(eth)) { -+ switch (interface) { -+ case PHY_INTERFACE_MODE_1000BASEX: -+ case PHY_INTERFACE_MODE_2500BASEX: -+ case PHY_INTERFACE_MODE_SGMII: -+ return mac->sgmii_pcs; -+ case PHY_INTERFACE_MODE_5GBASER: -+ case PHY_INTERFACE_MODE_10GBASER: -+ case PHY_INTERFACE_MODE_USXGMII: -+ return mac->usxgmii_pcs; -+ default: -+ return NULL; -+ } -+ } -+ - if (interface == PHY_INTERFACE_MODE_SGMII || - phy_interface_mode_is_8023z(interface)) { - sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ? -@@ -581,7 +622,22 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode, - goto init_err; - } - break; -+ case PHY_INTERFACE_MODE_USXGMII: -+ case PHY_INTERFACE_MODE_10GBASER: -+ case PHY_INTERFACE_MODE_5GBASER: -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) { -+ err = mtk_gmac_usxgmii_path_setup(eth, mac->id); -+ if (err) -+ goto init_err; -+ } -+ break; - case PHY_INTERFACE_MODE_INTERNAL: -+ if (mac->id == MTK_GMAC2_ID && -+ MTK_HAS_CAPS(eth->soc->caps, MTK_2P5GPHY)) { -+ err = mtk_gmac_2p5gphy_path_setup(eth, mac->id); -+ if (err) -+ goto init_err; -+ } - break; - default: - goto err_phy; -@@ -628,8 +684,6 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode, - val &= ~SYSCFG0_GE_MODE(SYSCFG0_GE_MASK, mac->id); - val |= SYSCFG0_GE_MODE(ge_mode, mac->id); - regmap_write(eth->ethsys, ETHSYS_SYSCFG0, val); -- -- mac->interface = state->interface; - } - - /* SGMII */ -@@ -646,21 +700,40 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode, - - /* Save the syscfg0 value for mac_finish */ - mac->syscfg0 = val; -- } else if (phylink_autoneg_inband(mode)) { -+ } else if (state->interface != PHY_INTERFACE_MODE_USXGMII && -+ state->interface != PHY_INTERFACE_MODE_10GBASER && -+ state->interface != PHY_INTERFACE_MODE_5GBASER && -+ phylink_autoneg_inband(mode)) { - dev_err(eth->dev, -- "In-band mode not supported in non SGMII mode!\n"); -+ "In-band mode not supported in non-SerDes modes!\n"); - return; - } - - /* Setup gmac */ -- if (mtk_is_netsys_v3_or_greater(eth) && -- mac->interface == PHY_INTERFACE_MODE_INTERNAL) { -- mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id)); -- mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id)); -+ if (mtk_is_netsys_v3_or_greater(eth)) { -+ if (mtk_interface_mode_is_xgmii(state->interface)) { -+ mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id)); -+ mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id)); - -- mtk_setup_bridge_switch(eth); -+ if (mac->id == MTK_GMAC1_ID) -+ mtk_setup_bridge_switch(eth); -+ } else { -+ mtk_w32(eth, 0, MTK_GDMA_EG_CTRL(mac->id)); -+ -+ /* FIXME: In current hardware design, we have to reset FE -+ * when swtiching XGDM to GDM. Therefore, here trigger an SER -+ * to let GDM go back to the initial state. -+ */ -+ if ((mtk_interface_mode_is_xgmii(mac->interface) || -+ mac->interface == PHY_INTERFACE_MODE_NA) && -+ !mtk_check_gmac23_idle(mac) && -+ !test_bit(MTK_RESETTING, ð->state)) -+ schedule_work(ð->pending_work); -+ } - } - -+ mac->interface = state->interface; -+ - return; - - err_phy: -@@ -673,6 +746,18 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode, - mac->id, phy_modes(state->interface), err); - } - -+static int mtk_mac_prepare(struct phylink_config *config, unsigned int mode, -+ phy_interface_t interface) -+{ -+ struct mtk_mac *mac = container_of(config, struct mtk_mac, -+ phylink_config); -+ -+ if (mac->pextp && mac->interface != interface) -+ phy_reset(mac->pextp); -+ -+ return 0; -+} -+ - static int mtk_mac_finish(struct phylink_config *config, unsigned int mode, - phy_interface_t interface) - { -@@ -681,6 +766,10 @@ static int mtk_mac_finish(struct phylink_config *config, unsigned int mode, - struct mtk_eth *eth = mac->hw; - u32 mcr_cur, mcr_new; - -+ /* Setup PMA/PMD */ -+ if (mac->pextp) -+ phy_set_mode_ext(mac->pextp, PHY_MODE_ETHERNET, interface); -+ - /* Enable SGMII */ - if (interface == PHY_INTERFACE_MODE_SGMII || - phy_interface_mode_is_8023z(interface)) -@@ -705,10 +794,14 @@ static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode, - { - struct mtk_mac *mac = container_of(config, struct mtk_mac, - phylink_config); -- u32 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); - -- mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK); -- mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); -+ if (!mtk_interface_mode_is_xgmii(interface)) { -+ mtk_m32(mac->hw, MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK, 0, MTK_MAC_MCR(mac->id)); -+ if (mtk_is_netsys_v3_or_greater(mac->hw)) -+ mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), 0, MTK_XGMAC_STS(mac->id)); -+ } else if (mtk_is_netsys_v3_or_greater(mac->hw) && mac->id != MTK_GMAC1_ID) { -+ mtk_m32(mac->hw, XMAC_MCR_TRX_DISABLE, XMAC_MCR_TRX_DISABLE, MTK_XMAC_MCR(mac->id)); -+ } - } - - static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx, -@@ -780,13 +873,11 @@ static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx, - mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs); - } - --static void mtk_mac_link_up(struct phylink_config *config, -- struct phy_device *phy, -- unsigned int mode, phy_interface_t interface, -- int speed, int duplex, bool tx_pause, bool rx_pause) -+static void mtk_gdm_mac_link_up(struct mtk_mac *mac, -+ struct phy_device *phy, -+ unsigned int mode, phy_interface_t interface, -+ int speed, int duplex, bool tx_pause, bool rx_pause) - { -- struct mtk_mac *mac = container_of(config, struct mtk_mac, -- phylink_config); - u32 mcr; - - mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); -@@ -830,9 +921,63 @@ static void mtk_mac_link_up(struct phylink_config *config, - mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); - } - -+static void mtk_xgdm_mac_link_up(struct mtk_mac *mac, -+ struct phy_device *phy, -+ unsigned int mode, phy_interface_t interface, -+ int speed, int duplex, bool tx_pause, bool rx_pause) -+{ -+ u32 mcr, force_link = 0; -+ -+ if (mac->id == MTK_GMAC1_ID) -+ return; -+ -+ /* Eliminate the interference(before link-up) caused by PHY noise */ -+ mtk_m32(mac->hw, XMAC_LOGIC_RST, 0, MTK_XMAC_LOGIC_RST(mac->id)); -+ mdelay(20); -+ mtk_m32(mac->hw, XMAC_GLB_CNTCLR, XMAC_GLB_CNTCLR, MTK_XMAC_CNT_CTRL(mac->id)); -+ -+ if (mac->interface == PHY_INTERFACE_MODE_INTERNAL || mac->id == MTK_GMAC3_ID) -+ force_link = MTK_XGMAC_FORCE_LINK(mac->id); -+ -+ mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), force_link, MTK_XGMAC_STS(mac->id)); -+ -+ mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id)); -+ mcr &= ~(XMAC_MCR_FORCE_TX_FC | XMAC_MCR_FORCE_RX_FC | XMAC_MCR_TRX_DISABLE); -+ /* Configure pause modes - -+ * phylink will avoid these for half duplex -+ */ -+ if (tx_pause) -+ mcr |= XMAC_MCR_FORCE_TX_FC; -+ if (rx_pause) -+ mcr |= XMAC_MCR_FORCE_RX_FC; -+ -+ mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id)); -+} -+ -+static void mtk_mac_link_up(struct phylink_config *config, -+ struct phy_device *phy, -+ unsigned int mode, phy_interface_t interface, -+ int speed, int duplex, bool tx_pause, bool rx_pause) -+{ -+ struct mtk_mac *mac = container_of(config, struct mtk_mac, -+ phylink_config); -+ -+ if (mtk_is_netsys_v3_or_greater(mac->hw) && mtk_interface_mode_is_xgmii(interface)) -+ mtk_xgdm_mac_link_up(mac, phy, mode, interface, speed, duplex, -+ tx_pause, rx_pause); -+ else -+ mtk_gdm_mac_link_up(mac, phy, mode, interface, speed, duplex, -+ tx_pause, rx_pause); -+ -+ /* Repeat pextp setup to tune link */ -+ if (mac->pextp) -+ phy_set_mode_ext(mac->pextp, PHY_MODE_ETHERNET, interface); -+} -+ - static const struct phylink_mac_ops mtk_phylink_ops = { - .mac_select_pcs = mtk_mac_select_pcs, - .mac_config = mtk_mac_config, -+ .mac_prepare = mtk_mac_prepare, - .mac_finish = mtk_mac_finish, - .mac_link_down = mtk_mac_link_down, - .mac_link_up = mtk_mac_link_up, -@@ -3584,6 +3729,9 @@ static int mtk_open(struct net_device *dev) - - ppe_num = eth->soc->ppe_num; - -+ if (mac->pextp) -+ phy_power_on(mac->pextp); -+ - err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0); - if (err) { - netdev_err(dev, "%s: could not attach PHY: %d\n", __func__, -@@ -3731,6 +3879,9 @@ static int mtk_stop(struct net_device *dev) - for (i = 0; i < ARRAY_SIZE(eth->ppe); i++) - mtk_ppe_stop(eth->ppe[i]); - -+ if (mac->pextp) -+ phy_power_off(mac->pextp); -+ - return 0; - } - -@@ -4821,6 +4972,7 @@ static const struct net_device_ops mtk_netdev_ops = { - static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) - { - const __be32 *_id = of_get_property(np, "reg", NULL); -+ struct device_node *pcs_np; - phy_interface_t phy_mode; - struct phylink *phylink; - struct mtk_mac *mac; -@@ -4859,16 +5011,41 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) - mac->id = id; - mac->hw = eth; - mac->of_node = np; -+ pcs_np = of_parse_phandle(mac->of_node, "pcs-handle", 0); -+ if (pcs_np) { -+ mac->sgmii_pcs = mtk_pcs_lynxi_get(eth->dev, pcs_np); -+ if (IS_ERR(mac->sgmii_pcs)) { -+ if (PTR_ERR(mac->sgmii_pcs) == -EPROBE_DEFER) -+ return -EPROBE_DEFER; -+ -+ dev_err(eth->dev, "cannot select SGMII PCS, error %ld\n", -+ PTR_ERR(mac->sgmii_pcs)); -+ return PTR_ERR(mac->sgmii_pcs); -+ } -+ } - -- err = of_get_ethdev_address(mac->of_node, eth->netdev[id]); -- if (err == -EPROBE_DEFER) -- return err; -+ pcs_np = of_parse_phandle(mac->of_node, "pcs-handle", 1); -+ if (pcs_np) { -+ mac->usxgmii_pcs = mtk_usxgmii_pcs_get(eth->dev, pcs_np); -+ if (IS_ERR(mac->usxgmii_pcs)) { -+ if (PTR_ERR(mac->usxgmii_pcs) == -EPROBE_DEFER) -+ return -EPROBE_DEFER; - -- if (err) { -- /* If the mac address is invalid, use random mac address */ -- eth_hw_addr_random(eth->netdev[id]); -- dev_err(eth->dev, "generated random MAC address %pM\n", -- eth->netdev[id]->dev_addr); -+ dev_err(eth->dev, "cannot select USXGMII PCS, error %ld\n", -+ PTR_ERR(mac->usxgmii_pcs)); -+ return PTR_ERR(mac->usxgmii_pcs); -+ } -+ } -+ -+ if (mtk_is_netsys_v3_or_greater(eth) && (mac->sgmii_pcs || mac->usxgmii_pcs)) { -+ mac->pextp = devm_of_phy_get(eth->dev, mac->of_node, NULL); -+ if (IS_ERR(mac->pextp)) { -+ if (PTR_ERR(mac->pextp) != -EPROBE_DEFER) -+ dev_err(eth->dev, "cannot get PHY, error %ld\n", -+ PTR_ERR(mac->pextp)); -+ -+ return PTR_ERR(mac->pextp); -+ } - } - - memset(mac->hwlro_ip, 0, sizeof(mac->hwlro_ip)); -@@ -4951,8 +5128,21 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) - phy_interface_zero(mac->phylink_config.supported_interfaces); - __set_bit(PHY_INTERFACE_MODE_INTERNAL, - mac->phylink_config.supported_interfaces); -+ } else if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_USXGMII)) { -+ mac->phylink_config.mac_capabilities |= MAC_5000FD | MAC_10000FD; -+ __set_bit(PHY_INTERFACE_MODE_5GBASER, -+ mac->phylink_config.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_10GBASER, -+ mac->phylink_config.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_USXGMII, -+ mac->phylink_config.supported_interfaces); - } - -+ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_2P5GPHY) && -+ id == MTK_GMAC2_ID) -+ __set_bit(PHY_INTERFACE_MODE_INTERNAL, -+ mac->phylink_config.supported_interfaces); -+ - phylink = phylink_create(&mac->phylink_config, - of_fwnode_handle(mac->of_node), - phy_mode, &mtk_phylink_ops); -@@ -5003,6 +5193,26 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) - return err; - } - -+static int mtk_mac_assign_address(struct mtk_eth *eth, int i, bool test_defer_only) -+{ -+ int err = of_get_ethdev_address(eth->mac[i]->of_node, eth->netdev[i]); -+ -+ if (err == -EPROBE_DEFER) -+ return err; -+ -+ if (test_defer_only) -+ return 0; -+ -+ if (err) { -+ /* If the mac address is invalid, use random mac address */ -+ eth_hw_addr_random(eth->netdev[i]); -+ dev_err(eth->dev, "generated random MAC address %pM\n", -+ eth->netdev[i]); -+ } -+ -+ return 0; -+} -+ - void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev) - { - struct net_device *dev, *tmp; -@@ -5149,7 +5359,8 @@ static int mtk_probe(struct platform_device *pdev) - regmap_write(cci, 0, 3); - } - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) { -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII) && -+ !mtk_is_netsys_v3_or_greater(eth)) { - err = mtk_sgmii_init(eth); - - if (err) -@@ -5260,6 +5471,24 @@ static int mtk_probe(struct platform_device *pdev) - } - } - -+ for (i = 0; i < MTK_MAX_DEVS; i++) { -+ if (!eth->netdev[i]) -+ continue; -+ -+ err = mtk_mac_assign_address(eth, i, true); -+ if (err) -+ goto err_deinit_hw; -+ } -+ -+ for (i = 0; i < MTK_MAX_DEVS; i++) { -+ if (!eth->netdev[i]) -+ continue; -+ -+ err = mtk_mac_assign_address(eth, i, false); -+ if (err) -+ goto err_deinit_hw; -+ } -+ - if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT)) { - err = devm_request_irq(eth->dev, eth->irq[0], - mtk_handle_irq, 0, -@@ -5370,6 +5599,11 @@ static void mtk_remove(struct platform_device *pdev) - mtk_stop(eth->netdev[i]); - mac = netdev_priv(eth->netdev[i]); - phylink_disconnect_phy(mac->phylink); -+ if (mac->sgmii_pcs) -+ mtk_pcs_lynxi_put(mac->sgmii_pcs); -+ -+ if (mac->usxgmii_pcs) -+ mtk_usxgmii_pcs_put(mac->usxgmii_pcs); - } - - mtk_wed_exit(); -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -index 88dee7983642..c7ad88351a1b 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -527,6 +528,21 @@ - #define INTF_MODE_RGMII_1000 (TRGMII_MODE | TRGMII_CENTRAL_ALIGNED) - #define INTF_MODE_RGMII_10_100 0 - -+/* XFI Mac control registers */ -+#define MTK_XMAC_BASE(x) (0x12000 + (((x) - 1) * 0x1000)) -+#define MTK_XMAC_MCR(x) (MTK_XMAC_BASE(x)) -+#define XMAC_MCR_TRX_DISABLE 0xf -+#define XMAC_MCR_FORCE_TX_FC BIT(5) -+#define XMAC_MCR_FORCE_RX_FC BIT(4) -+ -+/* XFI Mac logic reset registers */ -+#define MTK_XMAC_LOGIC_RST(x) (MTK_XMAC_BASE(x) + 0x10) -+#define XMAC_LOGIC_RST BIT(0) -+ -+/* XFI Mac count global control */ -+#define MTK_XMAC_CNT_CTRL(x) (MTK_XMAC_BASE(x) + 0x100) -+#define XMAC_GLB_CNTCLR BIT(0) -+ - /* GPIO port control registers for GMAC 2*/ - #define GPIO_OD33_CTRL8 0x4c0 - #define GPIO_BIAS_CTRL 0xed0 -@@ -552,6 +568,7 @@ - #define SYSCFG0_SGMII_GMAC2 ((3 << 8) & SYSCFG0_SGMII_MASK) - #define SYSCFG0_SGMII_GMAC1_V2 BIT(9) - #define SYSCFG0_SGMII_GMAC2_V2 BIT(8) -+#define SYSCFG0_SGMII_GMAC3_V2 BIT(7) - - - /* ethernet subsystem clock register */ -@@ -590,6 +607,11 @@ - #define GEPHY_MAC_SEL BIT(1) - - /* Top misc registers */ -+#define TOP_MISC_NETSYS_PCS_MUX 0x0 -+#define NETSYS_PCS_MUX_MASK GENMASK(1, 0) -+#define MUX_G2_USXGMII_SEL BIT(1) -+#define MUX_HSGMII1_G1_SEL BIT(0) -+ - #define USB_PHY_SWITCH_REG 0x218 - #define QPHY_SEL_MASK GENMASK(1, 0) - #define SGMII_QPHY_SEL 0x2 -@@ -614,6 +636,8 @@ - #define MT7628_SDM_RBCNT (MT7628_SDM_OFFSET + 0x10c) - #define MT7628_SDM_CS_ERR (MT7628_SDM_OFFSET + 0x110) - -+/* Debug Purpose Register */ -+#define MTK_PSE_FQFC_CFG 0x100 - #define MTK_FE_CDM1_FSM 0x220 - #define MTK_FE_CDM2_FSM 0x224 - #define MTK_FE_CDM3_FSM 0x238 -@@ -622,6 +646,11 @@ - #define MTK_FE_CDM6_FSM 0x328 - #define MTK_FE_GDM1_FSM 0x228 - #define MTK_FE_GDM2_FSM 0x22C -+#define MTK_FE_GDM3_FSM 0x23C -+#define MTK_FE_PSE_FREE 0x240 -+#define MTK_FE_DROP_FQ 0x244 -+#define MTK_FE_DROP_FC 0x248 -+#define MTK_FE_DROP_PPE 0x24C - - #define MTK_MAC_FSM(x) (0x1010C + ((x) * 0x100)) - -@@ -945,6 +974,8 @@ enum mkt_eth_capabilities { - MTK_RGMII_BIT = 0, - MTK_TRGMII_BIT, - MTK_SGMII_BIT, -+ MTK_USXGMII_BIT, -+ MTK_2P5GPHY_BIT, - MTK_ESW_BIT, - MTK_GEPHY_BIT, - MTK_MUX_BIT, -@@ -965,8 +996,11 @@ enum mkt_eth_capabilities { - MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT, - MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT, - MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT, -+ MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT, - MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT, - MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT, -+ MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT, -+ MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT, - - /* PATH BITS */ - MTK_ETH_PATH_GMAC1_RGMII_BIT, -@@ -974,14 +1008,21 @@ enum mkt_eth_capabilities { - MTK_ETH_PATH_GMAC1_SGMII_BIT, - MTK_ETH_PATH_GMAC2_RGMII_BIT, - MTK_ETH_PATH_GMAC2_SGMII_BIT, -+ MTK_ETH_PATH_GMAC2_2P5GPHY_BIT, - MTK_ETH_PATH_GMAC2_GEPHY_BIT, -+ MTK_ETH_PATH_GMAC3_SGMII_BIT, - MTK_ETH_PATH_GDM1_ESW_BIT, -+ MTK_ETH_PATH_GMAC1_USXGMII_BIT, -+ MTK_ETH_PATH_GMAC2_USXGMII_BIT, -+ MTK_ETH_PATH_GMAC3_USXGMII_BIT, - }; - - /* Supported hardware group on SoCs */ - #define MTK_RGMII BIT_ULL(MTK_RGMII_BIT) - #define MTK_TRGMII BIT_ULL(MTK_TRGMII_BIT) - #define MTK_SGMII BIT_ULL(MTK_SGMII_BIT) -+#define MTK_USXGMII BIT_ULL(MTK_USXGMII_BIT) -+#define MTK_2P5GPHY BIT_ULL(MTK_2P5GPHY_BIT) - #define MTK_ESW BIT_ULL(MTK_ESW_BIT) - #define MTK_GEPHY BIT_ULL(MTK_GEPHY_BIT) - #define MTK_MUX BIT_ULL(MTK_MUX_BIT) -@@ -1004,10 +1045,16 @@ enum mkt_eth_capabilities { - BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT) - #define MTK_ETH_MUX_U3_GMAC2_TO_QPHY \ - BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT) -+#define MTK_ETH_MUX_GMAC2_TO_2P5GPHY \ -+ BIT_ULL(MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT) - #define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII \ - BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT) - #define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII \ - BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT) -+#define MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII \ -+ BIT_ULL(MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT) -+#define MTK_ETH_MUX_GMAC123_TO_USXGMII \ -+ BIT_ULL(MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT) - - /* Supported path present on SoCs */ - #define MTK_ETH_PATH_GMAC1_RGMII BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT) -@@ -1015,8 +1062,13 @@ enum mkt_eth_capabilities { - #define MTK_ETH_PATH_GMAC1_SGMII BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT) - #define MTK_ETH_PATH_GMAC2_RGMII BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT) - #define MTK_ETH_PATH_GMAC2_SGMII BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT) -+#define MTK_ETH_PATH_GMAC2_2P5GPHY BIT_ULL(MTK_ETH_PATH_GMAC2_2P5GPHY_BIT) - #define MTK_ETH_PATH_GMAC2_GEPHY BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT) -+#define MTK_ETH_PATH_GMAC3_SGMII BIT_ULL(MTK_ETH_PATH_GMAC3_SGMII_BIT) - #define MTK_ETH_PATH_GDM1_ESW BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT) -+#define MTK_ETH_PATH_GMAC1_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC1_USXGMII_BIT) -+#define MTK_ETH_PATH_GMAC2_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC2_USXGMII_BIT) -+#define MTK_ETH_PATH_GMAC3_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC3_USXGMII_BIT) - - #define MTK_GMAC1_RGMII (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII) - #define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII) -@@ -1024,7 +1076,12 @@ enum mkt_eth_capabilities { - #define MTK_GMAC2_RGMII (MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII) - #define MTK_GMAC2_SGMII (MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII) - #define MTK_GMAC2_GEPHY (MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY) -+#define MTK_GMAC2_2P5GPHY (MTK_ETH_PATH_GMAC2_2P5GPHY | MTK_2P5GPHY) -+#define MTK_GMAC3_SGMII (MTK_ETH_PATH_GMAC3_SGMII | MTK_SGMII) - #define MTK_GDM1_ESW (MTK_ETH_PATH_GDM1_ESW | MTK_ESW) -+#define MTK_GMAC1_USXGMII (MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII) -+#define MTK_GMAC2_USXGMII (MTK_ETH_PATH_GMAC2_USXGMII | MTK_USXGMII) -+#define MTK_GMAC3_USXGMII (MTK_ETH_PATH_GMAC3_USXGMII | MTK_USXGMII) - - /* MUXes present on SoCs */ - /* 0: GDM1 -> GMAC1, 1: GDM1 -> ESW */ -@@ -1043,10 +1100,20 @@ enum mkt_eth_capabilities { - (MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_MUX | \ - MTK_SHARED_SGMII) - -+/* 2: GMAC2 -> XGMII */ -+#define MTK_MUX_GMAC2_TO_2P5GPHY \ -+ (MTK_ETH_MUX_GMAC2_TO_2P5GPHY | MTK_MUX | MTK_INFRA) -+ - /* 0: GMACx -> GEPHY, 1: GMACx -> SGMII where x is 1 or 2 */ - #define MTK_MUX_GMAC12_TO_GEPHY_SGMII \ - (MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX) - -+#define MTK_MUX_GMAC123_TO_GEPHY_SGMII \ -+ (MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII | MTK_MUX) -+ -+#define MTK_MUX_GMAC123_TO_USXGMII \ -+ (MTK_ETH_MUX_GMAC123_TO_USXGMII | MTK_MUX | MTK_INFRA) -+ - #define MTK_HAS_CAPS(caps, _x) (((caps) & (_x)) == (_x)) - - #define MT7621_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \ -@@ -1078,8 +1145,12 @@ enum mkt_eth_capabilities { - MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ - MTK_RSTCTRL_PPE1 | MTK_SRAM) - --#define MT7988_CAPS (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_QDMA | \ -- MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM) -+#define MT7988_CAPS (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_GMAC1_SGMII | \ -+ MTK_GMAC2_2P5GPHY | MTK_GMAC2_SGMII | MTK_GMAC2_USXGMII | \ -+ MTK_GMAC3_SGMII | MTK_GMAC3_USXGMII | \ -+ MTK_MUX_GMAC123_TO_GEPHY_SGMII | \ -+ MTK_MUX_GMAC123_TO_USXGMII | MTK_MUX_GMAC2_TO_2P5GPHY | \ -+ MTK_QDMA | MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM) - - struct mtk_tx_dma_desc_info { - dma_addr_t addr; -@@ -1327,6 +1398,9 @@ struct mtk_mac { - struct device_node *of_node; - struct phylink *phylink; - struct phylink_config phylink_config; -+ struct phylink_pcs *sgmii_pcs; -+ struct phylink_pcs *usxgmii_pcs; -+ struct phy *pextp; - struct mtk_eth *hw; - struct mtk_hw_stats *hw_stats; - __be32 hwlro_ip[MTK_MAX_LRO_IP_CNT]; -@@ -1450,6 +1524,19 @@ static inline u32 mtk_get_ib2_multicast_mask(struct mtk_eth *eth) - return MTK_FOE_IB2_MULTICAST; - } - -+static inline bool mtk_interface_mode_is_xgmii(phy_interface_t interface) -+{ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_INTERNAL: -+ case PHY_INTERFACE_MODE_USXGMII: -+ case PHY_INTERFACE_MODE_10GBASER: -+ case PHY_INTERFACE_MODE_5GBASER: -+ return true; -+ default: -+ return false; -+ } -+} -+ - /* read the hardware status register */ - void mtk_stats_update_mac(struct mtk_mac *mac); - -@@ -1458,8 +1545,10 @@ u32 mtk_r32(struct mtk_eth *eth, unsigned reg); - u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg); - - int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id); -+int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id); - int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id); - int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id); -+int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id); - - int mtk_eth_offload_init(struct mtk_eth *eth, u8 id); - int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type, --- -2.51.0 - - -From f45eeb706a8d64bfc50fd9b3b667530ff0625232 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Tue, 15 Oct 2024 13:09:37 +0200 -Subject: [PATCH 301/517] net: ethernet: mtk_eth_soc: reduce rx ring size for - older chipsets - -Commit c57e55819443 ("net: ethernet: mtk_eth_soc: handle dma buffer -size soc specific") resolved some tx timeout issues by bumping FQ and -tx ring sizes from 512 to 2048 entries (the value used in the MediaTek -SDK), however it also changed the rx ring size for all chipsets in the -same way. - -Based on a few tests, it seems that a symmetric rx/tx ring size of 2048 -really only makes sense on MT7988, which is capable of 10G ethernet links. - -Older chipsets are typically deployed in systems that are more memory -constrained and don't actually need the larger rings to handle received -packets. - -In order to reduce wasted memory set the ring size based on the SoC to -the following values: -- 2048 on MT7988 -- 1024 on MT7986 -- 512 (previous value) on everything else, except: -- 256 on RT5350 (the oldest supported chipset) - -Fixes: c57e55819443 ("net: ethernet: mtk_eth_soc: handle dma buffer size soc specific") -Signed-off-by: Felix Fietkau ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -index 2883f53c016a..18a31e6ed350 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -5637,7 +5637,7 @@ static const struct mtk_soc_data mt2701_data = { - DESC_SIZE(struct mtk_rx_dma), - .irq_done_mask = MTK_RX_DONE_INT, - .dma_l4_valid = RX_DMA_L4_VALID, -- .dma_size = MTK_DMA_SIZE(2K), -+ .dma_size = MTK_DMA_SIZE(512), - .dma_max_len = MTK_TX_DMA_BUF_LEN, - .dma_len_offset = 16, - }, -@@ -5665,7 +5665,7 @@ static const struct mtk_soc_data mt7621_data = { - DESC_SIZE(struct mtk_rx_dma), - .irq_done_mask = MTK_RX_DONE_INT, - .dma_l4_valid = RX_DMA_L4_VALID, -- .dma_size = MTK_DMA_SIZE(2K), -+ .dma_size = MTK_DMA_SIZE(512), - .dma_max_len = MTK_TX_DMA_BUF_LEN, - .dma_len_offset = 16, - }, -@@ -5695,7 +5695,7 @@ static const struct mtk_soc_data mt7622_data = { - DESC_SIZE(struct mtk_rx_dma), - .irq_done_mask = MTK_RX_DONE_INT, - .dma_l4_valid = RX_DMA_L4_VALID, -- .dma_size = MTK_DMA_SIZE(2K), -+ .dma_size = MTK_DMA_SIZE(512), - .dma_max_len = MTK_TX_DMA_BUF_LEN, - .dma_len_offset = 16, - }, -@@ -5724,7 +5724,7 @@ static const struct mtk_soc_data mt7623_data = { - DESC_SIZE(struct mtk_rx_dma), - .irq_done_mask = MTK_RX_DONE_INT, - .dma_l4_valid = RX_DMA_L4_VALID, -- .dma_size = MTK_DMA_SIZE(2K), -+ .dma_size = MTK_DMA_SIZE(512), - .dma_max_len = MTK_TX_DMA_BUF_LEN, - .dma_len_offset = 16, - }, -@@ -5750,7 +5750,7 @@ static const struct mtk_soc_data mt7629_data = { - DESC_SIZE(struct mtk_rx_dma), - .irq_done_mask = MTK_RX_DONE_INT, - .dma_l4_valid = RX_DMA_L4_VALID, -- .dma_size = MTK_DMA_SIZE(2K), -+ .dma_size = MTK_DMA_SIZE(512), - .dma_max_len = MTK_TX_DMA_BUF_LEN, - .dma_len_offset = 16, - }, -@@ -5782,7 +5782,7 @@ static const struct mtk_soc_data mt7981_data = { - .dma_l4_valid = RX_DMA_L4_VALID_V2, - .dma_max_len = MTK_TX_DMA_BUF_LEN, - .dma_len_offset = 16, -- .dma_size = MTK_DMA_SIZE(2K), -+ .dma_size = MTK_DMA_SIZE(512), - }, - }; - -@@ -5812,7 +5812,7 @@ static const struct mtk_soc_data mt7986_data = { - .dma_l4_valid = RX_DMA_L4_VALID_V2, - .dma_max_len = MTK_TX_DMA_BUF_LEN, - .dma_len_offset = 16, -- .dma_size = MTK_DMA_SIZE(2K), -+ .dma_size = MTK_DMA_SIZE(1K), - }, - }; - -@@ -5865,7 +5865,7 @@ static const struct mtk_soc_data rt5350_data = { - .dma_l4_valid = RX_DMA_L4_VALID_PDMA, - .dma_max_len = MTK_TX_DMA_BUF_LEN, - .dma_len_offset = 16, -- .dma_size = MTK_DMA_SIZE(2K), -+ .dma_size = MTK_DMA_SIZE(256), - }, - }; - --- -2.51.0 - - -From 7fa390446c8e232a3663e8ed59c0efbb9a3978f3 Mon Sep 17 00:00:00 2001 -From: Danila Romanov -Date: Wed, 22 Jan 2025 06:48:45 +0100 -Subject: [PATCH 302/517] net: ethernet: mtk_eth_soc: do not enable page pool - stats by default - -There is no reason for it to be enabled by default. -Align mtk_eth_soc driver to mt76 driver. - -This option incurs additional CPU cost in allocation and recycle paths -and additional memory cost to store the statistics. - -Signed-off-by: Danila Romanov -Signed-off-by: Felix Fietkau ---- - drivers/net/ethernet/mediatek/Kconfig | 1 - - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 ++ - 2 files changed, 2 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/ethernet/mediatek/Kconfig b/drivers/net/ethernet/mediatek/Kconfig -index 95c4405b7d7b..d97431682c3a 100644 ---- a/drivers/net/ethernet/mediatek/Kconfig -+++ b/drivers/net/ethernet/mediatek/Kconfig -@@ -26,7 +26,6 @@ config NET_MEDIATEK_SOC - select PHYLINK - select DIMLIB - select PAGE_POOL -- select PAGE_POOL_STATS - select PCS_MTK_LYNXI - select REGMAP_MMIO - help -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -index 18a31e6ed350..bc217da6ffc7 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4740,6 +4740,7 @@ static int mtk_get_sset_count(struct net_device *dev, int sset) - - static void mtk_ethtool_pp_stats(struct mtk_eth *eth, u64 *data) - { -+#ifdef CONFIG_PAGE_POOL_STATS - struct page_pool_stats stats = {}; - int i; - -@@ -4752,6 +4753,7 @@ static void mtk_ethtool_pp_stats(struct mtk_eth *eth, u64 *data) - page_pool_get_stats(ring->page_pool, &stats); - } - page_pool_ethtool_stats_get(data, &stats); -+#endif - } - - static void mtk_get_ethtool_stats(struct net_device *dev, --- -2.51.0 - - -From 9e1ea8c49deab1c1c5681faf44991ca8ad03de1c Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 1 Feb 2024 21:52:20 +0000 -Subject: [PATCH 303/517] dt-bindings: phy: mediatek,xfi-tphy: add new bindings - -Add bindings for the MediaTek XFI T-PHY Ethernet SerDes PHY found in the -MediaTek MT7988 SoC which can operate at various interfaces modes: - -via USXGMII PCS: - * USXGMII - * 10GBase-R - * 5GBase-R - -via LynxI SGMII PCS: - * 2500Base-X - * 1000Base-X - * Cisco SGMII (MAC side) - -Signed-off-by: Daniel Golle ---- - .../bindings/phy/mediatek,xfi-tphy.yaml | 80 +++++++++++++++++++ - 1 file changed, 80 insertions(+) - create mode 100644 Documentation/devicetree/bindings/phy/mediatek,xfi-tphy.yaml - -diff --git a/Documentation/devicetree/bindings/phy/mediatek,xfi-tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,xfi-tphy.yaml -new file mode 100644 -index 000000000000..e897118dcf7e ---- /dev/null -+++ b/Documentation/devicetree/bindings/phy/mediatek,xfi-tphy.yaml -@@ -0,0 +1,80 @@ -+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/phy/mediatek,xfi-tphy.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: MediaTek XFI T-PHY -+ -+maintainers: -+ - Daniel Golle -+ -+description: -+ The MediaTek XFI SerDes T-PHY provides the physical SerDes lanes -+ used by the (10G/5G) USXGMII PCS and (1G/2.5G) LynxI PCS found in -+ MediaTek's 10G-capabale SoCs. -+ -+properties: -+ $nodename: -+ pattern: "^phy@[0-9a-f]+$" -+ -+ compatible: -+ const: mediatek,mt7988-xfi-tphy -+ -+ reg: -+ maxItems: 1 -+ -+ clocks: -+ items: -+ - description: XFI PHY clock -+ - description: XFI register clock -+ -+ clock-names: -+ items: -+ - const: xfipll -+ - const: topxtal -+ -+ resets: -+ items: -+ - description: PEXTP reset -+ -+ mediatek,usxgmii-performance-errata: -+ $ref: /schemas/types.yaml#/definitions/flag -+ description: -+ One instance of the T-PHY on MT7988 suffers from a performance -+ problem in 10GBase-R mode which needs a work-around in the driver. -+ The work-around is enabled using this flag. -+ -+ "#phy-cells": -+ const: 0 -+ -+required: -+ - compatible -+ - reg -+ - clocks -+ - clock-names -+ - resets -+ - "#phy-cells" -+ -+additionalProperties: false -+ -+examples: -+ - | -+ #include -+ soc { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ -+ phy@11f20000 { -+ compatible = "mediatek,mt7988-xfi-tphy"; -+ reg = <0 0x11f20000 0 0x10000>; -+ clocks = <&xfi_pll CLK_XFIPLL_PLL_EN>, -+ <&topckgen CLK_TOP_XFI_PHY_0_XTAL_SEL>; -+ clock-names = "xfipll", "topxtal"; -+ resets = <&watchdog 14>; -+ mediatek,usxgmii-performance-errata; -+ #phy-cells = <0>; -+ }; -+ }; -+ -+... --- -2.51.0 - - -From 6521c70d317c1145ac508e6d30bf15238af9c73f Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 12 Dec 2023 03:47:18 +0000 -Subject: [PATCH 304/517] net: pcs: pcs-mtk-lynxi: add platform driver for - MT7988 - -Introduce a proper platform MFD driver for the LynxI (H)SGMII PCS which -is going to initially be used for the MT7988 SoC. - -Signed-off-by: Daniel Golle ---- - drivers/net/pcs/pcs-mtk-lynxi.c | 224 ++++++++++++++++++++++++++++-- - include/linux/pcs/pcs-mtk-lynxi.h | 11 ++ - 2 files changed, 224 insertions(+), 11 deletions(-) - -diff --git a/drivers/net/pcs/pcs-mtk-lynxi.c b/drivers/net/pcs/pcs-mtk-lynxi.c -index 7de804535229..9f32540bba9c 100644 ---- a/drivers/net/pcs/pcs-mtk-lynxi.c -+++ b/drivers/net/pcs/pcs-mtk-lynxi.c -@@ -1,6 +1,6 @@ - // SPDX-License-Identifier: GPL-2.0 - // Copyright (c) 2018-2019 MediaTek Inc. --/* A library for MediaTek SGMII circuit -+/* A library and platform driver for the MediaTek LynxI SGMII circuit - * - * Author: Sean Wang - * Author: Alexander Couzens -@@ -8,11 +8,17 @@ - * - */ - -+#include - #include -+#include -+#include - #include -+#include - #include - #include -+#include - #include -+#include - - /* SGMII subsystem config registers */ - /* BMCR (low 16) BMSR (high 16) */ -@@ -65,6 +71,8 @@ - #define SGMII_PN_SWAP_MASK GENMASK(1, 0) - #define SGMII_PN_SWAP_TX_RX (BIT(0) | BIT(1)) - -+#define MTK_NETSYS_V3_AMA_RGC3 0x128 -+ - /* struct mtk_pcs_lynxi - This structure holds each sgmii regmap andassociated - * data - * @regmap: The register map pointing at the range used to setup -@@ -74,15 +82,29 @@ - * @interface: Currently configured interface mode - * @pcs: Phylink PCS structure - * @flags: Flags indicating hardware properties -+ * @rstc: Reset controller -+ * @sgmii_sel: SGMII Register Clock -+ * @sgmii_rx: SGMII RX Clock -+ * @sgmii_tx: SGMII TX Clock -+ * @node: List node - */ - struct mtk_pcs_lynxi { - struct regmap *regmap; -+ struct device *dev; - u32 ana_rgc3; - phy_interface_t interface; - struct phylink_pcs pcs; - u32 flags; -+ struct reset_control *rstc; -+ struct clk *sgmii_sel; -+ struct clk *sgmii_rx; -+ struct clk *sgmii_tx; -+ struct list_head node; - }; - -+static LIST_HEAD(mtk_pcs_lynxi_instances); -+static DEFINE_MUTEX(instance_mutex); -+ - static struct mtk_pcs_lynxi *pcs_to_mtk_pcs_lynxi(struct phylink_pcs *pcs) - { - return container_of(pcs, struct mtk_pcs_lynxi, pcs); -@@ -117,6 +139,17 @@ static void mtk_pcs_lynxi_get_state(struct phylink_pcs *pcs, - FIELD_GET(SGMII_LPA, adv)); - } - -+static void mtk_sgmii_reset(struct mtk_pcs_lynxi *mpcs) -+{ -+ if (!mpcs->rstc) -+ return; -+ -+ reset_control_assert(mpcs->rstc); -+ udelay(100); -+ reset_control_deassert(mpcs->rstc); -+ mdelay(1); -+} -+ - static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode, - phy_interface_t interface, - const unsigned long *advertising, -@@ -162,6 +195,7 @@ static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode, - SGMII_PHYA_PWD); - - /* Reset SGMII PCS state */ -+ mtk_sgmii_reset(mpcs); - regmap_set_bits(mpcs->regmap, SGMSYS_RESERVED_0, - SGMII_SW_RESET); - -@@ -248,10 +282,29 @@ static void mtk_pcs_lynxi_link_up(struct phylink_pcs *pcs, - } - } - -+static int mtk_pcs_lynxi_enable(struct phylink_pcs *pcs) -+{ -+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); -+ -+ if (mpcs->sgmii_tx && mpcs->sgmii_rx) { -+ clk_prepare_enable(mpcs->sgmii_rx); -+ clk_prepare_enable(mpcs->sgmii_tx); -+ } -+ -+ return 0; -+} -+ - static void mtk_pcs_lynxi_disable(struct phylink_pcs *pcs) - { - struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); - -+ regmap_set_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, SGMII_PHYA_PWD); -+ -+ if (mpcs->sgmii_tx && mpcs->sgmii_rx) { -+ clk_disable_unprepare(mpcs->sgmii_tx); -+ clk_disable_unprepare(mpcs->sgmii_rx); -+ } -+ - mpcs->interface = PHY_INTERFACE_MODE_NA; - } - -@@ -262,11 +315,12 @@ static const struct phylink_pcs_ops mtk_pcs_lynxi_ops = { - .pcs_an_restart = mtk_pcs_lynxi_restart_an, - .pcs_link_up = mtk_pcs_lynxi_link_up, - .pcs_disable = mtk_pcs_lynxi_disable, -+ .pcs_enable = mtk_pcs_lynxi_enable, - }; - --struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev, -- struct regmap *regmap, u32 ana_rgc3, -- u32 flags) -+static struct phylink_pcs *mtk_pcs_lynxi_init(struct device *dev, struct regmap *regmap, -+ u32 ana_rgc3, u32 flags, -+ struct mtk_pcs_lynxi *prealloc) - { - struct mtk_pcs_lynxi *mpcs; - u32 id, ver; -@@ -274,29 +328,33 @@ struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev, - - ret = regmap_read(regmap, SGMSYS_PCS_DEVICE_ID, &id); - if (ret < 0) -- return NULL; -+ return ERR_PTR(ret); - - if (id != SGMII_LYNXI_DEV_ID) { - dev_err(dev, "unknown PCS device id %08x\n", id); -- return NULL; -+ return ERR_PTR(-ENODEV); - } - - ret = regmap_read(regmap, SGMSYS_PCS_SCRATCH, &ver); - if (ret < 0) -- return NULL; -+ return ERR_PTR(ret); - - ver = FIELD_GET(SGMII_DEV_VERSION, ver); - if (ver != 0x1) { - dev_err(dev, "unknown PCS device version %04x\n", ver); -- return NULL; -+ return ERR_PTR(-ENODEV); - } - - dev_dbg(dev, "MediaTek LynxI SGMII PCS (id 0x%08x, ver 0x%04x)\n", id, - ver); - -- mpcs = kzalloc(sizeof(*mpcs), GFP_KERNEL); -- if (!mpcs) -- return NULL; -+ if (prealloc) { -+ mpcs = prealloc; -+ } else { -+ mpcs = kzalloc(sizeof(*mpcs), GFP_KERNEL); -+ if (!mpcs) -+ return ERR_PTR(-ENOMEM); -+ }; - - mpcs->ana_rgc3 = ana_rgc3; - mpcs->regmap = regmap; -@@ -307,6 +365,13 @@ struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev, - mpcs->interface = PHY_INTERFACE_MODE_NA; - - return &mpcs->pcs; -+}; -+ -+struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev, -+ struct regmap *regmap, u32 ana_rgc3, -+ u32 flags) -+{ -+ return mtk_pcs_lynxi_init(dev, regmap, ana_rgc3, flags, NULL); - } - EXPORT_SYMBOL(mtk_pcs_lynxi_create); - -@@ -319,5 +384,142 @@ void mtk_pcs_lynxi_destroy(struct phylink_pcs *pcs) - } - EXPORT_SYMBOL(mtk_pcs_lynxi_destroy); - -+static int mtk_pcs_lynxi_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct device_node *np = dev->of_node; -+ struct mtk_pcs_lynxi *mpcs; -+ struct phylink_pcs *pcs; -+ struct regmap *regmap; -+ u32 flags = 0; -+ -+ mpcs = devm_kzalloc(dev, sizeof(*mpcs), GFP_KERNEL); -+ if (!mpcs) -+ return -ENOMEM; -+ -+ mpcs->dev = dev; -+ regmap = syscon_node_to_regmap(np->parent); -+ if (IS_ERR(regmap)) -+ return PTR_ERR(regmap); -+ -+ if (of_property_read_bool(np->parent, "mediatek,pnswap")) -+ flags |= MTK_SGMII_FLAG_PN_SWAP; -+ -+ mpcs->rstc = of_reset_control_get_shared(np->parent, NULL); -+ if (IS_ERR(mpcs->rstc)) -+ return PTR_ERR(mpcs->rstc); -+ -+ reset_control_deassert(mpcs->rstc); -+ mpcs->sgmii_sel = devm_clk_get_enabled(dev, "sgmii_sel"); -+ if (IS_ERR(mpcs->sgmii_sel)) -+ return PTR_ERR(mpcs->sgmii_sel); -+ -+ mpcs->sgmii_rx = devm_clk_get(dev, "sgmii_rx"); -+ if (IS_ERR(mpcs->sgmii_rx)) -+ return PTR_ERR(mpcs->sgmii_rx); -+ -+ mpcs->sgmii_tx = devm_clk_get(dev, "sgmii_tx"); -+ if (IS_ERR(mpcs->sgmii_tx)) -+ return PTR_ERR(mpcs->sgmii_tx); -+ -+ pcs = mtk_pcs_lynxi_init(dev, regmap, (uintptr_t)of_device_get_match_data(dev), -+ flags, mpcs); -+ if (IS_ERR(pcs)) -+ return PTR_ERR(pcs); -+ -+ regmap_set_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, SGMII_PHYA_PWD); -+ -+ platform_set_drvdata(pdev, mpcs); -+ -+ mutex_lock(&instance_mutex); -+ list_add_tail(&mpcs->node, &mtk_pcs_lynxi_instances); -+ mutex_unlock(&instance_mutex); -+ -+ return 0; -+} -+ -+static void mtk_pcs_lynxi_remove(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct mtk_pcs_lynxi *cur, *tmp; -+ -+ mutex_lock(&instance_mutex); -+ list_for_each_entry_safe(cur, tmp, &mtk_pcs_lynxi_instances, node) -+ if (cur->dev == dev) { -+ list_del(&cur->node); -+ kfree(cur); -+ break; -+ } -+ mutex_unlock(&instance_mutex); -+} -+ -+static const struct of_device_id mtk_pcs_lynxi_of_match[] = { -+ { .compatible = "mediatek,mt7988-sgmii", .data = (void *)MTK_NETSYS_V3_AMA_RGC3 }, -+ { /* sentinel */ }, -+}; -+MODULE_DEVICE_TABLE(of, mtk_pcs_lynxi_of_match); -+ -+struct phylink_pcs *mtk_pcs_lynxi_get(struct device *dev, struct device_node *np) -+{ -+ struct platform_device *pdev; -+ struct mtk_pcs_lynxi *mpcs; -+ -+ if (!np) -+ return NULL; -+ -+ if (!of_device_is_available(np)) -+ return ERR_PTR(-ENODEV); -+ -+ if (!of_match_node(mtk_pcs_lynxi_of_match, np)) -+ return ERR_PTR(-EINVAL); -+ -+ pdev = of_find_device_by_node(np); -+ if (!pdev || !platform_get_drvdata(pdev)) { -+ if (pdev) -+ put_device(&pdev->dev); -+ return ERR_PTR(-EPROBE_DEFER); -+ } -+ -+ mpcs = platform_get_drvdata(pdev); -+ device_link_add(dev, mpcs->dev, DL_FLAG_AUTOREMOVE_CONSUMER); -+ -+ return &mpcs->pcs; -+} -+EXPORT_SYMBOL(mtk_pcs_lynxi_get); -+ -+void mtk_pcs_lynxi_put(struct phylink_pcs *pcs) -+{ -+ struct mtk_pcs_lynxi *cur, *mpcs = NULL; -+ -+ if (!pcs) -+ return; -+ -+ mutex_lock(&instance_mutex); -+ list_for_each_entry(cur, &mtk_pcs_lynxi_instances, node) -+ if (pcs == &cur->pcs) { -+ mpcs = cur; -+ break; -+ } -+ mutex_unlock(&instance_mutex); -+ -+ if (WARN_ON(!mpcs)) -+ return; -+ -+ put_device(mpcs->dev); -+} -+EXPORT_SYMBOL(mtk_pcs_lynxi_put); -+ -+static struct platform_driver mtk_pcs_lynxi_driver = { -+ .driver = { -+ .name = "mtk-pcs-lynxi", -+ .suppress_bind_attrs = true, -+ .of_match_table = mtk_pcs_lynxi_of_match, -+ }, -+ .probe = mtk_pcs_lynxi_probe, -+ .remove_new = mtk_pcs_lynxi_remove, -+}; -+module_platform_driver(mtk_pcs_lynxi_driver); -+ -+MODULE_AUTHOR("Daniel Golle "); - MODULE_DESCRIPTION("MediaTek SGMII library for LynxI"); - MODULE_LICENSE("GPL"); -diff --git a/include/linux/pcs/pcs-mtk-lynxi.h b/include/linux/pcs/pcs-mtk-lynxi.h -index be3b4ab32f4a..2d44e951229c 100644 ---- a/include/linux/pcs/pcs-mtk-lynxi.h -+++ b/include/linux/pcs/pcs-mtk-lynxi.h -@@ -10,4 +10,15 @@ struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev, - struct regmap *regmap, - u32 ana_rgc3, u32 flags); - void mtk_pcs_lynxi_destroy(struct phylink_pcs *pcs); -+ -+#if IS_ENABLED(CONFIG_PCS_MTK_LYNXI) -+struct phylink_pcs *mtk_pcs_lynxi_get(struct device *dev, struct device_node *np); -+void mtk_pcs_lynxi_put(struct phylink_pcs *pcs); -+#else -+static inline struct phylink_pcs *mtk_pcs_lynxi_get(struct device *dev, struct device_node *np) -+{ -+ return NULL; -+} -+static inline void mtk_pcs_lynxi_put(struct phylink_pcs *pcs) { } -+#endif /* IS_ENABLED(CONFIG_PCS_MTK_LYNXI) */ - #endif --- -2.51.0 - - -From a09eaf2a559be259da7878179db062e574fcf9ad Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 12 Dec 2023 03:47:31 +0000 -Subject: [PATCH 305/517] dt-bindings: net: pcs: add bindings for MediaTek - USXGMII PCS - -MediaTek's USXGMII can be found in the MT7988 SoC. We need to access -it in order to configure and monitor the Ethernet SerDes link in -USXGMII, 10GBase-R and 5GBase-R mode. By including a wrapped -legacy 1000Base-X/2500Base-X/Cisco SGMII LynxI PCS as well, those -interface modes are also available. - -Signed-off-by: Daniel Golle ---- - .../bindings/net/pcs/mediatek,usxgmii.yaml | 60 +++++++++++++++++++ - 1 file changed, 60 insertions(+) - create mode 100644 Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml - -diff --git a/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml b/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml -new file mode 100644 -index 000000000000..0cdaa3545edb ---- /dev/null -+++ b/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml -@@ -0,0 +1,60 @@ -+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/net/pcs/mediatek,usxgmii.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: MediaTek USXGMII PCS -+ -+maintainers: -+ - Daniel Golle -+ -+description: -+ The MediaTek USXGMII PCS provides physical link control and status -+ for USXGMII, 10GBase-R and 5GBase-R links on the SerDes interfaces -+ provided by the PEXTP PHY. -+ In order to also support legacy 2500Base-X, 1000Base-X and Cisco -+ SGMII an existing mediatek,*-sgmiisys LynxI PCS is wrapped to -+ provide those interfaces modes on the same SerDes interfaces shared -+ with the USXGMII PCS. -+ -+properties: -+ $nodename: -+ pattern: "^pcs@[0-9a-f]+$" -+ -+ compatible: -+ const: mediatek,mt7988-usxgmiisys -+ -+ reg: -+ maxItems: 1 -+ -+ clocks: -+ items: -+ - description: USXGMII top-level clock -+ -+ resets: -+ items: -+ - description: XFI reset -+ -+required: -+ - compatible -+ - reg -+ - clocks -+ - resets -+ -+additionalProperties: false -+ -+examples: -+ - | -+ #include -+ #define MT7988_TOPRGU_XFI0_GRST 12 -+ soc { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ usxgmiisys0: pcs@10080000 { -+ compatible = "mediatek,mt7988-usxgmiisys"; -+ reg = <0 0x10080000 0 0x1000>; -+ clocks = <&topckgen CLK_TOP_USXGMII_SBUS_0_SEL>; -+ resets = <&watchdog MT7988_TOPRGU_XFI0_GRST>; -+ }; -+ }; --- -2.51.0 - - -From 0005a0d86158863f4dd392dae5faca22f13d5f0e Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 12 Dec 2023 03:47:47 +0000 -Subject: [PATCH 306/517] net: pcs: add driver for MediaTek USXGMII PCS - -Add driver for USXGMII PCS found in the MediaTek MT7988 SoC and supporting -USXGMII, 10GBase-R and 5GBase-R interface modes. - -Signed-off-by: Daniel Golle ---- - MAINTAINERS | 2 + - drivers/net/pcs/Kconfig | 11 + - drivers/net/pcs/Makefile | 1 + - drivers/net/pcs/pcs-mtk-usxgmii.c | 454 ++++++++++++++++++++++++++++ - include/linux/pcs/pcs-mtk-usxgmii.h | 27 ++ - 5 files changed, 495 insertions(+) - create mode 100644 drivers/net/pcs/pcs-mtk-usxgmii.c - create mode 100644 include/linux/pcs/pcs-mtk-usxgmii.h - -diff --git a/MAINTAINERS b/MAINTAINERS -index dcb5c71bc204..3a22c29b35a6 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -14419,7 +14419,9 @@ M: Daniel Golle - L: netdev@vger.kernel.org - S: Maintained - F: drivers/net/pcs/pcs-mtk-lynxi.c -+F: drivers/net/pcs/pcs-mtk-usxgmii.c - F: include/linux/pcs/pcs-mtk-lynxi.h -+F: include/linux/pcs/pcs-mtk-usxgmii.h - - MEDIATEK ETHERNET PHY DRIVERS - M: Daniel Golle -diff --git a/drivers/net/pcs/Kconfig b/drivers/net/pcs/Kconfig -index f6aa437473de..8c642da2c6e0 100644 ---- a/drivers/net/pcs/Kconfig -+++ b/drivers/net/pcs/Kconfig -@@ -25,6 +25,17 @@ config PCS_MTK_LYNXI - This module provides helpers to phylink for managing the LynxI PCS - which is part of MediaTek's SoC and Ethernet switch ICs. - -+config PCS_MTK_USXGMII -+ tristate "MediaTek USXGMII PCS" -+ select PCS_MTK_LYNXI -+ select PHY_MTK_PEXTP -+ select PHYLINK -+ help -+ This module provides a driver for MediaTek's USXGMII PCS supporting -+ 10GBase-R, 5GBase-R and USXGMII interface modes. -+ 1000Base-X, 2500Base-X and Cisco SGMII are supported on the same -+ differential pairs via an embedded LynxI PHY. -+ - config PCS_RZN1_MIIC - tristate "Renesas RZ/N1 MII converter" - depends on OF && (ARCH_RZN1 || COMPILE_TEST) -diff --git a/drivers/net/pcs/Makefile b/drivers/net/pcs/Makefile -index 4f7920618b90..20647ac375d5 100644 ---- a/drivers/net/pcs/Makefile -+++ b/drivers/net/pcs/Makefile -@@ -8,3 +8,4 @@ obj-$(CONFIG_PCS_XPCS) += pcs_xpcs.o - obj-$(CONFIG_PCS_LYNX) += pcs-lynx.o - obj-$(CONFIG_PCS_MTK_LYNXI) += pcs-mtk-lynxi.o - obj-$(CONFIG_PCS_RZN1_MIIC) += pcs-rzn1-miic.o -+obj-$(CONFIG_PCS_MTK_USXGMII) += pcs-mtk-usxgmii.o -diff --git a/drivers/net/pcs/pcs-mtk-usxgmii.c b/drivers/net/pcs/pcs-mtk-usxgmii.c -new file mode 100644 -index 000000000000..9691d9e73790 ---- /dev/null -+++ b/drivers/net/pcs/pcs-mtk-usxgmii.c -@@ -0,0 +1,454 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (c) 2023 MediaTek Inc. -+ * Author: Henry Yen -+ * Daniel Golle -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* USXGMII subsystem config registers */ -+/* Register to control speed */ -+#define RG_PHY_TOP_SPEED_CTRL1 0x80c -+#define USXGMII_RATE_UPDATE_MODE BIT(31) -+#define USXGMII_MAC_CK_GATED BIT(29) -+#define USXGMII_IF_FORCE_EN BIT(28) -+#define USXGMII_RATE_ADAPT_MODE GENMASK(10, 8) -+#define USXGMII_RATE_ADAPT_MODE_X1 0 -+#define USXGMII_RATE_ADAPT_MODE_X2 1 -+#define USXGMII_RATE_ADAPT_MODE_X4 2 -+#define USXGMII_RATE_ADAPT_MODE_X10 3 -+#define USXGMII_RATE_ADAPT_MODE_X100 4 -+#define USXGMII_RATE_ADAPT_MODE_X5 5 -+#define USXGMII_RATE_ADAPT_MODE_X50 6 -+#define USXGMII_XFI_RX_MODE GENMASK(6, 4) -+#define USXGMII_XFI_TX_MODE GENMASK(2, 0) -+#define USXGMII_XFI_MODE_10G 0 -+#define USXGMII_XFI_MODE_5G 1 -+#define USXGMII_XFI_MODE_2P5G 3 -+ -+/* Register to control PCS AN */ -+#define RG_PCS_AN_CTRL0 0x810 -+#define USXGMII_AN_RESTART BIT(31) -+#define USXGMII_AN_SYNC_CNT GENMASK(30, 11) -+#define USXGMII_AN_ENABLE BIT(0) -+ -+#define RG_PCS_AN_CTRL2 0x818 -+#define USXGMII_LINK_TIMER_IDLE_DETECT GENMASK(29, 20) -+#define USXGMII_LINK_TIMER_COMP_ACK_DETECT GENMASK(19, 10) -+#define USXGMII_LINK_TIMER_AN_RESTART GENMASK(9, 0) -+ -+/* Register to read PCS AN status */ -+#define RG_PCS_AN_STS0 0x81c -+#define USXGMII_LPA GENMASK(15, 0) -+#define USXGMII_LPA_LATCH BIT(31) -+ -+/* Register to read PCS link status */ -+#define RG_PCS_RX_STATUS0 0x904 -+#define RG_PCS_RX_STATUS_UPDATE BIT(16) -+#define RG_PCS_RX_LINK_STATUS BIT(2) -+ -+/* struct mtk_usxgmii_pcs - This structure holds each usxgmii PCS -+ * @pcs: Phylink PCS structure -+ * @dev: Pointer to device structure -+ * @base: IO memory to access PCS hardware -+ * @clk: Pointer to USXGMII clk -+ * @reset: Pointer to USXGMII reset control -+ * @interface: Currently selected interface mode -+ * @neg_mode: Currently used phylink neg_mode -+ * @node: List node -+ */ -+struct mtk_usxgmii_pcs { -+ struct phylink_pcs pcs; -+ struct device *dev; -+ void __iomem *base; -+ struct clk *clk; -+ struct reset_control *reset; -+ phy_interface_t interface; -+ unsigned int neg_mode; -+ struct list_head node; -+}; -+ -+static LIST_HEAD(mtk_usxgmii_pcs_instances); -+static DEFINE_MUTEX(instance_mutex); -+ -+static u32 mtk_r32(struct mtk_usxgmii_pcs *mpcs, unsigned int reg) -+{ -+ return ioread32(mpcs->base + reg); -+} -+ -+static void mtk_m32(struct mtk_usxgmii_pcs *mpcs, unsigned int reg, u32 mask, u32 set) -+{ -+ u32 val; -+ -+ val = ioread32(mpcs->base + reg); -+ val &= ~mask; -+ val |= set; -+ iowrite32(val, mpcs->base + reg); -+} -+ -+static struct mtk_usxgmii_pcs *pcs_to_mtk_usxgmii_pcs(struct phylink_pcs *pcs) -+{ -+ return container_of(pcs, struct mtk_usxgmii_pcs, pcs); -+} -+ -+static void mtk_usxgmii_reset(struct mtk_usxgmii_pcs *mpcs) -+{ -+ reset_control_assert(mpcs->reset); -+ udelay(100); -+ reset_control_deassert(mpcs->reset); -+ -+ mdelay(10); -+} -+ -+static int mtk_usxgmii_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode, -+ phy_interface_t interface, -+ const unsigned long *advertising, -+ bool permit_pause_to_mac) -+{ -+ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); -+ unsigned int an_ctrl = 0, link_timer = 0, xfi_mode = 0, adapt_mode = 0; -+ bool mode_changed = false; -+ -+ if (interface == PHY_INTERFACE_MODE_USXGMII) { -+ an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF) | USXGMII_AN_ENABLE; -+ link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) | -+ FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) | -+ FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B); -+ xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_MODE_10G) | -+ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_MODE_10G); -+ } else if (interface == PHY_INTERFACE_MODE_10GBASER) { -+ an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF); -+ link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) | -+ FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) | -+ FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B); -+ xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_MODE_10G) | -+ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_MODE_10G); -+ adapt_mode = USXGMII_RATE_UPDATE_MODE; -+ } else if (interface == PHY_INTERFACE_MODE_5GBASER) { -+ an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0xFF); -+ link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x3D) | -+ FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x3D) | -+ FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x3D); -+ xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_MODE_5G) | -+ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_MODE_5G); -+ adapt_mode = USXGMII_RATE_UPDATE_MODE; -+ } else { -+ return -EINVAL; -+ } -+ -+ adapt_mode |= FIELD_PREP(USXGMII_RATE_ADAPT_MODE, USXGMII_RATE_ADAPT_MODE_X1); -+ -+ if (mpcs->interface != interface) { -+ mpcs->interface = interface; -+ mode_changed = true; -+ } -+ -+ mtk_usxgmii_reset(mpcs); -+ -+ /* Setup USXGMII AN ctrl */ -+ mtk_m32(mpcs, RG_PCS_AN_CTRL0, -+ USXGMII_AN_SYNC_CNT | USXGMII_AN_ENABLE, -+ an_ctrl); -+ -+ mtk_m32(mpcs, RG_PCS_AN_CTRL2, -+ USXGMII_LINK_TIMER_IDLE_DETECT | -+ USXGMII_LINK_TIMER_COMP_ACK_DETECT | -+ USXGMII_LINK_TIMER_AN_RESTART, -+ link_timer); -+ -+ mpcs->neg_mode = neg_mode; -+ -+ /* Gated MAC CK */ -+ mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1, -+ USXGMII_MAC_CK_GATED, USXGMII_MAC_CK_GATED); -+ -+ /* Enable interface force mode */ -+ mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1, -+ USXGMII_IF_FORCE_EN, USXGMII_IF_FORCE_EN); -+ -+ /* Setup USXGMII adapt mode */ -+ mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1, -+ USXGMII_RATE_UPDATE_MODE | USXGMII_RATE_ADAPT_MODE, -+ adapt_mode); -+ -+ /* Setup USXGMII speed */ -+ mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1, -+ USXGMII_XFI_RX_MODE | USXGMII_XFI_TX_MODE, -+ xfi_mode); -+ -+ usleep_range(1, 10); -+ -+ /* Un-gated MAC CK */ -+ mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1, USXGMII_MAC_CK_GATED, 0); -+ -+ usleep_range(1, 10); -+ -+ /* Disable interface force mode for the AN mode */ -+ if (an_ctrl & USXGMII_AN_ENABLE) -+ mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1, USXGMII_IF_FORCE_EN, 0); -+ -+ return mode_changed; -+} -+ -+static void mtk_usxgmii_pcs_get_fixed_speed(struct mtk_usxgmii_pcs *mpcs, -+ struct phylink_link_state *state) -+{ -+ u32 val = mtk_r32(mpcs, RG_PHY_TOP_SPEED_CTRL1); -+ int speed; -+ -+ /* Calculate speed from interface speed and rate adapt mode */ -+ switch (FIELD_GET(USXGMII_XFI_RX_MODE, val)) { -+ case USXGMII_XFI_MODE_10G: -+ speed = 10000; -+ break; -+ case USXGMII_XFI_MODE_5G: -+ speed = 5000; -+ break; -+ case USXGMII_XFI_MODE_2P5G: -+ speed = 2500; -+ break; -+ default: -+ state->speed = SPEED_UNKNOWN; -+ return; -+ } -+ -+ switch (FIELD_GET(USXGMII_RATE_ADAPT_MODE, val)) { -+ case USXGMII_RATE_ADAPT_MODE_X100: -+ speed /= 100; -+ break; -+ case USXGMII_RATE_ADAPT_MODE_X50: -+ speed /= 50; -+ break; -+ case USXGMII_RATE_ADAPT_MODE_X10: -+ speed /= 10; -+ break; -+ case USXGMII_RATE_ADAPT_MODE_X5: -+ speed /= 5; -+ break; -+ case USXGMII_RATE_ADAPT_MODE_X4: -+ speed /= 4; -+ break; -+ case USXGMII_RATE_ADAPT_MODE_X2: -+ speed /= 2; -+ break; -+ case USXGMII_RATE_ADAPT_MODE_X1: -+ break; -+ default: -+ state->speed = SPEED_UNKNOWN; -+ return; -+ } -+ -+ state->speed = speed; -+ state->duplex = DUPLEX_FULL; -+} -+ -+static void mtk_usxgmii_pcs_get_an_state(struct mtk_usxgmii_pcs *mpcs, -+ struct phylink_link_state *state) -+{ -+ u16 lpa; -+ -+ /* Refresh LPA by toggling LPA_LATCH */ -+ mtk_m32(mpcs, RG_PCS_AN_STS0, USXGMII_LPA_LATCH, USXGMII_LPA_LATCH); -+ ndelay(1020); -+ mtk_m32(mpcs, RG_PCS_AN_STS0, USXGMII_LPA_LATCH, 0); -+ ndelay(1020); -+ lpa = FIELD_GET(USXGMII_LPA, mtk_r32(mpcs, RG_PCS_AN_STS0)); -+ -+ phylink_decode_usxgmii_word(state, lpa); -+} -+ -+static void mtk_usxgmii_pcs_get_state(struct phylink_pcs *pcs, -+ struct phylink_link_state *state) -+{ -+ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); -+ -+ /* Refresh USXGMII link status by toggling RG_PCS_AN_STATUS_UPDATE */ -+ mtk_m32(mpcs, RG_PCS_RX_STATUS0, RG_PCS_RX_STATUS_UPDATE, -+ RG_PCS_RX_STATUS_UPDATE); -+ ndelay(1020); -+ mtk_m32(mpcs, RG_PCS_RX_STATUS0, RG_PCS_RX_STATUS_UPDATE, 0); -+ ndelay(1020); -+ -+ /* Read USXGMII link status */ -+ state->link = FIELD_GET(RG_PCS_RX_LINK_STATUS, -+ mtk_r32(mpcs, RG_PCS_RX_STATUS0)); -+ -+ /* Continuously repeat re-configuration sequence until link comes up */ -+ if (!state->link) { -+ mtk_usxgmii_pcs_config(pcs, mpcs->neg_mode, -+ state->interface, NULL, false); -+ return; -+ } -+ -+ if (FIELD_GET(USXGMII_AN_ENABLE, mtk_r32(mpcs, RG_PCS_AN_CTRL0))) -+ mtk_usxgmii_pcs_get_an_state(mpcs, state); -+ else -+ mtk_usxgmii_pcs_get_fixed_speed(mpcs, state); -+} -+ -+static void mtk_usxgmii_pcs_restart_an(struct phylink_pcs *pcs) -+{ -+ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); -+ -+ mtk_m32(mpcs, RG_PCS_AN_CTRL0, USXGMII_AN_RESTART, USXGMII_AN_RESTART); -+} -+ -+static void mtk_usxgmii_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode, -+ phy_interface_t interface, -+ int speed, int duplex) -+{ -+ /* Reconfiguring USXGMII to ensure the quality of the RX signal -+ * after the line side link up. -+ */ -+ mtk_usxgmii_pcs_config(pcs, neg_mode, interface, NULL, false); -+} -+ -+static void mtk_usxgmii_pcs_disable(struct phylink_pcs *pcs) -+{ -+ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); -+ -+ mpcs->interface = PHY_INTERFACE_MODE_NA; -+ mpcs->neg_mode = -1; -+} -+ -+static const struct phylink_pcs_ops mtk_usxgmii_pcs_ops = { -+ .pcs_config = mtk_usxgmii_pcs_config, -+ .pcs_get_state = mtk_usxgmii_pcs_get_state, -+ .pcs_an_restart = mtk_usxgmii_pcs_restart_an, -+ .pcs_link_up = mtk_usxgmii_pcs_link_up, -+ .pcs_disable = mtk_usxgmii_pcs_disable, -+}; -+ -+static int mtk_usxgmii_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct mtk_usxgmii_pcs *mpcs; -+ -+ mpcs = devm_kzalloc(dev, sizeof(*mpcs), GFP_KERNEL); -+ if (!mpcs) -+ return -ENOMEM; -+ -+ mpcs->base = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(mpcs->base)) -+ return PTR_ERR(mpcs->base); -+ -+ mpcs->dev = dev; -+ mpcs->pcs.ops = &mtk_usxgmii_pcs_ops; -+ mpcs->pcs.poll = true; -+ mpcs->pcs.neg_mode = true; -+ mpcs->interface = PHY_INTERFACE_MODE_NA; -+ mpcs->neg_mode = -1; -+ -+ mpcs->clk = devm_clk_get_enabled(mpcs->dev, NULL); -+ if (IS_ERR(mpcs->clk)) -+ return PTR_ERR(mpcs->clk); -+ -+ mpcs->reset = devm_reset_control_get_shared(dev, NULL); -+ if (IS_ERR(mpcs->reset)) -+ return PTR_ERR(mpcs->reset); -+ -+ reset_control_deassert(mpcs->reset); -+ -+ platform_set_drvdata(pdev, mpcs); -+ -+ mutex_lock(&instance_mutex); -+ list_add_tail(&mpcs->node, &mtk_usxgmii_pcs_instances); -+ mutex_unlock(&instance_mutex); -+ -+ return 0; -+} -+ -+static void mtk_usxgmii_remove(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct mtk_usxgmii_pcs *cur, *tmp; -+ -+ mutex_lock(&instance_mutex); -+ list_for_each_entry_safe(cur, tmp, &mtk_usxgmii_pcs_instances, node) -+ if (cur->dev == dev) { -+ list_del(&cur->node); -+ break; -+ } -+ mutex_unlock(&instance_mutex); -+} -+ -+static const struct of_device_id mtk_usxgmii_of_mtable[] = { -+ { .compatible = "mediatek,mt7988-usxgmiisys" }, -+ { /* sentinel */ }, -+}; -+MODULE_DEVICE_TABLE(of, mtk_usxgmii_of_mtable); -+ -+struct phylink_pcs *mtk_usxgmii_pcs_get(struct device *dev, struct device_node *np) -+{ -+ struct platform_device *pdev; -+ struct mtk_usxgmii_pcs *mpcs; -+ -+ if (!np) -+ return NULL; -+ -+ if (!of_device_is_available(np)) -+ return ERR_PTR(-ENODEV); -+ -+ if (!of_match_node(mtk_usxgmii_of_mtable, np)) -+ return ERR_PTR(-EINVAL); -+ -+ pdev = of_find_device_by_node(np); -+ if (!pdev || !platform_get_drvdata(pdev)) { -+ if (pdev) -+ put_device(&pdev->dev); -+ return ERR_PTR(-EPROBE_DEFER); -+ } -+ -+ mpcs = platform_get_drvdata(pdev); -+ device_link_add(dev, mpcs->dev, DL_FLAG_AUTOREMOVE_CONSUMER); -+ -+ return &mpcs->pcs; -+} -+EXPORT_SYMBOL(mtk_usxgmii_pcs_get); -+ -+void mtk_usxgmii_pcs_put(struct phylink_pcs *pcs) -+{ -+ struct mtk_usxgmii_pcs *cur, *mpcs = NULL; -+ -+ if (!pcs) -+ return; -+ -+ mutex_lock(&instance_mutex); -+ list_for_each_entry(cur, &mtk_usxgmii_pcs_instances, node) -+ if (pcs == &cur->pcs) { -+ mpcs = cur; -+ break; -+ } -+ mutex_unlock(&instance_mutex); -+ -+ if (WARN_ON(!mpcs)) -+ return; -+ -+ put_device(mpcs->dev); -+} -+EXPORT_SYMBOL(mtk_usxgmii_pcs_put); -+ -+static struct platform_driver mtk_usxgmii_driver = { -+ .driver = { -+ .name = "mtk_usxgmii", -+ .suppress_bind_attrs = true, -+ .of_match_table = mtk_usxgmii_of_mtable, -+ }, -+ .probe = mtk_usxgmii_probe, -+ .remove_new = mtk_usxgmii_remove, -+}; -+module_platform_driver(mtk_usxgmii_driver); -+ -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("MediaTek USXGMII PCS driver"); -+MODULE_AUTHOR("Daniel Golle "); -diff --git a/include/linux/pcs/pcs-mtk-usxgmii.h b/include/linux/pcs/pcs-mtk-usxgmii.h -new file mode 100644 -index 000000000000..ef936d9c5f11 ---- /dev/null -+++ b/include/linux/pcs/pcs-mtk-usxgmii.h -@@ -0,0 +1,27 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+#ifndef __LINUX_PCS_MTK_USXGMII_H -+#define __LINUX_PCS_MTK_USXGMII_H -+ -+#include -+ -+/** -+ * mtk_usxgmii_select_pcs() - Get MediaTek PCS instance -+ * @np: Pointer to device node indentifying a MediaTek USXGMII PCS -+ * @mode: Ethernet PHY interface mode -+ * -+ * Return PCS identified by a device node and the PHY interface mode in use -+ * -+ * Return: Pointer to phylink PCS instance of NULL -+ */ -+#if IS_ENABLED(CONFIG_PCS_MTK_USXGMII) -+struct phylink_pcs *mtk_usxgmii_pcs_get(struct device *dev, struct device_node *np); -+void mtk_usxgmii_pcs_put(struct phylink_pcs *pcs); -+#else -+static inline struct phylink_pcs *mtk_usxgmii_pcs_get(struct device *dev, struct device_node *np) -+{ -+ return NULL; -+} -+static inline void mtk_usxgmii_pcs_put(struct phylink_pcs *pcs) { } -+#endif /* IS_ENABLED(CONFIG_PCS_MTK_USXGMII) */ -+ -+#endif /* __LINUX_PCS_MTK_USXGMII_H */ --- -2.51.0 - - -From 8d0a817f11fff5555100d757f73aa7d702774a83 Mon Sep 17 00:00:00 2001 -From: Hauke Mehrtens -Date: Sun, 21 May 2023 22:24:56 +0200 -Subject: [PATCH 307/517] net: phy: motorcomm: Add missing include - -Directly include linux/bitfield.h which provides FIELD_PREP. - -Signed-off-by: Hauke Mehrtens ---- - drivers/net/phy/motorcomm.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c -index 0e91f5d1a4fd..cb57ebb87237 100644 ---- a/drivers/net/phy/motorcomm.c -+++ b/drivers/net/phy/motorcomm.c -@@ -6,6 +6,7 @@ - * Author: Frank - */ - -+#include - #include - #include - #include --- -2.51.0 - - -From 64c6f86708f9e4ccf5e70f38508f88be90d095c9 Mon Sep 17 00:00:00 2001 -From: David Bauer -Date: Sat, 16 Nov 2024 22:36:15 +0100 -Subject: [PATCH 308/517] net: phy: broadcom: update dependency condition - -The broadcom PHY driver only has to depend upon PTP_1588_CLOCK_OPTIONAL -if NETWORK_PHY_TIMESTAMPING is enabled. The PTP functionality is stubbed -in this case. - -Reflect this circumstance in the dependence condition. This allows to -build the driver as a built-in module even if PTP is built as a module. - -This is required to include the broadcom PHY module regardless of the -built-setting of the PTP subsystem. On ath79 (and probably more) -targets with Broadcom PHY, Gigabit operation is currently broken as the -PHY driver is only built as a module in case all kernel-packages are -built. Due to this circumstance, affected devices fall back to using the -generic PHY driver. - -Signed-off-by: David Bauer ---- - drivers/net/phy/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig -index bf7c34402e74..8c92405b84d4 100644 ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -151,7 +151,7 @@ config BROADCOM_PHY - tristate "Broadcom 54XX PHYs" - select BCM_NET_PHYLIB - select BCM_NET_PHYPTP if NETWORK_PHY_TIMESTAMPING -- depends on PTP_1588_CLOCK_OPTIONAL -+ depends on NETWORK_PHY_TIMESTAMPING=n || PTP_1588_CLOCK_OPTIONAL - help - Currently supports the BCM5411, BCM5421, BCM5461, BCM54616S, BCM5464, - BCM5481, BCM54810 and BCM5482 PHYs. --- -2.51.0 - - -From e3a83bc28d2d129742cc38dbb1e652c9839c110b Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 5 Aug 2021 23:23:30 +0100 -Subject: [PATCH 309/517] ARM: kirkwood: add missing for - ETH_ALEN - -After commit 83216e3988cd1 ("of: net: pass the dst buffer to -of_get_mac_address()") build fails for kirkwood as ETH_ALEN is not -defined. - -arch/arm/mach-mvebu/kirkwood.c: In function 'kirkwood_dt_eth_fixup': -arch/arm/mach-mvebu/kirkwood.c:87:13: error: 'ETH_ALEN' undeclared (first use in this function); did you mean 'ESTALE'? - u8 tmpmac[ETH_ALEN]; - ^~~~~~~~ - ESTALE -arch/arm/mach-mvebu/kirkwood.c:87:13: note: each undeclared identifier is reported only once for each function it appears in -arch/arm/mach-mvebu/kirkwood.c:87:6: warning: unused variable 'tmpmac' [-Wunused-variable] - u8 tmpmac[ETH_ALEN]; - ^~~~~~ -make[5]: *** [scripts/Makefile.build:262: arch/arm/mach-mvebu/kirkwood.o] Error 1 -make[5]: *** Waiting for unfinished jobs.... - -Add missing #include to fix this. - -Cc: David S. Miller -Cc: Andrew Lunn -Cc: Michael Walle -Reported-by: https://buildbot.openwrt.org/master/images/#/builders/56/builds/220/steps/44/logs/stdio -Fixes: 83216e3988cd1 ("of: net: pass the dst buffer to of_get_mac_address()") -Signed-off-by: Daniel Golle ---- - arch/arm/mach-mvebu/kirkwood.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm/mach-mvebu/kirkwood.c b/arch/arm/mach-mvebu/kirkwood.c -index 73b2a86d6489..b375df4010c2 100644 ---- a/arch/arm/mach-mvebu/kirkwood.c -+++ b/arch/arm/mach-mvebu/kirkwood.c -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - #include - #include - #include --- -2.51.0 - - -From 47f8ae989e1a237b33f2e91babea618444b71d42 Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Sat, 5 Nov 2022 20:02:56 +0100 -Subject: [PATCH 310/517] bus: mhi: core: add SBL state callback - -Add support for SBL state callback in MHI core. - -It is required for ath11k MHI devices in order to be able to set QRTR -instance ID in the SBL state so that QRTR instance ID-s dont conflict in -case of multiple PCI/MHI cards or AHB + PCI/MHI card. -Setting QRTR instance ID is only possible in SBL state and there is -currently no way to ensure that we are in that state, so provide a -callback that the controller can trigger off. - -Signed-off-by: Robert Marko ---- - drivers/bus/mhi/host/main.c | 1 + - include/linux/mhi.h | 2 ++ - 2 files changed, 3 insertions(+) - -diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c -index 45ec1b585577..45b28cd4f9b8 100644 ---- a/drivers/bus/mhi/host/main.c -+++ b/drivers/bus/mhi/host/main.c -@@ -916,6 +916,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl, - switch (event) { - case MHI_EE_SBL: - st = DEV_ST_TRANSITION_SBL; -+ mhi_cntrl->status_cb(mhi_cntrl, MHI_CB_EE_SBL_MODE); - break; - case MHI_EE_WFW: - case MHI_EE_AMSS: -diff --git a/include/linux/mhi.h b/include/linux/mhi.h -index 059dc94d20bb..b2f1cf400065 100644 ---- a/include/linux/mhi.h -+++ b/include/linux/mhi.h -@@ -34,6 +34,7 @@ struct mhi_buf_info; - * @MHI_CB_SYS_ERROR: MHI device entered error state (may recover) - * @MHI_CB_FATAL_ERROR: MHI device entered fatal error state - * @MHI_CB_BW_REQ: Received a bandwidth switch request from device -+ * @MHI_CB_EE_SBL_MODE: MHI device entered SBL mode - */ - enum mhi_callback { - MHI_CB_IDLE, -@@ -45,6 +46,7 @@ enum mhi_callback { - MHI_CB_SYS_ERROR, - MHI_CB_FATAL_ERROR, - MHI_CB_BW_REQ, -+ MHI_CB_EE_SBL_MODE, - }; - - /** --- -2.51.0 - - -From e75c28fcf09e756a41d0be9abc31eaa86b8f5ca3 Mon Sep 17 00:00:00 2001 -From: Pavan Chebbi -Date: Tue, 10 Dec 2024 03:28:31 -0800 -Subject: [PATCH 311/517] tg3: Fix DMA allocations on 57766 devices - -The coherent DMA mask of 31b may not be accepted if -the DMA mask is configured to use higher memories of -64b. Set the DMA mask also to lower 32b for 57766 -devices. - -Fixes: 614f4d166eee ("tg3: Set coherent DMA mask bits to 31 for BCM57766 chipsets") -Reported-By: Rui Salvaterra -Signed-off-by: Pavan Chebbi ---- - drivers/net/ethernet/broadcom/tg3.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c -index dc170feee8ad..cf61cb311f23 100644 ---- a/drivers/net/ethernet/broadcom/tg3.c -+++ b/drivers/net/ethernet/broadcom/tg3.c -@@ -17799,8 +17799,10 @@ static int tg3_init_one(struct pci_dev *pdev, - } else - persist_dma_mask = dma_mask = DMA_BIT_MASK(64); - -- if (tg3_asic_rev(tp) == ASIC_REV_57766) -+ if (tg3_asic_rev(tp) == ASIC_REV_57766) { -+ dma_mask = DMA_BIT_MASK(32); - persist_dma_mask = DMA_BIT_MASK(31); -+ } - - /* Configure DMA attributes. */ - if (dma_mask > DMA_BIT_MASK(32)) { --- -2.51.0 - - -From 672489ca59270bcbe18cf959c77b9401292371e4 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Mon, 3 Nov 2025 15:50:09 +0100 -Subject: [PATCH 312/517] bcma: get SoC device struct & copy its DMA params to - the subdevices -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -For bus devices to be fully usable it's required to set their DMA -parameters. - -For years it has been missing and remained unnoticed because of -mips_dma_alloc_coherent() silently handling the empty coherent_dma_mask. -Kernel 4.19 came with a lot of DMA changes and caused a regression on -the bcm47xx. Starting with the commit f8c55dc6e828 ("MIPS: use generic -dma noncoherent ops for simple noncoherent platforms") DMA coherent -allocations just fail. Example: -[ 1.114914] bgmac_bcma bcma0:2: Allocation of TX ring 0x200 failed -[ 1.121215] bgmac_bcma bcma0:2: Unable to alloc memory for DMA -[ 1.127626] bgmac_bcma: probe of bcma0:2 failed with error -12 -[ 1.133838] bgmac_bcma: Broadcom 47xx GBit MAC driver loaded - -This change fixes above regression in addition to the MIPS bcm47xx -commit 321c46b91550 ("MIPS: BCM47XX: Setup struct device for the SoC"). - -It also fixes another *old* GPIO regression caused by a parent pointing -to the NULL: -[ 0.157054] missing gpiochip .dev parent pointer -[ 0.157287] bcma: bus0: Error registering GPIO driver: -22 -introduced by the commit 74f4e0cc6108 ("bcma: switch GPIO portions to -use GPIOLIB_IRQCHIP"). - -Fixes: f8c55dc6e828 ("MIPS: use generic dma noncoherent ops for simple noncoherent platforms") -Fixes: 74f4e0cc6108 ("bcma: switch GPIO portions to use GPIOLIB_IRQCHIP") -Cc: linux-mips@linux-mips.org -Cc: Christoph Hellwig -Cc: Linus Walleij -Signed-off-by: Rafał Miłecki ---- - drivers/bcma/host_soc.c | 2 ++ - drivers/bcma/main.c | 10 +++++++--- - 2 files changed, 9 insertions(+), 3 deletions(-) - -diff --git a/drivers/bcma/host_soc.c b/drivers/bcma/host_soc.c -index 8ae0b918e740..280c2caeaf86 100644 ---- a/drivers/bcma/host_soc.c -+++ b/drivers/bcma/host_soc.c -@@ -191,6 +191,8 @@ int __init bcma_host_soc_init(struct bcma_soc *soc) - struct bcma_bus *bus = &soc->bus; - int err; - -+ bus->dev = soc->dev; -+ - /* Scan bus and initialize it */ - err = bcma_bus_early_register(bus); - if (err) -diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c -index 6ecfc821cf83..6842fe781eef 100644 ---- a/drivers/bcma/main.c -+++ b/drivers/bcma/main.c -@@ -237,13 +237,17 @@ EXPORT_SYMBOL(bcma_core_irq); - - void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core) - { -- device_initialize(&core->dev); -+ struct device *dev = &core->dev; -+ -+ device_initialize(dev); - core->dev.release = bcma_release_core_dev; - core->dev.bus = &bcma_bus_type; -- dev_set_name(&core->dev, "bcma%d:%d", bus->num, core->core_index); -+ dev_set_name(dev, "bcma%d:%d", bus->num, core->core_index); - core->dev.parent = bus->dev; -- if (bus->dev) -+ if (bus->dev) { - bcma_of_fill_device(bus->dev, core); -+ dma_coerce_mask_and_coherent(dev, bus->dev->coherent_dma_mask); -+ } - - switch (bus->hosttype) { - case BCMA_HOSTTYPE_PCI: --- -2.51.0 - - -From cf2b01ee5a6c91e55e54d40ebc0382ba875b19d5 Mon Sep 17 00:00:00 2001 -From: Mauri Sandberg -Date: Thu, 25 Mar 2021 11:48:05 +0200 -Subject: [PATCH 313/517] gpio: gpio-cascade: add generic GPIO cascade - -Adds support for building cascades of GPIO lines. That is, it allows -setups when there is one upstream line and multiple cascaded lines, out -of which one can be chosen at a time. The status of the upstream line -can be conveyed to the selected cascaded line or, vice versa, the status -of the cascaded line can be conveyed to the upstream line. - -A multiplexer is being used to select, which cascaded GPIO line is being -used at any given time. - -At the moment only input direction is supported. In future it should be -possible to add support for output direction, too. - -Signed-off-by: Mauri Sandberg -Reviewed-by: Linus Walleij -Reviewed-by: Andy Shevchenko ---- - drivers/gpio/Kconfig | 15 +++++ - drivers/gpio/Makefile | 1 + - drivers/gpio/gpio-cascade.c | 112 ++++++++++++++++++++++++++++++++++++ - 3 files changed, 128 insertions(+) - create mode 100644 drivers/gpio/gpio-cascade.c - -diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig -index d93cd4f722b4..6c74cafa987e 100644 ---- a/drivers/gpio/Kconfig -+++ b/drivers/gpio/Kconfig -@@ -1929,4 +1929,19 @@ config GPIO_VIRTUSER - - endmenu - -+comment "Other GPIO expanders" -+ -+config GPIO_CASCADE -+ tristate "General GPIO cascade" -+ select MULTIPLEXER -+ help -+ Say yes here to enable support for generic GPIO cascade. -+ -+ This allows building one-to-many cascades of GPIO lines using -+ different types of multiplexers readily available. At the -+ moment only input lines are supported. -+ -+ To build the driver as a module choose 'm' and the resulting module -+ will be called 'gpio-cascade'. -+ - endif -diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile -index 1429e8c0229b..b0c5979fd84e 100644 ---- a/drivers/gpio/Makefile -+++ b/drivers/gpio/Makefile -@@ -45,6 +45,7 @@ obj-$(CONFIG_GPIO_BD9571MWV) += gpio-bd9571mwv.o - obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o - obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o - obj-$(CONFIG_GPIO_CADENCE) += gpio-cadence.o -+obj-$(CONFIG_GPIO_CASCADE) += gpio-cascade.o - obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o - obj-$(CONFIG_GPIO_SNPS_CREG) += gpio-creg-snps.o - obj-$(CONFIG_GPIO_CROS_EC) += gpio-cros-ec.o -diff --git a/drivers/gpio/gpio-cascade.c b/drivers/gpio/gpio-cascade.c -new file mode 100644 -index 000000000000..5fae4f46ecf3 ---- /dev/null -+++ b/drivers/gpio/gpio-cascade.c -@@ -0,0 +1,112 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * A generic GPIO cascade driver -+ * -+ * Copyright (C) 2021 Mauri Sandberg -+ * -+ * This allows building cascades of GPIO lines in a manner illustrated -+ * below: -+ * -+ * /|---- Cascaded GPIO line 0 -+ * Upstream | |---- Cascaded GPIO line 1 -+ * GPIO line ----+ | . -+ * | | . -+ * \|---- Cascaded GPIO line n -+ * -+ * A multiplexer is being used to select, which cascaded line is being -+ * addressed at any given time. -+ * -+ * At the moment only input mode is supported due to lack of means for -+ * testing output functionality. At least theoretically output should be -+ * possible with open drain constructions. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+struct gpio_cascade { -+ struct gpio_chip gpio_chip; -+ struct device *parent; -+ struct mux_control *mux_control; -+ struct gpio_desc *upstream_line; -+}; -+ -+static int gpio_cascade_get_direction(struct gpio_chip *gc, unsigned int offset) -+{ -+ return GPIO_LINE_DIRECTION_IN; -+} -+ -+static int gpio_cascade_get_value(struct gpio_chip *gc, unsigned int offset) -+{ -+ struct gpio_cascade *cas = gpiochip_get_data(gc); -+ int ret; -+ -+ ret = mux_control_select(cas->mux_control, offset); -+ if (ret) -+ return ret; -+ -+ ret = gpiod_get_value(cas->upstream_line); -+ mux_control_deselect(cas->mux_control); -+ return ret; -+} -+ -+static int gpio_cascade_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct gpio_cascade *cas; -+ struct mux_control *mc; -+ struct gpio_desc *upstream; -+ struct gpio_chip *gc; -+ -+ cas = devm_kzalloc(dev, sizeof(*cas), GFP_KERNEL); -+ if (!cas) -+ return -ENOMEM; -+ -+ mc = devm_mux_control_get(dev, NULL); -+ if (IS_ERR(mc)) -+ return dev_err_probe(dev, PTR_ERR(mc), "unable to get mux-control\n"); -+ -+ cas->mux_control = mc; -+ upstream = devm_gpiod_get(dev, "upstream", GPIOD_IN); -+ if (IS_ERR(upstream)) -+ return dev_err_probe(dev, PTR_ERR(upstream), "unable to claim upstream GPIO line\n"); -+ -+ cas->upstream_line = upstream; -+ cas->parent = dev; -+ -+ gc = &cas->gpio_chip; -+ gc->get = gpio_cascade_get_value; -+ gc->get_direction = gpio_cascade_get_direction; -+ gc->base = -1; -+ gc->ngpio = mux_control_states(mc); -+ gc->label = dev_name(cas->parent); -+ gc->parent = cas->parent; -+ gc->owner = THIS_MODULE; -+ -+ platform_set_drvdata(pdev, cas); -+ return devm_gpiochip_add_data(dev, &cas->gpio_chip, cas); -+} -+ -+static const struct of_device_id gpio_cascade_id[] = { -+ { .compatible = "gpio-cascade" }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, gpio_cascade_id); -+ -+static struct platform_driver gpio_cascade_driver = { -+ .driver = { -+ .name = "gpio-cascade", -+ .of_match_table = gpio_cascade_id, -+ }, -+ .probe = gpio_cascade_probe, -+}; -+module_platform_driver(gpio_cascade_driver); -+ -+MODULE_AUTHOR("Mauri Sandberg "); -+MODULE_DESCRIPTION("Generic GPIO cascade"); -+MODULE_LICENSE("GPL"); --- -2.51.0 - - -From 1e797580d94af360372d4ee9b0287b4add407be4 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 15 Sep 2022 18:49:43 +0200 -Subject: [PATCH 314/517] OPP: Provide old opp to config_clks on _set_opp - -With the target opp, also pass the old opp to config_clks function. -This can be useful when a driver needs to take decision on what fequency -to set based on what is the current frequency without using a -clk_get_freq call. -Update the only user of custom config_clks (tegra30 devfreq driver) to -this new implementation. - -Signed-off-by: Christian Marangi ---- - drivers/devfreq/tegra30-devfreq.c | 5 +++-- - drivers/opp/core.c | 11 ++++++----- - drivers/ufs/core/ufshcd.c | 4 ++-- - include/linux/pm_opp.h | 11 ++++++----- - include/ufs/ufshcd.h | 4 ++-- - 5 files changed, 19 insertions(+), 16 deletions(-) - -diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c -index 4a4f0106ab9d..82616eeca6c3 100644 ---- a/drivers/devfreq/tegra30-devfreq.c -+++ b/drivers/devfreq/tegra30-devfreq.c -@@ -823,8 +823,9 @@ static int devm_tegra_devfreq_init_hw(struct device *dev, - - static int tegra_devfreq_config_clks_nop(struct device *dev, - struct opp_table *opp_table, -- struct dev_pm_opp *opp, void *data, -- bool scaling_down) -+ struct dev_pm_opp *old_opp, -+ struct dev_pm_opp *opp, -+ void *data, bool scaling_down) - { - /* We want to skip clk configuration via dev_pm_opp_set_opp() */ - return 0; -diff --git a/drivers/opp/core.c b/drivers/opp/core.c -index 5ac209472c0c..07cfde8119bf 100644 ---- a/drivers/opp/core.c -+++ b/drivers/opp/core.c -@@ -965,7 +965,8 @@ static int _set_opp_voltage(struct device *dev, struct regulator *reg, - - static int - _opp_config_clk_single(struct device *dev, struct opp_table *opp_table, -- struct dev_pm_opp *opp, void *data, bool scaling_down) -+ struct dev_pm_opp *old_opp, struct dev_pm_opp *opp, -+ void *data, bool scaling_down) - { - unsigned long *target = data; - unsigned long freq; -@@ -997,8 +998,8 @@ _opp_config_clk_single(struct device *dev, struct opp_table *opp_table, - * the order in which they are present in the array while scaling up. - */ - int dev_pm_opp_config_clks_simple(struct device *dev, -- struct opp_table *opp_table, struct dev_pm_opp *opp, void *data, -- bool scaling_down) -+ struct opp_table *opp_table, struct dev_pm_opp *old_opp, -+ struct dev_pm_opp *opp, void *data, bool scaling_down) - { - int ret, i; - -@@ -1265,7 +1266,7 @@ static int _set_opp(struct device *dev, struct opp_table *opp_table, - } - - if (opp_table->config_clks) { -- ret = opp_table->config_clks(dev, opp_table, opp, clk_data, scaling_down); -+ ret = opp_table->config_clks(dev, opp_table, old_opp, opp, clk_data, scaling_down); - if (ret) - return ret; - } -@@ -1344,7 +1345,7 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) - * equivalent to a clk_set_rate() - */ - if (!_get_opp_count(opp_table)) { -- ret = opp_table->config_clks(dev, opp_table, NULL, -+ ret = opp_table->config_clks(dev, opp_table, NULL, NULL, - &target_freq, false); - goto put_opp_table; - } -diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c -index e079cb5d9ec6..a700da1d03e5 100644 ---- a/drivers/ufs/core/ufshcd.c -+++ b/drivers/ufs/core/ufshcd.c -@@ -1119,8 +1119,8 @@ static int ufshcd_set_clk_freq(struct ufs_hba *hba, bool scale_up) - } - - int ufshcd_opp_config_clks(struct device *dev, struct opp_table *opp_table, -- struct dev_pm_opp *opp, void *data, -- bool scaling_down) -+ struct dev_pm_opp *old_opp, struct dev_pm_opp *opp, -+ void *data, bool scaling_down) - { - struct ufs_hba *hba = dev_get_drvdata(dev); - struct list_head *head = &hba->clk_list_head; -diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h -index 6424692c30b7..44b50cf91e93 100644 ---- a/include/linux/pm_opp.h -+++ b/include/linux/pm_opp.h -@@ -50,7 +50,8 @@ typedef int (*config_regulators_t)(struct device *dev, - struct dev_pm_opp *old_opp, struct dev_pm_opp *new_opp, - struct regulator **regulators, unsigned int count); - --typedef int (*config_clks_t)(struct device *dev, struct opp_table *opp_table, -+typedef int (*config_clks_t)(struct device *dev, -+ struct opp_table *opp_table, struct dev_pm_opp *old_opp, - struct dev_pm_opp *opp, void *data, bool scaling_down); - - /** -@@ -184,8 +185,8 @@ int dev_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config); - int devm_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config); - void dev_pm_opp_clear_config(int token); - int dev_pm_opp_config_clks_simple(struct device *dev, -- struct opp_table *opp_table, struct dev_pm_opp *opp, void *data, -- bool scaling_down); -+ struct opp_table *opp_table, struct dev_pm_opp *old_opp, -+ struct dev_pm_opp *opp, void *data, bool scaling_down); - - struct dev_pm_opp *dev_pm_opp_xlate_required_opp(struct opp_table *src_table, struct opp_table *dst_table, struct dev_pm_opp *src_opp); - int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate); -@@ -395,8 +396,8 @@ static inline int devm_pm_opp_set_config(struct device *dev, struct dev_pm_opp_c - static inline void dev_pm_opp_clear_config(int token) {} - - static inline int dev_pm_opp_config_clks_simple(struct device *dev, -- struct opp_table *opp_table, struct dev_pm_opp *opp, void *data, -- bool scaling_down) -+ struct opp_table *opp_table, struct dev_pm_opp *old_opp, -+ struct dev_pm_opp *opp, void *data, bool scaling_down) - { - return -EOPNOTSUPP; - } -diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h -index 47cba116f87b..a303f853acf0 100644 ---- a/include/ufs/ufshcd.h -+++ b/include/ufs/ufshcd.h -@@ -1326,8 +1326,8 @@ void ufshcd_mcq_enable(struct ufs_hba *hba); - void ufshcd_mcq_config_esi(struct ufs_hba *hba, struct msi_msg *msg); - - int ufshcd_opp_config_clks(struct device *dev, struct opp_table *opp_table, -- struct dev_pm_opp *opp, void *data, -- bool scaling_down); -+ struct dev_pm_opp *old_opp, struct dev_pm_opp *opp, -+ void *data, bool scaling_down); - /** - * ufshcd_set_variant - set variant specific data to the hba - * @hba: per adapter instance --- -2.51.0 - - -From af475ef6d3d0d36054adbf764810eafc2d0e3ef7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Thu, 13 Jul 2023 18:29:19 +0200 -Subject: [PATCH 315/517] nvmem: core: support "mac-base" fixed layout cells - -Fixed layout binding allows specifying "mac-base" NVMEM cells. It's used -for base MAC address (that can be used for calculating relative -addresses). It can be stored in a raw binary format or as an ASCII -string. ---- - drivers/nvmem/Kconfig | 1 + - drivers/nvmem/core.c | 78 +++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 79 insertions(+) - -diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig -index 40b5fd1bfde4..51257aa2cd3e 100644 ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -2,6 +2,7 @@ - menuconfig NVMEM - bool "NVMEM Support" - imply NVMEM_LAYOUTS -+ select GENERIC_NET_UTILS - help - Support for NVMEM(Non Volatile Memory) devices like EEPROM, EFUSES... - -diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c -index d1869e6de384..f978adbc5fff 100644 ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -7,9 +7,12 @@ - */ - - #include -+#include -+#include - #include - #include - #include -+#include - #include - #include - #include -@@ -811,6 +814,62 @@ static int nvmem_validate_keepouts(struct nvmem_device *nvmem) - return 0; - } - -+static int nvmem_mac_base_raw_read(void *context, const char *id, int index, unsigned int offset, -+ void *buf, size_t bytes) -+{ -+ if (WARN_ON(bytes != ETH_ALEN)) -+ return -EINVAL; -+ -+ if (index) -+ eth_addr_add(buf, index); -+ -+ return 0; -+} -+ -+static int nvmem_mac_base_ascii_read(void *context, const char *id, int index, unsigned int offset, -+ void *buf, size_t bytes) -+{ -+ u8 mac[ETH_ALEN]; -+ -+ if (WARN_ON(bytes != 3 * ETH_ALEN - 1)) -+ return -EINVAL; -+ -+ if (!mac_pton(buf, mac)) -+ return -EINVAL; -+ -+ if (index) -+ eth_addr_add(mac, index); -+ -+ ether_addr_copy(buf, mac); -+ -+ return 0; -+} -+ -+static int nvmem_mac_base_hex_read(void *context, const char *id, int index, unsigned int offset, -+ void *buf, size_t bytes) -+{ -+ u8 mac[ETH_ALEN], *hexstr; -+ int i; -+ -+ if (WARN_ON(bytes != 2 * ETH_ALEN)) -+ return -EINVAL; -+ -+ hexstr = (u8 *)buf; -+ for (i = 0; i < ETH_ALEN; i++) { -+ if (!isxdigit(hexstr[i * 2]) || !isxdigit(hexstr[i * 2 + 1])) -+ return -EINVAL; -+ -+ mac[i] = (hex_to_bin(hexstr[i * 2]) << 4) | hex_to_bin(hexstr[i * 2 + 1]); -+ } -+ -+ if (index) -+ eth_addr_add(mac, index); -+ -+ ether_addr_copy(buf, mac); -+ -+ return 0; -+} -+ - static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np) - { - struct device *dev = &nvmem->dev; -@@ -852,6 +911,25 @@ static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_nod - if (nvmem->fixup_dt_cell_info) - nvmem->fixup_dt_cell_info(nvmem, &info); - -+ if (of_device_is_compatible(np, "fixed-layout")) { -+ if (of_device_is_compatible(child, "mac-base")) { -+ if (info.bytes == ETH_ALEN) { -+ info.raw_len = info.bytes; -+ info.bytes = ETH_ALEN; -+ info.read_post_process = nvmem_mac_base_raw_read; -+ } else if (info.bytes == 2 * ETH_ALEN) { -+ info.raw_len = info.bytes; -+ info.bytes = ETH_ALEN; -+ info.read_post_process = nvmem_mac_base_hex_read; -+ } else if (info.bytes == 3 * ETH_ALEN - 1) { -+ info.raw_len = info.bytes; -+ info.bytes = ETH_ALEN; -+ info.read_post_process = nvmem_mac_base_ascii_read; -+ } -+ -+ } -+ } -+ - ret = nvmem_add_one_cell(nvmem, &info); - kfree(info.name); - if (ret) { --- -2.51.0 - - -From 38d604ad64b2a28e0d8560c01e741c2aada79bc8 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 3 Feb 2025 00:10:18 +0100 -Subject: [PATCH 316/517] nvmem: core: generalize "mac-base" cells handling - -Generalize support of "mac-base" nvmem cells and provide a GPL symbol to -permit also other NVMEM layout driver to parse mac-base cells. - -It's VERY COMMON for some specially formatted NVMEM to expose a mac -address in ASCII format or HEX format hence prevent code duplication by -exposing a common helper. - -Such helper will change the nvmem_info_cell and apply the correct post -process function to correctly parse the mac address. - -Since the API requires OF and is only related to layout, move the -function in layouts.c to correctly handle non-OF NVMEM. - -Signed-off-by: Christian Marangi ---- - drivers/nvmem/core.c | 79 +-------------------------------- - drivers/nvmem/layouts.c | 80 ++++++++++++++++++++++++++++++++++ - include/linux/nvmem-provider.h | 4 ++ - 3 files changed, 86 insertions(+), 77 deletions(-) - -diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c -index f978adbc5fff..9b9177e28706 100644 ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -7,12 +7,9 @@ - */ - - #include --#include --#include - #include - #include - #include --#include - #include - #include - #include -@@ -814,62 +811,6 @@ static int nvmem_validate_keepouts(struct nvmem_device *nvmem) - return 0; - } - --static int nvmem_mac_base_raw_read(void *context, const char *id, int index, unsigned int offset, -- void *buf, size_t bytes) --{ -- if (WARN_ON(bytes != ETH_ALEN)) -- return -EINVAL; -- -- if (index) -- eth_addr_add(buf, index); -- -- return 0; --} -- --static int nvmem_mac_base_ascii_read(void *context, const char *id, int index, unsigned int offset, -- void *buf, size_t bytes) --{ -- u8 mac[ETH_ALEN]; -- -- if (WARN_ON(bytes != 3 * ETH_ALEN - 1)) -- return -EINVAL; -- -- if (!mac_pton(buf, mac)) -- return -EINVAL; -- -- if (index) -- eth_addr_add(mac, index); -- -- ether_addr_copy(buf, mac); -- -- return 0; --} -- --static int nvmem_mac_base_hex_read(void *context, const char *id, int index, unsigned int offset, -- void *buf, size_t bytes) --{ -- u8 mac[ETH_ALEN], *hexstr; -- int i; -- -- if (WARN_ON(bytes != 2 * ETH_ALEN)) -- return -EINVAL; -- -- hexstr = (u8 *)buf; -- for (i = 0; i < ETH_ALEN; i++) { -- if (!isxdigit(hexstr[i * 2]) || !isxdigit(hexstr[i * 2 + 1])) -- return -EINVAL; -- -- mac[i] = (hex_to_bin(hexstr[i * 2]) << 4) | hex_to_bin(hexstr[i * 2 + 1]); -- } -- -- if (index) -- eth_addr_add(mac, index); -- -- ether_addr_copy(buf, mac); -- -- return 0; --} -- - static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np) - { - struct device *dev = &nvmem->dev; -@@ -911,24 +852,8 @@ static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_nod - if (nvmem->fixup_dt_cell_info) - nvmem->fixup_dt_cell_info(nvmem, &info); - -- if (of_device_is_compatible(np, "fixed-layout")) { -- if (of_device_is_compatible(child, "mac-base")) { -- if (info.bytes == ETH_ALEN) { -- info.raw_len = info.bytes; -- info.bytes = ETH_ALEN; -- info.read_post_process = nvmem_mac_base_raw_read; -- } else if (info.bytes == 2 * ETH_ALEN) { -- info.raw_len = info.bytes; -- info.bytes = ETH_ALEN; -- info.read_post_process = nvmem_mac_base_hex_read; -- } else if (info.bytes == 3 * ETH_ALEN - 1) { -- info.raw_len = info.bytes; -- info.bytes = ETH_ALEN; -- info.read_post_process = nvmem_mac_base_ascii_read; -- } -- -- } -- } -+ if (of_device_is_compatible(np, "fixed-layout")) -+ nvmem_layout_parse_mac_base(&info); - - ret = nvmem_add_one_cell(nvmem, &info); - kfree(info.name); -diff --git a/drivers/nvmem/layouts.c b/drivers/nvmem/layouts.c -index f381ce1e84bd..3220cd20c33a 100644 ---- a/drivers/nvmem/layouts.c -+++ b/drivers/nvmem/layouts.c -@@ -6,8 +6,11 @@ - * Author: Miquel Raynal - #include - #include -+#include -+#include - #include - #include - #include -@@ -21,6 +24,83 @@ - #define to_nvmem_layout_device(_dev) \ - container_of((_dev), struct nvmem_layout, dev) - -+static int nvmem_mac_base_raw_read(void *context, const char *id, int index, unsigned int offset, -+ void *buf, size_t bytes) -+{ -+ if (WARN_ON(bytes != ETH_ALEN)) -+ return -EINVAL; -+ -+ if (index) -+ eth_addr_add(buf, index); -+ -+ return 0; -+} -+ -+static int nvmem_mac_base_ascii_read(void *context, const char *id, int index, unsigned int offset, -+ void *buf, size_t bytes) -+{ -+ u8 mac[ETH_ALEN]; -+ -+ if (WARN_ON(bytes != 3 * ETH_ALEN - 1)) -+ return -EINVAL; -+ -+ if (!mac_pton(buf, mac)) -+ return -EINVAL; -+ -+ if (index) -+ eth_addr_add(mac, index); -+ -+ ether_addr_copy(buf, mac); -+ -+ return 0; -+} -+ -+static int nvmem_mac_base_hex_read(void *context, const char *id, int index, unsigned int offset, -+ void *buf, size_t bytes) -+{ -+ u8 mac[ETH_ALEN], *hexstr; -+ int i; -+ -+ if (WARN_ON(bytes != 2 * ETH_ALEN)) -+ return -EINVAL; -+ -+ hexstr = (u8 *)buf; -+ for (i = 0; i < ETH_ALEN; i++) { -+ if (!isxdigit(hexstr[i * 2]) || !isxdigit(hexstr[i * 2 + 1])) -+ return -EINVAL; -+ -+ mac[i] = (hex_to_bin(hexstr[i * 2]) << 4) | hex_to_bin(hexstr[i * 2 + 1]); -+ } -+ -+ if (index) -+ eth_addr_add(mac, index); -+ -+ ether_addr_copy(buf, mac); -+ -+ return 0; -+} -+ -+void nvmem_layout_parse_mac_base(struct nvmem_cell_info *info) -+{ -+ if (!of_device_is_compatible(info->np, "mac-base")) -+ return; -+ -+ if (info->bytes == ETH_ALEN) { -+ info->raw_len = info->bytes; -+ info->bytes = ETH_ALEN; -+ info->read_post_process = nvmem_mac_base_raw_read; -+ } else if (info->bytes == 2 * ETH_ALEN) { -+ info->raw_len = info->bytes; -+ info->bytes = ETH_ALEN; -+ info->read_post_process = nvmem_mac_base_hex_read; -+ } else if (info->bytes == 3 * ETH_ALEN - 1) { -+ info->raw_len = info->bytes; -+ info->bytes = ETH_ALEN; -+ info->read_post_process = nvmem_mac_base_ascii_read; -+ } -+} -+EXPORT_SYMBOL_GPL(nvmem_layout_parse_mac_base); -+ - static int nvmem_layout_bus_match(struct device *dev, const struct device_driver *drv) - { - return of_driver_match_device(dev, drv); -diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h -index 3ebeaa0ded00..97698b898dcf 100644 ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -242,6 +242,8 @@ static inline void nvmem_layout_unregister(struct nvmem_layout *layout) {} - - #if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF) - -+void nvmem_layout_parse_mac_base(struct nvmem_cell_info *info); -+ - /** - * of_nvmem_layout_get_container() - Get OF node of layout container - * -@@ -254,6 +256,8 @@ struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem); - - #else /* CONFIG_NVMEM && CONFIG_OF */ - -+static inline void nvmem_layout_parse_mac_base(struct nvmem_cell_info *info) {} -+ - static inline struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem) - { - return NULL; --- -2.51.0 - - -From c7d5b37e95ce1865a1c04a2d863966379f13b7fb Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 3 Feb 2025 00:36:12 +0100 -Subject: [PATCH 317/517] nvmem: layouts: add support for ascii-env driver - -Add support for simple ASCII envirorment driver for NVMEM layouts. - -It's very common for devices to store simple text file format in -partition for environment varibles. The most common pattern is variable -name, a delimiter and variable value all separated by a new line -character (\n). - -This driver adds support for exporting such data and expose NVMEM cells -so they can be referenced by other drivers. This driver also supports -parsing mac-base NVMEM cells to parse ASCII or HEX mac address. - -Signed-off-by: Christian Marangi ---- - drivers/nvmem/layouts/Kconfig | 13 +++ - drivers/nvmem/layouts/Makefile | 1 + - drivers/nvmem/layouts/ascii-env.c | 148 ++++++++++++++++++++++++++++++ - 3 files changed, 162 insertions(+) - create mode 100644 drivers/nvmem/layouts/ascii-env.c - -diff --git a/drivers/nvmem/layouts/Kconfig b/drivers/nvmem/layouts/Kconfig -index 5e586dfebe47..58df4ad61e13 100644 ---- a/drivers/nvmem/layouts/Kconfig -+++ b/drivers/nvmem/layouts/Kconfig -@@ -37,6 +37,19 @@ config NVMEM_LAYOUT_U_BOOT_ENV - - If unsure, say N. - -+config NVMEM_LAYOUT_ASCII_ENV -+ tristate "ASCII environment variables layout" -+ help -+ It's very common for devices to store simple text file format in -+ partition for environment varibles. The most common pattern is variable -+ name, a delimiter and variable value all separated by a new line -+ character (\n). -+ This driver adds support for exporting such data and expose NVMEM cells -+ so they can be referenced by other drivers. This driver also supports -+ parsing mac-base NVMEM cells to parse ASCII or HEX mac address. -+ -+ If unsure, say N. -+ - endmenu - - endif -diff --git a/drivers/nvmem/layouts/Makefile b/drivers/nvmem/layouts/Makefile -index 4940c9db0665..060ddf18d05a 100644 ---- a/drivers/nvmem/layouts/Makefile -+++ b/drivers/nvmem/layouts/Makefile -@@ -6,3 +6,4 @@ - obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o - obj-$(CONFIG_NVMEM_LAYOUT_ONIE_TLV) += onie-tlv.o - obj-$(CONFIG_NVMEM_LAYOUT_U_BOOT_ENV) += u-boot-env.o -+obj-$(CONFIG_NVMEM_LAYOUT_ASCII_ENV) += ascii-env.o -diff --git a/drivers/nvmem/layouts/ascii-env.c b/drivers/nvmem/layouts/ascii-env.c -new file mode 100644 -index 000000000000..491fcfd3a501 ---- /dev/null -+++ b/drivers/nvmem/layouts/ascii-env.c -@@ -0,0 +1,148 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (C) 2024 Christian Marangi -+ * -+ * This borrow some parse logic from u-boot-env. -+ */ -+#include -+#include -+#include -+#include -+ -+struct ascii_env_match_data { -+ const char delim; -+}; -+ -+/* -+ * Parse a buffer as an ASCII text with name delimiter value and each pattern separated -+ * with a new line char '\n' -+ * Example: (delimiter '=') -+ * name=value\nname2=value2\n -+ * 2 Cell: -+ * - name: value -+ * - name2: value2 -+ */ -+static int ascii_env_parse_cells(struct device *dev, struct nvmem_device *nvmem, uint8_t *buf, -+ size_t data_len, const char delim) -+{ -+ char *var, *value, *eq, *lf; -+ char *data = buf; -+ -+ /* -+ * Warning the inner loop take care of replacing '\n' -+ * with '\0', hence we can use strlen on value. -+ */ -+ for (var = data; var < data + data_len && *var; -+ var = value + strlen(value) + 1) { -+ struct nvmem_cell_info info = {}; -+ struct device_node *child; -+ const char *label; -+ -+ eq = strchr(var, delim); -+ if (!eq) -+ break; -+ *eq = '\0'; -+ value = eq + 1; -+ -+ /* Replace '\n' with '\0' to use strlen for value */ -+ lf = strchr(value, '\n'); -+ if (!lf) -+ break; -+ *lf = '\0'; -+ -+ info.name = devm_kstrdup(dev, var, GFP_KERNEL); -+ if (!info.name) -+ return -ENOMEM; -+ info.offset = value - data; -+ info.bytes = strlen(value); -+ info.np = of_get_child_by_name(dev->of_node, info.name); -+ for_each_child_of_node(dev->of_node, child) { -+ if (!of_property_read_string(child, "label", &label) && -+ !strncmp(info.name, label, info.bytes)) -+ info.np = child; -+ else if (of_node_name_eq(child, info.name)) -+ info.np = child; -+ } -+ -+ nvmem_layout_parse_mac_base(&info); -+ -+ nvmem_add_one_cell(nvmem, &info); -+ } -+ -+ return 0; -+} -+ -+static int ascii_env_add_cells(struct nvmem_layout *layout) -+{ -+ struct nvmem_device *nvmem = layout->nvmem; -+ const struct ascii_env_match_data *data; -+ struct device *dev = &layout->dev; -+ size_t dev_size; -+ uint8_t *buf; -+ int bytes; -+ int ret; -+ -+ /* Get the delimiter for name value pattern */ -+ data = device_get_match_data(dev); -+ -+ dev_size = nvmem_dev_size(nvmem); -+ -+ buf = kzalloc(dev_size, GFP_KERNEL); -+ if (!buf) { -+ ret = -ENOMEM; -+ goto err_out; -+ } -+ -+ bytes = nvmem_device_read(nvmem, 0, dev_size, buf); -+ if (bytes < 0) { -+ ret = bytes; -+ goto err_kfree; -+ } else if (bytes != dev_size) { -+ ret = -EIO; -+ goto err_kfree; -+ } -+ -+ buf[dev_size - 1] = '\0'; -+ ret = ascii_env_parse_cells(dev, nvmem, buf, dev_size, data->delim); -+ -+err_kfree: -+ kfree(buf); -+err_out: -+ return ret; -+} -+ -+static int ascii_env_probe(struct nvmem_layout *layout) -+{ -+ layout->add_cells = ascii_env_add_cells; -+ -+ return nvmem_layout_register(layout); -+} -+ -+static void ascii_env_remove(struct nvmem_layout *layout) -+{ -+ nvmem_layout_unregister(layout); -+} -+ -+static const struct ascii_env_match_data ascii_env_eq = { -+ .delim = '=', -+}; -+ -+static const struct of_device_id ascii_env_of_match_table[] = { -+ { .compatible = "ascii-eq-delim-env", .data = &ascii_env_eq, }, -+ {}, -+}; -+ -+static struct nvmem_layout_driver ascii_env_layout = { -+ .driver = { -+ .name = "ascii-env-layout", -+ .of_match_table = ascii_env_of_match_table, -+ }, -+ .probe = ascii_env_probe, -+ .remove = ascii_env_remove, -+}; -+module_nvmem_layout_driver(ascii_env_layout); -+ -+MODULE_AUTHOR("Christian Marangi "); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(of, ascii_env_of_match_table); -+MODULE_DESCRIPTION("NVMEM layout driver for ASCII environment variables"); --- -2.51.0 - - -From 773d9fc4bc823e602c25cb93786fd38bc9bfd9ac Mon Sep 17 00:00:00 2001 -From: George Moussalem -Date: Thu, 6 Feb 2025 21:55:28 +0400 -Subject: [PATCH 318/517] nvmem: layouts: ascii-env handle CRLF while parsing - -The current driver supports LF line endings only. - -For CRLF-based line endings in the ASCII env, the length of the value of -the variable passed to nvmem_layout_parse_mac_base is 18 bytes instead -of an expected length of 17 causing the parsing to fail. -So, let's add the ability to handle CRLF line endings by adding a -condition to check if the value ends with a '\r' character and replace it -with '\0' to properly parse the mac address. - -Tested on Linksys MX2000, MX5500, and SPNMX56. - -Signed-off-by: George Moussalem ---- - drivers/nvmem/layouts/ascii-env.c | 15 +++++++++++++-- - 1 file changed, 13 insertions(+), 2 deletions(-) - -diff --git a/drivers/nvmem/layouts/ascii-env.c b/drivers/nvmem/layouts/ascii-env.c -index 491fcfd3a501..119bfc2b26f7 100644 ---- a/drivers/nvmem/layouts/ascii-env.c -+++ b/drivers/nvmem/layouts/ascii-env.c -@@ -25,18 +25,20 @@ struct ascii_env_match_data { - static int ascii_env_parse_cells(struct device *dev, struct nvmem_device *nvmem, uint8_t *buf, - size_t data_len, const char delim) - { -- char *var, *value, *eq, *lf; -+ char *var, *value, *eq, *lf, *cr; - char *data = buf; -+ uint incr = 0; - - /* - * Warning the inner loop take care of replacing '\n' - * with '\0', hence we can use strlen on value. - */ - for (var = data; var < data + data_len && *var; -- var = value + strlen(value) + 1) { -+ var = value + strlen(value) + incr) { - struct nvmem_cell_info info = {}; - struct device_node *child; - const char *label; -+ incr = 0; - - eq = strchr(var, delim); - if (!eq) -@@ -49,6 +51,15 @@ static int ascii_env_parse_cells(struct device *dev, struct nvmem_device *nvmem, - if (!lf) - break; - *lf = '\0'; -+ incr++; -+ -+ /* For CRLF based env, replace '\r' with '\0' too to use strlen -+ * for value, and increment var by one in loop for next variable */ -+ cr = strchr(value, '\r'); -+ if (cr) { -+ *cr = '\0'; -+ incr++; -+ } - - info.name = devm_kstrdup(dev, var, GFP_KERNEL); - if (!info.name) --- -2.51.0 - - -From baede361c7b81acf63a533c25fe10c05b5116cf4 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Mon, 3 Nov 2025 15:50:11 +0100 -Subject: [PATCH 319/517] debloat: add kernel config option to disabling common - PCI quirks - -Signed-off-by: Gabor Juhos ---- - drivers/pci/Kconfig | 7 +++++++ - drivers/pci/quirks.c | 7 +++++++ - 2 files changed, 14 insertions(+) - -diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig -index 7cef00d9d7ab..6b458cba5c2f 100644 ---- a/drivers/pci/Kconfig -+++ b/drivers/pci/Kconfig -@@ -118,6 +118,13 @@ config XEN_PCIDEV_FRONTEND - The PCI device frontend driver allows the kernel to import arbitrary - PCI devices from a PCI backend to support PCI driver domains. - -+config PCI_DISABLE_COMMON_QUIRKS -+ bool "PCI disable common quirks" -+ depends on PCI -+ help -+ If you don't know what to do here, say N. -+ -+ - config PCI_ATS - bool - -diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c -index db609d26811b..26e7a21a5ee7 100644 ---- a/drivers/pci/quirks.c -+++ b/drivers/pci/quirks.c -@@ -313,6 +313,7 @@ static void quirk_mmio_always_on(struct pci_dev *dev) - DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_ANY_ID, PCI_ANY_ID, - PCI_CLASS_BRIDGE_HOST, 8, quirk_mmio_always_on); - -+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS - /* - * The Mellanox Tavor device gives false positive parity errors. Disable - * parity error reporting. -@@ -3508,6 +3509,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65f8, quirk_intel_mc_errata); - DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65f9, quirk_intel_mc_errata); - DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65fa, quirk_intel_mc_errata); - -+#endif /* !CONFIG_PCI_DISABLE_COMMON_QUIRKS */ -+ - /* - * Ivytown NTB BAR sizes are misreported by the hardware due to an erratum. - * To work around this, query the size it should be configured to by the -@@ -3533,6 +3536,8 @@ static void quirk_intel_ntb(struct pci_dev *dev) - DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0e08, quirk_intel_ntb); - DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0e0d, quirk_intel_ntb); - -+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS -+ - /* - * Some BIOS implementations leave the Intel GPU interrupts enabled, even - * though no one is handling them (e.g., if the i915 driver is never -@@ -3571,6 +3576,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0106, disable_igfx_irq); - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq); - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0152, disable_igfx_irq); - -+#endif /* !CONFIG_PCI_DISABLE_COMMON_QUIRKS */ -+ - /* - * PCI devices which are on Intel chips can skip the 10ms delay - * before entering D3 mode. --- -2.51.0 - - -From 5ba95a2dade8bae2429b2e6de0d7eed0e7819c7d Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Sat, 26 Apr 2025 21:10:40 +0200 -Subject: [PATCH 320/517] debloat: disable common USB quirks - -Signed-off-by: Felix Fietkau ---- - drivers/usb/host/pci-quirks.c | 7 +++++++ - drivers/usb/host/pci-quirks.h | 4 ++++ - 2 files changed, 11 insertions(+) - -diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c -index 0404489c2f6a..362d347b5982 100644 ---- a/drivers/usb/host/pci-quirks.c -+++ b/drivers/usb/host/pci-quirks.c -@@ -590,6 +590,7 @@ bool usb_amd_pt_check_port(struct device *device, int port) - EXPORT_SYMBOL_GPL(usb_amd_pt_check_port); - #endif /* CONFIG_USB_PCI_AMD */ - -+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS - static int usb_asmedia_wait_write(struct pci_dev *pdev) - { - unsigned long retry_count; -@@ -642,6 +643,7 @@ static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask) - } - - #define mmio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_MEMORY) -+#endif /* !CONFIG_PCI_DISABLE_COMMON_QUIRKS */ - - #if defined(CONFIG_HAS_IOPORT) && IS_ENABLED(CONFIG_USB_UHCI_HCD) - /* -@@ -724,6 +726,10 @@ int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base) - return 1; - } - EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc); -+#endif -+ -+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS -+#if defined(CONFIG_HAS_IOPORT) && IS_ENABLED(CONFIG_USB_UHCI_HCD) - - #define pio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_IO) - -@@ -1304,3 +1310,4 @@ static void quirk_usb_early_handoff(struct pci_dev *pdev) - } - DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID, - PCI_CLASS_SERIAL_USB, 8, quirk_usb_early_handoff); -+#endif /* !CONFIG_PCI_DISABLE_COMMON_QUIRKS */ -diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h -index a5230b0b9e91..9cc969a3b352 100644 ---- a/drivers/usb/host/pci-quirks.h -+++ b/drivers/usb/host/pci-quirks.h -@@ -38,12 +38,16 @@ static inline bool usb_amd_pt_check_port(struct device *device, int port) - #ifdef CONFIG_USB_PCI - void uhci_reset_hc(struct pci_dev *pdev, unsigned long base); - int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base); -+#endif -+ -+#if defined(CONFIG_USB_PCI) && !defined(CONFIG_PCI_DISABLE_COMMON_QUIRKS) - void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev); - void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev); - void usb_disable_xhci_ports(struct pci_dev *xhci_pdev); - #else - struct pci_dev; - static inline void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev) {} -+static inline void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev) {} - static inline void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) {} - #endif /* CONFIG_USB_PCI */ - --- -2.51.0 - - -From 922d037dad402d02ba7937afa88740db3487d89b Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 13 Oct 2025 20:45:25 +0200 -Subject: [PATCH 321/517] PCI/sysfs: enforce single creation of sysfs entry for - pdev -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -In some specific scenario it's possible that the -pci_create_resource_files() gets called multiple times and the created -entry actually gets wrongly deleted with extreme case of having a NULL -pointer dereference when the PCI is removed. - -This mainly happen due to bad timing where the PCI bus is adding PCI -devices and at the same time the sysfs code is adding the entry causing -double execution of the pci_create_resource_files function and kernel -WARNING. - -To be more precise there is a race between the late_initcall of -pci-sysfs with pci_sysfs_init and PCI bus.c pci_bus_add_device that also -call pci_create_sysfs_dev_files. - -With correct amount of ""luck"" (or better say bad luck) -pci_create_sysfs_dev_files in bus.c might be called with pci_sysfs_init -is executing the loop. - -This has been reported multiple times and on multiple system, like imx6 -system, ipq806x systems... - -To address this, imlement multiple improvement to the implementation: -1. Add a bool to pci_dev to flag when sysfs entry are created - (sysfs_init) -2. Implement a simple completion to wait pci_sysfs_init execution. -3. Permit additional call of pci_create_sysfs_dev_files only after - pci_sysfs_init has finished. - -With such logic in place, we address al kind of timing problem with -minimal change to any driver. - -A notice worth to mention is that the remove function are not affected -by this as the pci_remove_resource_files have enough check in place to -always work and it's always called by pci_stop_dev. - -Cc: stable@vger.kernel.org -Reported-by: Krzysztof Hałasa -Closes: https://bugzilla.kernel.org/show_bug.cgi?id=215515 -Signed-off-by: Christian Marangi ---- - drivers/pci/pci-sysfs.c | 34 +++++++++++++++++++++++++++++----- - include/linux/pci.h | 1 + - 2 files changed, 30 insertions(+), 5 deletions(-) - -diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c -index 96f9cf9f8d64..85440b4312e5 100644 ---- a/drivers/pci/pci-sysfs.c -+++ b/drivers/pci/pci-sysfs.c -@@ -13,6 +13,7 @@ - */ - - #include -+#include - #include - #include - #include -@@ -36,6 +37,7 @@ - #endif - - static int sysfs_initialized; /* = 0 */ -+static DECLARE_COMPLETION(sysfs_init_completion); - - /* show configuration fields */ - #define pci_config_attr(field, format_string) \ -@@ -1551,12 +1553,32 @@ static const struct attribute_group pci_dev_resource_resize_group = { - .is_visible = resource_resize_is_visible, - }; - -+static int __pci_create_sysfs_dev_files(struct pci_dev *pdev) -+{ -+ int ret; -+ -+ ret = pci_create_resource_files(pdev); -+ if (ret) -+ return ret; -+ -+ /* on success set sysfs correctly created */ -+ pdev->sysfs_init = true; -+ return 0; -+} -+ - int __must_check pci_create_sysfs_dev_files(struct pci_dev *pdev) - { - if (!sysfs_initialized) - return -EACCES; - -- return pci_create_resource_files(pdev); -+ /* sysfs entry already created */ -+ if (pdev->sysfs_init) -+ return 0; -+ -+ /* wait for pci_sysfs_init */ -+ wait_for_completion(&sysfs_init_completion); -+ -+ return __pci_create_sysfs_dev_files(pdev); - } - - /** -@@ -1577,21 +1599,23 @@ static int __init pci_sysfs_init(void) - { - struct pci_dev *pdev = NULL; - struct pci_bus *pbus = NULL; -- int retval; -+ int retval = 0; - - sysfs_initialized = 1; - for_each_pci_dev(pdev) { -- retval = pci_create_sysfs_dev_files(pdev); -+ retval = __pci_create_sysfs_dev_files(pdev); - if (retval) { - pci_dev_put(pdev); -- return retval; -+ goto exit; - } - } - - while ((pbus = pci_find_next_bus(pbus))) - pci_create_legacy_files(pbus); - -- return 0; -+exit: -+ complete_all(&sysfs_init_completion); -+ return retval; - } - late_initcall(pci_sysfs_init); - -diff --git a/include/linux/pci.h b/include/linux/pci.h -index 452a3dca28ea..2c3758975d35 100644 ---- a/include/linux/pci.h -+++ b/include/linux/pci.h -@@ -484,6 +484,7 @@ struct pci_dev { - unsigned int rom_attr_enabled:1; /* Display of ROM attribute enabled? */ - pci_dev_flags_t dev_flags; - atomic_t enable_cnt; /* pci_enable_device has been called */ -+ bool sysfs_init; /* sysfs entry has been created */ - - spinlock_t pcie_cap_lock; /* Protects RMW ops in capability accessors */ - u32 saved_config_space[16]; /* Config space saved at suspend time */ --- -2.51.0 - - -From ddc0f7fa795c53ea0c7728a6fabf718eead7aedd Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Nov 2025 15:50:12 +0100 -Subject: [PATCH 322/517] libata: add ledtrig support - -This adds a LED trigger for each ATA port indicating disk activity. - -As this is needed only on specific platforms (NAS SoCs and such), -these platforms should define ARCH_WANTS_LIBATA_LEDS if there -are boards with LED(s) intended to indicate ATA disk activity and -need the OS to take care of that. -In that way, if not selected, LED trigger support not will be -included in libata-core and both, codepaths and structures remain -untouched. - -Signed-off-by: Daniel Golle ---- - drivers/ata/Kconfig | 16 ++++++++++++++++ - drivers/ata/libata-core.c | 39 +++++++++++++++++++++++++++++++++++++++ - include/linux/libata.h | 7 +++++++ - 3 files changed, 62 insertions(+) - -diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig -index 120a2b7067fc..9f7d5609a577 100644 ---- a/drivers/ata/Kconfig -+++ b/drivers/ata/Kconfig -@@ -67,6 +67,22 @@ config ATA_FORCE - - If unsure, say Y. - -+config ARCH_WANT_LIBATA_LEDS -+ bool -+ -+config ATA_LEDS -+ bool "support ATA port LED triggers" -+ depends on ARCH_WANT_LIBATA_LEDS -+ select NEW_LEDS -+ select LEDS_CLASS -+ select LEDS_TRIGGERS -+ default y -+ help -+ This option adds a LED trigger for each registered ATA port. -+ It is used to drive disk activity leds connected via GPIO. -+ -+ If unsure, say N. -+ - config ATA_ACPI - bool "ATA ACPI Support" - depends on ACPI -diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c -index 0cb97181d10a..faf86008348c 100644 ---- a/drivers/ata/libata-core.c -+++ b/drivers/ata/libata-core.c -@@ -703,6 +703,17 @@ static inline void ata_set_tf_cdl(struct ata_queued_cmd *qc, int cdl) - qc->flags |= ATA_QCFLAG_HAS_CDL | ATA_QCFLAG_RESULT_TF; - } - -+#ifdef CONFIG_ATA_LEDS -+#define LIBATA_BLINK_DELAY 20 /* ms */ -+static inline void ata_led_act(struct ata_port *ap) -+{ -+ if (unlikely(!ap->ledtrig)) -+ return; -+ -+ led_trigger_blink_oneshot(ap->ledtrig, LIBATA_BLINK_DELAY, LIBATA_BLINK_DELAY, 0); -+} -+#endif -+ - /** - * ata_build_rw_tf - Build ATA taskfile for given read/write request - * @qc: Metadata associated with the taskfile to build -@@ -4767,6 +4778,9 @@ void __ata_qc_complete(struct ata_queued_cmd *qc) - link->active_tag = ATA_TAG_POISON; - ap->nr_active_links--; - } -+#ifdef CONFIG_ATA_LEDS -+ ata_led_act(ap); -+#endif - - /* clear exclusive status */ - if (unlikely(qc->flags & ATA_QCFLAG_CLEAR_EXCL && -@@ -5488,6 +5502,9 @@ struct ata_port *ata_port_alloc(struct ata_host *host) - #ifdef ATA_IRQ_TRAP - ap->stats.unhandled_irq = 1; - ap->stats.idle_irq = 1; -+#endif -+#ifdef CONFIG_ATA_LEDS -+ ap->ledtrig = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); - #endif - ata_sff_port_init(ap); - -@@ -5505,6 +5522,12 @@ void ata_port_free(struct ata_port *ap) - kfree(ap->pmp_link); - kfree(ap->slave_link); - ida_free(&ata_ida, ap->print_id); -+#ifdef CONFIG_ATA_LEDS -+ if (ap->ledtrig) { -+ led_trigger_unregister(ap->ledtrig); -+ kfree(ap->ledtrig); -+ }; -+#endif - kfree(ap); - } - EXPORT_SYMBOL_GPL(ata_port_free); -@@ -5909,7 +5932,23 @@ int ata_host_register(struct ata_host *host, const struct scsi_host_template *sh - WARN_ON(1); - return -EINVAL; - } -+#ifdef CONFIG_ATA_LEDS -+ for (i = 0; i < host->n_ports; i++) { -+ if (unlikely(!host->ports[i]->ledtrig)) -+ continue; -+ -+ snprintf(host->ports[i]->ledtrig_name, -+ sizeof(host->ports[i]->ledtrig_name), "ata%u", -+ host->ports[i]->print_id); - -+ host->ports[i]->ledtrig->name = host->ports[i]->ledtrig_name; -+ -+ if (led_trigger_register(host->ports[i]->ledtrig)) { -+ kfree(host->ports[i]->ledtrig); -+ host->ports[i]->ledtrig = NULL; -+ } -+ } -+#endif - /* Create associated sysfs transport objects */ - for (i = 0; i < host->n_ports; i++) { - rc = ata_tport_add(host->dev,host->ports[i]); -diff --git a/include/linux/libata.h b/include/linux/libata.h -index 1983a98e3d67..4b9a57cfb801 100644 ---- a/include/linux/libata.h -+++ b/include/linux/libata.h -@@ -23,6 +23,9 @@ - #include - #include - #include -+#ifdef CONFIG_ATA_LEDS -+#include -+#endif - - /* - * Define if arch has non-standard setup. This is a _PCI_ standard -@@ -935,6 +938,10 @@ struct ata_port { - #ifdef CONFIG_ATA_ACPI - struct ata_acpi_gtm __acpi_init_gtm; /* use ata_acpi_init_gtm() */ - #endif -+#ifdef CONFIG_ATA_LEDS -+ struct led_trigger *ledtrig; -+ char ledtrig_name[8]; -+#endif - }; - - /* The following initializer overrides a method to NULL whether one of --- -2.51.0 - - -From e21a9da306cb81ea815c95e7222b4a5cf31c1f8a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= -Date: Sat, 20 Feb 2021 18:36:38 +0100 -Subject: [PATCH 323/517] hwrng: bcm2835: set quality to 1000 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This allows devices without a high precission timer to reduce boot from >100s -to <30s. - -Signed-off-by: Álvaro Fernández Rojas ---- - drivers/char/hw_random/bcm2835-rng.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/char/hw_random/bcm2835-rng.c b/drivers/char/hw_random/bcm2835-rng.c -index aa2b135e3ee2..1a7b3fcd5eb8 100644 ---- a/drivers/char/hw_random/bcm2835-rng.c -+++ b/drivers/char/hw_random/bcm2835-rng.c -@@ -169,6 +169,7 @@ static int bcm2835_rng_probe(struct platform_device *pdev) - priv->rng.init = bcm2835_rng_init; - priv->rng.read = bcm2835_rng_read; - priv->rng.cleanup = bcm2835_rng_cleanup; -+ priv->rng.quality = 1000; - - if (dev_of_node(dev)) { - rng_id = of_match_node(bcm2835_rng_of_match, dev->of_node); --- -2.51.0 - - -From f207db8602135a5efdbdb5d9be0464162dc43531 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marek=20Beh=C3=BAn?= -Date: Mon, 10 Jan 2022 02:02:00 +0100 -Subject: [PATCH 324/517] PCI: aardvark: Make main irq_chip structure a static - driver structure -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Marc Zyngier says [1] that we should use struct irq_chip as a global -static struct in the driver. Even though the structure currently -contains a dynamic member (parent_device), Marc says [2] that he plans -to kill it and make the structure completely static. - -We have already converted others irq_chip structures in this driver in -this way, but we omitted this one because the .name member is -dynamically created from device's name, and the name is displayed in -sysfs, so changing it would break sysfs ABI. - -The rationale for changing the name (to "advk-INT") in spite of sysfs -ABI, and thus allowing to convert to a static structure, is that after -the other changes we made in this series, the IRQ chip is basically -something different: it no logner generates ERR and PME interrupts (they -are generated by emulated bridge's rp_irq_chip). - -[1] https://lore.kernel.org/linux-pci/877dbcvngf.wl-maz@kernel.org/ -[2] https://lore.kernel.org/linux-pci/874k6gvkhz.wl-maz@kernel.org/ - -Signed-off-by: Marek Behún ---- - drivers/pci/controller/pci-aardvark.c | 25 +++++++------------------ - 1 file changed, 7 insertions(+), 18 deletions(-) - -diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c -index a598a98247ce..b2acf14fe414 100644 ---- a/drivers/pci/controller/pci-aardvark.c -+++ b/drivers/pci/controller/pci-aardvark.c -@@ -276,7 +276,6 @@ struct advk_pcie { - u8 wins_count; - struct irq_domain *rp_irq_domain; - struct irq_domain *irq_domain; -- struct irq_chip irq_chip; - raw_spinlock_t irq_lock; - struct irq_domain *msi_domain; - struct irq_domain *msi_inner_domain; -@@ -1418,14 +1417,19 @@ static void advk_pcie_irq_unmask(struct irq_data *d) - raw_spin_unlock_irqrestore(&pcie->irq_lock, flags); - } - -+static struct irq_chip advk_irq_chip = { -+ .name = "advk-INT", -+ .irq_mask = advk_pcie_irq_mask, -+ .irq_unmask = advk_pcie_irq_unmask, -+}; -+ - static int advk_pcie_irq_map(struct irq_domain *h, - unsigned int virq, irq_hw_number_t hwirq) - { - struct advk_pcie *pcie = h->host_data; - - irq_set_status_flags(virq, IRQ_LEVEL); -- irq_set_chip_and_handler(virq, &pcie->irq_chip, -- handle_level_irq); -+ irq_set_chip_and_handler(virq, &advk_irq_chip, handle_level_irq); - irq_set_chip_data(virq, pcie); - - return 0; -@@ -1485,7 +1489,6 @@ static int advk_pcie_init_irq_domain(struct advk_pcie *pcie) - struct device *dev = &pcie->pdev->dev; - struct device_node *node = dev->of_node; - struct device_node *pcie_intc_node; -- struct irq_chip *irq_chip; - int ret = 0; - - raw_spin_lock_init(&pcie->irq_lock); -@@ -1496,28 +1499,14 @@ static int advk_pcie_init_irq_domain(struct advk_pcie *pcie) - return -ENODEV; - } - -- irq_chip = &pcie->irq_chip; -- -- irq_chip->name = devm_kasprintf(dev, GFP_KERNEL, "%s-irq", -- dev_name(dev)); -- if (!irq_chip->name) { -- ret = -ENOMEM; -- goto out_put_node; -- } -- -- irq_chip->irq_mask = advk_pcie_irq_mask; -- irq_chip->irq_unmask = advk_pcie_irq_unmask; -- - pcie->irq_domain = - irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX, - &advk_pcie_irq_domain_ops, pcie); - if (!pcie->irq_domain) { - dev_err(dev, "Failed to get a INTx IRQ domain\n"); - ret = -ENOMEM; -- goto out_put_node; - } - --out_put_node: - of_node_put(pcie_intc_node); - return ret; - } --- -2.51.0 - - -From 772fcedd8d860ca53e1f543962c11f4dcad5c3ba Mon Sep 17 00:00:00 2001 -From: Corentin Labbe -Date: Tue, 7 May 2024 13:15:22 +0000 -Subject: [PATCH 325/517] usb: serial: add support for CH348 - -The CH348 is an USB octo port serial adapter. -The device multiplexes all 8 ports in the same pair of Bulk endpoints. -Since there is no public datasheet, unfortunately it remains some magic values - -Signed-off-by: Corentin Labbe -Tested-by: Martin Blumenstingl ---- - drivers/usb/serial/Kconfig | 9 + - drivers/usb/serial/Makefile | 1 + - drivers/usb/serial/ch348.c | 725 ++++++++++++++++++++++++++++++++++++ - 3 files changed, 735 insertions(+) - create mode 100644 drivers/usb/serial/ch348.c - -diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig -index ef8d1c73c754..1e1842656b54 100644 ---- a/drivers/usb/serial/Kconfig -+++ b/drivers/usb/serial/Kconfig -@@ -112,6 +112,15 @@ config USB_SERIAL_CH341 - To compile this driver as a module, choose M here: the - module will be called ch341. - -+config USB_SERIAL_CH348 -+ tristate "USB Winchiphead CH348 Octo Port Serial Driver" -+ help -+ Say Y here if you want to use a Winchiphead CH348 octo port -+ USB to serial adapter. -+ -+ To compile this driver as a module, choose M here: the -+ module will be called ch348. -+ - config USB_SERIAL_WHITEHEAT - tristate "USB ConnectTech WhiteHEAT Serial Driver" - select USB_EZUSB_FX2 -diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile -index c7bb1a88173e..d16ff59fde68 100644 ---- a/drivers/usb/serial/Makefile -+++ b/drivers/usb/serial/Makefile -@@ -15,6 +15,7 @@ obj-$(CONFIG_USB_SERIAL_AIRCABLE) += aircable.o - obj-$(CONFIG_USB_SERIAL_ARK3116) += ark3116.o - obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o - obj-$(CONFIG_USB_SERIAL_CH341) += ch341.o -+obj-$(CONFIG_USB_SERIAL_CH348) += ch348.o - obj-$(CONFIG_USB_SERIAL_CP210X) += cp210x.o - obj-$(CONFIG_USB_SERIAL_CYBERJACK) += cyberjack.o - obj-$(CONFIG_USB_SERIAL_CYPRESS_M8) += cypress_m8.o -diff --git a/drivers/usb/serial/ch348.c b/drivers/usb/serial/ch348.c -new file mode 100644 -index 000000000000..e437ba36bb5e ---- /dev/null -+++ b/drivers/usb/serial/ch348.c -@@ -0,0 +1,725 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * USB serial driver for USB to Octal UARTs chip ch348. -+ * -+ * Copyright (C) 2022 Corentin Labbe -+ * With the help of Neil Armstrong -+ * and the help of Martin Blumenstingl -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define CH348_CMD_TIMEOUT 2000 -+ -+#define CH348_CTO_D 0x01 -+#define CH348_CTO_R 0x02 -+ -+#define CH348_CTI_C 0x10 -+#define CH348_CTI_DSR 0x20 -+#define CH348_CTI_R 0x40 -+#define CH348_CTI_DCD 0x80 -+ -+#define CH348_LO 0x02 -+#define CH348_LP 0x04 -+#define CH348_LF 0x08 -+#define CH348_LB 0x10 -+ -+#define CMD_W_R 0xC0 -+#define CMD_W_BR 0x80 -+ -+#define CMD_WB_E 0x90 -+#define CMD_RB_E 0xC0 -+ -+#define M_NOR 0x00 -+#define M_HF 0x03 -+ -+#define R_MOD 0x97 -+#define R_IO_D 0x98 -+#define R_IO_O 0x99 -+#define R_IO_I 0x9b -+#define R_TM_O 0x9c -+#define R_INIT 0xa1 -+ -+#define R_C1 0x01 -+#define R_C2 0x02 -+#define R_C4 0x04 -+#define R_C5 0x06 -+ -+#define R_II_B1 0x06 -+#define R_II_B2 0x02 -+#define R_II_B3 0x00 -+ -+#define CMD_VER 0x96 -+ -+#define CH348_RX_PORT_CHUNK_LENGTH 32 -+#define CH348_RX_PORT_MAX_LENGTH 30 -+ -+struct ch348_rxbuf { -+ u8 port; -+ u8 length; -+ u8 data[CH348_RX_PORT_MAX_LENGTH]; -+} __packed; -+ -+struct ch348_txbuf { -+ u8 port; -+ __le16 length; -+ u8 data[]; -+} __packed; -+ -+#define CH348_TX_HDRSIZE offsetof(struct ch348_txbuf, data) -+ -+struct ch348_initbuf { -+ u8 cmd; -+ u8 reg; -+ u8 port; -+ __be32 baudrate; -+ u8 format; -+ u8 paritytype; -+ u8 databits; -+ u8 rate; -+ u8 unknown; -+} __packed; -+ -+#define CH348_MAXPORT 8 -+ -+/* -+ * The CH348 multiplexes rx & tx into a pair of Bulk USB endpoints for -+ * the 8 serial ports, and another pair of Bulk USB endpoints to -+ * set port settings and receive port status events. -+ * -+ * The USB serial cores ties every Bulk endpoints pairs to each ports, -+ * but in our case it will set port 0 with the rx/tx endpoints -+ * and port 1 with the setup/status endpoints. -+ * -+ * To still take advantage of the generic code, we (re-)initialize -+ * the USB serial port structure with the correct USB endpoint -+ * for read and write, and write proper process_read_urb() -+ * and prepare_write_buffer() to correctly (de-)multiplex data. -+ * Also we use a custom write() implementation to wait until the buffer -+ * has been fully transmitted to prevent TX buffer overruns. -+ */ -+ -+/* -+ * struct ch348_port - per-port information -+ * @uartmode: UART port current mode -+ * @write_completion: completion event when the TX buffer has been written out -+ */ -+struct ch348_port { -+ u8 uartmode; -+ struct completion write_completion; -+}; -+ -+/* -+ * struct ch348 - main container for all this driver information -+ * @udev: pointer to the CH348 USB device -+ * @ports: List of per-port information -+ * @serial: pointer to the serial structure -+ * @write_lock: protect against concurrent writes so we don't lose data -+ * @cmd_ep: endpoint number for configure operations -+ * @status_urb: URB for status -+ * @status_buffer: buffer used by status_urb -+ */ -+struct ch348 { -+ struct usb_device *udev; -+ struct ch348_port ports[CH348_MAXPORT]; -+ struct usb_serial *serial; -+ -+ struct mutex write_lock; -+ -+ int cmd_ep; -+ -+ struct urb *status_urb; -+ u8 status_buffer[]; -+}; -+ -+struct ch348_magic { -+ u8 action; -+ u8 reg; -+ u8 control; -+} __packed; -+ -+struct ch348_status_entry { -+ u8 portnum:4; -+ u8 unused:4; -+ u8 reg_iir; -+ union { -+ u8 lsr_signal; -+ u8 modem_signal; -+ u8 init_data[10]; -+ }; -+} __packed; -+ -+static void ch348_process_status_urb(struct urb *urb) -+{ -+ struct ch348_status_entry *status_entry; -+ struct ch348 *ch348 = urb->context; -+ int ret, status = urb->status; -+ struct usb_serial_port *port; -+ unsigned int i, status_len; -+ -+ switch (status) { -+ case 0: -+ /* success */ -+ break; -+ case -ECONNRESET: -+ case -ENOENT: -+ case -ESHUTDOWN: -+ /* this urb is terminated, clean up */ -+ dev_dbg(&urb->dev->dev, "%s - urb shutting down with status: %d\n", -+ __func__, status); -+ return; -+ default: -+ dev_err(&urb->dev->dev, "%s - nonzero urb status received: %d\n", -+ __func__, status); -+ goto exit; -+ } -+ -+ if (urb->actual_length < 3) { -+ dev_warn(&ch348->udev->dev, -+ "Received too short status buffer with %u bytes\n", -+ urb->actual_length); -+ goto exit; -+ } -+ -+ for (i = 0; i < urb->actual_length;) { -+ status_entry = urb->transfer_buffer + i; -+ -+ if (status_entry->portnum >= CH348_MAXPORT) { -+ dev_warn(&ch348->udev->dev, -+ "Invalid port %d in status entry\n", -+ status_entry->portnum); -+ break; -+ } -+ -+ port = ch348->serial->port[status_entry->portnum]; -+ status_len = 3; -+ -+ if (!status_entry->reg_iir) { -+ dev_dbg(&port->dev, "Ignoring status with zero reg_iir\n"); -+ } else if (status_entry->reg_iir == R_INIT) { -+ status_len = 12; -+ } else if ((status_entry->reg_iir & 0x0f) == R_II_B1) { -+ if (status_entry->lsr_signal & CH348_LO) -+ port->icount.overrun++; -+ if (status_entry->lsr_signal & CH348_LP) -+ port->icount.parity++; -+ if (status_entry->lsr_signal & CH348_LF) -+ port->icount.frame++; -+ if (status_entry->lsr_signal & CH348_LF) -+ port->icount.brk++; -+ } else if ((status_entry->reg_iir & 0x0f) == R_II_B2) { -+ complete_all(&ch348->ports[status_entry->portnum].write_completion); -+ } else { -+ dev_warn(&port->dev, -+ "Unsupported status with reg_iir 0x%02x\n", -+ status_entry->reg_iir); -+ } -+ -+ usb_serial_debug_data(&port->dev, __func__, status_len, -+ urb->transfer_buffer + i); -+ -+ i += status_len; -+ } -+ -+exit: -+ ret = usb_submit_urb(urb, GFP_ATOMIC); -+ if (ret) -+ dev_err(&urb->dev->dev, "%s - usb_submit_urb failed; %d\n", -+ __func__, ret); -+} -+ -+/* -+ * Some values came from vendor tree, and we have no meaning for them, this -+ * function simply use them. -+ */ -+static int ch348_do_magic(struct ch348 *ch348, int portnum, u8 action, u8 reg, u8 control) -+{ -+ struct ch348_magic *buffer; -+ int ret, len; -+ -+ buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); -+ if (!buffer) -+ return -ENOMEM; -+ -+ if (portnum < 4) -+ reg += 0x10 * portnum; -+ else -+ reg += 0x10 * (portnum - 4) + 0x08; -+ -+ buffer->action = action; -+ buffer->reg = reg; -+ buffer->control = control; -+ -+ ret = usb_bulk_msg(ch348->udev, ch348->cmd_ep, buffer, 3, &len, -+ CH348_CMD_TIMEOUT); -+ if (ret) -+ dev_err(&ch348->udev->dev, "Failed to write magic err=%d\n", ret); -+ -+ kfree(buffer); -+ -+ return ret; -+} -+ -+static int ch348_configure(struct ch348 *ch348, int portnum) -+{ -+ int ret; -+ -+ ret = ch348_do_magic(ch348, portnum, CMD_W_R, R_C2, 0x87); -+ if (ret) -+ return ret; -+ -+ return ch348_do_magic(ch348, portnum, CMD_W_R, R_C4, 0x08); -+} -+ -+static void ch348_process_read_urb(struct urb *urb) -+{ -+ struct usb_serial_port *port = urb->context; -+ struct ch348 *ch348 = usb_get_serial_data(port->serial); -+ unsigned int portnum, usblen, i; -+ struct ch348_rxbuf *rxb; -+ -+ if (urb->actual_length < 2) { -+ dev_dbg(&ch348->udev->dev, "Empty rx buffer\n"); -+ return; -+ } -+ -+ for (i = 0; i < urb->actual_length; i += CH348_RX_PORT_CHUNK_LENGTH) { -+ rxb = urb->transfer_buffer + i; -+ portnum = rxb->port; -+ if (portnum >= CH348_MAXPORT) { -+ dev_dbg(&ch348->udev->dev, "Invalid port %d\n", portnum); -+ break; -+ } -+ -+ port = ch348->serial->port[portnum]; -+ -+ usblen = rxb->length; -+ if (usblen > CH348_RX_PORT_MAX_LENGTH) { -+ dev_dbg(&port->dev, "Invalid length %d for port %d\n", -+ usblen, portnum); -+ break; -+ } -+ -+ tty_insert_flip_string(&port->port, rxb->data, usblen); -+ tty_flip_buffer_push(&port->port); -+ port->icount.rx += usblen; -+ usb_serial_debug_data(&port->dev, __func__, usblen, rxb->data); -+ } -+} -+ -+static int ch348_prepare_write_buffer(struct usb_serial_port *port, void *dest, size_t size) -+{ -+ struct ch348_txbuf *rxt = dest; -+ int count; -+ -+ count = kfifo_out_locked(&port->write_fifo, rxt->data, -+ size - CH348_TX_HDRSIZE, &port->lock); -+ -+ rxt->port = port->port_number; -+ rxt->length = cpu_to_le16(count); -+ -+ return count + CH348_TX_HDRSIZE; -+} -+ -+static int ch348_write(struct tty_struct *tty, struct usb_serial_port *port, -+ const unsigned char *buf, int count) -+{ -+ struct ch348 *ch348 = usb_get_serial_data(port->serial); -+ struct ch348_port *ch348_port = &ch348->ports[port->port_number]; -+ int ret, max_tx_size; -+ -+ if (tty_get_baud_rate(tty) < 9600 && count >= 128) -+ /* -+ * Writing larger buffers can take longer than the hardware -+ * allows before discarding the write buffer. Limit the -+ * transfer size in such cases. -+ * These values have been found by empirical testing. -+ */ -+ max_tx_size = 128; -+ else -+ /* -+ * Only ingest as many bytes as we can transfer with one URB at -+ * a time. Once an URB has been written we need to wait for the -+ * R_II_B2 status event before we are allowed to send more data. -+ * If we ingest more data then usb_serial_generic_write() will -+ * internally try to process as much data as possible with any -+ * number of URBs without giving us the chance to wait in -+ * between transfers. -+ */ -+ max_tx_size = port->bulk_out_size - CH348_TX_HDRSIZE; -+ -+ reinit_completion(&ch348_port->write_completion); -+ -+ mutex_lock(&ch348->write_lock); -+ -+ /* -+ * For any (remaining) bytes that we did not transfer TTY core will -+ * call us again, with the buffer and count adjusted to the remaining -+ * data. -+ */ -+ ret = usb_serial_generic_write(tty, port, buf, min(count, max_tx_size)); -+ -+ mutex_unlock(&ch348->write_lock); -+ -+ if (ret <= 0) -+ return ret; -+ -+ if (!wait_for_completion_interruptible_timeout(&ch348_port->write_completion, -+ msecs_to_jiffies(CH348_CMD_TIMEOUT))) { -+ dev_err_console(port, "Failed to wait for TX buffer flush\n"); -+ return -ETIMEDOUT; -+ } -+ -+ return ret; -+} -+ -+static int ch348_set_uartmode(struct ch348 *ch348, int portnum, u8 mode) -+{ -+ int ret; -+ -+ if (ch348->ports[portnum].uartmode == M_NOR && mode == M_HF) { -+ ret = ch348_do_magic(ch348, portnum, CMD_W_BR, R_C4, 0x51); -+ if (ret) -+ return ret; -+ ch348->ports[portnum].uartmode = M_HF; -+ } -+ -+ if (ch348->ports[portnum].uartmode == M_HF && mode == M_NOR) { -+ ret = ch348_do_magic(ch348, portnum, CMD_W_BR, R_C4, 0x50); -+ if (ret) -+ return ret; -+ ch348->ports[portnum].uartmode = M_NOR; -+ } -+ return 0; -+} -+ -+static void ch348_set_termios(struct tty_struct *tty, struct usb_serial_port *port, -+ const struct ktermios *termios_old) -+{ -+ struct ch348 *ch348 = usb_get_serial_data(port->serial); -+ struct ktermios *termios = &tty->termios; -+ int ret, portnum = port->port_number; -+ struct ch348_initbuf *buffer; -+ speed_t baudrate; -+ u8 format; -+ -+ if (termios_old && !tty_termios_hw_change(&tty->termios, termios_old)) -+ return; -+ -+ buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); -+ if (!buffer) { -+ if (termios_old) -+ tty->termios = *termios_old; -+ return; -+ } -+ -+ /* -+ * The datasheet states that only baud rates in range of 1200..6000000 -+ * are supported. Tests however show that even baud rates as low as 50 -+ * and as high as 12000000 are working in practice. -+ */ -+ baudrate = clamp(tty_get_baud_rate(tty), 50, 12000000); -+ -+ format = termios->c_cflag & CSTOPB ? 2 : 1; -+ -+ buffer->paritytype = 0; -+ if (termios->c_cflag & PARENB) { -+ if (termios->c_cflag & PARODD) -+ buffer->paritytype += 1; -+ else -+ buffer->paritytype += 2; -+ if (termios->c_cflag & CMSPAR) -+ buffer->paritytype += 2; -+ } -+ -+ switch (C_CSIZE(tty)) { -+ case CS5: -+ buffer->databits = 5; -+ break; -+ case CS6: -+ buffer->databits = 6; -+ break; -+ case CS7: -+ buffer->databits = 7; -+ break; -+ case CS8: -+ default: -+ buffer->databits = 8; -+ break; -+ } -+ buffer->cmd = CMD_WB_E | (portnum & 0x0F); -+ buffer->reg = R_INIT; -+ buffer->port = portnum; -+ buffer->baudrate = cpu_to_be32(baudrate); -+ -+ if (format == 2) -+ buffer->format = 0x02; -+ else if (format == 1) -+ buffer->format = 0x00; -+ -+ buffer->rate = max_t(speed_t, 5, (10000 * 15 / baudrate) + 1); -+ -+ ret = usb_bulk_msg(ch348->udev, ch348->cmd_ep, buffer, -+ sizeof(*buffer), NULL, CH348_CMD_TIMEOUT); -+ if (ret < 0) { -+ dev_err(&ch348->udev->dev, "Failed to change line settings: err=%d\n", -+ ret); -+ goto out; -+ } -+ -+ ret = ch348_do_magic(ch348, portnum, CMD_W_R, R_C1, 0x0F); -+ if (ret < 0) -+ goto out; -+ -+ if (C_CRTSCTS(tty)) -+ ret = ch348_set_uartmode(ch348, portnum, M_HF); -+ else -+ ret = ch348_set_uartmode(ch348, portnum, M_NOR); -+ -+out: -+ kfree(buffer); -+} -+ -+static int ch348_open(struct tty_struct *tty, struct usb_serial_port *port) -+{ -+ struct ch348 *ch348 = usb_get_serial_data(port->serial); -+ int ret; -+ -+ if (tty) -+ ch348_set_termios(tty, port, NULL); -+ -+ ret = ch348_configure(ch348, port->port_number); -+ if (ret) { -+ dev_err(&ch348->udev->dev, "Fail to configure err=%d\n", ret); -+ return ret; -+ } -+ -+ return usb_serial_generic_open(tty, port); -+} -+ -+static int ch348_attach(struct usb_serial *serial) -+{ -+ struct usb_endpoint_descriptor *epcmd, *epstatus; -+ struct usb_serial_port *port0 = serial->port[1]; -+ struct usb_device *usb_dev = serial->dev; -+ int status_buffer_size, i, ret; -+ struct usb_interface *intf; -+ struct ch348 *ch348; -+ -+ intf = usb_ifnum_to_if(usb_dev, 0); -+ epstatus = &intf->cur_altsetting->endpoint[2].desc; -+ epcmd = &intf->cur_altsetting->endpoint[3].desc; -+ -+ status_buffer_size = usb_endpoint_maxp(epstatus); -+ -+ ch348 = kzalloc(struct_size(ch348, status_buffer, status_buffer_size), -+ GFP_KERNEL); -+ if (!ch348) -+ return -ENOMEM; -+ -+ usb_set_serial_data(serial, ch348); -+ -+ ch348->udev = serial->dev; -+ ch348->serial = serial; -+ mutex_init(&ch348->write_lock); -+ -+ for (i = 0; i < CH348_MAXPORT; i++) -+ init_completion(&ch348->ports[i].write_completion); -+ -+ ch348->status_urb = usb_alloc_urb(0, GFP_KERNEL); -+ if (!ch348->status_urb) { -+ ret = -ENOMEM; -+ goto err_free_ch348; -+ } -+ -+ usb_fill_bulk_urb(ch348->status_urb, ch348->udev, -+ usb_rcvbulkpipe(ch348->udev, epstatus->bEndpointAddress), -+ ch348->status_buffer, status_buffer_size, -+ ch348_process_status_urb, ch348); -+ -+ ret = usb_submit_urb(ch348->status_urb, GFP_KERNEL); -+ if (ret) { -+ dev_err(&ch348->udev->dev, -+ "%s - failed to submit status/interrupt urb %i\n", -+ __func__, ret); -+ goto err_free_status_urb; -+ } -+ -+ ret = usb_serial_generic_submit_read_urbs(port0, GFP_KERNEL); -+ if (ret) -+ goto err_kill_status_urb; -+ -+ ch348->cmd_ep = usb_sndbulkpipe(usb_dev, epcmd->bEndpointAddress); -+ -+ return 0; -+ -+err_kill_status_urb: -+ usb_kill_urb(ch348->status_urb); -+err_free_status_urb: -+ usb_free_urb(ch348->status_urb); -+err_free_ch348: -+ kfree(ch348); -+ return ret; -+} -+ -+static void ch348_release(struct usb_serial *serial) -+{ -+ struct ch348 *ch348 = usb_get_serial_data(serial); -+ -+ usb_kill_urb(ch348->status_urb); -+ usb_free_urb(ch348->status_urb); -+ -+ kfree(ch348); -+} -+ -+static void ch348_print_version(struct usb_serial *serial) -+{ -+ u8 *version_buf; -+ int ret; -+ -+ version_buf = kzalloc(4, GFP_KERNEL); -+ if (!version_buf) -+ return; -+ -+ ret = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), -+ CMD_VER, -+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, -+ 0, 0, version_buf, 4, CH348_CMD_TIMEOUT); -+ if (ret < 0) -+ dev_dbg(&serial->dev->dev, "Failed to read CMD_VER: %d\n", ret); -+ else -+ dev_info(&serial->dev->dev, "Found WCH CH348%s\n", -+ (version_buf[1] & 0x80) ? "Q" : "L"); -+ -+ kfree(version_buf); -+} -+ -+static int ch348_probe(struct usb_serial *serial, const struct usb_device_id *id) -+{ -+ struct usb_endpoint_descriptor *epread, *epwrite, *epstatus, *epcmd; -+ struct usb_device *usb_dev = serial->dev; -+ struct usb_interface *intf; -+ int ret; -+ -+ intf = usb_ifnum_to_if(usb_dev, 0); -+ -+ ret = usb_find_common_endpoints(intf->cur_altsetting, &epread, &epwrite, -+ NULL, NULL); -+ if (ret) { -+ dev_err(&serial->dev->dev, "Failed to find basic endpoints ret=%d\n", ret); -+ return ret; -+ } -+ -+ epstatus = &intf->cur_altsetting->endpoint[2].desc; -+ if (!usb_endpoint_is_bulk_in(epstatus)) { -+ dev_err(&serial->dev->dev, "Missing second bulk in (STATUS/INT)\n"); -+ return -ENODEV; -+ } -+ -+ epcmd = &intf->cur_altsetting->endpoint[3].desc; -+ if (!usb_endpoint_is_bulk_out(epcmd)) { -+ dev_err(&serial->dev->dev, "Missing second bulk out (CMD)\n"); -+ return -ENODEV; -+ } -+ -+ ch348_print_version(serial); -+ -+ return 0; -+} -+ -+static int ch348_calc_num_ports(struct usb_serial *serial, -+ struct usb_serial_endpoints *epds) -+{ -+ int i; -+ -+ for (i = 1; i < CH348_MAXPORT; ++i) { -+ epds->bulk_out[i] = epds->bulk_out[0]; -+ epds->bulk_in[i] = epds->bulk_in[0]; -+ } -+ -+ epds->num_bulk_out = CH348_MAXPORT; -+ epds->num_bulk_in = CH348_MAXPORT; -+ -+ return CH348_MAXPORT; -+} -+ -+static int ch348_suspend(struct usb_serial *serial, pm_message_t message) -+{ -+ struct ch348 *ch348 = usb_get_serial_data(serial); -+ -+ usb_kill_urb(ch348->status_urb); -+ -+ return 0; -+} -+ -+static int ch348_resume(struct usb_serial *serial) -+{ -+ struct ch348 *ch348 = usb_get_serial_data(serial); -+ int ret; -+ -+ ret = usb_submit_urb(ch348->status_urb, GFP_KERNEL); -+ if (ret) { -+ dev_err(&ch348->udev->dev, -+ "%s - failed to submit status/interrupt urb %i\n", -+ __func__, ret); -+ return ret; -+ } -+ -+ ret = usb_serial_generic_resume(serial); -+ if (ret) -+ usb_kill_urb(ch348->status_urb); -+ -+ return ret; -+} -+ -+static const struct usb_device_id ch348_ids[] = { -+ { USB_DEVICE(0x1a86, 0x55d9), }, -+ { /* sentinel */ } -+}; -+ -+MODULE_DEVICE_TABLE(usb, ch348_ids); -+ -+static struct usb_serial_driver ch348_device = { -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = "ch348", -+ }, -+ .id_table = ch348_ids, -+ .num_ports = CH348_MAXPORT, -+ .num_bulk_in = 1, -+ .num_bulk_out = 1, -+ .open = ch348_open, -+ .set_termios = ch348_set_termios, -+ .process_read_urb = ch348_process_read_urb, -+ .prepare_write_buffer = ch348_prepare_write_buffer, -+ .write = ch348_write, -+ .probe = ch348_probe, -+ .calc_num_ports = ch348_calc_num_ports, -+ .attach = ch348_attach, -+ .release = ch348_release, -+ .suspend = ch348_suspend, -+ .resume = ch348_resume, -+}; -+ -+static struct usb_serial_driver * const serial_drivers[] = { -+ &ch348_device, NULL -+}; -+ -+module_usb_serial_driver(serial_drivers, ch348_ids); -+ -+MODULE_AUTHOR("Corentin Labbe "); -+MODULE_DESCRIPTION("USB CH348 Octo port serial converter driver"); -+MODULE_LICENSE("GPL"); --- -2.51.0 - - -From 7425a0d41434f00f9190aeee0fbbe6c94315589b Mon Sep 17 00:00:00 2001 -From: Vicentiu Galanopulo -Date: Wed, 18 Dec 2024 18:33:58 +0000 -Subject: [PATCH 326/517] dt-bindings: leds: Add LED1202 LED Controller - -The LED1202 is a 12-channel low quiescent current LED driver with: - * Supply range from 2.6 V to 5 V - * 20 mA current capability per channel - * 1.8 V compatible I2C control interface - * 8-bit analog dimming individual control - * 12-bit local PWM resolution - * 8 programmable patterns - -If the led node is present in the controller then the channel is -set to active. - -Signed-off-by: Vicentiu Galanopulo -Reviewed-by: Krzysztof Kozlowski ---- - .../devicetree/bindings/leds/st,led1202.yaml | 132 ++++++++++++++++++ - 1 file changed, 132 insertions(+) - create mode 100644 Documentation/devicetree/bindings/leds/st,led1202.yaml - -diff --git a/Documentation/devicetree/bindings/leds/st,led1202.yaml b/Documentation/devicetree/bindings/leds/st,led1202.yaml -new file mode 100644 -index 000000000000..f1e5e4efaa3a ---- /dev/null -+++ b/Documentation/devicetree/bindings/leds/st,led1202.yaml -@@ -0,0 +1,132 @@ -+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/leds/st,led1202.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: ST LED1202 LED controllers -+ -+maintainers: -+ - Vicentiu Galanopulo -+ -+description: | -+ The LED1202 is a 12-channel low quiescent current LED controller -+ programmable via I2C; The output current can be adjusted separately -+ for each channel by 8-bit analog and 12-bit digital dimming control. -+ Datasheet available at -+ https://www.st.com/en/power-management/led1202.html -+ -+properties: -+ compatible: -+ const: st,led1202 -+ -+ reg: -+ maxItems: 1 -+ -+ "#address-cells": -+ const: 1 -+ -+ "#size-cells": -+ const: 0 -+ -+patternProperties: -+ "^led@[0-9a-f]$": -+ type: object -+ $ref: common.yaml# -+ unevaluatedProperties: false -+ -+ properties: -+ reg: -+ minimum: 0 -+ maximum: 11 -+ -+ required: -+ - reg -+ -+required: -+ - compatible -+ - reg -+ - "#address-cells" -+ - "#size-cells" -+ -+additionalProperties: false -+ -+examples: -+ - | -+ #include -+ -+ i2c { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ led-controller@58 { -+ compatible = "st,led1202"; -+ reg = <0x58>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ led@0 { -+ reg = <0x0>; -+ function = LED_FUNCTION_STATUS; -+ color = ; -+ function-enumerator = <1>; -+ }; -+ -+ led@1 { -+ reg = <0x1>; -+ function = LED_FUNCTION_STATUS; -+ color = ; -+ function-enumerator = <2>; -+ }; -+ -+ led@2 { -+ reg = <0x2>; -+ function = LED_FUNCTION_STATUS; -+ color = ; -+ function-enumerator = <3>; -+ }; -+ -+ led@3 { -+ reg = <0x3>; -+ function = LED_FUNCTION_STATUS; -+ color = ; -+ function-enumerator = <4>; -+ }; -+ -+ led@4 { -+ reg = <0x4>; -+ function = LED_FUNCTION_STATUS; -+ color = ; -+ function-enumerator = <5>; -+ }; -+ -+ led@5 { -+ reg = <0x5>; -+ function = LED_FUNCTION_STATUS; -+ color = ; -+ function-enumerator = <6>; -+ }; -+ -+ led@6 { -+ reg = <0x6>; -+ function = LED_FUNCTION_STATUS; -+ color = ; -+ function-enumerator = <7>; -+ }; -+ -+ led@7 { -+ reg = <0x7>; -+ function = LED_FUNCTION_STATUS; -+ color = ; -+ function-enumerator = <8>; -+ }; -+ -+ led@8 { -+ reg = <0x8>; -+ function = LED_FUNCTION_STATUS; -+ color = ; -+ function-enumerator = <9>; -+ }; -+ }; -+ }; -+... --- -2.51.0 - - -From 266622ae5a057e31d2539cf532af4287df3aa656 Mon Sep 17 00:00:00 2001 -From: Vicentiu Galanopulo -Date: Wed, 18 Dec 2024 18:33:59 +0000 -Subject: [PATCH 327/517] leds: Add LED1202 I2C driver - -The output current can be adjusted separately for each channel by 8-bit -analog (current sink input) and 12-bit digital (PWM) dimming control. The -LED1202 implements 12 low-side current generators with independent dimming -control. -Internal volatile memory allows the user to store up to 8 different patterns, -each pattern is a particular output configuration in terms of PWM -duty-cycle (on 4096 steps). Analog dimming (on 256 steps) is per channel but -common to all patterns. Each device tree LED node will have a corresponding -entry in /sys/class/leds with the label name. The brightness property -corresponds to the per channel analog dimming, while the patterns[1-8] to the -PWM dimming control. - -Signed-off-by: Vicentiu Galanopulo ---- - drivers/leds/Kconfig | 10 + - drivers/leds/Makefile | 1 + - drivers/leds/leds-st1202.c | 416 +++++++++++++++++++++++++++++++++++++ - 3 files changed, 427 insertions(+) - create mode 100644 drivers/leds/leds-st1202.c - -diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig -index b784bb74a837..c275963c498c 100644 ---- a/drivers/leds/Kconfig -+++ b/drivers/leds/Kconfig -@@ -931,6 +931,16 @@ config LEDS_LM36274 - Say Y to enable the LM36274 LED driver for TI LMU devices. - This supports the LED device LM36274. - -+config LEDS_ST1202 -+ tristate "LED Support for STMicroelectronics LED1202 I2C chips" -+ depends on LEDS_CLASS -+ depends on I2C -+ depends on OF -+ select LEDS_TRIGGERS -+ help -+ Say Y to enable support for LEDs connected to LED1202 -+ LED driver chips accessed via the I2C bus. -+ - config LEDS_TPS6105X - tristate "LED support for TI TPS6105X" - depends on LEDS_CLASS -diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile -index 18afbb5a23ee..32241451b805 100644 ---- a/drivers/leds/Makefile -+++ b/drivers/leds/Makefile -@@ -82,6 +82,7 @@ obj-$(CONFIG_LEDS_PWM) += leds-pwm.o - obj-$(CONFIG_LEDS_REGULATOR) += leds-regulator.o - obj-$(CONFIG_LEDS_SC27XX_BLTC) += leds-sc27xx-bltc.o - obj-$(CONFIG_LEDS_SUN50I_A100) += leds-sun50i-a100.o -+obj-$(CONFIG_LEDS_ST1202) += leds-st1202.o - obj-$(CONFIG_LEDS_SUNFIRE) += leds-sunfire.o - obj-$(CONFIG_LEDS_SYSCON) += leds-syscon.o - obj-$(CONFIG_LEDS_TCA6507) += leds-tca6507.o -diff --git a/drivers/leds/leds-st1202.c b/drivers/leds/leds-st1202.c -new file mode 100644 -index 000000000000..b691c4886993 ---- /dev/null -+++ b/drivers/leds/leds-st1202.c -@@ -0,0 +1,416 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * LED driver for STMicroelectronics LED1202 chip -+ * -+ * Copyright (C) 2024 Remote-Tech Ltd. UK -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define ST1202_CHAN_DISABLE_ALL 0x00 -+#define ST1202_CHAN_ENABLE_HIGH 0x03 -+#define ST1202_CHAN_ENABLE_LOW 0x02 -+#define ST1202_CONFIG_REG 0x04 -+/* PATS: Pattern sequence feature enable */ -+#define ST1202_CONFIG_REG_PATS BIT(7) -+/* PATSR: Pattern sequence runs (self-clear when sequence is finished) */ -+#define ST1202_CONFIG_REG_PATSR BIT(6) -+#define ST1202_CONFIG_REG_SHFT BIT(3) -+#define ST1202_DEV_ENABLE 0x01 -+#define ST1202_DEV_ENABLE_ON BIT(0) -+#define ST1202_DEV_ENABLE_RESET BIT(7) -+#define ST1202_DEVICE_ID 0x00 -+#define ST1202_ILED_REG0 0x09 -+#define ST1202_MAX_LEDS 12 -+#define ST1202_MAX_PATTERNS 8 -+#define ST1202_MILLIS_PATTERN_DUR_MAX 5660 -+#define ST1202_MILLIS_PATTERN_DUR_MIN 22 -+#define ST1202_PATTERN_DUR 0x16 -+#define ST1202_PATTERN_PWM 0x1E -+#define ST1202_PATTERN_REP 0x15 -+ -+struct st1202_led { -+ struct fwnode_handle *fwnode; -+ struct led_classdev led_cdev; -+ struct st1202_chip *chip; -+ bool is_active; -+ int led_num; -+}; -+ -+struct st1202_chip { -+ struct i2c_client *client; -+ struct mutex lock; -+ struct st1202_led leds[ST1202_MAX_LEDS]; -+}; -+ -+static struct st1202_led *cdev_to_st1202_led(struct led_classdev *cdev) -+{ -+ return container_of(cdev, struct st1202_led, led_cdev); -+} -+ -+static int st1202_read_reg(struct st1202_chip *chip, int reg, uint8_t *val) -+{ -+ struct device *dev = &chip->client->dev; -+ int ret; -+ -+ ret = i2c_smbus_read_byte_data(chip->client, reg); -+ if (ret < 0) { -+ dev_err(dev, "Failed to read register [0x%x]: %d\n", reg, ret); -+ return ret; -+ } -+ -+ *val = (uint8_t)ret; -+ return 0; -+} -+ -+static int st1202_write_reg(struct st1202_chip *chip, int reg, uint8_t val) -+{ -+ struct device *dev = &chip->client->dev; -+ int ret; -+ -+ ret = i2c_smbus_write_byte_data(chip->client, reg, val); -+ if (ret != 0) -+ dev_err(dev, "Failed to write %d to register [0x%x]: %d\n", val, reg, ret); -+ -+ return ret; -+} -+ -+static uint8_t st1202_prescalar_to_miliseconds(unsigned int value) -+{ -+ return value / ST1202_MILLIS_PATTERN_DUR_MIN - 1; -+} -+ -+static int st1202_pwm_pattern_write(struct st1202_chip *chip, int led_num, -+ int pattern, unsigned int value) -+{ -+ u8 value_l, value_h; -+ int ret; -+ -+ value_l = (u8)value; -+ value_h = (u8)(value >> 8); -+ -+ /* -+ * Datasheet: Register address low = 1Eh + 2*(xh) + 18h*(yh), -+ * where x is the channel number (led number) in hexadecimal (x = 00h .. 0Bh) -+ * and y is the pattern number in hexadecimal (y = 00h .. 07h) -+ */ -+ ret = st1202_write_reg(chip, (ST1202_PATTERN_PWM + (led_num * 2) + 0x18 * pattern), -+ value_l); -+ if (ret != 0) -+ return ret; -+ -+ /* -+ * Datasheet: Register address high = 1Eh + 01h + 2(xh) +18h*(yh), -+ * where x is the channel number in hexadecimal (x = 00h .. 0Bh) -+ * and y is the pattern number in hexadecimal (y = 00h .. 07h) -+ */ -+ ret = st1202_write_reg(chip, (ST1202_PATTERN_PWM + 0x1 + (led_num * 2) + 0x18 * pattern), -+ value_h); -+ if (ret != 0) -+ return ret; -+ -+ return 0; -+} -+ -+static int st1202_duration_pattern_write(struct st1202_chip *chip, int pattern, -+ unsigned int value) -+{ -+ return st1202_write_reg(chip, (ST1202_PATTERN_DUR + pattern), -+ st1202_prescalar_to_miliseconds(value)); -+} -+ -+static void st1202_brightness_set(struct led_classdev *led_cdev, -+ enum led_brightness value) -+{ -+ struct st1202_led *led = cdev_to_st1202_led(led_cdev); -+ struct st1202_chip *chip = led->chip; -+ -+ guard(mutex)(&chip->lock); -+ -+ st1202_write_reg(chip, ST1202_ILED_REG0 + led->led_num, value); -+} -+ -+static enum led_brightness st1202_brightness_get(struct led_classdev *led_cdev) -+{ -+ struct st1202_led *led = cdev_to_st1202_led(led_cdev); -+ struct st1202_chip *chip = led->chip; -+ u8 value = 0; -+ -+ guard(mutex)(&chip->lock); -+ -+ st1202_read_reg(chip, ST1202_ILED_REG0 + led->led_num, &value); -+ -+ return value; -+} -+ -+static int st1202_channel_set(struct st1202_chip *chip, int led_num, bool active) -+{ -+ u8 chan_low, chan_high; -+ int ret; -+ -+ guard(mutex)(&chip->lock); -+ -+ if (led_num <= 7) { -+ ret = st1202_read_reg(chip, ST1202_CHAN_ENABLE_LOW, &chan_low); -+ if (ret < 0) -+ return ret; -+ -+ chan_low = active ? chan_low | BIT(led_num) : chan_low & ~BIT(led_num); -+ -+ ret = st1202_write_reg(chip, ST1202_CHAN_ENABLE_LOW, chan_low); -+ if (ret < 0) -+ return ret; -+ -+ } else { -+ ret = st1202_read_reg(chip, ST1202_CHAN_ENABLE_HIGH, &chan_high); -+ if (ret < 0) -+ return ret; -+ -+ chan_high = active ? chan_high | (BIT(led_num) >> 8) : -+ chan_high & ~(BIT(led_num) >> 8); -+ -+ ret = st1202_write_reg(chip, ST1202_CHAN_ENABLE_HIGH, chan_high); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int st1202_led_set(struct led_classdev *ldev, enum led_brightness value) -+{ -+ struct st1202_led *led = cdev_to_st1202_led(ldev); -+ struct st1202_chip *chip = led->chip; -+ -+ return st1202_channel_set(chip, led->led_num, value == LED_OFF ? false : true); -+} -+ -+static int st1202_led_pattern_clear(struct led_classdev *ldev) -+{ -+ struct st1202_led *led = cdev_to_st1202_led(ldev); -+ struct st1202_chip *chip = led->chip; -+ int ret; -+ -+ guard(mutex)(&chip->lock); -+ -+ for (int patt = 0; patt < ST1202_MAX_PATTERNS; patt++) { -+ ret = st1202_pwm_pattern_write(chip, led->led_num, patt, LED_OFF); -+ if (ret != 0) -+ return ret; -+ -+ ret = st1202_duration_pattern_write(chip, patt, ST1202_MILLIS_PATTERN_DUR_MIN); -+ if (ret != 0) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int st1202_led_pattern_set(struct led_classdev *ldev, -+ struct led_pattern *pattern, -+ u32 len, int repeat) -+{ -+ struct st1202_led *led = cdev_to_st1202_led(ldev); -+ struct st1202_chip *chip = led->chip; -+ int ret; -+ -+ if (len > ST1202_MAX_PATTERNS) -+ return -EINVAL; -+ -+ guard(mutex)(&chip->lock); -+ -+ for (int patt = 0; patt < len; patt++) { -+ if (pattern[patt].delta_t < ST1202_MILLIS_PATTERN_DUR_MIN || -+ pattern[patt].delta_t > ST1202_MILLIS_PATTERN_DUR_MAX) -+ return -EINVAL; -+ -+ ret = st1202_pwm_pattern_write(chip, led->led_num, patt, pattern[patt].brightness); -+ if (ret != 0) -+ return ret; -+ -+ ret = st1202_duration_pattern_write(chip, patt, pattern[patt].delta_t); -+ if (ret != 0) -+ return ret; -+ } -+ -+ ret = st1202_write_reg(chip, ST1202_PATTERN_REP, repeat); -+ if (ret != 0) -+ return ret; -+ -+ ret = st1202_write_reg(chip, ST1202_CONFIG_REG, (ST1202_CONFIG_REG_PATSR | -+ ST1202_CONFIG_REG_PATS | ST1202_CONFIG_REG_SHFT)); -+ if (ret != 0) -+ return ret; -+ -+ return 0; -+} -+ -+static int st1202_dt_init(struct st1202_chip *chip) -+{ -+ struct device *dev = &chip->client->dev; -+ struct st1202_led *led; -+ int err, reg; -+ -+ for_each_available_child_of_node_scoped(dev_of_node(dev), child) { -+ struct led_init_data init_data = {}; -+ -+ err = of_property_read_u32(child, "reg", ®); -+ if (err) -+ return dev_err_probe(dev, err, "Invalid register\n"); -+ -+ led = &chip->leds[reg]; -+ led->is_active = true; -+ led->fwnode = of_fwnode_handle(child); -+ -+ led->led_cdev.max_brightness = U8_MAX; -+ led->led_cdev.brightness_set_blocking = st1202_led_set; -+ led->led_cdev.pattern_set = st1202_led_pattern_set; -+ led->led_cdev.pattern_clear = st1202_led_pattern_clear; -+ led->led_cdev.default_trigger = "pattern"; -+ -+ init_data.fwnode = led->fwnode; -+ init_data.devicename = "st1202"; -+ init_data.default_label = ":"; -+ -+ err = devm_led_classdev_register_ext(dev, &led->led_cdev, &init_data); -+ if (err < 0) -+ return dev_err_probe(dev, err, "Failed to register LED class device\n"); -+ -+ led->led_cdev.brightness_set = st1202_brightness_set; -+ led->led_cdev.brightness_get = st1202_brightness_get; -+ } -+ -+ return 0; -+} -+ -+static int st1202_setup(struct st1202_chip *chip) -+{ -+ int ret; -+ -+ guard(mutex)(&chip->lock); -+ -+ /* -+ * Once the supply voltage is applied, the LED1202 executes some internal checks, -+ * afterwords it stops the oscillator and puts the internal LDO in quiescent mode. -+ * To start the device, EN bit must be set inside the “Device Enable” register at -+ * address 01h. As soon as EN is set, the LED1202 loads the adjustment parameters -+ * from the internal non-volatile memory and performs an auto-calibration procedure -+ * in order to increase the output current precision. -+ * Such initialization lasts about 6.5 ms. -+ */ -+ -+ /* Reset the chip during setup */ -+ ret = st1202_write_reg(chip, ST1202_DEV_ENABLE, ST1202_DEV_ENABLE_RESET); -+ if (ret < 0) -+ return ret; -+ -+ /* Enable phase-shift delay feature */ -+ ret = st1202_write_reg(chip, ST1202_CONFIG_REG, ST1202_CONFIG_REG_SHFT); -+ if (ret < 0) -+ return ret; -+ -+ /* Enable the device */ -+ ret = st1202_write_reg(chip, ST1202_DEV_ENABLE, ST1202_DEV_ENABLE_ON); -+ if (ret < 0) -+ return ret; -+ -+ /* Duration of initialization */ -+ usleep_range(6500, 10000); -+ -+ /* Deactivate all LEDS (channels) and activate only the ones found in Device Tree */ -+ ret = st1202_write_reg(chip, ST1202_CHAN_ENABLE_LOW, ST1202_CHAN_DISABLE_ALL); -+ if (ret < 0) -+ return ret; -+ -+ ret = st1202_write_reg(chip, ST1202_CHAN_ENABLE_HIGH, ST1202_CHAN_DISABLE_ALL); -+ if (ret < 0) -+ return ret; -+ -+ ret = st1202_write_reg(chip, ST1202_CONFIG_REG, -+ ST1202_CONFIG_REG_PATS | ST1202_CONFIG_REG_PATSR); -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+static int st1202_probe(struct i2c_client *client) -+{ -+ struct st1202_chip *chip; -+ struct st1202_led *led; -+ int ret; -+ -+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) -+ return dev_err_probe(&client->dev, -EIO, "SMBUS Byte Data not Supported\n"); -+ -+ chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); -+ if (!chip) -+ return -ENOMEM; -+ -+ devm_mutex_init(&client->dev, &chip->lock); -+ chip->client = client; -+ -+ ret = st1202_dt_init(chip); -+ if (ret < 0) -+ return ret; -+ -+ ret = st1202_setup(chip); -+ if (ret < 0) -+ return ret; -+ -+ for (int i = 0; i < ST1202_MAX_LEDS; i++) { -+ led = &chip->leds[i]; -+ led->chip = chip; -+ led->led_num = i; -+ -+ if (!led->is_active) -+ continue; -+ -+ ret = st1202_channel_set(led->chip, led->led_num, true); -+ if (ret < 0) -+ return dev_err_probe(&client->dev, ret, -+ "Failed to activate LED channel\n"); -+ -+ ret = st1202_led_pattern_clear(&led->led_cdev); -+ if (ret < 0) -+ return dev_err_probe(&client->dev, ret, -+ "Failed to clear LED pattern\n"); -+ } -+ -+ return 0; -+} -+ -+static const struct i2c_device_id st1202_id[] = { -+ { "st1202-i2c" }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(i2c, st1202_id); -+ -+static const struct of_device_id st1202_dt_ids[] = { -+ { .compatible = "st,led1202" }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, st1202_dt_ids); -+ -+static struct i2c_driver st1202_driver = { -+ .driver = { -+ .name = "leds-st1202", -+ .of_match_table = of_match_ptr(st1202_dt_ids), -+ }, -+ .probe = st1202_probe, -+ .id_table = st1202_id, -+}; -+module_i2c_driver(st1202_driver); -+ -+MODULE_AUTHOR("Remote Tech LTD"); -+MODULE_DESCRIPTION("STMicroelectronics LED1202 : 12-channel constant current LED driver"); -+MODULE_LICENSE("GPL"); --- -2.51.0 - - -From d379a1ad8f3ca2546f188f019764f46e06fdf24e Mon Sep 17 00:00:00 2001 -From: Manuel Fombuena -Date: Fri, 17 Jan 2025 12:31:49 +0000 -Subject: [PATCH 328/517] leds: leds-st1202: fix NULL pointer access on race - condition - -st1202_dt_init() calls devm_led_classdev_register_ext() before the -internal data structures are properly setup, so the leds become visible -to user space while being partially initialized, leading to a window -where trying to access them causes a NULL pointer access. - -This change moves devm_led_classdev_register_ext() to the last thing to -happen during initialization to eliminate it. - -Signed-off-by: Manuel Fombuena ---- - drivers/leds/leds-st1202.c | 21 ++++++++++----------- - 1 file changed, 10 insertions(+), 11 deletions(-) - -diff --git a/drivers/leds/leds-st1202.c b/drivers/leds/leds-st1202.c -index b691c4886993..e894b3f9a0f4 100644 ---- a/drivers/leds/leds-st1202.c -+++ b/drivers/leds/leds-st1202.c -@@ -261,8 +261,6 @@ static int st1202_dt_init(struct st1202_chip *chip) - int err, reg; - - for_each_available_child_of_node_scoped(dev_of_node(dev), child) { -- struct led_init_data init_data = {}; -- - err = of_property_read_u32(child, "reg", ®); - if (err) - return dev_err_probe(dev, err, "Invalid register\n"); -@@ -276,15 +274,6 @@ static int st1202_dt_init(struct st1202_chip *chip) - led->led_cdev.pattern_set = st1202_led_pattern_set; - led->led_cdev.pattern_clear = st1202_led_pattern_clear; - led->led_cdev.default_trigger = "pattern"; -- -- init_data.fwnode = led->fwnode; -- init_data.devicename = "st1202"; -- init_data.default_label = ":"; -- -- err = devm_led_classdev_register_ext(dev, &led->led_cdev, &init_data); -- if (err < 0) -- return dev_err_probe(dev, err, "Failed to register LED class device\n"); -- - led->led_cdev.brightness_set = st1202_brightness_set; - led->led_cdev.brightness_get = st1202_brightness_get; - } -@@ -368,6 +357,7 @@ static int st1202_probe(struct i2c_client *client) - return ret; - - for (int i = 0; i < ST1202_MAX_LEDS; i++) { -+ struct led_init_data init_data = {}; - led = &chip->leds[i]; - led->chip = chip; - led->led_num = i; -@@ -384,6 +374,15 @@ static int st1202_probe(struct i2c_client *client) - if (ret < 0) - return dev_err_probe(&client->dev, ret, - "Failed to clear LED pattern\n"); -+ -+ init_data.fwnode = led->fwnode; -+ init_data.devicename = "st1202"; -+ init_data.default_label = ":"; -+ -+ ret = devm_led_classdev_register_ext(&client->dev, &led->led_cdev, &init_data); -+ if (ret < 0) -+ return dev_err_probe(&client->dev, ret, -+ "Failed to register LED class device\n"); - } - - return 0; --- -2.51.0 - - -From 563309444342b92bf2a677a057a3ed0753c5a2d6 Mon Sep 17 00:00:00 2001 -From: Oskari Lemmela -Date: Sat, 13 Jul 2024 18:56:59 +0300 -Subject: [PATCH 329/517] net: ag71xx: fix qca9530 and qca9550 mdio probe - -Newer QCA9530 and QCA9550 devices should use same div table as AR933X. - -Fixes: d51b6ce441d3 ("net: ethernet: add ag71xx driver") -Signed-off-by: Oskari Lemmela ---- - drivers/net/ethernet/atheros/ag71xx.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/ethernet/atheros/ag71xx.c b/drivers/net/ethernet/atheros/ag71xx.c -index bccc7e7b2a84..adac0a9e0ceb 100644 ---- a/drivers/net/ethernet/atheros/ag71xx.c -+++ b/drivers/net/ethernet/atheros/ag71xx.c -@@ -641,7 +641,8 @@ static int ag71xx_mdio_get_divider(struct ag71xx *ag, u32 *div) - if (!ref_clock) - return -EINVAL; - -- if (ag71xx_is(ag, AR9330) || ag71xx_is(ag, AR9340)) { -+ if (ag71xx_is(ag, AR9330) || ag71xx_is(ag, AR9340) || -+ ag71xx_is(ag, QCA9530) || ag71xx_is(ag, QCA9550)) { - table = ar933x_mdio_div_table; - ndivs = ARRAY_SIZE(ar933x_mdio_div_table); - } else if (ag71xx_is(ag, AR7240)) { --- -2.51.0 - - -From d35ab9470d3d007cfbae608b5c50dabc29299843 Mon Sep 17 00:00:00 2001 -From: Imre Kaloz -Date: Mon, 3 Nov 2025 15:50:14 +0100 -Subject: [PATCH 330/517] init: add CONFIG_MANGLE_BOOTARGS and disable it by - default - -Enabling this option renames the bootloader supplied root= -and rootfstype= variables, which might have to be know but -would break the automatisms OpenWrt uses. - -Signed-off-by: Imre Kaloz ---- - init/Kconfig | 9 +++++++++ - init/main.c | 24 ++++++++++++++++++++++++ - 2 files changed, 33 insertions(+) - -diff --git a/init/Kconfig b/init/Kconfig -index 9b04e413be82..0de264f33b49 100644 ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -1888,6 +1888,15 @@ config ARCH_HAS_MEMBARRIER_CALLBACKS - config ARCH_HAS_MEMBARRIER_SYNC_CORE - bool - -+config MANGLE_BOOTARGS -+ bool "Rename offending bootargs" -+ depends on EXPERT -+ help -+ Sometimes the bootloader passed bogus root= and rootfstype= -+ parameters to the kernel, and while you want to ignore them, -+ you need to know the values f.e. to support dual firmware -+ layouts on the flash. -+ - config HAVE_PERF_EVENTS - bool - help -diff --git a/init/main.c b/init/main.c -index 821df1f05e9c..13fdc3236647 100644 ---- a/init/main.c -+++ b/init/main.c -@@ -633,6 +633,29 @@ static inline void setup_nr_cpu_ids(void) { } - static inline void smp_prepare_cpus(unsigned int maxcpus) { } - #endif - -+#ifdef CONFIG_MANGLE_BOOTARGS -+static void __init mangle_bootargs(char *command_line) -+{ -+ char *rootdev; -+ char *rootfs; -+ -+ rootdev = strstr(command_line, "root=/dev/mtdblock"); -+ -+ if (rootdev) -+ strncpy(rootdev, "mangled_rootblock=", 18); -+ -+ rootfs = strstr(command_line, "rootfstype"); -+ -+ if (rootfs) -+ strncpy(rootfs, "mangled_fs", 10); -+ -+} -+#else -+static void __init mangle_bootargs(char *command_line) -+{ -+} -+#endif -+ - /* - * We need to store the untouched command line for future reference. - * We also need to store the touched command line since the parameter -@@ -939,6 +962,7 @@ void start_kernel(void) - jump_label_init(); - static_call_init(); - early_security_init(); -+ mangle_bootargs(command_line); - setup_boot_config(); - setup_command_line(command_line); - setup_nr_cpu_ids(); --- -2.51.0 - - -From 8ffc66f125f867d5a7b40ab3b1e0735ec30b7e2f Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Tue, 7 May 2024 12:22:15 +0200 -Subject: [PATCH 331/517] kernel: fix tools build breakage on macos with x86 - -Signed-off-by: Felix Fietkau ---- - tools/arch/x86/include/asm/insn.h | 2 +- - tools/arch/x86/include/asm/orc_types.h | 10 ++++++++++ - tools/arch/x86/lib/insn.c | 4 ++++ - tools/include/asm-generic/bitops/fls.h | 3 +++ - tools/include/linux/rbtree.h | 1 - - tools/include/linux/types.h | 1 + - tools/lib/string.c | 2 ++ - tools/lib/subcmd/exec-cmd.c | 3 +++ - tools/objtool/Makefile | 2 ++ - tools/objtool/include/objtool/objtool.h | 1 + - tools/scripts/Makefile.include | 10 ++++++---- - 11 files changed, 33 insertions(+), 6 deletions(-) - -diff --git a/tools/arch/x86/include/asm/insn.h b/tools/arch/x86/include/asm/insn.h -index 0e5abd896ad4..f65f0f2a5466 100644 ---- a/tools/arch/x86/include/asm/insn.h -+++ b/tools/arch/x86/include/asm/insn.h -@@ -7,7 +7,7 @@ - * Copyright (C) IBM Corporation, 2009 - */ - --#include -+#include - /* insn_attr_t is defined in inat.h */ - #include "inat.h" /* __ignore_sync_check__ */ - -diff --git a/tools/arch/x86/include/asm/orc_types.h b/tools/arch/x86/include/asm/orc_types.h -index 46d7e06763c9..6e4afd2ec247 100644 ---- a/tools/arch/x86/include/asm/orc_types.h -+++ b/tools/arch/x86/include/asm/orc_types.h -@@ -46,7 +46,17 @@ - #define ORC_TYPE_REGS_PARTIAL 4 - - #ifndef __ASSEMBLY__ -+#ifdef __APPLE__ -+#include -+ -+#if __BYTE_ORDER == __LITTLE_ENDIAN -+#define __LITTLE_ENDIAN_BITFIELD -+#elif __BYTE_ORDER == __BIG_ENDIAN -+#define __BIG_ENDIAN_BITFIELD -+#endif -+#else - #include -+#endif - - /* - * This struct is more or less a vastly simplified version of the DWARF Call -diff --git a/tools/arch/x86/lib/insn.c b/tools/arch/x86/lib/insn.c -index e91d4c4e1c16..613539c3b015 100644 ---- a/tools/arch/x86/lib/insn.c -+++ b/tools/arch/x86/lib/insn.c -@@ -15,7 +15,11 @@ - #include "../include/asm/insn.h" /* __ignore_sync_check__ */ - #include /* __ignore_sync_check__ */ - -+#ifdef __KERNEL__ - #include -+#else -+#include -+#endif - #include - - #include "../include/asm/emulate_prefix.h" /* __ignore_sync_check__ */ -diff --git a/tools/include/asm-generic/bitops/fls.h b/tools/include/asm-generic/bitops/fls.h -index 26f3ce1dd6e4..d028c2eab89b 100644 ---- a/tools/include/asm-generic/bitops/fls.h -+++ b/tools/include/asm-generic/bitops/fls.h -@@ -2,6 +2,8 @@ - #ifndef _ASM_GENERIC_BITOPS_FLS_H_ - #define _ASM_GENERIC_BITOPS_FLS_H_ - -+#include -+ - /** - * generic_fls - find last (most-significant) bit set - * @x: the word to search -@@ -10,6 +12,7 @@ - * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. - */ - -+#define generic_fls __linux_fls - static __always_inline int generic_fls(unsigned int x) - { - int r = 32; -diff --git a/tools/include/linux/rbtree.h b/tools/include/linux/rbtree.h -index 2680f2edb837..656890130ffd 100644 ---- a/tools/include/linux/rbtree.h -+++ b/tools/include/linux/rbtree.h -@@ -18,7 +18,6 @@ - #define __TOOLS_LINUX_PERF_RBTREE_H - - #include --#include - - struct rb_node { - unsigned long __rb_parent_color; -diff --git a/tools/include/linux/types.h b/tools/include/linux/types.h -index 8519386acd23..be6804eb9f82 100644 ---- a/tools/include/linux/types.h -+++ b/tools/include/linux/types.h -@@ -56,6 +56,7 @@ typedef __s8 s8; - #define __user - #endif - #define __must_check -+#undef __cold - #define __cold - - typedef __u16 __bitwise __le16; -diff --git a/tools/lib/string.c b/tools/lib/string.c -index 3126d2cff716..5016d4ccae24 100644 ---- a/tools/lib/string.c -+++ b/tools/lib/string.c -@@ -96,6 +96,7 @@ int strtobool(const char *s, bool *res) - * If libc has strlcpy() then that version will override this - * implementation: - */ -+#ifndef __APPLE__ - #ifdef __clang__ - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wignored-attributes" -@@ -114,6 +115,7 @@ size_t __weak strlcpy(char *dest, const char *src, size_t size) - #ifdef __clang__ - #pragma clang diagnostic pop - #endif -+#endif - - /** - * skip_spaces - Removes leading whitespace from @str. -diff --git a/tools/lib/subcmd/exec-cmd.c b/tools/lib/subcmd/exec-cmd.c -index 7739b5217cf6..dc82cacd82cb 100644 ---- a/tools/lib/subcmd/exec-cmd.c -+++ b/tools/lib/subcmd/exec-cmd.c -@@ -12,7 +12,10 @@ - #include "subcmd-config.h" - - #define MAX_ARGS 32 -+ -+#ifndef PATH_MAX - #define PATH_MAX 4096 -+#endif - - static const char *argv_exec_path; - static const char *argv0_path; -diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile -index bf7f7f84ac62..aa6deced92d2 100644 ---- a/tools/objtool/Makefile -+++ b/tools/objtool/Makefile -@@ -39,6 +39,8 @@ OBJTOOL_LDFLAGS := $(LIBELF_LIBS) $(LIBSUBCMD) $(KBUILD_HOSTLDFLAGS) - elfshdr := $(shell echo '$(pound)include ' | $(HOSTCC) $(OBJTOOL_CFLAGS) -x c -E - | grep elf_getshdr) - OBJTOOL_CFLAGS += $(if $(elfshdr),,-DLIBELF_USE_DEPRECATED) - -+OBJTOOL_CFLAGS += $(HOST_EXTRACFLAGS) -+ - # Always want host compilation. - HOST_OVERRIDES := CC="$(HOSTCC)" LD="$(HOSTLD)" AR="$(HOSTAR)" - -diff --git a/tools/objtool/include/objtool/objtool.h b/tools/objtool/include/objtool/objtool.h -index 94a33ee7b363..f34332e00155 100644 ---- a/tools/objtool/include/objtool/objtool.h -+++ b/tools/objtool/include/objtool/objtool.h -@@ -12,6 +12,7 @@ - - #include - -+#undef __weak - #define __weak __attribute__((weak)) - - struct pv_state { -diff --git a/tools/scripts/Makefile.include b/tools/scripts/Makefile.include -index 5f2afd95de43..dd3369624bdb 100644 ---- a/tools/scripts/Makefile.include -+++ b/tools/scripts/Makefile.include -@@ -72,8 +72,6 @@ $(call allow-override,CXX,$(CROSS_COMPILE)g++) - $(call allow-override,STRIP,$(CROSS_COMPILE)strip) - endif - --CC_NO_CLANG := $(shell $(CC) -dM -E -x c /dev/null | grep -Fq "__clang__"; echo $$?) -- - ifneq ($(LLVM),) - HOSTAR ?= $(LLVM_PREFIX)llvm-ar$(LLVM_SUFFIX) - HOSTCC ?= $(LLVM_PREFIX)clang$(LLVM_SUFFIX) -@@ -84,6 +82,9 @@ HOSTCC ?= gcc - HOSTLD ?= ld - endif - -+CC_NO_CLANG := $(shell $(CC) -dM -E -x c /dev/null | grep -Fq "__clang__"; echo $$?) -+HOSTCC_NO_CLANG := $(shell $(HOSTCC) -dM -E -x c /dev/null | grep -Fq "__clang__"; echo $$?) -+ - # Some tools require Clang, LLC and/or LLVM utils - CLANG ?= clang - LLC ?= llc -@@ -92,8 +93,9 @@ LLVM_OBJCOPY ?= llvm-objcopy - LLVM_STRIP ?= llvm-strip - - ifeq ($(CC_NO_CLANG), 1) --EXTRA_WARNINGS += -Wstrict-aliasing=3 -- -+ ifeq ($(HOSTCC_NO_CLANG), 1) -+ EXTRA_WARNINGS += -Wstrict-aliasing=3 -+ endif - else ifneq ($(CROSS_COMPILE),) - # Allow userspace to override CLANG_CROSS_FLAGS to specify their own - # sysroots and flags or to avoid the GCC call in pure Clang builds. --- -2.51.0 - - -From c9d439a6002e088e00dda40c83df1e5fcd956ae4 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 7 Jul 2017 16:56:48 +0200 -Subject: [PATCH 332/517] build: add a hack for removing non-essential module - info - -Signed-off-by: Felix Fietkau ---- - include/linux/module.h | 13 ++++++++----- - include/linux/moduleparam.h | 12 +++++++++++- - kernel/module/Kconfig | 7 +++++++ - kernel/module/main.c | 7 ++++++- - scripts/mod/modpost.c | 10 ++++++++++ - 5 files changed, 42 insertions(+), 7 deletions(-) - -diff --git a/include/linux/module.h b/include/linux/module.h -index 7886217c9988..22566f9aa0ee 100644 ---- a/include/linux/module.h -+++ b/include/linux/module.h -@@ -166,6 +166,7 @@ struct module_kobject *lookup_or_create_module_kobject(const char *name); - - /* Generic info of form tag = "info" */ - #define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info) -+#define MODULE_INFO_STRIP(tag, info) __MODULE_INFO_STRIP(tag, tag, info) - - /* For userspace: you can also call me... */ - #define MODULE_ALIAS(_alias) MODULE_INFO(alias, _alias) -@@ -241,12 +242,12 @@ struct module_kobject *lookup_or_create_module_kobject(const char *name); - * Author(s), use "Name " or just "Name", for multiple - * authors use multiple MODULE_AUTHOR() statements/lines. - */ --#define MODULE_AUTHOR(_author) MODULE_INFO(author, _author) -+#define MODULE_AUTHOR(_author) MODULE_INFO_STRIP(author, _author) - - /* What your module does. */ --#define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description) -+#define MODULE_DESCRIPTION(_description) MODULE_INFO_STRIP(description, _description) - --#ifdef MODULE -+#if defined(MODULE) && !defined(CONFIG_MODULE_STRIPPED) - /* Creates an alias so file2alias.c can find device table. */ - #define MODULE_DEVICE_TABLE(type, name) \ - extern typeof(name) __mod_##type##__##name##_device_table \ -@@ -273,7 +274,9 @@ extern typeof(name) __mod_##type##__##name##_device_table \ - */ - - #if defined(MODULE) || !defined(CONFIG_SYSFS) --#define MODULE_VERSION(_version) MODULE_INFO(version, _version) -+#define MODULE_VERSION(_version) MODULE_INFO_STRIP(version, _version) -+#elif defined(CONFIG_MODULE_STRIPPED) -+#define MODULE_VERSION(_version) __MODULE_INFO_DISABLED(version) - #else - #define MODULE_VERSION(_version) \ - MODULE_INFO(version, _version); \ -@@ -296,7 +299,7 @@ extern typeof(name) __mod_##type##__##name##_device_table \ - /* Optional firmware file (or files) needed by the module - * format is simply firmware file name. Multiple firmware - * files require multiple MODULE_FIRMWARE() specifiers */ --#define MODULE_FIRMWARE(_firmware) MODULE_INFO(firmware, _firmware) -+#define MODULE_FIRMWARE(_firmware) MODULE_INFO_STRIP(firmware, _firmware) - - #define MODULE_IMPORT_NS(ns) MODULE_INFO(import_ns, __stringify(ns)) - -diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h -index 110e9d09de24..198f715e7bcc 100644 ---- a/include/linux/moduleparam.h -+++ b/include/linux/moduleparam.h -@@ -20,6 +20,16 @@ - /* Chosen so that structs with an unsigned long line up. */ - #define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long)) - -+/* This struct is here for syntactic coherency, it is not used */ -+#define __MODULE_INFO_DISABLED(name) \ -+ struct __UNIQUE_ID(name) {} -+ -+#ifdef CONFIG_MODULE_STRIPPED -+#define __MODULE_INFO_STRIP(tag, name, info) __MODULE_INFO_DISABLED(name) -+#else -+#define __MODULE_INFO_STRIP(tag, name, info) __MODULE_INFO(tag, name, info) -+#endif -+ - #define __MODULE_INFO(tag, name, info) \ - static const char __UNIQUE_ID(name)[] \ - __used __section(".modinfo") __aligned(1) \ -@@ -31,7 +41,7 @@ - /* One for each parameter, describing how to use it. Some files do - multiple of these per line, so can't just use MODULE_INFO. */ - #define MODULE_PARM_DESC(_parm, desc) \ -- __MODULE_INFO(parm, _parm, #_parm ":" desc) -+ __MODULE_INFO_STRIP(parm, _parm, #_parm ":" desc) - - struct kernel_param; - -diff --git a/kernel/module/Kconfig b/kernel/module/Kconfig -index 0c746a150e34..ccc20082d0f0 100644 ---- a/kernel/module/Kconfig -+++ b/kernel/module/Kconfig -@@ -402,4 +402,11 @@ config MODULES_TREE_LOOKUP - def_bool y - depends on PERF_EVENTS || TRACING || CFI_CLANG - -+config MODULE_STRIPPED -+ bool "Reduce module size" -+ depends on MODULES -+ help -+ Remove module parameter descriptions, author info, version, aliases, -+ device tables, etc. -+ - endif # MODULES -diff --git a/kernel/module/main.c b/kernel/module/main.c -index 4511d0a4762a..2122fab827f1 100644 ---- a/kernel/module/main.c -+++ b/kernel/module/main.c -@@ -1001,6 +1001,7 @@ size_t modinfo_attrs_count = ARRAY_SIZE(modinfo_attrs); - - static const char vermagic[] = VERMAGIC_STRING; - -+#if defined(CONFIG_MODVERSIONS) || !defined(CONFIG_MODULE_STRIPPED) - int try_to_force_load(struct module *mod, const char *reason) - { - #ifdef CONFIG_MODULE_FORCE_LOAD -@@ -1012,6 +1013,7 @@ int try_to_force_load(struct module *mod, const char *reason) - return -ENOEXEC; - #endif - } -+#endif - - /* Parse tag=value strings from .modinfo section */ - char *module_next_tag_pair(char *string, unsigned long *secsize) -@@ -2095,9 +2097,11 @@ static void module_augment_kernel_taints(struct module *mod, struct load_info *i - - static int check_modinfo(struct module *mod, struct load_info *info, int flags) - { -- const char *modmagic = get_modinfo(info, "vermagic"); - int err; - -+#ifndef CONFIG_MODULE_STRIPPED -+ const char *modmagic = get_modinfo(info, "vermagic"); -+ - if (flags & MODULE_INIT_IGNORE_VERMAGIC) - modmagic = NULL; - -@@ -2111,6 +2115,7 @@ static int check_modinfo(struct module *mod, struct load_info *info, int flags) - info->name, modmagic, vermagic); - return -ENOEXEC; - } -+#endif - - err = check_modinfo_livepatch(mod, info); - if (err) -diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c -index 971eda0c6ba7..f90320fdea74 100644 ---- a/scripts/mod/modpost.c -+++ b/scripts/mod/modpost.c -@@ -1601,7 +1601,9 @@ static void read_symbols(const char *modname) - symname = remove_dot(info.strtab + sym->st_name); - - handle_symbol(mod, &info, sym, symname); -+#ifndef CONFIG_MODULE_STRIPPED - handle_moddevtable(mod, &info, sym, symname); -+#endif - } - - check_sec_ref(mod, &info); -@@ -1758,7 +1760,9 @@ static void add_header(struct buffer *b, struct module *mod) - buf_printf(b, "#include \n"); - buf_printf(b, "#include \n"); - buf_printf(b, "\n"); -+#ifndef CONFIG_MODULE_STRIPPED - buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n"); -+#endif - buf_printf(b, "\n"); - buf_printf(b, "__visible struct module __this_module\n"); - buf_printf(b, "__section(\".gnu.linkonce.this_module\") = {\n"); -@@ -1772,11 +1776,13 @@ static void add_header(struct buffer *b, struct module *mod) - buf_printf(b, "\t.arch = MODULE_ARCH_INIT,\n"); - buf_printf(b, "};\n"); - -+#ifndef CONFIG_MODULE_STRIPPED - if (!external_module) - buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n"); - - if (strstarts(mod->name, "drivers/staging")) - buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n"); -+#endif - - if (strstarts(mod->name, "tools/testing")) - buf_printf(b, "\nMODULE_INFO(test, \"Y\");\n"); -@@ -1886,11 +1892,13 @@ static void add_depends(struct buffer *b, struct module *mod) - - static void add_srcversion(struct buffer *b, struct module *mod) - { -+#ifndef CONFIG_MODULE_STRIPPED - if (mod->srcversion[0]) { - buf_printf(b, "\n"); - buf_printf(b, "MODULE_INFO(srcversion, \"%s\");\n", - mod->srcversion); - } -+#endif - } - - static void write_buf(struct buffer *b, const char *fname) -@@ -1973,7 +1981,9 @@ static void write_mod_c_file(struct module *mod) - add_exported_symbols(&buf, mod); - add_versions(&buf, mod); - add_depends(&buf, mod); -+#ifndef CONFIG_MODULE_STRIPPED - add_moddevtable(&buf, mod); -+#endif - add_srcversion(&buf, mod); - - ret = snprintf(fname, sizeof(fname), "%s.mod.c", mod->name); --- -2.51.0 - - -From b3b18ef0e01eaa79077ae5c4f669df7d62d59695 Mon Sep 17 00:00:00 2001 -From: David Bauer -Date: Fri, 11 Nov 2022 13:33:44 +0100 -Subject: [PATCH 333/517] kconfig: abort configuration on unset symbol - -When a target configuration has unset Kconfig symbols, the build will -fail when OpenWrt is compiled with V=s and stdin is connected to a tty. - -In case OpenWrt is compiled without either of these preconditions, the -build will succeed with the symbols in question being unset. - -Modify the kernel configuration in a way it fails on unset symbols -regardless of the aforementioned preconditions. - -Signed-off-by: David Bauer ---- - scripts/kconfig/conf.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c -index 3d7d454c54da..d260f1519722 100644 ---- a/scripts/kconfig/conf.c -+++ b/scripts/kconfig/conf.c -@@ -312,6 +312,9 @@ static int conf_askvalue(struct symbol *sym, const char *def) - } - /* fall through */ - default: -+ if (!tty_stdio && getenv("FAIL_ON_UNCONFIGURED")) { -+ exit(1); -+ } - fflush(stdout); - xfgets(line, sizeof(line), stdin); - break; -@@ -470,6 +473,9 @@ static void conf_choice(struct menu *menu) - } - /* fall through */ - case oldaskconfig: -+ if (!tty_stdio && getenv("FAIL_ON_UNCONFIGURED")) { -+ exit(1); -+ } - fflush(stdout); - xfgets(line, sizeof(line), stdin); - strip(line); --- -2.51.0 - - -From e94565caa2778a2c0a56e359b47169cea8111d3f Mon Sep 17 00:00:00 2001 -From: Florian Fainelli -Date: Fri, 7 Jul 2017 17:00:49 +0200 -Subject: [PATCH 334/517] Add an OSX specific patch to make the kernel be - compiled - -lede-commit: 3fc2a24f0422b2f55f9ed43f116db3111f700526 -Signed-off-by: Florian Fainelli ---- - scripts/mod/elf.h | 3007 ++++++++++++++++++++++++++++++++++++ - scripts/mod/mk_elfconfig.c | 4 + - scripts/mod/modpost.h | 4 + - 3 files changed, 3015 insertions(+) - create mode 100644 scripts/mod/elf.h - -diff --git a/scripts/mod/elf.h b/scripts/mod/elf.h -new file mode 100644 -index 000000000000..036a176345eb ---- /dev/null -+++ b/scripts/mod/elf.h -@@ -0,0 +1,3007 @@ -+/* This file defines standard ELF types, structures, and macros. -+ Copyright (C) 1995-2012 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+#ifndef _ELF_H -+#define _ELF_H 1 -+ -+/* Standard ELF types. */ -+ -+#include -+ -+/* Type for a 16-bit quantity. */ -+typedef uint16_t Elf32_Half; -+typedef uint16_t Elf64_Half; -+ -+/* Types for signed and unsigned 32-bit quantities. */ -+typedef uint32_t Elf32_Word; -+typedef int32_t Elf32_Sword; -+typedef uint32_t Elf64_Word; -+typedef int32_t Elf64_Sword; -+ -+/* Types for signed and unsigned 64-bit quantities. */ -+typedef uint64_t Elf32_Xword; -+typedef int64_t Elf32_Sxword; -+typedef uint64_t Elf64_Xword; -+typedef int64_t Elf64_Sxword; -+ -+/* Type of addresses. */ -+typedef uint32_t Elf32_Addr; -+typedef uint64_t Elf64_Addr; -+ -+/* Type of file offsets. */ -+typedef uint32_t Elf32_Off; -+typedef uint64_t Elf64_Off; -+ -+/* Type for section indices, which are 16-bit quantities. */ -+typedef uint16_t Elf32_Section; -+typedef uint16_t Elf64_Section; -+ -+/* Type for version symbol information. */ -+typedef Elf32_Half Elf32_Versym; -+typedef Elf64_Half Elf64_Versym; -+ -+ -+/* The ELF file header. This appears at the start of every ELF file. */ -+ -+#define EI_NIDENT (16) -+ -+typedef struct -+{ -+ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ -+ Elf32_Half e_type; /* Object file type */ -+ Elf32_Half e_machine; /* Architecture */ -+ Elf32_Word e_version; /* Object file version */ -+ Elf32_Addr e_entry; /* Entry point virtual address */ -+ Elf32_Off e_phoff; /* Program header table file offset */ -+ Elf32_Off e_shoff; /* Section header table file offset */ -+ Elf32_Word e_flags; /* Processor-specific flags */ -+ Elf32_Half e_ehsize; /* ELF header size in bytes */ -+ Elf32_Half e_phentsize; /* Program header table entry size */ -+ Elf32_Half e_phnum; /* Program header table entry count */ -+ Elf32_Half e_shentsize; /* Section header table entry size */ -+ Elf32_Half e_shnum; /* Section header table entry count */ -+ Elf32_Half e_shstrndx; /* Section header string table index */ -+} Elf32_Ehdr; -+ -+typedef struct -+{ -+ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ -+ Elf64_Half e_type; /* Object file type */ -+ Elf64_Half e_machine; /* Architecture */ -+ Elf64_Word e_version; /* Object file version */ -+ Elf64_Addr e_entry; /* Entry point virtual address */ -+ Elf64_Off e_phoff; /* Program header table file offset */ -+ Elf64_Off e_shoff; /* Section header table file offset */ -+ Elf64_Word e_flags; /* Processor-specific flags */ -+ Elf64_Half e_ehsize; /* ELF header size in bytes */ -+ Elf64_Half e_phentsize; /* Program header table entry size */ -+ Elf64_Half e_phnum; /* Program header table entry count */ -+ Elf64_Half e_shentsize; /* Section header table entry size */ -+ Elf64_Half e_shnum; /* Section header table entry count */ -+ Elf64_Half e_shstrndx; /* Section header string table index */ -+} Elf64_Ehdr; -+ -+/* Fields in the e_ident array. The EI_* macros are indices into the -+ array. The macros under each EI_* macro are the values the byte -+ may have. */ -+ -+#define EI_MAG0 0 /* File identification byte 0 index */ -+#define ELFMAG0 0x7f /* Magic number byte 0 */ -+ -+#define EI_MAG1 1 /* File identification byte 1 index */ -+#define ELFMAG1 'E' /* Magic number byte 1 */ -+ -+#define EI_MAG2 2 /* File identification byte 2 index */ -+#define ELFMAG2 'L' /* Magic number byte 2 */ -+ -+#define EI_MAG3 3 /* File identification byte 3 index */ -+#define ELFMAG3 'F' /* Magic number byte 3 */ -+ -+/* Conglomeration of the identification bytes, for easy testing as a word. */ -+#define ELFMAG "\177ELF" -+#define SELFMAG 4 -+ -+#define EI_CLASS 4 /* File class byte index */ -+#define ELFCLASSNONE 0 /* Invalid class */ -+#define ELFCLASS32 1 /* 32-bit objects */ -+#define ELFCLASS64 2 /* 64-bit objects */ -+#define ELFCLASSNUM 3 -+ -+#define EI_DATA 5 /* Data encoding byte index */ -+#define ELFDATANONE 0 /* Invalid data encoding */ -+#define ELFDATA2LSB 1 /* 2's complement, little endian */ -+#define ELFDATA2MSB 2 /* 2's complement, big endian */ -+#define ELFDATANUM 3 -+ -+#define EI_VERSION 6 /* File version byte index */ -+ /* Value must be EV_CURRENT */ -+ -+#define EI_OSABI 7 /* OS ABI identification */ -+#define ELFOSABI_NONE 0 /* UNIX System V ABI */ -+#define ELFOSABI_SYSV 0 /* Alias. */ -+#define ELFOSABI_HPUX 1 /* HP-UX */ -+#define ELFOSABI_NETBSD 2 /* NetBSD. */ -+#define ELFOSABI_GNU 3 /* Object uses GNU ELF extensions. */ -+#define ELFOSABI_LINUX ELFOSABI_GNU /* Compatibility alias. */ -+#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */ -+#define ELFOSABI_AIX 7 /* IBM AIX. */ -+#define ELFOSABI_IRIX 8 /* SGI Irix. */ -+#define ELFOSABI_FREEBSD 9 /* FreeBSD. */ -+#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */ -+#define ELFOSABI_MODESTO 11 /* Novell Modesto. */ -+#define ELFOSABI_OPENBSD 12 /* OpenBSD. */ -+#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */ -+#define ELFOSABI_ARM 97 /* ARM */ -+#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ -+ -+#define EI_ABIVERSION 8 /* ABI version */ -+ -+#define EI_PAD 9 /* Byte index of padding bytes */ -+ -+/* Legal values for e_type (object file type). */ -+ -+#define ET_NONE 0 /* No file type */ -+#define ET_REL 1 /* Relocatable file */ -+#define ET_EXEC 2 /* Executable file */ -+#define ET_DYN 3 /* Shared object file */ -+#define ET_CORE 4 /* Core file */ -+#define ET_NUM 5 /* Number of defined types */ -+#define ET_LOOS 0xfe00 /* OS-specific range start */ -+#define ET_HIOS 0xfeff /* OS-specific range end */ -+#define ET_LOPROC 0xff00 /* Processor-specific range start */ -+#define ET_HIPROC 0xffff /* Processor-specific range end */ -+ -+/* Legal values for e_machine (architecture). */ -+ -+#define EM_NONE 0 /* No machine */ -+#define EM_M32 1 /* AT&T WE 32100 */ -+#define EM_SPARC 2 /* SUN SPARC */ -+#define EM_386 3 /* Intel 80386 */ -+#define EM_68K 4 /* Motorola m68k family */ -+#define EM_88K 5 /* Motorola m88k family */ -+#define EM_860 7 /* Intel 80860 */ -+#define EM_MIPS 8 /* MIPS R3000 big-endian */ -+#define EM_S370 9 /* IBM System/370 */ -+#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */ -+ -+#define EM_PARISC 15 /* HPPA */ -+#define EM_VPP500 17 /* Fujitsu VPP500 */ -+#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ -+#define EM_960 19 /* Intel 80960 */ -+#define EM_PPC 20 /* PowerPC */ -+#define EM_PPC64 21 /* PowerPC 64-bit */ -+#define EM_S390 22 /* IBM S390 */ -+ -+#define EM_V800 36 /* NEC V800 series */ -+#define EM_FR20 37 /* Fujitsu FR20 */ -+#define EM_RH32 38 /* TRW RH-32 */ -+#define EM_RCE 39 /* Motorola RCE */ -+#define EM_ARM 40 /* ARM */ -+#define EM_FAKE_ALPHA 41 /* Digital Alpha */ -+#define EM_SH 42 /* Hitachi SH */ -+#define EM_SPARCV9 43 /* SPARC v9 64-bit */ -+#define EM_TRICORE 44 /* Siemens Tricore */ -+#define EM_ARC 45 /* Argonaut RISC Core */ -+#define EM_H8_300 46 /* Hitachi H8/300 */ -+#define EM_H8_300H 47 /* Hitachi H8/300H */ -+#define EM_H8S 48 /* Hitachi H8S */ -+#define EM_H8_500 49 /* Hitachi H8/500 */ -+#define EM_IA_64 50 /* Intel Merced */ -+#define EM_MIPS_X 51 /* Stanford MIPS-X */ -+#define EM_COLDFIRE 52 /* Motorola Coldfire */ -+#define EM_68HC12 53 /* Motorola M68HC12 */ -+#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/ -+#define EM_PCP 55 /* Siemens PCP */ -+#define EM_NCPU 56 /* Sony nCPU embeeded RISC */ -+#define EM_NDR1 57 /* Denso NDR1 microprocessor */ -+#define EM_STARCORE 58 /* Motorola Start*Core processor */ -+#define EM_ME16 59 /* Toyota ME16 processor */ -+#define EM_ST100 60 /* STMicroelectronic ST100 processor */ -+#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/ -+#define EM_X86_64 62 /* AMD x86-64 architecture */ -+#define EM_PDSP 63 /* Sony DSP Processor */ -+ -+#define EM_FX66 66 /* Siemens FX66 microcontroller */ -+#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */ -+#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */ -+#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */ -+#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */ -+#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */ -+#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */ -+#define EM_SVX 73 /* Silicon Graphics SVx */ -+#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */ -+#define EM_VAX 75 /* Digital VAX */ -+#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */ -+#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */ -+#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ -+#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ -+#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */ -+#define EM_HUANY 81 /* Harvard University machine-independent object files */ -+#define EM_PRISM 82 /* SiTera Prism */ -+#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ -+#define EM_FR30 84 /* Fujitsu FR30 */ -+#define EM_D10V 85 /* Mitsubishi D10V */ -+#define EM_D30V 86 /* Mitsubishi D30V */ -+#define EM_V850 87 /* NEC v850 */ -+#define EM_M32R 88 /* Mitsubishi M32R */ -+#define EM_MN10300 89 /* Matsushita MN10300 */ -+#define EM_MN10200 90 /* Matsushita MN10200 */ -+#define EM_PJ 91 /* picoJava */ -+#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ -+#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ -+#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ -+#define EM_TILEPRO 188 /* Tilera TILEPro */ -+#define EM_TILEGX 191 /* Tilera TILE-Gx */ -+#define EM_NUM 192 -+ -+/* If it is necessary to assign new unofficial EM_* values, please -+ pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the -+ chances of collision with official or non-GNU unofficial values. */ -+ -+#define EM_ALPHA 0x9026 -+ -+/* Legal values for e_version (version). */ -+ -+#define EV_NONE 0 /* Invalid ELF version */ -+#define EV_CURRENT 1 /* Current version */ -+#define EV_NUM 2 -+ -+/* Section header. */ -+ -+typedef struct -+{ -+ Elf32_Word sh_name; /* Section name (string tbl index) */ -+ Elf32_Word sh_type; /* Section type */ -+ Elf32_Word sh_flags; /* Section flags */ -+ Elf32_Addr sh_addr; /* Section virtual addr at execution */ -+ Elf32_Off sh_offset; /* Section file offset */ -+ Elf32_Word sh_size; /* Section size in bytes */ -+ Elf32_Word sh_link; /* Link to another section */ -+ Elf32_Word sh_info; /* Additional section information */ -+ Elf32_Word sh_addralign; /* Section alignment */ -+ Elf32_Word sh_entsize; /* Entry size if section holds table */ -+} Elf32_Shdr; -+ -+typedef struct -+{ -+ Elf64_Word sh_name; /* Section name (string tbl index) */ -+ Elf64_Word sh_type; /* Section type */ -+ Elf64_Xword sh_flags; /* Section flags */ -+ Elf64_Addr sh_addr; /* Section virtual addr at execution */ -+ Elf64_Off sh_offset; /* Section file offset */ -+ Elf64_Xword sh_size; /* Section size in bytes */ -+ Elf64_Word sh_link; /* Link to another section */ -+ Elf64_Word sh_info; /* Additional section information */ -+ Elf64_Xword sh_addralign; /* Section alignment */ -+ Elf64_Xword sh_entsize; /* Entry size if section holds table */ -+} Elf64_Shdr; -+ -+/* Special section indices. */ -+ -+#define SHN_UNDEF 0 /* Undefined section */ -+#define SHN_LORESERVE 0xff00 /* Start of reserved indices */ -+#define SHN_LOPROC 0xff00 /* Start of processor-specific */ -+#define SHN_BEFORE 0xff00 /* Order section before all others -+ (Solaris). */ -+#define SHN_AFTER 0xff01 /* Order section after all others -+ (Solaris). */ -+#define SHN_HIPROC 0xff1f /* End of processor-specific */ -+#define SHN_LOOS 0xff20 /* Start of OS-specific */ -+#define SHN_HIOS 0xff3f /* End of OS-specific */ -+#define SHN_ABS 0xfff1 /* Associated symbol is absolute */ -+#define SHN_COMMON 0xfff2 /* Associated symbol is common */ -+#define SHN_XINDEX 0xffff /* Index is in extra table. */ -+#define SHN_HIRESERVE 0xffff /* End of reserved indices */ -+ -+/* Legal values for sh_type (section type). */ -+ -+#define SHT_NULL 0 /* Section header table entry unused */ -+#define SHT_PROGBITS 1 /* Program data */ -+#define SHT_SYMTAB 2 /* Symbol table */ -+#define SHT_STRTAB 3 /* String table */ -+#define SHT_RELA 4 /* Relocation entries with addends */ -+#define SHT_HASH 5 /* Symbol hash table */ -+#define SHT_DYNAMIC 6 /* Dynamic linking information */ -+#define SHT_NOTE 7 /* Notes */ -+#define SHT_NOBITS 8 /* Program space with no data (bss) */ -+#define SHT_REL 9 /* Relocation entries, no addends */ -+#define SHT_SHLIB 10 /* Reserved */ -+#define SHT_DYNSYM 11 /* Dynamic linker symbol table */ -+#define SHT_INIT_ARRAY 14 /* Array of constructors */ -+#define SHT_FINI_ARRAY 15 /* Array of destructors */ -+#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ -+#define SHT_GROUP 17 /* Section group */ -+#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ -+#define SHT_NUM 19 /* Number of defined types. */ -+#define SHT_LOOS 0x60000000 /* Start OS-specific. */ -+#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */ -+#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */ -+#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */ -+#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */ -+#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */ -+#define SHT_SUNW_move 0x6ffffffa -+#define SHT_SUNW_COMDAT 0x6ffffffb -+#define SHT_SUNW_syminfo 0x6ffffffc -+#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */ -+#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */ -+#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */ -+#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */ -+#define SHT_HIOS 0x6fffffff /* End OS-specific type */ -+#define SHT_LOPROC 0x70000000 /* Start of processor-specific */ -+#define SHT_HIPROC 0x7fffffff /* End of processor-specific */ -+#define SHT_LOUSER 0x80000000 /* Start of application-specific */ -+#define SHT_HIUSER 0x8fffffff /* End of application-specific */ -+ -+/* Legal values for sh_flags (section flags). */ -+ -+#define SHF_WRITE (1 << 0) /* Writable */ -+#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */ -+#define SHF_EXECINSTR (1 << 2) /* Executable */ -+#define SHF_MERGE (1 << 4) /* Might be merged */ -+#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */ -+#define SHF_INFO_LINK (1 << 6) /* `sh_info' contains SHT index */ -+#define SHF_LINK_ORDER (1 << 7) /* Preserve order after combining */ -+#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling -+ required */ -+#define SHF_GROUP (1 << 9) /* Section is member of a group. */ -+#define SHF_TLS (1 << 10) /* Section hold thread-local data. */ -+#define SHF_MASKOS 0x0ff00000 /* OS-specific. */ -+#define SHF_MASKPROC 0xf0000000 /* Processor-specific */ -+#define SHF_ORDERED (1 << 30) /* Special ordering requirement -+ (Solaris). */ -+#define SHF_EXCLUDE (1 << 31) /* Section is excluded unless -+ referenced or allocated (Solaris).*/ -+ -+/* Section group handling. */ -+#define GRP_COMDAT 0x1 /* Mark group as COMDAT. */ -+ -+/* Symbol table entry. */ -+ -+typedef struct -+{ -+ Elf32_Word st_name; /* Symbol name (string tbl index) */ -+ Elf32_Addr st_value; /* Symbol value */ -+ Elf32_Word st_size; /* Symbol size */ -+ unsigned char st_info; /* Symbol type and binding */ -+ unsigned char st_other; /* Symbol visibility */ -+ Elf32_Section st_shndx; /* Section index */ -+} Elf32_Sym; -+ -+typedef struct -+{ -+ Elf64_Word st_name; /* Symbol name (string tbl index) */ -+ unsigned char st_info; /* Symbol type and binding */ -+ unsigned char st_other; /* Symbol visibility */ -+ Elf64_Section st_shndx; /* Section index */ -+ Elf64_Addr st_value; /* Symbol value */ -+ Elf64_Xword st_size; /* Symbol size */ -+} Elf64_Sym; -+ -+/* The syminfo section if available contains additional information about -+ every dynamic symbol. */ -+ -+typedef struct -+{ -+ Elf32_Half si_boundto; /* Direct bindings, symbol bound to */ -+ Elf32_Half si_flags; /* Per symbol flags */ -+} Elf32_Syminfo; -+ -+typedef struct -+{ -+ Elf64_Half si_boundto; /* Direct bindings, symbol bound to */ -+ Elf64_Half si_flags; /* Per symbol flags */ -+} Elf64_Syminfo; -+ -+/* Possible values for si_boundto. */ -+#define SYMINFO_BT_SELF 0xffff /* Symbol bound to self */ -+#define SYMINFO_BT_PARENT 0xfffe /* Symbol bound to parent */ -+#define SYMINFO_BT_LOWRESERVE 0xff00 /* Beginning of reserved entries */ -+ -+/* Possible bitmasks for si_flags. */ -+#define SYMINFO_FLG_DIRECT 0x0001 /* Direct bound symbol */ -+#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-thru symbol for translator */ -+#define SYMINFO_FLG_COPY 0x0004 /* Symbol is a copy-reloc */ -+#define SYMINFO_FLG_LAZYLOAD 0x0008 /* Symbol bound to object to be lazy -+ loaded */ -+/* Syminfo version values. */ -+#define SYMINFO_NONE 0 -+#define SYMINFO_CURRENT 1 -+#define SYMINFO_NUM 2 -+ -+ -+/* How to extract and insert information held in the st_info field. */ -+ -+#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4) -+#define ELF32_ST_TYPE(val) ((val) & 0xf) -+#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) -+ -+/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */ -+#define ELF64_ST_BIND(val) ELF32_ST_BIND (val) -+#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val) -+#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type)) -+ -+/* Legal values for ST_BIND subfield of st_info (symbol binding). */ -+ -+#define STB_LOCAL 0 /* Local symbol */ -+#define STB_GLOBAL 1 /* Global symbol */ -+#define STB_WEAK 2 /* Weak symbol */ -+#define STB_NUM 3 /* Number of defined types. */ -+#define STB_LOOS 10 /* Start of OS-specific */ -+#define STB_GNU_UNIQUE 10 /* Unique symbol. */ -+#define STB_HIOS 12 /* End of OS-specific */ -+#define STB_LOPROC 13 /* Start of processor-specific */ -+#define STB_HIPROC 15 /* End of processor-specific */ -+ -+/* Legal values for ST_TYPE subfield of st_info (symbol type). */ -+ -+#define STT_NOTYPE 0 /* Symbol type is unspecified */ -+#define STT_OBJECT 1 /* Symbol is a data object */ -+#define STT_FUNC 2 /* Symbol is a code object */ -+#define STT_SECTION 3 /* Symbol associated with a section */ -+#define STT_FILE 4 /* Symbol's name is file name */ -+#define STT_COMMON 5 /* Symbol is a common data object */ -+#define STT_TLS 6 /* Symbol is thread-local data object*/ -+#define STT_NUM 7 /* Number of defined types. */ -+#define STT_LOOS 10 /* Start of OS-specific */ -+#define STT_GNU_IFUNC 10 /* Symbol is indirect code object */ -+#define STT_HIOS 12 /* End of OS-specific */ -+#define STT_LOPROC 13 /* Start of processor-specific */ -+#define STT_HIPROC 15 /* End of processor-specific */ -+ -+ -+/* Symbol table indices are found in the hash buckets and chain table -+ of a symbol hash table section. This special index value indicates -+ the end of a chain, meaning no further symbols are found in that bucket. */ -+ -+#define STN_UNDEF 0 /* End of a chain. */ -+ -+ -+/* How to extract and insert information held in the st_other field. */ -+ -+#define ELF32_ST_VISIBILITY(o) ((o) & 0x03) -+ -+/* For ELF64 the definitions are the same. */ -+#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o) -+ -+/* Symbol visibility specification encoded in the st_other field. */ -+#define STV_DEFAULT 0 /* Default symbol visibility rules */ -+#define STV_INTERNAL 1 /* Processor specific hidden class */ -+#define STV_HIDDEN 2 /* Sym unavailable in other modules */ -+#define STV_PROTECTED 3 /* Not preemptible, not exported */ -+ -+ -+/* Relocation table entry without addend (in section of type SHT_REL). */ -+ -+typedef struct -+{ -+ Elf32_Addr r_offset; /* Address */ -+ Elf32_Word r_info; /* Relocation type and symbol index */ -+} Elf32_Rel; -+ -+/* I have seen two different definitions of the Elf64_Rel and -+ Elf64_Rela structures, so we'll leave them out until Novell (or -+ whoever) gets their act together. */ -+/* The following, at least, is used on Sparc v9, MIPS, and Alpha. */ -+ -+typedef struct -+{ -+ Elf64_Addr r_offset; /* Address */ -+ Elf64_Xword r_info; /* Relocation type and symbol index */ -+} Elf64_Rel; -+ -+/* Relocation table entry with addend (in section of type SHT_RELA). */ -+ -+typedef struct -+{ -+ Elf32_Addr r_offset; /* Address */ -+ Elf32_Word r_info; /* Relocation type and symbol index */ -+ Elf32_Sword r_addend; /* Addend */ -+} Elf32_Rela; -+ -+typedef struct -+{ -+ Elf64_Addr r_offset; /* Address */ -+ Elf64_Xword r_info; /* Relocation type and symbol index */ -+ Elf64_Sxword r_addend; /* Addend */ -+} Elf64_Rela; -+ -+/* How to extract and insert information held in the r_info field. */ -+ -+#define ELF32_R_SYM(val) ((val) >> 8) -+#define ELF32_R_TYPE(val) ((val) & 0xff) -+#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff)) -+ -+#define ELF64_R_SYM(i) ((i) >> 32) -+#define ELF64_R_TYPE(i) ((i) & 0xffffffff) -+#define ELF64_R_INFO(sym,type) ((((Elf64_Xword) (sym)) << 32) + (type)) -+ -+/* Program segment header. */ -+ -+typedef struct -+{ -+ Elf32_Word p_type; /* Segment type */ -+ Elf32_Off p_offset; /* Segment file offset */ -+ Elf32_Addr p_vaddr; /* Segment virtual address */ -+ Elf32_Addr p_paddr; /* Segment physical address */ -+ Elf32_Word p_filesz; /* Segment size in file */ -+ Elf32_Word p_memsz; /* Segment size in memory */ -+ Elf32_Word p_flags; /* Segment flags */ -+ Elf32_Word p_align; /* Segment alignment */ -+} Elf32_Phdr; -+ -+typedef struct -+{ -+ Elf64_Word p_type; /* Segment type */ -+ Elf64_Word p_flags; /* Segment flags */ -+ Elf64_Off p_offset; /* Segment file offset */ -+ Elf64_Addr p_vaddr; /* Segment virtual address */ -+ Elf64_Addr p_paddr; /* Segment physical address */ -+ Elf64_Xword p_filesz; /* Segment size in file */ -+ Elf64_Xword p_memsz; /* Segment size in memory */ -+ Elf64_Xword p_align; /* Segment alignment */ -+} Elf64_Phdr; -+ -+/* Special value for e_phnum. This indicates that the real number of -+ program headers is too large to fit into e_phnum. Instead the real -+ value is in the field sh_info of section 0. */ -+ -+#define PN_XNUM 0xffff -+ -+/* Legal values for p_type (segment type). */ -+ -+#define PT_NULL 0 /* Program header table entry unused */ -+#define PT_LOAD 1 /* Loadable program segment */ -+#define PT_DYNAMIC 2 /* Dynamic linking information */ -+#define PT_INTERP 3 /* Program interpreter */ -+#define PT_NOTE 4 /* Auxiliary information */ -+#define PT_SHLIB 5 /* Reserved */ -+#define PT_PHDR 6 /* Entry for header table itself */ -+#define PT_TLS 7 /* Thread-local storage segment */ -+#define PT_NUM 8 /* Number of defined types */ -+#define PT_LOOS 0x60000000 /* Start of OS-specific */ -+#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */ -+#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */ -+#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */ -+#define PT_LOSUNW 0x6ffffffa -+#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ -+#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ -+#define PT_HISUNW 0x6fffffff -+#define PT_HIOS 0x6fffffff /* End of OS-specific */ -+#define PT_LOPROC 0x70000000 /* Start of processor-specific */ -+#define PT_HIPROC 0x7fffffff /* End of processor-specific */ -+ -+/* Legal values for p_flags (segment flags). */ -+ -+#define PF_X (1 << 0) /* Segment is executable */ -+#define PF_W (1 << 1) /* Segment is writable */ -+#define PF_R (1 << 2) /* Segment is readable */ -+#define PF_MASKOS 0x0ff00000 /* OS-specific */ -+#define PF_MASKPROC 0xf0000000 /* Processor-specific */ -+ -+/* Legal values for note segment descriptor types for core files. */ -+ -+#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */ -+#define NT_FPREGSET 2 /* Contains copy of fpregset struct */ -+#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */ -+#define NT_PRXREG 4 /* Contains copy of prxregset struct */ -+#define NT_TASKSTRUCT 4 /* Contains copy of task structure */ -+#define NT_PLATFORM 5 /* String from sysinfo(SI_PLATFORM) */ -+#define NT_AUXV 6 /* Contains copy of auxv array */ -+#define NT_GWINDOWS 7 /* Contains copy of gwindows struct */ -+#define NT_ASRS 8 /* Contains copy of asrset struct */ -+#define NT_PSTATUS 10 /* Contains copy of pstatus struct */ -+#define NT_PSINFO 13 /* Contains copy of psinfo struct */ -+#define NT_PRCRED 14 /* Contains copy of prcred struct */ -+#define NT_UTSNAME 15 /* Contains copy of utsname struct */ -+#define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */ -+#define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */ -+#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct */ -+#define NT_PRXFPREG 0x46e62b7f /* Contains copy of user_fxsr_struct */ -+#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ -+#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */ -+#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */ -+#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ -+#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */ -+#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */ -+ -+/* Legal values for the note segment descriptor types for object files. */ -+ -+#define NT_VERSION 1 /* Contains a version string. */ -+ -+ -+/* Dynamic section entry. */ -+ -+typedef struct -+{ -+ Elf32_Sword d_tag; /* Dynamic entry type */ -+ union -+ { -+ Elf32_Word d_val; /* Integer value */ -+ Elf32_Addr d_ptr; /* Address value */ -+ } d_un; -+} Elf32_Dyn; -+ -+typedef struct -+{ -+ Elf64_Sxword d_tag; /* Dynamic entry type */ -+ union -+ { -+ Elf64_Xword d_val; /* Integer value */ -+ Elf64_Addr d_ptr; /* Address value */ -+ } d_un; -+} Elf64_Dyn; -+ -+/* Legal values for d_tag (dynamic entry type). */ -+ -+#define DT_NULL 0 /* Marks end of dynamic section */ -+#define DT_NEEDED 1 /* Name of needed library */ -+#define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */ -+#define DT_PLTGOT 3 /* Processor defined value */ -+#define DT_HASH 4 /* Address of symbol hash table */ -+#define DT_STRTAB 5 /* Address of string table */ -+#define DT_SYMTAB 6 /* Address of symbol table */ -+#define DT_RELA 7 /* Address of Rela relocs */ -+#define DT_RELASZ 8 /* Total size of Rela relocs */ -+#define DT_RELAENT 9 /* Size of one Rela reloc */ -+#define DT_STRSZ 10 /* Size of string table */ -+#define DT_SYMENT 11 /* Size of one symbol table entry */ -+#define DT_INIT 12 /* Address of init function */ -+#define DT_FINI 13 /* Address of termination function */ -+#define DT_SONAME 14 /* Name of shared object */ -+#define DT_RPATH 15 /* Library search path (deprecated) */ -+#define DT_SYMBOLIC 16 /* Start symbol search here */ -+#define DT_REL 17 /* Address of Rel relocs */ -+#define DT_RELSZ 18 /* Total size of Rel relocs */ -+#define DT_RELENT 19 /* Size of one Rel reloc */ -+#define DT_PLTREL 20 /* Type of reloc in PLT */ -+#define DT_DEBUG 21 /* For debugging; unspecified */ -+#define DT_TEXTREL 22 /* Reloc might modify .text */ -+#define DT_JMPREL 23 /* Address of PLT relocs */ -+#define DT_BIND_NOW 24 /* Process relocations of object */ -+#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ -+#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ -+#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ -+#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ -+#define DT_RUNPATH 29 /* Library search path */ -+#define DT_FLAGS 30 /* Flags for the object being loaded */ -+#define DT_ENCODING 32 /* Start of encoded range */ -+#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ -+#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ -+#define DT_NUM 34 /* Number used */ -+#define DT_LOOS 0x6000000d /* Start of OS-specific */ -+#define DT_HIOS 0x6ffff000 /* End of OS-specific */ -+#define DT_LOPROC 0x70000000 /* Start of processor-specific */ -+#define DT_HIPROC 0x7fffffff /* End of processor-specific */ -+#define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */ -+ -+/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the -+ Dyn.d_un.d_val field of the Elf*_Dyn structure. This follows Sun's -+ approach. */ -+#define DT_VALRNGLO 0x6ffffd00 -+#define DT_GNU_PRELINKED 0x6ffffdf5 /* Prelinking timestamp */ -+#define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* Size of conflict section */ -+#define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* Size of library list */ -+#define DT_CHECKSUM 0x6ffffdf8 -+#define DT_PLTPADSZ 0x6ffffdf9 -+#define DT_MOVEENT 0x6ffffdfa -+#define DT_MOVESZ 0x6ffffdfb -+#define DT_FEATURE_1 0x6ffffdfc /* Feature selection (DTF_*). */ -+#define DT_POSFLAG_1 0x6ffffdfd /* Flags for DT_* entries, effecting -+ the following DT_* entry. */ -+#define DT_SYMINSZ 0x6ffffdfe /* Size of syminfo table (in bytes) */ -+#define DT_SYMINENT 0x6ffffdff /* Entry size of syminfo */ -+#define DT_VALRNGHI 0x6ffffdff -+#define DT_VALTAGIDX(tag) (DT_VALRNGHI - (tag)) /* Reverse order! */ -+#define DT_VALNUM 12 -+ -+/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the -+ Dyn.d_un.d_ptr field of the Elf*_Dyn structure. -+ -+ If any adjustment is made to the ELF object after it has been -+ built these entries will need to be adjusted. */ -+#define DT_ADDRRNGLO 0x6ffffe00 -+#define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table. */ -+#define DT_TLSDESC_PLT 0x6ffffef6 -+#define DT_TLSDESC_GOT 0x6ffffef7 -+#define DT_GNU_CONFLICT 0x6ffffef8 /* Start of conflict section */ -+#define DT_GNU_LIBLIST 0x6ffffef9 /* Library list */ -+#define DT_CONFIG 0x6ffffefa /* Configuration information. */ -+#define DT_DEPAUDIT 0x6ffffefb /* Dependency auditing. */ -+#define DT_AUDIT 0x6ffffefc /* Object auditing. */ -+#define DT_PLTPAD 0x6ffffefd /* PLT padding. */ -+#define DT_MOVETAB 0x6ffffefe /* Move table. */ -+#define DT_SYMINFO 0x6ffffeff /* Syminfo table. */ -+#define DT_ADDRRNGHI 0x6ffffeff -+#define DT_ADDRTAGIDX(tag) (DT_ADDRRNGHI - (tag)) /* Reverse order! */ -+#define DT_ADDRNUM 11 -+ -+/* The versioning entry types. The next are defined as part of the -+ GNU extension. */ -+#define DT_VERSYM 0x6ffffff0 -+ -+#define DT_RELACOUNT 0x6ffffff9 -+#define DT_RELCOUNT 0x6ffffffa -+ -+/* These were chosen by Sun. */ -+#define DT_FLAGS_1 0x6ffffffb /* State flags, see DF_1_* below. */ -+#define DT_VERDEF 0x6ffffffc /* Address of version definition -+ table */ -+#define DT_VERDEFNUM 0x6ffffffd /* Number of version definitions */ -+#define DT_VERNEED 0x6ffffffe /* Address of table with needed -+ versions */ -+#define DT_VERNEEDNUM 0x6fffffff /* Number of needed versions */ -+#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */ -+#define DT_VERSIONTAGNUM 16 -+ -+/* Sun added these machine-independent extensions in the "processor-specific" -+ range. Be compatible. */ -+#define DT_AUXILIARY 0x7ffffffd /* Shared object to load before self */ -+#define DT_FILTER 0x7fffffff /* Shared object to get values from */ -+#define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1) -+#define DT_EXTRANUM 3 -+ -+/* Values of `d_un.d_val' in the DT_FLAGS entry. */ -+#define DF_ORIGIN 0x00000001 /* Object may use DF_ORIGIN */ -+#define DF_SYMBOLIC 0x00000002 /* Symbol resolutions starts here */ -+#define DF_TEXTREL 0x00000004 /* Object contains text relocations */ -+#define DF_BIND_NOW 0x00000008 /* No lazy binding for this object */ -+#define DF_STATIC_TLS 0x00000010 /* Module uses the static TLS model */ -+ -+/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1 -+ entry in the dynamic section. */ -+#define DF_1_NOW 0x00000001 /* Set RTLD_NOW for this object. */ -+#define DF_1_GLOBAL 0x00000002 /* Set RTLD_GLOBAL for this object. */ -+#define DF_1_GROUP 0x00000004 /* Set RTLD_GROUP for this object. */ -+#define DF_1_NODELETE 0x00000008 /* Set RTLD_NODELETE for this object.*/ -+#define DF_1_LOADFLTR 0x00000010 /* Trigger filtee loading at runtime.*/ -+#define DF_1_INITFIRST 0x00000020 /* Set RTLD_INITFIRST for this object*/ -+#define DF_1_NOOPEN 0x00000040 /* Set RTLD_NOOPEN for this object. */ -+#define DF_1_ORIGIN 0x00000080 /* $ORIGIN must be handled. */ -+#define DF_1_DIRECT 0x00000100 /* Direct binding enabled. */ -+#define DF_1_TRANS 0x00000200 -+#define DF_1_INTERPOSE 0x00000400 /* Object is used to interpose. */ -+#define DF_1_NODEFLIB 0x00000800 /* Ignore default lib search path. */ -+#define DF_1_NODUMP 0x00001000 /* Object can't be dldump'ed. */ -+#define DF_1_CONFALT 0x00002000 /* Configuration alternative created.*/ -+#define DF_1_ENDFILTEE 0x00004000 /* Filtee terminates filters search. */ -+#define DF_1_DISPRELDNE 0x00008000 /* Disp reloc applied at build time. */ -+#define DF_1_DISPRELPND 0x00010000 /* Disp reloc applied at run-time. */ -+ -+/* Flags for the feature selection in DT_FEATURE_1. */ -+#define DTF_1_PARINIT 0x00000001 -+#define DTF_1_CONFEXP 0x00000002 -+ -+/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry. */ -+#define DF_P1_LAZYLOAD 0x00000001 /* Lazyload following object. */ -+#define DF_P1_GROUPPERM 0x00000002 /* Symbols from next object are not -+ generally available. */ -+ -+/* Version definition sections. */ -+ -+typedef struct -+{ -+ Elf32_Half vd_version; /* Version revision */ -+ Elf32_Half vd_flags; /* Version information */ -+ Elf32_Half vd_ndx; /* Version Index */ -+ Elf32_Half vd_cnt; /* Number of associated aux entries */ -+ Elf32_Word vd_hash; /* Version name hash value */ -+ Elf32_Word vd_aux; /* Offset in bytes to verdaux array */ -+ Elf32_Word vd_next; /* Offset in bytes to next verdef -+ entry */ -+} Elf32_Verdef; -+ -+typedef struct -+{ -+ Elf64_Half vd_version; /* Version revision */ -+ Elf64_Half vd_flags; /* Version information */ -+ Elf64_Half vd_ndx; /* Version Index */ -+ Elf64_Half vd_cnt; /* Number of associated aux entries */ -+ Elf64_Word vd_hash; /* Version name hash value */ -+ Elf64_Word vd_aux; /* Offset in bytes to verdaux array */ -+ Elf64_Word vd_next; /* Offset in bytes to next verdef -+ entry */ -+} Elf64_Verdef; -+ -+ -+/* Legal values for vd_version (version revision). */ -+#define VER_DEF_NONE 0 /* No version */ -+#define VER_DEF_CURRENT 1 /* Current version */ -+#define VER_DEF_NUM 2 /* Given version number */ -+ -+/* Legal values for vd_flags (version information flags). */ -+#define VER_FLG_BASE 0x1 /* Version definition of file itself */ -+#define VER_FLG_WEAK 0x2 /* Weak version identifier */ -+ -+/* Versym symbol index values. */ -+#define VER_NDX_LOCAL 0 /* Symbol is local. */ -+#define VER_NDX_GLOBAL 1 /* Symbol is global. */ -+#define VER_NDX_LORESERVE 0xff00 /* Beginning of reserved entries. */ -+#define VER_NDX_ELIMINATE 0xff01 /* Symbol is to be eliminated. */ -+ -+/* Auxialiary version information. */ -+ -+typedef struct -+{ -+ Elf32_Word vda_name; /* Version or dependency names */ -+ Elf32_Word vda_next; /* Offset in bytes to next verdaux -+ entry */ -+} Elf32_Verdaux; -+ -+typedef struct -+{ -+ Elf64_Word vda_name; /* Version or dependency names */ -+ Elf64_Word vda_next; /* Offset in bytes to next verdaux -+ entry */ -+} Elf64_Verdaux; -+ -+ -+/* Version dependency section. */ -+ -+typedef struct -+{ -+ Elf32_Half vn_version; /* Version of structure */ -+ Elf32_Half vn_cnt; /* Number of associated aux entries */ -+ Elf32_Word vn_file; /* Offset of filename for this -+ dependency */ -+ Elf32_Word vn_aux; /* Offset in bytes to vernaux array */ -+ Elf32_Word vn_next; /* Offset in bytes to next verneed -+ entry */ -+} Elf32_Verneed; -+ -+typedef struct -+{ -+ Elf64_Half vn_version; /* Version of structure */ -+ Elf64_Half vn_cnt; /* Number of associated aux entries */ -+ Elf64_Word vn_file; /* Offset of filename for this -+ dependency */ -+ Elf64_Word vn_aux; /* Offset in bytes to vernaux array */ -+ Elf64_Word vn_next; /* Offset in bytes to next verneed -+ entry */ -+} Elf64_Verneed; -+ -+ -+/* Legal values for vn_version (version revision). */ -+#define VER_NEED_NONE 0 /* No version */ -+#define VER_NEED_CURRENT 1 /* Current version */ -+#define VER_NEED_NUM 2 /* Given version number */ -+ -+/* Auxiliary needed version information. */ -+ -+typedef struct -+{ -+ Elf32_Word vna_hash; /* Hash value of dependency name */ -+ Elf32_Half vna_flags; /* Dependency specific information */ -+ Elf32_Half vna_other; /* Unused */ -+ Elf32_Word vna_name; /* Dependency name string offset */ -+ Elf32_Word vna_next; /* Offset in bytes to next vernaux -+ entry */ -+} Elf32_Vernaux; -+ -+typedef struct -+{ -+ Elf64_Word vna_hash; /* Hash value of dependency name */ -+ Elf64_Half vna_flags; /* Dependency specific information */ -+ Elf64_Half vna_other; /* Unused */ -+ Elf64_Word vna_name; /* Dependency name string offset */ -+ Elf64_Word vna_next; /* Offset in bytes to next vernaux -+ entry */ -+} Elf64_Vernaux; -+ -+ -+/* Legal values for vna_flags. */ -+#define VER_FLG_WEAK 0x2 /* Weak version identifier */ -+ -+ -+/* Auxiliary vector. */ -+ -+/* This vector is normally only used by the program interpreter. The -+ usual definition in an ABI supplement uses the name auxv_t. The -+ vector is not usually defined in a standard file, but it -+ can't hurt. We rename it to avoid conflicts. The sizes of these -+ types are an arrangement between the exec server and the program -+ interpreter, so we don't fully specify them here. */ -+ -+typedef struct -+{ -+ uint32_t a_type; /* Entry type */ -+ union -+ { -+ uint32_t a_val; /* Integer value */ -+ /* We use to have pointer elements added here. We cannot do that, -+ though, since it does not work when using 32-bit definitions -+ on 64-bit platforms and vice versa. */ -+ } a_un; -+} Elf32_auxv_t; -+ -+typedef struct -+{ -+ uint64_t a_type; /* Entry type */ -+ union -+ { -+ uint64_t a_val; /* Integer value */ -+ /* We use to have pointer elements added here. We cannot do that, -+ though, since it does not work when using 32-bit definitions -+ on 64-bit platforms and vice versa. */ -+ } a_un; -+} Elf64_auxv_t; -+ -+/* Legal values for a_type (entry type). */ -+ -+#define AT_NULL 0 /* End of vector */ -+#define AT_IGNORE 1 /* Entry should be ignored */ -+#define AT_EXECFD 2 /* File descriptor of program */ -+#define AT_PHDR 3 /* Program headers for program */ -+#define AT_PHENT 4 /* Size of program header entry */ -+#define AT_PHNUM 5 /* Number of program headers */ -+#define AT_PAGESZ 6 /* System page size */ -+#define AT_BASE 7 /* Base address of interpreter */ -+#define AT_FLAGS 8 /* Flags */ -+#define AT_ENTRY 9 /* Entry point of program */ -+#define AT_NOTELF 10 /* Program is not ELF */ -+#define AT_UID 11 /* Real uid */ -+#define AT_EUID 12 /* Effective uid */ -+#define AT_GID 13 /* Real gid */ -+#define AT_EGID 14 /* Effective gid */ -+#define AT_CLKTCK 17 /* Frequency of times() */ -+ -+/* Some more special a_type values describing the hardware. */ -+#define AT_PLATFORM 15 /* String identifying platform. */ -+#define AT_HWCAP 16 /* Machine dependent hints about -+ processor capabilities. */ -+ -+/* This entry gives some information about the FPU initialization -+ performed by the kernel. */ -+#define AT_FPUCW 18 /* Used FPU control word. */ -+ -+/* Cache block sizes. */ -+#define AT_DCACHEBSIZE 19 /* Data cache block size. */ -+#define AT_ICACHEBSIZE 20 /* Instruction cache block size. */ -+#define AT_UCACHEBSIZE 21 /* Unified cache block size. */ -+ -+/* A special ignored value for PPC, used by the kernel to control the -+ interpretation of the AUXV. Must be > 16. */ -+#define AT_IGNOREPPC 22 /* Entry should be ignored. */ -+ -+#define AT_SECURE 23 /* Boolean, was exec setuid-like? */ -+ -+#define AT_BASE_PLATFORM 24 /* String identifying real platforms.*/ -+ -+#define AT_RANDOM 25 /* Address of 16 random bytes. */ -+ -+#define AT_EXECFN 31 /* Filename of executable. */ -+ -+/* Pointer to the global system page used for system calls and other -+ nice things. */ -+#define AT_SYSINFO 32 -+#define AT_SYSINFO_EHDR 33 -+ -+/* Shapes of the caches. Bits 0-3 contains associativity; bits 4-7 contains -+ log2 of line size; mask those to get cache size. */ -+#define AT_L1I_CACHESHAPE 34 -+#define AT_L1D_CACHESHAPE 35 -+#define AT_L2_CACHESHAPE 36 -+#define AT_L3_CACHESHAPE 37 -+ -+/* Note section contents. Each entry in the note section begins with -+ a header of a fixed form. */ -+ -+typedef struct -+{ -+ Elf32_Word n_namesz; /* Length of the note's name. */ -+ Elf32_Word n_descsz; /* Length of the note's descriptor. */ -+ Elf32_Word n_type; /* Type of the note. */ -+} Elf32_Nhdr; -+ -+typedef struct -+{ -+ Elf64_Word n_namesz; /* Length of the note's name. */ -+ Elf64_Word n_descsz; /* Length of the note's descriptor. */ -+ Elf64_Word n_type; /* Type of the note. */ -+} Elf64_Nhdr; -+ -+/* Known names of notes. */ -+ -+/* Solaris entries in the note section have this name. */ -+#define ELF_NOTE_SOLARIS "SUNW Solaris" -+ -+/* Note entries for GNU systems have this name. */ -+#define ELF_NOTE_GNU "GNU" -+ -+ -+/* Defined types of notes for Solaris. */ -+ -+/* Value of descriptor (one word) is desired pagesize for the binary. */ -+#define ELF_NOTE_PAGESIZE_HINT 1 -+ -+ -+/* Defined note types for GNU systems. */ -+ -+/* ABI information. The descriptor consists of words: -+ word 0: OS descriptor -+ word 1: major version of the ABI -+ word 2: minor version of the ABI -+ word 3: subminor version of the ABI -+*/ -+#define NT_GNU_ABI_TAG 1 -+#define ELF_NOTE_ABI NT_GNU_ABI_TAG /* Old name. */ -+ -+/* Known OSes. These values can appear in word 0 of an -+ NT_GNU_ABI_TAG note section entry. */ -+#define ELF_NOTE_OS_LINUX 0 -+#define ELF_NOTE_OS_GNU 1 -+#define ELF_NOTE_OS_SOLARIS2 2 -+#define ELF_NOTE_OS_FREEBSD 3 -+ -+/* Synthetic hwcap information. The descriptor begins with two words: -+ word 0: number of entries -+ word 1: bitmask of enabled entries -+ Then follow variable-length entries, one byte followed by a -+ '\0'-terminated hwcap name string. The byte gives the bit -+ number to test if enabled, (1U << bit) & bitmask. */ -+#define NT_GNU_HWCAP 2 -+ -+/* Build ID bits as generated by ld --build-id. -+ The descriptor consists of any nonzero number of bytes. */ -+#define NT_GNU_BUILD_ID 3 -+ -+/* Version note generated by GNU gold containing a version string. */ -+#define NT_GNU_GOLD_VERSION 4 -+ -+ -+/* Move records. */ -+typedef struct -+{ -+ Elf32_Xword m_value; /* Symbol value. */ -+ Elf32_Word m_info; /* Size and index. */ -+ Elf32_Word m_poffset; /* Symbol offset. */ -+ Elf32_Half m_repeat; /* Repeat count. */ -+ Elf32_Half m_stride; /* Stride info. */ -+} Elf32_Move; -+ -+typedef struct -+{ -+ Elf64_Xword m_value; /* Symbol value. */ -+ Elf64_Xword m_info; /* Size and index. */ -+ Elf64_Xword m_poffset; /* Symbol offset. */ -+ Elf64_Half m_repeat; /* Repeat count. */ -+ Elf64_Half m_stride; /* Stride info. */ -+} Elf64_Move; -+ -+/* Macro to construct move records. */ -+#define ELF32_M_SYM(info) ((info) >> 8) -+#define ELF32_M_SIZE(info) ((unsigned char) (info)) -+#define ELF32_M_INFO(sym, size) (((sym) << 8) + (unsigned char) (size)) -+ -+#define ELF64_M_SYM(info) ELF32_M_SYM (info) -+#define ELF64_M_SIZE(info) ELF32_M_SIZE (info) -+#define ELF64_M_INFO(sym, size) ELF32_M_INFO (sym, size) -+ -+ -+/* Motorola 68k specific definitions. */ -+ -+/* Values for Elf32_Ehdr.e_flags. */ -+#define EF_CPU32 0x00810000 -+ -+/* m68k relocs. */ -+ -+#define R_68K_NONE 0 /* No reloc */ -+#define R_68K_32 1 /* Direct 32 bit */ -+#define R_68K_16 2 /* Direct 16 bit */ -+#define R_68K_8 3 /* Direct 8 bit */ -+#define R_68K_PC32 4 /* PC relative 32 bit */ -+#define R_68K_PC16 5 /* PC relative 16 bit */ -+#define R_68K_PC8 6 /* PC relative 8 bit */ -+#define R_68K_GOT32 7 /* 32 bit PC relative GOT entry */ -+#define R_68K_GOT16 8 /* 16 bit PC relative GOT entry */ -+#define R_68K_GOT8 9 /* 8 bit PC relative GOT entry */ -+#define R_68K_GOT32O 10 /* 32 bit GOT offset */ -+#define R_68K_GOT16O 11 /* 16 bit GOT offset */ -+#define R_68K_GOT8O 12 /* 8 bit GOT offset */ -+#define R_68K_PLT32 13 /* 32 bit PC relative PLT address */ -+#define R_68K_PLT16 14 /* 16 bit PC relative PLT address */ -+#define R_68K_PLT8 15 /* 8 bit PC relative PLT address */ -+#define R_68K_PLT32O 16 /* 32 bit PLT offset */ -+#define R_68K_PLT16O 17 /* 16 bit PLT offset */ -+#define R_68K_PLT8O 18 /* 8 bit PLT offset */ -+#define R_68K_COPY 19 /* Copy symbol at runtime */ -+#define R_68K_GLOB_DAT 20 /* Create GOT entry */ -+#define R_68K_JMP_SLOT 21 /* Create PLT entry */ -+#define R_68K_RELATIVE 22 /* Adjust by program base */ -+#define R_68K_TLS_GD32 25 /* 32 bit GOT offset for GD */ -+#define R_68K_TLS_GD16 26 /* 16 bit GOT offset for GD */ -+#define R_68K_TLS_GD8 27 /* 8 bit GOT offset for GD */ -+#define R_68K_TLS_LDM32 28 /* 32 bit GOT offset for LDM */ -+#define R_68K_TLS_LDM16 29 /* 16 bit GOT offset for LDM */ -+#define R_68K_TLS_LDM8 30 /* 8 bit GOT offset for LDM */ -+#define R_68K_TLS_LDO32 31 /* 32 bit module-relative offset */ -+#define R_68K_TLS_LDO16 32 /* 16 bit module-relative offset */ -+#define R_68K_TLS_LDO8 33 /* 8 bit module-relative offset */ -+#define R_68K_TLS_IE32 34 /* 32 bit GOT offset for IE */ -+#define R_68K_TLS_IE16 35 /* 16 bit GOT offset for IE */ -+#define R_68K_TLS_IE8 36 /* 8 bit GOT offset for IE */ -+#define R_68K_TLS_LE32 37 /* 32 bit offset relative to -+ static TLS block */ -+#define R_68K_TLS_LE16 38 /* 16 bit offset relative to -+ static TLS block */ -+#define R_68K_TLS_LE8 39 /* 8 bit offset relative to -+ static TLS block */ -+#define R_68K_TLS_DTPMOD32 40 /* 32 bit module number */ -+#define R_68K_TLS_DTPREL32 41 /* 32 bit module-relative offset */ -+#define R_68K_TLS_TPREL32 42 /* 32 bit TP-relative offset */ -+/* Keep this the last entry. */ -+#define R_68K_NUM 43 -+ -+/* Intel 80386 specific definitions. */ -+ -+/* i386 relocs. */ -+ -+#define R_386_NONE 0 /* No reloc */ -+#define R_386_32 1 /* Direct 32 bit */ -+#define R_386_PC32 2 /* PC relative 32 bit */ -+#define R_386_GOT32 3 /* 32 bit GOT entry */ -+#define R_386_PLT32 4 /* 32 bit PLT address */ -+#define R_386_COPY 5 /* Copy symbol at runtime */ -+#define R_386_GLOB_DAT 6 /* Create GOT entry */ -+#define R_386_JMP_SLOT 7 /* Create PLT entry */ -+#define R_386_RELATIVE 8 /* Adjust by program base */ -+#define R_386_GOTOFF 9 /* 32 bit offset to GOT */ -+#define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */ -+#define R_386_32PLT 11 -+#define R_386_TLS_TPOFF 14 /* Offset in static TLS block */ -+#define R_386_TLS_IE 15 /* Address of GOT entry for static TLS -+ block offset */ -+#define R_386_TLS_GOTIE 16 /* GOT entry for static TLS block -+ offset */ -+#define R_386_TLS_LE 17 /* Offset relative to static TLS -+ block */ -+#define R_386_TLS_GD 18 /* Direct 32 bit for GNU version of -+ general dynamic thread local data */ -+#define R_386_TLS_LDM 19 /* Direct 32 bit for GNU version of -+ local dynamic thread local data -+ in LE code */ -+#define R_386_16 20 -+#define R_386_PC16 21 -+#define R_386_8 22 -+#define R_386_PC8 23 -+#define R_386_TLS_GD_32 24 /* Direct 32 bit for general dynamic -+ thread local data */ -+#define R_386_TLS_GD_PUSH 25 /* Tag for pushl in GD TLS code */ -+#define R_386_TLS_GD_CALL 26 /* Relocation for call to -+ __tls_get_addr() */ -+#define R_386_TLS_GD_POP 27 /* Tag for popl in GD TLS code */ -+#define R_386_TLS_LDM_32 28 /* Direct 32 bit for local dynamic -+ thread local data in LE code */ -+#define R_386_TLS_LDM_PUSH 29 /* Tag for pushl in LDM TLS code */ -+#define R_386_TLS_LDM_CALL 30 /* Relocation for call to -+ __tls_get_addr() in LDM code */ -+#define R_386_TLS_LDM_POP 31 /* Tag for popl in LDM TLS code */ -+#define R_386_TLS_LDO_32 32 /* Offset relative to TLS block */ -+#define R_386_TLS_IE_32 33 /* GOT entry for negated static TLS -+ block offset */ -+#define R_386_TLS_LE_32 34 /* Negated offset relative to static -+ TLS block */ -+#define R_386_TLS_DTPMOD32 35 /* ID of module containing symbol */ -+#define R_386_TLS_DTPOFF32 36 /* Offset in TLS block */ -+#define R_386_TLS_TPOFF32 37 /* Negated offset in static TLS block */ -+/* 38? */ -+#define R_386_TLS_GOTDESC 39 /* GOT offset for TLS descriptor. */ -+#define R_386_TLS_DESC_CALL 40 /* Marker of call through TLS -+ descriptor for -+ relaxation. */ -+#define R_386_TLS_DESC 41 /* TLS descriptor containing -+ pointer to code and to -+ argument, returning the TLS -+ offset for the symbol. */ -+#define R_386_IRELATIVE 42 /* Adjust indirectly by program base */ -+/* Keep this the last entry. */ -+#define R_386_NUM 43 -+ -+/* SUN SPARC specific definitions. */ -+ -+/* Legal values for ST_TYPE subfield of st_info (symbol type). */ -+ -+#define STT_SPARC_REGISTER 13 /* Global register reserved to app. */ -+ -+/* Values for Elf64_Ehdr.e_flags. */ -+ -+#define EF_SPARCV9_MM 3 -+#define EF_SPARCV9_TSO 0 -+#define EF_SPARCV9_PSO 1 -+#define EF_SPARCV9_RMO 2 -+#define EF_SPARC_LEDATA 0x800000 /* little endian data */ -+#define EF_SPARC_EXT_MASK 0xFFFF00 -+#define EF_SPARC_32PLUS 0x000100 /* generic V8+ features */ -+#define EF_SPARC_SUN_US1 0x000200 /* Sun UltraSPARC1 extensions */ -+#define EF_SPARC_HAL_R1 0x000400 /* HAL R1 extensions */ -+#define EF_SPARC_SUN_US3 0x000800 /* Sun UltraSPARCIII extensions */ -+ -+/* SPARC relocs. */ -+ -+#define R_SPARC_NONE 0 /* No reloc */ -+#define R_SPARC_8 1 /* Direct 8 bit */ -+#define R_SPARC_16 2 /* Direct 16 bit */ -+#define R_SPARC_32 3 /* Direct 32 bit */ -+#define R_SPARC_DISP8 4 /* PC relative 8 bit */ -+#define R_SPARC_DISP16 5 /* PC relative 16 bit */ -+#define R_SPARC_DISP32 6 /* PC relative 32 bit */ -+#define R_SPARC_WDISP30 7 /* PC relative 30 bit shifted */ -+#define R_SPARC_WDISP22 8 /* PC relative 22 bit shifted */ -+#define R_SPARC_HI22 9 /* High 22 bit */ -+#define R_SPARC_22 10 /* Direct 22 bit */ -+#define R_SPARC_13 11 /* Direct 13 bit */ -+#define R_SPARC_LO10 12 /* Truncated 10 bit */ -+#define R_SPARC_GOT10 13 /* Truncated 10 bit GOT entry */ -+#define R_SPARC_GOT13 14 /* 13 bit GOT entry */ -+#define R_SPARC_GOT22 15 /* 22 bit GOT entry shifted */ -+#define R_SPARC_PC10 16 /* PC relative 10 bit truncated */ -+#define R_SPARC_PC22 17 /* PC relative 22 bit shifted */ -+#define R_SPARC_WPLT30 18 /* 30 bit PC relative PLT address */ -+#define R_SPARC_COPY 19 /* Copy symbol at runtime */ -+#define R_SPARC_GLOB_DAT 20 /* Create GOT entry */ -+#define R_SPARC_JMP_SLOT 21 /* Create PLT entry */ -+#define R_SPARC_RELATIVE 22 /* Adjust by program base */ -+#define R_SPARC_UA32 23 /* Direct 32 bit unaligned */ -+ -+/* Additional Sparc64 relocs. */ -+ -+#define R_SPARC_PLT32 24 /* Direct 32 bit ref to PLT entry */ -+#define R_SPARC_HIPLT22 25 /* High 22 bit PLT entry */ -+#define R_SPARC_LOPLT10 26 /* Truncated 10 bit PLT entry */ -+#define R_SPARC_PCPLT32 27 /* PC rel 32 bit ref to PLT entry */ -+#define R_SPARC_PCPLT22 28 /* PC rel high 22 bit PLT entry */ -+#define R_SPARC_PCPLT10 29 /* PC rel trunc 10 bit PLT entry */ -+#define R_SPARC_10 30 /* Direct 10 bit */ -+#define R_SPARC_11 31 /* Direct 11 bit */ -+#define R_SPARC_64 32 /* Direct 64 bit */ -+#define R_SPARC_OLO10 33 /* 10bit with secondary 13bit addend */ -+#define R_SPARC_HH22 34 /* Top 22 bits of direct 64 bit */ -+#define R_SPARC_HM10 35 /* High middle 10 bits of ... */ -+#define R_SPARC_LM22 36 /* Low middle 22 bits of ... */ -+#define R_SPARC_PC_HH22 37 /* Top 22 bits of pc rel 64 bit */ -+#define R_SPARC_PC_HM10 38 /* High middle 10 bit of ... */ -+#define R_SPARC_PC_LM22 39 /* Low miggle 22 bits of ... */ -+#define R_SPARC_WDISP16 40 /* PC relative 16 bit shifted */ -+#define R_SPARC_WDISP19 41 /* PC relative 19 bit shifted */ -+#define R_SPARC_GLOB_JMP 42 /* was part of v9 ABI but was removed */ -+#define R_SPARC_7 43 /* Direct 7 bit */ -+#define R_SPARC_5 44 /* Direct 5 bit */ -+#define R_SPARC_6 45 /* Direct 6 bit */ -+#define R_SPARC_DISP64 46 /* PC relative 64 bit */ -+#define R_SPARC_PLT64 47 /* Direct 64 bit ref to PLT entry */ -+#define R_SPARC_HIX22 48 /* High 22 bit complemented */ -+#define R_SPARC_LOX10 49 /* Truncated 11 bit complemented */ -+#define R_SPARC_H44 50 /* Direct high 12 of 44 bit */ -+#define R_SPARC_M44 51 /* Direct mid 22 of 44 bit */ -+#define R_SPARC_L44 52 /* Direct low 10 of 44 bit */ -+#define R_SPARC_REGISTER 53 /* Global register usage */ -+#define R_SPARC_UA64 54 /* Direct 64 bit unaligned */ -+#define R_SPARC_UA16 55 /* Direct 16 bit unaligned */ -+#define R_SPARC_TLS_GD_HI22 56 -+#define R_SPARC_TLS_GD_LO10 57 -+#define R_SPARC_TLS_GD_ADD 58 -+#define R_SPARC_TLS_GD_CALL 59 -+#define R_SPARC_TLS_LDM_HI22 60 -+#define R_SPARC_TLS_LDM_LO10 61 -+#define R_SPARC_TLS_LDM_ADD 62 -+#define R_SPARC_TLS_LDM_CALL 63 -+#define R_SPARC_TLS_LDO_HIX22 64 -+#define R_SPARC_TLS_LDO_LOX10 65 -+#define R_SPARC_TLS_LDO_ADD 66 -+#define R_SPARC_TLS_IE_HI22 67 -+#define R_SPARC_TLS_IE_LO10 68 -+#define R_SPARC_TLS_IE_LD 69 -+#define R_SPARC_TLS_IE_LDX 70 -+#define R_SPARC_TLS_IE_ADD 71 -+#define R_SPARC_TLS_LE_HIX22 72 -+#define R_SPARC_TLS_LE_LOX10 73 -+#define R_SPARC_TLS_DTPMOD32 74 -+#define R_SPARC_TLS_DTPMOD64 75 -+#define R_SPARC_TLS_DTPOFF32 76 -+#define R_SPARC_TLS_DTPOFF64 77 -+#define R_SPARC_TLS_TPOFF32 78 -+#define R_SPARC_TLS_TPOFF64 79 -+#define R_SPARC_GOTDATA_HIX22 80 -+#define R_SPARC_GOTDATA_LOX10 81 -+#define R_SPARC_GOTDATA_OP_HIX22 82 -+#define R_SPARC_GOTDATA_OP_LOX10 83 -+#define R_SPARC_GOTDATA_OP 84 -+#define R_SPARC_H34 85 -+#define R_SPARC_SIZE32 86 -+#define R_SPARC_SIZE64 87 -+#define R_SPARC_WDISP10 88 -+#define R_SPARC_JMP_IREL 248 -+#define R_SPARC_IRELATIVE 249 -+#define R_SPARC_GNU_VTINHERIT 250 -+#define R_SPARC_GNU_VTENTRY 251 -+#define R_SPARC_REV32 252 -+/* Keep this the last entry. */ -+#define R_SPARC_NUM 253 -+ -+/* For Sparc64, legal values for d_tag of Elf64_Dyn. */ -+ -+#define DT_SPARC_REGISTER 0x70000001 -+#define DT_SPARC_NUM 2 -+ -+/* MIPS R3000 specific definitions. */ -+ -+/* Legal values for e_flags field of Elf32_Ehdr. */ -+ -+#define EF_MIPS_NOREORDER 1 /* A .noreorder directive was used */ -+#define EF_MIPS_PIC 2 /* Contains PIC code */ -+#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence */ -+#define EF_MIPS_XGOT 8 -+#define EF_MIPS_64BIT_WHIRL 16 -+#define EF_MIPS_ABI2 32 -+#define EF_MIPS_ABI_ON32 64 -+#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level */ -+ -+/* Legal values for MIPS architecture level. */ -+ -+#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ -+#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ -+#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ -+#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ -+#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ -+#define EF_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */ -+#define EF_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */ -+ -+/* The following are non-official names and should not be used. */ -+ -+#define E_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ -+#define E_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ -+#define E_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ -+#define E_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ -+#define E_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ -+#define E_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */ -+#define E_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */ -+ -+/* Special section indices. */ -+ -+#define SHN_MIPS_ACOMMON 0xff00 /* Allocated common symbols */ -+#define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */ -+#define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */ -+#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols */ -+#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols */ -+ -+/* Legal values for sh_type field of Elf32_Shdr. */ -+ -+#define SHT_MIPS_LIBLIST 0x70000000 /* Shared objects used in link */ -+#define SHT_MIPS_MSYM 0x70000001 -+#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicting symbols */ -+#define SHT_MIPS_GPTAB 0x70000003 /* Global data area sizes */ -+#define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */ -+#define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging information*/ -+#define SHT_MIPS_REGINFO 0x70000006 /* Register usage information */ -+#define SHT_MIPS_PACKAGE 0x70000007 -+#define SHT_MIPS_PACKSYM 0x70000008 -+#define SHT_MIPS_RELD 0x70000009 -+#define SHT_MIPS_IFACE 0x7000000b -+#define SHT_MIPS_CONTENT 0x7000000c -+#define SHT_MIPS_OPTIONS 0x7000000d /* Miscellaneous options. */ -+#define SHT_MIPS_SHDR 0x70000010 -+#define SHT_MIPS_FDESC 0x70000011 -+#define SHT_MIPS_EXTSYM 0x70000012 -+#define SHT_MIPS_DENSE 0x70000013 -+#define SHT_MIPS_PDESC 0x70000014 -+#define SHT_MIPS_LOCSYM 0x70000015 -+#define SHT_MIPS_AUXSYM 0x70000016 -+#define SHT_MIPS_OPTSYM 0x70000017 -+#define SHT_MIPS_LOCSTR 0x70000018 -+#define SHT_MIPS_LINE 0x70000019 -+#define SHT_MIPS_RFDESC 0x7000001a -+#define SHT_MIPS_DELTASYM 0x7000001b -+#define SHT_MIPS_DELTAINST 0x7000001c -+#define SHT_MIPS_DELTACLASS 0x7000001d -+#define SHT_MIPS_DWARF 0x7000001e /* DWARF debugging information. */ -+#define SHT_MIPS_DELTADECL 0x7000001f -+#define SHT_MIPS_SYMBOL_LIB 0x70000020 -+#define SHT_MIPS_EVENTS 0x70000021 /* Event section. */ -+#define SHT_MIPS_TRANSLATE 0x70000022 -+#define SHT_MIPS_PIXIE 0x70000023 -+#define SHT_MIPS_XLATE 0x70000024 -+#define SHT_MIPS_XLATE_DEBUG 0x70000025 -+#define SHT_MIPS_WHIRL 0x70000026 -+#define SHT_MIPS_EH_REGION 0x70000027 -+#define SHT_MIPS_XLATE_OLD 0x70000028 -+#define SHT_MIPS_PDR_EXCEPTION 0x70000029 -+ -+/* Legal values for sh_flags field of Elf32_Shdr. */ -+ -+#define SHF_MIPS_GPREL 0x10000000 /* Must be part of global data area */ -+#define SHF_MIPS_MERGE 0x20000000 -+#define SHF_MIPS_ADDR 0x40000000 -+#define SHF_MIPS_STRINGS 0x80000000 -+#define SHF_MIPS_NOSTRIP 0x08000000 -+#define SHF_MIPS_LOCAL 0x04000000 -+#define SHF_MIPS_NAMES 0x02000000 -+#define SHF_MIPS_NODUPE 0x01000000 -+ -+ -+/* Symbol tables. */ -+ -+/* MIPS specific values for `st_other'. */ -+#define STO_MIPS_DEFAULT 0x0 -+#define STO_MIPS_INTERNAL 0x1 -+#define STO_MIPS_HIDDEN 0x2 -+#define STO_MIPS_PROTECTED 0x3 -+#define STO_MIPS_PLT 0x8 -+#define STO_MIPS_SC_ALIGN_UNUSED 0xff -+ -+/* MIPS specific values for `st_info'. */ -+#define STB_MIPS_SPLIT_COMMON 13 -+ -+/* Entries found in sections of type SHT_MIPS_GPTAB. */ -+ -+typedef union -+{ -+ struct -+ { -+ Elf32_Word gt_current_g_value; /* -G value used for compilation */ -+ Elf32_Word gt_unused; /* Not used */ -+ } gt_header; /* First entry in section */ -+ struct -+ { -+ Elf32_Word gt_g_value; /* If this value were used for -G */ -+ Elf32_Word gt_bytes; /* This many bytes would be used */ -+ } gt_entry; /* Subsequent entries in section */ -+} Elf32_gptab; -+ -+/* Entry found in sections of type SHT_MIPS_REGINFO. */ -+ -+typedef struct -+{ -+ Elf32_Word ri_gprmask; /* General registers used */ -+ Elf32_Word ri_cprmask[4]; /* Coprocessor registers used */ -+ Elf32_Sword ri_gp_value; /* $gp register value */ -+} Elf32_RegInfo; -+ -+/* Entries found in sections of type SHT_MIPS_OPTIONS. */ -+ -+typedef struct -+{ -+ unsigned char kind; /* Determines interpretation of the -+ variable part of descriptor. */ -+ unsigned char size; /* Size of descriptor, including header. */ -+ Elf32_Section section; /* Section header index of section affected, -+ 0 for global options. */ -+ Elf32_Word info; /* Kind-specific information. */ -+} Elf_Options; -+ -+/* Values for `kind' field in Elf_Options. */ -+ -+#define ODK_NULL 0 /* Undefined. */ -+#define ODK_REGINFO 1 /* Register usage information. */ -+#define ODK_EXCEPTIONS 2 /* Exception processing options. */ -+#define ODK_PAD 3 /* Section padding options. */ -+#define ODK_HWPATCH 4 /* Hardware workarounds performed */ -+#define ODK_FILL 5 /* record the fill value used by the linker. */ -+#define ODK_TAGS 6 /* reserve space for desktop tools to write. */ -+#define ODK_HWAND 7 /* HW workarounds. 'AND' bits when merging. */ -+#define ODK_HWOR 8 /* HW workarounds. 'OR' bits when merging. */ -+ -+/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries. */ -+ -+#define OEX_FPU_MIN 0x1f /* FPE's which MUST be enabled. */ -+#define OEX_FPU_MAX 0x1f00 /* FPE's which MAY be enabled. */ -+#define OEX_PAGE0 0x10000 /* page zero must be mapped. */ -+#define OEX_SMM 0x20000 /* Force sequential memory mode? */ -+#define OEX_FPDBUG 0x40000 /* Force floating point debug mode? */ -+#define OEX_PRECISEFP OEX_FPDBUG -+#define OEX_DISMISS 0x80000 /* Dismiss invalid address faults? */ -+ -+#define OEX_FPU_INVAL 0x10 -+#define OEX_FPU_DIV0 0x08 -+#define OEX_FPU_OFLO 0x04 -+#define OEX_FPU_UFLO 0x02 -+#define OEX_FPU_INEX 0x01 -+ -+/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry. */ -+ -+#define OHW_R4KEOP 0x1 /* R4000 end-of-page patch. */ -+#define OHW_R8KPFETCH 0x2 /* may need R8000 prefetch patch. */ -+#define OHW_R5KEOP 0x4 /* R5000 end-of-page patch. */ -+#define OHW_R5KCVTL 0x8 /* R5000 cvt.[ds].l bug. clean=1. */ -+ -+#define OPAD_PREFIX 0x1 -+#define OPAD_POSTFIX 0x2 -+#define OPAD_SYMBOL 0x4 -+ -+/* Entry found in `.options' section. */ -+ -+typedef struct -+{ -+ Elf32_Word hwp_flags1; /* Extra flags. */ -+ Elf32_Word hwp_flags2; /* Extra flags. */ -+} Elf_Options_Hw; -+ -+/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries. */ -+ -+#define OHWA0_R4KEOP_CHECKED 0x00000001 -+#define OHWA1_R4KEOP_CLEAN 0x00000002 -+ -+/* MIPS relocs. */ -+ -+#define R_MIPS_NONE 0 /* No reloc */ -+#define R_MIPS_16 1 /* Direct 16 bit */ -+#define R_MIPS_32 2 /* Direct 32 bit */ -+#define R_MIPS_REL32 3 /* PC relative 32 bit */ -+#define R_MIPS_26 4 /* Direct 26 bit shifted */ -+#define R_MIPS_HI16 5 /* High 16 bit */ -+#define R_MIPS_LO16 6 /* Low 16 bit */ -+#define R_MIPS_GPREL16 7 /* GP relative 16 bit */ -+#define R_MIPS_LITERAL 8 /* 16 bit literal entry */ -+#define R_MIPS_GOT16 9 /* 16 bit GOT entry */ -+#define R_MIPS_PC16 10 /* PC relative 16 bit */ -+#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */ -+#define R_MIPS_GPREL32 12 /* GP relative 32 bit */ -+ -+#define R_MIPS_SHIFT5 16 -+#define R_MIPS_SHIFT6 17 -+#define R_MIPS_64 18 -+#define R_MIPS_GOT_DISP 19 -+#define R_MIPS_GOT_PAGE 20 -+#define R_MIPS_GOT_OFST 21 -+#define R_MIPS_GOT_HI16 22 -+#define R_MIPS_GOT_LO16 23 -+#define R_MIPS_SUB 24 -+#define R_MIPS_INSERT_A 25 -+#define R_MIPS_INSERT_B 26 -+#define R_MIPS_DELETE 27 -+#define R_MIPS_HIGHER 28 -+#define R_MIPS_HIGHEST 29 -+#define R_MIPS_CALL_HI16 30 -+#define R_MIPS_CALL_LO16 31 -+#define R_MIPS_SCN_DISP 32 -+#define R_MIPS_REL16 33 -+#define R_MIPS_ADD_IMMEDIATE 34 -+#define R_MIPS_PJUMP 35 -+#define R_MIPS_RELGOT 36 -+#define R_MIPS_JALR 37 -+#define R_MIPS_TLS_DTPMOD32 38 /* Module number 32 bit */ -+#define R_MIPS_TLS_DTPREL32 39 /* Module-relative offset 32 bit */ -+#define R_MIPS_TLS_DTPMOD64 40 /* Module number 64 bit */ -+#define R_MIPS_TLS_DTPREL64 41 /* Module-relative offset 64 bit */ -+#define R_MIPS_TLS_GD 42 /* 16 bit GOT offset for GD */ -+#define R_MIPS_TLS_LDM 43 /* 16 bit GOT offset for LDM */ -+#define R_MIPS_TLS_DTPREL_HI16 44 /* Module-relative offset, high 16 bits */ -+#define R_MIPS_TLS_DTPREL_LO16 45 /* Module-relative offset, low 16 bits */ -+#define R_MIPS_TLS_GOTTPREL 46 /* 16 bit GOT offset for IE */ -+#define R_MIPS_TLS_TPREL32 47 /* TP-relative offset, 32 bit */ -+#define R_MIPS_TLS_TPREL64 48 /* TP-relative offset, 64 bit */ -+#define R_MIPS_TLS_TPREL_HI16 49 /* TP-relative offset, high 16 bits */ -+#define R_MIPS_TLS_TPREL_LO16 50 /* TP-relative offset, low 16 bits */ -+#define R_MIPS_GLOB_DAT 51 -+#define R_MIPS_COPY 126 -+#define R_MIPS_JUMP_SLOT 127 -+/* Keep this the last entry. */ -+#define R_MIPS_NUM 128 -+ -+/* Legal values for p_type field of Elf32_Phdr. */ -+ -+#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */ -+#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */ -+#define PT_MIPS_OPTIONS 0x70000002 -+ -+/* Special program header types. */ -+ -+#define PF_MIPS_LOCAL 0x10000000 -+ -+/* Legal values for d_tag field of Elf32_Dyn. */ -+ -+#define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime linker interface version */ -+#define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */ -+#define DT_MIPS_ICHECKSUM 0x70000003 /* Checksum */ -+#define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */ -+#define DT_MIPS_FLAGS 0x70000005 /* Flags */ -+#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */ -+#define DT_MIPS_MSYM 0x70000007 -+#define DT_MIPS_CONFLICT 0x70000008 /* Address of CONFLICT section */ -+#define DT_MIPS_LIBLIST 0x70000009 /* Address of LIBLIST section */ -+#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local GOT entries */ -+#define DT_MIPS_CONFLICTNO 0x7000000b /* Number of CONFLICT entries */ -+#define DT_MIPS_LIBLISTNO 0x70000010 /* Number of LIBLIST entries */ -+#define DT_MIPS_SYMTABNO 0x70000011 /* Number of DYNSYM entries */ -+#define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */ -+#define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in DYNSYM */ -+#define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */ -+#define DT_MIPS_RLD_MAP 0x70000016 /* Address of run time loader map. */ -+#define DT_MIPS_DELTA_CLASS 0x70000017 /* Delta C++ class definition. */ -+#define DT_MIPS_DELTA_CLASS_NO 0x70000018 /* Number of entries in -+ DT_MIPS_DELTA_CLASS. */ -+#define DT_MIPS_DELTA_INSTANCE 0x70000019 /* Delta C++ class instances. */ -+#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in -+ DT_MIPS_DELTA_INSTANCE. */ -+#define DT_MIPS_DELTA_RELOC 0x7000001b /* Delta relocations. */ -+#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in -+ DT_MIPS_DELTA_RELOC. */ -+#define DT_MIPS_DELTA_SYM 0x7000001d /* Delta symbols that Delta -+ relocations refer to. */ -+#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in -+ DT_MIPS_DELTA_SYM. */ -+#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the -+ class declaration. */ -+#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in -+ DT_MIPS_DELTA_CLASSSYM. */ -+#define DT_MIPS_CXX_FLAGS 0x70000022 /* Flags indicating for C++ flavor. */ -+#define DT_MIPS_PIXIE_INIT 0x70000023 -+#define DT_MIPS_SYMBOL_LIB 0x70000024 -+#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025 -+#define DT_MIPS_LOCAL_GOTIDX 0x70000026 -+#define DT_MIPS_HIDDEN_GOTIDX 0x70000027 -+#define DT_MIPS_PROTECTED_GOTIDX 0x70000028 -+#define DT_MIPS_OPTIONS 0x70000029 /* Address of .options. */ -+#define DT_MIPS_INTERFACE 0x7000002a /* Address of .interface. */ -+#define DT_MIPS_DYNSTR_ALIGN 0x7000002b -+#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */ -+#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve -+ function stored in GOT. */ -+#define DT_MIPS_PERF_SUFFIX 0x7000002e /* Default suffix of dso to be added -+ by rld on dlopen() calls. */ -+#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */ -+#define DT_MIPS_GP_VALUE 0x70000030 /* GP value for aux GOTs. */ -+#define DT_MIPS_AUX_DYNAMIC 0x70000031 /* Address of aux .dynamic. */ -+/* The address of .got.plt in an executable using the new non-PIC ABI. */ -+#define DT_MIPS_PLTGOT 0x70000032 -+/* The base of the PLT in an executable using the new non-PIC ABI if that -+ PLT is writable. For a non-writable PLT, this is omitted or has a zero -+ value. */ -+#define DT_MIPS_RWPLT 0x70000034 -+#define DT_MIPS_NUM 0x35 -+ -+/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */ -+ -+#define RHF_NONE 0 /* No flags */ -+#define RHF_QUICKSTART (1 << 0) /* Use quickstart */ -+#define RHF_NOTPOT (1 << 1) /* Hash size not power of 2 */ -+#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2) /* Ignore LD_LIBRARY_PATH */ -+#define RHF_NO_MOVE (1 << 3) -+#define RHF_SGI_ONLY (1 << 4) -+#define RHF_GUARANTEE_INIT (1 << 5) -+#define RHF_DELTA_C_PLUS_PLUS (1 << 6) -+#define RHF_GUARANTEE_START_INIT (1 << 7) -+#define RHF_PIXIE (1 << 8) -+#define RHF_DEFAULT_DELAY_LOAD (1 << 9) -+#define RHF_REQUICKSTART (1 << 10) -+#define RHF_REQUICKSTARTED (1 << 11) -+#define RHF_CORD (1 << 12) -+#define RHF_NO_UNRES_UNDEF (1 << 13) -+#define RHF_RLD_ORDER_SAFE (1 << 14) -+ -+/* Entries found in sections of type SHT_MIPS_LIBLIST. */ -+ -+typedef struct -+{ -+ Elf32_Word l_name; /* Name (string table index) */ -+ Elf32_Word l_time_stamp; /* Timestamp */ -+ Elf32_Word l_checksum; /* Checksum */ -+ Elf32_Word l_version; /* Interface version */ -+ Elf32_Word l_flags; /* Flags */ -+} Elf32_Lib; -+ -+typedef struct -+{ -+ Elf64_Word l_name; /* Name (string table index) */ -+ Elf64_Word l_time_stamp; /* Timestamp */ -+ Elf64_Word l_checksum; /* Checksum */ -+ Elf64_Word l_version; /* Interface version */ -+ Elf64_Word l_flags; /* Flags */ -+} Elf64_Lib; -+ -+ -+/* Legal values for l_flags. */ -+ -+#define LL_NONE 0 -+#define LL_EXACT_MATCH (1 << 0) /* Require exact match */ -+#define LL_IGNORE_INT_VER (1 << 1) /* Ignore interface version */ -+#define LL_REQUIRE_MINOR (1 << 2) -+#define LL_EXPORTS (1 << 3) -+#define LL_DELAY_LOAD (1 << 4) -+#define LL_DELTA (1 << 5) -+ -+/* Entries found in sections of type SHT_MIPS_CONFLICT. */ -+ -+typedef Elf32_Addr Elf32_Conflict; -+ -+ -+/* HPPA specific definitions. */ -+ -+/* Legal values for e_flags field of Elf32_Ehdr. */ -+ -+#define EF_PARISC_TRAPNIL 0x00010000 /* Trap nil pointer dereference. */ -+#define EF_PARISC_EXT 0x00020000 /* Program uses arch. extensions. */ -+#define EF_PARISC_LSB 0x00040000 /* Program expects little endian. */ -+#define EF_PARISC_WIDE 0x00080000 /* Program expects wide mode. */ -+#define EF_PARISC_NO_KABP 0x00100000 /* No kernel assisted branch -+ prediction. */ -+#define EF_PARISC_LAZYSWAP 0x00400000 /* Allow lazy swapping. */ -+#define EF_PARISC_ARCH 0x0000ffff /* Architecture version. */ -+ -+/* Defined values for `e_flags & EF_PARISC_ARCH' are: */ -+ -+#define EFA_PARISC_1_0 0x020b /* PA-RISC 1.0 big-endian. */ -+#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */ -+#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */ -+ -+/* Additional section indeces. */ -+ -+#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tenatively declared -+ symbols in ANSI C. */ -+#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */ -+ -+/* Legal values for sh_type field of Elf32_Shdr. */ -+ -+#define SHT_PARISC_EXT 0x70000000 /* Contains product specific ext. */ -+#define SHT_PARISC_UNWIND 0x70000001 /* Unwind information. */ -+#define SHT_PARISC_DOC 0x70000002 /* Debug info for optimized code. */ -+ -+/* Legal values for sh_flags field of Elf32_Shdr. */ -+ -+#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */ -+#define SHF_PARISC_HUGE 0x40000000 /* Section far from gp. */ -+#define SHF_PARISC_SBP 0x80000000 /* Static branch prediction code. */ -+ -+/* Legal values for ST_TYPE subfield of st_info (symbol type). */ -+ -+#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */ -+ -+#define STT_HP_OPAQUE (STT_LOOS + 0x1) -+#define STT_HP_STUB (STT_LOOS + 0x2) -+ -+/* HPPA relocs. */ -+ -+#define R_PARISC_NONE 0 /* No reloc. */ -+#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */ -+#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */ -+#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */ -+#define R_PARISC_DIR17F 4 /* 17 bits of eff. address. */ -+#define R_PARISC_DIR14R 6 /* Right 14 bits of eff. address. */ -+#define R_PARISC_PCREL32 9 /* 32-bit rel. address. */ -+#define R_PARISC_PCREL21L 10 /* Left 21 bits of rel. address. */ -+#define R_PARISC_PCREL17R 11 /* Right 17 bits of rel. address. */ -+#define R_PARISC_PCREL17F 12 /* 17 bits of rel. address. */ -+#define R_PARISC_PCREL14R 14 /* Right 14 bits of rel. address. */ -+#define R_PARISC_DPREL21L 18 /* Left 21 bits of rel. address. */ -+#define R_PARISC_DPREL14R 22 /* Right 14 bits of rel. address. */ -+#define R_PARISC_GPREL21L 26 /* GP-relative, left 21 bits. */ -+#define R_PARISC_GPREL14R 30 /* GP-relative, right 14 bits. */ -+#define R_PARISC_LTOFF21L 34 /* LT-relative, left 21 bits. */ -+#define R_PARISC_LTOFF14R 38 /* LT-relative, right 14 bits. */ -+#define R_PARISC_SECREL32 41 /* 32 bits section rel. address. */ -+#define R_PARISC_SEGBASE 48 /* No relocation, set segment base. */ -+#define R_PARISC_SEGREL32 49 /* 32 bits segment rel. address. */ -+#define R_PARISC_PLTOFF21L 50 /* PLT rel. address, left 21 bits. */ -+#define R_PARISC_PLTOFF14R 54 /* PLT rel. address, right 14 bits. */ -+#define R_PARISC_LTOFF_FPTR32 57 /* 32 bits LT-rel. function pointer. */ -+#define R_PARISC_LTOFF_FPTR21L 58 /* LT-rel. fct ptr, left 21 bits. */ -+#define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */ -+#define R_PARISC_FPTR64 64 /* 64 bits function address. */ -+#define R_PARISC_PLABEL32 65 /* 32 bits function address. */ -+#define R_PARISC_PLABEL21L 66 /* Left 21 bits of fdesc address. */ -+#define R_PARISC_PLABEL14R 70 /* Right 14 bits of fdesc address. */ -+#define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */ -+#define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */ -+#define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */ -+#define R_PARISC_PCREL14DR 76 /* PC rel. address, right 14 bits. */ -+#define R_PARISC_PCREL16F 77 /* 16 bits PC-rel. address. */ -+#define R_PARISC_PCREL16WF 78 /* 16 bits PC-rel. address. */ -+#define R_PARISC_PCREL16DF 79 /* 16 bits PC-rel. address. */ -+#define R_PARISC_DIR64 80 /* 64 bits of eff. address. */ -+#define R_PARISC_DIR14WR 83 /* 14 bits of eff. address. */ -+#define R_PARISC_DIR14DR 84 /* 14 bits of eff. address. */ -+#define R_PARISC_DIR16F 85 /* 16 bits of eff. address. */ -+#define R_PARISC_DIR16WF 86 /* 16 bits of eff. address. */ -+#define R_PARISC_DIR16DF 87 /* 16 bits of eff. address. */ -+#define R_PARISC_GPREL64 88 /* 64 bits of GP-rel. address. */ -+#define R_PARISC_GPREL14WR 91 /* GP-rel. address, right 14 bits. */ -+#define R_PARISC_GPREL14DR 92 /* GP-rel. address, right 14 bits. */ -+#define R_PARISC_GPREL16F 93 /* 16 bits GP-rel. address. */ -+#define R_PARISC_GPREL16WF 94 /* 16 bits GP-rel. address. */ -+#define R_PARISC_GPREL16DF 95 /* 16 bits GP-rel. address. */ -+#define R_PARISC_LTOFF64 96 /* 64 bits LT-rel. address. */ -+#define R_PARISC_LTOFF14WR 99 /* LT-rel. address, right 14 bits. */ -+#define R_PARISC_LTOFF14DR 100 /* LT-rel. address, right 14 bits. */ -+#define R_PARISC_LTOFF16F 101 /* 16 bits LT-rel. address. */ -+#define R_PARISC_LTOFF16WF 102 /* 16 bits LT-rel. address. */ -+#define R_PARISC_LTOFF16DF 103 /* 16 bits LT-rel. address. */ -+#define R_PARISC_SECREL64 104 /* 64 bits section rel. address. */ -+#define R_PARISC_SEGREL64 112 /* 64 bits segment rel. address. */ -+#define R_PARISC_PLTOFF14WR 115 /* PLT-rel. address, right 14 bits. */ -+#define R_PARISC_PLTOFF14DR 116 /* PLT-rel. address, right 14 bits. */ -+#define R_PARISC_PLTOFF16F 117 /* 16 bits LT-rel. address. */ -+#define R_PARISC_PLTOFF16WF 118 /* 16 bits PLT-rel. address. */ -+#define R_PARISC_PLTOFF16DF 119 /* 16 bits PLT-rel. address. */ -+#define R_PARISC_LTOFF_FPTR64 120 /* 64 bits LT-rel. function ptr. */ -+#define R_PARISC_LTOFF_FPTR14WR 123 /* LT-rel. fct. ptr., right 14 bits. */ -+#define R_PARISC_LTOFF_FPTR14DR 124 /* LT-rel. fct. ptr., right 14 bits. */ -+#define R_PARISC_LTOFF_FPTR16F 125 /* 16 bits LT-rel. function ptr. */ -+#define R_PARISC_LTOFF_FPTR16WF 126 /* 16 bits LT-rel. function ptr. */ -+#define R_PARISC_LTOFF_FPTR16DF 127 /* 16 bits LT-rel. function ptr. */ -+#define R_PARISC_LORESERVE 128 -+#define R_PARISC_COPY 128 /* Copy relocation. */ -+#define R_PARISC_IPLT 129 /* Dynamic reloc, imported PLT */ -+#define R_PARISC_EPLT 130 /* Dynamic reloc, exported PLT */ -+#define R_PARISC_TPREL32 153 /* 32 bits TP-rel. address. */ -+#define R_PARISC_TPREL21L 154 /* TP-rel. address, left 21 bits. */ -+#define R_PARISC_TPREL14R 158 /* TP-rel. address, right 14 bits. */ -+#define R_PARISC_LTOFF_TP21L 162 /* LT-TP-rel. address, left 21 bits. */ -+#define R_PARISC_LTOFF_TP14R 166 /* LT-TP-rel. address, right 14 bits.*/ -+#define R_PARISC_LTOFF_TP14F 167 /* 14 bits LT-TP-rel. address. */ -+#define R_PARISC_TPREL64 216 /* 64 bits TP-rel. address. */ -+#define R_PARISC_TPREL14WR 219 /* TP-rel. address, right 14 bits. */ -+#define R_PARISC_TPREL14DR 220 /* TP-rel. address, right 14 bits. */ -+#define R_PARISC_TPREL16F 221 /* 16 bits TP-rel. address. */ -+#define R_PARISC_TPREL16WF 222 /* 16 bits TP-rel. address. */ -+#define R_PARISC_TPREL16DF 223 /* 16 bits TP-rel. address. */ -+#define R_PARISC_LTOFF_TP64 224 /* 64 bits LT-TP-rel. address. */ -+#define R_PARISC_LTOFF_TP14WR 227 /* LT-TP-rel. address, right 14 bits.*/ -+#define R_PARISC_LTOFF_TP14DR 228 /* LT-TP-rel. address, right 14 bits.*/ -+#define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */ -+#define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */ -+#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */ -+#define R_PARISC_GNU_VTENTRY 232 -+#define R_PARISC_GNU_VTINHERIT 233 -+#define R_PARISC_TLS_GD21L 234 /* GD 21-bit left. */ -+#define R_PARISC_TLS_GD14R 235 /* GD 14-bit right. */ -+#define R_PARISC_TLS_GDCALL 236 /* GD call to __t_g_a. */ -+#define R_PARISC_TLS_LDM21L 237 /* LD module 21-bit left. */ -+#define R_PARISC_TLS_LDM14R 238 /* LD module 14-bit right. */ -+#define R_PARISC_TLS_LDMCALL 239 /* LD module call to __t_g_a. */ -+#define R_PARISC_TLS_LDO21L 240 /* LD offset 21-bit left. */ -+#define R_PARISC_TLS_LDO14R 241 /* LD offset 14-bit right. */ -+#define R_PARISC_TLS_DTPMOD32 242 /* DTP module 32-bit. */ -+#define R_PARISC_TLS_DTPMOD64 243 /* DTP module 64-bit. */ -+#define R_PARISC_TLS_DTPOFF32 244 /* DTP offset 32-bit. */ -+#define R_PARISC_TLS_DTPOFF64 245 /* DTP offset 32-bit. */ -+#define R_PARISC_TLS_LE21L R_PARISC_TPREL21L -+#define R_PARISC_TLS_LE14R R_PARISC_TPREL14R -+#define R_PARISC_TLS_IE21L R_PARISC_LTOFF_TP21L -+#define R_PARISC_TLS_IE14R R_PARISC_LTOFF_TP14R -+#define R_PARISC_TLS_TPREL32 R_PARISC_TPREL32 -+#define R_PARISC_TLS_TPREL64 R_PARISC_TPREL64 -+#define R_PARISC_HIRESERVE 255 -+ -+/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */ -+ -+#define PT_HP_TLS (PT_LOOS + 0x0) -+#define PT_HP_CORE_NONE (PT_LOOS + 0x1) -+#define PT_HP_CORE_VERSION (PT_LOOS + 0x2) -+#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3) -+#define PT_HP_CORE_COMM (PT_LOOS + 0x4) -+#define PT_HP_CORE_PROC (PT_LOOS + 0x5) -+#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6) -+#define PT_HP_CORE_STACK (PT_LOOS + 0x7) -+#define PT_HP_CORE_SHM (PT_LOOS + 0x8) -+#define PT_HP_CORE_MMF (PT_LOOS + 0x9) -+#define PT_HP_PARALLEL (PT_LOOS + 0x10) -+#define PT_HP_FASTBIND (PT_LOOS + 0x11) -+#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12) -+#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13) -+#define PT_HP_STACK (PT_LOOS + 0x14) -+ -+#define PT_PARISC_ARCHEXT 0x70000000 -+#define PT_PARISC_UNWIND 0x70000001 -+ -+/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr. */ -+ -+#define PF_PARISC_SBP 0x08000000 -+ -+#define PF_HP_PAGE_SIZE 0x00100000 -+#define PF_HP_FAR_SHARED 0x00200000 -+#define PF_HP_NEAR_SHARED 0x00400000 -+#define PF_HP_CODE 0x01000000 -+#define PF_HP_MODIFY 0x02000000 -+#define PF_HP_LAZYSWAP 0x04000000 -+#define PF_HP_SBP 0x08000000 -+ -+ -+/* Alpha specific definitions. */ -+ -+/* Legal values for e_flags field of Elf64_Ehdr. */ -+ -+#define EF_ALPHA_32BIT 1 /* All addresses must be < 2GB. */ -+#define EF_ALPHA_CANRELAX 2 /* Relocations for relaxing exist. */ -+ -+/* Legal values for sh_type field of Elf64_Shdr. */ -+ -+/* These two are primerily concerned with ECOFF debugging info. */ -+#define SHT_ALPHA_DEBUG 0x70000001 -+#define SHT_ALPHA_REGINFO 0x70000002 -+ -+/* Legal values for sh_flags field of Elf64_Shdr. */ -+ -+#define SHF_ALPHA_GPREL 0x10000000 -+ -+/* Legal values for st_other field of Elf64_Sym. */ -+#define STO_ALPHA_NOPV 0x80 /* No PV required. */ -+#define STO_ALPHA_STD_GPLOAD 0x88 /* PV only used for initial ldgp. */ -+ -+/* Alpha relocs. */ -+ -+#define R_ALPHA_NONE 0 /* No reloc */ -+#define R_ALPHA_REFLONG 1 /* Direct 32 bit */ -+#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */ -+#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */ -+#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */ -+#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */ -+#define R_ALPHA_GPDISP 6 /* Add displacement to GP */ -+#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */ -+#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */ -+#define R_ALPHA_SREL16 9 /* PC relative 16 bit */ -+#define R_ALPHA_SREL32 10 /* PC relative 32 bit */ -+#define R_ALPHA_SREL64 11 /* PC relative 64 bit */ -+#define R_ALPHA_GPRELHIGH 17 /* GP relative 32 bit, high 16 bits */ -+#define R_ALPHA_GPRELLOW 18 /* GP relative 32 bit, low 16 bits */ -+#define R_ALPHA_GPREL16 19 /* GP relative 16 bit */ -+#define R_ALPHA_COPY 24 /* Copy symbol at runtime */ -+#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */ -+#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */ -+#define R_ALPHA_RELATIVE 27 /* Adjust by program base */ -+#define R_ALPHA_TLS_GD_HI 28 -+#define R_ALPHA_TLSGD 29 -+#define R_ALPHA_TLS_LDM 30 -+#define R_ALPHA_DTPMOD64 31 -+#define R_ALPHA_GOTDTPREL 32 -+#define R_ALPHA_DTPREL64 33 -+#define R_ALPHA_DTPRELHI 34 -+#define R_ALPHA_DTPRELLO 35 -+#define R_ALPHA_DTPREL16 36 -+#define R_ALPHA_GOTTPREL 37 -+#define R_ALPHA_TPREL64 38 -+#define R_ALPHA_TPRELHI 39 -+#define R_ALPHA_TPRELLO 40 -+#define R_ALPHA_TPREL16 41 -+/* Keep this the last entry. */ -+#define R_ALPHA_NUM 46 -+ -+/* Magic values of the LITUSE relocation addend. */ -+#define LITUSE_ALPHA_ADDR 0 -+#define LITUSE_ALPHA_BASE 1 -+#define LITUSE_ALPHA_BYTOFF 2 -+#define LITUSE_ALPHA_JSR 3 -+#define LITUSE_ALPHA_TLS_GD 4 -+#define LITUSE_ALPHA_TLS_LDM 5 -+ -+/* Legal values for d_tag of Elf64_Dyn. */ -+#define DT_ALPHA_PLTRO (DT_LOPROC + 0) -+#define DT_ALPHA_NUM 1 -+ -+/* PowerPC specific declarations */ -+ -+/* Values for Elf32/64_Ehdr.e_flags. */ -+#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */ -+ -+/* Cygnus local bits below */ -+#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/ -+#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib -+ flag */ -+ -+/* PowerPC relocations defined by the ABIs */ -+#define R_PPC_NONE 0 -+#define R_PPC_ADDR32 1 /* 32bit absolute address */ -+#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */ -+#define R_PPC_ADDR16 3 /* 16bit absolute address */ -+#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ -+#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ -+#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ -+#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ -+#define R_PPC_ADDR14_BRTAKEN 8 -+#define R_PPC_ADDR14_BRNTAKEN 9 -+#define R_PPC_REL24 10 /* PC relative 26 bit */ -+#define R_PPC_REL14 11 /* PC relative 16 bit */ -+#define R_PPC_REL14_BRTAKEN 12 -+#define R_PPC_REL14_BRNTAKEN 13 -+#define R_PPC_GOT16 14 -+#define R_PPC_GOT16_LO 15 -+#define R_PPC_GOT16_HI 16 -+#define R_PPC_GOT16_HA 17 -+#define R_PPC_PLTREL24 18 -+#define R_PPC_COPY 19 -+#define R_PPC_GLOB_DAT 20 -+#define R_PPC_JMP_SLOT 21 -+#define R_PPC_RELATIVE 22 -+#define R_PPC_LOCAL24PC 23 -+#define R_PPC_UADDR32 24 -+#define R_PPC_UADDR16 25 -+#define R_PPC_REL32 26 -+#define R_PPC_PLT32 27 -+#define R_PPC_PLTREL32 28 -+#define R_PPC_PLT16_LO 29 -+#define R_PPC_PLT16_HI 30 -+#define R_PPC_PLT16_HA 31 -+#define R_PPC_SDAREL16 32 -+#define R_PPC_SECTOFF 33 -+#define R_PPC_SECTOFF_LO 34 -+#define R_PPC_SECTOFF_HI 35 -+#define R_PPC_SECTOFF_HA 36 -+ -+/* PowerPC relocations defined for the TLS access ABI. */ -+#define R_PPC_TLS 67 /* none (sym+add)@tls */ -+#define R_PPC_DTPMOD32 68 /* word32 (sym+add)@dtpmod */ -+#define R_PPC_TPREL16 69 /* half16* (sym+add)@tprel */ -+#define R_PPC_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ -+#define R_PPC_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ -+#define R_PPC_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ -+#define R_PPC_TPREL32 73 /* word32 (sym+add)@tprel */ -+#define R_PPC_DTPREL16 74 /* half16* (sym+add)@dtprel */ -+#define R_PPC_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ -+#define R_PPC_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ -+#define R_PPC_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ -+#define R_PPC_DTPREL32 78 /* word32 (sym+add)@dtprel */ -+#define R_PPC_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ -+#define R_PPC_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ -+#define R_PPC_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ -+#define R_PPC_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ -+#define R_PPC_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ -+#define R_PPC_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ -+#define R_PPC_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ -+#define R_PPC_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ -+#define R_PPC_GOT_TPREL16 87 /* half16* (sym+add)@got@tprel */ -+#define R_PPC_GOT_TPREL16_LO 88 /* half16 (sym+add)@got@tprel@l */ -+#define R_PPC_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ -+#define R_PPC_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ -+#define R_PPC_GOT_DTPREL16 91 /* half16* (sym+add)@got@dtprel */ -+#define R_PPC_GOT_DTPREL16_LO 92 /* half16* (sym+add)@got@dtprel@l */ -+#define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */ -+#define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */ -+ -+/* The remaining relocs are from the Embedded ELF ABI, and are not -+ in the SVR4 ELF ABI. */ -+#define R_PPC_EMB_NADDR32 101 -+#define R_PPC_EMB_NADDR16 102 -+#define R_PPC_EMB_NADDR16_LO 103 -+#define R_PPC_EMB_NADDR16_HI 104 -+#define R_PPC_EMB_NADDR16_HA 105 -+#define R_PPC_EMB_SDAI16 106 -+#define R_PPC_EMB_SDA2I16 107 -+#define R_PPC_EMB_SDA2REL 108 -+#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */ -+#define R_PPC_EMB_MRKREF 110 -+#define R_PPC_EMB_RELSEC16 111 -+#define R_PPC_EMB_RELST_LO 112 -+#define R_PPC_EMB_RELST_HI 113 -+#define R_PPC_EMB_RELST_HA 114 -+#define R_PPC_EMB_BIT_FLD 115 -+#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */ -+ -+/* Diab tool relocations. */ -+#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */ -+#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */ -+#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */ -+#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */ -+#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */ -+#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */ -+ -+/* GNU extension to support local ifunc. */ -+#define R_PPC_IRELATIVE 248 -+ -+/* GNU relocs used in PIC code sequences. */ -+#define R_PPC_REL16 249 /* half16 (sym+add-.) */ -+#define R_PPC_REL16_LO 250 /* half16 (sym+add-.)@l */ -+#define R_PPC_REL16_HI 251 /* half16 (sym+add-.)@h */ -+#define R_PPC_REL16_HA 252 /* half16 (sym+add-.)@ha */ -+ -+/* This is a phony reloc to handle any old fashioned TOC16 references -+ that may still be in object files. */ -+#define R_PPC_TOC16 255 -+ -+/* PowerPC specific values for the Dyn d_tag field. */ -+#define DT_PPC_GOT (DT_LOPROC + 0) -+#define DT_PPC_NUM 1 -+ -+/* PowerPC64 relocations defined by the ABIs */ -+#define R_PPC64_NONE R_PPC_NONE -+#define R_PPC64_ADDR32 R_PPC_ADDR32 /* 32bit absolute address */ -+#define R_PPC64_ADDR24 R_PPC_ADDR24 /* 26bit address, word aligned */ -+#define R_PPC64_ADDR16 R_PPC_ADDR16 /* 16bit absolute address */ -+#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of address */ -+#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of address. */ -+#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits. */ -+#define R_PPC64_ADDR14 R_PPC_ADDR14 /* 16bit address, word aligned */ -+#define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN -+#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN -+#define R_PPC64_REL24 R_PPC_REL24 /* PC-rel. 26 bit, word aligned */ -+#define R_PPC64_REL14 R_PPC_REL14 /* PC relative 16 bit */ -+#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN -+#define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN -+#define R_PPC64_GOT16 R_PPC_GOT16 -+#define R_PPC64_GOT16_LO R_PPC_GOT16_LO -+#define R_PPC64_GOT16_HI R_PPC_GOT16_HI -+#define R_PPC64_GOT16_HA R_PPC_GOT16_HA -+ -+#define R_PPC64_COPY R_PPC_COPY -+#define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT -+#define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT -+#define R_PPC64_RELATIVE R_PPC_RELATIVE -+ -+#define R_PPC64_UADDR32 R_PPC_UADDR32 -+#define R_PPC64_UADDR16 R_PPC_UADDR16 -+#define R_PPC64_REL32 R_PPC_REL32 -+#define R_PPC64_PLT32 R_PPC_PLT32 -+#define R_PPC64_PLTREL32 R_PPC_PLTREL32 -+#define R_PPC64_PLT16_LO R_PPC_PLT16_LO -+#define R_PPC64_PLT16_HI R_PPC_PLT16_HI -+#define R_PPC64_PLT16_HA R_PPC_PLT16_HA -+ -+#define R_PPC64_SECTOFF R_PPC_SECTOFF -+#define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO -+#define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI -+#define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA -+#define R_PPC64_ADDR30 37 /* word30 (S + A - P) >> 2 */ -+#define R_PPC64_ADDR64 38 /* doubleword64 S + A */ -+#define R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A) */ -+#define R_PPC64_ADDR16_HIGHERA 40 /* half16 #highera(S + A) */ -+#define R_PPC64_ADDR16_HIGHEST 41 /* half16 #highest(S + A) */ -+#define R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A) */ -+#define R_PPC64_UADDR64 43 /* doubleword64 S + A */ -+#define R_PPC64_REL64 44 /* doubleword64 S + A - P */ -+#define R_PPC64_PLT64 45 /* doubleword64 L + A */ -+#define R_PPC64_PLTREL64 46 /* doubleword64 L + A - P */ -+#define R_PPC64_TOC16 47 /* half16* S + A - .TOC */ -+#define R_PPC64_TOC16_LO 48 /* half16 #lo(S + A - .TOC.) */ -+#define R_PPC64_TOC16_HI 49 /* half16 #hi(S + A - .TOC.) */ -+#define R_PPC64_TOC16_HA 50 /* half16 #ha(S + A - .TOC.) */ -+#define R_PPC64_TOC 51 /* doubleword64 .TOC */ -+#define R_PPC64_PLTGOT16 52 /* half16* M + A */ -+#define R_PPC64_PLTGOT16_LO 53 /* half16 #lo(M + A) */ -+#define R_PPC64_PLTGOT16_HI 54 /* half16 #hi(M + A) */ -+#define R_PPC64_PLTGOT16_HA 55 /* half16 #ha(M + A) */ -+ -+#define R_PPC64_ADDR16_DS 56 /* half16ds* (S + A) >> 2 */ -+#define R_PPC64_ADDR16_LO_DS 57 /* half16ds #lo(S + A) >> 2 */ -+#define R_PPC64_GOT16_DS 58 /* half16ds* (G + A) >> 2 */ -+#define R_PPC64_GOT16_LO_DS 59 /* half16ds #lo(G + A) >> 2 */ -+#define R_PPC64_PLT16_LO_DS 60 /* half16ds #lo(L + A) >> 2 */ -+#define R_PPC64_SECTOFF_DS 61 /* half16ds* (R + A) >> 2 */ -+#define R_PPC64_SECTOFF_LO_DS 62 /* half16ds #lo(R + A) >> 2 */ -+#define R_PPC64_TOC16_DS 63 /* half16ds* (S + A - .TOC.) >> 2 */ -+#define R_PPC64_TOC16_LO_DS 64 /* half16ds #lo(S + A - .TOC.) >> 2 */ -+#define R_PPC64_PLTGOT16_DS 65 /* half16ds* (M + A) >> 2 */ -+#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds #lo(M + A) >> 2 */ -+ -+/* PowerPC64 relocations defined for the TLS access ABI. */ -+#define R_PPC64_TLS 67 /* none (sym+add)@tls */ -+#define R_PPC64_DTPMOD64 68 /* doubleword64 (sym+add)@dtpmod */ -+#define R_PPC64_TPREL16 69 /* half16* (sym+add)@tprel */ -+#define R_PPC64_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ -+#define R_PPC64_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ -+#define R_PPC64_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ -+#define R_PPC64_TPREL64 73 /* doubleword64 (sym+add)@tprel */ -+#define R_PPC64_DTPREL16 74 /* half16* (sym+add)@dtprel */ -+#define R_PPC64_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ -+#define R_PPC64_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ -+#define R_PPC64_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ -+#define R_PPC64_DTPREL64 78 /* doubleword64 (sym+add)@dtprel */ -+#define R_PPC64_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ -+#define R_PPC64_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ -+#define R_PPC64_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ -+#define R_PPC64_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ -+#define R_PPC64_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ -+#define R_PPC64_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ -+#define R_PPC64_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ -+#define R_PPC64_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ -+#define R_PPC64_GOT_TPREL16_DS 87 /* half16ds* (sym+add)@got@tprel */ -+#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */ -+#define R_PPC64_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ -+#define R_PPC64_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ -+#define R_PPC64_GOT_DTPREL16_DS 91 /* half16ds* (sym+add)@got@dtprel */ -+#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */ -+#define R_PPC64_GOT_DTPREL16_HI 93 /* half16 (sym+add)@got@dtprel@h */ -+#define R_PPC64_GOT_DTPREL16_HA 94 /* half16 (sym+add)@got@dtprel@ha */ -+#define R_PPC64_TPREL16_DS 95 /* half16ds* (sym+add)@tprel */ -+#define R_PPC64_TPREL16_LO_DS 96 /* half16ds (sym+add)@tprel@l */ -+#define R_PPC64_TPREL16_HIGHER 97 /* half16 (sym+add)@tprel@higher */ -+#define R_PPC64_TPREL16_HIGHERA 98 /* half16 (sym+add)@tprel@highera */ -+#define R_PPC64_TPREL16_HIGHEST 99 /* half16 (sym+add)@tprel@highest */ -+#define R_PPC64_TPREL16_HIGHESTA 100 /* half16 (sym+add)@tprel@highesta */ -+#define R_PPC64_DTPREL16_DS 101 /* half16ds* (sym+add)@dtprel */ -+#define R_PPC64_DTPREL16_LO_DS 102 /* half16ds (sym+add)@dtprel@l */ -+#define R_PPC64_DTPREL16_HIGHER 103 /* half16 (sym+add)@dtprel@higher */ -+#define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */ -+#define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */ -+#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */ -+ -+/* GNU extension to support local ifunc. */ -+#define R_PPC64_JMP_IREL 247 -+#define R_PPC64_IRELATIVE 248 -+#define R_PPC64_REL16 249 /* half16 (sym+add-.) */ -+#define R_PPC64_REL16_LO 250 /* half16 (sym+add-.)@l */ -+#define R_PPC64_REL16_HI 251 /* half16 (sym+add-.)@h */ -+#define R_PPC64_REL16_HA 252 /* half16 (sym+add-.)@ha */ -+ -+/* PowerPC64 specific values for the Dyn d_tag field. */ -+#define DT_PPC64_GLINK (DT_LOPROC + 0) -+#define DT_PPC64_OPD (DT_LOPROC + 1) -+#define DT_PPC64_OPDSZ (DT_LOPROC + 2) -+#define DT_PPC64_NUM 3 -+ -+ -+/* ARM specific declarations */ -+ -+/* Processor specific flags for the ELF header e_flags field. */ -+#define EF_ARM_RELEXEC 0x01 -+#define EF_ARM_HASENTRY 0x02 -+#define EF_ARM_INTERWORK 0x04 -+#define EF_ARM_APCS_26 0x08 -+#define EF_ARM_APCS_FLOAT 0x10 -+#define EF_ARM_PIC 0x20 -+#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */ -+#define EF_ARM_NEW_ABI 0x80 -+#define EF_ARM_OLD_ABI 0x100 -+#define EF_ARM_SOFT_FLOAT 0x200 -+#define EF_ARM_VFP_FLOAT 0x400 -+#define EF_ARM_MAVERICK_FLOAT 0x800 -+ -+ -+/* Other constants defined in the ARM ELF spec. version B-01. */ -+/* NB. These conflict with values defined above. */ -+#define EF_ARM_SYMSARESORTED 0x04 -+#define EF_ARM_DYNSYMSUSESEGIDX 0x08 -+#define EF_ARM_MAPSYMSFIRST 0x10 -+#define EF_ARM_EABIMASK 0XFF000000 -+ -+/* Constants defined in AAELF. */ -+#define EF_ARM_BE8 0x00800000 -+#define EF_ARM_LE8 0x00400000 -+ -+#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK) -+#define EF_ARM_EABI_UNKNOWN 0x00000000 -+#define EF_ARM_EABI_VER1 0x01000000 -+#define EF_ARM_EABI_VER2 0x02000000 -+#define EF_ARM_EABI_VER3 0x03000000 -+#define EF_ARM_EABI_VER4 0x04000000 -+#define EF_ARM_EABI_VER5 0x05000000 -+ -+/* Additional symbol types for Thumb. */ -+#define STT_ARM_TFUNC STT_LOPROC /* A Thumb function. */ -+#define STT_ARM_16BIT STT_HIPROC /* A Thumb label. */ -+ -+/* ARM-specific values for sh_flags */ -+#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */ -+#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined -+ in the input to a link step. */ -+ -+/* ARM-specific program header flags */ -+#define PF_ARM_SB 0x10000000 /* Segment contains the location -+ addressed by the static base. */ -+#define PF_ARM_PI 0x20000000 /* Position-independent segment. */ -+#define PF_ARM_ABS 0x40000000 /* Absolute segment. */ -+ -+/* Processor specific values for the Phdr p_type field. */ -+#define PT_ARM_EXIDX (PT_LOPROC + 1) /* ARM unwind segment. */ -+ -+/* Processor specific values for the Shdr sh_type field. */ -+#define SHT_ARM_EXIDX (SHT_LOPROC + 1) /* ARM unwind section. */ -+#define SHT_ARM_PREEMPTMAP (SHT_LOPROC + 2) /* Preemption details. */ -+#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3) /* ARM attributes section. */ -+ -+ -+/* ARM relocs. */ -+ -+#define R_ARM_NONE 0 /* No reloc */ -+#define R_ARM_PC24 1 /* PC relative 26 bit branch */ -+#define R_ARM_ABS32 2 /* Direct 32 bit */ -+#define R_ARM_REL32 3 /* PC relative 32 bit */ -+#define R_ARM_PC13 4 -+#define R_ARM_ABS16 5 /* Direct 16 bit */ -+#define R_ARM_ABS12 6 /* Direct 12 bit */ -+#define R_ARM_THM_ABS5 7 -+#define R_ARM_ABS8 8 /* Direct 8 bit */ -+#define R_ARM_SBREL32 9 -+#define R_ARM_THM_PC22 10 -+#define R_ARM_THM_PC8 11 -+#define R_ARM_AMP_VCALL9 12 -+#define R_ARM_SWI24 13 /* Obsolete static relocation. */ -+#define R_ARM_TLS_DESC 13 /* Dynamic relocation. */ -+#define R_ARM_THM_SWI8 14 -+#define R_ARM_XPC25 15 -+#define R_ARM_THM_XPC22 16 -+#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */ -+#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */ -+#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */ -+#define R_ARM_COPY 20 /* Copy symbol at runtime */ -+#define R_ARM_GLOB_DAT 21 /* Create GOT entry */ -+#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */ -+#define R_ARM_RELATIVE 23 /* Adjust by program base */ -+#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */ -+#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */ -+#define R_ARM_GOT32 26 /* 32 bit GOT entry */ -+#define R_ARM_PLT32 27 /* 32 bit PLT address */ -+#define R_ARM_ALU_PCREL_7_0 32 -+#define R_ARM_ALU_PCREL_15_8 33 -+#define R_ARM_ALU_PCREL_23_15 34 -+#define R_ARM_LDR_SBREL_11_0 35 -+#define R_ARM_ALU_SBREL_19_12 36 -+#define R_ARM_ALU_SBREL_27_20 37 -+#define R_ARM_TLS_GOTDESC 90 -+#define R_ARM_TLS_CALL 91 -+#define R_ARM_TLS_DESCSEQ 92 -+#define R_ARM_THM_TLS_CALL 93 -+#define R_ARM_GNU_VTENTRY 100 -+#define R_ARM_GNU_VTINHERIT 101 -+#define R_ARM_THM_PC11 102 /* thumb unconditional branch */ -+#define R_ARM_THM_PC9 103 /* thumb conditional branch */ -+#define R_ARM_TLS_GD32 104 /* PC-rel 32 bit for global dynamic -+ thread local data */ -+#define R_ARM_TLS_LDM32 105 /* PC-rel 32 bit for local dynamic -+ thread local data */ -+#define R_ARM_TLS_LDO32 106 /* 32 bit offset relative to TLS -+ block */ -+#define R_ARM_TLS_IE32 107 /* PC-rel 32 bit for GOT entry of -+ static TLS block offset */ -+#define R_ARM_TLS_LE32 108 /* 32 bit offset relative to static -+ TLS block */ -+#define R_ARM_THM_TLS_DESCSEQ 129 -+#define R_ARM_IRELATIVE 160 -+#define R_ARM_RXPC25 249 -+#define R_ARM_RSBREL32 250 -+#define R_ARM_THM_RPC22 251 -+#define R_ARM_RREL32 252 -+#define R_ARM_RABS22 253 -+#define R_ARM_RPC24 254 -+#define R_ARM_RBASE 255 -+/* Keep this the last entry. */ -+#define R_ARM_NUM 256 -+ -+/* IA-64 specific declarations. */ -+ -+/* Processor specific flags for the Ehdr e_flags field. */ -+#define EF_IA_64_MASKOS 0x0000000f /* os-specific flags */ -+#define EF_IA_64_ABI64 0x00000010 /* 64-bit ABI */ -+#define EF_IA_64_ARCH 0xff000000 /* arch. version mask */ -+ -+/* Processor specific values for the Phdr p_type field. */ -+#define PT_IA_64_ARCHEXT (PT_LOPROC + 0) /* arch extension bits */ -+#define PT_IA_64_UNWIND (PT_LOPROC + 1) /* ia64 unwind bits */ -+#define PT_IA_64_HP_OPT_ANOT (PT_LOOS + 0x12) -+#define PT_IA_64_HP_HSL_ANOT (PT_LOOS + 0x13) -+#define PT_IA_64_HP_STACK (PT_LOOS + 0x14) -+ -+/* Processor specific flags for the Phdr p_flags field. */ -+#define PF_IA_64_NORECOV 0x80000000 /* spec insns w/o recovery */ -+ -+/* Processor specific values for the Shdr sh_type field. */ -+#define SHT_IA_64_EXT (SHT_LOPROC + 0) /* extension bits */ -+#define SHT_IA_64_UNWIND (SHT_LOPROC + 1) /* unwind bits */ -+ -+/* Processor specific flags for the Shdr sh_flags field. */ -+#define SHF_IA_64_SHORT 0x10000000 /* section near gp */ -+#define SHF_IA_64_NORECOV 0x20000000 /* spec insns w/o recovery */ -+ -+/* Processor specific values for the Dyn d_tag field. */ -+#define DT_IA_64_PLT_RESERVE (DT_LOPROC + 0) -+#define DT_IA_64_NUM 1 -+ -+/* IA-64 relocations. */ -+#define R_IA64_NONE 0x00 /* none */ -+#define R_IA64_IMM14 0x21 /* symbol + addend, add imm14 */ -+#define R_IA64_IMM22 0x22 /* symbol + addend, add imm22 */ -+#define R_IA64_IMM64 0x23 /* symbol + addend, mov imm64 */ -+#define R_IA64_DIR32MSB 0x24 /* symbol + addend, data4 MSB */ -+#define R_IA64_DIR32LSB 0x25 /* symbol + addend, data4 LSB */ -+#define R_IA64_DIR64MSB 0x26 /* symbol + addend, data8 MSB */ -+#define R_IA64_DIR64LSB 0x27 /* symbol + addend, data8 LSB */ -+#define R_IA64_GPREL22 0x2a /* @gprel(sym + add), add imm22 */ -+#define R_IA64_GPREL64I 0x2b /* @gprel(sym + add), mov imm64 */ -+#define R_IA64_GPREL32MSB 0x2c /* @gprel(sym + add), data4 MSB */ -+#define R_IA64_GPREL32LSB 0x2d /* @gprel(sym + add), data4 LSB */ -+#define R_IA64_GPREL64MSB 0x2e /* @gprel(sym + add), data8 MSB */ -+#define R_IA64_GPREL64LSB 0x2f /* @gprel(sym + add), data8 LSB */ -+#define R_IA64_LTOFF22 0x32 /* @ltoff(sym + add), add imm22 */ -+#define R_IA64_LTOFF64I 0x33 /* @ltoff(sym + add), mov imm64 */ -+#define R_IA64_PLTOFF22 0x3a /* @pltoff(sym + add), add imm22 */ -+#define R_IA64_PLTOFF64I 0x3b /* @pltoff(sym + add), mov imm64 */ -+#define R_IA64_PLTOFF64MSB 0x3e /* @pltoff(sym + add), data8 MSB */ -+#define R_IA64_PLTOFF64LSB 0x3f /* @pltoff(sym + add), data8 LSB */ -+#define R_IA64_FPTR64I 0x43 /* @fptr(sym + add), mov imm64 */ -+#define R_IA64_FPTR32MSB 0x44 /* @fptr(sym + add), data4 MSB */ -+#define R_IA64_FPTR32LSB 0x45 /* @fptr(sym + add), data4 LSB */ -+#define R_IA64_FPTR64MSB 0x46 /* @fptr(sym + add), data8 MSB */ -+#define R_IA64_FPTR64LSB 0x47 /* @fptr(sym + add), data8 LSB */ -+#define R_IA64_PCREL60B 0x48 /* @pcrel(sym + add), brl */ -+#define R_IA64_PCREL21B 0x49 /* @pcrel(sym + add), ptb, call */ -+#define R_IA64_PCREL21M 0x4a /* @pcrel(sym + add), chk.s */ -+#define R_IA64_PCREL21F 0x4b /* @pcrel(sym + add), fchkf */ -+#define R_IA64_PCREL32MSB 0x4c /* @pcrel(sym + add), data4 MSB */ -+#define R_IA64_PCREL32LSB 0x4d /* @pcrel(sym + add), data4 LSB */ -+#define R_IA64_PCREL64MSB 0x4e /* @pcrel(sym + add), data8 MSB */ -+#define R_IA64_PCREL64LSB 0x4f /* @pcrel(sym + add), data8 LSB */ -+#define R_IA64_LTOFF_FPTR22 0x52 /* @ltoff(@fptr(s+a)), imm22 */ -+#define R_IA64_LTOFF_FPTR64I 0x53 /* @ltoff(@fptr(s+a)), imm64 */ -+#define R_IA64_LTOFF_FPTR32MSB 0x54 /* @ltoff(@fptr(s+a)), data4 MSB */ -+#define R_IA64_LTOFF_FPTR32LSB 0x55 /* @ltoff(@fptr(s+a)), data4 LSB */ -+#define R_IA64_LTOFF_FPTR64MSB 0x56 /* @ltoff(@fptr(s+a)), data8 MSB */ -+#define R_IA64_LTOFF_FPTR64LSB 0x57 /* @ltoff(@fptr(s+a)), data8 LSB */ -+#define R_IA64_SEGREL32MSB 0x5c /* @segrel(sym + add), data4 MSB */ -+#define R_IA64_SEGREL32LSB 0x5d /* @segrel(sym + add), data4 LSB */ -+#define R_IA64_SEGREL64MSB 0x5e /* @segrel(sym + add), data8 MSB */ -+#define R_IA64_SEGREL64LSB 0x5f /* @segrel(sym + add), data8 LSB */ -+#define R_IA64_SECREL32MSB 0x64 /* @secrel(sym + add), data4 MSB */ -+#define R_IA64_SECREL32LSB 0x65 /* @secrel(sym + add), data4 LSB */ -+#define R_IA64_SECREL64MSB 0x66 /* @secrel(sym + add), data8 MSB */ -+#define R_IA64_SECREL64LSB 0x67 /* @secrel(sym + add), data8 LSB */ -+#define R_IA64_REL32MSB 0x6c /* data 4 + REL */ -+#define R_IA64_REL32LSB 0x6d /* data 4 + REL */ -+#define R_IA64_REL64MSB 0x6e /* data 8 + REL */ -+#define R_IA64_REL64LSB 0x6f /* data 8 + REL */ -+#define R_IA64_LTV32MSB 0x74 /* symbol + addend, data4 MSB */ -+#define R_IA64_LTV32LSB 0x75 /* symbol + addend, data4 LSB */ -+#define R_IA64_LTV64MSB 0x76 /* symbol + addend, data8 MSB */ -+#define R_IA64_LTV64LSB 0x77 /* symbol + addend, data8 LSB */ -+#define R_IA64_PCREL21BI 0x79 /* @pcrel(sym + add), 21bit inst */ -+#define R_IA64_PCREL22 0x7a /* @pcrel(sym + add), 22bit inst */ -+#define R_IA64_PCREL64I 0x7b /* @pcrel(sym + add), 64bit inst */ -+#define R_IA64_IPLTMSB 0x80 /* dynamic reloc, imported PLT, MSB */ -+#define R_IA64_IPLTLSB 0x81 /* dynamic reloc, imported PLT, LSB */ -+#define R_IA64_COPY 0x84 /* copy relocation */ -+#define R_IA64_SUB 0x85 /* Addend and symbol difference */ -+#define R_IA64_LTOFF22X 0x86 /* LTOFF22, relaxable. */ -+#define R_IA64_LDXMOV 0x87 /* Use of LTOFF22X. */ -+#define R_IA64_TPREL14 0x91 /* @tprel(sym + add), imm14 */ -+#define R_IA64_TPREL22 0x92 /* @tprel(sym + add), imm22 */ -+#define R_IA64_TPREL64I 0x93 /* @tprel(sym + add), imm64 */ -+#define R_IA64_TPREL64MSB 0x96 /* @tprel(sym + add), data8 MSB */ -+#define R_IA64_TPREL64LSB 0x97 /* @tprel(sym + add), data8 LSB */ -+#define R_IA64_LTOFF_TPREL22 0x9a /* @ltoff(@tprel(s+a)), imm2 */ -+#define R_IA64_DTPMOD64MSB 0xa6 /* @dtpmod(sym + add), data8 MSB */ -+#define R_IA64_DTPMOD64LSB 0xa7 /* @dtpmod(sym + add), data8 LSB */ -+#define R_IA64_LTOFF_DTPMOD22 0xaa /* @ltoff(@dtpmod(sym + add)), imm22 */ -+#define R_IA64_DTPREL14 0xb1 /* @dtprel(sym + add), imm14 */ -+#define R_IA64_DTPREL22 0xb2 /* @dtprel(sym + add), imm22 */ -+#define R_IA64_DTPREL64I 0xb3 /* @dtprel(sym + add), imm64 */ -+#define R_IA64_DTPREL32MSB 0xb4 /* @dtprel(sym + add), data4 MSB */ -+#define R_IA64_DTPREL32LSB 0xb5 /* @dtprel(sym + add), data4 LSB */ -+#define R_IA64_DTPREL64MSB 0xb6 /* @dtprel(sym + add), data8 MSB */ -+#define R_IA64_DTPREL64LSB 0xb7 /* @dtprel(sym + add), data8 LSB */ -+#define R_IA64_LTOFF_DTPREL22 0xba /* @ltoff(@dtprel(s+a)), imm22 */ -+ -+/* SH specific declarations */ -+ -+/* Processor specific flags for the ELF header e_flags field. */ -+#define EF_SH_MACH_MASK 0x1f -+#define EF_SH_UNKNOWN 0x0 -+#define EF_SH1 0x1 -+#define EF_SH2 0x2 -+#define EF_SH3 0x3 -+#define EF_SH_DSP 0x4 -+#define EF_SH3_DSP 0x5 -+#define EF_SH4AL_DSP 0x6 -+#define EF_SH3E 0x8 -+#define EF_SH4 0x9 -+#define EF_SH2E 0xb -+#define EF_SH4A 0xc -+#define EF_SH2A 0xd -+#define EF_SH4_NOFPU 0x10 -+#define EF_SH4A_NOFPU 0x11 -+#define EF_SH4_NOMMU_NOFPU 0x12 -+#define EF_SH2A_NOFPU 0x13 -+#define EF_SH3_NOMMU 0x14 -+#define EF_SH2A_SH4_NOFPU 0x15 -+#define EF_SH2A_SH3_NOFPU 0x16 -+#define EF_SH2A_SH4 0x17 -+#define EF_SH2A_SH3E 0x18 -+ -+/* SH relocs. */ -+#define R_SH_NONE 0 -+#define R_SH_DIR32 1 -+#define R_SH_REL32 2 -+#define R_SH_DIR8WPN 3 -+#define R_SH_IND12W 4 -+#define R_SH_DIR8WPL 5 -+#define R_SH_DIR8WPZ 6 -+#define R_SH_DIR8BP 7 -+#define R_SH_DIR8W 8 -+#define R_SH_DIR8L 9 -+#define R_SH_SWITCH16 25 -+#define R_SH_SWITCH32 26 -+#define R_SH_USES 27 -+#define R_SH_COUNT 28 -+#define R_SH_ALIGN 29 -+#define R_SH_CODE 30 -+#define R_SH_DATA 31 -+#define R_SH_LABEL 32 -+#define R_SH_SWITCH8 33 -+#define R_SH_GNU_VTINHERIT 34 -+#define R_SH_GNU_VTENTRY 35 -+#define R_SH_TLS_GD_32 144 -+#define R_SH_TLS_LD_32 145 -+#define R_SH_TLS_LDO_32 146 -+#define R_SH_TLS_IE_32 147 -+#define R_SH_TLS_LE_32 148 -+#define R_SH_TLS_DTPMOD32 149 -+#define R_SH_TLS_DTPOFF32 150 -+#define R_SH_TLS_TPOFF32 151 -+#define R_SH_GOT32 160 -+#define R_SH_PLT32 161 -+#define R_SH_COPY 162 -+#define R_SH_GLOB_DAT 163 -+#define R_SH_JMP_SLOT 164 -+#define R_SH_RELATIVE 165 -+#define R_SH_GOTOFF 166 -+#define R_SH_GOTPC 167 -+/* Keep this the last entry. */ -+#define R_SH_NUM 256 -+ -+/* S/390 specific definitions. */ -+ -+/* Valid values for the e_flags field. */ -+ -+#define EF_S390_HIGH_GPRS 0x00000001 /* High GPRs kernel facility needed. */ -+ -+/* Additional s390 relocs */ -+ -+#define R_390_NONE 0 /* No reloc. */ -+#define R_390_8 1 /* Direct 8 bit. */ -+#define R_390_12 2 /* Direct 12 bit. */ -+#define R_390_16 3 /* Direct 16 bit. */ -+#define R_390_32 4 /* Direct 32 bit. */ -+#define R_390_PC32 5 /* PC relative 32 bit. */ -+#define R_390_GOT12 6 /* 12 bit GOT offset. */ -+#define R_390_GOT32 7 /* 32 bit GOT offset. */ -+#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */ -+#define R_390_COPY 9 /* Copy symbol at runtime. */ -+#define R_390_GLOB_DAT 10 /* Create GOT entry. */ -+#define R_390_JMP_SLOT 11 /* Create PLT entry. */ -+#define R_390_RELATIVE 12 /* Adjust by program base. */ -+#define R_390_GOTOFF32 13 /* 32 bit offset to GOT. */ -+#define R_390_GOTPC 14 /* 32 bit PC relative offset to GOT. */ -+#define R_390_GOT16 15 /* 16 bit GOT offset. */ -+#define R_390_PC16 16 /* PC relative 16 bit. */ -+#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */ -+#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */ -+#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */ -+#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */ -+#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */ -+#define R_390_64 22 /* Direct 64 bit. */ -+#define R_390_PC64 23 /* PC relative 64 bit. */ -+#define R_390_GOT64 24 /* 64 bit GOT offset. */ -+#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */ -+#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */ -+#define R_390_GOTOFF16 27 /* 16 bit offset to GOT. */ -+#define R_390_GOTOFF64 28 /* 64 bit offset to GOT. */ -+#define R_390_GOTPLT12 29 /* 12 bit offset to jump slot. */ -+#define R_390_GOTPLT16 30 /* 16 bit offset to jump slot. */ -+#define R_390_GOTPLT32 31 /* 32 bit offset to jump slot. */ -+#define R_390_GOTPLT64 32 /* 64 bit offset to jump slot. */ -+#define R_390_GOTPLTENT 33 /* 32 bit rel. offset to jump slot. */ -+#define R_390_PLTOFF16 34 /* 16 bit offset from GOT to PLT. */ -+#define R_390_PLTOFF32 35 /* 32 bit offset from GOT to PLT. */ -+#define R_390_PLTOFF64 36 /* 16 bit offset from GOT to PLT. */ -+#define R_390_TLS_LOAD 37 /* Tag for load insn in TLS code. */ -+#define R_390_TLS_GDCALL 38 /* Tag for function call in general -+ dynamic TLS code. */ -+#define R_390_TLS_LDCALL 39 /* Tag for function call in local -+ dynamic TLS code. */ -+#define R_390_TLS_GD32 40 /* Direct 32 bit for general dynamic -+ thread local data. */ -+#define R_390_TLS_GD64 41 /* Direct 64 bit for general dynamic -+ thread local data. */ -+#define R_390_TLS_GOTIE12 42 /* 12 bit GOT offset for static TLS -+ block offset. */ -+#define R_390_TLS_GOTIE32 43 /* 32 bit GOT offset for static TLS -+ block offset. */ -+#define R_390_TLS_GOTIE64 44 /* 64 bit GOT offset for static TLS -+ block offset. */ -+#define R_390_TLS_LDM32 45 /* Direct 32 bit for local dynamic -+ thread local data in LE code. */ -+#define R_390_TLS_LDM64 46 /* Direct 64 bit for local dynamic -+ thread local data in LE code. */ -+#define R_390_TLS_IE32 47 /* 32 bit address of GOT entry for -+ negated static TLS block offset. */ -+#define R_390_TLS_IE64 48 /* 64 bit address of GOT entry for -+ negated static TLS block offset. */ -+#define R_390_TLS_IEENT 49 /* 32 bit rel. offset to GOT entry for -+ negated static TLS block offset. */ -+#define R_390_TLS_LE32 50 /* 32 bit negated offset relative to -+ static TLS block. */ -+#define R_390_TLS_LE64 51 /* 64 bit negated offset relative to -+ static TLS block. */ -+#define R_390_TLS_LDO32 52 /* 32 bit offset relative to TLS -+ block. */ -+#define R_390_TLS_LDO64 53 /* 64 bit offset relative to TLS -+ block. */ -+#define R_390_TLS_DTPMOD 54 /* ID of module containing symbol. */ -+#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */ -+#define R_390_TLS_TPOFF 56 /* Negated offset in static TLS -+ block. */ -+#define R_390_20 57 /* Direct 20 bit. */ -+#define R_390_GOT20 58 /* 20 bit GOT offset. */ -+#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */ -+#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS -+ block offset. */ -+#define R_390_IRELATIVE 61 /* STT_GNU_IFUNC relocation. */ -+/* Keep this the last entry. */ -+#define R_390_NUM 62 -+ -+ -+/* CRIS relocations. */ -+#define R_CRIS_NONE 0 -+#define R_CRIS_8 1 -+#define R_CRIS_16 2 -+#define R_CRIS_32 3 -+#define R_CRIS_8_PCREL 4 -+#define R_CRIS_16_PCREL 5 -+#define R_CRIS_32_PCREL 6 -+#define R_CRIS_GNU_VTINHERIT 7 -+#define R_CRIS_GNU_VTENTRY 8 -+#define R_CRIS_COPY 9 -+#define R_CRIS_GLOB_DAT 10 -+#define R_CRIS_JUMP_SLOT 11 -+#define R_CRIS_RELATIVE 12 -+#define R_CRIS_16_GOT 13 -+#define R_CRIS_32_GOT 14 -+#define R_CRIS_16_GOTPLT 15 -+#define R_CRIS_32_GOTPLT 16 -+#define R_CRIS_32_GOTREL 17 -+#define R_CRIS_32_PLT_GOTREL 18 -+#define R_CRIS_32_PLT_PCREL 19 -+ -+#define R_CRIS_NUM 20 -+ -+ -+/* AMD x86-64 relocations. */ -+#define R_X86_64_NONE 0 /* No reloc */ -+#define R_X86_64_64 1 /* Direct 64 bit */ -+#define R_X86_64_PC32 2 /* PC relative 32 bit signed */ -+#define R_X86_64_GOT32 3 /* 32 bit GOT entry */ -+#define R_X86_64_PLT32 4 /* 32 bit PLT address */ -+#define R_X86_64_COPY 5 /* Copy symbol at runtime */ -+#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ -+#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ -+#define R_X86_64_RELATIVE 8 /* Adjust by program base */ -+#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative -+ offset to GOT */ -+#define R_X86_64_32 10 /* Direct 32 bit zero extended */ -+#define R_X86_64_32S 11 /* Direct 32 bit sign extended */ -+#define R_X86_64_16 12 /* Direct 16 bit zero extended */ -+#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ -+#define R_X86_64_8 14 /* Direct 8 bit sign extended */ -+#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ -+#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ -+#define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block */ -+#define R_X86_64_TPOFF64 18 /* Offset in initial TLS block */ -+#define R_X86_64_TLSGD 19 /* 32 bit signed PC relative offset -+ to two GOT entries for GD symbol */ -+#define R_X86_64_TLSLD 20 /* 32 bit signed PC relative offset -+ to two GOT entries for LD symbol */ -+#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ -+#define R_X86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset -+ to GOT entry for IE symbol */ -+#define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */ -+#define R_X86_64_PC64 24 /* PC relative 64 bit */ -+#define R_X86_64_GOTOFF64 25 /* 64 bit offset to GOT */ -+#define R_X86_64_GOTPC32 26 /* 32 bit signed pc relative -+ offset to GOT */ -+#define R_X86_64_GOT64 27 /* 64-bit GOT entry offset */ -+#define R_X86_64_GOTPCREL64 28 /* 64-bit PC relative offset -+ to GOT entry */ -+#define R_X86_64_GOTPC64 29 /* 64-bit PC relative offset to GOT */ -+#define R_X86_64_GOTPLT64 30 /* like GOT64, says PLT entry needed */ -+#define R_X86_64_PLTOFF64 31 /* 64-bit GOT relative offset -+ to PLT entry */ -+#define R_X86_64_SIZE32 32 /* Size of symbol plus 32-bit addend */ -+#define R_X86_64_SIZE64 33 /* Size of symbol plus 64-bit addend */ -+#define R_X86_64_GOTPC32_TLSDESC 34 /* GOT offset for TLS descriptor. */ -+#define R_X86_64_TLSDESC_CALL 35 /* Marker for call through TLS -+ descriptor. */ -+#define R_X86_64_TLSDESC 36 /* TLS descriptor. */ -+#define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base */ -+#define R_X86_64_RELATIVE64 38 /* 64-bit adjust by program base */ -+ -+#define R_X86_64_NUM 39 -+ -+ -+/* AM33 relocations. */ -+#define R_MN10300_NONE 0 /* No reloc. */ -+#define R_MN10300_32 1 /* Direct 32 bit. */ -+#define R_MN10300_16 2 /* Direct 16 bit. */ -+#define R_MN10300_8 3 /* Direct 8 bit. */ -+#define R_MN10300_PCREL32 4 /* PC-relative 32-bit. */ -+#define R_MN10300_PCREL16 5 /* PC-relative 16-bit signed. */ -+#define R_MN10300_PCREL8 6 /* PC-relative 8-bit signed. */ -+#define R_MN10300_GNU_VTINHERIT 7 /* Ancient C++ vtable garbage... */ -+#define R_MN10300_GNU_VTENTRY 8 /* ... collection annotation. */ -+#define R_MN10300_24 9 /* Direct 24 bit. */ -+#define R_MN10300_GOTPC32 10 /* 32-bit PCrel offset to GOT. */ -+#define R_MN10300_GOTPC16 11 /* 16-bit PCrel offset to GOT. */ -+#define R_MN10300_GOTOFF32 12 /* 32-bit offset from GOT. */ -+#define R_MN10300_GOTOFF24 13 /* 24-bit offset from GOT. */ -+#define R_MN10300_GOTOFF16 14 /* 16-bit offset from GOT. */ -+#define R_MN10300_PLT32 15 /* 32-bit PCrel to PLT entry. */ -+#define R_MN10300_PLT16 16 /* 16-bit PCrel to PLT entry. */ -+#define R_MN10300_GOT32 17 /* 32-bit offset to GOT entry. */ -+#define R_MN10300_GOT24 18 /* 24-bit offset to GOT entry. */ -+#define R_MN10300_GOT16 19 /* 16-bit offset to GOT entry. */ -+#define R_MN10300_COPY 20 /* Copy symbol at runtime. */ -+#define R_MN10300_GLOB_DAT 21 /* Create GOT entry. */ -+#define R_MN10300_JMP_SLOT 22 /* Create PLT entry. */ -+#define R_MN10300_RELATIVE 23 /* Adjust by program base. */ -+ -+#define R_MN10300_NUM 24 -+ -+ -+/* M32R relocs. */ -+#define R_M32R_NONE 0 /* No reloc. */ -+#define R_M32R_16 1 /* Direct 16 bit. */ -+#define R_M32R_32 2 /* Direct 32 bit. */ -+#define R_M32R_24 3 /* Direct 24 bit. */ -+#define R_M32R_10_PCREL 4 /* PC relative 10 bit shifted. */ -+#define R_M32R_18_PCREL 5 /* PC relative 18 bit shifted. */ -+#define R_M32R_26_PCREL 6 /* PC relative 26 bit shifted. */ -+#define R_M32R_HI16_ULO 7 /* High 16 bit with unsigned low. */ -+#define R_M32R_HI16_SLO 8 /* High 16 bit with signed low. */ -+#define R_M32R_LO16 9 /* Low 16 bit. */ -+#define R_M32R_SDA16 10 /* 16 bit offset in SDA. */ -+#define R_M32R_GNU_VTINHERIT 11 -+#define R_M32R_GNU_VTENTRY 12 -+/* M32R relocs use SHT_RELA. */ -+#define R_M32R_16_RELA 33 /* Direct 16 bit. */ -+#define R_M32R_32_RELA 34 /* Direct 32 bit. */ -+#define R_M32R_24_RELA 35 /* Direct 24 bit. */ -+#define R_M32R_10_PCREL_RELA 36 /* PC relative 10 bit shifted. */ -+#define R_M32R_18_PCREL_RELA 37 /* PC relative 18 bit shifted. */ -+#define R_M32R_26_PCREL_RELA 38 /* PC relative 26 bit shifted. */ -+#define R_M32R_HI16_ULO_RELA 39 /* High 16 bit with unsigned low */ -+#define R_M32R_HI16_SLO_RELA 40 /* High 16 bit with signed low */ -+#define R_M32R_LO16_RELA 41 /* Low 16 bit */ -+#define R_M32R_SDA16_RELA 42 /* 16 bit offset in SDA */ -+#define R_M32R_RELA_GNU_VTINHERIT 43 -+#define R_M32R_RELA_GNU_VTENTRY 44 -+#define R_M32R_REL32 45 /* PC relative 32 bit. */ -+ -+#define R_M32R_GOT24 48 /* 24 bit GOT entry */ -+#define R_M32R_26_PLTREL 49 /* 26 bit PC relative to PLT shifted */ -+#define R_M32R_COPY 50 /* Copy symbol at runtime */ -+#define R_M32R_GLOB_DAT 51 /* Create GOT entry */ -+#define R_M32R_JMP_SLOT 52 /* Create PLT entry */ -+#define R_M32R_RELATIVE 53 /* Adjust by program base */ -+#define R_M32R_GOTOFF 54 /* 24 bit offset to GOT */ -+#define R_M32R_GOTPC24 55 /* 24 bit PC relative offset to GOT */ -+#define R_M32R_GOT16_HI_ULO 56 /* High 16 bit GOT entry with unsigned -+ low */ -+#define R_M32R_GOT16_HI_SLO 57 /* High 16 bit GOT entry with signed -+ low */ -+#define R_M32R_GOT16_LO 58 /* Low 16 bit GOT entry */ -+#define R_M32R_GOTPC_HI_ULO 59 /* High 16 bit PC relative offset to -+ GOT with unsigned low */ -+#define R_M32R_GOTPC_HI_SLO 60 /* High 16 bit PC relative offset to -+ GOT with signed low */ -+#define R_M32R_GOTPC_LO 61 /* Low 16 bit PC relative offset to -+ GOT */ -+#define R_M32R_GOTOFF_HI_ULO 62 /* High 16 bit offset to GOT -+ with unsigned low */ -+#define R_M32R_GOTOFF_HI_SLO 63 /* High 16 bit offset to GOT -+ with signed low */ -+#define R_M32R_GOTOFF_LO 64 /* Low 16 bit offset to GOT */ -+#define R_M32R_NUM 256 /* Keep this the last entry. */ -+ -+ -+/* TILEPro relocations. */ -+#define R_TILEPRO_NONE 0 /* No reloc */ -+#define R_TILEPRO_32 1 /* Direct 32 bit */ -+#define R_TILEPRO_16 2 /* Direct 16 bit */ -+#define R_TILEPRO_8 3 /* Direct 8 bit */ -+#define R_TILEPRO_32_PCREL 4 /* PC relative 32 bit */ -+#define R_TILEPRO_16_PCREL 5 /* PC relative 16 bit */ -+#define R_TILEPRO_8_PCREL 6 /* PC relative 8 bit */ -+#define R_TILEPRO_LO16 7 /* Low 16 bit */ -+#define R_TILEPRO_HI16 8 /* High 16 bit */ -+#define R_TILEPRO_HA16 9 /* High 16 bit, adjusted */ -+#define R_TILEPRO_COPY 10 /* Copy relocation */ -+#define R_TILEPRO_GLOB_DAT 11 /* Create GOT entry */ -+#define R_TILEPRO_JMP_SLOT 12 /* Create PLT entry */ -+#define R_TILEPRO_RELATIVE 13 /* Adjust by program base */ -+#define R_TILEPRO_BROFF_X1 14 /* X1 pipe branch offset */ -+#define R_TILEPRO_JOFFLONG_X1 15 /* X1 pipe jump offset */ -+#define R_TILEPRO_JOFFLONG_X1_PLT 16 /* X1 pipe jump offset to PLT */ -+#define R_TILEPRO_IMM8_X0 17 /* X0 pipe 8-bit */ -+#define R_TILEPRO_IMM8_Y0 18 /* Y0 pipe 8-bit */ -+#define R_TILEPRO_IMM8_X1 19 /* X1 pipe 8-bit */ -+#define R_TILEPRO_IMM8_Y1 20 /* Y1 pipe 8-bit */ -+#define R_TILEPRO_MT_IMM15_X1 21 /* X1 pipe mtspr */ -+#define R_TILEPRO_MF_IMM15_X1 22 /* X1 pipe mfspr */ -+#define R_TILEPRO_IMM16_X0 23 /* X0 pipe 16-bit */ -+#define R_TILEPRO_IMM16_X1 24 /* X1 pipe 16-bit */ -+#define R_TILEPRO_IMM16_X0_LO 25 /* X0 pipe low 16-bit */ -+#define R_TILEPRO_IMM16_X1_LO 26 /* X1 pipe low 16-bit */ -+#define R_TILEPRO_IMM16_X0_HI 27 /* X0 pipe high 16-bit */ -+#define R_TILEPRO_IMM16_X1_HI 28 /* X1 pipe high 16-bit */ -+#define R_TILEPRO_IMM16_X0_HA 29 /* X0 pipe high 16-bit, adjusted */ -+#define R_TILEPRO_IMM16_X1_HA 30 /* X1 pipe high 16-bit, adjusted */ -+#define R_TILEPRO_IMM16_X0_PCREL 31 /* X0 pipe PC relative 16 bit */ -+#define R_TILEPRO_IMM16_X1_PCREL 32 /* X1 pipe PC relative 16 bit */ -+#define R_TILEPRO_IMM16_X0_LO_PCREL 33 /* X0 pipe PC relative low 16 bit */ -+#define R_TILEPRO_IMM16_X1_LO_PCREL 34 /* X1 pipe PC relative low 16 bit */ -+#define R_TILEPRO_IMM16_X0_HI_PCREL 35 /* X0 pipe PC relative high 16 bit */ -+#define R_TILEPRO_IMM16_X1_HI_PCREL 36 /* X1 pipe PC relative high 16 bit */ -+#define R_TILEPRO_IMM16_X0_HA_PCREL 37 /* X0 pipe PC relative ha() 16 bit */ -+#define R_TILEPRO_IMM16_X1_HA_PCREL 38 /* X1 pipe PC relative ha() 16 bit */ -+#define R_TILEPRO_IMM16_X0_GOT 39 /* X0 pipe 16-bit GOT offset */ -+#define R_TILEPRO_IMM16_X1_GOT 40 /* X1 pipe 16-bit GOT offset */ -+#define R_TILEPRO_IMM16_X0_GOT_LO 41 /* X0 pipe low 16-bit GOT offset */ -+#define R_TILEPRO_IMM16_X1_GOT_LO 42 /* X1 pipe low 16-bit GOT offset */ -+#define R_TILEPRO_IMM16_X0_GOT_HI 43 /* X0 pipe high 16-bit GOT offset */ -+#define R_TILEPRO_IMM16_X1_GOT_HI 44 /* X1 pipe high 16-bit GOT offset */ -+#define R_TILEPRO_IMM16_X0_GOT_HA 45 /* X0 pipe ha() 16-bit GOT offset */ -+#define R_TILEPRO_IMM16_X1_GOT_HA 46 /* X1 pipe ha() 16-bit GOT offset */ -+#define R_TILEPRO_MMSTART_X0 47 /* X0 pipe mm "start" */ -+#define R_TILEPRO_MMEND_X0 48 /* X0 pipe mm "end" */ -+#define R_TILEPRO_MMSTART_X1 49 /* X1 pipe mm "start" */ -+#define R_TILEPRO_MMEND_X1 50 /* X1 pipe mm "end" */ -+#define R_TILEPRO_SHAMT_X0 51 /* X0 pipe shift amount */ -+#define R_TILEPRO_SHAMT_X1 52 /* X1 pipe shift amount */ -+#define R_TILEPRO_SHAMT_Y0 53 /* Y0 pipe shift amount */ -+#define R_TILEPRO_SHAMT_Y1 54 /* Y1 pipe shift amount */ -+#define R_TILEPRO_DEST_IMM8_X1 55 /* X1 pipe destination 8-bit */ -+/* Relocs 56-59 are currently not defined. */ -+#define R_TILEPRO_TLS_GD_CALL 60 /* "jal" for TLS GD */ -+#define R_TILEPRO_IMM8_X0_TLS_GD_ADD 61 /* X0 pipe "addi" for TLS GD */ -+#define R_TILEPRO_IMM8_X1_TLS_GD_ADD 62 /* X1 pipe "addi" for TLS GD */ -+#define R_TILEPRO_IMM8_Y0_TLS_GD_ADD 63 /* Y0 pipe "addi" for TLS GD */ -+#define R_TILEPRO_IMM8_Y1_TLS_GD_ADD 64 /* Y1 pipe "addi" for TLS GD */ -+#define R_TILEPRO_TLS_IE_LOAD 65 /* "lw_tls" for TLS IE */ -+#define R_TILEPRO_IMM16_X0_TLS_GD 66 /* X0 pipe 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X1_TLS_GD 67 /* X1 pipe 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X0_TLS_GD_LO 68 /* X0 pipe low 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X1_TLS_GD_LO 69 /* X1 pipe low 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X0_TLS_GD_HI 70 /* X0 pipe high 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X1_TLS_GD_HI 71 /* X1 pipe high 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X0_TLS_GD_HA 72 /* X0 pipe ha() 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X1_TLS_GD_HA 73 /* X1 pipe ha() 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X0_TLS_IE 74 /* X0 pipe 16-bit TLS IE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_IE 75 /* X1 pipe 16-bit TLS IE offset */ -+#define R_TILEPRO_IMM16_X0_TLS_IE_LO 76 /* X0 pipe low 16-bit TLS IE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_IE_LO 77 /* X1 pipe low 16-bit TLS IE offset */ -+#define R_TILEPRO_IMM16_X0_TLS_IE_HI 78 /* X0 pipe high 16-bit TLS IE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_IE_HI 79 /* X1 pipe high 16-bit TLS IE offset */ -+#define R_TILEPRO_IMM16_X0_TLS_IE_HA 80 /* X0 pipe ha() 16-bit TLS IE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_IE_HA 81 /* X1 pipe ha() 16-bit TLS IE offset */ -+#define R_TILEPRO_TLS_DTPMOD32 82 /* ID of module containing symbol */ -+#define R_TILEPRO_TLS_DTPOFF32 83 /* Offset in TLS block */ -+#define R_TILEPRO_TLS_TPOFF32 84 /* Offset in static TLS block */ -+#define R_TILEPRO_IMM16_X0_TLS_LE 85 /* X0 pipe 16-bit TLS LE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_LE 86 /* X1 pipe 16-bit TLS LE offset */ -+#define R_TILEPRO_IMM16_X0_TLS_LE_LO 87 /* X0 pipe low 16-bit TLS LE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_LE_LO 88 /* X1 pipe low 16-bit TLS LE offset */ -+#define R_TILEPRO_IMM16_X0_TLS_LE_HI 89 /* X0 pipe high 16-bit TLS LE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_LE_HI 90 /* X1 pipe high 16-bit TLS LE offset */ -+#define R_TILEPRO_IMM16_X0_TLS_LE_HA 91 /* X0 pipe ha() 16-bit TLS LE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_LE_HA 92 /* X1 pipe ha() 16-bit TLS LE offset */ -+ -+#define R_TILEPRO_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */ -+#define R_TILEPRO_GNU_VTENTRY 129 /* GNU C++ vtable member usage */ -+ -+#define R_TILEPRO_NUM 130 -+ -+ -+/* TILE-Gx relocations. */ -+#define R_TILEGX_NONE 0 /* No reloc */ -+#define R_TILEGX_64 1 /* Direct 64 bit */ -+#define R_TILEGX_32 2 /* Direct 32 bit */ -+#define R_TILEGX_16 3 /* Direct 16 bit */ -+#define R_TILEGX_8 4 /* Direct 8 bit */ -+#define R_TILEGX_64_PCREL 5 /* PC relative 64 bit */ -+#define R_TILEGX_32_PCREL 6 /* PC relative 32 bit */ -+#define R_TILEGX_16_PCREL 7 /* PC relative 16 bit */ -+#define R_TILEGX_8_PCREL 8 /* PC relative 8 bit */ -+#define R_TILEGX_HW0 9 /* hword 0 16-bit */ -+#define R_TILEGX_HW1 10 /* hword 1 16-bit */ -+#define R_TILEGX_HW2 11 /* hword 2 16-bit */ -+#define R_TILEGX_HW3 12 /* hword 3 16-bit */ -+#define R_TILEGX_HW0_LAST 13 /* last hword 0 16-bit */ -+#define R_TILEGX_HW1_LAST 14 /* last hword 1 16-bit */ -+#define R_TILEGX_HW2_LAST 15 /* last hword 2 16-bit */ -+#define R_TILEGX_COPY 16 /* Copy relocation */ -+#define R_TILEGX_GLOB_DAT 17 /* Create GOT entry */ -+#define R_TILEGX_JMP_SLOT 18 /* Create PLT entry */ -+#define R_TILEGX_RELATIVE 19 /* Adjust by program base */ -+#define R_TILEGX_BROFF_X1 20 /* X1 pipe branch offset */ -+#define R_TILEGX_JUMPOFF_X1 21 /* X1 pipe jump offset */ -+#define R_TILEGX_JUMPOFF_X1_PLT 22 /* X1 pipe jump offset to PLT */ -+#define R_TILEGX_IMM8_X0 23 /* X0 pipe 8-bit */ -+#define R_TILEGX_IMM8_Y0 24 /* Y0 pipe 8-bit */ -+#define R_TILEGX_IMM8_X1 25 /* X1 pipe 8-bit */ -+#define R_TILEGX_IMM8_Y1 26 /* Y1 pipe 8-bit */ -+#define R_TILEGX_DEST_IMM8_X1 27 /* X1 pipe destination 8-bit */ -+#define R_TILEGX_MT_IMM14_X1 28 /* X1 pipe mtspr */ -+#define R_TILEGX_MF_IMM14_X1 29 /* X1 pipe mfspr */ -+#define R_TILEGX_MMSTART_X0 30 /* X0 pipe mm "start" */ -+#define R_TILEGX_MMEND_X0 31 /* X0 pipe mm "end" */ -+#define R_TILEGX_SHAMT_X0 32 /* X0 pipe shift amount */ -+#define R_TILEGX_SHAMT_X1 33 /* X1 pipe shift amount */ -+#define R_TILEGX_SHAMT_Y0 34 /* Y0 pipe shift amount */ -+#define R_TILEGX_SHAMT_Y1 35 /* Y1 pipe shift amount */ -+#define R_TILEGX_IMM16_X0_HW0 36 /* X0 pipe hword 0 */ -+#define R_TILEGX_IMM16_X1_HW0 37 /* X1 pipe hword 0 */ -+#define R_TILEGX_IMM16_X0_HW1 38 /* X0 pipe hword 1 */ -+#define R_TILEGX_IMM16_X1_HW1 39 /* X1 pipe hword 1 */ -+#define R_TILEGX_IMM16_X0_HW2 40 /* X0 pipe hword 2 */ -+#define R_TILEGX_IMM16_X1_HW2 41 /* X1 pipe hword 2 */ -+#define R_TILEGX_IMM16_X0_HW3 42 /* X0 pipe hword 3 */ -+#define R_TILEGX_IMM16_X1_HW3 43 /* X1 pipe hword 3 */ -+#define R_TILEGX_IMM16_X0_HW0_LAST 44 /* X0 pipe last hword 0 */ -+#define R_TILEGX_IMM16_X1_HW0_LAST 45 /* X1 pipe last hword 0 */ -+#define R_TILEGX_IMM16_X0_HW1_LAST 46 /* X0 pipe last hword 1 */ -+#define R_TILEGX_IMM16_X1_HW1_LAST 47 /* X1 pipe last hword 1 */ -+#define R_TILEGX_IMM16_X0_HW2_LAST 48 /* X0 pipe last hword 2 */ -+#define R_TILEGX_IMM16_X1_HW2_LAST 49 /* X1 pipe last hword 2 */ -+#define R_TILEGX_IMM16_X0_HW0_PCREL 50 /* X0 pipe PC relative hword 0 */ -+#define R_TILEGX_IMM16_X1_HW0_PCREL 51 /* X1 pipe PC relative hword 0 */ -+#define R_TILEGX_IMM16_X0_HW1_PCREL 52 /* X0 pipe PC relative hword 1 */ -+#define R_TILEGX_IMM16_X1_HW1_PCREL 53 /* X1 pipe PC relative hword 1 */ -+#define R_TILEGX_IMM16_X0_HW2_PCREL 54 /* X0 pipe PC relative hword 2 */ -+#define R_TILEGX_IMM16_X1_HW2_PCREL 55 /* X1 pipe PC relative hword 2 */ -+#define R_TILEGX_IMM16_X0_HW3_PCREL 56 /* X0 pipe PC relative hword 3 */ -+#define R_TILEGX_IMM16_X1_HW3_PCREL 57 /* X1 pipe PC relative hword 3 */ -+#define R_TILEGX_IMM16_X0_HW0_LAST_PCREL 58 /* X0 pipe PC-rel last hword 0 */ -+#define R_TILEGX_IMM16_X1_HW0_LAST_PCREL 59 /* X1 pipe PC-rel last hword 0 */ -+#define R_TILEGX_IMM16_X0_HW1_LAST_PCREL 60 /* X0 pipe PC-rel last hword 1 */ -+#define R_TILEGX_IMM16_X1_HW1_LAST_PCREL 61 /* X1 pipe PC-rel last hword 1 */ -+#define R_TILEGX_IMM16_X0_HW2_LAST_PCREL 62 /* X0 pipe PC-rel last hword 2 */ -+#define R_TILEGX_IMM16_X1_HW2_LAST_PCREL 63 /* X1 pipe PC-rel last hword 2 */ -+#define R_TILEGX_IMM16_X0_HW0_GOT 64 /* X0 pipe hword 0 GOT offset */ -+#define R_TILEGX_IMM16_X1_HW0_GOT 65 /* X1 pipe hword 0 GOT offset */ -+/* Relocs 66-71 are currently not defined. */ -+#define R_TILEGX_IMM16_X0_HW0_LAST_GOT 72 /* X0 pipe last hword 0 GOT offset */ -+#define R_TILEGX_IMM16_X1_HW0_LAST_GOT 73 /* X1 pipe last hword 0 GOT offset */ -+#define R_TILEGX_IMM16_X0_HW1_LAST_GOT 74 /* X0 pipe last hword 1 GOT offset */ -+#define R_TILEGX_IMM16_X1_HW1_LAST_GOT 75 /* X1 pipe last hword 1 GOT offset */ -+/* Relocs 76-77 are currently not defined. */ -+#define R_TILEGX_IMM16_X0_HW0_TLS_GD 78 /* X0 pipe hword 0 TLS GD offset */ -+#define R_TILEGX_IMM16_X1_HW0_TLS_GD 79 /* X1 pipe hword 0 TLS GD offset */ -+#define R_TILEGX_IMM16_X0_HW0_TLS_LE 80 /* X0 pipe hword 0 TLS LE offset */ -+#define R_TILEGX_IMM16_X1_HW0_TLS_LE 81 /* X1 pipe hword 0 TLS LE offset */ -+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 82 /* X0 pipe last hword 0 LE off */ -+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 83 /* X1 pipe last hword 0 LE off */ -+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 84 /* X0 pipe last hword 1 LE off */ -+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 85 /* X1 pipe last hword 1 LE off */ -+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 86 /* X0 pipe last hword 0 GD off */ -+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 87 /* X1 pipe last hword 0 GD off */ -+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 88 /* X0 pipe last hword 1 GD off */ -+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 89 /* X1 pipe last hword 1 GD off */ -+/* Relocs 90-91 are currently not defined. */ -+#define R_TILEGX_IMM16_X0_HW0_TLS_IE 92 /* X0 pipe hword 0 TLS IE offset */ -+#define R_TILEGX_IMM16_X1_HW0_TLS_IE 93 /* X1 pipe hword 0 TLS IE offset */ -+/* Relocs 94-99 are currently not defined. */ -+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 100 /* X0 pipe last hword 0 IE off */ -+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 101 /* X1 pipe last hword 0 IE off */ -+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 102 /* X0 pipe last hword 1 IE off */ -+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 103 /* X1 pipe last hword 1 IE off */ -+/* Relocs 104-105 are currently not defined. */ -+#define R_TILEGX_TLS_DTPMOD64 106 /* 64-bit ID of symbol's module */ -+#define R_TILEGX_TLS_DTPOFF64 107 /* 64-bit offset in TLS block */ -+#define R_TILEGX_TLS_TPOFF64 108 /* 64-bit offset in static TLS block */ -+#define R_TILEGX_TLS_DTPMOD32 109 /* 32-bit ID of symbol's module */ -+#define R_TILEGX_TLS_DTPOFF32 110 /* 32-bit offset in TLS block */ -+#define R_TILEGX_TLS_TPOFF32 111 /* 32-bit offset in static TLS block */ -+#define R_TILEGX_TLS_GD_CALL 112 /* "jal" for TLS GD */ -+#define R_TILEGX_IMM8_X0_TLS_GD_ADD 113 /* X0 pipe "addi" for TLS GD */ -+#define R_TILEGX_IMM8_X1_TLS_GD_ADD 114 /* X1 pipe "addi" for TLS GD */ -+#define R_TILEGX_IMM8_Y0_TLS_GD_ADD 115 /* Y0 pipe "addi" for TLS GD */ -+#define R_TILEGX_IMM8_Y1_TLS_GD_ADD 116 /* Y1 pipe "addi" for TLS GD */ -+#define R_TILEGX_TLS_IE_LOAD 117 /* "ld_tls" for TLS IE */ -+#define R_TILEGX_IMM8_X0_TLS_ADD 118 /* X0 pipe "addi" for TLS GD/IE */ -+#define R_TILEGX_IMM8_X1_TLS_ADD 119 /* X1 pipe "addi" for TLS GD/IE */ -+#define R_TILEGX_IMM8_Y0_TLS_ADD 120 /* Y0 pipe "addi" for TLS GD/IE */ -+#define R_TILEGX_IMM8_Y1_TLS_ADD 121 /* Y1 pipe "addi" for TLS GD/IE */ -+ -+#define R_TILEGX_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */ -+#define R_TILEGX_GNU_VTENTRY 129 /* GNU C++ vtable member usage */ -+ -+#define R_TILEGX_NUM 130 -+ -+#endif /* elf.h */ -diff --git a/scripts/mod/mk_elfconfig.c b/scripts/mod/mk_elfconfig.c -index e8cee4e4bc73..bba672c0ac8d 100644 ---- a/scripts/mod/mk_elfconfig.c -+++ b/scripts/mod/mk_elfconfig.c -@@ -2,7 +2,11 @@ - #include - #include - #include -+#ifndef __APPLE__ - #include -+#else -+#include "elf.h" -+#endif - - int - main(int argc, char **argv) -diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h -index ada3a36cc4bc..b77c2b100c1c 100644 ---- a/scripts/mod/modpost.h -+++ b/scripts/mod/modpost.h -@@ -10,7 +10,11 @@ - #include - #include - #include -+#if !(defined(__APPLE__) || defined(__CYGWIN__)) - #include -+#else -+#include "elf.h" -+#endif - #include "../../include/linux/module_symbol.h" - - #include --- -2.51.0 - - -From ce8e117a6d444db0417063bea67049d2a685dac8 Mon Sep 17 00:00:00 2001 -From: Kevin Darbyshire-Bryant -Date: Wed, 5 Feb 2020 18:36:43 +0000 -Subject: [PATCH 335/517] file2alias: build on macos - -Signed-off-by: Kevin Darbyshire-Bryant ---- - scripts/mod/file2alias.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c -index 721e0e9f17ca..70d9013cad52 100644 ---- a/scripts/mod/file2alias.c -+++ b/scripts/mod/file2alias.c -@@ -35,6 +35,9 @@ typedef uint32_t __u32; - typedef uint16_t __u16; - typedef unsigned char __u8; - -+#ifdef __APPLE__ -+#define uuid_t compat_uuid_t -+#endif - /* UUID types for backward compatibility, don't use in new code */ - typedef struct { - __u8 b[16]; --- -2.51.0 - - -From 85b0cd39287de717d1d7b9165119a1ab54d8429c Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 7 Jul 2017 17:04:08 +0200 -Subject: [PATCH 336/517] kernel: fix linux/spi/spidev.h portability issues - with musl - -Felix will try to get this define included into musl - -lede-commit: 795e7cf60de19e7a076a46874fab7bb88b43bbff -Signed-off-by: Felix Fietkau ---- - include/uapi/linux/spi/spidev.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/include/uapi/linux/spi/spidev.h b/include/uapi/linux/spi/spidev.h -index 0c3da08f2aff..2a6d51008256 100644 ---- a/include/uapi/linux/spi/spidev.h -+++ b/include/uapi/linux/spi/spidev.h -@@ -93,7 +93,7 @@ struct spi_ioc_transfer { - - /* not all platforms use or _IOC_TYPECHECK() ... */ - #define SPI_MSGSIZE(N) \ -- ((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << _IOC_SIZEBITS)) \ -+ ((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << 13)) \ - ? ((N)*(sizeof (struct spi_ioc_transfer))) : 0) - #define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)]) - --- -2.51.0 - - -From e29ddf5fd71094fc52c65223084759947c6bd3a3 Mon Sep 17 00:00:00 2001 -From: Imre Kaloz -Date: Fri, 7 Jul 2017 17:06:55 +0200 -Subject: [PATCH 337/517] use the openwrt lzma options for now - -lede-commit: 548de949f392049420a6a1feeef118b30ab8ea8c -Signed-off-by: Imre Kaloz ---- - lib/decompress.c | 1 + - scripts/Makefile.lib | 4 ++-- - 2 files changed, 3 insertions(+), 2 deletions(-) - -diff --git a/lib/decompress.c b/lib/decompress.c -index ab3fc90ffc64..b9c1e51e4ebb 100644 ---- a/lib/decompress.c -+++ b/lib/decompress.c -@@ -53,6 +53,7 @@ static const struct compress_format compressed_formats[] __initconst = { - { {0x1f, 0x9e}, "gzip", gunzip }, - { {0x42, 0x5a}, "bzip2", bunzip2 }, - { {0x5d, 0x00}, "lzma", unlzma }, -+ { {0x6d, 0x00}, "lzma-openwrt", unlzma }, - { {0xfd, 0x37}, "xz", unxz }, - { {0x89, 0x4c}, "lzo", unlzo }, - { {0x02, 0x21}, "lz4", unlz4 }, -diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib -index 85e41c68c2c5..cc6992a801a7 100644 ---- a/scripts/Makefile.lib -+++ b/scripts/Makefile.lib -@@ -359,10 +359,10 @@ quiet_cmd_bzip2_with_size = BZIP2 $@ - # --------------------------------------------------------------------------- - - quiet_cmd_lzma = LZMA $@ -- cmd_lzma = cat $(real-prereqs) | $(LZMA) -9 > $@ -+ cmd_lzma = cat $(real-prereqs) | $(LZMA) e -d20 -lc1 -lp2 -pb2 -eos -si -so > $@ - - quiet_cmd_lzma_with_size = LZMA $@ -- cmd_lzma_with_size = { cat $(real-prereqs) | $(LZMA) -9; $(size_append); } > $@ -+ cmd_lzma_with_size = { cat $(real-prereqs) | $(LZMA) e -d20 -lc1 -lp2 -pb2 -eos -si -so; $(size_append); } > $@ - - quiet_cmd_lzo = LZO $@ - cmd_lzo = cat $(real-prereqs) | $(KLZOP) -9 > $@ --- -2.51.0 - - -From c6d1cf47863c85f7ae9be28da8fac7c491fe4ecd Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Mon, 3 Nov 2025 15:50:16 +0100 -Subject: [PATCH 338/517] hack: net: remove bogus netfilter dependencies - -lede-commit: 589d2a377dee27d206fc3725325309cf649e4df6 -Signed-off-by: Felix Fietkau ---- - net/netfilter/Kconfig | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig -index df2dc21304ef..f7cde787a680 100644 ---- a/net/netfilter/Kconfig -+++ b/net/netfilter/Kconfig -@@ -259,7 +259,6 @@ config NF_CONNTRACK_FTP - - config NF_CONNTRACK_H323 - tristate "H.323 protocol support" -- depends on IPV6 || IPV6=n - depends on NETFILTER_ADVANCED - help - H.323 is a VoIP signalling protocol from ITU-T. As one of the most -@@ -1120,7 +1119,6 @@ config NETFILTER_XT_TARGET_SECMARK - - config NETFILTER_XT_TARGET_TCPMSS - tristate '"TCPMSS" target support' -- depends on IPV6 || IPV6=n - default m if NETFILTER_ADVANCED=n - help - This option adds a `TCPMSS' target, which allows you to alter the --- -2.51.0 - - -From d3f50001d74545ae24daed6e79a96c24cb8823ac Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Fri, 7 Jul 2017 17:09:21 +0200 -Subject: [PATCH 339/517] kconfig: owrt specifc dependencies - -Signed-off-by: John Crispin ---- - crypto/Kconfig | 10 +++++----- - drivers/bcma/Kconfig | 1 + - drivers/ssb/Kconfig | 3 ++- - lib/Kconfig | 8 ++++---- - net/Kconfig | 2 +- - net/netfilter/Kconfig | 2 +- - sound/core/Kconfig | 4 ++-- - 7 files changed, 16 insertions(+), 14 deletions(-) - -diff --git a/crypto/Kconfig b/crypto/Kconfig -index e7528986e94f..79fc693086b7 100644 ---- a/crypto/Kconfig -+++ b/crypto/Kconfig -@@ -55,7 +55,7 @@ config CRYPTO_FIPS_VERSION - By default the KERNELRELEASE value is used. - - config CRYPTO_ALGAPI -- tristate -+ tristate "ALGAPI" - select CRYPTO_ALGAPI2 - help - This option provides the API for cryptographic algorithms. -@@ -64,7 +64,7 @@ config CRYPTO_ALGAPI2 - tristate - - config CRYPTO_AEAD -- tristate -+ tristate "AEAD" - select CRYPTO_AEAD2 - select CRYPTO_ALGAPI - -@@ -82,7 +82,7 @@ config CRYPTO_SIG2 - select CRYPTO_ALGAPI2 - - config CRYPTO_SKCIPHER -- tristate -+ tristate "SKCIPHER" - select CRYPTO_SKCIPHER2 - select CRYPTO_ALGAPI - select CRYPTO_ECB -@@ -92,7 +92,7 @@ config CRYPTO_SKCIPHER2 - select CRYPTO_ALGAPI2 - - config CRYPTO_HASH -- tristate -+ tristate "HASH" - select CRYPTO_HASH2 - select CRYPTO_ALGAPI - -@@ -101,7 +101,7 @@ config CRYPTO_HASH2 - select CRYPTO_ALGAPI2 - - config CRYPTO_RNG -- tristate -+ tristate "RNG" - select CRYPTO_RNG2 - select CRYPTO_ALGAPI - -diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig -index b9558ff20830..2e9732e5c565 100644 ---- a/drivers/bcma/Kconfig -+++ b/drivers/bcma/Kconfig -@@ -16,6 +16,7 @@ if BCMA - # Support for Block-I/O. SELECT this from the driver that needs it. - config BCMA_BLOCKIO - bool -+ default y - - config BCMA_HOST_PCI_POSSIBLE - bool -diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig -index 1cf1a98952fa..2bcf62e64f6f 100644 ---- a/drivers/ssb/Kconfig -+++ b/drivers/ssb/Kconfig -@@ -29,6 +29,7 @@ config SSB_SPROM - config SSB_BLOCKIO - bool - depends on SSB -+ default y - - config SSB_PCIHOST_POSSIBLE - bool -@@ -49,7 +50,7 @@ config SSB_PCIHOST - config SSB_B43_PCI_BRIDGE - bool - depends on SSB_PCIHOST -- default n -+ default y - - config SSB_PCMCIAHOST_POSSIBLE - bool -diff --git a/lib/Kconfig b/lib/Kconfig -index e9088bd10a6c..1ddb823c425e 100644 ---- a/lib/Kconfig -+++ b/lib/Kconfig -@@ -457,16 +457,16 @@ config BCH_CONST_T - # Textsearch support is select'ed if needed - # - config TEXTSEARCH -- bool -+ bool "Textsearch support" - - config TEXTSEARCH_KMP -- tristate -+ tristate "Textsearch KMP" - - config TEXTSEARCH_BM -- tristate -+ tristate "Textsearch BM" - - config TEXTSEARCH_FSM -- tristate -+ tristate "Textsearch FSM" - - config BTREE - bool -diff --git a/net/Kconfig b/net/Kconfig -index a629f92dc86b..6744f55d9683 100644 ---- a/net/Kconfig -+++ b/net/Kconfig -@@ -484,7 +484,7 @@ config NET_DEVLINK - default n - - config PAGE_POOL -- bool -+ bool "Page pool support" - - config PAGE_POOL_STATS - default n -diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig -index f7cde787a680..944a47d0e2fd 100644 ---- a/net/netfilter/Kconfig -+++ b/net/netfilter/Kconfig -@@ -22,7 +22,7 @@ config NETFILTER_SKIP_EGRESS - def_bool NETFILTER_EGRESS && (NET_CLS_ACT || IFB) - - config NETFILTER_NETLINK -- tristate -+ tristate "Netfilter NFNETLINK interface" - - config NETFILTER_FAMILY_BRIDGE - bool -diff --git a/sound/core/Kconfig b/sound/core/Kconfig -index 2c5b9f964703..e2e942179a09 100644 ---- a/sound/core/Kconfig -+++ b/sound/core/Kconfig -@@ -17,7 +17,7 @@ config SND_DMAENGINE_PCM - tristate - - config SND_HWDEP -- tristate -+ tristate "Sound hardware support" - - config SND_SEQ_DEVICE - tristate -@@ -57,7 +57,7 @@ config SND_CORE_TEST - - - config SND_COMPRESS_OFFLOAD -- tristate -+ tristate "Compression offloading support" - - config SND_JACK - bool --- -2.51.0 - - -From 96c73d623607c4b0d07e488648bc48d1b4297872 Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 13:33:30 +0200 -Subject: [PATCH 340/517] Kconfig: add tristate for OID and ASNI string - ---- - init/Kconfig | 2 +- - lib/Kconfig | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/init/Kconfig b/init/Kconfig -index 0de264f33b49..dfc689f2a766 100644 ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -2063,7 +2063,7 @@ config PADATA - bool - - config ASN1 -- tristate -+ tristate "ASN1" - help - Build a simple ASN.1 grammar compiler that produces a bytecode output - that can be interpreted by the ASN.1 stream decoder and used to -diff --git a/lib/Kconfig b/lib/Kconfig -index 1ddb823c425e..c8cc10b1f163 100644 ---- a/lib/Kconfig -+++ b/lib/Kconfig -@@ -642,7 +642,7 @@ config LIBFDT - bool - - config OID_REGISTRY -- tristate -+ tristate "OID" - help - Enable fast lookup object identifier registry. - --- -2.51.0 - - -From 8aaddb765893f392454753b44f0a4de7fe456788 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Sat, 15 Jul 2017 21:12:38 +0200 -Subject: [PATCH 341/517] kernel: move regmap bloat out of the kernel image if - it is only being used in modules - -lede-commit: 96f39119815028073583e4fca3a9c5fe9141e998 -Signed-off-by: Felix Fietkau ---- - drivers/base/regmap/Kconfig | 21 ++++++++++++++++++--- - drivers/base/regmap/Makefile | 8 +++++--- - drivers/base/regmap/regmap.c | 3 +++ - include/linux/regmap.h | 2 +- - 4 files changed, 27 insertions(+), 7 deletions(-) - -diff --git a/drivers/base/regmap/Kconfig b/drivers/base/regmap/Kconfig -index b1affac70d5d..4a6c93b51767 100644 ---- a/drivers/base/regmap/Kconfig -+++ b/drivers/base/regmap/Kconfig -@@ -4,8 +4,7 @@ - # subsystems should select the appropriate symbols. - - config REGMAP -- bool -- default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_W1 || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ || REGMAP_SOUNDWIRE || REGMAP_SOUNDWIRE_MBQ || REGMAP_SCCB || REGMAP_I3C || REGMAP_SPI_AVMM || REGMAP_MDIO || REGMAP_FSI) -+ tristate - select IRQ_DOMAIN if REGMAP_IRQ - select MDIO_BUS if REGMAP_MDIO - help -@@ -19,7 +18,7 @@ config REGMAP - - config REGMAP_KUNIT - tristate "KUnit tests for regmap" -- depends on KUNIT && REGMAP -+ depends on KUNIT - default KUNIT_ALL_TESTS - select REGMAP_RAM - -@@ -34,60 +33,76 @@ config REGMAP_BUILD - normally enabled. - - config REGMAP_AC97 -+ select REGMAP - tristate - - config REGMAP_I2C -+ select REGMAP - tristate - depends on I2C - - config REGMAP_SLIMBUS -+ select REGMAP - tristate - depends on SLIMBUS - - config REGMAP_SPI -+ select REGMAP - tristate - depends on SPI - - config REGMAP_SPMI -+ select REGMAP - tristate - depends on SPMI - - config REGMAP_W1 -+ select REGMAP - tristate - depends on W1 - - config REGMAP_MDIO -+ select REGMAP - tristate - - config REGMAP_MMIO -+ select REGMAP - tristate - - config REGMAP_IRQ -+ select REGMAP - bool - - config REGMAP_RAM -+ select REGMAP - tristate - - config REGMAP_SOUNDWIRE -+ select REGMAP - tristate - depends on SOUNDWIRE - - config REGMAP_SOUNDWIRE_MBQ -+ select REGMAP - tristate - depends on SOUNDWIRE - - config REGMAP_SCCB -+ select REGMAP - tristate - depends on I2C - - config REGMAP_I3C -+ select REGMAP - tristate - depends on I3C - - config REGMAP_SPI_AVMM -+ select REGMAP - tristate - depends on SPI - - config REGMAP_FSI -+ select REGMAP - tristate - depends on FSI -diff --git a/drivers/base/regmap/Makefile b/drivers/base/regmap/Makefile -index 5fdd0845b45e..f171215a71f7 100644 ---- a/drivers/base/regmap/Makefile -+++ b/drivers/base/regmap/Makefile -@@ -2,9 +2,11 @@ - # For include/trace/define_trace.h to include trace.h - CFLAGS_regmap.o := -I$(src) - --obj-$(CONFIG_REGMAP) += regmap.o regcache.o --obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-flat.o regcache-maple.o --obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o -+regmap-core-objs = regmap.o regcache.o regcache-rbtree.o regcache-flat.o regcache-maple.o -+ifdef CONFIG_DEBUG_FS -+regmap-core-objs += regmap-debugfs.o -+endif -+obj-$(CONFIG_REGMAP) += regmap-core.o - obj-$(CONFIG_REGMAP_KUNIT) += regmap-kunit.o - obj-$(CONFIG_REGMAP_AC97) += regmap-ac97.o - obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o -diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c -index 66b3840bd96e..93d26238811d 100644 ---- a/drivers/base/regmap/regmap.c -+++ b/drivers/base/regmap/regmap.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -3521,3 +3522,5 @@ static int __init regmap_initcall(void) - return 0; - } - postcore_initcall(regmap_initcall); -+ -+MODULE_LICENSE("GPL"); -diff --git a/include/linux/regmap.h b/include/linux/regmap.h -index f9ccad32fc5c..bb3765f8984d 100644 ---- a/include/linux/regmap.h -+++ b/include/linux/regmap.h -@@ -197,7 +197,7 @@ struct reg_sequence { - __ret ?: __tmp; \ - }) - --#ifdef CONFIG_REGMAP -+#if IS_REACHABLE(CONFIG_REGMAP) - - enum regmap_endian { - /* Unspecified -> 0 -> Backwards compatible default */ --- -2.51.0 - - -From d4c446b3081ba313c2fd5eba17b542e3beda61c6 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 7 Jul 2017 17:12:51 +0200 -Subject: [PATCH 342/517] kernel: prevent cryptomgr from pulling in useless - extra dependencies for tests that are not run - -Reduces kernel size after LZMA by about 5k on MIPS - -lede-commit: 044c316167e076479a344c59905e5b435b84a77f -Signed-off-by: Felix Fietkau ---- - crypto/Kconfig | 18 +++++++++--------- - crypto/algboss.c | 4 ++++ - 2 files changed, 13 insertions(+), 9 deletions(-) - -diff --git a/crypto/Kconfig b/crypto/Kconfig -index 79fc693086b7..0f9a815d0b5e 100644 ---- a/crypto/Kconfig -+++ b/crypto/Kconfig -@@ -149,15 +149,15 @@ config CRYPTO_MANAGER - cbc(aes). - - config CRYPTO_MANAGER2 -- def_tristate CRYPTO_MANAGER || (CRYPTO_MANAGER!=n && CRYPTO_ALGAPI=y) -- select CRYPTO_ACOMP2 -- select CRYPTO_AEAD2 -- select CRYPTO_AKCIPHER2 -- select CRYPTO_SIG2 -- select CRYPTO_HASH2 -- select CRYPTO_KPP2 -- select CRYPTO_RNG2 -- select CRYPTO_SKCIPHER2 -+ def_tristate CRYPTO_MANAGER || (CRYPTO_MANAGER!=n && CRYPTO_ALGAPI=y && !CRYPTO_MANAGER_DISABLE_TESTS) -+ select CRYPTO_ACOMP2 if !CRYPTO_MANAGER_DISABLE_TESTS -+ select CRYPTO_AEAD2 if !CRYPTO_MANAGER_DISABLE_TESTS -+ select CRYPTO_AKCIPHER2 if !CRYPTO_MANAGER_DISABLE_TESTS -+ select CRYPTO_SIG2 if !CRYPTO_MANAGER_DISABLE_TESTS -+ select CRYPTO_HASH2 if !CRYPTO_MANAGER_DISABLE_TESTS -+ select CRYPTO_KPP2 if !CRYPTO_MANAGER_DISABLE_TESTS -+ select CRYPTO_RNG2 if !CRYPTO_MANAGER_DISABLE_TESTS -+ select CRYPTO_SKCIPHER2 if !CRYPTO_MANAGER_DISABLE_TESTS - - config CRYPTO_USER - tristate "Userspace cryptographic algorithm configuration" -diff --git a/crypto/algboss.c b/crypto/algboss.c -index a20926bfd34e..3ac655fa7b94 100644 ---- a/crypto/algboss.c -+++ b/crypto/algboss.c -@@ -203,6 +203,10 @@ static int cryptomgr_schedule_test(struct crypto_alg *alg) - memcpy(param->alg, alg->cra_name, sizeof(param->alg)); - param->type = alg->cra_flags; - -+#ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS -+ param->type |= CRYPTO_ALG_TESTED; -+#endif -+ - thread = kthread_run(cryptomgr_test, param, "cryptomgr_test"); - if (IS_ERR(thread)) - goto err_free_param; --- -2.51.0 - - -From c59c9285d6b0e298be700e8d067881d4f0804f26 Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 13:35:18 +0200 -Subject: [PATCH 343/517] lib/crypto: add tristate string for ARC4 - -This makes it possible to select CONFIG_CRYPTO_LIB_ARC4 directly. We -need this to be able to compile this into the kernel and make use of it -from backports. ---- - lib/crypto/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/lib/crypto/Kconfig b/lib/crypto/Kconfig -index b09e78da959a..6bd7c7ba58e6 100644 ---- a/lib/crypto/Kconfig -+++ b/lib/crypto/Kconfig -@@ -20,7 +20,7 @@ config CRYPTO_LIB_AESGCM - select CRYPTO_LIB_UTILS - - config CRYPTO_LIB_ARC4 -- tristate -+ tristate "ARC4 cipher library" - - config CRYPTO_LIB_GF128MUL - tristate --- -2.51.0 - - -From 995f1f0db5478d75487df6df85dc4a2be4949a77 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Fri, 7 Jul 2017 17:13:44 +0200 -Subject: [PATCH 344/517] rfkill: add fake rfkill support - -allow building of modules depending on RFKILL even if RFKILL is not enabled. - -Signed-off-by: John Crispin ---- - include/linux/rfkill.h | 2 +- - net/Makefile | 2 +- - net/rfkill/Kconfig | 12 ++++++++---- - net/rfkill/Makefile | 2 +- - 4 files changed, 11 insertions(+), 7 deletions(-) - -diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h -index 997b34197385..9ec57a9e7c9f 100644 ---- a/include/linux/rfkill.h -+++ b/include/linux/rfkill.h -@@ -64,7 +64,7 @@ struct rfkill_ops { - int (*set_block)(void *data, bool blocked); - }; - --#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) -+#if defined(CONFIG_RFKILL_FULL) || defined(CONFIG_RFKILL_FULL_MODULE) - /** - * rfkill_alloc - Allocate rfkill structure - * @name: name of the struct -- the string is not copied internally -diff --git a/net/Makefile b/net/Makefile -index 65bb8c72a35e..d67f93b150e5 100644 ---- a/net/Makefile -+++ b/net/Makefile -@@ -51,7 +51,7 @@ obj-$(CONFIG_TIPC) += tipc/ - obj-$(CONFIG_NETLABEL) += netlabel/ - obj-$(CONFIG_IUCV) += iucv/ - obj-$(CONFIG_SMC) += smc/ --obj-$(CONFIG_RFKILL) += rfkill/ -+obj-$(CONFIG_RFKILL_FULL) += rfkill/ - obj-$(CONFIG_NET_9P) += 9p/ - obj-$(CONFIG_CAIF) += caif/ - obj-$(CONFIG_DCB) += dcb/ -diff --git a/net/rfkill/Kconfig b/net/rfkill/Kconfig -index 83a7af8982bb..d05d6ae15032 100644 ---- a/net/rfkill/Kconfig -+++ b/net/rfkill/Kconfig -@@ -2,7 +2,11 @@ - # - # RF switch subsystem configuration - # --menuconfig RFKILL -+config RFKILL -+ bool -+ default y -+ -+menuconfig RFKILL_FULL - tristate "RF switch subsystem support" - help - Say Y here if you want to have control over RF switches -@@ -14,19 +18,19 @@ menuconfig RFKILL - # LED trigger support - config RFKILL_LEDS - bool -- depends on RFKILL -+ depends on RFKILL_FULL - depends on LEDS_TRIGGERS = y || RFKILL = LEDS_TRIGGERS - default y - - config RFKILL_INPUT - bool "RF switch input support" if EXPERT -- depends on RFKILL -+ depends on RFKILL_FULL - depends on INPUT = y || RFKILL = INPUT - default y if !EXPERT - - config RFKILL_GPIO - tristate "GPIO RFKILL driver" -- depends on RFKILL -+ depends on RFKILL_FULL - depends on GPIOLIB || COMPILE_TEST - default n - help -diff --git a/net/rfkill/Makefile b/net/rfkill/Makefile -index dc47b6174ec5..be58b4119dac 100644 ---- a/net/rfkill/Makefile -+++ b/net/rfkill/Makefile -@@ -5,5 +5,5 @@ - - rfkill-y += core.o - rfkill-$(CONFIG_RFKILL_INPUT) += input.o --obj-$(CONFIG_RFKILL) += rfkill.o -+obj-$(CONFIG_RFKILL_FULL) += rfkill.o - obj-$(CONFIG_RFKILL_GPIO) += rfkill-gpio.o --- -2.51.0 - - -From 8e80abd396bc37470970931944b289314c894e81 Mon Sep 17 00:00:00 2001 -From: Ben Menchaca -Date: Fri, 7 Jun 2013 18:35:22 -0500 -Subject: [PATCH 345/517] MIPS: r4k_cache: use more efficient cache blast - -Optimize the compiler output for larger cache blast cases that are -common for DMA-based networking. - -Signed-off-by: Ben Menchaca -Signed-off-by: Felix Fietkau ---- - arch/mips/include/asm/r4kcache.h | 42 ++++++++++++++++++++++++++++---- - 1 file changed, 37 insertions(+), 5 deletions(-) - -diff --git a/arch/mips/include/asm/r4kcache.h b/arch/mips/include/asm/r4kcache.h -index da1cd1bbdbc5..1624b578a157 100644 ---- a/arch/mips/include/asm/r4kcache.h -+++ b/arch/mips/include/asm/r4kcache.h -@@ -290,14 +290,46 @@ static inline void prot##extra##blast_##pfx##cache##_range(unsigned long start, - unsigned long end) \ - { \ - unsigned long lsize = cpu_##desc##_line_size(); \ -+ unsigned long lsize_2 = lsize * 2; \ -+ unsigned long lsize_3 = lsize * 3; \ -+ unsigned long lsize_4 = lsize * 4; \ -+ unsigned long lsize_5 = lsize * 5; \ -+ unsigned long lsize_6 = lsize * 6; \ -+ unsigned long lsize_7 = lsize * 7; \ -+ unsigned long lsize_8 = lsize * 8; \ - unsigned long addr = start & ~(lsize - 1); \ -- unsigned long aend = (end - 1) & ~(lsize - 1); \ -+ unsigned long aend = (end + lsize - 1) & ~(lsize - 1); \ -+ int lines = (aend - addr) / lsize; \ - \ -- while (1) { \ -+ while (lines >= 8) { \ -+ prot##cache_op(hitop, addr); \ -+ prot##cache_op(hitop, addr + lsize); \ -+ prot##cache_op(hitop, addr + lsize_2); \ -+ prot##cache_op(hitop, addr + lsize_3); \ -+ prot##cache_op(hitop, addr + lsize_4); \ -+ prot##cache_op(hitop, addr + lsize_5); \ -+ prot##cache_op(hitop, addr + lsize_6); \ -+ prot##cache_op(hitop, addr + lsize_7); \ -+ addr += lsize_8; \ -+ lines -= 8; \ -+ } \ -+ \ -+ if (lines & 0x4) { \ -+ prot##cache_op(hitop, addr); \ -+ prot##cache_op(hitop, addr + lsize); \ -+ prot##cache_op(hitop, addr + lsize_2); \ -+ prot##cache_op(hitop, addr + lsize_3); \ -+ addr += lsize_4; \ -+ } \ -+ \ -+ if (lines & 0x2) { \ -+ prot##cache_op(hitop, addr); \ -+ prot##cache_op(hitop, addr + lsize); \ -+ addr += lsize_2; \ -+ } \ -+ \ -+ if (lines & 0x1) { \ - prot##cache_op(hitop, addr); \ -- if (addr == aend) \ -- break; \ -- addr += lsize; \ - } \ - } - --- -2.51.0 - - -From fb6db57e6a54fc221b942ee771066ade1318a27a Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 14 Apr 2025 18:04:25 +0200 -Subject: [PATCH 346/517] mm: permit to declare custom execmem alloc/free - function - -Permit to declare custom execmem alloc/free function that bypass the -execmem API. This works by making the alloc/free function weak -permitting an arch to declare a replacement for them. - -Signed-off-by: Christian Marangi -Co-authored-by: Shiji Yang ---- - include/linux/moduleloader.h | 4 ++++ - mm/execmem.c | 14 ++++++++++++-- - 2 files changed, 16 insertions(+), 2 deletions(-) - -diff --git a/include/linux/moduleloader.h b/include/linux/moduleloader.h -index e395461d59e5..ee24ba60f51a 100644 ---- a/include/linux/moduleloader.h -+++ b/include/linux/moduleloader.h -@@ -122,4 +122,8 @@ void module_arch_cleanup(struct module *mod); - /* Any cleanup before freeing mod->module_init */ - void module_arch_freeing_init(struct module *mod); - -+enum execmem_type; -+void *arch_execmem_alloc(enum execmem_type type, size_t size); -+void arch_execmem_free(void *ptr); -+ - #endif -diff --git a/mm/execmem.c b/mm/execmem.c -index 0c4b36bc6d10..3b21780a196b 100644 ---- a/mm/execmem.c -+++ b/mm/execmem.c -@@ -52,14 +52,19 @@ static void *__execmem_alloc(struct execmem_range *range, size_t size) - return kasan_reset_tag(p); - } - --void *execmem_alloc(enum execmem_type type, size_t size) -+void *__weak arch_execmem_alloc(enum execmem_type type, size_t size) - { - struct execmem_range *range = &execmem_info->ranges[type]; - - return __execmem_alloc(range, size); - } - --void execmem_free(void *ptr) -+void *execmem_alloc(enum execmem_type type, size_t size) -+{ -+ return arch_execmem_alloc(type, size); -+} -+ -+void __weak arch_execmem_free(void *ptr) - { - /* - * This memory may be RO, and freeing RO memory in an interrupt is not -@@ -69,6 +74,11 @@ void execmem_free(void *ptr) - vfree(ptr); - } - -+void execmem_free(void *ptr) -+{ -+ arch_execmem_free(ptr); -+} -+ - static bool execmem_validate(struct execmem_info *info) - { - struct execmem_range *r = &info->ranges[EXECMEM_DEFAULT]; --- -2.51.0 - - -From a72909bbbd432df45021d446dd0983251229c5a4 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Mon, 14 Apr 2025 18:05:45 +0200 -Subject: [PATCH 347/517] mips: replace -mlong-calls with -mno-long-calls if - possible - -This is a really old patch ported from MikroTik. It needs a an -additional patch to actually be implemented and both this and the old -one are considered HACK as they bypass normal kernel linux to make it -work. - -The original message quote: - -replace -mlong-calls with -mno-long-calls to make function -calls faster in kernel modules to achieve this, try to load -kernel modules to KSEG0 and if that doesn't work, use vmalloc -and fix up relocations with a jump table based on code from a -kernel patch by MikroTik. - -SVN-Revision: 16772 - -lede-commit: 3b3d64743ba2a874df9d70cd19e242205b0a788c -Signed-off-by: Felix Fietkau -Signed-off-by: Christian Marangi ---- - arch/mips/Makefile | 10 ++ - arch/mips/include/asm/module.h | 5 + - arch/mips/kernel/module.c | 281 ++++++++++++++++++++++++++++++++- - 3 files changed, 292 insertions(+), 4 deletions(-) - -diff --git a/arch/mips/Makefile b/arch/mips/Makefile -index 2a770f13a0cc..29a7c9a55358 100644 ---- a/arch/mips/Makefile -+++ b/arch/mips/Makefile -@@ -97,8 +97,18 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlinuz - cflags-y += -G 0 -mno-abicalls -fno-pic -pipe -mno-branch-likely - cflags-y += -msoft-float -Wa,-msoft-float - LDFLAGS_vmlinux += -G 0 -static -n -nostdlib -+ifdef CONFIG_64BIT - KBUILD_AFLAGS_MODULE += -mlong-calls - KBUILD_CFLAGS_MODULE += -mlong-calls -+else -+ ifdef CONFIG_DYNAMIC_FTRACE -+ KBUILD_AFLAGS_MODULE += -mlong-calls -+ KBUILD_CFLAGS_MODULE += -mlong-calls -+ else -+ KBUILD_AFLAGS_MODULE += -mno-long-calls -+ KBUILD_CFLAGS_MODULE += -mno-long-calls -+ endif -+endif - - ifeq ($(CONFIG_RELOCATABLE),y) - LDFLAGS_vmlinux += --emit-relocs -diff --git a/arch/mips/include/asm/module.h b/arch/mips/include/asm/module.h -index 724a0882576b..9dfc597be586 100644 ---- a/arch/mips/include/asm/module.h -+++ b/arch/mips/include/asm/module.h -@@ -12,6 +12,11 @@ struct mod_arch_specific { - const struct exception_table_entry *dbe_start; - const struct exception_table_entry *dbe_end; - struct mips_hi16 *r_mips_hi16_list; -+ -+ void *phys_plt_tbl; -+ void *virt_plt_tbl; -+ unsigned int phys_plt_offset; -+ unsigned int virt_plt_offset; - }; - - typedef uint8_t Elf64_Byte; /* Type for a 8-bit quantity. */ -diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c -index ba0f62d8eff5..bd731174b01e 100644 ---- a/arch/mips/kernel/module.c -+++ b/arch/mips/kernel/module.c -@@ -8,6 +8,7 @@ - - #undef DEBUG - -+#include - #include - #include - #include -@@ -19,6 +20,7 @@ - #include - #include - #include -+#include - #include - - struct mips_hi16 { -@@ -30,14 +32,254 @@ struct mips_hi16 { - static LIST_HEAD(dbe_list); - static DEFINE_SPINLOCK(dbe_lock); - -+/* -+ * Get the potential max trampolines size required of the init and -+ * non-init sections. Only used if we cannot find enough contiguous -+ * physically mapped memory to put the module into. -+ */ -+static unsigned int -+get_plt_size(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, -+ const char *secstrings, unsigned int symindex, bool is_init) -+{ -+ unsigned long ret = 0; -+ unsigned int i, j; -+ Elf_Sym *syms; -+ -+ /* Everything marked ALLOC (this includes the exported symbols) */ -+ for (i = 1; i < hdr->e_shnum; ++i) { -+ unsigned int info = sechdrs[i].sh_info; -+ -+ if (sechdrs[i].sh_type != SHT_REL -+ && sechdrs[i].sh_type != SHT_RELA) -+ continue; -+ -+ /* Not a valid relocation section? */ -+ if (info >= hdr->e_shnum) -+ continue; -+ -+ /* Don't bother with non-allocated sections */ -+ if (!(sechdrs[info].sh_flags & SHF_ALLOC)) -+ continue; -+ -+ /* If it's called *.init*, and we're not init, we're -+ not interested */ -+ if ((strstr(secstrings + sechdrs[i].sh_name, ".init") != 0) -+ != is_init) -+ continue; -+ -+ syms = (Elf_Sym *) sechdrs[symindex].sh_addr; -+ if (sechdrs[i].sh_type == SHT_REL) { -+ Elf_Mips_Rel *rel = (void *) sechdrs[i].sh_addr; -+ unsigned int size = sechdrs[i].sh_size / sizeof(*rel); -+ -+ for (j = 0; j < size; ++j) { -+ Elf_Sym *sym; -+ -+ if (ELF_MIPS_R_TYPE(rel[j]) != R_MIPS_26) -+ continue; -+ -+ sym = syms + ELF_MIPS_R_SYM(rel[j]); -+ if (!is_init && sym->st_shndx != SHN_UNDEF) -+ continue; -+ -+ ret += 4 * sizeof(int); -+ } -+ } else { -+ Elf_Mips_Rela *rela = (void *) sechdrs[i].sh_addr; -+ unsigned int size = sechdrs[i].sh_size / sizeof(*rela); -+ -+ for (j = 0; j < size; ++j) { -+ Elf_Sym *sym; -+ -+ if (ELF_MIPS_R_TYPE(rela[j]) != R_MIPS_26) -+ continue; -+ -+ sym = syms + ELF_MIPS_R_SYM(rela[j]); -+ if (!is_init && sym->st_shndx != SHN_UNDEF) -+ continue; -+ -+ ret += 4 * sizeof(int); -+ } -+ } -+ } -+ -+ return ret; -+} -+ -+#ifndef MODULES_VADDR -+static void *alloc_phys(unsigned long size) -+{ -+ unsigned order; -+ struct page *page; -+ struct page *p; -+ -+ size = PAGE_ALIGN(size); -+ order = get_order(size); -+ -+ page = alloc_pages(GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN | -+ __GFP_THISNODE, order); -+ if (!page) -+ return NULL; -+ -+ split_page(page, order); -+ -+ /* mark all pages except for the last one */ -+ for (p = page; p + 1 < page + (size >> PAGE_SHIFT); ++p) -+ set_bit(PG_owner_priv_1, &p->flags); -+ -+ for (p = page + (size >> PAGE_SHIFT); p < page + (1 << order); ++p) -+ __free_page(p); -+ -+ return page_address(page); -+} -+ -+static void free_phys(void *ptr) -+{ -+ struct page *page; -+ bool free; -+ -+ page = virt_to_page(ptr); -+ do { -+ free = test_and_clear_bit(PG_owner_priv_1, &page->flags); -+ __free_page(page); -+ page++; -+ } while (free); -+} -+ -+void *arch_execmem_alloc(enum execmem_type type, -+ size_t size) -+{ -+ void *ptr; -+ -+ ptr = alloc_phys(size); -+ -+ /* If we failed to allocate physically contiguous memory, -+ * fall back to regular vmalloc. The module loader code will -+ * create jump tables to handle long jumps */ -+ if (!ptr) -+ return vmalloc(size); -+ -+ return ptr; -+} -+#endif -+ -+static inline bool is_phys_addr(void *ptr) -+{ -+#ifdef CONFIG_64BIT -+ return (KSEGX((unsigned long)ptr) == CKSEG0); -+#else -+ return (KSEGX(ptr) == KSEG0); -+#endif -+} -+ -+#ifndef MODULES_VADDR -+/* Free memory returned from module_alloc */ -+void arch_execmem_free(void *ptr) -+{ -+ if (is_phys_addr(ptr)) -+ free_phys(ptr); -+ else -+ vfree(ptr); -+} -+#endif -+ -+static void *__module_alloc(int size, bool phys) -+{ -+ void *ptr; -+ -+ if (phys) -+ ptr = kmalloc(size, GFP_KERNEL); -+ else -+ ptr = vmalloc(size); -+ return ptr; -+} -+ -+static void __module_free(void *ptr) -+{ -+ if (is_phys_addr(ptr)) -+ kfree(ptr); -+ else -+ vfree(ptr); -+} -+ -+int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, -+ char *secstrings, struct module *mod) -+{ -+ unsigned int symindex = 0; -+ unsigned int core_size, init_size; -+ int i; -+ -+ mod->arch.phys_plt_offset = 0; -+ mod->arch.virt_plt_offset = 0; -+ mod->arch.phys_plt_tbl = NULL; -+ mod->arch.virt_plt_tbl = NULL; -+ -+ if (IS_ENABLED(CONFIG_64BIT)) -+ return 0; -+ -+ for (i = 1; i < hdr->e_shnum; i++) -+ if (sechdrs[i].sh_type == SHT_SYMTAB) -+ symindex = i; -+ -+ core_size = get_plt_size(hdr, sechdrs, secstrings, symindex, false); -+ init_size = get_plt_size(hdr, sechdrs, secstrings, symindex, true); -+ -+ if ((core_size + init_size) == 0) -+ return 0; -+ -+ mod->arch.phys_plt_tbl = __module_alloc(core_size + init_size, 1); -+ if (!mod->arch.phys_plt_tbl) -+ return -ENOMEM; -+ -+ mod->arch.virt_plt_tbl = __module_alloc(core_size + init_size, 0); -+ if (!mod->arch.virt_plt_tbl) { -+ __module_free(mod->arch.phys_plt_tbl); -+ mod->arch.phys_plt_tbl = NULL; -+ return -ENOMEM; -+ } -+ -+ return 0; -+} -+ - static void apply_r_mips_32(u32 *location, u32 base, Elf_Addr v) - { - *location = base + v; - } - -+static Elf_Addr add_plt_entry_to(unsigned *plt_offset, -+ void *start, Elf_Addr v) -+{ -+ unsigned *tramp = start + *plt_offset; -+ *plt_offset += 4 * sizeof(int); -+ -+ /* adjust carry for addiu */ -+ if (v & 0x00008000) -+ v += 0x10000; -+ -+ tramp[0] = 0x3c190000 | (v >> 16); /* lui t9, hi16 */ -+ tramp[1] = 0x27390000 | (v & 0xffff); /* addiu t9, t9, lo16 */ -+ tramp[2] = 0x03200008; /* jr t9 */ -+ tramp[3] = 0x00000000; /* nop */ -+ -+ return (Elf_Addr) tramp; -+} -+ -+static Elf_Addr add_plt_entry(struct module *me, void *location, Elf_Addr v) -+{ -+ if (is_phys_addr(location)) -+ return add_plt_entry_to(&me->arch.phys_plt_offset, -+ me->arch.phys_plt_tbl, v); -+ else -+ return add_plt_entry_to(&me->arch.virt_plt_offset, -+ me->arch.virt_plt_tbl, v); -+ -+} -+ - static int apply_r_mips_26(struct module *me, u32 *location, u32 base, - Elf_Addr v) - { -+ u32 ofs = base & 0x03ffffff; -+ - if (v % 4) { - pr_err("module %s: dangerous R_MIPS_26 relocation\n", - me->name); -@@ -45,13 +287,17 @@ static int apply_r_mips_26(struct module *me, u32 *location, u32 base, - } - - if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { -- pr_err("module %s: relocation overflow\n", -- me->name); -- return -ENOEXEC; -+ v = add_plt_entry(me, location, v + (ofs << 2)); -+ if (!v) { -+ pr_err("module %s: relocation overflow\n", -+ me->name); -+ return -ENOEXEC; -+ } -+ ofs = 0; - } - - *location = (*location & ~0x03ffffff) | -- ((base + (v >> 2)) & 0x03ffffff); -+ ((ofs + (v >> 2)) & 0x03ffffff); - - return 0; - } -@@ -431,9 +677,36 @@ int module_finalize(const Elf_Ehdr *hdr, - list_add(&me->arch.dbe_list, &dbe_list); - spin_unlock_irq(&dbe_lock); - } -+ -+ /* Get rid of the fixup trampoline if we're running the module -+ * from physically mapped address space */ -+ if (me->arch.phys_plt_offset == 0) { -+ __module_free(me->arch.phys_plt_tbl); -+ me->arch.phys_plt_tbl = NULL; -+ } -+ if (me->arch.virt_plt_offset == 0) { -+ __module_free(me->arch.virt_plt_tbl); -+ me->arch.virt_plt_tbl = NULL; -+ } -+ - return 0; - } - -+void module_arch_freeing_init(struct module *mod) -+{ -+ if (mod->state == MODULE_STATE_LIVE) -+ return; -+ -+ if (mod->arch.phys_plt_tbl) { -+ __module_free(mod->arch.phys_plt_tbl); -+ mod->arch.phys_plt_tbl = NULL; -+ } -+ if (mod->arch.virt_plt_tbl) { -+ __module_free(mod->arch.virt_plt_tbl); -+ mod->arch.virt_plt_tbl = NULL; -+ } -+} -+ - void module_arch_cleanup(struct module *mod) - { - spin_lock_irq(&dbe_lock); --- -2.51.0 - - -From 016d53c3a76a0abd9c3a5f88b080ee9ebeee8a3e Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Wed, 7 Apr 2021 22:45:54 +0100 -Subject: [PATCH 348/517] mtd: blktrans: call add disks after mtd device - -Calling device_add_disk while holding mtd_table_mutex leads -to deadlock in case part_bits!=0 as block partition parsers -will try to open the newly created disks, trying to acquire -mutex once again. -Move device_add_disk to additional function called after -add partitions of an MTD device have been added and locks -have been released. - -Signed-off-by: Daniel Golle ---- - drivers/mtd/mtd_blkdevs.c | 40 ++++++++++++++++++++++++++---------- - drivers/mtd/mtdcore.c | 3 +++ - include/linux/mtd/blktrans.h | 1 + - 3 files changed, 33 insertions(+), 11 deletions(-) - -diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c -index 47ead84407cd..f27a807dc886 100644 ---- a/drivers/mtd/mtd_blkdevs.c -+++ b/drivers/mtd/mtd_blkdevs.c -@@ -379,19 +379,8 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) - if (new->readonly) - set_disk_ro(gd, 1); - -- ret = device_add_disk(&new->mtd->dev, gd, NULL); -- if (ret) -- goto out_cleanup_disk; -- -- if (new->disk_attributes) { -- ret = sysfs_create_group(&disk_to_dev(gd)->kobj, -- new->disk_attributes); -- WARN_ON(ret); -- } - return 0; - --out_cleanup_disk: -- put_disk(new->disk); - out_free_tag_set: - blk_mq_free_tag_set(new->tag_set); - out_kfree_tag_set: -@@ -401,6 +390,35 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) - return ret; - } - -+void register_mtd_blktrans_devs(void) -+{ -+ struct mtd_blktrans_ops *tr; -+ struct mtd_blktrans_dev *dev, *next; -+ int ret; -+ -+ list_for_each_entry(tr, &blktrans_majors, list) { -+ list_for_each_entry_safe(dev, next, &tr->devs, list) { -+ if (disk_live(dev->disk)) -+ continue; -+ -+ ret = device_add_disk(&dev->mtd->dev, dev->disk, NULL); -+ if (ret) -+ goto out_cleanup_disk; -+ -+ if (dev->disk_attributes) { -+ ret = sysfs_create_group(&disk_to_dev(dev->disk)->kobj, -+ dev->disk_attributes); -+ WARN_ON(ret); -+ } -+ } -+ } -+ -+ return; -+ -+out_cleanup_disk: -+ put_disk(dev->disk); -+} -+ - int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old) - { - unsigned long flags; -diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c -index 6b98d581ceeb..c34e31a915f2 100644 ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -34,6 +34,7 @@ - - #include - #include -+#include - - #include "mtdcore.h" - -@@ -1132,6 +1133,8 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types, - register_reboot_notifier(&mtd->reboot_notifier); - } - -+ register_mtd_blktrans_devs(); -+ - out: - if (ret) { - nvmem_unregister(mtd->otp_user_nvmem); -diff --git a/include/linux/mtd/blktrans.h b/include/linux/mtd/blktrans.h -index 6e471436bba5..70f246a3dceb 100644 ---- a/include/linux/mtd/blktrans.h -+++ b/include/linux/mtd/blktrans.h -@@ -76,6 +76,7 @@ extern int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr); - extern int add_mtd_blktrans_dev(struct mtd_blktrans_dev *dev); - extern int del_mtd_blktrans_dev(struct mtd_blktrans_dev *dev); - extern int mtd_blktrans_cease_background(struct mtd_blktrans_dev *dev); -+extern void register_mtd_blktrans_devs(void); - - /** - * module_mtd_blktrans() - Helper macro for registering a mtd blktrans driver --- -2.51.0 - - -From 2be9bff250a6f8fe489c2b517985524c3ea64c18 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Mon, 7 Nov 2022 23:48:24 +0100 -Subject: [PATCH 349/517] mtd: support OpenWrt's MTD_ROOTFS_ROOT_DEV -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This allows setting ROOT_DEV to MTD partition named "rootfs". - -Signed-off-by: Rafał Miłecki ---- - drivers/mtd/mtdcore.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c -index c34e31a915f2..9bf60ad26daf 100644 ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -803,7 +803,8 @@ int add_mtd_device(struct mtd_info *mtd) - - mutex_unlock(&mtd_table_mutex); - -- if (of_property_read_bool(mtd_get_of_node(mtd), "linux,rootfs")) { -+ if (of_property_read_bool(mtd_get_of_node(mtd), "linux,rootfs") || -+ (IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) && !strcmp(mtd->name, "rootfs") && ROOT_DEV == 0)) { - if (IS_BUILTIN(CONFIG_MTD)) { - pr_info("mtd: setting mtd%d (%s) as root device\n", mtd->index, mtd->name); - ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index); --- -2.51.0 - - -From eddbc1471956f3bd6a0090488fb8549dca8d962c Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Mon, 11 Oct 2021 00:53:14 +0200 -Subject: [PATCH 350/517] drivers: mtd: parsers: add nvmem support to - cmdlinepart - -Assuming cmdlinepart is only one level deep partition scheme and that -static partition are also defined in DTS, we can assign an of_node for -partition declared from bootargs. cmdlinepart have priority than -fiexed-partition parser so in this specific case the parser doesn't -assign an of_node. Fix this by searching a defined of_node using a -similar fixed_partition parser and if a partition is found with the same -label, check that it has the same offset and size and return the DT -of_node to correctly use NVMEM cells. - -Signed-off-by: Ansuel Smith ---- - drivers/mtd/parsers/cmdlinepart.c | 71 +++++++++++++++++++++++++++++++ - 1 file changed, 71 insertions(+) - -diff --git a/drivers/mtd/parsers/cmdlinepart.c b/drivers/mtd/parsers/cmdlinepart.c -index 504e5fa2b45b..fe8354cd6515 100644 ---- a/drivers/mtd/parsers/cmdlinepart.c -+++ b/drivers/mtd/parsers/cmdlinepart.c -@@ -43,6 +43,7 @@ - #include - #include - #include -+#include - - /* special size referring to all the remaining space in a partition */ - #define SIZE_REMAINING ULLONG_MAX -@@ -315,6 +316,68 @@ static int mtdpart_setup_real(char *s) - return 0; - } - -+static int search_fixed_partition(struct mtd_info *master, -+ struct mtd_partition *target_part, -+ struct mtd_partition *fixed_part) -+{ -+ struct device_node *mtd_node; -+ struct device_node *ofpart_node; -+ struct device_node *pp; -+ struct mtd_partition part; -+ const char *partname; -+ -+ mtd_node = mtd_get_of_node(master); -+ if (!mtd_node) -+ return -EINVAL; -+ -+ ofpart_node = of_get_child_by_name(mtd_node, "partitions"); -+ -+ for_each_child_of_node(ofpart_node, pp) { -+ const __be32 *reg; -+ int len; -+ int a_cells, s_cells; -+ -+ reg = of_get_property(pp, "reg", &len); -+ if (!reg) { -+ pr_debug("%s: ofpart partition %pOF (%pOF) missing reg property.\n", -+ master->name, pp, -+ mtd_node); -+ continue; -+ } -+ -+ a_cells = of_n_addr_cells(pp); -+ s_cells = of_n_size_cells(pp); -+ if (len / 4 != a_cells + s_cells) { -+ pr_debug("%s: ofpart partition %pOF (%pOF) error parsing reg property.\n", -+ master->name, pp, -+ mtd_node); -+ continue; -+ } -+ -+ part.offset = of_read_number(reg, a_cells); -+ part.size = of_read_number(reg + a_cells, s_cells); -+ part.of_node = pp; -+ -+ partname = of_get_property(pp, "label", &len); -+ if (!partname) -+ partname = of_get_property(pp, "name", &len); -+ part.name = partname; -+ -+ if (!strncmp(target_part->name, part.name, len)) { -+ if (part.offset != target_part->offset) -+ return -EINVAL; -+ -+ if (part.size != target_part->size) -+ return -EINVAL; -+ -+ memcpy(fixed_part, &part, sizeof(struct mtd_partition)); -+ return 0; -+ } -+ } -+ -+ return -EINVAL; -+} -+ - /* - * Main function to be called from the MTD mapping driver/device to - * obtain the partitioning information. At this point the command line -@@ -330,6 +393,7 @@ static int parse_cmdline_partitions(struct mtd_info *master, - int i, err; - struct cmdline_mtd_partition *part; - const char *mtd_id = master->name; -+ struct mtd_partition fixed_part; - - /* parse command line */ - if (!cmdline_parsed) { -@@ -374,6 +438,13 @@ static int parse_cmdline_partitions(struct mtd_info *master, - sizeof(*part->parts) * (part->num_parts - i)); - i--; - } -+ -+ err = search_fixed_partition(master, &part->parts[i], &fixed_part); -+ if (!err) { -+ part->parts[i].of_node = fixed_part.of_node; -+ pr_info("Found partition defined in DT for %s. Assigning OF node to support nvmem.", -+ part->parts[i].name); -+ } - } - - *pparts = kmemdup(part->parts, sizeof(*part->parts) * part->num_parts, --- -2.51.0 - - -From b9b5fcad748eca6c1a4c8edcb34e2553f75f21aa Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 13:41:44 +0200 -Subject: [PATCH 351/517] mtd/nand: add MediaTek NAND bad block managment table - ---- - drivers/mtd/nand/Kconfig | 4 ++++ - drivers/mtd/nand/Makefile | 1 + - 2 files changed, 5 insertions(+) - -diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig -index 5b0c2c95f10c..e775c64e355d 100644 ---- a/drivers/mtd/nand/Kconfig -+++ b/drivers/mtd/nand/Kconfig -@@ -46,6 +46,10 @@ config MTD_NAND_ECC_SW_BCH - ECC codes. They are used with NAND devices requiring more than 1 bit - of error correction. - -+config MTD_NAND_MTK_BMT -+ bool "Support MediaTek NAND Bad-block Management Table" -+ default n -+ - config MTD_NAND_ECC_MXIC - bool "Macronix external hardware ECC engine" - depends on HAS_IOMEM -diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile -index db516a45f0c5..2998d84bb5d0 100644 ---- a/drivers/mtd/nand/Makefile -+++ b/drivers/mtd/nand/Makefile -@@ -3,6 +3,7 @@ - nandcore-objs := core.o bbt.o - obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o - obj-$(CONFIG_MTD_NAND_ECC_MEDIATEK) += ecc-mtk.o -+obj-$(CONFIG_MTD_NAND_MTK_BMT) += mtk_bmt.o mtk_bmt_v2.o mtk_bmt_bbt.o mtk_bmt_nmbm.o - ifeq ($(CONFIG_SPI_QPIC_SNAND),y) - obj-$(CONFIG_SPI_QPIC_SNAND) += qpic_common.o - else --- -2.51.0 - - -From fe7abda0ec355ddcf7184b0245f70dbfcb25d1aa Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Nov 2025 15:50:20 +0100 -Subject: [PATCH 352/517] LEGACY block: partitions: populate fwnode - -Assign matching firmware nodes to block partitions in order to allow -them to be referenced e.g. as NVMEM providers. - -REMOVE THIS PATCH ONCE ALL TARGETS ARE USING LINUX 6.12 AND ALL BOARDS -HAVE MIGRATED TO UPSTREAM DT BINDINGS. - -Signed-off-by: Daniel Golle ---- - block/partitions/core.c | 73 ++++++++++++++++++++++++++++++++++++++++ - drivers/mmc/core/block.c | 4 +++ - drivers/mmc/core/bus.c | 2 ++ - 3 files changed, 79 insertions(+) - -diff --git a/block/partitions/core.c b/block/partitions/core.c -index f5b5360dd518..29c9330b9050 100644 ---- a/block/partitions/core.c -+++ b/block/partitions/core.c -@@ -11,6 +11,8 @@ - #include - #include - #include -+#include -+ - #include "check.h" - - static int (*const check_part[])(struct parsed_partitions *) = { -@@ -285,6 +287,74 @@ static ssize_t whole_disk_show(struct device *dev, - } - static const DEVICE_ATTR(whole_disk, 0444, whole_disk_show, NULL); - -+static bool part_meta_match(const char *attr, const char *member, size_t length) -+{ -+ /* check if length of attr exceeds specified maximum length */ -+ if (strnlen(attr, length) == length) -+ return false; -+ -+ /* return true if strings match */ -+ return !strncmp(attr, member, length); -+} -+ -+static struct fwnode_handle *find_partition_fwnode(struct block_device *bdev) -+{ -+ struct fwnode_handle *fw_parts, *fw_part; -+ struct device *ddev = disk_to_dev(bdev->bd_disk); -+ const char *partname, *uuid; -+ u32 partno; -+ bool got_uuid, got_partname, got_partno; -+ -+ fw_parts = device_get_named_child_node(ddev, "partitions"); -+ if (!fw_parts) -+ return NULL; -+ -+ fwnode_for_each_child_node(fw_parts, fw_part) { -+ got_uuid = false; -+ got_partname = false; -+ got_partno = false; -+ /* -+ * In case 'uuid' is defined in the partitions firmware node -+ * require partition meta info being present and the specified -+ * uuid to match. -+ */ -+ got_uuid = !fwnode_property_read_string(fw_part, "uuid", &uuid); -+ if (got_uuid && (!bdev->bd_meta_info || -+ !part_meta_match(uuid, bdev->bd_meta_info->uuid, -+ PARTITION_META_INFO_UUIDLTH))) -+ continue; -+ -+ /* -+ * In case 'partname' is defined in the partitions firmware node -+ * require partition meta info being present and the specified -+ * volname to match. -+ */ -+ got_partname = !fwnode_property_read_string(fw_part, "partname", -+ &partname); -+ if (got_partname && (!bdev->bd_meta_info || -+ !part_meta_match(partname, -+ bdev->bd_meta_info->volname, -+ PARTITION_META_INFO_VOLNAMELTH))) -+ continue; -+ -+ /* -+ * In case 'partno' is defined in the partitions firmware node -+ * the specified partno needs to match. -+ */ -+ got_partno = !fwnode_property_read_u32(fw_part, "partno", &partno); -+ if (got_partno && bdev_partno(bdev) != partno) -+ continue; -+ -+ /* Skip if no matching criteria is present in firmware node */ -+ if (!got_uuid && !got_partname && !got_partno) -+ continue; -+ -+ return fw_part; -+ } -+ -+ return NULL; -+} -+ - /* - * Must be called either with open_mutex held, before a disk can be opened or - * after all disk users are gone. -@@ -361,6 +431,9 @@ static struct block_device *add_partition(struct gendisk *disk, int partno, - goto out_put; - } - -+ if (!pdev->fwnode && !pdev->of_node) -+ device_set_node(pdev, find_partition_fwnode(bdev)); -+ - /* delay uevent until 'holders' subdir is created */ - dev_set_uevent_suppress(pdev, 1); - err = device_add(pdev); -diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c -index f56eb44ec450..3c9443c7ac49 100644 ---- a/drivers/mmc/core/block.c -+++ b/drivers/mmc/core/block.c -@@ -2679,6 +2679,10 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, - if (area_type == MMC_BLK_DATA_AREA_MAIN) - dev_set_drvdata(&card->dev, md); - disk_fwnode = mmc_blk_get_partitions_node(parent, subname); -+ if (!disk_fwnode) -+ disk_fwnode = device_get_named_child_node(subname ? md->parent->parent : -+ md->parent, -+ subname ? subname : "block"); - ret = add_disk_fwnode(md->parent, md->disk, mmc_disk_attr_groups, - disk_fwnode); - if (ret) -diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c -index 4f3a26676ccb..359640be0592 100644 ---- a/drivers/mmc/core/bus.c -+++ b/drivers/mmc/core/bus.c -@@ -368,6 +368,8 @@ int mmc_add_card(struct mmc_card *card) - - mmc_add_card_debugfs(card); - card->dev.of_node = mmc_of_find_child_device(card->host, 0); -+ if (card->dev.of_node && !card->dev.fwnode) -+ card->dev.fwnode = &card->dev.of_node->fwnode; - - device_enable_async_suspend(&card->dev); - --- -2.51.0 - - -From 70fcd329f0105febc763f81d177058026db6c5f3 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Tue, 23 Apr 2024 12:35:21 +0200 -Subject: [PATCH 353/517] net: enable fraglist GRO by default - -This can significantly improve performance for packet forwarding/bridging - -Signed-off-by: Felix Fietkau ---- - include/linux/netdev_features.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h -index e2e3dd919068..8b9e912f6db6 100644 ---- a/include/linux/netdev_features.h -+++ b/include/linux/netdev_features.h -@@ -235,10 +235,10 @@ static inline int find_next_netdev_feature(u64 feature, unsigned long start) - #define NETIF_F_UPPER_DISABLES NETIF_F_LRO - - /* changeable features with no special hardware requirements */ --#define NETIF_F_SOFT_FEATURES (NETIF_F_GSO | NETIF_F_GRO) -+#define NETIF_F_SOFT_FEATURES (NETIF_F_GSO | NETIF_F_GRO | NETIF_F_GRO_FRAGLIST) - - /* Changeable features with no special hardware requirements that defaults to off. */ --#define NETIF_F_SOFT_FEATURES_OFF (NETIF_F_GRO_FRAGLIST | NETIF_F_GRO_UDP_FWD) -+#define NETIF_F_SOFT_FEATURES_OFF (NETIF_F_GRO_UDP_FWD) - - #define NETIF_F_VLAN_FEATURES (NETIF_F_HW_VLAN_CTAG_FILTER | \ - NETIF_F_HW_VLAN_CTAG_RX | \ --- -2.51.0 - - -From 9bc103b739dc6e694e05bcdc86b0583e94b5e140 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 3 Jan 2025 19:29:00 +0100 -Subject: [PATCH 354/517] net: page_pool: try to free deferred skbs while - waiting for pool release - -The NAPI defer list can accumulate no longer used skbs, which can be reused -during alloc. If this happens on a CPU that otherwise does not do any -rx softirq processing, skbs can be held indefinitely, causing warnings -on releasing page pools. -Deal with this by scheduling rx softirq on all CPUs. - -Patch by Lorenzo Bianconi - -Signed-off-by: Felix Fietkau ---- - net/core/page_pool.c | 18 +++++++++++++++++- - 1 file changed, 17 insertions(+), 1 deletion(-) - -diff --git a/net/core/page_pool.c b/net/core/page_pool.c -index 6a7d740b396f..c3a4ab60b6de 100644 ---- a/net/core/page_pool.c -+++ b/net/core/page_pool.c -@@ -1153,8 +1153,9 @@ static void page_pool_release_retry(struct work_struct *wq) - { - struct delayed_work *dwq = to_delayed_work(wq); - struct page_pool *pool = container_of(dwq, typeof(*pool), release_dw); -+ unsigned long flags; - void *netdev; -- int inflight; -+ int cpu, inflight; - - inflight = page_pool_release(pool); - /* In rare cases, a driver bug may cause inflight to go negative. -@@ -1166,6 +1167,21 @@ static void page_pool_release_retry(struct work_struct *wq) - if (inflight <= 0) - return; - -+ /* Run NET_RX_SOFTIRQ in order to free pending skbs in softnet_data -+ * defer_list that can stay in the list until we have enough queued -+ * traffic. -+ */ -+ local_irq_save(flags); -+ for_each_online_cpu(cpu) { -+ struct softnet_data *sd = &per_cpu(softnet_data, cpu); -+ -+ if (cpu == raw_smp_processor_id()) -+ raise_softirq_irqoff(NET_RX_SOFTIRQ); -+ else if (!cmpxchg(&sd->defer_ipi_scheduled, 0, 1)) -+ smp_call_function_single_async(cpu, &sd->defer_csd); -+ } -+ local_irq_restore(flags); -+ - /* Periodic warning for page pools the user can't see */ - netdev = READ_ONCE(pool->slow.netdev); - if (time_after_eq(jiffies, pool->defer_warn) && --- -2.51.0 - - -From 07c08919265a04b1535d18e75a8de2fc6644e6b9 Mon Sep 17 00:00:00 2001 -From: Kevin Darbyshire-Bryant -Date: Sat, 23 Mar 2019 09:29:49 +0000 -Subject: [PATCH 355/517] netfilter: connmark: introduce set-dscpmark - -set-dscpmark is a method of storing the DSCP of an ip packet into -conntrack mark. In combination with a suitable tc filter action -(act_ctinfo) DSCP values are able to be stored in the mark on egress and -restored on ingress across links that otherwise alter or bleach DSCP. - -This is useful for qdiscs such as CAKE which are able to shape according -to policies based on DSCP. - -Ingress classification is traditionally a challenging task since -iptables rules haven't yet run and tc filter/eBPF programs are pre-NAT -lookups, hence are unable to see internal IPv4 addresses as used on the -typical home masquerading gateway. - -x_tables CONNMARK set-dscpmark target solves the problem of storing the -DSCP to the conntrack mark in a way suitable for the new act_ctinfo tc -action to restore. - -The set-dscpmark option accepts 2 parameters, a 32bit 'dscpmask' and a -32bit 'statemask'. The dscp mask must be 6 contiguous bits and -represents the area where the DSCP will be stored in the connmark. The -state mask is a minimum 1 bit length mask that must not overlap with the -dscpmask. It represents a flag which is set when the DSCP has been -stored in the conntrack mark. This is useful to implement a 'one shot' -iptables based classification where the 'complicated' iptables rules are -only run once to classify the connection on initial (egress) packet and -subsequent packets are all marked/restored with the same DSCP. A state -mask of zero disables the setting of a status bit/s. - -example syntax with a suitably modified iptables user space application: - -iptables -A QOS_MARK_eth0 -t mangle -j CONNMARK --set-dscpmark 0xfc000000/0x01000000 - -Would store the DSCP in the top 6 bits of the 32bit mark field, and use -the LSB of the top byte as the 'DSCP has been stored' marker. - -|----0xFC----conntrack mark----000000---| -| Bits 31-26 | bit 25 | bit24 |~~~ Bit 0| -| DSCP | unused | flag |unused | -|-----------------------0x01---000000---| - ^ ^ - | | - ---| Conditional flag - | set this when dscp -|-ip diffserv-| stored in mark -| 6 bits | -|-------------| - -an identically configured tc action to restore looks like: - -tc filter show dev eth0 ingress -filter parent ffff: protocol all pref 10 u32 chain 0 -filter parent ffff: protocol all pref 10 u32 chain 0 fh 800: ht divisor 1 -filter parent ffff: protocol all pref 10 u32 chain 0 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1: not_in_hw - match 00000000/00000000 at 0 - action order 1: ctinfo zone 0 pipe - index 2 ref 1 bind 1 dscp 0xfc000000/0x1000000 - - action order 2: mirred (Egress Redirect to device ifb4eth0) stolen - index 1 ref 1 bind 1 - -|----0xFC----conntrack mark----000000---| -| Bits 31-26 | bit 25 | bit24 |~~~ Bit 0| -| DSCP | unused | flag |unused | -|-----------------------0x01---000000---| - | | - | | - ---| Conditional flag - v only restore if set -|-ip diffserv-| -| 6 bits | -|-------------| - -Signed-off-by: Kevin Darbyshire-Bryant ---- - include/uapi/linux/netfilter/xt_connmark.h | 10 ++++ - net/netfilter/xt_connmark.c | 67 ++++++++++++++++++---- - 2 files changed, 67 insertions(+), 10 deletions(-) - -diff --git a/include/uapi/linux/netfilter/xt_connmark.h b/include/uapi/linux/netfilter/xt_connmark.h -index 41b578ccd03b..1ef51bca5cc7 100644 ---- a/include/uapi/linux/netfilter/xt_connmark.h -+++ b/include/uapi/linux/netfilter/xt_connmark.h -@@ -14,6 +14,11 @@ enum { - XT_CONNMARK_RESTORE - }; - -+enum { -+ XT_CONNMARK_VALUE = (1 << 0), -+ XT_CONNMARK_DSCP = (1 << 1) -+}; -+ - enum { - D_SHIFT_LEFT = 0, - D_SHIFT_RIGHT, -@@ -29,6 +34,11 @@ struct xt_connmark_tginfo2 { - __u8 shift_dir, shift_bits, mode; - }; - -+struct xt_connmark_tginfo3 { -+ __u32 ctmark, ctmask, nfmask; -+ __u8 shift_dir, shift_bits, mode, func; -+}; -+ - struct xt_connmark_mtinfo1 { - __u32 mark, mask; - __u8 invert; -diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c -index 4277084de2e7..09e02d052ec7 100644 ---- a/net/netfilter/xt_connmark.c -+++ b/net/netfilter/xt_connmark.c -@@ -24,13 +24,13 @@ MODULE_ALIAS("ipt_connmark"); - MODULE_ALIAS("ip6t_connmark"); - - static unsigned int --connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo2 *info) -+connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo3 *info) - { - enum ip_conntrack_info ctinfo; - u_int32_t new_targetmark; - struct nf_conn *ct; - u_int32_t newmark; -- u_int32_t oldmark; -+ u_int8_t dscp; - - ct = nf_ct_get(skb, &ctinfo); - if (ct == NULL) -@@ -38,13 +38,24 @@ connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo2 *info) - - switch (info->mode) { - case XT_CONNMARK_SET: -- oldmark = READ_ONCE(ct->mark); -- newmark = (oldmark & ~info->ctmask) ^ info->ctmark; -- if (info->shift_dir == D_SHIFT_RIGHT) -- newmark >>= info->shift_bits; -- else -- newmark <<= info->shift_bits; -+ newmark = READ_ONCE(ct->mark); -+ if (info->func & XT_CONNMARK_VALUE) { -+ newmark = (newmark & ~info->ctmask) ^ info->ctmark; -+ if (info->shift_dir == D_SHIFT_RIGHT) -+ newmark >>= info->shift_bits; -+ else -+ newmark <<= info->shift_bits; -+ } else if (info->func & XT_CONNMARK_DSCP) { -+ if (skb->protocol == htons(ETH_P_IP)) -+ dscp = ipv4_get_dsfield(ip_hdr(skb)) >> 2; -+ else if (skb->protocol == htons(ETH_P_IPV6)) -+ dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> 2; -+ else /* protocol doesn't have diffserv */ -+ break; - -+ newmark = (newmark & ~info->ctmark) | -+ (info->ctmask | (dscp << info->shift_bits)); -+ } - if (READ_ONCE(ct->mark) != newmark) { - WRITE_ONCE(ct->mark, newmark); - nf_conntrack_event_cache(IPCT_MARK, ct); -@@ -83,20 +94,36 @@ static unsigned int - connmark_tg(struct sk_buff *skb, const struct xt_action_param *par) - { - const struct xt_connmark_tginfo1 *info = par->targinfo; -- const struct xt_connmark_tginfo2 info2 = { -+ const struct xt_connmark_tginfo3 info3 = { - .ctmark = info->ctmark, - .ctmask = info->ctmask, - .nfmask = info->nfmask, - .mode = info->mode, -+ .func = XT_CONNMARK_VALUE - }; - -- return connmark_tg_shift(skb, &info2); -+ return connmark_tg_shift(skb, &info3); - } - - static unsigned int - connmark_tg_v2(struct sk_buff *skb, const struct xt_action_param *par) - { - const struct xt_connmark_tginfo2 *info = par->targinfo; -+ const struct xt_connmark_tginfo3 info3 = { -+ .ctmark = info->ctmark, -+ .ctmask = info->ctmask, -+ .nfmask = info->nfmask, -+ .mode = info->mode, -+ .func = XT_CONNMARK_VALUE -+ }; -+ -+ return connmark_tg_shift(skb, &info3); -+} -+ -+static unsigned int -+connmark_tg_v3(struct sk_buff *skb, const struct xt_action_param *par) -+{ -+ const struct xt_connmark_tginfo3 *info = par->targinfo; - - return connmark_tg_shift(skb, info); - } -@@ -168,6 +195,16 @@ static struct xt_target connmark_tg_reg[] __read_mostly = { - .destroy = connmark_tg_destroy, - .me = THIS_MODULE, - }, -+ { -+ .name = "CONNMARK", -+ .revision = 3, -+ .family = NFPROTO_IPV4, -+ .checkentry = connmark_tg_check, -+ .target = connmark_tg_v3, -+ .targetsize = sizeof(struct xt_connmark_tginfo3), -+ .destroy = connmark_tg_destroy, -+ .me = THIS_MODULE, -+ }, - #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) - { - .name = "CONNMARK", -@@ -189,6 +226,16 @@ static struct xt_target connmark_tg_reg[] __read_mostly = { - .destroy = connmark_tg_destroy, - .me = THIS_MODULE, - }, -+ { -+ .name = "CONNMARK", -+ .revision = 3, -+ .family = NFPROTO_IPV6, -+ .checkentry = connmark_tg_check, -+ .target = connmark_tg_v3, -+ .targetsize = sizeof(struct xt_connmark_tginfo3), -+ .destroy = connmark_tg_destroy, -+ .me = THIS_MODULE, -+ }, - #endif - }; - --- -2.51.0 - - -From fd138131dfe7392f9794d929221cc4083f3661ed Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Tue, 20 Feb 2018 15:56:02 +0100 -Subject: [PATCH 356/517] netfilter: add xt_FLOWOFFLOAD target - -Signed-off-by: Felix Fietkau ---- - include/net/netfilter/nf_flow_table.h | 5 + - include/uapi/linux/netfilter/xt_FLOWOFFLOAD.h | 17 + - net/netfilter/Kconfig | 10 +- - net/netfilter/Makefile | 1 + - net/netfilter/nf_flow_table_core.c | 5 +- - net/netfilter/xt_FLOWOFFLOAD.c | 703 ++++++++++++++++++ - 6 files changed, 737 insertions(+), 4 deletions(-) - create mode 100644 include/uapi/linux/netfilter/xt_FLOWOFFLOAD.h - create mode 100644 net/netfilter/xt_FLOWOFFLOAD.c - -diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h -index 1a6fca013165..2709725ee8cc 100644 ---- a/include/net/netfilter/nf_flow_table.h -+++ b/include/net/netfilter/nf_flow_table.h -@@ -294,6 +294,11 @@ void nf_flow_table_free(struct nf_flowtable *flow_table); - - void flow_offload_teardown(struct flow_offload *flow); - -+int nf_flow_table_iterate(struct nf_flowtable *flow_table, -+ void (*iter)(struct nf_flowtable *flowtable, -+ struct flow_offload *flow, void *data), -+ void *data); -+ - void nf_flow_snat_port(const struct flow_offload *flow, - struct sk_buff *skb, unsigned int thoff, - u8 protocol, enum flow_offload_tuple_dir dir); -diff --git a/include/uapi/linux/netfilter/xt_FLOWOFFLOAD.h b/include/uapi/linux/netfilter/xt_FLOWOFFLOAD.h -new file mode 100644 -index 000000000000..5841bbe0e3db ---- /dev/null -+++ b/include/uapi/linux/netfilter/xt_FLOWOFFLOAD.h -@@ -0,0 +1,17 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -+#ifndef _XT_FLOWOFFLOAD_H -+#define _XT_FLOWOFFLOAD_H -+ -+#include -+ -+enum { -+ XT_FLOWOFFLOAD_HW = 1 << 0, -+ -+ XT_FLOWOFFLOAD_MASK = XT_FLOWOFFLOAD_HW -+}; -+ -+struct xt_flowoffload_target_info { -+ __u32 flags; -+}; -+ -+#endif /* _XT_FLOWOFFLOAD_H */ -diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig -index 944a47d0e2fd..e10e3b879121 100644 ---- a/net/netfilter/Kconfig -+++ b/net/netfilter/Kconfig -@@ -729,7 +729,6 @@ config NF_FLOW_TABLE - tristate "Netfilter flow table module" - depends on NETFILTER_INGRESS - depends on NF_CONNTRACK -- depends on NF_TABLES - help - This option adds the flow table core infrastructure. - -@@ -1025,6 +1024,15 @@ config NETFILTER_XT_TARGET_NOTRACK - depends on NETFILTER_ADVANCED - select NETFILTER_XT_TARGET_CT - -+config NETFILTER_XT_TARGET_FLOWOFFLOAD -+ tristate '"FLOWOFFLOAD" target support' -+ depends on NF_FLOW_TABLE -+ depends on NETFILTER_INGRESS -+ help -+ This option adds a `FLOWOFFLOAD' target, which uses the nf_flow_offload -+ module to speed up processing of packets by bypassing the usual -+ netfilter chains -+ - config NETFILTER_XT_TARGET_RATEEST - tristate '"RATEEST" target support' - depends on NETFILTER_ADVANCED -diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile -index f0aa4d7ef499..e9d11858a49b 100644 ---- a/net/netfilter/Makefile -+++ b/net/netfilter/Makefile -@@ -168,6 +168,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIFY) += xt_CLASSIFY.o - obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o - obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o - obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o -+obj-$(CONFIG_NETFILTER_XT_TARGET_FLOWOFFLOAD) += xt_FLOWOFFLOAD.o - obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o - obj-$(CONFIG_NETFILTER_XT_TARGET_HMARK) += xt_HMARK.o - obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o -diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c -index 54881f0e878a..f90303256229 100644 ---- a/net/netfilter/nf_flow_table_core.c -+++ b/net/netfilter/nf_flow_table_core.c -@@ -7,7 +7,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -373,8 +372,7 @@ flow_offload_lookup(struct nf_flowtable *flow_table, - } - EXPORT_SYMBOL_GPL(flow_offload_lookup); - --static int --nf_flow_table_iterate(struct nf_flowtable *flow_table, -+int nf_flow_table_iterate(struct nf_flowtable *flow_table, - void (*iter)(struct nf_flowtable *flowtable, - struct flow_offload *flow, void *data), - void *data) -@@ -435,6 +433,7 @@ static void nf_flow_offload_gc_step(struct nf_flowtable *flow_table, - nf_flow_offload_stats(flow_table, flow); - } - } -+EXPORT_SYMBOL_GPL(nf_flow_table_iterate); - - void nf_flow_table_gc_run(struct nf_flowtable *flow_table) - { -diff --git a/net/netfilter/xt_FLOWOFFLOAD.c b/net/netfilter/xt_FLOWOFFLOAD.c -new file mode 100644 -index 000000000000..08e0b945b4b0 ---- /dev/null -+++ b/net/netfilter/xt_FLOWOFFLOAD.c -@@ -0,0 +1,703 @@ -+/* -+ * Copyright (C) 2018-2021 Felix Fietkau -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+struct xt_flowoffload_hook { -+ struct hlist_node list; -+ struct nf_hook_ops ops; -+ struct net *net; -+ bool registered; -+ bool used; -+}; -+ -+struct xt_flowoffload_table { -+ struct nf_flowtable ft; -+ struct hlist_head hooks; -+ struct delayed_work work; -+}; -+ -+struct nf_forward_info { -+ const struct net_device *indev; -+ const struct net_device *outdev; -+ const struct net_device *hw_outdev; -+ struct id { -+ __u16 id; -+ __be16 proto; -+ } encap[NF_FLOW_TABLE_ENCAP_MAX]; -+ u8 num_encaps; -+ u8 ingress_vlans; -+ u8 h_source[ETH_ALEN]; -+ u8 h_dest[ETH_ALEN]; -+ enum flow_offload_xmit_type xmit_type; -+}; -+ -+static DEFINE_SPINLOCK(hooks_lock); -+ -+struct xt_flowoffload_table flowtable[2]; -+ -+static unsigned int -+xt_flowoffload_net_hook(void *priv, struct sk_buff *skb, -+ const struct nf_hook_state *state) -+{ -+ struct vlan_ethhdr *veth; -+ __be16 proto; -+ -+ switch (skb->protocol) { -+ case htons(ETH_P_8021Q): -+ veth = (struct vlan_ethhdr *)skb_mac_header(skb); -+ proto = veth->h_vlan_encapsulated_proto; -+ break; -+ case htons(ETH_P_PPP_SES): -+ if (!nf_flow_pppoe_proto(skb, &proto)) -+ return NF_ACCEPT; -+ break; -+ default: -+ proto = skb->protocol; -+ break; -+ } -+ -+ switch (proto) { -+ case htons(ETH_P_IP): -+ return nf_flow_offload_ip_hook(priv, skb, state); -+ case htons(ETH_P_IPV6): -+ return nf_flow_offload_ipv6_hook(priv, skb, state); -+ } -+ -+ return NF_ACCEPT; -+} -+ -+static int -+xt_flowoffload_create_hook(struct xt_flowoffload_table *table, -+ struct net_device *dev) -+{ -+ struct xt_flowoffload_hook *hook; -+ struct nf_hook_ops *ops; -+ -+ hook = kzalloc(sizeof(*hook), GFP_ATOMIC); -+ if (!hook) -+ return -ENOMEM; -+ -+ ops = &hook->ops; -+ ops->pf = NFPROTO_NETDEV; -+ ops->hooknum = NF_NETDEV_INGRESS; -+ ops->priority = 10; -+ ops->priv = &table->ft; -+ ops->hook = xt_flowoffload_net_hook; -+ ops->dev = dev; -+ -+ hlist_add_head(&hook->list, &table->hooks); -+ mod_delayed_work(system_power_efficient_wq, &table->work, 0); -+ -+ return 0; -+} -+ -+static struct xt_flowoffload_hook * -+flow_offload_lookup_hook(struct xt_flowoffload_table *table, -+ struct net_device *dev) -+{ -+ struct xt_flowoffload_hook *hook; -+ -+ hlist_for_each_entry(hook, &table->hooks, list) { -+ if (hook->ops.dev == dev) -+ return hook; -+ } -+ -+ return NULL; -+} -+ -+static void -+xt_flowoffload_check_device(struct xt_flowoffload_table *table, -+ struct net_device *dev) -+{ -+ struct xt_flowoffload_hook *hook; -+ -+ if (!dev) -+ return; -+ -+ spin_lock_bh(&hooks_lock); -+ hook = flow_offload_lookup_hook(table, dev); -+ if (hook) -+ hook->used = true; -+ else -+ xt_flowoffload_create_hook(table, dev); -+ spin_unlock_bh(&hooks_lock); -+} -+ -+static void -+xt_flowoffload_register_hooks(struct xt_flowoffload_table *table) -+{ -+ struct xt_flowoffload_hook *hook; -+ -+restart: -+ hlist_for_each_entry(hook, &table->hooks, list) { -+ if (hook->registered) -+ continue; -+ -+ hook->registered = true; -+ hook->net = dev_net(hook->ops.dev); -+ spin_unlock_bh(&hooks_lock); -+ nf_register_net_hook(hook->net, &hook->ops); -+ if (table->ft.flags & NF_FLOWTABLE_HW_OFFLOAD) -+ table->ft.type->setup(&table->ft, hook->ops.dev, -+ FLOW_BLOCK_BIND); -+ spin_lock_bh(&hooks_lock); -+ goto restart; -+ } -+ -+} -+ -+static bool -+xt_flowoffload_cleanup_hooks(struct xt_flowoffload_table *table) -+{ -+ struct xt_flowoffload_hook *hook; -+ bool active = false; -+ -+restart: -+ spin_lock_bh(&hooks_lock); -+ hlist_for_each_entry(hook, &table->hooks, list) { -+ if (hook->used || !hook->registered) { -+ active = true; -+ continue; -+ } -+ -+ hlist_del(&hook->list); -+ spin_unlock_bh(&hooks_lock); -+ if (table->ft.flags & NF_FLOWTABLE_HW_OFFLOAD) -+ table->ft.type->setup(&table->ft, hook->ops.dev, -+ FLOW_BLOCK_UNBIND); -+ nf_unregister_net_hook(hook->net, &hook->ops); -+ kfree(hook); -+ goto restart; -+ } -+ spin_unlock_bh(&hooks_lock); -+ -+ return active; -+} -+ -+static void -+xt_flowoffload_check_hook(struct nf_flowtable *flowtable, -+ struct flow_offload *flow, void *data) -+{ -+ struct xt_flowoffload_table *table; -+ struct flow_offload_tuple *tuple0 = &flow->tuplehash[0].tuple; -+ struct flow_offload_tuple *tuple1 = &flow->tuplehash[1].tuple; -+ struct xt_flowoffload_hook *hook; -+ -+ table = container_of(flowtable, struct xt_flowoffload_table, ft); -+ -+ spin_lock_bh(&hooks_lock); -+ hlist_for_each_entry(hook, &table->hooks, list) { -+ if (hook->ops.dev->ifindex != tuple0->iifidx && -+ hook->ops.dev->ifindex != tuple1->iifidx) -+ continue; -+ -+ hook->used = true; -+ } -+ spin_unlock_bh(&hooks_lock); -+} -+ -+static void -+xt_flowoffload_hook_work(struct work_struct *work) -+{ -+ struct xt_flowoffload_table *table; -+ struct xt_flowoffload_hook *hook; -+ int err; -+ -+ table = container_of(work, struct xt_flowoffload_table, work.work); -+ -+ spin_lock_bh(&hooks_lock); -+ xt_flowoffload_register_hooks(table); -+ hlist_for_each_entry(hook, &table->hooks, list) -+ hook->used = false; -+ spin_unlock_bh(&hooks_lock); -+ -+ err = nf_flow_table_iterate(&table->ft, xt_flowoffload_check_hook, -+ NULL); -+ if (err && err != -EAGAIN) -+ goto out; -+ -+ if (!xt_flowoffload_cleanup_hooks(table)) -+ return; -+ -+out: -+ queue_delayed_work(system_power_efficient_wq, &table->work, HZ); -+} -+ -+static bool -+xt_flowoffload_skip(struct sk_buff *skb, int family) -+{ -+ if (skb_sec_path(skb)) -+ return true; -+ -+ if (family == NFPROTO_IPV4) { -+ const struct ip_options *opt = &(IPCB(skb)->opt); -+ -+ if (unlikely(opt->optlen)) -+ return true; -+ } -+ -+ return false; -+} -+ -+static enum flow_offload_xmit_type nf_xmit_type(struct dst_entry *dst) -+{ -+ if (dst_xfrm(dst)) -+ return FLOW_OFFLOAD_XMIT_XFRM; -+ -+ return FLOW_OFFLOAD_XMIT_NEIGH; -+} -+ -+static void nf_default_forward_path(struct nf_flow_route *route, -+ struct dst_entry *dst_cache, -+ enum ip_conntrack_dir dir, -+ struct net_device **dev) -+{ -+ dev[!dir] = dst_cache->dev; -+ route->tuple[!dir].in.ifindex = dst_cache->dev->ifindex; -+ route->tuple[dir].dst = dst_cache; -+ route->tuple[dir].xmit_type = nf_xmit_type(dst_cache); -+} -+ -+static bool nf_is_valid_ether_device(const struct net_device *dev) -+{ -+ if (!dev || (dev->flags & IFF_LOOPBACK) || dev->type != ARPHRD_ETHER || -+ dev->addr_len != ETH_ALEN || !is_valid_ether_addr(dev->dev_addr)) -+ return false; -+ -+ return true; -+} -+ -+static void nf_dev_path_info(const struct net_device_path_stack *stack, -+ struct nf_forward_info *info, -+ unsigned char *ha) -+{ -+ const struct net_device_path *path; -+ int i; -+ -+ memcpy(info->h_dest, ha, ETH_ALEN); -+ -+ for (i = 0; i < stack->num_paths; i++) { -+ path = &stack->path[i]; -+ switch (path->type) { -+ case DEV_PATH_ETHERNET: -+ case DEV_PATH_DSA: -+ case DEV_PATH_VLAN: -+ case DEV_PATH_PPPOE: -+ info->indev = path->dev; -+ if (is_zero_ether_addr(info->h_source)) -+ memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN); -+ -+ if (path->type == DEV_PATH_ETHERNET) -+ break; -+ if (path->type == DEV_PATH_DSA) { -+ i = stack->num_paths; -+ break; -+ } -+ -+ /* DEV_PATH_VLAN and DEV_PATH_PPPOE */ -+ if (info->num_encaps >= NF_FLOW_TABLE_ENCAP_MAX) { -+ info->indev = NULL; -+ break; -+ } -+ if (!info->outdev) -+ info->outdev = path->dev; -+ info->encap[info->num_encaps].id = path->encap.id; -+ info->encap[info->num_encaps].proto = path->encap.proto; -+ info->num_encaps++; -+ if (path->type == DEV_PATH_PPPOE) -+ memcpy(info->h_dest, path->encap.h_dest, ETH_ALEN); -+ break; -+ case DEV_PATH_BRIDGE: -+ if (is_zero_ether_addr(info->h_source)) -+ memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN); -+ -+ switch (path->bridge.vlan_mode) { -+ case DEV_PATH_BR_VLAN_UNTAG_HW: -+ info->ingress_vlans |= BIT(info->num_encaps - 1); -+ break; -+ case DEV_PATH_BR_VLAN_TAG: -+ info->encap[info->num_encaps].id = path->bridge.vlan_id; -+ info->encap[info->num_encaps].proto = path->bridge.vlan_proto; -+ info->num_encaps++; -+ break; -+ case DEV_PATH_BR_VLAN_UNTAG: -+ info->num_encaps--; -+ break; -+ case DEV_PATH_BR_VLAN_KEEP: -+ break; -+ } -+ break; -+ default: -+ info->indev = NULL; -+ break; -+ } -+ } -+ if (!info->outdev) -+ info->outdev = info->indev; -+ -+ info->hw_outdev = info->indev; -+ -+ if (nf_is_valid_ether_device(info->indev)) -+ info->xmit_type = FLOW_OFFLOAD_XMIT_DIRECT; -+} -+ -+static int nf_dev_fill_forward_path(const struct nf_flow_route *route, -+ const struct dst_entry *dst_cache, -+ const struct nf_conn *ct, -+ enum ip_conntrack_dir dir, u8 *ha, -+ struct net_device_path_stack *stack) -+{ -+ const void *daddr = &ct->tuplehash[!dir].tuple.src.u3; -+ struct net_device *dev = dst_cache->dev; -+ struct neighbour *n; -+ u8 nud_state; -+ -+ if (!nf_is_valid_ether_device(dev)) -+ goto out; -+ -+ n = dst_neigh_lookup(dst_cache, daddr); -+ if (!n) -+ return -1; -+ -+ read_lock_bh(&n->lock); -+ nud_state = n->nud_state; -+ ether_addr_copy(ha, n->ha); -+ read_unlock_bh(&n->lock); -+ neigh_release(n); -+ -+ if (!(nud_state & NUD_VALID)) -+ return -1; -+ -+out: -+ return dev_fill_forward_path(dev, ha, stack); -+} -+ -+static void nf_dev_forward_path(struct nf_flow_route *route, -+ const struct nf_conn *ct, -+ enum ip_conntrack_dir dir, -+ struct net_device **devs) -+{ -+ const struct dst_entry *dst = route->tuple[dir].dst; -+ struct net_device_path_stack stack; -+ struct nf_forward_info info = {}; -+ unsigned char ha[ETH_ALEN]; -+ int i; -+ -+ if (nf_dev_fill_forward_path(route, dst, ct, dir, ha, &stack) >= 0) -+ nf_dev_path_info(&stack, &info, ha); -+ -+ devs[!dir] = (struct net_device *)info.indev; -+ if (!info.indev) -+ return; -+ -+ route->tuple[!dir].in.ifindex = info.indev->ifindex; -+ for (i = 0; i < info.num_encaps; i++) { -+ route->tuple[!dir].in.encap[i].id = info.encap[i].id; -+ route->tuple[!dir].in.encap[i].proto = info.encap[i].proto; -+ } -+ route->tuple[!dir].in.num_encaps = info.num_encaps; -+ route->tuple[!dir].in.ingress_vlans = info.ingress_vlans; -+ -+ if (info.xmit_type == FLOW_OFFLOAD_XMIT_DIRECT) { -+ memcpy(route->tuple[dir].out.h_source, info.h_source, ETH_ALEN); -+ memcpy(route->tuple[dir].out.h_dest, info.h_dest, ETH_ALEN); -+ route->tuple[dir].out.ifindex = info.outdev->ifindex; -+ route->tuple[dir].out.hw_ifindex = info.hw_outdev->ifindex; -+ route->tuple[dir].xmit_type = info.xmit_type; -+ } -+} -+ -+static int -+xt_flowoffload_route(struct sk_buff *skb, const struct nf_conn *ct, -+ const struct xt_action_param *par, -+ struct nf_flow_route *route, enum ip_conntrack_dir dir, -+ struct net_device **devs) -+{ -+ struct dst_entry *this_dst = skb_dst(skb); -+ struct dst_entry *other_dst = NULL; -+ struct flowi fl; -+ -+ memset(&fl, 0, sizeof(fl)); -+ switch (xt_family(par)) { -+ case NFPROTO_IPV4: -+ fl.u.ip4.daddr = ct->tuplehash[dir].tuple.src.u3.ip; -+ fl.u.ip4.flowi4_oif = xt_in(par)->ifindex; -+ break; -+ case NFPROTO_IPV6: -+ fl.u.ip6.saddr = ct->tuplehash[!dir].tuple.dst.u3.in6; -+ fl.u.ip6.daddr = ct->tuplehash[dir].tuple.src.u3.in6; -+ fl.u.ip6.flowi6_oif = xt_in(par)->ifindex; -+ break; -+ } -+ -+ if (!dst_hold_safe(this_dst)) -+ return -ENOENT; -+ -+ nf_route(xt_net(par), &other_dst, &fl, false, xt_family(par)); -+ if (!other_dst) { -+ dst_release(this_dst); -+ return -ENOENT; -+ } -+ -+ nf_default_forward_path(route, this_dst, dir, devs); -+ nf_default_forward_path(route, other_dst, !dir, devs); -+ -+ if (route->tuple[dir].xmit_type == FLOW_OFFLOAD_XMIT_NEIGH && -+ route->tuple[!dir].xmit_type == FLOW_OFFLOAD_XMIT_NEIGH) { -+ nf_dev_forward_path(route, ct, dir, devs); -+ nf_dev_forward_path(route, ct, !dir, devs); -+ } -+ -+ return 0; -+} -+ -+static unsigned int -+flowoffload_tg(struct sk_buff *skb, const struct xt_action_param *par) -+{ -+ struct xt_flowoffload_table *table; -+ const struct xt_flowoffload_target_info *info = par->targinfo; -+ struct tcphdr _tcph, *tcph = NULL; -+ enum ip_conntrack_info ctinfo; -+ enum ip_conntrack_dir dir; -+ struct nf_flow_route route = {}; -+ struct flow_offload *flow = NULL; -+ struct net_device *devs[2] = {}; -+ struct nf_conn *ct; -+ struct net *net; -+ -+ if (xt_flowoffload_skip(skb, xt_family(par))) -+ return XT_CONTINUE; -+ -+ ct = nf_ct_get(skb, &ctinfo); -+ if (ct == NULL) -+ return XT_CONTINUE; -+ -+ switch (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum) { -+ case IPPROTO_TCP: -+ if (ct->proto.tcp.state != TCP_CONNTRACK_ESTABLISHED) -+ return XT_CONTINUE; -+ -+ tcph = skb_header_pointer(skb, par->thoff, -+ sizeof(_tcph), &_tcph); -+ if (unlikely(!tcph || tcph->fin || tcph->rst)) -+ return XT_CONTINUE; -+ break; -+ case IPPROTO_UDP: -+ break; -+ default: -+ return XT_CONTINUE; -+ } -+ -+ if (nf_ct_ext_exist(ct, NF_CT_EXT_HELPER) || -+ ct->status & (IPS_SEQ_ADJUST | IPS_NAT_CLASH)) -+ return XT_CONTINUE; -+ -+ if (!nf_ct_is_confirmed(ct)) -+ return XT_CONTINUE; -+ -+ dir = CTINFO2DIR(ctinfo); -+ -+ devs[dir] = xt_out(par); -+ devs[!dir] = xt_in(par); -+ -+ if (!devs[dir] || !devs[!dir]) -+ return XT_CONTINUE; -+ -+ if (test_and_set_bit(IPS_OFFLOAD_BIT, &ct->status)) -+ return XT_CONTINUE; -+ -+ if (xt_flowoffload_route(skb, ct, par, &route, dir, devs) < 0) -+ goto err_flow_route; -+ -+ flow = flow_offload_alloc(ct); -+ if (!flow) -+ goto err_flow_alloc; -+ -+ flow_offload_route_init(flow, &route); -+ -+ if (tcph) { -+ ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; -+ ct->proto.tcp.seen[1].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; -+ } -+ -+ table = &flowtable[!!(info->flags & XT_FLOWOFFLOAD_HW)]; -+ -+ net = read_pnet(&table->ft.net); -+ if (!net) -+ write_pnet(&table->ft.net, xt_net(par)); -+ -+ __set_bit(NF_FLOW_HW_BIDIRECTIONAL, &flow->flags); -+ if (flow_offload_add(&table->ft, flow) < 0) -+ goto err_flow_add; -+ -+ xt_flowoffload_check_device(table, devs[0]); -+ xt_flowoffload_check_device(table, devs[1]); -+ -+ return XT_CONTINUE; -+ -+err_flow_add: -+ flow_offload_free(flow); -+err_flow_alloc: -+ dst_release(route.tuple[dir].dst); -+ dst_release(route.tuple[!dir].dst); -+err_flow_route: -+ clear_bit(IPS_OFFLOAD_BIT, &ct->status); -+ -+ return XT_CONTINUE; -+} -+ -+static int flowoffload_chk(const struct xt_tgchk_param *par) -+{ -+ struct xt_flowoffload_target_info *info = par->targinfo; -+ -+ if (info->flags & ~XT_FLOWOFFLOAD_MASK) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static struct xt_target offload_tg_reg __read_mostly = { -+ .family = NFPROTO_UNSPEC, -+ .name = "FLOWOFFLOAD", -+ .revision = 0, -+ .targetsize = sizeof(struct xt_flowoffload_target_info), -+ .usersize = sizeof(struct xt_flowoffload_target_info), -+ .checkentry = flowoffload_chk, -+ .target = flowoffload_tg, -+ .me = THIS_MODULE, -+}; -+ -+static int flow_offload_netdev_event(struct notifier_block *this, -+ unsigned long event, void *ptr) -+{ -+ struct xt_flowoffload_hook *hook0, *hook1; -+ struct net_device *dev = netdev_notifier_info_to_dev(ptr); -+ -+ if (event != NETDEV_UNREGISTER) -+ return NOTIFY_DONE; -+ -+ spin_lock_bh(&hooks_lock); -+ hook0 = flow_offload_lookup_hook(&flowtable[0], dev); -+ if (hook0) -+ hlist_del(&hook0->list); -+ -+ hook1 = flow_offload_lookup_hook(&flowtable[1], dev); -+ if (hook1) -+ hlist_del(&hook1->list); -+ spin_unlock_bh(&hooks_lock); -+ -+ if (hook0) { -+ nf_unregister_net_hook(hook0->net, &hook0->ops); -+ kfree(hook0); -+ } -+ -+ if (hook1) { -+ nf_unregister_net_hook(hook1->net, &hook1->ops); -+ kfree(hook1); -+ } -+ -+ nf_flow_table_cleanup(dev); -+ -+ return NOTIFY_DONE; -+} -+ -+static struct notifier_block flow_offload_netdev_notifier = { -+ .notifier_call = flow_offload_netdev_event, -+}; -+ -+static int nf_flow_rule_route_inet(struct net *net, -+ struct flow_offload *flow, -+ enum flow_offload_tuple_dir dir, -+ struct nf_flow_rule *flow_rule) -+{ -+ const struct flow_offload_tuple *flow_tuple = &flow->tuplehash[dir].tuple; -+ int err; -+ -+ switch (flow_tuple->l3proto) { -+ case NFPROTO_IPV4: -+ err = nf_flow_rule_route_ipv4(net, flow, dir, flow_rule); -+ break; -+ case NFPROTO_IPV6: -+ err = nf_flow_rule_route_ipv6(net, flow, dir, flow_rule); -+ break; -+ default: -+ err = -1; -+ break; -+ } -+ -+ return err; -+} -+ -+static struct nf_flowtable_type flowtable_inet = { -+ .family = NFPROTO_INET, -+ .init = nf_flow_table_init, -+ .setup = nf_flow_table_offload_setup, -+ .action = nf_flow_rule_route_inet, -+ .free = nf_flow_table_free, -+ .hook = xt_flowoffload_net_hook, -+ .owner = THIS_MODULE, -+}; -+ -+static int init_flowtable(struct xt_flowoffload_table *tbl) -+{ -+ INIT_DELAYED_WORK(&tbl->work, xt_flowoffload_hook_work); -+ tbl->ft.type = &flowtable_inet; -+ tbl->ft.flags = NF_FLOWTABLE_COUNTER; -+ -+ return nf_flow_table_init(&tbl->ft); -+} -+ -+static int __init xt_flowoffload_tg_init(void) -+{ -+ int ret; -+ -+ register_netdevice_notifier(&flow_offload_netdev_notifier); -+ -+ ret = init_flowtable(&flowtable[0]); -+ if (ret) -+ return ret; -+ -+ ret = init_flowtable(&flowtable[1]); -+ if (ret) -+ goto cleanup; -+ -+ flowtable[1].ft.flags |= NF_FLOWTABLE_HW_OFFLOAD; -+ -+ ret = xt_register_target(&offload_tg_reg); -+ if (ret) -+ goto cleanup2; -+ -+ return 0; -+ -+cleanup2: -+ nf_flow_table_free(&flowtable[1].ft); -+cleanup: -+ nf_flow_table_free(&flowtable[0].ft); -+ return ret; -+} -+ -+static void __exit xt_flowoffload_tg_exit(void) -+{ -+ xt_unregister_target(&offload_tg_reg); -+ unregister_netdevice_notifier(&flow_offload_netdev_notifier); -+ nf_flow_table_free(&flowtable[0].ft); -+ nf_flow_table_free(&flowtable[1].ft); -+} -+ -+MODULE_LICENSE("GPL"); -+module_init(xt_flowoffload_tg_init); -+module_exit(xt_flowoffload_tg_exit); --- -2.51.0 - - -From a0ee647309aad3970467977ed72824d7c453aba4 Mon Sep 17 00:00:00 2001 -From: Imre Kaloz -Date: Fri, 7 Jul 2017 17:21:05 +0200 -Subject: [PATCH 357/517] mac80211: increase wireless mesh header size - -lede-commit 3d4466cfd8f75f717efdb1f96fdde3c70d865fc1 -Signed-off-by: Imre Kaloz ---- - include/linux/netdevice.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h -index c0a26b22f590..0f68392e0199 100644 ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -159,8 +159,8 @@ static inline bool dev_xmit_complete(int rc) - - #if defined(CONFIG_HYPERV_NET) - # define LL_MAX_HEADER 128 --#elif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25) --# if defined(CONFIG_MAC80211_MESH) -+#elif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25) || 1 -+# if defined(CONFIG_MAC80211_MESH) || 1 - # define LL_MAX_HEADER 128 - # else - # define LL_MAX_HEADER 96 --- -2.51.0 - - -From 0444c74d164efb1fdec620766fd416d88fb65d4d Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 7 Jul 2017 17:21:53 +0200 -Subject: [PATCH 358/517] hack: net: fq_codel: tune defaults for small devices - -Assume that x86_64 devices always have a big memory and do not need this -optimization compared to devices with only 32 MB or 64 MB RAM. - -Signed-off-by: Felix Fietkau ---- - net/sched/sch_fq_codel.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c -index 551b7cbdae90..9f8741081cef 100644 ---- a/net/sched/sch_fq_codel.c -+++ b/net/sched/sch_fq_codel.c -@@ -472,7 +472,11 @@ static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt, - - sch->limit = 10*1024; - q->flows_cnt = 1024; -+#ifdef CONFIG_X86_64 - q->memory_limit = 32 << 20; /* 32 MBytes */ -+#else -+ q->memory_limit = 4 << 20; /* 4 MBytes */ -+#endif - q->drop_batch_size = 64; - q->quantum = psched_mtu(qdisc_dev(sch)); - INIT_LIST_HEAD(&q->new_flows); --- -2.51.0 - - -From 8bbcca90b9c5ef9e32a374a259d0ae25f128c95e Mon Sep 17 00:00:00 2001 -From: Rui Salvaterra -Date: Wed, 30 Mar 2022 22:51:55 +0100 -Subject: [PATCH 359/517] kernel: ct: size the hashtable more adequately - -To set the default size of the connection tracking hash table, a divider of -16384 becomes inadequate for a router handling lots of connections. Divide by -2048 instead, making the default size scale better with the available RAM. - -Signed-off-by: Rui Salvaterra ---- - net/netfilter/nf_conntrack_core.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c -index f5bde4f13958..cdcc01fcd30f 100644 ---- a/net/netfilter/nf_conntrack_core.c -+++ b/net/netfilter/nf_conntrack_core.c -@@ -2648,7 +2648,7 @@ int nf_conntrack_init_start(void) - - if (!nf_conntrack_htable_size) { - nf_conntrack_htable_size -- = (((nr_pages << PAGE_SHIFT) / 16384) -+ = (((nr_pages << PAGE_SHIFT) / 2048) - / sizeof(struct hlist_head)); - if (BITS_PER_LONG >= 64 && - nr_pages > (4 * (1024 * 1024 * 1024 / PAGE_SIZE))) --- -2.51.0 - - -From 2b0f67440761e35ef5eb7a2f3bc1e3d47deabf3c Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 7 Jul 2017 17:24:23 +0200 -Subject: [PATCH 360/517] net: swconfig: adds openwrt switch layer - -Signed-off-by: Felix Fietkau ---- - drivers/net/phy/Kconfig | 74 +++++++++++++++++++++++++++++++ - drivers/net/phy/Makefile | 15 +++++++ - include/linux/platform_data/b53.h | 3 ++ - 3 files changed, 92 insertions(+) - -diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig -index 8c92405b84d4..7b1a94e8aa8b 100644 ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -77,6 +77,80 @@ config SFP - depends on HWMON || HWMON=n - select MDIO_I2C - -+comment "Switch configuration API + drivers" -+ -+config SWCONFIG -+ tristate "Switch configuration API" -+ help -+ Switch configuration API using netlink. This allows -+ you to configure the VLAN features of certain switches. -+ -+config SWCONFIG_LEDS -+ bool "Switch LED trigger support" -+ depends on (SWCONFIG && LEDS_TRIGGERS) -+ -+config ADM6996_PHY -+ tristate "Driver for ADM6996 switches" -+ select SWCONFIG -+ help -+ Currently supports the ADM6996FC and ADM6996M switches. -+ Support for FC is very limited. -+ -+config AR8216_PHY -+ tristate "Driver for Atheros AR8216/8327 switches" -+ select SWCONFIG -+ select ETHERNET_PACKET_MANGLE -+ -+config AR8216_PHY_LEDS -+ bool "Atheros AR8216 switch LED support" -+ depends on (AR8216_PHY && LEDS_CLASS) -+ -+source "drivers/net/phy/b53/Kconfig" -+ -+config IP17XX_PHY -+ tristate "Driver for IC+ IP17xx switches" -+ select SWCONFIG -+ -+config PSB6970_PHY -+ tristate "Lantiq XWAY Tantos (PSB6970) Ethernet switch" -+ select SWCONFIG -+ -+config RTL8306_PHY -+ tristate "Driver for Realtek RTL8306S switches" -+ select SWCONFIG -+ -+config RTL8366_SMI -+ tristate "Driver for the RTL8366 SMI interface" -+ depends on GPIOLIB -+ help -+ This module implements the SMI interface protocol which is used -+ by some RTL8366 ethernet switch devices via the generic GPIO API. -+ -+if RTL8366_SMI -+ -+config RTL8366_SMI_DEBUG_FS -+ bool "RTL8366 SMI interface debugfs support" -+ depends on DEBUG_FS -+ default n -+ -+config RTL8366S_PHY -+ tristate "Driver for the Realtek RTL8366S switch" -+ select SWCONFIG -+ -+config RTL8366RB_PHY -+ tristate "Driver for the Realtek RTL8366RB switch" -+ select SWCONFIG -+ -+config RTL8367_PHY -+ tristate "Driver for the Realtek RTL8367R/M switches" -+ select SWCONFIG -+ -+config RTL8367B_PHY -+ tristate "Driver for the Realtek RTL8367R-VB switch" -+ select SWCONFIG -+ -+endif # RTL8366_SMI -+ - comment "MII PHY device drivers" - - config AS21XXX_PHY -diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile -index a9080b8d604e..5fefb4d699fb 100644 ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -27,6 +27,21 @@ libphy-$(CONFIG_OPEN_ALLIANCE_HELPERS) += open_alliance_helpers.o - obj-$(CONFIG_PHYLINK) += phylink.o - obj-$(CONFIG_PHYLIB) += libphy.o - -+obj-$(CONFIG_SWCONFIG) += swconfig.o -+obj-$(CONFIG_ADM6996_PHY) += adm6996.o -+obj-$(CONFIG_AR8216_PHY) += ar8xxx.o -+ar8xxx-y += ar8216.o -+ar8xxx-y += ar8327.o -+obj-$(CONFIG_SWCONFIG_B53) += b53/ -+obj-$(CONFIG_IP17XX_PHY) += ip17xx.o -+obj-$(CONFIG_PSB6970_PHY) += psb6970.o -+obj-$(CONFIG_RTL8306_PHY) += rtl8306.o -+obj-$(CONFIG_RTL8366_SMI) += rtl8366_smi.o -+obj-$(CONFIG_RTL8366S_PHY) += rtl8366s.o -+obj-$(CONFIG_RTL8366RB_PHY) += rtl8366rb.o -+obj-$(CONFIG_RTL8367_PHY) += rtl8367.o -+obj-$(CONFIG_RTL8367B_PHY) += rtl8367b.o -+ - obj-$(CONFIG_NETWORK_PHY_TIMESTAMPING) += mii_timestamper.o - - obj-$(CONFIG_SFP) += sfp.o -diff --git a/include/linux/platform_data/b53.h b/include/linux/platform_data/b53.h -index 6f6fed2b171d..2d90457926e5 100644 ---- a/include/linux/platform_data/b53.h -+++ b/include/linux/platform_data/b53.h -@@ -29,6 +29,9 @@ struct b53_platform_data { - u32 chip_id; - u16 enabled_ports; - -+ /* allow to specify an ethX alias */ -+ const char *alias; -+ - /* only used by MMAP'd driver */ - unsigned big_endian:1; - void __iomem *regs; --- -2.51.0 - - -From 18a667d953110fd776c1a9850bc80c9290fa7527 Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 13:45:56 +0200 -Subject: [PATCH 361/517] net/dsa/mv88e6xxx: disable ATU violation - ---- - drivers/net/dsa/mv88e6xxx/chip.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c -index 43e0482fe1fd..2b547c2a7f43 100644 ---- a/drivers/net/dsa/mv88e6xxx/chip.c -+++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -3582,6 +3582,9 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port) - else - reg = 1 << port; - -+ /* Disable ATU member violation interrupt */ -+ reg |= MV88E6XXX_PORT_ASSOC_VECTOR_IGNORE_WRONG; -+ - err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ASSOC_VECTOR, - reg); - if (err) --- -2.51.0 - - -From b3147d8d726ee0e591bb977db46056fa51385934 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 7 Jul 2017 17:25:00 +0200 -Subject: [PATCH 362/517] net: add packet mangeling - -ar8216 switches have a hardware bug, which renders normal 802.1q support -unusable. Packet mangling is required to fix up the vlan for incoming -packets. - -Signed-off-by: Felix Fietkau ---- - include/linux/netdevice.h | 10 ++++++++++ - include/linux/skbuff.h | 14 ++++---------- - net/Kconfig | 6 ++++++ - net/core/dev.c | 5 +++++ - net/core/skbuff.c | 17 +++++++++++++++++ - net/ethernet/eth.c | 6 ++++++ - 6 files changed, 48 insertions(+), 10 deletions(-) - -diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h -index 0f68392e0199..1d2dd73b6091 100644 ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -1687,6 +1687,7 @@ enum netdev_priv_flags { - IFF_L3MDEV_RX_HANDLER = 1<<29, - IFF_NO_ADDRCONF = BIT_ULL(30), - IFF_TX_SKB_NO_LINEAR = BIT_ULL(31), -+ IFF_NO_IP_ALIGN = BIT_ULL(32), - }; - - /* Specifies the type of the struct net_device::ml_priv pointer */ -@@ -2168,6 +2169,11 @@ struct net_device { - const struct tlsdev_ops *tlsdev_ops; - #endif - -+#ifdef CONFIG_ETHERNET_PACKET_MANGLE -+ void (*eth_mangle_rx)(struct net_device *dev, struct sk_buff *skb); -+ struct sk_buff *(*eth_mangle_tx)(struct net_device *dev, struct sk_buff *skb); -+#endif -+ - unsigned int operstate; - unsigned char link_mode; - -@@ -2237,6 +2243,10 @@ struct net_device { - struct mctp_dev __rcu *mctp_ptr; - #endif - -+#ifdef CONFIG_ETHERNET_PACKET_MANGLE -+ void *phy_ptr; /* PHY device specific data */ -+#endif -+ - /* - * Cache lines mostly used on receive path (including eth_type_trans()) - */ -diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h -index eb7b94939f46..d689ea0fa9f2 100644 ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -3242,6 +3242,10 @@ static inline int pskb_trim(struct sk_buff *skb, unsigned int len) - return (len < skb->len) ? __pskb_trim(skb, len) : 0; - } - -+extern struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev, -+ unsigned int length, gfp_t gfp); -+ -+ - /** - * pskb_trim_unique - remove end from a paged unique (not cloned) buffer - * @skb: buffer to alter -@@ -3407,16 +3411,6 @@ static inline struct sk_buff *dev_alloc_skb(unsigned int length) - } - - --static inline struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev, -- unsigned int length, gfp_t gfp) --{ -- struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp); -- -- if (NET_IP_ALIGN && skb) -- skb_reserve(skb, NET_IP_ALIGN); -- return skb; --} -- - static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev, - unsigned int length) - { -diff --git a/net/Kconfig b/net/Kconfig -index 6744f55d9683..c98df432683b 100644 ---- a/net/Kconfig -+++ b/net/Kconfig -@@ -26,6 +26,12 @@ menuconfig NET - - if NET - -+config ETHERNET_PACKET_MANGLE -+ bool -+ help -+ This option can be selected by phy drivers that need to mangle -+ packets going in or out of an ethernet device. -+ - config WANT_COMPAT_NETLINK_MESSAGES - bool - help -diff --git a/net/core/dev.c b/net/core/dev.c -index cfd32bd02a69..30a22db52d58 100644 ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -3658,6 +3658,11 @@ static int xmit_one(struct sk_buff *skb, struct net_device *dev, - if (dev_nit_active(dev)) - dev_queue_xmit_nit(skb, dev); - -+#ifdef CONFIG_ETHERNET_PACKET_MANGLE -+ if (dev->eth_mangle_tx && !(skb = dev->eth_mangle_tx(dev, skb))) -+ return NETDEV_TX_OK; -+#endif -+ - len = skb->len; - trace_net_dev_start_xmit(skb, dev); - rc = netdev_start_xmit(skb, dev, txq, more); -diff --git a/net/core/skbuff.c b/net/core/skbuff.c -index 6a92c03ee6f4..0a8628524de9 100644 ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -64,6 +64,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -326,6 +327,22 @@ void *__napi_alloc_frag_align(unsigned int fragsz, unsigned int align_mask) - } - EXPORT_SYMBOL(__napi_alloc_frag_align); - -+struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev, -+ unsigned int length, gfp_t gfp) -+{ -+ struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp); -+ -+#ifdef CONFIG_ETHERNET_PACKET_MANGLE -+ if (dev && (dev->priv_flags & IFF_NO_IP_ALIGN)) -+ return skb; -+#endif -+ -+ if (NET_IP_ALIGN && skb) -+ skb_reserve(skb, NET_IP_ALIGN); -+ return skb; -+} -+EXPORT_SYMBOL(__netdev_alloc_skb_ip_align); -+ - void *__netdev_alloc_frag_align(unsigned int fragsz, unsigned int align_mask) - { - void *data; -diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c -index 4e3651101b86..b7fb89299528 100644 ---- a/net/ethernet/eth.c -+++ b/net/ethernet/eth.c -@@ -159,6 +159,12 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev) - const struct ethhdr *eth; - - skb->dev = dev; -+ -+#ifdef CONFIG_ETHERNET_PACKET_MANGLE -+ if (dev->eth_mangle_rx) -+ dev->eth_mangle_rx(dev, skb); -+#endif -+ - skb_reset_mac_header(skb); - - eth = eth_skb_pull_mac(skb); --- -2.51.0 - - -From 2fb8b4eee5e48e4522386d31f25989d55aedab32 Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Tue, 27 Aug 2019 15:16:56 +0300 -Subject: [PATCH 363/517] drivers: net: phy: aquantia: enable AQR112 and AQR412 - -Adds support for AQR112 and AQR412 which is mostly based on existing code -with the addition of code configuring the protocol on system side. -This allows changing the system side protocol without having to deploy a -different firmware on the PHY. - -Signed-off-by: Alex Marginean ---- - drivers/net/phy/aquantia/aquantia_main.c | 72 +++++++++++++++++++++++- - 1 file changed, 70 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c -index 2008b98c689e..542c4d0d699e 100644 ---- a/drivers/net/phy/aquantia/aquantia_main.c -+++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -97,6 +97,29 @@ - #define AQR107_OP_IN_PROG_SLEEP 1000 - #define AQR107_OP_IN_PROG_TIMEOUT 100000 - -+/* registers in MDIO_MMD_VEND1 region */ -+#define AQUANTIA_VND1_GLOBAL_SC 0x000 -+#define AQUANTIA_VND1_GLOBAL_SC_LP BIT(0xb) -+ -+/* global start rate, the protocol associated with this speed is used by default -+ * on SI. -+ */ -+#define AQUANTIA_VND1_GSTART_RATE 0x31a -+#define AQUANTIA_VND1_GSTART_RATE_OFF 0 -+#define AQUANTIA_VND1_GSTART_RATE_100M 1 -+#define AQUANTIA_VND1_GSTART_RATE_1G 2 -+#define AQUANTIA_VND1_GSTART_RATE_10G 3 -+#define AQUANTIA_VND1_GSTART_RATE_2_5G 4 -+#define AQUANTIA_VND1_GSTART_RATE_5G 5 -+ -+/* SYSCFG registers for 100M, 1G, 2.5G, 5G, 10G */ -+#define AQUANTIA_VND1_GSYSCFG_BASE 0x31b -+#define AQUANTIA_VND1_GSYSCFG_100M 0 -+#define AQUANTIA_VND1_GSYSCFG_1G 1 -+#define AQUANTIA_VND1_GSYSCFG_2_5G 2 -+#define AQUANTIA_VND1_GSYSCFG_5G 3 -+#define AQUANTIA_VND1_GSYSCFG_10G 4 -+ - static int aqr107_get_sset_count(struct phy_device *phydev) - { - return AQR107_SGMII_STAT_SZ; -@@ -203,6 +226,51 @@ static int aqr_config_aneg(struct phy_device *phydev) - return genphy_c45_check_and_restart_aneg(phydev, changed); - } - -+static struct { -+ u16 syscfg; -+ int cnt; -+ u16 start_rate; -+} aquantia_syscfg[PHY_INTERFACE_MODE_MAX] = { -+ [PHY_INTERFACE_MODE_SGMII] = {0x04b, AQUANTIA_VND1_GSYSCFG_1G, -+ AQUANTIA_VND1_GSTART_RATE_1G}, -+ [PHY_INTERFACE_MODE_2500BASEX] = {0x144, AQUANTIA_VND1_GSYSCFG_2_5G, -+ AQUANTIA_VND1_GSTART_RATE_2_5G}, -+ [PHY_INTERFACE_MODE_XGMII] = {0x100, AQUANTIA_VND1_GSYSCFG_10G, -+ AQUANTIA_VND1_GSTART_RATE_10G}, -+ [PHY_INTERFACE_MODE_USXGMII] = {0x080, AQUANTIA_VND1_GSYSCFG_10G, -+ AQUANTIA_VND1_GSTART_RATE_10G}, -+}; -+ -+/* Sets up protocol on system side before calling aqr_config_aneg */ -+static int aqr_config_aneg_set_prot(struct phy_device *phydev) -+{ -+ int if_type = phydev->interface; -+ int i; -+ -+ if (!aquantia_syscfg[if_type].cnt) -+ return 0; -+ -+ /* set PHY in low power mode so we can configure protocols */ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GLOBAL_SC, -+ AQUANTIA_VND1_GLOBAL_SC_LP); -+ mdelay(10); -+ -+ /* set the default rate to enable the SI link */ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GSTART_RATE, -+ aquantia_syscfg[if_type].start_rate); -+ -+ for (i = 0; i <= aquantia_syscfg[if_type].cnt; i++) -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, -+ AQUANTIA_VND1_GSYSCFG_BASE + i, -+ aquantia_syscfg[if_type].syscfg); -+ -+ /* wake PHY back up */ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GLOBAL_SC, 0); -+ mdelay(10); -+ -+ return aqr_config_aneg(phydev); -+} -+ - static int aqr_config_intr(struct phy_device *phydev) - { - bool en = phydev->interrupts == PHY_INTERRUPT_ENABLED; -@@ -972,7 +1040,7 @@ static struct phy_driver aqr_driver[] = { - PHY_ID_MATCH_MODEL(PHY_ID_AQR112), - .name = "Aquantia AQR112", - .probe = aqr107_probe, -- .config_aneg = aqr_config_aneg, -+ .config_aneg = aqr_config_aneg_set_prot, - .config_intr = aqr_config_intr, - .handle_interrupt = aqr_handle_interrupt, - .get_tunable = aqr107_get_tunable, -@@ -995,7 +1063,7 @@ static struct phy_driver aqr_driver[] = { - PHY_ID_MATCH_MODEL(PHY_ID_AQR412), - .name = "Aquantia AQR412", - .probe = aqr107_probe, -- .config_aneg = aqr_config_aneg, -+ .config_aneg = aqr_config_aneg_set_prot, - .config_intr = aqr_config_intr, - .handle_interrupt = aqr_handle_interrupt, - .get_tunable = aqr107_get_tunable, --- -2.51.0 - - -From 36bebde61759d445e0eef0559c74377af98a3bbc Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Fri, 20 Sep 2019 18:22:52 +0300 -Subject: [PATCH 364/517] drivers: net: phy: aquantia: fix system side protocol - misconfiguration - -Do not set up protocols for speeds that are not supported by FW. Enabling -these protocols leads to link issues on system side. - -Signed-off-by: Alex Marginean ---- - drivers/net/phy/aquantia/aquantia_main.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c -index 542c4d0d699e..a5269b7ec26d 100644 ---- a/drivers/net/phy/aquantia/aquantia_main.c -+++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -259,10 +259,16 @@ static int aqr_config_aneg_set_prot(struct phy_device *phydev) - phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GSTART_RATE, - aquantia_syscfg[if_type].start_rate); - -- for (i = 0; i <= aquantia_syscfg[if_type].cnt; i++) -+ for (i = 0; i <= aquantia_syscfg[if_type].cnt; i++) { -+ u16 reg = phy_read_mmd(phydev, MDIO_MMD_VEND1, -+ AQUANTIA_VND1_GSYSCFG_BASE + i); -+ if (!reg) -+ continue; -+ - phy_write_mmd(phydev, MDIO_MMD_VEND1, - AQUANTIA_VND1_GSYSCFG_BASE + i, - aquantia_syscfg[if_type].syscfg); -+ } - - /* wake PHY back up */ - phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GLOBAL_SC, 0); --- -2.51.0 - - -From 9d7a3fd6822d5ea9dcd306a8adad5b3c1160047a Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 23 Dec 2021 14:52:56 +0000 -Subject: [PATCH 365/517] net: phy: aquantia: add PHY_ID for AQR112R - -As advised by Ian Chang this PHY is used in Puzzle devices. - -Signed-off-by: Daniel Golle ---- - drivers/net/phy/aquantia/aquantia_main.c | 28 ++++++++++++++++++++++++ - 1 file changed, 28 insertions(+) - -diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c -index a5269b7ec26d..f25e63480ec2 100644 ---- a/drivers/net/phy/aquantia/aquantia_main.c -+++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -32,6 +32,8 @@ - #define PHY_ID_AQR114C 0x31c31c22 - #define PHY_ID_AQR115C 0x31c31c33 - #define PHY_ID_AQR813 0x31c31cb2 -+#define PHY_ID_AQR112C 0x03a1b790 -+#define PHY_ID_AQR112R 0x31c31d12 - - #define MDIO_PHYXS_VEND_IF_STATUS 0xe812 - #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3) -@@ -1205,6 +1207,30 @@ static struct phy_driver aqr_driver[] = { - .led_hw_control_get = aqr_phy_led_hw_control_get, - .led_polarity_set = aqr_phy_led_polarity_set, - }, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR112C), -+ .name = "Aquantia AQR112C", -+ .probe = aqr107_probe, -+ .config_aneg = aqr_config_aneg_set_prot, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr107_read_status, -+ .get_sset_count = aqr107_get_sset_count, -+ .get_strings = aqr107_get_strings, -+ .get_stats = aqr107_get_stats, -+}, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR112R), -+ .name = "Aquantia AQR112R", -+ .probe = aqr107_probe, -+ .config_aneg = aqr_config_aneg_set_prot, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr107_read_status, -+ .get_sset_count = aqr107_get_sset_count, -+ .get_strings = aqr107_get_strings, -+ .get_stats = aqr107_get_stats, -+}, - }; - - module_phy_driver(aqr_driver); -@@ -1226,6 +1252,8 @@ static const struct mdio_device_id __maybe_unused aqr_tbl[] = { - { PHY_ID_MATCH_MODEL(PHY_ID_AQR114C) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQR115C) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQR813) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR112C) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR112R) }, - { } - }; - --- -2.51.0 - - -From 41fcce1b7749447554e6dd24270895a39be0a7ce Mon Sep 17 00:00:00 2001 -From: Bo-Cun Chen -Date: Wed, 27 Nov 2024 13:36:49 +0800 -Subject: [PATCH 366/517] net: ethernet: mtk_eth_soc: add hw dump for forced - reset - -Without this patch, the ETH driver is unable to dump the registers -before triggering a forced reset. - -Signed-off-by: Bo-Cun Chen ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 55 +++++++++++++++++++++ - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 + - 2 files changed, 56 insertions(+) - -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -index bc217da6ffc7..7d8c6ee707d1 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -74,6 +74,7 @@ static const struct mtk_reg_map mtk_reg_map = { - .rx_ptr = 0x1900, - .rx_cnt_cfg = 0x1904, - .qcrx_ptr = 0x1908, -+ .page = 0x19f0, - .glo_cfg = 0x1a04, - .rst_idx = 0x1a08, - .delay_irq = 0x1a0c, -@@ -140,6 +141,7 @@ static const struct mtk_reg_map mt7986_reg_map = { - .rx_ptr = 0x4500, - .rx_cnt_cfg = 0x4504, - .qcrx_ptr = 0x4508, -+ .page = 0x45f0, - .glo_cfg = 0x4604, - .rst_idx = 0x4608, - .delay_irq = 0x460c, -@@ -191,6 +193,7 @@ static const struct mtk_reg_map mt7988_reg_map = { - .rx_ptr = 0x4500, - .rx_cnt_cfg = 0x4504, - .qcrx_ptr = 0x4508, -+ .page = 0x45f0, - .glo_cfg = 0x4604, - .rst_idx = 0x4608, - .delay_irq = 0x460c, -@@ -4053,6 +4056,56 @@ static void mtk_set_mcr_max_rx(struct mtk_mac *mac, u32 val) - mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id)); - } - -+static void mtk_hw_dump_reg(struct mtk_eth *eth, char *name, u32 offset, u32 range) -+{ -+ u32 cur = offset; -+ -+ pr_info("\n==================== %s ====================\n", name); -+ while (cur < offset + range) { -+ pr_info("0x%08x: %08x %08x %08x %08x\n", -+ cur, mtk_r32(eth, cur), mtk_r32(eth, cur + 0x4), -+ mtk_r32(eth, cur + 0x8), mtk_r32(eth, cur + 0xc)); -+ cur += 0x10; -+ } -+} -+ -+static void mtk_hw_dump(struct mtk_eth *eth) -+{ -+ const struct mtk_reg_map *reg_map = eth->soc->reg_map; -+ u32 id; -+ -+ mtk_hw_dump_reg(eth, "FE", 0x0, 0x600); -+ mtk_hw_dump_reg(eth, "FE", 0x1400, 0x300); -+ mtk_hw_dump_reg(eth, "ADMA", reg_map->pdma.rx_ptr, 0x300); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) { -+ for (id = 0; id < MTK_QDMA_NUM_QUEUES / 16; id++) { -+ mtk_w32(eth, id, reg_map->qdma.page); -+ pr_info("\nQDMA PAGE:%x ", mtk_r32(eth, reg_map->qdma.page)); -+ mtk_hw_dump_reg(eth, "QDMA", reg_map->qdma.qtx_cfg, 0x100); -+ mtk_w32(eth, 0, reg_map->qdma.page); -+ } -+ mtk_hw_dump_reg(eth, "QDMA", reg_map->qdma.rx_ptr, 0x300); -+ } -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) { -+ mtk_hw_dump_reg(eth, "WDMA0", reg_map->wdma_base[0], 0x400); -+ mtk_hw_dump_reg(eth, "WDMA1", reg_map->wdma_base[1], 0x400); -+ if (mtk_is_netsys_v3_or_greater(eth)) -+ mtk_hw_dump_reg(eth, "WDMA2", reg_map->wdma_base[2], 0x400); -+ } -+ mtk_hw_dump_reg(eth, "PPE0", reg_map->ppe_base + 0x200, 0x200); -+ if (!mtk_is_netsys_v1(eth)) -+ mtk_hw_dump_reg(eth, "PPE1", reg_map->ppe_base + 0x600, 0x200); -+ if (mtk_is_netsys_v3_or_greater(eth)) -+ mtk_hw_dump_reg(eth, "PPE2", reg_map->ppe_base + 0xE00, 0x200); -+ mtk_hw_dump_reg(eth, "GMAC", 0x10000, 0x300); -+ if (mtk_is_netsys_v3_or_greater(eth)) -+ mtk_hw_dump_reg(eth, "GMAC", 0x10300, 0x100); -+ if (mtk_is_netsys_v3_or_greater(eth)) { -+ mtk_hw_dump_reg(eth, "XGMAC0", 0x12000, 0x300); -+ mtk_hw_dump_reg(eth, "XGMAC1", 0x13000, 0x300); -+ } -+} -+ - static void mtk_hw_reset(struct mtk_eth *eth) - { - u32 val; -@@ -4532,6 +4585,8 @@ static void mtk_pending_work(struct work_struct *work) - rtnl_lock(); - set_bit(MTK_RESETTING, ð->state); - -+ mtk_hw_dump(eth); -+ - mtk_prepare_for_reset(eth); - mtk_wed_fe_reset(); - /* Run again reset preliminary configuration in order to avoid any -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -index c7ad88351a1b..d0e7ce0bcb96 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1185,6 +1185,7 @@ struct mtk_reg_map { - u32 rx_ptr; /* rx base pointer */ - u32 rx_cnt_cfg; /* rx max count configuration */ - u32 qcrx_ptr; /* rx cpu pointer */ -+ u32 page; /* page configuration */ - u32 glo_cfg; /* global configuration */ - u32 rst_idx; /* reset index */ - u32 delay_irq; /* delay interrupt */ --- -2.51.0 - - -From 3353024c7ed6fc97e113e5f2e4e94a94913f1a9a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:25 +0100 -Subject: [PATCH 367/517] - /home/cynerd/turris/upstream/openwrt/target/linux/generic/hack-6.12/735-net-phy-realtek-rtl8261n.patch - ---- - drivers/net/phy/Kconfig | 2 ++ - drivers/net/phy/Makefile | 1 + - 2 files changed, 3 insertions(+) - -diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig -index 7b1a94e8aa8b..0e672540a0fa 100644 ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -431,6 +431,8 @@ config QSEMI_PHY - - source "drivers/net/phy/realtek/Kconfig" - -+source "drivers/net/phy/rtl8261n/Kconfig" -+ - config RENESAS_PHY - tristate "Renesas PHYs" - help -diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile -index 5fefb4d699fb..d0f2b36d5c87 100644 ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -110,6 +110,7 @@ obj-$(CONFIG_NXP_TJA11XX_PHY) += nxp-tja11xx.o - obj-y += qcom/ - obj-$(CONFIG_QSEMI_PHY) += qsemi.o - obj-$(CONFIG_REALTEK_PHY) += realtek/ -+obj-y += rtl8261n/ - obj-$(CONFIG_RENESAS_PHY) += uPD60620.o - obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o - obj-$(CONFIG_SMSC_PHY) += smsc.o --- -2.51.0 - - -From a0ea1cb120f6dabaf6dcd5dc79f5b5225718c901 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 27 Mar 2023 18:41:54 +0100 -Subject: [PATCH 368/517] generic: pcs-mtk-lynxi: add hack to use 2500Base-X - without AN - -Using 2500Base-T SFP modules e.g. on the BananaPi R3 requires manually -disabling auto-negotiation, e.g. using ethtool. While a proper fix -using SFP quirks is being discussed upstream, bring a work-around to -restore user experience to what it was before the switch to the -dedicated SGMII PCS driver. - -Signed-off-by: Daniel Golle ---- - drivers/net/pcs/pcs-mtk-lynxi.c | 24 ++++++++++++++++-------- - 1 file changed, 16 insertions(+), 8 deletions(-) - -diff --git a/drivers/net/pcs/pcs-mtk-lynxi.c b/drivers/net/pcs/pcs-mtk-lynxi.c -index 9f32540bba9c..893cac2cec05 100644 ---- a/drivers/net/pcs/pcs-mtk-lynxi.c -+++ b/drivers/net/pcs/pcs-mtk-lynxi.c -@@ -129,14 +129,23 @@ static void mtk_pcs_lynxi_get_state(struct phylink_pcs *pcs, - struct phylink_link_state *state) - { - struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); -- unsigned int bm, adv; -+ unsigned int bm, bmsr, adv; - - /* Read the BMSR and LPA */ - regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm); -- regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv); -+ bmsr = FIELD_GET(SGMII_BMSR, bm); -+ -+ if (state->interface == PHY_INTERFACE_MODE_2500BASEX) { -+ state->link = !!(bmsr & BMSR_LSTATUS); -+ state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE); -+ state->speed = SPEED_2500; -+ state->duplex = DUPLEX_FULL; - -- phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm), -- FIELD_GET(SGMII_LPA, adv)); -+ return; -+ } -+ -+ regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv); -+ phylink_mii_c22_pcs_decode_state(state, bmsr, FIELD_GET(SGMII_LPA, adv)); - } - - static void mtk_sgmii_reset(struct mtk_pcs_lynxi *mpcs) -@@ -157,7 +166,7 @@ static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode, - { - struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); - bool mode_changed = false, changed; -- unsigned int rgc3, sgm_mode, bmcr; -+ unsigned int rgc3, sgm_mode, bmcr = 0; - int advertise, link_timer; - - advertise = phylink_mii_c22_pcs_encode_advertisement(interface, -@@ -180,9 +189,8 @@ static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode, - if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) { - if (interface == PHY_INTERFACE_MODE_SGMII) - sgm_mode |= SGMII_SPEED_DUPLEX_AN; -- bmcr = BMCR_ANENABLE; -- } else { -- bmcr = 0; -+ if (interface != PHY_INTERFACE_MODE_2500BASEX) -+ bmcr = BMCR_ANENABLE; - } - - if (mpcs->interface != interface) { --- -2.51.0 - - -From 969256813f6ef11793261d85649fa8fdd5cc1ff5 Mon Sep 17 00:00:00 2001 -From: David Bauer -Date: Sun, 26 Jul 2020 02:38:31 +0200 -Subject: [PATCH 369/517] net: usb: r8152: add LED configuration from OF - -This adds the ability to configure the LED configuration register using -OF. This way, the correct value for board specific LED configuration can -be determined. - -Signed-off-by: David Bauer ---- - drivers/net/usb/r8152.c | 23 +++++++++++++++++++++++ - 1 file changed, 23 insertions(+) - -diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c -index 3fcd2b736c5e..22ab3a08a6bc 100644 ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -7047,6 +7048,22 @@ static void rtl_tally_reset(struct r8152 *tp) - ocp_write_word(tp, MCU_TYPE_PLA, PLA_RSTTALLY, ocp_data); - } - -+static int r8152_led_configuration(struct r8152 *tp) -+{ -+ u32 led_data; -+ int ret; -+ -+ ret = of_property_read_u32(tp->udev->dev.of_node, "realtek,led-data", -+ &led_data); -+ -+ if (ret) -+ return ret; -+ -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_LEDSEL, led_data); -+ -+ return 0; -+} -+ - static void r8152b_init(struct r8152 *tp) - { - u32 ocp_data; -@@ -7088,6 +7105,8 @@ static void r8152b_init(struct r8152 *tp) - ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); - ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); - ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); -+ -+ r8152_led_configuration(tp); - } - - static void r8153_init(struct r8152 *tp) -@@ -7228,6 +7247,8 @@ static void r8153_init(struct r8152 *tp) - tp->coalesce = COALESCE_SLOW; - break; - } -+ -+ r8152_led_configuration(tp); - } - - static void r8153b_init(struct r8152 *tp) -@@ -7310,6 +7331,8 @@ static void r8153b_init(struct r8152 *tp) - rtl_tally_reset(tp); - - tp->coalesce = 15000; /* 15 us */ -+ -+ r8152_led_configuration(tp); - } - - static void r8153c_init(struct r8152 *tp) --- -2.51.0 - - -From 8ed5aab6aef4043c297da7f4827030482eb477af Mon Sep 17 00:00:00 2001 -From: David Bauer -Date: Sun, 26 Jul 2020 15:30:33 +0200 -Subject: [PATCH 370/517] dt-bindings: net: add RTL8152 binding documentation - -Add binding documentation for the Realtek RTL8152 / RTL8153 USB ethernet -adapters. - -Signed-off-by: David Bauer ---- - .../bindings/net/realtek,rtl8152.yaml | 36 +++++++++++++++++++ - 1 file changed, 36 insertions(+) - create mode 100644 Documentation/devicetree/bindings/net/realtek,rtl8152.yaml - -diff --git a/Documentation/devicetree/bindings/net/realtek,rtl8152.yaml b/Documentation/devicetree/bindings/net/realtek,rtl8152.yaml -new file mode 100644 -index 000000000000..7501b074a499 ---- /dev/null -+++ b/Documentation/devicetree/bindings/net/realtek,rtl8152.yaml -@@ -0,0 +1,36 @@ -+# SPDX-License-Identifier: GPL-2.0 -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/net/realtek,rtl8152.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: Realtek RTL8152/RTL8153 series USB ethernet -+ -+maintainers: -+ - David Bauer -+ -+properties: -+ compatible: -+ oneOf: -+ - items: -+ - enum: -+ - realtek,rtl8152 -+ - realtek,rtl8153 -+ -+ reg: -+ description: The device number on the USB bus -+ -+ realtek,led-data: -+ description: Value to be written to the LED configuration register. -+ -+required: -+ - compatible -+ - reg -+ -+examples: -+ - | -+ usb-eth@2 { -+ compatible = "realtek,rtl8153"; -+ reg = <2>; -+ realtek,led-data = <0x87>; -+ }; -\ No newline at end of file --- -2.51.0 - - -From 3f30f686292664e0719b8a8f4d1f1dfb582fd655 Mon Sep 17 00:00:00 2001 -From: David Bauer -Date: Fri, 28 Apr 2023 01:53:01 +0200 -Subject: [PATCH 371/517] net: phy: mediatek-ge: add LED configuration - interface - -This adds a small hack similar to the one used for ar8xxx switches to -read a reg:value map for configuring the LED configuration registers. - -This allows OpenWrt to write device-specific LED action as well as blink -configurations. It is unlikely to be accepted upstream, as upstream -plans on integrating their own framework for handling these LEDs. - -Signed-off-by: David Bauer ---- - drivers/net/phy/mediatek/mtk-ge.c | 34 +++++++++++++++++++++++++++++++ - 1 file changed, 34 insertions(+) - -diff --git a/drivers/net/phy/mediatek/mtk-ge.c b/drivers/net/phy/mediatek/mtk-ge.c -index 73d9b72f9d9e..97d845c906dd 100644 ---- a/drivers/net/phy/mediatek/mtk-ge.c -+++ b/drivers/net/phy/mediatek/mtk-ge.c -@@ -1,4 +1,5 @@ - // SPDX-License-Identifier: GPL-2.0+ -+#include - #include - #include - #include -@@ -73,6 +74,36 @@ static int mt7530_phy_config_init(struct phy_device *phydev) - return 0; - } - -+static int mt7530_led_config_of(struct phy_device *phydev) -+{ -+ struct device_node *np = phydev->mdio.dev.of_node; -+ const __be32 *paddr; -+ int len; -+ int i; -+ -+ paddr = of_get_property(np, "mediatek,led-config", &len); -+ if (!paddr) -+ return 0; -+ -+ if (len < (2 * sizeof(*paddr))) -+ return -EINVAL; -+ -+ len /= sizeof(*paddr); -+ -+ phydev_warn(phydev, "Configure LED registers (num=%d)\n", len); -+ for (i = 0; i < len - 1; i += 2) { -+ u32 reg; -+ u32 val; -+ -+ reg = be32_to_cpup(paddr + i); -+ val = be32_to_cpup(paddr + i + 1); -+ -+ phy_write_mmd(phydev, MDIO_MMD_VEND2, reg, val); -+ } -+ -+ return 0; -+} -+ - static int mt7531_phy_config_init(struct phy_device *phydev) - { - mtk_gephy_config_init(phydev); -@@ -93,6 +124,9 @@ static int mt7531_phy_config_init(struct phy_device *phydev) - FIELD_PREP(MTK_TX_DELAY_PAIR_B_MASK, 0x4) | - FIELD_PREP(MTK_TX_DELAY_PAIR_D_MASK, 0x4)); - -+ /* LED Config*/ -+ mt7530_led_config_of(phydev); -+ - return 0; - } - --- -2.51.0 - - -From e454aa294e15a7756316afb673b263b115ce67bc Mon Sep 17 00:00:00 2001 -From: Hauke Mehrtens -Date: Fri, 7 Jul 2017 17:26:01 +0200 -Subject: [PATCH 372/517] bcm53xx: bgmac: use srab switch driver - -use the srab switch driver on these SoCs. - -Signed-off-by: Hauke Mehrtens ---- - drivers/net/ethernet/broadcom/bgmac-bcma.c | 1 + - drivers/net/ethernet/broadcom/bgmac.c | 24 ++++++++++++++++++++++ - drivers/net/ethernet/broadcom/bgmac.h | 4 ++++ - 3 files changed, 29 insertions(+) - -diff --git a/drivers/net/ethernet/broadcom/bgmac-bcma.c b/drivers/net/ethernet/broadcom/bgmac-bcma.c -index 36f9bad28e6a..81db24b76591 100644 ---- a/drivers/net/ethernet/broadcom/bgmac-bcma.c -+++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c -@@ -280,6 +280,7 @@ static int bgmac_probe(struct bcma_device *core) - bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; - bgmac->feature_flags |= BGMAC_FEAT_NO_RESET; - bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500; -+ bgmac->feature_flags |= BGMAC_FEAT_SRAB; - break; - default: - bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; -diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c -index 6ffdc4229407..dd0138ee7337 100644 ---- a/drivers/net/ethernet/broadcom/bgmac.c -+++ b/drivers/net/ethernet/broadcom/bgmac.c -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -1408,6 +1409,17 @@ static const struct ethtool_ops bgmac_ethtool_ops = { - .set_link_ksettings = phy_ethtool_set_link_ksettings, - }; - -+static struct b53_platform_data bgmac_b53_pdata = { -+}; -+ -+static struct platform_device bgmac_b53_dev = { -+ .name = "b53-srab-switch", -+ .id = -1, -+ .dev = { -+ .platform_data = &bgmac_b53_pdata, -+ }, -+}; -+ - /************************************************** - * MII - **************************************************/ -@@ -1546,6 +1558,14 @@ int bgmac_enet_probe(struct bgmac *bgmac) - - bgmac->in_init = false; - -+ if ((bgmac->feature_flags & BGMAC_FEAT_SRAB) && !bgmac_b53_pdata.regs) { -+ bgmac_b53_pdata.regs = ioremap(0x18007000, 0x1000); -+ -+ err = platform_device_register(&bgmac_b53_dev); -+ if (!err) -+ bgmac->b53_device = &bgmac_b53_dev; -+ } -+ - err = register_netdev(bgmac->net_dev); - if (err) { - dev_err(bgmac->dev, "Cannot register net device\n"); -@@ -1568,6 +1588,10 @@ EXPORT_SYMBOL_GPL(bgmac_enet_probe); - - void bgmac_enet_remove(struct bgmac *bgmac) - { -+ if (bgmac->b53_device) -+ platform_device_unregister(&bgmac_b53_dev); -+ bgmac->b53_device = NULL; -+ - unregister_netdev(bgmac->net_dev); - phy_disconnect(bgmac->net_dev->phydev); - netif_napi_del(&bgmac->napi); -diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h -index 6fee9a41839c..c75a00af5bf6 100644 ---- a/drivers/net/ethernet/broadcom/bgmac.h -+++ b/drivers/net/ethernet/broadcom/bgmac.h -@@ -387,6 +387,7 @@ - #define BGMAC_FEAT_CC4_IF_SW_TYPE_RGMII BIT(18) - #define BGMAC_FEAT_CC7_IF_TYPE_RGMII BIT(19) - #define BGMAC_FEAT_IDM_MASK BIT(20) -+#define BGMAC_FEAT_SRAB BIT(21) - - struct bgmac_slot_info { - union { -@@ -494,6 +495,9 @@ struct bgmac { - void (*cmn_maskset32)(struct bgmac *bgmac, u16 offset, u32 mask, - u32 set); - int (*phy_connect)(struct bgmac *bgmac); -+ -+ /* platform device for associated switch */ -+ struct platform_device *b53_device; - }; - - struct bgmac *bgmac_alloc(struct device *dev); --- -2.51.0 - - -From 890a69a2cfb04b333d3fe41cf0998ec70c5c0734 Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 13:49:26 +0200 -Subject: [PATCH 373/517] net/usb/qmi_wwan: add MeigLink modem support - ---- - drivers/net/usb/qmi_wwan.c | 6 ++++++ - drivers/usb/serial/option.c | 15 +++++++++++++++ - 2 files changed, 21 insertions(+) - -diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c -index f04da733240c..50b2e996488e 100644 ---- a/drivers/net/usb/qmi_wwan.c -+++ b/drivers/net/usb/qmi_wwan.c -@@ -1076,6 +1076,11 @@ static const struct usb_device_id products[] = { - USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x581d, USB_CLASS_VENDOR_SPEC, 1, 7), - .driver_info = (unsigned long)&qmi_wwan_info, - }, -+ { /* Meiglink SGM828 */ -+ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d49, USB_CLASS_VENDOR_SPEC, 0x10, 0x05), -+ .driver_info = (unsigned long)&qmi_wwan_info, -+ }, -+ - {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0122)}, /* Quectel RG650V */ - {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0125)}, /* Quectel EC25, EC20 R2.0 Mini PCIe */ - {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0306)}, /* Quectel EP06/EG06/EM06 */ -@@ -1083,6 +1088,7 @@ static const struct usb_device_id products[] = { - {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0620)}, /* Quectel EM160R-GL */ - {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0800)}, /* Quectel RM500Q-GL */ - {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0801)}, /* Quectel RM520N */ -+ {QMI_MATCH_FF_FF_FF(0x05c6, 0xf601)}, /* MeigLink SLM750 */ - - /* 3. Combined interface devices matching on interface number */ - {QMI_FIXED_INTF(0x0408, 0xea42, 4)}, /* Yota / Megafon M100-1 */ -diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c -index 62e984d20e59..2ce56d02aed7 100644 ---- a/drivers/usb/serial/option.c -+++ b/drivers/usb/serial/option.c -@@ -247,6 +247,11 @@ static void option_instat_callback(struct urb *urb); - #define UBLOX_PRODUCT_R410M 0x90b2 - /* These Yuga products use Qualcomm's vendor ID */ - #define YUGA_PRODUCT_CLM920_NC5 0x9625 -+/* These MeigLink products use Qualcomm's vendor ID */ -+#define MEIGLINK_PRODUCT_SLM750 0xf601 -+ -+#define MEIGLINK_VENDOR_ID 0x2dee -+#define MEIGLINK_PRODUCT_SLM828 0x4d49 - - #define QUECTEL_VENDOR_ID 0x2c7c - /* These Quectel products use Quectel's vendor ID */ -@@ -1154,6 +1159,11 @@ static const struct usb_device_id option_ids[] = { - { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */ - { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000), /* SIMCom SIM5218 */ - .driver_info = NCTRL(0) | NCTRL(1) | NCTRL(2) | NCTRL(3) | RSVD(4) }, -+ /* MeiG */ -+ { USB_DEVICE_AND_INTERFACE_INFO(MEIGLINK_VENDOR_ID, MEIGLINK_PRODUCT_SLM828, USB_CLASS_VENDOR_SPEC, 0x10, 0x01) }, -+ { USB_DEVICE_AND_INTERFACE_INFO(MEIGLINK_VENDOR_ID, MEIGLINK_PRODUCT_SLM828, USB_CLASS_VENDOR_SPEC, 0x10, 0x02) }, -+ { USB_DEVICE_AND_INTERFACE_INFO(MEIGLINK_VENDOR_ID, MEIGLINK_PRODUCT_SLM828, USB_CLASS_VENDOR_SPEC, 0x10, 0x03) }, -+ { USB_DEVICE_AND_INTERFACE_INFO(MEIGLINK_VENDOR_ID, MEIGLINK_PRODUCT_SLM828, USB_CLASS_VENDOR_SPEC, 0x10, 0x04) }, - /* Quectel products using Qualcomm vendor ID */ - { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC15)}, - { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC20), -@@ -1195,6 +1205,11 @@ static const struct usb_device_id option_ids[] = { - .driver_info = ZLP }, - { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96), - .driver_info = RSVD(4) }, -+ /* Meiglink products using Qualcomm vendor ID */ -+ // Works OK. In case of some issues check macros that are used by Quectel Products -+ { USB_DEVICE_AND_INTERFACE_INFO(QUALCOMM_VENDOR_ID, MEIGLINK_PRODUCT_SLM750, 0xff, 0xff, 0xff), -+ .driver_info = NUMEP2 }, -+ { USB_DEVICE_AND_INTERFACE_INFO(QUALCOMM_VENDOR_ID, MEIGLINK_PRODUCT_SLM750, 0xff, 0, 0) }, - { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0xff, 0xff), - .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, - { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0, 0) }, --- -2.51.0 - - -From 16caa64f04b96be21c4d0929fae283bfc073b022 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 9 Apr 2024 17:06:38 +0100 -Subject: [PATCH 374/517] rndis_host: add a bunch of USB IDs - -Add a bunch of USB IDs found in various places online to the -RNDIS USB network driver. - -Signed-off-by: Daniel Golle ---- - drivers/net/usb/rndis_host.c | 40 ++++++++++++++++++++++++++++++++++++ - 1 file changed, 40 insertions(+) - -diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c -index 7b3739b29c8f..81ca6a4e9c06 100644 ---- a/drivers/net/usb/rndis_host.c -+++ b/drivers/net/usb/rndis_host.c -@@ -630,6 +630,16 @@ static const struct driver_info zte_rndis_info = { - .tx_fixup = rndis_tx_fixup, - }; - -+static const struct driver_info asr_rndis_info = { -+ .description = "Asr RNDIS device", -+ .flags = FLAG_WWAN | FLAG_POINTTOPOINT | FLAG_FRAMING_RN | FLAG_NO_SETINT | FLAG_NOARP, -+ .bind = rndis_bind, -+ .unbind = rndis_unbind, -+ .status = rndis_status, -+ .rx_fixup = rndis_rx_fixup, -+ .tx_fixup = rndis_tx_fixup, -+}; -+ - /*-------------------------------------------------------------------------*/ - - static const struct usb_device_id products [] = { -@@ -665,6 +675,36 @@ static const struct usb_device_id products [] = { - /* RNDIS for tethering */ - USB_INTERFACE_INFO(USB_CLASS_WIRELESS_CONTROLLER, 1, 3), - .driver_info = (unsigned long) &rndis_info, -+}, { -+ /* Quectel EG060V rndis device */ -+ USB_DEVICE_AND_INTERFACE_INFO(0x2c7c, 0x6004, -+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3), -+ .driver_info = (unsigned long) &asr_rndis_info, -+}, { -+ /* Quectel EC200A rndis device */ -+ USB_DEVICE_AND_INTERFACE_INFO(0x2c7c, 0x6005, -+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3), -+ .driver_info = (unsigned long) &asr_rndis_info, -+}, { -+ /* Quectel EC200T rndis device */ -+ USB_DEVICE_AND_INTERFACE_INFO(0x2c7c, 0x6026, -+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3), -+ .driver_info = (unsigned long) &asr_rndis_info, -+}, { -+ /* Simcom A7906E rndis device */ -+ USB_DEVICE_AND_INTERFACE_INFO(0x1e0e, 0x9011, -+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3), -+ .driver_info = (unsigned long) &asr_rndis_info, -+}, { -+ /* Meig SLM770A */ -+ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d57, -+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3), -+ .driver_info = (unsigned long) &asr_rndis_info, -+}, { -+ /* Meig SLM828 */ -+ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d49, -+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3), -+ .driver_info = (unsigned long) &asr_rndis_info, - }, { - /* Novatel Verizon USB730L */ - USB_INTERFACE_INFO(USB_CLASS_MISC, 4, 1), --- -2.51.0 - - -From 35f347fc3508f2e506fd3d14677024e28f587056 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Tue, 12 Aug 2014 20:49:27 +0200 -Subject: [PATCH 375/517] GPIO: add named gpio exports - -Signed-off-by: John Crispin ---- - drivers/gpio/gpiolib-of.c | 72 +++++++++++++++++++++++++++++++++++ - drivers/gpio/gpiolib-sysfs.c | 17 ++++++++- - include/linux/gpio/consumer.h | 17 +++++++++ - 3 files changed, 105 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c -index 36f8c7bb79d8..1d700c06f850 100644 ---- a/drivers/gpio/gpiolib-of.c -+++ b/drivers/gpio/gpiolib-of.c -@@ -21,6 +21,8 @@ - - #include - #include -+#include -+#include - - #include "gpiolib.h" - #include "gpiolib-of.h" -@@ -1198,3 +1200,73 @@ void of_gpiochip_remove(struct gpio_chip *chip) - { - of_node_put(dev_of_node(&chip->gpiodev->dev)); - } -+ -+#ifdef CONFIG_GPIO_SYSFS -+ -+static const struct of_device_id gpio_export_ids[] = { -+ { .compatible = "gpio-export" }, -+ { /* sentinel */ } -+}; -+ -+static int of_gpio_export_probe(struct platform_device *pdev) -+{ -+ struct device_node *np = pdev->dev.of_node; -+ struct device_node *cnp; -+ u32 val; -+ int nb = 0; -+ -+ for_each_child_of_node(np, cnp) { -+ const char *name = NULL; -+ int gpio; -+ bool dmc; -+ int max_gpio = 1; -+ int i; -+ -+ of_property_read_string(cnp, "gpio-export,name", &name); -+ -+ if (!name) -+ max_gpio = of_gpio_named_count(cnp, "gpios"); -+ -+ for (i = 0; i < max_gpio; i++) { -+ struct gpio_desc *desc; -+ unsigned flags = 0; -+ enum of_gpio_flags of_flags; -+ -+ desc = of_get_named_gpiod_flags(cnp, "gpios", i, &of_flags); -+ if (IS_ERR(desc)) -+ return PTR_ERR(desc); -+ gpio = desc_to_gpio(desc); -+ -+ if (of_flags & OF_GPIO_ACTIVE_LOW) -+ flags |= GPIOF_ACTIVE_LOW; -+ -+ if (!of_property_read_u32(cnp, "gpio-export,output", &val)) -+ flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; -+ else -+ flags |= GPIOF_IN; -+ -+ if (devm_gpio_request_one(&pdev->dev, gpio, flags, name ? name : of_node_full_name(np))) -+ continue; -+ -+ dmc = of_property_read_bool(cnp, "gpio-export,direction_may_change"); -+ gpio_export_with_name(gpio_to_desc(gpio), dmc, name); -+ nb++; -+ } -+ } -+ -+ dev_info(&pdev->dev, "%d gpio(s) exported\n", nb); -+ -+ return 0; -+} -+ -+static struct platform_driver gpio_export_driver = { -+ .driver = { -+ .name = "gpio-export", -+ .of_match_table = of_match_ptr(gpio_export_ids), -+ }, -+ .probe = of_gpio_export_probe, -+}; -+ -+module_platform_driver(gpio_export_driver); -+ -+#endif -diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c -index 17ed229412af..aa98c5b08e9f 100644 ---- a/drivers/gpio/gpiolib-sysfs.c -+++ b/drivers/gpio/gpiolib-sysfs.c -@@ -571,7 +571,7 @@ static struct class gpio_class = { - * Returns: - * 0 on success, or negative errno on failure. - */ --int gpiod_export(struct gpio_desc *desc, bool direction_may_change) -+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name) - { - const char *ioname = NULL; - struct gpio_device *gdev; -@@ -629,6 +629,8 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change) - offset = gpio_chip_hwgpio(desc); - if (guard.gc->names && guard.gc->names[offset]) - ioname = guard.gc->names[offset]; -+ if (name) -+ ioname = name; - - dev = device_create_with_groups(&gpio_class, &gdev->dev, - MKDEV(0, 0), data, gpio_groups, -@@ -650,8 +652,21 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change) - gpiod_dbg(desc, "%s: status %d\n", __func__, status); - return status; - } -+EXPORT_SYMBOL_GPL(__gpiod_export); -+ -+int gpiod_export(struct gpio_desc *desc, bool direction_may_change) -+{ -+ return __gpiod_export(desc, direction_may_change, NULL); -+} - EXPORT_SYMBOL_GPL(gpiod_export); - -+int gpio_export_with_name(struct gpio_desc *desc, bool direction_may_change, -+ const char *name) -+{ -+ return __gpiod_export(desc, direction_may_change, name); -+} -+EXPORT_SYMBOL_GPL(gpio_export_with_name); -+ - static int match_export(struct device *dev, const void *desc) - { - struct gpiod_data *data = dev_get_drvdata(dev); -diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h -index db2dfbae8edb..22066cc19831 100644 ---- a/include/linux/gpio/consumer.h -+++ b/include/linux/gpio/consumer.h -@@ -628,7 +628,10 @@ static inline int devm_acpi_dev_add_driver_gpios(struct device *dev, - - #if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS) - -+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name); - int gpiod_export(struct gpio_desc *desc, bool direction_may_change); -+int gpio_export_with_name(struct gpio_desc *desc, bool direction_may_change, -+ const char *name); - int gpiod_export_link(struct device *dev, const char *name, - struct gpio_desc *desc); - void gpiod_unexport(struct gpio_desc *desc); -@@ -637,12 +640,26 @@ void gpiod_unexport(struct gpio_desc *desc); - - #include - -+static inline int __gpiod_export(struct gpio_desc *desc, -+ bool direction_may_change, -+ const char *name) -+{ -+ return -ENOSYS; -+} -+ - static inline int gpiod_export(struct gpio_desc *desc, - bool direction_may_change) - { - return -ENOSYS; - } - -+static inline int gpio_export_with_name(struct gpio_desc *desc, -+ bool direction_may_change, -+ const char *name) -+{ -+ return -ENOSYS; -+} -+ - static inline int gpiod_export_link(struct device *dev, const char *name, - struct gpio_desc *desc) - { --- -2.51.0 - - -From 07ee1fba26616921d99f3aa7fcf8afb7f542c7ef Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Fri, 12 May 2023 11:08:43 +0200 -Subject: [PATCH 376/517] ssb_sprom: add generic kernel support for Broadcom - Fallback SPROMs - ---- - drivers/bcma/Kconfig | 4 ++++ - drivers/bcma/Makefile | 1 + - drivers/bcma/bcma_private.h | 1 + - drivers/bcma/main.c | 8 ++++++++ - drivers/bcma/sprom.c | 23 ++++++++++++++--------- - drivers/ssb/Kconfig | 5 +++++ - drivers/ssb/Makefile | 1 + - drivers/ssb/main.c | 8 ++++++++ - drivers/ssb/sprom.c | 12 +++++++++++- - drivers/ssb/ssb_private.h | 2 +- - 10 files changed, 54 insertions(+), 11 deletions(-) - -diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig -index 2e9732e5c565..eb02cf92a983 100644 ---- a/drivers/bcma/Kconfig -+++ b/drivers/bcma/Kconfig -@@ -18,6 +18,10 @@ config BCMA_BLOCKIO - bool - default y - -+config BCMA_FALLBACK_SPROM -+ bool -+ default y -+ - config BCMA_HOST_PCI_POSSIBLE - bool - depends on PCI = y -diff --git a/drivers/bcma/Makefile b/drivers/bcma/Makefile -index f8c37de35da2..defc2de5c38a 100644 ---- a/drivers/bcma/Makefile -+++ b/drivers/bcma/Makefile -@@ -11,6 +11,7 @@ bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) += driver_pci_host.o - bcma-$(CONFIG_BCMA_DRIVER_MIPS) += driver_mips.o - bcma-$(CONFIG_BCMA_DRIVER_GMAC_CMN) += driver_gmac_cmn.o - bcma-$(CONFIG_BCMA_DRIVER_GPIO) += driver_gpio.o -+bcma-$(CONFIG_BCMA_FALLBACK_SPROM) += fallback-sprom.o - bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o - bcma-$(CONFIG_BCMA_HOST_SOC) += host_soc.o - obj-$(CONFIG_BCMA) += bcma.o -diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h -index 6eded32d1aac..16c1ad8d0d76 100644 ---- a/drivers/bcma/bcma_private.h -+++ b/drivers/bcma/bcma_private.h -@@ -8,6 +8,7 @@ - - #include - #include -+#include "fallback-sprom.h" - - #define bcma_err(bus, fmt, ...) \ - dev_err((bus)->dev, "bus%d: " fmt, (bus)->num, ##__VA_ARGS__) -diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c -index 6842fe781eef..a7dcb8afc580 100644 ---- a/drivers/bcma/main.c -+++ b/drivers/bcma/main.c -@@ -671,6 +671,14 @@ static int __init bcma_modinit(void) - { - int err; - -+#ifdef CONFIG_BCMA_FALLBACK_SPROM -+ err = bcma_fbs_register(); -+ if (err) { -+ pr_err("Fallback SPROM initialization failed\n"); -+ err = 0; -+ } -+#endif /* CONFIG_BCMA_FALLBACK_SPROM */ -+ - err = bcma_init_bus_register(); - if (err) - return err; -diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c -index e668ad7963fc..6024d6b61a01 100644 ---- a/drivers/bcma/sprom.c -+++ b/drivers/bcma/sprom.c -@@ -51,21 +51,26 @@ static int bcma_fill_sprom_with_fallback(struct bcma_bus *bus, - { - int err; - -- if (!get_fallback_sprom) { -+ if (get_fallback_sprom) -+ err = get_fallback_sprom(bus, out); -+ -+#ifdef CONFIG_BCMA_FALLBACK_SPROM -+ if (!get_fallback_sprom || err) -+ err = bcma_get_fallback_sprom(bus, out); -+#else -+ if (!get_fallback_sprom) - err = -ENOENT; -- goto fail; -- } -+#endif /* CONFIG_BCMA_FALLBACK_SPROM */ - -- err = get_fallback_sprom(bus, out); -- if (err) -- goto fail; -+ if (err) { -+ bcma_warn(bus, "Using fallback SPROM failed (err %d)\n", err); -+ return err; -+ } - - bcma_debug(bus, "Using SPROM revision %d provided by platform.\n", - bus->sprom.revision); -+ - return 0; --fail: -- bcma_warn(bus, "Using fallback SPROM failed (err %d)\n", err); -- return err; - } - - /************************************************** -diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig -index 2bcf62e64f6f..a878deeb0c32 100644 ---- a/drivers/ssb/Kconfig -+++ b/drivers/ssb/Kconfig -@@ -25,6 +25,11 @@ if SSB - config SSB_SPROM - bool - -+config SSB_FALLBACK_SPROM -+ bool -+ depends on SSB_PCIHOST -+ default y -+ - # Support for Block-I/O. SELECT this from the driver that needs it. - config SSB_BLOCKIO - bool -diff --git a/drivers/ssb/Makefile b/drivers/ssb/Makefile -index 142d33df040f..3edced378e31 100644 ---- a/drivers/ssb/Makefile -+++ b/drivers/ssb/Makefile -@@ -2,6 +2,7 @@ - # core - ssb-y += main.o scan.o - ssb-$(CONFIG_SSB_EMBEDDED) += embedded.o -+ssb-$(CONFIG_SSB_FALLBACK_SPROM) += fallback-sprom.o - ssb-$(CONFIG_SSB_SPROM) += sprom.o - - # host support -diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c -index aa6165e3db4a..a62bfefd27a4 100644 ---- a/drivers/ssb/main.c -+++ b/drivers/ssb/main.c -@@ -1289,6 +1289,14 @@ static int __init ssb_modinit(void) - { - int err; - -+#ifdef CONFIG_SSB_FALLBACK_SPROM -+ err = ssb_fbs_register(); -+ if (err) { -+ pr_err("Fallback SPROM initialization failed\n"); -+ err = 0; -+ } -+#endif /* CONFIG_SSB_FALLBACK_SPROM */ -+ - /* See the comment at the ssb_is_early_boot definition */ - ssb_is_early_boot = 0; - err = bus_register(&ssb_bustype); -diff --git a/drivers/ssb/sprom.c b/drivers/ssb/sprom.c -index 7cd553127861..1efc37466059 100644 ---- a/drivers/ssb/sprom.c -+++ b/drivers/ssb/sprom.c -@@ -180,10 +180,20 @@ int ssb_arch_register_fallback_sprom(int (*sprom_callback)(struct ssb_bus *bus, - - int ssb_fill_sprom_with_fallback(struct ssb_bus *bus, struct ssb_sprom *out) - { -+ int err; -+ -+ if (get_fallback_sprom) -+ err = get_fallback_sprom(bus, out); -+ -+#ifdef CONFIG_SSB_FALLBACK_SPROM -+ if (!get_fallback_sprom || err) -+ err = ssb_get_fallback_sprom(bus, out); -+#else - if (!get_fallback_sprom) - return -ENOENT; -+#endif /* CONFIG_SSB_FALLBACK_SPROM */ - -- return get_fallback_sprom(bus, out); -+ return err; - } - - /* https://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */ -diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h -index 5f31bdfbe77f..7bdc9f80cd86 100644 ---- a/drivers/ssb/ssb_private.h -+++ b/drivers/ssb/ssb_private.h -@@ -8,7 +8,7 @@ - #include - #include - #include -- -+#include "fallback-sprom.h" - - /* pci.c */ - #ifdef CONFIG_SSB_PCIHOST --- -2.51.0 - - -From 2ff5fac19d3f48f1890e0f07baa53f0f0ceddec0 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Sat, 8 Jul 2017 08:16:31 +0200 -Subject: [PATCH 377/517] debloat: add some debloat patches, strip down procfs - and make O_DIRECT support optional, saves ~15K after lzma on MIPS - -Signed-off-by: Felix Fietkau ---- - net/Kconfig | 3 +++ - net/core/Makefile | 3 ++- - net/core/sock.c | 19 +++++++++++++++++++ - net/core/sock_diag.c | 18 ------------------ - net/ipv4/Kconfig | 1 + - net/netlink/Kconfig | 1 + - net/packet/Kconfig | 1 + - net/unix/Kconfig | 1 + - net/xdp/Kconfig | 1 + - 9 files changed, 29 insertions(+), 19 deletions(-) - -diff --git a/net/Kconfig b/net/Kconfig -index c98df432683b..b1afb23fe2fb 100644 ---- a/net/Kconfig -+++ b/net/Kconfig -@@ -138,6 +138,9 @@ source "net/mptcp/Kconfig" - - endif # if INET - -+config SOCK_DIAG -+ bool -+ - config NETWORK_SECMARK - bool "Security Marking" - help -diff --git a/net/core/Makefile b/net/core/Makefile -index c3ebbaf9c81e..bd733d8aa76d 100644 ---- a/net/core/Makefile -+++ b/net/core/Makefile -@@ -11,12 +11,13 @@ obj-$(CONFIG_SYSCTL) += sysctl_net_core.o - - obj-y += dev.o dev_addr_lists.o dst.o netevent.o \ - neighbour.o rtnetlink.o utils.o link_watch.o filter.o \ -- sock_diag.o dev_ioctl.o tso.o sock_reuseport.o \ -+ dev_ioctl.o tso.o sock_reuseport.o \ - fib_notifier.o xdp.o flow_offload.o gro.o \ - netdev-genl.o netdev-genl-gen.o gso.o - - obj-$(CONFIG_NETDEV_ADDR_LIST_TEST) += dev_addr_lists_test.o - -+obj-$(CONFIG_SOCK_DIAG) += sock_diag.o - obj-y += net-sysfs.o - obj-y += hotdata.o - obj-y += netdev_rx_queue.o -diff --git a/net/core/sock.c b/net/core/sock.c -index 57fafa7cb47b..373671aee9c1 100644 ---- a/net/core/sock.c -+++ b/net/core/sock.c -@@ -118,6 +118,7 @@ - #include - #include - #include -+#include - - #include - -@@ -152,6 +153,7 @@ - - static DEFINE_MUTEX(proto_list_mutex); - static LIST_HEAD(proto_list); -+DEFINE_COOKIE(sock_cookie); - - static void sock_def_write_space_wfree(struct sock *sk); - static void sock_def_write_space(struct sock *sk); -@@ -587,6 +589,21 @@ int __sk_receive_skb(struct sock *sk, struct sk_buff *skb, - } - EXPORT_SYMBOL(__sk_receive_skb); - -+u64 __sock_gen_cookie(struct sock *sk) -+{ -+ u64 res = atomic64_read(&sk->sk_cookie); -+ -+ if (!res) { -+ u64 new = gen_cookie_next(&sock_cookie); -+ -+ atomic64_cmpxchg(&sk->sk_cookie, res, new); -+ -+ /* Another thread might have changed sk_cookie before us. */ -+ res = atomic64_read(&sk->sk_cookie); -+ } -+ return res; -+} -+ - INDIRECT_CALLABLE_DECLARE(struct dst_entry *ip6_dst_check(struct dst_entry *, - u32)); - INDIRECT_CALLABLE_DECLARE(struct dst_entry *ipv4_dst_check(struct dst_entry *, -@@ -2342,9 +2359,11 @@ static void __sk_free(struct sock *sk) - if (likely(sk->sk_net_refcnt)) - sock_inuse_add(sock_net(sk), -1); - -+#ifdef CONFIG_SOCK_DIAG - if (unlikely(sk->sk_net_refcnt && sock_diag_has_destroy_listeners(sk))) - sock_diag_broadcast_destroy(sk); - else -+#endif - sk_destruct(sk); - } - -diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c -index a08eed9b9142..a915ec59f71d 100644 ---- a/net/core/sock_diag.c -+++ b/net/core/sock_diag.c -@@ -12,7 +12,6 @@ - #include - #include - #include --#include - #include - #include - -@@ -22,23 +21,6 @@ static const struct sock_diag_inet_compat __rcu *inet_rcv_compat; - - static struct workqueue_struct *broadcast_wq; - --DEFINE_COOKIE(sock_cookie); -- --u64 __sock_gen_cookie(struct sock *sk) --{ -- u64 res = atomic64_read(&sk->sk_cookie); -- -- if (!res) { -- u64 new = gen_cookie_next(&sock_cookie); -- -- atomic64_cmpxchg(&sk->sk_cookie, res, new); -- -- /* Another thread might have changed sk_cookie before us. */ -- res = atomic64_read(&sk->sk_cookie); -- } -- return res; --} -- - int sock_diag_check_cookie(struct sock *sk, const __u32 *cookie) - { - u64 res; -diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig -index 6d2c97f8e9ef..9ffd577d8270 100644 ---- a/net/ipv4/Kconfig -+++ b/net/ipv4/Kconfig -@@ -423,6 +423,7 @@ config INET_TUNNEL - - config INET_DIAG - tristate "INET: socket monitoring interface" -+ select SOCK_DIAG - default y - help - Support for INET (TCP, DCCP, etc) socket monitoring interface used by -diff --git a/net/netlink/Kconfig b/net/netlink/Kconfig -index 1039d4f2ce11..ef355897a316 100644 ---- a/net/netlink/Kconfig -+++ b/net/netlink/Kconfig -@@ -5,6 +5,7 @@ - - config NETLINK_DIAG - tristate "NETLINK: socket monitoring interface" -+ select SOCK_DIAG - default n - help - Support for NETLINK socket monitoring interface used by the ss tool. -diff --git a/net/packet/Kconfig b/net/packet/Kconfig -index 2997382d597c..890796137daf 100644 ---- a/net/packet/Kconfig -+++ b/net/packet/Kconfig -@@ -19,6 +19,7 @@ config PACKET - config PACKET_DIAG - tristate "Packet: sockets monitoring interface" - depends on PACKET -+ select SOCK_DIAG - default n - help - Support for PF_PACKET sockets monitoring interface used by the ss tool. -diff --git a/net/unix/Kconfig b/net/unix/Kconfig -index 8b5d04210d7c..39203827d660 100644 ---- a/net/unix/Kconfig -+++ b/net/unix/Kconfig -@@ -24,6 +24,7 @@ config AF_UNIX_OOB - config UNIX_DIAG - tristate "UNIX: socket monitoring interface" - depends on UNIX -+ select SOCK_DIAG - default n - help - Support for UNIX socket monitoring interface used by the ss tool. -diff --git a/net/xdp/Kconfig b/net/xdp/Kconfig -index 71af2febe72a..719df49761a8 100644 ---- a/net/xdp/Kconfig -+++ b/net/xdp/Kconfig -@@ -10,6 +10,7 @@ config XDP_SOCKETS - config XDP_SOCKETS_DIAG - tristate "XDP sockets: monitoring interface" - depends on XDP_SOCKETS -+ select SOCK_DIAG - default n - help - Support for PF_XDP sockets monitoring interface used by the ss tool. --- -2.51.0 - - -From ef4552222c3a92648951ff86c41905786a7ce3a9 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Sat, 8 Jul 2017 08:20:09 +0200 -Subject: [PATCH 378/517] debloat: procfs - -Signed-off-by: Felix Fietkau ---- - fs/locks.c | 2 ++ - fs/proc/Kconfig | 5 +++++ - fs/proc/consoles.c | 3 +++ - fs/proc/proc_tty.c | 11 ++++++++++- - include/net/snmp.h | 18 +++++++++++++++++- - ipc/msg.c | 3 +++ - ipc/sem.c | 2 ++ - ipc/shm.c | 2 ++ - ipc/util.c | 3 +++ - kernel/exec_domain.c | 2 ++ - kernel/irq/proc.c | 9 +++++++++ - kernel/time/timer_list.c | 2 ++ - mm/vmalloc.c | 3 +++ - mm/vmstat.c | 8 +++++--- - net/8021q/vlanproc.c | 6 ++++++ - net/core/net-procfs.c | 18 ++++++++++++------ - net/core/sock.c | 2 ++ - net/ipv4/fib_trie.c | 18 ++++++++++++------ - net/ipv4/inet_timewait_sock.c | 2 +- - net/ipv4/proc.c | 3 +++ - net/ipv4/route.c | 3 +++ - 21 files changed, 107 insertions(+), 18 deletions(-) - -diff --git a/fs/locks.c b/fs/locks.c -index 204847628f3e..7a98847ea331 100644 ---- a/fs/locks.c -+++ b/fs/locks.c -@@ -2971,6 +2971,8 @@ static const struct seq_operations locks_seq_operations = { - - static int __init proc_locks_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; - proc_create_seq_private("locks", 0, NULL, &locks_seq_operations, - sizeof(struct locks_iterator), NULL); - return 0; -diff --git a/fs/proc/Kconfig b/fs/proc/Kconfig -index d80a1431ef7b..f5ab3bdea5c0 100644 ---- a/fs/proc/Kconfig -+++ b/fs/proc/Kconfig -@@ -101,6 +101,11 @@ config PROC_CHILDREN - Say Y if you are running any user-space software which takes benefit from - this interface. For example, rkt is such a piece of software. - -+config PROC_STRIPPED -+ default n -+ depends on EXPERT -+ bool "Strip non-essential /proc functionality to reduce code size" -+ - config PROC_PID_ARCH_STATUS - def_bool n - depends on PROC_FS -diff --git a/fs/proc/consoles.c b/fs/proc/consoles.c -index b7cab1ad990d..e19f627a2cee 100644 ---- a/fs/proc/consoles.c -+++ b/fs/proc/consoles.c -@@ -110,6 +110,9 @@ static const struct seq_operations consoles_op = { - - static int __init proc_consoles_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; -+ - proc_create_seq("consoles", 0, NULL, &consoles_op); - return 0; - } -diff --git a/fs/proc/proc_tty.c b/fs/proc/proc_tty.c -index 5c6a5ceab2f1..0e83f4daedf0 100644 ---- a/fs/proc/proc_tty.c -+++ b/fs/proc/proc_tty.c -@@ -131,7 +131,10 @@ static const struct seq_operations tty_drivers_op = { - void proc_tty_register_driver(struct tty_driver *driver) - { - struct proc_dir_entry *ent; -- -+ -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; -+ - if (!driver->driver_name || driver->proc_entry || - !driver->ops->proc_show) - return; -@@ -148,6 +151,9 @@ void proc_tty_unregister_driver(struct tty_driver *driver) - { - struct proc_dir_entry *ent; - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; -+ - ent = driver->proc_entry; - if (!ent) - return; -@@ -162,6 +168,9 @@ void proc_tty_unregister_driver(struct tty_driver *driver) - */ - void __init proc_tty_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; -+ - if (!proc_mkdir("tty", NULL)) - return; - proc_mkdir("tty/ldisc", NULL); /* Preserved: it's userspace visible */ -diff --git a/include/net/snmp.h b/include/net/snmp.h -index 468a67836e2f..f3ef151aa549 100644 ---- a/include/net/snmp.h -+++ b/include/net/snmp.h -@@ -124,6 +124,21 @@ struct linux_tls_mib { - #define DECLARE_SNMP_STAT(type, name) \ - extern __typeof__(type) __percpu *name - -+#ifdef CONFIG_PROC_STRIPPED -+#define __SNMP_STATS_DUMMY(mib) \ -+ do { (void) mib->mibs[0]; } while(0) -+ -+#define __SNMP_INC_STATS(mib, field) __SNMP_STATS_DUMMY(mib) -+#define SNMP_INC_STATS_ATOMIC_LONG(mib, field) __SNMP_STATS_DUMMY(mib) -+#define SNMP_INC_STATS(mib, field) __SNMP_STATS_DUMMY(mib) -+#define SNMP_DEC_STATS(mib, field) __SNMP_STATS_DUMMY(mib) -+#define __SNMP_ADD_STATS(mib, field, addend) __SNMP_STATS_DUMMY(mib) -+#define SNMP_ADD_STATS(mib, field, addend) __SNMP_STATS_DUMMY(mib) -+#define SNMP_UPD_PO_STATS(mib, basefield, addend) __SNMP_STATS_DUMMY(mib) -+#define __SNMP_UPD_PO_STATS(mib, basefield, addend) __SNMP_STATS_DUMMY(mib) -+ -+#else -+ - #define __SNMP_INC_STATS(mib, field) \ - __this_cpu_inc(mib->mibs[field]) - -@@ -154,8 +169,9 @@ struct linux_tls_mib { - __this_cpu_add(ptr[basefield##OCTETS], addend); \ - } while (0) - -+#endif - --#if BITS_PER_LONG==32 -+#if (BITS_PER_LONG==32) && !defined(CONFIG_PROC_STRIPPED) - - #define __SNMP_ADD_STATS64(mib, field, addend) \ - do { \ -diff --git a/ipc/msg.c b/ipc/msg.c -index fd08b3cb36d7..c71638872929 100644 ---- a/ipc/msg.c -+++ b/ipc/msg.c -@@ -1370,6 +1370,9 @@ void __init msg_init(void) - { - msg_init_ns(&init_ipc_ns); - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; -+ - ipc_init_proc_interface("sysvipc/msg", - " key msqid perms cbytes qnum lspid lrpid uid gid cuid cgid stime rtime ctime\n", - IPC_MSG_IDS, sysvipc_msg_proc_show); -diff --git a/ipc/sem.c b/ipc/sem.c -index a39cdc7bf88f..859af9ece817 100644 ---- a/ipc/sem.c -+++ b/ipc/sem.c -@@ -268,6 +268,8 @@ void sem_exit_ns(struct ipc_namespace *ns) - void __init sem_init(void) - { - sem_init_ns(&init_ipc_ns); -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; - ipc_init_proc_interface("sysvipc/sem", - " key semid perms nsems uid gid cuid cgid otime ctime\n", - IPC_SEM_IDS, sysvipc_sem_proc_show); -diff --git a/ipc/shm.c b/ipc/shm.c -index 492fcc699985..8d8be78ae889 100644 ---- a/ipc/shm.c -+++ b/ipc/shm.c -@@ -155,6 +155,8 @@ pure_initcall(ipc_ns_init); - - void __init shm_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; - ipc_init_proc_interface("sysvipc/shm", - #if BITS_PER_LONG <= 32 - " key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime rss swap\n", -diff --git a/ipc/util.c b/ipc/util.c -index 05cb9de66735..6a90d425e684 100644 ---- a/ipc/util.c -+++ b/ipc/util.c -@@ -141,6 +141,9 @@ void __init ipc_init_proc_interface(const char *path, const char *header, - struct proc_dir_entry *pde; - struct ipc_proc_iface *iface; - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; -+ - iface = kmalloc(sizeof(*iface), GFP_KERNEL); - if (!iface) - return; -diff --git a/kernel/exec_domain.c b/kernel/exec_domain.c -index 33f07c5f2515..4c226a052bcd 100644 ---- a/kernel/exec_domain.c -+++ b/kernel/exec_domain.c -@@ -29,6 +29,8 @@ static int execdomains_proc_show(struct seq_file *m, void *v) - - static int __init proc_execdomains_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; - proc_create_single("execdomains", 0, NULL, execdomains_proc_show); - return 0; - } -diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c -index 9081ada81c3d..6a6ed1559ac7 100644 ---- a/kernel/irq/proc.c -+++ b/kernel/irq/proc.c -@@ -339,6 +339,9 @@ void register_irq_proc(unsigned int irq, struct irq_desc *desc) - void __maybe_unused *irqp = (void *)(unsigned long) irq; - char name [MAX_NAMELEN]; - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP)) -+ return; -+ - if (!root_irq_dir || (desc->irq_data.chip == &no_irq_chip)) - return; - -@@ -397,6 +400,9 @@ void unregister_irq_proc(unsigned int irq, struct irq_desc *desc) - { - char name [MAX_NAMELEN]; - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP)) -+ return; -+ - if (!root_irq_dir || !desc->dir) - return; - #ifdef CONFIG_SMP -@@ -435,6 +441,9 @@ void init_irq_proc(void) - unsigned int irq; - struct irq_desc *desc; - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP)) -+ return; -+ - /* create /proc/irq */ - root_irq_dir = proc_mkdir("irq", NULL); - if (!root_irq_dir) -diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c -index cfbb46cc4e76..9a1dea23d175 100644 ---- a/kernel/time/timer_list.c -+++ b/kernel/time/timer_list.c -@@ -354,6 +354,8 @@ static int __init init_timer_list_procfs(void) - { - struct proc_dir_entry *pe; - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; - pe = proc_create_seq_private("timer_list", 0400, NULL, &timer_list_sops, - sizeof(struct timer_list_iter), NULL); - if (!pe) -diff --git a/mm/vmalloc.c b/mm/vmalloc.c -index 3519c4e4f841..8a1d2bc055d9 100644 ---- a/mm/vmalloc.c -+++ b/mm/vmalloc.c -@@ -5074,6 +5074,9 @@ static int vmalloc_info_show(struct seq_file *m, void *p) - - static int __init proc_vmalloc_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; -+ - proc_create_single("vmallocinfo", 0400, NULL, vmalloc_info_show); - return 0; - } -diff --git a/mm/vmstat.c b/mm/vmstat.c -index 3f4134423912..7dc56a7829b5 100644 ---- a/mm/vmstat.c -+++ b/mm/vmstat.c -@@ -2195,10 +2195,12 @@ void __init init_mm_internals(void) - start_shepherd_timer(); - #endif - #ifdef CONFIG_PROC_FS -- proc_create_seq("buddyinfo", 0444, NULL, &fragmentation_op); -- proc_create_seq("pagetypeinfo", 0400, NULL, &pagetypeinfo_op); -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) { -+ proc_create_seq("buddyinfo", 0444, NULL, &fragmentation_op); -+ proc_create_seq("pagetypeinfo", 0400, NULL, &pagetypeinfo_op); -+ proc_create_seq("zoneinfo", 0444, NULL, &zoneinfo_op); -+ } - proc_create_seq("vmstat", 0444, NULL, &vmstat_op); -- proc_create_seq("zoneinfo", 0444, NULL, &zoneinfo_op); - #endif - } - -diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c -index fa67374bda49..3434370ab83e 100644 ---- a/net/8021q/vlanproc.c -+++ b/net/8021q/vlanproc.c -@@ -93,6 +93,9 @@ void vlan_proc_cleanup(struct net *net) - { - struct vlan_net *vn = net_generic(net, vlan_net_id); - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; -+ - if (vn->proc_vlan_conf) - remove_proc_entry(name_conf, vn->proc_vlan_dir); - -@@ -112,6 +115,9 @@ int __net_init vlan_proc_init(struct net *net) - { - struct vlan_net *vn = net_generic(net, vlan_net_id); - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; -+ - vn->proc_vlan_dir = proc_net_mkdir(net, name_root, net->proc_net); - if (!vn->proc_vlan_dir) - goto err; -diff --git a/net/core/net-procfs.c b/net/core/net-procfs.c -index fa6d3969734a..5cafc5a9d3dc 100644 ---- a/net/core/net-procfs.c -+++ b/net/core/net-procfs.c -@@ -295,10 +295,12 @@ static int __net_init dev_proc_net_init(struct net *net) - if (!proc_create_net("dev", 0444, net->proc_net, &dev_seq_ops, - sizeof(struct seq_net_private))) - goto out; -- if (!proc_create_seq("softnet_stat", 0444, net->proc_net, -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && -+ !proc_create_seq("softnet_stat", 0444, net->proc_net, - &softnet_seq_ops)) - goto out_dev; -- if (!proc_create_net("ptype", 0444, net->proc_net, &ptype_seq_ops, -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && -+ !proc_create_net("ptype", 0444, net->proc_net, &ptype_seq_ops, - sizeof(struct seq_net_private))) - goto out_softnet; - -@@ -308,9 +310,11 @@ static int __net_init dev_proc_net_init(struct net *net) - out: - return rc; - out_ptype: -- remove_proc_entry("ptype", net->proc_net); -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ remove_proc_entry("ptype", net->proc_net); - out_softnet: -- remove_proc_entry("softnet_stat", net->proc_net); -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ remove_proc_entry("softnet_stat", net->proc_net); - out_dev: - remove_proc_entry("dev", net->proc_net); - goto out; -@@ -320,8 +324,10 @@ static void __net_exit dev_proc_net_exit(struct net *net) - { - wext_proc_exit(net); - -- remove_proc_entry("ptype", net->proc_net); -- remove_proc_entry("softnet_stat", net->proc_net); -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) { -+ remove_proc_entry("ptype", net->proc_net); -+ remove_proc_entry("softnet_stat", net->proc_net); -+ } - remove_proc_entry("dev", net->proc_net); - } - -diff --git a/net/core/sock.c b/net/core/sock.c -index 373671aee9c1..b8f37075a07e 100644 ---- a/net/core/sock.c -+++ b/net/core/sock.c -@@ -4277,6 +4277,8 @@ static __net_initdata struct pernet_operations proto_net_ops = { - - static int __init proto_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; - return register_pernet_subsys(&proto_net_ops); - } - -diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c -index b7440806041b..3708ed3ccb44 100644 ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -3015,11 +3015,13 @@ static const struct seq_operations fib_route_seq_ops = { - - int __net_init fib_proc_init(struct net *net) - { -- if (!proc_create_net("fib_trie", 0444, net->proc_net, &fib_trie_seq_ops, -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && -+ !proc_create_net("fib_trie", 0444, net->proc_net, &fib_trie_seq_ops, - sizeof(struct fib_trie_iter))) - goto out1; - -- if (!proc_create_net_single("fib_triestat", 0444, net->proc_net, -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && -+ !proc_create_net_single("fib_triestat", 0444, net->proc_net, - fib_triestat_seq_show, NULL)) - goto out2; - -@@ -3030,17 +3032,21 @@ int __net_init fib_proc_init(struct net *net) - return 0; - - out3: -- remove_proc_entry("fib_triestat", net->proc_net); -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ remove_proc_entry("fib_triestat", net->proc_net); - out2: -- remove_proc_entry("fib_trie", net->proc_net); -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ remove_proc_entry("fib_trie", net->proc_net); - out1: - return -ENOMEM; - } - - void __net_exit fib_proc_exit(struct net *net) - { -- remove_proc_entry("fib_trie", net->proc_net); -- remove_proc_entry("fib_triestat", net->proc_net); -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) { -+ remove_proc_entry("fib_trie", net->proc_net); -+ remove_proc_entry("fib_triestat", net->proc_net); -+ } - remove_proc_entry("route", net->proc_net); - } - -diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c -index 337390ba85b4..a03d02dca981 100644 ---- a/net/ipv4/inet_timewait_sock.c -+++ b/net/ipv4/inet_timewait_sock.c -@@ -296,7 +296,7 @@ void __inet_twsk_schedule(struct inet_timewait_sock *tw, int timeo, bool rearm) - */ - - if (!rearm) { -- bool kill = timeo <= 4*HZ; -+ bool __maybe_unused kill = timeo <= 4*HZ; - - __NET_INC_STATS(twsk_net(tw), kill ? LINUX_MIB_TIMEWAITKILLED : - LINUX_MIB_TIMEWAITED); -diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c -index 40053a02bae1..3e32011883f3 100644 ---- a/net/ipv4/proc.c -+++ b/net/ipv4/proc.c -@@ -563,5 +563,8 @@ static __net_initdata struct pernet_operations ip_proc_ops = { - - int __init ip_misc_proc_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; -+ - return register_pernet_subsys(&ip_proc_ops); - } -diff --git a/net/ipv4/route.c b/net/ipv4/route.c -index 7d04df4fc660..a27025ff7b20 100644 ---- a/net/ipv4/route.c -+++ b/net/ipv4/route.c -@@ -382,6 +382,9 @@ static struct pernet_operations ip_rt_proc_ops __net_initdata = { - - static int __init ip_rt_proc_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; -+ - return register_pernet_subsys(&ip_rt_proc_ops); - } - --- -2.51.0 - - -From 367044524b89a67e491b9fa119b1ba2fc7a7d560 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Sat, 8 Jul 2017 08:20:43 +0200 -Subject: [PATCH 379/517] debloat: dmabuf - -Signed-off-by: Felix Fietkau ---- - drivers/base/Kconfig | 2 +- - drivers/dma-buf/Makefile | 20 ++++++++++++-------- - drivers/dma-buf/dma-buf.c | 3 ++- - drivers/dma-buf/heaps/Makefile | 4 ++-- - fs/d_path.c | 1 + - kernel/sched/core.c | 1 + - net/Kconfig | 2 +- - 7 files changed, 20 insertions(+), 13 deletions(-) - -diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig -index 064eb52ff7e2..f17614172bf7 100644 ---- a/drivers/base/Kconfig -+++ b/drivers/base/Kconfig -@@ -198,7 +198,7 @@ config SOC_BUS - source "drivers/base/regmap/Kconfig" - - config DMA_SHARED_BUFFER -- bool -+ tristate - default n - select IRQ_WORK - help -diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile -index 70ec901edf2c..4efa1df475f0 100644 ---- a/drivers/dma-buf/Makefile -+++ b/drivers/dma-buf/Makefile -@@ -1,12 +1,14 @@ - # SPDX-License-Identifier: GPL-2.0-only --obj-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \ -+obj-$(CONFIG_DMA_SHARED_BUFFER) := dma-shared-buffer.o -+ -+dma-buf-objs-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \ - dma-fence-unwrap.o dma-resv.o --obj-$(CONFIG_DMABUF_HEAPS) += dma-heap.o --obj-$(CONFIG_DMABUF_HEAPS) += heaps/ --obj-$(CONFIG_SYNC_FILE) += sync_file.o --obj-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o --obj-$(CONFIG_UDMABUF) += udmabuf.o --obj-$(CONFIG_DMABUF_SYSFS_STATS) += dma-buf-sysfs-stats.o -+dma-buf-objs-$(CONFIG_DMABUF_HEAPS) += dma-heap.o -+obj-$(CONFIG_DMABUF_HEAPS) += heaps/ -+dma-buf-objs-$(CONFIG_SYNC_FILE) += sync_file.o -+dma-buf-objs-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o -+dma-buf-objs-$(CONFIG_UDMABUF) += udmabuf.o -+dma-buf-objs-$(CONFIG_DMABUF_SYSFS_STATS) += dma-buf-sysfs-stats.o - - dmabuf_selftests-y := \ - selftest.o \ -@@ -15,4 +17,6 @@ dmabuf_selftests-y := \ - st-dma-fence-unwrap.o \ - st-dma-resv.o - --obj-$(CONFIG_DMABUF_SELFTESTS) += dmabuf_selftests.o -+dma-buf-objs-$(CONFIG_DMABUF_SELFTESTS) += dmabuf_selftests.o -+ -+dma-shared-buffer-objs := $(dma-buf-objs-y) -diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c -index afb8c1c50107..f2e5dd69b100 100644 ---- a/drivers/dma-buf/dma-buf.c -+++ b/drivers/dma-buf/dma-buf.c -@@ -1743,4 +1743,5 @@ static void __exit dma_buf_deinit(void) - kern_unmount(dma_buf_mnt); - dma_buf_uninit_sysfs_statistics(); - } --__exitcall(dma_buf_deinit); -+module_exit(dma_buf_deinit); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/dma-buf/heaps/Makefile b/drivers/dma-buf/heaps/Makefile -index 974467791032..87f71c3ee6fb 100644 ---- a/drivers/dma-buf/heaps/Makefile -+++ b/drivers/dma-buf/heaps/Makefile -@@ -1,3 +1,3 @@ - # SPDX-License-Identifier: GPL-2.0 --obj-$(CONFIG_DMABUF_HEAPS_SYSTEM) += system_heap.o --obj-$(CONFIG_DMABUF_HEAPS_CMA) += cma_heap.o -+dma-buf-objs-$(CONFIG_DMABUF_HEAPS_SYSTEM) += system_heap.o -+dma-buf-objs-$(CONFIG_DMABUF_HEAPS_CMA) += cma_heap.o -diff --git a/fs/d_path.c b/fs/d_path.c -index 5f4da5c8d5db..69d49d7ab260 100644 ---- a/fs/d_path.c -+++ b/fs/d_path.c -@@ -314,6 +314,7 @@ char *dynamic_dname(char *buffer, int buflen, const char *fmt, ...) - buffer += buflen - sz; - return memcpy(buffer, temp, sz); - } -+EXPORT_SYMBOL_GPL(dynamic_dname); - - char *simple_dname(struct dentry *dentry, char *buffer, int buflen) - { -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index 4b1953b6c76a..ca7ee02dc916 100644 ---- a/kernel/sched/core.c -+++ b/kernel/sched/core.c -@@ -4433,6 +4433,7 @@ int wake_up_state(struct task_struct *p, unsigned int state) - { - return try_to_wake_up(p, state, 0); - } -+EXPORT_SYMBOL_GPL(wake_up_state); - - /* - * Perform scheduler related setup for a newly forked process p. -diff --git a/net/Kconfig b/net/Kconfig -index b1afb23fe2fb..5f179d2e74c2 100644 ---- a/net/Kconfig -+++ b/net/Kconfig -@@ -74,7 +74,7 @@ config SKB_EXTENSIONS - - config NET_DEVMEM - def_bool y -- depends on DMA_SHARED_BUFFER -+ depends on DMA_SHARED_BUFFER=y - depends on GENERIC_ALLOCATOR - depends on PAGE_POOL - --- -2.51.0 - - -From 9856b0a5865ac77a4941f011da93921ca0a1fff4 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Sun, 16 Jul 2017 16:56:10 +0200 -Subject: [PATCH 380/517] lib: add uevent_next_seqnum() - -Signed-off-by: Felix Fietkau ---- - include/linux/kobject.h | 2 ++ - lib/kobject_uevent.c | 6 ++++++ - 2 files changed, 8 insertions(+) - -diff --git a/include/linux/kobject.h b/include/linux/kobject.h -index c8219505a79f..f9c97c9b9847 100644 ---- a/include/linux/kobject.h -+++ b/include/linux/kobject.h -@@ -219,4 +219,6 @@ int kobject_synth_uevent(struct kobject *kobj, const char *buf, size_t count); - __printf(2, 3) - int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...); - -+u64 uevent_next_seqnum(void); -+ - #endif /* _KOBJECT_H_ */ -diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c -index b7f2fa08d9c8..788d8959a2d3 100644 ---- a/lib/kobject_uevent.c -+++ b/lib/kobject_uevent.c -@@ -178,6 +178,12 @@ static int kobject_action_args(const char *buf, size_t count, - return r; - } - -+u64 uevent_next_seqnum(void) -+{ -+ return atomic64_inc_return(&uevent_seqnum); -+} -+EXPORT_SYMBOL_GPL(uevent_next_seqnum); -+ - /** - * kobject_synth_uevent - send synthetic uevent with arguments - * --- -2.51.0 - - -From 84376022c24166ef12e2aff2b845a31f29fd43bf Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Sun, 16 Jul 2017 16:56:10 +0200 -Subject: [PATCH 381/517] lib: add broadcast_uevent() - -Signed-off-by: Felix Fietkau ---- - include/linux/kobject.h | 5 +++++ - lib/kobject_uevent.c | 37 +++++++++++++++++++++++++++++++++++++ - 2 files changed, 42 insertions(+) - -diff --git a/include/linux/kobject.h b/include/linux/kobject.h -index f9c97c9b9847..08d4818586b6 100644 ---- a/include/linux/kobject.h -+++ b/include/linux/kobject.h -@@ -32,6 +32,8 @@ - #define UEVENT_NUM_ENVP 64 /* number of env pointers */ - #define UEVENT_BUFFER_SIZE 2048 /* buffer for the variables */ - -+struct sk_buff; -+ - #ifdef CONFIG_UEVENT_HELPER - /* path to the userspace helper executed on an event */ - extern char uevent_helper[]; -@@ -221,4 +223,7 @@ int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...); - - u64 uevent_next_seqnum(void); - -+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group, -+ gfp_t allocation); -+ - #endif /* _KOBJECT_H_ */ -diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c -index 788d8959a2d3..2716e02169d6 100644 ---- a/lib/kobject_uevent.c -+++ b/lib/kobject_uevent.c -@@ -698,6 +698,43 @@ int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...) - } - EXPORT_SYMBOL_GPL(add_uevent_var); - -+#if defined(CONFIG_NET) -+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group, -+ gfp_t allocation) -+{ -+ struct uevent_sock *ue_sk; -+ int err = 0; -+ -+ /* send netlink message */ -+ mutex_lock(&uevent_sock_mutex); -+ list_for_each_entry(ue_sk, &uevent_sock_list, list) { -+ struct sock *uevent_sock = ue_sk->sk; -+ struct sk_buff *skb2; -+ -+ skb2 = skb_clone(skb, allocation); -+ if (!skb2) -+ break; -+ -+ err = netlink_broadcast(uevent_sock, skb2, pid, group, -+ allocation); -+ if (err) -+ break; -+ } -+ mutex_unlock(&uevent_sock_mutex); -+ -+ kfree_skb(skb); -+ return err; -+} -+#else -+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group, -+ gfp_t allocation) -+{ -+ kfree_skb(skb); -+ return 0; -+} -+#endif -+EXPORT_SYMBOL_GPL(broadcast_uevent); -+ - #if defined(CONFIG_NET) - static int uevent_net_broadcast(struct sock *usk, struct sk_buff *skb, - struct netlink_ext_ack *extack) --- -2.51.0 - - -From 809764a8e59e218960291427c0dfc3fec03896de Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 13:52:28 +0200 -Subject: [PATCH 382/517] of/ftd: add device tree cmdline - ---- - drivers/of/fdt.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c -index 8c80f4dc8b3f..500807cccee4 100644 ---- a/drivers/of/fdt.c -+++ b/drivers/of/fdt.c -@@ -1049,6 +1049,9 @@ int __init early_init_dt_scan_chosen(char *cmdline) - p = of_get_flat_dt_prop(node, "bootargs", &l); - if (p != NULL && l > 0) - strscpy(cmdline, p, min(l, COMMAND_LINE_SIZE)); -+ p = of_get_flat_dt_prop(node, "bootargs-append", &l); -+ if (p != NULL && l > 0) -+ strlcat(cmdline, p, min_t(int, strlen(cmdline) + (int)l, COMMAND_LINE_SIZE)); - - handle_cmdline: - /* --- -2.51.0 - - -From f9ab6c46d9c89e908775d62b0104f5a370a66023 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Tue, 19 Jul 2022 06:17:48 +0200 -Subject: [PATCH 383/517] Revert "Revert "Revert "driver core: Set - fw_devlink=on by default""" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This reverts commit ea718c699055c8566eb64432388a04974c43b2ea. - -With of_platform_populate() called for MTD partitions that commit breaks -probing devices which reference MTD in device tree. - -Link: https://lore.kernel.org/all/696cb2da-20b9-b3dd-46d9-de4bf91a1506@gmail.com/T/#u -Signed-off-by: Rafał Miłecki ---- - drivers/base/core.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/base/core.c b/drivers/base/core.c -index ba9b4cbef9e0..4bbd4c2c9448 100644 ---- a/drivers/base/core.c -+++ b/drivers/base/core.c -@@ -1653,7 +1653,7 @@ static void device_links_purge(struct device *dev) - #define FW_DEVLINK_FLAGS_RPM (FW_DEVLINK_FLAGS_ON | \ - DL_FLAG_PM_RUNTIME) - --static u32 fw_devlink_flags = FW_DEVLINK_FLAGS_RPM; -+static u32 fw_devlink_flags = FW_DEVLINK_FLAGS_PERMISSIVE; - static int __init fw_devlink_setup(char *arg) - { - if (!arg) --- -2.51.0 - - -From 0d4da66db0ee983798e8a0fc412539cdf4c8003a Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 17 Dec 2024 09:54:26 +0100 -Subject: [PATCH 384/517] pinctrl: mediatek: add support for MTK_PULL_PD_TYPE - -The MediaTek MT7988 SoC got some pins which only got configurable -pull-down but unlike previous designs there is no pull-up option. -Add new type MTK_PULL_PD_TYPE to support configuring such pins. - -Signed-off-by: Daniel Golle -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/20241217085435.9586-2-linux@fw-web.de -Signed-off-by: Linus Walleij ---- - .../pinctrl/mediatek/pinctrl-mtk-common-v2.c | 73 ++++++++++++++++--- - .../pinctrl/mediatek/pinctrl-mtk-common-v2.h | 1 + - 2 files changed, 63 insertions(+), 11 deletions(-) - -diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c -index 54301fbba524..7b704cc55c9f 100644 ---- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c -+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c -@@ -573,7 +573,7 @@ EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get_rev1); - */ - static int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw, - const struct mtk_pin_desc *desc, -- u32 pullup, u32 arg) -+ u32 pullup, u32 arg, bool pd_only) - { - int err, pu, pd; - -@@ -587,18 +587,34 @@ static int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw, - pu = 0; - pd = 1; - } else { -- err = -EINVAL; -- goto out; -+ return -EINVAL; - } - -- err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, pu); -- if (err) -- goto out; -+ if (!pd_only) { -+ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, pu); -+ if (err) -+ return err; -+ } - -- err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd); -+ return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd); -+} -+ -+static int mtk_pinconf_bias_set_pd(struct mtk_pinctrl *hw, -+ const struct mtk_pin_desc *desc, -+ u32 pullup, u32 arg) -+{ -+ int err, pd; -+ -+ if (arg != MTK_DISABLE && arg != MTK_ENABLE) -+ return -EINVAL; -+ -+ if (arg == MTK_DISABLE || pullup) -+ pd = 0; -+ else if (!pullup) -+ pd = 1; -+ -+ return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd); - --out: -- return err; - } - - static int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl *hw, -@@ -737,7 +753,7 @@ static int mtk_pinconf_bias_set_pu_pd_rsel(struct mtk_pinctrl *hw, - return err; - } - -- return mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, enable); -+ return mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, enable, false); - } - - int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw, -@@ -758,8 +774,14 @@ int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw, - return 0; - } - -+ if (try_all_type & MTK_PULL_PD_TYPE) { -+ err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg, true); -+ if (!err) -+ return err; -+ } -+ - if (try_all_type & MTK_PULL_PU_PD_TYPE) { -- err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg); -+ err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg, false); - if (!err) - return 0; - } -@@ -878,6 +900,29 @@ static int mtk_pinconf_bias_get_pu_pd(struct mtk_pinctrl *hw, - return err; - } - -+static int mtk_pinconf_bias_get_pd(struct mtk_pinctrl *hw, -+ const struct mtk_pin_desc *desc, -+ u32 *pullup, u32 *enable) -+{ -+ int err, pd; -+ -+ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &pd); -+ if (err) -+ goto out; -+ -+ if (pd == 0) { -+ *pullup = 0; -+ *enable = MTK_DISABLE; -+ } else if (pd == 1) { -+ *pullup = 0; -+ *enable = MTK_ENABLE; -+ } else -+ err = -EINVAL; -+ -+out: -+ return err; -+} -+ - static int mtk_pinconf_bias_get_pullsel_pullen(struct mtk_pinctrl *hw, - const struct mtk_pin_desc *desc, - u32 *pullup, u32 *enable) -@@ -947,6 +992,12 @@ int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw, - return 0; - } - -+ if (try_all_type & MTK_PULL_PD_TYPE) { -+ err = mtk_pinconf_bias_get_pd(hw, desc, pullup, enable); -+ if (!err) -+ return err; -+ } -+ - if (try_all_type & MTK_PULL_PU_PD_TYPE) { - err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable); - if (!err) -diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h -index 23688ca6d04e..9c271dc2b521 100644 ---- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h -+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h -@@ -24,6 +24,7 @@ - * turned on/off itself. But it can't be selected pull up/down - */ - #define MTK_PULL_RSEL_TYPE BIT(3) -+#define MTK_PULL_PD_TYPE BIT(4) - /* MTK_PULL_PU_PD_RSEL_TYPE is a type which is controlled by - * MTK_PULL_PU_PD_TYPE and MTK_PULL_RSEL_TYPE. - */ --- -2.51.0 - - -From 9f6832a6bcf3fa5ef863246b5ae17537433342a8 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 17 Dec 2024 09:54:27 +0100 -Subject: [PATCH 385/517] pinctrl: mediatek: add MT7988 pinctrl driver -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add pinctrl driver for the MediaTek MT7988 SoC. - -Signed-off-by: Sam Shih -Signed-off-by: Daniel Golle -[correctly initialise for the function_desc structure] -Signed-off-by: Arınç ÜNAL -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/20241217085435.9586-3-linux@fw-web.de -Signed-off-by: Linus Walleij ---- - drivers/pinctrl/mediatek/Kconfig | 7 + - drivers/pinctrl/mediatek/Makefile | 1 + - drivers/pinctrl/mediatek/pinctrl-mt7988.c | 1556 +++++++++++++++++++++ - 3 files changed, 1564 insertions(+) - create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7988.c - -diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig -index 7af287252834..952110c783d4 100644 ---- a/drivers/pinctrl/mediatek/Kconfig -+++ b/drivers/pinctrl/mediatek/Kconfig -@@ -187,6 +187,13 @@ config PINCTRL_MT7986 - default ARM64 && ARCH_MEDIATEK - select PINCTRL_MTK_MOORE - -+config PINCTRL_MT7988 -+ bool "Mediatek MT7988 pin control" -+ depends on OF -+ depends on ARM64 || COMPILE_TEST -+ default ARM64 && ARCH_MEDIATEK -+ select PINCTRL_MTK_MOORE -+ - config PINCTRL_MT8167 - bool "MediaTek MT8167 pin control" - depends on OF -diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile -index 680f7e8526e0..2b47ce030b54 100644 ---- a/drivers/pinctrl/mediatek/Makefile -+++ b/drivers/pinctrl/mediatek/Makefile -@@ -27,6 +27,7 @@ obj-$(CONFIG_PINCTRL_MT7623) += pinctrl-mt7623.o - obj-$(CONFIG_PINCTRL_MT7629) += pinctrl-mt7629.o - obj-$(CONFIG_PINCTRL_MT7981) += pinctrl-mt7981.o - obj-$(CONFIG_PINCTRL_MT7986) += pinctrl-mt7986.o -+obj-$(CONFIG_PINCTRL_MT7988) += pinctrl-mt7988.o - obj-$(CONFIG_PINCTRL_MT8167) += pinctrl-mt8167.o - obj-$(CONFIG_PINCTRL_MT8173) += pinctrl-mt8173.o - obj-$(CONFIG_PINCTRL_MT8183) += pinctrl-mt8183.o -diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7988.c b/drivers/pinctrl/mediatek/pinctrl-mt7988.c -new file mode 100644 -index 000000000000..68b4097792b8 ---- /dev/null -+++ b/drivers/pinctrl/mediatek/pinctrl-mt7988.c -@@ -0,0 +1,1556 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * The MT7988 driver based on Linux generic pinctrl binding. -+ * -+ * Copyright (C) 2020 MediaTek Inc. -+ * Author: Sam Shih -+ */ -+ -+#include "pinctrl-moore.h" -+ -+enum mt7988_pinctrl_reg_page { -+ GPIO_BASE, -+ IOCFG_TR_BASE, -+ IOCFG_BR_BASE, -+ IOCFG_RB_BASE, -+ IOCFG_LB_BASE, -+ IOCFG_TL_BASE, -+}; -+ -+#define MT7988_PIN(_number, _name) MTK_PIN(_number, _name, 0, _number, DRV_GRP4) -+ -+#define PIN_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \ -+ _x_bits) \ -+ PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \ -+ _x_bits, 32, 0) -+ -+#define PINS_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \ -+ _x_bits) \ -+ PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \ -+ _x_bits, 32, 1) -+ -+static const struct mtk_pin_field_calc mt7988_pin_mode_range[] = { -+ PIN_FIELD(0, 83, 0x300, 0x10, 0, 4), -+}; -+ -+static const struct mtk_pin_field_calc mt7988_pin_dir_range[] = { -+ PIN_FIELD(0, 83, 0x0, 0x10, 0, 1), -+}; -+ -+static const struct mtk_pin_field_calc mt7988_pin_di_range[] = { -+ PIN_FIELD(0, 83, 0x200, 0x10, 0, 1), -+}; -+ -+static const struct mtk_pin_field_calc mt7988_pin_do_range[] = { -+ PIN_FIELD(0, 83, 0x100, 0x10, 0, 1), -+}; -+ -+static const struct mtk_pin_field_calc mt7988_pin_ies_range[] = { -+ PIN_FIELD_BASE(0, 0, 5, 0x30, 0x10, 13, 1), -+ PIN_FIELD_BASE(1, 1, 5, 0x30, 0x10, 14, 1), -+ PIN_FIELD_BASE(2, 2, 5, 0x30, 0x10, 11, 1), -+ PIN_FIELD_BASE(3, 3, 5, 0x30, 0x10, 12, 1), -+ PIN_FIELD_BASE(4, 4, 5, 0x30, 0x10, 0, 1), -+ PIN_FIELD_BASE(5, 5, 5, 0x30, 0x10, 9, 1), -+ PIN_FIELD_BASE(6, 6, 5, 0x30, 0x10, 10, 1), -+ -+ PIN_FIELD_BASE(7, 7, 4, 0x30, 0x10, 8, 1), -+ PIN_FIELD_BASE(8, 8, 4, 0x30, 0x10, 6, 1), -+ PIN_FIELD_BASE(9, 9, 4, 0x30, 0x10, 5, 1), -+ PIN_FIELD_BASE(10, 10, 4, 0x30, 0x10, 3, 1), -+ -+ PIN_FIELD_BASE(11, 11, 1, 0x40, 0x10, 0, 1), -+ PIN_FIELD_BASE(12, 12, 1, 0x40, 0x10, 21, 1), -+ PIN_FIELD_BASE(13, 13, 1, 0x40, 0x10, 1, 1), -+ PIN_FIELD_BASE(14, 14, 1, 0x40, 0x10, 2, 1), -+ -+ PIN_FIELD_BASE(15, 15, 5, 0x30, 0x10, 7, 1), -+ PIN_FIELD_BASE(16, 16, 5, 0x30, 0x10, 8, 1), -+ PIN_FIELD_BASE(17, 17, 5, 0x30, 0x10, 3, 1), -+ PIN_FIELD_BASE(18, 18, 5, 0x30, 0x10, 4, 1), -+ -+ PIN_FIELD_BASE(19, 19, 4, 0x30, 0x10, 7, 1), -+ PIN_FIELD_BASE(20, 20, 4, 0x30, 0x10, 4, 1), -+ -+ PIN_FIELD_BASE(21, 21, 3, 0x50, 0x10, 17, 1), -+ PIN_FIELD_BASE(22, 22, 3, 0x50, 0x10, 23, 1), -+ PIN_FIELD_BASE(23, 23, 3, 0x50, 0x10, 20, 1), -+ PIN_FIELD_BASE(24, 24, 3, 0x50, 0x10, 19, 1), -+ PIN_FIELD_BASE(25, 25, 3, 0x50, 0x10, 21, 1), -+ PIN_FIELD_BASE(26, 26, 3, 0x50, 0x10, 22, 1), -+ PIN_FIELD_BASE(27, 27, 3, 0x50, 0x10, 18, 1), -+ PIN_FIELD_BASE(28, 28, 3, 0x50, 0x10, 25, 1), -+ PIN_FIELD_BASE(29, 29, 3, 0x50, 0x10, 26, 1), -+ PIN_FIELD_BASE(30, 30, 3, 0x50, 0x10, 27, 1), -+ PIN_FIELD_BASE(31, 31, 3, 0x50, 0x10, 24, 1), -+ PIN_FIELD_BASE(32, 32, 3, 0x50, 0x10, 28, 1), -+ PIN_FIELD_BASE(33, 33, 3, 0x60, 0x10, 0, 1), -+ PIN_FIELD_BASE(34, 34, 3, 0x50, 0x10, 31, 1), -+ PIN_FIELD_BASE(35, 35, 3, 0x50, 0x10, 29, 1), -+ PIN_FIELD_BASE(36, 36, 3, 0x50, 0x10, 30, 1), -+ PIN_FIELD_BASE(37, 37, 3, 0x60, 0x10, 1, 1), -+ PIN_FIELD_BASE(38, 38, 3, 0x50, 0x10, 11, 1), -+ PIN_FIELD_BASE(39, 39, 3, 0x50, 0x10, 10, 1), -+ PIN_FIELD_BASE(40, 40, 3, 0x50, 0x10, 0, 1), -+ PIN_FIELD_BASE(41, 41, 3, 0x50, 0x10, 1, 1), -+ PIN_FIELD_BASE(42, 42, 3, 0x50, 0x10, 9, 1), -+ PIN_FIELD_BASE(43, 43, 3, 0x50, 0x10, 8, 1), -+ PIN_FIELD_BASE(44, 44, 3, 0x50, 0x10, 7, 1), -+ PIN_FIELD_BASE(45, 45, 3, 0x50, 0x10, 6, 1), -+ PIN_FIELD_BASE(46, 46, 3, 0x50, 0x10, 5, 1), -+ PIN_FIELD_BASE(47, 47, 3, 0x50, 0x10, 4, 1), -+ PIN_FIELD_BASE(48, 48, 3, 0x50, 0x10, 3, 1), -+ PIN_FIELD_BASE(49, 49, 3, 0x50, 0x10, 2, 1), -+ PIN_FIELD_BASE(50, 50, 3, 0x50, 0x10, 15, 1), -+ PIN_FIELD_BASE(51, 51, 3, 0x50, 0x10, 12, 1), -+ PIN_FIELD_BASE(52, 52, 3, 0x50, 0x10, 13, 1), -+ PIN_FIELD_BASE(53, 53, 3, 0x50, 0x10, 14, 1), -+ PIN_FIELD_BASE(54, 54, 3, 0x50, 0x10, 16, 1), -+ -+ PIN_FIELD_BASE(55, 55, 1, 0x40, 0x10, 14, 1), -+ PIN_FIELD_BASE(56, 56, 1, 0x40, 0x10, 15, 1), -+ PIN_FIELD_BASE(57, 57, 1, 0x40, 0x10, 13, 1), -+ PIN_FIELD_BASE(58, 58, 1, 0x40, 0x10, 4, 1), -+ PIN_FIELD_BASE(59, 59, 1, 0x40, 0x10, 5, 1), -+ PIN_FIELD_BASE(60, 60, 1, 0x40, 0x10, 6, 1), -+ PIN_FIELD_BASE(61, 61, 1, 0x40, 0x10, 3, 1), -+ PIN_FIELD_BASE(62, 62, 1, 0x40, 0x10, 7, 1), -+ PIN_FIELD_BASE(63, 63, 1, 0x40, 0x10, 20, 1), -+ PIN_FIELD_BASE(64, 64, 1, 0x40, 0x10, 8, 1), -+ PIN_FIELD_BASE(65, 65, 1, 0x40, 0x10, 9, 1), -+ PIN_FIELD_BASE(66, 66, 1, 0x40, 0x10, 10, 1), -+ PIN_FIELD_BASE(67, 67, 1, 0x40, 0x10, 11, 1), -+ PIN_FIELD_BASE(68, 68, 1, 0x40, 0x10, 12, 1), -+ -+ PIN_FIELD_BASE(69, 69, 5, 0x30, 0x10, 1, 1), -+ PIN_FIELD_BASE(70, 70, 5, 0x30, 0x10, 2, 1), -+ PIN_FIELD_BASE(71, 71, 5, 0x30, 0x10, 5, 1), -+ PIN_FIELD_BASE(72, 72, 5, 0x30, 0x10, 6, 1), -+ -+ PIN_FIELD_BASE(73, 73, 4, 0x30, 0x10, 10, 1), -+ PIN_FIELD_BASE(74, 74, 4, 0x30, 0x10, 1, 1), -+ PIN_FIELD_BASE(75, 75, 4, 0x30, 0x10, 11, 1), -+ PIN_FIELD_BASE(76, 76, 4, 0x30, 0x10, 9, 1), -+ PIN_FIELD_BASE(77, 77, 4, 0x30, 0x10, 2, 1), -+ PIN_FIELD_BASE(78, 78, 4, 0x30, 0x10, 0, 1), -+ PIN_FIELD_BASE(79, 79, 4, 0x30, 0x10, 12, 1), -+ -+ PIN_FIELD_BASE(80, 80, 1, 0x40, 0x10, 18, 1), -+ PIN_FIELD_BASE(81, 81, 1, 0x40, 0x10, 19, 1), -+ PIN_FIELD_BASE(82, 82, 1, 0x40, 0x10, 16, 1), -+ PIN_FIELD_BASE(83, 83, 1, 0x40, 0x10, 17, 1), -+}; -+ -+static const struct mtk_pin_field_calc mt7988_pin_smt_range[] = { -+ PIN_FIELD_BASE(0, 0, 5, 0xc0, 0x10, 13, 1), -+ PIN_FIELD_BASE(1, 1, 5, 0xc0, 0x10, 14, 1), -+ PIN_FIELD_BASE(2, 2, 5, 0xc0, 0x10, 11, 1), -+ PIN_FIELD_BASE(3, 3, 5, 0xc0, 0x10, 12, 1), -+ PIN_FIELD_BASE(4, 4, 5, 0xc0, 0x10, 0, 1), -+ PIN_FIELD_BASE(5, 5, 5, 0xc0, 0x10, 9, 1), -+ PIN_FIELD_BASE(6, 6, 5, 0xc0, 0x10, 10, 1), -+ -+ PIN_FIELD_BASE(7, 7, 4, 0xb0, 0x10, 8, 1), -+ PIN_FIELD_BASE(8, 8, 4, 0xb0, 0x10, 6, 1), -+ PIN_FIELD_BASE(9, 9, 4, 0xb0, 0x10, 5, 1), -+ PIN_FIELD_BASE(10, 10, 4, 0xb0, 0x10, 3, 1), -+ -+ PIN_FIELD_BASE(11, 11, 1, 0xe0, 0x10, 0, 1), -+ PIN_FIELD_BASE(12, 12, 1, 0xe0, 0x10, 21, 1), -+ PIN_FIELD_BASE(13, 13, 1, 0xe0, 0x10, 1, 1), -+ PIN_FIELD_BASE(14, 14, 1, 0xe0, 0x10, 2, 1), -+ -+ PIN_FIELD_BASE(15, 15, 5, 0xc0, 0x10, 7, 1), -+ PIN_FIELD_BASE(16, 16, 5, 0xc0, 0x10, 8, 1), -+ PIN_FIELD_BASE(17, 17, 5, 0xc0, 0x10, 3, 1), -+ PIN_FIELD_BASE(18, 18, 5, 0xc0, 0x10, 4, 1), -+ -+ PIN_FIELD_BASE(19, 19, 4, 0xb0, 0x10, 7, 1), -+ PIN_FIELD_BASE(20, 20, 4, 0xb0, 0x10, 4, 1), -+ -+ PIN_FIELD_BASE(21, 21, 3, 0x140, 0x10, 17, 1), -+ PIN_FIELD_BASE(22, 22, 3, 0x140, 0x10, 23, 1), -+ PIN_FIELD_BASE(23, 23, 3, 0x140, 0x10, 20, 1), -+ PIN_FIELD_BASE(24, 24, 3, 0x140, 0x10, 19, 1), -+ PIN_FIELD_BASE(25, 25, 3, 0x140, 0x10, 21, 1), -+ PIN_FIELD_BASE(26, 26, 3, 0x140, 0x10, 22, 1), -+ PIN_FIELD_BASE(27, 27, 3, 0x140, 0x10, 18, 1), -+ PIN_FIELD_BASE(28, 28, 3, 0x140, 0x10, 25, 1), -+ PIN_FIELD_BASE(29, 29, 3, 0x140, 0x10, 26, 1), -+ PIN_FIELD_BASE(30, 30, 3, 0x140, 0x10, 27, 1), -+ PIN_FIELD_BASE(31, 31, 3, 0x140, 0x10, 24, 1), -+ PIN_FIELD_BASE(32, 32, 3, 0x140, 0x10, 28, 1), -+ PIN_FIELD_BASE(33, 33, 3, 0x150, 0x10, 0, 1), -+ PIN_FIELD_BASE(34, 34, 3, 0x140, 0x10, 31, 1), -+ PIN_FIELD_BASE(35, 35, 3, 0x140, 0x10, 29, 1), -+ PIN_FIELD_BASE(36, 36, 3, 0x140, 0x10, 30, 1), -+ PIN_FIELD_BASE(37, 37, 3, 0x150, 0x10, 1, 1), -+ PIN_FIELD_BASE(38, 38, 3, 0x140, 0x10, 11, 1), -+ PIN_FIELD_BASE(39, 39, 3, 0x140, 0x10, 10, 1), -+ PIN_FIELD_BASE(40, 40, 3, 0x140, 0x10, 0, 1), -+ PIN_FIELD_BASE(41, 41, 3, 0x140, 0x10, 1, 1), -+ PIN_FIELD_BASE(42, 42, 3, 0x140, 0x10, 9, 1), -+ PIN_FIELD_BASE(43, 43, 3, 0x140, 0x10, 8, 1), -+ PIN_FIELD_BASE(44, 44, 3, 0x140, 0x10, 7, 1), -+ PIN_FIELD_BASE(45, 45, 3, 0x140, 0x10, 6, 1), -+ PIN_FIELD_BASE(46, 46, 3, 0x140, 0x10, 5, 1), -+ PIN_FIELD_BASE(47, 47, 3, 0x140, 0x10, 4, 1), -+ PIN_FIELD_BASE(48, 48, 3, 0x140, 0x10, 3, 1), -+ PIN_FIELD_BASE(49, 49, 3, 0x140, 0x10, 2, 1), -+ PIN_FIELD_BASE(50, 50, 3, 0x140, 0x10, 15, 1), -+ PIN_FIELD_BASE(51, 51, 3, 0x140, 0x10, 12, 1), -+ PIN_FIELD_BASE(52, 52, 3, 0x140, 0x10, 13, 1), -+ PIN_FIELD_BASE(53, 53, 3, 0x140, 0x10, 14, 1), -+ PIN_FIELD_BASE(54, 54, 3, 0x140, 0x10, 16, 1), -+ -+ PIN_FIELD_BASE(55, 55, 1, 0xe0, 0x10, 14, 1), -+ PIN_FIELD_BASE(56, 56, 1, 0xe0, 0x10, 15, 1), -+ PIN_FIELD_BASE(57, 57, 1, 0xe0, 0x10, 13, 1), -+ PIN_FIELD_BASE(58, 58, 1, 0xe0, 0x10, 4, 1), -+ PIN_FIELD_BASE(59, 59, 1, 0xe0, 0x10, 5, 1), -+ PIN_FIELD_BASE(60, 60, 1, 0xe0, 0x10, 6, 1), -+ PIN_FIELD_BASE(61, 61, 1, 0xe0, 0x10, 3, 1), -+ PIN_FIELD_BASE(62, 62, 1, 0xe0, 0x10, 7, 1), -+ PIN_FIELD_BASE(63, 63, 1, 0xe0, 0x10, 20, 1), -+ PIN_FIELD_BASE(64, 64, 1, 0xe0, 0x10, 8, 1), -+ PIN_FIELD_BASE(65, 65, 1, 0xe0, 0x10, 9, 1), -+ PIN_FIELD_BASE(66, 66, 1, 0xe0, 0x10, 10, 1), -+ PIN_FIELD_BASE(67, 67, 1, 0xe0, 0x10, 11, 1), -+ PIN_FIELD_BASE(68, 68, 1, 0xe0, 0x10, 12, 1), -+ -+ PIN_FIELD_BASE(69, 69, 5, 0xc0, 0x10, 1, 1), -+ PIN_FIELD_BASE(70, 70, 5, 0xc0, 0x10, 2, 1), -+ PIN_FIELD_BASE(71, 71, 5, 0xc0, 0x10, 5, 1), -+ PIN_FIELD_BASE(72, 72, 5, 0xc0, 0x10, 6, 1), -+ -+ PIN_FIELD_BASE(73, 73, 4, 0xb0, 0x10, 10, 1), -+ PIN_FIELD_BASE(74, 74, 4, 0xb0, 0x10, 1, 1), -+ PIN_FIELD_BASE(75, 75, 4, 0xb0, 0x10, 11, 1), -+ PIN_FIELD_BASE(76, 76, 4, 0xb0, 0x10, 9, 1), -+ PIN_FIELD_BASE(77, 77, 4, 0xb0, 0x10, 2, 1), -+ PIN_FIELD_BASE(78, 78, 4, 0xb0, 0x10, 0, 1), -+ PIN_FIELD_BASE(79, 79, 4, 0xb0, 0x10, 12, 1), -+ -+ PIN_FIELD_BASE(80, 80, 1, 0xe0, 0x10, 18, 1), -+ PIN_FIELD_BASE(81, 81, 1, 0xe0, 0x10, 19, 1), -+ PIN_FIELD_BASE(82, 82, 1, 0xe0, 0x10, 16, 1), -+ PIN_FIELD_BASE(83, 83, 1, 0xe0, 0x10, 17, 1), -+}; -+ -+static const struct mtk_pin_field_calc mt7988_pin_pu_range[] = { -+ PIN_FIELD_BASE(7, 7, 4, 0x60, 0x10, 5, 1), -+ PIN_FIELD_BASE(8, 8, 4, 0x60, 0x10, 4, 1), -+ PIN_FIELD_BASE(9, 9, 4, 0x60, 0x10, 3, 1), -+ PIN_FIELD_BASE(10, 10, 4, 0x60, 0x10, 2, 1), -+ -+ PIN_FIELD_BASE(13, 13, 1, 0x70, 0x10, 0, 1), -+ PIN_FIELD_BASE(14, 14, 1, 0x70, 0x10, 1, 1), -+ PIN_FIELD_BASE(63, 63, 1, 0x70, 0x10, 2, 1), -+ -+ PIN_FIELD_BASE(75, 75, 4, 0x60, 0x10, 7, 1), -+ PIN_FIELD_BASE(76, 76, 4, 0x60, 0x10, 6, 1), -+ PIN_FIELD_BASE(77, 77, 4, 0x60, 0x10, 1, 1), -+ PIN_FIELD_BASE(78, 78, 4, 0x60, 0x10, 0, 1), -+ PIN_FIELD_BASE(79, 79, 4, 0x60, 0x10, 8, 1), -+}; -+ -+static const struct mtk_pin_field_calc mt7988_pin_pd_range[] = { -+ PIN_FIELD_BASE(7, 7, 4, 0x40, 0x10, 5, 1), -+ PIN_FIELD_BASE(8, 8, 4, 0x40, 0x10, 4, 1), -+ PIN_FIELD_BASE(9, 9, 4, 0x40, 0x10, 3, 1), -+ PIN_FIELD_BASE(10, 10, 4, 0x40, 0x10, 2, 1), -+ -+ PIN_FIELD_BASE(13, 13, 1, 0x50, 0x10, 0, 1), -+ PIN_FIELD_BASE(14, 14, 1, 0x50, 0x10, 1, 1), -+ -+ PIN_FIELD_BASE(15, 15, 5, 0x40, 0x10, 4, 1), -+ PIN_FIELD_BASE(16, 16, 5, 0x40, 0x10, 5, 1), -+ PIN_FIELD_BASE(17, 17, 5, 0x40, 0x10, 0, 1), -+ PIN_FIELD_BASE(18, 18, 5, 0x40, 0x10, 1, 1), -+ -+ PIN_FIELD_BASE(63, 63, 1, 0x50, 0x10, 2, 1), -+ PIN_FIELD_BASE(71, 71, 5, 0x40, 0x10, 2, 1), -+ PIN_FIELD_BASE(72, 72, 5, 0x40, 0x10, 3, 1), -+ -+ PIN_FIELD_BASE(75, 75, 4, 0x40, 0x10, 7, 1), -+ PIN_FIELD_BASE(76, 76, 4, 0x40, 0x10, 6, 1), -+ PIN_FIELD_BASE(77, 77, 4, 0x40, 0x10, 1, 1), -+ PIN_FIELD_BASE(78, 78, 4, 0x40, 0x10, 0, 1), -+ PIN_FIELD_BASE(79, 79, 4, 0x40, 0x10, 8, 1), -+}; -+ -+static const struct mtk_pin_field_calc mt7988_pin_drv_range[] = { -+ PIN_FIELD_BASE(0, 0, 5, 0x00, 0x10, 21, 3), -+ PIN_FIELD_BASE(1, 1, 5, 0x00, 0x10, 24, 3), -+ PIN_FIELD_BASE(2, 2, 5, 0x00, 0x10, 15, 3), -+ PIN_FIELD_BASE(3, 3, 5, 0x00, 0x10, 18, 3), -+ PIN_FIELD_BASE(4, 4, 5, 0x00, 0x10, 0, 3), -+ PIN_FIELD_BASE(5, 5, 5, 0x00, 0x10, 9, 3), -+ PIN_FIELD_BASE(6, 6, 5, 0x00, 0x10, 12, 3), -+ -+ PIN_FIELD_BASE(7, 7, 4, 0x00, 0x10, 24, 3), -+ PIN_FIELD_BASE(8, 8, 4, 0x00, 0x10, 28, 3), -+ PIN_FIELD_BASE(9, 9, 4, 0x00, 0x10, 15, 3), -+ PIN_FIELD_BASE(10, 10, 4, 0x00, 0x10, 9, 3), -+ -+ PIN_FIELD_BASE(11, 11, 1, 0x00, 0x10, 0, 3), -+ PIN_FIELD_BASE(12, 12, 1, 0x20, 0x10, 3, 3), -+ PIN_FIELD_BASE(13, 13, 1, 0x00, 0x10, 3, 3), -+ PIN_FIELD_BASE(14, 14, 1, 0x00, 0x10, 6, 3), -+ -+ PIN_FIELD_BASE(19, 19, 4, 0x00, 0x10, 21, 3), -+ PIN_FIELD_BASE(20, 20, 4, 0x00, 0x10, 12, 3), -+ -+ PIN_FIELD_BASE(21, 21, 3, 0x10, 0x10, 21, 3), -+ PIN_FIELD_BASE(22, 22, 3, 0x20, 0x10, 9, 3), -+ PIN_FIELD_BASE(23, 23, 3, 0x20, 0x10, 0, 3), -+ PIN_FIELD_BASE(24, 24, 3, 0x10, 0x10, 27, 3), -+ PIN_FIELD_BASE(25, 25, 3, 0x20, 0x10, 3, 3), -+ PIN_FIELD_BASE(26, 26, 3, 0x20, 0x10, 6, 3), -+ PIN_FIELD_BASE(27, 27, 3, 0x10, 0x10, 24, 3), -+ PIN_FIELD_BASE(28, 28, 3, 0x20, 0x10, 15, 3), -+ PIN_FIELD_BASE(29, 29, 3, 0x20, 0x10, 18, 3), -+ PIN_FIELD_BASE(30, 30, 3, 0x20, 0x10, 21, 3), -+ PIN_FIELD_BASE(31, 31, 3, 0x20, 0x10, 12, 3), -+ PIN_FIELD_BASE(32, 32, 3, 0x20, 0x10, 24, 3), -+ PIN_FIELD_BASE(33, 33, 3, 0x30, 0x10, 6, 3), -+ PIN_FIELD_BASE(34, 34, 3, 0x30, 0x10, 3, 3), -+ PIN_FIELD_BASE(35, 35, 3, 0x20, 0x10, 27, 3), -+ PIN_FIELD_BASE(36, 36, 3, 0x30, 0x10, 0, 3), -+ PIN_FIELD_BASE(37, 37, 3, 0x30, 0x10, 9, 3), -+ PIN_FIELD_BASE(38, 38, 3, 0x10, 0x10, 3, 3), -+ PIN_FIELD_BASE(39, 39, 3, 0x10, 0x10, 0, 3), -+ PIN_FIELD_BASE(40, 40, 3, 0x00, 0x10, 0, 3), -+ PIN_FIELD_BASE(41, 41, 3, 0x00, 0x10, 3, 3), -+ PIN_FIELD_BASE(42, 42, 3, 0x00, 0x10, 27, 3), -+ PIN_FIELD_BASE(43, 43, 3, 0x00, 0x10, 24, 3), -+ PIN_FIELD_BASE(44, 44, 3, 0x00, 0x10, 21, 3), -+ PIN_FIELD_BASE(45, 45, 3, 0x00, 0x10, 18, 3), -+ PIN_FIELD_BASE(46, 46, 3, 0x00, 0x10, 15, 3), -+ PIN_FIELD_BASE(47, 47, 3, 0x00, 0x10, 12, 3), -+ PIN_FIELD_BASE(48, 48, 3, 0x00, 0x10, 9, 3), -+ PIN_FIELD_BASE(49, 49, 3, 0x00, 0x10, 6, 3), -+ PIN_FIELD_BASE(50, 50, 3, 0x10, 0x10, 15, 3), -+ PIN_FIELD_BASE(51, 51, 3, 0x10, 0x10, 6, 3), -+ PIN_FIELD_BASE(52, 52, 3, 0x10, 0x10, 9, 3), -+ PIN_FIELD_BASE(53, 53, 3, 0x10, 0x10, 12, 3), -+ PIN_FIELD_BASE(54, 54, 3, 0x10, 0x10, 18, 3), -+ -+ PIN_FIELD_BASE(55, 55, 1, 0x10, 0x10, 12, 3), -+ PIN_FIELD_BASE(56, 56, 1, 0x10, 0x10, 15, 3), -+ PIN_FIELD_BASE(57, 57, 1, 0x10, 0x10, 9, 3), -+ PIN_FIELD_BASE(58, 58, 1, 0x00, 0x10, 12, 3), -+ PIN_FIELD_BASE(59, 59, 1, 0x00, 0x10, 15, 3), -+ PIN_FIELD_BASE(60, 60, 1, 0x00, 0x10, 18, 3), -+ PIN_FIELD_BASE(61, 61, 1, 0x00, 0x10, 9, 3), -+ PIN_FIELD_BASE(62, 62, 1, 0x00, 0x10, 21, 3), -+ PIN_FIELD_BASE(63, 63, 1, 0x20, 0x10, 0, 3), -+ PIN_FIELD_BASE(64, 64, 1, 0x00, 0x10, 24, 3), -+ PIN_FIELD_BASE(65, 65, 1, 0x00, 0x10, 27, 3), -+ PIN_FIELD_BASE(66, 66, 1, 0x10, 0x10, 0, 3), -+ PIN_FIELD_BASE(67, 67, 1, 0x10, 0x10, 3, 3), -+ PIN_FIELD_BASE(68, 68, 1, 0x10, 0x10, 6, 3), -+ -+ PIN_FIELD_BASE(69, 69, 5, 0x00, 0x10, 3, 3), -+ PIN_FIELD_BASE(70, 70, 5, 0x00, 0x10, 6, 3), -+ -+ PIN_FIELD_BASE(73, 73, 4, 0x10, 0x10, 0, 3), -+ PIN_FIELD_BASE(74, 74, 4, 0x00, 0x10, 3, 3), -+ PIN_FIELD_BASE(75, 75, 4, 0x10, 0x10, 3, 3), -+ PIN_FIELD_BASE(76, 76, 4, 0x00, 0x10, 27, 3), -+ PIN_FIELD_BASE(77, 77, 4, 0x00, 0x10, 6, 3), -+ PIN_FIELD_BASE(78, 78, 4, 0x00, 0x10, 0, 3), -+ PIN_FIELD_BASE(79, 79, 4, 0x10, 0x10, 6, 3), -+ -+ PIN_FIELD_BASE(80, 80, 1, 0x10, 0x10, 24, 3), -+ PIN_FIELD_BASE(81, 81, 1, 0x10, 0x10, 27, 3), -+ PIN_FIELD_BASE(82, 82, 1, 0x10, 0x10, 18, 3), -+ PIN_FIELD_BASE(83, 83, 1, 0x10, 0x10, 21, 3), -+}; -+ -+static const struct mtk_pin_field_calc mt7988_pin_pupd_range[] = { -+ PIN_FIELD_BASE(0, 0, 5, 0x50, 0x10, 7, 1), -+ PIN_FIELD_BASE(1, 1, 5, 0x50, 0x10, 8, 1), -+ PIN_FIELD_BASE(2, 2, 5, 0x50, 0x10, 5, 1), -+ PIN_FIELD_BASE(3, 3, 5, 0x50, 0x10, 6, 1), -+ PIN_FIELD_BASE(4, 4, 5, 0x50, 0x10, 0, 1), -+ PIN_FIELD_BASE(5, 5, 5, 0x50, 0x10, 3, 1), -+ PIN_FIELD_BASE(6, 6, 5, 0x50, 0x10, 4, 1), -+ -+ PIN_FIELD_BASE(11, 11, 1, 0x60, 0x10, 0, 1), -+ PIN_FIELD_BASE(12, 12, 1, 0x60, 0x10, 18, 1), -+ -+ PIN_FIELD_BASE(19, 19, 4, 0x50, 0x10, 2, 1), -+ PIN_FIELD_BASE(20, 20, 4, 0x50, 0x10, 1, 1), -+ -+ PIN_FIELD_BASE(21, 21, 3, 0x70, 0x10, 17, 1), -+ PIN_FIELD_BASE(22, 22, 3, 0x70, 0x10, 23, 1), -+ PIN_FIELD_BASE(23, 23, 3, 0x70, 0x10, 20, 1), -+ PIN_FIELD_BASE(24, 24, 3, 0x70, 0x10, 19, 1), -+ PIN_FIELD_BASE(25, 25, 3, 0x70, 0x10, 21, 1), -+ PIN_FIELD_BASE(26, 26, 3, 0x70, 0x10, 22, 1), -+ PIN_FIELD_BASE(27, 27, 3, 0x70, 0x10, 18, 1), -+ PIN_FIELD_BASE(28, 28, 3, 0x70, 0x10, 25, 1), -+ PIN_FIELD_BASE(29, 29, 3, 0x70, 0x10, 26, 1), -+ PIN_FIELD_BASE(30, 30, 3, 0x70, 0x10, 27, 1), -+ PIN_FIELD_BASE(31, 31, 3, 0x70, 0x10, 24, 1), -+ PIN_FIELD_BASE(32, 32, 3, 0x70, 0x10, 28, 1), -+ PIN_FIELD_BASE(33, 33, 3, 0x80, 0x10, 0, 1), -+ PIN_FIELD_BASE(34, 34, 3, 0x70, 0x10, 31, 1), -+ PIN_FIELD_BASE(35, 35, 3, 0x70, 0x10, 29, 1), -+ PIN_FIELD_BASE(36, 36, 3, 0x70, 0x10, 30, 1), -+ PIN_FIELD_BASE(37, 37, 3, 0x80, 0x10, 1, 1), -+ PIN_FIELD_BASE(38, 38, 3, 0x70, 0x10, 11, 1), -+ PIN_FIELD_BASE(39, 39, 3, 0x70, 0x10, 10, 1), -+ PIN_FIELD_BASE(40, 40, 3, 0x70, 0x10, 0, 1), -+ PIN_FIELD_BASE(41, 41, 3, 0x70, 0x10, 1, 1), -+ PIN_FIELD_BASE(42, 42, 3, 0x70, 0x10, 9, 1), -+ PIN_FIELD_BASE(43, 43, 3, 0x70, 0x10, 8, 1), -+ PIN_FIELD_BASE(44, 44, 3, 0x70, 0x10, 7, 1), -+ PIN_FIELD_BASE(45, 45, 3, 0x70, 0x10, 6, 1), -+ PIN_FIELD_BASE(46, 46, 3, 0x70, 0x10, 5, 1), -+ PIN_FIELD_BASE(47, 47, 3, 0x70, 0x10, 4, 1), -+ PIN_FIELD_BASE(48, 48, 3, 0x70, 0x10, 3, 1), -+ PIN_FIELD_BASE(49, 49, 3, 0x70, 0x10, 2, 1), -+ PIN_FIELD_BASE(50, 50, 3, 0x70, 0x10, 15, 1), -+ PIN_FIELD_BASE(51, 51, 3, 0x70, 0x10, 12, 1), -+ PIN_FIELD_BASE(52, 52, 3, 0x70, 0x10, 13, 1), -+ PIN_FIELD_BASE(53, 53, 3, 0x70, 0x10, 14, 1), -+ PIN_FIELD_BASE(54, 54, 3, 0x70, 0x10, 16, 1), -+ -+ PIN_FIELD_BASE(55, 55, 1, 0x60, 0x10, 12, 1), -+ PIN_FIELD_BASE(56, 56, 1, 0x60, 0x10, 13, 1), -+ PIN_FIELD_BASE(57, 57, 1, 0x60, 0x10, 11, 1), -+ PIN_FIELD_BASE(58, 58, 1, 0x60, 0x10, 2, 1), -+ PIN_FIELD_BASE(59, 59, 1, 0x60, 0x10, 3, 1), -+ PIN_FIELD_BASE(60, 60, 1, 0x60, 0x10, 4, 1), -+ PIN_FIELD_BASE(61, 61, 1, 0x60, 0x10, 1, 1), -+ PIN_FIELD_BASE(62, 62, 1, 0x60, 0x10, 5, 1), -+ PIN_FIELD_BASE(64, 64, 1, 0x60, 0x10, 6, 1), -+ PIN_FIELD_BASE(65, 65, 1, 0x60, 0x10, 7, 1), -+ PIN_FIELD_BASE(66, 66, 1, 0x60, 0x10, 8, 1), -+ PIN_FIELD_BASE(67, 67, 1, 0x60, 0x10, 9, 1), -+ PIN_FIELD_BASE(68, 68, 1, 0x60, 0x10, 10, 1), -+ -+ PIN_FIELD_BASE(69, 69, 5, 0x50, 0x10, 1, 1), -+ PIN_FIELD_BASE(70, 70, 5, 0x50, 0x10, 2, 1), -+ -+ PIN_FIELD_BASE(73, 73, 4, 0x50, 0x10, 3, 1), -+ PIN_FIELD_BASE(74, 74, 4, 0x50, 0x10, 0, 1), -+ -+ PIN_FIELD_BASE(80, 80, 1, 0x60, 0x10, 16, 1), -+ PIN_FIELD_BASE(81, 81, 1, 0x60, 0x10, 17, 1), -+ PIN_FIELD_BASE(82, 82, 1, 0x60, 0x10, 14, 1), -+ PIN_FIELD_BASE(83, 83, 1, 0x60, 0x10, 15, 1), -+}; -+ -+static const struct mtk_pin_field_calc mt7988_pin_r0_range[] = { -+ PIN_FIELD_BASE(0, 0, 5, 0x60, 0x10, 7, 1), -+ PIN_FIELD_BASE(1, 1, 5, 0x60, 0x10, 8, 1), -+ PIN_FIELD_BASE(2, 2, 5, 0x60, 0x10, 5, 1), -+ PIN_FIELD_BASE(3, 3, 5, 0x60, 0x10, 6, 1), -+ PIN_FIELD_BASE(4, 4, 5, 0x60, 0x10, 0, 1), -+ PIN_FIELD_BASE(5, 5, 5, 0x60, 0x10, 3, 1), -+ PIN_FIELD_BASE(6, 6, 5, 0x60, 0x10, 4, 1), -+ -+ PIN_FIELD_BASE(11, 11, 1, 0x80, 0x10, 0, 1), -+ PIN_FIELD_BASE(12, 12, 1, 0x80, 0x10, 18, 1), -+ -+ PIN_FIELD_BASE(19, 19, 4, 0x70, 0x10, 2, 1), -+ PIN_FIELD_BASE(20, 20, 4, 0x70, 0x10, 1, 1), -+ -+ PIN_FIELD_BASE(21, 21, 3, 0x90, 0x10, 17, 1), -+ PIN_FIELD_BASE(22, 22, 3, 0x90, 0x10, 23, 1), -+ PIN_FIELD_BASE(23, 23, 3, 0x90, 0x10, 20, 1), -+ PIN_FIELD_BASE(24, 24, 3, 0x90, 0x10, 19, 1), -+ PIN_FIELD_BASE(25, 25, 3, 0x90, 0x10, 21, 1), -+ PIN_FIELD_BASE(26, 26, 3, 0x90, 0x10, 22, 1), -+ PIN_FIELD_BASE(27, 27, 3, 0x90, 0x10, 18, 1), -+ PIN_FIELD_BASE(28, 28, 3, 0x90, 0x10, 25, 1), -+ PIN_FIELD_BASE(29, 29, 3, 0x90, 0x10, 26, 1), -+ PIN_FIELD_BASE(30, 30, 3, 0x90, 0x10, 27, 1), -+ PIN_FIELD_BASE(31, 31, 3, 0x90, 0x10, 24, 1), -+ PIN_FIELD_BASE(32, 32, 3, 0x90, 0x10, 28, 1), -+ PIN_FIELD_BASE(33, 33, 3, 0xa0, 0x10, 0, 1), -+ PIN_FIELD_BASE(34, 34, 3, 0x90, 0x10, 31, 1), -+ PIN_FIELD_BASE(35, 35, 3, 0x90, 0x10, 29, 1), -+ PIN_FIELD_BASE(36, 36, 3, 0x90, 0x10, 30, 1), -+ PIN_FIELD_BASE(37, 37, 3, 0xa0, 0x10, 1, 1), -+ PIN_FIELD_BASE(38, 38, 3, 0x90, 0x10, 11, 1), -+ PIN_FIELD_BASE(39, 39, 3, 0x90, 0x10, 10, 1), -+ PIN_FIELD_BASE(40, 40, 3, 0x90, 0x10, 0, 1), -+ PIN_FIELD_BASE(41, 41, 3, 0x90, 0x10, 1, 1), -+ PIN_FIELD_BASE(42, 42, 3, 0x90, 0x10, 9, 1), -+ PIN_FIELD_BASE(43, 43, 3, 0x90, 0x10, 8, 1), -+ PIN_FIELD_BASE(44, 44, 3, 0x90, 0x10, 7, 1), -+ PIN_FIELD_BASE(45, 45, 3, 0x90, 0x10, 6, 1), -+ PIN_FIELD_BASE(46, 46, 3, 0x90, 0x10, 5, 1), -+ PIN_FIELD_BASE(47, 47, 3, 0x90, 0x10, 4, 1), -+ PIN_FIELD_BASE(48, 48, 3, 0x90, 0x10, 3, 1), -+ PIN_FIELD_BASE(49, 49, 3, 0x90, 0x10, 2, 1), -+ PIN_FIELD_BASE(50, 50, 3, 0x90, 0x10, 15, 1), -+ PIN_FIELD_BASE(51, 51, 3, 0x90, 0x10, 12, 1), -+ PIN_FIELD_BASE(52, 52, 3, 0x90, 0x10, 13, 1), -+ PIN_FIELD_BASE(53, 53, 3, 0x90, 0x10, 14, 1), -+ PIN_FIELD_BASE(54, 54, 3, 0x90, 0x10, 16, 1), -+ -+ PIN_FIELD_BASE(55, 55, 1, 0x80, 0x10, 12, 1), -+ PIN_FIELD_BASE(56, 56, 1, 0x80, 0x10, 13, 1), -+ PIN_FIELD_BASE(57, 57, 1, 0x80, 0x10, 11, 1), -+ PIN_FIELD_BASE(58, 58, 1, 0x80, 0x10, 2, 1), -+ PIN_FIELD_BASE(59, 59, 1, 0x80, 0x10, 3, 1), -+ PIN_FIELD_BASE(60, 60, 1, 0x80, 0x10, 4, 1), -+ PIN_FIELD_BASE(61, 61, 1, 0x80, 0x10, 1, 1), -+ PIN_FIELD_BASE(62, 62, 1, 0x80, 0x10, 5, 1), -+ PIN_FIELD_BASE(64, 64, 1, 0x80, 0x10, 6, 1), -+ PIN_FIELD_BASE(65, 65, 1, 0x80, 0x10, 7, 1), -+ PIN_FIELD_BASE(66, 66, 1, 0x80, 0x10, 8, 1), -+ PIN_FIELD_BASE(67, 67, 1, 0x80, 0x10, 9, 1), -+ PIN_FIELD_BASE(68, 68, 1, 0x80, 0x10, 10, 1), -+ -+ PIN_FIELD_BASE(69, 69, 5, 0x60, 0x10, 1, 1), -+ PIN_FIELD_BASE(70, 70, 5, 0x60, 0x10, 2, 1), -+ -+ PIN_FIELD_BASE(73, 73, 4, 0x70, 0x10, 3, 1), -+ PIN_FIELD_BASE(74, 74, 4, 0x70, 0x10, 0, 1), -+ -+ PIN_FIELD_BASE(80, 80, 1, 0x80, 0x10, 16, 1), -+ PIN_FIELD_BASE(81, 81, 1, 0x80, 0x10, 17, 1), -+ PIN_FIELD_BASE(82, 82, 1, 0x80, 0x10, 14, 1), -+ PIN_FIELD_BASE(83, 83, 1, 0x80, 0x10, 15, 1), -+}; -+ -+static const struct mtk_pin_field_calc mt7988_pin_r1_range[] = { -+ PIN_FIELD_BASE(0, 0, 5, 0x70, 0x10, 7, 1), -+ PIN_FIELD_BASE(1, 1, 5, 0x70, 0x10, 8, 1), -+ PIN_FIELD_BASE(2, 2, 5, 0x70, 0x10, 5, 1), -+ PIN_FIELD_BASE(3, 3, 5, 0x70, 0x10, 6, 1), -+ PIN_FIELD_BASE(4, 4, 5, 0x70, 0x10, 0, 1), -+ PIN_FIELD_BASE(5, 5, 5, 0x70, 0x10, 3, 1), -+ PIN_FIELD_BASE(6, 6, 5, 0x70, 0x10, 4, 1), -+ -+ PIN_FIELD_BASE(11, 11, 1, 0x90, 0x10, 0, 1), -+ PIN_FIELD_BASE(12, 12, 1, 0x90, 0x10, 18, 1), -+ -+ PIN_FIELD_BASE(19, 19, 4, 0x80, 0x10, 2, 1), -+ PIN_FIELD_BASE(20, 20, 4, 0x80, 0x10, 1, 1), -+ -+ PIN_FIELD_BASE(21, 21, 3, 0xb0, 0x10, 17, 1), -+ PIN_FIELD_BASE(22, 22, 3, 0xb0, 0x10, 23, 1), -+ PIN_FIELD_BASE(23, 23, 3, 0xb0, 0x10, 20, 1), -+ PIN_FIELD_BASE(24, 24, 3, 0xb0, 0x10, 19, 1), -+ PIN_FIELD_BASE(25, 25, 3, 0xb0, 0x10, 21, 1), -+ PIN_FIELD_BASE(26, 26, 3, 0xb0, 0x10, 22, 1), -+ PIN_FIELD_BASE(27, 27, 3, 0xb0, 0x10, 18, 1), -+ PIN_FIELD_BASE(28, 28, 3, 0xb0, 0x10, 25, 1), -+ PIN_FIELD_BASE(29, 29, 3, 0xb0, 0x10, 26, 1), -+ PIN_FIELD_BASE(30, 30, 3, 0xb0, 0x10, 27, 1), -+ PIN_FIELD_BASE(31, 31, 3, 0xb0, 0x10, 24, 1), -+ PIN_FIELD_BASE(32, 32, 3, 0xb0, 0x10, 28, 1), -+ PIN_FIELD_BASE(33, 33, 3, 0xc0, 0x10, 0, 1), -+ PIN_FIELD_BASE(34, 34, 3, 0xb0, 0x10, 31, 1), -+ PIN_FIELD_BASE(35, 35, 3, 0xb0, 0x10, 29, 1), -+ PIN_FIELD_BASE(36, 36, 3, 0xb0, 0x10, 30, 1), -+ PIN_FIELD_BASE(37, 37, 3, 0xc0, 0x10, 1, 1), -+ PIN_FIELD_BASE(38, 38, 3, 0xb0, 0x10, 11, 1), -+ PIN_FIELD_BASE(39, 39, 3, 0xb0, 0x10, 10, 1), -+ PIN_FIELD_BASE(40, 40, 3, 0xb0, 0x10, 0, 1), -+ PIN_FIELD_BASE(41, 41, 3, 0xb0, 0x10, 1, 1), -+ PIN_FIELD_BASE(42, 42, 3, 0xb0, 0x10, 9, 1), -+ PIN_FIELD_BASE(43, 43, 3, 0xb0, 0x10, 8, 1), -+ PIN_FIELD_BASE(44, 44, 3, 0xb0, 0x10, 7, 1), -+ PIN_FIELD_BASE(45, 45, 3, 0xb0, 0x10, 6, 1), -+ PIN_FIELD_BASE(46, 46, 3, 0xb0, 0x10, 5, 1), -+ PIN_FIELD_BASE(47, 47, 3, 0xb0, 0x10, 4, 1), -+ PIN_FIELD_BASE(48, 48, 3, 0xb0, 0x10, 3, 1), -+ PIN_FIELD_BASE(49, 49, 3, 0xb0, 0x10, 2, 1), -+ PIN_FIELD_BASE(50, 50, 3, 0xb0, 0x10, 15, 1), -+ PIN_FIELD_BASE(51, 51, 3, 0xb0, 0x10, 12, 1), -+ PIN_FIELD_BASE(52, 52, 3, 0xb0, 0x10, 13, 1), -+ PIN_FIELD_BASE(53, 53, 3, 0xb0, 0x10, 14, 1), -+ PIN_FIELD_BASE(54, 54, 3, 0xb0, 0x10, 16, 1), -+ -+ PIN_FIELD_BASE(55, 55, 1, 0x90, 0x10, 12, 1), -+ PIN_FIELD_BASE(56, 56, 1, 0x90, 0x10, 13, 1), -+ PIN_FIELD_BASE(57, 57, 1, 0x90, 0x10, 11, 1), -+ PIN_FIELD_BASE(58, 58, 1, 0x90, 0x10, 2, 1), -+ PIN_FIELD_BASE(59, 59, 1, 0x90, 0x10, 3, 1), -+ PIN_FIELD_BASE(60, 60, 1, 0x90, 0x10, 4, 1), -+ PIN_FIELD_BASE(61, 61, 1, 0x90, 0x10, 1, 1), -+ PIN_FIELD_BASE(62, 62, 1, 0x90, 0x10, 5, 1), -+ PIN_FIELD_BASE(64, 64, 1, 0x90, 0x10, 6, 1), -+ PIN_FIELD_BASE(65, 65, 1, 0x90, 0x10, 7, 1), -+ PIN_FIELD_BASE(66, 66, 1, 0x90, 0x10, 8, 1), -+ PIN_FIELD_BASE(67, 67, 1, 0x90, 0x10, 9, 1), -+ PIN_FIELD_BASE(68, 68, 1, 0x90, 0x10, 10, 1), -+ -+ PIN_FIELD_BASE(69, 69, 5, 0x70, 0x10, 1, 1), -+ PIN_FIELD_BASE(70, 70, 5, 0x70, 0x10, 2, 1), -+ -+ PIN_FIELD_BASE(73, 73, 4, 0x80, 0x10, 3, 1), -+ PIN_FIELD_BASE(74, 74, 4, 0x80, 0x10, 0, 1), -+ -+ PIN_FIELD_BASE(80, 80, 1, 0x90, 0x10, 16, 1), -+ PIN_FIELD_BASE(81, 81, 1, 0x90, 0x10, 17, 1), -+ PIN_FIELD_BASE(82, 82, 1, 0x90, 0x10, 14, 1), -+ PIN_FIELD_BASE(83, 83, 1, 0x90, 0x10, 15, 1), -+}; -+ -+static const unsigned int mt7988_pull_type[] = { -+ MTK_PULL_PUPD_R1R0_TYPE,/*0*/ MTK_PULL_PUPD_R1R0_TYPE,/*1*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*2*/ MTK_PULL_PUPD_R1R0_TYPE,/*3*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*4*/ MTK_PULL_PUPD_R1R0_TYPE,/*5*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*6*/ MTK_PULL_PU_PD_TYPE, /*7*/ -+ MTK_PULL_PU_PD_TYPE, /*8*/ MTK_PULL_PU_PD_TYPE, /*9*/ -+ MTK_PULL_PU_PD_TYPE, /*10*/ MTK_PULL_PUPD_R1R0_TYPE,/*11*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*12*/ MTK_PULL_PU_PD_TYPE, /*13*/ -+ MTK_PULL_PU_PD_TYPE, /*14*/ MTK_PULL_PD_TYPE, /*15*/ -+ MTK_PULL_PD_TYPE, /*16*/ MTK_PULL_PD_TYPE, /*17*/ -+ MTK_PULL_PD_TYPE, /*18*/ MTK_PULL_PUPD_R1R0_TYPE,/*19*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*20*/ MTK_PULL_PUPD_R1R0_TYPE,/*21*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*22*/ MTK_PULL_PUPD_R1R0_TYPE,/*23*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*24*/ MTK_PULL_PUPD_R1R0_TYPE,/*25*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*26*/ MTK_PULL_PUPD_R1R0_TYPE,/*27*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*28*/ MTK_PULL_PUPD_R1R0_TYPE,/*29*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*30*/ MTK_PULL_PUPD_R1R0_TYPE,/*31*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*32*/ MTK_PULL_PUPD_R1R0_TYPE,/*33*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*34*/ MTK_PULL_PUPD_R1R0_TYPE,/*35*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*36*/ MTK_PULL_PUPD_R1R0_TYPE,/*37*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*38*/ MTK_PULL_PUPD_R1R0_TYPE,/*39*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*40*/ MTK_PULL_PUPD_R1R0_TYPE,/*41*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*42*/ MTK_PULL_PUPD_R1R0_TYPE,/*43*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*44*/ MTK_PULL_PUPD_R1R0_TYPE,/*45*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*46*/ MTK_PULL_PUPD_R1R0_TYPE,/*47*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*48*/ MTK_PULL_PUPD_R1R0_TYPE,/*49*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*50*/ MTK_PULL_PUPD_R1R0_TYPE,/*51*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*52*/ MTK_PULL_PUPD_R1R0_TYPE,/*53*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*54*/ MTK_PULL_PUPD_R1R0_TYPE,/*55*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*56*/ MTK_PULL_PUPD_R1R0_TYPE,/*57*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*58*/ MTK_PULL_PUPD_R1R0_TYPE,/*59*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*60*/ MTK_PULL_PUPD_R1R0_TYPE,/*61*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*62*/ MTK_PULL_PU_PD_TYPE, /*63*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*64*/ MTK_PULL_PUPD_R1R0_TYPE,/*65*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*66*/ MTK_PULL_PUPD_R1R0_TYPE,/*67*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*68*/ MTK_PULL_PUPD_R1R0_TYPE,/*69*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*70*/ MTK_PULL_PD_TYPE, /*71*/ -+ MTK_PULL_PD_TYPE, /*72*/ MTK_PULL_PUPD_R1R0_TYPE,/*73*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*74*/ MTK_PULL_PU_PD_TYPE, /*75*/ -+ MTK_PULL_PU_PD_TYPE, /*76*/ MTK_PULL_PU_PD_TYPE, /*77*/ -+ MTK_PULL_PU_PD_TYPE, /*78*/ MTK_PULL_PU_PD_TYPE, /*79*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*80*/ MTK_PULL_PUPD_R1R0_TYPE,/*81*/ -+ MTK_PULL_PUPD_R1R0_TYPE,/*82*/ MTK_PULL_PUPD_R1R0_TYPE,/*83*/ -+}; -+ -+static const struct mtk_pin_reg_calc mt7988_reg_cals[] = { -+ [PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7988_pin_mode_range), -+ [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7988_pin_dir_range), -+ [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7988_pin_di_range), -+ [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7988_pin_do_range), -+ [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7988_pin_smt_range), -+ [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7988_pin_ies_range), -+ [PINCTRL_PIN_REG_PU] = MTK_RANGE(mt7988_pin_pu_range), -+ [PINCTRL_PIN_REG_PD] = MTK_RANGE(mt7988_pin_pd_range), -+ [PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7988_pin_drv_range), -+ [PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt7988_pin_pupd_range), -+ [PINCTRL_PIN_REG_R0] = MTK_RANGE(mt7988_pin_r0_range), -+ [PINCTRL_PIN_REG_R1] = MTK_RANGE(mt7988_pin_r1_range), -+}; -+ -+static const struct mtk_pin_desc mt7988_pins[] = { -+ MT7988_PIN(0, "UART2_RXD"), -+ MT7988_PIN(1, "UART2_TXD"), -+ MT7988_PIN(2, "UART2_CTS"), -+ MT7988_PIN(3, "UART2_RTS"), -+ MT7988_PIN(4, "GPIO_A"), -+ MT7988_PIN(5, "SMI_0_MDC"), -+ MT7988_PIN(6, "SMI_0_MDIO"), -+ MT7988_PIN(7, "PCIE30_2L_0_WAKE_N"), -+ MT7988_PIN(8, "PCIE30_2L_0_CLKREQ_N"), -+ MT7988_PIN(9, "PCIE30_1L_1_WAKE_N"), -+ MT7988_PIN(10, "PCIE30_1L_1_CLKREQ_N"), -+ MT7988_PIN(11, "GPIO_P"), -+ MT7988_PIN(12, "WATCHDOG"), -+ MT7988_PIN(13, "GPIO_RESET"), -+ MT7988_PIN(14, "GPIO_WPS"), -+ MT7988_PIN(15, "PMIC_I2C_SCL"), -+ MT7988_PIN(16, "PMIC_I2C_SDA"), -+ MT7988_PIN(17, "I2C_1_SCL"), -+ MT7988_PIN(18, "I2C_1_SDA"), -+ MT7988_PIN(19, "PCIE30_2L_0_PRESET_N"), -+ MT7988_PIN(20, "PCIE30_1L_1_PRESET_N"), -+ MT7988_PIN(21, "PWMD1"), -+ MT7988_PIN(22, "SPI0_WP"), -+ MT7988_PIN(23, "SPI0_HOLD"), -+ MT7988_PIN(24, "SPI0_CSB"), -+ MT7988_PIN(25, "SPI0_MISO"), -+ MT7988_PIN(26, "SPI0_MOSI"), -+ MT7988_PIN(27, "SPI0_CLK"), -+ MT7988_PIN(28, "SPI1_CSB"), -+ MT7988_PIN(29, "SPI1_MISO"), -+ MT7988_PIN(30, "SPI1_MOSI"), -+ MT7988_PIN(31, "SPI1_CLK"), -+ MT7988_PIN(32, "SPI2_CLK"), -+ MT7988_PIN(33, "SPI2_MOSI"), -+ MT7988_PIN(34, "SPI2_MISO"), -+ MT7988_PIN(35, "SPI2_CSB"), -+ MT7988_PIN(36, "SPI2_HOLD"), -+ MT7988_PIN(37, "SPI2_WP"), -+ MT7988_PIN(38, "EMMC_RSTB"), -+ MT7988_PIN(39, "EMMC_DSL"), -+ MT7988_PIN(40, "EMMC_CK"), -+ MT7988_PIN(41, "EMMC_CMD"), -+ MT7988_PIN(42, "EMMC_DATA_7"), -+ MT7988_PIN(43, "EMMC_DATA_6"), -+ MT7988_PIN(44, "EMMC_DATA_5"), -+ MT7988_PIN(45, "EMMC_DATA_4"), -+ MT7988_PIN(46, "EMMC_DATA_3"), -+ MT7988_PIN(47, "EMMC_DATA_2"), -+ MT7988_PIN(48, "EMMC_DATA_1"), -+ MT7988_PIN(49, "EMMC_DATA_0"), -+ MT7988_PIN(50, "PCM_FS_I2S_LRCK"), -+ MT7988_PIN(51, "PCM_CLK_I2S_BCLK"), -+ MT7988_PIN(52, "PCM_DRX_I2S_DIN"), -+ MT7988_PIN(53, "PCM_DTX_I2S_DOUT"), -+ MT7988_PIN(54, "PCM_MCK_I2S_MCLK"), -+ MT7988_PIN(55, "UART0_RXD"), -+ MT7988_PIN(56, "UART0_TXD"), -+ MT7988_PIN(57, "PWMD0"), -+ MT7988_PIN(58, "JTAG_JTDI"), -+ MT7988_PIN(59, "JTAG_JTDO"), -+ MT7988_PIN(60, "JTAG_JTMS"), -+ MT7988_PIN(61, "JTAG_JTCLK"), -+ MT7988_PIN(62, "JTAG_JTRST_N"), -+ MT7988_PIN(63, "USB_DRV_VBUS_P1"), -+ MT7988_PIN(64, "LED_A"), -+ MT7988_PIN(65, "LED_B"), -+ MT7988_PIN(66, "LED_C"), -+ MT7988_PIN(67, "LED_D"), -+ MT7988_PIN(68, "LED_E"), -+ MT7988_PIN(69, "GPIO_B"), -+ MT7988_PIN(70, "GPIO_C"), -+ MT7988_PIN(71, "I2C_2_SCL"), -+ MT7988_PIN(72, "I2C_2_SDA"), -+ MT7988_PIN(73, "PCIE30_2L_1_PRESET_N"), -+ MT7988_PIN(74, "PCIE30_1L_0_PRESET_N"), -+ MT7988_PIN(75, "PCIE30_2L_1_WAKE_N"), -+ MT7988_PIN(76, "PCIE30_2L_1_CLKREQ_N"), -+ MT7988_PIN(77, "PCIE30_1L_0_WAKE_N"), -+ MT7988_PIN(78, "PCIE30_1L_0_CLKREQ_N"), -+ MT7988_PIN(79, "USB_DRV_VBUS_P0"), -+ MT7988_PIN(80, "UART1_RXD"), -+ MT7988_PIN(81, "UART1_TXD"), -+ MT7988_PIN(82, "UART1_CTS"), -+ MT7988_PIN(83, "UART1_RTS"), -+}; -+ -+/* jtag */ -+static const int mt7988_tops_jtag0_0_pins[] = { 0, 1, 2, 3, 4 }; -+static int mt7988_tops_jtag0_0_funcs[] = { 2, 2, 2, 2, 2 }; -+ -+static const int mt7988_wo0_jtag_pins[] = { 50, 51, 52, 53, 54 }; -+static int mt7988_wo0_jtag_funcs[] = { 3, 3, 3, 3, 3 }; -+ -+static const int mt7988_wo1_jtag_pins[] = { 50, 51, 52, 53, 54 }; -+static int mt7988_wo1_jtag_funcs[] = { 4, 4, 4, 4, 4 }; -+ -+static const int mt7988_wo2_jtag_pins[] = { 50, 51, 52, 53, 54 }; -+static int mt7988_wo2_jtag_funcs[] = { 5, 5, 5, 5, 5 }; -+ -+static const int mt7988_jtag_pins[] = { 58, 59, 60, 61, 62 }; -+static int mt7988_jtag_funcs[] = { 1, 1, 1, 1, 1 }; -+ -+static const int mt7988_tops_jtag0_1_pins[] = { 58, 59, 60, 61, 62 }; -+static int mt7988_tops_jtag0_1_funcs[] = { 4, 4, 4, 4, 4 }; -+ -+/* int_usxgmii */ -+static const int mt7988_int_usxgmii_pins[] = { 2, 3 }; -+static int mt7988_int_usxgmii_funcs[] = { 3, 3 }; -+ -+/* pwm */ -+static const int mt7988_pwm0_pins[] = { 57 }; -+static int mt7988_pwm0_funcs[] = { 1 }; -+ -+static const int mt7988_pwm1_pins[] = { 21 }; -+static int mt7988_pwm1_funcs[] = { 1 }; -+ -+static const int mt7988_pwm2_pins[] = { 80 }; -+static int mt7988_pwm2_funcs[] = { 2 }; -+ -+static const int mt7988_pwm2_0_pins[] = { 58 }; -+static int mt7988_pwm2_0_funcs[] = { 5 }; -+ -+static const int mt7988_pwm3_pins[] = { 81 }; -+static int mt7988_pwm3_funcs[] = { 2 }; -+ -+static const int mt7988_pwm3_0_pins[] = { 59 }; -+static int mt7988_pwm3_0_funcs[] = { 5 }; -+ -+static const int mt7988_pwm4_pins[] = { 82 }; -+static int mt7988_pwm4_funcs[] = { 2 }; -+ -+static const int mt7988_pwm4_0_pins[] = { 60 }; -+static int mt7988_pwm4_0_funcs[] = { 5 }; -+ -+static const int mt7988_pwm5_pins[] = { 83 }; -+static int mt7988_pwm5_funcs[] = { 2 }; -+ -+static const int mt7988_pwm5_0_pins[] = { 61 }; -+static int mt7988_pwm5_0_funcs[] = { 5 }; -+ -+static const int mt7988_pwm6_pins[] = { 69 }; -+static int mt7988_pwm6_funcs[] = { 3 }; -+ -+static const int mt7988_pwm6_0_pins[] = { 62 }; -+static int mt7988_pwm6_0_funcs[] = { 5 }; -+ -+static const int mt7988_pwm7_pins[] = { 70 }; -+static int mt7988_pwm7_funcs[] = { 3 }; -+ -+static const int mt7988_pwm7_0_pins[] = { 4 }; -+static int mt7988_pwm7_0_funcs[] = { 3 }; -+ -+/* dfd */ -+static const int mt7988_dfd_pins[] = { 0, 1, 2, 3, 4 }; -+static int mt7988_dfd_funcs[] = { 4, 4, 4, 4, 4 }; -+ -+/* i2c */ -+static const int mt7988_xfi_phy0_i2c0_pins[] = { 0, 1 }; -+static int mt7988_xfi_phy0_i2c0_funcs[] = { 5, 5 }; -+ -+static const int mt7988_xfi_phy1_i2c0_pins[] = { 0, 1 }; -+static int mt7988_xfi_phy1_i2c0_funcs[] = { 6, 6 }; -+ -+static const int mt7988_xfi_phy_pll_i2c0_pins[] = { 3, 4 }; -+static int mt7988_xfi_phy_pll_i2c0_funcs[] = { 5, 5 }; -+ -+static const int mt7988_xfi_phy_pll_i2c1_pins[] = { 3, 4 }; -+static int mt7988_xfi_phy_pll_i2c1_funcs[] = { 6, 6 }; -+ -+static const int mt7988_i2c0_0_pins[] = { 5, 6 }; -+static int mt7988_i2c0_0_funcs[] = { 2, 2 }; -+ -+static const int mt7988_i2c1_sfp_pins[] = { 5, 6 }; -+static int mt7988_i2c1_sfp_funcs[] = { 4, 4 }; -+ -+static const int mt7988_xfi_pextp_phy0_i2c_pins[] = { 5, 6 }; -+static int mt7988_xfi_pextp_phy0_i2c_funcs[] = { 5, 5 }; -+ -+static const int mt7988_xfi_pextp_phy1_i2c_pins[] = { 5, 6 }; -+static int mt7988_xfi_pextp_phy1_i2c_funcs[] = { 6, 6 }; -+ -+static const int mt7988_i2c0_1_pins[] = { 15, 16 }; -+static int mt7988_i2c0_1_funcs[] = { 1, 1 }; -+ -+static const int mt7988_u30_phy_i2c0_pins[] = { 15, 16 }; -+static int mt7988_u30_phy_i2c0_funcs[] = { 2, 2 }; -+ -+static const int mt7988_u32_phy_i2c0_pins[] = { 15, 16 }; -+static int mt7988_u32_phy_i2c0_funcs[] = { 3, 3 }; -+ -+static const int mt7988_xfi_phy0_i2c1_pins[] = { 15, 16 }; -+static int mt7988_xfi_phy0_i2c1_funcs[] = { 5, 5 }; -+ -+static const int mt7988_xfi_phy1_i2c1_pins[] = { 15, 16 }; -+static int mt7988_xfi_phy1_i2c1_funcs[] = { 6, 6 }; -+ -+static const int mt7988_xfi_phy_pll_i2c2_pins[] = { 15, 16 }; -+static int mt7988_xfi_phy_pll_i2c2_funcs[] = { 7, 7 }; -+ -+static const int mt7988_i2c1_0_pins[] = { 17, 18 }; -+static int mt7988_i2c1_0_funcs[] = { 1, 1 }; -+ -+static const int mt7988_u30_phy_i2c1_pins[] = { 17, 18 }; -+static int mt7988_u30_phy_i2c1_funcs[] = { 2, 2 }; -+ -+static const int mt7988_u32_phy_i2c1_pins[] = { 17, 18 }; -+static int mt7988_u32_phy_i2c1_funcs[] = { 3, 3 }; -+ -+static const int mt7988_xfi_phy_pll_i2c3_pins[] = { 17, 18 }; -+static int mt7988_xfi_phy_pll_i2c3_funcs[] = { 4, 4 }; -+ -+static const int mt7988_sgmii0_i2c_pins[] = { 17, 18 }; -+static int mt7988_sgmii0_i2c_funcs[] = { 5, 5 }; -+ -+static const int mt7988_sgmii1_i2c_pins[] = { 17, 18 }; -+static int mt7988_sgmii1_i2c_funcs[] = { 6, 6 }; -+ -+static const int mt7988_i2c1_2_pins[] = { 69, 70 }; -+static int mt7988_i2c1_2_funcs[] = { 2, 2 }; -+ -+static const int mt7988_i2c2_0_pins[] = { 69, 70 }; -+static int mt7988_i2c2_0_funcs[] = { 4, 4 }; -+ -+static const int mt7988_i2c2_1_pins[] = { 71, 72 }; -+static int mt7988_i2c2_1_funcs[] = { 1, 1 }; -+ -+/* eth */ -+static const int mt7988_mdc_mdio0_pins[] = { 5, 6 }; -+static int mt7988_mdc_mdio0_funcs[] = { 1, 1 }; -+ -+static const int mt7988_2p5g_ext_mdio_pins[] = { 28, 29 }; -+static int mt7988_2p5g_ext_mdio_funcs[] = { 6, 6 }; -+ -+static const int mt7988_gbe_ext_mdio_pins[] = { 30, 31 }; -+static int mt7988_gbe_ext_mdio_funcs[] = { 6, 6 }; -+ -+static const int mt7988_mdc_mdio1_pins[] = { 69, 70 }; -+static int mt7988_mdc_mdio1_funcs[] = { 1, 1 }; -+ -+/* pcie */ -+static const int mt7988_pcie_wake_n0_0_pins[] = { 7 }; -+static int mt7988_pcie_wake_n0_0_funcs[] = { 1 }; -+ -+static const int mt7988_pcie_clk_req_n0_0_pins[] = { 8 }; -+static int mt7988_pcie_clk_req_n0_0_funcs[] = { 1 }; -+ -+static const int mt7988_pcie_wake_n3_0_pins[] = { 9 }; -+static int mt7988_pcie_wake_n3_0_funcs[] = { 1 }; -+ -+static const int mt7988_pcie_clk_req_n3_pins[] = { 10 }; -+static int mt7988_pcie_clk_req_n3_funcs[] = { 1 }; -+ -+static const int mt7988_pcie_clk_req_n0_1_pins[] = { 10 }; -+static int mt7988_pcie_clk_req_n0_1_funcs[] = { 2 }; -+ -+static const int mt7988_pcie_p0_phy_i2c_pins[] = { 7, 8 }; -+static int mt7988_pcie_p0_phy_i2c_funcs[] = { 3, 3 }; -+ -+static const int mt7988_pcie_p1_phy_i2c_pins[] = { 7, 8 }; -+static int mt7988_pcie_p1_phy_i2c_funcs[] = { 4, 4 }; -+ -+static const int mt7988_pcie_p3_phy_i2c_pins[] = { 9, 10 }; -+static int mt7988_pcie_p3_phy_i2c_funcs[] = { 4, 4 }; -+ -+static const int mt7988_pcie_p2_phy_i2c_pins[] = { 7, 8 }; -+static int mt7988_pcie_p2_phy_i2c_funcs[] = { 5, 5 }; -+ -+static const int mt7988_ckm_phy_i2c_pins[] = { 9, 10 }; -+static int mt7988_ckm_phy_i2c_funcs[] = { 5, 5 }; -+ -+static const int mt7988_pcie_wake_n0_1_pins[] = { 13 }; -+static int mt7988_pcie_wake_n0_1_funcs[] = { 2 }; -+ -+static const int mt7988_pcie_wake_n3_1_pins[] = { 14 }; -+static int mt7988_pcie_wake_n3_1_funcs[] = { 2 }; -+ -+static const int mt7988_pcie_2l_0_pereset_pins[] = { 19 }; -+static int mt7988_pcie_2l_0_pereset_funcs[] = { 1 }; -+ -+static const int mt7988_pcie_1l_1_pereset_pins[] = { 20 }; -+static int mt7988_pcie_1l_1_pereset_funcs[] = { 1 }; -+ -+static const int mt7988_pcie_clk_req_n2_1_pins[] = { 63 }; -+static int mt7988_pcie_clk_req_n2_1_funcs[] = { 2 }; -+ -+static const int mt7988_pcie_2l_1_pereset_pins[] = { 73 }; -+static int mt7988_pcie_2l_1_pereset_funcs[] = { 1 }; -+ -+static const int mt7988_pcie_1l_0_pereset_pins[] = { 74 }; -+static int mt7988_pcie_1l_0_pereset_funcs[] = { 1 }; -+ -+static const int mt7988_pcie_wake_n1_0_pins[] = { 75 }; -+static int mt7988_pcie_wake_n1_0_funcs[] = { 1 }; -+ -+static const int mt7988_pcie_clk_req_n1_pins[] = { 76 }; -+static int mt7988_pcie_clk_req_n1_funcs[] = { 1 }; -+ -+static const int mt7988_pcie_wake_n2_0_pins[] = { 77 }; -+static int mt7988_pcie_wake_n2_0_funcs[] = { 1 }; -+ -+static const int mt7988_pcie_clk_req_n2_0_pins[] = { 78 }; -+static int mt7988_pcie_clk_req_n2_0_funcs[] = { 1 }; -+ -+static const int mt7988_pcie_wake_n2_1_pins[] = { 79 }; -+static int mt7988_pcie_wake_n2_1_funcs[] = { 2 }; -+ -+/* pmic */ -+static const int mt7988_pmic_pins[] = { 11 }; -+static int mt7988_pmic_funcs[] = { 1 }; -+ -+/* watchdog */ -+static const int mt7988_watchdog_pins[] = { 12 }; -+static int mt7988_watchdog_funcs[] = { 1 }; -+ -+/* spi */ -+static const int mt7988_spi0_wp_hold_pins[] = { 22, 23 }; -+static int mt7988_spi0_wp_hold_funcs[] = { 1, 1 }; -+ -+static const int mt7988_spi0_pins[] = { 24, 25, 26, 27 }; -+static int mt7988_spi0_funcs[] = { 1, 1, 1, 1 }; -+ -+static const int mt7988_spi1_pins[] = { 28, 29, 30, 31 }; -+static int mt7988_spi1_funcs[] = { 1, 1, 1, 1 }; -+ -+static const int mt7988_spi2_pins[] = { 32, 33, 34, 35 }; -+static int mt7988_spi2_funcs[] = { 1, 1, 1, 1 }; -+ -+static const int mt7988_spi2_wp_hold_pins[] = { 36, 37 }; -+static int mt7988_spi2_wp_hold_funcs[] = { 1, 1 }; -+ -+/* flash */ -+static const int mt7988_snfi_pins[] = { 22, 23, 24, 25, 26, 27 }; -+static int mt7988_snfi_funcs[] = { 2, 2, 2, 2, 2, 2 }; -+ -+static const int mt7988_emmc_45_pins[] = { -+ 21, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37 -+}; -+static int mt7988_emmc_45_funcs[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 }; -+ -+static const int mt7988_sdcard_pins[] = { 32, 33, 34, 35, 36, 37 }; -+static int mt7988_sdcard_funcs[] = { 5, 5, 5, 5, 5, 5 }; -+ -+static const int mt7988_emmc_51_pins[] = { 38, 39, 40, 41, 42, 43, -+ 44, 45, 46, 47, 48, 49 }; -+static int mt7988_emmc_51_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; -+ -+/* uart */ -+static const int mt7988_uart2_pins[] = { 0, 1, 2, 3 }; -+static int mt7988_uart2_funcs[] = { 1, 1, 1, 1 }; -+ -+static const int mt7988_tops_uart0_0_pins[] = { 22, 23 }; -+static int mt7988_tops_uart0_0_funcs[] = { 3, 3 }; -+ -+static const int mt7988_uart2_0_pins[] = { 28, 29, 30, 31 }; -+static int mt7988_uart2_0_funcs[] = { 2, 2, 2, 2 }; -+ -+static const int mt7988_uart1_0_pins[] = { 32, 33, 34, 35 }; -+static int mt7988_uart1_0_funcs[] = { 2, 2, 2, 2 }; -+ -+static const int mt7988_uart2_1_pins[] = { 32, 33, 34, 35 }; -+static int mt7988_uart2_1_funcs[] = { 3, 3, 3, 3 }; -+ -+static const int mt7988_net_wo0_uart_txd_0_pins[] = { 28 }; -+static int mt7988_net_wo0_uart_txd_0_funcs[] = { 3 }; -+ -+static const int mt7988_net_wo1_uart_txd_0_pins[] = { 29 }; -+static int mt7988_net_wo1_uart_txd_0_funcs[] = { 3 }; -+ -+static const int mt7988_net_wo2_uart_txd_0_pins[] = { 30 }; -+static int mt7988_net_wo2_uart_txd_0_funcs[] = { 3 }; -+ -+static const int mt7988_tops_uart1_0_pins[] = { 28, 29 }; -+static int mt7988_tops_uart1_0_funcs[] = { 4, 4 }; -+ -+static const int mt7988_tops_uart0_1_pins[] = { 30, 31 }; -+static int mt7988_tops_uart0_1_funcs[] = { 4, 4 }; -+ -+static const int mt7988_tops_uart1_1_pins[] = { 36, 37 }; -+static int mt7988_tops_uart1_1_funcs[] = { 3, 3 }; -+ -+static const int mt7988_uart0_pins[] = { 55, 56 }; -+static int mt7988_uart0_funcs[] = { 1, 1 }; -+ -+static const int mt7988_tops_uart0_2_pins[] = { 55, 56 }; -+static int mt7988_tops_uart0_2_funcs[] = { 2, 2 }; -+ -+static const int mt7988_uart2_2_pins[] = { 50, 51, 52, 53 }; -+static int mt7988_uart2_2_funcs[] = { 2, 2, 2, 2 }; -+ -+static const int mt7988_uart1_1_pins[] = { 58, 59, 60, 61 }; -+static int mt7988_uart1_1_funcs[] = { 2, 2, 2, 2 }; -+ -+static const int mt7988_uart2_3_pins[] = { 58, 59, 60, 61 }; -+static int mt7988_uart2_3_funcs[] = { 3, 3, 3, 3 }; -+ -+static const int mt7988_uart1_2_pins[] = { 80, 81, 82, 83 }; -+static int mt7988_uart1_2_funcs[] = { 1, 1, 1, 1 }; -+ -+static const int mt7988_uart1_2_lite_pins[] = { 80, 81 }; -+static int mt7988_uart1_2_lite_funcs[] = { 1, 1 }; -+ -+static const int mt7988_tops_uart1_2_pins[] = { 80, 81 }; -+static int mt7988_tops_uart1_2_funcs[] = { 4, 4, }; -+ -+static const int mt7988_net_wo0_uart_txd_1_pins[] = { 80 }; -+static int mt7988_net_wo0_uart_txd_1_funcs[] = { 3 }; -+ -+static const int mt7988_net_wo1_uart_txd_1_pins[] = { 81 }; -+static int mt7988_net_wo1_uart_txd_1_funcs[] = { 3 }; -+ -+static const int mt7988_net_wo2_uart_txd_1_pins[] = { 82 }; -+static int mt7988_net_wo2_uart_txd_1_funcs[] = { 3 }; -+ -+/* udi */ -+static const int mt7988_udi_pins[] = { 32, 33, 34, 35, 36 }; -+static int mt7988_udi_funcs[] = { 4, 4, 4, 4, 4 }; -+ -+/* i2s */ -+static const int mt7988_i2s_pins[] = { 50, 51, 52, 53, 54 }; -+static int mt7988_i2s_funcs[] = { 1, 1, 1, 1, 1 }; -+ -+/* pcm */ -+static const int mt7988_pcm_pins[] = { 50, 51, 52, 53 }; -+static int mt7988_pcm_funcs[] = { 1, 1, 1, 1 }; -+ -+/* led */ -+static const int mt7988_gbe0_led1_pins[] = { 58 }; -+static int mt7988_gbe0_led1_funcs[] = { 6 }; -+static const int mt7988_gbe1_led1_pins[] = { 59 }; -+static int mt7988_gbe1_led1_funcs[] = { 6 }; -+static const int mt7988_gbe2_led1_pins[] = { 60 }; -+static int mt7988_gbe2_led1_funcs[] = { 6 }; -+static const int mt7988_gbe3_led1_pins[] = { 61 }; -+static int mt7988_gbe3_led1_funcs[] = { 6 }; -+ -+static const int mt7988_2p5gbe_led1_pins[] = { 62 }; -+static int mt7988_2p5gbe_led1_funcs[] = { 6 }; -+ -+static const int mt7988_gbe0_led0_pins[] = { 64 }; -+static int mt7988_gbe0_led0_funcs[] = { 1 }; -+static const int mt7988_gbe1_led0_pins[] = { 65 }; -+static int mt7988_gbe1_led0_funcs[] = { 1 }; -+static const int mt7988_gbe2_led0_pins[] = { 66 }; -+static int mt7988_gbe2_led0_funcs[] = { 1 }; -+static const int mt7988_gbe3_led0_pins[] = { 67 }; -+static int mt7988_gbe3_led0_funcs[] = { 1 }; -+ -+static const int mt7988_2p5gbe_led0_pins[] = { 68 }; -+static int mt7988_2p5gbe_led0_funcs[] = { 1 }; -+ -+/* usb */ -+static const int mt7988_drv_vbus_p1_pins[] = { 63 }; -+static int mt7988_drv_vbus_p1_funcs[] = { 1 }; -+ -+static const int mt7988_drv_vbus_pins[] = { 79 }; -+static int mt7988_drv_vbus_funcs[] = { 1 }; -+ -+static const struct group_desc mt7988_groups[] = { -+ /* @GPIO(0,1,2,3): uart2 */ -+ PINCTRL_PIN_GROUP("uart2", mt7988_uart2), -+ /* @GPIO(0,1,2,3,4): tops_jtag0_0 */ -+ PINCTRL_PIN_GROUP("tops_jtag0_0", mt7988_tops_jtag0_0), -+ /* @GPIO(2,3): int_usxgmii */ -+ PINCTRL_PIN_GROUP("int_usxgmii", mt7988_int_usxgmii), -+ /* @GPIO(0,1,2,3,4): dfd */ -+ PINCTRL_PIN_GROUP("dfd", mt7988_dfd), -+ /* @GPIO(0,1): xfi_phy0_i2c0 */ -+ PINCTRL_PIN_GROUP("xfi_phy0_i2c0", mt7988_xfi_phy0_i2c0), -+ /* @GPIO(0,1): xfi_phy1_i2c0 */ -+ PINCTRL_PIN_GROUP("xfi_phy1_i2c0", mt7988_xfi_phy1_i2c0), -+ /* @GPIO(3,4): xfi_phy_pll_i2c0 */ -+ PINCTRL_PIN_GROUP("xfi_phy_pll_i2c0", mt7988_xfi_phy_pll_i2c0), -+ /* @GPIO(3,4): xfi_phy_pll_i2c1 */ -+ PINCTRL_PIN_GROUP("xfi_phy_pll_i2c1", mt7988_xfi_phy_pll_i2c1), -+ /* @GPIO(4): pwm7 */ -+ PINCTRL_PIN_GROUP("pwm7_0", mt7988_pwm7_0), -+ /* @GPIO(5,6) i2c0_0 */ -+ PINCTRL_PIN_GROUP("i2c0_0", mt7988_i2c0_0), -+ /* @GPIO(5,6) i2c1_sfp */ -+ PINCTRL_PIN_GROUP("i2c1_sfp", mt7988_i2c1_sfp), -+ /* @GPIO(5,6) xfi_pextp_phy0_i2c */ -+ PINCTRL_PIN_GROUP("xfi_pextp_phy0_i2c", mt7988_xfi_pextp_phy0_i2c), -+ /* @GPIO(5,6) xfi_pextp_phy1_i2c */ -+ PINCTRL_PIN_GROUP("xfi_pextp_phy1_i2c", mt7988_xfi_pextp_phy1_i2c), -+ /* @GPIO(5,6) mdc_mdio0 */ -+ PINCTRL_PIN_GROUP("mdc_mdio0", mt7988_mdc_mdio0), -+ /* @GPIO(7): pcie_wake_n0_0 */ -+ PINCTRL_PIN_GROUP("pcie_wake_n0_0", mt7988_pcie_wake_n0_0), -+ /* @GPIO(8): pcie_clk_req_n0_0 */ -+ PINCTRL_PIN_GROUP("pcie_clk_req_n0_0", mt7988_pcie_clk_req_n0_0), -+ /* @GPIO(9): pcie_wake_n3_0 */ -+ PINCTRL_PIN_GROUP("pcie_wake_n3_0", mt7988_pcie_wake_n3_0), -+ /* @GPIO(10): pcie_clk_req_n3 */ -+ PINCTRL_PIN_GROUP("pcie_clk_req_n3", mt7988_pcie_clk_req_n3), -+ /* @GPIO(10): pcie_clk_req_n0_1 */ -+ PINCTRL_PIN_GROUP("pcie_clk_req_n0_1", mt7988_pcie_clk_req_n0_1), -+ /* @GPIO(7,8) pcie_p0_phy_i2c */ -+ PINCTRL_PIN_GROUP("pcie_p0_phy_i2c", mt7988_pcie_p0_phy_i2c), -+ /* @GPIO(7,8) pcie_p1_phy_i2c */ -+ PINCTRL_PIN_GROUP("pcie_p1_phy_i2c", mt7988_pcie_p1_phy_i2c), -+ /* @GPIO(7,8) pcie_p2_phy_i2c */ -+ PINCTRL_PIN_GROUP("pcie_p2_phy_i2c", mt7988_pcie_p2_phy_i2c), -+ /* @GPIO(9,10) pcie_p3_phy_i2c */ -+ PINCTRL_PIN_GROUP("pcie_p3_phy_i2c", mt7988_pcie_p3_phy_i2c), -+ /* @GPIO(9,10) ckm_phy_i2c */ -+ PINCTRL_PIN_GROUP("ckm_phy_i2c", mt7988_ckm_phy_i2c), -+ /* @GPIO(11): pmic */ -+ PINCTRL_PIN_GROUP("pcie_pmic", mt7988_pmic), -+ /* @GPIO(12): watchdog */ -+ PINCTRL_PIN_GROUP("watchdog", mt7988_watchdog), -+ /* @GPIO(13): pcie_wake_n0_1 */ -+ PINCTRL_PIN_GROUP("pcie_wake_n0_1", mt7988_pcie_wake_n0_1), -+ /* @GPIO(14): pcie_wake_n3_1 */ -+ PINCTRL_PIN_GROUP("pcie_wake_n3_1", mt7988_pcie_wake_n3_1), -+ /* @GPIO(15,16) i2c0_1 */ -+ PINCTRL_PIN_GROUP("i2c0_1", mt7988_i2c0_1), -+ /* @GPIO(15,16) u30_phy_i2c0 */ -+ PINCTRL_PIN_GROUP("u30_phy_i2c0", mt7988_u30_phy_i2c0), -+ /* @GPIO(15,16) u32_phy_i2c0 */ -+ PINCTRL_PIN_GROUP("u32_phy_i2c0", mt7988_u32_phy_i2c0), -+ /* @GPIO(15,16) xfi_phy0_i2c1 */ -+ PINCTRL_PIN_GROUP("xfi_phy0_i2c1", mt7988_xfi_phy0_i2c1), -+ /* @GPIO(15,16) xfi_phy1_i2c1 */ -+ PINCTRL_PIN_GROUP("xfi_phy1_i2c1", mt7988_xfi_phy1_i2c1), -+ /* @GPIO(15,16) xfi_phy_pll_i2c2 */ -+ PINCTRL_PIN_GROUP("xfi_phy_pll_i2c2", mt7988_xfi_phy_pll_i2c2), -+ /* @GPIO(17,18) i2c1_0 */ -+ PINCTRL_PIN_GROUP("i2c1_0", mt7988_i2c1_0), -+ /* @GPIO(17,18) u30_phy_i2c1 */ -+ PINCTRL_PIN_GROUP("u30_phy_i2c1", mt7988_u30_phy_i2c1), -+ /* @GPIO(17,18) u32_phy_i2c1 */ -+ PINCTRL_PIN_GROUP("u32_phy_i2c1", mt7988_u32_phy_i2c1), -+ /* @GPIO(17,18) xfi_phy_pll_i2c3 */ -+ PINCTRL_PIN_GROUP("xfi_phy_pll_i2c3", mt7988_xfi_phy_pll_i2c3), -+ /* @GPIO(17,18) sgmii0_i2c */ -+ PINCTRL_PIN_GROUP("sgmii0_i2c", mt7988_sgmii0_i2c), -+ /* @GPIO(17,18) sgmii1_i2c */ -+ PINCTRL_PIN_GROUP("sgmii1_i2c", mt7988_sgmii1_i2c), -+ /* @GPIO(19): pcie_2l_0_pereset */ -+ PINCTRL_PIN_GROUP("pcie_2l_0_pereset", mt7988_pcie_2l_0_pereset), -+ /* @GPIO(20): pcie_1l_1_pereset */ -+ PINCTRL_PIN_GROUP("pcie_1l_1_pereset", mt7988_pcie_1l_1_pereset), -+ /* @GPIO(21): pwm1 */ -+ PINCTRL_PIN_GROUP("pwm1", mt7988_pwm1), -+ /* @GPIO(22,23) spi0_wp_hold */ -+ PINCTRL_PIN_GROUP("spi0_wp_hold", mt7988_spi0_wp_hold), -+ /* @GPIO(24,25,26,27) spi0 */ -+ PINCTRL_PIN_GROUP("spi0", mt7988_spi0), -+ /* @GPIO(28,29,30,31) spi1 */ -+ PINCTRL_PIN_GROUP("spi1", mt7988_spi1), -+ /* @GPIO(32,33,34,35) spi2 */ -+ PINCTRL_PIN_GROUP("spi2", mt7988_spi2), -+ /* @GPIO(36,37) spi2_wp_hold */ -+ PINCTRL_PIN_GROUP("spi2_wp_hold", mt7988_spi2_wp_hold), -+ /* @GPIO(22,23,24,25,26,27) snfi */ -+ PINCTRL_PIN_GROUP("snfi", mt7988_snfi), -+ /* @GPIO(22,23) tops_uart0_0 */ -+ PINCTRL_PIN_GROUP("tops_uart0_0", mt7988_tops_uart0_0), -+ /* @GPIO(28,29,30,31) uart2_0 */ -+ PINCTRL_PIN_GROUP("uart2_0", mt7988_uart2_0), -+ /* @GPIO(32,33,34,35) uart1_0 */ -+ PINCTRL_PIN_GROUP("uart1_0", mt7988_uart1_0), -+ /* @GPIO(32,33,34,35) uart2_1 */ -+ PINCTRL_PIN_GROUP("uart2_1", mt7988_uart2_1), -+ /* @GPIO(28) net_wo0_uart_txd_0 */ -+ PINCTRL_PIN_GROUP("net_wo0_uart_txd_0", mt7988_net_wo0_uart_txd_0), -+ /* @GPIO(29) net_wo1_uart_txd_0 */ -+ PINCTRL_PIN_GROUP("net_wo1_uart_txd_0", mt7988_net_wo1_uart_txd_0), -+ /* @GPIO(30) net_wo2_uart_txd_0 */ -+ PINCTRL_PIN_GROUP("net_wo2_uart_txd_0", mt7988_net_wo2_uart_txd_0), -+ /* @GPIO(28,29) tops_uart1_0 */ -+ PINCTRL_PIN_GROUP("tops_uart0_0", mt7988_tops_uart1_0), -+ /* @GPIO(30,31) tops_uart0_1 */ -+ PINCTRL_PIN_GROUP("tops_uart0_1", mt7988_tops_uart0_1), -+ /* @GPIO(36,37) tops_uart1_1 */ -+ PINCTRL_PIN_GROUP("tops_uart1_1", mt7988_tops_uart1_1), -+ /* @GPIO(32,33,34,35,36) udi */ -+ PINCTRL_PIN_GROUP("udi", mt7988_udi), -+ /* @GPIO(21,28,29,30,31,32,33,34,35,36,37) emmc_45 */ -+ PINCTRL_PIN_GROUP("emmc_45", mt7988_emmc_45), -+ /* @GPIO(32,33,34,35,36,37) sdcard */ -+ PINCTRL_PIN_GROUP("sdcard", mt7988_sdcard), -+ /* @GPIO(38,39,40,41,42,43,44,45,46,47,48,49) emmc_51 */ -+ PINCTRL_PIN_GROUP("emmc_51", mt7988_emmc_51), -+ /* @GPIO(28,29) 2p5g_ext_mdio */ -+ PINCTRL_PIN_GROUP("2p5g_ext_mdio", mt7988_2p5g_ext_mdio), -+ /* @GPIO(30,31) gbe_ext_mdio */ -+ PINCTRL_PIN_GROUP("gbe_ext_mdio", mt7988_gbe_ext_mdio), -+ /* @GPIO(50,51,52,53,54) i2s */ -+ PINCTRL_PIN_GROUP("i2s", mt7988_i2s), -+ /* @GPIO(50,51,52,53) pcm */ -+ PINCTRL_PIN_GROUP("pcm", mt7988_pcm), -+ /* @GPIO(55,56) uart0 */ -+ PINCTRL_PIN_GROUP("uart0", mt7988_uart0), -+ /* @GPIO(55,56) tops_uart0_2 */ -+ PINCTRL_PIN_GROUP("tops_uart0_2", mt7988_tops_uart0_2), -+ /* @GPIO(50,51,52,53) uart2_2 */ -+ PINCTRL_PIN_GROUP("uart2_2", mt7988_uart2_2), -+ /* @GPIO(50,51,52,53,54) wo0_jtag */ -+ PINCTRL_PIN_GROUP("wo0_jtag", mt7988_wo0_jtag), -+ /* @GPIO(50,51,52,53,54) wo1-wo1_jtag */ -+ PINCTRL_PIN_GROUP("wo1_jtag", mt7988_wo1_jtag), -+ /* @GPIO(50,51,52,53,54) wo2_jtag */ -+ PINCTRL_PIN_GROUP("wo2_jtag", mt7988_wo2_jtag), -+ /* @GPIO(57) pwm0 */ -+ PINCTRL_PIN_GROUP("pwm0", mt7988_pwm0), -+ /* @GPIO(58) pwm2_0 */ -+ PINCTRL_PIN_GROUP("pwm2_0", mt7988_pwm2_0), -+ /* @GPIO(59) pwm3_0 */ -+ PINCTRL_PIN_GROUP("pwm3_0", mt7988_pwm3_0), -+ /* @GPIO(60) pwm4_0 */ -+ PINCTRL_PIN_GROUP("pwm4_0", mt7988_pwm4_0), -+ /* @GPIO(61) pwm5_0 */ -+ PINCTRL_PIN_GROUP("pwm5_0", mt7988_pwm5_0), -+ /* @GPIO(58,59,60,61,62) jtag */ -+ PINCTRL_PIN_GROUP("jtag", mt7988_jtag), -+ /* @GPIO(58,59,60,61,62) tops_jtag0_1 */ -+ PINCTRL_PIN_GROUP("tops_jtag0_1", mt7988_tops_jtag0_1), -+ /* @GPIO(58,59,60,61) uart2_3 */ -+ PINCTRL_PIN_GROUP("uart2_3", mt7988_uart2_3), -+ /* @GPIO(58,59,60,61) uart1_1 */ -+ PINCTRL_PIN_GROUP("uart1_1", mt7988_uart1_1), -+ /* @GPIO(58,59,60,61) gbe_led1 */ -+ PINCTRL_PIN_GROUP("gbe0_led1", mt7988_gbe0_led1), -+ PINCTRL_PIN_GROUP("gbe1_led1", mt7988_gbe1_led1), -+ PINCTRL_PIN_GROUP("gbe2_led1", mt7988_gbe2_led1), -+ PINCTRL_PIN_GROUP("gbe3_led1", mt7988_gbe3_led1), -+ /* @GPIO(62) pwm6_0 */ -+ PINCTRL_PIN_GROUP("pwm6_0", mt7988_pwm6_0), -+ /* @GPIO(62) 2p5gbe_led1 */ -+ PINCTRL_PIN_GROUP("2p5gbe_led1", mt7988_2p5gbe_led1), -+ /* @GPIO(64,65,66,67) gbe_led0 */ -+ PINCTRL_PIN_GROUP("gbe0_led0", mt7988_gbe0_led0), -+ PINCTRL_PIN_GROUP("gbe1_led0", mt7988_gbe1_led0), -+ PINCTRL_PIN_GROUP("gbe2_led0", mt7988_gbe2_led0), -+ PINCTRL_PIN_GROUP("gbe3_led0", mt7988_gbe3_led0), -+ /* @GPIO(68) 2p5gbe_led0 */ -+ PINCTRL_PIN_GROUP("2p5gbe_led0", mt7988_2p5gbe_led0), -+ /* @GPIO(63) drv_vbus_p1 */ -+ PINCTRL_PIN_GROUP("drv_vbus_p1", mt7988_drv_vbus_p1), -+ /* @GPIO(63) pcie_clk_req_n2_1 */ -+ PINCTRL_PIN_GROUP("pcie_clk_req_n2_1", mt7988_pcie_clk_req_n2_1), -+ /* @GPIO(69, 70) mdc_mdio1 */ -+ PINCTRL_PIN_GROUP("mdc_mdio1", mt7988_mdc_mdio1), -+ /* @GPIO(69, 70) i2c1_2 */ -+ PINCTRL_PIN_GROUP("i2c1_2", mt7988_i2c1_2), -+ /* @GPIO(69) pwm6 */ -+ PINCTRL_PIN_GROUP("pwm6", mt7988_pwm6), -+ /* @GPIO(70) pwm7 */ -+ PINCTRL_PIN_GROUP("pwm7", mt7988_pwm7), -+ /* @GPIO(69,70) i2c2_0 */ -+ PINCTRL_PIN_GROUP("i2c2_0", mt7988_i2c2_0), -+ /* @GPIO(71,72) i2c2_1 */ -+ PINCTRL_PIN_GROUP("i2c2_1", mt7988_i2c2_1), -+ /* @GPIO(73) pcie_2l_1_pereset */ -+ PINCTRL_PIN_GROUP("pcie_2l_1_pereset", mt7988_pcie_2l_1_pereset), -+ /* @GPIO(74) pcie_1l_0_pereset */ -+ PINCTRL_PIN_GROUP("pcie_1l_0_pereset", mt7988_pcie_1l_0_pereset), -+ /* @GPIO(75) pcie_wake_n1_0 */ -+ PINCTRL_PIN_GROUP("pcie_wake_n1_0", mt7988_pcie_wake_n1_0), -+ /* @GPIO(76) pcie_clk_req_n1 */ -+ PINCTRL_PIN_GROUP("pcie_clk_req_n1", mt7988_pcie_clk_req_n1), -+ /* @GPIO(77) pcie_wake_n2_0 */ -+ PINCTRL_PIN_GROUP("pcie_wake_n2_0", mt7988_pcie_wake_n2_0), -+ /* @GPIO(78) pcie_clk_req_n2_0 */ -+ PINCTRL_PIN_GROUP("pcie_clk_req_n2_0", mt7988_pcie_clk_req_n2_0), -+ /* @GPIO(79) drv_vbus */ -+ PINCTRL_PIN_GROUP("drv_vbus", mt7988_drv_vbus), -+ /* @GPIO(79) pcie_wake_n2_1 */ -+ PINCTRL_PIN_GROUP("pcie_wake_n2_1", mt7988_pcie_wake_n2_1), -+ /* @GPIO(80,81,82,83) uart1_2 */ -+ PINCTRL_PIN_GROUP("uart1_2", mt7988_uart1_2), -+ /* @GPIO(80,81) uart1_2_lite */ -+ PINCTRL_PIN_GROUP("uart1_2_lite", mt7988_uart1_2_lite), -+ /* @GPIO(80) pwm2 */ -+ PINCTRL_PIN_GROUP("pwm2", mt7988_pwm2), -+ /* @GPIO(81) pwm3 */ -+ PINCTRL_PIN_GROUP("pwm3", mt7988_pwm3), -+ /* @GPIO(82) pwm4 */ -+ PINCTRL_PIN_GROUP("pwm4", mt7988_pwm4), -+ /* @GPIO(83) pwm5 */ -+ PINCTRL_PIN_GROUP("pwm5", mt7988_pwm5), -+ /* @GPIO(80) net_wo0_uart_txd_0 */ -+ PINCTRL_PIN_GROUP("net_wo0_uart_txd_0", mt7988_net_wo0_uart_txd_0), -+ /* @GPIO(81) net_wo1_uart_txd_0 */ -+ PINCTRL_PIN_GROUP("net_wo1_uart_txd_0", mt7988_net_wo1_uart_txd_0), -+ /* @GPIO(82) net_wo2_uart_txd_0 */ -+ PINCTRL_PIN_GROUP("net_wo2_uart_txd_0", mt7988_net_wo2_uart_txd_0), -+ /* @GPIO(80,81) tops_uart1_2 */ -+ PINCTRL_PIN_GROUP("tops_uart1_2", mt7988_tops_uart1_2), -+ /* @GPIO(80) net_wo0_uart_txd_1 */ -+ PINCTRL_PIN_GROUP("net_wo0_uart_txd_1", mt7988_net_wo0_uart_txd_1), -+ /* @GPIO(81) net_wo1_uart_txd_1 */ -+ PINCTRL_PIN_GROUP("net_wo1_uart_txd_1", mt7988_net_wo1_uart_txd_1), -+ /* @GPIO(82) net_wo2_uart_txd_1 */ -+ PINCTRL_PIN_GROUP("net_wo2_uart_txd_1", mt7988_net_wo2_uart_txd_1), -+}; -+ -+/* Joint those groups owning the same capability in user point of view which -+ * allows that people tend to use through the device tree. -+ */ -+static const char * const mt7988_jtag_groups[] = { -+ "tops_jtag0_0", "wo0_jtag", "wo1_jtag", -+ "wo2_jtag", "jtag", "tops_jtag0_1", -+}; -+static const char * const mt7988_int_usxgmii_groups[] = { -+ "int_usxgmii", -+}; -+static const char * const mt7988_pwm_groups[] = { -+ "pwm0", "pwm1", "pwm2", "pwm2_0", "pwm3", "pwm3_0", "pwm4", "pwm4_0", -+ "pwm5", "pwm5_0", "pwm6", "pwm6_0", "pwm7", "pwm7_0", -+ -+}; -+static const char * const mt7988_dfd_groups[] = { -+ "dfd", -+}; -+static const char * const mt7988_i2c_groups[] = { -+ "xfi_phy0_i2c0", -+ "xfi_phy1_i2c0", -+ "xfi_phy_pll_i2c0", -+ "xfi_phy_pll_i2c1", -+ "i2c0_0", -+ "i2c1_sfp", -+ "xfi_pextp_phy0_i2c", -+ "xfi_pextp_phy1_i2c", -+ "i2c0_1", -+ "u30_phy_i2c0", -+ "u32_phy_i2c0", -+ "xfi_phy0_i2c1", -+ "xfi_phy1_i2c1", -+ "xfi_phy_pll_i2c2", -+ "i2c1_0", -+ "u30_phy_i2c1", -+ "u32_phy_i2c1", -+ "xfi_phy_pll_i2c3", -+ "sgmii0_i2c", -+ "sgmii1_i2c", -+ "i2c1_2", -+ "i2c2_0", -+ "i2c2_1", -+}; -+static const char * const mt7988_ethernet_groups[] = { -+ "mdc_mdio0", -+ "2p5g_ext_mdio", -+ "gbe_ext_mdio", -+ "mdc_mdio1", -+}; -+static const char * const mt7988_pcie_groups[] = { -+ "pcie_wake_n0_0", "pcie_clk_req_n0_0", "pcie_wake_n3_0", -+ "pcie_clk_req_n3", "pcie_p0_phy_i2c", "pcie_p1_phy_i2c", -+ "pcie_p3_phy_i2c", "pcie_p2_phy_i2c", "ckm_phy_i2c", -+ "pcie_wake_n0_1", "pcie_wake_n3_1", "pcie_2l_0_pereset", -+ "pcie_1l_1_pereset", "pcie_clk_req_n2_1", "pcie_2l_1_pereset", -+ "pcie_1l_0_pereset", "pcie_wake_n1_0", "pcie_clk_req_n1", -+ "pcie_wake_n2_0", "pcie_clk_req_n2_0", "pcie_wake_n2_1", -+ "pcie_clk_req_n0_1" -+}; -+static const char * const mt7988_pmic_groups[] = { -+ "pmic", -+}; -+static const char * const mt7988_wdt_groups[] = { -+ "watchdog", -+}; -+static const char * const mt7988_spi_groups[] = { -+ "spi0", "spi0_wp_hold", "spi1", "spi2", "spi2_wp_hold", -+}; -+static const char * const mt7988_flash_groups[] = { "emmc_45", "sdcard", "snfi", -+ "emmc_51" }; -+static const char * const mt7988_uart_groups[] = { -+ "uart2", -+ "tops_uart0_0", -+ "uart2_0", -+ "uart1_0", -+ "uart2_1", -+ "net_wo0_uart_txd_0", -+ "net_wo1_uart_txd_0", -+ "net_wo2_uart_txd_0", -+ "tops_uart1_0", -+ "ops_uart0_1", -+ "ops_uart1_1", -+ "uart0", -+ "tops_uart0_2", -+ "uart1_1", -+ "uart2_3", -+ "uart1_2", -+ "uart1_2_lite", -+ "tops_uart1_2", -+ "net_wo0_uart_txd_1", -+ "net_wo1_uart_txd_1", -+ "net_wo2_uart_txd_1", -+}; -+static const char * const mt7988_udi_groups[] = { -+ "udi", -+}; -+static const char * const mt7988_audio_groups[] = { -+ "i2s", "pcm", -+}; -+static const char * const mt7988_led_groups[] = { -+ "gbe0_led1", "gbe1_led1", "gbe2_led1", "gbe3_led1", "2p5gbe_led1", -+ "gbe0_led0", "gbe1_led0", "gbe2_led0", "gbe3_led0", "2p5gbe_led0", -+ "wf5g_led0", "wf5g_led1", -+}; -+static const char * const mt7988_usb_groups[] = { -+ "drv_vbus", -+ "drv_vbus_p1", -+}; -+ -+static const struct function_desc mt7988_functions[] = { -+ { { "audio", mt7988_audio_groups, ARRAY_SIZE(mt7988_audio_groups) }, -+ NULL }, -+ { { "jtag", mt7988_jtag_groups, ARRAY_SIZE(mt7988_jtag_groups) }, -+ NULL }, -+ { { "int_usxgmii", mt7988_int_usxgmii_groups, -+ ARRAY_SIZE(mt7988_int_usxgmii_groups) }, -+ NULL }, -+ { { "pwm", mt7988_pwm_groups, ARRAY_SIZE(mt7988_pwm_groups) }, NULL }, -+ { { "dfd", mt7988_dfd_groups, ARRAY_SIZE(mt7988_dfd_groups) }, NULL }, -+ { { "i2c", mt7988_i2c_groups, ARRAY_SIZE(mt7988_i2c_groups) }, NULL }, -+ { { "eth", mt7988_ethernet_groups, ARRAY_SIZE(mt7988_ethernet_groups) }, -+ NULL }, -+ { { "pcie", mt7988_pcie_groups, ARRAY_SIZE(mt7988_pcie_groups) }, -+ NULL }, -+ { { "pmic", mt7988_pmic_groups, ARRAY_SIZE(mt7988_pmic_groups) }, -+ NULL }, -+ { { "watchdog", mt7988_wdt_groups, ARRAY_SIZE(mt7988_wdt_groups) }, -+ NULL }, -+ { { "spi", mt7988_spi_groups, ARRAY_SIZE(mt7988_spi_groups) }, NULL }, -+ { { "flash", mt7988_flash_groups, ARRAY_SIZE(mt7988_flash_groups) }, -+ NULL }, -+ { { "uart", mt7988_uart_groups, ARRAY_SIZE(mt7988_uart_groups) }, -+ NULL }, -+ { { "udi", mt7988_udi_groups, ARRAY_SIZE(mt7988_udi_groups) }, NULL }, -+ { { "usb", mt7988_usb_groups, ARRAY_SIZE(mt7988_usb_groups) }, NULL }, -+ { { "led", mt7988_led_groups, ARRAY_SIZE(mt7988_led_groups) }, NULL }, -+}; -+ -+static const struct mtk_eint_hw mt7988_eint_hw = { -+ .port_mask = 7, -+ .ports = 7, -+ .ap_num = ARRAY_SIZE(mt7988_pins), -+ .db_cnt = 16, -+}; -+ -+static const char * const mt7988_pinctrl_register_base_names[] = { -+ "gpio", "iocfg_tr", "iocfg_br", -+ "iocfg_rb", "iocfg_lb", "iocfg_tl", -+}; -+ -+static const struct mtk_pin_soc mt7988_data = { -+ .reg_cal = mt7988_reg_cals, -+ .pins = mt7988_pins, -+ .npins = ARRAY_SIZE(mt7988_pins), -+ .grps = mt7988_groups, -+ .ngrps = ARRAY_SIZE(mt7988_groups), -+ .funcs = mt7988_functions, -+ .nfuncs = ARRAY_SIZE(mt7988_functions), -+ .eint_hw = &mt7988_eint_hw, -+ .gpio_m = 0, -+ .ies_present = false, -+ .base_names = mt7988_pinctrl_register_base_names, -+ .nbase_names = ARRAY_SIZE(mt7988_pinctrl_register_base_names), -+ .bias_disable_set = mtk_pinconf_bias_disable_set, -+ .bias_disable_get = mtk_pinconf_bias_disable_get, -+ .bias_set = mtk_pinconf_bias_set, -+ .bias_get = mtk_pinconf_bias_get, -+ .pull_type = mt7988_pull_type, -+ .bias_set_combo = mtk_pinconf_bias_set_combo, -+ .bias_get_combo = mtk_pinconf_bias_get_combo, -+ .drive_set = mtk_pinconf_drive_set_rev1, -+ .drive_get = mtk_pinconf_drive_get_rev1, -+ .adv_pull_get = mtk_pinconf_adv_pull_get, -+ .adv_pull_set = mtk_pinconf_adv_pull_set, -+}; -+ -+static const struct of_device_id mt7988_pinctrl_of_match[] = { -+ { .compatible = "mediatek,mt7988-pinctrl" }, -+ {} -+}; -+ -+static int mt7988_pinctrl_probe(struct platform_device *pdev) -+{ -+ return mtk_moore_pinctrl_probe(pdev, &mt7988_data); -+} -+ -+static struct platform_driver mt7988_pinctrl_driver = { -+ .driver = { -+ .name = "mt7988-pinctrl", -+ .of_match_table = mt7988_pinctrl_of_match, -+ }, -+ .probe = mt7988_pinctrl_probe, -+}; -+ -+static int __init mt7988_pinctrl_init(void) -+{ -+ return platform_driver_register(&mt7988_pinctrl_driver); -+} -+arch_initcall(mt7988_pinctrl_init); --- -2.51.0 - - -From 521e63edd7dc24d0a8474f682ce9256d9456c754 Mon Sep 17 00:00:00 2001 -From: Linus Walleij -Date: Wed, 8 Jan 2025 22:52:44 +0100 -Subject: [PATCH 386/517] pinctrl: mediatek: Drop mtk_pinconf_bias_set_pd() - -This function is unused and causing compile errors, delete it. - -Reported-by: Stephen Rothwell -Link: https://lore.kernel.org/linux-next/20250106164630.4447cd0d@canb.auug.org.au/ -Signed-off-by: Linus Walleij ---- - .../pinctrl/mediatek/pinctrl-mtk-common-v2.c | 18 ------------------ - 1 file changed, 18 deletions(-) - -diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c -index 7b704cc55c9f..00e95682b9f8 100644 ---- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c -+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c -@@ -599,24 +599,6 @@ static int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw, - return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd); - } - --static int mtk_pinconf_bias_set_pd(struct mtk_pinctrl *hw, -- const struct mtk_pin_desc *desc, -- u32 pullup, u32 arg) --{ -- int err, pd; -- -- if (arg != MTK_DISABLE && arg != MTK_ENABLE) -- return -EINVAL; -- -- if (arg == MTK_DISABLE || pullup) -- pd = 0; -- else if (!pullup) -- pd = 1; -- -- return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd); -- --} -- - static int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl *hw, - const struct mtk_pin_desc *desc, - u32 pullup, u32 arg) --- -2.51.0 - - -From 4e3da9d88396aac9caa6a20f414ed01d54adc02b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Wed, 5 Jun 2024 10:54:33 +0200 -Subject: [PATCH 387/517] arm64: dts: mediatek: mt7988: add UART controllers -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -MT7988 has three on-SoC UART controllers that support M16C450 and -M16550A modes. - -Signed-off-by: Rafał Miłecki -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/r/20240605085433.26513-2-zajec5@gmail.com -Signed-off-by: Matthias Brugger -Signed-off-by: AngeloGioacchino Del Regno ---- - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 35 ++++++++++++++++++++++- - 1 file changed, 34 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index 284e240b7997..bf7468c00d11 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -86,7 +86,7 @@ infracfg: clock-controller@10001000 { - #clock-cells = <1>; - }; - -- clock-controller@1001b000 { -+ topckgen: clock-controller@1001b000 { - compatible = "mediatek,mt7988-topckgen", "syscon"; - reg = <0 0x1001b000 0 0x1000>; - #clock-cells = <1>; -@@ -124,6 +124,39 @@ pwm@10048000 { - status = "disabled"; - }; - -+ serial@11000000 { -+ compatible = "mediatek,mt7988-uart", "mediatek,mt6577-uart"; -+ reg = <0 0x11000000 0 0x100>; -+ interrupts = ; -+ interrupt-names = "uart", "wakeup"; -+ clocks = <&topckgen CLK_TOP_UART_SEL>, -+ <&infracfg CLK_INFRA_52M_UART0_CK>; -+ clock-names = "baud", "bus"; -+ status = "disabled"; -+ }; -+ -+ serial@11000100 { -+ compatible = "mediatek,mt7988-uart", "mediatek,mt6577-uart"; -+ reg = <0 0x11000100 0 0x100>; -+ interrupts = ; -+ interrupt-names = "uart", "wakeup"; -+ clocks = <&topckgen CLK_TOP_UART_SEL>, -+ <&infracfg CLK_INFRA_52M_UART1_CK>; -+ clock-names = "baud", "bus"; -+ status = "disabled"; -+ }; -+ -+ serial@11000200 { -+ compatible = "mediatek,mt7988-uart", "mediatek,mt6577-uart"; -+ reg = <0 0x11000200 0 0x100>; -+ interrupts = ; -+ interrupt-names = "uart", "wakeup"; -+ clocks = <&topckgen CLK_TOP_UART_SEL>, -+ <&infracfg CLK_INFRA_52M_UART2_CK>; -+ clock-names = "baud", "bus"; -+ status = "disabled"; -+ }; -+ - i2c@11003000 { - compatible = "mediatek,mt7981-i2c"; - reg = <0 0x11003000 0 0x1000>, --- -2.51.0 - - -From 24ab7e822a0a6504bdec0061f051edbb3975c767 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Thu, 13 Jun 2024 21:59:33 +0200 -Subject: [PATCH 388/517] arm64: dts: mediatek: mt7988: add efuse block -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -MT7988 (AKA MediaTek Filogic 880) uses efuse for storing calibration -data. - -Signed-off-by: Rafał Miłecki -Link: https://lore.kernel.org/r/20240613195933.31089-2-zajec5@gmail.com -Signed-off-by: Matthias Brugger -Signed-off-by: AngeloGioacchino Del Regno ---- - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index bf7468c00d11..73561c7a3ad2 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -234,6 +234,13 @@ clock-controller@11f40000 { - #clock-cells = <1>; - }; - -+ efuse@11f50000 { -+ compatible = "mediatek,mt7988-efuse", "mediatek,efuse"; -+ reg = <0 0x11f50000 0 0x1000>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ }; -+ - clock-controller@15000000 { - compatible = "mediatek,mt7988-ethsys", "syscon"; - reg = <0 0x15000000 0 0x1000>; --- -2.51.0 - - -From d8836ca9c42c01503f86c4f0e239eec89005713a Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 17 Dec 2024 09:54:29 +0100 -Subject: [PATCH 389/517] arm64: dts: mediatek: mt7988: Add pinctrl support - -Add mt7988a pinctrl node. - -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/r/20241217085435.9586-5-linux@fw-web.de -Signed-off-by: AngeloGioacchino Del Regno ---- - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 54 +++++++++++++++++++++++ - 1 file changed, 54 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index 73561c7a3ad2..69998351489d 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -3,6 +3,7 @@ - #include - #include - #include -+#include - - / { - compatible = "mediatek,mt7988a"; -@@ -105,6 +106,59 @@ clock-controller@1001e000 { - #clock-cells = <1>; - }; - -+ pio: pinctrl@1001f000 { -+ compatible = "mediatek,mt7988-pinctrl"; -+ reg = <0 0x1001f000 0 0x1000>, -+ <0 0x11c10000 0 0x1000>, -+ <0 0x11d00000 0 0x1000>, -+ <0 0x11d20000 0 0x1000>, -+ <0 0x11e00000 0 0x1000>, -+ <0 0x11f00000 0 0x1000>, -+ <0 0x1000b000 0 0x1000>; -+ reg-names = "gpio", "iocfg_tr", -+ "iocfg_br", "iocfg_rb", -+ "iocfg_lb", "iocfg_tl", "eint"; -+ gpio-controller; -+ #gpio-cells = <2>; -+ gpio-ranges = <&pio 0 0 84>; -+ interrupt-controller; -+ interrupts = ; -+ interrupt-parent = <&gic>; -+ #interrupt-cells = <2>; -+ -+ pcie0_pins: pcie0-pins { -+ mux { -+ function = "pcie"; -+ groups = "pcie_2l_0_pereset", "pcie_clk_req_n0_0", -+ "pcie_wake_n0_0"; -+ }; -+ }; -+ -+ pcie1_pins: pcie1-pins { -+ mux { -+ function = "pcie"; -+ groups = "pcie_2l_1_pereset", "pcie_clk_req_n1", -+ "pcie_wake_n1_0"; -+ }; -+ }; -+ -+ pcie2_pins: pcie2-pins { -+ mux { -+ function = "pcie"; -+ groups = "pcie_1l_0_pereset", "pcie_clk_req_n2_0", -+ "pcie_wake_n2_0"; -+ }; -+ }; -+ -+ pcie3_pins: pcie3-pins { -+ mux { -+ function = "pcie"; -+ groups = "pcie_1l_1_pereset", "pcie_clk_req_n3", -+ "pcie_wake_n3_0"; -+ }; -+ }; -+ }; -+ - pwm@10048000 { - compatible = "mediatek,mt7988-pwm"; - reg = <0 0x10048000 0 0x1000>; --- -2.51.0 - - -From f2c71d82b159b8019e0cc8e1845aa1b8905564e4 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 17 Dec 2024 10:12:15 +0100 -Subject: [PATCH 390/517] arm64: dts: mediatek: mt7988: Add reserved memory - -Add memory range handled by ATF to not be touched by linux kernel. -ATF is SoC specific and not board-specific so add it to mt7988.dtsi. - -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/r/20241217091238.16032-2-linux@fw-web.de -Signed-off-by: AngeloGioacchino Del Regno ---- - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index 69998351489d..8fc7160e23a8 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -62,6 +62,18 @@ psci { - method = "smc"; - }; - -+ reserved-memory { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ ranges; -+ -+ /* 320 KiB reserved for ARM Trusted Firmware (BL31 and BL32) */ -+ secmon@43000000 { -+ reg = <0 0x43000000 0 0x50000>; -+ no-map; -+ }; -+ }; -+ - soc { - compatible = "simple-bus"; - ranges; --- -2.51.0 - - -From 47c00a33f75dfb3da9f42b1e934d0491df437b92 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 17 Dec 2024 10:12:16 +0100 -Subject: [PATCH 391/517] arm64: dts: mediatek: mt7988: Add mmc support - -Add devicetree node for MMC controller. - -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/r/20241217091238.16032-3-linux@fw-web.de -Signed-off-by: AngeloGioacchino Del Regno ---- - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 21 ++++++++++++++++++++- - 1 file changed, 20 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index 8fc7160e23a8..62c2befb2f94 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -112,7 +112,7 @@ watchdog: watchdog@1001c000 { - #reset-cells = <1>; - }; - -- clock-controller@1001e000 { -+ apmixedsys: clock-controller@1001e000 { - compatible = "mediatek,mt7988-apmixedsys"; - reg = <0 0x1001e000 0 0x1000>; - #clock-cells = <1>; -@@ -293,6 +293,25 @@ usb@11200000 { - clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck"; - }; - -+ mmc0: mmc@11230000 { -+ compatible = "mediatek,mt7988-mmc"; -+ reg = <0 0x11230000 0 0x1000>, -+ <0 0x11D60000 0 0x1000>; -+ interrupts = ; -+ clocks = <&infracfg CLK_INFRA_MSDC400>, -+ <&infracfg CLK_INFRA_MSDC2_HCK>, -+ <&infracfg CLK_INFRA_66M_MSDC_0_HCK>, -+ <&infracfg CLK_INFRA_133M_MSDC_0_HCK>; -+ assigned-clocks = <&topckgen CLK_TOP_EMMC_250M_SEL>, -+ <&topckgen CLK_TOP_EMMC_400M_SEL>; -+ assigned-clock-parents = <&topckgen CLK_TOP_NET1PLL_D5_D2>, -+ <&apmixedsys CLK_APMIXED_MSDCPLL>; -+ clock-names = "source", "hclk", "axi_cg", "ahb_cg"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ - clock-controller@11f40000 { - compatible = "mediatek,mt7988-xfi-pll"; - reg = <0 0x11f40000 0 0x1000>; --- -2.51.0 - - -From 18d2e044598267f937931938ebc27fb564d97c1c Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 17 Dec 2024 10:12:17 +0100 -Subject: [PATCH 392/517] arm64: dts: mediatek: mt7988: Add lvts node - -Add Low Voltage Thermal Sensor (LVTS) node for mt7988 SoC. - -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/r/20241217091238.16032-4-linux@fw-web.de -Signed-off-by: AngeloGioacchino Del Regno ---- - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index 62c2befb2f94..e46f4dc0b453 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -4,6 +4,7 @@ - #include - #include - #include -+#include - - / { - compatible = "mediatek,mt7988a"; -@@ -97,6 +98,7 @@ infracfg: clock-controller@10001000 { - compatible = "mediatek,mt7988-infracfg", "syscon"; - reg = <0 0x10001000 0 0x1000>; - #clock-cells = <1>; -+ #reset-cells = <1>; - }; - - topckgen: clock-controller@1001b000 { -@@ -265,6 +267,17 @@ i2c@11005000 { - status = "disabled"; - }; - -+ lvts: lvts@1100a000 { -+ compatible = "mediatek,mt7988-lvts-ap"; -+ #thermal-sensor-cells = <1>; -+ reg = <0 0x1100a000 0 0x1000>; -+ clocks = <&infracfg CLK_INFRA_26M_THERM_SYSTEM>; -+ interrupts = ; -+ resets = <&infracfg MT7988_INFRA_RST1_THERM_CTRL_SWRST>; -+ nvmem-cells = <&lvts_calibration>; -+ nvmem-cell-names = "lvts-calib-data-1"; -+ }; -+ - usb@11190000 { - compatible = "mediatek,mt7988-xhci", "mediatek,mtk-xhci"; - reg = <0 0x11190000 0 0x2e00>, -@@ -324,6 +337,10 @@ efuse@11f50000 { - reg = <0 0x11f50000 0 0x1000>; - #address-cells = <1>; - #size-cells = <1>; -+ -+ lvts_calibration: calib@918 { -+ reg = <0x918 0x28>; -+ }; - }; - - clock-controller@15000000 { --- -2.51.0 - - -From a2d9e3b266aaf5e9949459218934a94fc7cd85a3 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 17 Dec 2024 10:12:18 +0100 -Subject: [PATCH 393/517] arm64: dts: mediatek: mt7988: Add thermal-zone - -Add basic thermal-zone node. - -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/r/20241217091238.16032-5-linux@fw-web.de -Signed-off-by: AngeloGioacchino Del Regno ---- - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index e46f4dc0b453..16b28fcf1e3c 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -358,6 +358,21 @@ clock-controller@15031000 { - }; - }; - -+ thermal-zones { -+ cpu_thermal: cpu-thermal { -+ polling-delay-passive = <1000>; -+ polling-delay = <1000>; -+ thermal-sensors = <&lvts 0>; -+ trips { -+ cpu_trip_crit: crit { -+ temperature = <125000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ }; -+ }; -+ }; -+ - timer { - compatible = "arm,armv8-timer"; - interrupt-parent = <&gic>; --- -2.51.0 - - -From bfde0dd54fbdfb71446eb27aa3ab94feafc012cf Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 17 Dec 2024 10:12:20 +0100 -Subject: [PATCH 394/517] arm64: dts: mediatek: mt7988: Add mcu-sys node for - cpu - -In preparation for adding support for CPU DVFS and clock tables for it, -add the MCUSYS clock controller node. - -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/r/20241217091238.16032-7-linux@fw-web.de -Signed-off-by: AngeloGioacchino Del Regno ---- - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index 16b28fcf1e3c..5e53ea47f159 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -192,6 +192,12 @@ pwm@10048000 { - status = "disabled"; - }; - -+ mcusys: mcusys@100e0000 { -+ compatible = "mediatek,mt7988-mcusys", "syscon"; -+ reg = <0 0x100e0000 0 0x1000>; -+ #clock-cells = <1>; -+ }; -+ - serial@11000000 { - compatible = "mediatek,mt7988-uart", "mediatek,mt6577-uart"; - reg = <0 0x11000000 0 0x100>; --- -2.51.0 - - -From a148d657d3d03a61d9612b016bfc699693c3dfc9 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 17 Dec 2024 10:12:21 +0100 -Subject: [PATCH 395/517] arm64: dts: mediatek: mt7988: Add CPU OPP table for - clock scaling - -Add operating points defining frequency/voltages of cpu cores. - -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/r/20241217091238.16032-8-linux@fw-web.de -Signed-off-by: AngeloGioacchino Del Regno ---- - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 38 +++++++++++++++++++++++ - 1 file changed, 38 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index 5e53ea47f159..a7954bf5c81e 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -21,6 +21,10 @@ cpu@0 { - reg = <0x0>; - device_type = "cpu"; - enable-method = "psci"; -+ clocks = <&mcusys CLK_MCU_ARM_DIV_SEL>, -+ <&topckgen CLK_TOP_XTAL>; -+ clock-names = "cpu", "intermediate"; -+ operating-points-v2 = <&cluster0_opp>; - }; - - cpu@1 { -@@ -28,6 +32,10 @@ cpu@1 { - reg = <0x1>; - device_type = "cpu"; - enable-method = "psci"; -+ clocks = <&mcusys CLK_MCU_ARM_DIV_SEL>, -+ <&topckgen CLK_TOP_XTAL>; -+ clock-names = "cpu", "intermediate"; -+ operating-points-v2 = <&cluster0_opp>; - }; - - cpu@2 { -@@ -35,6 +43,10 @@ cpu@2 { - reg = <0x2>; - device_type = "cpu"; - enable-method = "psci"; -+ clocks = <&mcusys CLK_MCU_ARM_DIV_SEL>, -+ <&topckgen CLK_TOP_XTAL>; -+ clock-names = "cpu", "intermediate"; -+ operating-points-v2 = <&cluster0_opp>; - }; - - cpu@3 { -@@ -42,6 +54,32 @@ cpu@3 { - reg = <0x3>; - device_type = "cpu"; - enable-method = "psci"; -+ clocks = <&mcusys CLK_MCU_ARM_DIV_SEL>, -+ <&topckgen CLK_TOP_XTAL>; -+ clock-names = "cpu", "intermediate"; -+ operating-points-v2 = <&cluster0_opp>; -+ }; -+ -+ cluster0_opp: opp-table-0 { -+ compatible = "operating-points-v2"; -+ opp-shared; -+ -+ opp-800000000 { -+ opp-hz = /bits/ 64 <800000000>; -+ opp-microvolt = <850000>; -+ }; -+ opp-1100000000 { -+ opp-hz = /bits/ 64 <1100000000>; -+ opp-microvolt = <850000>; -+ }; -+ opp-1500000000 { -+ opp-hz = /bits/ 64 <1500000000>; -+ opp-microvolt = <850000>; -+ }; -+ opp-1800000000 { -+ opp-hz = /bits/ 64 <1800000000>; -+ opp-microvolt = <900000>; -+ }; - }; - }; - --- -2.51.0 - - -From a32293660d2f75d86ff0510e5080e1b6872cf19d Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 17 Dec 2024 10:12:22 +0100 -Subject: [PATCH 396/517] arm64: dts: mediatek: mt7988: Disable usb controllers - by default - -The controllers should be enabled at board level if used. - -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/r/20241217091238.16032-9-linux@fw-web.de -Signed-off-by: AngeloGioacchino Del Regno ---- - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index a7954bf5c81e..f8b01f3fff32 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -334,6 +334,7 @@ usb@11190000 { - <&infracfg CLK_INFRA_133M_USB_HCK>, - <&infracfg CLK_INFRA_USB_XHCI>; - clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck"; -+ status = "disabled"; - }; - - usb@11200000 { -@@ -348,6 +349,7 @@ usb@11200000 { - <&infracfg CLK_INFRA_133M_USB_HCK_CK_P1>, - <&infracfg CLK_INFRA_USB_XHCI_CK_P1>; - clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck"; -+ status = "disabled"; - }; - - mmc0: mmc@11230000 { --- -2.51.0 - - -From 1fdb543475c2e842edf667c3012ed827d7986831 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 17 Dec 2024 10:12:23 +0100 -Subject: [PATCH 397/517] arm64: dts: mediatek: mt7988: Add t-phy for ssusb1 - -USB controller needs phys for working properly. -On mt7988 ssusb0 uses a xs-phy, ssusb uses t-phy. -For now add the t-phy for ssusb1. We can reuse the mt7986 compatible -here. - -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/r/20241217091238.16032-10-linux@fw-web.de -Signed-off-by: AngeloGioacchino Del Regno ---- - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 25 +++++++++++++++++++++++ - 1 file changed, 25 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index f8b01f3fff32..209d170bce7f 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -349,6 +349,8 @@ usb@11200000 { - <&infracfg CLK_INFRA_133M_USB_HCK_CK_P1>, - <&infracfg CLK_INFRA_USB_XHCI_CK_P1>; - clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck"; -+ phys = <&tphyu2port0 PHY_TYPE_USB2>, -+ <&tphyu3port0 PHY_TYPE_USB3>; - status = "disabled"; - }; - -@@ -371,6 +373,29 @@ mmc0: mmc@11230000 { - status = "disabled"; - }; - -+ t-phy@11c50000 { -+ compatible = "mediatek,mt7986-tphy", -+ "mediatek,generic-tphy-v2"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ ranges; -+ status = "disabled"; -+ -+ tphyu2port0: usb-phy@11c50000 { -+ reg = <0 0x11c50000 0 0x700>; -+ clocks = <&infracfg CLK_INFRA_USB_UTMI_CK_P1>; -+ clock-names = "ref"; -+ #phy-cells = <1>; -+ }; -+ -+ tphyu3port0: usb-phy@11c50700 { -+ reg = <0 0x11c50700 0 0x900>; -+ clocks = <&infracfg CLK_INFRA_USB_PIPE_CK_P1>; -+ clock-names = "ref"; -+ #phy-cells = <1>; -+ }; -+ }; -+ - clock-controller@11f40000 { - compatible = "mediatek,mt7988-xfi-pll"; - reg = <0 0x11f40000 0 0x1000>; --- -2.51.0 - - -From ba6afcc4d52795e58ce148e960c3fefe94468e69 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 17 Dec 2024 10:12:24 +0100 -Subject: [PATCH 398/517] arm64: dts: mediatek: mt7988: Add pcie nodes - -Add pcie controllers for mt7988. Reuse mt7986 compatible. - -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/r/20241217091238.16032-11-linux@fw-web.de -Signed-off-by: AngeloGioacchino Del Regno ---- - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 152 ++++++++++++++++++++++ - 1 file changed, 152 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index 209d170bce7f..74c75d5149d7 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -373,6 +373,158 @@ mmc0: mmc@11230000 { - status = "disabled"; - }; - -+ pcie@11280000 { -+ compatible = "mediatek,mt7986-pcie", -+ "mediatek,mt8192-pcie"; -+ device_type = "pci"; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ reg = <0 0x11280000 0 0x2000>; -+ reg-names = "pcie-mac"; -+ linux,pci-domain = <3>; -+ interrupts = ; -+ bus-range = <0x00 0xff>; -+ ranges = <0x81000000 0x00 0x20000000 0x00 -+ 0x20000000 0x00 0x00200000>, -+ <0x82000000 0x00 0x20200000 0x00 -+ 0x20200000 0x00 0x07e00000>; -+ clocks = <&infracfg CLK_INFRA_PCIE_PIPE_P2>, -+ <&infracfg CLK_INFRA_PCIE_GFMUX_TL_P2>, -+ <&infracfg CLK_INFRA_PCIE_PERI_26M_CK_P2>, -+ <&infracfg CLK_INFRA_133M_PCIE_CK_P2>; -+ clock-names = "pl_250m", "tl_26m", "peri_26m", -+ "top_133m"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie2_pins>; -+ status = "disabled"; -+ -+ #interrupt-cells = <1>; -+ interrupt-map-mask = <0 0 0 0x7>; -+ interrupt-map = <0 0 0 1 &pcie_intc2 0>, -+ <0 0 0 2 &pcie_intc2 1>, -+ <0 0 0 3 &pcie_intc2 2>, -+ <0 0 0 4 &pcie_intc2 3>; -+ pcie_intc2: interrupt-controller { -+ #address-cells = <0>; -+ #interrupt-cells = <1>; -+ interrupt-controller; -+ }; -+ }; -+ -+ pcie@11290000 { -+ compatible = "mediatek,mt7986-pcie", -+ "mediatek,mt8192-pcie"; -+ device_type = "pci"; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ reg = <0 0x11290000 0 0x2000>; -+ reg-names = "pcie-mac"; -+ linux,pci-domain = <2>; -+ interrupts = ; -+ bus-range = <0x00 0xff>; -+ ranges = <0x81000000 0x00 0x28000000 0x00 -+ 0x28000000 0x00 0x00200000>, -+ <0x82000000 0x00 0x28200000 0x00 -+ 0x28200000 0x00 0x07e00000>; -+ clocks = <&infracfg CLK_INFRA_PCIE_PIPE_P3>, -+ <&infracfg CLK_INFRA_PCIE_GFMUX_TL_P3>, -+ <&infracfg CLK_INFRA_PCIE_PERI_26M_CK_P3>, -+ <&infracfg CLK_INFRA_133M_PCIE_CK_P3>; -+ clock-names = "pl_250m", "tl_26m", "peri_26m", -+ "top_133m"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie3_pins>; -+ status = "disabled"; -+ -+ #interrupt-cells = <1>; -+ interrupt-map-mask = <0 0 0 0x7>; -+ interrupt-map = <0 0 0 1 &pcie_intc3 0>, -+ <0 0 0 2 &pcie_intc3 1>, -+ <0 0 0 3 &pcie_intc3 2>, -+ <0 0 0 4 &pcie_intc3 3>; -+ pcie_intc3: interrupt-controller { -+ #address-cells = <0>; -+ #interrupt-cells = <1>; -+ interrupt-controller; -+ }; -+ }; -+ -+ pcie@11300000 { -+ compatible = "mediatek,mt7986-pcie", -+ "mediatek,mt8192-pcie"; -+ device_type = "pci"; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ reg = <0 0x11300000 0 0x2000>; -+ reg-names = "pcie-mac"; -+ linux,pci-domain = <0>; -+ interrupts = ; -+ bus-range = <0x00 0xff>; -+ ranges = <0x81000000 0x00 0x30000000 0x00 -+ 0x30000000 0x00 0x00200000>, -+ <0x82000000 0x00 0x30200000 0x00 -+ 0x30200000 0x00 0x07e00000>; -+ clocks = <&infracfg CLK_INFRA_PCIE_PIPE_P0>, -+ <&infracfg CLK_INFRA_PCIE_GFMUX_TL_P0>, -+ <&infracfg CLK_INFRA_PCIE_PERI_26M_CK_P0>, -+ <&infracfg CLK_INFRA_133M_PCIE_CK_P0>; -+ clock-names = "pl_250m", "tl_26m", "peri_26m", -+ "top_133m"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie0_pins>; -+ status = "disabled"; -+ -+ #interrupt-cells = <1>; -+ interrupt-map-mask = <0 0 0 0x7>; -+ interrupt-map = <0 0 0 1 &pcie_intc0 0>, -+ <0 0 0 2 &pcie_intc0 1>, -+ <0 0 0 3 &pcie_intc0 2>, -+ <0 0 0 4 &pcie_intc0 3>; -+ pcie_intc0: interrupt-controller { -+ #address-cells = <0>; -+ #interrupt-cells = <1>; -+ interrupt-controller; -+ }; -+ }; -+ -+ pcie@11310000 { -+ compatible = "mediatek,mt7986-pcie", -+ "mediatek,mt8192-pcie"; -+ device_type = "pci"; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ reg = <0 0x11310000 0 0x2000>; -+ reg-names = "pcie-mac"; -+ linux,pci-domain = <1>; -+ interrupts = ; -+ bus-range = <0x00 0xff>; -+ ranges = <0x81000000 0x00 0x38000000 0x00 -+ 0x38000000 0x00 0x00200000>, -+ <0x82000000 0x00 0x38200000 0x00 -+ 0x38200000 0x00 0x07e00000>; -+ clocks = <&infracfg CLK_INFRA_PCIE_PIPE_P1>, -+ <&infracfg CLK_INFRA_PCIE_GFMUX_TL_P1>, -+ <&infracfg CLK_INFRA_PCIE_PERI_26M_CK_P1>, -+ <&infracfg CLK_INFRA_133M_PCIE_CK_P1>; -+ clock-names = "pl_250m", "tl_26m", "peri_26m", -+ "top_133m"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie1_pins>; -+ status = "disabled"; -+ -+ #interrupt-cells = <1>; -+ interrupt-map-mask = <0 0 0 0x7>; -+ interrupt-map = <0 0 0 1 &pcie_intc1 0>, -+ <0 0 0 2 &pcie_intc1 1>, -+ <0 0 0 3 &pcie_intc1 2>, -+ <0 0 0 4 &pcie_intc1 3>; -+ pcie_intc1: interrupt-controller { -+ #address-cells = <0>; -+ #interrupt-cells = <1>; -+ interrupt-controller; -+ }; -+ }; -+ - t-phy@11c50000 { - compatible = "mediatek,mt7986-tphy", - "mediatek,generic-tphy-v2"; --- -2.51.0 - - -From a99265c23bb893b0b9c5f5ba13fdacb5a21652ce Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 17 Dec 2024 09:54:30 +0100 -Subject: [PATCH 399/517] arm64: dts: mediatek: mt7988a-bpi-r4: Add pinctrl - subnodes for bpi-r4 - -Add board specific pinctrl configurations on Bananapi R4. - -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/r/20241217085435.9586-6-linux@fw-web.de -Signed-off-by: AngeloGioacchino Del Regno ---- - .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 189 ++++++++++++++++++ - 1 file changed, 189 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -index efc4ad0b08b8..aa2dabc041fd 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -@@ -9,3 +9,192 @@ / { - model = "Banana Pi BPI-R4"; - chassis-type = "embedded"; - }; -+ -+&pio { -+ mdio0_pins: mdio0-pins { -+ mux { -+ function = "eth"; -+ groups = "mdc_mdio0"; -+ }; -+ -+ conf { -+ pins = "SMI_0_MDC", "SMI_0_MDIO"; -+ drive-strength = <8>; -+ }; -+ }; -+ -+ i2c0_pins: i2c0-g0-pins { -+ mux { -+ function = "i2c"; -+ groups = "i2c0_1"; -+ }; -+ }; -+ -+ i2c1_pins: i2c1-g0-pins { -+ mux { -+ function = "i2c"; -+ groups = "i2c1_0"; -+ }; -+ }; -+ -+ i2c1_sfp_pins: i2c1-sfp-g0-pins { -+ mux { -+ function = "i2c"; -+ groups = "i2c1_sfp"; -+ }; -+ }; -+ -+ i2c2_0_pins: i2c2-g0-pins { -+ mux { -+ function = "i2c"; -+ groups = "i2c2_0"; -+ }; -+ }; -+ -+ i2c2_1_pins: i2c2-g1-pins { -+ mux { -+ function = "i2c"; -+ groups = "i2c2_1"; -+ }; -+ }; -+ -+ gbe0_led0_pins: gbe0-led0-pins { -+ mux { -+ function = "led"; -+ groups = "gbe0_led0"; -+ }; -+ }; -+ -+ gbe1_led0_pins: gbe1-led0-pins { -+ mux { -+ function = "led"; -+ groups = "gbe1_led0"; -+ }; -+ }; -+ -+ gbe2_led0_pins: gbe2-led0-pins { -+ mux { -+ function = "led"; -+ groups = "gbe2_led0"; -+ }; -+ }; -+ -+ gbe3_led0_pins: gbe3-led0-pins { -+ mux { -+ function = "led"; -+ groups = "gbe3_led0"; -+ }; -+ }; -+ -+ gbe0_led1_pins: gbe0-led1-pins { -+ mux { -+ function = "led"; -+ groups = "gbe0_led1"; -+ }; -+ }; -+ -+ gbe1_led1_pins: gbe1-led1-pins { -+ mux { -+ function = "led"; -+ groups = "gbe1_led1"; -+ }; -+ }; -+ -+ gbe2_led1_pins: gbe2-led1-pins { -+ mux { -+ function = "led"; -+ groups = "gbe2_led1"; -+ }; -+ }; -+ -+ gbe3_led1_pins: gbe3-led1-pins { -+ mux { -+ function = "led"; -+ groups = "gbe3_led1"; -+ }; -+ }; -+ -+ i2p5gbe_led0_pins: 2p5gbe-led0-pins { -+ mux { -+ function = "led"; -+ groups = "2p5gbe_led0"; -+ }; -+ }; -+ -+ i2p5gbe_led1_pins: 2p5gbe-led1-pins { -+ mux { -+ function = "led"; -+ groups = "2p5gbe_led1"; -+ }; -+ }; -+ -+ mmc0_pins_emmc_45: mmc0-emmc-45-pins { -+ mux { -+ function = "flash"; -+ groups = "emmc_45"; -+ }; -+ }; -+ -+ mmc0_pins_emmc_51: mmc0-emmc-51-pins { -+ mux { -+ function = "flash"; -+ groups = "emmc_51"; -+ }; -+ }; -+ -+ mmc0_pins_sdcard: mmc0-sdcard-pins { -+ mux { -+ function = "flash"; -+ groups = "sdcard"; -+ }; -+ }; -+ -+ uart0_pins: uart0-pins { -+ mux { -+ function = "uart"; -+ groups = "uart0"; -+ }; -+ }; -+ -+ snfi_pins: snfi-pins { -+ mux { -+ function = "flash"; -+ groups = "snfi"; -+ }; -+ }; -+ -+ spi0_pins: spi0-pins { -+ mux { -+ function = "spi"; -+ groups = "spi0"; -+ }; -+ }; -+ -+ spi0_flash_pins: spi0-flash-pins { -+ mux { -+ function = "spi"; -+ groups = "spi0", "spi0_wp_hold"; -+ }; -+ }; -+ -+ spi1_pins: spi1-pins { -+ mux { -+ function = "spi"; -+ groups = "spi1"; -+ }; -+ }; -+ -+ spi2_pins: spi2-pins { -+ mux { -+ function = "spi"; -+ groups = "spi2"; -+ }; -+ }; -+ -+ spi2_flash_pins: spi2-flash-pins { -+ mux { -+ function = "spi"; -+ groups = "spi2", "spi2_wp_hold"; -+ }; -+ }; -+}; --- -2.51.0 - - -From c311c2eff0873eac18886281d368b42581c01d1c Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 17 Dec 2024 10:12:25 +0100 -Subject: [PATCH 400/517] arm64: dts: mediatek: mt7988a-bpi-r4: Enable watchdog - -Enable the watchdog on Bananapi R4 board. - -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/r/20241217091238.16032-12-linux@fw-web.de -Signed-off-by: AngeloGioacchino Del Regno ---- - arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -index aa2dabc041fd..d914eae2b524 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -@@ -198,3 +198,7 @@ mux { - }; - }; - }; -+ -+&watchdog { -+ status = "okay"; -+}; --- -2.51.0 - - -From 65c66cd8018fd84c92c9ccf5f0c678d50229c7c5 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 17 Dec 2024 10:12:26 +0100 -Subject: [PATCH 401/517] arm64: dts: mediatek: mt7988a-bpi-r4: Add fixed - regulators for 1v8 and 3v3 - -Add regulator nodes used for mmc to Bananapi R4 board. -This board has 1 MMC controller used for SDMMC and eMMC where only one can -be used at one time, selected by hardware switches. SD uses 3v3 for both -supplies and emmc uses both regulators. -So defining both regulators in board dts and referencing them in the dt -overlay. - -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/r/20241217091238.16032-13-linux@fw-web.de -Signed-off-by: AngeloGioacchino Del Regno ---- - .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -index d914eae2b524..df53512c6890 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -@@ -8,6 +8,24 @@ / { - compatible = "bananapi,bpi-r4", "mediatek,mt7988a"; - model = "Banana Pi BPI-R4"; - chassis-type = "embedded"; -+ -+ reg_1p8v: regulator-1p8v { -+ compatible = "regulator-fixed"; -+ regulator-name = "fixed-1.8V"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ reg_3p3v: regulator-3p3v { -+ compatible = "regulator-fixed"; -+ regulator-name = "fixed-3.3V"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; - }; - - &pio { --- -2.51.0 - - -From fbf80ec8ea987d4b1502f5c3cd828178cd25ae60 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 17 Dec 2024 10:12:28 +0100 -Subject: [PATCH 402/517] arm64: dts: mediatek: mt7988a-bpi-r4: Add thermal - configuration - -Add additional thermal trips to Bananapi R4 board. -SoC only contains the critical trip. - -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/r/20241217091238.16032-15-linux@fw-web.de -Signed-off-by: AngeloGioacchino Del Regno ---- - .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 28 +++++++++++++++++++ - 1 file changed, 28 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -index df53512c6890..8a320d9da443 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -@@ -28,6 +28,34 @@ reg_3p3v: regulator-3p3v { - }; - }; - -+&cpu_thermal { -+ trips { -+ cpu_trip_hot: hot { -+ temperature = <120000>; -+ hysteresis = <2000>; -+ type = "hot"; -+ }; -+ -+ cpu_trip_active_high: active-high { -+ temperature = <115000>; -+ hysteresis = <2000>; -+ type = "active"; -+ }; -+ -+ cpu_trip_active_med: active-med { -+ temperature = <85000>; -+ hysteresis = <2000>; -+ type = "active"; -+ }; -+ -+ cpu_trip_active_low: active-low { -+ temperature = <40000>; -+ hysteresis = <2000>; -+ type = "active"; -+ }; -+ }; -+}; -+ - &pio { - mdio0_pins: mdio0-pins { - mux { --- -2.51.0 - - -From d9387686201948033cc157e6f558a74355d26df5 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 17 Dec 2024 10:12:29 +0100 -Subject: [PATCH 403/517] arm64: dts: mediatek: mt7988a-bpi-r4: Enable serial0 - debug uart - -Enable the debug uart on Bananapi R4 board. - -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/r/20241217091238.16032-16-linux@fw-web.de -Signed-off-by: AngeloGioacchino Del Regno ---- - arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 4 ++++ - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 2 +- - 2 files changed, 5 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -index 8a320d9da443..9037f35857a9 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -@@ -245,6 +245,10 @@ mux { - }; - }; - -+&serial0 { -+ status = "okay"; -+}; -+ - &watchdog { - status = "okay"; - }; -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index 74c75d5149d7..59a1ffc2edfc 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -236,7 +236,7 @@ mcusys: mcusys@100e0000 { - #clock-cells = <1>; - }; - -- serial@11000000 { -+ serial0: serial@11000000 { - compatible = "mediatek,mt7988-uart", "mediatek,mt6577-uart"; - reg = <0 0x11000000 0 0x100>; - interrupts = ; --- -2.51.0 - - -From cf8247feecf2566f95bffc1b759132155c0f00de Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 17 Dec 2024 10:12:30 +0100 -Subject: [PATCH 404/517] arm64: dts: mediatek: mt7988a-bpi-r4: Add default - UART stdout - -Add chosen node on Bananapi R4 board with stdout and default bootargs. - -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/r/20241217091238.16032-17-linux@fw-web.de -Signed-off-by: AngeloGioacchino Del Regno ---- - arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -index 9037f35857a9..46117df7d44c 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -@@ -9,6 +9,10 @@ / { - model = "Banana Pi BPI-R4"; - chassis-type = "embedded"; - -+ chosen { -+ stdout-path = "serial0:115200n8"; -+ }; -+ - reg_1p8v: regulator-1p8v { - compatible = "regulator-fixed"; - regulator-name = "fixed-1.8V"; --- -2.51.0 - - -From 0ae0dc4c7db9945521c400ffdf8f02879b50689c Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 17 Dec 2024 10:12:31 +0100 -Subject: [PATCH 405/517] arm64: dts: mediatek: mt7988a-bpi-r4: Enable I2C - controllers - -Enable the I2C0, I2C2 controllers found on the BananaPi R4 board. -Both controllers are not accessible from user and having fixed spare -devices. I2C0 have a pmic connected, I2C2 is used with I2C-multiplexer -for e.g. SFP cages. -The missing I2C1 is connected to GPIO header which can have either GPIO -mode or I2C mode. - -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/r/20241217091238.16032-18-linux@fw-web.de -Signed-off-by: AngeloGioacchino Del Regno ---- - .../boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 12 ++++++++++++ - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 6 +++--- - 2 files changed, 15 insertions(+), 3 deletions(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -index 46117df7d44c..3d165f7b29dc 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -@@ -60,6 +60,18 @@ cpu_trip_active_low: active-low { - }; - }; - -+&i2c0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_pins>; -+ status = "okay"; -+}; -+ -+&i2c2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c2_1_pins>; -+ status = "okay"; -+}; -+ - &pio { - mdio0_pins: mdio0-pins { - mux { -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index 59a1ffc2edfc..c0a49f68834a 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -269,7 +269,7 @@ serial@11000200 { - status = "disabled"; - }; - -- i2c@11003000 { -+ i2c0: i2c@11003000 { - compatible = "mediatek,mt7981-i2c"; - reg = <0 0x11003000 0 0x1000>, - <0 0x10217080 0 0x80>; -@@ -283,7 +283,7 @@ i2c@11003000 { - status = "disabled"; - }; - -- i2c@11004000 { -+ i2c1: i2c@11004000 { - compatible = "mediatek,mt7981-i2c"; - reg = <0 0x11004000 0 0x1000>, - <0 0x10217100 0 0x80>; -@@ -297,7 +297,7 @@ i2c@11004000 { - status = "disabled"; - }; - -- i2c@11005000 { -+ i2c2: i2c@11005000 { - compatible = "mediatek,mt7981-i2c"; - reg = <0 0x11005000 0 0x1000>, - <0 0x10217180 0 0x80>; --- -2.51.0 - - -From cb1ff418a05559a1e32911d8721217269d978c3f Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 17 Dec 2024 10:12:32 +0100 -Subject: [PATCH 406/517] arm64: dts: mediatek: mt7988a-bpi-r4: Add PCA9545 I2C - Mux - -Bananapi R4 uses an i2c multiplexer for SFP slots, rtc and eeprom. -Add its node to the right i2c controller. - -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/r/20241217091238.16032-19-linux@fw-web.de -Signed-off-by: AngeloGioacchino Del Regno ---- - .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 41 +++++++++++++++++++ - 1 file changed, 41 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -index 3d165f7b29dc..0dc1fd9265c6 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -@@ -2,6 +2,8 @@ - - /dts-v1/; - -+#include -+ - #include "mt7988a.dtsi" - - / { -@@ -70,6 +72,45 @@ &i2c2 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c2_1_pins>; - status = "okay"; -+ -+ pca9545: i2c-mux@70 { -+ compatible = "nxp,pca9545"; -+ reg = <0x70>; -+ reset-gpios = <&pio 5 GPIO_ACTIVE_LOW>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ -+ pcf8563: rtc@51 { -+ compatible = "nxp,pcf8563"; -+ reg = <0x51>; -+ #clock-cells = <0>; -+ }; -+ -+ eeprom@57 { -+ compatible = "atmel,24c02"; -+ reg = <0x57>; -+ size = <256>; -+ }; -+ -+ }; -+ -+ i2c_sfp1: i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ }; -+ -+ i2c_sfp2: i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <2>; -+ }; -+ }; - }; - - &pio { --- -2.51.0 - - -From fc1e5be0bc78c5339f0d864251b4da8e72a4bf09 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 17 Dec 2024 10:12:33 +0100 -Subject: [PATCH 407/517] arm64: dts: mediatek: mt7988a-bpi-r4: Enable t-phy - for ssusb1 - -Bananapi R4 uses t-phy for usb. Enable its node at board level. - -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/r/20241217091238.16032-20-linux@fw-web.de -Signed-off-by: AngeloGioacchino Del Regno ---- - arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 4 ++++ - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 2 +- - 2 files changed, 5 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -index 0dc1fd9265c6..129031b0d784 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -@@ -306,6 +306,10 @@ &serial0 { - status = "okay"; - }; - -+&tphy { -+ status = "okay"; -+}; -+ - &watchdog { - status = "okay"; - }; -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index c0a49f68834a..0766ca0dd3f6 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -525,7 +525,7 @@ pcie_intc1: interrupt-controller { - }; - }; - -- t-phy@11c50000 { -+ tphy: t-phy@11c50000 { - compatible = "mediatek,mt7986-tphy", - "mediatek,generic-tphy-v2"; - #address-cells = <2>; --- -2.51.0 - - -From 622671b5fc76a6544e1394c8ea019ad7e90a22f4 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 17 Dec 2024 10:12:34 +0100 -Subject: [PATCH 408/517] arm64: dts: mediatek: mt7988a-bpi-r4: Enable ssusb1 - on bpi-r4 - -Enable usb on Bananapi R4 board. - -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/r/20241217091238.16032-21-linux@fw-web.de -Signed-off-by: AngeloGioacchino Del Regno ---- - arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 4 ++++ - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 2 +- - 2 files changed, 5 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -index 129031b0d784..08d664d6449b 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -@@ -306,6 +306,10 @@ &serial0 { - status = "okay"; - }; - -+&ssusb1 { -+ status = "okay"; -+}; -+ - &tphy { - status = "okay"; - }; -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index 0766ca0dd3f6..f3e942db0b99 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -337,7 +337,7 @@ usb@11190000 { - status = "disabled"; - }; - -- usb@11200000 { -+ ssusb1: usb@11200000 { - compatible = "mediatek,mt7988-xhci", "mediatek,mtk-xhci"; - reg = <0 0x11200000 0 0x2e00>, - <0 0x11203e00 0 0x0100>; --- -2.51.0 - - -From d985de90a4c6d7b466c7d42d85095604a83a63fe Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 17 Dec 2024 10:12:35 +0100 -Subject: [PATCH 409/517] arm64: dts: mediatek: mt7988a-bpi-r4: Enable pwm - -Enable pwm on Bananapi R4 board. - -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/r/20241217091238.16032-22-linux@fw-web.de -Signed-off-by: AngeloGioacchino Del Regno ---- - arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 4 ++++ - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 2 +- - 2 files changed, 5 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -index 08d664d6449b..4b1eaf818b66 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -@@ -302,6 +302,10 @@ mux { - }; - }; - -+&pwm { -+ status = "okay"; -+}; -+ - &serial0 { - status = "okay"; - }; -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index f3e942db0b99..6f6a1a1c1d78 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -211,7 +211,7 @@ mux { - }; - }; - -- pwm@10048000 { -+ pwm: pwm@10048000 { - compatible = "mediatek,mt7988-pwm"; - reg = <0 0x10048000 0 0x1000>; - clocks = <&infracfg CLK_INFRA_66M_PWM_BCK>, --- -2.51.0 - - -From 0d428f6a03e252a4977c226592370b6057ba47ec Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 17 Dec 2024 10:12:36 +0100 -Subject: [PATCH 410/517] arm64: dts: mediatek: mt7988a-bpi-r4: Enable pcie - -Enable the pci controllers on BPI-R4. - -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/r/20241217091238.16032-23-linux@fw-web.de -Signed-off-by: AngeloGioacchino Del Regno ---- - .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 20 +++++++++++++++++++ - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 8 ++++---- - 2 files changed, 24 insertions(+), 4 deletions(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -index 4b1eaf818b66..d6f1fca3323c 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -@@ -113,6 +113,26 @@ i2c_sfp2: i2c@2 { - }; - }; - -+/* mPCIe SIM2 */ -+&pcie0 { -+ status = "okay"; -+}; -+ -+/* mPCIe SIM3 */ -+&pcie1 { -+ status = "okay"; -+}; -+ -+/* M.2 key-B SIM1 */ -+&pcie2 { -+ status = "okay"; -+}; -+ -+/* M.2 key-M SSD */ -+&pcie3 { -+ status = "okay"; -+}; -+ - &pio { - mdio0_pins: mdio0-pins { - mux { -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index 6f6a1a1c1d78..7a5e16a97476 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -373,7 +373,7 @@ mmc0: mmc@11230000 { - status = "disabled"; - }; - -- pcie@11280000 { -+ pcie2: pcie@11280000 { - compatible = "mediatek,mt7986-pcie", - "mediatek,mt8192-pcie"; - device_type = "pci"; -@@ -411,7 +411,7 @@ pcie_intc2: interrupt-controller { - }; - }; - -- pcie@11290000 { -+ pcie3: pcie@11290000 { - compatible = "mediatek,mt7986-pcie", - "mediatek,mt8192-pcie"; - device_type = "pci"; -@@ -449,7 +449,7 @@ pcie_intc3: interrupt-controller { - }; - }; - -- pcie@11300000 { -+ pcie0: pcie@11300000 { - compatible = "mediatek,mt7986-pcie", - "mediatek,mt8192-pcie"; - device_type = "pci"; -@@ -487,7 +487,7 @@ pcie_intc0: interrupt-controller { - }; - }; - -- pcie@11310000 { -+ pcie1: pcie@11310000 { - compatible = "mediatek,mt7986-pcie", - "mediatek,mt8192-pcie"; - device_type = "pci"; --- -2.51.0 - - -From b3e25597ce6ae8971e784945a00c8bdbd7866883 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Fri, 20 Dec 2024 17:38:35 +0100 -Subject: [PATCH 411/517] arm64: dts: mediatek: mt7988a-bpi-r4: Add MediaTek - MT6682A/RT5190A PMIC - -Bananapi R4 Board contains a MT6682A pmic which is compatible to rt5190a. -Add its node to the i2 controller. - -The BananaPi R4 board has a MediaTek MT6682A PMIC, a rebrand of the -Richtek RT5190A chip, connected to the I2C0 bus. - -Add the relevant node and, while at it, also configure the regulators -from this PMIC that are used on this board. - -Only Buck2/Buck3 voltage can be controlled by software. - -BUCK4 input is 5V from BUCK1 output, and the resistor (mapped to RP30/RP31 -on BPI-R4) configures BUCK4 output to 1.8V. -LDO input is 3.3V from 3.3VD, and the resistor (mapped to RP38/RP40 on -BPI-R4) configures LDO output to 1.8V. - -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/r/20241220163838.114786-2-linux@fw-web.de -Signed-off-by: AngeloGioacchino Del Regno ---- - .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 50 +++++++++++++++++++ - 1 file changed, 50 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -index d6f1fca3323c..27edc6b84f80 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -@@ -3,6 +3,7 @@ - /dts-v1/; - - #include -+#include - - #include "mt7988a.dtsi" - -@@ -66,6 +67,55 @@ &i2c0 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins>; - status = "okay"; -+ -+ rt5190a_64: rt5190a@64 { -+ compatible = "richtek,rt5190a"; -+ reg = <0x64>; -+ vin2-supply = <&rt5190_buck1>; -+ vin3-supply = <&rt5190_buck1>; -+ vin4-supply = <&rt5190_buck1>; -+ -+ regulators { -+ rt5190_buck1: buck1 { -+ regulator-name = "rt5190a-buck1"; -+ regulator-min-microvolt = <5090000>; -+ regulator-max-microvolt = <5090000>; -+ regulator-allowed-modes = -+ , ; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ buck2 { -+ regulator-name = "vcore"; -+ regulator-min-microvolt = <600000>; -+ regulator-max-microvolt = <1400000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ rt5190_buck3: buck3 { -+ regulator-name = "vproc"; -+ regulator-min-microvolt = <600000>; -+ regulator-max-microvolt = <1400000>; -+ regulator-boot-on; -+ }; -+ buck4 { -+ regulator-name = "rt5190a-buck4"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-allowed-modes = -+ , ; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ ldo { -+ regulator-name = "rt5190a-ldo"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ }; -+ }; - }; - - &i2c2 { --- -2.51.0 - - -From 200185c61220ecb7982d5605701649e925c7e11b Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Fri, 20 Dec 2024 17:38:36 +0100 -Subject: [PATCH 412/517] arm64: dts: mediatek: mt7988a-bpi-r4: Add proc-supply - for cpus - -Add proc-supply property to cpus on Bananapi R4 board. - -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/r/20241220163838.114786-3-linux@fw-web.de -Signed-off-by: AngeloGioacchino Del Regno ---- - .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 16 ++++++++++++++++ - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 8 ++++---- - 2 files changed, 20 insertions(+), 4 deletions(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -index 27edc6b84f80..6623112c24c7 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -@@ -35,6 +35,22 @@ reg_3p3v: regulator-3p3v { - }; - }; - -+&cpu0 { -+ proc-supply = <&rt5190_buck3>; -+}; -+ -+&cpu1 { -+ proc-supply = <&rt5190_buck3>; -+}; -+ -+&cpu2 { -+ proc-supply = <&rt5190_buck3>; -+}; -+ -+&cpu3 { -+ proc-supply = <&rt5190_buck3>; -+}; -+ - &cpu_thermal { - trips { - cpu_trip_hot: hot { -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index 7a5e16a97476..88b56a24efca 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -16,7 +16,7 @@ cpus { - #address-cells = <1>; - #size-cells = <0>; - -- cpu@0 { -+ cpu0: cpu@0 { - compatible = "arm,cortex-a73"; - reg = <0x0>; - device_type = "cpu"; -@@ -27,7 +27,7 @@ cpu@0 { - operating-points-v2 = <&cluster0_opp>; - }; - -- cpu@1 { -+ cpu1: cpu@1 { - compatible = "arm,cortex-a73"; - reg = <0x1>; - device_type = "cpu"; -@@ -38,7 +38,7 @@ cpu@1 { - operating-points-v2 = <&cluster0_opp>; - }; - -- cpu@2 { -+ cpu2: cpu@2 { - compatible = "arm,cortex-a73"; - reg = <0x2>; - device_type = "cpu"; -@@ -49,7 +49,7 @@ cpu@2 { - operating-points-v2 = <&cluster0_opp>; - }; - -- cpu@3 { -+ cpu3: cpu@3 { - compatible = "arm,cortex-a73"; - reg = <0x3>; - device_type = "cpu"; --- -2.51.0 - - -From 59d0aeb36921af8a5aea530485a6ede3adf9abc3 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 22 Apr 2025 15:24:29 +0200 -Subject: [PATCH 413/517] phy: mediatek: xsphy: support type switch by pericfg - -Patch from Sam Shih found in MediaTek SDK -released under GPL. - -Get syscon and use it to set the PHY type. -Extend support to PCIe and SGMII mode in addition to USB2 and USB3. - -Signed-off-by: Daniel Golle -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno ---- - drivers/phy/mediatek/phy-mtk-xsphy.c | 85 +++++++++++++++++++++++++++- - 1 file changed, 84 insertions(+), 1 deletion(-) - -diff --git a/drivers/phy/mediatek/phy-mtk-xsphy.c b/drivers/phy/mediatek/phy-mtk-xsphy.c -index 7c248f5cfca5..c0ddb9273cc3 100644 ---- a/drivers/phy/mediatek/phy-mtk-xsphy.c -+++ b/drivers/phy/mediatek/phy-mtk-xsphy.c -@@ -11,10 +11,12 @@ - #include - #include - #include -+#include - #include - #include - #include - #include -+#include - - #include "phy-mtk-io.h" - -@@ -81,12 +83,22 @@ - #define XSP_SR_COEF_DIVISOR 1000 - #define XSP_FM_DET_CYCLE_CNT 1024 - -+/* PHY switch between pcie/usb3/sgmii */ -+#define USB_PHY_SWITCH_CTRL 0x0 -+#define RG_PHY_SW_TYPE GENMASK(3, 0) -+#define RG_PHY_SW_PCIE 0x0 -+#define RG_PHY_SW_USB3 0x1 -+#define RG_PHY_SW_SGMII 0x2 -+ - struct xsphy_instance { - struct phy *phy; - void __iomem *port_base; - struct clk *ref_clk; /* reference clock of anolog phy */ - u32 index; - u32 type; -+ struct regmap *type_sw; -+ u32 type_sw_reg; -+ u32 type_sw_index; - /* only for HQA test */ - int efuse_intr; - int efuse_tx_imp; -@@ -259,6 +271,10 @@ static void phy_parse_property(struct mtk_xsphy *xsphy, - inst->efuse_intr, inst->efuse_tx_imp, - inst->efuse_rx_imp); - break; -+ case PHY_TYPE_PCIE: -+ case PHY_TYPE_SGMII: -+ /* nothing to do */ -+ break; - default: - dev_err(xsphy->dev, "incompatible phy type\n"); - return; -@@ -305,6 +321,62 @@ static void u3_phy_props_set(struct mtk_xsphy *xsphy, - RG_XTP_LN0_RX_IMPSEL, inst->efuse_rx_imp); - } - -+/* type switch for usb3/pcie/sgmii */ -+static int phy_type_syscon_get(struct xsphy_instance *instance, -+ struct device_node *dn) -+{ -+ struct of_phandle_args args; -+ int ret; -+ -+ /* type switch function is optional */ -+ if (!of_property_present(dn, "mediatek,syscon-type")) -+ return 0; -+ -+ ret = of_parse_phandle_with_fixed_args(dn, "mediatek,syscon-type", -+ 2, 0, &args); -+ if (ret) -+ return ret; -+ -+ instance->type_sw_reg = args.args[0]; -+ instance->type_sw_index = args.args[1] & 0x3; /* <=3 */ -+ instance->type_sw = syscon_node_to_regmap(args.np); -+ of_node_put(args.np); -+ dev_info(&instance->phy->dev, "type_sw - reg %#x, index %d\n", -+ instance->type_sw_reg, instance->type_sw_index); -+ -+ return PTR_ERR_OR_ZERO(instance->type_sw); -+} -+ -+static int phy_type_set(struct xsphy_instance *instance) -+{ -+ int type; -+ u32 offset; -+ -+ if (!instance->type_sw) -+ return 0; -+ -+ switch (instance->type) { -+ case PHY_TYPE_USB3: -+ type = RG_PHY_SW_USB3; -+ break; -+ case PHY_TYPE_PCIE: -+ type = RG_PHY_SW_PCIE; -+ break; -+ case PHY_TYPE_SGMII: -+ type = RG_PHY_SW_SGMII; -+ break; -+ case PHY_TYPE_USB2: -+ default: -+ return 0; -+ } -+ -+ offset = instance->type_sw_index * BITS_PER_BYTE; -+ regmap_update_bits(instance->type_sw, instance->type_sw_reg, -+ RG_PHY_SW_TYPE << offset, type << offset); -+ -+ return 0; -+} -+ - static int mtk_phy_init(struct phy *phy) - { - struct xsphy_instance *inst = phy_get_drvdata(phy); -@@ -325,6 +397,10 @@ static int mtk_phy_init(struct phy *phy) - case PHY_TYPE_USB3: - u3_phy_props_set(xsphy, inst); - break; -+ case PHY_TYPE_PCIE: -+ case PHY_TYPE_SGMII: -+ /* nothing to do, only used to set type */ -+ break; - default: - dev_err(xsphy->dev, "incompatible phy type\n"); - clk_disable_unprepare(inst->ref_clk); -@@ -403,12 +479,15 @@ static struct phy *mtk_phy_xlate(struct device *dev, - - inst->type = args->args[0]; - if (!(inst->type == PHY_TYPE_USB2 || -- inst->type == PHY_TYPE_USB3)) { -+ inst->type == PHY_TYPE_USB3 || -+ inst->type == PHY_TYPE_PCIE || -+ inst->type == PHY_TYPE_SGMII)) { - dev_err(dev, "unsupported phy type: %d\n", inst->type); - return ERR_PTR(-EINVAL); - } - - phy_parse_property(xsphy, inst); -+ phy_type_set(inst); - - return inst->phy; - } -@@ -510,6 +589,10 @@ static int mtk_xsphy_probe(struct platform_device *pdev) - dev_err(dev, "failed to get ref_clk(id-%d)\n", port); - return PTR_ERR(inst->ref_clk); - } -+ -+ retval = phy_type_syscon_get(inst, child_np); -+ if (retval) -+ return retval; - } - - provider = devm_of_phy_provider_register(dev, mtk_phy_xlate); --- -2.51.0 - - -From 15a3afc987aa9c3756760898f296372abd94f71b Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Sat, 12 Oct 2024 16:38:23 +0200 -Subject: [PATCH 414/517] mmc: mtk-sd: add support for mt7988 - -Add support for mmc on MT7988 SoC. - -We can use mt7986 platform data in driver, but mt7988 needs different -clocks so for binding we need own compatible. - -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno -Message-ID: <20241012143826.7690-3-linux@fw-web.de> -Signed-off-by: Ulf Hansson ---- - drivers/mmc/host/mtk-sd.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c -index be9954f5bc0a..4a486eb77f3b 100644 ---- a/drivers/mmc/host/mtk-sd.c -+++ b/drivers/mmc/host/mtk-sd.c -@@ -631,6 +631,7 @@ static const struct of_device_id msdc_of_ids[] = { - { .compatible = "mediatek,mt7620-mmc", .data = &mt7620_compat}, - { .compatible = "mediatek,mt7622-mmc", .data = &mt7622_compat}, - { .compatible = "mediatek,mt7986-mmc", .data = &mt7986_compat}, -+ { .compatible = "mediatek,mt7988-mmc", .data = &mt7986_compat}, - { .compatible = "mediatek,mt8135-mmc", .data = &mt8135_compat}, - { .compatible = "mediatek,mt8173-mmc", .data = &mt8173_compat}, - { .compatible = "mediatek,mt8183-mmc", .data = &mt8183_compat}, --- -2.51.0 - - -From 1cd673167f75da5662cfd2762a35245b0799b743 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:38 +0100 -Subject: [PATCH 415/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/100-dts-update-mt7622-rfb1.patch - ---- - arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts | 44 +++++++++++++------- - 1 file changed, 29 insertions(+), 15 deletions(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts -index 8c3e2e2578bc..5280ca95e5c1 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts -@@ -1,7 +1,6 @@ - /* -- * Copyright (c) 2017 MediaTek Inc. -- * Author: Ming Huang -- * Sean Wang -+ * Copyright (c) 2018 MediaTek Inc. -+ * Author: Ryder Lee - * - * SPDX-License-Identifier: (GPL-2.0 OR MIT) - */ -@@ -24,7 +23,7 @@ aliases { - - chosen { - stdout-path = "serial0:115200n8"; -- bootargs = "earlycon=uart8250,mmio32,0x11002000 swiotlb=512"; -+ bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512"; - }; - - cpus { -@@ -45,18 +44,18 @@ gpio-keys { - key-factory { - label = "factory"; - linux,code = ; -- gpios = <&pio 0 0>; -+ gpios = <&pio 0 GPIO_ACTIVE_LOW>; - }; - - key-wps { - label = "wps"; - linux,code = ; -- gpios = <&pio 102 0>; -+ gpios = <&pio 102 GPIO_ACTIVE_LOW>; - }; - }; - - memory@40000000 { -- reg = <0 0x40000000 0 0x20000000>; -+ reg = <0 0x40000000 0 0x40000000>; - device_type = "memory"; - }; - -@@ -134,9 +133,9 @@ mdio-bus { - #address-cells = <1>; - #size-cells = <0>; - -- switch@0 { -+ switch@1f { - compatible = "mediatek,mt7531"; -- reg = <0>; -+ reg = <31>; - reset-gpios = <&pio 54 0>; - - ports { -@@ -145,22 +144,22 @@ ports { - - port@0 { - reg = <0>; -- label = "lan0"; -+ label = "lan1"; - }; - - port@1 { - reg = <1>; -- label = "lan1"; -+ label = "lan2"; - }; - - port@2 { - reg = <2>; -- label = "lan2"; -+ label = "lan3"; - }; - - port@3 { - reg = <3>; -- label = "lan3"; -+ label = "lan4"; - }; - - port@4 { -@@ -264,7 +263,22 @@ &pcie0 { - status = "okay"; - }; - -+&pcie1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie1_pins>; -+ status = "okay"; -+}; -+ - &pio { -+ /* Attention: GPIO 90 is used to switch between PCIe@1,0 and -+ * SATA functions. i.e. output-high: PCIe, output-low: SATA -+ */ -+ asm_sel { -+ gpio-hog; -+ gpios = <90 GPIO_ACTIVE_HIGH>; -+ output-high; -+ }; -+ - /* eMMC is shared pin with parallel NAND */ - emmc_pins_default: emmc-pins-default { - mux { -@@ -541,11 +555,11 @@ &pwrap { - }; - - &sata { -- status = "okay"; -+ status = "disabled"; - }; - - &sata_phy { -- status = "okay"; -+ status = "disabled"; - }; - - &spi0 { --- -2.51.0 - - -From 98902ead914a8b836afc3adb01d46eeeca1d9fd2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:39 +0100 -Subject: [PATCH 416/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/101-dts-update-mt7629-rfb.patch - ---- - arch/arm/boot/dts/mediatek/mt7629-rfb.dts | 27 ++++++++++++++++++++++- - 1 file changed, 26 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/mediatek/mt7629-rfb.dts b/arch/arm/boot/dts/mediatek/mt7629-rfb.dts -index f24ebc20732a..c1a306268730 100644 ---- a/arch/arm/boot/dts/mediatek/mt7629-rfb.dts -+++ b/arch/arm/boot/dts/mediatek/mt7629-rfb.dts -@@ -18,6 +18,7 @@ aliases { - - chosen { - stdout-path = "serial0:115200n8"; -+ bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n8"; - }; - - gpio-keys { -@@ -70,6 +71,10 @@ gmac0: mac@0 { - compatible = "mediatek,eth-mac"; - reg = <0>; - phy-mode = "2500base-x"; -+ -+ nvmem-cells = <&macaddr_factory_2a>; -+ nvmem-cell-names = "mac-address"; -+ - fixed-link { - speed = <2500>; - full-duplex; -@@ -82,6 +87,9 @@ gmac1: mac@1 { - reg = <1>; - phy-mode = "gmii"; - phy-handle = <&phy0>; -+ -+ nvmem-cells = <&macaddr_factory_24>; -+ nvmem-cell-names = "mac-address"; - }; - - mdio: mdio-bus { -@@ -133,8 +141,9 @@ factory: partition@70000 { - }; - - partition@b0000 { -- label = "kernel"; -+ label = "firmware"; - reg = <0xb0000 0xb50000>; -+ compatible = "denx,fit"; - }; - }; - }; -@@ -273,3 +282,19 @@ &watchdog { - pinctrl-0 = <&watchdog_pins>; - status = "okay"; - }; -+ -+&factory { -+ nvmem-layout { -+ compatible = "fixed-layout"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ macaddr_factory_24: macaddr@24 { -+ reg = <0x24 0x6>; -+ }; -+ -+ macaddr_factory_2a: macaddr@2a { -+ reg = <0x2a 0x6>; -+ }; -+ }; -+}; --- -2.51.0 - - -From 89b17d34e902fd03937449e3bac9fba792144827 Mon Sep 17 00:00:00 2001 -From: Chuanhong Guo -Date: Fri, 29 Apr 2022 10:40:56 +0800 -Subject: [PATCH 417/517] arm: mediatek: select arch timer for mt7623 - -Signed-off-by: Chuanhong Guo ---- - arch/arm/mach-mediatek/Kconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig -index 35a3430c7942..8a8d9142260a 100644 ---- a/arch/arm/mach-mediatek/Kconfig -+++ b/arch/arm/mach-mediatek/Kconfig -@@ -26,6 +26,7 @@ config MACH_MT6592 - config MACH_MT7623 - bool "MediaTek MT7623 SoCs support" - default ARCH_MEDIATEK -+ select HAVE_ARM_ARCH_TIMER - - config MACH_MT7629 - bool "MediaTek MT7629 SoCs support" --- -2.51.0 - - -From fe577f41bdfe2ec80ddc1a83bb3b71a6690dd2be Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:40 +0100 -Subject: [PATCH 418/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/104-mt7622-add-snor-irq.patch - ---- - arch/arm64/boot/dts/mediatek/mt7622.dtsi | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi -index 917fa39a74f8..bc40287b8f55 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi -@@ -575,6 +575,7 @@ nor_flash: spi@11014000 { - compatible = "mediatek,mt7622-nor", - "mediatek,mt8173-nor"; - reg = <0 0x11014000 0 0xe0>; -+ interrupts = ; - clocks = <&pericfg CLK_PERI_FLASH_PD>, - <&topckgen CLK_TOP_FLASH_SEL>; - clock-names = "spi", "sf"; --- -2.51.0 - - -From 6d49971735a5928b5a1b13714f6931bb70a4bfe9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:40 +0100 -Subject: [PATCH 419/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/105-dts-mt7622-enable-pstore.patch - ---- - arch/arm64/boot/dts/mediatek/mt7622.dtsi | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi -index bc40287b8f55..9aeca60effc0 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi -@@ -135,6 +135,13 @@ reserved-memory { - #size-cells = <2>; - ranges; - -+ /* 64 KiB reserved for ramoops/pstore */ -+ ramoops@42ff0000 { -+ compatible = "ramoops"; -+ reg = <0 0x42ff0000 0 0x10000>; -+ record-size = <0x1000>; -+ }; -+ - /* 192 KiB reserved for ARM Trusted Firmware (BL31) */ - secmon_reserved: secmon@43000000 { - reg = <0 0x43000000 0 0x30000>; --- -2.51.0 - - -From 840aa57c1c8487ed681cf4dcae1d3d710c0b2b2d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:41 +0100 -Subject: [PATCH 420/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/106-dts-mt7622-disable_btif.patch - ---- - arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts | 4 ---- - arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts | 4 ---- - 2 files changed, 8 deletions(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -index d12eac9b3eeb..e516e8357082 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -@@ -109,10 +109,6 @@ &bch { - status = "disabled"; - }; - --&btif { -- status = "okay"; --}; -- - &cir { - pinctrl-names = "default"; - pinctrl-0 = <&irrx_pins>; -diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts -index 5280ca95e5c1..06b708e8fd0e 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts -@@ -90,10 +90,6 @@ &bch { - status = "disabled"; - }; - --&btif { -- status = "okay"; --}; -- - &cir { - pinctrl-names = "default"; - pinctrl-0 = <&irrx_pins>; --- -2.51.0 - - -From 8240371de56292ac0183c36f963744c6f54df9fc Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:41 +0100 -Subject: [PATCH 421/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/110-dts-fix-bpi2-console.patch - ---- - arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts -index a37f3fa223c7..4275d1214f49 100644 ---- a/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts -+++ b/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts -@@ -19,6 +19,7 @@ aliases { - - chosen { - stdout-path = "serial2:115200n8"; -+ bootargs = "console=ttyS2,115200n8 console=tty1"; - }; - - connector { --- -2.51.0 - - -From 1afd404bb68fc69428d4e9a312a8a0a4dd49e6f6 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:41 +0100 -Subject: [PATCH 422/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/111-dts-fix-bpi64-console.patch - ---- - arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -index e516e8357082..6490fa754ddd 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -@@ -24,7 +24,7 @@ aliases { - - chosen { - stdout-path = "serial0:115200n8"; -- bootargs = "earlycon=uart8250,mmio32,0x11002000 swiotlb=512"; -+ bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512"; - }; - - cpus { --- -2.51.0 - - -From ddce26c256090622c46bad02c8b588a096d6c290 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:42 +0100 -Subject: [PATCH 423/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/112-dts-fix-bpi64-lan-names.patch - ---- - arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -index 6490fa754ddd..0bea189e91db 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -@@ -20,6 +20,7 @@ / { - - aliases { - serial0 = &uart0; -+ ethernet0 = &gmac0; - }; - - chosen { -@@ -164,22 +165,22 @@ port@0 { - - port@1 { - reg = <1>; -- label = "lan0"; -+ label = "lan1"; - }; - - port@2 { - reg = <2>; -- label = "lan1"; -+ label = "lan2"; - }; - - port@3 { - reg = <3>; -- label = "lan2"; -+ label = "lan3"; - }; - - port@4 { - reg = <4>; -- label = "lan3"; -+ label = "lan4"; - }; - - port@5 { --- -2.51.0 - - -From 2fa7e103e880630228e8349e155155ff63baceca Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:42 +0100 -Subject: [PATCH 424/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/113-dts-fix-bpi64-leds-and-buttons.patch - ---- - .../dts/mediatek/mt7622-bananapi-bpi-r64.dts | 20 ++++++++++++------- - 1 file changed, 13 insertions(+), 7 deletions(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -index 0bea189e91db..35b7f3b79d6b 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -@@ -21,6 +21,12 @@ / { - aliases { - serial0 = &uart0; - ethernet0 = &gmac0; -+ led-boot = &led_system_green; -+ led-failsafe = &led_system_blue; -+ led-running = &led_system_green; -+ led-upgrade = &led_system_blue; -+ mmc0 = &mmc0; -+ mmc1 = &mmc1; - }; - - chosen { -@@ -44,8 +50,8 @@ gpio-keys { - compatible = "gpio-keys"; - - factory-key { -- label = "factory"; -- linux,code = ; -+ label = "reset"; -+ linux,code = ; - gpios = <&pio 0 GPIO_ACTIVE_HIGH>; - }; - -@@ -59,17 +65,17 @@ wps-key { - leds { - compatible = "gpio-leds"; - -- led-0 { -+ led_system_green: led-0 { - label = "bpi-r64:pio:green"; - color = ; - gpios = <&pio 89 GPIO_ACTIVE_HIGH>; - default-state = "off"; - }; - -- led-1 { -- label = "bpi-r64:pio:red"; -- color = ; -- gpios = <&pio 88 GPIO_ACTIVE_HIGH>; -+ led_system_blue: led-1 { -+ label = "bpi-r64:pio:blue"; -+ color = ; -+ gpios = <&pio 85 GPIO_ACTIVE_HIGH>; - default-state = "off"; - }; - }; --- -2.51.0 - - -From ead9f5e3bff60916a5920349f44eb821f71468da Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:43 +0100 -Subject: [PATCH 425/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/114-dts-bpi64-disable-rtc.patch - ---- - arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -index 35b7f3b79d6b..77ecf5086c2c 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -@@ -599,6 +599,10 @@ &pwrap { - status = "okay"; - }; - -+&rtc { -+ status = "disabled"; -+}; -+ - &sata { - status = "disabled"; - }; --- -2.51.0 - - -From 1b51556c1ab773999e0472f79357ae4595364e61 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sat, 1 Feb 2025 04:24:17 +0000 -Subject: [PATCH 426/517] Revert "arm64: dts: mediatek: fix t-phy unit name" - -This reverts commit 963c3b0c47ec29b4c49c9f45965cd066f419d17f. ---- - arch/arm64/boot/dts/mediatek/mt7622.dtsi | 2 +- - arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi -index 9aeca60effc0..c1fb43eefc83 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi -@@ -908,7 +908,7 @@ sata: sata@1a200000 { - status = "disabled"; - }; - -- sata_phy: t-phy { -+ sata_phy: t-phy@1a243000 { - compatible = "mediatek,mt7622-tphy", - "mediatek,generic-tphy-v1"; - #address-cells = <2>; -diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi -index 559990dcd1d1..f9aaf3f20cd7 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi -@@ -428,7 +428,7 @@ pcie_intc: interrupt-controller { - }; - }; - -- pcie_phy: t-phy { -+ pcie_phy: t-phy@11c00000 { - compatible = "mediatek,mt7986-tphy", - "mediatek,generic-tphy-v2"; - ranges; --- -2.51.0 - - -From fb543ac462d31ffc4d6ed11dad784849cf06b7c4 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 28 Jun 2024 12:55:40 +0200 -Subject: [PATCH 427/517] arm64: dts: mediatek: mt7622: readd syscon to pciesys - node - -Sata node reference the pciesys with the property mediatek,phy-node -and that is used as a syscon to access the pciesys regs. - -Readd the syscon compatible to pciesys node to restore correct -functionality of the SATA interface. - -Fixes: 3ba5a6159434 ("arm64: dts: mediatek: mt7622: fix clock controllers") -Reported-by: Frank Wunderlich -Co-developed-by: Frank Wunderlich -Signed-off-by: Frank Wunderlich -Signed-off-by: Christian Marangi -Cc: stable@vger.kernel.org ---- - arch/arm64/boot/dts/mediatek/mt7622.dtsi | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi -index c1fb43eefc83..f2e526840582 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi -@@ -798,7 +798,7 @@ u2port1: usb-phy@1a0c5000 { - }; - - pciesys: clock-controller@1a100800 { -- compatible = "mediatek,mt7622-pciesys"; -+ compatible = "mediatek,mt7622-pciesys", "syscon"; - reg = <0 0x1a100800 0 0x1000>; - #clock-cells = <1>; - #reset-cells = <1>; --- -2.51.0 - - -From e5cb89538893dfe9c929bda92a429a768aff7b94 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Wed, 28 Dec 2022 23:44:42 +0000 -Subject: [PATCH 428/517] complete mt7981 dts - -working: - * Ethernet (fully working incl. ppe) - * UART - * SPI-NAND flash - * thermal sensors (SoC and mxl-gpy) - * random number generator via SMC - * USB 1.1, 2.0 and 3.0 - * WiFi with MT7976C 2.4G+5G DBDC incl. WED offloading - * PWM ---- - arch/arm64/boot/dts/mediatek/mt7981b.dtsi | 566 +++++++++++++++++++++- - 1 file changed, 554 insertions(+), 12 deletions(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi -index 5cbea9cd411f..6a816e5c1f46 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi -@@ -1,7 +1,14 @@ - // SPDX-License-Identifier: GPL-2.0-only OR MIT - - #include -+#include -+#include - #include -+#include -+#include -+#include -+#include -+#include - #include - - / { -@@ -41,6 +48,57 @@ psci { - method = "smc"; - }; - -+ fan: pwm-fan { -+ compatible = "pwm-fan"; -+ /* cooling level (0, 1, 2, 3) : (0% duty, 50% duty, 75% duty, 100% duty) */ -+ cooling-levels = <0 128 192 255>; -+ #cooling-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ reg_3p3v: regulator-3p3v { -+ compatible = "regulator-fixed"; -+ regulator-name = "fixed-3.3V"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ reserved-memory { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ ranges; -+ -+ /* 64 KiB reserved for ramoops/pstore */ -+ ramoops@42ff0000 { -+ compatible = "ramoops"; -+ reg = <0 0x42ff0000 0 0x10000>; -+ record-size = <0x1000>; -+ }; -+ -+ /* 192 KiB reserved for ARM Trusted Firmware (BL31) */ -+ secmon_reserved: secmon@43000000 { -+ reg = <0 0x43000000 0 0x30000>; -+ no-map; -+ }; -+ -+ wmcpu_emi: wmcpu-reserved@47c80000 { -+ reg = <0 0x47c80000 0 0x100000>; -+ no-map; -+ }; -+ -+ wo_emi0: wo-emi@47d80000 { -+ reg = <0 0x47d80000 0 0x40000>; -+ no-map; -+ }; -+ -+ wo_data: wo-data@47dc0000 { -+ reg = <0 0x47dc0000 0 0x240000>; -+ no-map; -+ }; -+ }; -+ - soc { - compatible = "simple-bus"; - ranges; -@@ -76,13 +134,13 @@ watchdog: watchdog@1001c000 { - #reset-cells = <1>; - }; - -- clock-controller@1001e000 { -- compatible = "mediatek,mt7981-apmixedsys"; -+ apmixedsys: clock-controller@1001e000 { -+ compatible = "mediatek,mt7981-apmixedsys", "syscon"; - reg = <0 0x1001e000 0 0x1000>; - #clock-cells = <1>; - }; - -- pwm@10048000 { -+ pwm: pwm@10048000 { - compatible = "mediatek,mt7981-pwm"; - reg = <0 0x10048000 0 0x1000>; - clocks = <&infracfg CLK_INFRA_PWM_STA>, -@@ -94,7 +152,21 @@ pwm@10048000 { - #pwm-cells = <2>; - }; - -- serial@11002000 { -+ crypto: crypto@10320000 { -+ compatible = "inside-secure,safexcel-eip97"; -+ reg = <0 0x10320000 0 0x40000>; -+ interrupts = , -+ , -+ , -+ ; -+ interrupt-names = "ring0", "ring1", "ring2", "ring3"; -+ clocks = <&topckgen CLK_TOP_EIP97B>; -+ clock-names = "top_eip97_ck"; -+ assigned-clocks = <&topckgen CLK_TOP_EIP97B_SEL>; -+ assigned-clock-parents = <&topckgen CLK_TOP_CB_NET1_D5>; -+ }; -+ -+ uart0: serial@11002000 { - compatible = "mediatek,mt7981-uart", "mediatek,mt6577-uart"; - reg = <0 0x11002000 0 0x100>; - interrupts = ; -@@ -105,7 +177,7 @@ serial@11002000 { - status = "disabled"; - }; - -- serial@11003000 { -+ uart1: serial@11003000 { - compatible = "mediatek,mt7981-uart", "mediatek,mt6577-uart"; - reg = <0 0x11003000 0 0x100>; - interrupts = ; -@@ -116,7 +188,7 @@ serial@11003000 { - status = "disabled"; - }; - -- serial@11004000 { -+ uart2: serial@11004000 { - compatible = "mediatek,mt7981-uart", "mediatek,mt6577-uart"; - reg = <0 0x11004000 0 0x100>; - interrupts = ; -@@ -127,11 +199,12 @@ serial@11004000 { - status = "disabled"; - }; - -- i2c@11007000 { -+ i2c0: i2c@11007000 { - compatible = "mediatek,mt7981-i2c"; - reg = <0 0x11007000 0 0x1000>, - <0 0x10217080 0 0x80>; - interrupts = ; -+ clock-div = <1>; - clocks = <&infracfg CLK_INFRA_I2C0_CK>, - <&infracfg CLK_INFRA_AP_DMA_CK>, - <&infracfg CLK_INFRA_I2C_MCK_CK>, -@@ -142,7 +215,32 @@ i2c@11007000 { - status = "disabled"; - }; - -- spi@11009000 { -+ thermal: thermal@1100c800 { -+ #thermal-sensor-cells = <1>; -+ compatible = "mediatek,mt7981-thermal", "mediatek,mt7986-thermal"; -+ reg = <0 0x1100c800 0 0x800>; -+ interrupts = ; -+ clocks = <&infracfg CLK_INFRA_THERM_CK>, -+ <&infracfg CLK_INFRA_ADC_26M_CK>; -+ clock-names = "therm", "auxadc"; -+ mediatek,auxadc = <&auxadc>; -+ mediatek,apmixedsys = <&apmixedsys>; -+ nvmem-cells = <&thermal_calibration>; -+ nvmem-cell-names = "calibration-data"; -+ }; -+ -+ auxadc: adc@1100d000 { -+ compatible = "mediatek,mt7981-auxadc", -+ "mediatek,mt7986-auxadc", -+ "mediatek,mt7622-auxadc"; -+ reg = <0 0x1100d000 0 0x1000>; -+ clocks = <&infracfg CLK_INFRA_ADC_26M_CK>, -+ <&infracfg CLK_INFRA_ADC_FRC_CK>; -+ clock-names = "main", "32k"; -+ #io-channel-cells = <1>; -+ }; -+ -+ spi2: spi@11009000 { - compatible = "mediatek,mt7981-spi-ipm", "mediatek,spi-ipm"; - reg = <0 0x11009000 0 0x1000>; - interrupts = ; -@@ -156,7 +254,7 @@ spi@11009000 { - status = "disabled"; - }; - -- spi@1100a000 { -+ spi0: spi@1100a000 { - compatible = "mediatek,mt7981-spi-ipm", "mediatek,spi-ipm"; - reg = <0 0x1100a000 0 0x1000>; - interrupts = ; -@@ -170,7 +268,7 @@ spi@1100a000 { - status = "disabled"; - }; - -- spi@1100b000 { -+ spi1: spi@1100b000 { - compatible = "mediatek,mt7981-spi-ipm", "mediatek,spi-ipm"; - reg = <0 0x1100b000 0 0x1000>; - interrupts = ; -@@ -184,6 +282,41 @@ spi@1100b000 { - status = "disabled"; - }; - -+ pcie: pcie@11280000 { -+ compatible = "mediatek,mt7981-pcie", -+ "mediatek,mt8192-pcie"; -+ device_type = "pci"; -+ reg = <0 0x11280000 0 0x4000>; -+ reg-names = "pcie-mac"; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ interrupts = ; -+ bus-range = <0x00 0xff>; -+ ranges = <0x82000000 0 0x20000000 -+ 0x0 0x20000000 0 0x10000000>; -+ status = "disabled"; -+ -+ clocks = <&infracfg CLK_INFRA_IPCIE_CK>, -+ <&infracfg CLK_INFRA_IPCIE_PIPE_CK>, -+ <&infracfg CLK_INFRA_IPCIER_CK>, -+ <&infracfg CLK_INFRA_IPCIEB_CK>; -+ -+ phys = <&u3port0 PHY_TYPE_PCIE>; -+ phy-names = "pcie-phy"; -+ -+ #interrupt-cells = <1>; -+ interrupt-map-mask = <0 0 0 7>; -+ interrupt-map = <0 0 0 1 &pcie_intc 0>, -+ <0 0 0 2 &pcie_intc 1>, -+ <0 0 0 3 &pcie_intc 2>, -+ <0 0 0 4 &pcie_intc 3>; -+ pcie_intc: interrupt-controller { -+ interrupt-controller; -+ #address-cells = <0>; -+ #interrupt-cells = <1>; -+ }; -+ }; -+ - pio: pinctrl@11d00000 { - compatible = "mediatek,mt7981-pinctrl"; - reg = <0 0x11d00000 0 0x1000>, -@@ -204,6 +337,49 @@ pio: pinctrl@11d00000 { - gpio-controller; - #gpio-cells = <2>; - #interrupt-cells = <2>; -+ -+ mdio_pins: mdc-mdio-pins { -+ mux { -+ function = "eth"; -+ groups = "smi_mdc_mdio"; -+ }; -+ }; -+ -+ uart0_pins: uart0-pins { -+ mux { -+ function = "uart"; -+ groups = "uart0"; -+ }; -+ }; -+ -+ wifi_dbdc_pins: wifi-dbdc-pins { -+ mux { -+ function = "eth"; -+ groups = "wf0_mode1"; -+ }; -+ conf { -+ pins = "WF_HB1", "WF_HB2", "WF_HB3", "WF_HB4", -+ "WF_HB0", "WF_HB0_B", "WF_HB5", "WF_HB6", -+ "WF_HB7", "WF_HB8", "WF_HB9", "WF_HB10", -+ "WF_TOP_CLK", "WF_TOP_DATA", "WF_XO_REQ", -+ "WF_CBA_RESETB", "WF_DIG_RESETB"; -+ drive-strength = ; -+ }; -+ }; -+ -+ gbe_led0_pins: gbe-led0-pins { -+ mux { -+ function = "led"; -+ groups = "gbe_led0"; -+ }; -+ }; -+ -+ gbe_led1_pins: gbe-led1-pins { -+ mux { -+ function = "led"; -+ groups = "gbe_led1"; -+ }; -+ }; - }; - - efuse@11f20000 { -@@ -211,17 +387,318 @@ efuse@11f20000 { - reg = <0 0x11f20000 0 0x1000>; - #address-cells = <1>; - #size-cells = <1>; -+ -+ thermal_calibration: thermal-calib@274 { -+ reg = <0x274 0xc>; -+ }; -+ -+ phy_calibration: phy-calib@8dc { -+ reg = <0x8dc 0x10>; -+ }; -+ -+ comb_rx_imp_p0: usb3-rx-imp@8c8 { -+ reg = <0x8c8 1>; -+ bits = <0 5>; -+ }; -+ -+ comb_tx_imp_p0: usb3-tx-imp@8c8 { -+ reg = <0x8c8 2>; -+ bits = <5 5>; -+ }; -+ -+ comb_intr_p0: usb3-intr@8c9 { -+ reg = <0x8c9 1>; -+ bits = <2 6>; -+ }; - }; - -- clock-controller@15000000 { -+ ethsys: clock-controller@15000000 { - compatible = "mediatek,mt7981-ethsys", "syscon"; - reg = <0 0x15000000 0 0x1000>; - #clock-cells = <1>; - #reset-cells = <1>; - }; - -- wifi@18000000 { -+ wed: wed@15010000 { -+ compatible = "mediatek,mt7981-wed", -+ "mediatek,mt7986-wed", -+ "syscon"; -+ reg = <0 0x15010000 0 0x1000>; -+ interrupt-parent = <&gic>; -+ interrupts = ; -+ memory-region = <&wo_emi0>, <&wo_data>; -+ memory-region-names = "wo-emi", "wo-data"; -+ mediatek,wo-ccif = <&wo_ccif0>; -+ mediatek,wo-ilm = <&wo_ilm0>; -+ mediatek,wo-dlm = <&wo_dlm0>; -+ mediatek,wo-cpuboot = <&wo_cpuboot>; -+ }; -+ -+ eth: ethernet@15100000 { -+ compatible = "mediatek,mt7981-eth"; -+ reg = <0 0x15100000 0 0x80000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ interrupts = , -+ , -+ , -+ ; -+ clocks = <ðsys CLK_ETH_FE_EN>, -+ <ðsys CLK_ETH_GP2_EN>, -+ <ðsys CLK_ETH_GP1_EN>, -+ <ðsys CLK_ETH_WOCPU0_EN>, -+ <&sgmiisys0 CLK_SGM0_TX_EN>, -+ <&sgmiisys0 CLK_SGM0_RX_EN>, -+ <&sgmiisys0 CLK_SGM0_CK0_EN>, -+ <&sgmiisys0 CLK_SGM0_CDR_CK0_EN>, -+ <&sgmiisys1 CLK_SGM1_TX_EN>, -+ <&sgmiisys1 CLK_SGM1_RX_EN>, -+ <&sgmiisys1 CLK_SGM1_CK1_EN>, -+ <&sgmiisys1 CLK_SGM1_CDR_CK1_EN>, -+ <&topckgen CLK_TOP_SGM_REG>, -+ <&topckgen CLK_TOP_NETSYS_SEL>, -+ <&topckgen CLK_TOP_NETSYS_500M_SEL>; -+ clock-names = "fe", "gp2", "gp1", "wocpu0", -+ "sgmii_tx250m", "sgmii_rx250m", -+ "sgmii_cdr_ref", "sgmii_cdr_fb", -+ "sgmii2_tx250m", "sgmii2_rx250m", -+ "sgmii2_cdr_ref", "sgmii2_cdr_fb", -+ "sgmii_ck", "netsys0", "netsys1"; -+ assigned-clocks = <&topckgen CLK_TOP_NETSYS_2X_SEL>, -+ <&topckgen CLK_TOP_SGM_325M_SEL>; -+ assigned-clock-parents = <&topckgen CLK_TOP_CB_NET2_800M>, -+ <&topckgen CLK_TOP_CB_SGM_325M>; -+ mediatek,ethsys = <ðsys>; -+ mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>; -+ mediatek,infracfg = <&topmisc>; -+ mediatek,wed = <&wed>; -+ status = "disabled"; -+ -+ mdio_bus: mdio-bus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ int_gbe_phy: ethernet-phy@0 { -+ reg = <0>; -+ compatible = "ethernet-phy-ieee802.3-c22"; -+ phy-mode = "gmii"; -+ phy-is-integrated; -+ nvmem-cells = <&phy_calibration>; -+ nvmem-cell-names = "phy-cal-data"; -+ -+ leds { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ int_gbe_phy_led0: int-gbe-phy-led0@0 { -+ reg = <0>; -+ function = LED_FUNCTION_LAN; -+ pinctrl-0 = <&gbe_led0_pins>; -+ pinctrl-names = "default"; -+ status = "disabled"; -+ }; -+ -+ int_gbe_phy_led1: int-gbe-phy-led1@1 { -+ reg = <1>; -+ function = LED_FUNCTION_LAN; -+ pinctrl-0 = <&gbe_led1_pins>; -+ pinctrl-names = "default"; -+ status = "disabled"; -+ }; -+ }; -+ }; -+ }; -+ }; -+ -+ wdma: wdma@15104800 { -+ compatible = "mediatek,wed-wdma"; -+ reg = <0 0x15104800 0 0x400>, -+ <0 0x15104c00 0 0x400>; -+ }; -+ -+ ap2woccif: ap2woccif@151a5000 { -+ compatible = "mediatek,ap2woccif"; -+ reg = <0 0x151a5000 0 0x1000>, -+ <0 0x151ad000 0 0x1000>; -+ interrupt-parent = <&gic>; -+ interrupts = , -+ ; -+ }; -+ -+ wo_dlm0: syscon@151e8000 { -+ compatible = "mediatek,mt7986-wo-dlm", "syscon"; -+ reg = <0 0x151e8000 0 0x2000>; -+ }; -+ -+ wo_ilm0: syscon@151e0000 { -+ compatible = "mediatek,mt7986-wo-ilm", "syscon"; -+ reg = <0 0x151e0000 0 0x8000>; -+ }; -+ -+ wo_cpuboot: syscon@15194000 { -+ compatible = "mediatek,mt7986-wo-cpuboot", "syscon"; -+ reg = <0 0x15194000 0 0x1000>; -+ }; -+ -+ wo_ccif0: syscon@151a5000 { -+ compatible = "mediatek,mt7986-wo-ccif", "syscon"; -+ reg = <0 0x151a5000 0 0x1000>; -+ interrupt-parent = <&gic>; -+ interrupts = ; -+ }; -+ -+ sgmiisys0: syscon@10060000 { -+ compatible = "mediatek,mt7981-sgmiisys_0", "mediatek,mt7986-sgmiisys_0", "syscon"; -+ reg = <0 0x10060000 0 0x1000>; -+ mediatek,pnswap; -+ #clock-cells = <1>; -+ }; -+ -+ sgmiisys1: syscon@10070000 { -+ compatible = "mediatek,mt7981-sgmiisys_1", "mediatek,mt7986-sgmiisys_1", "syscon"; -+ reg = <0 0x10070000 0 0x1000>; -+ #clock-cells = <1>; -+ }; -+ -+ topmisc: topmisc@11d10000 { -+ compatible = "mediatek,mt7981-topmisc", "syscon"; -+ reg = <0 0x11d10000 0 0x10000>; -+ #clock-cells = <1>; -+ }; -+ -+ snand: snfi@11005000 { -+ compatible = "mediatek,mt7986-snand"; -+ reg = <0 0x11005000 0 0x1000>, <0 0x11006000 0 0x1000>; -+ reg-names = "nfi", "ecc"; -+ interrupts = ; -+ clocks = <&infracfg CLK_INFRA_SPINFI1_CK>, -+ <&infracfg CLK_INFRA_NFI1_CK>, -+ <&infracfg CLK_INFRA_NFI_HCK_CK>; -+ clock-names = "pad_clk", "nfi_clk", "nfi_hclk"; -+ assigned-clocks = <&topckgen CLK_TOP_SPINFI_SEL>, -+ <&topckgen CLK_TOP_NFI1X_SEL>; -+ assigned-clock-parents = <&topckgen CLK_TOP_CB_M_D8>, -+ <&topckgen CLK_TOP_CB_M_D8>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ mmc0: mmc@11230000 { -+ compatible = "mediatek,mt7986-mmc", -+ "mediatek,mt7981-mmc"; -+ reg = <0 0x11230000 0 0x1000>, <0 0x11c20000 0 0x1000>; -+ interrupts = ; -+ clocks = <&infracfg CLK_INFRA_MSDC_CK>, -+ <&infracfg CLK_INFRA_MSDC_HCK_CK>, -+ <&infracfg CLK_INFRA_MSDC_66M_CK>, -+ <&infracfg CLK_INFRA_MSDC_133M_CK>; -+ assigned-clocks = <&topckgen CLK_TOP_EMMC_208M_SEL>, -+ <&topckgen CLK_TOP_EMMC_400M_SEL>; -+ assigned-clock-parents = <&topckgen CLK_TOP_CB_M_D2>, -+ <&topckgen CLK_TOP_CB_NET2_D2>; -+ clock-names = "source", "hclk", "axi_cg", "ahb_cg"; -+ status = "disabled"; -+ }; -+ -+ wed_pcie: wed_pcie@10003000 { -+ compatible = "mediatek,wed_pcie"; -+ reg = <0 0x10003000 0 0x10>; -+ }; -+ -+ consys: consys@10000000 { -+ compatible = "mediatek,mt7981-consys"; -+ reg = <0 0x10000000 0 0x8600000>; -+ memory-region = <&wmcpu_emi>; -+ }; -+ -+ xhci: usb@11200000 { -+ compatible = "mediatek,mt7986-xhci", -+ "mediatek,mtk-xhci"; -+ reg = <0 0x11200000 0 0x2e00>, -+ <0 0x11203e00 0 0x0100>; -+ reg-names = "mac", "ippc"; -+ interrupts = ; -+ clocks = <&infracfg CLK_INFRA_IUSB_SYS_CK>, -+ <&infracfg CLK_INFRA_IUSB_CK>, -+ <&infracfg CLK_INFRA_IUSB_133_CK>, -+ <&infracfg CLK_INFRA_IUSB_66M_CK>, -+ <&topckgen CLK_TOP_U2U3_XHCI_SEL>; -+ clock-names = "sys_ck", -+ "ref_ck", -+ "mcu_ck", -+ "dma_ck", -+ "xhci_ck"; -+ phys = <&u2port0 PHY_TYPE_USB2>, -+ <&u3port0 PHY_TYPE_USB3>; -+ vusb33-supply = <®_3p3v>; -+ status = "disabled"; -+ }; -+ -+ usb_phy: usb-phy@11e10000 { -+ compatible = "mediatek,mt7981", -+ "mediatek,generic-tphy-v2"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0 0 0x11e10000 0x1700>; -+ status = "disabled"; -+ -+ u2port0: usb-phy@0 { -+ reg = <0x0 0x700>; -+ clocks = <&topckgen CLK_TOP_USB_FRMCNT_SEL>; -+ clock-names = "ref"; -+ #phy-cells = <1>; -+ }; -+ -+ u3port0: usb-phy@700 { -+ reg = <0x700 0x900>; -+ clocks = <&topckgen CLK_TOP_USB3_PHY_SEL>; -+ clock-names = "ref"; -+ #phy-cells = <1>; -+ mediatek,syscon-type = <&topmisc 0x218 0>; -+ status = "okay"; -+ }; -+ }; -+ -+ -+ afe: audio-controller@11210000 { -+ compatible = "mediatek,mt79xx-audio"; -+ reg = <0 0x11210000 0 0x9000>; -+ interrupts = ; -+ clocks = <&infracfg CLK_INFRA_AUD_BUS_CK>, -+ <&infracfg CLK_INFRA_AUD_26M_CK>, -+ <&infracfg CLK_INFRA_AUD_L_CK>, -+ <&infracfg CLK_INFRA_AUD_AUD_CK>, -+ <&infracfg CLK_INFRA_AUD_EG2_CK>, -+ <&topckgen CLK_TOP_AUD_SEL>; -+ clock-names = "aud_bus_ck", -+ "aud_26m_ck", -+ "aud_l_ck", -+ "aud_aud_ck", -+ "aud_eg2_ck", -+ "aud_sel"; -+ assigned-clocks = <&topckgen CLK_TOP_AUD_SEL>, -+ <&topckgen CLK_TOP_A1SYS_SEL>, -+ <&topckgen CLK_TOP_AUD_L_SEL>, -+ <&topckgen CLK_TOP_A_TUNER_SEL>; -+ assigned-clock-parents = <&topckgen CLK_TOP_CB_APLL2_196M>, -+ <&topckgen CLK_TOP_APLL2_D4>, -+ <&topckgen CLK_TOP_CB_APLL2_196M>, -+ <&topckgen CLK_TOP_APLL2_D4>; -+ status = "disabled"; -+ }; -+ -+ ice: ice_debug { -+ compatible = "mediatek,mt7981-ice_debug", -+ "mediatek,mt2701-ice_debug"; -+ clocks = <&infracfg CLK_INFRA_DBG_CK>; -+ clock-names = "ice_dbg"; -+ }; -+ -+ wifi: wifi@18000000 { - compatible = "mediatek,mt7981-wmac"; -+ pinctrl-0 = <&wifi_dbdc_pins>; -+ pinctrl-names = "dbdc"; - reg = <0 0x18000000 0 0x1000000>, - <0 0x10003000 0 0x1000>, - <0 0x11d10000 0 0x1000>; -@@ -234,6 +711,67 @@ wifi@18000000 { - clock-names = "mcu", "ap2conn"; - resets = <&watchdog MT7986_TOPRGU_CONSYS_SW_RST>; - reset-names = "consys"; -+ memory-region = <&wmcpu_emi>; -+ status = "disabled"; -+ }; -+ }; -+ -+ thermal-zones { -+ cpu_thermal: cpu-thermal { -+ polling-delay-passive = <1000>; -+ polling-delay = <1000>; -+ thermal-sensors = <&thermal 0>; -+ trips { -+ cpu_trip_crit: crit { -+ temperature = <125000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ -+ cpu_trip_hot: hot { -+ temperature = <120000>; -+ hysteresis = <2000>; -+ type = "hot"; -+ }; -+ -+ cpu_trip_active_high: active-high { -+ temperature = <115000>; -+ hysteresis = <2000>; -+ type = "active"; -+ }; -+ -+ cpu_trip_active_med: active-med { -+ temperature = <85000>; -+ hysteresis = <2000>; -+ type = "active"; -+ }; -+ -+ cpu_trip_active_low: active-low { -+ temperature = <60000>; -+ hysteresis = <2000>; -+ type = "active"; -+ }; -+ }; -+ -+ cooling-maps { -+ cpu-active-high { -+ /* active: set fan to cooling level 3 */ -+ cooling-device = <&fan 3 3>; -+ trip = <&cpu_trip_active_high>; -+ }; -+ -+ cpu-active-med { -+ /* active: set fan to cooling level 2 */ -+ cooling-device = <&fan 2 2>; -+ trip = <&cpu_trip_active_med>; -+ }; -+ -+ cpu-active-low { -+ /* passive: set fan to cooling level 1 */ -+ cooling-device = <&fan 1 1>; -+ trip = <&cpu_trip_active_low>; -+ }; -+ }; - }; - }; - -@@ -245,4 +783,8 @@ timer { - , - ; - }; -+ -+ trng { -+ compatible = "mediatek,mt7981-rng"; -+ }; - }; --- -2.51.0 - - -From 7d19b9de2f9cfb1e02cd61673bfe0a1f8b8453e6 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:44 +0100 -Subject: [PATCH 429/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/121-hack-spi-nand-1b-bbm.patch - ---- - drivers/mtd/nand/spi/core.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c -index 8e56ca65ac4f..8a3c9db90c6f 100644 ---- a/drivers/mtd/nand/spi/core.c -+++ b/drivers/mtd/nand/spi/core.c -@@ -913,7 +913,7 @@ static int spinand_mtd_write(struct mtd_info *mtd, loff_t to, - static bool spinand_isbad(struct nand_device *nand, const struct nand_pos *pos) - { - struct spinand_device *spinand = nand_to_spinand(nand); -- u8 marker[2] = { }; -+ u8 marker[1] = { }; - struct nand_page_io_req req = { - .pos = *pos, - .ooblen = sizeof(marker), -@@ -924,7 +924,7 @@ static bool spinand_isbad(struct nand_device *nand, const struct nand_pos *pos) - - spinand_select_target(spinand, pos->target); - spinand_read_page(spinand, &req); -- if (marker[0] != 0xff || marker[1] != 0xff) -+ if (marker[0] != 0xff) - return true; - - return false; --- -2.51.0 - - -From f657099ea98f26165a6c283903770c12936addc6 Mon Sep 17 00:00:00 2001 -From: Xiangsheng Hou -Date: Thu, 6 Jun 2019 16:29:04 +0800 -Subject: [PATCH 430/517] spi: spi-mem: Mediatek: Add SPI Nand support for - MT7629 - -Signed-off-by: Xiangsheng Hou ---- - arch/arm/boot/dts/mediatek/mt7629-rfb.dts | 44 +++++++++++++++++++++++ - arch/arm/boot/dts/mediatek/mt7629.dtsi | 21 +++++++++++ - 2 files changed, 65 insertions(+) - -diff --git a/arch/arm/boot/dts/mediatek/mt7629-rfb.dts b/arch/arm/boot/dts/mediatek/mt7629-rfb.dts -index c1a306268730..b999fae80fed 100644 ---- a/arch/arm/boot/dts/mediatek/mt7629-rfb.dts -+++ b/arch/arm/boot/dts/mediatek/mt7629-rfb.dts -@@ -255,6 +255,50 @@ mux { - }; - }; - -+&bch { -+ status = "okay"; -+}; -+ -+&snfi { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&serial_nand_pins>; -+ status = "okay"; -+ flash@0 { -+ compatible = "spi-nand"; -+ reg = <0>; -+ spi-tx-bus-width = <4>; -+ spi-rx-bus-width = <4>; -+ nand-ecc-engine = <&snfi>; -+ -+ partitions { -+ compatible = "fixed-partitions"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ partition@0 { -+ label = "Bootloader"; -+ reg = <0x00000 0x0100000>; -+ read-only; -+ }; -+ -+ partition@100000 { -+ label = "Config"; -+ reg = <0x100000 0x0040000>; -+ }; -+ -+ partition@140000 { -+ label = "factory"; -+ reg = <0x140000 0x0080000>; -+ }; -+ -+ partition@1c0000 { -+ label = "firmware"; -+ reg = <0x1c0000 0x1000000>; -+ }; -+ }; -+ }; -+}; -+ - &spi { - pinctrl-names = "default"; - pinctrl-0 = <&spi_pins>; -diff --git a/arch/arm/boot/dts/mediatek/mt7629.dtsi b/arch/arm/boot/dts/mediatek/mt7629.dtsi -index acab0883a3bb..cdbe85d8b030 100644 ---- a/arch/arm/boot/dts/mediatek/mt7629.dtsi -+++ b/arch/arm/boot/dts/mediatek/mt7629.dtsi -@@ -271,6 +271,27 @@ i2c: i2c@11007000 { - status = "disabled"; - }; - -+ snfi: spi@1100d000 { -+ compatible = "mediatek,mt7629-snand"; -+ reg = <0x1100d000 0x1000>; -+ interrupts = ; -+ clocks = <&pericfg CLK_PERI_NFI_PD>, <&pericfg CLK_PERI_SNFI_PD>; -+ clock-names = "nfi_clk", "pad_clk"; -+ nand-ecc-engine = <&bch>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ bch: ecc@1100e000 { -+ compatible = "mediatek,mt7622-ecc"; -+ reg = <0x1100e000 0x1000>; -+ interrupts = ; -+ clocks = <&pericfg CLK_PERI_NFIECC_PD>; -+ clock-names = "nfiecc_clk"; -+ status = "disabled"; -+ }; -+ - spi: spi@1100a000 { - compatible = "mediatek,mt7629-spi", - "mediatek,mt7622-spi"; --- -2.51.0 - - -From cac818b46d4cc0b9162576bf3e338ac2bdca1d9b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:44 +0100 -Subject: [PATCH 431/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/131-dts-mt7622-add-snand-support.patch - ---- - arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts | 59 ++++++++++++++++++++ - 1 file changed, 59 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts -index 06b708e8fd0e..e64201b79292 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts -@@ -558,6 +558,65 @@ &sata_phy { - status = "disabled"; - }; - -+&bch { -+ status = "okay"; -+}; -+ -+&snfi { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&serial_nand_pins>; -+ status = "okay"; -+ flash@0 { -+ compatible = "spi-nand"; -+ reg = <0>; -+ spi-tx-bus-width = <4>; -+ spi-rx-bus-width = <4>; -+ nand-ecc-engine = <&snfi>; -+ -+ partitions { -+ compatible = "fixed-partitions"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ partition@0 { -+ label = "Preloader"; -+ reg = <0x00000 0x0080000>; -+ read-only; -+ }; -+ -+ partition@80000 { -+ label = "ATF"; -+ reg = <0x80000 0x0040000>; -+ }; -+ -+ partition@c0000 { -+ label = "Bootloader"; -+ reg = <0xc0000 0x0080000>; -+ }; -+ -+ partition@140000 { -+ label = "Config"; -+ reg = <0x140000 0x0080000>; -+ }; -+ -+ partition@1c0000 { -+ label = "Factory"; -+ reg = <0x1c0000 0x0100000>; -+ }; -+ -+ partition@200000 { -+ label = "firmware"; -+ reg = <0x2c0000 0x2000000>; -+ }; -+ -+ partition@2200000 { -+ label = "User_data"; -+ reg = <0x22c0000 0x4000000>; -+ }; -+ }; -+ }; -+}; -+ - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spic0_pins>; --- -2.51.0 - - -From 01d5c5c6ba4d56b1908d51aa9327727440bdb0ef Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:45 +0100 -Subject: [PATCH 432/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/140-dts-fix-wmac-support-for-mt7622-rfb1.patch - ---- - arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts -index e64201b79292..a478bab2e8cf 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts -@@ -599,7 +599,7 @@ partition@140000 { - reg = <0x140000 0x0080000>; - }; - -- partition@1c0000 { -+ factory: partition@1c0000 { - label = "Factory"; - reg = <0x1c0000 0x0100000>; - }; -@@ -660,5 +660,6 @@ &watchdog { - &wmac { - pinctrl-names = "default"; - pinctrl-0 = <&wmac_pins>; -+ mediatek,mtd-eeprom = <&factory 0x0000>; - status = "okay"; - }; --- -2.51.0 - - -From 1669509614ddf5ffb64bde85f4bcaafeefb65f64 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:45 +0100 -Subject: [PATCH 433/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/150-dts-mt7623-eip97-inside-secure-support.patch - ---- - arch/arm/boot/dts/mediatek/mt7623.dtsi | 10 ++++------ - 1 file changed, 4 insertions(+), 6 deletions(-) - -diff --git a/arch/arm/boot/dts/mediatek/mt7623.dtsi b/arch/arm/boot/dts/mediatek/mt7623.dtsi -index fd7a89cc337d..c6b7d1713096 100644 ---- a/arch/arm/boot/dts/mediatek/mt7623.dtsi -+++ b/arch/arm/boot/dts/mediatek/mt7623.dtsi -@@ -995,17 +995,15 @@ gmac1: mac@1 { - }; - - crypto: crypto@1b240000 { -- compatible = "mediatek,eip97-crypto"; -+ compatible = "inside-secure,safexcel-eip97"; - reg = <0 0x1b240000 0 0x20000>; - interrupts = , - , - , -- , -- ; -+ ; -+ interrupt-names = "ring0", "ring1", "ring2", "ring3"; - clocks = <ðsys CLK_ETHSYS_CRYPTO>; -- clock-names = "cryp"; -- power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>; -- status = "disabled"; -+ status = "okay"; - }; - - bdpsys: syscon@1c000000 { --- -2.51.0 - - -From 260ac5379c33a9757834519325577441a7b062cf Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:46 +0100 -Subject: [PATCH 434/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/160-dts-mt7623-bpi-r2-earlycon.patch - ---- - arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts -index 4275d1214f49..f68e99ca7027 100644 ---- a/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts -+++ b/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts -@@ -19,7 +19,7 @@ aliases { - - chosen { - stdout-path = "serial2:115200n8"; -- bootargs = "console=ttyS2,115200n8 console=tty1"; -+ bootargs = "earlycon=uart8250,mmio32,0x11004000 console=ttyS2,115200n8 console=tty1"; - }; - - connector { --- -2.51.0 - - -From 5303571fd150e453bf13f523f4fc32bc946807e6 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:46 +0100 -Subject: [PATCH 435/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/161-dts-mt7623-bpi-r2-mmc-device-order.patch - ---- - arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts -index f68e99ca7027..fdec3d8170e6 100644 ---- a/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts -+++ b/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts -@@ -15,6 +15,8 @@ / { - - aliases { - serial2 = &uart2; -+ mmc0 = &mmc0; -+ mmc1 = &mmc1; - }; - - chosen { --- -2.51.0 - - -From 2e82a39d56d22f1dc86a594687ebdb74b18910ee Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:47 +0100 -Subject: [PATCH 436/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/162-dts-mt7623-bpi-r2-led-aliases.patch - ---- - arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts -index fdec3d8170e6..d980f068bde9 100644 ---- a/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts -+++ b/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts -@@ -17,6 +17,10 @@ aliases { - serial2 = &uart2; - mmc0 = &mmc0; - mmc1 = &mmc1; -+ led-boot = &led_system_green; -+ led-failsafe = &led_system_blue; -+ led-running = &led_system_green; -+ led-upgrade = &led_system_blue; - }; - - chosen { -@@ -112,13 +116,13 @@ leds { - pinctrl-names = "default"; - pinctrl-0 = <&led_pins_a>; - -- blue { -+ led_system_blue: blue { - label = "bpi-r2:pio:blue"; - gpios = <&pio 240 GPIO_ACTIVE_LOW>; - default-state = "off"; - }; - -- green { -+ led_system_green: green { - label = "bpi-r2:pio:green"; - gpios = <&pio 241 GPIO_ACTIVE_LOW>; - default-state = "off"; --- -2.51.0 - - -From c0a89fcb4019825cf792107ebf3295f058f3d0df Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:47 +0100 -Subject: [PATCH 437/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/163-dts-mt7623-bpi-r2-ethernet-alias.patch - ---- - arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts -index d980f068bde9..7ff310fdb138 100644 ---- a/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts -+++ b/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts -@@ -15,6 +15,7 @@ / { - - aliases { - serial2 = &uart2; -+ ethernet0 = &gmac0; - mmc0 = &mmc0; - mmc1 = &mmc1; - led-boot = &led_system_green; --- -2.51.0 - - -From 820e8b578867d75a0221837af059984f72a348c4 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:47 +0100 -Subject: [PATCH 438/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/164-dts-mt7623-bpi-r2-rootdisk-for-fitblk.patch - ---- - .../dts/mediatek/mt7623n-bananapi-bpi-r2.dts | 32 ++++++++++++++++++- - 1 file changed, 31 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts -index 7ff310fdb138..9b1cf2c7f672 100644 ---- a/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts -+++ b/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts -@@ -26,7 +26,9 @@ aliases { - - chosen { - stdout-path = "serial2:115200n8"; -- bootargs = "earlycon=uart8250,mmio32,0x11004000 console=ttyS2,115200n8 console=tty1"; -+ bootargs = "root=/dev/fit0 rootwait earlycon=uart8250,mmio32,0x11004000 console=ttyS2,115200n8 console=tty1"; -+ rootdisk-emmc = <&emmc_rootdisk>; -+ rootdisk-sd = <&sd_rootdisk>; - }; - - connector { -@@ -338,6 +340,20 @@ &mmc0 { - vmmc-supply = <®_3p3v>; - vqmmc-supply = <®_1p8v>; - non-removable; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ card@0 { -+ compatible = "mmc-card"; -+ reg = <0>; -+ -+ partitions { -+ compatible = "msdos-partitions"; -+ emmc_rootdisk: block-partition-fit { -+ partno = <3>; -+ }; -+ }; -+ }; - }; - - &mmc1 { -@@ -351,6 +367,20 @@ &mmc1 { - cd-gpios = <&pio 261 GPIO_ACTIVE_LOW>; - vmmc-supply = <®_3p3v>; - vqmmc-supply = <®_3p3v>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ card@0 { -+ compatible = "mmc-card"; -+ reg = <0>; -+ -+ partitions { -+ compatible = "msdos-partitions"; -+ sd_rootdisk: block-partition-fit { -+ partno = <3>; -+ }; -+ }; -+ }; - }; - - &mt6323keys { --- -2.51.0 - - -From 39278041735b59e066bd4440b141b69aaddc07ee Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 22 Apr 2025 15:24:25 +0200 -Subject: [PATCH 439/517] arm64: dts: mediatek: mt7988a-bpi-r4: allow hw - variants of bpi-r4 - -Sinovoip has released other variants of Bananapi-R4 board. -The known changes affecting only the LAN SFP+ slot which is replaced -by a 2.5G phy with optional PoE. - -Just move the common parts to a new dtsi and keep differences (only -i2c for lan-sfp) in dts. - -Signed-off-by: Frank Wunderlich -Acked-by: Krzysztof Kozlowski -Reviewed-by: AngeloGioacchino Del Regno ---- - arch/arm64/boot/dts/mediatek/Makefile | 6 + - .../mediatek/mt7988a-bananapi-bpi-r4-2g5.dts | 11 + - .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 400 +----------------- - .../dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi | 399 +++++++++++++++++ - 4 files changed, 421 insertions(+), 395 deletions(-) - create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-2g5.dts - create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi - -diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile -index 8fd7b2bb7a15..cd70066352b6 100644 ---- a/arch/arm64/boot/dts/mediatek/Makefile -+++ b/arch/arm64/boot/dts/mediatek/Makefile -@@ -21,6 +21,9 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-sd.dtbo - dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-rfb.dtb - dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986b-rfb.dtb - dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4.dtb -+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-2g5.dtb -+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-emmc.dtbo -+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-sd.dtbo - dtb-$(CONFIG_ARCH_MEDIATEK) += mt8167-pumpkin.dtb - dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm.dtb - dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm-hana.dtb -@@ -90,3 +93,6 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pumpkin.dtb - # Device tree overlays support - DTC_FLAGS_mt7986a-bananapi-bpi-r3 := -@ - DTC_FLAGS_mt7986a-bananapi-bpi-r3-mini := -@ -+DTC_FLAGS_mt7988a-bananapi-bpi-r4 := -@ -+DTC_FLAGS_mt7988a-bananapi-bpi-r4-2g5 := -@ -+DTC_FLAGS_mt8395-radxa-nio-12l := -@ -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-2g5.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-2g5.dts -new file mode 100644 -index 000000000000..53de9c113f60 ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-2g5.dts -@@ -0,0 +1,11 @@ -+// SPDX-License-Identifier: GPL-2.0-only OR MIT -+ -+/dts-v1/; -+ -+#include "mt7988a-bananapi-bpi-r4.dtsi" -+ -+/ { -+ compatible = "bananapi,bpi-r4-2g5", "bananapi,bpi-r4", "mediatek,mt7988a"; -+ model = "Banana Pi BPI-R4 (1x SFP+, 1x 2.5GbE)"; -+ chassis-type = "embedded"; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -index 6623112c24c7..36bd1ef2efab 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -@@ -2,408 +2,18 @@ - - /dts-v1/; - --#include --#include -- --#include "mt7988a.dtsi" -+#include "mt7988a-bananapi-bpi-r4.dtsi" - - / { - compatible = "bananapi,bpi-r4", "mediatek,mt7988a"; -- model = "Banana Pi BPI-R4"; -+ model = "Banana Pi BPI-R4 (2x SFP+)"; - chassis-type = "embedded"; -- -- chosen { -- stdout-path = "serial0:115200n8"; -- }; -- -- reg_1p8v: regulator-1p8v { -- compatible = "regulator-fixed"; -- regulator-name = "fixed-1.8V"; -- regulator-min-microvolt = <1800000>; -- regulator-max-microvolt = <1800000>; -- regulator-boot-on; -- regulator-always-on; -- }; -- -- reg_3p3v: regulator-3p3v { -- compatible = "regulator-fixed"; -- regulator-name = "fixed-3.3V"; -- regulator-min-microvolt = <3300000>; -- regulator-max-microvolt = <3300000>; -- regulator-boot-on; -- regulator-always-on; -- }; - }; - --&cpu0 { -- proc-supply = <&rt5190_buck3>; --}; -- --&cpu1 { -- proc-supply = <&rt5190_buck3>; --}; -- --&cpu2 { -- proc-supply = <&rt5190_buck3>; --}; -- --&cpu3 { -- proc-supply = <&rt5190_buck3>; --}; -- --&cpu_thermal { -- trips { -- cpu_trip_hot: hot { -- temperature = <120000>; -- hysteresis = <2000>; -- type = "hot"; -- }; -- -- cpu_trip_active_high: active-high { -- temperature = <115000>; -- hysteresis = <2000>; -- type = "active"; -- }; -- -- cpu_trip_active_med: active-med { -- temperature = <85000>; -- hysteresis = <2000>; -- type = "active"; -- }; -- -- cpu_trip_active_low: active-low { -- temperature = <40000>; -- hysteresis = <2000>; -- type = "active"; -- }; -- }; --}; -- --&i2c0 { -- pinctrl-names = "default"; -- pinctrl-0 = <&i2c0_pins>; -- status = "okay"; -- -- rt5190a_64: rt5190a@64 { -- compatible = "richtek,rt5190a"; -- reg = <0x64>; -- vin2-supply = <&rt5190_buck1>; -- vin3-supply = <&rt5190_buck1>; -- vin4-supply = <&rt5190_buck1>; -- -- regulators { -- rt5190_buck1: buck1 { -- regulator-name = "rt5190a-buck1"; -- regulator-min-microvolt = <5090000>; -- regulator-max-microvolt = <5090000>; -- regulator-allowed-modes = -- , ; -- regulator-boot-on; -- regulator-always-on; -- }; -- buck2 { -- regulator-name = "vcore"; -- regulator-min-microvolt = <600000>; -- regulator-max-microvolt = <1400000>; -- regulator-boot-on; -- regulator-always-on; -- }; -- rt5190_buck3: buck3 { -- regulator-name = "vproc"; -- regulator-min-microvolt = <600000>; -- regulator-max-microvolt = <1400000>; -- regulator-boot-on; -- }; -- buck4 { -- regulator-name = "rt5190a-buck4"; -- regulator-min-microvolt = <1800000>; -- regulator-max-microvolt = <1800000>; -- regulator-allowed-modes = -- , ; -- regulator-boot-on; -- regulator-always-on; -- }; -- ldo { -- regulator-name = "rt5190a-ldo"; -- regulator-min-microvolt = <1800000>; -- regulator-max-microvolt = <1800000>; -- regulator-boot-on; -- regulator-always-on; -- }; -- }; -- }; --}; -- --&i2c2 { -- pinctrl-names = "default"; -- pinctrl-0 = <&i2c2_1_pins>; -- status = "okay"; -- -- pca9545: i2c-mux@70 { -- compatible = "nxp,pca9545"; -- reg = <0x70>; -- reset-gpios = <&pio 5 GPIO_ACTIVE_LOW>; -+&pca9545 { -+ i2c_sfp2: i2c@2 { - #address-cells = <1>; - #size-cells = <0>; -- -- i2c@0 { -- #address-cells = <1>; -- #size-cells = <0>; -- reg = <0>; -- -- pcf8563: rtc@51 { -- compatible = "nxp,pcf8563"; -- reg = <0x51>; -- #clock-cells = <0>; -- }; -- -- eeprom@57 { -- compatible = "atmel,24c02"; -- reg = <0x57>; -- size = <256>; -- }; -- -- }; -- -- i2c_sfp1: i2c@1 { -- #address-cells = <1>; -- #size-cells = <0>; -- reg = <1>; -- }; -- -- i2c_sfp2: i2c@2 { -- #address-cells = <1>; -- #size-cells = <0>; -- reg = <2>; -- }; -- }; --}; -- --/* mPCIe SIM2 */ --&pcie0 { -- status = "okay"; --}; -- --/* mPCIe SIM3 */ --&pcie1 { -- status = "okay"; --}; -- --/* M.2 key-B SIM1 */ --&pcie2 { -- status = "okay"; --}; -- --/* M.2 key-M SSD */ --&pcie3 { -- status = "okay"; --}; -- --&pio { -- mdio0_pins: mdio0-pins { -- mux { -- function = "eth"; -- groups = "mdc_mdio0"; -- }; -- -- conf { -- pins = "SMI_0_MDC", "SMI_0_MDIO"; -- drive-strength = <8>; -- }; -- }; -- -- i2c0_pins: i2c0-g0-pins { -- mux { -- function = "i2c"; -- groups = "i2c0_1"; -- }; -- }; -- -- i2c1_pins: i2c1-g0-pins { -- mux { -- function = "i2c"; -- groups = "i2c1_0"; -- }; -- }; -- -- i2c1_sfp_pins: i2c1-sfp-g0-pins { -- mux { -- function = "i2c"; -- groups = "i2c1_sfp"; -- }; -- }; -- -- i2c2_0_pins: i2c2-g0-pins { -- mux { -- function = "i2c"; -- groups = "i2c2_0"; -- }; -+ reg = <2>; - }; -- -- i2c2_1_pins: i2c2-g1-pins { -- mux { -- function = "i2c"; -- groups = "i2c2_1"; -- }; -- }; -- -- gbe0_led0_pins: gbe0-led0-pins { -- mux { -- function = "led"; -- groups = "gbe0_led0"; -- }; -- }; -- -- gbe1_led0_pins: gbe1-led0-pins { -- mux { -- function = "led"; -- groups = "gbe1_led0"; -- }; -- }; -- -- gbe2_led0_pins: gbe2-led0-pins { -- mux { -- function = "led"; -- groups = "gbe2_led0"; -- }; -- }; -- -- gbe3_led0_pins: gbe3-led0-pins { -- mux { -- function = "led"; -- groups = "gbe3_led0"; -- }; -- }; -- -- gbe0_led1_pins: gbe0-led1-pins { -- mux { -- function = "led"; -- groups = "gbe0_led1"; -- }; -- }; -- -- gbe1_led1_pins: gbe1-led1-pins { -- mux { -- function = "led"; -- groups = "gbe1_led1"; -- }; -- }; -- -- gbe2_led1_pins: gbe2-led1-pins { -- mux { -- function = "led"; -- groups = "gbe2_led1"; -- }; -- }; -- -- gbe3_led1_pins: gbe3-led1-pins { -- mux { -- function = "led"; -- groups = "gbe3_led1"; -- }; -- }; -- -- i2p5gbe_led0_pins: 2p5gbe-led0-pins { -- mux { -- function = "led"; -- groups = "2p5gbe_led0"; -- }; -- }; -- -- i2p5gbe_led1_pins: 2p5gbe-led1-pins { -- mux { -- function = "led"; -- groups = "2p5gbe_led1"; -- }; -- }; -- -- mmc0_pins_emmc_45: mmc0-emmc-45-pins { -- mux { -- function = "flash"; -- groups = "emmc_45"; -- }; -- }; -- -- mmc0_pins_emmc_51: mmc0-emmc-51-pins { -- mux { -- function = "flash"; -- groups = "emmc_51"; -- }; -- }; -- -- mmc0_pins_sdcard: mmc0-sdcard-pins { -- mux { -- function = "flash"; -- groups = "sdcard"; -- }; -- }; -- -- uart0_pins: uart0-pins { -- mux { -- function = "uart"; -- groups = "uart0"; -- }; -- }; -- -- snfi_pins: snfi-pins { -- mux { -- function = "flash"; -- groups = "snfi"; -- }; -- }; -- -- spi0_pins: spi0-pins { -- mux { -- function = "spi"; -- groups = "spi0"; -- }; -- }; -- -- spi0_flash_pins: spi0-flash-pins { -- mux { -- function = "spi"; -- groups = "spi0", "spi0_wp_hold"; -- }; -- }; -- -- spi1_pins: spi1-pins { -- mux { -- function = "spi"; -- groups = "spi1"; -- }; -- }; -- -- spi2_pins: spi2-pins { -- mux { -- function = "spi"; -- groups = "spi2"; -- }; -- }; -- -- spi2_flash_pins: spi2-flash-pins { -- mux { -- function = "spi"; -- groups = "spi2", "spi2_wp_hold"; -- }; -- }; --}; -- --&pwm { -- status = "okay"; --}; -- --&serial0 { -- status = "okay"; --}; -- --&ssusb1 { -- status = "okay"; --}; -- --&tphy { -- status = "okay"; --}; -- --&watchdog { -- status = "okay"; - }; -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi -new file mode 100644 -index 000000000000..0d332822971d ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi -@@ -0,0 +1,399 @@ -+// SPDX-License-Identifier: GPL-2.0-only OR MIT -+ -+/dts-v1/; -+ -+#include -+#include -+ -+#include "mt7988a.dtsi" -+ -+/ { -+ chosen { -+ stdout-path = "serial0:115200n8"; -+ }; -+ -+ reg_1p8v: regulator-1p8v { -+ compatible = "regulator-fixed"; -+ regulator-name = "fixed-1.8V"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ reg_3p3v: regulator-3p3v { -+ compatible = "regulator-fixed"; -+ regulator-name = "fixed-3.3V"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+}; -+ -+&cpu0 { -+ proc-supply = <&rt5190_buck3>; -+}; -+ -+&cpu1 { -+ proc-supply = <&rt5190_buck3>; -+}; -+ -+&cpu2 { -+ proc-supply = <&rt5190_buck3>; -+}; -+ -+&cpu3 { -+ proc-supply = <&rt5190_buck3>; -+}; -+ -+&cpu_thermal { -+ trips { -+ cpu_trip_hot: hot { -+ temperature = <120000>; -+ hysteresis = <2000>; -+ type = "hot"; -+ }; -+ -+ cpu_trip_active_high: active-high { -+ temperature = <115000>; -+ hysteresis = <2000>; -+ type = "active"; -+ }; -+ -+ cpu_trip_active_med: active-med { -+ temperature = <85000>; -+ hysteresis = <2000>; -+ type = "active"; -+ }; -+ -+ cpu_trip_active_low: active-low { -+ temperature = <40000>; -+ hysteresis = <2000>; -+ type = "active"; -+ }; -+ }; -+}; -+ -+&i2c0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_pins>; -+ status = "okay"; -+ -+ rt5190a_64: rt5190a@64 { -+ compatible = "richtek,rt5190a"; -+ reg = <0x64>; -+ vin2-supply = <&rt5190_buck1>; -+ vin3-supply = <&rt5190_buck1>; -+ vin4-supply = <&rt5190_buck1>; -+ -+ regulators { -+ rt5190_buck1: buck1 { -+ regulator-name = "rt5190a-buck1"; -+ regulator-min-microvolt = <5090000>; -+ regulator-max-microvolt = <5090000>; -+ regulator-allowed-modes = -+ , ; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ buck2 { -+ regulator-name = "vcore"; -+ regulator-min-microvolt = <600000>; -+ regulator-max-microvolt = <1400000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ rt5190_buck3: buck3 { -+ regulator-name = "vproc"; -+ regulator-min-microvolt = <600000>; -+ regulator-max-microvolt = <1400000>; -+ regulator-boot-on; -+ }; -+ buck4 { -+ regulator-name = "rt5190a-buck4"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-allowed-modes = -+ , ; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ ldo { -+ regulator-name = "rt5190a-ldo"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ }; -+ }; -+}; -+ -+&i2c2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c2_1_pins>; -+ status = "okay"; -+ -+ pca9545: i2c-mux@70 { -+ compatible = "nxp,pca9545"; -+ reg = <0x70>; -+ reset-gpios = <&pio 5 GPIO_ACTIVE_LOW>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ i2c@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ -+ pcf8563: rtc@51 { -+ compatible = "nxp,pcf8563"; -+ reg = <0x51>; -+ #clock-cells = <0>; -+ }; -+ -+ eeprom@57 { -+ compatible = "atmel,24c02"; -+ reg = <0x57>; -+ size = <256>; -+ }; -+ -+ }; -+ -+ i2c_sfp1: i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ }; -+ }; -+}; -+ -+/* mPCIe SIM2 */ -+&pcie0 { -+ status = "okay"; -+}; -+ -+/* mPCIe SIM3 */ -+&pcie1 { -+ status = "okay"; -+}; -+ -+/* M.2 key-B SIM1 */ -+&pcie2 { -+ status = "okay"; -+}; -+ -+/* M.2 key-M SSD */ -+&pcie3 { -+ status = "okay"; -+}; -+ -+&pio { -+ mdio0_pins: mdio0-pins { -+ mux { -+ function = "eth"; -+ groups = "mdc_mdio0"; -+ }; -+ -+ conf { -+ pins = "SMI_0_MDC", "SMI_0_MDIO"; -+ drive-strength = <8>; -+ }; -+ }; -+ -+ i2c0_pins: i2c0-g0-pins { -+ mux { -+ function = "i2c"; -+ groups = "i2c0_1"; -+ }; -+ }; -+ -+ i2c1_pins: i2c1-g0-pins { -+ mux { -+ function = "i2c"; -+ groups = "i2c1_0"; -+ }; -+ }; -+ -+ i2c1_sfp_pins: i2c1-sfp-g0-pins { -+ mux { -+ function = "i2c"; -+ groups = "i2c1_sfp"; -+ }; -+ }; -+ -+ i2c2_0_pins: i2c2-g0-pins { -+ mux { -+ function = "i2c"; -+ groups = "i2c2_0"; -+ }; -+ }; -+ -+ i2c2_1_pins: i2c2-g1-pins { -+ mux { -+ function = "i2c"; -+ groups = "i2c2_1"; -+ }; -+ }; -+ -+ gbe0_led0_pins: gbe0-led0-pins { -+ mux { -+ function = "led"; -+ groups = "gbe0_led0"; -+ }; -+ }; -+ -+ gbe1_led0_pins: gbe1-led0-pins { -+ mux { -+ function = "led"; -+ groups = "gbe1_led0"; -+ }; -+ }; -+ -+ gbe2_led0_pins: gbe2-led0-pins { -+ mux { -+ function = "led"; -+ groups = "gbe2_led0"; -+ }; -+ }; -+ -+ gbe3_led0_pins: gbe3-led0-pins { -+ mux { -+ function = "led"; -+ groups = "gbe3_led0"; -+ }; -+ }; -+ -+ gbe0_led1_pins: gbe0-led1-pins { -+ mux { -+ function = "led"; -+ groups = "gbe0_led1"; -+ }; -+ }; -+ -+ gbe1_led1_pins: gbe1-led1-pins { -+ mux { -+ function = "led"; -+ groups = "gbe1_led1"; -+ }; -+ }; -+ -+ gbe2_led1_pins: gbe2-led1-pins { -+ mux { -+ function = "led"; -+ groups = "gbe2_led1"; -+ }; -+ }; -+ -+ gbe3_led1_pins: gbe3-led1-pins { -+ mux { -+ function = "led"; -+ groups = "gbe3_led1"; -+ }; -+ }; -+ -+ i2p5gbe_led0_pins: 2p5gbe-led0-pins { -+ mux { -+ function = "led"; -+ groups = "2p5gbe_led0"; -+ }; -+ }; -+ -+ i2p5gbe_led1_pins: 2p5gbe-led1-pins { -+ mux { -+ function = "led"; -+ groups = "2p5gbe_led1"; -+ }; -+ }; -+ -+ mmc0_pins_emmc_45: mmc0-emmc-45-pins { -+ mux { -+ function = "flash"; -+ groups = "emmc_45"; -+ }; -+ }; -+ -+ mmc0_pins_emmc_51: mmc0-emmc-51-pins { -+ mux { -+ function = "flash"; -+ groups = "emmc_51"; -+ }; -+ }; -+ -+ mmc0_pins_sdcard: mmc0-sdcard-pins { -+ mux { -+ function = "flash"; -+ groups = "sdcard"; -+ }; -+ }; -+ -+ uart0_pins: uart0-pins { -+ mux { -+ function = "uart"; -+ groups = "uart0"; -+ }; -+ }; -+ -+ snfi_pins: snfi-pins { -+ mux { -+ function = "flash"; -+ groups = "snfi"; -+ }; -+ }; -+ -+ spi0_pins: spi0-pins { -+ mux { -+ function = "spi"; -+ groups = "spi0"; -+ }; -+ }; -+ -+ spi0_flash_pins: spi0-flash-pins { -+ mux { -+ function = "spi"; -+ groups = "spi0", "spi0_wp_hold"; -+ }; -+ }; -+ -+ spi1_pins: spi1-pins { -+ mux { -+ function = "spi"; -+ groups = "spi1"; -+ }; -+ }; -+ -+ spi2_pins: spi2-pins { -+ mux { -+ function = "spi"; -+ groups = "spi2"; -+ }; -+ }; -+ -+ spi2_flash_pins: spi2-flash-pins { -+ mux { -+ function = "spi"; -+ groups = "spi2", "spi2_wp_hold"; -+ }; -+ }; -+}; -+ -+&pwm { -+ status = "okay"; -+}; -+ -+&serial0 { -+ status = "okay"; -+}; -+ -+&ssusb1 { -+ status = "okay"; -+}; -+ -+&tphy { -+ status = "okay"; -+}; -+ -+&watchdog { -+ status = "okay"; -+}; --- -2.51.0 - - -From 85dec32b37881f3eb8fa393afcc9c32d1a685667 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 22 Apr 2025 15:24:30 +0200 -Subject: [PATCH 440/517] arm64: dts: mediatek: mt7988: Add xsphy for - ssusb0/pcie2 - -First usb and third pcie controller on mt7988 need a xs-phy to work -properly. - -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno ---- - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 36 +++++++++++++++++++++++ - 1 file changed, 36 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index 88b56a24efca..a59f8708f0ef 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -334,6 +334,8 @@ usb@11190000 { - <&infracfg CLK_INFRA_133M_USB_HCK>, - <&infracfg CLK_INFRA_USB_XHCI>; - clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck"; -+ phys = <&xphyu2port0 PHY_TYPE_USB2>, -+ <&xphyu3port0 PHY_TYPE_USB3>; - status = "disabled"; - }; - -@@ -398,6 +400,9 @@ pcie2: pcie@11280000 { - pinctrl-0 = <&pcie2_pins>; - status = "disabled"; - -+ phys = <&xphyu3port0 PHY_TYPE_PCIE>; -+ phy-names = "pcie-phy"; -+ - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 0x7>; - interrupt-map = <0 0 0 1 &pcie_intc2 0>, -@@ -548,6 +553,37 @@ tphyu3port0: usb-phy@11c50700 { - }; - }; - -+ -+ topmisc: system-controller@11d10084 { -+ compatible = "mediatek,mt7988-topmisc", -+ "syscon"; -+ reg = <0 0x11d10084 0 0xff80>; -+ }; -+ -+ xs-phy@11e10000 { -+ compatible = "mediatek,mt7988-xsphy", -+ "mediatek,xsphy"; -+ #address-cells = <2>; -+ #size-cells = <2>; -+ ranges; -+ status = "disabled"; -+ -+ xphyu2port0: usb-phy@11e10000 { -+ reg = <0 0x11e10000 0 0x400>; -+ clocks = <&infracfg CLK_INFRA_USB_UTMI>; -+ clock-names = "ref"; -+ #phy-cells = <1>; -+ }; -+ -+ xphyu3port0: usb-phy@11e13000 { -+ reg = <0 0x11e13400 0 0x500>; -+ clocks = <&infracfg CLK_INFRA_USB_PIPE>; -+ clock-names = "ref"; -+ #phy-cells = <1>; -+ mediatek,syscon-type = <&topmisc 0x194 0>; -+ }; -+ }; -+ - clock-controller@11f40000 { - compatible = "mediatek,mt7988-xfi-pll"; - reg = <0 0x11f40000 0 0x1000>; --- -2.51.0 - - -From 72b8292bf3f9f14d1effee2ba565704bd95cdaa2 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 22 Apr 2025 15:24:31 +0200 -Subject: [PATCH 441/517] arm64: dts: mediatek: mt7988a-bpi-r4: enable xsphy - -Enable XS-Phy on Bananapi R4 for pcie2. - -Signed-off-by: Frank Wunderlich -Reviewed-by: AngeloGioacchino Del Regno ---- - arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi | 4 ++++ - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 2 +- - 2 files changed, 5 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi -index 0d332822971d..37e541a98ee1 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi -@@ -397,3 +397,7 @@ &tphy { - &watchdog { - status = "okay"; - }; -+ -+&xsphy { -+ status = "okay"; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index a59f8708f0ef..8f6d1dfae24a 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -560,7 +560,7 @@ topmisc: system-controller@11d10084 { - reg = <0 0x11d10084 0 0xff80>; - }; - -- xs-phy@11e10000 { -+ xsphy: xs-phy@11e10000 { - compatible = "mediatek,mt7988-xsphy", - "mediatek,xsphy"; - #address-cells = <2>; --- -2.51.0 - - -From ac56a2fb07e5a0cc06c96d60801d5f6f88a05715 Mon Sep 17 00:00:00 2001 -From: Sky Huang -Date: Wed, 19 Feb 2025 16:39:09 +0800 -Subject: [PATCH 442/517] dts: mt7988a: Add built-in ethernet phy firmware node - -Add built-in ethernet phy firmware node in mt7988a.dtsi. - -Signed-off-by: Sky Huang ---- - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index 8f6d1dfae24a..1bd5f6f7cab9 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -322,6 +322,12 @@ lvts: lvts@1100a000 { - nvmem-cell-names = "lvts-calib-data-1"; - }; - -+ phyfw: phy-firmware@f000000 { -+ compatible = "mediatek,2p5gphy-fw"; -+ reg = <0 0x0f100000 0 0x20000>, -+ <0 0x0f0f0018 0 0x20>; -+ }; -+ - usb@11190000 { - compatible = "mediatek,mt7988-xhci", "mediatek,mtk-xhci"; - reg = <0 0x11190000 0 0x2e00>, --- -2.51.0 - - -From 963d669897db001e98a3beda0efdc1c36c416c8f Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Sun, 11 May 2025 16:19:20 +0200 -Subject: [PATCH 443/517] arm64: dts: mediatek: mt7988: add spi controllers - -Add SPI controllers for mt7988. - -Signed-off-by: Daniel Golle -Signed-off-by: Frank Wunderlich ---- - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 45 +++++++++++++++++++++++ - 1 file changed, 45 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index 1bd5f6f7cab9..00804f5d7cfb 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -311,6 +311,51 @@ i2c2: i2c@11005000 { - status = "disabled"; - }; - -+ spi0: spi@11007000 { -+ compatible = "mediatek,mt7988-spi-quad", "mediatek,spi-ipm"; -+ reg = <0 0x11007000 0 0x100>; -+ interrupts = ; -+ clocks = <&topckgen CLK_TOP_MPLL_D2>, -+ <&topckgen CLK_TOP_SPI_SEL>, -+ <&infracfg CLK_INFRA_104M_SPI0>, -+ <&infracfg CLK_INFRA_66M_SPI0_HCK>; -+ clock-names = "parent-clk", "sel-clk", "spi-clk", -+ "hclk"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ spi1: spi@11008000 { -+ compatible = "mediatek,mt7988-spi-single", "mediatek,spi-ipm"; -+ reg = <0 0x11008000 0 0x100>; -+ interrupts = ; -+ clocks = <&topckgen CLK_TOP_MPLL_D2>, -+ <&topckgen CLK_TOP_SPIM_MST_SEL>, -+ <&infracfg CLK_INFRA_104M_SPI1>, -+ <&infracfg CLK_INFRA_66M_SPI1_HCK>; -+ clock-names = "parent-clk", "sel-clk", "spi-clk", -+ "hclk"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ spi2: spi@11009000 { -+ compatible = "mediatek,mt7988-spi-quad", "mediatek,spi-ipm"; -+ reg = <0 0x11009000 0 0x100>; -+ interrupts = ; -+ clocks = <&topckgen CLK_TOP_MPLL_D2>, -+ <&topckgen CLK_TOP_SPI_SEL>, -+ <&infracfg CLK_INFRA_104M_SPI2_BCK>, -+ <&infracfg CLK_INFRA_66M_SPI2_HCK>; -+ clock-names = "parent-clk", "sel-clk", "spi-clk", -+ "hclk"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ - lvts: lvts@1100a000 { - compatible = "mediatek,mt7988-lvts-ap"; - #thermal-sensor-cells = <1>; --- -2.51.0 - - -From bf8119d36aa8a45ef759d007d1f380559ce5c75b Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Sun, 11 May 2025 16:19:21 +0200 -Subject: [PATCH 444/517] arm64: dts: mediatek: mt7988: move uart0 and spi1 - pins to soc dtsi - -In order to use uart0 or spi1 there is only 1 possible pin definition -so move them to soc dtsi to reuse them in other boards and avoiding -conflict if defined twice. - -Suggested-by: Daniel Golle -Signed-off-by: Frank Wunderlich ---- - .../dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi | 14 -------------- - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 18 ++++++++++++++++++ - 2 files changed, 18 insertions(+), 14 deletions(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi -index 37e541a98ee1..23b267cd47ac 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi -@@ -328,13 +328,6 @@ mux { - }; - }; - -- uart0_pins: uart0-pins { -- mux { -- function = "uart"; -- groups = "uart0"; -- }; -- }; -- - snfi_pins: snfi-pins { - mux { - function = "flash"; -@@ -356,13 +349,6 @@ mux { - }; - }; - -- spi1_pins: spi1-pins { -- mux { -- function = "spi"; -- groups = "spi1"; -- }; -- }; -- - spi2_pins: spi2-pins { - mux { - function = "spi"; -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index 00804f5d7cfb..e6f453cba690 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -209,6 +209,20 @@ mux { - "pcie_wake_n3_0"; - }; - }; -+ -+ spi1_pins: spi1-pins { -+ mux { -+ function = "spi"; -+ groups = "spi1"; -+ }; -+ }; -+ -+ uart0_pins: uart0-pins { -+ mux { -+ function = "uart"; -+ groups = "uart0"; -+ }; -+ }; - }; - - pwm: pwm@10048000 { -@@ -244,6 +258,8 @@ serial0: serial@11000000 { - clocks = <&topckgen CLK_TOP_UART_SEL>, - <&infracfg CLK_INFRA_52M_UART0_CK>; - clock-names = "baud", "bus"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_pins>; - status = "disabled"; - }; - -@@ -338,6 +354,8 @@ spi1: spi@11008000 { - "hclk"; - #address-cells = <1>; - #size-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi1_pins>; - status = "disabled"; - }; - --- -2.51.0 - - -From 47332041261f52b7abadb9697e530606ae4a04d1 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Sun, 11 May 2025 16:19:22 +0200 -Subject: [PATCH 445/517] arm64: dts: mediatek: mt7988: add cci node - -Add cci devicetree node for cpu frequency scaling. - -Signed-off-by: Daniel Golle -Signed-off-by: Frank Wunderlich ---- - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 33 +++++++++++++++++++++++ - 1 file changed, 33 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index e6f453cba690..c0012ecc0279 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -12,6 +12,35 @@ / { - #address-cells = <2>; - #size-cells = <2>; - -+ cci: cci { -+ compatible = "mediatek,mt8183-cci"; -+ clocks = <&mcusys CLK_MCU_BUS_DIV_SEL>, -+ <&topckgen CLK_TOP_XTAL>; -+ clock-names = "cci", "intermediate"; -+ operating-points-v2 = <&cci_opp>; -+ }; -+ -+ cci_opp: opp-table-cci { -+ compatible = "operating-points-v2"; -+ opp-shared; -+ opp-480000000 { -+ opp-hz = /bits/ 64 <480000000>; -+ opp-microvolt = <850000>; -+ }; -+ opp-660000000 { -+ opp-hz = /bits/ 64 <660000000>; -+ opp-microvolt = <850000>; -+ }; -+ opp-900000000 { -+ opp-hz = /bits/ 64 <900000000>; -+ opp-microvolt = <850000>; -+ }; -+ opp-1080000000 { -+ opp-hz = /bits/ 64 <1080000000>; -+ opp-microvolt = <900000>; -+ }; -+ }; -+ - cpus { - #address-cells = <1>; - #size-cells = <0>; -@@ -25,6 +54,7 @@ cpu0: cpu@0 { - <&topckgen CLK_TOP_XTAL>; - clock-names = "cpu", "intermediate"; - operating-points-v2 = <&cluster0_opp>; -+ mediatek,cci = <&cci>; - }; - - cpu1: cpu@1 { -@@ -36,6 +66,7 @@ cpu1: cpu@1 { - <&topckgen CLK_TOP_XTAL>; - clock-names = "cpu", "intermediate"; - operating-points-v2 = <&cluster0_opp>; -+ mediatek,cci = <&cci>; - }; - - cpu2: cpu@2 { -@@ -47,6 +78,7 @@ cpu2: cpu@2 { - <&topckgen CLK_TOP_XTAL>; - clock-names = "cpu", "intermediate"; - operating-points-v2 = <&cluster0_opp>; -+ mediatek,cci = <&cci>; - }; - - cpu3: cpu@3 { -@@ -58,6 +90,7 @@ cpu3: cpu@3 { - <&topckgen CLK_TOP_XTAL>; - clock-names = "cpu", "intermediate"; - operating-points-v2 = <&cluster0_opp>; -+ mediatek,cci = <&cci>; - }; - - cluster0_opp: opp-table-0 { --- -2.51.0 - - -From 8eaa49fa6b1ad51e5ff86d8996611202f0b91f60 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Sun, 11 May 2025 16:19:23 +0200 -Subject: [PATCH 446/517] arm64: dts: mediatek: mt7988: add phy calibration - efuse subnodes - -MT7988 contains buildin mt753x switch which needs calibration data from -efuse. - -Signed-off-by: Daniel Golle -Signed-off-by: Frank Wunderlich ---- - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index c0012ecc0279..9b5f1d8b7a5e 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -702,6 +702,22 @@ efuse@11f50000 { - lvts_calibration: calib@918 { - reg = <0x918 0x28>; - }; -+ -+ phy_calibration_p0: calib@940 { -+ reg = <0x940 0x10>; -+ }; -+ -+ phy_calibration_p1: calib@954 { -+ reg = <0x954 0x10>; -+ }; -+ -+ phy_calibration_p2: calib@968 { -+ reg = <0x968 0x10>; -+ }; -+ -+ phy_calibration_p3: calib@97c { -+ reg = <0x97c 0x10>; -+ }; - }; - - clock-controller@15000000 { --- -2.51.0 - - -From 55218122074b172b336b24d381b46308fcfef693 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Sun, 11 May 2025 16:19:24 +0200 -Subject: [PATCH 447/517] arm64: dts: mediatek: mt7988: add basic - ethernet-nodes - -Add basic ethernet related nodes. - -Mac1+2 needs pcs (sgmii+usxgmii) to work correctly which will be linked -later when driver is merged. - -Signed-off-by: Daniel Golle -Signed-off-by: Frank Wunderlich ---- - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 124 +++++++++++++++++++++- - 1 file changed, 121 insertions(+), 3 deletions(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index 9b5f1d8b7a5e..87c39335c528 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -686,7 +686,28 @@ xphyu3port0: usb-phy@11e13000 { - }; - }; - -- clock-controller@11f40000 { -+ xfi_tphy0: phy@11f20000 { -+ compatible = "mediatek,mt7988-xfi-tphy"; -+ reg = <0 0x11f20000 0 0x10000>; -+ resets = <&watchdog 14>; -+ clocks = <&xfi_pll CLK_XFIPLL_PLL_EN>, -+ <&topckgen CLK_TOP_XFI_PHY_0_XTAL_SEL>; -+ clock-names = "xfipll", "topxtal"; -+ mediatek,usxgmii-performance-errata; -+ #phy-cells = <0>; -+ }; -+ -+ xfi_tphy1: phy@11f30000 { -+ compatible = "mediatek,mt7988-xfi-tphy"; -+ reg = <0 0x11f30000 0 0x10000>; -+ resets = <&watchdog 15>; -+ clocks = <&xfi_pll CLK_XFIPLL_PLL_EN>, -+ <&topckgen CLK_TOP_XFI_PHY_1_XTAL_SEL>; -+ clock-names = "xfipll", "topxtal"; -+ #phy-cells = <0>; -+ }; -+ -+ xfi_pll: clock-controller@11f40000 { - compatible = "mediatek,mt7988-xfi-pll"; - reg = <0 0x11f40000 0 0x1000>; - resets = <&watchdog 16>; -@@ -720,19 +741,116 @@ phy_calibration_p3: calib@97c { - }; - }; - -- clock-controller@15000000 { -+ ethsys: clock-controller@15000000 { - compatible = "mediatek,mt7988-ethsys", "syscon"; - reg = <0 0x15000000 0 0x1000>; - #clock-cells = <1>; - #reset-cells = <1>; - }; - -- clock-controller@15031000 { -+ ethwarp: clock-controller@15031000 { - compatible = "mediatek,mt7988-ethwarp"; - reg = <0 0x15031000 0 0x1000>; - #clock-cells = <1>; - #reset-cells = <1>; - }; -+ -+ eth: ethernet@15100000 { -+ compatible = "mediatek,mt7988-eth"; -+ reg = <0 0x15100000 0 0x80000>, -+ <0 0x15400000 0 0x200000>; -+ interrupts = , -+ , -+ , -+ ; -+ clocks = <ðsys CLK_ETHDMA_CRYPT0_EN>, -+ <ðsys CLK_ETHDMA_FE_EN>, -+ <ðsys CLK_ETHDMA_GP2_EN>, -+ <ðsys CLK_ETHDMA_GP1_EN>, -+ <ðsys CLK_ETHDMA_GP3_EN>, -+ <ðwarp CLK_ETHWARP_WOCPU2_EN>, -+ <ðwarp CLK_ETHWARP_WOCPU1_EN>, -+ <ðwarp CLK_ETHWARP_WOCPU0_EN>, -+ <ðsys CLK_ETHDMA_ESW_EN>, -+ <&topckgen CLK_TOP_ETH_GMII_SEL>, -+ <&topckgen CLK_TOP_ETH_REFCK_50M_SEL>, -+ <&topckgen CLK_TOP_ETH_SYS_200M_SEL>, -+ <&topckgen CLK_TOP_ETH_SYS_SEL>, -+ <&topckgen CLK_TOP_ETH_XGMII_SEL>, -+ <&topckgen CLK_TOP_ETH_MII_SEL>, -+ <&topckgen CLK_TOP_NETSYS_SEL>, -+ <&topckgen CLK_TOP_NETSYS_500M_SEL>, -+ <&topckgen CLK_TOP_NETSYS_PAO_2X_SEL>, -+ <&topckgen CLK_TOP_NETSYS_SYNC_250M_SEL>, -+ <&topckgen CLK_TOP_NETSYS_PPEFB_250M_SEL>, -+ <&topckgen CLK_TOP_NETSYS_WARP_SEL>, -+ <ðsys CLK_ETHDMA_XGP1_EN>, -+ <ðsys CLK_ETHDMA_XGP2_EN>, -+ <ðsys CLK_ETHDMA_XGP3_EN>; -+ clock-names = "crypto", "fe", "gp2", "gp1", -+ "gp3", -+ "ethwarp_wocpu2", "ethwarp_wocpu1", -+ "ethwarp_wocpu0", "esw", "top_eth_gmii_sel", -+ "top_eth_refck_50m_sel", "top_eth_sys_200m_sel", -+ "top_eth_sys_sel", "top_eth_xgmii_sel", -+ "top_eth_mii_sel", "top_netsys_sel", -+ "top_netsys_500m_sel", "top_netsys_pao_2x_sel", -+ "top_netsys_sync_250m_sel", -+ "top_netsys_ppefb_250m_sel", -+ "top_netsys_warp_sel","xgp1", "xgp2", "xgp3"; -+ assigned-clocks = <&topckgen CLK_TOP_NETSYS_2X_SEL>, -+ <&topckgen CLK_TOP_NETSYS_GSW_SEL>, -+ <&topckgen CLK_TOP_USXGMII_SBUS_0_SEL>, -+ <&topckgen CLK_TOP_USXGMII_SBUS_1_SEL>, -+ <&topckgen CLK_TOP_SGM_0_SEL>, -+ <&topckgen CLK_TOP_SGM_1_SEL>; -+ assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>, -+ <&topckgen CLK_TOP_NET1PLL_D4>, -+ <&topckgen CLK_TOP_NET1PLL_D8_D4>, -+ <&topckgen CLK_TOP_NET1PLL_D8_D4>, -+ <&apmixedsys CLK_APMIXED_SGMPLL>, -+ <&apmixedsys CLK_APMIXED_SGMPLL>; -+ mediatek,ethsys = <ðsys>; -+ mediatek,infracfg = <&topmisc>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ gmac0: mac@0 { -+ compatible = "mediatek,eth-mac"; -+ reg = <0>; -+ phy-mode = "internal"; -+ -+ fixed-link { -+ speed = <10000>; -+ full-duplex; -+ pause; -+ }; -+ }; -+ -+ gmac1: mac@1 { -+ compatible = "mediatek,eth-mac"; -+ reg = <1>; -+ status = "disabled"; -+ }; -+ -+ gmac2: mac@2 { -+ compatible = "mediatek,eth-mac"; -+ reg = <2>; -+ status = "disabled"; -+ }; -+ -+ mdio_bus: mdio-bus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ /* internal 2.5G PHY */ -+ int_2p5g_phy: ethernet-phy@f { -+ reg = <15>; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ phy-mode = "internal"; -+ }; -+ }; -+ }; - }; - - thermal-zones { --- -2.51.0 - - -From 19b301d95660bf872d694d0180f3e1fc9eb51a5a Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Sun, 11 May 2025 16:19:25 +0200 -Subject: [PATCH 448/517] arm64: dts: mediatek: mt7988: add switch node - -Add mt7988 builtin mt753x switch nodes. - -Signed-off-by: Daniel Golle -Signed-off-by: Frank Wunderlich ---- - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 154 ++++++++++++++++++++++ - 1 file changed, 154 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index 87c39335c528..f19e884f13be 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -5,6 +5,7 @@ - #include - #include - #include -+#include - - / { - compatible = "mediatek,mt7988a"; -@@ -748,6 +749,159 @@ ethsys: clock-controller@15000000 { - #reset-cells = <1>; - }; - -+ switch: switch@15020000 { -+ compatible = "mediatek,mt7988-switch"; -+ reg = <0 0x15020000 0 0x8000>; -+ interrupt-controller; -+ #interrupt-cells = <1>; -+ interrupt-parent = <&gic>; -+ interrupts = ; -+ resets = <ðwarp MT7988_ETHWARP_RST_SWITCH>; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ gsw_port0: port@0 { -+ reg = <0>; -+ phy-mode = "internal"; -+ phy-handle = <&gsw_phy0>; -+ }; -+ -+ gsw_port1: port@1 { -+ reg = <1>; -+ phy-mode = "internal"; -+ phy-handle = <&gsw_phy1>; -+ }; -+ -+ gsw_port2: port@2 { -+ reg = <2>; -+ phy-mode = "internal"; -+ phy-handle = <&gsw_phy2>; -+ }; -+ -+ gsw_port3: port@3 { -+ reg = <3>; -+ phy-mode = "internal"; -+ phy-handle = <&gsw_phy3>; -+ }; -+ -+ port@6 { -+ reg = <6>; -+ ethernet = <&gmac0>; -+ phy-mode = "internal"; -+ -+ fixed-link { -+ speed = <10000>; -+ full-duplex; -+ pause; -+ }; -+ }; -+ }; -+ -+ mdio { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ mediatek,pio = <&pio>; -+ -+ gsw_phy0: ethernet-phy@0 { -+ compatible = "ethernet-phy-ieee802.3-c22"; -+ reg = <0>; -+ interrupts = <0>; -+ phy-mode = "internal"; -+ nvmem-cells = <&phy_calibration_p0>; -+ nvmem-cell-names = "phy-cal-data"; -+ -+ leds { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ gsw_phy0_led0: led@0 { -+ reg = <0>; -+ status = "disabled"; -+ }; -+ -+ gsw_phy0_led1: led@1 { -+ reg = <1>; -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ gsw_phy1: ethernet-phy@1 { -+ compatible = "ethernet-phy-ieee802.3-c22"; -+ reg = <1>; -+ interrupts = <1>; -+ phy-mode = "internal"; -+ nvmem-cells = <&phy_calibration_p1>; -+ nvmem-cell-names = "phy-cal-data"; -+ -+ leds { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ gsw_phy1_led0: led@0 { -+ reg = <0>; -+ status = "disabled"; -+ }; -+ -+ gsw_phy1_led1: led@1 { -+ reg = <1>; -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ gsw_phy2: ethernet-phy@2 { -+ compatible = "ethernet-phy-ieee802.3-c22"; -+ reg = <2>; -+ interrupts = <2>; -+ phy-mode = "internal"; -+ nvmem-cells = <&phy_calibration_p2>; -+ nvmem-cell-names = "phy-cal-data"; -+ -+ leds { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ gsw_phy2_led0: led@0 { -+ reg = <0>; -+ status = "disabled"; -+ }; -+ -+ gsw_phy2_led1: led@1 { -+ reg = <1>; -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ gsw_phy3: ethernet-phy@3 { -+ compatible = "ethernet-phy-ieee802.3-c22"; -+ reg = <3>; -+ interrupts = <3>; -+ phy-mode = "internal"; -+ nvmem-cells = <&phy_calibration_p3>; -+ nvmem-cell-names = "phy-cal-data"; -+ -+ leds { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ gsw_phy3_led0: led@0 { -+ reg = <0>; -+ status = "disabled"; -+ }; -+ -+ gsw_phy3_led1: led@1 { -+ reg = <1>; -+ status = "disabled"; -+ }; -+ }; -+ }; -+ }; -+ }; -+ - ethwarp: clock-controller@15031000 { - compatible = "mediatek,mt7988-ethwarp"; - reg = <0 0x15031000 0 0x1000>; --- -2.51.0 - - -From 7991a17ef4b6834d4ecc1bfb7fa2df0bc2ffff4d Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Sun, 11 May 2025 16:26:50 +0200 -Subject: [PATCH 449/517] arm64: dts: mediatek: mt7988a-bpi-r4: Add fan and - coolingmaps - -Add Fan and cooling maps for Bananpi-R4 board. - -Signed-off-by: Frank Wunderlich ---- - .../dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi | 29 +++++++++++++++++++ - 1 file changed, 29 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi -index 23b267cd47ac..c6f84de82a4d 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi -@@ -12,6 +12,15 @@ chosen { - stdout-path = "serial0:115200n8"; - }; - -+ fan: pwm-fan { -+ compatible = "pwm-fan"; -+ /* cooling level (0, 1, 2, 3) : (0% duty, 30% duty, 50% duty, 100% duty) */ -+ cooling-levels = <0 80 128 255>; -+ #cooling-cells = <2>; -+ pwms = <&pwm 0 50000>; -+ status = "okay"; -+ }; -+ - reg_1p8v: regulator-1p8v { - compatible = "regulator-fixed"; - regulator-name = "fixed-1.8V"; -@@ -73,6 +82,26 @@ cpu_trip_active_low: active-low { - type = "active"; - }; - }; -+ -+ cooling-maps { -+ map-cpu-active-high { -+ /* active: set fan to cooling level 2 */ -+ cooling-device = <&fan 3 3>; -+ trip = <&cpu_trip_active_high>; -+ }; -+ -+ map-cpu-active-med { -+ /* active: set fan to cooling level 1 */ -+ cooling-device = <&fan 2 2>; -+ trip = <&cpu_trip_active_med>; -+ }; -+ -+ map-cpu-active-low { -+ /* active: set fan to cooling level 0 */ -+ cooling-device = <&fan 1 1>; -+ trip = <&cpu_trip_active_low>; -+ }; -+ }; - }; - - &i2c0 { --- -2.51.0 - - -From 34036bee1ee2975448782b641760094739edb0b2 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Sun, 11 May 2025 16:26:51 +0200 -Subject: [PATCH 450/517] arm64: dts: mediatek: mt7988a-bpi-r4: configure - spi-nodes - -Configure and enable SPI nodes on Bananapi R4 board. - -Signed-off-by: Frank Wunderlich ---- - .../dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi | 32 +++++++++++++++++++ - 1 file changed, 32 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi -index c6f84de82a4d..81ba045e0e0e 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi -@@ -401,6 +401,38 @@ &serial0 { - status = "okay"; - }; - -+&spi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_flash_pins>; -+ status = "okay"; -+ -+ spi_nand: flash@0 { -+ compatible = "spi-nand"; -+ reg = <0>; -+ spi-max-frequency = <52000000>; -+ spi-tx-bus-width = <4>; -+ spi-rx-bus-width = <4>; -+ }; -+}; -+ -+&spi1 { -+ status = "okay"; -+}; -+ -+&spi_nand { -+ partitions { -+ compatible = "fixed-partitions"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ partition@0 { -+ label = "bl2"; -+ reg = <0x0 0x200000>; -+ read-only; -+ }; -+ }; -+}; -+ - &ssusb1 { - status = "okay"; - }; --- -2.51.0 - - -From b3d73b099fe717cb56b4a817cb25f08484f84568 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Sun, 11 May 2025 16:26:52 +0200 -Subject: [PATCH 451/517] arm64: dts: mediatek: mt7988a-bpi-r4: add proc-supply - for cci - -CCI requires proc-supply. Add it on board level. - -Signed-off-by: Frank Wunderlich ---- - arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi -index 81ba045e0e0e..afa9e3b2b16a 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi -@@ -40,6 +40,10 @@ reg_3p3v: regulator-3p3v { - }; - }; - -+&cci { -+ proc-supply = <&rt5190_buck3>; -+}; -+ - &cpu0 { - proc-supply = <&rt5190_buck3>; - }; --- -2.51.0 - - -From 0f84f4d23dd468c858924446723397acf590d0dc Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Sun, 11 May 2025 16:26:53 +0200 -Subject: [PATCH 452/517] arm64: dts: mediatek: mt7988a-bpi-r4: add sfp cages - and link to gmac - -Add SFP cages to Bananapi-R4 board. The 2.5g phy variant only contains the -wan-SFP, so add this to common dtsi and the lan-sfp only to the dual-SFP -variant. - -Signed-off-by: Daniel Golle -Signed-off-by: Frank Wunderlich ---- - .../mediatek/mt7988a-bananapi-bpi-r4-2g5.dts | 11 +++++++++++ - .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 18 ++++++++++++++++++ - .../dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi | 18 ++++++++++++++++++ - 3 files changed, 47 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-2g5.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-2g5.dts -index 53de9c113f60..574ac1b853a6 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-2g5.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-2g5.dts -@@ -9,3 +9,14 @@ / { - model = "Banana Pi BPI-R4 (1x SFP+, 1x 2.5GbE)"; - chassis-type = "embedded"; - }; -+ -+&gmac1 { -+ phy-mode = "internal"; -+ phy-connection-type = "internal"; -+ phy = <&int_2p5g_phy>; -+}; -+ -+&int_2p5g_phy { -+ pinctrl-names = "i2p5gbe-led"; -+ pinctrl-0 = <&i2p5gbe_led0_pins>; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -index 36bd1ef2efab..3136dc4ba4cc 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -@@ -8,6 +8,24 @@ / { - compatible = "bananapi,bpi-r4", "mediatek,mt7988a"; - model = "Banana Pi BPI-R4 (2x SFP+)"; - chassis-type = "embedded"; -+ -+ /* SFP2 cage (LAN) */ -+ sfp2: sfp2 { -+ compatible = "sff,sfp"; -+ i2c-bus = <&i2c_sfp2>; -+ los-gpios = <&pio 2 GPIO_ACTIVE_HIGH>; -+ mod-def0-gpios = <&pio 83 GPIO_ACTIVE_LOW>; -+ tx-disable-gpios = <&pio 0 GPIO_ACTIVE_HIGH>; -+ tx-fault-gpios = <&pio 1 GPIO_ACTIVE_HIGH>; -+ rate-select0-gpios = <&pio 3 GPIO_ACTIVE_LOW>; -+ maximum-power-milliwatt = <3000>; -+ }; -+}; -+ -+&gmac1 { -+ sfp = <&sfp2>; -+ managed = "in-band-status"; -+ phy-mode = "usxgmii"; - }; - - &pca9545 { -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi -index afa9e3b2b16a..d40c8dbcd18e 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi -@@ -38,6 +38,18 @@ reg_3p3v: regulator-3p3v { - regulator-boot-on; - regulator-always-on; - }; -+ -+ /* SFP1 cage (WAN) */ -+ sfp1: sfp1 { -+ compatible = "sff,sfp"; -+ i2c-bus = <&i2c_sfp1>; -+ los-gpios = <&pio 54 GPIO_ACTIVE_HIGH>; -+ mod-def0-gpios = <&pio 82 GPIO_ACTIVE_LOW>; -+ tx-disable-gpios = <&pio 70 GPIO_ACTIVE_HIGH>; -+ tx-fault-gpios = <&pio 69 GPIO_ACTIVE_HIGH>; -+ rate-select0-gpios = <&pio 21 GPIO_ACTIVE_LOW>; -+ maximum-power-milliwatt = <3000>; -+ }; - }; - - &cci { -@@ -108,6 +120,12 @@ map-cpu-active-low { - }; - }; - -+&gmac2 { -+ sfp = <&sfp1>; -+ managed = "in-band-status"; -+ phy-mode = "usxgmii"; -+}; -+ - &i2c0 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins>; --- -2.51.0 - - -From 2fb0f965b31d743d149659417366d2dc2fead79e Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Sun, 11 May 2025 16:26:54 +0200 -Subject: [PATCH 453/517] arm64: dts: mediatek: mt7988a-bpi-r4: configure - switch phys and leds - -Assign pinctrl to switch phys and leds. - -Signed-off-by: Daniel Golle -Signed-off-by: Frank Wunderlich ---- - .../dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi | 48 +++++++++++++++++++ - 1 file changed, 48 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi -index d40c8dbcd18e..7258039fda58 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi -@@ -126,6 +126,54 @@ &gmac2 { - phy-mode = "usxgmii"; - }; - -+&gsw_phy0 { -+ pinctrl-names = "gbe-led"; -+ label = "wan"; -+ pinctrl-0 = <&gbe0_led0_pins>; -+}; -+ -+&gsw_phy0_led0 { -+ status = "okay"; -+ function = LED_FUNCTION_WAN; -+ color = ; -+}; -+ -+&gsw_phy1 { -+ pinctrl-names = "gbe-led"; -+ label = "lan1"; -+ pinctrl-0 = <&gbe1_led0_pins>; -+}; -+ -+&gsw_phy1_led0 { -+ status = "okay"; -+ function = LED_FUNCTION_LAN; -+ color = ; -+}; -+ -+&gsw_phy2 { -+ pinctrl-names = "gbe-led"; -+ label = "lan2"; -+ pinctrl-0 = <&gbe2_led0_pins>; -+}; -+ -+&gsw_phy2_led0 { -+ status = "okay"; -+ function = LED_FUNCTION_LAN; -+ color = ; -+}; -+ -+&gsw_phy3 { -+ pinctrl-names = "gbe-led"; -+ label = "lan3"; -+ pinctrl-0 = <&gbe3_led0_pins>; -+}; -+ -+&gsw_phy3_led0 { -+ status = "okay"; -+ function = LED_FUNCTION_LAN; -+ color = ; -+}; -+ - &i2c0 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins>; --- -2.51.0 - - -From 1760d4553e831d99af6db3e3d8825f8930d39c0d Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 8 May 2025 04:03:58 +0100 -Subject: [PATCH 454/517] arm64: dts: mt7988a: add serial1 and serial2 aliases - -Add aliases serial1 and serial2, so boards can make use of the -auxilary UARTs of the MediaTek MT7988 SoC. - -Signed-off-by: Daniel Golle ---- - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index f19e884f13be..52b640f31249 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -297,7 +297,7 @@ serial0: serial@11000000 { - status = "disabled"; - }; - -- serial@11000100 { -+ serial1: serial@11000100 { - compatible = "mediatek,mt7988-uart", "mediatek,mt6577-uart"; - reg = <0 0x11000100 0 0x100>; - interrupts = ; -@@ -308,7 +308,7 @@ serial@11000100 { - status = "disabled"; - }; - -- serial@11000200 { -+ serial2: serial@11000200 { - compatible = "mediatek,mt7988-uart", "mediatek,mt6577-uart"; - reg = <0 0x11000200 0 0x100>; - interrupts = ; --- -2.51.0 - - -From 6161581d6eeb1e01aefde06e5872308860e1100f Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 26 Jun 2025 00:54:32 +0100 -Subject: [PATCH 455/517] arm64: dts: mt7988a: complete dtsi - -Work-in-progress patch to complete mt7988a.dtsi ---- - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 156 +++++++++++++++++++++- - 1 file changed, 154 insertions(+), 2 deletions(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index 52b640f31249..b2338231fab4 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -193,7 +193,7 @@ apmixedsys: clock-controller@1001e000 { - }; - - pio: pinctrl@1001f000 { -- compatible = "mediatek,mt7988-pinctrl"; -+ compatible = "mediatek,mt7988-pinctrl", "syscon"; - reg = <0 0x1001f000 0 0x1000>, - <0 0x11c10000 0 0x1000>, - <0 0x11d00000 0 0x1000>, -@@ -212,6 +212,13 @@ pio: pinctrl@1001f000 { - interrupt-parent = <&gic>; - #interrupt-cells = <2>; - -+ snfi_pins: snfi-pins { -+ mux { -+ function = "flash"; -+ groups = "snfi"; -+ }; -+ }; -+ - pcie0_pins: pcie0-pins { - mux { - function = "pcie"; -@@ -278,6 +285,60 @@ pwm: pwm@10048000 { - status = "disabled"; - }; - -+ sgmiisys0: syscon@10060000 { -+ compatible = "mediatek,mt7988-sgmiisys", -+ "mediatek,mt7988-sgmiisys0", -+ "syscon", -+ "simple-mfd"; -+ reg = <0 0x10060000 0 0x1000>; -+ resets = <&watchdog 1>; -+ #clock-cells = <1>; -+ -+ sgmiipcs0: pcs { -+ compatible = "mediatek,mt7988-sgmii"; -+ clocks = <&topckgen CLK_TOP_SGM_0_SEL>, -+ <&sgmiisys0 CLK_SGM0_TX_EN>, -+ <&sgmiisys0 CLK_SGM0_RX_EN>; -+ clock-names = "sgmii_sel", "sgmii_tx", "sgmii_rx"; -+ #pcs-cells = <0>; -+ }; -+ }; -+ -+ sgmiisys1: syscon@10070000 { -+ compatible = "mediatek,mt7988-sgmiisys", -+ "mediatek,mt7988-sgmiisys1", -+ "syscon", -+ "simple-mfd"; -+ reg = <0 0x10070000 0 0x1000>; -+ resets = <&watchdog 2>; -+ #clock-cells = <1>; -+ -+ sgmiipcs1: pcs { -+ compatible = "mediatek,mt7988-sgmii"; -+ clocks = <&topckgen CLK_TOP_SGM_1_SEL>, -+ <&sgmiisys1 CLK_SGM1_TX_EN>, -+ <&sgmiisys1 CLK_SGM1_RX_EN>; -+ clock-names = "sgmii_sel", "sgmii_tx", "sgmii_rx"; -+ #pcs-cells = <0>; -+ }; -+ }; -+ -+ usxgmiisys0: pcs@10080000 { -+ compatible = "mediatek,mt7988-usxgmiisys"; -+ reg = <0 0x10080000 0 0x1000>; -+ resets = <&watchdog 12>; -+ clocks = <&topckgen CLK_TOP_USXGMII_SBUS_0_SEL>; -+ #pcs-cells = <0>; -+ }; -+ -+ usxgmiisys1: pcs@10081000 { -+ compatible = "mediatek,mt7988-usxgmiisys"; -+ reg = <0 0x10081000 0 0x1000>; -+ resets = <&watchdog 13>; -+ clocks = <&topckgen CLK_TOP_USXGMII_SBUS_1_SEL>; -+ #pcs-cells = <0>; -+ }; -+ - mcusys: mcusys@100e0000 { - compatible = "mediatek,mt7988-mcusys", "syscon"; - reg = <0 0x100e0000 0 0x1000>; -@@ -319,6 +380,32 @@ serial2: serial@11000200 { - status = "disabled"; - }; - -+ snand: spi@11001000 { -+ compatible = "mediatek,mt7986-snand"; -+ reg = <0 0x11001000 0 0x1000>; -+ interrupts = ; -+ clocks = <&infracfg CLK_INFRA_SPINFI>, -+ <&infracfg CLK_INFRA_NFI>, -+ <&infracfg CLK_INFRA_66M_NFI_HCK>; -+ clock-names = "pad_clk", "nfi_clk", "nfi_hclk"; -+ nand-ecc-engine = <&bch>; -+ mediatek,quad-spi; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&snfi_pins>; -+ status = "disabled"; -+ }; -+ -+ bch: ecc@11002000 { -+ compatible = "mediatek,mt7686-ecc"; -+ reg = <0 0x11002000 0 0x1000>; -+ interrupts = ; -+ clocks = <&infracfg CLK_INFRA_NFI>; -+ clock-names = "nfiecc_clk"; -+ status = "disabled"; -+ }; -+ - i2c0: i2c@11003000 { - compatible = "mediatek,mt7981-i2c"; - reg = <0 0x11003000 0 0x1000>, -@@ -425,7 +512,7 @@ phyfw: phy-firmware@f000000 { - <0 0x0f0f0018 0 0x20>; - }; - -- usb@11190000 { -+ ssusb0: usb@11190000 { - compatible = "mediatek,mt7988-xhci", "mediatek,mtk-xhci"; - reg = <0 0x11190000 0 0x2e00>, - <0 0x11193e00 0 0x0100>; -@@ -459,6 +546,35 @@ ssusb1: usb@11200000 { - status = "disabled"; - }; - -+ afe: audio-controller@11210000 { -+ compatible = "mediatek,mt79xx-audio"; -+ reg = <0 0x11210000 0 0x9000>; -+ interrupts = ; -+ clocks = <&infracfg CLK_INFRA_66M_AUD_SLV_BCK>, -+ <&infracfg CLK_INFRA_AUD_26M>, -+ <&infracfg CLK_INFRA_AUD_L>, -+ <&infracfg CLK_INFRA_AUD_AUD>, -+ <&infracfg CLK_INFRA_AUD_EG2>, -+ <&topckgen CLK_TOP_AUD_SEL>, -+ <&topckgen CLK_TOP_AUD_I2S_M>; -+ clock-names = "aud_bus_ck", -+ "aud_26m_ck", -+ "aud_l_ck", -+ "aud_aud_ck", -+ "aud_eg2_ck", -+ "aud_sel", -+ "aud_i2s_m"; -+ assigned-clocks = <&topckgen CLK_TOP_AUD_SEL>, -+ <&topckgen CLK_TOP_A1SYS_SEL>, -+ <&topckgen CLK_TOP_AUD_L_SEL>, -+ <&topckgen CLK_TOP_A_TUNER_SEL>; -+ assigned-clock-parents = <&apmixedsys CLK_APMIXED_APLL2>, -+ <&topckgen CLK_TOP_APLL2_D4>, -+ <&apmixedsys CLK_APMIXED_APLL2>, -+ <&topckgen CLK_TOP_APLL2_D4>; -+ status = "disabled"; -+ }; -+ - mmc0: mmc@11230000 { - compatible = "mediatek,mt7988-mmc"; - reg = <0 0x11230000 0 0x1000>, -@@ -721,6 +837,10 @@ efuse@11f50000 { - #address-cells = <1>; - #size-cells = <1>; - -+ cpufreq_calibration: calib@278 { -+ reg = <0x278 0x1>; -+ }; -+ - lvts_calibration: calib@918 { - reg = <0x918 0x28>; - }; -@@ -984,12 +1104,16 @@ fixed-link { - gmac1: mac@1 { - compatible = "mediatek,eth-mac"; - reg = <1>; -+ pcs-handle = <&sgmiipcs1>, <&usxgmiisys1>; -+ phys = <&xfi_tphy1>; - status = "disabled"; - }; - - gmac2: mac@2 { - compatible = "mediatek,eth-mac"; - reg = <2>; -+ pcs-handle = <&sgmiipcs0>, <&usxgmiisys0>; -+ phys = <&xfi_tphy0>; - status = "disabled"; - }; - -@@ -1002,9 +1126,37 @@ int_2p5g_phy: ethernet-phy@f { - reg = <15>; - compatible = "ethernet-phy-ieee802.3-c45"; - phy-mode = "internal"; -+ -+ leds { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ i2p5gbe_led0: i2p5gbe-led0@0 { -+ reg = <0>; -+ function = LED_FUNCTION_LAN; -+ status = "disabled"; -+ }; -+ -+ i2p5gbe_led1: i2p5gbe-led1@1 { -+ reg = <1>; -+ function = LED_FUNCTION_LAN; -+ status = "disabled"; -+ }; -+ }; - }; - }; - }; -+ -+ crypto: crypto@15600000 { -+ compatible = "inside-secure,safexcel-eip197b"; -+ reg = <0 0x15600000 0 0x180000>; -+ interrupts = , -+ , -+ , -+ ; -+ interrupt-names = "ring0", "ring1", "ring2", "ring3"; -+ status = "okay"; -+ }; - }; - - thermal-zones { --- -2.51.0 - - -From 35fcc31a8c177e9f346b6556757d3e565c83a136 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Wed, 22 Feb 2023 19:15:49 +0000 -Subject: [PATCH 456/517] dts: arm64: mediatek: add MT7988A reference board - device tree - -Complete device tree include for the MediaTek MT7988A SoC and make use -of it by adding the device tree of the MediaTek MT7988A Reference Board -as well as overlays for various options regarding the connected -network interfaces and storage devices present. - -Available options for GMAC1 (eth0): - * internal 4-port 1GE switch - -Available options for GMAC2 (eth1): - * internal 2.5G PHY - * external MaxLinear 2.5G PHY - * external Aquantia AQR113C PHY - * SFP+ cage - -Available options for GMAC3 (eth2): - * external MaxLinear 2.5G PHY - * external Aquantia AQR113C PHY - * SFP+ cage - -Available storage options: - * eMMC - * SNFI (ECC-less SPI-NAND with BCH done in SoC) - * SPI-NAND (with ECC done by the flash die) - * SPI-NOR - * SD card - -Signed-off-by: Sam Shih -Signed-off-by: Daniel Golle ---- - arch/arm64/boot/dts/mediatek/Makefile | 13 + - .../boot/dts/mediatek/mt7988a-rfb-emmc.dtso | 62 +++ - .../dts/mediatek/mt7988a-rfb-eth1-aqr.dtso | 41 ++ - .../mediatek/mt7988a-rfb-eth1-i2p5g-phy.dtso | 30 ++ - .../dts/mediatek/mt7988a-rfb-eth1-mxl.dtso | 39 ++ - .../dts/mediatek/mt7988a-rfb-eth1-sfp.dtso | 47 ++ - .../dts/mediatek/mt7988a-rfb-eth2-aqr.dtso | 41 ++ - .../dts/mediatek/mt7988a-rfb-eth2-mxl.dtso | 39 ++ - .../dts/mediatek/mt7988a-rfb-eth2-sfp.dtso | 47 ++ - .../boot/dts/mediatek/mt7988a-rfb-sd.dtso | 60 +++ - .../dts/mediatek/mt7988a-rfb-snfi-nand.dtso | 85 ++++ - .../mt7988a-rfb-spim-nand-factory.dtso | 87 ++++ - .../dts/mediatek/mt7988a-rfb-spim-nand.dtso | 77 +++ - .../dts/mediatek/mt7988a-rfb-spim-nor.dtso | 69 +++ - arch/arm64/boot/dts/mediatek/mt7988a-rfb.dts | 471 ++++++++++++++++++ - 15 files changed, 1208 insertions(+) - create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a-rfb-emmc.dtso - create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth1-aqr.dtso - create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth1-i2p5g-phy.dtso - create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth1-mxl.dtso - create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth1-sfp.dtso - create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth2-aqr.dtso - create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth2-mxl.dtso - create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth2-sfp.dtso - create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a-rfb-sd.dtso - create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a-rfb-snfi-nand.dtso - create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a-rfb-spim-nand-factory.dtso - create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a-rfb-spim-nand.dtso - create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a-rfb-spim-nor.dtso - create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a-rfb.dts - -diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile -index cd70066352b6..82f7332077c4 100644 ---- a/arch/arm64/boot/dts/mediatek/Makefile -+++ b/arch/arm64/boot/dts/mediatek/Makefile -@@ -24,6 +24,19 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4.dtb - dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-2g5.dtb - dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-emmc.dtbo - dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-sd.dtbo -+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-rfb.dtb -+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-rfb-emmc.dtbo -+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-rfb-eth1-aqr.dtbo -+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-rfb-eth1-i2p5g-phy.dtbo -+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-rfb-eth1-mxl.dtbo -+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-rfb-eth1-sfp.dtbo -+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-rfb-eth2-aqr.dtbo -+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-rfb-eth2-mxl.dtbo -+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-rfb-eth2-sfp.dtbo -+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-rfb-sd.dtbo -+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-rfb-snfi-nand.dtbo -+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-rfb-spim-nand.dtbo -+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-rfb-spim-nor.dtbo - dtb-$(CONFIG_ARCH_MEDIATEK) += mt8167-pumpkin.dtb - dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm.dtb - dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm-hana.dtb -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-rfb-emmc.dtso b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-emmc.dtso -new file mode 100644 -index 000000000000..b430ec3f27b8 ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-emmc.dtso -@@ -0,0 +1,62 @@ -+// SPDX-License-Identifier: (GPL-2.0 OR MIT) -+/* -+ * Copyright (C) 2021 MediaTek Inc. -+ * Author: Frank Wunderlich -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a"; -+ -+ fragment@0 { -+ target = <&mmc0>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-names = "default", "state_uhs"; -+ pinctrl-0 = <&mmc0_pins_emmc_51>; -+ pinctrl-1 = <&mmc0_pins_emmc_51>; -+ bus-width = <8>; -+ max-frequency = <200000000>; -+ cap-mmc-highspeed; -+ mmc-hs200-1_8v; -+ mmc-hs400-1_8v; -+ hs400-ds-delay = <0x12814>; -+ vqmmc-supply = <®_1p8v>; -+ vmmc-supply = <®_3p3v>; -+ non-removable; -+ no-sd; -+ no-sdio; -+ status = "okay"; -+ -+ card@0 { -+ compatible = "mmc-card"; -+ reg = <0>; -+ -+ partitions { -+ compatible = "gpt-partitions"; -+ -+ block-partition-env { -+ partname = "ubootenv"; -+ nvmem-layout { -+ compatible = "u-boot,env-layout"; -+ }; -+ }; -+ -+ emmc_root: block-partition-production { -+ partname = "production"; -+ }; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target-path = "/chosen"; -+ __overlay__ { -+ rootdisk-emmc = <&emmc_root>; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth1-aqr.dtso b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth1-aqr.dtso -new file mode 100644 -index 000000000000..d21a61ad19fe ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth1-aqr.dtso -@@ -0,0 +1,41 @@ -+// SPDX-License-Identifier: (GPL-2.0 OR MIT) -+/* -+ * Copyright (C) 2022 MediaTek Inc. -+ * Author: Sam.Shih -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+#include -+ -+/ { -+ compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a"; -+ -+ fragment@0 { -+ target = <&mdio_bus>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ /* external Aquantia AQR113C */ -+ phy0: ethernet-phy@0 { -+ reg = <0>; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ reset-gpios = <&pio 72 GPIO_ACTIVE_LOW>; -+ reset-assert-us = <100000>; -+ reset-deassert-us = <221000>; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gmac1>; -+ __overlay__ { -+ phy-mode = "usxgmii"; -+ phy-connection-type = "usxgmii"; -+ phy = <&phy0>; -+ status = "okay"; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth1-i2p5g-phy.dtso b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth1-i2p5g-phy.dtso -new file mode 100644 -index 000000000000..86ab7566dc29 ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth1-i2p5g-phy.dtso -@@ -0,0 +1,30 @@ -+// SPDX-License-Identifier: (GPL-2.0 OR MIT) -+/* -+ * Copyright (C) 2022 MediaTek Inc. -+ * Author: Sam.Shih -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a"; -+ -+ fragment@0 { -+ target = <&gmac1>; -+ __overlay__ { -+ phy-mode = "internal"; -+ phy-connection-type = "internal"; -+ phy = <&int_2p5g_phy>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&int_2p5g_phy>; -+ __overlay__ { -+ pinctrl-names = "i2p5gbe-led"; -+ pinctrl-0 = <&i2p5gbe_led0_pins>; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth1-mxl.dtso b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth1-mxl.dtso -new file mode 100644 -index 000000000000..34a23bbd7eb0 ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth1-mxl.dtso -@@ -0,0 +1,39 @@ -+// SPDX-License-Identifier: (GPL-2.0 OR MIT) -+/* -+ * Copyright (C) 2022 MediaTek Inc. -+ * Author: Sam.Shih -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+#include -+ -+/ { -+ compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a"; -+ -+ fragment@0 { -+ target = <&mdio_bus>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ /* external Maxlinear GPY211C */ -+ phy13: ethernet-phy@13 { -+ reg = <13>; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ phy-mode = "2500base-x"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gmac1>; -+ __overlay__ { -+ phy-mode = "2500base-x"; -+ phy-connection-type = "2500base-x"; -+ phy = <&phy13>; -+ status = "okay"; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth1-sfp.dtso b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth1-sfp.dtso -new file mode 100644 -index 000000000000..ef5e4b360441 ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth1-sfp.dtso -@@ -0,0 +1,47 @@ -+// SPDX-License-Identifier: (GPL-2.0 OR MIT) -+/* -+ * Copyright (C) 2022 MediaTek Inc. -+ * Author: Sam.Shih -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+#include -+ -+/ { -+ compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a"; -+ -+ fragment@0 { -+ target = <&i2c2>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c2_pins>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target-path = "/"; -+ __overlay__ { -+ sfp_esp1: sfp@1 { -+ compatible = "sff,sfp"; -+ i2c-bus = <&i2c2>; -+ mod-def0-gpios = <&pio 82 GPIO_ACTIVE_LOW>; -+ los-gpios = <&pio 81 GPIO_ACTIVE_HIGH>; -+ tx-disable-gpios = <&pio 36 GPIO_ACTIVE_HIGH>; -+ maximum-power-milliwatt = <3000>; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&gmac1>; -+ __overlay__ { -+ phy-mode = "10gbase-r"; -+ managed = "in-band-status"; -+ sfp = <&sfp_esp1>; -+ status = "okay"; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth2-aqr.dtso b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth2-aqr.dtso -new file mode 100644 -index 000000000000..140391fc45a8 ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth2-aqr.dtso -@@ -0,0 +1,41 @@ -+// SPDX-License-Identifier: (GPL-2.0 OR MIT) -+/* -+ * Copyright (C) 2022 MediaTek Inc. -+ * Author: Sam.Shih -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+#include -+ -+/ { -+ compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a"; -+ -+ fragment@0 { -+ target = <&mdio_bus>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ /* external Aquantia AQR113C */ -+ phy8: ethernet-phy@8 { -+ reg = <8>; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ reset-gpios = <&pio 71 GPIO_ACTIVE_LOW>; -+ reset-assert-us = <100000>; -+ reset-deassert-us = <221000>; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gmac2>; -+ __overlay__ { -+ phy-mode = "usxgmii"; -+ phy-connection-type = "usxgmii"; -+ phy = <&phy8>; -+ status = "okay"; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth2-mxl.dtso b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth2-mxl.dtso -new file mode 100644 -index 000000000000..19e0b2799fc8 ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth2-mxl.dtso -@@ -0,0 +1,39 @@ -+// SPDX-License-Identifier: (GPL-2.0 OR MIT) -+/* -+ * Copyright (C) 2022 MediaTek Inc. -+ * Author: Sam.Shih -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+#include -+ -+/ { -+ compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a"; -+ -+ fragment@0 { -+ target = <&mdio_bus>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ /* external Maxlinear GPY211C */ -+ phy5: ethernet-phy@5 { -+ reg = <5>; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ phy-mode = "2500base-x"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gmac2>; -+ __overlay__ { -+ phy-mode = "2500base-x"; -+ phy-connection-type = "2500base-x"; -+ phy = <&phy5>; -+ status = "okay"; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth2-sfp.dtso b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth2-sfp.dtso -new file mode 100644 -index 000000000000..83d65322eb0e ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth2-sfp.dtso -@@ -0,0 +1,47 @@ -+// SPDX-License-Identifier: (GPL-2.0 OR MIT) -+/* -+ * Copyright (C) 2022 MediaTek Inc. -+ * Author: Sam.Shih -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+#include -+ -+/ { -+ compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a"; -+ -+ fragment@0 { -+ target = <&i2c1>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target-path = "/"; -+ __overlay__ { -+ sfp_esp0: sfp@0 { -+ compatible = "sff,sfp"; -+ i2c-bus = <&i2c1>; -+ mod-def0-gpios = <&pio 35 GPIO_ACTIVE_LOW>; -+ los-gpios = <&pio 33 GPIO_ACTIVE_HIGH>; -+ tx-disable-gpios = <&pio 29 GPIO_ACTIVE_HIGH>; -+ maximum-power-milliwatt = <3000>; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&gmac2>; -+ __overlay__ { -+ phy-mode = "10gbase-r"; -+ managed = "in-band-status"; -+ sfp = <&sfp_esp0>; -+ status = "okay"; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-rfb-sd.dtso b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-sd.dtso -new file mode 100644 -index 000000000000..9a06c425a0b2 ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-sd.dtso -@@ -0,0 +1,60 @@ -+// SPDX-License-Identifier: (GPL-2.0 OR MIT) -+/* -+ * Copyright (C) 2023 MediaTek Inc. -+ * Author: Frank Wunderlich -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+#include -+ -+/ { -+ compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a"; -+ -+ fragment@0 { -+ target-path = <&mmc0>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-names = "default", "state_uhs"; -+ pinctrl-0 = <&mmc0_pins_sdcard>; -+ pinctrl-1 = <&mmc0_pins_sdcard>; -+ cd-gpios = <&pio 69 GPIO_ACTIVE_LOW>; -+ bus-width = <4>; -+ max-frequency = <52000000>; -+ cap-sd-highspeed; -+ vmmc-supply = <®_3p3v>; -+ vqmmc-supply = <®_3p3v>; -+ no-mmc; -+ status = "okay"; -+ -+ card@0 { -+ compatible = "mmc-card"; -+ reg = <0>; -+ -+ partitions { -+ compatible = "gpt-partitions"; -+ -+ block-partition-env { -+ partname = "ubootenv"; -+ nvmem-layout { -+ compatible = "u-boot,env-layout"; -+ }; -+ }; -+ -+ sd_root: block-partition-production { -+ partname = "production"; -+ }; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target-path = "/chosen"; -+ __overlay__ { -+ rootdisk-sd = <&sd_root>; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-rfb-snfi-nand.dtso b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-snfi-nand.dtso -new file mode 100644 -index 000000000000..f334de82e9d4 ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-snfi-nand.dtso -@@ -0,0 +1,85 @@ -+// SPDX-License-Identifier: (GPL-2.0 OR MIT) -+/* -+ * Copyright (C) 2022 MediaTek Inc. -+ * Author: Sam.Shih -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a"; -+ -+ fragment@0 { -+ target = <&snand>; -+ __overlay__ { -+ status = "okay"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ flash@0 { -+ compatible = "spi-nand"; -+ reg = <0>; -+ spi-max-frequency = <52000000>; -+ spi-tx-bus-width = <4>; -+ spi-rx-bus-width = <4>; -+ -+ partitions { -+ compatible = "fixed-partitions"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ partition@0 { -+ label = "BL2"; -+ reg = <0x00000 0x0200000>; -+ read-only; -+ }; -+ -+ ubi_part: partition@200000 { -+ label = "ubi"; -+ reg = <0x0200000 0x7e00000>; -+ compatible = "linux,ubi"; -+ -+ volumes { -+ ubi-volume-ubootenv { -+ volname = "ubootenv"; -+ nvmem-layout { -+ compatible = "u-boot,env-redundant-bool"; -+ }; -+ }; -+ -+ ubi-volume-ubootenv2 { -+ volname = "ubootenv2"; -+ nvmem-layout { -+ compatible = "u-boot,env-redundant-bool"; -+ }; -+ }; -+ -+ snfi_root: ubi-volume-fit { -+ volname = "fit"; -+ }; -+ }; -+ }; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&bch>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target-path = "/chosen"; -+ __overlay__ { -+ /* -+ * U-Boot currently cannot detect diffrentiate between -+ * SD and SNFI boot media and always uses rootdisk-sd in -+ * both cases -+ */ -+ rootdisk-sd = <&snfi_root>; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-rfb-spim-nand-factory.dtso b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-spim-nand-factory.dtso -new file mode 100644 -index 000000000000..4b554a1bdeb4 ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-spim-nand-factory.dtso -@@ -0,0 +1,87 @@ -+// SPDX-License-Identifier: (GPL-2.0 OR MIT) -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a"; -+ -+ fragment@0 { -+ target = <&ubi_part>; -+ -+ __overlay__ { -+ volumes { -+ ubi_factory: ubi-volume-factory { -+ volname = "factory"; -+ -+ nvmem-layout { -+ compatible = "fixed-layout"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ eeprom_wmac: eeprom@0 { -+ reg = <0x0 0x1e00>; -+ }; -+ -+ gmac2_mac: eeprom@fffee { -+ reg = <0xfffee 0x6>; -+ }; -+ -+ gmac1_mac: eeprom@ffff4 { -+ reg = <0xffff4 0x6>; -+ }; -+ -+ gmac0_mac: eeprom@ffffa { -+ reg = <0xffffa 0x6>; -+ }; -+ }; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&pcie0>; -+ __overlay__ { -+ #address-cells = <3>; -+ #size-cells = <2>; -+ -+ pcie@0,0 { -+ reg = <0x0000 0 0 0 0>; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ -+ wifi@0,0 { -+ compatible = "mediatek,mt76"; -+ reg = <0x0000 0 0 0 0>; -+ nvmem-cell-names = "eeprom"; -+ nvmem-cells = <&eeprom_wmac>; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&gmac0>; -+ __overlay__ { -+ nvmem-cell-names = "mac-address"; -+ nvmem-cells = <&gmac0_mac>; -+ }; -+ }; -+ -+ fragment@3 { -+ target = <&gmac1>; -+ __overlay__ { -+ nvmem-cell-names = "mac-address"; -+ nvmem-cells = <&gmac1_mac>; -+ }; -+ }; -+ -+ fragment@4 { -+ target = <&gmac2>; -+ __overlay__ { -+ nvmem-cell-names = "mac-address"; -+ nvmem-cells = <&gmac2_mac>; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-rfb-spim-nand.dtso b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-spim-nand.dtso -new file mode 100644 -index 000000000000..e7efd375620d ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-spim-nand.dtso -@@ -0,0 +1,77 @@ -+// SPDX-License-Identifier: (GPL-2.0 OR MIT) -+/* -+ * Copyright (C) 2022 MediaTek Inc. -+ * Author: Sam.Shih -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_flash_pins>; -+ status = "okay"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ flash@0 { -+ compatible = "spi-nand"; -+ reg = <0>; -+ spi-max-frequency = <52000000>; -+ spi-tx-bus-width = <4>; -+ spi-rx-bus-width = <4>; -+ -+ partitions { -+ compatible = "fixed-partitions"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ partition@0 { -+ label = "BL2"; -+ reg = <0x00000 0x0200000>; -+ read-only; -+ }; -+ -+ ubi_part: partition@200000 { -+ label = "ubi"; -+ reg = <0x0200000 0x7e00000>; -+ compatible = "linux,ubi"; -+ -+ volumes { -+ ubi-volume-ubootenv { -+ volname = "ubootenv"; -+ nvmem-layout { -+ compatible = "u-boot,env-redundant-bool"; -+ }; -+ }; -+ -+ ubi-volume-ubootenv2 { -+ volname = "ubootenv2"; -+ nvmem-layout { -+ compatible = "u-boot,env-redundant-bool"; -+ }; -+ }; -+ -+ ubi_root: ubi-volume-fit { -+ volname = "fit"; -+ }; -+ -+ }; -+ }; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target-path = "/chosen"; -+ __overlay__ { -+ rootdisk-spim-nand = <&ubi_root>; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-rfb-spim-nor.dtso b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-spim-nor.dtso -new file mode 100644 -index 000000000000..4c9bc70ff712 ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-spim-nor.dtso -@@ -0,0 +1,69 @@ -+// SPDX-License-Identifier: (GPL-2.0 OR MIT) -+/* -+ * Copyright (C) 2022 MediaTek Inc. -+ * Author: Sam.Shih -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a"; -+ -+ fragment@0 { -+ target = <&spi2>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi2_flash_pins>; -+ status = "okay"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ flash@0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "jedec,spi-nor"; -+ spi-cal-enable; -+ spi-cal-mode = "read-data"; -+ spi-cal-datalen = <7>; -+ spi-cal-data = /bits/ 8 < -+ 0x53 0x46 0x5F 0x42 0x4F 0x4F 0x54>; /* SF_BOOT */ -+ spi-cal-addrlen = <1>; -+ spi-cal-addr = /bits/ 32 <0x0>; -+ reg = <0>; -+ spi-max-frequency = <52000000>; -+ spi-tx-bus-width = <4>; -+ spi-rx-bus-width = <4>; -+ -+ partition@0 { -+ label = "BL2"; -+ reg = <0x0 0x40000>; -+ }; -+ partition@40000 { -+ label = "u-boot-env"; -+ reg = <0x40000 0x10000>; -+ }; -+ partition@50000 { -+ label = "Factory"; -+ reg = <0x50000 0x200000>; -+ }; -+ partition@250000 { -+ label = "FIP"; -+ reg = <0x250000 0x80000>; -+ }; -+ nor_root: partition@2D0000 { -+ label = "firmware"; -+ reg = <0x2d0000 0x1d30000>; -+ compatible = "denx,fit"; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target-path = "/chosen"; -+ __overlay__ { -+ rootdisk-nor = <&nor_root>; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-rfb.dts b/arch/arm64/boot/dts/mediatek/mt7988a-rfb.dts -new file mode 100644 -index 000000000000..01989041d9c2 ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-rfb.dts -@@ -0,0 +1,471 @@ -+// SPDX-License-Identifier: (GPL-2.0 OR MIT) -+/* -+ * Copyright (C) 2022 MediaTek Inc. -+ * Author: Sam.Shih -+ */ -+ -+/dts-v1/; -+#include -+#include -+#include -+ -+#include "mt7988a.dtsi" -+ -+/ { -+ model = "MediaTek MT7988A Reference Board"; -+ compatible = "mediatek,mt7988a-rfb", -+ "mediatek,mt7988a"; -+ -+ chosen { -+ bootargs = "console=ttyS0,115200n1 \ -+ earlycon=uart8250,mmio32,0x11000000 \ -+ pci=pcie_bus_perf"; -+ }; -+ -+ memory@40000000 { -+ reg = <0 0x40000000 0 0x40000000>; -+ device_type = "memory"; -+ }; -+ -+ reg_1p8v: regulator-1p8v { -+ compatible = "regulator-fixed"; -+ regulator-name = "fixed-1.8V"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ reg_3p3v: regulator-3p3v { -+ compatible = "regulator-fixed"; -+ regulator-name = "fixed-3.3V"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+}; -+ -+ð { -+ pinctrl-0 = <&mdio0_pins>; -+ pinctrl-names = "default"; -+}; -+ -+&gmac0 { -+ status = "okay"; -+}; -+ -+&cpu0 { -+ proc-supply = <&rt5190_buck3>; -+}; -+ -+&cpu1 { -+ proc-supply = <&rt5190_buck3>; -+}; -+ -+&cpu2 { -+ proc-supply = <&rt5190_buck3>; -+}; -+ -+&cpu3 { -+ proc-supply = <&rt5190_buck3>; -+}; -+ -+&cci { -+ proc-supply = <&rt5190_buck3>; -+}; -+ -+ð { -+ status = "okay"; -+}; -+ -+&switch { -+ status = "okay"; -+}; -+ -+&gsw_phy0 { -+ pinctrl-names = "gbe-led"; -+ pinctrl-0 = <&gbe0_led0_pins>; -+}; -+ -+&gsw_phy0_led0 { -+ status = "okay"; -+ function = LED_FUNCTION_LAN; -+ color = ; -+}; -+ -+&gsw_port0 { -+ label = "lan0"; -+}; -+ -+&gsw_phy1 { -+ pinctrl-names = "gbe-led"; -+ pinctrl-0 = <&gbe1_led0_pins>; -+}; -+ -+&gsw_phy1_led0 { -+ status = "okay"; -+ function = LED_FUNCTION_LAN; -+ color = ; -+}; -+ -+&gsw_port1 { -+ label = "lan1"; -+}; -+ -+&gsw_phy2 { -+ pinctrl-names = "gbe-led"; -+ pinctrl-0 = <&gbe2_led0_pins>; -+}; -+ -+&gsw_phy2_led0 { -+ status = "okay"; -+ function = LED_FUNCTION_LAN; -+ color = ; -+}; -+ -+&gsw_port2 { -+ label = "lan2"; -+}; -+ -+&gsw_phy3 { -+ pinctrl-names = "gbe-led"; -+ pinctrl-0 = <&gbe3_led0_pins>; -+}; -+ -+&gsw_phy3_led0 { -+ status = "okay"; -+ function = LED_FUNCTION_LAN; -+ color = ; -+}; -+ -+&gsw_port3 { -+ label = "lan3"; -+}; -+ -+&i2c0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_pins>; -+ status = "okay"; -+ -+ rt5190a_64: rt5190a@64 { -+ compatible = "richtek,rt5190a"; -+ reg = <0x64>; -+ /*interrupts-extended = <&gpio26 0 IRQ_TYPE_LEVEL_LOW>;*/ -+ vin2-supply = <&rt5190_buck1>; -+ vin3-supply = <&rt5190_buck1>; -+ vin4-supply = <&rt5190_buck1>; -+ -+ regulators { -+ rt5190_buck1: buck1 { -+ regulator-name = "rt5190a-buck1"; -+ regulator-min-microvolt = <5090000>; -+ regulator-max-microvolt = <5090000>; -+ regulator-allowed-modes = -+ ; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ buck2 { -+ regulator-name = "vcore"; -+ regulator-min-microvolt = <600000>; -+ regulator-max-microvolt = <1400000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ rt5190_buck3: buck3 { -+ regulator-name = "vproc"; -+ regulator-min-microvolt = <600000>; -+ regulator-max-microvolt = <1400000>; -+ regulator-boot-on; -+ }; -+ buck4 { -+ regulator-name = "rt5190a-buck4"; -+ regulator-min-microvolt = <850000>; -+ regulator-max-microvolt = <850000>; -+ regulator-allowed-modes = -+ ; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ ldo { -+ regulator-name = "rt5190a-ldo"; -+ regulator-min-microvolt = <1200000>; -+ regulator-max-microvolt = <1200000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ }; -+ }; -+}; -+ -+&pcie0 { -+ status = "okay"; -+}; -+ -+&pcie1 { -+ status = "okay"; -+}; -+ -+&pcie2 { -+ status = "disabled"; -+}; -+ -+&pcie3 { -+ status = "okay"; -+}; -+ -+&pio { -+ mdio0_pins: mdio0-pins { -+ mux { -+ function = "eth"; -+ groups = "mdc_mdio0"; -+ }; -+ -+ conf { -+ groups = "mdc_mdio0"; -+ drive-strength = ; -+ }; -+ }; -+ -+ gbe0_led0_pins: gbe0-led0-pins { -+ mux { -+ function = "led"; -+ groups = "gbe0_led0"; -+ }; -+ }; -+ -+ gbe1_led0_pins: gbe1-led0-pins { -+ mux { -+ function = "led"; -+ groups = "gbe1_led0"; -+ }; -+ }; -+ -+ gbe2_led0_pins: gbe2-led0-pins { -+ mux { -+ function = "led"; -+ groups = "gbe2_led0"; -+ }; -+ }; -+ -+ gbe3_led0_pins: gbe3-led0-pins { -+ mux { -+ function = "led"; -+ groups = "gbe3_led0"; -+ }; -+ }; -+ -+ gbe0_led1_pins: gbe0-led1-pins { -+ mux { -+ function = "led"; -+ groups = "gbe0_led1"; -+ }; -+ }; -+ -+ gbe1_led1_pins: gbe1-led1-pins { -+ mux { -+ function = "led"; -+ groups = "gbe1_led1"; -+ }; -+ }; -+ -+ gbe2_led1_pins: gbe2-led1-pins { -+ mux { -+ function = "led"; -+ groups = "gbe2_led1"; -+ }; -+ }; -+ -+ gbe3_led1_pins: gbe3-led1-pins { -+ mux { -+ function = "led"; -+ groups = "gbe3_led1"; -+ }; -+ }; -+ -+ i2c0_pins: i2c0-g0-pins { -+ mux { -+ function = "i2c"; -+ groups = "i2c0_1"; -+ }; -+ }; -+ -+ i2c1_pins: i2c1-g0-pins { -+ mux { -+ function = "i2c"; -+ groups = "i2c1_0"; -+ }; -+ }; -+ -+ i2c1_sfp_pins: i2c1-sfp-g0-pins { -+ mux { -+ function = "i2c"; -+ groups = "i2c1_sfp"; -+ }; -+ }; -+ -+ i2c2_0_pins: i2c2-g0-pins { -+ mux { -+ function = "i2c"; -+ groups = "i2c2_0"; -+ }; -+ }; -+ -+ i2c2_1_pins: i2c2-g1-pins { -+ mux { -+ function = "i2c"; -+ groups = "i2c2_1"; -+ }; -+ }; -+ -+ i2p5gbe_led0_pins: 2p5gbe-led0-pins { -+ mux { -+ function = "led"; -+ groups = "2p5gbe_led0"; -+ }; -+ }; -+ -+ i2p5gbe_led1_pins: 2p5gbe-led1-pins { -+ mux { -+ function = "led"; -+ groups = "2p5gbe_led1"; -+ }; -+ }; -+ -+ mmc0_pins_emmc_51: mmc0-emmc-51-pins { -+ mux { -+ function = "flash"; -+ groups = "emmc_51"; -+ }; -+ }; -+ -+ mmc0_pins_sdcard: mmc0-sdcard-pins { -+ mux { -+ function = "flash"; -+ groups = "sdcard"; -+ }; -+ }; -+ -+ spi0_pins: spi0-pins { -+ mux { -+ function = "spi"; -+ groups = "spi0"; -+ }; -+ }; -+ -+ spi0_flash_pins: spi0-flash-pins { -+ mux { -+ function = "spi"; -+ groups = "spi0", "spi0_wp_hold"; -+ }; -+ }; -+ -+ spi2_pins: spi2-pins { -+ mux { -+ function = "spi"; -+ groups = "spi2"; -+ }; -+ }; -+ -+ spi2_flash_pins: spi2-flash-pins { -+ mux { -+ function = "spi"; -+ groups = "spi2", "spi2_wp_hold"; -+ }; -+ }; -+ -+ uart0_pins: uart0-pins { -+ mux { -+ function = "uart"; -+ groups = "uart0"; -+ }; -+ }; -+ -+ uart1_0_pins: uart1-0-pins { -+ mux { -+ function = "uart"; -+ groups = "uart1_0"; -+ }; -+ }; -+ -+ uart1_1_pins: uart1-1-pins { -+ mux { -+ function = "uart"; -+ groups = "uart1_1"; -+ }; -+ }; -+ -+ uart1_2_pins: uart1-2-pins { -+ mux { -+ function = "uart"; -+ groups = "uart1_2"; -+ }; -+ }; -+ -+ uart1_2_lite_pins: uart1-2-lite-pins { -+ mux { -+ function = "uart"; -+ groups = "uart1_2_lite"; -+ }; -+ }; -+ -+ uart2_pins: uart2-pins { -+ mux { -+ function = "uart"; -+ groups = "uart2"; -+ }; -+ }; -+ -+ uart2_0_pins: uart2-0-pins { -+ mux { -+ function = "uart"; -+ groups = "uart2_0"; -+ }; -+ }; -+ -+ uart2_1_pins: uart2-1-pins { -+ mux { -+ function = "uart"; -+ groups = "uart2_1"; -+ }; -+ }; -+ -+ uart2_2_pins: uart2-2-pins { -+ mux { -+ function = "uart"; -+ groups = "uart2_2"; -+ }; -+ }; -+ -+ uart2_3_pins: uart2-3-pins { -+ mux { -+ function = "uart"; -+ groups = "uart2_3"; -+ }; -+ }; -+}; -+ -+&ssusb0 { -+ status = "okay"; -+}; -+ -+&ssusb1 { -+ status = "okay"; -+}; -+ -+&tphy { -+ status = "okay"; -+}; -+ -+&serial0 { -+ status = "okay"; -+}; -+ -+&watchdog { -+ status = "okay"; -+}; -+ -+&xsphy { -+ status = "okay"; -+}; --- -2.51.0 - - -From bee4aa5461f67063cafc2a29b4049e844c637b7e Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Wed, 26 Jul 2023 14:56:28 +0100 -Subject: [PATCH 457/517] WIP: add BPi-R4 - ---- - .../mediatek/mt7988a-bananapi-bpi-r4-2g5.dts | 13 + - .../mt7988a-bananapi-bpi-r4-emmc.dtso | 56 ++++ - .../mediatek/mt7988a-bananapi-bpi-r4-rtc.dtso | 19 ++ - .../mediatek/mt7988a-bananapi-bpi-r4-sd.dtso | 54 ++++ - .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 8 + - .../dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi | 241 +++++++++++++----- - 6 files changed, 328 insertions(+), 63 deletions(-) - create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtso - create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-rtc.dtso - create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-sd.dtso - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-2g5.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-2g5.dts -index 574ac1b853a6..a88bc88576d6 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-2g5.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-2g5.dts -@@ -20,3 +20,16 @@ &int_2p5g_phy { - pinctrl-names = "i2p5gbe-led"; - pinctrl-0 = <&i2p5gbe_led0_pins>; - }; -+ -+&gmac1 { -+ phy-mode = "internal"; -+ phy-connection-type = "internal"; -+ phy = <&int_2p5g_phy>; -+ openwrt,netdev-name = "lan4"; -+ status = "okay"; -+}; -+ -+&int_2p5g_phy { -+ pinctrl-names = "i2p5gbe-led"; -+ pinctrl-0 = <&i2p5gbe_led0_pins>; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtso b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtso -new file mode 100644 -index 000000000000..92cf2a2e2b53 ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtso -@@ -0,0 +1,56 @@ -+// SPDX-License-Identifier: (GPL-2.0 OR MIT) -+/* -+ * Copyright (C) 2021 MediaTek Inc. -+ * Author: Frank Wunderlich -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "bananapi,bpi-r4", "mediatek,mt7988a"; -+}; -+ -+&{/soc/mmc@11230000} { -+ pinctrl-names = "default", "state_uhs"; -+ pinctrl-0 = <&mmc0_pins_emmc_51>; -+ pinctrl-1 = <&mmc0_pins_emmc_51>; -+ bus-width = <8>; -+ max-frequency = <200000000>; -+ cap-mmc-highspeed; -+ mmc-hs200-1_8v; -+ mmc-hs400-1_8v; -+ hs400-ds-delay = <0x12814>; -+ vqmmc-supply = <®_1p8v>; -+ vmmc-supply = <®_3p3v>; -+ non-removable; -+ no-sd; -+ no-sdio; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ card@0 { -+ compatible = "mmc-card"; -+ reg = <0>; -+ -+ partitions { -+ compatible = "gpt-partitions"; -+ -+ block-partition-env { -+ partname = "ubootenv"; -+ nvmem-layout { -+ compatible = "u-boot,env-layout"; -+ }; -+ }; -+ -+ emmc_rootfs: block-partition-production { -+ partname = "production"; -+ }; -+ }; -+ }; -+}; -+ -+&{/chosen} { -+ rootdisk-emmc = <&emmc_rootfs>; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-rtc.dtso b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-rtc.dtso -new file mode 100644 -index 000000000000..39910b8cfee1 ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-rtc.dtso -@@ -0,0 +1,19 @@ -+// SPDX-License-Identifier: (GPL-2.0 OR MIT) -+/* -+ * Copyright (C) 2023 -+ * Author: Daniel Golle -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "bananapi,bpi-r4", "mediatek,mt7988a"; -+ -+ fragment@0 { -+ target = <&pcf8563>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-sd.dtso b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-sd.dtso -new file mode 100644 -index 000000000000..8c74010998cb ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-sd.dtso -@@ -0,0 +1,54 @@ -+// SPDX-License-Identifier: (GPL-2.0 OR MIT) -+/* -+ * Copyright (C) 2023 MediaTek Inc. -+ * Author: Frank Wunderlich -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+#include -+ -+/ { -+ compatible = "bananapi,bpi-r4", "mediatek,mt7988a"; -+}; -+ -+&{/soc/mmc@11230000} { -+ pinctrl-names = "default", "state_uhs"; -+ pinctrl-0 = <&mmc0_pins_sdcard>; -+ pinctrl-1 = <&mmc0_pins_sdcard>; -+ cd-gpios = <&pio 12 GPIO_ACTIVE_LOW>; -+ bus-width = <4>; -+ max-frequency = <52000000>; -+ cap-sd-highspeed; -+ vmmc-supply = <®_3p3v>; -+ vqmmc-supply = <®_3p3v>; -+ no-mmc; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ card@0 { -+ compatible = "mmc-card"; -+ reg = <0>; -+ -+ partitions { -+ compatible = "gpt-partitions"; -+ -+ block-partition-env { -+ partname = "ubootenv"; -+ nvmem-layout { -+ compatible = "u-boot,env-layout"; -+ }; -+ }; -+ -+ sd_rootfs: block-partition-production { -+ partname = "production"; -+ }; -+ }; -+ }; -+}; -+ -+&{/chosen} { -+ rootdisk-sd = <&sd_rootfs>; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -index 3136dc4ba4cc..bab30961d6c4 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts -@@ -35,3 +35,11 @@ i2c_sfp2: i2c@2 { - reg = <2>; - }; - }; -+ -+&gmac1 { -+ sfp = <&sfp2>; -+ managed = "in-band-status"; -+ phy-mode = "usxgmii"; -+ openwrt,netdev-name = "sfp-lan"; -+ status = "okay"; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi -index 7258039fda58..f22e5737750c 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi -@@ -3,6 +3,8 @@ - /dts-v1/; - - #include -+#include -+#include - #include - - #include "mt7988a.dtsi" -@@ -10,6 +12,8 @@ - / { - chosen { - stdout-path = "serial0:115200n8"; -+ bootargs = "console=ttyS0,115200n1 pci=pcie_bus_perf ubi.block=0,fit root=/dev/fit0"; -+ rootdisk-spim-nand = <&ubi_rootfs>; - }; - - fan: pwm-fan { -@@ -50,6 +54,142 @@ sfp1: sfp1 { - rate-select0-gpios = <&pio 21 GPIO_ACTIVE_LOW>; - maximum-power-milliwatt = <3000>; - }; -+ -+ aliases { -+ ethernet0 = &gmac0; -+ ethernet1 = &gmac1; -+ ethernet2 = &gmac2; -+ serial0 = &serial0; -+ led-boot = &led_green; -+ led-failsafe = &led_green; -+ led-running = &led_green; -+ led-upgrade = &led_green; -+ }; -+ -+ memory@40000000 { -+ reg = <0x00 0x40000000 0x00 0x10000000>; -+ device_type = "memory"; -+ }; -+ -+ /* SFP1 cage (WAN) */ -+ sfp1: sfp1 { -+ compatible = "sff,sfp"; -+ i2c-bus = <&i2c_sfp1>; -+ los-gpios = <&pio 54 GPIO_ACTIVE_HIGH>; -+ mod-def0-gpios = <&pio 82 GPIO_ACTIVE_LOW>; -+ tx-disable-gpios = <&pio 70 GPIO_ACTIVE_HIGH>; -+ tx-fault-gpios = <&pio 69 GPIO_ACTIVE_HIGH>; -+ rate-select0-gpios = <&pio 21 GPIO_ACTIVE_LOW>; -+ maximum-power-milliwatt = <3000>; -+ }; -+ -+ gpio-keys { -+ compatible = "gpio-keys"; -+ -+ wps { -+ label = "WPS"; -+ linux,code = ; -+ gpios = <&pio 14 GPIO_ACTIVE_LOW>; -+ }; -+ }; -+ -+ gpio-leds { -+ compatible = "gpio-leds"; -+ -+ led_green: led-green { -+ function = LED_FUNCTION_STATUS; -+ color = ; -+ gpios = <&pio 79 GPIO_ACTIVE_HIGH>; -+ default-state = "on"; -+ }; -+ -+ led_blue: led-blue { -+ function = LED_FUNCTION_WPS; -+ color = ; -+ gpios = <&pio 63 GPIO_ACTIVE_HIGH>; -+ default-state = "off"; -+ }; -+ }; -+}; -+ -+ð { -+ status = "okay"; -+}; -+ -+&gmac0 { -+ status = "okay"; -+}; -+ -+&gmac2 { -+ sfp = <&sfp1>; -+ managed = "in-band-status"; -+ phy-mode = "usxgmii"; -+ openwrt,netdev-name = "sfp-wan"; -+ status = "okay"; -+}; -+ -+&switch { -+ status = "okay"; -+}; -+ -+&gsw_phy0 { -+ pinctrl-names = "gbe-led"; -+ pinctrl-0 = <&gbe0_led0_pins>; -+}; -+ -+&gsw_port0 { -+ label = "wan"; -+}; -+ -+&gsw_phy0_led0 { -+ status = "okay"; -+ function = LED_FUNCTION_WAN; -+ color = ; -+}; -+ -+&gsw_phy1 { -+ pinctrl-names = "gbe-led"; -+ pinctrl-0 = <&gbe1_led0_pins>; -+}; -+ -+&gsw_port1 { -+ label = "lan1"; -+}; -+ -+&gsw_phy1_led0 { -+ status = "okay"; -+ function = LED_FUNCTION_LAN; -+ color = ; -+}; -+ -+&gsw_phy2 { -+ pinctrl-names = "gbe-led"; -+ pinctrl-0 = <&gbe2_led0_pins>; -+}; -+ -+&gsw_port2 { -+ label = "lan2"; -+}; -+ -+&gsw_phy2_led0 { -+ status = "okay"; -+ function = LED_FUNCTION_LAN; -+ color = ; -+}; -+ -+&gsw_phy3 { -+ pinctrl-names = "gbe-led"; -+ pinctrl-0 = <&gbe3_led0_pins>; -+}; -+ -+&gsw_port3 { -+ label = "lan3"; -+}; -+ -+&gsw_phy3_led0 { -+ status = "okay"; -+ function = LED_FUNCTION_LAN; -+ color = ; - }; - - &cci { -@@ -174,6 +314,10 @@ &gsw_phy3_led0 { - color = ; - }; - -+&cci { -+ proc-supply = <&rt5190_buck3>; -+}; -+ - &i2c0 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins>; -@@ -265,6 +409,14 @@ i2c_sfp1: i2c@1 { - #size-cells = <0>; - reg = <1>; - }; -+ -+ i2c_wifi: i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <3>; -+ -+ status = "disabled"; -+ }; - }; - }; - -@@ -364,34 +516,6 @@ mux { - }; - }; - -- gbe0_led1_pins: gbe0-led1-pins { -- mux { -- function = "led"; -- groups = "gbe0_led1"; -- }; -- }; -- -- gbe1_led1_pins: gbe1-led1-pins { -- mux { -- function = "led"; -- groups = "gbe1_led1"; -- }; -- }; -- -- gbe2_led1_pins: gbe2-led1-pins { -- mux { -- function = "led"; -- groups = "gbe2_led1"; -- }; -- }; -- -- gbe3_led1_pins: gbe3-led1-pins { -- mux { -- function = "led"; -- groups = "gbe3_led1"; -- }; -- }; -- - i2p5gbe_led0_pins: 2p5gbe-led0-pins { - mux { - function = "led"; -@@ -399,13 +523,6 @@ mux { - }; - }; - -- i2p5gbe_led1_pins: 2p5gbe-led1-pins { -- mux { -- function = "led"; -- groups = "2p5gbe_led1"; -- }; -- }; -- - mmc0_pins_emmc_45: mmc0-emmc-45-pins { - mux { - function = "flash"; -@@ -427,40 +544,12 @@ mux { - }; - }; - -- snfi_pins: snfi-pins { -- mux { -- function = "flash"; -- groups = "snfi"; -- }; -- }; -- -- spi0_pins: spi0-pins { -- mux { -- function = "spi"; -- groups = "spi0"; -- }; -- }; -- - spi0_flash_pins: spi0-flash-pins { - mux { - function = "spi"; - groups = "spi0", "spi0_wp_hold"; - }; - }; -- -- spi2_pins: spi2-pins { -- mux { -- function = "spi"; -- groups = "spi2"; -- }; -- }; -- -- spi2_flash_pins: spi2-flash-pins { -- mux { -- function = "spi"; -- groups = "spi2", "spi2_wp_hold"; -- }; -- }; - }; - - &pwm { -@@ -500,6 +589,32 @@ partition@0 { - reg = <0x0 0x200000>; - read-only; - }; -+ -+ partition@200000 { -+ label = "ubi"; -+ reg = <0x200000 0x7e00000>; -+ compatible = "linux,ubi"; -+ -+ volumes { -+ ubi-volume-ubootenv { -+ volname = "ubootenv"; -+ nvmem-layout { -+ compatible = "u-boot,env-redundant-bool-layout"; -+ }; -+ }; -+ -+ ubi-volume-ubootenv2 { -+ volname = "ubootenv2"; -+ nvmem-layout { -+ compatible = "u-boot,env-redundant-bool-layout"; -+ }; -+ }; -+ -+ ubi_rootfs: ubi-volume-fit { -+ volname = "fit"; -+ }; -+ }; -+ }; - }; - }; - --- -2.51.0 - - -From e9a4d50305620d1f59c45d3294121bddcff090c7 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 26 Apr 2022 20:51:36 +0100 -Subject: [PATCH 458/517] arm64: dts: mediatek: mt7622: fix GICv2 range - -With the current range specified for the CPU interface there is an -error message at boot: - -GIC: GICv2 detected, but range too small and irqchip.gicv2_force_probe not set - -Setting irqchip.gicv2_force_probe=1 in bootargs results in: - -GIC: Aliased GICv2 at 0x0000000010320000, trying to find the canonical range over 128kB -GIC: Adjusting CPU interface base to 0x000000001032f000 -GIC: Using split EOI/Deactivate mode - -Using the adjusted CPU interface base and 8K size results in only the -final line remaining and fully working system as well as /proc/interrupts -showing additional IPI3,4,5,6: - -IPI3: 0 0 CPU stop (for crash dump) interrupts -IPI4: 0 0 Timer broadcast interrupts -IPI5: 0 0 IRQ work interrupts -IPI6: 0 0 CPU wake-up interrupts - -Signed-off-by: Daniel Golle ---- - arch/arm64/boot/dts/mediatek/mt7622.dtsi | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi -index f2e526840582..39c57987412e 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi -@@ -345,7 +345,7 @@ gic: interrupt-controller@10300000 { - #interrupt-cells = <3>; - interrupt-parent = <&gic>; - reg = <0 0x10310000 0 0x1000>, -- <0 0x10320000 0 0x1000>, -+ <0 0x1032f000 0 0x2000>, - <0 0x10340000 0 0x2000>, - <0 0x10360000 0 0x2000>; - }; --- -2.51.0 - - -From 0e859ccadea781e3c84c4891d729beb5b5ced245 Mon Sep 17 00:00:00 2001 -From: Bruno Umuarama -Date: Thu, 13 Oct 2022 21:18:21 +0000 -Subject: [PATCH 459/517] mediatek: mt7623: fix thermal zone -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Raising the temperatures for passive and active trips. @VA1DER -proposed at issue 9396 to remove passive trip. This commit relates to -his suggestion. - -Without this patch. the CPU will be throttled all the way down to 98MHz -if the temperature rises even a degree above the trip point, and it was -further discovered that if the internal temperature of the device is -above the first trip point temperature when it boots then it will start -in a throttled state and even -$ echo disabled > /sys/class/thermal/thermal_zone0/mode -will have no effect. - -The patch increases the passive trip point and active cooling map. The -throttling temperature will then be at 77°C and 82°C, which is still a -low enough temperature for ARM devices to not be in the real danger -zone, and gives some operational headroom. - -Signed-off-by: Bruno Umuarama ---- - arch/arm/boot/dts/mediatek/mt7623.dtsi | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/mediatek/mt7623.dtsi b/arch/arm/boot/dts/mediatek/mt7623.dtsi -index c6b7d1713096..94e1ca43fee9 100644 ---- a/arch/arm/boot/dts/mediatek/mt7623.dtsi -+++ b/arch/arm/boot/dts/mediatek/mt7623.dtsi -@@ -160,13 +160,13 @@ cpu_thermal: cpu-thermal { - - trips { - cpu_passive: cpu-passive { -- temperature = <57000>; -+ temperature = <77000>; - hysteresis = <2000>; - type = "passive"; - }; - - cpu_active: cpu-active { -- temperature = <67000>; -+ temperature = <82000>; - hysteresis = <2000>; - type = "active"; - }; --- -2.51.0 - - -From 003346fae7e183886b6a3f9e991816b9758ab316 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:54 +0100 -Subject: [PATCH 460/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/194-dts-mt7968a-add-ramoops.patch - ---- - arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi -index f9aaf3f20cd7..39c4cee4b270 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi -@@ -68,6 +68,14 @@ reserved-memory { - #address-cells = <2>; - #size-cells = <2>; - ranges; -+ -+ /* 64 KiB reserved for ramoops/pstore */ -+ ramoops@42ff0000 { -+ compatible = "ramoops"; -+ reg = <0 0x42ff0000 0 0x10000>; -+ record-size = <0x1000>; -+ }; -+ - /* 192 KiB reserved for ARM Trusted Firmware (BL31) */ - secmon_reserved: secmon@43000000 { - reg = <0 0x43000000 0 0x30000>; --- -2.51.0 - - -From 7a4997adcfa4baacbc3101f5a46b9afcc9ce3fd2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:54 +0100 -Subject: [PATCH 461/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/195-dts-mt7986a-bpi-r3-leds-port-names-and-wifi-eeprom.patch - ---- - .../mediatek/mt7986a-bananapi-bpi-r3-nor.dtso | 1 + - .../dts/mediatek/mt7986a-bananapi-bpi-r3.dts | 146 +++++++++++++++++- - 2 files changed, 140 insertions(+), 7 deletions(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso -index 6a0d529b54ac..7cbdd574aa9a 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso -+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso -@@ -55,6 +55,7 @@ partition@180000 { - partition@c00000 { - label = "fit"; - reg = <0xc00000 0x1400000>; -+ compatible = "denx,fit"; - }; - }; - }; -diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts -index ed79ad1ae871..5e0c2941928d 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts -@@ -23,6 +23,10 @@ aliases { - serial0 = &uart0; - ethernet0 = &gmac0; - ethernet1 = &gmac1; -+ led-boot = &green_led; -+ led-failsafe = &green_led; -+ led-running = &green_led; -+ led-upgrade = &blue_led; - }; - - chosen { -@@ -418,27 +422,27 @@ port@0 { - - port@1 { - reg = <1>; -- label = "lan0"; -+ label = "lan1"; - }; - - port@2 { - reg = <2>; -- label = "lan1"; -+ label = "lan2"; - }; - - port@3 { - reg = <3>; -- label = "lan2"; -+ label = "lan3"; - }; - - port@4 { - reg = <4>; -- label = "lan3"; -+ label = "lan4"; - }; - - port5: port@5 { - reg = <5>; -- label = "lan4"; -+ label = "sfp2"; - phy-mode = "2500base-x"; - sfp = <&sfp2>; - managed = "in-band-status"; -@@ -489,9 +493,137 @@ &watchdog { - - &wifi { - status = "okay"; -- pinctrl-names = "default", "dbdc"; -+ pinctrl-names = "default"; - pinctrl-0 = <&wf_2g_5g_pins>, <&wf_led_pins>; -- pinctrl-1 = <&wf_dbdc_pins>, <&wf_led_pins>; -+ -+ mediatek,eeprom-data = <0x86790900 0x000c4326 0x60000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x01000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000800 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x24649090 0x00280000 0x05100000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00021e00 0x021e0002 0x1e00021e 0x00022800 0x02280002 0x28000228 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00008080 0x8080fdf7 -+ 0x0903150d 0x80808080 0x80808080 0x05050d0d 0x1313c6c6 0xc3c3c200 0x00c200c2 0x00008182 -+ 0x8585c2c2 0x82828282 0x858500c2 0xc2000081 0x82858587 0x87c2c200 0x81818285 0x858787c2 -+ 0xc2000081 0x82858587 0x87c2c200 0x00818285 0x858787c2 0xc2000081 0x82858587 0x87c4c4c2 -+ 0xc100c300 0xc3c3c100 0x818383c3 0xc3c3c100 0x81838300 0xc2c2c2c0 0x81828484 0x000000c3 -+ 0xc3c3c100 0x81838386 0x86c3c3c3 0xc1008183 0x838686c2 0xc2c2c081 0x82848486 0x86c3c3c3 -+ 0xc1008183 0x838686c3 0xc3c3c100 0x81838386 0x86c3c3c3 0xc1008183 0x83868622 0x28002228 -+ 0x00222800 0x22280000 0xdddddddd 0xdddddddd 0xddbbbbbb 0xccccccdd 0xdddddddd 0xdddddddd -+ 0xeeeeeecc 0xccccdddd 0xdddddddd 0x004a5662 0x0000004a 0x56620000 0x004a5662 0x0000004a -+ 0x56620000 0x88888888 0x33333326 0x26262626 0x26262600 0x33333326 0x26262626 0x26262600 -+ 0x33333326 0x26262626 0x26262600 0x33333326 0x26262626 0x26262600 0x00000000 0xf0f0cc00 -+ 0x00000000 0x0000aaaa 0xaabbbbbb 0xcccccccc 0xccccbbbb 0xbbbbbbbb 0xbbbbbbaa 0xaaaabbbb -+ 0xbbaaaaaa 0x999999aa 0xaaaabbbb 0xbbcccccc 0x00000000 0x0000aaaa 0xaa000000 0xbbbbbbbb -+ 0xbbbbaaaa 0xaa999999 0xaaaaaaaa 0xaaaaaaaa 0xaaaaaaaa 0xaaaaaaaa 0xaaaabbbb 0xbbbbbbbb -+ 0x00000000 0x00000000 0x00000000 0x99999999 0x9999aaaa 0xaaaaaaaa 0x999999aa 0xaaaaaaaa -+ 0xaaaaaaaa 0xaaaaaaaa 0xaaaabbbb 0xbbbbbbbb 0x00000000 0x0000eeee 0xeeffffff 0xcccccccc -+ 0xccccdddd 0xddbbbbbb 0xccccccbb 0xbbbbbbbb 0xbbbbbbbb 0xbbbbbbbb 0xbbbbcccc 0xccdddddd -+ 0x00516200 0x686e0051 0x6200686e 0x00516200 0x686e0051 0x6200686e 0x00516200 0x686e0051 -+ 0x6200686e 0x00516200 0x686e0051 0x6200686e 0x00516200 0x686e0051 0x6200686e 0x00516200 -+ 0x686e0051 0x6200686e 0x00516200 0x686e0051 0x6200686e 0x00516200 0x686e0051 0x6200686e -+ 0x00516200 0x686e0051 0x6200686e 0x00516200 0x686e0051 0x6200686e 0x00516200 0x686e0051 -+ 0x6200686e 0x00516200 0x686e0051 0x6200686e 0x00516200 0x686e0051 0x6200686e 0x00516200 -+ 0x686e0051 0x6200686e 0x00516200 0x686e0051 0x6200686e 0x00516200 0x686e0051 0x6200686e -+ 0x88888888 0x88888888 0x88888888 0x88888888 0x88888888 0x88888888 0x88888888 0x88888888 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000001 0x06000100 0x01050002 0x00ff0300 -+ 0xf900fe03 0x00000000 0x00000000 0x0000009b 0x6e370000 0x00000000 0x00fc0009 0x0a00fe00 -+ 0x060700fe 0x00070800 0x05000b0a 0x00000000 0x00000000 0x000000e2 0x96460000 0x00000000 -+ 0x000400f7 0xf8000300 0xfcfe0003 0x00fbfc00 0xee00e3f2 0x00000000 0x00000000 0x00000011 -+ 0xbb550000 0x00000000 0x000600f6 0xfc000300 0xfbfe0004 0x00fafe00 0xf600ecf2 0x00000000 -+ 0x00000000 0x0000001f 0xbf580000 0x00000000 0x000600f5 0xf6000400 0xf8f90004 0x00f7f800 -+ 0xf700f0f4 0x00000000 0x00000000 0x00000024 0xbe570000 0x00000000 0x000800f8 0xfe000600 -+ 0xf8fd0007 0x00f9fe00 0xf500f0f4 0x00000000 0x00000000 0x0000002d 0xd6610000 0x00000000 -+ 0x000400f7 0xfc000500 0xf7fc0005 0x00f7fc00 0xf900f5f8 0x00000000 0x00000000 0x00000026 -+ 0xd96e0000 0x00000000 0x000400f7 0xf9000600 0xf5f70005 0x00f5f800 0xf900f4f7 0x00000000 -+ 0x00000000 0x0000001b 0xce690000 0x00000000 0x000300f8 0xf8000600 0xf6f60004 0x00f6f700 -+ 0xf900f4f7 0x00000000 0x00000000 0x00000018 0xd8720000 0x00000000 0x00000000 0x02404002 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0xc1c2c1c2 0x41c341c3 0x3fc13fc1 0x40c13fc2 0x3fc240c1 0x41c040c0 0x3fc23fc2 0x40c13fc2 -+ 0x3fc140c0 0x41c040c0 0x3fc33fc3 0x40c23fc2 0x3fc240c1 0x41c040c0 0x3fc23fc2 0x40c23fc2 -+ 0x3fc140c1 0x41c040c0 0x00000000 0x00000000 0x41c741c7 0xc1c7c1c7 0x00000000 0x00000000 -+ 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 -+ 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 -+ 0x00a0ce00 0x00000000 0xb6840000 0x00000000 0x00000000 0x00000000 0x18181818 0x18181818 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x004b5763 0x0000004b 0x57630000 0x004b5763 0x0000004b 0x57630000 0x88888888 0x08474759 -+ 0x69780849 0x49596d7a 0x0849495a 0x6d790848 0x48596c78 0x08484858 0x6a780848 0x48586a78 -+ 0x08484858 0x6c78084a 0x4a5b6d79 0x08474759 0x697a0848 0x48596b79 0x08484859 0x6c7a0848 -+ 0x48586c79 0x08484857 0x68770848 0x48576877 0x08484857 0x6a77084a 0x4a5a6a77 0x08464659 -+ 0x69790848 0x48586b79 0x08484858 0x6c7a0848 0x48596c79 0x08484857 0x68770848 0x48576877 -+ 0x08494958 0x6d7a084b 0x4b5c6c77 0x0847475a 0x6a7b0849 0x495a6e7c 0x0849495a 0x6e7c0849 -+ 0x495b6e7c 0x08494959 0x6a7a0849 0x49596a7a 0x084a4a5a 0x6f7d084b 0x4b5c6e7b 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x85848484 -+ 0xc3c4c4c5 0xc4c3c33f 0xc3c3c2c2 0xc2c2c03f 0xc3c3c3c4 0xc4c4c33f 0xc2c2c2c2 0xc1c3c1c1 -+ 0xc0c08282 0x83848686 0x88880000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00001111 0x00000000 -+ 0x8080f703 0x10808080 0x80050d13 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x000000a4 0xce000000 0x0000b684 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 -+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000>; - - led { - led-active-low; --- -2.51.0 - - -From 9301b8648c259afbd936ca0d82993486c7f8621c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:55 +0100 -Subject: [PATCH 462/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/196-dts-mt7986a-bpi-r3-use-all-ubi-nand-layout.patch - ---- - .../mt7986a-bananapi-bpi-r3-emmc.dtso | 19 ++++++++++++ - .../mt7986a-bananapi-bpi-r3-nand.dtso | 29 +++++++++---------- - .../mediatek/mt7986a-bananapi-bpi-r3-nor.dtso | 6 +++- - .../mediatek/mt7986a-bananapi-bpi-r3-sd.dtso | 19 ++++++++++++ - 4 files changed, 57 insertions(+), 16 deletions(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso -index 047a8388811e..888f1e20374b 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso -+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso -@@ -21,5 +21,24 @@ / { - non-removable; - no-sd; - no-sdio; -+ #address-cells = <1>; -+ #size-cells = <0>; - status = "okay"; -+ -+ card@0 { -+ compatible = "mmc-card"; -+ reg = <0>; -+ -+ partitions { -+ compatible = "gpt-partitions"; -+ -+ emmc_rootdisk: block-partition-production { -+ partname = "production"; -+ }; -+ }; -+ }; -+}; -+ -+&{/chosen} { -+ rootdisk-emmc = <&emmc_rootdisk>; - }; -diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso -index 24398f8a7da4..2b998cc9b054 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso -+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso -@@ -29,25 +29,24 @@ partitions { - - partition@0 { - label = "bl2"; -- reg = <0x0 0x100000>; -- read-only; -+ reg = <0x0 0x200000>; - }; - -- partition@100000 { -- label = "reserved"; -- reg = <0x100000 0x280000>; -- }; -- -- partition@380000 { -- label = "fip"; -- reg = <0x380000 0x200000>; -- read-only; -- }; -- -- partition@580000 { -+ partition@200000 { - label = "ubi"; -- reg = <0x580000 0x7a80000>; -+ reg = <0x200000 0x7e00000>; -+ compatible = "linux,ubi"; -+ -+ volumes { -+ nand_rootdisk: ubi-volume-fit { -+ volname = "fit"; -+ }; -+ }; - }; - }; - }; - }; -+ -+&{/chosen} { -+ rootdisk-spim-nand = <&nand_rootdisk>; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso -index 7cbdd574aa9a..384ceab38e3f 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso -+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso -@@ -52,7 +52,7 @@ partition@180000 { - reg = <0x180000 0xa80000>; - }; - -- partition@c00000 { -+ nor_rootdisk: partition@c00000 { - label = "fit"; - reg = <0xc00000 0x1400000>; - compatible = "denx,fit"; -@@ -60,3 +60,7 @@ partition@c00000 { - }; - }; - }; -+ -+&{/chosen} { -+ rootdisk-nor = <&nor_rootdisk>; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso -index d9e01967acc4..98be406ecae1 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso -+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso -@@ -15,5 +15,24 @@ / { - bus-width = <4>; - max-frequency = <52000000>; - cap-sd-highspeed; -+ #address-cells = <1>; -+ #size-cells = <0>; - status = "okay"; -+ -+ card@0 { -+ compatible = "mmc-card"; -+ reg = <0>; -+ -+ partitions { -+ compatible = "gpt-partitions"; -+ -+ sd_rootdisk: block-partition-production { -+ partname = "production"; -+ }; -+ }; -+ }; -+}; -+ -+&{/chosen} { -+ rootdisk-sd = <&sd_rootdisk>; - }; --- -2.51.0 - - -From a3d2dc6ef2ff5f5cb44223775f18f400b3d25f64 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:55 +0100 -Subject: [PATCH 463/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/198-dts-mt7988a-enable-wed.patch - ---- - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 137 ++++++++++++++++++++++ - 1 file changed, 137 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index b2338231fab4..5717729f563c 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -145,6 +145,32 @@ secmon@43000000 { - reg = <0 0x43000000 0 0x50000>; - no-map; - }; -+ -+ wmcpu_emi: wmcpu-reserved@47cc0000 { -+ reg = <0 0x47cc0000 0 0x00100000>; -+ no-map; -+ }; -+ -+ wo_emi0: wo-emi@4f600000 { -+ reg = <0 0x4f600000 0 0x40000>; -+ no-map; -+ }; -+ -+ wo_emi1: wo-emi@4f640000 { -+ reg = <0 0x4f640000 0 0x40000>; -+ no-map; -+ }; -+ -+ wo_emi2: wo-emi@4f680000 { -+ reg = <0 0x4f680000 0 0x40000>; -+ no-map; -+ }; -+ -+ wo_data: wo-data@4f700000 { -+ reg = <0 0x4f700000 0 0x800000>; -+ no-map; -+ shared = <1>; -+ }; - }; - - soc { -@@ -867,6 +893,50 @@ ethsys: clock-controller@15000000 { - reg = <0 0x15000000 0 0x1000>; - #clock-cells = <1>; - #reset-cells = <1>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ }; -+ -+ wed0: wed@15010000 { -+ compatible = "mediatek,mt7988-wed", -+ "syscon"; -+ reg = <0 0x15010000 0 0x2000>; -+ interrupt-parent = <&gic>; -+ interrupts = ; -+ memory-region = <&wo_emi0>, <&wo_data>; -+ memory-region-names = "wo-emi", "wo-data"; -+ mediatek,wo-ccif = <&wo_ccif0>; -+ mediatek,wo-ilm = <&wo_ilm0>; -+ mediatek,wo-dlm = <&wo_dlm0>; -+ mediatek,wo-cpuboot = <&wo_cpuboot0>; -+ }; -+ -+ wed1: wed@15012000 { -+ compatible = "mediatek,mt7988-wed", -+ "syscon"; -+ reg = <0 0x15012000 0 0x2000>; -+ interrupt-parent = <&gic>; -+ interrupts = ; -+ memory-region = <&wo_emi1>, <&wo_data>; -+ memory-region-names = "wo-emi", "wo-data"; -+ mediatek,wo-ccif = <&wo_ccif1>; -+ mediatek,wo-ilm = <&wo_ilm1>; -+ mediatek,wo-dlm = <&wo_dlm1>; -+ mediatek,wo-cpuboot = <&wo_cpuboot1>; -+ }; -+ -+ wed2: wed@15014000 { -+ compatible = "mediatek,mt7988-wed", -+ "syscon"; -+ reg = <0 0x15014000 0 0x2000>; -+ interrupt-parent = <&gic>; -+ interrupts = ; -+ memory-region = <&wo_emi2>, <&wo_data>; -+ memory-region-names = "wo-emi", "wo-data"; -+ mediatek,wo-ccif = <&wo_ccif2>; -+ mediatek,wo-ilm = <&wo_ilm2>; -+ mediatek,wo-dlm = <&wo_dlm2>; -+ mediatek,wo-cpuboot = <&wo_cpuboot2>; - }; - - switch: switch@15020000 { -@@ -1086,6 +1156,7 @@ eth: ethernet@15100000 { - <&apmixedsys CLK_APMIXED_SGMPLL>; - mediatek,ethsys = <ðsys>; - mediatek,infracfg = <&topmisc>; -+ mediatek,wed = <&wed0>, <&wed1>, <&wed2>; - #address-cells = <1>; - #size-cells = <0>; - -@@ -1147,6 +1218,72 @@ i2p5gbe_led1: i2p5gbe-led1@1 { - }; - }; - -+ wo_ccif0: syscon@151a5000 { -+ compatible = "mediatek,mt7988-wo-ccif", "syscon"; -+ reg = <0 0x151a5000 0 0x1000>; -+ interrupt-parent = <&gic>; -+ interrupts = ; -+ }; -+ -+ wo_ccif1: syscon@152a5000 { -+ compatible = "mediatek,mt7988-wo-ccif", "syscon"; -+ reg = <0 0x152a5000 0 0x1000>; -+ interrupt-parent = <&gic>; -+ interrupts = ; -+ }; -+ -+ wo_ccif2: syscon@153a5000 { -+ compatible = "mediatek,mt7988-wo-ccif", "syscon"; -+ reg = <0 0x153a5000 0 0x1000>; -+ interrupt-parent = <&gic>; -+ interrupts = ; -+ }; -+ -+ wo_ilm0: syscon@151e0000 { -+ compatible = "mediatek,mt7988-wo-ilm", "syscon"; -+ reg = <0 0x151e0000 0 0x8000>; -+ }; -+ -+ wo_ilm1: syscon@152e0000 { -+ compatible = "mediatek,mt7988-wo-ilm", "syscon"; -+ reg = <0 0x152e0000 0 0x8000>; -+ }; -+ -+ wo_ilm2: syscon@153e0000 { -+ compatible = "mediatek,mt7988-wo-ilm", "syscon"; -+ reg = <0 0x153e0000 0 0x8000>; -+ }; -+ -+ wo_dlm0: syscon@151e8000 { -+ compatible = "mediatek,mt7988-wo-dlm", "syscon"; -+ reg = <0 0x151e8000 0 0x2000>; -+ }; -+ -+ wo_dlm1: syscon@152e8000 { -+ compatible = "mediatek,mt7988-wo-dlm", "syscon"; -+ reg = <0 0x152e8000 0 0x2000>; -+ }; -+ -+ wo_dlm2: syscon@153e8000 { -+ compatible = "mediatek,mt7988-wo-dlm", "syscon"; -+ reg = <0 0x153e8000 0 0x2000>; -+ }; -+ -+ wo_cpuboot0: syscon@15194000 { -+ compatible = "mediatek,mt7988-wo-cpuboot", "syscon"; -+ reg = <0 0x15194000 0 0x1000>; -+ }; -+ -+ wo_cpuboot1: syscon@15294000 { -+ compatible = "mediatek,mt7988-wo-cpuboot", "syscon"; -+ reg = <0 0x15294000 0 0x1000>; -+ }; -+ -+ wo_cpuboot2: syscon@15394000 { -+ compatible = "mediatek,mt7988-wo-cpuboot", "syscon"; -+ reg = <0 0x15394000 0 0x1000>; -+ }; -+ - crypto: crypto@15600000 { - compatible = "inside-secure,safexcel-eip197b"; - reg = <0 0x15600000 0 0x180000>; --- -2.51.0 - - -From a578fcc5a7b10a8a40c829a21a9d9db28b7c8cd7 Mon Sep 17 00:00:00 2001 -From: Shiji Yang -Date: Sun, 10 Aug 2025 18:11:01 +0800 -Subject: [PATCH 464/517] arm64: dts: mediatek: mt7986: increase ATF reserved - memory to 256 kiB - -The latest Mediatek open-source Trusted Firmware-A project has -reserved 256 KiB for BL2 and BL31. It is better to increase the -reserved memory region in the Linux kernel to protect the data. - -Signed-off-by: Shiji Yang ---- - arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi -index 39c4cee4b270..9a8d7db31261 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi -@@ -76,9 +76,9 @@ ramoops@42ff0000 { - record-size = <0x1000>; - }; - -- /* 192 KiB reserved for ARM Trusted Firmware (BL31) */ -+ /* 256 KiB reserved for ARM Trusted Firmware (BL31 + BL32) */ - secmon_reserved: secmon@43000000 { -- reg = <0 0x43000000 0 0x30000>; -+ reg = <0 0x43000000 0 0x40000>; - no-map; - }; - --- -2.51.0 - - -From 58d452682aae8137393174cc17db1b3277413904 Mon Sep 17 00:00:00 2001 -From: Kristian Evensen -Date: Mon, 30 Apr 2018 14:38:01 +0200 -Subject: [PATCH 465/517] phy: phy-mtk-tphy: Add hifsys-support - ---- - drivers/phy/mediatek/phy-mtk-tphy.c | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - -diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c -index 3f7095ec5978..4662518a38ed 100644 ---- a/drivers/phy/mediatek/phy-mtk-tphy.c -+++ b/drivers/phy/mediatek/phy-mtk-tphy.c -@@ -18,6 +18,8 @@ - #include - #include - #include -+#include -+#include - - #include "phy-mtk-io.h" - -@@ -271,6 +273,9 @@ - - #define USER_BUF_LEN(count) min_t(size_t, 8, (count)) - -+#define HIF_SYSCFG1 0x14 -+#define HIF_SYSCFG1_PHY2_MASK (0x3 << 20) -+ - enum mtk_phy_version { - MTK_PHY_V1 = 1, - MTK_PHY_V2, -@@ -339,6 +344,7 @@ struct mtk_tphy { - void __iomem *sif_base; /* only shared sif */ - const struct mtk_phy_pdata *pdata; - struct mtk_phy_instance **phys; -+ struct regmap *hif; - int nphys; - int src_ref_clk; /* MHZ, reference clock for slew rate calibrate */ - int src_coef; /* coefficient for slew rate calibrate */ -@@ -973,6 +979,10 @@ static void pcie_phy_instance_init(struct mtk_tphy *tphy, - if (tphy->pdata->version != MTK_PHY_V1) - return; - -+ if (tphy->hif) -+ regmap_update_bits(tphy->hif, HIF_SYSCFG1, -+ HIF_SYSCFG1_PHY2_MASK, 0); -+ - mtk_phy_update_bits(phya + U3P_U3_PHYA_DA_REG0, - P3A_RG_XTAL_EXT_PE1H | P3A_RG_XTAL_EXT_PE2H, - FIELD_PREP(P3A_RG_XTAL_EXT_PE1H, 0x2) | -@@ -1621,6 +1631,16 @@ static int mtk_tphy_probe(struct platform_device *pdev) - &tphy->src_coef); - } - -+ if (of_find_property(np, "mediatek,phy-switch", NULL)) { -+ tphy->hif = syscon_regmap_lookup_by_phandle(np, -+ "mediatek,phy-switch"); -+ if (IS_ERR(tphy->hif)) { -+ dev_err(&pdev->dev, -+ "missing \"mediatek,phy-switch\" phandle\n"); -+ return PTR_ERR(tphy->hif); -+ } -+ } -+ - port = 0; - for_each_child_of_node_scoped(np, child_np) { - struct mtk_phy_instance *instance; --- -2.51.0 - - -From e45d21bc40ab81b4a082310763c9f0ef19f980ec Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Fri, 1 Nov 2024 03:19:39 +0000 -Subject: [PATCH 466/517] clk: mediatek: mt7988-infracfg: SPI0 clocks are not - critical - -SPI0 clocks have wrongly been marked as critical while, probably due -to the SPI driver not requesting them. This can (and should) be addressed -in device tree instead. -Remove CLK_IS_CRITICAL flag from clocks related to SPI0. - -Fixes: 4b4719437d85 ("clk: mediatek: add drivers for MT7988 SoC") -Signed-off-by: Daniel Golle ---- - drivers/clk/mediatek/clk-mt7988-infracfg.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/drivers/clk/mediatek/clk-mt7988-infracfg.c b/drivers/clk/mediatek/clk-mt7988-infracfg.c -index ef8267319d91..c40e18c27f12 100644 ---- a/drivers/clk/mediatek/clk-mt7988-infracfg.c -+++ b/drivers/clk/mediatek/clk-mt7988-infracfg.c -@@ -196,12 +196,10 @@ static const struct mtk_gate infra_clks[] = { - GATE_INFRA2(CLK_INFRA_SPINFI, "infra_f_fspinfi", "spinfi_sel", 10), - GATE_INFRA2_FLAGS(CLK_INFRA_66M_NFI_HCK, "infra_hf_66m_nfi_hck", "sysaxi_sel", 11, - CLK_IS_CRITICAL), -- GATE_INFRA2_FLAGS(CLK_INFRA_104M_SPI0, "infra_hf_104m_spi0", "infra_mux_spi0_sel", 12, -- CLK_IS_CRITICAL), -+ GATE_INFRA2(CLK_INFRA_104M_SPI0, "infra_hf_104m_spi0", "infra_mux_spi0_sel", 12), - GATE_INFRA2(CLK_INFRA_104M_SPI1, "infra_hf_104m_spi1", "infra_mux_spi1_sel", 13), - GATE_INFRA2(CLK_INFRA_104M_SPI2_BCK, "infra_hf_104m_spi2_bck", "infra_mux_spi2_sel", 14), -- GATE_INFRA2_FLAGS(CLK_INFRA_66M_SPI0_HCK, "infra_hf_66m_spi0_hck", "sysaxi_sel", 15, -- CLK_IS_CRITICAL), -+ GATE_INFRA2(CLK_INFRA_66M_SPI0_HCK, "infra_hf_66m_spi0_hck", "sysaxi_sel", 15), - GATE_INFRA2(CLK_INFRA_66M_SPI1_HCK, "infra_hf_66m_spi1_hck", "sysaxi_sel", 16), - GATE_INFRA2(CLK_INFRA_66M_SPI2_HCK, "infra_hf_66m_spi2_hck", "sysaxi_sel", 17), - GATE_INFRA2(CLK_INFRA_66M_FLASHIF_AXI, "infra_hf_66m_flashif_axi", "sysaxi_sel", 18), --- -2.51.0 - - -From 2635aa94e576bbcaf5fdfe2a2ac47d35203f0ff1 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Wed, 25 Jan 2023 00:27:49 +0000 -Subject: [PATCH 467/517] hwrng: add driver for MediaTek TRNG SMC - -Add driver providing kernel-side support for the Random Number -Generator hardware found on Mediatek SoCs which have a driver in ARM -TrustedFirmware-A allowing Linux to read random numbers using a -non-standard vendor-defined Secure Monitor Call. - -Signed-off-by: Daniel Golle ---- - drivers/char/hw_random/Kconfig | 17 +++++++ - drivers/char/hw_random/Makefile | 1 + - drivers/char/hw_random/mtk-rng-v2.c | 76 +++++++++++++++++++++++++++++ - 3 files changed, 94 insertions(+) - create mode 100644 drivers/char/hw_random/mtk-rng-v2.c - -diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig -index f0dde77f50b4..fc19371e6217 100644 ---- a/drivers/char/hw_random/Kconfig -+++ b/drivers/char/hw_random/Kconfig -@@ -452,6 +452,23 @@ config HW_RANDOM_MTK - - If unsure, say Y. - -+config HW_RANDOM_MTK_V2 -+ tristate "Mediatek Random Number Generator support (v2/SMC)" -+ depends on HAVE_ARM_SMCCC -+ depends on HW_RANDOM -+ depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST -+ default y -+ help -+ This driver provides kernel-side support for the Random Number -+ Generator hardware found on Mediatek SoCs which have a driver -+ in ARM TrustedFirmware-A allowing Linux to read using a non- -+ standard vendor-defined Secure Monitor Call. -+ -+ To compile this driver as a module, choose M here. the -+ module will be called mtk-rng-v2. -+ -+ If unsure, say Y. -+ - config HW_RANDOM_S390 - tristate "S390 True Random Number Generator support" - depends on S390 -diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile -index 01f012eab440..3403f6b9282a 100644 ---- a/drivers/char/hw_random/Makefile -+++ b/drivers/char/hw_random/Makefile -@@ -39,6 +39,7 @@ obj-$(CONFIG_HW_RANDOM_PIC32) += pic32-rng.o - obj-$(CONFIG_HW_RANDOM_MESON) += meson-rng.o - obj-$(CONFIG_HW_RANDOM_CAVIUM) += cavium-rng.o cavium-rng-vf.o - obj-$(CONFIG_HW_RANDOM_MTK) += mtk-rng.o -+obj-$(CONFIG_HW_RANDOM_MTK_V2) += mtk-rng-v2.o - obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o - obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o - obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o -diff --git a/drivers/char/hw_random/mtk-rng-v2.c b/drivers/char/hw_random/mtk-rng-v2.c -new file mode 100644 -index 000000000000..8c506a7897d0 ---- /dev/null -+++ b/drivers/char/hw_random/mtk-rng-v2.c -@@ -0,0 +1,76 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * Driver for Mediatek Hardware Random Number Generator (v2/SMCC) -+ * -+ * Copyright (C) 2023 Daniel Golle -+ * based on patch from Mingming Su -+ */ -+#define MTK_RNG_DEV KBUILD_MODNAME -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MTK_SIP_KERNEL_GET_RND MTK_SIP_SMC_CMD(0x550) -+ -+static int mtk_rng_v2_read(struct hwrng *rng, void *buf, size_t max, bool wait) -+{ -+ struct arm_smccc_res res; -+ int retval = 0; -+ -+ while (max >= sizeof(u32)) { -+ arm_smccc_smc(MTK_SIP_KERNEL_GET_RND, 0, 0, 0, 0, 0, 0, 0, -+ &res); -+ if (res.a0) -+ break; -+ -+ *(u32 *)buf = res.a1; -+ retval += sizeof(u32); -+ buf += sizeof(u32); -+ max -= sizeof(u32); -+ } -+ -+ return retval || !wait ? retval : -EIO; -+} -+ -+static int mtk_rng_v2_probe(struct platform_device *pdev) -+{ -+ struct hwrng *trng; -+ -+ trng = devm_kzalloc(&pdev->dev, sizeof(*trng), GFP_KERNEL); -+ if (!trng) -+ return -ENOMEM; -+ -+ trng->name = pdev->name; -+ trng->read = mtk_rng_v2_read; -+ trng->quality = 900; -+ -+ return devm_hwrng_register(&pdev->dev, trng); -+} -+ -+static const struct of_device_id mtk_rng_v2_match[] = { -+ { .compatible = "mediatek,mt7981-rng" }, -+ { .compatible = "mediatek,mt7987-rng" }, -+ { .compatible = "mediatek,mt7988-rng" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, mtk_rng_v2_match); -+ -+static struct platform_driver mtk_rng_v2_driver = { -+ .probe = mtk_rng_v2_probe, -+ .driver = { -+ .name = KBUILD_MODNAME, -+ .of_match_table = mtk_rng_v2_match, -+ }, -+}; -+module_platform_driver(mtk_rng_v2_driver); -+ -+MODULE_DESCRIPTION("Mediatek Random Number Generator Driver (v2/SMC)"); -+MODULE_AUTHOR("Daniel Golle "); -+MODULE_LICENSE("GPL"); --- -2.51.0 - - -From 7ab0a6fa1cbc0955011ee9d40ee6dd4ab9e3eade Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:56 +0100 -Subject: [PATCH 468/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/330-snand-mtk-bmt-support.patch - ---- - drivers/mtd/nand/spi/core.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c -index 8a3c9db90c6f..685a92a50fe6 100644 ---- a/drivers/mtd/nand/spi/core.c -+++ b/drivers/mtd/nand/spi/core.c -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - - static int spinand_read_reg_op(struct spinand_device *spinand, u8 reg, u8 *val) - { -@@ -1574,6 +1575,7 @@ static int spinand_probe(struct spi_mem *mem) - if (ret) - return ret; - -+ mtk_bmt_attach(mtd); - ret = mtd_device_register(mtd, NULL, 0); - if (ret) - goto err_spinand_cleanup; -@@ -1581,6 +1583,7 @@ static int spinand_probe(struct spi_mem *mem) - return 0; - - err_spinand_cleanup: -+ mtk_bmt_detach(mtd); - spinand_cleanup(spinand); - - return ret; -@@ -1599,6 +1602,7 @@ static int spinand_remove(struct spi_mem *mem) - if (ret) - return ret; - -+ mtk_bmt_detach(mtd); - spinand_cleanup(spinand); - - return 0; --- -2.51.0 - - -From 14a79939d2d384b4a9bf0ff262a01071e4e1b559 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:57 +0100 -Subject: [PATCH 469/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/331-mt7622-rfb1-enable-bmt.patch - ---- - arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts -index a478bab2e8cf..d6c52654e5ed 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts -@@ -572,6 +572,7 @@ flash@0 { - spi-tx-bus-width = <4>; - spi-rx-bus-width = <4>; - nand-ecc-engine = <&snfi>; -+ mediatek,bmt-v2; - - partitions { - compatible = "fixed-partitions"; --- -2.51.0 - - -From aa4935c265e21729b534f8fd79fe2411dec468a4 Mon Sep 17 00:00:00 2001 -From: Davide Fioravanti -Date: Fri, 8 Jan 2021 15:35:24 +0100 -Subject: [PATCH 470/517] mtd: spinand: Add support for the Fidelix FM35X1GA - -Datasheet: http://www.hobos.com.cn/upload/datasheet/DS35X1GAXXX_100_rev00.pdf - -Signed-off-by: Davide Fioravanti ---- - drivers/mtd/nand/spi/Makefile | 2 +- - drivers/mtd/nand/spi/core.c | 1 + - drivers/mtd/nand/spi/fidelix.c | 76 ++++++++++++++++++++++++++++++++++ - include/linux/mtd/spinand.h | 1 + - 4 files changed, 79 insertions(+), 1 deletion(-) - create mode 100644 drivers/mtd/nand/spi/fidelix.c - -diff --git a/drivers/mtd/nand/spi/Makefile b/drivers/mtd/nand/spi/Makefile -index f725f0c67307..27dc57924f19 100644 ---- a/drivers/mtd/nand/spi/Makefile -+++ b/drivers/mtd/nand/spi/Makefile -@@ -1,4 +1,4 @@ - # SPDX-License-Identifier: GPL-2.0 --spinand-objs := core.o alliancememory.o ato.o esmt.o etron.o fmsh.o foresee.o gigadevice.o -+spinand-objs := core.o alliancememory.o ato.o esmt.o etron.o fidelix.o fmsh.o foresee.o gigadevice.o - spinand-objs += macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o - obj-$(CONFIG_MTD_SPI_NAND) += spinand.o -diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c -index 685a92a50fe6..d0071aba4f77 100644 ---- a/drivers/mtd/nand/spi/core.c -+++ b/drivers/mtd/nand/spi/core.c -@@ -1162,6 +1162,7 @@ static const struct spinand_manufacturer *spinand_manufacturers[] = { - &esmt_c8_spinand_manufacturer, - &etron_spinand_manufacturer, - &fmsh_spinand_manufacturer, -+ &fidelix_spinand_manufacturer, - &foresee_spinand_manufacturer, - &gigadevice_spinand_manufacturer, - ¯onix_spinand_manufacturer, -diff --git a/drivers/mtd/nand/spi/fidelix.c b/drivers/mtd/nand/spi/fidelix.c -new file mode 100644 -index 000000000000..039bf331813c ---- /dev/null -+++ b/drivers/mtd/nand/spi/fidelix.c -@@ -0,0 +1,76 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (c) 2020 Davide Fioravanti -+ */ -+ -+#include -+#include -+#include -+ -+#define SPINAND_MFR_FIDELIX 0xE5 -+#define FIDELIX_ECCSR_MASK 0x0F -+ -+static SPINAND_OP_VARIANTS(read_cache_variants, -+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); -+ -+static SPINAND_OP_VARIANTS(write_cache_variants, -+ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), -+ SPINAND_PROG_LOAD(true, 0, NULL, 0)); -+ -+static SPINAND_OP_VARIANTS(update_cache_variants, -+ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), -+ SPINAND_PROG_LOAD(true, 0, NULL, 0)); -+ -+static int fm35x1ga_ooblayout_ecc(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *region) -+{ -+ if (section > 3) -+ return -ERANGE; -+ -+ region->offset = (16 * section) + 8; -+ region->length = 8; -+ -+ return 0; -+} -+ -+static int fm35x1ga_ooblayout_free(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *region) -+{ -+ if (section > 3) -+ return -ERANGE; -+ -+ region->offset = (16 * section) + 2; -+ region->length = 6; -+ -+ return 0; -+} -+ -+static const struct mtd_ooblayout_ops fm35x1ga_ooblayout = { -+ .ecc = fm35x1ga_ooblayout_ecc, -+ .free = fm35x1ga_ooblayout_free, -+}; -+ -+static const struct spinand_info fidelix_spinand_table[] = { -+ SPINAND_INFO("FM35X1GA", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x71), -+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), -+ NAND_ECCREQ(4, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, -+ &write_cache_variants, -+ &update_cache_variants), -+ SPINAND_HAS_QE_BIT, -+ SPINAND_ECCINFO(&fm35x1ga_ooblayout, NULL)), -+}; -+ -+static const struct spinand_manufacturer_ops fidelix_spinand_manuf_ops = { -+}; -+ -+const struct spinand_manufacturer fidelix_spinand_manufacturer = { -+ .id = SPINAND_MFR_FIDELIX, -+ .name = "Fidelix", -+ .chips = fidelix_spinand_table, -+ .nchips = ARRAY_SIZE(fidelix_spinand_table), -+ .ops = &fidelix_spinand_manuf_ops, -+}; -diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h -index e5b6ac340383..11f7a6a1a31f 100644 ---- a/include/linux/mtd/spinand.h -+++ b/include/linux/mtd/spinand.h -@@ -265,6 +265,7 @@ extern const struct spinand_manufacturer ato_spinand_manufacturer; - extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer; - extern const struct spinand_manufacturer etron_spinand_manufacturer; - extern const struct spinand_manufacturer fmsh_spinand_manufacturer; -+extern const struct spinand_manufacturer fidelix_spinand_manufacturer; - extern const struct spinand_manufacturer foresee_spinand_manufacturer; - extern const struct spinand_manufacturer gigadevice_spinand_manufacturer; - extern const struct spinand_manufacturer macronix_spinand_manufacturer; --- -2.51.0 - - -From 3444bd6e424a34dfa604bd275471bbc90db46127 Mon Sep 17 00:00:00 2001 -From: Sam Shih -Date: Fri, 19 Apr 2024 17:59:07 +0100 -Subject: [PATCH 471/517] cpufreq: mediatek: Add support for MT7988A - -This add cpufreq support for mediatek MT7988A SoC. - -The platform data of MT7988A is different from previous MediaTek SoCs, -so we add a new compatible and platform data for it. - -Signed-off-by: Sam Shih ---- - drivers/cpufreq/mediatek-cpufreq.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c -index 663f61565cf7..fa6633d44ac9 100644 ---- a/drivers/cpufreq/mediatek-cpufreq.c -+++ b/drivers/cpufreq/mediatek-cpufreq.c -@@ -744,6 +744,7 @@ static const struct of_device_id mtk_cpufreq_machines[] __initconst __maybe_unus - { .compatible = "mediatek,mt7622", .data = &mt7622_platform_data }, - { .compatible = "mediatek,mt7623", .data = &mt7623_platform_data }, - { .compatible = "mediatek,mt7988a", .data = &mt7988_platform_data }, -+ { .compatible = "mediatek,mt7988d", .data = &mt7988_platform_data }, - { .compatible = "mediatek,mt8167", .data = &mt8516_platform_data }, - { .compatible = "mediatek,mt817x", .data = &mt2701_platform_data }, - { .compatible = "mediatek,mt8173", .data = &mt2701_platform_data }, --- -2.51.0 - - -From ee055daffe2d0aa9cdc5229ef49bd46c8cfb4078 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:58 +0100 -Subject: [PATCH 472/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/400-crypto-add-eip97-inside-secure-support.patch - ---- - drivers/crypto/inside-secure/safexcel.c | 8 ++++++++ - drivers/crypto/inside-secure/safexcel.h | 1 + - 2 files changed, 9 insertions(+) - -diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c -index f5c1912aa564..c0a1fa1f7169 100644 ---- a/drivers/crypto/inside-secure/safexcel.c -+++ b/drivers/crypto/inside-secure/safexcel.c -@@ -608,6 +608,14 @@ static int safexcel_hw_init(struct safexcel_crypto_priv *priv) - val |= EIP197_MST_CTRL_TX_MAX_CMD(5); - writel(val, EIP197_HIA_AIC(priv) + EIP197_HIA_MST_CTRL); - } -+ /* -+ * Set maximum number of TX commands to 2^4 = 16 for EIP97 HW2.1/HW2.3 -+ */ -+ else { -+ val = 0; -+ val |= EIP97_MST_CTRL_TX_MAX_CMD(4); -+ writel(val, EIP197_HIA_AIC(priv) + EIP197_HIA_MST_CTRL); -+ } - - /* Configure wr/rd cache values */ - writel(EIP197_MST_CTRL_RD_CACHE(RD_CACHE_4BITS) | -diff --git a/drivers/crypto/inside-secure/safexcel.h b/drivers/crypto/inside-secure/safexcel.h -index 0c79ad78d1c0..2ad691a84180 100644 ---- a/drivers/crypto/inside-secure/safexcel.h -+++ b/drivers/crypto/inside-secure/safexcel.h -@@ -315,6 +315,7 @@ - #define EIP197_MST_CTRL_RD_CACHE(n) (((n) & 0xf) << 0) - #define EIP197_MST_CTRL_WD_CACHE(n) (((n) & 0xf) << 4) - #define EIP197_MST_CTRL_TX_MAX_CMD(n) (((n) & 0xf) << 20) -+#define EIP97_MST_CTRL_TX_MAX_CMD(n) (((n) & 0xf) << 4) - #define EIP197_MST_CTRL_BYTE_SWAP BIT(24) - #define EIP197_MST_CTRL_NO_BYTE_SWAP BIT(25) - #define EIP197_MST_CTRL_BYTE_SWAP_BITS GENMASK(25, 24) --- -2.51.0 - - -From 6048c6fc7613b02d5f9b4ea8e3c18b08e33164f9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:58 +0100 -Subject: [PATCH 473/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/401-crypto-fix-eip97-cache-incoherent.patch - ---- - drivers/crypto/inside-secure/safexcel.h | 3 +++ - drivers/crypto/inside-secure/safexcel_hash.c | 4 ++-- - 2 files changed, 5 insertions(+), 2 deletions(-) - -diff --git a/drivers/crypto/inside-secure/safexcel.h b/drivers/crypto/inside-secure/safexcel.h -index 2ad691a84180..c2c1773104e3 100644 ---- a/drivers/crypto/inside-secure/safexcel.h -+++ b/drivers/crypto/inside-secure/safexcel.h -@@ -743,6 +743,9 @@ struct safexcel_priv_data { - /* Priority we use for advertising our algorithms */ - #define SAFEXCEL_CRA_PRIORITY 300 - -+/* System cache line size */ -+#define SYSTEM_CACHELINE_SIZE 64 -+ - /* SM3 digest result for zero length message */ - #define EIP197_SM3_ZEROM_HASH "\x1A\xB2\x1D\x83\x55\xCF\xA1\x7F" \ - "\x8E\x61\x19\x48\x31\xE8\x1A\x8F" \ -diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c -index af4b978189e5..eb640382e17b 100644 ---- a/drivers/crypto/inside-secure/safexcel_hash.c -+++ b/drivers/crypto/inside-secure/safexcel_hash.c -@@ -55,9 +55,9 @@ struct safexcel_ahash_req { - u8 block_sz; /* block size, only set once */ - u8 digest_sz; /* output digest size, only set once */ - __le32 state[SHA3_512_BLOCK_SIZE / -- sizeof(__le32)] __aligned(sizeof(__le32)); -+ sizeof(__le32)] __aligned(SYSTEM_CACHELINE_SIZE); - -- u64 len; -+ u64 len __aligned(SYSTEM_CACHELINE_SIZE); - u64 processed; - - u8 cache[HASH_CACHE_SIZE] __aligned(sizeof(u32)); --- -2.51.0 - - -From a97801fc420b739ae5139abf71e1016a1f09e646 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:59 +0100 -Subject: [PATCH 474/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/410-bt-mtk-serial-fix.patch - ---- - drivers/tty/serial/8250/8250.h | 1 + - drivers/tty/serial/8250/8250_port.c | 7 ++++++- - 2 files changed, 7 insertions(+), 1 deletion(-) - -diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h -index 10a706fe4b24..927a286d185a 100644 ---- a/drivers/tty/serial/8250/8250.h -+++ b/drivers/tty/serial/8250/8250.h -@@ -86,6 +86,7 @@ struct serial8250_config { - * STOP PARITY EPAR SPAR WLEN5 WLEN6 - */ - #define UART_CAP_NOTEMT BIT(18) /* UART without interrupt on TEMT available */ -+#define UART_CAP_NMOD BIT(19) /* UART doesn't do termios */ - - #define UART_BUG_QUOT BIT(0) /* UART has buggy quot LSB */ - #define UART_BUG_TXEN BIT(1) /* UART has buggy TX IIR status */ -diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c -index 03aca7eaca16..6005f78838e8 100644 ---- a/drivers/tty/serial/8250/8250_port.c -+++ b/drivers/tty/serial/8250/8250_port.c -@@ -276,7 +276,7 @@ static const struct serial8250_config uart_config[] = { - .tx_loadsz = 16, - .fcr = UART_FCR_ENABLE_FIFO | - UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT, -- .flags = UART_CAP_FIFO, -+ .flags = UART_CAP_FIFO | UART_CAP_NMOD, - }, - [PORT_NPCM] = { - .name = "Nuvoton 16550", -@@ -2729,6 +2729,11 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, - unsigned long flags; - unsigned int baud, quot, frac = 0; - -+ if (up->capabilities & UART_CAP_NMOD) { -+ termios->c_cflag = 0; -+ return; -+ } -+ - if (up->capabilities & UART_CAP_MINI) { - termios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CMSPAR); - if ((termios->c_cflag & CSIZE) == CS5 || --- -2.51.0 - - -From 4711a23773c1c01b04b8c28af3dd375e28e0c5a2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:50:59 +0100 -Subject: [PATCH 475/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/411-mtd-spinand-fix-support-for-FORESEE.patch - ---- - drivers/mtd/nand/spi/foresee.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/mtd/nand/spi/foresee.c b/drivers/mtd/nand/spi/foresee.c -index 8a01582c0f53..f762d514a362 100644 ---- a/drivers/mtd/nand/spi/foresee.c -+++ b/drivers/mtd/nand/spi/foresee.c -@@ -22,8 +22,8 @@ static SPINAND_OP_VARIANTS(write_cache_variants, - SPINAND_PROG_LOAD(true, 0, NULL, 0)); - - static SPINAND_OP_VARIANTS(update_cache_variants, -- SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), -- SPINAND_PROG_LOAD(false, 0, NULL, 0)); -+ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), -+ SPINAND_PROG_LOAD(true, 0, NULL, 0)); - - static int f35sqa002g_ooblayout_ecc(struct mtd_info *mtd, int section, - struct mtd_oob_region *region) --- -2.51.0 - - -From a40812a662070cc3134ec9bd21e5ca0bb42bd872 Mon Sep 17 00:00:00 2001 -From: "SkyLake.Huang" -Date: Thu, 23 Jun 2022 18:29:51 +0800 -Subject: [PATCH 476/517] drivers: spi-mt65xx: Move chip_config to driver's - private data - -Signed-off-by: SkyLake.Huang ---- - drivers/spi/spi-mt65xx.c | 29 +++++++++--------------- - include/linux/platform_data/spi-mt65xx.h | 17 -------------- - 2 files changed, 11 insertions(+), 35 deletions(-) - delete mode 100644 include/linux/platform_data/spi-mt65xx.h - -diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c -index dfee244fc317..6830325cab71 100644 ---- a/drivers/spi/spi-mt65xx.c -+++ b/drivers/spi/spi-mt65xx.c -@@ -15,7 +15,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -172,6 +171,8 @@ struct mtk_spi { - struct device *dev; - dma_addr_t tx_dma; - dma_addr_t rx_dma; -+ u32 sample_sel; -+ u32 get_tick_dly; - }; - - static const struct mtk_spi_compatible mtk_common_compat; -@@ -217,15 +218,6 @@ static const struct mtk_spi_compatible mt6893_compat = { - .no_need_unprepare = true, - }; - --/* -- * A piece of default chip info unless the platform -- * supplies it. -- */ --static const struct mtk_chip_config mtk_default_chip_info = { -- .sample_sel = 0, -- .tick_delay = 0, --}; -- - static const struct of_device_id mtk_spi_of_match[] = { - { .compatible = "mediatek,spi-ipm", - .data = (void *)&mtk_ipm_compat, -@@ -353,7 +345,6 @@ static int mtk_spi_hw_init(struct spi_controller *host, - { - u16 cpha, cpol; - u32 reg_val; -- struct mtk_chip_config *chip_config = spi->controller_data; - struct mtk_spi *mdata = spi_controller_get_devdata(host); - - cpha = spi->mode & SPI_CPHA ? 1 : 0; -@@ -403,7 +394,7 @@ static int mtk_spi_hw_init(struct spi_controller *host, - else - reg_val &= ~SPI_CMD_CS_POL; - -- if (chip_config->sample_sel) -+ if (mdata->sample_sel) - reg_val |= SPI_CMD_SAMPLE_SEL; - else - reg_val &= ~SPI_CMD_SAMPLE_SEL; -@@ -430,20 +421,20 @@ static int mtk_spi_hw_init(struct spi_controller *host, - if (mdata->dev_comp->ipm_design) { - reg_val = readl(mdata->base + SPI_CMD_REG); - reg_val &= ~SPI_CMD_IPM_GET_TICKDLY_MASK; -- reg_val |= ((chip_config->tick_delay & 0x7) -+ reg_val |= ((mdata->get_tick_dly & 0x7) - << SPI_CMD_IPM_GET_TICKDLY_OFFSET); - writel(reg_val, mdata->base + SPI_CMD_REG); - } else { - reg_val = readl(mdata->base + SPI_CFG1_REG); - reg_val &= ~SPI_CFG1_GET_TICK_DLY_MASK; -- reg_val |= ((chip_config->tick_delay & 0x7) -+ reg_val |= ((mdata->get_tick_dly & 0x7) - << SPI_CFG1_GET_TICK_DLY_OFFSET); - writel(reg_val, mdata->base + SPI_CFG1_REG); - } - } else { - reg_val = readl(mdata->base + SPI_CFG1_REG); - reg_val &= ~SPI_CFG1_GET_TICK_DLY_MASK_V1; -- reg_val |= ((chip_config->tick_delay & 0x3) -+ reg_val |= ((mdata->get_tick_dly & 0x3) - << SPI_CFG1_GET_TICK_DLY_OFFSET_V1); - writel(reg_val, mdata->base + SPI_CFG1_REG); - } -@@ -733,9 +724,6 @@ static int mtk_spi_setup(struct spi_device *spi) - { - struct mtk_spi *mdata = spi_controller_get_devdata(spi->controller); - -- if (!spi->controller_data) -- spi->controller_data = (void *)&mtk_default_chip_info; -- - if (mdata->dev_comp->need_pad_sel && spi_get_csgpiod(spi, 0)) - /* CS de-asserted, gpiolib will handle inversion */ - gpiod_direction_output(spi_get_csgpiod(spi, 0), 0); -@@ -1146,6 +1134,11 @@ static int mtk_spi_probe(struct platform_device *pdev) - host->use_gpio_descriptors = true; - - mdata = spi_controller_get_devdata(host); -+ -+ /* Set device configs to default first. Calibrate it later. */ -+ mdata->sample_sel = 0; -+ mdata->get_tick_dly = 2; -+ - mdata->dev_comp = device_get_match_data(dev); - - if (mdata->dev_comp->enhance_timing) -diff --git a/include/linux/platform_data/spi-mt65xx.h b/include/linux/platform_data/spi-mt65xx.h -deleted file mode 100644 -index f0db674f07b8..000000000000 ---- a/include/linux/platform_data/spi-mt65xx.h -+++ /dev/null -@@ -1,17 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0-only */ --/* -- * MTK SPI bus driver definitions -- * -- * Copyright (c) 2015 MediaTek Inc. -- * Author: Leilk Liu -- */ -- --#ifndef ____LINUX_PLATFORM_DATA_SPI_MTK_H --#define ____LINUX_PLATFORM_DATA_SPI_MTK_H -- --/* Board specific platform_data */ --struct mtk_chip_config { -- u32 sample_sel; -- u32 tick_delay; --}; --#endif --- -2.51.0 - - -From 5d3efaf4850193f1e68e7cba13464ff909cbbb10 Mon Sep 17 00:00:00 2001 -From: "SkyLake.Huang" -Date: Thu, 23 Jun 2022 18:35:52 +0800 -Subject: [PATCH 477/517] drivers: spi: Add support for dynamic calibration - -Signed-off-by: SkyLake.Huang ---- - drivers/spi/spi.c | 137 ++++++++++++++++++++++++++++++++++++++++ - include/linux/spi/spi.h | 42 ++++++++++++ - 2 files changed, 179 insertions(+) - -diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c -index 5ad9f4a2148f..8d5144801178 100644 ---- a/drivers/spi/spi.c -+++ b/drivers/spi/spi.c -@@ -1494,6 +1494,70 @@ static int spi_transfer_wait(struct spi_controller *ctlr, - return 0; - } - -+int spi_do_calibration(struct spi_controller *ctlr, struct spi_device *spi, -+ int (*cal_read)(void *priv, u32 *addr, int addrlen, u8 *buf, int readlen), void *drv_priv) -+{ -+ int datalen = ctlr->cal_rule->datalen; -+ int addrlen = ctlr->cal_rule->addrlen; -+ u8 *buf; -+ int ret; -+ int i; -+ struct list_head *cal_head, *listptr; -+ struct spi_cal_target *target; -+ -+ /* Calculate calibration result */ -+ int hit_val, total_hit, origin; -+ bool hit; -+ -+ /* Make sure we can start calibration */ -+ if(!ctlr->cal_target || !ctlr->cal_rule || !ctlr->append_caldata) -+ return 0; -+ -+ buf = kzalloc(datalen * sizeof(u8), GFP_KERNEL); -+ if(!buf) -+ return -ENOMEM; -+ -+ ret = ctlr->append_caldata(ctlr); -+ if (ret) -+ goto cal_end; -+ -+ cal_head = ctlr->cal_target; -+ list_for_each(listptr, cal_head) { -+ target = list_entry(listptr, struct spi_cal_target, list); -+ -+ hit = false; -+ hit_val = 0; -+ total_hit = 0; -+ origin = *target->cal_item; -+ -+ for(i=target->cal_min; i<=target->cal_max; i+=target->step) { -+ *target->cal_item = i; -+ ret = (*cal_read)(drv_priv, ctlr->cal_rule->addr, addrlen, buf, datalen); -+ if(ret) -+ break; -+ dev_dbg(&spi->dev, "controller cal item value: 0x%x\n", i); -+ if(memcmp(ctlr->cal_rule->match_data, buf, datalen * sizeof(u8)) == 0) { -+ hit = true; -+ hit_val += i; -+ total_hit++; -+ dev_dbg(&spi->dev, "golden data matches data read!\n"); -+ } -+ } -+ if(hit) { -+ *target->cal_item = DIV_ROUND_CLOSEST(hit_val, total_hit); -+ dev_info(&spi->dev, "calibration result: 0x%x", *target->cal_item); -+ } else { -+ *target->cal_item = origin; -+ dev_warn(&spi->dev, "calibration failed, fallback to default: 0x%x", origin); -+ } -+ } -+ -+cal_end: -+ kfree(buf); -+ return ret? ret: 0; -+} -+EXPORT_SYMBOL_GPL(spi_do_calibration); -+ - static void _spi_transfer_delay_ns(u32 ns) - { - if (!ns) -@@ -2352,6 +2416,75 @@ void spi_flush_queue(struct spi_controller *ctlr) - /*-------------------------------------------------------------------------*/ - - #if defined(CONFIG_OF) -+static inline void alloc_cal_data(struct list_head **cal_target, -+ struct spi_cal_rule **cal_rule, bool enable) -+{ -+ if(enable) { -+ *cal_target = kmalloc(sizeof(struct list_head), GFP_KERNEL); -+ INIT_LIST_HEAD(*cal_target); -+ *cal_rule = kmalloc(sizeof(struct spi_cal_rule), GFP_KERNEL); -+ } else { -+ kfree(*cal_target); -+ kfree(*cal_rule); -+ } -+} -+ -+static int of_spi_parse_cal_dt(struct spi_controller *ctlr, struct spi_device *spi, -+ struct device_node *nc) -+{ -+ u32 value; -+ int rc; -+ const char *cal_mode; -+ -+ rc = of_property_read_bool(nc, "spi-cal-enable"); -+ if (rc) -+ alloc_cal_data(&ctlr->cal_target, &ctlr->cal_rule, true); -+ else -+ return 0; -+ -+ rc = of_property_read_string(nc, "spi-cal-mode", &cal_mode); -+ if(!rc) { -+ if(strcmp("read-data", cal_mode) == 0){ -+ ctlr->cal_rule->mode = SPI_CAL_READ_DATA; -+ } else if(strcmp("read-pp", cal_mode) == 0) { -+ ctlr->cal_rule->mode = SPI_CAL_READ_PP; -+ return 0; -+ } else if(strcmp("read-sfdp", cal_mode) == 0){ -+ ctlr->cal_rule->mode = SPI_CAL_READ_SFDP; -+ return 0; -+ } -+ } else -+ goto err; -+ -+ ctlr->cal_rule->datalen = 0; -+ rc = of_property_read_u32(nc, "spi-cal-datalen", &value); -+ if(!rc && value > 0) { -+ ctlr->cal_rule->datalen = value; -+ -+ ctlr->cal_rule->match_data = kzalloc(value * sizeof(u8), GFP_KERNEL); -+ rc = of_property_read_u8_array(nc, "spi-cal-data", -+ ctlr->cal_rule->match_data, value); -+ if(rc) -+ kfree(ctlr->cal_rule->match_data); -+ } -+ -+ rc = of_property_read_u32(nc, "spi-cal-addrlen", &value); -+ if(!rc && value > 0) { -+ ctlr->cal_rule->addrlen = value; -+ -+ ctlr->cal_rule->addr = kzalloc(value * sizeof(u32), GFP_KERNEL); -+ rc = of_property_read_u32_array(nc, "spi-cal-addr", -+ ctlr->cal_rule->addr, value); -+ if(rc) -+ kfree(ctlr->cal_rule->addr); -+ } -+ return 0; -+ -+err: -+ alloc_cal_data(&ctlr->cal_target, &ctlr->cal_rule, false); -+ return 0; -+} -+ - static void of_spi_parse_dt_cs_delay(struct device_node *nc, - struct spi_delay *delay, const char *prop) - { -@@ -2516,6 +2649,10 @@ of_register_spi_device(struct spi_controller *ctlr, struct device_node *nc) - if (rc) - goto err_out; - -+ rc = of_spi_parse_cal_dt(ctlr, spi, nc); -+ if (rc) -+ goto err_out; -+ - /* Store a pointer to the node in the device structure */ - of_node_get(nc); - -diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h -index 71ad766932d3..9ccc08819613 100644 ---- a/include/linux/spi/spi.h -+++ b/include/linux/spi/spi.h -@@ -348,6 +348,40 @@ struct spi_driver { - struct device_driver driver; - }; - -+enum { -+ SPI_CAL_READ_DATA = 0, -+ SPI_CAL_READ_PP = 1, /* only for SPI-NAND */ -+ SPI_CAL_READ_SFDP = 2, /* only for SPI-NOR */ -+}; -+ -+struct nand_addr { -+ unsigned int lun; -+ unsigned int plane; -+ unsigned int eraseblock; -+ unsigned int page; -+ unsigned int dataoffs; -+}; -+ -+/** -+ * Read calibration rule from device dts node. -+ * Once calibration result matches the rule, we regard is as success. -+ */ -+struct spi_cal_rule { -+ int datalen; -+ u8 *match_data; -+ int addrlen; -+ u32 *addr; -+ int mode; -+}; -+ -+struct spi_cal_target { -+ u32 *cal_item; -+ int cal_min; /* min of cal_item */ -+ int cal_max; /* max of cal_item */ -+ int step; /* Increase/decrease cal_item */ -+ struct list_head list; -+}; -+ - #define to_spi_driver(__drv) \ - ( __drv ? container_of_const(__drv, struct spi_driver, driver) : NULL ) - -@@ -754,6 +788,11 @@ struct spi_controller { - void *dummy_rx; - void *dummy_tx; - -+ /* For calibration */ -+ int (*append_caldata)(struct spi_controller *ctlr); -+ struct list_head *cal_target; -+ struct spi_cal_rule *cal_rule; -+ - int (*fw_translate_cs)(struct spi_controller *ctlr, unsigned cs); - - /* -@@ -1657,6 +1696,9 @@ spi_register_board_info(struct spi_board_info const *info, unsigned n) - { return 0; } - #endif - -+extern int spi_do_calibration(struct spi_controller *ctlr, -+ struct spi_device *spi, int (*cal_read)(void *, u32 *, int, u8 *, int), void *drv_priv); -+ - /* - * If you're hotplugging an adapter with devices (parport, USB, etc) - * use spi_new_device() to describe each device. You can also call --- -2.51.0 - - -From 98ba0b15846cc6f0664d651a42a650cf5af8ce71 Mon Sep 17 00:00:00 2001 -From: "SkyLake.Huang" -Date: Thu, 23 Jun 2022 18:37:55 +0800 -Subject: [PATCH 478/517] drivers: spi-mem: Add spi calibration hook - -Signed-off-by: SkyLake.Huang ---- - drivers/spi/spi-mem.c | 8 ++++++++ - include/linux/spi/spi-mem.h | 4 ++++ - 2 files changed, 12 insertions(+) - -diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c -index 17b8baf749e6..597e6157d051 100644 ---- a/drivers/spi/spi-mem.c -+++ b/drivers/spi/spi-mem.c -@@ -466,6 +466,14 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) - } - EXPORT_SYMBOL_GPL(spi_mem_exec_op); - -+int spi_mem_do_calibration(struct spi_mem *mem, -+ int (*cal_read)(void *priv, u32 *addr, int addrlen, u8 *buf, int readlen), -+ void *priv) -+{ -+ return spi_do_calibration(mem->spi->controller, mem->spi, cal_read, priv); -+} -+EXPORT_SYMBOL_GPL(spi_mem_do_calibration); -+ - /** - * spi_mem_get_name() - Return the SPI mem device name to be used by the - * upper layer if necessary -diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h -index f866d5c8ed32..821ab7055640 100644 ---- a/include/linux/spi/spi-mem.h -+++ b/include/linux/spi/spi-mem.h -@@ -372,6 +372,10 @@ bool spi_mem_supports_op(struct spi_mem *mem, - int spi_mem_exec_op(struct spi_mem *mem, - const struct spi_mem_op *op); - -+int spi_mem_do_calibration(struct spi_mem *mem, -+ int (*cal_read)(void *, u32 *, int, u8 *, int), -+ void *priv); -+ - const char *spi_mem_get_name(struct spi_mem *mem); - - struct spi_mem_dirmap_desc * --- -2.51.0 - - -From 4471f9130681170008741e9988d8a96767a3b5ba Mon Sep 17 00:00:00 2001 -From: "SkyLake.Huang" -Date: Thu, 23 Jun 2022 18:39:03 +0800 -Subject: [PATCH 479/517] drivers: spi-mt65xx: Add controller's calibration - paramter - -Signed-off-by: SkyLake.Huang ---- - drivers/spi/spi-mt65xx.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c -index 6830325cab71..906e188987c8 100644 ---- a/drivers/spi/spi-mt65xx.c -+++ b/drivers/spi/spi-mt65xx.c -@@ -842,6 +842,21 @@ static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id) - return IRQ_WAKE_THREAD; - } - -+static int mtk_spi_append_caldata(struct spi_controller *ctlr) -+{ -+ struct spi_cal_target *cal_target = kmalloc(sizeof(*cal_target), GFP_KERNEL); -+ struct mtk_spi *mdata = spi_controller_get_devdata(ctlr); -+ -+ cal_target->cal_item = &mdata->get_tick_dly; -+ cal_target->cal_min = 0; -+ cal_target->cal_max = 7; -+ cal_target->step = 1; -+ -+ list_add(&cal_target->list, ctlr->cal_target); -+ -+ return 0; -+} -+ - static int mtk_spi_mem_adjust_op_size(struct spi_mem *mem, - struct spi_mem_op *op) - { -@@ -1132,6 +1147,7 @@ static int mtk_spi_probe(struct platform_device *pdev) - host->setup = mtk_spi_setup; - host->set_cs_timing = mtk_spi_set_hw_cs_timing; - host->use_gpio_descriptors = true; -+ host->append_caldata = mtk_spi_append_caldata; - - mdata = spi_controller_get_devdata(host); - --- -2.51.0 - - -From 12093e201819865a1a75fad0932a37f7213f0195 Mon Sep 17 00:00:00 2001 -From: "SkyLake.Huang" -Date: Thu, 23 Jun 2022 18:39:56 +0800 -Subject: [PATCH 480/517] drivers: mtd: spinand: Add calibration support for - spinand - -Signed-off-by: SkyLake.Huang ---- - drivers/mtd/nand/spi/core.c | 54 +++++++++++++++++++++++++++++++++++++ - 1 file changed, 54 insertions(+) - -diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c -index d0071aba4f77..ed8a2d2b2dd2 100644 ---- a/drivers/mtd/nand/spi/core.c -+++ b/drivers/mtd/nand/spi/core.c -@@ -1200,6 +1200,56 @@ static int spinand_manufacturer_match(struct spinand_device *spinand, - return -EOPNOTSUPP; - } - -+static int spinand_cal_read(void *priv, u32 *addr, int addrlen, u8 *buf, int readlen) { -+ struct spinand_device *spinand = (struct spinand_device *)priv; -+ struct device *dev = &spinand->spimem->spi->dev; -+ struct spi_mem_op op = SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, buf, readlen); -+ struct nand_pos pos; -+ struct nand_page_io_req req; -+ u8 status; -+ int ret; -+ -+ if(addrlen != sizeof(struct nand_addr)/sizeof(unsigned int)) { -+ dev_err(dev, "Must provide correct addr(length) for spinand calibration\n"); -+ return -EINVAL; -+ } -+ -+ ret = spinand_reset_op(spinand); -+ if (ret) -+ return ret; -+ -+ /* We should store our golden data in first target because -+ * we can't switch target at this moment. -+ */ -+ pos = (struct nand_pos){ -+ .target = 0, -+ .lun = *addr, -+ .plane = *(addr+1), -+ .eraseblock = *(addr+2), -+ .page = *(addr+3), -+ }; -+ -+ req = (struct nand_page_io_req){ -+ .pos = pos, -+ .dataoffs = *(addr+4), -+ .datalen = readlen, -+ .databuf.in = buf, -+ .mode = MTD_OPS_AUTO_OOB, -+ }; -+ -+ ret = spinand_load_page_op(spinand, &req); -+ if (ret) -+ return ret; -+ -+ ret = spinand_wait(spinand, &status); -+ if (ret < 0) -+ return ret; -+ -+ ret = spi_mem_exec_op(spinand->spimem, &op); -+ -+ return 0; -+} -+ - static int spinand_id_detect(struct spinand_device *spinand) - { - u8 *id = spinand->id.data; -@@ -1451,6 +1501,10 @@ static int spinand_init(struct spinand_device *spinand) - if (!spinand->scratchbuf) - return -ENOMEM; - -+ ret = spi_mem_do_calibration(spinand->spimem, spinand_cal_read, spinand); -+ if (ret) -+ dev_err(dev, "Failed to calibrate SPI-NAND (err = %d)\n", ret); -+ - ret = spinand_detect(spinand); - if (ret) - goto err_free_bufs; --- -2.51.0 - - -From 4041e34414c85a3f4bbfd292b255cce4eb722b49 Mon Sep 17 00:00:00 2001 -From: "SkyLake.Huang" -Date: Thu, 23 Jun 2022 18:40:59 +0800 -Subject: [PATCH 481/517] drivers: mtd: spi-nor: Add calibration support for - spi-nor - -Signed-off-by: SkyLake.Huang ---- - drivers/mtd/nand/spi/core.c | 5 ++++- - drivers/mtd/spi-nor/core.c | 15 +++++++++++++++ - 2 files changed, 19 insertions(+), 1 deletion(-) - -diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c -index ed8a2d2b2dd2..a74bda5c4965 100644 ---- a/drivers/mtd/nand/spi/core.c -+++ b/drivers/mtd/nand/spi/core.c -@@ -1241,7 +1241,10 @@ static int spinand_cal_read(void *priv, u32 *addr, int addrlen, u8 *buf, int rea - if (ret) - return ret; - -- ret = spinand_wait(spinand, &status); -+ ret = spinand_wait(spinand, -+ SPINAND_READ_INITIAL_DELAY_US, -+ SPINAND_READ_POLL_DELAY_US, -+ &status); - if (ret < 0) - return ret; - -diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c -index 5bb7da0ef34d..de146408e605 100644 ---- a/drivers/mtd/spi-nor/core.c -+++ b/drivers/mtd/spi-nor/core.c -@@ -3300,6 +3300,18 @@ static const struct flash_info *spi_nor_match_name(struct spi_nor *nor, - return NULL; - } - -+static int spi_nor_cal_read(void *priv, u32 *addr, int addrlen, u8 *buf, int readlen) -+{ -+ struct spi_nor *nor = (struct spi_nor *)priv; -+ -+ nor->reg_proto = SNOR_PROTO_1_1_1; -+ nor->read_proto = SNOR_PROTO_1_1_1; -+ nor->read_opcode = SPINOR_OP_READ; -+ nor->read_dummy = 0; -+ -+ return nor->controller_ops->read(nor, *addr, readlen, buf); -+} -+ - static const struct flash_info *spi_nor_get_flash_info(struct spi_nor *nor, - const char *name) - { -@@ -3474,6 +3486,9 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, - if (ret) - return ret; - -+ if(nor->spimem) -+ spi_mem_do_calibration(nor->spimem, spi_nor_cal_read, nor); -+ - info = spi_nor_get_flash_info(nor, name); - if (IS_ERR(info)) - return PTR_ERR(info); --- -2.51.0 - - -From 989bc477ae72c09f5068823fd74d038b4219c6f2 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Wed, 12 Jul 2023 13:38:35 +0100 -Subject: [PATCH 482/517] nvmem: add layout for Adtran devices - -Adtran stores unique factory data on GPT partitions on the eMMC. -Using blk-nvmem the 'mfginfo' partition gets exposes as NVMEM provider. - -Add layout driver to parse mfginfo, mainly to provide MAC addresses to -Ethernet and wireless interfaces. - -Variable names are converted to lower-case and '_' is replaced with '-' -in order to comply with the device tree node naming convention. -The main MAC address always ends on a 0 and up to 16 addresses are -alocated for each device to use for various interfaces. - -Implement post-processing function for 'MFG_MAC' variable ('mfg-mac' -node name in device tree) adding the nvmem cell index to the least -significant digit of the MAC address. - -Signed-off-by: Daniel Golle ---- - drivers/nvmem/layouts/Kconfig | 9 +++ - drivers/nvmem/layouts/Makefile | 1 + - drivers/nvmem/layouts/adtran.c | 135 +++++++++++++++++++++++++++++++++ - 3 files changed, 145 insertions(+) - create mode 100644 drivers/nvmem/layouts/adtran.c - -diff --git a/drivers/nvmem/layouts/Kconfig b/drivers/nvmem/layouts/Kconfig -index 58df4ad61e13..3b8ef65629b7 100644 ---- a/drivers/nvmem/layouts/Kconfig -+++ b/drivers/nvmem/layouts/Kconfig -@@ -8,6 +8,15 @@ if NVMEM_LAYOUTS - - menu "Layout Types" - -+config NVMEM_LAYOUT_ADTRAN -+ tristate "Adtran mfginfo layout support" -+ select GENERIC_NET_UTILS -+ help -+ Say Y here if you want to support the layout used by Adtran for -+ mfginfo. -+ -+ If unsure, say N. -+ - config NVMEM_LAYOUT_SL28_VPD - tristate "Kontron sl28 VPD layout support" - select CRC8 -diff --git a/drivers/nvmem/layouts/Makefile b/drivers/nvmem/layouts/Makefile -index 060ddf18d05a..75902980e89a 100644 ---- a/drivers/nvmem/layouts/Makefile -+++ b/drivers/nvmem/layouts/Makefile -@@ -6,4 +6,5 @@ - obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o - obj-$(CONFIG_NVMEM_LAYOUT_ONIE_TLV) += onie-tlv.o - obj-$(CONFIG_NVMEM_LAYOUT_U_BOOT_ENV) += u-boot-env.o -+obj-$(CONFIG_NVMEM_LAYOUT_ADTRAN) += adtran.o - obj-$(CONFIG_NVMEM_LAYOUT_ASCII_ENV) += ascii-env.o -diff --git a/drivers/nvmem/layouts/adtran.c b/drivers/nvmem/layouts/adtran.c -new file mode 100644 -index 000000000000..65f55f413917 ---- /dev/null -+++ b/drivers/nvmem/layouts/adtran.c -@@ -0,0 +1,135 @@ -+// SPDX-License-Identifier: GPL-2.0 -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* -+ * Adtran devices usually come with a main MAC address ending on 0 and -+ * hence may have up to 16 MAC addresses per device. -+ * The main MAC address is stored as variable MFG_MAC in ASCII format. -+ */ -+static int adtran_mac_address_pp(void *priv, const char *id, int index, -+ unsigned int offset, void *buf, -+ size_t bytes) -+{ -+ u8 mac[ETH_ALEN]; -+ -+ if (WARN_ON(bytes != 3 * ETH_ALEN - 1)) -+ return -EINVAL; -+ -+ if (!mac_pton(buf, mac)) -+ return -EINVAL; -+ -+ if (index) -+ eth_addr_add(mac, index); -+ -+ ether_addr_copy(buf, mac); -+ -+ return 0; -+} -+ -+static int adtran_add_cells(struct nvmem_layout *layout) -+{ -+ struct nvmem_device *nvmem = layout->nvmem; -+ struct nvmem_cell_info info; -+ struct device_node *layout_np; -+ char mfginfo[1024], *c, *t, *p; -+ int ret = -EINVAL; -+ -+ ret = nvmem_device_read(nvmem, 0, sizeof(mfginfo), mfginfo); -+ if (ret < 0) -+ return ret; -+ else if (ret != sizeof(mfginfo)) -+ return -EIO; -+ -+ layout_np = of_nvmem_layout_get_container(nvmem); -+ if (!layout_np) -+ return -ENOENT; -+ -+ c = mfginfo; -+ while (*c != 0xff) { -+ memset(&info, 0, sizeof(info)); -+ if (*c == '#') -+ goto nextline; -+ -+ t = strchr(c, '='); -+ if (!t) -+ goto nextline; -+ -+ *t = '\0'; -+ ++t; -+ info.offset = t - mfginfo; -+ /* process variable name: convert to lower-case, '_' -> '-' */ -+ p = c; -+ do { -+ *p = tolower(*p); -+ if (*p == '_') -+ *p = '-'; -+ } while (*++p); -+ info.name = c; -+ c = strchr(t, 0xa); /* find newline */ -+ if (!c) -+ break; -+ -+ info.bytes = c - t; -+ if (!strcmp(info.name, "mfg-mac")) { -+ info.raw_len = info.bytes; -+ info.bytes = ETH_ALEN; -+ info.read_post_process = adtran_mac_address_pp; -+ } -+ -+ info.np = of_get_child_by_name(layout_np, info.name); -+ ret = nvmem_add_one_cell(nvmem, &info); -+ if (ret) -+ break; -+ -+ ++c; -+ continue; -+ -+nextline: -+ c = strchr(c, 0xa); /* find newline */ -+ if (!c) -+ break; -+ ++c; -+ } -+ -+ of_node_put(layout_np); -+ -+ return ret; -+} -+ -+static int adtran_probe(struct nvmem_layout *layout) -+{ -+ layout->add_cells = adtran_add_cells; -+ -+ return nvmem_layout_register(layout); -+} -+ -+static void adtran_remove(struct nvmem_layout *layout) -+{ -+ nvmem_layout_unregister(layout); -+} -+ -+static const struct of_device_id adtran_of_match_table[] = { -+ { .compatible = "adtran,mfginfo" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, adtran_of_match_table); -+ -+static struct nvmem_layout_driver adtran_layout = { -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = "adtran-layout", -+ .of_match_table = adtran_of_match_table, -+ }, -+ .probe = adtran_probe, -+ .remove = adtran_remove, -+}; -+module_nvmem_layout_driver(adtran_layout); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Daniel Golle "); -+MODULE_DESCRIPTION("NVMEM layout driver for Adtran mfginfo"); --- -2.51.0 - - -From 21831b4ae092e1a34c89accb466796f284aecccd Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:51:02 +0100 -Subject: [PATCH 483/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/500-gsw-rtl8367s-mt7622-support.patch - ---- - drivers/net/phy/Kconfig | 6 ++++++ - drivers/net/phy/Makefile | 1 + - 2 files changed, 7 insertions(+) - -diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig -index 0e672540a0fa..2fcb9544a3b0 100644 ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -443,6 +443,12 @@ config ROCKCHIP_PHY - help - Currently supports the integrated Ethernet PHY. - -+config RTL8367S_GSW -+ tristate "rtl8367 Gigabit Switch support for mt7622" -+ depends on NET_VENDOR_MEDIATEK -+ help -+ This driver supports rtl8367s in mt7622 -+ - config SMSC_PHY - tristate "SMSC PHYs" - select CRC16 -diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile -index d0f2b36d5c87..f869dd4a7ff4 100644 ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -113,6 +113,7 @@ obj-$(CONFIG_REALTEK_PHY) += realtek/ - obj-y += rtl8261n/ - obj-$(CONFIG_RENESAS_PHY) += uPD60620.o - obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o -+obj-$(CONFIG_RTL8367S_GSW) += rtk/ - obj-$(CONFIG_SMSC_PHY) += smsc.o - obj-$(CONFIG_STE10XP) += ste10Xp.o - obj-$(CONFIG_TERANETICS_PHY) += teranetics.o --- -2.51.0 - - -From 3e406f4731e75b7970b37050aacbeba4dec6adbc Mon Sep 17 00:00:00 2001 -From: qizhong cheng -Date: Mon, 27 Dec 2021 21:31:10 +0800 -Subject: [PATCH 484/517] PCI: mediatek: Assert PERST# for 100ms for power and - clock to stabilize -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Described in PCIe CEM specification sections 2.2 (PERST# Signal) and -2.2.1 (Initial Power-Up (G3 to S0)). The deassertion of PERST# should -be delayed 100ms (TPVPERL) for the power and clock to become stable. - -Link: https://lore.kernel.org/r/20211227133110.14500-1-qizhong.cheng@mediatek.com -Signed-off-by: qizhong cheng -Signed-off-by: Lorenzo Pieralisi -Acked-by: Pali Rohár ---- - drivers/pci/controller/pcie-mediatek.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c -index 7f7d04c2ea57..bebad5744f6a 100644 ---- a/drivers/pci/controller/pcie-mediatek.c -+++ b/drivers/pci/controller/pcie-mediatek.c -@@ -700,6 +700,13 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port) - */ - msleep(100); - -+ /* -+ * Described in PCIe CEM specification sections 2.2 (PERST# Signal) and -+ * 2.2.1 (Initial Power-Up (G3 to S0)). The deassertion of PERST# should -+ * be delayed 100ms (TPVPERL) for the power and clock to become stable. -+ */ -+ msleep(100); -+ - /* De-assert PHY, PE, PIPE, MAC and configuration reset */ - val = readl(port->base + PCIE_RST_CTRL); - val |= PCIE_PHY_RSTB | PCIE_PERSTB | PCIE_PIPE_SRSTB | --- -2.51.0 - - -From 2b9d1f47e69e82aed8f0bd2a2d90058b0e3d419d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:51:03 +0100 -Subject: [PATCH 485/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/602-arm64-dts-mediatek-add-mt7622-pcie-slot-node.patch - ---- - arch/arm64/boot/dts/mediatek/mt7622.dtsi | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi -index 39c57987412e..ce802c3b22df 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi -@@ -844,6 +844,12 @@ pcie_intc0: interrupt-controller { - #address-cells = <0>; - #interrupt-cells = <1>; - }; -+ -+ slot0: pcie@0,0 { -+ reg = <0x0000 0 0 0 0>; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ }; - }; - - pcie1: pcie@1a145000 { -@@ -882,6 +888,12 @@ pcie_intc1: interrupt-controller { - #address-cells = <0>; - #interrupt-cells = <1>; - }; -+ -+ slot1: pcie@1,0 { -+ reg = <0x0800 0 0 0 0>; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ }; - }; - - sata: sata@1a200000 { --- -2.51.0 - - -From 69fde5ab7287db38c278acdb564529d89ad28e10 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 4 Sep 2020 18:33:27 +0200 -Subject: [PATCH 486/517] pcie-mediatek: fix clearing interrupt status - -Clearing the status needs to happen after running the handler, otherwise -we will get an extra spurious interrupt after the cause has been cleared - -Signed-off-by: Felix Fietkau ---- - drivers/pci/controller/pcie-mediatek.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c -index bebad5744f6a..b723cdfab3a0 100644 ---- a/drivers/pci/controller/pcie-mediatek.c -+++ b/drivers/pci/controller/pcie-mediatek.c -@@ -599,9 +599,9 @@ static void mtk_pcie_intr_handler(struct irq_desc *desc) - if (status & INTX_MASK) { - for_each_set_bit_from(bit, &status, PCI_NUM_INTX + INTX_SHIFT) { - /* Clear the INTx */ -- writel(1 << bit, port->base + PCIE_INT_STATUS); - generic_handle_domain_irq(port->irq_domain, - bit - INTX_SHIFT); -+ writel(1 << bit, port->base + PCIE_INT_STATUS); - } - } - --- -2.51.0 - - -From 02b4f75a67349d0d6d444424714f3af80ee1d8b1 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:51:03 +0100 -Subject: [PATCH 487/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/611-pcie-mediatek-gen3-PERST-for-100ms.patch - ---- - drivers/pci/controller/pcie-mediatek-gen3.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c -index 66ce4b5d309b..ebc9f95871f9 100644 ---- a/drivers/pci/controller/pcie-mediatek-gen3.c -+++ b/drivers/pci/controller/pcie-mediatek-gen3.c -@@ -416,7 +416,13 @@ static int mtk_pcie_startup_port(struct mtk_gen3_pcie *pcie) - msleep(100); - - /* De-assert reset signals */ -- val &= ~(PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB | PCIE_PE_RSTB); -+ val &= ~(PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB); -+ writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG); -+ -+ msleep(100); -+ -+ /* De-assert PERST# signals */ -+ val &= ~(PCIE_PE_RSTB); - writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG); - - /* Check if the link is up or not */ --- -2.51.0 - - -From c4fd81f1dc30a95d6edce67a6cbc0fa933c403b2 Mon Sep 17 00:00:00 2001 -From: Sky Huang -Date: Wed, 19 Feb 2025 16:39:08 +0800 -Subject: [PATCH 488/517] net: phy: mediatek: Add 2.5Gphy firmware dt-bindings - and dts node - -Add 2.5Gphy firmware dt-bindings and dts node since mtk-2p5ge -driver requires firmware to run. Also, update MAINTAINERS for -MediaTek's built-in 2.5Gphy dt-bindings and change MAINTAINER's name. - -Signed-off-by: Sky Huang ---- - .../bindings/net/mediatek,2p5gphy-fw.yaml | 37 +++++++++++++++++++ - MAINTAINERS | 3 +- - 2 files changed, 39 insertions(+), 1 deletion(-) - create mode 100644 Documentation/devicetree/bindings/net/mediatek,2p5gphy-fw.yaml - -diff --git a/Documentation/devicetree/bindings/net/mediatek,2p5gphy-fw.yaml b/Documentation/devicetree/bindings/net/mediatek,2p5gphy-fw.yaml -new file mode 100644 -index 000000000000..56ebe88b8921 ---- /dev/null -+++ b/Documentation/devicetree/bindings/net/mediatek,2p5gphy-fw.yaml -@@ -0,0 +1,37 @@ -+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/net/mediatek,2p5gphy-fw.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: MediaTek Built-in 2.5G Ethernet PHY -+ -+maintainers: -+ - Sky Huang -+ -+description: | -+ MediaTek Built-in 2.5G Ethernet PHY needs to load firmware so it can -+ run correctly. -+ -+properties: -+ compatible: -+ const: "mediatek,2p5gphy-fw" -+ -+ reg: -+ items: -+ - description: pmb firmware load address -+ - description: firmware trigger register -+ -+required: -+ - compatible -+ - reg -+ -+additionalProperties: false -+ -+examples: -+ - | -+ phyfw: phy-firmware@f000000 { -+ compatible = "mediatek,2p5gphy-fw"; -+ reg = <0 0x0f100000 0 0x20000>, -+ <0 0x0f0f0018 0 0x20>; -+ }; -diff --git a/MAINTAINERS b/MAINTAINERS -index 3a22c29b35a6..f04fc126dd78 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -14426,9 +14426,10 @@ F: include/linux/pcs/pcs-mtk-usxgmii.h - MEDIATEK ETHERNET PHY DRIVERS - M: Daniel Golle - M: Qingfang Deng --M: SkyLake Huang -+M: Sky Huang - L: netdev@vger.kernel.org - S: Maintained -+F: Documentation/devicetree/bindings/net/mediatek,2p5gphy-fw.yaml - F: drivers/net/phy/mediatek/mtk-ge-soc.c - F: drivers/net/phy/mediatek/mtk-phy-lib.c - F: drivers/net/phy/mediatek/mtk-ge.c --- -2.51.0 - - -From 6b90226390bcd6d572873fe141aa5eec27f598ba Mon Sep 17 00:00:00 2001 -From: Sky Huang -Date: Wed, 19 Feb 2025 16:39:10 +0800 -Subject: [PATCH 489/517] net: phy: mediatek: add driver for built-in 2.5G - ethernet PHY on MT7988 - -Add support for internal 2.5Gphy on MT7988. This driver will load -necessary firmware and add appropriate time delay to make sure -that firmware works stably. Also, certain control registers will -be set to fix link-up issues. - -Signed-off-by: Sky Huang ---- - MAINTAINERS | 1 + - drivers/net/phy/mediatek/Kconfig | 11 + - drivers/net/phy/mediatek/Makefile | 1 + - drivers/net/phy/mediatek/mtk-2p5ge.c | 342 +++++++++++++++++++++++++++ - 4 files changed, 355 insertions(+) - create mode 100644 drivers/net/phy/mediatek/mtk-2p5ge.c - -diff --git a/MAINTAINERS b/MAINTAINERS -index f04fc126dd78..8495e72f363b 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -14430,6 +14430,7 @@ M: Sky Huang - L: netdev@vger.kernel.org - S: Maintained - F: Documentation/devicetree/bindings/net/mediatek,2p5gphy-fw.yaml -+F: drivers/net/phy/mediatek/mtk-2p5ge.c - F: drivers/net/phy/mediatek/mtk-ge-soc.c - F: drivers/net/phy/mediatek/mtk-phy-lib.c - F: drivers/net/phy/mediatek/mtk-ge.c -diff --git a/drivers/net/phy/mediatek/Kconfig b/drivers/net/phy/mediatek/Kconfig -index 4308002bb82c..6f8f69213aae 100644 ---- a/drivers/net/phy/mediatek/Kconfig -+++ b/drivers/net/phy/mediatek/Kconfig -@@ -26,3 +26,14 @@ config MEDIATEK_GE_SOC_PHY - the MT7981 and MT7988 SoCs. These PHYs need calibration data - present in the SoCs efuse and will dynamically calibrate VCM - (common-mode voltage) during startup. -+ -+config MEDIATEK_2P5GE_PHY -+ tristate "MediaTek 2.5Gb Ethernet PHYs" -+ depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST -+ select MTK_NET_PHYLIB -+ help -+ Supports MediaTek SoC built-in 2.5Gb Ethernet PHYs. -+ -+ This will load necessary firmware and add appropriate time delay. -+ Accelerate this procedure through internal pbus instead of MDIO -+ bus. Certain link-up issues will also be fixed here. -diff --git a/drivers/net/phy/mediatek/Makefile b/drivers/net/phy/mediatek/Makefile -index 814879d0abe5..c6db8abd2c9c 100644 ---- a/drivers/net/phy/mediatek/Makefile -+++ b/drivers/net/phy/mediatek/Makefile -@@ -2,3 +2,4 @@ - obj-$(CONFIG_MTK_NET_PHYLIB) += mtk-phy-lib.o - obj-$(CONFIG_MEDIATEK_GE_PHY) += mtk-ge.o - obj-$(CONFIG_MEDIATEK_GE_SOC_PHY) += mtk-ge-soc.o -+obj-$(CONFIG_MEDIATEK_2P5GE_PHY) += mtk-2p5ge.o -diff --git a/drivers/net/phy/mediatek/mtk-2p5ge.c b/drivers/net/phy/mediatek/mtk-2p5ge.c -new file mode 100644 -index 000000000000..9e5a0331e719 ---- /dev/null -+++ b/drivers/net/phy/mediatek/mtk-2p5ge.c -@@ -0,0 +1,342 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mtk.h" -+ -+#define MTK_2P5GPHY_ID_MT7988 (0x00339c11) -+ -+#define MT7988_2P5GE_PMB_FW "mediatek/mt7988/i2p5ge-phy-pmb.bin" -+#define MT7988_2P5GE_PMB_FW_SIZE (0x20000) -+#define MD32_EN_CFG (0x18) -+#define MD32_EN BIT(0) -+ -+#define BASE100T_STATUS_EXTEND (0x10) -+#define BASE1000T_STATUS_EXTEND (0x11) -+#define EXTEND_CTRL_AND_STATUS (0x16) -+ -+#define PHY_AUX_CTRL_STATUS (0x1d) -+#define PHY_AUX_DPX_MASK GENMASK(5, 5) -+#define PHY_AUX_SPEED_MASK GENMASK(4, 2) -+ -+/* Registers on MDIO_MMD_VEND1 */ -+#define MTK_PHY_LPI_PCS_DSP_CTRL (0x121) -+#define MTK_PHY_LPI_SIG_EN_LO_THRESH100_MASK GENMASK(12, 8) -+ -+#define MTK_PHY_HOST_CMD1 0x800e -+#define MTK_PHY_HOST_CMD2 0x800f -+/* Registers on Token Ring debug nodes */ -+/* ch_addr = 0x0, node_addr = 0xf, data_addr = 0x3c */ -+#define AUTO_NP_10XEN BIT(6) -+ -+struct mtk_i2p5ge_phy_priv { -+ bool fw_loaded; -+}; -+ -+enum { -+ PHY_AUX_SPD_10 = 0, -+ PHY_AUX_SPD_100, -+ PHY_AUX_SPD_1000, -+ PHY_AUX_SPD_2500, -+}; -+ -+static int mt798x_2p5ge_phy_load_fw(struct phy_device *phydev) -+{ -+ struct mtk_i2p5ge_phy_priv *priv = phydev->priv; -+ void __iomem *mcu_csr_base, *pmb_addr; -+ struct device *dev = &phydev->mdio.dev; -+ const struct firmware *fw; -+ struct device_node *np; -+ int ret, i; -+ u32 reg; -+ -+ np = of_find_compatible_node(NULL, NULL, "mediatek,2p5gphy-fw"); -+ if (!np) -+ return -ENOENT; -+ -+ pmb_addr = of_iomap(np, 0); -+ if (!pmb_addr) -+ return -ENOMEM; -+ mcu_csr_base = of_iomap(np, 1); -+ if (!mcu_csr_base) { -+ ret = -ENOMEM; -+ goto free_pmb; -+ } -+ -+ ret = request_firmware(&fw, MT7988_2P5GE_PMB_FW, dev); -+ if (ret) { -+ dev_err(dev, "failed to load firmware: %s, ret: %d\n", -+ MT7988_2P5GE_PMB_FW, ret); -+ goto free; -+ } -+ -+ if (fw->size != MT7988_2P5GE_PMB_FW_SIZE) { -+ dev_err(dev, "Firmware size 0x%zx != 0x%x\n", -+ fw->size, MT7988_2P5GE_PMB_FW_SIZE); -+ ret = -EINVAL; -+ goto release_fw; -+ } -+ -+ reg = readw(mcu_csr_base + MD32_EN_CFG); -+ if (reg & MD32_EN) { -+ phy_set_bits(phydev, MII_BMCR, BMCR_RESET); -+ usleep_range(10000, 11000); -+ } -+ phy_set_bits(phydev, MII_BMCR, BMCR_PDOWN); -+ -+ /* Write magic number to safely stall MCU */ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_HOST_CMD1, 0x1100); -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_HOST_CMD2, 0x00df); -+ -+ for (i = 0; i < MT7988_2P5GE_PMB_FW_SIZE - 1; i += 4) -+ writel(*((uint32_t *)(fw->data + i)), pmb_addr + i); -+ -+ if (!priv->fw_loaded) -+ dev_info(dev, "Firmware date code: %x/%x/%x, version: %x.%x\n", -+ be16_to_cpu(*((__be16 *)(fw->data + -+ MT7988_2P5GE_PMB_FW_SIZE - 8))), -+ *(fw->data + MT7988_2P5GE_PMB_FW_SIZE - 6), -+ *(fw->data + MT7988_2P5GE_PMB_FW_SIZE - 5), -+ *(fw->data + MT7988_2P5GE_PMB_FW_SIZE - 2), -+ *(fw->data + MT7988_2P5GE_PMB_FW_SIZE - 1)); -+ -+ writew(reg & ~MD32_EN, mcu_csr_base + MD32_EN_CFG); -+ writew(reg | MD32_EN, mcu_csr_base + MD32_EN_CFG); -+ phy_set_bits(phydev, MII_BMCR, BMCR_RESET); -+ /* We need a delay here to stabilize initialization of MCU */ -+ usleep_range(7000, 8000); -+ -+ priv->fw_loaded = true; -+ -+release_fw: -+ release_firmware(fw); -+free: -+ iounmap(mcu_csr_base); -+free_pmb: -+ iounmap(pmb_addr); -+ -+ return ret; -+} -+ -+static int mt798x_2p5ge_phy_config_init(struct phy_device *phydev) -+{ -+ struct pinctrl *pinctrl; -+ int ret; -+ -+ /* Check if PHY interface type is compatible */ -+ if (phydev->interface != PHY_INTERFACE_MODE_INTERNAL) -+ return -ENODEV; -+ -+ ret = mt798x_2p5ge_phy_load_fw(phydev); -+ if (ret < 0) -+ return ret; -+ -+ /* Setup LED */ -+ phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL, -+ MTK_PHY_LED_ON_POLARITY | MTK_PHY_LED_ON_LINK10 | -+ MTK_PHY_LED_ON_LINK100 | MTK_PHY_LED_ON_LINK1000 | -+ MTK_PHY_LED_ON_LINK2500); -+ phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED1_ON_CTRL, -+ MTK_PHY_LED_ON_FDX | MTK_PHY_LED_ON_HDX); -+ -+ /* Switch pinctrl after setting polarity to avoid bogus blinking */ -+ pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "i2p5gbe-led"); -+ if (IS_ERR(pinctrl) && PTR_ERR(pinctrl) != -ENODEV) -+ dev_err(&phydev->mdio.dev, "Fail to set LED pins!\n"); -+ -+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LPI_PCS_DSP_CTRL, -+ MTK_PHY_LPI_SIG_EN_LO_THRESH100_MASK, 0); -+ -+ /* Enable 16-bit next page exchange bit if 1000-BT isn't advertising */ -+ mtk_tr_modify(phydev, 0x0, 0xf, 0x3c, AUTO_NP_10XEN, -+ FIELD_PREP(AUTO_NP_10XEN, 0x1)); -+ -+ /* Enable HW auto downshift */ -+ phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED_1, -+ MTK_PHY_AUX_CTRL_AND_STATUS, -+ 0, MTK_PHY_ENABLE_DOWNSHIFT); -+ -+ return 0; -+} -+ -+static int mt798x_2p5ge_phy_config_aneg(struct phy_device *phydev) -+{ -+ bool changed = false; -+ u32 adv; -+ int ret; -+ -+ ret = genphy_c45_an_config_aneg(phydev); -+ if (ret < 0) -+ return ret; -+ if (ret > 0) -+ changed = true; -+ -+ /* Clause 45 doesn't define 1000BaseT support. Use Clause 22 instead in -+ * our design. -+ */ -+ adv = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising); -+ ret = phy_modify_changed(phydev, MII_CTRL1000, ADVERTISE_1000FULL, adv); -+ if (ret < 0) -+ return ret; -+ if (ret > 0) -+ changed = true; -+ -+ return __genphy_config_aneg(phydev, changed); -+} -+ -+static int mt798x_2p5ge_phy_get_features(struct phy_device *phydev) -+{ -+ int ret; -+ -+ ret = genphy_c45_pma_read_abilities(phydev); -+ if (ret) -+ return ret; -+ -+ /* This phy can't handle collision, and neither can (XFI)MAC it's -+ * connected to. Although it can do HDX handshake, it doesn't support -+ * CSMA/CD that HDX requires. -+ */ -+ linkmode_clear_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, -+ phydev->supported); -+ -+ return 0; -+} -+ -+static int mt798x_2p5ge_phy_read_status(struct phy_device *phydev) -+{ -+ int ret; -+ -+ /* When MDIO_STAT1_LSTATUS is raised genphy_c45_read_link(), this phy -+ * actually hasn't finished AN. So use CL22's link update function -+ * instead. -+ */ -+ ret = genphy_update_link(phydev); -+ if (ret) -+ return ret; -+ -+ phydev->speed = SPEED_UNKNOWN; -+ phydev->duplex = DUPLEX_UNKNOWN; -+ phydev->pause = 0; -+ phydev->asym_pause = 0; -+ -+ /* We'll read link speed through vendor specific registers down below. -+ * So remove phy_resolve_aneg_linkmode (AN on) & genphy_c45_read_pma -+ * (AN off). -+ */ -+ if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) { -+ ret = genphy_c45_read_lpa(phydev); -+ if (ret < 0) -+ return ret; -+ -+ /* Clause 45 doesn't define 1000BaseT support. Read the link -+ * partner's 1G advertisement via Clause 22. -+ */ -+ ret = phy_read(phydev, MII_STAT1000); -+ if (ret < 0) -+ return ret; -+ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, ret); -+ } else if (phydev->autoneg == AUTONEG_DISABLE) { -+ linkmode_zero(phydev->lp_advertising); -+ } -+ -+ if (phydev->link) { -+ ret = phy_read(phydev, PHY_AUX_CTRL_STATUS); -+ if (ret < 0) -+ return ret; -+ -+ switch (FIELD_GET(PHY_AUX_SPEED_MASK, ret)) { -+ case PHY_AUX_SPD_10: -+ phydev->speed = SPEED_10; -+ break; -+ case PHY_AUX_SPD_100: -+ phydev->speed = SPEED_100; -+ break; -+ case PHY_AUX_SPD_1000: -+ phydev->speed = SPEED_1000; -+ break; -+ case PHY_AUX_SPD_2500: -+ phydev->speed = SPEED_2500; -+ break; -+ } -+ -+ phydev->duplex = DUPLEX_FULL; -+ /* FIXME: -+ * The current firmware always enables rate adaptation mode. -+ */ -+ phydev->rate_matching = RATE_MATCH_PAUSE; -+ } -+ -+ return 0; -+} -+ -+static int mt798x_2p5ge_phy_get_rate_matching(struct phy_device *phydev, -+ phy_interface_t iface) -+{ -+ return RATE_MATCH_PAUSE; -+} -+ -+static int mt798x_2p5ge_phy_probe(struct phy_device *phydev) -+{ -+ struct mtk_i2p5ge_phy_priv *priv; -+ -+ priv = devm_kzalloc(&phydev->mdio.dev, -+ sizeof(struct mtk_i2p5ge_phy_priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ switch (phydev->drv->phy_id) { -+ case MTK_2P5GPHY_ID_MT7988: -+ /* The original hardware only sets MDIO_DEVS_PMAPMD */ -+ phydev->c45_ids.mmds_present |= MDIO_DEVS_PCS | -+ MDIO_DEVS_AN | -+ MDIO_DEVS_VEND1 | -+ MDIO_DEVS_VEND2; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ priv->fw_loaded = false; -+ phydev->priv = priv; -+ -+ return 0; -+} -+ -+static struct phy_driver mtk_2p5gephy_driver[] = { -+ { -+ PHY_ID_MATCH_MODEL(MTK_2P5GPHY_ID_MT7988), -+ .name = "MediaTek MT7988 2.5GbE PHY", -+ .probe = mt798x_2p5ge_phy_probe, -+ .config_init = mt798x_2p5ge_phy_config_init, -+ .config_aneg = mt798x_2p5ge_phy_config_aneg, -+ .get_features = mt798x_2p5ge_phy_get_features, -+ .read_status = mt798x_2p5ge_phy_read_status, -+ .get_rate_matching = mt798x_2p5ge_phy_get_rate_matching, -+ .suspend = genphy_suspend, -+ .resume = genphy_resume, -+ .read_page = mtk_phy_read_page, -+ .write_page = mtk_phy_write_page, -+ }, -+}; -+ -+module_phy_driver(mtk_2p5gephy_driver); -+ -+static struct mdio_device_id __maybe_unused mtk_2p5ge_phy_tbl[] = { -+ { PHY_ID_MATCH_VENDOR(0x00339c00) }, -+ { } -+}; -+ -+MODULE_DESCRIPTION("MediaTek 2.5Gb Ethernet PHY driver"); -+MODULE_AUTHOR("SkyLake Huang "); -+MODULE_LICENSE("GPL"); -+ -+MODULE_DEVICE_TABLE(mdio, mtk_2p5ge_phy_tbl); -+MODULE_FIRMWARE(MT7988_2P5GE_PMB_FW); --- -2.51.0 - - -From a42eb788cf9cd31ab5c465f6a0843ff7530cb20d Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 4 Sep 2020 18:42:42 +0200 -Subject: [PATCH 490/517] pci: pcie-mediatek: add support for coherent DMA - -It improves performance by eliminating the need for a cache flush for DMA on -attached devices - -Signed-off-by: Felix Fietkau ---- - arch/arm64/boot/dts/mediatek/mt7622.dtsi | 8 ++++++- - drivers/pci/controller/pcie-mediatek.c | 27 ++++++++++++++++++++++++ - 2 files changed, 34 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi -index ce802c3b22df..c4216828487e 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi -@@ -832,6 +832,9 @@ pcie0: pcie@1a143000 { - bus-range = <0x00 0xff>; - ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x8000000>; - status = "disabled"; -+ dma-coherent; -+ mediatek,hifsys = <&hifsys>; -+ mediatek,cci-control = <&cci_control2>; - - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 7>; -@@ -876,6 +879,9 @@ pcie1: pcie@1a145000 { - bus-range = <0x00 0xff>; - ranges = <0x82000000 0 0x28000000 0x0 0x28000000 0 0x8000000>; - status = "disabled"; -+ dma-coherent; -+ mediatek,hifsys = <&hifsys>; -+ mediatek,cci-control = <&cci_control2>; - - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 7>; -@@ -937,7 +943,7 @@ sata_port: sata-phy@1a243000 { - }; - - hifsys: clock-controller@1af00000 { -- compatible = "mediatek,mt7622-hifsys"; -+ compatible = "mediatek,mt7622-hifsys", "syscon"; - reg = <0 0x1af00000 0 0x70>; - #clock-cells = <1>; - }; -diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c -index b723cdfab3a0..daec88901679 100644 ---- a/drivers/pci/controller/pcie-mediatek.c -+++ b/drivers/pci/controller/pcie-mediatek.c -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -139,6 +140,11 @@ - #define PCIE_LINK_STATUS_V2 0x804 - #define PCIE_PORT_LINKUP_V2 BIT(10) - -+/* DMA channel mapping */ -+#define HIFSYS_DMA_AG_MAP 0x008 -+#define HIFSYS_DMA_AG_MAP_PCIE0 BIT(0) -+#define HIFSYS_DMA_AG_MAP_PCIE1 BIT(1) -+ - struct mtk_pcie_port; - - /** -@@ -1052,6 +1058,27 @@ static int mtk_pcie_setup(struct mtk_pcie *pcie) - struct mtk_pcie_port *port, *tmp; - int err, slot; - -+ if (of_dma_is_coherent(node)) { -+ struct regmap *con; -+ u32 mask; -+ -+ con = syscon_regmap_lookup_by_phandle(node, -+ "mediatek,cci-control"); -+ /* enable CPU/bus coherency */ -+ if (!IS_ERR(con)) -+ regmap_write(con, 0, 3); -+ -+ con = syscon_regmap_lookup_by_phandle(node, -+ "mediatek,hifsys"); -+ if (IS_ERR(con)) { -+ dev_err(dev, "missing hifsys node\n"); -+ return PTR_ERR(con); -+ } -+ -+ mask = HIFSYS_DMA_AG_MAP_PCIE0 | HIFSYS_DMA_AG_MAP_PCIE1; -+ regmap_update_bits(con, HIFSYS_DMA_AG_MAP, mask, mask); -+ } -+ - slot = of_get_pci_domain_nr(dev->of_node); - if (slot < 0) { - for_each_available_child_of_node(node, child) { --- -2.51.0 - - -From 1c08409b312633c3478c952996235c3de2976465 Mon Sep 17 00:00:00 2001 -From: Jip de Beer -Date: Sun, 9 Jan 2022 13:14:04 +0100 -Subject: [PATCH 491/517] mediatek mt7622: fix 300mhz typo in dts - -The lowest frequency should be 300MHz, since that is the label -assigned to the OPP in the mt7622.dtsi device tree, while there is one -missing zero in the actual value. - -To be clear, the lowest frequency should be 300MHz instead of 30MHz. - -As mentioned @dangowrt on the OpenWrt forum there is no benefit in -leaving 30MHz as the lowest frequency. - -Signed-off-by: Jip de Beer -Signed-off-by: Fritz D. Ansel ---- - arch/arm64/boot/dts/mediatek/mt7622.dtsi | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi -index c4216828487e..4ffc52a101f7 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi -@@ -24,7 +24,7 @@ cpu_opp_table: opp-table { - compatible = "operating-points-v2"; - opp-shared; - opp-300000000 { -- opp-hz = /bits/ 64 <30000000>; -+ opp-hz = /bits/ 64 <300000000>; - opp-microvolt = <950000>; - }; - --- -2.51.0 - - -From a0cda045c7e0d8dc0a6164cd45c6ae3d84fadcbb Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:51:05 +0100 -Subject: [PATCH 492/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/722-remove-300Hz-to-prevent-freeze.patch - ---- - arch/arm64/boot/dts/mediatek/mt7622.dtsi | 16 +++++++++++----- - 1 file changed, 11 insertions(+), 5 deletions(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi -index 4ffc52a101f7..8ea9ae91c45c 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi -@@ -23,11 +23,17 @@ / { - cpu_opp_table: opp-table { - compatible = "operating-points-v2"; - opp-shared; -- opp-300000000 { -- opp-hz = /bits/ 64 <300000000>; -- opp-microvolt = <950000>; -- }; -- -+ /* Due to the bug described at the link below, remove the 300 MHz clock to avoid a low -+ * voltage condition that can cause a hang when rebooting the RT3200/E8450. -+ * -+ * https://forum.openwrt.org/t/belkin-rt3200-linksys-e8450-wifi-ax-discussion/94302/1490 -+ * -+ * opp-300000000 { -+ * opp-hz = /bits/ 64 <300000000>; -+ * opp-microvolt = <950000>; -+ * }; -+ * -+ */ - opp-437500000 { - opp-hz = /bits/ 64 <437500000>; - opp-microvolt = <1000000>; --- -2.51.0 - - -From 19f58b171d2812a5f40b48d4a61d7627996ac650 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 6 Apr 2023 23:36:50 +0100 -Subject: [PATCH 493/517] net: phy: mxl-gpy: don't use SGMII AN if using - phylink - -MAC drivers using phylink expect SGMII in-band-status to be switched off -when attached to a PHY. Make sure this is the case also for mxl-gpy which -keeps SGMII in-band-status in case of SGMII interface mode is used. - -Signed-off-by: Daniel Golle ---- - drivers/net/phy/mxl-gpy.c | 19 ++++++++++++++++--- - 1 file changed, 16 insertions(+), 3 deletions(-) - -diff --git a/drivers/net/phy/mxl-gpy.c b/drivers/net/phy/mxl-gpy.c -index e0bdbb66df5c..48fe9241cab3 100644 ---- a/drivers/net/phy/mxl-gpy.c -+++ b/drivers/net/phy/mxl-gpy.c -@@ -380,8 +380,11 @@ static bool gpy_2500basex_chk(struct phy_device *phydev) - - phydev->speed = SPEED_2500; - phydev->interface = PHY_INTERFACE_MODE_2500BASEX; -- phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL, -- VSPEC1_SGMII_CTRL_ANEN, 0); -+ -+ if (!phydev->phylink) -+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL, -+ VSPEC1_SGMII_CTRL_ANEN, 0); -+ - return true; - } - -@@ -432,6 +435,14 @@ static int gpy_config_aneg(struct phy_device *phydev) - u32 adv; - int ret; - -+ /* Disable SGMII auto-negotiation if using phylink */ -+ if (phydev->phylink) { -+ ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL, -+ VSPEC1_SGMII_CTRL_ANEN, 0); -+ if (ret < 0) -+ return ret; -+ } -+ - if (phydev->autoneg == AUTONEG_DISABLE) { - /* Configure half duplex with genphy_setup_forced, - * because genphy_c45_pma_setup_forced does not support. -@@ -554,6 +565,8 @@ static int gpy_update_interface(struct phy_device *phydev) - switch (phydev->speed) { - case SPEED_2500: - phydev->interface = PHY_INTERFACE_MODE_2500BASEX; -+ if (phydev->phylink) -+ break; - ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL, - VSPEC1_SGMII_CTRL_ANEN, 0); - if (ret < 0) { -@@ -567,7 +580,7 @@ static int gpy_update_interface(struct phy_device *phydev) - case SPEED_100: - case SPEED_10: - phydev->interface = PHY_INTERFACE_MODE_SGMII; -- if (gpy_sgmii_aneg_en(phydev)) -+ if (phydev->phylink || gpy_sgmii_aneg_en(phydev)) - break; - /* Enable and restart SGMII ANEG for 10/100/1000Mbps link speed - * if ANEG is disabled (in 2500-BaseX mode). --- -2.51.0 - - -From 1afe6c2034b55a0e26d3e458c83c8d09b8da783b Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Sat, 23 Mar 2024 20:21:14 +0100 -Subject: [PATCH 494/517] net: phy: add Airoha EN8801SC PHY - -Airoha EN8801SC Gigabit PHY is used on Edgecore EAP111, so include a -modified version of MTK SDK driver. - -Signed-off-by: Robert Marko ---- - drivers/net/phy/Kconfig | 5 +++++ - drivers/net/phy/Makefile | 1 + - 2 files changed, 6 insertions(+) - -diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig -index 2fcb9544a3b0..c627136d9ed0 100644 ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -165,6 +165,11 @@ config AS21XXX_PHY - AS21210PB1 that all register with the PHY ID 0x7500 0x7500 - before the firmware is loaded. - -+config AIROHA_EN8801SC_PHY -+ tristate "Airoha EN8801SC Gigabit PHY" -+ help -+ Currently supports the Airoha EN8801SC PHY. -+ - config AIR_EN8811H_PHY - tristate "Airoha EN8811H 2.5 Gigabit PHY" - help -diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile -index f869dd4a7ff4..845ee491e8d9 100644 ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -50,6 +50,7 @@ obj-y += $(sfp-obj-y) $(sfp-obj-m) - - obj-$(CONFIG_ADIN_PHY) += adin.o - obj-$(CONFIG_ADIN1100_PHY) += adin1100.o -+obj-$(CONFIG_AIROHA_EN8801SC_PHY) += en8801sc.o - obj-$(CONFIG_AIR_EN8811H_PHY) += air_en8811h.o - obj-$(CONFIG_AMD_PHY) += amd.o - obj-$(CONFIG_AMCC_QT2025_PHY) += qt2025.o --- -2.51.0 - - -From e1f280932e8365d4a856f205554968ae9aea46c8 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:51:06 +0100 -Subject: [PATCH 495/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/736-net-pcs-mtk_usxgmii-add-polarity-control.patch - ---- - drivers/net/pcs/pcs-mtk-usxgmii.c | 19 +++++++++++++++++++ - 1 file changed, 19 insertions(+) - -diff --git a/drivers/net/pcs/pcs-mtk-usxgmii.c b/drivers/net/pcs/pcs-mtk-usxgmii.c -index 9691d9e73790..4ce212e366e9 100644 ---- a/drivers/net/pcs/pcs-mtk-usxgmii.c -+++ b/drivers/net/pcs/pcs-mtk-usxgmii.c -@@ -52,6 +52,12 @@ - #define USXGMII_LPA GENMASK(15, 0) - #define USXGMII_LPA_LATCH BIT(31) - -+/* Register to control PCS polarity */ -+#define RG_PHY_TOP_CTRL0 0x82C -+#define USXGMII_PN_SWAP_MASK GENMASK(1, 0) -+#define USXGMII_PN_SWAP_RX BIT(1) -+#define USXGMII_PN_SWAP_TX BIT(0) -+ - /* Register to read PCS link status */ - #define RG_PCS_RX_STATUS0 0x904 - #define RG_PCS_RX_STATUS_UPDATE BIT(16) -@@ -74,6 +80,7 @@ struct mtk_usxgmii_pcs { - struct clk *clk; - struct reset_control *reset; - phy_interface_t interface; -+ unsigned int polarity; - unsigned int neg_mode; - struct list_head node; - }; -@@ -155,6 +162,10 @@ static int mtk_usxgmii_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode - - mtk_usxgmii_reset(mpcs); - -+ /* Configure the interface polarity */ -+ mtk_m32(mpcs, RG_PHY_TOP_CTRL0, -+ USXGMII_PN_SWAP_MASK, mpcs->polarity); -+ - /* Setup USXGMII AN ctrl */ - mtk_m32(mpcs, RG_PCS_AN_CTRL0, - USXGMII_AN_SYNC_CNT | USXGMII_AN_ENABLE, -@@ -332,6 +343,7 @@ static const struct phylink_pcs_ops mtk_usxgmii_pcs_ops = { - static int mtk_usxgmii_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -+ struct device_node *np = dev->of_node; - struct mtk_usxgmii_pcs *mpcs; - - mpcs = devm_kzalloc(dev, sizeof(*mpcs), GFP_KERNEL); -@@ -342,6 +354,13 @@ static int mtk_usxgmii_probe(struct platform_device *pdev) - if (IS_ERR(mpcs->base)) - return PTR_ERR(mpcs->base); - -+ if (of_property_read_bool(np->parent, "mediatek,pnswap")) -+ mpcs->polarity = USXGMII_PN_SWAP_TX | USXGMII_PN_SWAP_RX; -+ else if (of_property_read_bool(np, "mediatek,pnswap-tx")) -+ mpcs->polarity = USXGMII_PN_SWAP_TX; -+ else if (of_property_read_bool(np, "mediatek,pnswap-rx")) -+ mpcs->polarity = USXGMII_PN_SWAP_RX; -+ - mpcs->dev = dev; - mpcs->pcs.ops = &mtk_usxgmii_pcs_ops; - mpcs->pcs.poll = true; --- -2.51.0 - - -From 82fbdfafa6531553caab6cf3b09e8f969956ff1d Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 9 Dec 2024 14:44:17 +0100 -Subject: [PATCH 496/517] net: dsa: Add Airoha AN8855 support - -This small series add the initial support for the Airoha AN8855 Switch. - -It's a 5 port Gigabit Switch with SGMII/HSGMII upstream port. - -This is starting to get in the wild and there are already some router -having this switch chip. - -It's conceptually similar to mediatek switch but register and bits -are different. And there is that massive Hell that is the PCS -configuration. -Saddly for that part we have absolutely NO documentation currently. - -There is this special thing where PHY needs to be calibrated with values -from the switch efuse. (the thing have a whole cpu timer and MCU) - -Changes v11: -- Address reviews from Christophe (spell mistake + dev_err_probe) -- Fix kconfig dependency for MFD driver (depends on MDIO_DEVICE instead of MDIO) - (indirectly fix link error for mdio APIs) -- Fix copy-paste error for MFD driver of_table -- Fix compilation error for PHY (move NVMEM to .config) -- Drop unneeded NVMEM node from MDIO example schema (from Andrew) -- Adapt MFD example schema to MDIO reg property restrictions -Changes v10: -- Entire rework to MFD + split to MDIO, EFUSE, SWITCH separate drivers -- Drop EEE OPs (while Russell finish RFC for EEE changes) -- Use new pcs_inpand OPs -- Drop AN restart function and move to pcs_config -- Enable assisted_learning and disable CPU learn (preparation for fdb_isolation) -- Move EFUSE read in Internal PHY driver to .config to handle EPROBE_DEFER - (needed now that NVMEM driver is register externally instead of internally to switch - node) -Changes v9: -- Error out on using 5G speed as currently not supported -- Add missing MAC_2500FD in phylink mac_capabilities -- Add comment and improve if condition for an8855_phylink_mac_config -Changes v8: -- Add port Fast Age support -- Add support for Port Isolation -- Use correct register for Learning Disable -- Add support for Ageing Time OP -- Set default PVID to 0 by default -- Add mdb OPs -- Add port change MTU -- Fix support for Upper VLAN -Changes v7: -- Fix devm_dsa_register_switch wrong export symbol -Changes v6: -- Drop standard MIB and handle with ethtool OPs (as requested by Jakub) -- Cosmetic: use bool instead of 0 or 1 -Changes v5: -- Add devm_dsa_register_switch() patch -- Add Reviewed-by tag for DT patch -Changes v4: -- Set regmap readable_table static (mute compilation warning) -- Add support for port_bridge flags (LEARNING, FLOOD) -- Reset fdb struct in fdb_dump -- Drop support_asym_pause in port_enable -- Add define for get_phy_flags -- Fix bug for port not inititially part of a bridge - (in an8855_setup the port matrix was always cleared but - the CPU port was never initially added) -- Disable learning and flood for user port by default -- Set CPU port to flood and learning by default -- Correctly AND force duplex and flow control in an8855_phylink_mac_link_up -- Drop RGMII from pcs_config -- Check ret in "Disable AN if not in autoneg" -- Use devm_mutex_init -- Fix typo for AN8855_PORT_CHECK_MODE -- Better define AN8855_STP_LISTENING = AN8855_STP_BLOCKING -- Fix typo in AN8855_PHY_EN_DOWN_SHIFT -- Use paged helper for PHY -- Skip calibration in config_init if priv not defined -Changes v3: -- Out of RFC -- Switch PHY code to select_page API -- Better describe masks and bits in PHY driver for ADC register -- Drop raw values and use define for mii read/write -- Switch to absolute PHY address -- Replace raw values with mask and bits for pcs_config -- Fix typo for ext-surge property name -- Drop support for relocating Switch base PHY address on the bus -Changes v2: -- Drop mutex guard patch -- Drop guard usage in DSA driver -- Use __mdiobus_write/read -- Check return condition and return errors for mii read/write -- Fix wrong logic for EEE -- Fix link_down (don't force link down with autoneg) -- Fix forcing speed on sgmii autoneg -- Better document link speed for sgmii reg -- Use standard define for sgmii reg -- Imlement nvmem support to expose switch EFUSE -- Rework PHY calibration with the use of NVMEM producer/consumer -- Update DT with new NVMEM property -- Move aneg validation for 2500-basex in pcs_config -- Move r50Ohm table and function to PHY driver - -Christian Marangi (9): - dt-bindings: nvmem: Document support for Airoha AN8855 Switch EFUSE - dt-bindings: net: Document support for Airoha AN8855 Switch Virtual - MDIO - dt-bindings: net: dsa: Document support for Airoha AN8855 DSA Switch - dt-bindings: mfd: Document support for Airoha AN8855 Switch SoC - mfd: an8855: Add support for Airoha AN8855 Switch MFD - net: mdio: Add Airoha AN8855 Switch MDIO Passtrough - nvmem: an8855: Add support for Airoha AN8855 Switch EFUSE - net: dsa: Add Airoha AN8855 5-Port Gigabit DSA Switch driver - net: phy: Add Airoha AN8855 Internal Switch Gigabit PHY - - .../bindings/mfd/airoha,an8855-mfd.yaml | 178 ++ - .../bindings/net/airoha,an8855-mdio.yaml | 56 + - .../net/dsa/airoha,an8855-switch.yaml | 105 + - .../bindings/nvmem/airoha,an8855-efuse.yaml | 123 + - MAINTAINERS | 17 + - drivers/mfd/Kconfig | 10 + - drivers/mfd/Makefile | 1 + - drivers/mfd/airoha-an8855.c | 278 ++ - drivers/net/dsa/Kconfig | 9 + - drivers/net/dsa/Makefile | 1 + - drivers/net/dsa/an8855.c | 2310 +++++++++++++++++ - drivers/net/dsa/an8855.h | 783 ++++++ - drivers/net/mdio/Kconfig | 9 + - drivers/net/mdio/Makefile | 1 + - drivers/net/mdio/mdio-an8855.c | 113 + - drivers/net/phy/Kconfig | 5 + - drivers/net/phy/Makefile | 1 + - drivers/net/phy/air_an8855.c | 267 ++ - drivers/nvmem/Kconfig | 11 + - drivers/nvmem/Makefile | 2 + - drivers/nvmem/an8855-efuse.c | 63 + - include/linux/mfd/airoha-an8855-mfd.h | 41 + - 22 files changed, 4384 insertions(+) - create mode 100644 Documentation/devicetree/bindings/mfd/airoha,an8855-mfd.yaml - create mode 100644 Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml - create mode 100644 Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml - create mode 100644 Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml - create mode 100644 drivers/mfd/airoha-an8855.c - create mode 100644 drivers/net/dsa/an8855.c - create mode 100644 drivers/net/dsa/an8855.h - create mode 100644 drivers/net/mdio/mdio-an8855.c - create mode 100644 drivers/net/phy/air_an8855.c - create mode 100644 drivers/nvmem/an8855-efuse.c - create mode 100644 include/linux/mfd/airoha-an8855-mfd.h ---- - drivers/mfd/Kconfig | 10 ++++++++++ - drivers/mfd/Makefile | 1 + - drivers/net/dsa/Kconfig | 9 +++++++++ - drivers/net/dsa/Makefile | 1 + - drivers/net/mdio/Kconfig | 9 +++++++++ - drivers/net/mdio/Makefile | 1 + - drivers/net/phy/Kconfig | 5 +++++ - drivers/net/phy/Makefile | 1 + - drivers/nvmem/Kconfig | 11 +++++++++++ - drivers/nvmem/Makefile | 2 ++ - 10 files changed, 50 insertions(+) - -diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig -index f9325bcce1b9..340d8a03558c 100644 ---- a/drivers/mfd/Kconfig -+++ b/drivers/mfd/Kconfig -@@ -53,6 +53,16 @@ config MFD_ALTERA_SYSMGR - using regmap_mmio accesses for ARM32 parts and SMC calls to - EL3 for ARM64 parts. - -+config MFD_AIROHA_AN8855 -+ tristate "Airoha AN8855 Switch MFD" -+ select MFD_CORE -+ select MDIO_DEVICE -+ depends on NETDEVICES && OF -+ help -+ Support for the Airoha AN8855 Switch MFD. This is a SoC Switch -+ that provides various peripherals. Currently it provides a -+ DSA switch and a NVMEM provider. -+ - config MFD_ACT8945A - tristate "Active-semi ACT8945A" - select MFD_CORE -diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile -index 2a9f91e81af8..da210d16c7bb 100644 ---- a/drivers/mfd/Makefile -+++ b/drivers/mfd/Makefile -@@ -9,6 +9,7 @@ obj-$(CONFIG_MFD_88PM800) += 88pm800.o 88pm80x.o - obj-$(CONFIG_MFD_88PM805) += 88pm805.o 88pm80x.o - obj-$(CONFIG_MFD_88PM886_PMIC) += 88pm886.o - obj-$(CONFIG_MFD_ACT8945A) += act8945a.o -+obj-$(CONFIG_MFD_AIROHA_AN8855) += airoha-an8855.o - obj-$(CONFIG_MFD_SM501) += sm501.o - obj-$(CONFIG_ARCH_BCM2835) += bcm2835-pm.o - obj-$(CONFIG_MFD_BCM590XX) += bcm590xx.o -diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig -index b7b473e3fc02..37a4a0b7ae96 100644 ---- a/drivers/net/dsa/Kconfig -+++ b/drivers/net/dsa/Kconfig -@@ -24,6 +24,15 @@ config NET_DSA_LOOP - This enables support for a fake mock-up switch chip which - exercises the DSA APIs. - -+config NET_DSA_AN8855 -+ tristate "Airoha AN8855 Ethernet switch support" -+ depends on MFD_AIROHA_AN8855 -+ depends on NET_DSA -+ select NET_DSA_TAG_MTK -+ help -+ This enables support for the Airoha AN8855 Ethernet switch -+ chip. -+ - source "drivers/net/dsa/hirschmann/Kconfig" - - config NET_DSA_LANTIQ_GSWIP -diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile -index 23dbdf1a36a8..1e9d01ef7490 100644 ---- a/drivers/net/dsa/Makefile -+++ b/drivers/net/dsa/Makefile -@@ -6,6 +6,7 @@ ifdef CONFIG_NET_DSA_LOOP - obj-$(CONFIG_FIXED_PHY) += dsa_loop_bdinfo.o - endif - obj-$(CONFIG_NET_DSA_KS8995) += ks8995.o -+obj-$(CONFIG_NET_DSA_AN8855) += an8855.o - obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o - obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o - obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o -diff --git a/drivers/net/mdio/Kconfig b/drivers/net/mdio/Kconfig -index 4a7a303be2f7..3d417948e73a 100644 ---- a/drivers/net/mdio/Kconfig -+++ b/drivers/net/mdio/Kconfig -@@ -61,6 +61,15 @@ config MDIO_XGENE - This module provides a driver for the MDIO busses found in the - APM X-Gene SoC's. - -+config MDIO_AN8855 -+ tristate "Airoha AN8855 Switch MDIO bus controller" -+ depends on MFD_AIROHA_AN8855 -+ depends on OF_MDIO -+ help -+ This module provides a driver for the Airoha AN8855 Switch -+ that requires a MDIO passtrough as switch address is shared -+ with the internal PHYs and requires additional page handling. -+ - config MDIO_ASPEED - tristate "ASPEED MDIO bus controller" - depends on ARCH_ASPEED || COMPILE_TEST -diff --git a/drivers/net/mdio/Makefile b/drivers/net/mdio/Makefile -index 1015f0db4531..546c4e55b475 100644 ---- a/drivers/net/mdio/Makefile -+++ b/drivers/net/mdio/Makefile -@@ -5,6 +5,7 @@ obj-$(CONFIG_ACPI_MDIO) += acpi_mdio.o - obj-$(CONFIG_FWNODE_MDIO) += fwnode_mdio.o - obj-$(CONFIG_OF_MDIO) += of_mdio.o - -+obj-$(CONFIG_MDIO_AN8855) += mdio-an8855.o - obj-$(CONFIG_MDIO_ASPEED) += mdio-aspeed.o - obj-$(CONFIG_MDIO_BCM_IPROC) += mdio-bcm-iproc.o - obj-$(CONFIG_MDIO_BCM_UNIMAC) += mdio-bcm-unimac.o -diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig -index c627136d9ed0..2682c7ba2b14 100644 ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -170,6 +170,11 @@ config AIROHA_EN8801SC_PHY - help - Currently supports the Airoha EN8801SC PHY. - -+config AIR_AN8855_PHY -+ tristate "Airoha AN8855 Internal Gigabit PHY" -+ help -+ Currently supports the internal Airoha AN8855 Switch PHY. -+ - config AIR_EN8811H_PHY - tristate "Airoha EN8811H 2.5 Gigabit PHY" - help -diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile -index 845ee491e8d9..d75b8fab63eb 100644 ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -51,6 +51,7 @@ obj-y += $(sfp-obj-y) $(sfp-obj-m) - obj-$(CONFIG_ADIN_PHY) += adin.o - obj-$(CONFIG_ADIN1100_PHY) += adin1100.o - obj-$(CONFIG_AIROHA_EN8801SC_PHY) += en8801sc.o -+obj-$(CONFIG_AIR_AN8855_PHY) += air_an8855.o - obj-$(CONFIG_AIR_EN8811H_PHY) += air_en8811h.o - obj-$(CONFIG_AMD_PHY) += amd.o - obj-$(CONFIG_AMCC_QT2025_PHY) += qt2025.o -diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig -index 51257aa2cd3e..9b998a92189a 100644 ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -29,6 +29,17 @@ source "drivers/nvmem/layouts/Kconfig" - - # Devices - -+config NVMEM_AN8855_EFUSE -+ tristate "Airoha AN8855 eFuse support" -+ depends on MFD_AIROHA_AN8855 || COMPILE_TEST -+ help -+ Say y here to enable support for reading eFuses on Airoha AN8855 -+ Switch. These are e.g. used to store factory programmed -+ calibration data required for the PHY. -+ -+ This driver can also be built as a module. If so, the module will -+ be called nvmem-an8855-efuse. -+ - config NVMEM_APPLE_EFUSES - tristate "Apple eFuse support" - depends on ARCH_APPLE || COMPILE_TEST -diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile -index 68fcf845f417..6c6a49cb9890 100644 ---- a/drivers/nvmem/Makefile -+++ b/drivers/nvmem/Makefile -@@ -10,6 +10,8 @@ nvmem_layouts-y := layouts.o - obj-y += layouts/ - - # Devices -+obj-$(CONFIG_NVMEM_AN8855_EFUSE) += nvmem-an8855-efuse.o -+nvmem-an8855-efuse-y := an8855-efuse.o - obj-$(CONFIG_NVMEM_APPLE_EFUSES) += nvmem-apple-efuses.o - nvmem-apple-efuses-y := apple-efuses.o - obj-$(CONFIG_NVMEM_BCM_OCOTP) += nvmem-bcm-ocotp.o --- -2.51.0 - - -From 744a0be88f4d250f79d3ae4beaba2a4bcab033c4 Mon Sep 17 00:00:00 2001 -From: Maso Huang -Date: Thu, 7 Sep 2023 10:54:37 +0800 -Subject: [PATCH 497/517] arm64: dts: mt7986: add afe - ---- - arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 23 +++++++++++++++++++++++ - 1 file changed, 23 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi -index 9a8d7db31261..49b5839eb7e9 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi -@@ -202,6 +202,29 @@ pio: pinctrl@1001f000 { - #interrupt-cells = <2>; - }; - -+ afe: audio-controller@11210000 { -+ compatible = "mediatek,mt7986-afe"; -+ reg = <0 0x11210000 0 0x9000>; -+ #sound-dai-cells = <0>; -+ interrupts = ; -+ clocks = <&infracfg CLK_INFRA_AUD_BUS_CK>, -+ <&infracfg CLK_INFRA_AUD_26M_CK>, -+ <&infracfg CLK_INFRA_AUD_L_CK>, -+ <&infracfg CLK_INFRA_AUD_AUD_CK>, -+ <&infracfg CLK_INFRA_AUD_EG2_CK>; -+ clock-names = "aud_bus_ck", -+ "aud_26m_ck", -+ "aud_l_ck", -+ "aud_aud_ck", -+ "aud_eg2_ck"; -+ assigned-clocks = <&topckgen CLK_TOP_A1SYS_SEL>, -+ <&topckgen CLK_TOP_AUD_L_SEL>, -+ <&topckgen CLK_TOP_A_TUNER_SEL>; -+ assigned-clock-parents = <&topckgen CLK_TOP_APLL2_D4>, -+ <&apmixedsys CLK_APMIXED_APLL2>, -+ <&topckgen CLK_TOP_APLL2_D4>; -+ }; -+ - pwm: pwm@10048000 { - compatible = "mediatek,mt7986-pwm"; - reg = <0 0x10048000 0 0x1000>; --- -2.51.0 - - -From 9576cb9f4d5b90fdbae13c30eaca52d4e77dfb50 Mon Sep 17 00:00:00 2001 -From: Maso Huang -Date: Thu, 7 Sep 2023 10:54:37 +0800 -Subject: [PATCH 498/517] arm64: dts: mt7986: add sound wm8960 - ---- - .../dts/mediatek/mt7986a-rfb-spim-nand.dts | 40 +++++++++++++++++++ - 1 file changed, 40 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-rfb-spim-nand.dts b/arch/arm64/boot/dts/mediatek/mt7986a-rfb-spim-nand.dts -index 479a5ca2fc4d..85ec95de405f 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7986a-rfb-spim-nand.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7986a-rfb-spim-nand.dts -@@ -4,6 +4,36 @@ - - / { - compatible = "mediatek,mt7986a-rfb-snand"; -+ -+ sound_wm8960 { -+ compatible = "mediatek,mt7986-wm8960-sound"; -+ audio-routing = "Headphone", "HP_L", -+ "Headphone", "HP_R", -+ "LINPUT1", "AMIC", -+ "RINPUT1", "AMIC"; -+ -+ status = "okay"; -+ -+ platform { -+ sound-dai = <&afe>; -+ }; -+ -+ codec { -+ sound-dai = <&wm8960>; -+ }; -+ }; -+}; -+ -+&i2c0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c_pins>; -+ status = "okay"; -+ -+ wm8960: wm8960@1a { -+ compatible = "wlf,wm8960"; -+ #sound-dai-cells = <0>; -+ reg = <0x1a>; -+ }; - }; - - &spi0 { -@@ -50,3 +80,13 @@ partition@580000 { - &wifi { - mediatek,mtd-eeprom = <&factory 0>; - }; -+ -+&pio { -+ i2c_pins: i2c-pins-3-4 { -+ mux { -+ function = "i2c"; -+ groups = "i2c"; -+ }; -+ }; -+}; -+ --- -2.51.0 - - -From 865785365dda36ad89ca2a72db9304f5c9cd7b5d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:51:07 +0100 -Subject: [PATCH 499/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/864-arm64-dts-mt7986-add-sound-overlay-for-bpi-r3.patch - ---- - arch/arm64/boot/dts/mediatek/Makefile | 1 + - ...7986a-bananapi-bpi-r3-respeaker-2mics.dtso | 65 +++++++++++++++++++ - 2 files changed, 66 insertions(+) - create mode 100644 arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-respeaker-2mics.dtso - -diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile -index 82f7332077c4..7d4c852cb124 100644 ---- a/arch/arm64/boot/dts/mediatek/Makefile -+++ b/arch/arm64/boot/dts/mediatek/Makefile -@@ -18,6 +18,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-emmc.dtbo - dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-nand.dtbo - dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-nor.dtbo - dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-sd.dtbo -+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-respeaker-2mics.dtbo - dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-rfb.dtb - dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986b-rfb.dtb - dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4.dtb -diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-respeaker-2mics.dtso b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-respeaker-2mics.dtso -new file mode 100644 -index 000000000000..e583875154a3 ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-respeaker-2mics.dtso -@@ -0,0 +1,65 @@ -+// SPDX-License-Identifier: (GPL-2.0 OR MIT) -+/* -+ * Copyright (C) 2023 MediaTek Inc. -+ * Author: Maso Huang -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "bananapi,bpi-r3", "mediatek,mt7986a"; -+ -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ sound_wm8960 { -+ compatible = "mediatek,mt7986-wm8960-sound"; -+ audio-routing = "Headphone", "HP_L", -+ "Headphone", "HP_R", -+ "LINPUT1", "AMIC", -+ "RINPUT1", "AMIC"; -+ -+ status = "okay"; -+ -+ platform { -+ sound-dai = <&afe>; -+ }; -+ -+ codec { -+ sound-dai = <&wm8960>; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2c0>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c_pins>; -+ clock-frequency = <400000>; -+ status = "okay"; -+ -+ wm8960: wm8960@1a { -+ compatible = "wlf,wm8960"; -+ #sound-dai-cells = <0>; -+ reg = <0x1a>; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&pio>; -+ __overlay__ { -+ i2c_pins: i2c-pins-3-4 { -+ mux { -+ function = "i2c"; -+ groups = "i2c"; -+ }; -+ }; -+ }; -+ }; -+}; --- -2.51.0 - - -From 58396f54f6a0640436a55866eb4ff7567d54ec08 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:51:08 +0100 -Subject: [PATCH 500/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/900-dts-mt7622-bpi-r64-aliases-for-dtoverlay.patch - ---- - .../mt7622-bananapi-bpi-r64-pcie1.dtso | 17 ++++++++++ - .../mt7622-bananapi-bpi-r64-sata.dtso | 31 +++++++++++++++++++ - .../dts/mediatek/mt7622-bananapi-bpi-r64.dts | 2 +- - 3 files changed, 49 insertions(+), 1 deletion(-) - create mode 100644 arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64-pcie1.dtso - create mode 100644 arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64-sata.dtso - -diff --git a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64-pcie1.dtso b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64-pcie1.dtso -new file mode 100644 -index 000000000000..6be1ea2a8a13 ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64-pcie1.dtso -@@ -0,0 +1,17 @@ -+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ -+ -+#include -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "bananapi,bpi-r64", "mediatek,mt7622"; -+ -+ fragment@0 { -+ target = <&asmsel>; -+ __overlay__ { -+ gpios = <90 GPIO_ACTIVE_HIGH>; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64-sata.dtso b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64-sata.dtso -new file mode 100644 -index 000000000000..160423348b4c ---- /dev/null -+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64-sata.dtso -@@ -0,0 +1,31 @@ -+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ -+ -+#include -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "bananapi,bpi-r64", "mediatek,mt7622"; -+ -+ fragment@0 { -+ target = <&asmsel>; -+ __overlay__ { -+ gpios = <90 GPIO_ACTIVE_LOW>; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&sata>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&sata_phy>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -index 77ecf5086c2c..b8cc6b9516e5 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -@@ -323,7 +323,7 @@ &pio { - /* Attention: GPIO 90 is used to switch between PCIe@1,0 and - * SATA functions. i.e. output-high: PCIe, output-low: SATA - */ -- asm_sel { -+ asmsel: asm_sel { - gpio-hog; - gpios = <90 GPIO_ACTIVE_HIGH>; - output-high; --- -2.51.0 - - -From 98b9ffa72c8692d6441504a508fdbeaa83418ebc Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:51:08 +0100 -Subject: [PATCH 501/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/901-arm-add-cmdline-override.patch - ---- - arch/arm/Kconfig | 8 ++++++++ - arch/arm64/Kconfig | 8 ++++++++ - drivers/of/fdt.c | 11 +++++++++++ - 3 files changed, 27 insertions(+) - -diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index d5bf16462bdb..bb39e14b7486 100644 ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -1505,6 +1505,14 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND - - endchoice - -+config CMDLINE_OVERRIDE -+ bool "Use alternative cmdline from device tree" -+ help -+ Some bootloaders may have uneditable bootargs. While CMDLINE_FORCE can -+ be used, this is not a good option for kernels that are shared across -+ devices. This setting enables using "chosen/cmdline-override" as the -+ cmdline if it exists in the device tree. -+ - config CMDLINE - string "Default kernel command string" - default "" -diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig -index 40ae4dd961b1..788c05232708 100644 ---- a/arch/arm64/Kconfig -+++ b/arch/arm64/Kconfig -@@ -2381,6 +2381,14 @@ config CMDLINE_FORCE - - endchoice - -+config CMDLINE_OVERRIDE -+ bool "Use alternative cmdline from device tree" -+ help -+ Some bootloaders may have uneditable bootargs. While CMDLINE_FORCE can -+ be used, this is not a good option for kernels that are shared across -+ devices. This setting enables using "chosen/cmdline-override" as the -+ cmdline if it exists in the device tree. -+ - config EFI_STUB - bool - -diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c -index 500807cccee4..1ca6cb71a908 100644 ---- a/drivers/of/fdt.c -+++ b/drivers/of/fdt.c -@@ -1053,6 +1053,17 @@ int __init early_init_dt_scan_chosen(char *cmdline) - if (p != NULL && l > 0) - strlcat(cmdline, p, min_t(int, strlen(cmdline) + (int)l, COMMAND_LINE_SIZE)); - -+ /* CONFIG_CMDLINE_OVERRIDE is used to fallback to a different -+ * device tree option of chosen/bootargs-override. This is -+ * helpful on boards where u-boot sets bootargs, and is unable -+ * to be modified. -+ */ -+#ifdef CONFIG_CMDLINE_OVERRIDE -+ p = of_get_flat_dt_prop(node, "bootargs-override", &l); -+ if (p != NULL && l > 0) -+ strscpy(cmdline, p, min((int)l, COMMAND_LINE_SIZE)); -+#endif -+ - handle_cmdline: - /* - * CONFIG_CMDLINE is meant to be a default in case nothing else --- -2.51.0 - - -From 9aafa16a5e03d1d3488357d03c769324d01d9546 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:51:08 +0100 -Subject: [PATCH 502/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/910-dts-mt7622-bpi-r64-wifi-eeprom.patch - ---- - .../dts/mediatek/mt7622-bananapi-bpi-r64.dts | 23 +++++++++++++++++++ - 1 file changed, 23 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -index b8cc6b9516e5..456d260b5edf 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -@@ -650,5 +650,28 @@ &watchdog { - }; - - &wmac { -+ mediatek,eeprom-data = <0x22760500 0x0 0x0 0x0 -+ 0x0 0x0 0x0 0x0 -+ 0x0 0x0 0x0 0x0 -+ 0x0 0x44000020 0x0 0x10002000 -+ 0x4400 0x4000000 0x0 0x0 -+ 0x200000b3 0x40b6c3c3 0x26000000 0x41c42600 -+ 0x41c4 0x26000000 0xc0c52600 0x0 -+ 0x0 0x0 0x0 0x0 -+ 0x0 0x0 0x0 0x0 -+ 0x0 0x0 0x0 0x0 -+ 0x0 0x0 0x0 0x0 -+ 0x0 0x0 0x0 0xc6c6 -+ 0xc3c3c2c1 0xc300c3 0x818181 0x83c1c182 -+ 0x83838382 0x0 0x0 0x0 -+ 0x0 0x0 0x0 0x0 -+ 0x84002e00 0x90000087 0x8a000000 0x0 -+ 0x0 0x0 0x0 0x0 -+ 0x0 0x0 0x0 0x0 -+ 0xb000009 0x0 0x0 0x0 -+ 0x0 0x0 0x0 0x0 -+ 0x0 0x0 0x0 0x0 -+ 0x0 0x0 0x0 0x7707>; -+ - status = "okay"; - }; --- -2.51.0 - - -From c4409ad0cbfc4b8700cf01d1670473352839322c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:51:09 +0100 -Subject: [PATCH 503/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/911-dts-mt7622-bpi-r64-add-rootdisk.patch - ---- - .../dts/mediatek/mt7622-bananapi-bpi-r64.dts | 78 +++++++++++++++++-- - 1 file changed, 70 insertions(+), 8 deletions(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -index 456d260b5edf..bec66209492f 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts -@@ -32,6 +32,9 @@ aliases { - chosen { - stdout-path = "serial0:115200n8"; - bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512"; -+ rootdisk-emmc = <&emmc_rootfs>; -+ rootdisk-sd = <&sd_rootfs>; -+ rootdisk-snfi = <&ubi_rootfs>; - }; - - cpus { -@@ -245,6 +248,28 @@ &mmc0 { - assigned-clocks = <&topckgen CLK_TOP_MSDC30_0_SEL>; - assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>; - non-removable; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ card@0 { -+ compatible = "mmc-card"; -+ reg = <0>; -+ -+ block { -+ compatible = "block-device"; -+ partitions { -+ block-partition-env { -+ partname = "ubootenv"; -+ nvmem-layout { -+ compatible = "u-boot,env"; -+ }; -+ }; -+ emmc_rootfs: block-partition-production { -+ partname = "production"; -+ }; -+ }; -+ }; -+ }; - }; - - &mmc1 { -@@ -260,6 +285,28 @@ &mmc1 { - vqmmc-supply = <®_3p3v>; - assigned-clocks = <&topckgen CLK_TOP_MSDC30_1_SEL>; - assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ card@0 { -+ compatible = "mmc-card"; -+ reg = <0>; -+ -+ block { -+ compatible = "block-device"; -+ partitions { -+ block-partition-env { -+ partname = "ubootenv"; -+ nvmem-layout { -+ compatible = "u-boot,env"; -+ }; -+ }; -+ sd_rootfs: block-partition-production { -+ partname = "production"; -+ }; -+ }; -+ }; -+ }; - }; - - &nandc { -@@ -293,15 +340,30 @@ partition@0 { - read-only; - }; - -- partition@80000 { -- label = "fip"; -- reg = <0x80000 0x200000>; -- read-only; -- }; -- -- ubi: partition@280000 { -+ ubi: partition@80000 { - label = "ubi"; -- reg = <0x280000 0x7d80000>; -+ reg = <0x80000 0x7f80000>; -+ compatible = "linux,ubi"; -+ -+ volumes { -+ ubi-volume-ubootenv { -+ volname = "ubootenv"; -+ nvmem-layout { -+ compatible = "u-boot,env-redundant-bool"; -+ }; -+ }; -+ -+ ubi-volume-ubootenv2 { -+ volname = "ubootenv2"; -+ nvmem-layout { -+ compatible = "u-boot,env-redundant-bool"; -+ }; -+ }; -+ -+ ubi_rootfs: ubi-volume-fit { -+ volname = "fit"; -+ }; -+ }; - }; - }; - }; --- -2.51.0 - - -From 0f6cc451cecc15b12cf113f5046e9985bc23f7a7 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Fri, 9 May 2025 02:38:51 +0100 -Subject: [PATCH 504/517] block: partitions: msdos: add OF node by partition - number - -A hack for some legacy boards... - -Signed-off-by: Daniel Golle ---- - block/partitions/msdos.c | 36 +++++++++++++++++++++++++++++++++--- - 1 file changed, 33 insertions(+), 3 deletions(-) - -diff --git a/block/partitions/msdos.c b/block/partitions/msdos.c -index 073be78ba0b0..857893fa5c39 100644 ---- a/block/partitions/msdos.c -+++ b/block/partitions/msdos.c -@@ -27,6 +27,7 @@ - */ - #include - #include -+#include - - #include "check.h" - #include "efi.h" -@@ -116,6 +117,26 @@ static void set_info(struct parsed_partitions *state, int slot, - state->parts[slot].has_info = true; - } - -+static struct device_node *find_partno_of_node(struct device_node *partitions_np, -+ int partno) -+{ -+ int np_partno; -+ -+ if (!partitions_np || -+ !of_device_is_compatible(partitions_np, "msdos-partitions")) -+ return NULL; -+ -+ for_each_available_child_of_node_scoped(partitions_np, np) { -+ if (!of_property_read_u32(np, "partno", &np_partno) && -+ partno != np_partno) -+ continue; -+ -+ return np; -+ } -+ -+ return NULL; -+} -+ - /* - * Create devices for each logical partition in an extended partition. - * The logical partitions form a linked list, with each entry being -@@ -131,6 +152,8 @@ static void parse_extended(struct parsed_partitions *state, - sector_t first_sector, sector_t first_size, - u32 disksig) - { -+ struct device *ddev = disk_to_dev(state->disk); -+ struct device_node *partitions_np = of_node_get(ddev->of_node); - struct msdos_partition *p; - Sector sect; - unsigned char *data; -@@ -190,7 +213,8 @@ static void parse_extended(struct parsed_partitions *state, - continue; - } - -- put_partition(state, state->next, next, size); -+ of_put_partition(state, state->next, next, size, -+ find_partno_of_node(partitions_np, state->next)); - set_info(state, state->next, disksig); - if (p->sys_ind == LINUX_RAID_PARTITION) - state->parts[state->next].flags = ADDPART_FLAG_RAID; -@@ -580,6 +604,8 @@ static struct { - - int msdos_partition(struct parsed_partitions *state) - { -+ struct device *ddev = disk_to_dev(state->disk); -+ struct device_node *partitions_np = of_node_get(ddev->of_node); - sector_t sector_size; - Sector sect; - unsigned char *data; -@@ -676,14 +702,18 @@ int msdos_partition(struct parsed_partitions *state) - sector_t n = 2; - - n = min(size, max(sector_size, n)); -- put_partition(state, slot, start, n); -+ of_put_partition(state, slot, start, n, -+ find_partno_of_node(partitions_np, -+ slot)); - - strlcat(state->pp_buf, " <", PAGE_SIZE); - parse_extended(state, start, size, disksig); - strlcat(state->pp_buf, " >", PAGE_SIZE); - continue; - } -- put_partition(state, slot, start, size); -+ of_put_partition(state, slot, start, size, -+ find_partno_of_node(partitions_np, -+ slot)); - set_info(state, slot, disksig); - if (p->sys_ind == LINUX_RAID_PARTITION) - state->parts[slot].flags = ADDPART_FLAG_RAID; --- -2.51.0 - - -From cad132ca9e315f20dca290a1b8f5b7c71e5796be Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:51:10 +0100 -Subject: [PATCH 505/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/930-spi-mt65xx-enable-sel-clk.patch - ---- - drivers/spi/spi-mt65xx.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c -index 906e188987c8..4aed51720298 100644 ---- a/drivers/spi/spi-mt65xx.c -+++ b/drivers/spi/spi-mt65xx.c -@@ -1237,8 +1237,15 @@ static int mtk_spi_probe(struct platform_device *pdev) - if (ret < 0) - return dev_err_probe(dev, ret, "failed to enable hclk\n"); - -+ ret = clk_prepare_enable(mdata->sel_clk); -+ if (ret < 0) { -+ clk_disable_unprepare(mdata->spi_hclk); -+ return dev_err_probe(dev, ret, "failed to enable sel_clk\n"); -+ } -+ - ret = clk_prepare_enable(mdata->spi_clk); - if (ret < 0) { -+ clk_disable_unprepare(mdata->sel_clk); - clk_disable_unprepare(mdata->spi_hclk); - return dev_err_probe(dev, ret, "failed to enable spi_clk\n"); - } --- -2.51.0 - - -From 23e8f05982b92a225fe2f9dc1475feefd6aedd52 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Sun, 12 Mar 2023 16:40:31 +0100 -Subject: [PATCH 506/517] net: ethernet: mtk_wed: rename - mtk_wed_get_memory_region in mtk_wed_get_reserved_memory_region - -This is a preliminary patch to move wed ilm/dlm and cpuboot properties in -dedicated dts nodes. - -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/mediatek/mtk_wed_mcu.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -index c06e5ad18b01..ed97ca29b4e5 100644 ---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -@@ -234,8 +234,8 @@ int mtk_wed_mcu_msg_update(struct mtk_wed_device *dev, int id, void *data, - } - - static int --mtk_wed_get_memory_region(struct mtk_wed_hw *hw, int index, -- struct mtk_wed_wo_memory_region *region) -+mtk_wed_get_reserved_memory_region(struct mtk_wed_hw *hw, int index, -+ struct mtk_wed_wo_memory_region *region) - { - struct reserved_mem *rmem; - struct device_node *np; -@@ -325,7 +325,7 @@ mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo) - if (index < 0) - continue; - -- ret = mtk_wed_get_memory_region(wo->hw, index, &mem_region[i]); -+ ret = mtk_wed_get_reserved_memory_region(wo->hw, index, &mem_region[i]); - if (ret) - return ret; - } --- -2.51.0 - - -From e8e2af046559ce38fcdb522f4cc1337ea0932a70 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Sat, 11 Mar 2023 16:32:41 +0100 -Subject: [PATCH 507/517] arm64: dts: mt7986: move cpuboot in a dedicated node - -Signed-off-by: Lorenzo Bianconi ---- - arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 21 +++++++++++---------- - 1 file changed, 11 insertions(+), 10 deletions(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi -index 49b5839eb7e9..d7908645dbf8 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi -@@ -121,12 +121,6 @@ wo_dlm1: wo-dlm@151f8000 { - reg = <0 0x151f8000 0 0x2000>; - no-map; - }; -- -- wo_boot: wo-boot@15194000 { -- reg = <0 0x15194000 0 0x1000>; -- no-map; -- }; -- - }; - - soc { -@@ -533,10 +527,11 @@ wed0: wed@15010000 { - interrupt-parent = <&gic>; - interrupts = ; - memory-region = <&wo_emi0>, <&wo_ilm0>, <&wo_dlm0>, -- <&wo_data>, <&wo_boot>; -+ <&wo_data>; - memory-region-names = "wo-emi", "wo-ilm", "wo-dlm", -- "wo-data", "wo-boot"; -+ "wo-data"; - mediatek,wo-ccif = <&wo_ccif0>; -+ mediatek,wo-cpuboot = <&wo_cpuboot>; - }; - - wed1: wed@15011000 { -@@ -546,10 +541,11 @@ wed1: wed@15011000 { - interrupt-parent = <&gic>; - interrupts = ; - memory-region = <&wo_emi1>, <&wo_ilm1>, <&wo_dlm1>, -- <&wo_data>, <&wo_boot>; -+ <&wo_data>; - memory-region-names = "wo-emi", "wo-ilm", "wo-dlm", -- "wo-data", "wo-boot"; -+ "wo-data"; - mediatek,wo-ccif = <&wo_ccif1>; -+ mediatek,wo-cpuboot = <&wo_cpuboot>; - }; - - eth: ethernet@15100000 { -@@ -607,6 +603,11 @@ wo_ccif1: syscon@151ad000 { - interrupts = ; - }; - -+ wo_cpuboot: syscon@15194000 { -+ compatible = "mediatek,mt7986-wo-cpuboot", "syscon"; -+ reg = <0 0x15194000 0 0x1000>; -+ }; -+ - wifi: wifi@18000000 { - compatible = "mediatek,mt7986-wmac"; - reg = <0 0x18000000 0 0x1000000>, --- -2.51.0 - - -From 4a24e54ea7cff129f0ad3a539c091b92228885d4 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Sat, 11 Mar 2023 18:13:04 +0100 -Subject: [PATCH 508/517] net: ethernet: mtk_wed: move cpuboot in a dedicated - dts node - -Since the cpuboot memory region is not part of the RAM SoC, move cpuboot -in a deidicated syscon node. -This patch helps to keep backward-compatibility with older version of -uboot codebase where we have a limit of 8 reserved-memory dts child -nodes. -Keep backward-compatibility with older dts version where cpuboot was -defined as reserved-memory child node. - -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/mediatek/mtk_wed_mcu.c | 33 ++++++++++++++++----- - drivers/net/ethernet/mediatek/mtk_wed_wo.h | 1 + - 2 files changed, 26 insertions(+), 8 deletions(-) - -diff --git a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -index ed97ca29b4e5..87f8d0def161 100644 ---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -@@ -32,14 +32,25 @@ static struct mtk_wed_wo_memory_region mem_region[] = { - }, - }; - --static u32 wo_r32(u32 reg) -+static u32 wo_r32(struct mtk_wed_wo *wo, u32 reg) - { -- return readl(mem_region[MTK_WED_WO_REGION_BOOT].addr + reg); -+ u32 val; -+ -+ if (!wo->boot_regmap) -+ return readl(mem_region[MTK_WED_WO_REGION_BOOT].addr + reg); -+ -+ if (regmap_read(wo->boot_regmap, reg, &val)) -+ val = ~0; -+ -+ return val; - } - --static void wo_w32(u32 reg, u32 val) -+static void wo_w32(struct mtk_wed_wo *wo, u32 reg, u32 val) - { -- writel(val, mem_region[MTK_WED_WO_REGION_BOOT].addr + reg); -+ if (wo->boot_regmap) -+ regmap_write(wo->boot_regmap, reg, val); -+ else -+ writel(val, mem_region[MTK_WED_WO_REGION_BOOT].addr + reg); - } - - static struct sk_buff * -@@ -317,6 +328,9 @@ mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo) - u32 val, boot_cr; - int ret, i; - -+ wo->boot_regmap = syscon_regmap_lookup_by_phandle(wo->hw->node, -+ "mediatek,wo-cpuboot"); -+ - /* load firmware region metadata */ - for (i = 0; i < ARRAY_SIZE(mem_region); i++) { - int index = of_property_match_string(wo->hw->node, -@@ -325,6 +339,9 @@ mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo) - if (index < 0) - continue; - -+ if (index == MTK_WED_WO_REGION_BOOT && !IS_ERR(wo->boot_regmap)) -+ continue; -+ - ret = mtk_wed_get_reserved_memory_region(wo->hw, index, &mem_region[i]); - if (ret) - return ret; -@@ -373,13 +390,13 @@ mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo) - boot_cr = MTK_WO_MCU_CFG_LS_WA_BOOT_ADDR_ADDR; - else - boot_cr = MTK_WO_MCU_CFG_LS_WM_BOOT_ADDR_ADDR; -- wo_w32(boot_cr, mem_region[MTK_WED_WO_REGION_EMI].phy_addr >> 16); -+ wo_w32(wo, boot_cr, mem_region[MTK_WED_WO_REGION_EMI].phy_addr >> 16); - /* wo firmware reset */ -- wo_w32(MTK_WO_MCU_CFG_LS_WF_MCCR_CLR_ADDR, 0xc00); -+ wo_w32(wo, MTK_WO_MCU_CFG_LS_WF_MCCR_CLR_ADDR, 0xc00); - -- val = wo_r32(MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR) | -+ val = wo_r32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR) | - MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK; -- wo_w32(MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR, val); -+ wo_w32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR, val); - out: - release_firmware(fw); - -diff --git a/drivers/net/ethernet/mediatek/mtk_wed_wo.h b/drivers/net/ethernet/mediatek/mtk_wed_wo.h -index c01b1e8428f6..1b06f79662e3 100644 ---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h -@@ -231,6 +231,7 @@ struct mtk_wed_wo_queue { - struct mtk_wed_wo { - struct mtk_wed_hw *hw; - -+ struct regmap *boot_regmap; - struct mtk_wed_wo_queue q_tx; - struct mtk_wed_wo_queue q_rx; - --- -2.51.0 - - -From d66901ae6cee48a1b0735d43f780d2b1372a734f Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Sun, 12 Mar 2023 18:51:47 +0100 -Subject: [PATCH 509/517] net: ethernet: mtk_wed: move ilm a dedicated dts node - -Since the ilm memory region is not part of the RAM SoC, move ilm in a -deidicated syscon node. -This patch helps to keep backward-compatibility with older version of -uboot codebase where we have a limit of 8 reserved-memory dts child -nodes. -Keep backward-compatibility with older dts version where ilm was defined -as reserved-memory child node. - -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/mediatek/mtk_wed_mcu.c | 45 +++++++++++++++++++-- - 1 file changed, 42 insertions(+), 3 deletions(-) - -diff --git a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -index 87f8d0def161..81f77492e1ef 100644 ---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -@@ -319,6 +319,39 @@ mtk_wed_mcu_run_firmware(struct mtk_wed_wo *wo, const struct firmware *fw) - return 0; - } - -+static int -+mtk_wed_mcu_load_ilm(struct mtk_wed_wo *wo) -+{ -+ struct mtk_wed_wo_memory_region *ilm_region; -+ struct resource res; -+ struct device_node *np; -+ int ret; -+ -+ np = of_parse_phandle(wo->hw->node, "mediatek,wo-ilm", 0); -+ if (!np) -+ return 0; -+ -+ ret = of_address_to_resource(np, 0, &res); -+ of_node_put(np); -+ -+ if (ret < 0) -+ return ret; -+ -+ ilm_region = &mem_region[MTK_WED_WO_REGION_ILM]; -+ ilm_region->phy_addr = res.start; -+ ilm_region->size = resource_size(&res); -+ ilm_region->addr = devm_ioremap(wo->hw->dev, res.start, -+ resource_size(&res)); -+ -+ if (!IS_ERR(ilm_region->addr)) -+ return 0; -+ -+ ret = PTR_ERR(ilm_region->addr); -+ ilm_region->addr = NULL; -+ -+ return ret; -+} -+ - static int - mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo) - { -@@ -328,14 +361,20 @@ mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo) - u32 val, boot_cr; - int ret, i; - -+ mtk_wed_mcu_load_ilm(wo); - wo->boot_regmap = syscon_regmap_lookup_by_phandle(wo->hw->node, - "mediatek,wo-cpuboot"); - - /* load firmware region metadata */ - for (i = 0; i < ARRAY_SIZE(mem_region); i++) { -- int index = of_property_match_string(wo->hw->node, -- "memory-region-names", -- mem_region[i].name); -+ int index; -+ -+ if (mem_region[i].addr) -+ continue; -+ -+ index = of_property_match_string(wo->hw->node, -+ "memory-region-names", -+ mem_region[i].name); - if (index < 0) - continue; - --- -2.51.0 - - -From 660d36d99016c57f240fd84219aed006f716de11 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Mon, 13 Mar 2023 15:45:16 +0100 -Subject: [PATCH 510/517] net: ethernet: mtk_wed: move dlm a dedicated dts node - -Since the dlm memory region is not part of the RAM SoC, move dlm in a -deidicated syscon node. -This patch helps to keep backward-compatibility with older version of -uboot codebase where we have a limit of 8 reserved-memory dts child -nodes. -Keep backward-compatibility with older dts version where dlm was defined -as reserved-memory child node. - -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/mediatek/mtk_wed.c | 19 +++++++++++++++++++ - 1 file changed, 19 insertions(+) - -diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c -index 1e369a059edd..3c22aaefa267 100644 ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -1333,6 +1333,24 @@ mtk_wed_rro_alloc(struct mtk_wed_device *dev) - struct device_node *np; - int index; - -+ np = of_parse_phandle(dev->hw->node, "mediatek,wo-dlm", 0); -+ if (np) { -+ struct resource res; -+ int ret; -+ -+ ret = of_address_to_resource(np, 0, &res); -+ of_node_put(np); -+ -+ if (ret < 0) -+ return ret; -+ -+ dev->rro.miod_phys = res.start; -+ goto out; -+ } -+ -+ /* For backward compatibility, we need to check if DLM -+ * node is defined through reserved memory property. -+ */ - index = of_property_match_string(dev->hw->node, "memory-region-names", - "wo-dlm"); - if (index < 0) -@@ -1349,6 +1367,7 @@ mtk_wed_rro_alloc(struct mtk_wed_device *dev) - return -ENODEV; - - dev->rro.miod_phys = rmem->base; -+out: - dev->rro.fdbk_phys = MTK_WED_MIOD_COUNT + dev->rro.miod_phys; - - return mtk_wed_rro_ring_alloc(dev, &dev->rro.ring, --- -2.51.0 - - -From ddab7743c6cc805854cde7032aa185f501007ae3 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Mon, 13 Mar 2023 15:10:56 +0100 -Subject: [PATCH 511/517] arm64: dts: mt7986: move ilm in a dedicated node - -Since the ilm memory region is not part of the RAM SoC, move ilm in a -deidicated syscon node. -This patch helps to keep backward-compatibility with older version of -uboot codebase where we have a limit of 8 reserved-memory dts child -nodes. - -Signed-off-by: Lorenzo Bianconi ---- - arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 34 +++++++++++------------ - 1 file changed, 16 insertions(+), 18 deletions(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi -index d7908645dbf8..60e12fba069c 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi -@@ -97,16 +97,6 @@ wo_emi1: wo-emi@4fd40000 { - no-map; - }; - -- wo_ilm0: wo-ilm@151e0000 { -- reg = <0 0x151e0000 0 0x8000>; -- no-map; -- }; -- -- wo_ilm1: wo-ilm@151f0000 { -- reg = <0 0x151f0000 0 0x8000>; -- no-map; -- }; -- - wo_data: wo-data@4fd80000 { - reg = <0 0x4fd80000 0 0x240000>; - no-map; -@@ -526,11 +516,10 @@ wed0: wed@15010000 { - reg = <0 0x15010000 0 0x1000>; - interrupt-parent = <&gic>; - interrupts = ; -- memory-region = <&wo_emi0>, <&wo_ilm0>, <&wo_dlm0>, -- <&wo_data>; -- memory-region-names = "wo-emi", "wo-ilm", "wo-dlm", -- "wo-data"; -+ memory-region = <&wo_emi0>, <&wo_dlm0>, <&wo_data>; -+ memory-region-names = "wo-emi", "wo-dlm", "wo-data"; - mediatek,wo-ccif = <&wo_ccif0>; -+ mediatek,wo-ilm = <&wo_ilm0>; - mediatek,wo-cpuboot = <&wo_cpuboot>; - }; - -@@ -540,11 +529,10 @@ wed1: wed@15011000 { - reg = <0 0x15011000 0 0x1000>; - interrupt-parent = <&gic>; - interrupts = ; -- memory-region = <&wo_emi1>, <&wo_ilm1>, <&wo_dlm1>, -- <&wo_data>; -- memory-region-names = "wo-emi", "wo-ilm", "wo-dlm", -- "wo-data"; -+ memory-region = <&wo_emi1>, <&wo_dlm1>, <&wo_data>; -+ memory-region-names = "wo-emi", "wo-dlm", "wo-data"; - mediatek,wo-ccif = <&wo_ccif1>; -+ mediatek,wo-ilm = <&wo_ilm1>; - mediatek,wo-cpuboot = <&wo_cpuboot>; - }; - -@@ -603,6 +591,16 @@ wo_ccif1: syscon@151ad000 { - interrupts = ; - }; - -+ wo_ilm0: syscon@151e0000 { -+ compatible = "mediatek,mt7986-wo-ilm", "syscon"; -+ reg = <0 0x151e0000 0 0x8000>; -+ }; -+ -+ wo_ilm1: syscon@151f0000 { -+ compatible = "mediatek,mt7986-wo-ilm", "syscon"; -+ reg = <0 0x151f0000 0 0x8000>; -+ }; -+ - wo_cpuboot: syscon@15194000 { - compatible = "mediatek,mt7986-wo-cpuboot", "syscon"; - reg = <0 0x15194000 0 0x1000>; --- -2.51.0 - - -From f8607a0f13c5a3138a6a6c20d8954f0abeb98cc5 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Mon, 13 Mar 2023 15:53:30 +0100 -Subject: [PATCH 512/517] arm64: dts: mt7986: move dlm in a dedicated node - -Since the dlm memory region is not part of the RAM SoC, move dlm in a -deidicated syscon node. -This patch helps to keep backward-compatibility with older version of -uboot codebase where we have a limit of 8 reserved-memory dts child -nodes. - -Signed-off-by: Lorenzo Bianconi ---- - arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 30 ++++++++++++----------- - 1 file changed, 16 insertions(+), 14 deletions(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi -index 60e12fba069c..f8a99686e374 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi -@@ -101,16 +101,6 @@ wo_data: wo-data@4fd80000 { - reg = <0 0x4fd80000 0 0x240000>; - no-map; - }; -- -- wo_dlm0: wo-dlm@151e8000 { -- reg = <0 0x151e8000 0 0x2000>; -- no-map; -- }; -- -- wo_dlm1: wo-dlm@151f8000 { -- reg = <0 0x151f8000 0 0x2000>; -- no-map; -- }; - }; - - soc { -@@ -516,10 +506,11 @@ wed0: wed@15010000 { - reg = <0 0x15010000 0 0x1000>; - interrupt-parent = <&gic>; - interrupts = ; -- memory-region = <&wo_emi0>, <&wo_dlm0>, <&wo_data>; -- memory-region-names = "wo-emi", "wo-dlm", "wo-data"; -+ memory-region = <&wo_emi0>, <&wo_data>; -+ memory-region-names = "wo-emi", "wo-data"; - mediatek,wo-ccif = <&wo_ccif0>; - mediatek,wo-ilm = <&wo_ilm0>; -+ mediatek,wo-dlm = <&wo_dlm0>; - mediatek,wo-cpuboot = <&wo_cpuboot>; - }; - -@@ -529,10 +520,11 @@ wed1: wed@15011000 { - reg = <0 0x15011000 0 0x1000>; - interrupt-parent = <&gic>; - interrupts = ; -- memory-region = <&wo_emi1>, <&wo_dlm1>, <&wo_data>; -- memory-region-names = "wo-emi", "wo-dlm", "wo-data"; -+ memory-region = <&wo_emi1>, <&wo_data>; -+ memory-region-names = "wo-emi", "wo-data"; - mediatek,wo-ccif = <&wo_ccif1>; - mediatek,wo-ilm = <&wo_ilm1>; -+ mediatek,wo-dlm = <&wo_dlm1>; - mediatek,wo-cpuboot = <&wo_cpuboot>; - }; - -@@ -601,6 +593,16 @@ wo_ilm1: syscon@151f0000 { - reg = <0 0x151f0000 0 0x8000>; - }; - -+ wo_dlm0: syscon@151e8000 { -+ compatible = "mediatek,mt7986-wo-dlm", "syscon"; -+ reg = <0 0x151e8000 0 0x2000>; -+ }; -+ -+ wo_dlm1: syscon@151f8000 { -+ compatible = "mediatek,mt7986-wo-dlm", "syscon"; -+ reg = <0 0x151f8000 0 0x2000>; -+ }; -+ - wo_cpuboot: syscon@15194000 { - compatible = "mediatek,mt7986-wo-cpuboot", "syscon"; - reg = <0 0x15194000 0 0x1000>; --- -2.51.0 - - -From 74446121fe51ebdad4b00400a1b92340f0a61fee Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:51:12 +0100 -Subject: [PATCH 513/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/950-smartrg-i2c-led-driver.patch - ---- - drivers/leds/Kconfig | 10 ++++++++++ - drivers/leds/Makefile | 1 + - 2 files changed, 11 insertions(+) - -diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig -index c275963c498c..7dd68878d84b 100644 ---- a/drivers/leds/Kconfig -+++ b/drivers/leds/Kconfig -@@ -977,6 +977,16 @@ source "drivers/leds/flash/Kconfig" - comment "RGB LED drivers" - source "drivers/leds/rgb/Kconfig" - -+config LEDS_SMARTRG_LED -+ tristate "LED support for Adtran SmartRG" -+ depends on LEDS_CLASS && I2C && OF -+ help -+ This option enables support for the Adtran SmartRG platform -+ system LED driver. -+ -+ To compile this driver as a module, choose M here: the module -+ will be called leds-smartrg-system. -+ - comment "LED Triggers" - source "drivers/leds/trigger/Kconfig" - -diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile -index 32241451b805..1eabbf823afe 100644 ---- a/drivers/leds/Makefile -+++ b/drivers/leds/Makefile -@@ -81,6 +81,7 @@ obj-$(CONFIG_LEDS_POWERNV) += leds-powernv.o - obj-$(CONFIG_LEDS_PWM) += leds-pwm.o - obj-$(CONFIG_LEDS_REGULATOR) += leds-regulator.o - obj-$(CONFIG_LEDS_SC27XX_BLTC) += leds-sc27xx-bltc.o -+obj-$(CONFIG_LEDS_SMARTRG_LED) += leds-smartrg-system.o - obj-$(CONFIG_LEDS_SUN50I_A100) += leds-sun50i-a100.o - obj-$(CONFIG_LEDS_ST1202) += leds-st1202.o - obj-$(CONFIG_LEDS_SUNFIRE) += leds-sunfire.o --- -2.51.0 - - -From ce803bc11bfcaf5bb6c01c942ecd8a1d3549164c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:51:12 +0100 -Subject: [PATCH 514/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/955-dts-mt7968a-bpi-r3-add-label-to-gmac-for-sfp1-port.patch - ---- - arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts -index 5e0c2941928d..db8928987342 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts -@@ -195,6 +195,7 @@ gmac1: mac@1 { - phy-mode = "2500base-x"; - sfp = <&sfp1>; - managed = "in-band-status"; -+ openwrt,netdev-name = "sfp1"; - }; - - mdio: mdio-bus { --- -2.51.0 - - -From 4df705cab8dd3bb7be1c5f456cda96d665847a47 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 6 Feb 2025 05:07:20 +0000 -Subject: [PATCH 515/517] mtd: spinand: add work-around to prevent bootloader - wiping mtdparts - -ASUS makes use of U-Boot's fdt_fixup_mtdparts() function which applies -the partitions defined in U-Boot's mtdparts and mtdids environment -variables to the devicetree passed over to Linux. - -The undesired side-effect is that in this way also all additional -properties and child nodes get wiped, preventing NVMEM cells to be -defined for MTD partitions or UBI volumes. - -To work-around this issue, add an additional compatible string -'u-boot-dont-touch-spi-nand' which can be used instead of 'spi-nand' in -case the replacement of the MTD partitions by U-Boot should be skipped -alltogether. - -In practise this is mostly relevant for SPI-NAND which anyway comes only -with two partitions nowadays: 'Bootloader' and 'UBI_DEV'. Hence this -work-around is applicable for SPI-NAND only. Similar work-arounds for -other MTD devices can be created as well should they actually be needed. - -Signed-off-by: Daniel Golle ---- - drivers/mtd/nand/spi/core.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c -index a74bda5c4965..1dcffc2bbd18 100644 ---- a/drivers/mtd/nand/spi/core.c -+++ b/drivers/mtd/nand/spi/core.c -@@ -1668,6 +1668,7 @@ static int spinand_remove(struct spi_mem *mem) - - static const struct spi_device_id spinand_ids[] = { - { .name = "spi-nand" }, -+ { .name = "u-boot-dont-touch-spi-nand" }, - { /* sentinel */ }, - }; - MODULE_DEVICE_TABLE(spi, spinand_ids); -@@ -1675,6 +1676,7 @@ MODULE_DEVICE_TABLE(spi, spinand_ids); - #ifdef CONFIG_OF - static const struct of_device_id spinand_of_ids[] = { - { .compatible = "spi-nand" }, -+ { .compatible = "u-boot-dont-touch-spi-nand" }, - { /* sentinel */ }, - }; - MODULE_DEVICE_TABLE(of, spinand_of_ids); --- -2.51.0 - - -From 3c06beabf11952531131a8c93d4a7e11267b2b49 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Mon, 3 Nov 2025 15:51:13 +0100 -Subject: [PATCH 516/517] - /home/cynerd/turris/upstream/openwrt/target/linux/mediatek/patches-6.12/965-dts-mt7988a-add-trng-support.patch - ---- - arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -index 5717729f563c..d907769259ca 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi -@@ -1319,4 +1319,8 @@ timer { - , - ; - }; -+ -+ trng { -+ compatible = "mediatek,mt7988-rng"; -+ }; - }; --- -2.51.0 - - -From 1e87e9227c60dd7f73de3aec9882ffd5423113ad Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= -Date: Thu, 2 Oct 2025 11:54:23 +0200 -Subject: [PATCH 517/517] Pull OpenWrt One device tree from OpenWrt master - -The commit used: 915a57ccd9086db88ee74cfa531ff13f8652a447 ---- - .../boot/dts/mediatek/mt7981b-openwrt-one.dts | 460 +++++++++++++++++- - 1 file changed, 457 insertions(+), 3 deletions(-) - -diff --git a/arch/arm64/boot/dts/mediatek/mt7981b-openwrt-one.dts b/arch/arm64/boot/dts/mediatek/mt7981b-openwrt-one.dts -index 4f6cbb491287..5f54506b2cba 100644 ---- a/arch/arm64/boot/dts/mediatek/mt7981b-openwrt-one.dts -+++ b/arch/arm64/boot/dts/mediatek/mt7981b-openwrt-one.dts -@@ -1,15 +1,469 @@ --// SPDX-License-Identifier: GPL-2.0-only OR MIT -+// SPDX-License-Identifier: (GPL-2.0 OR MIT) - - /dts-v1/; -- - #include "mt7981b.dtsi" - - / { -- compatible = "openwrt,one", "mediatek,mt7981b"; - model = "OpenWrt One"; -+ compatible = "openwrt,one", "mediatek,mt7981"; -+ -+ aliases { -+ ethernet0 = &gmac1; -+ label-mac-device = &gmac0; -+ led-boot = &led_status_white; -+ led-failsafe = &led_status_red; -+ led-running = &led_status_green; -+ led-upgrade = &led_status_green; -+ serial0 = &uart0; -+ }; -+ -+ chosen { -+ stdout-path = "serial0:115200n8"; -+ rootdisk = <&ubi_fit_volume>; -+ }; - - memory@40000000 { - reg = <0 0x40000000 0 0x40000000>; - device_type = "memory"; - }; -+ -+ reg_3p3v: regulator-3p3v { -+ compatible = "regulator-fixed"; -+ regulator-name = "fixed-3.3V"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ reg_5v: regulator-5v { -+ compatible = "regulator-fixed"; -+ regulator-name = "fixed-5V"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ gpio-keys { -+ compatible = "gpio-keys"; -+ -+ user { -+ label = "user"; -+ linux,code = ; -+ gpios = <&pio 0 GPIO_ACTIVE_LOW>; -+ }; -+ -+ reset { -+ label = "reset"; -+ linux,code = ; -+ gpios = <&pio 1 GPIO_ACTIVE_LOW>; -+ }; -+ }; -+ -+ pwm-leds { -+ compatible = "pwm-leds"; -+ -+ led_status_white: led-0 { -+ color = ; -+ function = LED_FUNCTION_STATUS; -+ pwms = <&pwm 0 10000>; -+ linux,default-trigger = "pattern"; -+ led-pattern = <0 500 25 500>; -+ }; -+ -+ led_status_green: led-1 { -+ color = ; -+ function = LED_FUNCTION_STATUS; -+ pwms = <&pwm 1 10000>; -+ }; -+ }; -+ -+ gpio-leds { -+ compatible = "gpio-leds"; -+ -+ led_status_red: led-0 { -+ color = ; -+ function = LED_FUNCTION_STATUS; -+ gpios = <&pio 9 GPIO_ACTIVE_HIGH>; -+ }; -+ -+ led-1 { -+ function = LED_FUNCTION_LAN; -+ color = ; -+ gpios = <&pio 34 GPIO_ACTIVE_LOW>; -+ }; -+ -+ led-2 { -+ function = LED_FUNCTION_LAN; -+ color = ; -+ gpios = <&pio 35 GPIO_ACTIVE_LOW>; -+ }; -+ }; -+ -+ gpio-export { -+ compatible = "gpio-export"; -+ -+ gpio-0 { -+ gpio-export,name = "mikrobus-reset"; -+ gpio-export,output = <1>; -+ gpios = <&pio 2 GPIO_ACTIVE_HIGH>; -+ }; -+ -+ gpio-1 { -+ gpio-export,name = "watchdog-enable"; -+ gpio-export,output = <1>; -+ gpios = <&pio 11 GPIO_ACTIVE_HIGH>; -+ }; -+ -+ gpio-2 { -+ gpio-export,name = "usb-enable"; -+ gpio-export,output = <1>; -+ gpios = <&pio 14 GPIO_ACTIVE_HIGH>; -+ }; -+ }; -+ -+ gpio-watchdog { -+ compatible = "linux,wdt-gpio"; -+ gpios = <&pio 8 GPIO_ACTIVE_LOW>; -+ hw_algo = "toggle"; -+ hw_margin_ms = <25000>; -+ always-running; -+ }; -+}; -+ -+ð { -+ status = "okay"; -+ -+ gmac0: mac@0 { -+ compatible = "mediatek,eth-mac"; -+ reg = <0>; -+ phy-handle = <&phy15>; -+ phy-mode = "2500base-x"; -+ nvmem-cell-names = "mac-address"; -+ nvmem-cells = <&macaddr_factory_24>; -+ }; -+ -+ gmac1: mac@1 { -+ compatible = "mediatek,eth-mac"; -+ reg = <1>; -+ phy-mode = "gmii"; -+ phy-handle = <&int_gbe_phy>; -+ }; -+}; -+ -+&mdio_bus { -+ phy15: phy@f { -+ reg = <0xf>; -+ -+ airoha,pnswap-rx; -+ -+ interrupt-parent = <&pio>; -+ interrupts = <38 IRQ_TYPE_EDGE_FALLING>; -+ reset-gpios = <&pio 39 GPIO_ACTIVE_LOW>; -+ reset-assert-us = <10000>; -+ reset-deassert-us = <20000>; -+ -+ phy-mode = "2500base-x"; -+ full-duplex; -+ pause; -+ -+ leds { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ led@0 { -+ reg = <0>; -+ function = LED_FUNCTION_WAN; -+ color = ; -+ }; -+ -+ led@1 { -+ reg = <1>; -+ function = LED_FUNCTION_WAN; -+ color = ; -+ }; -+ }; -+ }; -+}; -+ -+&crypto { -+ status = "okay"; -+}; -+ -+&pio { -+ spi0_flash_pins: spi0-pins { -+ mux { -+ function = "spi"; -+ groups = "spi0", "spi0_wp_hold"; -+ }; -+ -+ conf-pu { -+ pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP"; -+ drive-strength = ; -+ bias-pull-up = ; -+ }; -+ -+ conf-pd { -+ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO"; -+ drive-strength = ; -+ bias-pull-down = ; -+ }; -+ }; -+ -+ spi1_flash_pins: spi1-pins { -+ mux { -+ function = "spi"; -+ groups = "spi1_1"; -+ }; -+ -+ conf-pu { -+ pins = "SPI1_CS"; -+ drive-strength = ; -+ bias-pull-up = ; -+ }; -+ -+ conf-pd { -+ pins = "SPI1_CLK", "SPI1_MOSI", "SPI1_MISO"; -+ drive-strength = ; -+ bias-pull-down = ; -+ }; -+ }; -+ -+ spi2_flash_pins: spi2-pins { -+ mux { -+ function = "spi"; -+ groups = "spi2"; -+ }; -+ -+ conf-pu { -+ pins = "SPI2_CS", "SPI2_WP"; -+ drive-strength = ; -+ bias-pull-up = ; -+ }; -+ -+ conf-pd { -+ pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; -+ drive-strength = ; -+ bias-pull-down = ; -+ }; -+ }; -+ -+ i2c_pins: i2c-pins { -+ mux { -+ function = "i2c"; -+ groups = "i2c0_0"; -+ }; -+ }; -+ -+ uart2_pins: uart2-pins { -+ mux { -+ function = "uart"; -+ groups = "uart2_0_tx_rx"; -+ }; -+ }; -+ -+ pwm_pins: pwm-pins { -+ mux { -+ function = "pwm"; -+ groups = "pwm0_0", "pwm1_1"; -+ }; -+ }; -+ -+ pcie_pins: pcie-pins { -+ mux { -+ function = "pcie"; -+ groups = "pcie_pereset"; -+ }; -+ }; -+}; -+ -+&pwm { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pwm_pins>; -+ status = "okay"; -+}; -+ -+&i2c0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c_pins>; -+ status = "okay"; -+ -+ rtc@51 { -+ compatible = "nxp,pcf8563"; -+ reg = <0x51>; -+ }; -+}; -+ -+&spi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_flash_pins>; -+ cs-gpios = <0>, <0>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ flash@1 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "spi-nand"; -+ reg = <1>; -+ spi-max-frequency = <52000000>; -+ -+ spi-cal-enable; -+ spi-cal-mode = "read-data"; -+ spi-cal-datalen = <7>; -+ spi-cal-data = /bits/ 8 <0x53 0x50 0x49 0x4E 0x41 0x4E 0x44>; -+ spi-cal-addrlen = <5>; -+ spi-cal-addr = /bits/ 32 <0x0 0x0 0x0 0x0 0x0>; -+ -+ partitions { -+ compatible = "fixed-partitions"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ partition@0 { -+ label = "bl2"; -+ reg = <0x0 0x100000>; -+ read-only; -+ }; -+ -+ partition@580000 { -+ label = "ubi"; -+ reg = <0x100000 0xFF00000>; -+ compatible = "linux,ubi"; -+ -+ volumes { -+ ubi_fit_volume: ubi-volume-fit { -+ volname = "fit"; -+ }; -+ }; -+ }; -+ }; -+ }; -+}; -+ -+&spi1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi1_flash_pins>; -+ status = "okay"; -+}; -+ -+&spi2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi2_flash_pins>; -+ status = "okay"; -+ -+ flash@0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "jedec,spi-nor"; -+ reg = <0>; -+ -+ spi-max-frequency = <52000000>; -+ -+ partitions { -+ compatible = "fixed-partitions"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ partition@0 { -+ label = "bl2-nor"; -+ reg = <0x00000 0x40000>; -+ }; -+ -+ partition@40000 { -+ label = "factory"; -+ reg = <0x40000 0xc0000>; -+ read-only; -+ -+ nvmem-layout { -+ compatible = "fixed-layout"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ eeprom_factory_0: eeprom@0 { -+ reg = <0x0 0x1000>; -+ }; -+ -+ macaddr_factory_4: macaddr@4 { -+ reg = <0x4 0x6>; -+ compatible = "mac-base"; -+ #nvmem-cell-cells = <1>; -+ }; -+ -+ macaddr_factory_24: macaddr@24 { -+ reg = <0x24 0x6>; -+ compatible = "mac-base"; -+ }; -+ }; -+ }; -+ -+ partition@100000 { -+ label = "fip-nor"; -+ reg = <0x100000 0x80000>; -+ }; -+ -+ partition@180000 { -+ label = "recovery"; -+ reg = <0x180000 0xc80000>; -+ }; -+ }; -+ }; -+}; -+ -+&xhci { -+ phys = <&u2port0 PHY_TYPE_USB2>; -+ vusb33-supply = <®_3p3v>; -+ vbus-supply = <®_5v>; -+ mediatek,u3p-dis-msk = <0x01>; -+ status = "okay"; -+}; -+ -+&uart0 { -+ status = "okay"; -+}; -+ -+&uart2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart2_pins>; -+ status = "okay"; -+}; -+ -+&usb_phy { -+ status = "okay"; -+}; -+ -+&watchdog { -+ status = "okay"; -+}; -+ -+&wifi { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ nvmem-cells = <&eeprom_factory_0>; -+ nvmem-cell-names = "eeprom"; -+ status = "okay"; -+ -+ band@0 { -+ reg = <0>; -+ nvmem-cells = <&macaddr_factory_4 0>; -+ nvmem-cell-names = "mac-address"; -+ }; -+ -+ band@1 { -+ reg = <1>; -+ nvmem-cells = <&macaddr_factory_4 7>; -+ nvmem-cell-names = "mac-address"; -+ }; -+}; -+ -+&pcie { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie_pins>; -+ status = "okay"; -+}; -+ -+&sgmiisys0 { -+ /delete-node/ mediatek,pnswap; - }; --- -2.51.0 - -- cgit v1.3.1