Merge Official Source

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
Tianling Shen
2026-03-20 23:42:42 +08:00
65 changed files with 1555 additions and 252 deletions
+1 -1
View File
@@ -146,7 +146,7 @@ list_conffiles() {
' /usr/lib/opkg/status ' /usr/lib/opkg/status
elif [ -d /lib/apk/packages ]; then elif [ -d /lib/apk/packages ]; then
conffiles="" conffiles=""
for file in /lib/apk/packages/*.conffiles_static; do for file in $(find /lib/apk/packages -name "*.conffiles_static" -type f); do
conffiles="$(echo -e "$(cat $file)\n$conffiles")" conffiles="$(echo -e "$(cat $file)\n$conffiles")"
done done
echo "$conffiles" echo "$conffiles"
@@ -164,3 +164,26 @@
return 0; return 0;
} }
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2429,6 +2429,7 @@ static bool ath9k_hw_dfs_tested(struct ath_hw *ah)
static void ath9k_gpio_cap_init(struct ath_hw *ah)
{
struct ath9k_hw_capabilities *pCap = &ah->caps;
+ u32 gpio_mask = pCap->gpio_mask;
if (AR_SREV_9271(ah)) {
pCap->num_gpio_pins = AR9271_NUM_GPIO;
@@ -2479,6 +2480,12 @@ static void ath9k_gpio_cap_init(struct ath_hw *ah)
pCap->num_gpio_pins = AR_NUM_GPIO;
pCap->gpio_mask = AR_GPIO_MASK;
}
+
+ if (gpio_mask) {
+ pCap->gpio_mask = gpio_mask;
+ ath_info(ath9k_hw_common(ah), "Use overridden gpio mask 0x%x\n",
+ gpio_mask);
+ }
}
int ath9k_hw_fill_cap_info(struct ath_hw *ah)
@@ -1,44 +0,0 @@
From 9c9a3c27b96e057f3c3f47151d7a170d84e3bb5f Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Sun, 15 Oct 2023 15:31:47 +0200
Subject: [PATCH 4/5] wifi: rt2x00: Support EEPROM swap binding
Add binding "ralink,eeprom-swap" to swap bytes of EEPROM before using
it.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c
@@ -19,6 +19,19 @@
#include "rt2x00.h"
#if IS_ENABLED(CONFIG_MTD)
+static void rt2800lib_eeprom_swap(struct rt2x00_dev *rt2x00dev)
+{
+ struct device_node *np = rt2x00dev->dev->of_node;
+ size_t len = rt2x00dev->ops->eeprom_size;
+ int i;
+
+ if (!of_property_present(np, "ralink,eeprom-swap"))
+ return;
+
+ for (i = 0; i < len / sizeof(u16); i++)
+ rt2x00dev->eeprom[i] = swab16(rt2x00dev->eeprom[i]);
+}
+
static int rt2800lib_read_eeprom_mtd(struct rt2x00_dev *rt2x00dev)
{
struct device_node *np = rt2x00dev->dev->of_node, *mtd_np = NULL;
@@ -64,6 +77,8 @@ static int rt2800lib_read_eeprom_mtd(str
return ret;
}
+ rt2800lib_eeprom_swap(rt2x00dev);
+
dev_info(rt2x00dev->dev, "loaded eeprom from mtd device \"%s\"\n", part);
return ret;
@@ -21,7 +21,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c --- a/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c
@@ -15,10 +15,10 @@ @@ -15,6 +15,7 @@
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#endif #endif
@@ -29,19 +29,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
#include "rt2x00.h" #include "rt2x00.h"
-#if IS_ENABLED(CONFIG_MTD) @@ -70,6 +71,38 @@ static int rt2800lib_read_eeprom_mtd(str
static void rt2800lib_eeprom_swap(struct rt2x00_dev *rt2x00dev)
{
struct device_node *np = rt2x00dev->dev->of_node;
@@ -32,6 +32,7 @@ static void rt2800lib_eeprom_swap(struct
rt2x00dev->eeprom[i] = swab16(rt2x00dev->eeprom[i]);
}
+#if IS_ENABLED(CONFIG_MTD)
static int rt2800lib_read_eeprom_mtd(struct rt2x00_dev *rt2x00dev)
{
struct device_node *np = rt2x00dev->dev->of_node, *mtd_np = NULL;
@@ -85,6 +86,40 @@ static int rt2800lib_read_eeprom_mtd(str
} }
#endif #endif
@@ -72,8 +60,6 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+ +
+ memcpy(rt2x00dev->eeprom, data, len); + memcpy(rt2x00dev->eeprom, data, len);
+ +
+ rt2800lib_eeprom_swap(rt2x00dev);
+
+exit: +exit:
+ kfree(data); + kfree(data);
+ return ret; + return ret;
@@ -82,7 +68,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
static const char * static const char *
rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev) rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev)
{ {
@@ -152,6 +187,10 @@ int rt2x00lib_read_eeprom(struct rt2x00_ @@ -137,6 +170,10 @@ int rt2x00lib_read_eeprom(struct rt2x00_
return 0; return 0;
#endif #endif
@@ -35,9 +35,9 @@ Signed-off-by: Coia Prant <coiaprant@gmail.com>
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c --- a/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c
@@ -32,6 +32,27 @@ static void rt2800lib_eeprom_swap(struct @@ -19,6 +19,27 @@
rt2x00dev->eeprom[i] = swab16(rt2x00dev->eeprom[i]);
} #include "rt2x00.h"
+static int rt2800lib_read_eeprom_data(struct rt2x00_dev *rt2x00dev) +static int rt2800lib_read_eeprom_data(struct rt2x00_dev *rt2x00dev)
+{ +{
@@ -63,7 +63,7 @@ Signed-off-by: Coia Prant <coiaprant@gmail.com>
#if IS_ENABLED(CONFIG_MTD) #if IS_ENABLED(CONFIG_MTD)
static int rt2800lib_read_eeprom_mtd(struct rt2x00_dev *rt2x00dev) static int rt2800lib_read_eeprom_mtd(struct rt2x00_dev *rt2x00dev)
{ {
@@ -181,6 +202,10 @@ int rt2x00lib_read_eeprom(struct rt2x00_ @@ -164,6 +185,10 @@ int rt2x00lib_read_eeprom(struct rt2x00_
{ {
int ret; int ret;
@@ -0,0 +1,33 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Wed, 18 Mar 2026 20:01:16 +0000
Subject: [PATCH] mac80211: report assoc_link_id in station info for non-MLD
STAs on MLD AP
When a non-MLD station associates with an MLD AP, it does so on a
specific link. However, sta_set_sinfo() never sets mlo_params_valid,
so nl80211 never emits NL80211_ATTR_MLO_LINK_ID in get_station /
dump_station responses. Userspace has no way to determine which link
a non-MLD STA is associated on.
Set mlo_params_valid to 1 and assoc_link_id to sta->deflink.link_id,
when valid_links is set.
Also set the mld_addr copy only for MLD STAs, so that non-MLD STAs
get a zeroed mld_addr as documented.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -3252,7 +3252,10 @@ void sta_set_sinfo(struct sta_info *sta,
struct link_sta_info *link_sta;
int link_id;
- ether_addr_copy(sinfo->mld_addr, sta->addr);
+ sinfo->mlo_params_valid = true;
+ sinfo->assoc_link_id = sta->deflink.link_id;
+ if (sta->sta.mlo)
+ ether_addr_copy(sinfo->mld_addr, sta->addr);
/* assign valid links first for iteration */
sinfo->valid_links = sta->sta.valid_links;
+4 -4
View File
@@ -1,16 +1,16 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=mt76 PKG_NAME:=mt76
PKG_RELEASE=2 PKG_RELEASE=1
PKG_LICENSE:=BSD-3-Clause-Clear PKG_LICENSE:=BSD-3-Clause-Clear
PKG_LICENSE_FILES:= PKG_LICENSE_FILES:=
PKG_SOURCE_URL:=https://github.com/openwrt/mt76 PKG_SOURCE_URL:=https://github.com/openwrt/mt76
PKG_SOURCE_PROTO:=git PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2026-03-05 PKG_SOURCE_DATE:=2026-03-19
PKG_SOURCE_VERSION:=9f95baf93a070692ed922a2fc57ef8bfde801c84 PKG_SOURCE_VERSION:=39c960c3ada558b4c2e7915772483d3731573d09
PKG_MIRROR_HASH:=eaca371ec6f8d0f089d098a3f7fc8c5819aea090e05f4f3d9e8a9b2a2d4f2ff8 PKG_MIRROR_HASH:=7a9f8ea21eee5324e6638ace627dd305b3650ae6ca86109317d9ee83702140eb
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name> PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
PKG_USE_NINJA:=0 PKG_USE_NINJA:=0
@@ -1,42 +0,0 @@
From e78688a4f44478a9270813ac494fc548ed6b3be9 Mon Sep 17 00:00:00 2001
From: David Bauer <mail@david-bauer.net>
Date: Fri, 13 Mar 2026 12:19:37 +0100
Subject: [PATCH] wifi: mt76: mt7915: set mt76 specific PS flag
mt76 tracks the PSM state of a sta internally with a wcid flag. TX to
such clients is skipped based on the presence of this flag.
This flag was not added to the PS state notify handler for MT7915 chips.
Without this flag, mt76 queues pending frames to the hardware,
accounting for airtime when a PSM notification is received while in a TX
iteration.
Set the PS flag for the STA WCID to prevent this from happening. TX gets
skipped in presence of this flag.
Link: https://patchwork.kernel.org/project/linux-wireless/patch/20260313112502.2026974-1-mail@david-bauer.net/
Signed-off-by: David Bauer <mail@david-bauer.net>
---
mt7915/mcu.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/mt7915/mcu.c b/mt7915/mcu.c
index 6625f905..52c89d2b 100644
--- a/mt7915/mcu.c
+++ b/mt7915/mcu.c
@@ -421,6 +421,11 @@ static void mt7915_mcu_rx_ps_sync(struct mt7915_dev *dev, struct sk_buff *skb)
if (!sta)
goto out;
+ if (p->ps_bit)
+ set_bit(MT_WCID_FLAG_PS, &wcid->flags);
+ else
+ clear_bit(MT_WCID_FLAG_PS, &wcid->flags);
+
ieee80211_sta_ps_transition_ni(sta, !!p->ps_bit);
out:
--
2.51.0
@@ -351,13 +351,13 @@ function device_htmode_append(config) {
if (vht_capab & 0x800 && config.su_beamformer) if (vht_capab & 0x800 && config.su_beamformer)
config.vht_capab += '[SOUNDING-DIMENSION-' + min(((vht_capab >> 16) & 3) + 1, config.beamformer_antennas) + ']'; config.vht_capab += '[SOUNDING-DIMENSION-' + min(((vht_capab >> 16) & 3) + 1, config.beamformer_antennas) + ']';
if (vht_capab & 0x1000 && config.su_beamformee) if (vht_capab & 0x1000 && config.su_beamformee)
config.vht_capab += '[BF-ANTENNA-' + min(((vht_capab >> 13) & 3) + 1, config.beamformer_antennas) + ']'; config.vht_capab += '[BF-ANTENNA-' + min(((vht_capab >> 13) & 3) + 1, config.beamformee_antennas) + ']';
/* supported Channel widths */ /* supported Channel widths */
if (((vht_capab & 0xc) == 4 || (vht_capab & 0xc) == 8) && config.vht160 >= 1)
config.vht_capab += '[VHT160]';
if ((vht_capab & 0xc) == 8 && config.vht160 >= 2) if ((vht_capab & 0xc) == 8 && config.vht160 >= 2)
config.vht_capab += '[VHT160-80PLUS80]'; config.vht_capab += '[VHT160-80PLUS80]';
else if (((vht_capab & 0xc) == 4 || (vht_capab & 0xc) == 8) && config.vht160 >= 1)
config.vht_capab += '[VHT160]';
/* maximum MPDU length */ /* maximum MPDU length */
if ((vht_capab & 3) > 1 && config.vht_max_mpdu >= 11454) if ((vht_capab & 3) > 1 && config.vht_max_mpdu >= 11454)
@@ -1212,6 +1212,9 @@ hostapd_rrm_beacon_req(struct ubus_context *ctx, struct ubus_object *obj,
if (tb[BEACON_REQ_REPORTING_DETAIL]) if (tb[BEACON_REQ_REPORTING_DETAIL])
reporting_detail = blobmsg_get_u32(tb[BEACON_REQ_REPORTING_DETAIL]); reporting_detail = blobmsg_get_u32(tb[BEACON_REQ_REPORTING_DETAIL]);
if (reporting_detail >= 0 && reporting_detail < 3)
buf_len += 3;
req = wpabuf_alloc(buf_len); req = wpabuf_alloc(buf_len);
if (!req) if (!req)
return UBUS_STATUS_UNKNOWN_ERROR; return UBUS_STATUS_UNKNOWN_ERROR;
@@ -1245,7 +1248,7 @@ hostapd_rrm_beacon_req(struct ubus_context *ctx, struct ubus_object *obj,
/* as per 9-104 */ /* as per 9-104 */
wpabuf_put_u8(req, 2); wpabuf_put_u8(req, 2);
wpabuf_put_u8(req, 1); wpabuf_put_u8(req, 1);
wpabuf_put_le16(req, reporting_detail); wpabuf_put_u8(req, reporting_detail);
} }
ret = hostapd_send_beacon_req(hapd, addr, 0, req); ret = hostapd_send_beacon_req(hapd, addr, 0, req);
@@ -2016,6 +2019,7 @@ void hostapd_ubus_notify_beacon_report(
blob_buf_init(&b, 0); blob_buf_init(&b, 0);
blobmsg_add_macaddr(&b, "address", addr); blobmsg_add_macaddr(&b, "address", addr);
blobmsg_add_u32(&b, "token", token);
blobmsg_add_u16(&b, "op-class", rep->op_class); blobmsg_add_u16(&b, "op-class", rep->op_class);
blobmsg_add_u16(&b, "channel", rep->channel); blobmsg_add_u16(&b, "channel", rep->channel);
blobmsg_add_u64(&b, "start-time", rep->start_time); blobmsg_add_u64(&b, "start-time", rep->start_time);
@@ -2025,7 +2029,7 @@ void hostapd_ubus_notify_beacon_report(
blobmsg_add_u16(&b, "rsni", rep->rsni); blobmsg_add_u16(&b, "rsni", rep->rsni);
blobmsg_add_macaddr(&b, "bssid", rep->bssid); blobmsg_add_macaddr(&b, "bssid", rep->bssid);
blobmsg_add_u16(&b, "antenna-id", rep->antenna_id); blobmsg_add_u16(&b, "antenna-id", rep->antenna_id);
blobmsg_add_u16(&b, "parent-tsf", rep->parent_tsf); blobmsg_add_u32(&b, "parent-tsf", rep->parent_tsf);
blobmsg_add_u16(&b, "rep-mode", rep_mode); blobmsg_add_u16(&b, "rep-mode", rep_mode);
encoded = base64_encode(rep, len, NULL); encoded = base64_encode(rep, len, NULL);
if (encoded) { if (encoded) {
@@ -2090,9 +2094,9 @@ void hostapd_ubus_notify_bss_transition_response(
blob_buf_init(&b, 0); blob_buf_init(&b, 0);
blobmsg_add_macaddr(&b, "address", addr); blobmsg_add_macaddr(&b, "address", addr);
blobmsg_add_u8(&b, "dialog-token", dialog_token); blobmsg_add_u32(&b, "dialog-token", dialog_token);
blobmsg_add_u8(&b, "status-code", status_code); blobmsg_add_u32(&b, "status-code", status_code);
blobmsg_add_u8(&b, "bss-termination-delay", bss_termination_delay); blobmsg_add_u32(&b, "bss-termination-delay", bss_termination_delay);
if (target_bssid) if (target_bssid)
blobmsg_add_macaddr(&b, "target-bssid", target_bssid); blobmsg_add_macaddr(&b, "target-bssid", target_bssid);
@@ -2119,8 +2123,8 @@ int hostapd_ubus_notify_bss_transition_query(
blob_buf_init(&b, 0); blob_buf_init(&b, 0);
blobmsg_add_macaddr(&b, "address", addr); blobmsg_add_macaddr(&b, "address", addr);
blobmsg_add_u8(&b, "dialog-token", dialog_token); blobmsg_add_u32(&b, "dialog-token", dialog_token);
blobmsg_add_u8(&b, "reason", reason); blobmsg_add_u32(&b, "reason", reason);
hostapd_ubus_notify_bss_transition_add_candidate_list(candidate_list, candidate_list_len); hostapd_ubus_notify_bss_transition_add_candidate_list(candidate_list, candidate_list_len);
if (!hapd->ubus.notify_response) { if (!hapd->ubus.notify_response) {
@@ -19,6 +19,7 @@ an7581_setup_interfaces()
;; ;;
nokia,valyrian) nokia,valyrian)
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 10g" "wan" ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 10g" "wan"
;;
*) *)
echo "Unsupported hardware. Network interfaces not initialized" echo "Unsupported hardware. Network interfaces not initialized"
;; ;;
@@ -184,12 +184,32 @@
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pcie0_rst_pins>; pinctrl-0 = <&pcie0_rst_pins>;
status = "okay"; status = "okay";
pcie@0,0 {
reg = <0x0000 0 0 0 0>;
wifi@0,0 {
compatible = "mediatek,mt76";
reg = <0x0000 0 0 0 0>;
airoha,npu = <&npu>;
airoha,eth = <&eth>;
};
};
}; };
&pcie1 { &pcie1 {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pcie1_rst_pins>; pinctrl-0 = <&pcie1_rst_pins>;
status = "okay"; status = "okay";
pcie@1,0 {
reg = <0x0000 0 0 0 0>;
wifi@0,0 {
compatible = "mediatek,mt76";
reg = <0x0000 0 0 0 0>;
airoha,npu = <&npu>;
airoha,eth = <&eth>;
};
};
}; };
&pcie2 { &pcie2 {
+20
View File
@@ -196,12 +196,32 @@
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pcie0_rst_pins>; pinctrl-0 = <&pcie0_rst_pins>;
status = "okay"; status = "okay";
pcie@0,0 {
reg = <0x0000 0 0 0 0>;
wifi@0,0 {
compatible = "mediatek,mt76";
reg = <0x0000 0 0 0 0>;
airoha,npu = <&npu>;
airoha,eth = <&eth>;
};
};
}; };
&pcie1 { &pcie1 {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pcie1_rst_pins>; pinctrl-0 = <&pcie1_rst_pins>;
status = "okay"; status = "okay";
pcie@1,0 {
reg = <0x0000 0 0 0 0>;
wifi@0,0 {
compatible = "mediatek,mt76";
reg = <0x0000 0 0 0 0>;
airoha,npu = <&npu>;
airoha,eth = <&eth>;
};
};
}; };
&npu { &npu {
+1 -1
View File
@@ -87,7 +87,7 @@ define Device/gemtek_w1700k-ubi
DEVICE_PACKAGES := airoha-en7581-mt7996-npu-firmware \ DEVICE_PACKAGES := airoha-en7581-mt7996-npu-firmware \
fitblk kmod-i2c-an7581 kmod-hwmon-nct7802 \ fitblk kmod-i2c-an7581 kmod-hwmon-nct7802 \
kmod-mt7996-firmware kmod-phy-rtl8261n \ kmod-mt7996-firmware kmod-phy-rtl8261n \
wpad-basic-mbedtls wpad-openssl
UBINIZE_OPTS := -E 5 UBINIZE_OPTS := -E 5
BLOCKSIZE := 128k BLOCKSIZE := 128k
PAGESIZE := 2048 PAGESIZE := 2048
@@ -0,0 +1,34 @@
From a7fc8c641cab855824c45e5e8877e40fd528b5df Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Fri, 2 Jan 2026 12:29:38 +0100
Subject: [PATCH] net: airoha: Fix npu rx DMA definitions
Fix typos in npu rx DMA descriptor definitions.
Fixes: b3ef7bdec66fb ("net: airoha: Add airoha_offload.h header")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20260102-airoha-npu-dma-rx-def-fixes-v1-1-205fc6bf7d94@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
include/linux/soc/airoha/airoha_offload.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- a/include/linux/soc/airoha/airoha_offload.h
+++ b/include/linux/soc/airoha/airoha_offload.h
@@ -71,12 +71,12 @@ static inline void airoha_ppe_dev_check_
#define NPU_RX1_DESC_NUM 512
/* CTRL */
-#define NPU_RX_DMA_DESC_LAST_MASK BIT(29)
-#define NPU_RX_DMA_DESC_LEN_MASK GENMASK(28, 15)
-#define NPU_RX_DMA_DESC_CUR_LEN_MASK GENMASK(14, 1)
+#define NPU_RX_DMA_DESC_LAST_MASK BIT(27)
+#define NPU_RX_DMA_DESC_LEN_MASK GENMASK(26, 14)
+#define NPU_RX_DMA_DESC_CUR_LEN_MASK GENMASK(13, 1)
#define NPU_RX_DMA_DESC_DONE_MASK BIT(0)
/* INFO */
-#define NPU_RX_DMA_PKT_COUNT_MASK GENMASK(31, 28)
+#define NPU_RX_DMA_PKT_COUNT_MASK GENMASK(31, 29)
#define NPU_RX_DMA_PKT_ID_MASK GENMASK(28, 26)
#define NPU_RX_DMA_SRC_PORT_MASK GENMASK(25, 21)
#define NPU_RX_DMA_CRSN_MASK GENMASK(20, 16)
@@ -0,0 +1,89 @@
From 5e7365b5a1ac8f517a7a84442289d7de242deb76 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Sun, 14 Dec 2025 10:30:07 +0100
Subject: [PATCH] net: airoha: Move net_devs registration in a dedicated
routine
Since airoha_probe() is not executed under rtnl lock, there is small race
where a given device is configured by user-space while the remaining ones
are not completely loaded from the dts yet. This condition will allow a
hw device misconfiguration since there are some conditions (e.g. GDM2 check
in airoha_dev_init()) that require all device are properly loaded from the
device tree. Fix the issue moving net_devices registration at the end of
the airoha_probe routine.
Fixes: 9cd451d414f6e ("net: airoha: Add loopback support for GDM2")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20251214-airoha-fix-dev-registration-v1-1-860e027ad4c6@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
drivers/net/ethernet/airoha/airoha_eth.c | 39 ++++++++++++++++--------
1 file changed, 26 insertions(+), 13 deletions(-)
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2924,19 +2924,26 @@ static int airoha_alloc_gdm_port(struct
port->id = id;
eth->ports[p] = port;
- err = airoha_metadata_dst_alloc(port);
- if (err)
- return err;
+ return airoha_metadata_dst_alloc(port);
+}
- err = register_netdev(dev);
- if (err)
- goto free_metadata_dst;
+static int airoha_register_gdm_devices(struct airoha_eth *eth)
+{
+ int i;
- return 0;
+ for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
+ struct airoha_gdm_port *port = eth->ports[i];
+ int err;
+
+ if (!port)
+ continue;
+
+ err = register_netdev(port->dev);
+ if (err)
+ return err;
+ }
-free_metadata_dst:
- airoha_metadata_dst_free(port);
- return err;
+ return 0;
}
static int airoha_probe(struct platform_device *pdev)
@@ -3027,6 +3034,10 @@ static int airoha_probe(struct platform_
}
}
+ err = airoha_register_gdm_devices(eth);
+ if (err)
+ goto error_napi_stop;
+
return 0;
error_napi_stop:
@@ -3040,10 +3051,12 @@ error_hw_cleanup:
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
struct airoha_gdm_port *port = eth->ports[i];
- if (port && port->dev->reg_state == NETREG_REGISTERED) {
+ if (!port)
+ continue;
+
+ if (port->dev->reg_state == NETREG_REGISTERED)
unregister_netdev(port->dev);
- airoha_metadata_dst_free(port);
- }
+ airoha_metadata_dst_free(port);
}
free_netdev(eth->napi_dev);
platform_set_drvdata(pdev, NULL);
@@ -0,0 +1,132 @@
From 4d513329b87c1bd0546d9f0288794e244322daa6 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Mon, 5 Jan 2026 10:40:47 +0100
Subject: [PATCH] net: airoha: Use gdm port enum value whenever possible
Use AIROHA_GDMx_IDX enum value whenever possible.
This patch is just cosmetic changes and does not introduce any logic one.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20260105-airoha-use-port-idx-enum-v1-1-503ca5763858@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 40 +++++++++++++-----------
1 file changed, 21 insertions(+), 19 deletions(-)
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -108,11 +108,11 @@ static int airoha_set_vip_for_gdm_port(s
u32 vip_port;
switch (port->id) {
- case 3:
+ case AIROHA_GDM3_IDX:
/* FIXME: handle XSI_PCIE1_PORT */
vip_port = XSI_PCIE0_VIP_PORT_MASK;
break;
- case 4:
+ case AIROHA_GDM4_IDX:
/* FIXME: handle XSI_USB_PORT */
vip_port = XSI_ETH_VIP_PORT_MASK;
break;
@@ -514,8 +514,8 @@ static int airoha_fe_init(struct airoha_
FIELD_PREP(IP_ASSEMBLE_PORT_MASK, 0) |
FIELD_PREP(IP_ASSEMBLE_NBQ_MASK, 22));
- airoha_fe_set(eth, REG_GDM_FWD_CFG(3), GDM_PAD_EN_MASK);
- airoha_fe_set(eth, REG_GDM_FWD_CFG(4), GDM_PAD_EN_MASK);
+ airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM3_IDX), GDM_PAD_EN_MASK);
+ airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM4_IDX), GDM_PAD_EN_MASK);
airoha_fe_crsn_qsel_init(eth);
@@ -1690,27 +1690,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;
- 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_MASK);
+ airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX),
+ pse_port);
+ airoha_fe_clear(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX),
+ GDM_STRIP_CRC_MASK);
/* Enable GDM2 loopback */
- airoha_fe_wr(eth, REG_GDM_TXCHN_EN(2), 0xffffffff);
- airoha_fe_wr(eth, REG_GDM_RXCHN_EN(2), 0xffff);
+ airoha_fe_wr(eth, REG_GDM_TXCHN_EN(AIROHA_GDM2_IDX), 0xffffffff);
+ airoha_fe_wr(eth, REG_GDM_RXCHN_EN(AIROHA_GDM2_IDX), 0xffff);
chan = port->id == AIROHA_GDM3_IDX ? airoha_is_7581(eth) ? 4 : 3 : 0;
- airoha_fe_rmw(eth, REG_GDM_LPBK_CFG(2),
+ airoha_fe_rmw(eth, REG_GDM_LPBK_CFG(AIROHA_GDM2_IDX),
LPBK_CHAN_MASK | LPBK_MODE_MASK | LPBK_EN_MASK,
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(2),
+ 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));
/* Disable VIP and IFC for GDM2 */
- airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(2));
- airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(2));
+ 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));
/* XXX: handle XSI_USB_PORT and XSI_PCE1_PORT */
nbq = port->id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0;
@@ -1746,8 +1748,8 @@ static int airoha_dev_init(struct net_de
airoha_set_macaddr(port, dev->dev_addr);
switch (port->id) {
- case 3:
- case 4:
+ case AIROHA_GDM3_IDX:
+ case AIROHA_GDM4_IDX:
/* If GDM2 is active we can't enable loopback */
if (!eth->ports[1]) {
int err;
@@ -1757,7 +1759,7 @@ static int airoha_dev_init(struct net_de
return err;
}
fallthrough;
- case 2:
+ case AIROHA_GDM2_IDX:
if (airoha_ppe_is_enabled(eth, 1)) {
/* For PPE2 always use secondary cpu port. */
fe_cpu_port = FE_PSE_PORT_CDM2;
@@ -3101,14 +3103,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) {
- case 3:
+ case AIROHA_GDM3_IDX:
/* 7581 SoC supports PCIe serdes on GDM3 port */
if (nbq == 4)
return HSGMII_LAN_7581_PCIE0_SRCPORT;
if (nbq == 5)
return HSGMII_LAN_7581_PCIE1_SRCPORT;
break;
- case 4:
+ case AIROHA_GDM4_IDX:
/* 7581 SoC supports eth and usb serdes on GDM4 port */
if (!nbq)
return HSGMII_LAN_7581_ETH_SRCPORT;
@@ -3132,12 +3134,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) {
- case 3:
+ case AIROHA_GDM3_IDX:
/* 7583 SoC supports eth serdes on GDM3 port */
if (!nbq)
return HSGMII_LAN_7583_ETH_SRCPORT;
break;
- case 4:
+ case AIROHA_GDM4_IDX:
/* 7583 SoC supports PCIe and USB serdes on GDM4 port */
if (!nbq)
return HSGMII_LAN_7583_PCIE_SRCPORT;
@@ -0,0 +1,36 @@
From e4bc5dd53bf5d46cd58f081ffccc3809e2be5373 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Mon, 5 Jan 2026 09:49:16 +0100
Subject: [PATCH] net: airoha: npu: Dump fw version during probe
Dump firmware version running on the npu during module probe.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20260105-airoha-npu-dump-fw-v1-1-36d8326975f8@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/airoha/airoha_npu.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/drivers/net/ethernet/airoha/airoha_npu.c
+++ b/drivers/net/ethernet/airoha/airoha_npu.c
@@ -658,6 +658,7 @@ static int airoha_npu_probe(struct platf
struct device_node *np;
void __iomem *base;
int i, irq, err;
+ u32 val;
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
@@ -757,6 +758,11 @@ static int airoha_npu_probe(struct platf
regmap_write(npu->regmap, REG_CR_BOOT_TRIGGER, 0x1);
msleep(100);
+ if (!airoha_npu_wlan_msg_get(npu, 0, WLAN_FUNC_GET_WAIT_NPU_VERSION,
+ &val, sizeof(val), GFP_KERNEL))
+ dev_info(dev, "NPU fw version: %0d.%d\n",
+ (val >> 16) & 0xffff, val & 0xffff);
+
platform_set_drvdata(pdev, npu);
return 0;
@@ -0,0 +1,41 @@
From 6abcf751bc084804a9e5b3051442e8a2ce67f48a Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Mon, 5 Jan 2026 09:43:31 +0100
Subject: [PATCH] net: airoha: Fix schedule while atomic in airoha_ppe_deinit()
airoha_ppe_deinit() runs airoha_npu_ppe_deinit() in atomic context.
airoha_npu_ppe_deinit routine allocates ppe_data buffer with GFP_KERNEL
flag. Rely on rcu_replace_pointer in airoha_ppe_deinit routine in order
to fix schedule while atomic issue in airoha_npu_ppe_deinit() since we
do not need atomic context there.
Fixes: 00a7678310fe3 ("net: airoha: Introduce flowtable offload support")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20260105-airoha-fw-ethtool-v2-1-3b32b158cc31@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
drivers/net/ethernet/airoha/airoha_ppe.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
@@ -1547,13 +1547,16 @@ void airoha_ppe_deinit(struct airoha_eth
{
struct airoha_npu *npu;
- rcu_read_lock();
- npu = rcu_dereference(eth->npu);
+ mutex_lock(&flow_offload_mutex);
+
+ npu = rcu_replace_pointer(eth->npu, NULL,
+ lockdep_is_held(&flow_offload_mutex));
if (npu) {
npu->ops.ppe_deinit(npu);
airoha_npu_put(npu);
}
- rcu_read_unlock();
+
+ mutex_unlock(&flow_offload_mutex);
rhashtable_destroy(&eth->ppe->l2_flows);
rhashtable_destroy(&eth->flow_table);
@@ -16,7 +16,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
--- a/drivers/net/ethernet/airoha/airoha_eth.c --- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2844,6 +2844,7 @@ static const struct ethtool_ops airoha_e @@ -2805,6 +2805,7 @@ static const struct ethtool_ops airoha_e
.get_drvinfo = airoha_ethtool_get_drvinfo, .get_drvinfo = airoha_ethtool_get_drvinfo,
.get_eth_mac_stats = airoha_ethtool_get_mac_stats, .get_eth_mac_stats = airoha_ethtool_get_mac_stats,
.get_rmon_stats = airoha_ethtool_get_rmon_stats, .get_rmon_stats = airoha_ethtool_get_rmon_stats,
@@ -0,0 +1,37 @@
From 6406fc709ace081575de2a8a7eee12e63d4c96c6 Mon Sep 17 00:00:00 2001
From: Sayantan Nandy <sayantann11@gmail.com>
Date: Mon, 19 Jan 2026 13:06:58 +0530
Subject: [PATCH] net: airoha_eth: increase max MTU to 9220 for DSA jumbo
frames
The industry standard jumbo frame MTU is 9216 bytes. When using the DSA
subsystem, a 4-byte tag is added to each Ethernet frame.
Increase AIROHA_MAX_MTU to 9220 bytes (9216 + 4) so that users can set a
standard 9216-byte MTU on DSA ports.
The underlying hardware supports significantly larger frame sizes
(approximately 16K). However, the maximum MTU is limited to 9220 bytes
for now, as this is sufficient to support standard jumbo frames and does
not incur additional memory allocation overhead.
Signed-off-by: Sayantan Nandy <sayantann11@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20260119073658.6216-1-sayantann11@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -21,7 +21,7 @@
#define AIROHA_MAX_NUM_IRQ_BANKS 4
#define AIROHA_MAX_DSA_PORTS 7
#define AIROHA_MAX_NUM_RSTS 3
-#define AIROHA_MAX_MTU 9216
+#define AIROHA_MAX_MTU 9220
#define AIROHA_MAX_PACKET_SIZE 2048
#define AIROHA_NUM_QOS_CHANNELS 4
#define AIROHA_NUM_QOS_QUEUES 8
@@ -108,7 +108,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
} }
static irqreturn_t airoha_npu_mbox_handler(int irq, void *npu_instance) static irqreturn_t airoha_npu_mbox_handler(int irq, void *npu_instance)
@@ -791,6 +823,8 @@ module_platform_driver(airoha_npu_driver @@ -797,6 +829,8 @@ module_platform_driver(airoha_npu_driver
MODULE_FIRMWARE(NPU_EN7581_FIRMWARE_DATA); MODULE_FIRMWARE(NPU_EN7581_FIRMWARE_DATA);
MODULE_FIRMWARE(NPU_EN7581_FIRMWARE_RV32); MODULE_FIRMWARE(NPU_EN7581_FIRMWARE_RV32);
@@ -0,0 +1,53 @@
From aebf15e8eb09b01e99f043e9f5d423798aac9d32 Mon Sep 17 00:00:00 2001
From: Zhengping Zhang <aquapinn@qq.com>
Date: Thu, 26 Feb 2026 10:37:08 +0800
Subject: [PATCH] net: airoha: fix typo in function name
Corrected the typo in the function name from
`airhoa_is_lan_gdm_port` to `airoha_is_lan_gdm_port`. This change ensures
consistency in the API naming convention.
Signed-off-by: Zhengping Zhang <aquapinn@qq.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/tencent_E4FD5D6BC0131E617D848896F5F9FCED6E0A@qq.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 2 +-
drivers/net/ethernet/airoha/airoha_eth.h | 2 +-
drivers/net/ethernet/airoha/airoha_ppe.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -76,7 +76,7 @@ static void airoha_set_macaddr(struct ai
struct airoha_eth *eth = port->qdma->eth;
u32 val, reg;
- reg = airhoa_is_lan_gdm_port(port) ? REG_FE_LAN_MAC_H
+ reg = airoha_is_lan_gdm_port(port) ? 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);
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -626,7 +626,7 @@ u32 airoha_rmw(void __iomem *base, u32 o
#define airoha_qdma_clear(qdma, offset, val) \
airoha_rmw((qdma)->regs, (offset), (val), 0)
-static inline bool airhoa_is_lan_gdm_port(struct airoha_gdm_port *port)
+static inline bool airoha_is_lan_gdm_port(struct airoha_gdm_port *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
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
@@ -321,7 +321,7 @@ static int airoha_ppe_foe_entry_prepare(
/* For downlink traffic consume SRAM memory for hw
* forwarding descriptors queue.
*/
- if (airhoa_is_lan_gdm_port(port))
+ if (airoha_is_lan_gdm_port(port))
val |= AIROHA_FOE_IB2_FAST_PATH;
if (dsa_port >= 0)
val |= FIELD_PREP(AIROHA_FOE_IB2_NBQ,
@@ -0,0 +1,44 @@
From 7600fb3b41dd6ab65ed61169df1b6099044edf97 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Wed, 4 Mar 2026 11:56:47 +0100
Subject: [PATCH] net: airoha: Rely __field_prep for non-constant masks
Rely on __field_prep macros for non-constant masks preparing the values
for register updates instead of open-coding.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20260304-airoha-__field_prep-v1-1-b185facc4e2f@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1727,7 +1727,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),
- FE_PSE_PORT_CDM2 << __ffs(SP_CPORT_MASK(val)));
+ __field_prep(SP_CPORT_MASK(val), FE_PSE_PORT_CDM2));
if (port->id != AIROHA_GDM3_IDX && airoha_is_7581(eth))
airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6,
@@ -1781,7 +1781,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),
- fe_cpu_port << __ffs(DFT_CPORT_MASK(port->id)));
+ __field_prep(DFT_CPORT_MASK(port->id), fe_cpu_port));
return 0;
}
@@ -2138,7 +2138,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),
- mode << __ffs(CHAN_QOS_MODE_MASK(channel)));
+ __field_prep(CHAN_QOS_MODE_MASK(channel), mode));
return 0;
}
@@ -0,0 +1,52 @@
From bf3471e6e6c02137dc0d26caa783ac1849f9aab8 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Fri, 6 Mar 2026 09:07:27 +0100
Subject: [PATCH] net: airoha: Make flow control source port mapping dependent
on nbq parameter
Flow control source port mapping for USB serdes needs to be configured
according to the GDM port nbq parameter. This is a preliminary patch
since nbq parameter is specific for the given port serdes and needs to
be read from the DTS (in the current codebase is assigned statically).
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20260306-airoha-fix-loopback-for-usb-serdes-v2-1-319de9c96826@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 10 ++++++----
drivers/net/ethernet/airoha/airoha_regs.h | 5 +----
2 files changed, 7 insertions(+), 8 deletions(-)
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1729,10 +1729,12 @@ static int airhoha_set_gdm2_loopback(str
SP_CPORT_MASK(val),
__field_prep(SP_CPORT_MASK(val), FE_PSE_PORT_CDM2));
- if (port->id != AIROHA_GDM3_IDX && airoha_is_7581(eth))
- airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6,
- FC_ID_OF_SRC_PORT24_MASK,
- FIELD_PREP(FC_ID_OF_SRC_PORT24_MASK, 2));
+ if (port->id == AIROHA_GDM4_IDX && airoha_is_7581(eth)) {
+ u32 mask = FC_ID_OF_SRC_PORT_MASK(nbq);
+
+ airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6, mask,
+ __field_prep(mask, AIROHA_GDM2_IDX));
+ }
return 0;
}
--- a/drivers/net/ethernet/airoha/airoha_regs.h
+++ b/drivers/net/ethernet/airoha/airoha_regs.h
@@ -376,10 +376,7 @@
#define SP_CPORT_MASK(_n) GENMASK(3 + ((_n) << 2), ((_n) << 2))
#define REG_SRC_PORT_FC_MAP6 0x2298
-#define FC_ID_OF_SRC_PORT27_MASK GENMASK(28, 24)
-#define FC_ID_OF_SRC_PORT26_MASK GENMASK(20, 16)
-#define FC_ID_OF_SRC_PORT25_MASK GENMASK(12, 8)
-#define FC_ID_OF_SRC_PORT24_MASK GENMASK(4, 0)
+#define FC_ID_OF_SRC_PORT_MASK(_n) GENMASK(4 + ((_n) << 3), ((_n) << 3))
#define REG_CDM5_RX_OQ1_DROP_CNT 0x29d4
@@ -0,0 +1,86 @@
From 46097d011f77f5758fb47b7059b4f1f2e7403940 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Fri, 6 Mar 2026 16:09:47 +0100
Subject: [PATCH] net: airoha: Move GDM forward port configuration in
ndo_open/ndo_stop callbacks
This change allows to set GDM forward port configuration to
FE_PSE_PORT_DROP stopping the network device. Hw design requires to stop
packet forwarding putting the interface down. Moreover, PPE firmware
requires to use PPE1 for GDM3 or GDM4.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20260306-airoha-gdm-forward-ndo-open-stop-v1-1-7b7a20dd9ef0@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
drivers/net/ethernet/airoha/airoha_eth.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1611,6 +1611,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;
+ u32 pse_port = FE_PSE_PORT_PPE1;
netif_tx_start_all_queues(dev);
err = airoha_set_vip_for_gdm_port(port, true);
@@ -1634,6 +1635,14 @@ 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. */
+ pse_port = FE_PSE_PORT_PPE2;
+ }
+ airoha_set_gdm_port_fwd_cfg(qdma->eth, REG_GDM_FWD_CFG(port->id),
+ pse_port);
+
return 0;
}
@@ -1651,6 +1660,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);
+ 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,
GLOBAL_CFG_TX_DMA_EN_MASK |
@@ -1744,7 +1756,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;
- u32 pse_port, fe_cpu_port;
+ u32 fe_cpu_port;
u8 ppe_id;
airoha_set_macaddr(port, dev->dev_addr);
@@ -1765,7 +1777,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;
- pse_port = FE_PSE_PORT_PPE2;
+ ppe_id = 1;
break;
}
fallthrough;
@@ -1774,13 +1786,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;
- pse_port = FE_PSE_PORT_PPE1;
+ ppe_id = 0;
break;
}
}
- airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(port->id), pse_port);
- 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),
__field_prep(DFT_CPORT_MASK(port->id), fe_cpu_port));
@@ -0,0 +1,30 @@
From d4a533ad249e9fbdc2d0633f2ddd60a5b3a9a4ca Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Fri, 13 Mar 2026 12:27:00 +0100
Subject: [PATCH] net: airoha: Remove airoha_dev_stop() in airoha_remove()
Do not run airoha_dev_stop routine explicitly in airoha_remove()
since ndo_stop() callback is already executed by unregister_netdev() in
__dev_close_many routine if necessary and, doing so, we will end up causing
an underflow in the qdma users atomic counters. Rely on networking subsystem
to stop the device removing the airoha_eth module.
Fixes: 23020f0493270 ("net: airoha: Introduce ethernet support for EN7581 SoC")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260313-airoha-remove-ndo_stop-remove-net-v2-1-67542c3ceeca@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 1 -
1 file changed, 1 deletion(-)
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -3095,7 +3095,6 @@ static void airoha_remove(struct platfor
if (!port)
continue;
- airoha_dev_stop(port->dev);
unregister_netdev(port->dev);
airoha_metadata_dst_free(port);
}
@@ -0,0 +1,131 @@
From 8737d7194d6d5947c3d7d8813895b44a25b84477 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Fri, 13 Mar 2026 17:28:36 +0100
Subject: [PATCH] net: airoha: select QDMA block according LAN/WAN
configuration
Before this patch even GDM ports were assigned to QDMA0 while odd GDM
ports were using QDMA1, so, based on the DTS configuration, both QDMA0
and QDMA1 can theoretically receive traffic destinated to the host cpu
from LAN or WAN GDM ports.
Airoha folks reported the hw design assumes the LAN traffic destinated
to the host cpu is be forwarded to QDMA0 while traffic received on WAN
GDM port is managed by QDMA1. For this reason, select QDMA block according
to the GDM port LAN or WAN configuration:
- QDMA0 is used for GDM LAN devices
- QDMA1 is used for GDM WAN device
Assuming a device with three GDM ports, a typical configuration could be:
- MT7530 DSA switch -> GDM1 (eth0) -> QDMA0 (LAN traffic)
- External PHY -> GDM2 (eth1) -> QDMA1 (WAN traffic)
- External PHY -> GDM3 (eth2) -> QDMA0 (LAN traffic)
We can then bridge eth0 DSA port (lanX) with eth2 since they all tx/rx
LAN traffic.
Please note this patch introduces a change 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).
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20260313-airoha-qdma-lan-wan-mode-v2-1-7d577db6e40c@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
drivers/net/ethernet/airoha/airoha_eth.c | 18 ++++++++----------
drivers/net/ethernet/airoha/airoha_eth.h | 1 +
2 files changed, 9 insertions(+), 10 deletions(-)
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1754,11 +1754,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);
- struct airoha_qdma *qdma = port->qdma;
- struct airoha_eth *eth = qdma->eth;
+ struct airoha_eth *eth = port->eth;
u32 fe_cpu_port;
u8 ppe_id;
+ /* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */
+ port->qdma = &eth->qdma[!airoha_is_lan_gdm_port(port)];
+ port->dev->irq = port->qdma->irq_banks[0].irq;
airoha_set_macaddr(port, dev->dev_addr);
switch (port->id) {
@@ -1782,7 +1784,7 @@ static int airoha_dev_init(struct net_de
}
fallthrough;
default: {
- u8 qdma_id = qdma - &eth->qdma[0];
+ u8 qdma_id = port->qdma - &eth->qdma[0];
/* For PPE1 select cpu port according to the running QDMA. */
fe_cpu_port = qdma_id ? FE_PSE_PORT_CDM2 : FE_PSE_PORT_CDM1;
@@ -2866,11 +2868,10 @@ bool airoha_is_valid_gdm_port(struct air
}
static int airoha_alloc_gdm_port(struct airoha_eth *eth,
- struct device_node *np, int index)
+ struct device_node *np)
{
const __be32 *id_ptr = of_get_property(np, "reg", NULL);
struct airoha_gdm_port *port;
- struct airoha_qdma *qdma;
struct net_device *dev;
int err, p;
u32 id;
@@ -2901,7 +2902,6 @@ static int airoha_alloc_gdm_port(struct
return -ENOMEM;
}
- qdma = &eth->qdma[index % AIROHA_MAX_NUM_QDMA];
dev->netdev_ops = &airoha_netdev_ops;
dev->ethtool_ops = &airoha_ethtool_ops;
dev->max_mtu = AIROHA_MAX_MTU;
@@ -2913,7 +2913,6 @@ static int airoha_alloc_gdm_port(struct
dev->features |= dev->hw_features;
dev->vlan_features = dev->hw_features;
dev->dev.of_node = np;
- dev->irq = qdma->irq_banks[0].irq;
SET_NETDEV_DEV(dev, eth->dev);
/* reserve hw queues for HTB offloading */
@@ -2934,7 +2933,7 @@ static int airoha_alloc_gdm_port(struct
port = netdev_priv(dev);
u64_stats_init(&port->stats.syncp);
spin_lock_init(&port->stats.lock);
- port->qdma = qdma;
+ port->eth = eth;
port->dev = dev;
port->id = id;
eth->ports[p] = port;
@@ -3034,7 +3033,6 @@ static int airoha_probe(struct platform_
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
airoha_qdma_start_napi(&eth->qdma[i]);
- i = 0;
for_each_child_of_node(pdev->dev.of_node, np) {
if (!of_device_is_compatible(np, "airoha,eth-mac"))
continue;
@@ -3042,7 +3040,7 @@ static int airoha_probe(struct platform_
if (!of_device_is_available(np))
continue;
- err = airoha_alloc_gdm_port(eth, np, i++);
+ err = airoha_alloc_gdm_port(eth, np);
if (err) {
of_node_put(np);
goto error_napi_stop;
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -533,6 +533,7 @@ struct airoha_qdma {
struct airoha_gdm_port {
struct airoha_qdma *qdma;
+ struct airoha_eth *eth;
struct net_device *dev;
int id;
@@ -0,0 +1,32 @@
From dfdf774656205515b2d6ad94fce63c7ccbe92d91 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Fri, 9 Jan 2026 10:29:06 +0100
Subject: [PATCH] net: airoha: Fix typo in airoha_ppe_setup_tc_block_cb
definition
Fix Typo in airoha_ppe_dev_setup_tc_block_cb routine definition when
CONFIG_NET_AIROHA is not enabled.
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202601090517.Fj6v501r-lkp@intel.com/
Fixes: f45fc18b6de04 ("net: airoha: Add airoha_ppe_dev struct definition")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20260109-airoha_ppe_dev_setup_tc_block_cb-typo-v1-1-282e8834a9f9@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
include/linux/soc/airoha/airoha_offload.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/include/linux/soc/airoha/airoha_offload.h
+++ b/include/linux/soc/airoha/airoha_offload.h
@@ -52,8 +52,8 @@ static inline void airoha_ppe_put_dev(st
{
}
-static inline int airoha_ppe_setup_tc_block_cb(struct airoha_ppe_dev *dev,
- void *type_data)
+static inline int airoha_ppe_dev_setup_tc_block_cb(struct airoha_ppe_dev *dev,
+ void *type_data)
{
return -EOPNOTSUPP;
}
@@ -19,16 +19,16 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
FIELD_PREP(IP_ASSEMBLE_PORT_MASK, 0) | FIELD_PREP(IP_ASSEMBLE_PORT_MASK, 0) |
FIELD_PREP(IP_ASSEMBLE_NBQ_MASK, 22)); FIELD_PREP(IP_ASSEMBLE_NBQ_MASK, 22));
- airoha_fe_set(eth, REG_GDM_FWD_CFG(3), GDM_PAD_EN_MASK); - airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM3_IDX), GDM_PAD_EN_MASK);
- airoha_fe_set(eth, REG_GDM_FWD_CFG(4), GDM_PAD_EN_MASK); - airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM4_IDX), GDM_PAD_EN_MASK);
+ airoha_fe_set(eth, REG_GDM_FWD_CFG(3), + airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM3_IDX),
+ GDM_PAD_EN_MASK | GDM_STRIP_CRC_MASK); + GDM_PAD_EN_MASK | GDM_STRIP_CRC_MASK);
+ airoha_fe_set(eth, REG_GDM_FWD_CFG(4), + airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM4_IDX),
+ GDM_PAD_EN_MASK | GDM_STRIP_CRC_MASK); + GDM_PAD_EN_MASK | GDM_STRIP_CRC_MASK);
airoha_fe_crsn_qsel_init(eth); airoha_fe_crsn_qsel_init(eth);
@@ -1624,7 +1626,8 @@ static int airoha_dev_open(struct net_de @@ -1625,7 +1627,8 @@ static int airoha_dev_open(struct net_de
if (err) if (err)
return err; return err;
@@ -15,7 +15,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
--- a/drivers/net/ethernet/airoha/airoha_eth.c --- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -3088,7 +3088,6 @@ static void airoha_remove(struct platfor @@ -3113,7 +3113,6 @@ static void airoha_remove(struct platfor
} }
static const char * const en7581_xsi_rsts_names[] = { static const char * const en7581_xsi_rsts_names[] = {
@@ -23,7 +23,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
"hsi0-mac", "hsi0-mac",
"hsi1-mac", "hsi1-mac",
"hsi-mac", "hsi-mac",
@@ -3120,7 +3119,6 @@ static int airoha_en7581_get_src_port_id @@ -3145,7 +3144,6 @@ static int airoha_en7581_get_src_port_id
} }
static const char * const an7583_xsi_rsts_names[] = { static const char * const an7583_xsi_rsts_names[] = {
@@ -35,9 +35,9 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr) static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr)
{ {
struct airoha_eth *eth = port->qdma->eth; struct airoha_eth *eth = port->qdma->eth;
@@ -1621,6 +1627,17 @@ static int airoha_dev_open(struct net_de @@ -1622,6 +1628,17 @@ static int airoha_dev_open(struct net_de
struct airoha_gdm_port *port = netdev_priv(dev);
struct airoha_qdma *qdma = port->qdma; struct airoha_qdma *qdma = port->qdma;
u32 pse_port = FE_PSE_PORT_PPE1;
+ if (airhoa_is_phy_external(port)) { + if (airhoa_is_phy_external(port)) {
+ err = phylink_of_phy_connect(port->phylink, dev->dev.of_node, 0); + err = phylink_of_phy_connect(port->phylink, dev->dev.of_node, 0);
@@ -53,7 +53,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
netif_tx_start_all_queues(dev); netif_tx_start_all_queues(dev);
err = airoha_set_vip_for_gdm_port(port, true); err = airoha_set_vip_for_gdm_port(port, true);
if (err) if (err)
@@ -1674,6 +1691,11 @@ static int airoha_dev_stop(struct net_de @@ -1686,6 +1703,11 @@ static int airoha_dev_stop(struct net_de
} }
} }
@@ -65,7 +65,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
return 0; return 0;
} }
@@ -2816,6 +2838,20 @@ static const struct ethtool_ops airoha_e @@ -2833,6 +2855,20 @@ static const struct ethtool_ops airoha_e
.get_link = ethtool_op_get_link, .get_link = ethtool_op_get_link,
}; };
@@ -86,7 +86,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port) static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port)
{ {
int i; int i;
@@ -2860,6 +2896,99 @@ bool airoha_is_valid_gdm_port(struct air @@ -2877,6 +2913,99 @@ bool airoha_is_valid_gdm_port(struct air
return false; return false;
} }
@@ -184,34 +184,34 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+} +}
+ +
static int airoha_alloc_gdm_port(struct airoha_eth *eth, static int airoha_alloc_gdm_port(struct airoha_eth *eth,
struct device_node *np, int index) struct device_node *np)
{ {
@@ -2938,6 +3067,12 @@ static int airoha_alloc_gdm_port(struct @@ -2948,6 +3077,12 @@ static int airoha_alloc_gdm_port(struct
if (err) port->id = id;
return err; eth->ports[p] = port;
+ if (airhoa_is_phy_external(port)) { + if (airhoa_is_phy_external(port)) {
+ err = airoha_setup_phylink(dev); + err = airoha_setup_phylink(dev);
+ if (err) + if (err)
+ goto free_metadata_dst; + return err;
+ } + }
+ +
err = register_netdev(dev); return airoha_metadata_dst_alloc(port);
if (err) }
goto free_metadata_dst;
@@ -3053,6 +3188,10 @@ error_hw_cleanup: @@ -3079,6 +3214,10 @@ error_hw_cleanup:
if (port && port->dev->reg_state == NETREG_REGISTERED) {
if (port->dev->reg_state == NETREG_REGISTERED)
unregister_netdev(port->dev); unregister_netdev(port->dev);
airoha_metadata_dst_free(port); + if (airhoa_is_phy_external(port)) {
+ if (airhoa_is_phy_external(port)) { + phylink_destroy(port->phylink);
+ phylink_destroy(port->phylink); + airoha_pcs_destroy(port->pcs);
+ airoha_pcs_destroy(port->pcs); + }
+ } airoha_metadata_dst_free(port);
}
} }
free_netdev(eth->napi_dev); free_netdev(eth->napi_dev);
@@ -3080,6 +3219,10 @@ static void airoha_remove(struct platfor @@ -3105,6 +3244,10 @@ static void airoha_remove(struct platfor
airoha_dev_stop(port->dev);
unregister_netdev(port->dev); unregister_netdev(port->dev);
airoha_metadata_dst_free(port); airoha_metadata_dst_free(port);
+ if (airhoa_is_phy_external(port)) { + if (airhoa_is_phy_external(port)) {
@@ -223,7 +223,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
--- a/drivers/net/ethernet/airoha/airoha_eth.h --- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h +++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -536,6 +536,10 @@ struct airoha_gdm_port { @@ -537,6 +537,10 @@ struct airoha_gdm_port {
struct net_device *dev; struct net_device *dev;
int id; int id;
@@ -28,15 +28,15 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr) static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr)
{ {
@@ -1630,6 +1632,7 @@ static int airoha_dev_open(struct net_de @@ -1631,6 +1633,7 @@ static int airoha_dev_open(struct net_de
struct airoha_gdm_port *port = netdev_priv(dev);
struct airoha_qdma *qdma = port->qdma; struct airoha_qdma *qdma = port->qdma;
u32 pse_port = FE_PSE_PORT_PPE1;
+#if defined(CONFIG_PCS_AIROHA) +#if defined(CONFIG_PCS_AIROHA)
if (airhoa_is_phy_external(port)) { if (airhoa_is_phy_external(port)) {
err = phylink_of_phy_connect(port->phylink, dev->dev.of_node, 0); err = phylink_of_phy_connect(port->phylink, dev->dev.of_node, 0);
if (err) { if (err) {
@@ -1640,6 +1643,7 @@ static int airoha_dev_open(struct net_de @@ -1641,6 +1644,7 @@ static int airoha_dev_open(struct net_de
phylink_start(port->phylink); phylink_start(port->phylink);
} }
@@ -44,7 +44,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
netif_tx_start_all_queues(dev); netif_tx_start_all_queues(dev);
err = airoha_set_vip_for_gdm_port(port, true); err = airoha_set_vip_for_gdm_port(port, true);
@@ -1694,10 +1698,12 @@ static int airoha_dev_stop(struct net_de @@ -1706,10 +1710,12 @@ static int airoha_dev_stop(struct net_de
} }
} }
@@ -57,7 +57,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
return 0; return 0;
} }
@@ -2841,6 +2847,7 @@ static const struct ethtool_ops airoha_e @@ -2858,6 +2864,7 @@ static const struct ethtool_ops airoha_e
.get_link = ethtool_op_get_link, .get_link = ethtool_op_get_link,
}; };
@@ -65,7 +65,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
static struct phylink_pcs *airoha_phylink_mac_select_pcs(struct phylink_config *config, static struct phylink_pcs *airoha_phylink_mac_select_pcs(struct phylink_config *config,
phy_interface_t interface) phy_interface_t interface)
{ {
@@ -2854,6 +2861,7 @@ static void airoha_mac_config(struct phy @@ -2871,6 +2878,7 @@ static void airoha_mac_config(struct phy
const struct phylink_link_state *state) const struct phylink_link_state *state)
{ {
} }
@@ -73,7 +73,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port) static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port)
{ {
@@ -2899,6 +2907,7 @@ bool airoha_is_valid_gdm_port(struct air @@ -2916,6 +2924,7 @@ bool airoha_is_valid_gdm_port(struct air
return false; return false;
} }
@@ -81,43 +81,43 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
static void airoha_mac_link_up(struct phylink_config *config, struct phy_device *phy, static void airoha_mac_link_up(struct phylink_config *config, struct phy_device *phy,
unsigned int mode, phy_interface_t interface, unsigned int mode, phy_interface_t interface,
int speed, int duplex, bool tx_pause, bool rx_pause) int speed, int duplex, bool tx_pause, bool rx_pause)
@@ -2991,6 +3000,7 @@ static int airoha_setup_phylink(struct n @@ -3008,6 +3017,7 @@ static int airoha_setup_phylink(struct n
return 0; return 0;
} }
+#endif +#endif
static int airoha_alloc_gdm_port(struct airoha_eth *eth, static int airoha_alloc_gdm_port(struct airoha_eth *eth,
struct device_node *np, int index) struct device_node *np)
@@ -3070,11 +3080,13 @@ static int airoha_alloc_gdm_port(struct @@ -3080,11 +3090,13 @@ static int airoha_alloc_gdm_port(struct
if (err) port->id = id;
return err; eth->ports[p] = port;
+#if defined(CONFIG_PCS_AIROHA) +#if defined(CONFIG_PCS_AIROHA)
if (airhoa_is_phy_external(port)) { if (airhoa_is_phy_external(port)) {
err = airoha_setup_phylink(dev); err = airoha_setup_phylink(dev);
if (err) if (err)
goto free_metadata_dst; return err;
} }
+#endif +#endif
err = register_netdev(dev); return airoha_metadata_dst_alloc(port);
if (err) }
@@ -3191,10 +3203,12 @@ error_hw_cleanup: @@ -3217,10 +3229,12 @@ error_hw_cleanup:
if (port && port->dev->reg_state == NETREG_REGISTERED) {
if (port->dev->reg_state == NETREG_REGISTERED)
unregister_netdev(port->dev); unregister_netdev(port->dev);
airoha_metadata_dst_free(port);
+#if defined(CONFIG_PCS_AIROHA) +#if defined(CONFIG_PCS_AIROHA)
if (airhoa_is_phy_external(port)) { if (airhoa_is_phy_external(port)) {
phylink_destroy(port->phylink); phylink_destroy(port->phylink);
airoha_pcs_destroy(port->pcs); airoha_pcs_destroy(port->pcs);
}
+#endif
} }
+#endif
airoha_metadata_dst_free(port);
} }
free_netdev(eth->napi_dev); free_netdev(eth->napi_dev);
@@ -3222,10 +3236,12 @@ static void airoha_remove(struct platfor @@ -3247,10 +3261,12 @@ static void airoha_remove(struct platfor
airoha_dev_stop(port->dev);
unregister_netdev(port->dev); unregister_netdev(port->dev);
airoha_metadata_dst_free(port); airoha_metadata_dst_free(port);
+#if defined(CONFIG_PCS_AIROHA) +#if defined(CONFIG_PCS_AIROHA)
@@ -131,7 +131,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
--- a/drivers/net/ethernet/airoha/airoha_eth.h --- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h +++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -536,9 +536,11 @@ struct airoha_gdm_port { @@ -537,9 +537,11 @@ struct airoha_gdm_port {
struct net_device *dev; struct net_device *dev;
int id; int id;
@@ -136,7 +136,7 @@ ath79_setup_interfaces()
;; ;;
airtight,c-75) airtight,c-75)
ucidef_add_switch "switch0" \ ucidef_add_switch "switch0" \
"0@eth0" "2:wan" "3:lan" "6@eth1" "0u@eth0" "2:wan" "3:lan" "6u@eth1"
;; ;;
alfa-network,ap121fe) alfa-network,ap121fe)
ucidef_set_interface_lan "eth0 usb0" ucidef_set_interface_lan "eth0 usb0"
@@ -200,7 +200,7 @@ ath79_setup_interfaces()
tplink,tl-wdr4900-v2|\ tplink,tl-wdr4900-v2|\
tplink,tl-wdr7500-v3) tplink,tl-wdr7500-v3)
ucidef_add_switch "switch0" \ ucidef_add_switch "switch0" \
"0@eth1" "2:lan" "3:lan" "4:lan" "5:lan" "6@eth0" "1:wan" "0u@eth1" "2:lan" "3:lan" "4:lan" "5:lan" "6u@eth0" "1:wan"
;; ;;
buffalo,bhr-4grv|\ buffalo,bhr-4grv|\
buffalo,wzr-hp-g450h) buffalo,wzr-hp-g450h)
@@ -210,11 +210,11 @@ ath79_setup_interfaces()
buffalo,bhr-4grv2|\ buffalo,bhr-4grv2|\
trendnet,tew-823dru) trendnet,tew-823dru)
ucidef_add_switch "switch0" \ ucidef_add_switch "switch0" \
"0@eth1" "1:lan" "2:lan" "3:lan" "4:lan" "5:wan" "6@eth0" "0u@eth1" "1:lan" "2:lan" "3:lan" "4:lan" "5:wan" "6u@eth0"
;; ;;
buffalo,wzr-450hp2) buffalo,wzr-450hp2)
ucidef_add_switch "switch0" \ ucidef_add_switch "switch0" \
"6@eth1" "1:lan" "2:lan" "3:lan" "4:lan" "5:wan" "0@eth0" "6u@eth1" "1:lan" "2:lan" "3:lan" "4:lan" "5:wan" "0u@eth0"
;; ;;
buffalo,wzr-600dhp|\ buffalo,wzr-600dhp|\
buffalo,wzr-hp-ag300h|\ buffalo,wzr-hp-ag300h|\
@@ -287,7 +287,7 @@ ath79_setup_interfaces()
comfast,cf-wr650ac-v2|\ comfast,cf-wr650ac-v2|\
zyxel,nbg6616) zyxel,nbg6616)
ucidef_add_switch "switch0" \ ucidef_add_switch "switch0" \
"0@eth0" "1:lan" "2:lan" "3:lan" "4:lan" "5:wan" "6@eth1" "0u@eth0" "1:lan" "2:lan" "3:lan" "4:lan" "5:wan" "6u@eth1"
;; ;;
compex,wpj344-16m|\ compex,wpj344-16m|\
compex,wpj563) compex,wpj563)
@@ -301,7 +301,7 @@ ath79_setup_interfaces()
dell,apl26-0ae|\ dell,apl26-0ae|\
dell,apl27-0b1) dell,apl27-0b1)
ucidef_add_switch "switch0" \ ucidef_add_switch "switch0" \
"0@eth0" "2:lan:1" "3:lan:2" "6@eth1" "0u@eth0" "2:lan:1" "3:lan:2" "6u@eth1"
;; ;;
devolo,dlan-pro-1200plus-ac|\ devolo,dlan-pro-1200plus-ac|\
devolo,magic-2-wifi) devolo,magic-2-wifi)
@@ -318,11 +318,11 @@ ath79_setup_interfaces()
;; ;;
dlink,dap-2695-a1) dlink,dap-2695-a1)
ucidef_add_switch "switch0" \ ucidef_add_switch "switch0" \
"0@eth0" "2:lan" "3:wan" "6@eth1" "0u@eth0" "2:lan" "3:wan" "6u@eth1"
;; ;;
dlink,dap-3662-a1) dlink,dap-3662-a1)
ucidef_add_switch "switch0" \ ucidef_add_switch "switch0" \
"0@eth0" "1:lan:2" "2:lan:1" "6@eth1" "0u@eth0" "1:lan:2" "2:lan:1" "6u@eth1"
;; ;;
dlink,dch-g020-a1) dlink,dch-g020-a1)
ucidef_add_switch "switch0" \ ucidef_add_switch "switch0" \
@@ -394,7 +394,7 @@ ath79_setup_interfaces()
;; ;;
jjplus,jwap230) jjplus,jwap230)
ucidef_add_switch "switch0" \ ucidef_add_switch "switch0" \
"0@eth0" "5:wan:1" "1:lan:2" "6@eth1" "0u@eth0" "5:wan:1" "1:lan:2" "6u@eth1"
;; ;;
joyit,jt-or750i) joyit,jt-or750i)
ucidef_set_interface_wan "eth1" ucidef_set_interface_wan "eth1"
@@ -417,7 +417,7 @@ ath79_setup_interfaces()
;; ;;
librerouter,librerouter-v1) librerouter,librerouter-v1)
ucidef_add_switch "switch0" \ ucidef_add_switch "switch0" \
"0@eth0" "5:wan" "6@eth1" "4:lan" "0u@eth0" "5:wan" "6u@eth1" "4:lan"
;; ;;
longdata,aps256) longdata,aps256)
ucidef_set_interface_wan "eth1" ucidef_set_interface_wan "eth1"
@@ -500,7 +500,7 @@ ath79_setup_interfaces()
qxwlan,e558-v2-8m|\ qxwlan,e558-v2-8m|\
qxwlan,e558-v2-16m) qxwlan,e558-v2-16m)
ucidef_add_switch "switch0" \ ucidef_add_switch "switch0" \
"0@eth1" "4:lan" "5:lan" "6@eth0" "3:wan" "0u@eth1" "4:lan" "5:lan" "6u@eth0" "3:wan"
;; ;;
rosinson,wr818) rosinson,wr818)
ucidef_add_switch "switch0" \ ucidef_add_switch "switch0" \
@@ -513,7 +513,7 @@ ath79_setup_interfaces()
;; ;;
ruckus,r500) ruckus,r500)
ucidef_add_switch "switch0" \ ucidef_add_switch "switch0" \
"6u@eth0" "5:lan:1" "3:lan:2" "0@eth1" "6u@eth0" "5:lan:1" "3:lan:2" "0u@eth1"
;; ;;
teltonika,rut955|\ teltonika,rut955|\
teltonika,rut955-h7v3c0) teltonika,rut955-h7v3c0)
@@ -528,7 +528,7 @@ ath79_setup_interfaces()
tplink,archer-d7-v1|\ tplink,archer-d7-v1|\
tplink,archer-d7b-v1) tplink,archer-d7b-v1)
ucidef_add_switch "switch0" \ ucidef_add_switch "switch0" \
"0@eth1" "3:lan:3" "4:lan:2" "5:lan:1" "6@eth0" "2:wan:4" "1:wan:5" "0u@eth1" "3:lan:3" "4:lan:2" "5:lan:1" "6u@eth0" "2:wan:4" "1:wan:5"
;; ;;
tplink,deco-m4r-v1|\ tplink,deco-m4r-v1|\
tplink,deco-s4-v2) tplink,deco-s4-v2)
@@ -568,7 +568,7 @@ ath79_setup_interfaces()
tplink,tl-wr1043nd-v3|\ tplink,tl-wr1043nd-v3|\
tplink,tl-wr1045nd-v2) tplink,tl-wr1045nd-v2)
ucidef_add_switch "switch0" \ ucidef_add_switch "switch0" \
"0@eth1" "1:lan:4" "2:lan:3" "3:lan:2" "4:lan:1" "5:wan" "6@eth0" "0u@eth1" "1:lan:4" "2:lan:3" "3:lan:2" "4:lan:1" "5:wan" "6u@eth0"
;; ;;
tplink,tl-wr2543-v1) tplink,tl-wr2543-v1)
ucidef_add_switch "switch0" \ ucidef_add_switch "switch0" \
@@ -13,7 +13,7 @@ ath79_setup_interfaces()
;; ;;
domywifi,dw33d) domywifi,dw33d)
ucidef_add_switch "switch0" \ ucidef_add_switch "switch0" \
"0@eth0" "1:wan" "2:lan" "3:lan" "4:lan" "5:lan" "6@eth1" "0u@eth0" "1:wan" "2:lan" "3:lan" "4:lan" "5:lan" "6u@eth1"
;; ;;
dongwon,dw02-412h-64m|\ dongwon,dw02-412h-64m|\
dongwon,dw02-412h-128m) dongwon,dw02-412h-128m)
@@ -42,7 +42,7 @@ ath79_setup_interfaces()
;; ;;
linksys,ea4500-v3) linksys,ea4500-v3)
ucidef_add_switch "switch0" \ ucidef_add_switch "switch0" \
"6@eth1" "1:lan" "2:lan" "3:lan" "4:lan" "5:wan" "0@eth0" "6u@eth1" "1:lan" "2:lan" "3:lan" "4:lan" "5:wan" "0u@eth0"
;; ;;
netgear,pgzng1) netgear,pgzng1)
ucidef_set_interfaces_lan_wan "eth1" "eth0" ucidef_set_interfaces_lan_wan "eth1" "eth0"
@@ -81,7 +81,7 @@ ath79_setup_interfaces()
zyxel,emg2926-q10a|\ zyxel,emg2926-q10a|\
zyxel,nbg6716) zyxel,nbg6716)
ucidef_add_switch "switch0" \ ucidef_add_switch "switch0" \
"0@eth0" "1:lan" "2:lan" "3:lan" "4:lan" "5:wan" "6@eth1" "0u@eth0" "1:lan" "2:lan" "3:lan" "4:lan" "5:wan" "6u@eth1"
;; ;;
*) *)
ucidef_set_interfaces_lan_wan "eth0" "eth1" ucidef_set_interfaces_lan_wan "eth0" "eth1"
@@ -0,0 +1,103 @@
From 2a6c045640c38a407a39cd40c3c4d8dd2fd89aa8 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert+renesas@glider.be>
Date: Thu, 6 Nov 2025 14:34:00 +0100
Subject: [PATCH 1/2] bitfield: Add less-checking __FIELD_{GET,PREP}()
The BUILD_BUG_ON_MSG() check against "~0ull" works only with "unsigned
(long) long" _mask types. For constant masks, that condition is usually
met, as GENMASK() yields an UL value. The few places where the
constant mask is stored in an intermediate variable were fixed by
changing the variable type to u64 (see e.g. [1] and [2]).
However, for non-constant masks, smaller unsigned types should be valid,
too, but currently lead to "result of comparison of constant
18446744073709551615 with expression of type ... is always
false"-warnings with clang and W=1.
Hence refactor the __BF_FIELD_CHECK() helper, and factor out
__FIELD_{GET,PREP}(). The later lack the single problematic check, but
are otherwise identical to FIELD_{GET,PREP}(), and are intended to be
used in the fully non-const variants later.
[1] commit 5c667d5a5a3ec166 ("clk: sp7021: Adjust width of _m in
HWM_FIELD_PREP()")
[2] commit cfd6fb45cfaf46fa ("crypto: ccree - avoid out-of-range
warnings from clang")
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://git.kernel.org/torvalds/c/5c667d5a5a3ec166 [1]
Signed-off-by: Yury Norov (NVIDIA) <yury.norov@gmail.com>
---
include/linux/bitfield.h | 36 ++++++++++++++++++++++++++++--------
1 file changed, 28 insertions(+), 8 deletions(-)
--- a/include/linux/bitfield.h
+++ b/include/linux/bitfield.h
@@ -60,7 +60,7 @@
#define __bf_cast_unsigned(type, x) ((__unsigned_scalar_typeof(type))(x))
-#define __BF_FIELD_CHECK(_mask, _reg, _val, _pfx) \
+#define __BF_FIELD_CHECK_MASK(_mask, _val, _pfx) \
({ \
BUILD_BUG_ON_MSG(!__builtin_constant_p(_mask), \
_pfx "mask is not constant"); \
@@ -69,13 +69,33 @@
~((_mask) >> __bf_shf(_mask)) & \
(0 + (_val)) : 0, \
_pfx "value too large for the field"); \
- BUILD_BUG_ON_MSG(__bf_cast_unsigned(_mask, _mask) > \
- __bf_cast_unsigned(_reg, ~0ull), \
- _pfx "type of reg too small for mask"); \
__BUILD_BUG_ON_NOT_POWER_OF_2((_mask) + \
(1ULL << __bf_shf(_mask))); \
})
+#define __BF_FIELD_CHECK_REG(mask, reg, pfx) \
+ BUILD_BUG_ON_MSG(__bf_cast_unsigned(mask, mask) > \
+ __bf_cast_unsigned(reg, ~0ull), \
+ pfx "type of reg too small for mask")
+
+#define __BF_FIELD_CHECK(mask, reg, val, pfx) \
+ ({ \
+ __BF_FIELD_CHECK_MASK(mask, val, pfx); \
+ __BF_FIELD_CHECK_REG(mask, reg, pfx); \
+ })
+
+#define __FIELD_PREP(mask, val, pfx) \
+ ({ \
+ __BF_FIELD_CHECK_MASK(mask, val, pfx); \
+ ((typeof(mask))(val) << __bf_shf(mask)) & (mask); \
+ })
+
+#define __FIELD_GET(mask, reg, pfx) \
+ ({ \
+ __BF_FIELD_CHECK_MASK(mask, 0U, pfx); \
+ (typeof(mask))(((reg) & (mask)) >> __bf_shf(mask)); \
+ })
+
/**
* FIELD_MAX() - produce the maximum value representable by a field
* @_mask: shifted mask defining the field's length and position
@@ -112,8 +132,8 @@
*/
#define FIELD_PREP(_mask, _val) \
({ \
- __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); \
- ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \
+ __BF_FIELD_CHECK_REG(_mask, 0ULL, "FIELD_PREP: "); \
+ __FIELD_PREP(_mask, _val, "FIELD_PREP: "); \
})
#define __BF_CHECK_POW2(n) BUILD_BUG_ON_ZERO(((n) & ((n) - 1)) != 0)
@@ -152,8 +172,8 @@
*/
#define FIELD_GET(_mask, _reg) \
({ \
- __BF_FIELD_CHECK(_mask, _reg, 0U, "FIELD_GET: "); \
- (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \
+ __BF_FIELD_CHECK_REG(_mask, _reg, "FIELD_GET: "); \
+ __FIELD_GET(_mask, _reg, "FIELD_GET: "); \
})
extern void __compiletime_error("value doesn't fit into mask")
@@ -0,0 +1,114 @@
From c1c6ab80b25c8db1e2ef5ae3ac8075d2c242ae13 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert+renesas@glider.be>
Date: Thu, 6 Nov 2025 14:34:01 +0100
Subject: [PATCH 2/2] bitfield: Add non-constant field_{prep,get}() helpers
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The existing FIELD_{GET,PREP}() macros are limited to compile-time
constants. However, it is very common to prepare or extract bitfield
elements where the bitfield mask is not a compile-time constant.
To avoid this limitation, the AT91 clock driver and several other
drivers already have their own non-const field_{prep,get}() macros.
Make them available for general use by adding them to
<linux/bitfield.h>, and improve them slightly:
1. Avoid evaluating macro parameters more than once,
2. Replace "ffs() - 1" by "__ffs()",
3. Support 64-bit use on 32-bit architectures,
4. Wire field_{get,prep}() to FIELD_{GET,PREP}() when mask is
actually constant.
This is deliberately not merged into the existing FIELD_{GET,PREP}()
macros, as people expressed the desire to keep stricter variants for
increased safety, or for performance critical paths.
Yury: use __mask withing new macros.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Acked-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Acked-by: Crt Mori <cmo@melexis.com>
Acked-by: Nuno Sá <nuno.sa@analog.com>
Acked-by: Richard Genoud <richard.genoud@bootlin.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Reviewed-by: Yury Norov (NVIDIA) <yury.norov@gmail.com>
Signed-off-by: Yury Norov (NVIDIA) <yury.norov@gmail.com>
---
include/linux/bitfield.h | 59 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 59 insertions(+)
--- a/include/linux/bitfield.h
+++ b/include/linux/bitfield.h
@@ -16,6 +16,7 @@
* FIELD_{GET,PREP} macros take as first parameter shifted mask
* from which they extract the base mask and shift amount.
* Mask must be a compilation time constant.
+ * field_{get,prep} are variants that take a non-const mask.
*
* Example:
*
@@ -223,4 +224,62 @@ __MAKE_OP(64)
#undef __MAKE_OP
#undef ____MAKE_OP
+#define __field_prep(mask, val) \
+ ({ \
+ __auto_type __mask = (mask); \
+ typeof(__mask) __val = (val); \
+ unsigned int __shift = BITS_PER_TYPE(__mask) <= 32 ? \
+ __ffs(__mask) : __ffs64(__mask); \
+ (__val << __shift) & __mask; \
+ })
+
+#define __field_get(mask, reg) \
+ ({ \
+ __auto_type __mask = (mask); \
+ typeof(__mask) __reg = (reg); \
+ unsigned int __shift = BITS_PER_TYPE(__mask) <= 32 ? \
+ __ffs(__mask) : __ffs64(__mask); \
+ (__reg & __mask) >> __shift; \
+ })
+
+/**
+ * field_prep() - prepare a bitfield element
+ * @mask: shifted mask defining the field's length and position, must be
+ * non-zero
+ * @val: value to put in the field
+ *
+ * Return: field value masked and shifted to its final destination
+ *
+ * field_prep() masks and shifts up the value. The result should be
+ * combined with other fields of the bitfield using logical OR.
+ * Unlike FIELD_PREP(), @mask is not limited to a compile-time constant.
+ * Typical usage patterns are a value stored in a table, or calculated by
+ * shifting a constant by a variable number of bits.
+ * If you want to ensure that @mask is a compile-time constant, please use
+ * FIELD_PREP() directly instead.
+ */
+#define field_prep(mask, val) \
+ (__builtin_constant_p(mask) ? __FIELD_PREP(mask, val, "field_prep: ") \
+ : __field_prep(mask, val))
+
+/**
+ * field_get() - extract a bitfield element
+ * @mask: shifted mask defining the field's length and position, must be
+ * non-zero
+ * @reg: value of entire bitfield
+ *
+ * Return: extracted field value
+ *
+ * field_get() extracts the field specified by @mask from the
+ * bitfield passed in as @reg by masking and shifting it down.
+ * Unlike FIELD_GET(), @mask is not limited to a compile-time constant.
+ * Typical usage patterns are a value stored in a table, or calculated by
+ * shifting a constant by a variable number of bits.
+ * If you want to ensure that @mask is a compile-time constant, please use
+ * FIELD_GET() directly instead.
+ */
+#define field_get(mask, reg) \
+ (__builtin_constant_p(mask) ? __FIELD_GET(mask, reg, "field_get: ") \
+ : __field_get(mask, reg))
+
#endif
@@ -0,0 +1,28 @@
From b1cff2f4b2391a13bd3e9263502072df1ee5d035 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert+renesas@glider.be>
Date: Thu, 6 Nov 2025 14:34:10 +0100
Subject: [PATCH] ALSA: usb-audio: Convert to common field_{get,prep}() helpers
Drop the driver-specific field_get() and field_prep() macros, in favor
of the globally available variants from <linux/bitfield.h>.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Yury Norov (NVIDIA) <yury.norov@gmail.com>
---
sound/usb/mixer_quirks.c | 6 ------
1 file changed, 6 deletions(-)
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -3367,10 +3367,6 @@ static int snd_bbfpro_controls_create(st
#define RME_DIGIFACE_REGISTER(reg, mask) (((reg) << 16) | (mask))
#define RME_DIGIFACE_INVERT BIT(31)
-/* Nonconst helpers */
-#define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1))
-#define field_prep(_mask, _val) (((_val) << (ffs(_mask) - 1)) & (_mask))
-
static int snd_rme_digiface_write_reg(struct snd_kcontrol *kcontrol, int item, u16 mask, u16 val)
{
struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
@@ -0,0 +1,40 @@
From 0f8407a1f1c795c417e4c7750654a6024a3ec68b Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert+renesas@glider.be>
Date: Thu, 6 Nov 2025 14:34:02 +0100
Subject: [PATCH] clk: at91: Convert to common field_{get,prep}() helpers
Drop the driver-specific field_get() and field_prep() macros, in favor
of the globally available variants from <linux/bitfield.h>.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Acked-by: Stephen Boyd <sboyd@kernel.org>
Acked-by: Claudiu Beznea <claudiu.beznea@tuxon.dev>
Signed-off-by: Yury Norov (NVIDIA) <yury.norov@gmail.com>
---
drivers/clk/at91/clk-peripheral.c | 1 +
drivers/clk/at91/pmc.h | 5 -----
2 files changed, 1 insertion(+), 5 deletions(-)
--- a/drivers/clk/at91/clk-peripheral.c
+++ b/drivers/clk/at91/clk-peripheral.c
@@ -3,6 +3,7 @@
* Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
*/
+#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/clk-provider.h>
#include <linux/clkdev.h>
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -116,9 +116,6 @@ struct at91_clk_pms {
unsigned int parent;
};
-#define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1))
-#define field_prep(_mask, _val) (((_val) << (ffs(_mask) - 1)) & (_mask))
-
#define ndck(a, s) (a[s - 1].id + 1)
#define nck(a) (a[ARRAY_SIZE(a) - 1].id + 1)
@@ -0,0 +1,37 @@
From 1fe1c28a108e4953f083c0106575ee0eccc296ae Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert+renesas@glider.be>
Date: Thu, 6 Nov 2025 14:34:07 +0100
Subject: [PATCH] iio: mlx90614: Convert to common field_{get,prep}() helpers
Drop the driver-specific field_get() and field_prep() macros, in favor
of the globally available variants from <linux/bitfield.h>.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Acked-by: Crt Mori <cmo@melexis.com>
Signed-off-by: Yury Norov (NVIDIA) <yury.norov@gmail.com>
---
drivers/iio/temperature/mlx90614.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
--- a/drivers/iio/temperature/mlx90614.c
+++ b/drivers/iio/temperature/mlx90614.c
@@ -22,6 +22,7 @@
* the "wakeup" GPIO is not given, power management will be disabled.
*/
+#include <linux/bitfield.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/gpio/consumer.h>
@@ -68,10 +69,6 @@
#define MLX90614_CONST_SCALE 20 /* Scale in milliKelvin (0.02 * 1000) */
#define MLX90614_CONST_FIR 0x7 /* Fixed value for FIR part of low pass filter */
-/* Non-constant mask variant of FIELD_GET() and FIELD_PREP() */
-#define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1))
-#define field_prep(_mask, _val) (((_val) << (ffs(_mask) - 1)) & (_mask))
-
struct mlx_chip_info {
/* EEPROM offsets with 16-bit data, MSB first */
/* emissivity correction coefficient */
@@ -0,0 +1,28 @@
From bb0e7fda87753a973cb4a86c22905b1177f00d4e Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert+renesas@glider.be>
Date: Thu, 6 Nov 2025 14:34:08 +0100
Subject: [PATCH] pinctrl: ma35: Convert to common field_{get,prep}() helpers
Drop the driver-specific field_get() and field_prep() macros, in favor
of the globally available variants from <linux/bitfield.h>.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Yury Norov (NVIDIA) <yury.norov@gmail.com>
---
drivers/pinctrl/nuvoton/pinctrl-ma35.c | 6 ------
1 file changed, 6 deletions(-)
--- a/drivers/pinctrl/nuvoton/pinctrl-ma35.c
+++ b/drivers/pinctrl/nuvoton/pinctrl-ma35.c
@@ -81,10 +81,6 @@
#define MVOLT_1800 0
#define MVOLT_3300 1
-/* Non-constant mask variant of FIELD_GET() and FIELD_PREP() */
-#define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1))
-#define field_prep(_mask, _val) (((_val) << (ffs(_mask) - 1)) & (_mask))
-
static const char * const gpio_group_name[] = {
"gpioa", "gpiob", "gpioc", "gpiod", "gpioe", "gpiof", "gpiog",
"gpioh", "gpioi", "gpioj", "gpiok", "gpiol", "gpiom", "gpion",
@@ -156,6 +156,10 @@
reg = <0x16 0x6>; reg = <0x16 0x6>;
#nvmem-cell-cells = <1>; #nvmem-cell-cells = <1>;
}; };
eeprom_boardconfig_410: eeprom@410 {
reg = <0x410 0x200>;
};
}; };
}; };
}; };
@@ -174,9 +178,7 @@
wifi@e,0 { wifi@e,0 {
compatible = "pci1814,3592"; compatible = "pci1814,3592";
reg = <0x7000 0 0 0 0>; reg = <0x7000 0 0 0 0>;
ralink,mtd-eeprom = <&boardconfig 0x410>; nvmem-cells = <&eeprom_boardconfig_410>, <&macaddr_boardconfig_16 1>;
ralink,eeprom-swap; nvmem-cell-names = "eeprom", "mac-address";
nvmem-cells = <&macaddr_boardconfig_16 1>;
nvmem-cell-names = "mac-address";
}; };
}; };
@@ -162,6 +162,10 @@
macaddr_boardconfig_16: macaddr@16 { macaddr_boardconfig_16: macaddr@16 {
reg = <0x16 0x6>; reg = <0x16 0x6>;
}; };
eeprom_boardconfig_410: eeprom@410 {
reg = <0x410 0x200>;
};
}; };
}; };
}; };
@@ -187,8 +191,8 @@
wifi@e,0 { wifi@e,0 {
compatible = "pci1814,3592"; compatible = "pci1814,3592";
reg = <0x7000 0 0 0 0>; reg = <0x7000 0 0 0 0>;
ralink,mtd-eeprom = <&boardconfig 0x410>; nvmem-cells = <&eeprom_boardconfig_410>;
ralink,eeprom-swap; nvmem-cell-names = "eeprom";
}; };
}; };
@@ -194,6 +194,10 @@
reg = <0x16 0x6>; reg = <0x16 0x6>;
#nvmem-cell-cells = <1>; #nvmem-cell-cells = <1>;
}; };
eeprom_boardconfig_410: eeprom@410 {
reg = <0x410 0x200>;
};
}; };
}; };
}; };
@@ -211,10 +215,10 @@
req-mask = <0xf>; req-mask = <0xf>;
wifi@e,0 { wifi@e,0 {
compatible = "pci0,0"; compatible = "pci1814,0601";
reg = <0x7000 0 0 0 0>; reg = <0x7000 0 0 0 0>;
ralink,mtd-eeprom = <&boardconfig 0x410>; nvmem-cells = <&eeprom_boardconfig_410>;
ralink,eeprom-swap; nvmem-cell-names = "eeprom";
}; };
}; };
@@ -204,6 +204,10 @@
macaddr_boardconfig_16: macaddr@16 { macaddr_boardconfig_16: macaddr@16 {
reg = <0x16 0x6>; reg = <0x16 0x6>;
}; };
eeprom_boardconfig_410: eeprom@410 {
reg = <0x410 0x200>;
};
}; };
}; };
}; };
@@ -234,10 +238,8 @@
wifi0: wifi@e,0 { wifi0: wifi@e,0 {
compatible = "pci1814,0601"; compatible = "pci1814,0601";
reg = <0x7000 0 0 0 0>; reg = <0x7000 0 0 0 0>;
nvmem-cells = <&macaddr_boardconfig_16>; nvmem-cells = <&eeprom_boardconfig_410>, <&macaddr_boardconfig_16>;
nvmem-cell-names = "mac-address"; nvmem-cell-names = "eeprom", "mac-address";
ralink,mtd-eeprom = <&boardconfig 0x410>;
ralink,eeprom-swap;
}; };
}; };
@@ -219,6 +219,10 @@
macaddr_boardconfig_16: macaddr@16 { macaddr_boardconfig_16: macaddr@16 {
reg = <0x16 0x6>; reg = <0x16 0x6>;
}; };
eeprom_boardconfig_410: eeprom@410 {
reg = <0x410 0x200>;
};
}; };
}; };
}; };
@@ -254,10 +258,8 @@
wifi@e,0 { wifi@e,0 {
compatible = "pci1814,3592"; compatible = "pci1814,3592";
reg = <0x7000 0 0 0 0>; reg = <0x7000 0 0 0 0>;
ralink,mtd-eeprom = <&boardconfig 0x410>; nvmem-cells = <&eeprom_boardconfig_410>, <&macaddr_boardconfig_16>;
ralink,eeprom-swap; nvmem-cell-names = "eeprom", "mac-address";
nvmem-cells = <&macaddr_boardconfig_16>;
nvmem-cell-names = "mac-address";
}; };
usb@0f,0 { usb@0f,0 {
@@ -230,6 +230,10 @@
reg = <0x16 0x6>; reg = <0x16 0x6>;
#nvmem-cell-cells = <1>; #nvmem-cell-cells = <1>;
}; };
eeprom_boardconfig_410: eeprom@410 {
reg = <0x410 0x200>;
};
}; };
}; };
}; };
@@ -243,10 +247,8 @@
wifi@e,0 { wifi@e,0 {
compatible = "pci1814,3592"; compatible = "pci1814,3592";
reg = <0x7000 0 0 0 0>; reg = <0x7000 0 0 0 0>;
ralink,mtd-eeprom = <&boardconfig 0x410>; nvmem-cells = <&eeprom_boardconfig_410>, <&macaddr_boardconfig_16 1>;
ralink,eeprom-swap; nvmem-cell-names = "eeprom", "mac-address";
nvmem-cells = <&macaddr_boardconfig_16 1>;
nvmem-cell-names = "mac-address";
}; };
}; };
@@ -247,6 +247,10 @@
reg = <0x16 0x6>; reg = <0x16 0x6>;
#nvmem-cell-cells = <1>; #nvmem-cell-cells = <1>;
}; };
eeprom_boardconfig_410: eeprom@410 {
reg = <0x410 0x200>;
};
}; };
}; };
}; };
@@ -260,10 +264,8 @@
wifi@e,0 { wifi@e,0 {
compatible = "pci1814,3091"; compatible = "pci1814,3091";
reg = <0x7000 0 0 0 0>; reg = <0x7000 0 0 0 0>;
ralink,mtd-eeprom = <&boardconfig 0x410>; nvmem-cells = <&eeprom_boardconfig_410>, <&macaddr_boardconfig_16 1>;
ralink,eeprom-swap; nvmem-cell-names = "eeprom", "mac-address";
nvmem-cells = <&macaddr_boardconfig_16 1>;
nvmem-cell-names = "mac-address";
}; };
}; };
@@ -12,7 +12,7 @@
compatible = "tenda,be12-pro", "mediatek,mt7987a", "mediatek,mt7987"; compatible = "tenda,be12-pro", "mediatek,mt7987a", "mediatek,mt7987";
aliases { aliases {
label-mac-device = &gmac2; label-mac-device = &gmac0;
led-boot = &led_status_green; led-boot = &led_status_green;
led-failsafe = &led_status_red; led-failsafe = &led_status_red;
led-running = &led_status_green; led-running = &led_status_green;
@@ -80,13 +80,13 @@
partition@0 { partition@0 {
label = "Bootloader"; label = "Bootloader";
reg = <0x00000 0x0300000>; reg = <0x000000 0x0300000>;
read-only; read-only;
}; };
partition@300000 { partition@300000 {
label = "u-boot-env"; label = "u-boot-env";
reg = <0x0300000 0x0080000>; reg = <0x300000 0x0080000>;
}; };
partition@380000 { partition@380000 {
@@ -113,7 +113,7 @@
partition@780000 { partition@780000 {
label = "kernel"; label = "kernel";
reg = <0x780000 0x600000>; reg = <0x780000 0x0600000>;
}; };
partition@d80000 { partition@d80000 {
@@ -140,7 +140,7 @@
phy-mode = "2500base-x"; phy-mode = "2500base-x";
status = "okay"; status = "okay";
nvmem-cells = <&macaddr_factory_4 (-1)>; nvmem-cells = <&macaddr_factory_4 (-2)>;
nvmem-cell-names = "mac-address"; nvmem-cell-names = "mac-address";
fixed-link { fixed-link {
@@ -155,7 +155,7 @@
phy-handle = <&phy15>; phy-handle = <&phy15>;
status = "okay"; status = "okay";
nvmem-cells = <&macaddr_factory_4 (-3)>; nvmem-cells = <&macaddr_factory_4 (-2)>;
nvmem-cell-names = "mac-address"; nvmem-cell-names = "mac-address";
}; };
@@ -164,7 +164,7 @@
phy-handle = <&phy11>; phy-handle = <&phy11>;
status = "okay"; status = "okay";
nvmem-cells = <&macaddr_factory_4 (-2)>; nvmem-cells = <&macaddr_factory_4 (-1)>;
nvmem-cell-names = "mac-address"; nvmem-cell-names = "mac-address";
}; };
@@ -273,14 +273,14 @@
port@0 { port@0 {
reg = <0>; reg = <0>;
label = "lan1"; label = "lan5";
phy-mode = "internal"; phy-mode = "internal";
phy-handle = <&internal_phy1>; phy-handle = <&internal_phy1>;
}; };
port@1 { port@1 {
reg = <1>; reg = <1>;
label = "lan2"; label = "lan4";
phy-mode = "internal"; phy-mode = "internal";
phy-handle = <&internal_phy2>; phy-handle = <&internal_phy2>;
}; };
@@ -351,11 +351,11 @@
pcie@0,0 { pcie@0,0 {
reg = <0x0000 0 0 0 0>; reg = <0x0000 0 0 0 0>;
device_type = "pci";
mt7992@0,0 { mt7992@0,0 {
compatible = "mediatek,mt76"; compatible = "mediatek,mt76";
reg = <0x0000 0 0 0 0>; reg = <0x0000 0 0 0 0>;
device_type = "pci";
nvmem-cells = <&eeprom_factory_0>; nvmem-cells = <&eeprom_factory_0>;
nvmem-cell-names = "eeprom"; nvmem-cell-names = "eeprom";
@@ -368,13 +368,13 @@
band@0 { band@0 {
reg = <0>; reg = <0>;
nvmem-cells = <&macaddr_factory_4 (0)>; nvmem-cells = <&macaddr_factory_4 1>;
nvmem-cell-names = "mac-address"; nvmem-cell-names = "mac-address";
}; };
band@1 { band@1 {
reg = <1>; reg = <1>;
nvmem-cells = <&macaddr_factory_4 (1)>; nvmem-cells = <&macaddr_factory_4 3>;
nvmem-cell-names = "mac-address"; nvmem-cell-names = "mac-address";
}; };
}; };
@@ -183,7 +183,7 @@ mediatek_setup_interfaces()
ucidef_set_interfaces_lan_wan "lan0 lan1 lan2" eth1 ucidef_set_interfaces_lan_wan "lan0 lan1 lan2" eth1
;; ;;
tenda,be12-pro) tenda,be12-pro)
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 eth1" eth2 ucidef_set_interfaces_lan_wan "lan3 lan4 lan5 eth1" eth2
;; ;;
tplink,fr365-v1) tplink,fr365-v1)
ucidef_set_interfaces_lan_wan "port1 port3 port4 port5 port6" "port2" ucidef_set_interfaces_lan_wan "port1 port3 port4 port5 port6" "port2"
@@ -55,13 +55,33 @@
}; };
&wifi0 { &wifi0 {
nvmem-cells = <&eeprom_factory_0>, <&macaddr_factory_e000 1>;
nvmem-cell-names = "eeprom", "mac-address";
ieee80211-freq-limit;
/delete-property/ ieee80211-freq-limit; /delete-property/ ieee80211-freq-limit;
nvmem-cells = <&eeprom_factory_0>;
nvmem-cell-names = "eeprom";
#address-cells = <1>;
#size-cells = <0>;
band@0 {
reg = <0>;
nvmem-cells = <&macaddr_factory_e000 2>;
nvmem-cell-names = "mac-address";
};
band@1 {
reg = <1>;
nvmem-cells = <&macaddr_factory_e000 1>;
nvmem-cell-names = "mac-address";
};
}; };
&wifi1 { &wifi1 {
nvmem-cells = <&eeprom_factory_8000>, <&macaddr_factory_e000 3>; nvmem-cells = <&eeprom_factory_8000>, <&macaddr_factory_e000 3>;
nvmem-cell-names = "eeprom", "mac-address"; nvmem-cell-names = "eeprom", "mac-address";
}; };
&gmac1 {
nvmem-cells = <&macaddr_factory_e000 4>;
nvmem-cell-names = "mac-address";
};
@@ -105,7 +105,7 @@
}; };
eeprom_factory_8000: eeprom@8000 { eeprom_factory_8000: eeprom@8000 {
reg = <0x8000 0x600>; reg = <0x8000 0x4da8>;
}; };
macaddr_factory_8004: macaddr@8004 { macaddr_factory_8004: macaddr@8004 {
@@ -57,11 +57,6 @@ case "$board" in
[ "$PHYNBR" = "1" ] && \ [ "$PHYNBR" = "1" ] && \
macaddr_add $label_mac 2 > /sys${DEVPATH}/macaddress macaddr_add $label_mac 2 > /sys${DEVPATH}/macaddress
;; ;;
dlink,dir-3040-a1)
lan_mac_addr="$(mtd_get_mac_binary factory 0xe000)"
[ "$PHYNBR" = "0" ] && \
macaddr_add $lan_mac_addr 2 > /sys${DEVPATH}/macaddress
;;
dlink,dir-853-a3) dlink,dir-853-a3)
[ "$PHYNBR" = "0" ] && \ [ "$PHYNBR" = "0" ] && \
macaddr_setbit_la "$(mtd_get_mac_binary factory 0xe000)" \ macaddr_setbit_la "$(mtd_get_mac_binary factory 0xe000)" \
-1
View File
@@ -89,7 +89,6 @@ CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y CONFIG_HAS_IOPORT=y
CONFIG_HAS_IOPORT_MAP=y CONFIG_HAS_IOPORT_MAP=y
CONFIG_HZ_PERIODIC=y CONFIG_HZ_PERIODIC=y
CONFIG_ICPLUS_PHY=y
CONFIG_INITRAMFS_SOURCE="" CONFIG_INITRAMFS_SOURCE=""
CONFIG_IRQCHIP=y CONFIG_IRQCHIP=y
CONFIG_IRQ_DOMAIN=y CONFIG_IRQ_DOMAIN=y
@@ -7,13 +7,14 @@ menuconfig COMMON_CLK_REALTEK
if COMMON_CLK_REALTEK if COMMON_CLK_REALTEK
config COMMON_CLK_RTL83XX config COMMON_CLK_RTL83XX
bool "Clock driver for Realtek RTL83XX" bool "Clock driver for Realtek RTL83XX and RTL960X"
depends on MACH_REALTEK_RTL depends on MACH_REALTEK_RTL
select SRAM select SRAM
help help
This driver adds support for the Realtek RTL83xx series basic clocks. This driver adds support for the Realtek RTL83xx series basic clocks.
This includes chips in the RTL838x series, such as RTL8380, RTL8381, This includes chips in the RTL838x series, such as RTL8380, RTL8381,
RTL832, as well as chips from the RTL839x series, such as RTL8390, RTL832, chips from the RTL839x series, such as RTL8390, RT8391,
RT8391, RTL8392, RTL8393 and RTL8396. RTL8392, RTL8393 and RTL8396 as well as chips from the RTL960X
series, such as RTL9607C, RTL8198D.
endif endif
@@ -92,7 +92,8 @@
#define SOC_RTL838X 0 #define SOC_RTL838X 0
#define SOC_RTL839X 1 #define SOC_RTL839X 1
#define SOC_COUNT 2 #define SOC_RTL960X 2
#define SOC_COUNT 3
#define MEM_DDR1 1 #define MEM_DDR1 1
#define MEM_DDR2 2 #define MEM_DDR2 2
@@ -264,6 +265,8 @@ static const struct rtcl_round_set rtcl_round_set[SOC_COUNT][CLK_COUNT] = {
RTCL_ROUND_SET(400000000, 850000000, 25000000), RTCL_ROUND_SET(400000000, 850000000, 25000000),
RTCL_ROUND_SET(100000000, 400000000, 25000000), RTCL_ROUND_SET(100000000, 400000000, 25000000),
RTCL_ROUND_SET(50000000, 200000000, 50000000) RTCL_ROUND_SET(50000000, 200000000, 50000000)
}, {
RTCL_ROUND_SET(500000000, 1200000000, 25000000)
} }
}; };
@@ -465,6 +468,91 @@ static long rtcl_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long
return rrate; return rrate;
} }
static unsigned long rtcl_960x_cpu_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
u32 ocp_pll_ctrl0, ocp_pll_ctrl3, cmu_gcr;
u32 cpu_freq_sel0, en_div2_cpu0, cmu_mode, freq_div;
unsigned long rate;
ocp_pll_ctrl0 = read_soc(RTL960X_OCP_PLL_CTRL0);
ocp_pll_ctrl3 = read_soc(RTL960X_OCP_PLL_CTRL3);
cmu_gcr = read_soc(RTL960X_CMU_GCR);
cpu_freq_sel0 = RTL960X_OCP_CTRL0_CPU_FREQ_SEL0(ocp_pll_ctrl0);
en_div2_cpu0 = RTL960X_OCP_CTRL3_EN_DIV2_CPU0(ocp_pll_ctrl3);
cmu_mode = RTL960X_CMU_GCR_CMU_MODE(cmu_gcr);
freq_div = RTL960X_CMU_GCR_FREQ_DIV(cmu_gcr);
rate = ((cpu_freq_sel0 + 2) * 2 * parent_rate) >> en_div2_cpu0;
if (cmu_mode != 0)
rate >>= freq_div;
return rate;
}
static unsigned long rtcl_960x_lxb_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
u32 phy_rg5x_pll, lx_freq_sel;
unsigned long rate;
phy_rg5x_pll = read_sw(RTL960X_PHY_RG5X_PLL);
lx_freq_sel = RTL960X_LX_FREQ_SEL(phy_rg5x_pll);
rate = (40 * parent_rate) / (lx_freq_sel + 5);
return rate;
}
static unsigned long rtcl_960x_mem_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
u32 mem_pll_ctrl2, mem_pll_ctrl3, mem_pll_ctrl5;
u32 n_code, pdiv, f_code;
unsigned long rate;
u64 t;
mem_pll_ctrl2 = read_soc(RTL960X_MEM_PLL_CTRL2);
mem_pll_ctrl3 = read_soc(RTL960X_MEM_PLL_CTRL3);
mem_pll_ctrl5 = read_soc(RTL960X_MEM_PLL_CTRL5);
pdiv = RTL960X_MEM_CTRL2_PDIV(mem_pll_ctrl2);
n_code = RTL960X_MEM_CTRL3_N_CODE(mem_pll_ctrl3);
f_code = RTL960X_MEM_CTRL5_F_CODE(mem_pll_ctrl5);
rate = (parent_rate * (n_code + 3)) / (2 * (1 << pdiv));
t = parent_rate;
t *= f_code;
t /= 16384;
rate += t;
return rate;
}
static unsigned long rtcl_960x_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
{
struct rtcl_clk *clk = rtcl_hw_to_clk(hw);
unsigned long rate;
if ((clk->idx >= CLK_COUNT) || (!rtcl_ccu) || (rtcl_ccu->soc >= SOC_COUNT))
return 0;
switch (clk->idx) {
case CLK_CPU:
rate = rtcl_960x_cpu_recalc_rate(hw, parent_rate);
break;
case CLK_MEM:
rate = rtcl_960x_mem_recalc_rate(hw, parent_rate);
break;
case CLK_LXB:
rate = rtcl_960x_lxb_recalc_rate(hw, parent_rate);
break;
}
return rate;
}
/* /*
* Initialization functions to register the CCU and its clocks * Initialization functions to register the CCU and its clocks
*/ */
@@ -474,6 +562,10 @@ static long rtcl_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long
(void *)&rtcl_##SOC##_dram_start) + \ (void *)&rtcl_##SOC##_dram_start) + \
(void *)PBASE; }) (void *)PBASE; })
static const struct clk_ops rtcl_960x_clk_ops = {
.recalc_rate = rtcl_960x_recalc_rate,
};
static const struct clk_ops rtcl_clk_ops = { static const struct clk_ops rtcl_clk_ops = {
.set_rate = rtcl_set_rate, .set_rate = rtcl_set_rate,
.round_rate = rtcl_round_rate, .round_rate = rtcl_round_rate,
@@ -488,6 +580,8 @@ static int rtcl_ccu_create(struct device_node *np)
soc = SOC_RTL838X; soc = SOC_RTL838X;
else if (of_device_is_compatible(np, "realtek,rtl8390-clock")) else if (of_device_is_compatible(np, "realtek,rtl8390-clock"))
soc = SOC_RTL839X; soc = SOC_RTL839X;
else if (of_device_is_compatible(np, "realtek,rtl9607-clock"))
soc = SOC_RTL960X;
else else
return -ENXIO; return -ENXIO;
@@ -516,10 +610,14 @@ static int rtcl_register_clkhw(int clk_idx)
rclk->hw.init = &hw_init; rclk->hw.init = &hw_init;
hw_init.num_parents = 1; hw_init.num_parents = 1;
hw_init.ops = &rtcl_clk_ops;
hw_init.parent_data = &parent_data; hw_init.parent_data = &parent_data;
hw_init.name = rtcl_clk_info[clk_idx].name; hw_init.name = rtcl_clk_info[clk_idx].name;
if (rtcl_ccu->soc == SOC_RTL960X)
hw_init.ops = &rtcl_960x_clk_ops;
else
hw_init.ops = &rtcl_clk_ops;
ret = of_clk_hw_register(rtcl_ccu->np, &rclk->hw); ret = of_clk_hw_register(rtcl_ccu->np, &rclk->hw);
if (ret) if (ret)
return ret; return ret;
@@ -719,6 +817,7 @@ static void __init rtcl_probe_early(struct device_node *np)
CLK_OF_DECLARE_DRIVER(rtl838x_clk, "realtek,rtl8380-clock", rtcl_probe_early); CLK_OF_DECLARE_DRIVER(rtl838x_clk, "realtek,rtl8380-clock", rtcl_probe_early);
CLK_OF_DECLARE_DRIVER(rtl839x_clk, "realtek,rtl8390-clock", rtcl_probe_early); CLK_OF_DECLARE_DRIVER(rtl839x_clk, "realtek,rtl8390-clock", rtcl_probe_early);
CLK_OF_DECLARE_DRIVER(rtl960x_clk, "realtek,rtl9607-clock", rtcl_probe_early);
/* /*
* Late registration: Finally register as normal platform driver. At this point * Late registration: Finally register as normal platform driver. At this point
@@ -26,6 +26,8 @@
#define RTL839X_PLL_MEM_CTRL0 (0x0048) #define RTL839X_PLL_MEM_CTRL0 (0x0048)
#define RTL839X_PLL_MEM_CTRL1 (0x004c) #define RTL839X_PLL_MEM_CTRL1 (0x004c)
#define RTL960X_PHY_RG5X_PLL (0x1f054)
#define RTL_PLL_CTRL0_CMU_SEL_PREDIV(v) (((v) >> 0) & 0x3) #define RTL_PLL_CTRL0_CMU_SEL_PREDIV(v) (((v) >> 0) & 0x3)
#define RTL_PLL_CTRL0_CMU_SEL_DIV4(v) (((v) >> 2) & 0x1) #define RTL_PLL_CTRL0_CMU_SEL_DIV4(v) (((v) >> 2) & 0x1)
#define RTL_PLL_CTRL0_CMU_NCODE_IN(v) (((v) >> 4) & 0xff) #define RTL_PLL_CTRL0_CMU_NCODE_IN(v) (((v) >> 4) & 0xff)
@@ -49,6 +51,8 @@
#define RTL839X_PLL_CTRL1_CMU_DIVN2_SELB(v) (((v) >> 2) & 0x1) #define RTL839X_PLL_CTRL1_CMU_DIVN2_SELB(v) (((v) >> 2) & 0x1)
#define RTL839X_PLL_CTRL1_CMU_DIVN3_SEL(v) (((v) >> 0) & 0x3) #define RTL839X_PLL_CTRL1_CMU_DIVN3_SEL(v) (((v) >> 0) & 0x3)
#define RTL960X_LX_FREQ_SEL(v) ((v) & 0xf)
/* /*
* Core registers (e.g. memory controller) * Core registers (e.g. memory controller)
*/ */
@@ -67,6 +71,24 @@
#define RTL_MC_MCR_DRAMTYPE(v) ((((v) >> 28) & 0xf) + 1) #define RTL_MC_MCR_DRAMTYPE(v) ((((v) >> 28) & 0xf) + 1)
#define RTL_MC_DCR_BUSWIDTH(v) (8 << (((v) >> 24) & 0xf)) #define RTL_MC_DCR_BUSWIDTH(v) (8 << (((v) >> 24) & 0xf))
#define RTL960X_OCP_PLL_CTRL0 (0x0200)
#define RTL960X_OCP_PLL_CTRL3 (0x020c)
#define RTL960X_CMU_GCR (0x0380)
#define RTL960X_MEM_PLL_CTRL2 (0x023c)
#define RTL960X_MEM_PLL_CTRL3 (0x0240)
#define RTL960X_MEM_PLL_CTRL5 (0x0248)
#define RTL960X_OCP_CTRL0_CPU_FREQ_SEL0(v) (((v) >> 16) & 0x3f)
#define RTL960X_OCP_CTRL3_EN_DIV2_CPU0(v) (((v) >> 18) & 0x1)
#define RTL960X_CMU_GCR_CMU_MODE(v) ((v) & 0x3)
#define RTL960X_CMU_GCR_FREQ_DIV(v) (((v) >> 4) & 0x7)
#define RTL960X_MEM_CTRL2_PDIV(v) (((v) >> 14) & 0x3)
#define RTL960X_MEM_CTRL3_N_CODE(v) (((v) >> 24) & 0xff)
#define RTL960X_MEM_CTRL5_F_CODE(v) ((v) & 0x1fff)
/* /*
* Other stuff * Other stuff
*/ */
+1
View File
@@ -15,6 +15,7 @@ PKG_SOURCE_URL=https://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs-utils
PKG_MIRROR_HASH:=a21d244aee8cb216ac4436bf7f790e75fca113ea9a5512c8e4ac530c4983ef32 PKG_MIRROR_HASH:=a21d244aee8cb216ac4436bf7f790e75fca113ea9a5512c8e4ac530c4983ef32
PKG_SOURCE_DATE:=2025-07-15 PKG_SOURCE_DATE:=2025-07-15
PKG_SOURCE_VERSION:=51b5939b5f783221310d25146e6a2019ba8129b6 PKG_SOURCE_VERSION:=51b5939b5f783221310d25146e6a2019ba8129b6
PKG_CPE_ID:=cpe:/a:erofs-utils_project:erofs-utils
PKG_FIXUP:=autoreconf PKG_FIXUP:=autoreconf