|
@@ -4003,6 +4003,60 @@ csr_roam_chk_lnk_assoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
|
|
|
qdf_mem_free(roam_info);
|
|
|
}
|
|
|
|
|
|
+/* csr_if_peer_present() - Check whether peer is present or not
|
|
|
+ * @mac_ctx: Pointer to mac context
|
|
|
+ * @bssid: Pointer to bssid address
|
|
|
+ * @peer_macaddr: Pointer to peer mac address
|
|
|
+ *
|
|
|
+ * Consider a case
|
|
|
+ * 1. SAP received south bound disconnect command
|
|
|
+ * 2. At same time, SAP CSA to DFS channel happened and thus peers are deleted.
|
|
|
+ * 3. Later same peer got re-added and south bound disconnect command becomes
|
|
|
+ * active for same peer.
|
|
|
+ *
|
|
|
+ * When SAP receives south bound disconnect command req, driver will post to
|
|
|
+ * schedular thread and it will wait in SME message queue. When SAP CSA to DFS
|
|
|
+ * channel happens, driver will post to schedular thread and it will wait in PE
|
|
|
+ * message queue. Since PE has higher priority than SME message queue, so it
|
|
|
+ * will process first. As part of CSA, it will delete all peer including sta
|
|
|
+ * hash entry.
|
|
|
+ * After CSA, south bound disconnect command got queue to serialization and
|
|
|
+ * same peer got re-added again. When south bound disconnect command becomes
|
|
|
+ * active, the states will not be proper because for old peer, disassocTrigger
|
|
|
+ * is eLIM_PEER_ENTITY_DISASSOC/eLIM_PEER_ENTITY_DEAUTH and when new peer gets
|
|
|
+ * re-added, disassocTrigger will be eLIM_HOST_DISASSOC/eLIM_HOST_DEAUTH and
|
|
|
+ * thus response to CSR will not be proper. Due to this south bound disconnect
|
|
|
+ * command will not remove from active queue which leads to active command
|
|
|
+ * timeout.
|
|
|
+ * Validate the peer before sending to serialization to avoid queuing command
|
|
|
+ * if peer is already deleted.
|
|
|
+ *
|
|
|
+ * Return: True if peer is present otherwise return false
|
|
|
+ */
|
|
|
+static bool csr_if_peer_present(struct mac_context *mac_ctx,
|
|
|
+ uint8_t *bssid,
|
|
|
+ uint8_t *peer_macaddr)
|
|
|
+{
|
|
|
+ struct wlan_objmgr_peer *peer;
|
|
|
+ uint8_t pdev_id;
|
|
|
+
|
|
|
+ pdev_id = wlan_objmgr_pdev_get_pdev_id(mac_ctx->pdev);
|
|
|
+
|
|
|
+ peer = wlan_objmgr_get_peer_by_mac_n_vdev(mac_ctx->psoc, pdev_id,
|
|
|
+ bssid, peer_macaddr,
|
|
|
+ WLAN_LEGACY_SME_ID);
|
|
|
+
|
|
|
+ if (!peer) {
|
|
|
+ sme_info("peer not found for mac: " QDF_MAC_ADDR_FMT "and bssid: "
|
|
|
+ QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(peer_macaddr),
|
|
|
+ QDF_MAC_ADDR_REF(bssid));
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_SME_ID);
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
static void
|
|
|
csr_roam_chk_lnk_disassoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
|
|
|
{
|
|
@@ -4028,6 +4082,10 @@ csr_roam_chk_lnk_disassoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ if (!csr_if_peer_present(mac_ctx, &pDisassocInd->bssid.bytes[0],
|
|
|
+ &pDisassocInd->peer_macaddr.bytes[0]))
|
|
|
+ return;
|
|
|
+
|
|
|
if (csr_is_deauth_disassoc_already_active(mac_ctx, sessionId,
|
|
|
pDisassocInd->peer_macaddr))
|
|
|
return;
|
|
@@ -4070,6 +4128,10 @@ csr_roam_chk_lnk_deauth_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ if (!csr_if_peer_present(mac_ctx, &pDeauthInd->bssid.bytes[0],
|
|
|
+ &pDeauthInd->peer_macaddr.bytes[0]))
|
|
|
+ return;
|
|
|
+
|
|
|
if (csr_is_deauth_disassoc_already_active(mac_ctx, sessionId,
|
|
|
pDeauthInd->peer_macaddr))
|
|
|
return;
|