Compare commits

..

21 Commits

Author SHA1 Message Date
jaspreetsachdev
a00dbfa6e4 Merge pull request #985 from Telecominfraproject/main
merge for 4.2.0 RC2
2025-12-12 18:42:38 -05:00
John Crispin
815006f3e7 ucentral: set version to 4.2.0
Signed-off-by: John Crispin <john@phrozen.org>
2025-12-12 16:02:07 +01:00
John Crispin
a7a9458d81 profiles/sonicfi_rap63xc-211g: add missing hostap feed
Signed-off-by: John Crispin <john@phrozen.org>
2025-12-12 16:02:07 +01:00
ruanyaoyu
e366742c1b ipq807x: enable CPTCFG_ATH12K_DEBUG for CIG devices
Signed-off-by: ruanyaoyu <ruanyaoyu@cigtech.com>
2025-12-12 14:12:06 +01:00
Sebastian Huang
ee601508d9 qca-wifi-7/hostapd: keep BSS coloring enabled with the same color if there is no free colors
Fixes: WIFI-15279

Signed-off-by: Sebastian Huang <sebastian_huang@accton.com>
2025-12-12 14:11:37 +01:00
Tanya Singh
5c5eb7891c rrmd: Add DFS channel exclusion support to the RCS (Random Channel Selection) algo when DFS is disabled
Fixes: WIFI-15270
Signed-off-by: Tanya Singh <tanya_singh@accton.com>
2025-12-12 14:11:23 +01:00
Venkat Chimata
501c11be52 bandwidth: Correct handling of RADIUS-assigned bandwidth limits
Description:
Hostapd successfully parsed the uplink and downlink bandwidth attributes from
the RADIUS server, but the values were not being propagated correctly into
sta_info. As a result, the bandwidth information was missing in the UBUS
events sent to ucentral-event.

Fix:
Ensure the parsed bandwidth values are correctly passed to sta_info so they
 are included in subsequent UBUS notifications.

Tests Performed:
Configured per-client bandwidth limits on the RADIUS server and verified that:

 - The AP enforces the configured uplink/downlink limits, and
 - The correct bandwidth values appear in the UBUS events.

Signed-off-by: Venkat Chimata <venkat@nearhop.com>
2025-12-11 16:04:46 +01:00
Venkat Chimata
352e94a133 ratelimit: generate shorter IFB names for phy-based interfaces
Interfaces like phy6g-ap0 can produce overly long IFB device names
(e.g., i-phy6g-ap0), which may exceed kernel name-length limits,
specifically in case of VLANs.
This patch normalizes such interface names by replacing the phy
prefix with p and shortening ap → a, producing more compact
IFB device names (e.g., i-p2g-a0).

Other interfaces continue using their original names.

Signed-off-by: Venkat Chimata <venkat@nearhop.com>
2025-12-11 16:04:46 +01:00
John Crispin
20f5fa0284 profiles/edgecore_eap111.yml: use the sdk kernel for v4.2
Signed-off-by: John Crispin <john@phrozen.org>
2025-12-11 08:06:49 +01:00
John Crispin
aa1d2b1c73 feeds/morse: update mirror hashes
Signed-off-by: John Crispin <john@phrozen.org>
2025-12-11 06:24:44 +01:00
John Crispin
09a7f53fb4 ucentral-schema: update to latest HEAD
a6fdd32 cmd_upgrade: enable curl to follow redirects
1c3e51f fix: Updated schema to fix issue with fingerprinting raw mode

Signed-off-by: John Crispin <john@phrozen.org>
2025-12-11 06:24:44 +01:00
Yang-Yongzhi
7665eefe1d qca-wifi-7: Add Asterfusion AP7330 model (WIFI-15267)
Enable the CONFIG_GPIO_WATCHDOG of kernel config
Add the 'wdt' watchdog service in /etc/init.d/

Signed-off-by: Yang-Yongzhi <yangyongzhi@asterfusion.com>
2025-12-11 06:24:44 +01:00
ruanyaoyu
099726eff6 ipq60xx: Fix issue where ipq60xx chip would not compile ftm
Fixes: WIFI-15271
Signed-off-by: ruanyaoyu <ruanyaoyu@cigtech.com>
2025-12-11 06:18:58 +01:00
John Crispin
7d641524e1 ucentral-schema: fix vxlan.json
the upstream section had no DNS

Fixes: WIFI-15256
Signed-off-by: John Crispin <john@phrozen.org>
2025-12-05 11:14:07 +01:00
John Crispin
bf3781e793 ucentral-schema: update to latest HEAD
384eba5 radio: apply HE settings for EHT modes

Signed-off-by: John Crispin <john@phrozen.org>
2025-12-05 10:55:25 +01:00
Venkat Chimata
415a512450 ath11k: Synchronize num_peers with the actual peer count when out of sync
Description:
The num_peers counter does not always update at the exact moment a peer is deleted.
Since deletion and decrement are not fully atomic, there are scenarios where
num_peers can drift out of sync with the actual number of peers.

Fix:
A complete rewrite of the num_peers update logic—ensuring fully correct
increment/decrement handling during peer insertion and deletion—would require
significant effort and QA validation. As an immediate and effective solution,
this patch synchronizes num_peers with the actual peer count whenever a mismatch
is detected.

Fixes WIFI-14998 and indirectly resolves WIFI-15202.

Signed-off-by: Venkat Chimata <venkat@nearhop.com>
2025-12-05 07:28:59 +01:00
Venkat Chimata
194109d317 ath11k: Fix memory leak in ath11k_qmi_driver_event_work
The buffer pointed to by event is not freed in case
ATH11K_FLAG_UNREGISTERING bit is set, resulting in
memory leak, so fix it.

Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1

Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
Signed-off-by: Baochen Qiang <bqiang@codeaurora.org>
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20210913180246.193388-4-jouni@codeaurora.org

Signed-off-by: Venkat Chimata <venkat@nearhop.com>
2025-12-05 07:28:59 +01:00
Venkat Chimata
d64e3c8d14 wifi: ath11k: Fix memory leak in ath11k_peer_rx_frag_setup
crypto_alloc_shash() allocates resources, which should be released by
crypto_free_shash(). When ath11k_peer_find() fails, there has memory
leak. Add missing crypto_free_shash() to fix this.

Fixes: 243874c64c81 ("ath11k: handle RX fragments")
Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://lore.kernel.org/r/20230102081142.3937570-1-linmq006@gmail.com

Signed-off-by: Venkat Chimata <venkat@nearhop.com>
2025-12-05 07:28:59 +01:00
Oleksandr Mazur
a81fe1274b ath11k: fix memory leak when peer lookup fails in dp rx path
In the DP RX path, fast_rx is set to true by default.
Currently, if peer lookup fails in ath11k_dp_rx_h_mpdu(), the SKB is not sent
to the network stack or mac80211 because fast_rx remains true. This results
in a memory leak.

Fix this by setting fast_rx = false when peer lookup fails in
ath11k_dp_rx_h_mpdu(), ensuring the SKB is properly delivered to mac80211
via ath11k_dp_rx_deliver_msdu().

Fixes: WIFI-15202

Signed-off-by: Marek Kwaczynski <marek@shasta.cloud>
2025-12-05 07:28:59 +01:00
John Crispin
05b5bae4aa ath11k: fix num_peers counter corruption and add debug logging
The num_peers counter becomes corrupted during peer deletion due to race
conditions between ath11k_peer_delete() and ath11k_peer_unmap_event().
The firmware may or may not send unmap events, and the timing varies,
causing the counter to either leak (increment without decrement) or
underflow (double decrement).

Root causes:
1. ath11k_peer_delete() doesn't decrement num_peers, relying on
   ath11k_peer_unmap_event() to do it
2. Firmware sometimes doesn't send unmap events, leaving num_peers
   inflated
3. When unmap events do arrive, timing races with ath11k_peer_delete()
   can cause missed decrements
4. Cleanup paths may double-decrement if delete_in_progress not checked
5. num_peers modified outside proper locking in some paths

This fix:
- Moves num_peers decrement into ath11k_peer_delete() after successful
  peer deletion wait, ensuring exactly one decrement per deletion
- Handles both cases: peer removed by unmap event, or peer still in list
- Removes num_peers decrement from ath11k_peer_unmap_event() to prevent
  double-decrement when unmap event arrives
- Adds ath11k_dp_peer_cleanup() call before ath11k_peer_delete() in
  roaming path to ensure datapath structures properly cleaned up
- Adds delete_in_progress checks in cleanup paths to prevent
  double-delete
- Ensures all num_peers modifications happen under base_lock
- Adds comprehensive debug logging to track num_peers throughout peer
  lifecycle

Signed-off-by: Arif Alam <arif.alam@netexperience.com>
Signed-off-by: John Crispin <john@phrozen.org>
2025-12-05 07:28:59 +01:00
Venkat Chimata
fbca032f4c WIFI-14998: wifi: ap: mitigate peer-delete WMI timeout to reduce blind period & prevent peer leaks
1. When a connected client roams to another AP, the AP is trying to delete the peer
   but for some reason the WMI command times out and while driver is waiting for
   the response, we observed that the AP doesn't respond to any frames from STA
   (probe requests, authentication etc) and once the response times out (3seconds default)
   then AP starts responding to the older requets but client has already connected to
   another AP. As the root cause for the response timing out is in the FW, we added
   a WAR to reduce the timeout to minimize this blind period, with this AP responds
   after 100ms and client connects successfully. And 100ms timeout is also reasonable
   for this internal operation.
2. In case of peer deletion timeout, the driver peer database is not cleared, so,
   if this happens often (which it is) then eventually we hit the max peers in the
   driver and all subsequent operations fail, so, in case of timeout ignore the failure
   and proceed with driver peer database cleanup.

Signed-off-by: Venkat Chimata <venkat@nearhop.com>
2025-12-05 07:28:59 +01:00
39 changed files with 1490 additions and 22 deletions

View File

@@ -21,7 +21,7 @@ jobs:
strategy:
fail-fast: false
matrix:
target: [ 'cig_wf189h', 'cig_wf189w', 'cig_wf660a', 'cig_wf672', 'cig_wf186h', 'cig_wf186w', 'cig_wf188n', 'cig_wf189', 'cig_wf196', 'cig_wf196', 'cybertan_eww631-a1', 'cybertan_eww631-b1', 'sonicfi_rap630w-312g', 'sonicfi_rap63xc-211g', 'sonicfi_rap630c-311g', 'sonicfi_rap630w-311g', 'sonicfi_rap630w-211g', 'sonicfi_rap650c', 'sonicfi_rap7110c-341x', 'sonicfi_rap750e-h', 'sonicfi_rap750e-s', 'sonicfi_rap750w-311a', 'edgecore_eap101', 'edgecore_eap102', 'edgecore_eap104', 'edgecore_eap105', 'edgecore_eap111', 'edgecore_eap112', 'edgecore_oap101', 'edgecore_oap101-6e', 'edgecore_oap101e', 'edgecore_oap101e-6e', 'edgecore_oap103', 'hfcl_ion4xe', 'hfcl_ion4xi', 'hfcl_ion4x', 'hfcl_ion4x_2', 'hfcl_ion4x_3', 'hfcl_ion4xi_w', 'hfcl_ion4x_w', 'indio_um-305ax', 'senao_iap4300m', 'senao_iap2300m', 'senao_jeap6500', 'udaya_a6-id2', 'udaya_a6-od2', 'yuncore_ax820', 'yuncore_ax840', 'yuncore_fap640', 'yuncore_fap650', 'yuncore_fap655', 'emplus_wap588m', 'zyxel_nwa130be', 'sercomm_ap72tip-v4' ]
target: [ 'cig_wf189h', 'cig_wf189w', 'cig_wf660a', 'cig_wf672', 'cig_wf186h', 'cig_wf186w', 'cig_wf188n', 'cig_wf189', 'cig_wf196', 'cig_wf196', 'cybertan_eww631-a1', 'cybertan_eww631-b1', 'sonicfi_rap630w-312g', 'sonicfi_rap63xc-211g', 'sonicfi_rap630c-311g', 'sonicfi_rap630w-311g', 'sonicfi_rap630w-211g', 'sonicfi_rap650c', 'sonicfi_rap7110c-341x', 'sonicfi_rap750e-h', 'sonicfi_rap750e-s', 'sonicfi_rap750w-311a', 'edgecore_eap101', 'edgecore_eap102', 'edgecore_eap104', 'edgecore_eap105', 'edgecore_eap111', 'edgecore_eap112', 'edgecore_oap101', 'edgecore_oap101-6e', 'edgecore_oap101e', 'edgecore_oap101e-6e', 'edgecore_oap103', 'hfcl_ion4xe', 'hfcl_ion4xi', 'hfcl_ion4x', 'hfcl_ion4x_2', 'hfcl_ion4x_3', 'hfcl_ion4xi_w', 'hfcl_ion4x_w', 'indio_um-305ax', 'senao_iap4300m', 'senao_iap2300m', 'senao_jeap6500', 'udaya_a6-id2', 'udaya_a6-od2', 'yuncore_ax820', 'yuncore_ax840', 'yuncore_fap640', 'yuncore_fap650', 'yuncore_fap655', 'emplus_wap588m', 'zyxel_nwa130be', 'sercomm_ap72tip-v4', 'asterfusion_ap7330']
steps:
- uses: actions/checkout@v3

View File

@@ -15,7 +15,7 @@ define Package/$(PKG_NAME)
URL:=http://www.qca.qualcomm.com
MAINTAINER:=Qualcomm Atheros
TITLE:= QCA ftm utils
DEPENDS:= @TARGET_ipq_ipq807x||TARGET_ipq_ipq807x_64||TARGET_ipq_ipq60xx||TARGET_ipq_ipq60xx_64||TARGET_ipq_ipq50xx||TARGET_ipq_ipq50xx_64||TARGET_ipq807x||TARGET_ipq50xx +libnl +libtcmd +qca-diag +librt +kmod-diag-char
DEPENDS:= @TARGET_ipq_ipq807x||TARGET_ipq_ipq807x_64||TARGET_ipq_ipq60xx||TARGET_ipq_ipq60xx_64||TARGET_ipq_ipq50xx||TARGET_ipq_ipq50xx_64||TARGET_ipq807x||TARGET_ipq60xx||TARGET_ipq50xx +libnl +libtcmd +qca-diag +librt +kmod-diag-char
endef
define Package/$(PKG_NAME)/description/Default

View File

@@ -0,0 +1,22 @@
Index: backports-20210222_001-5.4.164-b157d2276/drivers/net/wireless/ath/ath11k/dp_rx.c
===================================================================
--- backports-20210222_001-5.4.164-b157d2276.orig/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ backports-20210222_001-5.4.164-b157d2276/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -2847,8 +2847,6 @@ static void ath11k_dp_rx_h_mpdu(struct a
}
}
- *fast_rx = false;
-
if (rxcb->is_mcbc)
enctype = peer->sec_type_grp;
else
@@ -2858,6 +2856,8 @@ static void ath11k_dp_rx_h_mpdu(struct a
}
spin_unlock_bh(&ar->ab->base_lock);
+ *fast_rx = false;
+
rx_attention = ath11k_dp_rx_get_attention(ar->ab, rx_desc);
err_bitmap = ath11k_dp_rx_h_attn_mpdu_err(rx_attention);
if (enctype != HAL_ENCRYPT_TYPE_OPEN && !err_bitmap)

View File

@@ -0,0 +1,53 @@
From 375d0d25e6c02991392e44956c81cbac84909f49 Mon Sep 17 00:00:00 2001
From: Venkat Chimata <venkat@nearhop.com>
Date: Thu, 4 Sep 2025 00:09:17 +0530
Subject: [PATCH] wifi: ap: mitigate peer-delete WMI timeout to reduce blind
period & prevent peer leaks
1. When a connected client roams to another AP, the AP is trying to delete the peer
but for some reason the WMI command times out and while driver is waiting for
the response, we observed that the AP doesn't respond to any frames from STA
(probe requests, authentication etc) and once the response times out (3seconds default)
then AP starts responding to the older requets but client has already connected to
another AP. As the root cause for the response timing out is in the FW, we added
a WAR to reduce the timeout to minimize this blind period, with this AP responds
after 100ms and client connects successfully. And 100ms timeout is also reasonable
for this internal operation.
2. In case of peer deletion timeout, the driver peer database is not cleared, so,
if this happens often (which it is) then eventually we hit the max peers in the
driver and all subsequent operations fail, so, in case of timeout ignore the failure
and proceed with driver peer database cleanup.
Signed-off-by: Venkat Chimata <venkat@nearhop.com>
---
drivers/net/wireless/ath/ath11k/peer.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/peer.c b/drivers/net/wireless/ath/ath11k/peer.c
index 1907067..aefc6ba 100644
--- a/drivers/net/wireless/ath/ath11k/peer.c
+++ b/drivers/net/wireless/ath/ath11k/peer.c
@@ -771,7 +771,7 @@ int ath11k_wait_for_peer_delete_done(struct ath11k *ar, u32 vdev_id,
}
time_left = wait_for_completion_timeout(&ar->peer_delete_done,
- 3 * HZ);
+ 100 * HZ / 1000);
if (time_left == 0) {
ath11k_warn(ar->ab, "Timeout in receiving peer delete response\n");
return -ETIMEDOUT;
@@ -857,7 +857,10 @@ int ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, u8 *addr)
}
ret = ath11k_wait_for_peer_delete_done(ar, vdev_id, addr);
- if (ret)
+ /* WAR: For the timeout case, proceed to delete the peer anyway, as FW is
+ * still functional, without this, driver ends up hitting max peers
+ */
+ if (ret && ret != -ETIMEDOUT)
return ret;
ATH11K_MEMORY_STATS_DEC(ar->ab, per_peer_object,
--
2.34.1

View File

@@ -0,0 +1,193 @@
From: John Crispin <john@phrozen.org>
Date: Thu, 2 Oct 2025 09:00:00 +0000
Subject: [PATCH] ath11k: fix num_peers counter corruption and add debug
logging
The num_peers counter becomes corrupted during peer deletion due to race
conditions between ath11k_peer_delete() and ath11k_peer_unmap_event().
The firmware may or may not send unmap events, and the timing varies,
causing the counter to either leak (increment without decrement) or
underflow (double decrement).
Root causes:
1. ath11k_peer_delete() doesn't decrement num_peers, relying on
ath11k_peer_unmap_event() to do it
2. Firmware sometimes doesn't send unmap events, leaving num_peers
inflated
3. When unmap events do arrive, timing races with ath11k_peer_delete()
can cause missed decrements
4. Cleanup paths may double-decrement if delete_in_progress not checked
5. num_peers modified outside proper locking in some paths
This fix:
- Moves num_peers decrement into ath11k_peer_delete() after successful
peer deletion wait, ensuring exactly one decrement per deletion
- Handles both cases: peer removed by unmap event, or peer still in list
- Removes num_peers decrement from ath11k_peer_unmap_event() to prevent
double-decrement when unmap event arrives
- Adds ath11k_dp_peer_cleanup() call before ath11k_peer_delete() in
roaming path to ensure datapath structures properly cleaned up
- Adds delete_in_progress checks in cleanup paths to prevent
double-delete
- Ensures all num_peers modifications happen under base_lock
- Adds comprehensive debug logging to track num_peers throughout peer
lifecycle
Signed-off-by: Arif Alam <arif.alam@netexperience.com>
Signed-off-by: John Crispin <john@phrozen.org>
---
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -5742,14 +5742,22 @@ static int ath11k_mac_op_sta_state(struc
mutex_lock(&ar->ab->tbl_mtx_lock);
spin_lock_bh(&ar->ab->base_lock);
peer = ath11k_peer_find(ar->ab, arvif->vdev_id, sta->addr);
- if (peer && peer->sta == sta) {
+ /* Skip if peer deletion already in progress to prevent
+ * double-delete and num_peers underflow
+ */
+ if (peer && peer->sta == sta && !peer->delete_in_progress) {
ath11k_warn(ar->ab, "Found peer entry %pM n vdev %i after it was supposedly removed\n",
vif->addr, arvif->vdev_id);
ath11k_peer_rhash_delete(ar->ab, peer);
peer->sta = NULL;
+ /* num_peers decrement now happens under base_lock when
+ * peer is actually removed from list
+ */
list_del(&peer->list);
kfree(peer);
ar->num_peers--;
+ ath11k_dbg(ar->ab, ATH11K_DBG_PEER, "%s peer deleted %pM vdev_id: %d num_peers: %d\n",
+ __func__, sta->addr, arvif->vdev_id, ar->num_peers);
}
spin_unlock_bh(&ar->ab->base_lock);
mutex_unlock(&ar->ab->tbl_mtx_lock);
@@ -7847,6 +7855,8 @@ err_peer_del:
goto err_keyid;
ar->num_peers--;
+ ath11k_dbg(ar->ab, ATH11K_DBG_PEER, "%s vif peer deleted %pM vdev_id: %d num_peers: %d\n",
+ __func__, vif->addr, arvif->vdev_id, ar->num_peers);
}
err_vdev_del:
--- a/drivers/net/wireless/ath/ath11k/peer.c
+++ b/drivers/net/wireless/ath/ath11k/peer.c
@@ -461,6 +461,9 @@ void ath11k_peer_unmap_event(struct ath1
ath11k_dbg(ab, ATH11K_DBG_PEER, "peer unmap vdev %d peer %pM id %d\n",
peer->vdev_id, peer->addr, peer_id);
+ /* Don't decrement num_peers here - it's already decremented in
+ * ath11k_peer_delete() after successful wait. Just clean up the peer.
+ */
list_del(&peer->list);
kfree(peer);
wake_up(&ab->peer_mapping_wq);
@@ -726,6 +729,10 @@ void ath11k_peer_cleanup(struct ath11k *
if (peer->vdev_id != vdev_id)
continue;
+ /* Skip peers that are being deleted to prevent double-free */
+ if (peer->delete_in_progress)
+ continue;
+
ath11k_warn(ab, "removing stale peer %pM from vdev_id %d\n",
peer->addr, vdev_id);
@@ -743,7 +750,10 @@ void ath11k_peer_cleanup(struct ath11k *
ath11k_peer_rhash_delete(ab, peer);
list_del(&peer->list);
kfree(peer);
+ /* num_peers decrement happens here under base_lock */
ar->num_peers--;
+ ath11k_dbg(ar->ab, ATH11K_DBG_PEER, "%s peer cleanup %pM vdev_id: %d num_peers: %d\n",
+ __func__, peer->addr, vdev_id, ar->num_peers);
}
spin_unlock_bh(&ab->base_lock);
@@ -824,6 +834,12 @@ int ath11k_peer_delete(struct ath11k *ar
#ifdef CPTCFG_ATH11K_NSS_SUPPORT
peer->delete_in_progress = true;
+#else
+ if (peer)
+ peer->delete_in_progress = true;
+#endif
+
+#ifdef CPTCFG_ATH11K_NSS_SUPPORT
if (peer->self_ast_entry) {
ath11k_peer_del_ast(ar, peer->self_ast_entry);
peer->self_ast_entry = NULL;
@@ -863,10 +879,51 @@ int ath11k_peer_delete(struct ath11k *ar
if (ret && ret != -ETIMEDOUT)
return ret;
- ATH11K_MEMORY_STATS_DEC(ar->ab, per_peer_object,
- sizeof(struct ath11k_peer));
+ /* If timeout occurred, manually remove peer from list since firmware
+ * won't send unmap event. This prevents peer leaks and num_peers corruption.
+ */
+ if (ret == -ETIMEDOUT) {
+ ath11k_warn(ar->ab, "peer delete timeout %pM vdev %d, manually cleaning up\n",
+ addr, vdev_id);
- ar->num_peers--;
+ mutex_lock(&ar->ab->tbl_mtx_lock);
+ spin_lock_bh(&ar->ab->base_lock);
+ peer = ath11k_peer_find(ar->ab, vdev_id, addr);
+ if (peer) {
+ list_del(&peer->list);
+ kfree(peer);
+ ar->num_peers--;
+ ath11k_dbg(ar->ab, ATH11K_DBG_PEER,
+ "%s peer deleted (timeout) %pM vdev_id: %d num_peers: %d\n",
+ __func__, addr, vdev_id, ar->num_peers);
+ }
+ spin_unlock_bh(&ar->ab->base_lock);
+ mutex_unlock(&ar->ab->tbl_mtx_lock);
+ } else {
+ /* Normal path - but firmware may not send unmap event, so decrement here
+ * after successful peer deletion wait
+ */
+ mutex_lock(&ar->ab->tbl_mtx_lock);
+ spin_lock_bh(&ar->ab->base_lock);
+ peer = ath11k_peer_find(ar->ab, vdev_id, addr);
+ if (peer) {
+ /* Peer still in list - firmware didn't send unmap event yet */
+ list_del(&peer->list);
+ kfree(peer);
+ ar->num_peers--;
+ ath11k_dbg(ar->ab, ATH11K_DBG_PEER,
+ "%s peer deleted (no unmap event) %pM vdev_id: %d num_peers: %d\n",
+ __func__, addr, vdev_id, ar->num_peers);
+ } else {
+ /* Peer already removed by unmap event - still need to decrement */
+ ar->num_peers--;
+ ath11k_dbg(ar->ab, ATH11K_DBG_PEER,
+ "%s peer deleted (via unmap event) %pM vdev_id: %d num_peers: %d\n",
+ __func__, addr, vdev_id, ar->num_peers);
+ }
+ spin_unlock_bh(&ar->ab->base_lock);
+ mutex_unlock(&ar->ab->tbl_mtx_lock);
+ }
return 0;
}
@@ -905,6 +962,7 @@ int ath11k_peer_create(struct ath11k *ar
if (vdev_id == param->vdev_id)
return -EINVAL;
+ ath11k_dp_peer_cleanup(ar, vdev_id, param->peer_addr);
ath11k_peer_delete(ar, vdev_id, param->peer_addr);
}
@@ -970,7 +1028,8 @@ int ath11k_peer_create(struct ath11k *ar
ar->num_peers++;
if (ath11k_mac_sta_level_info(arvif, sta)) {
- ath11k_dbg(ar->ab, ATH11K_DBG_PEER, "peer created %pM\n", param->peer_addr);
+ ath11k_dbg(ar->ab, ATH11K_DBG_PEER, "peer created %pM vdev_id: %d num_peers: %d\n",
+ param->peer_addr, param->vdev_id, ar->num_peers);
peer->peer_logging_enabled = true;
}

View File

@@ -0,0 +1,174 @@
From 6a9ba11a6c58ddf6a9902c0f0396507778ef83ec Mon Sep 17 00:00:00 2001
From: Venkat Chimata <venkat@nearhop.com>
Date: Mon, 1 Dec 2025 07:25:36 +0530
Subject: [PATCH] ath11k: Synchronize num_peers with the actual peer count when
out of sync
Description:
The num_peers counter does not always update at the exact moment a peer is deleted.
Since deletion and decrement are not fully atomic, there are scenarios where
num_peers can drift out of sync with the actual number of peers.
Fix:
A complete rewrite of the num_peers update logic—ensuring fully correct
increment/decrement handling during peer insertion and deletion—would require
significant effort and QA validation. As an immediate and effective solution,
this patch synchronizes num_peers with the actual peer count whenever a mismatch
is detected.
Signed-off-by: Venkat Chimata <venkat@nearhop.com>
---
drivers/net/wireless/ath/ath11k/mac.c | 4 +-
drivers/net/wireless/ath/ath11k/peer.c | 70 +++++++++++++++++++-------
2 files changed, 53 insertions(+), 21 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index f300c4f..5d936d9 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -5745,7 +5745,7 @@ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw,
/* Skip if peer deletion already in progress to prevent
* double-delete and num_peers underflow
*/
- if (peer && peer->sta == sta && !peer->delete_in_progress) {
+ if (peer && peer->sta == sta) {
ath11k_warn(ar->ab, "Found peer entry %pM n vdev %i after it was supposedly removed\n",
vif->addr, arvif->vdev_id);
ath11k_peer_rhash_delete(ar->ab, peer);
@@ -7947,7 +7947,7 @@ static void ath11k_mac_op_remove_interface(struct ieee80211_hw *hw,
if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
ret = ath11k_peer_delete(ar, arvif->vdev_id, vif->addr);
if (ret)
- ath11k_warn(ab, "failed to submit AP self-peer removal on vdev %d: %d\n",
+ ath11k_warn(ab, "%s: failed to submit AP self-peer removal on vdev %d: %d\n", __func__,
arvif->vdev_id, ret);
list_for_each_entry_safe(ap_vlan_arvif, tmp, &arvif->ap_vlan_arvifs,
diff --git a/drivers/net/wireless/ath/ath11k/peer.c b/drivers/net/wireless/ath/ath11k/peer.c
index 877ea30..3433857 100644
--- a/drivers/net/wireless/ath/ath11k/peer.c
+++ b/drivers/net/wireless/ath/ath11k/peer.c
@@ -882,48 +882,38 @@ int ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, u8 *addr)
/* If timeout occurred, manually remove peer from list since firmware
* won't send unmap event. This prevents peer leaks and num_peers corruption.
*/
+ mutex_lock(&ar->ab->tbl_mtx_lock);
+ spin_lock_bh(&ar->ab->base_lock);
if (ret == -ETIMEDOUT) {
ath11k_warn(ar->ab, "peer delete timeout %pM vdev %d, manually cleaning up\n",
addr, vdev_id);
- mutex_lock(&ar->ab->tbl_mtx_lock);
- spin_lock_bh(&ar->ab->base_lock);
peer = ath11k_peer_find(ar->ab, vdev_id, addr);
if (peer) {
list_del(&peer->list);
kfree(peer);
- ar->num_peers--;
ath11k_dbg(ar->ab, ATH11K_DBG_PEER,
"%s peer deleted (timeout) %pM vdev_id: %d num_peers: %d\n",
__func__, addr, vdev_id, ar->num_peers);
}
- spin_unlock_bh(&ar->ab->base_lock);
- mutex_unlock(&ar->ab->tbl_mtx_lock);
} else {
/* Normal path - but firmware may not send unmap event, so decrement here
* after successful peer deletion wait
*/
- mutex_lock(&ar->ab->tbl_mtx_lock);
- spin_lock_bh(&ar->ab->base_lock);
peer = ath11k_peer_find(ar->ab, vdev_id, addr);
if (peer) {
/* Peer still in list - firmware didn't send unmap event yet */
list_del(&peer->list);
kfree(peer);
- ar->num_peers--;
ath11k_dbg(ar->ab, ATH11K_DBG_PEER,
"%s peer deleted (no unmap event) %pM vdev_id: %d num_peers: %d\n",
__func__, addr, vdev_id, ar->num_peers);
- } else {
- /* Peer already removed by unmap event - still need to decrement */
- ar->num_peers--;
- ath11k_dbg(ar->ab, ATH11K_DBG_PEER,
- "%s peer deleted (via unmap event) %pM vdev_id: %d num_peers: %d\n",
- __func__, addr, vdev_id, ar->num_peers);
}
- spin_unlock_bh(&ar->ab->base_lock);
- mutex_unlock(&ar->ab->tbl_mtx_lock);
}
+ // Peer can be deleted in the unmap or here, so only decrement num_peers once
+ ar->num_peers--;
+ spin_unlock_bh(&ar->ab->base_lock);
+ mutex_unlock(&ar->ab->tbl_mtx_lock);
return 0;
}
@@ -933,6 +923,31 @@ static int ath11k_wait_for_peer_created(struct ath11k *ar, int vdev_id, const u8
return ath11k_wait_for_peer_common(ar->ab, vdev_id, addr, true);
}
+static int ath11k_get_peer_count(struct rhashtable *ht)
+{
+ struct rhashtable_iter iter;
+ struct rhash_head *pos;
+ int count = 0;
+
+ rhashtable_walk_enter(ht, &iter);
+ rhashtable_walk_start(&iter);
+
+ while ((pos = rhashtable_walk_next(&iter))) {
+ if (IS_ERR(pos)) {
+ if (PTR_ERR(pos) == -EAGAIN)
+ continue; // retry due to resize
+ break; // some other error
+ }
+ count++;
+ }
+
+ rhashtable_walk_stop(&iter);
+ rhashtable_walk_exit(&iter);
+
+ return count;
+}
+
+
int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif,
struct ieee80211_sta *sta, struct peer_create_params *param)
{
@@ -941,13 +956,30 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif,
struct ath11k_sta *arsta;
int ret, fbret;
u8 vdev_id = 0;
+ int rhash_count;
lockdep_assert_held(&ar->conf_mutex);
- if (ar->num_peers > (ar->max_num_peers - 1)) {
+ // Check for peer count desynchronization
+ // If num_peers is negative or exceeds max_num_peers - 1, recalculate from rhashtable
+ if ((ar->num_peers < 0) || (ar->num_peers > (ar->max_num_peers - 1))) {
+ // This can happen if rhash table and num_peers get out of sync
+ // e.g. during peer delete for some unknown reason
+ // Recalculate num_peers from rhash table
ath11k_warn(ar->ab,
- "failed to create peer due to insufficient peer entry resource in firmware\n");
- return -ENOBUFS;
+ "failed to create peer due to insufficient peer entry resource in firmware ar->num_peers = %d "
+ "ar->max_num_peers = %d ar->num_stations = %d\n", ar->num_peers, ar->max_num_peers, ar->num_stations);
+ mutex_lock(&ar->ab->tbl_mtx_lock);
+ spin_lock_bh(&ar->ab->base_lock);
+ rhash_count = ath11k_get_peer_count(ar->ab->rhead_peer_addr);
+ spin_unlock_bh(&ar->ab->base_lock);
+ mutex_unlock(&ar->ab->tbl_mtx_lock);
+ if (rhash_count > ar->max_num_peers -1 ) {
+ ath11k_warn(ar->ab,
+ "rhash_count %d exceeds max_num_peers %d\n", rhash_count, ar->max_num_peers);
+ return -ENOBUFS;
+ }
+ ar->num_peers = rhash_count;
}
mutex_lock(&ar->ab->tbl_mtx_lock);
--
2.34.1

View File

@@ -0,0 +1,33 @@
From ed3f83b3459a67a3ab9d806490ac304b567b1c2d Mon Sep 17 00:00:00 2001
From: Miaoqian Lin <linmq006@gmail.com>
Date: Mon, 2 Jan 2023 12:11:42 +0400
Subject: wifi: ath11k: Fix memory leak in ath11k_peer_rx_frag_setup
crypto_alloc_shash() allocates resources, which should be released by
crypto_free_shash(). When ath11k_peer_find() fails, there has memory
leak. Add missing crypto_free_shash() to fix this.
Fixes: 243874c64c81 ("ath11k: handle RX fragments")
Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://lore.kernel.org/r/20230102081142.3937570-1-linmq006@gmail.com
---
drivers/net/wireless/ath/ath11k/dp_rx.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
index be391322956fec..b65a84a8826413 100644
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -3126,6 +3126,7 @@ int ath11k_peer_rx_frag_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id
if (!peer) {
ath11k_warn(ab, "failed to find the peer to set up fragment info\n");
spin_unlock_bh(&ab->base_lock);
+ crypto_free_shash(tfm);
return -ENOENT;
}
--
cgit 1.2.3-korg

View File

@@ -0,0 +1,39 @@
From 72de799aa9e3e064b35238ef053d2f0a49db055a Mon Sep 17 00:00:00 2001
From: Baochen Qiang <bqiang@codeaurora.org>
Date: Tue, 28 Sep 2021 14:00:44 +0300
Subject: ath11k: Fix memory leak in ath11k_qmi_driver_event_work
The buffer pointed to by event is not freed in case
ATH11K_FLAG_UNREGISTERING bit is set, resulting in
memory leak, so fix it.
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1
Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
Signed-off-by: Baochen Qiang <bqiang@codeaurora.org>
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20210913180246.193388-4-jouni@codeaurora.org
---
drivers/net/wireless/ath/ath11k/qmi.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c
index babadd574e4b9c..8c615bc788cacf 100644
--- a/drivers/net/wireless/ath/ath11k/qmi.c
+++ b/drivers/net/wireless/ath/ath11k/qmi.c
@@ -2759,8 +2759,10 @@ static void ath11k_qmi_driver_event_work(struct work_struct *work)
list_del(&event->list);
spin_unlock(&qmi->event_lock);
- if (test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags))
+ if (test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags)) {
+ kfree(event);
return;
+ }
switch (event->type) {
case ATH11K_QMI_EVENT_SERVER_ARRIVE:
--
cgit 1.2.3-korg

View File

@@ -16,6 +16,7 @@ PKG_LICENSE_FILES:=LICENSE
PKG_SOURCE_VERSION:=$(PKG_VERSION)
PKG_SOURCE_URL:=https://github.com/MorseMicro/morse_driver.git
PKG_MIRROR_HASH:=3ba6acd2760a1939fcd8e6f9b4dadbaed4562ce9879a21ff2a821ab445fa22b5
PKG_HASH:=159d018a92e0cf742795ed49bd94fb6ed324163012bb91c2a2e4e0f6037bbf23
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=b2ab42a5f22527422adf6afab73f2d019c16f162

View File

@@ -16,6 +16,7 @@ PKG_LICENSE:=BSD-3-Clause
PKG_SOURCE_VERSION:=$(PKG_VERSION)
PKG_SOURCE_URL:=https://github.com/MorseMicro/hostap.git
PKG_MIRROR_HASH:=a2f17ce3d2fe25d45cc2d6869e9ea644bcac441ec9b541972034768d4fc63608
PKG_HASH:=a2f17ce3d2fe25d45cc2d6869e9ea644bcac441ec9b541972034768d4fc63608
PKG_SOURCE_PROTO:=git

View File

@@ -17,6 +17,7 @@ PKG_LICENSE_FILES:=
PKG_SOURCE_VERSION:=$(PKG_VERSION)
PKG_SOURCE_URL:=https://github.com/MorseMicro/morse_cli.git
PKG_MIRROR_HASH:=04c88a3aea99082a29eb1f84a9b62dcbb85980fa040e0e34901c1826f33ae74c
PKG_HASH:=04c88a3aea99082a29eb1f84a9b62dcbb85980fa040e0e34901c1826f33ae74c
PKG_SOURCE_PROTO:=git

View File

@@ -16,6 +16,7 @@ PKG_LICENSE:=BSD-3-Clause
PKG_SOURCE_VERSION:=$(PKG_VERSION)
PKG_SOURCE_URL:=https://github.com/MorseMicro/hostap.git
PKG_MIRROR_HASH:=c342d1489d03363b79b5b4e185ccbceca53aab9e634daefb81180ad1012b77b7
PKG_HASH:=c342d1489d03363b79b5b4e185ccbceca53aab9e634daefb81180ad1012b77b7
PKG_SOURCE_PROTO:=git

View File

@@ -108,6 +108,11 @@ $(call Package/ath12k-wifi-default)
TITLE:=board-2.bin for WF672
endef
define Package/ath12k-wifi-asterfusion-ap7330
$(call Package/ath12k-wifi-default)
TITLE:=board.bin for Asterfusion AP7330
endef
define Package/ath12k-wifi-cig-wf189/install
$(INSTALL_DIR) $(1)/lib/firmware/ath12k/QCN92XX/hw1.0/
$(INSTALL_DIR) $(1)/lib/firmware/ath12k/IPQ5332/hw1.0/
@@ -223,6 +228,13 @@ define Package/ath12k-wifi-cig-wf672/install
$(INSTALL_DATA) ./board-2.bin.wf672-us.IPQ5332 $(1)/lib/firmware/ath12k/IPQ5332/hw1.0/board-2.bin.US
endef
define Package/ath12k-wifi-asterfusion-ap7330/install
$(INSTALL_DIR) $(1)/lib/firmware/ath12k/QCN92XX/hw1.0/
$(INSTALL_DIR) $(1)/lib/firmware/ath12k/IPQ5332/hw1.0/
$(INSTALL_DATA) ./board-2.bin.ap7330.QCN92XX $(1)/lib/firmware/ath12k/QCN92XX/hw1.0/board-2.bin
$(INSTALL_DATA) ./board-2.bin.ap7330.IPQ5332 $(1)/lib/firmware/ath12k/IPQ5332/hw1.0/board-2.bin
endef
$(eval $(call BuildPackage,ath12k-wifi-cig-wf189))
$(eval $(call BuildPackage,ath12k-wifi-edgecore-eap105))
$(eval $(call BuildPackage,ath12k-wifi-emplus-wap7635))
@@ -238,3 +250,4 @@ $(eval $(call BuildPackage,ath12k-wifi-zyxel-nwa130be))
$(eval $(call BuildPackage,ath12k-wifi-zyxel-nwa50be))
$(eval $(call BuildPackage,ath12k-wifi-zyxel-nwa210be))
$(eval $(call BuildPackage,ath12k-wifi-cig-wf672))
$(eval $(call BuildPackage,ath12k-wifi-asterfusion-ap7330))

View File

@@ -0,0 +1,20 @@
[
{
"board": [
{
"names": [
"bus=ahb,qmi-chip-id=0,qmi-board-id=255"
],
"data": "board-asterfusion-ap7330.bin.ipq53xx"
}
],
"regdb": [
{
"names": [
"bus=ahb,qmi-chip-id=0,qmi-board-id=255"
],
"data": "regdb-asterfusion-ipq5332-qcn92xx.bin"
}
]
}
]

View File

@@ -0,0 +1,20 @@
[
{
"board": [
{
"names": [
"bus=pci,qmi-chip-id=0,qmi-board-id=255"
],
"data": "board-asterfusion-ap7330.bin.qcn9224"
}
],
"regdb": [
{
"names": [
"bus=pci,qmi-chip-id=0,qmi-board-id=255"
],
"data": "regdb-asterfusion-ipq5332-qcn92xx.bin"
}
]
}
]

View File

@@ -24,3 +24,6 @@ $encoder -c board-2-nwa50be-QCN6432.json -o board-2.bin.nwa50be.QCN6432
$encoder -c board-2-nwa210be-IPQ5332.json -o board-2.bin.nwa210be.IPQ5332
$encoder -c board-2-nwa210be-QCN92XX.json -o board-2.bin.nwa210be.QCN92XX
$encoder -c board-2-ap7330-IPQ5332.json -o board-2.bin.ap7330.IPQ5332
$encoder -c board-2-ap7330-QCN92XX.json -o board-2.bin.ap7330.QCN92XX

View File

@@ -0,0 +1,69 @@
From c2e1dbd799ae5ed166e9c84a3c3d3a07a8f8cc9b Mon Sep 17 00:00:00 2001
From: Venkat Chimata <venkat@nearhop.com>
Date: Thu, 11 Dec 2025 10:38:07 +0530
Subject: [PATCH] bandwidth: Correct handling of RADIUS-assigned bandwidth
limits
Description:
Hostapd successfully parsed the uplink and downlink bandwidth attributes from
the RADIUS server, but the values were not being propagated correctly into
sta_info. As a result, the bandwidth information was missing in the UBUS
events sent to ucentral-event.
Fix:
Ensure the parsed bandwidth values are correctly passed to sta_info so they
are included in subsequent UBUS notifications.
Tests Performed:
Configured per-client bandwidth limits on the RADIUS server and verified that:
- The AP enforces the configured uplink/downlink limits, and
- The correct bandwidth values appear in the UBUS events.
Signed-off-by: Venkat Chimata <venkat@nearhop.com>
---
src/ap/ieee802_11.c | 2 ++
src/ap/ieee802_11_auth.c | 1 +
src/ap/ieee802_11_auth.h | 1 +
3 files changed, 4 insertions(+)
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index ef1ad21..615fb32 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -2485,6 +2485,8 @@ int ieee802_11_set_radius_info(struct hostapd_data *hapd, struct sta_info *sta,
ap_sta_no_session_timeout(hapd, sta);
}
+ os_memcpy(sta->bandwidth, info->bandwidth, sizeof(sta->bandwidth));
+
return 0;
}
diff --git a/src/ap/ieee802_11_auth.c b/src/ap/ieee802_11_auth.c
index e673296..9d0d734 100644
--- a/src/ap/ieee802_11_auth.c
+++ b/src/ap/ieee802_11_auth.c
@@ -581,6 +581,7 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
os_memcpy(info->radius_cui, buf, len);
}
+ radius_msg_get_wispr(msg, info->bandwidth);
if (hapd->conf->wpa_psk_radius == PSK_RADIUS_REQUIRED &&
!info->psk)
cache->accepted = HOSTAPD_ACL_REJECT;
diff --git a/src/ap/ieee802_11_auth.h b/src/ap/ieee802_11_auth.h
index 22ae1a9..b0005bd 100644
--- a/src/ap/ieee802_11_auth.h
+++ b/src/ap/ieee802_11_auth.h
@@ -23,6 +23,7 @@ struct radius_sta {
struct hostapd_sta_wpa_psk_short *psk;
char *identity;
char *radius_cui;
+ u32 bandwidth[2];
};
int hostapd_check_acl(struct hostapd_data *hapd, const u8 *addr,
--
2.34.1

View File

@@ -0,0 +1,20 @@
diff -urp a/src/ap/hostapd.c b/src/ap/hostapd.c
--- a/src/ap/hostapd.c 2025-10-28 15:50:59.024346272 +0800
+++ b/src/ap/hostapd.c 2025-12-09 23:03:55.351738472 +0800
@@ -5115,14 +5115,11 @@ static void hostapd_switch_color_timeout
}
if (i == HE_OPERATION_BSS_COLOR_MAX) {
- /* There are no free colors so turn BSS coloring off */
+ /* There are no free colors so do not change color and wait for next check */
wpa_printf(MSG_INFO,
- "No free colors left, turning off BSS coloring");
+ "No free colors left, stay at the same color");
hapd->iface->conf->he_op.he_bss_color_disabled = 1;
- hapd->iface->conf->he_op.he_bss_color = os_random() % 63 + 1;
hapd->no_free_color = 1;
- for (b = 0; b < hapd->iface->num_bss; b++)
- ieee802_11_set_beacon(hapd->iface->bss[b]);
/* Enabling for next check after timeout*/
hapd->iface->conf->he_op.he_bss_color_disabled = 0;

View File

@@ -46,6 +46,11 @@ ipq53xx_setup_interfaces()
zyxel,nwa130be)
ucidef_set_interfaces_lan_wan "eth1" "eth0"
;;
asterfusion,AP7330)
ucidef_set_interface_wan "eth0"
ucidef_add_switch "switch1" \
"0u@eth1" "3:lan" "4:lan"
;;
esac
}
@@ -154,6 +159,19 @@ qcom_setup_macs()
ucidef_set_wireless_macaddr_base 2g $(macaddr_add "$wan_mac" 1)
ucidef_set_wireless_macaddr_base 5g $(macaddr_add "$wan_mac" 2)
;;
asterfusion,AP7330)
mtd=$(find_mtd_chardev "0:ART")
[ -z "$mtd" ] && return;
wan_mac=$(mtd_get_mac_binary 0:ART 0x0)
[ -z "$wan_mac" ] && return;
wan_mac=$(macaddr_canonicalize $wan_mac)
lan_mac=$(macaddr_add "$wan_mac" 1)
ucidef_set_network_device_mac eth0 $wan_mac
ucidef_set_network_device_mac eth1 $lan_mac
ucidef_set_wireless_macaddr_base 2g $(macaddr_add "$wan_mac" 2)
ucidef_set_wireless_macaddr_base 5g $(macaddr_add "$wan_mac" 3)
ucidef_set_wireless_macaddr_base 6g $(macaddr_add "$wan_mac" 4)
;;
*)
wan_mac=$(cat /sys/class/net/eth1/address)
lan_mac=$(macaddr_add "$wan_mac" 1)

View File

@@ -67,6 +67,7 @@ ath12k/IPQ5332/hw1.0/caldata.bin)
emplus,wap7635|\
sercomm,ap72tip-v4|\
sercomm,ap72tip|\
asterfusion,AP7330|\
zyxel,nwa130be|\
zyxel,nwa210be|\
zyxel,nwa50be)
@@ -92,6 +93,7 @@ ath12k/QCN92XX/hw1.0/cal-pci-0001:01:00.0.bin)
emplus,wap7635|\
sercomm,ap72tip-v4|\
sercomm,ap72tip|\
asterfusion,AP7330|\
zyxel,nwa210be|\
zyxel,nwa130be)
caldata_extract "0:ART" 0x58800 0x2d000

View File

@@ -5,6 +5,7 @@
board=$(board_name)
case "$board" in
"asterfusion,AP7330"|\
"edgecore,eap105")
ln -s /sys/kernel/debug/ath12k/ipq5332\ hw1.0_c000000.wifi/mac0/fw_stats/pdev_stats /tmp/pdev_stats_phy2g
ln -s /sys/kernel/debug/ath12k/qcn9274\ hw2.0_0001:01:00.0/mac0/fw_stats/pdev_stats /tmp/pdev_stats_phy5g

View File

@@ -174,6 +174,7 @@ platform_do_upgrade() {
sonicfi_dualimage_check
nand_upgrade_tar "$1"
;;
asterfusion,AP7330|\
zyxel,nwa130be|\
zyxel,nwa210be|\
zyxel,nwa50be)

View File

@@ -1226,3 +1226,5 @@ CONFIG_PSTORE_RAM=y
# CONFIG_RTL8221D_PHY is not set
# CONFIG_INPUT_LSM303AGR is not set
# CONFIG_USB_SERIAL_XR is not set
CONFIG_GPIO_WATCHDOG=y
CONFIG_GPIO_WATCHDOG_ARCH_INITCALL=y

View File

@@ -0,0 +1,711 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
* IPQ5332 RDP468 board device tree source
*
* Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
/dts-v1/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/leds/common.h>
#include "ipq5332.dtsi"
#include "ipq5332-default-memory.dtsi"
/*
* This file is copied from ipq5332-rdp468.dts but has been modified.
* For modification, please compare the original QSDK's ipq5332-mi01.6.dts
* with the modified version.
*/
/ {
model = "ASTERFUSION";
compatible = "asterfusion,AP7330", "qcom,ipq5332-ap-mi01.6", "qcom,ipq5332-rdp468", "qcom,ipq5332";
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
ramoops@49c00000 {
compatible = "ramoops";
no-map;
reg = <0x0 0x49c00000 0x0 0x50000>;
record-size = <0x20000>;
console-size = <0x8000>;
pmsg-size = <0x8000>;
};
};
aliases {
serial0 = &blsp1_uart0;
serial1 = &blsp1_uart1;
ethernet0 = "/soc/dp1";
ethernet1 = "/soc/dp2";
led-boot = &led_green;
led-failsafe = &led_red;
led-running = &led_green;
led-upgrade = &led_green;
};
chosen {
stdout-path = "serial0";
};
soc@0 {
mdio:mdio@90000 {
pinctrl-0 = <&mdio1_pins &mdio0_pins>;
pinctrl-names = "default";
/*gpio51 for manhattan reset*/
phy-reset-gpio = <&tlmm 51 GPIO_ACTIVE_LOW>;
phyaddr_fixup = <0xC90F018>;
uniphyaddr_fixup = <0xC90F014>;
mdio_clk_fixup; /* MDIO clock sequence fix up flag */
status = "okay";
phy0: ethernet-phy@0 {
reg = <1>;
fixup;
};
phy1: ethernet-phy@1 {
reg = <2>;
fixup;
};
phy2: ethernet-phy@2 {
reg = <3>;
fixup;
};
phy3: ethernet-phy@3 {
reg = <4>;
fixup;
};
switch0@10 {
compatible = "qca,qca8386";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x10>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
label = "cpu";
ethernet = <&gmac2>;
phy-mode = "sgmii";
};
port@1 {
reg = <1>;
label = "lan1";
phy-handle = <&phy0>;
};
port@2 {
reg = <2>;
label = "lan2";
phy-handle = <&phy1>;
};
port@3 {
reg = <3>;
label = "lan3";
phy-handle = <&phy2>;
};
port@4 {
reg = <4>;
label = "lan4";
phy-handle = <&phy3>;
};
};
};
};
ess-instance {
num_devices = <0x2>;
ess-switch@3a000000 {
pinctrl-names = "default";
switch_cpu_bmp = <0x1>; /* cpu port bitmap */
switch_lan_bmp = <0x2>; /* lan port bitmap */
switch_wan_bmp = <0x4>; /* wan port bitmap */
switch_mac_mode = <0xc>; /* mac mode for uniphy instance0*/
switch_mac_mode1 = <0xe>; /* mac mode for uniphy instance1*/
switch_mac_mode2 = <0xff>; /* mac mode for uniphy instance2*/
qcom,port_phyinfo {
port@0 {
port_id = <1>;
forced-speed = <2500>;
forced-duplex = <1>;
};
port@1 {
port_id = <2>;
phy_address = <30>;
media-type = "sfp"; /* fiber mode */
};
};
};
ess-switch1@1 {
compatible = "qcom,ess-switch-qca8386";
device_id = <1>;
switch_access_mode = "mdio";
mdio-bus = <&mdio>;
switch_mac_mode = <0xc>; /* mac mode for uniphy instance0 */
switch_mac_mode1 = <0xff>; /* mac mode1 for uniphy instance1 */
switch_cpu_bmp = <0x1>; /* cpu port bitmap */
switch_lan_bmp = <0x1e>; /* lan port bitmap */
switch_wan_bmp = <0x0>; /* wan port bitmap */
link-polling-required = <0>;
fdb_sync = "interrupt";
link-intr-gpio = <&tlmm 23 GPIO_ACTIVE_HIGH>;
qcom,port_phyinfo {
port@0 {
port_id = <0>;
forced-speed = <2500>;
forced-duplex = <1>;
};
port@1 {
port_id = <1>;
phy_address = <1>;
};
port@2 {
port_id = <2>;
phy_address = <2>;
};
port@3 {
port_id = <3>;
phy_address = <3>;
};
port@4 {
port_id = <4>;
phy_address = <4>;
};
};
led_source@2 {
source = <2>;
mode = "normal";
speed = "all";
blink_en = "enable";
active = "high";
};
led_source@5 {
source = <5>;
mode = "normal";
speed = "all";
blink_en = "enable";
active = "high";
};
led_source@8 {
source = <8>;
mode = "normal";
speed = "all";
blink_en = "enable";
active = "high";
};
led_source@11 {
source = <11>;
mode = "normal";
speed = "all";
blink_en = "enable";
active = "high";
};
};
};
dp1 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <2>;
reg = <0x3a504000 0x4000>;
qcom,mactype = <1>;
local-mac-address = [000000000000];
mdio-bus = <&mdio>;
qcom,phy-mdio-addr = <30>;
qcom,link-poll = <1>;
phy-mode = "sgmii";
};
gmac2:dp2 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <1>;
reg = <0x3a500000 0x4000>;
qcom,mactype = <1>;
local-mac-address = [000000000000];
phy-mode = "sgmii";
qcom,mht-dev = <1>;
qcom,is_switch_connected = <1>;
qcom,ppe-offload-disabled = <1>;
};
/* EDMA host driver configuration for the board */
edma@3ab00000 {
qcom,txdesc-ring-start = <4>; /* Tx desc ring start ID */
qcom,txdesc-rings = <12>; /* Total number of Tx desc rings to be provisioned */
qcom,mht-txdesc-rings = <8>; /* Extra Tx desc rings to be provisioned for MHT SW ports */
qcom,txcmpl-ring-start = <4>; /* Tx complete ring start ID */
qcom,txcmpl-rings = <12>; /* Total number of Tx complete rings to be provisioned */
qcom,mht-txcmpl-rings = <8>; /* Extra Tx complete rings to be provisioned for mht sw ports. */
qcom,rxfill-ring-start = <4>; /* Rx fill ring start ID */
qcom,rxfill-rings = <4>; /* Total number of Rx fill rings to be provisioned */
qcom,rxdesc-ring-start = <12>; /* Rx desc ring start ID */
qcom,rxdesc-rings = <4>; /* Total number of Rx desc rings to be provisioned */
qcom,rx-page-mode = <0>; /* Rx fill ring page mode */
qcom,tx-map-priority-level = <1>; /* Tx priority level per port */
qcom,rx-map-priority-level = <1>; /* Rx priority level per core */
qcom,ppeds-num = <2>; /* Number of PPEDS nodes */
/* PPE-DS node format: <Rx-fill Tx-cmpl Rx Tx Queue-base Queue-count> */
qcom,ppeds-map = <1 1 1 1 32 8>, /* PPEDS Node#0 ring and queue map */
<2 2 2 2 40 8>; /* PPEDS Node#1 ring and queue map */
qcom,txdesc-map = <8 9 10 11>, /* Port0 per-core Tx ring map */
<12 13 14 15>, /* MHT-Port1 per-core Tx ring map */
<4 5 6 7>, /* MHT-Port2 per-core Tx ring map/packets from vp*/
<16 17 18 19>, /* MHT-Port3 per-core Tx ring map */
<20 21 22 23>; /* MHT-Port4 per-core Tx ring map */
qcom,txdesc-fc-grp-map = <1 2 3 4 5>; /* Per GMAC flow control group map */
qcom,rxfill-map = <4 5 6 7>; /* Per-core Rx fill ring map */
qcom,rxdesc-map = <12 13 14 15>; /* Per-core Rx desc ring map */
qcom,rx-queue-start = <0>; /* Rx queue start */
qcom,rx-ring-queue-map = <0 8 16 24>, /* Priority 0 queues per-core Rx ring map */
<1 9 17 25>, /* Priority 1 queues per-core Rx ring map */
<2 10 18 26>, /* Priority 2 queues per-core Rx ring map */
<3 11 19 27>, /* Priority 3 queues per-core Rx ring map */
<4 12 20 28>, /* Priority 4 queues per-core Rx ring map */
<5 13 21 29>, /* Priority 5 queues per-core Rx ring map */
<6 14 22 30>, /* Priority 6 queues per-core Rx ring map */
<7 15 23 31>; /* Priority 7 queues per-core Rx ring map */
interrupts = <0 163 4>, /* Tx complete ring id #4 IRQ info */
<0 164 4>, /* Tx complete ring id #5 IRQ info */
<0 165 4>, /* Tx complete ring id #6 IRQ info */
<0 166 4>, /* Tx complete ring id #7 IRQ info */
<0 167 4>, /* Tx complete ring id #8 IRQ info */
<0 168 4>, /* Tx complete ring id #9 IRQ info */
<0 169 4>, /* Tx complete ring id #10 IRQ info */
<0 170 4>, /* Tx complete ring id #11 IRQ info */
<0 171 4>, /* Tx complete ring id #12 IRQ info */
<0 172 4>, /* Tx complete ring id #13 IRQ info */
<0 173 4>, /* Tx complete ring id #14 IRQ info */
<0 174 4>, /* Tx complete ring id #15 IRQ info */
<0 139 4>, /* Rx desc ring id #12 IRQ info */
<0 140 4>, /* Rx desc ring id #13 IRQ info */
<0 141 4>, /* Rx desc ring id #14 IRQ info */
<0 142 4>, /* Rx desc ring id #15 IRQ info */
<0 191 4>, /* Misc error IRQ info */
<0 160 4>, /* PPEDS Node #1(TxComp ring id #1) TxComplete IRQ info */
<0 128 4>, /* PPEDS Node #1(Rx Desc ring id #1) Rx Desc IRQ info */
<0 152 4>, /* PPEDS Node #1(RxFill Desc ring id #1) Rx Fill IRQ info */
<0 161 4>, /* PPEDS Node #2(TxComp ring id #2) TxComplete IRQ info */
<0 129 4>, /* PPEDS Node #2(Rx Desc ring id #2) Rx Desc IRQ info */
<0 153 4>, /* PPEDS Node #2(RxFill Desc ring id #2) Rx Fill IRQ info */
<0 175 4>, /* MHT port Tx complete ring id #16 IRQ info */
<0 176 4>, /* MHT port Tx complete ring id #17 IRQ info */
<0 177 4>, /* MHT port Tx complete ring id #18 IRQ info */
<0 178 4>, /* MHT port Tx complete ring id #19 IRQ info */
<0 179 4>, /* MHT port Tx complete ring id #20 IRQ info */
<0 180 4>, /* MHT port Tx complete ring id #21 IRQ info */
<0 181 4>, /* MHT port Tx complete ring id #22 IRQ info */
<0 182 4>; /* MHT port Tx complete ring id #23 IRQ info */
};
leds {
compatible = "gpio-leds";
pinctrl-0 = <&gpio_leds_default>;
pinctrl-names = "default";
led_wifi: led@36 {
label = "led_wifi";
gpios = <&tlmm 36 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "none";
default-state = "off";
};
led_red: led@37 {
label = "led_red";
gpios = <&tlmm 37 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "timer";
default-state = "on";
};
led_green: led@38 {
label = "led_green";
gpios = <&tlmm 38 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "none";
default-state = "off";
};
};
gpio-watchdog {
compatible = "linux,wdt-gpio";
gpios = <&tlmm 39 GPIO_ACTIVE_LOW>;
hw_algo = "toggle";
hw_margin_ms = <5000>;
always-running;
};
gpio_keys {
compatible = "gpio-keys";
pinctrl-0 = <&button_pins>;
pinctrl-names = "default";
status = "okay";
button@1 {
label = "wps";
linux,code = <KEY_WPS_BUTTON>;
gpios = <&tlmm 35 GPIO_ACTIVE_LOW>;
linux,input-type = <1>;
debounce-interval = <60>;
};
};
wsi: wsi {
id = <0>;
num_chip = <2>;
status = "okay";
chip_info = <0 1 1>,
<1 1 0>;
};
};
};
&wifi0 {
// led-gpio = <&tlmm 36 GPIO_ACTIVE_HIGH>;
qcom,rproc = <&q6_wcss_pd1>;
qcom,rproc_rpd = <&q6v5_wcss>;
qcom,multipd_arch;
qcom,userpd-subsys-name = "q6v5_wcss_userpd1";
memory-region = <&q6_region>;
qcom,wsi = <&wsi>;
qcom,wsi_index = <0>;
qcom,board_id = <0x12>;
status = "okay";
};
&qcn9224_pcie1 {
status = "okay";
};
&blsp1_uart0 {
pinctrl-0 = <&serial_0_pins>;
pinctrl-names = "default";
status = "okay";
};
&blsp1_uart1 {
pinctrl-0 = <&serial_1_pins>;
pinctrl-names = "default";
status = "disabled";
};
&blsp1_i2c1 {
clock-frequency = <400000>;
pinctrl-0 = <&i2c_1_pins>;
pinctrl-names = "default";
status = "ok";
};
&blsp1_spi0 {
pinctrl-0 = <&spi_0_data_clk_pins &spi_0_cs_pins>;
pinctrl-names = "default";
status = "okay";
flash@0 {
compatible = "n25q128a11", "micron,n25q128a11", "jedec,spi-nor";
reg = <0>;
#address-cells = <1>;
#size-cells = <1>;
spi-max-frequency = <50000000>;
};
};
&blsp1_spi2 {
pinctrl-0 = <&spi_2_pins>;
pinctrl-names = "default";
cs-select = <0>;
status = "disabled";
};
&pcm {
pinctrl-0 = <&audio_pins_pri>;
pinctrl-names = "primary";
status = "disabled";
};
&sdhc {
bus-width = <4>;
max-frequency = <192000000>;
mmc-ddr-1_8v;
mmc-hs200-1_8v;
non-removable;
pinctrl-0 = <&sdc_default_state>;
pinctrl-names = "default";
status = "disabled";
};
&sleep_clk {
clock-frequency = <32000>;
};
&xo {
clock-frequency = <24000000>;
};
&qpic_bam {
status = "okay";
};
&qpic_nand {
pinctrl-0 = <&qspi_default_state>;
pinctrl-names = "default";
status = "okay";
nandcs@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <1>;
nand-ecc-strength = <8>;
nand-ecc-step-size = <512>;
nand-bus-width = <8>;
};
};
&pcie1_phy_x2 {
status = "okay";
};
&pcie1 {
pinctrl-0 = <&pcie1_default_state>;
pinctrl-names = "default";
perst-gpios = <&tlmm 47 GPIO_ACTIVE_LOW>;
status = "okay";
pcie1_rp {
reg = <0 0 0 0 0>;
qcom,mhi@1 {
reg = <0 0 0 0 0>;
boot-args = <0x2 0x4 0x34 0x3 0x0 0x0 /* MX Rail, GPIO52, Drive strength 0x3 */
0x4 0x4 0x18 0x3 0x0 0x0 /* RFA1p2 Rail, GPIO24, Drive strength 0x3 */
0x0 0x4 0x0 0x0 0x0 0x0>; /* End of arguments */
memory-region = <&qcn9224_pcie1>;
qcom,wsi = <&wsi>;
qcom,wsi_index = <1>;
qcom,board_id = <0x1006>;
};
};
};
/* PINCTRL */
&tlmm {
audio_pins_pri: audio_pinmux_pri {
mux_1 {
pins = "gpio29";
function = "audio_pri";
drive-strength = <8>;
bias-pull-down;
};
mux_2 {
pins = "gpio30";
function = "audio_pri";
drive-strength = <8>;
bias-pull-down;
};
mux_3 {
pins = "gpio31";
function = "audio_pri";
drive-strength = <4>;
bias-pull-down;
};
mux_4 {
pins = "gpio32";
function = "audio_pri";
drive-strength = <4>;
bias-pull-down;
};
};
i2c_1_pins: i2c-1-state {
pins = "gpio29", "gpio30";
function = "blsp1_i2c0";
drive-strength = <8>;
bias-pull-up;
};
spi_2_pins: spi-2-pins {
pins = "gpio33", "gpio34", "gpio35";
function = "blsp2_spi0";
drive-strength = <8>;
bias-pull-down;
};
sdc_default_state: sdc-default-state {
clk-pins {
pins = "gpio13";
function = "sdc_clk";
drive-strength = <8>;
bias-disable;
};
cmd-pins {
pins = "gpio12";
function = "sdc_cmd";
drive-strength = <8>;
bias-pull-up;
};
data-pins {
pins = "gpio8", "gpio9", "gpio10", "gpio11";
function = "sdc_data";
drive-strength = <8>;
bias-pull-up;
};
};
spi_0_data_clk_pins: spi-0-data-clk-state {
pins = "gpio14", "gpio15", "gpio16";
function = "blsp0_spi";
drive-strength = <2>;
bias-pull-down;
};
spi_0_cs_pins: spi-0-cs-state {
pins = "gpio17";
function = "blsp0_spi";
drive-strength = <2>;
bias-pull-up;
};
qspi_default_state: qspi-default-state {
qspi_clock {
pins = "gpio13";
function = "qspi_clk";
drive-strength = <8>;
bias-pull-down;
};
qspi_cs {
pins = "gpio12";
function = "qspi_cs";
drive-strength = <8>;
bias-pull-up;
};
qspi_data {
pins = "gpio8", "gpio9", "gpio10", "gpio11";
function = "qspi_data";
drive-strength = <8>;
bias-pull-down;
};
};
serial_1_pins: serial1-pinmux {
pins = "gpio33", "gpio34", "gpio35", "gpio36";
function = "blsp1_uart2";
drive-strength = <8>;
bias-pull-up;
};
gpio_leds_default: gpio-leds-default-state {
led_wifi {
pins = "gpio36";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
led_blue {
pins = "gpio49";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
led_red {
pins = "gpio37";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
led_green {
pins = "gpio38";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
led_all_enable {
pins = "gpio24";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
};
hwwatchdog {
pins = "gpio39";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
button_pins: button-state {
pins = "gpio35";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
};
pwm_pins: pwm-state {
pins = "gpio46";
function = "pwm0";
drive-strength = <8>;
};
pcie1_default_state: pcie1-default-state {
pins = "gpio47";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
output-low;
};
};
&license_manager {
status = "okay";
};
&usb3 {
qcom,multiplexed-phy;
status = "okay";
};
&pwm {
pinctrl-0 = <&pwm_pins>;
pinctrl-names = "default";
status = "okay";
};
&hs_m31phy_0 {
status = "okay";
};
&ssuniphy_0 {
status = "okay";
};

View File

@@ -204,3 +204,16 @@ define Device/cig_wf672
DEVICE_PACKAGES := ath12k-wifi-cig-wf672 ath12k-firmware-ipq5332 ath12k-firmware-qcn92xx
endef
TARGET_DEVICES += cig_wf672
define Device/asterfusion_ap7330
DEVICE_TITLE := Asterfusion AP7330
DEVICE_DTS := ipq5332-asterfusion-ap7330
DEVICE_DTS_CONFIG := config@mi01.6
DEVICE_DTS_DIR := ../dts
SUPPORTED_DEVICES := asterfusion,AP7330 AP7330
IMAGE/sysupgrade.tar := sysupgrade-tar | append-metadata
IMAGE/nand-factory.bin := append-ubi | qsdk-ipq-factory-nand
IMAGE/nand-factory.ubi := append-ubi
DEVICE_PACKAGES := ath12k-wifi-asterfusion-ap7330 ath12k-firmware-qcn92xx ath12k-firmware-ipq5332
endef
TARGET_DEVICES += asterfusion_ap7330

View File

@@ -37,7 +37,19 @@ function qdisc_del(iface) {
}
function ifb_dev(iface) {
return "i-" + iface;
let ifbname;
if ((index(iface, 'phy') != -1) && (index(iface, 'ap') != -1)) {
// For interfaces like phy6g-ap0, phy5g-ap0, phy2g-ap0
// we replace 'phy' with "p" to confine the ifb name length
// and replace 'ap' with 'a' to further shorten it.
ifbname = replace(iface, 'phy', 'p');
ifbname = replace(ifbname, 'ap', 'a');
} else {
ifbname = iface;
}
ifbname = "i-" + ifbname;
return ifbname;
}
function ifb_add(iface, ifbdev) {

View File

@@ -364,9 +364,9 @@ function switch_status_check(iface, dfs_enabled_5g_flag) {
let cac_time = trim(_cac_time.read('all'));
_cac_time.close();
// if cac_time is a valid number, set timer to cac_time + 5 seconds
// if cac_time is a valid number, set timer to cac_time + 10 seconds
if (cac_time > 0 && match(cac_time, /^[0-9]+$/)) {
timer = int(cac_time) + 5;
timer = int(cac_time) + 10;
}
while (p < timer) {
@@ -537,7 +537,7 @@ function get_chan_util(radio_band, sleep_time) {
return chan_util;
}
function random_channel_selection(iface, band, htmode, chan_list_valid) {
function random_channel_selection(iface, band, htmode, chan_list_valid, exclude_dfs) {
let math = require('math');
let bw = replace(htmode, /[^0-9]/g, '');
let iface_num = replace(iface, /[^0-9]/g, '');
@@ -547,7 +547,9 @@ function random_channel_selection(iface, band, htmode, chan_list_valid) {
}
// channel list from the driver based on the country code
let chan_list_cc = global.phy.phys[phy_id].channels;
let chan_list_cc = uniq(sort(global.phy.phys[phy_id].channels, (a, b) => a - b));
// DFS channel list from the driver
let dfs_chan_list = global.phy.phys[phy_id].dfs_channels || [];
// complete channel list
let chan_list_default = {};
// allowed channel list to select random channel from
@@ -555,6 +557,7 @@ function random_channel_selection(iface, band, htmode, chan_list_valid) {
let chan_list_init = [];
let chan_list_legal = [];
let _chan_list_legal = [];
ulog_info(`[%s] Channel list from the driver = %s \n`, iface, chan_list_cc);
ulog_info(`[%s] Selected channel list from config (default channel list shall be used in case channels haven't been selected) = %s \n`, iface, (chan_list_valid || '[]'));
@@ -663,9 +666,29 @@ function random_channel_selection(iface, band, htmode, chan_list_valid) {
if (band == '5g' && (bw == "80" || bw == "40")) {
// exclude last channels from the channel list when bw is 80MHz or 40MHz to avoid selecting a channel with a secondary channel that cannot be supported
chan_list_legal = slice(chan_list_init, 0, length(chan_list_init)-1) ;
_chan_list_legal = slice(chan_list_init, 0, length(chan_list_init)-1) ;
} else {
chan_list_legal = chan_list_init;
_chan_list_legal = chan_list_init;
}
// check if dfs is enabled or disabled for 5G radio; if dfs is disabled, remove dfs channels from chan_list_legal
if (band == '5g' && exclude_dfs == true) {
ulog_info(`[%s] DFS Channel list from the driver = %s \n`, iface, dfs_chan_list);
for (let _legal_chan in _chan_list_legal) {
let is_dfs_chan = false;
for (let dfs_chan in dfs_chan_list) {
if (dfs_chan == _legal_chan) {
is_dfs_chan = true;
break;
}
}
if (is_dfs_chan == false) {
push(chan_list_legal, _legal_chan);
}
}
} else {
chan_list_legal = _chan_list_legal;
}
if (chan_list_valid) {
@@ -710,13 +733,13 @@ function check_center_channel(chosen_random_channel, current_channel, band, htmo
return ret;
}
function algo_rcs(iface, current_channel, band, htmode, selected_channels) {
function algo_rcs(iface, current_channel, band, htmode, selected_channels, exclude_dfs) {
let chosen_random_channel = 0;
let res = 0;
let same_center_channel = false;
// random_channel_selection script will help to select random channel
chosen_random_channel = random_channel_selection(iface, band, htmode, selected_channels);
chosen_random_channel = random_channel_selection(iface, band, htmode, selected_channels, exclude_dfs);
stats_info_write("/tmp/rrm_random_channel_" + iface, chosen_random_channel);
if (chosen_random_channel == current_channel) {
@@ -826,7 +849,7 @@ function channel_optimize() {
// get radio's uci config
htmode[j] = wireless_status[radio_id].config.htmode;
acs_exclude_dfs[j] = wireless_status[radio_id].config.acs_exclude_dfs;
acs_exclude_dfs[j] = wireless_status[radio_id].config.acs_exclude_dfs || false;
channel_config[j] = wireless_status[radio_id].config.channel;
selected_channels[j] = wireless_status[radio_id].config.channels;
@@ -961,7 +984,7 @@ function channel_optimize() {
let assign_max_chan_util = 0;
// call RCS for multiple random chan
let chan_scan = algo_rcs(radio_iface[l], curr_chan_list[num_chan-1], radio_band[l], htmode[l], selected_channels[l]);
let chan_scan = algo_rcs(radio_iface[l], curr_chan_list[num_chan-1], radio_band[l], htmode[l], selected_channels[l], acs_exclude_dfs[l]);
curr_chan_list[num_chan] = stats_info_read("/tmp/rrm_random_channel_" + radio_iface[l]);
if (chan_scan == 1) {

View File

@@ -1,5 +1,5 @@
{
"major": 4,
"minor": 1,
"patch": 1
"minor": 2,
"patch": 0
}

View File

@@ -4,10 +4,10 @@ PKG_NAME:=ucentral-schema
PKG_RELEASE:=1
PKG_SOURCE_URL=https://github.com/Telecominfraproject/wlan-ucentral-schema.git
PKG_MIRROR_HASH:=c0f43db0530a38eb424e81908ad47a14e1d4d8f8a86eb148e34f98187c79ba6b
PKG_MIRROR_HASH:=6d3b8e342ce8e7aeef908acfcbefc989523f0de9cac215d8be4f148746c4e0ce
PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2025-10-16
PKG_SOURCE_VERSION:=dc9cad95641266a08de73aab85d931d992090159
PKG_SOURCE_DATE:=2025-12-12
PKG_SOURCE_VERSION:=d26c4b0a1e38d331deeef89c5ccf669ce9044791
PKG_MAINTAINER:=John Crispin <john@phrozen.org>
PKG_LICENSE:=BSD-3-Clause

View File

@@ -38,7 +38,8 @@
"ipv4": {
"addressing": "static",
"subnet": "10.0.0.2/24",
"gateway": "10.0.0.1"
"gateway": "10.0.0.1",
"use-dns": ["10.0.0.1"]
},
"ssids": [
{

View File

@@ -0,0 +1,16 @@
---
profile: asterfusion_ap7330
target: ipq53xx
subtarget: generic
description: Build image for the asterfusion ap7330
image: bin/targets/ipq53xx/generic/openwrt-ipq53xx-asterfusion_ap7330-squashfs-sysupgrade.tar
feeds:
- name: qca
path: ../../feeds/qca-wifi-7
include:
- ucentral-ap
packages:
- ipq53xx
- qca-ssdk-shell
diffconfig: |
CONFIG_KERNEL_IPQ_MEM_PROFILE=0

View File

@@ -18,3 +18,4 @@ packages:
- kmod-cig-poe-judgment
diffconfig: |
CONFIG_KERNEL_IPQ_MEM_PROFILE=0
CONFIG_PACKAGE_ATH_DEBUG=y

View File

@@ -17,3 +17,4 @@ packages:
- kmod-cig-poe-judgment
diffconfig: |
CONFIG_KERNEL_IPQ_MEM_PROFILE=0
CONFIG_PACKAGE_ATH_DEBUG=y

View File

@@ -17,3 +17,4 @@ packages:
- kmod-cig-poe-judgment
diffconfig: |
CONFIG_KERNEL_IPQ_MEM_PROFILE=0
CONFIG_PACKAGE_ATH_DEBUG=y

View File

@@ -27,3 +27,4 @@ diffconfig: |
CONFIG_KERNEL_IPQ_MEM_PROFILE=0
CONFIG_BUSYBOX_CUSTOM=y
CONFIG_BUSYBOX_CONFIG_STTY=y
CONFIG_PACKAGE_ATH_DEBUG=y

View File

@@ -1,12 +1,12 @@
---
profile: edgecore_eap111
target: mediatek
subtarget: filogic
subtarget: mt7981
description: Build image for the EdgeCore EAP111
image: bin/targets/mediatek/filogic/openwrt-mediatek-filogic-edgecore_eap111-squashfs-sysupgrade.bin
image: bin/targets/mediatek/mt7981/openwrt-mediatek-mt7981-edgecore_eap111-squashfs-sysupgrade.bin
feeds:
- name: mediatek
path: ../../feeds/mediatek
path: ../../feeds/mediatek-sdk
packages:
- mediatek
include:

View File

@@ -6,3 +6,4 @@ description: Build image for the Sonicfi EAP RAP63XC-211G
image: bin/targets/ramips/mt7621/openwrt-ramips-mt7621-sonicfi_rap63xc-211g-squashfs-sysupgrade.bin
include:
- ucentral-ap
- hostapd