]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: ath12k: add monitor interface support on QCN9274
authorP Praneesh <quic_ppranees@quicinc.com>
Mon, 24 Mar 2025 06:25:18 +0000 (11:55 +0530)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Thu, 27 Mar 2025 22:55:42 +0000 (15:55 -0700)
Currently, the monitor interface is not supported. To support the monitor
interface, configure the monitor vdev state identifier, configure the HTT
filter setup, subscribe the mac80211 NO_VIRTUAL_MONITOR feature, remove
the VIRTUAL_MONITOR handler procedures since align to NO_VIRTUAL_MONITOR
feature and prevent monitor interface to transmit packet. Therefore, add
these procedures to add monitor interface support and enable the monitor
interface support on the QCN9274 platform through the hardware parameter.

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

Signed-off-by: P Praneesh <quic_ppranees@quicinc.com>
Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Link: https://patch.msgid.link/20250324062518.2752822-11-quic_periyasa@quicinc.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
drivers/net/wireless/ath/ath12k/core.c
drivers/net/wireless/ath/ath12k/dp_tx.c
drivers/net/wireless/ath/ath12k/hw.c
drivers/net/wireless/ath/ath12k/mac.c

index a27c8043a091d45fa7074ac916560e1e8ed488ab..a0618f9cad4cc24eded302cc74ddc16e25928dde 100644 (file)
@@ -1387,6 +1387,10 @@ static void ath12k_core_pre_reconfigure_recovery(struct ath12k_base *ab)
                                     ath12k_mac_tx_mgmt_pending_free, ar);
                        idr_destroy(&ar->txmgmt_idr);
                        wake_up(&ar->txmgmt_empty_waitq);
+
+                       ar->monitor_vdev_id = -1;
+                       ar->monitor_vdev_created = false;
+                       ar->monitor_started = false;
                }
        }
 
index ced232bf4aed01ee810eb3e3049cf3deada218c4..29e2715024cea270d5e122abf6ee9a7d6139ee1b 100644 (file)
@@ -7,6 +7,7 @@
 #include "core.h"
 #include "dp_tx.h"
 #include "debug.h"
+#include "debugfs.h"
 #include "hw.h"
 #include "peer.h"
 #include "mac.h"
@@ -1431,6 +1432,11 @@ int ath12k_dp_tx_htt_rx_monitor_mode_ring_config(struct ath12k *ar, bool reset)
                                        HTT_RX_MON_MO_CTRL_FILTER_FLASG3 |
                                        HTT_RX_MON_FP_DATA_FILTER_FLASG3 |
                                        HTT_RX_MON_MO_DATA_FILTER_FLASG3;
+       } else {
+               tlv_filter = ath12k_mac_mon_status_filter_default;
+
+               if (ath12k_debugfs_is_extd_rx_stats_enabled(ar))
+                       tlv_filter.rx_filter = ath12k_debugfs_rx_filter(ar);
        }
 
        if (ab->hw_params->rxdma1_enable) {
index b4d5651973b76ceb6ec4edc2b5c3ab3fd884c5f8..0ba6aedc8405364f7311871b2f32c2fb35c469ad 100644 (file)
@@ -1446,7 +1446,7 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
                                        BIT(NL80211_IFTYPE_AP) |
                                        BIT(NL80211_IFTYPE_MESH_POINT) |
                                        BIT(NL80211_IFTYPE_AP_VLAN),
-               .supports_monitor = false,
+               .supports_monitor = true,
 
                .idle_ps = false,
                .download_calib = true,
index 65bf1f24a45ff5c59c826ee043fd6545de3c2016..f2fddf213afb9cd8681d3d94a7863c8a25be2bb6 100644 (file)
@@ -1306,12 +1306,18 @@ static int ath12k_mac_monitor_start(struct ath12k *ar)
                return ret;
        }
 
+       ret = ath12k_dp_tx_htt_monitor_mode_ring_config(ar, false);
+       if (ret) {
+               ath12k_warn(ar->ab, "fail to set monitor filter: %d\n", ret);
+               return ret;
+       }
+
        ar->monitor_started = true;
        ar->num_started_vdevs++;
-       ret = ath12k_dp_tx_htt_monitor_mode_ring_config(ar, false);
-       ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac monitor started ret %d\n", ret);
 
-       return ret;
+       ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac monitor started\n");
+
+       return 0;
 }
 
 static int ath12k_mac_monitor_stop(struct ath12k *ar)
@@ -7370,6 +7376,11 @@ static void ath12k_mac_op_tx(struct ieee80211_hw *hw,
        u8 link_id;
        int ret;
 
+       if (ahvif->vdev_type == WMI_VDEV_TYPE_MONITOR) {
+               ieee80211_free_txskb(hw, skb);
+               return;
+       }
+
        link_id = u32_get_bits(info->control.flags, IEEE80211_TX_CTRL_MLO_LINK);
        memset(skb_cb, 0, sizeof(*skb_cb));
        skb_cb->vif = vif;
@@ -8117,6 +8128,12 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif)
 
        lockdep_assert_wiphy(hw->wiphy);
 
+       /* In NO_VIRTUAL_MONITOR, its necessary to restrict only one monitor
+        * interface in each radio
+        */
+       if (vif->type == NL80211_IFTYPE_MONITOR && ar->monitor_vdev_created)
+               return -EINVAL;
+
        /* If no link is active and scan vdev is requested
         * use a default link conf for scan address purpose.
         */
@@ -8272,6 +8289,9 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif)
                        goto err_peer_del;
                }
                break;
+       case WMI_VDEV_TYPE_MONITOR:
+               ar->monitor_vdev_created = true;
+               break;
        default:
                break;
        }
@@ -8315,6 +8335,11 @@ err_peer_del:
        }
 
 err_vdev_del:
+       if (ahvif->vdev_type == WMI_VDEV_TYPE_MONITOR) {
+               ar->monitor_vdev_id = -1;
+               ar->monitor_vdev_created = false;
+       }
+
        ath12k_wmi_vdev_delete(ar, arvif->vdev_id);
        ar->num_created_vdevs--;
        arvif->is_created = false;
@@ -11222,6 +11247,7 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)
        ieee80211_hw_set(hw, QUEUE_CONTROL);
        ieee80211_hw_set(hw, SUPPORTS_TX_FRAG);
        ieee80211_hw_set(hw, REPORTS_LOW_ACK);
+       ieee80211_hw_set(hw, NO_VIRTUAL_MONITOR);
 
        if ((ht_cap & WMI_HT_CAP_ENABLED) || is_6ghz) {
                ieee80211_hw_set(hw, AMPDU_AGGREGATION);
@@ -11420,6 +11446,10 @@ static void ath12k_mac_setup(struct ath12k *ar)
 
        wiphy_work_init(&ar->wmi_mgmt_tx_work, ath12k_mgmt_over_wmi_tx_work);
        skb_queue_head_init(&ar->wmi_mgmt_tx_queue);
+
+       ar->monitor_vdev_id = -1;
+       ar->monitor_vdev_created = false;
+       ar->monitor_started = false;
 }
 
 static int __ath12k_mac_mlo_setup(struct ath12k *ar)