[rdkb][common][bsp][Refactor and sync kernel from openwrt]
[Description]
bb73e7c [kernel][mt7981/mt7986/mt7988][spi][spi-calibration: Fix caldata wrongly freed]
80cb85d [kernel][common][eth][Update MDI Reversal feature for the Aquantia PHY driver]
37e50ea [kernel][common][eth][Update Airoha EN8801SC 1G PHY driver to v1.1.7 Generic]
f2af383 [openwrt][mt7988][tool][Update smp-mt76.sh 4-RSS scenario]
da7446a [kernel][common][hnat][Fix the issue of mistakenly deleting entries in foe_clear_entry]
e456a0b [kernel][mt7988][bsp][Rename MT7988C DTS to the MT7988D]
8d7521e [kernel][common][eth][Update firmware download feature for the Aquantia PHY driver]
f340eb8 [kernel][mt7988][eth][Refactor PCS programming sequence for the USXGMII]
9f09b66 [openwrt][mt7988][eth][Update Flowblock WED patch]
2732763 [kernel][mt7988][eth][phy: mediatek-2p5ge: Fix LED0/LED1 polarity]
3e8aa56 [openwrt][mt7988][eth][Add Ethernet RSS full support for Jaguar]
[Release-log]
Change-Id: Id277d48f13627d9d2165367218cc5083df430bae
diff --git a/recipes-devtools/smp/files/smp-mt76.sh b/recipes-devtools/smp/files/smp-mt76.sh
index cc5b46b..83d7799 100644
--- a/recipes-devtools/smp/files/smp-mt76.sh
+++ b/recipes-devtools/smp/files/smp-mt76.sh
@@ -96,9 +96,12 @@
DEFAULT_RPS=0
#Physical IRQ# setting
- eth0_irq=229
- eth1_irq=230
- eth2_irq=231
+ #Ethernet RSS feature enables 4 Rx rings
+ eth_irq_rx0=221
+ eth_irq_rx1=222
+ eth_irq_rx2=223
+ eth_irq_rx3=224
+ eth_irq_tx=229
wifi1_irq_pcie0=524288
wifi1_irq_pcie1=134742016
wifi2_irq_pcie0=
@@ -132,10 +135,10 @@
# CPU#_AFFINITY="add binding irq number here"
# CPU#_RPS="add binding interface name here"
if [ "$num_of_wifi" = "0" ]; then
- CPU0_AFFINITY="$eth0_irq"
- CPU1_AFFINITY="$eth1_irq"
- CPU2_AFFINITY="$eth2_irq"
- CPU3_AFFINITY=""
+ CPU0_AFFINITY="$eth_irq_rx0 $eth_irq_tx"
+ CPU1_AFFINITY="$eth_irq_rx1"
+ CPU2_AFFINITY="$eth_irq_rx2"
+ CPU3_AFFINITY="$eth_irq_rx3"
CPU0_RPS="$RPS_IF_LIST"
CPU1_RPS="$RPS_IF_LIST"
@@ -145,8 +148,8 @@
#we bound all wifi card to cpu0 and bound eth to cpu
CPU0_AFFINITY=""
CPU1_AFFINITY=""
- CPU2_AFFINITY="$eth1_irq"
- CPU3_AFFINITY="$eth0_irq $eth2_irq"
+ CPU2_AFFINITY="$eth_irq_rx0 $eth_irq_rx1 $eth_irq_tx"
+ CPU3_AFFINITY="$eth_irq_rx2 $eth_irq_rx3"
CPU0_RPS="$WIFI_IF_LIST"
CPU1_RPS="$WIFI_IF_LIST"
@@ -165,8 +168,8 @@
DEFAULT_RPS=0
#Physical IRQ# setting
- eth0_irq=229
- eth1_irq=230
+ eth_irq_rx=221
+ eth_irq_tx=229
wifi1_irq=
wifi2_irq=
wifi3_irq=
@@ -215,8 +218,8 @@
# CPU#_AFFINITY="add binding irq number here"
# CPU#_RPS="add binding interface name here"
if [ "$num_of_wifi" = "0" ]; then
- CPU0_AFFINITY="$eth0_irq"
- CPU1_AFFINITY="$eth1_irq"
+ CPU0_AFFINITY="$eth_irq_rx"
+ CPU1_AFFINITY="$eth_irq_tx"
CPU2_AFFINITY=""
CPU3_AFFINITY=""
@@ -226,8 +229,8 @@
CPU3_RPS="$RPS_IF_LIST"
else
#we bound all wifi card to cpu1 and bound eth to cpu0
- CPU0_AFFINITY="$eth0_irq"
- CPU1_AFFINITY="$eth1_irq"
+ CPU0_AFFINITY="$eth_irq_rx"
+ CPU1_AFFINITY="$eth_irq_tx"
CPU2_AFFINITY="$wifi2_irq $wifi3_irq"
CPU3_AFFINITY="$wifi1_irq"
@@ -248,8 +251,8 @@
DEFAULT_RPS=0
#Physical IRQ# setting
- eth0_irq=229
- eth1_irq=230
+ eth_irq_rx=221
+ eth_irq_tx=229
wifi1_irq=
wifi2_irq=
wifi3_irq=
@@ -261,15 +264,15 @@
# CPU#_AFFINITY="add binding irq number here"
# CPU#_RPS="add binding interface name here"
if [ "$num_of_wifi" = "0" ]; then
- CPU0_AFFINITY="$eth0_irq"
- CPU1_AFFINITY="$eth1_irq"
+ CPU0_AFFINITY="$eth_irq_rx"
+ CPU1_AFFINITY="$eth_irq_tx"
CPU0_RPS="$RPS_IF_LIST"
CPU1_RPS="$RPS_IF_LIST"
else
#we bound all wifi card to cpu0 and bound eth to cpu1
CPU0_AFFINITY="$wifi1_irq $wifi2_irq $wifi3_irq"
- CPU1_AFFINITY="$eth0_irq $eth1_irq"
+ CPU1_AFFINITY="$eth_irq_rx $eth_irq_tx"
CPU0_RPS="$RPS_IF_LIST"
CPU1_RPS="$RPS_IF_LIST"
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986a.dtsi b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986a.dtsi
index f1ccf54..820e8bb 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986a.dtsi
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986a.dtsi
@@ -475,10 +475,14 @@
eth: ethernet@15100000 {
compatible = "mediatek,mt7986-eth";
reg = <0 0x15100000 0 0x80000>;
- interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
clocks = <ðsys CK_ETH_FE_EN>,
<ðsys CK_ETH_GP2_EN>,
<ðsys CK_ETH_GP1_EN>,
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986b.dtsi b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986b.dtsi
index 666fddb..96c68a5 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986b.dtsi
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986b.dtsi
@@ -377,10 +377,14 @@
eth: ethernet@15100000 {
compatible = "mediatek,mt7986-eth";
reg = <0 0x15100000 0 0x80000>;
- interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
clocks = <ðsys CK_ETH_FE_EN>,
<ðsys CK_ETH_GP2_EN>,
<ðsys CK_ETH_GP1_EN>,
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981.dtsi b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981.dtsi
index e99ef83..6b47ee6 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981.dtsi
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981.dtsi
@@ -390,10 +390,14 @@
eth: ethernet@15100000 {
compatible = "mediatek,mt7981-eth";
reg = <0 0x15100000 0 0x80000>;
- interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
clocks = <ðsys CK_ETH_FE_EN>,
<ðsys CK_ETH_GP2_EN>,
<ðsys CK_ETH_GP1_EN>,
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
index f1ccf54..820e8bb 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
@@ -475,10 +475,14 @@
eth: ethernet@15100000 {
compatible = "mediatek,mt7986-eth";
reg = <0 0x15100000 0 0x80000>;
- interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
clocks = <ðsys CK_ETH_FE_EN>,
<ðsys CK_ETH_GP2_EN>,
<ðsys CK_ETH_GP1_EN>,
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986b.dtsi b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
index 666fddb..96c68a5 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
@@ -377,10 +377,14 @@
eth: ethernet@15100000 {
compatible = "mediatek,mt7986-eth";
reg = <0 0x15100000 0 0x80000>;
- interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
clocks = <ðsys CK_ETH_FE_EN>,
<ðsys CK_ETH_GP2_EN>,
<ðsys CK_ETH_GP1_EN>,
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 28cb8eb..98dc4df 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
@@ -774,7 +774,11 @@
compatible = "mediatek,mt7988-eth";
reg = <0 0x15100000 0 0x80000>,
<0 0x15400000 0 0x380000>;
- interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+ interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
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
index 3dbbae8..9e2e9a9 100644
--- 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
@@ -426,6 +426,7 @@
reset-gpios = <&pio 72 1>;
reset-assert-us = <100000>;
reset-deassert-us = <221000>;
+ mdi-reversal = /bits/ 16 <1>;
};
phy1: ethernet-phy@8 {
@@ -434,6 +435,7 @@
reset-gpios = <&pio 71 1>;
reset-assert-us = <100000>;
reset-deassert-us = <221000>;
+ mdi-reversal = /bits/ 16 <1>;
};
switch@0 {
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-emmc.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-emmc.dts
index 1011cb3..201f9ee 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-emmc.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-emmc.dts
@@ -237,6 +237,7 @@
reset-gpios = <&pio 72 1>;
reset-assert-us = <100000>;
reset-deassert-us = <221000>;
+ mdi-reversal = /bits/ 16 <1>;
};
phy1: ethernet-phy@8 {
@@ -245,6 +246,7 @@
reset-gpios = <&pio 71 1>;
reset-assert-us = <100000>;
reset-deassert-us = <221000>;
+ mdi-reversal = /bits/ 16 <1>;
};
switch@0 {
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-sd.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-sd.dts
index 5548023..d664a46 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-sd.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-sd.dts
@@ -228,6 +228,7 @@
reset-gpios = <&pio 72 1>;
reset-assert-us = <100000>;
reset-deassert-us = <221000>;
+ mdi-reversal = /bits/ 16 <1>;
};
phy1: ethernet-phy@8 {
@@ -236,6 +237,7 @@
reset-gpios = <&pio 71 1>;
reset-assert-us = <100000>;
reset-deassert-us = <221000>;
+ mdi-reversal = /bits/ 16 <1>;
};
switch@0 {
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 eb076ed..c7e83fd 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
@@ -263,6 +263,7 @@
reset-gpios = <&pio 72 1>;
reset-assert-us = <100000>;
reset-deassert-us = <221000>;
+ mdi-reversal = /bits/ 16 <1>;
};
phy1: ethernet-phy@8 {
@@ -271,6 +272,7 @@
reset-gpios = <&pio 71 1>;
reset-assert-us = <100000>;
reset-deassert-us = <221000>;
+ mdi-reversal = /bits/ 16 <1>;
};
switch@0 {
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nand.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nand.dts
index d305570..cf117ca 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nand.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nand.dts
@@ -421,6 +421,7 @@
reset-gpios = <&pio 72 1>;
reset-assert-us = <100000>;
reset-deassert-us = <221000>;
+ mdi-reversal = /bits/ 16 <1>;
};
phy1: ethernet-phy@8 {
@@ -429,6 +430,7 @@
reset-gpios = <&pio 71 1>;
reset-assert-us = <100000>;
reset-deassert-us = <221000>;
+ mdi-reversal = /bits/ 16 <1>;
};
switch@0 {
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nor.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nor.dts
index 62cb90e..a9fc3c5 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nor.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nor.dts
@@ -255,6 +255,7 @@
reset-gpios = <&pio 72 1>;
reset-assert-us = <100000>;
reset-deassert-us = <221000>;
+ mdi-reversal = /bits/ 16 <1>;
};
phy1: ethernet-phy@8 {
@@ -263,6 +264,7 @@
reset-gpios = <&pio 71 1>;
reset-assert-us = <100000>;
reset-deassert-us = <221000>;
+ mdi-reversal = /bits/ 16 <1>;
};
switch@0 {
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-i2p5g-spim-nand.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-i2p5g-spim-nand.dts
index 3f88986..2a24f7d 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-i2p5g-spim-nand.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-i2p5g-spim-nand.dts
@@ -253,7 +253,7 @@
#address-cells = <1>;
#size-cells = <0>;
phy0: ethernet-phy@0 {
- pinctrl-names = "default";
+ pinctrl-names = "i2p5gbe-led";
pinctrl-0 = <&i2p5gbe_led0_pins>;
reg = <15>;
compatible = "ethernet-phy-ieee802.3-c45";
@@ -263,6 +263,10 @@
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>;
+ mdi-reversal = /bits/ 16 <1>;
};
switch@0 {
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-gsw-10g-spim-nand-4pcie.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-gsw-10g-spim-nand-4pcie.dts
index 5969966..fde3572 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-gsw-10g-spim-nand-4pcie.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-gsw-10g-spim-nand-4pcie.dts
@@ -359,6 +359,7 @@
reset-gpios = <&pio 72 1>;
reset-assert-us = <100000>;
reset-deassert-us = <221000>;
+ mdi-reversal = /bits/ 16 <1>;
};
phy1: ethernet-phy@8 {
@@ -367,6 +368,7 @@
reset-gpios = <&pio 71 1>;
reset-assert-us = <100000>;
reset-deassert-us = <221000>;
+ mdi-reversal = /bits/ 16 <1>;
};
};
};
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 d1371c4..0941b06 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
@@ -392,6 +392,7 @@
reset-gpios = <&pio 72 1>;
reset-assert-us = <100000>;
reset-deassert-us = <221000>;
+ mdi-reversal = /bits/ 16 <1>;
};
phy1: ethernet-phy@8 {
@@ -400,6 +401,7 @@
reset-gpios = <&pio 71 1>;
reset-assert-us = <100000>;
reset-deassert-us = <221000>;
+ mdi-reversal = /bits/ 16 <1>;
};
};
};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988c-dsa-10g-emmc.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-emmc.dts
similarity index 97%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988c-dsa-10g-emmc.dts
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-emmc.dts
index 0e58ac7..ba29680 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988c-dsa-10g-emmc.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-emmc.dts
@@ -8,8 +8,8 @@
#include "mt7988.dtsi"
/ {
- model = "MediaTek MT7988C DSA 10G eMMC RFB";
- compatible = "mediatek,mt7988c-dsa-10g-emmc",
+ model = "MediaTek MT7988D DSA 10G eMMC RFB";
+ compatible = "mediatek,mt7988d-dsa-10g-emmc",
/* Reserve this for DVFS if creating new dts */
"mediatek,mt7988";
chosen {
@@ -239,7 +239,7 @@
clock-frequency = <10500000>;
phy0: ethernet-phy@0 {
- pinctrl-names = "default";
+ pinctrl-names = "i2p5gbe-led";
pinctrl-0 = <&i2p5gbe_led0_pins>;
reg = <15>;
compatible = "ethernet-phy-ieee802.3-c45";
@@ -252,6 +252,7 @@
reset-gpios = <&pio 3 1>;
reset-assert-us = <100000>;
reset-deassert-us = <221000>;
+ mdi-reversal = /bits/ 16 <1>;
};
switch@0 {
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988c-dsa-10g-sd.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-sd.dts
similarity index 97%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988c-dsa-10g-sd.dts
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-sd.dts
index d0b4ec3..133da0c 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988c-dsa-10g-sd.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-sd.dts
@@ -8,8 +8,8 @@
#include "mt7988.dtsi"
/ {
- model = "MediaTek MT7988C DSA 10G SD RFB";
- compatible = "mediatek,mt7988c-dsa-10g-sd",
+ model = "MediaTek MT7988D DSA 10G SD RFB";
+ compatible = "mediatek,mt7988d-dsa-10g-sd",
/* Reserve this for DVFS if creating new dts */
"mediatek,mt7988";
chosen {
@@ -230,7 +230,7 @@
clock-frequency = <10500000>;
phy0: ethernet-phy@0 {
- pinctrl-names = "default";
+ pinctrl-names = "i2p5gbe-led";
pinctrl-0 = <&i2p5gbe_led0_pins>;
reg = <15>;
compatible = "ethernet-phy-ieee802.3-c45";
@@ -243,6 +243,7 @@
reset-gpios = <&pio 3 1>;
reset-assert-us = <100000>;
reset-deassert-us = <221000>;
+ mdi-reversal = /bits/ 16 <1>;
};
switch@0 {
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/mt7988d-dsa-10g-snfi-nand.dts
similarity index 97%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988c-dsa-10g-snfi-nand.dts
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-snfi-nand.dts
index 6cadcfc..7721c07 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/mt7988d-dsa-10g-snfi-nand.dts
@@ -8,8 +8,8 @@
#include "mt7988.dtsi"
/ {
- model = "MediaTek MT7988C DSA 10G SNFI-NAND RFB";
- compatible = "mediatek,mt7988c-dsa-10g-snfi-snand",
+ model = "MediaTek MT7988D DSA 10G SNFI-NAND RFB";
+ compatible = "mediatek,mt7988d-dsa-10g-snfi-snand",
/* Reserve this for DVFS if creating new dts */
"mediatek,mt7988";
@@ -265,7 +265,7 @@
clock-frequency = <10500000>;
phy0: ethernet-phy@0 {
- pinctrl-names = "default";
+ pinctrl-names = "i2p5gbe-led";
pinctrl-0 = <&i2p5gbe_led0_pins>;
reg = <15>;
compatible = "ethernet-phy-ieee802.3-c45";
@@ -278,6 +278,7 @@
reset-gpios = <&pio 3 1>;
reset-assert-us = <100000>;
reset-deassert-us = <221000>;
+ mdi-reversal = /bits/ 16 <1>;
};
switch@0 {
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988c-dsa-10g-spim-nand.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nand.dts
similarity index 98%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988c-dsa-10g-spim-nand.dts
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nand.dts
index 564debe..06b5702 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988c-dsa-10g-spim-nand.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nand.dts
@@ -8,8 +8,8 @@
#include "mt7988.dtsi"
/ {
- model = "MediaTek MT7988C DSA 10G SPIM-NAND RFB";
- compatible = "mediatek,mt7988c-dsa-10g-spim-snand",
+ model = "MediaTek MT7988D DSA 10G SPIM-NAND RFB";
+ compatible = "mediatek,mt7988d-dsa-10g-spim-snand",
/* Reserve this for DVFS if creating new dts */
"mediatek,mt7988";
@@ -405,7 +405,7 @@
clock-frequency = <10500000>;
phy0: ethernet-phy@0 {
- pinctrl-names = "default";
+ pinctrl-names = "i2p5gbe-led";
pinctrl-0 = <&i2p5gbe_led0_pins>;
reg = <15>;
compatible = "ethernet-phy-ieee802.3-c45";
@@ -418,6 +418,7 @@
reset-gpios = <&pio 3 1>;
reset-assert-us = <100000>;
reset-deassert-us = <221000>;
+ mdi-reversal = /bits/ 16 <1>;
};
switch@0 {
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988c-dsa-10g-spim-nor.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nor.dts
similarity index 97%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988c-dsa-10g-spim-nor.dts
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nor.dts
index 1c98664..61cdf7b 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988c-dsa-10g-spim-nor.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nor.dts
@@ -8,8 +8,8 @@
#include "mt7988.dtsi"
/ {
- model = "MediaTek MT7988C DSA 10G SPIM-NOR RFB";
- compatible = "mediatek,mt7988c-dsa-10g-spim-nor",
+ model = "MediaTek MT7988D DSA 10G SPIM-NOR RFB";
+ compatible = "mediatek,mt7988d-dsa-10g-spim-nor",
/* Reserve this for DVFS if creating new dts */
"mediatek,mt7988";
@@ -257,7 +257,7 @@
clock-frequency = <10500000>;
phy0: ethernet-phy@0 {
- pinctrl-names = "default";
+ pinctrl-names = "i2p5gbe-led";
pinctrl-0 = <&i2p5gbe_led0_pins>;
reg = <15>;
compatible = "ethernet-phy-ieee802.3-c45";
@@ -270,6 +270,7 @@
reset-gpios = <&pio 3 1>;
reset-assert-us = <100000>;
reset-deassert-us = <221000>;
+ mdi-reversal = /bits/ 16 <1>;
};
switch@0 {
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988c-dsa-e2p5g-spim-nand.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-e2p5g-spim-nand.dts
similarity index 98%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988c-dsa-e2p5g-spim-nand.dts
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-e2p5g-spim-nand.dts
index e6a0115..5369716 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988c-dsa-e2p5g-spim-nand.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-e2p5g-spim-nand.dts
@@ -8,8 +8,8 @@
#include "mt7988.dtsi"
/ {
- model = "MediaTek MT7988C DSA external-2.5G SPIM-NAND RFB";
- compatible = "mediatek,mt7988c-dsa-e2p5g-spim-snand",
+ model = "MediaTek MT7988D DSA external-2.5G SPIM-NAND RFB";
+ compatible = "mediatek,mt7988d-dsa-e2p5g-spim-snand",
/* Reserve this for DVFS if creating new dts */
"mediatek,mt7988";
@@ -335,7 +335,7 @@
#size-cells = <0>;
phy0: ethernet-phy@0 {
- pinctrl-names = "default";
+ pinctrl-names = "i2p5gbe-led";
pinctrl-0 = <&i2p5gbe_led0_pins>;
reg = <15>;
compatible = "ethernet-phy-ieee802.3-c45";
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988c-gsw-10g-sfp-spim-nand.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-gsw-10g-sfp-spim-nand.dts
similarity index 98%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988c-gsw-10g-sfp-spim-nand.dts
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-gsw-10g-sfp-spim-nand.dts
index 2404586..c94247d 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988c-gsw-10g-sfp-spim-nand.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-gsw-10g-sfp-spim-nand.dts
@@ -8,8 +8,8 @@
#include "mt7988.dtsi"
/ {
- model = "MediaTek MT7988C GSW 10G SFP SPIM-NAND RFB";
- compatible = "mediatek,mt7988c-gsw-10g-sfp-spim-snand",
+ model = "MediaTek MT7988D GSW 10G SFP SPIM-NAND RFB";
+ compatible = "mediatek,mt7988d-gsw-10g-sfp-spim-snand",
/* Reserve this for DVFS if creating new dts */
"mediatek,mt7988";
@@ -350,7 +350,7 @@
#size-cells = <0>;
phy0: ethernet-phy@0 {
- pinctrl-names = "default";
+ pinctrl-names = "i2p5gbe-led";
pinctrl-0 = <&i2p5gbe_led0_pins>;
reg = <15>;
compatible = "ethernet-phy-ieee802.3-c45";
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988c-gsw-10g-spim-nand.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-gsw-10g-spim-nand.dts
similarity index 97%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988c-gsw-10g-spim-nand.dts
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-gsw-10g-spim-nand.dts
index 3446b6b..a86e77e 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988c-gsw-10g-spim-nand.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-gsw-10g-spim-nand.dts
@@ -9,8 +9,8 @@
#include "mt7988.dtsi"
/ {
- model = "MediaTek MT7988C GSW 10G SPIM-NAND RFB";
- compatible = "mediatek,mt7988c-gsw-10g-spim-snand",
+ model = "MediaTek MT7988D GSW 10G SPIM-NAND RFB";
+ compatible = "mediatek,mt7988d-gsw-10g-spim-snand",
/* Reserve this for DVFS if creating new dts */
"mediatek,mt7988";
@@ -381,7 +381,7 @@
clock-frequency = <10500000>;
phy0: ethernet-phy@0 {
- pinctrl-names = "default";
+ pinctrl-names = "i2p5gbe-led";
pinctrl-0 = <&i2p5gbe_led0_pins>;
reg = <15>;
compatible = "ethernet-phy-ieee802.3-c45";
@@ -394,6 +394,7 @@
reset-gpios = <&pio 3 1>;
reset-assert-us = <100000>;
reset-deassert-us = <221000>;
+ mdi-reversal = /bits/ 16 <1>;
};
};
};
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 6f17fa5..02f1d34 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
@@ -3067,10 +3067,12 @@
mtk_w32(eth, val, MTK_PDMA_RSS_GLO_CFG);
/* Set perRSS GRP INT */
- mtk_w32(eth, MTK_RX_DONE_INT(MTK_RSS_RING1), MTK_PDMA_INT_GRP3);
+ mtk_w32(eth, MTK_RX_DONE_INT(MTK_RSS_RING(1)), MTK_PDMA_INT_GRP1);
+ mtk_w32(eth, MTK_RX_DONE_INT(MTK_RSS_RING(2)), MTK_PDMA_INT_GRP2);
+ mtk_w32(eth, MTK_RX_DONE_INT(MTK_RSS_RING(3)), MTK_PDMA_INT_GRP3);
/* Set GRP INT */
- mtk_w32(eth, 0x21021030, MTK_FE_INT_GRP);
+ mtk_w32(eth, 0x210FFFF2, MTK_FE_INT_GRP);
/* Enable RSS delay interrupt */
mtk_w32(eth, 0x8f0f8f0f, MTK_PDMA_RSS_DELAY_INT);
@@ -3363,7 +3365,7 @@
mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
mtk_rx_irq_disable(eth, MTK_RX_DONE_INT(0));
- mtk_handle_irq_rx(eth->irq[2], ð->rx_napi[0]);
+ mtk_handle_irq_rx(eth->irq_fe[2], ð->rx_napi[0]);
mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
mtk_rx_irq_enable(eth, MTK_RX_DONE_INT(0));
}
@@ -3784,11 +3786,9 @@
mtk_rx_irq_disable(eth, ~0);
/* FE int grouping */
- mtk_w32(eth, MTK_TX_DONE_INT, reg_map->pdma.int_grp);
- mtk_w32(eth, MTK_RX_DONE_INT(0), reg_map->pdma.int_grp2);
mtk_w32(eth, MTK_TX_DONE_INT, reg_map->qdma.int_grp);
mtk_w32(eth, MTK_RX_DONE_INT(0), reg_map->qdma.int_grp2);
- mtk_w32(eth, 0x21021003, MTK_FE_INT_GRP);
+ mtk_w32(eth, 0x210FFFF2, MTK_FE_INT_GRP);
mtk_w32(eth, MTK_FE_INT_TSO_FAIL |
MTK_FE_INT_TSO_ILLEGAL | MTK_FE_INT_TSO_ALIGN |
MTK_FE_INT_RFIFO_OV | MTK_FE_INT_RFIFO_UF, MTK_FE_INT_ENABLE);
@@ -4553,7 +4553,7 @@
eth->netdev[id]->features |= eth->soc->hw_features;
eth->netdev[id]->ethtool_ops = &mtk_ethtool_ops;
- eth->netdev[id]->irq = eth->irq[0];
+ eth->netdev[id]->irq = eth->irq_fe[0];
eth->netdev[id]->dev.of_node = np;
return 0;
@@ -4710,12 +4710,17 @@
}
}
- for (i = 0; i < MTK_MAX_IRQ_NUM; i++) {
+ for (i = 0; i < MTK_PDMA_IRQ_NUM; i++)
+ eth->irq_pdma[i] = platform_get_irq(pdev, i);
+
+ for (i = 0; i < MTK_FE_IRQ_NUM; i++) {
if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT) && i > 0)
- eth->irq[i] = eth->irq[0];
+ eth->irq_fe[i] = eth->irq_fe[0];
else
- eth->irq[i] = platform_get_irq(pdev, i);
- if (eth->irq[i] < 0) {
+ eth->irq_fe[i] =
+ platform_get_irq(pdev, i + MTK_PDMA_IRQ_NUM);
+
+ if (eth->irq_fe[i] < 0) {
dev_err(&pdev->dev, "no IRQ%d resource found\n", i);
return -ENXIO;
}
@@ -4765,37 +4770,35 @@
goto err_free_dev;
if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT)) {
- err = devm_request_irq(eth->dev, eth->irq[0],
+ err = devm_request_irq(eth->dev, eth->irq_fe[0],
mtk_handle_irq, 0,
dev_name(eth->dev), eth);
} else {
- err = devm_request_irq(eth->dev, eth->irq[1],
+ err = devm_request_irq(eth->dev, eth->irq_fe[1],
mtk_handle_irq_tx, 0,
dev_name(eth->dev), eth);
if (err)
goto err_free_dev;
- err = devm_request_irq(eth->dev, eth->irq[2],
+ err = devm_request_irq(eth->dev, eth->irq_fe[2],
+ mtk_handle_fe_irq, 0,
+ dev_name(eth->dev), eth);
+ if (err)
+ goto err_free_dev;
+
+ err = devm_request_irq(eth->dev, eth->irq_pdma[0],
mtk_handle_irq_rx, 0,
dev_name(eth->dev), ð->rx_napi[0]);
if (err)
goto err_free_dev;
- if (MTK_MAX_IRQ_NUM > 3) {
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSS)) {
- for (i = 1; i < MTK_RX_NAPI_NUM; i++) {
- err = devm_request_irq(eth->dev,
- eth->irq[2 + i],
- mtk_handle_irq_rx, 0,
- dev_name(eth->dev),
- ð->rx_napi[i]);
- if (err)
- goto err_free_dev;
- }
- } else {
- err = devm_request_irq(eth->dev, eth->irq[3],
- mtk_handle_fe_irq, 0,
- dev_name(eth->dev), eth);
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSS)) {
+ for (i = 1; i < MTK_RX_NAPI_NUM; i++) {
+ err = devm_request_irq(eth->dev,
+ eth->irq_pdma[i],
+ mtk_handle_irq_rx, 0,
+ dev_name(eth->dev),
+ ð->rx_napi[i]);
if (err)
goto err_free_dev;
}
@@ -4823,7 +4826,7 @@
} else
netif_info(eth, probe, eth->netdev[i],
"mediatek frame engine at 0x%08lx, irq %d\n",
- eth->netdev[i]->base_addr, eth->irq[0]);
+ eth->netdev[i]->base_addr, eth->irq_fe[0]);
}
/* we run 2 devices on the same DMA ring so we need a dummy device
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 2082ec6..7465188 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
@@ -86,6 +86,9 @@
#define MTK_FE_INT_RFIFO_UF BIT(19)
#define MTK_GDM1_AF BIT(28)
#define MTK_GDM2_AF BIT(29)
+#define MTK_FE_IRQ_NUM (4)
+#define MTK_PDMA_IRQ_NUM (4)
+#define MTK_MAX_IRQ_NUM (MTK_FE_IRQ_NUM + MTK_PDMA_IRQ_NUM)
/* PDMA HW LRO Alter Flow Timer Register */
#define MTK_PDMA_LRO_ALT_REFRESH_TIMER 0x1c
@@ -254,14 +257,12 @@
/* PDMA RSS Control Registers */
#if defined(CONFIG_MEDIATEK_NETSYS_RX_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
#define MTK_PDMA_RSS_GLO_CFG (PDMA_BASE + 0x800)
-#define MTK_RX_NAPI_NUM (2)
-#define MTK_MAX_IRQ_NUM (4)
+#define MTK_RX_NAPI_NUM (4)
#else
#define MTK_PDMA_RSS_GLO_CFG 0x2800
#define MTK_RX_NAPI_NUM (1)
-#define MTK_MAX_IRQ_NUM (3)
#endif
-#define MTK_RSS_RING1 (1)
+#define MTK_RSS_RING(x) (x)
#define MTK_RSS_EN BIT(0)
#define MTK_RSS_CFG_REQ BIT(2)
#define MTK_RSS_IPV6_STATIC_HASH (0x7 << 8)
@@ -274,7 +275,7 @@
#define MTK_RSS_INDR_TABLE_DW5 (MTK_PDMA_RSS_GLO_CFG + 0x64)
#define MTK_RSS_INDR_TABLE_DW6 (MTK_PDMA_RSS_GLO_CFG + 0x68)
#define MTK_RSS_INDR_TABLE_DW7 (MTK_PDMA_RSS_GLO_CFG + 0x6C)
-#define MTK_RSS_INDR_TABLE_SIZE4 0x44444444
+#define MTK_RSS_INDR_TABLE_SIZE4 0x39393939
/* PDMA Global Configuration Register */
#define MTK_PDMA_GLO_CFG (PDMA_BASE + 0x204)
@@ -445,12 +446,13 @@
/* QDMA Interrupt Status Register */
#define MTK_QDMA_INT_STATUS (QDMA_BASE + 0x218)
#if defined(CONFIG_MEDIATEK_NETSYS_RX_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
-#define MTK_RX_DONE_INT(ring_no) \
+#define MTK_RX_DONE_INT(ring_no) \
(MTK_HAS_CAPS(eth->soc->caps, MTK_RSS) ? (BIT(24 + (ring_no))) : \
((ring_no) ? BIT(16 + (ring_no)) : BIT(14)))
#else
-#define MTK_RX_DONE_INT(ring_no) \
- ((ring_no)? BIT(24 + (ring_no)) : BIT(30))
+#define MTK_RX_DONE_INT(ring_no) \
+ (MTK_HAS_CAPS(eth->soc->caps, MTK_RSS) ? (BIT(16 + (ring_no))) : \
+ ((ring_no) ? BIT(24 + (ring_no)) : BIT(30)))
#endif
#define MTK_RX_DONE_INT3 BIT(19)
#define MTK_RX_DONE_INT2 BIT(18)
@@ -888,30 +890,36 @@
/* USXGMII subsystem config registers */
/* Register to control speed */
#define RG_PHY_TOP_SPEED_CTRL1 0x80C
-#define RG_USXGMII_RATE_UPDATE_MODE BIT(31)
-#define RG_MAC_CK_GATED BIT(29)
-#define RG_IF_FORCE_EN BIT(28)
-#define RG_RATE_ADAPT_MODE GENMASK(10, 8)
-#define RG_RATE_ADAPT_MODE_X1 0
-#define RG_RATE_ADAPT_MODE_X2 1
-#define RG_RATE_ADAPT_MODE_X4 2
-#define RG_RATE_ADAPT_MODE_X10 3
-#define RG_RATE_ADAPT_MODE_X100 4
-#define RG_RATE_ADAPT_MODE_X5 5
-#define RG_RATE_ADAPT_MODE_X50 6
-#define RG_XFI_RX_MODE GENMASK(6, 4)
-#define RG_XFI_RX_MODE_10G 0
-#define RG_XFI_RX_MODE_5G 1
-#define RG_XFI_TX_MODE GENMASK(2, 0)
-#define RG_XFI_TX_MODE_10G 0
-#define RG_XFI_TX_MODE_5G 1
+#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_RX_MODE_10G 0
+#define USXGMII_XFI_RX_MODE_5G 1
+#define USXGMII_XFI_TX_MODE GENMASK(2, 0)
+#define USXGMII_XFI_TX_MODE_10G 0
+#define USXGMII_XFI_TX_MODE_5G 1
/* 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)
-/* Register to control PCS AN */
+#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_SPEED_MASK GENMASK(11, 9)
#define USXGMII_LPA_SPEED_10 0
@@ -1767,7 +1775,8 @@
struct net_device dummy_dev;
struct net_device *netdev[MTK_MAX_DEVS];
struct mtk_mac *mac[MTK_MAX_DEVS];
- int irq[MTK_MAX_IRQ_NUM];
+ int irq_fe[MTK_FE_IRQ_NUM];
+ int irq_pdma[MTK_PDMA_IRQ_NUM];
u8 hwver;
u32 msg_enable;
unsigned long sysclk;
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 2e68d3d..95e5e3c 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
@@ -291,7 +291,8 @@
for (hash_index = 0; hash_index < hnat_priv->foe_etry_num; hash_index++) {
entry = hnat_priv->foe_table_cpu[i] + hash_index;
if (entry->bfib1.state == BIND &&
- entry->ipv4_hnapt.new_dip == ntohl(dip)) {
+ entry->ipv4_hnapt.new_dip == ntohl(dip) &&
+ IS_IPV4_HNAPT(entry)) {
*((u32 *)h_dest) = swab32(entry->ipv4_hnapt.dmac_hi);
*((u16 *)&h_dest[4]) =
swab16(entry->ipv4_hnapt.dmac_lo);
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 4841134..c2acab2 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
@@ -161,6 +161,7 @@
if (!mpcs->regmap_pextp)
return;
+ /* Setup operation mode */
regmap_update_bits(mpcs->regmap_pextp, 0x9024, GENMASK(31, 0),
0x00D9071C);
regmap_update_bits(mpcs->regmap_pextp, 0x2020, GENMASK(31, 0),
@@ -203,13 +204,17 @@
0x18190000);
regmap_update_bits(mpcs->regmap_pextp, 0x00F8, GENMASK(31, 0),
0x00FA32FA);
+ /* Force SGDT_OUT off and select PCS */
regmap_update_bits(mpcs->regmap_pextp, 0x00F4, GENMASK(31, 0),
0x80201F21);
+ /* Force GLB_CKDET_OUT */
regmap_update_bits(mpcs->regmap_pextp, 0x0030, GENMASK(31, 0),
0x00050C00);
+ /* Force AEQ on */
regmap_update_bits(mpcs->regmap_pextp, 0x0070, GENMASK(31, 0),
0x02002800);
ndelay(1020);
+ /* Setup DA default value */
regmap_update_bits(mpcs->regmap_pextp, 0x30B0, GENMASK(31, 0),
0x00000020);
regmap_update_bits(mpcs->regmap_pextp, 0x3028, GENMASK(31, 0),
@@ -234,15 +239,18 @@
0x00050000);
regmap_update_bits(mpcs->regmap_pextp, 0x90D0, GENMASK(31, 0),
0x00000007);
+ /* Release reset */
regmap_update_bits(mpcs->regmap_pextp, 0x0070, GENMASK(31, 0),
0x0200E800);
udelay(150);
+ /* Switch to P0 */
regmap_update_bits(mpcs->regmap_pextp, 0x0070, GENMASK(31, 0),
0x0200C111);
ndelay(1020);
regmap_update_bits(mpcs->regmap_pextp, 0x0070, GENMASK(31, 0),
0x0200C101);
udelay(15);
+ /* Switch to Gen2 */
regmap_update_bits(mpcs->regmap_pextp, 0x0070, GENMASK(31, 0),
0x0201C111);
ndelay(1020);
@@ -263,6 +271,7 @@
if (!mpcs->regmap_pextp)
return;
+ /* Setup operation mode */
regmap_update_bits(mpcs->regmap_pextp, 0x9024, GENMASK(31, 0),
0x00D9071C);
regmap_update_bits(mpcs->regmap_pextp, 0x2020, GENMASK(31, 0),
@@ -305,13 +314,17 @@
0x18190000);
regmap_update_bits(mpcs->regmap_pextp, 0x00F8, GENMASK(31, 0),
0x009C329C);
+ /* Force SGDT_OUT off and select PCS */
regmap_update_bits(mpcs->regmap_pextp, 0x00F4, GENMASK(31, 0),
0x80201F21);
+ /* Force GLB_CKDET_OUT */
regmap_update_bits(mpcs->regmap_pextp, 0x0030, GENMASK(31, 0),
0x00050C00);
+ /* Force AEQ on */
regmap_update_bits(mpcs->regmap_pextp, 0x0070, GENMASK(31, 0),
0x02002800);
ndelay(1020);
+ /* Setup DA default value */
regmap_update_bits(mpcs->regmap_pextp, 0x30B0, GENMASK(31, 0),
0x00000020);
regmap_update_bits(mpcs->regmap_pextp, 0x3028, GENMASK(31, 0),
@@ -334,15 +347,18 @@
0x00050000);
regmap_update_bits(mpcs->regmap_pextp, 0x90D0, GENMASK(31, 0),
0x00000005);
+ /* Release reset */
regmap_update_bits(mpcs->regmap_pextp, 0x0070, GENMASK(31, 0),
0x0200E800);
udelay(150);
+ /* Switch to P0 */
regmap_update_bits(mpcs->regmap_pextp, 0x0070, GENMASK(31, 0),
0x0200C111);
ndelay(1020);
regmap_update_bits(mpcs->regmap_pextp, 0x0070, GENMASK(31, 0),
0x0200C101);
udelay(15);
+ /* Switch to Gen2 */
regmap_update_bits(mpcs->regmap_pextp, 0x0070, GENMASK(31, 0),
0x0201C111);
ndelay(1020);
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 1bc4912..e6007f6 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
@@ -129,24 +129,12 @@
return mac_id;
}
-int mtk_usxgmii_setup_phya_an_10000(struct mtk_usxgmii_pcs *mpcs)
+void mtk_usxgmii_setup_phya_usxgmii(struct mtk_usxgmii_pcs *mpcs)
{
- if (!mpcs->regmap || !mpcs->regmap_pextp)
- return -EINVAL;
-
- regmap_update_bits(mpcs->regmap, 0x810, GENMASK(31, 0),
- 0x000FFE6D);
- regmap_update_bits(mpcs->regmap, 0x818, GENMASK(31, 0),
- 0x07B1EC7B);
- regmap_update_bits(mpcs->regmap, 0x80C, GENMASK(31, 0),
- 0x30000000);
- ndelay(1020);
- regmap_update_bits(mpcs->regmap, 0x80C, GENMASK(31, 0),
- 0x10000000);
- ndelay(1020);
- regmap_update_bits(mpcs->regmap, 0x80C, GENMASK(31, 0),
- 0x00000000);
+ if (!mpcs->regmap_pextp)
+ return;
+ /* Setup operation mode */
regmap_update_bits(mpcs->regmap_pextp, 0x9024, GENMASK(31, 0),
0x00C9071C);
regmap_update_bits(mpcs->regmap_pextp, 0x2020, GENMASK(31, 0),
@@ -189,13 +177,17 @@
0x18190000);
regmap_update_bits(mpcs->regmap_pextp, 0x00F8, GENMASK(31, 0),
0x01423342);
+ /* Force SGDT_OUT off and select PCS */
regmap_update_bits(mpcs->regmap_pextp, 0x00F4, GENMASK(31, 0),
0x80201F20);
+ /* Force GLB_CKDET_OUT */
regmap_update_bits(mpcs->regmap_pextp, 0x0030, GENMASK(31, 0),
0x00050C00);
+ /* Force AEQ on */
regmap_update_bits(mpcs->regmap_pextp, 0x0070, GENMASK(31, 0),
0x02002800);
ndelay(1020);
+ /* Setup DA default value */
regmap_update_bits(mpcs->regmap_pextp, 0x30B0, GENMASK(31, 0),
0x00000020);
regmap_update_bits(mpcs->regmap_pextp, 0x3028, GENMASK(31, 0),
@@ -222,15 +214,18 @@
0x00040000);
regmap_update_bits(mpcs->regmap_pextp, 0x90D0, GENMASK(31, 0),
0x00000001);
+ /* Release reset */
regmap_update_bits(mpcs->regmap_pextp, 0x0070, GENMASK(31, 0),
0x0200E800);
udelay(150);
+ /* Switch to P0 */
regmap_update_bits(mpcs->regmap_pextp, 0x0070, GENMASK(31, 0),
0x0200C111);
ndelay(1020);
regmap_update_bits(mpcs->regmap_pextp, 0x0070, GENMASK(31, 0),
0x0200C101);
udelay(15);
+ /* Switch to Gen3 */
regmap_update_bits(mpcs->regmap_pextp, 0x0070, GENMASK(31, 0),
0x0202C111);
ndelay(1020);
@@ -244,48 +239,14 @@
regmap_update_bits(mpcs->regmap_pextp, 0x3040, GENMASK(31, 0),
0x30000000);
udelay(400);
-
- return 0;
}
-int mtk_usxgmii_setup_phya_force_5000(struct mtk_usxgmii_pcs *mpcs)
+void mtk_usxgmii_setup_phya_5gbaser(struct mtk_usxgmii_pcs *mpcs)
{
- unsigned int val;
-
- if (!mpcs->regmap || !mpcs->regmap_pextp)
- return -EINVAL;
-
- /* Setup USXGMII speed */
- val = FIELD_PREP(RG_XFI_RX_MODE, RG_XFI_RX_MODE_5G) |
- FIELD_PREP(RG_XFI_TX_MODE, RG_XFI_TX_MODE_5G);
- regmap_write(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, val);
-
- /* Disable USXGMII AN mode */
- regmap_read(mpcs->regmap, RG_PCS_AN_CTRL0, &val);
- val &= ~USXGMII_AN_ENABLE;
- regmap_write(mpcs->regmap, RG_PCS_AN_CTRL0, val);
-
- /* Gated USXGMII */
- regmap_read(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, &val);
- val |= RG_MAC_CK_GATED;
- regmap_write(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, val);
-
- ndelay(1020);
-
- /* USXGMII force mode setting */
- regmap_read(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, &val);
- val |= RG_USXGMII_RATE_UPDATE_MODE;
- val |= RG_IF_FORCE_EN;
- val |= FIELD_PREP(RG_RATE_ADAPT_MODE, RG_RATE_ADAPT_MODE_X1);
- regmap_write(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, val);
-
- /* Un-gated USXGMII */
- regmap_read(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, &val);
- val &= ~RG_MAC_CK_GATED;
- regmap_write(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, val);
-
- ndelay(1020);
+ if (!mpcs->regmap_pextp)
+ return;
+ /* Setup operation mode */
regmap_update_bits(mpcs->regmap_pextp, 0x9024, GENMASK(31, 0),
0x00D9071C);
regmap_update_bits(mpcs->regmap_pextp, 0x2020, GENMASK(31, 0),
@@ -328,13 +289,17 @@
0x18000000);
regmap_update_bits(mpcs->regmap_pextp, 0x00F8, GENMASK(31, 0),
0x00A132A1);
+ /* Force SGDT_OUT off and select PCS */
regmap_update_bits(mpcs->regmap_pextp, 0x00F4, GENMASK(31, 0),
0x80201F20);
+ /* Force GLB_CKDET_OUT */
regmap_update_bits(mpcs->regmap_pextp, 0x0030, GENMASK(31, 0),
0x00050C00);
+ /* Force AEQ on */
regmap_update_bits(mpcs->regmap_pextp, 0x0070, GENMASK(31, 0),
0x02002800);
ndelay(1020);
+ /* Setup DA default value */
regmap_update_bits(mpcs->regmap_pextp, 0x30B0, GENMASK(31, 0),
0x00000020);
regmap_update_bits(mpcs->regmap_pextp, 0x3028, GENMASK(31, 0),
@@ -361,15 +326,18 @@
0x00040000);
regmap_update_bits(mpcs->regmap_pextp, 0x90D0, GENMASK(31, 0),
0x00000003);
+ /* Release reset */
regmap_update_bits(mpcs->regmap_pextp, 0x0070, GENMASK(31, 0),
0x0200E800);
udelay(150);
+ /* Switch to P0 */
regmap_update_bits(mpcs->regmap_pextp, 0x0070, GENMASK(31, 0),
0x0200C111);
ndelay(1020);
regmap_update_bits(mpcs->regmap_pextp, 0x0070, GENMASK(31, 0),
0x0200C101);
udelay(15);
+ /* Switch to Gen3 */
regmap_update_bits(mpcs->regmap_pextp, 0x0070, GENMASK(31, 0),
0x0202C111);
ndelay(1020);
@@ -383,48 +351,14 @@
regmap_update_bits(mpcs->regmap_pextp, 0x3040, GENMASK(31, 0),
0x30000000);
udelay(400);
-
- return 0;
}
-int mtk_usxgmii_setup_phya_force_10000(struct mtk_usxgmii_pcs *mpcs)
+void mtk_usxgmii_setup_phya_10gbaser(struct mtk_usxgmii_pcs *mpcs)
{
- unsigned int val;
-
- if (!mpcs->regmap || !mpcs->regmap_pextp)
- return -EINVAL;
-
- /* Setup USXGMII speed */
- val = FIELD_PREP(RG_XFI_RX_MODE, RG_XFI_RX_MODE_10G) |
- FIELD_PREP(RG_XFI_TX_MODE, RG_XFI_TX_MODE_10G);
- regmap_write(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, val);
-
- /* Disable USXGMII AN mode */
- regmap_read(mpcs->regmap, RG_PCS_AN_CTRL0, &val);
- val &= ~USXGMII_AN_ENABLE;
- regmap_write(mpcs->regmap, RG_PCS_AN_CTRL0, val);
-
- /* Gated USXGMII */
- regmap_read(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, &val);
- val |= RG_MAC_CK_GATED;
- regmap_write(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, val);
-
- ndelay(1020);
-
- /* USXGMII force mode setting */
- regmap_read(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, &val);
- val |= RG_USXGMII_RATE_UPDATE_MODE;
- val |= RG_IF_FORCE_EN;
- val |= FIELD_PREP(RG_RATE_ADAPT_MODE, RG_RATE_ADAPT_MODE_X1);
- regmap_write(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, val);
-
- /* Un-gated USXGMII */
- regmap_read(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, &val);
- val &= ~RG_MAC_CK_GATED;
- regmap_write(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, val);
-
- ndelay(1020);
+ if (!mpcs->regmap_pextp)
+ return;
+ /* Setup operation mode */
regmap_update_bits(mpcs->regmap_pextp, 0x9024, GENMASK(31, 0),
0x00C9071C);
regmap_update_bits(mpcs->regmap_pextp, 0x2020, GENMASK(31, 0),
@@ -467,13 +401,17 @@
0x18190000);
regmap_update_bits(mpcs->regmap_pextp, 0x00F8, GENMASK(31, 0),
0x01423342);
+ /* Force SGDT_OUT off and select PCS */
regmap_update_bits(mpcs->regmap_pextp, 0x00F4, GENMASK(31, 0),
0x80201F20);
+ /* Force GLB_CKDET_OUT */
regmap_update_bits(mpcs->regmap_pextp, 0x0030, GENMASK(31, 0),
0x00050C00);
+ /* Force AEQ on */
regmap_update_bits(mpcs->regmap_pextp, 0x0070, GENMASK(31, 0),
0x02002800);
ndelay(1020);
+ /* Setup DA default value */
regmap_update_bits(mpcs->regmap_pextp, 0x30B0, GENMASK(31, 0),
0x00000020);
regmap_update_bits(mpcs->regmap_pextp, 0x3028, GENMASK(31, 0),
@@ -503,15 +441,18 @@
0x00040000);
regmap_update_bits(mpcs->regmap_pextp, 0x90D0, GENMASK(31, 0),
0x00000001);
+ /* Release reset */
regmap_update_bits(mpcs->regmap_pextp, 0x0070, GENMASK(31, 0),
0x0200E800);
udelay(150);
+ /* Switch to P0 */
regmap_update_bits(mpcs->regmap_pextp, 0x0070, GENMASK(31, 0),
0x0200C111);
ndelay(1020);
regmap_update_bits(mpcs->regmap_pextp, 0x0070, GENMASK(31, 0),
0x0200C101);
udelay(15);
+ /* Switch to Gen3 */
regmap_update_bits(mpcs->regmap_pextp, 0x0070, GENMASK(31, 0),
0x0202C111);
ndelay(1020);
@@ -525,8 +466,6 @@
regmap_update_bits(mpcs->regmap_pextp, 0x3040, GENMASK(31, 0),
0x30000000);
udelay(400);
-
- return 0;
}
void mtk_usxgmii_reset(struct mtk_eth *eth, int id)
@@ -607,22 +546,97 @@
{
struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
struct mtk_eth *eth = mpcs->eth;
- int err = 0;
+ unsigned int an_ctrl = 0, link_timer = 0, xfi_mode = 0, adapt_mode = 0;
+ bool mode_changed = false;
- mpcs->interface = interface;
+ 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_RX_MODE_10G) |
+ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_10G);
+ } else if (interface == PHY_INTERFACE_MODE_10GKR) {
+ 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_RX_MODE_10G) |
+ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_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_RX_MODE_5G) |
+ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_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_xfi_pll_enable(eth->usxgmii);
mtk_usxgmii_reset(eth, mpcs->id);
+ /* Setup USXGMII AN ctrl */
+ regmap_update_bits(mpcs->regmap, RG_PCS_AN_CTRL0,
+ USXGMII_AN_SYNC_CNT | USXGMII_AN_ENABLE,
+ an_ctrl);
+
+ regmap_update_bits(mpcs->regmap, RG_PCS_AN_CTRL2,
+ USXGMII_LINK_TIMER_IDLE_DETECT |
+ USXGMII_LINK_TIMER_COMP_ACK_DETECT |
+ USXGMII_LINK_TIMER_AN_RESTART,
+ link_timer);
+
+ /* Gated MAC CK */
+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
+ USXGMII_MAC_CK_GATED, USXGMII_MAC_CK_GATED);
+
+ /* Enable interface force mode */
+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
+ USXGMII_IF_FORCE_EN, USXGMII_IF_FORCE_EN);
+
+ /* Setup USXGMII adapt mode */
+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
+ USXGMII_RATE_UPDATE_MODE | USXGMII_RATE_ADAPT_MODE,
+ adapt_mode);
+
+ /* Setup USXGMII speed */
+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
+ USXGMII_XFI_RX_MODE | USXGMII_XFI_TX_MODE,
+ xfi_mode);
+
+ udelay(1);
+
+ /* Un-gated MAC CK */
+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
+ USXGMII_MAC_CK_GATED, 0);
+
+ udelay(1);
+
+ /* Disable interface force mode for the AN mode */
+ if (an_ctrl & USXGMII_AN_ENABLE)
+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
+ USXGMII_IF_FORCE_EN, 0);
+
/* Setup USXGMIISYS with the determined property */
if (interface == PHY_INTERFACE_MODE_USXGMII)
- err = mtk_usxgmii_setup_phya_an_10000(mpcs);
+ mtk_usxgmii_setup_phya_usxgmii(mpcs);
else if (interface == PHY_INTERFACE_MODE_10GKR)
- err = mtk_usxgmii_setup_phya_force_10000(mpcs);
+ mtk_usxgmii_setup_phya_10gbaser(mpcs);
else if (interface == PHY_INTERFACE_MODE_5GBASER)
- err = mtk_usxgmii_setup_phya_force_5000(mpcs);
+ mtk_usxgmii_setup_phya_5gbaser(mpcs);
- return err;
+ return mode_changed;
}
static void mtk_usxgmii_pcs_get_state(struct phylink_pcs *pcs,
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/en8801sc.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/en8801sc.c
new file mode 100644
index 0000000..f8c5ad6
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/en8801sc.c
@@ -0,0 +1,1153 @@
+// SPDX-License-Identifier: GPL-2.0
+/* FILE NAME: en8801sc.c
+ * PURPOSE:
+ * EN8801SC phy driver for Linux
+ * NOTES:
+ *
+ */
+
+/* INCLUDE FILE DECLARATIONS
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/unistd.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/phy.h>
+#include <linux/delay.h>
+
+#include <linux/uaccess.h>
+#include <linux/version.h>
+#if (KERNEL_VERSION(4, 16, 0) > LINUX_VERSION_CODE)
+#include <linux/of_gpio.h>
+#include <linux/gpio/consumer.h>
+#endif
+
+#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))
+
+#if (KERNEL_VERSION(4, 5, 0) > LINUX_VERSION_CODE)
+#define phydev_mdio_bus(_dev) (_dev->bus)
+#define phydev_phy_addr(_dev) (_dev->addr)
+#define phydev_dev(_dev) (&_dev->dev)
+#define phydev_pbus_addr(dev) ((dev)->addr + 1)
+#else
+#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)
+#endif
+
+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;
+#if (KERNEL_VERSION(4, 16, 0) > LINUX_VERSION_CODE)
+ struct gpio_desc *hw_reset;
+#endif
+};
+
+/*
+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 unsigned int airoha_cl22_read(struct mii_bus *ebus, int phy_addr,
+ unsigned int phy_register, unsigned int *read_data)
+{
+ *read_data = mdiobus_read(ebus, phy_addr, phy_register);
+ return 0;
+}
+
+static int airoha_cl22_write(struct mii_bus *ebus, int phy_addr,
+ unsigned int phy_register, unsigned int write_data)
+{
+ int ret = 0;
+ struct device *dev = &ebus->dev;
+
+ ret = mdiobus_write(ebus, phy_addr, phy_register, write_data);
+ if (ret < 0) {
+ dev_err(dev, "%s fail. (ret=%d)\n", __func__, ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+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;
+ struct device *dev = &ebus->dev;
+
+ 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 pbusAddress = EN8801S_PBUS_DEFAULT_ID;
+ 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;
+
+#if (KERNEL_VERSION(4, 16, 0) > LINUX_VERSION_CODE)
+ /* Deassert the reset signal */
+ if (priv->hw_reset)
+ gpiod_set_value(priv->hw_reset, 0);
+#endif
+ priv->count = 1;
+ msleep(1000);
+
+ retry = MAX_OUI_CHECK;
+ while (1) {
+ pbus_data = airoha_pbus_read(mbus, pbusAddress,
+ EN8801S_RG_ETHER_PHY_OUI); /* PHY OUI */
+ if (pbus_data == EN8801S_PBUS_OUI) {
+ dev_info(dev, "PBUS addr 0x%x: Start initialized.\n",
+ pbusAddress);
+ break;
+ }
+ pbusAddress = phydev_pbus_addr(phydev);
+ if (0 == --retry) {
+ dev_err(dev, "Probe fail !\n");
+ return 0;
+ }
+ }
+
+ ret = airoha_pbus_write(mbus, pbusAddress, EN8801S_RG_BUCK_CTL, 0x03);
+ if (ret < 0)
+ return ret;
+ mdelay(10);
+ pbus_data = (airoha_pbus_read(mbus, pbusAddress, EN8801S_RG_LTR_CTL)
+ & 0xfffffffc) | BIT(2);
+ ret = airoha_pbus_write(mbus, pbusAddress,
+ 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, pbusAddress,
+ EN8801S_RG_LTR_CTL, pbus_data);
+ if (ret < 0)
+ return ret;
+ mdelay(500);
+
+ pbus_data = airoha_pbus_read(mbus, pbusAddress,
+ 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, pbusAddress,
+ 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);
+
+ 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)) {
+ 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) {
+ 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) {
+ 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) {
+ 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 mii_bus *mbus = phydev_mdio_bus(phydev);
+ struct device *dev = &mbus->dev;
+#if (KERNEL_VERSION(4, 16, 0) > LINUX_VERSION_CODE)
+ struct gpio_desc *en8801s_reset;
+ int err = 0;
+#else
+ struct mdio_device *mdiodev = &phydev->mdio;
+#endif
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->count = 0;
+ priv->first_init = true;
+
+#if (KERNEL_VERSION(4, 16, 0) > LINUX_VERSION_CODE)
+ /* Assert the optional reset signal */
+ en8801s_reset = gpiod_get_optional(&phydev->dev,
+ "reset", GPIOD_OUT_HIGH);
+ err = PTR_ERR_OR_ZERO(en8801s_reset);
+ if (err) {
+ dev_dbg(phydev_dev(phydev),
+ "PHY %lx have no reset pin in device tree.\n",
+ phy_addr);
+ } else {
+ dev_dbg(phydev_dev(phydev),
+ "Assert PHY %lx HWRST until config_init\n",
+ phy_addr);
+ priv->hw_reset = en8801s_reset;
+ }
+
+#else
+ 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);
+ }
+#endif
+
+ phydev->priv = priv;
+
+ return 0;
+}
+
+#if (KERNEL_VERSION(4, 5, 0) < LINUX_VERSION_CODE)
+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;
+}
+#endif
+
+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,
+#if (KERNEL_VERSION(4, 5, 0) < LINUX_VERSION_CODE)
+ .read_mmd = airoha_mmd_read,
+ .write_mmd = airoha_mmd_write,
+#endif
+ }
+};
+
+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/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/en8801sc.h b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/en8801sc.h
new file mode 100644
index 0000000..0a077c3
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/en8801sc.h
@@ -0,0 +1,255 @@
+// 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.7_Generic"
+#define EN8801S_PBUS_DEFAULT_ID 0x1e
+#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_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_EVT(reg, cod, result, bit) do \
+ { \
+ if (reg & cod) { \
+ result |= bit; \
+ } \
+ } while (0)
+
+#define LED_SET_GPIO_SEL(gpio, led, val) \
+ (val |= (led << (8 * (gpio % 4)))) \
+
+
+/* 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/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mediatek-2p5ge.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mediatek-2p5ge.c
index 32ae8ea..2825a36 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mediatek-2p5ge.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mediatek-2p5ge.c
@@ -28,8 +28,17 @@
/* Registers on MDIO_MMD_VEND2 */
#define MTK_PHY_LED0_ON_CTRL (0x24)
+#define MTK_PHY_LED0_ON_LINK1000 BIT(0)
+#define MTK_PHY_LED0_ON_LINK100 BIT(1)
+#define MTK_PHY_LED0_ON_LINK10 BIT(2)
+#define MTK_PHY_LED0_ON_LINK2500 BIT(7)
#define MTK_PHY_LED0_POLARITY BIT(14)
+#define MTK_PHY_LED1_ON_CTRL (0x26)
+#define MTK_PHY_LED1_ON_FDX BIT(4)
+#define MTK_PHY_LED1_ON_HDX BIT(5)
+#define MTK_PHY_LED1_POLARITY BIT(14)
+
enum {
PHY_AUX_SPD_10 = 0,
PHY_AUX_SPD_100,
@@ -37,22 +46,6 @@
PHY_AUX_SPD_2500,
};
-static int mt798x_2p5ge_phy_probe(struct phy_device *phydev)
-{
- struct pinctrl *pinctrl;
-
- phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
- MTK_PHY_LED0_POLARITY);
-
- pinctrl = devm_pinctrl_get_select_default(&phydev->mdio.dev);
- if (IS_ERR(pinctrl)) {
- dev_err(&phydev->mdio.dev, "Fail to set LED pins!\n");
- return PTR_ERR(pinctrl);
- }
-
- return 0;
-}
-
static int mt798x_2p5ge_phy_config_init(struct phy_device *phydev)
{
int ret;
@@ -64,6 +57,8 @@
void __iomem *pmb_addr;
void __iomem *mcucsr_base;
u16 reg;
+ struct pinctrl *pinctrl;
+
np = of_find_compatible_node(NULL, NULL, "mediatek,2p5gphy-fw");
if (!np)
@@ -103,6 +98,20 @@
writew(reg | MD32_EN, mcucsr_base + MD32_EN_CFG);
dev_info(dev, "Firmware loading/trigger ok.\n");
+ /* Setup LED */
+ phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
+ MTK_PHY_LED0_POLARITY | MTK_PHY_LED0_ON_LINK10 |
+ MTK_PHY_LED0_ON_LINK100 | MTK_PHY_LED0_ON_LINK1000 |
+ MTK_PHY_LED0_ON_LINK2500);
+ phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED1_ON_CTRL,
+ MTK_PHY_LED1_ON_FDX | MTK_PHY_LED1_ON_HDX);
+
+ pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "i2p5gbe-led");
+ if (IS_ERR(pinctrl)) {
+ dev_err(&phydev->mdio.dev, "Fail to set LED pins!\n");
+ return PTR_ERR(pinctrl);
+ }
+
return 0;
}
@@ -221,7 +230,6 @@
{
PHY_ID_MATCH_EXACT(0x00339c11),
.name = "MediaTek MT798x 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,
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9993-add-wed.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9993-add-wed.patch
index 04e4edc..201a629 100755
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9993-add-wed.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9993-add-wed.patch
@@ -208,9 +208,9 @@
+ mtk_wed_add_hw(np, eth, wdma, i);
+ }
+
- for (i = 0; i < MTK_MAX_IRQ_NUM; i++) {
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT) && i > 0)
- eth->irq[i] = eth->irq[0];
+ for (i = 0; i < MTK_PDMA_IRQ_NUM; i++)
+ eth->irq_pdma[i] = platform_get_irq(pdev, i);
+
@@ -4320,10 +4397,11 @@ static int mtk_probe(struct platform_dev
}
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7988.cfg b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7988.cfg
index e542a51..e706419 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7988.cfg
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7988.cfg
@@ -7,7 +7,6 @@
CONFIG_AQUANTIA_PHY_FW_DOWNLOAD_GANG=y
# CONFIG_AQUANTIA_PHY_FW_DOWNLOAD_SINGLE is not set
CONFIG_AQUANTIA_PHY_FW_FILE="Rhe-05.06-Candidate9-AQR_Mediatek_23B_P5_ID45824_LCLVER1.cld"
-# CONFIG_AQUANTIA_PHY_MDI_SWAP is not set
CONFIG_ARCH_CLOCKSOURCE_DATA=y
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
CONFIG_ARCH_KEEP_MEMBLOCK=y
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/745-en8801sc-gphy-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/745-en8801sc-gphy-support.patch
index b50a7bb..6de04c3 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/745-en8801sc-gphy-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/745-en8801sc-gphy-support.patch
@@ -1,1021 +1,3 @@
-Index: drivers/net/phy/en8801sc.c
-===================================================================
---- /dev/null
-+++ b/drivers/net/phy/en8801sc.c
-@@ -0,0 +1,732 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/* FILE NAME: en8801sc.c
-+ * PURPOSE:
-+ * EN8801SC phy driver for Linux
-+ * NOTES:
-+ *
-+ */
-+
-+/* INCLUDE FILE DECLARATIONS
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/string.h>
-+#include <linux/errno.h>
-+#include <linux/unistd.h>
-+#include <linux/interrupt.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/skbuff.h>
-+#include <linux/spinlock.h>
-+#include <linux/mm.h>
-+#include <linux/module.h>
-+#include <linux/mii.h>
-+#include <linux/ethtool.h>
-+#include <linux/phy.h>
-+#include <linux/delay.h>
-+
-+#include <linux/uaccess.h>
-+#include <linux/version.h>
-+
-+#include "en8801sc.h"
-+
-+MODULE_DESCRIPTION("Airoha EN8801S PHY drivers for MediaTek SoC");
-+MODULE_AUTHOR("Airoha");
-+MODULE_LICENSE("GPL");
-+
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0))
-+#define phydev_mdio_bus(dev) ((dev)->bus)
-+#else
-+#define phydev_mdio_bus(dev) ((dev)->mdio.bus)
-+#endif
-+
-+enum {
-+ PHY_STATE_DONE = 0,
-+ PHY_STATE_INIT = 1,
-+ PHY_STATE_PROCESS = 2,
-+ PHY_STATE_SS_FAIL = 3,
-+ PHY_STATE_FAIL = 4
-+};
-+
-+/*
-+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 AIR_BASE_T_LED_CFG_T led_cfg[4] =
-+{
-+ /*
-+ * LED Enable, GPIO, LED Polarity, LED ON, LED Blink
-+ */
-+ {LED_ENABLE, 5, AIR_ACTIVE_LOW, BASE_T_LED0_ON_CFG, BASE_T_LED0_BLK_CFG}, /* BASE-T LED0 */
-+ {LED_ENABLE, 9, AIR_ACTIVE_LOW, BASE_T_LED1_ON_CFG, BASE_T_LED1_BLK_CFG}, /* BASE-T LED1 */
-+ {LED_ENABLE, 8, AIR_ACTIVE_LOW, BASE_T_LED2_ON_CFG, BASE_T_LED2_BLK_CFG}, /* BASE-T LED2 */
-+ {LED_DISABLE, 1, AIR_ACTIVE_LOW, BASE_T_LED3_ON_CFG, BASE_T_LED3_BLK_CFG} /* BASE-T LED3 */
-+};
-+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 airoha_cl45_write(struct mii_bus *bus, u32 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);
-+ AIR_RTN_ON_ERR_MSG(ret < 0, ret, "%s fail. (ret=%d)\n", __func__, ret);
-+ ret = mdiobus_write(bus, port, MII_MMD_ADDR_DATA_REG, reg);
-+ AIR_RTN_ON_ERR_MSG(ret < 0, ret, "%s fail. (ret=%d)\n", __func__, ret);
-+ ret = mdiobus_write(bus, port, MII_MMD_ACC_CTL_REG, MMD_OP_MODE_DATA | devad);
-+ AIR_RTN_ON_ERR_MSG(ret < 0, ret, "%s fail. (ret=%d)\n", __func__, ret);
-+ ret = mdiobus_write(bus, port, MII_MMD_ADDR_DATA_REG, val);
-+ AIR_RTN_ON_ERR_MSG(ret < 0, ret, "%s fail. (ret=%d)\n", __func__, ret);
-+ return ret;
-+}
-+
-+static int airoha_cl45_read(struct mii_bus *bus, u32 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);
-+ AIR_RTN_ON_ERR_MSG(ret < 0, ret, "%s fail. (ret=%d)\n", __func__, ret);
-+ ret = mdiobus_write(bus, port, MII_MMD_ADDR_DATA_REG, reg);
-+ AIR_RTN_ON_ERR_MSG(ret < 0, ret, "%s fail. (ret=%d)\n", __func__, ret);
-+ ret = mdiobus_write(bus, port, MII_MMD_ACC_CTL_REG, MMD_OP_MODE_DATA | devad);
-+ AIR_RTN_ON_ERR_MSG(ret < 0, ret, "%s fail. (ret=%d)\n", __func__, ret);
-+ *read_data = mdiobus_read(bus, port, MII_MMD_ADDR_DATA_REG);
-+ return 0;
-+}
-+
-+static unsigned int airoha_cl22_read(struct mii_bus *ebus, unsigned int phy_addr, unsigned int phy_register, unsigned int *read_data)
-+{
-+ *read_data = mdiobus_read(ebus, phy_addr, phy_register);
-+ return 0;
-+}
-+
-+static int airoha_cl22_write(struct mii_bus *ebus, unsigned int phy_addr, unsigned int phy_register, unsigned int write_data)
-+{
-+ int ret = 0;
-+ struct device *dev = &ebus->dev;
-+
-+ ret = mdiobus_write(ebus, phy_addr, phy_register, write_data);
-+ AIR_RTN_ON_ERR_MSG(ret < 0, ret, "%s fail. (ret=%d)\n", __func__, ret);
-+ return ret;
-+}
-+
-+static int airoha_pbus_write(struct mii_bus *ebus, unsigned long pbus_id, unsigned long pbus_address, unsigned long pbus_data)
-+{
-+ int ret = 0;
-+
-+ ret = airoha_cl22_write(ebus, pbus_id, 0x1F, (unsigned int)(pbus_address >> 6));
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_cl22_write(ebus, pbus_id, (unsigned int)((pbus_address >> 2) & 0xf), (unsigned int)(pbus_data & 0xFFFF));
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_cl22_write(ebus, pbus_id, 0x10, (unsigned int)(pbus_data >> 16));
-+ AIR_RTN_ERR(ret);
-+ return ret;
-+}
-+
-+static unsigned long airoha_pbus_read(struct mii_bus *ebus, unsigned long 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 = airoha_cl22_write(ebus, pbus_id, 0x1F, (unsigned int)(pbus_address >> 6));
-+ if ( ret < 0) {
-+ AIR_RTN_ON_ERR_MSG(ret < 0, ret, "%s fail. (ret=%d)\n", __func__, ret);
-+ return INVALID_DATA;
-+ }
-+ airoha_cl22_read(ebus, pbus_id, (unsigned int)((pbus_address >> 2) & 0xf), &pbus_data_low);
-+ airoha_cl22_read(ebus, pbus_id, 0x10, &pbus_data_high);
-+ pbus_data = (pbus_data_high << 16) + pbus_data_low;
-+ return pbus_data;
-+}
-+
-+/* Airoha Token Ring Write function */
-+static int airoha_tr_reg_write(struct mii_bus *ebus, unsigned long tr_address, unsigned long tr_data)
-+{
-+ int ret = 0;
-+ ret = airoha_cl22_write(ebus, EN8801S_MDIO_PHY_ID, 0x1F, 0x52b5); /* page select */
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_cl22_write(ebus, EN8801S_MDIO_PHY_ID, 0x11, (unsigned int)(tr_data & 0xffff));
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_cl22_write(ebus, EN8801S_MDIO_PHY_ID, 0x12, (unsigned int)(tr_data >> 16));
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_cl22_write(ebus, EN8801S_MDIO_PHY_ID, 0x10, (unsigned int)(tr_address | TrReg_WR));
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_cl22_write(ebus, EN8801S_MDIO_PHY_ID, 0x1F, 0x0); /* page resetore */
-+ AIR_RTN_ERR(ret);
-+ return ret;
-+}
-+
-+#if 0
-+/* Airoha Token Ring Read function */
-+static unsigned long airoha_tr_reg_read(struct mii_bus *ebus, unsigned long tr_address)
-+{
-+ unsigned long tr_data;
-+ unsigned int tr_data_low, tr_data_high;
-+
-+ airoha_cl22_write(ebus, EN8801S_MDIO_PHY_ID, 0x1F, 0x52b5); /* page select */
-+ airoha_cl22_write(ebus, EN8801S_MDIO_PHY_ID, 0x10, (unsigned int)(tr_address | TrReg_RD));
-+ airoha_cl22_read(ebus, EN8801S_MDIO_PHY_ID, 0x11, &tr_data_low);
-+ airoha_cl22_read(ebus, EN8801S_MDIO_PHY_ID, 0x12, &tr_data_high);
-+ airoha_cl22_write(ebus, EN8801S_MDIO_PHY_ID, 0x1F, 0x0); /* page resetore */
-+ tr_data = (tr_data_high << 16) + tr_data_low;
-+ return tr_data;
-+}
-+#endif
-+#ifdef AIR_LED_SUPPORT
-+static int airoha_led_set_usr_def(struct mii_bus *mbus, u8 entity, int polar,
-+ u16 on_evt, u16 blk_evt)
-+{
-+ int ret = 0;
-+ if (AIR_ACTIVE_HIGH == polar) {
-+ on_evt |= LED_ON_POL;
-+ } else {
-+ on_evt &= ~LED_ON_POL;
-+ }
-+ ret = airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1f, LED_ON_CTRL(entity), on_evt | LED_ON_EN);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1f, LED_BLK_CTRL(entity), blk_evt);
-+ AIR_RTN_ERR(ret);
-+ return 0;
-+}
-+
-+static int airoha_led_set_mode(struct mii_bus *mbus, u8 mode)
-+{
-+ u16 cl45_data;
-+ int err = 0;
-+
-+ err = airoha_cl45_read(mbus, EN8801S_MDIO_PHY_ID, 0x1f, LED_BCR, &cl45_data);
-+ AIR_RTN_ERR(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, EN8801S_MDIO_PHY_ID, 0x1f, LED_BCR, cl45_data);
-+ AIR_RTN_ERR(err);
-+ return 0;
-+}
-+
-+static int airoha_led_set_state(struct mii_bus *mbus, u8 entity, u8 state)
-+{
-+ u16 cl45_data;
-+ int err;
-+
-+ err = airoha_cl45_read(mbus, EN8801S_MDIO_PHY_ID, 0x1f, LED_ON_CTRL(entity), &cl45_data);
-+ AIR_RTN_ERR(err);
-+ if (LED_ENABLE == state) {
-+ cl45_data |= LED_ON_EN;
-+ } else {
-+ cl45_data &= ~LED_ON_EN;
-+ }
-+
-+ err = airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1f, LED_ON_CTRL(entity), cl45_data);
-+ AIR_RTN_ERR(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 = &mbus->dev;
-+
-+ ret = airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1f, LED_BLK_DUR, cl45_data);
-+ AIR_RTN_ERR(ret);
-+ cl45_data >>= 1;
-+ ret = airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1f, LED_ON_DUR, cl45_data);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_led_set_mode(mbus, 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(mbus, 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_ENABLE == led_cfg[led_id].en)
-+ {
-+ 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, EN8801S_PBUS_PHY_ID, 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, EN8801S_PBUS_PHY_ID, gpio_led_rg[led_cfg[led_id].gpio / 4], reg_value);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_led_set_usr_def(mbus, 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, EN8801S_PBUS_PHY_ID, 0x1880) & ~led_gpio);
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x1880, reg_value);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x186c, led_gpio);
-+ AIR_RTN_ERR(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;
-+
-+ reg_value = airoha_pbus_read(mbus, EN8801S_PBUS_PHY_ID, 0x19e0);
-+ reg_value |= BIT(0);
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x19e0, reg_value);
-+ AIR_RTN_ERR(ret);
-+ reg_value = airoha_pbus_read(mbus, EN8801S_PBUS_PHY_ID, 0x19e0);
-+ reg_value &= ~BIT(0);
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x19e0, reg_value);
-+ AIR_RTN_ERR(ret);
-+ return ret;
-+}
-+
-+static int en8801s_phase1_init(struct phy_device *phydev)
-+{
-+ unsigned long pbus_data;
-+ unsigned int pbusAddress;
-+ u16 reg_value;
-+ int retry, ret = 0;
-+ struct mii_bus *mbus = phydev_mdio_bus(phydev);
-+ struct device *dev = &mbus->dev;
-+ msleep(1500);
-+
-+ pbusAddress = EN8801S_PBUS_DEFAULT_ID;
-+ retry = MAX_OUI_CHECK;
-+ while (1) {
-+ pbus_data = airoha_pbus_read(mbus, pbusAddress, EN8801S_RG_ETHER_PHY_OUI); /* PHY OUI */
-+ if (EN8801S_PBUS_OUI == pbus_data) {
-+ pbus_data = airoha_pbus_read(mbus, pbusAddress, EN8801S_RG_SMI_ADDR); /* SMI ADDR */
-+ pbus_data = (pbus_data & 0xffff0000) | (unsigned long)(EN8801S_PBUS_PHY_ID << 8) | (unsigned long)(EN8801S_MDIO_PHY_ID);
-+ dev_info(dev, "SMI_ADDR=%lx (renew)\n", pbus_data);
-+ ret = airoha_pbus_write(mbus, pbusAddress, EN8801S_RG_SMI_ADDR, pbus_data);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, EN8801S_RG_BUCK_CTL, 0x03);
-+ AIR_RTN_ERR(ret);
-+ mdelay(10);
-+ break;
-+ } else {
-+ pbusAddress = EN8801S_PBUS_PHY_ID;
-+ }
-+ if (0 == --retry) {
-+ dev_err(dev, "Probe fail !\n");
-+ return 0;
-+ }
-+ }
-+
-+ pbus_data = (airoha_pbus_read(mbus, EN8801S_PBUS_PHY_ID, EN8801S_RG_LTR_CTL) & 0xfffffffc) | 0x10 | (EN8801S_RX_POLARITY << 1) | EN8801S_TX_POLARITY;
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, EN8801S_RG_LTR_CTL, pbus_data);
-+ AIR_RTN_ERR(ret);
-+ mdelay(10);
-+ pbus_data &= ~BIT(4);
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, EN8801S_RG_LTR_CTL, pbus_data);
-+ AIR_RTN_ERR(ret);
-+
-+ 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 (0 == retry) {
-+ 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);
-+ AIR_RTN_ERR(ret);
-+ retry = MAX_RETRY;
-+ do {
-+ mdelay(10);
-+ reg_value = phy_read(phydev, MII_BMCR);
-+ retry--;
-+ if (0 == retry) {
-+ 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);
-+ return 0;
-+}
-+
-+static int en8801s_phase2_init(struct phy_device *phydev)
-+{
-+ gephy_all_REG_LpiReg1Ch GPHY_RG_LPI_1C;
-+ gephy_all_REG_dev1Eh_reg324h GPHY_RG_1E_324;
-+ gephy_all_REG_dev1Eh_reg012h GPHY_RG_1E_012;
-+ gephy_all_REG_dev1Eh_reg017h GPHY_RG_1E_017;
-+ unsigned long pbus_data;
-+ u16 cl45_value;
-+ int retry, ret = 0;
-+ struct mii_bus *mbus = phydev_mdio_bus(phydev);
-+ struct device *dev = &mbus->dev;
-+
-+ pbus_data = (airoha_pbus_read(mbus, EN8801S_PBUS_PHY_ID, EN8801S_RG_LTR_CTL) & 0xfffffffc) | 0x10 | (EN8801S_RX_POLARITY << 1) | EN8801S_TX_POLARITY;
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, EN8801S_RG_LTR_CTL, pbus_data);
-+ AIR_RTN_ERR(ret);
-+ mdelay(10);
-+ pbus_data &= 0xffffffef;
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, EN8801S_RG_LTR_CTL, pbus_data);
-+ AIR_RTN_ERR(ret);
-+
-+ pbus_data = airoha_pbus_read(mbus, EN8801S_PBUS_PHY_ID, 0x1690);
-+ pbus_data |= BIT(31);
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x1690, pbus_data);
-+ AIR_RTN_ERR(ret);
-+
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x0600, 0x0c000c00);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x10, 0xD801);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x0, 0x9140);
-+ AIR_RTN_ERR(ret);
-+
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x0A14, 0x0003);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x0600, 0x0c000c00);
-+ AIR_RTN_ERR(ret);
-+ /* Set FCM control */
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x1404, 0x004b);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x140c, 0x0007);
-+ AIR_RTN_ERR(ret);
-+
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x142c, 0x05050505);
-+ AIR_RTN_ERR(ret);
-+ pbus_data = airoha_pbus_read(mbus, EN8801S_PBUS_PHY_ID, 0x1440);
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x1440, pbus_data & ~BIT(11));
-+ AIR_RTN_ERR(ret);
-+
-+ pbus_data = airoha_pbus_read(mbus, EN8801S_PBUS_PHY_ID, 0x1408);
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x1408, pbus_data | BIT(5));
-+ AIR_RTN_ERR(ret);
-+
-+ /* Set GPHY Perfomance*/
-+ /* Token Ring */
-+ ret = airoha_tr_reg_write(mbus, RgAddr_R1000DEC_15h, 0x0055A0);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_tr_reg_write(mbus, RgAddr_R1000DEC_17h, 0x07FF3F);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_tr_reg_write(mbus, RgAddr_PMA_00h, 0x00001E);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_tr_reg_write(mbus, RgAddr_PMA_01h, 0x6FB90A);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_tr_reg_write(mbus, RgAddr_PMA_17h, 0x060671);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_tr_reg_write(mbus, RgAddr_PMA_18h, 0x0E2F00);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_tr_reg_write(mbus, RgAddr_TR_26h, 0x444444);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_tr_reg_write(mbus, RgAddr_DSPF_03h, 0x000000);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_tr_reg_write(mbus, RgAddr_DSPF_06h, 0x2EBAEF);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_tr_reg_write(mbus, RgAddr_DSPF_08h, 0x00000B);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_tr_reg_write(mbus, RgAddr_DSPF_0Ch, 0x00504D);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_tr_reg_write(mbus, RgAddr_DSPF_0Dh, 0x02314F);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_tr_reg_write(mbus, RgAddr_DSPF_0Fh, 0x003028);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_tr_reg_write(mbus, RgAddr_DSPF_10h, 0x005010);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_tr_reg_write(mbus, RgAddr_DSPF_11h, 0x040001);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_tr_reg_write(mbus, RgAddr_DSPF_13h, 0x018670);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_tr_reg_write(mbus, RgAddr_DSPF_14h, 0x00024A);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_tr_reg_write(mbus, RgAddr_DSPF_1Bh, 0x000072);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_tr_reg_write(mbus, RgAddr_DSPF_1Ch, 0x003210);
-+ AIR_RTN_ERR(ret);
-+
-+ /* CL22 & CL45 */
-+ ret = phy_write(phydev, 0x1f, 0x03);
-+ AIR_RTN_ERR(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);
-+ AIR_RTN_ERR(ret);
-+ ret = phy_write(phydev, RgAddr_LPI_1Ch, 0xC92);
-+ AIR_RTN_ERR(ret);
-+ ret = phy_write(phydev, RgAddr_AUXILIARY_1Dh, 0x1);
-+ AIR_RTN_ERR(ret);
-+ ret = phy_write(phydev, 0x1f, 0x0);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x120, 0x8014);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x122, 0xffff);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x123, 0xffff);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x144, 0x0200);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x14A, 0xEE20);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x189, 0x0110);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x19B, 0x0111);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x234, 0x0181);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x238, 0x0120);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x239, 0x0117);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x268, 0x07F4);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x2D1, 0x0733);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x323, 0x0011);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x324, 0x013F);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x326, 0x0037);
-+ AIR_RTN_ERR(ret);
-+
-+ ret = airoha_cl45_read(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x324, &cl45_value);
-+ AIR_RTN_ERR(ret);
-+ GPHY_RG_1E_324.DATA = cl45_value;
-+ GPHY_RG_1E_324.DataBitField.smi_det_deglitch_off = 0;
-+ ret = airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x324, GPHY_RG_1E_324.DATA);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x19E, 0xC2);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x013, 0x0);
-+ AIR_RTN_ERR(ret);
-+
-+ /* EFUSE */
-+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x1C08, 0x40000040);
-+ retry = MAX_RETRY;
-+ while (0 != retry) {
-+ mdelay(1);
-+ pbus_data = airoha_pbus_read(mbus, EN8801S_PBUS_PHY_ID, 0x1C08);
-+ if ((pbus_data & BIT(30)) == 0) {
-+ break;
-+ }
-+ retry--;
-+ }
-+ pbus_data = airoha_pbus_read(mbus, EN8801S_PBUS_PHY_ID, 0x1C38); /* RAW#2 */
-+ GPHY_RG_1E_012.DataBitField.da_tx_i2mpb_a_tbt = (u16)(pbus_data & 0x03f);
-+ ret = airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x12, GPHY_RG_1E_012.DATA);
-+ AIR_RTN_ERR(ret);
-+ GPHY_RG_1E_017.DataBitField.da_tx_i2mpb_b_tbt = (u16)((pbus_data >> 8) & 0x03f);
-+ ret = airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x12, GPHY_RG_1E_017.DATA);
-+ AIR_RTN_ERR(ret);
-+
-+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x1C08, 0x40400040);
-+ retry = MAX_RETRY;
-+ while (0 != retry) {
-+ mdelay(1);
-+ pbus_data = airoha_pbus_read(mbus, EN8801S_PBUS_PHY_ID, 0x1C08);
-+ if ((pbus_data & BIT(30)) == 0) {
-+ break;
-+ }
-+ retry--;
-+ }
-+ pbus_data = airoha_pbus_read(mbus, EN8801S_PBUS_PHY_ID, 0x1C30); /* RAW#16 */
-+ GPHY_RG_1E_324.DataBitField.smi_det_deglitch_off = (u16)((pbus_data >> 12) & 0x01);
-+ ret = airoha_cl45_write(mbus, EN8801S_MDIO_PHY_ID, 0x1E, 0x324, GPHY_RG_1E_324.DATA);
-+ AIR_RTN_ERR(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
-+ pbus_data = airoha_pbus_read(mbus, EN8801S_PBUS_PHY_ID, 0x1960);
-+ pbus_data -= (2 << 22);
-+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x1960, pbus_data);
-+ mdelay(10);
-+ pbus_data -= (2 << 22);
-+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x1960, pbus_data);
-+
-+ dev_info(dev, "Phase2 initialize OK !\n");
-+ return 0;
-+}
-+
-+static int en8801s_read_status(struct phy_device *phydev)
-+{
-+ int ret = 0, preSpeed = phydev->speed, retry = MAX_RETRY;
-+ struct mii_bus *mbus = phydev_mdio_bus(phydev);
-+ u32 reg_value;
-+ struct device *dev = &mbus->dev;
-+
-+ ret = genphy_read_status(phydev);
-+ if (LINK_DOWN == phydev->link) 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) {
-+ do {
-+ mdelay(100);
-+ reg_value = airoha_pbus_read(mbus, EN8801S_PBUS_PHY_ID, 0xb04);
-+ dev_dbg(dev, "[Airoha] 0xB04, reg_value 0x%x\n", reg_value);
-+ reg_value &= 0x21;
-+ if(reg_value == 0x21) {
-+ ret = en8801s_phase2_init(phydev);
-+ if (ret != 0) {
-+ dev_info(dev, "en8801_phase2_init failed\n");
-+ phydev->dev_flags = PHY_STATE_FAIL;
-+ return -1;
-+ } else {
-+ phydev->dev_flags = PHY_STATE_PROCESS;
-+ break;
-+ }
-+
-+ }
-+ if(0 == --retry) {
-+ dev_err(dev, "0xB04 return 0x%x !\n", reg_value);
-+ phydev->dev_flags = PHY_STATE_SS_FAIL;
-+ return -1;
-+ }
-+ } while(retry);
-+ }
-+
-+ if ((preSpeed != phydev->speed) && (LINK_UP == phydev->link)) {
-+ preSpeed = phydev->speed;
-+
-+ if (preSpeed == SPEED_10) {
-+ reg_value = airoha_pbus_read(mbus, EN8801S_PBUS_PHY_ID, 0x1694);
-+ reg_value |= BIT(31);
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x1694, reg_value);
-+ AIR_RTN_ERR(ret);
-+ phydev->dev_flags = PHY_STATE_PROCESS;
-+ } else {
-+ reg_value = airoha_pbus_read(mbus, EN8801S_PBUS_PHY_ID, 0x1694);
-+ reg_value &= ~BIT(31);
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x1694, reg_value);
-+ AIR_RTN_ERR(ret);
-+ phydev->dev_flags = PHY_STATE_PROCESS;
-+ }
-+
-+ airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x0600, 0x0c000c00);
-+ if (SPEED_1000 == preSpeed) {
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x10, 0xD801);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x0, 0x9140);
-+ AIR_RTN_ERR(ret);
-+
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x0A14, 0x0003);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x0600, 0x0c000c00);
-+ AIR_RTN_ERR(ret);
-+ mdelay(2); /* delay 2 ms */
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x1404, 0x004b);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x140c, 0x0007);
-+ AIR_RTN_ERR(ret);
-+ } else if (SPEED_100 == preSpeed) {
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x10, 0xD401);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x0, 0x9140);
-+ AIR_RTN_ERR(ret);
-+
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x0A14, 0x0007);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x0600, 0x0c11);
-+ AIR_RTN_ERR(ret);
-+ mdelay(2); /* delay 2 ms */
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x1404, 0x0027);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x140c, 0x0007);
-+ AIR_RTN_ERR(ret);
-+ } else if (SPEED_10 == preSpeed) {
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x10, 0xD001);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x0, 0x9140);
-+ AIR_RTN_ERR(ret);
-+
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x0A14, 0x000b);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x0600, 0x0c11);
-+ AIR_RTN_ERR(ret);
-+ mdelay(2); /* delay 2 ms */
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x1404, 0x0027);
-+ AIR_RTN_ERR(ret);
-+ ret = airoha_pbus_write(mbus, EN8801S_PBUS_PHY_ID, 0x140c, 0x0007);
-+ AIR_RTN_ERR(ret);
-+ }
-+ }
-+ return ret;
-+}
-+
-+static struct phy_driver Airoha_driver[] = {
-+ {
-+ .phy_id = EN8801SC_PHY_ID,
-+ .name = "Airoha EN8801SC",
-+ .phy_id_mask = 0x0ffffff0,
-+ .features = PHY_GBIT_FEATURES,
-+ .config_init = en8801s_phase1_init,
-+ .config_aneg = genphy_config_aneg,
-+ .read_status = en8801s_read_status,
-+ .suspend = genphy_suspend,
-+ .resume = genphy_resume,
-+ }
-+};
-+
-+module_phy_driver(Airoha_driver);
-+
-+static struct mdio_device_id __maybe_unused Airoha_tbl[] = {
-+ { EN8801SC_PHY_ID, 0x0ffffff0 },
-+ { }
-+};
-+
-+MODULE_DEVICE_TABLE(mdio, Airoha_tbl);
-Index: drivers/net/phy/en8801sc.h
-===================================================================
---- /dev/null
-+++ b/drivers/net/phy/en8801sc.h
-@@ -0,0 +1,276 @@
-+// 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.5"
-+
-+#define PHY_ADDRESS_RANGE 0x18
-+#define EN8801S_PBUS_DEFAULT_ID 0x1e
-+#define EN8801S_MDIO_PHY_ID 0x18 /* Range PHY_ADDRESS_RANGE .. 0x1e */
-+#define EN8801S_PBUS_PHY_ID (EN8801S_MDIO_PHY_ID + 1)
-+
-+#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_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
-+
-+//#define TEST_BOARD
-+#if defined(TEST_BOARD)
-+/* SFP sample for verification */
-+#define EN8801S_TX_POLARITY 1
-+#define EN8801S_RX_POLARITY 0
-+#else
-+/* chip on board */
-+#define EN8801S_TX_POLARITY 0
-+#define EN8801S_RX_POLARITY 1 /* The pin default assignment is set to 1 */
-+#endif
-+
-+/*
-+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 AIR_RTN_ON_ERR(cond, err) \
-+ do { if ((cond)) return (err); } while(0)
-+
-+#define AIR_RTN_ERR(err) AIR_RTN_ON_ERR(err < 0, err)
-+#define AIR_RTN_ON_ERR_MSG(cond, err, msg...) \
-+ do { if ((cond)) { dev_err(dev, ##msg); return (err); } } while(0)
-+
-+#define LED_SET_EVT(reg, cod, result, bit) do \
-+ { \
-+ if(reg & cod) { \
-+ result |= bit; \
-+ } \
-+ } while(0)
-+
-+#define LED_SET_GPIO_SEL(gpio, led, val) do \
-+ { \
-+ val |= (led << (8 * (gpio % 4))); \
-+ } while(0)
-+
-+/* DATA TYPE DECLARATIONS
-+ */
-+typedef struct AIR_BASE_T_LED_CFG_S
-+{
-+ u16 en;
-+ u16 gpio;
-+ u16 pol;
-+ u16 on_cfg;
-+ u16 blk_cfg;
-+}AIR_BASE_T_LED_CFG_T;
-+
-+typedef struct
-+{
-+ u16 DATA_Lo;
-+ u16 DATA_Hi;
-+}TR_DATA_T;
-+
-+typedef union
-+{
-+ 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;
-+} gephy_all_REG_LpiReg1Ch, *Pgephy_all_REG_LpiReg1Ch;
-+
-+typedef union
-+{
-+ 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;
-+} gephy_all_REG_dev1Eh_reg324h, *Pgephy_all_REG_dev1Eh_reg324h;
-+
-+typedef union
-+{
-+ 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;
-+} gephy_all_REG_dev1Eh_reg012h, *Pgephy_all_REG_dev1Eh_reg012h;
-+
-+typedef union
-+{
-+ 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;
-+} gephy_all_REG_dev1Eh_reg017h, *Pgephy_all_REG_dev1Eh_reg017h;
-+
-+typedef 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
-+} AIR_LED_BLK_DUT_T;
-+
-+typedef enum
-+{
-+ AIR_ACTIVE_LOW,
-+ AIR_ACTIVE_HIGH,
-+} AIR_LED_POLARITY;
-+typedef enum
-+{
-+ AIR_LED_MODE_DISABLE,
-+ AIR_LED_MODE_USER_DEFINE,
-+ AIR_LED_MODE_LAST
-+} AIR_LED_MODE_T;
-+
-+#endif /* End of __EN8801SC_H */
Index: drivers/net/phy/Kconfig
===================================================================
--- a/drivers/net/phy/Kconfig
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/751-net-phy-aquantia-add-firmware-download.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/751-net-phy-aquantia-add-firmware-download.patch
index 28248f4..0e38dad 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/751-net-phy-aquantia-add-firmware-download.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/751-net-phy-aquantia-add-firmware-download.patch
@@ -2,31 +2,13 @@
index 7b49c94..5a79af2 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
-@@ -372,7 +372,56 @@ config AMD_PHY
+@@ -372,7 +372,38 @@ config AMD_PHY
config AQUANTIA_PHY
tristate "Aquantia PHYs"
---help---
- Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405
+ Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405, AQR113C
+
-+config AQUANTIA_PHY_MDI_SWAP
-+ tristate "MDI Swap Enable"
-+ depends on AQUANTIA_PHY
-+ ---help---
-+ Currently supports the Aquantia AQR113C
-+
-+choice
-+ prompt "Swap mode"
-+ default AQUANTIA_PHY_MDI_REVERSED
-+ depends on AQUANTIA_PHY_MDI_SWAP
-+
-+ config AQUANTIA_PHY_MDI_NORMAL
-+ bool "Normal"
-+
-+ config AQUANTIA_PHY_MDI_REVERSED
-+ bool "Reversed"
-+endchoice
-+
+config AQUANTIA_PHY_FW_DOWNLOAD
+ tristate "Firmware Download Enable"
+ depends on AQUANTIA_PHY
@@ -74,13 +56,15 @@
obj-$(CONFIG_AIROHA_EN8801SC_PHY) += en8801sc.o
obj-$(CONFIG_AQUANTIA_PHY) += aquantia.o
diff --git a/drivers/net/phy/aquantia.h b/drivers/net/phy/aquantia.h
-index 5a16caa..912bbe6 100644
+index 5a16caa..ab1c241 100644
--- a/drivers/net/phy/aquantia.h
+++ b/drivers/net/phy/aquantia.h
-@@ -9,8 +9,66 @@
+@@ -9,8 +9,72 @@
#include <linux/device.h>
#include <linux/phy.h>
++#define MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT 4
++
+#define PMAPMD_RSVD_VEND_PROV 0xe400
+#define PMAPMD_RSVD_VEND_PROV_MDI_CONF BIT(0)
+
@@ -122,12 +106,15 @@
+#ifdef CONFIG_AQUANTIA_PHY_FW_DOWNLOAD
+ struct phy_device *phydevs[1];
+ struct task_struct *heartbeat_thread;
++ spinlock_t lock;
+ bool fw_initialized;
+ int fw_dl_mode;
+ u16 heartbeat;
+#endif
+};
+
++int aqr107_set_downshift(struct phy_device *phydev, u8 cnt);
++void aqr107_chip_info(struct phy_device *phydev);
+int aqr107_config_mdi(struct phy_device *phydev);
+
#if IS_REACHABLE(CONFIG_HWMON)
@@ -142,14 +129,15 @@
+ FW_DL_GNAGLOAD,
+};
+
++int aqr_firmware_heartbeat_thread(void *data);
+int aqr_firmware_download(struct phy_device *phydev);
+#endif
diff --git a/drivers/net/phy/aquantia_firmware.c b/drivers/net/phy/aquantia_firmware.c
new file mode 100644
-index 0000000..7aeec86
+index 0000000..622557c
--- /dev/null
+++ b/drivers/net/phy/aquantia_firmware.c
-@@ -0,0 +1,1096 @@
+@@ -0,0 +1,1090 @@
+// SPDX-License-Identifier: GPL-2.0
+/* FW download driver for Aquantia PHY
+ */
@@ -1037,15 +1025,17 @@
+ if (ret < 0)
+ return ret;
+
++ /* heartbeat stopped if the current heartbeat is equal to the previous */
+ if (priv->heartbeat == ret)
+ stopped = 1;
+
++ /* update heartbeat to the private data */
+ priv->heartbeat = ret;
+
+ return stopped;
+}
+
-+static int aqr_firmware_heartbeat_thread(void *data)
++int aqr_firmware_heartbeat_thread(void *data)
+{
+ struct phy_device *phydev = data;
+ struct aqr107_priv *priv = phydev->priv;
@@ -1058,10 +1048,11 @@
+ if (kthread_should_stop())
+ break;
+
-+ if (phydev->state != PHY_HALTED &&
++ if (priv->fw_initialized == true &&
+ aqr_firmware_check_heartbeat(phydev) == 1) {
+ dev_err(dev, "Detect heartbeat stopped, start to realod firmware...\n");
+ priv->fw_initialized = false;
++ priv->fw_dl_mode = FW_DL_SINGLE;
+ aqr_firmware_download_single(phydev);
+ }
+
@@ -1076,7 +1067,7 @@
+{
+ struct phy_device **phydevs = context;
+ struct phy_device *gandload_phydev = phydevs[0];
-+ struct device *dev;
++ struct device *dev = &phydevs[0]->mdio.dev;
+ struct aqr107_priv *priv = phydevs[0]->priv;
+ int result[MAX_GANGLOAD_DEVICES];
+ int i, num_phydevs = 0, ret = 0;
@@ -1089,7 +1080,6 @@
+
+retry:
+ if (gandload_phydev->state == PHY_HALTED) {
-+ dev = &phydevs[0]->mdio.dev;
+ dev_info(dev, "Detect PHY power down, stop to reload firmware...\n");
+ goto out;
+ }
@@ -1115,30 +1105,21 @@
+
+ for (i = 0; i < num_phydevs; i++) {
+ if (result[i] == 0) {
++ dev = &phydevs[i]->mdio.dev;
+ priv = phydevs[i]->priv;
+ priv->fw_initialized = true;
+
++ aqr107_chip_info(phydevs[i]);
++
-+#ifdef CONFIG_AQUANTIA_PHY_MDI_SWAP
+ aqr107_config_mdi(phydevs[i]);
-+#endif
+
-+ if (priv->fw_dl_mode == FW_DL_GNAGLOAD) {
++ aqr107_set_downshift(phydevs[i],
++ MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
++
++ if (phy_is_started(phydevs[i])) {
+ phydevs[i]->state = PHY_UP;
+ phy_queue_state_machine(phydevs[i], 0);
+ }
-+
-+ /* create a thread for monitor heartbeat status */
-+ if (!priv->heartbeat_thread) {
-+ priv->heartbeat_thread = kthread_create(aqr_firmware_heartbeat_thread,
-+ phydevs[i],
-+ "aqr_firmware_heartbeat_thread");
-+ if (IS_ERR(priv->heartbeat_thread)) {
-+ dev_err(dev,
-+ "%s Failed to create thread for aqr_firmware_heartbeat_thread\n",
-+ __func__);
-+ }
-+ wake_up_process(priv->heartbeat_thread);
-+ }
+ }
+ }
+out:
@@ -1155,13 +1136,14 @@
+ if (priv->fw_initialized == true)
+ return 0;
+
++ spin_lock_init(&priv->lock);
+ priv->fw_dl_mode = FW_DL_SINGLE;
+ priv->phydevs[0] = phydev;
+ priv->heartbeat = -1;
+
+ ret = request_firmware(&fw, AQR_FIRMWARE, dev);
+ if (ret) {
-+ dev_err(dev, "failed to load firmware %s, ret: %d\n",
++ dev_err(dev, "failed to request firmware %s, ret: %d\n",
+ AQR_FIRMWARE, ret);
+ }
+
@@ -1185,7 +1167,7 @@
+ ret = request_firmware_nowait(THIS_MODULE, true, AQR_FIRMWARE, dev,
+ GFP_KERNEL, phydevs, aqr_firmware_download_cb);
+ if (ret) {
-+ dev_err(dev, "failed to load firmware %s, ret: %d\n",
++ dev_err(dev, "failed to request firmware %s, ret: %d\n",
+ AQR_FIRMWARE, ret);
+ }
+ break;
@@ -1214,8 +1196,7 @@
+ "aqr_firmware_gandload_thread");
+ if (IS_ERR(gangload_kthread)) {
+ dev_err(dev,
-+ "%s Failed to create thread for aqr_firmware_gandload_thread\n",
-+ __func__);
++ "failed to create aqr_firmware_gandload_thread\n");
+ return PTR_ERR(gangload_kthread);
+ }
+ wake_up_process(gangload_kthread);
@@ -1223,11 +1204,12 @@
+
+ for (i = 0; i < gangload; i++) {
+ if (gangload_phydevs[i] == phydev) {
-+ dev_err(dev, "Detect duplicate gangload phydev\n");
++ dev_warn(dev, "Detect duplicate gangload phydev\n");
+ return -EINVAL;
+ }
+ }
+
++ spin_lock_init(&priv->lock);
+ priv->fw_dl_mode = FW_DL_GNAGLOAD;
+ priv->heartbeat = -1;
+ gangload_phydevs[gangload] = phydev;
@@ -1247,17 +1229,30 @@
+ return ret;
+}
diff --git a/drivers/net/phy/aquantia_main.c b/drivers/net/phy/aquantia_main.c
-index ac8dd8e..421cdd3 100644
+index a8c828b..d98757f 100644
--- a/drivers/net/phy/aquantia_main.c
+++ b/drivers/net/phy/aquantia_main.c
-@@ -8,6 +8,7 @@
+@@ -8,10 +8,12 @@
*/
-
+
#include <linux/kernel.h>
+#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/bitfield.h>
+ #include <linux/phy.h>
++#include <linux/of.h>
+
+ #include "aquantia.h"
+
+@@ -39,7 +40,6 @@
+ #define MDIO_AN_VEND_PROV_2500BASET_FULL BIT(10)
+ #define MDIO_AN_VEND_PROV_DOWNSHIFT_EN BIT(4)
+ #define MDIO_AN_VEND_PROV_DOWNSHIFT_MASK GENMASK(3, 0)
+-#define MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT 4
+
+ #define MDIO_AN_TX_VEND_STATUS1 0xc800
+ #define MDIO_AN_TX_VEND_STATUS1_RATE_MASK GENMASK(3, 1)
@@ -73,18 +73,6 @@
#define MDIO_AN_RX_VEND_STAT3 0xe832
#define MDIO_AN_RX_VEND_STAT3_AFR BIT(0)
@@ -1309,60 +1304,96 @@
static int aqr107_get_sset_count(struct phy_device *phydev)
{
return AQR107_SGMII_STAT_SZ;
-@@ -498,6 +461,17 @@ static void aqr107_chip_info(struct phy_device *phydev)
+@@ -422,7 +361,7 @@ static int aqr107_get_downshift(struct phy_device *phydev, u8 *data)
+ return 0;
+ }
+
+-static int aqr107_set_downshift(struct phy_device *phydev, u8 cnt)
++int aqr107_set_downshift(struct phy_device *phydev, u8 cnt)
+ {
+ int val = 0;
+
+@@ -482,7 +421,7 @@ static int aqr107_wait_reset_complete(struct phy_device *phydev)
+ return val ? 0 : -ETIMEDOUT;
+ }
+
+-static void aqr107_chip_info(struct phy_device *phydev)
++void aqr107_chip_info(struct phy_device *phydev)
+ {
+ u8 fw_major, fw_minor, build_id, prov_id;
+ int val;
+@@ -505,6 +444,21 @@ static void aqr107_chip_info(struct phy_device *phydev)
fw_major, fw_minor, build_id, prov_id);
}
+int aqr107_config_mdi(struct phy_device *phydev)
+{
-+#ifdef CONFIG_AQUANTIA_PHY_MDI_REVERSED
-+ return phy_modify_mmd(phydev, MDIO_MMD_PMAPMD, PMAPMD_RSVD_VEND_PROV,
-+ PMAPMD_RSVD_VEND_PROV_MDI_CONF, 1);
-+#else
++ struct device_node *np = phydev->mdio.dev.of_node;
++ u16 val;
++
++ if (of_property_read_u16(np, "mdi-reversal", &val))
++ return -ENOENT;
++
++ if (!FIELD_FIT(PMAPMD_RSVD_VEND_PROV_MDI_CONF, val))
++ return -E2BIG;
++
+ return phy_modify_mmd(phydev, MDIO_MMD_PMAPMD, PMAPMD_RSVD_VEND_PROV,
-+ PMAPMD_RSVD_VEND_PROV_MDI_CONF, 0);
-+#endif
++ PMAPMD_RSVD_VEND_PROV_MDI_CONF, val);
+}
+
static int aqr107_config_init(struct phy_device *phydev)
{
int ret;
-@@ -517,6 +491,14 @@ static int aqr107_config_init(struct phy_device *phydev)
+@@ -520,6 +470,12 @@ static int aqr107_config_init(struct phy_device *phydev)
+ ret = aqr107_wait_reset_complete(phydev);
if (!ret)
aqr107_chip_info(phydev);
-
-+#if !defined(CONFIG_AQUANTIA_PHY_FW_DOWNLOAD) && defined(CONFIG_AQUANTIA_PHY_MDI_SWAP)
-+ aqr107_config_mdi(phydev);
-+#endif
-+
+#ifdef CONFIG_AQUANTIA_PHY_FW_DOWNLOAD
-+ aqr_firmware_download(phydev);
++ else
++ return aqr_firmware_download(phydev);
+#endif
+
++ aqr107_config_mdi(phydev);
+
return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
}
+@@ -604,12 +556,39 @@ static void aqr107_link_change_notify(struct phy_device *phydev)
-@@ -605,6 +609,15 @@ static int aqr107_resume(struct phy_device *phydev)
- MDIO_CTRL1_LPOWER);
- }
-
-+static void aqr107_remove(struct phy_device *phydev)
-+{
+ static int aqr107_suspend(struct phy_device *phydev)
+ {
+#ifdef CONFIG_AQUANTIA_PHY_FW_DOWNLOAD
+ struct aqr107_priv *priv = phydev->priv;
+
-+ kthread_stop(priv->heartbeat_thread);
++ spin_lock(&priv->lock);
++ if (priv->heartbeat_thread) {
++ kthread_stop(priv->heartbeat_thread);
++ priv->heartbeat_thread = NULL;
++ priv->heartbeat = -1;
++ }
++ spin_unlock(&priv->lock);
+#endif
-+}
-+
- static int aqr107_probe(struct phy_device *phydev)
- {
- phydev->priv = devm_kzalloc(&phydev->mdio.dev,
-@@ -711,6 +737,7 @@ static struct phy_driver aqr_driver[] = {
- .get_strings = aqr107_get_strings,
- .get_stats = aqr107_get_stats,
- .link_change_notify = aqr107_link_change_notify,
-+ .remove = aqr107_remove,
- },
- };
+ return phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1,
+ MDIO_CTRL1_LPOWER);
+ }
+ static int aqr107_resume(struct phy_device *phydev)
+ {
++#ifdef CONFIG_AQUANTIA_PHY_FW_DOWNLOAD
++ struct aqr107_priv *priv = phydev->priv;
++
++ spin_lock(&priv->lock);
++ if (!priv->heartbeat_thread) {
++ priv->heartbeat_thread = kthread_create(aqr_firmware_heartbeat_thread,
++ phydev,
++ "aqr_firmware_heartbeat_thread");
++ if (IS_ERR(priv->heartbeat_thread)) {
++ phydev_err(phydev,
++ "Failed to create aqr_firmware_heartbeat_thread\n");
++ }
++ wake_up_process(priv->heartbeat_thread);
++ }
++ spin_unlock(&priv->lock);
++#endif
+ return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1,
+ MDIO_CTRL1_LPOWER);
+ }
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9014-drivers-spi-Add-support-for-dynamic-calibration.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9014-drivers-spi-Add-support-for-dynamic-calibration.patch
index 17102ea..750c87b 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9014-drivers-spi-Add-support-for-dynamic-calibration.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9014-drivers-spi-Add-support-for-dynamic-calibration.patch
@@ -11,7 +11,7 @@
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
-@@ -1109,6 +1109,73 @@ static int spi_transfer_wait(struct spi_
+@@ -1109,6 +1109,74 @@ static int spi_transfer_wait(struct spi_
return 0;
}
@@ -22,7 +22,7 @@
+ u8 *buf;
+ int ret;
+ int i;
-+ struct list_head *cal_head, *listptr;
++ struct list_head *pos, *tmp;
+ struct spi_cal_target *target;
+
+ /* Calculate calibration result */
@@ -43,9 +43,8 @@
+ 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);
++ list_for_each_safe(pos, tmp, ctlr->cal_target) {
++ target = list_entry(pos, struct spi_cal_target, list);
+
+ hit = false;
+ hit_val = 0;
@@ -73,8 +72,10 @@
+ dev_warn(&spi->dev, "calibration failed, fallback to default: 0x%x", origin);
+ ret = -EIO;
+ }
++
++ list_del(pos);
++ kfree(target);
+ }
-+ list_del(&target->list);
+
+cal_end:
+ kfree(buf);
@@ -85,7 +86,7 @@
static void _spi_transfer_delay_ns(u32 ns)
{
if (!ns)
-@@ -1720,6 +1787,75 @@ void spi_flush_queue(struct spi_controll
+@@ -1720,6 +1788,75 @@ void spi_flush_queue(struct spi_controll
/*-------------------------------------------------------------------------*/
#if defined(CONFIG_OF)
@@ -161,7 +162,7 @@
static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
struct device_node *nc)
{
-@@ -1841,6 +1977,10 @@ of_register_spi_device(struct spi_contro
+@@ -1841,6 +1978,10 @@ of_register_spi_device(struct spi_contro
if (rc)
goto err_out;