ath10k: wait for vdev delete response from firmware
When we add an interface immediately after removing the interface the vdev deletion in firmware might not have been completed. We need to synchronize the vdev creation with the firmware. Wait for vdev delete response from firmware when we remove an interface. CRs-Fixed: 2065345 Change-Id: Id045087b03d5c5e6451f79b9c1177aca26ed34a2 Signed-off-by: Rakesh Pillai <pillair@codeaurora.org>
This commit is contained in:
parent
db478ca29d
commit
93692eab3a
7 changed files with 32 additions and 1 deletions
|
@ -1550,6 +1550,7 @@ static void ath10k_core_restart(struct work_struct *work)
|
|||
complete(&ar->offchan_tx_completed);
|
||||
complete(&ar->install_key_done);
|
||||
complete(&ar->vdev_setup_done);
|
||||
complete(&ar->vdev_delete_done);
|
||||
complete(&ar->thermal.wmi_sync);
|
||||
complete(&ar->bss_survey_done);
|
||||
wake_up(&ar->htt.empty_tx_wq);
|
||||
|
@ -2373,6 +2374,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
|
|||
|
||||
init_completion(&ar->install_key_done);
|
||||
init_completion(&ar->vdev_setup_done);
|
||||
init_completion(&ar->vdev_delete_done);
|
||||
init_completion(&ar->thermal.wmi_sync);
|
||||
init_completion(&ar->bss_survey_done);
|
||||
init_completion(&ar->peer_delete_done);
|
||||
|
|
|
@ -365,7 +365,8 @@ struct ath10k_sta {
|
|||
#endif
|
||||
};
|
||||
|
||||
#define ATH10K_VDEV_SETUP_TIMEOUT_HZ (5 * HZ)
|
||||
#define ATH10K_VDEV_SETUP_TIMEOUT_HZ (5 * HZ)
|
||||
#define ATH10K_VDEV_DELETE_TIMEOUT_HZ (5 * HZ)
|
||||
|
||||
enum ath10k_beacon_state {
|
||||
ATH10K_BEACON_SCHEDULED = 0,
|
||||
|
@ -853,6 +854,7 @@ struct ath10k {
|
|||
struct completion install_key_done;
|
||||
|
||||
struct completion vdev_setup_done;
|
||||
struct completion vdev_delete_done;
|
||||
|
||||
struct workqueue_struct *workqueue;
|
||||
/* Auxiliary workqueue */
|
||||
|
|
|
@ -994,6 +994,7 @@ static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
|
|||
arg.channel.max_antenna_gain = channel->max_antenna_gain * 2;
|
||||
|
||||
reinit_completion(&ar->vdev_setup_done);
|
||||
reinit_completion(&ar->vdev_delete_done);
|
||||
|
||||
ret = ath10k_wmi_vdev_start(ar, &arg);
|
||||
if (ret) {
|
||||
|
@ -1043,6 +1044,7 @@ static int ath10k_monitor_vdev_stop(struct ath10k *ar)
|
|||
ar->monitor_vdev_id, ret);
|
||||
|
||||
reinit_completion(&ar->vdev_setup_done);
|
||||
reinit_completion(&ar->vdev_delete_done);
|
||||
|
||||
ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
|
||||
if (ret)
|
||||
|
@ -1349,6 +1351,7 @@ static int ath10k_vdev_stop(struct ath10k_vif *arvif)
|
|||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
reinit_completion(&ar->vdev_setup_done);
|
||||
reinit_completion(&ar->vdev_delete_done);
|
||||
|
||||
ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id);
|
||||
if (ret) {
|
||||
|
@ -1385,6 +1388,7 @@ static int ath10k_vdev_start_restart(struct ath10k_vif *arvif,
|
|||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
reinit_completion(&ar->vdev_setup_done);
|
||||
reinit_completion(&ar->vdev_delete_done);
|
||||
|
||||
arg.vdev_id = arvif->vdev_id;
|
||||
arg.dtim_period = arvif->dtim_period;
|
||||
|
@ -5123,6 +5127,7 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
|
|||
struct ath10k *ar = hw->priv;
|
||||
struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
|
||||
struct ath10k_peer *peer;
|
||||
unsigned long time_left;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
|
@ -5162,6 +5167,16 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
|
|||
ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
|
||||
if (QCA_REV_WCN3990(ar)) {
|
||||
time_left = wait_for_completion_timeout(
|
||||
&ar->vdev_delete_done,
|
||||
ATH10K_VDEV_DELETE_TIMEOUT_HZ);
|
||||
if (time_left == 0) {
|
||||
ath10k_warn(ar, "Timeout in receiving vdev delete resp\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Some firmware revisions don't notify host about self-peer removal
|
||||
* until after associated vdev is deleted.
|
||||
*/
|
||||
|
|
|
@ -477,6 +477,9 @@ static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb)
|
|||
case WMI_TLV_VDEV_STOPPED_EVENTID:
|
||||
ath10k_wmi_event_vdev_stopped(ar, skb);
|
||||
break;
|
||||
case WMI_TLV_VDEV_DELETE_RESP_EVENTID:
|
||||
ath10k_wmi_event_vdev_delete_resp(ar, skb);
|
||||
break;
|
||||
case WMI_TLV_PEER_STA_KICKOUT_EVENTID:
|
||||
ath10k_wmi_event_peer_sta_kickout(ar, skb);
|
||||
break;
|
||||
|
|
|
@ -308,6 +308,8 @@ enum wmi_tlv_event_id {
|
|||
WMI_TLV_VDEV_STOPPED_EVENTID,
|
||||
WMI_TLV_VDEV_INSTALL_KEY_COMPLETE_EVENTID,
|
||||
WMI_TLV_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID,
|
||||
WMI_TLV_VDEV_TSF_REPORT_EVENTID,
|
||||
WMI_TLV_VDEV_DELETE_RESP_EVENTID,
|
||||
WMI_TLV_PEER_STA_KICKOUT_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_PEER),
|
||||
WMI_TLV_PEER_INFO_EVENTID,
|
||||
WMI_TLV_PEER_TX_FAIL_CNT_THR_EVENTID,
|
||||
|
|
|
@ -3120,6 +3120,12 @@ void ath10k_wmi_event_vdev_stopped(struct ath10k *ar, struct sk_buff *skb)
|
|||
complete(&ar->vdev_setup_done);
|
||||
}
|
||||
|
||||
void ath10k_wmi_event_vdev_delete_resp(struct ath10k *ar, struct sk_buff *skb)
|
||||
{
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_DELETE_RESP_EVENTID\n");
|
||||
complete(&ar->vdev_delete_done);
|
||||
}
|
||||
|
||||
static int
|
||||
ath10k_wmi_op_pull_peer_kick_ev(struct ath10k *ar, struct sk_buff *skb,
|
||||
struct wmi_peer_kick_ev_arg *arg)
|
||||
|
|
|
@ -6599,6 +6599,7 @@ int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb);
|
|||
void ath10k_wmi_event_update_stats(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_vdev_start_resp(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_vdev_stopped(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_vdev_delete_resp(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_peer_sta_kickout(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_tbttoffset_update(struct ath10k *ar, struct sk_buff *skb);
|
||||
|
|
Loading…
Add table
Reference in a new issue