iwlwifi: mvm: check and report if wake up was due to net detect

Query the firmware for scan offload matches when waking up in order to
report net detect as the reason for the wake up.

This requires a new command API to be implemented.  Additionally,
remove some net detect command entries that are not valid anymore.

Signed-off-by: Luciano Coelho <luciano.coelho@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
This commit is contained in:
Luciano Coelho 2014-11-20 15:58:34 +02:00 committed by Emmanuel Grumbach
parent a52703b202
commit b04998f3d5
4 changed files with 94 additions and 12 deletions

View File

@ -1626,14 +1626,50 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
return false;
}
static u32 iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm)
{
struct iwl_scan_offload_profiles_query *query;
struct iwl_host_cmd cmd = {
.id = SCAN_OFFLOAD_PROFILES_QUERY_CMD,
.flags = CMD_WANT_SKB,
};
int ret, len;
ret = iwl_mvm_send_cmd(mvm, &cmd);
if (ret) {
IWL_ERR(mvm, "failed to query matched profiles (%d)\n", ret);
return 0;
}
/* RF-kill already asserted again... */
if (!cmd.resp_pkt)
goto out_free_resp;
len = iwl_rx_packet_payload_len(cmd.resp_pkt);
if (len < sizeof(*query)) {
IWL_ERR(mvm, "Invalid scan offload profiles query response!\n");
goto out_free_resp;
}
query = (void *)cmd.resp_pkt->data;
ret = le32_to_cpu(query->matched_profiles);
out_free_resp:
iwl_free_resp(&cmd);
return ret;
}
static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm,
struct ieee80211_vif *vif)
{
struct cfg80211_wowlan_nd_info net_detect = {};
struct cfg80211_wowlan_wakeup wakeup = {
.pattern_idx = -1,
};
struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup;
struct iwl_wowlan_status *fw_status;
u32 matched_profiles;
u32 reasons = 0;
fw_status = iwl_mvm_get_wakeup_status(mvm, vif);
@ -1643,11 +1679,17 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm,
if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED)
wakeup.rfkill_release = true;
if (reasons == IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS) {
/* TODO: read and check if it was netdetect */
if (reasons != IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS)
goto out;
matched_profiles = iwl_mvm_netdetect_query_results(mvm);
if (!matched_profiles) {
wakeup_report = NULL;
goto out;
}
wakeup.net_detect = &net_detect;
out:
mutex_unlock(&mvm->mutex);
ieee80211_report_wowlan_wakeup(vif, wakeup_report, GFP_KERNEL);
}

View File

@ -1047,4 +1047,48 @@ struct iwl_umac_scan_complete {
__le32 reserved;
} __packed; /* SCAN_COMPLETE_NTF_UMAC_API_S_VER_1 */
#define SCAN_OFFLOAD_MATCHING_CHANNELS_LEN 5
/**
* struct iwl_scan_offload_profile_match - match information
* @bssid: matched bssid
* @channel: channel where the match occurred
* @energy:
* @matching_feature:
* @matching_channels: bitmap of channels that matched, referencing
* the channels passed in tue scan offload request
*/
struct iwl_scan_offload_profile_match {
u8 bssid[ETH_ALEN];
__le16 reserved;
u8 channel;
u8 energy;
u8 matching_feature;
u8 matching_channels[SCAN_OFFLOAD_MATCHING_CHANNELS_LEN];
} __packed; /* SCAN_OFFLOAD_PROFILE_MATCH_RESULTS_S_VER_1 */
/**
* struct iwl_scan_offload_profiles_query - match results query response
* @matched_profiles: bitmap of matched profiles, referencing the
* matches passed in the scan offload request
* @last_scan_age: age of the last offloaded scan
* @n_scans_done: number of offloaded scans done
* @gp2_d0u: GP2 when D0U occurred
* @gp2_invoked: GP2 when scan offload was invoked
* @resume_while_scanning: not used
* @self_recovery: obsolete
* @reserved: reserved
* @matches: array of match information, one for each match
*/
struct iwl_scan_offload_profiles_query {
__le32 matched_profiles;
__le32 last_scan_age;
__le32 n_scans_done;
__le32 gp2_d0u;
__le32 gp2_invoked;
u8 resume_while_scanning;
u8 self_recovery;
__le16 reserved;
struct iwl_scan_offload_profile_match matches[IWL_SCAN_MAX_PROFILES];
} __packed; /* SCAN_OFFLOAD_PROFILES_QUERY_RSP_S_VER_2 */
#endif

View File

@ -249,11 +249,9 @@ enum {
WOWLAN_TX_POWER_PER_DB = 0xe6,
/* and for NetDetect */
NET_DETECT_CONFIG_CMD = 0x54,
NET_DETECT_PROFILES_QUERY_CMD = 0x56,
NET_DETECT_PROFILES_CMD = 0x57,
NET_DETECT_HOTSPOTS_CMD = 0x58,
NET_DETECT_HOTSPOTS_QUERY_CMD = 0x59,
SCAN_OFFLOAD_PROFILES_QUERY_CMD = 0x56,
SCAN_OFFLOAD_HOTSPOTS_CONFIG_CMD = 0x58,
SCAN_OFFLOAD_HOTSPOTS_QUERY_CMD = 0x59,
REPLY_MAX = 0xff,
};

View File

@ -325,11 +325,9 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = {
CMD(WOWLAN_KEK_KCK_MATERIAL),
CMD(WOWLAN_GET_STATUSES),
CMD(WOWLAN_TX_POWER_PER_DB),
CMD(NET_DETECT_CONFIG_CMD),
CMD(NET_DETECT_PROFILES_QUERY_CMD),
CMD(NET_DETECT_PROFILES_CMD),
CMD(NET_DETECT_HOTSPOTS_CMD),
CMD(NET_DETECT_HOTSPOTS_QUERY_CMD),
CMD(SCAN_OFFLOAD_PROFILES_QUERY_CMD),
CMD(SCAN_OFFLOAD_HOTSPOTS_CONFIG_CMD),
CMD(SCAN_OFFLOAD_HOTSPOTS_QUERY_CMD),
CMD(CARD_STATE_NOTIFICATION),
CMD(MISSED_BEACONS_NOTIFICATION),
CMD(BT_COEX_PRIO_TABLE),