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->iface_ext_capa[i].ext_capa_mask);
|
||||||
}
|
}
|
||||||
os_free(drv->first_bss);
|
os_free(drv->first_bss);
|
||||||
|
#ifdef CONFIG_DRIVER_NL80211_QCA
|
||||||
|
os_free(drv->pending_roam_data);
|
||||||
|
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
||||||
os_free(drv);
|
os_free(drv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6187,6 +6190,9 @@ skip_auth_type:
|
||||||
wpa_printf(MSG_DEBUG, "nl80211: MLME connect failed: ret=%d "
|
wpa_printf(MSG_DEBUG, "nl80211: MLME connect failed: ret=%d "
|
||||||
"(%s)", ret, strerror(-ret));
|
"(%s)", ret, strerror(-ret));
|
||||||
} else {
|
} else {
|
||||||
|
#ifdef CONFIG_DRIVER_NL80211_QCA
|
||||||
|
drv->roam_indication_done = false;
|
||||||
|
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"nl80211: Connect request send successfully");
|
"nl80211: Connect request send successfully");
|
||||||
}
|
}
|
||||||
|
|
|
@ -221,6 +221,12 @@ struct wpa_driver_nl80211_data {
|
||||||
* (NL80211_CMD_VENDOR). 0 if no pending scan request.
|
* (NL80211_CMD_VENDOR). 0 if no pending scan request.
|
||||||
*/
|
*/
|
||||||
int last_scan_cmd;
|
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;
|
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(
|
static void qca_nl80211_dfs_offload_radar_event(
|
||||||
struct wpa_driver_nl80211_data *drv, u32 subcmd, u8 *msg, int length)
|
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);
|
qca_nl80211_avoid_freq(drv, data, len);
|
||||||
break;
|
break;
|
||||||
case QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH:
|
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;
|
break;
|
||||||
case QCA_NL80211_VENDOR_SUBCMD_DO_ACS:
|
case QCA_NL80211_VENDOR_SUBCMD_DO_ACS:
|
||||||
qca_nl80211_acs_select_ch(drv, data, len);
|
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",
|
wpa_printf(MSG_DEBUG, "nl80211: Drv Event %d (%s) received for %s",
|
||||||
cmd, nl80211_command_to_string(cmd), bss->ifname);
|
cmd, nl80211_command_to_string(cmd), bss->ifname);
|
||||||
|
|
||||||
|
#ifdef CONFIG_DRIVER_NL80211_QCA
|
||||||
if (cmd == NL80211_CMD_ROAM &&
|
if (cmd == NL80211_CMD_ROAM &&
|
||||||
(drv->capa.flags & WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD)) {
|
(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
|
* Device will use roam+auth vendor event to indicate
|
||||||
* roaming, so ignore the regular roam event.
|
* roaming, so ignore the regular roam event.
|
||||||
*/
|
*/
|
||||||
|
drv->roam_indication_done = true;
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"nl80211: Ignore roam event (cmd=%d), device will use vendor event roam+auth",
|
"nl80211: Ignore roam event (cmd=%d), device will use vendor event roam+auth",
|
||||||
cmd);
|
cmd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
||||||
|
|
||||||
if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED &&
|
if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED &&
|
||||||
(cmd == NL80211_CMD_NEW_SCAN_RESULTS ||
|
(cmd == NL80211_CMD_NEW_SCAN_RESULTS ||
|
||||||
|
|
Loading…
Reference in a new issue