qcacld-3.0: Fix race between disconnection and RSO stop

Assume in case of STA + STA, where STA1 is on 2G band
and STA2 is on 5G band.

While switching STA1 to STA2, hdd_reg_set_band issue
disconnect, in order to change band (say 2G to 5G) and
start processing roam scan offload request to make sure
roaming gets enable on only one STA at a time.

eWNI_SME_DISASSOC_REQ and eWNI_SME_ROAM_SCAN_OFFLOAD_REQ
msg get posted to lim back to back through a single thread.

HOST starts processing DISASSOC_REQ first and waits for
tx_completion ACK for disassoc frame. Ideally, Host should
process eWNI_SME_ROAM_SCAN_OFFLOAD_REQ before getting ACK
for disassoc frame.

In case if DUT immediately gets disassoc ACK, DUT complete
disassoc req and then gets chance to process SCAN_OFFLOAD req.
Once DUT enters into Disconnection state, HOST never sends
RSO stop command to FW and leads to assert in fw.

Fix is to synchronize eWNI_SME_DISASSOC_REQ and
eWNI_SME_ROAM_SCAN_OFFLOAD_REQ command to make sure RSO stop
gets process first followed by Disconnection/deauth.

Change-Id: I4b29dda44729f5eddd82fec0b0e52a656d5cae37
CRs-Fixed: 2657305
This commit is contained in:
Abhinav Kumar
2020-04-06 14:01:34 +05:30
committed by nshrivas
szülő b3e8019000
commit b473f03317

Fájl megtekintése

@@ -755,7 +755,6 @@ int hdd_reg_set_band(struct net_device *dev, u8 ui_band)
struct hdd_context *hdd_ctx;
enum band_info current_band;
enum band_info connected_band;
long lrc;
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
@@ -818,29 +817,15 @@ int hdd_reg_set_band(struct net_device *dev, u8 ui_band)
hdd_debug("STA (Device mode %s(%d)) connected in band %u, Changing band to %u, Issuing Disconnect",
qdf_opmode_str(adapter->device_mode),
adapter->device_mode, current_band, band);
INIT_COMPLETION(adapter->disconnect_comp_var);
status = sme_roam_disconnect(
mac_handle,
adapter->vdev_id,
status = wlan_hdd_disconnect(adapter,
eCSR_DISCONNECT_REASON_UNSPECIFIED,
eSIR_MAC_OPER_CHANNEL_BAND_CHANGE);
if (QDF_STATUS_SUCCESS != status) {
hdd_err("sme_roam_disconnect failure, status: %d",
(int)status);
if (status) {
hdd_err("Hdd disconnect failed, status: %d",
status);
return -EINVAL;
}
lrc = wait_for_completion_timeout(
&adapter->disconnect_comp_var,
msecs_to_jiffies(
SME_DISCONNECT_TIMEOUT));
if (lrc == 0) {
hdd_err("Timeout while waiting for csr_roam_disconnect");
return -ETIMEDOUT;
}
}
ucfg_scan_flush_results(hdd_ctx->pdev, NULL);
}