[rdkb][common][bsp][Refactor and sync kernel from openwrt]
[Description]
8bbd77c [kernel][common][eth][Add 1000basex AN support for the SGMII]
ea141fa [mt7988][dts][Change mt7988 snfi dts to change ubi partition size align with spim]
1f40e40 [kernel][common][eth][Update power level parse function for the SFP]
1c921c6 [kernel][common][eth][Fix MINI-GBIC-GT v8.1 SFP IOT issue]
f1c42d3 [kernel][common][eth][Add 10000baseCR_Full capability to USXGMII for the SFP+]
9186b59 [kernel][mt7981][eth][mediatek-ge: Change TX amplitude from 89% to 100% on MT7981 now]
a0af641 [kernel][mt7988][Fix USXGMII to SGMII mode change issue]
c0f7841 [kernel][mt7988][eth][Refactor SER triggering condition for the XGDM to GDM dynamically change]
21e3d36 [kernel][mt7988][Fix SGMII to USXGMII mode change issue for the 10G SFP+ optical module]
7814223 [openwrt][mt7988][eth][Add HW version check for MT7988]
f1f4a6a [kernel][common][hnat][Fix the conditions for NAT66 binding]
8a3d83f [mt7988][gps][Add uart1 to gsw for Airoha gnss server anld]
c95912a [kernel][mt7988][dts][add dts to limit mt7988a pcie and cpu as mt7988d]
632cbdc [Add PCIe max link width adjustment feature]
[Release-log]
Change-Id: I9e24aab6e06280fe5a50febf490bf1ce704e1757
diff --git a/recipes-devtools/smp/files/smp-mt76.sh b/recipes-devtools/smp/files/smp-mt76.sh
index c76e2f8..cc5b46b 100644
--- a/recipes-devtools/smp/files/smp-mt76.sh
+++ b/recipes-devtools/smp/files/smp-mt76.sh
@@ -14,7 +14,8 @@
WIFI_RADIO3=0
WED_ENABLE=0
-module_param=/sys/module/mt7915e/parameters/wed_enable
+WIFI_MODULE_LIST='mt7915e mt7996e'
+
get_if_info()
{
# try to get all wifi and eth net interface.
@@ -54,15 +55,15 @@
fi
done;
- WED_ENABLE_LIST=
- if [[ -f "$module_param" ]]; then
- WED_ENABLE_LIST=`cat $module_param`
- fi
- for v in $WED_ENABLE_LIST;
+
+ for v in $WIFI_MODULE_LIST;
do
- dbg2 "wed enable ori info $v"
- if [[ $v == "Y" ]]; then
- WED_ENABLE=1
+ if [[ -f "/sys/module/$v/parameters/wed_enable" ]]; then
+ WED_ENABLE_LIST=`cat /sys/module/$v/parameters/wed_enable`
+ dbg2 "wed enable ori info $v $WED_ENABLE_LIST"
+ if [[ $WED_ENABLE_LIST == "Y" ]]; then
+ WED_ENABLE=1
+ fi
fi
done;
dbg2 "NUM_WIFI_CARD = $NUM_WIFI_CARD"
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988.dtsi b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988.dtsi
index c9da613..28cb8eb 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988.dtsi
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988.dtsi
@@ -127,6 +127,11 @@
interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
};
+ hwver: hwver {
+ compatible = "mediatek,hwver", "syscon";
+ reg = <0 0x8000000 0 0x1000>;
+ };
+
thermal-zones {
cpu_thermal: cpu-thermal {
polling-delay-passive = <1000>;
@@ -841,6 +846,7 @@
mediatek,xfi_pll = <&xfi_pll>;
mediatek,infracfg = <&topmisc>;
mediatek,toprgu = <&watchdog>;
+ mediatek,hwver = <&hwver>;
#reset-cells = <1>;
#address-cells = <1>;
#size-cells = <0>;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-88d-10g-spim-nand.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-88d-10g-spim-nand.dts
new file mode 100644
index 0000000..8aa687e
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-88d-10g-spim-nand.dts
@@ -0,0 +1,532 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2021 MediaTek Inc.
+ * Author: Sam.Shih <sam.shih@mediatek.com>
+ */
+
+/dts-v1/;
+#include "mt7988.dtsi"
+
+/ {
+ model = "MediaTek MT7988A as 88D DSA 10G SPIM-NAND RFB";
+ compatible = "mediatek,mt7988a-88d-10g-spim-snand",
+ /* Reserve this for DVFS if creating new dts */
+ "mediatek,mt7988";
+
+ chosen {
+ bootargs = "console=ttyS0,115200n1 loglevel=8 \
+ earlycon=uart8250,mmio32,0x11000000 \
+ pci=pcie_bus_perf";
+ };
+
+ cpus {
+ /delete-node/ cpu@3;
+ };
+
+ memory {
+ reg = <0 0x40000000 0 0x10000000>;
+ };
+
+ nmbm_spim_nand {
+ compatible = "generic,nmbm";
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ lower-mtd-device = <&spi_nand>;
+ forced-create;
+
+ 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 0x0400000>;
+ };
+
+ partition@580000 {
+ label = "FIP";
+ reg = <0x580000 0x0200000>;
+ };
+
+ partition@780000 {
+ label = "ubi";
+ reg = <0x780000 0x7080000>;
+ };
+ };
+ };
+
+ wsys_adie: wsys_adie@0 {
+ // fpga cases need to manual change adie_id / sku_type for dvt only
+ compatible = "mediatek,rebb-mt7988-adie";
+ adie_id = <7976>;
+ sku_type = <3000>;
+ };
+
+ sound_wm8960 {
+ compatible = "mediatek,mt79xx-wm8960-machine";
+ mediatek,platform = <&afe>;
+ audio-routing = "Headphone", "HP_L",
+ "Headphone", "HP_R",
+ "LINPUT1", "AMIC",
+ "RINPUT1", "AMIC";
+ mediatek,audio-codec = <&wm8960>;
+ status = "disabled";
+ };
+
+ sound_si3218x {
+ compatible = "mediatek,mt79xx-si3218x-machine";
+ mediatek,platform = <&afe>;
+ mediatek,ext-codec = <&proslic_spi>;
+ status = "disabled";
+ };
+};
+
+&fan {
+ pwms = <&pwm 0 50000 0>;
+ status = "okay";
+};
+
+&afe {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcm_pins>;
+ status = "okay";
+};
+
+&pwm {
+ status = "okay";
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+ status = "okay";
+};
+
+&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 =
+ <RT5190A_OPMODE_AUTO RT5190A_OPMODE_FPWM>;
+ regulator-boot-on;
+ };
+ buck2 {
+ regulator-name = "vcore";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-boot-on;
+ };
+ buck3 {
+ regulator-name = "proc";
+ 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 =
+ <RT5190A_OPMODE_AUTO RT5190A_OPMODE_FPWM>;
+ regulator-boot-on;
+ };
+ ldo {
+ regulator-name = "rt5190a-ldo";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-boot-on;
+ };
+ };
+ };
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+ status = "okay";
+
+ wm8960: wm8960@1a {
+ compatible = "wlf,wm8960";
+ reg = <0x1a>;
+ };
+
+ dps368: dps368@77 {
+ compatible = "infineon,dps310";
+ reg = <0x77>;
+ };
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_flash_pins>;
+ status = "okay";
+
+ spi_nand: spi_nand@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spi-nand";
+ 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>;
+ reg = <0>;
+ spi-max-frequency = <52000000>;
+ spi-tx-buswidth = <4>;
+ spi-rx-buswidth = <4>;
+ };
+};
+
+&spi1 {
+ pinctrl-names = "default";
+ /* pin shared with snfi */
+ pinctrl-0 = <&spic_pins>;
+ status = "disabled";
+
+ 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_gpio = <&pio 54 0>;
+ ig,enable-spi = <1>; /* 1: Enable, 0: Disable */
+ };
+};
+
+&pcie0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie0_pins>;
+ status = "okay";
+};
+
+&pcie1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie1_pins>;
+ max-link-width = <1>;
+ status = "okay";
+};
+
+&pcie2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie2_pins>;
+ status = "disabled";
+};
+
+&pcie3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie3_pins>;
+ status = "okay";
+};
+
+&pio {
+ mdio0_pins: mdio0-pins {
+ mux {
+ function = "mdio";
+ groups = "mdc_mdio0";
+ };
+
+ conf {
+ groups = "mdc_mdio0";
+ drive-strength = <MTK_DRIVE_8mA>;
+ };
+ };
+
+ gbe_led0_pins: gbe-pins {
+ mux {
+ function = "led";
+ groups = "gbe_led0";
+ };
+ };
+
+ i2c0_pins: i2c0-pins-g0 {
+ mux {
+ function = "i2c";
+ groups = "i2c0_1";
+ };
+ };
+
+ 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";
+ };
+ };
+
+ spi0_flash_pins: spi0-pins {
+ mux {
+ function = "spi";
+ groups = "spi0", "spi0_wp_hold";
+ };
+ };
+
+ spic_pins: spi1-pins {
+ mux {
+ function = "spi";
+ groups = "spi1";
+ };
+ };
+
+ i2c1_pins: i2c1-pins {
+ mux {
+ function = "i2c";
+ groups = "i2c1_0";
+ };
+ };
+
+ i2s_pins: i2s-pins {
+ mux {
+ function = "audio";
+ groups = "i2s";
+ };
+ };
+
+ pcm_pins: pcm-pins {
+ mux {
+ function = "audio";
+ groups = "pcm";
+ };
+ };
+
+ uart1_pins: uart1-pins {
+ mux {
+ function = "uart";
+ groups = "uart1_2";
+ };
+ };
+};
+
+&watchdog {
+ status = "disabled";
+};
+
+ð {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mdio0_pins>;
+ status = "okay";
+
+ gmac0: mac@0 {
+ compatible = "mediatek,eth-mac";
+ reg = <0>;
+ mac-type = "xgdm";
+ phy-mode = "10gbase-kr";
+
+ fixed-link {
+ speed = <10000>;
+ full-duplex;
+ pause;
+ };
+ };
+
+ gmac1: mac@1 {
+ compatible = "mediatek,eth-mac";
+ reg = <1>;
+ mac-type = "xgdm";
+ phy-mode = "usxgmii";
+ phy-handle = <&phy0>;
+ };
+
+ gmac2: mac@2 {
+ compatible = "mediatek,eth-mac";
+ reg = <2>;
+ mac-type = "xgdm";
+ phy-mode = "usxgmii";
+ phy-handle = <&phy1>;
+ };
+
+ mdio: mdio-bus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <10500000>;
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reset-gpios = <&pio 72 1>;
+ reset-assert-us = <100000>;
+ reset-deassert-us = <221000>;
+ };
+
+ phy1: ethernet-phy@8 {
+ reg = <8>;
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reset-gpios = <&pio 71 1>;
+ reset-assert-us = <100000>;
+ reset-deassert-us = <221000>;
+ };
+
+ switch@0 {
+ compatible = "mediatek,mt7988";
+ reg = <31>;
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ label = "lan0";
+ phy-mode = "gmii";
+ phy-handle = <&sphy0>;
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "lan1";
+ phy-mode = "gmii";
+ phy-handle = <&sphy1>;
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan2";
+ phy-mode = "gmii";
+ phy-handle = <&sphy2>;
+ };
+
+ port@3 {
+ reg = <3>;
+ label = "lan3";
+ phy-mode = "gmii";
+ phy-handle = <&sphy3>;
+ };
+
+ port@6 {
+ reg = <6>;
+ label = "cpu";
+ ethernet = <&gmac0>;
+ phy-mode = "10gbase-kr";
+
+ fixed-link {
+ speed = <10000>;
+ full-duplex;
+ pause;
+ };
+ };
+ };
+
+ mdio {
+ compatible = "mediatek,dsa-slave-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gbe_led0_pins>;
+
+ sphy0: switch_phy0@0 {
+ compatible = "ethernet-phy-id03a2.9481";
+ reg = <0>;
+ phy-mode = "gmii";
+ rext = "efuse";
+ tx_r50 = "efuse";
+ nvmem-cells = <&phy_calibration_p0>;
+ nvmem-cell-names = "phy-cal-data";
+ };
+
+ sphy1: switch_phy1@1 {
+ compatible = "ethernet-phy-id03a2.9481";
+ reg = <1>;
+ phy-mode = "gmii";
+ rext = "efuse";
+ tx_r50 = "efuse";
+ nvmem-cells = <&phy_calibration_p1>;
+ nvmem-cell-names = "phy-cal-data";
+ };
+
+ sphy2: switch_phy2@2 {
+ compatible = "ethernet-phy-id03a2.9481";
+ reg = <2>;
+ phy-mode = "gmii";
+ rext = "efuse";
+ tx_r50 = "efuse";
+ nvmem-cells = <&phy_calibration_p2>;
+ nvmem-cell-names = "phy-cal-data";
+ };
+
+ sphy3: switch_phy3@3 {
+ compatible = "ethernet-phy-id03a2.9481";
+ reg = <3>;
+ phy-mode = "gmii";
+ rext = "efuse";
+ tx_r50 = "efuse";
+ nvmem-cells = <&phy_calibration_p3>;
+ nvmem-cell-names = "phy-cal-data";
+ };
+ };
+ };
+ };
+};
+
+&hnat {
+ mtketh-wan = "eth1";
+ mtketh-lan = "lan";
+ mtketh-lan2 = "eth2";
+ mtketh-max-gmac = <3>;
+ status = "okay";
+};
+
+&slot0 {
+ mt7996@0,0 {
+ reg = <0x0000 0 0 0 0>;
+ device_type = "pci";
+ mediatek,mtd-eeprom = <&factory 0x0>;
+ };
+};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-snfi-nand.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-snfi-nand.dts
index c4b2721..adbfb7c 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-snfi-nand.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-snfi-nand.dts
@@ -61,7 +61,7 @@
partition@780000 {
label = "ubi";
- reg = <0x780000 0x4000000>;
+ reg = <0x780000 0x7080000>;
};
};
};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-gsw-10g-spim-nand.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-gsw-10g-spim-nand.dts
index 407b8ed..de90f42 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-gsw-10g-spim-nand.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-gsw-10g-spim-nand.dts
@@ -161,6 +161,12 @@
status = "okay";
};
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+ status = "okay";
+};
+
&spi0 {
pinctrl-names = "default";
pinctrl-0 = <&spi0_flash_pins>;
@@ -307,6 +313,13 @@
groups = "spi1";
};
};
+
+ uart1_pins: uart1-pins {
+ mux {
+ function = "uart";
+ groups = "uart1_2";
+ };
+ };
};
&watchdog {
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988c-dsa-10g-snfi-nand.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988c-dsa-10g-snfi-nand.dts
index 53b9668..972452f 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988c-dsa-10g-snfi-nand.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988c-dsa-10g-snfi-nand.dts
@@ -61,7 +61,7 @@
partition@780000 {
label = "ubi";
- reg = <0x780000 0x4000000>;
+ reg = <0x780000 0x7080000>;
};
};
};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.h b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.h
index b70fc72..ec7167b 100755
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.h
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.h
@@ -28,6 +28,7 @@
#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
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 05a5595..686ddda 100755
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -40,7 +40,6 @@
static int mtk_msg_level = -1;
atomic_t reset_lock = ATOMIC_INIT(0);
atomic_t force = ATOMIC_INIT(0);
-atomic_t reset_pending = ATOMIC_INIT(0);
module_param_named(msg_level, mtk_msg_level, int, 0);
MODULE_PARM_DESC(msg_level, "Message level (-1=defaults,0=none,...,16=all)");
@@ -462,6 +461,28 @@
mtk_w32(eth, val, 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;
+ };
+
+ if ((mac_fsm & 0xFFFF0000) == 0x01010000 &&
+ (gdm_fsm & 0xFFFF0000) == 0x00000000)
+ return true;
+
+ return false;
+}
+
static void mtk_setup_eee(struct mtk_mac *mac, bool enable)
{
struct mtk_eth *eth = mac->hw;
@@ -500,6 +521,34 @@
mtk_w32(eth, mcr, MTK_MAC_MCR(mac->id));
}
+static int mtk_get_hwver(struct mtk_eth *eth)
+{
+ struct device_node *np;
+ struct regmap *hwver;
+ u32 info = 0;
+
+ eth->hwver = MTK_HWID_V1;
+
+ np = of_parse_phandle(eth->dev->of_node, "mediatek,hwver", 0);
+ if (!np)
+ return -EINVAL;
+
+ hwver = syscon_node_to_regmap(np);
+ if (IS_ERR(hwver))
+ return PTR_ERR(hwver);
+
+ regmap_read(hwver, 0x8, &info);
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3))
+ eth->hwver = FIELD_GET(HWVER_BIT_NETSYS_3, info);
+ else
+ eth->hwver = FIELD_GET(HWVER_BIT_NETSYS_1_2, info);
+
+ of_node_put(np);
+
+ return 0;
+}
+
static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
phy_interface_t interface)
{
@@ -737,13 +786,11 @@
* when swtiching XGDM to GDM. Therefore, here trigger an SER
* to let GDM go back to the initial state.
*/
- if (mac->type != mac_type) {
- if (atomic_read(&reset_pending) == 0) {
+ if (mac->type != mac_type && !mtk_check_gmac23_idle(mac)) {
+ if (!test_bit(MTK_RESETTING, &mac->hw->state)) {
atomic_inc(&force);
schedule_work(ð->pending_work);
- atomic_inc(&reset_pending);
- } else
- atomic_dec(&reset_pending);
+ }
}
}
@@ -1037,6 +1084,7 @@
if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_USXGMII)) {
phylink_set(mask, 10000baseKR_Full);
phylink_set(mask, 10000baseT_Full);
+ phylink_set(mask, 10000baseCR_Full);
phylink_set(mask, 10000baseSR_Full);
phylink_set(mask, 10000baseLR_Full);
phylink_set(mask, 10000baseLRM_Full);
@@ -3744,6 +3792,12 @@
MTK_FE_INT_RFIFO_OV | MTK_FE_INT_RFIFO_UF, MTK_FE_INT_ENABLE);
if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
+ /* PSE dummy page mechanism */
+ if (eth->soc->caps != MT7988_CAPS || eth->hwver != MTK_HWID_V1)
+ mtk_w32(eth, PSE_DUMMY_WORK_GDM(1) |
+ PSE_DUMMY_WORK_GDM(2) | PSE_DUMMY_WORK_GDM(3) |
+ DUMMY_PAGE_THR, PSE_DUMY_REQ);
+
/* PSE should not drop port1, port8 and port9 packets */
mtk_w32(eth, 0x00000302, PSE_NO_DROP_CFG);
@@ -4568,6 +4622,8 @@
eth->phy_scratch_ring = res->start + MTK_ETH_SRAM_OFFSET;
}
+ mtk_get_hwver(eth);
+
if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
eth->ip_align = NET_IP_ALIGN;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 03c18f0..2082ec6 100755
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -761,6 +761,10 @@
#define GPIO_BIAS_CTRL 0xed0
#define GPIO_DRV_SEL10 0xf00
+/* SoC hardware version register */
+#define HWVER_BIT_NETSYS_1_2 BIT(0)
+#define HWVER_BIT_NETSYS_3 BIT(8)
+
/* ethernet subsystem chip id register */
#define ETHSYS_CHIPID0_3 0x0
#define ETHSYS_CHIPID4_7 0x4
@@ -1230,6 +1234,12 @@
MTK_GDM_TYPE_MAX
};
+enum mtk_hw_id {
+ MTK_HWID_V1 = 0,
+ MTK_HWID_V2,
+ MTK_HWID_MAX
+};
+
static inline const char *gdm_type(int type)
{
switch (type) {
@@ -1758,6 +1768,7 @@
struct net_device *netdev[MTK_MAX_DEVS];
struct mtk_mac *mac[MTK_MAX_DEVS];
int irq[MTK_MAX_IRQ_NUM];
+ u8 hwver;
u32 msg_enable;
unsigned long sysclk;
struct regmap *ethsys;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
index a30ec1e..2e68d3d 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
@@ -1368,8 +1368,8 @@
foe->ipv6_5t_route.dport;
}
-#if defined(CONFIG_MEDIATEK_NETSYS_V3)
if (ct && (ct->status & IPS_SRC_NAT)) {
+#if defined(CONFIG_MEDIATEK_NETSYS_V3)
entry.bfib1.pkt_type = IPV6_HNAPT;
if (IS_WAN(dev) || IS_DSA_WAN(dev)) {
@@ -1404,8 +1404,10 @@
entry.ipv6_hnapt.new_sport = ntohs(pptr->src);
entry.ipv6_hnapt.new_dport = ntohs(pptr->dst);
- }
+#else
+ return -1;
#endif
+ }
entry.ipv6_5t_route.iblk2.dscp =
(ip6h->priority << 4 |
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c
index 9aef092..4841134 100755
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c
@@ -144,6 +144,18 @@
mdelay(1);
}
+int mtk_sgmii_need_powerdown(struct mtk_sgmii_pcs *mpcs)
+{
+ u32 val;
+
+ /* need to power down sgmii if link down */
+ regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
+ if (!(val & SGMII_LINK_STATYS))
+ return true;
+
+ return false;
+}
+
void mtk_sgmii_setup_phya_gen1(struct mtk_sgmii_pcs *mpcs)
{
if (!mpcs->regmap_pextp)
@@ -412,6 +424,17 @@
sgm_mode = SGMII_IF_MODE_SGMII |
SGMII_REMOTE_FAULT_DIS |
SGMII_SPEED_DUPLEX_AN;
+ } else if (phylink_autoneg_inband(mode)) {
+ /* 1000base-X or HSGMII with autoneg */
+ if (interface == PHY_INTERFACE_MODE_2500BASEX)
+ return -EINVAL;
+
+ bmcr = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
+ advertising) ? SGMII_AN_ENABLE : 0;
+ if (bmcr)
+ sgm_mode = SGMII_SPEED_DUPLEX_AN;
+ else
+ speed = SGMII_SPEED_1000;
} else {
/* 1000base-X or HSGMII without autoneg */
speed = SGMII_SPEED_1000;
@@ -419,7 +442,8 @@
sgm_mode = SGMII_IF_MODE_SGMII;
}
- if (mpcs->interface != interface) {
+ if (mpcs->interface != interface ||
+ mtk_sgmii_need_powerdown(mpcs)) {
link_timer = phylink_get_link_timer_ns(interface);
if (link_timer < 0)
return link_timer;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_usxgmii.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_usxgmii.c
index 73f84f6..3deb616 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_usxgmii.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_usxgmii.c
@@ -597,6 +597,31 @@
mdelay(10);
}
+static int mtk_usxgmii_pcs_config(struct phylink_pcs *pcs, unsigned int 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);
+ struct mtk_eth *eth = mpcs->eth;
+ int err = 0;
+
+ mpcs->interface = interface;
+
+ mtk_usxgmii_xfi_pll_enable(eth->usxgmii);
+ mtk_usxgmii_reset(eth, mpcs->id);
+
+ /* Setup USXGMIISYS with the determined property */
+ if (interface == PHY_INTERFACE_MODE_USXGMII)
+ err = mtk_usxgmii_setup_phya_an_10000(mpcs);
+ else if (interface == PHY_INTERFACE_MODE_10GKR)
+ err = mtk_usxgmii_setup_phya_force_10000(mpcs);
+ else if (interface == PHY_INTERFACE_MODE_5GBASER)
+ err = mtk_usxgmii_setup_phya_force_5000(mpcs);
+
+ return err;
+}
+
static void mtk_usxgmii_pcs_get_state(struct phylink_pcs *pcs,
struct phylink_link_state *state)
{
@@ -664,31 +689,10 @@
state->link = FIELD_GET(MTK_USXGMII_PCS_LINK, val);
state->duplex = DUPLEX_FULL;
}
-}
-
-static int mtk_usxgmii_pcs_config(struct phylink_pcs *pcs, unsigned int 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);
- struct mtk_eth *eth = mpcs->eth;
- int err = 0;
-
- mpcs->interface = interface;
- mtk_usxgmii_xfi_pll_enable(eth->usxgmii);
- mtk_usxgmii_reset(eth, mpcs->id);
-
- /* Setup USXGMIISYS with the determined property */
- if (interface == PHY_INTERFACE_MODE_USXGMII)
- err = mtk_usxgmii_setup_phya_an_10000(mpcs);
- else if (interface == PHY_INTERFACE_MODE_10GKR)
- err = mtk_usxgmii_setup_phya_force_10000(mpcs);
- else if (interface == PHY_INTERFACE_MODE_5GBASER)
- err = mtk_usxgmii_setup_phya_force_5000(mpcs);
-
- return err;
+ if (state->link == 0)
+ mtk_usxgmii_pcs_config(pcs, MLO_AN_INBAND,
+ state->interface, NULL, false);
}
void mtk_usxgmii_pcs_restart_an(struct phylink_pcs *pcs)
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mediatek-ge.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mediatek-ge.c
index b99ee0b..7a1233a 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mediatek-ge.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mediatek-ge.c
@@ -510,17 +510,6 @@
* GBE: +7, TBT: +1, HBT: +4, TST: +7
*/
memcpy(bias, (const void *)vals_9461, sizeof(bias));
- for (i = 0; i <= 12; i += 4) {
- if (likely(buf[i >> 2] + bias[i] >= 32)) {
- bias[i] -= 13;
- } else {
- phy_modify_mmd(phydev, MDIO_MMD_VEND1,
- 0x5c, 0x7 << i, bias[i] << i);
- bias[i + 1] += 13;
- bias[i + 2] += 13;
- bias[i + 3] += 13;
- }
- }
break;
case MTK_GPHY_ID_MT7988:
memcpy(bias, (const void *)vals_9481, sizeof(bias));
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/pci/controller/pcie-mediatek-gen3.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/pci/controller/pcie-mediatek-gen3.c
index 0e01fde..4012dba 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/pci/controller/pcie-mediatek-gen3.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/pci/controller/pcie-mediatek-gen3.c
@@ -142,6 +142,7 @@
int num_clks;
int irq;
+ int max_link_width;
int direct_msi_enable;
int direct_msi[PCIE_MSI_IRQS_PER_SET];
u32 saved_irq_state;
@@ -211,6 +212,26 @@
.write = mtk_pcie_config_write,
};
+/**
+ * This function will try to find the limitation of link width by finding
+ * a property called "max-link-width" of the given device node.
+ *
+ * @node: device tree node with the max link width information
+ *
+ * Returns the associated max link width from DT, or a negative value if the
+ * required property is not found or is invalid.
+ */
+int of_pci_get_max_link_width(struct device_node *node)
+{
+ u32 max_link_width = 0;
+
+ if (of_property_read_u32(node, "max-link-width", &max_link_width) ||
+ max_link_width == 0 || max_link_width > 2)
+ return -EINVAL;
+
+ return max_link_width;
+}
+
static int mtk_pcie_set_trans_table(struct mtk_pcie_port *port,
resource_size_t cpu_addr,
resource_size_t pci_addr,
@@ -292,6 +313,16 @@
val |= PCIE_RC_MODE;
writel_relaxed(val, port->base + PCIE_SETTING_REG);
+ /* Set link width*/
+ val = readl_relaxed(port->base + PCIE_SETTING_REG);
+ if (port->max_link_width == 1) {
+ val &= ~GENMASK(11, 8);
+ } else if (port->max_link_width == 2) {
+ val &= ~GENMASK(11, 8);
+ val |= BIT(8);
+ }
+ writel_relaxed(val, port->base + PCIE_SETTING_REG);
+
/* Set class code */
val = readl_relaxed(port->base + PCIE_PCI_IDS_1);
val &= ~GENMASK(31, 8);
@@ -872,6 +903,10 @@
return port->num_clks;
}
+ port->max_link_width = of_pci_get_max_link_width(dev->of_node);
+ if (port->max_link_width < 0)
+ dev_err(dev, "failed to get max link width\n");
+
return 0;
}
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/755-net-phy-sfp-add-rollball-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/755-net-phy-sfp-add-rollball-support.patch
index a7a4481..5f85133 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/755-net-phy-sfp-add-rollball-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/755-net-phy-sfp-add-rollball-support.patch
@@ -676,7 +676,7 @@
#if IS_ENABLED(CONFIG_HWMON)
struct sfp_diag diag;
-@@ -303,6 +313,144 @@ static const struct of_device_id sfp_of_
+@@ -303,6 +313,155 @@ static const struct of_device_id sfp_of_
};
MODULE_DEVICE_TABLE(of, sfp_of_match);
@@ -690,6 +690,11 @@
+ sfp->tx_fault_ignore = true;
+}
+
++static void sfp_fixup_ruijie_gbic(struct sfp *sfp)
++{
++ sfp->mdio_protocol = MDIO_I2C_NONE;
++}
++
+static void sfp_fixup_halny_gsfp(struct sfp *sfp)
+{
+ /* Ignore the TX_FAULT and LOS signals on this module.
@@ -738,44 +743,48 @@
+ linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, modes);
+}
+
-+#define SFP_QUIRK(_v, _p, _m, _f) \
-+ { .vendor = _v, .part = _p, .modes = _m, .fixup = _f, }
-+#define SFP_QUIRK_M(_v, _p, _m) SFP_QUIRK(_v, _p, _m, NULL)
-+#define SFP_QUIRK_F(_v, _p, _f) SFP_QUIRK(_v, _p, NULL, _f)
++#define SFP_QUIRK(_v, _p, _r, _m, _f) \
++ { .vendor = _v, .part = _p, .revision = _r, .modes = _m, .fixup = _f, }
++#define SFP_QUIRK_M(_v, _p, _r, _m) SFP_QUIRK(_v, _p, _r, _m, NULL)
++#define SFP_QUIRK_F(_v, _p, _r, _f) SFP_QUIRK(_v, _p, _r, NULL, _f)
+
+static const struct sfp_quirk sfp_quirks[] = {
++ // Ruijie MINI-GBIC-GT81 has a RL8211F PHY device, but it cannot
++ // reflect correct BMSR/ADVERTISE from the PHY.
++ SFP_QUIRK_F("RUIJIE", "MINI-GBIC-GT", "81", sfp_fixup_ruijie_gbic),
++
+ // Alcatel Lucent G-010S-P can operate at 2500base-X, but incorrectly
+ // report 2500MBd NRZ in their EEPROM
-+ SFP_QUIRK_M("ALCATELLUCENT", "G010SP", sfp_quirk_2500basex),
++ SFP_QUIRK_M("ALCATELLUCENT", "G010SP", '\0', sfp_quirk_2500basex),
+
+ // Alcatel Lucent G-010S-A can operate at 2500base-X, but report 3.2GBd
+ // NRZ in their EEPROM
-+ SFP_QUIRK("ALCATELLUCENT", "3FE46541AA", sfp_quirk_2500basex,
++ SFP_QUIRK("ALCATELLUCENT", "3FE46541AA", '\0', sfp_quirk_2500basex,
+ sfp_fixup_long_startup),
+
-+ SFP_QUIRK_F("HALNy", "HL-GSFP", sfp_fixup_halny_gsfp),
++ SFP_QUIRK_F("HALNy", "HL-GSFP", '\0', sfp_fixup_halny_gsfp),
+
+ // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd NRZ in
+ // their EEPROM
-+ SFP_QUIRK("HUAWEI", "MA5671A", sfp_quirk_2500basex,
++ SFP_QUIRK("HUAWEI", "MA5671A", '\0', sfp_quirk_2500basex,
+ sfp_fixup_ignore_tx_fault),
+
+ // Lantech 8330-262D-E can operate at 2500base-X, but incorrectly report
+ // 2500MBd NRZ in their EEPROM
-+ SFP_QUIRK_M("Lantech", "8330-262D-E", sfp_quirk_2500basex),
++ SFP_QUIRK_M("Lantech", "8330-262D-E", '\0', sfp_quirk_2500basex),
+
-+ SFP_QUIRK_M("CISCO-JDSU", "PLRXPL-VC-S43-CG", sfp_quirk_10000baseSR),
++ SFP_QUIRK_M("CISCO-JDSU", "PLRXPL-VC-S43-CG", '\0', sfp_quirk_10000baseSR),
+
-+ SFP_QUIRK_M("UBNT", "UF-INSTANT", sfp_quirk_ubnt_uf_instant),
++ SFP_QUIRK_M("UBNT", "UF-INSTANT", '\0', sfp_quirk_ubnt_uf_instant),
+
-+ SFP_QUIRK_F("ETU", "ESP-T5-R", sfp_fixup_rollball_cc),
-+ SFP_QUIRK_F("OEM", "SFP-10G-T", sfp_fixup_rollball_cc),
-+ SFP_QUIRK_F("OEM", "RTSFP-10", sfp_fixup_rollball_cc),
-+ SFP_QUIRK_F("OEM", "RTSFP-10G", sfp_fixup_rollball_cc),
-+ SFP_QUIRK_F("OEM", "TNBYV02-C0X-C3", sfp_fixup_rollball_cc),
-+ SFP_QUIRK_F("Turris", "RTSFP-10", sfp_fixup_rollball),
-+ SFP_QUIRK_F("Turris", "RTSFP-10G", sfp_fixup_rollball),
-+ SFP_QUIRK_F("JESS-LINK", "P60000BBC001-1", sfp_fixup_rollball),
++ SFP_QUIRK_F("ETU", "ESP-T5-R", '\0', sfp_fixup_rollball_cc),
++ SFP_QUIRK_F("OEM", "SFP-10G-T", '\0', sfp_fixup_rollball_cc),
++ SFP_QUIRK_F("OEM", "RTSFP-10", '\0', sfp_fixup_rollball_cc),
++ SFP_QUIRK_F("OEM", "RTSFP-10G", '\0', sfp_fixup_rollball_cc),
++ SFP_QUIRK_F("OEM", "TNBYV02-C0X-C3", '\0', sfp_fixup_rollball_cc),
++ SFP_QUIRK_F("Turris", "RTSFP-10", '\0', sfp_fixup_rollball),
++ SFP_QUIRK_F("Turris", "RTSFP-10G", '\0', sfp_fixup_rollball),
++ SFP_QUIRK_F("JESS-LINK", "P60000BBC001-1", '\0', sfp_fixup_rollball),
+};
+
+static size_t sfp_strlen(const char *str, size_t maxlen)
@@ -805,14 +814,16 @@
+{
+ const struct sfp_quirk *q;
+ unsigned int i;
-+ size_t vs, ps;
++ size_t vs, ps, rs;
+
+ vs = sfp_strlen(id->base.vendor_name, ARRAY_SIZE(id->base.vendor_name));
+ ps = sfp_strlen(id->base.vendor_pn, ARRAY_SIZE(id->base.vendor_pn));
++ rs = sfp_strlen(id->base.vendor_rev, ARRAY_SIZE(id->base.vendor_rev));
+
+ for (i = 0, q = sfp_quirks; i < ARRAY_SIZE(sfp_quirks); i++, q++)
+ if (sfp_match(q->vendor, id->base.vendor_name, vs) &&
-+ sfp_match(q->part, id->base.vendor_pn, ps))
++ sfp_match(q->part, id->base.vendor_pn, ps) &&
++ sfp_match(q->revision, id->base.vendor_rev, rs))
+ return q;
+
+ return NULL;
@@ -967,6 +978,65 @@
return err;
}
+@@ -1755,17 +1783,29 @@ static int sfp_sm_probe_for_phy(struct sfp *sfp)
+ static int sfp_module_parse_power(struct sfp *sfp)
+ {
+ u32 power_mW = 1000;
++ bool supports_a2;
+
+- if (sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_POWER_DECL))
++ if (sfp->id.ext.sff8472_compliance >= SFP_SFF8472_COMPLIANCE_REV10_2 &&
++ sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_POWER_DECL))
+ power_mW = 1500;
+- if (sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_HIGH_POWER_LEVEL))
++ /* Added in Rev 11.9, but there is no compliance code for this */
++ if (sfp->id.ext.sff8472_compliance >= SFP_SFF8472_COMPLIANCE_REV11_4 &&
++ sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_HIGH_POWER_LEVEL))
+ power_mW = 2000;
+
++ /* Power level 1 modules (max. 1W) are always supported. */
++ if (power_mW <= 1000) {
++ sfp->module_power_mW = power_mW;
++ return 0;
++ }
++
++ supports_a2 = sfp->id.ext.sff8472_compliance !=
++ SFP_SFF8472_COMPLIANCE_NONE ||
++ sfp->id.ext.diagmon & SFP_DIAGMON_DDM;
++
+ if (power_mW > sfp->max_power_mW) {
+ /* Module power specification exceeds the allowed maximum. */
+- if (sfp->id.ext.sff8472_compliance ==
+- SFP_SFF8472_COMPLIANCE_NONE &&
+- !(sfp->id.ext.diagmon & SFP_DIAGMON_DDM)) {
++ if (!supports_a2) {
+ /* The module appears not to implement bus address
+ * 0xa2, so assume that the module powers up in the
+ * indicated mode.
+@@ -1782,13 +1822,21 @@ static int sfp_module_parse_power(struct sfp *sfp)
+ }
+ }
+
++ if (!supports_a2) {
++ /* The module power level is below the host maximum and the
++ * module appears not to implement bus address 0xa2, so assume
++ * that the module powers up in the indicated mode.
++ */
++ return 0;
++ }
++
+ /* If the module requires a higher power mode, but also requires
+ * an address change sequence, warn the user that the module may
+ * not be functional.
+ */
+- if (sfp->id.ext.diagmon & SFP_DIAGMON_ADDRMODE && power_mW > 1000) {
++ if (sfp->id.ext.diagmon & SFP_DIAGMON_ADDRMODE) {
+ dev_warn(sfp->dev,
+- "Address Change Sequence not supported but module requies %u.%uW, module may not be functional\n",
++ "Address Change Sequence not supported but module requires %u.%uW, module may not be functional\n",
+ power_mW / 1000, (power_mW / 100) % 10);
+ return 0;
+ }
@@ -1819,11 +1984,33 @@ static int sfp_sm_mod_probe(struct sfp *
if (ret < 0)
return ret;
@@ -1072,13 +1142,14 @@
--- a/drivers/net/phy/sfp.h
+++ b/drivers/net/phy/sfp.h
-@@ -6,6 +6,13 @@
+@@ -6,6 +6,14 @@
struct sfp;
+struct sfp_quirk {
+ const char *vendor;
+ const char *part;
++ const char *revision;
+ void (*modes)(const struct sfp_eeprom_id *id, unsigned long *modes);
+ void (*fixup)(struct sfp *sfp);
+};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/757-net-phy-add-phylink-pcs-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/757-net-phy-add-phylink-pcs-support.patch
index 83da92d..99e4141 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/757-net-phy-add-phylink-pcs-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/757-net-phy-add-phylink-pcs-support.patch
@@ -517,6 +517,15 @@
val = phylink_mii_emul_read(reg, &state);
}
break;
+@@ -2010,7 +2010,7 @@ static int phylink_sfp_config(struct phylink *pl, u8 mode,
+
+ if (changed && !test_bit(PHYLINK_DISABLE_STOPPED,
+ &pl->phylink_disable_state))
+- phylink_mac_config(pl, &pl->link_config);
++ phylink_mac_initial_config(pl, false);
+
+ return ret;
+ }
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index 8229f56..ba0f09d 100644
--- a/include/linux/phylink.h