Skip to content

Commit a339e91

Browse files
lucacoelhoegrumbach
authored andcommitted
iwlwifi: mvm: handle pass all scan reporting
The firmware doesn't send match found notifications when no matchsets are passed. This makes sense because if there are no matchsets, nothing can be matched. But the nl80211 API should report when there are results available, even if no matchsets were passed. To handle this, we can use the firmware's ITERATION_COMPLETE reporting, which will send us notifications every time it completed a scheduled scan iteration. Then we can set a flag when we received beacons and use that to report that results are available. Signed-off-by: Luca Coelho <[email protected]> Signed-off-by: Emmanuel Grumbach <[email protected]>
1 parent 3cce9bb commit a339e91

File tree

3 files changed

+44
-5
lines changed

3 files changed

+44
-5
lines changed

drivers/net/wireless/intel/iwlwifi/mvm/mvm.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,12 @@ enum iwl_mvm_scan_type {
493493
IWL_SCAN_TYPE_FRAGMENTED,
494494
};
495495

496+
enum iwl_mvm_sched_scan_pass_all_states {
497+
SCHED_SCAN_PASS_ALL_DISABLED,
498+
SCHED_SCAN_PASS_ALL_ENABLED,
499+
SCHED_SCAN_PASS_ALL_FOUND,
500+
};
501+
496502
/**
497503
* struct iwl_nvm_section - describes an NVM section in memory.
498504
*
@@ -687,6 +693,7 @@ struct iwl_mvm {
687693
void *scan_cmd;
688694
struct iwl_mcast_filter_cmd *mcast_filter_cmd;
689695
enum iwl_mvm_scan_type scan_type;
696+
enum iwl_mvm_sched_scan_pass_all_states sched_scan_pass_all;
690697

691698
/* max number of simultaneous scans the FW supports */
692699
unsigned int max_scans;

drivers/net/wireless/intel/iwlwifi/mvm/rx.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,12 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi,
448448
iwl_mvm_update_frame_stats(mvm, rate_n_flags,
449449
rx_status->flag & RX_FLAG_AMPDU_DETAILS);
450450
#endif
451+
452+
if (unlikely((ieee80211_is_beacon(hdr->frame_control) ||
453+
ieee80211_is_probe_resp(hdr->frame_control)) &&
454+
mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_ENABLED))
455+
mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_FOUND;
456+
451457
iwl_mvm_pass_packet_to_mac80211(mvm, napi, skb, hdr, len, ampdu_status,
452458
crypt_len, rxb);
453459
}

drivers/net/wireless/intel/iwlwifi/mvm/scan.c

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*
88
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
99
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10+
* Copyright(c) 2016 Intel Deutschland GmbH
1011
*
1112
* This program is free software; you can redistribute it and/or modify
1213
* it under the terms of version 2 of the GNU General Public License as
@@ -33,6 +34,7 @@
3334
*
3435
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
3536
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
37+
* Copyright(c) 2016 Intel Deutschland GmbH
3638
* All rights reserved.
3739
*
3840
* Redistribution and use in source and binary forms, with or without
@@ -297,6 +299,12 @@ void iwl_mvm_rx_lmac_scan_iter_complete_notif(struct iwl_mvm *mvm,
297299
iwl_mvm_dump_channel_list(notif->results,
298300
notif->scanned_channels, buf,
299301
sizeof(buf)));
302+
303+
if (mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_FOUND) {
304+
IWL_DEBUG_SCAN(mvm, "Pass all scheduled scan results found\n");
305+
ieee80211_sched_scan_results(mvm->hw);
306+
mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_ENABLED;
307+
}
300308
}
301309

302310
void iwl_mvm_rx_scan_match_found(struct iwl_mvm *mvm,
@@ -380,6 +388,7 @@ void iwl_mvm_rx_lmac_scan_complete_notif(struct iwl_mvm *mvm,
380388

381389
mvm->scan_status &= ~IWL_MVM_SCAN_SCHED;
382390
ieee80211_sched_scan_stopped(mvm->hw);
391+
mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
383392
} else if (mvm->scan_status & IWL_MVM_SCAN_REGULAR) {
384393
IWL_DEBUG_SCAN(mvm, "Regular scan %s, EBS status %s (FW)\n",
385394
aborted ? "aborted" : "completed",
@@ -533,10 +542,13 @@ static bool iwl_mvm_scan_pass_all(struct iwl_mvm *mvm,
533542
IWL_DEBUG_SCAN(mvm,
534543
"Sending scheduled scan with filtering, n_match_sets %d\n",
535544
req->n_match_sets);
545+
mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
536546
return false;
537547
}
538548

539549
IWL_DEBUG_SCAN(mvm, "Sending Scheduled scan without filtering\n");
550+
551+
mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_ENABLED;
540552
return true;
541553
}
542554

@@ -788,6 +800,9 @@ static int iwl_mvm_scan_lmac_flags(struct iwl_mvm *mvm,
788800
flags |= IWL_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE;
789801
#endif
790802

803+
if (mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_ENABLED)
804+
flags |= IWL_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE;
805+
791806
if (iwl_mvm_is_regular_scan(params) &&
792807
vif->type != NL80211_IFTYPE_P2P_DEVICE &&
793808
params->type != IWL_SCAN_TYPE_FRAGMENTED)
@@ -1074,6 +1089,9 @@ static u32 iwl_mvm_scan_umac_flags(struct iwl_mvm *mvm,
10741089
flags |= IWL_UMAC_SCAN_GEN_FLAGS_ITER_COMPLETE;
10751090
#endif
10761091

1092+
if (mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_ENABLED)
1093+
flags |= IWL_UMAC_SCAN_GEN_FLAGS_ITER_COMPLETE;
1094+
10771095
if (iwl_mvm_is_regular_scan(params) &&
10781096
vif->type != NL80211_IFTYPE_P2P_DEVICE &&
10791097
params->type != IWL_SCAN_TYPE_FRAGMENTED)
@@ -1301,10 +1319,6 @@ int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
13011319
return -EBUSY;
13021320
}
13031321

1304-
/* we don't support "match all" in the firmware */
1305-
if (!req->n_match_sets)
1306-
return -EOPNOTSUPP;
1307-
13081322
ret = iwl_mvm_check_running_scans(mvm, type);
13091323
if (ret)
13101324
return ret;
@@ -1400,6 +1414,7 @@ void iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm,
14001414
iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
14011415
} else if (mvm->scan_uid_status[uid] == IWL_MVM_SCAN_SCHED) {
14021416
ieee80211_sched_scan_stopped(mvm->hw);
1417+
mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
14031418
}
14041419

14051420
mvm->scan_status &= ~mvm->scan_uid_status[uid];
@@ -1434,6 +1449,12 @@ void iwl_mvm_rx_umac_scan_iter_complete_notif(struct iwl_mvm *mvm,
14341449
iwl_mvm_dump_channel_list(notif->results,
14351450
notif->scanned_channels, buf,
14361451
sizeof(buf)));
1452+
1453+
if (mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_FOUND) {
1454+
IWL_DEBUG_SCAN(mvm, "Pass all scheduled scan results found\n");
1455+
ieee80211_sched_scan_results(mvm->hw);
1456+
mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_ENABLED;
1457+
}
14371458
}
14381459

14391460
static int iwl_mvm_umac_scan_abort(struct iwl_mvm *mvm, int type)
@@ -1528,6 +1549,7 @@ void iwl_mvm_report_scan_aborted(struct iwl_mvm *mvm)
15281549
uid = iwl_mvm_scan_uid_by_status(mvm, IWL_MVM_SCAN_SCHED);
15291550
if (uid >= 0 && !mvm->restart_fw) {
15301551
ieee80211_sched_scan_stopped(mvm->hw);
1552+
mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
15311553
mvm->scan_uid_status[uid] = 0;
15321554
}
15331555

@@ -1549,8 +1571,11 @@ void iwl_mvm_report_scan_aborted(struct iwl_mvm *mvm)
15491571
* restart_hw, so do not report if FW is about to be
15501572
* restarted.
15511573
*/
1552-
if ((mvm->scan_status & IWL_MVM_SCAN_SCHED) && !mvm->restart_fw)
1574+
if ((mvm->scan_status & IWL_MVM_SCAN_SCHED) &&
1575+
!mvm->restart_fw) {
15531576
ieee80211_sched_scan_stopped(mvm->hw);
1577+
mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
1578+
}
15541579
}
15551580
}
15561581

@@ -1586,6 +1611,7 @@ int iwl_mvm_scan_stop(struct iwl_mvm *mvm, int type, bool notify)
15861611
ieee80211_scan_completed(mvm->hw, true);
15871612
} else if (notify) {
15881613
ieee80211_sched_scan_stopped(mvm->hw);
1614+
mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
15891615
}
15901616

15911617
return ret;

0 commit comments

Comments
 (0)