diff options
author | Naftali Goldstein <naftali.goldstein@intel.com> | 2022-09-06 16:42:19 +0300 |
---|---|---|
committer | Gregory Greenman <gregory.greenman@intel.com> | 2022-09-18 14:40:17 +0300 |
commit | 32fed4706d9aca31c9d575c1efa4a3624a9d5543 (patch) | |
tree | 202fa296f08730d91f4b6a890ca5ba9f376cc058 /drivers/net/wireless/intel | |
parent | 4a0e642228379e6329e36b932749c59497109ade (diff) | |
download | linux-32fed4706d9aca31c9d575c1efa4a3624a9d5543.tar.xz |
wifi: iwlwifi: mvm: d3: parse keys from wowlan info notification
This notification replaces the WOWLAN_GET_STATUSES command-and-response,
so it's required to parse all the keys in the notification just like
what happened when that command was used.
Move around a few required static functions in order to avoid forward
declarations.
Signed-off-by: Naftali Goldstein <naftali.goldstein@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20220906161827.ca3fb23cab81.I0a9fe7729af4567b98813bc51bad13ee5512a0ae@changeid
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
Diffstat (limited to 'drivers/net/wireless/intel')
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 171 |
1 files changed, 88 insertions, 83 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index d8a67f391ab9..919b1f478b4c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -1944,6 +1944,94 @@ out: return true; } +static void iwl_mvm_convert_gtk_v2(struct iwl_wowlan_status_data *status, + struct iwl_wowlan_gtk_status_v2 *data) +{ + BUILD_BUG_ON(sizeof(status->gtk.key) < sizeof(data->key)); + BUILD_BUG_ON(NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY + + sizeof(data->tkip_mic_key) > + sizeof(status->gtk.key)); + + status->gtk.len = data->key_len; + status->gtk.flags = data->key_flags; + + memcpy(status->gtk.key, data->key, sizeof(data->key)); + + /* if it's as long as the TKIP encryption key, copy MIC key */ + if (status->gtk.len == NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY) + memcpy(status->gtk.key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY, + data->tkip_mic_key, sizeof(data->tkip_mic_key)); +} + +static void iwl_mvm_convert_gtk_v3(struct iwl_wowlan_status_data *status, + struct iwl_wowlan_gtk_status_v3 *data) +{ + /* The parts we need are identical in v2 and v3 */ +#define CHECK(_f) do { \ + BUILD_BUG_ON(offsetof(struct iwl_wowlan_gtk_status_v2, _f) != \ + offsetof(struct iwl_wowlan_gtk_status_v3, _f)); \ + BUILD_BUG_ON(offsetofend(struct iwl_wowlan_gtk_status_v2, _f) !=\ + offsetofend(struct iwl_wowlan_gtk_status_v3, _f)); \ +} while (0) + + CHECK(key); + CHECK(key_len); + CHECK(key_flags); + CHECK(tkip_mic_key); +#undef CHECK + + iwl_mvm_convert_gtk_v2(status, (void *)data); +} + +static void iwl_mvm_convert_igtk(struct iwl_wowlan_status_data *status, + struct iwl_wowlan_igtk_status *data) +{ + const u8 *ipn = data->ipn; + + BUILD_BUG_ON(sizeof(status->igtk.key) < sizeof(data->key)); + + status->igtk.len = data->key_len; + status->igtk.flags = data->key_flags; + + memcpy(status->igtk.key, data->key, sizeof(data->key)); + + status->igtk.ipn = ((u64)ipn[5] << 0) | + ((u64)ipn[4] << 8) | + ((u64)ipn[3] << 16) | + ((u64)ipn[2] << 24) | + ((u64)ipn[1] << 32) | + ((u64)ipn[0] << 40); +} + +static void iwl_mvm_parse_wowlan_info_notif(struct iwl_mvm *mvm, + struct iwl_wowlan_info_notif *data, + struct iwl_wowlan_status_data *status, + u32 len) +{ + u32 i; + + if (len < sizeof(*data)) { + IWL_ERR(mvm, "Invalid WoWLAN info notification!\n"); + status = NULL; + return; + } + + iwl_mvm_convert_key_counters_v5(status, &data->gtk[0].sc); + iwl_mvm_convert_gtk_v3(status, &data->gtk[0]); + iwl_mvm_convert_igtk(status, &data->igtk[0]); + + status->replay_ctr = le64_to_cpu(data->replay_ctr); + status->pattern_number = le16_to_cpu(data->pattern_number); + for (i = 0; i < IWL_MAX_TID_COUNT; i++) + status->qos_seq_ctr[i] = + le16_to_cpu(data->qos_seq_ctr[i]); + status->wakeup_reasons = le32_to_cpu(data->wakeup_reasons); + status->num_of_gtk_rekeys = + le32_to_cpu(data->num_of_gtk_rekeys); + status->received_beacons = le32_to_cpu(data->received_beacons); + status->tid_tear_down = data->tid_tear_down; +} + /* Occasionally, templates would be nice. This is one of those times ... */ #define iwl_mvm_parse_wowlan_status_common(_ver) \ static struct iwl_wowlan_status_data * \ @@ -2005,89 +2093,6 @@ iwl_mvm_parse_wowlan_status_common(v7) iwl_mvm_parse_wowlan_status_common(v9) iwl_mvm_parse_wowlan_status_common(v12) -static void iwl_mvm_parse_wowlan_info_notif(struct iwl_mvm *mvm, - struct iwl_wowlan_info_notif *data, - struct iwl_wowlan_status_data *status, - u32 len) -{ - u32 i; - - if (len < sizeof(*data)) { - IWL_ERR(mvm, "Invalid WoWLAN info notification!\n"); - status = NULL; - return; - } - - status->replay_ctr = le64_to_cpu(data->replay_ctr); - status->pattern_number = le16_to_cpu(data->pattern_number); - for (i = 0; i < IWL_MAX_TID_COUNT; i++) - status->qos_seq_ctr[i] = - le16_to_cpu(data->qos_seq_ctr[i]); - status->wakeup_reasons = le32_to_cpu(data->wakeup_reasons); - status->num_of_gtk_rekeys = - le32_to_cpu(data->num_of_gtk_rekeys); - status->received_beacons = le32_to_cpu(data->received_beacons); -} - -static void iwl_mvm_convert_gtk_v2(struct iwl_wowlan_status_data *status, - struct iwl_wowlan_gtk_status_v2 *data) -{ - BUILD_BUG_ON(sizeof(status->gtk.key) < sizeof(data->key)); - BUILD_BUG_ON(NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY + - sizeof(data->tkip_mic_key) > - sizeof(status->gtk.key)); - - status->gtk.len = data->key_len; - status->gtk.flags = data->key_flags; - - memcpy(status->gtk.key, data->key, sizeof(data->key)); - - /* if it's as long as the TKIP encryption key, copy MIC key */ - if (status->gtk.len == NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY) - memcpy(status->gtk.key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY, - data->tkip_mic_key, sizeof(data->tkip_mic_key)); -} - -static void iwl_mvm_convert_gtk_v3(struct iwl_wowlan_status_data *status, - struct iwl_wowlan_gtk_status_v3 *data) -{ - /* The parts we need are identical in v2 and v3 */ -#define CHECK(_f) do { \ - BUILD_BUG_ON(offsetof(struct iwl_wowlan_gtk_status_v2, _f) != \ - offsetof(struct iwl_wowlan_gtk_status_v3, _f)); \ - BUILD_BUG_ON(offsetofend(struct iwl_wowlan_gtk_status_v2, _f) !=\ - offsetofend(struct iwl_wowlan_gtk_status_v3, _f)); \ -} while (0) - - CHECK(key); - CHECK(key_len); - CHECK(key_flags); - CHECK(tkip_mic_key); -#undef CHECK - - iwl_mvm_convert_gtk_v2(status, (void *)data); -} - -static void iwl_mvm_convert_igtk(struct iwl_wowlan_status_data *status, - struct iwl_wowlan_igtk_status *data) -{ - const u8 *ipn = data->ipn; - - BUILD_BUG_ON(sizeof(status->igtk.key) < sizeof(data->key)); - - status->igtk.len = data->key_len; - status->igtk.flags = data->key_flags; - - memcpy(status->igtk.key, data->key, sizeof(data->key)); - - status->igtk.ipn = ((u64)ipn[5] << 0) | - ((u64)ipn[4] << 8) | - ((u64)ipn[3] << 16) | - ((u64)ipn[2] << 24) | - ((u64)ipn[1] << 32) | - ((u64)ipn[0] << 40); -} - static struct iwl_wowlan_status_data * iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm, u8 sta_id) { |