Merge Official Source
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_VERSION:=2025.10
|
||||
PKG_HASH:=b4f032848e56cc8f213ad59f9132c084dbbb632bc29176d024e58220e0efdf4a
|
||||
PKG_VERSION:=2026.04
|
||||
PKG_HASH:=ac7c04b8b7004923b00a4e5d6699c5df4d21233bac9fda690d8cfbc209fff2fd
|
||||
|
||||
UBOOT_USE_INTREE_DTC:=1
|
||||
|
||||
|
||||
@@ -421,6 +421,19 @@ define U-Boot/mt7981_cudy_wr3000p-v1
|
||||
DEPENDS:=+trusted-firmware-a-mt7981-cudy-ddr4
|
||||
endef
|
||||
|
||||
define U-Boot/mt7981_gatonetworks_gdsp
|
||||
NAME:=GatoNetworks GDSP
|
||||
BUILD_SUBTARGET:=filogic
|
||||
BUILD_DEVICES:=gatonetworks_gdsp
|
||||
UBOOT_CONFIG:=mt7981_gatonetworks_gdsp
|
||||
UBOOT_IMAGE:=u-boot.fip
|
||||
BL2_BOOTDEV:=nor
|
||||
BL2_SOC:=mt7981
|
||||
BL2_DDRTYPE:=ddr3
|
||||
DEPENDS:=+trusted-firmware-a-mt7981-nor-ddr3
|
||||
FIP_COMPRESS:=1
|
||||
endef
|
||||
|
||||
define U-Boot/mt7981_glinet_gl-mt2500
|
||||
NAME:=GL.iNet GL-MT2500
|
||||
BUILD_SUBTARGET:=filogic
|
||||
@@ -554,6 +567,18 @@ define U-Boot/mt7981_livinet_zr-3020
|
||||
DEPENDS:=+trusted-firmware-a-mt7981-spim-nand-ddr3
|
||||
endef
|
||||
|
||||
define U-Boot/mt7981_netis_eap930-v1
|
||||
NAME:=netis EAP930 V1
|
||||
BUILD_SUBTARGET:=filogic
|
||||
BUILD_DEVICES:=netis_eap930-v1
|
||||
UBOOT_CONFIG:=mt7981_netis_eap930-v1
|
||||
UBOOT_IMAGE:=u-boot.fip
|
||||
BL2_BOOTDEV:=spim-nand
|
||||
BL2_SOC:=mt7981
|
||||
BL2_DDRTYPE:=ddr3
|
||||
DEPENDS:=+trusted-firmware-a-mt7981-spim-nand-ddr3
|
||||
endef
|
||||
|
||||
define U-Boot/mt7981_netis_nx30v2
|
||||
NAME:=netis NX30 V2
|
||||
BUILD_SUBTARGET:=filogic
|
||||
@@ -651,19 +676,6 @@ define U-Boot/mt7981_rfb-emmc
|
||||
DEPENDS:=+trusted-firmware-a-mt7981-emmc-ddr3
|
||||
endef
|
||||
|
||||
define U-Boot/mt7981_gatonetworks_gdsp
|
||||
NAME:=GatoNetworks GDSP
|
||||
BUILD_SUBTARGET:=filogic
|
||||
BUILD_DEVICES:=gatonetworks_gdsp
|
||||
UBOOT_CONFIG:=mt7981_gatonetworks_gdsp
|
||||
UBOOT_IMAGE:=u-boot.fip
|
||||
BL2_BOOTDEV:=nor
|
||||
BL2_SOC:=mt7981
|
||||
BL2_DDRTYPE:=ddr3
|
||||
DEPENDS:=+trusted-firmware-a-mt7981-nor-ddr3
|
||||
FIP_COMPRESS:=1
|
||||
endef
|
||||
|
||||
define U-Boot/mt7981_rfb-nor
|
||||
NAME:=MT7981 Reference Board
|
||||
BUILD_SUBTARGET:=filogic
|
||||
@@ -1074,6 +1086,42 @@ define U-Boot/mt7987_bananapi_bpi-r4-lite-nor
|
||||
FIP_COMPRESS:=1
|
||||
endef
|
||||
|
||||
define U-Boot/mt7987_rfb-emmc
|
||||
NAME:=MT7987 Reference Board
|
||||
BUILD_SUBTARGET:=filogic
|
||||
BUILD_DEVICES:=mediatek_mt7987a-rfb
|
||||
UBOOT_CONFIG:=mt7987_emmc_rfb
|
||||
UBOOT_IMAGE:=u-boot.fip
|
||||
BL2_BOOTDEV:=emmc
|
||||
BL2_SOC:=mt7987
|
||||
BL2_DDRTYPE:=comb
|
||||
DEPENDS:=+trusted-firmware-a-mt7987-emmc-comb
|
||||
endef
|
||||
|
||||
define U-Boot/mt7987_rfb-spim-nand
|
||||
NAME:=MT7987 Reference Board
|
||||
BUILD_SUBTARGET:=filogic
|
||||
BUILD_DEVICES:=mediatek_mt7987a-rfb
|
||||
UBOOT_CONFIG:=mt7987_rfb
|
||||
UBOOT_IMAGE:=u-boot.fip
|
||||
BL2_BOOTDEV:=spim-nand0-ubi
|
||||
BL2_SOC:=mt7987
|
||||
BL2_DDRTYPE:=comb
|
||||
DEPENDS:=+trusted-firmware-a-mt7987-spim-nand0-ubi-comb
|
||||
endef
|
||||
|
||||
define U-Boot/mt7987_rfb-sd
|
||||
NAME:=MT7987 Reference Board
|
||||
BUILD_SUBTARGET:=filogic
|
||||
BUILD_DEVICES:=mediatek_mt7987a-rfb
|
||||
UBOOT_CONFIG:=mt7987_sd_rfb
|
||||
UBOOT_IMAGE:=u-boot.fip
|
||||
BL2_BOOTDEV:=sdmmc
|
||||
BL2_SOC:=mt7987
|
||||
BL2_DDRTYPE:=comb
|
||||
DEPENDS:=+trusted-firmware-a-mt7987-sdmmc-comb
|
||||
endef
|
||||
|
||||
define U-Boot/mt7987_routerich_be7200
|
||||
NAME:=Routerich BE7200
|
||||
BUILD_SUBTARGET:=filogic
|
||||
@@ -1217,42 +1265,6 @@ define U-Boot/mt7988_tplink_tl-7dr7250-v1
|
||||
DEPENDS:=+trusted-firmware-a-mt7988-spim-nand-ddr4
|
||||
endef
|
||||
|
||||
define U-Boot/mt7987_rfb-emmc
|
||||
NAME:=MT7987 Reference Board
|
||||
BUILD_SUBTARGET:=filogic
|
||||
BUILD_DEVICES:=mediatek_mt7987a-rfb
|
||||
UBOOT_CONFIG:=mt7987_emmc_rfb
|
||||
UBOOT_IMAGE:=u-boot.fip
|
||||
BL2_BOOTDEV:=sdmmc
|
||||
BL2_SOC:=mt7987
|
||||
BL2_DDRTYPE:=comb
|
||||
DEPENDS:=+trusted-firmware-a-mt7987-emmc-comb
|
||||
endef
|
||||
|
||||
define U-Boot/mt7987_rfb-spim-nand
|
||||
NAME:=MT7987 Reference Board
|
||||
BUILD_SUBTARGET:=filogic
|
||||
BUILD_DEVICES:=mediatek_mt7987a-rfb
|
||||
UBOOT_CONFIG:=mt7987_rfb
|
||||
UBOOT_IMAGE:=u-boot.fip
|
||||
BL2_BOOTDEV:=spim-nand0-ubi
|
||||
BL2_SOC:=mt7987
|
||||
BL2_DDRTYPE:=comb
|
||||
DEPENDS:=+trusted-firmware-a-mt7987-spim-nand0-ubi-comb
|
||||
endef
|
||||
|
||||
define U-Boot/mt7987_rfb-sd
|
||||
NAME:=MT7987 Reference Board
|
||||
BUILD_SUBTARGET:=filogic
|
||||
BUILD_DEVICES:=mediatek_mt7987a-rfb
|
||||
UBOOT_CONFIG:=mt7987_sd_rfb
|
||||
UBOOT_IMAGE:=u-boot.fip
|
||||
BL2_BOOTDEV:=sdmmc
|
||||
BL2_SOC:=mt7987
|
||||
BL2_DDRTYPE:=comb
|
||||
DEPENDS:=+trusted-firmware-a-mt7987-sdmmc-comb
|
||||
endef
|
||||
|
||||
define U-Boot/mt7988_rfb-spim-nand
|
||||
NAME:=MT7988 Reference Board
|
||||
BUILD_SUBTARGET:=filogic
|
||||
@@ -1363,6 +1375,7 @@ UBOOT_TARGETS := \
|
||||
mt7981_konka_komi-a31-emmc \
|
||||
mt7981_konka_komi-a31-nor \
|
||||
mt7981_livinet_zr-3020 \
|
||||
mt7981_netis_eap930-v1 \
|
||||
mt7981_netis_nx30v2 \
|
||||
mt7981_netis_nx31 \
|
||||
mt7981_netis_nx32u \
|
||||
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ryan Leung <untilscour@protonmail.com>
|
||||
Date: Wed, 20 May 2026 15:16:13 +1000
|
||||
Subject: [PATCH] mtd: nand: spi: otp: add NULL guards to OTP size functions
|
||||
|
||||
U-Boot v2026.01 introduced drivers/mtd/nand/spi/otp.c which adds `spinand_user_otp_size()` and
|
||||
`spinand_fact_otp_size()`. These functions are called unconditionally from `spinand_init()` in
|
||||
drivers/mtd/nand/spi/core.c to determine whether to set up OTP methods:
|
||||
|
||||
if (spinand_user_otp_size(spinand) || spinand_fact_otp_size(spinand)) {
|
||||
ret = spinand_set_mtd_otp_ops(spinand); /* drivers/mtd/nand/spi/core.c:2369 */
|
||||
...
|
||||
}
|
||||
|
||||
Both OTP size functions pass `&spinand->user_otp->layout` or `&spinand->fact_otp->layout` to
|
||||
`spinand_otp_size()` without first checking whether the pointer is NULL. In the standard probing
|
||||
path, these pointers are assigned by `spinand_match_and_init()` from the per-chip `spinand_info`
|
||||
table. `100-21-mtd-spi-nand-add-CASN-page-support.patch` adds CASN detection to `spinand_detect()`
|
||||
so that when a CASN page is found, `spinand_init_via_casn()` is called instead of
|
||||
`spinand_id_detect()`. As `spinand_match_and_init()` is only called via `spinand_id_detect()`, it
|
||||
is never invoked for CASN-probed devices.
|
||||
|
||||
As a result, `spinand->user_otp` and `spinand->fact_otp` remain NULL from the zero-initialised DM
|
||||
priv allocation. Both `spinand_user_otp_size()` and `spinand_fact_otp_size()` spuriously return
|
||||
non-zero by reading `layout->npages` from a small mapped address computed from their respective
|
||||
NULL pointer, causing `spinand_init()` to call `spinand_set_mtd_otp_ops()` which reads
|
||||
`spinand->user_otp->ops` and thereby silently assigns a garbage value to `user_ops` that is then
|
||||
dereferenced at `if (user_ops->info)`.
|
||||
|
||||
int spinand_set_mtd_otp_ops(struct spinand_device *spinand)
|
||||
{
|
||||
struct mtd_info *mtd = spinand_to_mtd(spinand);
|
||||
const struct spinand_fact_otp_ops *fact_ops = spinand->fact_otp->ops;
|
||||
const struct spinand_user_otp_ops *user_ops = spinand->user_otp->ops;
|
||||
...
|
||||
if (user_ops) {
|
||||
if (user_ops->info) /* drivers/mtd/nand/spi/otp.c:343 */
|
||||
...
|
||||
...
|
||||
}
|
||||
...
|
||||
}
|
||||
|
||||
On COMFAST CF-WR632AX (MT7981, Winbond W25N01GV) this results in a "Synchronous Abort" during boot.
|
||||
The crash was confirmed via `addr2line` on the U-Boot ELF:
|
||||
|
||||
"Synchronous Abort" handler, esr 0x96000004, far 0xeafffffeeafffffe
|
||||
elr: 0000000041e2ff44 (drivers/mtd/nand/spi/otp.c:343)
|
||||
lr : 0000000041e2f2f8 (drivers/mtd/nand/spi/core.c:2369)
|
||||
|
||||
The same was observed on Acer Predator Connect W6x (MT7986, Winbond W25N02KV):
|
||||
|
||||
"Synchronous Abort" handler, esr 0x96000004, far 0xeafffffeeafffffe
|
||||
elr: 0000000041e2c868 (drivers/mtd/nand/spi/otp.c:343)
|
||||
lr : 0000000041e2bc1c (drivers/mtd/nand/spi/core.c:2369)
|
||||
|
||||
Fix this by adding NULL guards to both OTP size functions so that they return 0 when the pointer is
|
||||
NULL. With both functions returning 0, the condition in `spinand_init()` evaluates to false and
|
||||
`spinand_set_mtd_otp_ops()` is never called, skipping setup of OTP methods entirely for CASN-probed
|
||||
SPI NAND chips.
|
||||
|
||||
This change has no effect on SPI NAND chips that do have OTP data but not CASN. For those chips,
|
||||
`spinand_match_and_init()` sets `spinand->user_otp` and `spinand->fact_otp` to non-NULL values from
|
||||
the per-chip table, the NULL guard does not activate, and the existing behaviour is unchanged.
|
||||
|
||||
Fixes: b94de14bafd06660536691ed633f364edf5fbe4d ("uboot-mediatek: update to v2026.01")
|
||||
Signed-off-by: Ryan Leung <untilscour@protonmail.com>
|
||||
---
|
||||
drivers/mtd/nand/spi/otp.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/drivers/mtd/nand/spi/otp.c
|
||||
+++ b/drivers/mtd/nand/spi/otp.c
|
||||
@@ -39,6 +39,8 @@ static size_t spinand_otp_size(struct sp
|
||||
*/
|
||||
size_t spinand_fact_otp_size(struct spinand_device *spinand)
|
||||
{
|
||||
+ if (!spinand->fact_otp)
|
||||
+ return 0;
|
||||
return spinand_otp_size(spinand, &spinand->fact_otp->layout);
|
||||
}
|
||||
|
||||
@@ -50,6 +52,8 @@ size_t spinand_fact_otp_size(struct spin
|
||||
*/
|
||||
size_t spinand_user_otp_size(struct spinand_device *spinand)
|
||||
{
|
||||
+ if (!spinand->user_otp)
|
||||
+ return 0;
|
||||
return spinand_otp_size(spinand, &spinand->user_otp->layout);
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@
|
||||
+ label = "blue:wan";
|
||||
+ gpios = <&pio 10 GPIO_ACTIVE_LOW>;
|
||||
+ };
|
||||
+
|
||||
+
|
||||
+ led_wan_red {
|
||||
+ label = "red:wan";
|
||||
+ gpios = <&pio 4 GPIO_ACTIVE_LOW>;
|
||||
|
||||
@@ -242,10 +242,10 @@
|
||||
+ };
|
||||
+
|
||||
+ led-green {
|
||||
+ label = "blue:status";
|
||||
+ label = "green:status";
|
||||
+ gpios = <&pio 30 GPIO_ACTIVE_HIGH>;
|
||||
+ };
|
||||
+
|
||||
+
|
||||
+ led-blue {
|
||||
+ label = "blue:status";
|
||||
+ gpios = <&pio 31 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
@@ -0,0 +1,328 @@
|
||||
--- /dev/null
|
||||
+++ b/configs/mt7981_netis_eap930-v1_defconfig
|
||||
@@ -0,0 +1,112 @@
|
||||
+CONFIG_ARM=y
|
||||
+CONFIG_ARM_SMCCC=y
|
||||
+CONFIG_SYS_HAS_NONCACHED_MEMORY=y
|
||||
+CONFIG_POSITION_INDEPENDENT=y
|
||||
+CONFIG_ARCH_MEDIATEK=y
|
||||
+CONFIG_TEXT_BASE=0x41e00000
|
||||
+CONFIG_SYS_MALLOC_F_LEN=0x4000
|
||||
+CONFIG_NR_DRAM_BANKS=1
|
||||
+CONFIG_DEFAULT_DEVICE_TREE="mt7981-netis_eap930-v1"
|
||||
+CONFIG_OF_LIBFDT_OVERLAY=y
|
||||
+CONFIG_TARGET_MT7981=y
|
||||
+CONFIG_SYS_LOAD_ADDR=0x46000000
|
||||
+CONFIG_PRE_CON_BUF_ADDR=0x4007ef00
|
||||
+CONFIG_DEBUG_UART_BASE=0x11002000
|
||||
+CONFIG_DEBUG_UART_CLOCK=40000000
|
||||
+CONFIG_DEBUG_UART=y
|
||||
+CONFIG_FIT=y
|
||||
+CONFIG_BOOTDELAY=30
|
||||
+CONFIG_AUTOBOOT_KEYED=y
|
||||
+CONFIG_AUTOBOOT_MENU_SHOW=y
|
||||
+CONFIG_USE_PREBOOT=y
|
||||
+CONFIG_DEFAULT_FDT_FILE="mediatek/mt7981-netis_eap930-v1.dtb"
|
||||
+CONFIG_LOGLEVEL=7
|
||||
+CONFIG_PRE_CONSOLE_BUFFER=y
|
||||
+CONFIG_LOG=y
|
||||
+# CONFIG_BOARD_INIT is not set
|
||||
+CONFIG_BOARD_LATE_INIT=y
|
||||
+CONFIG_HUSH_PARSER=y
|
||||
+CONFIG_SYS_PROMPT="MT7981> "
|
||||
+CONFIG_CMD_CPU=y
|
||||
+CONFIG_CMD_LICENSE=y
|
||||
+CONFIG_CMD_BOOTMENU=y
|
||||
+CONFIG_CMD_ASKENV=y
|
||||
+CONFIG_CMD_ERASEENV=y
|
||||
+CONFIG_CMD_ENV_FLAGS=y
|
||||
+CONFIG_CMD_RNG=y
|
||||
+CONFIG_CMD_STRINGS=y
|
||||
+CONFIG_CMD_DM=y
|
||||
+CONFIG_CMD_GPIO=y
|
||||
+CONFIG_CMD_GPT=y
|
||||
+CONFIG_CMD_MTD=y
|
||||
+CONFIG_CMD_PART=y
|
||||
+CONFIG_CMD_TFTPSRV=y
|
||||
+CONFIG_CMD_RARP=y
|
||||
+CONFIG_CMD_CDP=y
|
||||
+CONFIG_CMD_SNTP=y
|
||||
+CONFIG_CMD_LINK_LOCAL=y
|
||||
+CONFIG_CMD_DHCP=y
|
||||
+CONFIG_CMD_DNS=y
|
||||
+CONFIG_CMD_PING=y
|
||||
+CONFIG_CMD_PXE=y
|
||||
+CONFIG_CMD_CACHE=y
|
||||
+CONFIG_CMD_PSTORE=y
|
||||
+CONFIG_CMD_PSTORE_MEM_ADDR=0x42ff0000
|
||||
+CONFIG_CMD_UUID=y
|
||||
+CONFIG_CMD_HASH=y
|
||||
+CONFIG_CMD_SMC=y
|
||||
+CONFIG_CMD_UBI=y
|
||||
+CONFIG_CMD_UBI_RENAME=y
|
||||
+CONFIG_OF_EMBED=y
|
||||
+CONFIG_ENV_OVERWRITE=y
|
||||
+CONFIG_ENV_IS_IN_UBI=y
|
||||
+CONFIG_ENV_REDUNDANT=y
|
||||
+CONFIG_ENV_UBI_PART="ubi"
|
||||
+CONFIG_ENV_UBI_VOLUME="ubootenv"
|
||||
+CONFIG_ENV_UBI_VOLUME_REDUND="ubootenv2"
|
||||
+CONFIG_ENV_RELOC_GD_ENV_ADDR=y
|
||||
+CONFIG_ENV_USE_DEFAULT_ENV_TEXT_FILE=y
|
||||
+CONFIG_ENV_DEFAULT_ENV_TEXT_FILE="defenvs/netis_eap930-v1_env"
|
||||
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
|
||||
+CONFIG_VERSION_VARIABLE=y
|
||||
+CONFIG_NETCONSOLE=y
|
||||
+CONFIG_USE_IPADDR=y
|
||||
+CONFIG_IPADDR="192.168.1.1"
|
||||
+CONFIG_USE_SERVERIP=y
|
||||
+CONFIG_SERVERIP="192.168.1.254"
|
||||
+CONFIG_NET_RANDOM_ETHADDR=y
|
||||
+CONFIG_BUTTON=y
|
||||
+CONFIG_BUTTON_GPIO=y
|
||||
+CONFIG_CLK=y
|
||||
+CONFIG_GPIO_HOG=y
|
||||
+CONFIG_LED=y
|
||||
+CONFIG_LED_BLINK=y
|
||||
+CONFIG_LED_GPIO=y
|
||||
+# CONFIG_MMC is not set
|
||||
+CONFIG_MTD=y
|
||||
+CONFIG_DM_MTD=y
|
||||
+CONFIG_MTD_SPI_NAND=y
|
||||
+CONFIG_MTD_UBI_FASTMAP=y
|
||||
+CONFIG_PHY_FIXED=y
|
||||
+CONFIG_MEDIATEK_ETH=y
|
||||
+CONFIG_PHY=y
|
||||
+CONFIG_PHY_MTK_TPHY=y
|
||||
+CONFIG_PINCTRL=y
|
||||
+CONFIG_PINCONF=y
|
||||
+CONFIG_PINCTRL_MT7981=y
|
||||
+CONFIG_POWER_DOMAIN=y
|
||||
+CONFIG_MTK_POWER_DOMAIN=y
|
||||
+CONFIG_DM_REGULATOR=y
|
||||
+CONFIG_DM_REGULATOR_FIXED=y
|
||||
+CONFIG_DM_REGULATOR_GPIO=y
|
||||
+CONFIG_RAM=y
|
||||
+CONFIG_DM_RNG=y
|
||||
+CONFIG_RNG_MTK_V2=y
|
||||
+CONFIG_DM_SERIAL=y
|
||||
+CONFIG_SERIAL_RX_BUFFER=y
|
||||
+CONFIG_MTK_SERIAL=y
|
||||
+CONFIG_SPI=y
|
||||
+CONFIG_DM_SPI=y
|
||||
+CONFIG_MTK_SPIM=y
|
||||
+CONFIG_ZSTD=y
|
||||
+CONFIG_HEXDUMP=y
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/dts/mt7981-netis_eap930-v1.dts
|
||||
@@ -0,0 +1,149 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * Copyright (c) 2026
|
||||
+ * Author: Mikhail Zhilkin <csharper2005@gmail.com>
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+#include "mt7981.dtsi"
|
||||
+#include <dt-bindings/gpio/gpio.h>
|
||||
+#include <dt-bindings/input/linux-event-codes.h>
|
||||
+
|
||||
+/ {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+ model = "netis EAP930 V1";
|
||||
+ compatible = "netis,eap930-v1", "mediatek,mt7981";
|
||||
+
|
||||
+ chosen {
|
||||
+ stdout-path = &uart0;
|
||||
+ tick-timer = &timer0;
|
||||
+ };
|
||||
+
|
||||
+ memory@40000000 {
|
||||
+ device_type = "memory";
|
||||
+ reg = <0x40000000 0x10000000>;
|
||||
+ };
|
||||
+
|
||||
+ keys {
|
||||
+ compatible = "gpio-keys";
|
||||
+
|
||||
+ button-0 {
|
||||
+ label = "reset";
|
||||
+ linux,code = <KEY_RESTART>;
|
||||
+ gpios = <&pio 1 GPIO_ACTIVE_LOW>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ leds {
|
||||
+ compatible = "gpio-leds";
|
||||
+
|
||||
+ led-0 {
|
||||
+ label = "red:system";
|
||||
+ gpios = <&pio 6 GPIO_ACTIVE_LOW>;
|
||||
+ };
|
||||
+
|
||||
+ led-1 {
|
||||
+ label = "blue:system";
|
||||
+ gpios = <&pio 7 GPIO_ACTIVE_LOW>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&uart0 {
|
||||
+ mediatek,force-highspeed;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+ð {
|
||||
+ status = "okay";
|
||||
+ mediatek,gmac-id = <1>;
|
||||
+ phy-mode = "gmii";
|
||||
+ phy-handle = <&int_gbe_phy>;
|
||||
+
|
||||
+ mdio {
|
||||
+ int_gbe_phy: ethernet-phy@0 {
|
||||
+ reg = <0>;
|
||||
+ compatible = "ethernet-phy-ieee802.3-c22";
|
||||
+ phy-mode = "gmii";
|
||||
+ phy-is-integrated;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&pio {
|
||||
+ spi_flash_pins: spi0-pins-func-1 {
|
||||
+ mux {
|
||||
+ function = "flash";
|
||||
+ groups = "spi0", "spi0_wp_hold";
|
||||
+ };
|
||||
+
|
||||
+ conf-pu {
|
||||
+ pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP";
|
||||
+ drive-strength = <MTK_DRIVE_8mA>;
|
||||
+ bias-pull-up = <MTK_PUPD_SET_R1R0_11>;
|
||||
+ };
|
||||
+
|
||||
+ conf-pd {
|
||||
+ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO";
|
||||
+ drive-strength = <MTK_DRIVE_8mA>;
|
||||
+ bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&spi0 {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&spi_flash_pins>;
|
||||
+ status = "okay";
|
||||
+ must_tx;
|
||||
+ enhance_timing;
|
||||
+ dma_ext;
|
||||
+ ipm_design;
|
||||
+ support_quad;
|
||||
+ tick_dly = <2>;
|
||||
+ sample_sel = <0>;
|
||||
+
|
||||
+ spi_nand@0 {
|
||||
+ compatible = "spi-nand";
|
||||
+ reg = <0>;
|
||||
+ spi-max-frequency = <52000000>;
|
||||
+
|
||||
+ partitions {
|
||||
+ compatible = "fixed-partitions";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+
|
||||
+ partition@0 {
|
||||
+ label = "BL2";
|
||||
+ reg = <0x0 0x100000>;
|
||||
+ };
|
||||
+
|
||||
+ partition@100000 {
|
||||
+ label = "u-boot-env";
|
||||
+ reg = <0x100000 0x80000>;
|
||||
+ };
|
||||
+
|
||||
+ partition@180000 {
|
||||
+ label = "Factory";
|
||||
+ reg = <0x180000 0x200000>;
|
||||
+ };
|
||||
+
|
||||
+ partition@380000 {
|
||||
+ label = "FIP";
|
||||
+ reg = <0x380000 0x200000>;
|
||||
+ };
|
||||
+
|
||||
+ partition@580000 {
|
||||
+ label = "ubi";
|
||||
+ reg = <0x580000 0x7a80000>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&watchdog {
|
||||
+ status = "disabled";
|
||||
+};
|
||||
--- /dev/null
|
||||
+++ b/defenvs/netis_eap930-v1_env
|
||||
@@ -0,0 +1,58 @@
|
||||
+ipaddr=192.168.1.1
|
||||
+serverip=192.168.1.254
|
||||
+loadaddr=0x46000000
|
||||
+console=earlycon=uart8250,mmio32,0x11002000 console=ttyS0
|
||||
+bootcmd=run check_buttons ; if pstore check ; then run boot_recovery ; else run boot_ubi ; fi
|
||||
+bootconf=config-1
|
||||
+bootdelay=0
|
||||
+bootfile=immortalwrt-mediatek-filogic-netis_eap930-v1-initramfs-recovery.itb
|
||||
+bootfile_bl2=immortalwrt-mediatek-filogic-netis_eap930-v1-preloader.bin
|
||||
+bootfile_fip=immortalwrt-mediatek-filogic-netis_eap930-v1-bl31-uboot.fip
|
||||
+bootfile_upg=immortalwrt-mediatek-filogic-netis_eap930-v1-squashfs-sysupgrade.itb
|
||||
+bootled_status=red:system
|
||||
+bootmenu_confirm_return=askenv - Press ENTER to return to menu ; bootmenu 60
|
||||
+bootmenu_default=0
|
||||
+bootmenu_delay=0
|
||||
+bootmenu_title= [0;34m( ( ( [1;39mOpenWrt[0;34m ) ) )
|
||||
+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 NAND.=run boot_production ; run bootmenu_confirm_return
|
||||
+bootmenu_3=Boot recovery system from NAND.=run boot_recovery ; run bootmenu_confirm_return
|
||||
+bootmenu_4=Load production system via TFTP then write to NAND.=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 NAND.=setenv noboot 1 ; setenv replacevol 1 ; run boot_tftp_recovery ; setenv noboot ; setenv replacevol ; run bootmenu_confirm_return
|
||||
+bootmenu_6=[31mLoad BL31+U-Boot FIP via TFTP then write to NAND.[0m=run boot_tftp_write_fip ; run bootmenu_confirm_return
|
||||
+bootmenu_7=[31mLoad BL2 preloader via TFTP then write to NAND.[0m=run boot_tftp_write_bl2 ; 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 led $bootled_status on ; 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=led $bootled_status on ; run ubi_read_production && bootm $loadaddr#$bootconf ; led $bootled_status off
|
||||
+boot_recovery=led $bootled_status on ; run ubi_read_recovery && bootm $loadaddr#$bootconf ; led $bootled_status off
|
||||
+boot_ubi=run boot_production ; run boot_recovery ; run boot_tftp_forever
|
||||
+boot_tftp_forever=led $bootled_status on ; while true ; do run boot_tftp ; sleep 1 ; done
|
||||
+boot_tftp_production=tftpboot $loadaddr $bootfile_upg && env exists replacevol && iminfo $loadaddr && run ubi_write_production ; if env exists noboot ; then else bootm $loadaddr#$bootconf ; fi
|
||||
+boot_tftp_recovery=tftpboot $loadaddr $bootfile && env exists replacevol && iminfo $loadaddr && run ubi_write_recovery ; if env exists noboot ; then else bootm $loadaddr#$bootconf ; fi
|
||||
+boot_tftp=tftpboot $loadaddr $bootfile && bootm $loadaddr#$bootconf
|
||||
+boot_tftp_write_fip=tftpboot $loadaddr $bootfile_fip && run mtd_write_fip && run reset_factory
|
||||
+boot_tftp_write_bl2=tftpboot $loadaddr $bootfile_bl2 && run mtd_write_bl2
|
||||
+preboot=led $bootled_status on
|
||||
+check_buttons=if button reset ; then run boot_tftp ; fi
|
||||
+ethaddr_factory=mtd read Factory 0x40080000 0x1e0000 0x20000 && env readmem -b ethaddr 0x4009ef20 0x6 ; setenv ethaddr_factory
|
||||
+part_default=production
|
||||
+part_recovery=recovery
|
||||
+reset_factory=ubi part ubi ; mw $loadaddr 0x0 0x800 ; ubi write $loadaddr ubootenv 0x800 ; ubi write $loadaddr ubootenv2 0x800
|
||||
+mtd_write_fip=mtd erase FIP && mtd write FIP $loadaddr
|
||||
+mtd_write_bl2=mtd erase BL2 && mtd write BL2 $loadaddr
|
||||
+ubi_create_env=ubi check ubootenv || ubi create ubootenv 0x100000 dynamic || run ubi_format ; ubi check ubootenv2 || ubi create ubootenv2 0x100000 dynamic || run ubi_format
|
||||
+ubi_format=ubi detach ; mtd erase ubi && ubi part ubi ; reset
|
||||
+ubi_prepare_rootfs=if ubi check rootfs_data ; then else if env exists rootfs_data_max ; then ubi create rootfs_data $rootfs_data_max dynamic || ubi create rootfs_data - dynamic ; else ubi create rootfs_data - dynamic ; fi ; fi
|
||||
+ubi_read_production=ubi read $loadaddr fit && iminfo $loadaddr && run ubi_prepare_rootfs
|
||||
+ubi_read_recovery=ubi check recovery && ubi read $loadaddr recovery
|
||||
+ubi_remove_rootfs=ubi check rootfs_data && ubi remove rootfs_data
|
||||
+ubi_write_production=ubi check fit && ubi remove fit ; run ubi_remove_rootfs ; ubi create fit $filesize dynamic && ubi write $loadaddr fit $filesize
|
||||
+ubi_write_recovery=ubi check recovery && ubi remove recovery ; run ubi_remove_rootfs ; ubi create recovery $filesize dynamic && ubi write $loadaddr recovery $filesize
|
||||
+_init_env=setenv _init_env ; run ubi_create_env ; saveenv ; saveenv
|
||||
+_firstboot=setenv _firstboot ; run ethaddr_factory ; run _switch_to_menu ; 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 [33m$ver[0m"
|
||||
@@ -167,7 +167,7 @@
|
||||
+/ {
|
||||
+ model = "Zyxel wx5600-T0 ubootmod";
|
||||
+ compatible = "zyxel,wx-5600", "mediatek,mt7986";
|
||||
+
|
||||
+
|
||||
+ options {
|
||||
+ u-boot {
|
||||
+ compatible = "u-boot,config";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/dts/mt7981-globitel-bt-r320.dts
|
||||
@@ -0,0 +1,160 @@
|
||||
@@ -0,0 +1,158 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+
|
||||
+/dts-v1/;
|
||||
@@ -161,7 +161,7 @@
|
||||
+};
|
||||
--- /dev/null
|
||||
+++ b/defenvs/mt7981_globitel_bt-r320_env
|
||||
@@ -0,0 +1,52 @@
|
||||
@@ -0,0 +1,53 @@
|
||||
+ipaddr=192.168.1.1
|
||||
+serverip=192.168.1.254
|
||||
+loadaddr=0x46000000
|
||||
@@ -217,7 +217,7 @@
|
||||
+_bootmenu_update_title=setenv _bootmenu_update_title ; setenv bootmenu_title "$bootmenu_title [33m$ver[0m"
|
||||
--- /dev/null
|
||||
+++ b/configs/mt7981_globitel_bt-r320_defconfig
|
||||
@@ -0,0 +1,126 @@
|
||||
@@ -0,0 +1,128 @@
|
||||
+CONFIG_ARM=y
|
||||
+CONFIG_ARM_SMCCC=y
|
||||
+CONFIG_SYS_HAS_NONCACHED_MEMORY=y
|
||||
|
||||
@@ -165,7 +165,7 @@
|
||||
+ label = "blue:power";
|
||||
+ gpios = <&pio 13 GPIO_ACTIVE_LOW>;
|
||||
+ };
|
||||
+
|
||||
+
|
||||
+ led_warning: led_fault {
|
||||
+ label = "red:fault";
|
||||
+ gpios = <&pio 34 GPIO_ACTIVE_LOW>;
|
||||
|
||||
@@ -41,6 +41,7 @@ livinet,zr-3020-ubootmod|\
|
||||
mercusys,mr90x-v1-ubi|\
|
||||
netcore,n60|\
|
||||
netcore,n60-pro|\
|
||||
netis,eap930-v1|\
|
||||
netis,nx30v2|\
|
||||
netis,nx31|\
|
||||
netis,nx32u|\
|
||||
|
||||
@@ -34,7 +34,8 @@ linksys,e8450-ubi)
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
buffalo,wsr-2533dhp2)
|
||||
buffalo,wsr-2533dhp2|\
|
||||
buffalo,wsr-2533dhp3)
|
||||
ubootenv_add_uci_config "/dev/mtd3" "0x0" "0x1000" "0x20000"
|
||||
;;
|
||||
dlink,eagle-pro-ai-m32-a1|\
|
||||
|
||||
@@ -21,6 +21,9 @@ checkpoint,v-80|\
|
||||
checkpoint,v-81)
|
||||
ubootenv_add_uci_config "/dev/mmcblk1boot0" "0x1f0000" "0x10000"
|
||||
;;
|
||||
cznic,turris-mox)
|
||||
ubootenv_add_uci_config "/dev/mtd2" "0x0" "0x10000" "0x10000"
|
||||
;;
|
||||
cznic,turris-omnia)
|
||||
idx="$(find_mtd_index u-boot-env)"
|
||||
if [ -n "$idx" ]; then
|
||||
|
||||
@@ -500,13 +500,6 @@ static int gpio_keys_button_probe(struct platform_device *pdev,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (button->irq) {
|
||||
dev_err(dev, "skipping button %s (only gpio buttons supported)\n",
|
||||
button->desc);
|
||||
bdata->b = &pdata->buttons[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (gpio_is_valid(button->gpio)) {
|
||||
/* legacy platform data... but is it the lookup table? */
|
||||
bdata->gpiod = devm_gpiod_get_index(dev, desc, i,
|
||||
@@ -541,6 +534,13 @@ static int gpio_keys_button_probe(struct platform_device *pdev,
|
||||
if (IS_ERR_OR_NULL(bdata->gpiod)) {
|
||||
error = IS_ERR(bdata->gpiod) ? PTR_ERR(bdata->gpiod) :
|
||||
-EINVAL;
|
||||
|
||||
if (button->irq && error == -ENOENT) {
|
||||
dev_err(dev, "skipping button %s (only gpio buttons supported)\n",
|
||||
button->desc);
|
||||
continue;
|
||||
}
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -598,6 +598,9 @@ static int gpio_keys_probe(struct platform_device *pdev)
|
||||
struct gpio_keys_button_data *bdata = &bdev->data[i];
|
||||
unsigned long irqflags = IRQF_ONESHOT;
|
||||
|
||||
if (!bdata->gpiod)
|
||||
continue;
|
||||
|
||||
INIT_DELAYED_WORK(&bdata->work, gpio_keys_irq_work_func);
|
||||
|
||||
if (!button->irq) {
|
||||
@@ -662,8 +665,10 @@ static void gpio_keys_irq_close(struct gpio_keys_button_dev *bdev)
|
||||
for (i = 0; i < pdata->nbuttons; i++) {
|
||||
struct gpio_keys_button_data *bdata = &bdev->data[i];
|
||||
|
||||
disable_irq(bdata->irq);
|
||||
cancel_delayed_work_sync(&bdata->work);
|
||||
if (bdata->irq) {
|
||||
disable_irq(bdata->irq);
|
||||
cancel_delayed_work_sync(&bdata->work);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,9 +11,9 @@ PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/iwinfo.git
|
||||
PKG_SOURCE_DATE:=2026-01-14
|
||||
PKG_SOURCE_VERSION:=f5dd57a84cc31a403a1383dd14944fa2e2b5824a
|
||||
PKG_MIRROR_HASH:=a9ed29ea9f222d222fc554238e9c79675e1784293685198f759785da9940571f
|
||||
PKG_SOURCE_DATE:=2026-05-26
|
||||
PKG_SOURCE_VERSION:=66bdd1a071895d91babc9b9228bb84626bbce226
|
||||
PKG_MIRROR_HASH:=e58dab2e33c52b0c217134e81b3ba5376b7a3b57dc1885edf62826573d9f6292
|
||||
PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
|
||||
@@ -235,6 +235,7 @@
|
||||
&gdm4 {
|
||||
status = "okay";
|
||||
|
||||
managed = "in-band-status";
|
||||
phy-handle = <&as21xx_1>;
|
||||
phy-mode = "usxgmii";
|
||||
};
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
From 1d304174106c93ce05f6088813ad7203b3eb381a Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Sat, 12 Oct 2024 11:01:11 +0200
|
||||
Subject: [PATCH] net: airoha: Implement BQL support
|
||||
|
||||
Introduce BQL support in the airoha_eth driver reporting to the kernel
|
||||
info about tx hw DMA queues in order to avoid bufferbloat and keep the
|
||||
latency small.
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://patch.msgid.link/20241012-en7581-bql-v2-1-4deb4efdb60b@kernel.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/airoha_eth.c | 8 ++++++--
|
||||
1 file changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||
@@ -1729,9 +1729,11 @@ static int airoha_qdma_tx_napi_poll(stru
|
||||
WRITE_ONCE(desc->msg1, 0);
|
||||
|
||||
if (skb) {
|
||||
+ u16 queue = skb_get_queue_mapping(skb);
|
||||
struct netdev_queue *txq;
|
||||
|
||||
- txq = netdev_get_tx_queue(skb->dev, qid);
|
||||
+ txq = netdev_get_tx_queue(skb->dev, queue);
|
||||
+ netdev_tx_completed_queue(txq, 1, skb->len);
|
||||
if (netif_tx_queue_stopped(txq) &&
|
||||
q->ndesc - q->queued >= q->free_thr)
|
||||
netif_tx_wake_queue(txq);
|
||||
@@ -2510,7 +2512,9 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
q->queued += i;
|
||||
|
||||
skb_tx_timestamp(skb);
|
||||
- if (!netdev_xmit_more())
|
||||
+ netdev_tx_sent_queue(txq, skb->len);
|
||||
+
|
||||
+ if (netif_xmit_stopped(txq) || !netdev_xmit_more())
|
||||
airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid),
|
||||
TX_RING_CPU_IDX_MASK,
|
||||
FIELD_PREP(TX_RING_CPU_IDX_MASK, q->head));
|
||||
+3
-3
@@ -17,7 +17,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||
@@ -1685,8 +1685,12 @@ static int airoha_qdma_tx_napi_poll(stru
|
||||
@@ -1690,8 +1690,12 @@ static int airoha_qdma_tx_napi_poll(stru
|
||||
irq_queued = FIELD_GET(IRQ_ENTRY_LEN_MASK, status);
|
||||
|
||||
while (irq_queued > 0 && done < budget) {
|
||||
@@ -31,7 +31,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
if (val == 0xff)
|
||||
break;
|
||||
@@ -1696,9 +1700,7 @@ static int airoha_qdma_tx_napi_poll(stru
|
||||
@@ -1701,9 +1705,7 @@ static int airoha_qdma_tx_napi_poll(stru
|
||||
irq_queued--;
|
||||
done++;
|
||||
|
||||
@@ -41,7 +41,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
if (qid >= ARRAY_SIZE(qdma->q_tx))
|
||||
continue;
|
||||
|
||||
@@ -1706,46 +1708,53 @@ static int airoha_qdma_tx_napi_poll(stru
|
||||
@@ -1711,46 +1713,53 @@ static int airoha_qdma_tx_napi_poll(stru
|
||||
if (!q->ndesc)
|
||||
continue;
|
||||
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||
@@ -1805,6 +1805,10 @@ static int airoha_qdma_init_tx_queue(str
|
||||
@@ -1810,6 +1810,10 @@ static int airoha_qdma_init_tx_queue(str
|
||||
WRITE_ONCE(q->desc[i].ctrl, cpu_to_le32(val));
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -29,7 +29,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
#define AIROHA_NUM_TX_RING 32
|
||||
#define AIROHA_NUM_RX_RING 32
|
||||
#define AIROHA_FE_MC_MAX_VLAN_TABLE 64
|
||||
@@ -2437,21 +2439,44 @@ static void airoha_dev_get_stats64(struc
|
||||
@@ -2442,21 +2444,44 @@ static void airoha_dev_get_stats64(struc
|
||||
} while (u64_stats_fetch_retry(&port->stats.syncp, start));
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
if (skb->ip_summed == CHECKSUM_PARTIAL)
|
||||
msg0 |= FIELD_PREP(QDMA_ETH_TXMSG_TCO_MASK, 1) |
|
||||
FIELD_PREP(QDMA_ETH_TXMSG_UCO_MASK, 1) |
|
||||
@@ -2625,6 +2650,7 @@ static const struct net_device_ops airoh
|
||||
@@ -2630,6 +2655,7 @@ static const struct net_device_ops airoh
|
||||
.ndo_init = airoha_dev_init,
|
||||
.ndo_open = airoha_dev_open,
|
||||
.ndo_stop = airoha_dev_stop,
|
||||
|
||||
+5
-5
@@ -100,7 +100,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
};
|
||||
|
||||
struct airoha_eth {
|
||||
@@ -1977,6 +2018,27 @@ static void airoha_qdma_init_qos(struct
|
||||
@@ -1982,6 +2023,27 @@ static void airoha_qdma_init_qos(struct
|
||||
FIELD_PREP(SLA_SLOW_TICK_RATIO_MASK, 40));
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
static int airoha_qdma_hw_init(struct airoha_qdma *qdma)
|
||||
{
|
||||
int i;
|
||||
@@ -2027,6 +2089,7 @@ static int airoha_qdma_hw_init(struct ai
|
||||
@@ -2032,6 +2094,7 @@ static int airoha_qdma_hw_init(struct ai
|
||||
|
||||
airoha_qdma_set(qdma, REG_TXQ_CNGST_CFG,
|
||||
TXQ_CNGST_DROP_EN | TXQ_CNGST_DEI_DROP_EN);
|
||||
@@ -136,7 +136,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2646,6 +2709,135 @@ airoha_ethtool_get_rmon_stats(struct net
|
||||
@@ -2651,6 +2714,135 @@ airoha_ethtool_get_rmon_stats(struct net
|
||||
} while (u64_stats_fetch_retry(&port->stats.syncp, start));
|
||||
}
|
||||
|
||||
@@ -272,7 +272,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
static const struct net_device_ops airoha_netdev_ops = {
|
||||
.ndo_init = airoha_dev_init,
|
||||
.ndo_open = airoha_dev_open,
|
||||
@@ -2654,6 +2846,7 @@ static const struct net_device_ops airoh
|
||||
@@ -2659,6 +2851,7 @@ static const struct net_device_ops airoh
|
||||
.ndo_start_xmit = airoha_dev_xmit,
|
||||
.ndo_get_stats64 = airoha_dev_get_stats64,
|
||||
.ndo_set_mac_address = airoha_dev_set_macaddr,
|
||||
@@ -280,7 +280,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
};
|
||||
|
||||
static const struct ethtool_ops airoha_ethtool_ops = {
|
||||
@@ -2703,7 +2896,8 @@ static int airoha_alloc_gdm_port(struct
|
||||
@@ -2708,7 +2901,8 @@ static int airoha_alloc_gdm_port(struct
|
||||
dev->watchdog_timeo = 5 * HZ;
|
||||
dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
|
||||
NETIF_F_TSO6 | NETIF_F_IPV6_CSUM |
|
||||
|
||||
+4
-4
@@ -94,7 +94,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
/* qos stats counters */
|
||||
u64 cpu_tx_packets;
|
||||
u64 fwd_tx_packets;
|
||||
@@ -2825,6 +2866,243 @@ static int airoha_tc_setup_qdisc_ets(str
|
||||
@@ -2830,6 +2871,243 @@ static int airoha_tc_setup_qdisc_ets(str
|
||||
}
|
||||
}
|
||||
|
||||
@@ -338,7 +338,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
static int airoha_dev_tc_setup(struct net_device *dev, enum tc_setup_type type,
|
||||
void *type_data)
|
||||
{
|
||||
@@ -2833,6 +3111,8 @@ static int airoha_dev_tc_setup(struct ne
|
||||
@@ -2838,6 +3116,8 @@ static int airoha_dev_tc_setup(struct ne
|
||||
switch (type) {
|
||||
case TC_SETUP_QDISC_ETS:
|
||||
return airoha_tc_setup_qdisc_ets(port, type_data);
|
||||
@@ -347,7 +347,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
@@ -2883,7 +3163,8 @@ static int airoha_alloc_gdm_port(struct
|
||||
@@ -2888,7 +3168,8 @@ static int airoha_alloc_gdm_port(struct
|
||||
}
|
||||
|
||||
dev = devm_alloc_etherdev_mqs(eth->dev, sizeof(*port),
|
||||
@@ -357,7 +357,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
if (!dev) {
|
||||
dev_err(eth->dev, "alloc_etherdev failed\n");
|
||||
return -ENOMEM;
|
||||
@@ -2903,6 +3184,11 @@ static int airoha_alloc_gdm_port(struct
|
||||
@@ -2908,6 +3189,11 @@ static int airoha_alloc_gdm_port(struct
|
||||
dev->irq = qdma->irq;
|
||||
SET_NETDEV_DEV(dev, eth->dev);
|
||||
|
||||
|
||||
+2
-2
@@ -20,7 +20,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||
@@ -2801,7 +2801,7 @@ static int airoha_qdma_set_tx_ets_sched(
|
||||
@@ -2806,7 +2806,7 @@ static int airoha_qdma_set_tx_ets_sched(
|
||||
struct tc_ets_qopt_offload_replace_params *p = &opt->replace_params;
|
||||
enum tx_sched_mode mode = TC_SCH_SP;
|
||||
u16 w[AIROHA_NUM_QOS_QUEUES] = {};
|
||||
@@ -29,7 +29,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
if (p->bands > AIROHA_NUM_QOS_QUEUES)
|
||||
return -EINVAL;
|
||||
@@ -2815,7 +2815,20 @@ static int airoha_qdma_set_tx_ets_sched(
|
||||
@@ -2820,7 +2820,20 @@ static int airoha_qdma_set_tx_ets_sched(
|
||||
if (nstrict == AIROHA_NUM_QOS_QUEUES - 1)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
+3
-3
@@ -24,7 +24,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||
@@ -2564,11 +2564,10 @@ static u16 airoha_dev_select_queue(struc
|
||||
@@ -2569,11 +2569,10 @@ static u16 airoha_dev_select_queue(struc
|
||||
static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
|
||||
struct net_device *dev)
|
||||
{
|
||||
@@ -37,7 +37,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
struct netdev_queue *txq;
|
||||
struct airoha_queue *q;
|
||||
void *data = skb->data;
|
||||
@@ -2591,8 +2590,9 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
@@ -2596,8 +2595,9 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
if (skb_cow_head(skb, 0))
|
||||
goto error;
|
||||
|
||||
@@ -49,7 +49,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
tcp_hdr(skb)->check = (__force __sum16)csum;
|
||||
msg0 |= FIELD_PREP(QDMA_ETH_TXMSG_TSO_MASK, 1);
|
||||
@@ -2621,7 +2621,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
@@ -2626,7 +2626,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
for (i = 0; i < nr_frags; i++) {
|
||||
struct airoha_qdma_desc *desc = &q->desc[index];
|
||||
struct airoha_queue_entry *e = &q->entry[index];
|
||||
|
||||
+2
-2
@@ -16,7 +16,7 @@ Signed-off-by: Andrew Lunn <andrew@lunn.ch>
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||
@@ -2484,7 +2484,7 @@ static int airoha_dev_stop(struct net_de
|
||||
@@ -2489,7 +2489,7 @@ static int airoha_dev_stop(struct net_de
|
||||
{
|
||||
struct airoha_gdm_port *port = netdev_priv(dev);
|
||||
struct airoha_qdma *qdma = port->qdma;
|
||||
@@ -25,7 +25,7 @@ Signed-off-by: Andrew Lunn <andrew@lunn.ch>
|
||||
|
||||
netif_tx_disable(dev);
|
||||
err = airoha_set_gdm_ports(qdma->eth, false);
|
||||
@@ -2495,6 +2495,14 @@ static int airoha_dev_stop(struct net_de
|
||||
@@ -2500,6 +2500,14 @@ static int airoha_dev_stop(struct net_de
|
||||
GLOBAL_CFG_TX_DMA_EN_MASK |
|
||||
GLOBAL_CFG_RX_DMA_EN_MASK);
|
||||
|
||||
|
||||
+26
-16
@@ -101,7 +101,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
-obj-$(CONFIG_NET_AIROHA) += airoha_eth.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -0,0 +1,3373 @@
|
||||
@@ -0,0 +1,3378 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+/*
|
||||
+ * Copyright (c) 2024 AIROHA Inc
|
||||
@@ -1763,14 +1763,18 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
+ dma_addr_t dma_addr;
|
||||
+
|
||||
+ q->buf_size = PAGE_SIZE / 2;
|
||||
+ q->ndesc = ndesc;
|
||||
+ q->qdma = qdma;
|
||||
+
|
||||
+ q->entry = devm_kzalloc(eth->dev, q->ndesc * sizeof(*q->entry),
|
||||
+ q->entry = devm_kzalloc(eth->dev, ndesc * sizeof(*q->entry),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!q->entry)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ q->desc = dmam_alloc_coherent(eth->dev, ndesc * sizeof(*q->desc),
|
||||
+ &dma_addr, GFP_KERNEL);
|
||||
+ if (!q->desc)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ q->page_pool = page_pool_create(&pp_params);
|
||||
+ if (IS_ERR(q->page_pool)) {
|
||||
+ int err = PTR_ERR(q->page_pool);
|
||||
@@ -1779,11 +1783,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ q->desc = dmam_alloc_coherent(eth->dev, q->ndesc * sizeof(*q->desc),
|
||||
+ &dma_addr, GFP_KERNEL);
|
||||
+ if (!q->desc)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ q->ndesc = ndesc;
|
||||
+ netif_napi_add(eth->napi_dev, &q->napi, airoha_qdma_rx_napi_poll);
|
||||
+
|
||||
+ airoha_qdma_wr(qdma, REG_RX_RING_BASE(qid), dma_addr);
|
||||
@@ -1830,6 +1830,11 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
+ }
|
||||
+
|
||||
+ q->head = q->tail;
|
||||
+ /* Set RX_DMA_IDX to RX_CPU_IDX to notify the hw the QDMA RX ring is
|
||||
+ * empty.
|
||||
+ */
|
||||
+ airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid), RX_RING_CPU_IDX_MASK,
|
||||
+ FIELD_PREP(RX_RING_CPU_IDX_MASK, q->head));
|
||||
+ airoha_qdma_rmw(qdma, REG_RX_DMA_IDX(qid), RX_RING_DMA_IDX_MASK,
|
||||
+ FIELD_PREP(RX_RING_DMA_IDX_MASK, q->tail));
|
||||
+}
|
||||
@@ -3477,7 +3482,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
+MODULE_DESCRIPTION("Ethernet driver for Airoha SoC");
|
||||
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
|
||||
+++ /dev/null
|
||||
@@ -1,3373 +0,0 @@
|
||||
@@ -1,3378 +0,0 @@
|
||||
-// SPDX-License-Identifier: GPL-2.0-only
|
||||
-/*
|
||||
- * Copyright (c) 2024 AIROHA Inc
|
||||
@@ -5139,14 +5144,18 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
- dma_addr_t dma_addr;
|
||||
-
|
||||
- q->buf_size = PAGE_SIZE / 2;
|
||||
- q->ndesc = ndesc;
|
||||
- q->qdma = qdma;
|
||||
-
|
||||
- q->entry = devm_kzalloc(eth->dev, q->ndesc * sizeof(*q->entry),
|
||||
- q->entry = devm_kzalloc(eth->dev, ndesc * sizeof(*q->entry),
|
||||
- GFP_KERNEL);
|
||||
- if (!q->entry)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- q->desc = dmam_alloc_coherent(eth->dev, ndesc * sizeof(*q->desc),
|
||||
- &dma_addr, GFP_KERNEL);
|
||||
- if (!q->desc)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- q->page_pool = page_pool_create(&pp_params);
|
||||
- if (IS_ERR(q->page_pool)) {
|
||||
- int err = PTR_ERR(q->page_pool);
|
||||
@@ -5155,11 +5164,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
- return err;
|
||||
- }
|
||||
-
|
||||
- q->desc = dmam_alloc_coherent(eth->dev, q->ndesc * sizeof(*q->desc),
|
||||
- &dma_addr, GFP_KERNEL);
|
||||
- if (!q->desc)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- q->ndesc = ndesc;
|
||||
- netif_napi_add(eth->napi_dev, &q->napi, airoha_qdma_rx_napi_poll);
|
||||
-
|
||||
- airoha_qdma_wr(qdma, REG_RX_RING_BASE(qid), dma_addr);
|
||||
@@ -5206,6 +5211,11 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
- }
|
||||
-
|
||||
- q->head = q->tail;
|
||||
- /* Set RX_DMA_IDX to RX_CPU_IDX to notify the hw the QDMA RX ring is
|
||||
- * empty.
|
||||
- */
|
||||
- airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid), RX_RING_CPU_IDX_MASK,
|
||||
- FIELD_PREP(RX_RING_CPU_IDX_MASK, q->head));
|
||||
- airoha_qdma_rmw(qdma, REG_RX_DMA_IDX(qid), RX_RING_DMA_IDX_MASK,
|
||||
- FIELD_PREP(RX_RING_DMA_IDX_MASK, q->tail));
|
||||
-}
|
||||
|
||||
+7
-7
@@ -74,7 +74,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
napi_gro_receive(&q->napi, skb);
|
||||
|
||||
done++;
|
||||
@@ -1652,25 +1671,76 @@ static u16 airoha_dev_select_queue(struc
|
||||
@@ -1657,25 +1676,76 @@ static u16 airoha_dev_select_queue(struc
|
||||
return queue < dev->num_tx_queues ? queue : 0;
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
if (skb->ip_summed == CHECKSUM_PARTIAL)
|
||||
msg0 |= FIELD_PREP(QDMA_ETH_TXMSG_TCO_MASK, 1) |
|
||||
FIELD_PREP(QDMA_ETH_TXMSG_UCO_MASK, 1) |
|
||||
@@ -1701,6 +1771,8 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
@@ -1706,6 +1776,8 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
spin_lock_bh(&q->lock);
|
||||
|
||||
txq = netdev_get_tx_queue(dev, qid);
|
||||
@@ -164,7 +164,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
if (q->queued + nr_frags > q->ndesc) {
|
||||
/* not enough space in the queue */
|
||||
netif_tx_stop_queue(txq);
|
||||
@@ -1708,7 +1780,10 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
@@ -1713,7 +1785,10 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
|
||||
@@ -175,7 +175,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
for (i = 0; i < nr_frags; i++) {
|
||||
struct airoha_qdma_desc *desc = &q->desc[index];
|
||||
struct airoha_queue_entry *e = &q->entry[index];
|
||||
@@ -2239,6 +2314,37 @@ static const struct ethtool_ops airoha_e
|
||||
@@ -2244,6 +2319,37 @@ static const struct ethtool_ops airoha_e
|
||||
.get_rmon_stats = airoha_ethtool_get_rmon_stats,
|
||||
};
|
||||
|
||||
@@ -213,7 +213,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
static int airoha_alloc_gdm_port(struct airoha_eth *eth, struct device_node *np)
|
||||
{
|
||||
const __be32 *id_ptr = of_get_property(np, "reg", NULL);
|
||||
@@ -2311,6 +2417,10 @@ static int airoha_alloc_gdm_port(struct
|
||||
@@ -2316,6 +2422,10 @@ static int airoha_alloc_gdm_port(struct
|
||||
port->id = id;
|
||||
eth->ports[index] = port;
|
||||
|
||||
@@ -224,7 +224,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
return register_netdev(dev);
|
||||
}
|
||||
|
||||
@@ -2403,8 +2513,10 @@ error_hw_cleanup:
|
||||
@@ -2408,8 +2518,10 @@ error_hw_cleanup:
|
||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
struct airoha_gdm_port *port = eth->ports[i];
|
||||
|
||||
@@ -236,7 +236,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
}
|
||||
free_netdev(eth->napi_dev);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
@@ -2429,6 +2541,7 @@ static void airoha_remove(struct platfor
|
||||
@@ -2434,6 +2546,7 @@ static void airoha_remove(struct platfor
|
||||
continue;
|
||||
|
||||
unregister_netdev(port->dev);
|
||||
|
||||
+7
-7
@@ -25,7 +25,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1578,6 +1578,7 @@ static int airoha_dev_open(struct net_de
|
||||
@@ -1583,6 +1583,7 @@ static int airoha_dev_open(struct net_de
|
||||
airoha_qdma_set(qdma, REG_QDMA_GLOBAL_CFG,
|
||||
GLOBAL_CFG_TX_DMA_EN_MASK |
|
||||
GLOBAL_CFG_RX_DMA_EN_MASK);
|
||||
@@ -33,7 +33,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1593,16 +1594,20 @@ static int airoha_dev_stop(struct net_de
|
||||
@@ -1598,16 +1599,20 @@ static int airoha_dev_stop(struct net_de
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -62,7 +62,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -2345,13 +2350,14 @@ static void airoha_metadata_dst_free(str
|
||||
@@ -2350,13 +2355,14 @@ static void airoha_metadata_dst_free(str
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
u32 id;
|
||||
|
||||
if (!id_ptr) {
|
||||
@@ -2360,14 +2366,14 @@ static int airoha_alloc_gdm_port(struct
|
||||
@@ -2365,14 +2371,14 @@ static int airoha_alloc_gdm_port(struct
|
||||
}
|
||||
|
||||
id = be32_to_cpup(id_ptr);
|
||||
@@ -96,7 +96,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
dev_err(eth->dev, "duplicate gdm port id: %d\n", id);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -2415,7 +2421,7 @@ static int airoha_alloc_gdm_port(struct
|
||||
@@ -2420,7 +2426,7 @@ static int airoha_alloc_gdm_port(struct
|
||||
port->qdma = qdma;
|
||||
port->dev = dev;
|
||||
port->id = id;
|
||||
@@ -105,7 +105,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
|
||||
err = airoha_metadata_dst_alloc(port);
|
||||
if (err)
|
||||
@@ -2487,6 +2493,7 @@ static int airoha_probe(struct platform_
|
||||
@@ -2492,6 +2498,7 @@ static int airoha_probe(struct platform_
|
||||
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
|
||||
airoha_qdma_start_napi(ð->qdma[i]);
|
||||
|
||||
@@ -113,7 +113,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
for_each_child_of_node(pdev->dev.of_node, np) {
|
||||
if (!of_device_is_compatible(np, "airoha,eth-mac"))
|
||||
continue;
|
||||
@@ -2494,7 +2501,7 @@ static int airoha_probe(struct platform_
|
||||
@@ -2499,7 +2506,7 @@ static int airoha_probe(struct platform_
|
||||
if (!of_device_is_available(np))
|
||||
continue;
|
||||
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
airoha_fe_rmw(eth, REG_GDM_LEN_CFG(p),
|
||||
GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK,
|
||||
FIELD_PREP(GDM_SHORT_LEN_MASK, 60) |
|
||||
@@ -1630,8 +1621,11 @@ static int airoha_dev_set_macaddr(struct
|
||||
@@ -1635,8 +1626,11 @@ static int airoha_dev_set_macaddr(struct
|
||||
static int airoha_dev_init(struct net_device *dev)
|
||||
{
|
||||
struct airoha_gdm_port *port = netdev_priv(dev);
|
||||
|
||||
+2
-2
@@ -83,7 +83,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
static void airoha_fe_maccr_init(struct airoha_eth *eth)
|
||||
{
|
||||
int p;
|
||||
@@ -1555,7 +1528,7 @@ static int airoha_dev_open(struct net_de
|
||||
@@ -1560,7 +1533,7 @@ static int airoha_dev_open(struct net_de
|
||||
int err;
|
||||
|
||||
netif_tx_start_all_queues(dev);
|
||||
@@ -92,7 +92,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -1581,7 +1554,7 @@ static int airoha_dev_stop(struct net_de
|
||||
@@ -1586,7 +1559,7 @@ static int airoha_dev_stop(struct net_de
|
||||
int i, err;
|
||||
|
||||
netif_tx_disable(dev);
|
||||
|
||||
+4
-4
@@ -76,7 +76,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
napi_gro_receive(&q->napi, skb);
|
||||
|
||||
done++;
|
||||
@@ -1317,6 +1326,10 @@ static int airoha_hw_init(struct platfor
|
||||
@@ -1322,6 +1331,10 @@ static int airoha_hw_init(struct platfor
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
set_bit(DEV_STATE_INITIALIZED, ð->state);
|
||||
|
||||
return 0;
|
||||
@@ -2181,6 +2194,47 @@ static int airoha_tc_htb_alloc_leaf_queu
|
||||
@@ -2186,6 +2199,47 @@ static int airoha_tc_htb_alloc_leaf_queu
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
static void airoha_tc_remove_htb_queue(struct airoha_gdm_port *port, int queue)
|
||||
{
|
||||
struct net_device *dev = port->dev;
|
||||
@@ -2264,6 +2318,9 @@ static int airoha_dev_tc_setup(struct ne
|
||||
@@ -2269,6 +2323,9 @@ static int airoha_dev_tc_setup(struct ne
|
||||
return airoha_tc_setup_qdisc_ets(port, type_data);
|
||||
case TC_SETUP_QDISC_HTB:
|
||||
return airoha_tc_setup_qdisc_htb(port, type_data);
|
||||
@@ -145,7 +145,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
@@ -2519,6 +2576,7 @@ static void airoha_remove(struct platfor
|
||||
@@ -2524,6 +2581,7 @@ static void airoha_remove(struct platfor
|
||||
}
|
||||
free_netdev(eth->napi_dev);
|
||||
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1604,14 +1604,81 @@ static int airoha_dev_set_macaddr(struct
|
||||
@@ -1609,14 +1609,81 @@ static int airoha_dev_set_macaddr(struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -34,7 +34,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
airoha_fe_rmw(eth, REG_CDM1_VLAN_CTRL, CDM1_VLAN_MASK,
|
||||
FIELD_PREP(CDM1_VLAN_MASK, 0x8100));
|
||||
@@ -1536,9 +1531,9 @@ static void airoha_update_hw_stats(struc
|
||||
@@ -1541,9 +1536,9 @@ static void airoha_update_hw_stats(struc
|
||||
|
||||
static int airoha_dev_open(struct net_device *dev)
|
||||
{
|
||||
@@ -45,7 +45,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
netif_tx_start_all_queues(dev);
|
||||
err = airoha_set_vip_for_gdm_port(port, true);
|
||||
@@ -1552,6 +1547,11 @@ static int airoha_dev_open(struct net_de
|
||||
@@ -1557,6 +1552,11 @@ static int airoha_dev_open(struct net_de
|
||||
airoha_fe_clear(qdma->eth, REG_GDM_INGRESS_CFG(port->id),
|
||||
GDM_STAG_EN_MASK);
|
||||
|
||||
|
||||
+1
-1
@@ -132,7 +132,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
airoha_qdma_fill_rx_queue(q);
|
||||
|
||||
@@ -1177,7 +1194,6 @@ static int airoha_qdma_hw_init(struct ai
|
||||
@@ -1182,7 +1199,6 @@ static int airoha_qdma_hw_init(struct ai
|
||||
}
|
||||
|
||||
airoha_qdma_wr(qdma, REG_QDMA_GLOBAL_CFG,
|
||||
|
||||
+2
-2
@@ -16,7 +16,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1721,6 +1721,20 @@ static void airoha_dev_get_stats64(struc
|
||||
@@ -1726,6 +1726,20 @@ static void airoha_dev_get_stats64(struc
|
||||
} while (u64_stats_fetch_retry(&port->stats.syncp, start));
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
static u16 airoha_dev_select_queue(struct net_device *dev, struct sk_buff *skb,
|
||||
struct net_device *sb_dev)
|
||||
{
|
||||
@@ -2413,6 +2427,7 @@ static const struct net_device_ops airoh
|
||||
@@ -2418,6 +2432,7 @@ static const struct net_device_ops airoh
|
||||
.ndo_init = airoha_dev_init,
|
||||
.ndo_open = airoha_dev_open,
|
||||
.ndo_stop = airoha_dev_stop,
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -2518,6 +2518,7 @@ static int airoha_alloc_gdm_port(struct
|
||||
@@ -2523,6 +2523,7 @@ static int airoha_alloc_gdm_port(struct
|
||||
NETIF_F_SG | NETIF_F_TSO |
|
||||
NETIF_F_HW_TC;
|
||||
dev->features |= dev->hw_features;
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1757,18 +1757,13 @@ static u32 airoha_get_dsa_tag(struct sk_
|
||||
@@ -1762,18 +1762,13 @@ static u32 airoha_get_dsa_tag(struct sk_
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_NET_DSA)
|
||||
struct ethhdr *ehdr;
|
||||
|
||||
+1
-1
@@ -66,7 +66,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -2371,7 +2371,7 @@ static int airoha_tc_get_htb_get_leaf_qu
|
||||
@@ -2376,7 +2376,7 @@ static int airoha_tc_get_htb_get_leaf_qu
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -22,7 +22,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -2044,7 +2044,7 @@ static int airoha_qdma_set_tx_ets_sched(
|
||||
@@ -2049,7 +2049,7 @@ static int airoha_qdma_set_tx_ets_sched(
|
||||
struct tc_ets_qopt_offload_replace_params *p = &opt->replace_params;
|
||||
enum tx_sched_mode mode = TC_SCH_SP;
|
||||
u16 w[AIROHA_NUM_QOS_QUEUES] = {};
|
||||
@@ -31,7 +31,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
if (p->bands > AIROHA_NUM_QOS_QUEUES)
|
||||
return -EINVAL;
|
||||
@@ -2062,17 +2062,17 @@ static int airoha_qdma_set_tx_ets_sched(
|
||||
@@ -2067,17 +2067,17 @@ static int airoha_qdma_set_tx_ets_sched(
|
||||
* lowest priorities with respect to SP ones.
|
||||
* e.g: WRR0, WRR1, .., WRRm, SP0, SP1, .., SPn
|
||||
*/
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -2467,6 +2467,19 @@ static void airoha_metadata_dst_free(str
|
||||
@@ -2472,6 +2472,19 @@ static void airoha_metadata_dst_free(str
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -55,7 +55,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
/* enable 1:N vlan action, init vlan table */
|
||||
airoha_fe_set(eth, REG_MC_VLAN_EN, MC_VLAN_EN_MASK);
|
||||
|
||||
@@ -1647,7 +1666,6 @@ static void airhoha_set_gdm2_loopback(st
|
||||
@@ -1652,7 +1671,6 @@ static void airhoha_set_gdm2_loopback(st
|
||||
|
||||
if (port->id == 3) {
|
||||
/* FIXME: handle XSI_PCE1_PORT */
|
||||
@@ -63,7 +63,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
airoha_fe_rmw(eth, REG_FE_WAN_PORT,
|
||||
WAN1_EN_MASK | WAN1_MASK | WAN0_MASK,
|
||||
FIELD_PREP(WAN0_MASK, HSGMII_LAN_PCIE0_SRCPORT));
|
||||
@@ -2122,6 +2140,125 @@ static int airoha_tc_setup_qdisc_ets(str
|
||||
@@ -2127,6 +2145,125 @@ static int airoha_tc_setup_qdisc_ets(str
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
static int airoha_qdma_get_trtcm_param(struct airoha_qdma *qdma, int channel,
|
||||
u32 addr, enum trtcm_param_type param,
|
||||
enum trtcm_mode_type mode,
|
||||
@@ -2286,10 +2423,142 @@ static int airoha_tc_htb_alloc_leaf_queu
|
||||
@@ -2291,10 +2428,142 @@ static int airoha_tc_htb_alloc_leaf_queu
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+9
-9
@@ -93,7 +93,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
RX_DONE_INT_MASK);
|
||||
|
||||
return done;
|
||||
@@ -960,7 +964,7 @@ unlock:
|
||||
@@ -965,7 +969,7 @@ unlock:
|
||||
}
|
||||
|
||||
if (done < budget && napi_complete(napi))
|
||||
@@ -102,7 +102,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
TX_DONE_INT_MASK(id));
|
||||
|
||||
return done;
|
||||
@@ -1191,13 +1195,16 @@ static int airoha_qdma_hw_init(struct ai
|
||||
@@ -1196,13 +1200,16 @@ static int airoha_qdma_hw_init(struct ai
|
||||
int i;
|
||||
|
||||
/* clear pending irqs */
|
||||
@@ -123,7 +123,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
/* setup irq binding */
|
||||
for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
|
||||
@@ -1242,13 +1249,14 @@ static int airoha_qdma_hw_init(struct ai
|
||||
@@ -1247,13 +1254,14 @@ static int airoha_qdma_hw_init(struct ai
|
||||
|
||||
static irqreturn_t airoha_irq_handler(int irq, void *dev_instance)
|
||||
{
|
||||
@@ -142,7 +142,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
airoha_qdma_wr(qdma, REG_INT_STATUS(i), intr[i]);
|
||||
}
|
||||
|
||||
@@ -1256,7 +1264,7 @@ static irqreturn_t airoha_irq_handler(in
|
||||
@@ -1261,7 +1269,7 @@ static irqreturn_t airoha_irq_handler(in
|
||||
return IRQ_NONE;
|
||||
|
||||
if (intr[1] & RX_DONE_INT_MASK) {
|
||||
@@ -151,7 +151,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
RX_DONE_INT_MASK);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
|
||||
@@ -1273,7 +1281,7 @@ static irqreturn_t airoha_irq_handler(in
|
||||
@@ -1278,7 +1286,7 @@ static irqreturn_t airoha_irq_handler(in
|
||||
if (!(intr[0] & TX_DONE_INT_MASK(i)))
|
||||
continue;
|
||||
|
||||
@@ -160,7 +160,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
TX_DONE_INT_MASK(i));
|
||||
napi_schedule(&qdma->q_tx_irq[i].napi);
|
||||
}
|
||||
@@ -1282,6 +1290,39 @@ static irqreturn_t airoha_irq_handler(in
|
||||
@@ -1287,6 +1295,39 @@ static irqreturn_t airoha_irq_handler(in
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
static int airoha_qdma_init(struct platform_device *pdev,
|
||||
struct airoha_eth *eth,
|
||||
struct airoha_qdma *qdma)
|
||||
@@ -1289,9 +1330,7 @@ static int airoha_qdma_init(struct platf
|
||||
@@ -1294,9 +1335,7 @@ static int airoha_qdma_init(struct platf
|
||||
int err, id = qdma - ð->qdma[0];
|
||||
const char *res;
|
||||
|
||||
@@ -210,7 +210,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
res = devm_kasprintf(eth->dev, GFP_KERNEL, "qdma%d", id);
|
||||
if (!res)
|
||||
return -ENOMEM;
|
||||
@@ -1301,12 +1340,7 @@ static int airoha_qdma_init(struct platf
|
||||
@@ -1306,12 +1345,7 @@ static int airoha_qdma_init(struct platf
|
||||
return dev_err_probe(eth->dev, PTR_ERR(qdma->regs),
|
||||
"failed to iomap qdma%d regs\n", id);
|
||||
|
||||
@@ -224,7 +224,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -2797,7 +2831,7 @@ static int airoha_alloc_gdm_port(struct
|
||||
@@ -2802,7 +2836,7 @@ static int airoha_alloc_gdm_port(struct
|
||||
dev->features |= dev->hw_features;
|
||||
dev->vlan_features = dev->hw_features;
|
||||
dev->dev.of_node = np;
|
||||
|
||||
+3
-3
@@ -58,7 +58,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
return done;
|
||||
}
|
||||
@@ -1194,17 +1204,24 @@ static int airoha_qdma_hw_init(struct ai
|
||||
@@ -1199,17 +1209,24 @@ static int airoha_qdma_hw_init(struct ai
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -91,7 +91,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
/* setup irq binding */
|
||||
for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
|
||||
@@ -1251,6 +1268,7 @@ static irqreturn_t airoha_irq_handler(in
|
||||
@@ -1256,6 +1273,7 @@ static irqreturn_t airoha_irq_handler(in
|
||||
{
|
||||
struct airoha_irq_bank *irq_bank = dev_instance;
|
||||
struct airoha_qdma *qdma = irq_bank->qdma;
|
||||
@@ -99,7 +99,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
u32 intr[ARRAY_SIZE(irq_bank->irqmask)];
|
||||
int i;
|
||||
|
||||
@@ -1263,17 +1281,24 @@ static irqreturn_t airoha_irq_handler(in
|
||||
@@ -1268,17 +1286,24 @@ static irqreturn_t airoha_irq_handler(in
|
||||
if (!test_bit(DEV_STATE_INITIALIZED, &qdma->eth->state))
|
||||
return IRQ_NONE;
|
||||
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1093,17 +1093,13 @@ static int airoha_qdma_init_hfwd_queues(
|
||||
@@ -1098,17 +1098,13 @@ static int airoha_qdma_init_hfwd_queues(
|
||||
int size;
|
||||
|
||||
size = HW_DSCP_NUM * sizeof(struct airoha_qdma_fwd_desc);
|
||||
|
||||
+2
-2
@@ -27,7 +27,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/u64_stats_sync.h>
|
||||
@@ -1088,9 +1089,11 @@ static void airoha_qdma_cleanup_tx_queue
|
||||
@@ -1093,9 +1094,11 @@ static void airoha_qdma_cleanup_tx_queue
|
||||
static int airoha_qdma_init_hfwd_queues(struct airoha_qdma *qdma)
|
||||
{
|
||||
struct airoha_eth *eth = qdma->eth;
|
||||
@@ -40,7 +40,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
|
||||
size = HW_DSCP_NUM * sizeof(struct airoha_qdma_fwd_desc);
|
||||
if (!dmam_alloc_coherent(eth->dev, size, &dma_addr, GFP_KERNEL))
|
||||
@@ -1098,10 +1101,34 @@ static int airoha_qdma_init_hfwd_queues(
|
||||
@@ -1103,10 +1106,34 @@ static int airoha_qdma_init_hfwd_queues(
|
||||
|
||||
airoha_qdma_wr(qdma, REG_FWD_DSCP_BASE, dma_addr);
|
||||
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr)
|
||||
{
|
||||
struct airoha_eth *eth = port->qdma->eth;
|
||||
@@ -1140,7 +1131,7 @@ static int airoha_qdma_init_hfwd_queues(
|
||||
@@ -1145,7 +1136,7 @@ static int airoha_qdma_init_hfwd_queues(
|
||||
LMGR_INIT_START | LMGR_SRAM_MODE_MASK |
|
||||
HW_FWD_DESC_NUM_MASK,
|
||||
FIELD_PREP(HW_FWD_DESC_NUM_MASK, HW_DSCP_NUM) |
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -2896,7 +2896,15 @@ static int airoha_alloc_gdm_port(struct
|
||||
@@ -2901,7 +2901,15 @@ static int airoha_alloc_gdm_port(struct
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
||||
+4
-4
@@ -19,7 +19,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1081,19 +1081,13 @@ static void airoha_qdma_cleanup_tx_queue
|
||||
@@ -1086,19 +1086,13 @@ static void airoha_qdma_cleanup_tx_queue
|
||||
|
||||
static int airoha_qdma_init_hfwd_queues(struct airoha_qdma *qdma)
|
||||
{
|
||||
@@ -40,7 +40,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
name = devm_kasprintf(eth->dev, GFP_KERNEL, "qdma%d-buf", id);
|
||||
if (!name)
|
||||
return -ENOMEM;
|
||||
@@ -1115,8 +1109,12 @@ static int airoha_qdma_init_hfwd_queues(
|
||||
@@ -1120,8 +1114,12 @@ static int airoha_qdma_init_hfwd_queues(
|
||||
rmem = of_reserved_mem_lookup(np);
|
||||
of_node_put(np);
|
||||
dma_addr = rmem->base;
|
||||
@@ -54,7 +54,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
if (!dmam_alloc_coherent(eth->dev, size, &dma_addr,
|
||||
GFP_KERNEL))
|
||||
return -ENOMEM;
|
||||
@@ -1124,6 +1122,11 @@ static int airoha_qdma_init_hfwd_queues(
|
||||
@@ -1129,6 +1127,11 @@ static int airoha_qdma_init_hfwd_queues(
|
||||
|
||||
airoha_qdma_wr(qdma, REG_FWD_BUF_BASE, dma_addr);
|
||||
|
||||
@@ -66,7 +66,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
airoha_qdma_rmw(qdma, REG_HW_FWD_DSCP_CFG,
|
||||
HW_FWD_DSCP_PAYLOAD_SIZE_MASK,
|
||||
FIELD_PREP(HW_FWD_DSCP_PAYLOAD_SIZE_MASK, 0));
|
||||
@@ -1132,7 +1135,7 @@ static int airoha_qdma_init_hfwd_queues(
|
||||
@@ -1137,7 +1140,7 @@ static int airoha_qdma_init_hfwd_queues(
|
||||
airoha_qdma_rmw(qdma, REG_LMGR_INIT_CFG,
|
||||
LMGR_INIT_START | LMGR_SRAM_MODE_MASK |
|
||||
HW_FWD_DESC_NUM_MASK,
|
||||
|
||||
+3
-3
@@ -21,7 +21,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1084,14 +1084,15 @@ static int airoha_qdma_init_hfwd_queues(
|
||||
@@ -1089,14 +1089,15 @@ static int airoha_qdma_init_hfwd_queues(
|
||||
int size, index, num_desc = HW_DSCP_NUM;
|
||||
struct airoha_eth *eth = qdma->eth;
|
||||
int id = qdma - ð->qdma[0];
|
||||
@@ -38,7 +38,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
index = of_property_match_string(eth->dev->of_node,
|
||||
"memory-region-names", name);
|
||||
if (index >= 0) {
|
||||
@@ -1112,9 +1113,9 @@ static int airoha_qdma_init_hfwd_queues(
|
||||
@@ -1117,9 +1118,9 @@ static int airoha_qdma_init_hfwd_queues(
|
||||
/* Compute the number of hw descriptors according to the
|
||||
* reserved memory size and the payload buffer size
|
||||
*/
|
||||
@@ -50,7 +50,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
if (!dmam_alloc_coherent(eth->dev, size, &dma_addr,
|
||||
GFP_KERNEL))
|
||||
return -ENOMEM;
|
||||
@@ -1127,9 +1128,10 @@ static int airoha_qdma_init_hfwd_queues(
|
||||
@@ -1132,9 +1133,10 @@ static int airoha_qdma_init_hfwd_queues(
|
||||
return -ENOMEM;
|
||||
|
||||
airoha_qdma_wr(qdma, REG_FWD_DSCP_BASE, dma_addr);
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -2617,13 +2617,15 @@ static int airoha_dev_setup_tc_block_cb(
|
||||
@@ -2622,13 +2622,15 @@ static int airoha_dev_setup_tc_block_cb(
|
||||
void *type_data, void *cb_priv)
|
||||
{
|
||||
struct net_device *dev = cb_priv;
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -2199,11 +2199,14 @@ static int airoha_qdma_get_tx_ets_stats(
|
||||
@@ -2204,11 +2204,14 @@ static int airoha_qdma_get_tx_ets_stats(
|
||||
static int airoha_tc_setup_qdisc_ets(struct airoha_gdm_port *port,
|
||||
struct tc_ets_qopt_offload *opt)
|
||||
{
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1731,7 +1731,9 @@ static void airhoha_set_gdm2_loopback(st
|
||||
@@ -1736,7 +1736,9 @@ static void airhoha_set_gdm2_loopback(st
|
||||
airoha_fe_wr(eth, REG_GDM_RXCHN_EN(2), 0xffff);
|
||||
airoha_fe_rmw(eth, REG_GDM_LPBK_CFG(2),
|
||||
LPBK_CHAN_MASK | LPBK_MODE_MASK | LPBK_EN_MASK,
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -2043,8 +2043,12 @@ static void airoha_ethtool_get_mac_stats
|
||||
@@ -2048,8 +2048,12 @@ static void airoha_ethtool_get_mac_stats
|
||||
airoha_update_hw_stats(port);
|
||||
do {
|
||||
start = u64_stats_fetch_begin(&port->stats.syncp);
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -2791,6 +2791,7 @@ static const struct ethtool_ops airoha_e
|
||||
@@ -2796,6 +2796,7 @@ static const struct ethtool_ops airoha_e
|
||||
.get_drvinfo = airoha_ethtool_get_drvinfo,
|
||||
.get_eth_mac_stats = airoha_ethtool_get_mac_stats,
|
||||
.get_rmon_stats = airoha_ethtool_get_rmon_stats,
|
||||
|
||||
+2
-2
@@ -22,7 +22,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1894,6 +1894,20 @@ static u32 airoha_get_dsa_tag(struct sk_
|
||||
@@ -1899,6 +1899,20 @@ static u32 airoha_get_dsa_tag(struct sk_
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
|
||||
struct net_device *dev)
|
||||
{
|
||||
@@ -1947,7 +1961,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
@@ -1952,7 +1966,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
txq = netdev_get_tx_queue(dev, qid);
|
||||
nr_frags = 1 + skb_shinfo(skb)->nr_frags;
|
||||
|
||||
|
||||
+5
-5
@@ -21,7 +21,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1408,8 +1408,7 @@ static int airoha_hw_init(struct platfor
|
||||
@@ -1413,8 +1413,7 @@ static int airoha_hw_init(struct platfor
|
||||
int err, i;
|
||||
|
||||
/* disable xsi */
|
||||
@@ -31,7 +31,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -2943,6 +2942,7 @@ free_metadata_dst:
|
||||
@@ -2948,6 +2947,7 @@ free_metadata_dst:
|
||||
|
||||
static int airoha_probe(struct platform_device *pdev)
|
||||
{
|
||||
@@ -39,7 +39,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
struct device_node *np;
|
||||
struct airoha_eth *eth;
|
||||
int i, err;
|
||||
@@ -2951,6 +2951,10 @@ static int airoha_probe(struct platform_
|
||||
@@ -2956,6 +2956,10 @@ static int airoha_probe(struct platform_
|
||||
if (!eth)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -50,7 +50,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
eth->dev = &pdev->dev;
|
||||
|
||||
err = dma_set_mask_and_coherent(eth->dev, DMA_BIT_MASK(32));
|
||||
@@ -2975,13 +2979,18 @@ static int airoha_probe(struct platform_
|
||||
@@ -2980,13 +2984,18 @@ static int airoha_probe(struct platform_
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
eth->xsi_rsts);
|
||||
if (err) {
|
||||
dev_err(eth->dev, "failed to get bulk xsi reset lines\n");
|
||||
@@ -3067,8 +3076,23 @@ static void airoha_remove(struct platfor
|
||||
@@ -3072,8 +3081,23 @@ static void airoha_remove(struct platfor
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
}
|
||||
/* GMD4 */
|
||||
for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_GDM4]; q++)
|
||||
@@ -1783,8 +1790,11 @@ static int airoha_dev_init(struct net_de
|
||||
@@ -1788,8 +1795,11 @@ static int airoha_dev_init(struct net_de
|
||||
airhoha_set_gdm2_loopback(port);
|
||||
fallthrough;
|
||||
case 2:
|
||||
|
||||
+2
-2
@@ -47,7 +47,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
/* enable 1:N vlan action, init vlan table */
|
||||
airoha_fe_set(eth, REG_MC_VLAN_EN, MC_VLAN_EN_MASK);
|
||||
|
||||
@@ -1777,8 +1758,10 @@ static void airhoha_set_gdm2_loopback(st
|
||||
@@ -1782,8 +1763,10 @@ static void airhoha_set_gdm2_loopback(st
|
||||
static int airoha_dev_init(struct net_device *dev)
|
||||
{
|
||||
struct airoha_gdm_port *port = netdev_priv(dev);
|
||||
@@ -60,7 +60,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
|
||||
airoha_set_macaddr(port, dev->dev_addr);
|
||||
|
||||
@@ -1791,16 +1774,27 @@ static int airoha_dev_init(struct net_de
|
||||
@@ -1796,16 +1779,27 @@ static int airoha_dev_init(struct net_de
|
||||
fallthrough;
|
||||
case 2:
|
||||
if (airoha_ppe_is_enabled(eth, 1)) {
|
||||
|
||||
+4
-4
@@ -22,7 +22,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1703,13 +1703,17 @@ static int airoha_dev_set_macaddr(struct
|
||||
@@ -1708,13 +1708,17 @@ static int airoha_dev_set_macaddr(struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(2), pse_port);
|
||||
airoha_fe_clear(eth, REG_GDM_FWD_CFG(2), GDM_STRIP_CRC);
|
||||
|
||||
@@ -1730,29 +1734,25 @@ static void airhoha_set_gdm2_loopback(st
|
||||
@@ -1735,29 +1739,25 @@ static void airhoha_set_gdm2_loopback(st
|
||||
airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(2));
|
||||
airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(2));
|
||||
|
||||
@@ -89,7 +89,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
}
|
||||
|
||||
static int airoha_dev_init(struct net_device *dev)
|
||||
@@ -1769,8 +1769,13 @@ static int airoha_dev_init(struct net_de
|
||||
@@ -1774,8 +1774,13 @@ static int airoha_dev_init(struct net_de
|
||||
case 3:
|
||||
case 4:
|
||||
/* If GDM2 is active we can't enable loopback */
|
||||
@@ -105,7 +105,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
fallthrough;
|
||||
case 2:
|
||||
if (airoha_ppe_is_enabled(eth, 1)) {
|
||||
@@ -3088,11 +3093,38 @@ static const char * const en7581_xsi_rst
|
||||
@@ -3093,11 +3098,38 @@ static const char * const en7581_xsi_rst
|
||||
"xfp-mac",
|
||||
};
|
||||
|
||||
|
||||
+8
-8
@@ -17,7 +17,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1705,10 +1705,8 @@ static int airoha_dev_set_macaddr(struct
|
||||
@@ -1710,10 +1710,8 @@ static int airoha_dev_set_macaddr(struct
|
||||
|
||||
static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port)
|
||||
{
|
||||
@@ -29,7 +29,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
int src_port;
|
||||
|
||||
/* Forward the traffic to the proper GDM port */
|
||||
@@ -1720,6 +1718,8 @@ static int airhoha_set_gdm2_loopback(str
|
||||
@@ -1725,6 +1723,8 @@ static int airhoha_set_gdm2_loopback(str
|
||||
/* Enable GDM2 loopback */
|
||||
airoha_fe_wr(eth, REG_GDM_TXCHN_EN(2), 0xffffffff);
|
||||
airoha_fe_wr(eth, REG_GDM_RXCHN_EN(2), 0xffff);
|
||||
@@ -38,7 +38,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
airoha_fe_rmw(eth, REG_GDM_LPBK_CFG(2),
|
||||
LPBK_CHAN_MASK | LPBK_MODE_MASK | LPBK_EN_MASK,
|
||||
FIELD_PREP(LPBK_CHAN_MASK, chan) |
|
||||
@@ -1734,6 +1734,8 @@ static int airhoha_set_gdm2_loopback(str
|
||||
@@ -1739,6 +1739,8 @@ static int airhoha_set_gdm2_loopback(str
|
||||
airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(2));
|
||||
airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(2));
|
||||
|
||||
@@ -47,7 +47,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
src_port = eth->soc->ops.get_src_port_id(port, nbq);
|
||||
if (src_port < 0)
|
||||
return src_port;
|
||||
@@ -1747,7 +1749,7 @@ static int airhoha_set_gdm2_loopback(str
|
||||
@@ -1752,7 +1754,7 @@ static int airhoha_set_gdm2_loopback(str
|
||||
SP_CPORT_MASK(val),
|
||||
FE_PSE_PORT_CDM2 << __ffs(SP_CPORT_MASK(val)));
|
||||
|
||||
@@ -56,7 +56,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6,
|
||||
FC_ID_OF_SRC_PORT24_MASK,
|
||||
FIELD_PREP(FC_ID_OF_SRC_PORT24_MASK, 2));
|
||||
@@ -1916,6 +1918,22 @@ static bool airoha_dev_tx_queue_busy(str
|
||||
@@ -1921,6 +1923,22 @@ static bool airoha_dev_tx_queue_busy(str
|
||||
return index >= tail;
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
|
||||
struct net_device *dev)
|
||||
{
|
||||
@@ -1956,7 +1974,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
@@ -1961,7 +1979,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) |
|
||||
FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f);
|
||||
|
||||
@@ -3117,6 +3135,35 @@ static int airoha_en7581_get_src_port_id
|
||||
@@ -3122,6 +3140,35 @@ static int airoha_en7581_get_src_port_id
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
static const struct airoha_eth_soc_data en7581_soc_data = {
|
||||
.version = 0x7581,
|
||||
.xsi_rsts_names = en7581_xsi_rsts_names,
|
||||
@@ -3127,8 +3174,19 @@ static const struct airoha_eth_soc_data
|
||||
@@ -3132,8 +3179,19 @@ static const struct airoha_eth_soc_data
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -172,7 +172,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
MBI_RX_AGE_SEL_MASK | MBI_TX_AGE_SEL_MASK,
|
||||
FIELD_PREP(MBI_RX_AGE_SEL_MASK, 3) |
|
||||
FIELD_PREP(MBI_TX_AGE_SEL_MASK, 3));
|
||||
@@ -1713,7 +1713,7 @@ static int airhoha_set_gdm2_loopback(str
|
||||
@@ -1718,7 +1718,7 @@ static int airhoha_set_gdm2_loopback(str
|
||||
pse_port = port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3
|
||||
: FE_PSE_PORT_GDM4;
|
||||
airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(2), pse_port);
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -3060,6 +3060,7 @@ static int airoha_probe(struct platform_
|
||||
@@ -3065,6 +3065,7 @@ static int airoha_probe(struct platform_
|
||||
error_napi_stop:
|
||||
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
|
||||
airoha_qdma_stop_napi(ð->qdma[i]);
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -3006,11 +3006,11 @@ static int airoha_probe(struct platform_
|
||||
@@ -3011,11 +3011,11 @@ static int airoha_probe(struct platform_
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
+13
-13
@@ -23,7 +23,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -908,19 +908,13 @@ static int airoha_qdma_tx_napi_poll(stru
|
||||
@@ -913,19 +913,13 @@ static int airoha_qdma_tx_napi_poll(stru
|
||||
|
||||
dma_unmap_single(eth->dev, e->dma_addr, e->dma_len,
|
||||
DMA_TO_DEVICE);
|
||||
@@ -46,7 +46,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
if (skb) {
|
||||
u16 queue = skb_get_queue_mapping(skb);
|
||||
struct netdev_queue *txq;
|
||||
@@ -965,6 +959,7 @@ static int airoha_qdma_init_tx_queue(str
|
||||
@@ -970,6 +964,7 @@ static int airoha_qdma_init_tx_queue(str
|
||||
q->ndesc = size;
|
||||
q->qdma = qdma;
|
||||
q->free_thr = 1 + MAX_SKB_FRAGS;
|
||||
@@ -54,7 +54,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
q->entry = devm_kzalloc(eth->dev, q->ndesc * sizeof(*q->entry),
|
||||
GFP_KERNEL);
|
||||
@@ -977,9 +972,9 @@ static int airoha_qdma_init_tx_queue(str
|
||||
@@ -982,9 +977,9 @@ static int airoha_qdma_init_tx_queue(str
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < q->ndesc; i++) {
|
||||
@@ -66,7 +66,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
WRITE_ONCE(q->desc[i].ctrl, cpu_to_le32(val));
|
||||
}
|
||||
|
||||
@@ -989,9 +984,9 @@ static int airoha_qdma_init_tx_queue(str
|
||||
@@ -994,9 +989,9 @@ static int airoha_qdma_init_tx_queue(str
|
||||
|
||||
airoha_qdma_wr(qdma, REG_TX_RING_BASE(qid), dma_addr);
|
||||
airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), TX_RING_CPU_IDX_MASK,
|
||||
@@ -78,7 +78,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1047,17 +1042,21 @@ static int airoha_qdma_init_tx(struct ai
|
||||
@@ -1052,17 +1047,21 @@ static int airoha_qdma_init_tx(struct ai
|
||||
static void airoha_qdma_cleanup_tx_queue(struct airoha_queue *q)
|
||||
{
|
||||
struct airoha_eth *eth = q->qdma->eth;
|
||||
@@ -104,7 +104,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
q->queued--;
|
||||
}
|
||||
spin_unlock_bh(&q->lock);
|
||||
@@ -1899,20 +1898,6 @@ static u32 airoha_get_dsa_tag(struct sk_
|
||||
@@ -1904,20 +1903,6 @@ static u32 airoha_get_dsa_tag(struct sk_
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
static int airoha_get_fe_port(struct airoha_gdm_port *port)
|
||||
{
|
||||
struct airoha_qdma *qdma = port->qdma;
|
||||
@@ -1935,8 +1920,10 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
@@ -1940,8 +1925,10 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
struct airoha_gdm_port *port = netdev_priv(dev);
|
||||
struct airoha_qdma *qdma = port->qdma;
|
||||
u32 nr_frags, tag, msg0, msg1, len;
|
||||
@@ -136,7 +136,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
void *data;
|
||||
int i, qid;
|
||||
u16 index;
|
||||
@@ -1982,7 +1969,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
@@ -1987,7 +1974,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
txq = netdev_get_tx_queue(dev, qid);
|
||||
nr_frags = 1 + skb_shinfo(skb)->nr_frags;
|
||||
|
||||
@@ -145,7 +145,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
/* not enough space in the queue */
|
||||
netif_tx_stop_queue(txq);
|
||||
spin_unlock_bh(&q->lock);
|
||||
@@ -1991,11 +1978,13 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
@@ -1996,11 +1983,13 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
|
||||
len = skb_headlen(skb);
|
||||
data = skb->data;
|
||||
@@ -161,7 +161,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
|
||||
dma_addr_t addr;
|
||||
u32 val;
|
||||
@@ -2005,7 +1994,14 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
@@ -2010,7 +1999,14 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
if (unlikely(dma_mapping_error(dev->dev.parent, addr)))
|
||||
goto error_unmap;
|
||||
|
||||
@@ -177,7 +177,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
val = FIELD_PREP(QDMA_DESC_LEN_MASK, len);
|
||||
if (i < nr_frags - 1)
|
||||
@@ -2018,15 +2014,9 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
@@ -2023,15 +2019,9 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
WRITE_ONCE(desc->msg1, cpu_to_le32(msg1));
|
||||
WRITE_ONCE(desc->msg2, cpu_to_le32(0xffff));
|
||||
|
||||
@@ -193,7 +193,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
q->queued += i;
|
||||
|
||||
skb_tx_timestamp(skb);
|
||||
@@ -2035,7 +2025,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
@@ -2040,7 +2030,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
if (netif_xmit_stopped(txq) || !netdev_xmit_more())
|
||||
airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid),
|
||||
TX_RING_CPU_IDX_MASK,
|
||||
@@ -202,7 +202,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
if (q->ndesc - q->queued < q->free_thr)
|
||||
netif_tx_stop_queue(txq);
|
||||
@@ -2045,10 +2035,13 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
@@ -2050,10 +2040,13 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
return NETDEV_TX_OK;
|
||||
|
||||
error_unmap:
|
||||
|
||||
+3
-3
@@ -23,7 +23,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -2940,19 +2940,26 @@ static int airoha_alloc_gdm_port(struct
|
||||
@@ -2945,19 +2945,26 @@ static int airoha_alloc_gdm_port(struct
|
||||
port->id = id;
|
||||
eth->ports[p] = port;
|
||||
|
||||
@@ -60,7 +60,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
}
|
||||
|
||||
static int airoha_probe(struct platform_device *pdev)
|
||||
@@ -3043,6 +3050,10 @@ static int airoha_probe(struct platform_
|
||||
@@ -3048,6 +3055,10 @@ static int airoha_probe(struct platform_
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
return 0;
|
||||
|
||||
error_napi_stop:
|
||||
@@ -3056,10 +3067,12 @@ error_hw_cleanup:
|
||||
@@ -3061,10 +3072,12 @@ error_hw_cleanup:
|
||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
struct airoha_gdm_port *port = eth->ports[i];
|
||||
|
||||
|
||||
+5
-5
@@ -40,7 +40,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
airoha_fe_crsn_qsel_init(eth);
|
||||
|
||||
@@ -1706,27 +1706,29 @@ static int airhoha_set_gdm2_loopback(str
|
||||
@@ -1711,27 +1711,29 @@ static int airhoha_set_gdm2_loopback(str
|
||||
/* Forward the traffic to the proper GDM port */
|
||||
pse_port = port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3
|
||||
: FE_PSE_PORT_GDM4;
|
||||
@@ -78,7 +78,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
/* XXX: handle XSI_USB_PORT and XSI_PCE1_PORT */
|
||||
nbq = port->id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0;
|
||||
@@ -1762,8 +1764,8 @@ static int airoha_dev_init(struct net_de
|
||||
@@ -1767,8 +1769,8 @@ static int airoha_dev_init(struct net_de
|
||||
airoha_set_macaddr(port, dev->dev_addr);
|
||||
|
||||
switch (port->id) {
|
||||
@@ -89,7 +89,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
/* If GDM2 is active we can't enable loopback */
|
||||
if (!eth->ports[1]) {
|
||||
int err;
|
||||
@@ -1773,7 +1775,7 @@ static int airoha_dev_init(struct net_de
|
||||
@@ -1778,7 +1780,7 @@ static int airoha_dev_init(struct net_de
|
||||
return err;
|
||||
}
|
||||
fallthrough;
|
||||
@@ -98,7 +98,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
if (airoha_ppe_is_enabled(eth, 1)) {
|
||||
/* For PPE2 always use secondary cpu port. */
|
||||
fe_cpu_port = FE_PSE_PORT_CDM2;
|
||||
@@ -3116,14 +3118,14 @@ static const char * const en7581_xsi_rst
|
||||
@@ -3121,14 +3123,14 @@ static const char * const en7581_xsi_rst
|
||||
static int airoha_en7581_get_src_port_id(struct airoha_gdm_port *port, int nbq)
|
||||
{
|
||||
switch (port->id) {
|
||||
@@ -115,7 +115,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
/* 7581 SoC supports eth and usb serdes on GDM4 port */
|
||||
if (!nbq)
|
||||
return HSGMII_LAN_7581_ETH_SRCPORT;
|
||||
@@ -3147,12 +3149,12 @@ static const char * const an7583_xsi_rst
|
||||
@@ -3152,12 +3154,12 @@ static const char * const an7583_xsi_rst
|
||||
static int airoha_an7583_get_src_port_id(struct airoha_gdm_port *port, int nbq)
|
||||
{
|
||||
switch (port->id) {
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -2821,6 +2821,7 @@ static const struct ethtool_ops airoha_e
|
||||
@@ -2826,6 +2826,7 @@ static const struct ethtool_ops airoha_e
|
||||
.get_drvinfo = airoha_ethtool_get_drvinfo,
|
||||
.get_eth_mac_stats = airoha_ethtool_get_mac_stats,
|
||||
.get_rmon_stats = airoha_ethtool_get_rmon_stats,
|
||||
|
||||
+3
-3
@@ -15,7 +15,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1743,7 +1743,7 @@ static int airhoha_set_gdm2_loopback(str
|
||||
@@ -1748,7 +1748,7 @@ static int airhoha_set_gdm2_loopback(str
|
||||
airoha_fe_rmw(eth,
|
||||
REG_SP_DFT_CPORT(src_port >> fls(SP_CPORT_DFT_MASK)),
|
||||
SP_CPORT_MASK(val),
|
||||
@@ -24,7 +24,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
if (port->id != AIROHA_GDM3_IDX && airoha_is_7581(eth))
|
||||
airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6,
|
||||
@@ -1797,7 +1797,7 @@ static int airoha_dev_init(struct net_de
|
||||
@@ -1802,7 +1802,7 @@ static int airoha_dev_init(struct net_de
|
||||
ppe_id = pse_port == FE_PSE_PORT_PPE2 ? 1 : 0;
|
||||
airoha_fe_rmw(eth, REG_PPE_DFT_CPORT0(ppe_id),
|
||||
DFT_CPORT_MASK(port->id),
|
||||
@@ -33,7 +33,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2154,7 +2154,7 @@ static int airoha_qdma_set_chan_tx_sched
|
||||
@@ -2159,7 +2159,7 @@ static int airoha_qdma_set_chan_tx_sched
|
||||
|
||||
airoha_qdma_rmw(port->qdma, REG_CHAN_QOS_MODE(channel >> 3),
|
||||
CHAN_QOS_MODE_MASK(channel),
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1745,10 +1745,12 @@ static int airhoha_set_gdm2_loopback(str
|
||||
@@ -1750,10 +1750,12 @@ static int airhoha_set_gdm2_loopback(str
|
||||
SP_CPORT_MASK(val),
|
||||
__field_prep(SP_CPORT_MASK(val), FE_PSE_PORT_CDM2));
|
||||
|
||||
|
||||
+6
-6
@@ -18,7 +18,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1627,6 +1627,7 @@ static int airoha_dev_open(struct net_de
|
||||
@@ -1632,6 +1632,7 @@ static int airoha_dev_open(struct net_de
|
||||
int err, len = ETH_HLEN + dev->mtu + ETH_FCS_LEN;
|
||||
struct airoha_gdm_port *port = netdev_priv(dev);
|
||||
struct airoha_qdma *qdma = port->qdma;
|
||||
@@ -26,7 +26,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
|
||||
netif_tx_start_all_queues(dev);
|
||||
err = airoha_set_vip_for_gdm_port(port, true);
|
||||
@@ -1650,6 +1651,14 @@ static int airoha_dev_open(struct net_de
|
||||
@@ -1655,6 +1656,14 @@ static int airoha_dev_open(struct net_de
|
||||
GLOBAL_CFG_RX_DMA_EN_MASK);
|
||||
atomic_inc(&qdma->users);
|
||||
|
||||
@@ -41,7 +41,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1667,6 +1676,9 @@ static int airoha_dev_stop(struct net_de
|
||||
@@ -1672,6 +1681,9 @@ static int airoha_dev_stop(struct net_de
|
||||
for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++)
|
||||
netdev_tx_reset_subqueue(dev, i);
|
||||
|
||||
@@ -51,7 +51,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
if (atomic_dec_and_test(&qdma->users)) {
|
||||
airoha_qdma_clear(qdma, REG_QDMA_GLOBAL_CFG,
|
||||
GLOBAL_CFG_TX_DMA_EN_MASK |
|
||||
@@ -1760,7 +1772,7 @@ static int airoha_dev_init(struct net_de
|
||||
@@ -1765,7 +1777,7 @@ static int airoha_dev_init(struct net_de
|
||||
struct airoha_gdm_port *port = netdev_priv(dev);
|
||||
struct airoha_qdma *qdma = port->qdma;
|
||||
struct airoha_eth *eth = qdma->eth;
|
||||
@@ -60,7 +60,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
u8 ppe_id;
|
||||
|
||||
airoha_set_macaddr(port, dev->dev_addr);
|
||||
@@ -1781,7 +1793,7 @@ static int airoha_dev_init(struct net_de
|
||||
@@ -1786,7 +1798,7 @@ static int airoha_dev_init(struct net_de
|
||||
if (airoha_ppe_is_enabled(eth, 1)) {
|
||||
/* For PPE2 always use secondary cpu port. */
|
||||
fe_cpu_port = FE_PSE_PORT_CDM2;
|
||||
@@ -69,7 +69,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
break;
|
||||
}
|
||||
fallthrough;
|
||||
@@ -1790,13 +1802,11 @@ static int airoha_dev_init(struct net_de
|
||||
@@ -1795,13 +1807,11 @@ static int airoha_dev_init(struct net_de
|
||||
|
||||
/* For PPE1 select cpu port according to the running QDMA. */
|
||||
fe_cpu_port = qdma_id ? FE_PSE_PORT_CDM2 : FE_PSE_PORT_CDM1;
|
||||
|
||||
+8
-8
@@ -39,7 +39,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1770,11 +1770,13 @@ static int airhoha_set_gdm2_loopback(str
|
||||
@@ -1775,11 +1775,13 @@ static int airhoha_set_gdm2_loopback(str
|
||||
static int airoha_dev_init(struct net_device *dev)
|
||||
{
|
||||
struct airoha_gdm_port *port = netdev_priv(dev);
|
||||
@@ -55,7 +55,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
airoha_set_macaddr(port, dev->dev_addr);
|
||||
|
||||
switch (port->id) {
|
||||
@@ -1798,7 +1800,7 @@ static int airoha_dev_init(struct net_de
|
||||
@@ -1803,7 +1805,7 @@ static int airoha_dev_init(struct net_de
|
||||
}
|
||||
fallthrough;
|
||||
default: {
|
||||
@@ -64,7 +64,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
|
||||
/* For PPE1 select cpu port according to the running QDMA. */
|
||||
fe_cpu_port = qdma_id ? FE_PSE_PORT_CDM2 : FE_PSE_PORT_CDM1;
|
||||
@@ -2882,11 +2884,10 @@ bool airoha_is_valid_gdm_port(struct air
|
||||
@@ -2887,11 +2889,10 @@ bool airoha_is_valid_gdm_port(struct air
|
||||
}
|
||||
|
||||
static int airoha_alloc_gdm_port(struct airoha_eth *eth,
|
||||
@@ -77,7 +77,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
struct net_device *dev;
|
||||
int err, p;
|
||||
u32 id;
|
||||
@@ -2917,7 +2918,6 @@ static int airoha_alloc_gdm_port(struct
|
||||
@@ -2922,7 +2923,6 @@ static int airoha_alloc_gdm_port(struct
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
dev->netdev_ops = &airoha_netdev_ops;
|
||||
dev->ethtool_ops = &airoha_ethtool_ops;
|
||||
dev->max_mtu = AIROHA_MAX_MTU;
|
||||
@@ -2929,7 +2929,6 @@ static int airoha_alloc_gdm_port(struct
|
||||
@@ -2934,7 +2934,6 @@ static int airoha_alloc_gdm_port(struct
|
||||
dev->features |= dev->hw_features;
|
||||
dev->vlan_features = dev->hw_features;
|
||||
dev->dev.of_node = np;
|
||||
@@ -93,7 +93,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
SET_NETDEV_DEV(dev, eth->dev);
|
||||
|
||||
/* reserve hw queues for HTB offloading */
|
||||
@@ -2950,7 +2949,7 @@ static int airoha_alloc_gdm_port(struct
|
||||
@@ -2955,7 +2954,7 @@ static int airoha_alloc_gdm_port(struct
|
||||
port = netdev_priv(dev);
|
||||
u64_stats_init(&port->stats.syncp);
|
||||
spin_lock_init(&port->stats.lock);
|
||||
@@ -102,7 +102,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
port->dev = dev;
|
||||
port->id = id;
|
||||
eth->ports[p] = port;
|
||||
@@ -3050,7 +3049,6 @@ static int airoha_probe(struct platform_
|
||||
@@ -3055,7 +3054,6 @@ static int airoha_probe(struct platform_
|
||||
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
|
||||
airoha_qdma_start_napi(ð->qdma[i]);
|
||||
|
||||
@@ -110,7 +110,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
for_each_child_of_node(pdev->dev.of_node, np) {
|
||||
if (!of_device_is_compatible(np, "airoha,eth-mac"))
|
||||
continue;
|
||||
@@ -3058,7 +3056,7 @@ static int airoha_probe(struct platform_
|
||||
@@ -3063,7 +3061,7 @@ static int airoha_probe(struct platform_
|
||||
if (!of_device_is_available(np))
|
||||
continue;
|
||||
|
||||
|
||||
+3
-3
@@ -32,7 +32,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1771,8 +1771,7 @@ static int airoha_dev_init(struct net_de
|
||||
@@ -1776,8 +1776,7 @@ static int airoha_dev_init(struct net_de
|
||||
{
|
||||
struct airoha_gdm_port *port = netdev_priv(dev);
|
||||
struct airoha_eth *eth = port->eth;
|
||||
@@ -42,7 +42,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
/* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */
|
||||
port->qdma = ð->qdma[!airoha_is_lan_gdm_port(port)];
|
||||
@@ -1790,28 +1789,13 @@ static int airoha_dev_init(struct net_de
|
||||
@@ -1795,28 +1794,13 @@ static int airoha_dev_init(struct net_de
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
@@ -75,7 +75,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1914,7 +1898,7 @@ static u32 airoha_get_dsa_tag(struct sk_
|
||||
@@ -1919,7 +1903,7 @@ static u32 airoha_get_dsa_tag(struct sk_
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
+7
-7
@@ -23,7 +23,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1384,6 +1384,33 @@ static int airoha_qdma_init(struct platf
|
||||
@@ -1389,6 +1389,33 @@ static int airoha_qdma_init(struct platf
|
||||
return airoha_qdma_hw_init(qdma);
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
static int airoha_hw_init(struct platform_device *pdev,
|
||||
struct airoha_eth *eth)
|
||||
{
|
||||
@@ -1411,41 +1438,30 @@ static int airoha_hw_init(struct platfor
|
||||
@@ -1416,41 +1443,30 @@ static int airoha_hw_init(struct platfor
|
||||
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) {
|
||||
err = airoha_qdma_init(pdev, eth, ð->qdma[i]);
|
||||
if (err)
|
||||
@@ -110,7 +110,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
}
|
||||
|
||||
static void airoha_qdma_start_napi(struct airoha_qdma *qdma)
|
||||
@@ -3028,7 +3044,7 @@ static int airoha_probe(struct platform_
|
||||
@@ -3033,7 +3049,7 @@ static int airoha_probe(struct platform_
|
||||
|
||||
err = airoha_hw_init(pdev, eth);
|
||||
if (err)
|
||||
@@ -119,7 +119,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
|
||||
airoha_qdma_start_napi(ð->qdma[i]);
|
||||
@@ -3056,10 +3072,6 @@ static int airoha_probe(struct platform_
|
||||
@@ -3061,10 +3077,6 @@ static int airoha_probe(struct platform_
|
||||
error_napi_stop:
|
||||
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
|
||||
airoha_qdma_stop_napi(ð->qdma[i]);
|
||||
@@ -130,7 +130,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
struct airoha_gdm_port *port = eth->ports[i];
|
||||
@@ -3071,6 +3083,8 @@ error_hw_cleanup:
|
||||
@@ -3076,6 +3088,8 @@ error_hw_cleanup:
|
||||
unregister_netdev(port->dev);
|
||||
airoha_metadata_dst_free(port);
|
||||
}
|
||||
@@ -139,7 +139,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
free_netdev(eth->napi_dev);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
||||
@@ -3082,10 +3096,8 @@ static void airoha_remove(struct platfor
|
||||
@@ -3087,10 +3101,8 @@ static void airoha_remove(struct platfor
|
||||
struct airoha_eth *eth = platform_get_drvdata(pdev);
|
||||
int i;
|
||||
|
||||
@@ -151,7 +151,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
struct airoha_gdm_port *port = eth->ports[i];
|
||||
@@ -3096,9 +3108,9 @@ static void airoha_remove(struct platfor
|
||||
@@ -3101,9 +3113,9 @@ static void airoha_remove(struct platfor
|
||||
unregister_netdev(port->dev);
|
||||
airoha_metadata_dst_free(port);
|
||||
}
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -2973,6 +2973,8 @@ static int airoha_register_gdm_devices(s
|
||||
@@ -2978,6 +2978,8 @@ static int airoha_register_gdm_devices(s
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
From 656121b155030086b01cfce9bd31b0c925ee6860 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Wed, 8 Apr 2026 20:26:56 +0200
|
||||
Subject: [PATCH] net: airoha: Add missing RX_CPU_IDX() configuration in
|
||||
airoha_qdma_cleanup_rx_queue()
|
||||
|
||||
When the descriptor index written in REG_RX_CPU_IDX() is equal to the one
|
||||
stored in REG_RX_DMA_IDX(), the hw will stop since the QDMA RX ring is
|
||||
empty.
|
||||
Add missing REG_RX_CPU_IDX() configuration in airoha_qdma_cleanup_rx_queue
|
||||
routine during QDMA RX ring cleanup.
|
||||
|
||||
Fixes: 514aac359987 ("net: airoha: Add missing cleanup bits in airoha_qdma_cleanup_rx_queue()")
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://patch.msgid.link/20260408-airoha-cpu-idx-airoha_qdma_cleanup_rx_queue-v1-1-8efa64844308@kernel.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -824,6 +824,11 @@ static void airoha_qdma_cleanup_rx_queue
|
||||
}
|
||||
|
||||
q->head = q->tail;
|
||||
+ /* Set RX_DMA_IDX to RX_CPU_IDX to notify the hw the QDMA RX ring is
|
||||
+ * empty.
|
||||
+ */
|
||||
+ airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid), RX_RING_CPU_IDX_MASK,
|
||||
+ FIELD_PREP(RX_RING_CPU_IDX_MASK, q->head));
|
||||
airoha_qdma_rmw(qdma, REG_RX_DMA_IDX(qid), RX_RING_DMA_IDX_MASK,
|
||||
FIELD_PREP(RX_RING_DMA_IDX_MASK, q->tail));
|
||||
}
|
||||
-61
@@ -1,61 +0,0 @@
|
||||
From 379050947a1828826ad7ea50c95245a56929b35a Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Mon, 20 Apr 2026 10:07:47 +0200
|
||||
Subject: [PATCH] net: airoha: Move ndesc initialization at end of
|
||||
airoha_qdma_init_rx_queue()
|
||||
|
||||
If queue entry or DMA descriptor list allocation fails in
|
||||
airoha_qdma_init_rx_queue routine, airoha_qdma_cleanup() will trigger a
|
||||
NULL pointer dereference running netif_napi_del() for RX queue NAPIs
|
||||
since netif_napi_add() has never been executed to this particular RX NAPI.
|
||||
The issue is due to the early ndesc initialization in
|
||||
airoha_qdma_init_rx_queue() since airoha_qdma_cleanup() relies on ndesc
|
||||
value to check if the queue is properly initialized. Fix the issue moving
|
||||
ndesc initialization at end of airoha_qdma_init_tx routine.
|
||||
Move page_pool allocation after descriptor list allocation in order to
|
||||
avoid memory leaks if desc allocation fails.
|
||||
|
||||
Fixes: 23020f049327 ("net: airoha: Introduce ethernet support for EN7581 SoC")
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://patch.msgid.link/20260420-airoha_qdma_init_rx_queue-fix-v2-1-d99347e5c18d@kernel.org
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 14 +++++++-------
|
||||
1 file changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -745,14 +745,18 @@ static int airoha_qdma_init_rx_queue(str
|
||||
dma_addr_t dma_addr;
|
||||
|
||||
q->buf_size = PAGE_SIZE / 2;
|
||||
- q->ndesc = ndesc;
|
||||
q->qdma = qdma;
|
||||
|
||||
- q->entry = devm_kzalloc(eth->dev, q->ndesc * sizeof(*q->entry),
|
||||
+ q->entry = devm_kzalloc(eth->dev, ndesc * sizeof(*q->entry),
|
||||
GFP_KERNEL);
|
||||
if (!q->entry)
|
||||
return -ENOMEM;
|
||||
|
||||
+ q->desc = dmam_alloc_coherent(eth->dev, ndesc * sizeof(*q->desc),
|
||||
+ &dma_addr, GFP_KERNEL);
|
||||
+ if (!q->desc)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
q->page_pool = page_pool_create(&pp_params);
|
||||
if (IS_ERR(q->page_pool)) {
|
||||
int err = PTR_ERR(q->page_pool);
|
||||
@@ -761,11 +765,7 @@ static int airoha_qdma_init_rx_queue(str
|
||||
return err;
|
||||
}
|
||||
|
||||
- q->desc = dmam_alloc_coherent(eth->dev, q->ndesc * sizeof(*q->desc),
|
||||
- &dma_addr, GFP_KERNEL);
|
||||
- if (!q->desc)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
+ q->ndesc = ndesc;
|
||||
netif_napi_add(eth->napi_dev, &q->napi, airoha_qdma_rx_napi_poll);
|
||||
|
||||
airoha_qdma_wr(qdma, REG_RX_RING_BASE(qid), dma_addr);
|
||||
+1012
File diff suppressed because it is too large
Load Diff
+495
@@ -0,0 +1,495 @@
|
||||
From f62cea6483cc55360863d66300790a5fb9de5f7c Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <f62cea6483cc55360863d66300790a5fb9de5f7c.1779348625.git.lorenzo@kernel.org>
|
||||
In-Reply-To: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
|
||||
References: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Tue, 24 Feb 2026 18:43:05 +0100
|
||||
Subject: [PATCH 02/13] net: airoha: Move airoha_qdma pointer in airoha_gdm_dev
|
||||
struct
|
||||
|
||||
Move airoha_qdma pointer from airoha_gdm_port struct to airoha_gdm_dev
|
||||
one since the QDMA block used depends on the particular net_device
|
||||
WAN/LAN configuration and in the current codebase net_device pointer is
|
||||
associated to airoha_gdm_dev struct.
|
||||
This is a preliminary patch to support multiple net_devices connected
|
||||
to the same GDM{3,4} port via an external hw arbiter.
|
||||
|
||||
Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 105 +++++++++++------------
|
||||
drivers/net/ethernet/airoha/airoha_eth.h | 9 +-
|
||||
drivers/net/ethernet/airoha/airoha_ppe.c | 17 ++--
|
||||
3 files changed, 64 insertions(+), 67 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -80,9 +80,10 @@ static bool airhoa_is_phy_external(struc
|
||||
}
|
||||
#endif
|
||||
|
||||
-static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr)
|
||||
+static void airoha_set_macaddr(struct airoha_gdm_dev *dev, const u8 *addr)
|
||||
{
|
||||
- struct airoha_eth *eth = port->qdma->eth;
|
||||
+ struct airoha_gdm_port *port = dev->port;
|
||||
+ struct airoha_eth *eth = dev->eth;
|
||||
u32 val, reg;
|
||||
|
||||
reg = airoha_is_lan_gdm_port(port) ? REG_FE_LAN_MAC_H
|
||||
@@ -94,7 +95,7 @@ static void airoha_set_macaddr(struct ai
|
||||
airoha_fe_wr(eth, REG_FE_MAC_LMIN(reg), val);
|
||||
airoha_fe_wr(eth, REG_FE_MAC_LMAX(reg), val);
|
||||
|
||||
- airoha_ppe_init_upd_mem(port);
|
||||
+ airoha_ppe_init_upd_mem(dev);
|
||||
}
|
||||
|
||||
static void airoha_set_gdm_port_fwd_cfg(struct airoha_eth *eth, u32 addr,
|
||||
@@ -110,10 +111,10 @@ static void airoha_set_gdm_port_fwd_cfg(
|
||||
FIELD_PREP(GDM_UCFQ_MASK, val));
|
||||
}
|
||||
|
||||
-static int airoha_set_vip_for_gdm_port(struct airoha_gdm_port *port,
|
||||
- bool enable)
|
||||
+static int airoha_set_vip_for_gdm_port(struct airoha_gdm_dev *dev, bool enable)
|
||||
{
|
||||
- struct airoha_eth *eth = port->qdma->eth;
|
||||
+ struct airoha_gdm_port *port = dev->port;
|
||||
+ struct airoha_eth *eth = dev->eth;
|
||||
u32 vip_port;
|
||||
|
||||
vip_port = eth->soc->ops.get_vip_port(port, port->nbq);
|
||||
@@ -994,10 +995,13 @@ static void airoha_qdma_wake_netdev_txqs
|
||||
if (!port)
|
||||
continue;
|
||||
|
||||
- if (port->qdma != qdma)
|
||||
+ dev = port->dev;
|
||||
+ if (!dev)
|
||||
+ continue;
|
||||
+
|
||||
+ if (dev->qdma != qdma)
|
||||
continue;
|
||||
|
||||
- dev = port->dev;
|
||||
for (j = 0; j < dev->dev->num_tx_queues; j++) {
|
||||
if (airoha_qdma_get_txq(qdma, j) != qid)
|
||||
continue;
|
||||
@@ -1702,9 +1706,10 @@ static void airoha_qdma_stop_napi(struct
|
||||
}
|
||||
}
|
||||
|
||||
-static void airoha_update_hw_stats(struct airoha_gdm_port *port)
|
||||
+static void airoha_update_hw_stats(struct airoha_gdm_dev *dev)
|
||||
{
|
||||
- struct airoha_eth *eth = port->qdma->eth;
|
||||
+ struct airoha_gdm_port *port = dev->port;
|
||||
+ struct airoha_eth *eth = dev->eth;
|
||||
u32 val, i = 0;
|
||||
|
||||
spin_lock(&port->stats.lock);
|
||||
@@ -1851,7 +1856,7 @@ static int airoha_dev_open(struct net_de
|
||||
int err, len = ETH_HLEN + netdev->mtu + ETH_FCS_LEN;
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
struct airoha_gdm_port *port = dev->port;
|
||||
- struct airoha_qdma *qdma = port->qdma;
|
||||
+ struct airoha_qdma *qdma = dev->qdma;
|
||||
u32 pse_port = FE_PSE_PORT_PPE1;
|
||||
|
||||
#if defined(CONFIG_PCS_AIROHA)
|
||||
@@ -1868,7 +1873,7 @@ static int airoha_dev_open(struct net_de
|
||||
#endif
|
||||
|
||||
netif_tx_start_all_queues(netdev);
|
||||
- err = airoha_set_vip_for_gdm_port(port, true);
|
||||
+ err = airoha_set_vip_for_gdm_port(dev, true);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -1905,11 +1910,11 @@ static int airoha_dev_stop(struct net_de
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
struct airoha_gdm_port *port = dev->port;
|
||||
- struct airoha_qdma *qdma = port->qdma;
|
||||
+ struct airoha_qdma *qdma = dev->qdma;
|
||||
int i;
|
||||
|
||||
netif_tx_disable(netdev);
|
||||
- airoha_set_vip_for_gdm_port(port, false);
|
||||
+ airoha_set_vip_for_gdm_port(dev, false);
|
||||
for (i = 0; i < netdev->num_tx_queues; i++)
|
||||
netdev_tx_reset_subqueue(netdev, i);
|
||||
|
||||
@@ -1942,21 +1947,21 @@ static int airoha_dev_stop(struct net_de
|
||||
static int airoha_dev_set_macaddr(struct net_device *netdev, void *p)
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
- struct airoha_gdm_port *port = dev->port;
|
||||
int err;
|
||||
|
||||
err = eth_mac_addr(netdev, p);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- airoha_set_macaddr(port, netdev->dev_addr);
|
||||
+ airoha_set_macaddr(dev, netdev->dev_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int airoha_set_gdm2_loopback(struct airoha_gdm_port *port)
|
||||
+static int airoha_set_gdm2_loopback(struct airoha_gdm_dev *dev)
|
||||
{
|
||||
- struct airoha_eth *eth = port->qdma->eth;
|
||||
+ struct airoha_gdm_port *port = dev->port;
|
||||
+ struct airoha_eth *eth = dev->eth;
|
||||
u32 val, pse_port, chan;
|
||||
int i, src_port;
|
||||
|
||||
@@ -2003,7 +2008,7 @@ static int airoha_set_gdm2_loopback(stru
|
||||
__field_prep(SP_CPORT_MASK(val), FE_PSE_PORT_CDM2));
|
||||
|
||||
for (i = 0; i < eth->soc->num_ppe; i++)
|
||||
- airoha_ppe_set_cpu_port(port, i, AIROHA_GDM2_IDX);
|
||||
+ airoha_ppe_set_cpu_port(dev, i, AIROHA_GDM2_IDX);
|
||||
|
||||
if (port->id == AIROHA_GDM4_IDX && airoha_is_7581(eth)) {
|
||||
u32 mask = FC_ID_OF_SRC_PORT_MASK(port->nbq);
|
||||
@@ -2023,9 +2028,9 @@ static int airoha_dev_init(struct net_de
|
||||
int i;
|
||||
|
||||
/* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */
|
||||
- port->qdma = ð->qdma[!airoha_is_lan_gdm_port(port)];
|
||||
- dev->dev->irq = port->qdma->irq_banks[0].irq;
|
||||
- airoha_set_macaddr(port, netdev->dev_addr);
|
||||
+ dev->qdma = ð->qdma[!airoha_is_lan_gdm_port(port)];
|
||||
+ dev->dev->irq = dev->qdma->irq_banks[0].irq;
|
||||
+ airoha_set_macaddr(dev, netdev->dev_addr);
|
||||
|
||||
switch (port->id) {
|
||||
case AIROHA_GDM3_IDX:
|
||||
@@ -2034,7 +2039,7 @@ static int airoha_dev_init(struct net_de
|
||||
if (!eth->ports[1]) {
|
||||
int err;
|
||||
|
||||
- err = airoha_set_gdm2_loopback(port);
|
||||
+ err = airoha_set_gdm2_loopback(dev);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
@@ -2044,8 +2049,7 @@ static int airoha_dev_init(struct net_de
|
||||
}
|
||||
|
||||
for (i = 0; i < eth->soc->num_ppe; i++)
|
||||
- airoha_ppe_set_cpu_port(port, i,
|
||||
- airoha_get_fe_port(port));
|
||||
+ airoha_ppe_set_cpu_port(dev, i, airoha_get_fe_port(dev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2057,7 +2061,7 @@ static void airoha_dev_get_stats64(struc
|
||||
struct airoha_gdm_port *port = dev->port;
|
||||
unsigned int start;
|
||||
|
||||
- airoha_update_hw_stats(port);
|
||||
+ airoha_update_hw_stats(dev);
|
||||
do {
|
||||
start = u64_stats_fetch_begin(&port->stats.syncp);
|
||||
storage->rx_packets = port->stats.rx_ok_pkts;
|
||||
@@ -2077,8 +2081,8 @@ static int airoha_dev_change_mtu(struct
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
struct airoha_gdm_port *port = dev->port;
|
||||
- struct airoha_eth *eth = port->qdma->eth;
|
||||
u32 len = ETH_HLEN + mtu + ETH_FCS_LEN;
|
||||
+ struct airoha_eth *eth = dev->eth;
|
||||
|
||||
airoha_fe_rmw(eth, REG_GDM_LEN_CFG(port->id),
|
||||
GDM_LONG_LEN_MASK,
|
||||
@@ -2152,10 +2156,10 @@ static u32 airoha_get_dsa_tag(struct sk_
|
||||
#endif
|
||||
}
|
||||
|
||||
-int airoha_get_fe_port(struct airoha_gdm_port *port)
|
||||
+int airoha_get_fe_port(struct airoha_gdm_dev *dev)
|
||||
{
|
||||
- struct airoha_qdma *qdma = port->qdma;
|
||||
- struct airoha_eth *eth = qdma->eth;
|
||||
+ struct airoha_gdm_port *port = dev->port;
|
||||
+ struct airoha_eth *eth = dev->eth;
|
||||
|
||||
switch (eth->soc->version) {
|
||||
case 0x7583:
|
||||
@@ -2174,8 +2178,7 @@ static int airoha_dev_set_features(struc
|
||||
|
||||
netdev_features_t diff = netdev->features ^ features;
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
- struct airoha_gdm_port *port = dev->port;
|
||||
- struct airoha_qdma *qdma = port->qdma;
|
||||
+ struct airoha_qdma *qdma = dev->qdma;
|
||||
struct airoha_eth *eth = qdma->eth;
|
||||
int qdma_id = qdma - ð->qdma[0];
|
||||
int i;
|
||||
@@ -2213,10 +2216,10 @@ static int airoha_dev_set_features(struc
|
||||
if (!p)
|
||||
continue;
|
||||
|
||||
- if (p->qdma != qdma)
|
||||
+ d = p->dev;
|
||||
+ if (d->qdma != qdma)
|
||||
continue;
|
||||
|
||||
- d = p->dev;
|
||||
if (d->dev == netdev)
|
||||
continue;
|
||||
|
||||
@@ -2233,8 +2236,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
struct net_device *netdev)
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
- struct airoha_gdm_port *port = dev->port;
|
||||
- struct airoha_qdma *qdma = port->qdma;
|
||||
+ struct airoha_qdma *qdma = dev->qdma;
|
||||
u32 nr_frags, tag, msg0, msg1, len;
|
||||
struct airoha_queue_entry *e;
|
||||
struct netdev_queue *txq;
|
||||
@@ -2272,7 +2274,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
}
|
||||
}
|
||||
|
||||
- fport = airoha_get_fe_port(port);
|
||||
+ fport = airoha_get_fe_port(dev);
|
||||
msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) |
|
||||
FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f);
|
||||
|
||||
@@ -2375,8 +2377,7 @@ static void airoha_ethtool_get_drvinfo(s
|
||||
struct ethtool_drvinfo *info)
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
- struct airoha_gdm_port *port = dev->port;
|
||||
- struct airoha_eth *eth = port->qdma->eth;
|
||||
+ struct airoha_eth *eth = dev->eth;
|
||||
|
||||
strscpy(info->driver, eth->dev->driver->name, sizeof(info->driver));
|
||||
strscpy(info->bus_info, dev_name(eth->dev), sizeof(info->bus_info));
|
||||
@@ -2389,7 +2390,7 @@ static void airoha_ethtool_get_mac_stats
|
||||
struct airoha_gdm_port *port = dev->port;
|
||||
unsigned int start;
|
||||
|
||||
- airoha_update_hw_stats(port);
|
||||
+ airoha_update_hw_stats(dev);
|
||||
do {
|
||||
start = u64_stats_fetch_begin(&port->stats.syncp);
|
||||
stats->FramesTransmittedOK = port->stats.tx_ok_pkts;
|
||||
@@ -2429,7 +2430,7 @@ airoha_ethtool_get_rmon_stats(struct net
|
||||
ARRAY_SIZE(hw_stats->rx_len) + 1);
|
||||
|
||||
*ranges = airoha_ethtool_rmon_ranges;
|
||||
- airoha_update_hw_stats(port);
|
||||
+ airoha_update_hw_stats(dev);
|
||||
do {
|
||||
int i;
|
||||
|
||||
@@ -2449,18 +2450,17 @@ static int airoha_qdma_set_chan_tx_sched
|
||||
const u16 *weights, u8 n_weights)
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
- struct airoha_gdm_port *port = dev->port;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < AIROHA_NUM_TX_RING; i++)
|
||||
- airoha_qdma_clear(port->qdma, REG_QUEUE_CLOSE_CFG(channel),
|
||||
+ airoha_qdma_clear(dev->qdma, REG_QUEUE_CLOSE_CFG(channel),
|
||||
TXQ_DISABLE_CHAN_QUEUE_MASK(channel, i));
|
||||
|
||||
for (i = 0; i < n_weights; i++) {
|
||||
u32 status;
|
||||
int err;
|
||||
|
||||
- airoha_qdma_wr(port->qdma, REG_TXWRR_WEIGHT_CFG,
|
||||
+ airoha_qdma_wr(dev->qdma, REG_TXWRR_WEIGHT_CFG,
|
||||
TWRR_RW_CMD_MASK |
|
||||
FIELD_PREP(TWRR_CHAN_IDX_MASK, channel) |
|
||||
FIELD_PREP(TWRR_QUEUE_IDX_MASK, i) |
|
||||
@@ -2468,13 +2468,12 @@ static int airoha_qdma_set_chan_tx_sched
|
||||
err = read_poll_timeout(airoha_qdma_rr, status,
|
||||
status & TWRR_RW_CMD_DONE,
|
||||
USEC_PER_MSEC, 10 * USEC_PER_MSEC,
|
||||
- true, port->qdma,
|
||||
- REG_TXWRR_WEIGHT_CFG);
|
||||
+ true, dev->qdma, REG_TXWRR_WEIGHT_CFG);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
- airoha_qdma_rmw(port->qdma, REG_CHAN_QOS_MODE(channel >> 3),
|
||||
+ airoha_qdma_rmw(dev->qdma, REG_CHAN_QOS_MODE(channel >> 3),
|
||||
CHAN_QOS_MODE_MASK(channel),
|
||||
__field_prep(CHAN_QOS_MODE_MASK(channel), mode));
|
||||
|
||||
@@ -2540,9 +2539,9 @@ static int airoha_qdma_get_tx_ets_stats(
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
struct airoha_gdm_port *port = dev->port;
|
||||
|
||||
- u64 cpu_tx_packets = airoha_qdma_rr(port->qdma,
|
||||
+ u64 cpu_tx_packets = airoha_qdma_rr(dev->qdma,
|
||||
REG_CNTR_VAL(channel << 1));
|
||||
- u64 fwd_tx_packets = airoha_qdma_rr(port->qdma,
|
||||
+ u64 fwd_tx_packets = airoha_qdma_rr(dev->qdma,
|
||||
REG_CNTR_VAL((channel << 1) + 1));
|
||||
u64 tx_packets = (cpu_tx_packets - port->cpu_tx_packets) +
|
||||
(fwd_tx_packets - port->fwd_tx_packets);
|
||||
@@ -2806,17 +2805,16 @@ static int airoha_qdma_set_tx_rate_limit
|
||||
u32 bucket_size)
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
- struct airoha_gdm_port *port = dev->port;
|
||||
int i, err;
|
||||
|
||||
for (i = 0; i <= TRTCM_PEAK_MODE; i++) {
|
||||
- err = airoha_qdma_set_trtcm_config(port->qdma, channel,
|
||||
+ err = airoha_qdma_set_trtcm_config(dev->qdma, channel,
|
||||
REG_EGRESS_TRTCM_CFG, i,
|
||||
!!rate, TRTCM_METER_MODE);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- err = airoha_qdma_set_trtcm_token_bucket(port->qdma, channel,
|
||||
+ err = airoha_qdma_set_trtcm_token_bucket(dev->qdma, channel,
|
||||
REG_EGRESS_TRTCM_CFG,
|
||||
i, rate, bucket_size);
|
||||
if (err)
|
||||
@@ -2866,11 +2864,11 @@ static int airoha_tc_htb_alloc_leaf_queu
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int airoha_qdma_set_rx_meter(struct airoha_gdm_port *port,
|
||||
+static int airoha_qdma_set_rx_meter(struct airoha_gdm_dev *dev,
|
||||
u32 rate, u32 bucket_size,
|
||||
enum trtcm_unit_type unit_type)
|
||||
{
|
||||
- struct airoha_qdma *qdma = port->qdma;
|
||||
+ struct airoha_qdma *qdma = dev->qdma;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
|
||||
@@ -2949,7 +2947,6 @@ static int airoha_dev_tc_matchall(struct
|
||||
{
|
||||
enum trtcm_unit_type unit_type = TRTCM_BYTE_UNIT;
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
- struct airoha_gdm_port *port = dev->port;
|
||||
u32 rate = 0, bucket_size = 0;
|
||||
|
||||
switch (f->command) {
|
||||
@@ -2974,7 +2971,7 @@ static int airoha_dev_tc_matchall(struct
|
||||
fallthrough;
|
||||
}
|
||||
case TC_CLSMATCHALL_DESTROY:
|
||||
- return airoha_qdma_set_rx_meter(port, rate, bucket_size,
|
||||
+ return airoha_qdma_set_rx_meter(dev, rate, bucket_size,
|
||||
unit_type);
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
@@ -2986,8 +2983,7 @@ static int airoha_dev_setup_tc_block_cb(
|
||||
{
|
||||
struct net_device *netdev = cb_priv;
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
- struct airoha_gdm_port *port = dev->port;
|
||||
- struct airoha_eth *eth = port->qdma->eth;
|
||||
+ struct airoha_eth *eth = dev->eth;
|
||||
|
||||
if (!tc_can_offload(netdev))
|
||||
return -EOPNOTSUPP;
|
||||
@@ -3222,7 +3218,7 @@ static void airoha_mac_link_up(struct ph
|
||||
struct airoha_gdm_dev *dev = container_of(config, struct airoha_gdm_dev,
|
||||
phylink_config);
|
||||
struct airoha_gdm_port *port = dev->port;
|
||||
- struct airoha_qdma *qdma = port->qdma;
|
||||
+ struct airoha_qdma *qdma = dev->qdma;
|
||||
struct airoha_eth *eth = qdma->eth;
|
||||
u32 frag_size_tx, frag_size_rx;
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
@@ -548,6 +548,7 @@ struct airoha_qdma {
|
||||
|
||||
struct airoha_gdm_dev {
|
||||
struct airoha_gdm_port *port;
|
||||
+ struct airoha_qdma *qdma;
|
||||
struct net_device *dev;
|
||||
struct airoha_eth *eth;
|
||||
|
||||
@@ -558,7 +559,6 @@ struct airoha_gdm_dev {
|
||||
};
|
||||
|
||||
struct airoha_gdm_port {
|
||||
- struct airoha_qdma *qdma;
|
||||
struct airoha_gdm_dev *dev;
|
||||
int id;
|
||||
int nbq;
|
||||
@@ -694,19 +694,18 @@ static inline bool airoha_qdma_is_lro_qu
|
||||
return !!(AIROHA_RXQ_LRO_EN_MASK & BIT(qid));
|
||||
}
|
||||
|
||||
-int airoha_get_fe_port(struct airoha_gdm_port *port);
|
||||
+int airoha_get_fe_port(struct airoha_gdm_dev *dev);
|
||||
bool airoha_is_valid_gdm_dev(struct airoha_eth *eth,
|
||||
struct airoha_gdm_dev *dev);
|
||||
|
||||
-void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id,
|
||||
- u8 fport);
|
||||
+void airoha_ppe_set_cpu_port(struct airoha_gdm_dev *dev, u8 ppe_id, u8 fport);
|
||||
bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index);
|
||||
void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb,
|
||||
u16 hash, bool rx_wlan);
|
||||
int airoha_ppe_setup_tc_block_cb(struct airoha_ppe_dev *dev, void *type_data);
|
||||
int airoha_ppe_init(struct airoha_eth *eth);
|
||||
void airoha_ppe_deinit(struct airoha_eth *eth);
|
||||
-void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port);
|
||||
+void airoha_ppe_init_upd_mem(struct airoha_gdm_dev *dev);
|
||||
u32 airoha_ppe_get_total_num_entries(struct airoha_ppe *ppe);
|
||||
struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe,
|
||||
u32 hash);
|
||||
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
|
||||
@@ -85,9 +85,9 @@ static u32 airoha_ppe_get_timestamp(stru
|
||||
AIROHA_FOE_IB1_BIND_TIMESTAMP);
|
||||
}
|
||||
|
||||
-void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id, u8 fport)
|
||||
+void airoha_ppe_set_cpu_port(struct airoha_gdm_dev *dev, u8 ppe_id, u8 fport)
|
||||
{
|
||||
- struct airoha_qdma *qdma = port->qdma;
|
||||
+ struct airoha_qdma *qdma = dev->qdma;
|
||||
struct airoha_eth *eth = qdma->eth;
|
||||
u8 qdma_id = qdma - ð->qdma[0];
|
||||
u32 fe_cpu_port;
|
||||
@@ -181,8 +181,8 @@ static void airoha_ppe_hw_init(struct ai
|
||||
if (!port)
|
||||
continue;
|
||||
|
||||
- airoha_ppe_set_cpu_port(port, i,
|
||||
- airoha_get_fe_port(port));
|
||||
+ airoha_ppe_set_cpu_port(port->dev, i,
|
||||
+ airoha_get_fe_port(port->dev));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1483,11 +1483,12 @@ void airoha_ppe_check_skb(struct airoha_
|
||||
airoha_ppe_foe_insert_entry(ppe, skb, hash, rx_wlan);
|
||||
}
|
||||
|
||||
-void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port)
|
||||
+void airoha_ppe_init_upd_mem(struct airoha_gdm_dev *dev)
|
||||
{
|
||||
- struct airoha_eth *eth = port->qdma->eth;
|
||||
- struct net_device *dev = port->dev->dev;
|
||||
- const u8 *addr = dev->dev_addr;
|
||||
+ struct airoha_gdm_port *port = dev->port;
|
||||
+ struct net_device *netdev = dev->dev;
|
||||
+ struct airoha_eth *eth = dev->eth;
|
||||
+ const u8 *addr = netdev->dev_addr;
|
||||
u32 val;
|
||||
|
||||
val = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5];
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
From 32bfd008c19f9ad55514181d8cd02e14bf384475 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <32bfd008c19f9ad55514181d8cd02e14bf384475.1779348625.git.lorenzo@kernel.org>
|
||||
In-Reply-To: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
|
||||
References: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Sat, 13 Dec 2025 10:06:45 +0100
|
||||
Subject: [PATCH 03/13] net: airoha: Rely on airoha_gdm_dev pointer in
|
||||
airoha_is_lan_gdm_port()
|
||||
|
||||
Rename airoha_is_lan_gdm_port in airoha_is_lan_gdm_dev. Moreover, rely
|
||||
on airoha_gdm_dev pointer in airoha_is_lan_gdm_dev() instead of
|
||||
airoha_gdm_port one.
|
||||
This is a preliminary patch to support multiple net_devices connected to
|
||||
the same GDM{3,4} port via an external hw arbiter.
|
||||
|
||||
Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 6 ++----
|
||||
drivers/net/ethernet/airoha/airoha_eth.h | 4 +++-
|
||||
drivers/net/ethernet/airoha/airoha_ppe.c | 2 +-
|
||||
3 files changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -82,12 +82,10 @@ static bool airhoa_is_phy_external(struc
|
||||
|
||||
static void airoha_set_macaddr(struct airoha_gdm_dev *dev, const u8 *addr)
|
||||
{
|
||||
- struct airoha_gdm_port *port = dev->port;
|
||||
struct airoha_eth *eth = dev->eth;
|
||||
u32 val, reg;
|
||||
|
||||
- reg = airoha_is_lan_gdm_port(port) ? REG_FE_LAN_MAC_H
|
||||
- : REG_FE_WAN_MAC_H;
|
||||
+ reg = airoha_is_lan_gdm_dev(dev) ? REG_FE_LAN_MAC_H : REG_FE_WAN_MAC_H;
|
||||
val = (addr[0] << 16) | (addr[1] << 8) | addr[2];
|
||||
airoha_fe_wr(eth, reg, val);
|
||||
|
||||
@@ -2028,7 +2026,7 @@ static int airoha_dev_init(struct net_de
|
||||
int i;
|
||||
|
||||
/* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */
|
||||
- dev->qdma = ð->qdma[!airoha_is_lan_gdm_port(port)];
|
||||
+ dev->qdma = ð->qdma[!airoha_is_lan_gdm_dev(dev)];
|
||||
dev->dev->irq = dev->qdma->irq_banks[0].irq;
|
||||
airoha_set_macaddr(dev, netdev->dev_addr);
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
@@ -663,8 +663,10 @@ static inline u16 airoha_qdma_get_txq(st
|
||||
return qid % ARRAY_SIZE(qdma->q_tx);
|
||||
}
|
||||
|
||||
-static inline bool airoha_is_lan_gdm_port(struct airoha_gdm_port *port)
|
||||
+static inline bool airoha_is_lan_gdm_dev(struct airoha_gdm_dev *dev)
|
||||
{
|
||||
+ struct airoha_gdm_port *port = dev->port;
|
||||
+
|
||||
/* GDM1 port on EN7581 SoC is connected to the lan dsa switch.
|
||||
* GDM{2,3,4} can be used as wan port connected to an external
|
||||
* phy module.
|
||||
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
|
||||
@@ -365,7 +365,7 @@ static int airoha_ppe_foe_entry_prepare(
|
||||
/* For downlink traffic consume SRAM memory for hw
|
||||
* forwarding descriptors queue.
|
||||
*/
|
||||
- if (airoha_is_lan_gdm_port(port))
|
||||
+ if (airoha_is_lan_gdm_dev(dev))
|
||||
val |= AIROHA_FOE_IB2_FAST_PATH;
|
||||
if (dsa_port >= 0)
|
||||
val |= FIELD_PREP(AIROHA_FOE_IB2_NBQ,
|
||||
+184
@@ -0,0 +1,184 @@
|
||||
From 634d75285db77f3385aa85a1bf2b185396225100 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <634d75285db77f3385aa85a1bf2b185396225100.1779348625.git.lorenzo@kernel.org>
|
||||
In-Reply-To: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
|
||||
References: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Fri, 10 Apr 2026 14:35:32 +0200
|
||||
Subject: [PATCH 04/13] net: airoha: Move qos_sq_bmap in airoha_gdm_dev struct
|
||||
|
||||
Since now multiple net_devices connected to different QDMA blocks can
|
||||
share the same GDM port, qos_sq_bmap field can be overwritten with the
|
||||
configuration obtained from a net_device connected to a different QDMA
|
||||
block. In order to fix the issue move qos_sq_bmap field from
|
||||
airoha_gdm_port struct to airoha_gdm_dev one.
|
||||
Add qos_channel_map bitmap in airoha_qdma struct to track if a shared
|
||||
QDMA channel is already in use by another net_device.
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 58 +++++++++++++++---------
|
||||
drivers/net/ethernet/airoha/airoha_eth.h | 6 ++-
|
||||
2 files changed, 40 insertions(+), 24 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -2822,30 +2822,40 @@ static int airoha_qdma_set_tx_rate_limit
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int airoha_tc_htb_alloc_leaf_queue(struct net_device *netdev,
|
||||
- struct tc_htb_qopt_offload *opt)
|
||||
+static int airoha_tc_htb_modify_queue(struct net_device *dev,
|
||||
+ struct tc_htb_qopt_offload *opt)
|
||||
{
|
||||
u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
|
||||
u32 rate = div_u64(opt->rate, 1000) << 3; /* kbps */
|
||||
- int err, num_tx_queues = netdev->real_num_tx_queues;
|
||||
- struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
- struct airoha_gdm_port *port = dev->port;
|
||||
|
||||
if (opt->parent_classid != TC_HTB_CLASSID_ROOT) {
|
||||
NL_SET_ERR_MSG_MOD(opt->extack, "invalid parent classid");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- err = airoha_qdma_set_tx_rate_limit(netdev, channel, rate,
|
||||
- opt->quantum);
|
||||
- if (err) {
|
||||
+ return airoha_qdma_set_tx_rate_limit(dev, channel, rate, opt->quantum);
|
||||
+}
|
||||
+
|
||||
+static int airoha_tc_htb_alloc_leaf_queue(struct net_device *netdev,
|
||||
+ struct tc_htb_qopt_offload *opt)
|
||||
+{
|
||||
+ u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
|
||||
+ int err, num_tx_queues = netdev->real_num_tx_queues;
|
||||
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
+ struct airoha_qdma *qdma = dev->qdma;
|
||||
+
|
||||
+ /* Here we need to check the requested QDMA channel is not already
|
||||
+ * in use by another net_device running on the same QDMA block.
|
||||
+ */
|
||||
+ if (test_and_set_bit(channel, qdma->qos_channel_map)) {
|
||||
NL_SET_ERR_MSG_MOD(opt->extack,
|
||||
- "failed configuring htb offload");
|
||||
- return err;
|
||||
+ "qdma qos channel already in use");
|
||||
+ return -EBUSY;
|
||||
}
|
||||
|
||||
- if (opt->command == TC_HTB_NODE_MODIFY)
|
||||
- return 0;
|
||||
+ err = airoha_tc_htb_modify_queue(netdev, opt);
|
||||
+ if (err)
|
||||
+ goto error;
|
||||
|
||||
err = netif_set_real_num_tx_queues(netdev, num_tx_queues + 1);
|
||||
if (err) {
|
||||
@@ -2853,13 +2863,17 @@ static int airoha_tc_htb_alloc_leaf_queu
|
||||
opt->quantum);
|
||||
NL_SET_ERR_MSG_MOD(opt->extack,
|
||||
"failed setting real_num_tx_queues");
|
||||
- return err;
|
||||
+ goto error;
|
||||
}
|
||||
|
||||
- set_bit(channel, port->qos_sq_bmap);
|
||||
+ set_bit(channel, dev->qos_sq_bmap);
|
||||
opt->qid = AIROHA_NUM_TX_RING + channel;
|
||||
|
||||
return 0;
|
||||
+error:
|
||||
+ clear_bit(channel, qdma->qos_channel_map);
|
||||
+
|
||||
+ return err;
|
||||
}
|
||||
|
||||
static int airoha_qdma_set_rx_meter(struct airoha_gdm_dev *dev,
|
||||
@@ -3040,11 +3054,13 @@ static int airoha_dev_setup_tc_block(str
|
||||
static void airoha_tc_remove_htb_queue(struct net_device *netdev, int queue)
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
- struct airoha_gdm_port *port = dev->port;
|
||||
+ struct airoha_qdma *qdma = dev->qdma;
|
||||
|
||||
netif_set_real_num_tx_queues(netdev, netdev->real_num_tx_queues - 1);
|
||||
airoha_qdma_set_tx_rate_limit(netdev, queue + 1, 0, 0);
|
||||
- clear_bit(queue, port->qos_sq_bmap);
|
||||
+
|
||||
+ clear_bit(queue, qdma->qos_channel_map);
|
||||
+ clear_bit(queue, dev->qos_sq_bmap);
|
||||
}
|
||||
|
||||
static int airoha_tc_htb_delete_leaf_queue(struct net_device *netdev,
|
||||
@@ -3052,9 +3068,8 @@ static int airoha_tc_htb_delete_leaf_que
|
||||
{
|
||||
u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
- struct airoha_gdm_port *port = dev->port;
|
||||
|
||||
- if (!test_bit(channel, port->qos_sq_bmap)) {
|
||||
+ if (!test_bit(channel, dev->qos_sq_bmap)) {
|
||||
NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id");
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -3067,10 +3082,9 @@ static int airoha_tc_htb_delete_leaf_que
|
||||
static int airoha_tc_htb_destroy(struct net_device *netdev)
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
- struct airoha_gdm_port *port = dev->port;
|
||||
int q;
|
||||
|
||||
- for_each_set_bit(q, port->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS)
|
||||
+ for_each_set_bit(q, dev->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS)
|
||||
airoha_tc_remove_htb_queue(netdev, q);
|
||||
|
||||
return 0;
|
||||
@@ -3081,9 +3095,8 @@ static int airoha_tc_get_htb_get_leaf_qu
|
||||
{
|
||||
u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
- struct airoha_gdm_port *port = dev->port;
|
||||
|
||||
- if (!test_bit(channel, port->qos_sq_bmap)) {
|
||||
+ if (!test_bit(channel, dev->qos_sq_bmap)) {
|
||||
NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id");
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -3102,6 +3115,7 @@ static int airoha_tc_setup_qdisc_htb(str
|
||||
case TC_HTB_DESTROY:
|
||||
return airoha_tc_htb_destroy(dev);
|
||||
case TC_HTB_NODE_MODIFY:
|
||||
+ return airoha_tc_htb_modify_queue(dev, opt);
|
||||
case TC_HTB_LEAF_ALLOC_QUEUE:
|
||||
return airoha_tc_htb_alloc_leaf_queue(dev, opt);
|
||||
case TC_HTB_LEAF_DEL:
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
@@ -544,6 +544,8 @@ struct airoha_qdma {
|
||||
|
||||
struct airoha_queue q_tx[AIROHA_NUM_TX_RING];
|
||||
struct airoha_queue q_rx[AIROHA_NUM_RX_RING];
|
||||
+
|
||||
+ DECLARE_BITMAP(qos_channel_map, AIROHA_NUM_QOS_CHANNELS);
|
||||
};
|
||||
|
||||
struct airoha_gdm_dev {
|
||||
@@ -556,6 +558,8 @@ struct airoha_gdm_dev {
|
||||
struct phylink *phylink;
|
||||
struct phylink_config phylink_config;
|
||||
#endif
|
||||
+
|
||||
+ DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS);
|
||||
};
|
||||
|
||||
struct airoha_gdm_port {
|
||||
@@ -565,8 +569,6 @@ struct airoha_gdm_port {
|
||||
|
||||
struct airoha_hw_stats stats;
|
||||
|
||||
- DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS);
|
||||
-
|
||||
/* qos stats counters */
|
||||
u64 cpu_tx_packets;
|
||||
u64 fwd_tx_packets;
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
From 00272dbf6a52241a21145631f22dc5f03891078b Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <00272dbf6a52241a21145631f22dc5f03891078b.1779348625.git.lorenzo@kernel.org>
|
||||
In-Reply-To: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
|
||||
References: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Fri, 10 Apr 2026 14:47:08 +0200
|
||||
Subject: [PATCH 05/13] net: airoha: Move {cpu,fwd}_tx_packets in
|
||||
airoha_gdm_dev struct
|
||||
|
||||
Since now multiple net_devices connected to different QDMA blocks can
|
||||
share the same GDM port, cpu_tx_packets and fwd_tx_packets fields can
|
||||
be overwritten with the value from a different QDMA block. In order to
|
||||
fix the issue move cpu_tx_packets and fwd_tx_packets fields from
|
||||
airoha_gdm_port struct to airoha_gdm_dev one.
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 16 +++++++---------
|
||||
drivers/net/ethernet/airoha/airoha_eth.h | 7 +++----
|
||||
2 files changed, 10 insertions(+), 13 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -2535,19 +2535,17 @@ static int airoha_qdma_get_tx_ets_stats(
|
||||
struct tc_ets_qopt_offload *opt)
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
- struct airoha_gdm_port *port = dev->port;
|
||||
+ struct airoha_qdma *qdma = dev->qdma;
|
||||
|
||||
- u64 cpu_tx_packets = airoha_qdma_rr(dev->qdma,
|
||||
- REG_CNTR_VAL(channel << 1));
|
||||
- u64 fwd_tx_packets = airoha_qdma_rr(dev->qdma,
|
||||
+ u64 cpu_tx_packets = airoha_qdma_rr(qdma, REG_CNTR_VAL(channel << 1));
|
||||
+ u64 fwd_tx_packets = airoha_qdma_rr(qdma,
|
||||
REG_CNTR_VAL((channel << 1) + 1));
|
||||
- u64 tx_packets = (cpu_tx_packets - port->cpu_tx_packets) +
|
||||
- (fwd_tx_packets - port->fwd_tx_packets);
|
||||
+ u64 tx_packets = (cpu_tx_packets - dev->cpu_tx_packets) +
|
||||
+ (fwd_tx_packets - dev->fwd_tx_packets);
|
||||
|
||||
_bstats_update(opt->stats.bstats, 0, tx_packets);
|
||||
-
|
||||
- port->cpu_tx_packets = cpu_tx_packets;
|
||||
- port->fwd_tx_packets = fwd_tx_packets;
|
||||
+ dev->cpu_tx_packets = cpu_tx_packets;
|
||||
+ dev->fwd_tx_packets = fwd_tx_packets;
|
||||
|
||||
return 0;
|
||||
}
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
@@ -560,6 +560,9 @@ struct airoha_gdm_dev {
|
||||
#endif
|
||||
|
||||
DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS);
|
||||
+ /* qos stats counters */
|
||||
+ u64 cpu_tx_packets;
|
||||
+ u64 fwd_tx_packets;
|
||||
};
|
||||
|
||||
struct airoha_gdm_port {
|
||||
@@ -569,10 +572,6 @@ struct airoha_gdm_port {
|
||||
|
||||
struct airoha_hw_stats stats;
|
||||
|
||||
- /* qos stats counters */
|
||||
- u64 cpu_tx_packets;
|
||||
- u64 fwd_tx_packets;
|
||||
-
|
||||
struct metadata_dst *dsa_meta[AIROHA_MAX_DSA_PORTS];
|
||||
};
|
||||
|
||||
+714
@@ -0,0 +1,714 @@
|
||||
From 8eb0a71bfbe92b6fbc668c5d9ebdcbf6523a89ad Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <8eb0a71bfbe92b6fbc668c5d9ebdcbf6523a89ad.1779348625.git.lorenzo@kernel.org>
|
||||
In-Reply-To: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
|
||||
References: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Sat, 1 Nov 2025 11:27:48 +0100
|
||||
Subject: [PATCH 06/13] net: airoha: Support multiple net_devices for a single
|
||||
FE GDM port
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
EN7581 or AN7583 SoCs support connecting multiple external SerDes (e.g.
|
||||
Ethernet or USB SerDes) to GDM3 or GDM4 ports via a hw arbiter that
|
||||
manages the traffic in a TDM manner. As a result multiple net_devices can
|
||||
connect to the same GDM{3,4} port and there is a theoretical "1:n"
|
||||
relation between GDM ports and net_devices.
|
||||
|
||||
┌─────────────────────────────────┐
|
||||
│ │ ┌──────┐
|
||||
│ P1 GDM1 ├────►MT7530│
|
||||
│ │ └──────┘
|
||||
│ │ ETH0 (DSA conduit)
|
||||
│ │
|
||||
│ PSE/FE │
|
||||
│ │
|
||||
│ │
|
||||
│ │ ┌─────┐
|
||||
│ P0 CDM1 ├────►QDMA0│
|
||||
│ P4 P9 GDM4 │ └─────┘
|
||||
└──┬─────────────────────────┬────┘
|
||||
│ │
|
||||
┌──▼──┐ ┌────▼────┐
|
||||
│ PPE │ │ ARB │
|
||||
└─────┘ └─┬─────┬─┘
|
||||
│ │
|
||||
┌──▼──┐┌─▼───┐
|
||||
│ ETH ││ USB │
|
||||
└─────┘└─────┘
|
||||
ETH1 ETH2
|
||||
|
||||
Introduce support for multiple net_devices connected to the same Frame
|
||||
Engine (FE) GDM port (GDM3 or GDM4) via an external hw arbiter.
|
||||
Please note GDM1 or GDM2 does not support the connection with the external
|
||||
arbiter.
|
||||
Add get_dev_from_sport callback since EN7581 and AN7583 have different
|
||||
logics for the net_device type connected to GDM3 or GDM4.
|
||||
|
||||
Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 274 +++++++++++++++++------
|
||||
drivers/net/ethernet/airoha/airoha_eth.h | 10 +-
|
||||
drivers/net/ethernet/airoha/airoha_ppe.c | 13 +-
|
||||
3 files changed, 228 insertions(+), 69 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -115,7 +115,7 @@ static int airoha_set_vip_for_gdm_port(s
|
||||
struct airoha_eth *eth = dev->eth;
|
||||
u32 vip_port;
|
||||
|
||||
- vip_port = eth->soc->ops.get_vip_port(port, port->nbq);
|
||||
+ vip_port = eth->soc->ops.get_vip_port(port, dev->nbq);
|
||||
if (enable) {
|
||||
airoha_fe_set(eth, REG_FE_VIP_PORT_EN, vip_port);
|
||||
airoha_fe_set(eth, REG_FE_IFC_PORT_EN, vip_port);
|
||||
@@ -618,30 +618,26 @@ static int airoha_qdma_fill_rx_queue(str
|
||||
return nframes;
|
||||
}
|
||||
|
||||
-static int airoha_qdma_get_gdm_port(struct airoha_eth *eth,
|
||||
- struct airoha_qdma_desc *desc)
|
||||
+static struct airoha_gdm_dev *
|
||||
+airoha_qdma_get_gdm_dev(struct airoha_eth *eth, struct airoha_qdma_desc *desc)
|
||||
{
|
||||
- u32 port, sport, msg1 = le32_to_cpu(READ_ONCE(desc->msg1));
|
||||
+ struct airoha_gdm_port *port;
|
||||
+ u16 p, d;
|
||||
|
||||
- sport = FIELD_GET(QDMA_ETH_RXMSG_SPORT_MASK, msg1);
|
||||
- switch (sport) {
|
||||
- case 0x18:
|
||||
- port = 3; /* GDM4 */
|
||||
- break;
|
||||
- case 0x16:
|
||||
- port = 2; /* GDM3 */
|
||||
- break;
|
||||
- case 0x10 ... 0x14:
|
||||
- port = 0; /* GDM1 */
|
||||
- break;
|
||||
- case 0x2 ... 0x4:
|
||||
- port = sport - 1;
|
||||
- break;
|
||||
- default:
|
||||
- return -EINVAL;
|
||||
- }
|
||||
+ if (eth->soc->ops.get_dev_from_sport(desc, &p, &d))
|
||||
+ return ERR_PTR(-ENODEV);
|
||||
+
|
||||
+ if (p >= ARRAY_SIZE(eth->ports))
|
||||
+ return ERR_PTR(-ENODEV);
|
||||
+
|
||||
+ port = eth->ports[p];
|
||||
+ if (!port)
|
||||
+ return ERR_PTR(-ENODEV);
|
||||
+
|
||||
+ if (d >= ARRAY_SIZE(port->devs))
|
||||
+ return ERR_PTR(-ENODEV);
|
||||
|
||||
- return port >= ARRAY_SIZE(eth->ports) ? -EINVAL : port;
|
||||
+ return port->devs[d] ? port->devs[d] : ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
static int airoha_qdma_lro_rx_process(struct airoha_queue *q,
|
||||
@@ -725,9 +721,8 @@ static int airoha_qdma_rx_process(struct
|
||||
struct airoha_queue_entry *e = &q->entry[q->tail];
|
||||
struct airoha_qdma_desc *desc = &q->desc[q->tail];
|
||||
u32 hash, reason, msg1, desc_ctrl;
|
||||
- struct airoha_gdm_port *port;
|
||||
- struct net_device *netdev;
|
||||
- int data_len, len, p;
|
||||
+ struct airoha_gdm_dev *dev;
|
||||
+ int data_len, len;
|
||||
struct page *page;
|
||||
|
||||
desc_ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
|
||||
@@ -748,15 +743,10 @@ static int airoha_qdma_rx_process(struct
|
||||
if (!len || data_len < len)
|
||||
goto free_frag;
|
||||
|
||||
- p = airoha_qdma_get_gdm_port(eth, desc);
|
||||
- if (p < 0 || !eth->ports[p])
|
||||
- goto free_frag;
|
||||
-
|
||||
- port = eth->ports[p];
|
||||
- if (!port->dev)
|
||||
+ dev = airoha_qdma_get_gdm_dev(eth, desc);
|
||||
+ if (IS_ERR(dev))
|
||||
goto free_frag;
|
||||
|
||||
- netdev = port->dev->dev;
|
||||
if (!q->skb) { /* first buffer */
|
||||
q->skb = napi_build_skb(e->buf - AIROHA_RX_HEADROOM,
|
||||
q->buf_size);
|
||||
@@ -766,15 +756,15 @@ static int airoha_qdma_rx_process(struct
|
||||
skb_reserve(q->skb, AIROHA_RX_HEADROOM);
|
||||
__skb_put(q->skb, len);
|
||||
skb_mark_for_recycle(q->skb);
|
||||
- q->skb->dev = netdev;
|
||||
+ q->skb->dev = dev->dev;
|
||||
q->skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
skb_record_rx_queue(q->skb, qid);
|
||||
|
||||
- if (lro_q && (netdev->features & NETIF_F_LRO) &&
|
||||
+ if (lro_q && (dev->dev->features & NETIF_F_LRO) &&
|
||||
airoha_qdma_lro_rx_process(q, desc) < 0)
|
||||
goto free_frag;
|
||||
|
||||
- q->skb->protocol = eth_type_trans(q->skb, netdev);
|
||||
+ q->skb->protocol = eth_type_trans(q->skb, dev->dev);
|
||||
} else { /* scattered frame */
|
||||
struct skb_shared_info *shinfo = skb_shinfo(q->skb);
|
||||
int nr_frags = shinfo->nr_frags;
|
||||
@@ -790,7 +780,9 @@ static int airoha_qdma_rx_process(struct
|
||||
if (FIELD_GET(QDMA_DESC_MORE_MASK, desc_ctrl))
|
||||
continue;
|
||||
|
||||
- if (netdev_uses_dsa(netdev)) {
|
||||
+ if (netdev_uses_dsa(dev->dev)) {
|
||||
+ struct airoha_gdm_port *port = dev->port;
|
||||
+
|
||||
/* PPE module requires untagged packets to work
|
||||
* properly and it provides DSA port index via the
|
||||
* DMA descriptor. Report DSA tag to the DSA stack
|
||||
@@ -987,24 +979,27 @@ static void airoha_qdma_wake_netdev_txqs
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
struct airoha_gdm_port *port = eth->ports[i];
|
||||
- struct airoha_gdm_dev *dev;
|
||||
- int j;
|
||||
+ int d;
|
||||
|
||||
if (!port)
|
||||
continue;
|
||||
|
||||
- dev = port->dev;
|
||||
- if (!dev)
|
||||
- continue;
|
||||
+ for (d = 0; d < ARRAY_SIZE(port->devs); d++) {
|
||||
+ struct airoha_gdm_dev *dev = port->devs[d];
|
||||
+ int j;
|
||||
|
||||
- if (dev->qdma != qdma)
|
||||
- continue;
|
||||
+ if (!dev)
|
||||
+ continue;
|
||||
|
||||
- for (j = 0; j < dev->dev->num_tx_queues; j++) {
|
||||
- if (airoha_qdma_get_txq(qdma, j) != qid)
|
||||
+ if (dev->qdma != qdma)
|
||||
continue;
|
||||
|
||||
- netif_wake_subqueue(dev->dev, j);
|
||||
+ for (j = 0; j < dev->dev->num_tx_queues; j++) {
|
||||
+ if (airoha_qdma_get_txq(qdma, j) != qid)
|
||||
+ continue;
|
||||
+
|
||||
+ netif_wake_subqueue(dev->dev, j);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
q->txq_stopped = false;
|
||||
@@ -1893,11 +1888,9 @@ static int airoha_dev_open(struct net_de
|
||||
GLOBAL_CFG_RX_DMA_EN_MASK);
|
||||
atomic_inc(&qdma->users);
|
||||
|
||||
- if (port->id == AIROHA_GDM2_IDX &&
|
||||
- airoha_ppe_is_enabled(qdma->eth, 1)) {
|
||||
- /* For PPE2 always use secondary cpu port. */
|
||||
+ if (!airoha_is_lan_gdm_dev(dev) &&
|
||||
+ airoha_ppe_is_enabled(qdma->eth, 1))
|
||||
pse_port = FE_PSE_PORT_PPE2;
|
||||
- }
|
||||
airoha_set_gdm_port_fwd_cfg(qdma->eth, REG_GDM_FWD_CFG(port->id),
|
||||
pse_port);
|
||||
|
||||
@@ -1992,7 +1985,7 @@ static int airoha_set_gdm2_loopback(stru
|
||||
airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(AIROHA_GDM2_IDX));
|
||||
airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(AIROHA_GDM2_IDX));
|
||||
|
||||
- src_port = eth->soc->ops.get_sport(port, port->nbq);
|
||||
+ src_port = eth->soc->ops.get_sport(port, dev->nbq);
|
||||
if (src_port < 0)
|
||||
return src_port;
|
||||
|
||||
@@ -2009,7 +2002,7 @@ static int airoha_set_gdm2_loopback(stru
|
||||
airoha_ppe_set_cpu_port(dev, i, AIROHA_GDM2_IDX);
|
||||
|
||||
if (port->id == AIROHA_GDM4_IDX && airoha_is_7581(eth)) {
|
||||
- u32 mask = FC_ID_OF_SRC_PORT_MASK(port->nbq);
|
||||
+ u32 mask = FC_ID_OF_SRC_PORT_MASK(dev->nbq);
|
||||
|
||||
airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6, mask,
|
||||
__field_prep(mask, AIROHA_GDM2_IDX));
|
||||
@@ -2023,7 +2016,7 @@ static int airoha_dev_init(struct net_de
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
struct airoha_gdm_port *port = dev->port;
|
||||
struct airoha_eth *eth = dev->eth;
|
||||
- int i;
|
||||
+ int ppe_id;
|
||||
|
||||
/* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */
|
||||
dev->qdma = ð->qdma[!airoha_is_lan_gdm_dev(dev)];
|
||||
@@ -2046,8 +2039,8 @@ static int airoha_dev_init(struct net_de
|
||||
break;
|
||||
}
|
||||
|
||||
- for (i = 0; i < eth->soc->num_ppe; i++)
|
||||
- airoha_ppe_set_cpu_port(dev, i, airoha_get_fe_port(dev));
|
||||
+ ppe_id = !airoha_is_lan_gdm_dev(dev) && airoha_ppe_is_enabled(eth, 1);
|
||||
+ airoha_ppe_set_cpu_port(dev, ppe_id, airoha_get_fe_port(dev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2209,20 +2202,26 @@ static int airoha_dev_set_features(struc
|
||||
} else {
|
||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
struct airoha_gdm_port *p = eth->ports[i];
|
||||
- struct airoha_gdm_dev *d;
|
||||
+ int j;
|
||||
|
||||
if (!p)
|
||||
continue;
|
||||
|
||||
- d = p->dev;
|
||||
- if (d->qdma != qdma)
|
||||
- continue;
|
||||
+ for (j = 0; j < ARRAY_SIZE(p->devs); j++) {
|
||||
+ struct airoha_gdm_dev *d = p->devs[j];
|
||||
|
||||
- if (d->dev == netdev)
|
||||
- continue;
|
||||
+ if (!d)
|
||||
+ continue;
|
||||
|
||||
- if (d->dev->features & NETIF_F_LRO)
|
||||
- return 0;
|
||||
+ if (d->qdma != qdma)
|
||||
+ continue;
|
||||
+
|
||||
+ if (d->dev == netdev)
|
||||
+ continue;
|
||||
+
|
||||
+ if (d->dev->features & NETIF_F_LRO)
|
||||
+ return 0;
|
||||
+ }
|
||||
}
|
||||
airoha_fe_lro_disable(eth, qdma_id);
|
||||
}
|
||||
@@ -2273,7 +2272,8 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
}
|
||||
|
||||
fport = airoha_get_fe_port(dev);
|
||||
- msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) |
|
||||
+ msg1 = FIELD_PREP(QDMA_ETH_TXMSG_NBOQ_MASK, dev->nbq) |
|
||||
+ FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) |
|
||||
FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f);
|
||||
|
||||
q = &qdma->q_tx[qid];
|
||||
@@ -3209,12 +3209,15 @@ bool airoha_is_valid_gdm_dev(struct airo
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
struct airoha_gdm_port *port = eth->ports[i];
|
||||
+ int j;
|
||||
|
||||
if (!port)
|
||||
continue;
|
||||
|
||||
- if (port->dev == dev)
|
||||
- return true;
|
||||
+ for (j = 0; j < ARRAY_SIZE(port->devs); j++) {
|
||||
+ if (port->devs[j] == dev)
|
||||
+ return true;
|
||||
+ }
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -3338,10 +3341,11 @@ static int airoha_setup_phylink(struct n
|
||||
|
||||
static int airoha_alloc_gdm_device(struct airoha_eth *eth,
|
||||
struct airoha_gdm_port *port,
|
||||
- struct device_node *np)
|
||||
+ int nbq, struct device_node *np)
|
||||
{
|
||||
- struct airoha_gdm_dev *dev;
|
||||
struct net_device *netdev;
|
||||
+ struct airoha_gdm_dev *dev;
|
||||
+ u8 index;
|
||||
int err;
|
||||
|
||||
netdev = devm_alloc_etherdev_mqs(eth->dev, sizeof(*dev),
|
||||
@@ -3359,7 +3363,6 @@ static int airoha_alloc_gdm_device(struc
|
||||
netdev->hw_features = AIROHA_HW_FEATURES | NETIF_F_LRO;
|
||||
netdev->features |= AIROHA_HW_FEATURES;
|
||||
netdev->vlan_features = AIROHA_HW_FEATURES;
|
||||
- netdev->dev.of_node = np;
|
||||
SET_NETDEV_DEV(netdev, eth->dev);
|
||||
|
||||
/* reserve hw queues for HTB offloading */
|
||||
@@ -3377,11 +3380,25 @@ static int airoha_alloc_gdm_device(struc
|
||||
netdev->dev_addr);
|
||||
}
|
||||
|
||||
+ /* Allowed nbq for EN7581 on GDM3 port are 4 and 5 for PCIE0
|
||||
+ * and PCIE1 respectively.
|
||||
+ */
|
||||
+ index = nbq;
|
||||
+ if (index && airoha_is_7581(eth) && port->id == AIROHA_GDM3_IDX)
|
||||
+ index -= 4;
|
||||
+
|
||||
+ if (index >= ARRAY_SIZE(port->devs) || port->devs[index]) {
|
||||
+ dev_err(eth->dev, "invalid nbq id: %d\n", nbq);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ netdev->dev.of_node = of_node_get(np);
|
||||
dev = netdev_priv(netdev);
|
||||
dev->dev = netdev;
|
||||
dev->port = port;
|
||||
- port->dev = dev;
|
||||
dev->eth = eth;
|
||||
+ dev->nbq = nbq;
|
||||
+ port->devs[index] = dev;
|
||||
|
||||
#if defined(CONFIG_PCS_AIROHA)
|
||||
if (airhoa_is_phy_external(port)) {
|
||||
@@ -3399,7 +3416,8 @@ static int airoha_alloc_gdm_port(struct
|
||||
{
|
||||
const __be32 *id_ptr = of_get_property(np, "reg", NULL);
|
||||
struct airoha_gdm_port *port;
|
||||
- int err, p;
|
||||
+ struct device_node *node;
|
||||
+ int err, nbq, p, d = 0;
|
||||
u32 id;
|
||||
|
||||
if (!id_ptr) {
|
||||
@@ -3427,15 +3445,51 @@ static int airoha_alloc_gdm_port(struct
|
||||
u64_stats_init(&port->stats.syncp);
|
||||
spin_lock_init(&port->stats.lock);
|
||||
port->id = id;
|
||||
- /* XXX: Read nbq from DTS */
|
||||
- port->nbq = id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0;
|
||||
eth->ports[p] = port;
|
||||
|
||||
err = airoha_metadata_dst_alloc(port);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- return airoha_alloc_gdm_device(eth, port, np);
|
||||
+ /* Default nbq value to ensure backward compatibility */
|
||||
+ nbq = id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0;
|
||||
+
|
||||
+ for_each_child_of_node(np, node) {
|
||||
+ /* Multiple external serdes connected to the FE GDM port via an
|
||||
+ * external arbiter.
|
||||
+ */
|
||||
+ const __be32 *nbq_ptr;
|
||||
+
|
||||
+ if (!of_device_is_compatible(node, "airoha,eth-port"))
|
||||
+ continue;
|
||||
+
|
||||
+ d++;
|
||||
+ if (!of_device_is_available(node))
|
||||
+ continue;
|
||||
+
|
||||
+ nbq_ptr = of_get_property(node, "reg", NULL);
|
||||
+ if (!nbq_ptr) {
|
||||
+ dev_err(eth->dev, "missing nbq id\n");
|
||||
+ of_node_put(node);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ /* Verify the provided nbq parameter is valid */
|
||||
+ nbq = be32_to_cpup(nbq_ptr);
|
||||
+ err = eth->soc->ops.get_sport(port, nbq);
|
||||
+ if (err < 0) {
|
||||
+ of_node_put(node);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ err = airoha_alloc_gdm_device(eth, port, nbq, node);
|
||||
+ if (err) {
|
||||
+ of_node_put(node);
|
||||
+ return err;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return !d ? airoha_alloc_gdm_device(eth, port, nbq, np) : 0;
|
||||
}
|
||||
|
||||
static int airoha_register_gdm_devices(struct airoha_eth *eth)
|
||||
@@ -3444,14 +3498,22 @@ static int airoha_register_gdm_devices(s
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
struct airoha_gdm_port *port = eth->ports[i];
|
||||
- int err;
|
||||
+ int j;
|
||||
|
||||
if (!port)
|
||||
continue;
|
||||
|
||||
- err = register_netdev(port->dev->dev);
|
||||
- if (err)
|
||||
- return err;
|
||||
+ for (j = 0; j < ARRAY_SIZE(port->devs); j++) {
|
||||
+ struct airoha_gdm_dev *dev = port->devs[j];
|
||||
+ int err;
|
||||
+
|
||||
+ if (!dev)
|
||||
+ continue;
|
||||
+
|
||||
+ err = register_netdev(dev->dev);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ }
|
||||
}
|
||||
|
||||
set_bit(DEV_STATE_REGISTERED, ð->state);
|
||||
@@ -3558,18 +3620,27 @@ error_napi_stop:
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
struct airoha_gdm_port *port = eth->ports[i];
|
||||
- struct airoha_gdm_dev *dev;
|
||||
+ int j;
|
||||
|
||||
if (!port)
|
||||
continue;
|
||||
|
||||
- dev = port->dev;
|
||||
- if (dev && dev->dev->reg_state == NETREG_REGISTERED) {
|
||||
+ for (j = 0; j < ARRAY_SIZE(port->devs); j++) {
|
||||
+ struct airoha_gdm_dev *dev = port->devs[j];
|
||||
+ struct net_device *netdev;
|
||||
+
|
||||
+ if (!dev)
|
||||
+ continue;
|
||||
+
|
||||
+ netdev = dev->dev;
|
||||
+ if (netdev->reg_state == NETREG_REGISTERED) {
|
||||
#if defined(CONFIG_PCS_AIROHA)
|
||||
- if (airhoa_is_phy_external(port))
|
||||
- phylink_destroy(dev->phylink);
|
||||
+ if (airhoa_is_phy_external(port))
|
||||
+ phylink_destroy(dev->phylink);
|
||||
#endif
|
||||
- unregister_netdev(dev->dev);
|
||||
+ unregister_netdev(netdev);
|
||||
+ }
|
||||
+ of_node_put(netdev->dev.of_node);
|
||||
}
|
||||
airoha_metadata_dst_free(port);
|
||||
}
|
||||
@@ -3591,19 +3662,26 @@ static void airoha_remove(struct platfor
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
struct airoha_gdm_port *port = eth->ports[i];
|
||||
- struct airoha_gdm_dev *dev;
|
||||
+ int j;
|
||||
|
||||
if (!port)
|
||||
continue;
|
||||
|
||||
+ for (j = 0; j < ARRAY_SIZE(port->devs); j++) {
|
||||
+ struct airoha_gdm_dev *dev = port->devs[j];
|
||||
+ struct net_device *netdev;
|
||||
+
|
||||
+ if (!dev)
|
||||
+ continue;
|
||||
+
|
||||
#if defined(CONFIG_PCS_AIROHA)
|
||||
if (airhoa_is_phy_external(port))
|
||||
phylink_destroy(dev->phylink);
|
||||
#endif
|
||||
-
|
||||
- dev = port->dev;
|
||||
- if (dev)
|
||||
- unregister_netdev(dev->dev);
|
||||
+ netdev = dev->dev;
|
||||
+ unregister_netdev(netdev);
|
||||
+ of_node_put(netdev->dev.of_node);
|
||||
+ }
|
||||
airoha_metadata_dst_free(port);
|
||||
}
|
||||
airoha_hw_cleanup(eth);
|
||||
@@ -3665,6 +3743,39 @@ static u32 airoha_en7581_get_vip_port(st
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int airoha_en7581_get_dev_from_sport(struct airoha_qdma_desc *desc,
|
||||
+ u16 *port, u16 *dev)
|
||||
+{
|
||||
+ u32 sport = FIELD_GET(QDMA_ETH_RXMSG_SPORT_MASK,
|
||||
+ le32_to_cpu(READ_ONCE(desc->msg1)));
|
||||
+
|
||||
+ *dev = 0;
|
||||
+ switch (sport) {
|
||||
+ case 0x10 ... 0x14:
|
||||
+ *port = 0; /* GDM1 */
|
||||
+ break;
|
||||
+ case 0x2 ... 0x4:
|
||||
+ *port = sport - 1;
|
||||
+ break;
|
||||
+ case HSGMII_LAN_7581_PCIE1_SRCPORT:
|
||||
+ *dev = 1;
|
||||
+ fallthrough;
|
||||
+ case HSGMII_LAN_7581_PCIE0_SRCPORT:
|
||||
+ *port = 2; /* GDM3 */
|
||||
+ break;
|
||||
+ case HSGMII_LAN_7581_USB_SRCPORT:
|
||||
+ *dev = 1;
|
||||
+ fallthrough;
|
||||
+ case HSGMII_LAN_7581_ETH_SRCPORT:
|
||||
+ *port = 3; /* GDM4 */
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static const char * const an7583_xsi_rsts_names[] = {
|
||||
"hsi0-mac",
|
||||
"hsi1-mac",
|
||||
@@ -3713,6 +3824,36 @@ static u32 airoha_an7583_get_vip_port(st
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int airoha_an7583_get_dev_from_sport(struct airoha_qdma_desc *desc,
|
||||
+ u16 *port, u16 *dev)
|
||||
+{
|
||||
+ u32 sport = FIELD_GET(QDMA_ETH_RXMSG_SPORT_MASK,
|
||||
+ le32_to_cpu(READ_ONCE(desc->msg1)));
|
||||
+
|
||||
+ *dev = 0;
|
||||
+ switch (sport) {
|
||||
+ case 0x10 ... 0x14:
|
||||
+ *port = 0; /* GDM1 */
|
||||
+ break;
|
||||
+ case 0x2 ... 0x4:
|
||||
+ *port = sport - 1;
|
||||
+ break;
|
||||
+ case HSGMII_LAN_7583_ETH_SRCPORT:
|
||||
+ *port = 2; /* GDM3 */
|
||||
+ break;
|
||||
+ case HSGMII_LAN_7583_USB_SRCPORT:
|
||||
+ *dev = 1;
|
||||
+ fallthrough;
|
||||
+ case HSGMII_LAN_7583_PCIE_SRCPORT:
|
||||
+ *port = 3; /* GDM4 */
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static const struct airoha_eth_soc_data en7581_soc_data = {
|
||||
.version = 0x7581,
|
||||
.xsi_rsts_names = en7581_xsi_rsts_names,
|
||||
@@ -3721,6 +3862,7 @@ static const struct airoha_eth_soc_data
|
||||
.ops = {
|
||||
.get_sport = airoha_en7581_get_sport,
|
||||
.get_vip_port = airoha_en7581_get_vip_port,
|
||||
+ .get_dev_from_sport = airoha_en7581_get_dev_from_sport,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -3732,6 +3874,7 @@ static const struct airoha_eth_soc_data
|
||||
.ops = {
|
||||
.get_sport = airoha_an7583_get_sport,
|
||||
.get_vip_port = airoha_an7583_get_vip_port,
|
||||
+ .get_dev_from_sport = airoha_an7583_get_dev_from_sport,
|
||||
},
|
||||
};
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <net/dsa.h>
|
||||
|
||||
#define AIROHA_MAX_NUM_GDM_PORTS 4
|
||||
+#define AIROHA_MAX_NUM_GDM_DEVS 2
|
||||
#define AIROHA_MAX_NUM_QDMA 2
|
||||
#define AIROHA_MAX_NUM_IRQ_BANKS 4
|
||||
#define AIROHA_MAX_DSA_PORTS 7
|
||||
@@ -551,8 +552,8 @@ struct airoha_qdma {
|
||||
struct airoha_gdm_dev {
|
||||
struct airoha_gdm_port *port;
|
||||
struct airoha_qdma *qdma;
|
||||
- struct net_device *dev;
|
||||
struct airoha_eth *eth;
|
||||
+ struct net_device *dev;
|
||||
|
||||
#if defined(CONFIG_PCS_AIROHA)
|
||||
struct phylink *phylink;
|
||||
@@ -563,12 +564,13 @@ struct airoha_gdm_dev {
|
||||
/* qos stats counters */
|
||||
u64 cpu_tx_packets;
|
||||
u64 fwd_tx_packets;
|
||||
+
|
||||
+ int nbq;
|
||||
};
|
||||
|
||||
struct airoha_gdm_port {
|
||||
- struct airoha_gdm_dev *dev;
|
||||
+ struct airoha_gdm_dev *devs[AIROHA_MAX_NUM_GDM_DEVS];
|
||||
int id;
|
||||
- int nbq;
|
||||
|
||||
struct airoha_hw_stats stats;
|
||||
|
||||
@@ -604,6 +606,8 @@ struct airoha_eth_soc_data {
|
||||
struct {
|
||||
int (*get_sport)(struct airoha_gdm_port *port, int nbq);
|
||||
u32 (*get_vip_port)(struct airoha_gdm_port *port, int nbq);
|
||||
+ int (*get_dev_from_sport)(struct airoha_qdma_desc *desc,
|
||||
+ u16 *port, u16 *dev);
|
||||
} ops;
|
||||
};
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
|
||||
@@ -168,9 +168,7 @@ static void airoha_ppe_hw_init(struct ai
|
||||
airoha_fe_clear(eth, REG_PPE_PPE_FLOW_CFG(i),
|
||||
PPE_FLOW_CFG_IP6_6RD_MASK);
|
||||
|
||||
- for (p = 0; p < ARRAY_SIZE(eth->ports); p++) {
|
||||
- struct airoha_gdm_port *port = eth->ports[p];
|
||||
-
|
||||
+ for (p = 0; p < ARRAY_SIZE(eth->ports); p++)
|
||||
airoha_fe_rmw(eth, REG_PPE_MTU(i, p),
|
||||
FP0_EGRESS_MTU_MASK |
|
||||
FP1_EGRESS_MTU_MASK,
|
||||
@@ -178,11 +176,24 @@ static void airoha_ppe_hw_init(struct ai
|
||||
AIROHA_MAX_MTU) |
|
||||
FIELD_PREP(FP1_EGRESS_MTU_MASK,
|
||||
AIROHA_MAX_MTU));
|
||||
- if (!port)
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
+ struct airoha_gdm_port *port = eth->ports[i];
|
||||
+ int j;
|
||||
+
|
||||
+ if (!port)
|
||||
+ continue;
|
||||
+
|
||||
+ for (j = 0; j < ARRAY_SIZE(port->devs); j++) {
|
||||
+ struct airoha_gdm_dev *dev = port->devs[j];
|
||||
+ u8 fport;
|
||||
+
|
||||
+ if (!dev)
|
||||
continue;
|
||||
|
||||
- airoha_ppe_set_cpu_port(port->dev, i,
|
||||
- airoha_get_fe_port(port->dev));
|
||||
+ fport = airoha_get_fe_port(dev);
|
||||
+ airoha_ppe_set_cpu_port(dev, i, fport);
|
||||
}
|
||||
}
|
||||
}
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
From de856a5b802cf030c8e242e98df3bc88446a4ea1 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <de856a5b802cf030c8e242e98df3bc88446a4ea1.1779348625.git.lorenzo@kernel.org>
|
||||
In-Reply-To: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
|
||||
References: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Fri, 20 Mar 2026 11:09:40 +0100
|
||||
Subject: [PATCH 07/13] net: airoha: Do not stop GDM port if it is shared
|
||||
|
||||
Theoretically, in the current codebase, two independent net_devices can
|
||||
be connected to the same GDM port so we need to check the GDM port is not
|
||||
used by any other running net_device before setting the forward
|
||||
configuration to FE_PSE_PORT_DROP.
|
||||
Moreover, always set in GDM_LONG_LEN_MASK field of REG_GDM_LEN_CFG
|
||||
register the maximum MTU of all running net_devices connected to the same
|
||||
GDM port.
|
||||
|
||||
Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 59 +++++++++++++++++++-----
|
||||
drivers/net/ethernet/airoha/airoha_eth.h | 1 +
|
||||
2 files changed, 48 insertions(+), 12 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1849,8 +1849,8 @@ static int airoha_dev_open(struct net_de
|
||||
int err, len = ETH_HLEN + netdev->mtu + ETH_FCS_LEN;
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
struct airoha_gdm_port *port = dev->port;
|
||||
+ u32 cur_len, pse_port = FE_PSE_PORT_PPE1;
|
||||
struct airoha_qdma *qdma = dev->qdma;
|
||||
- u32 pse_port = FE_PSE_PORT_PPE1;
|
||||
|
||||
#if defined(CONFIG_PCS_AIROHA)
|
||||
if (airhoa_is_phy_external(port)) {
|
||||
@@ -1878,10 +1878,20 @@ static int airoha_dev_open(struct net_de
|
||||
airoha_fe_clear(qdma->eth, REG_GDM_INGRESS_CFG(port->id),
|
||||
GDM_STAG_EN_MASK);
|
||||
|
||||
- airoha_fe_rmw(qdma->eth, REG_GDM_LEN_CFG(port->id),
|
||||
- GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK,
|
||||
- FIELD_PREP(GDM_SHORT_LEN_MASK, 60) |
|
||||
- FIELD_PREP(GDM_LONG_LEN_MASK, len));
|
||||
+ cur_len = airoha_fe_get(qdma->eth, REG_GDM_LEN_CFG(port->id),
|
||||
+ GDM_LONG_LEN_MASK);
|
||||
+ if (!port->users || len > cur_len) {
|
||||
+ /* Opening a sibling net_device with a larger MTU updates the
|
||||
+ * MTU of already running devices. This is required to allow
|
||||
+ * multiple net_devices with different MTUs to share the same
|
||||
+ * GDM port.
|
||||
+ */
|
||||
+ airoha_fe_rmw(qdma->eth, REG_GDM_LEN_CFG(port->id),
|
||||
+ GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK,
|
||||
+ FIELD_PREP(GDM_SHORT_LEN_MASK, 60) |
|
||||
+ FIELD_PREP(GDM_LONG_LEN_MASK, len));
|
||||
+ }
|
||||
+ port->users++;
|
||||
|
||||
airoha_qdma_set(qdma, REG_QDMA_GLOBAL_CFG,
|
||||
GLOBAL_CFG_TX_DMA_EN_MASK |
|
||||
@@ -1897,6 +1907,30 @@ static int airoha_dev_open(struct net_de
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void airoha_set_port_mtu(struct airoha_eth *eth,
|
||||
+ struct airoha_gdm_port *port)
|
||||
+{
|
||||
+ u32 len = 0;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(port->devs); i++) {
|
||||
+ struct airoha_gdm_dev *dev = port->devs[i];
|
||||
+ struct net_device *netdev;
|
||||
+
|
||||
+ if (!dev)
|
||||
+ continue;
|
||||
+
|
||||
+ netdev = dev->dev;
|
||||
+ if (netif_running(netdev))
|
||||
+ len = max_t(u32, len, netdev->mtu);
|
||||
+ }
|
||||
+ len += ETH_HLEN + ETH_FCS_LEN;
|
||||
+
|
||||
+ airoha_fe_rmw(eth, REG_GDM_LEN_CFG(port->id),
|
||||
+ GDM_LONG_LEN_MASK,
|
||||
+ FIELD_PREP(GDM_LONG_LEN_MASK, len));
|
||||
+}
|
||||
+
|
||||
static int airoha_dev_stop(struct net_device *netdev)
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
@@ -1909,8 +1943,12 @@ static int airoha_dev_stop(struct net_de
|
||||
for (i = 0; i < netdev->num_tx_queues; i++)
|
||||
netdev_tx_reset_subqueue(netdev, i);
|
||||
|
||||
- airoha_set_gdm_port_fwd_cfg(qdma->eth, REG_GDM_FWD_CFG(port->id),
|
||||
- FE_PSE_PORT_DROP);
|
||||
+ if (--port->users)
|
||||
+ airoha_set_port_mtu(dev->eth, port);
|
||||
+ else
|
||||
+ airoha_set_gdm_port_fwd_cfg(qdma->eth,
|
||||
+ REG_GDM_FWD_CFG(port->id),
|
||||
+ FE_PSE_PORT_DROP);
|
||||
|
||||
if (atomic_dec_and_test(&qdma->users)) {
|
||||
airoha_qdma_clear(qdma, REG_QDMA_GLOBAL_CFG,
|
||||
@@ -2072,13 +2110,10 @@ static int airoha_dev_change_mtu(struct
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
struct airoha_gdm_port *port = dev->port;
|
||||
- u32 len = ETH_HLEN + mtu + ETH_FCS_LEN;
|
||||
- struct airoha_eth *eth = dev->eth;
|
||||
|
||||
- airoha_fe_rmw(eth, REG_GDM_LEN_CFG(port->id),
|
||||
- GDM_LONG_LEN_MASK,
|
||||
- FIELD_PREP(GDM_LONG_LEN_MASK, len));
|
||||
WRITE_ONCE(netdev->mtu, mtu);
|
||||
+ if (port->users)
|
||||
+ airoha_set_port_mtu(dev->eth, port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
@@ -571,6 +571,7 @@ struct airoha_gdm_dev {
|
||||
struct airoha_gdm_port {
|
||||
struct airoha_gdm_dev *devs[AIROHA_MAX_NUM_GDM_DEVS];
|
||||
int id;
|
||||
+ int users;
|
||||
|
||||
struct airoha_hw_stats stats;
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
From c4f3077948eda05a6b9d1a11304d82c3e0300151 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <c4f3077948eda05a6b9d1a11304d82c3e0300151.1779348625.git.lorenzo@kernel.org>
|
||||
In-Reply-To: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
|
||||
References: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Fri, 3 Apr 2026 12:07:27 +0200
|
||||
Subject: [PATCH 08/13] net: airoha: Introduce WAN device flag
|
||||
|
||||
Introduce WAN flag to specify if a given device is used to transmit/receive
|
||||
WAN or LAN traffic. Current codebase supports specifying LAN/WAN device
|
||||
configuration in ndo_init() callback during device bootstrap.
|
||||
In order to consider setups where LAN configuration is used even for
|
||||
GDM3/GDM4 devices, check airoha_is_lan_gdm_dev() to select pse_port in
|
||||
airoha_ppe_foe_entry_prepare().
|
||||
Please note after this patch, it will be possible to specify multiple LAN
|
||||
devices but just a single WAN one. Please note this change is not visible
|
||||
to the user since airoha_eth driver currently supports just the internal
|
||||
phy available via the MT7530 DSA switch and there are no WAN interfaces
|
||||
officially supported since PCS/external phy is not merged mainline yet
|
||||
(it will be posted with following patches).
|
||||
|
||||
Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 72 +++++++++++++++++++-----
|
||||
drivers/net/ethernet/airoha/airoha_eth.h | 13 ++---
|
||||
drivers/net/ethernet/airoha/airoha_ppe.c | 2 +-
|
||||
3 files changed, 65 insertions(+), 22 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -2049,36 +2049,80 @@ static int airoha_set_gdm2_loopback(stru
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int airoha_dev_init(struct net_device *netdev)
|
||||
+static struct airoha_gdm_dev *
|
||||
+airoha_get_wan_gdm_dev(struct airoha_eth *eth)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
+ struct airoha_gdm_port *port = eth->ports[i];
|
||||
+ int j;
|
||||
+
|
||||
+ if (!port)
|
||||
+ continue;
|
||||
+
|
||||
+ for (j = 0; j < ARRAY_SIZE(port->devs); j++) {
|
||||
+ struct airoha_gdm_dev *dev = port->devs[j];
|
||||
+
|
||||
+ if (dev && !airoha_is_lan_gdm_dev(dev))
|
||||
+ return dev;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static void airoha_dev_set_qdma(struct airoha_gdm_dev *dev)
|
||||
{
|
||||
- struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
- struct airoha_gdm_port *port = dev->port;
|
||||
struct airoha_eth *eth = dev->eth;
|
||||
int ppe_id;
|
||||
|
||||
/* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */
|
||||
dev->qdma = ð->qdma[!airoha_is_lan_gdm_dev(dev)];
|
||||
dev->dev->irq = dev->qdma->irq_banks[0].irq;
|
||||
- airoha_set_macaddr(dev, netdev->dev_addr);
|
||||
+
|
||||
+ ppe_id = !airoha_is_lan_gdm_dev(dev) && airoha_ppe_is_enabled(eth, 1);
|
||||
+ airoha_ppe_set_cpu_port(dev, ppe_id, airoha_get_fe_port(dev));
|
||||
+}
|
||||
+
|
||||
+static int airoha_dev_init(struct net_device *netdev)
|
||||
+{
|
||||
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
+ struct airoha_gdm_port *port = dev->port;
|
||||
|
||||
switch (port->id) {
|
||||
case AIROHA_GDM3_IDX:
|
||||
- case AIROHA_GDM4_IDX:
|
||||
- /* If GDM2 is active we can't enable loopback */
|
||||
- if (!eth->ports[1]) {
|
||||
- int err;
|
||||
-
|
||||
- err = airoha_set_gdm2_loopback(dev);
|
||||
- if (err)
|
||||
- return err;
|
||||
- }
|
||||
+ case AIROHA_GDM4_IDX: {
|
||||
+ struct airoha_eth *eth = dev->eth;
|
||||
+
|
||||
+ /* GDM2 supports a single net_device */
|
||||
+ if (eth->ports[1] && eth->ports[1]->devs[0])
|
||||
+ break;
|
||||
+
|
||||
+ if (airoha_get_wan_gdm_dev(eth))
|
||||
+ break;
|
||||
+
|
||||
+ fallthrough;
|
||||
+ }
|
||||
+ case AIROHA_GDM2_IDX:
|
||||
+ /* GDM2 is always used as wan */
|
||||
+ dev->flags |= AIROHA_PRIV_F_WAN;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
- ppe_id = !airoha_is_lan_gdm_dev(dev) && airoha_ppe_is_enabled(eth, 1);
|
||||
- airoha_ppe_set_cpu_port(dev, ppe_id, airoha_get_fe_port(dev));
|
||||
+ airoha_dev_set_qdma(dev);
|
||||
+ airoha_set_macaddr(dev, netdev->dev_addr);
|
||||
+
|
||||
+ if (!airoha_is_lan_gdm_dev(dev) &&
|
||||
+ (port->id == AIROHA_GDM3_IDX || port->id == AIROHA_GDM4_IDX)) {
|
||||
+ int err;
|
||||
+
|
||||
+ err = airoha_set_gdm2_loopback(dev);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
}
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
@@ -549,6 +549,10 @@ struct airoha_qdma {
|
||||
DECLARE_BITMAP(qos_channel_map, AIROHA_NUM_QOS_CHANNELS);
|
||||
};
|
||||
|
||||
+enum airoha_priv_flags {
|
||||
+ AIROHA_PRIV_F_WAN = BIT(0),
|
||||
+};
|
||||
+
|
||||
struct airoha_gdm_dev {
|
||||
struct airoha_gdm_port *port;
|
||||
struct airoha_qdma *qdma;
|
||||
@@ -565,6 +569,7 @@ struct airoha_gdm_dev {
|
||||
u64 cpu_tx_packets;
|
||||
u64 fwd_tx_packets;
|
||||
|
||||
+ u32 flags;
|
||||
int nbq;
|
||||
};
|
||||
|
||||
@@ -671,13 +676,7 @@ static inline u16 airoha_qdma_get_txq(st
|
||||
|
||||
static inline bool airoha_is_lan_gdm_dev(struct airoha_gdm_dev *dev)
|
||||
{
|
||||
- struct airoha_gdm_port *port = dev->port;
|
||||
-
|
||||
- /* GDM1 port on EN7581 SoC is connected to the lan dsa switch.
|
||||
- * GDM{2,3,4} can be used as wan port connected to an external
|
||||
- * phy module.
|
||||
- */
|
||||
- return port->id == 1;
|
||||
+ return !(dev->flags & AIROHA_PRIV_F_WAN);
|
||||
}
|
||||
|
||||
static inline bool airoha_is_7581(struct airoha_eth *eth)
|
||||
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
|
||||
@@ -351,7 +351,7 @@ static int airoha_ppe_foe_entry_prepare(
|
||||
return -EINVAL;
|
||||
|
||||
port = dev->port;
|
||||
- if (dsa_port >= 0 || eth->ports[1])
|
||||
+ if (dsa_port >= 0 || airoha_is_lan_gdm_dev(dev))
|
||||
pse_port = port->id == 4 ? FE_PSE_PORT_GDM4
|
||||
: port->id;
|
||||
else
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
From 144f0e6e55896625e3411aad02399a5ebb48d8f9 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <144f0e6e55896625e3411aad02399a5ebb48d8f9.1779348625.git.lorenzo@kernel.org>
|
||||
In-Reply-To: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
|
||||
References: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Mon, 13 Apr 2026 17:38:51 +0200
|
||||
Subject: [PATCH 09/13] net: airoha: Support multiple LAN/WAN interfaces for hw
|
||||
MAC address configuration
|
||||
|
||||
The EN7581 and AN7583 SoCs provide registers to configure hardware LAN/WAN
|
||||
MAC addresses, used to determine whether received traffic is destined for
|
||||
this host or should be forwarded to another device.
|
||||
The SoC hardware design assumes all interfaces configured as LAN (or WAN)
|
||||
share a common upper MAC address, which is programmed into the
|
||||
REG_FE_{LAN,WAN}_MAC_H register. The lower bytes of 'local' addresses can
|
||||
be expressed as a range via the REG_FE_MAC_LMIN and REG_FE_MAC_LMAX
|
||||
registers.
|
||||
Previously, only a single interface was considered when programming these
|
||||
registers. Extend the logic to derive the correct minimum and maximum
|
||||
values for REG_FE_MAC_LMIN/REG_FE_MAC_LMAX when two or more interfaces are
|
||||
configured as LAN or WAN.
|
||||
|
||||
Tested-by: Madhur Agrawal <madhur.agrawal@airoha.com>
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 77 ++++++++++++++++++++----
|
||||
drivers/net/ethernet/airoha/airoha_eth.h | 2 +-
|
||||
drivers/net/ethernet/airoha/airoha_ppe.c | 4 +-
|
||||
3 files changed, 68 insertions(+), 15 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -80,20 +80,74 @@ static bool airhoa_is_phy_external(struc
|
||||
}
|
||||
#endif
|
||||
|
||||
-static void airoha_set_macaddr(struct airoha_gdm_dev *dev, const u8 *addr)
|
||||
+static int airoha_set_macaddr(struct airoha_gdm_dev *dev, const u8 *addr)
|
||||
{
|
||||
+ u8 ref_addr[ETH_ALEN] __aligned(2);
|
||||
struct airoha_eth *eth = dev->eth;
|
||||
- u32 val, reg;
|
||||
+ u32 reg, val, lmin, lmax;
|
||||
+ int i;
|
||||
+
|
||||
+ eth_zero_addr(ref_addr);
|
||||
+ lmin = (addr[3] << 16) | (addr[4] << 8) | addr[5];
|
||||
+ lmax = lmin;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
+ struct airoha_gdm_port *port = eth->ports[i];
|
||||
+ int j;
|
||||
+
|
||||
+ if (!port)
|
||||
+ continue;
|
||||
+
|
||||
+ for (j = 0; j < ARRAY_SIZE(port->devs); j++) {
|
||||
+ struct airoha_gdm_dev *iter_dev;
|
||||
+ struct net_device *netdev;
|
||||
+
|
||||
+ iter_dev = port->devs[j];
|
||||
+ if (!iter_dev || iter_dev == dev)
|
||||
+ continue;
|
||||
+
|
||||
+ if (airoha_is_lan_gdm_dev(iter_dev) !=
|
||||
+ airoha_is_lan_gdm_dev(dev))
|
||||
+ continue;
|
||||
+
|
||||
+ netdev = iter_dev->dev;
|
||||
+ if (netdev->reg_state != NETREG_REGISTERED)
|
||||
+ continue;
|
||||
+
|
||||
+ ether_addr_copy(ref_addr, netdev->dev_addr);
|
||||
+ val = (netdev->dev_addr[3] << 16) |
|
||||
+ (netdev->dev_addr[4] << 8) | netdev->dev_addr[5];
|
||||
+ if (val < lmin)
|
||||
+ lmin = val;
|
||||
+ if (val > lmax)
|
||||
+ lmax = val;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!is_zero_ether_addr(ref_addr) && memcmp(ref_addr, addr, 3)) {
|
||||
+ /* According to the HW design, hw mac address MSBs must be
|
||||
+ * the same for each net_device with the same LAN/WAN
|
||||
+ * configuration.
|
||||
+ */
|
||||
+ dev_warn(eth->dev,
|
||||
+ "%s: wrong mac addr, MSBs must be %02x:%02x:%02x\n",
|
||||
+ dev->dev->name, ref_addr[0], ref_addr[1],
|
||||
+ ref_addr[2]);
|
||||
+ dev_warn(eth->dev, "FE hw forwarding won't work properly\n");
|
||||
+
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
|
||||
reg = airoha_is_lan_gdm_dev(dev) ? REG_FE_LAN_MAC_H : REG_FE_WAN_MAC_H;
|
||||
val = (addr[0] << 16) | (addr[1] << 8) | addr[2];
|
||||
airoha_fe_wr(eth, reg, val);
|
||||
|
||||
- val = (addr[3] << 16) | (addr[4] << 8) | addr[5];
|
||||
- airoha_fe_wr(eth, REG_FE_MAC_LMIN(reg), val);
|
||||
- airoha_fe_wr(eth, REG_FE_MAC_LMAX(reg), val);
|
||||
+ airoha_fe_wr(eth, REG_FE_MAC_LMIN(reg), lmin);
|
||||
+ airoha_fe_wr(eth, REG_FE_MAC_LMAX(reg), lmax);
|
||||
+
|
||||
+ airoha_ppe_init_upd_mem(dev, addr);
|
||||
|
||||
- airoha_ppe_init_upd_mem(dev);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static void airoha_set_gdm_port_fwd_cfg(struct airoha_eth *eth, u32 addr,
|
||||
@@ -1976,13 +2030,18 @@ static int airoha_dev_stop(struct net_de
|
||||
static int airoha_dev_set_macaddr(struct net_device *netdev, void *p)
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
+ struct sockaddr *addr = p;
|
||||
int err;
|
||||
|
||||
- err = eth_mac_addr(netdev, p);
|
||||
+ err = eth_prepare_mac_addr_change(netdev, p);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ err = airoha_set_macaddr(dev, addr->sa_data);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- airoha_set_macaddr(dev, netdev->dev_addr);
|
||||
+ eth_commit_mac_addr_change(netdev, p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
@@ -712,7 +712,7 @@ void airoha_ppe_check_skb(struct airoha_
|
||||
int airoha_ppe_setup_tc_block_cb(struct airoha_ppe_dev *dev, void *type_data);
|
||||
int airoha_ppe_init(struct airoha_eth *eth);
|
||||
void airoha_ppe_deinit(struct airoha_eth *eth);
|
||||
-void airoha_ppe_init_upd_mem(struct airoha_gdm_dev *dev);
|
||||
+void airoha_ppe_init_upd_mem(struct airoha_gdm_dev *dev, const u8 *addr);
|
||||
u32 airoha_ppe_get_total_num_entries(struct airoha_ppe *ppe);
|
||||
struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe,
|
||||
u32 hash);
|
||||
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
|
||||
@@ -1494,12 +1494,10 @@ void airoha_ppe_check_skb(struct airoha_
|
||||
airoha_ppe_foe_insert_entry(ppe, skb, hash, rx_wlan);
|
||||
}
|
||||
|
||||
-void airoha_ppe_init_upd_mem(struct airoha_gdm_dev *dev)
|
||||
+void airoha_ppe_init_upd_mem(struct airoha_gdm_dev *dev, const u8 *addr)
|
||||
{
|
||||
struct airoha_gdm_port *port = dev->port;
|
||||
- struct net_device *netdev = dev->dev;
|
||||
struct airoha_eth *eth = dev->eth;
|
||||
- const u8 *addr = netdev->dev_addr;
|
||||
u32 val;
|
||||
|
||||
val = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5];
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
From 917f959d54efd09719bd5047aa4b9543615e131e Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <917f959d54efd09719bd5047aa4b9543615e131e.1779348625.git.lorenzo@kernel.org>
|
||||
In-Reply-To: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
|
||||
References: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Fri, 19 Dec 2025 23:12:32 +0100
|
||||
Subject: [PATCH 10/13] net: airoha: Rename airoha_set_gdm2_loopback in
|
||||
airoha_enable_gdm2_loopback
|
||||
|
||||
This is a preliminary patch in order to allow the user to select if the
|
||||
configured device will be used as hw lan or wan.
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -2046,7 +2046,7 @@ static int airoha_dev_set_macaddr(struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int airoha_set_gdm2_loopback(struct airoha_gdm_dev *dev)
|
||||
+static int airoha_enable_gdm2_loopback(struct airoha_gdm_dev *dev)
|
||||
{
|
||||
struct airoha_gdm_port *port = dev->port;
|
||||
struct airoha_eth *eth = dev->eth;
|
||||
@@ -2178,7 +2178,7 @@ static int airoha_dev_init(struct net_de
|
||||
(port->id == AIROHA_GDM3_IDX || port->id == AIROHA_GDM4_IDX)) {
|
||||
int err;
|
||||
|
||||
- err = airoha_set_gdm2_loopback(dev);
|
||||
+ err = airoha_enable_gdm2_loopback(dev);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
+246
@@ -0,0 +1,246 @@
|
||||
From e928621a0bbd010b75624c77105ce31f2b8d2faf Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <e928621a0bbd010b75624c77105ce31f2b8d2faf.1779348625.git.lorenzo@kernel.org>
|
||||
In-Reply-To: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
|
||||
References: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Sat, 13 Dec 2025 09:45:09 +0100
|
||||
Subject: [PATCH 12/13] net: airoha: Add ethtool priv_flags callbacks
|
||||
|
||||
Introduce ethtool priv_flags callbacks in order to allow the user to
|
||||
select if the configured device will be used as hw lan or wan and enable
|
||||
or disable gdm2 loopback (used for hw QoS).
|
||||
|
||||
Tested-by: Madhur Agrawal <madhur.agrawal@airoha.com>
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 173 ++++++++++++++++++++++
|
||||
drivers/net/ethernet/airoha/airoha_regs.h | 1 +
|
||||
2 files changed, 174 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1906,6 +1906,11 @@ static int airoha_dev_open(struct net_de
|
||||
u32 cur_len, pse_port = FE_PSE_PORT_PPE1;
|
||||
struct airoha_qdma *qdma = dev->qdma;
|
||||
|
||||
+ if (port->id == AIROHA_GDM2_IDX && airoha_is_lan_gdm_dev(dev)) {
|
||||
+ /* GDM2 can be used just as wan */
|
||||
+ return -EBUSY;
|
||||
+ }
|
||||
+
|
||||
#if defined(CONFIG_PCS_AIROHA)
|
||||
if (airhoa_is_phy_external(port)) {
|
||||
err = phylink_of_phy_connect(dev->phylink, netdev->dev.of_node, 0);
|
||||
@@ -2108,6 +2113,45 @@ static int airoha_enable_gdm2_loopback(s
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int airoha_disable_gdm2_loopback(struct airoha_gdm_dev *dev)
|
||||
+{
|
||||
+ struct airoha_eth *eth = dev->eth;
|
||||
+ int i, src_port;
|
||||
+ u32 pse_port;
|
||||
+
|
||||
+ src_port = eth->soc->ops.get_sport(dev->port, dev->nbq);
|
||||
+ if (src_port < 0)
|
||||
+ return src_port;
|
||||
+
|
||||
+ airoha_fe_clear(eth,
|
||||
+ REG_SP_DFT_CPORT(src_port >> fls(SP_CPORT_DFT_MASK)),
|
||||
+ SP_CPORT_MASK(src_port & SP_CPORT_DFT_MASK));
|
||||
+
|
||||
+ airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX),
|
||||
+ FE_PSE_PORT_DROP);
|
||||
+ airoha_fe_clear(eth, REG_GDM_LPBK_CFG(AIROHA_GDM2_IDX),
|
||||
+ LPBK_CHAN_MASK | LPBK_MODE_MASK | LPBK_EN_MASK);
|
||||
+ pse_port = airoha_ppe_is_enabled(eth, 1) ? FE_PSE_PORT_PPE2
|
||||
+ : FE_PSE_PORT_PPE1;
|
||||
+ airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX),
|
||||
+ pse_port);
|
||||
+
|
||||
+ airoha_fe_rmw(eth, REG_FE_WAN_PORT, WAN0_MASK,
|
||||
+ FIELD_PREP(WAN0_MASK, AIROHA_GDM2_IDX));
|
||||
+
|
||||
+ for (i = 0; i < eth->soc->num_ppe; i++)
|
||||
+ airoha_fe_clear(eth, REG_PPE_DFT_CPORT(i, AIROHA_GDM2_IDX),
|
||||
+ DFT_CPORT_MASK(AIROHA_GDM2_IDX));
|
||||
+
|
||||
+ /* Enable VIP and IFC for GDM2 */
|
||||
+ airoha_fe_set(eth, REG_FE_VIP_PORT_EN, BIT(AIROHA_GDM2_IDX));
|
||||
+ airoha_fe_set(eth, REG_FE_IFC_PORT_EN, BIT(AIROHA_GDM2_IDX));
|
||||
+
|
||||
+ airoha_fe_wr(eth, REG_SRC_PORT_FC_MAP6, FC_MAP6_DEF_VALUE);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static struct airoha_gdm_dev *
|
||||
airoha_get_wan_gdm_dev(struct airoha_eth *eth)
|
||||
{
|
||||
@@ -2509,6 +2553,80 @@ error:
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
+struct airoha_ethool_priv_flags {
|
||||
+ char name[ETH_GSTRING_LEN];
|
||||
+ int (*handler)(struct net_device *netdev, u32 flags);
|
||||
+};
|
||||
+
|
||||
+static int airoha_dev_set_wan_flag(struct net_device *netdev, u32 flags)
|
||||
+{
|
||||
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
+ struct airoha_gdm_port *port = dev->port;
|
||||
+ struct airoha_eth *eth = dev->eth;
|
||||
+
|
||||
+ if (!((dev->flags ^ flags) & AIROHA_PRIV_F_WAN))
|
||||
+ return 0;
|
||||
+
|
||||
+ if (netif_running(netdev))
|
||||
+ return -EBUSY;
|
||||
+
|
||||
+ if (flags & AIROHA_PRIV_F_WAN) {
|
||||
+ struct airoha_gdm_dev *wan_dev;
|
||||
+
|
||||
+ /* Verify the wan device is not already configured */
|
||||
+ wan_dev = airoha_get_wan_gdm_dev(eth);
|
||||
+ if (wan_dev && wan_dev != dev)
|
||||
+ return -EBUSY;
|
||||
+
|
||||
+ switch (port->id) {
|
||||
+ case AIROHA_GDM2_IDX:
|
||||
+ dev->flags |= AIROHA_PRIV_F_WAN;
|
||||
+ airoha_dev_set_qdma(dev);
|
||||
+ break;
|
||||
+ case AIROHA_GDM3_IDX:
|
||||
+ case AIROHA_GDM4_IDX: {
|
||||
+ int err;
|
||||
+
|
||||
+ dev->flags |= AIROHA_PRIV_F_WAN;
|
||||
+ airoha_dev_set_qdma(dev);
|
||||
+
|
||||
+ err = airoha_enable_gdm2_loopback(dev);
|
||||
+ if (err) {
|
||||
+ dev->flags &= ~AIROHA_PRIV_F_WAN;
|
||||
+ return err;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ default:
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
+ } else {
|
||||
+ switch (port->id) {
|
||||
+ case AIROHA_GDM3_IDX:
|
||||
+ case AIROHA_GDM4_IDX: {
|
||||
+ int err;
|
||||
+
|
||||
+ err = airoha_disable_gdm2_loopback(dev);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ break;
|
||||
+ }
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ dev->flags &= ~AIROHA_PRIV_F_WAN;
|
||||
+ airoha_dev_set_qdma(dev);
|
||||
+ }
|
||||
+
|
||||
+ return airoha_set_macaddr(dev, netdev->dev_addr);
|
||||
+}
|
||||
+
|
||||
+static const struct airoha_ethool_priv_flags airoha_eth_priv_flags[] = {
|
||||
+ { "wan", airoha_dev_set_wan_flag },
|
||||
+};
|
||||
+#define AIROHA_PRIV_FLAGS_STR_LEN ARRAY_SIZE(airoha_eth_priv_flags)
|
||||
+
|
||||
static void airoha_ethtool_get_drvinfo(struct net_device *netdev,
|
||||
struct ethtool_drvinfo *info)
|
||||
{
|
||||
@@ -2517,6 +2635,7 @@ static void airoha_ethtool_get_drvinfo(s
|
||||
|
||||
strscpy(info->driver, eth->dev->driver->name, sizeof(info->driver));
|
||||
strscpy(info->bus_info, dev_name(eth->dev), sizeof(info->bus_info));
|
||||
+ info->n_priv_flags = AIROHA_PRIV_FLAGS_STR_LEN;
|
||||
}
|
||||
|
||||
static void airoha_ethtool_get_mac_stats(struct net_device *netdev,
|
||||
@@ -2581,6 +2700,56 @@ airoha_ethtool_get_rmon_stats(struct net
|
||||
} while (u64_stats_fetch_retry(&port->stats.syncp, start));
|
||||
}
|
||||
|
||||
+static int airoha_ethtool_set_priv_flags(struct net_device *netdev, u32 flags)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < AIROHA_PRIV_FLAGS_STR_LEN; i++) {
|
||||
+ int err;
|
||||
+
|
||||
+ if (!airoha_eth_priv_flags[i].handler)
|
||||
+ continue;
|
||||
+
|
||||
+ err = airoha_eth_priv_flags[i].handler(netdev, flags);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static u32 airoha_ethtool_get_priv_flags(struct net_device *netdev)
|
||||
+{
|
||||
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
+
|
||||
+ return dev->flags;
|
||||
+}
|
||||
+
|
||||
+static int airoha_ethtool_get_sset_count(struct net_device *netdev, int sset)
|
||||
+{
|
||||
+ switch (sset) {
|
||||
+ case ETH_SS_PRIV_FLAGS:
|
||||
+ return AIROHA_PRIV_FLAGS_STR_LEN;
|
||||
+ default:
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void airoha_ethtool_get_strings(struct net_device *netdev,
|
||||
+ u32 stringset, u8 *data)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ switch (stringset) {
|
||||
+ case ETH_SS_PRIV_FLAGS:
|
||||
+ for (i = 0; i < AIROHA_PRIV_FLAGS_STR_LEN; i++)
|
||||
+ ethtool_puts(&data, airoha_eth_priv_flags[i].name);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int airoha_qdma_set_chan_tx_sched(struct net_device *netdev,
|
||||
int channel, enum tx_sched_mode mode,
|
||||
const u16 *weights, u8 n_weights)
|
||||
@@ -3302,6 +3471,10 @@ static const struct ethtool_ops airoha_e
|
||||
.get_rmon_stats = airoha_ethtool_get_rmon_stats,
|
||||
.get_link_ksettings = phy_ethtool_get_link_ksettings,
|
||||
.get_link = ethtool_op_get_link,
|
||||
+ .set_priv_flags = airoha_ethtool_set_priv_flags,
|
||||
+ .get_priv_flags = airoha_ethtool_get_priv_flags,
|
||||
+ .get_sset_count = airoha_ethtool_get_sset_count,
|
||||
+ .get_strings = airoha_ethtool_get_strings,
|
||||
};
|
||||
|
||||
static void airoha_mac_config(struct phylink_config *config, unsigned int mode,
|
||||
--- a/drivers/net/ethernet/airoha/airoha_regs.h
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_regs.h
|
||||
@@ -402,6 +402,7 @@
|
||||
|
||||
#define REG_SRC_PORT_FC_MAP6 0x2298
|
||||
#define FC_ID_OF_SRC_PORT_MASK(_n) GENMASK(4 + ((_n) << 3), ((_n) << 3))
|
||||
+#define FC_MAP6_DEF_VALUE 0x1b1a1918
|
||||
|
||||
#define REG_CDM5_RX_OQ1_DROP_CNT 0x29d4
|
||||
|
||||
@@ -0,0 +1,223 @@
|
||||
From 99e204d255c9b47a188dd79762b9406d9c5fed9b Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <99e204d255c9b47a188dd79762b9406d9c5fed9b.1779348625.git.lorenzo@kernel.org>
|
||||
In-Reply-To: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
|
||||
References: <e15783f7c987e199ecf80b3d858ed5a86d33c508.1779348625.git.lorenzo@kernel.org>
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Wed, 20 May 2026 17:16:39 +0200
|
||||
Subject: [PATCH 13/13] net: airoha: Rework MTU configuration
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 85 +++++++++++------------
|
||||
drivers/net/ethernet/airoha/airoha_eth.h | 1 +
|
||||
drivers/net/ethernet/airoha/airoha_ppe.c | 8 +--
|
||||
drivers/net/ethernet/airoha/airoha_regs.h | 9 ++-
|
||||
4 files changed, 49 insertions(+), 54 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -185,10 +185,15 @@ static void airoha_fe_maccr_init(struct
|
||||
{
|
||||
int p;
|
||||
|
||||
- for (p = 1; p <= ARRAY_SIZE(eth->ports); p++)
|
||||
+ for (p = 1; p <= ARRAY_SIZE(eth->ports); p++) {
|
||||
airoha_fe_set(eth, REG_GDM_FWD_CFG(p),
|
||||
GDM_TCP_CKSUM_MASK | GDM_UDP_CKSUM_MASK |
|
||||
GDM_IP4_CKSUM_MASK | GDM_DROP_CRC_ERR_MASK);
|
||||
+ airoha_fe_rmw(eth, REG_GDM_LEN_CFG(p),
|
||||
+ GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK,
|
||||
+ FIELD_PREP(GDM_SHORT_LEN_MASK, 60) |
|
||||
+ FIELD_PREP(GDM_LONG_LEN_MASK, AIROHA_MAX_MTU));
|
||||
+ }
|
||||
|
||||
airoha_fe_rmw(eth, REG_CDM_VLAN_CTRL(1), CDM_VLAN_MASK,
|
||||
FIELD_PREP(CDM_VLAN_MASK, 0x8100));
|
||||
@@ -1898,13 +1903,37 @@ static void airoha_update_hw_stats(struc
|
||||
spin_unlock(&port->stats.lock);
|
||||
}
|
||||
|
||||
+void airoha_set_port_mtu(struct airoha_eth *eth, struct airoha_gdm_port *port)
|
||||
+{
|
||||
+ u32 mtu = 0, index;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(port->devs); i++) {
|
||||
+ struct airoha_gdm_dev *dev = port->devs[i];
|
||||
+ struct net_device *netdev;
|
||||
+
|
||||
+ if (!dev)
|
||||
+ continue;
|
||||
+
|
||||
+ netdev = dev->dev;
|
||||
+ if (netif_running(netdev))
|
||||
+ mtu = max_t(u32, mtu, netdev->mtu);
|
||||
+ }
|
||||
+
|
||||
+ index = port->id == AIROHA_GDM4_IDX ? 7 : port->id;
|
||||
+ for (i = 0; i < eth->soc->num_ppe; i++)
|
||||
+ airoha_fe_rmw(eth, REG_PPE_MTU(i, index),
|
||||
+ FP_EGRESS_MTU_MASK(index),
|
||||
+ __field_prep(FP_EGRESS_MTU_MASK(index), mtu));
|
||||
+}
|
||||
+
|
||||
static int airoha_dev_open(struct net_device *netdev)
|
||||
{
|
||||
- int err, len = ETH_HLEN + netdev->mtu + ETH_FCS_LEN;
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
struct airoha_gdm_port *port = dev->port;
|
||||
- u32 cur_len, pse_port = FE_PSE_PORT_PPE1;
|
||||
struct airoha_qdma *qdma = dev->qdma;
|
||||
+ u32 pse_port = FE_PSE_PORT_PPE1;
|
||||
+ int err;
|
||||
|
||||
if (port->id == AIROHA_GDM2_IDX && airoha_is_lan_gdm_dev(dev)) {
|
||||
/* GDM2 can be used just as wan */
|
||||
@@ -1937,19 +1966,12 @@ static int airoha_dev_open(struct net_de
|
||||
airoha_fe_clear(qdma->eth, REG_GDM_INGRESS_CFG(port->id),
|
||||
GDM_STAG_EN_MASK);
|
||||
|
||||
- cur_len = airoha_fe_get(qdma->eth, REG_GDM_LEN_CFG(port->id),
|
||||
- GDM_LONG_LEN_MASK);
|
||||
- if (!port->users || len > cur_len) {
|
||||
- /* Opening a sibling net_device with a larger MTU updates the
|
||||
- * MTU of already running devices. This is required to allow
|
||||
- * multiple net_devices with different MTUs to share the same
|
||||
- * GDM port.
|
||||
- */
|
||||
- airoha_fe_rmw(qdma->eth, REG_GDM_LEN_CFG(port->id),
|
||||
- GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK,
|
||||
- FIELD_PREP(GDM_SHORT_LEN_MASK, 60) |
|
||||
- FIELD_PREP(GDM_LONG_LEN_MASK, len));
|
||||
- }
|
||||
+ airoha_set_port_mtu(qdma->eth, port);
|
||||
+ if (!airoha_is_lan_gdm_dev(dev))
|
||||
+ airoha_fe_rmw(qdma->eth, REG_WAN_MTU0,
|
||||
+ WAN_MTU0_MASK,
|
||||
+ FIELD_PREP(WAN_MTU0_MASK, netdev->mtu));
|
||||
+
|
||||
port->users++;
|
||||
|
||||
airoha_qdma_set(qdma, REG_QDMA_GLOBAL_CFG,
|
||||
@@ -1966,30 +1988,6 @@ static int airoha_dev_open(struct net_de
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void airoha_set_port_mtu(struct airoha_eth *eth,
|
||||
- struct airoha_gdm_port *port)
|
||||
-{
|
||||
- u32 len = 0;
|
||||
- int i;
|
||||
-
|
||||
- for (i = 0; i < ARRAY_SIZE(port->devs); i++) {
|
||||
- struct airoha_gdm_dev *dev = port->devs[i];
|
||||
- struct net_device *netdev;
|
||||
-
|
||||
- if (!dev)
|
||||
- continue;
|
||||
-
|
||||
- netdev = dev->dev;
|
||||
- if (netif_running(netdev))
|
||||
- len = max_t(u32, len, netdev->mtu);
|
||||
- }
|
||||
- len += ETH_HLEN + ETH_FCS_LEN;
|
||||
-
|
||||
- airoha_fe_rmw(eth, REG_GDM_LEN_CFG(port->id),
|
||||
- GDM_LONG_LEN_MASK,
|
||||
- FIELD_PREP(GDM_LONG_LEN_MASK, len));
|
||||
-}
|
||||
-
|
||||
static int airoha_dev_stop(struct net_device *netdev)
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
@@ -2073,10 +2071,6 @@ static int airoha_enable_gdm2_loopback(s
|
||||
FIELD_PREP(LPBK_CHAN_MASK, chan) |
|
||||
LBK_GAP_MODE_MASK | LBK_LEN_MODE_MASK |
|
||||
LBK_CHAN_MODE_MASK | LPBK_EN_MASK);
|
||||
- airoha_fe_rmw(eth, REG_GDM_LEN_CFG(AIROHA_GDM2_IDX),
|
||||
- GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK,
|
||||
- FIELD_PREP(GDM_SHORT_LEN_MASK, 60) |
|
||||
- FIELD_PREP(GDM_LONG_LEN_MASK, AIROHA_MAX_MTU));
|
||||
/* Forward the traffic to the proper GDM port */
|
||||
pse_port = port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3
|
||||
: FE_PSE_PORT_GDM4;
|
||||
@@ -2600,6 +2594,9 @@ static int airoha_dev_set_wan_flag(struc
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
+ airoha_fe_rmw(eth, REG_WAN_MTU0,
|
||||
+ WAN_MTU0_MASK,
|
||||
+ FIELD_PREP(WAN_MTU0_MASK, netdev->mtu));
|
||||
} else {
|
||||
switch (port->id) {
|
||||
case AIROHA_GDM3_IDX:
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
@@ -705,6 +705,7 @@ int airoha_get_fe_port(struct airoha_gdm
|
||||
bool airoha_is_valid_gdm_dev(struct airoha_eth *eth,
|
||||
struct airoha_gdm_dev *dev);
|
||||
|
||||
+void airoha_set_port_mtu(struct airoha_eth *eth, struct airoha_gdm_port *port);
|
||||
void airoha_ppe_set_cpu_port(struct airoha_gdm_dev *dev, u8 ppe_id, u8 fport);
|
||||
bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index);
|
||||
void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb,
|
||||
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
|
||||
@@ -116,8 +116,6 @@ static void airoha_ppe_hw_init(struct ai
|
||||
PPE_RAM_NUM_ENTRIES_SHIFT(sram_ppe_num_data_entries);
|
||||
|
||||
for (i = 0; i < eth->soc->num_ppe; i++) {
|
||||
- int p;
|
||||
-
|
||||
airoha_fe_wr(eth, REG_PPE_TB_BASE(i),
|
||||
ppe->foe_dma + sram_tb_size);
|
||||
|
||||
@@ -167,15 +165,6 @@ static void airoha_ppe_hw_init(struct ai
|
||||
airoha_fe_wr(eth, REG_PPE_HASH_SEED(i), PPE_HASH_SEED);
|
||||
airoha_fe_clear(eth, REG_PPE_PPE_FLOW_CFG(i),
|
||||
PPE_FLOW_CFG_IP6_6RD_MASK);
|
||||
-
|
||||
- for (p = 0; p < ARRAY_SIZE(eth->ports); p++)
|
||||
- airoha_fe_rmw(eth, REG_PPE_MTU(i, p),
|
||||
- FP0_EGRESS_MTU_MASK |
|
||||
- FP1_EGRESS_MTU_MASK,
|
||||
- FIELD_PREP(FP0_EGRESS_MTU_MASK,
|
||||
- AIROHA_MAX_MTU) |
|
||||
- FIELD_PREP(FP1_EGRESS_MTU_MASK,
|
||||
- AIROHA_MAX_MTU));
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
@@ -185,6 +174,7 @@ static void airoha_ppe_hw_init(struct ai
|
||||
if (!port)
|
||||
continue;
|
||||
|
||||
+ airoha_set_port_mtu(eth, port);
|
||||
for (j = 0; j < ARRAY_SIZE(port->devs); j++) {
|
||||
struct airoha_gdm_dev *dev = port->devs[j];
|
||||
u8 fport;
|
||||
--- a/drivers/net/ethernet/airoha/airoha_regs.h
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_regs.h
|
||||
@@ -341,9 +341,8 @@
|
||||
#define PPE_SRAM_TABLE_EN_MASK BIT(0)
|
||||
|
||||
#define REG_PPE_MTU_BASE(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x304)
|
||||
-#define REG_PPE_MTU(_m, _n) (REG_PPE_MTU_BASE(_m) + ((_n) << 2))
|
||||
-#define FP1_EGRESS_MTU_MASK GENMASK(29, 16)
|
||||
-#define FP0_EGRESS_MTU_MASK GENMASK(13, 0)
|
||||
+#define REG_PPE_MTU(_m, _n) (REG_PPE_MTU_BASE(_m) + (((_n) / 2) << 2))
|
||||
+#define FP_EGRESS_MTU_MASK(_n) GENMASK(13 + (((_n) % 2) << 4), ((_n) % 2) << 4)
|
||||
|
||||
#define REG_PPE_RAM_CTRL(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x31c)
|
||||
#define PPE_SRAM_CTRL_ACK_MASK BIT(31)
|
||||
@@ -404,6 +403,10 @@
|
||||
#define FC_ID_OF_SRC_PORT_MASK(_n) GENMASK(4 + ((_n) << 3), ((_n) << 3))
|
||||
#define FC_MAP6_DEF_VALUE 0x1b1a1918
|
||||
|
||||
+#define REG_WAN_MTU0 0x2300
|
||||
+#define WAN_MTU1_MASK GENMASK(29, 16)
|
||||
+#define WAN_MTU0_MASK GENMASK(13, 0)
|
||||
+
|
||||
#define REG_CDM5_RX_OQ1_DROP_CNT 0x29d4
|
||||
|
||||
/* QDMA */
|
||||
+415
@@ -0,0 +1,415 @@
|
||||
From 9652322e0b47eacfef497828f6476a2a3169fd13 Mon Sep 17 00:00:00 2001
|
||||
Message-ID: <9652322e0b47eacfef497828f6476a2a3169fd13.1779351672.git.lorenzo@kernel.org>
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Sat, 17 Jan 2026 14:46:12 +0100
|
||||
Subject: [PATCH] net: airoha: Better handle MIB for GDM with multiple port
|
||||
attached
|
||||
|
||||
In the context of a GDM that can have multiple port attached (GDM3/4)
|
||||
the HW counter (MIB) are global for the GDM port. This cause duplicated
|
||||
stats reported to the kernel for the related interface.
|
||||
|
||||
The SoC supports a split MIB feature where each counter is tracked based
|
||||
on the relevant HW channel (NBQ) to account for this scenario and
|
||||
provide a way to select the related counter on accessing the MIB
|
||||
registers.
|
||||
|
||||
Enable this feature for GDM3 and GDM4 and configure the relevant HW
|
||||
channel before updating the HW stats to report correct HW counter to the
|
||||
kernel for the related interface.
|
||||
|
||||
Also move the stats struct from port to dev since HW counter are
|
||||
now specific to the network interface instead of the GDM port.
|
||||
|
||||
Co-developed-by: Brown Huang <Brown.huang@airoha.com>
|
||||
Signed-off-by: Brown Huang <Brown.huang@airoha.com>
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 191 +++++++++++++----------
|
||||
drivers/net/ethernet/airoha/airoha_eth.h | 7 +-
|
||||
2 files changed, 112 insertions(+), 86 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -611,6 +611,14 @@ static int airoha_fe_init(struct airoha_
|
||||
airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM4_IDX),
|
||||
GDM_PAD_EN_MASK | GDM_STRIP_CRC_MASK);
|
||||
|
||||
+ /* Enable split for MIB counters for GDM3 and GDM4 */
|
||||
+ airoha_fe_set(eth, REG_FE_GDM_MIB_CFG(AIROHA_GDM3_IDX),
|
||||
+ FE_GDM_TX_MIB_SPLIT_EN_MASK |
|
||||
+ FE_GDM_RX_MIB_SPLIT_EN_MASK);
|
||||
+ airoha_fe_set(eth, REG_FE_GDM_MIB_CFG(AIROHA_GDM4_IDX),
|
||||
+ FE_GDM_TX_MIB_SPLIT_EN_MASK |
|
||||
+ FE_GDM_RX_MIB_SPLIT_EN_MASK);
|
||||
+
|
||||
airoha_fe_crsn_qsel_init(eth);
|
||||
|
||||
airoha_fe_clear(eth, REG_FE_CPORT_CFG, FE_CPORT_QUEUE_XFC_MASK);
|
||||
@@ -1758,149 +1766,169 @@ static void airoha_qdma_stop_napi(struct
|
||||
}
|
||||
}
|
||||
|
||||
-static void airoha_update_hw_stats(struct airoha_gdm_dev *dev)
|
||||
+static void airoha_dev_get_hw_stats(struct airoha_gdm_dev *dev)
|
||||
{
|
||||
struct airoha_gdm_port *port = dev->port;
|
||||
struct airoha_eth *eth = dev->eth;
|
||||
u32 val, i = 0;
|
||||
|
||||
- spin_lock(&port->stats.lock);
|
||||
- u64_stats_update_begin(&port->stats.syncp);
|
||||
+ u64_stats_update_begin(&dev->stats.syncp);
|
||||
+
|
||||
+ /* Read relevant MIB for GDM with multiple port attached */
|
||||
+ if (port->id == AIROHA_GDM3_IDX || port->id == AIROHA_GDM4_IDX)
|
||||
+ airoha_fe_rmw(eth, REG_FE_GDM_MIB_CFG(port->id),
|
||||
+ FE_TX_MIB_ID_MASK | FE_RX_MIB_ID_MASK,
|
||||
+ FIELD_PREP(FE_TX_MIB_ID_MASK, dev->nbq) |
|
||||
+ FIELD_PREP(FE_RX_MIB_ID_MASK, dev->nbq));
|
||||
|
||||
/* TX */
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_PKT_CNT_H(port->id));
|
||||
- port->stats.tx_ok_pkts += ((u64)val << 32);
|
||||
+ dev->stats.tx_ok_pkts += ((u64)val << 32);
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_PKT_CNT_L(port->id));
|
||||
- port->stats.tx_ok_pkts += val;
|
||||
+ dev->stats.tx_ok_pkts += val;
|
||||
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_BYTE_CNT_H(port->id));
|
||||
- port->stats.tx_ok_bytes += ((u64)val << 32);
|
||||
+ dev->stats.tx_ok_bytes += ((u64)val << 32);
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_BYTE_CNT_L(port->id));
|
||||
- port->stats.tx_ok_bytes += val;
|
||||
+ dev->stats.tx_ok_bytes += val;
|
||||
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_DROP_CNT(port->id));
|
||||
- port->stats.tx_drops += val;
|
||||
+ dev->stats.tx_drops += val;
|
||||
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_BC_CNT(port->id));
|
||||
- port->stats.tx_broadcast += val;
|
||||
+ dev->stats.tx_broadcast += val;
|
||||
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_MC_CNT(port->id));
|
||||
- port->stats.tx_multicast += val;
|
||||
+ dev->stats.tx_multicast += val;
|
||||
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_RUNT_CNT(port->id));
|
||||
- port->stats.tx_len[i] += val;
|
||||
+ dev->stats.tx_len[i] += val;
|
||||
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_E64_CNT_H(port->id));
|
||||
- port->stats.tx_len[i] += ((u64)val << 32);
|
||||
+ dev->stats.tx_len[i] += ((u64)val << 32);
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_E64_CNT_L(port->id));
|
||||
- port->stats.tx_len[i++] += val;
|
||||
+ dev->stats.tx_len[i++] += val;
|
||||
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L64_CNT_H(port->id));
|
||||
- port->stats.tx_len[i] += ((u64)val << 32);
|
||||
+ dev->stats.tx_len[i] += ((u64)val << 32);
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L64_CNT_L(port->id));
|
||||
- port->stats.tx_len[i++] += val;
|
||||
+ dev->stats.tx_len[i++] += val;
|
||||
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L127_CNT_H(port->id));
|
||||
- port->stats.tx_len[i] += ((u64)val << 32);
|
||||
+ dev->stats.tx_len[i] += ((u64)val << 32);
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L127_CNT_L(port->id));
|
||||
- port->stats.tx_len[i++] += val;
|
||||
+ dev->stats.tx_len[i++] += val;
|
||||
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L255_CNT_H(port->id));
|
||||
- port->stats.tx_len[i] += ((u64)val << 32);
|
||||
+ dev->stats.tx_len[i] += ((u64)val << 32);
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L255_CNT_L(port->id));
|
||||
- port->stats.tx_len[i++] += val;
|
||||
+ dev->stats.tx_len[i++] += val;
|
||||
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L511_CNT_H(port->id));
|
||||
- port->stats.tx_len[i] += ((u64)val << 32);
|
||||
+ dev->stats.tx_len[i] += ((u64)val << 32);
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L511_CNT_L(port->id));
|
||||
- port->stats.tx_len[i++] += val;
|
||||
+ dev->stats.tx_len[i++] += val;
|
||||
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L1023_CNT_H(port->id));
|
||||
- port->stats.tx_len[i] += ((u64)val << 32);
|
||||
+ dev->stats.tx_len[i] += ((u64)val << 32);
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L1023_CNT_L(port->id));
|
||||
- port->stats.tx_len[i++] += val;
|
||||
+ dev->stats.tx_len[i++] += val;
|
||||
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_LONG_CNT(port->id));
|
||||
- port->stats.tx_len[i++] += val;
|
||||
+ dev->stats.tx_len[i++] += val;
|
||||
|
||||
/* RX */
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_PKT_CNT_H(port->id));
|
||||
- port->stats.rx_ok_pkts += ((u64)val << 32);
|
||||
+ dev->stats.rx_ok_pkts += ((u64)val << 32);
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_PKT_CNT_L(port->id));
|
||||
- port->stats.rx_ok_pkts += val;
|
||||
+ dev->stats.rx_ok_pkts += val;
|
||||
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_BYTE_CNT_H(port->id));
|
||||
- port->stats.rx_ok_bytes += ((u64)val << 32);
|
||||
+ dev->stats.rx_ok_bytes += ((u64)val << 32);
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_BYTE_CNT_L(port->id));
|
||||
- port->stats.rx_ok_bytes += val;
|
||||
+ dev->stats.rx_ok_bytes += val;
|
||||
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_DROP_CNT(port->id));
|
||||
- port->stats.rx_drops += val;
|
||||
+ dev->stats.rx_drops += val;
|
||||
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_BC_CNT(port->id));
|
||||
- port->stats.rx_broadcast += val;
|
||||
+ dev->stats.rx_broadcast += val;
|
||||
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_MC_CNT(port->id));
|
||||
- port->stats.rx_multicast += val;
|
||||
+ dev->stats.rx_multicast += val;
|
||||
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ERROR_DROP_CNT(port->id));
|
||||
- port->stats.rx_errors += val;
|
||||
+ dev->stats.rx_errors += val;
|
||||
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_CRC_ERR_CNT(port->id));
|
||||
- port->stats.rx_crc_error += val;
|
||||
+ dev->stats.rx_crc_error += val;
|
||||
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_RX_OVERFLOW_DROP_CNT(port->id));
|
||||
- port->stats.rx_over_errors += val;
|
||||
+ dev->stats.rx_over_errors += val;
|
||||
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_FRAG_CNT(port->id));
|
||||
- port->stats.rx_fragment += val;
|
||||
+ dev->stats.rx_fragment += val;
|
||||
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_JABBER_CNT(port->id));
|
||||
- port->stats.rx_jabber += val;
|
||||
+ dev->stats.rx_jabber += val;
|
||||
|
||||
i = 0;
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_RUNT_CNT(port->id));
|
||||
- port->stats.rx_len[i] += val;
|
||||
+ dev->stats.rx_len[i] += val;
|
||||
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_E64_CNT_H(port->id));
|
||||
- port->stats.rx_len[i] += ((u64)val << 32);
|
||||
+ dev->stats.rx_len[i] += ((u64)val << 32);
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_E64_CNT_L(port->id));
|
||||
- port->stats.rx_len[i++] += val;
|
||||
+ dev->stats.rx_len[i++] += val;
|
||||
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L64_CNT_H(port->id));
|
||||
- port->stats.rx_len[i] += ((u64)val << 32);
|
||||
+ dev->stats.rx_len[i] += ((u64)val << 32);
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L64_CNT_L(port->id));
|
||||
- port->stats.rx_len[i++] += val;
|
||||
+ dev->stats.rx_len[i++] += val;
|
||||
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L127_CNT_H(port->id));
|
||||
- port->stats.rx_len[i] += ((u64)val << 32);
|
||||
+ dev->stats.rx_len[i] += ((u64)val << 32);
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L127_CNT_L(port->id));
|
||||
- port->stats.rx_len[i++] += val;
|
||||
+ dev->stats.rx_len[i++] += val;
|
||||
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L255_CNT_H(port->id));
|
||||
- port->stats.rx_len[i] += ((u64)val << 32);
|
||||
+ dev->stats.rx_len[i] += ((u64)val << 32);
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L255_CNT_L(port->id));
|
||||
- port->stats.rx_len[i++] += val;
|
||||
+ dev->stats.rx_len[i++] += val;
|
||||
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L511_CNT_H(port->id));
|
||||
- port->stats.rx_len[i] += ((u64)val << 32);
|
||||
+ dev->stats.rx_len[i] += ((u64)val << 32);
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L511_CNT_L(port->id));
|
||||
- port->stats.rx_len[i++] += val;
|
||||
+ dev->stats.rx_len[i++] += val;
|
||||
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L1023_CNT_H(port->id));
|
||||
- port->stats.rx_len[i] += ((u64)val << 32);
|
||||
+ dev->stats.rx_len[i] += ((u64)val << 32);
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L1023_CNT_L(port->id));
|
||||
- port->stats.rx_len[i++] += val;
|
||||
+ dev->stats.rx_len[i++] += val;
|
||||
|
||||
val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_LONG_CNT(port->id));
|
||||
- port->stats.rx_len[i++] += val;
|
||||
+ dev->stats.rx_len[i++] += val;
|
||||
+
|
||||
+ u64_stats_update_end(&dev->stats.syncp);
|
||||
+}
|
||||
|
||||
- /* reset mib counters */
|
||||
- airoha_fe_set(eth, REG_FE_GDM_MIB_CLEAR(port->id),
|
||||
+static void airoha_update_hw_stats(struct airoha_gdm_dev *dev)
|
||||
+{
|
||||
+ struct airoha_gdm_port *port = dev->port;
|
||||
+ int i;
|
||||
+
|
||||
+ spin_lock(&port->stats_lock);
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(port->devs); i++) {
|
||||
+ if (port->devs[i])
|
||||
+ airoha_dev_get_hw_stats(port->devs[i]);
|
||||
+ }
|
||||
+
|
||||
+ /* Reset MIB counters */
|
||||
+ airoha_fe_set(dev->eth, REG_FE_GDM_MIB_CLEAR(port->id),
|
||||
FE_GDM_MIB_RX_CLEAR_MASK | FE_GDM_MIB_TX_CLEAR_MASK);
|
||||
|
||||
- u64_stats_update_end(&port->stats.syncp);
|
||||
- spin_unlock(&port->stats.lock);
|
||||
+ spin_unlock(&port->stats_lock);
|
||||
}
|
||||
|
||||
void airoha_set_port_mtu(struct airoha_eth *eth, struct airoha_gdm_port *port)
|
||||
@@ -2228,23 +2256,22 @@ static void airoha_dev_get_stats64(struc
|
||||
struct rtnl_link_stats64 *storage)
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
- struct airoha_gdm_port *port = dev->port;
|
||||
unsigned int start;
|
||||
|
||||
airoha_update_hw_stats(dev);
|
||||
do {
|
||||
- start = u64_stats_fetch_begin(&port->stats.syncp);
|
||||
- storage->rx_packets = port->stats.rx_ok_pkts;
|
||||
- storage->tx_packets = port->stats.tx_ok_pkts;
|
||||
- storage->rx_bytes = port->stats.rx_ok_bytes;
|
||||
- storage->tx_bytes = port->stats.tx_ok_bytes;
|
||||
- storage->multicast = port->stats.rx_multicast;
|
||||
- storage->rx_errors = port->stats.rx_errors;
|
||||
- storage->rx_dropped = port->stats.rx_drops;
|
||||
- storage->tx_dropped = port->stats.tx_drops;
|
||||
- storage->rx_crc_errors = port->stats.rx_crc_error;
|
||||
- storage->rx_over_errors = port->stats.rx_over_errors;
|
||||
- } while (u64_stats_fetch_retry(&port->stats.syncp, start));
|
||||
+ start = u64_stats_fetch_begin(&dev->stats.syncp);
|
||||
+ storage->rx_packets = dev->stats.rx_ok_pkts;
|
||||
+ storage->tx_packets = dev->stats.tx_ok_pkts;
|
||||
+ storage->rx_bytes = dev->stats.rx_ok_bytes;
|
||||
+ storage->tx_bytes = dev->stats.tx_ok_bytes;
|
||||
+ storage->multicast = dev->stats.rx_multicast;
|
||||
+ storage->rx_errors = dev->stats.rx_errors;
|
||||
+ storage->rx_dropped = dev->stats.rx_drops;
|
||||
+ storage->tx_dropped = dev->stats.tx_drops;
|
||||
+ storage->rx_crc_errors = dev->stats.rx_crc_error;
|
||||
+ storage->rx_over_errors = dev->stats.rx_over_errors;
|
||||
+ } while (u64_stats_fetch_retry(&dev->stats.syncp, start));
|
||||
}
|
||||
|
||||
static int airoha_dev_change_mtu(struct net_device *netdev, int mtu)
|
||||
@@ -2639,20 +2666,19 @@ static void airoha_ethtool_get_mac_stats
|
||||
struct ethtool_eth_mac_stats *stats)
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
- struct airoha_gdm_port *port = dev->port;
|
||||
unsigned int start;
|
||||
|
||||
airoha_update_hw_stats(dev);
|
||||
do {
|
||||
- start = u64_stats_fetch_begin(&port->stats.syncp);
|
||||
- stats->FramesTransmittedOK = port->stats.tx_ok_pkts;
|
||||
- stats->OctetsTransmittedOK = port->stats.tx_ok_bytes;
|
||||
- stats->MulticastFramesXmittedOK = port->stats.tx_multicast;
|
||||
- stats->BroadcastFramesXmittedOK = port->stats.tx_broadcast;
|
||||
- stats->FramesReceivedOK = port->stats.rx_ok_pkts;
|
||||
- stats->OctetsReceivedOK = port->stats.rx_ok_bytes;
|
||||
- stats->BroadcastFramesReceivedOK = port->stats.rx_broadcast;
|
||||
- } while (u64_stats_fetch_retry(&port->stats.syncp, start));
|
||||
+ start = u64_stats_fetch_begin(&dev->stats.syncp);
|
||||
+ stats->FramesTransmittedOK = dev->stats.tx_ok_pkts;
|
||||
+ stats->OctetsTransmittedOK = dev->stats.tx_ok_bytes;
|
||||
+ stats->MulticastFramesXmittedOK = dev->stats.tx_multicast;
|
||||
+ stats->BroadcastFramesXmittedOK = dev->stats.tx_broadcast;
|
||||
+ stats->FramesReceivedOK = dev->stats.rx_ok_pkts;
|
||||
+ stats->OctetsReceivedOK = dev->stats.rx_ok_bytes;
|
||||
+ stats->BroadcastFramesReceivedOK = dev->stats.rx_broadcast;
|
||||
+ } while (u64_stats_fetch_retry(&dev->stats.syncp, start));
|
||||
}
|
||||
|
||||
static const struct ethtool_rmon_hist_range airoha_ethtool_rmon_ranges[] = {
|
||||
@@ -2672,8 +2698,7 @@ airoha_ethtool_get_rmon_stats(struct net
|
||||
const struct ethtool_rmon_hist_range **ranges)
|
||||
{
|
||||
struct airoha_gdm_dev *dev = netdev_priv(netdev);
|
||||
- struct airoha_gdm_port *port = dev->port;
|
||||
- struct airoha_hw_stats *hw_stats = &port->stats;
|
||||
+ struct airoha_hw_stats *hw_stats = &dev->stats;
|
||||
unsigned int start;
|
||||
|
||||
BUILD_BUG_ON(ARRAY_SIZE(airoha_ethtool_rmon_ranges) !=
|
||||
@@ -2686,7 +2711,7 @@ airoha_ethtool_get_rmon_stats(struct net
|
||||
do {
|
||||
int i;
|
||||
|
||||
- start = u64_stats_fetch_begin(&port->stats.syncp);
|
||||
+ start = u64_stats_fetch_begin(&dev->stats.syncp);
|
||||
stats->fragments = hw_stats->rx_fragment;
|
||||
stats->jabbers = hw_stats->rx_jabber;
|
||||
for (i = 0; i < ARRAY_SIZE(airoha_ethtool_rmon_ranges) - 1;
|
||||
@@ -2694,7 +2719,7 @@ airoha_ethtool_get_rmon_stats(struct net
|
||||
stats->hist[i] = hw_stats->rx_len[i];
|
||||
stats->hist_tx[i] = hw_stats->tx_len[i];
|
||||
}
|
||||
- } while (u64_stats_fetch_retry(&port->stats.syncp, start));
|
||||
+ } while (u64_stats_fetch_retry(&dev->stats.syncp, start));
|
||||
}
|
||||
|
||||
static int airoha_ethtool_set_priv_flags(struct net_device *netdev, u32 flags)
|
||||
@@ -3702,6 +3727,7 @@ static int airoha_alloc_gdm_device(struc
|
||||
|
||||
netdev->dev.of_node = of_node_get(np);
|
||||
dev = netdev_priv(netdev);
|
||||
+ u64_stats_init(&dev->stats.syncp);
|
||||
dev->dev = netdev;
|
||||
dev->port = port;
|
||||
dev->eth = eth;
|
||||
@@ -3750,9 +3776,8 @@ static int airoha_alloc_gdm_port(struct
|
||||
if (!port)
|
||||
return -ENOMEM;
|
||||
|
||||
- u64_stats_init(&port->stats.syncp);
|
||||
- spin_lock_init(&port->stats.lock);
|
||||
port->id = id;
|
||||
+ spin_lock_init(&port->stats_lock);
|
||||
eth->ports[p] = port;
|
||||
|
||||
err = airoha_metadata_dst_alloc(port);
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
@@ -226,8 +226,6 @@ struct airoha_tx_irq_queue {
|
||||
};
|
||||
|
||||
struct airoha_hw_stats {
|
||||
- /* protect concurrent hw_stats accesses */
|
||||
- spinlock_t lock;
|
||||
struct u64_stats_sync syncp;
|
||||
|
||||
/* get_stats64 */
|
||||
@@ -571,6 +569,8 @@ struct airoha_gdm_dev {
|
||||
|
||||
u32 flags;
|
||||
int nbq;
|
||||
+
|
||||
+ struct airoha_hw_stats stats;
|
||||
};
|
||||
|
||||
struct airoha_gdm_port {
|
||||
@@ -578,7 +578,8 @@ struct airoha_gdm_port {
|
||||
int id;
|
||||
int users;
|
||||
|
||||
- struct airoha_hw_stats stats;
|
||||
+ /* protect concurrent hw_stats accesses */
|
||||
+ spinlock_t stats_lock;
|
||||
|
||||
struct metadata_dst *dsa_meta[AIROHA_MAX_DSA_PORTS];
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
From 1e596dac503da44a9fcd3e2654a4963db3e2ee6a Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Wed, 28 Jan 2026 02:38:24 +0100
|
||||
Subject: [PATCH] net: airoha: fix wrong airoha_get_fe_port()
|
||||
|
||||
It seems the SDK where the airoha_get_fe_port() logic was taken was
|
||||
actually wrong and the AN7583 SoC doesn't have such difference. Instead
|
||||
it does follow the same port order of AN7581 SoC.
|
||||
|
||||
Drop the switch case and apply the same condition on both AN7581 and
|
||||
AN7583 SoC.
|
||||
|
||||
Fixes: e4e5ce823bdd ("net: airoha: Add AN7583 SoC support")
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 14 ++------------
|
||||
1 file changed, 2 insertions(+), 12 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -2353,17 +2353,9 @@ static u32 airoha_get_dsa_tag(struct sk_
|
||||
int airoha_get_fe_port(struct airoha_gdm_dev *dev)
|
||||
{
|
||||
struct airoha_gdm_port *port = dev->port;
|
||||
- struct airoha_eth *eth = dev->eth;
|
||||
|
||||
- switch (eth->soc->version) {
|
||||
- case 0x7583:
|
||||
- return port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3
|
||||
- : port->id;
|
||||
- case 0x7581:
|
||||
- default:
|
||||
- return port->id == AIROHA_GDM4_IDX ? FE_PSE_PORT_GDM4
|
||||
- : port->id;
|
||||
- }
|
||||
+ return port->id == AIROHA_GDM4_IDX ? FE_PSE_PORT_GDM4
|
||||
+ : port->id;
|
||||
}
|
||||
|
||||
static int airoha_dev_set_features(struct net_device *netdev,
|
||||
@@ -10,6 +10,7 @@ FEATURES:=fpu dt gpio ramdisk squashfs usb
|
||||
SUBTARGETS:=nand sata
|
||||
|
||||
KERNEL_PATCHVER:=6.12
|
||||
KERNEL_TESTING_PATCHVER:=6.18
|
||||
|
||||
define Target/Description
|
||||
Build images for AppliedMicro APM821xx based boards.
|
||||
|
||||
@@ -0,0 +1,269 @@
|
||||
# CONFIG_440_CPU is not set
|
||||
CONFIG_44x=y
|
||||
CONFIG_464_CPU=y
|
||||
CONFIG_4xx=y
|
||||
# CONFIG_ADVANCED_OPTIONS is not set
|
||||
CONFIG_APM821xx=y
|
||||
# CONFIG_APOLLO3G is not set
|
||||
# CONFIG_ARCHES is not set
|
||||
CONFIG_ARCH_32BIT_OFF_T=y
|
||||
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
|
||||
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
|
||||
CONFIG_ARCH_KEEP_MEMBLOCK=y
|
||||
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
|
||||
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
|
||||
CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
|
||||
CONFIG_ARCH_MMAP_RND_BITS=11
|
||||
CONFIG_ARCH_MMAP_RND_BITS_MAX=17
|
||||
CONFIG_ARCH_MMAP_RND_BITS_MIN=11
|
||||
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=17
|
||||
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
|
||||
CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
|
||||
CONFIG_ARCH_PKEY_BITS=5
|
||||
CONFIG_ARCH_SPLIT_ARG64=y
|
||||
CONFIG_ARCH_STACKWALK=y
|
||||
CONFIG_ARCH_SUSPEND_POSSIBLE=y
|
||||
CONFIG_ARCH_WEAK_RELEASE_ACQUIRE=y
|
||||
CONFIG_AUDIT_ARCH=y
|
||||
# CONFIG_BAMBOO is not set
|
||||
# CONFIG_BLK_DEV_INITRD is not set
|
||||
CONFIG_BLUESTONE=y
|
||||
CONFIG_BOOKE=y
|
||||
CONFIG_BOOKE_WDT=y
|
||||
# CONFIG_CANYONLANDS is not set
|
||||
CONFIG_CLONE_BACKWARDS=y
|
||||
CONFIG_CMDLINE="rootfstype=squashfs noinitrd"
|
||||
CONFIG_CMDLINE_FROM_BOOTLOADER=y
|
||||
CONFIG_COMMON_CLK=y
|
||||
CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
|
||||
CONFIG_COMPAT_32BIT_TIME=y
|
||||
CONFIG_CPU_BIG_ENDIAN=y
|
||||
CONFIG_CPU_MITIGATIONS=y
|
||||
CONFIG_CRC16=y
|
||||
CONFIG_CRYPTO_DEFLATE=y
|
||||
CONFIG_CRYPTO_ECB=y
|
||||
CONFIG_CRYPTO_JITTERENTROPY=y
|
||||
CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKS=64
|
||||
CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKSIZE=32
|
||||
CONFIG_CRYPTO_JITTERENTROPY_OSR=1
|
||||
CONFIG_CRYPTO_LIB_GF128MUL=y
|
||||
CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
|
||||
CONFIG_CRYPTO_LIB_UTILS=y
|
||||
CONFIG_CRYPTO_LZO=y
|
||||
CONFIG_CRYPTO_RNG=y
|
||||
CONFIG_CRYPTO_SHA3=y
|
||||
CONFIG_DATA_SHIFT=12
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_DMADEVICES=y
|
||||
CONFIG_DMA_DIRECT_REMAP=y
|
||||
CONFIG_DMA_ENGINE=y
|
||||
CONFIG_DMA_NEED_SYNC=y
|
||||
CONFIG_DMA_OF=y
|
||||
CONFIG_DTC=y
|
||||
CONFIG_DW_DMAC=y
|
||||
CONFIG_DW_DMAC_CORE=y
|
||||
CONFIG_EARLY_PRINTK=y
|
||||
# CONFIG_EBONY is not set
|
||||
CONFIG_EDAC_ATOMIC_SCRUB=y
|
||||
CONFIG_EDAC_SUPPORT=y
|
||||
# CONFIG_EIGER is not set
|
||||
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
|
||||
CONFIG_EXTRA_TARGETS="uImage"
|
||||
CONFIG_FIXED_PHY=y
|
||||
CONFIG_FORCE_NR_CPUS=y
|
||||
CONFIG_FORCE_PCI=y
|
||||
# CONFIG_FSL_LBC is not set
|
||||
CONFIG_FS_IOMAP=y
|
||||
CONFIG_FUNCTION_ALIGNMENT=4
|
||||
CONFIG_FUNCTION_ALIGNMENT_4B=y
|
||||
CONFIG_FWNODE_MDIO=y
|
||||
CONFIG_FW_LOADER_PAGED_BUF=y
|
||||
CONFIG_FW_LOADER_SYSFS=y
|
||||
CONFIG_GENERIC_ALLOCATOR=y
|
||||
CONFIG_GENERIC_ATOMIC64=y
|
||||
CONFIG_GENERIC_BUG=y
|
||||
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS=y
|
||||
CONFIG_GENERIC_CMOS_UPDATE=y
|
||||
CONFIG_GENERIC_CPU_AUTOPROBE=y
|
||||
CONFIG_GENERIC_EARLY_IOREMAP=y
|
||||
CONFIG_GENERIC_GETTIMEOFDAY=y
|
||||
CONFIG_GENERIC_IDLE_POLL_SETUP=y
|
||||
CONFIG_GENERIC_IOREMAP=y
|
||||
CONFIG_GENERIC_IRQ_SHOW=y
|
||||
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
|
||||
CONFIG_GENERIC_ISA_DMA=y
|
||||
CONFIG_GENERIC_MSI_IRQ=y
|
||||
CONFIG_GENERIC_PCI_IOMAP=y
|
||||
CONFIG_GENERIC_PHY=y
|
||||
CONFIG_GENERIC_SMP_IDLE_THREAD=y
|
||||
CONFIG_GENERIC_STRNCPY_FROM_USER=y
|
||||
CONFIG_GENERIC_STRNLEN_USER=y
|
||||
CONFIG_GENERIC_TIME_VSYSCALL=y
|
||||
# CONFIG_GEN_RTC is not set
|
||||
# CONFIG_GLACIER is not set
|
||||
CONFIG_GPIO_CDEV=y
|
||||
CONFIG_GPIO_GENERIC=y
|
||||
CONFIG_GPIO_GENERIC_PLATFORM=y
|
||||
CONFIG_HAS_DMA=y
|
||||
CONFIG_HAS_IOMEM=y
|
||||
CONFIG_HAS_IOPORT=y
|
||||
CONFIG_HAS_IOPORT_MAP=y
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_BOARDINFO=y
|
||||
CONFIG_I2C_CHARDEV=y
|
||||
CONFIG_I2C_IBM_IIC=y
|
||||
CONFIG_IBM_EMAC=y
|
||||
CONFIG_IBM_EMAC_EMAC4=y
|
||||
CONFIG_IBM_EMAC_POLL_WEIGHT=32
|
||||
CONFIG_IBM_EMAC_RGMII=y
|
||||
CONFIG_IBM_EMAC_RXB=128
|
||||
CONFIG_IBM_EMAC_RX_COPY_THRESHOLD=256
|
||||
CONFIG_IBM_EMAC_TAH=y
|
||||
CONFIG_IBM_EMAC_TXB=128
|
||||
# CONFIG_ICON is not set
|
||||
CONFIG_ILLEGAL_POINTER_VALUE=0
|
||||
CONFIG_IRQCHIP=y
|
||||
CONFIG_IRQ_DOMAIN=y
|
||||
CONFIG_IRQ_DOMAIN_HIERARCHY=y
|
||||
CONFIG_IRQ_FORCED_THREADING=y
|
||||
CONFIG_IRQ_WORK=y
|
||||
CONFIG_ISA_DMA_API=y
|
||||
# CONFIG_JFFS2_FS is not set
|
||||
# CONFIG_KATMAI is not set
|
||||
CONFIG_KERNEL_START=0xc0000000
|
||||
CONFIG_LEDS_TRIGGER_MTD=y
|
||||
CONFIG_LEDS_TRIGGER_PATTERN=y
|
||||
CONFIG_LIBFDT=y
|
||||
CONFIG_LOCK_DEBUGGING_SUPPORT=y
|
||||
CONFIG_LOWMEM_SIZE=0x30000000
|
||||
CONFIG_LZO_COMPRESS=y
|
||||
CONFIG_LZO_DECOMPRESS=y
|
||||
# CONFIG_MATH_EMULATION is not set
|
||||
CONFIG_MDIO_BUS=y
|
||||
CONFIG_MIGRATION=y
|
||||
CONFIG_MMU_GATHER_MERGE_VMAS=y
|
||||
CONFIG_MMU_GATHER_PAGE_SIZE=y
|
||||
CONFIG_MMU_LAZY_TLB_REFCOUNT=y
|
||||
CONFIG_MODULES_SIZE=1
|
||||
CONFIG_MODULES_USE_ELF_RELA=y
|
||||
CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS=y
|
||||
CONFIG_MTD_CFI_ADV_OPTIONS=y
|
||||
# CONFIG_MTD_CFI_GEOMETRY is not set
|
||||
# CONFIG_MTD_SPLIT_SQUASHFS_ROOT is not set
|
||||
CONFIG_NEED_DMA_MAP_STATE=y
|
||||
CONFIG_NEED_PER_CPU_KM=y
|
||||
CONFIG_NEED_SG_DMA_LENGTH=y
|
||||
CONFIG_NET_EGRESS=y
|
||||
CONFIG_NET_INGRESS=y
|
||||
CONFIG_NET_SELFTESTS=y
|
||||
CONFIG_NET_XGRESS=y
|
||||
CONFIG_NOT_COHERENT_CACHE=y
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_NO_HZ_COMMON=y
|
||||
CONFIG_NO_HZ_IDLE=y
|
||||
CONFIG_NR_CPUS=1
|
||||
CONFIG_NR_IRQS=512
|
||||
CONFIG_NVMEM=y
|
||||
CONFIG_NVMEM_LAYOUTS=y
|
||||
CONFIG_NVMEM_SYSFS=y
|
||||
CONFIG_OBJTOOL=y
|
||||
CONFIG_OF=y
|
||||
CONFIG_OF_ADDRESS=y
|
||||
CONFIG_OF_EARLY_FLATTREE=y
|
||||
CONFIG_OF_FLATTREE=y
|
||||
CONFIG_OF_GPIO=y
|
||||
CONFIG_OF_IRQ=y
|
||||
CONFIG_OF_KOBJ=y
|
||||
CONFIG_OF_MDIO=y
|
||||
CONFIG_OLD_SIGACTION=y
|
||||
CONFIG_OLD_SIGSUSPEND=y
|
||||
CONFIG_PACKING=y
|
||||
CONFIG_PAGE_BLOCK_MAX_ORDER=11
|
||||
CONFIG_PAGE_OFFSET=0xc0000000
|
||||
CONFIG_PAGE_POOL=y
|
||||
CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
|
||||
CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
|
||||
CONFIG_PCI=y
|
||||
CONFIG_PCIEAER=y
|
||||
CONFIG_PCIEPORTBUS=y
|
||||
CONFIG_PCI_DISABLE_COMMON_QUIRKS=y
|
||||
CONFIG_PCI_DOMAINS=y
|
||||
CONFIG_PCI_MSI=y
|
||||
CONFIG_PCI_MSI_ARCH_FALLBACKS=y
|
||||
CONFIG_PGTABLE_LEVELS=2
|
||||
CONFIG_PHYLIB=y
|
||||
CONFIG_PHYLIB_LEDS=y
|
||||
CONFIG_PHYSICAL_START=0x00000000
|
||||
CONFIG_PHYS_64BIT=y
|
||||
CONFIG_PHYS_ADDR_T_64BIT=y
|
||||
# CONFIG_PMU_SYSFS is not set
|
||||
CONFIG_PPC=y
|
||||
CONFIG_PPC32=y
|
||||
CONFIG_PPC44x_SIMPLE=y
|
||||
CONFIG_PPC4xx_GPIO=y
|
||||
CONFIG_PPC4xx_PCI_EXPRESS=y
|
||||
# CONFIG_PPC64 is not set
|
||||
# CONFIG_PPC_47x is not set
|
||||
# CONFIG_PPC_85xx is not set
|
||||
# CONFIG_PPC_8xx is not set
|
||||
CONFIG_PPC_ADV_DEBUG_DACS=2
|
||||
CONFIG_PPC_ADV_DEBUG_DAC_RANGE=y
|
||||
CONFIG_PPC_ADV_DEBUG_DVCS=2
|
||||
CONFIG_PPC_ADV_DEBUG_IACS=4
|
||||
CONFIG_PPC_ADV_DEBUG_REGS=y
|
||||
# CONFIG_PPC_BOOK3S_32 is not set
|
||||
CONFIG_PPC_DCR=y
|
||||
CONFIG_PPC_DCR_NATIVE=y
|
||||
# CONFIG_PPC_EARLY_DEBUG is not set
|
||||
CONFIG_PPC_FPU=y
|
||||
CONFIG_PPC_FPU_REGS=y
|
||||
CONFIG_PPC_INDIRECT_PCI=y
|
||||
CONFIG_PPC_KUAP=y
|
||||
# CONFIG_PPC_KUAP_DEBUG is not set
|
||||
CONFIG_PPC_KUEP=y
|
||||
CONFIG_PPC_MMU_NOHASH=y
|
||||
# CONFIG_PPC_PCI_BUS_NUM_DOMAIN_DEPENDENT is not set
|
||||
CONFIG_PPC_UDBG_16550=y
|
||||
CONFIG_PPC_WERROR=y
|
||||
CONFIG_PTE_64BIT=y
|
||||
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
|
||||
# CONFIG_RAINIER is not set
|
||||
CONFIG_RANDSTRUCT_NONE=y
|
||||
CONFIG_RAS=y
|
||||
CONFIG_RATIONAL=y
|
||||
CONFIG_REGULATOR=y
|
||||
CONFIG_RSEQ=y
|
||||
# CONFIG_SAM440EP is not set
|
||||
# CONFIG_SCOM_DEBUGFS is not set
|
||||
# CONFIG_SEQUOIA is not set
|
||||
CONFIG_SERIAL_8250_FSL=y
|
||||
CONFIG_SERIAL_MCTRL_GPIO=y
|
||||
CONFIG_SERIAL_OF_PLATFORM=y
|
||||
CONFIG_SMT_NUM_THREADS_DYNAMIC=y
|
||||
CONFIG_SOFTIRQ_ON_OWN_STACK=y
|
||||
CONFIG_SPARSE_IRQ=y
|
||||
# CONFIG_STATIC_CALL_SELFTEST is not set
|
||||
CONFIG_SWPHY=y
|
||||
CONFIG_SYSCTL_EXCEPTION_TRACE=y
|
||||
# CONFIG_TAISHAN is not set
|
||||
CONFIG_TARGET_CPU="464"
|
||||
CONFIG_TARGET_CPU_BOOL=y
|
||||
CONFIG_TASK_SIZE=0xc0000000
|
||||
CONFIG_THREAD_INFO_IN_TASK=y
|
||||
CONFIG_THREAD_SHIFT=13
|
||||
CONFIG_TICK_CPU_ACCOUNTING=y
|
||||
CONFIG_TINY_SRCU=y
|
||||
# CONFIG_TOOLCHAIN_DEFAULT_CPU is not set
|
||||
CONFIG_USB_SUPPORT=y
|
||||
CONFIG_VDSO32=y
|
||||
CONFIG_VDSO_GETRANDOM=y
|
||||
# CONFIG_VIRTIO_MENU is not set
|
||||
# CONFIG_VIRT_CPU_ACCOUNTING_NATIVE is not set
|
||||
# CONFIG_WARP is not set
|
||||
CONFIG_WATCHDOG_CORE=y
|
||||
CONFIG_XZ_DEC_BCJ=y
|
||||
CONFIG_XZ_DEC_POWERPC=y
|
||||
# CONFIG_YOSEMITE is not set
|
||||
CONFIG_ZLIB_DEFLATE=y
|
||||
CONFIG_ZLIB_INFLATE=y
|
||||
@@ -0,0 +1,30 @@
|
||||
From 0f18b7fdec817f94ad9ebeb6076ad914e0334299 Mon Sep 17 00:00:00 2001
|
||||
From: Rosen Penev <rosenp@gmail.com>
|
||||
Date: Fri, 15 May 2026 15:54:59 -0700
|
||||
Subject: [PATCH] powerpc/44x: Set GPIO chip firmware node
|
||||
|
||||
The PPC4xx GPIO driver stopped assigning an explicit firmware node
|
||||
to the gpio_chip when it moved away from of_mm_gpiochip_add_data().
|
||||
|
||||
Restore that association from the platform device so OF GPIO lookup
|
||||
can match phandles to the registered gpiochip.
|
||||
|
||||
Tested on: Cisco MX60W. No more probe deferral.
|
||||
|
||||
Assisted-by: Codex:GPT-5.5
|
||||
Fixes: 1044dbaf2a77 ("powerpc/44x: Change GPIO driver to a proper platform driver")
|
||||
Signed-off-by: Rosen Penev <rosenp@gmail.com>
|
||||
---
|
||||
arch/powerpc/platforms/44x/gpio.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/arch/powerpc/platforms/44x/gpio.c
|
||||
+++ b/arch/powerpc/platforms/44x/gpio.c
|
||||
@@ -169,6 +169,7 @@ static int ppc4xx_gpio_probe(struct plat
|
||||
|
||||
gc = &chip->gc;
|
||||
|
||||
+ gc->parent = dev;
|
||||
gc->base = -1;
|
||||
gc->ngpio = 32;
|
||||
gc->direction_input = ppc4xx_gpio_dir_in;
|
||||
@@ -0,0 +1,30 @@
|
||||
--- a/arch/powerpc/platforms/44x/Kconfig
|
||||
+++ b/arch/powerpc/platforms/44x/Kconfig
|
||||
@@ -118,6 +118,17 @@ config CANYONLANDS
|
||||
help
|
||||
This option enables support for the AMCC PPC460EX evaluation board.
|
||||
|
||||
+config APOLLO3G
|
||||
+ bool "Apollo3G"
|
||||
+ depends on 44x
|
||||
+ default n
|
||||
+ select PPC44x_SIMPLE
|
||||
+ select APM821xx
|
||||
+ select IBM_EMAC_RGMII
|
||||
+ select 460EX
|
||||
+ help
|
||||
+ This option enables support for the AMCC Apollo 3G board.
|
||||
+
|
||||
config GLACIER
|
||||
bool "Glacier"
|
||||
depends on 44x
|
||||
--- a/arch/powerpc/platforms/44x/ppc44x_simple.c
|
||||
+++ b/arch/powerpc/platforms/44x/ppc44x_simple.c
|
||||
@@ -46,6 +46,7 @@ machine_device_initcall(ppc44x_simple, p
|
||||
* board.c file for it rather than adding it to this list.
|
||||
*/
|
||||
static char *board[] __initdata = {
|
||||
+ "amcc,apollo3g",
|
||||
"amcc,arches",
|
||||
"amcc,bamboo",
|
||||
"apm,bluestone",
|
||||
@@ -0,0 +1,51 @@
|
||||
--- a/arch/powerpc/platforms/44x/pci.c
|
||||
+++ b/arch/powerpc/platforms/44x/pci.c
|
||||
@@ -1053,15 +1053,24 @@ static int __init apm821xx_pciex_init_po
|
||||
u32 val;
|
||||
|
||||
/*
|
||||
- * Do a software reset on PCIe ports.
|
||||
- * This code is to fix the issue that pci drivers doesn't re-assign
|
||||
- * bus number for PCIE devices after Uboot
|
||||
- * scanned and configured all the buses (eg. PCIE NIC IntelPro/1000
|
||||
- * PT quad port, SAS LSI 1064E)
|
||||
+ * Only reset the PHY when no link is currently established.
|
||||
+ * This is for the Atheros PCIe board which has problems to establish
|
||||
+ * the link (again) after this PHY reset. All other currently tested
|
||||
+ * PCIe boards don't show this problem.
|
||||
*/
|
||||
-
|
||||
- mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x0);
|
||||
- mdelay(10);
|
||||
+ val = mfdcri(SDR0, port->sdr_base + PESDRn_LOOP);
|
||||
+ if (!(val & 0x00001000)) {
|
||||
+ /*
|
||||
+ * Do a software reset on PCIe ports.
|
||||
+ * This code is to fix the issue that pci drivers doesn't re-assign
|
||||
+ * bus number for PCIE devices after Uboot
|
||||
+ * scanned and configured all the buses (eg. PCIE NIC IntelPro/1000
|
||||
+ * PT quad port, SAS LSI 1064E)
|
||||
+ */
|
||||
+
|
||||
+ mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x0);
|
||||
+ mdelay(10);
|
||||
+ }
|
||||
|
||||
if (port->endpoint)
|
||||
val = PTYPE_LEGACY_ENDPOINT << 20;
|
||||
@@ -1078,9 +1087,12 @@ static int __init apm821xx_pciex_init_po
|
||||
mtdcri(SDR0, PESDR0_460EX_L0DRV, 0x00000130);
|
||||
mtdcri(SDR0, PESDR0_460EX_L0CLK, 0x00000006);
|
||||
|
||||
- mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x10000000);
|
||||
- mdelay(50);
|
||||
- mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x30000000);
|
||||
+ val = mfdcri(SDR0, port->sdr_base + PESDRn_LOOP);
|
||||
+ if (!(val & 0x00001000)) {
|
||||
+ mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x10000000);
|
||||
+ mdelay(50);
|
||||
+ mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x30000000);
|
||||
+ }
|
||||
|
||||
mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET,
|
||||
mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET) |
|
||||
@@ -0,0 +1,14 @@
|
||||
--- a/arch/powerpc/platforms/44x/pci.c
|
||||
+++ b/arch/powerpc/platforms/44x/pci.c
|
||||
@@ -1795,9 +1795,9 @@ static void __init ppc4xx_configure_pcie
|
||||
* if it works
|
||||
*/
|
||||
out_le32(mbase + PECFG_PIM0LAL, 0x00000000);
|
||||
- out_le32(mbase + PECFG_PIM0LAH, 0x00000000);
|
||||
+ out_le32(mbase + PECFG_PIM0LAH, 0x00000008);
|
||||
out_le32(mbase + PECFG_PIM1LAL, 0x00000000);
|
||||
- out_le32(mbase + PECFG_PIM1LAH, 0x00000000);
|
||||
+ out_le32(mbase + PECFG_PIM1LAH, 0x0000000c);
|
||||
out_le32(mbase + PECFG_PIM01SAH, 0xffff0000);
|
||||
out_le32(mbase + PECFG_PIM01SAL, 0x00000000);
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
From f992336a598ce4508b75e25dff755715f38b9b8e Mon Sep 17 00:00:00 2001
|
||||
From: Rosen Penev <rosenp@gmail.com>
|
||||
Date: Sat, 16 May 2026 16:31:09 -0700
|
||||
Subject: [PATCH] net: ibm: emac: Clear MAL descriptors without memset
|
||||
|
||||
Clear MAL descriptor rings with explicit field stores instead of
|
||||
memset(). The descriptor rings are carved from MAL coherent DMA memory,
|
||||
which may be mapped uncached on 32-bit powerpc. The optimized memset()
|
||||
path can use dcbz there and trigger an alignment warning.
|
||||
|
||||
The skb tracking arrays remain ordinary CPU memory and still use memset().
|
||||
|
||||
Assisted-by: Codex:GPT-5.5
|
||||
Signed-off-by: Rosen Penev <rosenp@gmail.com>
|
||||
---
|
||||
drivers/net/ethernet/ibm/emac/core.c | 15 +++++++++++++--
|
||||
1 file changed, 13 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/ibm/emac/core.c
|
||||
+++ b/drivers/net/ethernet/ibm/emac/core.c
|
||||
@@ -1161,6 +1161,17 @@ static void emac_clean_rx_ring(struct em
|
||||
}
|
||||
}
|
||||
|
||||
+static void emac_clear_mal_desc(struct mal_descriptor *desc, int count)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < count; i++) {
|
||||
+ desc[i].ctrl = 0;
|
||||
+ desc[i].data_len = 0;
|
||||
+ desc[i].data_ptr = 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int
|
||||
__emac_prepare_rx_skb(struct sk_buff *skb, struct emac_instance *dev, int slot)
|
||||
{
|
||||
@@ -3086,8 +3097,8 @@ static int emac_probe(struct platform_de
|
||||
DBG(dev, "rx_desc %p" NL, dev->rx_desc);
|
||||
|
||||
/* Clean rings */
|
||||
- memset(dev->tx_desc, 0, NUM_TX_BUFF * sizeof(struct mal_descriptor));
|
||||
- memset(dev->rx_desc, 0, NUM_RX_BUFF * sizeof(struct mal_descriptor));
|
||||
+ emac_clear_mal_desc(dev->tx_desc, NUM_TX_BUFF);
|
||||
+ emac_clear_mal_desc(dev->rx_desc, NUM_RX_BUFF);
|
||||
memset(dev->tx_skb, 0, NUM_TX_BUFF * sizeof(struct sk_buff *));
|
||||
memset(dev->rx_skb, 0, NUM_RX_BUFF * sizeof(struct sk_buff *));
|
||||
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
From 286eda6cb8c69e38ef83b2e73b14bb92b482ad9d Mon Sep 17 00:00:00 2001
|
||||
From: Rosen Penev <rosenp@gmail.com>
|
||||
Date: Thu, 21 May 2026 13:52:11 -0700
|
||||
Subject: [PATCH] net: ibm_emac: Use napi_gro_receive() for Rx packets
|
||||
|
||||
emac_poll_rx() already runs in NAPI context and TAH-equipped EMACs set
|
||||
CHECKSUM_UNNECESSARY on verified frames, which lets GRO coalesce TCP
|
||||
segments without a software checksum on the merge path. Replace the
|
||||
per-poll rx_list batched with netif_receive_skb_list() with direct
|
||||
napi_gro_receive() calls so the stack can merge segments into super-skbs
|
||||
and skip a full traversal per packet -- a meaningful win on the slow
|
||||
4xx-class CPUs this driver targets.
|
||||
|
||||
Small routing speed improvement tested on a Cisco Meraki MX60W:
|
||||
|
||||
Tested with iperf3
|
||||
|
||||
Before:
|
||||
|
||||
[ ID] Interval Transfer Bitrate Retr
|
||||
[ 5] 0.00-10.00 sec 494 MBytes 414 Mbits/sec 839 sender
|
||||
[ 5] 0.00-10.04 sec 492 MBytes 411 Mbits/sec receiver
|
||||
|
||||
After:
|
||||
|
||||
[ ID] Interval Transfer Bitrate Retr
|
||||
[ 5] 0.00-10.00 sec 510 MBytes 428 Mbits/sec 580 sender
|
||||
[ 5] 0.00-10.04 sec 508 MBytes 424 Mbits/sec receiver
|
||||
|
||||
Traffic to and from the router seems to be slow no matter what:
|
||||
|
||||
Tested with iperf3 --bidir
|
||||
|
||||
Before:
|
||||
|
||||
[ ID][Role] Interval Transfer Bitrate Retr
|
||||
[ 8][TX-C] 0.00-10.00 sec 297 MBytes 249 Mbits/sec 35 sender
|
||||
[ 8][TX-C] 0.00-10.00 sec 293 MBytes 245 Mbits/sec receiver
|
||||
[ 10][RX-C] 0.00-10.00 sec 184 MBytes 154 Mbits/sec 0 sender
|
||||
[ 10][RX-C] 0.00-10.00 sec 184 MBytes 154 Mbits/sec receiver
|
||||
|
||||
After:
|
||||
|
||||
[ ID][Role] Interval Transfer Bitrate Retr
|
||||
[ 8][TX-C] 0.00-10.00 sec 295 MBytes 248 Mbits/sec 31 sender
|
||||
[ 8][TX-C] 0.00-10.00 sec 294 MBytes 246 Mbits/sec receiver
|
||||
[ 10][RX-C] 0.00-10.00 sec 181 MBytes 152 Mbits/sec 0 sender
|
||||
[ 10][RX-C] 0.00-10.00 sec 181 MBytes 152 Mbits/sec receiver
|
||||
|
||||
Assisted-by: Claude:Opus-4.7
|
||||
Signed-off-by: Rosen Penev <rosenp@gmail.com>
|
||||
---
|
||||
drivers/net/ethernet/ibm/emac/core.c | 5 +----
|
||||
1 file changed, 1 insertion(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/ibm/emac/core.c
|
||||
+++ b/drivers/net/ethernet/ibm/emac/core.c
|
||||
@@ -1738,7 +1738,6 @@ static inline int emac_rx_sg_append(stru
|
||||
/* NAPI poll context */
|
||||
static int emac_poll_rx(void *param, int budget)
|
||||
{
|
||||
- LIST_HEAD(rx_list);
|
||||
struct emac_instance *dev = param;
|
||||
int slot = dev->rx_slot, received = 0;
|
||||
|
||||
@@ -1795,7 +1794,7 @@ static int emac_poll_rx(void *param, int
|
||||
skb->protocol = eth_type_trans(skb, dev->ndev);
|
||||
emac_rx_csum(dev, skb, ctrl);
|
||||
|
||||
- list_add_tail(&skb->list, &rx_list);
|
||||
+ napi_gro_receive(&dev->mal->napi, skb);
|
||||
next:
|
||||
++dev->stats.rx_packets;
|
||||
skip:
|
||||
@@ -1839,8 +1838,6 @@ static int emac_poll_rx(void *param, int
|
||||
goto next;
|
||||
}
|
||||
|
||||
- netif_receive_skb_list(&rx_list);
|
||||
-
|
||||
if (received) {
|
||||
DBG2(dev, "rx %d BDs" NL, received);
|
||||
dev->rx_slot = slot;
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
From c9395ad54e2cabb87d408becc37566f3d8248933 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Lamparter <chunkeey@gmail.com>
|
||||
Date: Sun, 1 Dec 2019 02:08:23 +0100
|
||||
Subject: [PATCH] powerpc: bootwrapper: force gzip as mkimage's compression
|
||||
method
|
||||
|
||||
Due to CONFIG_KERNEL_XZ symbol, the bootwrapper code tries to
|
||||
instruct the mkimage to use the xz compression, which isn't
|
||||
supported. This patch forces the gzip compression, which is
|
||||
supported and doesn't matter because the generated uImage for
|
||||
the apm821xx target gets ignored as the OpenWrt toolchain will
|
||||
do separate U-Boot kernel images for each device individually.
|
||||
|
||||
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
|
||||
---
|
||||
arch/powerpc/boot/Makefile | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/arch/powerpc/boot/Makefile
|
||||
+++ b/arch/powerpc/boot/Makefile
|
||||
@@ -270,7 +270,7 @@ compressor-$(CONFIG_KERNEL_LZO) := lzo
|
||||
|
||||
# args (to if_changed): 1 = (this rule), 2 = platform, 3 = dts 4=dtb 5=initrd
|
||||
quiet_cmd_wrap = WRAP $@
|
||||
- cmd_wrap =$(CONFIG_SHELL) $(wrapper) -Z $(compressor-y) -c -o $@ -p $2 \
|
||||
+ cmd_wrap =$(CONFIG_SHELL) $(wrapper) -Z gzip -c -o $@ -p $2 \
|
||||
$(CROSSWRAP) $(if $3, -s $3)$(if $4, -d $4)$(if $5, -i $5) \
|
||||
vmlinux
|
||||
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
From 78bddfc01439de243624b1e60a7f599ec11b55b7 Mon Sep 17 00:00:00 2001
|
||||
From: Rosen Penev <rosenp@gmail.com>
|
||||
Date: Sat, 16 May 2026 16:08:49 -0700
|
||||
Subject: [PATCH] dma-direct: Clear pages before coherent remap
|
||||
|
||||
Clear pages through their page mapping before creating a coherent
|
||||
remap for dma-direct allocations. Some architectures implement the
|
||||
coherent remap as uncached memory, where the generic memset() path may
|
||||
use cache-only zeroing instructions that are not valid for the returned
|
||||
CPU mapping.
|
||||
|
||||
Keep the existing memset() for non-remapped allocations, but avoid
|
||||
normal memset() on the remapped coherent allocation path.
|
||||
|
||||
Assisted-by: Codex:GPT-5.5
|
||||
Signed-off-by: Rosen Penev <rosenp@gmail.com>
|
||||
---
|
||||
kernel/dma/direct.c | 20 ++++++++++++++++++--
|
||||
1 file changed, 18 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/kernel/dma/direct.c
|
||||
+++ b/kernel/dma/direct.c
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <linux/export.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/dma-map-ops.h>
|
||||
+#include <linux/highmem.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/pfn.h>
|
||||
#include <linux/vmalloc.h>
|
||||
@@ -104,6 +105,15 @@ static void __dma_direct_free_pages(stru
|
||||
dma_free_contiguous(dev, page, size);
|
||||
}
|
||||
|
||||
+static void dma_direct_zero_pages(struct page *page, size_t size)
|
||||
+{
|
||||
+ unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
|
||||
+ unsigned long i;
|
||||
+
|
||||
+ for (i = 0; i < count; i++)
|
||||
+ clear_highpage(page + i);
|
||||
+}
|
||||
+
|
||||
static struct page *dma_direct_alloc_swiotlb(struct device *dev, size_t size)
|
||||
{
|
||||
struct page *page = swiotlb_alloc(dev, size);
|
||||
@@ -268,6 +278,13 @@ void *dma_direct_alloc(struct device *de
|
||||
if (remap) {
|
||||
pgprot_t prot = dma_pgprot(dev, PAGE_KERNEL, attrs);
|
||||
|
||||
+ /*
|
||||
+ * Zero via the page mapping before creating a potentially
|
||||
+ * uncached remap. Some architectures cannot safely run normal
|
||||
+ * memset on uncached memory.
|
||||
+ */
|
||||
+ dma_direct_zero_pages(page, size);
|
||||
+
|
||||
if (force_dma_unencrypted(dev))
|
||||
prot = pgprot_decrypted(prot);
|
||||
|
||||
@@ -283,10 +300,9 @@ void *dma_direct_alloc(struct device *de
|
||||
ret = page_address(page);
|
||||
if (dma_set_decrypted(dev, ret, size))
|
||||
goto out_leak_pages;
|
||||
+ memset(ret, 0, size);
|
||||
}
|
||||
|
||||
- memset(ret, 0, size);
|
||||
-
|
||||
if (set_uncached) {
|
||||
arch_dma_prep_coherent(page, size);
|
||||
ret = arch_dma_set_uncached(ret, size);
|
||||
@@ -15,8 +15,6 @@ CONFIG_BROADCOM_PHY=y
|
||||
CONFIG_BUFFER_HEAD=y
|
||||
CONFIG_CRYPTO_CRC32=y
|
||||
CONFIG_CRYPTO_CRC32C=y
|
||||
CONFIG_CRYPTO_MD5_PPC=y
|
||||
CONFIG_CRYPTO_SHA1_PPC=y
|
||||
# CONFIG_DM_CRYPT is not set
|
||||
# CONFIG_DM_INIT is not set
|
||||
# CONFIG_DM_MIRROR is not set
|
||||
@@ -49,12 +47,6 @@ CONFIG_PM_WAKELOCKS=y
|
||||
CONFIG_PM_WAKELOCKS_GC=y
|
||||
CONFIG_PM_WAKELOCKS_LIMIT=100
|
||||
CONFIG_PPC4xx_CPM=y
|
||||
CONFIG_PPC_EARLY_DEBUG=y
|
||||
# CONFIG_PPC_EARLY_DEBUG_16550 is not set
|
||||
CONFIG_PPC_EARLY_DEBUG_44x=y
|
||||
CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH=0x4
|
||||
CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW=0xef600300
|
||||
# CONFIG_PPC_EARLY_DEBUG_MEMCONS is not set
|
||||
CONFIG_REGULATOR_FIXED_VOLTAGE=y
|
||||
CONFIG_SATA_DWC=y
|
||||
CONFIG_SATA_HOST=y
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user