Merge Official Source

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
Tianling Shen 2023-09-11 09:54:11 +08:00
commit 739467539f
No known key found for this signature in database
GPG Key ID: 6850B6345C862176
165 changed files with 10583 additions and 3495 deletions

View File

@ -1,2 +1,2 @@
LINUX_VERSION-5.15 = .127
LINUX_KERNEL_HASH-5.15.127 = add0a575341b263a06e93599fc220a5dd34cb4ca5b9d05097a5db2a061928f26
LINUX_VERSION-5.15 = .130
LINUX_KERNEL_HASH-5.15.130 = ab464e4107329ff5262f1c585c40fc29dc68f17687a9a918f3e90faba5303d62

View File

@ -9,7 +9,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=arm-trusted-firmware-mediatek
PKG_RELEASE:=1
PKG_RELEASE:=2
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=https://github.com/mtk-openwrt/arm-trusted-firmware.git

View File

@ -0,0 +1,11 @@
--- a/plat/mediatek/mt7988/bl2/bl2_plat_init.c
+++ b/plat/mediatek/mt7988/bl2/bl2_plat_init.c
@@ -90,6 +90,8 @@ static void mtk_i2p5g_phy_init(void)
* clear bit 22 to use external MDIO.
*/
mmio_setbits_32(GBE_TOP_REG, I2P5G_MDIO);
+ /* Internal 2.5Gphy power on sequence */
+ eth_2p5g_phy_mtcmos_ctrl(true);
}
static void mt7988_i2c_init(void)

View File

@ -0,0 +1,28 @@
From 9e8cb08bc64530e7511b86a131cfad1ae0199586 Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Sun, 10 Sep 2023 23:35:47 +0100
Subject: [PATCH] mt7622: move wdt init after dram init
resolves hang on reboot
---
plat/mediatek/mt7622/bl2/bl2_plat_init.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/plat/mediatek/mt7622/bl2/bl2_plat_init.c
+++ b/plat/mediatek/mt7622/bl2/bl2_plat_init.c
@@ -40,7 +40,6 @@ bool plat_is_my_cpu_primary(void)
const struct initcall bl2_initcalls[] = {
INITCALL(plat_mt_cpuxgpt_init),
INITCALL(generic_delay_timer_init),
- INITCALL(mtk_wdt_init),
INITCALL(mtk_print_cpu),
INITCALL(mtk_pin_init),
#ifndef IMAGE_BL2PL
@@ -49,6 +48,7 @@ const struct initcall bl2_initcalls[] =
INITCALL(mtk_pwrap_init),
INITCALL(mtk_pmic_init),
INITCALL(mtk_mem_init),
+ INITCALL(mtk_wdt_init),
INITCALL(NULL)
};

View File

@ -124,10 +124,34 @@ define U-Boot/mt7622_bananapi_bpi-r64-snand
DEPENDS:=+trusted-firmware-a-mt7622-snand-2ddr
endef
define U-Boot/mt7622_ubnt_unifi-6-lr
define U-Boot/mt7622_ubnt_unifi-6-lr-v1
NAME:=Ubiquiti UniFi 6 LR
UBOOT_CONFIG:=mt7622_ubnt_unifi-6-lr
BUILD_DEVICES:=ubnt_unifi-6-lr-v1-ubootmod ubnt_unifi-6-lr-v2-ubootmod
UBOOT_CONFIG:=mt7622_ubnt_unifi-6-lr-v1
BUILD_DEVICES:=ubnt_unifi-6-lr-v1-ubootmod
BUILD_SUBTARGET:=mt7622
UBOOT_IMAGE:=u-boot.fip
BL2_BOOTDEV:=nor
BL2_DDRBLOB:=2
DEPENDS:=+trusted-firmware-a-mt7622-nor-2ddr
FIP_COMPRESS:=1
endef
define U-Boot/mt7622_ubnt_unifi-6-lr-v2
NAME:=Ubiquiti UniFi 6 LR v2
UBOOT_CONFIG:=mt7622_ubnt_unifi-6-lr-v2
BUILD_DEVICES:=ubnt_unifi-6-lr-v2-ubootmod
BUILD_SUBTARGET:=mt7622
UBOOT_IMAGE:=u-boot.fip
BL2_BOOTDEV:=nor
BL2_DDRBLOB:=2
DEPENDS:=+trusted-firmware-a-mt7622-nor-2ddr
FIP_COMPRESS:=1
endef
define U-Boot/mt7622_ubnt_unifi-6-lr-v3
NAME:=Ubiquiti UniFi 6 LR v3
UBOOT_CONFIG:=mt7622_ubnt_unifi-6-lr-v3
BUILD_DEVICES:=ubnt_unifi-6-lr-v3-ubootmod
BUILD_SUBTARGET:=mt7622
UBOOT_IMAGE:=u-boot.fip
BL2_BOOTDEV:=nor
@ -324,61 +348,62 @@ endef
define U-Boot/mt7988_rfb-spim-nand
NAME:=MT7988 Reference Board
BUILD_SUBTARGET:=filogic
BUILD_DEVICES:=mediatek_mt7988a-rfb-nand
BUILD_DEVICES:=mediatek_mt7988a-rfb
UBOOT_CONFIG:=mt7988_rfb
UBOOT_IMAGE:=u-boot.fip
BL2_BOOTDEV:=spim-nand
BL2_SOC:=mt7988
BL2_DDRTYPE:=ddr4
DEPENDS:=+trusted-firmware-a-mt7988-spim-nand-ddr4
BL2_DDRTYPE:=comb
DEPENDS:=+trusted-firmware-a-mt7988-spim-nand-comb
endef
define U-Boot/mt7988_rfb-snand
NAME:=MT7988 Reference Board
BUILD_SUBTARGET:=filogic
BUILD_DEVICES:=mediatek_mt7988a-rfb-nand
BUILD_DEVICES:=mediatek_mt7988a-rfb
UBOOT_CONFIG:=mt7988_rfb
UBOOT_IMAGE:=u-boot.fip
BL2_BOOTDEV:=snand
BL2_SOC:=mt7988
BL2_DDRTYPE:=ddr4
DEPENDS:=+trusted-firmware-a-mt7988-snand-ddr4
BL2_DDRTYPE:=comb
DEPENDS:=+trusted-firmware-a-mt7988-snand-comb
endef
define U-Boot/mt7988_rfb-nor
NAME:=MT7988 Reference Board
BUILD_SUBTARGET:=filogic
BUILD_DEVICES:=mediatek_mt7988a-rfb-nand
BUILD_DEVICES:=mediatek_mt7988a-rfb
UBOOT_CONFIG:=mt7988_rfb
UBOOT_IMAGE:=u-boot.fip
BL2_BOOTDEV:=nor
BL2_SOC:=mt7988
BL2_DDRTYPE:=ddr4
DEPENDS:=+trusted-firmware-a-mt7988-nor-ddr4
BL2_DDRTYPE:=comb
DEPENDS:=+trusted-firmware-a-mt7988-nor-comb
FIP_COMPRESS:=1
endef
define U-Boot/mt7988_rfb-emmc
NAME:=MT7988 Reference Board
BUILD_SUBTARGET:=filogic
BUILD_DEVICES:=mediatek_mt7988a-rfb-nand
BUILD_DEVICES:=mediatek_mt7988a-rfb
UBOOT_CONFIG:=mt7988_rfb
UBOOT_IMAGE:=u-boot.fip
BL2_BOOTDEV:=emmc
BL2_SOC:=mt7988
BL2_DDRTYPE:=ddr4
DEPENDS:=+trusted-firmware-a-mt7988-emmc-ddr4
BL2_DDRTYPE:=comb
DEPENDS:=+trusted-firmware-a-mt7988-emmc-comb
endef
define U-Boot/mt7988_rfb-sd
NAME:=MT7988 Reference Board
BUILD_SUBTARGET:=filogic
BUILD_DEVICES:=mediatek_mt7988a-rfb-nand
BUILD_DEVICES:=mediatek_mt7988a-rfb
UBOOT_CONFIG:=mt7988_sd_rfb
UBOOT_IMAGE:=u-boot.fip
BL2_BOOTDEV:=sdmmc
BL2_SOC:=mt7988
BL2_DDRTYPE:=ddr4
DEPENDS:=+trusted-firmware-a-mt7988-sdmmc-ddr4
BL2_DDRTYPE:=comb
DEPENDS:=+trusted-firmware-a-mt7988-sdmmc-comb
endef
UBOOT_TARGETS := \
@ -391,7 +416,9 @@ UBOOT_TARGETS := \
mt7622_bananapi_bpi-r64-snand \
mt7622_linksys_e8450 \
mt7622_rfb1 \
mt7622_ubnt_unifi-6-lr \
mt7622_ubnt_unifi-6-lr-v1 \
mt7622_ubnt_unifi-6-lr-v2 \
mt7622_ubnt_unifi-6-lr-v3 \
mt7623n_bpir2 \
mt7623a_unielec_u7623 \
mt7628_rfb \

View File

@ -17,14 +17,14 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
drivers/mtd/mtk-snand/Kconfig | 21 +
drivers/mtd/mtk-snand/Makefile | 11 +
drivers/mtd/mtk-snand/mtk-snand-def.h | 271 ++++
drivers/mtd/mtk-snand/mtk-snand-ecc.c | 395 +++++
drivers/mtd/mtk-snand/mtk-snand-ids.c | 511 +++++++
drivers/mtd/mtk-snand/mtk-snand-ecc.c | 411 ++++++
drivers/mtd/mtk-snand/mtk-snand-ids.c | 515 +++++++
drivers/mtd/mtk-snand/mtk-snand-mtd.c | 535 +++++++
drivers/mtd/mtk-snand/mtk-snand-os.c | 39 +
drivers/mtd/mtk-snand/mtk-snand-os.h | 120 ++
drivers/mtd/mtk-snand/mtk-snand.c | 1933 +++++++++++++++++++++++++
drivers/mtd/mtk-snand/mtk-snand.h | 77 +
12 files changed, 3917 insertions(+)
12 files changed, 3937 insertions(+)
create mode 100644 drivers/mtd/mtk-snand/Kconfig
create mode 100644 drivers/mtd/mtk-snand/Makefile
create mode 100644 drivers/mtd/mtk-snand/mtk-snand-def.h
@ -369,7 +369,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+#endif /* _MTK_SNAND_DEF_H_ */
--- /dev/null
+++ b/drivers/mtd/mtk-snand/mtk-snand-ecc.c
@@ -0,0 +1,395 @@
@@ -0,0 +1,411 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
@ -418,6 +418,10 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+
+static const uint8_t mt7622_ecc_caps[] = { 4, 6, 8, 10, 12 };
+
+static const uint8_t mt7981_ecc_caps[] = {
+ 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24
+};
+
+static const uint8_t mt7986_ecc_caps[] = {
+ 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24
+};
@ -426,6 +430,10 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ [ECC_DECDONE] = 0x11c,
+};
+
+static const uint32_t mt7981_ecc_regs[] = {
+ [ECC_DECDONE] = 0x124,
+};
+
+static const uint32_t mt7986_ecc_regs[] = {
+ [ECC_DECDONE] = 0x124,
+};
@ -447,6 +455,14 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ .errnum_bits = 5,
+ .errnum_shift = 5,
+ },
+ [SNAND_SOC_MT7981] = {
+ .ecc_caps = mt7981_ecc_caps,
+ .num_ecc_cap = ARRAY_SIZE(mt7981_ecc_caps),
+ .regs = mt7981_ecc_regs,
+ .mode_shift = 5,
+ .errnum_bits = 5,
+ .errnum_shift = 8,
+ },
+ [SNAND_SOC_MT7986] = {
+ .ecc_caps = mt7986_ecc_caps,
+ .num_ecc_cap = ARRAY_SIZE(mt7986_ecc_caps),
@ -767,7 +783,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+}
--- /dev/null
+++ b/drivers/mtd/mtk-snand/mtk-snand-ids.c
@@ -0,0 +1,511 @@
@@ -0,0 +1,515 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
@ -860,6 +876,10 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ &snand_cap_read_from_cache_quad,
+ &snand_cap_program_load_x4,
+ mtk_snand_winbond_select_die),
+ SNAND_INFO("W25N01KV", SNAND_ID(SNAND_ID_DYMMY, 0xef, 0xae, 0x21),
+ SNAND_MEMORG_1G_2K_64,
+ &snand_cap_read_from_cache_quad,
+ &snand_cap_program_load_x4),
+ SNAND_INFO("W25N02KV", SNAND_ID(SNAND_ID_DYMMY, 0xef, 0xaa, 0x22),
+ SNAND_MEMORG_2G_2K_128,
+ &snand_cap_read_from_cache_quad,
@ -903,7 +923,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ &snand_cap_program_load_x4),
+ SNAND_INFO("GD5F2GQ5UExxG", SNAND_ID(SNAND_ID_DYMMY, 0xc8, 0x52),
+ SNAND_MEMORG_2G_2K_128,
+ &snand_cap_read_from_cache_quad_q2d,
+ &snand_cap_read_from_cache_quad_a8d,
+ &snand_cap_program_load_x4),
+ SNAND_INFO("GD5F4GQ4UCxIG", SNAND_ID(SNAND_ID_DYMMY, 0xc8, 0xb4),
+ SNAND_MEMORG_4G_4K_256,

View File

@ -310,3 +310,14 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
switch (key) {
case BKEY_PLUS:
--- a/boot/bootflow_menu.c
+++ b/boot/bootflow_menu.c
@@ -231,7 +231,7 @@ int bootflow_menu_run(struct bootstd_pri
key = 0;
if (ichar) {
- key = bootmenu_conv_key(ichar);
+ key = bootmenu_conv_key(NULL, ichar, NULL);
if (key == BKEY_NONE)
key = ichar;
}

View File

@ -411,7 +411,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+CONFIG_TARGET_MT7988=y
+CONFIG_DEBUG_UART_BASE=0x11000000
+CONFIG_DEBUG_UART_CLOCK=40000000
+CONFIG_SYS_LOAD_ADDR=0x46000000
+CONFIG_SYS_LOAD_ADDR=0x50000000
+CONFIG_DEBUG_UART=y
+# CONFIG_AUTOBOOT is not set
+CONFIG_DEFAULT_FDT_FILE="mt7988-rfb"
@ -497,7 +497,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+CONFIG_TARGET_MT7988=y
+CONFIG_DEBUG_UART_BASE=0x11000000
+CONFIG_DEBUG_UART_CLOCK=40000000
+CONFIG_SYS_LOAD_ADDR=0x46000000
+CONFIG_SYS_LOAD_ADDR=0x50000000
+CONFIG_DEBUG_UART=y
+# CONFIG_AUTOBOOT is not set
+CONFIG_DEFAULT_FDT_FILE="mt7988-sd-rfb"

View File

@ -0,0 +1,314 @@
--- a/configs/mt7988_sd_rfb_defconfig
+++ b/configs/mt7988_sd_rfb_defconfig
@@ -12,6 +12,24 @@ CONFIG_DEBUG_UART_BASE=0x11000000
CONFIG_DEBUG_UART_CLOCK=40000000
CONFIG_SYS_LOAD_ADDR=0x50000000
CONFIG_DEBUG_UART=y
+CONFIG_OF_LIBFDT_OVERLAY=y
+CONFIG_SMBIOS_PRODUCT_NAME=""
+CONFIG_CFB_CONSOLE_ANSI=y
+CONFIG_BOARD_LATE_INIT=y
+CONFIG_BUTTON=y
+CONFIG_BUTTON_GPIO=y
+CONFIG_GPIO_HOG=y
+CONFIG_CMD_ENV_FLAGS=y
+CONFIG_FIT=y
+CONFIG_FIT_ENABLE_SHA256_SUPPORT=y
+CONFIG_LED=y
+CONFIG_LED_BLINK=y
+CONFIG_LED_GPIO=y
+CONFIG_SPI_BOOT=y
+CONFIG_SD_BOOT=y
+CONFIG_NAND_BOOT=y
+CONFIG_BOOTSTD_DEFAULTS=y
+CONFIG_BOOTSTD_FULL=y
# CONFIG_AUTOBOOT is not set
CONFIG_DEFAULT_FDT_FILE="mt7988-sd-rfb"
CONFIG_LOGLEVEL=7
@@ -22,15 +40,118 @@ CONFIG_SYS_PBSIZE=1049
# CONFIG_BOOTM_PLAN9 is not set
# CONFIG_BOOTM_RTEMS is not set
# CONFIG_BOOTM_VXWORKS is not set
-# CONFIG_CMD_ELF is not set
+CONFIG_CMD_BOOTMENU=y
+CONFIG_CMD_BOOTP=y
+CONFIG_CMD_BUTTON=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_CDP=y
+CONFIG_CMD_CPU=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_DM=y
+CONFIG_CMD_ELF=y
+CONFIG_CMD_DNS=y
+CONFIG_CMD_ECHO=y
+CONFIG_CMD_ENV_READMEM=y
+CONFIG_CMD_ERASEENV=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FDT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_CMD_FS_UUID=y
CONFIG_CMD_CLK=y
CONFIG_CMD_DM=y
CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_HASH=y
+CONFIG_CMD_ITEST=y
+CONFIG_CMD_LED=y
+CONFIG_CMD_LICENSE=y
+CONFIG_CMD_LINK_LOCAL=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_MTD=y
+CONFIG_CMD_NAND=y
+CONFIG_CMD_NAND_TRIMFFS=y
+CONFIG_CMD_PCI=y
+CONFIG_CMD_PSTORE=y
+CONFIG_CMD_PSTORE_MEM_ADDR=0x42ff0000
+CONFIG_CMD_SF_TEST=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_PXE=y
CONFIG_CMD_PWM=y
CONFIG_CMD_MMC=y
CONFIG_CMD_MTD=y
CONFIG_CMD_PING=y
+CONFIG_CMD_SF=y
CONFIG_CMD_SMC=y
+CONFIG_CMD_TFTPBOOT=y
+CONFIG_CMD_TFTPSRV=y
+CONFIG_CMD_UBI=y
+CONFIG_CMD_UBI_RENAME=y
+CONFIG_CMD_UBIFS=y
+CONFIG_CMD_ASKENV=y
+CONFIG_CMD_PART=y
+CONFIG_CMD_RARP=y
+CONFIG_CMD_SETEXPR=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SNTP=y
+CONFIG_CMD_SOURCE=y
+CONFIG_CMD_STRINGS=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_UUID=y
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_DM_MMC=y
+CONFIG_DM_MTD=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_REGULATOR_GPIO=y
+CONFIG_DM_USB=y
+CONFIG_DM_PWM=y
+CONFIG_PWM_MTK=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_VERSION_VARIABLE=y
+CONFIG_PARTITION_UUIDS=y
+CONFIG_NETCONSOLE=y
+CONFIG_DM_GPIO=y
+CONFIG_DM_SCSI=y
+CONFIG_PHY=y
+CONFIG_PHY_MTK_TPHY=y
+CONFIG_PCI=y
+CONFIG_MTD=y
+CONFIG_MTD_UBI_FASTMAP=y
+# CONFIG_MTD_RAW_NAND is not set
+CONFIG_DM_PCI=y
+CONFIG_PCIE_MEDIATEK=y
+CONFIG_PINCTRL_MT7988=y
+CONFIG_PRE_CONSOLE_BUFFER=y
+CONFIG_PRE_CON_BUF_ADDR=0x4007EF00
+CONFIG_RAM=y
+CONFIG_DM_SERIAL=y
+CONFIG_MTK_SERIAL=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_MTK_SPI_NAND=y
+CONFIG_MTK_SPI_NAND_MTD=y
+CONFIG_SYSRESET_WATCHDOG=y
+CONFIG_WDT_MTK=y
+CONFIG_LZO=y
+CONFIG_ZSTD=y
+CONFIG_HEXDUMP=y
+CONFIG_RANDOM_UUID=y
+CONFIG_REGEX=y
+CONFIG_USB=y
+CONFIG_USB_HOST=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_MTK=y
+CONFIG_USB_STORAGE=y
+CONFIG_OF_EMBED=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_OFFSET=0x400000
+CONFIG_ENV_OFFSET_REDUND=0x440000
+CONFIG_ENV_SIZE=0x40000
+CONFIG_ENV_SIZE_REDUND=0x40000
CONFIG_DOS_PARTITION=y
CONFIG_EFI_PARTITION=y
CONFIG_PARTITION_TYPE_GUID=y
@@ -46,6 +167,9 @@ CONFIG_PROT_TCP=y
CONFIG_REGMAP=y
CONFIG_SYSCON=y
CONFIG_CLK=y
+CONFIG_MMC=y
+CONFIG_MMC_DEFAULT_DEV=1
+CONFIG_MMC_SUPPORTS_TUNING=y
CONFIG_MMC_HS200_SUPPORT=y
CONFIG_MMC_MTK=y
CONFIG_MTD=y
--- a/configs/mt7988_rfb_defconfig
+++ b/configs/mt7988_rfb_defconfig
@@ -12,6 +12,24 @@ CONFIG_DEBUG_UART_BASE=0x11000000
CONFIG_DEBUG_UART_CLOCK=40000000
CONFIG_SYS_LOAD_ADDR=0x50000000
CONFIG_DEBUG_UART=y
+CONFIG_OF_LIBFDT_OVERLAY=y
+CONFIG_SMBIOS_PRODUCT_NAME=""
+CONFIG_CFB_CONSOLE_ANSI=y
+CONFIG_BOARD_LATE_INIT=y
+CONFIG_BUTTON=y
+CONFIG_BUTTON_GPIO=y
+CONFIG_GPIO_HOG=y
+CONFIG_CMD_ENV_FLAGS=y
+CONFIG_FIT=y
+CONFIG_FIT_ENABLE_SHA256_SUPPORT=y
+CONFIG_LED=y
+CONFIG_LED_BLINK=y
+CONFIG_LED_GPIO=y
+CONFIG_SPI_BOOT=y
+CONFIG_SD_BOOT=y
+CONFIG_NAND_BOOT=y
+CONFIG_BOOTSTD_DEFAULTS=y
+CONFIG_BOOTSTD_FULL=y
# CONFIG_AUTOBOOT is not set
CONFIG_DEFAULT_FDT_FILE="mt7988-rfb"
CONFIG_LOGLEVEL=7
@@ -22,15 +40,118 @@ CONFIG_SYS_PBSIZE=1049
# CONFIG_BOOTM_PLAN9 is not set
# CONFIG_BOOTM_RTEMS is not set
# CONFIG_BOOTM_VXWORKS is not set
-# CONFIG_CMD_ELF is not set
+CONFIG_CMD_BOOTMENU=y
+CONFIG_CMD_BOOTP=y
+CONFIG_CMD_BUTTON=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_CDP=y
+CONFIG_CMD_CPU=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_DM=y
+CONFIG_CMD_ELF=y
+CONFIG_CMD_DNS=y
+CONFIG_CMD_ECHO=y
+CONFIG_CMD_ENV_READMEM=y
+CONFIG_CMD_ERASEENV=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FDT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_CMD_FS_UUID=y
CONFIG_CMD_CLK=y
CONFIG_CMD_DM=y
CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_HASH=y
+CONFIG_CMD_ITEST=y
+CONFIG_CMD_LED=y
+CONFIG_CMD_LICENSE=y
+CONFIG_CMD_LINK_LOCAL=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_MTD=y
+CONFIG_CMD_NAND=y
+CONFIG_CMD_NAND_TRIMFFS=y
+CONFIG_CMD_PCI=y
+CONFIG_CMD_PSTORE=y
+CONFIG_CMD_PSTORE_MEM_ADDR=0x42ff0000
+CONFIG_CMD_SF_TEST=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_PXE=y
CONFIG_CMD_PWM=y
CONFIG_CMD_MMC=y
CONFIG_CMD_MTD=y
CONFIG_CMD_PING=y
+CONFIG_CMD_SF=y
CONFIG_CMD_SMC=y
+CONFIG_CMD_TFTPBOOT=y
+CONFIG_CMD_TFTPSRV=y
+CONFIG_CMD_UBI=y
+CONFIG_CMD_UBI_RENAME=y
+CONFIG_CMD_UBIFS=y
+CONFIG_CMD_ASKENV=y
+CONFIG_CMD_PART=y
+CONFIG_CMD_RARP=y
+CONFIG_CMD_SETEXPR=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SNTP=y
+CONFIG_CMD_SOURCE=y
+CONFIG_CMD_STRINGS=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_UUID=y
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_DM_MMC=y
+CONFIG_DM_MTD=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_REGULATOR_GPIO=y
+CONFIG_DM_USB=y
+CONFIG_DM_PWM=y
+CONFIG_PWM_MTK=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_VERSION_VARIABLE=y
+CONFIG_PARTITION_UUIDS=y
+CONFIG_NETCONSOLE=y
+CONFIG_DM_GPIO=y
+CONFIG_DM_SCSI=y
+CONFIG_PHY=y
+CONFIG_PHY_MTK_TPHY=y
+CONFIG_PCI=y
+CONFIG_MTD=y
+CONFIG_MTD_UBI_FASTMAP=y
+# CONFIG_MTD_RAW_NAND is not set
+CONFIG_DM_PCI=y
+CONFIG_PCIE_MEDIATEK=y
+CONFIG_PINCTRL_MT7988=y
+CONFIG_PRE_CONSOLE_BUFFER=y
+CONFIG_PRE_CON_BUF_ADDR=0x4007EF00
+CONFIG_RAM=y
+CONFIG_DM_SERIAL=y
+CONFIG_MTK_SERIAL=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_MTK_SPI_NAND=y
+CONFIG_MTK_SPI_NAND_MTD=y
+CONFIG_SYSRESET_WATCHDOG=y
+CONFIG_WDT_MTK=y
+CONFIG_LZO=y
+CONFIG_ZSTD=y
+CONFIG_HEXDUMP=y
+CONFIG_RANDOM_UUID=y
+CONFIG_REGEX=y
+CONFIG_USB=y
+CONFIG_USB_HOST=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_MTK=y
+CONFIG_USB_STORAGE=y
+CONFIG_OF_EMBED=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_OFFSET=0x400000
+CONFIG_ENV_OFFSET_REDUND=0x440000
+CONFIG_ENV_SIZE=0x40000
+CONFIG_ENV_SIZE_REDUND=0x40000
CONFIG_DOS_PARTITION=y
CONFIG_EFI_PARTITION=y
CONFIG_PARTITION_TYPE_GUID=y
@@ -46,6 +167,9 @@ CONFIG_PROT_TCP=y
CONFIG_REGMAP=y
CONFIG_SYSCON=y
CONFIG_CLK=y
+CONFIG_MMC=y
+CONFIG_MMC_DEFAULT_DEV=1
+CONFIG_MMC_SUPPORTS_TUNING=y
CONFIG_MMC_HS200_SUPPORT=y
CONFIG_MMC_MTK=y
CONFIG_MTD=y

View File

@ -1,5 +1,5 @@
--- /dev/null
+++ b/configs/mt7622_ubnt_unifi-6-lr_defconfig
+++ b/configs/mt7622_ubnt_unifi-6-lr-v1_defconfig
@@ -0,0 +1,147 @@
+CONFIG_ARM=y
+CONFIG_POSITION_INDEPENDENT=y
@ -149,6 +149,305 @@
+CONFIG_USE_SERVERIP=y
+CONFIG_SERVERIP="192.168.1.254"
--- /dev/null
+++ b/configs/mt7622_ubnt_unifi-6-lr-v2_defconfig
@@ -0,0 +1,147 @@
+CONFIG_ARM=y
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_TARGET_MT7622=y
+CONFIG_TEXT_BASE=0x41e00000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_SYS_LOAD_ADDR=0x40080000
+CONFIG_USE_DEFAULT_ENV_FILE=y
+CONFIG_MTDPARTS_DEFAULT="mtdparts=nor0:128k(bl2),640k(fip),64k(u-boot-env),256k(factory),64k(eeprom),15232k(recovery),-(firmware)"
+CONFIG_ENV_IS_IN_MTD=y
+CONFIG_ENV_MTD_NAME="nor0"
+CONFIG_ENV_SIZE_REDUND=0x4000
+CONFIG_ENV_SIZE=0x4000
+CONFIG_ENV_OFFSET=0xc0000
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_BOARD_LATE_INIT=y
+CONFIG_RESET_BUTTON_SETTLE_DELAY=400
+CONFIG_BOOTP_SEND_HOSTNAME=y
+CONFIG_DEFAULT_ENV_FILE="ubnt_unifi-6-lr-v2_env"
+CONFIG_DEBUG_UART_BASE=0x11002000
+CONFIG_DEBUG_UART_CLOCK=25000000
+CONFIG_DEFAULT_DEVICE_TREE="mt7622-ubnt-unifi-6-lr"
+CONFIG_DEBUG_UART=y
+CONFIG_SMBIOS_PRODUCT_NAME=""
+CONFIG_AUTOBOOT_KEYED=y
+CONFIG_BOOTDELAY=30
+CONFIG_AUTOBOOT_MENU_SHOW=y
+CONFIG_CFB_CONSOLE_ANSI=y
+CONFIG_BUTTON=y
+CONFIG_BUTTON_GPIO=y
+CONFIG_GPIO_HOG=y
+CONFIG_CMD_ENV_FLAGS=y
+CONFIG_FIT=y
+CONFIG_FIT_ENABLE_SHA256_SUPPORT=y
+CONFIG_LOGLEVEL=7
+CONFIG_LOG=y
+CONFIG_DEFAULT_FDT_FILE="mt7622-ubnt-unifi-6-lr"
+CONFIG_SYS_PROMPT="MT7622> "
+# CONFIG_LEGACY_IMAGE_FORMAT is not set
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+# CONFIG_EFI is not set
+# CONFIG_EFI_LOADER is not set
+CONFIG_CMD_BOOTMENU=y
+# CONFIG_CMD_BOOTEFI is not set
+CONFIG_CMD_BOOTP=y
+CONFIG_CMD_BUTTON=y
+CONFIG_CMD_CDP=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_DNS=y
+CONFIG_CMD_ECHO=y
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_BOOTEFI_BOOTMGR is not set
+CONFIG_CMD_ENV_READMEM=y
+CONFIG_CMD_ERASEENV=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_HASH=y
+CONFIG_CMD_ITEST=y
+CONFIG_CMD_LED=y
+CONFIG_CMD_LINK_LOCAL=y
+# CONFIG_CMD_MBR is not set
+CONFIG_CMD_MTD=y
+CONFIG_CMD_MTDPARTS=y
+# CONFIG_CMD_PCI is not set
+CONFIG_CMD_SF_TEST=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_PXE=y
+CONFIG_CMD_SMC=y
+CONFIG_CMD_TFTPBOOT=y
+CONFIG_CMD_TFTPSRV=y
+# CONFIG_CMD_UNLZ4 is not set
+CONFIG_CMD_ASKENV=y
+CONFIG_CMD_PSTORE=y
+CONFIG_CMD_PSTORE_MEM_ADDR=0x42ff0000
+CONFIG_CMD_RARP=y
+CONFIG_CMD_SETEXPR=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SOURCE=y
+CONFIG_CMD_UUID=y
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_DM_ETH=y
+CONFIG_DM_ETH_PHY=y
+CONFIG_DM_GPIO=y
+CONFIG_DM_MDIO=y
+CONFIG_DM_MTD=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_REGULATOR_GPIO=y
+# CONFIG_DM_MMC is not set
+CONFIG_DM_SERIAL=y
+CONFIG_DM_SPI=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_HUSH_PARSER=y
+# CONFIG_PARTITION_UUIDS is not set
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+# CONFIG_LED is not set
+# CONFIG_LZ4 is not set
+CONFIG_VERSION_VARIABLE=y
+CONFIG_NETCONSOLE=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_PHY=y
+CONFIG_PHY_FIXED=y
+CONFIG_PHYLIB_10G=y
+CONFIG_PHY_AQUANTIA=y
+CONFIG_PHY_ADDR_ENABLE=y
+CONFIG_PHY_ADDR=8
+CONFIG_MEDIATEK_ETH=y
+CONFIG_MTD=y
+# CONFIG_MMC is not set
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_MT7622=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_PRE_CONSOLE_BUFFER=y
+CONFIG_PRE_CON_BUF_ADDR=0x4007EF00
+CONFIG_MTK_POWER_DOMAIN=y
+CONFIG_RAM=y
+CONFIG_MTK_SERIAL=y
+CONFIG_SPI=y
+CONFIG_MTK_SNFI_SPI=y
+CONFIG_MTK_SNOR=y
+CONFIG_SYSRESET_WATCHDOG=y
+CONFIG_WDT_MTK=y
+CONFIG_HEXDUMP=y
+CONFIG_RANDOM_UUID=y
+CONFIG_REGEX=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_SPI_FLASH_UNLOCK_ALL=y
+CONFIG_SPI_FLASH_EON=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_SST=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_XMC=y
+CONFIG_SPI_FLASH_USE_4K_SECTORS=y
+CONFIG_SYS_HAS_NONCACHED_MEMORY=y
+CONFIG_USE_IPADDR=y
+CONFIG_IPADDR="192.168.1.1"
+CONFIG_USE_SERVERIP=y
+CONFIG_SERVERIP="192.168.1.254"
--- /dev/null
+++ b/configs/mt7622_ubnt_unifi-6-lr-v3_defconfig
@@ -0,0 +1,146 @@
+CONFIG_ARM=y
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_TARGET_MT7622=y
+CONFIG_TEXT_BASE=0x41e00000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_SYS_LOAD_ADDR=0x40080000
+CONFIG_USE_DEFAULT_ENV_FILE=y
+CONFIG_MTDPARTS_DEFAULT="mtdparts=nor0:128k(bl2),640k(fip),64k(u-boot-env),256k(factory),64k(eeprom),15232k(recovery),-(firmware)"
+CONFIG_ENV_IS_IN_MTD=y
+CONFIG_ENV_MTD_NAME="nor0"
+CONFIG_ENV_SIZE_REDUND=0x4000
+CONFIG_ENV_SIZE=0x4000
+CONFIG_ENV_OFFSET=0xc0000
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_BOARD_LATE_INIT=y
+CONFIG_RESET_BUTTON_SETTLE_DELAY=400
+CONFIG_BOOTP_SEND_HOSTNAME=y
+CONFIG_DEFAULT_ENV_FILE="ubnt_unifi-6-lr_env"
+CONFIG_DEBUG_UART_BASE=0x11002000
+CONFIG_DEBUG_UART_CLOCK=25000000
+CONFIG_DEFAULT_DEVICE_TREE="mt7622-ubnt-unifi-6-lr-v3"
+CONFIG_DEBUG_UART=y
+CONFIG_SMBIOS_PRODUCT_NAME=""
+CONFIG_AUTOBOOT_KEYED=y
+CONFIG_BOOTDELAY=30
+CONFIG_AUTOBOOT_MENU_SHOW=y
+CONFIG_CFB_CONSOLE_ANSI=y
+CONFIG_BUTTON=y
+CONFIG_BUTTON_GPIO=y
+CONFIG_GPIO_HOG=y
+CONFIG_CMD_ENV_FLAGS=y
+CONFIG_FIT=y
+CONFIG_FIT_ENABLE_SHA256_SUPPORT=y
+CONFIG_LOGLEVEL=7
+CONFIG_LOG=y
+CONFIG_DEFAULT_FDT_FILE="mt7622-ubnt-unifi-6-lr-v3"
+CONFIG_SYS_PROMPT="MT7622> "
+# CONFIG_LEGACY_IMAGE_FORMAT is not set
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+# CONFIG_EFI is not set
+# CONFIG_EFI_LOADER is not set
+CONFIG_CMD_BOOTMENU=y
+# CONFIG_CMD_BOOTEFI is not set
+CONFIG_CMD_BOOTP=y
+CONFIG_CMD_BUTTON=y
+CONFIG_CMD_CDP=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_DNS=y
+CONFIG_CMD_ECHO=y
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_BOOTEFI_BOOTMGR is not set
+CONFIG_CMD_ENV_READMEM=y
+CONFIG_CMD_ERASEENV=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_HASH=y
+CONFIG_CMD_ITEST=y
+CONFIG_CMD_LED=y
+CONFIG_CMD_LINK_LOCAL=y
+# CONFIG_CMD_MBR is not set
+CONFIG_CMD_MTD=y
+CONFIG_CMD_MTDPARTS=y
+# CONFIG_CMD_PCI is not set
+CONFIG_CMD_SF_TEST=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_PXE=y
+CONFIG_CMD_SMC=y
+CONFIG_CMD_TFTPBOOT=y
+CONFIG_CMD_TFTPSRV=y
+# CONFIG_CMD_UNLZ4 is not set
+CONFIG_CMD_ASKENV=y
+CONFIG_CMD_PSTORE=y
+CONFIG_CMD_PSTORE_MEM_ADDR=0x42ff0000
+CONFIG_CMD_RARP=y
+CONFIG_CMD_SETEXPR=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SOURCE=y
+CONFIG_CMD_UUID=y
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_DM_ETH=y
+CONFIG_DM_ETH_PHY=y
+CONFIG_DM_GPIO=y
+CONFIG_DM_MDIO=y
+CONFIG_DM_MTD=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_REGULATOR_GPIO=y
+# CONFIG_DM_MMC is not set
+CONFIG_DM_SERIAL=y
+CONFIG_DM_SPI=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_HUSH_PARSER=y
+# CONFIG_PARTITION_UUIDS is not set
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+# CONFIG_LED is not set
+# CONFIG_LZ4 is not set
+CONFIG_VERSION_VARIABLE=y
+CONFIG_NETCONSOLE=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_PHY=y
+CONFIG_PHY_FIXED=y
+CONFIG_PHY_REALTEK=y
+CONFIG_PHY_ADDR_ENABLE=y
+CONFIG_PHY_ADDR=0
+CONFIG_MEDIATEK_ETH=y
+CONFIG_MTD=y
+# CONFIG_MMC is not set
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_MT7622=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_PRE_CONSOLE_BUFFER=y
+CONFIG_PRE_CON_BUF_ADDR=0x4007EF00
+CONFIG_MTK_POWER_DOMAIN=y
+CONFIG_RAM=y
+CONFIG_MTK_SERIAL=y
+CONFIG_SPI=y
+CONFIG_MTK_SNFI_SPI=y
+CONFIG_MTK_SNOR=y
+CONFIG_SYSRESET_WATCHDOG=y
+CONFIG_WDT_MTK=y
+CONFIG_HEXDUMP=y
+CONFIG_RANDOM_UUID=y
+CONFIG_REGEX=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_SPI_FLASH_UNLOCK_ALL=y
+CONFIG_SPI_FLASH_EON=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_SST=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_XMC=y
+CONFIG_SPI_FLASH_USE_4K_SECTORS=y
+CONFIG_SYS_HAS_NONCACHED_MEMORY=y
+CONFIG_USE_IPADDR=y
+CONFIG_IPADDR="192.168.1.1"
+CONFIG_USE_SERVERIP=y
+CONFIG_SERVERIP="192.168.1.254"
--- /dev/null
+++ b/arch/arm/dts/mt7622-ubnt-unifi-6-lr.dts
@@ -0,0 +1,193 @@
+// SPDX-License-Identifier: GPL-2.0
@ -344,13 +643,210 @@
+ };
+ };
+};
--- /dev/null
+++ b/arch/arm/dts/mt7622-ubnt-unifi-6-lr-v3.dts
@@ -0,0 +1,193 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/linux-event-codes.h>
+#include "mt7622.dtsi"
+#include "mt7622-u-boot.dtsi"
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "mt7622-ubnt-unifi-6-lr-v3";
+ compatible = "mediatek,mt7622", "ubnt,unifi-6-lr-v3";
+
+ chosen {
+ stdout-path = &uart0;
+ tick-timer = &timer0;
+ };
+
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0x40000000 0x20000000>;
+ };
+
+ aliases {
+ spi0 = &snor;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ gpios = <&gpio 62 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+ };
+
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0x40000000 0x20000000>;
+ };
+
+ reg_1p8v: regulator-1p8v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_3p3v: regulator-3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_5v: regulator-5v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+};
+
+&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie0_pins>, <&pcie1_pins>;
+ status = "okay";
+
+ pcie@0,0 {
+ status = "okay";
+ };
+
+ pcie@1,0 {
+ status = "okay";
+ };
+};
+
+&pinctrl {
+ eth_pins: eth-pins {
+ mux {
+ function = "eth";
+ groups = "mdc_mdio", "rgmii_via_gmac2";
+ };
+ };
+
+ pcie0_pins: pcie0-pins {
+ mux {
+ function = "pcie";
+ groups = "pcie0_pad_perst",
+ "pcie0_1_waken",
+ "pcie0_1_clkreq";
+ };
+ };
+
+ pcie1_pins: pcie1-pins {
+ mux {
+ function = "pcie";
+ groups = "pcie1_pad_perst",
+ "pcie1_0_waken",
+ "pcie1_0_clkreq";
+ };
+ };
+
+ snfi_pins: snfi-pins {
+ mux {
+ function = "flash";
+ groups = "snfi";
+ };
+ };
+
+ snor_pins: snor-pins {
+ mux {
+ function = "flash";
+ groups = "spi_nor";
+ };
+ };
+
+ uart0_pins: uart0 {
+ mux {
+ function = "uart";
+ groups = "uart0_0_tx_rx" ;
+ };
+ };
+
+ watchdog_pins: watchdog-default {
+ mux {
+ function = "watchdog";
+ groups = "watchdog";
+ };
+ };
+};
+
+&snor {
+ pinctrl-names = "default";
+ pinctrl-0 = <&snor_pins>;
+ status = "okay";
+
+ spi-flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <4>;
+ u-boot,dm-pre-reloc;
+ };
+};
+
+&uart0 {
+ mediatek,force-highspeed;
+ status = "okay";
+};
+
+&watchdog {
+ pinctrl-names = "default";
+ pinctrl-0 = <&watchdog_pins>;
+ status = "okay";
+};
+
+&eth {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&eth_pins>;
+
+ mediatek,gmac-id = <0>;
+ phy-mode = "sgmii";
+ phy-handle = <&gphy>;
+
+ fixed-link {
+ speed = <2500>;
+ full-duplex;
+ };
+
+ mdio-bus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gphy: ethernet-phy@0 {
+ /* RealTek RTL8211FS */
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x0>;
+ };
+ };
+};
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1306,6 +1306,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \
@@ -1306,6 +1306,8 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \
mt7623a-unielec-u7623-02-emmc.dtb \
mt7622-bananapi-bpi-r64.dtb \
mt7622-linksys-e8450-ubi.dtb \
+ mt7622-ubnt-unifi-6-lr.dtb \
+ mt7622-ubnt-unifi-6-lr-v3.dtb \
mt7623n-bananapi-bpi-r2.dtb \
mt7629-rfb.dtb \
mt7981-rfb.dtb \
@ -407,6 +903,112 @@
+_firstboot=setenv _firstboot ; run _switch_to_menu ; run ethaddr_factory ; run _init_env ; run boot_first
+_switch_to_menu=setenv _switch_to_menu ; setenv bootdelay 3 ; setenv bootmenu_delay 3 ; setenv bootmenu_0 $bootmenu_0d ; setenv bootmenu_0d ; run _bootmenu_update_title
+_bootmenu_update_title=setenv _bootmenu_update_title ; setenv bootmenu_title "$bootmenu_title $ver"
--- /dev/null
+++ b/ubnt_unifi-6-lr-v2_env
@@ -0,0 +1,50 @@
+ethaddr_factory=mtd read nor0 $loadaddr 0x110000 0x10000 && env readmem -b ethaddr $loadaddr 0x6 ; setenv ethaddr_factory
+ipaddr=192.168.1.1
+serverip=192.168.1.254
+loadaddr=0x48000000
+bootcmd=if pstore check ; then run boot_recovery ; else run boot_nor ; fi
+bootdelay=0
+bootfile=openwrt-mediatek-mt7622-ubnt_unifi-6-lr-v2-ubootmod-initramfs-recovery.itb
+bootfile_bl2=openwrt-mediatek-mt7622-ubnt_unifi-6-lr-v2-ubootmod-preloader.bin
+bootfile_fip=openwrt-mediatek-mt7622-ubnt_unifi-6-lr-v2-ubootmod-bl31-uboot.fip
+bootfile_upg=openwrt-mediatek-mt7622-ubnt_unifi-6-lr-v2-ubootmod-squashfs-sysupgrade.itb
+bootmenu_confirm_return=askenv - Press ENTER to return to menu ; bootmenu 60
+bootmenu_default=0
+bootmenu_delay=0
+bootmenu_title= ( ( ( OpenWrt ) ) )
+bootmenu_0=Initialize environment.=run _firstboot
+bootmenu_0d=Run default boot command.=run boot_default
+bootmenu_1=Boot system via TFTP.=run boot_tftp ; run bootmenu_confirm_return
+bootmenu_2=Boot production system from flash.=run boot_production ; run bootmenu_confirm_return
+bootmenu_3=Boot recovery system from flash.=run boot_recovery ; run bootmenu_confirm_return
+bootmenu_4=Load production system via TFTP then write to flash.=setenv noboot 1 ; setenv replacevol 1 ; run boot_tftp_production ; setenv noboot ; setenv replacevol ; run bootmenu_confirm_return
+bootmenu_5=Load recovery system via TFTP then write to flash.=setenv noboot 1 ; setenv replacevol 1 ; run boot_tftp_recovery ; setenv noboot ; setenv replacevol ; run bootmenu_confirm_return
+bootmenu_6=Load BL31+U-Boot FIP via TFTP then write to flash.=run boot_tftp_write_fip ; run bootmenu_confirm_return
+bootmenu_7=Load BL2 preloader via TFTP then write to flash.=run boot_tftp_write_preloader ; run bootmenu_confirm_return
+bootmenu_8=Reboot.=reset
+bootmenu_9=Reset all settings to factory defaults.=run reset_factory ; reset
+boot_first=if button reset ; then run boot_tftp_recovery ; setenv flag_recover 1 ; run boot_default ; fi ; bootmenu
+boot_default=if env exists flag_recover ; then else run bootcmd ; fi ; run boot_recovery ; setenv replacevol 1 ; run boot_tftp_forever
+boot_production=run nor_read_production && bootm $loadaddr
+boot_recovery=run nor_read_recovery ; bootm $loadaddr
+boot_serial_write_fip=loadx $loadaddr 115200 && run boot_write_fip
+boot_serial_write_preloader=loadx $loadaddr 115200 && run boot_write_preloader
+boot_tftp_forever=while true ; do run boot_tftp_recovery ; sleep 1 ; done
+boot_tftp_production=tftpboot $loadaddr $bootfile_upg && env exists replacevol && iminfo $loadaddr && run nor_write_production ; if env exists noboot ; then else bootm $loadaddr ; fi
+boot_tftp_recovery=tftpboot $loadaddr $bootfile && env exists replacevol && iminfo $loadaddr && run nor_write_recovery ; if env exists noboot ; then else bootm $loadaddr ; fi
+boot_tftp=tftpboot $loadaddr $bootfile && bootm $loadaddr
+boot_tftp_write_fip=tftpboot $loadaddr $bootfile_fip && run boot_write_fip
+boot_tftp_write_preloader=tftpboot $loadaddr $bootfile_bl2 && run boot_write_preloader
+boot_nor=run boot_production ; run boot_recovery
+boot_write_fip=mtd erase nor0 0x20000 0x80000 && mtd write nor0 $loadaddr 0x20000 0x80000
+boot_write_preloader=mtd erase nor0 0x0 0x20000 && mtd write nor0 $loadaddr 0x0 0x20000
+reset_factory=mtd erase nor0 0xc0000 0x10000 && reset
+nor_read_production=mtd read nor0 $loadaddr 0x1000000 0x1000 && imsz $loadaddr image_size && mtd read nor0 $loadaddr 0x1000000 $image_size
+nor_read_recovery=mtd read nor0 $loadaddr 0x120000 0x1000 && imsz $loadaddr image_size && mtd read nor0 $loadaddr 0x120000 $image_size
+nor_pad_size=imsz $loadaddr image_size ; setexpr image_eb 0x$image_size / 0x1000 ; setexpr tmp1 0x$image_size % 0x1000 ; test 0x$tmp1 -gt 0 && setexpr image_eb 0x$image_eb + 1 ; setexpr image_eb 0x$image_eb * 0x1000
+nor_write_production=run nor_pad_size ; test 0x$image_eb -le 0x3000000 && mtd erase nor0 0x1000000 0x$image_eb && mtd write nor0 $loadaddr 0x1000000 $filesize
+nor_write_recovery=run nor_pad_size ; test 0x$image_eb -le 0xee0000 && mtd erase nor0 0x120000 0x$image_eb && mtd write nor0 $loadaddr 0x120000 $filesize
+_init_env=setenv _init_env ; saveenv
+_firstboot=setenv _firstboot ; run _switch_to_menu ; run ethaddr_factory ; run _init_env ; run boot_first
+_switch_to_menu=setenv _switch_to_menu ; setenv bootdelay 3 ; setenv bootmenu_delay 3 ; setenv bootmenu_0 $bootmenu_0d ; setenv bootmenu_0d ; run _bootmenu_update_title
+_bootmenu_update_title=setenv _bootmenu_update_title ; setenv bootmenu_title "$bootmenu_title $ver"--- /dev/null
--- /dev/null
+++ b/ubnt_unifi-6-lr-v3_env
@@ -0,0 +1,50 @@
+ethaddr_factory=mtd read nor0 $loadaddr 0x110000 0x10000 && env readmem -b ethaddr $loadaddr 0x6 ; setenv ethaddr_factory
+ipaddr=192.168.1.1
+serverip=192.168.1.254
+loadaddr=0x48000000
+bootcmd=if pstore check ; then run boot_recovery ; else run boot_nor ; fi
+bootdelay=0
+bootfile=openwrt-mediatek-mt7622-ubnt_unifi-6-lr-v3-ubootmod-initramfs-recovery.itb
+bootfile_bl2=openwrt-mediatek-mt7622-ubnt_unifi-6-lr-v3-ubootmod-preloader.bin
+bootfile_fip=openwrt-mediatek-mt7622-ubnt_unifi-6-lr-v3-ubootmod-bl31-uboot.fip
+bootfile_upg=openwrt-mediatek-mt7622-ubnt_unifi-6-lr-v3-ubootmod-squashfs-sysupgrade.itb
+bootmenu_confirm_return=askenv - Press ENTER to return to menu ; bootmenu 60
+bootmenu_default=0
+bootmenu_delay=0
+bootmenu_title= ( ( ( OpenWrt ) ) )
+bootmenu_0=Initialize environment.=run _firstboot
+bootmenu_0d=Run default boot command.=run boot_default
+bootmenu_1=Boot system via TFTP.=run boot_tftp ; run bootmenu_confirm_return
+bootmenu_2=Boot production system from flash.=run boot_production ; run bootmenu_confirm_return
+bootmenu_3=Boot recovery system from flash.=run boot_recovery ; run bootmenu_confirm_return
+bootmenu_4=Load production system via TFTP then write to flash.=setenv noboot 1 ; setenv replacevol 1 ; run boot_tftp_production ; setenv noboot ; setenv replacevol ; run bootmenu_confirm_return
+bootmenu_5=Load recovery system via TFTP then write to flash.=setenv noboot 1 ; setenv replacevol 1 ; run boot_tftp_recovery ; setenv noboot ; setenv replacevol ; run bootmenu_confirm_return
+bootmenu_6=Load BL31+U-Boot FIP via TFTP then write to flash.=run boot_tftp_write_fip ; run bootmenu_confirm_return
+bootmenu_7=Load BL2 preloader via TFTP then write to flash.=run boot_tftp_write_preloader ; run bootmenu_confirm_return
+bootmenu_8=Reboot.=reset
+bootmenu_9=Reset all settings to factory defaults.=run reset_factory ; reset
+boot_first=if button reset ; then run boot_tftp_recovery ; setenv flag_recover 1 ; run boot_default ; fi ; bootmenu
+boot_default=if env exists flag_recover ; then else run bootcmd ; fi ; run boot_recovery ; setenv replacevol 1 ; run boot_tftp_forever
+boot_production=run nor_read_production && bootm $loadaddr
+boot_recovery=run nor_read_recovery ; bootm $loadaddr
+boot_serial_write_fip=loadx $loadaddr 115200 && run boot_write_fip
+boot_serial_write_preloader=loadx $loadaddr 115200 && run boot_write_preloader
+boot_tftp_forever=while true ; do run boot_tftp_recovery ; sleep 1 ; done
+boot_tftp_production=tftpboot $loadaddr $bootfile_upg && env exists replacevol && iminfo $loadaddr && run nor_write_production ; if env exists noboot ; then else bootm $loadaddr ; fi
+boot_tftp_recovery=tftpboot $loadaddr $bootfile && env exists replacevol && iminfo $loadaddr && run nor_write_recovery ; if env exists noboot ; then else bootm $loadaddr ; fi
+boot_tftp=tftpboot $loadaddr $bootfile && bootm $loadaddr
+boot_tftp_write_fip=tftpboot $loadaddr $bootfile_fip && run boot_write_fip
+boot_tftp_write_preloader=tftpboot $loadaddr $bootfile_bl2 && run boot_write_preloader
+boot_nor=run boot_production ; run boot_recovery
+boot_write_fip=mtd erase nor0 0x20000 0x80000 && mtd write nor0 $loadaddr 0x20000 0x80000
+boot_write_preloader=mtd erase nor0 0x0 0x20000 && mtd write nor0 $loadaddr 0x0 0x20000
+reset_factory=mtd erase nor0 0xc0000 0x10000 && reset
+nor_read_production=mtd read nor0 $loadaddr 0x1000000 0x1000 && imsz $loadaddr image_size && mtd read nor0 $loadaddr 0x1000000 $image_size
+nor_read_recovery=mtd read nor0 $loadaddr 0x120000 0x1000 && imsz $loadaddr image_size && mtd read nor0 $loadaddr 0x120000 $image_size
+nor_pad_size=imsz $loadaddr image_size ; setexpr image_eb 0x$image_size / 0x1000 ; setexpr tmp1 0x$image_size % 0x1000 ; test 0x$tmp1 -gt 0 && setexpr image_eb 0x$image_eb + 1 ; setexpr image_eb 0x$image_eb * 0x1000
+nor_write_production=run nor_pad_size ; test 0x$image_eb -le 0x3000000 && mtd erase nor0 0x1000000 0x$image_eb && mtd write nor0 $loadaddr 0x1000000 $filesize
+nor_write_recovery=run nor_pad_size ; test 0x$image_eb -le 0xee0000 && mtd erase nor0 0x120000 0x$image_eb && mtd write nor0 $loadaddr 0x120000 $filesize
+_init_env=setenv _init_env ; saveenv
+_firstboot=setenv _firstboot ; run _switch_to_menu ; run ethaddr_factory ; run _init_env ; run boot_first
+_switch_to_menu=setenv _switch_to_menu ; setenv bootdelay 3 ; setenv bootmenu_delay 3 ; setenv bootmenu_0 $bootmenu_0d ; setenv bootmenu_0d ; run _bootmenu_update_title
+_bootmenu_update_title=setenv _bootmenu_update_title ; setenv bootmenu_title "$bootmenu_title $ver"
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -66,6 +66,7 @@

View File

@ -0,0 +1,413 @@
From: Shiji Yang <yangshiji66@outlook.com>
Date: Tue, 25 Jul 2023 20:05:06 +0800
Subject: [PATCH] wifi: rt2x00: rework MT7620 PA/LNA RF calibration
1. Move MT7620 PA/LNA calibration code to dedicated functions.
2. For external PA/LNA devices, restore RF and BBP registers before
R-Calibration.
3. Do Rx DCOC calibration again before RXIQ calibration.
4. Correct MAC_SYS_CTRL register RX mask to 0x08 in R-Calibration
function. For MAC_SYS_CTRL register, Bit[2] controls MAC_TX_EN
and Bit[3] controls MAC_RX_EN (Bit index starts from 0).
5. Move the channel configuration code from rt2800_vco_calibration()
to the rt2800_config_channel().
6. Use MT7620 SOC specific AGC initial LNA value instead of the
RT5592's value.
7. Adjust the register operation sequence according to the vendor
driver code. This may not be useful, but it can make things
clearer when developers try to review it.
Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
---
.../net/wireless/ralink/rt2x00/rt2800lib.c | 306 ++++++++++--------
drivers/net/wireless/ralink/rt2x00/rt2x00.h | 6 +
2 files changed, 182 insertions(+), 130 deletions(-)
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -3881,14 +3881,6 @@ static void rt2800_config_channel_rf7620
rfcsr |= tx_agc_fc;
rt2800_rfcsr_write_bank(rt2x00dev, 7, 59, rfcsr);
}
-
- if (conf_is_ht40(conf)) {
- rt2800_bbp_glrt_write(rt2x00dev, 141, 0x10);
- rt2800_bbp_glrt_write(rt2x00dev, 157, 0x2f);
- } else {
- rt2800_bbp_glrt_write(rt2x00dev, 141, 0x1a);
- rt2800_bbp_glrt_write(rt2x00dev, 157, 0x40);
- }
}
static void rt2800_config_alc_rt6352(struct rt2x00_dev *rt2x00dev,
@@ -4457,89 +4449,63 @@ static void rt2800_config_channel(struct
usleep_range(1000, 1500);
}
- if (rt2x00_rt(rt2x00dev, RT5592) || rt2x00_rt(rt2x00dev, RT6352)) {
+ if (rt2x00_rt(rt2x00dev, RT5592)) {
reg = 0x10;
- if (!conf_is_ht40(conf)) {
- if (rt2x00_rt(rt2x00dev, RT6352) &&
- rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
- reg |= 0x5;
- } else {
- reg |= 0xa;
- }
- }
+ if (!conf_is_ht40(conf))
+ reg |= 0xa;
rt2800_bbp_write(rt2x00dev, 195, 141);
rt2800_bbp_write(rt2x00dev, 196, reg);
- /* AGC init.
- * Despite the vendor driver using different values here for
- * RT6352 chip, we use 0x1c for now. This may have to be changed
- * once TSSI got implemented.
- */
reg = (rf->channel <= 14 ? 0x1c : 0x24) + 2*rt2x00dev->lna_gain;
rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg);
-
- if (rt2x00_rt(rt2x00dev, RT5592))
- rt2800_iq_calibrate(rt2x00dev, rf->channel);
+
+ rt2800_iq_calibrate(rt2x00dev, rf->channel);
}
if (rt2x00_rt(rt2x00dev, RT6352)) {
- if (test_bit(CAPABILITY_EXTERNAL_PA_TX0,
- &rt2x00dev->cap_flags)) {
- reg = rt2800_register_read(rt2x00dev, RF_CONTROL3);
- reg |= 0x00000101;
- rt2800_register_write(rt2x00dev, RF_CONTROL3, reg);
-
- reg = rt2800_register_read(rt2x00dev, RF_BYPASS3);
- reg |= 0x00000101;
- rt2800_register_write(rt2x00dev, RF_BYPASS3, reg);
-
- rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0x73);
- rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0x73);
- rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0x73);
- rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27);
- rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0xC8);
- rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xA4);
- rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x05);
- rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27);
- rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0xC8);
- rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xA4);
- rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x05);
- rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x27);
- rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0xC8);
- rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xA4);
- rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x05);
- rt2800_rfcsr_write_dccal(rt2x00dev, 05, 0x00);
+ /* BBP for GLRT BW */
+ if (conf_is_ht40(conf)) {
+ rt2800_bbp_glrt_write(rt2x00dev, 141, 0x10);
+ rt2800_bbp_glrt_write(rt2x00dev, 157, 0x2f);
+ } else {
+ rt2800_bbp_glrt_write(rt2x00dev, 141, 0x1a);
+ rt2800_bbp_glrt_write(rt2x00dev, 157, 0x40);
- rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT,
- 0x36303636);
- rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN,
- 0x6C6C6B6C);
- rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN,
- 0x6C6C6B6C);
+ if (rt2800_hw_get_chippkg(rt2x00dev) == 1 &&
+ rt2x00_has_cap_external_lna_bg(rt2x00dev))
+ rt2800_bbp_glrt_write(rt2x00dev, 141, 0x15);
}
- if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
- reg = rt2800_register_read(rt2x00dev, RF_CONTROL3);
- reg |= 0x00000101;
- rt2800_register_write(rt2x00dev, RF_CONTROL3, reg);
-
- reg = rt2800_register_read(rt2x00dev, RF_BYPASS3);
- reg |= 0x00000101;
- rt2800_register_write(rt2x00dev, RF_BYPASS3, reg);
-
- rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x66);
- rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x20);
- rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x42);
- rt2800_bbp_write(rt2x00dev, 75, 0x68);
- rt2800_bbp_write(rt2x00dev, 76, 0x4C);
- rt2800_bbp_write(rt2x00dev, 79, 0x1C);
- rt2800_bbp_write(rt2x00dev, 80, 0x0C);
- rt2800_bbp_write(rt2x00dev, 82, 0xB6);
- /* bank 0 RF reg 42 and glrt BBP reg 141 will be set in
- * config channel function in dependence of channel and
- * HT20/HT40 so don't touch it
- */
+ if (rt2x00dev->default_ant.rx_chain_num == 1) {
+ rt2800_bbp_write(rt2x00dev, 91, 0x07);
+ rt2800_bbp_write(rt2x00dev, 95, 0x1A);
+ rt2800_bbp_write(rt2x00dev, 195, 128);
+ rt2800_bbp_write(rt2x00dev, 196, 0xA0);
+ rt2800_bbp_write(rt2x00dev, 195, 170);
+ rt2800_bbp_write(rt2x00dev, 196, 0x12);
+ rt2800_bbp_write(rt2x00dev, 195, 171);
+ rt2800_bbp_write(rt2x00dev, 196, 0x10);
+ } else {
+ rt2800_bbp_write(rt2x00dev, 91, 0x06);
+ rt2800_bbp_write(rt2x00dev, 95, 0x9A);
+ rt2800_bbp_write(rt2x00dev, 195, 128);
+ rt2800_bbp_write(rt2x00dev, 196, 0xE0);
+ rt2800_bbp_write(rt2x00dev, 195, 170);
+ rt2800_bbp_write(rt2x00dev, 196, 0x30);
+ rt2800_bbp_write(rt2x00dev, 195, 171);
+ rt2800_bbp_write(rt2x00dev, 196, 0x30);
}
+
+ /* AGC init */
+ reg = rf->channel <= 14 ? 0x04 + 2 * rt2x00dev->lna_gain : 0;
+ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg);
+
+ /* On 11A, We should delay and wait RF/BBP to be stable
+ * and the appropriate time should be 1000 micro seconds
+ * 2005/06/05 - On 11G, we also need this delay time.
+ * Otherwise it's difficult to pass the WHQL.
+ */
+ usleep_range(1000, 1500);
}
bbp = rt2800_bbp_read(rt2x00dev, 4);
@@ -5649,43 +5615,6 @@ void rt2800_vco_calibration(struct rt2x0
}
}
rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
-
- if (rt2x00_rt(rt2x00dev, RT6352)) {
- if (rt2x00dev->default_ant.rx_chain_num == 1) {
- rt2800_bbp_write(rt2x00dev, 91, 0x07);
- rt2800_bbp_write(rt2x00dev, 95, 0x1A);
- rt2800_bbp_write(rt2x00dev, 195, 128);
- rt2800_bbp_write(rt2x00dev, 196, 0xA0);
- rt2800_bbp_write(rt2x00dev, 195, 170);
- rt2800_bbp_write(rt2x00dev, 196, 0x12);
- rt2800_bbp_write(rt2x00dev, 195, 171);
- rt2800_bbp_write(rt2x00dev, 196, 0x10);
- } else {
- rt2800_bbp_write(rt2x00dev, 91, 0x06);
- rt2800_bbp_write(rt2x00dev, 95, 0x9A);
- rt2800_bbp_write(rt2x00dev, 195, 128);
- rt2800_bbp_write(rt2x00dev, 196, 0xE0);
- rt2800_bbp_write(rt2x00dev, 195, 170);
- rt2800_bbp_write(rt2x00dev, 196, 0x30);
- rt2800_bbp_write(rt2x00dev, 195, 171);
- rt2800_bbp_write(rt2x00dev, 196, 0x30);
- }
-
- if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
- rt2800_bbp_write(rt2x00dev, 75, 0x68);
- rt2800_bbp_write(rt2x00dev, 76, 0x4C);
- rt2800_bbp_write(rt2x00dev, 79, 0x1C);
- rt2800_bbp_write(rt2x00dev, 80, 0x0C);
- rt2800_bbp_write(rt2x00dev, 82, 0xB6);
- }
-
- /* On 11A, We should delay and wait RF/BBP to be stable
- * and the appropriate time should be 1000 micro seconds
- * 2005/06/05 - On 11G, we also need this delay time.
- * Otherwise it's difficult to pass the WHQL.
- */
- usleep_range(1000, 1500);
- }
}
EXPORT_SYMBOL_GPL(rt2800_vco_calibration);
@@ -8650,7 +8579,7 @@ static void rt2800_r_calibration(struct
rt2x00_warn(rt2x00dev, "Wait MAC Tx Status to MAX !!!\n");
maccfg = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
- maccfg &= (~0x04);
+ maccfg &= (~0x08);
rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, maccfg);
if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY_RX)))
@@ -10688,30 +10617,143 @@ static void rt2800_init_rfcsr_6352(struc
rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C);
}
+}
- rt6352_enable_pa_pin(rt2x00dev, 0);
- rt2800_r_calibration(rt2x00dev);
- rt2800_rf_self_txdc_cal(rt2x00dev);
- rt2800_rxdcoc_calibration(rt2x00dev);
- rt2800_bw_filter_calibration(rt2x00dev, true);
- rt2800_bw_filter_calibration(rt2x00dev, false);
- rt2800_loft_iq_calibration(rt2x00dev);
- rt2800_rxiq_calibration(rt2x00dev);
- rt6352_enable_pa_pin(rt2x00dev, 1);
+static void rt2800_init_palna_rt6352(struct rt2x00_dev *rt2x00dev)
+{
+ u32 reg;
+
+ if (rt2x00_has_cap_external_pa(rt2x00dev)) {
+ reg = rt2800_register_read(rt2x00dev, RF_CONTROL3);
+ reg |= 0x00000101;
+ rt2800_register_write(rt2x00dev, RF_CONTROL3, reg);
+
+ reg = rt2800_register_read(rt2x00dev, RF_BYPASS3);
+ reg |= 0x00000101;
+ rt2800_register_write(rt2x00dev, RF_BYPASS3, reg);
+ }
- if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
+ if (rt2800_hw_get_chippkg(rt2x00dev) == 1 &&
+ rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x66);
rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x20);
rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x42);
+ }
+
+ if (rt2800_hw_get_chippkg(rt2x00dev) == 1 &&
+ rt2x00_has_cap_external_pa(rt2x00dev)) {
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0x73);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0x73);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0x73);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0xC8);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xA4);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x05);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0xC8);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xA4);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x05);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x27);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0xC8);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xA4);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x05);
+ }
+
+ if (rt2800_hw_get_chippkg(rt2x00dev) == 1 &&
+ rt2x00_has_cap_external_pa(rt2x00dev))
+ rt2800_rfcsr_write_dccal(rt2x00dev, 05, 0x00);
+
+ if (rt2800_hw_get_chippkg(rt2x00dev) == 1 &&
+ rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
rt2800_bbp_write(rt2x00dev, 75, 0x68);
rt2800_bbp_write(rt2x00dev, 76, 0x4C);
rt2800_bbp_write(rt2x00dev, 79, 0x1C);
rt2800_bbp_write(rt2x00dev, 80, 0x0C);
rt2800_bbp_write(rt2x00dev, 82, 0xB6);
- /* bank 0 RF reg 42 and glrt BBP reg 141 will be set in config
- * channel function in dependence of channel and HT20/HT40,
- * so don't touch them here.
- */
+ }
+
+ if (rt2800_hw_get_chippkg(rt2x00dev) == 1 &&
+ rt2x00_has_cap_external_pa(rt2x00dev)) {
+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT, 0x36303636);
+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN, 0x6C6C6B6C);
+ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN, 0x6C6C6B6C);
+ }
+}
+
+static void rt2800_restore_rf_bbp_rt6352(struct rt2x00_dev *rt2x00dev)
+{
+ if (rt2x00_has_cap_external_pa(rt2x00dev)) {
+ rt2800_register_write(rt2x00dev, RF_CONTROL3, 0x0);
+ rt2800_register_write(rt2x00dev, RF_BYPASS3, 0x0);
+ }
+
+ if (rt2800_hw_get_chippkg(rt2x00dev) == 1 &&
+ rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x16);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x23);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x02);
+ }
+
+ if (rt2800_hw_get_chippkg(rt2x00dev) == 1 &&
+ rt2x00_has_cap_external_pa(rt2x00dev)) {
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xB3);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xD5);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x6C);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFC);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1F);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xFF);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x1C);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x20);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xF7);
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x09);
+ }
+
+ if (rt2800_hw_get_chippkg(rt2x00dev) == 1 &&
+ rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
+ rt2800_bbp_write(rt2x00dev, 75, 0x60);
+ rt2800_bbp_write(rt2x00dev, 76, 0x44);
+ rt2800_bbp_write(rt2x00dev, 79, 0x1C);
+ rt2800_bbp_write(rt2x00dev, 80, 0x0C);
+ rt2800_bbp_write(rt2x00dev, 82, 0xB6);
+ }
+
+ if (rt2800_hw_get_chippkg(rt2x00dev) == 1 &&
+ rt2x00_has_cap_external_pa(rt2x00dev)) {
+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT, 0x3630363A);
+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN, 0x6C6C666C);
+ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN, 0x6C6C666C);
+ }
+}
+
+static void rt2800_calibration_rt6352(struct rt2x00_dev *rt2x00dev)
+{
+ if (rt2x00_has_cap_external_pa(rt2x00dev) ||
+ rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
+ rt6352_enable_pa_pin(rt2x00dev, 0);
+ rt2800_restore_rf_bbp_rt6352(rt2x00dev);
+ }
+
+ rt2800_r_calibration(rt2x00dev);
+ rt2800_rf_self_txdc_cal(rt2x00dev);
+ rt2800_rxdcoc_calibration(rt2x00dev);
+ rt2800_bw_filter_calibration(rt2x00dev, true);
+ rt2800_bw_filter_calibration(rt2x00dev, false);
+ rt2800_loft_iq_calibration(rt2x00dev);
+
+ /* missing DPD Calibration for devices using internal PA */
+
+ rt2800_rxdcoc_calibration(rt2x00dev);
+ rt2800_rxiq_calibration(rt2x00dev);
+
+ if (rt2x00_has_cap_external_pa(rt2x00dev) ||
+ rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
+ rt6352_enable_pa_pin(rt2x00dev, 1);
+ rt2800_init_palna_rt6352(rt2x00dev);
}
}
@@ -10804,6 +10846,10 @@ int rt2800_enable_radio(struct rt2x00_de
rt2800_init_bbp(rt2x00dev);
rt2800_init_rfcsr(rt2x00dev);
+ /* Do calibration and init PA/LNA for RT6352 */
+ if (rt2x00_rt(rt2x00dev, RT6352))
+ rt2800_calibration_rt6352(rt2x00dev);
+
if (rt2x00_is_usb(rt2x00dev) &&
(rt2x00_rt(rt2x00dev, RT3070) ||
rt2x00_rt(rt2x00dev, RT3071) ||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
@@ -1277,6 +1277,12 @@ rt2x00_has_cap_external_lna_bg(struct rt
}
static inline bool
+rt2x00_has_cap_external_pa(struct rt2x00_dev *rt2x00dev)
+{
+ return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_EXTERNAL_PA_TX0);
+}
+
+static inline bool
rt2x00_has_cap_double_antenna(struct rt2x00_dev *rt2x00dev)
{
return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_DOUBLE_ANTENNA);

View File

@ -17,7 +17,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -5889,6 +5889,9 @@ int __init cgroup_init_early(void)
@@ -5890,6 +5890,9 @@ int __init cgroup_init_early(void)
return 0;
}
@ -27,7 +27,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
/**
* cgroup_init - cgroup initialization
*
@@ -5927,6 +5930,12 @@ int __init cgroup_init(void)
@@ -5928,6 +5931,12 @@ int __init cgroup_init(void)
mutex_unlock(&cgroup_mutex);
@ -40,7 +40,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
for_each_subsys(ss, ssid) {
if (ss->early_init) {
struct cgroup_subsys_state *css =
@@ -6516,6 +6525,10 @@ static int __init cgroup_disable(char *s
@@ -6520,6 +6529,10 @@ static int __init cgroup_disable(char *s
strcmp(token, ss->legacy_name))
continue;
@ -51,7 +51,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
static_branch_disable(cgroup_subsys_enabled_key[i]);
pr_info("Disabling %s control group subsystem\n",
ss->name);
@@ -6534,6 +6547,31 @@ static int __init cgroup_disable(char *s
@@ -6538,6 +6551,31 @@ static int __init cgroup_disable(char *s
}
__setup("cgroup_disable=", cgroup_disable);

View File

@ -244,7 +244,7 @@ bcm2835-mmc: uninitialized_var is no more
static inline int mmc_blk_part_switch(struct mmc_card *card,
unsigned int part_type);
static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
@@ -2941,6 +2948,8 @@ static int mmc_blk_probe(struct mmc_card
@@ -2942,6 +2949,8 @@ static int mmc_blk_probe(struct mmc_card
{
struct mmc_blk_data *md;
int ret = 0;
@ -253,7 +253,7 @@ bcm2835-mmc: uninitialized_var is no more
/*
* Check that the card supports the command class(es) we need.
@@ -2948,7 +2957,16 @@ static int mmc_blk_probe(struct mmc_card
@@ -2949,7 +2958,16 @@ static int mmc_blk_probe(struct mmc_card
if (!(card->csd.cmdclass & CCC_BLOCK_READ))
return -ENODEV;
@ -271,7 +271,7 @@ bcm2835-mmc: uninitialized_var is no more
card->complete_wq = alloc_workqueue("mmc_complete",
WQ_MEM_RECLAIM | WQ_HIGHPRI, 0);
@@ -2963,6 +2981,17 @@ static int mmc_blk_probe(struct mmc_card
@@ -2964,6 +2982,17 @@ static int mmc_blk_probe(struct mmc_card
goto out_free;
}

View File

@ -156,7 +156,7 @@ See: https://github.com/raspberrypi/linux/issues/1064
+MODULE_LICENSE("GPL");
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -85,6 +85,9 @@ struct led_classdev {
@@ -95,6 +95,9 @@ struct led_classdev {
#define LED_BRIGHT_HW_CHANGED BIT(21)
#define LED_RETAIN_AT_SHUTDOWN BIT(22)
#define LED_INIT_DEFAULT_TRIGGER BIT(23)

View File

@ -33,7 +33,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.org>
#define USB_VENDOR_ID_BELKIN 0x050d
#define USB_DEVICE_ID_FLIP_KVM 0x3201
@@ -1317,6 +1320,9 @@
@@ -1318,6 +1321,9 @@
#define USB_VENDOR_ID_XAT 0x2505
#define USB_DEVICE_ID_XAT_CSR 0x0220
@ -53,7 +53,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.org>
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH), HID_QUIRK_MULTI_INPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE2), HID_QUIRK_ALWAYS_POLL },
@@ -197,6 +198,7 @@ static const struct hid_device_id hid_qu
@@ -198,6 +199,7 @@ static const struct hid_device_id hid_qu
{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD), HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_XIN_MO_DUAL_ARCADE), HID_QUIRK_MULTI_INPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_GROUP_AUDIO), HID_QUIRK_NOGET },

View File

@ -26,7 +26,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.org>
return;
val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_SCR3);
@@ -753,7 +754,7 @@ static struct phy_driver broadcom_driver
@@ -764,7 +765,7 @@ static struct phy_driver broadcom_driver
.handle_interrupt = bcm_phy_handle_interrupt,
}, {
.phy_id = PHY_ID_BCM54210E,
@ -35,7 +35,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.org>
.name = "Broadcom BCM54210E",
/* PHY_GBIT_FEATURES */
.get_sset_count = bcm_phy_get_sset_count,
@@ -764,6 +765,13 @@ static struct phy_driver broadcom_driver
@@ -775,6 +776,13 @@ static struct phy_driver broadcom_driver
.config_intr = bcm_phy_config_intr,
.handle_interrupt = bcm_phy_handle_interrupt,
}, {
@ -49,7 +49,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.org>
.phy_id = PHY_ID_BCM5461,
.phy_id_mask = 0xfffffff0,
.name = "Broadcom BCM5461",
@@ -962,7 +970,8 @@ module_phy_driver(broadcom_drivers);
@@ -975,7 +983,8 @@ module_phy_driver(broadcom_drivers);
static struct mdio_device_id __maybe_unused broadcom_tbl[] = {
{ PHY_ID_BCM5411, 0xfffffff0 },
{ PHY_ID_BCM5421, 0xfffffff0 },

View File

@ -55,7 +55,7 @@ Signed-off-by: Maxime Ripard <maxime@cerno.tech>
KUNIT_CASE(clk_test_orphan_transparent_multiple_parent_mux_set_parent_set_range_modified),
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -829,8 +829,9 @@ int clk_set_parent(struct clk *clk, stru
@@ -837,8 +837,9 @@ int clk_set_parent(struct clk *clk, stru
* clk_get_parent - get the parent clock source for this clock
* @clk: clock source
*

View File

@ -55,7 +55,7 @@ Signed-off-by: Maxime Ripard <maxime@cerno.tech>
*
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -799,6 +799,17 @@ bool clk_has_parent(struct clk *clk, str
@@ -807,6 +807,17 @@ bool clk_has_parent(struct clk *clk, str
int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max);
/**

View File

@ -8,7 +8,7 @@ This fixes OpenWrt ticket #1485: https://dev.openwrt.org/ticket/1485
---
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -240,6 +240,9 @@
@@ -257,6 +257,9 @@
#ifndef cpu_has_pindexed_dcache
#define cpu_has_pindexed_dcache (cpu_data[0].dcache.flags & MIPS_CACHE_PINDEX)
#endif

View File

@ -0,0 +1,35 @@
From 8110437e59616293228cd781c486d8495a61e36a Mon Sep 17 00:00:00 2001
From: Yan Cangang <nalanzeyu@gmail.com>
Date: Sun, 20 Nov 2022 13:52:58 +0800
Subject: [PATCH] net: ethernet: mtk_eth_soc: fix resource leak in error path
In mtk_probe(), when mtk_ppe_init() or mtk_eth_offload_init() failed,
mtk_mdio_cleanup() isn't called. Fix it.
Fixes: ba37b7caf1ed ("net: ethernet: mtk_eth_soc: add support for initializing the PPE")
Fixes: 502e84e2382d ("net: ethernet: mtk_eth_soc: add flow offloading support")
Signed-off-by: Yan Cangang <nalanzeyu@gmail.com>
Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -4087,13 +4087,13 @@ static int mtk_probe(struct platform_dev
eth->soc->offload_version, i);
if (!eth->ppe[i]) {
err = -ENOMEM;
- goto err_free_dev;
+ goto err_deinit_mdio;
}
}
err = mtk_eth_offload_init(eth);
if (err)
- goto err_free_dev;
+ goto err_deinit_mdio;
}
for (i = 0; i < MTK_MAX_DEVS; i++) {

View File

@ -0,0 +1,107 @@
From 603ea5e7ffa73c7fac07d8713d97285990695213 Mon Sep 17 00:00:00 2001
From: Yan Cangang <nalanzeyu@gmail.com>
Date: Sun, 20 Nov 2022 13:52:59 +0800
Subject: [PATCH] net: ethernet: mtk_eth_soc: fix memory leak in error path
In mtk_ppe_init(), when dmam_alloc_coherent() or devm_kzalloc() failed,
the rhashtable ppe->l2_flows isn't destroyed. Fix it.
In mtk_probe(), when mtk_ppe_init() or mtk_eth_offload_init() or
register_netdev() failed, have the same problem. Fix it.
Fixes: 33fc42de3327 ("net: ethernet: mtk_eth_soc: support creating mac address based offload entries")
Signed-off-by: Yan Cangang <nalanzeyu@gmail.com>
Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 9 +++++----
drivers/net/ethernet/mediatek/mtk_ppe.c | 19 +++++++++++++++++--
drivers/net/ethernet/mediatek/mtk_ppe.h | 1 +
3 files changed, 23 insertions(+), 6 deletions(-)
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -4087,13 +4087,13 @@ static int mtk_probe(struct platform_dev
eth->soc->offload_version, i);
if (!eth->ppe[i]) {
err = -ENOMEM;
- goto err_deinit_mdio;
+ goto err_deinit_ppe;
}
}
err = mtk_eth_offload_init(eth);
if (err)
- goto err_deinit_mdio;
+ goto err_deinit_ppe;
}
for (i = 0; i < MTK_MAX_DEVS; i++) {
@@ -4103,7 +4103,7 @@ static int mtk_probe(struct platform_dev
err = register_netdev(eth->netdev[i]);
if (err) {
dev_err(eth->dev, "error bringing up device\n");
- goto err_deinit_mdio;
+ goto err_deinit_ppe;
} else
netif_info(eth, probe, eth->netdev[i],
"mediatek frame engine at 0x%08lx, irq %d\n",
@@ -4123,7 +4123,8 @@ static int mtk_probe(struct platform_dev
return 0;
-err_deinit_mdio:
+err_deinit_ppe:
+ mtk_ppe_deinit(eth);
mtk_mdio_cleanup(eth);
err_free_dev:
mtk_free_dev(eth);
--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
@@ -743,7 +743,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
MTK_PPE_ENTRIES * soc->foe_entry_size,
&ppe->foe_phys, GFP_KERNEL);
if (!foe)
- return NULL;
+ goto err_free_l2_flows;
ppe->foe_table = foe;
@@ -751,11 +751,26 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
sizeof(*ppe->foe_flow);
ppe->foe_flow = devm_kzalloc(dev, foe_flow_size, GFP_KERNEL);
if (!ppe->foe_flow)
- return NULL;
+ goto err_free_l2_flows;
mtk_ppe_debugfs_init(ppe, index);
return ppe;
+
+err_free_l2_flows:
+ rhashtable_destroy(&ppe->l2_flows);
+ return NULL;
+}
+
+void mtk_ppe_deinit(struct mtk_eth *eth)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(eth->ppe); i++) {
+ if (!eth->ppe[i])
+ return;
+ rhashtable_destroy(&eth->ppe[i]->l2_flows);
+ }
}
static void mtk_ppe_init_foe_table(struct mtk_ppe *ppe)
--- a/drivers/net/ethernet/mediatek/mtk_ppe.h
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
@@ -304,6 +304,7 @@ struct mtk_ppe {
struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
int version, int index);
+void mtk_ppe_deinit(struct mtk_eth *eth);
void mtk_ppe_start(struct mtk_ppe *ppe);
int mtk_ppe_stop(struct mtk_ppe *ppe);

View File

@ -237,8 +237,8 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
{
--- a/drivers/net/ethernet/mediatek/mtk_ppe.h
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
@@ -306,6 +306,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
int version, int index);
@@ -307,6 +307,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
void mtk_ppe_deinit(struct mtk_eth *eth);
void mtk_ppe_start(struct mtk_ppe *ppe);
int mtk_ppe_stop(struct mtk_ppe *ppe);
+int mtk_ppe_prepare_reset(struct mtk_ppe *ppe);

View File

@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -4421,7 +4421,7 @@ static const struct mtk_soc_data mt7621_
@@ -4422,7 +4422,7 @@ static const struct mtk_soc_data mt7621_
.hw_features = MTK_HW_FEATURES,
.required_clks = MT7621_CLKS_BITMAP,
.required_pctl = false,
@ -21,7 +21,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
.hash_offset = 2,
.foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
.txrx = {
@@ -4460,7 +4460,7 @@ static const struct mtk_soc_data mt7623_
@@ -4461,7 +4461,7 @@ static const struct mtk_soc_data mt7623_
.hw_features = MTK_HW_FEATURES,
.required_clks = MT7623_CLKS_BITMAP,
.required_pctl = true,

View File

@ -47,7 +47,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
#define MTK_FOE_IB2_DEST_PORT_V2 GENMASK(12, 9)
#define MTK_FOE_IB2_MULTICAST_V2 BIT(13)
#define MTK_FOE_IB2_WDMA_WINFO_V2 BIT(19)
@@ -351,6 +353,8 @@ int mtk_foe_entry_set_pppoe(struct mtk_e
@@ -352,6 +354,8 @@ int mtk_foe_entry_set_pppoe(struct mtk_e
int sid);
int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry,
int wdma_idx, int txq, int bss, int wcid);

View File

@ -1,28 +0,0 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Thu, 27 Oct 2022 23:39:52 +0200
Subject: [PATCH] net: ethernet: mtk_eth_soc: compile out netsys v2 code
on mt7621
Avoid some branches in the hot path on low-end devices with limited CPU power,
and reduce code size
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -917,7 +917,13 @@ enum mkt_eth_capabilities {
#define MTK_MUX_GMAC12_TO_GEPHY_SGMII \
(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX)
-#define MTK_HAS_CAPS(caps, _x) (((caps) & (_x)) == (_x))
+#ifdef CONFIG_SOC_MT7621
+#define MTK_CAP_MASK MTK_NETSYS_V2
+#else
+#define MTK_CAP_MASK 0
+#endif
+
+#define MTK_HAS_CAPS(caps, _x) (((caps) & (_x) & ~(MTK_CAP_MASK)) == (_x))
#define MT7621_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \
MTK_GMAC2_RGMII | MTK_SHARED_INT | \

View File

@ -181,7 +181,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
/* CDMP Ingress Control Register */
#define MTK_CDMP_IG_CTRL 0x400
#define MTK_CDMP_STAG_EN BIT(0)
@@ -1166,6 +1172,8 @@ struct mtk_eth {
@@ -1160,6 +1166,8 @@ struct mtk_eth {
int ip_align;

View File

@ -34,7 +34,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -1070,11 +1070,13 @@ struct mtk_soc_data {
@@ -1064,11 +1064,13 @@ struct mtk_soc_data {
* @regmap: The register map pointing at the range used to setup
* SGMII modes
* @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap

View File

@ -51,7 +51,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
mtk_eth_path_name(path), __func__, updated);
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -4748,6 +4748,26 @@ static const struct mtk_soc_data mt7629_
@@ -4749,6 +4749,26 @@ static const struct mtk_soc_data mt7629_
},
};
@ -78,7 +78,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
static const struct mtk_soc_data mt7986_data = {
.reg_map = &mt7986_reg_map,
.ana_rgc3 = 0x128,
@@ -4790,6 +4810,7 @@ const struct of_device_id of_mtk_match[]
@@ -4791,6 +4811,7 @@ const struct of_device_id of_mtk_match[]
{ .compatible = "mediatek,mt7622-eth", .data = &mt7622_data},
{ .compatible = "mediatek,mt7623-eth", .data = &mt7623_data},
{ .compatible = "mediatek,mt7629-eth", .data = &mt7629_data},
@ -145,7 +145,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
#define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \
BIT(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
@@ -963,6 +987,11 @@ enum mkt_eth_capabilities {
@@ -957,6 +981,11 @@ enum mkt_eth_capabilities {
MTK_MUX_U3_GMAC2_TO_QPHY | \
MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA)
@ -157,7 +157,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
#define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
@@ -1076,12 +1105,14 @@ struct mtk_soc_data {
@@ -1070,12 +1099,14 @@ struct mtk_soc_data {
* @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap
* @interface: Currently configured interface mode
* @pcs: Phylink PCS structure

View File

@ -151,7 +151,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
}
if (eth->soc->offload_version) {
@@ -4648,6 +4685,8 @@ err_deinit_hw:
@@ -4649,6 +4686,8 @@ err_deinit_hw:
mtk_hw_deinit(eth);
err_wed_exit:
mtk_wed_exit();
@ -228,7 +228,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
/* Infrasys subsystem config registers */
#define INFRA_MISC2 0x70c
#define CO_QPHY_SEL BIT(0)
@@ -1105,31 +1046,6 @@ struct mtk_soc_data {
@@ -1099,31 +1040,6 @@ struct mtk_soc_data {
/* currently no SoC has more than 2 macs */
#define MTK_MAX_DEVS 2
@ -260,7 +260,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
/* struct mtk_eth - This is the main datasructure for holding the state
* of the driver
* @dev: The device pointer
@@ -1149,6 +1065,7 @@ struct mtk_sgmii {
@@ -1143,6 +1059,7 @@ struct mtk_sgmii {
* MII modes
* @infra: The register map pointing at the range used to setup
* SGMII and GePHY path
@ -268,7 +268,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
* @pctl: The register map pointing at the range used to setup
* GMAC port drive/slew values
* @dma_refcnt: track how many netdevs are using the DMA engine
@@ -1189,8 +1106,8 @@ struct mtk_eth {
@@ -1183,8 +1100,8 @@ struct mtk_eth {
u32 msg_enable;
unsigned long sysclk;
struct regmap *ethsys;
@ -279,7 +279,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
struct regmap *pctl;
bool hwlro;
refcount_t dma_refcnt;
@@ -1352,10 +1269,6 @@ void mtk_stats_update_mac(struct mtk_mac
@@ -1346,10 +1263,6 @@ void mtk_stats_update_mac(struct mtk_mac
void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg);
u32 mtk_r32(struct mtk_eth *eth, unsigned reg);

View File

@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
@@ -523,6 +523,7 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
@@ -464,6 +464,7 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
hwe->ib1 &= ~MTK_FOE_IB1_STATE;
hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID);
dma_wmb();

View File

@ -63,8 +63,8 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov
+
if (!eth->ppe[i]) {
err = -ENOMEM;
goto err_free_dev;
@@ -4763,6 +4763,7 @@ static const struct mtk_soc_data mt7622_
goto err_deinit_ppe;
@@ -4762,6 +4762,7 @@ static const struct mtk_soc_data mt7622_
.required_pctl = false,
.offload_version = 2,
.hash_offset = 2,
@ -72,7 +72,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov
.foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
@@ -4800,6 +4801,7 @@ static const struct mtk_soc_data mt7629_
@@ -4799,6 +4800,7 @@ static const struct mtk_soc_data mt7629_
.hw_features = MTK_HW_FEATURES,
.required_clks = MT7629_CLKS_BITMAP,
.required_pctl = false,
@ -80,7 +80,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
@@ -4820,6 +4822,7 @@ static const struct mtk_soc_data mt7981_
@@ -4819,6 +4821,7 @@ static const struct mtk_soc_data mt7981_
.offload_version = 2,
.hash_offset = 4,
.foe_entry_size = sizeof(struct mtk_foe_entry),
@ -88,7 +88,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma_v2),
.rxd_size = sizeof(struct mtk_rx_dma_v2),
@@ -4840,6 +4843,7 @@ static const struct mtk_soc_data mt7986_
@@ -4839,6 +4842,7 @@ static const struct mtk_soc_data mt7986_
.offload_version = 2,
.hash_offset = 4,
.foe_entry_size = sizeof(struct mtk_foe_entry),
@ -98,7 +98,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov
.rxd_size = sizeof(struct mtk_rx_dma_v2),
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -1014,6 +1014,8 @@ struct mtk_reg_map {
@@ -1008,6 +1008,8 @@ struct mtk_reg_map {
* the extra setup for those pins used by GMAC.
* @hash_offset Flow table hash offset.
* @foe_entry_size Foe table entry size.
@ -107,7 +107,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov
* @txd_size Tx DMA descriptor size.
* @rxd_size Rx DMA descriptor size.
* @rx_irq_done_mask Rx irq done register mask.
@@ -1031,6 +1033,7 @@ struct mtk_soc_data {
@@ -1025,6 +1027,7 @@ struct mtk_soc_data {
u8 hash_offset;
u16 foe_entry_size;
netdev_features_t hw_features;
@ -166,10 +166,10 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov
static void mtk_ppe_cache_clear(struct mtk_ppe *ppe)
{
ppe_set(ppe, MTK_PPE_CACHE_CTL, MTK_PPE_CACHE_CTL_CLEAR);
@@ -464,6 +506,13 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
hwe->ib1 &= ~MTK_FOE_IB1_STATE;
@@ -465,6 +507,13 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID);
dma_wmb();
mtk_ppe_cache_clear(ppe);
+ if (ppe->accounting) {
+ struct mtk_foe_accounting *acct;
+
@ -180,7 +180,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov
}
entry->hash = 0xffff;
@@ -571,6 +620,9 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
@@ -572,6 +621,9 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
wmb();
hwe->ib1 = entry->ib1;
@ -190,7 +190,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov
dma_wmb();
mtk_ppe_cache_clear(ppe);
@@ -762,11 +814,39 @@ int mtk_ppe_prepare_reset(struct mtk_ppe
@@ -763,11 +815,39 @@ int mtk_ppe_prepare_reset(struct mtk_ppe
return mtk_ppe_wait_busy(ppe);
}
@ -232,7 +232,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov
struct mtk_ppe *ppe;
u32 foe_flow_size;
void *foe;
@@ -783,7 +863,8 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
@@ -784,7 +864,8 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
ppe->base = base;
ppe->eth = eth;
ppe->dev = dev;
@ -242,9 +242,9 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov
foe = dmam_alloc_coherent(ppe->dev,
MTK_PPE_ENTRIES * soc->foe_entry_size,
@@ -799,6 +880,23 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
@@ -800,6 +881,23 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
if (!ppe->foe_flow)
return NULL;
goto err_free_l2_flows;
+ if (accounting) {
+ mib = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*mib),
@ -266,7 +266,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov
mtk_ppe_debugfs_init(ppe, index);
return ppe;
@@ -913,6 +1011,16 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
@@ -929,6 +1027,16 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777);
ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f);
}
@ -335,10 +335,10 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov
-struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
- int version, int index);
+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index);
void mtk_ppe_deinit(struct mtk_eth *eth);
void mtk_ppe_start(struct mtk_ppe *ppe);
int mtk_ppe_stop(struct mtk_ppe *ppe);
int mtk_ppe_prepare_reset(struct mtk_ppe *ppe);
@@ -358,5 +376,7 @@ int mtk_foe_entry_commit(struct mtk_ppe
@@ -359,5 +377,7 @@ int mtk_foe_entry_commit(struct mtk_ppe
void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index);

View File

@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
@@ -646,6 +646,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
@@ -605,6 +605,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
struct mtk_eth *eth = ppe->eth;
u16 timestamp = mtk_eth_timestamp(eth);
struct mtk_foe_entry *hwe;
@ -19,7 +19,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP_V2;
@@ -662,8 +663,13 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
@@ -621,8 +622,13 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
wmb();
hwe->ib1 = entry->ib1;

View File

@ -0,0 +1,31 @@
From b804f765485109f9644cc05d1e8fc79ca6c6e4aa Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Wed, 19 Jul 2023 01:39:36 +0100
Subject: [PATCH 094/250] net: ethernet: mtk_eth_soc: always
mtk_get_ib1_pkt_type
entries and bind debugfs files would display wrong data on NETSYS_V2 and
later because instead of using mtk_get_ib1_pkt_type the driver would use
MTK_FOE_IB1_PACKET_TYPE which corresponds to NETSYS_V1(.x) SoCs.
Use mtk_get_ib1_pkt_type so entries and bind records display correctly.
Fixes: 03a3180e5c09e ("net: ethernet: mtk_eth_soc: introduce flow offloading support for mt7986")
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://lore.kernel.org/r/c0ae03d0182f4d27b874cbdf0059bc972c317f3c.1689727134.git.daniel@makrotopia.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
@@ -98,7 +98,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file
acct = mtk_foe_entry_get_mib(ppe, i, NULL);
- type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
+ type = mtk_get_ib1_pkt_type(ppe->eth, entry->ib1);
seq_printf(m, "%05x %s %7s", i,
mtk_foe_entry_state_str(state),
mtk_foe_pkt_type_str(type));

View File

@ -0,0 +1,78 @@
From 5ea0e1312bcfebc06b5f91d1bb82b823d6395125 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Wed, 19 Jul 2023 12:29:49 +0200
Subject: [PATCH 095/250] net: ethernet: mtk_ppe: add MTK_FOE_ENTRY_V{1,2}_SIZE
macros
Introduce MTK_FOE_ENTRY_V{1,2}_SIZE macros in order to make more
explicit foe_entry size for different chipset revisions.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 10 +++++-----
drivers/net/ethernet/mediatek/mtk_ppe.h | 3 +++
2 files changed, 8 insertions(+), 5 deletions(-)
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -4711,7 +4711,7 @@ static const struct mtk_soc_data mt7621_
.required_pctl = false,
.offload_version = 1,
.hash_offset = 2,
- .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
+ .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
@@ -4732,7 +4732,7 @@ static const struct mtk_soc_data mt7622_
.offload_version = 2,
.hash_offset = 2,
.has_accounting = true,
- .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
+ .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
@@ -4751,7 +4751,7 @@ static const struct mtk_soc_data mt7623_
.required_pctl = true,
.offload_version = 1,
.hash_offset = 2,
- .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
+ .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
@@ -4789,8 +4789,8 @@ static const struct mtk_soc_data mt7981_
.required_pctl = false,
.offload_version = 2,
.hash_offset = 4,
- .foe_entry_size = sizeof(struct mtk_foe_entry),
.has_accounting = true,
+ .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma_v2),
.rxd_size = sizeof(struct mtk_rx_dma_v2),
@@ -4810,8 +4810,8 @@ static const struct mtk_soc_data mt7986_
.required_pctl = false,
.offload_version = 2,
.hash_offset = 4,
- .foe_entry_size = sizeof(struct mtk_foe_entry),
.has_accounting = true,
+ .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma_v2),
.rxd_size = sizeof(struct mtk_rx_dma_v2),
--- a/drivers/net/ethernet/mediatek/mtk_ppe.h
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
@@ -216,6 +216,9 @@ struct mtk_foe_ipv6_6rd {
struct mtk_foe_mac_info l2;
};
+#define MTK_FOE_ENTRY_V1_SIZE 80
+#define MTK_FOE_ENTRY_V2_SIZE 96
+
struct mtk_foe_entry {
u32 ib1;

View File

@ -0,0 +1,141 @@
From 8cfa2576d79f9379d167a8994f0fca935c07a8bc Mon Sep 17 00:00:00 2001
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
Date: Sat, 22 Jul 2023 21:32:49 +0100
Subject: [PATCH 096/250] net: ethernet: mtk_eth_soc: remove incorrect PLL
configuration
MT7623 GMAC0 attempts to configure the system clocking according to the
required speed in the .mac_config callback for non-SGMII, non-baseX and
non-TRGMII modes.
state->speed setting has never been reliable in the .mac_config
callback - there are cases where this is not the link speed,
particularly via ethtool paths, so this has always been unreliable (as
detailed in phylink's documentation.)
There is the additional issue that mtk_gmac0_rgmii_adjust() will only
be called if state->interface changes, which means it only configures
the system clocking on the very first .mac_config call, which will be
made when the network device is first brought up before any link is
established.
Essentially, this code is incredibly buggy, and probably never worked.
Moreover, checking the in-kernel DT files, it seems no platform makes
use of this code path.
Therefore, let's remove it, and disable interface modes for port 0 that
are not SGMII, 1000base-X, 2500base-X or TRGMII on the MT7623.
Reviewed-by: Daniel Golle <daniel@makrotopia.org>
Tested-by: Daniel Golle <daniel@makrotopia.org>
Tested-by: Frank Wunderlich <frank-w@public-files.de>
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 54 ++++++---------------
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 +
2 files changed, 17 insertions(+), 38 deletions(-)
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -309,7 +309,7 @@ static int mt7621_gmac0_rgmii_adjust(str
}
static void mtk_gmac0_rgmii_adjust(struct mtk_eth *eth,
- phy_interface_t interface, int speed)
+ phy_interface_t interface)
{
u32 val;
int ret;
@@ -323,26 +323,7 @@ static void mtk_gmac0_rgmii_adjust(struc
return;
}
- val = (speed == SPEED_1000) ?
- INTF_MODE_RGMII_1000 : INTF_MODE_RGMII_10_100;
- mtk_w32(eth, val, INTF_MODE);
-
- regmap_update_bits(eth->ethsys, ETHSYS_CLKCFG0,
- ETHSYS_TRGMII_CLK_SEL362_5,
- ETHSYS_TRGMII_CLK_SEL362_5);
-
- val = (speed == SPEED_1000) ? 250000000 : 500000000;
- ret = clk_set_rate(eth->clks[MTK_CLK_TRGPLL], val);
- if (ret)
- dev_err(eth->dev, "Failed to set trgmii pll: %d\n", ret);
-
- val = (speed == SPEED_1000) ?
- RCK_CTRL_RGMII_1000 : RCK_CTRL_RGMII_10_100;
- mtk_w32(eth, val, TRGMII_RCK_CTRL);
-
- val = (speed == SPEED_1000) ?
- TCK_CTRL_RGMII_1000 : TCK_CTRL_RGMII_10_100;
- mtk_w32(eth, val, TRGMII_TCK_CTRL);
+ dev_err(eth->dev, "Missing PLL configuration, ethernet may not work\n");
}
static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
@@ -428,17 +409,8 @@ static void mtk_mac_config(struct phylin
state->interface))
goto err_phy;
} else {
- /* FIXME: this is incorrect. Not only does it
- * use state->speed (which is not guaranteed
- * to be correct) but it also makes use of it
- * in a code path that will only be reachable
- * when the PHY interface mode changes, not
- * when the speed changes. Consequently, RGMII
- * is probably broken.
- */
mtk_gmac0_rgmii_adjust(mac->hw,
- state->interface,
- state->speed);
+ state->interface);
/* mt7623_pad_clk_setup */
for (i = 0 ; i < NUM_TRGMII_CTRL; i++)
@@ -4286,13 +4258,19 @@ static int mtk_add_mac(struct mtk_eth *e
mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD;
- __set_bit(PHY_INTERFACE_MODE_MII,
- mac->phylink_config.supported_interfaces);
- __set_bit(PHY_INTERFACE_MODE_GMII,
- mac->phylink_config.supported_interfaces);
+ /* MT7623 gmac0 is now missing its speed-specific PLL configuration
+ * in its .mac_config method (since state->speed is not valid there.
+ * Disable support for MII, GMII and RGMII.
+ */
+ if (!mac->hw->soc->disable_pll_modes || mac->id != 0) {
+ __set_bit(PHY_INTERFACE_MODE_MII,
+ mac->phylink_config.supported_interfaces);
+ __set_bit(PHY_INTERFACE_MODE_GMII,
+ mac->phylink_config.supported_interfaces);
- if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII))
- phy_interface_set_rgmii(mac->phylink_config.supported_interfaces);
+ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII))
+ phy_interface_set_rgmii(mac->phylink_config.supported_interfaces);
+ }
if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_TRGMII) && !mac->id)
__set_bit(PHY_INTERFACE_MODE_TRGMII,
@@ -4752,6 +4730,7 @@ static const struct mtk_soc_data mt7623_
.offload_version = 1,
.hash_offset = 2,
.foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
+ .disable_pll_modes = true,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -1027,6 +1027,7 @@ struct mtk_soc_data {
u16 foe_entry_size;
netdev_features_t hw_features;
bool has_accounting;
+ bool disable_pll_modes;
struct {
u32 txd_size;
u32 rxd_size;

View File

@ -0,0 +1,81 @@
From a4c2233b1e4359b6c64b6f9ba98c8718a11fffee Mon Sep 17 00:00:00 2001
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
Date: Sat, 22 Jul 2023 21:32:54 +0100
Subject: [PATCH 097/250] net: ethernet: mtk_eth_soc: remove mac_pcs_get_state
and modernise
Remove the .mac_pcs_get_state function, since as far as I can tell is
never called - no DT appears to specify an in-band-status management
nor SFP support for this driver.
Removal of this, along with the previous patch to remove the incorrect
clocking configuration, means that the driver becomes non-legacy, so
we can remove the "legacy_pre_march2020" status from this driver.
Reviewed-by: Daniel Golle <daniel@makrotopia.org>
Tested-by: Daniel Golle <daniel@makrotopia.org>
Tested-by: Frank Wunderlich <frank-w@public-files.de>
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 35 ---------------------
1 file changed, 35 deletions(-)
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -512,38 +512,6 @@ static int mtk_mac_finish(struct phylink
return 0;
}
-static void mtk_mac_pcs_get_state(struct phylink_config *config,
- struct phylink_link_state *state)
-{
- struct mtk_mac *mac = container_of(config, struct mtk_mac,
- phylink_config);
- u32 pmsr = mtk_r32(mac->hw, MTK_MAC_MSR(mac->id));
-
- state->link = (pmsr & MAC_MSR_LINK);
- state->duplex = (pmsr & MAC_MSR_DPX) >> 1;
-
- switch (pmsr & (MAC_MSR_SPEED_1000 | MAC_MSR_SPEED_100)) {
- case 0:
- state->speed = SPEED_10;
- break;
- case MAC_MSR_SPEED_100:
- state->speed = SPEED_100;
- break;
- case MAC_MSR_SPEED_1000:
- state->speed = SPEED_1000;
- break;
- default:
- state->speed = SPEED_UNKNOWN;
- break;
- }
-
- state->pause &= (MLO_PAUSE_RX | MLO_PAUSE_TX);
- if (pmsr & MAC_MSR_RX_FC)
- state->pause |= MLO_PAUSE_RX;
- if (pmsr & MAC_MSR_TX_FC)
- state->pause |= MLO_PAUSE_TX;
-}
-
static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode,
phy_interface_t interface)
{
@@ -666,7 +634,6 @@ static void mtk_mac_link_up(struct phyli
static const struct phylink_mac_ops mtk_phylink_ops = {
.validate = phylink_generic_validate,
.mac_select_pcs = mtk_mac_select_pcs,
- .mac_pcs_get_state = mtk_mac_pcs_get_state,
.mac_config = mtk_mac_config,
.mac_finish = mtk_mac_finish,
.mac_link_down = mtk_mac_link_down,
@@ -4253,8 +4220,6 @@ static int mtk_add_mac(struct mtk_eth *e
mac->phylink_config.dev = &eth->netdev[id]->dev;
mac->phylink_config.type = PHYLINK_NETDEV;
- /* This driver makes use of state->speed in mac_config */
- mac->phylink_config.legacy_pre_march2020 = true;
mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD;

View File

@ -0,0 +1,550 @@
From 5d8d05fbf804b4485646d39551ac27452e45afd3 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Tue, 25 Jul 2023 01:52:02 +0100
Subject: [PATCH 099/250] net: ethernet: mtk_eth_soc: add version in
mtk_soc_data
Introduce version field in mtk_soc_data data structure in order to
make mtk_eth driver easier to maintain for chipset configuration
codebase. Get rid of MTK_NETSYS_V2 bit in chip capabilities.
This is a preliminary patch to introduce support for MT7988 SoC.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Link: https://lore.kernel.org/r/e52fae302ca135436e5cdd26d38d87be2da63055.1690246066.git.daniel@makrotopia.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 55 +++++++++++--------
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 36 +++++++-----
drivers/net/ethernet/mediatek/mtk_ppe.c | 18 +++---
.../net/ethernet/mediatek/mtk_ppe_offload.c | 2 +-
drivers/net/ethernet/mediatek/mtk_wed.c | 4 +-
5 files changed, 66 insertions(+), 49 deletions(-)
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -537,7 +537,7 @@ static void mtk_set_queue_speed(struct m
FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (mtk_is_netsys_v1(eth))
val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
if (IS_ENABLED(CONFIG_SOC_MT7621)) {
@@ -912,7 +912,7 @@ static bool mtk_rx_get_desc(struct mtk_e
rxd->rxd1 = READ_ONCE(dma_rxd->rxd1);
rxd->rxd3 = READ_ONCE(dma_rxd->rxd3);
rxd->rxd4 = READ_ONCE(dma_rxd->rxd4);
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (mtk_is_netsys_v2_or_greater(eth)) {
rxd->rxd5 = READ_ONCE(dma_rxd->rxd5);
rxd->rxd6 = READ_ONCE(dma_rxd->rxd6);
}
@@ -970,7 +970,7 @@ static int mtk_init_fq_dma(struct mtk_et
txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
txd->txd4 = 0;
- if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) {
+ if (mtk_is_netsys_v2_or_greater(eth)) {
txd->txd5 = 0;
txd->txd6 = 0;
txd->txd7 = 0;
@@ -1159,7 +1159,7 @@ static void mtk_tx_set_dma_desc(struct n
struct mtk_mac *mac = netdev_priv(dev);
struct mtk_eth *eth = mac->hw;
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (mtk_is_netsys_v2_or_greater(eth))
mtk_tx_set_dma_desc_v2(dev, txd, info);
else
mtk_tx_set_dma_desc_v1(dev, txd, info);
@@ -1466,7 +1466,7 @@ static void mtk_update_rx_cpu_idx(struct
static bool mtk_page_pool_enabled(struct mtk_eth *eth)
{
- return MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2);
+ return eth->soc->version == 2;
}
static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth,
@@ -1806,7 +1806,7 @@ static int mtk_poll_rx(struct napi_struc
break;
/* find out which mac the packet come from. values start at 1 */
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (mtk_is_netsys_v2_or_greater(eth))
mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1;
else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
!(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
@@ -1902,7 +1902,7 @@ static int mtk_poll_rx(struct napi_struc
skb->dev = netdev;
bytes += skb->len;
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (mtk_is_netsys_v2_or_greater(eth)) {
reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5);
hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY;
if (hash != MTK_RXD5_FOE_ENTRY)
@@ -1927,8 +1927,8 @@ static int mtk_poll_rx(struct napi_struc
/* When using VLAN untagging in combination with DSA, the
* hardware treats the MTK special tag as a VLAN and untags it.
*/
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) &&
- (trxd.rxd2 & RX_DMA_VTAG) && netdev_uses_dsa(netdev)) {
+ if (mtk_is_netsys_v1(eth) && (trxd.rxd2 & RX_DMA_VTAG) &&
+ netdev_uses_dsa(netdev)) {
unsigned int port = RX_DMA_VPID(trxd.rxd3) & GENMASK(2, 0);
if (port < ARRAY_SIZE(eth->dsa_meta) &&
@@ -2232,7 +2232,7 @@ static int mtk_tx_alloc(struct mtk_eth *
txd->txd2 = next_ptr;
txd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
txd->txd4 = 0;
- if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) {
+ if (mtk_is_netsys_v2_or_greater(eth)) {
txd->txd5 = 0;
txd->txd6 = 0;
txd->txd7 = 0;
@@ -2285,14 +2285,14 @@ static int mtk_tx_alloc(struct mtk_eth *
FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (mtk_is_netsys_v1(eth))
val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
ofs += MTK_QTX_OFFSET;
}
val = MTK_QDMA_TX_SCH_MAX_WFQ | (MTK_QDMA_TX_SCH_MAX_WFQ << 16);
mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate);
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (mtk_is_netsys_v2_or_greater(eth))
mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate + 4);
} else {
mtk_w32(eth, ring->phys_pdma, MT7628_TX_BASE_PTR0);
@@ -2419,7 +2419,7 @@ static int mtk_rx_alloc(struct mtk_eth *
rxd->rxd3 = 0;
rxd->rxd4 = 0;
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (mtk_is_netsys_v2_or_greater(eth)) {
rxd->rxd5 = 0;
rxd->rxd6 = 0;
rxd->rxd7 = 0;
@@ -2967,7 +2967,7 @@ static int mtk_start_dma(struct mtk_eth
MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO |
MTK_RX_2B_OFFSET | MTK_TX_WB_DDONE;
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (mtk_is_netsys_v2_or_greater(eth))
val |= MTK_MUTLI_CNT | MTK_RESV_BUF |
MTK_WCOMP_EN | MTK_DMAD_WR_WDONE |
MTK_CHK_DDONE_EN | MTK_LEAKY_BUCKET_EN;
@@ -3111,7 +3111,7 @@ static int mtk_open(struct net_device *d
phylink_start(mac->phylink);
netif_tx_start_all_queues(dev);
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (mtk_is_netsys_v2_or_greater(eth))
return 0;
if (mtk_uses_dsa(dev) && !eth->prog) {
@@ -3376,7 +3376,7 @@ static void mtk_hw_reset(struct mtk_eth
{
u32 val;
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (mtk_is_netsys_v2_or_greater(eth)) {
regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
val = RSTCTRL_PPE0_V2;
} else {
@@ -3388,7 +3388,7 @@ static void mtk_hw_reset(struct mtk_eth
ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (mtk_is_netsys_v2_or_greater(eth))
regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
0x3ffffff);
}
@@ -3414,7 +3414,7 @@ static void mtk_hw_warm_reset(struct mtk
return;
}
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (mtk_is_netsys_v2_or_greater(eth))
rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V2;
else
rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0;
@@ -3584,7 +3584,7 @@ static int mtk_hw_init(struct mtk_eth *e
else
mtk_hw_reset(eth);
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (mtk_is_netsys_v2_or_greater(eth)) {
/* Set FE to PDMAv2 if necessary */
val = mtk_r32(eth, MTK_FE_GLO_MISC);
mtk_w32(eth, val | BIT(4), MTK_FE_GLO_MISC);
@@ -3621,7 +3621,7 @@ static int mtk_hw_init(struct mtk_eth *e
*/
val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (mtk_is_netsys_v1(eth)) {
val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL);
@@ -3643,7 +3643,7 @@ static int mtk_hw_init(struct mtk_eth *e
mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4);
mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (mtk_is_netsys_v2_or_greater(eth)) {
/* PSE should not drop port8 and port9 packets from WDMA Tx */
mtk_w32(eth, 0x00000300, PSE_DROP_CFG);
@@ -4432,7 +4432,7 @@ static int mtk_probe(struct platform_dev
}
}
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (mtk_is_netsys_v2_or_greater(eth)) {
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
err = -EINVAL;
@@ -4540,9 +4540,8 @@ static int mtk_probe(struct platform_dev
}
if (eth->soc->offload_version) {
- u32 num_ppe;
+ u32 num_ppe = mtk_is_netsys_v2_or_greater(eth) ? 2 : 1;
- num_ppe = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1;
num_ppe = min_t(u32, ARRAY_SIZE(eth->ppe), num_ppe);
for (i = 0; i < num_ppe; i++) {
u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400;
@@ -4636,6 +4635,7 @@ static const struct mtk_soc_data mt2701_
.hw_features = MTK_HW_FEATURES,
.required_clks = MT7623_CLKS_BITMAP,
.required_pctl = true,
+ .version = 1,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
@@ -4652,6 +4652,7 @@ static const struct mtk_soc_data mt7621_
.hw_features = MTK_HW_FEATURES,
.required_clks = MT7621_CLKS_BITMAP,
.required_pctl = false,
+ .version = 1,
.offload_version = 1,
.hash_offset = 2,
.foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
@@ -4672,6 +4673,7 @@ static const struct mtk_soc_data mt7622_
.hw_features = MTK_HW_FEATURES,
.required_clks = MT7622_CLKS_BITMAP,
.required_pctl = false,
+ .version = 1,
.offload_version = 2,
.hash_offset = 2,
.has_accounting = true,
@@ -4692,6 +4694,7 @@ static const struct mtk_soc_data mt7623_
.hw_features = MTK_HW_FEATURES,
.required_clks = MT7623_CLKS_BITMAP,
.required_pctl = true,
+ .version = 1,
.offload_version = 1,
.hash_offset = 2,
.foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
@@ -4714,6 +4717,7 @@ static const struct mtk_soc_data mt7629_
.required_clks = MT7629_CLKS_BITMAP,
.required_pctl = false,
.has_accounting = true,
+ .version = 1,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
@@ -4731,6 +4735,7 @@ static const struct mtk_soc_data mt7981_
.hw_features = MTK_HW_FEATURES,
.required_clks = MT7981_CLKS_BITMAP,
.required_pctl = false,
+ .version = 2,
.offload_version = 2,
.hash_offset = 4,
.has_accounting = true,
@@ -4752,6 +4757,7 @@ static const struct mtk_soc_data mt7986_
.hw_features = MTK_HW_FEATURES,
.required_clks = MT7986_CLKS_BITMAP,
.required_pctl = false,
+ .version = 2,
.offload_version = 2,
.hash_offset = 4,
.has_accounting = true,
@@ -4772,6 +4778,7 @@ static const struct mtk_soc_data rt5350_
.hw_features = MTK_HW_FEATURES_MT7628,
.required_clks = MT7628_CLKS_BITMAP,
.required_pctl = false,
+ .version = 1,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -817,7 +817,6 @@ enum mkt_eth_capabilities {
MTK_SHARED_INT_BIT,
MTK_TRGMII_MT7621_CLK_BIT,
MTK_QDMA_BIT,
- MTK_NETSYS_V2_BIT,
MTK_SOC_MT7628_BIT,
MTK_RSTCTRL_PPE1_BIT,
MTK_U3_COPHY_V2_BIT,
@@ -852,7 +851,6 @@ enum mkt_eth_capabilities {
#define MTK_SHARED_INT BIT(MTK_SHARED_INT_BIT)
#define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT)
#define MTK_QDMA BIT(MTK_QDMA_BIT)
-#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT)
#define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT)
#define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT)
#define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT)
@@ -931,11 +929,11 @@ enum mkt_eth_capabilities {
#define MT7981_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \
MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \
- MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
+ MTK_RSTCTRL_PPE1)
#define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
- MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
+ MTK_RSTCTRL_PPE1)
struct mtk_tx_dma_desc_info {
dma_addr_t addr;
@@ -1006,6 +1004,7 @@ struct mtk_reg_map {
* @required_pctl A bool value to show whether the SoC requires
* the extra setup for those pins used by GMAC.
* @hash_offset Flow table hash offset.
+ * @version SoC version.
* @foe_entry_size Foe table entry size.
* @has_accounting Bool indicating support for accounting of
* offloaded flows.
@@ -1024,6 +1023,7 @@ struct mtk_soc_data {
bool required_pctl;
u8 offload_version;
u8 hash_offset;
+ u8 version;
u16 foe_entry_size;
netdev_features_t hw_features;
bool has_accounting;
@@ -1180,6 +1180,16 @@ struct mtk_mac {
/* the struct describing the SoC. these are declared in the soc_xyz.c files */
extern const struct of_device_id of_mtk_match[];
+static inline bool mtk_is_netsys_v1(struct mtk_eth *eth)
+{
+ return eth->soc->version == 1;
+}
+
+static inline bool mtk_is_netsys_v2_or_greater(struct mtk_eth *eth)
+{
+ return eth->soc->version > 1;
+}
+
static inline struct mtk_foe_entry *
mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash)
{
@@ -1190,7 +1200,7 @@ mtk_foe_get_entry(struct mtk_ppe *ppe, u
static inline u32 mtk_get_ib1_ts_mask(struct mtk_eth *eth)
{
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (mtk_is_netsys_v2_or_greater(eth))
return MTK_FOE_IB1_BIND_TIMESTAMP_V2;
return MTK_FOE_IB1_BIND_TIMESTAMP;
@@ -1198,7 +1208,7 @@ static inline u32 mtk_get_ib1_ts_mask(st
static inline u32 mtk_get_ib1_ppoe_mask(struct mtk_eth *eth)
{
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (mtk_is_netsys_v2_or_greater(eth))
return MTK_FOE_IB1_BIND_PPPOE_V2;
return MTK_FOE_IB1_BIND_PPPOE;
@@ -1206,7 +1216,7 @@ static inline u32 mtk_get_ib1_ppoe_mask(
static inline u32 mtk_get_ib1_vlan_tag_mask(struct mtk_eth *eth)
{
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (mtk_is_netsys_v2_or_greater(eth))
return MTK_FOE_IB1_BIND_VLAN_TAG_V2;
return MTK_FOE_IB1_BIND_VLAN_TAG;
@@ -1214,7 +1224,7 @@ static inline u32 mtk_get_ib1_vlan_tag_m
static inline u32 mtk_get_ib1_vlan_layer_mask(struct mtk_eth *eth)
{
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (mtk_is_netsys_v2_or_greater(eth))
return MTK_FOE_IB1_BIND_VLAN_LAYER_V2;
return MTK_FOE_IB1_BIND_VLAN_LAYER;
@@ -1222,7 +1232,7 @@ static inline u32 mtk_get_ib1_vlan_layer
static inline u32 mtk_prep_ib1_vlan_layer(struct mtk_eth *eth, u32 val)
{
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (mtk_is_netsys_v2_or_greater(eth))
return FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER_V2, val);
return FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, val);
@@ -1230,7 +1240,7 @@ static inline u32 mtk_prep_ib1_vlan_laye
static inline u32 mtk_get_ib1_vlan_layer(struct mtk_eth *eth, u32 val)
{
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (mtk_is_netsys_v2_or_greater(eth))
return FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER_V2, val);
return FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER, val);
@@ -1238,7 +1248,7 @@ static inline u32 mtk_get_ib1_vlan_layer
static inline u32 mtk_get_ib1_pkt_type_mask(struct mtk_eth *eth)
{
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (mtk_is_netsys_v2_or_greater(eth))
return MTK_FOE_IB1_PACKET_TYPE_V2;
return MTK_FOE_IB1_PACKET_TYPE;
@@ -1246,7 +1256,7 @@ static inline u32 mtk_get_ib1_pkt_type_m
static inline u32 mtk_get_ib1_pkt_type(struct mtk_eth *eth, u32 val)
{
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (mtk_is_netsys_v2_or_greater(eth))
return FIELD_GET(MTK_FOE_IB1_PACKET_TYPE_V2, val);
return FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, val);
@@ -1254,7 +1264,7 @@ static inline u32 mtk_get_ib1_pkt_type(s
static inline u32 mtk_get_ib2_multicast_mask(struct mtk_eth *eth)
{
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (mtk_is_netsys_v2_or_greater(eth))
return MTK_FOE_IB2_MULTICAST_V2;
return MTK_FOE_IB2_MULTICAST;
--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
@@ -207,7 +207,7 @@ int mtk_foe_entry_prepare(struct mtk_eth
memset(entry, 0, sizeof(*entry));
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (mtk_is_netsys_v2_or_greater(eth)) {
val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) |
FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE_V2, type) |
FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) |
@@ -271,7 +271,7 @@ int mtk_foe_entry_set_pse_port(struct mt
u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
u32 val = *ib2;
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (mtk_is_netsys_v2_or_greater(eth)) {
val &= ~MTK_FOE_IB2_DEST_PORT_V2;
val |= FIELD_PREP(MTK_FOE_IB2_DEST_PORT_V2, port);
} else {
@@ -422,7 +422,7 @@ int mtk_foe_entry_set_wdma(struct mtk_et
struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry);
u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (mtk_is_netsys_v2_or_greater(eth)) {
*ib2 &= ~MTK_FOE_IB2_PORT_MG_V2;
*ib2 |= FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) |
MTK_FOE_IB2_WDMA_WINFO_V2;
@@ -452,7 +452,7 @@ int mtk_foe_entry_set_queue(struct mtk_e
{
u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (mtk_is_netsys_v2_or_greater(eth)) {
*ib2 &= ~MTK_FOE_IB2_QID_V2;
*ib2 |= FIELD_PREP(MTK_FOE_IB2_QID_V2, queue);
*ib2 |= MTK_FOE_IB2_PSE_QOS_V2;
@@ -607,7 +607,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
struct mtk_foe_entry *hwe;
u32 val;
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (mtk_is_netsys_v2_or_greater(eth)) {
entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP_V2;
entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP_V2,
timestamp);
@@ -623,7 +623,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
hwe->ib1 = entry->ib1;
if (ppe->accounting) {
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (mtk_is_netsys_v2_or_greater(eth))
val = MTK_FOE_IB2_MIB_CNT_V2;
else
val = MTK_FOE_IB2_MIB_CNT;
@@ -971,7 +971,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
MTK_PPE_SCAN_MODE_KEEPALIVE_AGE) |
FIELD_PREP(MTK_PPE_TB_CFG_ENTRY_NUM,
MTK_PPE_ENTRIES_SHIFT);
- if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2))
+ if (mtk_is_netsys_v2_or_greater(ppe->eth))
val |= MTK_PPE_TB_CFG_INFO_SEL;
ppe_w32(ppe, MTK_PPE_TB_CFG, val);
@@ -987,7 +987,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
MTK_PPE_FLOW_CFG_IP4_NAPT |
MTK_PPE_FLOW_CFG_IP4_DSLITE |
MTK_PPE_FLOW_CFG_IP4_NAT_FRAG;
- if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2))
+ if (mtk_is_netsys_v2_or_greater(ppe->eth))
val |= MTK_PPE_MD_TOAP_BYP_CRSN0 |
MTK_PPE_MD_TOAP_BYP_CRSN1 |
MTK_PPE_MD_TOAP_BYP_CRSN2 |
@@ -1029,7 +1029,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT, 0);
- if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) {
+ if (mtk_is_netsys_v2_or_greater(ppe->eth)) {
ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777);
ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f);
}
--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
@@ -193,7 +193,7 @@ mtk_flow_set_output_device(struct mtk_et
if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) {
mtk_foe_entry_set_wdma(eth, foe, info.wdma_idx, info.queue,
info.bss, info.wcid);
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (mtk_is_netsys_v2_or_greater(eth)) {
switch (info.wdma_idx) {
case 0:
pse_port = 8;
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
@@ -1091,7 +1091,7 @@ mtk_wed_rx_reset(struct mtk_wed_device *
} else {
struct mtk_eth *eth = dev->hw->eth;
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (mtk_is_netsys_v2_or_greater(eth))
wed_set(dev, MTK_WED_RESET_IDX,
MTK_WED_RESET_IDX_RX_V2);
else
@@ -1813,7 +1813,7 @@ void mtk_wed_add_hw(struct device_node *
hw->wdma = wdma;
hw->index = index;
hw->irq = irq;
- hw->version = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1;
+ hw->version = mtk_is_netsys_v1(eth) ? 1 : 2;
if (hw->version == 1) {
hw->mirror = syscon_regmap_lookup_by_phandle(eth_np,

View File

@ -0,0 +1,29 @@
From f8fb8dbd158c585be7574faf92db7d614b6722ff Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Tue, 25 Jul 2023 01:52:27 +0100
Subject: [PATCH 100/250] net: ethernet: mtk_eth_soc: increase MAX_DEVS to 3
This is a preliminary patch to add MT7988 SoC support since it runs 3
macs instead of 2.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Link: https://lore.kernel.org/r/3563e5fab367e7d79a7f1296fabaa5c20f202d7a.1690246066.git.daniel@makrotopia.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -1040,8 +1040,8 @@ struct mtk_soc_data {
#define MTK_DMA_MONITOR_TIMEOUT msecs_to_jiffies(1000)
-/* currently no SoC has more than 2 macs */
-#define MTK_MAX_DEVS 2
+/* currently no SoC has more than 3 macs */
+#define MTK_MAX_DEVS 3
/* struct mtk_eth - This is the main datasructure for holding the state
* of the driver

View File

@ -1,143 +1,176 @@
From 4e35e80750b33727e606be9e7ce447bde2e0deb7 Mon Sep 17 00:00:00 2001
From 856be974290f28d7943be2ac5a382c4139486196 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Tue, 7 Mar 2023 15:55:35 +0000
Subject: [PATCH 3/7] net: ethernet: mtk_eth_soc: rely on num_devs and remove
MTK_MAC_COUNT
Date: Tue, 25 Jul 2023 01:52:44 +0100
Subject: [PATCH 101/250] net: ethernet: mtk_eth_soc: rely on MTK_MAX_DEVS and
remove MTK_MAC_COUNT
Get rid of MTK_MAC_COUNT since it is a duplicated of eth->soc->num_devs.
Get rid of MTK_MAC_COUNT since it is a duplicated of MTK_MAX_DEVS.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Link: https://lore.kernel.org/r/1856f4266f2fc80677807b1bad867659e7b00c65.1690246066.git.daniel@makrotopia.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 ++++++++++-----------
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 49 ++++++++++++---------
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 -
2 files changed, 15 insertions(+), 16 deletions(-)
2 files changed, 27 insertions(+), 23 deletions(-)
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -900,7 +900,7 @@ static void mtk_stats_update(struct mtk_
@@ -838,7 +838,7 @@ static void mtk_stats_update(struct mtk_
{
int i;
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
+ for (i = 0; i < MTK_MAX_DEVS; i++) {
if (!eth->mac[i] || !eth->mac[i]->hw_stats)
continue;
if (spin_trylock(&eth->mac[i]->hw_stats->stats_lock)) {
@@ -1403,7 +1403,7 @@ static int mtk_queue_stopped(struct mtk_
@@ -1341,7 +1341,7 @@ static int mtk_queue_stopped(struct mtk_
{
int i;
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
+ for (i = 0; i < MTK_MAX_DEVS; i++) {
if (!eth->netdev[i])
continue;
if (netif_queue_stopped(eth->netdev[i]))
@@ -1417,7 +1417,7 @@ static void mtk_wake_queue(struct mtk_et
@@ -1355,7 +1355,7 @@ static void mtk_wake_queue(struct mtk_et
{
int i;
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
+ for (i = 0; i < MTK_MAX_DEVS; i++) {
if (!eth->netdev[i])
continue;
netif_tx_wake_all_queues(eth->netdev[i]);
@@ -1908,7 +1908,7 @@ static int mtk_poll_rx(struct napi_struc
@@ -1812,7 +1812,7 @@ static int mtk_poll_rx(struct napi_struc
!(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1;
- if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT ||
+ if (unlikely(mac < 0 || mac >= eth->soc->num_devs ||
+ if (unlikely(mac < 0 || mac >= MTK_MAX_DEVS ||
!eth->netdev[mac]))
goto release_desc;
@@ -2937,7 +2937,7 @@ static void mtk_dma_free(struct mtk_eth
@@ -2841,7 +2841,7 @@ static void mtk_dma_free(struct mtk_eth
const struct mtk_soc_data *soc = eth->soc;
int i;
- for (i = 0; i < MTK_MAC_COUNT; i++)
+ for (i = 0; i < soc->num_devs; i++)
+ for (i = 0; i < MTK_MAX_DEVS; i++)
if (eth->netdev[i])
netdev_reset_queue(eth->netdev[i]);
if (eth->scratch_ring) {
@@ -3091,7 +3091,7 @@ static void mtk_gdm_config(struct mtk_et
@@ -2995,8 +2995,13 @@ static void mtk_gdm_config(struct mtk_et
if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
return;
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
u32 val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i));
- u32 val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i));
+ for (i = 0; i < MTK_MAX_DEVS; i++) {
+ u32 val;
+
+ if (!eth->netdev[i])
+ continue;
+
+ val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i));
/* default setup the forward port to send frame to PDMA */
@@ -3704,7 +3704,7 @@ static int mtk_hw_init(struct mtk_eth *e
val &= ~0xffff;
@@ -3006,7 +3011,7 @@ static void mtk_gdm_config(struct mtk_et
val |= config;
- if (eth->netdev[i] && netdev_uses_dsa(eth->netdev[i]))
+ if (netdev_uses_dsa(eth->netdev[i]))
val |= MTK_GDMA_SPECIAL_TAG;
mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i));
@@ -3605,15 +3610,15 @@ static int mtk_hw_init(struct mtk_eth *e
* up with the more appropriate value when mtk_mac_config call is being
* invoked.
*/
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
+ for (i = 0; i < MTK_MAX_DEVS; i++) {
struct net_device *dev = eth->netdev[i];
mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i));
@@ -3892,7 +3892,7 @@ static void mtk_pending_work(struct work
- mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i));
- if (dev) {
- struct mtk_mac *mac = netdev_priv(dev);
+ if (!dev)
+ continue;
- mtk_set_mcr_max_rx(mac, dev->mtu + MTK_RX_ETH_HLEN);
- }
+ mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i));
+ mtk_set_mcr_max_rx(netdev_priv(dev),
+ dev->mtu + MTK_RX_ETH_HLEN);
}
/* Indicates CDM to parse the MTK special tag from CPU
@@ -3793,7 +3798,7 @@ static void mtk_pending_work(struct work
mtk_prepare_for_reset(eth);
/* stop all devices to make sure that dma is properly shut down */
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
+ for (i = 0; i < MTK_MAX_DEVS; i++) {
if (!eth->netdev[i] || !netif_running(eth->netdev[i]))
continue;
@@ -3908,7 +3908,7 @@ static void mtk_pending_work(struct work
@@ -3809,8 +3814,8 @@ static void mtk_pending_work(struct work
mtk_hw_init(eth, true);
/* restart DMA and enable IRQs */
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
if (!test_bit(i, &restart))
- if (!test_bit(i, &restart))
+ for (i = 0; i < MTK_MAX_DEVS; i++) {
+ if (!eth->netdev[i] || !test_bit(i, &restart))
continue;
@@ -3936,7 +3936,7 @@ static int mtk_free_dev(struct mtk_eth *
if (mtk_open(eth->netdev[i])) {
@@ -3837,7 +3842,7 @@ static int mtk_free_dev(struct mtk_eth *
{
int i;
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
+ for (i = 0; i < MTK_MAX_DEVS; i++) {
if (!eth->netdev[i])
continue;
free_netdev(eth->netdev[i]);
@@ -3955,7 +3955,7 @@ static int mtk_unreg_dev(struct mtk_eth
@@ -3856,7 +3861,7 @@ static int mtk_unreg_dev(struct mtk_eth
{
int i;
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
+ for (i = 0; i < MTK_MAX_DEVS; i++) {
struct mtk_mac *mac;
if (!eth->netdev[i])
continue;
@@ -4259,7 +4259,7 @@ static int mtk_add_mac(struct mtk_eth *e
@@ -4157,7 +4162,7 @@ static int mtk_add_mac(struct mtk_eth *e
}
id = be32_to_cpup(_id);
- if (id >= MTK_MAC_COUNT) {
+ if (id >= eth->soc->num_devs) {
+ if (id >= MTK_MAX_DEVS) {
dev_err(eth->dev, "%d is not a valid mac id\n", id);
return -EINVAL;
}
@@ -4400,7 +4400,7 @@ void mtk_eth_set_dma_device(struct mtk_e
@@ -4302,7 +4307,7 @@ void mtk_eth_set_dma_device(struct mtk_e
rtnl_lock();
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
+ for (i = 0; i < MTK_MAX_DEVS; i++) {
dev = eth->netdev[i];
if (!dev || !(dev->flags & IFF_UP))
@@ -4727,7 +4727,7 @@ static int mtk_remove(struct platform_de
@@ -4610,7 +4615,7 @@ static int mtk_remove(struct platform_de
int i;
/* stop all devices to make sure that dma is properly shut down */
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
+ for (i = 0; i < MTK_MAX_DEVS; i++) {
if (!eth->netdev[i])
continue;
mtk_stop(eth->netdev[i]);

View File

@ -1,22 +1,24 @@
From ab817f559d505329d8a413c7d29250f6d87d77a0 Mon Sep 17 00:00:00 2001
From a41d535855976838d246c079143c948dcf0f7931 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Tue, 7 Mar 2023 15:55:47 +0000
Subject: [PATCH 4/7] net: ethernet: mtk_eth_soc: add MTK_NETSYS_V3 capability
bit
Date: Tue, 25 Jul 2023 01:52:59 +0100
Subject: [PATCH 102/250] net: ethernet: mtk_eth_soc: add NETSYS_V3 version
support
Introduce MTK_NETSYS_V3 bit in the device capabilities.
Introduce NETSYS_V3 chipset version support.
This is a preliminary patch to introduce support for MT7988 SoC.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Link: https://lore.kernel.org/r/0db2260910755d76fa48e303b9f9bdf4e5a82340.1690246066.git.daniel@makrotopia.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 115 ++++++++++++++++----
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 44 +++++++-
2 files changed, 134 insertions(+), 25 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 105 ++++++++++++++------
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 48 +++++++--
2 files changed, 116 insertions(+), 37 deletions(-)
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -880,17 +880,32 @@ void mtk_stats_update_mac(struct mtk_mac
@@ -818,17 +818,32 @@ void mtk_stats_update_mac(struct mtk_mac
mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x20 + offs);
hw_stats->rx_flow_control_packets +=
mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x24 + offs);
@ -32,7 +34,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
- hw_stats->tx_packets +=
- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs);
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
+ if (mtk_is_netsys_v3_or_greater(eth)) {
+ hw_stats->tx_skip +=
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x50 + offs);
+ hw_stats->tx_collisions +=
@ -60,7 +62,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
}
u64_stats_update_end(&hw_stats->syncp);
@@ -1192,7 +1207,10 @@ static void mtk_tx_set_dma_desc_v2(struc
@@ -1130,7 +1145,10 @@ static void mtk_tx_set_dma_desc_v2(struc
data |= TX_DMA_LS0;
WRITE_ONCE(desc->txd3, data);
@ -72,57 +74,53 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid);
WRITE_ONCE(desc->txd4, data);
@@ -1203,6 +1221,9 @@ static void mtk_tx_set_dma_desc_v2(struc
@@ -1141,6 +1159,8 @@ static void mtk_tx_set_dma_desc_v2(struc
/* tx checksum offload */
if (info->csum)
data |= TX_DMA_CHKSUM_V2;
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) &&
+ netdev_uses_dsa(dev))
+ if (mtk_is_netsys_v3_or_greater(eth) && netdev_uses_dsa(dev))
+ data |= TX_DMA_SPTAG_V3;
}
WRITE_ONCE(desc->txd5, data);
@@ -1268,8 +1289,13 @@ static int mtk_tx_map(struct sk_buff *sk
@@ -1206,8 +1226,7 @@ static int mtk_tx_map(struct sk_buff *sk
mtk_tx_set_dma_desc(dev, itxd, &txd_info);
itx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
- itx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
- MTK_TX_FLAGS_FPORT1;
+ if (mac->id == MTK_GMAC1_ID)
+ itx_buf->flags |= MTK_TX_FLAGS_FPORT0;
+ else if (mac->id == MTK_GMAC2_ID)
+ itx_buf->flags |= MTK_TX_FLAGS_FPORT1;
+ else
+ itx_buf->flags |= MTK_TX_FLAGS_FPORT2;
+
+ itx_buf->mac_id = mac->id;
setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size,
k++);
@@ -1317,8 +1343,13 @@ static int mtk_tx_map(struct sk_buff *sk
@@ -1255,8 +1274,7 @@ static int mtk_tx_map(struct sk_buff *sk
memset(tx_buf, 0, sizeof(*tx_buf));
tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
tx_buf->flags |= MTK_TX_FLAGS_PAGE0;
- tx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
- MTK_TX_FLAGS_FPORT1;
+
+ if (mac->id == MTK_GMAC1_ID)
+ tx_buf->flags |= MTK_TX_FLAGS_FPORT0;
+ else if (mac->id == MTK_GMAC2_ID)
+ tx_buf->flags |= MTK_TX_FLAGS_FPORT1;
+ else
+ tx_buf->flags |= MTK_TX_FLAGS_FPORT2;
+ tx_buf->mac_id = mac->id;
setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr,
txd_info.size, k++);
@@ -1902,11 +1933,24 @@ static int mtk_poll_rx(struct napi_struc
@@ -1558,7 +1576,7 @@ static int mtk_xdp_frame_map(struct mtk_
}
mtk_tx_set_dma_desc(dev, txd, txd_info);
- tx_buf->flags |= !mac->id ? MTK_TX_FLAGS_FPORT0 : MTK_TX_FLAGS_FPORT1;
+ tx_buf->mac_id = mac->id;
tx_buf->type = dma_map ? MTK_TYPE_XDP_NDO : MTK_TYPE_XDP_TX;
tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
@@ -1806,11 +1824,24 @@ static int mtk_poll_rx(struct napi_struc
break;
/* find out which mac the packet come from. values start at 1 */
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
- if (mtk_is_netsys_v2_or_greater(eth))
- mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1;
- else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
- !(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
+ if (mtk_is_netsys_v2_or_greater(eth)) {
+ u32 val = RX_DMA_GET_SPORT_V2(trxd.rxd5);
+
+ switch (val) {
@ -137,29 +135,44 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+ break;
+ }
+ } else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
+ !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) {
+ !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) {
mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1;
+ }
if (unlikely(mac < 0 || mac >= eth->soc->num_devs ||
if (unlikely(mac < 0 || mac >= MTK_MAX_DEVS ||
!eth->netdev[mac]))
@@ -2135,7 +2179,9 @@ static int mtk_poll_tx_qdma(struct mtk_e
@@ -2030,7 +2061,6 @@ static int mtk_poll_tx_qdma(struct mtk_e
while ((cpu != dma) && budget) {
u32 next_cpu = desc->txd2;
- int mac = 0;
desc = mtk_qdma_phys_to_virt(ring, desc->txd2);
if ((desc->txd3 & TX_DMA_OWNER_CPU) == 0)
@@ -2038,15 +2068,13 @@ static int mtk_poll_tx_qdma(struct mtk_e
tx_buf = mtk_desc_to_tx_buf(ring, desc,
eth->soc->txrx.txd_size);
if (tx_buf->flags & MTK_TX_FLAGS_FPORT1)
- if (tx_buf->flags & MTK_TX_FLAGS_FPORT1)
- mac = 1;
+ mac = MTK_GMAC2_ID;
+ else if (tx_buf->flags & MTK_TX_FLAGS_FPORT2)
+ mac = MTK_GMAC3_ID;
-
if (!tx_buf->data)
break;
@@ -3742,7 +3788,26 @@ static int mtk_hw_init(struct mtk_eth *e
if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) {
if (tx_buf->type == MTK_TYPE_SKB)
- mtk_poll_tx_done(eth, state, mac, tx_buf->data);
+ mtk_poll_tx_done(eth, state, tx_buf->mac_id,
+ tx_buf->data);
budget--;
}
@@ -3648,7 +3676,24 @@ static int mtk_hw_init(struct mtk_eth *e
mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4);
mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
- if (mtk_is_netsys_v2_or_greater(eth)) {
+ if (mtk_is_netsys_v3_or_greater(eth)) {
+ /* PSE should not drop port1, port8 and port9 packets */
+ mtk_w32(eth, 0x00000302, PSE_DROP_CFG);
+
@ -168,9 +181,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+ mtk_w32(eth, 0x00000077, MTK_CDMW1_THRES);
+
+ /* Disable GDM1 RX CRC stripping */
+ val = mtk_r32(eth, MTK_GDMA_FWD_CFG(0));
+ val &= ~MTK_GDMA_STRP_CRC;
+ mtk_w32(eth, val, MTK_GDMA_FWD_CFG(0));
+ mtk_m32(eth, MTK_GDMA_STRP_CRC, 0, MTK_GDMA_FWD_CFG(0));
+
+ /* PSE GDM3 MIB counter has incorrect hw default values,
+ * so the driver ought to read clear the values beforehand
@ -178,17 +189,17 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+ */
+ for (i = 0; i < 0x80; i += 0x4)
+ mtk_r32(eth, reg_map->gdm1_cnt + 0x100 + i);
+ } else if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ } else if (!mtk_is_netsys_v1(eth)) {
/* PSE should not drop port8 and port9 packets from WDMA Tx */
mtk_w32(eth, 0x00000300, PSE_DROP_CFG);
@@ -4307,7 +4372,11 @@ static int mtk_add_mac(struct mtk_eth *e
@@ -4210,7 +4255,11 @@ static int mtk_add_mac(struct mtk_eth *e
}
spin_lock_init(&mac->hw_stats->stats_lock);
u64_stats_init(&mac->hw_stats->syncp);
- mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET;
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3))
+ if (mtk_is_netsys_v3_or_greater(eth))
+ mac->hw_stats->reg_offset = id * 0x80;
+ else
+ mac->hw_stats->reg_offset = id * 0x40;
@ -197,7 +208,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
err = of_get_phy_mode(np, &phy_mode);
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -121,6 +121,7 @@
@@ -122,6 +122,7 @@
#define MTK_GDMA_ICS_EN BIT(22)
#define MTK_GDMA_TCS_EN BIT(21)
#define MTK_GDMA_UCS_EN BIT(20)
@ -205,7 +216,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
#define MTK_GDMA_TO_PDMA 0x0
#define MTK_GDMA_DROP_ALL 0x7777
@@ -286,8 +287,6 @@
@@ -287,8 +288,6 @@
/* QDMA Interrupt grouping registers */
#define MTK_RLS_DONE_INT BIT(0)
@ -214,7 +225,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
/* QDMA TX NUM */
#define QID_BITS_V2(x) (((x) & 0x3f) << 16)
#define MTK_QDMA_GMAC2_QID 8
@@ -300,6 +299,8 @@
@@ -301,6 +300,8 @@
#define TX_DMA_CHKSUM_V2 (0x7 << 28)
#define TX_DMA_TSO_V2 BIT(31)
@ -223,15 +234,20 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
/* QDMA V2 descriptor txd4 */
#define TX_DMA_FPORT_SHIFT_V2 8
#define TX_DMA_FPORT_MASK_V2 0xf
@@ -636,6 +637,7 @@ enum mtk_tx_flags {
@@ -631,12 +632,6 @@ enum mtk_tx_flags {
*/
MTK_TX_FLAGS_FPORT0 = 0x04,
MTK_TX_FLAGS_FPORT1 = 0x08,
+ MTK_TX_FLAGS_FPORT2 = 0x10,
MTK_TX_FLAGS_SINGLE0 = 0x01,
MTK_TX_FLAGS_PAGE0 = 0x02,
-
- /* MTK_TX_FLAGS_FPORTx allows tracking which port the transmitted
- * SKB out instead of looking up through hardware TX descriptor.
- */
- MTK_TX_FLAGS_FPORT0 = 0x04,
- MTK_TX_FLAGS_FPORT1 = 0x08,
};
/* This enum allows us to identify how the clock is defined on the array of the
@@ -721,6 +723,42 @@ enum mtk_dev_state {
@@ -722,6 +717,35 @@ enum mtk_dev_state {
MTK_RESETTING
};
@ -263,30 +279,29 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+ MTK_GMAC3_ID,
+ MTK_GMAC_ID_MAX
+};
+
+/* GDM Type */
+enum mtk_gdm_type {
+ MTK_GDM_TYPE = 0,
+ MTK_XGDM_TYPE,
+ MTK_GDM_TYPE_MAX
+};
+
enum mtk_tx_buf_type {
MTK_TYPE_SKB,
MTK_TYPE_XDP_TX,
@@ -817,6 +855,7 @@ enum mkt_eth_capabilities {
MTK_QDMA_BIT,
MTK_NETSYS_V1_BIT,
MTK_NETSYS_V2_BIT,
+ MTK_NETSYS_V3_BIT,
MTK_SOC_MT7628_BIT,
MTK_RSTCTRL_PPE1_BIT,
MTK_U3_COPHY_V2_BIT,
@@ -853,6 +892,7 @@ enum mkt_eth_capabilities {
#define MTK_QDMA BIT(MTK_QDMA_BIT)
#define MTK_NETSYS_V1 BIT(MTK_NETSYS_V1_BIT)
#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT)
+#define MTK_NETSYS_V3 BIT(MTK_NETSYS_V3_BIT)
#define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT)
#define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT)
#define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT)
@@ -740,7 +764,8 @@ struct mtk_tx_buf {
enum mtk_tx_buf_type type;
void *data;
- u32 flags;
+ u16 mac_id;
+ u16 flags;
DEFINE_DMA_UNMAP_ADDR(dma_addr0);
DEFINE_DMA_UNMAP_LEN(dma_len0);
DEFINE_DMA_UNMAP_ADDR(dma_addr1);
@@ -1189,6 +1214,11 @@ static inline bool mtk_is_netsys_v2_or_g
return eth->soc->version > 1;
}
+static inline bool mtk_is_netsys_v3_or_greater(struct mtk_eth *eth)
+{
+ return eth->soc->version > 2;
+}
+
static inline struct mtk_foe_entry *
mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash)
{

View File

@ -1,17 +1,19 @@
From 45b575fd9e6a455090820248bf1b98b1f2c7b6c8 Mon Sep 17 00:00:00 2001
From db797ae0542220a98658229397da464c383c991c Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Tue, 7 Mar 2023 15:56:00 +0000
Subject: [PATCH 5/7] net: ethernet: mtk_eth_soc: convert caps in mtk_soc_data
struct to u64
Date: Tue, 25 Jul 2023 01:53:13 +0100
Subject: [PATCH 103/250] net: ethernet: mtk_eth_soc: convert caps in
mtk_soc_data struct to u64
This is a preliminary patch to introduce support for MT7988 SoC.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Link: https://lore.kernel.org/r/9499ac3670b2fc5b444404b84e8a4a169beabbf2.1690246066.git.daniel@makrotopia.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/mediatek/mtk_eth_path.c | 22 +++----
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 62 ++++++++++----------
2 files changed, 42 insertions(+), 42 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_path.c | 22 ++++----
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 56 ++++++++++----------
2 files changed, 39 insertions(+), 39 deletions(-)
--- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
@ -111,7 +113,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
MTK_ETH_PATH_GMAC2_RGMII;
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -878,44 +878,44 @@ enum mkt_eth_capabilities {
@@ -863,41 +863,41 @@ enum mkt_eth_capabilities {
};
/* Supported hardware group on SoCs */
@ -127,9 +129,6 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-#define MTK_SHARED_INT BIT(MTK_SHARED_INT_BIT)
-#define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT)
-#define MTK_QDMA BIT(MTK_QDMA_BIT)
-#define MTK_NETSYS_V1 BIT(MTK_NETSYS_V1_BIT)
-#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT)
-#define MTK_NETSYS_V3 BIT(MTK_NETSYS_V3_BIT)
-#define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT)
-#define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT)
-#define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT)
@ -145,9 +144,6 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+#define MTK_SHARED_INT BIT_ULL(MTK_SHARED_INT_BIT)
+#define MTK_TRGMII_MT7621_CLK BIT_ULL(MTK_TRGMII_MT7621_CLK_BIT)
+#define MTK_QDMA BIT_ULL(MTK_QDMA_BIT)
+#define MTK_NETSYS_V1 BIT_ULL(MTK_NETSYS_V1_BIT)
+#define MTK_NETSYS_V2 BIT_ULL(MTK_NETSYS_V2_BIT)
+#define MTK_NETSYS_V3 BIT_ULL(MTK_NETSYS_V3_BIT)
+#define MTK_SOC_MT7628 BIT_ULL(MTK_SOC_MT7628_BIT)
+#define MTK_RSTCTRL_PPE1 BIT_ULL(MTK_RSTCTRL_PPE1_BIT)
+#define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT)
@ -186,7 +182,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
#define MTK_GMAC1_RGMII (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII)
#define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
@@ -1071,7 +1071,7 @@ struct mtk_reg_map {
@@ -1042,7 +1042,7 @@ struct mtk_reg_map {
struct mtk_soc_data {
const struct mtk_reg_map *reg_map;
u32 ana_rgc3;

View File

@ -0,0 +1,132 @@
From a1c9f7d1d24e90294f6a6755b137fcf306851e93 Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Tue, 25 Jul 2023 01:53:28 +0100
Subject: [PATCH 104/250] net: ethernet: mtk_eth_soc: convert clock bitmap to
u64
The to-be-added MT7988 SoC adds many new clocks which need to be
controlled by the Ethernet driver, which will result in their total
number exceeding 32.
Prepare by converting clock bitmaps into 64-bit types.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Link: https://lore.kernel.org/r/6960a39bb0078cf84d7642a9558e6a91c6cc9df3.1690246066.git.daniel@makrotopia.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 96 +++++++++++----------
1 file changed, 49 insertions(+), 47 deletions(-)
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -663,54 +663,56 @@ enum mtk_clks_map {
MTK_CLK_MAX
};
-#define MT7623_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \
- BIT(MTK_CLK_GP1) | BIT(MTK_CLK_GP2) | \
- BIT(MTK_CLK_TRGPLL))
-#define MT7622_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \
- BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \
- BIT(MTK_CLK_GP2) | \
- BIT(MTK_CLK_SGMII_TX_250M) | \
- BIT(MTK_CLK_SGMII_RX_250M) | \
- BIT(MTK_CLK_SGMII_CDR_REF) | \
- BIT(MTK_CLK_SGMII_CDR_FB) | \
- BIT(MTK_CLK_SGMII_CK) | \
- BIT(MTK_CLK_ETH2PLL))
+#define MT7623_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \
+ BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \
+ BIT_ULL(MTK_CLK_TRGPLL))
+#define MT7622_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \
+ BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \
+ BIT_ULL(MTK_CLK_GP2) | \
+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
+ BIT_ULL(MTK_CLK_SGMII_CK) | \
+ BIT_ULL(MTK_CLK_ETH2PLL))
#define MT7621_CLKS_BITMAP (0)
#define MT7628_CLKS_BITMAP (0)
-#define MT7629_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \
- BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \
- BIT(MTK_CLK_GP2) | BIT(MTK_CLK_FE) | \
- BIT(MTK_CLK_SGMII_TX_250M) | \
- BIT(MTK_CLK_SGMII_RX_250M) | \
- BIT(MTK_CLK_SGMII_CDR_REF) | \
- BIT(MTK_CLK_SGMII_CDR_FB) | \
- BIT(MTK_CLK_SGMII2_TX_250M) | \
- BIT(MTK_CLK_SGMII2_RX_250M) | \
- BIT(MTK_CLK_SGMII2_CDR_REF) | \
- BIT(MTK_CLK_SGMII2_CDR_FB) | \
- BIT(MTK_CLK_SGMII_CK) | \
- BIT(MTK_CLK_ETH2PLL) | BIT(MTK_CLK_SGMIITOP))
-#define MT7981_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
- BIT(MTK_CLK_WOCPU0) | \
- BIT(MTK_CLK_SGMII_TX_250M) | \
- BIT(MTK_CLK_SGMII_RX_250M) | \
- BIT(MTK_CLK_SGMII_CDR_REF) | \
- BIT(MTK_CLK_SGMII_CDR_FB) | \
- BIT(MTK_CLK_SGMII2_TX_250M) | \
- BIT(MTK_CLK_SGMII2_RX_250M) | \
- BIT(MTK_CLK_SGMII2_CDR_REF) | \
- BIT(MTK_CLK_SGMII2_CDR_FB) | \
- BIT(MTK_CLK_SGMII_CK))
-#define MT7986_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
- BIT(MTK_CLK_WOCPU1) | BIT(MTK_CLK_WOCPU0) | \
- BIT(MTK_CLK_SGMII_TX_250M) | \
- BIT(MTK_CLK_SGMII_RX_250M) | \
- BIT(MTK_CLK_SGMII_CDR_REF) | \
- BIT(MTK_CLK_SGMII_CDR_FB) | \
- BIT(MTK_CLK_SGMII2_TX_250M) | \
- BIT(MTK_CLK_SGMII2_RX_250M) | \
- BIT(MTK_CLK_SGMII2_CDR_REF) | \
- BIT(MTK_CLK_SGMII2_CDR_FB))
+#define MT7629_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \
+ BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \
+ BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_FE) | \
+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \
+ BIT_ULL(MTK_CLK_SGMII_CK) | \
+ BIT_ULL(MTK_CLK_ETH2PLL) | BIT_ULL(MTK_CLK_SGMIITOP))
+#define MT7981_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | \
+ BIT_ULL(MTK_CLK_GP1) | \
+ BIT_ULL(MTK_CLK_WOCPU0) | \
+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \
+ BIT_ULL(MTK_CLK_SGMII_CK))
+#define MT7986_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | \
+ BIT_ULL(MTK_CLK_GP1) | \
+ BIT_ULL(MTK_CLK_WOCPU1) | BIT_ULL(MTK_CLK_WOCPU0) | \
+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB))
enum mtk_dev_state {
MTK_HW_INIT,
@@ -1043,7 +1045,7 @@ struct mtk_soc_data {
const struct mtk_reg_map *reg_map;
u32 ana_rgc3;
u64 caps;
- u32 required_clks;
+ u64 required_clks;
bool required_pctl;
u8 offload_version;
u8 hash_offset;

View File

@ -0,0 +1,477 @@
From 94f825a7eadfc8b4c8828efdb7705d9703f9c73e Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Tue, 25 Jul 2023 01:57:42 +0100
Subject: [PATCH 105/250] net: ethernet: mtk_eth_soc: add basic support for
MT7988 SoC
Introduce support for ethernet chip available in MT7988 SoC to
mtk_eth_soc driver. As a first step support only the first GMAC which
is hard-wired to the internal DSA switch having 4 built-in gigabit
Ethernet PHYs.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Link: https://lore.kernel.org/r/25c8377095b95d186872eeda7aa055da83e8f0ca.1690246605.git.daniel@makrotopia.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/mediatek/mtk_eth_path.c | 14 +-
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 201 +++++++++++++++++--
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 86 +++++++-
3 files changed, 273 insertions(+), 28 deletions(-)
--- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
@@ -43,7 +43,7 @@ static const char *mtk_eth_path_name(u64
static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, u64 path)
{
bool updated = true;
- u32 val, mask, set;
+ u32 mask, set, reg;
switch (path) {
case MTK_ETH_PATH_GMAC1_SGMII:
@@ -59,11 +59,13 @@ static int set_mux_gdm1_to_gmac1_esw(str
break;
}
- if (updated) {
- val = mtk_r32(eth, MTK_MAC_MISC);
- val = (val & mask) | set;
- mtk_w32(eth, val, MTK_MAC_MISC);
- }
+ if (mtk_is_netsys_v3_or_greater(eth))
+ reg = MTK_MAC_MISC_V3;
+ else
+ reg = MTK_MAC_MISC;
+
+ if (updated)
+ mtk_m32(eth, mask, set, reg);
dev_dbg(eth->dev, "path %s in %s updated = %d\n",
mtk_eth_path_name(path), __func__, updated);
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -152,6 +152,54 @@ static const struct mtk_reg_map mt7986_r
.pse_oq_sta = 0x01a0,
};
+static const struct mtk_reg_map mt7988_reg_map = {
+ .tx_irq_mask = 0x461c,
+ .tx_irq_status = 0x4618,
+ .pdma = {
+ .rx_ptr = 0x6900,
+ .rx_cnt_cfg = 0x6904,
+ .pcrx_ptr = 0x6908,
+ .glo_cfg = 0x6a04,
+ .rst_idx = 0x6a08,
+ .delay_irq = 0x6a0c,
+ .irq_status = 0x6a20,
+ .irq_mask = 0x6a28,
+ .adma_rx_dbg0 = 0x6a38,
+ .int_grp = 0x6a50,
+ },
+ .qdma = {
+ .qtx_cfg = 0x4400,
+ .qtx_sch = 0x4404,
+ .rx_ptr = 0x4500,
+ .rx_cnt_cfg = 0x4504,
+ .qcrx_ptr = 0x4508,
+ .glo_cfg = 0x4604,
+ .rst_idx = 0x4608,
+ .delay_irq = 0x460c,
+ .fc_th = 0x4610,
+ .int_grp = 0x4620,
+ .hred = 0x4644,
+ .ctx_ptr = 0x4700,
+ .dtx_ptr = 0x4704,
+ .crx_ptr = 0x4710,
+ .drx_ptr = 0x4714,
+ .fq_head = 0x4720,
+ .fq_tail = 0x4724,
+ .fq_count = 0x4728,
+ .fq_blen = 0x472c,
+ .tx_sch_rate = 0x4798,
+ },
+ .gdm1_cnt = 0x1c00,
+ .gdma_to_ppe0 = 0x3333,
+ .ppe_base = 0x2000,
+ .wdma_base = {
+ [0] = 0x4800,
+ [1] = 0x4c00,
+ },
+ .pse_iq_sta = 0x0180,
+ .pse_oq_sta = 0x01a0,
+};
+
/* strings used by ethtool */
static const struct mtk_ethtool_stats {
char str[ETH_GSTRING_LEN];
@@ -179,10 +227,54 @@ static const struct mtk_ethtool_stats {
};
static const char * const mtk_clks_source_name[] = {
- "ethif", "sgmiitop", "esw", "gp0", "gp1", "gp2", "fe", "trgpll",
- "sgmii_tx250m", "sgmii_rx250m", "sgmii_cdr_ref", "sgmii_cdr_fb",
- "sgmii2_tx250m", "sgmii2_rx250m", "sgmii2_cdr_ref", "sgmii2_cdr_fb",
- "sgmii_ck", "eth2pll", "wocpu0", "wocpu1", "netsys0", "netsys1"
+ "ethif",
+ "sgmiitop",
+ "esw",
+ "gp0",
+ "gp1",
+ "gp2",
+ "gp3",
+ "xgp1",
+ "xgp2",
+ "xgp3",
+ "crypto",
+ "fe",
+ "trgpll",
+ "sgmii_tx250m",
+ "sgmii_rx250m",
+ "sgmii_cdr_ref",
+ "sgmii_cdr_fb",
+ "sgmii2_tx250m",
+ "sgmii2_rx250m",
+ "sgmii2_cdr_ref",
+ "sgmii2_cdr_fb",
+ "sgmii_ck",
+ "eth2pll",
+ "wocpu0",
+ "wocpu1",
+ "netsys0",
+ "netsys1",
+ "ethwarp_wocpu2",
+ "ethwarp_wocpu1",
+ "ethwarp_wocpu0",
+ "top_usxgmii0_sel",
+ "top_usxgmii1_sel",
+ "top_sgm0_sel",
+ "top_sgm1_sel",
+ "top_xfi_phy0_xtal_sel",
+ "top_xfi_phy1_xtal_sel",
+ "top_eth_gmii_sel",
+ "top_eth_refck_50m_sel",
+ "top_eth_sys_200m_sel",
+ "top_eth_sys_sel",
+ "top_eth_xgmii_sel",
+ "top_eth_mii_sel",
+ "top_netsys_sel",
+ "top_netsys_500m_sel",
+ "top_netsys_pao_2x_sel",
+ "top_netsys_sync_250m_sel",
+ "top_netsys_ppefb_250m_sel",
+ "top_netsys_warp_sel",
};
void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg)
@@ -195,7 +287,7 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne
return __raw_readl(eth->base + reg);
}
-static u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned reg)
+u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg)
{
u32 val;
@@ -326,6 +418,19 @@ static void mtk_gmac0_rgmii_adjust(struc
dev_err(eth->dev, "Missing PLL configuration, ethernet may not work\n");
}
+static void mtk_setup_bridge_switch(struct mtk_eth *eth)
+{
+ /* Force Port1 XGMAC Link Up */
+ mtk_m32(eth, 0, MTK_XGMAC_FORCE_LINK(MTK_GMAC1_ID),
+ MTK_XGMAC_STS(MTK_GMAC1_ID));
+
+ /* Adjust GSW bridge IPG to 11 */
+ mtk_m32(eth, GSWTX_IPG_MASK | GSWRX_IPG_MASK,
+ (GSW_IPG_11 << GSWTX_IPG_SHIFT) |
+ (GSW_IPG_11 << GSWRX_IPG_SHIFT),
+ MTK_GSW_CFG);
+}
+
static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
phy_interface_t interface)
{
@@ -395,6 +500,8 @@ static void mtk_mac_config(struct phylin
goto init_err;
}
break;
+ case PHY_INTERFACE_MODE_INTERNAL:
+ break;
default:
goto err_phy;
}
@@ -472,6 +579,15 @@ static void mtk_mac_config(struct phylin
return;
}
+ /* Setup gmac */
+ if (mtk_is_netsys_v3_or_greater(eth) &&
+ mac->interface == PHY_INTERFACE_MODE_INTERNAL) {
+ mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id));
+ mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id));
+
+ mtk_setup_bridge_switch(eth);
+ }
+
return;
err_phy:
@@ -682,11 +798,15 @@ static int mtk_mdio_init(struct mtk_eth
}
divider = min_t(unsigned int, DIV_ROUND_UP(MDC_MAX_FREQ, max_clk), 63);
+ /* Configure MDC Turbo Mode */
+ if (mtk_is_netsys_v3_or_greater(eth))
+ mtk_m32(eth, 0, MISC_MDC_TURBO, MTK_MAC_MISC_V3);
+
/* Configure MDC Divider */
- val = mtk_r32(eth, MTK_PPSC);
- val &= ~PPSC_MDC_CFG;
- val |= FIELD_PREP(PPSC_MDC_CFG, divider) | PPSC_MDC_TURBO;
- mtk_w32(eth, val, MTK_PPSC);
+ val = FIELD_PREP(PPSC_MDC_CFG, divider);
+ if (!mtk_is_netsys_v3_or_greater(eth))
+ val |= PPSC_MDC_TURBO;
+ mtk_m32(eth, PPSC_MDC_CFG, val, MTK_PPSC);
dev_dbg(eth->dev, "MDC is running on %d Hz\n", MDC_MAX_FREQ / divider);
@@ -1145,10 +1265,19 @@ static void mtk_tx_set_dma_desc_v2(struc
data |= TX_DMA_LS0;
WRITE_ONCE(desc->txd3, data);
- if (mac->id == MTK_GMAC3_ID)
- data = PSE_GDM3_PORT;
- else
- data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
+ /* set forward port */
+ switch (mac->id) {
+ case MTK_GMAC1_ID:
+ data = PSE_GDM1_PORT << TX_DMA_FPORT_SHIFT_V2;
+ break;
+ case MTK_GMAC2_ID:
+ data = PSE_GDM2_PORT << TX_DMA_FPORT_SHIFT_V2;
+ break;
+ case MTK_GMAC3_ID:
+ data = PSE_GDM3_PORT << TX_DMA_FPORT_SHIFT_V2;
+ break;
+ }
+
data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid);
WRITE_ONCE(desc->txd4, data);
@@ -4304,6 +4433,17 @@ static int mtk_add_mac(struct mtk_eth *e
mac->phylink_config.supported_interfaces);
}
+ if (mtk_is_netsys_v3_or_greater(mac->hw) &&
+ MTK_HAS_CAPS(mac->hw->soc->caps, MTK_ESW_BIT) &&
+ id == MTK_GMAC1_ID) {
+ mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE |
+ MAC_SYM_PAUSE |
+ MAC_10000FD;
+ phy_interface_zero(mac->phylink_config.supported_interfaces);
+ __set_bit(PHY_INTERFACE_MODE_INTERNAL,
+ mac->phylink_config.supported_interfaces);
+ }
+
phylink = phylink_create(&mac->phylink_config,
of_fwnode_handle(mac->of_node),
phy_mode, &mtk_phylink_ops);
@@ -4826,6 +4966,24 @@ static const struct mtk_soc_data mt7986_
},
};
+static const struct mtk_soc_data mt7988_data = {
+ .reg_map = &mt7988_reg_map,
+ .ana_rgc3 = 0x128,
+ .caps = MT7988_CAPS,
+ .hw_features = MTK_HW_FEATURES,
+ .required_clks = MT7988_CLKS_BITMAP,
+ .required_pctl = false,
+ .version = 3,
+ .txrx = {
+ .txd_size = sizeof(struct mtk_tx_dma_v2),
+ .rxd_size = sizeof(struct mtk_rx_dma_v2),
+ .rx_irq_done_mask = MTK_RX_DONE_INT_V2,
+ .rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
+ .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
+ .dma_len_offset = 8,
+ },
+};
+
static const struct mtk_soc_data rt5350_data = {
.reg_map = &mt7628_reg_map,
.caps = MT7628_CAPS,
@@ -4844,14 +5002,15 @@ static const struct mtk_soc_data rt5350_
};
const struct of_device_id of_mtk_match[] = {
- { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data},
- { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data},
- { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data},
- { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data},
- { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data},
- { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data},
- { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data},
- { .compatible = "ralink,rt5350-eth", .data = &rt5350_data},
+ { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data },
+ { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data },
+ { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data },
+ { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data },
+ { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data },
+ { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data },
+ { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data },
+ { .compatible = "mediatek,mt7988-eth", .data = &mt7988_data },
+ { .compatible = "ralink,rt5350-eth", .data = &rt5350_data },
{},
};
MODULE_DEVICE_TABLE(of, of_mtk_match);
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -117,7 +117,8 @@
#define MTK_CDMP_EG_CTRL 0x404
/* GDM Exgress Control Register */
-#define MTK_GDMA_FWD_CFG(x) (0x500 + (x * 0x1000))
+#define MTK_GDMA_FWD_CFG(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \
+ 0x540 : 0x500 + (_x * 0x1000); })
#define MTK_GDMA_SPECIAL_TAG BIT(24)
#define MTK_GDMA_ICS_EN BIT(22)
#define MTK_GDMA_TCS_EN BIT(21)
@@ -126,6 +127,11 @@
#define MTK_GDMA_TO_PDMA 0x0
#define MTK_GDMA_DROP_ALL 0x7777
+/* GDM Egress Control Register */
+#define MTK_GDMA_EG_CTRL(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \
+ 0x544 : 0x504 + (_x * 0x1000); })
+#define MTK_GDMA_XGDM_SEL BIT(31)
+
/* Unicast Filter MAC Address Register - Low */
#define MTK_GDMA_MAC_ADRL(x) (0x508 + (x * 0x1000))
@@ -386,7 +392,26 @@
#define PHY_IAC_TIMEOUT HZ
#define MTK_MAC_MISC 0x1000c
+#define MTK_MAC_MISC_V3 0x10010
#define MTK_MUX_TO_ESW BIT(0)
+#define MISC_MDC_TURBO BIT(4)
+
+/* XMAC status registers */
+#define MTK_XGMAC_STS(x) (((x) == MTK_GMAC3_ID) ? 0x1001C : 0x1000C)
+#define MTK_XGMAC_FORCE_LINK(x) (((x) == MTK_GMAC2_ID) ? BIT(31) : BIT(15))
+#define MTK_USXGMII_PCS_LINK BIT(8)
+#define MTK_XGMAC_RX_FC BIT(5)
+#define MTK_XGMAC_TX_FC BIT(4)
+#define MTK_USXGMII_PCS_MODE GENMASK(3, 1)
+#define MTK_XGMAC_LINK_STS BIT(0)
+
+/* GSW bridge registers */
+#define MTK_GSW_CFG (0x10080)
+#define GSWTX_IPG_MASK GENMASK(19, 16)
+#define GSWTX_IPG_SHIFT 16
+#define GSWRX_IPG_MASK GENMASK(3, 0)
+#define GSWRX_IPG_SHIFT 0
+#define GSW_IPG_11 11
/* Mac control registers */
#define MTK_MAC_MCR(x) (0x10100 + (x * 0x100))
@@ -644,6 +669,11 @@ enum mtk_clks_map {
MTK_CLK_GP0,
MTK_CLK_GP1,
MTK_CLK_GP2,
+ MTK_CLK_GP3,
+ MTK_CLK_XGP1,
+ MTK_CLK_XGP2,
+ MTK_CLK_XGP3,
+ MTK_CLK_CRYPTO,
MTK_CLK_FE,
MTK_CLK_TRGPLL,
MTK_CLK_SGMII_TX_250M,
@@ -660,6 +690,27 @@ enum mtk_clks_map {
MTK_CLK_WOCPU1,
MTK_CLK_NETSYS0,
MTK_CLK_NETSYS1,
+ MTK_CLK_ETHWARP_WOCPU2,
+ MTK_CLK_ETHWARP_WOCPU1,
+ MTK_CLK_ETHWARP_WOCPU0,
+ MTK_CLK_TOP_USXGMII_SBUS_0_SEL,
+ MTK_CLK_TOP_USXGMII_SBUS_1_SEL,
+ MTK_CLK_TOP_SGM_0_SEL,
+ MTK_CLK_TOP_SGM_1_SEL,
+ MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL,
+ MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL,
+ MTK_CLK_TOP_ETH_GMII_SEL,
+ MTK_CLK_TOP_ETH_REFCK_50M_SEL,
+ MTK_CLK_TOP_ETH_SYS_200M_SEL,
+ MTK_CLK_TOP_ETH_SYS_SEL,
+ MTK_CLK_TOP_ETH_XGMII_SEL,
+ MTK_CLK_TOP_ETH_MII_SEL,
+ MTK_CLK_TOP_NETSYS_SEL,
+ MTK_CLK_TOP_NETSYS_500M_SEL,
+ MTK_CLK_TOP_NETSYS_PAO_2X_SEL,
+ MTK_CLK_TOP_NETSYS_SYNC_250M_SEL,
+ MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL,
+ MTK_CLK_TOP_NETSYS_WARP_SEL,
MTK_CLK_MAX
};
@@ -713,6 +764,36 @@ enum mtk_clks_map {
BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
BIT_ULL(MTK_CLK_SGMII2_CDR_FB))
+#define MT7988_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_ESW) | \
+ BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \
+ BIT_ULL(MTK_CLK_GP3) | BIT_ULL(MTK_CLK_XGP1) | \
+ BIT_ULL(MTK_CLK_XGP2) | BIT_ULL(MTK_CLK_XGP3) | \
+ BIT_ULL(MTK_CLK_CRYPTO) | \
+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU2) | \
+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU1) | \
+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU0) | \
+ BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_0_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_1_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_SGM_0_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_SGM_1_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_ETH_GMII_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_ETH_REFCK_50M_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_ETH_SYS_200M_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_ETH_SYS_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_ETH_XGMII_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_ETH_MII_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_NETSYS_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_NETSYS_500M_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_NETSYS_PAO_2X_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_NETSYS_SYNC_250M_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_NETSYS_WARP_SEL))
enum mtk_dev_state {
MTK_HW_INIT,
@@ -961,6 +1042,8 @@ enum mkt_eth_capabilities {
MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
MTK_RSTCTRL_PPE1)
+#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1)
+
struct mtk_tx_dma_desc_info {
dma_addr_t addr;
u32 size;
@@ -1306,6 +1389,7 @@ void mtk_stats_update_mac(struct mtk_mac
void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg);
u32 mtk_r32(struct mtk_eth *eth, unsigned reg);
+u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg);
int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id);

View File

@ -0,0 +1,27 @@
From 38a7eb76220731eff40602cf433f24880be0a6c2 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Thu, 27 Jul 2023 09:02:26 +0200
Subject: [PATCH 106/250] net: ethernet: mtk_eth_soc: enable page_pool support
for MT7988 SoC
In order to recycle pages, enable page_pool allocator for MT7988 SoC.
Tested-by: Daniel Golle <daniel@makrotopia.org>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://lore.kernel.org/r/fd4e8693980e47385a543e7b002eec0b88bd09df.1690440675.git.lorenzo@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -1613,7 +1613,7 @@ static void mtk_update_rx_cpu_idx(struct
static bool mtk_page_pool_enabled(struct mtk_eth *eth)
{
- return eth->soc->version == 2;
+ return mtk_is_netsys_v2_or_greater(eth);
}
static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth,

View File

@ -0,0 +1,135 @@
From 199e7d5a7f03dd377f3a7a458360dbedd71d50ba Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Thu, 27 Jul 2023 09:07:28 +0200
Subject: [PATCH 107/250] net: ethernet: mtk_eth_soc: enable nft hw
flowtable_offload for MT7988 SoC
Enable hw Packet Process Engine (PPE) for MT7988 SoC.
Tested-by: Daniel Golle <daniel@makrotopia.org>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://lore.kernel.org/r/5e86341b0220a49620dadc02d77970de5ded9efc.1690441576.git.lorenzo@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 +++
drivers/net/ethernet/mediatek/mtk_ppe.c | 19 +++++++++++++++----
drivers/net/ethernet/mediatek/mtk_ppe.h | 19 ++++++++++++++++++-
3 files changed, 36 insertions(+), 5 deletions(-)
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -4974,6 +4974,9 @@ static const struct mtk_soc_data mt7988_
.required_clks = MT7988_CLKS_BITMAP,
.required_pctl = false,
.version = 3,
+ .offload_version = 2,
+ .hash_offset = 4,
+ .foe_entry_size = MTK_FOE_ENTRY_V3_SIZE,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma_v2),
.rxd_size = sizeof(struct mtk_rx_dma_v2),
--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
@@ -422,13 +422,22 @@ int mtk_foe_entry_set_wdma(struct mtk_et
struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry);
u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
- if (mtk_is_netsys_v2_or_greater(eth)) {
+ switch (eth->soc->version) {
+ case 3:
+ *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2;
+ *ib2 |= FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) |
+ MTK_FOE_IB2_WDMA_WINFO_V2;
+ l2->w3info = FIELD_PREP(MTK_FOE_WINFO_WCID_V3, wcid) |
+ FIELD_PREP(MTK_FOE_WINFO_BSS_V3, bss);
+ break;
+ case 2:
*ib2 &= ~MTK_FOE_IB2_PORT_MG_V2;
*ib2 |= FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) |
MTK_FOE_IB2_WDMA_WINFO_V2;
l2->winfo = FIELD_PREP(MTK_FOE_WINFO_WCID, wcid) |
FIELD_PREP(MTK_FOE_WINFO_BSS, bss);
- } else {
+ break;
+ default:
*ib2 &= ~MTK_FOE_IB2_PORT_MG;
*ib2 |= MTK_FOE_IB2_WDMA_WINFO;
if (wdma_idx)
@@ -436,6 +445,7 @@ int mtk_foe_entry_set_wdma(struct mtk_et
l2->vlan2 = FIELD_PREP(MTK_FOE_VLAN2_WINFO_BSS, bss) |
FIELD_PREP(MTK_FOE_VLAN2_WINFO_WCID, wcid) |
FIELD_PREP(MTK_FOE_VLAN2_WINFO_RING, txq);
+ break;
}
return 0;
@@ -956,8 +966,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
mtk_ppe_init_foe_table(ppe);
ppe_w32(ppe, MTK_PPE_TB_BASE, ppe->foe_phys);
- val = MTK_PPE_TB_CFG_ENTRY_80B |
- MTK_PPE_TB_CFG_AGE_NON_L4 |
+ val = MTK_PPE_TB_CFG_AGE_NON_L4 |
MTK_PPE_TB_CFG_AGE_UNBIND |
MTK_PPE_TB_CFG_AGE_TCP |
MTK_PPE_TB_CFG_AGE_UDP |
@@ -973,6 +982,8 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
MTK_PPE_ENTRIES_SHIFT);
if (mtk_is_netsys_v2_or_greater(ppe->eth))
val |= MTK_PPE_TB_CFG_INFO_SEL;
+ if (!mtk_is_netsys_v3_or_greater(ppe->eth))
+ val |= MTK_PPE_TB_CFG_ENTRY_80B;
ppe_w32(ppe, MTK_PPE_TB_CFG, val);
ppe_w32(ppe, MTK_PPE_IP_PROTO_CHK,
--- a/drivers/net/ethernet/mediatek/mtk_ppe.h
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
@@ -85,6 +85,17 @@ enum {
#define MTK_FOE_WINFO_BSS GENMASK(5, 0)
#define MTK_FOE_WINFO_WCID GENMASK(15, 6)
+#define MTK_FOE_WINFO_BSS_V3 GENMASK(23, 16)
+#define MTK_FOE_WINFO_WCID_V3 GENMASK(15, 0)
+
+#define MTK_FOE_WINFO_PAO_USR_INFO GENMASK(15, 0)
+#define MTK_FOE_WINFO_PAO_TID GENMASK(19, 16)
+#define MTK_FOE_WINFO_PAO_IS_FIXEDRATE BIT(20)
+#define MTK_FOE_WINFO_PAO_IS_PRIOR BIT(21)
+#define MTK_FOE_WINFO_PAO_IS_SP BIT(22)
+#define MTK_FOE_WINFO_PAO_HF BIT(23)
+#define MTK_FOE_WINFO_PAO_AMSDU_EN BIT(24)
+
enum {
MTK_FOE_STATE_INVALID,
MTK_FOE_STATE_UNBIND,
@@ -106,8 +117,13 @@ struct mtk_foe_mac_info {
u16 pppoe_id;
u16 src_mac_lo;
+ /* netsys_v2 */
u16 minfo;
u16 winfo;
+
+ /* netsys_v3 */
+ u32 w3info;
+ u32 wpao;
};
/* software-only entry type */
@@ -218,6 +234,7 @@ struct mtk_foe_ipv6_6rd {
#define MTK_FOE_ENTRY_V1_SIZE 80
#define MTK_FOE_ENTRY_V2_SIZE 96
+#define MTK_FOE_ENTRY_V3_SIZE 128
struct mtk_foe_entry {
u32 ib1;
@@ -228,7 +245,7 @@ struct mtk_foe_entry {
struct mtk_foe_ipv4_dslite dslite;
struct mtk_foe_ipv6 ipv6;
struct mtk_foe_ipv6_6rd ipv6_6rd;
- u32 data[23];
+ u32 data[31];
};
};

View File

@ -0,0 +1,78 @@
From 0c024632c1e7ff69914329bfd87bec749b9c0aed Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Wed, 2 Aug 2023 04:31:09 +0100
Subject: [PATCH 108/250] net: ethernet: mtk_eth_soc: support per-flow
accounting on MT7988
NETSYS_V3 uses 64 bits for each counters while older SoCs are using
48/40 bits for each counter.
Support reading per-flow byte and package counters on NETSYS_V3.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://lore.kernel.org/r/37a0928fa8c1253b197884c68ce1f54239421ac5.1690946442.git.daniel@makrotopia.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1 +
drivers/net/ethernet/mediatek/mtk_ppe.c | 21 +++++++++++++-------
drivers/net/ethernet/mediatek/mtk_ppe_regs.h | 2 ++
3 files changed, 17 insertions(+), 7 deletions(-)
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -4976,6 +4976,7 @@ static const struct mtk_soc_data mt7988_
.version = 3,
.offload_version = 2,
.hash_offset = 4,
+ .has_accounting = true,
.foe_entry_size = MTK_FOE_ENTRY_V3_SIZE,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma_v2),
--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
@@ -91,7 +91,6 @@ static int mtk_ppe_mib_wait_busy(struct
static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *packets)
{
- u32 byte_cnt_low, byte_cnt_high, pkt_cnt_low, pkt_cnt_high;
u32 val, cnt_r0, cnt_r1, cnt_r2;
int ret;
@@ -106,12 +105,20 @@ static int mtk_mib_entry_read(struct mtk
cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1);
cnt_r2 = readl(ppe->base + MTK_PPE_MIB_SER_R2);
- byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0);
- byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1);
- pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1);
- pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2);
- *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low;
- *packets = (pkt_cnt_high << 16) | pkt_cnt_low;
+ if (mtk_is_netsys_v3_or_greater(ppe->eth)) {
+ /* 64 bit for each counter */
+ u32 cnt_r3 = readl(ppe->base + MTK_PPE_MIB_SER_R3);
+ *bytes = ((u64)cnt_r1 << 32) | cnt_r0;
+ *packets = ((u64)cnt_r3 << 32) | cnt_r2;
+ } else {
+ /* 48 bit byte counter, 40 bit packet counter */
+ u32 byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0);
+ u32 byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1);
+ u32 pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1);
+ u32 pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2);
+ *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low;
+ *packets = (pkt_cnt_high << 16) | pkt_cnt_low;
+ }
return 0;
}
--- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
+++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
@@ -163,6 +163,8 @@ enum {
#define MTK_PPE_MIB_SER_R2 0x348
#define MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH GENMASK(23, 0)
+#define MTK_PPE_MIB_SER_R3 0x34c
+
#define MTK_PPE_MIB_CACHE_CTL 0x350
#define MTK_PPE_MIB_CACHE_CTL_EN BIT(0)
#define MTK_PPE_MIB_CACHE_CTL_FLUSH BIT(2)

View File

@ -0,0 +1,52 @@
From 3b12f42772c26869d60398c1710aa27b27cd945c Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Mon, 21 Aug 2023 17:12:44 +0100
Subject: [PATCH 109/250] net: ethernet: mtk_eth_soc: fix NULL pointer on hw
reset
When a hardware reset is triggered on devices not initializing WED the
calls to mtk_wed_fe_reset and mtk_wed_fe_reset_complete dereference a
pointer on uninitialized stack memory.
Break out of both functions in case a hw_list entry is 0.
Fixes: 08a764a7c51b ("net: ethernet: mtk_wed: add reset/reset_complete callbacks")
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Simon Horman <horms@kernel.org>
Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://lore.kernel.org/r/5465c1609b464cc7407ae1530c40821dcdf9d3e6.1692634266.git.daniel@makrotopia.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/mediatek/mtk_wed.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
@@ -214,9 +214,13 @@ void mtk_wed_fe_reset(void)
for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
struct mtk_wed_hw *hw = hw_list[i];
- struct mtk_wed_device *dev = hw->wed_dev;
+ struct mtk_wed_device *dev;
int err;
+ if (!hw)
+ break;
+
+ dev = hw->wed_dev;
if (!dev || !dev->wlan.reset)
continue;
@@ -237,8 +241,12 @@ void mtk_wed_fe_reset_complete(void)
for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
struct mtk_wed_hw *hw = hw_list[i];
- struct mtk_wed_device *dev = hw->wed_dev;
+ struct mtk_wed_device *dev;
+
+ if (!hw)
+ break;
+ dev = hw->wed_dev;
if (!dev || !dev->wlan.reset_complete)
continue;

View File

@ -0,0 +1,44 @@
From 489aea123d74a846ce746bfdb3efe1e7ad512e0d Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Tue, 22 Aug 2023 17:31:24 +0100
Subject: [PATCH 110/250] net: ethernet: mtk_eth_soc: fix register definitions
for MT7988
More register macros need to be adjusted for the 3rd GMAC on MT7988.
Account for added bit in SYSCFG0_SGMII_MASK.
Fixes: 445eb6448ed3 ("net: ethernet: mtk_eth_soc: add basic support for MT7988 SoC")
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://lore.kernel.org/r/1c8da012e2ca80939906d85f314138c552139f0f.1692721443.git.daniel@makrotopia.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -133,10 +133,12 @@
#define MTK_GDMA_XGDM_SEL BIT(31)
/* Unicast Filter MAC Address Register - Low */
-#define MTK_GDMA_MAC_ADRL(x) (0x508 + (x * 0x1000))
+#define MTK_GDMA_MAC_ADRL(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \
+ 0x548 : 0x508 + (_x * 0x1000); })
/* Unicast Filter MAC Address Register - High */
-#define MTK_GDMA_MAC_ADRH(x) (0x50C + (x * 0x1000))
+#define MTK_GDMA_MAC_ADRH(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \
+ 0x54C : 0x50C + (_x * 0x1000); })
/* FE global misc reg*/
#define MTK_FE_GLO_MISC 0x124
@@ -500,7 +502,7 @@
#define ETHSYS_SYSCFG0 0x14
#define SYSCFG0_GE_MASK 0x3
#define SYSCFG0_GE_MODE(x, y) (x << (12 + (y * 2)))
-#define SYSCFG0_SGMII_MASK GENMASK(9, 8)
+#define SYSCFG0_SGMII_MASK GENMASK(9, 7)
#define SYSCFG0_SGMII_GMAC1 ((2 << 8) & SYSCFG0_SGMII_MASK)
#define SYSCFG0_SGMII_GMAC2 ((3 << 8) & SYSCFG0_SGMII_MASK)
#define SYSCFG0_SGMII_GMAC1_V2 BIT(9)

View File

@ -0,0 +1,188 @@
From 15a84d1c44ae8c1451c265ee60500588a24e8cd6 Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Tue, 22 Aug 2023 17:32:03 +0100
Subject: [PATCH 111/250] net: ethernet: mtk_eth_soc: add reset bits for MT7988
Add bits needed to reset the frame engine on MT7988.
Fixes: 445eb6448ed3 ("net: ethernet: mtk_eth_soc: add basic support for MT7988 SoC")
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Link: https://lore.kernel.org/r/89b6c38380e7a3800c1362aa7575600717bc7543.1692721443.git.daniel@makrotopia.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 76 +++++++++++++++------
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 16 +++--
2 files changed, 68 insertions(+), 24 deletions(-)
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -3538,19 +3538,34 @@ static void mtk_hw_reset(struct mtk_eth
{
u32 val;
- if (mtk_is_netsys_v2_or_greater(eth)) {
+ if (mtk_is_netsys_v2_or_greater(eth))
regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
+
+ if (mtk_is_netsys_v3_or_greater(eth)) {
+ val = RSTCTRL_PPE0_V3;
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
+ val |= RSTCTRL_PPE1_V3;
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2))
+ val |= RSTCTRL_PPE2;
+
+ val |= RSTCTRL_WDMA0 | RSTCTRL_WDMA1 | RSTCTRL_WDMA2;
+ } else if (mtk_is_netsys_v2_or_greater(eth)) {
val = RSTCTRL_PPE0_V2;
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
+ val |= RSTCTRL_PPE1;
} else {
val = RSTCTRL_PPE0;
}
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
- val |= RSTCTRL_PPE1;
-
ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
- if (mtk_is_netsys_v2_or_greater(eth))
+ if (mtk_is_netsys_v3_or_greater(eth))
+ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
+ 0x6f8ff);
+ else if (mtk_is_netsys_v2_or_greater(eth))
regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
0x3ffffff);
}
@@ -3576,13 +3591,21 @@ static void mtk_hw_warm_reset(struct mtk
return;
}
- if (mtk_is_netsys_v2_or_greater(eth))
+ if (mtk_is_netsys_v3_or_greater(eth)) {
+ rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V3;
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
+ rst_mask |= RSTCTRL_PPE1_V3;
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2))
+ rst_mask |= RSTCTRL_PPE2;
+
+ rst_mask |= RSTCTRL_WDMA0 | RSTCTRL_WDMA1 | RSTCTRL_WDMA2;
+ } else if (mtk_is_netsys_v2_or_greater(eth)) {
rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V2;
- else
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
+ rst_mask |= RSTCTRL_PPE1;
+ } else {
rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0;
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
- rst_mask |= RSTCTRL_PPE1;
+ }
regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, rst_mask, rst_mask);
@@ -3934,11 +3957,17 @@ static void mtk_prepare_for_reset(struct
u32 val;
int i;
- /* disabe FE P3 and P4 */
- val = mtk_r32(eth, MTK_FE_GLO_CFG) | MTK_FE_LINK_DOWN_P3;
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
- val |= MTK_FE_LINK_DOWN_P4;
- mtk_w32(eth, val, MTK_FE_GLO_CFG);
+ /* set FE PPE ports link down */
+ for (i = MTK_GMAC1_ID;
+ i <= (mtk_is_netsys_v3_or_greater(eth) ? MTK_GMAC3_ID : MTK_GMAC2_ID);
+ i += 2) {
+ val = mtk_r32(eth, MTK_FE_GLO_CFG(i)) | MTK_FE_LINK_DOWN_P(PSE_PPE0_PORT);
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
+ val |= MTK_FE_LINK_DOWN_P(PSE_PPE1_PORT);
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2))
+ val |= MTK_FE_LINK_DOWN_P(PSE_PPE2_PORT);
+ mtk_w32(eth, val, MTK_FE_GLO_CFG(i));
+ }
/* adjust PPE configurations to prepare for reset */
for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
@@ -3999,11 +4028,18 @@ static void mtk_pending_work(struct work
}
}
- /* enabe FE P3 and P4 */
- val = mtk_r32(eth, MTK_FE_GLO_CFG) & ~MTK_FE_LINK_DOWN_P3;
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
- val &= ~MTK_FE_LINK_DOWN_P4;
- mtk_w32(eth, val, MTK_FE_GLO_CFG);
+ /* set FE PPE ports link up */
+ for (i = MTK_GMAC1_ID;
+ i <= (mtk_is_netsys_v3_or_greater(eth) ? MTK_GMAC3_ID : MTK_GMAC2_ID);
+ i += 2) {
+ val = mtk_r32(eth, MTK_FE_GLO_CFG(i)) & ~MTK_FE_LINK_DOWN_P(PSE_PPE0_PORT);
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
+ val &= ~MTK_FE_LINK_DOWN_P(PSE_PPE1_PORT);
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2))
+ val &= ~MTK_FE_LINK_DOWN_P(PSE_PPE2_PORT);
+
+ mtk_w32(eth, val, MTK_FE_GLO_CFG(i));
+ }
clear_bit(MTK_RESETTING, &eth->state);
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -76,9 +76,8 @@
#define MTK_HW_LRO_SDL_REMAIN_ROOM 1522
/* Frame Engine Global Configuration */
-#define MTK_FE_GLO_CFG 0x00
-#define MTK_FE_LINK_DOWN_P3 BIT(11)
-#define MTK_FE_LINK_DOWN_P4 BIT(12)
+#define MTK_FE_GLO_CFG(x) (((x) == MTK_GMAC3_ID) ? 0x24 : 0x00)
+#define MTK_FE_LINK_DOWN_P(x) BIT(((x) + 8) % 16)
/* Frame Engine Global Reset Register */
#define MTK_RST_GL 0x04
@@ -519,9 +518,15 @@
/* ethernet reset control register */
#define ETHSYS_RSTCTRL 0x34
#define RSTCTRL_FE BIT(6)
+#define RSTCTRL_WDMA0 BIT(24)
+#define RSTCTRL_WDMA1 BIT(25)
+#define RSTCTRL_WDMA2 BIT(26)
#define RSTCTRL_PPE0 BIT(31)
#define RSTCTRL_PPE0_V2 BIT(30)
#define RSTCTRL_PPE1 BIT(31)
+#define RSTCTRL_PPE0_V3 BIT(29)
+#define RSTCTRL_PPE1_V3 BIT(30)
+#define RSTCTRL_PPE2 BIT(31)
#define RSTCTRL_ETH BIT(23)
/* ethernet reset check idle register */
@@ -928,6 +933,7 @@ enum mkt_eth_capabilities {
MTK_QDMA_BIT,
MTK_SOC_MT7628_BIT,
MTK_RSTCTRL_PPE1_BIT,
+ MTK_RSTCTRL_PPE2_BIT,
MTK_U3_COPHY_V2_BIT,
/* MUX BITS*/
@@ -962,6 +968,7 @@ enum mkt_eth_capabilities {
#define MTK_QDMA BIT_ULL(MTK_QDMA_BIT)
#define MTK_SOC_MT7628 BIT_ULL(MTK_SOC_MT7628_BIT)
#define MTK_RSTCTRL_PPE1 BIT_ULL(MTK_RSTCTRL_PPE1_BIT)
+#define MTK_RSTCTRL_PPE2 BIT_ULL(MTK_RSTCTRL_PPE2_BIT)
#define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT)
#define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \
@@ -1044,7 +1051,8 @@ enum mkt_eth_capabilities {
MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
MTK_RSTCTRL_PPE1)
-#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1)
+#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1 | \
+ MTK_RSTCTRL_PPE2)
struct mtk_tx_dma_desc_info {
dma_addr_t addr;

View File

@ -0,0 +1,254 @@
From 25ce45fe40b574e5d7ffa407f7f2db03e7d5a910 Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Tue, 22 Aug 2023 17:32:54 +0100
Subject: [PATCH 112/250] net: ethernet: mtk_eth_soc: add support for in-SoC
SRAM
MT7981, MT7986 and MT7988 come with in-SoC SRAM dedicated for Ethernet
DMA rings. Support using the SRAM without breaking existing device tree
bindings, ie. only new SoC starting from MT7988 will have the SRAM
declared as additional resource in device tree. For MT7981 and MT7986
an offset on top of the main I/O base is used.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Link: https://lore.kernel.org/r/e45e0f230c63ad58869e8fe35b95a2fb8925b625.1692721443.git.daniel@makrotopia.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 88 ++++++++++++++++-----
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 12 ++-
2 files changed, 78 insertions(+), 22 deletions(-)
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -1075,10 +1075,13 @@ static int mtk_init_fq_dma(struct mtk_et
dma_addr_t dma_addr;
int i;
- eth->scratch_ring = dma_alloc_coherent(eth->dma_dev,
- cnt * soc->txrx.txd_size,
- &eth->phy_scratch_ring,
- GFP_KERNEL);
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM))
+ eth->scratch_ring = eth->sram_base;
+ else
+ eth->scratch_ring = dma_alloc_coherent(eth->dma_dev,
+ cnt * soc->txrx.txd_size,
+ &eth->phy_scratch_ring,
+ GFP_KERNEL);
if (unlikely(!eth->scratch_ring))
return -ENOMEM;
@@ -2376,8 +2379,14 @@ static int mtk_tx_alloc(struct mtk_eth *
if (!ring->buf)
goto no_tx_mem;
- ring->dma = dma_alloc_coherent(eth->dma_dev, ring_size * sz,
- &ring->phys, GFP_KERNEL);
+ if (MTK_HAS_CAPS(soc->caps, MTK_SRAM)) {
+ ring->dma = eth->sram_base + ring_size * sz;
+ ring->phys = eth->phy_scratch_ring + ring_size * (dma_addr_t)sz;
+ } else {
+ ring->dma = dma_alloc_coherent(eth->dma_dev, ring_size * sz,
+ &ring->phys, GFP_KERNEL);
+ }
+
if (!ring->dma)
goto no_tx_mem;
@@ -2476,8 +2485,7 @@ static void mtk_tx_clean(struct mtk_eth
kfree(ring->buf);
ring->buf = NULL;
}
-
- if (ring->dma) {
+ if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && ring->dma) {
dma_free_coherent(eth->dma_dev,
ring->dma_size * soc->txrx.txd_size,
ring->dma, ring->phys);
@@ -2496,9 +2504,14 @@ static int mtk_rx_alloc(struct mtk_eth *
{
const struct mtk_reg_map *reg_map = eth->soc->reg_map;
struct mtk_rx_ring *ring;
- int rx_data_len, rx_dma_size;
+ int rx_data_len, rx_dma_size, tx_ring_size;
int i;
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA))
+ tx_ring_size = MTK_QDMA_RING_SIZE;
+ else
+ tx_ring_size = MTK_DMA_SIZE;
+
if (rx_flag == MTK_RX_FLAGS_QDMA) {
if (ring_no)
return -EINVAL;
@@ -2533,9 +2546,20 @@ static int mtk_rx_alloc(struct mtk_eth *
ring->page_pool = pp;
}
- ring->dma = dma_alloc_coherent(eth->dma_dev,
- rx_dma_size * eth->soc->txrx.rxd_size,
- &ring->phys, GFP_KERNEL);
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM) ||
+ rx_flag != MTK_RX_FLAGS_NORMAL) {
+ ring->dma = dma_alloc_coherent(eth->dma_dev,
+ rx_dma_size * eth->soc->txrx.rxd_size,
+ &ring->phys, GFP_KERNEL);
+ } else {
+ struct mtk_tx_ring *tx_ring = &eth->tx_ring;
+
+ ring->dma = tx_ring->dma + tx_ring_size *
+ eth->soc->txrx.txd_size * (ring_no + 1);
+ ring->phys = tx_ring->phys + tx_ring_size *
+ eth->soc->txrx.txd_size * (ring_no + 1);
+ }
+
if (!ring->dma)
return -ENOMEM;
@@ -2618,7 +2642,7 @@ static int mtk_rx_alloc(struct mtk_eth *
return 0;
}
-static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring)
+static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring, bool in_sram)
{
int i;
@@ -2641,7 +2665,7 @@ static void mtk_rx_clean(struct mtk_eth
ring->data = NULL;
}
- if (ring->dma) {
+ if (!in_sram && ring->dma) {
dma_free_coherent(eth->dma_dev,
ring->dma_size * eth->soc->txrx.rxd_size,
ring->dma, ring->phys);
@@ -3001,7 +3025,7 @@ static void mtk_dma_free(struct mtk_eth
for (i = 0; i < MTK_MAX_DEVS; i++)
if (eth->netdev[i])
netdev_reset_queue(eth->netdev[i]);
- if (eth->scratch_ring) {
+ if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && eth->scratch_ring) {
dma_free_coherent(eth->dma_dev,
MTK_QDMA_RING_SIZE * soc->txrx.txd_size,
eth->scratch_ring, eth->phy_scratch_ring);
@@ -3009,13 +3033,13 @@ static void mtk_dma_free(struct mtk_eth
eth->phy_scratch_ring = 0;
}
mtk_tx_clean(eth);
- mtk_rx_clean(eth, &eth->rx_ring[0]);
- mtk_rx_clean(eth, &eth->rx_ring_qdma);
+ mtk_rx_clean(eth, &eth->rx_ring[0], MTK_HAS_CAPS(soc->caps, MTK_SRAM));
+ mtk_rx_clean(eth, &eth->rx_ring_qdma, false);
if (eth->hwlro) {
mtk_hwlro_rx_uninit(eth);
for (i = 1; i < MTK_MAX_RX_RING_NUM; i++)
- mtk_rx_clean(eth, &eth->rx_ring[i]);
+ mtk_rx_clean(eth, &eth->rx_ring[i], false);
}
kfree(eth->scratch_head);
@@ -4585,7 +4609,7 @@ static int mtk_sgmii_init(struct mtk_eth
static int mtk_probe(struct platform_device *pdev)
{
- struct resource *res = NULL;
+ struct resource *res = NULL, *res_sram;
struct device_node *mac_np;
struct mtk_eth *eth;
int err, i;
@@ -4605,6 +4629,20 @@ static int mtk_probe(struct platform_dev
if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
eth->ip_align = NET_IP_ALIGN;
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM)) {
+ /* SRAM is actual memory and supports transparent access just like DRAM.
+ * Hence we don't require __iomem being set and don't need to use accessor
+ * functions to read from or write to SRAM.
+ */
+ if (mtk_is_netsys_v3_or_greater(eth)) {
+ eth->sram_base = (void __force *)devm_platform_ioremap_resource(pdev, 1);
+ if (IS_ERR(eth->sram_base))
+ return PTR_ERR(eth->sram_base);
+ } else {
+ eth->sram_base = (void __force *)eth->base + MTK_ETH_SRAM_OFFSET;
+ }
+ }
+
spin_lock_init(&eth->page_lock);
spin_lock_init(&eth->tx_irq_lock);
spin_lock_init(&eth->rx_irq_lock);
@@ -4668,6 +4706,18 @@ static int mtk_probe(struct platform_dev
err = -EINVAL;
goto err_destroy_sgmii;
}
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM)) {
+ if (mtk_is_netsys_v3_or_greater(eth)) {
+ res_sram = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res_sram) {
+ err = -EINVAL;
+ goto err_destroy_sgmii;
+ }
+ eth->phy_scratch_ring = res_sram->start;
+ } else {
+ eth->phy_scratch_ring = res->start + MTK_ETH_SRAM_OFFSET;
+ }
+ }
}
if (eth->soc->offload_version) {
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -139,6 +139,9 @@
#define MTK_GDMA_MAC_ADRH(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \
0x54C : 0x50C + (_x * 0x1000); })
+/* Internal SRAM offset */
+#define MTK_ETH_SRAM_OFFSET 0x40000
+
/* FE global misc reg*/
#define MTK_FE_GLO_MISC 0x124
@@ -935,6 +938,7 @@ enum mkt_eth_capabilities {
MTK_RSTCTRL_PPE1_BIT,
MTK_RSTCTRL_PPE2_BIT,
MTK_U3_COPHY_V2_BIT,
+ MTK_SRAM_BIT,
/* MUX BITS*/
MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
@@ -970,6 +974,7 @@ enum mkt_eth_capabilities {
#define MTK_RSTCTRL_PPE1 BIT_ULL(MTK_RSTCTRL_PPE1_BIT)
#define MTK_RSTCTRL_PPE2 BIT_ULL(MTK_RSTCTRL_PPE2_BIT)
#define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT)
+#define MTK_SRAM BIT_ULL(MTK_SRAM_BIT)
#define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \
BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
@@ -1045,14 +1050,14 @@ enum mkt_eth_capabilities {
#define MT7981_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \
MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \
- MTK_RSTCTRL_PPE1)
+ MTK_RSTCTRL_PPE1 | MTK_SRAM)
#define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
- MTK_RSTCTRL_PPE1)
+ MTK_RSTCTRL_PPE1 | MTK_SRAM)
#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1 | \
- MTK_RSTCTRL_PPE2)
+ MTK_RSTCTRL_PPE2 | MTK_SRAM)
struct mtk_tx_dma_desc_info {
dma_addr_t addr;
@@ -1212,6 +1217,7 @@ struct mtk_eth {
struct device *dev;
struct device *dma_dev;
void __iomem *base;
+ void *sram_base;
spinlock_t page_lock;
spinlock_t tx_irq_lock;
spinlock_t rx_irq_lock;

View File

@ -0,0 +1,166 @@
From 0b0d606eb9650fa01dd5621e072aa29a10544399 Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Tue, 22 Aug 2023 17:33:12 +0100
Subject: [PATCH 113/250] net: ethernet: mtk_eth_soc: support 36-bit DMA
addressing on MT7988
Systems having 4 GiB of RAM and more require DMA addressing beyond the
current 32-bit limit. Starting from MT7988 the hardware now supports
36-bit DMA addressing, let's use that new capability in the driver to
avoid running into swiotlb on systems with 4 GiB of RAM or more.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Link: https://lore.kernel.org/r/95b919c98876c9e49761e44662e7c937479eecb8.1692721443.git.daniel@makrotopia.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 +++++++++++++++++++--
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 22 +++++++++++++--
2 files changed, 48 insertions(+), 4 deletions(-)
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -1266,6 +1266,10 @@ static void mtk_tx_set_dma_desc_v2(struc
data = TX_DMA_PLEN0(info->size);
if (info->last)
data |= TX_DMA_LS0;
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
+ data |= TX_DMA_PREP_ADDR64(info->addr);
+
WRITE_ONCE(desc->txd3, data);
/* set forward port */
@@ -1933,6 +1937,7 @@ static int mtk_poll_rx(struct napi_struc
bool xdp_flush = false;
int idx;
struct sk_buff *skb;
+ u64 addr64 = 0;
u8 *data, *new_data;
struct mtk_rx_dma_v2 *rxd, trxd;
int done = 0, bytes = 0;
@@ -2048,7 +2053,10 @@ static int mtk_poll_rx(struct napi_struc
goto release_desc;
}
- dma_unmap_single(eth->dma_dev, trxd.rxd1,
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
+ addr64 = RX_DMA_GET_ADDR64(trxd.rxd2);
+
+ dma_unmap_single(eth->dma_dev, ((u64)trxd.rxd1 | addr64),
ring->buf_size, DMA_FROM_DEVICE);
skb = build_skb(data, ring->frag_size);
@@ -2114,6 +2122,9 @@ release_desc:
else
rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size);
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
+ rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr);
+
ring->calc_idx = idx;
done++;
}
@@ -2598,6 +2609,9 @@ static int mtk_rx_alloc(struct mtk_eth *
else
rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size);
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
+ rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr);
+
rxd->rxd3 = 0;
rxd->rxd4 = 0;
if (mtk_is_netsys_v2_or_greater(eth)) {
@@ -2644,6 +2658,7 @@ static int mtk_rx_alloc(struct mtk_eth *
static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring, bool in_sram)
{
+ u64 addr64 = 0;
int i;
if (ring->data && ring->dma) {
@@ -2657,7 +2672,10 @@ static void mtk_rx_clean(struct mtk_eth
if (!rxd->rxd1)
continue;
- dma_unmap_single(eth->dma_dev, rxd->rxd1,
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
+ addr64 = RX_DMA_GET_ADDR64(rxd->rxd2);
+
+ dma_unmap_single(eth->dma_dev, ((u64)rxd->rxd1 | addr64),
ring->buf_size, DMA_FROM_DEVICE);
mtk_rx_put_buff(ring, ring->data[i], false);
}
@@ -4643,6 +4661,14 @@ static int mtk_probe(struct platform_dev
}
}
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) {
+ err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36));
+ if (err) {
+ dev_err(&pdev->dev, "Wrong DMA config\n");
+ return -EINVAL;
+ }
+ }
+
spin_lock_init(&eth->page_lock);
spin_lock_init(&eth->tx_irq_lock);
spin_lock_init(&eth->rx_irq_lock);
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -331,6 +331,14 @@
#define TX_DMA_PLEN1(x) ((x) & eth->soc->txrx.dma_max_len)
#define TX_DMA_SWC BIT(14)
#define TX_DMA_PQID GENMASK(3, 0)
+#define TX_DMA_ADDR64_MASK GENMASK(3, 0)
+#if IS_ENABLED(CONFIG_64BIT)
+# define TX_DMA_GET_ADDR64(x) (((u64)FIELD_GET(TX_DMA_ADDR64_MASK, (x))) << 32)
+# define TX_DMA_PREP_ADDR64(x) FIELD_PREP(TX_DMA_ADDR64_MASK, ((x) >> 32))
+#else
+# define TX_DMA_GET_ADDR64(x) (0)
+# define TX_DMA_PREP_ADDR64(x) (0)
+#endif
/* PDMA on MT7628 */
#define TX_DMA_DONE BIT(31)
@@ -343,6 +351,14 @@
#define RX_DMA_PREP_PLEN0(x) (((x) & eth->soc->txrx.dma_max_len) << eth->soc->txrx.dma_len_offset)
#define RX_DMA_GET_PLEN0(x) (((x) >> eth->soc->txrx.dma_len_offset) & eth->soc->txrx.dma_max_len)
#define RX_DMA_VTAG BIT(15)
+#define RX_DMA_ADDR64_MASK GENMASK(3, 0)
+#if IS_ENABLED(CONFIG_64BIT)
+# define RX_DMA_GET_ADDR64(x) (((u64)FIELD_GET(RX_DMA_ADDR64_MASK, (x))) << 32)
+# define RX_DMA_PREP_ADDR64(x) FIELD_PREP(RX_DMA_ADDR64_MASK, ((x) >> 32))
+#else
+# define RX_DMA_GET_ADDR64(x) (0)
+# define RX_DMA_PREP_ADDR64(x) (0)
+#endif
/* QDMA descriptor rxd3 */
#define RX_DMA_VID(x) ((x) & VLAN_VID_MASK)
@@ -939,6 +955,7 @@ enum mkt_eth_capabilities {
MTK_RSTCTRL_PPE2_BIT,
MTK_U3_COPHY_V2_BIT,
MTK_SRAM_BIT,
+ MTK_36BIT_DMA_BIT,
/* MUX BITS*/
MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
@@ -975,6 +992,7 @@ enum mkt_eth_capabilities {
#define MTK_RSTCTRL_PPE2 BIT_ULL(MTK_RSTCTRL_PPE2_BIT)
#define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT)
#define MTK_SRAM BIT_ULL(MTK_SRAM_BIT)
+#define MTK_36BIT_DMA BIT_ULL(MTK_36BIT_DMA_BIT)
#define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \
BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
@@ -1056,8 +1074,8 @@ enum mkt_eth_capabilities {
MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
MTK_RSTCTRL_PPE1 | MTK_SRAM)
-#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1 | \
- MTK_RSTCTRL_PPE2 | MTK_SRAM)
+#define MT7988_CAPS (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_QDMA | \
+ MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM)
struct mtk_tx_dma_desc_info {
dma_addr_t addr;

View File

@ -0,0 +1,81 @@
From bfac8c490d605bea03b1f1927582b6f396462164 Mon Sep 17 00:00:00 2001
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
Date: Mon, 27 Jun 2022 12:44:43 +0100
Subject: [PATCH] net: phylink: disable PCS polling over major configuration
While we are performing a major configuration, there is no point having
the PCS polling timer running. Stop it before we begin preparing for
the configuration change, and restart it only once we've successfully
completed the change.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/phy/phylink.c | 30 ++++++++++++++++++++----------
1 file changed, 20 insertions(+), 10 deletions(-)
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -756,6 +756,18 @@ static void phylink_resolve_flow(struct
}
}
+static void phylink_pcs_poll_stop(struct phylink *pl)
+{
+ if (pl->cfg_link_an_mode == MLO_AN_INBAND)
+ del_timer(&pl->link_poll);
+}
+
+static void phylink_pcs_poll_start(struct phylink *pl)
+{
+ if (pl->pcs->poll && pl->cfg_link_an_mode == MLO_AN_INBAND)
+ mod_timer(&pl->link_poll, jiffies + HZ);
+}
+
static void phylink_mac_config(struct phylink *pl,
const struct phylink_link_state *state)
{
@@ -787,6 +799,7 @@ static void phylink_major_config(struct
const struct phylink_link_state *state)
{
struct phylink_pcs *pcs = NULL;
+ bool pcs_changed = false;
int err;
phylink_dbg(pl, "major config %s\n", phy_modes(state->interface));
@@ -799,8 +812,12 @@ static void phylink_major_config(struct
pcs);
return;
}
+
+ pcs_changed = pcs && pl->pcs != pcs;
}
+ phylink_pcs_poll_stop(pl);
+
if (pl->mac_ops->mac_prepare) {
err = pl->mac_ops->mac_prepare(pl->config, pl->cur_link_an_mode,
state->interface);
@@ -814,8 +831,10 @@ static void phylink_major_config(struct
/* If we have a new PCS, switch to the new PCS after preparing the MAC
* for the change.
*/
- if (pcs)
- phylink_set_pcs(pl, pcs);
+ if (pcs_changed) {
+ pl->pcs = pcs;
+ pl->pcs_ops = pcs->ops;
+ }
phylink_mac_config(pl, state);
@@ -841,6 +860,8 @@ static void phylink_major_config(struct
phylink_err(pl, "mac_finish failed: %pe\n",
ERR_PTR(err));
}
+
+ phylink_pcs_poll_start(pl);
}
/*

View File

@ -0,0 +1,38 @@
From b7d78b46d5e8dc77c656c13885d31e931923b915 Mon Sep 17 00:00:00 2001
From: Vladimir Oltean <vladimir.oltean@nxp.com>
Date: Wed, 29 Jun 2022 22:33:58 +0300
Subject: [PATCH] net: phylink: fix NULL pl->pcs dereference during
phylink_pcs_poll_start
The current link mode of the phylink instance may not require an
attached PCS. However, phylink_major_config() unconditionally
dereferences this potentially NULL pointer when restarting the link poll
timer, which will panic the kernel.
Fix the problem by checking whether a PCS exists in phylink_pcs_poll_start(),
otherwise do nothing. The code prior to the blamed patch also only
looked at pcs->poll within an "if (pcs)" block.
Fixes: bfac8c490d60 ("net: phylink: disable PCS polling over major configuration")
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Tested-by: Gerhard Engleder <gerhard@engleder-embedded.com>
Tested-by: Michael Walle <michael@walle.cc> # on kontron-kbox-a-230-ls
Tested-by: Nicolas Ferre <nicolas.ferre@microchip.com> # on sam9x60ek
Link: https://lore.kernel.org/r/20220629193358.4007923-1-vladimir.oltean@nxp.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/phy/phylink.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -764,7 +764,7 @@ static void phylink_pcs_poll_stop(struct
static void phylink_pcs_poll_start(struct phylink *pl)
{
- if (pl->pcs->poll && pl->cfg_link_an_mode == MLO_AN_INBAND)
+ if (pl->pcs && pl->pcs->poll && pl->cfg_link_an_mode == MLO_AN_INBAND)
mod_timer(&pl->link_poll, jiffies + HZ);
}

View File

@ -0,0 +1,172 @@
From 90ef0a7b0622c62758b2638604927867775479ea Mon Sep 17 00:00:00 2001
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
Date: Thu, 13 Jul 2023 09:42:07 +0100
Subject: [PATCH] net: phylink: add pcs_enable()/pcs_disable() methods
Add phylink PCS enable/disable callbacks that will allow us to place
IEEE 802.3 register compliant PCS in power-down mode while not being
used.
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/phy/phylink.c | 48 +++++++++++++++++++++++++++++++--------
include/linux/phylink.h | 16 +++++++++++++
2 files changed, 55 insertions(+), 9 deletions(-)
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -34,6 +34,10 @@ enum {
PHYLINK_DISABLE_STOPPED,
PHYLINK_DISABLE_LINK,
PHYLINK_DISABLE_MAC_WOL,
+
+ PCS_STATE_DOWN = 0,
+ PCS_STATE_STARTING,
+ PCS_STATE_STARTED,
};
/**
@@ -72,6 +76,7 @@ struct phylink {
struct mutex state_mutex;
struct phylink_link_state phy_state;
struct work_struct resolve;
+ unsigned int pcs_state;
bool mac_link_dropped;
bool using_mac_select_pcs;
@@ -795,6 +800,22 @@ static void phylink_mac_pcs_an_restart(s
}
}
+static void phylink_pcs_disable(struct phylink_pcs *pcs)
+{
+ if (pcs && pcs->ops->pcs_disable)
+ pcs->ops->pcs_disable(pcs);
+}
+
+static int phylink_pcs_enable(struct phylink_pcs *pcs)
+{
+ int err = 0;
+
+ if (pcs && pcs->ops->pcs_enable)
+ err = pcs->ops->pcs_enable(pcs);
+
+ return err;
+}
+
static void phylink_major_config(struct phylink *pl, bool restart,
const struct phylink_link_state *state)
{
@@ -832,12 +853,16 @@ static void phylink_major_config(struct
* for the change.
*/
if (pcs_changed) {
+ phylink_pcs_disable(pl->pcs);
pl->pcs = pcs;
pl->pcs_ops = pcs->ops;
}
phylink_mac_config(pl, state);
+ if (pl->pcs_state == PCS_STATE_STARTING || pcs_changed)
+ phylink_pcs_enable(pl->pcs);
+
if (pl->pcs_ops) {
err = pl->pcs_ops->pcs_config(pl->pcs, pl->cur_link_an_mode,
state->interface,
@@ -1260,6 +1285,7 @@ struct phylink *phylink_create(struct ph
pl->link_config.speed = SPEED_UNKNOWN;
pl->link_config.duplex = DUPLEX_UNKNOWN;
pl->link_config.an_enabled = true;
+ pl->pcs_state = PCS_STATE_DOWN;
pl->mac_ops = mac_ops;
__set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state);
timer_setup(&pl->link_poll, phylink_fixed_poll, 0);
@@ -1651,6 +1677,8 @@ void phylink_start(struct phylink *pl)
if (pl->netdev)
netif_carrier_off(pl->netdev);
+ pl->pcs_state = PCS_STATE_STARTING;
+
/* Apply the link configuration to the MAC when starting. This allows
* a fixed-link to start with the correct parameters, and also
* ensures that we set the appropriate advertisement for Serdes links.
@@ -1661,6 +1689,8 @@ void phylink_start(struct phylink *pl)
*/
phylink_mac_initial_config(pl, true);
+ pl->pcs_state = PCS_STATE_STARTED;
+
clear_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state);
phylink_run_resolve(pl);
@@ -1680,16 +1710,9 @@ void phylink_start(struct phylink *pl)
poll = true;
}
- switch (pl->cfg_link_an_mode) {
- case MLO_AN_FIXED:
+ if (pl->cfg_link_an_mode == MLO_AN_FIXED)
poll |= pl->config->poll_fixed_state;
- break;
- case MLO_AN_INBAND:
- poll |= pl->config->pcs_poll;
- if (pl->pcs)
- poll |= pl->pcs->poll;
- break;
- }
+
if (poll)
mod_timer(&pl->link_poll, jiffies + HZ);
if (pl->phydev)
@@ -1726,6 +1749,10 @@ void phylink_stop(struct phylink *pl)
}
phylink_run_resolve_and_disable(pl, PHYLINK_DISABLE_STOPPED);
+
+ pl->pcs_state = PCS_STATE_DOWN;
+
+ phylink_pcs_disable(pl->pcs);
}
EXPORT_SYMBOL_GPL(phylink_stop);
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -419,6 +419,8 @@ struct phylink_pcs {
/**
* struct phylink_pcs_ops - MAC PCS operations structure.
* @pcs_validate: validate the link configuration.
+ * @pcs_enable: enable the PCS.
+ * @pcs_disable: disable the PCS.
* @pcs_get_state: read the current MAC PCS link state from the hardware.
* @pcs_config: configure the MAC PCS for the selected mode and state.
* @pcs_an_restart: restart 802.3z BaseX autonegotiation.
@@ -428,6 +430,8 @@ struct phylink_pcs {
struct phylink_pcs_ops {
int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported,
const struct phylink_link_state *state);
+ int (*pcs_enable)(struct phylink_pcs *pcs);
+ void (*pcs_disable)(struct phylink_pcs *pcs);
void (*pcs_get_state)(struct phylink_pcs *pcs,
struct phylink_link_state *state);
int (*pcs_config)(struct phylink_pcs *pcs, unsigned int mode,
@@ -458,6 +462,18 @@ int pcs_validate(struct phylink_pcs *pcs
const struct phylink_link_state *state);
/**
+ * pcs_enable() - enable the PCS.
+ * @pcs: a pointer to a &struct phylink_pcs.
+ */
+int pcs_enable(struct phylink_pcs *pcs);
+
+/**
+ * pcs_disable() - disable the PCS.
+ * @pcs: a pointer to a &struct phylink_pcs.
+ */
+void pcs_disable(struct phylink_pcs *pcs);
+
+/**
* pcs_get_state() - Read the current inband link state from the hardware
* @pcs: a pointer to a &struct phylink_pcs.
* @state: a pointer to a &struct phylink_link_state.

View File

@ -0,0 +1,44 @@
From e4ccdfb78a47132f2d215658aab8902fc457c4b4 Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Fri, 18 Aug 2023 04:07:46 +0100
Subject: [PATCH 082/125] net: pcs: lynxi: implement pcs_disable op
When switching from 10GBase-R/5GBase-R/USXGMII to one of the interface
modes provided by mtk-pcs-lynxi we need to make sure to always perform
a full configuration of the PHYA.
Implement pcs_disable op which resets the stored interface mode to
PHY_INTERFACE_MODE_NA to trigger a full reconfiguration once the LynxI
PCS driver had previously been deselected in favor of another PCS
driver such as the to-be-added driver for the USXGMII PCS found in
MT7988.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Link: https://lore.kernel.org/r/f23d1a60d2c9d2fb72e32dcb0eaa5f7e867a3d68.1692327891.git.daniel@makrotopia.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/pcs/pcs-mtk-lynxi.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/drivers/net/pcs/pcs-mtk-lynxi.c
+++ b/drivers/net/pcs/pcs-mtk-lynxi.c
@@ -241,11 +241,19 @@ static void mtk_pcs_lynxi_link_up(struct
}
}
+static void mtk_pcs_lynxi_disable(struct phylink_pcs *pcs)
+{
+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
+
+ mpcs->interface = PHY_INTERFACE_MODE_NA;
+}
+
static const struct phylink_pcs_ops mtk_pcs_lynxi_ops = {
.pcs_get_state = mtk_pcs_lynxi_get_state,
.pcs_config = mtk_pcs_lynxi_config,
.pcs_an_restart = mtk_pcs_lynxi_restart_an,
.pcs_link_up = mtk_pcs_lynxi_link_up,
+ .pcs_disable = mtk_pcs_lynxi_disable,
};
struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev,

View File

@ -0,0 +1,39 @@
From 156a5bb89ca6f3edd2be0bfd0de15e575442927e Mon Sep 17 00:00:00 2001
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Date: Tue, 3 Jan 2023 15:12:47 +0200
Subject: [PATCH] leds: Move led_init_default_state_get() to the global header
There are users inside and outside LED framework that have implemented
a local copy of led_init_default_state_get(). In order to deduplicate
that, as the first step move the declaration from LED header to the
global one.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Lee Jones <lee@kernel.org>
Link: https://lore.kernel.org/r/20230103131256.33894-3-andriy.shevchenko@linux.intel.com
---
drivers/leds/leds.h | 1 -
include/linux/leds.h | 2 ++
2 files changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/leds/leds.h
+++ b/drivers/leds/leds.h
@@ -27,7 +27,6 @@ ssize_t led_trigger_read(struct file *fi
ssize_t led_trigger_write(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr, char *buf,
loff_t pos, size_t count);
-enum led_default_state led_init_default_state_get(struct fwnode_handle *fwnode);
extern struct rw_semaphore leds_list_lock;
extern struct list_head leds_list;
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -63,6 +63,8 @@ struct led_init_data {
bool devname_mandatory;
};
+enum led_default_state led_init_default_state_get(struct fwnode_handle *fwnode);
+
struct led_hw_trigger_type {
int dummy;
};

View File

@ -0,0 +1,67 @@
From 3e8b4d6277fd19d98c817576954dd6a4ff3caa2b Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Mon, 17 Apr 2023 17:17:23 +0200
Subject: [PATCH 1/9] net: dsa: qca8k: move qca8k_port_to_phy() to header
Move qca8k_port_to_phy() to qca8k header as it's useful for future
reference in Switch LEDs module since the same logic is applied to get
the right index of the switch port.
Make it inline as it's simple function that just decrease the port.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Michal Kubiak <michal.kubiak@intel.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/dsa/qca/qca8k-8xxx.c | 15 ---------------
drivers/net/dsa/qca/qca8k.h | 14 ++++++++++++++
2 files changed, 14 insertions(+), 15 deletions(-)
--- a/drivers/net/dsa/qca/qca8k-8xxx.c
+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
@@ -716,21 +716,6 @@ err_clear_skb:
return ret;
}
-static u32
-qca8k_port_to_phy(int port)
-{
- /* From Andrew Lunn:
- * Port 0 has no internal phy.
- * Port 1 has an internal PHY at MDIO address 0.
- * Port 2 has an internal PHY at MDIO address 1.
- * ...
- * Port 5 has an internal PHY at MDIO address 4.
- * Port 6 has no internal PHY.
- */
-
- return port - 1;
-}
-
static int
qca8k_mdio_busy_wait(struct mii_bus *bus, u32 reg, u32 mask)
{
--- a/drivers/net/dsa/qca/qca8k.h
+++ b/drivers/net/dsa/qca/qca8k.h
@@ -414,6 +414,20 @@ struct qca8k_fdb {
u8 mac[6];
};
+static inline u32 qca8k_port_to_phy(int port)
+{
+ /* From Andrew Lunn:
+ * Port 0 has no internal phy.
+ * Port 1 has an internal PHY at MDIO address 0.
+ * Port 2 has an internal PHY at MDIO address 1.
+ * ...
+ * Port 5 has an internal PHY at MDIO address 4.
+ * Port 6 has no internal PHY.
+ */
+
+ return port - 1;
+}
+
/* Common setup function */
extern const struct qca8k_mib_desc ar8327_mib[];
extern const struct regmap_access_table qca8k_readable_table;

View File

@ -0,0 +1,435 @@
From 1e264f9d2918b5737023c44a23ae04def1095210 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Mon, 17 Apr 2023 17:17:24 +0200
Subject: [PATCH 2/9] net: dsa: qca8k: add LEDs basic support
Add LEDs basic support for qca8k Switch Family by adding basic
brightness_set() support.
Since these LEDs refelect port status, the default label is set to
":port". DT binding should describe the color and function of the
LEDs using standard LEDs api.
Each LED always have the device name as prefix. The device name is
composed from the mii bus id and the PHY addr resulting in example
names like:
- qca8k-0.0:00:amber:lan
- qca8k-0.0:00:white:lan
- qca8k-0.0:01:amber:lan
- qca8k-0.0:01:white:lan
These LEDs supports only blocking variant of the brightness_set()
function since they can sleep during access of the switch leds to set
the brightness.
While at it add to the qca8k header file each mode defined by the Switch
Documentation for future use.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/dsa/qca/Kconfig | 8 ++
drivers/net/dsa/qca/Makefile | 3 +
drivers/net/dsa/qca/qca8k-8xxx.c | 5 +
drivers/net/dsa/qca/qca8k-leds.c | 239 +++++++++++++++++++++++++++++++
drivers/net/dsa/qca/qca8k.h | 60 ++++++++
drivers/net/dsa/qca/qca8k_leds.h | 16 +++
6 files changed, 331 insertions(+)
create mode 100644 drivers/net/dsa/qca/qca8k-leds.c
create mode 100644 drivers/net/dsa/qca/qca8k_leds.h
--- a/drivers/net/dsa/qca/Kconfig
+++ b/drivers/net/dsa/qca/Kconfig
@@ -15,3 +15,11 @@ config NET_DSA_QCA8K
help
This enables support for the Qualcomm Atheros QCA8K Ethernet
switch chips.
+
+config NET_DSA_QCA8K_LEDS_SUPPORT
+ bool "Qualcomm Atheros QCA8K Ethernet switch family LEDs support"
+ depends on NET_DSA_QCA8K
+ depends on LEDS_CLASS
+ help
+ This enabled support for LEDs present on the Qualcomm Atheros
+ QCA8K Ethernet switch chips.
--- a/drivers/net/dsa/qca/Makefile
+++ b/drivers/net/dsa/qca/Makefile
@@ -2,3 +2,6 @@
obj-$(CONFIG_NET_DSA_AR9331) += ar9331.o
obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o
qca8k-y += qca8k-common.o qca8k-8xxx.o
+ifdef CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT
+qca8k-y += qca8k-leds.o
+endif
--- a/drivers/net/dsa/qca/qca8k-8xxx.c
+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
@@ -22,6 +22,7 @@
#include <linux/dsa/tag_qca.h>
#include "qca8k.h"
+#include "qca8k_leds.h"
static void
qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page)
@@ -1185,6 +1186,10 @@ qca8k_setup(struct dsa_switch *ds)
if (ret)
return ret;
+ ret = qca8k_setup_led_ctrl(priv);
+ if (ret)
+ return ret;
+
/* Make sure MAC06 is disabled */
ret = regmap_clear_bits(priv->regmap, QCA8K_REG_PORT0_PAD_CTRL,
QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN);
--- /dev/null
+++ b/drivers/net/dsa/qca/qca8k-leds.c
@@ -0,0 +1,239 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/regmap.h>
+#include <net/dsa.h>
+
+#include "qca8k.h"
+#include "qca8k_leds.h"
+
+static int
+qca8k_get_enable_led_reg(int port_num, int led_num, struct qca8k_led_pattern_en *reg_info)
+{
+ switch (port_num) {
+ case 0:
+ reg_info->reg = QCA8K_LED_CTRL_REG(led_num);
+ reg_info->shift = QCA8K_LED_PHY0123_CONTROL_RULE_SHIFT;
+ break;
+ case 1:
+ case 2:
+ case 3:
+ /* Port 123 are controlled on a different reg */
+ reg_info->reg = QCA8K_LED_CTRL3_REG;
+ reg_info->shift = QCA8K_LED_PHY123_PATTERN_EN_SHIFT(port_num, led_num);
+ break;
+ case 4:
+ reg_info->reg = QCA8K_LED_CTRL_REG(led_num);
+ reg_info->shift = QCA8K_LED_PHY4_CONTROL_RULE_SHIFT;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int
+qca8k_led_brightness_set(struct qca8k_led *led,
+ enum led_brightness brightness)
+{
+ struct qca8k_led_pattern_en reg_info;
+ struct qca8k_priv *priv = led->priv;
+ u32 mask, val;
+
+ qca8k_get_enable_led_reg(led->port_num, led->led_num, &reg_info);
+
+ val = QCA8K_LED_ALWAYS_OFF;
+ if (brightness)
+ val = QCA8K_LED_ALWAYS_ON;
+
+ /* HW regs to control brightness is special and port 1-2-3
+ * are placed in a different reg.
+ *
+ * To control port 0 brightness:
+ * - the 2 bit (15, 14) of:
+ * - QCA8K_LED_CTRL0_REG for led1
+ * - QCA8K_LED_CTRL1_REG for led2
+ * - QCA8K_LED_CTRL2_REG for led3
+ *
+ * To control port 4:
+ * - the 2 bit (31, 30) of:
+ * - QCA8K_LED_CTRL0_REG for led1
+ * - QCA8K_LED_CTRL1_REG for led2
+ * - QCA8K_LED_CTRL2_REG for led3
+ *
+ * To control port 1:
+ * - the 2 bit at (9, 8) of QCA8K_LED_CTRL3_REG are used for led1
+ * - the 2 bit at (11, 10) of QCA8K_LED_CTRL3_REG are used for led2
+ * - the 2 bit at (13, 12) of QCA8K_LED_CTRL3_REG are used for led3
+ *
+ * To control port 2:
+ * - the 2 bit at (15, 14) of QCA8K_LED_CTRL3_REG are used for led1
+ * - the 2 bit at (17, 16) of QCA8K_LED_CTRL3_REG are used for led2
+ * - the 2 bit at (19, 18) of QCA8K_LED_CTRL3_REG are used for led3
+ *
+ * To control port 3:
+ * - the 2 bit at (21, 20) of QCA8K_LED_CTRL3_REG are used for led1
+ * - the 2 bit at (23, 22) of QCA8K_LED_CTRL3_REG are used for led2
+ * - the 2 bit at (25, 24) of QCA8K_LED_CTRL3_REG are used for led3
+ *
+ * To abstract this and have less code, we use the port and led numm
+ * to calculate the shift and the correct reg due to this problem of
+ * not having a 1:1 map of LED with the regs.
+ */
+ if (led->port_num == 0 || led->port_num == 4) {
+ mask = QCA8K_LED_PATTERN_EN_MASK;
+ val <<= QCA8K_LED_PATTERN_EN_SHIFT;
+ } else {
+ mask = QCA8K_LED_PHY123_PATTERN_EN_MASK;
+ }
+
+ return regmap_update_bits(priv->regmap, reg_info.reg,
+ mask << reg_info.shift,
+ val << reg_info.shift);
+}
+
+static int
+qca8k_cled_brightness_set_blocking(struct led_classdev *ldev,
+ enum led_brightness brightness)
+{
+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
+
+ return qca8k_led_brightness_set(led, brightness);
+}
+
+static enum led_brightness
+qca8k_led_brightness_get(struct qca8k_led *led)
+{
+ struct qca8k_led_pattern_en reg_info;
+ struct qca8k_priv *priv = led->priv;
+ u32 val;
+ int ret;
+
+ qca8k_get_enable_led_reg(led->port_num, led->led_num, &reg_info);
+
+ ret = regmap_read(priv->regmap, reg_info.reg, &val);
+ if (ret)
+ return 0;
+
+ val >>= reg_info.shift;
+
+ if (led->port_num == 0 || led->port_num == 4) {
+ val &= QCA8K_LED_PATTERN_EN_MASK;
+ val >>= QCA8K_LED_PATTERN_EN_SHIFT;
+ } else {
+ val &= QCA8K_LED_PHY123_PATTERN_EN_MASK;
+ }
+
+ /* Assume brightness ON only when the LED is set to always ON */
+ return val == QCA8K_LED_ALWAYS_ON;
+}
+
+static int
+qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num)
+{
+ struct fwnode_handle *led = NULL, *leds = NULL;
+ struct led_init_data init_data = { };
+ struct dsa_switch *ds = priv->ds;
+ enum led_default_state state;
+ struct qca8k_led *port_led;
+ int led_num, led_index;
+ int ret;
+
+ leds = fwnode_get_named_child_node(port, "leds");
+ if (!leds) {
+ dev_dbg(priv->dev, "No Leds node specified in device tree for port %d!\n",
+ port_num);
+ return 0;
+ }
+
+ fwnode_for_each_child_node(leds, led) {
+ /* Reg represent the led number of the port.
+ * Each port can have at most 3 leds attached
+ * Commonly:
+ * 1. is gigabit led
+ * 2. is mbit led
+ * 3. additional status led
+ */
+ if (fwnode_property_read_u32(led, "reg", &led_num))
+ continue;
+
+ if (led_num >= QCA8K_LED_PORT_COUNT) {
+ dev_warn(priv->dev, "Invalid LED reg %d defined for port %d",
+ led_num, port_num);
+ continue;
+ }
+
+ led_index = QCA8K_LED_PORT_INDEX(port_num, led_num);
+
+ port_led = &priv->ports_led[led_index];
+ port_led->port_num = port_num;
+ port_led->led_num = led_num;
+ port_led->priv = priv;
+
+ state = led_init_default_state_get(led);
+ switch (state) {
+ case LEDS_DEFSTATE_ON:
+ port_led->cdev.brightness = 1;
+ qca8k_led_brightness_set(port_led, 1);
+ break;
+ case LEDS_DEFSTATE_KEEP:
+ port_led->cdev.brightness =
+ qca8k_led_brightness_get(port_led);
+ break;
+ default:
+ port_led->cdev.brightness = 0;
+ qca8k_led_brightness_set(port_led, 0);
+ }
+
+ port_led->cdev.max_brightness = 1;
+ port_led->cdev.brightness_set_blocking = qca8k_cled_brightness_set_blocking;
+ init_data.default_label = ":port";
+ init_data.fwnode = led;
+ init_data.devname_mandatory = true;
+ init_data.devicename = kasprintf(GFP_KERNEL, "%s:0%d", ds->slave_mii_bus->id,
+ port_num);
+ if (!init_data.devicename)
+ return -ENOMEM;
+
+ ret = devm_led_classdev_register_ext(priv->dev, &port_led->cdev, &init_data);
+ if (ret)
+ dev_warn(priv->dev, "Failed to init LED %d for port %d", led_num, port_num);
+
+ kfree(init_data.devicename);
+ }
+
+ return 0;
+}
+
+int
+qca8k_setup_led_ctrl(struct qca8k_priv *priv)
+{
+ struct fwnode_handle *ports, *port;
+ int port_num;
+ int ret;
+
+ ports = device_get_named_child_node(priv->dev, "ports");
+ if (!ports) {
+ dev_info(priv->dev, "No ports node specified in device tree!");
+ return 0;
+ }
+
+ fwnode_for_each_child_node(ports, port) {
+ if (fwnode_property_read_u32(port, "reg", &port_num))
+ continue;
+
+ /* Skip checking for CPU port 0 and CPU port 6 as not supported */
+ if (port_num == 0 || port_num == 6)
+ continue;
+
+ /* Each port can have at most 3 different leds attached.
+ * Switch port starts from 0 to 6, but port 0 and 6 are CPU
+ * port. The port index needs to be decreased by one to identify
+ * the correct port for LED setup.
+ */
+ ret = qca8k_parse_port_leds(priv, port, qca8k_port_to_phy(port_num));
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
--- a/drivers/net/dsa/qca/qca8k.h
+++ b/drivers/net/dsa/qca/qca8k.h
@@ -11,6 +11,7 @@
#include <linux/delay.h>
#include <linux/regmap.h>
#include <linux/gpio.h>
+#include <linux/leds.h>
#include <linux/dsa/tag_qca.h>
#define QCA8K_ETHERNET_MDIO_PRIORITY 7
@@ -85,6 +86,51 @@
#define QCA8K_MDIO_MASTER_DATA(x) FIELD_PREP(QCA8K_MDIO_MASTER_DATA_MASK, x)
#define QCA8K_MDIO_MASTER_MAX_PORTS 5
#define QCA8K_MDIO_MASTER_MAX_REG 32
+
+/* LED control register */
+#define QCA8K_LED_PORT_COUNT 3
+#define QCA8K_LED_COUNT ((QCA8K_NUM_PORTS - QCA8K_NUM_CPU_PORTS) * QCA8K_LED_PORT_COUNT)
+#define QCA8K_LED_RULE_COUNT 6
+#define QCA8K_LED_RULE_MAX 11
+#define QCA8K_LED_PORT_INDEX(_phy, _led) (((_phy) * QCA8K_LED_PORT_COUNT) + (_led))
+
+#define QCA8K_LED_PHY123_PATTERN_EN_SHIFT(_phy, _led) ((((_phy) - 1) * 6) + 8 + (2 * (_led)))
+#define QCA8K_LED_PHY123_PATTERN_EN_MASK GENMASK(1, 0)
+
+#define QCA8K_LED_PHY0123_CONTROL_RULE_SHIFT 0
+#define QCA8K_LED_PHY4_CONTROL_RULE_SHIFT 16
+
+#define QCA8K_LED_CTRL_REG(_i) (0x050 + (_i) * 4)
+#define QCA8K_LED_CTRL0_REG 0x50
+#define QCA8K_LED_CTRL1_REG 0x54
+#define QCA8K_LED_CTRL2_REG 0x58
+#define QCA8K_LED_CTRL3_REG 0x5C
+#define QCA8K_LED_CTRL_SHIFT(_i) (((_i) % 2) * 16)
+#define QCA8K_LED_CTRL_MASK GENMASK(15, 0)
+#define QCA8K_LED_RULE_MASK GENMASK(13, 0)
+#define QCA8K_LED_BLINK_FREQ_MASK GENMASK(1, 0)
+#define QCA8K_LED_BLINK_FREQ_SHITF 0
+#define QCA8K_LED_BLINK_2HZ 0
+#define QCA8K_LED_BLINK_4HZ 1
+#define QCA8K_LED_BLINK_8HZ 2
+#define QCA8K_LED_BLINK_AUTO 3
+#define QCA8K_LED_LINKUP_OVER_MASK BIT(2)
+#define QCA8K_LED_TX_BLINK_MASK BIT(4)
+#define QCA8K_LED_RX_BLINK_MASK BIT(5)
+#define QCA8K_LED_COL_BLINK_MASK BIT(7)
+#define QCA8K_LED_LINK_10M_EN_MASK BIT(8)
+#define QCA8K_LED_LINK_100M_EN_MASK BIT(9)
+#define QCA8K_LED_LINK_1000M_EN_MASK BIT(10)
+#define QCA8K_LED_POWER_ON_LIGHT_MASK BIT(11)
+#define QCA8K_LED_HALF_DUPLEX_MASK BIT(12)
+#define QCA8K_LED_FULL_DUPLEX_MASK BIT(13)
+#define QCA8K_LED_PATTERN_EN_MASK GENMASK(15, 14)
+#define QCA8K_LED_PATTERN_EN_SHIFT 14
+#define QCA8K_LED_ALWAYS_OFF 0
+#define QCA8K_LED_ALWAYS_BLINK_4HZ 1
+#define QCA8K_LED_ALWAYS_ON 2
+#define QCA8K_LED_RULE_CONTROLLED 3
+
#define QCA8K_GOL_MAC_ADDR0 0x60
#define QCA8K_GOL_MAC_ADDR1 0x64
#define QCA8K_MAX_FRAME_SIZE 0x78
@@ -377,6 +423,19 @@ struct qca8k_mdio_cache {
u16 page;
};
+struct qca8k_led_pattern_en {
+ u32 reg;
+ u8 shift;
+};
+
+struct qca8k_led {
+ u8 port_num;
+ u8 led_num;
+ u16 old_rule;
+ struct qca8k_priv *priv;
+ struct led_classdev cdev;
+};
+
struct qca8k_priv {
u8 switch_id;
u8 switch_revision;
@@ -399,6 +458,7 @@ struct qca8k_priv {
struct qca8k_mib_eth_data mib_eth_data;
struct qca8k_mdio_cache mdio_cache;
const struct qca8k_match_data *info;
+ struct qca8k_led ports_led[QCA8K_LED_COUNT];
};
struct qca8k_mib_desc {
--- /dev/null
+++ b/drivers/net/dsa/qca/qca8k_leds.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __QCA8K_LEDS_H
+#define __QCA8K_LEDS_H
+
+/* Leds Support function */
+#ifdef CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT
+int qca8k_setup_led_ctrl(struct qca8k_priv *priv);
+#else
+static inline int qca8k_setup_led_ctrl(struct qca8k_priv *priv)
+{
+ return 0;
+}
+#endif
+
+#endif /* __QCA8K_LEDS_H */

View File

@ -0,0 +1,74 @@
From 91acadcc6e599dfc62717abcdad58a459cfb1684 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Mon, 17 Apr 2023 17:17:25 +0200
Subject: [PATCH 3/9] net: dsa: qca8k: add LEDs blink_set() support
Add LEDs blink_set() support to qca8k Switch Family.
These LEDs support hw accellerated blinking at a fixed rate
of 4Hz.
Reject any other value since not supported by the LEDs switch.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Acked-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/dsa/qca/qca8k-leds.c | 38 ++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
--- a/drivers/net/dsa/qca/qca8k-leds.c
+++ b/drivers/net/dsa/qca/qca8k-leds.c
@@ -128,6 +128,43 @@ qca8k_led_brightness_get(struct qca8k_le
}
static int
+qca8k_cled_blink_set(struct led_classdev *ldev,
+ unsigned long *delay_on,
+ unsigned long *delay_off)
+{
+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
+ u32 mask, val = QCA8K_LED_ALWAYS_BLINK_4HZ;
+ struct qca8k_led_pattern_en reg_info;
+ struct qca8k_priv *priv = led->priv;
+
+ if (*delay_on == 0 && *delay_off == 0) {
+ *delay_on = 125;
+ *delay_off = 125;
+ }
+
+ if (*delay_on != 125 || *delay_off != 125) {
+ /* The hardware only supports blinking at 4Hz. Fall back
+ * to software implementation in other cases.
+ */
+ return -EINVAL;
+ }
+
+ qca8k_get_enable_led_reg(led->port_num, led->led_num, &reg_info);
+
+ if (led->port_num == 0 || led->port_num == 4) {
+ mask = QCA8K_LED_PATTERN_EN_MASK;
+ val <<= QCA8K_LED_PATTERN_EN_SHIFT;
+ } else {
+ mask = QCA8K_LED_PHY123_PATTERN_EN_MASK;
+ }
+
+ regmap_update_bits(priv->regmap, reg_info.reg, mask << reg_info.shift,
+ val << reg_info.shift);
+
+ return 0;
+}
+
+static int
qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num)
{
struct fwnode_handle *led = NULL, *leds = NULL;
@@ -186,6 +223,7 @@ qca8k_parse_port_leds(struct qca8k_priv
port_led->cdev.max_brightness = 1;
port_led->cdev.brightness_set_blocking = qca8k_cled_brightness_set_blocking;
+ port_led->cdev.blink_set = qca8k_cled_blink_set;
init_data.default_label = ":port";
init_data.fwnode = led;
init_data.devname_mandatory = true;

View File

@ -0,0 +1,59 @@
From e5029edd53937a29801ef507cee12e657ff31ea9 Mon Sep 17 00:00:00 2001
From: Andrew Lunn <andrew@lunn.ch>
Date: Mon, 17 Apr 2023 17:17:26 +0200
Subject: [PATCH 4/9] leds: Provide stubs for when CLASS_LED & NEW_LEDS are
disabled
Provide stubs for devm_led_classdev_register_ext() and
led_init_default_state_get() so that LED drivers embedded within other
drivers such as PHYs and Ethernet switches still build when LEDS_CLASS
or NEW_LEDS are disabled. This also helps with Kconfig dependencies,
which are somewhat hairy for phylib and mdio and only get worse when
adding a dependency on LED_CLASS.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
include/linux/leds.h | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -63,7 +63,15 @@ struct led_init_data {
bool devname_mandatory;
};
+#if IS_ENABLED(CONFIG_NEW_LEDS)
enum led_default_state led_init_default_state_get(struct fwnode_handle *fwnode);
+#else
+static inline enum led_default_state
+led_init_default_state_get(struct fwnode_handle *fwnode)
+{
+ return LEDS_DEFSTATE_OFF;
+}
+#endif
struct led_hw_trigger_type {
int dummy;
@@ -198,9 +206,19 @@ static inline int led_classdev_register(
return led_classdev_register_ext(parent, led_cdev, NULL);
}
+#if IS_ENABLED(CONFIG_LEDS_CLASS)
int devm_led_classdev_register_ext(struct device *parent,
struct led_classdev *led_cdev,
struct led_init_data *init_data);
+#else
+static inline int
+devm_led_classdev_register_ext(struct device *parent,
+ struct led_classdev *led_cdev,
+ struct led_init_data *init_data)
+{
+ return 0;
+}
+#endif
static inline int devm_led_classdev_register(struct device *parent,
struct led_classdev *led_cdev)

View File

@ -0,0 +1,191 @@
From 01e5b728e9e43ae444e0369695a5f72209906464 Mon Sep 17 00:00:00 2001
From: Andrew Lunn <andrew@lunn.ch>
Date: Mon, 17 Apr 2023 17:17:27 +0200
Subject: [PATCH 5/9] net: phy: Add a binding for PHY LEDs
Define common binding parsing for all PHY drivers with LEDs using
phylib. Parse the DT as part of the phy_probe and add LEDs to the
linux LED class infrastructure. For the moment, provide a dummy
brightness function, which will later be replaced with a call into the
PHY driver. This allows testing since the LED core might otherwise
reject an LED whose brightness cannot be set.
Add a dependency on LED_CLASS. It either needs to be built in, or not
enabled, since a modular build can result in linker errors.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/phy/Kconfig | 1 +
drivers/net/phy/phy_device.c | 76 ++++++++++++++++++++++++++++++++++++
include/linux/phy.h | 16 ++++++++
3 files changed, 93 insertions(+)
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -18,6 +18,7 @@ menuconfig PHYLIB
depends on NETDEVICES
select MDIO_DEVICE
select MDIO_DEVRES
+ depends on LEDS_CLASS || LEDS_CLASS=n
help
Ethernet controllers are usually attached to PHY
devices. This option provides infrastructure for
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -19,10 +19,12 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
+#include <linux/list.h>
#include <linux/mdio.h>
#include <linux/mii.h>
#include <linux/mm.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/netdevice.h>
#include <linux/phy.h>
#include <linux/phy_led_triggers.h>
@@ -641,6 +643,7 @@ struct phy_device *phy_device_create(str
device_initialize(&mdiodev->dev);
dev->state = PHY_DOWN;
+ INIT_LIST_HEAD(&dev->leds);
mutex_init(&dev->lock);
INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine);
@@ -2942,6 +2945,74 @@ static bool phy_drv_supports_irq(struct
return phydrv->config_intr && phydrv->handle_interrupt;
}
+/* Dummy implementation until calls into PHY driver are added */
+static int phy_led_set_brightness(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ return 0;
+}
+
+static int of_phy_led(struct phy_device *phydev,
+ struct device_node *led)
+{
+ struct device *dev = &phydev->mdio.dev;
+ struct led_init_data init_data = {};
+ struct led_classdev *cdev;
+ struct phy_led *phyled;
+ int err;
+
+ phyled = devm_kzalloc(dev, sizeof(*phyled), GFP_KERNEL);
+ if (!phyled)
+ return -ENOMEM;
+
+ cdev = &phyled->led_cdev;
+
+ err = of_property_read_u8(led, "reg", &phyled->index);
+ if (err)
+ return err;
+
+ cdev->brightness_set_blocking = phy_led_set_brightness;
+ cdev->max_brightness = 1;
+ init_data.devicename = dev_name(&phydev->mdio.dev);
+ init_data.fwnode = of_fwnode_handle(led);
+ init_data.devname_mandatory = true;
+
+ err = devm_led_classdev_register_ext(dev, cdev, &init_data);
+ if (err)
+ return err;
+
+ list_add(&phyled->list, &phydev->leds);
+
+ return 0;
+}
+
+static int of_phy_leds(struct phy_device *phydev)
+{
+ struct device_node *node = phydev->mdio.dev.of_node;
+ struct device_node *leds, *led;
+ int err;
+
+ if (!IS_ENABLED(CONFIG_OF_MDIO))
+ return 0;
+
+ if (!node)
+ return 0;
+
+ leds = of_get_child_by_name(node, "leds");
+ if (!leds)
+ return 0;
+
+ for_each_available_child_of_node(leds, led) {
+ err = of_phy_led(phydev, led);
+ if (err) {
+ of_node_put(led);
+ return err;
+ }
+ }
+
+ return 0;
+}
+
/**
* fwnode_mdio_find_device - Given a fwnode, find the mdio_device
* @fwnode: pointer to the mdio_device's fwnode
@@ -3120,6 +3191,11 @@ static int phy_probe(struct device *dev)
/* Set the state to READY by default */
phydev->state = PHY_READY;
+ /* Get the LEDs from the device tree, and instantiate standard
+ * LEDs for them.
+ */
+ err = of_phy_leds(phydev);
+
out:
/* Re-assert the reset signal on error */
if (err)
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -14,6 +14,7 @@
#include <linux/compiler.h>
#include <linux/spinlock.h>
#include <linux/ethtool.h>
+#include <linux/leds.h>
#include <linux/linkmode.h>
#include <linux/netlink.h>
#include <linux/mdio.h>
@@ -582,6 +583,7 @@ struct macsec_ops;
* @phy_num_led_triggers: Number of triggers in @phy_led_triggers
* @led_link_trigger: LED trigger for link up/down
* @last_triggered: last LED trigger for link speed
+ * @leds: list of PHY LED structures
* @master_slave_set: User requested master/slave configuration
* @master_slave_get: Current master/slave advertisement
* @master_slave_state: Current master/slave configuration
@@ -668,6 +670,7 @@ struct phy_device {
struct phy_led_trigger *led_link_trigger;
#endif
+ struct list_head leds;
/*
* Interrupt number for this PHY
@@ -739,6 +742,19 @@ struct phy_tdr_config {
#define PHY_PAIR_ALL -1
/**
+ * struct phy_led: An LED driven by the PHY
+ *
+ * @list: List of LEDs
+ * @led_cdev: Standard LED class structure
+ * @index: Number of the LED
+ */
+struct phy_led {
+ struct list_head list;
+ struct led_classdev led_cdev;
+ u8 index;
+};
+
+/**
* struct phy_driver - Driver structure for a particular PHY type
*
* @mdiodrv: Data common to all MDIO devices

View File

@ -0,0 +1,97 @@
From 684818189b04b095b34964ed4a3ea5249a840eab Mon Sep 17 00:00:00 2001
From: Andrew Lunn <andrew@lunn.ch>
Date: Mon, 17 Apr 2023 17:17:28 +0200
Subject: [PATCH 6/9] net: phy: phy_device: Call into the PHY driver to set LED
brightness
Linux LEDs can be software controlled via the brightness file in /sys.
LED drivers need to implement a brightness_set function which the core
will call. Implement an intermediary in phy_device, which will call
into the phy driver if it implements the necessary function.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/phy/phy_device.c | 15 ++++++++++++---
include/linux/phy.h | 13 +++++++++++++
2 files changed, 25 insertions(+), 3 deletions(-)
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -2945,11 +2945,18 @@ static bool phy_drv_supports_irq(struct
return phydrv->config_intr && phydrv->handle_interrupt;
}
-/* Dummy implementation until calls into PHY driver are added */
static int phy_led_set_brightness(struct led_classdev *led_cdev,
enum led_brightness value)
{
- return 0;
+ struct phy_led *phyled = to_phy_led(led_cdev);
+ struct phy_device *phydev = phyled->phydev;
+ int err;
+
+ mutex_lock(&phydev->lock);
+ err = phydev->drv->led_brightness_set(phydev, phyled->index, value);
+ mutex_unlock(&phydev->lock);
+
+ return err;
}
static int of_phy_led(struct phy_device *phydev,
@@ -2966,12 +2973,14 @@ static int of_phy_led(struct phy_device
return -ENOMEM;
cdev = &phyled->led_cdev;
+ phyled->phydev = phydev;
err = of_property_read_u8(led, "reg", &phyled->index);
if (err)
return err;
- cdev->brightness_set_blocking = phy_led_set_brightness;
+ if (phydev->drv->led_brightness_set)
+ cdev->brightness_set_blocking = phy_led_set_brightness;
cdev->max_brightness = 1;
init_data.devicename = dev_name(&phydev->mdio.dev);
init_data.fwnode = of_fwnode_handle(led);
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -745,15 +745,19 @@ struct phy_tdr_config {
* struct phy_led: An LED driven by the PHY
*
* @list: List of LEDs
+ * @phydev: PHY this LED is attached to
* @led_cdev: Standard LED class structure
* @index: Number of the LED
*/
struct phy_led {
struct list_head list;
+ struct phy_device *phydev;
struct led_classdev led_cdev;
u8 index;
};
+#define to_phy_led(d) container_of(d, struct phy_led, led_cdev)
+
/**
* struct phy_driver - Driver structure for a particular PHY type
*
@@ -953,6 +957,15 @@ struct phy_driver {
int (*get_sqi)(struct phy_device *dev);
/** @get_sqi_max: Get the maximum signal quality indication */
int (*get_sqi_max)(struct phy_device *dev);
+
+ /**
+ * @led_brightness_set: Set a PHY LED brightness. Index
+ * indicates which of the PHYs led should be set. Value
+ * follows the standard LED class meaning, e.g. LED_OFF,
+ * LED_HALF, LED_FULL.
+ */
+ int (*led_brightness_set)(struct phy_device *dev,
+ u8 index, enum led_brightness value);
};
#define to_phy_driver(d) container_of(to_mdio_common_driver(d), \
struct phy_driver, mdiodrv)

View File

@ -0,0 +1,112 @@
From 2d3960e58ef7c83fe1dbf952f056b9e906cb6df8 Mon Sep 17 00:00:00 2001
From: Andrew Lunn <andrew@lunn.ch>
Date: Mon, 17 Apr 2023 17:17:29 +0200
Subject: [PATCH 7/9] net: phy: marvell: Add software control of the LEDs
Add a brightness function, so the LEDs can be controlled from
software using the standard Linux LED infrastructure.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/phy/marvell.c | 45 ++++++++++++++++++++++++++++++++++-----
1 file changed, 40 insertions(+), 5 deletions(-)
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -144,11 +144,13 @@
/* WOL Event Interrupt Enable */
#define MII_88E1318S_PHY_CSIER_WOL_EIE BIT(7)
-/* LED Timer Control Register */
-#define MII_88E1318S_PHY_LED_TCR 0x12
-#define MII_88E1318S_PHY_LED_TCR_FORCE_INT BIT(15)
-#define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE BIT(7)
-#define MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW BIT(11)
+#define MII_88E1318S_PHY_LED_FUNC 0x10
+#define MII_88E1318S_PHY_LED_FUNC_OFF (0x8)
+#define MII_88E1318S_PHY_LED_FUNC_ON (0x9)
+#define MII_88E1318S_PHY_LED_TCR 0x12
+#define MII_88E1318S_PHY_LED_TCR_FORCE_INT BIT(15)
+#define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE BIT(7)
+#define MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW BIT(11)
/* Magic Packet MAC address registers */
#define MII_88E1318S_PHY_MAGIC_PACKET_WORD2 0x17
@@ -2793,6 +2795,34 @@ static int marvell_hwmon_probe(struct ph
}
#endif
+static int m88e1318_led_brightness_set(struct phy_device *phydev,
+ u8 index, enum led_brightness value)
+{
+ int reg;
+
+ reg = phy_read_paged(phydev, MII_MARVELL_LED_PAGE,
+ MII_88E1318S_PHY_LED_FUNC);
+ if (reg < 0)
+ return reg;
+
+ switch (index) {
+ case 0:
+ case 1:
+ case 2:
+ reg &= ~(0xf << (4 * index));
+ if (value == LED_OFF)
+ reg |= MII_88E1318S_PHY_LED_FUNC_OFF << (4 * index);
+ else
+ reg |= MII_88E1318S_PHY_LED_FUNC_ON << (4 * index);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return phy_write_paged(phydev, MII_MARVELL_LED_PAGE,
+ MII_88E1318S_PHY_LED_FUNC, reg);
+}
+
static int marvell_probe(struct phy_device *phydev)
{
struct marvell_priv *priv;
@@ -3041,6 +3071,7 @@ static struct phy_driver marvell_drivers
.get_sset_count = marvell_get_sset_count,
.get_strings = marvell_get_strings,
.get_stats = marvell_get_stats,
+ .led_brightness_set = m88e1318_led_brightness_set,
},
{
.phy_id = MARVELL_PHY_ID_88E1145,
@@ -3147,6 +3178,7 @@ static struct phy_driver marvell_drivers
.cable_test_start = marvell_vct7_cable_test_start,
.cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
.cable_test_get_status = marvell_vct7_cable_test_get_status,
+ .led_brightness_set = m88e1318_led_brightness_set,
},
{
.phy_id = MARVELL_PHY_ID_88E1540,
@@ -3173,6 +3205,7 @@ static struct phy_driver marvell_drivers
.cable_test_start = marvell_vct7_cable_test_start,
.cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
.cable_test_get_status = marvell_vct7_cable_test_get_status,
+ .led_brightness_set = m88e1318_led_brightness_set,
},
{
.phy_id = MARVELL_PHY_ID_88E1545,
@@ -3199,6 +3232,7 @@ static struct phy_driver marvell_drivers
.cable_test_start = marvell_vct7_cable_test_start,
.cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
.cable_test_get_status = marvell_vct7_cable_test_get_status,
+ .led_brightness_set = m88e1318_led_brightness_set,
},
{
.phy_id = MARVELL_PHY_ID_88E3016,
@@ -3340,6 +3374,7 @@ static struct phy_driver marvell_drivers
.get_stats = marvell_get_stats,
.get_tunable = m88e1540_get_tunable,
.set_tunable = m88e1540_set_tunable,
+ .led_brightness_set = m88e1318_led_brightness_set,
},
};

View File

@ -0,0 +1,73 @@
From 4e901018432e38eab35d2a352661ce4727795be1 Mon Sep 17 00:00:00 2001
From: Andrew Lunn <andrew@lunn.ch>
Date: Mon, 17 Apr 2023 17:17:30 +0200
Subject: [PATCH 8/9] net: phy: phy_device: Call into the PHY driver to set LED
blinking
Linux LEDs can be requested to perform hardware accelerated
blinking. Pass this to the PHY driver, if it implements the op.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/phy/phy_device.c | 18 ++++++++++++++++++
include/linux/phy.h | 12 ++++++++++++
2 files changed, 30 insertions(+)
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -2959,6 +2959,22 @@ static int phy_led_set_brightness(struct
return err;
}
+static int phy_led_blink_set(struct led_classdev *led_cdev,
+ unsigned long *delay_on,
+ unsigned long *delay_off)
+{
+ struct phy_led *phyled = to_phy_led(led_cdev);
+ struct phy_device *phydev = phyled->phydev;
+ int err;
+
+ mutex_lock(&phydev->lock);
+ err = phydev->drv->led_blink_set(phydev, phyled->index,
+ delay_on, delay_off);
+ mutex_unlock(&phydev->lock);
+
+ return err;
+}
+
static int of_phy_led(struct phy_device *phydev,
struct device_node *led)
{
@@ -2981,6 +2997,8 @@ static int of_phy_led(struct phy_device
if (phydev->drv->led_brightness_set)
cdev->brightness_set_blocking = phy_led_set_brightness;
+ if (phydev->drv->led_blink_set)
+ cdev->blink_set = phy_led_blink_set;
cdev->max_brightness = 1;
init_data.devicename = dev_name(&phydev->mdio.dev);
init_data.fwnode = of_fwnode_handle(led);
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -966,6 +966,18 @@ struct phy_driver {
*/
int (*led_brightness_set)(struct phy_device *dev,
u8 index, enum led_brightness value);
+
+ /**
+ * @led_blink_set: Set a PHY LED brightness. Index indicates
+ * which of the PHYs led should be configured to blink. Delays
+ * are in milliseconds and if both are zero then a sensible
+ * default should be chosen. The call should adjust the
+ * timings in that case and if it can't match the values
+ * specified exactly.
+ */
+ int (*led_blink_set)(struct phy_device *dev, u8 index,
+ unsigned long *delay_on,
+ unsigned long *delay_off);
};
#define to_phy_driver(d) container_of(to_mdio_common_driver(d), \
struct phy_driver, mdiodrv)

View File

@ -0,0 +1,104 @@
From ea9e86485decb2ac1750005bd96c166c9b780406 Mon Sep 17 00:00:00 2001
From: Andrew Lunn <andrew@lunn.ch>
Date: Mon, 17 Apr 2023 17:17:31 +0200
Subject: [PATCH 9/9] net: phy: marvell: Implement led_blink_set()
The Marvell PHY can blink the LEDs, simple on/off. All LEDs blink at
the same rate, and the reset default is 84ms per blink, which is
around 12Hz.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/phy/marvell.c | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -147,6 +147,8 @@
#define MII_88E1318S_PHY_LED_FUNC 0x10
#define MII_88E1318S_PHY_LED_FUNC_OFF (0x8)
#define MII_88E1318S_PHY_LED_FUNC_ON (0x9)
+#define MII_88E1318S_PHY_LED_FUNC_HI_Z (0xa)
+#define MII_88E1318S_PHY_LED_FUNC_BLINK (0xb)
#define MII_88E1318S_PHY_LED_TCR 0x12
#define MII_88E1318S_PHY_LED_TCR_FORCE_INT BIT(15)
#define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE BIT(7)
@@ -2823,6 +2825,35 @@ static int m88e1318_led_brightness_set(s
MII_88E1318S_PHY_LED_FUNC, reg);
}
+static int m88e1318_led_blink_set(struct phy_device *phydev, u8 index,
+ unsigned long *delay_on,
+ unsigned long *delay_off)
+{
+ int reg;
+
+ reg = phy_read_paged(phydev, MII_MARVELL_LED_PAGE,
+ MII_88E1318S_PHY_LED_FUNC);
+ if (reg < 0)
+ return reg;
+
+ switch (index) {
+ case 0:
+ case 1:
+ case 2:
+ reg &= ~(0xf << (4 * index));
+ reg |= MII_88E1318S_PHY_LED_FUNC_BLINK << (4 * index);
+ /* Reset default is 84ms */
+ *delay_on = 84 / 2;
+ *delay_off = 84 / 2;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return phy_write_paged(phydev, MII_MARVELL_LED_PAGE,
+ MII_88E1318S_PHY_LED_FUNC, reg);
+}
+
static int marvell_probe(struct phy_device *phydev)
{
struct marvell_priv *priv;
@@ -3072,6 +3103,7 @@ static struct phy_driver marvell_drivers
.get_strings = marvell_get_strings,
.get_stats = marvell_get_stats,
.led_brightness_set = m88e1318_led_brightness_set,
+ .led_blink_set = m88e1318_led_blink_set,
},
{
.phy_id = MARVELL_PHY_ID_88E1145,
@@ -3179,6 +3211,7 @@ static struct phy_driver marvell_drivers
.cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
.cable_test_get_status = marvell_vct7_cable_test_get_status,
.led_brightness_set = m88e1318_led_brightness_set,
+ .led_blink_set = m88e1318_led_blink_set,
},
{
.phy_id = MARVELL_PHY_ID_88E1540,
@@ -3206,6 +3239,7 @@ static struct phy_driver marvell_drivers
.cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
.cable_test_get_status = marvell_vct7_cable_test_get_status,
.led_brightness_set = m88e1318_led_brightness_set,
+ .led_blink_set = m88e1318_led_blink_set,
},
{
.phy_id = MARVELL_PHY_ID_88E1545,
@@ -3233,6 +3267,7 @@ static struct phy_driver marvell_drivers
.cable_test_tdr_start = marvell_vct5_cable_test_tdr_start,
.cable_test_get_status = marvell_vct7_cable_test_get_status,
.led_brightness_set = m88e1318_led_brightness_set,
+ .led_blink_set = m88e1318_led_blink_set,
},
{
.phy_id = MARVELL_PHY_ID_88E3016,
@@ -3375,6 +3410,7 @@ static struct phy_driver marvell_drivers
.get_tunable = m88e1540_get_tunable,
.set_tunable = m88e1540_set_tunable,
.led_brightness_set = m88e1318_led_brightness_set,
+ .led_blink_set = m88e1318_led_blink_set,
},
};

View File

@ -0,0 +1,38 @@
From 4774ad841bef97cc51df90195338c5b2573dd4cb Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Sun, 23 Apr 2023 19:28:00 +0200
Subject: [PATCH] net: phy: marvell: Fix inconsistent indenting in
led_blink_set
Fix inconsistent indeinting in m88e1318_led_blink_set reported by kernel
test robot, probably done by the presence of an if condition dropped in
later revision of the same code.
Reported-by: kernel test robot <lkp@intel.com>
Link: https://lore.kernel.org/oe-kbuild-all/202304240007.0VEX8QYG-lkp@intel.com/
Fixes: ea9e86485dec ("net: phy: marvell: Implement led_blink_set()")
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://lore.kernel.org/r/20230423172800.3470-1-ansuelsmth@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/phy/marvell.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -2841,10 +2841,10 @@ static int m88e1318_led_blink_set(struct
case 1:
case 2:
reg &= ~(0xf << (4 * index));
- reg |= MII_88E1318S_PHY_LED_FUNC_BLINK << (4 * index);
- /* Reset default is 84ms */
- *delay_on = 84 / 2;
- *delay_off = 84 / 2;
+ reg |= MII_88E1318S_PHY_LED_FUNC_BLINK << (4 * index);
+ /* Reset default is 84ms */
+ *delay_on = 84 / 2;
+ *delay_off = 84 / 2;
break;
default:
return -EINVAL;

View File

@ -0,0 +1,87 @@
From e2f24cb1b5daf9a4f6f3ba574c1fa74aab9807a4 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Wed, 19 Apr 2023 23:07:40 +0200
Subject: [PATCH 2/5] leds: trigger: netdev: Drop NETDEV_LED_MODE_LINKUP from
mode
Putting NETDEV_LED_MODE_LINKUP in the same list of the netdev trigger
modes is wrong as it's used to set the link state of the device and not
to set a blink mode as it's done by NETDEV_LED_LINK, NETDEV_LED_TX and
NETDEV_LED_RX. It's also wrong to put this state in the same bitmap of the
netdev trigger mode and should be external to it.
Drop NETDEV_LED_MODE_LINKUP from mode list and convert to a simple bool
that will be true or false based on the carrier link. No functional
change intended.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Lee Jones <lee@kernel.org>
Link: https://lore.kernel.org/r/20230419210743.3594-3-ansuelsmth@gmail.com
---
drivers/leds/trigger/ledtrig-netdev.c | 19 ++++++++-----------
1 file changed, 8 insertions(+), 11 deletions(-)
--- a/drivers/leds/trigger/ledtrig-netdev.c
+++ b/drivers/leds/trigger/ledtrig-netdev.c
@@ -50,10 +50,10 @@ struct led_netdev_data {
unsigned int last_activity;
unsigned long mode;
+ bool carrier_link_up;
#define NETDEV_LED_LINK 0
#define NETDEV_LED_TX 1
#define NETDEV_LED_RX 2
-#define NETDEV_LED_MODE_LINKUP 3
};
enum netdev_led_attr {
@@ -73,9 +73,9 @@ static void set_baseline_state(struct le
if (!led_cdev->blink_brightness)
led_cdev->blink_brightness = led_cdev->max_brightness;
- if (!test_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode))
+ if (!trigger_data->carrier_link_up) {
led_set_brightness(led_cdev, LED_OFF);
- else {
+ } else {
if (test_bit(NETDEV_LED_LINK, &trigger_data->mode))
led_set_brightness(led_cdev,
led_cdev->blink_brightness);
@@ -131,10 +131,9 @@ static ssize_t device_name_store(struct
trigger_data->net_dev =
dev_get_by_name(&init_net, trigger_data->device_name);
- clear_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode);
+ trigger_data->carrier_link_up = false;
if (trigger_data->net_dev != NULL)
- if (netif_carrier_ok(trigger_data->net_dev))
- set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode);
+ trigger_data->carrier_link_up = netif_carrier_ok(trigger_data->net_dev);
trigger_data->last_activity = 0;
@@ -315,11 +314,10 @@ static int netdev_trig_notify(struct not
spin_lock_bh(&trigger_data->lock);
- clear_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode);
+ trigger_data->carrier_link_up = false;
switch (evt) {
case NETDEV_CHANGENAME:
- if (netif_carrier_ok(dev))
- set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode);
+ trigger_data->carrier_link_up = netif_carrier_ok(dev);
fallthrough;
case NETDEV_REGISTER:
if (trigger_data->net_dev)
@@ -333,8 +331,7 @@ static int netdev_trig_notify(struct not
break;
case NETDEV_UP:
case NETDEV_CHANGE:
- if (netif_carrier_ok(dev))
- set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode);
+ trigger_data->carrier_link_up = netif_carrier_ok(dev);
break;
}

View File

@ -0,0 +1,149 @@
From bdec9cb83936e0ac4cb87fed5b49fad0175f7dec Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Wed, 19 Apr 2023 23:07:41 +0200
Subject: [PATCH 3/5] leds: trigger: netdev: Rename add namespace to netdev
trigger enum modes
Rename NETDEV trigger enum modes to a more symbolic name and add a
namespace to them.
Also add __TRIGGER_NETDEV_MAX to identify the max modes of the netdev
trigger.
This is a cleanup to drop the define and no behaviour change are
intended.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Lee Jones <lee@kernel.org>
Link: https://lore.kernel.org/r/20230419210743.3594-4-ansuelsmth@gmail.com
---
drivers/leds/trigger/ledtrig-netdev.c | 58 ++++++++++++---------------
1 file changed, 25 insertions(+), 33 deletions(-)
--- a/drivers/leds/trigger/ledtrig-netdev.c
+++ b/drivers/leds/trigger/ledtrig-netdev.c
@@ -51,15 +51,15 @@ struct led_netdev_data {
unsigned long mode;
bool carrier_link_up;
-#define NETDEV_LED_LINK 0
-#define NETDEV_LED_TX 1
-#define NETDEV_LED_RX 2
};
-enum netdev_led_attr {
- NETDEV_ATTR_LINK,
- NETDEV_ATTR_TX,
- NETDEV_ATTR_RX
+enum led_trigger_netdev_modes {
+ TRIGGER_NETDEV_LINK = 0,
+ TRIGGER_NETDEV_TX,
+ TRIGGER_NETDEV_RX,
+
+ /* Keep last */
+ __TRIGGER_NETDEV_MAX,
};
static void set_baseline_state(struct led_netdev_data *trigger_data)
@@ -76,7 +76,7 @@ static void set_baseline_state(struct le
if (!trigger_data->carrier_link_up) {
led_set_brightness(led_cdev, LED_OFF);
} else {
- if (test_bit(NETDEV_LED_LINK, &trigger_data->mode))
+ if (test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode))
led_set_brightness(led_cdev,
led_cdev->blink_brightness);
else
@@ -85,8 +85,8 @@ static void set_baseline_state(struct le
/* If we are looking for RX/TX start periodically
* checking stats
*/
- if (test_bit(NETDEV_LED_TX, &trigger_data->mode) ||
- test_bit(NETDEV_LED_RX, &trigger_data->mode))
+ if (test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) ||
+ test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode))
schedule_delayed_work(&trigger_data->work, 0);
}
}
@@ -146,20 +146,16 @@ static ssize_t device_name_store(struct
static DEVICE_ATTR_RW(device_name);
static ssize_t netdev_led_attr_show(struct device *dev, char *buf,
- enum netdev_led_attr attr)
+ enum led_trigger_netdev_modes attr)
{
struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
int bit;
switch (attr) {
- case NETDEV_ATTR_LINK:
- bit = NETDEV_LED_LINK;
- break;
- case NETDEV_ATTR_TX:
- bit = NETDEV_LED_TX;
- break;
- case NETDEV_ATTR_RX:
- bit = NETDEV_LED_RX;
+ case TRIGGER_NETDEV_LINK:
+ case TRIGGER_NETDEV_TX:
+ case TRIGGER_NETDEV_RX:
+ bit = attr;
break;
default:
return -EINVAL;
@@ -169,7 +165,7 @@ static ssize_t netdev_led_attr_show(stru
}
static ssize_t netdev_led_attr_store(struct device *dev, const char *buf,
- size_t size, enum netdev_led_attr attr)
+ size_t size, enum led_trigger_netdev_modes attr)
{
struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
unsigned long state;
@@ -181,14 +177,10 @@ static ssize_t netdev_led_attr_store(str
return ret;
switch (attr) {
- case NETDEV_ATTR_LINK:
- bit = NETDEV_LED_LINK;
- break;
- case NETDEV_ATTR_TX:
- bit = NETDEV_LED_TX;
- break;
- case NETDEV_ATTR_RX:
- bit = NETDEV_LED_RX;
+ case TRIGGER_NETDEV_LINK:
+ case TRIGGER_NETDEV_TX:
+ case TRIGGER_NETDEV_RX:
+ bit = attr;
break;
default:
return -EINVAL;
@@ -360,21 +352,21 @@ static void netdev_trig_work(struct work
}
/* If we are not looking for RX/TX then return */
- if (!test_bit(NETDEV_LED_TX, &trigger_data->mode) &&
- !test_bit(NETDEV_LED_RX, &trigger_data->mode))
+ if (!test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) &&
+ !test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode))
return;
dev_stats = dev_get_stats(trigger_data->net_dev, &temp);
new_activity =
- (test_bit(NETDEV_LED_TX, &trigger_data->mode) ?
+ (test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) ?
dev_stats->tx_packets : 0) +
- (test_bit(NETDEV_LED_RX, &trigger_data->mode) ?
+ (test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode) ?
dev_stats->rx_packets : 0);
if (trigger_data->last_activity != new_activity) {
led_stop_software_blink(trigger_data->led_cdev);
- invert = test_bit(NETDEV_LED_LINK, &trigger_data->mode);
+ invert = test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode);
interval = jiffies_to_msecs(
atomic_read(&trigger_data->interval));
/* base state is ON (link present) */

View File

@ -0,0 +1,82 @@
From 164b67d53476a9d114be85c885bd31f783835be4 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Wed, 19 Apr 2023 23:07:42 +0200
Subject: [PATCH 4/5] leds: trigger: netdev: Convert device attr to macro
Convert link tx and rx device attr to a common macro to reduce common
code and in preparation for additional attr.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Lee Jones <lee@kernel.org>
Link: https://lore.kernel.org/r/20230419210743.3594-5-ansuelsmth@gmail.com
---
drivers/leds/trigger/ledtrig-netdev.c | 57 ++++++++-------------------
1 file changed, 16 insertions(+), 41 deletions(-)
--- a/drivers/leds/trigger/ledtrig-netdev.c
+++ b/drivers/leds/trigger/ledtrig-netdev.c
@@ -198,47 +198,22 @@ static ssize_t netdev_led_attr_store(str
return size;
}
-static ssize_t link_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return netdev_led_attr_show(dev, buf, NETDEV_ATTR_LINK);
-}
-
-static ssize_t link_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
-{
- return netdev_led_attr_store(dev, buf, size, NETDEV_ATTR_LINK);
-}
-
-static DEVICE_ATTR_RW(link);
-
-static ssize_t tx_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return netdev_led_attr_show(dev, buf, NETDEV_ATTR_TX);
-}
-
-static ssize_t tx_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
-{
- return netdev_led_attr_store(dev, buf, size, NETDEV_ATTR_TX);
-}
-
-static DEVICE_ATTR_RW(tx);
-
-static ssize_t rx_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return netdev_led_attr_show(dev, buf, NETDEV_ATTR_RX);
-}
-
-static ssize_t rx_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
-{
- return netdev_led_attr_store(dev, buf, size, NETDEV_ATTR_RX);
-}
-
-static DEVICE_ATTR_RW(rx);
+#define DEFINE_NETDEV_TRIGGER(trigger_name, trigger) \
+ static ssize_t trigger_name##_show(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+ { \
+ return netdev_led_attr_show(dev, buf, trigger); \
+ } \
+ static ssize_t trigger_name##_store(struct device *dev, \
+ struct device_attribute *attr, const char *buf, size_t size) \
+ { \
+ return netdev_led_attr_store(dev, buf, size, trigger); \
+ } \
+ static DEVICE_ATTR_RW(trigger_name)
+
+DEFINE_NETDEV_TRIGGER(link, TRIGGER_NETDEV_LINK);
+DEFINE_NETDEV_TRIGGER(tx, TRIGGER_NETDEV_TX);
+DEFINE_NETDEV_TRIGGER(rx, TRIGGER_NETDEV_RX);
static ssize_t interval_show(struct device *dev,
struct device_attribute *attr, char *buf)

View File

@ -0,0 +1,106 @@
From d1b9e1391ab2dc80e9db87fe8b2de015c651e4c9 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Wed, 19 Apr 2023 23:07:43 +0200
Subject: [PATCH 5/5] leds: trigger: netdev: Use mutex instead of spinlocks
Some LEDs may require to sleep while doing some operation like setting
brightness and other cleanup.
For this reason, using a spinlock will cause a sleep under spinlock
warning.
It should be safe to convert this to a sleepable lock since:
- sysfs read/write can sleep
- netdev_trig_work is a work queue and can sleep
- netdev _trig_notify can sleep
The spinlock was used when brightness didn't support sleeping, but this
changed and now it supported with brightness_set_blocking().
Convert to mutex lock to permit sleeping using brightness_set_blocking().
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Lee Jones <lee@kernel.org>
Link: https://lore.kernel.org/r/20230419210743.3594-6-ansuelsmth@gmail.com
---
drivers/leds/trigger/ledtrig-netdev.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
--- a/drivers/leds/trigger/ledtrig-netdev.c
+++ b/drivers/leds/trigger/ledtrig-netdev.c
@@ -20,7 +20,7 @@
#include <linux/list.h>
#include <linux/module.h>
#include <linux/netdevice.h>
-#include <linux/spinlock.h>
+#include <linux/mutex.h>
#include <linux/timer.h>
#include "../leds.h"
@@ -37,7 +37,7 @@
*/
struct led_netdev_data {
- spinlock_t lock;
+ struct mutex lock;
struct delayed_work work;
struct notifier_block notifier;
@@ -97,9 +97,9 @@ static ssize_t device_name_show(struct d
struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
ssize_t len;
- spin_lock_bh(&trigger_data->lock);
+ mutex_lock(&trigger_data->lock);
len = sprintf(buf, "%s\n", trigger_data->device_name);
- spin_unlock_bh(&trigger_data->lock);
+ mutex_unlock(&trigger_data->lock);
return len;
}
@@ -115,7 +115,7 @@ static ssize_t device_name_store(struct
cancel_delayed_work_sync(&trigger_data->work);
- spin_lock_bh(&trigger_data->lock);
+ mutex_lock(&trigger_data->lock);
if (trigger_data->net_dev) {
dev_put(trigger_data->net_dev);
@@ -138,7 +138,7 @@ static ssize_t device_name_store(struct
trigger_data->last_activity = 0;
set_baseline_state(trigger_data);
- spin_unlock_bh(&trigger_data->lock);
+ mutex_unlock(&trigger_data->lock);
return size;
}
@@ -279,7 +279,7 @@ static int netdev_trig_notify(struct not
cancel_delayed_work_sync(&trigger_data->work);
- spin_lock_bh(&trigger_data->lock);
+ mutex_lock(&trigger_data->lock);
trigger_data->carrier_link_up = false;
switch (evt) {
@@ -304,7 +304,7 @@ static int netdev_trig_notify(struct not
set_baseline_state(trigger_data);
- spin_unlock_bh(&trigger_data->lock);
+ mutex_unlock(&trigger_data->lock);
return NOTIFY_DONE;
}
@@ -365,7 +365,7 @@ static int netdev_trig_activate(struct l
if (!trigger_data)
return -ENOMEM;
- spin_lock_init(&trigger_data->lock);
+ mutex_init(&trigger_data->lock);
trigger_data->notifier.notifier_call = netdev_trig_notify;
trigger_data->notifier.priority = 10;

View File

@ -0,0 +1,74 @@
From ed554d3f945179c5b159bddfad7be34b403fe11a Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Mon, 29 May 2023 18:32:31 +0200
Subject: [PATCH 01/13] leds: add APIs for LEDs hw control
Add an option to permit LED driver to declare support for a specific
trigger to use hw control and setup the LED to blink based on specific
provided modes.
Add APIs for LEDs hw control. These functions will be used to activate
hardware control where a LED will use the provided flags, from an
unique defined supported trigger, to setup the LED to be driven by
hardware.
Add hw_control_is_supported() to ask the LED driver if the requested
mode by the trigger are supported and the LED can be setup to follow
the requested modes.
Deactivate hardware blink control by setting brightness to LED_OFF via
the brightness_set() callback.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
include/linux/leds.h | 37 +++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -164,6 +164,43 @@ struct led_classdev {
/* LEDs that have private triggers have this set */
struct led_hw_trigger_type *trigger_type;
+
+ /* Unique trigger name supported by LED set in hw control mode */
+ const char *hw_control_trigger;
+ /*
+ * Check if the LED driver supports the requested mode provided by the
+ * defined supported trigger to setup the LED to hw control mode.
+ *
+ * Return 0 on success. Return -EOPNOTSUPP when the passed flags are not
+ * supported and software fallback needs to be used.
+ * Return a negative error number on any other case for check fail due
+ * to various reason like device not ready or timeouts.
+ */
+ int (*hw_control_is_supported)(struct led_classdev *led_cdev,
+ unsigned long flags);
+ /*
+ * Activate hardware control, LED driver will use the provided flags
+ * from the supported trigger and setup the LED to be driven by hardware
+ * following the requested mode from the trigger flags.
+ * Deactivate hardware blink control by setting brightness to LED_OFF via
+ * the brightness_set() callback.
+ *
+ * Return 0 on success, a negative error number on flags apply fail.
+ */
+ int (*hw_control_set)(struct led_classdev *led_cdev,
+ unsigned long flags);
+ /*
+ * Get from the LED driver the current mode that the LED is set in hw
+ * control mode and put them in flags.
+ * Trigger can use this to get the initial state of a LED already set in
+ * hardware blink control.
+ *
+ * Return 0 on success, a negative error number on failing parsing the
+ * initial mode. Error from this function is NOT FATAL as the device
+ * may be in a not supported initial state by the attached LED trigger.
+ */
+ int (*hw_control_get)(struct led_classdev *led_cdev,
+ unsigned long *flags);
#endif
#ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED

View File

@ -0,0 +1,37 @@
From 052c38eb17e866c5b4cd43924e7a5e20167b55c0 Mon Sep 17 00:00:00 2001
From: Andrew Lunn <andrew@lunn.ch>
Date: Mon, 29 May 2023 18:32:32 +0200
Subject: [PATCH 02/13] leds: add API to get attached device for LED hw control
Some specific LED triggers blink the LED based on events from a device
or subsystem.
For example, an LED could be blinked to indicate a network device is
receiving packets, or a disk is reading blocks. To correctly enable and
request the hw control of the LED, the trigger has to check if the
network interface or block device configured via a /sys/class/led file
match the one the LED driver provide for hw control for.
Provide an API call to get the device which the LED blinks for.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
include/linux/leds.h | 6 ++++++
1 file changed, 6 insertions(+)
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -201,6 +201,12 @@ struct led_classdev {
*/
int (*hw_control_get)(struct led_classdev *led_cdev,
unsigned long *flags);
+ /*
+ * Get the device this LED blinks in response to.
+ * e.g. for a PHY LED, it is the network device. If the LED is
+ * not yet associated to a device, return NULL.
+ */
+ struct device *(*hw_control_get_device)(struct led_classdev *led_cdev);
#endif
#ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED

View File

@ -0,0 +1,113 @@
From 8aa2fd7b66980ecd2e45e95af61cf7eafede1211 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Mon, 29 May 2023 18:32:33 +0200
Subject: [PATCH 03/13] Documentation: leds: leds-class: Document new Hardware
driven LEDs APIs
Document new Hardware driven LEDs APIs.
Some LEDs can be programmed to be driven by hardware. This is not
limited to blink but also to turn off or on autonomously.
To support this feature, a LED needs to implement various additional
ops and needs to declare specific support for the supported triggers.
Add documentation for each required value and API to make hw control
possible and implementable by both LEDs and triggers.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
Documentation/leds/leds-class.rst | 81 +++++++++++++++++++++++++++++++
1 file changed, 81 insertions(+)
--- a/Documentation/leds/leds-class.rst
+++ b/Documentation/leds/leds-class.rst
@@ -169,6 +169,87 @@ Setting the brightness to zero with brig
should completely turn off the LED and cancel the previously programmed
hardware blinking function, if any.
+Hardware driven LEDs
+====================
+
+Some LEDs can be programmed to be driven by hardware. This is not
+limited to blink but also to turn off or on autonomously.
+To support this feature, a LED needs to implement various additional
+ops and needs to declare specific support for the supported triggers.
+
+With hw control we refer to the LED driven by hardware.
+
+LED driver must define the following value to support hw control:
+
+ - hw_control_trigger:
+ unique trigger name supported by the LED in hw control
+ mode.
+
+LED driver must implement the following API to support hw control:
+ - hw_control_is_supported:
+ check if the flags passed by the supported trigger can
+ be parsed and activate hw control on the LED.
+
+ Return 0 if the passed flags mask is supported and
+ can be set with hw_control_set().
+
+ If the passed flags mask is not supported -EOPNOTSUPP
+ must be returned, the LED trigger will use software
+ fallback in this case.
+
+ Return a negative error in case of any other error like
+ device not ready or timeouts.
+
+ - hw_control_set:
+ activate hw control. LED driver will use the provided
+ flags passed from the supported trigger, parse them to
+ a set of mode and setup the LED to be driven by hardware
+ following the requested modes.
+
+ Set LED_OFF via the brightness_set to deactivate hw control.
+
+ Return 0 on success, a negative error number on failing to
+ apply flags.
+
+ - hw_control_get:
+ get active modes from a LED already in hw control, parse
+ them and set in flags the current active flags for the
+ supported trigger.
+
+ Return 0 on success, a negative error number on failing
+ parsing the initial mode.
+ Error from this function is NOT FATAL as the device may
+ be in a not supported initial state by the attached LED
+ trigger.
+
+ - hw_control_get_device:
+ return the device associated with the LED driver in
+ hw control. A trigger might use this to match the
+ returned device from this function with a configured
+ device for the trigger as the source for blinking
+ events and correctly enable hw control.
+ (example a netdev trigger configured to blink for a
+ particular dev match the returned dev from get_device
+ to set hw control)
+
+ Returns a pointer to a struct device or NULL if nothing
+ is currently attached.
+
+LED driver can activate additional modes by default to workaround the
+impossibility of supporting each different mode on the supported trigger.
+Examples are hardcoding the blink speed to a set interval, enable special
+feature like bypassing blink if some requirements are not met.
+
+A trigger should first check if the hw control API are supported by the LED
+driver and check if the trigger is supported to verify if hw control is possible,
+use hw_control_is_supported to check if the flags are supported and only at
+the end use hw_control_set to activate hw control.
+
+A trigger can use hw_control_get to check if a LED is already in hw control
+and init their flags.
+
+When the LED is in hw control, no software blink is possible and doing so
+will effectively disable hw control.
Known Issues
============

View File

@ -0,0 +1,69 @@
From 28a6a2ef18ad840a390d519840c303b03040961c Mon Sep 17 00:00:00 2001
From: Andrew Lunn <andrew@lunn.ch>
Date: Mon, 29 May 2023 18:32:34 +0200
Subject: [PATCH 04/13] leds: trigger: netdev: refactor code setting device
name
Move the code into a helper, ready for it to be called at
other times. No intended behaviour change.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/leds/trigger/ledtrig-netdev.c | 29 ++++++++++++++++++---------
1 file changed, 20 insertions(+), 9 deletions(-)
--- a/drivers/leds/trigger/ledtrig-netdev.c
+++ b/drivers/leds/trigger/ledtrig-netdev.c
@@ -104,15 +104,9 @@ static ssize_t device_name_show(struct d
return len;
}
-static ssize_t device_name_store(struct device *dev,
- struct device_attribute *attr, const char *buf,
- size_t size)
+static int set_device_name(struct led_netdev_data *trigger_data,
+ const char *name, size_t size)
{
- struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
-
- if (size >= IFNAMSIZ)
- return -EINVAL;
-
cancel_delayed_work_sync(&trigger_data->work);
mutex_lock(&trigger_data->lock);
@@ -122,7 +116,7 @@ static ssize_t device_name_store(struct
trigger_data->net_dev = NULL;
}
- memcpy(trigger_data->device_name, buf, size);
+ memcpy(trigger_data->device_name, name, size);
trigger_data->device_name[size] = 0;
if (size > 0 && trigger_data->device_name[size - 1] == '\n')
trigger_data->device_name[size - 1] = 0;
@@ -140,6 +134,23 @@ static ssize_t device_name_store(struct
set_baseline_state(trigger_data);
mutex_unlock(&trigger_data->lock);
+ return 0;
+}
+
+static ssize_t device_name_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t size)
+{
+ struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
+ int ret;
+
+ if (size >= IFNAMSIZ)
+ return -EINVAL;
+
+ ret = set_device_name(trigger_data, buf, size);
+
+ if (ret < 0)
+ return ret;
return size;
}

View File

@ -0,0 +1,54 @@
From 4fd1b6d47a7a38e81fdc6f8be2ccd4216b3f93db Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Mon, 29 May 2023 18:32:35 +0200
Subject: [PATCH 05/13] leds: trigger: netdev: introduce check for possible hw
control
Introduce function to check if the requested mode can use hw control in
preparation for hw control support. Currently everything is handled in
software so can_hw_control will always return false.
Add knob with the new value hw_control in trigger_data struct to
set hw control possible. Useful for future implementation to implement
in set_baseline_state() the required function to set the requested mode
using LEDs hw control ops and in other function to reject set if hw
control is currently active.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/leds/trigger/ledtrig-netdev.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/drivers/leds/trigger/ledtrig-netdev.c
+++ b/drivers/leds/trigger/ledtrig-netdev.c
@@ -51,6 +51,7 @@ struct led_netdev_data {
unsigned long mode;
bool carrier_link_up;
+ bool hw_control;
};
enum led_trigger_netdev_modes {
@@ -91,6 +92,11 @@ static void set_baseline_state(struct le
}
}
+static bool can_hw_control(struct led_netdev_data *trigger_data)
+{
+ return false;
+}
+
static ssize_t device_name_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -204,6 +210,8 @@ static ssize_t netdev_led_attr_store(str
else
clear_bit(bit, &trigger_data->mode);
+ trigger_data->hw_control = can_hw_control(trigger_data);
+
set_baseline_state(trigger_data);
return size;

View File

@ -0,0 +1,42 @@
From 6352f25f9fadba59d5df2ba7139495759ccc81d5 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Mon, 29 May 2023 18:32:36 +0200
Subject: [PATCH 06/13] leds: trigger: netdev: add basic check for hw control
support
Add basic check for hw control support. Check if the required API are
defined and check if the defined trigger supported in hw control for the
LED driver match netdev.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/leds/trigger/ledtrig-netdev.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
--- a/drivers/leds/trigger/ledtrig-netdev.c
+++ b/drivers/leds/trigger/ledtrig-netdev.c
@@ -92,8 +92,22 @@ static void set_baseline_state(struct le
}
}
+static bool supports_hw_control(struct led_classdev *led_cdev)
+{
+ if (!led_cdev->hw_control_get || !led_cdev->hw_control_set ||
+ !led_cdev->hw_control_is_supported)
+ return false;
+
+ return !strcmp(led_cdev->hw_control_trigger, led_cdev->trigger->name);
+}
+
static bool can_hw_control(struct led_netdev_data *trigger_data)
{
+ struct led_classdev *led_cdev = trigger_data->led_cdev;
+
+ if (!supports_hw_control(led_cdev))
+ return false;
+
return false;
}

View File

@ -0,0 +1,28 @@
From c84c80c7388f887b10dafd70fc55bc6c5fe9fa5a Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Mon, 29 May 2023 18:32:37 +0200
Subject: [PATCH 07/13] leds: trigger: netdev: reject interval store for
hw_control
Reject interval store with hw_control enabled. It's are currently not
supported and MUST be set to the default value with hw control enabled.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/leds/trigger/ledtrig-netdev.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/leds/trigger/ledtrig-netdev.c
+++ b/drivers/leds/trigger/ledtrig-netdev.c
@@ -265,6 +265,9 @@ static ssize_t interval_store(struct dev
unsigned long value;
int ret;
+ if (trigger_data->hw_control)
+ return -EINVAL;
+
ret = kstrtoul(buf, 0, &value);
if (ret)
return ret;

View File

@ -0,0 +1,107 @@
From 7c145a34ba6e380616af93262fcab9fc7261d851 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Mon, 29 May 2023 18:32:38 +0200
Subject: [PATCH 08/13] leds: trigger: netdev: add support for LED hw control
Add support for LED hw control for the netdev trigger.
The trigger on calling set_baseline_state to configure a new mode, will
do various check to verify if hw control can be used for the requested
mode in can_hw_control() function.
It will first check if the LED driver supports hw control for the netdev
trigger, then will use hw_control_is_supported() and finally will call
hw_control_set() to apply the requested mode.
To use such mode, interval MUST be set to the default value and net_dev
MUST be set. If one of these 2 value are not valid, hw control will
never be used and normal software fallback is used.
The default interval value is moved to a define to make sure they are
always synced.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/leds/trigger/ledtrig-netdev.c | 43 +++++++++++++++++++++++++--
1 file changed, 41 insertions(+), 2 deletions(-)
--- a/drivers/leds/trigger/ledtrig-netdev.c
+++ b/drivers/leds/trigger/ledtrig-netdev.c
@@ -24,6 +24,8 @@
#include <linux/timer.h>
#include "../leds.h"
+#define NETDEV_LED_DEFAULT_INTERVAL 50
+
/*
* Configurable sysfs attributes:
*
@@ -68,6 +70,13 @@ static void set_baseline_state(struct le
int current_brightness;
struct led_classdev *led_cdev = trigger_data->led_cdev;
+ /* Already validated, hw control is possible with the requested mode */
+ if (trigger_data->hw_control) {
+ led_cdev->hw_control_set(led_cdev, trigger_data->mode);
+
+ return;
+ }
+
current_brightness = led_cdev->brightness;
if (current_brightness)
led_cdev->blink_brightness = current_brightness;
@@ -103,12 +112,42 @@ static bool supports_hw_control(struct l
static bool can_hw_control(struct led_netdev_data *trigger_data)
{
+ unsigned long default_interval = msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL);
+ unsigned int interval = atomic_read(&trigger_data->interval);
struct led_classdev *led_cdev = trigger_data->led_cdev;
+ int ret;
if (!supports_hw_control(led_cdev))
return false;
- return false;
+ /*
+ * Interval must be set to the default
+ * value. Any different value is rejected if in hw
+ * control.
+ */
+ if (interval != default_interval)
+ return false;
+
+ /*
+ * net_dev must be set with hw control, otherwise no
+ * blinking can be happening and there is nothing to
+ * offloaded.
+ */
+ if (!trigger_data->net_dev)
+ return false;
+
+ /* Check if the requested mode is supported */
+ ret = led_cdev->hw_control_is_supported(led_cdev, trigger_data->mode);
+ /* Fall back to software blinking if not supported */
+ if (ret == -EOPNOTSUPP)
+ return false;
+ if (ret) {
+ dev_warn(led_cdev->dev,
+ "Current mode check failed with error %d\n", ret);
+ return false;
+ }
+
+ return true;
}
static ssize_t device_name_show(struct device *dev,
@@ -413,7 +452,7 @@ static int netdev_trig_activate(struct l
trigger_data->device_name[0] = 0;
trigger_data->mode = 0;
- atomic_set(&trigger_data->interval, msecs_to_jiffies(50));
+ atomic_set(&trigger_data->interval, msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL));
trigger_data->last_activity = 0;
led_set_trigger_data(led_cdev, trigger_data);

View File

@ -0,0 +1,58 @@
From 33ec0b53befff2c0a7f3aa19ff08556d60585d6b Mon Sep 17 00:00:00 2001
From: Andrew Lunn <andrew@lunn.ch>
Date: Mon, 29 May 2023 18:32:39 +0200
Subject: [PATCH 09/13] leds: trigger: netdev: validate configured netdev
The netdev which the LED should blink for is configurable in
/sys/class/led/foo/device_name. Ensure when offloading that the
configured netdev is the same as the netdev the LED is associated
with. If it is not, only perform software blinking.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/leds/trigger/ledtrig-netdev.c | 24 ++++++++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)
--- a/drivers/leds/trigger/ledtrig-netdev.c
+++ b/drivers/leds/trigger/ledtrig-netdev.c
@@ -110,6 +110,24 @@ static bool supports_hw_control(struct l
return !strcmp(led_cdev->hw_control_trigger, led_cdev->trigger->name);
}
+/*
+ * Validate the configured netdev is the same as the one associated with
+ * the LED driver in hw control.
+ */
+static bool validate_net_dev(struct led_classdev *led_cdev,
+ struct net_device *net_dev)
+{
+ struct device *dev = led_cdev->hw_control_get_device(led_cdev);
+ struct net_device *ndev;
+
+ if (!dev)
+ return false;
+
+ ndev = to_net_dev(dev);
+
+ return ndev == net_dev;
+}
+
static bool can_hw_control(struct led_netdev_data *trigger_data)
{
unsigned long default_interval = msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL);
@@ -131,9 +149,11 @@ static bool can_hw_control(struct led_ne
/*
* net_dev must be set with hw control, otherwise no
* blinking can be happening and there is nothing to
- * offloaded.
+ * offloaded. Additionally, for hw control to be
+ * valid, the configured netdev must be the same as
+ * netdev associated to the LED.
*/
- if (!trigger_data->net_dev)
+ if (!validate_net_dev(led_cdev, trigger_data->net_dev))
return false;
/* Check if the requested mode is supported */

View File

@ -0,0 +1,53 @@
From 0316cc5629d15880dd3f097d221c55ca648bcd61 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Mon, 29 May 2023 18:32:40 +0200
Subject: [PATCH 10/13] leds: trigger: netdev: init mode if hw control already
active
On netdev trigger activation, hw control may be already active by
default. If this is the case and a device is actually provided by
hw_control_get_device(), init the already active mode and set the
bool to hw_control bool to true to reflect the already set mode in the
trigger_data.
Co-developed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/leds/trigger/ledtrig-netdev.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
--- a/drivers/leds/trigger/ledtrig-netdev.c
+++ b/drivers/leds/trigger/ledtrig-netdev.c
@@ -454,6 +454,8 @@ static void netdev_trig_work(struct work
static int netdev_trig_activate(struct led_classdev *led_cdev)
{
struct led_netdev_data *trigger_data;
+ unsigned long mode;
+ struct device *dev;
int rc;
trigger_data = kzalloc(sizeof(struct led_netdev_data), GFP_KERNEL);
@@ -475,6 +477,21 @@ static int netdev_trig_activate(struct l
atomic_set(&trigger_data->interval, msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL));
trigger_data->last_activity = 0;
+ /* Check if hw control is active by default on the LED.
+ * Init already enabled mode in hw control.
+ */
+ if (supports_hw_control(led_cdev) &&
+ !led_cdev->hw_control_get(led_cdev, &mode)) {
+ dev = led_cdev->hw_control_get_device(led_cdev);
+ if (dev) {
+ const char *name = dev_name(dev);
+
+ set_device_name(trigger_data, name, strlen(name));
+ trigger_data->hw_control = true;
+ trigger_data->mode = mode;
+ }
+ }
+
led_set_trigger_data(led_cdev, trigger_data);
rc = register_netdevice_notifier(&trigger_data->notifier);

View File

@ -0,0 +1,54 @@
From 947acacab5ea151291b861cdfbde16ff5cf1b08c Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Mon, 29 May 2023 18:32:41 +0200
Subject: [PATCH 11/13] leds: trigger: netdev: expose netdev trigger modes in
linux include
Expose netdev trigger modes to make them accessible by LED driver that
will support netdev trigger for hw control.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/leds/trigger/ledtrig-netdev.c | 9 ---------
include/linux/leds.h | 10 ++++++++++
2 files changed, 10 insertions(+), 9 deletions(-)
--- a/drivers/leds/trigger/ledtrig-netdev.c
+++ b/drivers/leds/trigger/ledtrig-netdev.c
@@ -56,15 +56,6 @@ struct led_netdev_data {
bool hw_control;
};
-enum led_trigger_netdev_modes {
- TRIGGER_NETDEV_LINK = 0,
- TRIGGER_NETDEV_TX,
- TRIGGER_NETDEV_RX,
-
- /* Keep last */
- __TRIGGER_NETDEV_MAX,
-};
-
static void set_baseline_state(struct led_netdev_data *trigger_data)
{
int current_brightness;
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -527,6 +527,16 @@ static inline void *led_get_trigger_data
#endif /* CONFIG_LEDS_TRIGGERS */
+/* Trigger specific enum */
+enum led_trigger_netdev_modes {
+ TRIGGER_NETDEV_LINK = 0,
+ TRIGGER_NETDEV_TX,
+ TRIGGER_NETDEV_RX,
+
+ /* Keep last */
+ __TRIGGER_NETDEV_MAX,
+};
+
/* Trigger specific functions */
#ifdef CONFIG_LEDS_TRIGGER_DISK
void ledtrig_disk_activity(bool write);

View File

@ -0,0 +1,200 @@
From e0256648c831af13cbfe4a1787327fcec01c2807 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Mon, 29 May 2023 18:32:42 +0200
Subject: [PATCH 12/13] net: dsa: qca8k: implement hw_control ops
Implement hw_control ops to drive Switch LEDs based on hardware events.
Netdev trigger is the declared supported trigger for hw control
operation and supports the following mode:
- tx
- rx
When hw_control_set is called, LEDs are set to follow the requested
mode.
Each LEDs will blink at 4Hz by default.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/dsa/qca/qca8k-leds.c | 154 +++++++++++++++++++++++++++++++
1 file changed, 154 insertions(+)
--- a/drivers/net/dsa/qca/qca8k-leds.c
+++ b/drivers/net/dsa/qca/qca8k-leds.c
@@ -32,6 +32,43 @@ qca8k_get_enable_led_reg(int port_num, i
}
static int
+qca8k_get_control_led_reg(int port_num, int led_num, struct qca8k_led_pattern_en *reg_info)
+{
+ reg_info->reg = QCA8K_LED_CTRL_REG(led_num);
+
+ /* 6 total control rule:
+ * 3 control rules for phy0-3 that applies to all their leds
+ * 3 control rules for phy4
+ */
+ if (port_num == 4)
+ reg_info->shift = QCA8K_LED_PHY4_CONTROL_RULE_SHIFT;
+ else
+ reg_info->shift = QCA8K_LED_PHY0123_CONTROL_RULE_SHIFT;
+
+ return 0;
+}
+
+static int
+qca8k_parse_netdev(unsigned long rules, u32 *offload_trigger)
+{
+ /* Parsing specific to netdev trigger */
+ if (test_bit(TRIGGER_NETDEV_TX, &rules))
+ *offload_trigger |= QCA8K_LED_TX_BLINK_MASK;
+ if (test_bit(TRIGGER_NETDEV_RX, &rules))
+ *offload_trigger |= QCA8K_LED_RX_BLINK_MASK;
+
+ if (rules && !*offload_trigger)
+ return -EOPNOTSUPP;
+
+ /* Enable some default rule by default to the requested mode:
+ * - Blink at 4Hz by default
+ */
+ *offload_trigger |= QCA8K_LED_BLINK_4HZ;
+
+ return 0;
+}
+
+static int
qca8k_led_brightness_set(struct qca8k_led *led,
enum led_brightness brightness)
{
@@ -165,6 +202,119 @@ qca8k_cled_blink_set(struct led_classdev
}
static int
+qca8k_cled_trigger_offload(struct led_classdev *ldev, bool enable)
+{
+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
+
+ struct qca8k_led_pattern_en reg_info;
+ struct qca8k_priv *priv = led->priv;
+ u32 mask, val = QCA8K_LED_ALWAYS_OFF;
+
+ qca8k_get_enable_led_reg(led->port_num, led->led_num, &reg_info);
+
+ if (enable)
+ val = QCA8K_LED_RULE_CONTROLLED;
+
+ if (led->port_num == 0 || led->port_num == 4) {
+ mask = QCA8K_LED_PATTERN_EN_MASK;
+ val <<= QCA8K_LED_PATTERN_EN_SHIFT;
+ } else {
+ mask = QCA8K_LED_PHY123_PATTERN_EN_MASK;
+ }
+
+ return regmap_update_bits(priv->regmap, reg_info.reg, mask << reg_info.shift,
+ val << reg_info.shift);
+}
+
+static bool
+qca8k_cled_hw_control_status(struct led_classdev *ldev)
+{
+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
+
+ struct qca8k_led_pattern_en reg_info;
+ struct qca8k_priv *priv = led->priv;
+ u32 val;
+
+ qca8k_get_enable_led_reg(led->port_num, led->led_num, &reg_info);
+
+ regmap_read(priv->regmap, reg_info.reg, &val);
+
+ val >>= reg_info.shift;
+
+ if (led->port_num == 0 || led->port_num == 4) {
+ val &= QCA8K_LED_PATTERN_EN_MASK;
+ val >>= QCA8K_LED_PATTERN_EN_SHIFT;
+ } else {
+ val &= QCA8K_LED_PHY123_PATTERN_EN_MASK;
+ }
+
+ return val == QCA8K_LED_RULE_CONTROLLED;
+}
+
+static int
+qca8k_cled_hw_control_is_supported(struct led_classdev *ldev, unsigned long rules)
+{
+ u32 offload_trigger = 0;
+
+ return qca8k_parse_netdev(rules, &offload_trigger);
+}
+
+static int
+qca8k_cled_hw_control_set(struct led_classdev *ldev, unsigned long rules)
+{
+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
+ struct qca8k_led_pattern_en reg_info;
+ struct qca8k_priv *priv = led->priv;
+ u32 offload_trigger = 0;
+ int ret;
+
+ ret = qca8k_parse_netdev(rules, &offload_trigger);
+ if (ret)
+ return ret;
+
+ ret = qca8k_cled_trigger_offload(ldev, true);
+ if (ret)
+ return ret;
+
+ qca8k_get_control_led_reg(led->port_num, led->led_num, &reg_info);
+
+ return regmap_update_bits(priv->regmap, reg_info.reg,
+ QCA8K_LED_RULE_MASK << reg_info.shift,
+ offload_trigger << reg_info.shift);
+}
+
+static int
+qca8k_cled_hw_control_get(struct led_classdev *ldev, unsigned long *rules)
+{
+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
+ struct qca8k_led_pattern_en reg_info;
+ struct qca8k_priv *priv = led->priv;
+ u32 val;
+ int ret;
+
+ /* With hw control not active return err */
+ if (!qca8k_cled_hw_control_status(ldev))
+ return -EINVAL;
+
+ qca8k_get_control_led_reg(led->port_num, led->led_num, &reg_info);
+
+ ret = regmap_read(priv->regmap, reg_info.reg, &val);
+ if (ret)
+ return ret;
+
+ val >>= reg_info.shift;
+ val &= QCA8K_LED_RULE_MASK;
+
+ /* Parsing specific to netdev trigger */
+ if (val & QCA8K_LED_TX_BLINK_MASK)
+ set_bit(TRIGGER_NETDEV_TX, rules);
+ if (val & QCA8K_LED_RX_BLINK_MASK)
+ set_bit(TRIGGER_NETDEV_RX, rules);
+
+ return 0;
+}
+
+static int
qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num)
{
struct fwnode_handle *led = NULL, *leds = NULL;
@@ -224,6 +374,10 @@ qca8k_parse_port_leds(struct qca8k_priv
port_led->cdev.max_brightness = 1;
port_led->cdev.brightness_set_blocking = qca8k_cled_brightness_set_blocking;
port_led->cdev.blink_set = qca8k_cled_blink_set;
+ port_led->cdev.hw_control_is_supported = qca8k_cled_hw_control_is_supported;
+ port_led->cdev.hw_control_set = qca8k_cled_hw_control_set;
+ port_led->cdev.hw_control_get = qca8k_cled_hw_control_get;
+ port_led->cdev.hw_control_trigger = "netdev";
init_data.default_label = ":port";
init_data.fwnode = led;
init_data.devname_mandatory = true;

View File

@ -0,0 +1,70 @@
From 4f53c27f772e27e4cf4e5507d6f4d5980002cb6a Mon Sep 17 00:00:00 2001
From: Andrew Lunn <andrew@lunn.ch>
Date: Mon, 29 May 2023 18:32:43 +0200
Subject: [PATCH 13/13] net: dsa: qca8k: add op to get ports netdev
In order that the LED trigger can blink the switch MAC ports LED, it
needs to know the netdev associated to the port. Add the callback to
return the struct device of the netdev.
Add an helper function qca8k_phy_to_port() to convert the phy back to
dsa_port index, as we reference LED port based on the internal PHY
index and needs to be converted back.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/dsa/qca/qca8k-leds.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
--- a/drivers/net/dsa/qca/qca8k-leds.c
+++ b/drivers/net/dsa/qca/qca8k-leds.c
@@ -5,6 +5,18 @@
#include "qca8k.h"
#include "qca8k_leds.h"
+static u32 qca8k_phy_to_port(int phy)
+{
+ /* Internal PHY 0 has port at index 1.
+ * Internal PHY 1 has port at index 2.
+ * Internal PHY 2 has port at index 3.
+ * Internal PHY 3 has port at index 4.
+ * Internal PHY 4 has port at index 5.
+ */
+
+ return phy + 1;
+}
+
static int
qca8k_get_enable_led_reg(int port_num, int led_num, struct qca8k_led_pattern_en *reg_info)
{
@@ -314,6 +326,20 @@ qca8k_cled_hw_control_get(struct led_cla
return 0;
}
+static struct device *qca8k_cled_hw_control_get_device(struct led_classdev *ldev)
+{
+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev);
+ struct qca8k_priv *priv = led->priv;
+ struct dsa_port *dp;
+
+ dp = dsa_to_port(priv->ds, qca8k_phy_to_port(led->port_num));
+ if (!dp)
+ return NULL;
+ if (dp->slave)
+ return &dp->slave->dev;
+ return NULL;
+}
+
static int
qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num)
{
@@ -377,6 +403,7 @@ qca8k_parse_port_leds(struct qca8k_priv
port_led->cdev.hw_control_is_supported = qca8k_cled_hw_control_is_supported;
port_led->cdev.hw_control_set = qca8k_cled_hw_control_set;
port_led->cdev.hw_control_get = qca8k_cled_hw_control_get;
+ port_led->cdev.hw_control_get_device = qca8k_cled_hw_control_get_device;
port_led->cdev.hw_control_trigger = "netdev";
init_data.default_label = ":port";
init_data.fwnode = led;

View File

@ -17,7 +17,7 @@ Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -2272,6 +2272,23 @@ struct btmtk_section_map {
@@ -2275,6 +2275,23 @@ struct btmtk_section_map {
};
} __packed;
@ -41,7 +41,7 @@ Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
static void btusb_mtk_wmt_recv(struct urb *urb)
{
struct hci_dev *hdev = urb->context;
@@ -3923,6 +3940,7 @@ static int btusb_probe(struct usb_interf
@@ -3926,6 +3943,7 @@ static int btusb_probe(struct usb_interf
hdev->shutdown = btusb_mtk_shutdown;
hdev->manufacturer = 70;
hdev->cmd_timeout = btusb_mtk_cmd_timeout;

View File

@ -18,7 +18,7 @@ Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -2277,7 +2277,7 @@ static int btusb_set_bdaddr_mtk(struct h
@@ -2280,7 +2280,7 @@ static int btusb_set_bdaddr_mtk(struct h
struct sk_buff *skb;
long ret;

View File

@ -4088,6 +4088,7 @@ CONFIG_NET_CORE=y
# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
# CONFIG_NET_DSA_MV88E6XXX_PTP is not set
# CONFIG_NET_DSA_QCA8K is not set
# CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT is not set
# CONFIG_NET_DSA_REALTEK_SMI is not set
# CONFIG_NET_DSA_SJA1105 is not set
# CONFIG_NET_DSA_SMSC_LAN9303_I2C is not set

View File

@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -61,6 +61,80 @@ config SFP
@@ -62,6 +62,80 @@ config SFP
depends on HWMON || HWMON=n
select MDIO_I2C

View File

@ -9,7 +9,7 @@ Subject: [PATCH] net/dsa/mv88e6xxx: disable ATU violation
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2985,6 +2985,9 @@ static int mv88e6xxx_setup_port(struct m
@@ -2993,6 +2993,9 @@ static int mv88e6xxx_setup_port(struct m
else
reg = 1 << port;

View File

@ -17,7 +17,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -584,10 +584,37 @@ int phylink_speed_up(struct phylink *pl)
@@ -600,10 +600,37 @@ int phylink_speed_up(struct phylink *pl)
#define phylink_test(bm, mode) __phylink_do_bit(test_bit, bm, mode)
void phylink_set_port_modes(unsigned long *bits);
@ -57,7 +57,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
const unsigned long *advertising);
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -885,7 +885,6 @@ static int phylink_change_inband_advert(
@@ -931,7 +931,6 @@ static int phylink_change_inband_advert(
return 0;
}
@ -65,7 +65,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
static void phylink_mac_pcs_get_state(struct phylink *pl,
struct phylink_link_state *state)
{
@@ -2966,6 +2965,52 @@ void phylink_mii_c22_pcs_get_state(struc
@@ -3014,6 +3013,52 @@ void phylink_mii_c22_pcs_get_state(struc
EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_get_state);
/**
@ -118,7 +118,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
* phylink_mii_c22_pcs_set_advertisement() - configure the clause 37 PCS
* advertisement
* @pcs: a pointer to a &struct mdio_device.
@@ -3037,6 +3082,46 @@ int phylink_mii_c22_pcs_set_advertisemen
@@ -3085,6 +3130,46 @@ int phylink_mii_c22_pcs_set_advertisemen
EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_set_advertisement);
/**

View File

@ -235,7 +235,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (!pe)
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -3964,6 +3964,8 @@ static const struct seq_operations vmall
@@ -3968,6 +3968,8 @@ static const struct seq_operations vmall
static int __init proc_vmalloc_init(void)
{

View File

@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -2992,8 +2992,8 @@ static irqreturn_t mtk_handle_irq_rx(int
@@ -3095,8 +3095,8 @@ static irqreturn_t mtk_handle_irq_rx(int
eth->rx_events++;
if (likely(napi_schedule_prep(&eth->rx_napi))) {
@ -20,7 +20,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
}
return IRQ_HANDLED;
@@ -3005,8 +3005,8 @@ static irqreturn_t mtk_handle_irq_tx(int
@@ -3108,8 +3108,8 @@ static irqreturn_t mtk_handle_irq_tx(int
eth->tx_events++;
if (likely(napi_schedule_prep(&eth->tx_napi))) {
@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
}
return IRQ_HANDLED;
@@ -4666,6 +4666,8 @@ static int mtk_probe(struct platform_dev
@@ -4883,6 +4883,8 @@ static int mtk_probe(struct platform_dev
* for NAPI to work
*/
init_dummy_netdev(&eth->dummy_dev);

View File

@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1748,6 +1748,9 @@ void phy_detach(struct phy_device *phyde
@@ -1751,6 +1751,9 @@ void phy_detach(struct phy_device *phyde
struct module *ndev_owner = NULL;
struct mii_bus *bus;
@ -23,7 +23,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
sysfs_remove_link(&dev->dev.kobj, "phydev");
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -823,6 +823,12 @@ struct phy_driver {
@@ -843,6 +843,12 @@ struct phy_driver {
/** @handle_interrupt: Override default interrupt handling */
irqreturn_t (*handle_interrupt)(struct phy_device *phydev);

View File

@ -161,7 +161,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
struct rtnl_link {
rtnl_doit_func doit;
@@ -4712,7 +4712,9 @@ int ndo_dflt_bridge_getlink(struct sk_bu
@@ -4739,7 +4739,9 @@ int ndo_dflt_bridge_getlink(struct sk_bu
brport_nla_put_flag(skb, flags, mask,
IFLA_BRPORT_MCAST_FLOOD, BR_MCAST_FLOOD) ||
brport_nla_put_flag(skb, flags, mask,

View File

@ -0,0 +1,44 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Thu, 27 Oct 2022 23:39:52 +0200
Subject: [PATCH] net: ethernet: mtk_eth_soc: compile out netsys v2 code
on mt7621
Avoid some branches in the hot path on low-end devices with limited CPU power,
and reduce code size
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -1323,6 +1323,22 @@ struct mtk_mac {
/* the struct describing the SoC. these are declared in the soc_xyz.c files */
extern const struct of_device_id of_mtk_match[];
+#ifdef CONFIG_SOC_MT7621
+static inline bool mtk_is_netsys_v1(struct mtk_eth *eth)
+{
+ return true;
+}
+
+static inline bool mtk_is_netsys_v2_or_greater(struct mtk_eth *eth)
+{
+ return false;
+}
+
+static inline bool mtk_is_netsys_v3_or_greater(struct mtk_eth *eth)
+{
+ return false;
+}
+#else
static inline bool mtk_is_netsys_v1(struct mtk_eth *eth)
{
return eth->soc->version == 1;
@@ -1337,6 +1353,7 @@ static inline bool mtk_is_netsys_v3_or_g
{
return eth->soc->version > 2;
}
+#endif
static inline struct mtk_foe_entry *
mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash)

View File

@ -16,7 +16,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -1423,12 +1423,28 @@ static void mtk_wake_queue(struct mtk_et
@@ -1516,12 +1516,28 @@ static void mtk_wake_queue(struct mtk_et
}
}
@ -45,11 +45,11 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
bool gso = false;
int tx_num;
@@ -1450,6 +1466,18 @@ static netdev_tx_t mtk_start_xmit(struct
@@ -1543,6 +1559,18 @@ static netdev_tx_t mtk_start_xmit(struct
return NETDEV_TX_BUSY;
}
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) &&
+ if (mtk_is_netsys_v1(eth) &&
+ skb_is_gso(skb) && mtk_skb_has_small_frag(skb)) {
+ segs = skb_gso_segment(skb, dev->features & ~NETIF_F_ALL_TSO);
+ if (IS_ERR(segs))
@ -64,14 +64,14 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
/* TSO: fill MSS info in tcp checksum field */
if (skb_is_gso(skb)) {
if (skb_cow_head(skb, 0)) {
@@ -1465,8 +1493,14 @@ static netdev_tx_t mtk_start_xmit(struct
@@ -1558,8 +1586,14 @@ static netdev_tx_t mtk_start_xmit(struct
}
}
- if (mtk_tx_map(skb, dev, tx_num, ring, gso) < 0)
- goto drop;
+ skb_list_walk_safe(skb, skb, next) {
+ if ((!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) &&
+ if ((mtk_is_netsys_v1(eth) &&
+ mtk_skb_has_small_frag(skb) && skb_linearize(skb)) ||
+ mtk_tx_map(skb, dev, tx_num, ring, gso) < 0) {
+ stats->tx_dropped++;
@ -83,7 +83,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
netif_tx_stop_all_queues(dev);
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -258,7 +258,7 @@
@@ -268,7 +268,7 @@
#define MTK_CHK_DDONE_EN BIT(28)
#define MTK_DMAD_WR_WDONE BIT(26)
#define MTK_WCOMP_EN BIT(24)

View File

@ -9,7 +9,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -48,8 +48,7 @@
@@ -47,8 +47,7 @@
#define MTK_HW_FEATURES (NETIF_F_IP_CSUM | \
NETIF_F_RXCSUM | \
NETIF_F_HW_VLAN_CTAG_TX | \

View File

@ -22,7 +22,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -667,6 +667,7 @@ static void mtk_mac_link_up(struct phyli
@@ -723,6 +723,7 @@ static void mtk_mac_link_up(struct phyli
MAC_MCR_FORCE_RX_FC);
/* Configure speed */
@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
switch (speed) {
case SPEED_2500:
case SPEED_1000:
@@ -3145,6 +3146,9 @@ found:
@@ -3288,6 +3289,9 @@ found:
if (dp->index >= MTK_QDMA_NUM_QUEUES)
return NOTIFY_DONE;

Some files were not shown because too many files have changed in this diff Show More