wifi: ath12k: fix handling of CSA offsets in beacon template command

The driver is informed of the counter offsets in the beacon during CSA
through the ieee80211_mutable_offsets structure. According to the
documentation for the cntdwn_counter_offs member, "This array can contain
zero values which should be ignored." However, the current implementation
uses these values unconditionally, without checking for zeros.

Whenever CSA is active, these offsets are guaranteed to be set. Therefore,
add a check for CSA active status before setting the CSA switch count
offsets. This ensures that the offsets are only set when CSA is active,
preventing incorrect configurations.

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-2-420c42fcfecf@quicinc.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
This commit is contained in:
Aditya Kumar Singh
2025-01-24 11:46:36 +05:30
committed by Jeff Johnson
parent 4094445969
commit f9c88d65e8
3 changed files with 22 additions and 4 deletions

View File

@@ -579,7 +579,7 @@ static int ath12k_mac_vif_link_chan(struct ieee80211_vif *vif, u8 link_id,
return 0;
}
static struct ieee80211_bss_conf *
struct ieee80211_bss_conf *
ath12k_mac_get_link_bss_conf(struct ath12k_link_vif *arvif)
{
struct ieee80211_vif *vif = arvif->ahvif->vif;

View File

@@ -111,5 +111,6 @@ void ath12k_mac_get_any_chanctx_conf_iter(struct ieee80211_hw *hw,
u16 ath12k_mac_he_convert_tones_to_ru_tones(u16 tones);
enum nl80211_eht_ru_alloc ath12k_mac_eht_ru_tones_to_nl80211_eht_ru_alloc(u16 ru_tones);
enum nl80211_eht_gi ath12k_mac_eht_gi_to_nl80211_eht_gi(u8 sgi);
struct ieee80211_bss_conf *ath12k_mac_get_link_bss_conf(struct ath12k_link_vif *arvif);
#endif

View File

@@ -1934,8 +1934,11 @@ int ath12k_wmi_bcn_tmpl(struct ath12k_link_vif *arvif,
{
struct ath12k *ar = arvif->ar;
struct ath12k_wmi_pdev *wmi = ar->wmi;
struct ath12k_base *ab = ar->ab;
struct wmi_bcn_tmpl_cmd *cmd;
struct ath12k_wmi_bcn_prb_info_params *bcn_prb_info;
struct ath12k_vif *ahvif = arvif->ahvif;
struct ieee80211_bss_conf *conf;
u32 vdev_id = arvif->vdev_id;
struct wmi_tlv *tlv;
struct sk_buff *skb;
@@ -1944,6 +1947,14 @@ int ath12k_wmi_bcn_tmpl(struct ath12k_link_vif *arvif,
int ret, len;
size_t aligned_len = roundup(bcn->len, 4);
conf = ath12k_mac_get_link_bss_conf(arvif);
if (!conf) {
ath12k_warn(ab,
"unable to access bss link conf in beacon template command for vif %pM link %u\n",
ahvif->vif->addr, arvif->link_id);
return -EINVAL;
}
len = sizeof(*cmd) + sizeof(*bcn_prb_info) + TLV_HDR_SIZE + aligned_len;
skb = ath12k_wmi_alloc_skb(wmi->wmi_ab, len);
@@ -1955,8 +1966,14 @@ int ath12k_wmi_bcn_tmpl(struct ath12k_link_vif *arvif,
sizeof(*cmd));
cmd->vdev_id = cpu_to_le32(vdev_id);
cmd->tim_ie_offset = cpu_to_le32(offs->tim_offset);
cmd->csa_switch_count_offset = cpu_to_le32(offs->cntdwn_counter_offs[0]);
cmd->ext_csa_switch_count_offset = cpu_to_le32(offs->cntdwn_counter_offs[1]);
if (conf->csa_active) {
cmd->csa_switch_count_offset =
cpu_to_le32(offs->cntdwn_counter_offs[0]);
cmd->ext_csa_switch_count_offset =
cpu_to_le32(offs->cntdwn_counter_offs[1]);
}
cmd->buf_len = cpu_to_le32(bcn->len);
cmd->mbssid_ie_offset = cpu_to_le32(offs->mbssid_off);
if (ema_args) {
@@ -1986,7 +2003,7 @@ int ath12k_wmi_bcn_tmpl(struct ath12k_link_vif *arvif,
ret = ath12k_wmi_cmd_send(wmi, skb, WMI_BCN_TMPL_CMDID);
if (ret) {
ath12k_warn(ar->ab, "failed to send WMI_BCN_TMPL_CMDID\n");
ath12k_warn(ab, "failed to send WMI_BCN_TMPL_CMDID\n");
dev_kfree_skb(skb);
}