mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-24 21:02:35 +00:00
315 lines
10 KiB
Diff
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(¶m, 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,
|