diff mbox series

[07/16] wil6210: refactor disconnect flow

Message ID 1540975944-30576-8-git-send-email-merez@codeaurora.org (mailing list archive)
State Accepted
Commit e1b43407c034650c11bc597bef319f03b8262b6c
Delegated to: Kalle Valo
Headers show
Series wil6210 patches | expand

Commit Message

Maya Erez Oct. 31, 2018, 8:52 a.m. UTC
From: Ahmad Masri <amasri@codeaurora.org>

Separate sending command to the fw from the event handling function to
simplify the disconnect flow and track the from_event flag correctly.

Signed-off-by: Ahmad Masri <amasri@codeaurora.org>
Signed-off-by: Maya Erez <merez@codeaurora.org>
---
 drivers/net/wireless/ath/wil6210/cfg80211.c |   2 +-
 drivers/net/wireless/ath/wil6210/main.c     | 180 +++++++++++++++++++++-------
 drivers/net/wireless/ath/wil6210/netdev.c   |   2 +-
 drivers/net/wireless/ath/wil6210/wil6210.h  |   8 +-
 drivers/net/wireless/ath/wil6210/wmi.c      |  28 ++---
 5 files changed, 148 insertions(+), 72 deletions(-)

Comments

Kalle Valo Nov. 6, 2018, 10:30 a.m. UTC | #1
Maya Erez <merez@codeaurora.org> writes:

> From: Ahmad Masri <amasri@codeaurora.org>
>
> Separate sending command to the fw from the event handling function to
> simplify the disconnect flow and track the from_event flag correctly.
>
> Signed-off-by: Ahmad Masri <amasri@codeaurora.org>
> Signed-off-by: Maya Erez <merez@codeaurora.org>

[...]

> +static int wil_disconnect_cid(struct wil6210_vif *vif, int cid,
> +			      u16 reason_code)
> +__acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
> +{
> +	struct wil6210_priv *wil = vif_to_wil(vif);
> +	struct wireless_dev *wdev = vif_to_wdev(vif);
> +	struct wil_sta_info *sta = &wil->sta[cid];
> +	bool del_sta = false;
> +
> +	might_sleep();
> +	wil_dbg_misc(wil, "disconnect_cid: CID %d, MID %d, status %d\n",
> +		     cid, sta->mid, sta->status);
> +
> +	if (sta->status == wil_sta_unused)
> +		return 0;
> +
> +	if (vif->mid != sta->mid) {
> +		wil_err(wil, "STA MID mismatch with VIF MID(%d)\n", vif->mid);
> +		return -EINVAL;
> +	}
> +
> +	/* inform lower layers */
> +	if (wdev->iftype == NL80211_IFTYPE_AP && disable_ap_sme)
> +		del_sta = true;
> +
> +	/* disconnect by sending command disconnect/del_sta and wait
> +	 * synchronously for WMI_DISCONNECT_EVENTID event.
> +	 */
> +	return wmi_disconnect_sta(vif, sta->addr, reason_code, del_sta);
> +}

I don't get use of __acquires() and __releases() in this function. I see
similar pattern already in wil6210 but care to explain why this is
needed? I don't see the function even accessing tid_rx_lock so I'm very
confused.
Maya Erez Nov. 6, 2018, 11:52 a.m. UTC | #2
On 2018-11-06 12:30, Kalle Valo wrote:
> Maya Erez <merez@codeaurora.org> writes:
> 
>> From: Ahmad Masri <amasri@codeaurora.org>
>> 
>> Separate sending command to the fw from the event handling function to
>> simplify the disconnect flow and track the from_event flag correctly.
>> 
>> Signed-off-by: Ahmad Masri <amasri@codeaurora.org>
>> Signed-off-by: Maya Erez <merez@codeaurora.org>
> 
> [...]
> 
>> +static int wil_disconnect_cid(struct wil6210_vif *vif, int cid,
>> +			      u16 reason_code)
>> +__acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
>> +{
>> +	struct wil6210_priv *wil = vif_to_wil(vif);
>> +	struct wireless_dev *wdev = vif_to_wdev(vif);
>> +	struct wil_sta_info *sta = &wil->sta[cid];
>> +	bool del_sta = false;
>> +
>> +	might_sleep();
>> +	wil_dbg_misc(wil, "disconnect_cid: CID %d, MID %d, status %d\n",
>> +		     cid, sta->mid, sta->status);
>> +
>> +	if (sta->status == wil_sta_unused)
>> +		return 0;
>> +
>> +	if (vif->mid != sta->mid) {
>> +		wil_err(wil, "STA MID mismatch with VIF MID(%d)\n", vif->mid);
>> +		return -EINVAL;
>> +	}
>> +
>> +	/* inform lower layers */
>> +	if (wdev->iftype == NL80211_IFTYPE_AP && disable_ap_sme)
>> +		del_sta = true;
>> +
>> +	/* disconnect by sending command disconnect/del_sta and wait
>> +	 * synchronously for WMI_DISCONNECT_EVENTID event.
>> +	 */
>> +	return wmi_disconnect_sta(vif, sta->addr, reason_code, del_sta);
>> +}
> 
> I don't get use of __acquires() and __releases() in this function. I 
> see
> similar pattern already in wil6210 but care to explain why this is
> needed? I don't see the function even accessing tid_rx_lock so I'm very
> confused.

I assume it is a copy / paste leftover that we missed in the code 
review.
We will remove it.
Kalle Valo Nov. 6, 2018, 12:28 p.m. UTC | #3
merez@codeaurora.org writes:

> On 2018-11-06 12:30, Kalle Valo wrote:
>> Maya Erez <merez@codeaurora.org> writes:
>>
>>> From: Ahmad Masri <amasri@codeaurora.org>
>>>
>>> Separate sending command to the fw from the event handling function to
>>> simplify the disconnect flow and track the from_event flag correctly.
>>>
>>> Signed-off-by: Ahmad Masri <amasri@codeaurora.org>
>>> Signed-off-by: Maya Erez <merez@codeaurora.org>
>>
>> [...]
>>
>>> +static int wil_disconnect_cid(struct wil6210_vif *vif, int cid,
>>> +			      u16 reason_code)
>>> +__acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
>>> +{
>>> +	struct wil6210_priv *wil = vif_to_wil(vif);
>>> +	struct wireless_dev *wdev = vif_to_wdev(vif);
>>> +	struct wil_sta_info *sta = &wil->sta[cid];
>>> +	bool del_sta = false;
>>> +
>>> +	might_sleep();
>>> +	wil_dbg_misc(wil, "disconnect_cid: CID %d, MID %d, status %d\n",
>>> +		     cid, sta->mid, sta->status);
>>> +
>>> +	if (sta->status == wil_sta_unused)
>>> +		return 0;
>>> +
>>> +	if (vif->mid != sta->mid) {
>>> +		wil_err(wil, "STA MID mismatch with VIF MID(%d)\n", vif->mid);
>>> +		return -EINVAL;
>>> +	}
>>> +
>>> +	/* inform lower layers */
>>> +	if (wdev->iftype == NL80211_IFTYPE_AP && disable_ap_sme)
>>> +		del_sta = true;
>>> +
>>> +	/* disconnect by sending command disconnect/del_sta and wait
>>> +	 * synchronously for WMI_DISCONNECT_EVENTID event.
>>> +	 */
>>> +	return wmi_disconnect_sta(vif, sta->addr, reason_code, del_sta);
>>> +}
>>
>> I don't get use of __acquires() and __releases() in this function. I
>> see
>> similar pattern already in wil6210 but care to explain why this is
>> needed? I don't see the function even accessing tid_rx_lock so I'm very
>> confused.
>
> I assume it is a copy / paste leftover that we missed in the code
> review. We will remove it.

Actually I already removed the annotations from the pending branch and
no need to resend, it's faster that way. Please double check if you can,
unfortunately I cannot provide a direct link cgit doesn't show the new
commit yet.
Maya Erez Nov. 6, 2018, 12:38 p.m. UTC | #4
On 2018-11-06 14:28, Kalle Valo wrote:
> merez@codeaurora.org writes:
> 
>> On 2018-11-06 12:30, Kalle Valo wrote:
>>> Maya Erez <merez@codeaurora.org> writes:
>>> 
>>>> From: Ahmad Masri <amasri@codeaurora.org>
>>>> 
>>>> Separate sending command to the fw from the event handling function 
>>>> to
>>>> simplify the disconnect flow and track the from_event flag 
>>>> correctly.
>>>> 
>>>> Signed-off-by: Ahmad Masri <amasri@codeaurora.org>
>>>> Signed-off-by: Maya Erez <merez@codeaurora.org>
>>> 
>>> [...]
>>> 
>>>> +static int wil_disconnect_cid(struct wil6210_vif *vif, int cid,
>>>> +			      u16 reason_code)
>>>> +__acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
>>>> +{
>>>> +	struct wil6210_priv *wil = vif_to_wil(vif);
>>>> +	struct wireless_dev *wdev = vif_to_wdev(vif);
>>>> +	struct wil_sta_info *sta = &wil->sta[cid];
>>>> +	bool del_sta = false;
>>>> +
>>>> +	might_sleep();
>>>> +	wil_dbg_misc(wil, "disconnect_cid: CID %d, MID %d, status %d\n",
>>>> +		     cid, sta->mid, sta->status);
>>>> +
>>>> +	if (sta->status == wil_sta_unused)
>>>> +		return 0;
>>>> +
>>>> +	if (vif->mid != sta->mid) {
>>>> +		wil_err(wil, "STA MID mismatch with VIF MID(%d)\n", vif->mid);
>>>> +		return -EINVAL;
>>>> +	}
>>>> +
>>>> +	/* inform lower layers */
>>>> +	if (wdev->iftype == NL80211_IFTYPE_AP && disable_ap_sme)
>>>> +		del_sta = true;
>>>> +
>>>> +	/* disconnect by sending command disconnect/del_sta and wait
>>>> +	 * synchronously for WMI_DISCONNECT_EVENTID event.
>>>> +	 */
>>>> +	return wmi_disconnect_sta(vif, sta->addr, reason_code, del_sta);
>>>> +}
>>> 
>>> I don't get use of __acquires() and __releases() in this function. I
>>> see
>>> similar pattern already in wil6210 but care to explain why this is
>>> needed? I don't see the function even accessing tid_rx_lock so I'm 
>>> very
>>> confused.
>> 
>> I assume it is a copy / paste leftover that we missed in the code
>> review. We will remove it.
> 
> Actually I already removed the annotations from the pending branch and
> no need to resend, it's faster that way. Please double check if you 
> can,
> unfortunately I cannot provide a direct link cgit doesn't show the new
> commit yet.

In such a case you can go ahead and apply the patches without
"wil6210: ignore HALP ICR if already handled". I'll upstream its fixed 
version
in the next set of wil6210 patches.
Kalle Valo Nov. 6, 2018, 12:40 p.m. UTC | #5
merez@codeaurora.org writes:

> On 2018-11-06 14:28, Kalle Valo wrote:
>> merez@codeaurora.org writes:
>>
>>> On 2018-11-06 12:30, Kalle Valo wrote:
>>>> Maya Erez <merez@codeaurora.org> writes:
>>>>
>>>>> From: Ahmad Masri <amasri@codeaurora.org>
>>>>>
>>>>> Separate sending command to the fw from the event handling
>>>>> function to
>>>>> simplify the disconnect flow and track the from_event flag
>>>>> correctly.
>>>>>
>>>>> Signed-off-by: Ahmad Masri <amasri@codeaurora.org>
>>>>> Signed-off-by: Maya Erez <merez@codeaurora.org>
>>>>
>>>> [...]
>>>>
>>>>> +static int wil_disconnect_cid(struct wil6210_vif *vif, int cid,
>>>>> +			      u16 reason_code)
>>>>> +__acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
>>>>> +{
>>>>> +	struct wil6210_priv *wil = vif_to_wil(vif);
>>>>> +	struct wireless_dev *wdev = vif_to_wdev(vif);
>>>>> +	struct wil_sta_info *sta = &wil->sta[cid];
>>>>> +	bool del_sta = false;
>>>>> +
>>>>> +	might_sleep();
>>>>> +	wil_dbg_misc(wil, "disconnect_cid: CID %d, MID %d, status %d\n",
>>>>> +		     cid, sta->mid, sta->status);
>>>>> +
>>>>> +	if (sta->status == wil_sta_unused)
>>>>> +		return 0;
>>>>> +
>>>>> +	if (vif->mid != sta->mid) {
>>>>> +		wil_err(wil, "STA MID mismatch with VIF MID(%d)\n", vif->mid);
>>>>> +		return -EINVAL;
>>>>> +	}
>>>>> +
>>>>> +	/* inform lower layers */
>>>>> +	if (wdev->iftype == NL80211_IFTYPE_AP && disable_ap_sme)
>>>>> +		del_sta = true;
>>>>> +
>>>>> +	/* disconnect by sending command disconnect/del_sta and wait
>>>>> +	 * synchronously for WMI_DISCONNECT_EVENTID event.
>>>>> +	 */
>>>>> +	return wmi_disconnect_sta(vif, sta->addr, reason_code, del_sta);
>>>>> +}
>>>>
>>>> I don't get use of __acquires() and __releases() in this function. I
>>>> see
>>>> similar pattern already in wil6210 but care to explain why this is
>>>> needed? I don't see the function even accessing tid_rx_lock so I'm
>>>> very
>>>> confused.
>>>
>>> I assume it is a copy / paste leftover that we missed in the code
>>> review. We will remove it.
>>
>> Actually I already removed the annotations from the pending branch and
>> no need to resend, it's faster that way. Please double check if you
>> can,
>> unfortunately I cannot provide a direct link cgit doesn't show the new
>> commit yet.
>
> In such a case you can go ahead and apply the patches without
> "wil6210: ignore HALP ICR if already handled". I'll upstream its fixed
> version
> in the next set of wil6210 patches.

Ok, I dropped "wil6210: ignore HALP ICR if already handled" and I'm
planning to apply the rest.
diff mbox series

Patch

diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index e9135d6..9b2f9f5 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -2015,7 +2015,7 @@  static int wil_cfg80211_del_station(struct wiphy *wiphy,
 		     params->mac, params->reason_code, vif->mid);
 
 	mutex_lock(&wil->mutex);
-	wil6210_disconnect(vif, params->mac, params->reason_code, false);
+	wil6210_disconnect(vif, params->mac, params->reason_code);
 	mutex_unlock(&wil->mutex);
 
 	return 0;
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 2b328c1..9dd068d 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -215,8 +215,21 @@  static void wil_ring_fini_tx(struct wil6210_priv *wil, int id)
 	wil->txrx_ops.ring_fini_tx(wil, ring);
 }
 
-static void wil_disconnect_cid(struct wil6210_vif *vif, int cid,
-			       u16 reason_code, bool from_event)
+static bool wil_vif_is_connected(struct wil6210_priv *wil, u8 mid)
+{
+	int i;
+
+	for (i = 0; i < WIL6210_MAX_CID; i++) {
+		if (wil->sta[i].mid == mid &&
+		    wil->sta[i].status == wil_sta_connected)
+			return true;
+	}
+
+	return false;
+}
+
+static void wil_disconnect_cid_complete(struct wil6210_vif *vif, int cid,
+					u16 reason_code)
 __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
 {
 	uint i;
@@ -227,24 +240,14 @@  static void wil_disconnect_cid(struct wil6210_vif *vif, int cid,
 	int min_ring_id = wil_get_min_tx_ring_id(wil);
 
 	might_sleep();
-	wil_dbg_misc(wil, "disconnect_cid: CID %d, MID %d, status %d\n",
+	wil_dbg_misc(wil,
+		     "disconnect_cid_complete: CID %d, MID %d, status %d\n",
 		     cid, sta->mid, sta->status);
-	/* inform upper/lower layers */
+	/* inform upper layers */
 	if (sta->status != wil_sta_unused) {
 		if (vif->mid != sta->mid) {
 			wil_err(wil, "STA MID mismatch with VIF MID(%d)\n",
 				vif->mid);
-			/* let FW override sta->mid but be more strict with
-			 * user space requests
-			 */
-			if (!from_event)
-				return;
-		}
-		if (!from_event) {
-			bool del_sta = (wdev->iftype == NL80211_IFTYPE_AP) ?
-						disable_ap_sme : false;
-			wmi_disconnect_sta(vif, sta->addr, reason_code,
-					   true, del_sta);
 		}
 
 		switch (wdev->iftype) {
@@ -284,36 +287,20 @@  static void wil_disconnect_cid(struct wil6210_vif *vif, int cid,
 	sta->stats.tx_latency_min_us = U32_MAX;
 }
 
-static bool wil_vif_is_connected(struct wil6210_priv *wil, u8 mid)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
-		if (wil->sta[i].mid == mid &&
-		    wil->sta[i].status == wil_sta_connected)
-			return true;
-	}
-
-	return false;
-}
-
-static void _wil6210_disconnect(struct wil6210_vif *vif, const u8 *bssid,
-				u16 reason_code, bool from_event)
+static void _wil6210_disconnect_complete(struct wil6210_vif *vif,
+					 const u8 *bssid, u16 reason_code)
 {
 	struct wil6210_priv *wil = vif_to_wil(vif);
 	int cid = -ENOENT;
 	struct net_device *ndev;
 	struct wireless_dev *wdev;
 
-	if (unlikely(!vif))
-		return;
-
 	ndev = vif_to_ndev(vif);
 	wdev = vif_to_wdev(vif);
 
 	might_sleep();
-	wil_info(wil, "bssid=%pM, reason=%d, ev%s\n", bssid,
-		 reason_code, from_event ? "+" : "-");
+	wil_info(wil, "disconnect_complete: bssid=%pM, reason=%d\n",
+		 bssid, reason_code);
 
 	/* Cases are:
 	 * - disconnect single STA, still connected
@@ -328,14 +315,15 @@  static void _wil6210_disconnect(struct wil6210_vif *vif, const u8 *bssid,
 	if (bssid && !is_broadcast_ether_addr(bssid) &&
 	    !ether_addr_equal_unaligned(ndev->dev_addr, bssid)) {
 		cid = wil_find_cid(wil, vif->mid, bssid);
-		wil_dbg_misc(wil, "Disconnect %pM, CID=%d, reason=%d\n",
+		wil_dbg_misc(wil,
+			     "Disconnect complete %pM, CID=%d, reason=%d\n",
 			     bssid, cid, reason_code);
 		if (cid >= 0) /* disconnect 1 peer */
-			wil_disconnect_cid(vif, cid, reason_code, from_event);
+			wil_disconnect_cid_complete(vif, cid, reason_code);
 	} else { /* all */
-		wil_dbg_misc(wil, "Disconnect all\n");
+		wil_dbg_misc(wil, "Disconnect complete all\n");
 		for (cid = 0; cid < WIL6210_MAX_CID; cid++)
-			wil_disconnect_cid(vif, cid, reason_code, from_event);
+			wil_disconnect_cid_complete(vif, cid, reason_code);
 	}
 
 	/* link state */
@@ -381,6 +369,85 @@  static void _wil6210_disconnect(struct wil6210_vif *vif, const u8 *bssid,
 	}
 }
 
+static int wil_disconnect_cid(struct wil6210_vif *vif, int cid,
+			      u16 reason_code)
+__acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
+{
+	struct wil6210_priv *wil = vif_to_wil(vif);
+	struct wireless_dev *wdev = vif_to_wdev(vif);
+	struct wil_sta_info *sta = &wil->sta[cid];
+	bool del_sta = false;
+
+	might_sleep();
+	wil_dbg_misc(wil, "disconnect_cid: CID %d, MID %d, status %d\n",
+		     cid, sta->mid, sta->status);
+
+	if (sta->status == wil_sta_unused)
+		return 0;
+
+	if (vif->mid != sta->mid) {
+		wil_err(wil, "STA MID mismatch with VIF MID(%d)\n", vif->mid);
+		return -EINVAL;
+	}
+
+	/* inform lower layers */
+	if (wdev->iftype == NL80211_IFTYPE_AP && disable_ap_sme)
+		del_sta = true;
+
+	/* disconnect by sending command disconnect/del_sta and wait
+	 * synchronously for WMI_DISCONNECT_EVENTID event.
+	 */
+	return wmi_disconnect_sta(vif, sta->addr, reason_code, del_sta);
+}
+
+static void _wil6210_disconnect(struct wil6210_vif *vif, const u8 *bssid,
+				u16 reason_code)
+{
+	struct wil6210_priv *wil;
+	struct net_device *ndev;
+	struct wireless_dev *wdev;
+	int cid = -ENOENT;
+
+	if (unlikely(!vif))
+		return;
+
+	wil = vif_to_wil(vif);
+	ndev = vif_to_ndev(vif);
+	wdev = vif_to_wdev(vif);
+
+	might_sleep();
+	wil_info(wil, "disconnect bssid=%pM, reason=%d\n", bssid, reason_code);
+
+	/* Cases are:
+	 * - disconnect single STA, still connected
+	 * - disconnect single STA, already disconnected
+	 * - disconnect all
+	 *
+	 * For "disconnect all", there are 3 options:
+	 * - bssid == NULL
+	 * - bssid is broadcast address (ff:ff:ff:ff:ff:ff)
+	 * - bssid is our MAC address
+	 */
+	if (bssid && !is_broadcast_ether_addr(bssid) &&
+	    !ether_addr_equal_unaligned(ndev->dev_addr, bssid)) {
+		cid = wil_find_cid(wil, vif->mid, bssid);
+		wil_dbg_misc(wil, "Disconnect %pM, CID=%d, reason=%d\n",
+			     bssid, cid, reason_code);
+		if (cid >= 0) /* disconnect 1 peer */
+			wil_disconnect_cid(vif, cid, reason_code);
+	} else { /* all */
+		wil_dbg_misc(wil, "Disconnect all\n");
+		for (cid = 0; cid < WIL6210_MAX_CID; cid++)
+			wil_disconnect_cid(vif, cid, reason_code);
+	}
+
+	/* call event handler manually after processing wmi_call,
+	 * to avoid deadlock - disconnect event handler acquires
+	 * wil->mutex while it is already held here
+	 */
+	_wil6210_disconnect_complete(vif, bssid, reason_code);
+}
+
 void wil_disconnect_worker(struct work_struct *work)
 {
 	struct wil6210_vif *vif = container_of(work,
@@ -705,20 +772,41 @@  void wil6210_bus_request(struct wil6210_priv *wil, u32 kbps)
  * @vif: virtual interface context
  * @bssid: peer to disconnect, NULL to disconnect all
  * @reason_code: Reason code for the Disassociation frame
- * @from_event: whether is invoked from FW event handler
  *
- * Disconnect and release associated resources. If invoked not from the
- * FW event handler, issue WMI command(s) to trigger MAC disconnect.
+ * Disconnect and release associated resources. Issue WMI
+ * command(s) to trigger MAC disconnect. When command was issued
+ * successfully, call the wil6210_disconnect_complete function
+ * to handle the event synchronously
  */
 void wil6210_disconnect(struct wil6210_vif *vif, const u8 *bssid,
-			u16 reason_code, bool from_event)
+			u16 reason_code)
+{
+	struct wil6210_priv *wil = vif_to_wil(vif);
+
+	wil_dbg_misc(wil, "disconnecting\n");
+
+	del_timer_sync(&vif->connect_timer);
+	_wil6210_disconnect(vif, bssid, reason_code);
+}
+
+/**
+ * wil6210_disconnect_complete - handle disconnect event
+ * @vif: virtual interface context
+ * @bssid: peer to disconnect, NULL to disconnect all
+ * @reason_code: Reason code for the Disassociation frame
+ *
+ * Release associated resources and indicate upper layers the
+ * connection is terminated.
+ */
+void wil6210_disconnect_complete(struct wil6210_vif *vif, const u8 *bssid,
+				 u16 reason_code)
 {
 	struct wil6210_priv *wil = vif_to_wil(vif);
 
-	wil_dbg_misc(wil, "disconnect\n");
+	wil_dbg_misc(wil, "got disconnect\n");
 
 	del_timer_sync(&vif->connect_timer);
-	_wil6210_disconnect(vif, bssid, reason_code, from_event);
+	_wil6210_disconnect_complete(vif, bssid, reason_code);
 }
 
 void wil_priv_deinit(struct wil6210_priv *wil)
@@ -1525,7 +1613,7 @@  int wil_reset(struct wil6210_priv *wil, bool load_fw)
 		if (vif) {
 			cancel_work_sync(&vif->disconnect_worker);
 			wil6210_disconnect(vif, NULL,
-					   WLAN_REASON_DEAUTH_LEAVING, false);
+					   WLAN_REASON_DEAUTH_LEAVING);
 		}
 	}
 	wil_bcast_fini_all(wil);
diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c
index 64fa1a2..b4e0eb1 100644
--- a/drivers/net/wireless/ath/wil6210/netdev.c
+++ b/drivers/net/wireless/ath/wil6210/netdev.c
@@ -512,7 +512,7 @@  void wil_vif_remove(struct wil6210_priv *wil, u8 mid)
 	}
 
 	mutex_lock(&wil->mutex);
-	wil6210_disconnect(vif, NULL, WLAN_REASON_DEAUTH_LEAVING, false);
+	wil6210_disconnect(vif, NULL, WLAN_REASON_DEAUTH_LEAVING);
 	mutex_unlock(&wil->mutex);
 
 	ndev = vif_to_ndev(vif);
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 8050c4b..ad7003f 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -1229,8 +1229,8 @@  int wmi_add_cipher_key(struct wil6210_vif *vif, u8 key_index,
 int wmi_update_ft_ies(struct wil6210_vif *vif, u16 ie_len, const void *ie);
 int wmi_rxon(struct wil6210_priv *wil, bool on);
 int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r);
-int wmi_disconnect_sta(struct wil6210_vif *vif, const u8 *mac,
-		       u16 reason, bool full_disconnect, bool del_sta);
+int wmi_disconnect_sta(struct wil6210_vif *vif, const u8 *mac, u16 reason,
+		       bool del_sta);
 int wmi_addba(struct wil6210_priv *wil, u8 mid,
 	      u8 ringid, u8 size, u16 timeout);
 int wmi_delba_tx(struct wil6210_priv *wil, u8 mid, u8 ringid, u16 reason);
@@ -1316,7 +1316,9 @@  int wmi_pcp_start(struct wil6210_vif *vif, int bi, u8 wmi_nettype, u8 chan,
 void wil_abort_scan_all_vifs(struct wil6210_priv *wil, bool sync);
 void wil6210_bus_request(struct wil6210_priv *wil, u32 kbps);
 void wil6210_disconnect(struct wil6210_vif *vif, const u8 *bssid,
-			u16 reason_code, bool from_event);
+			u16 reason_code);
+void wil6210_disconnect_complete(struct wil6210_vif *vif, const u8 *bssid,
+				 u16 reason_code);
 void wil_probe_client_flush(struct wil6210_vif *vif);
 void wil_probe_client_worker(struct work_struct *work);
 void wil_disconnect_worker(struct work_struct *work);
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 4859f0e..5ff1862 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -1018,7 +1018,7 @@  static void wmi_evt_connect(struct wil6210_vif *vif, int id, void *d, int len)
 		wil_err(wil, "config tx vring failed for CID %d, rc (%d)\n",
 			evt->cid, rc);
 		wmi_disconnect_sta(vif, wil->sta[evt->cid].addr,
-				   WLAN_REASON_UNSPECIFIED, false, false);
+				   WLAN_REASON_UNSPECIFIED, false);
 	} else {
 		wil_info(wil, "successful connection to CID %d\n", evt->cid);
 	}
@@ -1112,7 +1112,7 @@  static void wmi_evt_disconnect(struct wil6210_vif *vif, int id,
 	}
 
 	mutex_lock(&wil->mutex);
-	wil6210_disconnect(vif, evt->bssid, reason_code, true);
+	wil6210_disconnect_complete(vif, evt->bssid, reason_code);
 	mutex_unlock(&wil->mutex);
 }
 
@@ -1637,7 +1637,7 @@  static int wil_find_cid_ringid_sta(struct wil6210_priv *wil,
 	return;
 
 fail:
-	wil6210_disconnect(vif, NULL, WLAN_REASON_PREV_AUTH_NOT_VALID, false);
+	wil6210_disconnect(vif, NULL, WLAN_REASON_PREV_AUTH_NOT_VALID);
 }
 
 static void
@@ -1766,7 +1766,7 @@  static int wil_find_cid_ringid_sta(struct wil6210_priv *wil,
 	return;
 
 fail:
-	wil6210_disconnect(vif, NULL, WLAN_REASON_PREV_AUTH_NOT_VALID, false);
+	wil6210_disconnect(vif, NULL, WLAN_REASON_PREV_AUTH_NOT_VALID);
 }
 
 /**
@@ -2560,12 +2560,11 @@  int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_bb, u32 *t_rf)
 	return 0;
 }
 
-int wmi_disconnect_sta(struct wil6210_vif *vif, const u8 *mac,
-		       u16 reason, bool full_disconnect, bool del_sta)
+int wmi_disconnect_sta(struct wil6210_vif *vif, const u8 *mac, u16 reason,
+		       bool del_sta)
 {
 	struct wil6210_priv *wil = vif_to_wil(vif);
 	int rc;
-	u16 reason_code;
 	struct wmi_disconnect_sta_cmd disc_sta_cmd = {
 		.disconnect_reason = cpu_to_le16(reason),
 	};
@@ -2598,21 +2597,8 @@  int wmi_disconnect_sta(struct wil6210_vif *vif, const u8 *mac,
 		wil_fw_error_recovery(wil);
 		return rc;
 	}
+	wil->sinfo_gen++;
 
-	if (full_disconnect) {
-		/* call event handler manually after processing wmi_call,
-		 * to avoid deadlock - disconnect event handler acquires
-		 * wil->mutex while it is already held here
-		 */
-		reason_code = le16_to_cpu(reply.evt.protocol_reason_status);
-
-		wil_dbg_wmi(wil, "Disconnect %pM reason [proto %d wmi %d]\n",
-			    reply.evt.bssid, reason_code,
-			    reply.evt.disconnect_reason);
-
-		wil->sinfo_gen++;
-		wil6210_disconnect(vif, reply.evt.bssid, reason_code, true);
-	}
 	return 0;
 }