diff mbox series

[3/4] wifi: ath12k: update the latest CSA counter

Message ID 20241223-ath12k_mlo_csa-v1-3-78b6d7515568@quicinc.com
State New
Headers show
Series [1/4] wifi: ath12k: update beacon template function to use arvif structure | expand

Commit Message

Aditya Kumar Singh Dec. 23, 2024, 4:21 p.m. UTC
At present, the driver configures the firmware to send the Channel Switch
(CS) count event only when the count reaches zero during a Channel Switch
Announcement (CSA). For frames managed by the upper layer, where the driver
does not update the counter, the CS count in these frames remains unchanged
throughout the entire CSA period. This is because the upper layer is not
aware of the latest ongoing count. Indicating same count value throughout
the CSA time is wrong and could lead to connection instabilities.

Fix this by configuring firmware to send CS count event for every count and
then accordingly decrementing the count in mac80211.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1

Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
---
 drivers/net/wireless/ath/ath12k/wmi.c | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)
diff mbox series

Patch

diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index ff973372a01a85bede15fde72bbe7db99bcfb300..99f6dc2fbbe3d0aa71ab96e500cfaa8e4bf9930f 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -1933,6 +1933,7 @@  int ath12k_wmi_bcn_tmpl(struct ath12k_link_vif *arvif,
 				cpu_to_le32(offs->cntdwn_counter_offs[0]);
 		cmd->ext_csa_switch_count_offset =
 				cpu_to_le32(offs->cntdwn_counter_offs[1]);
+		cmd->csa_event_bitmap = cpu_to_le32(0xFFFFFFFF);
 	}
 
 	cmd->buf_len = cpu_to_le32(bcn->len);
@@ -6876,17 +6877,15 @@  ath12k_wmi_process_csa_switch_count_event(struct ath12k_base *ab,
 					  const struct ath12k_wmi_pdev_csa_event *ev,
 					  const u32 *vdev_ids)
 {
-	int i;
+	u32 current_switch_count = le32_to_cpu(ev->current_switch_count);
+	u32 num_vdevs = le32_to_cpu(ev->num_vdevs);
 	struct ieee80211_bss_conf *conf;
 	struct ath12k_link_vif *arvif;
 	struct ath12k_vif *ahvif;
-
-	/* Finish CSA once the switch count becomes NULL */
-	if (ev->current_switch_count)
-		return;
+	int i;
 
 	rcu_read_lock();
-	for (i = 0; i < le32_to_cpu(ev->num_vdevs); i++) {
+	for (i = 0; i < num_vdevs; i++) {
 		arvif = ath12k_mac_get_arvif_by_vdev_id(ab, vdev_ids[i]);
 
 		if (!arvif) {
@@ -6909,8 +6908,14 @@  ath12k_wmi_process_csa_switch_count_event(struct ath12k_base *ab,
 			continue;
 		}
 
-		if (arvif->is_up && conf->csa_active)
-			ieee80211_csa_finish(ahvif->vif, 0);
+		if (!arvif->is_up || !conf->csa_active)
+			continue;
+
+		/* Finish CSA when counter reaches zero */
+		if (!current_switch_count)
+			ieee80211_csa_finish(ahvif->vif, arvif->link_id);
+		else if (current_switch_count > 1)
+			ieee80211_beacon_update_cntdwn(ahvif->vif, arvif->link_id);
 	}
 	rcu_read_unlock();
 }