Merge Official Source

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
Tianling Shen 2025-10-21 14:03:24 +08:00
commit c876ca9e57
No known key found for this signature in database
GPG Key ID: 6850B6345C862176
194 changed files with 2487 additions and 1149 deletions

View File

@ -20,7 +20,7 @@ define Package/Default
PROVIDES:=
EXTRA_DEPENDS:=
MAINTAINER:=$(PKG_MAINTAINER)
SOURCE:=$(patsubst $(TOPDIR)/%,%,$(patsubst $(TOPDIR)/package/%,feeds/base/%,$(CURDIR)))
SOURCE:=$(patsubst $(TOPDIR)/%,%,$(if $(__pkg_source_makefile),$(__pkg_source_makefile),$(CURDIR)))
ifneq ($(PKG_VERSION),)
ifneq ($(PKG_RELEASE),)
VERSION:=$(PKG_VERSION)-r$(PKG_RELEASE)

View File

@ -134,6 +134,35 @@ endef
PKG_INSTALL_STAMP:=$(PKG_INFO_DIR)/$(PKG_DIR_NAME).$(if $(BUILD_VARIANT),$(BUILD_VARIANT),default).install
# Normalize package SOURCE entry to pack reproducible package
# If we are packing a package with OpenWrt buildroot:
# - Replace package/... with feeds/base/...
# If we are packing a package with SDK:
# - Replace feeds/.*_root/... with feeds/.*/... and remove
# the intermediate directory to reflect what the symbolic link
# points to.
# Example:
# Feed link: feeds/base_root/package -> feeds/base
# Package: feeds/base_root/package/system/uci -> feeds/base/system/uci
ifeq ($(DUMP),)
__pkg_base_path:=$(patsubst $(TOPDIR)/%,%,$(CURDIR))
__pkg_provider_path:=$(word 1,$(subst /, ,$(__pkg_base_path)))
ifeq ($(__pkg_provider_path), feeds)
__pkg_feed_path:=$(word 2,$(subst /, ,$(__pkg_base_path)))
__pkg_feed_name:=$(patsubst %_root,%,$(__pkg_feed_path))
ifneq (__pkg_feed_path, __pkg_feed_name)
__pkg_feed_realpath:=$(realpath $(TOPDIR)/feeds/$(__pkg_feed_name))
__pkg_feed_dir:=$(patsubst $(TOPDIR)/feeds/$(__pkg_feed_path)/%,%,$(__pkg_feed_realpath))
__pkg_path:=$(patsubst feeds/$(__pkg_feed_path)/$(__pkg_feed_dir)/%,%,$(__pkg_base_path))
else
__pkg_path:=$(patsubst feeds/$(__pkg_feed_path)/%,%,$(__pkg_base_path))
endif
__pkg_source_makefile:=$(TOPDIR)/feeds/$(__pkg_feed_name)/$(__pkg_path)
else ifeq ($(__pkg_provider_path), package)
__pkg_source_makefile:=$(TOPDIR)/feeds/base/$(patsubst package/%,%,$(__pkg_base_path))
endif
endif
include $(INCLUDE_DIR)/package-defaults.mk
include $(INCLUDE_DIR)/package-dumpinfo.mk
include $(INCLUDE_DIR)/package-pack.mk

View File

@ -237,7 +237,7 @@ endif
$(STAGING_DIR_HOST)/bin/mkhash: $(SCRIPT_DIR)/mkhash.c
mkdir -p $(dir $@)
$(CC) -O2 -I$(TOPDIR)/tools/include -o $@ $<
$(STAGING_DIR_HOST)/bin/gcc -O2 -I$(TOPDIR)/tools/include -o $@ $<
$(STAGING_DIR_HOST)/bin/xxd: $(SCRIPT_DIR)/xxdi.pl
$(LN) $< $@

View File

@ -71,7 +71,7 @@ endef
# 4: optional link library test (example -lncurses)
define RequireCHeader
define Require/$(1)
echo 'int main(int argc, char **argv) { $(3); return 0; }' | gcc -include $(1) -x c -o $(TMP_DIR)/a.out - $(4)
echo 'int main(int argc, char **argv) { $(3); return 0; }' | $(STAGING_DIR_HOST)/bin/gcc -include $(1) -x c -o $(TMP_DIR)/a.out - $(4)
endef
$$(eval $$(call Require,$(1),$(2)))

View File

@ -44,14 +44,15 @@ generate_static_network() {
set network.loopback.device='lo'
set network.loopback.proto='static'
add_list network.loopback.ipaddr='127.0.0.1/8'
delete network.globals
set network.globals='globals'
set network.globals.dhcp_default_duid='auto'
EOF
[ -e /proc/sys/net/ipv6 ] && {
uci -q batch <<-EOF
delete network.globals
set network.globals='globals'
set network.globals.ula_prefix='auto'
EOF
}
[ -e /proc/sys/net/ipv6 ] && {
uci -q batch <<-EOF
set network.globals.ula_prefix='auto'
EOF
}
if json_is_a dsl object; then
json_select dsl

View File

@ -0,0 +1,9 @@
[ "$(uci -q get network.globals.dhcp_default_duid)" != "auto" ] && exit 0
uci -q batch <<-EOF >/dev/null
# DUID-UUID - RFC6355
set network.globals.dhcp_default_duid="$(hexdump -vn 16 -e '"0004" 2/2 "%x"' /dev/urandom)"
commit network
EOF
exit 0

View File

@ -1,6 +1,6 @@
setenv mmc_rootpart 2
part uuid mmc ${mmc_bootdev}:${mmc_rootpart} uuid
setenv loadkernel fatload mmc \$mmc_bootdev \$kernel_comp_addr_r uImage
setenv bootargs coherent_pool=2M console=ttyS0,115200 earlyprintk root=PARTUUID=${uuid} rootwait earlycon=uart,mmio32,0x01c28000
setenv bootargs coherent_pool=2M console=ttyS0,115200 earlycon=uart,mmio32,0x01c28000 root=PARTUUID=${uuid} rootwait
setenv uenvcmd run loadkernel \&\& bootm \$kernel_comp_addr_r
run uenvcmd

View File

@ -1,6 +1,6 @@
setenv mmc_rootpart 2
part uuid mmc ${mmc_bootdev}:${mmc_rootpart} uuid
setenv loadkernel fatload mmc \$mmc_bootdev \$kernel_comp_addr_r uImage
setenv bootargs coherent_pool=2M console=ttyS0,115200 earlyprintk root=PARTUUID=${uuid} rootwait
setenv bootargs coherent_pool=2M console=ttyS0,115200 root=PARTUUID=${uuid} rootwait
setenv uenvcmd run loadkernel \&\& bootm \$kernel_comp_addr_r
run uenvcmd

View File

@ -1,6 +1,6 @@
setenv mmc_rootpart 2
part uuid mmc ${mmc_bootdev}:${mmc_rootpart} uuid
setenv loadkernel fatload mmc \$mmc_bootdev \$kernel_comp_addr_r uImage
setenv bootargs coherent_pool=2M console=ttyS0,115200 earlyprintk root=PARTUUID=${uuid} rootwait
setenv bootargs coherent_pool=2M console=ttyS0,115200 root=PARTUUID=${uuid} rootwait
setenv uenvcmd run loadkernel \&\& bootm \$kernel_comp_addr_r
run uenvcmd

View File

@ -13,7 +13,7 @@ Signed-off-by: Mantas Pucka <mantas@8devices.com>
--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
@@ -171,8 +171,8 @@ static const struct ath11k_hw_params ath
@@ -171,8 +171,8 @@ static struct ath11k_hw_params ath11k_hw
.supports_shadow_regs = false,
.idle_ps = false,
.supports_sta_ps = false,

View File

@ -14,7 +14,7 @@ Signed-off-by: George Moussalem <george.moussalem@outlook.com>
--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
@@ -698,8 +698,8 @@ static const struct ath11k_hw_params ath
@@ -698,8 +698,8 @@ static struct ath11k_hw_params ath11k_hw
.supports_suspend = false,
.hal_params = &ath11k_hw_hal_params_ipq8074,
.single_pdev_only = false,

View File

@ -1,48 +0,0 @@
From 52393e2ae12f18fb1a60578c24c46ebab292ddb6 Mon Sep 17 00:00:00 2001
From: Rameshkumar Sundaram <quic_ramess@quicinc.com>
Date: Mon, 28 Mar 2022 13:21:04 +0530
Subject: [PATCH] ath11k: Revert: clear the keys properly when DISABLE_KEY
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reverting the Upstream clear key change added as a part of
436a4e886598 ("ath11k: clear the keys properly
when DISABLE_KEY")
This change exposed a race in WLAN Firmware where target asserts
are seen frequently due FW not synchronizing ath11k hosts clear
key commands(CIPHER changes to NONE) with frames in TX queue.
Hence reverting this change untill FW fixes to synchronize
ath11k hosts clear key command are available.
Signed-off-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
---
drivers/net/wireless/ath/ath11k/mac.c | 4 +++-
drivers/net/wireless/ath/ath11k/wmi.c | 3 +--
2 files changed, 4 insertions(+), 3 deletions(-)
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -4232,7 +4232,9 @@ static int ath11k_install_key(struct ath
return 0;
if (cmd == DISABLE_KEY) {
- arg.key_cipher = WMI_CIPHER_NONE;
+ /* TODO: Check if FW expects value other than NONE for del */
+ /* arg.key_cipher = WMI_CIPHER_NONE; */
+ arg.key_len = 0;
arg.key_data = NULL;
goto install;
}
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -1854,8 +1854,7 @@ int ath11k_wmi_vdev_install_key(struct a
tlv = (struct wmi_tlv *)(skb->data + sizeof(*cmd));
tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) |
FIELD_PREP(WMI_TLV_LEN, key_len_aligned);
- if (arg->key_data)
- memcpy(tlv->value, (u8 *)arg->key_data, key_len_aligned);
+ memcpy(tlv->value, (u8 *)arg->key_data, key_len_aligned);
ret = ath11k_wmi_cmd_send(wmi, skb, WMI_VDEV_INSTALL_KEY_CMDID);
if (ret) {

View File

@ -0,0 +1,92 @@
From 16872194c80f2724472fc207991712895ac8a230 Mon Sep 17 00:00:00 2001
From: Sergey Senozhatsky <senozhatsky@chromium.org>
Date: Thu, 12 Jun 2025 17:45:06 +0900
Subject: wifi: ath11k: clear initialized flag for deinit-ed srng lists
[ Upstream commit a5b46aa7cf5f05c213316a018e49a8e086efd98e ]
In a number of cases we see kernel panics on resume due
to ath11k kernel page fault, which happens under the
following circumstances:
1) First ath11k_hal_dump_srng_stats() call
Last interrupt received for each group:
ath11k_pci 0000:01:00.0: group_id 0 22511ms before
ath11k_pci 0000:01:00.0: group_id 1 14440788ms before
[..]
ath11k_pci 0000:01:00.0: failed to receive control response completion, polling..
ath11k_pci 0000:01:00.0: Service connect timeout
ath11k_pci 0000:01:00.0: failed to connect to HTT: -110
ath11k_pci 0000:01:00.0: failed to start core: -110
ath11k_pci 0000:01:00.0: firmware crashed: MHI_CB_EE_RDDM
ath11k_pci 0000:01:00.0: already resetting count 2
ath11k_pci 0000:01:00.0: failed to wait wlan mode request (mode 4): -110
ath11k_pci 0000:01:00.0: qmi failed to send wlan mode off: -110
ath11k_pci 0000:01:00.0: failed to reconfigure driver on crash recovery
[..]
2) At this point reconfiguration fails (we have 2 resets) and
ath11k_core_reconfigure_on_crash() calls ath11k_hal_srng_deinit()
which destroys srng lists. However, it does not reset per-list
->initialized flag.
3) Second ath11k_hal_dump_srng_stats() call sees stale ->initialized
flag and attempts to dump srng stats:
Last interrupt received for each group:
ath11k_pci 0000:01:00.0: group_id 0 66785ms before
ath11k_pci 0000:01:00.0: group_id 1 14485062ms before
ath11k_pci 0000:01:00.0: group_id 2 14485062ms before
ath11k_pci 0000:01:00.0: group_id 3 14485062ms before
ath11k_pci 0000:01:00.0: group_id 4 14780845ms before
ath11k_pci 0000:01:00.0: group_id 5 14780845ms before
ath11k_pci 0000:01:00.0: group_id 6 14485062ms before
ath11k_pci 0000:01:00.0: group_id 7 66814ms before
ath11k_pci 0000:01:00.0: group_id 8 68997ms before
ath11k_pci 0000:01:00.0: group_id 9 67588ms before
ath11k_pci 0000:01:00.0: group_id 10 69511ms before
BUG: unable to handle page fault for address: ffffa007404eb010
#PF: supervisor read access in kernel mode
#PF: error_code(0x0000) - not-present page
PGD 100000067 P4D 100000067 PUD 10022d067 PMD 100b01067 PTE 0
Oops: 0000 [#1] PREEMPT SMP NOPTI
RIP: 0010:ath11k_hal_dump_srng_stats+0x2b4/0x3b0 [ath11k]
Call Trace:
<TASK>
? __die_body+0xae/0xb0
? page_fault_oops+0x381/0x3e0
? exc_page_fault+0x69/0xa0
? asm_exc_page_fault+0x22/0x30
? ath11k_hal_dump_srng_stats+0x2b4/0x3b0 [ath11k (HASH:6cea 4)]
ath11k_qmi_driver_event_work+0xbd/0x1050 [ath11k (HASH:6cea 4)]
worker_thread+0x389/0x930
kthread+0x149/0x170
Clear per-list ->initialized flag in ath11k_hal_srng_deinit().
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Reviewed-by: Baochen Qiang <quic_bqiang@quicinc.com>
Fixes: 5118935b1bc2 ("ath11k: dump SRNG stats during FW assert")
Link: https://patch.msgid.link/20250612084551.702803-1-senozhatsky@chromium.org
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/ath/ath11k/hal.c | 4 ++++
1 file changed, 4 insertions(+)
(limited to 'drivers/net/wireless/ath/ath11k')
--- a/drivers/net/wireless/ath/ath11k/hal.c
+++ b/drivers/net/wireless/ath/ath11k/hal.c
@@ -1341,6 +1341,10 @@ EXPORT_SYMBOL(ath11k_hal_srng_init);
void ath11k_hal_srng_deinit(struct ath11k_base *ab)
{
struct ath11k_hal *hal = &ab->hal;
+ int i;
+
+ for (i = 0; i < HAL_SRNG_RING_ID_MAX; i++)
+ ab->hal.srng_list[i].initialized = 0;
ath11k_hal_unregister_srng_key(ab);
ath11k_hal_free_cont_rdp(ab);

View File

@ -0,0 +1,67 @@
From 6bdef22d540258ca06f079f7b6ae100669a19b47 Mon Sep 17 00:00:00 2001
From: Baochen Qiang <quic_bqiang@quicinc.com>
Date: Tue, 3 Jun 2025 10:25:28 +0800
Subject: wifi: ath11k: fix sleeping-in-atomic in
ath11k_mac_op_set_bitrate_mask()
[ Upstream commit 65c12b104cb942d588a1a093acc4537fb3d3b129 ]
ath11k_mac_disable_peer_fixed_rate() is passed as the iterator to
ieee80211_iterate_stations_atomic(). Note in this case the iterator is
required to be atomic, however ath11k_mac_disable_peer_fixed_rate() does
not follow it as it might sleep. Consequently below warning is seen:
BUG: sleeping function called from invalid context at wmi.c:304
Call Trace:
<TASK>
dump_stack_lvl
__might_resched.cold
ath11k_wmi_cmd_send
ath11k_wmi_set_peer_param
ath11k_mac_disable_peer_fixed_rate
ieee80211_iterate_stations_atomic
ath11k_mac_op_set_bitrate_mask.cold
Change to ieee80211_iterate_stations_mtx() to fix this issue.
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.30
Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
Signed-off-by: Baochen Qiang <quic_bqiang@quicinc.com>
Link: https://patch.msgid.link/20250603-ath11k-use-non-atomic-iterator-v1-1-d75762068d56@quicinc.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/ath/ath11k/mac.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
(limited to 'drivers/net/wireless/ath/ath11k')
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -8740,9 +8740,9 @@ ath11k_mac_op_set_bitrate_mask(struct ie
arvif->vdev_id, ret);
return ret;
}
- ieee80211_iterate_stations_atomic(ar->hw,
- ath11k_mac_disable_peer_fixed_rate,
- arvif);
+ ieee80211_iterate_stations_mtx(ar->hw,
+ ath11k_mac_disable_peer_fixed_rate,
+ arvif);
} else if (ath11k_mac_bitrate_mask_get_single_nss(ar, arvif, band, mask,
&single_nss)) {
rate = WMI_FIXED_RATE_NONE;
@@ -8809,9 +8809,9 @@ ath11k_mac_op_set_bitrate_mask(struct ie
}
mutex_lock(&ar->conf_mutex);
- ieee80211_iterate_stations_atomic(ar->hw,
- ath11k_mac_disable_peer_fixed_rate,
- arvif);
+ ieee80211_iterate_stations_mtx(ar->hw,
+ ath11k_mac_disable_peer_fixed_rate,
+ arvif);
arvif->bitrate_mask = *mask;
ieee80211_iterate_stations_atomic(ar->hw,

View File

@ -0,0 +1,83 @@
From 0f708ced89758247f5d2d70def00e7c1c80ff557 Mon Sep 17 00:00:00 2001
From: Johan Hovold <johan+linaro@kernel.org>
Date: Wed, 4 Jun 2025 16:34:53 +0200
Subject: wifi: ath11k: fix dest ring-buffer corruption
commit 8c1ba5091fa9a2d1478da63173b16a701bdf86bb upstream.
Add the missing memory barrier to make sure that destination ring
descriptors are read after the head pointers to avoid using stale data
on weakly ordered architectures like aarch64.
The barrier is added to the ath11k_hal_srng_access_begin() helper for
symmetry with follow-on fixes for source ring buffer corruption which
will add barriers to ath11k_hal_srng_access_end().
Tested-on: WCN6855 hw2.1 WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41
Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
Cc: stable@vger.kernel.org # 5.6
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
Reviewed-by: Baochen Qiang <quic_bqiang@quicinc.com>
Link: https://patch.msgid.link/20250604143457.26032-2-johan+linaro@kernel.org
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wireless/ath/ath11k/ce.c | 3 ---
drivers/net/wireless/ath/ath11k/dp_rx.c | 3 ---
drivers/net/wireless/ath/ath11k/hal.c | 12 +++++++++++-
3 files changed, 11 insertions(+), 7 deletions(-)
(limited to 'drivers/net/wireless/ath/ath11k')
--- a/drivers/net/wireless/ath/ath11k/ce.c
+++ b/drivers/net/wireless/ath/ath11k/ce.c
@@ -393,9 +393,6 @@ static int ath11k_ce_completed_recv_next
goto err;
}
- /* Make sure descriptor is read after the head pointer. */
- dma_rmb();
-
*nbytes = ath11k_hal_ce_dst_status_get_length(desc);
*skb = pipe->dest_ring->skb[sw_index];
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -2650,9 +2650,6 @@ int ath11k_dp_process_rx(struct ath11k_b
try_again:
ath11k_hal_srng_access_begin(ab, srng);
- /* Make sure descriptor is read after the head pointer. */
- dma_rmb();
-
while (likely(desc =
(struct hal_reo_dest_ring *)ath11k_hal_srng_dst_get_next_entry(ab,
srng))) {
--- a/drivers/net/wireless/ath/ath11k/hal.c
+++ b/drivers/net/wireless/ath/ath11k/hal.c
@@ -823,13 +823,23 @@ u32 *ath11k_hal_srng_src_peek(struct ath
void ath11k_hal_srng_access_begin(struct ath11k_base *ab, struct hal_srng *srng)
{
+ u32 hp;
+
lockdep_assert_held(&srng->lock);
if (srng->ring_dir == HAL_SRNG_DIR_SRC) {
srng->u.src_ring.cached_tp =
*(volatile u32 *)srng->u.src_ring.tp_addr;
} else {
- srng->u.dst_ring.cached_hp = READ_ONCE(*srng->u.dst_ring.hp_addr);
+ hp = READ_ONCE(*srng->u.dst_ring.hp_addr);
+
+ if (hp != srng->u.dst_ring.cached_hp) {
+ srng->u.dst_ring.cached_hp = hp;
+ /* Make sure descriptor is read after the head
+ * pointer.
+ */
+ dma_rmb();
+ }
/* Try to prefetch the next descriptor in the ring */
if (srng->flags & HAL_SRNG_FLAGS_CACHED)

View File

@ -0,0 +1,56 @@
From eed5fcf4a3d20fdbd9af2e602eab2b581264822f Mon Sep 17 00:00:00 2001
From: Johan Hovold <johan+linaro@kernel.org>
Date: Wed, 4 Jun 2025 16:34:56 +0200
Subject: wifi: ath11k: fix source ring-buffer corruption
commit 6efa0df54022c6c9fd4d294b87622c7fcdc418c8 upstream.
Add the missing memory barrier to make sure that LMAC source ring
descriptors are written before updating the head pointer to avoid
passing stale data to the firmware on weakly ordered architectures like
aarch64.
Note that non-LMAC rings use MMIO write accessors which have the
required write memory barrier.
Tested-on: WCN6855 hw2.1 WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41
Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
Cc: stable@vger.kernel.org # 5.6
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
Reviewed-by: Baochen Qiang <quic_bqiang@quicinc.com>
Link: https://patch.msgid.link/20250604143457.26032-5-johan+linaro@kernel.org
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wireless/ath/ath11k/hal.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
(limited to 'drivers/net/wireless/ath/ath11k')
--- a/drivers/net/wireless/ath/ath11k/hal.c
+++ b/drivers/net/wireless/ath/ath11k/hal.c
@@ -862,7 +862,11 @@ void ath11k_hal_srng_access_end(struct a
if (srng->ring_dir == HAL_SRNG_DIR_SRC) {
srng->u.src_ring.last_tp =
*(volatile u32 *)srng->u.src_ring.tp_addr;
- *srng->u.src_ring.hp_addr = srng->u.src_ring.hp;
+ /* Make sure descriptor is written before updating the
+ * head pointer.
+ */
+ dma_wmb();
+ WRITE_ONCE(*srng->u.src_ring.hp_addr, srng->u.src_ring.hp);
} else {
srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr;
*srng->u.dst_ring.tp_addr = srng->u.dst_ring.tp;
@@ -871,6 +875,10 @@ void ath11k_hal_srng_access_end(struct a
if (srng->ring_dir == HAL_SRNG_DIR_SRC) {
srng->u.src_ring.last_tp =
*(volatile u32 *)srng->u.src_ring.tp_addr;
+ /* Assume implementation use an MMIO write accessor
+ * which has the required wmb() so that the descriptor
+ * is written before the updating the head pointer.
+ */
ath11k_hif_write32(ab,
(unsigned long)srng->u.src_ring.hp_addr -
(unsigned long)ab->mem,

View File

@ -0,0 +1,61 @@
From 6fc2589aae91818dd1183a589ab97d8e5c25364e Mon Sep 17 00:00:00 2001
From: Johan Hovold <johan+linaro@kernel.org>
Date: Wed, 4 Jun 2025 16:34:57 +0200
Subject: wifi: ath11k: fix dest ring-buffer corruption when ring is full
commit aa6956150f820e6a6deba44be325ddfcb5b10f88 upstream.
Add the missing memory barriers to make sure that destination ring
descriptors are read before updating the tail pointer (and passing
ownership to the device) to avoid memory corruption on weakly ordered
architectures like aarch64 when the ring is full.
Tested-on: WCN6855 hw2.1 WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41
Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
Cc: stable@vger.kernel.org # 5.6
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
Reviewed-by: Baochen Qiang <quic_bqiang@quicinc.com>
Link: https://patch.msgid.link/20250604143457.26032-6-johan+linaro@kernel.org
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wireless/ath/ath11k/hal.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
(limited to 'drivers/net/wireless/ath/ath11k')
--- a/drivers/net/wireless/ath/ath11k/hal.c
+++ b/drivers/net/wireless/ath/ath11k/hal.c
@@ -854,7 +854,6 @@ void ath11k_hal_srng_access_end(struct a
{
lockdep_assert_held(&srng->lock);
- /* TODO: See if we need a write memory barrier here */
if (srng->flags & HAL_SRNG_FLAGS_LMAC_RING) {
/* For LMAC rings, ring pointer updates are done through FW and
* hence written to a shared memory location that is read by FW
@@ -869,7 +868,11 @@ void ath11k_hal_srng_access_end(struct a
WRITE_ONCE(*srng->u.src_ring.hp_addr, srng->u.src_ring.hp);
} else {
srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr;
- *srng->u.dst_ring.tp_addr = srng->u.dst_ring.tp;
+ /* Make sure descriptor is read before updating the
+ * tail pointer.
+ */
+ dma_mb();
+ WRITE_ONCE(*srng->u.dst_ring.tp_addr, srng->u.dst_ring.tp);
}
} else {
if (srng->ring_dir == HAL_SRNG_DIR_SRC) {
@@ -885,6 +888,10 @@ void ath11k_hal_srng_access_end(struct a
srng->u.src_ring.hp);
} else {
srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr;
+ /* Make sure descriptor is read before updating the
+ * tail pointer.
+ */
+ mb();
ath11k_hif_write32(ab,
(unsigned long)srng->u.dst_ring.tp_addr -
(unsigned long)ab->mem,

View File

@ -0,0 +1,237 @@
From 9a394fd149502394c20dc2ebecb8acfde6f6aeac Mon Sep 17 00:00:00 2001
From: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Date: Sun, 10 Aug 2025 22:30:18 +0530
Subject: wifi: ath11k: fix group data packet drops during rekey
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
[ Upstream commit 97acb0259cc9cbfbd7ab689e25684f3d8ce10e26 ]
During GTK rekey, mac80211 issues a clear key (if the old key exists)
followed by an install key operation in the same context. This causes
ath11k to send two WMI commands in quick succession: one to clear the
old key and another to install the new key in the same slot.
Under certain conditions—especially under high load or time sensitive
scenarios, firmware may process these commands asynchronously in a way
that firmware assumes the key is cleared whereas hardware has a valid key.
This inconsistency between hardware and firmware leads to group addressed
packet drops. Only setting the same key again can restore a valid key in
firmware and allow packets to be transmitted.
This issue remained latent because the host's clear key commands were
not effective in firmware until commit 436a4e886598 ("ath11k: clear the
keys properly via DISABLE_KEY"). That commit enabled the host to
explicitly clear group keys, which inadvertently exposed the race.
To mitigate this, restrict group key clearing across all modes (AP, STA,
MESH). During rekey, the new key can simply be set on top of the previous
one, avoiding the need for a clear followed by a set.
However, in AP mode specifically, permit group key clearing when no
stations are associated. This exception supports transitions from secure
modes (e.g., WPA2/WPA3) to open mode, during which all associated peers
are removed and the group key is cleared as part of the transition.
Add a per-BSS station counter to track the presence of stations during
set key operations. Also add a reset_group_keys flag to track the key
re-installation state and avoid repeated installation of the same key
when the number of connected stations transitions to non-zero within a
rekey period.
Additionally, for AP and Mesh modes, when the first station associates,
reinstall the same group key that was last set. This ensures that the
firmware recovers from any race that may have occurred during a previous
key clear when no stations were associated.
This change ensures that key clearing is permitted only when no clients
are connected, avoiding packet loss while enabling dynamic security mode
transitions.
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.9.0.1-02146-QCAHKSWPL_SILICONZ-1
Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41
Reported-by: Steffen Moser <lists@steffen-moser.de>
Closes: https://lore.kernel.org/linux-wireless/c6366409-9928-4dd7-bf7b-ba7fcf20eabf@steffen-moser.de
Fixes: 436a4e886598 ("ath11k: clear the keys properly via DISABLE_KEY")
Signed-off-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Tested-by: Nicolas Escande <nico.escande@gmail.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Link: https://patch.msgid.link/20250810170018.1124014-1-rameshkumar.sundaram@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/ath/ath11k/core.h | 2 +
drivers/net/wireless/ath/ath11k/mac.c | 111 ++++++++++++++++++++++++++++++---
2 files changed, 104 insertions(+), 9 deletions(-)
(limited to 'drivers/net/wireless/ath/ath11k')
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -414,6 +414,8 @@ struct ath11k_vif {
bool do_not_send_tmpl;
struct ath11k_arp_ns_offload arp_ns_offload;
struct ath11k_rekey_data rekey_data;
+ u32 num_stations;
+ bool reinstall_group_keys;
struct ath11k_reg_tpc_power_info reg_tpc_info;
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -4317,6 +4317,40 @@ static int ath11k_clear_peer_keys(struct
return first_errno;
}
+static int ath11k_set_group_keys(struct ath11k_vif *arvif)
+{
+ struct ath11k *ar = arvif->ar;
+ struct ath11k_base *ab = ar->ab;
+ const u8 *addr = arvif->bssid;
+ int i, ret, first_errno = 0;
+ struct ath11k_peer *peer;
+
+ spin_lock_bh(&ab->base_lock);
+ peer = ath11k_peer_find(ab, arvif->vdev_id, addr);
+ spin_unlock_bh(&ab->base_lock);
+
+ if (!peer)
+ return -ENOENT;
+
+ for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
+ struct ieee80211_key_conf *key = peer->keys[i];
+
+ if (!key || (key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
+ continue;
+
+ ret = ath11k_install_key(arvif, key, SET_KEY, addr,
+ WMI_KEY_GROUP);
+ if (ret < 0 && first_errno == 0)
+ first_errno = ret;
+
+ if (ret < 0)
+ ath11k_warn(ab, "failed to set group key of idx %d for vdev %d: %d\n",
+ i, arvif->vdev_id, ret);
+ }
+
+ return first_errno;
+}
+
static int ath11k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
struct ieee80211_vif *vif, struct ieee80211_sta *sta,
struct ieee80211_key_conf *key)
@@ -4326,6 +4360,7 @@ static int ath11k_mac_op_set_key(struct
struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
struct ath11k_peer *peer;
struct ath11k_sta *arsta;
+ bool is_ap_with_no_sta;
const u8 *peer_addr;
int ret = 0;
u32 flags = 0;
@@ -4386,16 +4421,57 @@ static int ath11k_mac_op_set_key(struct
else
flags |= WMI_KEY_GROUP;
- ret = ath11k_install_key(arvif, key, cmd, peer_addr, flags);
- if (ret) {
- ath11k_warn(ab, "ath11k_install_key failed (%d)\n", ret);
- goto exit;
- }
+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
+ "%s for peer %pM on vdev %d flags 0x%X, type = %d, num_sta %d\n",
+ cmd == SET_KEY ? "SET_KEY" : "DEL_KEY", peer_addr, arvif->vdev_id,
+ flags, arvif->vdev_type, arvif->num_stations);
+
+ /* Allow group key clearing only in AP mode when no stations are
+ * associated. There is a known race condition in firmware where
+ * group addressed packets may be dropped if the key is cleared
+ * and immediately set again during rekey.
+ *
+ * During GTK rekey, mac80211 issues a clear key (if the old key
+ * exists) followed by an install key operation for same key
+ * index. This causes ath11k to send two WMI commands in quick
+ * succession: one to clear the old key and another to install the
+ * new key in the same slot.
+ *
+ * Under certain conditions—especially under high load or time
+ * sensitive scenarios, firmware may process these commands
+ * asynchronously in a way that firmware assumes the key is
+ * cleared whereas hardware has a valid key. This inconsistency
+ * between hardware and firmware leads to group addressed packet
+ * drops after rekey.
+ * Only setting the same key again can restore a valid key in
+ * firmware and allow packets to be transmitted.
+ *
+ * There is a use case where an AP can transition from Secure mode
+ * to open mode without a vdev restart by just deleting all
+ * associated peers and clearing key, Hence allow clear key for
+ * that case alone. Mark arvif->reinstall_group_keys in such cases
+ * and reinstall the same key when the first peer is added,
+ * allowing firmware to recover from the race if it had occurred.
+ */
- ret = ath11k_dp_peer_rx_pn_replay_config(arvif, peer_addr, cmd, key);
- if (ret) {
- ath11k_warn(ab, "failed to offload PN replay detection %d\n", ret);
- goto exit;
+ is_ap_with_no_sta = (vif->type == NL80211_IFTYPE_AP &&
+ !arvif->num_stations);
+ if ((flags & WMI_KEY_PAIRWISE) || cmd == SET_KEY || is_ap_with_no_sta) {
+ ret = ath11k_install_key(arvif, key, cmd, peer_addr, flags);
+ if (ret) {
+ ath11k_warn(ab, "ath11k_install_key failed (%d)\n", ret);
+ goto exit;
+ }
+
+ ret = ath11k_dp_peer_rx_pn_replay_config(arvif, peer_addr, cmd, key);
+ if (ret) {
+ ath11k_warn(ab, "failed to offload PN replay detection %d\n",
+ ret);
+ goto exit;
+ }
+
+ if ((flags & WMI_KEY_GROUP) && cmd == SET_KEY && is_ap_with_no_sta)
+ arvif->reinstall_group_keys = true;
}
spin_lock_bh(&ab->base_lock);
@@ -4994,6 +5070,7 @@ static int ath11k_mac_inc_num_stations(s
return -ENOBUFS;
ar->num_stations++;
+ arvif->num_stations++;
return 0;
}
@@ -5009,6 +5086,7 @@ static void ath11k_mac_dec_num_stations(
return;
ar->num_stations--;
+ arvif->num_stations--;
}
static u32 ath11k_mac_ieee80211_sta_bw_to_wmi(struct ath11k *ar,
@@ -9536,6 +9614,21 @@ static int ath11k_mac_station_add(struct
goto exit;
}
+ /* Driver allows the DEL KEY followed by SET KEY sequence for
+ * group keys for only when there is no clients associated, if at
+ * all firmware has entered the race during that window,
+ * reinstalling the same key when the first sta connects will allow
+ * firmware to recover from the race.
+ */
+ if (arvif->num_stations == 1 && arvif->reinstall_group_keys) {
+ ath11k_dbg(ab, ATH11K_DBG_MAC, "set group keys on 1st station add for vdev %d\n",
+ arvif->vdev_id);
+ ret = ath11k_set_group_keys(arvif);
+ if (ret)
+ goto dec_num_station;
+ arvif->reinstall_group_keys = false;
+ }
+
arsta->rx_stats = kzalloc(sizeof(*arsta->rx_stats), GFP_KERNEL);
if (!arsta->rx_stats) {
ret = -ENOMEM;

View File

@ -0,0 +1,40 @@
From 888830b2cbc035838bebefe94502976da94332a5 Mon Sep 17 00:00:00 2001
From: Matvey Kovalev <matvey.kovalev@ispras.ru>
Date: Wed, 17 Sep 2025 22:20:01 +0300
Subject: wifi: ath11k: fix NULL dereference in ath11k_qmi_m3_load()
commit 3fd2ef2ae2b5c955584a3bee8e83ae7d7a98f782 upstream.
If ab->fw.m3_data points to data, then fw pointer remains null.
Further, if m3_mem is not allocated, then fw is dereferenced to be
passed to ath11k_err function.
Replace fw->size by m3_len.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: 7db88b962f06 ("wifi: ath11k: add firmware-2.bin support")
Cc: stable@vger.kernel.org
Signed-off-by: Matvey Kovalev <matvey.kovalev@ispras.ru>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Link: https://patch.msgid.link/20250917192020.1340-1-matvey.kovalev@ispras.ru
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wireless/ath/ath11k/qmi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'drivers/net/wireless/ath/ath11k')
--- a/drivers/net/wireless/ath/ath11k/qmi.c
+++ b/drivers/net/wireless/ath/ath11k/qmi.c
@@ -2576,7 +2576,7 @@ static int ath11k_qmi_m3_load(struct ath
GFP_KERNEL);
if (!m3_mem->vaddr) {
ath11k_err(ab, "failed to allocate memory for M3 with size %zu\n",
- fw->size);
+ m3_len);
ret = -ENOMEM;
goto out;
}

View File

@ -3,14 +3,14 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=mt76
PKG_RELEASE=1
PKG_LICENSE:=GPLv2
PKG_LICENSE:=BSD-3-Clause-Clear
PKG_LICENSE_FILES:=
PKG_SOURCE_URL:=https://github.com/openwrt/mt76
PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2025-10-03
PKG_SOURCE_VERSION:=ec3f05480e5b02a39bac93b76253d56b2a19bdb6
PKG_MIRROR_HASH:=c6469e91204793d0a859b78ab3baa1eb33a97458228a2849451baabb31e6499b
PKG_SOURCE_DATE:=2025-10-20
PKG_SOURCE_VERSION:=c63db0fcadb88680b35bec202b5142cfd016c10f
PKG_MIRROR_HASH:=38c3c84f5c58b6967283acf524412f6e13628d50add6f09d539f1239fb02b486
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
PKG_USE_NINJA:=0

View File

@ -1,125 +0,0 @@
From: Sven Eckelmann (Plasma Cloud) <se@simonwunderlich.de>
Date: Mon, 30 Jun 2025 16:18:21 +0200
Subject: wifi: mt76: Fix DTS power-limits on little endian systems
The power-limits for ru and mcs and stored in the devicetree as bytewise
array (often with sizes which are not a multiple of 4). These arrays have a
prefix which defines for how many modes a line is applied. This prefix is
also only a byte - but the code still tried to fix the endianness of this
byte with a be32 operation. As result, loading was mostly failing or was
sending completely unexpected values to the firmware.
Since the other rates are also stored in the devicetree as bytewise arrays,
just drop the u32 access + be32_to_cpu conversion and directly access them
as bytes arrays.
Cc: stable@vger.kernel.org
Fixes: 22b980badc0f ("mt76: add functions for parsing rate power limits from DT")
Fixes: a9627d992b5e ("mt76: extend DT rate power limits to support 11ax devices")
Signed-off-by: Sven Eckelmann (Plasma Cloud) <se@simonwunderlich.de>
Forwarded: https://lore.kernel.org/r/20250926-fix-power-limits-v2-1-c2bc7881eb6d@simonwunderlich.de
--- a/eeprom.c
+++ b/eeprom.c
@@ -273,6 +273,19 @@ mt76_get_of_array(struct device_node *np
return prop->value;
}
+static const s8 *
+mt76_get_of_array_s8(struct device_node *np, char *name, size_t *len, int min)
+{
+ struct property *prop = of_find_property(np, name, NULL);
+
+ if (!prop || !prop->value || prop->length < min)
+ return NULL;
+
+ *len = prop->length;
+
+ return prop->value;
+}
+
struct device_node *
mt76_find_channel_node(struct device_node *np, struct ieee80211_channel *chan)
{
@@ -314,7 +327,7 @@ mt76_get_txs_delta(struct device_node *n
}
static void
-mt76_apply_array_limit(s8 *pwr, size_t pwr_len, const __be32 *data,
+mt76_apply_array_limit(s8 *pwr, size_t pwr_len, const s8 *data,
s8 target_power, s8 nss_delta, s8 *max_power)
{
int i;
@@ -323,15 +336,14 @@ mt76_apply_array_limit(s8 *pwr, size_t p
return;
for (i = 0; i < pwr_len; i++) {
- pwr[i] = min_t(s8, target_power,
- be32_to_cpu(data[i]) + nss_delta);
+ pwr[i] = min_t(s8, target_power, data[i] + nss_delta);
*max_power = max(*max_power, pwr[i]);
}
}
static void
mt76_apply_multi_array_limit(s8 *pwr, size_t pwr_len, s8 pwr_num,
- const __be32 *data, size_t len, s8 target_power,
+ const s8 *data, size_t len, s8 target_power,
s8 nss_delta, s8 *max_power)
{
int i, cur;
@@ -339,8 +351,7 @@ mt76_apply_multi_array_limit(s8 *pwr, si
if (!data)
return;
- len /= 4;
- cur = be32_to_cpu(data[0]);
+ cur = data[0];
for (i = 0; i < pwr_num; i++) {
if (len < pwr_len + 1)
break;
@@ -355,7 +366,7 @@ mt76_apply_multi_array_limit(s8 *pwr, si
if (!len)
break;
- cur = be32_to_cpu(data[0]);
+ cur = data[0];
}
}
@@ -366,7 +377,7 @@ s8 mt76_get_rate_power_limits(struct mt7
{
struct mt76_dev *dev = phy->dev;
struct device_node *np;
- const __be32 *val;
+ const s8 *val;
char name[16];
u32 mcs_rates = dev->drv->mcs_rates;
u32 ru_rates = ARRAY_SIZE(dest->ru[0]);
@@ -412,21 +423,21 @@ s8 mt76_get_rate_power_limits(struct mt7
txs_delta = mt76_get_txs_delta(np, hweight16(phy->chainmask));
- val = mt76_get_of_array(np, "rates-cck", &len, ARRAY_SIZE(dest->cck));
+ val = mt76_get_of_array_s8(np, "rates-cck", &len, ARRAY_SIZE(dest->cck));
mt76_apply_array_limit(dest->cck, ARRAY_SIZE(dest->cck), val,
target_power, txs_delta, &max_power);
- val = mt76_get_of_array(np, "rates-ofdm",
- &len, ARRAY_SIZE(dest->ofdm));
+ val = mt76_get_of_array_s8(np, "rates-ofdm",
+ &len, ARRAY_SIZE(dest->ofdm));
mt76_apply_array_limit(dest->ofdm, ARRAY_SIZE(dest->ofdm), val,
target_power, txs_delta, &max_power);
- val = mt76_get_of_array(np, "rates-mcs", &len, mcs_rates + 1);
+ val = mt76_get_of_array_s8(np, "rates-mcs", &len, mcs_rates + 1);
mt76_apply_multi_array_limit(dest->mcs[0], ARRAY_SIZE(dest->mcs[0]),
ARRAY_SIZE(dest->mcs), val, len,
target_power, txs_delta, &max_power);
- val = mt76_get_of_array(np, "rates-ru", &len, ru_rates + 1);
+ val = mt76_get_of_array_s8(np, "rates-ru", &len, ru_rates + 1);
mt76_apply_multi_array_limit(dest->ru[0], ARRAY_SIZE(dest->ru[0]),
ARRAY_SIZE(dest->ru), val, len,
target_power, txs_delta, &max_power);

View File

@ -1,576 +0,0 @@
From: Shayne Chen <shayne.chen@mediatek.com>
Date: Mon, 5 Dec 2022 18:21:51 +0800
Subject: wifi: mt76: mt7915: add bf backoff limit table support
The commit 22b980badc0f ("mt76: add functions for parsing rate power limits
from DT") introduced generic support for rates limits in the devicetree.
But the mt7915 supports beamforming and has another table for configuring
the backoff limits. These can be configured in the DT with the paths-*
properties. The path-*-bf are the ones relevant for beamforming and the
ones without -bf suffix for "traditional" path backoff.
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
Signed-off-by: Sven Eckelmann (Plasma Cloud) <se@simonwunderlich.de>
Forwarded: https://lore.kernel.org/r/20250924-backoff-table-support-v1-3-20e50fbc59de@simonwunderlich.de
--- a/debugfs.c
+++ b/debugfs.c
@@ -93,9 +93,9 @@ void mt76_seq_puts_array(struct seq_file
{
int i;
- seq_printf(file, "%10s:", str);
+ seq_printf(file, "%16s:", str);
for (i = 0; i < len; i++)
- seq_printf(file, " %2d", val[i]);
+ seq_printf(file, " %4d", val[i]);
seq_puts(file, "\n");
}
EXPORT_SYMBOL_GPL(mt76_seq_puts_array);
--- a/eeprom.c
+++ b/eeprom.c
@@ -344,9 +344,10 @@ mt76_apply_array_limit(s8 *pwr, size_t p
static void
mt76_apply_multi_array_limit(s8 *pwr, size_t pwr_len, s8 pwr_num,
const s8 *data, size_t len, s8 target_power,
- s8 nss_delta, s8 *max_power)
+ s8 nss_delta)
{
int i, cur;
+ s8 max_power = -128;
if (!data)
return;
@@ -357,7 +358,7 @@ mt76_apply_multi_array_limit(s8 *pwr, si
break;
mt76_apply_array_limit(pwr + pwr_len * i, pwr_len, data + 1,
- target_power, nss_delta, max_power);
+ target_power, nss_delta, &max_power);
if (--cur > 0)
continue;
@@ -384,12 +385,16 @@ s8 mt76_get_rate_power_limits(struct mt7
char band;
size_t len;
s8 max_power = 0;
+ s8 max_power_backoff = -127;
s8 txs_delta;
+ int n_chains = hweight16(phy->chainmask);
+ s8 target_power_combine = target_power + mt76_tx_power_path_delta(n_chains);
if (!mcs_rates)
mcs_rates = 10;
- memset(dest, target_power, sizeof(*dest));
+ memset(dest, target_power, sizeof(*dest) - sizeof(dest->path));
+ memset(&dest->path, 0, sizeof(dest->path));
if (!IS_ENABLED(CONFIG_OF))
return target_power;
@@ -435,12 +440,35 @@ s8 mt76_get_rate_power_limits(struct mt7
val = mt76_get_of_array_s8(np, "rates-mcs", &len, mcs_rates + 1);
mt76_apply_multi_array_limit(dest->mcs[0], ARRAY_SIZE(dest->mcs[0]),
ARRAY_SIZE(dest->mcs), val, len,
- target_power, txs_delta, &max_power);
+ target_power, txs_delta);
val = mt76_get_of_array_s8(np, "rates-ru", &len, ru_rates + 1);
mt76_apply_multi_array_limit(dest->ru[0], ARRAY_SIZE(dest->ru[0]),
ARRAY_SIZE(dest->ru), val, len,
- target_power, txs_delta, &max_power);
+ target_power, txs_delta);
+
+ max_power_backoff = max_power;
+ val = mt76_get_of_array_s8(np, "paths-cck", &len, ARRAY_SIZE(dest->path.cck));
+ mt76_apply_array_limit(dest->path.cck, ARRAY_SIZE(dest->path.cck), val,
+ target_power_combine, txs_delta, &max_power_backoff);
+
+ val = mt76_get_of_array_s8(np, "paths-ofdm", &len, ARRAY_SIZE(dest->path.ofdm));
+ mt76_apply_array_limit(dest->path.ofdm, ARRAY_SIZE(dest->path.ofdm), val,
+ target_power_combine, txs_delta, &max_power_backoff);
+
+ val = mt76_get_of_array_s8(np, "paths-ofdm-bf", &len, ARRAY_SIZE(dest->path.ofdm_bf));
+ mt76_apply_array_limit(dest->path.ofdm_bf, ARRAY_SIZE(dest->path.ofdm_bf), val,
+ target_power_combine, txs_delta, &max_power_backoff);
+
+ val = mt76_get_of_array_s8(np, "paths-ru", &len, ARRAY_SIZE(dest->path.ru[0]) + 1);
+ mt76_apply_multi_array_limit(dest->path.ru[0], ARRAY_SIZE(dest->path.ru[0]),
+ ARRAY_SIZE(dest->path.ru), val, len,
+ target_power_combine, txs_delta);
+
+ val = mt76_get_of_array_s8(np, "paths-ru-bf", &len, ARRAY_SIZE(dest->path.ru_bf[0]) + 1);
+ mt76_apply_multi_array_limit(dest->path.ru_bf[0], ARRAY_SIZE(dest->path.ru_bf[0]),
+ ARRAY_SIZE(dest->path.ru_bf), val, len,
+ target_power_combine, txs_delta);
return max_power;
}
--- a/mt76.h
+++ b/mt76.h
@@ -1118,6 +1118,14 @@ struct mt76_power_limits {
s8 mcs[4][10];
s8 ru[7][12];
s8 eht[16][16];
+
+ struct {
+ s8 cck[4];
+ s8 ofdm[4];
+ s8 ofdm_bf[4];
+ s8 ru[7][10];
+ s8 ru_bf[7][10];
+ } path;
};
struct mt76_ethtool_worker_info {
--- a/mt7915/debugfs.c
+++ b/mt7915/debugfs.c
@@ -1008,7 +1008,7 @@ mt7915_rate_txpower_get(struct file *fil
if (!buf)
return -ENOMEM;
- ret = mt7915_mcu_get_txpower_sku(phy, txpwr, sizeof(txpwr));
+ ret = mt7915_mcu_get_txpower_sku(phy, txpwr, sizeof(txpwr), TX_POWER_INFO_RATE);
if (ret)
goto out;
@@ -1118,7 +1118,7 @@ mt7915_rate_txpower_set(struct file *fil
mutex_lock(&dev->mt76.mutex);
ret = mt7915_mcu_get_txpower_sku(phy, req.txpower_sku,
- sizeof(req.txpower_sku));
+ sizeof(req.txpower_sku), TX_POWER_INFO_RATE);
if (ret)
goto out;
@@ -1160,7 +1160,7 @@ out:
return ret ? ret : count;
}
-static const struct file_operations mt7915_rate_txpower_fops = {
+static const struct file_operations mt7915_txpower_fops = {
.write = mt7915_rate_txpower_set,
.read = mt7915_rate_txpower_get,
.open = simple_open,
@@ -1169,6 +1169,70 @@ static const struct file_operations mt79
};
static int
+mt7915_path_txpower_show(struct seq_file *file)
+{
+ struct mt7915_phy *phy = file->private;
+ s8 txpower[MT7915_SKU_PATH_NUM], *buf = txpower;
+ int ret;
+
+#define PATH_POWER_SHOW(_name, _len, _skip) do { \
+ size_t __len = (_len); \
+ if (_skip) { \
+ buf -= 1; \
+ *buf = 0; \
+ } \
+ mt76_seq_puts_array(file, _name, buf, __len); \
+ buf += __len; \
+ } while (0)
+
+ seq_printf(file, "\n%*c", 18, ' ');
+ seq_puts(file, "1T1S/2T1S/3T1S/4T1S/2T2S/3T2S/4T2S/3T3S/4T3S/4T4S\n");
+ ret = mt7915_mcu_get_txpower_sku(phy, txpower, sizeof(txpower),
+ TX_POWER_INFO_PATH);
+ if (ret)
+ return ret;
+
+ PATH_POWER_SHOW("CCK", 4, 0);
+ PATH_POWER_SHOW("OFDM", 4, 0);
+ PATH_POWER_SHOW("BF-OFDM", 4, 1);
+
+ PATH_POWER_SHOW("HT/VHT20", 10, 0);
+ PATH_POWER_SHOW("BF-HT/VHT20", 10, 1);
+ PATH_POWER_SHOW("HT/VHT40", 10, 0);
+ PATH_POWER_SHOW("BF-HT/VHT40", 10, 1);
+
+ PATH_POWER_SHOW("BW20/RU242", 10, 0);
+ PATH_POWER_SHOW("BF-BW20/RU242", 10, 1);
+ PATH_POWER_SHOW("BW40/RU484", 10, 0);
+ PATH_POWER_SHOW("BF-BW40/RU484", 10, 1);
+ PATH_POWER_SHOW("BW80/RU996", 10, 0);
+ PATH_POWER_SHOW("BF-BW80/RU996", 10, 1);
+ PATH_POWER_SHOW("BW160/RU2x996", 10, 0);
+ PATH_POWER_SHOW("BF-BW160/RU2x996", 10, 1);
+ PATH_POWER_SHOW("RU26", 10, 0);
+ PATH_POWER_SHOW("BF-RU26", 10, 0);
+ PATH_POWER_SHOW("RU52", 10, 0);
+ PATH_POWER_SHOW("BF-RU52", 10, 0);
+ PATH_POWER_SHOW("RU106", 10, 0);
+ PATH_POWER_SHOW("BF-RU106", 10, 0);
+#undef PATH_POWER_SHOW
+
+ return 0;
+}
+
+static int
+mt7915_txpower_path_show(struct seq_file *file, void *data)
+{
+ struct mt7915_phy *phy = file->private;
+
+ seq_printf(file, "\nBand %d\n", phy != &phy->dev->phy);
+
+ return mt7915_path_txpower_show(file);
+}
+
+DEFINE_SHOW_ATTRIBUTE(mt7915_txpower_path);
+
+static int
mt7915_twt_stats(struct seq_file *s, void *data)
{
struct mt7915_dev *dev = dev_get_drvdata(s->private);
@@ -1254,7 +1318,9 @@ int mt7915_init_debugfs(struct mt7915_ph
debugfs_create_file("implicit_txbf", 0600, dir, dev,
&fops_implicit_txbf);
debugfs_create_file("txpower_sku", 0400, dir, phy,
- &mt7915_rate_txpower_fops);
+ &mt7915_txpower_fops);
+ debugfs_create_file("txpower_path", 0400, dir, phy,
+ &mt7915_txpower_path_fops);
debugfs_create_devm_seqfile(dev->mt76.dev, "twt_stats", dir,
mt7915_twt_stats);
debugfs_create_file("rf_regval", 0600, dir, dev, &fops_rf_regval);
--- a/mt7915/init.c
+++ b/mt7915/init.c
@@ -289,6 +289,8 @@ static void __mt7915_init_txpower(struct
int pwr_delta = mt7915_eeprom_get_power_delta(dev, sband->band);
struct mt76_power_limits limits;
+ phy->sku_limit_en = true;
+ phy->sku_path_en = true;
for (i = 0; i < sband->n_channels; i++) {
struct ieee80211_channel *chan = &sband->channels[i];
u32 target_power = 0;
@@ -305,6 +307,11 @@ static void __mt7915_init_txpower(struct
target_power = mt76_get_rate_power_limits(phy->mt76, chan,
&limits,
target_power);
+
+ /* MT7915N can not enable Backoff table without setting value in dts */
+ if (!limits.path.ofdm[0])
+ phy->sku_path_en = false;
+
target_power += path_delta;
target_power = DIV_ROUND_UP(target_power, 2);
chan->max_power = min_t(int, chan->max_reg_power,
--- a/mt7915/main.c
+++ b/mt7915/main.c
@@ -73,7 +73,7 @@ int mt7915_run(struct ieee80211_hw *hw)
if (ret)
goto out;
- ret = mt7915_mcu_set_sku_en(phy, true);
+ ret = mt7915_mcu_set_sku_en(phy);
if (ret)
goto out;
--- a/mt7915/mcu.c
+++ b/mt7915/mcu.c
@@ -3336,7 +3336,8 @@ int mt7915_mcu_set_txpower_frame(struct
int ret;
s8 txpower_sku[MT7915_SKU_RATE_NUM];
- ret = mt7915_mcu_get_txpower_sku(phy, txpower_sku, sizeof(txpower_sku));
+ ret = mt7915_mcu_get_txpower_sku(phy, txpower_sku, sizeof(txpower_sku),
+ TX_POWER_INFO_RATE);
if (ret)
return ret;
@@ -3376,51 +3377,136 @@ int mt7915_mcu_set_txpower_frame(struct
sizeof(req), true);
}
+static void
+mt7915_update_txpower(struct mt7915_phy *phy, int tx_power)
+{
+ struct mt76_phy *mphy = phy->mt76;
+ struct ieee80211_channel *chan = mphy->main_chandef.chan;
+ int chain_idx, val, e2p_power_limit = 0;
+
+ if (!chan) {
+ mphy->txpower_cur = tx_power;
+ return;
+ }
+
+ for (chain_idx = 0; chain_idx < hweight16(mphy->chainmask); chain_idx++) {
+ val = mt7915_eeprom_get_target_power(phy->dev, chan, chain_idx);
+ val += mt7915_eeprom_get_power_delta(phy->dev, chan->band);
+
+ e2p_power_limit = max_t(int, e2p_power_limit, val);
+ }
+
+ if (phy->sku_limit_en)
+ mphy->txpower_cur = min_t(int, e2p_power_limit, tx_power);
+ else
+ mphy->txpower_cur = e2p_power_limit;
+}
+
int mt7915_mcu_set_txpower_sku(struct mt7915_phy *phy)
{
+#define TX_POWER_LIMIT_TABLE_RATE 0
+#define TX_POWER_LIMIT_TABLE_PATH 1
struct mt7915_dev *dev = phy->dev;
struct mt76_phy *mphy = phy->mt76;
struct ieee80211_hw *hw = mphy->hw;
- struct mt7915_mcu_txpower_sku req = {
+ struct mt7915_sku_val {
+ u8 format_id;
+ u8 limit_type;
+ u8 band_idx;
+ } __packed hdr = {
.format_id = TX_POWER_LIMIT_TABLE,
+ .limit_type = TX_POWER_LIMIT_TABLE_RATE,
.band_idx = phy->mt76->band_idx,
};
- struct mt76_power_limits limits_array;
- s8 *la = (s8 *)&limits_array;
- int i, idx;
- int tx_power;
+ int i, ret, tx_power;
+ const u8 *len = mt7915_sku_group_len;
+ struct mt76_power_limits la = {};
+ struct sk_buff *skb;
tx_power = mt76_get_power_bound(mphy, hw->conf.power_level);
- tx_power = mt76_get_rate_power_limits(mphy, mphy->chandef.chan,
- &limits_array, tx_power);
- mphy->txpower_cur = tx_power;
-
- for (i = 0, idx = 0; i < ARRAY_SIZE(mt7915_sku_group_len); i++) {
- u8 mcs_num, len = mt7915_sku_group_len[i];
- int j;
+ if (phy->sku_limit_en) {
+ tx_power = mt76_get_rate_power_limits(mphy, mphy->chandef.chan,
+ &la, tx_power);
+ mt7915_update_txpower(phy, tx_power);
+ } else {
+ mt7915_update_txpower(phy, tx_power);
+ return 0;
+ }
- if (i >= SKU_HT_BW20 && i <= SKU_VHT_BW160) {
- mcs_num = 10;
+ skb = mt76_mcu_msg_alloc(&dev->mt76, NULL,
+ sizeof(hdr) + MT7915_SKU_RATE_NUM);
+ if (!skb)
+ return -ENOMEM;
+
+ skb_put_data(skb, &hdr, sizeof(hdr));
+ skb_put_data(skb, &la.cck, len[SKU_CCK] + len[SKU_OFDM]);
+ skb_put_data(skb, &la.mcs[0], len[SKU_HT_BW20]);
+ skb_put_data(skb, &la.mcs[1], len[SKU_HT_BW40]);
+
+ /* vht */
+ for (i = 0; i < 4; i++) {
+ skb_put_data(skb, &la.mcs[i], sizeof(la.mcs[i]));
+ skb_put_zero(skb, 2); /* padding */
+ }
- if (i == SKU_HT_BW20 || i == SKU_VHT_BW20)
- la = (s8 *)&limits_array + 12;
- } else {
- mcs_num = len;
- }
+ /* he */
+ skb_put_data(skb, &la.ru[0], sizeof(la.ru));
+ ret = mt76_mcu_skb_send_msg(&dev->mt76, skb,
+ MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), true);
+ if (ret)
+ return ret;
+
+ /* only set per-path power table when it's configured */
+ if (!phy->sku_path_en)
+ return 0;
+
+ skb = mt76_mcu_msg_alloc(&dev->mt76, NULL,
+ sizeof(hdr) + MT7915_SKU_PATH_NUM);
+ if (!skb)
+ return -ENOMEM;
+
+ hdr.limit_type = TX_POWER_LIMIT_TABLE_PATH;
+ skb_put_data(skb, &hdr, sizeof(hdr));
+ skb_put_data(skb, &la.path.cck, sizeof(la.path.cck));
+ skb_put_data(skb, &la.path.ofdm, sizeof(la.path.ofdm));
+ skb_put_data(skb, &la.path.ofdm_bf[1], sizeof(la.path.ofdm_bf) - 1);
+
+ /* HT20 and HT40 */
+ skb_put_data(skb, &la.path.ru[3], sizeof(la.path.ru[3]));
+ skb_put_data(skb, &la.path.ru_bf[3][1], sizeof(la.path.ru_bf[3]) - 1);
+ skb_put_data(skb, &la.path.ru[4], sizeof(la.path.ru[4]));
+ skb_put_data(skb, &la.path.ru_bf[4][1], sizeof(la.path.ru_bf[4]) - 1);
+
+ /* start from non-bf and bf fields of
+ * BW20/RU242, BW40/RU484, BW80/RU996, BW160/RU2x996,
+ * RU26, RU52, and RU106
+ */
+
+ for (i = 0; i < 8; i++) {
+ bool bf = i % 2;
+ u8 idx = (i + 6) / 2;
+ s8 *buf = bf ? la.path.ru_bf[idx] : la.path.ru[idx];
+ /* The non-bf fields of RU26 to RU106 are special cases */
+ if (bf)
+ skb_put_data(skb, buf + 1, 9);
+ else
+ skb_put_data(skb, buf, 10);
+ }
- for (j = 0; j < min_t(u8, mcs_num, len); j++)
- req.txpower_sku[idx + j] = la[j];
+ for (i = 0; i < 6; i++) {
+ bool bf = i % 2;
+ u8 idx = i / 2;
+ s8 *buf = bf ? la.path.ru_bf[idx] : la.path.ru[idx];
- la += mcs_num;
- idx += len;
+ skb_put_data(skb, buf, 10);
}
- return mt76_mcu_send_msg(&dev->mt76,
- MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), &req,
- sizeof(req), true);
+ return mt76_mcu_skb_send_msg(&dev->mt76, skb,
+ MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), true);
}
-int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len)
+int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len,
+ u8 category)
{
#define RATE_POWER_INFO 2
struct mt7915_dev *dev = phy->dev;
@@ -3431,10 +3517,9 @@ int mt7915_mcu_get_txpower_sku(struct mt
u8 _rsv;
} __packed req = {
.format_id = TX_POWER_LIMIT_INFO,
- .category = RATE_POWER_INFO,
+ .category = category,
.band_idx = phy->mt76->band_idx,
};
- s8 txpower_sku[MT7915_SKU_RATE_NUM][2];
struct sk_buff *skb;
int ret, i;
@@ -3444,9 +3529,15 @@ int mt7915_mcu_get_txpower_sku(struct mt
if (ret)
return ret;
- memcpy(txpower_sku, skb->data + 4, sizeof(txpower_sku));
- for (i = 0; i < len; i++)
- txpower[i] = txpower_sku[i][req.band_idx];
+ if (category == TX_POWER_INFO_RATE) {
+ s8 res[MT7915_SKU_RATE_NUM][2];
+
+ memcpy(res, skb->data + 4, sizeof(res));
+ for (i = 0; i < len; i++)
+ txpower[i] = res[i][req.band_idx];
+ } else if (category == TX_POWER_INFO_PATH) {
+ memcpy(txpower, skb->data + 4, len);
+ }
dev_kfree_skb(skb);
@@ -3475,7 +3566,7 @@ int mt7915_mcu_set_test_param(struct mt7
sizeof(req), false);
}
-int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable)
+int mt7915_mcu_set_sku_en(struct mt7915_phy *phy)
{
struct mt7915_dev *dev = phy->dev;
struct mt7915_sku {
@@ -3484,10 +3575,21 @@ int mt7915_mcu_set_sku_en(struct mt7915_
u8 band_idx;
u8 rsv;
} __packed req = {
- .format_id = TX_POWER_LIMIT_ENABLE,
.band_idx = phy->mt76->band_idx,
- .sku_enable = enable,
};
+ int ret;
+
+ req.sku_enable = phy->sku_limit_en;
+ req.format_id = TX_POWER_LIMIT_ENABLE;
+
+ ret = mt76_mcu_send_msg(&dev->mt76,
+ MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), &req,
+ sizeof(req), true);
+ if (ret)
+ return ret;
+
+ req.sku_enable = phy->sku_path_en;
+ req.format_id = TX_POWER_LIMIT_PATH_ENABLE;
return mt76_mcu_send_msg(&dev->mt76,
MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), &req,
--- a/mt7915/mcu.h
+++ b/mt7915/mcu.h
@@ -429,6 +429,7 @@ enum {
enum {
TX_POWER_LIMIT_ENABLE,
+ TX_POWER_LIMIT_PATH_ENABLE = 0x3,
TX_POWER_LIMIT_TABLE = 0x4,
TX_POWER_LIMIT_INFO = 0x7,
TX_POWER_LIMIT_FRAME = 0x11,
@@ -436,6 +437,11 @@ enum {
};
enum {
+ TX_POWER_INFO_PATH = 1,
+ TX_POWER_INFO_RATE,
+};
+
+enum {
SPR_ENABLE = 0x1,
SPR_ENABLE_SD = 0x3,
SPR_ENABLE_MODE = 0x5,
--- a/mt7915/mt7915.h
+++ b/mt7915/mt7915.h
@@ -70,6 +70,7 @@
#define MT7915_CDEV_THROTTLE_MAX 99
#define MT7915_SKU_RATE_NUM 161
+#define MT7915_SKU_PATH_NUM 185
#define MT7915_MAX_TWT_AGRT 16
#define MT7915_MAX_STA_TWT_AGRT 8
@@ -223,6 +224,9 @@ struct mt7915_phy {
struct mt76_mib_stats mib;
struct mt76_channel_state state_ts;
+ bool sku_limit_en:1;
+ bool sku_path_en:1;
+
#ifdef CONFIG_NL80211_TESTMODE
struct {
u32 *reg_backup;
@@ -491,9 +495,10 @@ int mt7915_mcu_set_mac(struct mt7915_dev
int mt7915_mcu_set_test_param(struct mt7915_dev *dev, u8 param, bool test_mode,
u8 en);
int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band);
-int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable);
+int mt7915_mcu_set_sku_en(struct mt7915_phy *phy);
int mt7915_mcu_set_txpower_sku(struct mt7915_phy *phy);
-int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len);
+int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len,
+ u8 category);
int mt7915_mcu_set_txpower_frame_min(struct mt7915_phy *phy, s8 txpower);
int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy,
struct ieee80211_vif *vif,
--- a/mt7915/testmode.c
+++ b/mt7915/testmode.c
@@ -409,7 +409,7 @@ mt7915_tm_init(struct mt7915_phy *phy, b
if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state))
return;
- mt7915_mcu_set_sku_en(phy, !en);
+ mt7915_mcu_set_sku_en(phy);
mt7915_tm_mode_ctrl(dev, en);
mt7915_tm_reg_backup_restore(phy);

View File

@ -5,9 +5,9 @@ PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/project/netifd.git
PKG_SOURCE_DATE:=2025-10-06
PKG_SOURCE_VERSION:=649028013a3c8f6ed53fc97ca997d2528d06b5d9
PKG_MIRROR_HASH:=6b1ca809111c583d75ad68ce6b3b6211c0acfcb07c06e5c843b021004bf19613
PKG_SOURCE_DATE:=2025-10-20
PKG_SOURCE_VERSION:=777f5942fa7d6245f6ad29daa1daecc400344d37
PKG_MIRROR_HASH:=7fc56f436faa1a5b05a147febed52c6f58c479125a38c9737736b352cd8d4409
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
PKG_LICENSE:=GPL-2.0

View File

@ -4,6 +4,7 @@
. /lib/functions.sh
. ../netifd-proto.sh
. /lib/config/uci.sh
init_proto "$@"
proto_dhcp_init_config() {
@ -31,6 +32,18 @@ proto_dhcp_add_sendopts() {
[ -n "$1" ] && append "$3" "-x $1"
}
proto_dhcp_get_default_clientid() {
[ -z "$1" ] && return
local iface="$1"
local duid
local iaid="0"
[ -e "/sys/class/net/$iface/ifindex" ] && iaid="$(cat "/sys/class/net/$iface/ifindex")"
duid="$(uci_get network @globals[0] dhcp_default_duid)"
[ -n "$duid" ] && printf "ff%08x%s" "$iaid" "$duid"
}
proto_dhcp_setup() {
local config="$1"
local iface="$2"
@ -51,6 +64,7 @@ proto_dhcp_setup() {
[ "$defaultreqopts" = 0 ] && defaultreqopts="-o" || defaultreqopts=
[ "$broadcast" = 1 ] && broadcast="-B" || broadcast=
[ "$norelease" = 1 ] && norelease="" || norelease="-R"
[ -z "$clientid" ] && clientid="$(proto_dhcp_get_default_clientid "$iface")"
[ -n "$clientid" ] && clientid="-x 0x3d:${clientid//:/}"
[ -n "$iface6rd" ] && proto_export "IFACE6RD=$iface6rd"
[ "$iface6rd" != 0 -a -f /lib/netifd/proto/6rd.sh ] && append dhcpopts "-O 212"

View File

@ -270,11 +270,15 @@ function setup() {
if (!v.config.default_macaddr)
config.macaddr = v.config.macaddr;
config_add(config, "htmode", wdev_htmode(data.config));
config_add(config, "freq", data.config.frequency);
config_add(config, "htmode", iw_htmode(data.config));
if (mode != "monitor") {
config_add(config, "basic-rates", supplicant.ratelist(data.config.basic_rate));
let basic_rate_list = v.config.basic_rate ?? data.config.basic_rate;
config_add(config, "basic-rates", supplicant.ratelist(basic_rate_list));
config_add(config, "mcast-rate", supplicant.ratestr(v.config.mcast_rate));
config_add(config, "beacon-interval", data.config.beacon_int);
if (mode == "adhoc")
config_add(config, "bssid", v.config.bssid);
if (mode == "mesh") {
config_add(config, "ssid", v.config.mesh_id);
config_add_mesh_params(config, v.config);

View File

@ -91,6 +91,20 @@ function print_scan(cells) {
printf('\t\tChannel Width: %s\n', cell.vht.chan_width);
}
if (cell.he) {
printf('\t HE Operation:\n');
printf('\t\tCenter Frequency 1: %d\n', cell.he.center_chan_1);
printf('\t\tCenter Frequency 2: %s\n', cell.he.center_chan_2);
printf('\t\tChannel Width: %s\n', cell.he.chan_width);
}
if (cell.eht) {
printf('\t EHT Operation:\n');
printf('\t\tCenter Frequency 1: %d\n', cell.eht.center_chan_1);
printf('\t\tCenter Frequency 2: %s\n', cell.eht.center_chan_2);
printf('\t\tChannel Width: %s\n', cell.eht.chan_width);
}
printf('\n');
}
}

View File

@ -481,6 +481,42 @@ export function countrylist(dev) {
return list;
};
function scan_extension(ext, cell) {
const eht_chan_width = [ '20 MHz', '40 MHz', '80 MHz', '160 MHz', '320 MHz'];
switch(ord(ext, 0)) {
case 36:
let offset = 7;
if (!(ord(ext, 3) & 0x2))
break;
if (ord(ext, 2) & 0x40)
offset += 3;
if (ord(ext, 2) & 0x80)
offset += 1;
cell.he = {
chan_width: eht_chan_width[ord(ext, offset + 1) & 0x3],
center_chan_1: ord(ext, offset + 2),
center_chan_2: ord(ext, offset + 3),
};
break;
case 106:
if (!(ord(ext, 1) & 0x1))
break;
cell.eht = {
chan_width: eht_chan_width[ord(ext, 6) & 0x7],
center_chan_1: ord(ext, 7),
center_chan_2: ord(ext, 8),
};
break;
}
};
export function scan(dev) {
const rsn_cipher = [ 'NONE', 'WEP-40', 'TKIP', 'WRAP', 'CCMP', 'WEP-104', 'AES-OCB', 'CKIP', 'GCMP', 'GCMP-256', 'CCMP-256' ];
const ht_chan_offset = [ 'no secondary', 'above', '[reserved]', 'below' ];
@ -591,6 +627,10 @@ export function scan(dev) {
center_chan_2: ord(ie.data, 2),
};
break;
case 255:
scan_extension(ie.data, cell);
break;
};

View File

@ -2,6 +2,7 @@
. /lib/functions.sh
. ../netifd-proto.sh
. /lib/config/uci.sh
init_proto "$@"
proto_dhcpv6_init_config() {
@ -66,6 +67,7 @@ proto_dhcpv6_setup() {
[ -z "$reqprefix" -o "$reqprefix" = "auto" ] && reqprefix=0
[ "$reqprefix" != "no" ] && append opts "-P$reqprefix"
[ -z "$clientid" ] && clientid="$(uci_get network @globals[0] dhcp_default_duid)"
[ -n "$clientid" ] && append opts "-c$clientid"
[ "$defaultreqopts" = "0" ] && append opts "-R"

View File

@ -345,7 +345,6 @@ CONFIG_RESET_CONTROLLER=y
CONFIG_RFS_ACCEL=y
CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
CONFIG_RPS=y
CONFIG_RTL8261N_PHY=y
CONFIG_RWSEM_SPIN_ON_OWNER=y
CONFIG_SERIAL_8250_AIROHA=y
CONFIG_SERIAL_8250_EXTENDED=y

View File

@ -336,7 +336,6 @@ CONFIG_RESET_CONTROLLER=y
CONFIG_RFS_ACCEL=y
CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
CONFIG_RPS=y
CONFIG_RTL8261N_PHY=y
CONFIG_RWSEM_SPIN_ON_OWNER=y
CONFIG_SERIAL_8250_AIROHA=y
CONFIG_SERIAL_8250_EXTENDED=y

View File

@ -8,7 +8,7 @@ define Device/Default
KERNEL = kernel-bin | lzma | \
fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb
KERNEL_INITRAMFS = kernel-bin | lzma | \
fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb with-initrd
fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb
FILESYSTEMS := squashfs
DEVICE_DTS = $$(SOC)-$(lastword $(subst _, ,$(1)))
DEVICE_DTS_DIR := ../dts

View File

@ -181,9 +181,11 @@
#size-cells = <1>;
partition@0 {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
label = "uboot";
reg = <0x00000000 0x00180000>;
compatible = "fixed-partitions";
read-only;
partition@40000 {

View File

@ -165,6 +165,14 @@
reg = <0x520c 0x6>;
#nvmem-cell-cells = <1>;
};
cal_art_1000: calibration@1000 {
reg = <0x1000 0xeb8>;
};
cal_art_5000: calibration@5000 {
reg = <0x5000 0xeb8>;
};
};
};
@ -201,7 +209,8 @@
ath9k0: wifi@11,0 {
compatible = "pci168c,0029";
reg = <0x8800 0 0 0 0>;
qca,no-eeprom;
nvmem-cells = <&cal_art_1000>;
nvmem-cell-names = "calibration";
#gpio-cells = <2>;
gpio-controller;
};
@ -209,7 +218,8 @@
ath9k1: wifi@12,0 {
compatible = "pci168c,0029";
reg = <0x9000 0 0 0 0>;
qca,no-eeprom;
nvmem-cells = <&cal_art_5000>;
nvmem-cell-names = "calibration";
#gpio-cells = <2>;
gpio-controller;
};

View File

@ -74,9 +74,8 @@
ath9k: wifi@0,0 {
compatible = "pci168c,0030";
reg = <0x0000 0 0 0 0>;
nvmem-cells = <&macaddr_art_1002>;
nvmem-cell-names = "mac-address";
qca,no-eeprom;
nvmem-cells = <&cal_art_1000>;
nvmem-cell-names = "calibration";
#gpio-cells = <2>;
gpio-controller;
qca,tx-gain-buffalo;
@ -89,6 +88,10 @@
#address-cells = <1>;
#size-cells = <1>;
cal_art_1000: calibration@1000 {
reg = <0x1000 0x440>;
};
macaddr_art_1002: macaddr@1002 {
reg = <0x1002 0x6>;
};

View File

@ -46,7 +46,7 @@
sck-gpios = <&gpio 16 GPIO_ACTIVE_HIGH>;
mosi-gpios = <&gpio 15 GPIO_ACTIVE_HIGH>;
cs-gpios = <&gpio 14 GPIO_ACTIVE_HIGH>;
cs-gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
num-chipselects = <1>;
gpio_hc595: gpio_spi@0 {

View File

@ -61,7 +61,6 @@
&spi {
status = "okay";
num-cs = <1>;
flash@0 {
compatible = "jedec,spi-nor";

View File

@ -64,7 +64,6 @@
&spi {
status = "okay";
num-cs = <1>;
flash@0 {
compatible = "jedec,spi-nor";

View File

@ -26,7 +26,7 @@
sck-gpios = <&gpio 15 GPIO_ACTIVE_HIGH>;
mosi-gpios = <&gpio 16 GPIO_ACTIVE_HIGH>;
cs-gpios = <&gpio 13 GPIO_ACTIVE_HIGH>;
cs-gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
num-chipselects = <1>;
led_gpio: led_gpio@0 {

View File

@ -205,7 +205,7 @@
&pcie0 {
status = "okay";
wifi@0,0,0 {
wifi@0,0 {
compatible = "qcom,ath10k";
reg = <0x0 0 0 0 0>;
nvmem-cells = <&calibration_pcie>, <&macaddr_uboot_3ff80 2>;

View File

@ -39,7 +39,7 @@
sck-gpios = <&gpio 0 GPIO_ACTIVE_HIGH>;
mosi-gpios = <&gpio 1 GPIO_ACTIVE_HIGH>;
cs-gpios = <&gpio 3 GPIO_ACTIVE_HIGH>;
cs-gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
num-chipselects = <1>;
led_gpio: led_gpio@0 {

View File

@ -25,7 +25,7 @@
sck-gpios = <&gpio 15 GPIO_ACTIVE_HIGH>;
mosi-gpios = <&gpio 14 GPIO_ACTIVE_HIGH>;
cs-gpios = <&gpio 16 GPIO_ACTIVE_HIGH>;
cs-gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
num-chipselects = <1>;
led_gpio: led_gpio@0 {

View File

@ -23,7 +23,7 @@
sck-gpios = <&gpio 18 GPIO_ACTIVE_HIGH>;
mosi-gpios = <&gpio 17 GPIO_ACTIVE_HIGH>;
cs-gpios = <&gpio 20 GPIO_ACTIVE_HIGH>;
cs-gpios = <&gpio 20 GPIO_ACTIVE_LOW>;
num-chipselects = <1>;
led_gpio: led_gpio@0 {

View File

@ -25,7 +25,7 @@
sck-gpios = <&gpio 15 GPIO_ACTIVE_HIGH>; // 74HC595 SRCLK (Serial Clock)
mosi-gpios = <&gpio 14 GPIO_ACTIVE_HIGH>; // 74HC595 SER (Serial)
cs-gpios = <&gpio 16 GPIO_ACTIVE_HIGH>; // 74HC595 RCLK (Register Clock)
cs-gpios = <&gpio 16 GPIO_ACTIVE_LOW>; // 74HC595 RCLK (Register Clock)
num-chipselects = <1>;
led_gpio: led_gpio@0 {

View File

@ -81,7 +81,6 @@
&spi {
status = "okay";
num-cs = <1>;
flash@0 {
compatible = "jedec,spi-nor";

View File

@ -81,7 +81,6 @@
&spi {
status = "okay";
num-cs = <1>;
flash@0 {
compatible = "jedec,spi-nor";

View File

@ -47,9 +47,6 @@ case "$FIRMWARE" in
avm,fritz300e)
caldata_extract_reverse "urloader" 0x1541 0x440
;;
buffalo,wzr-hp-g450h)
caldata_extract "art" 0x1000 0x440
;;
enterasys,ws-ap3705i)
caldata_extract "calibrate" 0x5000 0x440
ath9k_patch_mac $(mtd_get_mac_ascii u-boot-env0 RADIOADDR0)
@ -72,10 +69,6 @@ case "$FIRMWARE" in
;;
"ath9k-eeprom-pci-0000:00:11.0.bin")
case $board in
buffalo,wzr-600dhp|\
buffalo,wzr-hp-ag300h)
caldata_extract "art" 0x1000 0xeb8
;;
meraki,mr16)
caldata_extract "art" 0x11000 0xeb8
;;
@ -86,10 +79,6 @@ case "$FIRMWARE" in
;;
"ath9k-eeprom-pci-0000:00:12.0.bin")
case $board in
buffalo,wzr-600dhp|\
buffalo,wzr-hp-ag300h)
caldata_extract "art" 0x5000 0xeb8
;;
meraki,mr16)
caldata_extract "art" 0x15000 0xeb8
;;

View File

@ -206,8 +206,9 @@
#size-cells = <2>;
#address-cells = <3>;
device_type = "pci";
ranges;
ath9k: wifi@168c,002e {
ath9k: wifi@0,0 {
compatible = "pci168c,002e";
reg = <0 0 0 0 0>;

View File

@ -9,6 +9,7 @@ block_size=
code_openwrt=
code_factory=
code_offset=
read_mask=
read_nand() {
dd "if=$part" "of=$file" "bs=$block_size" "skip=$offset_blocks" count=1 2>/dev/null
@ -29,6 +30,24 @@ part_named() {
echo "/dev/$pn"
}
mask() {
if [ -z "$2" ]; then
echo "$1"
return
fi
echo "$1 $2" | awk '{
a=$1; b=$2;
res="";
for(i=1;i<=length(a);i++){
abit=substr(a,i,1);
bbit=substr(b,i,1);
if(bbit=="X") res=res""abit;
else res=res"0";
}
print res;
}'
}
to_hex() {
hexdump -v -e '1/1 "%02x"'
}
@ -38,16 +57,19 @@ from_hex() {
}
check() {
stored_code=$(dd \
local stored_code=$(dd \
"if=$part" \
bs=1 \
skip=$((offset_blocks * block_size + code_offset)) \
count=$((${#code_openwrt} / 2)) \
2>/dev/null | to_hex
)
if [ "$stored_code" = "$code_openwrt" ]; then
stored_code=$(mask "$stored_code" "$read_mask")
local code_owrt=$(mask "$code_openwrt" "$read_mask")
local code_fact=$(mask "$code_factory" "$read_mask")
if [ "$stored_code" = "$code_owrt" ]; then
echo "Current boot flag set to OS A (OpenWrt)"
elif [ "$stored_code" = "$code_factory" ]; then
elif [ "$stored_code" = "$code_fact" ]; then
echo "Current boot flag set to OS B (Factory)"
else
echo "Current boot flag unknown: $stored_code"
@ -86,6 +108,14 @@ main() {
code_offset=0
code_openwrt=0000000101000002
code_factory=0000000101010003
elif [ "$machine" = "Nokia G-240G-E" ]; then
part=$(part_named '"flag"')
offset_blocks=0
block_size=$((1024 * 128))
code_offset=0
code_openwrt=000000000000000000000001000000010000000000000000
code_factory=000000000000000100000001000000010000000000000000
read_mask=000000000000000X00000000000000000000000000000000
elif [ "$machine" = "SmartFiber XP8421-B" ]; then
# 0dfc0000
part=$(part_named '"reservearea"')

View File

@ -0,0 +1,52 @@
// SPDX-License-Identifier: GPL-2.0
/dts-v1/;
#include "en751221.dtsi"
/ {
model = "Generic EN751221";
compatible = "econet,en751221";
memory@0 {
// We hope at least 64MB will be available on every device
device_type = "memory";
reg = <0x00000000 0x4000000>;
};
chosen {
stdout-path = "/serial@1fbf0000:115200";
linux,usable-memory-range = <0x00020000 0x3fe0000>;
};
};
&nand {
status = "okay";
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
partition@1 {
// We don't know how big the flash is
// Put 1GB and let it truncate
label = "all_flash";
reg = <0x0 0x40000000>;
read-only;
};
partition@2 {
// We don't know how big the bootloader
// is, but when we're doing testing, lets
// make sure nobody touches anything below 4MB
label = "bootloader";
reg = <0x0 0x00400000>;
read-only;
};
partition@3 {
label = "rest_of_flash";
reg = <0x00400000 0x40000000>;
};
};
};

View File

@ -0,0 +1,123 @@
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/dts-v1/;
#include "en751221.dtsi"
/ {
model = "Nokia G-240G-E";
compatible = "nokia,g240g-e", "econet,en751221";
memory@0 {
device_type = "memory";
reg = <0x00000000 0x10000000>;
};
chosen {
stdout-path = "/serial@1fbf0000:115200";
linux,usable-memory-range = <0x00020000 0x0ffe0000>;
};
};
&nand {
status = "okay";
econet,bmt;
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "bootloader";
reg = <0x00000000 0x00040000>;
read-only;
};
partition@40000 {
// Unused
label = "romfile";
reg = <0x00040000 0x00040000>;
};
partition@80000 {
// trx - OpenWRT kernel is 4MB, factory is 3MB
label = "kernel";
reg = <0x00080000 0x00400000>;
};
partition@380000 {
// squashfs
label = "rootfs";
reg = <0x00480000 0x01F00000>;
linux,rootfs;
};
partition@2280000 {
// trx
label = "kernel_slave";
reg = <0x02280000 0x00300000>;
};
partition@2580000 {
// squashfs
label = "rootfs_slave";
reg = <0x02580000 0x01F00000>;
};
partition@4480000 {
// trx
label = "kernel_oflt";
reg = <0x04480000 0x00300000>;
};
partition@4780000 {
// squashfs
label = "rootfs_oflt";
reg = <0x04780000 0x00C00000>;
};
partition@5380000 {
// UBI
label = "config";
reg = <0x05380000 0x00800000>;
};
partition@5b80000 {
// UBI
label = "log";
reg = <0x05b80000 0x00C00000>;
};
partition@6780000 {
// UBI / unused
label = "extfs";
reg = <0x06780000 0x00600000>;
};
partition@6d80000 {
// binary
label = "bosa";
reg = <0x06d80000 0x00040000>;
};
partition@6dc0000 {
label = "flag";
reg = <0x06dc0000 0x00040000>;
};
partition@6e00000 {
label = "flagback";
reg = <0x06e00000 0x00040000>;
};
partition@6e40000 {
label = "ri";
reg = <0x06e40000 0x00040000>;
};
partition@6e80000 {
label = "riback";
reg = <0x06e80000 0x00040000>;
};
};
};

View File

@ -1,3 +1,22 @@
define Device/en751221_generic
DEVICE_VENDOR := EN751221 Family
DEVICE_MODEL := Initramfs Image
DEVICE_TITLE := EN751221 Initramfs Image
DEVICE_DESCRIPTION := In-memory build for testing and recovery of EN751221 SoCs
DEVICE_DTS := en751221_generic
endef
TARGET_DEVICES += en751221_generic
define Device/nokia_g240g-e
DEVICE_VENDOR := Nokia
DEVICE_MODEL := G-240G-E
DEVICE_DTS := en751221_nokia_g240g-e
IMAGES := tclinux.trx
IMAGE/tclinux.trx := append-kernel | lzma | tclinux-trx
DEVICE_PACKAGES := kmod-usb3
endef
TARGET_DEVICES += nokia_g240g-e
define Device/smartfiber_xp8421-b
DEVICE_VENDOR := SmartFiber
DEVICE_MODEL := XP8421-B

View File

@ -6499,6 +6499,7 @@ CONFIG_SQUASHFS=y
# CONFIG_SQUASHFS_COMPILE_DECOMP_MULTI is not set
CONFIG_SQUASHFS_COMPILE_DECOMP_MULTI_PERCPU=y
# CONFIG_SQUASHFS_COMPILE_DECOMP_SINGLE is not set
CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
CONFIG_SQUASHFS_EMBEDDED=y
# CONFIG_SQUASHFS_FILE_CACHE is not set
CONFIG_SQUASHFS_FILE_DIRECT=y

View File

@ -6330,6 +6330,7 @@ CONFIG_SQUASHFS=y
# CONFIG_SQUASHFS_COMPILE_DECOMP_MULTI is not set
CONFIG_SQUASHFS_COMPILE_DECOMP_MULTI_PERCPU=y
# CONFIG_SQUASHFS_COMPILE_DECOMP_SINGLE is not set
CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
CONFIG_SQUASHFS_EMBEDDED=y
# CONFIG_SQUASHFS_FILE_CACHE is not set
CONFIG_SQUASHFS_FILE_DIRECT=y

View File

@ -16,16 +16,18 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/net/core/page_pool.c
+++ b/net/core/page_pool.c
@@ -1124,7 +1124,7 @@ static void page_pool_release_retry(stru
@@ -1123,8 +1123,9 @@ static void page_pool_release_retry(stru
{
struct delayed_work *dwq = to_delayed_work(wq);
struct page_pool *pool = container_of(dwq, typeof(*pool), release_dw);
+ unsigned long flags;
void *netdev;
- int inflight;
+ int cpu, inflight;
inflight = page_pool_release(pool);
/* In rare cases, a driver bug may cause inflight to go negative.
@@ -1136,6 +1136,17 @@ static void page_pool_release_retry(stru
@@ -1136,6 +1137,21 @@ static void page_pool_release_retry(stru
if (inflight <= 0)
return;
@ -33,12 +35,16 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ * defer_list that can stay in the list until we have enough queued
+ * traffic.
+ */
+ local_irq_save(flags);
+ for_each_online_cpu(cpu) {
+ struct softnet_data *sd = &per_cpu(softnet_data, cpu);
+
+ if (!cmpxchg(&sd->defer_ipi_scheduled, 0, 1))
+ if (cpu == raw_smp_processor_id())
+ raise_softirq_irqoff(NET_RX_SOFTIRQ);
+ else if (!cmpxchg(&sd->defer_ipi_scheduled, 0, 1))
+ smp_call_function_single_async(cpu, &sd->defer_csd);
+ }
+ local_irq_restore(flags);
+
/* Periodic warning for page pools the user can't see */
netdev = READ_ONCE(pool->slow.netdev);

View File

@ -37,7 +37,7 @@ Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
.glo_cfg = 0x4604,
.rst_idx = 0x4608,
.delay_irq = 0x460c,
@@ -4050,6 +4053,56 @@ static void mtk_set_mcr_max_rx(struct mt
@@ -4053,6 +4056,56 @@ static void mtk_set_mcr_max_rx(struct mt
mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id));
}
@ -94,7 +94,7 @@ Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
static void mtk_hw_reset(struct mtk_eth *eth)
{
u32 val;
@@ -4529,6 +4582,8 @@ static void mtk_pending_work(struct work
@@ -4532,6 +4585,8 @@ static void mtk_pending_work(struct work
rtnl_lock();
set_bit(MTK_RESETTING, &eth->state);

View File

@ -178,7 +178,8 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ .vlan_tci = skb_vlan_tag_get(skb),
+ .first = true,
+ };
+
- mtk_tx_set_dma_desc(dev, itxd, &txd_info);
+ offset = 0;
+ frag_size = skb_headlen(cur_skb);
+ if (cur_skb != skb) {
@ -204,13 +205,6 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ struct ipv6hdr *iph = ipv6_hdr(cur_skb);
+ struct ipv6hdr *iph2 = ipv6_hdr(skb);
- mtk_tx_set_dma_desc(dev, itxd, &txd_info);
+ mtk_tx_update_ip6addr(skb, iph, th, &iph->saddr,
+ &iph2->saddr);
+ mtk_tx_update_ip6addr(skb, iph, th, &iph->daddr,
+ &iph2->daddr);
+ }
- itx_buf->mac_id = mac->id;
- setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size,
- k++);
@ -223,11 +217,23 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
- skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
- unsigned int offset = 0;
- int frag_size = skb_frag_size(frag);
+ mtk_tx_update_port(skb, th, &th->source, th2->source);
+ mtk_tx_update_port(skb, th, &th->dest, th2->dest);
+ mtk_tx_update_ip6addr(skb, iph, th, &iph->saddr,
+ &iph2->saddr);
+ mtk_tx_update_ip6addr(skb, iph, th, &iph->daddr,
+ &iph2->daddr);
+ }
- while (frag_size) {
- bool new_desc = true;
+ mtk_tx_update_port(skb, th, &th->source, th2->source);
+ mtk_tx_update_port(skb, th, &th->dest, th2->dest);
- if (MTK_HAS_CAPS(soc->caps, MTK_QDMA) ||
- (i & 0x1)) {
- txd = mtk_qdma_phys_to_virt(ring, txd->txd2);
- txd_pdma = qdma_to_pdma(ring, txd);
- if (txd == ring->last_free)
- goto err_dma;
+ offset = -header_len;
+ frag_size += header_len;
+ } else if (next_skb) {
@ -236,22 +242,16 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ struct iphdr *iph = ip_hdr(cur_skb);
+ __be16 ip_len_val = cpu_to_be16(ip_len);
- if (MTK_HAS_CAPS(soc->caps, MTK_QDMA) ||
- (i & 0x1)) {
- txd = mtk_qdma_phys_to_virt(ring, txd->txd2);
- txd_pdma = qdma_to_pdma(ring, txd);
- if (txd == ring->last_free)
- goto err_dma;
- n_desc++;
- } else {
- new_desc = false;
- }
+ csum_replace2(&iph->check, iph->tot_len, ip_len_val);
+ iph->tot_len = ip_len_val;
+ } else {
+ struct ipv6hdr *iph = ipv6_hdr(cur_skb);
+ __be16 ip_len_val = cpu_to_be16(ip_len - sizeof(*iph));
- n_desc++;
- } else {
- new_desc = false;
- }
+
+ iph->payload_len = ip_len_val;
+ }
+ }
@ -329,14 +329,14 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ } else {
+ state.txd_pdma->txd2 |= TX_DMA_LS1;
+ }
}
+ }
+
+ if (next_skb) {
+ cur_skb = next_skb;
+ next_skb = cur_skb->next;
+ goto next;
+ }
+
}
+ /* store skb to cleanup */
+ state.tx_buf->type = MTK_TYPE_SKB;
+ state.tx_buf->data = skb;
@ -400,7 +400,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
return nfrags;
}
@@ -1609,9 +1742,26 @@ static bool mtk_skb_has_small_frag(struc
@@ -1609,9 +1742,29 @@ static bool mtk_skb_has_small_frag(struc
if (skb_frag_size(&skb_shinfo(skb)->frags[i]) < min_size)
return true;
@ -420,6 +420,9 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ if (!(skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST))
+ return true;
+
+ if (skb_tnl_header_len(skb))
+ return false;
+
+ return skb_pagelen(skb) - header_len == skb_shinfo(skb)->gso_size &&
+ skb_headlen(skb) > header_len;
+}
@ -427,7 +430,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
static netdev_tx_t mtk_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct mtk_mac *mac = netdev_priv(dev);
@@ -1619,6 +1769,7 @@ static netdev_tx_t mtk_start_xmit(struct
@@ -1619,6 +1772,7 @@ static netdev_tx_t mtk_start_xmit(struct
struct mtk_tx_ring *ring = &eth->tx_ring;
struct net_device_stats *stats = &dev->stats;
struct sk_buff *segs, *next;
@ -435,7 +438,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
bool gso = false;
int tx_num;
@@ -1647,37 +1798,42 @@ static netdev_tx_t mtk_start_xmit(struct
@@ -1647,37 +1801,42 @@ static netdev_tx_t mtk_start_xmit(struct
return NETDEV_TX_BUSY;
}

View File

@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -2302,7 +2302,7 @@ static int mtk_poll_rx(struct napi_struc
@@ -2305,7 +2305,7 @@ static int mtk_poll_rx(struct napi_struc
if (ret != XDP_PASS)
goto skip_rx;
@ -19,7 +19,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (unlikely(!skb)) {
page_pool_put_full_page(ring->page_pool,
page, true);
@@ -2340,7 +2340,7 @@ static int mtk_poll_rx(struct napi_struc
@@ -2343,7 +2343,7 @@ static int mtk_poll_rx(struct napi_struc
dma_unmap_single(eth->dma_dev, ((u64)trxd.rxd1 | addr64),
ring->buf_size, DMA_FROM_DEVICE);

View File

@ -25,7 +25,7 @@ Signed-off-by: Chad Monroe <chad@monroe.io>
/* QDMA Flow Control Register */
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -3473,12 +3473,14 @@ static int mtk_start_dma(struct mtk_eth
@@ -3476,12 +3476,14 @@ static int mtk_start_dma(struct mtk_eth
MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO |
MTK_RX_2B_OFFSET | MTK_TX_WB_DDONE;

View File

@ -477,7 +477,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
.mac_finish = mtk_mac_finish,
.mac_link_down = mtk_mac_link_down,
.mac_link_up = mtk_mac_link_up,
@@ -3581,6 +3726,9 @@ static int mtk_open(struct net_device *d
@@ -3584,6 +3729,9 @@ static int mtk_open(struct net_device *d
ppe_num = eth->soc->ppe_num;
@ -487,7 +487,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0);
if (err) {
netdev_err(dev, "%s: could not attach PHY: %d\n", __func__,
@@ -3728,6 +3876,9 @@ static int mtk_stop(struct net_device *d
@@ -3731,6 +3879,9 @@ static int mtk_stop(struct net_device *d
for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
mtk_ppe_stop(eth->ppe[i]);
@ -497,7 +497,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
return 0;
}
@@ -4818,6 +4969,7 @@ static const struct net_device_ops mtk_n
@@ -4821,6 +4972,7 @@ static const struct net_device_ops mtk_n
static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
{
const __be32 *_id = of_get_property(np, "reg", NULL);
@ -505,7 +505,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
phy_interface_t phy_mode;
struct phylink *phylink;
struct mtk_mac *mac;
@@ -4856,16 +5008,41 @@ static int mtk_add_mac(struct mtk_eth *e
@@ -4859,16 +5011,41 @@ static int mtk_add_mac(struct mtk_eth *e
mac->id = id;
mac->hw = eth;
mac->of_node = np;
@ -555,7 +555,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
}
memset(mac->hwlro_ip, 0, sizeof(mac->hwlro_ip));
@@ -4948,8 +5125,21 @@ static int mtk_add_mac(struct mtk_eth *e
@@ -4951,8 +5128,21 @@ static int mtk_add_mac(struct mtk_eth *e
phy_interface_zero(mac->phylink_config.supported_interfaces);
__set_bit(PHY_INTERFACE_MODE_INTERNAL,
mac->phylink_config.supported_interfaces);
@ -577,7 +577,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
phylink = phylink_create(&mac->phylink_config,
of_fwnode_handle(mac->of_node),
phy_mode, &mtk_phylink_ops);
@@ -5000,6 +5190,26 @@ free_netdev:
@@ -5003,6 +5193,26 @@ free_netdev:
return err;
}
@ -604,7 +604,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev)
{
struct net_device *dev, *tmp;
@@ -5146,7 +5356,8 @@ static int mtk_probe(struct platform_dev
@@ -5149,7 +5359,8 @@ static int mtk_probe(struct platform_dev
regmap_write(cci, 0, 3);
}
@ -614,7 +614,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
err = mtk_sgmii_init(eth);
if (err)
@@ -5257,6 +5468,24 @@ static int mtk_probe(struct platform_dev
@@ -5260,6 +5471,24 @@ static int mtk_probe(struct platform_dev
}
}
@ -639,7 +639,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT)) {
err = devm_request_irq(eth->dev, eth->irq[0],
mtk_handle_irq, 0,
@@ -5367,6 +5596,11 @@ static void mtk_remove(struct platform_d
@@ -5370,6 +5599,11 @@ static void mtk_remove(struct platform_d
mtk_stop(eth->netdev[i]);
mac = netdev_priv(eth->netdev[i]);
phylink_disconnect_phy(mac->phylink);

View File

@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -5634,7 +5634,7 @@ static const struct mtk_soc_data mt2701_
@@ -5637,7 +5637,7 @@ static const struct mtk_soc_data mt2701_
DESC_SIZE(struct mtk_rx_dma),
.irq_done_mask = MTK_RX_DONE_INT,
.dma_l4_valid = RX_DMA_L4_VALID,
@ -39,7 +39,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16,
},
@@ -5662,7 +5662,7 @@ static const struct mtk_soc_data mt7621_
@@ -5665,7 +5665,7 @@ static const struct mtk_soc_data mt7621_
DESC_SIZE(struct mtk_rx_dma),
.irq_done_mask = MTK_RX_DONE_INT,
.dma_l4_valid = RX_DMA_L4_VALID,
@ -48,7 +48,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16,
},
@@ -5692,7 +5692,7 @@ static const struct mtk_soc_data mt7622_
@@ -5695,7 +5695,7 @@ static const struct mtk_soc_data mt7622_
DESC_SIZE(struct mtk_rx_dma),
.irq_done_mask = MTK_RX_DONE_INT,
.dma_l4_valid = RX_DMA_L4_VALID,
@ -57,7 +57,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16,
},
@@ -5721,7 +5721,7 @@ static const struct mtk_soc_data mt7623_
@@ -5724,7 +5724,7 @@ static const struct mtk_soc_data mt7623_
DESC_SIZE(struct mtk_rx_dma),
.irq_done_mask = MTK_RX_DONE_INT,
.dma_l4_valid = RX_DMA_L4_VALID,
@ -66,7 +66,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16,
},
@@ -5747,7 +5747,7 @@ static const struct mtk_soc_data mt7629_
@@ -5750,7 +5750,7 @@ static const struct mtk_soc_data mt7629_
DESC_SIZE(struct mtk_rx_dma),
.irq_done_mask = MTK_RX_DONE_INT,
.dma_l4_valid = RX_DMA_L4_VALID,
@ -75,7 +75,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16,
},
@@ -5779,7 +5779,7 @@ static const struct mtk_soc_data mt7981_
@@ -5782,7 +5782,7 @@ static const struct mtk_soc_data mt7981_
.dma_l4_valid = RX_DMA_L4_VALID_V2,
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16,
@ -84,7 +84,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
},
};
@@ -5809,7 +5809,7 @@ static const struct mtk_soc_data mt7986_
@@ -5812,7 +5812,7 @@ static const struct mtk_soc_data mt7986_
.dma_l4_valid = RX_DMA_L4_VALID_V2,
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16,
@ -93,7 +93,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
},
};
@@ -5862,7 +5862,7 @@ static const struct mtk_soc_data rt5350_
@@ -5865,7 +5865,7 @@ static const struct mtk_soc_data rt5350_
.dma_l4_valid = RX_DMA_L4_VALID_PDMA,
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16,

View File

@ -25,7 +25,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
help
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -4737,6 +4737,7 @@ static int mtk_get_sset_count(struct net
@@ -4740,6 +4740,7 @@ static int mtk_get_sset_count(struct net
static void mtk_ethtool_pp_stats(struct mtk_eth *eth, u64 *data)
{
@ -33,7 +33,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
struct page_pool_stats stats = {};
int i;
@@ -4749,6 +4750,7 @@ static void mtk_ethtool_pp_stats(struct
@@ -4752,6 +4753,7 @@ static void mtk_ethtool_pp_stats(struct
page_pool_get_stats(ring->page_pool, &stats);
}
page_pool_ethtool_stats_get(data, &stats);

View File

@ -139,7 +139,7 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
status = "okay";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>;
flash@0 {
#address-cells = <1>;

View File

@ -124,8 +124,8 @@
pinctrl-0 = <&spi0_pins>;
pinctrl-names = "default";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>,
<&tlmm 4 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>,
<&tlmm 4 GPIO_ACTIVE_LOW>;
flash@0 {
compatible = "jedec,spi-nor";

View File

@ -155,7 +155,7 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>;
flash@0 {
reg = <0>;

View File

@ -138,7 +138,7 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
status = "okay";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>;
flash@0 {
compatible = "jedec,spi-nor";

View File

@ -82,7 +82,7 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
status = "okay";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>;
flash@0 {
compatible = "jedec,spi-nor";

View File

@ -175,8 +175,8 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
status = "okay";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>,
<&tlmm 59 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>,
<&tlmm 59 GPIO_ACTIVE_LOW>;
flash@0 {
compatible = "jedec,spi-nor";

View File

@ -127,7 +127,7 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
status = "okay";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>;
m25p80@0 {
compatible = "jedec,spi-nor";

View File

@ -158,7 +158,7 @@
pinctrl-0 = <&spi0_pins>;
pinctrl-names = "default";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>, <&tlmm 4 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>, <&tlmm 4 GPIO_ACTIVE_LOW>;
flash@0 {
compatible = "jedec,spi-nor";

View File

@ -122,7 +122,7 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
status = "okay";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>;
flash@0 {
compatible = "jedec,spi-nor";

View File

@ -119,7 +119,7 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
status = "okay";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>;
m25p80@0 {
compatible = "jedec,spi-nor";

View File

@ -143,7 +143,7 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
status = "okay";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>;
flash@0 {
#address-cells = <1>;

View File

@ -185,7 +185,7 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
status = "okay";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>;
mx25l12805d@0 {
compatible = "jedec,spi-nor";

View File

@ -154,7 +154,7 @@
status = "okay";
/delete-property/ dmas;
/delete-property/ dma-names;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>;
flash@0 {
compatible = "jedec,spi-nor";

View File

@ -125,7 +125,7 @@
pinctrl-0 = <&spi0_pins>;
pinctrl-names = "default";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>, <&tlmm 5 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>, <&tlmm 5 GPIO_ACTIVE_LOW>;
flash@0 {
compatible = "jedec,spi-nor";

View File

@ -109,7 +109,7 @@
pinctrl-0 = <&spi0_pins>;
pinctrl-names = "default";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>, <&tlmm 5 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>, <&tlmm 5 GPIO_ACTIVE_LOW>;
flash@0 {
status = "okay";

View File

@ -150,7 +150,7 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>;
flash@0 {
reg = <0>;

View File

@ -112,7 +112,7 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>, <&tlmm 59 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>, <&tlmm 59 GPIO_ACTIVE_LOW>;
flash@0 {
status = "okay";

View File

@ -169,7 +169,7 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
status = "okay";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>;
flash@0 {
compatible = "jedec,spi-nor";

View File

@ -30,9 +30,9 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
status = "okay";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>,
<&tlmm 59 GPIO_ACTIVE_HIGH>,
<&tlmm 1 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>,
<&tlmm 59 GPIO_ACTIVE_LOW>,
<&tlmm 1 GPIO_ACTIVE_LOW>;
flash@0 {
compatible = "jedec,spi-nor";

View File

@ -30,9 +30,9 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
status = "okay";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>,
<&tlmm 59 GPIO_ACTIVE_HIGH>,
<&tlmm 1 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>,
<&tlmm 59 GPIO_ACTIVE_LOW>,
<&tlmm 1 GPIO_ACTIVE_LOW>;
flash@0 {
compatible = "jedec,spi-nor";

View File

@ -48,8 +48,8 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
status = "okay";
cs-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>,
<&tlmm 54 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>,
<&tlmm 54 GPIO_ACTIVE_LOW>;
flash@0 {
compatible = "jedec,spi-nor";

View File

@ -165,7 +165,7 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
status = "okay";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>;
flash@0 {
compatible = "jedec,spi-nor";

View File

@ -131,7 +131,7 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
status = "okay";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>;
flash@0 {
#address-cells = <1>;

View File

@ -170,8 +170,8 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
status = "okay";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>,
<&tlmm 59 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>,
<&tlmm 59 GPIO_ACTIVE_LOW>;
flash@0 {
/*

View File

@ -141,7 +141,7 @@
&blsp1_spi1 {
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>, <&tlmm 63 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>, <&tlmm 63 GPIO_ACTIVE_LOW>;
num-cs = <2>;
status = "okay";

View File

@ -119,7 +119,7 @@
gpio-sck = <&tlmm 1 GPIO_ACTIVE_HIGH>;
gpio-mosi = <&tlmm 3 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 2 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>;
num-chipselects = <1>;
shift_io: shift_io@0 {

View File

@ -154,7 +154,7 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>;
flash@0 {
reg = <0>;

View File

@ -201,8 +201,8 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>,
<&tlmm 59 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>,
<&tlmm 59 GPIO_ACTIVE_LOW>;
flash@0 {
compatible = "jedec,spi-nor";

View File

@ -118,7 +118,7 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>;
flash@0 {
reg = <0>;

View File

@ -83,7 +83,7 @@
status = "okay";
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>, <&tlmm 4 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>, <&tlmm 4 GPIO_ACTIVE_LOW>;
nor@0 {
reg = <0>;

View File

@ -92,7 +92,7 @@
&blsp1_spi1 {
status = "okay";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>;
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";

View File

@ -149,7 +149,7 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
status = "okay";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>;
mx25l12805d@0 {
compatible = "jedec,spi-nor";

View File

@ -92,8 +92,8 @@
&blsp1_spi1 {
status = "okay";
cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>,
<&tlmm 59 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>,
<&tlmm 59 GPIO_ACTIVE_LOW>;
pinctrl-0 = <&spi0_pins>;
pinctrl-names = "default";

View File

@ -146,7 +146,7 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
status = "okay";
cs-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>;
flash@0 {
#address-cells = <1>;

View File

@ -90,7 +90,7 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
status = "okay";
cs-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>;
flash@0 {
#address-cells = <1>;

View File

@ -128,7 +128,7 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
status = "okay";
cs-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>;
flash@0 {
compatible = "jedec,spi-nor";

View File

@ -210,7 +210,7 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
cs-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>;
flash@0 {
compatible = "jedec,spi-nor";

View File

@ -184,7 +184,7 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
cs-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>;
flash@0 {
reg = <0>;

View File

@ -221,7 +221,7 @@
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
cs-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>;
cs-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>;
flash@0 {
reg = <0>;

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