aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuciano Coelho <luciano.coelho@intel.com>2014-11-20 08:58:34 -0500
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-12-01 05:04:35 -0500
commitb04998f3d57adc9ccde264b125bc4ff00b9993d5 (patch)
tree7a1e2d815448b0733b9c1ece041738f7a0387b18
parenta52703b2020f46d95e9f8e837615b5754c06a0ea (diff)
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>
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c46
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h44
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h8
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c8
4 files changed, 94 insertions, 12 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index 60748bd37954..8970386f6b9f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -1626,14 +1626,50 @@ out_unlock:
1626 return false; 1626 return false;
1627} 1627}
1628 1628
1629static u32 iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm)
1630{
1631 struct iwl_scan_offload_profiles_query *query;
1632 struct iwl_host_cmd cmd = {
1633 .id = SCAN_OFFLOAD_PROFILES_QUERY_CMD,
1634 .flags = CMD_WANT_SKB,
1635 };
1636 int ret, len;
1637
1638 ret = iwl_mvm_send_cmd(mvm, &cmd);
1639 if (ret) {
1640 IWL_ERR(mvm, "failed to query matched profiles (%d)\n", ret);
1641 return 0;
1642 }
1643
1644 /* RF-kill already asserted again... */
1645 if (!cmd.resp_pkt)
1646 goto out_free_resp;
1647
1648 len = iwl_rx_packet_payload_len(cmd.resp_pkt);
1649 if (len < sizeof(*query)) {
1650 IWL_ERR(mvm, "Invalid scan offload profiles query response!\n");
1651 goto out_free_resp;
1652 }
1653
1654 query = (void *)cmd.resp_pkt->data;
1655
1656 ret = le32_to_cpu(query->matched_profiles);
1657
1658out_free_resp:
1659 iwl_free_resp(&cmd);
1660 return ret;
1661}
1662
1629static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm, 1663static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm,
1630 struct ieee80211_vif *vif) 1664 struct ieee80211_vif *vif)
1631{ 1665{
1666 struct cfg80211_wowlan_nd_info net_detect = {};
1632 struct cfg80211_wowlan_wakeup wakeup = { 1667 struct cfg80211_wowlan_wakeup wakeup = {
1633 .pattern_idx = -1, 1668 .pattern_idx = -1,
1634 }; 1669 };
1635 struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup; 1670 struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup;
1636 struct iwl_wowlan_status *fw_status; 1671 struct iwl_wowlan_status *fw_status;
1672 u32 matched_profiles;
1637 u32 reasons = 0; 1673 u32 reasons = 0;
1638 1674
1639 fw_status = iwl_mvm_get_wakeup_status(mvm, vif); 1675 fw_status = iwl_mvm_get_wakeup_status(mvm, vif);
@@ -1643,11 +1679,17 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm,
1643 if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) 1679 if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED)
1644 wakeup.rfkill_release = true; 1680 wakeup.rfkill_release = true;
1645 1681
1646 if (reasons == IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS) { 1682 if (reasons != IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS)
1647 /* TODO: read and check if it was netdetect */ 1683 goto out;
1684
1685 matched_profiles = iwl_mvm_netdetect_query_results(mvm);
1686 if (!matched_profiles) {
1648 wakeup_report = NULL; 1687 wakeup_report = NULL;
1688 goto out;
1649 } 1689 }
1650 1690
1691 wakeup.net_detect = &net_detect;
1692out:
1651 mutex_unlock(&mvm->mutex); 1693 mutex_unlock(&mvm->mutex);
1652 ieee80211_report_wowlan_wakeup(vif, wakeup_report, GFP_KERNEL); 1694 ieee80211_report_wowlan_wakeup(vif, wakeup_report, GFP_KERNEL);
1653} 1695}
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
index 7163eb391826..1f2acf47bfb2 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
@@ -1047,4 +1047,48 @@ struct iwl_umac_scan_complete {
1047 __le32 reserved; 1047 __le32 reserved;
1048} __packed; /* SCAN_COMPLETE_NTF_UMAC_API_S_VER_1 */ 1048} __packed; /* SCAN_COMPLETE_NTF_UMAC_API_S_VER_1 */
1049 1049
1050#define SCAN_OFFLOAD_MATCHING_CHANNELS_LEN 5
1051/**
1052 * struct iwl_scan_offload_profile_match - match information
1053 * @bssid: matched bssid
1054 * @channel: channel where the match occurred
1055 * @energy:
1056 * @matching_feature:
1057 * @matching_channels: bitmap of channels that matched, referencing
1058 * the channels passed in tue scan offload request
1059 */
1060struct iwl_scan_offload_profile_match {
1061 u8 bssid[ETH_ALEN];
1062 __le16 reserved;
1063 u8 channel;
1064 u8 energy;
1065 u8 matching_feature;
1066 u8 matching_channels[SCAN_OFFLOAD_MATCHING_CHANNELS_LEN];
1067} __packed; /* SCAN_OFFLOAD_PROFILE_MATCH_RESULTS_S_VER_1 */
1068
1069/**
1070 * struct iwl_scan_offload_profiles_query - match results query response
1071 * @matched_profiles: bitmap of matched profiles, referencing the
1072 * matches passed in the scan offload request
1073 * @last_scan_age: age of the last offloaded scan
1074 * @n_scans_done: number of offloaded scans done
1075 * @gp2_d0u: GP2 when D0U occurred
1076 * @gp2_invoked: GP2 when scan offload was invoked
1077 * @resume_while_scanning: not used
1078 * @self_recovery: obsolete
1079 * @reserved: reserved
1080 * @matches: array of match information, one for each match
1081 */
1082struct iwl_scan_offload_profiles_query {
1083 __le32 matched_profiles;
1084 __le32 last_scan_age;
1085 __le32 n_scans_done;
1086 __le32 gp2_d0u;
1087 __le32 gp2_invoked;
1088 u8 resume_while_scanning;
1089 u8 self_recovery;
1090 __le16 reserved;
1091 struct iwl_scan_offload_profile_match matches[IWL_SCAN_MAX_PROFILES];
1092} __packed; /* SCAN_OFFLOAD_PROFILES_QUERY_RSP_S_VER_2 */
1093
1050#endif 1094#endif
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index 2ff4f41d79bd..01d6f9e5db51 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -249,11 +249,9 @@ enum {
249 WOWLAN_TX_POWER_PER_DB = 0xe6, 249 WOWLAN_TX_POWER_PER_DB = 0xe6,
250 250
251 /* and for NetDetect */ 251 /* and for NetDetect */
252 NET_DETECT_CONFIG_CMD = 0x54, 252 SCAN_OFFLOAD_PROFILES_QUERY_CMD = 0x56,
253 NET_DETECT_PROFILES_QUERY_CMD = 0x56, 253 SCAN_OFFLOAD_HOTSPOTS_CONFIG_CMD = 0x58,
254 NET_DETECT_PROFILES_CMD = 0x57, 254 SCAN_OFFLOAD_HOTSPOTS_QUERY_CMD = 0x59,
255 NET_DETECT_HOTSPOTS_CMD = 0x58,
256 NET_DETECT_HOTSPOTS_QUERY_CMD = 0x59,
257 255
258 REPLY_MAX = 0xff, 256 REPLY_MAX = 0xff,
259}; 257};
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index b3ae094db907..b952e7904a07 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -325,11 +325,9 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = {
325 CMD(WOWLAN_KEK_KCK_MATERIAL), 325 CMD(WOWLAN_KEK_KCK_MATERIAL),
326 CMD(WOWLAN_GET_STATUSES), 326 CMD(WOWLAN_GET_STATUSES),
327 CMD(WOWLAN_TX_POWER_PER_DB), 327 CMD(WOWLAN_TX_POWER_PER_DB),
328 CMD(NET_DETECT_CONFIG_CMD), 328 CMD(SCAN_OFFLOAD_PROFILES_QUERY_CMD),
329 CMD(NET_DETECT_PROFILES_QUERY_CMD), 329 CMD(SCAN_OFFLOAD_HOTSPOTS_CONFIG_CMD),
330 CMD(NET_DETECT_PROFILES_CMD), 330 CMD(SCAN_OFFLOAD_HOTSPOTS_QUERY_CMD),
331 CMD(NET_DETECT_HOTSPOTS_CMD),
332 CMD(NET_DETECT_HOTSPOTS_QUERY_CMD),
333 CMD(CARD_STATE_NOTIFICATION), 331 CMD(CARD_STATE_NOTIFICATION),
334 CMD(MISSED_BEACONS_NOTIFICATION), 332 CMD(MISSED_BEACONS_NOTIFICATION),
335 CMD(BT_COEX_PRIO_TABLE), 333 CMD(BT_COEX_PRIO_TABLE),