Commit 250380c9 authored by Mordechay Goodstein's avatar Mordechay Goodstein Committed by Luca Coelho

iwlwifi: support version 9 of WOWLAN_GET_STATUS notification

Add support for the new WOWLAN_GET_STATUS notification that contains a
new element that informs the driver of TIDs whose BA sessions were
closed during suspend.

Note that the new functionality of handling these closed sessions is not
implemented in this patch it.  It only aligns to the new API version.
Signed-off-by: default avatarMordechay Goodstein <mordechay.goodstein@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/iwlwifi.20200417131727.b02153b94c1d.Ieb6291586d60f372d5a505604b18227ef97e7202@changeid
parent 7a99c877
...@@ -618,7 +618,7 @@ struct iwl_wowlan_status_v6 { ...@@ -618,7 +618,7 @@ struct iwl_wowlan_status_v6 {
* @wake_packet_bufsize: wakeup packet buffer size * @wake_packet_bufsize: wakeup packet buffer size
* @wake_packet: wakeup packet * @wake_packet: wakeup packet
*/ */
struct iwl_wowlan_status { struct iwl_wowlan_status_v7 {
struct iwl_wowlan_gtk_status gtk[WOWLAN_GTK_KEYS_NUM]; struct iwl_wowlan_gtk_status gtk[WOWLAN_GTK_KEYS_NUM];
struct iwl_wowlan_igtk_status igtk[WOWLAN_IGTK_KEYS_NUM]; struct iwl_wowlan_igtk_status igtk[WOWLAN_IGTK_KEYS_NUM];
__le64 replay_ctr; __le64 replay_ctr;
...@@ -634,6 +634,43 @@ struct iwl_wowlan_status { ...@@ -634,6 +634,43 @@ struct iwl_wowlan_status {
u8 wake_packet[]; /* can be truncated from _length to _bufsize */ u8 wake_packet[]; /* can be truncated from _length to _bufsize */
} __packed; /* WOWLAN_STATUSES_API_S_VER_7 */ } __packed; /* WOWLAN_STATUSES_API_S_VER_7 */
/**
* struct iwl_wowlan_status - WoWLAN status
* @gtk: GTK data
* @igtk: IGTK data
* @replay_ctr: GTK rekey replay counter
* @pattern_number: number of the matched pattern
* @non_qos_seq_ctr: non-QoS sequence counter to use next
* @qos_seq_ctr: QoS sequence counters to use next
* @wakeup_reasons: wakeup reasons, see &enum iwl_wowlan_wakeup_reason
* @num_of_gtk_rekeys: number of GTK rekeys
* @transmitted_ndps: number of transmitted neighbor discovery packets
* @received_beacons: number of received beacons
* @wake_packet_length: wakeup packet length
* @wake_packet_bufsize: wakeup packet buffer size
* @tid_tear_down: bit mask of tids whose BA sessions were closed
* in suspend state
* @reserved: unused
* @wake_packet: wakeup packet
*/
struct iwl_wowlan_status {
struct iwl_wowlan_gtk_status gtk[WOWLAN_GTK_KEYS_NUM];
struct iwl_wowlan_igtk_status igtk[WOWLAN_IGTK_KEYS_NUM];
__le64 replay_ctr;
__le16 pattern_number;
__le16 non_qos_seq_ctr;
__le16 qos_seq_ctr[8];
__le32 wakeup_reasons;
__le32 num_of_gtk_rekeys;
__le32 transmitted_ndps;
__le32 received_beacons;
__le32 wake_packet_length;
__le32 wake_packet_bufsize;
u8 tid_tear_down;
u8 reserved[3];
u8 wake_packet[]; /* can be truncated from _length to _bufsize */
} __packed; /* WOWLAN_STATUSES_API_S_VER_9 */
static inline u8 iwlmvm_wowlan_gtk_idx(struct iwl_wowlan_gtk_status *gtk) static inline u8 iwlmvm_wowlan_gtk_idx(struct iwl_wowlan_gtk_status *gtk)
{ {
return gtk->key_flags & IWL_WOWLAN_GTK_IDX_MASK; return gtk->key_flags & IWL_WOWLAN_GTK_IDX_MASK;
......
...@@ -1517,12 +1517,14 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm, ...@@ -1517,12 +1517,14 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
struct iwl_wowlan_status *iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm) struct iwl_wowlan_status *iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm)
{ {
struct iwl_wowlan_status *v7, *status; struct iwl_wowlan_status_v7 *v7;
struct iwl_wowlan_status *status;
struct iwl_host_cmd cmd = { struct iwl_host_cmd cmd = {
.id = WOWLAN_GET_STATUSES, .id = WOWLAN_GET_STATUSES,
.flags = CMD_WANT_SKB, .flags = CMD_WANT_SKB,
}; };
int ret, len, status_size; int ret, len, status_size, data_size;
u8 notif_ver;
lockdep_assert_held(&mvm->mutex); lockdep_assert_held(&mvm->mutex);
...@@ -1532,13 +1534,12 @@ struct iwl_wowlan_status *iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm) ...@@ -1532,13 +1534,12 @@ struct iwl_wowlan_status *iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm)
return ERR_PTR(ret); return ERR_PTR(ret);
} }
len = iwl_rx_packet_payload_len(cmd.resp_pkt);
if (!fw_has_api(&mvm->fw->ucode_capa, if (!fw_has_api(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_API_WOWLAN_KEY_MATERIAL)) { IWL_UCODE_TLV_API_WOWLAN_KEY_MATERIAL)) {
struct iwl_wowlan_status_v6 *v6 = (void *)cmd.resp_pkt->data; struct iwl_wowlan_status_v6 *v6 = (void *)cmd.resp_pkt->data;
int data_size;
status_size = sizeof(*v6); status_size = sizeof(*v6);
len = iwl_rx_packet_payload_len(cmd.resp_pkt);
if (len < status_size) { if (len < status_size) {
IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
...@@ -1593,23 +1594,33 @@ struct iwl_wowlan_status *iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm) ...@@ -1593,23 +1594,33 @@ struct iwl_wowlan_status *iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm)
} }
v7 = (void *)cmd.resp_pkt->data; v7 = (void *)cmd.resp_pkt->data;
notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP,
WOWLAN_GET_STATUSES, 0);
status_size = sizeof(*status);
if (notif_ver == IWL_FW_CMD_VER_UNKNOWN || notif_ver < 9)
status_size = sizeof(*v7); status_size = sizeof(*v7);
len = iwl_rx_packet_payload_len(cmd.resp_pkt);
if (len < status_size) { if (len < status_size) {
IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
status = ERR_PTR(-EIO); status = ERR_PTR(-EIO);
goto out_free_resp; goto out_free_resp;
} }
data_size = ALIGN(le32_to_cpu(v7->wake_packet_bufsize), 4);
if (len != (status_size + if (len != (status_size + data_size)) {
ALIGN(le32_to_cpu(v7->wake_packet_bufsize), 4))) {
IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
status = ERR_PTR(-EIO); status = ERR_PTR(-EIO);
goto out_free_resp; goto out_free_resp;
} }
status = kmemdup(v7, len, GFP_KERNEL); status = kzalloc(sizeof(*status) + data_size, GFP_KERNEL);
if (!status)
goto out_free_resp;
memcpy(status, v7, status_size);
memcpy(status->wake_packet, (u8 *)v7 + status_size, data_size);
out_free_resp: out_free_resp:
iwl_free_resp(&cmd); iwl_free_resp(&cmd);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment