diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath10k/mac.c')
| -rw-r--r-- | drivers/net/wireless/ath/ath10k/mac.c | 41 |
1 files changed, 39 insertions, 2 deletions
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 572c03667110..24ac525df318 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -693,6 +693,26 @@ ath10k_mac_get_any_chandef_iter(struct ieee80211_hw *hw, *def = &conf->def; } +static void ath10k_wait_for_peer_delete_done(struct ath10k *ar, u32 vdev_id, + const u8 *addr) +{ + unsigned long time_left; + int ret; + + if (test_bit(WMI_SERVICE_SYNC_DELETE_CMDS, ar->wmi.svc_map)) { + ret = ath10k_wait_for_peer_deleted(ar, vdev_id, addr); + if (ret) { + ath10k_warn(ar, "failed wait for peer deleted"); + return; + } + + time_left = wait_for_completion_timeout(&ar->peer_delete_done, + 5 * HZ); + if (!time_left) + ath10k_warn(ar, "Timeout in receiving peer delete response\n"); + } +} + static int ath10k_peer_create(struct ath10k *ar, struct ieee80211_vif *vif, struct ieee80211_sta *sta, @@ -737,7 +757,7 @@ static int ath10k_peer_create(struct ath10k *ar, spin_unlock_bh(&ar->data_lock); ath10k_warn(ar, "failed to find peer %pM on vdev %i after creation\n", addr, vdev_id); - ath10k_wmi_peer_delete(ar, vdev_id, addr); + ath10k_wait_for_peer_delete_done(ar, vdev_id, addr); return -ENOENT; } @@ -819,6 +839,18 @@ static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr) if (ret) return ret; + if (test_bit(WMI_SERVICE_SYNC_DELETE_CMDS, ar->wmi.svc_map)) { + unsigned long time_left; + + time_left = wait_for_completion_timeout + (&ar->peer_delete_done, 5 * HZ); + + if (!time_left) { + ath10k_warn(ar, "Timeout in receiving peer delete response\n"); + return -ETIMEDOUT; + } + } + ar->num_peers--; return 0; @@ -5423,8 +5455,11 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, err_peer_delete: if (arvif->vdev_type == WMI_VDEV_TYPE_AP || - arvif->vdev_type == WMI_VDEV_TYPE_IBSS) + arvif->vdev_type == WMI_VDEV_TYPE_IBSS) { ath10k_wmi_peer_delete(ar, arvif->vdev_id, vif->addr); + ath10k_wait_for_peer_delete_done(ar, arvif->vdev_id, + vif->addr); + } err_vdev_delete: ath10k_wmi_vdev_delete(ar, arvif->vdev_id); @@ -5490,6 +5525,8 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, ath10k_warn(ar, "failed to submit AP/IBSS self-peer removal on vdev %i: %d\n", arvif->vdev_id, ret); + ath10k_wait_for_peer_delete_done(ar, arvif->vdev_id, + vif->addr); kfree(arvif->u.ap.noa_data); } |
