Merge "ath10k: wait for vdev delete response from firmware"

This commit is contained in:
Linux Build Service Account 2017-06-23 05:56:57 -07:00 committed by Gerrit - the friendly Code Review server
commit bbf9eb8202
7 changed files with 32 additions and 1 deletions

View file

@ -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);

View file

@ -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 */

View file

@ -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.
*/

View file

@ -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;

View file

@ -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,

View file

@ -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)

View file

@ -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);