eloop_cancel_timeout(wpa_driver_nl80211_send_rfkill, drv, drv->ctx);
rfkill_deinit(drv->rfkill);
- eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
+ eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, bss->ctx);
if (!drv->start_iface_up)
(void) i802_set_iface_flags(bss, 0);
}
+u8 nl80211_get_link_id_from_link(struct i802_bss *bss, struct i802_link *link)
+{
+ u8 link_id;
+
+ if (link == bss->flink)
+ return 0;
+
+ for_each_link(bss->valid_links, link_id) {
+ if (&bss->links[link_id] == link)
+ return link_id;
+ }
+
+ return 0;
+}
+
+
static void nl80211_link_set_freq(struct i802_bss *bss, s8 link_id, int freq)
{
struct i802_link *link = nl80211_get_link(bss, link_id);
int err;
union wpa_event_data data;
struct survey_results *survey_results;
+ void *ctx = (bss->scan_link && bss->scan_link->ctx) ?
+ bss->scan_link->ctx : bss->ctx;
os_memset(&data, 0, sizeof(data));
survey_results = &data.survey_results;
if (err)
wpa_printf(MSG_ERROR, "nl80211: Failed to process survey data");
else
- wpa_supplicant_event(drv->ctx, EVENT_SURVEY, &data);
+ wpa_supplicant_event(ctx, EVENT_SURVEY, &data);
clean_survey_results(survey_results);
return err;
}
-static void send_scan_event(struct wpa_driver_nl80211_data *drv, int aborted,
+static void send_scan_event(struct i802_bss *bss, int aborted,
struct nlattr *tb[], int external_scan)
{
+ struct wpa_driver_nl80211_data *drv = bss->drv;
union wpa_event_data event;
struct nlattr *nl;
int rem;
#define MAX_REPORT_FREQS 110
int freqs[MAX_REPORT_FREQS];
int num_freqs = 0;
+ struct i802_link *mld_link;
+ void *ctx = bss->ctx;
if (!external_scan && drv->scan_for_auth) {
drv->scan_for_auth = 0;
ETH_ALEN);
}
- wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, &event);
+ /* Need to pass to the correct link ctx during AP MLD operation */
+ if (is_ap_interface(drv->nlmode)) {
+ mld_link = bss->scan_link;
+ if (!mld_link) {
+ wpa_printf(MSG_DEBUG,
+ "nl80211: Scan event on unknown link");
+ } else if (mld_link->ctx) {
+ u8 link_id = nl80211_get_link_id_from_link(bss,
+ mld_link);
+
+ wpa_printf(MSG_DEBUG,
+ "nl80211: Scan event for link_id %d",
+ link_id);
+ ctx = mld_link->ctx;
+ }
+ }
+
+ wpa_supplicant_event(ctx, EVENT_SCAN_RESULTS, &event);
}
drv->scan_state = SCAN_ABORTED;
eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
- drv->ctx);
+ drv->first_bss->ctx);
drv->vendor_scan_cookie = 0;
drv->last_scan_cmd = 0;
}
switch (cmd) {
case NL80211_CMD_TRIGGER_SCAN:
- wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan trigger");
+ wpa_dbg(bss->ctx, MSG_DEBUG, "nl80211: Scan trigger");
drv->scan_state = SCAN_STARTED;
if (drv->scan_for_auth) {
/*
wpa_printf(MSG_DEBUG, "nl80211: Do not indicate scan-start event due to internal scan_for_auth");
break;
}
- wpa_supplicant_event(drv->ctx, EVENT_SCAN_STARTED, NULL);
+ wpa_supplicant_event(bss->ctx, EVENT_SCAN_STARTED, NULL);
break;
case NL80211_CMD_START_SCHED_SCAN:
- wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan started");
+ wpa_dbg(bss->ctx, MSG_DEBUG, "nl80211: Sched scan started");
drv->scan_state = SCHED_SCAN_STARTED;
break;
case NL80211_CMD_SCHED_SCAN_STOPPED:
- wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan stopped");
+ wpa_dbg(bss->ctx, MSG_DEBUG, "nl80211: Sched scan stopped");
drv->scan_state = SCHED_SCAN_STOPPED;
- wpa_supplicant_event(drv->ctx, EVENT_SCHED_SCAN_STOPPED, NULL);
+ wpa_supplicant_event(bss->ctx, EVENT_SCHED_SCAN_STOPPED, NULL);
break;
case NL80211_CMD_NEW_SCAN_RESULTS:
- wpa_dbg(drv->ctx, MSG_DEBUG,
+ wpa_dbg(bss->ctx, MSG_DEBUG,
"nl80211: New scan results available");
if (drv->last_scan_cmd != NL80211_CMD_VENDOR)
drv->scan_state = SCAN_COMPLETED;
drv->scan_complete_events = 1;
if (drv->last_scan_cmd == NL80211_CMD_TRIGGER_SCAN) {
eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout,
- drv, drv->ctx);
+ drv, bss->ctx);
drv->last_scan_cmd = 0;
} else {
external_scan_event = 1;
}
- send_scan_event(drv, 0, tb, external_scan_event);
+ send_scan_event(bss, 0, tb, external_scan_event);
break;
case NL80211_CMD_SCHED_SCAN_RESULTS:
- wpa_dbg(drv->ctx, MSG_DEBUG,
+ wpa_dbg(bss->ctx, MSG_DEBUG,
"nl80211: New sched scan results available");
drv->scan_state = SCHED_SCAN_RESULTS;
- send_scan_event(drv, 0, tb, 0);
+ send_scan_event(bss, 0, tb, 0);
break;
case NL80211_CMD_SCAN_ABORTED:
- wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan aborted");
+ wpa_dbg(bss->ctx, MSG_DEBUG, "nl80211: Scan aborted");
if (drv->last_scan_cmd != NL80211_CMD_VENDOR)
drv->scan_state = SCAN_ABORTED;
if (drv->last_scan_cmd == NL80211_CMD_TRIGGER_SCAN) {
* order not to make wpa_supplicant stop its scanning.
*/
eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout,
- drv, drv->ctx);
+ drv, bss->ctx);
drv->last_scan_cmd = 0;
} else {
external_scan_event = 1;
}
- send_scan_event(drv, 1, tb, external_scan_event);
+ send_scan_event(bss, 1, tb, external_scan_event);
break;
case NL80211_CMD_AUTHENTICATE:
case NL80211_CMD_ASSOCIATE:
void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx)
{
struct wpa_driver_nl80211_data *drv = eloop_ctx;
+ struct i802_bss *bss;
wpa_printf(MSG_DEBUG, "nl80211: Scan timeout - try to abort it");
#ifdef CONFIG_DRIVER_NL80211_QCA
nl80211_abort_vendor_scan(drv, drv->vendor_scan_cookie) == 0)
return;
#endif /* CONFIG_DRIVER_NL80211_QCA */
+
+ for (bss = drv->first_bss; bss; bss = bss->next) {
+ if (bss->scan_link)
+ break;
+ }
+
+ if (!bss) {
+ wpa_printf(MSG_DEBUG, "nl80211: Failed to find scan BSS");
+ return;
+ }
+
if (!drv->vendor_scan_cookie &&
- nl80211_abort_scan(drv->first_bss) == 0)
+ nl80211_abort_scan(bss) == 0) {
+ bss->scan_link = NULL;
return;
+ }
wpa_printf(MSG_DEBUG, "nl80211: Failed to abort scan");
if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED)
- nl80211_restore_ap_mode(drv->first_bss);
+ nl80211_restore_ap_mode(bss);
wpa_printf(MSG_DEBUG, "nl80211: Try to get scan results");
wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
int ret = -1, timeout;
struct nl_msg *msg = NULL;
- wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: scan request");
+ wpa_dbg(bss->ctx, MSG_DEBUG, "nl80211: scan request");
drv->scan_for_auth = 0;
if (TEST_FAIL())
}
wpa_printf(MSG_DEBUG, "Scan requested (ret=%d) - scan timeout %d "
"seconds", ret, timeout);
- eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
+ eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, bss->ctx);
eloop_register_timeout(timeout, 0, wpa_driver_nl80211_scan_timeout,
- drv, drv->ctx);
+ drv, bss->ctx);
drv->last_scan_cmd = NL80211_CMD_TRIGGER_SCAN;
+ bss->scan_link = bss->flink;
+ if (is_ap_interface(drv->nlmode) &&
+ nl80211_link_valid(bss->valid_links, params->link_id)) {
+ wpa_dbg(bss->ctx, MSG_DEBUG,
+ "nl80211: Scan requested for link %d",
+ params->link_id);
+ bss->scan_link = nl80211_get_link(bss, params->link_id);
+ }
+
fail:
nlmsg_free(msg);
return ret;
wpa_printf(MSG_DEBUG,
"nl80211: Vendor scan requested (ret=%d) - scan timeout 30 seconds, scan cookie:0x%llx",
ret, (long long unsigned int) cookie);
- eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
+ eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, bss->ctx);
eloop_register_timeout(30, 0, wpa_driver_nl80211_scan_timeout,
- drv, drv->ctx);
+ drv, bss->ctx);
drv->last_scan_cmd = NL80211_CMD_VENDOR;
fail: