wlan-ap-Telecominfraproject/feeds/ipq95xx/mac80211/patches/qca/640-001-ath12k-Enable-monitor-interface-support.patch
John Crispin 144c5d00f4 ipq95xx/mac80211: update to ATH12.3-CS
Signed-off-by: John Crispin <john@phrozen.org>
2024-02-28 18:56:21 +01:00

315 lines
10 KiB
Diff

From e0fe0badf88df8e2035f18f852c6ee7e90cc1e5b Mon Sep 17 00:00:00 2001
From: P Praneesh <quic_ppranees@quicinc.com>
Date: Wed, 8 Jun 2022 16:49:01 +0530
Subject: [PATCH 1/4] ath12k: Enable monitor interface support
mac80211 enables monitor interface based on the hardware flag
advertised by the driver. Set WANT_MONITOR_VIF hardware flag
during MAC allocation. Also, add seperate flags for representing
various monitor vdev state machine.
Signed-off-by: P Praneesh <quic_ppranees@quicinc.com>
---
drivers/net/wireless/ath/ath12k/core.c | 2 +-
drivers/net/wireless/ath/ath12k/core.h | 7 ++-
drivers/net/wireless/ath/ath12k/dp_mon.c | 2 +-
drivers/net/wireless/ath/ath12k/mac.c | 73 +++++++++++++++++++++-----------
4 files changed, 53 insertions(+), 31 deletions(-)
--- a/drivers/net/wireless/ath/ath12k/core.c
+++ b/drivers/net/wireless/ath/ath12k/core.c
@@ -827,6 +827,10 @@ static void ath12k_core_restart(struct w
ath12k_mac_tx_mgmt_pending_free, ar);
idr_destroy(&ar->txmgmt_idr);
wake_up(&ar->txmgmt_empty_waitq);
+
+ ar->monitor_vdev_id = -1;
+ clear_bit(MONITOR_VDEV_STARTED, &ar->monitor_flags);
+ clear_bit(MONITOR_VDEV_CREATED, &ar->monitor_flags);
}
wake_up(&ab->wmi_ab.tx_credits_wq);
--- a/drivers/net/wireless/ath/ath12k/core.h
+++ b/drivers/net/wireless/ath/ath12k/core.h
@@ -208,7 +208,9 @@ enum ath12k_dev_flags {
};
enum ath12k_monitor_flags {
- ATH12K_FLAG_MONITOR_ENABLED,
+ MONITOR_VDEV_CREATED,
+ MONITOR_VDEV_STARTED,
+ MONITOR_CONF_ENABLED,
};
struct ath12k_fw_vdev_ol_stats {
@@ -710,9 +712,6 @@ struct ath12k {
#endif
bool dfs_block_radar_events;
struct ath12k_thermal thermal;
- bool monitor_conf_enabled;
- bool monitor_vdev_created;
- bool monitor_started;
int monitor_vdev_id;
u8 twt_enabled;
s8 max_allowed_tx_power;
--- a/drivers/net/wireless/ath/ath12k/dp_mon.c
+++ b/drivers/net/wireless/ath/ath12k/dp_mon.c
@@ -2608,7 +2608,7 @@ int ath12k_dp_mon_process_ring(struct at
struct ath12k *ar = ath12k_ab_to_ar(ab, mac_id);
int num_buffs_reaped = 0;
- if (!ar->monitor_started)
+ if (!test_bit(MONITOR_VDEV_STARTED, &ar->monitor_flags))
num_buffs_reaped = ath12k_dp_mon_rx_process_stats(ar, mac_id,
napi, &budget);
else
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -980,7 +980,7 @@ static int ath12k_mac_monitor_vdev_creat
lockdep_assert_held(&ar->conf_mutex);
- if (ar->monitor_vdev_created)
+ if (test_bit(MONITOR_VDEV_CREATED, &ar->monitor_flags))
return 0;
memset(&param, 0, sizeof(param));
@@ -1034,7 +1034,8 @@ static int ath12k_mac_monitor_vdev_creat
ar->allocated_vdev_map |= 1LL << ar->monitor_vdev_id;
ar->ab->free_vdev_map &= ~(1LL << ar->monitor_vdev_id);
ar->num_created_vdevs++;
- ar->monitor_vdev_created = true;
+ set_bit(MONITOR_VDEV_CREATED, &ar->monitor_flags);
+
ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac monitor vdev %d created\n",
ar->monitor_vdev_id);
@@ -1048,7 +1049,7 @@ static int ath12k_mac_monitor_vdev_delet
lockdep_assert_held(&ar->conf_mutex);
- if (!ar->monitor_vdev_created)
+ if (!test_bit(MONITOR_VDEV_CREATED, &ar->monitor_flags))
return 0;
reinit_completion(&ar->vdev_delete_done);
@@ -1071,7 +1072,7 @@ static int ath12k_mac_monitor_vdev_delet
ar->monitor_vdev_id);
ar->num_created_vdevs--;
ar->monitor_vdev_id = -1;
- ar->monitor_vdev_created = false;
+ clear_bit(MONITOR_VDEV_CREATED, &ar->monitor_flags);
}
return ret;
@@ -1094,7 +1095,7 @@ static int ath12k_mac_monitor_start(stru
lockdep_assert_held(&ar->conf_mutex);
- if (ar->monitor_started)
+ if (test_bit(MONITOR_VDEV_STARTED, &ar->monitor_flags))
return 0;
ieee80211_iter_chan_contexts_atomic(ar->hw,
@@ -1110,9 +1111,16 @@ static int ath12k_mac_monitor_start(stru
return ret;
}
- ar->monitor_started = true;
- ar->num_started_vdevs++;
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;
+ }
+
+ set_bit(MONITOR_VDEV_STARTED, &ar->monitor_flags);
+ ar->num_started_vdevs++;
+
ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac monitor started ret %d\n", ret);
return ret;
@@ -1124,7 +1132,7 @@ static int ath12k_mac_monitor_stop(struc
lockdep_assert_held(&ar->conf_mutex);
- if (!ar->monitor_started)
+ if (!test_bit(MONITOR_VDEV_STARTED, &ar->monitor_flags))
return 0;
ret = ath12k_mac_monitor_vdev_stop(ar);
@@ -1133,7 +1141,7 @@ static int ath12k_mac_monitor_stop(struc
return ret;
}
- ar->monitor_started = false;
+ clear_bit(MONITOR_VDEV_STARTED, &ar->monitor_flags);
ar->num_started_vdevs--;
ret = ath12k_dp_tx_htt_monitor_mode_ring_config(ar, true);
ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac monitor stopped ret %d\n", ret);
@@ -1149,10 +1157,12 @@ static int ath12k_mac_op_config(struct i
mutex_lock(&ar->conf_mutex);
if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
- ar->monitor_conf_enabled = conf->flags & IEEE80211_CONF_MONITOR;
- if (ar->monitor_conf_enabled) {
- if (ar->monitor_vdev_created)
+ if (conf->flags & IEEE80211_CONF_MONITOR) {
+ set_bit(MONITOR_CONF_ENABLED, &ar->monitor_flags);
+ if (test_bit(MONITOR_VDEV_CREATED,
+ &ar->monitor_flags))
goto exit;
+
ret = ath12k_mac_monitor_vdev_create(ar);
if (ret)
goto exit;
@@ -1160,8 +1170,11 @@ static int ath12k_mac_op_config(struct i
if (ret)
goto err_mon_del;
} else {
- if (!ar->monitor_vdev_created)
+ clear_bit(MONITOR_CONF_ENABLED, &ar->monitor_flags);
+ if (!test_bit(MONITOR_VDEV_CREATED,
+ &ar->monitor_flags))
goto exit;
+
ret = ath12k_mac_monitor_stop(ar);
if (ret)
goto exit;
@@ -3394,7 +3407,7 @@ static int ath12k_mac_config_obss_pd(str
/* Set and enable SRG/non-SRG OBSS PD Threshold */
param_id = WMI_PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD;
- if (test_bit(ATH12K_FLAG_MONITOR_ENABLED, &ar->monitor_flags)) {
+ if (test_bit(MONITOR_CONF_ENABLED, &ar->monitor_flags)) {
ret = ath12k_wmi_pdev_set_param(ar, param_id, 0, pdev_id);
if (ret)
ath12k_warn(ar->ab,
@@ -6806,6 +6819,9 @@ static int ath12k_mac_op_add_interface(s
goto err_peer_del;
}
break;
+ case WMI_VDEV_TYPE_MONITOR:
+ set_bit(MONITOR_VDEV_CREATED, &ar->monitor_flags);
+ break;
default:
break;
}
@@ -6828,7 +6844,8 @@ static int ath12k_mac_op_add_interface(s
ath12k_mac_ap_ps_recalc(ar);
- if (vif->type != NL80211_IFTYPE_MONITOR && ar->monitor_conf_enabled)
+ if (vif->type != NL80211_IFTYPE_MONITOR &&
+ test_bit(MONITOR_CONF_ENABLED, &ar->monitor_flags))
ath12k_mac_monitor_vdev_create(ar);
ret = ath12k_debugfs_add_interface(arvif);
@@ -6945,8 +6962,9 @@ static void ath12k_mac_op_remove_interfa
if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) {
ar->monitor_vdev_id = -1;
- ar->monitor_vdev_created = false;
- } else if (ar->monitor_vdev_created && !ar->monitor_started) {
+ clear_bit(MONITOR_VDEV_CREATED, &ar->monitor_flags);
+ } else if (test_bit(MONITOR_VDEV_CREATED, &ar->monitor_flags) &&
+ !test_bit(MONITOR_VDEV_STARTED, &ar->monitor_flags)) {
ret = ath12k_mac_monitor_vdev_delete(ar);
}
@@ -6975,7 +6993,7 @@ err_vdev_del:
/* Recalc txpower for remaining vdev */
ath12k_mac_txpower_recalc(ar);
ath12k_mac_ap_ps_recalc(ar);
- clear_bit(ATH12K_FLAG_MONITOR_ENABLED, &ar->monitor_flags);
+ clear_bit(MONITOR_CONF_ENABLED, &ar->monitor_flags);
ath12k_debugfs_remove_interface(arvif);
@@ -7003,7 +7021,6 @@ static void ath12k_mac_op_configure_filt
mutex_lock(&ar->conf_mutex);
- changed_flags &= SUPPORTED_FILTERS;
*total_flags &= SUPPORTED_FILTERS;
ar->filter_flags = *total_flags;
@@ -7478,7 +7495,8 @@ ath12k_mac_update_vif_chan(struct ath12k
}
/* Restart the internal monitor vdev on new channel */
- if (!monitor_vif && ar->monitor_vdev_created) {
+ if (!monitor_vif &&
+ test_bit(MONITOR_VDEV_CREATED, &ar->monitor_flags)) {
if (!ath12k_mac_monitor_stop(ar))
ath12k_mac_monitor_start(ar);
}
@@ -8167,7 +8185,7 @@ ath12k_mac_op_assign_vif_chanctx(struct
if (ab->hw_params->vdev_start_delay &&
(arvif->vdev_type == WMI_VDEV_TYPE_AP ||
- arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)) {
+ arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)) {
param.vdev_id = arvif->vdev_id;
param.peer_type = WMI_PEER_TYPE_DEFAULT;
param.peer_addr = ar->mac_addr;
@@ -8196,7 +8214,8 @@ ath12k_mac_op_assign_vif_chanctx(struct
goto out;
}
- if (arvif->vdev_type != WMI_VDEV_TYPE_MONITOR && ar->monitor_vdev_created)
+ if (arvif->vdev_type != WMI_VDEV_TYPE_MONITOR &&
+ test_bit(MONITOR_VDEV_CREATED, &ar->monitor_flags))
ath12k_mac_monitor_start(ar);
arvif->is_started = true;
@@ -8244,6 +8263,7 @@ ath12k_mac_op_unassign_vif_chanctx(struc
arvif->is_started = false;
mutex_unlock(&ar->conf_mutex);
+ return;
}
ret = ath12k_mac_vdev_stop(arvif);
@@ -8258,7 +8278,8 @@ ath12k_mac_op_unassign_vif_chanctx(struc
ath12k_wmi_vdev_down(ar, arvif->vdev_id);
if (arvif->vdev_type != WMI_VDEV_TYPE_MONITOR &&
- ar->num_started_vdevs == 1 && ar->monitor_vdev_created)
+ ar->num_started_vdevs == 1 &&
+ test_bit(MONITOR_VDEV_CREATED, &ar->monitor_flags))
ath12k_mac_monitor_stop(ar);
mutex_unlock(&ar->conf_mutex);
@@ -9692,6 +9713,7 @@ static int __ath12k_mac_register(struct
ieee80211_hw_set(ar->hw, SPECTRUM_MGMT);
ieee80211_hw_set(ar->hw, CONNECTION_MONITOR);
ieee80211_hw_set(ar->hw, SUPPORTS_PER_STA_GTK);
+ ieee80211_hw_set(ar->hw, WANT_MONITOR_VIF);
ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA);
ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG);
@@ -9928,7 +9950,9 @@ int ath12k_mac_allocate(struct ath12k_ba
INIT_WORK(&ar->wmi_mgmt_tx_work, ath12k_mgmt_over_wmi_tx_work);
skb_queue_head_init(&ar->wmi_mgmt_tx_queue);
- clear_bit(ATH12K_FLAG_MONITOR_ENABLED, &ar->monitor_flags);
+ clear_bit(MONITOR_VDEV_STARTED, &ar->monitor_flags);
+ ar->monitor_vdev_id = -1;
+ clear_bit(MONITOR_VDEV_CREATED, &ar->monitor_flags);
}
return 0;
--- a/drivers/net/wireless/ath/ath12k/hw.c
+++ b/drivers/net/wireless/ath/ath12k/hw.c
@@ -853,7 +853,7 @@ static const struct ath12k_hw_params ath
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_MESH_POINT),
- .supports_monitor = false,
+ .supports_monitor = true,
.idle_ps = false,
.cold_boot_calib = false,