summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorRakesh Pillai <pillair@codeaurora.org>2019-06-03 10:41:33 -0400
committerKalle Valo <kvalo@codeaurora.org>2019-06-25 09:04:14 -0400
commitfe36e70f766ed99c5a140f8e265e81dd39897bb6 (patch)
tree985654a2aaa2888b9016f245aff67b4fbb2d8f9f /drivers/net/wireless
parent011d4111c8c602ea829fa4917af1818eb0500a90 (diff)
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. Tested HW: WCN3990 Tested FW: WLAN.HL.2.0-01188-QCAHLSWMTPLZ-1 Signed-off-by: Rakesh Pillai <pillair@codeaurora.org> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c4
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h6
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c15
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.c12
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.h6
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.h4
6 files changed, 41 insertions, 6 deletions
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index d5cb22e04a1e..c9aa90e1e565 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -2,7 +2,7 @@
2/* 2/*
3 * Copyright (c) 2005-2011 Atheros Communications Inc. 3 * Copyright (c) 2005-2011 Atheros Communications Inc.
4 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 4 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
5 * Copyright (c) 2018, The Linux Foundation. All rights reserved. 5 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
6 */ 6 */
7 7
8#include <linux/module.h> 8#include <linux/module.h>
@@ -2197,6 +2197,7 @@ static void ath10k_core_restart(struct work_struct *work)
2197 complete(&ar->offchan_tx_completed); 2197 complete(&ar->offchan_tx_completed);
2198 complete(&ar->install_key_done); 2198 complete(&ar->install_key_done);
2199 complete(&ar->vdev_setup_done); 2199 complete(&ar->vdev_setup_done);
2200 complete(&ar->vdev_delete_done);
2200 complete(&ar->thermal.wmi_sync); 2201 complete(&ar->thermal.wmi_sync);
2201 complete(&ar->bss_survey_done); 2202 complete(&ar->bss_survey_done);
2202 wake_up(&ar->htt.empty_tx_wq); 2203 wake_up(&ar->htt.empty_tx_wq);
@@ -3163,6 +3164,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
3163 3164
3164 init_completion(&ar->install_key_done); 3165 init_completion(&ar->install_key_done);
3165 init_completion(&ar->vdev_setup_done); 3166 init_completion(&ar->vdev_setup_done);
3167 init_completion(&ar->vdev_delete_done);
3166 init_completion(&ar->thermal.wmi_sync); 3168 init_completion(&ar->thermal.wmi_sync);
3167 init_completion(&ar->bss_survey_done); 3169 init_completion(&ar->bss_survey_done);
3168 3170
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index fe6e88d2bdf9..872f13d0ba64 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -2,7 +2,7 @@
2/* 2/*
3 * Copyright (c) 2005-2011 Atheros Communications Inc. 3 * Copyright (c) 2005-2011 Atheros Communications Inc.
4 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 4 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
5 * Copyright (c) 2018, The Linux Foundation. All rights reserved. 5 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
6 */ 6 */
7 7
8#ifndef _CORE_H_ 8#ifndef _CORE_H_
@@ -514,7 +514,8 @@ struct ath10k_sta {
514 u32 peer_ps_state; 514 u32 peer_ps_state;
515}; 515};
516 516
517#define ATH10K_VDEV_SETUP_TIMEOUT_HZ (5 * HZ) 517#define ATH10K_VDEV_SETUP_TIMEOUT_HZ (5 * HZ)
518#define ATH10K_VDEV_DELETE_TIMEOUT_HZ (5 * HZ)
518 519
519enum ath10k_beacon_state { 520enum ath10k_beacon_state {
520 ATH10K_BEACON_SCHEDULED = 0, 521 ATH10K_BEACON_SCHEDULED = 0,
@@ -1072,6 +1073,7 @@ struct ath10k {
1072 1073
1073 int last_wmi_vdev_start_status; 1074 int last_wmi_vdev_start_status;
1074 struct completion vdev_setup_done; 1075 struct completion vdev_setup_done;
1076 struct completion vdev_delete_done;
1075 1077
1076 struct workqueue_struct *workqueue; 1078 struct workqueue_struct *workqueue;
1077 /* Auxiliary workqueue */ 1079 /* Auxiliary workqueue */
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index c4e7adf3ae45..572c03667110 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -1011,6 +1011,7 @@ static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
1011 arg.channel.max_antenna_gain = channel->max_antenna_gain * 2; 1011 arg.channel.max_antenna_gain = channel->max_antenna_gain * 2;
1012 1012
1013 reinit_completion(&ar->vdev_setup_done); 1013 reinit_completion(&ar->vdev_setup_done);
1014 reinit_completion(&ar->vdev_delete_done);
1014 1015
1015 ret = ath10k_wmi_vdev_start(ar, &arg); 1016 ret = ath10k_wmi_vdev_start(ar, &arg);
1016 if (ret) { 1017 if (ret) {
@@ -1060,6 +1061,7 @@ static int ath10k_monitor_vdev_stop(struct ath10k *ar)
1060 ar->monitor_vdev_id, ret); 1061 ar->monitor_vdev_id, ret);
1061 1062
1062 reinit_completion(&ar->vdev_setup_done); 1063 reinit_completion(&ar->vdev_setup_done);
1064 reinit_completion(&ar->vdev_delete_done);
1063 1065
1064 ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id); 1066 ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
1065 if (ret) 1067 if (ret)
@@ -1401,6 +1403,7 @@ static int ath10k_vdev_stop(struct ath10k_vif *arvif)
1401 lockdep_assert_held(&ar->conf_mutex); 1403 lockdep_assert_held(&ar->conf_mutex);
1402 1404
1403 reinit_completion(&ar->vdev_setup_done); 1405 reinit_completion(&ar->vdev_setup_done);
1406 reinit_completion(&ar->vdev_delete_done);
1404 1407
1405 ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id); 1408 ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id);
1406 if (ret) { 1409 if (ret) {
@@ -1437,6 +1440,7 @@ static int ath10k_vdev_start_restart(struct ath10k_vif *arvif,
1437 lockdep_assert_held(&ar->conf_mutex); 1440 lockdep_assert_held(&ar->conf_mutex);
1438 1441
1439 reinit_completion(&ar->vdev_setup_done); 1442 reinit_completion(&ar->vdev_setup_done);
1443 reinit_completion(&ar->vdev_delete_done);
1440 1444
1441 arg.vdev_id = arvif->vdev_id; 1445 arg.vdev_id = arvif->vdev_id;
1442 arg.dtim_period = arvif->dtim_period; 1446 arg.dtim_period = arvif->dtim_period;
@@ -5455,6 +5459,7 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
5455 struct ath10k *ar = hw->priv; 5459 struct ath10k *ar = hw->priv;
5456 struct ath10k_vif *arvif = (void *)vif->drv_priv; 5460 struct ath10k_vif *arvif = (void *)vif->drv_priv;
5457 struct ath10k_peer *peer; 5461 struct ath10k_peer *peer;
5462 unsigned long time_left;
5458 int ret; 5463 int ret;
5459 int i; 5464 int i;
5460 5465
@@ -5496,6 +5501,15 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
5496 ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n", 5501 ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
5497 arvif->vdev_id, ret); 5502 arvif->vdev_id, ret);
5498 5503
5504 if (test_bit(WMI_SERVICE_SYNC_DELETE_CMDS, ar->wmi.svc_map)) {
5505 time_left = wait_for_completion_timeout(&ar->vdev_delete_done,
5506 ATH10K_VDEV_DELETE_TIMEOUT_HZ);
5507 if (time_left == 0) {
5508 ath10k_warn(ar, "Timeout in receiving vdev delete response\n");
5509 goto out;
5510 }
5511 }
5512
5499 /* Some firmware revisions don't notify host about self-peer removal 5513 /* Some firmware revisions don't notify host about self-peer removal
5500 * until after associated vdev is deleted. 5514 * until after associated vdev is deleted.
5501 */ 5515 */
@@ -5546,6 +5560,7 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
5546 5560
5547 ath10k_mac_txq_unref(ar, vif->txq); 5561 ath10k_mac_txq_unref(ar, vif->txq);
5548 5562
5563out:
5549 mutex_unlock(&ar->conf_mutex); 5564 mutex_unlock(&ar->conf_mutex);
5550} 5565}
5551 5566
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index 34e187486c63..13d66638dbb4 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -2,7 +2,7 @@
2/* 2/*
3 * Copyright (c) 2005-2011 Atheros Communications Inc. 3 * Copyright (c) 2005-2011 Atheros Communications Inc.
4 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 4 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
5 * Copyright (c) 2018, The Linux Foundation. All rights reserved. 5 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
6 */ 6 */
7#include "core.h" 7#include "core.h"
8#include "debug.h" 8#include "debug.h"
@@ -212,6 +212,13 @@ static int ath10k_wmi_tlv_event_bcn_tx_status(struct ath10k *ar,
212 return 0; 212 return 0;
213} 213}
214 214
215static void ath10k_wmi_tlv_event_vdev_delete_resp(struct ath10k *ar,
216 struct sk_buff *skb)
217{
218 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_DELETE_RESP_EVENTID\n");
219 complete(&ar->vdev_delete_done);
220}
221
215static int ath10k_wmi_tlv_event_diag_data(struct ath10k *ar, 222static int ath10k_wmi_tlv_event_diag_data(struct ath10k *ar,
216 struct sk_buff *skb) 223 struct sk_buff *skb)
217{ 224{
@@ -514,6 +521,9 @@ static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb)
514 case WMI_TLV_VDEV_STOPPED_EVENTID: 521 case WMI_TLV_VDEV_STOPPED_EVENTID:
515 ath10k_wmi_event_vdev_stopped(ar, skb); 522 ath10k_wmi_event_vdev_stopped(ar, skb);
516 break; 523 break;
524 case WMI_TLV_VDEV_DELETE_RESP_EVENTID:
525 ath10k_wmi_tlv_event_vdev_delete_resp(ar, skb);
526 break;
517 case WMI_TLV_PEER_STA_KICKOUT_EVENTID: 527 case WMI_TLV_PEER_STA_KICKOUT_EVENTID:
518 ath10k_wmi_event_peer_sta_kickout(ar, skb); 528 ath10k_wmi_event_peer_sta_kickout(ar, skb);
519 break; 529 break;
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.h b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
index bc3198b08844..a4b1a1477e04 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
@@ -2,7 +2,7 @@
2/* 2/*
3 * Copyright (c) 2005-2011 Atheros Communications Inc. 3 * Copyright (c) 2005-2011 Atheros Communications Inc.
4 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 4 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
5 * Copyright (c) 2018, The Linux Foundation. All rights reserved. 5 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
6 */ 6 */
7#ifndef _WMI_TLV_H 7#ifndef _WMI_TLV_H
8#define _WMI_TLV_H 8#define _WMI_TLV_H
@@ -301,6 +301,8 @@ enum wmi_tlv_event_id {
301 WMI_TLV_VDEV_STOPPED_EVENTID, 301 WMI_TLV_VDEV_STOPPED_EVENTID,
302 WMI_TLV_VDEV_INSTALL_KEY_COMPLETE_EVENTID, 302 WMI_TLV_VDEV_INSTALL_KEY_COMPLETE_EVENTID,
303 WMI_TLV_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID, 303 WMI_TLV_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID,
304 WMI_TLV_VDEV_TSF_REPORT_EVENTID,
305 WMI_TLV_VDEV_DELETE_RESP_EVENTID,
304 WMI_TLV_PEER_STA_KICKOUT_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_PEER), 306 WMI_TLV_PEER_STA_KICKOUT_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_PEER),
305 WMI_TLV_PEER_INFO_EVENTID, 307 WMI_TLV_PEER_INFO_EVENTID,
306 WMI_TLV_PEER_TX_FAIL_CNT_THR_EVENTID, 308 WMI_TLV_PEER_TX_FAIL_CNT_THR_EVENTID,
@@ -1569,6 +1571,8 @@ wmi_tlv_svc_map(const __le32 *in, unsigned long *out, size_t len)
1569 WMI_SERVICE_MGMT_TX_WMI, len); 1571 WMI_SERVICE_MGMT_TX_WMI, len);
1570 SVCMAP(WMI_TLV_SERVICE_MESH_11S, 1572 SVCMAP(WMI_TLV_SERVICE_MESH_11S,
1571 WMI_SERVICE_MESH_11S, len); 1573 WMI_SERVICE_MESH_11S, len);
1574 SVCMAP(WMI_TLV_SERVICE_SYNC_DELETE_CMDS,
1575 WMI_SERVICE_SYNC_DELETE_CMDS, len);
1572} 1576}
1573 1577
1574static inline void 1578static inline void
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index bd54da64cd02..8b869c289039 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -2,7 +2,7 @@
2/* 2/*
3 * Copyright (c) 2005-2011 Atheros Communications Inc. 3 * Copyright (c) 2005-2011 Atheros Communications Inc.
4 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 4 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
5 * Copyright (c) 2018, The Linux Foundation. All rights reserved. 5 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
6 */ 6 */
7 7
8#ifndef _WMI_H_ 8#ifndef _WMI_H_
@@ -200,6 +200,7 @@ enum wmi_service {
200 WMI_SERVICE_RTT_RESPONDER_ROLE, 200 WMI_SERVICE_RTT_RESPONDER_ROLE,
201 WMI_SERVICE_PER_PACKET_SW_ENCRYPT, 201 WMI_SERVICE_PER_PACKET_SW_ENCRYPT,
202 WMI_SERVICE_REPORT_AIRTIME, 202 WMI_SERVICE_REPORT_AIRTIME,
203 WMI_SERVICE_SYNC_DELETE_CMDS,
203 204
204 /* Remember to add the new value to wmi_service_name()! */ 205 /* Remember to add the new value to wmi_service_name()! */
205 206
@@ -491,6 +492,7 @@ static inline char *wmi_service_name(enum wmi_service service_id)
491 SVCSTR(WMI_SERVICE_RTT_RESPONDER_ROLE); 492 SVCSTR(WMI_SERVICE_RTT_RESPONDER_ROLE);
492 SVCSTR(WMI_SERVICE_PER_PACKET_SW_ENCRYPT); 493 SVCSTR(WMI_SERVICE_PER_PACKET_SW_ENCRYPT);
493 SVCSTR(WMI_SERVICE_REPORT_AIRTIME); 494 SVCSTR(WMI_SERVICE_REPORT_AIRTIME);
495 SVCSTR(WMI_SERVICE_SYNC_DELETE_CMDS);
494 496
495 case WMI_SERVICE_MAX: 497 case WMI_SERVICE_MAX:
496 return NULL; 498 return NULL;