Process QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH after NL80211_CMD_ROAM
NL80211_CMD_ROAM indication is scheduled via a kernel work queue, while QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH is a vendor event from the driver. Thus, a race condition can exist wherein the vendor event is received prior to the NL80211_CMD_ROAM indication. The processing of this vendor event depends on the NL80211_CMD_ROAM indication to update the roamed BSS/BSSID information and thus the out of sequence processing of these events would result in not updating the right BSS information. This commit adds a workaround to hold the pending QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH event for up to 100 ms in case NL80211_CMD_ROAM is not received first. Signed-off-by: Purushottam Kushwaha <pkushwah@codeaurora.org>
This commit is contained in:
parent
b4a41abad4
commit
74818ca63f
3 changed files with 53 additions and 1 deletions
|
@ -2986,6 +2986,9 @@ static void wpa_driver_nl80211_deinit(struct i802_bss *bss)
|
|||
os_free(drv->iface_ext_capa[i].ext_capa_mask);
|
||||
}
|
||||
os_free(drv->first_bss);
|
||||
#ifdef CONFIG_DRIVER_NL80211_QCA
|
||||
os_free(drv->pending_roam_data);
|
||||
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
||||
os_free(drv);
|
||||
}
|
||||
|
||||
|
@ -6187,6 +6190,9 @@ skip_auth_type:
|
|||
wpa_printf(MSG_DEBUG, "nl80211: MLME connect failed: ret=%d "
|
||||
"(%s)", ret, strerror(-ret));
|
||||
} else {
|
||||
#ifdef CONFIG_DRIVER_NL80211_QCA
|
||||
drv->roam_indication_done = false;
|
||||
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"nl80211: Connect request send successfully");
|
||||
}
|
||||
|
|
|
@ -221,6 +221,12 @@ struct wpa_driver_nl80211_data {
|
|||
* (NL80211_CMD_VENDOR). 0 if no pending scan request.
|
||||
*/
|
||||
int last_scan_cmd;
|
||||
#ifdef CONFIG_DRIVER_NL80211_QCA
|
||||
bool roam_indication_done;
|
||||
u8 *pending_roam_data;
|
||||
size_t pending_roam_data_len;
|
||||
struct os_reltime pending_roam_ind_time;
|
||||
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
||||
};
|
||||
|
||||
struct nl_msg;
|
||||
|
|
|
@ -2072,6 +2072,27 @@ static void qca_nl80211_key_mgmt_auth(struct wpa_driver_nl80211_data *drv,
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
qca_nl80211_key_mgmt_auth_handler(struct wpa_driver_nl80211_data *drv,
|
||||
const u8 *data, size_t len)
|
||||
{
|
||||
if (!drv->roam_indication_done) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"nl80211: Pending roam indication, delay processing roam+auth vendor event");
|
||||
os_get_reltime(&drv->pending_roam_ind_time);
|
||||
|
||||
os_free(drv->pending_roam_data);
|
||||
drv->pending_roam_data = os_memdup(data, len);
|
||||
if (!drv->pending_roam_data)
|
||||
return;
|
||||
drv->pending_roam_data_len = len;
|
||||
return;
|
||||
}
|
||||
drv->roam_indication_done = false;
|
||||
qca_nl80211_key_mgmt_auth(drv, data, len);
|
||||
}
|
||||
|
||||
|
||||
static void qca_nl80211_dfs_offload_radar_event(
|
||||
struct wpa_driver_nl80211_data *drv, u32 subcmd, u8 *msg, int length)
|
||||
{
|
||||
|
@ -2329,7 +2350,7 @@ static void nl80211_vendor_event_qca(struct wpa_driver_nl80211_data *drv,
|
|||
qca_nl80211_avoid_freq(drv, data, len);
|
||||
break;
|
||||
case QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH:
|
||||
qca_nl80211_key_mgmt_auth(drv, data, len);
|
||||
qca_nl80211_key_mgmt_auth_handler(drv, data, len);
|
||||
break;
|
||||
case QCA_NL80211_VENDOR_SUBCMD_DO_ACS:
|
||||
qca_nl80211_acs_select_ch(drv, data, len);
|
||||
|
@ -2721,17 +2742,36 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
|
|||
wpa_printf(MSG_DEBUG, "nl80211: Drv Event %d (%s) received for %s",
|
||||
cmd, nl80211_command_to_string(cmd), bss->ifname);
|
||||
|
||||
#ifdef CONFIG_DRIVER_NL80211_QCA
|
||||
if (cmd == NL80211_CMD_ROAM &&
|
||||
(drv->capa.flags & WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD)) {
|
||||
if (drv->pending_roam_data) {
|
||||
struct os_reltime now, age;
|
||||
|
||||
os_get_reltime(&now);
|
||||
os_reltime_sub(&now, &drv->pending_roam_ind_time, &age);
|
||||
if (age.sec == 0 && age.usec < 100000) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"nl80211: Process pending roam+auth vendor event");
|
||||
qca_nl80211_key_mgmt_auth(
|
||||
drv, drv->pending_roam_data,
|
||||
drv->pending_roam_data_len);
|
||||
}
|
||||
os_free(drv->pending_roam_data);
|
||||
drv->pending_roam_data = NULL;
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Device will use roam+auth vendor event to indicate
|
||||
* roaming, so ignore the regular roam event.
|
||||
*/
|
||||
drv->roam_indication_done = true;
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"nl80211: Ignore roam event (cmd=%d), device will use vendor event roam+auth",
|
||||
cmd);
|
||||
return;
|
||||
}
|
||||
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
||||
|
||||
if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED &&
|
||||
(cmd == NL80211_CMD_NEW_SCAN_RESULTS ||
|
||||
|
|
Loading…
Reference in a new issue