ath11k: Add htt cmd to enable full monitor mode
authorAnilkumar Kolli <akolli@codeaurora.org>
Wed, 8 Dec 2021 08:44:00 +0000 (10:44 +0200)
committerKalle Valo <quic_kvalo@quicinc.com>
Thu, 9 Dec 2021 08:10:31 +0000 (10:10 +0200)
A new hw_param full_monitor_mode is added to enable full
monitor support for QCN9074.
HTT_H2T_MSG_TYPE_RX_FULL_MONITOR_MODE cmd is sent to FW
to enable the full monitor mode.

Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1-01734-QCAHKSWPL_SILICONZ-1

Signed-off-by: Anilkumar Kolli <akolli@codeaurora.org>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://lore.kernel.org/r/1638881695-22155-2-git-send-email-akolli@codeaurora.org
drivers/net/wireless/ath/ath11k/core.c
drivers/net/wireless/ath/ath11k/dp.h
drivers/net/wireless/ath/ath11k/dp_tx.c
drivers/net/wireless/ath/ath11k/dp_tx.h
drivers/net/wireless/ath/ath11k/hw.h

index 80cfc365b3f39828cfa1b1310ca02b27380b25fe..1d983fde6fc91ce3093bc12523ce7cda69c58df2 100644 (file)
@@ -74,6 +74,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
                                        BIT(NL80211_IFTYPE_AP) |
                                        BIT(NL80211_IFTYPE_MESH_POINT),
                .supports_monitor = true,
+               .full_monitor_mode = false,
                .supports_shadow_regs = false,
                .idle_ps = false,
                .supports_sta_ps = false,
@@ -128,6 +129,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
                                        BIT(NL80211_IFTYPE_AP) |
                                        BIT(NL80211_IFTYPE_MESH_POINT),
                .supports_monitor = true,
+               .full_monitor_mode = false,
                .supports_shadow_regs = false,
                .idle_ps = false,
                .supports_sta_ps = false,
@@ -181,6 +183,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
                .interface_modes = BIT(NL80211_IFTYPE_STATION) |
                                        BIT(NL80211_IFTYPE_AP),
                .supports_monitor = false,
+               .full_monitor_mode = false,
                .supports_shadow_regs = true,
                .idle_ps = true,
                .supports_sta_ps = true,
@@ -234,6 +237,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
                                        BIT(NL80211_IFTYPE_AP) |
                                        BIT(NL80211_IFTYPE_MESH_POINT),
                .supports_monitor = true,
+               .full_monitor_mode = true,
                .supports_shadow_regs = false,
                .idle_ps = false,
                .supports_sta_ps = false,
@@ -287,6 +291,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
                .interface_modes = BIT(NL80211_IFTYPE_STATION) |
                                        BIT(NL80211_IFTYPE_AP),
                .supports_monitor = false,
+               .full_monitor_mode = false,
                .supports_shadow_regs = true,
                .idle_ps = true,
                .supports_sta_ps = true,
index a4c36a9be338a7bbfaaa97c567b19a76a419f40c..10f234b3f11c62ca427e25a2038c3e9950b92808 100644 (file)
@@ -292,6 +292,7 @@ enum htt_h2t_msg_type {
        HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG  = 0xc,
        HTT_H2T_MSG_TYPE_EXT_STATS_CFG          = 0x10,
        HTT_H2T_MSG_TYPE_PPDU_STATS_CFG         = 0x11,
+       HTT_H2T_MSG_TYPE_RX_FULL_MONITOR_MODE   = 0x17,
 };
 
 #define HTT_VER_REQ_INFO_MSG_ID                GENMASK(7, 0)
@@ -957,6 +958,33 @@ struct htt_rx_ring_tlv_filter {
        u32 pkt_filter_flags3; /* DATA */
 };
 
+#define HTT_RX_FULL_MON_MODE_CFG_CMD_INFO0_MSG_TYPE    GENMASK(7, 0)
+#define HTT_RX_FULL_MON_MODE_CFG_CMD_INFO0_PDEV_ID     GENMASK(15, 8)
+
+#define HTT_RX_FULL_MON_MODE_CFG_CMD_CFG_ENABLE                        BIT(0)
+#define HTT_RX_FULL_MON_MODE_CFG_CMD_CFG_ZERO_MPDUS_END                BIT(1)
+#define HTT_RX_FULL_MON_MODE_CFG_CMD_CFG_NON_ZERO_MPDUS_END    BIT(2)
+#define HTT_RX_FULL_MON_MODE_CFG_CMD_CFG_RELEASE_RING          GENMASK(10, 3)
+
+/**
+ * Enumeration for full monitor mode destination ring select
+ * 0 - REO destination ring select
+ * 1 - FW destination ring select
+ * 2 - SW destination ring select
+ * 3 - Release destination ring select
+ */
+enum htt_rx_full_mon_release_ring {
+       HTT_RX_MON_RING_REO,
+       HTT_RX_MON_RING_FW,
+       HTT_RX_MON_RING_SW,
+       HTT_RX_MON_RING_RELEASE,
+};
+
+struct htt_rx_full_monitor_mode_cfg_cmd {
+       u32 info0;
+       u32 cfg;
+} __packed;
+
 /* HTT message target->host */
 
 enum htt_t2h_msg_type {
index 7587e1679ec3fc6621b5f60b0e78daa3c94b237f..8560f3b33812d53e4550a3bdb4f8980a715ea824 100644 (file)
@@ -1033,6 +1033,15 @@ int ath11k_dp_tx_htt_monitor_mode_ring_config(struct ath11k *ar, bool reset)
        struct htt_rx_ring_tlv_filter tlv_filter = {0};
        int ret = 0, ring_id = 0, i;
 
+       if (ab->hw_params.full_monitor_mode) {
+               ret = ath11k_dp_tx_htt_rx_full_mon_setup(ab,
+                                                        dp->mac_id, !reset);
+               if (ret < 0) {
+                       ath11k_err(ab, "failed to setup full monitor %d\n", ret);
+                       return ret;
+               }
+       }
+
        ring_id = dp->rxdma_mon_buf_ring.refill_buf_ring.ring_id;
 
        if (!reset) {
@@ -1098,3 +1107,42 @@ int ath11k_dp_tx_htt_monitor_mode_ring_config(struct ath11k *ar, bool reset)
 
        return ret;
 }
+
+int ath11k_dp_tx_htt_rx_full_mon_setup(struct ath11k_base *ab, int mac_id,
+                                      bool config)
+{
+       struct htt_rx_full_monitor_mode_cfg_cmd *cmd;
+       struct sk_buff *skb;
+       int ret, len = sizeof(*cmd);
+
+       skb = ath11k_htc_alloc_skb(ab, len);
+       if (!skb)
+               return -ENOMEM;
+
+       skb_put(skb, len);
+       cmd = (struct htt_rx_full_monitor_mode_cfg_cmd *)skb->data;
+       memset(cmd, 0, sizeof(*cmd));
+       cmd->info0 = FIELD_PREP(HTT_RX_FULL_MON_MODE_CFG_CMD_INFO0_MSG_TYPE,
+                               HTT_H2T_MSG_TYPE_RX_FULL_MONITOR_MODE);
+
+       cmd->info0 |= FIELD_PREP(HTT_RX_FULL_MON_MODE_CFG_CMD_INFO0_PDEV_ID, mac_id);
+
+       cmd->cfg = HTT_RX_FULL_MON_MODE_CFG_CMD_CFG_ENABLE |
+                  FIELD_PREP(HTT_RX_FULL_MON_MODE_CFG_CMD_CFG_RELEASE_RING,
+                             HTT_RX_MON_RING_SW);
+       if (config) {
+               cmd->cfg |= HTT_RX_FULL_MON_MODE_CFG_CMD_CFG_ZERO_MPDUS_END |
+                           HTT_RX_FULL_MON_MODE_CFG_CMD_CFG_NON_ZERO_MPDUS_END;
+       }
+
+       ret = ath11k_htc_send(&ab->htc, ab->dp.eid, skb);
+       if (ret)
+               goto err_free;
+
+       return 0;
+
+err_free:
+       dev_kfree_skb_any(skb);
+
+       return ret;
+}
index 698b907b878d7e65a7173c7cd2f83fbadc63da86..e373dbccf417c7f0c5b69e6532bcad8b6b5b38b0 100644 (file)
@@ -37,4 +37,6 @@ int ath11k_dp_tx_htt_rx_filter_setup(struct ath11k_base *ab, u32 ring_id,
                                     int rx_buf_size,
                                     struct htt_rx_ring_tlv_filter *tlv_filter);
 
+int ath11k_dp_tx_htt_rx_full_mon_setup(struct ath11k_base *ab, int mac_id,
+                                      bool config);
 #endif
index 2c9d232ebfedf4911aa4a6e0f49385fa3142a615..fe6e0cb9476cc210540d027ecf39d32ebb6ff7a7 100644 (file)
@@ -168,6 +168,7 @@ struct ath11k_hw_params {
 
        u16 interface_modes;
        bool supports_monitor;
+       bool full_monitor_mode;
        bool supports_shadow_regs;
        bool idle_ps;
        bool supports_sta_ps;