ath10k: Add peer delete response event
Peer creation in firmware fails if last peer deletion is still in progress. The firmware sends a peer delete response event if it advertises the service WMI_SERVICE_SYNC_DELETE_CMDS. This peer delete response event is used to synchronize the peer deletion. Add peer delete response event and wait for the event after deleting every peer from host driver to synchronize with firmware. Tested HW: WCN3990 Tested FW: WLAN.HL.2.0-01188-QCAHLSWMTPLZ-1 Signed-off-by: Dundi Raviteja <dundi@codeaurora.org> Signed-off-by: Rakesh Pillai <pillair@codeaurora.org> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:

committed by
Kalle Valo

parent
fe36e70f76
commit
c6f537a11b
@@ -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);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user