From c27379e93fee03453d3275a4f68fea2277d375c9 Mon Sep 17 00:00:00 2001 From: Aditya Prayoga Date: Mon, 10 Aug 2020 23:22:48 +0700 Subject: [PATCH] Add Helios64 support (#2126) * Add initial Helios64 configuration Add ethernet udev rules Added disable auto power on script during shutdown Configure ALSA to output audio to (DisplayPort) USB type-C armbian-firstrun: exclude helios64 from generating fixed_mac Each network interface on Helios64 already assigned to unique MAC address in factory. Assigning Network Manager with cloned MAC is not needed. Signed-off-by: Aditya Prayoga * u-boot: rk3399: Add Helios64 Use rockchip propriettary loader * kernel: rk3399-legacy: Update r8152 to support 2.5GbE USB RTL8156 Required for Helios64 * kernel: rk3399-legacy: update Rockchip PCIe driver Port changes by ayufan on rockchip64. * kernel: rk3399-legacy: Add support for Helios64 Add Helios64 device tree. Enable missing driver/kernel module. Auto load lm75 modules Signed-off-by: Aditya Prayoga * kernel: rk3399-legacy: rework roc-rk3399-pc patch the patch broken due to additional line added by helios64 on arch/arm64/boot/dts/rockchip/Makefile Signed-off-by: Aditya Prayoga * kernel: rk3399-legacy: update Rockchip PCIe driver Backport bugfix from mainline refer to https://patchwork.kernel.org/patch/11561979/ and https://patchwork.kernel.org/patch/11561977/ Signed-off-by: Aditya Prayoga * kernel: rockchip64-current: Add support for Helios64 Add Helios64 device tree. Enable missing driver/kernel module. * config: helios64: use mainline ATF on current branch and u-boot TPL/SPL instead of Rockchip proprietary loader * helios64: u-boot v2020.07 update * Add Helios64 target * kernel: rk3399-legacy: update Rockchip PCIe driver Removed unrelated changes from porting ayufan fixes Signed-off-by: Piotr Szczepanik * helios64: make use of PACKAGE_LIST* variables Co-authored-by: Piotr Szczepanik --- config/boards/helios64.wip | 9 + config/kernel/linux-rk3399-legacy.config | 26 +- config/kernel/linux-rockchip64-current.config | 7 +- .../families/include/rockchip64_common.inc | 10 + config/sources/families/rk3399.conf | 11 + config/targets.conf | 7 + .../common/usr/lib/armbian/armbian-firstrun | 2 +- .../bsp/helios64/50-usb-realtek-net.rules | 38 + .../helios64/70-keep-usb-lan-as-eth1.rules | 1 + packages/bsp/helios64/asound.conf | 2 + packages/bsp/helios64/disable_auto_poweron | 18 + .../rk3399-legacy/helios64-add-board.patch | 1293 ++ ...ip-0000-scan-bus-fix-from-rockchip64.patch | 241 + ...t-fix-power-stable-and-config-access.patch | 45 + .../roc-rk3399-pc-add-board.patch | 31 +- ...pdate_2.5GBE_usb_rtl8156_to_v2.13.0.patch} | 11539 +++++++++++++--- .../add-board-helios64.patch | 1114 ++ .../add-board-helios64.patch | 2171 +++ ...rk3399-populate-child-node-of-syscon.patch | 31 + 19 files changed, 14593 insertions(+), 2003 deletions(-) create mode 100644 config/boards/helios64.wip create mode 100644 packages/bsp/helios64/50-usb-realtek-net.rules create mode 100644 packages/bsp/helios64/70-keep-usb-lan-as-eth1.rules create mode 100644 packages/bsp/helios64/asound.conf create mode 100755 packages/bsp/helios64/disable_auto_poweron create mode 100644 patch/kernel/rk3399-legacy/helios64-add-board.patch create mode 100644 patch/kernel/rk3399-legacy/pci-host-rockchip-0000-scan-bus-fix-from-rockchip64.patch create mode 100644 patch/kernel/rk3399-legacy/pci-host-rockchip-0001-backport-fix-power-stable-and-config-access.patch rename patch/kernel/rk3399-legacy/{update_2.5GBE_usb_rtl8156_to_v2.12.0.patch.disabled => update_2.5GBE_usb_rtl8156_to_v2.13.0.patch} (52%) create mode 100644 patch/kernel/rockchip64-current/add-board-helios64.patch create mode 100644 patch/u-boot/u-boot-rockchip64-mainline/add-board-helios64.patch create mode 100644 patch/u-boot/u-boot-rockchip64-mainline/rk3399-populate-child-node-of-syscon.patch diff --git a/config/boards/helios64.wip b/config/boards/helios64.wip new file mode 100644 index 0000000000..28bed19bf7 --- /dev/null +++ b/config/boards/helios64.wip @@ -0,0 +1,9 @@ +# RK3399 hexa core 4GB SoC 2.5GbE eMMC USB3 SATA M.2 UPS +BOARD_NAME="Helios64" +BOARDFAMILY="rk3399" +BOOTCONFIG="helios64_defconfig" +KERNEL_TARGET="legacy,current" +MODULES="lm75" +FULL_DESKTOP="yes" +PACKAGE_LIST_BOARD="mdadm i2c-tools" +PACKAGE_LIST_BOARD_REMOVE="fake-hwclock" diff --git a/config/kernel/linux-rk3399-legacy.config b/config/kernel/linux-rk3399-legacy.config index e06e450ae7..875366b1e0 100644 --- a/config/kernel/linux-rk3399-legacy.config +++ b/config/kernel/linux-rk3399-legacy.config @@ -526,7 +526,9 @@ CONFIG_SUSPEND_FREEZER=y # CONFIG_SUSPEND_SKIP_SYNC is not set CONFIG_HAS_WAKELOCK=y CONFIG_WAKELOCK=y -# CONFIG_HIBERNATION is not set +CONFIG_HIBERNATE_CALLBACKS=y +CONFIG_HIBERNATION=y +CONFIG_PM_STD_PARTITION="" CONFIG_PM_SLEEP=y CONFIG_PM_SLEEP_SMP=y # CONFIG_PM_AUTOSLEEP is not set @@ -545,6 +547,7 @@ CONFIG_PM_GENERIC_DOMAINS_SLEEP=y CONFIG_PM_GENERIC_DOMAINS_OF=y CONFIG_CPU_PM=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_HIBERNATION_HEADER=y CONFIG_ARCH_SUSPEND_POSSIBLE=y # @@ -1904,7 +1907,7 @@ CONFIG_DM_MULTIPATH=m CONFIG_DM_MULTIPATH_QL=m CONFIG_DM_MULTIPATH_ST=m CONFIG_DM_DELAY=m -# CONFIG_DM_UEVENT is not set +CONFIG_DM_UEVENT=y CONFIG_DM_FLAKEY=m CONFIG_DM_VERITY=m # CONFIG_DM_VERITY_FEC is not set @@ -2662,7 +2665,7 @@ CONFIG_INPUT_AD714X_SPI=m # CONFIG_INPUT_MMA8450 is not set # CONFIG_INPUT_MPU3050 is not set # CONFIG_INPUT_GP2A is not set -# CONFIG_INPUT_GPIO_BEEPER is not set +CONFIG_INPUT_GPIO_BEEPER=m # CONFIG_INPUT_GPIO_TILT_POLLED is not set CONFIG_INPUT_ATI_REMOTE2=m CONFIG_INPUT_KEYCHORD=m @@ -2940,6 +2943,7 @@ CONFIG_ARCH_REQUIRE_GPIOLIB=y CONFIG_GPIOLIB=y CONFIG_GPIO_DEVRES=y CONFIG_OF_GPIO=y +CONFIG_GPIOLIB_IRQCHIP=y CONFIG_DEBUG_GPIO=y CONFIG_GPIO_SYSFS=y CONFIG_GPIO_GENERIC=y @@ -2966,7 +2970,8 @@ CONFIG_GPIO_GENERIC_PLATFORM=y # CONFIG_GPIO_ADNP is not set # CONFIG_GPIO_MAX7300 is not set # CONFIG_GPIO_MAX732X is not set -# CONFIG_GPIO_PCA953X is not set +CONFIG_GPIO_PCA953X=y +CONFIG_GPIO_PCA953X_IRQ=y # CONFIG_GPIO_PCF857X is not set # CONFIG_GPIO_SX150X is not set @@ -3032,7 +3037,7 @@ CONFIG_W1_SLAVE_BQ27000=m CONFIG_POWER_SUPPLY=y # CONFIG_POWER_SUPPLY_DEBUG is not set # CONFIG_PDA_POWER is not set -# CONFIG_GENERIC_ADC_BATTERY is not set +CONFIG_GENERIC_ADC_BATTERY=m # CONFIG_TEST_POWER is not set CONFIG_BATTERY_DS2760=m # CONFIG_BATTERY_DS2780 is not set @@ -4449,12 +4454,12 @@ CONFIG_SND_SOC_ROCKCHIP_SPDIF=y # CONFIG_SND_SOC_ROCKCHIP_VAD is not set # CONFIG_SND_SOC_ROCKCHIP_DA7219 is not set # CONFIG_SND_SOC_ROCKCHIP_HDMI_ANALOG is not set -# CONFIG_SND_SOC_ROCKCHIP_HDMI_DP is not set +CONFIG_SND_SOC_ROCKCHIP_HDMI_DP=m CONFIG_SND_SOC_ROCKCHIP_MAX98090=m # CONFIG_SND_SOC_ROCKCHIP_MULTICODECS is not set CONFIG_SND_SOC_ROCKCHIP_RT5645=y # CONFIG_SND_SOC_ROCKCHIP_RT5651_TC358749 is not set -# CONFIG_SND_SOC_ROCKCHIP_CDNDP is not set +CONFIG_SND_SOC_ROCKCHIP_CDNDP=m # # Allwinner SoC Audio support @@ -5007,7 +5012,7 @@ CONFIG_USB_G_WEBCAM=m # # CONFIG_USB20_HOST is not set # CONFIG_USB20_OTG is not set -# CONFIG_USB_LED_TRIG is not set +CONFIG_USB_LED_TRIG=y # CONFIG_UWB is not set CONFIG_MMC=y # CONFIG_MMC_DEBUG is not set @@ -5534,7 +5539,8 @@ CONFIG_ROCKCHIP_OPP=y # CONFIG_ROCKCHIP_PM_TEST is not set CONFIG_ROCKCHIP_GRF=y CONFIG_ROCKCHIP_PM_DOMAINS=y -# CONFIG_ROCKCHIP_PVTM is not set +CONFIG_ROCKCHIP_PVTM=y +CONFIG_ROCKCHIP_SUSPEND_MODE=y CONFIG_ROCKCHIP_SYSTEM_MONITOR=y # CONFIG_ROCKCHIP_VENDOR_STORAGE_UPDATE_LOADER is not set # CONFIG_SUNXI_SRAM is not set @@ -5887,7 +5893,7 @@ CONFIG_RK_FLASH=m CONFIG_ARM_PSCI_FW=y # CONFIG_FIRMWARE_MEMMAP is not set CONFIG_HAVE_ARM_SMCCC=y -# CONFIG_ROCKCHIP_SIP is not set +CONFIG_ROCKCHIP_SIP=y # CONFIG_ACPI is not set # diff --git a/config/kernel/linux-rockchip64-current.config b/config/kernel/linux-rockchip64-current.config index 2c48153798..0208a8d5c1 100644 --- a/config/kernel/linux-rockchip64-current.config +++ b/config/kernel/linux-rockchip64-current.config @@ -3397,7 +3397,7 @@ CONFIG_INPUT_MSM_VIBRATOR=m CONFIG_INPUT_MAX77650_ONKEY=m # CONFIG_INPUT_MMA8450 is not set # CONFIG_INPUT_GP2A is not set -# CONFIG_INPUT_GPIO_BEEPER is not set +CONFIG_INPUT_GPIO_BEEPER=m CONFIG_INPUT_GPIO_DECODER=m CONFIG_INPUT_GPIO_VIBRA=m # CONFIG_INPUT_ATI_REMOTE2 is not set @@ -3836,7 +3836,8 @@ CONFIG_GPIO_ADNP=m CONFIG_GPIO_GW_PLD=m CONFIG_GPIO_MAX7300=m CONFIG_GPIO_MAX732X=m -CONFIG_GPIO_PCA953X=m +CONFIG_GPIO_PCA953X=y +CONFIG_GPIO_PCA953X_IRQ=y CONFIG_GPIO_PCF857X=m CONFIG_GPIO_TPIC2810=m # end of I2C GPIO expanders @@ -3938,7 +3939,7 @@ CONFIG_POWER_SUPPLY=y # CONFIG_POWER_SUPPLY_DEBUG is not set CONFIG_POWER_SUPPLY_HWMON=y # CONFIG_PDA_POWER is not set -# CONFIG_GENERIC_ADC_BATTERY is not set +CONFIG_GENERIC_ADC_BATTERY=m # CONFIG_TEST_POWER is not set CONFIG_CHARGER_ADP5061=m CONFIG_BATTERY_CW2015=m diff --git a/config/sources/families/include/rockchip64_common.inc b/config/sources/families/include/rockchip64_common.inc index bf98ed5a23..18dacad2e7 100644 --- a/config/sources/families/include/rockchip64_common.inc +++ b/config/sources/families/include/rockchip64_common.inc @@ -298,6 +298,16 @@ family_tweaks_bsp() cp $SRC/packages/bsp/pinebook-pro/xorg.conf $destination/etc/X11/ fi + if [[ $BOARD == helios64 ]]; then + + mkdir -p $destination/etc/udev/rules.d/ + mkdir -p $destination/lib/systemd/system-shutdown/ + cp $SRC/packages/bsp/helios64/50-usb-realtek-net.rules $destination/etc/udev/rules.d/ + cp $SRC/packages/bsp/helios64/70-keep-usb-lan-as-eth1.rules $destination/etc/udev/rules.d/ + cp $SRC/packages/bsp/helios64/asound.conf $destination/etc/ + install -m 755 $SRC/packages/bsp/helios64/disable_auto_poweron $destination/lib/systemd/system-shutdown/ + fi + # Graphics and media mkdir -p $destination/etc/udev/rules.d cp $SRC/packages/bsp/rk3399/50-mali.rules $destination/etc/udev/rules.d/ diff --git a/config/sources/families/rk3399.conf b/config/sources/families/rk3399.conf index 2f5c2d9849..ac3dee9f91 100644 --- a/config/sources/families/rk3399.conf +++ b/config/sources/families/rk3399.conf @@ -20,6 +20,17 @@ if [[ $BOARD == roc-rk3399-pc ]]; then BOOT_USE_MAINLINE_ATF=yes +elif [[ $BOARD == helios64 ]]; then + + if [[ $BRANCH == legacy ]]; then + BOOT_USE_BLOBS=yes + DDR_BLOB='rk33/rk3399_ddr_933MHz_v1.24.bin' + MINILOADER_BLOB='rk33/rk3399_miniloader_v1.19.bin' + BL31_BLOB='rk33/rk3399_bl31_v1.30.elf' + else + BOOT_USE_MAINLINE_ATF=yes + fi + elif [[ $BOARD == nanopim4v2 || $BOARD == orangepi4 ]]; then BOOT_USE_BLOBS=yes diff --git a/config/targets.conf b/config/targets.conf index f2ab818505..041d4f6f0b 100644 --- a/config/targets.conf +++ b/config/targets.conf @@ -83,6 +83,13 @@ helios4 current focal cli stable yes helios4 current bullseye cli stable yes helios4 current focal cli beta yes +# Helios64 +helios64 legacy buster cli stable yes +helios64 current buster cli stable yes +helios64 current bionic cli stable yes +helios64 current focal cli stable yes +helios64 current bullseye cli stable yes + # Clearfog Base clearfogbase legacy buster cli stable no clearfogbase current buster cli stable yes diff --git a/packages/bsp/common/usr/lib/armbian/armbian-firstrun b/packages/bsp/common/usr/lib/armbian/armbian-firstrun index 93b537a2d7..2f52318a5b 100755 --- a/packages/bsp/common/usr/lib/armbian/armbian-firstrun +++ b/packages/bsp/common/usr/lib/armbian/armbian-firstrun @@ -131,7 +131,7 @@ case "$1" in esac # varios temporary hardware workarounds - [[ $LINUXFAMILY == rk3399 || $LINUXFAMILY == rockchip64 ]] && set_fixed_mac + [[ $LINUXFAMILY == rk3399 || $LINUXFAMILY == rockchip64 ]] && [[ $BOARD != helios64 ]] && set_fixed_mac [[ $BRANCH == dev && $LINUXFAMILY == rockchip ]] && set_fixed_mac [[ $BRANCH == current && $LINUXFAMILY == odroidc1 ]] && set_fixed_mac [[ $LINUXFAMILY == meson64 ]] && set_fixed_mac diff --git a/packages/bsp/helios64/50-usb-realtek-net.rules b/packages/bsp/helios64/50-usb-realtek-net.rules new file mode 100644 index 0000000000..71c996157f --- /dev/null +++ b/packages/bsp/helios64/50-usb-realtek-net.rules @@ -0,0 +1,38 @@ +# This is used to change the default configuration of Realtek USB ethernet adapters + +ACTION!="add", GOTO="usb_realtek_net_end" +SUBSYSTEM!="usb", GOTO="usb_realtek_net_end" +ENV{DEVTYPE}!="usb_device", GOTO="usb_realtek_net_end" + +# Modify this to change the default value +ENV{REALTEK_NIC_MODE}="1" + +# Realtek +ATTR{idVendor}=="0bda", ATTR{idProduct}=="8156", ATTR{bConfigurationValue}!="$env{REALTEK_NIC_MODE}", ATTR{bConfigurationValue}="$env{REALTEK_NIC_MODE}" +ATTR{idVendor}=="0bda", ATTR{idProduct}=="8153", ATTR{bConfigurationValue}!="$env{REALTEK_NIC_MODE}", ATTR{bConfigurationValue}="$env{REALTEK_NIC_MODE}" +ATTR{idVendor}=="0bda", ATTR{idProduct}=="8152", ATTR{bConfigurationValue}!="$env{REALTEK_NIC_MODE}", ATTR{bConfigurationValue}="$env{REALTEK_NIC_MODE}" + +# Samsung +ATTR{idVendor}=="04e8", ATTR{idProduct}=="a101", ATTR{bConfigurationValue}!="$env{REALTEK_NIC_MODE}", ATTR{bConfigurationValue}="$env{REALTEK_NIC_MODE}" + +# Lenovo +ATTR{idVendor}=="17ef", ATTR{idProduct}=="304f", ATTR{bConfigurationValue}!="$env{REALTEK_NIC_MODE}", ATTR{bConfigurationValue}="$env{REALTEK_NIC_MODE}" +ATTR{idVendor}=="17ef", ATTR{idProduct}=="3052", ATTR{bConfigurationValue}!="$env{REALTEK_NIC_MODE}", ATTR{bConfigurationValue}="$env{REALTEK_NIC_MODE}" +ATTR{idVendor}=="17ef", ATTR{idProduct}=="3054", ATTR{bConfigurationValue}!="$env{REALTEK_NIC_MODE}", ATTR{bConfigurationValue}="$env{REALTEK_NIC_MODE}" +ATTR{idVendor}=="17ef", ATTR{idProduct}=="3057", ATTR{bConfigurationValue}!="$env{REALTEK_NIC_MODE}", ATTR{bConfigurationValue}="$env{REALTEK_NIC_MODE}" +ATTR{idVendor}=="17ef", ATTR{idProduct}=="3082", ATTR{bConfigurationValue}!="$env{REALTEK_NIC_MODE}", ATTR{bConfigurationValue}="$env{REALTEK_NIC_MODE}" +ATTR{idVendor}=="17ef", ATTR{idProduct}=="7205", ATTR{bConfigurationValue}!="$env{REALTEK_NIC_MODE}", ATTR{bConfigurationValue}="$env{REALTEK_NIC_MODE}" +ATTR{idVendor}=="17ef", ATTR{idProduct}=="720a", ATTR{bConfigurationValue}!="$env{REALTEK_NIC_MODE}", ATTR{bConfigurationValue}="$env{REALTEK_NIC_MODE}" +ATTR{idVendor}=="17ef", ATTR{idProduct}=="720b", ATTR{bConfigurationValue}!="$env{REALTEK_NIC_MODE}", ATTR{bConfigurationValue}="$env{REALTEK_NIC_MODE}" +ATTR{idVendor}=="17ef", ATTR{idProduct}=="720c", ATTR{bConfigurationValue}!="$env{REALTEK_NIC_MODE}", ATTR{bConfigurationValue}="$env{REALTEK_NIC_MODE}" +ATTR{idVendor}=="17ef", ATTR{idProduct}=="721e", ATTR{bConfigurationValue}!="$env{REALTEK_NIC_MODE}", ATTR{bConfigurationValue}="$env{REALTEK_NIC_MODE}" +ATTR{idVendor}=="17ef", ATTR{idProduct}=="a359", ATTR{bConfigurationValue}!="$env{REALTEK_NIC_MODE}", ATTR{bConfigurationValue}="$env{REALTEK_NIC_MODE}" +ATTR{idVendor}=="17ef", ATTR{idProduct}=="a387", ATTR{bConfigurationValue}!="$env{REALTEK_NIC_MODE}", ATTR{bConfigurationValue}="$env{REALTEK_NIC_MODE}" + +# TP-LINK +ATTR{idVendor}=="2357", ATTR{idProduct}=="0601", ATTR{bConfigurationValue}!="$env{REALTEK_NIC_MODE}", ATTR{bConfigurationValue}="$env{REALTEK_NIC_MODE}" + +# Nvidia +ATTR{idVendor}=="0955", ATTR{idProduct}=="09ff", ATTR{bConfigurationValue}!="$env{REALTEK_NIC_MODE}", ATTR{bConfigurationValue}="$env{REALTEK_NIC_MODE}" + +LABEL="usb_realtek_net_end" diff --git a/packages/bsp/helios64/70-keep-usb-lan-as-eth1.rules b/packages/bsp/helios64/70-keep-usb-lan-as-eth1.rules new file mode 100644 index 0000000000..532abd14b8 --- /dev/null +++ b/packages/bsp/helios64/70-keep-usb-lan-as-eth1.rules @@ -0,0 +1 @@ +SUBSYSTEM=="net", ACTION=="add", DRIVERS=="r8152", KERNEL=="eth1", NAME="eth1" diff --git a/packages/bsp/helios64/asound.conf b/packages/bsp/helios64/asound.conf new file mode 100644 index 0000000000..2fb7768c9e --- /dev/null +++ b/packages/bsp/helios64/asound.conf @@ -0,0 +1,2 @@ +defaults.pcm.!card rkhdmidpsound +defaults.ctl.!card rkhdmidpsound diff --git a/packages/bsp/helios64/disable_auto_poweron b/packages/bsp/helios64/disable_auto_poweron new file mode 100755 index 0000000000..4f511969bb --- /dev/null +++ b/packages/bsp/helios64/disable_auto_poweron @@ -0,0 +1,18 @@ +#!/bin/bash + +# Export GPIO +# AUTO_ON_D +echo 153 > /sys/class/gpio/export +# AUTO_EN_CLK +echo 154 > /sys/class/gpio/export + +echo out > /sys/class/gpio/gpio153/direction +echo out > /sys/class/gpio/gpio154/direction + +# Toggling the D Flip-Flop +echo 0 > /sys/class/gpio/gpio153/value +echo 0 > /sys/class/gpio/gpio154/value +sleep 0.1 +echo 1 > /sys/class/gpio/gpio154/value +sleep 0.1 +echo 0 > /sys/class/gpio/gpio154/value diff --git a/patch/kernel/rk3399-legacy/helios64-add-board.patch b/patch/kernel/rk3399-legacy/helios64-add-board.patch new file mode 100644 index 0000000000..774288be69 --- /dev/null +++ b/patch/kernel/rk3399-legacy/helios64-add-board.patch @@ -0,0 +1,1293 @@ +From 022ada1465cac946e17097ea3f9b9715f66494de Mon Sep 17 00:00:00 2001 +From: Aditya Prayoga +Date: Tue, 28 Jul 2020 11:30:39 +0700 +Subject: [PATCH] Add Helios64 board device tree + +Signed-off-by: Aditya Prayoga +--- + arch/arm64/boot/dts/rockchip/Makefile | 1 + + .../boot/dts/rockchip/rk3399-helios64.dts | 1260 +++++++++++++++++ + 2 files changed, 1261 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-helios64.dts + +diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile +index 270c0c62..adfa8211 100644 +--- a/arch/arm64/boot/dts/rockchip/Makefile ++++ b/arch/arm64/boot/dts/rockchip/Makefile +@@ -14,6 +14,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \ + rk3399-nanopi4-rev21.dtb \ + rk3399-nanopi-m4v2.dtb \ + rk3399-nanopi4-rev22.dtb \ ++ rk3399-helios64.dtb \ + rk3399-firefly.dtb + + dtb-$(CONFIG_ARCH_ROCKCHIP) += \ +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-helios64.dts b/arch/arm64/boot/dts/rockchip/rk3399-helios64.dts +new file mode 100644 +index 00000000..d4248a01 +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3399-helios64.dts +@@ -0,0 +1,1260 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (c) 2020 Aditya Prayoga (aditya@kobol.io) ++ */ ++ ++/dts-v1/; ++#include ++#include ++#include ++#include "rk3399.dtsi" ++#include "rk3399-opp.dtsi" ++#include "rk3399-linux.dtsi" ++ ++/ { ++ model = "Helios64"; ++ compatible = "kobol,helios64", "rockchip,rk3399"; ++ ++ adc-keys { ++ compatible = "adc-keys"; ++ io-channels = <&saradc 1>; ++ io-channel-names = "buttons"; ++ keyup-threshold-microvolt = <1800000>; ++ poll-interval = <100>; ++ ++ user2-button { ++ label = "User Button 2"; ++ linux,code = ; ++ press-threshold-microvolt = <100000>; ++ }; ++ }; ++ ++ aliases { ++ spi0 = &spi1; ++ spi1 = &spi2; ++ spi2 = &spi5; ++ ethernet0 = &gmac; ++ ethernet1 = &usb_lan; ++ }; ++ ++ beeper: beeper { ++ compatible = "gpio-beeper"; ++ gpios = <&gpio4 RK_PD3 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ clkin_gmac: external-gmac-clock { ++ compatible = "fixed-clock"; ++ clock-frequency = <125000000>; ++ clock-output-names = "clkin_gmac"; ++ #clock-cells = <0>; ++ }; ++ ++ /* first 64k(0xff8c0000~0xff8d0000) for ddr and suspend */ ++ iram: sram@ff8d0000 { ++ compatible = "mmio-sram"; ++ reg = <0x0 0xff8d0000 0x0 0x20000>; /* 128k */ ++ }; ++ ++ ion { ++ compatible = "rockchip,ion"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cma-heap { ++ reg = <0x00000000 0x02000000>; ++ }; ++ ++ system-heap { ++ }; ++ }; ++ ++ vcc12v_dcin: vcc12v-dcin { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc12v_dcin"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ }; ++ ++ vcc12v_dcin_bkup: vcc12v-dcin-bkup { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc12v_dcin_bkup"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ vin-supply = <&vcc12v_dcin>; ++ }; ++ ++ vcc12v_hdd: vcc12v-hdd { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc12v_hdd"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ vin-supply = <&vcc12v_dcin_bkup>; ++ }; ++ ++ /* switched by pmic_sleep */ ++ vcc1v8_sys_s0: vcc1v8-sys-s0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc1v8_sys_s0"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ vin-supply = <&vcc1v8_sys_s3>; ++ }; ++ ++ vcc0v9_s3: vcc0v9-s3 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc0v9_s3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ vin-supply = <&vcc3v3_sys_s3>; ++ }; ++ ++ avdd_0v9_s0: avdd-0v9-s0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "avdd_0v9_s0"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ vin-supply = <&vcc1v8_sys_s3>; ++ }; ++ ++ avdd_1v8_s0: avdd-1v8-s0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "avdd_1v8_s0"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ vin-supply = <&vcc3v3_sys_s3>; ++ }; ++ ++ pcie_power: pcie-power { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio1 RK_PD0 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie_pwr_en>; ++ regulator-name = "pcie_power"; ++ regulator-boot-on; ++ startup-delay-us = <10000>; ++ vin-supply = <&vcc5v0_perdev>; ++ }; ++ ++ vcc3v3_sys_s3: vcc_lan: vcc3v3-sys-s3 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v3_sys_s3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc5v0_sys>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc3v0_sd: vcc3v0-sd { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0_pwr_h>; ++ regulator-name = "vcc3v0_sd"; ++ regulator-always-on; ++ regulator-boot-on; ++ startup-delay-us = <20000>; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ vin-supply = <&vcc3v3_sys_s3>; ++ }; ++ ++ vcc5v0_usb: vcc5v0-usb { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio1 RK_PC6 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vcc5v0_usb_en>; ++ regulator-name = "vcc5v0_usb"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc5v0_perdev>; ++ }; ++ ++ vcc5v0_perdev: vcc5v0-perdev { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_perdev"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc12v_dcin_bkup>; ++ }; ++ ++ vcc5v0_hdd: vcc5v0-hdd { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_hdd"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc12v_dcin_bkup>; ++ }; ++ ++ vcc5v0_sys: vcc5v0-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc12v_dcin_bkup>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vdd_log: vdd-log { ++ compatible = "pwm-regulator"; ++ pwms = <&pwm2 0 25000 1>; ++ regulator-name = "vdd_log"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <1400000>; ++ vin-supply = <&vcc5v0_sys>; ++ ++ /* for rockchip boot on */ ++ rockchip,pwm_id = <2>; ++ rockchip,pwm_voltage = <1000000>; ++ }; ++ ++ power_hdd_a: power-hdd-a { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hdd_a_power>; ++ regulator-name = "power_hdd_a"; ++ regulator-always-on; ++ regulator-boot-on; ++ startup-delay-us = <2000000>; ++ }; ++ ++ power_hdd_b: power-hdd-b { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio1 RK_PA1 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hdd_b_power>; ++ regulator-name = "power_hdd_b"; ++ regulator-always-on; ++ regulator-boot-on; ++ startup-delay-us = <2000000>; ++ }; ++ ++ usblan_power: usblan-power { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio1 RK_PC7 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usb_lan_en>; ++ regulator-name = "usblan_power"; ++ regulator-always-on; ++ regulator-boot-on; ++ vin-supply = <&vcc5v0_usb>; ++ }; ++ ++ fan1: p7-fan { ++ compatible = "pwm-fan"; ++ pwms = <&pwm0 0 40000 0>; ++ cooling-min-state = <0>; ++ cooling-max-state = <3>; ++ #cooling-cells = <2>; ++ cooling-levels = <0 80 170 255>; ++ }; ++ ++ fan2: p6-fan { ++ compatible = "pwm-fan"; ++ pwms = <&pwm1 0 40000 0>; ++ cooling-min-state = <0>; ++ cooling-max-state = <3>; ++ #cooling-cells = <2>; ++ cooling-levels = <0 80 170 255>; ++ }; ++ ++ gpio-charger { ++ compatible = "gpio-charger"; ++ charger-type = "mains"; ++ gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; ++ charge-status-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ac_present_ap>, <&charger_status>; ++ }; ++ ++ gpio-keys { ++ compatible = "gpio-keys"; ++ autorepeat; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwrbtn>, <&user1btn>, <&wake_on_lan>; ++ ++ power { ++ debounce-interval = <100>; ++ gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>; ++ label = "Power"; ++ linux,code = ; ++ wakeup-source; ++ }; ++ ++ user1-button { ++ debounce-interval = <100>; ++ gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_LOW>; ++ label = "User Button 1"; ++ linux,code = ; ++ }; ++ }; ++ ++ hdmi_dp_sound: hdmi-dp-sound { ++ status = "okay"; ++ compatible = "rockchip,rk3399-hdmi-dp"; ++ rockchip,cpu = <&i2s2>; ++ rockchip,codec = <&cdn_dp>; ++ }; ++ ++ io_leds: io-gpio-leds { ++ status = "okay"; ++ compatible = "gpio-leds"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&network_act>, <&usb3_act>, ++ <&sata_act>, <&sata_err_led>; ++ ++ network { ++ label = "helios64:blue:net"; ++ gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "netdev"; ++ default-state = "off"; ++ }; ++ ++ sata { ++ label = "helios64:blue:hdd-status"; ++ gpios = <&gpio4 RK_PD4 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "disk-activity"; ++ default-state = "off"; ++ }; ++ ++ sata_err1 { ++ label = "helios64:red:ata1-err"; ++ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_HIGH>; ++ default-state = "keep"; ++ }; ++ ++ sata_err2 { ++ label = "helios64:red:ata2-err"; ++ gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_HIGH>; ++ default-state = "keep"; ++ }; ++ ++ sata_err3 { ++ label = "helios64:red:ata3-err"; ++ gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_HIGH>; ++ default-state = "keep"; ++ }; ++ ++ sata_err4 { ++ label = "helios64:red:ata4-err"; ++ gpios = <&gpio2 RK_PA5 GPIO_ACTIVE_HIGH>; ++ default-state = "keep"; ++ }; ++ ++ sata_err5 { ++ label = "helios64:red:ata5-err"; ++ gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_HIGH>; ++ default-state = "keep"; ++ }; ++ ++ usb3 { ++ label = "helios64:blue:usb3"; ++ gpios = <&gpio0 RK_PB3 GPIO_ACTIVE_HIGH>; ++ trigger-sources = <&int_hub_port1>, ++ <&int_hub_port2>, ++ <&int_hub_port3>; ++ linux,default-trigger = "usbport"; ++ default-state = "off"; ++ }; ++ }; ++ ++ pwmleds { ++ compatible = "pwm-leds"; ++ status = "okay"; ++ ++ power-led { ++ label = "helios64:blue:power-status"; ++ pwms = <&pwm3 0 2000000000 0>; ++ max-brightness = <255>; ++ }; ++ }; ++ ++ system_leds: system-gpio-leds { ++ status = "okay"; ++ compatible = "gpio-leds"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&system_led>; ++ ++ status-led { ++ label = "helios64::status"; ++ gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "none"; ++ default-state = "on"; ++ mode = <0x23>; ++ }; ++ ++ fault-led { ++ label = "helios64:red:fault"; ++ gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "none"; ++ default-state = "keep"; ++ mode = <0x23>; ++ }; ++ }; ++}; ++ ++&cdn_dp { ++ status = "okay"; ++ extcon = <&fusb0>; ++ phys = <&tcphy0_dp>; ++}; ++ ++&cpu_l0 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_l1 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_l2 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_l3 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_b0 { ++ cpu-supply = <&vdd_cpu_b>; ++}; ++ ++&cpu_b1 { ++ cpu-supply = <&vdd_cpu_b>; ++}; ++ ++&dfi { ++ status = "okay"; ++}; ++ ++&display_subsystem { ++ status = "okay"; ++ ++ route { ++ route_dp: route-dp { ++ status = "okay"; ++ logo,uboot = "logo.bmp"; ++ logo,kernel = "logo_kernel.bmp"; ++ logo,mode = "center"; ++ charge_logo,mode = "center"; ++ connect = <&vopl_out_dp>; ++ }; ++ }; ++}; ++ ++&dmc { ++ status = "okay"; ++ center-supply = <&vdd_center>; ++ upthreshold = <40>; ++ downdifferential = <20>; ++ system-status-freq = < ++ /*system status freq(KHz)*/ ++ SYS_STATUS_NORMAL 933000 ++ SYS_STATUS_REBOOT 400000 ++ SYS_STATUS_SUSPEND 400000 ++ SYS_STATUS_VIDEO_1080P 416000 ++ SYS_STATUS_VIDEO_4K 933000 ++ SYS_STATUS_VIDEO_4K_10B 933000 ++ SYS_STATUS_PERFORMANCE 933000 ++ SYS_STATUS_BOOST 416000 ++ SYS_STATUS_DUALVIEW 856000 ++ SYS_STATUS_ISP 856000 ++ >; ++ vop-bw-dmc-freq = < ++ /* min_bw(MB/s) max_bw(MB/s) freq(KHz) */ ++ 0 1893 416000 ++ 1894 99999 856000 ++ >; ++ auto-min-freq = <400000>; ++}; ++ ++&dmc_opp_table { ++ opp-416000000 { ++ opp-hz = /bits/ 64 <416000000>; ++ opp-microvolt = <900000>; ++ }; ++ opp-528000000 { ++ status = "disable"; ++ }; ++ opp-856000000 { ++ opp-hz = /bits/ 64 <856000000>; ++ opp-microvolt = <900000>; ++ }; ++}; ++ ++&emmc_phy { ++ status = "okay"; ++}; ++ ++&gmac { ++ assigned-clocks = <&cru SCLK_RMII_SRC>; ++ assigned-clock-parents = <&clkin_gmac>; ++ clock_in_out = "input"; ++ phy-supply = <&vcc_lan>; ++ phy-mode = "rgmii"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rgmii_pins &rgmii_phy_reset>; ++ //rockchip,bugged_tx_coe; ++ //disable,wake-on-lan; // device does not resume ++ snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; ++ snps,reset-active-low; ++ snps,reset-delays-us = <0 10000 50000>; ++ tx_delay = <0x28>; ++ rx_delay = <0x20>; ++ status = "okay"; ++}; ++ ++&gpu { ++ status = "okay"; ++ mali-supply = <&vdd_gpu>; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ i2c-scl-rising-time-ns = <168>; ++ i2c-scl-falling-time-ns = <4>; ++ clock-frequency = <400000>; ++ ++ rk808: pmic@1b { ++ compatible = "rockchip,rk808"; ++ reg = <0x1b>; ++ interrupt-parent = <&gpio0>; ++ interrupts = <10 IRQ_TYPE_LEVEL_LOW>; ++ #clock-cells = <1>; ++ clock-output-names = "xin32k", "rk808-clkout2"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int_l>; ++ rockchip,system-power-controller; ++ wakeup-source; ++ ++ vcc1-supply = <&vcc5v0_sys>; ++ vcc2-supply = <&vcc5v0_sys>; ++ vcc3-supply = <&vcc5v0_sys>; ++ vcc4-supply = <&vcc5v0_sys>; ++ vcc6-supply = <&vcc5v0_sys>; ++ vcc7-supply = <&vcc5v0_sys>; ++ vcc8-supply = <&vcc3v3_sys_s3>; ++ vcc9-supply = <&vcc5v0_sys>; ++ vcc10-supply = <&vcc5v0_sys>; ++ vcc11-supply = <&vcc5v0_sys>; ++ vcc12-supply = <&vcc3v3_sys_s3>; ++ vddio-supply = <&vcc3v0_s3>; ++ ++ regulators { ++ vdd_center: DCDC_REG1 { ++ regulator-name = "vdd_center"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_cpu_l: DCDC_REG2 { ++ regulator-name = "vdd_cpu_l"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_ddr_s3: DCDC_REG3 { ++ regulator-name = "vcc_ddr_s3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc1v8_sys_s3: DCDC_REG4 { ++ regulator-name = "vcc1v8_sys_s3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ /* not used */ ++ vcc1v8_dvp: LDO_REG1 { ++ regulator-name = "vcc1v8_dvp"; ++ }; ++ ++ /* not used */ ++ vcc3v0_touch: LDO_REG2 { ++ regulator-name = "vcc3v0_touch"; ++ }; ++ ++ vcc1v8_s3: LDO_REG3 { ++ regulator-name = "vcc1v8_s3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc_sdio_s0: LDO_REG4 { ++ regulator-name = "vcc_sdio_s0"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++// regulator-state-mem { ++// regulator-on-in-suspend; ++// regulator-suspend-microvolt = <3300000>; ++// }; ++ }; ++ ++ /* not used */ ++ vcca3v0_codec: LDO_REG5 { ++ regulator-name = "vcca3v0_codec"; ++ }; ++ ++ vcc1v5_s3: LDO_REG6 { ++ regulator-name = "vcc1v5_s3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1500000>; ++ regulator-max-microvolt = <1500000>; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1500000>; ++ }; ++ }; ++ ++ /* not used */ ++ vcca1v8_codec: LDO_REG7 { ++ regulator-name = "vcca1v8_codec"; ++ }; ++ ++ vcc3v0_s3: LDO_REG8 { ++ regulator-name = "vcc3v0_s3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3000000>; ++ }; ++ }; ++ ++ vcc3v3_sys_s0: SWITCH_REG1 { ++ regulator-name = "vcc3v3_sys_s0"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ /* not used */ ++ vcc3v3_s0: SWITCH_REG2 { ++ regulator-name = "vcc3v3_s0"; ++ }; ++ }; ++ }; ++ ++ vdd_cpu_b: regulator@40 { ++ compatible = "silergy,syr827"; ++ reg = <0x40>; ++ fcs,suspend-voltage-selector = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vsel1_gpio>; ++ vsel-gpios = <&gpio1 RK_PC1 GPIO_ACTIVE_HIGH>; ++ regulator-compatible = "fan53555-reg"; ++ regulator-name = "vdd_cpu_b"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1500000>; ++ regulator-ramp-delay = <1000>; ++ regulator-always-on; ++ regulator-boot-on; ++ vin-supply = <&vcc5v0_sys>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_gpu: regulator@41 { ++ compatible = "silergy,syr828"; ++ reg = <0x41>; ++ fcs,suspend-voltage-selector = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vsel2_gpio>; ++ vsel-gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_HIGH>; ++ regulator-compatible = "fan53555-reg"; ++ regulator-name = "vdd_gpu"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1500000>; ++ regulator-ramp-delay = <1000>; ++ regulator-always-on; ++ regulator-boot-on; ++ vin-supply = <&vcc5v0_sys>; ++ regulator-initial-mode = <1>; /* 1:force PWM 2:auto */ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++}; ++ ++&i2c2 { ++ clock-frequency = <400000>; ++ i2c-scl-rising-time-ns = <160>; ++ i2c-scl-falling-time-ns = <30>; ++ status = "okay"; ++ ++ gpio-expander@20 { ++ compatible = "nxp,pca9555"; ++ reg = <0x20>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pca0_pins>; ++ interrupt-parent = <&gpio0>; ++ interrupts = <9 IRQ_TYPE_EDGE_FALLING>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ vcc-supply = <&vcc3v3_sys_s3>; ++ }; ++ ++ temp@4c { ++ compatible = "onnn,lm75"; ++ reg = <0x4c>; ++ vcc-supply = <&vcc3v3_sys_s0>; ++ }; ++}; ++ ++&i2c4 { ++ status = "okay"; ++ i2c-scl-rising-time-ns = <160>; ++ i2c-scl-falling-time-ns = <30>; ++ clock-frequency = <400000>; ++ ++ fusb0: typec-portc@22 { ++ compatible = "fairchild,fusb302"; ++ reg = <0x22>; ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&fusb0_int>, <&fusb0_vbus_en>; ++ vbus-5v-gpios = <&gpio1 RK_PA3 GPIO_ACTIVE_HIGH>; ++ int-n-gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>; ++ fusb302,role = "ROLE_MODE_DRP"; ++ fusb302,try_role = "ROLE_MODE_UFP"; ++ }; ++}; ++ ++/* I2C on UEXT */ ++&i2c7 { ++ status = "okay"; ++}; ++ ++/* External I2C */ ++&i2c8 { ++ status = "okay"; ++}; ++ ++&i2s2 { ++ #sound-dai-cells = <0>; ++ status = "okay"; ++}; ++ ++&io_domains { ++ status = "okay"; ++ bt656-supply = <&vcc1v8_sys_s0>; ++ audio-supply = <&vcc1v8_sys_s0>; ++ sdmmc-supply = <&vcc_sdio_s0>; ++ gpio1830-supply = <&vcc3v0_s3>; ++}; ++ ++&pcie0 { ++ bus-scan-delay-ms = <2000>; ++ ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>; ++ num-lanes = <2>; ++ max-link-speed = <2>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie_prst &pcie_clkreqn>; ++ vpcie12v-supply = <&vcc12v_dcin>; ++ vpcie3v3-supply = <&pcie_power>; ++ vpcie1v8-supply = <&avdd_1v8_s0>; ++ vpcie0v9-supply = <&avdd_0v9_s0>; ++ status = "okay"; ++}; ++ ++&pcie_phy { ++ status = "okay"; ++ assigned-clocks = <&cru SCLK_PCIEPHY_REF>; ++ assigned-clock-parents = <&cru SCLK_PCIEPHY_REF100M>; ++ assigned-clock-rates = <100000000>; ++}; ++ ++&pinctrl { ++ buttons { ++ pwrbtn: pwrbtn { ++ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ ++ user1btn: usr1btn { ++ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ charger { ++ ac_present_ap: ac-present-ap { ++ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ charger_status: charger-status { ++ rockchip,pins = <2 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ fan { ++ fan1_sense: fan1-sense { ++ rockchip,pins = <4 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ fan2_sense: fan2-sense { ++ rockchip,pins = <4 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ fusb30x { ++ fusb0_int: fusb0-int { ++ rockchip,pins = ++ <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ ++ fusb0_vbus_en: fusb0-vbus-en { ++ rockchip,pins = ++ <1 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ gmac { ++ rgmii_phy_reset: rgmii-phy-reset { ++ rockchip,pins = ++ <3 RK_PB7 RK_FUNC_GPIO &pcfg_output_low>; ++ }; ++ }; ++ ++ leds { ++ network_act: network-act { ++ rockchip,pins = ++ <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ ++ usb3_act: usb3-act { ++ rockchip,pins = ++ <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ ++ sata_act: sata-act { ++ rockchip,pins = ++ <4 RK_PD4 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ ++ system_led: sys-led { ++ rockchip,pins = ++ <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_down>, ++ <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ ++ sata_err_led: sata-err-led { ++ rockchip,pins = ++ <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_down>, ++ <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_down>, ++ <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_down>, ++ <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_down>, ++ <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ }; ++ ++ misc { ++ pca0_pins: pca0-pins { ++ rockchip,pins = ++ <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ wake_on_lan: wake-on-lan { ++ rockchip,pins = ++ <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pcie { ++ pcie_prst: pcie-prst { ++ rockchip,pins = ++ <2 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ pcie_pwr_en: pcie-pwr-en { ++ rockchip,pins = ++ <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = ++ <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ ++ vsel1_gpio: vsel1-gpio { ++ rockchip,pins = ++ <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ ++ vsel2_gpio: vsel2-gpio { ++ rockchip,pins = ++ <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ }; ++ ++ power { ++ hdd_a_power: hdd-a-power { ++ rockchip,pins = ++ <1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ hdd_b_power: hdd-b-power { ++ rockchip,pins = ++ <1 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ vcc5v0_usb_en: vcc5v0-usb-en { ++ rockchip,pins = ++ <1 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ sdmmc0_pwr_h: sdmmc0-pwr-h { ++ rockchip,pins = ++ ; ++ }; ++ ++ usb_lan_en: usb-lan-en { ++ rockchip,pins = ++ <1 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ usb { ++ usb_mux_hs: usb-mux-hs { ++ rockchip,pins = ++ <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ usb_mux_oe: usb-mux-oe { ++ rockchip,pins = ++ <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&pmu_io_domains { ++ pmu1830-supply = <&vcc3v0_s3>; ++ status = "okay"; ++}; ++ ++&pmu_pvtm { ++ status = "okay"; ++}; ++ ++&pwm0 { ++ status = "okay"; ++}; ++ ++&pwm1 { ++ status = "okay"; ++}; ++ ++&pwm2 { ++ status = "okay"; ++ pinctrl-names = "active"; ++ pinctrl-0 = <&pwm2_pin_pull_down>; ++}; ++ ++&pwm3 { ++ status = "okay"; ++}; ++ ++&saradc { ++ vref-supply = <&vcc1v8_s3>; ++ status = "okay"; ++}; ++ ++&rng { ++ status = "okay"; ++}; ++ ++&rockchip_suspend { ++ status = "okay"; ++ rockchip,sleep-debug-en = <1>; ++ rockchip,sleep-mode-config = < ++ (0 ++ | RKPM_SLP_ARMPD ++ | RKPM_SLP_PERILPPD ++ | RKPM_SLP_DDR_RET ++ | RKPM_SLP_PLLPD ++ | RKPM_SLP_CENTER_PD ++ | RKPM_SLP_AP_PWROFF ++ ) ++ >; ++ rockchip,wakeup-config = < ++ (0 ++ | RKPM_GPIO_WKUP_EN ++ | RKPM_CLUSTER_L_WKUP_EN ++ | RKPM_PWM_WKUP_EN ++ ) ++ >; ++ rockchip,pwm-regulator-config = < ++ (0 ++ | PWM2_REGULATOR_EN ++ ) ++ >; ++ rockchip,power-ctrl = ++ <&gpio1 RK_PC1 GPIO_ACTIVE_HIGH>, ++ <&gpio1 RK_PB6 GPIO_ACTIVE_HIGH>; ++}; ++ ++&sdhci { ++ bus-width = <8>; ++ mmc-hs400-1_8v; ++ mmc-hs200-1_8v; ++ mmc-hs400-enhanced-strobe; ++ //keep-power-in-suspend; ++ supports-emmc; ++ non-removable; ++ disable-wp; ++ status = "okay"; ++ //vmmc-supply = <&vcc3v3_sys_s0>; ++ //vqmmc-supply = <&vcc1v8_sys_s0>; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ card-detect-delay = <800>; ++ disable-wp; ++ num-slots = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; ++ sd-uhs-sdr104; ++ supports-sd; ++ vmmc-supply = <&vcc3v0_sd>; ++ vqmmc-supply = <&vcc_sdio_s0>; ++ status = "okay"; ++}; ++ ++&spi1 { ++ status = "okay"; ++ ++ flash@0 { ++ #address-cells = <0x1>; ++ #size-cells = <1>; ++ compatible = "winbond,w25q128", "jedec,spi-nor"; ++ reg = <0x0>; ++ spi-max-frequency = <25000000>; ++ status = "okay"; ++ }; ++}; ++ ++/* UEXT connector */ ++&spi2 { ++ status = "okay"; ++}; ++ ++&spi5 { ++ status = "okay"; ++}; ++ ++&tcphy0 { ++ extcon = <&fusb0>; ++ status = "okay"; ++}; ++ ++&tcphy1 { ++ status = "okay"; ++}; ++ ++&tsadc { ++ /* tshut mode 0:CRU 1:GPIO */ ++ rockchip,hw-tshut-mode = <1>; ++ /* tshut polarity 0:LOW 1:HIGH */ ++ rockchip,hw-tshut-polarity = <1>; ++ rockchip,hw-tshut-temp = <110000>; ++ status = "okay"; ++}; ++ ++&u2phy0 { ++ status = "okay"; ++ extcon = <&fusb0>; ++ ++ u2phy0_otg: otg-port { ++ status = "okay"; ++ }; ++ ++ u2phy0_host: host-port { ++ phy-supply = <&vcc5v0_usb>; ++ status = "okay"; ++ }; ++}; ++ ++&u2phy1 { ++ status = "okay"; ++ ++ u2phy1_otg: otg-port { ++ status = "okay"; ++ }; ++ ++ u2phy1_host: host-port { ++ phy-supply = <&vcc5v0_usb>; ++ status = "okay"; ++ }; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usbdrd3_0 { ++ extcon = <&fusb0>; ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3_0 { ++ status = "okay"; ++ dr_mode = "otg"; ++}; ++ ++&usbdrd3_1 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3_1 { ++ status = "okay"; ++ dr_mode = "host"; ++ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ int_hub: hub@1 { ++ compatible = "usb2109,0815"; ++ reg = <1>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ int_hub_port1: port@1 { ++ reg = <1>; ++ #trigger-source-cells = <0>; ++ }; ++ ++ int_hub_port2: port@2 { ++ reg = <2>; ++ #trigger-source-cells = <0>; ++ }; ++ ++ int_hub_port3: port@3 { ++ reg = <3>; ++ #trigger-source-cells = <0>; ++ }; ++ ++ usb_lan: device@4 { ++ compatible = "usbbda,8156"; ++ reg = <4>; ++ ++ #address-cells = <2>; ++ #size-cells = <0>; ++ ++ interface@0 { /* interface 0 of configuration 1 */ ++ compatible = "usbifbda,8156.config1.0"; ++ reg = <0 1>; ++ }; ++ }; ++ }; ++}; ++ ++&vdec_mmu { ++ status = "okay"; ++}; ++ ++&vpu_mmu { ++ status = "okay"; ++}; ++ ++&vopb { ++ status = "okay"; ++ assigned-clocks = <&cru DCLK_VOP0_DIV>; ++ assigned-clock-parents = <&cru PLL_VPLL>; ++}; ++ ++&vopb_mmu { ++ status = "okay"; ++}; ++ ++&vopl { ++ status = "okay"; ++ assigned-clocks = <&cru DCLK_VOP1_DIV>; ++ assigned-clock-parents = <&cru PLL_CPLL>; ++}; ++ ++&vopl_mmu { ++ status = "okay"; ++}; +-- +Created with Armbian build tools https://github.com/armbian/build + diff --git a/patch/kernel/rk3399-legacy/pci-host-rockchip-0000-scan-bus-fix-from-rockchip64.patch b/patch/kernel/rk3399-legacy/pci-host-rockchip-0000-scan-bus-fix-from-rockchip64.patch new file mode 100644 index 0000000000..04d4cdb892 --- /dev/null +++ b/patch/kernel/rk3399-legacy/pci-host-rockchip-0000-scan-bus-fix-from-rockchip64.patch @@ -0,0 +1,241 @@ +From e5467fb60570c9c300e9d412b9d5386cbb9951ba Mon Sep 17 00:00:00 2001 +From: Aditya Prayoga +Date: Mon, 18 May 2020 09:42:14 +0700 +Subject: [PATCH] port pcie changes from ayufan rockchip64 + +Signed-off-by: Aditya Prayoga +--- + drivers/pci/host/pcie-rockchip.c | 119 +++++++++++++++++++++++++------ + 1 file changed, 96 insertions(+), 23 deletions(-) + +diff --git a/drivers/pci/host/pcie-rockchip.c b/drivers/pci/host/pcie-rockchip.c +index 87291016d..1823323f8 100644 +--- a/drivers/pci/host/pcie-rockchip.c ++++ b/drivers/pci/host/pcie-rockchip.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -153,6 +154,7 @@ + PCIE_CORE_INT_CT | PCIE_CORE_INT_UTC | \ + PCIE_CORE_INT_MMVC) + ++#define PCIE_RC_CONFIG_NORMAL_BASE 0x800000 + #define PCIE_RC_CONFIG_BASE 0xa00000 + #define PCIE_RC_CONFIG_RID_CCR (PCIE_RC_CONFIG_BASE + 0x08) + #define PCIE_RC_CONFIG_SCC_SHIFT 16 +@@ -189,6 +191,8 @@ + #define IB_ROOT_PORT_REG_SIZE_SHIFT 3 + #define AXI_WRAPPER_IO_WRITE 0x6 + #define AXI_WRAPPER_MEM_WRITE 0x2 ++#define AXI_WRAPPER_TYPE0_CFG 0xa ++#define AXI_WRAPPER_TYPE1_CFG 0xb + #define AXI_WRAPPER_CFG0 0xa + #define AXI_WRAPPER_NOR_MSG 0xc + +@@ -213,6 +217,7 @@ + #define RC_REGION_0_ADDR_TRANS_H 0x00000000 + #define RC_REGION_0_ADDR_TRANS_L 0x00000000 + #define RC_REGION_0_PASS_BITS (25 - 1) ++#define RC_REGION_0_TYPE_MASK GENMASK(3, 0) + #define MAX_AXI_WRAPPER_REGION_NUM 33 + + struct rockchip_pcie { +@@ -253,8 +258,12 @@ struct rockchip_pcie { + int wait_ep; + struct dma_trx_obj *dma_obj; + struct list_head resources; ++ u32 bus_scan_delay; + }; + ++static int bus_scan_delay = -1; ++core_param(pcie_rk_bus_scan_delay, bus_scan_delay, int, S_IRUGO); ++ + static u32 rockchip_pcie_read(struct rockchip_pcie *rockchip, u32 reg) + { + return readl(rockchip->apb_base + reg); +@@ -330,7 +339,9 @@ static int rockchip_pcie_valid_device(struct rockchip_pcie *rockchip, + static int rockchip_pcie_rd_own_conf(struct rockchip_pcie *rockchip, + int where, int size, u32 *val) + { +- void __iomem *addr = rockchip->apb_base + PCIE_RC_CONFIG_BASE + where; ++ void __iomem *addr; ++ ++ addr = rockchip->apb_base + PCIE_RC_CONFIG_NORMAL_BASE + where; + + if (!IS_ALIGNED((uintptr_t)addr, size)) { + *val = 0; +@@ -354,11 +365,13 @@ static int rockchip_pcie_wr_own_conf(struct rockchip_pcie *rockchip, + int where, int size, u32 val) + { + u32 mask, tmp, offset; ++ void __iomem *addr; + + offset = where & ~0x3; ++ addr = rockchip->apb_base + PCIE_RC_CONFIG_NORMAL_BASE + offset; + + if (size == 4) { +- writel(val, rockchip->apb_base + PCIE_RC_CONFIG_BASE + offset); ++ writel(val, addr); + return PCIBIOS_SUCCESSFUL; + } + +@@ -369,13 +382,33 @@ static int rockchip_pcie_wr_own_conf(struct rockchip_pcie *rockchip, + * corrupt RW1C bits in adjacent registers. But the hardware + * doesn't support smaller writes. + */ +- tmp = readl(rockchip->apb_base + PCIE_RC_CONFIG_BASE + offset) & mask; ++ tmp = readl(addr) & mask; + tmp |= val << ((where & 0x3) * 8); +- writel(tmp, rockchip->apb_base + PCIE_RC_CONFIG_BASE + offset); ++ writel(tmp, addr); + + return PCIBIOS_SUCCESSFUL; + } + ++static void rockchip_pcie_cfg_configuration_accesses( ++ struct rockchip_pcie *rockchip, u32 type) ++{ ++ u32 ob_desc_0; ++ ++ /* Configuration Accesses for region 0 */ ++ rockchip_pcie_write(rockchip, 0x0, PCIE_RC_BAR_CONF); ++ ++ rockchip_pcie_write(rockchip, ++ (RC_REGION_0_ADDR_TRANS_L + RC_REGION_0_PASS_BITS), ++ PCIE_CORE_OB_REGION_ADDR0); ++ rockchip_pcie_write(rockchip, RC_REGION_0_ADDR_TRANS_H, ++ PCIE_CORE_OB_REGION_ADDR1); ++ ob_desc_0 = rockchip_pcie_read(rockchip, PCIE_CORE_OB_REGION_DESC0); ++ ob_desc_0 &= ~(RC_REGION_0_TYPE_MASK); ++ ob_desc_0 |= (type | (0x1 << 23)); ++ rockchip_pcie_write(rockchip, ob_desc_0, PCIE_CORE_OB_REGION_DESC0); ++ rockchip_pcie_write(rockchip, 0x0, PCIE_CORE_OB_REGION_DESC1); ++} ++ + static int rockchip_pcie_rd_other_conf(struct rockchip_pcie *rockchip, + struct pci_bus *bus, u32 devfn, + int where, int size, u32 *val) +@@ -385,11 +418,23 @@ static int rockchip_pcie_rd_other_conf(struct rockchip_pcie *rockchip, + busdev = PCIE_ECAM_ADDR(bus->number, PCI_SLOT(devfn), + PCI_FUNC(devfn), where); + ++ if (bus->number > 0x1f) { ++ *val = 0; ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ } ++ + if (!IS_ALIGNED(busdev, size)) { + *val = 0; + return PCIBIOS_BAD_REGISTER_NUMBER; + } + ++ if (bus->parent->number == rockchip->root_bus_nr) ++ rockchip_pcie_cfg_configuration_accesses(rockchip, ++ AXI_WRAPPER_TYPE0_CFG); ++ else ++ rockchip_pcie_cfg_configuration_accesses(rockchip, ++ AXI_WRAPPER_TYPE1_CFG); ++ + if (size == 4) { + *val = readl(rockchip->reg_base + busdev); + } else if (size == 2) { +@@ -411,9 +456,19 @@ static int rockchip_pcie_wr_other_conf(struct rockchip_pcie *rockchip, + + busdev = PCIE_ECAM_ADDR(bus->number, PCI_SLOT(devfn), + PCI_FUNC(devfn), where); ++ ++ if (bus->number > 0x1f) ++ return PCIBIOS_DEVICE_NOT_FOUND; + if (!IS_ALIGNED(busdev, size)) + return PCIBIOS_BAD_REGISTER_NUMBER; + ++ if (bus->parent->number == rockchip->root_bus_nr) ++ rockchip_pcie_cfg_configuration_accesses(rockchip, ++ AXI_WRAPPER_TYPE0_CFG); ++ else ++ rockchip_pcie_cfg_configuration_accesses(rockchip, ++ AXI_WRAPPER_TYPE1_CFG); ++ + if (size == 4) + writel(val, rockchip->reg_base + busdev); + else if (size == 2) +@@ -638,6 +693,11 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) + status |= PCI_EXP_LNKCTL_CCC; + rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS); + ++ /* Set RC's RCB to 128 */ ++ status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LCS); ++ status |= PCI_EXP_LNKCTL_RCB; ++ rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS); ++ + /* Enable Gen1 training */ + rockchip_pcie_write(rockchip, PCIE_CLIENT_LINK_TRAIN_ENABLE, + PCIE_CLIENT_CONFIG); +@@ -696,15 +756,8 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) + rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LINK_CAP); + } + +- rockchip_pcie_write(rockchip, 0x0, PCIE_RC_BAR_CONF); +- +- rockchip_pcie_write(rockchip, +- (RC_REGION_0_ADDR_TRANS_L + RC_REGION_0_PASS_BITS), +- PCIE_CORE_OB_REGION_ADDR0); +- rockchip_pcie_write(rockchip, RC_REGION_0_ADDR_TRANS_H, +- PCIE_CORE_OB_REGION_ADDR1); +- rockchip_pcie_write(rockchip, 0x0080000a, PCIE_CORE_OB_REGION_DESC0); +- rockchip_pcie_write(rockchip, 0x0, PCIE_CORE_OB_REGION_DESC1); ++ rockchip_pcie_cfg_configuration_accesses(rockchip, ++ AXI_WRAPPER_TYPE0_CFG); + + return 0; + } +@@ -1067,6 +1120,14 @@ static int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip) + dev_info(dev, "no vpcie0v9 regulator found\n"); + } + ++ err = of_property_read_u32(node, "bus-scan-delay-ms", &rockchip->bus_scan_delay); ++ if (err) { ++ dev_info(dev, "no bus-scan-delay-ms in device tree, default 0 ms\n"); ++ rockchip->bus_scan_delay = 0; ++ } else { ++ dev_info(dev, "bus-scan-delay-ms in device tree is %u ms\n", rockchip->bus_scan_delay); ++ } ++ + mem = of_parse_phandle(node, "memory-region", 0); + if (!mem) { + dev_warn(dev, "missing \"memory-region\" property\n"); +@@ -1396,6 +1457,7 @@ static int rockchip_pcie_really_probe(struct rockchip_pcie *rockchip) + int err; + struct pci_bus *bus, *child; + struct device *dev = rockchip->dev; ++ u32 delay = 0; + + err = rockchip_pcie_init_port(rockchip); + if (err) +@@ -1407,6 +1469,18 @@ static int rockchip_pcie_really_probe(struct rockchip_pcie *rockchip) + if (err) + return err; + ++ /* Prefer command-line param over device tree */ ++ if (bus_scan_delay > 0) { ++ delay = bus_scan_delay; ++ dev_info(dev, "wait %u ms (from command-line) before bus scan\n", delay); ++ } else if (rockchip->bus_scan_delay > 0 && bus_scan_delay < 0) { ++ delay = rockchip->bus_scan_delay; ++ dev_info(dev, "wait %u ms (from device tree) before bus scan\n", delay); ++ } ++ if (delay > 0) { ++ msleep(delay); ++ } ++ + bus = pci_scan_root_bus(dev, 0, &rockchip_pcie_ops, + rockchip, &rockchip->resources); + if (!bus) +-- +Created with Armbian build tools https://github.com/armbian/build + diff --git a/patch/kernel/rk3399-legacy/pci-host-rockchip-0001-backport-fix-power-stable-and-config-access.patch b/patch/kernel/rk3399-legacy/pci-host-rockchip-0001-backport-fix-power-stable-and-config-access.patch new file mode 100644 index 0000000000..370e2e7513 --- /dev/null +++ b/patch/kernel/rk3399-legacy/pci-host-rockchip-0001-backport-fix-power-stable-and-config-access.patch @@ -0,0 +1,45 @@ +From 6606ce73fb42a987b1cc45edbeb7c5e78246fb51 Mon Sep 17 00:00:00 2001 +From: Aditya Prayoga +Date: Wed, 10 Jun 2020 17:21:06 +0700 +Subject: [PATCH] backport pcie fix power stable and config access + +Signed-off-by: Aditya Prayoga +--- + drivers/pci/host/pcie-rockchip.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/drivers/pci/host/pcie-rockchip.c b/drivers/pci/host/pcie-rockchip.c +index 1823323f8..f57571863 100644 +--- a/drivers/pci/host/pcie-rockchip.c ++++ b/drivers/pci/host/pcie-rockchip.c +@@ -394,8 +394,11 @@ static void rockchip_pcie_cfg_configuration_accesses( + { + u32 ob_desc_0; + +- /* Configuration Accesses for region 0 */ +- rockchip_pcie_write(rockchip, 0x0, PCIE_RC_BAR_CONF); ++ /* ++ * Configuration Accesses for region 0. ++ * Bit 19 is for enabling IO base and limit registers. ++ */ ++ rockchip_pcie_write(rockchip, BIT(19), PCIE_RC_BAR_CONF); + + rockchip_pcie_write(rockchip, + (RC_REGION_0_ADDR_TRANS_L + RC_REGION_0_PASS_BITS), +@@ -701,6 +704,13 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) + /* Enable Gen1 training */ + rockchip_pcie_write(rockchip, PCIE_CLIENT_LINK_TRAIN_ENABLE, + PCIE_CLIENT_CONFIG); ++ /* ++ * According to PCI Express Card Electromechanical Specification ++ * Revision 3.0, Table 2-4, power stable and reference clk stable ++ * before PERST# inactive should be at least 100ms and 100us ++ * respectively. Otherwise we do see some failures for link training. ++ */ ++ msleep(100); + + gpiod_set_value(rockchip->ep_gpio, 1); + +-- +Created with Armbian build tools https://github.com/armbian/build + diff --git a/patch/kernel/rk3399-legacy/roc-rk3399-pc-add-board.patch b/patch/kernel/rk3399-legacy/roc-rk3399-pc-add-board.patch index 294a281c76..776cb7a6e7 100644 --- a/patch/kernel/rk3399-legacy/roc-rk3399-pc-add-board.patch +++ b/patch/kernel/rk3399-legacy/roc-rk3399-pc-add-board.patch @@ -1,16 +1,18 @@ +diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile +index adfa8211..2c3a023a 100644 --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile -@@ -8,7 +8,8 @@ - rk3399-nanopi4-rev07.dtb \ - rk3399-nanopi4-rev21.dtb \ +@@ -15,7 +15,8 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \ + rk3399-nanopi-m4v2.dtb \ rk3399-nanopi4-rev22.dtb \ + rk3399-helios64.dtb \ - rk3399-firefly.dtb + rk3399-firefly.dtb \ + rk3399-roc-pc.dtb - else - -@@ -109,6 +110,7 @@ + dtb-$(CONFIG_ARCH_ROCKCHIP) += \ + rk3328-nanopi-r2-rev00.dtb +@@ -119,6 +120,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-kevin-r0.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-kevin-r1.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-mid-818-android-6.0.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-mid-818-android.dtb @@ -18,6 +20,9 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock960-ab.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rockpro64.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rv1-android.dtb +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-exp.dts b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-exp.dts +new file mode 100644 +index 00000000..cc922411 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-exp.dts @@ -0,0 +1,20 @@ @@ -41,6 +46,9 @@ + status = "okay"; +}; + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-mipi.dts b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-mipi.dts +new file mode 100644 +index 00000000..b3145e99 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-mipi.dts @@ -0,0 +1,78 @@ @@ -122,6 +130,9 @@ +&route_dsi { + status = "disabled"; +}; +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dts b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dts +new file mode 100644 +index 00000000..0b1c902b --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dts @@ -0,0 +1,7 @@ @@ -133,6 +144,9 @@ + compatible = "firefly,roc-rk3399-pc", "rockchip,rk3399"; +}; \ No newline at end of file +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi +new file mode 100644 +index 00000000..f871f0c5 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi @@ -0,0 +1,1419 @@ @@ -1555,6 +1569,8 @@ +&isp1_mmu { + status = "okay"; +}; +diff --git a/include/dt-bindings/clock/rk3399-cru.h b/include/dt-bindings/clock/rk3399-cru.h +index a2aa50c8..70a7bdb5 100644 --- a/include/dt-bindings/clock/rk3399-cru.h +++ b/include/dt-bindings/clock/rk3399-cru.h @@ -31,6 +31,7 @@ @@ -1565,3 +1581,6 @@ #define SCLK_I2C1 65 #define SCLK_I2C2 66 #define SCLK_I2C3 67 +-- +Created with Armbian build tools https://github.com/armbian/build + diff --git a/patch/kernel/rk3399-legacy/update_2.5GBE_usb_rtl8156_to_v2.12.0.patch.disabled b/patch/kernel/rk3399-legacy/update_2.5GBE_usb_rtl8156_to_v2.13.0.patch similarity index 52% rename from patch/kernel/rk3399-legacy/update_2.5GBE_usb_rtl8156_to_v2.12.0.patch.disabled rename to patch/kernel/rk3399-legacy/update_2.5GBE_usb_rtl8156_to_v2.13.0.patch index b8bc42bb8e..4d6155ce95 100644 --- a/patch/kernel/rk3399-legacy/update_2.5GBE_usb_rtl8156_to_v2.12.0.patch.disabled +++ b/patch/kernel/rk3399-legacy/update_2.5GBE_usb_rtl8156_to_v2.13.0.patch @@ -1,9 +1,21 @@ +From c6de5f0d730b0dbc87f0fca622473e49a67b7530 Mon Sep 17 00:00:00 2001 +From: Aditya Prayoga +Date: Mon, 11 May 2020 11:14:49 +0700 +Subject: [PATCH] update r8152 to v2.13 + +Signed-off-by: Aditya Prayoga +--- + drivers/net/usb/compatibility.h | 562 ++ + drivers/net/usb/r8152.c | 15914 +++++++++++++++++++++++++++--- + 2 files changed, 15193 insertions(+), 1283 deletions(-) + create mode 100644 drivers/net/usb/compatibility.h + diff --git a/drivers/net/usb/compatibility.h b/drivers/net/usb/compatibility.h new file mode 100644 -index 00000000..208d90c0 +index 000000000..cf6353043 --- /dev/null +++ b/drivers/net/usb/compatibility.h -@@ -0,0 +1,508 @@ +@@ -0,0 +1,562 @@ +#ifndef LINUX_COMPATIBILITY_H +#define LINUX_COMPATIBILITY_H + @@ -22,9 +34,15 @@ index 00000000..208d90c0 +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0) */ +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) */ + ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0) ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4,20,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,12,0) + #define SPEED_2500 2500 + #define SPEED_25000 25000 ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0) ++ #ifndef ETHTOOL_LINK_MODE_2500baseT_Full_BIT ++ #define ETHTOOL_LINK_MODE_2500baseT_Full_BIT ETHTOOL_LINK_MODE_2500baseX_Full_BIT ++ #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0) + #define BMCR_SPEED10 0x0000 +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0) @@ -49,6 +67,7 @@ index 00000000..208d90c0 + #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0) + #define IS_ERR_OR_NULL(ptr) (!ptr) ++ +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0) + #define ether_addr_copy(dst, src) memcpy(dst, src, ETH_ALEN) +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0) @@ -56,6 +75,7 @@ index 00000000..208d90c0 + #define BIT_ULL(nr) (1ULL << (nr)) + #define BITS_PER_BYTE 8 + #define reinit_completion(x) ((x)->done = 0) ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) + #define NETIF_F_HW_VLAN_CTAG_RX NETIF_F_HW_VLAN_RX + #define NETIF_F_HW_VLAN_CTAG_TX NETIF_F_HW_VLAN_TX @@ -63,13 +83,6 @@ index 00000000..208d90c0 + #define USB_DEVICE_INTERFACE_CLASS(vend, prod, iclass) \ + USB_DEVICE_AND_INTERFACE_INFO(vend, prod, iclass, 0xff, 0) + -+ static inline __sum16 tcp_v6_check(int len, -+ const struct in6_addr *saddr, -+ const struct in6_addr *daddr, -+ __wsum base) -+ { -+ return csum_ipv6_magic(saddr, daddr, len, IPPROTO_TCP, base); -+ } +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0) + #ifndef SPEED_UNKNOWN + #define SPEED_UNKNOWN 0 @@ -86,10 +99,6 @@ index 00000000..208d90c0 +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0) + #define ETH_MDIO_SUPPORTS_C22 MDIO_SUPPORTS_C22 + -+ static inline void eth_hw_addr_random(struct net_device *dev) -+ { -+ random_ether_addr(dev->dev_addr); -+ } +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) + #define module_usb_driver(__driver) \ + static int __init __driver##_init(void) \ @@ -107,20 +116,6 @@ index 00000000..208d90c0 +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) + #define PMSG_IS_AUTO(msg) (((msg).event & PM_EVENT_AUTO) != 0) + -+ static inline struct page *skb_frag_page(const skb_frag_t *frag) -+ { -+ return frag->page; -+ } -+ -+ static inline void *skb_frag_address(const skb_frag_t *frag) -+ { -+ return page_address(skb_frag_page(frag)) + frag->page_offset; -+ } -+ -+ static inline unsigned int skb_frag_size(const skb_frag_t *frag) -+ { -+ return frag->size; -+ } +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) + #define ndo_set_rx_mode ndo_set_multicast_list +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39) @@ -132,45 +127,13 @@ index 00000000..208d90c0 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) + #define skb_checksum_none_assert(skb_ptr) (skb_ptr)->ip_summed = CHECKSUM_NONE + -+ static inline __be16 vlan_get_protocol(const struct sk_buff *skb) -+ { -+ __be16 protocol = 0; -+ -+ if (vlan_tx_tag_present(skb) || -+ skb->protocol != cpu_to_be16(ETH_P_8021Q)) -+ protocol = skb->protocol; -+ else { -+ __be16 proto, *protop; -+ protop = skb_header_pointer(skb, offsetof(struct vlan_ethhdr, -+ h_vlan_encapsulated_proto), -+ sizeof(proto), &proto); -+ if (likely(protop)) -+ protocol = *protop; -+ } -+ -+ return protocol; -+ } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) + #define skb_tx_timestamp(skb) + + #define queue_delayed_work(long_wq, work, delay) schedule_delayed_work(work, delay) + -+ static inline void usleep_range(unsigned long min, unsigned long max) -+ { -+ unsigned long ms = min / 1000; -+ -+ if (ms) -+ mdelay(ms); -+ -+ udelay(min % 1000); -+ } -+ + #define work_busy(x) 0 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) -+ static inline bool pci_dev_run_wake(struct pci_dev *dev) -+ { -+ return 1; -+ } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) + #define netdev_mc_count(netdev) ((netdev)->mc_count) + #define netdev_mc_empty(netdev) (netdev_mc_count(netdev) == 0) @@ -196,23 +159,9 @@ index 00000000..208d90c0 + #define netif_info(priv, type, netdev, fmt, args...) \ + netif_printk(priv, type, KERN_INFO, (netdev), fmt, ##args) + -+ static inline int usb_enable_autosuspend(struct usb_device *udev) -+ { return 0; } -+ static inline int usb_disable_autosuspend(struct usb_device *udev) -+ { return 0; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) + #define get_sset_count get_stats_count + -+ static inline -+ struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev, -+ unsigned int length) -+ { -+ struct sk_buff *skb = netdev_alloc_skb(dev, length + NET_IP_ALIGN); -+ -+ if (NET_IP_ALIGN && skb) -+ skb_reserve(skb, NET_IP_ALIGN); -+ return skb; -+ } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) + #define pm_request_resume(para) + #define pm_runtime_set_suspended(para) @@ -233,43 +182,140 @@ index 00000000..208d90c0 + #define vlan_gro_receive(napi, grp, vlan_tci, skb) \ + vlan_hwaccel_receive_skb(skb, grp, vlan_tci) + -+ static inline void usb_autopm_put_interface_async(struct usb_interface *intf) -+ { -+ struct usb_device *udev = interface_to_usbdev(intf); -+ int status = 0; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) ++ #define PM_EVENT_AUTO 0x0400 + -+ if (intf->condition == USB_INTERFACE_UNBOUND) { -+ status = -ENODEV; -+ } else { -+ udev->last_busy = jiffies; -+ --intf->pm_usage_cnt; -+ if (udev->autosuspend_disabled || udev->autosuspend_delay < 0) -+ status = -EPERM; -+ } ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) ++ struct napi_struct { ++ struct list_head poll_list; ++ unsigned long state; ++ int weight; ++ int (*poll)(struct napi_struct *, int); ++ #ifdef CONFIG_NETPOLL ++ spinlock_t poll_lock; ++ int poll_owner; ++ struct net_device *dev; ++ struct list_head dev_list; ++ #endif ++ }; ++ ++ #define napi_enable(napi_ptr) netif_poll_enable(container_of(napi_ptr, struct r8152, napi)->netdev) ++ #define napi_disable(napi_ptr) netif_poll_disable(container_of(napi_ptr, struct r8152, napi)->netdev) ++ #define napi_schedule(napi_ptr) netif_rx_schedule(container_of(napi_ptr, struct r8152, napi)->netdev) ++ #define napi_complete(napi_ptr) netif_rx_complete(container_of(napi_ptr, struct r8152, napi)->netdev) ++ #define netif_napi_add(ndev, napi_ptr, function, weight_t) \ ++ ndev->poll = function; \ ++ ndev->weight = weight_t; ++ typedef unsigned long uintptr_t; ++ #define DMA_BIT_MASK(value) \ ++ (value < 64 ? ((1ULL << value) - 1) : 0xFFFFFFFFFFFFFFFFULL) ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) ++ #define NETIF_F_IPV6_CSUM 16 ++ #define cancel_delayed_work_sync cancel_delayed_work ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) ++ #define ip_hdr(skb_ptr) (skb_ptr)->nh.iph ++ #define ipv6hdr(skb_ptr) (skb_ptr)->nh.ipv6h ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) ++ #define vlan_group_set_device(vlgrp, vid, value) \ ++ if (vlgrp) \ ++ (vlgrp)->vlan_devices[vid] = value; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) ++ #define delayed_work work_struct ++ #define INIT_DELAYED_WORK(a,b) INIT_WORK(a,b,tp) ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) ++ #define CHECKSUM_PARTIAL CHECKSUM_HW ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) ++ #define skb_is_gso(skb_ptr) skb_shinfo(skb_ptr)->tso_size ++ #define netdev_alloc_skb(dev, len) dev_alloc_skb(len) ++ #define IRQF_SHARED SA_SHIRQ ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16) ++ #ifndef __LINUX_MUTEX_H ++ #define mutex semaphore ++ #define mutex_lock down ++ #define mutex_unlock up ++ #define mutex_trylock down_trylock ++ #define mutex_lock_interruptible down_interruptible ++ #define mutex_init init_MUTEX ++ #endif ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) ++ #define ADVERTISED_Pause (1 << 13) ++ #define ADVERTISED_Asym_Pause (1 << 14) ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) ++ #define skb_header_cloned(skb) skb_cloned(skb) ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) */ ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) */ ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16) */ ++ static inline struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features) ++ { ++ return NULL; + } -+ -+ static inline int usb_autopm_get_interface_async(struct usb_interface *intf) ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) */ ++ static inline void *kmemdup(const void *src, size_t len, gfp_t gfp) + { -+ struct usb_device *udev = interface_to_usbdev(intf); -+ int status = 0; ++ void *p; + -+ if (intf->condition == USB_INTERFACE_UNBOUND) -+ status = -ENODEV; -+ else if (udev->autoresume_disabled) -+ status = -EPERM; -+ else -+ ++intf->pm_usage_cnt; -+ return status; ++ p = kmalloc_track_caller(len, gfp); ++ if (p) ++ memcpy(p, src, len); ++ return p; + } -+ -+ static inline int eth_change_mtu(struct net_device *dev, int new_mtu) ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */ ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) */ ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) */ ++ static inline void skb_copy_from_linear_data(const struct sk_buff *skb, ++ void *to, ++ const unsigned int len) + { -+ if (new_mtu < 68 || new_mtu > ETH_DATA_LEN) -+ return -EINVAL; -+ dev->mtu = new_mtu; ++ memcpy(to, skb->data, len); ++ } ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) */ ++ static inline int skb_cow_head(struct sk_buff *skb, unsigned int headroom) ++ { ++ int delta = 0; ++ ++ if (headroom > skb_headroom(skb)) ++ delta = headroom - skb_headroom(skb); ++ ++ if (delta || skb_header_cloned(skb)) ++ return pskb_expand_head(skb, ALIGN(delta, NET_SKB_PAD), ++ 0, GFP_ATOMIC); + return 0; + } -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) */ ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) */ ++ static inline void __list_splice2(const struct list_head *list, ++ struct list_head *prev, ++ struct list_head *next) ++ { ++ struct list_head *first = list->next; ++ struct list_head *last = list->prev; ++ ++ first->prev = prev; ++ prev->next = first; ++ ++ last->next = next; ++ next->prev = last; ++ } ++ ++ static inline void list_splice_tail(struct list_head *list, ++ struct list_head *head) ++ { ++ if (!list_empty(list)) ++ __list_splice2(list, head->prev, head); ++ } ++ ++ static inline void netif_napi_del(struct napi_struct *napi) ++ { ++ #ifdef CONFIG_NETPOLL ++ list_del(&napi->dev_list); ++ #endif ++ } ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) */ + static inline void __skb_queue_splice(const struct sk_buff_head *list, + struct sk_buff *prev, + struct sk_buff *next) @@ -308,159 +354,152 @@ index 00000000..208d90c0 + __skb_queue_head_init(list); + } + } -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) -+ #define PM_EVENT_AUTO 0x0400 -+ -+ static inline void __list_splice2(const struct list_head *list, -+ struct list_head *prev, -+ struct list_head *next) ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) */ ++ static inline void usb_autopm_put_interface_async(struct usb_interface *intf) + { -+ struct list_head *first = list->next; -+ struct list_head *last = list->prev; ++ struct usb_device *udev = interface_to_usbdev(intf); ++ int status = 0; + -+ first->prev = prev; -+ prev->next = first; -+ -+ last->next = next; -+ next->prev = last; ++ if (intf->condition == USB_INTERFACE_UNBOUND) { ++ status = -ENODEV; ++ } else { ++ udev->last_busy = jiffies; ++ --intf->pm_usage_cnt; ++ if (udev->autosuspend_disabled || udev->autosuspend_delay < 0) ++ status = -EPERM; ++ } + } + -+ static inline void list_splice_tail(struct list_head *list, -+ struct list_head *head) ++ static inline int usb_autopm_get_interface_async(struct usb_interface *intf) + { -+ if (!list_empty(list)) -+ __list_splice2(list, head->prev, head); ++ struct usb_device *udev = interface_to_usbdev(intf); ++ int status = 0; ++ ++ if (intf->condition == USB_INTERFACE_UNBOUND) ++ status = -ENODEV; ++ else if (udev->autoresume_disabled) ++ status = -EPERM; ++ else ++ ++intf->pm_usage_cnt; ++ return status; + } -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) -+ struct napi_struct { -+ struct list_head poll_list; -+ unsigned long state; -+ int weight; -+ int (*poll)(struct napi_struct *, int); -+ #ifdef CONFIG_NETPOLL -+ spinlock_t poll_lock; -+ int poll_owner; -+ struct net_device *dev; -+ struct list_head dev_list; -+ #endif -+ }; + -+ #define napi_enable(napi_ptr) netif_poll_enable(container_of(napi_ptr, struct r8152, napi)->netdev) -+ #define napi_disable(napi_ptr) netif_poll_disable(container_of(napi_ptr, struct r8152, napi)->netdev) -+ #define napi_schedule(napi_ptr) netif_rx_schedule(container_of(napi_ptr, struct r8152, napi)->netdev) -+ #define napi_complete(napi_ptr) netif_rx_complete(container_of(napi_ptr, struct r8152, napi)->netdev) -+ #define netif_napi_add(ndev, napi_ptr, function, weight_t) \ -+ ndev->poll = function; \ -+ ndev->weight = weight_t; -+ typedef unsigned long uintptr_t; -+ #define DMA_BIT_MASK(value) \ -+ (value < 64 ? ((1ULL << value) - 1) : 0xFFFFFFFFFFFFFFFFULL) -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) -+ #define NETIF_F_IPV6_CSUM 16 -+ #define cancel_delayed_work_sync cancel_delayed_work -+ -+ static inline int skb_cow_head(struct sk_buff *skb, unsigned int headroom) ++ static inline int eth_change_mtu(struct net_device *dev, int new_mtu) + { -+ int delta = 0; -+ -+ if (headroom > skb_headroom(skb)) -+ delta = headroom - skb_headroom(skb); -+ -+ if (delta || skb_header_cloned(skb)) -+ return pskb_expand_head(skb, ALIGN(delta, NET_SKB_PAD), -+ 0, GFP_ATOMIC); ++ if (new_mtu < 68 || new_mtu > ETH_DATA_LEN) ++ return -EINVAL; ++ dev->mtu = new_mtu; + return 0; + } -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) -+ #define ip_hdr(skb_ptr) (skb_ptr)->nh.iph -+ #define ipv6hdr(skb_ptr) (skb_ptr)->nh.ipv6h -+ -+ static inline void skb_copy_from_linear_data(const struct sk_buff *skb, -+ void *to, -+ const unsigned int len) -+ { -+ memcpy(to, skb->data, len); -+ } -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) -+ #define vlan_group_set_device(vlgrp, vid, value) \ -+ if (vlgrp) \ -+ (vlgrp)->vlan_devices[vid] = value; -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) -+ #define delayed_work work_struct -+ #define INIT_DELAYED_WORK(a,b) INIT_WORK(a,b,tp) -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) -+ #define CHECKSUM_PARTIAL CHECKSUM_HW -+ -+ static inline void *kmemdup(const void *src, size_t len, gfp_t gfp) -+ { -+ void *p; -+ -+ p = kmalloc_track_caller(len, gfp); -+ if (p) -+ memcpy(p, src, len); -+ return p; -+ } -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) -+ #define skb_is_gso(skb_ptr) skb_shinfo(skb_ptr)->tso_size -+ #define netdev_alloc_skb(dev, len) dev_alloc_skb(len) -+ #define IRQF_SHARED SA_SHIRQ -+ -+ static inline struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features) -+ { -+ return NULL; -+ } -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16) -+ #ifndef __LINUX_MUTEX_H -+ #define mutex semaphore -+ #define mutex_lock down -+ #define mutex_unlock up -+ #define mutex_trylock down_trylock -+ #define mutex_lock_interruptible down_interruptible -+ #define mutex_init init_MUTEX -+ #endif -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) -+ #define ADVERTISED_Pause (1 << 13) -+ #define ADVERTISED_Asym_Pause (1 << 14) -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) -+ #define skb_header_cloned(skb) skb_cloned(skb) -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) */ -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) */ -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16) */ -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) */ -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */ -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) */ -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) */ -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) */ -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) */ -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) */ -+ static inline void netif_napi_del(struct napi_struct *napi) -+ { -+ #ifdef CONFIG_NETPOLL -+ list_del(&napi->dev_list); -+ #endif -+ } -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) */ -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) */ +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) */ +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31) */ +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) */ ++ static inline ++ struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev, ++ unsigned int length) ++ { ++ struct sk_buff *skb = netdev_alloc_skb(dev, length + NET_IP_ALIGN); ++ ++ if (NET_IP_ALIGN && skb) ++ skb_reserve(skb, NET_IP_ALIGN); ++ return skb; ++ } +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) */ ++ static inline int usb_enable_autosuspend(struct usb_device *udev) ++ { return 0; } ++ static inline int usb_disable_autosuspend(struct usb_device *udev) ++ { return 0; } +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) */ ++ static inline bool pci_dev_run_wake(struct pci_dev *dev) ++ { ++ return 1; ++ } +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) */ ++ static inline void usleep_range(unsigned long min, unsigned long max) ++ { ++ unsigned long ms = min / 1000; ++ ++ if (ms) ++ mdelay(ms); ++ ++ udelay(min % 1000); ++ } ++ +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) */ ++ static inline __be16 vlan_get_protocol(const struct sk_buff *skb) ++ { ++ __be16 protocol = 0; ++ ++ if (vlan_tx_tag_present(skb) || ++ skb->protocol != cpu_to_be16(ETH_P_8021Q)) ++ protocol = skb->protocol; ++ else { ++ __be16 proto, *protop; ++ protop = skb_header_pointer(skb, offsetof(struct vlan_ethhdr, ++ h_vlan_encapsulated_proto), ++ sizeof(proto), &proto); ++ if (likely(protop)) ++ protocol = *protop; ++ } ++ ++ return protocol; ++ } +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) */ +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) */ +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39) */ +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) */ ++ static inline struct page *skb_frag_page(const skb_frag_t *frag) ++ { ++ return frag->page; ++ } ++ ++ static inline void *skb_frag_address(const skb_frag_t *frag) ++ { ++ return page_address(skb_frag_page(frag)) + frag->page_offset; ++ } ++ ++ static inline unsigned int skb_frag_size(const skb_frag_t *frag) ++ { ++ return frag->size; ++ } +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) */ +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) */ ++ static inline void eth_hw_addr_random(struct net_device *dev) ++ { ++ random_ether_addr(dev->dev_addr); ++ } +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0) */ +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0) */ +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0) */ ++ static inline __sum16 tcp_v6_check(int len, ++ const struct in6_addr *saddr, ++ const struct in6_addr *daddr, ++ __wsum base) ++ { ++ return csum_ipv6_magic(saddr, daddr, len, IPPROTO_TCP, base); ++ } +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0) */ +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) */ ++ static inline bool usb_device_no_sg_constraint(struct usb_device *udev) ++ { ++ return 0; ++ } ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0) */ +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0) */ +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0) */ ++ static inline int skb_to_sgvec_nomark(struct sk_buff *skb, ++ struct scatterlist *sg, ++ int offset, int len) ++ { ++ int nsg = skb_to_sgvec(skb, sg, offset, len); ++ ++ if (nsg <= 0) ++ return nsg; ++ ++ sg_unmark_end(&sg[nsg - 1]); ++ ++ return nsg; ++ } +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0) */ +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0) */ +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0) */ @@ -468,7 +507,34 @@ index 00000000..208d90c0 +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(4,1,0) */ +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0) */ +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0) */ ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0) */ +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(4,12,0) */ ++ static inline void linkmode_set_bit(int nr, volatile unsigned long *addr) ++ { ++ __set_bit(nr, addr); ++ } ++ ++ static inline void linkmode_clear_bit(int nr, volatile unsigned long *addr) ++ { ++ __clear_bit(nr, addr); ++ } ++ ++ static inline int linkmode_test_bit(int nr, volatile unsigned long *addr) ++ { ++ return test_bit(nr, addr); ++ } ++ ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(4,20,0) */ ++ static inline void linkmode_mod_bit(int nr, volatile unsigned long *addr, ++ int set) ++ { ++ if (set) ++ linkmode_set_bit(nr, addr); ++ else ++ linkmode_clear_bit(nr, addr); ++ } ++ ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0) */ + +#ifndef FALSE + #define TRUE 1 @@ -513,7 +579,7 @@ index 00000000..208d90c0 + +#endif /* LINUX_COMPATIBILITY_H */ diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c -index 2490498b..26cc7c1a 100644 +index 9b73225a6..f52aaf67c 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -1,10 +1,12 @@ @@ -530,7 +596,7 @@ index 2490498b..26cc7c1a 100644 */ #include -@@ -22,23 +24,21 @@ +@@ -22,27 +24,21 @@ #include #include #include @@ -538,39 +604,163 @@ index 2490498b..26cc7c1a 100644 -#include #include #include --#include ++#include + #include ++#include "compatibility.h" -/* Information for net-next */ -#define NETNEXT_VERSION "09" -+#include "compatibility.h" - +- -/* Information for net */ -#define NET_VERSION "9" - -#define DRIVER_VERSION "v1." NETNEXT_VERSION "." NET_VERSION -#define DRIVER_AUTHOR "Realtek linux nic maintainers " +/* Version Information */ -+#define DRIVER_VERSION "v2.12.0 (2019/04/29)" ++#define DRIVER_VERSION "v2.13.0 (2020/04/20)" +#define DRIVER_AUTHOR "Realtek nic sw " #define DRIVER_DESC "Realtek RTL8152/RTL8153 Based USB Ethernet Adapters" #define MODULENAME "r8152" +-/* LED0: Activity, LED1: Link */ +-static int ledsel = 0x78; +-module_param(ledsel, int, 0); +-MODULE_PARM_DESC(ledsel, "Override default LED configuration"); +#define PATENTS "This product is covered by one or more of the " \ + "following patents:\n" \ + "\t\tUS6,570,884, US6,115,776, and US6,327,625.\n" -+ + #define R8152_PHY_ID 32 - #define PLA_IDR 0xc000 -@@ -129,7 +129,6 @@ +@@ -59,15 +55,22 @@ MODULE_PARM_DESC(ledsel, "Override default LED configuration"); + #define PLA_TEREDO_WAKE_BASE 0xc0c4 + #define PLA_MAR 0xcd00 + #define PLA_BACKUP 0xd000 +-#define PAL_BDC_CR 0xd1a0 ++#define PLA_BDC_CR 0xd1a0 + #define PLA_TEREDO_TIMER 0xd2cc + #define PLA_REALWOW_TIMER 0xd2e8 ++#define PLA_UPHY_TIMER 0xd388 ++#define PLA_SUSPEND_FLAG 0xd38a ++#define PLA_INDICATE_FALG 0xd38c ++#define PLA_MACDBG_PRE 0xd38c /* RTL_VER_04 only */ ++#define PLA_MACDBG_POST 0xd38e /* RTL_VER_04 only */ ++#define PLA_EXTRA_STATUS 0xd398 + #define PLA_EFUSE_DATA 0xdd00 + #define PLA_EFUSE_CMD 0xdd02 + #define PLA_LEDSEL 0xdd90 + #define PLA_LED_FEATURE 0xdd92 + #define PLA_PHYAR 0xde00 + #define PLA_BOOT_CTRL 0xe004 ++#define PLA_LWAKE_CTRL_REG 0xe007 + #define PLA_GPHY_INTR_IMR 0xe022 + #define PLA_EEE_CR 0xe040 + #define PLA_EEEP_CR 0xe080 +@@ -95,6 +98,7 @@ MODULE_PARM_DESC(ledsel, "Override default LED configuration"); + #define PLA_TALLYCNT 0xe890 + #define PLA_SFF_STS_7 0xe8de + #define PLA_PHYSTATUS 0xe908 ++#define PLA_CONFIG6 0xe90a /* CONFIG6 */ + #define PLA_BP_BA 0xfc26 + #define PLA_BP_0 0xfc28 + #define PLA_BP_1 0xfc2a +@@ -107,6 +111,7 @@ MODULE_PARM_DESC(ledsel, "Override default LED configuration"); + #define PLA_BP_EN 0xfc38 + + #define USB_USB2PHY 0xb41e ++#define USB_SSPHYLINK1 0xb426 + #define USB_SSPHYLINK2 0xb428 + #define USB_U2P3_CTRL 0xb460 + #define USB_CSR_DUMMY1 0xb464 +@@ -115,7 +120,13 @@ MODULE_PARM_DESC(ledsel, "Override default LED configuration"); + #define USB_CONNECT_TIMER 0xcbf8 + #define USB_MSC_TIMER 0xcbfc + #define USB_BURST_SIZE 0xcfc0 ++#define USB_FW_FIX_EN0 0xcfca ++#define USB_FW_FIX_EN1 0xcfcc + #define USB_LPM_CONFIG 0xcfd8 ++#define USB_EFUSE 0xcfdb ++#define USB_CSTMR 0xcfef /* RTL8153A */ ++#define USB_FW_CTRL 0xd334 /* RTL8153B */ ++#define USB_FC_TIMER 0xd340 + #define USB_USB_CTRL 0xd406 + #define USB_PHY_CTRL 0xd408 + #define USB_TX_AGG 0xd40a +@@ -131,6 +142,7 @@ MODULE_PARM_DESC(ledsel, "Override default LED configuration"); + #define USB_LPM_CTRL 0xd41a + #define USB_BMU_RESET 0xd4b0 + #define USB_U1U2_TIMER 0xd4da ++#define USB_FW_TASK 0xd4e8 /* RTL8153B */ #define USB_UPS_CTRL 0xd800 #define USB_POWER_CUT 0xd80a #define USB_MISC_0 0xd81a --#define USB_MISC_1 0xd81f +@@ -138,18 +150,19 @@ MODULE_PARM_DESC(ledsel, "Override default LED configuration"); #define USB_AFE_CTRL2 0xd824 #define USB_UPS_CFG 0xd842 #define USB_UPS_FLAGS 0xd848 -@@ -298,6 +297,7 @@ ++#define USB_WDT1_CTRL 0xe404 + #define USB_WDT11_CTRL 0xe43c +-#define USB_BP_BA 0xfc26 +-#define USB_BP_0 0xfc28 +-#define USB_BP_1 0xfc2a +-#define USB_BP_2 0xfc2c +-#define USB_BP_3 0xfc2e +-#define USB_BP_4 0xfc30 +-#define USB_BP_5 0xfc32 +-#define USB_BP_6 0xfc34 +-#define USB_BP_7 0xfc36 +-#define USB_BP_EN 0xfc38 +-#define USB_BP_8 0xfc38 ++#define USB_BP_BA PLA_BP_BA ++#define USB_BP_0 PLA_BP_0 ++#define USB_BP_1 PLA_BP_1 ++#define USB_BP_2 PLA_BP_2 ++#define USB_BP_3 PLA_BP_3 ++#define USB_BP_4 PLA_BP_4 ++#define USB_BP_5 PLA_BP_5 ++#define USB_BP_6 PLA_BP_6 ++#define USB_BP_7 PLA_BP_7 ++#define USB_BP_EN PLA_BP_EN /* RTL8153A */ ++#define USB_BP_8 0xfc38 /* RTL8153B */ + #define USB_BP_9 0xfc3a + #define USB_BP_10 0xfc3c + #define USB_BP_11 0xfc3e +@@ -180,6 +193,7 @@ MODULE_PARM_DESC(ledsel, "Override default LED configuration"); + #define OCP_PHY_STATE 0xa708 /* nway state for 8153 */ + #define OCP_PHY_PATCH_STAT 0xb800 + #define OCP_PHY_PATCH_CMD 0xb820 ++#define OCP_PHY_LOCK 0xb82e + #define OCP_ADC_IOFFSET 0xbcfc + #define OCP_ADC_CFG 0xbc06 + #define OCP_SYSCLK_CFG 0xc416 +@@ -190,6 +204,7 @@ MODULE_PARM_DESC(ledsel, "Override default LED configuration"); + #define SRAM_10M_AMP1 0x8080 + #define SRAM_10M_AMP2 0x8082 + #define SRAM_IMPEDANCE 0x8084 ++#define SRAM_PHY_LOCK 0xb82e + + /* PLA_RCR */ + #define RCR_AAP 0x00000001 +@@ -280,7 +295,7 @@ MODULE_PARM_DESC(ledsel, "Override default LED configuration"); + #define TEREDO_RS_EVENT_MASK 0x00fe + #define OOB_TEREDO_EN 0x0001 + +-/* PAL_BDC_CR */ ++/* PLA_BDC_CR */ + #define ALDPS_PROXY_MODE 0x0001 + + /* PLA_EFUSE_CMD */ +@@ -291,6 +306,9 @@ MODULE_PARM_DESC(ledsel, "Override default LED configuration"); + #define LINK_ON_WAKE_EN 0x0010 + #define LINK_OFF_WAKE_EN 0x0008 + ++/* PLA_CONFIG6 */ ++#define LANWAKE_CLR_EN BIT(0) ++ + /* PLA_CONFIG5 */ + #define BWF_EN 0x0040 + #define MWF_EN 0x0020 +@@ -303,6 +321,7 @@ MODULE_PARM_DESC(ledsel, "Override default LED configuration"); /* PLA_PHY_PWR */ #define TX_10M_IDLE_EN 0x0080 #define PFM_PWM_SWITCH 0x0040 @@ -578,7 +768,113 @@ index 2490498b..26cc7c1a 100644 /* PLA_MAC_PWR_CTRL */ #define D3_CLK_GATED_EN 0x00004000 -@@ -441,13 +441,14 @@ +@@ -315,6 +334,7 @@ MODULE_PARM_DESC(ledsel, "Override default LED configuration"); + #define MAC_CLK_SPDWN_EN BIT(15) + + /* PLA_MAC_PWR_CTRL3 */ ++#define PLA_MCU_SPDWN_EN BIT(14) + #define PKT_AVAIL_SPDWN_EN 0x0100 + #define SUSPEND_SPDWN_EN 0x0004 + #define U1U2_SPDWN_EN 0x0002 +@@ -345,10 +365,32 @@ MODULE_PARM_DESC(ledsel, "Override default LED configuration"); + /* PLA_BOOT_CTRL */ + #define AUTOLOAD_DONE 0x0002 + ++/* PLA_LWAKE_CTRL_REG */ ++#define LANWAKE_PIN BIT(7) ++ ++/* PLA_SUSPEND_FLAG */ ++#define LINK_CHG_EVENT BIT(0) ++ ++/* PLA_INDICATE_FALG */ ++#define UPCOMING_RUNTIME_D3 BIT(0) ++ ++/* PLA_MACDBG_PRE and PLA_MACDBG_POST */ ++#define DEBUG_OE BIT(0) ++#define DEBUG_LTSSM 0x0082 ++ ++/* PLA_EXTRA_STATUS */ ++#define CUR_LINK_OK BIT(15) ++#define U3P3_CHECK_EN BIT(7) /* RTL_VER_05 only */ ++#define LINK_CHANGE_FLAG BIT(8) ++#define POLL_LINK_CHG BIT(0) ++ + /* USB_USB2PHY */ + #define USB2PHY_SUSPEND 0x0001 + #define USB2PHY_L1 0x0002 + ++/* USB_SSPHYLINK1 */ ++#define DELAY_PHY_PWR_CHG BIT(1) ++ + /* USB_SSPHYLINK2 */ + #define pwd_dn_scale_mask 0x3ffe + #define pwd_dn_scale(x) ((x) << 1) +@@ -364,9 +406,18 @@ MODULE_PARM_DESC(ledsel, "Override default LED configuration"); + #define STAT_SPEED_HIGH 0x0000 + #define STAT_SPEED_FULL 0x0002 + ++/* USB_FW_FIX_EN0 */ ++#define FW_FIX_SUSPEND BIT(14) ++ ++/* USB_FW_FIX_EN1 */ ++#define FW_IP_RESET_EN BIT(9) ++ + /* USB_LPM_CONFIG */ + #define LPM_U1U2_EN BIT(0) + ++/* USB_EFUSE */ ++#define PASS_THRU_MASK BIT(0) ++ + /* USB_TX_AGG */ + #define TX_AGG_MAX_THRESHOLD 0x03 + +@@ -388,12 +439,24 @@ MODULE_PARM_DESC(ledsel, "Override default LED configuration"); + #define OWN_UPDATE BIT(0) + #define OWN_CLEAR BIT(1) + ++/* USB_FW_TASK */ ++#define FC_PATCH_TASK BIT(1) ++ + /* USB_UPS_CTRL */ + #define POWER_CUT 0x0100 + + /* USB_PM_CTRL_STATUS */ + #define RESUME_INDICATE 0x0001 + ++/* USB_CSTMR */ ++#define FORCE_SUPER BIT(0) ++ ++/* USB_FW_CTRL */ ++#define FLOW_CTRL_PATCH_OPT BIT(1) ++ ++/* USB_FC_TIMER */ ++#define CTRL_TIMER_EN BIT(15) ++ + /* USB_USB_CTRL */ + #define RX_AGG_DISABLE 0x0010 + #define RX_ZERO_EN 0x0080 +@@ -409,12 +472,20 @@ MODULE_PARM_DESC(ledsel, "Override default LED configuration"); + + /* USB_MISC_0 */ + #define PCUT_STATUS 0x0001 ++#define AD_MASK 0xfee0 ++ ++/* USB_MISC_1 */ ++#define BD_MASK BIT(0) ++#define BND_MASK BIT(2) + + /* USB_RX_EARLY_TIMEOUT */ + #define COALESCE_SUPER 85000U + #define COALESCE_HIGH 250000U + #define COALESCE_SLOW 524280U + ++/* USB_WDT1_CTRL */ ++#define WTD1_EN BIT(0) ++ + /* USB_WDT11_CTRL */ + #define TIMER11_EN 0x0001 + +@@ -446,13 +517,14 @@ MODULE_PARM_DESC(ledsel, "Override default LED configuration"); #define UPS_FLAGS_EN_EEE BIT(20) #define UPS_FLAGS_EN_500M_EEE BIT(21) #define UPS_FLAGS_EN_EEE_CKDIV BIT(22) @@ -594,7 +890,7 @@ index 2490498b..26cc7c1a 100644 NWAY_10M_FULL, NWAY_100M_HALF, NWAY_100M_FULL, -@@ -456,6 +457,8 @@ enum spd_duplex { +@@ -461,6 +533,8 @@ enum spd_duplex { FORCE_10M_FULL, FORCE_100M_HALF, FORCE_100M_FULL, @@ -603,7 +899,17 @@ index 2490498b..26cc7c1a 100644 }; /* OCP_ALDPS_CONFIG */ -@@ -554,14 +557,10 @@ enum spd_duplex { +@@ -535,6 +609,9 @@ enum spd_duplex { + /* OCP_PHY_PATCH_CMD */ + #define PATCH_REQUEST BIT(4) + ++/* OCP_PHY_LOCK */ ++#define PATCH_LOCK BIT(0) ++ + /* OCP_ADC_CFG */ + #define CKADSEL_L 0x0100 + #define ADC_EN 0x0080 +@@ -559,14 +636,13 @@ enum spd_duplex { /* SRAM_IMPEDANCE */ #define RX_DRIVING_MASK 0x6000 @@ -613,7 +919,9 @@ index 2490498b..26cc7c1a 100644 -#define BD_MASK 0x0001 -#define EFUSE 0xcfdb -#define PASS_THRU_MASK 0x1 -- ++/* SRAM_PHY_LOCK */ ++#define PHY_PATCH_LOCK 0x0001 + enum rtl_register_content { + _2500bps = BIT(10), + _1250bps = BIT(9), @@ -621,7 +929,30 @@ index 2490498b..26cc7c1a 100644 _1000bps = 0x10, _100bps = 0x08, _10bps = 0x04, -@@ -607,9 +606,10 @@ enum rtl8152_flags { +@@ -580,6 +656,9 @@ enum rtl_register_content { + #define TX_ALIGN 4 + #define RX_ALIGN 8 + ++#define RTL8152_RX_MAX_PENDING 4096 ++#define RTL8152_RXFG_HEADSZ 256 ++ + #define INTR_LINK 0x0004 + + #define RTL8152_REQT_READ 0xc0 +@@ -600,10 +679,11 @@ enum rtl_register_content { + #define RTL8152_RMS (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN) + #define RTL8153_RMS RTL8153_MAX_PACKET + #define RTL8152_TX_TIMEOUT (5 * HZ) +-#define RTL8152_NAPI_WEIGHT 64 + #define rx_reserved_size(x) ((x) + VLAN_ETH_HLEN + ETH_FCS_LEN + \ + sizeof(struct rx_desc) + RX_ALIGN) + ++#define RTL_MAX_SG_NUM 64 ++ + /* rtl8152 flags */ + enum rtl8152_flags { + RTL8152_UNPLUG = 0, +@@ -612,9 +692,9 @@ enum rtl8152_flags { RTL8152_LINK_CHG, SELECTIVE_SUSPEND, PHY_RESET, @@ -630,22 +961,10 @@ index 2490498b..26cc7c1a 100644 GREEN_ETHERNET, - DELL_TB_RX_AGG_BUG, + RECOVER_SPEED, -+ SUPPORT_2500FULL, }; /* Define these values to match your device */ -@@ -617,9 +617,8 @@ enum rtl8152_flags { - #define VENDOR_ID_MICROSOFT 0x045e - #define VENDOR_ID_SAMSUNG 0x04e8 - #define VENDOR_ID_LENOVO 0x17ef --#define VENDOR_ID_LINKSYS 0x13b1 --#define VENDOR_ID_NVIDIA 0x0955 - #define VENDOR_ID_TPLINK 0x2357 -+#define VENDOR_ID_NVIDIA 0x0955 - - #define MCU_TYPE_PLA 0x0100 - #define MCU_TYPE_USB 0x0000 -@@ -642,6 +641,7 @@ struct tally_counter { +@@ -647,6 +727,7 @@ struct tally_counter { struct rx_desc { __le32 opts1; @@ -653,7 +972,7 @@ index 2490498b..26cc7c1a 100644 #define RX_LEN_MASK 0x7fff __le32 opts2; -@@ -665,6 +665,7 @@ struct tx_desc { +@@ -670,6 +751,7 @@ struct tx_desc { __le32 opts1; #define TX_FS BIT(31) /* First segment of a packet */ #define TX_LS BIT(30) /* Final segment of a packet */ @@ -661,7 +980,36 @@ index 2490498b..26cc7c1a 100644 #define GTSENDV4 BIT(28) #define GTSENDV6 BIT(27) #define GTTCPHO_SHIFT 18 -@@ -718,9 +719,16 @@ struct r8152 { +@@ -691,17 +773,18 @@ struct tx_desc { + struct r8152; + + struct rx_agg { +- struct list_head list; ++ struct list_head list, info_list; + struct urb *urb; + struct r8152 *context; ++ struct page *page; + void *buffer; +- void *head; + }; + + struct tx_agg { + struct list_head list; + struct urb *urb; + struct r8152 *context; ++ struct sk_buff_head tx_skb; + void *buffer; + void *head; + u32 skb_num; +@@ -716,40 +799,82 @@ struct r8152 { + struct net_device *netdev; + struct urb *intr_urb; + struct tx_agg tx_info[RTL8152_MAX_TX]; +- struct rx_agg rx_info[RTL8152_MAX_RX]; ++ struct list_head rx_info, rx_used; + struct list_head rx_done, tx_free; + struct sk_buff_head tx_queue, rx_queue; + spinlock_t rx_lock, tx_lock; struct delayed_work schedule, hw_phy_work; struct mii_if_info mii; struct mutex control; /* use for hw setting */ @@ -678,17 +1026,28 @@ index 2490498b..26cc7c1a 100644 + struct tasklet_struct tx_tl; struct rtl_ops { - void (*init)(struct r8152 *); -@@ -729,22 +737,46 @@ struct r8152 { - void (*up)(struct r8152 *); - void (*down)(struct r8152 *); - void (*unload)(struct r8152 *); +- void (*init)(struct r8152 *); +- int (*enable)(struct r8152 *); +- void (*disable)(struct r8152 *); +- void (*up)(struct r8152 *); +- void (*down)(struct r8152 *); +- void (*unload)(struct r8152 *); +- int (*eee_get)(struct r8152 *, struct ethtool_eee *); +- int (*eee_set)(struct r8152 *, struct ethtool_eee *); +- bool (*in_nway)(struct r8152 *); +- void (*hw_phy_cfg)(struct r8152 *); ++ void (*init)(struct r8152 *tp); ++ int (*enable)(struct r8152 *tp); ++ void (*disable)(struct r8152 *tp); ++ void (*up)(struct r8152 *tp); ++ void (*down)(struct r8152 *tp); ++ void (*unload)(struct r8152 *tp); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) - int (*eee_get)(struct r8152 *, struct ethtool_eee *); - int (*eee_set)(struct r8152 *, struct ethtool_eee *); ++ int (*eee_get)(struct r8152 *tp, struct ethtool_eee *eee); ++ int (*eee_set)(struct r8152 *tp, struct ethtool_eee *eee); +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) */ - bool (*in_nway)(struct r8152 *); - void (*hw_phy_cfg)(struct r8152 *); ++ bool (*in_nway)(struct r8152 *tp); ++ void (*hw_phy_cfg)(struct r8152 *tp); void (*autosuspend_en)(struct r8152 *tp, bool enable); } rtl_ops; @@ -709,6 +1068,8 @@ index 2490498b..26cc7c1a 100644 + u32 ctap_short_off:1; + } ups_info; + ++ atomic_t rx_count; ++ + bool eee_en; int intr_interval; u32 saved_wolopts; @@ -717,6 +1078,15 @@ index 2490498b..26cc7c1a 100644 u32 coalesce; + u32 advertising; + u32 rx_buf_sz; ++ u32 rx_copybreak; ++ u32 rx_pending; ++ u32 fc_pause, fc_restart; ++ ++ u32 support_2500full:1; ++ u32 sg_use:1; ++// u32 dash_mode:1; ++ u32 lenovo_macpassthru:1; ++ u16 ocp_base; u16 speed; + u16 eee_adv; @@ -726,7 +1096,7 @@ index 2490498b..26cc7c1a 100644 u8 duplex; u8 autoneg; }; -@@ -760,6 +792,11 @@ enum rtl_version { +@@ -765,6 +890,13 @@ enum rtl_version { RTL_VER_07, RTL_VER_08, RTL_VER_09, @@ -734,11 +1104,50 @@ index 2490498b..26cc7c1a 100644 + RTL_TEST_01, + RTL_VER_10, + RTL_VER_11, ++ RTL_VER_12, ++ RTL_VER_13, + RTL_VER_MAX }; -@@ -817,6 +857,14 @@ int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) +@@ -774,6 +906,14 @@ enum tx_csum_stat { + TX_CSUM_NONE + }; + ++#define RTL_ADVERTISED_10_HALF BIT(0) ++#define RTL_ADVERTISED_10_FULL BIT(1) ++#define RTL_ADVERTISED_100_HALF BIT(2) ++#define RTL_ADVERTISED_100_FULL BIT(3) ++#define RTL_ADVERTISED_1000_HALF BIT(4) ++#define RTL_ADVERTISED_1000_FULL BIT(5) ++#define RTL_ADVERTISED_2500_FULL BIT(6) ++ + /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). + * The RTL chips use a 64 element hash table based on the Ethernet CRC. + */ +@@ -803,6 +943,12 @@ int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) + + kfree(tmp); + ++ if (ret < 0) { ++ if (ret == -ETIMEDOUT) ++ usb_queue_reset_device(tp->intf); ++ netif_err(tp, drv, tp->netdev, "get_registers %d\n", ret); ++ } ++ + return ret; + } + +@@ -822,9 +968,23 @@ int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) + + kfree(tmp); + ++ if (ret < 0) { ++ if (ret == -ETIMEDOUT) ++ usb_queue_reset_device(tp->intf); ++ netif_err(tp, drv, tp->netdev, "set_registers %d\n", ret); ++ } ++ return ret; } @@ -753,7 +1162,7 @@ index 2490498b..26cc7c1a 100644 static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size, void *data, u16 type) { -@@ -855,7 +903,7 @@ static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size, +@@ -863,7 +1023,7 @@ static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size, } if (ret == -ENODEV) @@ -762,7 +1171,7 @@ index 2490498b..26cc7c1a 100644 return ret; } -@@ -925,7 +973,7 @@ static int generic_ocp_write(struct r8152 *tp, u16 index, u16 byteen, +@@ -933,7 +1093,7 @@ static int generic_ocp_write(struct r8152 *tp, u16 index, u16 byteen, error1: if (ret == -ENODEV) @@ -771,7 +1180,7 @@ index 2490498b..26cc7c1a 100644 return ret; } -@@ -942,6 +990,12 @@ int pla_ocp_write(struct r8152 *tp, u16 index, u16 byteen, u16 size, void *data) +@@ -950,6 +1110,12 @@ int pla_ocp_write(struct r8152 *tp, u16 index, u16 byteen, u16 size, void *data) return generic_ocp_write(tp, index, byteen, size, data, MCU_TYPE_PLA); } @@ -784,7 +1193,7 @@ index 2490498b..26cc7c1a 100644 static inline int usb_ocp_write(struct r8152 *tp, u16 index, u16 byteen, u16 size, void *data) { -@@ -1095,7 +1149,7 @@ static u16 sram_read(struct r8152 *tp, u16 addr) +@@ -1103,7 +1269,7 @@ static u16 sram_read(struct r8152 *tp, u16 addr) static int read_mii_word(struct net_device *netdev, int phy_id, int reg) { struct r8152 *tp = netdev_priv(netdev); @@ -793,7 +1202,7 @@ index 2490498b..26cc7c1a 100644 if (test_bit(RTL8152_UNPLUG, &tp->flags)) return -ENODEV; -@@ -1103,8 +1157,15 @@ static int read_mii_word(struct net_device *netdev, int phy_id, int reg) +@@ -1111,8 +1277,15 @@ static int read_mii_word(struct net_device *netdev, int phy_id, int reg) if (phy_id != R8152_PHY_ID) return -EINVAL; @@ -809,7 +1218,7 @@ index 2490498b..26cc7c1a 100644 return ret; } -@@ -1112,6 +1173,7 @@ static +@@ -1120,6 +1293,7 @@ static void write_mii_word(struct net_device *netdev, int phy_id, int reg, int val) { struct r8152 *tp = netdev_priv(netdev); @@ -817,7 +1226,7 @@ index 2490498b..26cc7c1a 100644 if (test_bit(RTL8152_UNPLUG, &tp->flags)) return; -@@ -1119,18 +1181,32 @@ void write_mii_word(struct net_device *netdev, int phy_id, int reg, int val) +@@ -1127,18 +1301,32 @@ void write_mii_word(struct net_device *netdev, int phy_id, int reg, int val) if (phy_id != R8152_PHY_ID) return; @@ -850,22 +1259,10 @@ index 2490498b..26cc7c1a 100644 if (!is_valid_ether_addr(addr->sa_data)) goto out1; -@@ -1153,90 +1229,16 @@ out1: - return ret; - } - --/* Devices containing proper chips can support a persistent -- * host system provided MAC address. -- * Examples of this are Dell TB15 and Dell WD15 docks -- */ --static int vendor_mac_passthru_addr_read(struct r8152 *tp, struct sockaddr *sa) --{ -- acpi_status status; -- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; -- union acpi_object *obj; -- int ret = -EINVAL; -- u32 ocp_data; -- unsigned char buf[6]; +@@ -1173,38 +1361,52 @@ static int vendor_mac_passthru_addr_read(struct r8152 *tp, struct sockaddr *sa) + int ret = -EINVAL; + u32 ocp_data; + unsigned char buf[6]; - - /* test for -AD variant of RTL8153 */ - ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); @@ -877,77 +1274,141 @@ index 2490498b..26cc7c1a 100644 - "No efuse for RTL8153-AD MAC pass through\n"); - return -ENODEV; - } -- } else { ++ char *mac_obj_name; ++ acpi_object_type mac_obj_type; ++ int mac_strlen; ++ ++ if (tp->lenovo_macpassthru) { ++ mac_obj_name = "\\MACA"; ++ mac_obj_type = ACPI_TYPE_STRING; ++ mac_strlen = 0x16; + } else { - /* test for RTL8153-BND and RTL8153-BD */ - ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_1); - if ((ocp_data & BND_MASK) == 0 && (ocp_data & BD_MASK) == 0) { - netif_dbg(tp, probe, tp->netdev, - "Invalid variant for MAC pass through\n"); - return -ENODEV; -- } -- } -- -- /* returns _AUXMAC_#AABBCCDDEEFF# */ ++ /* test for -AD variant of RTL8153 */ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); ++ if ((ocp_data & AD_MASK) == 0x1000) { ++ /* test for MAC address pass-through bit */ ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_EFUSE); ++ if ((ocp_data & PASS_THRU_MASK) != 1) { ++ netif_dbg(tp, probe, tp->netdev, ++ "No efuse for RTL8153-AD MAC pass through\n"); ++ return -ENODEV; ++ } ++ } else { ++ /* test for RTL8153-BND and RTL8153-BD */ ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_1); ++ if ((ocp_data & BND_MASK) == 0 && (ocp_data & BD_MASK) == 0) { ++ netif_dbg(tp, probe, tp->netdev, ++ "Invalid variant for MAC pass through\n"); ++ return -ENODEV; ++ } + } ++ ++ mac_obj_name = "\\_SB.AMAC"; ++ mac_obj_type = ACPI_TYPE_BUFFER; ++ mac_strlen = 0x17; + } + + /* returns _AUXMAC_#AABBCCDDEEFF# */ - status = acpi_evaluate_object(NULL, "\\_SB.AMAC", NULL, &buffer); -- obj = (union acpi_object *)buffer.pointer; -- if (!ACPI_SUCCESS(status)) -- return -ENODEV; ++ status = acpi_evaluate_object(NULL, mac_obj_name, NULL, &buffer); + obj = (union acpi_object *)buffer.pointer; + if (!ACPI_SUCCESS(status)) + return -ENODEV; - if (obj->type != ACPI_TYPE_BUFFER || obj->string.length != 0x17) { -- netif_warn(tp, probe, tp->netdev, -- "Invalid buffer for pass-thru MAC addr: (%d, %d)\n", -- obj->type, obj->string.length); -- goto amacout; -- } -- if (strncmp(obj->string.pointer, "_AUXMAC_#", 9) != 0 || -- strncmp(obj->string.pointer + 0x15, "#", 1) != 0) { -- netif_warn(tp, probe, tp->netdev, -- "Invalid header when reading pass-thru MAC addr\n"); -- goto amacout; -- } -- ret = hex2bin(buf, obj->string.pointer + 9, 6); -- if (!(ret == 0 && is_valid_ether_addr(buf))) { -- netif_warn(tp, probe, tp->netdev, -- "Invalid MAC for pass-thru MAC addr: %d, %pM\n", -- ret, buf); -- ret = -EINVAL; -- goto amacout; -- } -- memcpy(sa->sa_data, buf, 6); ++ if (obj->type != mac_obj_type || obj->string.length != mac_strlen) { + netif_warn(tp, probe, tp->netdev, + "Invalid buffer for pass-thru MAC addr: (%d, %d)\n", + obj->type, obj->string.length); + goto amacout; + } ++ + if (strncmp(obj->string.pointer, "_AUXMAC_#", 9) != 0 || + strncmp(obj->string.pointer + 0x15, "#", 1) != 0) { + netif_warn(tp, probe, tp->netdev, +@@ -1220,7 +1422,6 @@ static int vendor_mac_passthru_addr_read(struct r8152 *tp, struct sockaddr *sa) + goto amacout; + } + memcpy(sa->sa_data, buf, 6); - ether_addr_copy(tp->netdev->dev_addr, sa->sa_data); -- netif_info(tp, probe, tp->netdev, -- "Using pass-thru MAC addr %pM\n", sa->sa_data); -- --amacout: -- kfree(obj); -- return ret; --} -- - static int set_ethernet_addr(struct r8152 *tp) - { - struct net_device *dev = tp->netdev; - struct sockaddr sa; - int ret; + netif_info(tp, probe, tp->netdev, + "Using pass-thru MAC addr %pM\n", sa->sa_data); -- if (tp->version == RTL_VER_01) { -+ if (tp->version == RTL_VER_01) - ret = pla_ocp_read(tp, PLA_IDR, 8, sa.sa_data); -- } else { -- /* if device doesn't support MAC pass through this will -- * be expected to be non-zero -- */ -- ret = vendor_mac_passthru_addr_read(tp, &sa); -- if (ret < 0) -- ret = pla_ocp_read(tp, PLA_BACKUP, 8, sa.sa_data); -- } -+ else -+ ret = pla_ocp_read(tp, PLA_BACKUP, 8, sa.sa_data); - - if (ret < 0) { - netif_err(tp, probe, dev, "Get ether addr fail\n"); -@@ -1258,6 +1260,17 @@ static int set_ethernet_addr(struct r8152 *tp) +@@ -1229,43 +1430,68 @@ amacout: return ret; } +-static int set_ethernet_addr(struct r8152 *tp) ++static int determine_ethernet_addr(struct r8152 *tp, struct sockaddr *sa) + { + struct net_device *dev = tp->netdev; +- struct sockaddr sa; + int ret; + ++ sa->sa_family = dev->type; ++ + if (tp->version == RTL_VER_01) { +- ret = pla_ocp_read(tp, PLA_IDR, 8, sa.sa_data); ++ ret = pla_ocp_read(tp, PLA_IDR, 8, sa->sa_data); + } else { + /* if device doesn't support MAC pass through this will + * be expected to be non-zero + */ +- ret = vendor_mac_passthru_addr_read(tp, &sa); ++ ret = vendor_mac_passthru_addr_read(tp, sa); + if (ret < 0) +- ret = pla_ocp_read(tp, PLA_BACKUP, 8, sa.sa_data); ++ ret = pla_ocp_read(tp, PLA_BACKUP, 8, sa->sa_data); + } + + if (ret < 0) { + netif_err(tp, probe, dev, "Get ether addr fail\n"); +- } else if (!is_valid_ether_addr(sa.sa_data)) { ++ } else if (!is_valid_ether_addr(sa->sa_data)) { + netif_err(tp, probe, dev, "Invalid ether addr %pM\n", +- sa.sa_data); ++ sa->sa_data); + eth_hw_addr_random(dev); +- ether_addr_copy(sa.sa_data, dev->dev_addr); +- ret = rtl8152_set_mac_address(dev, &sa); ++ ether_addr_copy(sa->sa_data, dev->dev_addr); + netif_info(tp, probe, dev, "Random ether addr %pM\n", +- sa.sa_data); +- } else { +- if (tp->version == RTL_VER_01) +- ether_addr_copy(dev->dev_addr, sa.sa_data); +- else +- ret = rtl8152_set_mac_address(dev, &sa); ++ sa->sa_data); ++ return 0; + } + + return ret; + } + ++static int set_ethernet_addr(struct r8152 *tp) ++{ ++ struct net_device *dev = tp->netdev; ++ struct sockaddr sa; ++ int ret; ++ ++ ret = determine_ethernet_addr(tp, &sa); ++ if (ret < 0) ++ return ret; ++ ++ if (tp->version == RTL_VER_01) ++ ether_addr_copy(dev->dev_addr, sa.sa_data); ++ else ++ ret = rtl8152_set_mac_address(dev, &sa); ++ ++ return ret; ++} ++ +static inline struct net_device_stats *rtl8152_get_stats(struct net_device *dev) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) @@ -962,7 +1423,7 @@ index 2490498b..26cc7c1a 100644 static void read_bulk_callback(struct urb *urb) { struct net_device *netdev; -@@ -1300,18 +1313,20 @@ static void read_bulk_callback(struct urb *urb) +@@ -1308,18 +1534,20 @@ static void read_bulk_callback(struct urb *urb) napi_schedule(&tp->napi); return; case -ESHUTDOWN: @@ -986,7 +1447,7 @@ index 2490498b..26cc7c1a 100644 break; } -@@ -1336,10 +1351,11 @@ static void write_bulk_callback(struct urb *urb) +@@ -1344,10 +1572,11 @@ static void write_bulk_callback(struct urb *urb) return; netdev = tp->netdev; @@ -1000,24 +1461,69 @@ index 2490498b..26cc7c1a 100644 stats->tx_errors += agg->skb_num; } else { stats->tx_packets += agg->skb_num; -@@ -1362,7 +1378,7 @@ static void write_bulk_callback(struct urb *urb) +@@ -1370,7 +1599,60 @@ static void write_bulk_callback(struct urb *urb) return; if (!skb_queue_empty(&tp->tx_queue)) - napi_schedule(&tp->napi); ++ tasklet_schedule(&tp->tx_tl); ++} ++ ++static void write_bulk_sg_callback(struct urb *urb) ++{ ++ struct net_device *netdev; ++ struct tx_agg *agg; ++ struct r8152 *tp; ++ unsigned long flags; ++ int status = urb->status; ++ ++ agg = urb->context; ++ if (!agg) ++ return; ++ ++ tp = agg->context; ++ if (!tp) ++ return; ++ ++ netdev = tp->netdev; ++ if (status && net_ratelimit()) ++ netif_warn(tp, tx_err, netdev, "Tx status %d\n", status); ++ ++ while (!skb_queue_empty(&agg->tx_skb)) { ++ struct sk_buff *skb = __skb_dequeue(&agg->tx_skb); ++ struct net_device_stats *stats = rtl8152_get_stats(netdev); ++ ++ if (status) { ++ stats->tx_errors += skb_shinfo(skb)->gso_segs ?: 1; ++ dev_kfree_skb_any(skb); ++ } else { ++ stats->tx_packets += skb_shinfo(skb)->gso_segs ?: 1; ++ stats->tx_bytes += skb->len - skb->cb[0]; ++ dev_consume_skb_any(skb); ++ } ++ } ++ ++ spin_lock_irqsave(&tp->tx_lock, flags); ++ list_add_tail(&agg->list, &tp->tx_free); ++ spin_unlock_irqrestore(&tp->tx_lock, flags); ++ ++ usb_autopm_put_interface_async(tp->intf); ++ ++ if (!netif_carrier_ok(netdev)) ++ return; ++ ++ if (!test_bit(WORK_ENABLE, &tp->flags)) ++ return; ++ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return; ++ ++ if (!skb_queue_empty(&tp->tx_queue)) + tasklet_schedule(&tp->tx_tl); } static void intr_callback(struct urb *urb) -@@ -1388,7 +1404,6 @@ static void intr_callback(struct urb *urb) - case -ECONNRESET: /* unlink */ - case -ESHUTDOWN: - netif_device_detach(tp->netdev); -- /* fall through */ - case -ENOENT: - case -EPROTO: - netif_info(tp, intr, tp->netdev, -@@ -1420,7 +1435,7 @@ static void intr_callback(struct urb *urb) +@@ -1428,7 +1710,7 @@ static void intr_callback(struct urb *urb) resubmit: res = usb_submit_urb(urb, GFP_ATOMIC); if (res == -ENODEV) { @@ -1026,23 +1532,157 @@ index 2490498b..26cc7c1a 100644 netif_device_detach(tp->netdev); } else if (res) { netif_err(tp, intr, tp->netdev, -@@ -1487,13 +1502,13 @@ static int alloc_all_mem(struct r8152 *tp) +@@ -1446,18 +1728,72 @@ static inline void *tx_agg_align(void *data) + return (void *)ALIGN((uintptr_t)data, TX_ALIGN); + } + ++static void free_rx_agg(struct r8152 *tp, struct rx_agg *agg) ++{ ++ list_del(&agg->info_list); ++ ++ usb_free_urb(agg->urb); ++ put_page(agg->page); ++ kfree(agg); ++ ++ atomic_dec(&tp->rx_count); ++} ++ ++static struct rx_agg *alloc_rx_agg(struct r8152 *tp, gfp_t mflags) ++{ ++ struct net_device *netdev = tp->netdev; ++ int node = netdev->dev.parent ? dev_to_node(netdev->dev.parent) : -1; ++ unsigned int order = get_order(tp->rx_buf_sz); ++ struct rx_agg *rx_agg; ++ unsigned long flags; ++ ++ rx_agg = kmalloc_node(sizeof(*rx_agg), mflags, node); ++ if (!rx_agg) ++ return NULL; ++ ++ rx_agg->page = alloc_pages(mflags | __GFP_COMP, order); ++ if (!rx_agg->page) ++ goto free_rx; ++ ++ rx_agg->buffer = page_address(rx_agg->page); ++ ++ rx_agg->urb = usb_alloc_urb(0, mflags); ++ if (!rx_agg->urb) ++ goto free_buf; ++ ++ rx_agg->context = tp; ++ ++ INIT_LIST_HEAD(&rx_agg->list); ++ INIT_LIST_HEAD(&rx_agg->info_list); ++ spin_lock_irqsave(&tp->rx_lock, flags); ++ list_add_tail(&rx_agg->info_list, &tp->rx_info); ++ spin_unlock_irqrestore(&tp->rx_lock, flags); ++ ++ atomic_inc(&tp->rx_count); ++ ++ return rx_agg; ++ ++free_buf: ++ __free_pages(rx_agg->page, order); ++free_rx: ++ kfree(rx_agg); ++ return NULL; ++} ++ + static void free_all_mem(struct r8152 *tp) + { ++ struct rx_agg *agg, *agg_next; ++ unsigned long flags; + int i; + +- for (i = 0; i < RTL8152_MAX_RX; i++) { +- usb_free_urb(tp->rx_info[i].urb); +- tp->rx_info[i].urb = NULL; ++ spin_lock_irqsave(&tp->rx_lock, flags); + +- kfree(tp->rx_info[i].buffer); +- tp->rx_info[i].buffer = NULL; +- tp->rx_info[i].head = NULL; +- } ++ list_for_each_entry_safe(agg, agg_next, &tp->rx_info, info_list) ++ free_rx_agg(tp, agg); ++ ++ spin_unlock_irqrestore(&tp->rx_lock, flags); ++ ++ WARN_ON(atomic_read(&tp->rx_count)); + + for (i = 0; i < RTL8152_MAX_TX; i++) { + usb_free_urb(tp->tx_info[i].urb); +@@ -1481,46 +1817,28 @@ static int alloc_all_mem(struct r8152 *tp) + struct usb_interface *intf = tp->intf; + struct usb_host_interface *alt = intf->cur_altsetting; + struct usb_host_endpoint *ep_intr = alt->endpoint + 2; +- struct urb *urb; + int node, i; +- u8 *buf; + + node = netdev->dev.parent ? dev_to_node(netdev->dev.parent) : -1; + + spin_lock_init(&tp->rx_lock); + spin_lock_init(&tp->tx_lock); ++ INIT_LIST_HEAD(&tp->rx_info); + INIT_LIST_HEAD(&tp->tx_free); + INIT_LIST_HEAD(&tp->rx_done); + skb_queue_head_init(&tp->tx_queue); skb_queue_head_init(&tp->rx_queue); ++ atomic_set(&tp->rx_count, 0); for (i = 0; i < RTL8152_MAX_RX; i++) { - buf = kmalloc_node(agg_buf_sz, GFP_KERNEL, node); -+ buf = kmalloc_node(tp->rx_buf_sz, GFP_KERNEL, node); +- if (!buf) +- goto err1; +- +- if (buf != rx_agg_align(buf)) { +- kfree(buf); +- buf = kmalloc_node(agg_buf_sz + RX_ALIGN, GFP_KERNEL, +- node); +- if (!buf) +- goto err1; +- } +- +- urb = usb_alloc_urb(0, GFP_KERNEL); +- if (!urb) { +- kfree(buf); ++ if (!alloc_rx_agg(tp, GFP_KERNEL)) + goto err1; +- } +- +- INIT_LIST_HEAD(&tp->rx_info[i].list); +- tp->rx_info[i].context = tp; +- tp->rx_info[i].urb = urb; +- tp->rx_info[i].buffer = buf; +- tp->rx_info[i].head = rx_agg_align(buf); + } + + for (i = 0; i < RTL8152_MAX_TX; i++) { ++ struct urb *urb; ++ u8 *buf; ++ + buf = kmalloc_node(agg_buf_sz, GFP_KERNEL, node); if (!buf) goto err1; +@@ -1546,6 +1864,7 @@ static int alloc_all_mem(struct r8152 *tp) + tp->tx_info[i].head = tx_agg_align(buf); - if (buf != rx_agg_align(buf)) { - kfree(buf); -- buf = kmalloc_node(agg_buf_sz + RX_ALIGN, GFP_KERNEL, -+ buf = kmalloc_node(tp->rx_buf_sz + RX_ALIGN, GFP_KERNEL, - node); - if (!buf) - goto err1; -@@ -1618,7 +1633,7 @@ static void r8152_csum_workaround(struct r8152 *tp, struct sk_buff *skb, + list_add_tail(&tp->tx_info[i].list, &tp->tx_free); ++ skb_queue_head_init(&tp->tx_info[i].tx_skb); + } + + tp->intr_urb = usb_alloc_urb(0, GFP_KERNEL); +@@ -1590,7 +1909,7 @@ static struct tx_agg *r8152_get_tx_agg(struct r8152 *tp) + } + + /* r8152_csum_workaround() +- * The hw limites the value the transport offset. When the offset is out of the ++ * The hw limits the value of the transport offset. When the offset is out of + * range, calculate the checksum by sw. + */ + static void r8152_csum_workaround(struct r8152 *tp, struct sk_buff *skb, +@@ -1626,7 +1945,7 @@ static void r8152_csum_workaround(struct r8152 *tp, struct sk_buff *skb, struct net_device_stats *stats; drop: @@ -1051,7 +1691,7 @@ index 2490498b..26cc7c1a 100644 stats->tx_dropped++; dev_kfree_skb(skb); } -@@ -1657,15 +1672,62 @@ static inline void rtl_tx_vlan_tag(struct tx_desc *desc, struct sk_buff *skb) +@@ -1665,15 +1984,62 @@ static inline void rtl_tx_vlan_tag(struct tx_desc *desc, struct sk_buff *skb) } } @@ -1114,8 +1754,12 @@ index 2490498b..26cc7c1a 100644 static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, struct sk_buff *skb, u32 len, u32 transport_offset) { -@@ -1814,9 +1876,6 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg) - dev_kfree_skb_any(skb); +@@ -1819,12 +2185,9 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg) + agg->skb_len += len; + agg->skb_num += skb_shinfo(skb)->gso_segs ?: 1; + +- dev_kfree_skb_any(skb); ++ dev_consume_skb_any(skb); remain = agg_buf_sz - (int)(tx_agg_align(tx_data) - agg->head); - @@ -1124,7 +1768,268 @@ index 2490498b..26cc7c1a 100644 } if (!skb_queue_empty(&skb_head)) { -@@ -1889,15 +1948,34 @@ static int rx_bottom(struct r8152 *tp, int budget) +@@ -1849,6 +2212,9 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg) + agg->head, (int)(tx_data - (u8 *)agg->head), + (usb_complete_t)write_bulk_callback, agg); + ++ agg->urb->sg = NULL; ++ agg->urb->num_sgs = 0; ++ + ret = usb_submit_urb(agg->urb, GFP_ATOMIC); + if (ret < 0) + usb_autopm_put_interface_async(tp->intf); +@@ -1857,39 +2223,223 @@ out_tx_fill: + return ret; + } + +-static u8 r8152_rx_csum(struct r8152 *tp, struct rx_desc *rx_desc) ++static int r8152_tx_agg_sg_fill(struct r8152 *tp, struct tx_agg *agg) + { +- u8 checksum = CHECKSUM_NONE; +- u32 opts2, opts3; ++ struct sk_buff_head skb_head, *tx_queue = &tp->tx_queue; ++ int max_sg_num, ret, sg_num; ++ struct scatterlist *sg; ++ int padding = 0; + +- if (!(tp->netdev->features & NETIF_F_RXCSUM)) +- goto return_result; ++ __skb_queue_head_init(&skb_head); ++ spin_lock(&tx_queue->lock); ++ skb_queue_splice_init(tx_queue, &skb_head); ++ spin_unlock(&tx_queue->lock); + +- opts2 = le32_to_cpu(rx_desc->opts2); +- opts3 = le32_to_cpu(rx_desc->opts3); ++ sg = agg->head; ++ max_sg_num = (agg_buf_sz / sizeof(*sg)) - 1; ++ max_sg_num = min_t(int, RTL_MAX_SG_NUM, max_sg_num); ++ sg_init_table(sg, max_sg_num + 1); ++ agg->skb_num = 0; ++ agg->skb_len = 0; + +- if (opts2 & RD_IPV4_CS) { +- if (opts3 & IPF) +- checksum = CHECKSUM_NONE; +- else if ((opts2 & RD_UDP_CS) && !(opts3 & UDPF)) +- checksum = CHECKSUM_UNNECESSARY; +- else if ((opts2 & RD_TCP_CS) && !(opts3 & TCPF)) +- checksum = CHECKSUM_UNNECESSARY; +- } else if (opts2 & RD_IPV6_CS) { +- if ((opts2 & RD_UDP_CS) && !(opts3 & UDPF)) +- checksum = CHECKSUM_UNNECESSARY; +- else if ((opts2 & RD_TCP_CS) && !(opts3 & TCPF)) +- checksum = CHECKSUM_UNNECESSARY; +- } ++ for (sg_num = 0; sg_num < max_sg_num;) { ++ struct tx_desc tx_desc; ++ struct sk_buff *skb; ++ int num_sgs, headroom; ++ unsigned int len; ++ u32 offset; + +-return_result: +- return checksum; +-} ++ skb = __skb_dequeue(&skb_head); ++ if (!skb) ++ break; + +-static int rx_bottom(struct r8152 *tp, int budget) +-{ +- unsigned long flags; +- struct list_head *cursor, *next, rx_queue; ++ headroom = skb_headroom(skb) - padding - sizeof(tx_desc); ++ ++ if (skb_header_cloned(skb) || headroom < 0) { ++ struct sk_buff *tx_skb; ++ ++ headroom = padding + sizeof(tx_desc); ++ tx_skb = skb_copy_expand(skb, headroom, 0, GFP_ATOMIC); ++ dev_kfree_skb_any(skb); ++ if (!tx_skb) { ++ struct net_device_stats *stats; ++ ++ stats = rtl8152_get_stats(tp->netdev); ++ stats->tx_dropped++; ++ netif_wake_queue(tp->netdev); ++ return NETDEV_TX_OK; ++ } ++ skb = tx_skb; ++ headroom = skb_headroom(skb) - headroom; ++ } ++ ++ /* calculate the fragment numbers for skb */ ++ num_sgs = 1 + skb_shinfo(skb)->nr_frags; ++ len = skb->len; ++ ++ if ((num_sgs + sg_num) > max_sg_num) { ++ __skb_queue_head(&skb_head, skb); ++ break; ++ } ++ ++ offset = (u32)skb_transport_offset(skb); ++ ++ if (r8152_tx_csum(tp, &tx_desc, skb, len, offset)) { ++ r8152_csum_workaround(tp, skb, &skb_head); ++ continue; ++ } ++ ++ rtl_tx_vlan_tag(&tx_desc, skb); ++ ++ WARN_ON(padding < 0); ++ ++ /* use skb_headroom for tx desc */ ++ skb->cb[0] = padding + sizeof(tx_desc); ++ memcpy(skb_push(skb, sizeof(tx_desc)), &tx_desc, ++ sizeof(tx_desc)); ++ if (padding) ++ memset(skb_push(skb, padding), 0, padding); ++ ++ num_sgs = skb_to_sgvec_nomark(skb, sg, 0, skb->len); ++ if (num_sgs < 0) { ++ netif_err(tp, tx_err, tp->netdev, ++ "skb_to_sgvec fail %d\n", num_sgs); ++ __skb_queue_head(&skb_head, skb); ++ break; ++ } ++ ++ sg += num_sgs; ++ ++ __skb_queue_tail(&agg->tx_skb, skb); ++ ++ sg_num += num_sgs; ++ agg->skb_len += skb->len; ++ padding = len + sizeof(tx_desc); ++ ++ agg->skb_num++; ++ ++ padding = ALIGN(padding, TX_ALIGN) - padding; ++ } ++ ++ sg_mark_end(sg); ++ ++ if (!skb_queue_empty(&skb_head)) { ++ spin_lock(&tx_queue->lock); ++ skb_queue_splice(&skb_head, tx_queue); ++ spin_unlock(&tx_queue->lock); ++ } ++ ++ netif_tx_lock(tp->netdev); ++ ++ if (netif_queue_stopped(tp->netdev) && ++ skb_queue_len(&tp->tx_queue) < tp->tx_qlen) ++ netif_wake_queue(tp->netdev); ++ ++ netif_tx_unlock(tp->netdev); ++ ++ if (sg_num == 0) { ++ unsigned long flags; ++ ++ spin_lock_irqsave(&tp->tx_lock, flags); ++ list_add_tail(&agg->list, &tp->tx_free); ++ spin_unlock_irqrestore(&tp->tx_lock, flags); ++ ++ ret = 0; ++ goto out_tx_fill; ++ } ++ ++ ret = usb_autopm_get_interface_async(tp->intf); ++ if (ret < 0) ++ goto out_tx_fill; ++ ++ usb_fill_bulk_urb(agg->urb, tp->udev, usb_sndbulkpipe(tp->udev, 2), ++ NULL, (int)agg->skb_len, ++ (usb_complete_t)write_bulk_sg_callback, agg); ++ ++ agg->urb->sg = agg->head; ++ agg->urb->num_sgs = sg_num; ++ ++ ret = usb_submit_urb(agg->urb, GFP_ATOMIC); ++ if (ret < 0) ++ usb_autopm_put_interface_async(tp->intf); ++ ++out_tx_fill: ++ return ret; ++} ++ ++static u8 r8152_rx_csum(struct r8152 *tp, struct rx_desc *rx_desc) ++{ ++ u8 checksum = CHECKSUM_NONE; ++ u32 opts2, opts3; ++ ++ if (!(tp->netdev->features & NETIF_F_RXCSUM)) ++ goto return_result; ++ ++ opts2 = le32_to_cpu(rx_desc->opts2); ++ opts3 = le32_to_cpu(rx_desc->opts3); ++ ++ if (opts2 & RD_IPV4_CS) { ++ if (opts3 & IPF) ++ checksum = CHECKSUM_NONE; ++ else if ((opts2 & RD_UDP_CS) && !(opts3 & UDPF)) ++ checksum = CHECKSUM_UNNECESSARY; ++ else if ((opts2 & RD_TCP_CS) && !(opts3 & TCPF)) ++ checksum = CHECKSUM_UNNECESSARY; ++ } else if (opts2 & RD_IPV6_CS) { ++ if ((opts2 & RD_UDP_CS) && !(opts3 & UDPF)) ++ checksum = CHECKSUM_UNNECESSARY; ++ else if ((opts2 & RD_TCP_CS) && !(opts3 & TCPF)) ++ checksum = CHECKSUM_UNNECESSARY; ++ } ++ ++return_result: ++ return checksum; ++} ++ ++static inline bool rx_count_exceed(struct r8152 *tp) ++{ ++ return atomic_read(&tp->rx_count) > RTL8152_MAX_RX; ++} ++ ++static inline int agg_offset(struct rx_agg *agg, void *addr) ++{ ++ return (int)(addr - agg->buffer); ++} ++ ++static struct rx_agg *rtl_get_free_rx(struct r8152 *tp, gfp_t mflags) ++{ ++ struct rx_agg *agg, *agg_next, *agg_free = NULL; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&tp->rx_lock, flags); ++ ++ list_for_each_entry_safe(agg, agg_next, &tp->rx_used, list) { ++ if (page_count(agg->page) == 1) { ++ if (!agg_free) { ++ list_del_init(&agg->list); ++ agg_free = agg; ++ continue; ++ } ++ if (rx_count_exceed(tp)) { ++ list_del_init(&agg->list); ++ free_rx_agg(tp, agg); ++ } ++ break; ++ } ++ } ++ ++ spin_unlock_irqrestore(&tp->rx_lock, flags); ++ ++ if (!agg_free && atomic_read(&tp->rx_count) < tp->rx_pending) ++ agg_free = alloc_rx_agg(tp, mflags); ++ ++ return agg_free; ++} ++ ++static int rx_bottom(struct r8152 *tp, int budget) ++{ ++ unsigned long flags; ++ struct list_head *cursor, *next, rx_queue; + int ret = 0, work_done = 0; + struct napi_struct *napi = &tp->napi; + +@@ -1897,15 +2447,34 @@ static int rx_bottom(struct r8152 *tp, int budget) while (work_done < budget) { struct sk_buff *skb = __skb_dequeue(&tp->rx_queue); struct net_device *netdev = tp->netdev; @@ -1160,16 +2065,37 @@ index 2490498b..26cc7c1a 100644 stats->rx_packets++; stats->rx_bytes += pkt_len; } -@@ -1931,7 +2009,7 @@ static int rx_bottom(struct r8152 *tp, int budget) +@@ -1921,7 +2490,7 @@ static int rx_bottom(struct r8152 *tp, int budget) + + list_for_each_safe(cursor, next, &rx_queue) { + struct rx_desc *rx_desc; +- struct rx_agg *agg; ++ struct rx_agg *agg, *agg_free; + int len_used = 0; + struct urb *urb; + u8 *rx_data; +@@ -1933,14 +2502,16 @@ static int rx_bottom(struct r8152 *tp, int budget) + if (urb->actual_length < ETH_ZLEN) + goto submit; + +- rx_desc = agg->head; +- rx_data = agg->head; ++ agg_free = rtl_get_free_rx(tp, GFP_ATOMIC); ++ ++ rx_desc = agg->buffer; ++ rx_data = agg->buffer; + len_used += sizeof(struct rx_desc); while (urb->actual_length > len_used) { struct net_device *netdev = tp->netdev; - struct net_device_stats *stats = &netdev->stats; +- unsigned int pkt_len; + struct net_device_stats *stats; - unsigned int pkt_len; ++ unsigned int pkt_len, rx_frag_head_sz; struct sk_buff *skb; -@@ -1947,6 +2025,8 @@ static int rx_bottom(struct r8152 *tp, int budget) + /* limite the skb numbers for rx_queue */ +@@ -1955,36 +2526,87 @@ static int rx_bottom(struct r8152 *tp, int budget) if (urb->actual_length < len_used) break; @@ -1178,10 +2104,33 @@ index 2490498b..26cc7c1a 100644 pkt_len -= ETH_FCS_LEN; rx_data += sizeof(struct rx_desc); -@@ -1959,7 +2039,26 @@ static int rx_bottom(struct r8152 *tp, int budget) +- skb = napi_alloc_skb(napi, pkt_len); ++ if (!agg_free || tp->rx_copybreak > pkt_len) ++ rx_frag_head_sz = pkt_len; ++ else ++ rx_frag_head_sz = tp->rx_copybreak; ++ ++ skb = napi_alloc_skb(napi, rx_frag_head_sz); + if (!skb) { + stats->rx_dropped++; + goto find_next_rx; + } + skb->ip_summed = r8152_rx_csum(tp, rx_desc); - memcpy(skb->data, rx_data, pkt_len); - skb_put(skb, pkt_len); +- memcpy(skb->data, rx_data, pkt_len); +- skb_put(skb, pkt_len); ++ memcpy(skb->data, rx_data, rx_frag_head_sz); ++ skb_put(skb, rx_frag_head_sz); ++ pkt_len -= rx_frag_head_sz; ++ rx_data += rx_frag_head_sz; ++ if (pkt_len) { ++ skb_add_rx_frag(skb, 0, agg->page, ++ agg_offset(agg, rx_data), ++ pkt_len, ++ SKB_DATA_ALIGN(pkt_len)); ++ get_page(agg->page); ++ } ++ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) + skb->dev = netdev; +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) */ @@ -1196,7 +2145,7 @@ index 2490498b..26cc7c1a 100644 +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) */ + work_done++; + stats->rx_packets++; -+ stats->rx_bytes += pkt_len; ++ stats->rx_bytes += skb->len; + } else { + rtl_vlan_put_tag(tp, rx_desc, skb); + __skb_queue_tail(&tp->rx_queue, skb); @@ -1204,8 +2153,12 @@ index 2490498b..26cc7c1a 100644 +#else rtl_rx_vlan_tag(rx_desc, skb); if (work_done < budget) { - napi_gro_receive(napi, skb); -@@ -1969,6 +2068,7 @@ static int rx_bottom(struct r8152 *tp, int budget) +- napi_gro_receive(napi, skb); + work_done++; + stats->rx_packets++; +- stats->rx_bytes += pkt_len; ++ stats->rx_bytes += skb->len; ++ napi_gro_receive(napi, skb); } else { __skb_queue_tail(&tp->rx_queue, skb); } @@ -1213,23 +2166,80 @@ index 2490498b..26cc7c1a 100644 find_next_rx: rx_data = rx_agg_align(rx_data + pkt_len + ETH_FCS_LEN); -@@ -2015,12 +2115,13 @@ static void tx_bottom(struct r8152 *tp) - struct net_device *netdev = tp->netdev; + rx_desc = (struct rx_desc *)rx_data; +- len_used = (int)(rx_data - (u8 *)agg->head); ++ len_used = agg_offset(agg, rx_data); + len_used += sizeof(struct rx_desc); + } - if (res == -ENODEV) { ++ WARN_ON(!agg_free && page_count(agg->page) > 1); ++ ++ if (agg_free) { ++ spin_lock_irqsave(&tp->rx_lock, flags); ++ if (page_count(agg->page) == 1) { ++ list_add(&agg_free->list, &tp->rx_used); ++ } else { ++ list_add_tail(&agg->list, &tp->rx_used); ++ agg = agg_free; ++ urb = agg->urb; ++ } ++ spin_unlock_irqrestore(&tp->rx_lock, flags); ++ } ++ + submit: + if (!ret) { + ret = r8152_submit_rx(tp, agg, GFP_ATOMIC); +@@ -2009,6 +2631,7 @@ static void tx_bottom(struct r8152 *tp) + int res; + + do { ++ struct net_device *netdev = tp->netdev; + struct tx_agg *agg; + + if (skb_queue_empty(&tp->tx_queue)) +@@ -2018,31 +2641,38 @@ static void tx_bottom(struct r8152 *tp) + if (!agg) + break; + +- res = r8152_tx_agg_fill(tp, agg); +- if (res) { +- struct net_device *netdev = tp->netdev; ++ if (tp->sg_use) ++ res = r8152_tx_agg_sg_fill(tp, agg); ++ else ++ res = r8152_tx_agg_fill(tp, agg); + +- if (res == -ENODEV) { - set_bit(RTL8152_UNPLUG, &tp->flags); -+ rtl_set_unplug(tp); - netif_device_detach(netdev); - } else { +- netif_device_detach(netdev); +- } else { - struct net_device_stats *stats = &netdev->stats; -+ struct net_device_stats *stats; - unsigned long flags; +- unsigned long flags; ++ if (!res) ++ continue; ++ ++ if (res == -ENODEV) { ++ rtl_set_unplug(tp); ++ netif_device_detach(netdev); ++ } else { ++ struct net_device_stats *stats = &netdev->stats; ++ unsigned long flags; -+ stats = rtl8152_get_stats(netdev); - netif_warn(tp, tx_err, netdev, - "failed tx_urb %d\n", res); - stats->tx_dropped += agg->skb_num; -@@ -2033,8 +2134,12 @@ static void tx_bottom(struct r8152 *tp) +- netif_warn(tp, tx_err, netdev, +- "failed tx_urb %d\n", res); +- stats->tx_dropped += agg->skb_num; ++ netif_warn(tp, tx_err, netdev, ++ "failed tx_urb %d\n", res); ++ stats->tx_dropped += agg->skb_num; + +- spin_lock_irqsave(&tp->tx_lock, flags); +- list_add_tail(&agg->list, &tp->tx_free); +- spin_unlock_irqrestore(&tp->tx_lock, flags); +- } ++ spin_lock_irqsave(&tp->tx_lock, flags); ++ list_add_tail(&agg->list, &tp->tx_free); ++ spin_unlock_irqrestore(&tp->tx_lock, flags); + } } while (res == 0); } @@ -1243,7 +2253,7 @@ index 2490498b..26cc7c1a 100644 if (test_bit(RTL8152_UNPLUG, &tp->flags)) return; -@@ -2046,31 +2151,62 @@ static void bottom_half(struct r8152 *tp) +@@ -2054,31 +2684,62 @@ static void bottom_half(struct r8152 *tp) if (!netif_carrier_ok(tp->netdev)) return; @@ -1314,12 +2324,12 @@ index 2490498b..26cc7c1a 100644 static int r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags) { -@@ -2082,12 +2218,12 @@ int r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags) +@@ -2090,12 +2751,12 @@ int r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags) return 0; usb_fill_bulk_urb(agg->urb, tp->udev, usb_rcvbulkpipe(tp->udev, 1), - agg->head, agg_buf_sz, -+ agg->head, tp->rx_buf_sz, ++ agg->buffer, tp->rx_buf_sz, (usb_complete_t)read_bulk_callback, agg); ret = usb_submit_urb(agg->urb, mem_flags); @@ -1329,7 +2339,7 @@ index 2490498b..26cc7c1a 100644 netif_device_detach(tp->netdev); } else if (ret) { struct urb *urb = agg->urb; -@@ -2109,7 +2245,7 @@ int r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags) +@@ -2117,7 +2778,7 @@ int r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags) static void rtl_drop_queued_tx(struct r8152 *tp) { @@ -1338,8 +2348,15 @@ index 2490498b..26cc7c1a 100644 struct sk_buff_head skb_head, *tx_queue = &tp->tx_queue; struct sk_buff *skb; -@@ -2130,29 +2266,40 @@ static void rtl_drop_queued_tx(struct r8152 *tp) +@@ -2135,32 +2796,47 @@ static void rtl_drop_queued_tx(struct r8152 *tp) + } + } + ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5,6,0) static void rtl8152_tx_timeout(struct net_device *netdev) ++#else ++static void rtl8152_tx_timeout(struct net_device *netdev, unsigned int txqueue) ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5,6,0) */ { struct r8152 *tp = netdev_priv(netdev); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) @@ -1389,7 +2406,7 @@ index 2490498b..26cc7c1a 100644 netif_stop_queue(netdev); ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); ocp_data &= ~RCR_ACPT_ALL; -@@ -2171,6 +2318,21 @@ static void _rtl8152_set_rx_mode(struct net_device *netdev) +@@ -2179,6 +2855,21 @@ static void _rtl8152_set_rx_mode(struct net_device *netdev) mc_filter[1] = 0xffffffff; mc_filter[0] = 0xffffffff; } else { @@ -1411,7 +2428,7 @@ index 2490498b..26cc7c1a 100644 struct netdev_hw_addr *ha; mc_filter[1] = 0; -@@ -2181,6 +2343,7 @@ static void _rtl8152_set_rx_mode(struct net_device *netdev) +@@ -2189,6 +2880,7 @@ static void _rtl8152_set_rx_mode(struct net_device *netdev) mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); ocp_data |= RCR_AM; } @@ -1419,21 +2436,35 @@ index 2490498b..26cc7c1a 100644 } tmp[0] = __cpu_to_le32(swab32(mc_filter[1])); -@@ -2191,6 +2354,7 @@ static void _rtl8152_set_rx_mode(struct net_device *netdev) +@@ -2199,6 +2891,20 @@ static void _rtl8152_set_rx_mode(struct net_device *netdev) netif_wake_queue(netdev); } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,4) ++ ++static inline bool rtl_gso_check(struct net_device *dev, struct sk_buff *skb) ++{ ++ struct r8152 *tp = netdev_priv(dev); ++ ++ if (tp->sg_use) ++ return true; ++ else if ((skb->len + sizeof(struct tx_desc)) <= agg_buf_sz) ++ return true; ++ else ++ return false; ++} ++ static netdev_features_t rtl8152_features_check(struct sk_buff *skb, struct net_device *dev, netdev_features_t features) -@@ -2200,29 +2364,57 @@ rtl8152_features_check(struct sk_buff *skb, struct net_device *dev, +@@ -2208,29 +2914,57 @@ rtl8152_features_check(struct sk_buff *skb, struct net_device *dev, int offset = skb_transport_offset(skb); if ((mss || skb->ip_summed == CHECKSUM_PARTIAL) && offset > max_offset) - features &= ~(NETIF_F_ALL_CSUM | NETIF_F_GSO_MASK); +- else if ((skb->len + sizeof(struct tx_desc)) > agg_buf_sz) + features &= ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK); - else if ((skb->len + sizeof(struct tx_desc)) > agg_buf_sz) ++ else if (!rtl_gso_check(dev, skb)) features &= ~NETIF_F_GSO_MASK; return features; @@ -1446,7 +2477,7 @@ index 2490498b..26cc7c1a 100644 struct r8152 *tp = netdev_priv(netdev); +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,4) -+ if (unlikely((skb->len + sizeof(struct tx_desc)) > agg_buf_sz)) { ++ if (unlikely(!rtl_gso_check(netdev, skb)) { + netdev_features_t features = netdev->features; + struct sk_buff *segs, *nskb; + @@ -1488,11 +2519,101 @@ index 2490498b..26cc7c1a 100644 } } else if (skb_queue_len(&tp->tx_queue) > tp->tx_qlen) { netif_stop_queue(netdev); -@@ -2263,15 +2455,15 @@ static void set_tx_qlen(struct r8152 *tp) - sizeof(struct tx_desc)); - } +@@ -2241,7 +2975,7 @@ static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb, + + static void r8152b_reset_packet_filter(struct r8152 *tp) + { +- u32 ocp_data; ++ u32 ocp_data; + + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_FMC); + ocp_data &= ~FMC_FCR_MCU_EN; +@@ -2252,34 +2986,82 @@ static void r8152b_reset_packet_filter(struct r8152 *tp) + + static void rtl8152_nic_reset(struct r8152 *tp) + { +- int i; ++ u32 ocp_data; ++ int i; + +- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, CR_RST); ++ switch (tp->version) { ++ case RTL_TEST_01: ++ case RTL_VER_10: ++ case RTL_VER_11: ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR); ++ ocp_data &= ~CR_TE; ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xd4b0); ++ ocp_data &= ~BIT(0); ++ ocp_write_word(tp, MCU_TYPE_USB, 0xd4b0, ocp_data); + +- for (i = 0; i < 1000; i++) { +- if (!(ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR) & CR_RST)) +- break; +- usleep_range(100, 400); +- } +-} ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xd406); ++ ocp_data |= BIT(3); ++ ocp_write_word(tp, MCU_TYPE_USB, 0xd406, ocp_data); + +-static void set_tx_qlen(struct r8152 *tp) +-{ +- struct net_device *netdev = tp->netdev; ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR); ++ ocp_data &= ~CR_RE; ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, ocp_data); + +- tp->tx_qlen = agg_buf_sz / (netdev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN + +- sizeof(struct tx_desc)); +-} ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xd4b0); ++ ocp_data |= BIT(0); ++ ocp_write_word(tp, MCU_TYPE_USB, 0xd4b0, ocp_data); -static inline u8 rtl8152_get_speed(struct r8152 *tp) ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xd406); ++ ocp_data &= ~BIT(3); ++ ocp_write_word(tp, MCU_TYPE_USB, 0xd406, ocp_data); ++ break; ++ ++ case RTL_VER_01: ++ case RTL_VER_02: ++ case RTL_VER_03: ++ case RTL_VER_04: ++ case RTL_VER_05: ++ case RTL_VER_06: ++ case RTL_VER_07: ++ case RTL_VER_08: ++ case RTL_VER_09: ++ case RTL_VER_12: ++ case RTL_VER_13: ++ default: ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, CR_RST); ++ ++ for (i = 0; i < 1000; i++) { ++ if (!(ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR) & CR_RST)) ++ break; ++ usleep_range(100, 400); ++ } ++ break; ++ } ++} ++ ++static void set_tx_qlen(struct r8152 *tp) ++{ ++ struct net_device *netdev = tp->netdev; ++ ++ if (tp->sg_use) ++ tp->tx_qlen = RTL_MAX_SG_NUM; ++ else ++ tp->tx_qlen = agg_buf_sz / (netdev->mtu + VLAN_ETH_HLEN + ++ ETH_FCS_LEN + ++ sizeof(struct tx_desc)); ++} ++ +static inline u16 rtl8152_get_speed(struct r8152 *tp) { - return ocp_read_byte(tp, MCU_TYPE_PLA, PLA_PHYSTATUS); @@ -1507,11 +2628,11 @@ index 2490498b..26cc7c1a 100644 speed = rtl8152_get_speed(tp); if (speed & _10bps) { -@@ -2297,6 +2489,30 @@ static void rxdy_gated_en(struct r8152 *tp, bool enable) +@@ -2305,46 +3087,106 @@ static void rxdy_gated_en(struct r8152 *tp, bool enable) ocp_write_word(tp, MCU_TYPE_PLA, PLA_MISC_1, ocp_data); } -+#if defined(RTL8152_S5_WOL) && defined(CONFIG_PM) ++#if defined(CONFIG_PM) +static int rtl_s5_wol(struct r8152 *tp) +{ + struct usb_device *udev = tp->udev; @@ -1537,8 +2658,108 @@ index 2490498b..26cc7c1a 100644 + static int rtl_start_rx(struct r8152 *tp) { - int i, ret = 0; -@@ -2344,6 +2560,12 @@ static int rtl_stop_rx(struct r8152 *tp) +- int i, ret = 0; ++ struct rx_agg *agg, *agg_next; ++ struct list_head tmp_list; ++ unsigned long flags; ++ int ret = 0, i = 0; + +- INIT_LIST_HEAD(&tp->rx_done); +- for (i = 0; i < RTL8152_MAX_RX; i++) { +- INIT_LIST_HEAD(&tp->rx_info[i].list); +- ret = r8152_submit_rx(tp, &tp->rx_info[i], GFP_KERNEL); +- if (ret) +- break; +- } ++ INIT_LIST_HEAD(&tmp_list); + +- if (ret && ++i < RTL8152_MAX_RX) { +- struct list_head rx_queue; +- unsigned long flags; ++ spin_lock_irqsave(&tp->rx_lock, flags); + +- INIT_LIST_HEAD(&rx_queue); ++ INIT_LIST_HEAD(&tp->rx_done); ++ INIT_LIST_HEAD(&tp->rx_used); + +- do { +- struct rx_agg *agg = &tp->rx_info[i++]; +- struct urb *urb = agg->urb; ++ list_splice_init(&tp->rx_info, &tmp_list); + +- urb->actual_length = 0; +- list_add_tail(&agg->list, &rx_queue); +- } while (i < RTL8152_MAX_RX); ++ spin_unlock_irqrestore(&tp->rx_lock, flags); + +- spin_lock_irqsave(&tp->rx_lock, flags); +- list_splice_tail(&rx_queue, &tp->rx_done); +- spin_unlock_irqrestore(&tp->rx_lock, flags); ++ list_for_each_entry_safe(agg, agg_next, &tmp_list, info_list) { ++ INIT_LIST_HEAD(&agg->list); ++ ++ /* Only RTL8152_MAX_RX rx_agg need to be submitted. */ ++ if (++i > RTL8152_MAX_RX) { ++ spin_lock_irqsave(&tp->rx_lock, flags); ++ list_add_tail(&agg->list, &tp->rx_used); ++ spin_unlock_irqrestore(&tp->rx_lock, flags); ++ } else if (unlikely(ret < 0)) { ++ spin_lock_irqsave(&tp->rx_lock, flags); ++ list_add_tail(&agg->list, &tp->rx_done); ++ spin_unlock_irqrestore(&tp->rx_lock, flags); ++ } else { ++ ret = r8152_submit_rx(tp, agg, GFP_KERNEL); ++ } + } + ++ spin_lock_irqsave(&tp->rx_lock, flags); ++ WARN_ON(!list_empty(&tp->rx_info)); ++ list_splice(&tmp_list, &tp->rx_info); ++ spin_unlock_irqrestore(&tp->rx_lock, flags); ++ + return ret; + } + + static int rtl_stop_rx(struct r8152 *tp) + { +- int i; ++ struct rx_agg *agg, *agg_next; ++ struct list_head tmp_list; ++ unsigned long flags; ++ ++ INIT_LIST_HEAD(&tmp_list); ++ ++ /* The usb_kill_urb() couldn't be used in atomic. ++ * Therefore, move the list of rx_info to a tmp one. ++ * Then, list_for_each_entry_safe could be used without ++ * spin lock. ++ */ ++ ++ spin_lock_irqsave(&tp->rx_lock, flags); ++ list_splice_init(&tp->rx_info, &tmp_list); ++ spin_unlock_irqrestore(&tp->rx_lock, flags); ++ ++ list_for_each_entry_safe(agg, agg_next, &tmp_list, info_list) { ++ /* At least RTL8152_MAX_RX rx_agg have the page_count being ++ * equal to 1, so the other ones could be freed safely. ++ */ ++ if (page_count(agg->page) > 1) ++ free_rx_agg(tp, agg); ++ else ++ usb_kill_urb(agg->urb); ++ } + +- for (i = 0; i < RTL8152_MAX_RX; i++) +- usb_kill_urb(tp->rx_info[i].urb); ++ /* Move back the list of temp to the rx_info */ ++ spin_lock_irqsave(&tp->rx_lock, flags); ++ WARN_ON(!list_empty(&tp->rx_info)); ++ list_splice(&tmp_list, &tp->rx_info); ++ spin_unlock_irqrestore(&tp->rx_lock, flags); + + while (!skb_queue_empty(&tp->rx_queue)) + dev_kfree_skb(__skb_dequeue(&tp->rx_queue)); +@@ -2352,6 +3194,12 @@ static int rtl_stop_rx(struct r8152 *tp) return 0; } @@ -1551,14 +2772,13 @@ index 2490498b..26cc7c1a 100644 static int rtl_enable(struct r8152 *tp) { u32 ocp_data; -@@ -2354,6 +2576,16 @@ static int rtl_enable(struct r8152 *tp) +@@ -2362,6 +3210,15 @@ static int rtl_enable(struct r8152 *tp) ocp_data |= CR_RE | CR_TE; ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, ocp_data); + switch (tp->version) { + case RTL_VER_08: + case RTL_VER_09: -+ case RTL_TEST_01: + r8153b_rx_agg_chg_indicate(tp); + break; + default: @@ -1568,7 +2788,7 @@ index 2490498b..26cc7c1a 100644 rxdy_gated_en(tp, false); return 0; -@@ -2370,12 +2602,6 @@ static int rtl8152_enable(struct r8152 *tp) +@@ -2378,12 +3235,6 @@ static int rtl8152_enable(struct r8152 *tp) return rtl_enable(tp); } @@ -1581,7 +2801,7 @@ index 2490498b..26cc7c1a 100644 static void r8153_set_rx_early_timeout(struct r8152 *tp) { u32 ocp_data = tp->coalesce / 8; -@@ -2392,10 +2618,19 @@ static void r8153_set_rx_early_timeout(struct r8152 *tp) +@@ -2400,10 +3251,20 @@ static void r8153_set_rx_early_timeout(struct r8152 *tp) case RTL_VER_08: case RTL_VER_09: /* The RTL8153B uses USB_RX_EXTRA_AGGR_TMR for rx timeout @@ -1595,15 +2815,16 @@ index 2490498b..26cc7c1a 100644 + ocp_data); + break; + -+ case RTL_TEST_01: + case RTL_VER_10: + case RTL_VER_11: ++ case RTL_VER_12: ++ case RTL_VER_13: + ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_TIMEOUT, + 640 / 8); ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EXTRA_AGGR_TMR, ocp_data); r8153b_rx_agg_chg_indicate(tp); -@@ -2408,7 +2643,7 @@ static void r8153_set_rx_early_timeout(struct r8152 *tp) +@@ -2416,7 +3277,7 @@ static void r8153_set_rx_early_timeout(struct r8152 *tp) static void r8153_set_rx_early_size(struct r8152 *tp) { @@ -1612,17 +2833,22 @@ index 2490498b..26cc7c1a 100644 switch (tp->version) { case RTL_VER_03: -@@ -2420,6 +2655,9 @@ static void r8153_set_rx_early_size(struct r8152 *tp) +@@ -2428,6 +3289,14 @@ static void r8153_set_rx_early_size(struct r8152 *tp) break; case RTL_VER_08: case RTL_VER_09: ++ ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_SIZE, ++ ocp_data / 8); ++ break; + case RTL_TEST_01: + case RTL_VER_10: + case RTL_VER_11: ++ case RTL_VER_12: ++ case RTL_VER_13: ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_SIZE, ocp_data / 8); r8153b_rx_agg_chg_indicate(tp); -@@ -2432,6 +2670,9 @@ static void r8153_set_rx_early_size(struct r8152 *tp) +@@ -2440,6 +3309,9 @@ static void r8153_set_rx_early_size(struct r8152 *tp) static int rtl8153_enable(struct r8152 *tp) { @@ -1632,7 +2858,7 @@ index 2490498b..26cc7c1a 100644 if (test_bit(RTL8152_UNPLUG, &tp->flags)) return -ENODEV; -@@ -2440,6 +2681,34 @@ static int rtl8153_enable(struct r8152 *tp) +@@ -2448,6 +3320,34 @@ static int rtl8153_enable(struct r8152 *tp) r8153_set_rx_early_timeout(tp); r8153_set_rx_early_size(tp); @@ -1656,85 +2882,24 @@ index 2490498b..26cc7c1a 100644 + } + + if (tp->version == RTL_VER_09) { -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xd4e8); -+ ocp_data &= ~BIT(1); -+ ocp_write_word(tp, MCU_TYPE_USB, 0xd4e8, ocp_data); ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_TASK); ++ ocp_data &= ~FC_PATCH_TASK; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); + usleep_range(1000, 2000); -+ ocp_data |= BIT(1); -+ ocp_write_word(tp, MCU_TYPE_USB, 0xd4e8, ocp_data); ++ ocp_data |= FC_PATCH_TASK; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); + } + return rtl_enable(tp); } -@@ -2479,7 +2748,51 @@ static void rtl_disable(struct r8152 *tp) - - rtl_stop_rx(tp); - -- rtl8152_nic_reset(tp); -+ switch (tp->version) { -+ case RTL_VER_01: -+ case RTL_VER_02: -+ case RTL_VER_03: -+ case RTL_VER_04: -+ case RTL_VER_05: -+ case RTL_VER_06: -+ case RTL_VER_07: -+ case RTL_VER_08: -+ case RTL_VER_09: -+ rtl8152_nic_reset(tp); -+ break; -+ -+ case RTL_TEST_01: -+ case RTL_VER_10: -+ case RTL_VER_11: -+ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR); -+ ocp_data &= ~CR_TE; -+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, ocp_data); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xd4b0); -+ ocp_data &= ~BIT(0); -+ ocp_write_word(tp, MCU_TYPE_USB, 0xd4b0, ocp_data); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xd406); -+ ocp_data |= BIT(3); -+ ocp_write_word(tp, MCU_TYPE_USB, 0xd406, ocp_data); -+ -+ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR); -+ ocp_data &= ~CR_RE; -+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, ocp_data); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xd4b0); -+ ocp_data |= BIT(0); -+ ocp_write_word(tp, MCU_TYPE_USB, 0xd4b0, ocp_data); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xd406); -+ ocp_data &= ~BIT(3); -+ ocp_write_word(tp, MCU_TYPE_USB, 0xd406, ocp_data); -+ break; -+ -+ default: -+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, 0); -+ break; -+ } - } - - static void r8152_power_cut_en(struct r8152 *tp, bool enable) -@@ -2502,21 +2815,85 @@ static void rtl_rx_vlan_en(struct r8152 *tp, bool enable) +@@ -2510,14 +3410,77 @@ static void rtl_rx_vlan_en(struct r8152 *tp, bool enable) { u32 ocp_data; - ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CPCR); - if (enable) - ocp_data |= CPCR_RX_VLAN; -- else -- ocp_data &= ~CPCR_RX_VLAN; -- ocp_write_word(tp, MCU_TYPE_PLA, PLA_CPCR, ocp_data); --} -- --static int rtl8152_set_features(struct net_device *dev, -- netdev_features_t features) --{ + switch (tp->version) { + case RTL_VER_01: + case RTL_VER_02: @@ -1756,13 +2921,15 @@ index 2490498b..26cc7c1a 100644 + case RTL_TEST_01: + case RTL_VER_10: + case RTL_VER_11: ++ case RTL_VER_12: ++ case RTL_VER_13: + default: + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, 0xc012); + if (enable) + ocp_data |= BIT(7) | BIT(6); + else + ocp_data &= ~(BIT(7) | BIT(6)); -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_CPCR, ocp_data); ++ ocp_write_word(tp, MCU_TYPE_PLA, 0xc012, ocp_data); + break; + } +} @@ -1785,7 +2952,9 @@ index 2490498b..26cc7c1a 100644 + tp->vlgrp = grp; + if (tp->vlgrp) + rtl_rx_vlan_en(tp, true); -+ else + else +- ocp_data &= ~CPCR_RX_VLAN; +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_CPCR, ocp_data); + rtl_rx_vlan_en(tp, false); + + mutex_unlock(&tp->control); @@ -1798,16 +2967,16 @@ index 2490498b..26cc7c1a 100644 + struct r8152 *tp = netdev_priv(dev); + + vlan_group_set_device(tp->vlgrp, vid, NULL); -+} -+ + } + +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) */ + +#else + -+static int rtl8152_set_features(struct net_device *dev, -+ netdev_features_t features) -+{ - netdev_features_t changed = features ^ dev->features; + static int rtl8152_set_features(struct net_device *dev, + netdev_features_t features) + { +@@ -2525,6 +3488,9 @@ static int rtl8152_set_features(struct net_device *dev, struct r8152 *tp = netdev_priv(dev); int ret; @@ -1817,7 +2986,7 @@ index 2490498b..26cc7c1a 100644 ret = usb_autopm_get_interface(tp->intf); if (ret < 0) goto out; -@@ -2538,6 +2915,8 @@ out: +@@ -2546,6 +3512,8 @@ out: return ret; } @@ -1826,7 +2995,7 @@ index 2490498b..26cc7c1a 100644 #define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST) static u32 __rtl_get_wol(struct r8152 *tp) -@@ -2623,6 +3002,26 @@ static void r8153_mac_clk_spd(struct r8152 *tp, bool enable) +@@ -2631,6 +3599,39 @@ static void r8153_mac_clk_spd(struct r8152 *tp, bool enable) } } @@ -1849,11 +3018,24 @@ index 2490498b..26cc7c1a 100644 + ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, ocp_data); + } +} ++ ++static void r8156b_mac_clk_spd(struct r8152 *tp, bool enable) ++{ ++ r8156_mac_clk_spd(tp, enable); ++ ++ if (enable) { ++ u32 ocp_data; ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4); ++ ocp_data |= BIT(6); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ocp_data); ++ } ++} + static void r8153_u1u2en(struct r8152 *tp, bool enable) { u8 u1u2[8]; -@@ -2660,14 +3059,158 @@ static void r8153_u2p3en(struct r8152 *tp, bool enable) +@@ -2668,20 +3669,177 @@ static void r8153_u2p3en(struct r8152 *tp, bool enable) ocp_write_word(tp, MCU_TYPE_USB, USB_U2P3_CTRL, ocp_data); } @@ -1874,11 +3056,7 @@ index 2490498b..26cc7c1a 100644 + + if (tp->ups_info.flow_control) + ups_flags |= UPS_FLAGS_EN_FLOW_CTR; - -- ocp_data = ocp_read_dword(tp, MCU_TYPE_USB, USB_UPS_FLAGS); -- ocp_data &= ~clear; -- ocp_data |= set; -- ocp_write_dword(tp, MCU_TYPE_USB, USB_UPS_FLAGS, ocp_data); ++ + if (tp->ups_info.eee_ckdiv) + ups_flags |= UPS_FLAGS_EN_EEE_CKDIV; + @@ -1902,39 +3080,44 @@ index 2490498b..26cc7c1a 100644 + + switch (tp->ups_info.speed_duplex) { + case NWAY_10M_HALF: -+ ups_flags |= 1 << 16; ++ ups_flags |= ups_flags_speed(1); + break; + case NWAY_10M_FULL: -+ ups_flags |= 2 << 16; ++ ups_flags |= ups_flags_speed(2); + break; + case NWAY_100M_HALF: -+ ups_flags |= 3 << 16; ++ ups_flags |= ups_flags_speed(3); + break; + case NWAY_100M_FULL: -+ ups_flags |= 4 << 16; ++ ups_flags |= ups_flags_speed(4); + break; + case NWAY_1000M_FULL: -+ ups_flags |= 5 << 16; ++ ups_flags |= ups_flags_speed(5); + break; + case FORCE_10M_HALF: -+ ups_flags |= 6 << 16; ++ ups_flags |= ups_flags_speed(6); + break; + case FORCE_10M_FULL: -+ ups_flags |= 7 << 16; ++ ups_flags |= ups_flags_speed(7); + break; + case FORCE_100M_HALF: -+ ups_flags |= 8 << 16; ++ ups_flags |= ups_flags_speed(8); + break; + case FORCE_100M_FULL: -+ ups_flags |= 9 << 16; ++ ups_flags |= ups_flags_speed(9); + break; + default: + break; + } -+ + +- ocp_data = ocp_read_dword(tp, MCU_TYPE_USB, USB_UPS_FLAGS); +- ocp_data &= ~clear; +- ocp_data |= set; +- ocp_write_dword(tp, MCU_TYPE_USB, USB_UPS_FLAGS, ocp_data); + ocp_write_dword(tp, MCU_TYPE_USB, USB_UPS_FLAGS, ups_flags); -+} -+ + } + +-static void r8153b_green_en(struct r8152 *tp, bool enable) +static void r8156_ups_flags(struct r8152 *tp) +{ + u32 ups_flags = 0; @@ -1968,34 +3151,34 @@ index 2490498b..26cc7c1a 100644 + + switch (tp->ups_info.speed_duplex) { + case FORCE_10M_HALF: -+ ups_flags |= 0 << 16; ++ ups_flags |= ups_flags_speed(0); + break; + case FORCE_10M_FULL: -+ ups_flags |= 1 << 16; ++ ups_flags |= ups_flags_speed(1); + break; + case FORCE_100M_HALF: -+ ups_flags |= 2 << 16; ++ ups_flags |= ups_flags_speed(2); + break; + case FORCE_100M_FULL: -+ ups_flags |= 3 << 16; ++ ups_flags |= ups_flags_speed(3); + break; + case NWAY_10M_HALF: -+ ups_flags |= 4 << 16; ++ ups_flags |= ups_flags_speed(4); + break; + case NWAY_10M_FULL: -+ ups_flags |= 5 << 16; ++ ups_flags |= ups_flags_speed(5); + break; + case NWAY_100M_HALF: -+ ups_flags |= 6 << 16; ++ ups_flags |= ups_flags_speed(6); + break; + case NWAY_100M_FULL: -+ ups_flags |= 7 << 16; ++ ups_flags |= ups_flags_speed(7); + break; + case NWAY_1000M_FULL: -+ ups_flags |= 8 << 16; ++ ups_flags |= ups_flags_speed(8); + break; + case NWAY_2500M_FULL: -+ ups_flags |= 9 << 16; ++ ups_flags |= ups_flags_speed(9); + break; + default: + break; @@ -2015,19 +3198,42 @@ index 2490498b..26cc7c1a 100644 + } + + ocp_write_dword(tp, MCU_TYPE_USB, USB_UPS_FLAGS, ups_flags); - } ++} ++ ++static void rtl_green_en(struct r8152 *tp, bool enable) + { + u16 data; - static void r8153b_green_en(struct r8152 *tp, bool enable) -@@ -2688,7 +3231,7 @@ static void r8153b_green_en(struct r8152 *tp, bool enable) - data |= GREEN_ETH_EN; - sram_write(tp, SRAM_GREEN_CFG, data); - -- r8153b_ups_flags_w1w0(tp, UPS_FLAGS_EN_GREEN, 0); ++ data = sram_read(tp, SRAM_GREEN_CFG); ++ if (enable) ++ data |= GREEN_ETH_EN; ++ else ++ data &= ~GREEN_ETH_EN; ++ sram_write(tp, SRAM_GREEN_CFG, data); ++ ++ + tp->ups_info.green = enable; ++} ++ ++static void r8153b_green_en(struct r8152 *tp, bool enable) ++{ + if (enable) { + sram_write(tp, 0x8045, 0); /* 10M abiq&ldvbias */ + sram_write(tp, 0x804d, 0x1222); /* 100M short abiq&ldvbias */ +@@ -2692,11 +3850,7 @@ static void r8153b_green_en(struct r8152 *tp, bool enable) + sram_write(tp, 0x805d, 0x2444); /* 1000M short abiq&ldvbias */ + } + +- data = sram_read(tp, SRAM_GREEN_CFG); +- data |= GREEN_ETH_EN; +- sram_write(tp, SRAM_GREEN_CFG, data); +- +- r8153b_ups_flags_w1w0(tp, UPS_FLAGS_EN_GREEN, 0); ++ rtl_green_en(tp, enable); } static u16 r8153_phy_status(struct r8152 *tp, u16 desired) -@@ -2718,6 +3261,8 @@ static void r8153b_ups_en(struct r8152 *tp, bool enable) +@@ -2726,6 +3880,8 @@ static void r8153b_ups_en(struct r8152 *tp, bool enable) u32 ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_POWER_CUT); if (enable) { @@ -2036,7 +3242,7 @@ index 2490498b..26cc7c1a 100644 ocp_data |= UPS_EN | USP_PREWAKE | PHASE2_EN; ocp_write_byte(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data); -@@ -2725,7 +3270,9 @@ static void r8153b_ups_en(struct r8152 *tp, bool enable) +@@ -2733,7 +3889,9 @@ static void r8153b_ups_en(struct r8152 *tp, bool enable) ocp_data |= BIT(0); ocp_write_byte(tp, MCU_TYPE_USB, 0xcfff, ocp_data); } else { @@ -2046,7 +3252,7 @@ index 2490498b..26cc7c1a 100644 ocp_data &= ~(UPS_EN | USP_PREWAKE); ocp_write_byte(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data); -@@ -2735,34 +3282,76 @@ static void r8153b_ups_en(struct r8152 *tp, bool enable) +@@ -2743,35 +3901,80 @@ static void r8153b_ups_en(struct r8152 *tp, bool enable) ocp_write_byte(tp, MCU_TYPE_USB, 0xcfff, ocp_data); ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); @@ -2076,8 +3282,8 @@ index 2490498b..26cc7c1a 100644 r8152_mdio_write(tp, MII_BMCR, data); data = r8153_phy_status(tp, PHY_STAT_LAN_ON); -- /* fall through */ - + /* fall through */ +- default: if (data != PHY_STAT_LAN_ON) netif_warn(tp, link, tp->netdev, @@ -2093,6 +3299,7 @@ index 2490498b..26cc7c1a 100644 } } +-static void r8153_power_cut_en(struct r8152 *tp, bool enable) +static void r8156_ups_en(struct r8152 *tp, bool enable) +{ + u32 ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_POWER_CUT); @@ -2118,16 +3325,20 @@ index 2490498b..26cc7c1a 100644 +// ocp_data &= ~(BIT(8) | BIT(9)); +// ocp_write_word(tp, MCU_TYPE_USB, 0xd32a, ocp_data); + -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); -+ if (ocp_data & PCUT_STATUS) ++ if (ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0) & PCUT_STATUS) { + tp->rtl_ops.hw_phy_cfg(tp); ++ ++ rtl8152_set_speed(tp, tp->autoneg, tp->speed, ++ tp->duplex, tp->advertising); ++ } + } +} + - static void r8153_power_cut_en(struct r8152 *tp, bool enable) ++static void r8153_power_cut_en(struct r8152 *tp, bool enable) { u32 ocp_data; -@@ -2795,20 +3384,24 @@ static void r8153b_power_cut_en(struct r8152 *tp, bool enable) + +@@ -2803,20 +4006,24 @@ static void r8153b_power_cut_en(struct r8152 *tp, bool enable) ocp_write_word(tp, MCU_TYPE_USB, USB_MISC_0, ocp_data); } @@ -2137,27 +3348,30 @@ index 2490498b..26cc7c1a 100644 u32 ocp_data; - ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, 0xd38a); -+ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, 0xd38c); ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_INDICATE_FALG); if (enable) - ocp_data |= BIT(0); +- ocp_data |= BIT(0); ++ ocp_data |= UPCOMING_RUNTIME_D3; else - ocp_data &= ~BIT(0); +- ocp_data &= ~BIT(0); - ocp_write_byte(tp, MCU_TYPE_PLA, 0xd38a, ocp_data); -+ ocp_write_byte(tp, MCU_TYPE_PLA, 0xd38c, ocp_data); ++ ocp_data &= ~UPCOMING_RUNTIME_D3; ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_INDICATE_FALG, ocp_data); - ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, 0xd38c); -+ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, 0xd38a); - ocp_data &= ~BIT(0); +- ocp_data &= ~BIT(0); - ocp_write_byte(tp, MCU_TYPE_PLA, 0xd38c, ocp_data); -+ ocp_write_byte(tp, MCU_TYPE_PLA, 0xd38a, ocp_data); ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_SUSPEND_FLAG); ++ ocp_data &= ~LINK_CHG_EVENT; ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_SUSPEND_FLAG, ocp_data); + -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, 0xd398); -+ ocp_data &= ~BIT(8); -+ ocp_write_word(tp, MCU_TYPE_PLA, 0xd398, ocp_data); ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS); ++ ocp_data &= ~LINK_CHANGE_FLAG; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, ocp_data); } static bool rtl_can_wakeup(struct r8152 *tp) -@@ -2850,11 +3443,15 @@ static void rtl_runtime_suspend_enable(struct r8152 *tp, bool enable) +@@ -2858,11 +4065,15 @@ static void rtl_runtime_suspend_enable(struct r8152 *tp, bool enable) static void rtl8153_runtime_enable(struct r8152 *tp, bool enable) { if (enable) { @@ -2173,7 +3387,7 @@ index 2490498b..26cc7c1a 100644 rtl_runtime_suspend_enable(tp, false); r8153_mac_clk_spd(tp, false); -@@ -2876,20 +3473,56 @@ static void rtl8153_runtime_enable(struct r8152 *tp, bool enable) +@@ -2884,18 +4095,56 @@ static void rtl8153_runtime_enable(struct r8152 *tp, bool enable) static void rtl8153b_runtime_enable(struct r8152 *tp, bool enable) { if (enable) { @@ -2189,7 +3403,8 @@ index 2490498b..26cc7c1a 100644 + r8153_queue_wake(tp, false); + rtl_runtime_suspend_enable(tp, false); +// r8153_u2p3en(tp, true); -+ r8153b_u1u2en(tp, true); ++ if (tp->udev->speed >= USB_SPEED_SUPER) ++ r8153b_u1u2en(tp, true); + } +} + @@ -2204,14 +3419,16 @@ index 2490498b..26cc7c1a 100644 +// tp->udev->speed == USB_SPEED_HIGH) +// r8156_ups_en(tp, true); + } else { -+ r8156_ups_en(tp, false); ++// r8156_ups_en(tp, false); + r8153_queue_wake(tp, false); rtl_runtime_suspend_enable(tp, false); r8153_u2p3en(tp, true); - r8153b_u1u2en(tp, true); - } - } - +- r8153b_u1u2en(tp, true); ++ if (tp->udev->speed >= USB_SPEED_SUPER) ++ r8153b_u1u2en(tp, true); ++ } ++} ++ +static int rtl_nway_restart(struct r8152 *tp) +{ + int r = -EINVAL; @@ -2224,56 +3441,61 @@ index 2490498b..26cc7c1a 100644 + bmcr |= BMCR_ANRESTART; + r8152_mdio_write(tp, MII_BMCR, bmcr); + r = 0; -+ } + } + + return r; -+} -+ + } + static void r8153_teredo_off(struct r8152 *tp) - { - u32 ocp_data; -@@ -2910,6 +3543,9 @@ static void r8153_teredo_off(struct r8152 *tp) +@@ -2918,6 +4167,11 @@ static void r8153_teredo_off(struct r8152 *tp) case RTL_VER_08: case RTL_VER_09: + case RTL_TEST_01: + case RTL_VER_10: + case RTL_VER_11: ++ case RTL_VER_12: ++ case RTL_VER_13: /* The bit 0 ~ 7 are relative with teredo settings. They are * W1C (write 1 to clear), so set all 1 to disable it. */ -@@ -2936,6 +3572,661 @@ static void rtl_reset_bmu(struct r8152 *tp) +@@ -2944,6 +4198,829 @@ static void rtl_reset_bmu(struct r8152 *tp) ocp_write_byte(tp, MCU_TYPE_USB, USB_BMU_RESET, ocp_data); } -+static void rtl_clear_bp(struct r8152 *tp) ++/* Clear the bp to stop the firmware before loading a new one */ ++static void rtl_clear_bp(struct r8152 *tp, u16 type) +{ -+ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_0, 0); -+ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_2, 0); -+ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_4, 0); -+ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_6, 0); -+ ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_0, 0); -+ ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_2, 0); -+ ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_4, 0); -+ ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_6, 0); -+ usleep_range(3000, 6000); -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_BA, 0); -+ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_BA, 0); -+} ++ switch (tp->version) { ++ case RTL_VER_01: ++ case RTL_VER_02: ++ case RTL_VER_07: ++ break; ++ case RTL_VER_03: ++ case RTL_VER_04: ++ case RTL_VER_05: ++ case RTL_VER_06: ++ ocp_write_byte(tp, type, PLA_BP_EN, 0); ++ break; ++ case RTL_VER_08: ++ case RTL_VER_09: ++ default: ++ if (type == MCU_TYPE_USB) { ++ ocp_write_byte(tp, MCU_TYPE_USB, USB_BP2_EN, 0); + -+static void r8153_clear_bp(struct r8152 *tp) -+{ -+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_BP_EN, 0); -+ ocp_write_byte(tp, MCU_TYPE_USB, USB_BP_EN, 0); -+ rtl_clear_bp(tp); -+} -+ -+static void r8153b_clear_bp(struct r8152 *tp, u16 type) -+{ -+ if (type == MCU_TYPE_PLA) -+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_BP_EN, 0); -+ else -+ ocp_write_byte(tp, MCU_TYPE_USB, USB_BP2_EN, 0); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_8, 0); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_9, 0); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_10, 0); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_11, 0); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_12, 0); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_13, 0); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_14, 0); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_15, 0); ++ } else { ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_BP_EN, 0); ++ } ++ break; ++ } + + ocp_write_word(tp, type, PLA_BP_0, 0); + ocp_write_word(tp, type, PLA_BP_1, 0); @@ -2284,20 +3506,81 @@ index 2490498b..26cc7c1a 100644 + ocp_write_word(tp, type, PLA_BP_6, 0); + ocp_write_word(tp, type, PLA_BP_7, 0); + -+ if (type == MCU_TYPE_USB) { -+ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_8, 0); -+ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_9, 0); -+ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_10, 0); -+ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_11, 0); -+ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_12, 0); -+ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_13, 0); -+ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_14, 0); -+ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_15, 0); -+ } ++ /* wait 3 ms to make sure the firmware is stopped */ + usleep_range(3000, 6000); + ocp_write_word(tp, type, PLA_BP_BA, 0); +} + ++static int r8153_patch_request(struct r8152 *tp, bool request) ++{ ++ u16 data, check; ++ int i; ++ ++ data = ocp_reg_read(tp, OCP_PHY_PATCH_CMD); ++ if (request) { ++ data |= PATCH_REQUEST; ++ check = 0; ++ } else { ++ data &= ~PATCH_REQUEST; ++ check = PATCH_READY; ++ } ++ ocp_reg_write(tp, OCP_PHY_PATCH_CMD, data); ++ ++ for (i = 0; i < 5000; i++) { ++ usleep_range(1000, 2000); ++ if ((ocp_reg_read(tp, OCP_PHY_PATCH_STAT) & PATCH_READY) ^ check) ++ break; ++ } ++ ++ if (request && !(ocp_reg_read(tp, OCP_PHY_PATCH_STAT) & PATCH_READY)) { ++ dev_err(&tp->intf->dev, "patch request fail\n"); ++ r8153_patch_request(tp, false); ++ return -ETIME; ++ } else { ++ return 0; ++ } ++} ++ ++static void rtl_patch_key_set(struct r8152 *tp, u16 key_addr, u16 patch_key) ++{ ++ sram_write(tp, key_addr, patch_key); ++ sram_write(tp, SRAM_PHY_LOCK, PHY_PATCH_LOCK); ++} ++ ++static void rtl_patch_key_clear(struct r8152 *tp, u16 key_addr) ++{ ++ u16 data; ++ ++ sram_write(tp, 0x0000, 0x0000); ++ ++ data = ocp_reg_read(tp, OCP_PHY_LOCK); ++ data &= ~PATCH_LOCK; ++ ocp_reg_write(tp, OCP_PHY_LOCK, data); ++ ++ sram_write(tp, key_addr, 0x0000); ++} ++ ++static int r8153_pre_ram_code(struct r8152 *tp, u16 key_addr, u16 patch_key) ++{ ++ if (r8153_patch_request(tp, true)) ++ return -ETIME; ++ ++ rtl_patch_key_set(tp, key_addr, patch_key); ++ ++ return 0; ++} ++ ++static int r8153_post_ram_code(struct r8152 *tp, u16 key_addr) ++{ ++ rtl_patch_key_clear(tp, key_addr); ++ ++ r8153_patch_request(tp, false); ++ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_OCP_GPHY_BASE, tp->ocp_base); ++ ++ return 0; ++} ++ +static void patch4(struct r8152 *tp) +{ + u8 data; @@ -2696,7 +3979,7 @@ index 2490498b..26cc7c1a 100644 + 0xbcf1, 0x3001 }; + + patch4(tp); -+ rtl_clear_bp(tp); ++ rtl_clear_bp(tp, MCU_TYPE_PLA); + + generic_ocp_write(tp, 0xf800, 0x3f, sizeof(pla_patch_a), + pla_patch_a, MCU_TYPE_PLA); @@ -2886,8 +4169,82 @@ index 2490498b..26cc7c1a 100644 + 0x00, 0x00, 0x02, 0xc6, + 0x00, 0xbe, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }; ++ static u8 usb_patch_a2[] = { ++ 0x10, 0xe0, 0x2d, 0xe0, ++ 0x0e, 0xe0, 0x0d, 0xe0, ++ 0x0c, 0xe0, 0x0b, 0xe0, ++ 0x0a, 0xe0, 0x09, 0xe0, ++ 0x08, 0xe0, 0x07, 0xe0, ++ 0x06, 0xe0, 0x05, 0xe0, ++ 0x04, 0xe0, 0x03, 0xe0, ++ 0x02, 0xe0, 0x01, 0xe0, ++ 0x1c, 0xc2, 0x40, 0x71, ++ 0x9f, 0x48, 0x40, 0x99, ++ 0x1f, 0x48, 0x40, 0x99, ++ 0x15, 0xc2, 0x40, 0x61, ++ 0x90, 0x49, 0x0a, 0xf0, ++ 0x42, 0x70, 0x80, 0x49, ++ 0x07, 0xf0, 0x80, 0x48, ++ 0x42, 0x98, 0x0b, 0xc2, ++ 0x40, 0x60, 0x03, 0x48, ++ 0x40, 0x88, 0x0a, 0xc2, ++ 0x08, 0x18, 0x55, 0x60, ++ 0x55, 0x88, 0x02, 0xc0, ++ 0x00, 0xb8, 0xc2, 0x09, ++ 0x28, 0xd4, 0xd4, 0xc4, ++ 0x06, 0xd4, 0x00, 0xb0, ++ 0x61, 0xc7, 0x5a, 0xc6, ++ 0xe4, 0x9e, 0x0f, 0x1e, ++ 0xe6, 0x8e, 0xe6, 0x76, ++ 0xef, 0x49, 0xfe, 0xf1, ++ 0xe0, 0x73, 0xe2, 0x74, ++ 0xb8, 0x26, 0xb8, 0x21, ++ 0xb8, 0x25, 0x48, 0x23, ++ 0x68, 0x27, 0x04, 0xb4, ++ 0x05, 0xb4, 0x06, 0xb4, ++ 0x4a, 0xc6, 0xe3, 0x23, ++ 0xfe, 0x39, 0x00, 0x1c, ++ 0x00, 0x1d, 0x00, 0x13, ++ 0x0a, 0xf0, 0xb0, 0x49, ++ 0x04, 0xf1, 0x01, 0x05, ++ 0xb1, 0x25, 0xfa, 0xe7, ++ 0xb8, 0x33, 0x35, 0x43, ++ 0x30, 0x31, 0xf6, 0xe7, ++ 0x06, 0xb0, 0x05, 0xb0, ++ 0xae, 0x41, 0x25, 0x31, ++ 0x37, 0xc5, 0x6c, 0x41, ++ 0x04, 0xb0, 0x48, 0x26, ++ 0x05, 0xb4, 0x36, 0xc7, ++ 0x2f, 0xc6, 0x04, 0x06, ++ 0xe4, 0x9e, 0x0f, 0x1e, ++ 0xe6, 0x8e, 0xe6, 0x76, ++ 0xef, 0x49, 0xfe, 0xf1, ++ 0xe0, 0x76, 0xe8, 0x25, ++ 0xe8, 0x23, 0xf8, 0x27, ++ 0x24, 0xc5, 0x6c, 0x41, ++ 0x33, 0x22, 0x23, 0x39, ++ 0x7c, 0x41, 0xfd, 0x31, ++ 0x1f, 0xc6, 0x7e, 0x41, ++ 0x20, 0xc6, 0xc4, 0x9f, ++ 0xf2, 0x21, 0xdf, 0x30, ++ 0xdf, 0x30, 0x05, 0xb0, ++ 0xc2, 0x9d, 0x53, 0x22, ++ 0x25, 0x31, 0xa3, 0x31, ++ 0x12, 0xc7, 0xb7, 0x31, ++ 0x12, 0xc7, 0x77, 0x41, ++ 0x12, 0xc7, 0xe6, 0x9e, ++ 0x0f, 0xc3, 0xde, 0x30, ++ 0x60, 0x64, 0xe8, 0x8c, ++ 0x06, 0xc7, 0x04, 0x1e, ++ 0xe0, 0x8e, 0x02, 0xc4, ++ 0x00, 0xbc, 0xb6, 0x02, ++ 0x34, 0xe4, 0x00, 0xc0, ++ 0x25, 0x00, 0xff, 0x00, ++ 0x7f, 0x00, 0x00, 0xf8, ++ 0xf0, 0xc4, 0x08, 0xdc }; ++ u32 ocp_data; + -+ rtl_clear_bp(tp); ++ rtl_clear_bp(tp, MCU_TYPE_PLA); + + generic_ocp_write(tp, 0xf800, 0xff, sizeof(pla_patch_a2), + pla_patch_a2, MCU_TYPE_PLA); @@ -2898,13 +4255,41 @@ index 2490498b..26cc7c1a 100644 + ocp_write_word(tp, MCU_TYPE_PLA, 0xfc2a, 0x13ad); + ocp_write_word(tp, MCU_TYPE_PLA, 0xfc2c, 0x184d); + ocp_write_word(tp, MCU_TYPE_PLA, 0xfc2e, 0x01e1); ++ ++ rtl_clear_bp(tp, MCU_TYPE_USB); ++ ++ generic_ocp_write(tp, 0xf800, 0xff, sizeof(usb_patch_a2), ++ usb_patch_a2, MCU_TYPE_USB); ++ ++ ocp_write_word(tp, MCU_TYPE_USB, 0xfc26, 0xA000); ++ ++ ocp_write_word(tp, MCU_TYPE_USB, 0xfc28, 0x0c87); ++ ocp_write_word(tp, MCU_TYPE_USB, 0xfc2a, 0x024f); ++ ocp_write_word(tp, MCU_TYPE_USB, 0xfc2c, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_USB, 0xfc2e, 0x0000); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xd428); ++ ocp_data |= BIT(15); ++ ocp_write_word(tp, MCU_TYPE_USB, 0xd428, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xc4d4); ++ ocp_data |= BIT(0); ++ ocp_write_word(tp, MCU_TYPE_USB, 0xc4d4, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xc4d6); ++ ocp_data &= ~BIT(0); ++ ocp_write_word(tp, MCU_TYPE_USB, 0xc4d6, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xd428); ++ ocp_data &= ~BIT(15); ++ ocp_write_word(tp, MCU_TYPE_USB, 0xd428, ocp_data); + } +} + static void r8152_aldps_en(struct r8152 *tp, bool enable) { if (enable) { -@@ -2955,6 +4246,7 @@ static inline void r8152_mmd_indirect(struct r8152 *tp, u16 dev, u16 reg) +@@ -2963,6 +5040,7 @@ static inline void r8152_mmd_indirect(struct r8152 *tp, u16 dev, u16 reg) ocp_reg_write(tp, OCP_EEE_AR, FUN_DATA | dev); } @@ -2912,7 +4297,7 @@ index 2490498b..26cc7c1a 100644 static u16 r8152_mmd_read(struct r8152 *tp, u16 dev, u16 reg) { u16 data; -@@ -2965,6 +4257,7 @@ static u16 r8152_mmd_read(struct r8152 *tp, u16 dev, u16 reg) +@@ -2973,6 +5051,7 @@ static u16 r8152_mmd_read(struct r8152 *tp, u16 dev, u16 reg) return data; } @@ -2920,16 +4305,101 @@ index 2490498b..26cc7c1a 100644 static void r8152_mmd_write(struct r8152 *tp, u16 dev, u16 reg, u16 data) { -@@ -3007,7 +4300,7 @@ static void r8152_eee_en(struct r8152 *tp, bool enable) - static void r8152b_enable_eee(struct r8152 *tp) +@@ -3012,10 +5091,90 @@ static void r8152_eee_en(struct r8152 *tp, bool enable) + ocp_reg_write(tp, OCP_EEE_CONFIG3, config3); + } + +-static void r8152b_enable_eee(struct r8152 *tp) ++static void r8153_eee_en(struct r8152 *tp, bool enable) ++{ ++ u32 ocp_data; ++ u16 config; ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); ++ config = ocp_reg_read(tp, OCP_EEE_CFG); ++ ++ if (enable) { ++ ocp_data |= EEE_RX_EN | EEE_TX_EN; ++ config |= EEE10_EN; ++ } else { ++ ocp_data &= ~(EEE_RX_EN | EEE_TX_EN); ++ config &= ~EEE10_EN; ++ } ++ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data); ++ ++ if (tp->version != RTL_VER_13) ++ ocp_reg_write(tp, OCP_EEE_CFG, config); ++ ++ tp->ups_info.eee = enable; ++} ++ ++static void r8156_eee_en(struct r8152 *tp, bool enable) ++{ ++ u16 config; ++ ++ r8153_eee_en(tp, enable); ++ ++ config = ocp_reg_read(tp, 0xa6d4); ++ ++ if (enable) ++ config |= BIT(0); ++ else ++ config &= ~BIT(0); ++ ++ ocp_reg_write(tp, 0xa6d4, config); ++} ++ ++static void rtl_eee_enable(struct r8152 *tp, bool enable) { - r8152_eee_en(tp, true); +- r8152_eee_en(tp, true); - r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, MDIO_EEE_100TX); -+ r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, tp->eee_adv); ++ switch (tp->version) { ++ case RTL_VER_01: ++ case RTL_VER_02: ++ case RTL_VER_07: ++ if (enable) { ++ r8152_eee_en(tp, true); ++ r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, ++ tp->eee_adv); ++ } else { ++ r8152_eee_en(tp, false); ++ r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0); ++ } ++ break; ++ case RTL_VER_03: ++ case RTL_VER_04: ++ case RTL_VER_05: ++ case RTL_VER_06: ++ case RTL_VER_08: ++ case RTL_VER_09: ++ if (enable) { ++ r8153_eee_en(tp, true); ++ ocp_reg_write(tp, OCP_EEE_ADV, tp->eee_adv); ++ } else { ++ r8153_eee_en(tp, false); ++ ocp_reg_write(tp, OCP_EEE_ADV, 0); ++ } ++ break; ++ case RTL_VER_10: ++ case RTL_VER_11: ++ case RTL_VER_12: ++ case RTL_VER_13: ++ if (enable) { ++ r8156_eee_en(tp, true); ++ ocp_reg_write(tp, OCP_EEE_ADV, tp->eee_adv); ++ } else { ++ r8156_eee_en(tp, false); ++ ocp_reg_write(tp, OCP_EEE_ADV, 0); ++ } ++ break; ++ default: ++ break; ++ } } static void r8152b_enable_fc(struct r8152 *tp) -@@ -3017,6 +4310,8 @@ static void r8152b_enable_fc(struct r8152 *tp) +@@ -3025,6 +5184,8 @@ static void r8152b_enable_fc(struct r8152 *tp) anar = r8152_mdio_read(tp, MII_ADVERTISE); anar |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; r8152_mdio_write(tp, MII_ADVERTISE, anar); @@ -2938,119 +4408,146 @@ index 2490498b..26cc7c1a 100644 } static void rtl8152_disable(struct r8152 *tp) -@@ -3028,6 +4323,8 @@ static void rtl8152_disable(struct r8152 *tp) +@@ -3036,18 +5197,32 @@ static void rtl8152_disable(struct r8152 *tp) static void r8152b_hw_phy_cfg(struct r8152 *tp) { +- r8152b_enable_eee(tp); + r8152b_firmware(tp); + - r8152b_enable_eee(tp); ++ rtl_eee_enable(tp, tp->eee_en); r8152_aldps_en(tp, true); r8152b_enable_fc(tp); -@@ -3166,19 +4463,22 @@ static void r8152b_enter_oob(struct r8152 *tp) - static int r8153_patch_request(struct r8152 *tp, bool request) + set_bit(PHY_RESET, &tp->flags); + } + +-static void r8152b_exit_oob(struct r8152 *tp) ++static void wait_oob_link_list_ready(struct r8152 *tp) { -- u16 data; -+ u16 data, check; + u32 ocp_data; int i; - data = ocp_reg_read(tp, OCP_PHY_PATCH_CMD); -- if (request) -+ if (request) { - data |= PATCH_REQUEST; -- else -+ check = 0; -+ } else { - data &= ~PATCH_REQUEST; -+ check = PATCH_READY; ++ for (i = 0; i < 1000; i++) { ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); ++ if (ocp_data & LINK_LIST_READY) ++ break; ++ usleep_range(1000, 2000); + } - ocp_reg_write(tp, OCP_PHY_PATCH_CMD, data); ++} ++ ++static void r8152b_exit_oob(struct r8152 *tp) ++{ ++ u32 ocp_data; ++ + ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); + ocp_data &= ~RCR_ACPT_ALL; + ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); +@@ -3065,23 +5240,13 @@ static void r8152b_exit_oob(struct r8152 *tp) + ocp_data &= ~MCU_BORW_EN; + ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); -- for (i = 0; request && i < 5000; i++) { -+ for (i = 0; i < 5000; i++) { - usleep_range(1000, 2000); -- if (ocp_reg_read(tp, OCP_PHY_PATCH_STAT) & PATCH_READY) -+ if ((ocp_reg_read(tp, OCP_PHY_PATCH_STAT) & PATCH_READY) ^ check) - break; - } - -@@ -3191,71 +4491,2836 @@ static int r8153_patch_request(struct r8152 *tp, bool request) - } - } - --static void r8153_aldps_en(struct r8152 *tp, bool enable) -+static int r8153_pre_ram_code(struct r8152 *tp, u16 key_addr, u16 patch_key) - { -- u16 data; -+ if (r8153_patch_request(tp, true)) -+ return -ETIME; - -- data = ocp_reg_read(tp, OCP_POWER_CFG); -- if (enable) { -- data |= EN_ALDPS; -- ocp_reg_write(tp, OCP_POWER_CFG, data); -- } else { -- int i; -+ sram_write(tp, key_addr, patch_key); -+ sram_write(tp, 0xb82e, 0x0001); - -- data &= ~EN_ALDPS; -- ocp_reg_write(tp, OCP_POWER_CFG, data); -- for (i = 0; i < 20; i++) { -- usleep_range(1000, 2000); -- if (ocp_read_word(tp, MCU_TYPE_PLA, 0xe000) & 0x0100) -- break; -- } +- for (i = 0; i < 1000; i++) { +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); +- if (ocp_data & LINK_LIST_READY) +- break; +- usleep_range(1000, 2000); - } -+ return 0; - } ++ wait_oob_link_list_ready(tp); --static void r8153b_aldps_en(struct r8152 *tp, bool enable) -+static int r8153_post_ram_code(struct r8152 *tp, u16 key_addr) + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); + ocp_data |= RE_INIT_LL; + ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); + +- for (i = 0; i < 1000; i++) { +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); +- if (ocp_data & LINK_LIST_READY) +- break; +- usleep_range(1000, 2000); +- } ++ wait_oob_link_list_ready(tp); + + rtl8152_nic_reset(tp); + +@@ -3104,7 +5269,7 @@ static void r8152b_exit_oob(struct r8152 *tp) + } + + /* TX share fifo free credit full threshold */ +- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_TXFIFO_CTRL, TXFIFO_THR_NORMAL); ++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_TXFIFO_CTRL, TXFIFO_THR_NORMAL2); + + ocp_write_byte(tp, MCU_TYPE_USB, USB_TX_AGG, TX_AGG_MAX_THRESHOLD); + ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, RX_THR_HIGH); +@@ -3123,7 +5288,6 @@ static void r8152b_exit_oob(struct r8152 *tp) + static void r8152b_enter_oob(struct r8152 *tp) { -- r8153_aldps_en(tp, enable); -+ u16 data; + u32 ocp_data; +- int i; -- if (enable) -- r8153b_ups_flags_w1w0(tp, UPS_FLAGS_EN_ALDPS, 0); -- else -- r8153b_ups_flags_w1w0(tp, 0, UPS_FLAGS_EN_ALDPS); -+ sram_write(tp, 0x0000, 0x0000); -+ -+ data = ocp_reg_read(tp, 0xb82e); -+ data &= ~0x0001; -+ ocp_reg_write(tp, 0xb82e, data); -+ -+ sram_write(tp, key_addr, 0x0000); -+ -+ r8153_patch_request(tp, false); -+ -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_OCP_GPHY_BASE, tp->ocp_base); -+ -+ return 0; + ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); + ocp_data &= ~NOW_IS_OOB; +@@ -3135,31 +5299,21 @@ static void r8152b_enter_oob(struct r8152 *tp) + + rtl_disable(tp); + +- for (i = 0; i < 1000; i++) { +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); +- if (ocp_data & LINK_LIST_READY) +- break; +- usleep_range(1000, 2000); +- } ++ wait_oob_link_list_ready(tp); + + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); + ocp_data |= RE_INIT_LL; + ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); + +- for (i = 0; i < 1000; i++) { +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); +- if (ocp_data & LINK_LIST_READY) +- break; +- usleep_range(1000, 2000); +- } ++ wait_oob_link_list_ready(tp); + + ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8152_RMS); + + rtl_rx_vlan_en(tp, true); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PAL_BDC_CR); ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_BDC_CR); + ocp_data |= ALDPS_PROXY_MODE; +- ocp_write_word(tp, MCU_TYPE_PLA, PAL_BDC_CR, ocp_data); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_BDC_CR, ocp_data); + + ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); + ocp_data |= NOW_IS_OOB | DIS_MCU_CLROOB; +@@ -3172,98 +5326,2803 @@ static void r8152b_enter_oob(struct r8152 *tp) + ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); } --static void r8153_eee_en(struct r8152 *tp, bool enable) +-static int r8153_patch_request(struct r8152 *tp, bool request) +static int r8156_lock_mian(struct r8152 *tp, bool lock) { -- u32 ocp_data; -- u16 config; -+ u16 data; -+ int i; + u16 data; + int i; -- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); -- config = ocp_reg_read(tp, OCP_EEE_CFG); +- data = ocp_reg_read(tp, OCP_PHY_PATCH_CMD); +- if (request) +- data |= PATCH_REQUEST; + data = ocp_reg_read(tp, 0xa46a); + if (lock) + data |= BIT(1); -+ else + else +- data &= ~PATCH_REQUEST; +- ocp_reg_write(tp, OCP_PHY_PATCH_CMD, data); + data &= ~BIT(1); + ocp_reg_write(tp, 0xa46a, data); -- if (enable) { -- ocp_data |= EEE_RX_EN | EEE_TX_EN; -- config |= EEE10_EN; +- for (i = 0; request && i < 5000; i++) { +- usleep_range(1000, 2000); +- if (ocp_reg_read(tp, OCP_PHY_PATCH_STAT) & PATCH_READY) +- break; + if (lock) { + for (i = 0; i < 100; i++) { + usleep_range(1000, 2000); @@ -3058,9 +4555,7 @@ index 2490498b..26cc7c1a 100644 + if (data == 1) + break; + } - } else { -- ocp_data &= ~(EEE_RX_EN | EEE_TX_EN); -- config &= ~EEE10_EN; ++ } else { + for (i = 0; i < 100; i++) { + usleep_range(1000, 2000); + data = ocp_reg_read(tp, 0xa730) & 0xff; @@ -3069,31 +4564,51 @@ index 2490498b..26cc7c1a 100644 + } } -- ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data); -- ocp_reg_write(tp, OCP_EEE_CFG, config); +- if (request && !(ocp_reg_read(tp, OCP_PHY_PATCH_STAT) & PATCH_READY)) { +- netif_err(tp, drv, tp->netdev, "patch request fail\n"); +- r8153_patch_request(tp, false); + if (i == 100) -+ return -ETIME; + return -ETIME; +- } else { + else -+ return 0; + return 0; +- } } --static void r8153b_eee_en(struct r8152 *tp, bool enable) +-static void r8153_aldps_en(struct r8152 *tp, bool enable) +static void r8153_wdt1_end(struct r8152 *tp) { +- u16 data; + int i; -+ + +- data = ocp_reg_read(tp, OCP_POWER_CFG); +- if (enable) { +- data |= EN_ALDPS; +- ocp_reg_write(tp, OCP_POWER_CFG, data); +- } else { +- int i; ++ /* Wait till the WTD timer is ready. It would take at most 104 ms. */ + for (i = 0; i < 104; i++) { -+ if (!(ocp_read_byte(tp, MCU_TYPE_USB, 0xe404) & 1)) ++ u32 ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_WDT1_CTRL); + +- data &= ~EN_ALDPS; +- ocp_reg_write(tp, OCP_POWER_CFG, data); +- for (i = 0; i < 20; i++) { +- usleep_range(1000, 2000); +- if (ocp_read_word(tp, MCU_TYPE_PLA, 0xe000) & 0x0100) +- break; +- } ++ if (!(ocp_data & WTD1_EN)) + break; + usleep_range(1000, 2000); -+ } -+} -+ + } + } + +-static void r8153b_aldps_en(struct r8152 *tp, bool enable) +static void r8153_firmware(struct r8152 *tp) -+{ + { +- r8153_aldps_en(tp, enable); + if (tp->version == RTL_VER_03) { -+ r8153_clear_bp(tp); -+ + r8153_pre_ram_code(tp, 0x8146, 0x7000); + sram_write(tp, 0xb820, 0x0290); + sram_write(tp, 0xa012, 0x0000); @@ -3547,9 +5062,9 @@ index 2490498b..26cc7c1a 100644 + r8153_post_ram_code(tp, 0x8146); + + r8153_wdt1_end(tp); -+ r8153_clear_bp(tp); + -+ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_EN, 0x0000); ++ rtl_clear_bp(tp, MCU_TYPE_USB); ++ + generic_ocp_write(tp, 0xf800, 0xff, sizeof(usb_patch_b), + usb_patch_b, MCU_TYPE_USB); + ocp_write_word(tp, MCU_TYPE_USB, 0xfc26, 0xa000); @@ -3563,12 +5078,24 @@ index 2490498b..26cc7c1a 100644 + ocp_write_word(tp, MCU_TYPE_USB, 0xfc36, 0x0098); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_EN, 0x00FF); + -+ if (!(ocp_read_word(tp, MCU_TYPE_PLA, 0xd38e) & BIT(0))) { -+ ocp_write_word(tp, MCU_TYPE_PLA, 0xd38c, 0x0082); -+ ocp_write_word(tp, MCU_TYPE_PLA, 0xd38e, 0x0082); -+ } ++ rtl_clear_bp(tp, MCU_TYPE_PLA); + -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, 0x0000); ++ /* Enable backup/restore of MACDBG. This is required after ++ * clearing PLA break points and before applying the PLA ++ * firmware. ++ */ ++ if (!(ocp_read_word(tp, MCU_TYPE_PLA, PLA_MACDBG_POST) & ++ DEBUG_OE)) { ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MACDBG_PRE, ++ DEBUG_LTSSM); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MACDBG_POST, ++ DEBUG_LTSSM); ++ } + +- if (enable) +- r8153b_ups_flags_w1w0(tp, UPS_FLAGS_EN_ALDPS, 0); +- else +- r8153b_ups_flags_w1w0(tp, 0, UPS_FLAGS_EN_ALDPS); + generic_ocp_write(tp, 0xf800, 0xff, sizeof(pla_patch_b), + pla_patch_b, MCU_TYPE_PLA); + ocp_write_word(tp, MCU_TYPE_PLA, 0xfc26, 0x8000); @@ -3582,14 +5109,15 @@ index 2490498b..26cc7c1a 100644 + ocp_write_word(tp, MCU_TYPE_PLA, 0xfc36, 0x0000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, 0x007f); + -+ ocp_write_word(tp, MCU_TYPE_PLA, 0xd388, 0x08ca); ++ /* reset UPHY timer to 36 ms */ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_UPHY_TIMER, 36000 / 16); + } else if (tp->version == RTL_VER_05) { + u32 ocp_data; + static u8 usb_patch_c[] = { + 0x08, 0xe0, 0x0a, 0xe0, + 0x14, 0xe0, 0x58, 0xe0, + 0x64, 0xe0, 0x79, 0xe0, -+ 0xa8, 0xe0, 0xb3, 0xe0, ++ 0xab, 0xe0, 0xb6, 0xe0, + 0x02, 0xc5, 0x00, 0xbd, + 0x38, 0x3b, 0xdb, 0x49, + 0x04, 0xf1, 0x06, 0xc3, @@ -3649,41 +5177,43 @@ index 2490498b..26cc7c1a 100644 + 0x02, 0xc1, 0x00, 0xb9, + 0x9c, 0x15, 0x00, 0xd8, + 0xef, 0xcf, 0x20, 0xd4, -+ 0x2b, 0xc5, 0xa0, 0x77, -+ 0x00, 0x1c, 0xa0, 0x9c, -+ 0x28, 0xc5, 0xa0, 0x64, -+ 0xc0, 0x48, 0xc1, 0x48, -+ 0xc2, 0x48, 0xa0, 0x8c, -+ 0xb1, 0x64, 0xc0, 0x48, -+ 0xb1, 0x8c, 0x20, 0xc5, -+ 0xa0, 0x64, 0x40, 0x48, -+ 0x41, 0x48, 0xc2, 0x48, -+ 0xa0, 0x8c, 0x19, 0xc5, -+ 0xa4, 0x64, 0x44, 0x48, -+ 0xa4, 0x8c, 0xb1, 0x64, -+ 0x40, 0x48, 0xb1, 0x8c, -+ 0x14, 0xc4, 0x80, 0x73, -+ 0x13, 0xc4, 0x82, 0x9b, -+ 0x11, 0x1b, 0x80, 0x9b, -+ 0x0c, 0xc5, 0xa0, 0x64, ++ 0x30, 0x18, 0xe7, 0xc1, ++ 0xcb, 0xef, 0x2b, 0xc5, ++ 0xa0, 0x77, 0x00, 0x1c, ++ 0xa0, 0x9c, 0x28, 0xc5, ++ 0xa0, 0x64, 0xc0, 0x48, ++ 0xc1, 0x48, 0xc2, 0x48, ++ 0xa0, 0x8c, 0xb1, 0x64, ++ 0xc0, 0x48, 0xb1, 0x8c, ++ 0x20, 0xc5, 0xa0, 0x64, + 0x40, 0x48, 0x41, 0x48, -+ 0x42, 0x48, 0xa0, 0x8c, -+ 0x05, 0xc5, 0xa0, 0x9f, -+ 0x02, 0xc5, 0x00, 0xbd, -+ 0x6c, 0x3a, 0x1e, 0xfc, -+ 0x10, 0xd8, 0x86, 0xd4, -+ 0xf8, 0xcb, 0x20, 0xe4, -+ 0x0a, 0xc0, 0x16, 0x61, -+ 0x91, 0x48, 0x16, 0x89, -+ 0x07, 0xc0, 0x11, 0x19, -+ 0x0c, 0x89, 0x02, 0xc1, -+ 0x00, 0xb9, 0x02, 0x06, -+ 0x00, 0xd4, 0x40, 0xb4, -+ 0xfe, 0xc0, 0x16, 0x61, -+ 0x91, 0x48, 0x16, 0x89, -+ 0xfb, 0xc0, 0x11, 0x19, -+ 0x0c, 0x89, 0x02, 0xc1, -+ 0x00, 0xb9, 0xd2, 0x05 }; ++ 0xc2, 0x48, 0xa0, 0x8c, ++ 0x19, 0xc5, 0xa4, 0x64, ++ 0x44, 0x48, 0xa4, 0x8c, ++ 0xb1, 0x64, 0x40, 0x48, ++ 0xb1, 0x8c, 0x14, 0xc4, ++ 0x80, 0x73, 0x13, 0xc4, ++ 0x82, 0x9b, 0x11, 0x1b, ++ 0x80, 0x9b, 0x0c, 0xc5, ++ 0xa0, 0x64, 0x40, 0x48, ++ 0x41, 0x48, 0x42, 0x48, ++ 0xa0, 0x8c, 0x05, 0xc5, ++ 0xa0, 0x9f, 0x02, 0xc5, ++ 0x00, 0xbd, 0x6c, 0x3a, ++ 0x1e, 0xfc, 0x10, 0xd8, ++ 0x86, 0xd4, 0xf8, 0xcb, ++ 0x20, 0xe4, 0x0a, 0xc0, ++ 0x16, 0x61, 0x91, 0x48, ++ 0x16, 0x89, 0x07, 0xc0, ++ 0x11, 0x19, 0x0c, 0x89, ++ 0x02, 0xc1, 0x00, 0xb9, ++ 0x02, 0x06, 0x00, 0xd4, ++ 0x40, 0xb4, 0xfe, 0xc0, ++ 0x16, 0x61, 0x91, 0x48, ++ 0x16, 0x89, 0xfb, 0xc0, ++ 0x11, 0x19, 0x0c, 0x89, ++ 0x02, 0xc1, 0x00, 0xb9, ++ 0xd2, 0x05, 0x00, 0x00 }; + static u8 pla_patch_c[] = { + 0x5d, 0xe0, 0x07, 0xe0, + 0x0f, 0xe0, 0x5a, 0xe0, @@ -3850,10 +5380,6 @@ index 2490498b..26cc7c1a 100644 + 0x00, 0xd8, 0x02, 0xc6, + 0x00, 0xbe, 0xe0, 0x08 }; + -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xcfca); -+ ocp_data &= ~0x4000; -+ ocp_write_word(tp, MCU_TYPE_USB, 0xcfca, ocp_data); -+ + r8153_pre_ram_code(tp, 0x8146, 0x7001); + sram_write(tp, 0xb820, 0x0290); + sram_write(tp, 0xa012, 0x0000); @@ -3881,9 +5407,13 @@ index 2490498b..26cc7c1a 100644 + r8153_post_ram_code(tp, 0x8146); + + r8153_wdt1_end(tp); -+ r8153_clear_bp(tp); + -+ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_EN, 0x0000); ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN0); ++ ocp_data &= ~FW_FIX_SUSPEND; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN0, ocp_data); ++ ++ rtl_clear_bp(tp, MCU_TYPE_USB); ++ + generic_ocp_write(tp, 0xf800, 0xff, sizeof(usb_patch_c), + usb_patch_c, MCU_TYPE_USB); + ocp_write_word(tp, MCU_TYPE_USB, 0xfc26, 0xa000); @@ -3891,7 +5421,7 @@ index 2490498b..26cc7c1a 100644 + ocp_write_word(tp, MCU_TYPE_USB, 0xfc2a, 0x027c); + ocp_write_word(tp, MCU_TYPE_USB, 0xfc2c, 0x15de); + ocp_write_word(tp, MCU_TYPE_USB, 0xfc2e, 0x10ce); -+ if (ocp_read_byte(tp, MCU_TYPE_USB, 0xcfef) & 1) ++ if (ocp_read_byte(tp, MCU_TYPE_USB, USB_CSTMR) & FORCE_SUPER) + ocp_write_word(tp, MCU_TYPE_USB, 0xfc30, 0x1578); + else + ocp_write_word(tp, MCU_TYPE_USB, 0xfc30, 0x1adc); @@ -3900,7 +5430,8 @@ index 2490498b..26cc7c1a 100644 + ocp_write_word(tp, MCU_TYPE_USB, 0xfc36, 0x05c8); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_EN, 0x00ff); + -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, 0x0000); ++ rtl_clear_bp(tp, MCU_TYPE_PLA); ++ + generic_ocp_write(tp, 0xf800, 0xff, sizeof(pla_patch_c), + pla_patch_c, MCU_TYPE_PLA); + ocp_write_word(tp, MCU_TYPE_PLA, 0xfc26, 0x8000); @@ -3914,12 +5445,16 @@ index 2490498b..26cc7c1a 100644 + ocp_write_word(tp, MCU_TYPE_PLA, 0xfc36, 0x0894); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, 0x00e6); + -+ ocp_write_word(tp, MCU_TYPE_PLA, 0xd388, 0x08ca); -+ ocp_write_word(tp, MCU_TYPE_PLA, 0xd398, 0x0084); ++ /* reset UPHY timer to 36 ms */ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_UPHY_TIMER, 36000 / 16); + -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xcfca); -+ ocp_data |= 0x4000; -+ ocp_write_word(tp, MCU_TYPE_USB, 0xcfca, ocp_data); ++ /* enable U3P3 check, set the counter to 4 */ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, ++ U3P3_CHECK_EN | 4); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN0); ++ ocp_data |= FW_FIX_SUSPEND; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN0, ocp_data); + + ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_USB2PHY); + ocp_data |= USB2PHY_L1 | USB2PHY_SUSPEND; @@ -3929,12 +5464,12 @@ index 2490498b..26cc7c1a 100644 + static u8 usb_patch_d[] = { + 0x08, 0xe0, 0x0e, 0xe0, + 0x11, 0xe0, 0x24, 0xe0, -+ 0x30, 0xe0, 0x38, 0xe0, ++ 0x2b, 0xe0, 0x33, 0xe0, + 0x3a, 0xe0, 0x3c, 0xe0, + 0x1e, 0xc3, 0x70, 0x61, + 0x12, 0x48, 0x70, 0x89, + 0x02, 0xc3, 0x00, 0xbb, -+ 0x02, 0x17, 0x31, 0x19, ++ 0x02, 0x17, 0x32, 0x19, + 0x02, 0xc3, 0x00, 0xbb, + 0x44, 0x14, 0x30, 0x18, + 0x11, 0xc1, 0x05, 0xe8, @@ -3946,22 +5481,22 @@ index 2490498b..26cc7c1a 100644 + 0x8e, 0x49, 0xfe, 0xf1, + 0x02, 0xb0, 0x80, 0xff, + 0xc0, 0xd4, 0xe4, 0x40, -+ 0x20, 0xd4, 0x0c, 0xc0, -+ 0x00, 0x63, 0xb5, 0x49, -+ 0x0c, 0xc0, 0x30, 0x18, -+ 0x06, 0xc1, 0xed, 0xef, -+ 0xf8, 0xc7, 0x02, 0xc0, ++ 0x20, 0xd4, 0x30, 0x18, ++ 0x06, 0xc1, 0xf1, 0xef, ++ 0xfc, 0xc7, 0x02, 0xc0, + 0x00, 0xb8, 0x38, 0x12, -+ 0xe4, 0x4b, 0x00, 0xd8, -+ 0x0c, 0x61, 0x95, 0x48, -+ 0x96, 0x48, 0x92, 0x48, -+ 0x93, 0x48, 0x0c, 0x89, -+ 0x02, 0xc0, 0x00, 0xb8, -+ 0x0e, 0x06, 0x02, 0xc5, -+ 0x00, 0xbd, 0x00, 0x00, -+ 0x02, 0xc1, 0x00, 0xb9, -+ 0x00, 0x00, 0x02, 0xc1, -+ 0x00, 0xb9, 0x00, 0x00 }; ++ 0xe4, 0x4b, 0x0c, 0x61, ++ 0x92, 0x48, 0x93, 0x48, ++ 0x95, 0x48, 0x96, 0x48, ++ 0x0c, 0x89, 0x02, 0xc0, ++ 0x00, 0xb8, 0x0e, 0x06, ++ 0x30, 0x18, 0xf5, 0xc1, ++ 0xe0, 0xef, 0x04, 0xc5, ++ 0x02, 0xc4, 0x00, 0xbc, ++ 0x76, 0x3c, 0x1e, 0xfc, ++ 0x02, 0xc6, 0x00, 0xbe, ++ 0x00, 0x00, 0x02, 0xc6, ++ 0x00, 0xbe, 0x00, 0x00 }; + static u8 pla_patch_d[] = { + 0x03, 0xe0, 0x16, 0xe0, + 0x30, 0xe0, 0x12, 0xc2, @@ -4035,9 +5570,8 @@ index 2490498b..26cc7c1a 100644 + sram_write(tp, 0xb820, 0x0210); + r8153_post_ram_code(tp, 0x8146); + -+ r8153_clear_bp(tp); ++ rtl_clear_bp(tp, MCU_TYPE_USB); + -+ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_EN, 0x0000); + generic_ocp_write(tp, 0xf800, 0xff, sizeof(usb_patch_d), + usb_patch_d, MCU_TYPE_USB); + ocp_write_word(tp, MCU_TYPE_USB, 0xfc26, 0xa000); @@ -4046,15 +5580,16 @@ index 2490498b..26cc7c1a 100644 + ocp_write_word(tp, MCU_TYPE_USB, 0xfc2c, 0x1792); + ocp_write_word(tp, MCU_TYPE_USB, 0xfc2e, 0x1236); + ocp_write_word(tp, MCU_TYPE_USB, 0xfc30, 0x0606); -+ ocp_write_word(tp, MCU_TYPE_USB, 0xfc32, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_USB, 0xfc32, 0x3C74); + ocp_write_word(tp, MCU_TYPE_USB, 0xfc34, 0x0000); + ocp_write_word(tp, MCU_TYPE_USB, 0xfc36, 0x0000); -+ if (ocp_read_byte(tp, MCU_TYPE_USB, 0xcfef) & 1) -+ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_EN, 0x001b); ++ if (ocp_read_byte(tp, MCU_TYPE_USB, USB_CSTMR) & FORCE_SUPER) ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_EN, 0x003f); + else -+ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_EN, 0x001a); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_EN, 0x003e); ++ ++ rtl_clear_bp(tp, MCU_TYPE_PLA); + -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, 0x0000); + generic_ocp_write(tp, 0xf800, 0xff, sizeof(pla_patch_d), + pla_patch_d, MCU_TYPE_PLA); + ocp_write_word(tp, MCU_TYPE_PLA, 0xfc26, 0x8000); @@ -4071,11 +5606,18 @@ index 2490498b..26cc7c1a 100644 + ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_USB2PHY); + ocp_data |= USB2PHY_L1 | USB2PHY_SUSPEND; + ocp_write_byte(tp, MCU_TYPE_USB, USB_USB2PHY, ocp_data); -+ } -+} + ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN1); ++ ocp_data |= FW_IP_RESET_EN; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN1, ocp_data); ++ } + } + +-static void r8153_eee_en(struct r8152 *tp, bool enable) +static void r8153b_firmware(struct r8152 *tp) -+{ + { +- u32 ocp_data; +- u16 config; + if (tp->version == RTL_VER_09) { + u32 ocp_data; + static u8 usb_patch2_b[] = { @@ -4084,9 +5626,9 @@ index 2490498b..26cc7c1a 100644 + 0x6c, 0xe0, 0x85, 0xe0, + 0xa5, 0xe0, 0xbe, 0xe0, + 0xd8, 0xe0, 0xdb, 0xe0, -+ 0xdd, 0xe0, 0xdf, 0xe0, -+ 0xe1, 0xe0, 0xe3, 0xe0, -+ 0xe5, 0xe0, 0xe7, 0xe0, ++ 0xf3, 0xe0, 0xf5, 0xe0, ++ 0xf7, 0xe0, 0xf9, 0xe0, ++ 0xfb, 0xe0, 0xfd, 0xe0, + 0x16, 0xc0, 0x00, 0x75, + 0xd1, 0x49, 0x0d, 0xf0, + 0x0f, 0xc0, 0x0f, 0xc5, @@ -4193,8 +5735,19 @@ index 2490498b..26cc7c1a 100644 + 0x34, 0xd3, 0x00, 0xdc, + 0x1e, 0x89, 0x02, 0xc0, + 0x00, 0xb8, 0xfa, 0x12, -+ 0x02, 0xc0, 0x00, 0xb8, -+ 0x00, 0x00, 0x02, 0xc0, ++ 0x18, 0xc0, 0x00, 0x65, ++ 0xd1, 0x49, 0x0e, 0xf0, ++ 0x11, 0xc0, 0x11, 0xc5, ++ 0x00, 0x1e, 0x08, 0x9e, ++ 0x0c, 0x9d, 0x0e, 0xc6, ++ 0x0a, 0x9e, 0x8f, 0x1c, ++ 0x0e, 0x8c, 0x0e, 0x74, ++ 0xcf, 0x49, 0xfe, 0xf1, ++ 0x04, 0xc0, 0x02, 0xc2, ++ 0x00, 0xba, 0xa0, 0x41, ++ 0x06, 0xd4, 0x00, 0xdc, ++ 0x24, 0xe4, 0x80, 0x02, ++ 0x34, 0xd3, 0x02, 0xc0, + 0x00, 0xb8, 0x00, 0x00, + 0x02, 0xc0, 0x00, 0xb8, + 0x00, 0x00, 0x02, 0xc0, @@ -4279,10 +5832,11 @@ index 2490498b..26cc7c1a 100644 + 0x02, 0xc2, 0x00, 0xba, + 0xda, 0x0e, 0x08, 0xe9 }; + -+ r8153b_clear_bp(tp, MCU_TYPE_USB); -+ r8153b_clear_bp(tp, MCU_TYPE_PLA); ++ rtl_clear_bp(tp, MCU_TYPE_USB); + -+ ocp_write_word(tp, MCU_TYPE_USB, 0xd340, 0x807d); ++ /* enable fc timer and set timer to 1 second. */ ++ ocp_write_word(tp, MCU_TYPE_USB, USB_FC_TIMER, ++ CTRL_TIMER_EN | (1000 / 8)); + + generic_ocp_write(tp, 0xe600, 0xff, sizeof(usb_patch2_b), + usb_patch2_b, MCU_TYPE_USB); @@ -4297,14 +5851,16 @@ index 2490498b..26cc7c1a 100644 + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_6, 0x340c); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_7, 0x335e); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_8, 0x12f8); -+ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_9, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_9, 0x419e); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_10, 0x0000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_11, 0x0000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_12, 0x0000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_13, 0x0000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_14, 0x0000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_15, 0x0000); -+ ocp_write_word(tp, MCU_TYPE_USB, USB_BP2_EN, 0x01ff); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP2_EN, 0x03ff); ++ ++ rtl_clear_bp(tp, MCU_TYPE_PLA); + + generic_ocp_write(tp, 0xf800, 0xff, sizeof(pla_patch2_b), + pla_patch2_b, MCU_TYPE_PLA); @@ -4320,28 +5876,41 @@ index 2490498b..26cc7c1a 100644 + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_7, 0x0000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, 0x001e); + -+ if (ocp_read_byte(tp, MCU_TYPE_USB, 0xd81f) & BIT(2)) { ++ if (ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_1) & BND_MASK) { + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_BP_EN); + ocp_data |= BIT(0); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, ocp_data); + } -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xd334); -+ ocp_data |= BIT(1); -+ ocp_write_word(tp, MCU_TYPE_USB, 0xd334, ocp_data); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xd4e8); -+ ocp_data |= BIT(1); -+ ocp_write_word(tp, MCU_TYPE_USB, 0xd4e8, ocp_data); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xcfcc); -+ ocp_data |= BIT(9); -+ ocp_write_word(tp, MCU_TYPE_USB, 0xcfcc, ocp_data); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); +- config = ocp_reg_read(tp, OCP_EEE_CFG); ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_CTRL); ++ ocp_data |= FLOW_CTRL_PATCH_OPT; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_FW_CTRL, ocp_data); + +- if (enable) { +- ocp_data |= EEE_RX_EN | EEE_TX_EN; +- config |= EEE10_EN; +- } else { +- ocp_data &= ~(EEE_RX_EN | EEE_TX_EN); +- config &= ~EEE10_EN; +- } ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_TASK); ++ ocp_data |= FC_PATCH_TASK; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); + +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data); +- ocp_reg_write(tp, OCP_EEE_CFG, config); ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN1); ++ ocp_data |= FW_IP_RESET_EN; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN1, ocp_data); + } -+} -+ + } + +-static void r8153b_eee_en(struct r8152 *tp, bool enable) +static void r8156_firmware(struct r8152 *tp) -+{ + { +- r8153_eee_en(tp, enable); + if (tp->version == RTL_TEST_01) { + static u8 usb3_patch_t[] = { + 0x01, 0xe0, 0x05, 0xc7, @@ -4349,7 +5918,11 @@ index 2490498b..26cc7c1a 100644 + 0x00, 0xb8, 0x40, 0x03, + 0x00, 0xd4, 0x00, 0x00 }; + u16 data; -+ + +- if (enable) +- r8153b_ups_flags_w1w0(tp, UPS_FLAGS_EN_EEE, 0); +- else +- r8153b_ups_flags_w1w0(tp, 0, UPS_FLAGS_EN_EEE); + ocp_reg_write(tp, 0xb87c, 0x8099); + ocp_reg_write(tp, 0xb87e, 0x2a50); + ocp_reg_write(tp, 0xb87c, 0x80a1); @@ -4483,7 +6056,7 @@ index 2490498b..26cc7c1a 100644 + data |= BIT(0); + ocp_reg_write(tp, 0xb896, data); + -+ r8153_pre_ram_code(tp, 0x8024, 0x0000); ++ rtl_patch_key_set(tp, 0x8024, 0x0000); + + data = ocp_reg_read(tp, 0xb820); + data |= BIT(7); @@ -5652,7 +7225,7 @@ index 2490498b..26cc7c1a 100644 + sram_write(tp, 0xb81e, 0xffff); + sram_write(tp, 0xb832, 0x0003); + -+ r8153_post_ram_code(tp, 0x8024); ++ rtl_patch_key_clear(tp, 0x8024); + ocp_reg_write(tp, 0xc414, 0x0200); + + r8153_patch_request(tp, false); @@ -5759,7 +7332,7 @@ index 2490498b..26cc7c1a 100644 + + r8156_lock_mian(tp, false); + -+ r8153b_clear_bp(tp, MCU_TYPE_USB); ++ rtl_clear_bp(tp, MCU_TYPE_USB); + + generic_ocp_write(tp, 0xe600, 0xff, sizeof(usb3_patch_t), + usb3_patch_t, MCU_TYPE_USB); @@ -5783,10 +7356,13 @@ index 2490498b..26cc7c1a 100644 +// ocp_write_word(tp, MCU_TYPE_USB, USB_BP_15, 0x0000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP2_EN, 0x0001); + } -+} -+ + } + +-static void r8153b_enable_fc(struct r8152 *tp) +static void r8153_aldps_en(struct r8152 *tp, bool enable) -+{ + { +- r8152b_enable_fc(tp); +- r8153b_ups_flags_w1w0(tp, UPS_FLAGS_EN_FLOW_CTR, 0); + u16 data; + + data = ocp_reg_read(tp, OCP_POWER_CFG); @@ -5806,77 +7382,33 @@ index 2490498b..26cc7c1a 100644 + } + + tp->ups_info.aldps = enable; -+} -+ -+static void r8153_eee_en(struct r8152 *tp, bool enable) -+{ -+ u32 ocp_data; -+ u16 config; -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); -+ config = ocp_reg_read(tp, OCP_EEE_CFG); -+ -+ if (enable) { -+ ocp_data |= EEE_RX_EN | EEE_TX_EN; -+ config |= EEE10_EN; -+ } else { -+ ocp_data &= ~(EEE_RX_EN | EEE_TX_EN); -+ config &= ~EEE10_EN; -+ } -+ -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data); -+ ocp_reg_write(tp, OCP_EEE_CFG, config); -+ -+ tp->ups_info.eee = enable; -+} -+ -+static void r8156_eee_en(struct r8152 *tp, bool enable) -+{ -+ u16 config; -+ - r8153_eee_en(tp, enable); - -+ config = ocp_reg_read(tp, 0xa6d4); -+ - if (enable) -- r8153b_ups_flags_w1w0(tp, UPS_FLAGS_EN_EEE, 0); -+ config |= BIT(0); - else -- r8153b_ups_flags_w1w0(tp, 0, UPS_FLAGS_EN_EEE); --} -+ config &= ~BIT(0); - --static void r8153b_enable_fc(struct r8152 *tp) --{ -- r8152b_enable_fc(tp); -- r8153b_ups_flags_w1w0(tp, UPS_FLAGS_EN_FLOW_CTR, 0); -+ ocp_reg_write(tp, 0xa6d4, config); } static void r8153_hw_phy_cfg(struct r8152 *tp) -@@ -3270,6 +7335,8 @@ static void r8153_hw_phy_cfg(struct r8152 *tp) - r8153_eee_en(tp, false); - ocp_reg_write(tp, OCP_EEE_ADV, 0); +@@ -3275,8 +8134,9 @@ static void r8153_hw_phy_cfg(struct r8152 *tp) + r8153_aldps_en(tp, false); -+ r8153_firmware(tp); + /* disable EEE before updating the PHY parameters */ +- r8153_eee_en(tp, false); +- ocp_reg_write(tp, OCP_EEE_ADV, 0); ++ rtl_eee_enable(tp, false); + ++ r8153_firmware(tp); + if (tp->version == RTL_VER_03) { data = ocp_reg_read(tp, OCP_EEE_CFG); - data &= ~CTAP_SHORT_EN; -@@ -3299,8 +7366,10 @@ static void r8153_hw_phy_cfg(struct r8152 *tp) +@@ -3307,8 +8167,8 @@ static void r8153_hw_phy_cfg(struct r8152 *tp) sram_write(tp, SRAM_10M_AMP1, 0x00af); sram_write(tp, SRAM_10M_AMP2, 0x0208); - r8153_eee_en(tp, true); - ocp_reg_write(tp, OCP_EEE_ADV, MDIO_EEE_1000T | MDIO_EEE_100TX); -+ if (tp->eee_en) { -+ r8153_eee_en(tp, true); -+ ocp_reg_write(tp, OCP_EEE_ADV, tp->eee_adv); -+ } ++ if (tp->eee_en) ++ rtl_eee_enable(tp, true); r8153_aldps_en(tp, true); r8152b_enable_fc(tp); -@@ -3333,16 +7402,21 @@ static u32 r8152_efuse_read(struct r8152 *tp, u8 addr) +@@ -3341,15 +8201,19 @@ static u32 r8152_efuse_read(struct r8152 *tp, u8 addr) static void r8153b_hw_phy_cfg(struct r8152 *tp) { @@ -5890,18 +7422,17 @@ index 2490498b..26cc7c1a 100644 /* disable EEE before updating the PHY parameters */ - r8153b_eee_en(tp, false); -+ r8153_eee_en(tp, false); - ocp_reg_write(tp, OCP_EEE_ADV, 0); - +- ocp_reg_write(tp, OCP_EEE_ADV, 0); ++ rtl_eee_enable(tp, false); ++ + /* U1/U2/L1 idle timer. 500 us */ + ocp_write_word(tp, MCU_TYPE_USB, USB_U1U2_TIMER, 500); + + r8153b_firmware(tp); -+ + r8153b_green_en(tp, test_bit(GREEN_ETHERNET, &tp->flags)); - data = sram_read(tp, SRAM_GREEN_CFG); -@@ -3381,34 +7455,42 @@ static void r8153b_hw_phy_cfg(struct r8152 *tp) +@@ -3389,34 +8253,40 @@ static void r8153b_hw_phy_cfg(struct r8152 *tp) ocp_data |= PFM_PWM_SWITCH; ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data); @@ -5938,14 +7469,12 @@ index 2490498b..26cc7c1a 100644 } - r8153b_ups_flags_w1w0(tp, ups_flags, 0); -- ++ if (tp->eee_en) ++ rtl_eee_enable(tp, true); + - r8153b_eee_en(tp, true); - ocp_reg_write(tp, OCP_EEE_ADV, MDIO_EEE_1000T | MDIO_EEE_100TX); -+ if (tp->eee_en) { -+ r8153_eee_en(tp, true); -+ ocp_reg_write(tp, OCP_EEE_ADV, tp->eee_adv); -+ } - +- - r8153b_aldps_en(tp, true); - r8153b_enable_fc(tp); - r8153_u2p3en(tp, true); @@ -5955,24 +7484,91 @@ index 2490498b..26cc7c1a 100644 set_bit(PHY_RESET, &tp->flags); } -@@ -3418,7 +7500,6 @@ static void r8153_first_init(struct r8152 *tp) +@@ -3424,9 +8294,7 @@ static void r8153b_hw_phy_cfg(struct r8152 *tp) + static void r8153_first_init(struct r8152 *tp) + { u32 ocp_data; - int i; +- int i; - r8153_mac_clk_spd(tp, false); rxdy_gated_en(tp, true); r8153_teredo_off(tp); -@@ -3480,8 +7561,6 @@ static void r8153_enter_oob(struct r8152 *tp) - u32 ocp_data; - int i; +@@ -3445,23 +8313,13 @@ static void r8153_first_init(struct r8152 *tp) + ocp_data &= ~MCU_BORW_EN; + ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); -- r8153_mac_clk_spd(tp, true); +- for (i = 0; i < 1000; i++) { +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); +- if (ocp_data & LINK_LIST_READY) +- break; +- usleep_range(1000, 2000); +- } ++ wait_oob_link_list_ready(tp); + + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); + ocp_data |= RE_INIT_LL; + ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); + +- for (i = 0; i < 1000; i++) { +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); +- if (ocp_data & LINK_LIST_READY) +- break; +- usleep_range(1000, 2000); +- } ++ wait_oob_link_list_ready(tp); + + rtl_rx_vlan_en(tp, tp->netdev->features & NETIF_F_HW_VLAN_CTAG_RX); + +@@ -3486,9 +8344,6 @@ static void r8153_first_init(struct r8152 *tp) + static void r8153_enter_oob(struct r8152 *tp) + { + u32 ocp_data; +- int i; - +- r8153_mac_clk_spd(tp, true); + ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); ocp_data &= ~NOW_IS_OOB; - ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); -@@ -3558,111 +7637,198 @@ static void rtl8153_disable(struct r8152 *tp) +@@ -3497,23 +8352,13 @@ static void r8153_enter_oob(struct r8152 *tp) + rtl_disable(tp); + rtl_reset_bmu(tp); + +- for (i = 0; i < 1000; i++) { +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); +- if (ocp_data & LINK_LIST_READY) +- break; +- usleep_range(1000, 2000); +- } ++ wait_oob_link_list_ready(tp); + + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); + ocp_data |= RE_INIT_LL; + ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); + +- for (i = 0; i < 1000; i++) { +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); +- if (ocp_data & LINK_LIST_READY) +- break; +- usleep_range(1000, 2000); +- } ++ wait_oob_link_list_ready(tp); + + ocp_data = tp->netdev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; + ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, ocp_data); +@@ -3543,9 +8388,9 @@ static void r8153_enter_oob(struct r8152 *tp) + + rtl_rx_vlan_en(tp, true); + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PAL_BDC_CR); ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_BDC_CR); + ocp_data |= ALDPS_PROXY_MODE; +- ocp_write_word(tp, MCU_TYPE_PLA, PAL_BDC_CR, ocp_data); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_BDC_CR, ocp_data); + + ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); + ocp_data |= NOW_IS_OOB | DIS_MCU_CLROOB; +@@ -3566,111 +8411,258 @@ static void rtl8153_disable(struct r8152 *tp) r8153_aldps_en(tp, true); } @@ -5983,24 +7579,12 @@ index 2490498b..26cc7c1a 100644 - rtl_disable(tp); - rtl_reset_bmu(tp); - r8153b_aldps_en(tp, true); --} + u32 ocp_data; + u16 speed; - --static int rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u16 speed, u8 duplex) --{ -- u16 bmcr, anar, gbcr; -- enum spd_duplex speed_duplex; -- int ret = 0; ++ + if (test_bit(RTL8152_UNPLUG, &tp->flags)) + return -ENODEV; - -- anar = r8152_mdio_read(tp, MII_ADVERTISE); -- anar &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL | -- ADVERTISE_100HALF | ADVERTISE_100FULL); -- if (tp->mii.supports_gmii) { -- gbcr = r8152_mdio_read(tp, MII_CTRL1000); -- gbcr &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); ++ + set_tx_qlen(tp); + rtl_set_eee_plus(tp); + r8153_set_rx_early_timeout(tp); @@ -6032,16 +7616,15 @@ index 2490498b..26cc7c1a 100644 + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4); + ocp_data &= ~BIT(8); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ocp_data); - } else { -- gbcr = 0; ++ } else { + ocp_data |= BIT(9) | BIT(8); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_TCR1, ocp_data); + + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4); + ocp_data |= BIT(8); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ocp_data); - } - ++ } ++ + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4); + if (speed & _2500bps) + ocp_data &= ~BIT(6); @@ -6054,6 +7637,79 @@ index 2490498b..26cc7c1a 100644 + else if (speed & _500bps) + ocp_write_byte(tp, MCU_TYPE_PLA, 0xe04c, 0x3d); + ++ return rtl_enable(tp); + } + +-static int rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u16 speed, u8 duplex) ++static int rtl8156b_enable(struct r8152 *tp) + { +- u16 bmcr, anar, gbcr; +- enum spd_duplex speed_duplex; +- int ret = 0; ++ u32 ocp_data; ++ u16 speed; + +- anar = r8152_mdio_read(tp, MII_ADVERTISE); +- anar &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL | +- ADVERTISE_100HALF | ADVERTISE_100FULL); +- if (tp->mii.supports_gmii) { +- gbcr = r8152_mdio_read(tp, MII_CTRL1000); +- gbcr &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return -ENODEV; ++ ++ set_tx_qlen(tp); ++ rtl_set_eee_plus(tp); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xd4ee); ++ ocp_data &= ~0x1ff; ++ ocp_data |= 2; ++ ocp_write_word(tp, MCU_TYPE_USB, 0xd4ee, ocp_data); ++ ++ r8153_set_rx_early_timeout(tp); ++ r8153_set_rx_early_size(tp); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR1); ++ ocp_data &= ~(BIT(3) | BIT(9) | BIT(8)); ++ speed = rtl8152_get_speed(tp); ++ if ((speed & (_10bps | _100bps)) && !(speed & FULL_DUP)) { ++ ocp_data |= BIT(9); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_TCR1, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4); ++ ocp_data &= ~TX10MIDLE_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ocp_data); + } else { +- gbcr = 0; ++ ocp_data |= BIT(9) | BIT(8); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_TCR1, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4); ++ ocp_data |= TX10MIDLE_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ocp_data); + } + ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4); ++ if (speed & _2500bps) ++ ocp_data &= ~BIT(6); ++ else ++ ocp_data |= BIT(6); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ocp_data); ++ ++ if (tp->udev->speed == USB_SPEED_HIGH) { ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xb45e); ++ ocp_data &= ~0xf; ++ ocp_data |= 1; ++ ocp_write_word(tp, MCU_TYPE_USB, 0xb45e, ocp_data); ++ } ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_TASK); ++ ocp_data &= ~FC_PATCH_TASK; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); ++ usleep_range(1000, 2000); ++ ocp_data |= FC_PATCH_TASK; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); ++ + return rtl_enable(tp); +} + @@ -6137,6 +7793,7 @@ index 2490498b..26cc7c1a 100644 } - speed_duplex = NWAY_1000M_FULL; - } else { ++ /* fall through */ + default: ret = -EINVAL; goto out; @@ -6149,76 +7806,73 @@ index 2490498b..26cc7c1a 100644 + + tp->mii.force_media = 1; + } else { -+ u16 anar, tmp1; ++ u16 orig, new1; + u32 support; + -+ support = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | -+ ADVERTISED_100baseT_Half | -+ ADVERTISED_100baseT_Full; ++ support = RTL_ADVERTISED_10_HALF | RTL_ADVERTISED_10_FULL | ++ RTL_ADVERTISED_100_HALF | RTL_ADVERTISED_100_FULL; + + if (tp->mii.supports_gmii) { -+ support |= ADVERTISED_1000baseT_Full; ++ support |= RTL_ADVERTISED_1000_FULL; + -+ if (test_bit(SUPPORT_2500FULL, &tp->flags)) -+ support |= ADVERTISED_2500baseX_Full; ++ if (tp->support_2500full) ++ support |= RTL_ADVERTISED_2500_FULL; + } + + if (!(advertising & support)) + return -EINVAL; + -+ anar = r8152_mdio_read(tp, MII_ADVERTISE); -+ tmp1 = anar & ~(ADVERTISE_10HALF | ADVERTISE_10FULL | ++ orig = r8152_mdio_read(tp, MII_ADVERTISE); ++ new1 = orig & ~(ADVERTISE_10HALF | ADVERTISE_10FULL | + ADVERTISE_100HALF | ADVERTISE_100FULL); -+ if (advertising & ADVERTISED_10baseT_Half) { -+ tmp1 |= ADVERTISE_10HALF; ++ if (advertising & RTL_ADVERTISED_10_HALF) { ++ new1 |= ADVERTISE_10HALF; + tp->ups_info.speed_duplex = NWAY_10M_HALF; + } -+ if (advertising & ADVERTISED_10baseT_Full) { -+ tmp1 |= ADVERTISE_10FULL; ++ if (advertising & RTL_ADVERTISED_10_FULL) { ++ new1 |= ADVERTISE_10FULL; + tp->ups_info.speed_duplex = NWAY_10M_FULL; + } + -+ if (advertising & ADVERTISED_100baseT_Half) { -+ tmp1 |= ADVERTISE_100HALF; ++ if (advertising & RTL_ADVERTISED_100_HALF) { ++ new1 |= ADVERTISE_100HALF; + tp->ups_info.speed_duplex = NWAY_100M_HALF; + } -+ if (advertising & ADVERTISED_100baseT_Full) { -+ tmp1 |= ADVERTISE_100FULL; ++ if (advertising & RTL_ADVERTISED_100_FULL) { ++ new1 |= ADVERTISE_100FULL; + tp->ups_info.speed_duplex = NWAY_100M_FULL; + } + -+ if (anar != tmp1) { -+ r8152_mdio_write(tp, MII_ADVERTISE, tmp1); -+ tp->mii.advertising = tmp1; ++ if (orig != new1) { ++ r8152_mdio_write(tp, MII_ADVERTISE, new1); ++ tp->mii.advertising = new1; + } + + if (tp->mii.supports_gmii) { -+ u16 gbcr, tmp2 = 0; -+ -+ gbcr = r8152_mdio_read(tp, MII_CTRL1000); -+ tmp2 = gbcr & ~(ADVERTISE_1000FULL | ++ orig = r8152_mdio_read(tp, MII_CTRL1000); ++ new1 = orig & ~(ADVERTISE_1000FULL | + ADVERTISE_1000HALF); + -+ if (advertising & ADVERTISED_1000baseT_Half) { -+ tmp2 |= ADVERTISE_1000HALF; -+ tp->ups_info.speed_duplex = NWAY_1000M_FULL; -+ } -+ if (advertising & ADVERTISED_1000baseT_Full) { -+ tmp2 |= ADVERTISE_1000FULL; ++ if (advertising & RTL_ADVERTISED_1000_FULL) { ++ new1 |= ADVERTISE_1000FULL; + tp->ups_info.speed_duplex = NWAY_1000M_FULL; + } + -+ if (gbcr != tmp2) -+ r8152_mdio_write(tp, MII_CTRL1000, tmp2); ++ if (orig != new1) ++ r8152_mdio_write(tp, MII_CTRL1000, new1); ++ } + -+ gbcr = ocp_reg_read(tp, 0xa5d4); -+ tmp2 = gbcr & ~BIT(7); ++ if (tp->support_2500full) { ++ orig = ocp_reg_read(tp, 0xa5d4); ++ new1 = orig & ~BIT(7); + -+ if (advertising & ADVERTISED_2500baseX_Full) -+ tmp2 |= BIT(7); ++ if (advertising & RTL_ADVERTISED_2500_FULL) { ++ new1 |= BIT(7); ++ tp->ups_info.speed_duplex = NWAY_2500M_FULL; ++ } + -+ if (gbcr != tmp2) -+ ocp_reg_write(tp, 0xa5d4, tmp2); ++ if (orig != new1) ++ ocp_reg_write(tp, 0xa5d4, new1); + } + bmcr = BMCR_ANENABLE | BMCR_ANRESTART; @@ -6249,20 +7903,30 @@ index 2490498b..26cc7c1a 100644 if (bmcr & BMCR_RESET) { int i; -@@ -3677,6 +7843,64 @@ out: +@@ -3685,20 +8677,78 @@ out: return ret; } +-static void rtl8152_up(struct r8152 *tp) +static bool rtl_speed_down(struct r8152 *tp) -+{ + { + bool ret = false; + -+ if (test_bit(RTL8152_UNPLUG, &tp->flags)) + if (test_bit(RTL8152_UNPLUG, &tp->flags)) +- return; + return ret; -+ + +- r8152_aldps_en(tp, false); +- r8152b_exit_oob(tp); +- r8152_aldps_en(tp, true); +-} + if ((tp->saved_wolopts & WAKE_ANY) && !(tp->saved_wolopts & WAKE_PHY)) { + u16 bmcr; -+ + +-static void rtl8152_down(struct r8152 *tp) +-{ +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) { +- rtl_drop_queued_tx(tp); + bmcr = r8152_mdio_read(tp, MII_BMCR); + + if (netif_carrier_ok(tp->netdev) && (bmcr & BMCR_ANENABLE) && @@ -6277,7 +7941,7 @@ index 2490498b..26cc7c1a 100644 + gbcr = r8152_mdio_read(tp, MII_CTRL1000); + gbcr &= ~(ADVERTISE_1000FULL | + ADVERTISE_1000HALF); -+ if (test_bit(SUPPORT_2500FULL, &tp->flags)) { ++ if (tp->support_2500full) { + gbcr2 = ocp_reg_read(tp, 0xa5d4); + gbcr2 &= ~BIT(7); + } @@ -6295,7 +7959,7 @@ index 2490498b..26cc7c1a 100644 + + if (tp->mii.supports_gmii) { + r8152_mdio_write(tp, MII_CTRL1000, gbcr); -+ if (test_bit(SUPPORT_2500FULL, &tp->flags)) ++ if (tp->support_2500full) + ocp_reg_write(tp, 0xa5d4, gbcr2); + } + @@ -6311,18 +7975,24 @@ index 2490498b..26cc7c1a 100644 + return ret; +} + - static void rtl8152_up(struct r8152 *tp) - { - if (test_bit(RTL8152_UNPLUG, &tp->flags)) -@@ -3698,28 +7922,46 @@ static void rtl8152_down(struct r8152 *tp) - r8152_aldps_en(tp, false); - r8152b_enter_oob(tp); - r8152_aldps_en(tp, true); -+ if (tp->version == RTL_VER_01) -+ rtl8152_set_speed(tp, AUTONEG_ENABLE, 0, 0, 3); -+ else -+ rtl_speed_down(tp); - } ++static void rtl8152_up(struct r8152 *tp) ++{ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return; ++ ++ r8152_aldps_en(tp, false); ++ r8152b_exit_oob(tp); ++ r8152_aldps_en(tp, true); ++} ++ ++static void rtl8152_down(struct r8152 *tp) ++{ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) { ++ rtl_drop_queued_tx(tp); + return; + } + +@@ -3710,13 +8760,29 @@ static void rtl8152_down(struct r8152 *tp) static void rtl8153_up(struct r8152 *tp) { @@ -6336,42 +8006,23 @@ index 2490498b..26cc7c1a 100644 r8153_aldps_en(tp, false); + r8153_mac_clk_spd(tp, false); r8153_first_init(tp); -- r8153_aldps_en(tp, true); ++ ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6); ++ ocp_data |= LANWAKE_CLR_EN; ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6, ocp_data); ++ ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_LWAKE_CTRL_REG); ++ ocp_data &= ~LANWAKE_PIN; ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_LWAKE_CTRL_REG, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_SSPHYLINK1); ++ ocp_data &= ~DELAY_PHY_PWR_CHG; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_SSPHYLINK1, ocp_data); ++ + r8153_aldps_en(tp, true); -- switch (tp->version) { -- case RTL_VER_03: -- case RTL_VER_04: -- break; -- case RTL_VER_05: -- case RTL_VER_06: -- default: -- r8153_u2p3en(tp, true); -- break; -+ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, 0xe90a); -+ ocp_data |= BIT(0); -+ ocp_write_byte(tp, MCU_TYPE_PLA, 0xe90a, ocp_data); -+ -+ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, 0xe007); -+ ocp_data &= ~BIT(7); -+ ocp_write_byte(tp, MCU_TYPE_PLA, 0xe007, ocp_data); -+ -+ if (!work_busy(&tp->hw_phy_work.work)) { -+ r8153_aldps_en(tp, true); -+ -+ switch (tp->version) { -+ case RTL_VER_03: -+ case RTL_VER_04: -+ break; -+ case RTL_VER_05: -+ case RTL_VER_06: -+ default: -+ r8153_u2p3en(tp, true); -+ break; -+ } - } - - r8153_u1u2en(tp, true); -@@ -3727,49 +7969,196 @@ static void rtl8153_up(struct r8152 *tp) + switch (tp->version) { +@@ -3735,49 +8801,224 @@ static void rtl8153_up(struct r8152 *tp) static void rtl8153_down(struct r8152 *tp) { @@ -6382,9 +8033,9 @@ index 2490498b..26cc7c1a 100644 return; } -+ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, 0xe90a); -+ ocp_data &= ~BIT(0); -+ ocp_write_byte(tp, MCU_TYPE_PLA, 0xe90a, ocp_data); ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6); ++ ocp_data &= ~LANWAKE_CLR_EN; ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6, ocp_data); + r8153_u1u2en(tp, false); r8153_u2p3en(tp, false); @@ -6393,7 +8044,6 @@ index 2490498b..26cc7c1a 100644 + r8153_mac_clk_spd(tp, true); r8153_enter_oob(tp); r8153_aldps_en(tp, true); -+ rtl_speed_down(tp); } static void rtl8153b_up(struct r8152 *tp) @@ -6403,48 +8053,70 @@ index 2490498b..26cc7c1a 100644 if (test_bit(RTL8152_UNPLUG, &tp->flags)) return; -- r8153b_u1u2en(tp, false); -- r8153_u2p3en(tp, false); + r8153b_u1u2en(tp, false); + r8153_u2p3en(tp, false); - r8153b_aldps_en(tp, false); -+ r8153b_u1u2en(tp, false); -+ r8153_u2p3en(tp, false); + r8153_aldps_en(tp, false); -+ -+ r8153_first_init(tp); -+ ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, RX_THR_B); -+ + + r8153_first_init(tp); + ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, RX_THR_B); + +- r8153b_aldps_en(tp, true); +- r8153_u2p3en(tp, true); +- r8153b_u1u2en(tp, true); + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); -+ ocp_data &= ~BIT(14); ++ ocp_data &= ~PLA_MCU_SPDWN_EN; + ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data); + -+ if (!work_busy(&tp->hw_phy_work.work)) { -+ r8153_aldps_en(tp, true); -+// r8153_u2p3en(tp, true); -+ } -+ -+ r8153b_u1u2en(tp, true); -+} -+ -+static void rtl8153b_down(struct r8152 *tp) -+{ ++ r8153_aldps_en(tp, true); ++// r8153_u2p3en(tp, true); ++ if (tp->udev->speed >= USB_SPEED_SUPER) ++ r8153b_u1u2en(tp, true); + } + + static void rtl8153b_down(struct r8152 *tp) + { + u32 ocp_data; + -+ if (test_bit(RTL8152_UNPLUG, &tp->flags)) { -+ rtl_drop_queued_tx(tp); -+ return; -+ } -+ + if (test_bit(RTL8152_UNPLUG, &tp->flags)) { + rtl_drop_queued_tx(tp); + return; + } + + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); -+ ocp_data |= BIT(14); ++ ocp_data |= PLA_MCU_SPDWN_EN; + ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data); + -+ r8153b_u1u2en(tp, false); -+ r8153_u2p3en(tp, false); -+ r8153b_power_cut_en(tp, false); + r8153b_u1u2en(tp, false); + r8153_u2p3en(tp, false); + r8153b_power_cut_en(tp, false); +- r8153b_aldps_en(tp, false); + r8153_aldps_en(tp, false); -+ r8153_enter_oob(tp); + r8153_enter_oob(tp); +- r8153b_aldps_en(tp, true); + r8153_aldps_en(tp, true); -+ rtl_speed_down(tp); ++} ++ ++static void r8156_fc_parameter(struct r8152 *tp) ++{ ++ u32 base = ALIGN(tp->netdev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN, 1024); ++ u32 fc_pause = tp->fc_pause ? tp->fc_pause : (base + 0x800); ++ u32 fc_restart = tp->fc_restart ? tp->fc_restart : (base + 0x1800); ++ ++ switch (tp->version) { ++ case RTL_VER_10: ++ case RTL_VER_11: ++ ocp_write_word(tp, MCU_TYPE_PLA, 0xc0a6, fc_pause / 8); ++ ocp_write_word(tp, MCU_TYPE_PLA, 0xc0aa, fc_restart / 8); ++ break; ++ case RTL_VER_12: ++ case RTL_VER_13: ++ ocp_write_word(tp, MCU_TYPE_PLA, 0xc0a6, fc_pause / 16); ++ ocp_write_word(tp, MCU_TYPE_PLA, 0xc0aa, fc_restart / 16); ++ break; ++ default: ++ break; ++ } +} + +static void rtl8156_up(struct r8152 *tp) @@ -6465,7 +8137,7 @@ index 2490498b..26cc7c1a 100644 + ocp_data &= ~RCR_ACPT_ALL; + ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); + -+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, 0); ++ rtl8152_nic_reset(tp); + rtl_reset_bmu(tp); + + ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); @@ -6482,72 +8154,75 @@ index 2490498b..26cc7c1a 100644 + ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, ocp_data); + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_MTPS, MTPS_JUMBO); + ++ switch (tp->version) { ++ case RTL_VER_10: ++ case RTL_VER_11: ++ r8156_fc_parameter(tp); ++ ++ /* TX share fifo free credit full threshold */ ++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_TXFIFO_CTRL, ++ TXFIFO_THR_NORMAL2); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xd4b4); ++ ocp_data |= BIT(1); ++ ocp_write_word(tp, MCU_TYPE_USB, 0xd4b4, ocp_data); ++ break; ++ case RTL_VER_12: ++ case RTL_VER_13: ++ default: ++ r8156_fc_parameter(tp); ++ ++ /* TX share fifo free credit full threshold */ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_TXFIFO_CTRL, 0x0008); ++ ocp_write_word(tp, MCU_TYPE_PLA, 0xe61a, ++ (ocp_data + 0x800) / 16); ++ break; ++ } ++ + /* share FIFO settings */ + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, 0xc0a2); + ocp_data &= ~0xfff; + ocp_data |= 0x08; + ocp_write_word(tp, MCU_TYPE_PLA, 0xc0a2, ocp_data); + -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, 0xc0a6); -+ ocp_data &= ~0xfff; -+ ocp_data |= 0x0100; -+ ocp_write_word(tp, MCU_TYPE_PLA, 0xc0a6, ocp_data); -+ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, 0xc0a8); -+ ocp_data &= ~0xfff; -+ ocp_data |= 0x0200; -+ ocp_write_word(tp, MCU_TYPE_PLA, 0xc0a8, ocp_data); -+ -+ /* TX share fifo free credit full threshold */ -+ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_TXFIFO_CTRL, TXFIFO_THR_NORMAL2); -+ + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); -+ ocp_data &= ~BIT(14); ++ ocp_data &= ~PLA_MCU_SPDWN_EN; + ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data); + -+// ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xd32a); -+// ocp_data &= ~(BIT(8) | BIT(9)); -+// ocp_write_word(tp, MCU_TYPE_USB, 0xd32a, ocp_data); ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xd32a); ++ ocp_data &= ~(BIT(8) | BIT(9)); ++ ocp_write_word(tp, MCU_TYPE_USB, 0xd32a, ocp_data); + + ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, 0x00600400); - -- r8153_first_init(tp); -- ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, RX_THR_B); ++ + if (tp->saved_wolopts != __rtl_get_wol(tp)) { + netif_warn(tp, ifup, tp->netdev, "wol setting is changed\n"); + __rtl_set_wol(tp, tp->saved_wolopts); + } + -+ if (!work_busy(&tp->hw_phy_work.work)) { -+ r8153_aldps_en(tp, true); -+ r8153_u2p3en(tp, true); -+ } - -- r8153b_aldps_en(tp, true); -- r8153_u2p3en(tp, true); - r8153b_u1u2en(tp, true); - } - --static void rtl8153b_down(struct r8152 *tp) ++ r8153_aldps_en(tp, true); ++ r8153_u2p3en(tp, true); ++ ++ if (tp->udev->speed >= USB_SPEED_SUPER) ++ r8153b_u1u2en(tp, true); ++} ++ +static void rtl8156_down(struct r8152 *tp) - { ++{ + u32 ocp_data; + - if (test_bit(RTL8152_UNPLUG, &tp->flags)) { - rtl_drop_queued_tx(tp); - return; - } - ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) { ++ rtl_drop_queued_tx(tp); ++ return; ++ } ++ + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); -+ ocp_data |= BIT(14); ++ ocp_data |= PLA_MCU_SPDWN_EN; + ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data); + - r8153b_u1u2en(tp, false); - r8153_u2p3en(tp, false); - r8153b_power_cut_en(tp, false); -- r8153b_aldps_en(tp, false); -- r8153_enter_oob(tp); -- r8153b_aldps_en(tp, true); ++ r8153b_u1u2en(tp, false); ++ r8153_u2p3en(tp, false); ++ r8153b_power_cut_en(tp, false); + r8153_aldps_en(tp, false); + + ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); @@ -6575,11 +8250,10 @@ index 2490498b..26cc7c1a 100644 + ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); + + r8153_aldps_en(tp, true); -+ rtl_speed_down(tp); } static bool rtl8152_in_nway(struct r8152 *tp) -@@ -3802,7 +8191,7 @@ static void set_carrier(struct r8152 *tp) +@@ -3810,7 +9051,7 @@ static void set_carrier(struct r8152 *tp) { struct net_device *netdev = tp->netdev; struct napi_struct *napi = &tp->napi; @@ -6588,7 +8262,7 @@ index 2490498b..26cc7c1a 100644 speed = rtl8152_get_speed(tp); -@@ -3813,8 +8202,7 @@ static void set_carrier(struct r8152 *tp) +@@ -3821,8 +9062,7 @@ static void set_carrier(struct r8152 *tp) napi_disable(napi); netif_carrier_on(netdev); rtl_start_rx(tp); @@ -6598,7 +8272,7 @@ index 2490498b..26cc7c1a 100644 napi_enable(&tp->napi); netif_wake_queue(netdev); netif_info(tp, link, netdev, "carrier on\n"); -@@ -3825,18 +8213,18 @@ static void set_carrier(struct r8152 *tp) +@@ -3833,18 +9073,18 @@ static void set_carrier(struct r8152 *tp) } else { if (netif_carrier_ok(netdev)) { netif_carrier_off(netdev); @@ -6620,7 +8294,7 @@ index 2490498b..26cc7c1a 100644 /* If the device is unplugged or !netif_running(), the workqueue * doesn't need to wake the device, and could return directly. */ -@@ -3857,13 +8245,13 @@ static void rtl_work_func_t(struct work_struct *work) +@@ -3865,13 +9105,13 @@ static void rtl_work_func_t(struct work_struct *work) if (test_and_clear_bit(RTL8152_LINK_CHG, &tp->flags)) set_carrier(tp); @@ -6639,7 +8313,7 @@ index 2490498b..26cc7c1a 100644 mutex_unlock(&tp->control); -@@ -3871,10 +8259,8 @@ out1: +@@ -3879,10 +9119,8 @@ out1: usb_autopm_put_interface(tp->intf); } @@ -6651,7 +8325,7 @@ index 2490498b..26cc7c1a 100644 if (test_bit(RTL8152_UNPLUG, &tp->flags)) return; -@@ -3885,14 +8271,49 @@ static void rtl_hw_phy_work_func_t(struct work_struct *work) +@@ -3893,14 +9131,49 @@ static void rtl_hw_phy_work_func_t(struct work_struct *work) tp->rtl_ops.hw_phy_cfg(tp); @@ -6703,7 +8377,7 @@ index 2490498b..26cc7c1a 100644 static int rtl_notifier(struct notifier_block *nb, unsigned long action, void *data) { -@@ -3919,11 +8340,26 @@ static int rtl_notifier(struct notifier_block *nb, unsigned long action, +@@ -3927,11 +9200,31 @@ static int rtl_notifier(struct notifier_block *nb, unsigned long action, } #endif @@ -6726,11 +8400,16 @@ index 2490498b..26cc7c1a 100644 + if (unlikely(tp->rtk_enable_diag)) + return -EBUSY; ++ ++ if (work_busy(&tp->hw_phy_work.work) & WORK_BUSY_PENDING) { ++ cancel_delayed_work_sync(&tp->hw_phy_work); ++ __rtl_hw_phy_work_func(tp); ++ } + res = alloc_all_mem(tp); if (res) goto out; -@@ -3938,7 +8374,13 @@ static int rtl8152_open(struct net_device *netdev) +@@ -3946,7 +9239,13 @@ static int rtl8152_open(struct net_device *netdev) netif_carrier_off(netdev); netif_start_queue(netdev); @@ -6744,7 +8423,7 @@ index 2490498b..26cc7c1a 100644 res = usb_submit_urb(tp->intr_urb, GFP_KERNEL); if (res) { -@@ -3949,11 +8391,12 @@ static int rtl8152_open(struct net_device *netdev) +@@ -3957,11 +9256,12 @@ static int rtl8152_open(struct net_device *netdev) goto out_unlock; } napi_enable(&tp->napi); @@ -6758,7 +8437,7 @@ index 2490498b..26cc7c1a 100644 tp->pm_notifier.notifier_call = rtl_notifier; register_pm_notifier(&tp->pm_notifier); #endif -@@ -3973,16 +8416,23 @@ static int rtl8152_close(struct net_device *netdev) +@@ -3981,16 +9281,23 @@ static int rtl8152_close(struct net_device *netdev) struct r8152 *tp = netdev_priv(netdev); int res = 0; @@ -6769,12 +8448,12 @@ index 2490498b..26cc7c1a 100644 - if (!test_bit(RTL8152_UNPLUG, &tp->flags)) - napi_disable(&tp->napi); + tasklet_disable(&tp->tx_tl); -+ napi_disable(&tp->napi); + smp_mb__before_atomic(); clear_bit(WORK_ENABLE, &tp->flags); + smp_mb__after_atomic(); usb_kill_urb(tp->intr_urb); cancel_delayed_work_sync(&tp->schedule); ++ napi_disable(&tp->napi); netif_stop_queue(netdev); + if (unlikely(tp->rtk_enable_diag)) { @@ -6785,18 +8464,22 @@ index 2490498b..26cc7c1a 100644 res = usb_autopm_get_interface(tp->intf); if (res < 0 || test_bit(RTL8152_UNPLUG, &tp->flags)) { rtl_drop_queued_tx(tp); -@@ -3991,7 +8441,9 @@ static int rtl8152_close(struct net_device *netdev) - mutex_lock(&tp->control); +@@ -4000,6 +9307,14 @@ static int rtl8152_close(struct net_device *netdev) tp->rtl_ops.down(tp); -- -+#if defined(RTL8152_S5_WOL) && defined(CONFIG_PM) + ++ if (tp->version == RTL_VER_01) ++ rtl8152_set_speed(tp, AUTONEG_ENABLE, 0, 0, 3); ++ else ++ rtl_speed_down(tp); ++ ++#if defined(CONFIG_PM) + res = rtl_s5_wol(tp); +#endif mutex_unlock(&tp->control); usb_autopm_put_interface(tp->intf); -@@ -4019,6 +8471,18 @@ static void r8152b_init(struct r8152 *tp) +@@ -4027,6 +9342,18 @@ static void r8152b_init(struct r8152 *tp) if (test_bit(RTL8152_UNPLUG, &tp->flags)) return; @@ -6815,7 +8498,7 @@ index 2490498b..26cc7c1a 100644 data = r8152_mdio_read(tp, MII_BMCR); if (data & BMCR_PDOWN) { data &= ~BMCR_PDOWN; -@@ -4034,6 +8498,7 @@ static void r8152b_init(struct r8152 *tp) +@@ -4042,6 +9369,7 @@ static void r8152b_init(struct r8152 *tp) } r8152_power_cut_en(tp, false); @@ -6823,7 +8506,7 @@ index 2490498b..26cc7c1a 100644 ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR); ocp_data |= TX_10M_IDLE_EN | PFM_PWM_SWITCH; -@@ -4046,6 +8511,13 @@ static void r8152b_init(struct r8152 *tp) +@@ -4054,6 +9382,13 @@ static void r8152b_init(struct r8152 *tp) SPDWN_RXDV_MSK | SPDWN_LINKCHG_MSK; ocp_write_word(tp, MCU_TYPE_PLA, PLA_GPHY_INTR_IMR, ocp_data); @@ -6837,28 +8520,28 @@ index 2490498b..26cc7c1a 100644 rtl_tally_reset(tp); /* enable rx aggregation */ -@@ -4115,6 +8587,20 @@ static void r8153_init(struct r8152 *tp) +@@ -4123,6 +9458,20 @@ static void r8153_init(struct r8152 *tp) else ocp_data |= DYNAMIC_BURST; ocp_write_byte(tp, MCU_TYPE_USB, USB_CSR_DUMMY1, ocp_data); + + r8153_queue_wake(tp, false); + -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, 0xd398); ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS); + if (rtl8152_get_speed(tp) & LINK_STATUS) -+ ocp_data |= BIT(15); ++ ocp_data |= CUR_LINK_OK; + else -+ ocp_data &= ~BIT(15); ++ ocp_data &= ~CUR_LINK_OK; + + /* r8153_queue_wake() has set this bit */ + /* ocp_data &= ~BIT(8); */ + -+ ocp_data |= BIT(0); -+ ocp_write_word(tp, MCU_TYPE_PLA, 0xd398, ocp_data); ++ ocp_data |= POLL_LINK_CHG; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, ocp_data); } ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_CSR_DUMMY2); -@@ -4144,35 +8630,2193 @@ static void r8153_init(struct r8152 *tp) +@@ -4152,23 +9501,31 @@ static void r8153_init(struct r8152 *tp) ocp_write_word(tp, MCU_TYPE_USB, USB_CONNECT_TIMER, 0x0001); r8153_power_cut_en(tp, false); @@ -6867,106 +8550,78 @@ index 2490498b..26cc7c1a 100644 r8153_mac_clk_spd(tp, false); usb_enable_lpm(tp->udev); -+ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, 0xe90a); -+ ocp_data |= BIT(0); -+ ocp_write_byte(tp, MCU_TYPE_PLA, 0xe90a, ocp_data); ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6); ++ ocp_data |= LANWAKE_CLR_EN; ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6, ocp_data); + -+ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, 0xe007); -+ ocp_data &= ~BIT(7); -+ ocp_write_byte(tp, MCU_TYPE_PLA, 0xe007, ocp_data); ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_LWAKE_CTRL_REG); ++ ocp_data &= ~LANWAKE_PIN; ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_LWAKE_CTRL_REG, ocp_data); + /* rx aggregation */ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); - if (test_bit(DELL_TB_RX_AGG_BUG, &tp->flags)) - ocp_data |= RX_AGG_DISABLE; -+ ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); -+ -+ rtl_tally_reset(tp); -+ -+ switch (tp->udev->speed) { -+ case USB_SPEED_SUPER: -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0) -+ case USB_SPEED_SUPER_PLUS: -+#endif -+ tp->coalesce = COALESCE_SUPER; -+ break; -+ case USB_SPEED_HIGH: -+ tp->coalesce = COALESCE_HIGH; -+ break; -+ default: -+ tp->coalesce = COALESCE_SLOW; -+ break; -+ } -+} -+ -+static void r8153b_init(struct r8152 *tp) -+{ -+ u32 ocp_data; -+ u16 data; -+ int i; -+ -+ if (test_bit(RTL8152_UNPLUG, &tp->flags)) -+ return; -+ -+ r8153b_u1u2en(tp, false); +- + ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); -+ for (i = 0; i < 500; i++) { -+ if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & -+ AUTOLOAD_DONE) -+ break; -+ msleep(20); -+ } -+ -+ data = r8153_phy_status(tp, 0); -+ -+ data = r8152_mdio_read(tp, MII_BMCR); -+ if (data & BMCR_PDOWN) { -+ data &= ~BMCR_PDOWN; -+ r8152_mdio_write(tp, MII_BMCR, data); -+ } -+ -+ data = r8153_phy_status(tp, PHY_STAT_LAN_ON); -+ -+ r8153_u2p3en(tp, false); -+ -+ /* MSC timer = 0xfff * 8ms = 32760 ms */ -+ ocp_write_word(tp, MCU_TYPE_USB, USB_MSC_TIMER, 0x0fff); -+ -+ r8153b_power_cut_en(tp, false); -+ r8153b_ups_en(tp, false); + rtl_tally_reset(tp); + + switch (tp->udev->speed) { + case USB_SPEED_SUPER: ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0) + case USB_SPEED_SUPER_PLUS: ++#endif + tp->coalesce = COALESCE_SUPER; + break; + case USB_SPEED_HIGH: +@@ -4213,14 +9570,30 @@ static void r8153b_init(struct r8152 *tp) + /* MSC timer = 0xfff * 8ms = 32760 ms */ + ocp_write_word(tp, MCU_TYPE_USB, USB_MSC_TIMER, 0x0fff); + +- /* U1/U2/L1 idle timer. 500 us */ +- ocp_write_word(tp, MCU_TYPE_USB, USB_U1U2_TIMER, 500); +- + r8153b_power_cut_en(tp, false); + r8153b_ups_en(tp, false); +- r8153b_queue_wake(tp, false); + r8153_queue_wake(tp, false); -+ rtl_runtime_suspend_enable(tp, false); + rtl_runtime_suspend_enable(tp, false); +- r8153b_u1u2en(tp, true); + -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, 0xd398); ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS); + if (rtl8152_get_speed(tp) & LINK_STATUS) -+ ocp_data |= BIT(15); ++ ocp_data |= CUR_LINK_OK; + else -+ ocp_data &= ~BIT(15); ++ ocp_data &= ~CUR_LINK_OK; + + /* r8153_queue_wake() has set this bit */ + /* ocp_data &= ~BIT(8); */ + -+ ocp_data |= BIT(0); -+ ocp_write_word(tp, MCU_TYPE_PLA, 0xd398, ocp_data); ++ ocp_data |= POLL_LINK_CHG; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, ocp_data); + + if (tp->udev->descriptor.idVendor == VENDOR_ID_LENOVO && + tp->udev->descriptor.idProduct == 0x3069) + ocp_write_word(tp, MCU_TYPE_USB, USB_SSPHYLINK2, 0x0c8c); + -+ r8153b_u1u2en(tp, true); -+ usb_enable_lpm(tp->udev); -+ -+ /* MAC clock speed down */ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2); -+ ocp_data |= MAC_CLK_SPDWN_EN; -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, ocp_data); ++ if (tp->udev->speed >= USB_SPEED_SUPER) ++ r8153b_u1u2en(tp, true); + + usb_enable_lpm(tp->udev); + + /* MAC clock speed down */ +@@ -4228,6 +9601,19 @@ static void r8153b_init(struct r8152 *tp) + ocp_data |= MAC_CLK_SPDWN_EN; + ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, ocp_data); + + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); -+ ocp_data &= ~BIT(14); ++ ocp_data &= ~PLA_MCU_SPDWN_EN; + ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data); + + if (tp->version == RTL_VER_09) { ++ /* Disable Test IO for 32QFN */ + if (ocp_read_byte(tp, MCU_TYPE_PLA, 0xdc00) & BIT(5)) { + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR); + ocp_data |= TEST_IO_OFF; @@ -6974,21 +8629,26 @@ index 2490498b..26cc7c1a 100644 + } + } + -+ set_bit(GREEN_ETHERNET, &tp->flags); -+ -+ /* rx aggregation */ -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); -+ ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); + set_bit(GREEN_ETHERNET, &tp->flags); + + /* rx aggregation */ +@@ -4235,940 +9621,8780 @@ static void r8153b_init(struct r8152 *tp) + ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); -- rtl_tally_reset(tp); -+ rtl_tally_reset(tp); -+ -+ tp->coalesce = 15000; /* 15 us */ -+} -+ +- /* set customized led */ +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_LEDSEL, ledsel); +- + rtl_tally_reset(tp); + + tp->coalesce = 15000; /* 15 us */ + } + +-static int rtl8152_pre_reset(struct usb_interface *intf) +static void r8156_patch_code(struct r8152 *tp) -+{ + { +- struct r8152 *tp = usb_get_intfdata(intf); +- struct net_device *netdev; + if (tp->version == RTL_TEST_01) { + static u8 usb3_patch_t[] = { + 0x01, 0xe0, 0x05, 0xc7, @@ -6996,7 +8656,7 @@ index 2490498b..26cc7c1a 100644 + 0x00, 0xb8, 0x40, 0x03, + 0x00, 0xd4, 0x00, 0x00 }; + -+ r8153b_clear_bp(tp, MCU_TYPE_USB); ++ rtl_clear_bp(tp, MCU_TYPE_USB); + + generic_ocp_write(tp, 0xe600, 0xff, sizeof(usb3_patch_t), + usb3_patch_t, MCU_TYPE_USB); @@ -7143,7 +8803,7 @@ index 2490498b..26cc7c1a 100644 + 0x6c, 0xe8, 0x20, 0xe8, + 0x00, 0xa0, 0x38, 0xe4}; + -+ r8153b_clear_bp(tp, MCU_TYPE_USB); ++ rtl_clear_bp(tp, MCU_TYPE_USB); + + generic_ocp_write(tp, 0xe600, 0xff, sizeof(usb_patch3_b), + usb_patch3_b, MCU_TYPE_USB); @@ -7168,14 +8828,14 @@ index 2490498b..26cc7c1a 100644 + ocp_write_word(tp, MCU_TYPE_USB, USB_BP2_EN, 0x001f); + ocp_write_byte(tp, MCU_TYPE_USB, 0xcfd7, 0x03); + -+ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xcfcc); -+ ocp_data &= ~BIT(9); -+ ocp_write_word(tp, MCU_TYPE_USB, 0xcfcc, ocp_data); ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN1); ++ ocp_data |= FW_IP_RESET_EN; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN1, ocp_data); + + ocp_write_dword(tp, MCU_TYPE_USB, 0xd480, 0x4026840e); + ocp_write_dword(tp, MCU_TYPE_USB, 0xd480, 0x4001acc9); + -+ r8153b_clear_bp(tp, MCU_TYPE_PLA); ++ rtl_clear_bp(tp, MCU_TYPE_PLA); + + generic_ocp_write(tp, 0xf800, 0xff, sizeof(pla_patch11), + pla_patch11, MCU_TYPE_PLA); @@ -7191,15 +8851,1202 @@ index 2490498b..26cc7c1a 100644 + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_7, 0x0000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, 0x0003); + ocp_write_byte(tp, MCU_TYPE_USB, 0xcfd6, 0x02); ++ } else if (tp->version == RTL_VER_12) { ++ static u8 usb_patch4_a[] = { ++ 0x10, 0xe0, 0x38, 0xe0, ++ 0x4e, 0xe0, 0x8b, 0xe0, ++ 0xc1, 0xe0, 0xcd, 0xe0, ++ 0xd5, 0xe0, 0xed, 0xe0, ++ 0xf9, 0xe0, 0xfb, 0xe0, ++ 0xfd, 0xe0, 0xff, 0xe0, ++ 0x01, 0xe1, 0x03, 0xe1, ++ 0x05, 0xe1, 0x07, 0xe1, ++ 0x22, 0xc2, 0x4a, 0x41, ++ 0x91, 0x20, 0x20, 0xc0, ++ 0x16, 0x00, 0x00, 0x73, ++ 0x1e, 0xc4, 0x5c, 0x41, ++ 0x8b, 0x41, 0x1a, 0xc0, ++ 0x1a, 0x00, 0x00, 0x73, ++ 0xbd, 0x48, 0x0d, 0x18, ++ 0x17, 0xc6, 0xc0, 0x88, ++ 0xc1, 0x9b, 0x15, 0xe8, ++ 0x0b, 0x18, 0x12, 0xc6, ++ 0xc0, 0x88, 0xc1, 0x99, ++ 0x10, 0xe8, 0x0c, 0xc0, ++ 0x1c, 0x00, 0x00, 0x73, ++ 0x0e, 0x18, 0x0a, 0xc6, ++ 0xc0, 0x88, 0xc1, 0x9b, ++ 0x08, 0xe8, 0x02, 0xc6, ++ 0x00, 0xbe, 0x10, 0x12, ++ 0xf0, 0x00, 0x90, 0xc7, ++ 0x1f, 0xfe, 0x8f, 0xcb, ++ 0x02, 0xc6, 0x00, 0xbe, ++ 0x66, 0x3f, 0x11, 0x21, ++ 0x2b, 0x25, 0x13, 0xc4, ++ 0xa2, 0x41, 0x80, 0x63, ++ 0xf5, 0xc0, 0x48, 0x00, ++ 0xbb, 0x21, 0xb9, 0x25, ++ 0x00, 0x71, 0x0c, 0xc2, ++ 0x4a, 0x41, 0x8b, 0x41, ++ 0x24, 0x18, 0xee, 0xc6, ++ 0xc0, 0x88, 0xc1, 0x99, ++ 0xec, 0xef, 0x02, 0xc6, ++ 0x00, 0xbe, 0x8a, 0x12, ++ 0xa0, 0xf9, 0x83, 0xff, ++ 0xd4, 0x18, 0x20, 0x88, ++ 0x36, 0xe8, 0x22, 0x60, ++ 0x85, 0x48, 0x06, 0x48, ++ 0x21, 0x88, 0xf4, 0x18, ++ 0x20, 0x88, 0x32, 0xe8, ++ 0x2d, 0xc3, 0xc0, 0x18, ++ 0x20, 0x88, 0x2b, 0xe8, ++ 0x22, 0x60, 0x60, 0x88, ++ 0xc1, 0x18, 0x20, 0x88, ++ 0x26, 0xe8, 0x22, 0x60, ++ 0x61, 0x88, 0xc2, 0x18, ++ 0x20, 0x88, 0x21, 0xe8, ++ 0x22, 0x60, 0x62, 0x88, ++ 0xc3, 0x18, 0x20, 0x88, ++ 0x1c, 0xe8, 0x22, 0x60, ++ 0x63, 0x88, 0xc4, 0x18, ++ 0x20, 0x88, 0x17, 0xe8, ++ 0x22, 0x60, 0x64, 0x88, ++ 0xc5, 0x18, 0x20, 0x88, ++ 0x12, 0xe8, 0x22, 0x60, ++ 0x65, 0x88, 0xc6, 0x18, ++ 0x20, 0x88, 0x0d, 0xe8, ++ 0x22, 0x60, 0x66, 0x88, ++ 0xc7, 0x18, 0x20, 0x88, ++ 0x08, 0xe8, 0x22, 0x60, ++ 0x67, 0x88, 0xd4, 0x18, ++ 0x02, 0xc5, 0x00, 0xbd, ++ 0xc2, 0x35, 0xc0, 0xd3, ++ 0x02, 0xc5, 0x00, 0xbd, ++ 0xb2, 0x3e, 0x02, 0xc5, ++ 0x00, 0xbd, 0x08, 0x3f, ++ 0xd4, 0x18, 0xc0, 0x88, ++ 0xf8, 0xef, 0xc2, 0x60, ++ 0x85, 0x48, 0x06, 0x48, ++ 0xc1, 0x88, 0xf4, 0x18, ++ 0xc0, 0x88, 0xf4, 0xef, ++ 0xef, 0xc3, 0x60, 0x60, ++ 0xc1, 0x88, 0xe0, 0x18, ++ 0xc0, 0x88, 0xee, 0xef, ++ 0x61, 0x60, 0xc1, 0x88, ++ 0xe1, 0x18, 0xc0, 0x88, ++ 0xe9, 0xef, 0x62, 0x60, ++ 0xc1, 0x88, 0xe2, 0x18, ++ 0xc0, 0x88, 0xe4, 0xef, ++ 0x63, 0x60, 0xc1, 0x88, ++ 0xe3, 0x18, 0xc0, 0x88, ++ 0xdf, 0xef, 0x64, 0x60, ++ 0xc1, 0x88, 0xe4, 0x18, ++ 0xc0, 0x88, 0xda, 0xef, ++ 0x65, 0x60, 0xc1, 0x88, ++ 0xe5, 0x18, 0xc0, 0x88, ++ 0xd5, 0xef, 0x66, 0x60, ++ 0xc1, 0x88, 0xe6, 0x18, ++ 0xc0, 0x88, 0xd0, 0xef, ++ 0x67, 0x60, 0xc1, 0x88, ++ 0xe7, 0x18, 0xc0, 0x88, ++ 0xcb, 0xef, 0xd4, 0x18, ++ 0x02, 0xc2, 0x00, 0xba, ++ 0x3a, 0x15, 0x0b, 0xc6, ++ 0xc7, 0x65, 0xd0, 0x49, ++ 0x05, 0xf1, 0x08, 0xc0, ++ 0x02, 0xc6, 0x00, 0xbe, ++ 0x50, 0x2f, 0x02, 0xc7, ++ 0x00, 0xbf, 0x56, 0x2f, ++ 0x20, 0xd4, 0x00, 0xd4, ++ 0x08, 0xc3, 0x60, 0x60, ++ 0x03, 0x48, 0x60, 0x88, ++ 0x00, 0x1b, 0x02, 0xc6, ++ 0x00, 0xbe, 0xda, 0x2c, ++ 0x60, 0xb4, 0x17, 0xc1, ++ 0x17, 0xc2, 0x4c, 0x99, ++ 0x00, 0x19, 0x4e, 0x89, ++ 0x4f, 0x61, 0x97, 0x49, ++ 0xfe, 0xf1, 0x48, 0x61, ++ 0x01, 0xb4, 0x16, 0x48, ++ 0x17, 0x48, 0x48, 0x89, ++ 0x0a, 0xc1, 0x4c, 0x99, ++ 0x81, 0x19, 0x4e, 0x89, ++ 0x4f, 0x61, 0x97, 0x49, ++ 0xfe, 0xf1, 0x02, 0xc0, ++ 0x00, 0xb8, 0x32, 0x7c, ++ 0x1c, 0xe8, 0x00, 0xdc, ++ 0x01, 0xb0, 0xfe, 0xc2, ++ 0x48, 0x89, 0xfb, 0xc1, ++ 0x4c, 0x99, 0x81, 0x19, ++ 0x4e, 0x89, 0x4f, 0x61, ++ 0x97, 0x49, 0xfe, 0xf1, ++ 0x02, 0xc0, 0x00, 0xb8, ++ 0x96, 0x7c, 0x02, 0xc0, ++ 0x00, 0xb8, 0x00, 0x00, ++ 0x02, 0xc0, 0x00, 0xb8, ++ 0x00, 0x00, 0x02, 0xc0, ++ 0x00, 0xb8, 0x00, 0x00, ++ 0x02, 0xc0, 0x00, 0xb8, ++ 0x00, 0x00, 0x02, 0xc0, ++ 0x00, 0xb8, 0x00, 0x00, ++ 0x02, 0xc0, 0x00, 0xb8, ++ 0x00, 0x00, 0x02, 0xc0, ++ 0x00, 0xb8, 0x00, 0x00, ++ 0x02, 0xc0, 0x00, 0xb8, ++ 0x00, 0x00, 0x00, 0x00}; ++ static u8 pla_patch4_a[] = { ++ 0x08, 0xe0, 0x0c, 0xe0, ++ 0x10, 0xe0, 0x3e, 0xe0, ++ 0x40, 0xe0, 0x42, 0xe0, ++ 0x44, 0xe0, 0x46, 0xe0, ++ 0x03, 0xb4, 0x02, 0xb4, ++ 0x02, 0xc7, 0x00, 0xbf, ++ 0xb4, 0x03, 0x02, 0xb0, ++ 0x03, 0xb0, 0x02, 0xc6, ++ 0x00, 0xbe, 0x8c, 0x05, ++ 0xaf, 0x49, 0x17, 0xf1, ++ 0x20, 0xc6, 0x00, 0x1a, ++ 0x23, 0xe8, 0x21, 0xc6, ++ 0xc0, 0x61, 0x91, 0x49, ++ 0x0c, 0xf0, 0x95, 0x49, ++ 0x0a, 0xf1, 0x14, 0x48, ++ 0x16, 0xc6, 0x81, 0x1a, ++ 0x19, 0xe8, 0x14, 0xc6, ++ 0xc0, 0x62, 0x24, 0x48, ++ 0xc0, 0x8a, 0x0c, 0xe0, ++ 0x10, 0xc6, 0xc0, 0x62, ++ 0xa5, 0x49, 0x08, 0xf1, ++ 0x0d, 0xc6, 0xc0, 0x62, ++ 0xa0, 0x48, 0xc0, 0x8a, ++ 0xc2, 0x62, 0xa3, 0x48, ++ 0xc2, 0x8a, 0x02, 0xc6, ++ 0x00, 0xbe, 0xd2, 0x16, ++ 0x84, 0xd2, 0x6a, 0xdc, ++ 0x90, 0xd3, 0x66, 0xb4, ++ 0x08, 0xea, 0xff, 0xc0, ++ 0x04, 0x9e, 0x00, 0x99, ++ 0x06, 0x8a, 0x06, 0x72, ++ 0xaf, 0x49, 0xfe, 0xf1, ++ 0x80, 0xff, 0x02, 0xc6, ++ 0x00, 0xbe, 0x00, 0x00, ++ 0x02, 0xc6, 0x00, 0xbe, ++ 0x00, 0x00, 0x02, 0xc6, ++ 0x00, 0xbe, 0x00, 0x00, ++ 0x02, 0xc6, 0x00, 0xbe, ++ 0x00, 0x00, 0x02, 0xc6, ++ 0x00, 0xbe, 0x00, 0x00}; ++ ++ rtl_clear_bp(tp, MCU_TYPE_USB); ++ ++ generic_ocp_write(tp, 0xe600, 0xff, sizeof(usb_patch4_a), ++ usb_patch4_a, MCU_TYPE_USB); ++ ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_BA, 0xc000); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_0, 0x11e2); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_1, 0x1268); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_2, 0x35c0); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_3, 0x1538); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_4, 0x2f4e); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_5, 0x2cd8); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_6, 0x7c26); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_7, 0x7c90); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_8, 0x0000); ++// ocp_write_word(tp, MCU_TYPE_USB, USB_BP_9, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_10, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_11, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_12, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_13, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_14, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_15, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP2_EN, 0x00df); ++ ocp_write_byte(tp, MCU_TYPE_USB, 0xcfd7, 0x02); ++ ++// ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN1); ++// ocp_data |= FW_IP_RESET_EN; ++// ocp_write_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN1, ocp_data); ++ ++// ocp_write_dword(tp, MCU_TYPE_USB, 0xd480, 0x4026840e); ++// ocp_write_dword(tp, MCU_TYPE_USB, 0xd480, 0x4001acc9); ++ ++ rtl_clear_bp(tp, MCU_TYPE_PLA); ++ ++ generic_ocp_write(tp, 0xf800, 0xff, sizeof(pla_patch4_a), ++ pla_patch4_a, MCU_TYPE_PLA); ++ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_BA, 0x8000); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_0, 0x03b2); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_1, 0x058a); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_2, 0x16c0); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_3, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_4, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_5, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_6, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_7, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, 0x0007); ++ ocp_write_byte(tp, MCU_TYPE_USB, 0xcfd6, 0x02); ++ } else if (tp->version == RTL_VER_13) { ++ static u8 usb_patch_13[] = { ++ 0x10, 0xe0, 0x25, 0xe0, ++ 0x29, 0xe0, 0x2d, 0xe0, ++ 0x52, 0xe0, 0xff, 0xe0, ++ 0x02, 0xe1, 0x0b, 0xe1, ++ 0x0d, 0xe1, 0x0f, 0xe1, ++ 0x11, 0xe1, 0x13, 0xe1, ++ 0x15, 0xe1, 0x17, 0xe1, ++ 0x19, 0xe1, 0x1b, 0xe1, ++ 0x13, 0xc3, 0x60, 0x70, ++ 0x8b, 0x49, 0x0d, 0xf1, ++ 0x10, 0xc3, 0x60, 0x60, ++ 0x85, 0x49, 0x09, 0xf1, ++ 0x40, 0x03, 0x64, 0x60, ++ 0x82, 0x49, 0x05, 0xf1, ++ 0x09, 0xc3, 0x60, 0x60, ++ 0x80, 0x48, 0x60, 0x88, ++ 0x02, 0xc0, 0x00, 0xb8, ++ 0xde, 0x0f, 0xca, 0xcf, ++ 0x00, 0xd8, 0x1e, 0xb4, ++ 0x04, 0xc3, 0x02, 0xc0, ++ 0x00, 0xb8, 0x62, 0x36, ++ 0xc8, 0xd3, 0x04, 0xc3, ++ 0x02, 0xc0, 0x00, 0xb8, ++ 0x7a, 0x14, 0xc8, 0xd3, ++ 0x00, 0xb4, 0x01, 0xb4, ++ 0x02, 0xb4, 0x03, 0xb4, ++ 0x1f, 0xc1, 0x02, 0x1b, ++ 0x2c, 0x8b, 0x0c, 0x62, ++ 0xa7, 0x49, 0x0a, 0xf1, ++ 0x00, 0x1b, 0x08, 0x72, ++ 0x13, 0x40, 0x04, 0xf1, ++ 0x0a, 0x72, 0x13, 0x40, ++ 0x03, 0xf0, 0x01, 0x1b, ++ 0x2c, 0x8b, 0x12, 0xc0, ++ 0x01, 0x1a, 0x08, 0x8a, ++ 0x0a, 0x8a, 0x0d, 0xc0, ++ 0x12, 0x71, 0x19, 0x48, ++ 0x1a, 0x48, 0x12, 0x99, ++ 0x03, 0xb0, 0x02, 0xb0, ++ 0x01, 0xb0, 0x00, 0xb0, ++ 0x02, 0xc0, 0x00, 0xb8, ++ 0xb0, 0x77, 0x20, 0xc3, ++ 0x18, 0xb4, 0x80, 0xcb, ++ 0x00, 0xb4, 0x01, 0xb4, ++ 0x02, 0xb4, 0x03, 0xb4, ++ 0x07, 0xb4, 0x23, 0xc0, ++ 0x24, 0xc1, 0x08, 0x1a, ++ 0x2a, 0x8a, 0x24, 0x01, ++ 0x0d, 0x1a, 0x20, 0x9a, ++ 0x24, 0x09, 0x00, 0x1a, ++ 0x22, 0x9a, 0x04, 0x72, ++ 0x06, 0x73, 0x18, 0xc7, ++ 0xe4, 0x9a, 0xe6, 0x9b, ++ 0x17, 0xc2, 0x17, 0xc3, ++ 0xe0, 0x9a, 0xe2, 0x9b, ++ 0x80, 0x1b, 0x32, 0x8b, ++ 0x00, 0x1a, 0x24, 0x9f, ++ 0x26, 0x9a, 0x01, 0x1a, ++ 0x28, 0x8a, 0x0f, 0xe8, ++ 0x07, 0xb0, 0x03, 0xb0, ++ 0x02, 0xb0, 0x01, 0xb0, ++ 0x00, 0xb0, 0x02, 0xc6, ++ 0x00, 0xbe, 0xe6, 0x60, ++ 0x00, 0xc3, 0x20, 0xc3, ++ 0x80, 0xcb, 0x55, 0x53, ++ 0x42, 0x53, 0x80, 0xcb, ++ 0x03, 0xb4, 0x06, 0xb4, ++ 0x07, 0xb4, 0xfc, 0xc7, ++ 0x79, 0xc7, 0xe0, 0x73, ++ 0xba, 0x49, 0x0d, 0xf0, ++ 0xf7, 0xc6, 0x24, 0x06, ++ 0xc0, 0x77, 0xfa, 0x25, ++ 0x76, 0x23, 0x66, 0x27, ++ 0x70, 0xc7, 0xe1, 0x9e, ++ 0x00, 0x16, 0x10, 0xf0, ++ 0x01, 0x03, 0x0e, 0xe0, ++ 0xb9, 0x49, 0x10, 0xf0, ++ 0xe9, 0xc6, 0x24, 0x06, ++ 0xc0, 0x77, 0xf9, 0x25, ++ 0x77, 0x23, 0x67, 0x27, ++ 0x62, 0xc7, 0xe1, 0x9e, ++ 0x00, 0x16, 0x02, 0xf0, ++ 0x01, 0x03, 0x5e, 0xc7, ++ 0xe0, 0x8b, 0x12, 0xe8, ++ 0x0d, 0xe0, 0xda, 0xc6, ++ 0x24, 0x06, 0xc0, 0x77, ++ 0xf6, 0x25, 0x7a, 0x23, ++ 0x6a, 0x27, 0x53, 0xc7, ++ 0xe1, 0x9e, 0x00, 0x16, ++ 0xf3, 0xf0, 0x01, 0x03, ++ 0xf1, 0xe7, 0x07, 0xb0, ++ 0x06, 0xb0, 0x03, 0xb0, ++ 0x80, 0xff, 0x03, 0xb4, ++ 0x06, 0xb4, 0x07, 0xb4, ++ 0xc7, 0xc6, 0xc4, 0x77, ++ 0x40, 0xc3, 0x7c, 0x9f, ++ 0x41, 0xc6, 0xc0, 0x73, ++ 0xba, 0x49, 0x05, 0xf1, ++ 0x00, 0x13, 0x05, 0xf1, ++ 0x39, 0xc3, 0x04, 0xe0, ++ 0x38, 0xc3, 0x02, 0xe0, ++ 0x40, 0x1b, 0xb8, 0xc6, ++ 0xfb, 0x31, 0xc4, 0x9f, ++ 0x35, 0xc6, 0xc0, 0x67, ++ 0x01, 0x17, 0x07, 0xfc, ++ 0x30, 0xc6, 0xc1, 0x77, ++ 0x01, 0x1b, 0xc0, 0x8b, ++ 0x00, 0x17, 0x0c, 0xf1, ++ 0x29, 0xc6, 0xc0, 0x73, ++ 0xba, 0x49, 0x05, 0xf1, ++ 0xb9, 0x49, 0x05, 0xf0, ++ 0x21, 0xc7, 0x04, 0xe0, ++ 0x20, 0xc7, 0x02, 0xe0, ++ 0x40, 0x1f, 0x1a, 0xc6, ++ 0x7e, 0x41, 0x1d, 0xc6, ++ 0xc0, 0x63, 0xbb, 0x21, ++ 0xbb, 0x41, 0x15, 0xc3, ++ 0x66, 0x9f, 0x18, 0xc6, ++ 0xc0, 0x67, 0xf9, 0x3b, ++ 0xc0, 0x8f, 0x01, 0x17, ++ 0x03, 0xfd, 0x00, 0x1f, ++ 0x02, 0xe0, 0x01, 0x1f, ++ 0x0e, 0xc6, 0xc0, 0x8f, ++ 0x08, 0xc3, 0x04, 0x1e, ++ 0x60, 0x8e, 0x07, 0xb0, ++ 0x06, 0xb0, 0x03, 0xb0, ++ 0x80, 0xff, 0xff, 0x07, ++ 0x40, 0xd4, 0x00, 0x02, ++ 0x00, 0x04, 0x80, 0xb9, ++ 0xfd, 0xcb, 0xa2, 0xcb, ++ 0xe8, 0x74, 0x02, 0xc5, ++ 0x00, 0xbd, 0x96, 0x6d, ++ 0x08, 0xc7, 0xe0, 0x71, ++ 0x9e, 0x48, 0xe0, 0x99, ++ 0x05, 0xc7, 0x02, 0xc1, ++ 0x00, 0xb9, 0x24, 0x3f, ++ 0x00, 0xcf, 0x00, 0xd8, ++ 0x02, 0xc0, 0x00, 0xb8, ++ 0x3a, 0x4e, 0x02, 0xc0, ++ 0x00, 0xb8, 0x00, 0x00, ++ 0x02, 0xc0, 0x00, 0xb8, ++ 0x00, 0x00, 0x02, 0xc0, ++ 0x00, 0xb8, 0x00, 0x00, ++ 0x02, 0xc0, 0x00, 0xb8, ++ 0x00, 0x00, 0x02, 0xc0, ++ 0x00, 0xb8, 0x00, 0x00, ++ 0x02, 0xc0, 0x00, 0xb8, ++ 0x00, 0x00, 0x02, 0xc0, ++ 0x00, 0xb8, 0x00, 0x00, ++ 0x02, 0xc0, 0x00, 0xb8, ++ 0x00, 0x00, 0x00, 0x00}; ++ static u8 pla_patch_13[] = { ++ 0x10, 0xe0, 0x1c, 0xe0, ++ 0x20, 0xe0, 0x22, 0xe0, ++ 0x24, 0xe0, 0x26, 0xe0, ++ 0x28, 0xe0, 0x2a, 0xe0, ++ 0x2c, 0xe0, 0x2e, 0xe0, ++ 0x30, 0xe0, 0x32, 0xe0, ++ 0x34, 0xe0, 0x36, 0xe0, ++ 0x38, 0xe0, 0x3a, 0xe0, ++ 0x0c, 0xc4, 0x04, 0x40, ++ 0x05, 0xf0, 0x8c, 0x26, ++ 0x0b, 0x15, 0x02, 0xf0, ++ 0x03, 0xe0, 0x00, 0x9a, ++ 0x01, 0xe0, 0x02, 0xc4, ++ 0x00, 0xbc, 0x36, 0x37, ++ 0x6c, 0xe8, 0x3a, 0x73, ++ 0xbb, 0x49, 0x02, 0xc6, ++ 0x00, 0xbe, 0xde, 0x27, ++ 0x02, 0xc0, 0x00, 0xb8, ++ 0x3a, 0x4e, 0x02, 0xc0, ++ 0x00, 0xb8, 0x3a, 0x4e, ++ 0x02, 0xc0, 0x00, 0xb8, ++ 0x3a, 0x4e, 0x02, 0xc0, ++ 0x00, 0xb8, 0x3a, 0x4e, ++ 0x02, 0xc0, 0x00, 0xb8, ++ 0x3a, 0x4e, 0x02, 0xc0, ++ 0x00, 0xb8, 0x3a, 0x4e, ++ 0x02, 0xc0, 0x00, 0xb8, ++ 0x00, 0x00, 0x02, 0xc0, ++ 0x00, 0xb8, 0x00, 0x00, ++ 0x02, 0xc0, 0x00, 0xb8, ++ 0x00, 0x00, 0x02, 0xc0, ++ 0x00, 0xb8, 0x00, 0x00, ++ 0x02, 0xc0, 0x00, 0xb8, ++ 0x00, 0x00, 0x02, 0xc0, ++ 0x00, 0xb8, 0x00, 0x00, ++ 0x02, 0xc0, 0x00, 0xb8, ++ 0x00, 0x00, 0x02, 0xc0, ++ 0x00, 0xb8, 0x00, 0x00}; ++ ++ rtl_clear_bp(tp, MCU_TYPE_USB); ++ ++ generic_ocp_write(tp, 0xe600, 0xff, sizeof(usb_patch_13), ++ usb_patch_13, MCU_TYPE_USB); ++ ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_BA, 0xc000); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_0, 0x0fba); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_1, 0x3660); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_2, 0x1478); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_3, 0x77ae); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_4, 0x60e0); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_5, 0x6d94); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_6, 0x3f22); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_7, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_8, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_9, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_10, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_11, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_12, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_13, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_14, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP_15, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_BP2_EN, 0x007f); ++ ocp_write_byte(tp, MCU_TYPE_USB, 0xcfd7, 0x02); ++ ++ rtl_clear_bp(tp, MCU_TYPE_PLA); ++ ++ generic_ocp_write(tp, 0xf800, 0xff, sizeof(pla_patch_13), ++ pla_patch_13, MCU_TYPE_PLA); ++ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_BA, 0x8000); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_0, 0x374e); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_1, 0x27dc); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_2, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_3, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_4, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_5, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_6, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_7, 0x0000); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, 0x0003); ++ ocp_write_byte(tp, MCU_TYPE_USB, 0xcfd6, 0x02); + } +} + +- if (!tp) +- return 0; ++static void rtl_ram_code_speed_up(struct r8152 *tp) ++{ ++ u32 ocp_data, len = 0; ++ u8 *data = NULL; + -+static void r8156_ram_code(struct r8152 *tp) ++ if (tp->version == RTL_VER_13) { ++ static u8 ram13[] = { ++ 0x6c, 0xe8, 0x00, 0xa0, ++ 0x36, 0xb4, 0x24, 0x80, ++ 0x38, 0xb4, 0x01, 0x37, ++ 0x36, 0xb4, 0x2e, 0xb8, ++ 0x38, 0xb4, 0x01, 0x00, ++ 0x6c, 0xe8, 0x00, 0xb0, ++ 0x20, 0xb8, 0x90, 0x00, ++ 0x6c, 0xe8, 0x00, 0xa0, ++ 0x36, 0xb4, 0x16, 0xa0, ++ 0x38, 0xb4, 0x00, 0x00, ++ 0x36, 0xb4, 0x12, 0xa0, ++ 0x38, 0xb4, 0x00, 0x00, ++ 0x36, 0xb4, 0x14, 0xa0, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x10, 0x80, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x1a, 0x80, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x24, 0x80, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x2f, 0x80, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x50, 0x80, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x50, 0x80, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x50, 0x80, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x50, 0x80, ++ 0x38, 0xb4, 0x93, 0xd0, ++ 0x38, 0xb4, 0xc4, 0xd1, ++ 0x38, 0xb4, 0x00, 0x10, ++ 0x38, 0xb4, 0x5c, 0x13, ++ 0x38, 0xb4, 0x04, 0xd7, ++ 0x38, 0xb4, 0xbc, 0x5f, ++ 0x38, 0xb4, 0x04, 0xd5, ++ 0x38, 0xb4, 0xf1, 0xc9, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0xc9, 0x0f, ++ 0x38, 0xb4, 0x50, 0xbb, ++ 0x38, 0xb4, 0x05, 0xd5, ++ 0x38, 0xb4, 0x02, 0xa2, ++ 0x38, 0xb4, 0x04, 0xd5, ++ 0x38, 0xb4, 0x0f, 0x8c, ++ 0x38, 0xb4, 0x00, 0xd5, ++ 0x38, 0xb4, 0x00, 0x10, ++ 0x38, 0xb4, 0x19, 0x15, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x48, 0x15, ++ 0x38, 0xb4, 0x70, 0x2f, ++ 0x38, 0xb4, 0x2a, 0x80, ++ 0x38, 0xb4, 0x73, 0x2f, ++ 0x38, 0xb4, 0x6a, 0x15, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x5c, 0x15, ++ 0x38, 0xb4, 0x05, 0xd5, ++ 0x38, 0xb4, 0x02, 0xa2, ++ 0x38, 0xb4, 0x00, 0xd5, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x51, 0x15, ++ 0x38, 0xb4, 0xc1, 0xc0, ++ 0x38, 0xb4, 0xc0, 0xc0, ++ 0x38, 0xb4, 0x5a, 0xd0, ++ 0x38, 0xb4, 0xba, 0xd1, ++ 0x38, 0xb4, 0x01, 0xd7, ++ 0x38, 0xb4, 0x29, 0x25, ++ 0x38, 0xb4, 0x2a, 0x02, ++ 0x38, 0xb4, 0xa7, 0xd0, ++ 0x38, 0xb4, 0xb9, 0xd1, ++ 0x38, 0xb4, 0x00, 0x10, ++ 0x38, 0xb4, 0x0e, 0x08, ++ 0x38, 0xb4, 0x01, 0xd7, ++ 0x38, 0xb4, 0x8b, 0x40, ++ 0x38, 0xb4, 0x00, 0x10, ++ 0x38, 0xb4, 0x65, 0x0a, ++ 0x38, 0xb4, 0x03, 0xf0, ++ 0x38, 0xb4, 0x00, 0x10, ++ 0x38, 0xb4, 0x6b, 0x0a, ++ 0x38, 0xb4, 0x01, 0xd7, ++ 0x38, 0xb4, 0x00, 0x10, ++ 0x38, 0xb4, 0x20, 0x09, ++ 0x38, 0xb4, 0x00, 0x10, ++ 0x38, 0xb4, 0x15, 0x09, ++ 0x38, 0xb4, 0x00, 0x10, ++ 0x38, 0xb4, 0x09, 0x09, ++ 0x38, 0xb4, 0x8f, 0x22, ++ 0x38, 0xb4, 0x38, 0x80, ++ 0x38, 0xb4, 0x01, 0x98, ++ 0x38, 0xb4, 0x1e, 0xd7, ++ 0x38, 0xb4, 0x81, 0x5d, ++ 0x38, 0xb4, 0x01, 0xd7, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x2a, 0x02, ++ 0x36, 0xb4, 0x26, 0xa0, ++ 0x38, 0xb4, 0xff, 0xff, ++ 0x36, 0xb4, 0x24, 0xa0, ++ 0x38, 0xb4, 0xff, 0xff, ++ 0x36, 0xb4, 0x22, 0xa0, ++ 0x38, 0xb4, 0xff, 0xff, ++ 0x36, 0xb4, 0x20, 0xa0, ++ 0x38, 0xb4, 0xff, 0xff, ++ 0x36, 0xb4, 0x06, 0xa0, ++ 0x38, 0xb4, 0x0a, 0x02, ++ 0x36, 0xb4, 0x04, 0xa0, ++ 0x38, 0xb4, 0x5b, 0x15, ++ 0x36, 0xb4, 0x02, 0xa0, ++ 0x38, 0xb4, 0x42, 0x15, ++ 0x36, 0xb4, 0x00, 0xa0, ++ 0x38, 0xb4, 0xc7, 0x0f, ++ 0x36, 0xb4, 0x08, 0xa0, ++ 0x38, 0xb4, 0x00, 0x0f, ++ 0x6c, 0xe8, 0x00, 0xa0, ++ 0x36, 0xb4, 0x16, 0xa0, ++ 0x38, 0xb4, 0x10, 0x00, ++ 0x36, 0xb4, 0x12, 0xa0, ++ 0x38, 0xb4, 0x00, 0x00, ++ 0x36, 0xb4, 0x14, 0xa0, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x10, 0x80, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x1d, 0x80, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x2c, 0x80, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x2c, 0x80, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x2c, 0x80, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x2c, 0x80, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x2c, 0x80, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x2c, 0x80, ++ 0x38, 0xb4, 0x00, 0xd7, ++ 0x38, 0xb4, 0x90, 0x60, ++ 0x38, 0xb4, 0xd1, 0x60, ++ 0x38, 0xb4, 0x5c, 0xc9, ++ 0x38, 0xb4, 0x07, 0xf0, ++ 0x38, 0xb4, 0xb1, 0x60, ++ 0x38, 0xb4, 0x5a, 0xc9, ++ 0x38, 0xb4, 0x04, 0xf0, ++ 0x38, 0xb4, 0x56, 0xc9, ++ 0x38, 0xb4, 0x02, 0xf0, ++ 0x38, 0xb4, 0x4e, 0xc9, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0xcd, 0x00, ++ 0x38, 0xb4, 0x00, 0xd7, ++ 0x38, 0xb4, 0x90, 0x60, ++ 0x38, 0xb4, 0xd1, 0x60, ++ 0x38, 0xb4, 0x5c, 0xc9, ++ 0x38, 0xb4, 0x07, 0xf0, ++ 0x38, 0xb4, 0xb1, 0x60, ++ 0x38, 0xb4, 0x5a, 0xc9, ++ 0x38, 0xb4, 0x04, 0xf0, ++ 0x38, 0xb4, 0x56, 0xc9, ++ 0x38, 0xb4, 0x02, 0xf0, ++ 0x38, 0xb4, 0x4e, 0xc9, ++ 0x38, 0xb4, 0x00, 0x10, ++ 0x38, 0xb4, 0x2a, 0x02, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x32, 0x01, ++ 0x36, 0xb4, 0x8e, 0xa0, ++ 0x38, 0xb4, 0xff, 0xff, ++ 0x36, 0xb4, 0x8c, 0xa0, ++ 0x38, 0xb4, 0xff, 0xff, ++ 0x36, 0xb4, 0x8a, 0xa0, ++ 0x38, 0xb4, 0xff, 0xff, ++ 0x36, 0xb4, 0x88, 0xa0, ++ 0x38, 0xb4, 0xff, 0xff, ++ 0x36, 0xb4, 0x86, 0xa0, ++ 0x38, 0xb4, 0xff, 0xff, ++ 0x36, 0xb4, 0x84, 0xa0, ++ 0x38, 0xb4, 0xff, 0xff, ++ 0x36, 0xb4, 0x82, 0xa0, ++ 0x38, 0xb4, 0x2f, 0x01, ++ 0x36, 0xb4, 0x80, 0xa0, ++ 0x38, 0xb4, 0xcc, 0x00, ++ 0x36, 0xb4, 0x90, 0xa0, ++ 0x38, 0xb4, 0x03, 0x01, ++ 0x6c, 0xe8, 0x00, 0xa0, ++ 0x36, 0xb4, 0x16, 0xa0, ++ 0x38, 0xb4, 0x20, 0x00, ++ 0x36, 0xb4, 0x12, 0xa0, ++ 0x38, 0xb4, 0x00, 0x00, ++ 0x36, 0xb4, 0x14, 0xa0, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x10, 0x80, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x1e, 0x80, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x26, 0x80, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x2f, 0x80, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x36, 0x80, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x36, 0x80, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x36, 0x80, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x36, 0x80, ++ 0x38, 0xb4, 0x07, 0xd1, ++ 0x38, 0xb4, 0x42, 0xd0, ++ 0x38, 0xb4, 0x04, 0xa4, ++ 0x38, 0xb4, 0x00, 0xd7, ++ 0x38, 0xb4, 0xf4, 0x5f, ++ 0x38, 0xb4, 0x80, 0x82, ++ 0x38, 0xb4, 0x00, 0xd7, ++ 0x38, 0xb4, 0x65, 0x60, ++ 0x38, 0xb4, 0x25, 0xd1, ++ 0x38, 0xb4, 0x02, 0xf0, ++ 0x38, 0xb4, 0x2b, 0xd1, ++ 0x38, 0xb4, 0x40, 0xd0, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x7f, 0x07, ++ 0x38, 0xb4, 0xf0, 0x0c, ++ 0x38, 0xb4, 0x50, 0x0c, ++ 0x38, 0xb4, 0x04, 0xd1, ++ 0x38, 0xb4, 0x40, 0xd0, ++ 0x38, 0xb4, 0x00, 0xd7, ++ 0x38, 0xb4, 0xf4, 0x5f, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x2e, 0x0a, ++ 0x38, 0xb4, 0x9b, 0xcb, ++ 0x38, 0xb4, 0x10, 0xd1, ++ 0x38, 0xb4, 0x40, 0xd0, ++ 0x38, 0xb4, 0x00, 0x10, ++ 0x38, 0xb4, 0x7b, 0x0b, ++ 0x38, 0xb4, 0x00, 0xd7, ++ 0x38, 0xb4, 0xf4, 0x5f, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x1b, 0x08, ++ 0x38, 0xb4, 0x00, 0x10, ++ 0x38, 0xb4, 0xdf, 0x09, ++ 0x38, 0xb4, 0x04, 0xd7, ++ 0x38, 0xb4, 0xb8, 0x7f, ++ 0x38, 0xb4, 0x18, 0xa7, ++ 0x38, 0xb4, 0x00, 0x18, ++ 0x38, 0xb4, 0x4e, 0x07, ++ 0x36, 0xb4, 0x0e, 0xa1, ++ 0x38, 0xb4, 0xff, 0xff, ++ 0x36, 0xb4, 0x0c, 0xa1, ++ 0x38, 0xb4, 0xff, 0xff, ++ 0x36, 0xb4, 0x0a, 0xa1, ++ 0x38, 0xb4, 0xff, 0xff, ++ 0x36, 0xb4, 0x08, 0xa1, ++ 0x38, 0xb4, 0xff, 0xff, ++ 0x36, 0xb4, 0x06, 0xa1, ++ 0x38, 0xb4, 0x4d, 0x07, ++ 0x36, 0xb4, 0x04, 0xa1, ++ 0x38, 0xb4, 0x18, 0x08, ++ 0x36, 0xb4, 0x02, 0xa1, ++ 0x38, 0xb4, 0x2c, 0x0a, ++ 0x36, 0xb4, 0x00, 0xa1, ++ 0x38, 0xb4, 0x7e, 0x07, ++ 0x36, 0xb4, 0x10, 0xa1, ++ 0x38, 0xb4, 0x0f, 0x00, ++ 0x6c, 0xe8, 0x00, 0xa0, ++ 0x36, 0xb4, 0x7c, 0xb8, ++ 0x38, 0xb4, 0x25, 0x86, ++ 0x36, 0xb4, 0x7e, 0xb8, ++ 0x38, 0xb4, 0x86, 0xaf, ++ 0x38, 0xb4, 0xaf, 0x3d, ++ 0x38, 0xb4, 0x89, 0x86, ++ 0x38, 0xb4, 0x88, 0xaf, ++ 0x38, 0xb4, 0xaf, 0x69, ++ 0x38, 0xb4, 0x87, 0x88, ++ 0x38, 0xb4, 0x88, 0xaf, ++ 0x38, 0xb4, 0xaf, 0x9c, ++ 0x38, 0xb4, 0x9c, 0x88, ++ 0x38, 0xb4, 0x88, 0xaf, ++ 0x38, 0xb4, 0xaf, 0x9c, ++ 0x38, 0xb4, 0x9c, 0x88, ++ 0x38, 0xb4, 0x86, 0xbf, ++ 0x38, 0xb4, 0xd7, 0x49, ++ 0x38, 0xb4, 0x40, 0x00, ++ 0x38, 0xb4, 0x77, 0x02, ++ 0x38, 0xb4, 0xaf, 0x7d, ++ 0x38, 0xb4, 0x27, 0x27, ++ 0x38, 0xb4, 0x00, 0x00, ++ 0x38, 0xb4, 0x05, 0x72, ++ 0x38, 0xb4, 0x00, 0x00, ++ 0x38, 0xb4, 0x08, 0x72, ++ 0x38, 0xb4, 0x00, 0x00, ++ 0x38, 0xb4, 0xf3, 0x71, ++ 0x38, 0xb4, 0x00, 0x00, ++ 0x38, 0xb4, 0xf6, 0x71, ++ 0x38, 0xb4, 0x00, 0x00, ++ 0x38, 0xb4, 0x29, 0x72, ++ 0x38, 0xb4, 0x00, 0x00, ++ 0x38, 0xb4, 0x2c, 0x72, ++ 0x38, 0xb4, 0x00, 0x00, ++ 0x38, 0xb4, 0x17, 0x72, ++ 0x38, 0xb4, 0x00, 0x00, ++ 0x38, 0xb4, 0x1a, 0x72, ++ 0x38, 0xb4, 0x00, 0x00, ++ 0x38, 0xb4, 0x1d, 0x72, ++ 0x38, 0xb4, 0x00, 0x00, ++ 0x38, 0xb4, 0x11, 0x72, ++ 0x38, 0xb4, 0x00, 0x00, ++ 0x38, 0xb4, 0x20, 0x72, ++ 0x38, 0xb4, 0x00, 0x00, ++ 0x38, 0xb4, 0x14, 0x72, ++ 0x38, 0xb4, 0x00, 0x00, ++ 0x38, 0xb4, 0x2f, 0x72, ++ 0x38, 0xb4, 0x00, 0x00, ++ 0x38, 0xb4, 0x23, 0x72, ++ 0x38, 0xb4, 0x00, 0x00, ++ 0x38, 0xb4, 0x32, 0x72, ++ 0x38, 0xb4, 0x00, 0x00, ++ 0x38, 0xb4, 0x26, 0x72, ++ 0x38, 0xb4, 0xf9, 0xf8, ++ 0x38, 0xb4, 0xe0, 0xfa, ++ 0x38, 0xb4, 0xb3, 0x85, ++ 0x38, 0xb4, 0x02, 0x38, ++ 0x38, 0xb4, 0x27, 0xad, ++ 0x38, 0xb4, 0xae, 0x02, ++ 0x38, 0xb4, 0xaf, 0x03, ++ 0x38, 0xb4, 0x30, 0x88, ++ 0x38, 0xb4, 0x66, 0x1f, ++ 0x38, 0xb4, 0x65, 0xef, ++ 0x38, 0xb4, 0xc2, 0xbf, ++ 0x38, 0xb4, 0x1a, 0x1f, ++ 0x38, 0xb4, 0xf7, 0x96, ++ 0x38, 0xb4, 0xee, 0x05, ++ 0x38, 0xb4, 0xd2, 0xff, ++ 0x38, 0xb4, 0xda, 0x00, ++ 0x38, 0xb4, 0x05, 0xf6, ++ 0x38, 0xb4, 0xc2, 0xbf, ++ 0x38, 0xb4, 0x1a, 0x2f, ++ 0x38, 0xb4, 0xf7, 0x96, ++ 0x38, 0xb4, 0xee, 0x05, ++ 0x38, 0xb4, 0xd2, 0xff, ++ 0x38, 0xb4, 0xdb, 0x00, ++ 0x38, 0xb4, 0x05, 0xf6, ++ 0x38, 0xb4, 0x02, 0xef, ++ 0x38, 0xb4, 0x11, 0x1f, ++ 0x38, 0xb4, 0x42, 0x0d, ++ 0x38, 0xb4, 0x88, 0xbf, ++ 0x38, 0xb4, 0x02, 0x42, ++ 0x38, 0xb4, 0x7d, 0x6e, ++ 0x38, 0xb4, 0x02, 0xef, ++ 0x38, 0xb4, 0x03, 0x1b, ++ 0x38, 0xb4, 0x11, 0x1f, ++ 0x38, 0xb4, 0x42, 0x0d, ++ 0x38, 0xb4, 0x88, 0xbf, ++ 0x38, 0xb4, 0x02, 0x45, ++ 0x38, 0xb4, 0x7d, 0x6e, ++ 0x38, 0xb4, 0x02, 0xef, ++ 0x38, 0xb4, 0x03, 0x1a, ++ 0x38, 0xb4, 0x11, 0x1f, ++ 0x38, 0xb4, 0x42, 0x0d, ++ 0x38, 0xb4, 0x88, 0xbf, ++ 0x38, 0xb4, 0x02, 0x48, ++ 0x38, 0xb4, 0x7d, 0x6e, ++ 0x38, 0xb4, 0xc2, 0xbf, ++ 0x38, 0xb4, 0x1a, 0x3f, ++ 0x38, 0xb4, 0xf7, 0x96, ++ 0x38, 0xb4, 0xee, 0x05, ++ 0x38, 0xb4, 0xd2, 0xff, ++ 0x38, 0xb4, 0xda, 0x00, ++ 0x38, 0xb4, 0x05, 0xf6, ++ 0x38, 0xb4, 0xc2, 0xbf, ++ 0x38, 0xb4, 0x1a, 0x4f, ++ 0x38, 0xb4, 0xf7, 0x96, ++ 0x38, 0xb4, 0xee, 0x05, ++ 0x38, 0xb4, 0xd2, 0xff, ++ 0x38, 0xb4, 0xdb, 0x00, ++ 0x38, 0xb4, 0x05, 0xf6, ++ 0x38, 0xb4, 0x02, 0xef, ++ 0x38, 0xb4, 0x11, 0x1f, ++ 0x38, 0xb4, 0x42, 0x0d, ++ 0x38, 0xb4, 0x88, 0xbf, ++ 0x38, 0xb4, 0x02, 0x4b, ++ 0x38, 0xb4, 0x7d, 0x6e, ++ 0x38, 0xb4, 0x02, 0xef, ++ 0x38, 0xb4, 0x03, 0x1b, ++ 0x38, 0xb4, 0x11, 0x1f, ++ 0x38, 0xb4, 0x42, 0x0d, ++ 0x38, 0xb4, 0x88, 0xbf, ++ 0x38, 0xb4, 0x02, 0x4e, ++ 0x38, 0xb4, 0x7d, 0x6e, ++ 0x38, 0xb4, 0x02, 0xef, ++ 0x38, 0xb4, 0x03, 0x1a, ++ 0x38, 0xb4, 0x11, 0x1f, ++ 0x38, 0xb4, 0x42, 0x0d, ++ 0x38, 0xb4, 0x88, 0xbf, ++ 0x38, 0xb4, 0x02, 0x51, ++ 0x38, 0xb4, 0x7d, 0x6e, ++ 0x38, 0xb4, 0x56, 0xef, ++ 0x38, 0xb4, 0x20, 0xd0, ++ 0x38, 0xb4, 0x11, 0x1f, ++ 0x38, 0xb4, 0x88, 0xbf, ++ 0x38, 0xb4, 0x02, 0x54, ++ 0x38, 0xb4, 0x7d, 0x6e, ++ 0x38, 0xb4, 0x88, 0xbf, ++ 0x38, 0xb4, 0x02, 0x57, ++ 0x38, 0xb4, 0x7d, 0x6e, ++ 0x38, 0xb4, 0x88, 0xbf, ++ 0x38, 0xb4, 0x02, 0x5a, ++ 0x38, 0xb4, 0x7d, 0x6e, ++ 0x38, 0xb4, 0x85, 0xe1, ++ 0x38, 0xb4, 0xef, 0xa0, ++ 0x38, 0xb4, 0x48, 0x03, ++ 0x38, 0xb4, 0x28, 0x0a, ++ 0x38, 0xb4, 0xef, 0x05, ++ 0x38, 0xb4, 0x1b, 0x20, ++ 0x38, 0xb4, 0xad, 0x01, ++ 0x38, 0xb4, 0x35, 0x27, ++ 0x38, 0xb4, 0x44, 0x1f, ++ 0x38, 0xb4, 0x85, 0xe0, ++ 0x38, 0xb4, 0xe1, 0x88, ++ 0x38, 0xb4, 0x89, 0x85, ++ 0x38, 0xb4, 0x88, 0xbf, ++ 0x38, 0xb4, 0x02, 0x5d, ++ 0x38, 0xb4, 0x7d, 0x6e, ++ 0x38, 0xb4, 0x85, 0xe0, ++ 0x38, 0xb4, 0xe1, 0x8e, ++ 0x38, 0xb4, 0x8f, 0x85, ++ 0x38, 0xb4, 0x88, 0xbf, ++ 0x38, 0xb4, 0x02, 0x60, ++ 0x38, 0xb4, 0x7d, 0x6e, ++ 0x38, 0xb4, 0x85, 0xe0, ++ 0x38, 0xb4, 0xe1, 0x94, ++ 0x38, 0xb4, 0x95, 0x85, ++ 0x38, 0xb4, 0x88, 0xbf, ++ 0x38, 0xb4, 0x02, 0x63, ++ 0x38, 0xb4, 0x7d, 0x6e, ++ 0x38, 0xb4, 0x85, 0xe0, ++ 0x38, 0xb4, 0xe1, 0x9a, ++ 0x38, 0xb4, 0x9b, 0x85, ++ 0x38, 0xb4, 0x88, 0xbf, ++ 0x38, 0xb4, 0x02, 0x66, ++ 0x38, 0xb4, 0x7d, 0x6e, ++ 0x38, 0xb4, 0x88, 0xaf, ++ 0x38, 0xb4, 0xbf, 0x3c, ++ 0x38, 0xb4, 0x3f, 0x88, ++ 0x38, 0xb4, 0x6e, 0x02, ++ 0x38, 0xb4, 0xad, 0x9c, ++ 0x38, 0xb4, 0x35, 0x28, ++ 0x38, 0xb4, 0x44, 0x1f, ++ 0x38, 0xb4, 0x8f, 0xe0, ++ 0x38, 0xb4, 0xe1, 0xf8, ++ 0x38, 0xb4, 0xf9, 0x8f, ++ 0x38, 0xb4, 0x88, 0xbf, ++ 0x38, 0xb4, 0x02, 0x5d, ++ 0x38, 0xb4, 0x7d, 0x6e, ++ 0x38, 0xb4, 0x8f, 0xe0, ++ 0x38, 0xb4, 0xe1, 0xfa, ++ 0x38, 0xb4, 0xfb, 0x8f, ++ 0x38, 0xb4, 0x88, 0xbf, ++ 0x38, 0xb4, 0x02, 0x60, ++ 0x38, 0xb4, 0x7d, 0x6e, ++ 0x38, 0xb4, 0x8f, 0xe0, ++ 0x38, 0xb4, 0xe1, 0xfc, ++ 0x38, 0xb4, 0xfd, 0x8f, ++ 0x38, 0xb4, 0x88, 0xbf, ++ 0x38, 0xb4, 0x02, 0x63, ++ 0x38, 0xb4, 0x7d, 0x6e, ++ 0x38, 0xb4, 0x8f, 0xe0, ++ 0x38, 0xb4, 0xe1, 0xfe, ++ 0x38, 0xb4, 0xff, 0x8f, ++ 0x38, 0xb4, 0x88, 0xbf, ++ 0x38, 0xb4, 0x02, 0x66, ++ 0x38, 0xb4, 0x7d, 0x6e, ++ 0x38, 0xb4, 0x88, 0xaf, ++ 0x38, 0xb4, 0xe1, 0x3c, ++ 0x38, 0xb4, 0xa1, 0x85, ++ 0x38, 0xb4, 0x21, 0x1b, ++ 0x38, 0xb4, 0x37, 0xad, ++ 0x38, 0xb4, 0x1f, 0x34, ++ 0x38, 0xb4, 0xe0, 0x44, ++ 0x38, 0xb4, 0x8a, 0x85, ++ 0x38, 0xb4, 0x85, 0xe1, ++ 0x38, 0xb4, 0xbf, 0x8b, ++ 0x38, 0xb4, 0x5d, 0x88, ++ 0x38, 0xb4, 0x6e, 0x02, ++ 0x38, 0xb4, 0xe0, 0x7d, ++ 0x38, 0xb4, 0x90, 0x85, ++ 0x38, 0xb4, 0x85, 0xe1, ++ 0x38, 0xb4, 0xbf, 0x91, ++ 0x38, 0xb4, 0x60, 0x88, ++ 0x38, 0xb4, 0x6e, 0x02, ++ 0x38, 0xb4, 0xe0, 0x7d, ++ 0x38, 0xb4, 0x96, 0x85, ++ 0x38, 0xb4, 0x85, 0xe1, ++ 0x38, 0xb4, 0xbf, 0x97, ++ 0x38, 0xb4, 0x63, 0x88, ++ 0x38, 0xb4, 0x6e, 0x02, ++ 0x38, 0xb4, 0xe0, 0x7d, ++ 0x38, 0xb4, 0x9c, 0x85, ++ 0x38, 0xb4, 0x85, 0xe1, ++ 0x38, 0xb4, 0xbf, 0x9d, ++ 0x38, 0xb4, 0x66, 0x88, ++ 0x38, 0xb4, 0x6e, 0x02, ++ 0x38, 0xb4, 0xae, 0x7d, ++ 0x38, 0xb4, 0x1f, 0x40, ++ 0x38, 0xb4, 0xe0, 0x44, ++ 0x38, 0xb4, 0x8c, 0x85, ++ 0x38, 0xb4, 0x85, 0xe1, ++ 0x38, 0xb4, 0xbf, 0x8d, ++ 0x38, 0xb4, 0x5d, 0x88, ++ 0x38, 0xb4, 0x6e, 0x02, ++ 0x38, 0xb4, 0xe0, 0x7d, ++ 0x38, 0xb4, 0x92, 0x85, ++ 0x38, 0xb4, 0x85, 0xe1, ++ 0x38, 0xb4, 0xbf, 0x93, ++ 0x38, 0xb4, 0x60, 0x88, ++ 0x38, 0xb4, 0x6e, 0x02, ++ 0x38, 0xb4, 0xe0, 0x7d, ++ 0x38, 0xb4, 0x98, 0x85, ++ 0xff, 0xff, 0xff, 0xff, ++ 0x38, 0xb4, 0x85, 0xe1, ++ 0x38, 0xb4, 0xbf, 0x99, ++ 0x38, 0xb4, 0x63, 0x88, ++ 0x38, 0xb4, 0x6e, 0x02, ++ 0x38, 0xb4, 0xe0, 0x7d, ++ 0x38, 0xb4, 0x9e, 0x85, ++ 0x38, 0xb4, 0x85, 0xe1, ++ 0x38, 0xb4, 0xbf, 0x9f, ++ 0x38, 0xb4, 0x66, 0x88, ++ 0x38, 0xb4, 0x6e, 0x02, ++ 0x38, 0xb4, 0xae, 0x7d, ++ 0x38, 0xb4, 0xe1, 0x0c, ++ 0x38, 0xb4, 0xb3, 0x85, ++ 0x38, 0xb4, 0x04, 0x39, ++ 0x38, 0xb4, 0x2f, 0xac, ++ 0x38, 0xb4, 0xee, 0x04, ++ 0x38, 0xb4, 0xb3, 0x85, ++ 0x38, 0xb4, 0xaf, 0x00, ++ 0x38, 0xb4, 0xd9, 0x39, ++ 0x38, 0xb4, 0xac, 0x22, ++ 0x38, 0xb4, 0xf0, 0xea, ++ 0x38, 0xb4, 0xf6, 0xac, ++ 0x38, 0xb4, 0xac, 0xf0, ++ 0x38, 0xb4, 0xf0, 0xfa, ++ 0x38, 0xb4, 0xf8, 0xac, ++ 0x38, 0xb4, 0xac, 0xf0, ++ 0x38, 0xb4, 0xf0, 0xfc, ++ 0x38, 0xb4, 0x00, 0xad, ++ 0x38, 0xb4, 0xac, 0xf0, ++ 0x38, 0xb4, 0xf0, 0xfe, ++ 0x38, 0xb4, 0xf0, 0xac, ++ 0x38, 0xb4, 0xac, 0xf0, ++ 0x38, 0xb4, 0xf0, 0xf4, ++ 0x38, 0xb4, 0xf2, 0xac, ++ 0x38, 0xb4, 0xac, 0xf0, ++ 0x38, 0xb4, 0xf0, 0xb0, ++ 0x38, 0xb4, 0xae, 0xac, ++ 0x38, 0xb4, 0xac, 0xf0, ++ 0x38, 0xb4, 0xf0, 0xac, ++ 0x38, 0xb4, 0xaa, 0xac, ++ 0x38, 0xb4, 0x00, 0xa1, ++ 0x38, 0xb4, 0xe1, 0x0c, ++ 0x38, 0xb4, 0xf7, 0x8f, ++ 0x38, 0xb4, 0x88, 0xbf, ++ 0x38, 0xb4, 0x02, 0x84, ++ 0x38, 0xb4, 0x7d, 0x6e, ++ 0x38, 0xb4, 0x26, 0xaf, ++ 0x38, 0xb4, 0xe1, 0xe9, ++ 0x38, 0xb4, 0xf6, 0x8f, ++ 0x38, 0xb4, 0x88, 0xbf, ++ 0x38, 0xb4, 0x02, 0x84, ++ 0x38, 0xb4, 0x7d, 0x6e, ++ 0x38, 0xb4, 0x26, 0xaf, ++ 0x38, 0xb4, 0x20, 0xf5, ++ 0x38, 0xb4, 0x86, 0xac, ++ 0x38, 0xb4, 0x88, 0xbf, ++ 0x38, 0xb4, 0x02, 0x3f, ++ 0x38, 0xb4, 0x9c, 0x6e, ++ 0x38, 0xb4, 0x28, 0xad, ++ 0x38, 0xb4, 0xaf, 0x03, ++ 0x38, 0xb4, 0x24, 0x33, ++ 0x38, 0xb4, 0x38, 0xad, ++ 0x38, 0xb4, 0xaf, 0x03, ++ 0x38, 0xb4, 0xe6, 0x32, ++ 0x38, 0xb4, 0x32, 0xaf, ++ 0x38, 0xb4, 0x00, 0xfb, ++ 0x36, 0xb4, 0x7c, 0xb8, ++ 0x38, 0xb4, 0xf6, 0x8f, ++ 0x36, 0xb4, 0x7e, 0xb8, ++ 0x38, 0xb4, 0x05, 0x07, ++ 0x36, 0xb4, 0x7c, 0xb8, ++ 0x38, 0xb4, 0xf8, 0x8f, ++ 0x36, 0xb4, 0x7e, 0xb8, ++ 0x38, 0xb4, 0xcc, 0x19, ++ 0x36, 0xb4, 0x7c, 0xb8, ++ 0x38, 0xb4, 0xfa, 0x8f, ++ 0x36, 0xb4, 0x7e, 0xb8, ++ 0x38, 0xb4, 0xe3, 0x28, ++ 0x36, 0xb4, 0x7c, 0xb8, ++ 0x38, 0xb4, 0xfc, 0x8f, ++ 0x36, 0xb4, 0x7e, 0xb8, ++ 0x38, 0xb4, 0x47, 0x10, ++ 0x36, 0xb4, 0x7c, 0xb8, ++ 0x38, 0xb4, 0xfe, 0x8f, ++ 0x36, 0xb4, 0x7e, 0xb8, ++ 0x38, 0xb4, 0x45, 0x0a, ++ 0x36, 0xb4, 0x5e, 0xb8, ++ 0x38, 0xb4, 0x1e, 0x27, ++ 0x36, 0xb4, 0x60, 0xb8, ++ 0x38, 0xb4, 0x46, 0x38, ++ 0x36, 0xb4, 0x62, 0xb8, ++ 0x38, 0xb4, 0xe6, 0x26, ++ 0x36, 0xb4, 0x64, 0xb8, ++ 0x38, 0xb4, 0xe3, 0x32, ++ 0x36, 0xb4, 0x86, 0xb8, ++ 0x38, 0xb4, 0xff, 0xff, ++ 0x36, 0xb4, 0x88, 0xb8, ++ 0x38, 0xb4, 0xff, 0xff, ++ 0x36, 0xb4, 0x8a, 0xb8, ++ 0x38, 0xb4, 0xff, 0xff, ++ 0x36, 0xb4, 0x8c, 0xb8, ++ 0x38, 0xb4, 0xff, 0xff, ++ 0x36, 0xb4, 0x38, 0xb8, ++ 0x38, 0xb4, 0x0f, 0x00, ++ 0x20, 0xb8, 0x10, 0x00, ++ 0x6c, 0xe8, 0x00, 0xa0, ++ 0x36, 0xb4, 0x00, 0x00, ++ 0x38, 0xb4, 0x00, 0x00, ++ 0x36, 0xb4, 0x2e, 0xb8, ++ 0x38, 0xb4, 0x00, 0x00, ++ 0x36, 0xb4, 0x24, 0x80, ++ 0x38, 0xb4, 0x00, 0x00, ++ 0x6c, 0xe8, 0x00, 0xb0, ++ 0x20, 0xb8, 0x00, 0x00, ++ 0x6c, 0xe8, 0x00, 0xa0, ++ 0x36, 0xb4, 0x1e, 0x80, ++ 0x38, 0xb4, 0x10, 0x00, ++ 0xff, 0xff, 0xff, 0xff}; ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xd284); ++ ocp_data |= BIT(2) | BIT(6); ++ ocp_write_word(tp, MCU_TYPE_USB, 0xd284, ocp_data); ++ ++ data = ram13; ++ len = sizeof(ram13); ++ } + +- netdev = tp->netdev; +- if (!netif_running(netdev)) +- return 0; ++ if (!data) ++ return; + +- netif_stop_queue(netdev); +- napi_disable(&tp->napi); +- clear_bit(WORK_ENABLE, &tp->flags); +- usb_kill_urb(tp->intr_urb); +- cancel_delayed_work_sync(&tp->schedule); +- if (netif_carrier_ok(netdev)) { +- mutex_lock(&tp->control); +- tp->rtl_ops.disable(tp); +- mutex_unlock(&tp->control); +- } ++ while (len) { ++ u32 size; ++ int i; + +- return 0; +-} ++ if (len < 2048) ++ size = len; ++ else ++ size = 2048; + +-static int rtl8152_post_reset(struct usb_interface *intf) +-{ +- struct r8152 *tp = usb_get_intfdata(intf); +- struct net_device *netdev; ++ generic_ocp_write(tp, 0x9A00, 0xff, size, data, MCU_TYPE_USB); + +- if (!tp) +- return 0; ++ data += size; ++ len -= size; + +- netdev = tp->netdev; +- if (!netif_running(netdev)) +- return 0; ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xdc6a); ++ ocp_data |= BIT(4); ++ ocp_write_word(tp, MCU_TYPE_USB, 0xdc6a, ocp_data); + +- set_bit(WORK_ENABLE, &tp->flags); +- if (netif_carrier_ok(netdev)) { +- mutex_lock(&tp->control); +- tp->rtl_ops.enable(tp); +- rtl_start_rx(tp); +- _rtl8152_set_rx_mode(netdev); +- mutex_unlock(&tp->control); ++ for (i = 0; i < 1000; i++) { ++ if (!(ocp_read_word(tp, MCU_TYPE_USB, 0xdc6a) & BIT(4))) ++ break; ++ } ++ ++ if (i == 1000) { ++ dev_err(&tp->intf->dev, "ram code speedup mode fail\n"); ++ return; ++ } + } ++} + +- napi_enable(&tp->napi); +- netif_wake_queue(netdev); +- usb_submit_urb(tp->intr_urb, GFP_KERNEL); ++static void r8156_ram_code(struct r8152 *tp, bool power_cut) +{ + u16 data; -+ + +- if (!list_empty(&tp->rx_done)) +- napi_schedule(&tp->napi); + if (tp->version == RTL_VER_10) { -+ r8153_pre_ram_code(tp, 0x8024, 0x8600); ++ if (power_cut) ++ rtl_patch_key_set(tp, 0x8024, 0x8600); ++ else ++ r8153_pre_ram_code(tp, 0x8024, 0x8600); + + data = ocp_reg_read(tp, 0xb820); + data |= BIT(7); @@ -7982,9 +10829,15 @@ index 2490498b..26cc7c1a 100644 + data &= ~BIT(7); + ocp_reg_write(tp, 0xb820, data); + -+ r8153_post_ram_code(tp, 0x8024); ++ if (power_cut) ++ rtl_patch_key_clear(tp, 0x8024); ++ else ++ r8153_post_ram_code(tp, 0x8024); + } else if (tp->version == RTL_VER_11) { -+ r8153_pre_ram_code(tp, 0x8024, 0x8601); ++ if (power_cut) ++ rtl_patch_key_set(tp, 0x8024, 0x8601); ++ else ++ r8153_pre_ram_code(tp, 0x8024, 0x8601); + + data = ocp_reg_read(tp, 0xb820); + data |= BIT(7); @@ -8509,50 +11362,2478 @@ index 2490498b..26cc7c1a 100644 + data &= ~BIT(7); + ocp_reg_write(tp, 0xb820, data); + -+ r8153_post_ram_code(tp, 0x8024); -+ } -+} ++ if (power_cut) ++ rtl_patch_key_clear(tp, 0x8024); ++ else ++ r8153_post_ram_code(tp, 0x8024); ++ } else if (tp->version == RTL_VER_12) { ++ if (power_cut) ++ rtl_patch_key_set(tp, 0x8024, 0x3700); ++ else ++ r8153_pre_ram_code(tp, 0x8024, 0x3700); + -+static void r8156_hw_phy_cfg2(struct r8152 *tp) -+{ ++ data = ocp_reg_read(tp, 0xb820); ++ data |= BIT(7); ++ ocp_reg_write(tp, 0xb820, data); ++ ++ /* nc_patch */ ++ sram_write(tp, 0xA016, 0x0000); ++ sram_write(tp, 0xA012, 0x0000); ++ sram_write(tp, 0xA014, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8010); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8025); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x803a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8044); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8083); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x808d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x808d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x808d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd712); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4077); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4159); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6099); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7f44); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1a14); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9040); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9201); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1b1a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x2425); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1a14); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3ce5); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1afb); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1b00); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd712); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4077); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4159); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x60b9); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x2421); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1c17); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1a14); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9040); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1c2c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x2425); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1a14); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3ce5); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1c0f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1c13); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd702); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd501); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6072); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8401); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf002); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa401); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x146e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0b77); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd703); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x665d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x653e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x641f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x62c4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6185); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6066); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x165a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xc101); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb00); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1945); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7fa6); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x807d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xc102); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb00); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1945); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x2569); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8058); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x807d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xc104); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb00); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1945); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7fa4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x807d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xc120); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb00); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1945); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd703); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7fbf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x807d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xc140); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb00); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1945); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd703); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7fbe); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x807d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xc180); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb00); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1945); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd703); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7fbd); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xc100); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb00); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd708); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6018); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x165a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x14f6); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd014); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd1e3); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1356); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd705); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fbe); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1559); ++ sram_write(tp, 0xA026, 0xffff); ++ sram_write(tp, 0xA024, 0xffff); ++ sram_write(tp, 0xA022, 0xffff); ++ sram_write(tp, 0xA020, 0x1557); ++ sram_write(tp, 0xA006, 0x1677); ++ sram_write(tp, 0xA004, 0x0b75); ++ sram_write(tp, 0xA002, 0x1c17); ++ sram_write(tp, 0xA000, 0x1b04); ++ sram_write(tp, 0xA008, 0x1f00); ++ ++ /* nc1_patch */ ++ ++ /* nc2_patch */ ++ sram_write(tp, 0xA016, 0x0020); ++ sram_write(tp, 0xA012, 0x0000); ++ sram_write(tp, 0xA014, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8010); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x817f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x82ab); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x83f8); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8444); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8454); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8459); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8465); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb11); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa50c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8310); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd701); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4076); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c03); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0903); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6083); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c1f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0d00); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf003); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c1f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0d00); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a7d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a4d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb12); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5f84); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd102); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd040); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fb4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd701); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x60f3); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd413); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a37); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd410); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a37); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb13); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa108); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a42); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8108); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa00a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa910); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa780); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd14a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd048); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd701); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6255); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5f74); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6326); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd702); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5f07); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x800a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa004); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a42); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8004); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa001); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a42); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8001); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c03); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0902); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xffe2); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fab); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xba08); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7f8b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9a08); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x800a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd702); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6535); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd40d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a37); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb14); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa004); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a42); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8004); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa001); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a42); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8001); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa00a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa780); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd14a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd048); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fb4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6206); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd702); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5f47); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x800a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa004); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a42); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8004); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa001); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a42); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8001); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c03); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0902); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8064); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x800a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd40e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a37); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb920); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9920); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7f8c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd701); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6073); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd701); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4216); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa004); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a42); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8004); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa001); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a42); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8001); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd120); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd040); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fb4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8504); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb21); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa301); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5f9f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8301); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd704); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x40e0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd196); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd04d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fb4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb22); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a6d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c03); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1502); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa640); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9503); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8910); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8720); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6083); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c1f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0d01); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf003); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c1f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0d01); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a7d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c1f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0f14); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb23); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8fc0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a25); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaf40); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a25); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0cc0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0f80); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a25); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xafc0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a25); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd701); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5dee); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb24); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8f1f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd701); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7f6e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa111); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa215); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa401); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8404); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa720); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb25); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c03); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1502); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8640); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9503); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0b43); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0b86); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb920); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9920); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7f8c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb26); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5f82); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8111); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8205); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8404); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb27); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd404); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a37); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6083); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c1f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0d02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf003); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c1f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0d02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a7d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa710); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa104); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a42); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8104); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa001); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a42); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8001); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa120); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaa0f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8110); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa284); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa404); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa00a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd193); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd046); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fb4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb28); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa110); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fa8); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8110); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8284); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa404); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x800a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8710); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb804); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7f82); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9804); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb29); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5f85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa710); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb820); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7f65); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9820); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb2a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa190); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa284); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa404); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa00a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd13d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd04a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3444); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8149); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa220); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd1a0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd040); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3444); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8151); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd702); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5f51); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb2f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa302); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd708); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5f63); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd411); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a37); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8302); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd409); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a37); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb920); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9920); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7f8c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fa3); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8190); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x82a4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8404); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x800a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb808); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7fa3); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9808); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0433); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb15); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa508); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6083); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c1f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0d01); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf003); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c1f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0d01); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a7d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a4d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa301); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5f9f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8301); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd704); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x40e0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd115); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd04f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fb4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd413); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a37); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb16); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a6d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c03); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1502); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa640); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9503); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8720); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd17a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd04c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c1f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0f14); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb17); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8fc0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a25); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaf40); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a25); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0cc0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0f80); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a25); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xafc0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a25); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd701); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x61ce); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5db4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb18); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c03); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1502); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8640); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9503); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa720); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0b43); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xffd6); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8f1f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd701); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7f8e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa131); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaa0f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa2d5); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa407); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa720); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8310); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa308); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8308); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb19); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c03); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1502); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8640); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9503); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0b43); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0b86); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb920); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9920); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7f8c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb1a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5f82); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8111); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x82c5); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa404); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8402); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb804); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7f82); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9804); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb1b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5f85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa710); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb820); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7f65); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9820); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb1c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6083); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c1f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0d02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf003); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c1f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0d02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a7d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa110); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa284); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa404); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8402); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fa8); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb1d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa180); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa402); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fa8); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa220); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd1f5); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd049); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3444); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8221); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd702); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5f51); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb920); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9920); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7f8c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fa3); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa504); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6083); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c1f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0d00); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf003); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c1f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0d00); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a7d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa00a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8190); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x82a4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8402); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa404); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb808); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7fa3); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9808); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb2b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb2c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5f84); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd14a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd048); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa780); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb2d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5f94); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6208); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd702); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5f27); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x800a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa004); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a42); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8004); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa001); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a42); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8001); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c03); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0902); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa00a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xffe9); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb2e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6083); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c1f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0d02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf003); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c1f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0d02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a7d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa190); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa284); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa406); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fa8); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa220); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd1a0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd040); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3444); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x827d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd702); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5f51); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb2f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa302); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd708); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5f63); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd411); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a37); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8302); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd409); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a37); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb920); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9920); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7f8c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fa3); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8190); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x82a4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8406); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x800a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb808); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7fa3); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9808); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0433); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb30); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8380); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb31); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5f86); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9308); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb204); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb301); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd701); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fa2); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb302); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9204); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb32); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd408); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a37); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd141); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd043); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fb4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd704); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4ccc); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4c81); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd702); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x609e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd1e5); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd04d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf003); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd1e5); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd04d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fb4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6083); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c1f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0d01); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf003); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c1f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0d01); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a7d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8710); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa108); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a42); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8108); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa203); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8120); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8a0f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa111); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8204); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa140); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a42); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8140); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd17a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd04b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fb4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa204); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fa7); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb920); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9920); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7f8c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd404); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a37); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6083); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c1f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0d02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf003); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c1f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0d02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a7d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa710); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8101); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8201); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa104); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a42); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8104); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa120); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaa0f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8110); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa284); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa404); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa00a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd193); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd047); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fb4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa110); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fa8); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa180); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd13d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd04a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fb4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf024); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa710); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa00a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8190); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8204); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa280); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa404); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fa7); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8710); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb920); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9920); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7f8c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x800a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8190); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8284); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8406); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4121); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd701); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x60f3); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd1e5); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd04d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fb4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8710); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa00a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8190); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8204); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa280); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa404); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb920); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9920); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7f8c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb33); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5f85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa710); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb820); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd71f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7f65); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9820); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb34); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa00a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa190); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa284); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa404); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fa9); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd701); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6853); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6083); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c1f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0d00); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf003); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c1f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0d00); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a7d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8190); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8284); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb35); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd407); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a37); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8110); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8204); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa280); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa00a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd704); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4215); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa304); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fb8); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd1c3); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd043); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fb4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8304); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4109); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf01e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb36); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd412); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a37); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6309); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd702); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x42c7); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x800a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8180); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8280); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8404); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa004); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a42); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8004); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa001); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a42); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8001); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c03); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0902); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa00a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd14a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd048); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fb4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6083); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c1f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0d02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf003); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c1f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0d02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a7d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcc55); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb37); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa00a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa190); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa2a4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa404); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6041); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa402); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd13d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd04a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fb4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fa9); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd702); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5f71); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb38); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8224); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa288); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8180); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa110); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa404); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x800a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6041); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8402); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd415); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a37); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd13d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd04a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fb4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb39); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa00a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa190); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa2a0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa404); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6041); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa402); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd17a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd047); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fb4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0560); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa111); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd3f5); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd219); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c31); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd708); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fa5); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa215); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd30e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd21a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c31); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd708); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x63e9); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd708); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5f65); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd708); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7f36); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa004); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c35); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8004); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa001); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c35); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8001); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd708); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4098); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd102); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9401); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf003); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd103); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb401); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c27); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa108); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c35); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8108); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8110); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8294); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa202); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0bdb); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd39c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd210); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c31); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd708); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fa5); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd39c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd210); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c31); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd708); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5fa5); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c31); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd708); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x29b5); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x840e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd708); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5f4a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c1f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1014); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c31); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd709); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7fa4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x901f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c23); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb43); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa508); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd701); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3699); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x844a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa504); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa190); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa2a0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa404); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa00a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x2109); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x05ea); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa402); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x05ea); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcb90); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0cf0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0ca0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x06db); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd1ff); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd052); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa508); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8718); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa00a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa190); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa2a0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa404); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0cf0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c50); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x09ef); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a5e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd704); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x2e70); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x06da); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5f55); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa90c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0645); ++ sram_write(tp, 0xA10E, 0x0644); ++ sram_write(tp, 0xA10C, 0x09e9); ++ sram_write(tp, 0xA10A, 0x06da); ++ sram_write(tp, 0xA108, 0x05e1); ++ sram_write(tp, 0xA106, 0x0be4); ++ sram_write(tp, 0xA104, 0x0435); ++ sram_write(tp, 0xA102, 0x0141); ++ sram_write(tp, 0xA100, 0x026d); ++ sram_write(tp, 0xA110, 0x00ff); ++ ++ /* uc2 */ ++ sram_write(tp, 0xb87c, 0x85fe); ++ sram_write(tp, 0xb87e, 0xaf86); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x16af); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8699); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaf86); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe5af); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x86f9); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaf87); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7aaf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x883a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaf88); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x58af); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8b6c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd48b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7c02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8644); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x2c00); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x503c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xffd6); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xac27); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x18e1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x82fe); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xad28); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0cd4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8b84); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0286); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x442c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x003c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xac27); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x06ee); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8299); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x01ae); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x04ee); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8299); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x00af); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x23dc); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf9fa); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcefa); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xfbef); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x79fb); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xc4bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8b76); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x026c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6dac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x2804); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd203); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xae02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd201); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbdd8); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x19d9); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xef94); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x026c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6d78); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x03ef); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x648a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0002); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbdd8); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x19d9); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xef94); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x026c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6d78); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x03ef); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7402); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x72cd); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xac50); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x02ef); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x643a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x019f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe4ef); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4678); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x03ac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x2002); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xae02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd0ff); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xffef); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x97ff); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xfec6); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xfefd); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x041f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x771f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x221c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x450d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x481f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x00ac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7f04); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1a94); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xae08); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1a94); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xac7f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x03d7); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0100); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xef46); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0d48); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1f00); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1c45); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xef69); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xef57); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xef74); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0272); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe8a7); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xffff); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0d1a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x941b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x979e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x072d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0100); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1a64); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xef76); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xef97); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0d98); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd400); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xff1d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x941a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x89cf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1a75); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaf74); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf9bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8b79); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x026c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6da1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0005); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe180); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa0ae); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x03e1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x80a1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaf26); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9aac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x284d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe08f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xffef); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x10c0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe08f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xfe10); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1b08); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x04c8); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaf40); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x67c8); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8c02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6c4e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xc4bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8b8f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x026c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6def); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x74e0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x830c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xad20); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0302); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x74ac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xccef); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x971b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x76ad); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5f02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xae13); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xef69); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xef30); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1b32); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xc4ef); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x46e4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8ffb); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe58f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xfce7); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8ffd); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xcc10); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x11ae); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb8d1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x00a1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1f03); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaf40); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4fbf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8b8c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x026c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4ec4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8f02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6c6d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xef74); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe083); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0cad); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x2003); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0274); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaccc); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xef97); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1b76); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xad5f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x02ae); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x04ef); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x69ef); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3111); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaed1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0287); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x80af); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x2293); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf8f9); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xfafb); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xef59); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe080); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x13ad); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x252f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf88); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x2802); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6c6d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xef64); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1f44); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe18f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb91b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x64ad); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4f1d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd688); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x2bd7); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x882e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0274); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x73ad); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5008); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf88); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3102); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x737c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xae03); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0287); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd0bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x882b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0273); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x73e0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x824c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf621); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe482); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4cbf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8834); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0273); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7cef); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x95ff); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xfefd); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xfc04); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf8f9); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xfafb); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xef79); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf88); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1f02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x737c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1f22); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xac32); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x31ef); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x12bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8822); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x026c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4ed6); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8fba); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1f33); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xac3c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1eef); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x13bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8837); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x026c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4eef); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x96d8); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x19d9); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf88); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x2502); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6c4e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf88); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x2502); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6c4e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1616); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x13ae); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xdf12); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaecc); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf88); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1f02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7373); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xef97); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xfffe); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xfdfc); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0466); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xac88); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x54ac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x88f0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xac8a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x92ac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbadd); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xac6c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xeeac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6cff); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xad02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x99ac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0030); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xac88); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd4c3); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0000); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x00b4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xecee); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8298); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x00af); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1412); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf8bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8b5d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x026c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6d58); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x03e1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8fb8); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x2901); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe58f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb8a0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0049); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xef47); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe483); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x02e5); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8303); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbfc2); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5f1a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x95f7); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x05ee); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xffd2); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x00d8); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf605); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1f11); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xef60); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3002); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6c4e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3302); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6c6d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf728); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3302); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6c4e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf628); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3302); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6c4e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c64); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xef46); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6002); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6c4e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0289); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9902); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3920); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaf89); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x96a0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0149); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xef47); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe483); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x04e5); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8305); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbfc2); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5f1a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x95f7); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x05ee); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xffd2); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x00d8); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf605); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1f11); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xef60); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3002); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6c4e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3302); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6c6d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf729); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3302); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6c4e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf629); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3302); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6c4e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c64); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xef46); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6302); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6c4e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0289); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9902); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3920); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaf89); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x96a0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0249); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xef47); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe483); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x06e5); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8307); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbfc2); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5f1a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x95f7); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x05ee); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xffd2); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x00d8); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf605); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1f11); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xef60); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3002); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6c4e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3302); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6c6d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf72a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3302); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6c4e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf62a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3302); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6c4e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0c64); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xef46); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6602); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6c4e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0289); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x9902); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3920); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaf89); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x96ef); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x47e4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8308); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe583); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x09bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xc25f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1a95); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf705); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xeeff); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd200); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd8f6); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x051f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x11ef); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x60bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8b30); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x026c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4ebf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8b33); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x026c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6df7); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x2bbf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8b33); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x026c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4ef6); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x2bbf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8b33); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x026c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4e0c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x64ef); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x46bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8b69); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x026c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4e02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8999); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0239); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x20af); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8996); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaf39); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1ef8); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf9fa); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe08f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb838); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x02ad); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x2702); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xae03); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaf8b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x201f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x66ef); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x65bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xc21f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1a96); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf705); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xeeff); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd200); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xdaf6); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x05bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xc22f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1a96); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf705); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xeeff); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd200); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xdbf6); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x05ef); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x021f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x110d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x42bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8b3c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x026c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4eef); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x021b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x031f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x110d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x42bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8b36); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x026c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4eef); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x021a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x031f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x110d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x42bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8b39); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x026c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4ebf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xc23f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1a96); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf705); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xeeff); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd200); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xdaf6); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x05bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xc24f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1a96); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf705); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xeeff); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd200); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xdbf6); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x05ef); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x021f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x110d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x42bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8b45); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x026c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4eef); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x021b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x031f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x110d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x42bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8b3f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x026c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4eef); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x021a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x031f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x110d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x42bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8b42); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x026c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4eef); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x56d0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x201f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x11bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8b4e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x026c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4ebf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8b48); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x026c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4ebf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8b4b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x026c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4ee1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8578); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xef03); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x480a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x2805); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xef20); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1b01); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xad27); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3f1f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x44e0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8560); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe185); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x61bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8b51); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x026c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4ee0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8566); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe185); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x67bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8b54); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x026c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4ee0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x856c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe185); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6dbf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8b57); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x026c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4ee0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8572); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe185); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x73bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8b5a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x026c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4ee1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8fb8); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5900); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf728); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe58f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb8af); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8b2c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe185); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x791b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x21ad); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x373e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1f44); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe085); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x62e1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8563); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5102); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6c4e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe085); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x68e1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8569); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5402); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6c4e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe085); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6ee1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x856f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5702); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6c4e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe085); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x74e1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8575); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5a02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6c4e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe18f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb859); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x00f7); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x28e5); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8fb8); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xae4a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1f44); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe085); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x64e1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8565); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5102); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6c4e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe085); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6ae1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x856b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5402); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6c4e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe085); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x70e1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8571); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5702); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6c4e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe085); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x76e1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8577); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5a02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6c4e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe18f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb859); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x00f7); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x28e5); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8fb8); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xae0c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe18f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb839); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x04ac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x2f04); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xee8f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xfefd); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xfc04); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf0ac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8efc); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xac8c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf0ac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xfaf0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xacf8); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf0ac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf6f0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xad00); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf0ac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xfef0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xacfc); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf0ac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf4f0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xacf2); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf0ac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf0f0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xacb0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf0ac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaef0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xacac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf0ac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaaf0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xacee); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf0b0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x24f0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb0a4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf0b1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x24f0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb1a4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xee8f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd400); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x00af); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3976); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x66ac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xeabb); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa430); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6e50); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6e53); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6e56); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6e59); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6e5c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6e5f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6e62); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6e65); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd9ac); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x70f0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xac6a); ++ sram_write(tp, 0xb85e, 0x23b7); ++ sram_write(tp, 0xb860, 0x74db); ++ sram_write(tp, 0xb862, 0x268c); ++ sram_write(tp, 0xb864, 0x3FE5); ++ sram_write(tp, 0xb886, 0x2250); ++ sram_write(tp, 0xb888, 0x140e); ++ sram_write(tp, 0xb88a, 0x3696); ++ sram_write(tp, 0xb88c, 0x3973); ++ sram_write(tp, 0xb838, 0x00ff); ++ ++ data = ocp_reg_read(tp, 0xb820); ++ data &= ~BIT(7); ++ ocp_reg_write(tp, 0xb820, data); ++ ++ /* uc */ ++ sram_write(tp, 0x8464, 0xaf84); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7caf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8485); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x13af); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x851e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb9af); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8684); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaf87); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x01af); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8701); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xac38); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x03af); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x38bb); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaf38); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xc302); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4618); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0a02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x54b7); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1002); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x54c0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd400); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0fbf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8507); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x024f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x48bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8504); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x024f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6759); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf0a1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3008); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0d02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x54c0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xae06); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0d02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x54b7); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0402); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4f67); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa183); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x02ae); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x15a1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8502); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xae10); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x59f0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa180); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x16bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8501); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x024f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x67a1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x381b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xae0b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe18f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xffbf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x84fe); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x024f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x48ae); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x17bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x84fe); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0254); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb7bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x84fb); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0254); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb7ae); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x09a1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x5006); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf84); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xfb02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x54c0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaf04); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4700); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xad34); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xfdad); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0670); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xae14); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf0a6); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x00b8); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbd32); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x30bd); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x30aa); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbd2c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xccbd); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x2ca1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x0705); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xec80); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaf40); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf7af); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x40f5); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd101); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa402); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4f48); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa702); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x54c0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd10f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaa02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4f48); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x024d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6abf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x85ad); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x024f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x67bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8ff7); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xddbf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x85b0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x024f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x67bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8ff8); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xddbf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x85b3); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x024f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x67bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8ff9); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xddbf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x85b6); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x024f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x67bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8ffa); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xddd1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x00bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x85aa); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x024f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4802); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4d6a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xad02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4f67); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xfbdd); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb002); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4f67); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xfcdd); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb302); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4f67); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xfddd); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb602); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4f67); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xfedd); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa702); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x54b7); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa102); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x54b7); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaf3c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x2066); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb800); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb8bd); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x30ee); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbd2c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb8bd); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7040); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbd86); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xc8bd); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8640); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbd88); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xc8bd); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8802); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1929); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa202); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x02ae); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x03a2); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x032e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd10f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaa02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4f48); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe18f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf7bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x85ad); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x024f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x48e1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8ff8); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb002); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4f48); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe18f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf9bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x85b3); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x024f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x48e1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8ffa); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb602); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4f48); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xae2c); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd100); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaa02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4f48); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe18f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xfbbf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x85ad); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x024f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x48e1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8ffc); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb002); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4f48); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe18f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xfdbf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x85b3); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x024f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x48e1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8ffe); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb602); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4f48); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf86); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7e02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4f67); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa100); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x02ae); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x25a1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x041d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe18f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf1bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8675); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x024f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x48e1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8ff2); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf86); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7802); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4f48); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe18f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf3bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x867b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x024f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x48ae); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x29a1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x070b); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xae24); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf86); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8102); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4f67); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xad28); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1be1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8ff4); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf86); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7502); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4f48); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xe18f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xf5bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8678); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x024f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x48e1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8ff6); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf86); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x7b02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4f48); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaf09); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8420); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbc32); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x20bc); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x3e76); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbc08); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xfda6); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x1a00); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb64e); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd101); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa402); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4f48); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa702); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x54c0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xd10f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaa02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4f48); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x024d); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x6abf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x85ad); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x024f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x67bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8ff7); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xddbf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x85b0); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x024f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x67bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8ff8); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xddbf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x85b3); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x024f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x67bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8ff9); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xddbf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x85b6); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x024f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x67bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8ffa); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xddd1); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x00bf); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x85aa); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x024f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4802); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4d6a); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xad02); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4f67); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xfbdd); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb002); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4f67); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xfcdd); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb302); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4f67); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xfddd); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xb602); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x4f67); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf8f); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xfedd); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xbf85); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xa702); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x54b7); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0xaf00); ++ ocp_reg_write(tp, OCP_SRAM_DATA, 0x8800); ++ sram_write(tp, 0xb818, 0x38b8); ++ sram_write(tp, 0xb81a, 0x0444); ++ sram_write(tp, 0xb81c, 0x40ee); ++ sram_write(tp, 0xb81e, 0x3C1A); ++ sram_write(tp, 0xb850, 0x0981); ++ sram_write(tp, 0xb852, 0x0085); ++ sram_write(tp, 0xb878, 0xffff); ++ sram_write(tp, 0xb884, 0xffff); ++ sram_write(tp, 0xb832, 0x003f); ++ ++ if (power_cut) ++ rtl_patch_key_clear(tp, 0x8024); ++ else ++ r8153_post_ram_code(tp, 0x8024); ++ } else { ++ rtl_ram_code_speed_up(tp); ++ } + +- return 0; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_OCP_GPHY_BASE, tp->ocp_base); + } + +-static bool delay_autosuspend(struct r8152 *tp) ++static void r8156_hw_phy_cfg(struct r8152 *tp) + { +- bool sw_linking = !!netif_carrier_ok(tp->netdev); +- bool hw_linking = !!(rtl8152_get_speed(tp) & LINK_STATUS); + bool pcut_entr; + u32 ocp_data; + u16 data; -+ + +- /* This means a linking change occurs and the driver doesn't detect it, +- * yet. If the driver has disabled tx/rx and hw is linking on, the +- * device wouldn't wake up by receiving any packet. +- */ +- if (work_busy(&tp->schedule.work) || sw_linking != hw_linking) +- return true; ++ r8156_patch_code(tp); + +- /* If the linking down is occurred by nway, the device may miss the +- * linking change event. And it wouldn't wake when linking on. +- */ +- if (!sw_linking && tp->rtl_ops.in_nway(tp)) +- return true; +- else if (!skb_queue_empty(&tp->tx_queue)) +- return true; +- else +- return false; +-} + ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); + pcut_entr = (ocp_data & PCUT_STATUS) ? true : false; + if (pcut_entr) { + ocp_data &= ~PCUT_STATUS; + ocp_write_word(tp, MCU_TYPE_USB, USB_MISC_0, ocp_data); -+ + +-static int rtl8152_runtime_resume(struct r8152 *tp) +-{ +- struct net_device *netdev = tp->netdev; + data = r8153_phy_status(tp, PHY_STAT_EXT_INIT); + WARN_ON_ONCE(data != PHY_STAT_EXT_INIT); -+ -+ r8156_ram_code(tp); -+ + +- if (netif_running(netdev) && netdev->flags & IFF_UP) { +- struct napi_struct *napi = &tp->napi; ++ r8156_ram_code(tp, true); + +- tp->rtl_ops.autosuspend_en(tp, false); +- napi_disable(napi); +- set_bit(WORK_ENABLE, &tp->flags); + data = ocp_reg_read(tp, 0xa468); -+ data &= ~(BIT(3) | BIT(0)); ++ data &= ~(BIT(3) | BIT(1)); + ocp_reg_write(tp, 0xa468, data); + } else { -+ r8156_patch_code(tp); -+ -+ if (r8153_patch_request(tp, true)) { -+ netif_err(tp, drv, tp->netdev, -+ "patch request error\n"); -+ return; -+ } -+ -+ r8156_ram_code(tp); -+ -+ r8153_patch_request(tp, false); -+ -+ /* disable ALDPS before updating the PHY parameters */ -+ r8153_aldps_en(tp, false); -+ -+ /* disable EEE before updating the PHY parameters */ -+ r8153_eee_en(tp, false); -+ ocp_reg_write(tp, OCP_EEE_ADV, 0); ++ r8156_ram_code(tp, false); + } + +- if (netif_carrier_ok(netdev)) { +- if (rtl8152_get_speed(tp) & LINK_STATUS) { +- rtl_start_rx(tp); +- } else { +- netif_carrier_off(netdev); +- tp->rtl_ops.disable(tp); +- netif_info(tp, link, netdev, "linking down\n"); +- } ++ /* disable ALDPS before updating the PHY parameters */ ++ r8153_aldps_en(tp, false); ++ ++ /* disable EEE before updating the PHY parameters */ ++ rtl_eee_enable(tp, false); + + data = r8153_phy_status(tp, PHY_STAT_LAN_ON); + WARN_ON_ONCE(data != PHY_STAT_LAN_ON); @@ -8666,9 +13947,9 @@ index 2490498b..26cc7c1a 100644 + ocp_reg_write(tp, 0xbd2c, data); + break; + case RTL_VER_11: -+ data = ocp_reg_read(tp, 0xad4e); -+ data |= BIT(4); -+ ocp_reg_write(tp, 0xad4e, data); ++// data = ocp_reg_read(tp, 0xad4e); ++// data |= BIT(4); ++// ocp_reg_write(tp, 0xad4e, data); + data = ocp_reg_read(tp, 0xad16); + data |= 0x3ff; + ocp_reg_write(tp, 0xad16, data); @@ -8698,12 +13979,21 @@ index 2490498b..26cc7c1a 100644 + data |= BIT(1); + ocp_reg_write(tp, 0xac5e, data); + ocp_reg_write(tp, 0xad4c, 0x00a8); -+ data = ocp_reg_read(tp, 0xac5c); + ocp_reg_write(tp, 0xac5c, 0x01ff); + data = ocp_reg_read(tp, 0xac8a); + data &= ~0xf0; + data |= BIT(4) | BIT(5); + ocp_reg_write(tp, 0xac8a, data); ++ ocp_reg_write(tp, 0xb87c, 0x8157); ++ data = ocp_reg_read(tp, 0xb87e); ++ data &= ~0xff00; ++ data |= 0x0500; ++ ocp_reg_write(tp, 0xb87e, data); ++ ocp_reg_write(tp, 0xb87c, 0x8159); ++ data = ocp_reg_read(tp, 0xb87e); ++ data &= ~0xff00; ++ data |= 0x0700; ++ ocp_reg_write(tp, 0xb87e, data); + ocp_reg_write(tp, 0xb87c, 0x80a2); + ocp_reg_write(tp, 0xb87e, 0x0153); + ocp_reg_write(tp, 0xb87c, 0x809c); @@ -8763,8 +14053,11 @@ index 2490498b..26cc7c1a 100644 + netif_err(tp, drv, tp->netdev, + "patch request error\n"); + return; -+ } -+ + } + +- napi_enable(napi); +- clear_bit(SELECTIVE_SUSPEND, &tp->flags); +- smp_mb__after_atomic(); + data = ocp_reg_read(tp, 0xb896); + data &= ~BIT(0); + ocp_reg_write(tp, 0xb896, data); @@ -8829,7 +14122,9 @@ index 2490498b..26cc7c1a 100644 + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4); + ocp_data |= EEE_SPDWN_EN; + ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ocp_data); -+ + +- if (!list_empty(&tp->rx_done)) +- napi_schedule(&tp->napi); + data = ocp_reg_read(tp, OCP_DOWN_SPEED); + data &= ~(EN_EEE_100 | EN_EEE_1000); + data |= EN_10M_CLKDIV; @@ -8837,12 +14132,17 @@ index 2490498b..26cc7c1a 100644 + tp->ups_info._10m_ckdiv = true; + tp->ups_info.eee_plloff_100 = false; + tp->ups_info.eee_plloff_giga = false; -+ + +- usb_submit_urb(tp->intr_urb, GFP_NOIO); +- } else { +- if (netdev->flags & IFF_UP) +- tp->rtl_ops.autosuspend_en(tp, false); + data = ocp_reg_read(tp, OCP_POWER_CFG); + data &= ~EEE_CLKDIV_EN; + ocp_reg_write(tp, OCP_POWER_CFG, data); + tp->ups_info.eee_ckdiv = false; -+ + +- clear_bit(SELECTIVE_SUSPEND, &tp->flags); + ocp_reg_write(tp, OCP_SYSCLK_CFG, 0); + ocp_reg_write(tp, OCP_SYSCLK_CFG, clk_div_expo(5)); + tp->ups_info._250m_ckdiv = false; @@ -8874,47 +14174,650 @@ index 2490498b..26cc7c1a 100644 + data = ocp_reg_read(tp, 0xa86a); + data &= ~BIT(0); + ocp_reg_write(tp, 0xa86a, data); ++ ++ /* MDI SWAP */ ++ if ((ocp_read_word(tp, MCU_TYPE_USB, 0xdb42) & BIT(5)) && ++ (ocp_reg_read(tp, 0xd068) & BIT(1))) { ++ u16 swap_a, swap_b; ++ ++ data = ocp_reg_read(tp, 0xd068); ++ data &= ~0x1f; ++ data |= 0; ++ ocp_reg_write(tp, 0xd068, data); ++ swap_a = ocp_reg_read(tp, 0xd06a); ++ data &= ~0x1f; ++ data |= 0x18; ++ ocp_reg_write(tp, 0xd068, data); ++ swap_b = ocp_reg_read(tp, 0xd06a); ++ data &= ~0x1f; ++ data |= 0; ++ ocp_reg_write(tp, 0xd068, data); ++ ocp_reg_write(tp, 0xd06a, ++ (swap_a & ~0x7ff) | (swap_b & 0x7ff)); ++ data &= ~0x1f; ++ data |= 0x18; ++ ocp_reg_write(tp, 0xd068, data); ++ ocp_reg_write(tp, 0xd06a, ++ (swap_b & ~0x7ff) | (swap_a & 0x7ff)); ++ data &= ~0x1f; ++ data |= 0x08; ++ ocp_reg_write(tp, 0xd068, data); ++ swap_a = ocp_reg_read(tp, 0xd06a); ++ data &= ~0x1f; ++ data |= 0x10; ++ ocp_reg_write(tp, 0xd068, data); ++ swap_b = ocp_reg_read(tp, 0xd06a); ++ data &= ~0x1f; ++ data |= 0x08; ++ ocp_reg_write(tp, 0xd068, data); ++ ocp_reg_write(tp, 0xd06a, ++ (swap_a & ~0x7ff) | (swap_b & 0x7ff)); ++ data &= ~0x1f; ++ data |= 0x10; ++ ocp_reg_write(tp, 0xd068, data); ++ ocp_reg_write(tp, 0xd06a, ++ (swap_b & ~0x7ff) | (swap_a & 0x7ff)); ++ swap_a = ocp_reg_read(tp, 0xbd5a); ++ swap_b = ocp_reg_read(tp, 0xbd5c); ++ ocp_reg_write(tp, 0xbd5a, (swap_a & ~0x1f1f) | ++ ((swap_b & 0x1f) << 8) | ++ ((swap_b >> 8) & 0x1f)); ++ ocp_reg_write(tp, 0xbd5c, (swap_b & ~0x1f1f) | ++ ((swap_a & 0x1f) << 8) | ++ ((swap_a >> 8) & 0x1f)); ++ swap_a = ocp_reg_read(tp, 0xbc18); ++ swap_b = ocp_reg_read(tp, 0xbc1a); ++ ocp_reg_write(tp, 0xbc18, (swap_a & ~0x1f1f) | ++ ((swap_b & 0x1f) << 8) | ++ ((swap_b >> 8) & 0x1f)); ++ ocp_reg_write(tp, 0xbc1a, (swap_b & ~0x1f1f) | ++ ((swap_a & 0x1f) << 8) | ++ ((swap_a >> 8) & 0x1f)); ++ } ++ break; ++ default: ++ break; + } + +- return 0; ++ data = ocp_reg_read(tp, 0xa428); ++ data &= ~BIT(9); ++ ocp_reg_write(tp, 0xa428, data); ++ data = ocp_reg_read(tp, 0xa5ea); ++ data &= ~BIT(0); ++ ocp_reg_write(tp, 0xa5ea, data); ++ tp->ups_info.lite_mode = 0; ++ ++ if (tp->eee_en) ++ rtl_eee_enable(tp, true); ++ ++ r8153_aldps_en(tp, true); ++ r8152b_enable_fc(tp); ++ r8153_u2p3en(tp, true); ++ ++ set_bit(PHY_RESET, &tp->flags); + } + +-static int rtl8152_system_resume(struct r8152 *tp) ++static void r8156b_hw_phy_cfg(struct r8152 *tp) + { +- struct net_device *netdev = tp->netdev; +- +- netif_device_attach(netdev); ++ bool pcut_entr; ++ u32 ocp_data; ++ u16 data; + +- if (netif_running(netdev) && netdev->flags & IFF_UP) { +- tp->rtl_ops.up(tp); +- netif_carrier_off(netdev); +- set_bit(WORK_ENABLE, &tp->flags); +- usb_submit_urb(tp->intr_urb, GFP_NOIO); ++ r8156_patch_code(tp); ++ ++ if (tp->version == RTL_VER_12) { ++ ocp_reg_write(tp, 0xbf86, 0x9000); ++ data = ocp_reg_read(tp, 0xc402); ++ data |= BIT(10); ++ ocp_reg_write(tp, 0xc402, data); ++ data &= ~BIT(10); ++ ocp_reg_write(tp, 0xc402, data); ++ ocp_reg_write(tp, 0xbd86, 0x1010); ++ ocp_reg_write(tp, 0xbd88, 0x1010); ++ data = ocp_reg_read(tp, 0xbd4e); ++ data &= ~(BIT(10) | BIT(11)); ++ data |= BIT(11); ++ ocp_reg_write(tp, 0xbd4e, data); ++ data = ocp_reg_read(tp, 0xbf46); ++ data &= ~0xf00; ++ data |= 0x700; ++ ocp_reg_write(tp, 0xbf46, data); + } + +- return 0; +-} ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); ++ pcut_entr = (ocp_data & PCUT_STATUS) ? true : false; ++ if (pcut_entr) { ++ ocp_data &= ~PCUT_STATUS; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_MISC_0, ocp_data); + +-static int rtl8152_runtime_suspend(struct r8152 *tp) +-{ +- struct net_device *netdev = tp->netdev; +- int ret = 0; ++ data = r8153_phy_status(tp, PHY_STAT_EXT_INIT); ++// switch (data) { ++// case PHY_STAT_PWRDN: ++// case PHY_STAT_EXT_INIT: ++// break; ++// default: ++// break; ++// } + +- set_bit(SELECTIVE_SUSPEND, &tp->flags); +- smp_mb__after_atomic(); ++ r8156_ram_code(tp, true); + +- if (netif_running(netdev) && test_bit(WORK_ENABLE, &tp->flags)) { +- u32 rcr = 0; ++ data = ocp_reg_read(tp, 0xa466); ++ data &= ~BIT(0); ++ ocp_reg_write(tp, 0xa466, data); + +- if (netif_carrier_ok(netdev)) { +- u32 ocp_data; ++ data = ocp_reg_read(tp, 0xa468); ++ data &= ~(BIT(3) | BIT(1)); ++ ocp_reg_write(tp, 0xa468, data); + +- rcr = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); +- ocp_data = rcr & ~RCR_ACPT_ALL; +- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); +- rxdy_gated_en(tp, true); +- ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, +- PLA_OOB_CTRL); +- if (!(ocp_data & RXFIFO_EMPTY)) { +- rxdy_gated_en(tp, false); +- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, rcr); +- clear_bit(SELECTIVE_SUSPEND, &tp->flags); +- smp_mb__after_atomic(); +- ret = -EBUSY; +- goto out1; +- } ++ data = r8152_mdio_read(tp, MII_BMCR); ++ if (data & BMCR_PDOWN) { ++ data &= ~BMCR_PDOWN; ++ r8152_mdio_write(tp, MII_BMCR, data); + } ++ } else { ++ r8156_ram_code(tp, false); ++ } + +- clear_bit(WORK_ENABLE, &tp->flags); +- usb_kill_urb(tp->intr_urb); ++ /* disable ALDPS before updating the PHY parameters */ ++ r8153_aldps_en(tp, false); + +- tp->rtl_ops.autosuspend_en(tp, true); ++ /* disable EEE before updating the PHY parameters */ ++ rtl_eee_enable(tp, false); + +- if (netif_carrier_ok(netdev)) { +- struct napi_struct *napi = &tp->napi; ++ data = r8153_phy_status(tp, PHY_STAT_LAN_ON); ++ WARN_ON_ONCE(data != PHY_STAT_LAN_ON); + +- napi_disable(napi); +- rtl_stop_rx(tp); +- rxdy_gated_en(tp, false); +- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, rcr); +- napi_enable(napi); +- } ++// ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR); ++// ocp_data |= PFM_PWM_SWITCH; ++// ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data); + +- if (delay_autosuspend(tp)) { +- rtl8152_runtime_resume(tp); +- ret = -EBUSY; ++ switch (tp->version) { ++ case RTL_VER_12: ++// ocp_reg_write(tp, 0xbf86, 0x9000); ++// data = ocp_reg_read(tp, 0xc402); ++// data |= BIT(10); ++// ocp_reg_write(tp, 0xc402, data); ++// data &= ~BIT(10); ++// ocp_reg_write(tp, 0xc402, data); ++// ocp_reg_write(tp, 0xbd86, 0x1010); ++// ocp_reg_write(tp, 0xbd88, 0x1010); ++// data = ocp_reg_read(tp, 0xbd4e); ++// data &= ~(BIT(10) | BIT(11)); ++// data |= BIT(11); ++// ocp_reg_write(tp, 0xbd4e, data); ++// data = ocp_reg_read(tp, 0xbf46); ++// data &= ~0xf00; ++// data |= 0x700; ++// ocp_reg_write(tp, 0xbf46, data); ++ ++ data = ocp_reg_read(tp, 0xbc08); ++ data |= BIT(3) | BIT(2); ++ ocp_reg_write(tp, 0xbc08, data); ++ ++ data = sram_read(tp, 0x8fff); ++ data &= ~0xff00; ++ data |= 0x0400; ++ sram_write(tp, 0x8fff, data); ++ ++ data = ocp_reg_read(tp, 0xacda); ++ data |= 0xff00; ++ ocp_reg_write(tp, 0xacda, data); ++ data = ocp_reg_read(tp, 0xacde); ++ data |= 0xf000; ++ ocp_reg_write(tp, 0xacde, data); ++ ocp_reg_write(tp, 0xac8c, 0x0ffc); ++ ocp_reg_write(tp, 0xac46, 0xb7b4); ++ ocp_reg_write(tp, 0xac50, 0x0fbc); ++ ocp_reg_write(tp, 0xac3c, 0x9240); ++ ocp_reg_write(tp, 0xac4e, 0x0db4); ++ ocp_reg_write(tp, 0xacc6, 0x0707); ++ ocp_reg_write(tp, 0xacc8, 0xa0d3); ++ ocp_reg_write(tp, 0xad08, 0x0007); ++ ++ ocp_reg_write(tp, 0xb87c, 0x8560); ++ ocp_reg_write(tp, 0xb87e, 0x19cc); ++ ocp_reg_write(tp, 0xb87c, 0x8562); ++ ocp_reg_write(tp, 0xb87e, 0x19cc); ++ ocp_reg_write(tp, 0xb87c, 0x8564); ++ ocp_reg_write(tp, 0xb87e, 0x19cc); ++ ocp_reg_write(tp, 0xb87c, 0x8566); ++ ocp_reg_write(tp, 0xb87e, 0x147d); ++ ocp_reg_write(tp, 0xb87c, 0x8568); ++ ocp_reg_write(tp, 0xb87e, 0x147d); ++ ocp_reg_write(tp, 0xb87c, 0x856a); ++ ocp_reg_write(tp, 0xb87e, 0x147d); ++ ocp_reg_write(tp, 0xb87c, 0x8ffe); ++ ocp_reg_write(tp, 0xb87e, 0x0907); ++ ocp_reg_write(tp, 0xb87c, 0x80d6); ++ ocp_reg_write(tp, 0xb87e, 0x2801); ++ ocp_reg_write(tp, 0xb87c, 0x80f2); ++ ocp_reg_write(tp, 0xb87e, 0x2801); ++ ocp_reg_write(tp, 0xb87c, 0x80f4); ++ ocp_reg_write(tp, 0xb87e, 0x6077); ++ ocp_reg_write(tp, 0xb506, 0x01e7); ++ ++ ocp_reg_write(tp, 0xb87c, 0x8013); ++ ocp_reg_write(tp, 0xb87e, 0x0700); ++ ocp_reg_write(tp, 0xb87c, 0x8fb9); ++ ocp_reg_write(tp, 0xb87e, 0x2801); ++ ocp_reg_write(tp, 0xb87c, 0x8fba); ++ ocp_reg_write(tp, 0xb87e, 0x0100); ++ ocp_reg_write(tp, 0xb87c, 0x8fbc); ++ ocp_reg_write(tp, 0xb87e, 0x1900); ++ ocp_reg_write(tp, 0xb87c, 0x8fbe); ++ ocp_reg_write(tp, 0xb87e, 0xe100); ++ ocp_reg_write(tp, 0xb87c, 0x8fc0); ++ ocp_reg_write(tp, 0xb87e, 0x0800); ++ ocp_reg_write(tp, 0xb87c, 0x8fc2); ++ ocp_reg_write(tp, 0xb87e, 0xe500); ++ ocp_reg_write(tp, 0xb87c, 0x8fc4); ++ ocp_reg_write(tp, 0xb87e, 0x0f00); ++ ocp_reg_write(tp, 0xb87c, 0x8fc6); ++ ocp_reg_write(tp, 0xb87e, 0xf100); ++ ocp_reg_write(tp, 0xb87c, 0x8fc8); ++ ocp_reg_write(tp, 0xb87e, 0x0400); ++ ocp_reg_write(tp, 0xb87c, 0x8fca); ++ ocp_reg_write(tp, 0xb87e, 0xf300); ++ ocp_reg_write(tp, 0xb87c, 0x8fcc); ++ ocp_reg_write(tp, 0xb87e, 0xfd00); ++ ocp_reg_write(tp, 0xb87c, 0x8fce); ++ ocp_reg_write(tp, 0xb87e, 0xff00); ++ ocp_reg_write(tp, 0xb87c, 0x8fd0); ++ ocp_reg_write(tp, 0xb87e, 0xfb00); ++ ocp_reg_write(tp, 0xb87c, 0x8fd2); ++ ocp_reg_write(tp, 0xb87e, 0x0100); ++ ocp_reg_write(tp, 0xb87c, 0x8fd4); ++ ocp_reg_write(tp, 0xb87e, 0xf400); ++ ocp_reg_write(tp, 0xb87c, 0x8fd6); ++ ocp_reg_write(tp, 0xb87e, 0xff00); ++ ocp_reg_write(tp, 0xb87c, 0x8fd8); ++ ocp_reg_write(tp, 0xb87e, 0xf600); ++ ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, 0xe952); ++ ocp_data |= BIT(2) | BIT(1); ++ ocp_write_byte(tp, MCU_TYPE_PLA, 0xe952, ocp_data); ++ ocp_reg_write(tp, 0xb87c, 0x813d); ++ ocp_reg_write(tp, 0xb87e, 0x390e); ++ ocp_reg_write(tp, 0xb87c, 0x814f); ++ ocp_reg_write(tp, 0xb87e, 0x790e); ++ ocp_reg_write(tp, 0xb87c, 0x80b0); ++ ocp_reg_write(tp, 0xb87e, 0x0f31); ++ data = ocp_reg_read(tp, 0xbf4c); ++ data |= BIT(1); ++ ocp_reg_write(tp, 0xbf4c, data); ++ data = ocp_reg_read(tp, 0xbcca); ++ data |= BIT(9) | BIT(8); ++ ocp_reg_write(tp, 0xbcca, data); ++ ocp_reg_write(tp, 0xb87c, 0x8141); ++ ocp_reg_write(tp, 0xb87e, 0x320e); ++ ocp_reg_write(tp, 0xb87c, 0x8153); ++ ocp_reg_write(tp, 0xb87e, 0x720e); ++ ocp_reg_write(tp, 0xb87c, 0x8529); ++ ocp_reg_write(tp, 0xb87e, 0x050e); ++ data = ocp_reg_read(tp, OCP_EEE_CFG); ++ data &= ~CTAP_SHORT_EN; ++ ocp_reg_write(tp, OCP_EEE_CFG, data); ++ ++ sram_write(tp, 0x816c, 0xc4a0); ++ sram_write(tp, 0x8170, 0xc4a0); ++ sram_write(tp, 0x8174, 0x04a0); ++ sram_write(tp, 0x8178, 0x04a0); ++ sram_write(tp, 0x817c, 0x0719); ++ sram_write(tp, 0x8ff4, 0x0400); ++ sram_write(tp, 0x8ff1, 0x0404); ++ ++ ocp_reg_write(tp, 0xbf4a, 0x001b); ++ ocp_reg_write(tp, 0xb87c, 0x8033); ++ ocp_reg_write(tp, 0xb87e, 0x7c13); ++ ocp_reg_write(tp, 0xb87c, 0x8037); ++ ocp_reg_write(tp, 0xb87e, 0x7c13); ++ ocp_reg_write(tp, 0xb87c, 0x803b); ++ ocp_reg_write(tp, 0xb87e, 0xfc32); ++ ocp_reg_write(tp, 0xb87c, 0x803f); ++ ocp_reg_write(tp, 0xb87e, 0x7c13); ++ ocp_reg_write(tp, 0xb87c, 0x8043); ++ ocp_reg_write(tp, 0xb87e, 0x7c13); ++ ocp_reg_write(tp, 0xb87c, 0x8047); ++ ocp_reg_write(tp, 0xb87e, 0x7c13); ++ ++ ocp_reg_write(tp, 0xb87c, 0x8145); ++ ocp_reg_write(tp, 0xb87e, 0x370e); ++ ocp_reg_write(tp, 0xb87c, 0x8157); ++ ocp_reg_write(tp, 0xb87e, 0x770e); ++ ocp_reg_write(tp, 0xb87c, 0x8169); ++ ocp_reg_write(tp, 0xb87e, 0x0d0a); ++ ocp_reg_write(tp, 0xb87c, 0x817b); ++ ocp_reg_write(tp, 0xb87e, 0x1d0a); ++ ++ data = sram_read(tp, 0x8217); ++ data &= ~0xff00; ++ data |= 0x5000; ++ sram_write(tp, 0x8217, data); ++ data = sram_read(tp, 0x821a); ++ data &= ~0xff00; ++ data |= 0x5000; ++ sram_write(tp, 0x821a, data); ++ sram_write(tp, 0x80da, 0x0403); ++ data = sram_read(tp, 0x80dc); ++ data &= ~0xff00; ++ data |= 0x1000; ++ sram_write(tp, 0x80dc, data); ++ sram_write(tp, 0x80b3, 0x0384); ++ sram_write(tp, 0x80b7, 0x2007); ++ data = sram_read(tp, 0x80ba); ++ data &= ~0xff00; ++ data |= 0x6c00; ++ sram_write(tp, 0x80ba, data); ++ sram_write(tp, 0x80b5, 0xf009); ++ data = sram_read(tp, 0x80bd); ++ data &= ~0xff00; ++ data |= 0x9f00; ++ sram_write(tp, 0x80bd, data); ++ sram_write(tp, 0x80c7, 0xf083); ++ sram_write(tp, 0x80dd, 0x03f0); ++ data = sram_read(tp, 0x80df); ++ data &= ~0xff00; ++ data |= 0x1000; ++ sram_write(tp, 0x80df, data); ++ sram_write(tp, 0x80cb, 0x2007); ++ data = sram_read(tp, 0x80ce); ++ data &= ~0xff00; ++ data |= 0x6c00; ++ sram_write(tp, 0x80ce, data); ++ sram_write(tp, 0x80c9, 0x8009); ++ data = sram_read(tp, 0x80d1); ++ data &= ~0xff00; ++ data |= 0x8000; ++ sram_write(tp, 0x80d1, data); ++ sram_write(tp, 0x80a3, 0x200a); ++ sram_write(tp, 0x80a5, 0xf0ad); ++ sram_write(tp, 0x809f, 0x6073); ++ sram_write(tp, 0x80a1, 0x000b); ++ data = sram_read(tp, 0x80a9); ++ data &= ~0xff00; ++ data |= 0xc000; ++ sram_write(tp, 0x80a9, data); ++ ++ if (r8153_patch_request(tp, true)) { ++ netif_err(tp, drv, tp->netdev, ++ "patch request error\n"); ++ return; + } +- } ++ data = ocp_reg_read(tp, 0xb896); ++ data &= ~BIT(0); ++ ocp_reg_write(tp, 0xb896, data); ++ data = ocp_reg_read(tp, 0xb892); ++ data &= ~0xff00; ++ ocp_reg_write(tp, 0xb892, data); ++ ocp_reg_write(tp, 0xb88e, 0xc23e); ++ ocp_reg_write(tp, 0xb890, 0x0000); ++ ocp_reg_write(tp, 0xb88e, 0xc240); ++ ocp_reg_write(tp, 0xb890, 0x0103); ++ ocp_reg_write(tp, 0xb88e, 0xc242); ++ ocp_reg_write(tp, 0xb890, 0x0507); ++ ocp_reg_write(tp, 0xb88e, 0xc244); ++ ocp_reg_write(tp, 0xb890, 0x090b); ++ ocp_reg_write(tp, 0xb88e, 0xc246); ++ ocp_reg_write(tp, 0xb890, 0x0c0e); ++ ocp_reg_write(tp, 0xb88e, 0xc248); ++ ocp_reg_write(tp, 0xb890, 0x1012); ++ ocp_reg_write(tp, 0xb88e, 0xc24a); ++ ocp_reg_write(tp, 0xb890, 0x1416); ++ data = ocp_reg_read(tp, 0xb896); ++ data |= BIT(0); ++ ocp_reg_write(tp, 0xb896, data); + +-out1: +- return ret; +-} ++ r8153_patch_request(tp, false); + +-static int rtl8152_system_suspend(struct r8152 *tp) +-{ +- struct net_device *netdev = tp->netdev; ++ data = ocp_reg_read(tp, 0xa86a); ++ data |= BIT(0); ++ ocp_reg_write(tp, 0xa86a, data); ++ data = ocp_reg_read(tp, 0xa6f0); ++ data |= BIT(0); ++ ocp_reg_write(tp, 0xa6f0, data); ++ ++ ocp_reg_write(tp, 0xbfa0, 0xd70d); ++ ocp_reg_write(tp, 0xbfa2, 0x4100); ++ ocp_reg_write(tp, 0xbfa4, 0xe868); ++ ocp_reg_write(tp, 0xbfa6, 0xdc59); ++ ocp_reg_write(tp, 0xb54c, 0x3c18); ++ data = ocp_reg_read(tp, 0xbfa4); ++ data &= ~BIT(5); ++ ocp_reg_write(tp, 0xbfa4, data); ++ data = sram_read(tp, 0x817d); ++ data |= BIT(12); ++ sram_write(tp, 0x817d, data); ++ break; ++ case RTL_VER_13: ++ // 2.5G INRX ++ data = ocp_reg_read(tp, 0xac46); ++ data &= ~0x00f0; ++ data |= 0x0090; ++ ocp_reg_write(tp, 0xac46, data); ++ data = ocp_reg_read(tp, 0xad30); ++ data &= ~0x0003; ++ data |= 0x0001; ++ ocp_reg_write(tp, 0xad30, data); ++ ++ // EEE parameter ++ ocp_reg_write(tp, 0xb87c, 0x80f5); ++ ocp_reg_write(tp, 0xb87e, 0x760e); ++ ocp_reg_write(tp, 0xb87c, 0x8107); ++ ocp_reg_write(tp, 0xb87e, 0x360E); ++ ocp_reg_write(tp, 0xb87c, 0x8551); ++ data = ocp_reg_read(tp, 0xb87e); ++ data &= ~0xff00; ++ data |= 0x0800; ++ ocp_reg_write(tp, 0xb87e, data); ++ ++ // ADC_PGA parameter ++ data = ocp_reg_read(tp, 0xbf00); ++ data &= ~0xe000; ++ data |= 0xa000; ++ ocp_reg_write(tp, 0xbf00, data); ++ data = ocp_reg_read(tp, 0xbf46); ++ data &= ~0x0f00; ++ data |= 0x0300; ++ ocp_reg_write(tp, 0xbf46, data); ++ ++ data = sram_read(tp, 0x8044); ++ data &= ~0xff00; ++ data |= 0x2400; ++ sram_write(tp, 0x8044, data); ++ data = sram_read(tp, 0x804a); ++ data &= ~0xff00; ++ data |= 0x2400; ++ sram_write(tp, 0x804a, data); ++ data = sram_read(tp, 0x8050); ++ data &= ~0xff00; ++ data |= 0x2400; ++ sram_write(tp, 0x8050, data); ++ data = sram_read(tp, 0x8056); ++ data &= ~0xff00; ++ data |= 0x2400; ++ sram_write(tp, 0x8056, data); ++ data = sram_read(tp, 0x805c); ++ data &= ~0xff00; ++ data |= 0x2400; ++ sram_write(tp, 0x805c, data); ++ data = sram_read(tp, 0x8062); ++ data &= ~0xff00; ++ data |= 0x2400; ++ sram_write(tp, 0x8062, data); ++ data = sram_read(tp, 0x8068); ++ data &= ~0xff00; ++ data |= 0x2400; ++ sram_write(tp, 0x8068, data); ++ data = sram_read(tp, 0x806e); ++ data &= ~0xff00; ++ data |= 0x2400; ++ sram_write(tp, 0x806e, data); ++ data = sram_read(tp, 0x8074); ++ data &= ~0xff00; ++ data |= 0x2400; ++ sram_write(tp, 0x8074, data); ++ data = sram_read(tp, 0x807a); ++ data &= ~0xff00; ++ data |= 0x2400; ++ sram_write(tp, 0x807a, data); + break; + default: + break; + } -+ -+ if (!pcut_entr) { -+ data = ocp_reg_read(tp, 0xa428); -+ data &= ~BIT(9); -+ ocp_reg_write(tp, 0xa428, data); -+ data = ocp_reg_read(tp, 0xa5ea); -+ data &= ~BIT(0); -+ ocp_reg_write(tp, 0xa5ea, data); -+ tp->ups_info.lite_mode = 0; -+ -+ if (tp->eee_en) { -+ r8156_eee_en(tp, true); -+ ocp_reg_write(tp, OCP_EEE_ADV, tp->eee_adv); -+ } -+ -+ r8153_aldps_en(tp, true); -+ r8152b_enable_fc(tp); -+ r8153_u2p3en(tp, true); -+ -+ set_bit(PHY_RESET, &tp->flags); + +- netif_device_detach(netdev); ++ if (r8153_patch_request(tp, true)) { ++ dev_err(&tp->intf->dev, "patch request fail\n"); ++ return; + } -+} + +- if (netif_running(netdev) && test_bit(WORK_ENABLE, &tp->flags)) { +- struct napi_struct *napi = &tp->napi; ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4); ++ ocp_data |= EEE_SPDWN_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ocp_data); + +- clear_bit(WORK_ENABLE, &tp->flags); +- usb_kill_urb(tp->intr_urb); +- napi_disable(napi); +- cancel_delayed_work_sync(&tp->schedule); +- tp->rtl_ops.down(tp); +- napi_enable(napi); +- } ++ data = ocp_reg_read(tp, OCP_DOWN_SPEED); ++ data &= ~(EN_EEE_100 | EN_EEE_1000); ++ data |= EN_10M_CLKDIV; ++ ocp_reg_write(tp, OCP_DOWN_SPEED, data); ++ tp->ups_info._10m_ckdiv = true; ++ tp->ups_info.eee_plloff_100 = false; ++ tp->ups_info.eee_plloff_giga = false; + +- return 0; +-} ++ data = ocp_reg_read(tp, OCP_POWER_CFG); ++ data &= ~EEE_CLKDIV_EN; ++ ocp_reg_write(tp, OCP_POWER_CFG, data); ++ tp->ups_info.eee_ckdiv = false; + +-static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message) +-{ +- struct r8152 *tp = usb_get_intfdata(intf); +- int ret; ++ r8153_patch_request(tp, false); + +- mutex_lock(&tp->control); ++ rtl_green_en(tp, true); + +- if (PMSG_IS_AUTO(message)) +- ret = rtl8152_runtime_suspend(tp); +- else +- ret = rtl8152_system_suspend(tp); ++ data = ocp_reg_read(tp, 0xa428); ++ data &= ~BIT(9); ++ ocp_reg_write(tp, 0xa428, data); ++ data = ocp_reg_read(tp, 0xa5ea); ++ data &= ~BIT(0); ++ ocp_reg_write(tp, 0xa5ea, data); ++ tp->ups_info.lite_mode = 0; + +- mutex_unlock(&tp->control); ++ if (tp->eee_en) ++ rtl_eee_enable(tp, true); + +- return ret; ++ r8153_aldps_en(tp, true); ++ r8152b_enable_fc(tp); ++ r8153_u2p3en(tp, true); + -+static void r8156_hw_phy_cfg(struct r8152 *tp) -+{ ++ set_bit(PHY_RESET, &tp->flags); + } + +-static int rtl8152_resume(struct usb_interface *intf) ++static void r8156_hw_phy_cfg_test(struct r8152 *tp) + { +- struct r8152 *tp = usb_get_intfdata(intf); +- int ret; + u32 ocp_data; + u16 data; -+ + +- mutex_lock(&tp->control); +- +- if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) +- ret = rtl8152_runtime_resume(tp); +- else +- ret = rtl8152_system_resume(tp); + data = r8153_phy_status(tp, PHY_STAT_LAN_ON); -+ + +- mutex_unlock(&tp->control); + /* disable ALDPS before updating the PHY parameters */ + r8153_aldps_en(tp, false); -+ + +- return ret; +-} + /* disable EEE before updating the PHY parameters */ + r8153_eee_en(tp, false); + ocp_reg_write(tp, OCP_EEE_ADV, 0); -+ + +-static int rtl8152_reset_resume(struct usb_interface *intf) +-{ +- struct r8152 *tp = usb_get_intfdata(intf); + r8156_firmware(tp); + + data = ocp_reg_read(tp, 0xa5d4); @@ -9046,32 +14949,37 @@ index 2490498b..26cc7c1a 100644 +// ocp_reg_write(tp, OCP_EEE_ADV, tp->eee_adv); +// } -- switch (tp->udev->speed) { -- case USB_SPEED_SUPER: -- case USB_SPEED_SUPER_PLUS: -- tp->coalesce = COALESCE_SUPER; -- break; -- case USB_SPEED_HIGH: -- tp->coalesce = COALESCE_HIGH; -- break; -- default: -- tp->coalesce = COALESCE_SLOW; -- break; -- } +- clear_bit(SELECTIVE_SUSPEND, &tp->flags); +- mutex_lock(&tp->control); +- tp->rtl_ops.init(tp); +- queue_delayed_work(system_long_wq, &tp->hw_phy_work, 0); +- mutex_unlock(&tp->control); +- return rtl8152_resume(intf); + r8153_aldps_en(tp, true); + r8152b_enable_fc(tp); + r8153_u2p3en(tp, true); } --static void r8153b_init(struct r8152 *tp) +-static void rtl8152_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +static void r8156_init(struct r8152 *tp) { - u32 ocp_data; - u16 data; -@@ -4181,6 +10825,16 @@ static void r8153b_init(struct r8152 *tp) - if (test_bit(RTL8152_UNPLUG, &tp->flags)) +- struct r8152 *tp = netdev_priv(dev); ++ u32 ocp_data; ++ u16 data; ++ int i; + +- if (usb_autopm_get_interface(tp->intf) < 0) ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) return; +- if (!rtl_can_wakeup(tp)) { +- wol->supported = 0; +- wol->wolopts = 0; +- } else { +- mutex_lock(&tp->control); +- wol->supported = WAKE_ANY; +- wol->wolopts = __rtl_get_wol(tp); +- mutex_unlock(&tp->control); + ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, 0xd26b); + ocp_data &= ~BIT(0); + ocp_write_byte(tp, MCU_TYPE_USB, 0xd26b, ocp_data); @@ -9082,213 +14990,738 @@ index 2490498b..26cc7c1a 100644 + ocp_data |= BIT(5); + ocp_write_word(tp, MCU_TYPE_USB, 0xcfee, ocp_data); + - r8153b_u1u2en(tp, false); - - for (i = 0; i < 500; i++) { -@@ -4191,6 +10845,11 @@ static void r8153b_init(struct r8152 *tp) ++ r8153b_u1u2en(tp, false); ++ ++ for (i = 0; i < 500; i++) { ++ if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & ++ AUTOLOAD_DONE) ++ break; ++ msleep(20); } - data = r8153_phy_status(tp, 0); +- usb_autopm_put_interface(tp->intf); +-} ++ data = r8153_phy_status(tp, 0); + if (data == PHY_STAT_EXT_INIT) { + data = ocp_reg_read(tp, 0xa468); -+ data &= ~(BIT(3) | BIT(0)); ++ data &= ~(BIT(3) | BIT(1)); + ocp_reg_write(tp, 0xa468, data); + } - data = r8152_mdio_read(tp, MII_BMCR); - if (data & BMCR_PDOWN) { -@@ -4209,29 +10868,51 @@ static void r8153b_init(struct r8152 *tp) - ocp_write_word(tp, MCU_TYPE_USB, USB_U1U2_TIMER, 500); +-static int rtl8152_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +-{ +- struct r8152 *tp = netdev_priv(dev); +- int ret; ++ data = r8152_mdio_read(tp, MII_BMCR); ++ if (data & BMCR_PDOWN) { ++ data &= ~BMCR_PDOWN; ++ r8152_mdio_write(tp, MII_BMCR, data); ++ } - r8153b_power_cut_en(tp, false); -- r8153b_ups_en(tp, false); -- r8153b_queue_wake(tp, false); +- if (!rtl_can_wakeup(tp)) +- return -EOPNOTSUPP; ++ data = r8153_phy_status(tp, PHY_STAT_LAN_ON); + +- if (wol->wolopts & ~WAKE_ANY) +- return -EINVAL; ++ r8153_u2p3en(tp, false); + +- ret = usb_autopm_get_interface(tp->intf); +- if (ret < 0) +- goto out_set_wol; ++ /* MSC timer = 0xfff * 8ms = 32760 ms */ ++ ocp_write_word(tp, MCU_TYPE_USB, USB_MSC_TIMER, 0x0fff); + +- mutex_lock(&tp->control); ++ /* U1/U2/L1 idle timer. 500 us */ ++ ocp_write_word(tp, MCU_TYPE_USB, USB_U1U2_TIMER, 500); + +- __rtl_set_wol(tp, wol->wolopts); +- tp->saved_wolopts = wol->wolopts & WAKE_ANY; ++ r8153b_power_cut_en(tp, false); + r8156_ups_en(tp, false); + r8153_queue_wake(tp, false); - rtl_runtime_suspend_enable(tp, false); ++ rtl_runtime_suspend_enable(tp, false); + +- mutex_unlock(&tp->control); ++ if (tp->udev->speed >= USB_SPEED_SUPER) ++ r8153b_u1u2en(tp, true); + +- usb_autopm_put_interface(tp->intf); ++ usb_enable_lpm(tp->udev); + +-out_set_wol: +- return ret; +-} ++// ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xd850) & 0xc000; ++// switch (ocp_data) { ++// case 0x4000: ++// tp->dash_mode = 1; ++// r8156_mac_clk_spd(tp, false); ++// break; ++// case 0x8000: ++// tp->dash_mode = 0; ++ r8156_mac_clk_spd(tp, true); ++// break; ++// default: ++// netif_warn(tp, drv, tp->netdev, "Invalid type %x\n", ocp_data); ++// break; ++// } ++ + - r8153b_u1u2en(tp, true); - usb_enable_lpm(tp->udev); - -- /* MAC clock speed down */ -- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2); -- ocp_data |= MAC_CLK_SPDWN_EN; -- ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, ocp_data); -+ r8156_mac_clk_spd(tp, true); - -- set_bit(GREEN_ETHERNET, &tp->flags); + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); -+ ocp_data &= ~BIT(14); ++ ocp_data &= ~PLA_MCU_SPDWN_EN; + ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data); + -+ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, 0xd398); ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS); + if (rtl8152_get_speed(tp) & LINK_STATUS) -+ ocp_data |= BIT(15); ++ ocp_data |= CUR_LINK_OK; + else -+ ocp_data &= ~BIT(15); -+ ocp_data &= ~BIT(8); -+ ocp_data |= BIT(0); -+ ocp_write_word(tp, MCU_TYPE_PLA, 0xd398, ocp_data); -+ ++ ocp_data &= ~CUR_LINK_OK; ++ /* r8153_queue_wake() has cleared this bit */ ++ /* ocp_data &= ~BIT(8); */ ++ ocp_data |= POLL_LINK_CHG; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, ocp_data); + +-static u32 rtl8152_get_msglevel(struct net_device *dev) +-{ +- struct r8152 *tp = netdev_priv(dev); +// set_bit(GREEN_ETHERNET, &tp->flags); - /* rx aggregation */ - ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); - ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); - ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); +- return tp->msg_enable; +-} ++ /* rx aggregation */ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); ++ ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); -+ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, 0xcfd9); +-static void rtl8152_set_msglevel(struct net_device *dev, u32 value) +-{ +- struct r8152 *tp = netdev_priv(dev); ++ /* Set Rx aggregation parameters to default value ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, 0xd4c9); + ocp_data |= BIT(2); -+ ocp_write_byte(tp, MCU_TYPE_USB, 0xcfd9, ocp_data); -+ - rtl_tally_reset(tp); ++ ocp_write_byte(tp, MCU_TYPE_USB, 0xd4c9, ocp_data); ++ */ - tp->coalesce = 15000; /* 15 us */ +- tp->msg_enable = value; +-} ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, 0xd4b4); ++ ocp_data |= BIT(1); ++ ocp_write_byte(tp, MCU_TYPE_USB, 0xd4b4, ocp_data); + +-static void rtl8152_get_drvinfo(struct net_device *netdev, +- struct ethtool_drvinfo *info) +-{ +- struct r8152 *tp = netdev_priv(netdev); ++ rtl_tally_reset(tp); + +- strlcpy(info->driver, MODULENAME, sizeof(info->driver)); +- strlcpy(info->version, DRIVER_VERSION, sizeof(info->version)); +- usb_make_path(tp->udev, info->bus_info, sizeof(info->bus_info)); ++ tp->coalesce = 15000; /* 15 us */ } +-static +-int rtl8152_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd) ++static void r8156b_init(struct r8152 *tp) + { +- struct r8152 *tp = netdev_priv(netdev); +- int ret; ++ u32 ocp_data; ++ u16 data; ++ int i; + +- if (!tp->mii.mdio_read) +- return -EOPNOTSUPP; ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return; + +- ret = usb_autopm_get_interface(tp->intf); +- if (ret < 0) +- goto out; ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, 0xd26b); ++ ocp_data &= ~BIT(0); ++ ocp_write_byte(tp, MCU_TYPE_USB, 0xd26b, ocp_data); + +- mutex_lock(&tp->control); ++ ocp_write_word(tp, MCU_TYPE_USB, 0xd32a, 0); + +- ret = mii_ethtool_gset(&tp->mii, cmd); ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xcfee); ++ ocp_data |= BIT(5); ++ ocp_write_word(tp, MCU_TYPE_USB, 0xcfee, ocp_data); + +- mutex_unlock(&tp->control); ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xb460); ++ ocp_data |= BIT(3); ++ ocp_write_word(tp, MCU_TYPE_USB, 0xb460, ocp_data); + +- usb_autopm_put_interface(tp->intf); ++ r8153b_u1u2en(tp, false); + +-out: +- return ret; +-} ++ for (i = 0; i < 500; i++) { ++ if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & ++ AUTOLOAD_DONE) ++ break; ++ msleep(20); ++ } + +-static int rtl8152_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +-{ +- struct r8152 *tp = netdev_priv(dev); +- int ret; ++ data = r8153_phy_status(tp, 0); ++ if (data == PHY_STAT_EXT_INIT) { ++ data = ocp_reg_read(tp, 0xa468); ++ data &= ~(BIT(3) | BIT(1)); ++ ocp_reg_write(tp, 0xa468, data); ++ ++ data = ocp_reg_read(tp, 0xa466); ++ data &= ~BIT(0); ++ ocp_reg_write(tp, 0xa466, data); ++ } + +- ret = usb_autopm_get_interface(tp->intf); +- if (ret < 0) +- goto out; ++ data = r8152_mdio_read(tp, MII_BMCR); ++ if (data & BMCR_PDOWN) { ++ data &= ~BMCR_PDOWN; ++ r8152_mdio_write(tp, MII_BMCR, data); ++ } + +- mutex_lock(&tp->control); ++ data = r8153_phy_status(tp, PHY_STAT_LAN_ON); + +- ret = rtl8152_set_speed(tp, cmd->autoneg, cmd->speed, cmd->duplex); +- if (!ret) { +- tp->autoneg = cmd->autoneg; +- tp->speed = cmd->speed; +- tp->duplex = cmd->duplex; +- } ++ r8153_u2p3en(tp, false); + +- mutex_unlock(&tp->control); ++ /* MSC timer = 0xfff * 8ms = 32760 ms */ ++ ocp_write_word(tp, MCU_TYPE_USB, USB_MSC_TIMER, 0x0fff); + +- usb_autopm_put_interface(tp->intf); ++ /* U1/U2/L1 idle timer. 500 us */ ++ ocp_write_word(tp, MCU_TYPE_USB, USB_U1U2_TIMER, 500); + +-out: +- return ret; +-} ++ r8153b_power_cut_en(tp, false); ++ r8156_ups_en(tp, false); ++ r8153_queue_wake(tp, false); ++ rtl_runtime_suspend_enable(tp, false); + +-static const char rtl8152_gstrings[][ETH_GSTRING_LEN] = { +- "tx_packets", +- "rx_packets", +- "tx_errors", +- "rx_errors", +- "rx_missed", +- "align_errors", +- "tx_single_collisions", +- "tx_multi_collisions", +- "rx_unicast", +- "rx_broadcast", +- "rx_multicast", +- "tx_aborted", +- "tx_underrun", +-}; ++ if (tp->udev->speed >= USB_SPEED_SUPER) ++ r8153b_u1u2en(tp, true); + +-static int rtl8152_get_sset_count(struct net_device *dev, int sset) +-{ +- switch (sset) { +- case ETH_SS_STATS: +- return ARRAY_SIZE(rtl8152_gstrings); +- default: +- return -EOPNOTSUPP; ++ usb_enable_lpm(tp->udev); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, 0xc010); ++ ocp_data &= ~BIT(11); ++ ocp_write_word(tp, MCU_TYPE_PLA, 0xc010, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, 0xe854); ++ ocp_data |= BIT(0); ++ ocp_write_word(tp, MCU_TYPE_PLA, 0xe854, ocp_data); ++ ++ /* enable fc timer and set timer to 600 ms. */ ++ ocp_write_word(tp, MCU_TYPE_USB, USB_FC_TIMER, ++ CTRL_TIMER_EN | (600 / 8)); ++ ++ if (!(ocp_read_byte(tp, MCU_TYPE_PLA, 0xdc6b) & BIT(7))) { ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, 0xd334); ++ ocp_data |= BIT(1) | BIT(8); ++ ocp_data &= ~BIT(3); ++ ocp_write_word(tp, MCU_TYPE_PLA, 0xd334, ocp_data); + } +-} + +-static void rtl8152_get_ethtool_stats(struct net_device *dev, +- struct ethtool_stats *stats, u64 *data) +-{ +- struct r8152 *tp = netdev_priv(dev); +- struct tally_counter tally; ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, 0xd4e8); ++ ocp_data |= BIT(1); ++ ocp_write_word(tp, MCU_TYPE_PLA, 0xd4e8, ocp_data); + +- if (usb_autopm_get_interface(tp->intf) < 0) +- return; ++ r8156b_mac_clk_spd(tp, true); + +- generic_ocp_read(tp, PLA_TALLYCNT, sizeof(tally), &tally, MCU_TYPE_PLA); ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); ++ ocp_data &= ~PLA_MCU_SPDWN_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data); + +- usb_autopm_put_interface(tp->intf); ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS); ++ if (rtl8152_get_speed(tp) & LINK_STATUS) ++ ocp_data |= CUR_LINK_OK; ++ else ++ ocp_data &= ~CUR_LINK_OK; ++ /* r8153_queue_wake() has cleared this bit */ ++ /* ocp_data &= ~BIT(8); */ ++ ocp_data |= POLL_LINK_CHG; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, ocp_data); + +- data[0] = le64_to_cpu(tally.tx_packets); +- data[1] = le64_to_cpu(tally.rx_packets); +- data[2] = le64_to_cpu(tally.tx_errors); +- data[3] = le32_to_cpu(tally.rx_errors); +- data[4] = le16_to_cpu(tally.rx_missed); +- data[5] = le16_to_cpu(tally.align_errors); +- data[6] = le32_to_cpu(tally.tx_one_collision); +- data[7] = le32_to_cpu(tally.tx_multi_collision); +- data[8] = le64_to_cpu(tally.rx_unicast); +- data[9] = le64_to_cpu(tally.rx_broadcast); +- data[10] = le32_to_cpu(tally.rx_multicast); +- data[11] = le16_to_cpu(tally.tx_aborted); +- data[12] = le16_to_cpu(tally.tx_underrun); ++// set_bit(GREEN_ETHERNET, &tp->flags); ++ ++ /* rx aggregation */ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); ++ ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); ++ ++ /* Set Rx aggregation parameters to default value ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, 0xd4c9); ++ ocp_data |= BIT(2); ++ ocp_write_byte(tp, MCU_TYPE_USB, 0xd4c9, ocp_data); ++ */ ++ ++ rtl_tally_reset(tp); ++ ++ tp->coalesce = 15000; /* 15 us */ + } + +-static void rtl8152_get_strings(struct net_device *dev, u32 stringset, u8 *data) +static bool rtl_vendor_mode(struct usb_interface *intf) -+{ + { +- switch (stringset) { +- case ETH_SS_STATS: +- memcpy(data, *rtl8152_gstrings, sizeof(rtl8152_gstrings)); + struct usb_host_interface *alt = intf->cur_altsetting; + + return alt->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC; +} + - static int rtl8152_pre_reset(struct usb_interface *intf) - { - struct r8152 *tp = usb_get_intfdata(intf); -@@ -4245,8 +10926,11 @@ static int rtl8152_pre_reset(struct usb_interface *intf) - return 0; - - netif_stop_queue(netdev); ++static int rtl8152_pre_reset(struct usb_interface *intf) ++{ ++ struct r8152 *tp = usb_get_intfdata(intf); ++ struct net_device *netdev; ++ ++ if (!tp) ++ return 0; ++ ++ netdev = tp->netdev; ++ if (!netif_running(netdev)) ++ return 0; ++ ++ netif_stop_queue(netdev); + tasklet_disable(&tp->tx_tl); - napi_disable(&tp->napi); + smp_mb__before_atomic(); - clear_bit(WORK_ENABLE, &tp->flags); ++ clear_bit(WORK_ENABLE, &tp->flags); + smp_mb__after_atomic(); - usb_kill_urb(tp->intr_urb); - cancel_delayed_work_sync(&tp->schedule); - if (netif_carrier_ok(netdev)) { -@@ -4270,16 +10954,19 @@ static int rtl8152_post_reset(struct usb_interface *intf) - if (!netif_running(netdev)) - return 0; - ++ usb_kill_urb(tp->intr_urb); ++ cancel_delayed_work_sync(&tp->schedule); ++ napi_disable(&tp->napi); ++ if (netif_carrier_ok(netdev)) { ++ mutex_lock(&tp->control); ++ tp->rtl_ops.disable(tp); ++ mutex_unlock(&tp->control); ++ } ++ ++ return 0; ++} ++ ++static int rtl8152_post_reset(struct usb_interface *intf) ++{ ++ struct r8152 *tp = usb_get_intfdata(intf); ++ struct net_device *netdev; ++ struct sockaddr sa; ++ ++ if (!tp) ++ return 0; ++ ++ /* reset the MAC adddress in case of policy change */ ++ if (determine_ethernet_addr(tp, &sa) >= 0) { ++ rtnl_lock(); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0) ++ dev_set_mac_address(tp->netdev, &sa); ++#else ++ dev_set_mac_address(tp->netdev, &sa, NULL); ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0) */ ++ rtnl_unlock(); ++ } ++ ++ netdev = tp->netdev; ++ if (!netif_running(netdev)) ++ return 0; ++ + smp_mb__before_atomic(); - set_bit(WORK_ENABLE, &tp->flags); ++ set_bit(WORK_ENABLE, &tp->flags); + smp_mb__after_atomic(); - if (netif_carrier_ok(netdev)) { - mutex_lock(&tp->control); - tp->rtl_ops.enable(tp); - rtl_start_rx(tp); -- _rtl8152_set_rx_mode(netdev); ++ if (netif_carrier_ok(netdev)) { ++ mutex_lock(&tp->control); ++ tp->rtl_ops.enable(tp); ++ rtl_start_rx(tp); + rtl8152_set_rx_mode(netdev); - mutex_unlock(&tp->control); - } - - napi_enable(&tp->napi); ++ mutex_unlock(&tp->control); ++ } ++ ++ napi_enable(&tp->napi); + tasklet_enable(&tp->tx_tl); - netif_wake_queue(netdev); - usb_submit_urb(tp->intr_urb, GFP_KERNEL); - -@@ -4321,7 +11008,9 @@ static int rtl8152_runtime_resume(struct r8152 *tp) - - tp->rtl_ops.autosuspend_en(tp, false); - napi_disable(napi); ++ netif_wake_queue(netdev); ++ usb_submit_urb(tp->intr_urb, GFP_KERNEL); ++ ++ if (!list_empty(&tp->rx_done)) ++ napi_schedule(&tp->napi); ++ ++ return 0; ++} ++ ++static bool delay_autosuspend(struct r8152 *tp) ++{ ++ bool sw_linking = !!netif_carrier_ok(tp->netdev); ++ bool hw_linking = !!(rtl8152_get_speed(tp) & LINK_STATUS); ++ ++ /* This means a linking change occurs and the driver doesn't detect it, ++ * yet. If the driver has disabled tx/rx and hw is linking on, the ++ * device wouldn't wake up by receiving any packet. ++ */ ++ if (work_busy(&tp->schedule.work) || sw_linking != hw_linking) ++ return true; ++ ++ /* If the linking down is occurred by nway, the device may miss the ++ * linking change event. And it wouldn't wake when linking on. ++ */ ++ if (!sw_linking && tp->rtl_ops.in_nway(tp)) ++ return true; ++ else if (!skb_queue_empty(&tp->tx_queue)) ++ return true; ++ else ++ return false; ++} ++ ++static int rtl8152_runtime_resume(struct r8152 *tp) ++{ ++ struct net_device *netdev = tp->netdev; ++ ++ if (netif_running(netdev) && netdev->flags & IFF_UP) { ++ struct napi_struct *napi = &tp->napi; ++ ++ tp->rtl_ops.autosuspend_en(tp, false); ++ napi_disable(napi); + smp_mb__before_atomic(); - set_bit(WORK_ENABLE, &tp->flags); ++ set_bit(WORK_ENABLE, &tp->flags); + smp_mb__after_atomic(); - - if (netif_carrier_ok(netdev)) { - if (rtl8152_get_speed(tp) & LINK_STATUS) { -@@ -4337,8 +11026,11 @@ static int rtl8152_runtime_resume(struct r8152 *tp) - clear_bit(SELECTIVE_SUSPEND, &tp->flags); - smp_mb__after_atomic(); - -- if (!list_empty(&tp->rx_done)) ++ ++ if (netif_carrier_ok(netdev)) { ++ if (rtl8152_get_speed(tp) & LINK_STATUS) { ++ rtl_start_rx(tp); ++ } else { ++ netif_carrier_off(netdev); ++ tp->rtl_ops.disable(tp); ++ netif_info(tp, link, netdev, "linking down\n"); ++ } ++ } ++ ++ napi_enable(napi); ++ clear_bit(SELECTIVE_SUSPEND, &tp->flags); ++ smp_mb__after_atomic(); ++ + if (!list_empty(&tp->rx_done)) { + local_bh_disable(); - napi_schedule(&tp->napi); ++ napi_schedule(&tp->napi); + local_bh_enable(); + } - - usb_submit_urb(tp->intr_urb, GFP_NOIO); - } else { -@@ -4346,6 +11038,7 @@ static int rtl8152_runtime_resume(struct r8152 *tp) - tp->rtl_ops.autosuspend_en(tp, false); - - clear_bit(SELECTIVE_SUSPEND, &tp->flags); ++ ++ usb_submit_urb(tp->intr_urb, GFP_NOIO); ++ } else { ++ if (netdev->flags & IFF_UP) ++ tp->rtl_ops.autosuspend_en(tp, false); ++ ++ clear_bit(SELECTIVE_SUSPEND, &tp->flags); + smp_mb__after_atomic(); - } - - return 0; -@@ -4357,10 +11050,15 @@ static int rtl8152_system_resume(struct r8152 *tp) - - netif_device_attach(netdev); - -- if (netif_running(netdev) && netdev->flags & IFF_UP) { ++ } ++ ++ return 0; ++} ++ ++static int rtl8152_system_resume(struct r8152 *tp) ++{ ++ struct net_device *netdev = tp->netdev; ++ ++ netif_device_attach(netdev); ++ + if (netif_running(netdev) && (netdev->flags & IFF_UP)) { - tp->rtl_ops.up(tp); - netif_carrier_off(netdev); ++ tp->rtl_ops.up(tp); ++ netif_carrier_off(netdev); + smp_mb__before_atomic(); - set_bit(WORK_ENABLE, &tp->flags); ++ set_bit(WORK_ENABLE, &tp->flags); + smp_mb__after_atomic(); + if (test_and_clear_bit(RECOVER_SPEED, &tp->flags)) + rtl8152_set_speed(tp, tp->autoneg, tp->speed, + tp->duplex, tp->advertising); - usb_submit_urb(tp->intr_urb, GFP_NOIO); - } - -@@ -4372,6 +11070,9 @@ static int rtl8152_runtime_suspend(struct r8152 *tp) - struct net_device *netdev = tp->netdev; - int ret = 0; - ++ usb_submit_urb(tp->intr_urb, GFP_NOIO); ++ } ++ ++ return 0; ++} ++ ++static int rtl8152_runtime_suspend(struct r8152 *tp) ++{ ++ struct net_device *netdev = tp->netdev; ++ int ret = 0; ++ + if (!tp->rtl_ops.autosuspend_en) + return -EBUSY; + - set_bit(SELECTIVE_SUSPEND, &tp->flags); - smp_mb__after_atomic(); - -@@ -4397,7 +11098,9 @@ static int rtl8152_runtime_suspend(struct r8152 *tp) - } - } - ++ set_bit(SELECTIVE_SUSPEND, &tp->flags); ++ smp_mb__after_atomic(); ++ ++ if (netif_running(netdev) && test_bit(WORK_ENABLE, &tp->flags)) { ++ u32 rcr = 0; ++ ++ if (netif_carrier_ok(netdev)) { ++ u32 ocp_data; ++ ++ rcr = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); ++ ocp_data = rcr & ~RCR_ACPT_ALL; ++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); ++ rxdy_gated_en(tp, true); ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, ++ PLA_OOB_CTRL); ++ if (!(ocp_data & RXFIFO_EMPTY)) { ++ rxdy_gated_en(tp, false); ++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, rcr); ++ clear_bit(SELECTIVE_SUSPEND, &tp->flags); ++ smp_mb__after_atomic(); ++ ret = -EBUSY; ++ goto out1; ++ } ++ } ++ + smp_mb__before_atomic(); - clear_bit(WORK_ENABLE, &tp->flags); ++ clear_bit(WORK_ENABLE, &tp->flags); + smp_mb__after_atomic(); - usb_kill_urb(tp->intr_urb); - - tp->rtl_ops.autosuspend_en(tp, true); -@@ -4431,12 +11134,16 @@ static int rtl8152_system_suspend(struct r8152 *tp) - if (netif_running(netdev) && test_bit(WORK_ENABLE, &tp->flags)) { - struct napi_struct *napi = &tp->napi; - ++ usb_kill_urb(tp->intr_urb); ++ ++ tp->rtl_ops.autosuspend_en(tp, true); ++ ++ if (netif_carrier_ok(netdev)) { ++ struct napi_struct *napi = &tp->napi; ++ ++ napi_disable(napi); ++ rtl_stop_rx(tp); ++ rxdy_gated_en(tp, false); ++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, rcr); ++ napi_enable(napi); ++ } ++ ++ if (delay_autosuspend(tp)) { ++ rtl8152_runtime_resume(tp); ++ ret = -EBUSY; ++ } ++ } ++ ++out1: ++ return ret; ++} ++ ++static int rtl8152_system_suspend(struct r8152 *tp) ++{ ++ struct net_device *netdev = tp->netdev; ++ ++ netif_device_detach(netdev); ++ ++ if (netif_running(netdev) && test_bit(WORK_ENABLE, &tp->flags)) { ++ struct napi_struct *napi = &tp->napi; ++ + smp_mb__before_atomic(); - clear_bit(WORK_ENABLE, &tp->flags); ++ clear_bit(WORK_ENABLE, &tp->flags); + smp_mb__after_atomic(); - usb_kill_urb(tp->intr_urb); ++ usb_kill_urb(tp->intr_urb); + tasklet_disable(&tp->tx_tl); - napi_disable(napi); - cancel_delayed_work_sync(&tp->schedule); - tp->rtl_ops.down(tp); - napi_enable(napi); ++ napi_disable(napi); ++ cancel_delayed_work_sync(&tp->schedule); ++ tp->rtl_ops.down(tp); ++ ++ if (tp->version == RTL_VER_01) ++ rtl8152_set_speed(tp, AUTONEG_ENABLE, 0, 0, 3); ++ else ++ rtl_speed_down(tp); ++ ++ napi_enable(napi); + tasklet_enable(&tp->tx_tl); - } - - return 0; -@@ -4564,18 +11271,125 @@ static - int rtl8152_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd) - { - struct r8152 *tp = netdev_priv(netdev); -- int ret; -- -- if (!tp->mii.mdio_read) -- return -EOPNOTSUPP; ++ } ++ ++ return 0; ++} ++ ++static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message) ++{ ++ struct r8152 *tp = usb_get_intfdata(intf); ++ int ret; ++ ++ mutex_lock(&tp->control); ++ ++ if (PMSG_IS_AUTO(message)) ++ ret = rtl8152_runtime_suspend(tp); ++ else ++ ret = rtl8152_system_suspend(tp); ++ ++ mutex_unlock(&tp->control); ++ ++ return ret; ++} ++ ++static int rtl8152_resume(struct usb_interface *intf) ++{ ++ struct r8152 *tp = usb_get_intfdata(intf); ++ int ret; ++ ++ mutex_lock(&tp->control); ++ ++ if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) ++ ret = rtl8152_runtime_resume(tp); ++ else ++ ret = rtl8152_system_resume(tp); ++ ++ mutex_unlock(&tp->control); ++ ++ return ret; ++} ++ ++static int rtl8152_reset_resume(struct usb_interface *intf) ++{ ++ struct r8152 *tp = usb_get_intfdata(intf); ++ ++ clear_bit(SELECTIVE_SUSPEND, &tp->flags); ++ tp->rtl_ops.init(tp); ++ queue_delayed_work(system_long_wq, &tp->hw_phy_work, 0); ++ set_ethernet_addr(tp); ++ return rtl8152_resume(intf); ++} ++ ++static void rtl8152_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) ++{ ++ struct r8152 *tp = netdev_priv(dev); ++ ++ if (usb_autopm_get_interface(tp->intf) < 0) ++ return; ++ ++ if (!rtl_can_wakeup(tp)) { ++ wol->supported = 0; ++ wol->wolopts = 0; ++ } else { ++ mutex_lock(&tp->control); ++ wol->supported = WAKE_ANY; ++ wol->wolopts = __rtl_get_wol(tp); ++ mutex_unlock(&tp->control); ++ } ++ ++ usb_autopm_put_interface(tp->intf); ++} ++ ++static int rtl8152_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) ++{ ++ struct r8152 *tp = netdev_priv(dev); ++ int ret; ++ ++ if (!rtl_can_wakeup(tp)) ++ return -EOPNOTSUPP; ++ ++ if (wol->wolopts & ~WAKE_ANY) ++ return -EINVAL; ++ ++ ret = usb_autopm_get_interface(tp->intf); ++ if (ret < 0) ++ goto out_set_wol; ++ ++ mutex_lock(&tp->control); ++ ++ __rtl_set_wol(tp, wol->wolopts); ++ tp->saved_wolopts = wol->wolopts & WAKE_ANY; ++ ++ mutex_unlock(&tp->control); ++ ++ usb_autopm_put_interface(tp->intf); ++ ++out_set_wol: ++ return ret; ++} ++ ++static u32 rtl8152_get_msglevel(struct net_device *dev) ++{ ++ struct r8152 *tp = netdev_priv(dev); ++ ++ return tp->msg_enable; ++} ++ ++static void rtl8152_set_msglevel(struct net_device *dev, u32 value) ++{ ++ struct r8152 *tp = netdev_priv(dev); ++ ++ tp->msg_enable = value; ++} ++ ++static void rtl8152_get_drvinfo(struct net_device *netdev, ++ struct ethtool_drvinfo *info) ++{ ++ struct r8152 *tp = netdev_priv(netdev); ++ ++ strlcpy(info->driver, MODULENAME, sizeof(info->driver)); ++ strlcpy(info->version, DRIVER_VERSION, sizeof(info->version)); ++ usb_make_path(tp->udev, info->bus_info, sizeof(info->bus_info)); ++} ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4,20,0) ++static ++int rtl8152_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd) ++{ ++ struct r8152 *tp = netdev_priv(netdev); + u16 bmcr, bmsr; + int ret, advert; - - ret = usb_autopm_get_interface(tp->intf); - if (ret < 0) - goto out; - ++ ++ ret = usb_autopm_get_interface(tp->intf); ++ if (ret < 0) ++ goto out; ++ + cmd->supported = + (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | @@ -9305,9 +15738,8 @@ index 2490498b..26cc7c1a 100644 +#endif + cmd->advertising = ADVERTISED_MII; + - mutex_lock(&tp->control); - -- ret = mii_ethtool_gset(&tp->mii, cmd); ++ mutex_lock(&tp->control); ++ + bmcr = r8152_mdio_read(tp, MII_BMCR); + bmsr = r8152_mdio_read(tp, MII_BMSR); + @@ -9329,7 +15761,7 @@ index 2490498b..26cc7c1a 100644 + + cmd->supported |= SUPPORTED_1000baseT_Full; + -+ if (test_bit(SUPPORT_2500FULL, &tp->flags)) { ++ if (tp->support_2500full) { + u16 data = ocp_reg_read(tp, 0xa5d4); + + cmd->supported |= SUPPORTED_2500baseX_Full; @@ -9393,8 +15825,7 @@ index 2490498b..26cc7c1a 100644 + cmd->speed = SPEED_10; + else if (tp->mii.supports_gmii && (speed & _1000bps)) + cmd->speed = SPEED_1000; -+ else if (test_bit(SUPPORT_2500FULL, &tp->flags) && -+ (speed & _2500bps)) ++ else if (tp->support_2500full && (speed & _2500bps)) + cmd->speed = SPEED_2500; + + cmd->duplex = (speed & FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF; @@ -9402,29 +15833,49 @@ index 2490498b..26cc7c1a 100644 + cmd->speed = SPEED_UNKNOWN; + cmd->duplex = DUPLEX_UNKNOWN; + } - - mutex_unlock(&tp->control); - -@@ -4585,6 +11399,7 @@ out: - return ret; - } - -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,20,0) - static int rtl8152_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) - { - struct r8152 *tp = netdev_priv(dev); -@@ -4596,11 +11411,79 @@ static int rtl8152_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) - - mutex_lock(&tp->control); - -- ret = rtl8152_set_speed(tp, cmd->autoneg, cmd->speed, cmd->duplex); ++ ++ mutex_unlock(&tp->control); ++ ++ usb_autopm_put_interface(tp->intf); ++ ++out: ++ return ret; ++} ++ ++static int rtl8152_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) ++{ ++ struct r8152 *tp = netdev_priv(dev); ++ u32 advertising = 0; ++ int ret; ++ ++ ret = usb_autopm_get_interface(tp->intf); ++ if (ret < 0) ++ goto out; ++ ++ if (cmd->advertising & ADVERTISED_10baseT_Half) ++ advertising |= RTL_ADVERTISED_10_HALF; ++ if (cmd->advertising & ADVERTISED_10baseT_Full) ++ advertising |= RTL_ADVERTISED_10_FULL; ++ if (cmd->advertising & ADVERTISED_100baseT_Half) ++ advertising |= RTL_ADVERTISED_100_HALF; ++ if (cmd->advertising & ADVERTISED_100baseT_Full) ++ advertising |= RTL_ADVERTISED_100_FULL; ++ if (cmd->advertising & ADVERTISED_1000baseT_Half) ++ advertising |= RTL_ADVERTISED_1000_HALF; ++ if (cmd->advertising & ADVERTISED_1000baseT_Full) ++ advertising |= RTL_ADVERTISED_1000_FULL; ++ if (cmd->advertising & ADVERTISED_2500baseX_Full) ++ advertising |= RTL_ADVERTISED_2500_FULL; ++ ++ mutex_lock(&tp->control); ++ + ret = rtl8152_set_speed(tp, cmd->autoneg, cmd->speed, cmd->duplex, -+ cmd->advertising); - if (!ret) { - tp->autoneg = cmd->autoneg; - tp->speed = cmd->speed; - tp->duplex = cmd->duplex; -+ tp->advertising = cmd->advertising; ++ advertising); ++ if (!ret) { ++ tp->autoneg = cmd->autoneg; ++ tp->speed = cmd->speed; ++ tp->duplex = cmd->duplex; ++ tp->advertising = advertising; + } + + mutex_unlock(&tp->control); @@ -9440,31 +15891,147 @@ index 2490498b..26cc7c1a 100644 +static int rtl8152_get_link_ksettings(struct net_device *netdev, + struct ethtool_link_ksettings *cmd) +{ -+ struct ethtool_cmd ecmd; ++ struct r8152 *tp = netdev_priv(netdev); ++ u16 bmcr, bmsr, advert; + int ret; + -+ memset(&ecmd, 0, sizeof(ecmd)); -+ ret = rtl8152_get_settings(netdev, &ecmd); ++ ret = usb_autopm_get_interface(tp->intf); + if (ret < 0) -+ goto out; ++ goto out1; + + /* only supports twisted-pair */ -+ cmd->base.port = ecmd.port; ++ cmd->base.port = PORT_MII; + -+ cmd->base.phy_address = ecmd.phy_address; -+ cmd->base.mdio_support = ecmd.mdio_support; -+ cmd->base.autoneg = ecmd.autoneg; -+ cmd->base.speed = ecmd.speed; -+ cmd->base.duplex = ecmd.duplex; ++ /* this isn't fully supported at higher layers */ ++ cmd->base.phy_address = 32; ++ cmd->base.mdio_support = ETH_MDIO_SUPPORTS_C22; + -+ ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported, -+ ecmd.supported); -+ ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising, -+ ecmd.advertising); -+ ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.lp_advertising, -+ ecmd.lp_advertising); ++ linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, ++ cmd->link_modes.supported); ++ linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, ++ cmd->link_modes.supported); ++ linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, ++ cmd->link_modes.supported); ++ linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, ++ cmd->link_modes.supported); ++ linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, ++ cmd->link_modes.supported); ++ linkmode_set_bit(ETHTOOL_LINK_MODE_MII_BIT, ++ cmd->link_modes.supported); ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, ++ cmd->link_modes.supported, tp->mii.supports_gmii); ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, ++ cmd->link_modes.supported, tp->support_2500full); + -+out: ++ ret = mutex_lock_interruptible(&tp->control); ++ if (ret < 0) ++ goto out2; ++ ++ bmcr = r8152_mdio_read(tp, MII_BMCR); ++ bmsr = r8152_mdio_read(tp, MII_BMSR); ++ ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, ++ cmd->link_modes.advertising, bmcr & BMCR_ANENABLE); ++ ++ if (bmcr & BMCR_ANENABLE) ++ cmd->base.autoneg = AUTONEG_ENABLE; ++ else ++ cmd->base.autoneg = AUTONEG_DISABLE; ++ ++ advert = r8152_mdio_read(tp, MII_ADVERTISE); ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, ++ cmd->link_modes.advertising, ++ advert & ADVERTISE_10HALF); ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, ++ cmd->link_modes.advertising, ++ advert & ADVERTISE_10FULL); ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, ++ cmd->link_modes.advertising, ++ advert & ADVERTISE_100HALF); ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, ++ cmd->link_modes.advertising, ++ advert & ADVERTISE_100FULL); ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT, ++ cmd->link_modes.advertising, ++ advert & ADVERTISE_PAUSE_CAP); ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, ++ cmd->link_modes.advertising, ++ advert & ADVERTISE_PAUSE_ASYM); ++ ++ if (tp->mii.supports_gmii) { ++ u16 ctrl1000 = r8152_mdio_read(tp, MII_CTRL1000); ++ ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, ++ cmd->link_modes.advertising, ++ ctrl1000 & ADVERTISE_1000HALF); ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, ++ cmd->link_modes.advertising, ++ ctrl1000 & ADVERTISE_1000FULL); ++ ++ if (tp->support_2500full) { ++ u16 data = ocp_reg_read(tp, 0xa5d4); ++ ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, ++ cmd->link_modes.advertising, ++ data & BIT(7)); ++ } ++ } ++ ++ if (bmsr & BMSR_ANEGCOMPLETE) { ++ advert = r8152_mdio_read(tp, MII_LPA); ++ ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, ++ cmd->link_modes.lp_advertising, ++ advert & LPA_LPACK); ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, ++ cmd->link_modes.lp_advertising, ++ advert & ADVERTISE_10HALF); ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, ++ cmd->link_modes.lp_advertising, ++ advert & ADVERTISE_10FULL); ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, ++ cmd->link_modes.lp_advertising, ++ advert & ADVERTISE_100HALF); ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, ++ cmd->link_modes.lp_advertising, ++ advert & ADVERTISE_100FULL); ++ ++ if (tp->mii.supports_gmii) { ++ u16 stat1000 = r8152_mdio_read(tp, MII_STAT1000); ++ ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, ++ cmd->link_modes.lp_advertising, ++ stat1000 & LPA_1000HALF); ++ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, ++ cmd->link_modes.lp_advertising, ++ stat1000 & LPA_1000FULL); ++ } ++ } ++ ++ if (netif_running(netdev) && netif_carrier_ok(netdev)) { ++ u16 speed = rtl8152_get_speed(tp); ++ ++ if (speed & _100bps) ++ cmd->base.speed = SPEED_100; ++ else if (speed & _10bps) ++ cmd->base.speed = SPEED_10; ++ else if (tp->mii.supports_gmii && (speed & _1000bps)) ++ cmd->base.speed = SPEED_1000; ++ else if (tp->support_2500full && (speed & _2500bps)) ++ cmd->base.speed = SPEED_2500; ++ ++ cmd->base.duplex = (speed & FULL_DUP) ? DUPLEX_FULL : ++ DUPLEX_HALF; ++ } else { ++ cmd->base.speed = SPEED_UNKNOWN; ++ cmd->base.duplex = DUPLEX_UNKNOWN; ++ } ++ ++ mutex_unlock(&tp->control); ++ ++out2: ++ usb_autopm_put_interface(tp->intf); ++out1: + return ret; +} + @@ -9472,17 +16039,42 @@ index 2490498b..26cc7c1a 100644 + const struct ethtool_link_ksettings *cmd) +{ + struct r8152 *tp = netdev_priv(dev); -+ u32 advertising; ++ u32 advertising = 0; + int ret; + + ret = usb_autopm_get_interface(tp->intf); + if (ret < 0) + goto out; + -+ mutex_lock(&tp->control); ++ if (test_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, ++ cmd->link_modes.advertising)) ++ advertising |= RTL_ADVERTISED_10_HALF; + -+ ethtool_convert_link_mode_to_legacy_u32(&advertising, -+ cmd->link_modes.advertising); ++ if (test_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, ++ cmd->link_modes.advertising)) ++ advertising |= RTL_ADVERTISED_10_FULL; ++ ++ if (test_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, ++ cmd->link_modes.advertising)) ++ advertising |= RTL_ADVERTISED_100_HALF; ++ ++ if (test_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, ++ cmd->link_modes.advertising)) ++ advertising |= RTL_ADVERTISED_100_FULL; ++ ++ if (test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, ++ cmd->link_modes.advertising)) ++ advertising |= RTL_ADVERTISED_1000_HALF; ++ ++ if (test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, ++ cmd->link_modes.advertising)) ++ advertising |= RTL_ADVERTISED_1000_FULL; ++ ++ if (test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, ++ cmd->link_modes.advertising)) ++ advertising |= RTL_ADVERTISED_2500_FULL; ++ ++ mutex_lock(&tp->control); + + ret = rtl8152_set_speed(tp, cmd->base.autoneg, cmd->base.speed, + cmd->base.duplex, advertising); @@ -9491,235 +16083,270 @@ index 2490498b..26cc7c1a 100644 + tp->speed = cmd->base.speed; + tp->duplex = cmd->base.duplex; + tp->advertising = advertising; - } - - mutex_unlock(&tp->control); -@@ -4610,6 +11493,7 @@ static int rtl8152_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) - out: - return ret; - } ++ } ++ ++ mutex_unlock(&tp->control); ++ ++ usb_autopm_put_interface(tp->intf); ++ ++out: ++ return ret; ++} +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0) */ - - static const char rtl8152_gstrings[][ETH_GSTRING_LEN] = { - "tx_packets", -@@ -4627,6 +11511,12 @@ static const char rtl8152_gstrings[][ETH_GSTRING_LEN] = { - "tx_underrun", - }; - ++ ++static const char rtl8152_gstrings[][ETH_GSTRING_LEN] = { ++ "tx_packets", ++ "rx_packets", ++ "tx_errors", ++ "rx_errors", ++ "rx_missed", ++ "align_errors", ++ "tx_single_collisions", ++ "tx_multi_collisions", ++ "rx_unicast", ++ "rx_broadcast", ++ "rx_multicast", ++ "tx_aborted", ++ "tx_underrun", ++}; ++ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) +static int rtl8152_get_sset_count(struct net_device *dev) +{ + return ARRAY_SIZE(rtl8152_gstrings); +} +#else - static int rtl8152_get_sset_count(struct net_device *dev, int sset) - { - switch (sset) { -@@ -4636,6 +11526,7 @@ static int rtl8152_get_sset_count(struct net_device *dev, int sset) - return -EOPNOTSUPP; - } - } ++static int rtl8152_get_sset_count(struct net_device *dev, int sset) ++{ ++ switch (sset) { ++ case ETH_SS_STATS: ++ return ARRAY_SIZE(rtl8152_gstrings); ++ default: ++ return -EOPNOTSUPP; ++ } ++} +#endif - - static void rtl8152_get_ethtool_stats(struct net_device *dev, - struct ethtool_stats *stats, u64 *data) -@@ -4646,8 +11537,15 @@ static void rtl8152_get_ethtool_stats(struct net_device *dev, - if (usb_autopm_get_interface(tp->intf) < 0) - return; - ++ ++static void rtl8152_get_ethtool_stats(struct net_device *dev, ++ struct ethtool_stats *stats, u64 *data) ++{ ++ struct r8152 *tp = netdev_priv(dev); ++ struct tally_counter tally; ++ ++ if (usb_autopm_get_interface(tp->intf) < 0) ++ return; ++ + if (mutex_lock_interruptible(&tp->control) < 0) { + usb_autopm_put_interface(tp->intf); + return; + } + - generic_ocp_read(tp, PLA_TALLYCNT, sizeof(tally), &tally, MCU_TYPE_PLA); - ++ generic_ocp_read(tp, PLA_TALLYCNT, sizeof(tally), &tally, MCU_TYPE_PLA); ++ + mutex_unlock(&tp->control); + - usb_autopm_put_interface(tp->intf); - - data[0] = le64_to_cpu(tally.tx_packets); -@@ -4674,9 +11572,10 @@ static void rtl8152_get_strings(struct net_device *dev, u32 stringset, u8 *data) - } - } - -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) - static int r8152_get_eee(struct r8152 *tp, struct ethtool_eee *eee) - { -- u32 ocp_data, lp, adv, supported = 0; -+ u32 lp, adv, supported = 0; - u16 val; - - val = r8152_mmd_read(tp, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE); -@@ -4688,10 +11587,7 @@ static int r8152_get_eee(struct r8152 *tp, struct ethtool_eee *eee) - val = r8152_mmd_read(tp, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE); - lp = mmd_eee_adv_to_ethtool_adv_t(val); - -- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); -- ocp_data &= EEE_RX_EN | EEE_TX_EN; -- -- eee->eee_enabled = !!ocp_data; -+ eee->eee_enabled = tp->eee_en; - eee->eee_active = !!(supported & adv & lp); - eee->supported = supported; - eee->advertised = adv; -@@ -4705,18 +11601,21 @@ static int r8152_set_eee(struct r8152 *tp, struct ethtool_eee *eee) - u16 val = ethtool_adv_to_mmd_eee_adv_t(eee->advertised); - - r8152_eee_en(tp, eee->eee_enabled); -+ tp->eee_en = eee->eee_enabled; - -- if (!eee->eee_enabled) -- val = 0; -- -- r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val); -+ if (eee->eee_enabled) { -+ r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val); -+ tp->eee_adv = val; -+ } else { -+ r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0); -+ } - - return 0; - } - - static int r8153_get_eee(struct r8152 *tp, struct ethtool_eee *eee) - { -- u32 ocp_data, lp, adv, supported = 0; -+ u32 lp, adv, supported = 0; - u16 val; - - val = ocp_reg_read(tp, OCP_EEE_ABLE); -@@ -4728,10 +11627,7 @@ static int r8153_get_eee(struct r8152 *tp, struct ethtool_eee *eee) - val = ocp_reg_read(tp, OCP_EEE_LPABLE); - lp = mmd_eee_adv_to_ethtool_adv_t(val); - -- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); -- ocp_data &= EEE_RX_EN | EEE_TX_EN; -- -- eee->eee_enabled = !!ocp_data; -+ eee->eee_enabled = tp->eee_en; - eee->eee_active = !!(supported & adv & lp); - eee->supported = supported; - eee->advertised = adv; -@@ -4745,11 +11641,14 @@ static int r8153_set_eee(struct r8152 *tp, struct ethtool_eee *eee) - u16 val = ethtool_adv_to_mmd_eee_adv_t(eee->advertised); - - r8153_eee_en(tp, eee->eee_enabled); -+ tp->eee_en = eee->eee_enabled; - -- if (!eee->eee_enabled) -- val = 0; -- -- ocp_reg_write(tp, OCP_EEE_ADV, val); -+ if (eee->eee_enabled) { -+ ocp_reg_write(tp, OCP_EEE_ADV, val); -+ tp->eee_adv = val; -+ } else { -+ ocp_reg_write(tp, OCP_EEE_ADV, 0); -+ } - - return 0; - } -@@ -4758,12 +11657,32 @@ static int r8153b_set_eee(struct r8152 *tp, struct ethtool_eee *eee) - { - u16 val = ethtool_adv_to_mmd_eee_adv_t(eee->advertised); - -- r8153b_eee_en(tp, eee->eee_enabled); -+ r8153_eee_en(tp, eee->eee_enabled); -+ tp->eee_en = eee->eee_enabled; ++ usb_autopm_put_interface(tp->intf); + -+ if (eee->eee_enabled) { -+ ocp_reg_write(tp, OCP_EEE_ADV, val); -+ tp->eee_adv = val; -+ } else { -+ ocp_reg_write(tp, OCP_EEE_ADV, 0); ++ data[0] = le64_to_cpu(tally.tx_packets); ++ data[1] = le64_to_cpu(tally.rx_packets); ++ data[2] = le64_to_cpu(tally.tx_errors); ++ data[3] = le32_to_cpu(tally.rx_errors); ++ data[4] = le16_to_cpu(tally.rx_missed); ++ data[5] = le16_to_cpu(tally.align_errors); ++ data[6] = le32_to_cpu(tally.tx_one_collision); ++ data[7] = le32_to_cpu(tally.tx_multi_collision); ++ data[8] = le64_to_cpu(tally.rx_unicast); ++ data[9] = le64_to_cpu(tally.rx_broadcast); ++ data[10] = le32_to_cpu(tally.rx_multicast); ++ data[11] = le16_to_cpu(tally.tx_aborted); ++ data[12] = le16_to_cpu(tally.tx_underrun); ++} ++ ++static void rtl8152_get_strings(struct net_device *dev, u32 stringset, u8 *data) ++{ ++ switch (stringset) { ++ case ETH_SS_STATS: ++ memcpy(data, *rtl8152_gstrings, sizeof(rtl8152_gstrings)); ++ break; + } ++} ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) ++static int r8152_get_eee(struct r8152 *tp, struct ethtool_eee *eee) ++{ ++ u32 lp, adv, supported = 0; ++ u16 val; ++ ++ val = r8152_mmd_read(tp, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE); ++ supported = mmd_eee_cap_to_ethtool_sup_t(val); ++ ++ val = r8152_mmd_read(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV); ++ adv = mmd_eee_adv_to_ethtool_adv_t(val); ++ ++ val = r8152_mmd_read(tp, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE); ++ lp = mmd_eee_adv_to_ethtool_adv_t(val); ++ ++ eee->eee_enabled = tp->eee_en; ++ eee->eee_active = !!(supported & adv & lp); ++ eee->supported = supported; ++ eee->advertised = tp->eee_adv; ++ eee->lp_advertised = lp; + + return 0; +} + -+static int r8156_set_eee(struct r8152 *tp, struct ethtool_eee *eee) ++static int r8152_set_eee(struct r8152 *tp, struct ethtool_eee *eee) +{ + u16 val = ethtool_adv_to_mmd_eee_adv_t(eee->advertised); - -- if (!eee->eee_enabled) -- val = 0; -+ r8156_eee_en(tp, eee->eee_enabled); ++ + tp->eee_en = eee->eee_enabled; - -- ocp_reg_write(tp, OCP_EEE_ADV, val); -+ if (eee->eee_enabled) { -+ ocp_reg_write(tp, OCP_EEE_ADV, val); -+ tp->eee_adv = val; -+ } else { -+ ocp_reg_write(tp, OCP_EEE_ADV, 0); -+ } - - return 0; - } -@@ -4774,6 +11693,11 @@ rtl_ethtool_get_eee(struct net_device *net, struct ethtool_eee *edata) - struct r8152 *tp = netdev_priv(net); - int ret; - ++ tp->eee_adv = val; ++ ++ rtl_eee_enable(tp, tp->eee_en); ++ ++ return 0; ++} ++ ++static int r8153_get_eee(struct r8152 *tp, struct ethtool_eee *eee) ++{ ++ u32 lp, adv, supported = 0; ++ u16 val; ++ ++ val = ocp_reg_read(tp, OCP_EEE_ABLE); ++ supported = mmd_eee_cap_to_ethtool_sup_t(val); ++ ++ val = ocp_reg_read(tp, OCP_EEE_ADV); ++ adv = mmd_eee_adv_to_ethtool_adv_t(val); ++ ++ val = ocp_reg_read(tp, OCP_EEE_LPABLE); ++ lp = mmd_eee_adv_to_ethtool_adv_t(val); ++ ++ eee->eee_enabled = tp->eee_en; ++ eee->eee_active = !!(supported & adv & lp); ++ eee->supported = supported; ++ eee->advertised = tp->eee_adv; ++ eee->lp_advertised = lp; ++ ++ return 0; ++} ++ ++static int ++rtl_ethtool_get_eee(struct net_device *net, struct ethtool_eee *edata) ++{ ++ struct r8152 *tp = netdev_priv(net); ++ int ret; ++ + if (!tp->rtl_ops.eee_get) { + ret = -EOPNOTSUPP; + goto out; + } + - ret = usb_autopm_get_interface(tp->intf); - if (ret < 0) - goto out; -@@ -4796,6 +11720,11 @@ rtl_ethtool_set_eee(struct net_device *net, struct ethtool_eee *edata) - struct r8152 *tp = netdev_priv(net); - int ret; - -+ if (!tp->rtl_ops.eee_get) { ++ ret = usb_autopm_get_interface(tp->intf); ++ if (ret < 0) ++ goto out; ++ ++ mutex_lock(&tp->control); ++ ++ ret = tp->rtl_ops.eee_get(tp, edata); ++ ++ mutex_unlock(&tp->control); ++ ++ usb_autopm_put_interface(tp->intf); ++ ++out: ++ return ret; ++} ++ ++static int ++rtl_ethtool_set_eee(struct net_device *net, struct ethtool_eee *edata) ++{ ++ struct r8152 *tp = netdev_priv(net); ++ int ret; ++ ++ if (!tp->rtl_ops.eee_set) { + ret = -EOPNOTSUPP; + goto out; + } + - ret = usb_autopm_get_interface(tp->intf); - if (ret < 0) - goto out; -@@ -4804,7 +11733,7 @@ rtl_ethtool_set_eee(struct net_device *net, struct ethtool_eee *edata) - - ret = tp->rtl_ops.eee_set(tp, edata); - if (!ret) -- ret = mii_nway_restart(&tp->mii); ++ ret = usb_autopm_get_interface(tp->intf); ++ if (ret < 0) ++ goto out; ++ ++ mutex_lock(&tp->control); ++ ++ ret = tp->rtl_ops.eee_set(tp, edata); ++ if (!ret) + ret = rtl_nway_restart(tp); - - mutex_unlock(&tp->control); - -@@ -4813,6 +11742,7 @@ rtl_ethtool_set_eee(struct net_device *net, struct ethtool_eee *edata) - out: - return ret; - } ++ ++ mutex_unlock(&tp->control); ++ ++ usb_autopm_put_interface(tp->intf); ++ ++out: ++ return ret; ++} +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) */ - - static int rtl8152_nway_reset(struct net_device *dev) - { -@@ -4825,7 +11755,7 @@ static int rtl8152_nway_reset(struct net_device *dev) - - mutex_lock(&tp->control); - -- ret = mii_nway_restart(&tp->mii); ++ ++static int rtl8152_nway_reset(struct net_device *dev) ++{ ++ struct r8152 *tp = netdev_priv(dev); ++ int ret; ++ ++ ret = usb_autopm_get_interface(tp->intf); ++ if (ret < 0) ++ goto out; ++ ++ mutex_lock(&tp->control); ++ + ret = rtl_nway_restart(tp); - - mutex_unlock(&tp->control); - -@@ -4864,64 +11794,273 @@ static int rtl8152_set_coalesce(struct net_device *netdev, - case RTL_VER_01: - case RTL_VER_02: - case RTL_VER_07: -+ case RTL_TEST_01: /* fix me */ - return -EOPNOTSUPP; - default: - break; -- } ++ ++ mutex_unlock(&tp->control); ++ ++ usb_autopm_put_interface(tp->intf); ++ ++out: ++ return ret; ++} ++ ++static int rtl8152_get_coalesce(struct net_device *netdev, ++ struct ethtool_coalesce *coalesce) ++{ ++ struct r8152 *tp = netdev_priv(netdev); ++ ++ switch (tp->version) { ++ case RTL_VER_01: ++ case RTL_VER_02: ++ case RTL_VER_07: ++ return -EOPNOTSUPP; ++ default: ++ break; + } + -+ if (coalesce->rx_coalesce_usecs > COALESCE_SLOW) ++ coalesce->rx_coalesce_usecs = tp->coalesce / 1000; ++ ++ return 0; ++} ++ ++static int rtl8152_set_coalesce(struct net_device *netdev, ++ struct ethtool_coalesce *coalesce) ++{ ++ struct r8152 *tp = netdev_priv(netdev); ++ u32 rx_coalesce_nsecs; ++ int ret; ++ ++ switch (tp->version) { ++ case RTL_VER_01: ++ case RTL_VER_02: ++ case RTL_VER_07: ++ case RTL_TEST_01: /* fix me */ ++ return -EOPNOTSUPP; ++ default: ++ break; ++ } ++ ++ rx_coalesce_nsecs = coalesce->rx_coalesce_usecs * 1000; ++ ++ if (rx_coalesce_nsecs > COALESCE_SLOW) + return -EINVAL; + + ret = usb_autopm_get_interface(tp->intf); @@ -9728,11 +16355,19 @@ index 2490498b..26cc7c1a 100644 + + mutex_lock(&tp->control); + -+ if (tp->coalesce != coalesce->rx_coalesce_usecs) { -+ tp->coalesce = coalesce->rx_coalesce_usecs; ++ if (tp->coalesce != rx_coalesce_nsecs) { ++ tp->coalesce = rx_coalesce_nsecs; + -+ if (netif_running(tp->netdev) && netif_carrier_ok(netdev)) -+ r8153_set_rx_early_timeout(tp); ++ if (netif_running(netdev) && netif_carrier_ok(netdev)) { ++ netif_stop_queue(netdev); ++ napi_disable(&tp->napi); ++ tp->rtl_ops.disable(tp); ++ tp->rtl_ops.enable(tp); ++ rtl_start_rx(tp); ++ napi_enable(&tp->napi); ++ rtl8152_set_rx_mode(netdev); ++ netif_wake_queue(netdev); ++ } + } + + mutex_unlock(&tp->control); @@ -9752,6 +16387,91 @@ index 2490498b..26cc7c1a 100644 + return 0; +} + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0) ++static int rtl8152_get_tunable(struct net_device *netdev, ++ const struct ethtool_tunable *tunable, void *d) ++{ ++ struct r8152 *tp = netdev_priv(netdev); ++ ++ switch (tunable->id) { ++ case ETHTOOL_RX_COPYBREAK: ++ *(u32 *)d = tp->rx_copybreak; ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ return 0; ++} ++ ++static int rtl8152_set_tunable(struct net_device *netdev, ++ const struct ethtool_tunable *tunable, ++ const void *d) ++{ ++ struct r8152 *tp = netdev_priv(netdev); ++ u32 val; ++ ++ switch (tunable->id) { ++ case ETHTOOL_RX_COPYBREAK: ++ val = *(u32 *)d; ++ if (val < ETH_ZLEN) { ++ netif_err(tp, rx_err, netdev, ++ "Invalid rx copy break value\n"); ++ return -EINVAL; ++ } ++ ++ if (tp->rx_copybreak != val) { ++ if (netdev->flags & IFF_UP) { ++ mutex_lock(&tp->control); ++ napi_disable(&tp->napi); ++ tp->rx_copybreak = val; ++ napi_enable(&tp->napi); ++ mutex_unlock(&tp->control); ++ } else { ++ tp->rx_copybreak = val; ++ } ++ } ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ return 0; ++} ++#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0) */ ++ ++static void rtl8152_get_ringparam(struct net_device *netdev, ++ struct ethtool_ringparam *ring) ++{ ++ struct r8152 *tp = netdev_priv(netdev); ++ ++ ring->rx_max_pending = RTL8152_RX_MAX_PENDING; ++ ring->rx_pending = tp->rx_pending; ++} ++ ++static int rtl8152_set_ringparam(struct net_device *netdev, ++ struct ethtool_ringparam *ring) ++{ ++ struct r8152 *tp = netdev_priv(netdev); ++ ++ if (ring->rx_pending < (RTL8152_MAX_RX * 2)) ++ return -EINVAL; ++ ++ if (tp->rx_pending != ring->rx_pending) { ++ if (netdev->flags & IFF_UP) { ++ mutex_lock(&tp->control); ++ napi_disable(&tp->napi); ++ tp->rx_pending = ring->rx_pending; ++ napi_enable(&tp->napi); ++ mutex_unlock(&tp->control); ++ } else { ++ tp->rx_pending = ring->rx_pending; ++ } ++ } ++ ++ return 0; ++} ++ +static const struct ethtool_ops ops = { + .get_drvinfo = rtl8152_get_drvinfo, +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,20,0) @@ -9788,6 +16508,12 @@ index 2490498b..26cc7c1a 100644 + .set_link_ksettings = rtl8152_set_link_ksettings, +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0) */ + .begin = rtl8152_ethtool_begin, ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0) ++ .get_tunable = rtl8152_get_tunable, ++ .set_tunable = rtl8152_set_tunable, ++#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0) */ ++ .get_ringparam = rtl8152_get_ringparam, ++ .set_ringparam = rtl8152_set_ringparam, +}; + +static int rtltool_ioctl(struct r8152 *tp, struct ifreq *ifr) @@ -9923,9 +16649,7 @@ index 2490498b..26cc7c1a 100644 + my_cmd.data, buffer); + kfree(buffer); + break; - -- if (coalesce->rx_coalesce_usecs > COALESCE_SLOW) -- return -EINVAL; ++ + case RTLTOOL_USB_INFO: + uinfo = (struct usb_device_info *)&my_cmd.nic_info; + udev = tp->udev; @@ -9935,33 +16659,23 @@ index 2490498b..26cc7c1a 100644 + strlcpy(uinfo->devpath, udev->devpath, sizeof(udev->devpath)); + pla_ocp_read(tp, PLA_IDR, sizeof(uinfo->dev_addr), + uinfo->dev_addr); - -- ret = usb_autopm_get_interface(tp->intf); -- if (ret < 0) -- return ret; ++ + if (copy_to_user(myptr, &my_cmd, sizeof(my_cmd))) + ret = -EFAULT; - -- mutex_lock(&tp->control); ++ + break; - -- if (tp->coalesce != coalesce->rx_coalesce_usecs) { -- tp->coalesce = coalesce->rx_coalesce_usecs; ++ + case RTL_ENABLE_USB_DIAG: + ret = usb_autopm_get_interface(tp->intf); + if (ret < 0) + break; - -- if (netif_running(tp->netdev) && netif_carrier_ok(netdev)) -- r8153_set_rx_early_timeout(tp); -- } ++ + mutex_lock(&tp->control); + tp->rtk_enable_diag++; + netif_info(tp, drv, netdev, "enable rtk diag %d\n", + tp->rtk_enable_diag); + break; - -- mutex_unlock(&tp->control); ++ + case RTL_DISABLE_USB_DIAG: + if (!tp->rtk_enable_diag) { + netif_err(tp, drv, netdev, @@ -9969,8 +16683,7 @@ index 2490498b..26cc7c1a 100644 + ret = -EPERM; + break; + } - -- usb_autopm_put_interface(tp->intf); ++ + rtk_disable_diag(tp); + break; + @@ -9978,77 +16691,55 @@ index 2490498b..26cc7c1a 100644 + ret = -EOPNOTSUPP; + break; + } - - return ret; - } - --static const struct ethtool_ops ops = { -- .get_drvinfo = rtl8152_get_drvinfo, -- .get_settings = rtl8152_get_settings, -- .set_settings = rtl8152_set_settings, -- .get_link = ethtool_op_get_link, -- .nway_reset = rtl8152_nway_reset, -- .get_msglevel = rtl8152_get_msglevel, -- .set_msglevel = rtl8152_set_msglevel, -- .get_wol = rtl8152_get_wol, -- .set_wol = rtl8152_set_wol, -- .get_strings = rtl8152_get_strings, -- .get_sset_count = rtl8152_get_sset_count, -- .get_ethtool_stats = rtl8152_get_ethtool_stats, -- .get_coalesce = rtl8152_get_coalesce, -- .set_coalesce = rtl8152_set_coalesce, -- .get_eee = rtl_ethtool_get_eee, -- .set_eee = rtl_ethtool_set_eee, --}; -- - static int rtl8152_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) - { - struct r8152 *tp = netdev_priv(netdev); - struct mii_ioctl_data *data = if_mii(rq); -- int res; ++ ++ return ret; ++} ++ ++static int rtl8152_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) ++{ ++ struct r8152 *tp = netdev_priv(netdev); ++ struct mii_ioctl_data *data = if_mii(rq); + int ret; - - if (test_bit(RTL8152_UNPLUG, &tp->flags)) - return -ENODEV; - -- res = usb_autopm_get_interface(tp->intf); -- if (res < 0) ++ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return -ENODEV; ++ + ret = usb_autopm_get_interface(tp->intf); + if (ret < 0) - goto out; - - switch (cmd) { -@@ -4930,6 +12069,11 @@ static int rtl8152_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) - break; - - case SIOCGMIIREG: ++ goto out; ++ ++ switch (cmd) { ++ case SIOCGMIIPHY: ++ data->phy_id = R8152_PHY_ID; /* Internal PHY */ ++ break; ++ ++ case SIOCGMIIREG: + if (unlikely(tp->rtk_enable_diag)) { + ret = -EBUSY; + break; + } + - mutex_lock(&tp->control); - data->val_out = r8152_mdio_read(tp, data->reg_num); - mutex_unlock(&tp->control); -@@ -4937,22 +12081,36 @@ static int rtl8152_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) - - case SIOCSMIIREG: - if (!capable(CAP_NET_ADMIN)) { -- res = -EPERM; ++ mutex_lock(&tp->control); ++ data->val_out = r8152_mdio_read(tp, data->reg_num); ++ mutex_unlock(&tp->control); ++ break; ++ ++ case SIOCSMIIREG: ++ if (!capable(CAP_NET_ADMIN)) { + ret = -EPERM; - break; - } ++ break; ++ } + + if (unlikely(tp->rtk_enable_diag)) { + ret = -EBUSY; + break; + } + - mutex_lock(&tp->control); - r8152_mdio_write(tp, data->reg_num, data->val_in); - mutex_unlock(&tp->control); - break; - ++ mutex_lock(&tp->control); ++ r8152_mdio_write(tp, data->reg_num, data->val_in); ++ mutex_unlock(&tp->control); ++ break; ++ + case SIOCDEVPRIVATE: + if (!capable(CAP_NET_ADMIN)) { + ret = -EPERM; @@ -10057,117 +16748,185 @@ index 2490498b..26cc7c1a 100644 + ret = rtltool_ioctl(tp, rq); + break; + - default: -- res = -EOPNOTSUPP; ++ default: + ret = -EOPNOTSUPP; - } - - usb_autopm_put_interface(tp->intf); - - out: -- return res; ++ } ++ ++ usb_autopm_put_interface(tp->intf); ++ ++out: + return ret; - } - - static int rtl8152_change_mtu(struct net_device *dev, int new_mtu) -@@ -4964,14 +12122,20 @@ static int rtl8152_change_mtu(struct net_device *dev, int new_mtu) - case RTL_VER_01: - case RTL_VER_02: - case RTL_VER_07: ++} ++ ++static int rtl8152_change_mtu(struct net_device *dev, int new_mtu) ++{ ++ struct r8152 *tp = netdev_priv(dev); ++ int ret; ++ ++ switch (tp->version) { ++ case RTL_VER_01: ++ case RTL_VER_02: ++ case RTL_VER_07: +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0) + return eth_change_mtu(dev, new_mtu); +#else - dev->mtu = new_mtu; - return 0; ++ dev->mtu = new_mtu; ++ return 0; +#endif - default: - break; - } - ++ default: ++ break; ++ } ++ +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0) - if (new_mtu < 68 || new_mtu > RTL8153_MAX_MTU) - return -EINVAL; ++ if (new_mtu < 68 || new_mtu > RTL8153_MAX_MTU) ++ return -EINVAL; +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0) */ - - ret = usb_autopm_get_interface(tp->intf); - if (ret < 0) -@@ -4997,19 +12161,27 @@ static int rtl8152_change_mtu(struct net_device *dev, int new_mtu) - return ret; - } - ++ ++ ret = usb_autopm_get_interface(tp->intf); ++ if (ret < 0) ++ return ret; ++ ++ mutex_lock(&tp->control); ++ ++ dev->mtu = new_mtu; ++ ++ if (netif_running(dev)) { ++ u32 ocp_data = new_mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; ++ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, ocp_data); ++ r8156_fc_parameter(tp); ++ ++ if (netif_carrier_ok(dev)) { ++ netif_stop_queue(dev); ++ napi_disable(&tp->napi); ++ tasklet_disable(&tp->tx_tl); ++ tp->rtl_ops.disable(tp); ++ tp->rtl_ops.enable(tp); ++ rtl_start_rx(tp); ++ tasklet_enable(&tp->tx_tl); ++ napi_enable(&tp->napi); ++ rtl8152_set_rx_mode(dev); ++ netif_wake_queue(dev); ++ } ++ } ++ ++ mutex_unlock(&tp->control); ++ ++ usb_autopm_put_interface(tp->intf); ++ ++ return ret; ++} ++ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) - static const struct net_device_ops rtl8152_netdev_ops = { - .ndo_open = rtl8152_open, - .ndo_stop = rtl8152_close, - .ndo_do_ioctl = rtl8152_ioctl, - .ndo_start_xmit = rtl8152_start_xmit, - .ndo_tx_timeout = rtl8152_tx_timeout, ++static const struct net_device_ops rtl8152_netdev_ops = { ++ .ndo_open = rtl8152_open, ++ .ndo_stop = rtl8152_close, ++ .ndo_do_ioctl = rtl8152_ioctl, ++ .ndo_start_xmit = rtl8152_start_xmit, ++ .ndo_tx_timeout = rtl8152_tx_timeout, +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) + .ndo_vlan_rx_register = rtl8152_vlan_rx_register, +#else - .ndo_set_features = rtl8152_set_features, ++ .ndo_set_features = rtl8152_set_features, +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) */ - .ndo_set_rx_mode = rtl8152_set_rx_mode, - .ndo_set_mac_address = rtl8152_set_mac_address, - .ndo_change_mtu = rtl8152_change_mtu, - .ndo_validate_addr = eth_validate_addr, ++ .ndo_set_rx_mode = rtl8152_set_rx_mode, ++ .ndo_set_mac_address = rtl8152_set_mac_address, ++ .ndo_change_mtu = rtl8152_change_mtu, ++ .ndo_validate_addr = eth_validate_addr, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,4) - .ndo_features_check = rtl8152_features_check, ++ .ndo_features_check = rtl8152_features_check, +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,4) */ - }; ++}; +#endif - - static void rtl8152_unload(struct r8152 *tp) - { -@@ -5051,11 +12223,16 @@ static int rtl_ops_init(struct r8152 *tp) - ops->up = rtl8152_up; - ops->down = rtl8152_down; - ops->unload = rtl8152_unload; ++ ++static void rtl8152_unload(struct r8152 *tp) ++{ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return; ++ ++ r8152_power_cut_en(tp, false); ++} ++ ++static void rtl8153_unload(struct r8152 *tp) ++{ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return; ++ ++ r8153_power_cut_en(tp, false); ++} ++ ++static void rtl8153b_unload(struct r8152 *tp) ++{ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return; ++ ++ r8153b_power_cut_en(tp, false); ++} ++ ++static int rtl_ops_init(struct r8152 *tp) ++{ ++ struct rtl_ops *ops = &tp->rtl_ops; ++ int ret = 0; ++ ++ switch (tp->version) { ++ case RTL_VER_01: ++ case RTL_VER_02: ++ case RTL_VER_07: ++ ops->init = r8152b_init; ++ ops->enable = rtl8152_enable; ++ ops->disable = rtl8152_disable; ++ ops->up = rtl8152_up; ++ ops->down = rtl8152_down; ++ ops->unload = rtl8152_unload; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) - ops->eee_get = r8152_get_eee; - ops->eee_set = r8152_set_eee; ++ ops->eee_get = r8152_get_eee; ++ ops->eee_set = r8152_set_eee; +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) */ - ops->in_nway = rtl8152_in_nway; - ops->hw_phy_cfg = r8152b_hw_phy_cfg; - ops->autosuspend_en = rtl_runtime_suspend_enable; ++ ops->in_nway = rtl8152_in_nway; ++ ops->hw_phy_cfg = r8152b_hw_phy_cfg; ++ ops->autosuspend_en = rtl_runtime_suspend_enable; + tp->rx_buf_sz = 16 * 1024; + tp->eee_en = true; + tp->eee_adv = MDIO_EEE_100TX; - break; - - case RTL_VER_03: -@@ -5068,26 +12245,75 @@ static int rtl_ops_init(struct r8152 *tp) - ops->up = rtl8153_up; - ops->down = rtl8153_down; - ops->unload = rtl8153_unload; ++ break; ++ ++ case RTL_VER_03: ++ case RTL_VER_04: ++ case RTL_VER_05: ++ case RTL_VER_06: ++ ops->init = r8153_init; ++ ops->enable = rtl8153_enable; ++ ops->disable = rtl8153_disable; ++ ops->up = rtl8153_up; ++ ops->down = rtl8153_down; ++ ops->unload = rtl8153_unload; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) - ops->eee_get = r8153_get_eee; - ops->eee_set = r8153_set_eee; ++ ops->eee_get = r8153_get_eee; ++ ops->eee_set = r8152_set_eee; +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) */ - ops->in_nway = rtl8153_in_nway; - ops->hw_phy_cfg = r8153_hw_phy_cfg; - ops->autosuspend_en = rtl8153_runtime_enable; ++ ops->in_nway = rtl8153_in_nway; ++ ops->hw_phy_cfg = r8153_hw_phy_cfg; ++ ops->autosuspend_en = rtl8153_runtime_enable; + tp->rx_buf_sz = 32 * 1024; + tp->eee_en = true; + tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX; - break; - - case RTL_VER_08: - case RTL_VER_09: - ops->init = r8153b_init; - ops->enable = rtl8153_enable; -- ops->disable = rtl8153b_disable; ++ break; ++ ++ case RTL_VER_08: ++ case RTL_VER_09: ++ ops->init = r8153b_init; ++ ops->enable = rtl8153_enable; + ops->disable = rtl8153_disable; - ops->up = rtl8153b_up; - ops->down = rtl8153b_down; - ops->unload = rtl8153b_unload; ++ ops->up = rtl8153b_up; ++ ops->down = rtl8153b_down; ++ ops->unload = rtl8153b_unload; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) - ops->eee_get = r8153_get_eee; - ops->eee_set = r8153b_set_eee; ++ ops->eee_get = r8153_get_eee; ++ ops->eee_set = r8152_set_eee; +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) */ - ops->in_nway = rtl8153_in_nway; - ops->hw_phy_cfg = r8153b_hw_phy_cfg; - ops->autosuspend_en = rtl8153b_runtime_enable; ++ ops->in_nway = rtl8153_in_nway; ++ ops->hw_phy_cfg = r8153b_hw_phy_cfg; ++ ops->autosuspend_en = rtl8153b_runtime_enable; + tp->rx_buf_sz = 32 * 1024; + tp->eee_en = true; + tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX; @@ -10185,15 +16944,16 @@ index 2490498b..26cc7c1a 100644 +// ops->eee_set = r8156_set_eee; +//#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) */ + ops->in_nway = rtl8153_in_nway; -+ ops->hw_phy_cfg = r8156_hw_phy_cfg; ++ ops->hw_phy_cfg = r8156_hw_phy_cfg_test; + ops->autosuspend_en = rtl8156_runtime_enable; + tp->rx_buf_sz = 48 * 1024; -+ set_bit(SUPPORT_2500FULL, &tp->flags); ++ tp->support_2500full = 1; + break; + + case RTL_VER_11: + tp->eee_en = true; + tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX; ++ /* fall through */ + case RTL_VER_10: + ops->init = r8156_init; + ops->enable = rtl8156_enable; @@ -10203,20 +16963,93 @@ index 2490498b..26cc7c1a 100644 + ops->unload = rtl8153_unload; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) + ops->eee_get = r8153_get_eee; -+ ops->eee_set = r8156_set_eee; ++ ops->eee_set = r8152_set_eee; +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) */ + ops->in_nway = rtl8153_in_nway; -+ ops->hw_phy_cfg = r8156_hw_phy_cfg2; ++ ops->hw_phy_cfg = r8156_hw_phy_cfg; + ops->autosuspend_en = rtl8156_runtime_enable; + tp->rx_buf_sz = 48 * 1024; -+ set_bit(SUPPORT_2500FULL, &tp->flags); - break; - - default: -@@ -5147,6 +12373,15 @@ static u8 rtl_get_version(struct usb_interface *intf) - case 0x6010: - version = RTL_VER_09; - break; ++ tp->support_2500full = 1; ++ break; ++ ++ case RTL_VER_12: ++ case RTL_VER_13: ++ tp->eee_en = true; ++ tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX; ++ ops->init = r8156b_init; ++ ops->enable = rtl8156b_enable; ++ ops->disable = rtl8153_disable; ++ ops->up = rtl8156_up; ++ ops->down = rtl8156_down; ++ ops->unload = rtl8153_unload; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) ++ ops->eee_get = r8153_get_eee; ++ ops->eee_set = r8152_set_eee; ++#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) */ ++ ops->in_nway = rtl8153_in_nway; ++ ops->hw_phy_cfg = r8156b_hw_phy_cfg; ++ ops->autosuspend_en = rtl8156_runtime_enable; ++ tp->rx_buf_sz = 48 * 1024; ++ tp->support_2500full = 1; ++ break; ++ ++ default: ++ ret = -ENODEV; ++ dev_err(&tp->intf->dev, "Unknown Device\n"); ++ break; ++ } ++ ++ return ret; ++} ++ ++static u8 rtl_get_version(struct usb_interface *intf) ++{ ++ struct usb_device *udev = interface_to_usbdev(intf); ++ u32 ocp_data = 0; ++ __le32 *tmp; ++ u8 version; ++ int ret; ++ ++ tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); ++ if (!tmp) ++ return 0; ++ ++ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), ++ RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, ++ PLA_TCR0, MCU_TYPE_PLA, tmp, sizeof(*tmp), 500); ++ if (ret > 0) ++ ocp_data = (__le32_to_cpu(*tmp) >> 16) & VERSION_MASK; ++ ++ kfree(tmp); ++ ++ switch (ocp_data) { ++ case 0x4c00: ++ version = RTL_VER_01; ++ break; ++ case 0x4c10: ++ version = RTL_VER_02; ++ break; ++ case 0x5c00: ++ version = RTL_VER_03; ++ break; ++ case 0x5c10: ++ version = RTL_VER_04; ++ break; ++ case 0x5c20: ++ version = RTL_VER_05; ++ break; ++ case 0x5c30: ++ version = RTL_VER_06; ++ break; ++ case 0x4800: ++ version = RTL_VER_07; ++ break; ++ case 0x6000: ++ version = RTL_VER_08; ++ break; ++ case 0x6010: ++ version = RTL_VER_09; ++ break; + case 0x7010: + version = RTL_TEST_01; + break; @@ -10226,20 +17059,31 @@ index 2490498b..26cc7c1a 100644 + case 0x7030: + version = RTL_VER_11; + break; - default: - version = RTL_VER_UNKNOWN; - dev_info(&intf->dev, "Unknown version 0x%04x\n", ocp_data); -@@ -5158,6 +12393,331 @@ static u8 rtl_get_version(struct usb_interface *intf) - return version; - } - ++ case 0x7400: ++ version = RTL_VER_12; ++ break; ++ case 0x7410: ++ version = RTL_VER_13; ++ break; ++ default: ++ version = RTL_VER_UNKNOWN; ++ dev_info(&intf->dev, "Unknown version 0x%04x\n", ocp_data); ++ break; ++ } ++ ++ dev_dbg(&intf->dev, "Detected version 0x%04x\n", version); ++ ++ return version; ++} ++ +#ifdef RTL8152_DEBUG + +static ssize_t +ocp_show(struct device *dev, struct device_attribute *attr, char *buf) +{ -+ struct usb_interface *intf = to_usb_interface(dev); -+ struct r8152 *tp = usb_get_intfdata(intf); ++ struct net_device *netdev = to_net_dev(dev); ++ struct r8152 *tp = netdev_priv(netdev); ++ struct usb_interface *intf = tp->intf; + char tmp[256]; + struct tally_counter tally; + int ret; @@ -10250,34 +17094,89 @@ index 2490498b..26cc7c1a 100644 + strcat(buf, "\n"); + + switch (tp->version) { ++ case RTL_VER_05: ++ strcat(buf, "RTL_VER_05\n"); ++ strcat(buf, "usb_patch_code_20190904\n"); ++ strcat(buf, "pla_patch_code_20190220_0\n"); ++ strcat(buf, "\n\n\n\n"); ++ break; ++ case RTL_VER_06: ++ strcat(buf, "RTL_VER_06\n"); ++ strcat(buf, "usb_patch_20190909\n"); ++ strcat(buf, "pla_patch_code_20190311_0\n"); ++ strcat(buf, "\n\n\n\n"); ++ break; ++ case RTL_VER_09: ++ strcat(buf, "RTL_VER_09\n"); ++ strcat(buf, "usb_patch_code_20190906.cfg\n"); ++ strcat(buf, "plamcu_patch_code_20190408_0\n"); ++ strcat(buf, "\n\n\n\n"); ++ break; + case RTL_VER_11: + strcat(buf, "RTL_VER_11\n"); -+ strcat(buf, "nc_patch_181008_usb\n"); ++ strcat(buf, "nc0_patch_190128_usb\n"); + strcat(buf, "nc1_patch_181029_usb\n"); + strcat(buf, "nc2_patch_180821_usb\n"); + strcat(buf, "uc2_patch_181018_usb\n"); -+ strcat(buf, "USB_patch_code_20180906_v2\n"); ++ strcat(buf, "USB_patch_code_20190212_v3\n"); + strcat(buf, "PLA_patch_code_20180914_v3\n"); + break; ++ case RTL_VER_12: ++ strcat(buf, "RTL_VER_12\n"); ++ strcat(buf, "nc_patch_190821_usb\n"); ++ strcat(buf, "nc2_patch_190823_usb\n"); ++ strcat(buf, "uc2_patch_190817_usb\n"); ++ strcat(buf, "uc_patch_190731_usb\n"); ++ strcat(buf, "USB_patch_code_20190816_v2\n"); ++ strcat(buf, "PLA_patch_code_20190827_v2\n"); ++ break; ++ case RTL_VER_13: ++ strcat(buf, "RTL_VER_13\n"); ++ strcat(buf, "gphy_ramcode_v10_usb_4ByteAlign_20200116\n"); ++ strcat(buf, "\n"); ++ strcat(buf, "\n"); ++ strcat(buf, "\n"); ++ strcat(buf, "usb_patch_20200109\n"); ++ strcat(buf, "pla_patch_code_svn6728_20200103\n"); ++ break; + default: + strcat(buf, "\n\n\n\n\n\n\n"); -+ break; -+ } -+ + break; + } +-} +- +-static int r8152_get_eee(struct r8152 *tp, struct ethtool_eee *eee) +-{ +- u32 ocp_data, lp, adv, supported = 0; +- u16 val; + +- val = r8152_mmd_read(tp, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE); +- supported = mmd_eee_cap_to_ethtool_sup_t(val); + ret = usb_autopm_get_interface(intf); + if (ret < 0) + return ret; -+ + +- val = r8152_mmd_read(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV); +- adv = mmd_eee_adv_to_ethtool_adv_t(val); + ret = mutex_lock_interruptible(&tp->control); + if (ret < 0) { + usb_autopm_put_interface(intf); + goto err1; + } -+ + +- val = r8152_mmd_read(tp, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE); +- lp = mmd_eee_adv_to_ethtool_adv_t(val); + generic_ocp_read(tp, PLA_TALLYCNT, sizeof(tally), &tally, MCU_TYPE_PLA); -+ + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); +- ocp_data &= EEE_RX_EN | EEE_TX_EN; + mutex_unlock(&tp->control); -+ + +- eee->eee_enabled = !!ocp_data; +- eee->eee_active = !!(supported & adv & lp); +- eee->supported = supported; +- eee->advertised = adv; +- eee->lp_advertised = lp; + usb_autopm_put_interface(intf); + + sprintf(tmp, "tx_packets = %Lu\n", le64_to_cpu(tally.tx_packets)); @@ -10308,32 +17207,39 @@ index 2490498b..26cc7c1a 100644 + strcat(buf, tmp); + sprintf(tmp, "tx_underrun = %u\n", le16_to_cpu(tally.tx_underrun)); + strcat(buf, tmp); -+ + +- return 0; +err1: + if (ret < 0) + return ret; + else + return strlen(buf); -+} -+ + } + +-static int r8152_set_eee(struct r8152 *tp, struct ethtool_eee *eee) +static inline bool hex_value(char p) -+{ + { +- u16 val = ethtool_adv_to_mmd_eee_adv_t(eee->advertised); + return (p >= '0' && p <= '9') || + (p >= 'a' && p <= 'f') || + (p >= 'A' && p <= 'F'); +} -+ + +- r8152_eee_en(tp, eee->eee_enabled); +static int ocp_count(char *v1) +{ + int len = strlen(v1), count = 0; + char *v2 = strchr(v1, ' '); + bool is_vaild = false; -+ + +- if (!eee->eee_enabled) +- val = 0; + if (len < 5 || !v2) + goto out1; +// else if (strncmp(v1, "pla ", 4) && strncmp(v1, "usb ", 4)) +// goto out1; -+ + +- r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val); + v1 = v2; + len = strlen(v2); + while(len) { @@ -10342,20 +17248,30 @@ index 2490498b..26cc7c1a 100644 + v1++; + len--; + } -+ + +- return 0; +-} + if (!len || *v1 == '\n') + goto out1; -+ + +-static int r8153_get_eee(struct r8152 *tp, struct ethtool_eee *eee) +-{ +- u32 ocp_data, lp, adv, supported = 0; +- u16 val; +check: + v2 = strchr(v1, ' '); -+ + +- val = ocp_reg_read(tp, OCP_EEE_ABLE); +- supported = mmd_eee_cap_to_ethtool_sup_t(val); + if (len > 2 && !strncasecmp(v1, "0x", 2)) { + v1 += 2; + len -= 2; + if (v1 == v2 || *v1 == '\n') + goto out1; + } -+ + +- val = ocp_reg_read(tp, OCP_EEE_ADV); +- adv = mmd_eee_adv_to_ethtool_adv_t(val); + if (v2) { + while (v1 < v2) { + if (!hex_value(*v1)) @@ -10363,58 +17279,80 @@ index 2490498b..26cc7c1a 100644 + v1++; + len--; + } -+ + +- val = ocp_reg_read(tp, OCP_EEE_LPABLE); +- lp = mmd_eee_adv_to_ethtool_adv_t(val); + count++; -+ + +- ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); +- ocp_data &= EEE_RX_EN | EEE_TX_EN; + while(len) { + if (*v1 != ' ') + break; + v1++; + len--; + } -+ + +- eee->eee_enabled = !!ocp_data; +- eee->eee_active = !!(supported & adv & lp); +- eee->supported = supported; +- eee->advertised = adv; +- eee->lp_advertised = lp; + if (len) + goto check; -+ + +- return 0; +-} + is_vaild = true; + } else { + int i; -+ + +-static int r8153_set_eee(struct r8152 *tp, struct ethtool_eee *eee) +-{ +- u16 val = ethtool_adv_to_mmd_eee_adv_t(eee->advertised); + if (len && v1[len - 1] == '\n') + len--; -+ + +- r8153_eee_en(tp, eee->eee_enabled); + for (i = 0; i < len; i++) { + if (!hex_value(*v1)) + goto out1; + v1++; + } -+ + +- if (!eee->eee_enabled) +- val = 0; + if (len) + count++; -+ + +- ocp_reg_write(tp, OCP_EEE_ADV, val); + is_vaild = true; + } -+ + +- return 0; +out1: + if (is_vaild) + return count; + else + return 0; -+} -+ + } + +-static int r8153b_set_eee(struct r8152 *tp, struct ethtool_eee *eee) +static ssize_t ocp_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) -+{ -+ struct usb_interface *intf; -+ struct net_device *netdev; + { +- u16 val = ethtool_adv_to_mmd_eee_adv_t(eee->advertised); +- +- r8153b_eee_en(tp, eee->eee_enabled); +- +- if (!eee->eee_enabled) +- val = 0; ++ struct net_device *netdev = to_net_dev(dev); ++ struct r8152 *tp = netdev_priv(netdev); ++ struct usb_interface *intf = tp->intf; + u32 v1, v2, v3, v4; -+ struct r8152 *tp; + u16 type; -+ int num; -+ -+ intf = to_usb_interface(dev); -+ tp = usb_get_intfdata(intf); -+ netdev = tp->netdev; ++ int num, ret; + + if (!strncmp(buf, "pla ", 4)) + type = MCU_TYPE_PLA; @@ -10422,12 +17360,20 @@ index 2490498b..26cc7c1a 100644 + type = MCU_TYPE_USB; + else + return -EINVAL; -+ + +- ocp_reg_write(tp, OCP_EEE_ADV, val); + if (!ocp_count((char *)buf)) + return -EINVAL; -+ + +- return 0; +-} + num = sscanf(strchr(buf, ' '), "%x %x %x %x\n", &v1, &v2, &v3, &v4); -+ + +-static int +-rtl_ethtool_get_eee(struct net_device *net, struct ethtool_eee *edata) +-{ +- struct r8152 *tp = netdev_priv(net); +- int ret; + if (num > 1) { + if ((v1 == 2 && (v2 & 1)) || + (v1 == 4 && (v2 & 3)) || @@ -10435,13 +17381,18 @@ index 2490498b..26cc7c1a 100644 + (v2 < 0xc000 || (v2 & ~3) == PLA_OCP_GPHY_BASE))) + return -EINVAL; + } -+ -+ count = usb_autopm_get_interface(intf); -+ if (count < 0) -+ return count; -+ -+ count = mutex_lock_interruptible(&tp->control); -+ if (count < 0) + +- ret = usb_autopm_get_interface(tp->intf); ++ ret = usb_autopm_get_interface(intf); + if (ret < 0) +- goto out; +- +- mutex_lock(&tp->control); ++ return ret; + +- ret = tp->rtl_ops.eee_get(tp, edata); ++ ret = mutex_lock_interruptible(&tp->control); ++ if (ret < 0) + goto put; + + switch(num) { @@ -10463,7 +17414,7 @@ index 2490498b..26cc7c1a 100644 + ocp_read_dword(tp, type, v2)); + break; + default: -+ count = -EINVAL; ++ ret = -EINVAL; + break; + } + break; @@ -10485,25 +17436,33 @@ index 2490498b..26cc7c1a 100644 + ocp_write_dword(tp, type, v2, v3); + break; + default: -+ count = -EINVAL; ++ ret = -EINVAL; + break; + } + break; + case 4: + case 1: + default: -+ count = -EINVAL; ++ ret = -EINVAL; + break; + } -+ -+ mutex_unlock(&tp->control); -+ + + mutex_unlock(&tp->control); + +- usb_autopm_put_interface(tp->intf); +put: + usb_autopm_put_interface(intf); -+ -+ return count; -+} -+ + +-out: +- return ret; ++ if (ret < 0) ++ return ret; ++ else ++ return count; + } + +-static int +-rtl_ethtool_set_eee(struct net_device *net, struct ethtool_eee *edata) +static DEVICE_ATTR_RW(ocp); + +static struct attribute *rtk_attrs[] = { @@ -10517,51 +17476,628 @@ index 2490498b..26cc7c1a 100644 +static ssize_t pla_read(struct file *fp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t offset, + size_t size) -+{ + { +- struct r8152 *tp = netdev_priv(net); + struct device *dev = kobj_to_dev(kobj); -+ struct usb_interface *intf = to_usb_interface(dev); -+ struct r8152 *tp = usb_get_intfdata(intf); -+ struct net_device *netdev = tp->netdev; -+ ++ struct net_device *netdev = to_net_dev(dev); ++ struct r8152 *tp = netdev_priv(netdev); + int ret; + +- ret = usb_autopm_get_interface(tp->intf); + if (size <= ATTR_PLA_SIZE) + size = min(size, ATTR_PLA_SIZE - (size_t)offset); + else + return -EINVAL; + ++ ret = usb_autopm_get_interface(intf); + if (ret < 0) +- goto out; ++ return ret; + +- mutex_lock(&tp->control); + /* rtnl_lock(); */ -+ if (mutex_lock_interruptible(&tp->control)) -+ return -EINTR; -+ -+ if (pla_ocp_read(tp, offset + 0xc000, (u16)size, buf) < 0) ++ ret = mutex_lock_interruptible(&tp->control) ++ if (ret < 0) ++ goto put; + +- ret = tp->rtl_ops.eee_set(tp, edata); +- if (!ret) +- ret = mii_nway_restart(&tp->mii); ++ ret = pla_ocp_read(tp, offset + 0xc000, (u16)size, buf); ++ if (ret < 0) + netif_err(tp, drv, netdev, + "Read PLA offset 0x%Lx, len = %zd fail\n", + offset + 0xc000, size); -+ -+ mutex_unlock(&tp->control); + + mutex_unlock(&tp->control); + /* rtnl_unlock(); */ -+ -+ return size; + +- usb_autopm_put_interface(tp->intf); +- +-out: +- return ret; +-} +- +-static int rtl8152_nway_reset(struct net_device *dev) +-{ +- struct r8152 *tp = netdev_priv(dev); +- int ret; ++put: ++ usb_autopm_put_interface(intf); + +- ret = usb_autopm_get_interface(tp->intf); + if (ret < 0) +- goto out; +- +- mutex_lock(&tp->control); ++ return ret; ++ else ++ return size; +} -+ + +- ret = mii_nway_restart(&tp->mii); +static BIN_ATTR_RO(pla, ATTR_PLA_SIZE); -+ + +- mutex_unlock(&tp->control); +static struct bin_attribute *rtk_bin_attrs[] = { + &bin_attr_pla, + NULL +}; -+ -+static struct attribute_group rtk_attr_grp = { + +- usb_autopm_put_interface(tp->intf); ++static struct attribute_group rtk_dbg_grp = { + .name = "nic_swsd", + .attrs = rtk_attrs, + .bin_attrs = rtk_bin_attrs, +}; + +-out: +- return ret; +-} ++#endif /* RTL8152_DEBUG */ + +-static int rtl8152_get_coalesce(struct net_device *netdev, +- struct ethtool_coalesce *coalesce) ++static ssize_t rx_copybreak_show(struct device *dev, ++ struct device_attribute *attr, char *buf) + { ++ struct net_device *netdev = to_net_dev(dev); + struct r8152 *tp = netdev_priv(netdev); + +- switch (tp->version) { +- case RTL_VER_01: +- case RTL_VER_02: +- case RTL_VER_07: +- return -EOPNOTSUPP; +- default: +- break; +- } +- +- coalesce->rx_coalesce_usecs = tp->coalesce; ++ sprintf(buf, "%u\n", tp->rx_copybreak); + +- return 0; ++ return strlen(buf); + } + +-static int rtl8152_set_coalesce(struct net_device *netdev, +- struct ethtool_coalesce *coalesce) ++static ssize_t rx_copybreak_store(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) + { ++ struct net_device *netdev = to_net_dev(dev); + struct r8152 *tp = netdev_priv(netdev); +- int ret; +- +- switch (tp->version) { +- case RTL_VER_01: +- case RTL_VER_02: +- case RTL_VER_07: +- return -EOPNOTSUPP; +- default: +- break; +- } ++ u32 rx_copybreak; + +- if (coalesce->rx_coalesce_usecs > COALESCE_SLOW) ++ if (sscanf(buf, "%u\n", &rx_copybreak) != 1) + return -EINVAL; + +- ret = usb_autopm_get_interface(tp->intf); +- if (ret < 0) +- return ret; ++ if (rx_copybreak < ETH_ZLEN) ++ return -EINVAL; + +- mutex_lock(&tp->control); ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return -ENODEV; + +- if (tp->coalesce != coalesce->rx_coalesce_usecs) { +- tp->coalesce = coalesce->rx_coalesce_usecs; ++ if (tp->rx_copybreak != rx_copybreak) { ++ if (tp->netdev->flags & IFF_UP) { ++ int ret; + +- if (netif_running(tp->netdev) && netif_carrier_ok(netdev)) +- r8153_set_rx_early_timeout(tp); +- } ++ ret = mutex_lock_interruptible(&tp->control); ++ if (ret < 0) ++ return ret; + +- mutex_unlock(&tp->control); ++ napi_disable(&tp->napi); ++ tp->rx_copybreak = rx_copybreak; ++ napi_enable(&tp->napi); + +- usb_autopm_put_interface(tp->intf); ++ mutex_unlock(&tp->control); ++ } else { ++ tp->rx_copybreak = rx_copybreak; ++ } ++ } + +- return ret; ++ return count; + } + +-static const struct ethtool_ops ops = { +- .get_drvinfo = rtl8152_get_drvinfo, +- .get_settings = rtl8152_get_settings, +- .set_settings = rtl8152_set_settings, +- .get_link = ethtool_op_get_link, +- .nway_reset = rtl8152_nway_reset, +- .get_msglevel = rtl8152_get_msglevel, +- .set_msglevel = rtl8152_set_msglevel, +- .get_wol = rtl8152_get_wol, +- .set_wol = rtl8152_set_wol, +- .get_strings = rtl8152_get_strings, +- .get_sset_count = rtl8152_get_sset_count, +- .get_ethtool_stats = rtl8152_get_ethtool_stats, +- .get_coalesce = rtl8152_get_coalesce, +- .set_coalesce = rtl8152_set_coalesce, +- .get_eee = rtl_ethtool_get_eee, +- .set_eee = rtl_ethtool_set_eee, +-}; ++static DEVICE_ATTR_RW(rx_copybreak); + +-static int rtl8152_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) ++static ssize_t fc_pause_show(struct device *dev, ++ struct device_attribute *attr, char *buf) + { ++ struct net_device *netdev = to_net_dev(dev); + struct r8152 *tp = netdev_priv(netdev); +- struct mii_ioctl_data *data = if_mii(rq); +- int res; +- +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) +- return -ENODEV; +- +- res = usb_autopm_get_interface(tp->intf); +- if (res < 0) +- goto out; +- +- switch (cmd) { +- case SIOCGMIIPHY: +- data->phy_id = R8152_PHY_ID; /* Internal PHY */ +- break; +- +- case SIOCGMIIREG: +- mutex_lock(&tp->control); +- data->val_out = r8152_mdio_read(tp, data->reg_num); +- mutex_unlock(&tp->control); +- break; + +- case SIOCSMIIREG: +- if (!capable(CAP_NET_ADMIN)) { +- res = -EPERM; +- break; +- } +- mutex_lock(&tp->control); +- r8152_mdio_write(tp, data->reg_num, data->val_in); +- mutex_unlock(&tp->control); +- break; ++ if (!tp->fc_pause) { ++ u32 fc_pause; + +- default: +- res = -EOPNOTSUPP; ++ fc_pause = netdev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; ++ fc_pause = 0x800 + ALIGN(fc_pause, 1024); ++ sprintf(buf, "(Auto)%u\n", fc_pause); ++ } else { ++ sprintf(buf, "%u\n", tp->fc_pause); + } +- +- usb_autopm_put_interface(tp->intf); +- +-out: +- return res; + -+#endif ++ return strlen(buf); + } + +-static int rtl8152_change_mtu(struct net_device *dev, int new_mtu) ++static ssize_t fc_pause_store(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) + { +- struct r8152 *tp = netdev_priv(dev); +- int ret; ++ struct net_device *netdev = to_net_dev(dev); ++ struct r8152 *tp = netdev_priv(netdev); ++ struct usb_interface *intf = tp->intf; ++ u32 fc_pause, fc_restart; ++ int ret = 0; + +- switch (tp->version) { +- case RTL_VER_01: +- case RTL_VER_02: +- case RTL_VER_07: +- dev->mtu = new_mtu; +- return 0; +- default: +- break; +- } ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return -ENODEV; + +- if (new_mtu < 68 || new_mtu > RTL8153_MAX_MTU) ++ if (sscanf(buf, "%u\n", &fc_pause) != 1) + return -EINVAL; + +- ret = usb_autopm_get_interface(tp->intf); +- if (ret < 0) +- return ret; ++ if (tp->fc_restart) { ++ fc_restart = tp->fc_restart; ++ } else { ++ fc_restart = netdev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; ++ fc_restart = 0x1800 + ALIGN(fc_restart, 1024); ++ } + +- mutex_lock(&tp->control); ++ if (fc_pause && (fc_pause >= fc_restart)) { ++ netif_err(tp, drv, netdev, "fc_pause must be less than %u\n", ++ fc_restart); ++ return -EINVAL; ++ } + +- dev->mtu = new_mtu; ++ if (tp->fc_pause != fc_pause) { ++ ret = usb_autopm_get_interface(intf); ++ if (ret < 0) ++ return ret; + +- if (netif_running(dev)) { +- u32 rms = new_mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; ++ ret = mutex_lock_interruptible(&tp->control); ++ if (ret < 0) ++ goto put; + +- ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, rms); ++ tp->fc_pause = fc_pause; + +- if (netif_carrier_ok(dev)) +- r8153_set_rx_early_size(tp); +- } ++ if (netdev->flags & IFF_UP) { ++ r8156_fc_parameter(tp); + +- mutex_unlock(&tp->control); ++ if (netif_carrier_ok(netdev)) { ++ netif_stop_queue(netdev); ++ napi_disable(&tp->napi); ++ tasklet_disable(&tp->tx_tl); ++ tp->rtl_ops.disable(tp); ++ tp->rtl_ops.enable(tp); ++ rtl_start_rx(tp); ++ tasklet_enable(&tp->tx_tl); ++ napi_enable(&tp->napi); ++ rtl8152_set_rx_mode(netdev); ++ netif_wake_queue(netdev); ++ } ++ } + +- usb_autopm_put_interface(tp->intf); ++ mutex_unlock(&tp->control); + +- return ret; ++put: ++ usb_autopm_put_interface(intf); ++ } ++ ++ if (ret < 0) ++ return ret; ++ else ++ return count; + } + +-static const struct net_device_ops rtl8152_netdev_ops = { +- .ndo_open = rtl8152_open, +- .ndo_stop = rtl8152_close, +- .ndo_do_ioctl = rtl8152_ioctl, +- .ndo_start_xmit = rtl8152_start_xmit, +- .ndo_tx_timeout = rtl8152_tx_timeout, +- .ndo_set_features = rtl8152_set_features, +- .ndo_set_rx_mode = rtl8152_set_rx_mode, +- .ndo_set_mac_address = rtl8152_set_mac_address, +- .ndo_change_mtu = rtl8152_change_mtu, +- .ndo_validate_addr = eth_validate_addr, +- .ndo_features_check = rtl8152_features_check, +-}; ++static DEVICE_ATTR_RW(fc_pause); + +-static void rtl8152_unload(struct r8152 *tp) ++static ssize_t fc_restart_show(struct device *dev, ++ struct device_attribute *attr, char *buf) + { +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) +- return; ++ struct net_device *netdev = to_net_dev(dev); ++ struct r8152 *tp = netdev_priv(netdev); + +- if (tp->version != RTL_VER_01) +- r8152_power_cut_en(tp, true); +-} ++ if (!tp->fc_restart) { ++ u32 fc_restart; + +-static void rtl8153_unload(struct r8152 *tp) +-{ +- if (test_bit(RTL8152_UNPLUG, &tp->flags)) +- return; ++ fc_restart = netdev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; ++ fc_restart = 0x1800 + ALIGN(fc_restart, 1024); ++ sprintf(buf, "(Auto)%u\n", fc_restart); ++ } else { ++ sprintf(buf, "%u\n", tp->fc_restart); ++ } + +- r8153_power_cut_en(tp, false); ++ return strlen(buf); + } + +-static void rtl8153b_unload(struct r8152 *tp) ++static ssize_t fc_restart_store(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) + { ++ struct net_device *netdev = to_net_dev(dev); ++ struct r8152 *tp = netdev_priv(netdev); ++ struct usb_interface *intf = tp->intf; ++ u32 fc_pause, fc_restart; ++ int ret = 0; ++ + if (test_bit(RTL8152_UNPLUG, &tp->flags)) +- return; ++ return -ENODEV; + +- r8153b_power_cut_en(tp, false); +-} ++ if (sscanf(buf, "%u\n", &fc_restart) != 1) ++ return -EINVAL; + +-static int rtl_ops_init(struct r8152 *tp) +-{ +- struct rtl_ops *ops = &tp->rtl_ops; +- int ret = 0; ++ if (tp->fc_pause) { ++ fc_pause = tp->fc_pause; ++ } else { ++ fc_pause = netdev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; ++ fc_pause = 0x800 + ALIGN(fc_pause, 1024); ++ } + +- switch (tp->version) { +- case RTL_VER_01: +- case RTL_VER_02: +- case RTL_VER_07: +- ops->init = r8152b_init; +- ops->enable = rtl8152_enable; +- ops->disable = rtl8152_disable; +- ops->up = rtl8152_up; +- ops->down = rtl8152_down; +- ops->unload = rtl8152_unload; +- ops->eee_get = r8152_get_eee; +- ops->eee_set = r8152_set_eee; +- ops->in_nway = rtl8152_in_nway; +- ops->hw_phy_cfg = r8152b_hw_phy_cfg; +- ops->autosuspend_en = rtl_runtime_suspend_enable; +- break; ++ if (fc_restart && (fc_restart <= tp->fc_pause)) { ++ netif_err(tp, drv, netdev, "fc_restart must be more than %u\n", ++ tp->fc_pause); ++ return -EINVAL; ++ } + +- case RTL_VER_03: +- case RTL_VER_04: +- case RTL_VER_05: +- case RTL_VER_06: +- ops->init = r8153_init; +- ops->enable = rtl8153_enable; +- ops->disable = rtl8153_disable; +- ops->up = rtl8153_up; +- ops->down = rtl8153_down; +- ops->unload = rtl8153_unload; +- ops->eee_get = r8153_get_eee; +- ops->eee_set = r8153_set_eee; +- ops->in_nway = rtl8153_in_nway; +- ops->hw_phy_cfg = r8153_hw_phy_cfg; +- ops->autosuspend_en = rtl8153_runtime_enable; +- break; ++ if (tp->fc_restart != fc_restart) { ++ ret = usb_autopm_get_interface(intf); ++ if (ret < 0) ++ return ret; + +- case RTL_VER_08: +- case RTL_VER_09: +- ops->init = r8153b_init; +- ops->enable = rtl8153_enable; +- ops->disable = rtl8153b_disable; +- ops->up = rtl8153b_up; +- ops->down = rtl8153b_down; +- ops->unload = rtl8153b_unload; +- ops->eee_get = r8153_get_eee; +- ops->eee_set = r8153b_set_eee; +- ops->in_nway = rtl8153_in_nway; +- ops->hw_phy_cfg = r8153b_hw_phy_cfg; +- ops->autosuspend_en = rtl8153b_runtime_enable; +- break; ++ ret = mutex_lock_interruptible(&tp->control); ++ if (ret < 0) ++ goto put; + +- default: +- ret = -ENODEV; +- netif_err(tp, probe, tp->netdev, "Unknown Device\n"); +- break; ++ tp->fc_restart = fc_restart; ++ ++ if (netdev->flags & IFF_UP) { ++ r8156_fc_parameter(tp); ++ ++ if (netif_carrier_ok(netdev)) { ++ netif_stop_queue(netdev); ++ napi_disable(&tp->napi); ++ tasklet_disable(&tp->tx_tl); ++ tp->rtl_ops.disable(tp); ++ tp->rtl_ops.enable(tp); ++ rtl_start_rx(tp); ++ tasklet_enable(&tp->tx_tl); ++ napi_enable(&tp->napi); ++ rtl8152_set_rx_mode(netdev); ++ netif_wake_queue(netdev); ++ } ++ } ++ ++ mutex_unlock(&tp->control); ++ ++put: ++ usb_autopm_put_interface(intf); + } + +- return ret; ++ if (ret < 0) ++ return ret; ++ else ++ return count; + } + +-static u8 rtl_get_version(struct usb_interface *intf) +-{ +- struct usb_device *udev = interface_to_usbdev(intf); +- u32 ocp_data = 0; +- __le32 *tmp; +- u8 version; +- int ret; ++static DEVICE_ATTR_RW(fc_restart); + +- tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); +- if (!tmp) +- return 0; ++static ssize_t ++sg_en_show(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct net_device *netdev = to_net_dev(dev); ++ struct r8152 *tp = netdev_priv(netdev); + +- ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), +- RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, +- PLA_TCR0, MCU_TYPE_PLA, tmp, sizeof(*tmp), 500); +- if (ret > 0) +- ocp_data = (__le32_to_cpu(*tmp) >> 16) & VERSION_MASK; ++ if (tp->sg_use) ++ strcat(buf, "enable\n"); ++ else ++ strcat(buf, "disable\n"); + +- kfree(tmp); ++ return strlen(buf); ++} + +- switch (ocp_data) { +- case 0x4c00: +- version = RTL_VER_01; +- break; +- case 0x4c10: +- version = RTL_VER_02; +- break; +- case 0x5c00: +- version = RTL_VER_03; +- break; +- case 0x5c10: +- version = RTL_VER_04; +- break; +- case 0x5c20: +- version = RTL_VER_05; +- break; +- case 0x5c30: +- version = RTL_VER_06; +- break; +- case 0x4800: +- version = RTL_VER_07; +- break; +- case 0x6000: +- version = RTL_VER_08; +- break; +- case 0x6010: +- version = RTL_VER_09; +- break; +- default: +- version = RTL_VER_UNKNOWN; +- dev_info(&intf->dev, "Unknown version 0x%04x\n", ocp_data); +- break; ++static ssize_t sg_en_store(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct net_device *netdev = to_net_dev(dev); ++ struct r8152 *tp = netdev_priv(netdev); ++ u32 tso_size; ++ ++ if (!strncmp(buf, "enable", 6) && ++ usb_device_no_sg_constraint(tp->udev)) { ++ tp->sg_use = true; ++ tso_size = GSO_MAX_SIZE; ++ } else if (!strncmp(buf, "disable", 7)) { ++ tp->sg_use = false; ++ tso_size = RTL_LIMITED_TSO_SIZE; ++ } else { ++ return -EINVAL; + } + +- dev_dbg(&intf->dev, "Detected version 0x%04x\n", version); ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) ++ netif_set_gso_max_size(netdev, tso_size); ++#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) */ + +- return version; ++ return count; + } + ++static DEVICE_ATTR_RW(sg_en); ++ ++static struct attribute *rtk_adv_attrs[] = { ++ &dev_attr_rx_copybreak.attr, ++ &dev_attr_sg_en.attr, ++ &dev_attr_fc_pause.attr, ++ &dev_attr_fc_restart.attr, ++ NULL ++}; ++ ++static struct attribute_group rtk_adv_grp = { ++ .name = "rtl_adv", ++ .attrs = rtk_adv_attrs, ++}; + static int rtl8152_probe(struct usb_interface *intf, const struct usb_device_id *id) { -@@ -5170,8 +12730,12 @@ static int rtl8152_probe(struct usb_interface *intf, +@@ -5181,8 +18407,12 @@ static int rtl8152_probe(struct usb_interface *intf, if (version == RTL_VER_UNKNOWN) return -ENODEV; @@ -10575,7 +18111,7 @@ index 2490498b..26cc7c1a 100644 return -ENODEV; } -@@ -5209,14 +12773,35 @@ static int rtl8152_probe(struct usb_interface *intf, +@@ -5223,14 +18453,40 @@ static int rtl8152_probe(struct usb_interface *intf, mutex_init(&tp->control); INIT_DELAYED_WORK(&tp->schedule, rtl_work_func_t); INIT_DELAYED_WORK(&tp->hw_phy_work, rtl_hw_phy_work_func_t); @@ -10583,6 +18119,11 @@ index 2490498b..26cc7c1a 100644 + tasklet_init(&tp->tx_tl, bottom_half, (unsigned long)tp); + tasklet_disable(&tp->tx_tl); + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,3) ++ if (usb_device_no_sg_constraint(udev)) ++ tp->sg_use = true; ++#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,3) */ ++ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) + netdev->open = rtl8152_open; + netdev->stop = rtl8152_close; @@ -10612,7 +18153,7 @@ index 2490498b..26cc7c1a 100644 netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO | NETIF_F_FRAGLIST | NETIF_F_IPV6_CSUM | NETIF_F_TSO6 | -@@ -5224,20 +12809,35 @@ static int rtl8152_probe(struct usb_interface *intf, +@@ -5238,20 +18494,39 @@ static int rtl8152_probe(struct usb_interface *intf, netdev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | NETIF_F_IPV6_CSUM | NETIF_F_TSO6; @@ -10622,18 +18163,22 @@ index 2490498b..26cc7c1a 100644 netdev->features &= ~NETIF_F_RXCSUM; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39) netdev->hw_features &= ~NETIF_F_RXCSUM; -- } -- ++#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39) */ + } + - if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x3011 && udev->serial && - (!strcmp(udev->serial, "000001000000") || !strcmp(udev->serial, "000002000000"))) { - dev_info(&udev->dev, "Dell TB16 Dock, disable RX aggregation"); - set_bit(DELL_TB_RX_AGG_BUG, &tp->flags); -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39) */ - } +- } ++ if (le16_to_cpu(udev->descriptor.idVendor) == VENDOR_ID_LENOVO) ++ tp->lenovo_macpassthru = 1; netdev->ethtool_ops = &ops; +- netif_set_gso_max_size(netdev, RTL_LIMITED_TSO_SIZE); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) - netif_set_gso_max_size(netdev, RTL_LIMITED_TSO_SIZE); ++ if (!tp->sg_use) ++ netif_set_gso_max_size(netdev, RTL_LIMITED_TSO_SIZE); +#else + netdev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6); +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) */ @@ -10654,7 +18199,7 @@ index 2490498b..26cc7c1a 100644 tp->mii.dev = netdev; tp->mii.mdio_read = read_mii_word; -@@ -5245,13 +12845,34 @@ static int rtl8152_probe(struct usb_interface *intf, +@@ -5259,11 +18534,29 @@ static int rtl8152_probe(struct usb_interface *intf, tp->mii.phy_id_mask = 0x3f; tp->mii.reg_num_mask = 0x1f; tp->mii.phy_id = R8152_PHY_ID; @@ -10665,41 +18210,45 @@ index 2490498b..26cc7c1a 100644 tp->autoneg = AUTONEG_ENABLE; - tp->speed = tp->mii.supports_gmii ? SPEED_1000 : SPEED_100; + tp->speed = SPEED_100; -+ tp->advertising = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | -+ ADVERTISED_100baseT_Half | -+ ADVERTISED_100baseT_Full; ++ tp->advertising = RTL_ADVERTISED_10_HALF | RTL_ADVERTISED_10_FULL | ++ RTL_ADVERTISED_100_HALF | RTL_ADVERTISED_100_FULL; + if (tp->mii.supports_gmii) { -+ if (test_bit(SUPPORT_2500FULL, &tp->flags) && ++ if (tp->support_2500full && + tp->udev->speed >= USB_SPEED_SUPER) { + tp->speed = SPEED_2500; -+ tp->advertising |= ADVERTISED_2500baseX_Full; ++ tp->advertising |= RTL_ADVERTISED_2500_FULL; + } else { + tp->speed = SPEED_1000; + } -+ tp->advertising |= ADVERTISED_1000baseT_Full; ++ tp->advertising |= RTL_ADVERTISED_1000_FULL; + } tp->duplex = DUPLEX_FULL; ++ tp->rx_copybreak = RTL8152_RXFG_HEADSZ; ++ tp->rx_pending = 10 * RTL8152_MAX_RX; ++ intf->needs_remote_wakeup = 1; -+ if (!rtl_can_wakeup(tp)) -+ __rtl_set_wol(tp, 0); -+ else -+ tp->saved_wolopts = __rtl_get_wol(tp); -+ - tp->rtl_ops.init(tp); - queue_delayed_work(system_long_wq, &tp->hw_phy_work, 0); + if (!rtl_can_wakeup(tp)) +@@ -5276,11 +18569,15 @@ static int rtl8152_probe(struct usb_interface *intf, set_ethernet_addr(tp); -@@ -5265,21 +12886,26 @@ static int rtl8152_probe(struct usb_interface *intf, + + usb_set_intfdata(intf, tp); +- netif_napi_add(netdev, &tp->napi, r8152_poll, RTL8152_NAPI_WEIGHT); ++ ++ if (tp->support_2500full) ++ netif_napi_add(netdev, &tp->napi, r8152_poll, 256); ++ else ++ netif_napi_add(netdev, &tp->napi, r8152_poll, 64); + + ret = register_netdev(netdev); + if (ret != 0) { +- netif_err(tp, probe, netdev, "couldn't register the device\n"); ++ dev_err(&intf->dev, "couldn't register the device\n"); goto out1; } -- if (!rtl_can_wakeup(tp)) -- __rtl_set_wol(tp, 0); -- -- tp->saved_wolopts = __rtl_get_wol(tp); - if (tp->saved_wolopts) - device_set_wakeup_enable(&udev->dev, true); +@@ -5289,12 +18586,36 @@ static int rtl8152_probe(struct usb_interface *intf, else device_set_wakeup_enable(&udev->dev, false); @@ -10708,26 +18257,42 @@ index 2490498b..26cc7c1a 100644 netif_info(tp, probe, netdev, "%s\n", DRIVER_VERSION); + netif_info(tp, probe, netdev, "%s\n", PATENTS); + ++ ret = sysfs_create_group(&netdev->dev.kobj, &rtk_adv_grp); ++ if (ret < 0) { ++ netif_err(tp, probe, netdev, "creat rtk_adv_grp fail\n"); ++ goto out2; ++ } ++ +#ifdef RTL8152_DEBUG -+ if (sysfs_create_group(&intf->dev.kobj, &rtk_attr_grp) < 0) -+ netif_err(tp, probe, netdev, "creat rtk_attr_grp fail\n"); ++ ret = sysfs_create_group(&netdev->dev.kobj, &rtk_dbg_grp); ++ if (ret < 0) { ++ netif_err(tp, probe, netdev, "creat rtk_dbg_grp fail\n"); ++ goto out3; ++ } +#endif return 0; ++#ifdef RTL8152_DEBUG ++out3: ++ sysfs_remove_group(&intf->dev.kobj, &rtk_adv_grp); ++#endif ++out2: ++ unregister_netdev(netdev); out1: netif_napi_del(&tp->napi); + tasklet_kill(&tp->tx_tl); usb_set_intfdata(intf, NULL); out: free_netdev(netdev); -@@ -5290,54 +12916,73 @@ static void rtl8152_disconnect(struct usb_interface *intf) +@@ -5305,54 +18626,79 @@ static void rtl8152_disconnect(struct usb_interface *intf) { struct r8152 *tp = usb_get_intfdata(intf); +#ifdef RTL8152_DEBUG -+ sysfs_remove_group(&intf->dev.kobj, &rtk_attr_grp); ++ sysfs_remove_group(&intf->dev.kobj, &rtk_dbg_grp); +#endif ++ sysfs_remove_group(&intf->dev.kobj, &rtk_adv_grp); + usb_set_intfdata(intf, NULL); if (tp) { @@ -10780,6 +18345,7 @@ index 2490498b..26cc7c1a 100644 {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8050)}, {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8152)}, {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8153)}, ++ {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8155)}, + {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8156)}, + + /* Microsoft */ @@ -10819,10 +18385,14 @@ index 2490498b..26cc7c1a 100644 + /* Nvidia */ {REALTEK_USB_DEVICE(VENDOR_ID_NVIDIA, 0x09ff)}, - {REALTEK_USB_DEVICE(VENDOR_ID_TPLINK, 0x0601)}, ++ ++ /* LINKSYS */ ++ {REALTEK_USB_DEVICE(VENDOR_ID_LINKSYS, 0x0041)}, ++ {} }; -@@ -5354,7 +12999,9 @@ static struct usb_driver rtl8152_driver = { +@@ -5369,7 +18715,9 @@ static struct usb_driver rtl8152_driver = { .pre_reset = rtl8152_pre_reset, .post_reset = rtl8152_post_reset, .supports_autosuspend = 1, @@ -10832,3 +18402,6 @@ index 2490498b..26cc7c1a 100644 }; module_usb_driver(rtl8152_driver); +-- +Created with Armbian build tools https://github.com/armbian/build + diff --git a/patch/kernel/rockchip64-current/add-board-helios64.patch b/patch/kernel/rockchip64-current/add-board-helios64.patch new file mode 100644 index 0000000000..6d0081f275 --- /dev/null +++ b/patch/kernel/rockchip64-current/add-board-helios64.patch @@ -0,0 +1,1114 @@ +From c2dafa427696ae0edd9f1348a00e90a22edddace Mon Sep 17 00:00:00 2001 +From: Aditya Prayoga +Date: Mon, 3 Aug 2020 02:53:02 +0700 +Subject: [PATCH] Add board Helios64 + +Signed-off-by: Aditya Prayoga +--- + arch/arm64/boot/dts/rockchip/Makefile | 1 + + .../boot/dts/rockchip/rk3399-helios64.dts | 1080 +++++++++++++++++ + 2 files changed, 1081 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-helios64.dts + +diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile +index 06ddfb869..b8a273c91 100644 +--- a/arch/arm64/boot/dts/rockchip/Makefile ++++ b/arch/arm64/boot/dts/rockchip/Makefile +@@ -19,6 +19,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-bob.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-kevin.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-scarlet-inx.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-scarlet-kd.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-helios64.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-hugsun-x99.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-khadas-edge.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-khadas-edge-captain.dtb +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-helios64.dts b/arch/arm64/boot/dts/rockchip/rk3399-helios64.dts +new file mode 100644 +index 000000000..342589131 +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3399-helios64.dts +@@ -0,0 +1,1080 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2020 Aditya Prayoga (aditya@kobol.io) ++ */ ++ ++/dts-v1/; ++#include ++#include ++#include ++#include ++#include "rk3399.dtsi" ++#include "rk3399-opp.dtsi" ++ ++/ { ++ model = "Helios64"; ++ compatible = "kobol,helios64", "rockchip,rk3399"; ++ ++ adc-keys { ++ compatible = "adc-keys"; ++ io-channels = <&saradc 1>; ++ io-channel-names = "buttons"; ++ keyup-threshold-microvolt = <1800000>; ++ poll-interval = <100>; ++ ++ user2-button { ++ label = "User Button 2"; ++ linux,code = ; ++ press-threshold-microvolt = <100000>; ++ }; ++ }; ++ ++ beeper: beeper { ++ compatible = "gpio-beeper"; ++ gpios = <&gpio4 RK_PD3 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ clkin_gmac: external-gmac-clock { ++ compatible = "fixed-clock"; ++ clock-frequency = <125000000>; ++ clock-output-names = "clkin_gmac"; ++ #clock-cells = <0>; ++ }; ++ ++ vcc12v_dcin: vcc12v-dcin { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc12v_dcin"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ }; ++ ++ vcc12v_dcin_bkup: vcc12v-dcin-bkup { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc12v_dcin_bkup"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ vin-supply = <&vcc12v_dcin>; ++ }; ++ ++ vcc12v_hdd: vcc12v-hdd { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc12v_hdd"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ vin-supply = <&vcc12v_dcin_bkup>; ++ }; ++ ++ /* switched by pmic_sleep */ ++ vcc1v8_sys_s0: vcc1v8-sys-s0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc1v8_sys_s0"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ vin-supply = <&vcc1v8_sys_s3>; ++ }; ++ ++ vcc0v9_s3: vcc0v9-s3 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc0v9_s3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ vin-supply = <&vcc3v3_sys_s3>; ++ }; ++ ++ avdd_0v9_s0: avdd-0v9-s0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "avdd_0v9_s0"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ vin-supply = <&vcc1v8_sys_s3>; ++ }; ++ ++ avdd_1v8_s0: avdd-1v8-s0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "avdd_1v8_s0"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ vin-supply = <&vcc3v3_sys_s3>; ++ }; ++ ++ pcie_power: pcie-power { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio1 RK_PD0 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie_pwr_en>; ++ regulator-name = "pcie_power"; ++ regulator-boot-on; ++ startup-delay-us = <10000>; ++ vin-supply = <&vcc5v0_perdev>; ++ }; ++ ++ vcc3v3_sys_s3: vcc_lan: vcc3v3-sys-s3 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v3_sys_s3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc5v0_sys>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc3v0_sd: vcc3v0-sd { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v0_sd"; ++ regulator-boot-on; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ vin-supply = <&vcc3v3_sys_s3>; ++ }; ++ ++ vcc5v0_usb: vcc5v0-usb { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio1 RK_PC6 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vcc5v0_usb_en>; ++ regulator-name = "vcc5v0_usb"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc5v0_perdev>; ++ }; ++ ++ vcc5v0_perdev: vcc5v0-perdev { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_perdev"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc12v_dcin_bkup>; ++ }; ++ ++ vcc5v0_hdd: vcc5v0-hdd { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_hdd"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc12v_dcin_bkup>; ++ }; ++ ++ vcc5v0_sys: vcc5v0-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc12v_dcin_bkup>; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vdd_log: vdd-log { ++ compatible = "pwm-regulator"; ++ pwms = <&pwm2 0 25000 1>; ++ regulator-name = "vdd_log"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <1400000>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ power_hdd_a: power-hdd-a { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hdd_a_power>; ++ regulator-name = "power_hdd_a"; ++ regulator-always-on; ++ regulator-boot-on; ++ startup-delay-us = <2000000>; ++ }; ++ ++ power_hdd_b: power-hdd-b { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio1 RK_PA1 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hdd_b_power>; ++ regulator-name = "power_hdd_b"; ++ regulator-always-on; ++ regulator-boot-on; ++ startup-delay-us = <2000000>; ++ }; ++ ++ usblan_power: usblan-power { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio1 RK_PC7 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usb_lan_en>; ++ regulator-name = "usblan_power"; ++ regulator-always-on; ++ regulator-boot-on; ++ vin-supply = <&vcc5v0_usb>; ++ }; ++ ++ fan1: p7-fan { ++ compatible = "pwm-fan"; ++ pwms = <&pwm0 0 40000 0>; ++ cooling-min-state = <0>; ++ cooling-max-state = <3>; ++ #cooling-cells = <2>; ++ cooling-levels = <0 80 170 255>; ++ }; ++ ++ fan2: p6-fan { ++ compatible = "pwm-fan"; ++ pwms = <&pwm1 0 40000 0>; ++ cooling-min-state = <0>; ++ cooling-max-state = <3>; ++ #cooling-cells = <2>; ++ cooling-levels = <0 80 170 255>; ++ }; ++ ++ gpio-charger { ++ compatible = "gpio-charger"; ++ charger-type = "mains"; ++ gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; ++ charge-status-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ac_present_ap>, <&charger_status>; ++ }; ++ ++ gpio-keys { ++ compatible = "gpio-keys"; ++ autorepeat; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwrbtn>, <&user1btn>, <&wake_on_lan>; ++ ++ power { ++ debounce-interval = <100>; ++ gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>; ++ label = "Power"; ++ linux,code = ; ++ wakeup-source; ++ }; ++ ++ user1-button { ++ debounce-interval = <100>; ++ gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_LOW>; ++ label = "User Button 1"; ++ linux,code = ; ++ wakeup-source; ++ }; ++ }; ++ ++ hdmi_dp_sound: hdmi-dp-sound { ++ status = "okay"; ++ compatible = "rockchip,rk3399-hdmi-dp"; ++ rockchip,cpu = <&i2s2>; ++ rockchip,codec = <&cdn_dp>; ++ }; ++ ++ io_leds: io-gpio-leds { ++ status = "okay"; ++ compatible = "gpio-leds"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&network_act>, <&usb3_act>, ++ <&sata_act>, <&sata_err_led>; ++ ++ network { ++ label = "helios64:blue:net"; ++ gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "netdev"; ++ default-state = "off"; ++ }; ++ ++ sata { ++ label = "helios64:blue:hdd-status"; ++ gpios = <&gpio4 RK_PD4 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "disk-activity"; ++ default-state = "off"; ++ }; ++ ++ sata_err1 { ++ label = "helios64:red:ata1-err"; ++ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_HIGH>; ++ default-state = "keep"; ++ }; ++ ++ sata_err2 { ++ label = "helios64:red:ata2-err"; ++ gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_HIGH>; ++ default-state = "keep"; ++ }; ++ ++ sata_err3 { ++ label = "helios64:red:ata3-err"; ++ gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_HIGH>; ++ default-state = "keep"; ++ }; ++ ++ sata_err4 { ++ label = "helios64:red:ata4-err"; ++ gpios = <&gpio2 RK_PA5 GPIO_ACTIVE_HIGH>; ++ default-state = "keep"; ++ }; ++ ++ sata_err5 { ++ label = "helios64:red:ata5-err"; ++ gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_HIGH>; ++ default-state = "keep"; ++ }; ++ ++ usb3 { ++ label = "helios64:blue:usb3"; ++ gpios = <&gpio0 RK_PB3 GPIO_ACTIVE_HIGH>; ++ trigger-sources = <&int_hub_port1>, ++ <&int_hub_port2>, ++ <&int_hub_port3>; ++ linux,default-trigger = "usbport"; ++ default-state = "off"; ++ }; ++ }; ++ ++ pwmleds { ++ compatible = "pwm-leds"; ++ status = "okay"; ++ ++ power-led { ++ label = "helios64:blue:power-status"; ++ pwms = <&pwm3 0 2000000000 0>; ++ max-brightness = <255>; ++ }; ++ }; ++ ++ system_leds: system-gpio-leds { ++ status = "okay"; ++ compatible = "gpio-leds"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&system_led>; ++ ++ status-led { ++ label = "helios64::status"; ++ gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "none"; ++ default-state = "on"; ++ mode = <0x23>; ++ }; ++ ++ fault-led { ++ label = "helios64:red:fault"; ++ gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "none"; ++ default-state = "keep"; ++ mode = <0x23>; ++ }; ++ }; ++}; ++ ++&cdn_dp { ++ status = "okay"; ++ extcon = <&fusb0>; ++ phys = <&tcphy0_dp>; ++}; ++ ++&cpu_l0 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_l1 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_l2 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_l3 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_b0 { ++ cpu-supply = <&vdd_cpu_b>; ++}; ++ ++&cpu_b1 { ++ cpu-supply = <&vdd_cpu_b>; ++}; ++ ++&emmc_phy { ++ status = "okay"; ++}; ++ ++&gmac { ++ assigned-clocks = <&cru SCLK_RMII_SRC>; ++ assigned-clock-parents = <&clkin_gmac>; ++ clock_in_out = "input"; ++ phy-supply = <&vcc_lan>; ++ phy-mode = "rgmii"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rgmii_pins &rgmii_phy_reset>; ++ snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; ++ snps,reset-active-low; ++ snps,reset-delays-us = <0 10000 50000>; ++ tx_delay = <0x28>; ++ rx_delay = <0x20>; ++ status = "okay"; ++}; ++ ++&gpu { ++ mali-supply = <&vdd_gpu>; ++ status = "okay"; ++}; ++ ++&i2c0 { ++ clock-frequency = <400000>; ++ i2c-scl-rising-time-ns = <168>; ++ i2c-scl-falling-time-ns = <4>; ++ status = "okay"; ++ ++ rk808: pmic@1b { ++ compatible = "rockchip,rk808"; ++ reg = <0x1b>; ++ #clock-cells = <1>; ++ clock-output-names = "xin32k", "rk808-clkout2"; ++ interrupt-parent = <&gpio0>; ++ interrupts = <10 IRQ_TYPE_LEVEL_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int_l>; ++ rockchip,system-power-controller; ++ wakeup-source; ++ ++ vcc1-supply = <&vcc5v0_sys>; ++ vcc2-supply = <&vcc5v0_sys>; ++ vcc3-supply = <&vcc5v0_sys>; ++ vcc4-supply = <&vcc5v0_sys>; ++ vcc6-supply = <&vcc5v0_sys>; ++ vcc7-supply = <&vcc5v0_sys>; ++ vcc8-supply = <&vcc3v3_sys_s3>; ++ vcc9-supply = <&vcc5v0_sys>; ++ vcc10-supply = <&vcc5v0_sys>; ++ vcc11-supply = <&vcc5v0_sys>; ++ vcc12-supply = <&vcc3v3_sys_s3>; ++ vddio-supply = <&vcc3v0_s3>; ++ ++ regulators { ++ vdd_center: DCDC_REG1 { ++ regulator-name = "vdd_center"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_cpu_l: DCDC_REG2 { ++ regulator-name = "vdd_cpu_l"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_ddr_s3: DCDC_REG3 { ++ regulator-name = "vcc_ddr_s3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc1v8_sys_s3: DCDC_REG4 { ++ regulator-name = "vcc1v8_sys_s3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ /* not used */ ++ vcc1v8_dvp: LDO_REG1 { ++ regulator-name = "vcc1v8_dvp"; ++ }; ++ ++ /* not used */ ++ vcc3v0_touch: LDO_REG2 { ++ regulator-name = "vcc3v0_touch"; ++ }; ++ ++ vcc1v8_s3: LDO_REG3 { ++ regulator-name = "vcc1v8_s3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc_sdio_s0: LDO_REG4 { ++ regulator-name = "vcc_sdio_s0"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3000000>; ++ }; ++ }; ++ ++ /* not used */ ++ vcca3v0_codec: LDO_REG5 { ++ regulator-name = "vcca3v0_codec"; ++ }; ++ ++ vcc1v5_s3: LDO_REG6 { ++ regulator-name = "vcc1v5_s3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1500000>; ++ regulator-max-microvolt = <1500000>; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1500000>; ++ }; ++ }; ++ ++ /* not used */ ++ vcca1v8_codec: LDO_REG7 { ++ regulator-name = "vcca1v8_codec"; ++ }; ++ ++ vcc3v0_s3: LDO_REG8 { ++ regulator-name = "vcc3v0_s3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3000000>; ++ }; ++ }; ++ ++ vcc3v3_sys_s0: SWITCH_REG1 { ++ regulator-name = "vcc3v3_sys_s0"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ /* not used */ ++ vcc3v3_s0: SWITCH_REG2 { ++ regulator-name = "vcc3v3_s0"; ++ }; ++ }; ++ }; ++ ++ vdd_cpu_b: regulator@40 { ++ compatible = "silergy,syr827"; ++ reg = <0x40>; ++ fcs,suspend-voltage-selector = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vsel1_gpio>; ++ regulator-name = "vdd_cpu_b"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1500000>; ++ regulator-ramp-delay = <1000>; ++ regulator-always-on; ++ regulator-boot-on; ++ vin-supply = <&vcc5v0_sys>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_gpu: regulator@41 { ++ compatible = "silergy,syr828"; ++ reg = <0x41>; ++ fcs,suspend-voltage-selector = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vsel2_gpio>; ++ regulator-name = "vdd_gpu"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1500000>; ++ regulator-ramp-delay = <1000>; ++ regulator-always-on; ++ regulator-boot-on; ++ vin-supply = <&vcc5v0_sys>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++}; ++ ++&i2c2 { ++ clock-frequency = <400000>; ++ i2c-scl-rising-time-ns = <160>; ++ i2c-scl-falling-time-ns = <30>; ++ status = "okay"; ++ ++ gpio-expander@20 { ++ compatible = "nxp,pca9555"; ++ reg = <0x20>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pca0_pins>; ++ interrupt-parent = <&gpio0>; ++ interrupts = <9 IRQ_TYPE_EDGE_FALLING>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ vcc-supply = <&vcc3v3_sys_s3>; ++ }; ++ ++ temp@4c { ++ compatible = "onnn,lm75"; ++ reg = <0x4c>; ++ }; ++}; ++ ++&i2c4 { ++ clock-frequency = <400000>; ++ i2c-scl-rising-time-ns = <160>; ++ i2c-scl-falling-time-ns = <30>; ++ status = "okay"; ++ ++ fusb0: typec-portc@22 { ++ compatible = "fairchild,fusb302"; ++ reg = <0x22>; ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&fusb0_int>, <&fusb0_vbus_en>; ++ vbus-5v-gpios = <&gpio1 RK_PA3 GPIO_ACTIVE_HIGH>; ++ int-n-gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>; ++ fusb302,role = "ROLE_MODE_DRP"; ++ fusb302,try_role = "ROLE_MODE_UFP"; ++ }; ++}; ++ ++/* I2C on UEXT */ ++&i2c7 { ++ status = "okay"; ++}; ++ ++/* External I2C */ ++&i2c8 { ++ status = "okay"; ++}; ++ ++&i2s2 { ++ #sound-dai-cells = <0>; ++ status = "okay"; ++}; ++ ++&io_domains { ++ status = "okay"; ++ bt656-supply = <&vcc1v8_sys_s0>; ++ audio-supply = <&vcc1v8_sys_s0>; ++ sdmmc-supply = <&vcc_sdio_s0>; ++ gpio1830-supply = <&vcc3v0_s3>; ++}; ++ ++&pcie0 { ++ ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>; ++ num-lanes = <2>; ++ max-link-speed = <2>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie_prst &pcie_clkreqn_cpm>; ++ vpcie12v-supply = <&vcc12v_dcin>; ++ vpcie3v3-supply = <&pcie_power>; ++ vpcie1v8-supply = <&avdd_1v8_s0>; ++ vpcie0v9-supply = <&avdd_0v9_s0>; ++ status = "okay"; ++}; ++ ++&pcie_phy { ++ status = "okay"; ++}; ++ ++&pinctrl { ++ buttons { ++ pwrbtn: pwrbtn { ++ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ ++ user1btn: usr1btn { ++ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ charger { ++ ac_present_ap: ac-present-ap { ++ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ charger_status: charger-status { ++ rockchip,pins = <2 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ fan { ++ fan1_sense: fan1-sense { ++ rockchip,pins = <4 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ fan2_sense: fan2-sense { ++ rockchip,pins = <4 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ fusb30x { ++ fusb0_int: fusb0-int { ++ rockchip,pins = ++ <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ ++ fusb0_vbus_en: fusb0-vbus-en { ++ rockchip,pins = ++ <1 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ gmac { ++ rgmii_phy_reset: rgmii-phy-reset { ++ rockchip,pins = ++ <3 RK_PB7 RK_FUNC_GPIO &pcfg_output_low>; ++ }; ++ }; ++ ++ leds { ++ network_act: network-act { ++ rockchip,pins = ++ <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ ++ usb3_act: usb3-act { ++ rockchip,pins = ++ <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ ++ sata_act: sata-act { ++ rockchip,pins = ++ <4 RK_PD4 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ ++ system_led: sys-led { ++ rockchip,pins = ++ <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_down>, ++ <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ ++ sata_err_led: sata-err-led { ++ rockchip,pins = ++ <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_down>, ++ <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_down>, ++ <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_down>, ++ <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_down>, ++ <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ }; ++ ++ misc { ++ pca0_pins: pca0-pins { ++ rockchip,pins = ++ <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ wake_on_lan: wake-on-lan { ++ rockchip,pins = ++ <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pcie { ++ pcie_prst: pcie-prst { ++ rockchip,pins = ++ <2 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ pcie_pwr_en: pcie-pwr-en { ++ rockchip,pins = ++ <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = ++ <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ ++ vsel1_gpio: vsel1-gpio { ++ rockchip,pins = ++ <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ ++ vsel2_gpio: vsel2-gpio { ++ rockchip,pins = ++ <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ }; ++ ++ power { ++ hdd_a_power: hdd-a-power { ++ rockchip,pins = ++ <1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ hdd_b_power: hdd-b-power { ++ rockchip,pins = ++ <1 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ vcc5v0_usb_en: vcc5v0-usb-en { ++ rockchip,pins = ++ <1 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ sdmmc0_pwr_h: sdmmc0-pwr-h { ++ rockchip,pins = ++ ; ++ }; ++ ++ usb_lan_en: usb-lan-en { ++ rockchip,pins = ++ <1 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&pmu_io_domains { ++ pmu1830-supply = <&vcc3v0_s3>; ++ status = "okay"; ++}; ++ ++&pwm0 { ++ status = "okay"; ++}; ++ ++&pwm1 { ++ status = "okay"; ++}; ++ ++&pwm2 { ++ status = "okay"; ++}; ++ ++&pwm3 { ++ status = "okay"; ++}; ++ ++&saradc { ++ vref-supply = <&vcc1v8_s3>; ++ status = "okay"; ++}; ++ ++&sdhci { ++ bus-width = <8>; ++ mmc-hs400-1_8v; ++ mmc-hs200-1_8v; ++ mmc-hs400-enhanced-strobe; ++ supports-emmc; ++ non-removable; ++ disable-wp; ++ status = "okay"; ++ vqmmc-supply = <&vcc1v8_sys_s0>; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ disable-wp; ++ sd-uhs-sdr104; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; ++ vmmc-supply = <&vcc3v0_sd>; ++ vqmmc-supply = <&vcc_sdio_s0>; ++ status = "okay"; ++}; ++ ++&spi1 { ++ status = "okay"; ++}; ++ ++/* UEXT connector */ ++&spi2 { ++ status = "okay"; ++}; ++ ++&spi5 { ++ status = "okay"; ++}; ++ ++&tcphy0 { ++ extcon = <&fusb0>; ++ status = "okay"; ++}; ++ ++&tcphy1 { ++ status = "okay"; ++}; ++ ++&tsadc { ++ /* tshut mode 0:CRU 1:GPIO */ ++ rockchip,hw-tshut-mode = <1>; ++ /* tshut polarity 0:LOW 1:HIGH */ ++ rockchip,hw-tshut-polarity = <1>; ++ status = "okay"; ++}; ++ ++&u2phy0 { ++ status = "okay"; ++ extcon = <&fusb0>; ++ ++ u2phy0_otg: otg-port { ++ status = "okay"; ++ }; ++ ++ u2phy0_host: host-port { ++ phy-supply = <&vcc5v0_usb>; ++ status = "okay"; ++ }; ++}; ++ ++&u2phy1 { ++ status = "okay"; ++ ++ u2phy1_otg: otg-port { ++ status = "okay"; ++ }; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_xfer>; ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usbdrd3_0 { ++ extcon = <&fusb0>; ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3_0 { ++ status = "okay"; ++ dr_mode = "otg"; ++}; ++ ++&usbdrd3_1 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3_1 { ++ status = "okay"; ++ dr_mode = "host"; ++ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ int_hub: hub@1 { ++ compatible = "usb2109,0815"; ++ reg = <1>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ int_hub_port1: port@1 { ++ reg = <1>; ++ #trigger-source-cells = <0>; ++ }; ++ ++ int_hub_port2: port@2 { ++ reg = <2>; ++ #trigger-source-cells = <0>; ++ }; ++ ++ int_hub_port3: port@3 { ++ reg = <3>; ++ #trigger-source-cells = <0>; ++ }; ++ ++ usb_lan: device@4 { ++ compatible = "usbbda,8156"; ++ reg = <4>; ++ ++ #address-cells = <2>; ++ #size-cells = <0>; ++ ++ interface@0 { /* interface 0 of configuration 1 */ ++ compatible = "usbbda,8156.config1.0"; ++ reg = <0 1>; ++ }; ++ }; ++ }; ++}; ++ ++&vopb { ++ status = "okay"; ++}; ++ ++&vopb_mmu { ++ status = "okay"; ++}; ++ ++&vopl { ++ status = "okay"; ++}; ++ ++&vopl_mmu { ++ status = "okay"; ++}; +\ No newline at end of file +-- +Created with Armbian build tools https://github.com/armbian/build + diff --git a/patch/u-boot/u-boot-rockchip64-mainline/add-board-helios64.patch b/patch/u-boot/u-boot-rockchip64-mainline/add-board-helios64.patch new file mode 100644 index 0000000000..70d1cd567a --- /dev/null +++ b/patch/u-boot/u-boot-rockchip64-mainline/add-board-helios64.patch @@ -0,0 +1,2171 @@ +From dde2516d9f7146a799c64750387727d478dee743 Mon Sep 17 00:00:00 2001 +From: Aditya Prayoga +Date: Mon, 3 Aug 2020 17:23:58 +0700 +Subject: [PATCH] Patching something + +Signed-off-by: Aditya Prayoga +--- + arch/arm/dts/Makefile | 1 + + arch/arm/dts/rk3399-helios64-u-boot.dtsi | 130 +++ + arch/arm/dts/rk3399-helios64.dts | 1149 ++++++++++++++++++++++ + arch/arm/mach-rockchip/rk3399/Kconfig | 17 + + board/kobol/helios64/Kconfig | 24 + + board/kobol/helios64/MAINTAINERS | 6 + + board/kobol/helios64/Makefile | 5 + + board/kobol/helios64/helios64.c | 262 +++++ + board/kobol/helios64/sys_otp.c | 248 +++++ + board/kobol/helios64/sys_otp.h | 10 + + configs/helios64_defconfig | 149 +++ + include/configs/helios64.h | 47 + + 12 files changed, 2048 insertions(+) + create mode 100644 arch/arm/dts/rk3399-helios64-u-boot.dtsi + create mode 100644 arch/arm/dts/rk3399-helios64.dts + create mode 100644 board/kobol/helios64/Kconfig + create mode 100644 board/kobol/helios64/MAINTAINERS + create mode 100644 board/kobol/helios64/Makefile + create mode 100644 board/kobol/helios64/helios64.c + create mode 100644 board/kobol/helios64/sys_otp.c + create mode 100644 board/kobol/helios64/sys_otp.h + create mode 100644 configs/helios64_defconfig + create mode 100644 include/configs/helios64.h + +diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile +index 530d60bfc..d9fd6cf1c 100644 +--- a/arch/arm/dts/Makefile ++++ b/arch/arm/dts/Makefile +@@ -122,6 +122,7 @@ dtb-$(CONFIG_ROCKCHIP_RK3399) += \ + rk3399-ficus.dtb \ + rk3399-firefly.dtb \ + rk3399-gru-bob.dtb \ ++ rk3399-helios64.dtb \ + rk3399-khadas-edge.dtb \ + rk3399-khadas-edge-captain.dtb \ + rk3399-khadas-edge-v.dtb \ +diff --git a/arch/arm/dts/rk3399-helios64-u-boot.dtsi b/arch/arm/dts/rk3399-helios64-u-boot.dtsi +new file mode 100644 +index 000000000..27ea5eaa9 +--- /dev/null ++++ b/arch/arm/dts/rk3399-helios64-u-boot.dtsi +@@ -0,0 +1,130 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (c) 2020 Aditya Prayoga (aditya@kobol.io) ++ */ ++ ++#include "rk3399-u-boot.dtsi" ++#include "rk3399-sdram-lpddr4-100.dtsi" ++/ { ++ aliases { ++ spi0 = &spi1; ++ spi1 = &spi2; ++ spi2 = &spi5; ++ ethernet0 = &gmac; ++ ethernet1 = &usb_lan; ++ }; ++ ++ chosen { ++ bootargs = "earlycon=uart8250,mmio32,0xff1a0000 earlyprintk"; ++ stdout-path = "serial2:1500000n8"; ++ u-boot,spl-boot-order = "same-as-spl", &spiflash, &sdmmc, &sdhci; ++ }; ++ ++ config { ++ u-boot,spl-payload-offset = <0x80000>; /* @ 512KB */ ++ }; ++}; ++ ++&gpio1 { ++ usb-mux-hs { ++ gpio-hog; ++ gpios = ; ++ output-low; ++ line-name = "USB_MUX_HS"; ++ }; ++ ++ usb-mux-oe { ++ gpio-hog; ++ gpios = ; ++ output-high; ++ line-name = "USB_MUX_OE#"; ++ }; ++ ++ soc-flash-wp { ++ gpio-hog; ++ gpios = ; ++ output-low; ++ line-name = "SOC_WP#"; ++ }; ++}; ++ ++&gpio2 { ++ sata-flash-wp { ++ gpio-hog; ++ gpios = ; ++ output-high; ++ line-name = "SATA_WP#_LV"; ++ }; ++}; ++ ++&gpio4 { ++ auto-on-en-d { ++ gpio-hog; ++ gpios = ; ++ output-low; ++ line-name = "AUTO_ON_EN_D"; ++ }; ++ ++ auto-on-en-clk { ++ gpio-hog; ++ gpios = ; ++ output-low; ++ line-name = "AUTO_ON_EN_CLK"; ++ }; ++ ++ board-rev-id-0 { ++ gpio-hog; ++ gpios = ; ++ input; ++ }; ++ ++ board-rev-id-1 { ++ gpio-hog; ++ gpios = ; ++ input; ++ }; ++}; ++ ++&int_hub { ++ compatible = "usb-hub"; ++ usb,device-class = ; ++}; ++ ++&pcie_prst { ++ rockchip,pins = ++ <2 RK_PD4 RK_FUNC_GPIO &pcfg_output_low>; ++}; ++ ++&pcie_pwr_en { ++ rockchip,pins = ++ <1 RK_PD0 RK_FUNC_GPIO &pcfg_output_low>; ++}; ++ ++&pinctrl { ++ usb { ++ usb_mux_hs: usb-mux-hs { ++ rockchip,pins = ++ <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ usb_mux_oe: usb-mux-oe { ++ rockchip,pins = ++ <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&spi1 { ++ spiflash: flash@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0x0>; ++ spi-max-frequency = <25000000>; ++ status = "okay"; ++ m25p,fast-read; ++ u-boot,dm-pre-reloc; ++ }; ++}; ++ ++&vdd_log { ++ regulator-init-microvolt = <950000>; ++}; +diff --git a/arch/arm/dts/rk3399-helios64.dts b/arch/arm/dts/rk3399-helios64.dts +new file mode 100644 +index 000000000..d5f1df674 +--- /dev/null ++++ b/arch/arm/dts/rk3399-helios64.dts +@@ -0,0 +1,1149 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2020 Aditya Prayoga (aditya@kobol.io) ++ */ ++ ++/dts-v1/; ++#include ++#include ++#include ++#include ++#include "rk3399.dtsi" ++#include "rk3399-opp.dtsi" ++ ++/ { ++ model = "Helios64"; ++ compatible = "kobol,helios64", "rockchip,rk3399"; ++ ++ adc-keys { ++ compatible = "adc-keys"; ++ io-channels = <&saradc 1>; ++ io-channel-names = "buttons"; ++ keyup-threshold-microvolt = <1800000>; ++ poll-interval = <100>; ++ ++ user2-button { ++ label = "User Button 2"; ++ linux,code = ; ++ press-threshold-microvolt = <100000>; ++ }; ++ }; ++ ++ beeper: beeper { ++ compatible = "gpio-beeper"; ++ gpios = <&gpio4 RK_PD3 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ clkin_gmac: external-gmac-clock { ++ compatible = "fixed-clock"; ++ clock-frequency = <125000000>; ++ clock-output-names = "clkin_gmac"; ++ #clock-cells = <0>; ++ }; ++ ++ vcc12v_dcin: vcc12v-dcin { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc12v_dcin"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ }; ++ ++ vcc12v_dcin_bkup: vcc12v-dcin-bkup { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc12v_dcin_bkup"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ vin-supply = <&vcc12v_dcin>; ++ }; ++ ++ vcc12v_hdd: vcc12v-hdd { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc12v_hdd"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; ++ vin-supply = <&vcc12v_dcin_bkup>; ++ }; ++ ++ /* switched by pmic_sleep */ ++ vcc1v8_sys_s0: vcc1v8-sys-s0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc1v8_sys_s0"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ vin-supply = <&vcc1v8_sys_s3>; ++ }; ++ ++ vcc0v9_s3: vcc0v9-s3 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc0v9_s3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ vin-supply = <&vcc3v3_sys_s3>; ++ }; ++ ++ avdd_0v9_s0: avdd-0v9-s0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "avdd_0v9_s0"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ vin-supply = <&vcc1v8_sys_s3>; ++ }; ++ ++ avdd_1v8_s0: avdd-1v8-s0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "avdd_1v8_s0"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ vin-supply = <&vcc3v3_sys_s3>; ++ }; ++ ++ pcie_power: pcie-power { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio1 RK_PD0 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie_pwr_en>; ++ regulator-name = "pcie_power"; ++ regulator-boot-on; ++ vin-supply = <&vcc5v0_perdev>; ++ }; ++ ++ vcc3v3_sys_s3: vcc_lan: vcc3v3-sys-s3 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v3_sys_s3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ vcc3v0_sd: vcc3v0-sd { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ regulator-name = "vcc3v0_sd"; ++ gpio = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0_pwr_h>; ++ regulator-boot-on; ++ startup-delay-us = <20000>; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ vin-supply = <&vcc3v3_sys_s3>; ++ }; ++ ++ vcc5v0_usb: vcc5v0-usb { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio1 RK_PC6 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vcc5v0_usb_en>; ++ regulator-name = "vcc5v0_usb"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc5v0_perdev>; ++ }; ++ ++ vcc5v0_typec: vcc5v0-typec-regulator { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio1 RK_PA3 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&fusb0_vbus_en>; ++ regulator-name = "vcc5v0_typec"; ++ vin-supply = <&vcc5v0_usb>; ++ }; ++ ++ vcc5v0_perdev: vcc5v0-perdev { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_perdev"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc12v_dcin_bkup>; ++ }; ++ ++ vcc5v0_hdd: vcc5v0-hdd { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_hdd"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc12v_dcin_bkup>; ++ }; ++ ++ vcc5v0_sys: vcc5v0-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ vin-supply = <&vcc12v_dcin_bkup>; ++ }; ++ ++ vdd_log: vdd-log { ++ compatible = "pwm-regulator"; ++ pwms = <&pwm2 0 25000 1>; ++ regulator-name = "vdd_log"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <1400000>; ++ vin-supply = <&vcc5v0_sys>; ++ }; ++ ++ power_hdd_a: power-hdd-a { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hdd_a_power>; ++ regulator-name = "power_hdd_a"; ++ regulator-always-on; ++ regulator-boot-on; ++ startup-delay-us = <2500000>; ++ }; ++ ++ power_hdd_b: power-hdd-b { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio1 RK_PA1 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hdd_b_power>; ++ regulator-name = "power_hdd_b"; ++ regulator-always-on; ++ regulator-boot-on; ++ startup-delay-us = <2500000>; ++ }; ++ ++ usblan_power: usblan-power { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpio = <&gpio1 RK_PC7 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usb_lan_en>; ++ regulator-name = "usblan_power"; ++ regulator-always-on; ++ regulator-boot-on; ++ vin-supply = <&vcc5v0_usb>; ++ }; ++ ++ fan1: p7-fan { ++ compatible = "pwm-fan"; ++ pwms = <&pwm0 0 40000 0>; ++ cooling-min-state = <0>; ++ cooling-max-state = <3>; ++ #cooling-cells = <2>; ++ cooling-levels = <0 80 170 255>; ++ }; ++ ++ fan2: p6-fan { ++ compatible = "pwm-fan"; ++ pwms = <&pwm1 0 40000 0>; ++ cooling-min-state = <0>; ++ cooling-max-state = <3>; ++ #cooling-cells = <2>; ++ cooling-levels = <0 80 170 255>; ++ }; ++ ++ gpio-charger { ++ compatible = "gpio-charger"; ++ charger-type = "mains"; ++ gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; ++ charge-status-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ac_present_ap>, <&charger_status>; ++ }; ++ ++ gpio-keys { ++ compatible = "gpio-keys"; ++ autorepeat; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwrbtn>, <&user1btn>, <&wake_on_lan>; ++ ++ power { ++ debounce-interval = <100>; ++ gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>; ++ label = "Power"; ++ linux,code = ; ++ wakeup-source; ++ }; ++ ++ user1-button { ++ debounce-interval = <100>; ++ gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_LOW>; ++ label = "User Button 1"; ++ linux,code = ; ++ }; ++ }; ++ ++ hdmi_dp_sound: hdmi-dp-sound { ++ status = "okay"; ++ compatible = "rockchip,rk3399-hdmi-dp"; ++ rockchip,cpu = <&i2s2>; ++ rockchip,codec = <&cdn_dp>; ++ }; ++ ++ io_leds: io-gpio-leds { ++ status = "okay"; ++ compatible = "gpio-leds"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&network_act>, <&usb3_act>, ++ <&sata_act>, <&sata_err_led>; ++ ++ network { ++ label = "helios64:blue:net"; ++ gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "netdev"; ++ default-state = "off"; ++ }; ++ ++ sata { ++ label = "helios64:blue:hdd-status"; ++ gpios = <&gpio4 RK_PD4 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "disk-activity"; ++ default-state = "off"; ++ }; ++ ++ sata_err1 { ++ label = "helios64:red:ata1-err"; ++ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_HIGH>; ++ default-state = "keep"; ++ }; ++ ++ sata_err2 { ++ label = "helios64:red:ata2-err"; ++ gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_HIGH>; ++ default-state = "keep"; ++ }; ++ ++ sata_err3 { ++ label = "helios64:red:ata3-err"; ++ gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_HIGH>; ++ default-state = "keep"; ++ }; ++ ++ sata_err4 { ++ label = "helios64:red:ata4-err"; ++ gpios = <&gpio2 RK_PA5 GPIO_ACTIVE_HIGH>; ++ default-state = "keep"; ++ }; ++ ++ sata_err5 { ++ label = "helios64:red:ata5-err"; ++ gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_HIGH>; ++ default-state = "keep"; ++ }; ++ ++ usb3 { ++ label = "helios64:blue:usb3"; ++ gpios = <&gpio0 RK_PB3 GPIO_ACTIVE_HIGH>; ++ trigger-sources = <&int_hub_port1>, ++ <&int_hub_port2>, ++ <&int_hub_port3>; ++ linux,default-trigger = "usbport"; ++ default-state = "off"; ++ }; ++ }; ++ ++ pwmleds { ++ compatible = "pwm-leds"; ++ status = "okay"; ++ ++ power-led { ++ label = "helios64:blue:power-status"; ++ pwms = <&pwm3 0 2000000000 0>; ++ max-brightness = <255>; ++ }; ++ }; ++ ++ system_leds: system-gpio-leds { ++ status = "okay"; ++ compatible = "gpio-leds"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&system_led>; ++ ++ status-led { ++ label = "helios64::status"; ++ gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "none"; ++ default-state = "on"; ++ mode = <0x23>; ++ }; ++ ++ fault-led { ++ label = "helios64:red:fault"; ++ gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "none"; ++ default-state = "keep"; ++ mode = <0x23>; ++ }; ++ }; ++}; ++ ++&cdn_dp { ++ status = "okay"; ++ extcon = <&fusb0>; ++ phys = <&tcphy0_dp>; ++}; ++ ++&cpu_l0 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_l1 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_l2 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_l3 { ++ cpu-supply = <&vdd_cpu_l>; ++}; ++ ++&cpu_b0 { ++ cpu-supply = <&vdd_cpu_b>; ++}; ++ ++&cpu_b1 { ++ cpu-supply = <&vdd_cpu_b>; ++}; ++ ++&cpu_alert0 { ++ temperature = <80000>; ++}; ++ ++&cpu_alert1 { ++ temperature = <95000>; ++}; ++ ++&cpu_crit { ++ temperature = <100000>; ++}; ++ ++&emmc_phy { ++ status = "okay"; ++}; ++ ++&gmac { ++ assigned-clocks = <&cru SCLK_RMII_SRC>; ++ assigned-clock-parents = <&clkin_gmac>; ++ clock_in_out = "input"; ++ phy-supply = <&vcc_lan>; ++ phy-mode = "rgmii"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rgmii_pins &rgmii_phy_reset>; ++ snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; ++ snps,reset-active-low; ++ snps,reset-delays-us = <0 10000 50000>; ++ tx_delay = <0x28>; ++ rx_delay = <0x20>; ++ status = "okay"; ++}; ++ ++&gpu { ++ mali-supply = <&vdd_gpu>; ++ status = "okay"; ++}; ++ ++&i2c0 { ++ clock-frequency = <400000>; ++ i2c-scl-rising-time-ns = <168>; ++ i2c-scl-falling-time-ns = <4>; ++ status = "okay"; ++ ++ rk808: pmic@1b { ++ compatible = "rockchip,rk808"; ++ reg = <0x1b>; ++ #clock-cells = <1>; ++ clock-output-names = "xin32k", "rk808-clkout2"; ++ interrupt-parent = <&gpio0>; ++ interrupts = <10 IRQ_TYPE_LEVEL_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int_l>; ++ rockchip,system-power-controller; ++ wakeup-source; ++ ++ vcc1-supply = <&vcc5v0_sys>; ++ vcc2-supply = <&vcc5v0_sys>; ++ vcc3-supply = <&vcc5v0_sys>; ++ vcc4-supply = <&vcc5v0_sys>; ++ vcc6-supply = <&vcc5v0_sys>; ++ vcc7-supply = <&vcc5v0_sys>; ++ vcc8-supply = <&vcc3v3_sys_s3>; ++ vcc9-supply = <&vcc5v0_sys>; ++ vcc10-supply = <&vcc5v0_sys>; ++ vcc11-supply = <&vcc5v0_sys>; ++ vcc12-supply = <&vcc3v3_sys_s3>; ++ vddio-supply = <&vcc3v0_s3>; ++ ++ regulators { ++ vdd_center: DCDC_REG1 { ++ regulator-name = "vdd_center"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_cpu_l: DCDC_REG2 { ++ regulator-name = "vdd_cpu_l"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_ddr_s3: DCDC_REG3 { ++ regulator-name = "vcc_ddr_s3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc1v8_sys_s3: DCDC_REG4 { ++ regulator-name = "vcc1v8_sys_s3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ /* not used */ ++ vcc1v8_dvp: LDO_REG1 { ++ regulator-name = "vcc1v8_dvp"; ++ }; ++ ++ /* not used */ ++ vcc3v0_touch: LDO_REG2 { ++ regulator-name = "vcc3v0_touch"; ++ }; ++ ++ vcc1v8_s3: LDO_REG3 { ++ regulator-name = "vcc1v8_s3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc_sdio_s0: LDO_REG4 { ++ regulator-name = "vcc_sdio_s0"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-state-mem { ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ /* not used */ ++ vcca3v0_codec: LDO_REG5 { ++ regulator-name = "vcca3v0_codec"; ++ }; ++ ++ vcc1v5_s3: LDO_REG6 { ++ regulator-name = "vcc1v5_s3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1500000>; ++ regulator-max-microvolt = <1500000>; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1500000>; ++ }; ++ }; ++ ++ /* not used */ ++ vcca1v8_codec: LDO_REG7 { ++ regulator-name = "vcca1v8_codec"; ++ }; ++ ++ vcc3v0_s3: LDO_REG8 { ++ regulator-name = "vcc3v0_s3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3000000>; ++ }; ++ }; ++ ++ vcc3v3_sys_s0: SWITCH_REG1 { ++ regulator-name = "vcc3v3_sys_s0"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc3v3_s0: SWITCH_REG2 { ++ regulator-name = "vcc3v3_s0"; ++ }; ++ }; ++ }; ++ ++ vdd_cpu_b: regulator@40 { ++ compatible = "silergy,syr827"; ++ reg = <0x40>; ++ fcs,suspend-voltage-selector = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vsel1_gpio>; ++ vsel-gpios = <&gpio1 RK_PC1 GPIO_ACTIVE_HIGH>; ++ regulator-compatible = "fan53555-reg"; ++ regulator-name = "vdd_cpu_b"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1500000>; ++ regulator-ramp-delay = <1000>; ++ regulator-always-on; ++ regulator-boot-on; ++ vin-supply = <&vcc5v0_sys>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vdd_gpu: regulator@41 { ++ compatible = "silergy,syr828"; ++ reg = <0x41>; ++ fcs,suspend-voltage-selector = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vsel2_gpio>; ++ vsel-gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_HIGH>; ++ regulator-compatible = "fan53555-reg"; ++ regulator-name = "vdd_gpu"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1500000>; ++ regulator-ramp-delay = <1000>; ++ regulator-always-on; ++ regulator-boot-on; ++ vin-supply = <&vcc5v0_sys>; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++}; ++ ++&i2c2 { ++ clock-frequency = <400000>; ++ i2c-scl-rising-time-ns = <160>; ++ i2c-scl-falling-time-ns = <30>; ++ status = "okay"; ++ ++ gpio-expander@20 { ++ compatible = "nxp,pca9555"; ++ reg = <0x20>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pca0_pins>; ++ interrupt-parent = <&gpio0>; ++ interrupts = <9 IRQ_TYPE_EDGE_FALLING>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ vcc-supply = <&vcc3v3_sys_s3>; ++ }; ++ ++ temp@4c { ++ compatible = "onnn,lm75"; ++ reg = <0x4c>; ++ vcc-supply = <&vcc3v3_sys_s0>; ++ }; ++}; ++ ++&i2c4 { ++ clock-frequency = <400000>; ++ i2c-scl-rising-time-ns = <160>; ++ i2c-scl-falling-time-ns = <30>; ++ status = "okay"; ++ ++ fusb0: typec-portc@22 { ++ /* For use with typec-fusb302 */ ++ compatible = "fcs,fusb302"; ++ reg = <0x22>; ++ interrupt-parent = <&gpio1>; ++ interrupts = ; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&fusb0_int>; ++ vbus-supply = <&vcc5v0_typec>; ++ status = "okay"; ++ ++ usb_con: connector { ++ compatible = "usb-c-connector"; ++ label = "USB-C"; ++ power-role = "dual"; ++ data-role = "dual"; ++ try-power-role = "sink"; ++ source-pdos = ; ++ sink-pdos = ; ++ op-sink-microwatt = <5000000>; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg = <0>; ++ usb_con_hs: endpoint { ++ remote-endpoint = <&u2phy0_typec_hs>; ++ }; ++ }; ++ port@1 { ++ reg = <1>; ++ usb_con_ss: endpoint { ++ remote-endpoint = <&tcphy0_typec_ss>; ++ }; ++ }; ++ port@2 { ++ reg = <2>; ++ usb_con_sbu: endpoint { ++ remote-endpoint = <&tcphy0_typec_dp>; ++ }; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++/* I2C on UEXT */ ++&i2c7 { ++ status = "okay"; ++}; ++ ++/* External I2C */ ++&i2c8 { ++ status = "okay"; ++}; ++ ++&i2s2 { ++ #sound-dai-cells = <0>; ++ status = "okay"; ++}; ++ ++&io_domains { ++ status = "okay"; ++ bt656-supply = <&vcc1v8_sys_s0>; ++ audio-supply = <&vcc1v8_sys_s0>; ++ sdmmc-supply = <&vcc_sdio_s0>; ++ gpio1830-supply = <&vcc3v0_s3>; ++}; ++ ++&pcie0 { ++ ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>; ++ num-lanes = <2>; ++ max-link-speed = <2>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie_prst &pcie_clkreqn_cpm>; ++ vpcie12v-supply = <&vcc12v_dcin>; ++ vpcie3v3-supply = <&pcie_power>; ++ vpcie1v8-supply = <&avdd_1v8_s0>; ++ vpcie0v9-supply = <&avdd_0v9_s0>; ++ status = "okay"; ++}; ++ ++&pcie_phy { ++ status = "okay"; ++}; ++ ++&pinctrl { ++ buttons { ++ pwrbtn: pwrbtn { ++ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ ++ user1btn: usr1btn { ++ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ charger { ++ ac_present_ap: ac-present-ap { ++ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ charger_status: charger-status { ++ rockchip,pins = <2 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ fan { ++ fan1_sense: fan1-sense { ++ rockchip,pins = <4 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ fan2_sense: fan2-sense { ++ rockchip,pins = <4 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ fusb30x { ++ fusb0_int: fusb0-int { ++ rockchip,pins = ++ <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ ++ fusb0_vbus_en: fusb0-vbus-en { ++ rockchip,pins = ++ <1 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ gmac { ++ rgmii_phy_reset: rgmii-phy-reset { ++ rockchip,pins = ++ <3 RK_PB7 RK_FUNC_GPIO &pcfg_output_low>; ++ }; ++ }; ++ ++ leds { ++ network_act: network-act { ++ rockchip,pins = ++ <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ ++ usb3_act: usb3-act { ++ rockchip,pins = ++ <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ ++ sata_act: sata-act { ++ rockchip,pins = ++ <4 RK_PD4 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ ++ system_led: sys-led { ++ rockchip,pins = ++ <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_down>, ++ <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ ++ sata_err_led: sata-err-led { ++ rockchip,pins = ++ <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_down>, ++ <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_down>, ++ <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_down>, ++ <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_down>, ++ <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ }; ++ ++ misc { ++ pca0_pins: pca0-pins { ++ rockchip,pins = ++ <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ wake_on_lan: wake-on-lan { ++ rockchip,pins = ++ <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pcie { ++ pcie_prst: pcie-prst { ++ rockchip,pins = ++ <2 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ pcie_pwr_en: pcie-pwr-en { ++ rockchip,pins = ++ <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = ++ <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ vsel1_gpio: vsel1-gpio { ++ rockchip,pins = ++ <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ ++ vsel2_gpio: vsel2-gpio { ++ rockchip,pins = ++ <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ }; ++ ++ power { ++ hdd_a_power: hdd-a-power { ++ rockchip,pins = ++ <1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ hdd_b_power: hdd-b-power { ++ rockchip,pins = ++ <1 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ vcc5v0_usb_en: vcc5v0-usb-en { ++ rockchip,pins = ++ <1 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ sdmmc0_pwr_h: sdmmc0-pwr-h { ++ rockchip,pins = ++ ; ++ }; ++ ++ usb_lan_en: usb-lan-en { ++ rockchip,pins = ++ <1 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&pmu_io_domains { ++ pmu1830-supply = <&vcc3v0_s3>; ++ status = "okay"; ++}; ++ ++&pwm0 { ++ status = "okay"; ++}; ++ ++&pwm1 { ++ status = "okay"; ++}; ++ ++&pwm2 { ++ status = "okay"; ++}; ++ ++&pwm3 { ++ status = "okay"; ++}; ++ ++&saradc { ++ vref-supply = <&vcc1v8_s3>; ++ status = "okay"; ++}; ++ ++&sdhci { ++ bus-width = <8>; ++ mmc-hs400-1_8v; ++ mmc-hs200-1_8v; ++ mmc-hs400-enhanced-strobe; ++ supports-emmc; ++ non-removable; ++ status = "okay"; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ disable-wp; ++ sd-uhs-sdr104; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; ++ vmmc-supply = <&vcc3v0_sd>; ++ vqmmc-supply = <&vcc_sdio_s0>; ++ status = "okay"; ++}; ++ ++&spi1 { ++ status = "okay"; ++}; ++ ++/* UEXT connector */ ++&spi2 { ++ status = "okay"; ++}; ++ ++&spi5 { ++ status = "okay"; ++}; ++ ++&tcphy0 { ++ extcon = <&fusb0>; ++ status = "okay"; ++}; ++ ++&tcphy0_dp { ++ port { ++ tcphy0_typec_dp: endpoint { ++ remote-endpoint = <&usb_con_sbu>; ++ }; ++ }; ++}; ++ ++&tcphy0_usb3 { ++ port { ++ tcphy0_typec_ss: endpoint { ++ remote-endpoint = <&usb_con_ss>; ++ }; ++ }; ++}; ++ ++&tcphy1 { ++ status = "okay"; ++}; ++ ++&tsadc { ++ /* tshut mode 0:CRU 1:GPIO */ ++ rockchip,hw-tshut-mode = <1>; ++ /* tshut polarity 0:LOW 1:HIGH */ ++ rockchip,hw-tshut-polarity = <1>; ++ status = "okay"; ++}; ++ ++&u2phy0 { ++ status = "okay"; ++ extcon = <&fusb0>; ++ ++ u2phy0_otg: otg-port { ++ status = "okay"; ++ ++ port { ++ u2phy0_typec_hs: endpoint { ++ remote-endpoint = <&usb_con_hs>; ++ }; ++ }; ++ }; ++ ++ u2phy0_host: host-port { ++ phy-supply = <&vcc5v0_usb>; ++ status = "okay"; ++ }; ++}; ++ ++&u2phy1 { ++ status = "okay"; ++ ++ u2phy1_otg: otg-port { ++ status = "okay"; ++ }; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usbdrd3_0 { ++ extcon = <&fusb0>; ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3_0 { ++ status = "okay"; ++ dr_mode = "otg"; ++}; ++ ++&usbdrd3_1 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3_1 { ++ status = "okay"; ++ dr_mode = "host"; ++ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ int_hub: hub@1 { ++ compatible = "usb2109,0815"; ++ reg = <1>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ int_hub_port1: port@1 { ++ reg = <1>; ++ #trigger-source-cells = <0>; ++ }; ++ ++ int_hub_port2: port@2 { ++ reg = <2>; ++ #trigger-source-cells = <0>; ++ }; ++ ++ int_hub_port3: port@3 { ++ reg = <3>; ++ #trigger-source-cells = <0>; ++ }; ++ ++ usb_lan: device@4 { ++ compatible = "usbbda,8156"; ++ reg = <4>; ++ ++ #address-cells = <2>; ++ #size-cells = <0>; ++ ++ interface@0 { /* interface 0 of configuration 1 */ ++ compatible = "usbbda,8156.config1.0"; ++ reg = <0 1>; ++ }; ++ }; ++ }; ++}; ++ ++&vopb { ++ status = "okay"; ++}; ++ ++&vopb_mmu { ++ status = "okay"; ++}; ++ ++&vopl { ++ status = "okay"; ++}; ++ ++&vopl_mmu { ++ status = "okay"; ++}; +diff --git a/arch/arm/mach-rockchip/rk3399/Kconfig b/arch/arm/mach-rockchip/rk3399/Kconfig +index 254b9c5b4..5f89bf6eb 100644 +--- a/arch/arm/mach-rockchip/rk3399/Kconfig ++++ b/arch/arm/mach-rockchip/rk3399/Kconfig +@@ -26,6 +26,22 @@ config TARGET_PINEBOOK_PRO_RK3399 + with 4Gb RAM, onboard eMMC, USB-C, a USB3 and USB2 port, + 1920*1080 screen and all the usual laptop features. + ++config TARGET_HELIOS64 ++ bool "Kobol Innovations Helios64" ++ select BOARD_LATE_INIT ++ help ++ Helios64 is a Network Attached Storage board based on Rockchip RK3399. ++ ++ Key features of the Helios64 include: ++ * on-board PCIe to 5 Ports SATA Controller JMB585 ++ * on-board USB 3.0 hub (3x USB 3.0 host) ++ * USB Type-C (Support DisplayPort Alt Mode) ++ * on-board 1 Gigabit Ethernet ++ * on-board 2.5 Gigabit Ethernet (Realtek RTL8156) ++ * on-board eMMC ++ * on-board LPDDR4 ++ * SPI, I2C, UART, GPIO ++ + config TARGET_PUMA_RK3399 + bool "Theobroma Systems RK3399-Q7 (Puma)" + help +@@ -151,6 +167,7 @@ endif # BOOTCOUNT_LIMIT + + source "board/firefly/roc-pc-rk3399/Kconfig" + source "board/google/gru/Kconfig" ++source "board/kobol/helios64/Kconfig" + source "board/pine64/pinebook-pro-rk3399/Kconfig" + source "board/pine64/rockpro64_rk3399/Kconfig" + source "board/rockchip/evb_rk3399/Kconfig" +diff --git a/board/kobol/helios64/Kconfig b/board/kobol/helios64/Kconfig +new file mode 100644 +index 000000000..644cdbd8f +--- /dev/null ++++ b/board/kobol/helios64/Kconfig +@@ -0,0 +1,24 @@ ++if TARGET_HELIOS64 ++ ++config SYS_BOARD ++ default "helios64" ++ ++config SYS_VENDOR ++ default "kobol" ++ ++config SYS_CONFIG_NAME ++ default "helios64" ++ ++config BOARD_SPECIFIC_OPTIONS # dummy ++ def_bool y ++ ++config ENV_SECT_SIZE ++ default 0x1000 if ENV_IS_IN_SPI_FLASH ++ ++config ENV_SIZE ++ default 0x8000 ++ ++config ENV_OFFSET ++ default 0x460000 if ENV_IS_IN_SPI_FLASH ++ ++endif +diff --git a/board/kobol/helios64/MAINTAINERS b/board/kobol/helios64/MAINTAINERS +new file mode 100644 +index 000000000..a9c88c79e +--- /dev/null ++++ b/board/kobol/helios64/MAINTAINERS +@@ -0,0 +1,6 @@ ++HELIOS64 BOARD ++M: Aditya Prayoga ++S: Maintained ++F: board/kobol/helios64/ ++F: include/configs/helios64.h ++F: configs/helios64_defconfig +diff --git a/board/kobol/helios64/Makefile b/board/kobol/helios64/Makefile +new file mode 100644 +index 000000000..ab34245a6 +--- /dev/null ++++ b/board/kobol/helios64/Makefile +@@ -0,0 +1,5 @@ ++# SPDX-License-Identifier: GPL-2.0+ ++# ++# Copyright (C) 2020 Aditya Prayoga ++ ++obj-y := helios64.o sys_otp.o +diff --git a/board/kobol/helios64/helios64.c b/board/kobol/helios64/helios64.c +new file mode 100644 +index 000000000..c7a0efa49 +--- /dev/null ++++ b/board/kobol/helios64/helios64.c +@@ -0,0 +1,262 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * (C) Copyright 2020 Aditya Prayoga (aditya@kobol.io) ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "sys_otp.h" ++ ++#ifndef CONFIG_TPL_BUILD ++int board_early_init_f(void) ++{ ++#ifdef CONFIG_SPL_BUILD ++#define GPIO0_BASE 0xff720000 ++#define GRF_BASE 0xff770000 ++ struct rk3399_grf_regs * const grf = (void *)GRF_BASE; ++ struct rockchip_gpio_regs * const gpio = (void *)GPIO0_BASE; ++ ++ /* Turn ON status LED. At this stage, FDT & DM is not initialized yet */ ++ spl_gpio_output(gpio, GPIO(BANK_B, 4), 1); ++#endif ++ return 0; ++} ++#endif ++ ++#ifndef CONFIG_SPL_BUILD ++int board_early_init_r(void) ++{ ++ read_otp_data(); ++ return 0; ++} ++#endif ++ ++#ifdef CONFIG_MISC_INIT_R ++#define GRF_IO_VSEL_BT565_SHIFT 0 ++#define GRF_IO_VSEL_AUDIO_SHIFT 1 ++#define GRF_IO_VSEL_SDMMC_SHIFT 2 ++#define GRF_IO_VSEL_GPIO1830_SHIFT 3 ++ ++#define PMUGRF_CON0_VSEL_SHIFT 8 ++#define PMUGRF_CON0_PMU1830_VOL_SHIFT 9 ++static void setup_iodomain(void) ++{ ++ struct rk3399_grf_regs *grf = ++ syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ struct rk3399_pmugrf_regs *pmugrf = ++ syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF); ++ ++ /* BT565 is in 1.8v domain */ ++ rk_setreg(&grf->io_vsel, 1 << GRF_IO_VSEL_BT565_SHIFT); ++ ++ /* AUDIO is in 1.8v domain */ ++ rk_setreg(&grf->io_vsel, 1 << GRF_IO_VSEL_AUDIO_SHIFT); ++ ++ /* SDMMC is in 3.0v domain */ ++ rk_setreg(&grf->io_vsel, 0 << GRF_IO_VSEL_SDMMC_SHIFT); ++ ++ /* GPIO1830 is in 3.0v domain */ ++ rk_setreg(&grf->io_vsel, 0 << GRF_IO_VSEL_GPIO1830_SHIFT); ++ ++ /* Set GPIO1 1.8v/3.0v source select to PMU1830_VOL */ ++ rk_setreg(&pmugrf->soc_con0, 1 << PMUGRF_CON0_VSEL_SHIFT); ++ rk_setreg(&pmugrf->soc_con0, 0 << PMUGRF_CON0_PMU1830_VOL_SHIFT); ++} ++ ++/* ++ * Swap mmc0 and mmc1 in boot_targets if booted from SD-Card. ++ * ++ * If bootsource is uSD-card we can assume that we want to use the ++ * SD-Card instead of the eMMC as first boot_target for distroboot. ++ * We only want to swap the defaults and not any custom environment a ++ * user has set. We exit early if a changed boot_targets environment ++ * is detected. ++ */ ++static int setup_boottargets(void) ++{ ++ const char *boot_device = ++ ofnode_read_chosen_string("u-boot,spl-boot-device"); ++ char *env_default, *env; ++ ++ if (!boot_device) { ++ debug("%s: /chosen/u-boot,spl-boot-device not set\n", ++ __func__); ++ return -1; ++ } ++ debug("%s: booted from %s\n", __func__, boot_device); ++ ++ env_default = env_get_default("boot_targets"); ++ env = env_get("boot_targets"); ++ if (!env) { ++ debug("%s: boot_targets does not exist\n", __func__); ++ return -1; ++ } ++ debug("%s: boot_targets current: %s - default: %s\n", ++ __func__, env, env_default); ++ ++ if (strcmp(env_default, env) != 0) { ++ debug("%s: boot_targets not default, don't change it\n", ++ __func__); ++ return 0; ++ } ++ ++ /* ++ * Only run, if booting from mmc1 (i.e. /mmc@fe320000) and ++ * only consider cases where the default boot-order first ++ * tries to boot from mmc0 (eMMC) and then from mmc1 ++ * (i.e. external SD). ++ * ++ * In other words: the SD card will be moved to earlier in the ++ * order, if U-Boot was also loaded from the SD-card. ++ */ ++ if (!strcmp(boot_device, "/mmc@fe320000")) { ++ char *mmc0, *mmc1; ++ ++ debug("%s: booted from SD-Card\n", __func__); ++ mmc0 = strstr(env, "mmc0"); ++ mmc1 = strstr(env, "mmc1"); ++ ++ if (!mmc0 || !mmc1) { ++ debug("%s: only one mmc boot_target found\n", __func__); ++ return -1; ++ } ++ ++ /* ++ * If mmc0 comes first in the boot order, we need to change ++ * the strings to make mmc1 first. ++ */ ++ if (mmc0 < mmc1) { ++ mmc0[3] = '1'; ++ mmc1[3] = '0'; ++ debug("%s: set boot_targets to: %s\n", __func__, env); ++ env_set("boot_targets", env); ++ } ++ } ++ ++ return 0; ++} ++ ++static void setup_leds(void) ++{ ++ struct udevice *dev; ++ ++ led_get_by_label("helios64::status", &dev); ++ led_set_state(dev, LEDST_OFF); ++ mdelay(250); ++ led_set_state(dev, LEDST_ON); ++} ++ ++int misc_init_r(void) ++{ ++ const u32 cpuid_offset = 0x7; ++ const u32 cpuid_length = 0x10; ++ u8 cpuid[cpuid_length]; ++ int ret; ++ ++ setup_iodomain(); ++ set_board_info(); ++ ++ ret = rockchip_cpuid_from_efuse(cpuid_offset, cpuid_length, cpuid); ++ if (ret) ++ return ret; ++ ++ ret = rockchip_cpuid_set(cpuid, cpuid_length); ++ if (ret) ++ return ret; ++ ++ if (mac_read_from_otp()) ++ ret = rockchip_setup_macaddr(); ++ ++ setup_boottargets(); ++ setup_leds(); ++ ++ return ret; ++} ++#endif ++ ++#ifdef CONFIG_LAST_STAGE_INIT ++static void auto_power_enable(void) ++{ ++ struct gpio_desc *enable, *clock; ++ ++ if (gpio_hog_lookup_name("AUTO_ON_EN_D", &enable)) { ++ debug("Fail to get AUTO_ON_EN_D\n"); ++ return; ++ } ++ ++ if (gpio_hog_lookup_name("AUTO_ON_EN_CLK", &clock)) { ++ debug("Fail to get AUTO_ON_EN_CLK\n"); ++ return; ++ } ++ ++ dm_gpio_set_value(enable, 1); ++ dm_gpio_set_value(clock, 1); ++ mdelay(10); ++ dm_gpio_set_value(clock, 0); ++} ++ ++int last_stage_init(void) ++{ ++ auto_power_enable(); ++ ++#ifdef CONFIG_PCI ++ scsi_scan(true); ++#endif ++ ++ return 0; ++} ++#endif ++ ++#if defined(CONFIG_DISPLAY_BOARDINFO_LATE) ++int checkboard(void) ++{ ++ int major, minor; ++ ++ printf("Revision: "); ++ ++ if (!get_revision(&major, &minor)) ++ printf("%i.%i - %s\n", major, minor, get_variant()); ++ else ++ printf("UNKNOWN\n"); ++ ++ return 0; ++} ++#endif ++ ++#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) ++int ft_board_setup(void *blob, bd_t *bd) ++{ ++ char *env; ++ ++ env = env_get("board_rev"); ++ if (env) ++ fdt_setprop_string(blob, fdt_path_offset(blob, "/"), ++ "kobol,board-rev", env); ++ ++ env = env_get("cpuid#"); ++ if (env) ++ fdt_setprop_string(blob, fdt_path_offset(blob, "/"), ++ "kobol,cpu-id", env); ++ ++ return 0; ++} ++#endif +diff --git a/board/kobol/helios64/sys_otp.c b/board/kobol/helios64/sys_otp.c +new file mode 100644 +index 000000000..3a2783464 +--- /dev/null ++++ b/board/kobol/helios64/sys_otp.c +@@ -0,0 +1,248 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "sys_otp.h" ++ ++#define OTP_DEVICE_BUS 0 ++#define OTP_DEVICE_CS 0 ++#define MAX_NUM_PORTS 2 ++ ++enum board_variant { ++ BOARD_VARIANT_INVALID = 0, ++ BOARD_VARIANT_ENG_SAMPLE, ++ BOARD_VARIANT_4G_PROD_NO_ECC, ++ BOARD_VARIANT_MAX ++}; ++ ++struct __attribute__ ((__packed__)) otp_data_t { ++ u8 magic[8]; ++ u8 part_num[16]; ++ u8 variant; ++ u8 revision; ++ u8 serial_num[6]; ++ u8 mfg_year[2]; ++ u8 mfg_month; ++ u8 mfg_day; ++ u8 mac_addr[MAX_NUM_PORTS][6]; ++ u8 reserved[204]; ++ u32 checksum; ++} otp; ++ ++static struct spi_slave *slave; ++static int has_been_read = 0; ++static int data_valid = 0; ++ ++static inline int is_data_valid(void) ++{ ++ return data_valid; ++} ++ ++static inline int is_valid_header(void) ++{ ++ if ((otp.magic[0] == 'H') || (otp.magic[1] == '6') || ++ (otp.magic[2] == '4') || (otp.magic[3] == 'N') || ++ (otp.magic[4] == 'P') || (otp.magic[5] == 'V') || ++ (otp.magic[6] == '1') || (otp.magic[7] == 0)) ++ ++ return 1; ++ ++ return 0; ++} ++ ++static int init_system_otp(int bus, int cs) ++{ ++ int ret; ++ char name[30], *str; ++ struct udevice *dev; ++ ++ snprintf(name, sizeof(name), "generic_%d:%d", bus, cs); ++ str = strdup(name); ++ if (!str) ++ return -ENOMEM; ++ ret = spi_get_bus_and_cs(bus, cs, 25000000, CONFIG_DEFAULT_SPI_MODE, "spi_generic_drv", ++ str, &dev, &slave); ++ return ret; ++} ++ ++#ifdef DEBUG ++/** ++ * show_otp_data - display the contents of the OTP register ++ */ ++static void show_otp_data(void) ++{ ++ u32 i; ++ u32 crc; ++ ++ const char* var_str[BOARD_VARIANT_MAX] = { ++ "Invalid variant", ++ "Engineering Sample", ++ "Production - 4GB non ECC" ++ }; ++ ++ printf("\n"); ++ printf("Register dump: (%lu bytes)\n", sizeof(otp)); ++ for (i = 0; i < sizeof(otp); i++) { ++ if ((i % 16) == 0) ++ printf("%02X: ", i); ++ printf("%02X ", ((u8 *)&otp)[i]); ++ if (((i % 16) == 15) || (i == sizeof(otp) - 1)) ++ printf("\n"); ++ } ++ ++ if (!is_valid_header()) ++ return; ++ ++ printf("Part Number: %s\n", otp.part_num); ++ printf("Variant: %s\n", var_str[otp.variant]); ++ printf("Revision: %x.%x\n", (otp.revision & 0xf0) >> 4, otp.revision & 0x0f); ++ printf("Serial Number: %012llx\n", *((uint64_t*) otp.serial_num) & ++ 0xFFFFFFFFFFFF); ++ printf("Manufacturing Date: %02X-%02X-%04X (DD-MM-YYYY)\n", otp.mfg_day, ++ otp.mfg_month, *(u16*) otp.mfg_year); ++ ++ printf("1GbE MAC Address: %02X:%02X:%02X:%02X:%02X:%02X\n", ++ otp.mac_addr[0][0], otp.mac_addr[0][1], otp.mac_addr[0][2], ++ otp.mac_addr[0][3], otp.mac_addr[0][4], otp.mac_addr[0][5]); ++ ++ printf("2.5GbE MAC Address: %02X:%02X:%02X:%02X:%02X:%02X\n", ++ otp.mac_addr[1][0], otp.mac_addr[1][1], otp.mac_addr[1][2], ++ otp.mac_addr[1][3], otp.mac_addr[1][4], otp.mac_addr[1][5]); ++ ++ crc = crc32(0, (void *)&otp, sizeof(otp) - 4); ++ ++ if (crc == le32_to_cpu(otp.checksum)) ++ printf("CRC: %08x\n\n", le32_to_cpu(otp.checksum)); ++ else ++ printf("CRC: %08x (should be %08x)\n\n", ++ le32_to_cpu(otp.checksum), crc); ++ ++} ++#endif ++ ++int read_otp_data(void) ++{ ++ int ret; ++ u8 dout[5]; ++ ++ if (has_been_read) { ++ if (is_data_valid()) ++ return 0; ++ else ++ goto data_invalid; ++ } ++ ++ ret = init_system_otp(OTP_DEVICE_BUS, OTP_DEVICE_CS); ++ if (ret) ++ return ret; ++ ++ ret = spi_claim_bus(slave); ++ if (ret) { ++ debug("SPI: Failed to claim SPI bus: %d\n", ret); ++ return ret; ++ } ++ ++ dout[0] = 0x48; ++ dout[1] = 0x00; ++ dout[2] = 0x10; /* Security Register #1 */ ++ dout[3] = 0x00; ++ dout[4] = 0x00; /* Dummy Byte */ ++ ++ ret = spi_write_then_read(slave, dout, sizeof(dout), NULL, (u8 *)&otp, ++ sizeof(otp)); ++ ++ spi_release_bus(slave); ++#ifdef DEBUG ++ show_otp_data(); ++#endif ++ ++ has_been_read = (ret == 0) ? 1 : 0; ++ if (!is_valid_header()) ++ goto data_invalid; ++ ++ if (crc32(0, (void *)&otp, sizeof(otp) - 4) == ++ le32_to_cpu(otp.checksum)) ++ data_valid = 1; ++ ++ if (!is_data_valid()) ++ goto data_invalid; ++ ++ return 0; ++ ++data_invalid: ++ printf("Invalid board ID data!\n"); ++ return -1; ++} ++ ++int get_revision(int *major, int *minor) ++{ ++ if (!is_data_valid()) ++ return -1; ++ ++ *major = (otp.revision & 0xf0) >> 4; ++ *minor = otp.revision & 0x0f; ++ ++ return 0; ++} ++ ++const char *get_variant(void) ++{ ++ const char* var_str[BOARD_VARIANT_MAX] = { ++ "Unknown", ++ "Engineering Sample", ++ "4GB non ECC" ++ }; ++ ++ if ((otp.variant < BOARD_VARIANT_ENG_SAMPLE) || ++ (otp.variant >= BOARD_VARIANT_MAX)) ++ return var_str[0]; ++ ++ return var_str[otp.variant]; ++} ++ ++void set_board_info(void) ++{ ++ char env_str[13]; ++ ++ if (!is_data_valid()) ++ return; ++ ++ snprintf(env_str, sizeof(env_str), "%i.%i", (otp.revision & 0xf0) >> 4, otp.revision & 0x0f); ++ env_set("board_rev", env_str); ++ ++ sprintf(env_str, "%012llx", *((uint64_t*) otp.serial_num) & ++ 0xFFFFFFFFFFFF); ++ ++ env_set("serial#", env_str); ++} ++ ++int mac_read_from_otp(void) ++{ ++ unsigned int i; ++ int ret; ++ ++ if (!is_data_valid()) ++ return -1; ++ ++ for (i = 0; i < MAX_NUM_PORTS; i++) { ++ char enetvar[9]; ++ ++ sprintf(enetvar, i ? "eth%daddr" : "ethaddr", i); ++ ++ if (!is_valid_ethaddr(otp.mac_addr[i])) { ++ debug("Not valid %s!\n", enetvar); ++ continue; ++ } ++ ++ /* Only initialize environment variables that are blank ++ * (i.e. have not yet been set) ++ */ ++ if (!env_get(enetvar)) ++ eth_env_set_enetaddr(enetvar, otp.mac_addr[i]); ++ } ++ ++ return ret; ++} +diff --git a/board/kobol/helios64/sys_otp.h b/board/kobol/helios64/sys_otp.h +new file mode 100644 +index 000000000..61f6f3b38 +--- /dev/null ++++ b/board/kobol/helios64/sys_otp.h +@@ -0,0 +1,10 @@ ++#ifndef __HELIOS64_SYS_OTP_H ++#define __HELIOS64_SYS_OTP_H ++ ++int read_otp_data(void); ++void set_board_info(void); ++int get_revision(int *major, int *minor); ++const char *get_variant(void); ++int mac_read_from_otp(void); ++ ++#endif +diff --git a/configs/helios64_defconfig b/configs/helios64_defconfig +new file mode 100644 +index 000000000..622100551 +--- /dev/null ++++ b/configs/helios64_defconfig +@@ -0,0 +1,149 @@ ++CONFIG_ARM=y ++CONFIG_ARCH_ROCKCHIP=y ++CONFIG_SYS_TEXT_BASE=0x00200000 ++CONFIG_SPL_GPIO_SUPPORT=y ++CONFIG_ENV_OFFSET=0x3F8000 ++CONFIG_ROCKCHIP_RK3399=y ++CONFIG_TARGET_HELIOS64=y ++CONFIG_NR_DRAM_BANKS=1 ++CONFIG_DEBUG_UART_BASE=0xFF1A0000 ++CONFIG_DEBUG_UART_CLOCK=24000000 ++CONFIG_SPL_SPI_FLASH_SUPPORT=y ++CONFIG_SPL_SPI_SUPPORT=y ++CONFIG_DEBUG_UART=y ++CONFIG_AHCI=y ++# CONFIG_ANDROID_BOOT_IMAGE is not set ++CONFIG_OF_BOARD_SETUP=y ++CONFIG_USE_PREBOOT=y ++CONFIG_CONSOLE_MUX=y ++CONFIG_SYS_CONSOLE_ENV_OVERWRITE=y ++CONFIG_DEFAULT_FDT_FILE="rockchip/rk3399-helios64.dtb" ++CONFIG_MISC_INIT_R=y ++CONFIG_VERSION_VARIABLE=y ++# CONFIG_DISPLAY_BOARDINFO is not set ++CONFIG_DISPLAY_BOARDINFO_LATE=y ++CONFIG_BOARD_TYPES=y ++CONFIG_BOARD_EARLY_INIT_F=y ++CONFIG_BOARD_EARLY_INIT_R=y ++CONFIG_LAST_STAGE_INIT=y ++# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set ++CONFIG_SPL_STACK_R=y ++CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x10000 ++CONFIG_SPL_I2C_SUPPORT=y ++CONFIG_SPL_POWER_SUPPORT=y ++CONFIG_SPL_SPI_LOAD=y ++CONFIG_TPL=y ++CONFIG_CMD_CONFIG=y ++CONFIG_CMD_BOOTZ=y ++# CONFIG_BOOTM_PLAN9 is not set ++# CONFIG_BOOTM_RTEMS is not set ++# CONFIG_BOOTM_VXWORKS is not set ++CONFIG_CMD_BOOTEFI_HELLO=y ++CONFIG_CMD_BOOTMENU=y ++CONFIG_CRC32_VERIFY=y ++CONFIG_CMD_MD5SUM=y ++CONFIG_MD5SUM_VERIFY=y ++CONFIG_CMD_MEMINFO=y ++CONFIG_CMD_MX_CYCLIC=y ++CONFIG_CMD_SHA1SUM=y ++CONFIG_SHA1SUM_VERIFY=y ++CONFIG_CMD_STRINGS=y ++CONFIG_CMD_ADC=y ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_GPT=y ++CONFIG_CMD_I2C=y ++CONFIG_CMD_MMC=y ++CONFIG_CMD_PCI=y ++CONFIG_CMD_POWEROFF=y ++CONFIG_CMD_READ=y ++CONFIG_CMD_SPI=y ++CONFIG_CMD_USB=y ++CONFIG_CMD_ROCKUSB=y ++CONFIG_CMD_USB_MASS_STORAGE=y ++CONFIG_CMD_EFIDEBUG=y ++CONFIG_CMD_EXCEPTION=y ++CONFIG_CMD_TIME=y ++CONFIG_CMD_PMIC=y ++CONFIG_CMD_REGULATOR=y ++CONFIG_CMD_FS_UUID=y ++CONFIG_PARTITION_TYPE_GUID=y ++CONFIG_SPL_OF_CONTROL=y ++CONFIG_OF_LIVE=y ++CONFIG_DEFAULT_DEVICE_TREE="rk3399-helios64" ++CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" ++CONFIG_ENV_IS_IN_MMC=y ++CONFIG_SYS_RELOC_GD_ENV_ADDR=y ++CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y ++CONFIG_IP_DEFRAG=y ++# CONFIG_DM_DEVICE_REMOVE is not set ++CONFIG_DEVRES=y ++CONFIG_SCSI_AHCI=y ++CONFIG_AHCI_PCI=y ++CONFIG_SPL_FIRMWARE=y ++CONFIG_GPIO_HOG=y ++CONFIG_ROCKCHIP_GPIO=y ++CONFIG_DM_PCA953X=y ++CONFIG_I2C_SET_DEFAULT_BUS_NUM=y ++CONFIG_I2C_DEFAULT_BUS_NUMBER=0x8 ++CONFIG_SYS_I2C_ROCKCHIP=y ++CONFIG_LED=y ++CONFIG_LED_GPIO=y ++CONFIG_MISC=y ++CONFIG_ROCKCHIP_EFUSE=y ++CONFIG_ROCKCHIP_OTP=y ++CONFIG_SUPPORT_EMMC_RPMB=y ++CONFIG_MMC_IO_VOLTAGE=y ++CONFIG_SPL_MMC_IO_VOLTAGE=y ++CONFIG_MMC_UHS_SUPPORT=y ++CONFIG_MMC_HS200_SUPPORT=y ++CONFIG_MMC_DW=y ++CONFIG_MMC_DW_ROCKCHIP=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_SDMA=y ++CONFIG_MMC_SDHCI_ROCKCHIP=y ++CONFIG_SPI_FLASH_WINBOND=y ++CONFIG_PHY_REALTEK=y ++CONFIG_DM_ETH=y ++CONFIG_DM_MDIO=y ++CONFIG_PHY_GIGE=y ++CONFIG_ETH_DESIGNWARE=y ++CONFIG_RGMII=y ++CONFIG_MII=y ++CONFIG_GMAC_ROCKCHIP=y ++CONFIG_PCI=y ++CONFIG_PHY_ROCKCHIP_INNO_USB2=y ++CONFIG_PHY_ROCKCHIP_TYPEC=y ++CONFIG_DM_PMIC_FAN53555=y ++CONFIG_PMIC_RK8XX=y ++CONFIG_SPL_DM_REGULATOR=y ++CONFIG_REGULATOR_PWM=y ++CONFIG_SPL_DM_REGULATOR_FIXED=y ++CONFIG_DM_REGULATOR_GPIO=y ++CONFIG_SPL_DM_REGULATOR_GPIO=y ++CONFIG_REGULATOR_RK8XX=y ++CONFIG_PWM_ROCKCHIP=y ++CONFIG_RAM_RK3399_LPDDR4=y ++CONFIG_DM_RESET=y ++CONFIG_SCSI=y ++CONFIG_DM_SCSI=y ++CONFIG_BAUDRATE=1500000 ++CONFIG_DEBUG_UART_SHIFT=2 ++CONFIG_ROCKCHIP_SPI=y ++CONFIG_SYSRESET=y ++CONFIG_SYSRESET_SYSCON=y ++CONFIG_DM_THERMAL=y ++CONFIG_USB=y ++# CONFIG_SPL_DM_USB is not set ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_DWC3=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_EHCI_GENERIC=y ++CONFIG_USB_DWC3=y ++CONFIG_USB_DWC3_GENERIC=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_FUNCTION_ROCKUSB=y ++CONFIG_USB_HOST_ETHER=y ++CONFIG_USB_ETHER_RTL8152=y ++CONFIG_SPL_TINY_MEMSET=y ++CONFIG_ERRNO_STR=y ++CONFIG_HEXDUMP=y +diff --git a/include/configs/helios64.h b/include/configs/helios64.h +new file mode 100644 +index 000000000..6fca9a6be +--- /dev/null ++++ b/include/configs/helios64.h +@@ -0,0 +1,47 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * (C) Copyright 2020 Aditya Prayoga ++ */ ++ ++#ifndef __HELIOS64_H ++#define __HELIOS64_H ++ ++#include ++ ++#define SDRAM_BANK_SIZE (2UL << 30) ++ ++#if defined(CONFIG_ENV_IS_IN_MMC) ++ #define CONFIG_SYS_MMC_ENV_DEV 0 ++#elif defined(CONFIG_ENV_IS_IN_SPI_FLASH) ++ #define CONFIG_ENV_SPI_BUS CONFIG_SF_DEFAULT_BUS ++ #define CONFIG_ENV_SPI_CS CONFIG_SF_DEFAULT_CS ++ #define CONFIG_ENV_SPI_MODE CONFIG_SF_DEFAULT_MODE ++ #define CONFIG_ENV_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED ++#endif ++ ++ ++#ifndef CONFIG_SPL_BUILD ++#if CONFIG_IS_ENABLED(SCSI) ++ ++ #define CONFIG_SYS_SCSI_MAX_SCSI_ID 5 ++ #define CONFIG_SYS_SCSI_MAX_LUN 1 ++ #define CONFIG_SYS_SCSI_MAX_DEVICE (CONFIG_SYS_SCSI_MAX_SCSI_ID * \ ++ CONFIG_SYS_SCSI_MAX_LUN) ++ ++ #define BOOT_TARGET_SCSI(func) \ ++ func(SCSI, scsi, 0) ++#else ++ #define BOOT_TARGET_SCSI(func) ++#endif ++ ++#undef BOOT_TARGET_DEVICES ++#define BOOT_TARGET_DEVICES(func) \ ++ BOOT_TARGET_MMC(func) \ ++ BOOT_TARGET_USB(func) \ ++ BOOT_TARGET_SCSI(func) \ ++ BOOT_TARGET_PXE(func) \ ++ BOOT_TARGET_DHCP(func) ++ ++#endif ++ ++#endif +-- +Created with Armbian build tools https://github.com/armbian/build + diff --git a/patch/u-boot/u-boot-rockchip64-mainline/rk3399-populate-child-node-of-syscon.patch b/patch/u-boot/u-boot-rockchip64-mainline/rk3399-populate-child-node-of-syscon.patch new file mode 100644 index 0000000000..3f36d5919f --- /dev/null +++ b/patch/u-boot/u-boot-rockchip64-mainline/rk3399-populate-child-node-of-syscon.patch @@ -0,0 +1,31 @@ +From 91cbd5f4fb25281319034c33b6e0c0f9b7d1e12b Mon Sep 17 00:00:00 2001 +Message-Id: <91cbd5f4fb25281319034c33b6e0c0f9b7d1e12b.1585676333.git.aditya@kobol.io> +In-Reply-To: +References: +From: Aditya Prayoga +Date: Wed, 4 Mar 2020 22:10:31 +0700 +Subject: [PATCH 4/4] arm:rockchip:rk3399: Populate child node of syscon + +U-Boot only populate first level of node. +Scan child node so device such as PHY can be initialized. +--- + arch/arm/mach-rockchip/rk3399/syscon_rk3399.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c b/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c +index 259ca44d68..81b04aa7f8 100644 +--- a/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c ++++ b/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c +@@ -21,6 +21,9 @@ U_BOOT_DRIVER(syscon_rk3399) = { + .name = "rk3399_syscon", + .id = UCLASS_SYSCON, + .of_match = rk3399_syscon_ids, ++#if !CONFIG_IS_ENABLED(OF_PLATDATA) ++ .bind = dm_scan_fdt_dev, ++#endif + }; + + #if CONFIG_IS_ENABLED(OF_PLATDATA) +-- +2.17.1 +