ath10k: Wait for peer delete response to synchronize with fw

Peer creation in firmware fails if last peer deletion is still
in progress.
Wait for peer delete response from firmware after deleting peer
from host driver.

CRs-Fixed: 2047126
Change-Id: I9eb01393d9cd3dd82f2084262c250081f2076b46
Signed-off-by: Ashutosh Kumar <askuma@codeaurora.org>
This commit is contained in:
Ashutosh Kumar 2017-05-16 18:10:22 +05:30 committed by Ashutosh Kumar
parent f19eadaabe
commit cbcff09e2f
5 changed files with 27 additions and 0 deletions

View file

@ -2375,6 +2375,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
init_completion(&ar->vdev_setup_done);
init_completion(&ar->thermal.wmi_sync);
init_completion(&ar->bss_survey_done);
init_completion(&ar->peer_delete_done);
INIT_DELAYED_WORK(&ar->scan.timeout, ath10k_scan_timeout_work);

View file

@ -957,6 +957,7 @@ struct ath10k {
struct fw_flag *fw_flags;
/* set for bmi chip sets */
struct completion peer_delete_done;
bool is_bmi;
/* must be last */
u8 drv_priv[0] __aligned(sizeof(void *));

View file

@ -782,6 +782,7 @@ static int ath10k_mac_set_rts(struct ath10k_vif *arvif, u32 value)
static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr)
{
int ret;
unsigned long time_left;
lockdep_assert_held(&ar->conf_mutex);
@ -793,6 +794,16 @@ static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr)
if (ret)
return ret;
if (QCA_REV_WCN3990(ar)) {
time_left = wait_for_completion_timeout(&ar->peer_delete_done,
5 * HZ);
if (time_left == 0) {
ath10k_warn(ar, "Timeout in receiving peer delete response\n");
return -ETIMEDOUT;
}
}
ar->num_peers--;
return 0;

View file

@ -412,6 +412,15 @@ static int ath10k_wmi_tlv_event_tx_pause(struct ath10k *ar,
return 0;
}
static int ath10k_wmi_tlv_event_peer_delete_resp(struct ath10k *ar,
struct sk_buff *skb)
{
ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TLV_PEER_DELETE_RESP_EVENTID\n");
complete(&ar->peer_delete_done);
return 0;
}
/***********/
/* TLV ops */
/***********/
@ -552,6 +561,9 @@ static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb)
case WMI_TLV_TX_PAUSE_EVENTID:
ath10k_wmi_tlv_event_tx_pause(ar, skb);
break;
case WMI_TLV_PEER_DELETE_RESP_EVENTID:
ath10k_wmi_tlv_event_peer_delete_resp(ar, skb);
break;
default:
ath10k_dbg(ar, ATH10K_DBG_WMI, "Unknown eventid: %d\n", id);
break;

View file

@ -313,6 +313,8 @@ enum wmi_tlv_event_id {
WMI_TLV_PEER_TX_FAIL_CNT_THR_EVENTID,
WMI_TLV_PEER_ESTIMATED_LINKSPEED_EVENTID,
WMI_TLV_PEER_STATE_EVENTID,
WMI_TLV_PEER_ASSOC_CONF_EVENTID,
WMI_TLV_PEER_DELETE_RESP_EVENTID,
WMI_TLV_MGMT_RX_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_MGMT),
WMI_TLV_HOST_SWBA_EVENTID,
WMI_TLV_TBTTOFFSET_UPDATE_EVENTID,