wifi: ath12k: designating channel frequency for ROC scan
authorKang Yang <quic_kangyang@quicinc.com>
Mon, 5 Feb 2024 17:03:30 +0000 (19:03 +0200)
committerKalle Valo <quic_kvalo@quicinc.com>
Wed, 7 Feb 2024 15:07:00 +0000 (17:07 +0200)
For P2P mode, the WLAN interface may be requested to remain on a
specific channel and then to send some management frames on that
channel. Now chananel frequency of wmi_mgmt_send_cmd is set as 0. As
a result, firmware may choose a default but wrong channel.

Fix it by assigning chanfreq field with the ROC channel frequency.

This change only applies to WCN7850, other chips are not affected.

Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1

Signed-off-by: Kang Yang <quic_kangyang@quicinc.com>
Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://msgid.link/20240130040303.370590-11-quic_kangyang@quicinc.com
drivers/net/wireless/ath/ath12k/wmi.c

index 37cfd607c0431c7c27dfdd429db065b686e8138c..84d7d6584fba7d5b33a7bc2a609f3919d552c679 100644 (file)
@@ -730,6 +730,20 @@ static int ath12k_service_ready_event(struct ath12k_base *ab, struct sk_buff *sk
        return 0;
 }
 
+static u32 ath12k_wmi_mgmt_get_freq(struct ath12k *ar,
+                                   struct ieee80211_tx_info *info)
+{
+       struct ath12k_base *ab = ar->ab;
+       u32 freq = 0;
+
+       if (ab->hw_params->single_pdev_only &&
+           ar->scan.is_roc &&
+           (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN))
+               freq = ar->scan.roc_freq;
+
+       return freq;
+}
+
 struct sk_buff *ath12k_wmi_alloc_skb(struct ath12k_wmi_base *wmi_ab, u32 len)
 {
        struct sk_buff *skb;
@@ -755,6 +769,7 @@ int ath12k_wmi_mgmt_send(struct ath12k *ar, u32 vdev_id, u32 buf_id,
 {
        struct ath12k_wmi_pdev *wmi = ar->wmi;
        struct wmi_mgmt_send_cmd *cmd;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(frame);
        struct wmi_tlv *frame_tlv;
        struct sk_buff *skb;
        u32 buf_len;
@@ -773,7 +788,7 @@ int ath12k_wmi_mgmt_send(struct ath12k *ar, u32 vdev_id, u32 buf_id,
                                                 sizeof(*cmd));
        cmd->vdev_id = cpu_to_le32(vdev_id);
        cmd->desc_id = cpu_to_le32(buf_id);
-       cmd->chanfreq = 0;
+       cmd->chanfreq = cpu_to_le32(ath12k_wmi_mgmt_get_freq(ar, info));
        cmd->paddr_lo = cpu_to_le32(lower_32_bits(ATH12K_SKB_CB(frame)->paddr));
        cmd->paddr_hi = cpu_to_le32(upper_32_bits(ATH12K_SKB_CB(frame)->paddr));
        cmd->frame_len = cpu_to_le32(frame->len);