wifi: iwlwifi: mvm: support wowlan info notification version 2
authorHaim Dreyfuss <haim.dreyfuss@intel.com>
Thu, 13 Apr 2023 18:40:27 +0000 (21:40 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 5 Jun 2023 07:26:20 +0000 (09:26 +0200)
[ Upstream commit 905d50ddbc83bef0d7f3386e7f3472b0324b405b ]

As part of version 2 we don't need to have wake_packet_bufsize
and wake_packet_length. The first one is already calculated by the driver,
the latter is sent as part of the wake packet notification.

Signed-off-by: Haim Dreyfuss <haim.dreyfuss@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230413213309.3b53213b10d4.Ibf2f15aca614def2d262dd267d1aad65931b58f1@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Stable-dep-of: 457d7fb03e6c ("wifi: iwlwifi: mvm: fix potential memory leak")
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
drivers/net/wireless/intel/iwlwifi/mvm/d3.c

index df08338..8a613e1 100644 (file)
@@ -767,7 +767,7 @@ struct iwl_wowlan_status_v12 {
 } __packed; /* WOWLAN_STATUSES_RSP_API_S_VER_12 */
 
 /**
- * struct iwl_wowlan_info_notif - WoWLAN information notification
+ * struct iwl_wowlan_info_notif_v1 - WoWLAN information notification
  * @gtk: GTK data
  * @igtk: IGTK data
  * @replay_ctr: GTK rekey replay counter
@@ -785,7 +785,7 @@ struct iwl_wowlan_status_v12 {
  * @station_id: station id
  * @reserved2: reserved
  */
-struct iwl_wowlan_info_notif {
+struct iwl_wowlan_info_notif_v1 {
        struct iwl_wowlan_gtk_status_v3 gtk[WOWLAN_GTK_KEYS_NUM];
        struct iwl_wowlan_igtk_status igtk[WOWLAN_IGTK_KEYS_NUM];
        __le64 replay_ctr;
@@ -804,6 +804,39 @@ struct iwl_wowlan_info_notif {
 } __packed; /* WOWLAN_INFO_NTFY_API_S_VER_1 */
 
 /**
+ * struct iwl_wowlan_info_notif - WoWLAN information notification
+ * @gtk: GTK data
+ * @igtk: IGTK data
+ * @replay_ctr: GTK rekey replay counter
+ * @pattern_number: number of the matched patterns
+ * @reserved1: reserved
+ * @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
+ * @tid_tear_down: bit mask of tids whose BA sessions were closed
+ *     in suspend state
+ * @station_id: station id
+ * @reserved2: reserved
+ */
+struct iwl_wowlan_info_notif {
+       struct iwl_wowlan_gtk_status_v3 gtk[WOWLAN_GTK_KEYS_NUM];
+       struct iwl_wowlan_igtk_status igtk[WOWLAN_IGTK_KEYS_NUM];
+       __le64 replay_ctr;
+       __le16 pattern_number;
+       __le16 reserved1;
+       __le16 qos_seq_ctr[8];
+       __le32 wakeup_reasons;
+       __le32 num_of_gtk_rekeys;
+       __le32 transmitted_ndps;
+       __le32 received_beacons;
+       u8 tid_tear_down;
+       u8 station_id;
+       u8 reserved2[2];
+} __packed; /* WOWLAN_INFO_NTFY_API_S_VER_2 */
+
+/**
  * struct iwl_wowlan_wake_pkt_notif - WoWLAN wake packet notification
  * @wake_packet_length: wakeup packet length
  * @station_id: station id
index bbdda3e..0253ded 100644 (file)
@@ -2011,6 +2011,12 @@ static void iwl_mvm_parse_wowlan_info_notif(struct iwl_mvm *mvm,
 {
        u32 i;
 
+       if (!data) {
+               IWL_ERR(mvm, "iwl_wowlan_info_notif data is NULL\n");
+               status = NULL;
+               return;
+       }
+
        if (len < sizeof(*data)) {
                IWL_ERR(mvm, "Invalid WoWLAN info notification!\n");
                status = NULL;
@@ -2698,10 +2704,33 @@ static bool iwl_mvm_wait_d3_notif(struct iwl_notif_wait_data *notif_wait,
        struct iwl_d3_data *d3_data = data;
        u32 len;
        int ret;
+       int wowlan_info_ver = iwl_fw_lookup_notif_ver(mvm->fw,
+                                                     PROT_OFFLOAD_GROUP,
+                                                     WOWLAN_INFO_NOTIFICATION,
+                                                     IWL_FW_CMD_VER_UNKNOWN);
+
 
        switch (WIDE_ID(pkt->hdr.group_id, pkt->hdr.cmd)) {
        case WIDE_ID(PROT_OFFLOAD_GROUP, WOWLAN_INFO_NOTIFICATION): {
-               struct iwl_wowlan_info_notif *notif = (void *)pkt->data;
+               struct iwl_wowlan_info_notif *notif;
+
+               if (wowlan_info_ver < 2) {
+                       struct iwl_wowlan_info_notif_v1 *notif_v1 = (void *)pkt->data;
+
+                       notif = kmemdup(notif_v1,
+                                       offsetofend(struct iwl_wowlan_info_notif,
+                                                   received_beacons),
+                                       GFP_ATOMIC);
+
+                       if (!notif)
+                               return false;
+
+                       notif->tid_tear_down = notif_v1->tid_tear_down;
+                       notif->station_id = notif_v1->station_id;
+
+               } else {
+                       notif = (void *)pkt->data;
+               }
 
                if (d3_data->notif_received & IWL_D3_NOTIF_WOWLAN_INFO) {
                        /* We might get two notifications due to dual bss */
@@ -2714,6 +2743,10 @@ static bool iwl_mvm_wait_d3_notif(struct iwl_notif_wait_data *notif_wait,
                len = iwl_rx_packet_payload_len(pkt);
                iwl_mvm_parse_wowlan_info_notif(mvm, notif, d3_data->status,
                                                len);
+
+               if (wowlan_info_ver < 2)
+                       kfree(notif);
+
                if (d3_data->status &&
                    d3_data->status->wakeup_reasons & IWL_WOWLAN_WAKEUP_REASON_HAS_WAKEUP_PKT)
                        /* We are supposed to get also wake packet notif */