]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: ath12k: update the latest CSA counter
authorAditya Kumar Singh <quic_adisi@quicinc.com>
Fri, 24 Jan 2025 06:16:37 +0000 (11:46 +0530)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Mon, 3 Feb 2025 22:43:28 +0000 (14:43 -0800)
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>
Link: https://patch.msgid.link/20250124-ath12k_mlo_csa-v2-3-420c42fcfecf@quicinc.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
drivers/net/wireless/ath/ath12k/wmi.c

index 7a133d39c9155714ca591ce961d4f386168fa9ae..fdbb604e4fb094d90785c58c453ca6302cd41eef 100644 (file)
@@ -1972,6 +1972,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);
@@ -7496,17 +7497,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) {
@@ -7529,8 +7528,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();
 }