Merge Official Source

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
Tianling Shen
2026-05-22 12:06:42 +08:00
49 changed files with 5658 additions and 900 deletions
+4
View File
@@ -373,6 +373,7 @@ define Image/gzip-ext4-padded-squashfs
endef
ifeq ($(filter-out targz,$(ROOTFS_FILESYSTEM)),)
ifdef CONFIG_TARGET_ROOTFS_TARGZ
define Image/Build/targz
$(TAR) -cp --numeric-owner --owner=0 --group=0 --mode=a-s --sort=name \
@@ -380,12 +381,15 @@ ifdef CONFIG_TARGET_ROOTFS_TARGZ
-C $(TARGET_DIR)/ . | gzip -9n > $(BIN_DIR)/$(IMG_PREFIX)$(if $(PROFILE_SANITIZED),-$(PROFILE_SANITIZED))-rootfs.tar.gz
endef
endif
endif
ifeq ($(filter-out cpiogz,$(ROOTFS_FILESYSTEM)),)
ifdef CONFIG_TARGET_ROOTFS_CPIOGZ
define Image/Build/cpiogz
( cd $(TARGET_DIR); find . | $(STAGING_DIR_HOST)/bin/cpio -o -H newc -R 0:0 | gzip -9n >$(BIN_DIR)/$(IMG_ROOTFS).cpio.gz )
endef
endif
endif
mkfs_packages = $(filter-out @%,$(PACKAGES_$(call param_get,pkg,pkg=$(target_params))))
mkfs_packages_add = $(foreach pkg,$(filter-out -% ~%,$(mkfs_packages)),$(pkg)$(call GetABISuffix,$(pkg)))
@@ -262,7 +262,7 @@
+};
--- /dev/null
+++ b/defenvs/wavlink_wl-wnt100x3_env
@@ -0,0 +1,53 @@
@@ -0,0 +1,54 @@
+ipaddr=192.168.1.1
+serverip=192.168.1.254
+loadaddr=0x46000000
@@ -0,0 +1,75 @@
# SPDX-License-Identifier: GPL-2.0-or-later
include $(TOPDIR)/rules.mk
PKG_NAME:=rtl826x-firmware
PKG_SOURCE_DATE:=2026-01-24
PKG_RELEASE:=2
PKG_SOURCE_URL:=https://github.com/balika011/realtek_phy_firmware
PKG_SOURCE_VERSION:=0cd4abe2b0bf197f75c27088f86a74c7ddb103b4
PKG_SOURCE_PROTO:=git
PKG_MIRROR_HASH:=f665e9f119cbfddcccae09a17382daa8306772d1e37db7eb69a8771157d06d5f
PKG_MAINTAINER:=Balázs Triszka <info@balika011.hu>
PKG_LICENSE:=GPL-2.0-only
include $(INCLUDE_DIR)/package.mk
define Build/Compile
(set -e; cd $(PKG_BUILD_DIR); \
$(HOSTCC) rtl8261n_rtl8264b.c phy_patch.c -o phy_patch; \
./phy_patch \
)
endef
define Package/rtl8261n-firmware
SECTION:=firmware
CATEGORY:=Firmware
TITLE:=Realtek RTL8251L/RTL8261BE/RTL8261N firmware
VERSION:=20221115
PKGARCH:=all
endef
define Package/rtl8261n-lp-firmware
SECTION:=firmware
CATEGORY:=Firmware
TITLE:=Realtek RTL8251L/RTL8261BE/RTL8261N low-power firmware
VERSION:=20240729
PROVIDES:=rtl8261n-firmware
CONFLICTS:=rtl8261n-firmware
PKGARCH:=all
endef
define Package/rtl8264b-firmware
SECTION:=firmware
CATEGORY:=Firmware
TITLE:=Realtek RTL8254B/RTL8264/RTL8264B firmware
VERSION:=20221215
PKGARCH:=all
endef
define Package/rtl8261n-firmware/install
$(INSTALL_DIR) $(1)/lib/firmware
$(INSTALL_DATA) \
$(PKG_BUILD_DIR)/rtl8261n.bin \
$(1)/lib/firmware/
endef
define Package/rtl8261n-lp-firmware/install
$(INSTALL_DIR) $(1)/lib/firmware
$(INSTALL_DATA) \
$(PKG_BUILD_DIR)/rtl8261n_lp.bin \
$(1)/lib/firmware/rtl8261n.bin
endef
define Package/rtl8264b-firmware/install
$(INSTALL_DIR) $(1)/lib/firmware
$(INSTALL_DATA) \
$(PKG_BUILD_DIR)/rtl8264b.bin \
$(1)/lib/firmware/
endef
$(eval $(call BuildPackage,rtl8261n-firmware))
$(eval $(call BuildPackage,rtl8261n-lp-firmware))
$(eval $(call BuildPackage,rtl8264b-firmware))
@@ -0,0 +1,47 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Fri, 27 Mar 2026 00:17:23 +0100
Subject: Fix endianness when building on big endian systems
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Forwarded: https://github.com/balika011/realtek_phy_firmware/pull/2
--- a/phy_patch.c
+++ b/phy_patch.c
@@ -3,6 +3,7 @@
#include <linux/errno.h>
#include <string.h>
#include <stdlib.h>
+#include <endian.h>
#include "phy_patch.h"
@@ -12,11 +13,11 @@ int phy_patch_op(rt_phy_patch_db_t *pPhy
op.patch_op = patch_op;
op.portmask = portmask;
- op.pagemmd = pagemmd;
- op.addr = addr;
+ op.pagemmd = htole16(pagemmd);
+ op.addr = htole16(addr);
op.msb = msb;
op.lsb = lsb;
- op.data = data;
+ op.data = htole16(data);
return pPhy_patchDb->fPatch_op(phydev, &op);
}
@@ -41,11 +42,11 @@ static int _phy_patch_process(struct phy
{
patch.patch_op = pPatch[i].patch_op;
patch.portmask = pPatch[i].portmask;
- patch.pagemmd = pPatch[i].pagemmd;
- patch.addr = pPatch[i].addr;
+ patch.pagemmd = htole16(pPatch[i].pagemmd);
+ patch.addr = htole16(pPatch[i].addr);
patch.msb = pPatch[i].msb;
patch.lsb = pPatch[i].lsb;
- patch.data = pPatch[i].data;
+ patch.data = htole16(pPatch[i].data);
ret = pPatchDb->fPatch_op(phydev, &patch);
if (ret < 0)
+1 -1
View File
@@ -579,7 +579,7 @@ define KernelPackage/phy-rtl8261n
SUBMENU:=$(NETWORK_DEVICES_MENU)
TITLE:=Realtek RTL8261N NBASE-T PHY driver
KCONFIG:=CONFIG_RTL8261N_PHY
DEPENDS:=+kmod-libphy
DEPENDS:=@LINUX_6_12 +kmod-libphy
FILES:=$(LINUX_DIR)/drivers/net/phy/rtl8261n/rtl8261n.ko
AUTOLOAD:=$(call AutoLoad,18,rtl8261n,1)
endef
+84 -21
View File
@@ -75,11 +75,36 @@ check_setup_() {
check_setup() {
[ -n "$o_network" ] || return 0
[ -z "$o_user" ] || return 0
check_setup_ || {
__errmsg "please check the script content to see the environment requirement"
return 1
}
}
# Append user-mode networking args to o_qemu_extra. $1 is the qemu NIC device
# (e.g. virtio-net-pci, e1000). The LAN netdev shares OpenWrt's default LAN
# subnet so the guest's static 192.168.1.1 is reachable through SLIRP; the WAN
# netdev uses SLIRP defaults (10.0.2.0/24) to provide internet via the host.
add_user_netdev() {
local nic="$1"
local ssh="${o_ssh_port:-2222}"
local http="${o_http_port:-8080}"
local https="${o_https_port:-8443}"
__errmsg "user-mode networking: ssh on 127.0.0.1:$ssh, http on 127.0.0.1:$http, https on 127.0.0.1:$https"
local lan="user,id=lan,net=192.168.1.0/24,host=192.168.1.2"
lan+=",hostfwd=tcp:127.0.0.1:$ssh-192.168.1.1:22"
lan+=",hostfwd=tcp:127.0.0.1:$http-192.168.1.1:80"
lan+=",hostfwd=tcp:127.0.0.1:$https-192.168.1.1:443"
o_qemu_extra+=(
-netdev "$lan"
-device "$nic,id=devlan,netdev=lan,mac=$MAC_LAN"
-netdev "user,id=wan"
-device "$nic,id=devwan,netdev=wan,mac=$MAC_WAN"
)
}
#do_setup; check_setup; exit $?
usage() {
@@ -91,6 +116,7 @@ Usage: $SELF [-h|--help]
[--rootfs <rootfs>]
[--machine <machine>]
[-n|--network]
[-u|--user-network [--ssh-port <port>] [--http-port <port>] [--https-port <port>]]
<subtarget> will default to "generic" and must be specified if
<extra-qemu-options> are present
@@ -100,15 +126,31 @@ e.g. <subtarget> for malta can be le, be, le64, be64, le-glibc, le64-glibc, etc
<kernel>, <rootfs> can be required or optional arguments to qemu depending on
the actual <target> in use. They will default to files under bin/targets/
Networking modes:
-n / --network use bridges \$BR_LAN and \$BR_WAN (needs sudo + helper
setup)
-u / --user-network use rootless qemu user-mode networking; the guest LAN
interface (static 192.168.1.1) is reachable from the
host via 127.0.0.1:<ssh-port> (default 2222),
127.0.0.1:<http-port> (default 8080) and
127.0.0.1:<https-port> (default 8443); the guest WAN
gets internet via SLIRP
--ssh-port <p> override host-side ssh forward port (default 2222)
--http-port <p> override host-side http forward port (default 8080)
--https-port <p> override host-side https forward port (default 8443)
Examples
$SELF x86 64
$SELF x86 64 --user-network
$SELF x86 64 --user-network --ssh-port 2200 --http-port 8000 --https-port 8001
$SELF x86 64 --machine q35,accel=kvm -device virtio-balloon-pci
$SELF x86 64 -incoming tcp:0:4444
$SELF x86 64-glibc
$SELF malta be -m 64
$SELF malta le64
$SELF malta be-glibc
$SELF armsr armv8 --user-network
$SELF armsr armv7 \\
--machine virt,highmem=off \\
--kernel bin/targets/armsr/armv7/openwrt-armsr-armv7-generic-kernel.bin \\
@@ -122,6 +164,7 @@ rand_mac() {
parse_args() {
o_network=
o_user=
o_qemu_extra=()
while [ "$#" -gt 0 ]; do
# Cmdline options for the script itself SHOULD try to be
@@ -134,6 +177,10 @@ parse_args() {
--rootfs) o_rootfs="$2"; shift 2 ;;
--machine|-machine|-M) o_mach="$2"; shift 2 ;;
--network|-n) o_network=1; shift ;;
--user-network|-u) o_user=1; o_network=1; shift ;;
--ssh-port) o_ssh_port="$2"; shift 2 ;;
--http-port) o_http_port="$2"; shift 2 ;;
--https-port) o_https_port="$2"; shift 2 ;;
--help|-h)
usage
exit 0
@@ -196,12 +243,16 @@ start_qemu_armsr() {
}
[ -z "$o_network" ] || {
o_qemu_extra+=( \
"-netdev" "bridge,id=lan,br=$BR_LAN,helper=$HELPER" \
"-device" "virtio-net-pci,id=devlan,netdev=lan,mac=$MAC_LAN" \
"-netdev" "bridge,id=wan,br=$BR_WAN,helper=$HELPER" "-device" \
"virtio-net-pci,id=devwan,netdev=wan,mac=$MAC_WAN" \
)
if [ -n "$o_user" ]; then
add_user_netdev virtio-net-pci
else
o_qemu_extra+=( \
"-netdev" "bridge,id=lan,br=$BR_LAN,helper=$HELPER" \
"-device" "virtio-net-pci,id=devlan,netdev=lan,mac=$MAC_LAN" \
"-netdev" "bridge,id=wan,br=$BR_WAN,helper=$HELPER" "-device" \
"virtio-net-pci,id=devwan,netdev=wan,mac=$MAC_WAN" \
)
fi
}
"$qemu_exe" -machine "$mach" -cpu "$cpu" -nographic \
@@ -236,14 +287,18 @@ start_qemu_malta() {
)
}
# NOTE: order of wan, lan -device arguments matters as it will affect which
# one will be actually used as the wan, lan network interface inside the
# guest machine
# NOTE: order of -device arguments matters: the first -device becomes eth0
# in the guest, which OpenWrt's 99-default_network assigns as LAN; the
# second becomes eth1 / WAN. Keep LAN first to match that mapping.
[ -z "$o_network" ] || {
o_qemu_extra+=(
-netdev bridge,id=wan,br="$BR_WAN,helper=$HELPER" -device pcnet,netdev=wan,mac="$MAC_WAN"
-netdev bridge,id=lan,br="$BR_LAN,helper=$HELPER" -device pcnet,netdev=lan,mac="$MAC_LAN"
)
if [ -n "$o_user" ]; then
add_user_netdev pcnet
else
o_qemu_extra+=(
-netdev bridge,id=lan,br="$BR_LAN,helper=$HELPER" -device pcnet,netdev=lan,mac="$MAC_LAN"
-netdev bridge,id=wan,br="$BR_WAN,helper=$HELPER" -device pcnet,netdev=wan,mac="$MAC_WAN"
)
fi
}
"$qemu_exe" -machine "$mach" -cpu "$cpu" -nographic \
@@ -287,16 +342,24 @@ start_qemu_x86() {
[ -z "$o_network" ] || {
case "${o_subtarget%-*}" in
legacy)
o_qemu_extra+=(
-netdev "bridge,id=lan,br=$BR_LAN,helper=$HELPER" -device "e1000,id=devlan,netdev=lan,mac=$MAC_LAN"
-netdev "bridge,id=wan,br=$BR_WAN,helper=$HELPER" -device "e1000,id=devwan,netdev=wan,mac=$MAC_WAN"
)
if [ -n "$o_user" ]; then
add_user_netdev e1000
else
o_qemu_extra+=(
-netdev "bridge,id=lan,br=$BR_LAN,helper=$HELPER" -device "e1000,id=devlan,netdev=lan,mac=$MAC_LAN"
-netdev "bridge,id=wan,br=$BR_WAN,helper=$HELPER" -device "e1000,id=devwan,netdev=wan,mac=$MAC_WAN"
)
fi
;;
generic|64)
o_qemu_extra+=(
-netdev "bridge,id=lan,br=$BR_LAN,helper=$HELPER" -device "virtio-net-pci,id=devlan,netdev=lan,mac=$MAC_LAN"
-netdev "bridge,id=wan,br=$BR_WAN,helper=$HELPER" -device "virtio-net-pci,id=devwan,netdev=wan,mac=$MAC_WAN"
)
if [ -n "$o_user" ]; then
add_user_netdev virtio-net-pci
else
o_qemu_extra+=(
-netdev "bridge,id=lan,br=$BR_LAN,helper=$HELPER" -device "virtio-net-pci,id=devlan,netdev=lan,mac=$MAC_LAN"
-netdev "bridge,id=wan,br=$BR_WAN,helper=$HELPER" -device "virtio-net-pci,id=devwan,netdev=wan,mac=$MAC_WAN"
)
fi
;;
esac
}
-1
View File
@@ -5548,7 +5548,6 @@ CONFIG_RTC_SYSTOHC_DEVICE="rtc0"
# CONFIG_RTL8180 is not set
# CONFIG_RTL8187 is not set
# CONFIG_RTL8192E is not set
# CONFIG_RTL8261N_PHY is not set
# CONFIG_RTL8306_PHY is not set
# CONFIG_RTL8366RB_PHY is not set
# CONFIG_RTL8366S_PHY is not set
@@ -1,28 +0,0 @@
From: John Crispin <john@phrozen.org>
Date: Tue, 29 Oct 2024 13:37:40 +0100
Subject: [PATCH] net: add support for Realtek RTL8261n 10G PHYs
There is no upstream driver yet. Merge the RTL SDK driver for now.
Signed-off-by: John Crispin <john@phrozen.org>
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -459,6 +459,8 @@ config QSEMI_PHY
source "drivers/net/phy/realtek/Kconfig"
+source "drivers/net/phy/rtl8261n/Kconfig"
+
config RENESAS_PHY
tristate "Renesas PHYs"
help
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -106,6 +106,7 @@ obj-$(CONFIG_NXP_TJA11XX_PHY) += nxp-tja
obj-y += qcom/
obj-$(CONFIG_QSEMI_PHY) += qsemi.o
obj-$(CONFIG_REALTEK_PHY) += realtek/
+obj-y += rtl8261n/
obj-$(CONFIG_RENESAS_PHY) += uPD60620.o
obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o
obj-$(CONFIG_SMSC_PHY) += smsc.o
@@ -471,7 +471,6 @@ CONFIG_RPS=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_MT7622=y
CONFIG_RTC_I2C_AND_SPI=y
CONFIG_RTL8261N_PHY=y
# CONFIG_RTL8367S_GSW is not set
CONFIG_RWSEM_SPIN_ON_OWNER=y
CONFIG_SCHED_MC=y
+4 -2
View File
@@ -2150,7 +2150,8 @@ TARGET_DEVICES += keenetic_kap-630
define Device/keenetic_kn-1812-common
DEVICE_DTS_DIR := ../dts
DEVICE_PACKAGES := kmod-mt7992-firmware kmod-usb3 automount \
mt7988-2p5g-phy-firmware mt7988-wo-firmware
mt7988-2p5g-phy-firmware mt7988-wo-firmware \
kmod-phy-realtek rtl8261n-firmware
UBINIZE_OPTS := -E 5
BLOCKSIZE := 128k
PAGESIZE := 2048
@@ -3218,7 +3219,8 @@ define Device/tplink_be450
DEVICE_DTS := mt7988d-tplink-be450
DEVICE_DTS_DIR := ../dts
DEVICE_PACKAGES := kmod-mt7992-firmware kmod-usb3 automount \
mt7988-2p5g-phy-firmware mt7988-wo-firmware
mt7988-2p5g-phy-firmware mt7988-wo-firmware \
kmod-phy-realtek rtl8261n-firmware
UBINIZE_OPTS := -E 5
BLOCKSIZE := 128k
PAGESIZE := 2048
@@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -471,6 +471,12 @@ config ROCKCHIP_PHY
@@ -469,6 +469,12 @@ config ROCKCHIP_PHY
help
Currently supports the integrated Ethernet PHY.
@@ -26,8 +26,8 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
select CRC16
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -109,6 +109,7 @@ obj-$(CONFIG_REALTEK_PHY) += realtek/
obj-y += rtl8261n/
@@ -108,6 +108,7 @@ obj-$(CONFIG_QSEMI_PHY) += qsemi.o
obj-$(CONFIG_REALTEK_PHY) += realtek/
obj-$(CONFIG_RENESAS_PHY) += uPD60620.o
obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o
+obj-$(CONFIG_RTL8367S_GSW) += rtk/
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/dts-v1/;
#include "rtl9313_zyxel_xs1930.dtsi"
#include "rtl9313_zyxel_xs1930-aqr813.dtsi"
#include <dt-bindings/input/input.h>
#include <dt-bindings/gpio/gpio.h>
@@ -12,131 +12,10 @@
/ {
compatible = "zyxel,xs1930-10", "realtek,rtl9313-soc";
model = "Zyxel XS1930-10";
leds {
led_pwr_green: led-2 {
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_POWER;
gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>;
default-state = "on";
};
led_pwr_red: led-3 {
color = <LED_COLOR_ID_RED>;
function = LED_FUNCTION_POWER;
gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
};
led_cloud_green: led-4 {
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
};
led_cloud_red: led-5 {
color = <LED_COLOR_ID_RED>;
gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
};
led_locator: led-6 {
color = <LED_COLOR_ID_BLUE>;
function = LED_FUNCTION_INDICATOR;
gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
};
};
led_set: led_set@0 {
compatible = "realtek,rtl9300-leds";
active-low;
/* Blue | Green | Red */
led_set0 = <(RTL93XX_LED_SET_10G | RTL93XX_LED_SET_5G | RTL93XX_LED_SET_2P5G |
RTL93XX_LED_SET_LINK | RTL93XX_LED_SET_ACT)
(RTL93XX_LED_SET_2P5G | RTL93XX_LED_SET_1G | RTL93XX_LED_SET_100M |
RTL93XX_LED_SET_LINK | RTL93XX_LED_SET_ACT)
(RTL93XX_LED_SET_5G | RTL93XX_LED_SET_100M | RTL93XX_LED_SET_LINK |
RTL93XX_LED_SET_ACT)>;
realtek,led-set0-force-port-mask = <0x00300000 0x00000000>;
};
sfp_gpio_mux: gpio-mux {
compatible = "gpio-mux";
mux-gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>,
<&gpio0 14 GPIO_ACTIVE_HIGH>;
#mux-control-cells = <0>;
idle-state = <MUX_IDLE_AS_IS>;
};
sfp1_gpio: sfp-gpio-1 {
compatible = "gpio-line-mux";
gpio-controller;
#gpio-cells = <2>;
mux-controls = <&sfp_gpio_mux>;
muxed-gpio = <&gpio0 19 GPIO_ACTIVE_HIGH>;
gpio-line-names = "SFP1_LOS", "SFP1_MOD_ABS", "SFP1_TX_FAULT";
gpio-line-mux-states = <0>, <1>, <3>;
};
sfp2_gpio: sfp-gpio-2 {
compatible = "gpio-line-mux";
gpio-controller;
#gpio-cells = <2>;
mux-controls = <&sfp_gpio_mux>;
muxed-gpio = <&gpio0 27 GPIO_ACTIVE_HIGH>;
gpio-line-names = "SFP2_LOS", "SFP2_MOD_ABS", "SFP2_TX_FAULT";
gpio-line-mux-states = <0>, <1>, <3>;
};
sfp1: sfp-p1 {
compatible = "sff,sfp";
i2c-bus = <&i2c0>;
los-gpio = <&sfp1_gpio 0 GPIO_ACTIVE_HIGH>;
mod-def0-gpio = <&sfp1_gpio 1 GPIO_ACTIVE_LOW>;
tx-disable-gpio = <&gpio0 5 GPIO_ACTIVE_HIGH>;
tx-fault-gpio = <&sfp1_gpio 2 GPIO_ACTIVE_HIGH>;
};
sfp2: sfp-p2 {
compatible = "sff,sfp";
i2c-bus = <&i2c1>;
los-gpio = <&sfp2_gpio 0 GPIO_ACTIVE_HIGH>;
mod-def0-gpio = <&sfp2_gpio 1 GPIO_ACTIVE_LOW>;
tx-disable-gpio = <&gpio0 11 GPIO_ACTIVE_HIGH>;
tx-fault-gpio = <&sfp2_gpio 2 GPIO_ACTIVE_HIGH>;
};
};
&gpio0 {
pinctrl-names = "default";
pinctrl-0 = <&pinmux_disable_jtag>;
sfp_enable_hog {
gpio-hog;
gpios = <6 GPIO_ACTIVE_LOW>,
<7 GPIO_ACTIVE_LOW>;
output-high;
line-name = "sfp-enable";
};
};
&i2c_mst1 {
status = "okay";
i2c0: i2c@0 {
reg = <0>;
};
i2c1: i2c@1 {
reg = <1>;
};
i2c2: i2c@2 {
reg = <2>;
lm96000: lm96000@2e {
compatible = "national,lm85";
reg = <0x2e>;
};
};
&led_set {
realtek,led-set0-force-port-mask = <0x00300000 0x00000000>;
};
&mdio_ctrl {
@@ -144,106 +23,9 @@
pinctrl-0 = <&pinmux_enable_mdc_mdio_0>;
};
&mdio_bus0 {
/* External Aquantia AQR813 */
PHY_C45(0, 8)
PHY_C45(8, 9)
PHY_C45(16, 10)
PHY_C45(24, 11)
PHY_C45(32, 12)
PHY_C45(40, 13)
PHY_C45(48, 14)
PHY_C45(50, 15)
};
&switch0 {
ethernet-ports {
#address-cells = <1>;
#size-cells = <0>;
/* Copper ports behind AQR813 */
SWITCH_PORT_LED(0, 1, 2, 0, usxgmii)
SWITCH_PORT_LED(8, 2, 3, 0, usxgmii)
SWITCH_PORT_LED(16, 3, 4, 0, usxgmii)
SWITCH_PORT_LED(24, 4, 5, 0, usxgmii)
SWITCH_PORT_LED(32, 5, 6, 0, usxgmii)
SWITCH_PORT_LED(40, 6, 7, 0, usxgmii)
SWITCH_PORT_LED(48, 7, 8, 0, usxgmii)
SWITCH_PORT_LED(50, 8, 9, 0, usxgmii)
/* SFP+ ports */
SWITCH_PORT_SFP(54, 9, 12, 0, 1)
SWITCH_PORT_SFP(55, 10, 13, 0, 2)
/* CPU port */
port@56 {
reg = <56>;
ethernet = <&ethernet0>;
phy-mode = "internal";
fixed-link {
speed = <1000>;
full-duplex;
};
};
};
};
&port0 {
managed = "in-band-status";
};
&port8 {
managed = "in-band-status";
};
&port16 {
managed = "in-band-status";
};
&port24 {
managed = "in-band-status";
};
&port32 {
managed = "in-band-status";
};
&port40 {
managed = "in-band-status";
};
&port48 {
managed = "in-band-status";
};
&port50 {
managed = "in-band-status";
};
&serdes6 {
rx-polarity = <PHY_POL_INVERT>;
tx-polarity = <PHY_POL_INVERT>;
};
&serdes7 {
rx-polarity = <PHY_POL_INVERT>;
tx-polarity = <PHY_POL_INVERT>;
};
&serdes8 {
rx-polarity = <PHY_POL_INVERT>;
tx-polarity = <PHY_POL_INVERT>;
};
&serdes9 {
rx-polarity = <PHY_POL_INVERT>;
tx-polarity = <PHY_POL_INVERT>;
};
&serdes12 {
tx-polarity = <PHY_POL_INVERT>;
};
&serdes13 {
tx-polarity = <PHY_POL_INVERT>;
};
@@ -13,51 +13,6 @@
compatible = "zyxel,xs1930-12f", "realtek,rtl9313-soc";
model = "Zyxel XS1930-12F";
leds {
led_pwr_green: led-2 {
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_POWER;
gpios = <&gpio2 10 GPIO_ACTIVE_HIGH>;
default-state = "on";
};
led_pwr_red: led-3 {
color = <LED_COLOR_ID_RED>;
function = LED_FUNCTION_POWER;
gpios = <&gpio2 11 GPIO_ACTIVE_LOW>;
};
led_cloud_green: led-4 {
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
};
led_cloud_red: led-5 {
color = <LED_COLOR_ID_RED>;
gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
};
led_locator: led-6 {
color = <LED_COLOR_ID_BLUE>;
function = LED_FUNCTION_INDICATOR;
gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
};
};
led_set: led_set@0 {
compatible = "realtek,rtl9300-leds";
active-low;
/* SFP ports */
led_set0 = <(RTL93XX_LED_SET_10G | RTL93XX_LED_SET_2P5G | RTL93XX_LED_SET_LINK |
RTL93XX_LED_SET_ACT)
(RTL93XX_LED_SET_2P5G | RTL93XX_LED_SET_1G | RTL93XX_LED_SET_LINK |
RTL93XX_LED_SET_ACT)>;
/* Base-T ports */
led_set1 = <(RTL93XX_LED_SET_10G | RTL93XX_LED_SET_5G | RTL93XX_LED_SET_2P5G |
RTL93XX_LED_SET_LINK | RTL93XX_LED_SET_ACT)
(RTL93XX_LED_SET_2P5G | RTL93XX_LED_SET_1G | RTL93XX_LED_SET_100M |
RTL93XX_LED_SET_LINK | RTL93XX_LED_SET_ACT)
(RTL93XX_LED_SET_5G | RTL93XX_LED_SET_100M | RTL93XX_LED_SET_LINK |
RTL93XX_LED_SET_ACT)>;
};
sfp1: sfp-p1 {
compatible = "sff,sfp";
i2c-bus = <&i2c0>;
@@ -149,6 +104,8 @@
};
};
&fan0 { gpios = <&gpio1 35 GPIO_ACTIVE_HIGH>; };
&gpio0 {
pinctrl-names = "default";
pinctrl-0 = <&pinmux_disable_jtag>,
@@ -158,41 +115,21 @@
&i2c_mst1 {
status = "okay";
i2c0: i2c@0 {
reg = <0>;
};
i2c1: i2c@1 {
reg = <1>;
};
i2c2: i2c@2 {
reg = <2>;
};
i2c3: i2c@3 {
reg = <3>;
};
i2c4: i2c@4 {
reg = <4>;
};
i2c5: i2c@5 {
reg = <5>;
};
i2c0: i2c@0 { reg = <0>; };
i2c1: i2c@1 { reg = <1>; };
i2c2: i2c@2 { reg = <2>; };
i2c3: i2c@3 { reg = <3>; };
i2c4: i2c@4 { reg = <4>; };
i2c5: i2c@5 { reg = <5>; };
};
&i2c_mst2 {
status = "okay";
i2c6: i2c@6 {
reg = <6>;
};
i2c7: i2c@7 {
reg = <7>;
};
i2c8: i2c@8 {
reg = <8>;
};
i2c9: i2c@9 {
reg = <9>;
};
i2c6: i2c@6 { reg = <6>; };
i2c7: i2c@7 { reg = <7>; };
i2c8: i2c@8 { reg = <8>; };
i2c9: i2c@9 { reg = <9>; };
i2c11: i2c@b {
reg = <0xb>;
@@ -230,6 +167,20 @@
};
};
&led_pwr_green { gpios = <&gpio2 10 GPIO_ACTIVE_HIGH>; };
&led_pwr_red { gpios = <&gpio2 11 GPIO_ACTIVE_LOW>; };
&led_cloud_green { gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; };
&led_cloud_red { gpios = <&gpio1 16 GPIO_ACTIVE_LOW>; };
&led_locator { gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; };
&led_set {
/* SFP ports */
led_set1 = <(RTL93XX_LED_SET_10G | RTL93XX_LED_SET_2P5G | RTL93XX_LED_SET_LINK |
RTL93XX_LED_SET_ACT)
(RTL93XX_LED_SET_2P5G | RTL93XX_LED_SET_1G | RTL93XX_LED_SET_LINK |
RTL93XX_LED_SET_ACT)>;
};
&mdio_aux {
status = "okay";
@@ -267,20 +218,20 @@
#address-cells = <1>;
#size-cells = <0>;
SWITCH_PORT_SFP(0, 1, 2, 0, 1)
SWITCH_PORT_SFP(8, 2, 3, 0, 2)
SWITCH_PORT_SFP(16, 3, 4, 0, 3)
SWITCH_PORT_SFP(24, 4, 5, 0, 4)
SWITCH_PORT_SFP(32, 5, 6, 0, 5)
SWITCH_PORT_SFP(40, 6, 7, 0, 6)
SWITCH_PORT_SFP(48, 7, 8, 0, 7)
SWITCH_PORT_SFP(50, 8, 9, 0, 8)
SWITCH_PORT_SFP(52, 9, 10, 0, 9)
SWITCH_PORT_SFP(53, 10, 11, 0, 10)
SWITCH_PORT_SFP(0, 1, 2, 1, 1)
SWITCH_PORT_SFP(8, 2, 3, 1, 2)
SWITCH_PORT_SFP(16, 3, 4, 1, 3)
SWITCH_PORT_SFP(24, 4, 5, 1, 4)
SWITCH_PORT_SFP(32, 5, 6, 1, 5)
SWITCH_PORT_SFP(40, 6, 7, 1, 6)
SWITCH_PORT_SFP(48, 7, 8, 1, 7)
SWITCH_PORT_SFP(50, 8, 9, 1, 8)
SWITCH_PORT_SFP(52, 9, 10, 1, 9)
SWITCH_PORT_SFP(53, 10, 11, 1, 10)
/* Base-T ports */
SWITCH_PORT_LED(54, 11, 12, 1, usxgmii)
SWITCH_PORT_LED(55, 12, 13, 1, usxgmii)
SWITCH_PORT_LED(54, 11, 12, 0, usxgmii)
SWITCH_PORT_LED(55, 12, 13, 0, usxgmii)
/* CPU port */
port@56 {
@@ -295,51 +246,17 @@
};
};
&port54 {
managed = "in-band-status";
};
&port54 { managed = "in-band-status"; };
&port55 { managed = "in-band-status"; };
&port55 {
managed = "in-band-status";
};
&serdes2 {
tx-polarity = <PHY_POL_INVERT>;
};
&serdes3 {
tx-polarity = <PHY_POL_INVERT>;
};
&serdes4 {
tx-polarity = <PHY_POL_INVERT>;
};
&serdes5 {
tx-polarity = <PHY_POL_INVERT>;
};
&serdes6 {
tx-polarity = <PHY_POL_INVERT>;
};
&serdes7 {
tx-polarity = <PHY_POL_INVERT>;
};
&serdes8 {
tx-polarity = <PHY_POL_INVERT>;
};
&serdes9 {
tx-polarity = <PHY_POL_INVERT>;
};
&serdes10 {
tx-polarity = <PHY_POL_INVERT>;
};
&serdes11 {
tx-polarity = <PHY_POL_INVERT>;
};
&serdes2 { tx-polarity = <PHY_POL_INVERT>; };
&serdes3 { tx-polarity = <PHY_POL_INVERT>; };
&serdes4 { tx-polarity = <PHY_POL_INVERT>; };
&serdes5 { tx-polarity = <PHY_POL_INVERT>; };
&serdes6 { tx-polarity = <PHY_POL_INVERT>; };
&serdes7 { tx-polarity = <PHY_POL_INVERT>; };
&serdes8 { tx-polarity = <PHY_POL_INVERT>; };
&serdes9 { tx-polarity = <PHY_POL_INVERT>; };
&serdes10 { tx-polarity = <PHY_POL_INVERT>; };
&serdes11 { tx-polarity = <PHY_POL_INVERT>; };
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/dts-v1/;
#include "rtl9313_zyxel_xs1930.dtsi"
#include "rtl9313_zyxel_xs1930-aqr813.dtsi"
#include <dt-bindings/input/input.h>
#include <dt-bindings/gpio/gpio.h>
@@ -14,121 +14,35 @@
model = "Zyxel XS1930-12HP";
leds {
led_pwr_green: led-2 {
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_POWER;
gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>;
default-state = "on";
};
led_pwr_red: led-3 {
led_poe_max: led-7 {
color = <LED_COLOR_ID_RED>;
function = LED_FUNCTION_POWER;
gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
function = "poe-usage";
gpios = <&gpio0 3 GPIO_ACTIVE_LOW>;
};
led_cloud_green: led-4 {
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
};
led_cloud_red: led-5 {
color = <LED_COLOR_ID_RED>;
gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
};
led_locator: led-6 {
color = <LED_COLOR_ID_BLUE>;
function = LED_FUNCTION_INDICATOR;
gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
};
};
led_set: led_set@0 {
compatible = "realtek,rtl9300-leds";
active-low;
/* Blue | Green | Red */
led_set0 = <(RTL93XX_LED_SET_10G | RTL93XX_LED_SET_5G | RTL93XX_LED_SET_2P5G |
RTL93XX_LED_SET_LINK | RTL93XX_LED_SET_ACT)
(RTL93XX_LED_SET_2P5G | RTL93XX_LED_SET_1G | RTL93XX_LED_SET_100M |
RTL93XX_LED_SET_LINK | RTL93XX_LED_SET_ACT)
(RTL93XX_LED_SET_5G | RTL93XX_LED_SET_100M | RTL93XX_LED_SET_LINK |
RTL93XX_LED_SET_ACT)>;
/* Phantom port chain padding (2 LEDs) */
led_set1 = <RTL93XX_LED_SET_NONE
RTL93XX_LED_SET_NONE>;
/* The LED PCB has two daisy-chained RTL8231 in scan mode.
* Net LEDs for P3-P12 are on the first RTL8231, P1/P2
* net LEDs are on the second. The 12 real ports provide
* 36 LED bits but the chain requires 65 bits to correctly
* span both chips. Phantom ports 1-7, 9-10 (set0, 3 LEDs
* each) and port 11 (set1, 2 LEDs) pad the chain with
* the remaining 29 bits.
*/
realtek,led-set0-force-port-mask = <0x00000000 0x000006FE>;
realtek,led-set1-force-port-mask = <0x00000000 0x00000800>;
};
sfp_gpio_mux: gpio-mux {
compatible = "gpio-mux";
mux-gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>,
<&gpio0 14 GPIO_ACTIVE_HIGH>;
#mux-control-cells = <0>;
idle-state = <MUX_IDLE_AS_IS>;
};
sfp1_gpio: sfp-gpio-1 {
compatible = "gpio-line-mux";
gpio-controller;
#gpio-cells = <2>;
mux-controls = <&sfp_gpio_mux>;
muxed-gpio = <&gpio0 19 GPIO_ACTIVE_HIGH>;
gpio-line-names = "SFP1_LOS", "SFP1_MOD_ABS", "SFP1_TX_FAULT";
gpio-line-mux-states = <0>, <1>, <3>;
};
sfp2_gpio: sfp-gpio-2 {
compatible = "gpio-line-mux";
gpio-controller;
#gpio-cells = <2>;
mux-controls = <&sfp_gpio_mux>;
muxed-gpio = <&gpio0 27 GPIO_ACTIVE_HIGH>;
gpio-line-names = "SFP2_LOS", "SFP2_MOD_ABS", "SFP2_TX_FAULT";
gpio-line-mux-states = <0>, <1>, <3>;
};
sfp1: sfp-p1 {
compatible = "sff,sfp";
i2c-bus = <&i2c0>;
los-gpio = <&sfp1_gpio 0 GPIO_ACTIVE_HIGH>;
mod-def0-gpio = <&sfp1_gpio 1 GPIO_ACTIVE_LOW>;
tx-disable-gpio = <&gpio0 5 GPIO_ACTIVE_HIGH>;
tx-fault-gpio = <&sfp1_gpio 2 GPIO_ACTIVE_HIGH>;
};
sfp2: sfp-p2 {
compatible = "sff,sfp";
i2c-bus = <&i2c1>;
los-gpio = <&sfp2_gpio 0 GPIO_ACTIVE_HIGH>;
mod-def0-gpio = <&sfp2_gpio 1 GPIO_ACTIVE_LOW>;
tx-disable-gpio = <&gpio0 11 GPIO_ACTIVE_HIGH>;
tx-fault-gpio = <&sfp2_gpio 2 GPIO_ACTIVE_HIGH>;
};
};
&gpio0 {
pinctrl-names = "default";
pinctrl-0 = <&pinmux_disable_jtag>;
&led_set {
/* Phantom port chain padding (2 LEDs) */
led_set1 = <RTL93XX_LED_SET_NONE
RTL93XX_LED_SET_NONE>;
sfp_enable_hog {
gpio-hog;
gpios = <6 GPIO_ACTIVE_LOW>,
<7 GPIO_ACTIVE_LOW>;
output-high;
line-name = "sfp-enable";
};
/* The LED PCB has two daisy-chained RTL8231 in scan mode.
* Net LEDs for P3-P12 are on the first RTL8231, P1/P2
* net LEDs are on the second. The 12 real ports provide
* 36 LED bits but the chain requires 65 bits to correctly
* span both chips. Phantom ports 1-7, 9-10 (set0, 3 LEDs
* each) and port 11 (set1, 2 LEDs) pad the chain with
* the remaining 29 bits.
*/
realtek,led-set0-force-port-mask = <0x00000000 0x000006FE>;
realtek,led-set1-force-port-mask = <0x00000000 0x00000800>;
};
&led_sys_green { gpios = <&gpio0 23 GPIO_ACTIVE_LOW>; };
&led_sys_red { gpios = <&gpio0 0 GPIO_ACTIVE_LOW>; };
&gpio0 {
poe_enable_hog {
gpio-hog;
gpios = <10 GPIO_ACTIVE_HIGH>;
@@ -138,29 +52,8 @@
};
&i2c_mst1 {
status = "okay";
i2c0: i2c@0 {
reg = <0>;
};
i2c1: i2c@1 {
reg = <1>;
};
i2c2: i2c@2 {
reg = <2>;
lm96000: lm96000@2e {
compatible = "national,lm85";
reg = <0x2e>;
};
};
/* PoE management MCU sits here */
i2c3: i2c@3 {
reg = <3>;
};
i2c3: i2c@3 { reg = <3>; };
};
&mdio_ctrl {
@@ -170,18 +63,6 @@
<&pinmux_enable_mdc_mdio_2>;
};
&mdio_bus0 {
/* AQR813 */
PHY_C45(0, 8)
PHY_C45(8, 9)
PHY_C45(16, 10)
PHY_C45(24, 11)
PHY_C45(32, 12)
PHY_C45(40, 13)
PHY_C45(48, 14)
PHY_C45(50, 15)
};
&mdio_bus1 {
PHY_C45(52, 0) /* AQR113C */
};
@@ -192,112 +73,18 @@
&switch0 {
ethernet-ports {
#address-cells = <1>;
#size-cells = <0>;
/* Copper ports behind AQR813 */
SWITCH_PORT_LED(0, 1, 2, 0, usxgmii)
SWITCH_PORT_LED(8, 2, 3, 0, usxgmii)
SWITCH_PORT_LED(16, 3, 4, 0, usxgmii)
SWITCH_PORT_LED(24, 4, 5, 0, usxgmii)
SWITCH_PORT_LED(32, 5, 6, 0, usxgmii)
SWITCH_PORT_LED(40, 6, 7, 0, usxgmii)
SWITCH_PORT_LED(48, 7, 8, 0, usxgmii)
SWITCH_PORT_LED(50, 8, 9, 0, usxgmii)
/* Copper ports behind AQR113C */
SWITCH_PORT_LED(52, 9, 10, 0, usxgmii)
SWITCH_PORT_LED(53, 10, 11, 0, usxgmii)
/* SFP+ ports */
SWITCH_PORT_SFP(54, 11, 12, 0, 1)
SWITCH_PORT_SFP(55, 12, 13, 0, 2)
/* CPU port */
port@56 {
ethernet = <&ethernet0>;
reg = <56>;
phy-mode = "internal";
fixed-link {
speed = <1000>;
full-duplex;
};
};
};
};
&port0 {
managed = "in-band-status";
};
&port52 { managed = "in-band-status"; };
&port53 { managed = "in-band-status"; };
&port8 {
managed = "in-band-status";
};
&serdes10 { tx-polarity = <PHY_POL_INVERT>; };
&serdes11 { tx-polarity = <PHY_POL_INVERT>; };
&port16 {
managed = "in-band-status";
};
&port24 {
managed = "in-band-status";
};
&port32 {
managed = "in-band-status";
};
&port40 {
managed = "in-band-status";
};
&port48 {
managed = "in-band-status";
};
&port50 {
managed = "in-band-status";
};
&port52 {
managed = "in-band-status";
};
&port53 {
managed = "in-band-status";
};
&serdes6 {
rx-polarity = <PHY_POL_INVERT>;
tx-polarity = <PHY_POL_INVERT>;
};
&serdes7 {
rx-polarity = <PHY_POL_INVERT>;
tx-polarity = <PHY_POL_INVERT>;
};
&serdes8 {
rx-polarity = <PHY_POL_INVERT>;
tx-polarity = <PHY_POL_INVERT>;
};
&serdes9 {
rx-polarity = <PHY_POL_INVERT>;
tx-polarity = <PHY_POL_INVERT>;
};
&serdes10 {
tx-polarity = <PHY_POL_INVERT>;
};
&serdes11 {
tx-polarity = <PHY_POL_INVERT>;
};
&serdes12 {
tx-polarity = <PHY_POL_INVERT>;
};
&serdes13 {
tx-polarity = <PHY_POL_INVERT>;
};
@@ -0,0 +1,183 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/dts-v1/;
#include "rtl9313_zyxel_xs1930.dtsi"
#include <dt-bindings/input/input.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/leds/common.h>
#include <dt-bindings/mux/mux.h>
#include <dt-bindings/phy/phy.h>
/ {
sfp_gpio_mux: gpio-mux {
compatible = "gpio-mux";
mux-gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>,
<&gpio0 14 GPIO_ACTIVE_HIGH>;
#mux-control-cells = <0>;
idle-state = <MUX_IDLE_AS_IS>;
};
sfp1_gpio: sfp-gpio-1 {
compatible = "gpio-line-mux";
gpio-controller;
#gpio-cells = <2>;
mux-controls = <&sfp_gpio_mux>;
muxed-gpio = <&gpio0 19 GPIO_ACTIVE_HIGH>;
gpio-line-names = "SFP1_LOS", "SFP1_MOD_ABS", "SFP1_TX_FAULT";
gpio-line-mux-states = <0>, <1>, <3>;
};
sfp2_gpio: sfp-gpio-2 {
compatible = "gpio-line-mux";
gpio-controller;
#gpio-cells = <2>;
mux-controls = <&sfp_gpio_mux>;
muxed-gpio = <&gpio0 27 GPIO_ACTIVE_HIGH>;
gpio-line-names = "SFP2_LOS", "SFP2_MOD_ABS", "SFP2_TX_FAULT";
gpio-line-mux-states = <0>, <1>, <3>;
};
sfp1: sfp-p1 {
compatible = "sff,sfp";
i2c-bus = <&i2c0>;
los-gpio = <&sfp1_gpio 0 GPIO_ACTIVE_HIGH>;
mod-def0-gpio = <&sfp1_gpio 1 GPIO_ACTIVE_LOW>;
tx-disable-gpio = <&gpio0 5 GPIO_ACTIVE_HIGH>;
tx-fault-gpio = <&sfp1_gpio 2 GPIO_ACTIVE_HIGH>;
};
sfp2: sfp-p2 {
compatible = "sff,sfp";
i2c-bus = <&i2c1>;
los-gpio = <&sfp2_gpio 0 GPIO_ACTIVE_HIGH>;
mod-def0-gpio = <&sfp2_gpio 1 GPIO_ACTIVE_LOW>;
tx-disable-gpio = <&gpio0 11 GPIO_ACTIVE_HIGH>;
tx-fault-gpio = <&sfp2_gpio 2 GPIO_ACTIVE_HIGH>;
};
};
&gpio0 {
pinctrl-names = "default";
pinctrl-0 = <&pinmux_disable_jtag>;
/*
* GPIO 31 is the global reset pin shared by all PHYs across all MDIO
* buses. It is intentionally not declared as reset-gpios on any bus:
* the MDIO driver / phylink only support a reset GPIO per bus, not on
* the parent controller. Attaching it to a single bus would still reset
* the PHYs on the other buses as a side effect, leaving their software
* state out of sync with the hardware and likely breaking them.
*/
phy_reset_hog {
gpio-hog;
gpios = <31 GPIO_ACTIVE_LOW>;
output-low;
line-name = "phy-reset";
};
sfp_enable_hog {
gpio-hog;
gpios = <6 GPIO_ACTIVE_LOW>,
<7 GPIO_ACTIVE_LOW>;
output-high;
line-name = "sfp-enable";
};
};
&i2c_mst1 {
status = "okay";
i2c0: i2c@0 {
reg = <0>;
};
i2c1: i2c@1 {
reg = <1>;
};
i2c2: i2c@2 {
reg = <2>;
lm96000: lm96000@2e {
compatible = "national,lm85";
reg = <0x2e>;
};
};
};
&mdio_bus0 {
/* AQR813 */
PHY_C45(0, 8)
PHY_C45(8, 9)
PHY_C45(16, 10)
PHY_C45(24, 11)
PHY_C45(32, 12)
PHY_C45(40, 13)
PHY_C45(48, 14)
PHY_C45(50, 15)
};
&switch0 {
ethernet-ports {
#address-cells = <1>;
#size-cells = <0>;
/* Copper ports behind AQR813 */
SWITCH_PORT_LED(0, 1, 2, 0, usxgmii)
SWITCH_PORT_LED(8, 2, 3, 0, usxgmii)
SWITCH_PORT_LED(16, 3, 4, 0, usxgmii)
SWITCH_PORT_LED(24, 4, 5, 0, usxgmii)
SWITCH_PORT_LED(32, 5, 6, 0, usxgmii)
SWITCH_PORT_LED(40, 6, 7, 0, usxgmii)
SWITCH_PORT_LED(48, 7, 8, 0, usxgmii)
SWITCH_PORT_LED(50, 8, 9, 0, usxgmii)
/* CPU port */
port@56 {
ethernet = <&ethernet0>;
reg = <56>;
phy-mode = "internal";
fixed-link {
speed = <1000>;
full-duplex;
};
};
};
};
&port0 { managed = "in-band-status"; };
&port8 { managed = "in-band-status"; };
&port16 { managed = "in-band-status"; };
&port24 { managed = "in-band-status"; };
&port32 { managed = "in-band-status"; };
&port40 { managed = "in-band-status"; };
&port48 { managed = "in-band-status"; };
&port50 { managed = "in-band-status"; };
&serdes6 {
rx-polarity = <PHY_POL_INVERT>;
tx-polarity = <PHY_POL_INVERT>;
};
&serdes7 {
rx-polarity = <PHY_POL_INVERT>;
tx-polarity = <PHY_POL_INVERT>;
};
&serdes8 {
rx-polarity = <PHY_POL_INVERT>;
tx-polarity = <PHY_POL_INVERT>;
};
&serdes9 {
rx-polarity = <PHY_POL_INVERT>;
tx-polarity = <PHY_POL_INVERT>;
};
&serdes12 { tx-polarity = <PHY_POL_INVERT>; };
&serdes13 { tx-polarity = <PHY_POL_INVERT>; };
@@ -32,7 +32,7 @@
key-restore {
label = "restore";
gpios = <&gpio0 28 GPIO_ACTIVE_LOW>;
linux,code = <KEY_RESTART>;
linux,code = <BTN_0>;
};
};
@@ -52,6 +52,56 @@
function = LED_FUNCTION_INDICATOR;
gpios = <&gpio0 30 GPIO_ACTIVE_HIGH>;
};
led_pwr_green: led-2 {
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_POWER;
gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>;
default-state = "on";
};
led_pwr_red: led-3 {
color = <LED_COLOR_ID_RED>;
function = LED_FUNCTION_POWER;
gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
};
led_cloud_green: led-4 {
color = <LED_COLOR_ID_GREEN>;
function = "cloud";
gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
};
led_cloud_red: led-5 {
color = <LED_COLOR_ID_RED>;
function = "cloud";
gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
};
led_locator: led-6 {
color = <LED_COLOR_ID_BLUE>;
function = "locator";
gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
};
};
led_set: led_set@0 {
compatible = "realtek,rtl9300-leds";
active-low;
/* Blue | Green | Red */
led_set0 = <(RTL93XX_LED_SET_10G | RTL93XX_LED_SET_5G | RTL93XX_LED_SET_2P5G |
RTL93XX_LED_SET_LINK | RTL93XX_LED_SET_ACT)
(RTL93XX_LED_SET_2P5G | RTL93XX_LED_SET_1G | RTL93XX_LED_SET_100M |
RTL93XX_LED_SET_LINK | RTL93XX_LED_SET_ACT)
(RTL93XX_LED_SET_5G | RTL93XX_LED_SET_100M | RTL93XX_LED_SET_LINK |
RTL93XX_LED_SET_ACT)>;
};
fan0: gpio-fan {
compatible = "gpio-fan";
gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>;
gpio-fan,speed-map =
<3600 0>,
<9000 1>;
#cooling-cells = <2>;
};
};
@@ -144,7 +144,7 @@ struct rtl838x_rx_q {
struct rteth_ctrl {
struct regmap *map;
struct net_device *netdev;
struct net_device *dev;
struct platform_device *pdev;
void *membase;
spinlock_t lock;
@@ -307,7 +307,7 @@ static bool rteth_93xx_decode_tag(struct rteth_packet *h, struct dsa_tag *t)
struct fdb_update_work {
struct work_struct work;
struct net_device *ndev;
struct net_device *dev;
u64 macs[NOTIFY_EVENTS + 1];
};
@@ -328,7 +328,7 @@ static void rtl838x_fdb_sync(struct work_struct *work)
info.vid = 0;
info.offloaded = 1;
pr_debug("FDB entry %d: %llx, action %d\n", i, uw->macs[0], action);
call_switchdev_notifiers(action, uw->ndev, &info.info, NULL);
call_switchdev_notifiers(action, uw->dev, &info.info, NULL);
}
kfree(work);
}
@@ -357,7 +357,7 @@ static void rtl839x_l2_notification_handler(struct rteth_ctrl *ctrl)
mac = event->mac;
if (event->type)
mac |= 1ULL << 63;
w->ndev = ctrl->netdev;
w->dev = ctrl->dev;
w->macs[i] = mac;
}
@@ -373,14 +373,14 @@ static void rtl839x_l2_notification_handler(struct rteth_ctrl *ctrl)
static irqreturn_t rteth_net_irq(int irq, void *dev_id)
{
struct net_device *ndev = dev_id;
struct rteth_ctrl *ctrl = netdev_priv(ndev);
struct net_device *dev = dev_id;
struct rteth_ctrl *ctrl = netdev_priv(dev);
unsigned long ring, rings;
bool l2;
rteth_confirm_and_disable_irqs(ctrl, &rings, &l2);
for_each_set_bit(ring, &rings, RTETH_RX_RINGS) {
netdev_dbg(ndev, "schedule rx ring %lu\n", ring);
netdev_dbg(dev, "schedule rx ring %lu\n", ring);
napi_schedule(&ctrl->rx_qs[ring].napi);
}
@@ -698,10 +698,10 @@ static void rteth_931x_hw_init(struct rteth_ctrl *ctrl)
regmap_set_bits(ctrl->map, RTL931X_PS_SOC_CTRL, BIT(1));
}
static int rteth_open(struct net_device *ndev)
static int rteth_open(struct net_device *dev)
{
unsigned long flags;
struct rteth_ctrl *ctrl = netdev_priv(ndev);
struct rteth_ctrl *ctrl = netdev_priv(dev);
pr_debug("%s called: RX rings %d(length %d), TX rings %d(length %d)\n",
__func__, RTETH_RX_RINGS, RTETH_RX_RING_SIZE, RTETH_TX_RINGS, RTETH_TX_RING_SIZE);
@@ -721,7 +721,7 @@ static int rteth_open(struct net_device *ndev)
ctrl->r->hw_init(ctrl);
ctrl->r->hw_en_rxtx(ctrl);
netif_tx_start_all_queues(ndev);
netif_tx_start_all_queues(dev);
spin_unlock_irqrestore(&ctrl->lock, flags);
return 0;
@@ -800,9 +800,9 @@ static void rteth_hw_stop(struct rteth_ctrl *ctrl)
mdelay(200);
}
static int rteth_stop(struct net_device *ndev)
static int rteth_stop(struct net_device *dev)
{
struct rteth_ctrl *ctrl = netdev_priv(ndev);
struct rteth_ctrl *ctrl = netdev_priv(dev);
pr_info("in %s\n", __func__);
@@ -812,51 +812,51 @@ static int rteth_stop(struct net_device *ndev)
for (int i = 0; i < RTETH_RX_RINGS; i++)
napi_disable(&ctrl->rx_qs[i].napi);
netif_tx_stop_all_queues(ndev);
netif_tx_stop_all_queues(dev);
return 0;
}
static void rteth_838x_set_rx_mode(struct net_device *ndev)
static void rteth_838x_set_rx_mode(struct net_device *dev)
{
struct rteth_ctrl *ctrl = netdev_priv(ndev);
struct rteth_ctrl *ctrl = netdev_priv(dev);
/* Flood all classes of RMA addresses (01-80-C2-00-00-{01..2F})
* CTRL_0_FULL = GENMASK(21, 0) = 0x3FFFFF
*/
if (!(ndev->flags & (IFF_PROMISC | IFF_ALLMULTI))) {
if (!(dev->flags & (IFF_PROMISC | IFF_ALLMULTI))) {
regmap_write(ctrl->map, RTETH_838X_RMA_CTRL_0, 0);
regmap_write(ctrl->map, RTETH_838X_RMA_CTRL_1, 0);
}
if (ndev->flags & IFF_ALLMULTI)
if (dev->flags & IFF_ALLMULTI)
regmap_write(ctrl->map, RTETH_838X_RMA_CTRL_0, GENMASK(21, 0));
if (ndev->flags & IFF_PROMISC) {
if (dev->flags & IFF_PROMISC) {
regmap_write(ctrl->map, RTETH_838X_RMA_CTRL_0, GENMASK(21, 0));
regmap_write(ctrl->map, RTETH_838X_RMA_CTRL_1, GENMASK(14, 0));
}
}
static void rteth_839x_set_rx_mode(struct net_device *ndev)
static void rteth_839x_set_rx_mode(struct net_device *dev)
{
struct rteth_ctrl *ctrl = netdev_priv(ndev);
struct rteth_ctrl *ctrl = netdev_priv(dev);
/* Flood all classes of RMA addresses (01-80-C2-00-00-{01..2F})
* CTRL_0_FULL = GENMASK(31, 2) = 0xFFFFFFFC
* Lower two bits are reserved, corresponding to RMA 01-80-C2-00-00-00
* CTRL_1_FULL = CTRL_2_FULL = GENMASK(31, 0)
*/
if (!(ndev->flags & (IFF_PROMISC | IFF_ALLMULTI))) {
if (!(dev->flags & (IFF_PROMISC | IFF_ALLMULTI))) {
regmap_write(ctrl->map, RTETH_839X_RMA_CTRL_0, 0);
regmap_write(ctrl->map, RTETH_839X_RMA_CTRL_1, 0);
regmap_write(ctrl->map, RTETH_839X_RMA_CTRL_2, 0);
regmap_write(ctrl->map, RTETH_839X_RMA_CTRL_3, 0);
}
if (ndev->flags & IFF_ALLMULTI) {
if (dev->flags & IFF_ALLMULTI) {
regmap_write(ctrl->map, RTETH_839X_RMA_CTRL_0, GENMASK(31, 2));
regmap_write(ctrl->map, RTETH_839X_RMA_CTRL_1, GENMASK(31, 0));
regmap_write(ctrl->map, RTETH_839X_RMA_CTRL_2, GENMASK(31, 0));
}
if (ndev->flags & IFF_PROMISC) {
if (dev->flags & IFF_PROMISC) {
regmap_write(ctrl->map, RTETH_839X_RMA_CTRL_0, GENMASK(31, 2));
regmap_write(ctrl->map, RTETH_839X_RMA_CTRL_1, GENMASK(31, 0));
regmap_write(ctrl->map, RTETH_839X_RMA_CTRL_2, GENMASK(31, 0));
@@ -864,16 +864,16 @@ static void rteth_839x_set_rx_mode(struct net_device *ndev)
}
}
static void rteth_930x_set_rx_mode(struct net_device *ndev)
static void rteth_930x_set_rx_mode(struct net_device *dev)
{
struct rteth_ctrl *ctrl = netdev_priv(ndev);
struct rteth_ctrl *ctrl = netdev_priv(dev);
/* Flood all classes of RMA addresses (01-80-C2-00-00-{01..2F})
* CTRL_0_FULL = GENMASK(31, 2) = 0xFFFFFFFC
* Lower two bits are reserved, corresponding to RMA 01-80-C2-00-00-00
* CTRL_1_FULL = CTRL_2_FULL = GENMASK(31, 0)
*/
if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC)) {
if (dev->flags & (IFF_ALLMULTI | IFF_PROMISC)) {
regmap_write(ctrl->map, RTETH_930X_RMA_CTRL_0, GENMASK(31, 2));
regmap_write(ctrl->map, RTETH_930X_RMA_CTRL_1, GENMASK(31, 0));
regmap_write(ctrl->map, RTETH_930X_RMA_CTRL_2, GENMASK(31, 0));
@@ -884,16 +884,16 @@ static void rteth_930x_set_rx_mode(struct net_device *ndev)
}
}
static void rteth_931x_set_rx_mode(struct net_device *ndev)
static void rteth_931x_set_rx_mode(struct net_device *dev)
{
struct rteth_ctrl *ctrl = netdev_priv(ndev);
struct rteth_ctrl *ctrl = netdev_priv(dev);
/* Flood all classes of RMA addresses (01-80-C2-00-00-{01..2F})
* CTRL_0_FULL = GENMASK(31, 2) = 0xFFFFFFFC
* Lower two bits are reserved, corresponding to RMA 01-80-C2-00-00-00.
* CTRL_1_FULL = CTRL_2_FULL = GENMASK(31, 0)
*/
if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC)) {
if (dev->flags & (IFF_ALLMULTI | IFF_PROMISC)) {
regmap_write(ctrl->map, RTETH_931X_RMA_CTRL_0, GENMASK(31, 2));
regmap_write(ctrl->map, RTETH_931X_RMA_CTRL_1, GENMASK(31, 0));
regmap_write(ctrl->map, RTETH_931X_RMA_CTRL_2, GENMASK(31, 0));
@@ -904,31 +904,30 @@ static void rteth_931x_set_rx_mode(struct net_device *ndev)
}
}
static void rteth_tx_timeout(struct net_device *ndev, unsigned int txqueue)
static void rteth_tx_timeout(struct net_device *dev, unsigned int txqueue)
{
unsigned long flags;
struct rteth_ctrl *ctrl = netdev_priv(ndev);
struct rteth_ctrl *ctrl = netdev_priv(dev);
pr_warn("%s\n", __func__);
spin_lock_irqsave(&ctrl->lock, flags);
rteth_hw_stop(ctrl);
rteth_hw_ring_setup(ctrl);
ctrl->r->hw_en_rxtx(ctrl);
netif_trans_update(ndev);
netif_start_queue(ndev);
netif_trans_update(dev);
netif_start_queue(dev);
spin_unlock_irqrestore(&ctrl->lock, flags);
}
static int rteth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
static int rteth_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct rteth_ctrl *ctrl = netdev_priv(netdev);
struct rteth_ctrl *ctrl = netdev_priv(dev);
int val, slot, len = skb->len, dest_port = -1;
int ring = skb_get_queue_mapping(skb);
struct device *dev = &ctrl->pdev->dev;
struct rteth_packet *packet;
dma_addr_t packet_dma;
if (netdev_uses_dsa(netdev) &&
if (netdev_uses_dsa(dev) &&
skb->data[len - 4] == 0x80 &&
skb->data[len - 3] < ctrl->r->cpu_port &&
skb->data[len - 2] == 0x10 &&
@@ -942,8 +941,8 @@ static int rteth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
len = max(ETH_ZLEN + ETH_FCS_LEN, len);
if (unlikely(skb_put_padto(skb, len))) {
netdev->stats.tx_errors++;
dev_warn(dev, "skb pad failed\n");
dev->stats.tx_errors++;
netdev_warn(dev, "skb pad failed\n");
return NETDEV_TX_OK;
}
@@ -953,24 +952,24 @@ static int rteth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
packet_dma = ctrl->tx_data[ring].ring[slot];
if (unlikely(packet_dma & RTETH_OWN_CPU)) {
netif_stop_subqueue(netdev, ring);
netif_stop_subqueue(dev, ring);
if (net_ratelimit())
dev_warn(dev, "tx ring %d busy, waiting for slot %d\n", ring, slot);
netdev_warn(dev, "tx ring %d busy, waiting for slot %d\n", ring, slot);
return NETDEV_TX_BUSY;
}
if (likely(packet->skb)) {
/* cleanup old data of this slot */
dma_unmap_single(dev, packet->dma, packet->skb->len, DMA_TO_DEVICE);
dma_unmap_single(&ctrl->pdev->dev, packet->dma, packet->skb->len, DMA_TO_DEVICE);
dev_kfree_skb_any(packet->skb);
}
packet->dma = dma_map_single(dev, skb->data, len, DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(dev, packet->dma))) {
packet->dma = dma_map_single(&ctrl->pdev->dev, skb->data, len, DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(&ctrl->pdev->dev, packet->dma))) {
dev_kfree_skb_any(skb);
packet->skb = NULL;
netdev->stats.tx_errors++;
dev->stats.tx_errors++;
return NETDEV_TX_OK;
}
@@ -995,12 +994,12 @@ static int rteth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
*/
if (regmap_read_poll_timeout(ctrl->map, ctrl->r->dma_if_ctrl,
val, val & ctrl->r->tx_rx_enable, 0, 5000))
dev_warn_once(dev, "DMA interface ctrl register read failed\n");
netdev_warn_once(dev, "DMA interface ctrl register read failed\n");
regmap_write(ctrl->map, ctrl->r->dma_if_ctrl, val | RTETH_TX_TRIGGER(ctrl, ring));
netdev->stats.tx_packets++;
netdev->stats.tx_bytes += len;
dev->stats.tx_packets++;
dev->stats.tx_bytes += len;
spin_unlock(&ctrl->tx_lock);
@@ -1087,7 +1086,7 @@ static int rteth_poll_rx(struct napi_struct *napi, int budget)
struct rteth_ctrl *ctrl = rx_q->ctrl;
int work_done, ring = rx_q->id;
work_done = rteth_hw_receive(ctrl->netdev, ring, budget);
work_done = rteth_hw_receive(ctrl->dev, ring, budget);
if (work_done < budget && napi_complete_done(napi, work_done))
rteth_reenable_irq(ctrl, ring);
@@ -1192,7 +1191,6 @@ static int rteth_930x_init_mac(struct rteth_ctrl *ctrl)
static int rteth_931x_init_mac(struct rteth_ctrl *ctrl)
{
struct device *dev = &ctrl->pdev->dev;
unsigned int val;
int ret;
@@ -1201,61 +1199,59 @@ static int rteth_931x_init_mac(struct rteth_ctrl *ctrl)
ret = regmap_read_poll_timeout(ctrl->map, RTL931X_MEM_ENCAP_INIT,
val, !(val & 1), 0, 100000);
if (ret)
dev_err(dev, "ENCAP init timeout\n");
return ret;
/* Initialize Management Information Base memory and wait until finished */
regmap_write(ctrl->map, RTL931X_MEM_MIB_INIT, 0x1);
ret = regmap_read_poll_timeout(ctrl->map, RTL931X_MEM_MIB_INIT,
val, !(val & 1), 0, 100000);
if (ret)
dev_err(dev, "MIB init timeout\n");
return ret;
/* Initialize ACL (PIE) memory and wait until finished */
regmap_write(ctrl->map, RTL931X_MEM_ACL_INIT, 0x1);
ret = regmap_read_poll_timeout(ctrl->map, RTL931X_MEM_ACL_INIT,
val, !(val & 1), 0, 100000);
if (ret)
dev_err(dev, "ACL init timeout\n");
return ret;
/* Initialize ALE memory and wait until finished */
regmap_write(ctrl->map, RTL931X_MEM_ALE_INIT_0, 0xffffffff);
ret = regmap_read_poll_timeout(ctrl->map, RTL931X_MEM_ALE_INIT_0,
val, !val, 0, 100000);
if (ret)
dev_err(dev, "ALE_0 init timeout\n");
return ret;
regmap_write(ctrl->map, RTL931X_MEM_ALE_INIT_1, 0x7f);
ret = regmap_read_poll_timeout(ctrl->map, RTL931X_MEM_ALE_INIT_1,
val, !val, 0, 100000);
if (ret)
dev_err(dev, "ALE_1 init timeout\n");
return ret;
regmap_write(ctrl->map, RTL931X_MEM_ALE_INIT_2, 0x7ff);
ret = regmap_read_poll_timeout(ctrl->map, RTL931X_MEM_ALE_INIT_2,
val, !val, 0, 100000);
if (ret)
dev_err(dev, "ALE_2 init timeout\n");
return ret;
/* Enable ESD auto recovery */
regmap_write(ctrl->map, RTL931X_MDX_CTRL_RSVD, 0x1);
return 0;
return regmap_write(ctrl->map, RTL931X_MDX_CTRL_RSVD, 0x1);
}
static int rteth_get_link_ksettings(struct net_device *ndev,
static int rteth_get_link_ksettings(struct net_device *dev,
struct ethtool_link_ksettings *cmd)
{
struct rteth_ctrl *ctrl = netdev_priv(ndev);
struct rteth_ctrl *ctrl = netdev_priv(dev);
pr_debug("%s called\n", __func__);
return phylink_ethtool_ksettings_get(ctrl->phylink, cmd);
}
static int rteth_set_link_ksettings(struct net_device *ndev,
static int rteth_set_link_ksettings(struct net_device *dev,
const struct ethtool_link_ksettings *cmd)
{
struct rteth_ctrl *ctrl = netdev_priv(ndev);
struct rteth_ctrl *ctrl = netdev_priv(dev);
pr_debug("%s called\n", __func__);
@@ -1516,8 +1512,12 @@ static int rteth_probe(struct platform_device *pdev)
if (!dev)
return -ENOMEM;
SET_NETDEV_DEV(dev, &pdev->dev);
ctrl = netdev_priv(dev);
ctrl->pdev = pdev;
ctrl->dev = dev;
ctrl->r = cfg;
ctrl->map = syscon_node_to_regmap(dn->parent);
if (IS_ERR(ctrl->map))
return PTR_ERR(ctrl->map);
@@ -1552,17 +1552,16 @@ static int rteth_probe(struct platform_device *pdev)
/* Obtain device IRQ number */
dev->irq = platform_get_irq(pdev, 0);
if (dev->irq < 0)
return -ENODEV;
return dev_err_probe(&pdev->dev, dev->irq, "could not determine interrupt\n");
rteth_disable_all_irqs(ctrl);
err = devm_request_irq(&pdev->dev, dev->irq, rteth_net_irq, IRQF_SHARED, dev->name, dev);
if (err) {
dev_err(&pdev->dev, "%s: could not acquire interrupt: %d\n",
__func__, err);
return err;
}
if (err)
return dev_err_probe(&pdev->dev, err, "could not acquire interrupt\n");
ctrl->r->init_mac(ctrl);
err = ctrl->r->init_mac(ctrl);
if (err)
return dev_err_probe(&pdev->dev, err, "failed to initialize MAC\n");
/* Try to get mac address in the following order:
* 1) from device tree data
@@ -1592,18 +1591,15 @@ static int rteth_probe(struct platform_device *pdev)
if (!is_valid_ether_addr(dev->dev_addr)) {
struct sockaddr sa = { AF_UNSPEC };
netdev_warn(dev, "Invalid MAC address, using random\n");
dev_warn(&pdev->dev, "Invalid MAC address, using random\n");
eth_hw_addr_random(dev);
memcpy(sa.sa_data, dev->dev_addr, ETH_ALEN);
if (rteth_set_mac_address(dev, &sa))
netdev_warn(dev, "Failed to set MAC address.\n");
dev_warn(&pdev->dev, "Failed to set MAC address.\n");
}
pr_info("Using MAC %pM\n", dev->dev_addr);
dev_info(&pdev->dev, "Using MAC %pM\n", dev->dev_addr);
strscpy(dev->name, "eth%d", sizeof(dev->name));
ctrl->pdev = pdev;
ctrl->netdev = dev;
for (int i = 0; i < RTETH_RX_RINGS; i++) {
ctrl->rx_qs[i].id = i;
ctrl->rx_qs[i].ctrl = ctrl;
@@ -1614,10 +1610,8 @@ static int rteth_probe(struct platform_device *pdev)
phy_mode = PHY_INTERFACE_MODE_NA;
err = of_get_phy_mode(dn, &phy_mode);
if (err < 0) {
dev_err(&pdev->dev, "incorrect phy-mode\n");
return -EINVAL;
}
if (err < 0)
return dev_err_probe(&pdev->dev, err, "incorrect phy-mode\n");
ctrl->phylink_config.dev = &dev->dev;
ctrl->phylink_config.type = PHYLINK_NETDEV;
@@ -1629,7 +1623,8 @@ static int rteth_probe(struct platform_device *pdev)
ctrl->phylink = phylink_create(&ctrl->phylink_config, pdev->dev.fwnode,
phy_mode, &rteth_mac_ops);
if (IS_ERR(ctrl->phylink))
return PTR_ERR(ctrl->phylink);
return dev_err_probe(&pdev->dev, PTR_ERR(ctrl->phylink),
"could not create phylink\n");
err = devm_register_netdev(&pdev->dev, dev);
if (err)
@@ -1,5 +1,58 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* On all Realtek switch platforms the hardware periodically reads the link status of all PHYs.
* The result is automatically written into MAC specific registers that can be consumed by a
* DSA driver. This is to some degree programmable, so that one can tell the hardware to read
* specific C22 registers from specific pages, or C45 registers, to determine the current link
* speed, duplex, flow-control, ...
*
* This happens without any need for the driver to do anything at runtime, completely invisible
* and in a parallel hardware thread, independent of the CPU running Linux. All one needs to do
* is to set it up once. Having the MAC link settings automatically follow the PHY link status
* also happens to be the only way to control MAC port status in a meaningful way, or at least
* it's the only way that is fully understood, as this is what every vendor firmware is doing.
*
* The hardware PHY polling unit doesn't care about bus locking. It just assumes that all paged
* PHY operations are also done via the same hardware unit offering this PHY access abstractions.
*
* Additionally the devices are known to have a so called raw mode. Using the special MAX_PAGE-1
* with the MDIO controller found in Realtek SoCs allows to access the PHY in raw mode, i.e.
* bypassing the cache and paging engine of the MDIO controller. E.g. for RTL838x this is 4095.
*
* On the other hand Realtek PHYs usually make use of select register 0x1f to switch pages. There
* is no problem to issue separate page and access bus calls to the PHYs when they are not
* attached to an Realtek SoC. The design should be to keep the PHY code bus independent.
*
* To bring all this together one needs a tricky bus design that intercepts select page calls but
* lets raw page accesses through. And especially knows how to handle raw accesses to the select
* register.
*
* While C45 clause handling is pretty standard the legacy functions basically track the accesses
* and the state of the bus with the rtmd_port attributes of the control structure. The page
* selection works as follows:
*
* phy_write(phydev, RTMD_PAGE_SELECT, 12) : store internal page 12 in driver
* phy_write(phydev, 7, 33) : write page=12, reg=7, val=33
*
* Any Realtek PHY that is connected to this bus must simply provide the standard page functions:
*
* define RTL821X_PAGE_SELECT 0x1f
*
* static int rtl821x_read_page(struct phy_device *phydev)
* {
* return __phy_read(phydev, RTL821X_PAGE_SELECT);
* }
*
* static int rtl821x_write_page(struct phy_device *phydev, int page)
* {
* return __phy_write(phydev, RTL821X_PAGE_SELECT, page);
* }
*
* In case there are non Realtek PHYs attached to the bus the logic might need to be changed.
* For now it should be sufficient.
*/
#include <linux/fwnode.h>
#include <linux/fwnode_mdio.h>
#include <linux/mfd/syscon.h>
@@ -150,68 +203,6 @@
#define for_each_sds_port(ctrl, pn) \
for_each_set_bit(pn, (ctrl)->sds_ports, RTMD_MAX_PORTS)
/*
* On all Realtek switch platforms the hardware periodically reads the link status of all
* PHYs. This is to some degree programmable, so that one can tell the hardware to read
* specific C22 registers from specific pages, or C45 registers, to determine the current
* link speed, duplex, flow-control, ...
*
* This happens without any need for the driver to do anything at runtime, completely
* invisible and in a parallel hardware thread, independent of the CPU running Linux.
* All one needs to do is to set it up once. Having the MAC link settings automatically
* follow the PHY link status also happens to be the only way to control MAC port status
* in a meaningful way, or at least it's the only way we fully understand, as this is
* what every vendor firmware is doing.
*
* The hardware PHY polling unit doesn't care about bus locking, it just assumes that all
* paged PHY operations are also done via the same hardware unit offering this PHY access
* abstractions.
*
* Additionally at least the RTL838x and RTL839x devices are known to have a so called
* raw mode. Using the special MAX_PAGE-1 with the MDIO controller found in Realtek
* SoCs allows to access the PHY in raw mode, ie. bypassing the cache and paging engine
* of the MDIO controller. E.g. for RTL838x this is 0xfff.
*
* On the other hand Realtek PHYs usually make use of select register 0x1f to switch
* pages. There is no problem to issue separate page and access bus calls to the PHYs
* when they are not attached to an Realtek SoC. The paradigm should be to keep the PHY
* implementation bus independent.
*
* To bring all this together we need a tricky bus design that intercepts select page
* calls but lets raw page accesses through. And especially knows how to handle raw
* accesses to the select register. Additionally we need the possibility to write to
* all 8 ports of the PHY individually.
*
* While the C45 clause stuff is pretty standard the legacy functions basically track
* the accesses and the state of the bus with the rtmd_port attributes of the control
* structure. The page selection works as follows:
*
* phy_write(phydev, RTMD_PAGE_SELECT, 12) : store internal page 12 in driver
* phy_write(phydev, 7, 33) : write page=12, reg=7, val=33
*
* or simply
*
* phy_write_paged(phydev, 12, 7, 33) : write page=12, reg=7, val=33
*
* Any Realtek PHY that will be connected to this bus must simply provide the standard
* page functions:
*
* define RTL821X_PAGE_SELECT 0x1f
*
* static int rtl821x_read_page(struct phy_device *phydev)
* {
* return __phy_read(phydev, RTL821X_PAGE_SELECT);
* }
*
* static int rtl821x_write_page(struct phy_device *phydev, int page)
* {
* return __phy_write(phydev, RTL821X_PAGE_SELECT, page);
* }
*
* In case there are non Realtek PHYs attached to the bus the logic might need to be
* reimplemented. For now it should be sufficient.
*/
struct rtmd_port {
int page;
bool raw;
@@ -225,7 +216,7 @@ struct rtmd_bus {
};
struct rtmd_ctrl {
struct mutex lock;
struct mutex lock; /* protect HW access */
struct regmap *map;
const struct rtmd_config *cfg;
struct rtmd_port port[RTMD_MAX_PORTS];
@@ -278,7 +269,7 @@ struct rtmd_phy_info {
unsigned int poll_lpa_1000;
};
static inline struct rtmd_ctrl *rtmd_ctrl_from_bus(struct mii_bus *bus)
static struct rtmd_ctrl *rtmd_bus_to_ctrl(struct mii_bus *bus)
{
return ((struct rtmd_chan *)bus->priv)->ctrl;
}
@@ -291,9 +282,9 @@ static int rtmd_phy_to_port(struct mii_bus *bus, int phy)
}
static int rtmd_run_cmd(struct mii_bus *bus, u32 cmd,
struct rtmd_command_data *cmd_data, u32 *val)
struct rtmd_command_data *cmd_data, u32 *val)
{
struct rtmd_ctrl *ctrl = rtmd_ctrl_from_bus(bus);
struct rtmd_ctrl *ctrl = rtmd_bus_to_ctrl(bus);
u32 cmdstate;
int ret;
@@ -531,15 +522,16 @@ static int rtmd_931x_write_c45(struct mii_bus *bus, u32 pn, u32 devnum, u32 regn
static int rtmd_read_c45(struct mii_bus *bus, int phy, int devnum, int regnum)
{
struct rtmd_ctrl *ctrl = rtmd_ctrl_from_bus(bus);
struct rtmd_ctrl *ctrl = rtmd_bus_to_ctrl(bus);
int ret, pn, val = 0;
pn = rtmd_phy_to_port(bus, phy);
if (pn < 0)
return -ENOENT;
guard(mutex)(&ctrl->lock);
ret = (*ctrl->cfg->read_c45)(bus, pn, devnum, regnum, &val);
scoped_guard(mutex, &ctrl->lock)
ret = (*ctrl->cfg->read_c45)(bus, pn, devnum, regnum, &val);
dev_dbg(&bus->dev, "rd_MMD(phy=0x%02x, dev=0x%04x, reg=0x%04x) = 0x%04x, ret = %d\n",
phy, devnum, regnum, val, ret);
@@ -548,38 +540,40 @@ static int rtmd_read_c45(struct mii_bus *bus, int phy, int devnum, int regnum)
static int rtmd_read_c22(struct mii_bus *bus, int phy, int regnum)
{
struct rtmd_ctrl *ctrl = rtmd_ctrl_from_bus(bus);
int ret, pn, val = 0;
struct rtmd_ctrl *ctrl = rtmd_bus_to_ctrl(bus);
int ret, pn, page, val = 0;
pn = rtmd_phy_to_port(bus, phy);
if (pn < 0)
return -ENOENT;
guard(mutex)(&ctrl->lock);
if (regnum == RTMD_PAGE_SELECT &&
ctrl->port[pn].page != RTMD_RAW_PAGE(ctrl->cfg->num_pages))
return ctrl->port[pn].page;
scoped_guard(mutex, &ctrl->lock) {
page = ctrl->port[pn].page;
if (regnum == RTMD_PAGE_SELECT &&
page != RTMD_RAW_PAGE(ctrl->cfg->num_pages))
return page;
ctrl->port[pn].raw = (ctrl->port[pn].page == RTMD_RAW_PAGE(ctrl->cfg->num_pages));
ctrl->port[pn].raw = (page == RTMD_RAW_PAGE(ctrl->cfg->num_pages));
ret = (*ctrl->cfg->read_c22)(bus, pn, page, regnum, &val);
}
ret = (*ctrl->cfg->read_c22)(bus, pn, ctrl->port[pn].page, regnum, &val);
dev_dbg(&bus->dev, "rd_PHY(phy=0x%02x, pag=0x%04x, reg=0x%04x) = 0x%04x, ret = %d\n",
phy, ctrl->port[pn].page, regnum, val, ret);
phy, page, regnum, val, ret);
return ret ? ret : val;
}
static int rtmd_write_c45(struct mii_bus *bus, int phy, int devnum, int regnum, u16 val)
{
struct rtmd_ctrl *ctrl = rtmd_ctrl_from_bus(bus);
struct rtmd_ctrl *ctrl = rtmd_bus_to_ctrl(bus);
int ret, pn;
pn = rtmd_phy_to_port(bus, phy);
if (pn < 0)
return -ENOENT;
guard(mutex)(&ctrl->lock);
ret = (*ctrl->cfg->write_c45)(bus, pn, devnum, regnum, val);
scoped_guard(mutex, &ctrl->lock)
ret = (*ctrl->cfg->write_c45)(bus, pn, devnum, regnum, val);
dev_dbg(&bus->dev, "wr_MMD(phy=0x%02x, dev=0x%04x, reg=0x%04x, val=0x%04x), ret = %d\n",
phy, devnum, regnum, val, ret);
@@ -588,33 +582,37 @@ static int rtmd_write_c45(struct mii_bus *bus, int phy, int devnum, int regnum,
static int rtmd_write_c22(struct mii_bus *bus, int phy, int regnum, u16 val)
{
struct rtmd_ctrl *ctrl = rtmd_ctrl_from_bus(bus);
int ret, page, pn;
struct rtmd_ctrl *ctrl = rtmd_bus_to_ctrl(bus);
bool do_write = false;
int ret = 0, page, pn;
pn = rtmd_phy_to_port(bus, phy);
if (pn < 0)
return -ENOENT;
guard(mutex)(&ctrl->lock);
page = ctrl->port[pn].page;
scoped_guard(mutex, &ctrl->lock) {
page = ctrl->port[pn].page;
if (regnum == RTMD_PAGE_SELECT)
ctrl->port[pn].page = val;
if (regnum == RTMD_PAGE_SELECT)
ctrl->port[pn].page = val;
do_write = !ctrl->port[pn].raw &&
(regnum != RTMD_PAGE_SELECT ||
page == RTMD_RAW_PAGE(ctrl->cfg->num_pages));
if (!ctrl->port[pn].raw &&
(regnum != RTMD_PAGE_SELECT || page == RTMD_RAW_PAGE(ctrl->cfg->num_pages))) {
ctrl->port[pn].raw = (page == RTMD_RAW_PAGE(ctrl->cfg->num_pages));
if (do_write) {
ctrl->port[pn].raw = (page == RTMD_RAW_PAGE(ctrl->cfg->num_pages));
ret = (*ctrl->cfg->write_c22)(bus, pn, page, regnum, val);
} else {
ctrl->port[pn].raw = false;
}
}
ret = (*ctrl->cfg->write_c22)(bus, pn, page, regnum, val);
if (do_write)
dev_dbg(&bus->dev,
"wr_PHY(phy=0x%02x, pag=0x%04x, reg=0x%04x, val=0x%04x), ret = %d\n",
phy, page, regnum, val, ret);
return ret;
}
ctrl->port[pn].raw = false;
return 0;
return ret;
}
static int rtmd_poll_port(struct rtmd_ctrl *ctrl, int pn, bool active)
@@ -992,7 +990,8 @@ static int rtmd_map_ports(struct device *dev)
if (test_bit(pn, ctrl->phy_ports) ||
test_bit(pn, ctrl->sds_ports))
return dev_err_probe(dev, -EINVAL, "%pfwP duplicate port number\n", fw_port);
return dev_err_probe(dev, -EINVAL, "%pfwP duplicate port number\n",
fw_port);
struct fwnode_handle *fw_phy __free(fwnode_handle) =
fwnode_find_reference(fw_port, "phy-handle", 0);
@@ -1028,7 +1027,7 @@ static int rtmd_map_ports(struct device *dev)
}
static int rtmd_probe_one(struct device *dev, struct rtmd_ctrl *ctrl,
struct fwnode_handle *fw_bus)
struct fwnode_handle *fw_bus)
{
struct rtmd_chan *chan;
struct mii_bus *bus;
@@ -1224,22 +1223,10 @@ static const struct rtmd_config rtmd_931x_cfg = {
};
static const struct of_device_id rtmd_ids[] = {
{
.compatible = "realtek,rtl8380-mdio",
.data = &rtmd_838x_cfg,
},
{
.compatible = "realtek,rtl8392-mdio",
.data = &rtmd_839x_cfg,
},
{
.compatible = "realtek,rtl9301-mdio",
.data = &rtmd_930x_cfg,
},
{
.compatible = "realtek,rtl9311-mdio",
.data = &rtmd_931x_cfg,
},
{ .compatible = "realtek,rtl8380-mdio", .data = &rtmd_838x_cfg, },
{ .compatible = "realtek,rtl8392-mdio", .data = &rtmd_839x_cfg, },
{ .compatible = "realtek,rtl9301-mdio", .data = &rtmd_930x_cfg, },
{ .compatible = "realtek,rtl9311-mdio", .data = &rtmd_931x_cfg, },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, rtmd_ids);
@@ -1256,4 +1243,4 @@ module_platform_driver(rtmd_driver);
MODULE_AUTHOR("Markus Stockhausen <markus.stockhausen@gmx.de>");
MODULE_DESCRIPTION("Realtek Otto MDIO driver");
MODULE_LICENSE("GPL v2");
MODULE_LICENSE("GPL");
@@ -2,7 +2,7 @@
/*
* Realtek thermal sensor driver
*
* Copyright (C) 2025 Bjørn Mork <bjorn@mork.no>>
* Copyright (C) 2025 Bjørn Mork <bjorn@mork.no>
*/
#include <linux/bitfield.h>
@@ -57,12 +57,17 @@
struct realtek_thermal_priv {
struct regmap *regmap;
bool enabled;
};
static void rtl8380_thermal_init(struct realtek_thermal_priv *priv)
struct realtek_thermal_chip {
const struct thermal_zone_device_ops *ops;
int (*init)(struct regmap *regmap);
};
static int rtl8380_thermal_init(struct regmap *regmap)
{
priv->enabled = !regmap_update_bits(priv->regmap, RTL8380_THERMAL_METER_CTRL0, RTL8380_TM_ENABLE, RTL8380_TM_ENABLE);
return regmap_update_bits(regmap, RTL8380_THERMAL_METER_CTRL0,
RTL8380_TM_ENABLE, RTL8380_TM_ENABLE);
}
static int rtl8380_get_temp(struct thermal_zone_device *tz, int *res)
@@ -73,9 +78,6 @@ static int rtl8380_get_temp(struct thermal_zone_device *tz, int *res)
u32 val;
int ret;
if (!priv->enabled)
rtl8380_thermal_init(priv);
ret = regmap_read(priv->regmap, RTL8380_THERMAL_METER_RESULT, &val);
if (ret)
return ret;
@@ -91,9 +93,15 @@ static const struct thermal_zone_device_ops rtl8380_ops = {
.get_temp = rtl8380_get_temp,
};
static void rtl8390_thermal_init(struct realtek_thermal_priv *priv)
static const struct realtek_thermal_chip rtl8380_chip = {
.ops = &rtl8380_ops,
.init = rtl8380_thermal_init
};
static int rtl8390_thermal_init(struct regmap *regmap)
{
priv->enabled = !regmap_update_bits(priv->regmap, RTL8390_THERMAL_METER0_CTRL0, RTL8390_TM_ENABLE, RTL8390_TM_ENABLE);
return regmap_update_bits(regmap, RTL8390_THERMAL_METER0_CTRL0,
RTL8390_TM_ENABLE, RTL8390_TM_ENABLE);
}
static int rtl8390_get_temp(struct thermal_zone_device *tz, int *res)
@@ -104,8 +112,6 @@ static int rtl8390_get_temp(struct thermal_zone_device *tz, int *res)
u32 val;
int ret;
if (!priv->enabled)
rtl8390_thermal_init(priv);
/* assume sensor0 is the CPU, both sensor0 & sensor1 report same values +/- 1 degree C */
ret = regmap_read(priv->regmap, RTL8390_THERMAL_METER0_RESULT, &val);
if (ret)
@@ -122,11 +128,23 @@ static const struct thermal_zone_device_ops rtl8390_ops = {
.get_temp = rtl8390_get_temp,
};
static void rtl9300_thermal_init(struct realtek_thermal_priv *priv)
static const struct realtek_thermal_chip rtl8390_chip = {
.ops = &rtl8390_ops,
.init = rtl8390_thermal_init
};
static int rtl9300_thermal_init(struct regmap *regmap)
{
int ret;
/* increasing sample delay makes get_temp() succeed more often */
regmap_update_bits(priv->regmap, RTL9300_THERMAL_METER_CTRL1, RTL9300_SAMPLE_DLY_MASK, 0x0800 << RTL9300_SAMPLE_DLY_SHIFT);
priv->enabled = !regmap_update_bits(priv->regmap, RTL9300_THERMAL_METER_CTRL2, RTL9300_TM_ENABLE, RTL9300_TM_ENABLE);
ret = regmap_update_bits(regmap, RTL9300_THERMAL_METER_CTRL1, RTL9300_SAMPLE_DLY_MASK,
FIELD_PREP(RTL9300_SAMPLE_DLY_MASK, 0x0800));
if (ret)
return ret;
return regmap_update_bits(regmap, RTL9300_THERMAL_METER_CTRL2,
RTL9300_TM_ENABLE, RTL9300_TM_ENABLE);
}
static int rtl9300_get_temp(struct thermal_zone_device *tz, int *res)
@@ -137,9 +155,6 @@ static int rtl9300_get_temp(struct thermal_zone_device *tz, int *res)
u32 val;
int ret;
if (!priv->enabled)
rtl9300_thermal_init(priv);
ret = regmap_read(priv->regmap, RTL9300_THERMAL_METER_RESULT0, &val);
if (ret)
return ret;
@@ -154,9 +169,15 @@ static const struct thermal_zone_device_ops rtl9300_ops = {
.get_temp = rtl9300_get_temp,
};
static void rtl9607_thermal_init(struct realtek_thermal_priv *priv)
static const struct realtek_thermal_chip rtl9300_chip = {
.ops = &rtl9300_ops,
.init = rtl9300_thermal_init
};
static int rtl9607_thermal_init(struct regmap *regmap)
{
priv->enabled = !regmap_update_bits(priv->regmap, RTL9607_THERMAL_CTRL_0, RTL9607_REG_PPOW, RTL9607_REG_PPOW);
return regmap_update_bits(regmap, RTL9607_THERMAL_CTRL_0,
RTL9607_REG_PPOW, RTL9607_REG_PPOW);
}
static int rtl9607_get_temp(struct thermal_zone_device *tz, int *res)
@@ -167,9 +188,6 @@ static int rtl9607_get_temp(struct thermal_zone_device *tz, int *res)
u32 val;
int ret;
if (!priv->enabled)
rtl9607_thermal_init(priv);
ret = regmap_read(priv->regmap, RTL9607_THERMAL_STS_0, &val);
if (ret)
return ret;
@@ -188,12 +206,23 @@ static const struct thermal_zone_device_ops rtl9607_ops = {
.get_temp = rtl9607_get_temp,
};
static const struct realtek_thermal_chip rtl9607_chip = {
.ops = &rtl9607_ops,
.init = rtl9607_thermal_init
};
static int realtek_thermal_probe(struct platform_device *pdev)
{
const struct realtek_thermal_chip *chip;
struct realtek_thermal_priv *priv;
struct thermal_zone_device *tzdev;
struct device *dev = &pdev->dev;
struct regmap *regmap;
int ret;
chip = device_get_match_data(dev);
if (!chip)
return -EINVAL;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
@@ -204,7 +233,12 @@ static int realtek_thermal_probe(struct platform_device *pdev)
return PTR_ERR(regmap);
priv->regmap = regmap;
tzdev = devm_thermal_of_zone_register(dev, 0, priv, device_get_match_data(dev));
ret = chip->init(priv->regmap);
if (ret)
return ret;
tzdev = devm_thermal_of_zone_register(dev, 0, priv, chip->ops);
if (IS_ERR(tzdev))
return PTR_ERR(tzdev);
@@ -212,10 +246,10 @@ static int realtek_thermal_probe(struct platform_device *pdev)
}
static const struct of_device_id realtek_sensor_ids[] = {
{ .compatible = "realtek,rtl8380-thermal", .data = &rtl8380_ops, },
{ .compatible = "realtek,rtl8390-thermal", .data = &rtl8390_ops, },
{ .compatible = "realtek,rtl9300-thermal", .data = &rtl9300_ops, },
{ .compatible = "realtek,rtl9607-thermal", .data = &rtl9607_ops, },
{ .compatible = "realtek,rtl8380-thermal", .data = &rtl8380_chip, },
{ .compatible = "realtek,rtl8390-thermal", .data = &rtl8390_chip, },
{ .compatible = "realtek,rtl9300-thermal", .data = &rtl9300_chip, },
{ .compatible = "realtek,rtl9607-thermal", .data = &rtl9607_chip, },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, realtek_sensor_ids);
@@ -232,4 +266,4 @@ module_platform_driver(realtek_thermal_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Bjørn Mork <bjorn@mork.no>");
MODULE_DESCRIPTION("Realtek temperature sensor");
MODULE_DESCRIPTION("Realtek temperature sensor driver");
+4 -1
View File
@@ -17,6 +17,7 @@ define Device/hasivo_s1100w-8xgt-se
DEVICE_VENDOR := Hasivo
DEVICE_MODEL := S1100W-8XGT-SE
IMAGE_SIZE := 12288k
DEVICE_PACKAGES := rtl8264b-firmware
$(Device/kernel-lzma)
endef
TARGET_DEVICES += hasivo_s1100w-8xgt-se
@@ -126,7 +127,7 @@ define Device/xikestor_sks8300-8t
UIMAGE_MAGIC := 0x93000000
DEVICE_VENDOR := XikeStor
DEVICE_MODEL := SKS8300-8T
DEVICE_PACKAGES := kmod-hwmon-lm75
DEVICE_PACKAGES := kmod-hwmon-lm75 rtl8261n-firmware
IMAGE_SIZE := 20480k
$(Device/kernel-lzma)
IMAGE/sysupgrade.bin := \
@@ -160,6 +161,7 @@ define Device/xikestor_sks8300-12e2t2x
UIMAGE_MAGIC := 0x93000000
DEVICE_VENDOR := XikeStor
DEVICE_MODEL := SKS8300-12E2T2X
DEVICE_PACKAGES := rtl8261n-firmware
IMAGE_SIZE := 20480k
$(Device/kernel-lzma)
IMAGE/sysupgrade.bin := \
@@ -250,6 +252,7 @@ TARGET_DEVICES += zyxel_xgs1250-12-a1
define Device/zyxel_xgs1250-12-b1
$(Device/zyxel_xgs1250-12-common)
DEVICE_VARIANT := B1
DEVICE_PACKAGES += rtl8261n-firmware
endef
TARGET_DEVICES += zyxel_xgs1250-12-b1
+1 -1
View File
@@ -49,7 +49,7 @@ TARGET_DEVICES += xikestor_sks8300-12x-v1
define Device/zyxel_xs1930
SOC := rtl9313
DEVICE_PACKAGES := kmod-hwmon-lm85
DEVICE_PACKAGES := kmod-hwmon-lm85 kmod-hwmon-gpiofan
FLASH_ADDR := 0xb4280000
IMAGE_SIZE := 31808k
ZYNFW_ALIGN := 0x10000
@@ -27,17 +27,17 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/phy/realtek/Kconfig
+++ b/drivers/net/phy/realtek/Kconfig
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
@@ -2,6 +2,7 @@
config REALTEK_PHY
tristate "Realtek PHYs"
select PHY_COMMON_PROPS
+ select PHY_PACKAGE
help
Currently supports RTL821x/RTL822x and fast ethernet PHYs
--- a/drivers/net/phy/realtek/realtek_main.c
+++ b/drivers/net/phy/realtek/realtek_main.c
@@ -19,6 +19,7 @@
@@ -21,6 +21,7 @@
#include <linux/string_choices.h>
#include <net/phy/realtek_phy.h>
@@ -45,7 +45,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
#include "realtek.h"
#define RTL8201F_IER 0x13
@@ -175,6 +176,8 @@
@@ -177,6 +178,8 @@
#define RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN BIT(12)
#define RTL8221B_PHYCR1_PHYAD_0_EN BIT(13)
@@ -54,7 +54,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
#define RTL8366RB_POWER_SAVE 0x15
#define RTL8366RB_POWER_SAVE_ON BIT(12)
@@ -1871,6 +1874,66 @@ static int rtl8224_cable_test_get_status
@@ -1889,6 +1892,66 @@ static int rtl8224_cable_test_get_status
return rtl8224_cable_test_report(phydev, finished);
}
@@ -121,7 +121,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
{
int val;
@@ -2472,6 +2535,8 @@ static struct phy_driver realtek_drvs[]
@@ -3096,6 +3159,8 @@ static struct phy_driver realtek_drvs[]
PHY_ID_MATCH_EXACT(0x001ccad0),
.name = "RTL8224 2.5Gbps PHY",
.flags = PHY_POLL_CABLE_TEST,
@@ -24,7 +24,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/phy/realtek/realtek_main.c
+++ b/drivers/net/phy/realtek/realtek_main.c
@@ -177,6 +177,7 @@
@@ -179,6 +179,7 @@
#define RTL8221B_PHYCR1_PHYAD_0_EN BIT(13)
#define RTL8224_VND1_MDI_PAIR_SWAP 0xa90
@@ -32,7 +32,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
#define RTL8366RB_POWER_SAVE 0x15
#define RTL8366RB_POWER_SAVE_ON BIT(12)
@@ -1922,9 +1923,40 @@ static int rtl8224_mdi_config_order(stru
@@ -1940,9 +1941,40 @@ static int rtl8224_mdi_config_order(stru
order ? BIT(port_offset) : 0);
}
@@ -9,14 +9,14 @@ configuration option for the phy module.
Submitted-by: Birger Koblitz <mail@birger-koblitz.de>
--- a/drivers/net/phy/realtek/Makefile
+++ b/drivers/net/phy/realtek/Makefile
@@ -2,3 +2,4 @@
realtek-y += realtek_main.o
@@ -4,3 +4,4 @@ realtek-y += phy_patch.o
realtek-y += phy_patch_rtl826x.o
realtek-$(CONFIG_REALTEK_PHY_HWMON) += realtek_hwmon.o
obj-$(CONFIG_REALTEK_PHY) += realtek.o
+obj-$(CONFIG_REALTEK_PHY_MULTIPORT) += realtek_multiport.o
--- a/drivers/net/phy/realtek/Kconfig
+++ b/drivers/net/phy/realtek/Kconfig
@@ -5,6 +5,13 @@ config REALTEK_PHY
@@ -6,6 +6,13 @@ config REALTEK_PHY
help
Currently supports RTL821x/RTL822x and fast ethernet PHYs
@@ -38,6 +38,6 @@ Submitted-by: Birger Koblitz <mail@birger-koblitz.de>
obj-$(CONFIG_QSEMI_PHY) += qsemi.o
-obj-$(CONFIG_REALTEK_PHY) += realtek/
+obj-y += realtek/
obj-y += rtl8261n/
obj-$(CONFIG_RENESAS_PHY) += uPD60620.o
obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o
obj-$(CONFIG_SMSC_PHY) += smsc.o
@@ -30,7 +30,7 @@ Signed-off-by: Jan Hoffmann <jan@3e8.eu>
--- a/drivers/net/phy/realtek/realtek_main.c
+++ b/drivers/net/phy/realtek/realtek_main.c
@@ -1496,6 +1496,148 @@ static unsigned int rtl822x_inband_caps(
@@ -1514,6 +1514,148 @@ static unsigned int rtl822x_inband_caps(
}
}
@@ -179,7 +179,7 @@ Signed-off-by: Jan Hoffmann <jan@3e8.eu>
static int rtl822xb_get_rate_matching(struct phy_device *phydev,
phy_interface_t iface)
{
@@ -2459,7 +2601,7 @@ static struct phy_driver realtek_drvs[]
@@ -3083,7 +3225,7 @@ static struct phy_driver realtek_drvs[]
.soft_reset = rtl822x_c45_soft_reset,
.get_features = rtl822x_c45_get_features,
.config_aneg = rtl822x_c45_config_aneg,
@@ -1,6 +1,6 @@
--- a/drivers/net/phy/realtek/realtek_main.c
+++ b/drivers/net/phy/realtek/realtek_main.c
@@ -171,6 +171,41 @@
@@ -173,6 +173,41 @@
#define RTL8224_SRAM_RTCT_LEN(pair) (0x8028 + (pair) * 4)
@@ -42,7 +42,7 @@
#define RTL8221B_PHYCR1 0xa430
#define RTL8221B_PHYCR1_ALDPS_EN BIT(2)
#define RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN BIT(12)
@@ -2040,6 +2075,147 @@ exit:
@@ -2058,6 +2093,147 @@ exit:
return ret;
}
@@ -190,7 +190,7 @@
static int rtl8224_mdi_config_order(struct phy_device *phydev)
{
struct device_node *np = phydev->mdio.dev.of_node;
@@ -2094,6 +2270,10 @@ static int rtl8224_config_init(struct ph
@@ -2112,6 +2288,10 @@ static int rtl8224_config_init(struct ph
{
int ret;
-1
View File
@@ -223,7 +223,6 @@ CONFIG_REGMAP_MMIO=y
CONFIG_RESET_CONTROLLER=y
CONFIG_RFS_ACCEL=y
CONFIG_RPS=y
CONFIG_RTL8261N_PHY=y
# CONFIG_RTL838X is not set
# CONFIG_RTL839X is not set
CONFIG_RTL930X=y
@@ -233,7 +233,6 @@ CONFIG_REGMAP_MMIO=y
CONFIG_RESET_CONTROLLER=y
CONFIG_RFS_ACCEL=y
CONFIG_RPS=y
CONFIG_RTL8261N_PHY=y
# CONFIG_RTL838X is not set
# CONFIG_RTL839X is not set
CONFIG_RTL930X=y