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);
}
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");
}
}
+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)
{
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);
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 ||