mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-27 12:57:53 +00:00
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>
This commit is contained in:
parent
4a0e642228
commit
32fed4706d
1 changed files with 88 additions and 83 deletions
|
@ -1944,6 +1944,94 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
|
|||
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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue