summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath11k/mac.c
diff options
context:
space:
mode:
authorCarl Huang <cjhuang@codeaurora.org>2020-08-17 13:31:53 +0300
committerKalle Valo <kvalo@codeaurora.org>2020-08-18 12:46:58 +0300
commite7495035286aae68e5cc67f842c3e8bcc4483352 (patch)
tree418acb06138260e3061b6cd2d674515f7081e3e7 /drivers/net/wireless/ath/ath11k/mac.c
parent84eee3c845d377cbe1cae722e8f83344107d709f (diff)
ath11k: delay vdev_start for QCA6390
For QCA6390 firmware, bss peer must be created before vdev_start, so delay vdev_start until bss peer is created. Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1 Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.1.0.1-01238-QCAHKSWPL_SILICONZ-2 Signed-off-by: Carl Huang <cjhuang@codeaurora.org> Signed-off-by: Kalle Valo <kvalo@codeaurora.org> Link: https://lore.kernel.org/r/1597555891-26112-6-git-send-email-kvalo@codeaurora.org
Diffstat (limited to 'drivers/net/wireless/ath/ath11k/mac.c')
-rw-r--r--drivers/net/wireless/ath/ath11k/mac.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index 5aae1ec27e9f..9759a5db39fc 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -244,6 +244,9 @@ static const u32 ath11k_smps_map[] = {
[WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE,
};
+static int ath11k_start_vdev_delay(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif);
+
u8 ath11k_mac_bw_to_mac80211_bw(u8 bw)
{
u8 ret = 0;
@@ -2960,6 +2963,14 @@ static int ath11k_mac_station_add(struct ath11k *ar,
goto free_tx_stats;
}
+ if (ab->hw_params.vdev_start_delay) {
+ ret = ath11k_start_vdev_delay(ar->hw, vif);
+ if (ret) {
+ ath11k_warn(ab, "failed to delay vdev start: %d\n", ret);
+ goto free_tx_stats;
+ }
+ }
+
return 0;
free_tx_stats:
@@ -5116,6 +5127,39 @@ unlock:
mutex_unlock(&ar->conf_mutex);
}
+static int ath11k_start_vdev_delay(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct ath11k *ar = hw->priv;
+ struct ath11k_base *ab = ar->ab;
+ struct ath11k_vif *arvif = (void *)vif->drv_priv;
+ int ret;
+
+ if (WARN_ON(arvif->is_started))
+ return -EBUSY;
+
+ ret = ath11k_mac_vdev_start(arvif, &arvif->chanctx.def);
+ if (ret) {
+ ath11k_warn(ab, "failed to start vdev %i addr %pM on freq %d: %d\n",
+ arvif->vdev_id, vif->addr,
+ arvif->chanctx.def.chan->center_freq, ret);
+ return ret;
+ }
+
+ if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) {
+ ret = ath11k_monitor_vdev_up(ar, arvif->vdev_id);
+ if (ret) {
+ ath11k_warn(ab, "failed put monitor up: %d\n", ret);
+ return ret;
+ }
+ }
+
+ arvif->is_started = true;
+
+ /* TODO: Setup ps and cts/rts protection */
+ return 0;
+}
+
static int
ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
@@ -5132,6 +5176,13 @@ ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
"mac chanctx assign ptr %pK vdev_id %i\n",
ctx, arvif->vdev_id);
+ /* for QCA6390 bss peer must be created before vdev_start */
+ if (ab->hw_params.vdev_start_delay) {
+ memcpy(&arvif->chanctx, ctx, sizeof(*ctx));
+ mutex_unlock(&ar->conf_mutex);
+ return 0;
+ }
+
if (WARN_ON(arvif->is_started)) {
mutex_unlock(&ar->conf_mutex);
return -EBUSY;