Commit aa44b2f3 authored by Carl Huang's avatar Carl Huang Committed by Kalle Valo

ath11k: start vdev if a bss peer is already created

For QCA6390, bss peer must be created before vdev is to start. This
change is to start vdev if a bss peer is created. Otherwise, ath11k
delays to start vdev.

This fixes an issue in a case where HT/VHT/HE settings change between
authentication and association, e.g., due to the user space request
to disable HT.

Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
Signed-off-by: default avatarCarl Huang <cjhuang@codeaurora.org>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20201211051358.9191-1-cjhuang@codeaurora.org
parent 35970106
...@@ -3021,6 +3021,7 @@ static int ath11k_mac_station_add(struct ath11k *ar, ...@@ -3021,6 +3021,7 @@ static int ath11k_mac_station_add(struct ath11k *ar,
} }
if (ab->hw_params.vdev_start_delay && if (ab->hw_params.vdev_start_delay &&
!arvif->is_started &&
arvif->vdev_type != WMI_VDEV_TYPE_AP) { arvif->vdev_type != WMI_VDEV_TYPE_AP) {
ret = ath11k_start_vdev_delay(ar->hw, vif); ret = ath11k_start_vdev_delay(ar->hw, vif);
if (ret) { if (ret) {
...@@ -5284,7 +5285,8 @@ ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, ...@@ -5284,7 +5285,8 @@ ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
/* for QCA6390 bss peer must be created before vdev_start */ /* for QCA6390 bss peer must be created before vdev_start */
if (ab->hw_params.vdev_start_delay && if (ab->hw_params.vdev_start_delay &&
arvif->vdev_type != WMI_VDEV_TYPE_AP && arvif->vdev_type != WMI_VDEV_TYPE_AP &&
arvif->vdev_type != WMI_VDEV_TYPE_MONITOR) { arvif->vdev_type != WMI_VDEV_TYPE_MONITOR &&
!ath11k_peer_find_by_vdev_id(ab, arvif->vdev_id)) {
memcpy(&arvif->chanctx, ctx, sizeof(*ctx)); memcpy(&arvif->chanctx, ctx, sizeof(*ctx));
ret = 0; ret = 0;
goto out; goto out;
...@@ -5295,7 +5297,9 @@ ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, ...@@ -5295,7 +5297,9 @@ ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
goto out; goto out;
} }
if (ab->hw_params.vdev_start_delay) { if (ab->hw_params.vdev_start_delay &&
(arvif->vdev_type == WMI_VDEV_TYPE_AP ||
arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)) {
param.vdev_id = arvif->vdev_id; param.vdev_id = arvif->vdev_id;
param.peer_type = WMI_PEER_TYPE_DEFAULT; param.peer_type = WMI_PEER_TYPE_DEFAULT;
param.peer_addr = ar->mac_addr; param.peer_addr = ar->mac_addr;
......
...@@ -76,6 +76,23 @@ struct ath11k_peer *ath11k_peer_find_by_id(struct ath11k_base *ab, ...@@ -76,6 +76,23 @@ struct ath11k_peer *ath11k_peer_find_by_id(struct ath11k_base *ab,
return NULL; return NULL;
} }
struct ath11k_peer *ath11k_peer_find_by_vdev_id(struct ath11k_base *ab,
int vdev_id)
{
struct ath11k_peer *peer;
spin_lock_bh(&ab->base_lock);
list_for_each_entry(peer, &ab->peers, list) {
if (vdev_id == peer->vdev_id) {
spin_unlock_bh(&ab->base_lock);
return peer;
}
}
spin_unlock_bh(&ab->base_lock);
return NULL;
}
void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id) void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id)
{ {
struct ath11k_peer *peer; struct ath11k_peer *peer;
......
...@@ -43,5 +43,7 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif, ...@@ -43,5 +43,7 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif,
struct ieee80211_sta *sta, struct peer_create_params *param); struct ieee80211_sta *sta, struct peer_create_params *param);
int ath11k_wait_for_peer_delete_done(struct ath11k *ar, u32 vdev_id, int ath11k_wait_for_peer_delete_done(struct ath11k *ar, u32 vdev_id,
const u8 *addr); const u8 *addr);
struct ath11k_peer *ath11k_peer_find_by_vdev_id(struct ath11k_base *ab,
int vdev_id);
#endif /* _PEER_H_ */ #endif /* _PEER_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment